C++ Instrument Catalog
MFC2x46Device.cpp
Go to the documentation of this file.
1 
6 // Standard includes
7 #include <regex>
8 #include <fstream> // ifstream to read files
9 #include <sstream> // string manipulation
10 
11 // Personal includes
12 #include "MFC2x46Device.h"
13 #include "CPT2026PeripheralROM.h"
14 #include "Exception.h"
15 
16 // External tools includes
17 #include "date.h"
18 
19 #if defined _WIN32
20 #define DIR_SEP '\\'
21 #else
22 #define DIR_SEP '/'
23 #endif
24 
25 #define LOG(__msg__, __level__,__location__) m_rMFCController.l_SendLogMessage(__msg__, __level__, ".MFC2x46Device", __location__)
26 
27 
28 //------------------------------------------------------------------//
29 // Constructors / Destructors
30 //------------------------------------------------------------------//
31 CMFC2x46Device::CMFC2x46Device ( CMFCController & rMFCController,
33  const std::string & rDefaultPAConfScriptFilePath,
34  const std::string & rCustomPAConfScriptDir)
35  :
36  m_rMFCController(rMFCController),
37  m_PT2026(rRM, Rsrc),
38  m_DefaultPAConfScriptFilePath(rDefaultPAConfScriptFilePath),
39  m_CustomPAConfScriptDirectory(rCustomPAConfScriptDir)
40 {
41 
42 }
43 
45 {
46 
47 }
48 
49 //--------------------------------------------------------------------------//
50 // Utilities
51 //--------------------------------------------------------------------------//
52 bool CMFC2x46Device::l_UtcToStrDateISO8601(const std::time_t & rUtcDate, std::string & rStrDate)
53 {
54  try {
55  auto l_TimePointUTC = std::chrono::system_clock::from_time_t(rUtcDate);
56  rStrDate = date::format("%FT%TZ", date::floor<std::chrono::seconds>(l_TimePointUTC)); // convert date UTC in YYYY-MM-DDTHH:MM:SSZ ISO8601 string format
57  if(rStrDate.empty())
58  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Fail to format time_t UTC date to string", MTL__LOCATION__);
59  }
60  catch (sMFCDeviceError & rE)
61  {
62  MTL_Unused(rE)
63  rStrDate.clear();
64  return false;
65  }
66  return true;
67 }
68 
69 bool CMFC2x46Device::l_ExecuteConfigurationScript (U16 Model, U32 SN, sMFCDeviceError & rError)
70 {
72 
73  try
74  {
75  // Build PA specific configuration script path: MODEL_SERIAL.scs
76  std::stringstream lssFileName;
77  lssFileName << std::setfill('0') << std::setw(4) << Model << "_" << std::setw(8) << SN << ".scs";
78  std::string lPAScriptFilePath = m_CustomPAConfScriptDirectory + DIR_SEP + lssFileName.str();
79 
80  std::ifstream lScriptFile;
81  // Try to open a PA specific script file
82  lScriptFile.open(lPAScriptFilePath);
83  if (lScriptFile.is_open())
84  {
85  LOG("Custom command script file loaded: " + lPAScriptFilePath , CInstrumentCatalog::eLogLevel::kInfo, MTL__LOCATION__);
86  }
87  else
88  {
89  // There is no PA specific script file, open the default one
90  lScriptFile.open(m_DefaultPAConfScriptFilePath);
91  if (!lScriptFile.is_open())
92  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not open Command Script File", MTL__LOCATION__);
93  LOG("Default command script file loaded: "+ m_DefaultPAConfScriptFilePath, CInstrumentCatalog::eLogLevel::kInfo, MTL__LOCATION__);
94  }
95 
96  std::string lFileLine;
97  while (std::getline(lScriptFile, lFileLine))
98  {
99  if (!m_PT2026.WriteCustomCommand(lFileLine))
100  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not write command from script", MTL__LOCATION__);
101  }
102  }
103  catch (sMFCDeviceError & rE)
104  {
105  LOG("Command script file could be (or not entirely) run. Some instrument parameters may not be set.", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
106 
107  rError = rE;
108  return false;
109  }
110  return true;
111 }
112 
113 bool CMFC2x46Device::l_ConfigurationChanged (CInstrumentCatalog::sInstrumentState lastcfg, CInstrumentCatalog::sInstrumentState newcfg)
114 {
115  return (lastcfg.OperatingMode != newcfg.OperatingMode ||
116  lastcfg.ProbeSelection != newcfg.ProbeSelection ||
117  *(reinterpret_cast<U64*>(&lastcfg.FreqMin)) != *(reinterpret_cast<U64*>(&newcfg.FreqMin)) || // Compare binary representation of the double values to detect value change
118  *(reinterpret_cast<U64*>(&lastcfg.FreqMax)) != *(reinterpret_cast<U64*>(&newcfg.FreqMax)) || // Compare binary representation of the double values to detect value change
120 }
121 
122 bool CMFC2x46Device::l_ConfigureForOperation (const CInstrumentCatalog::sInstrumentState & rInstrState, sMFCDeviceError & rError)
123 {
125 
126  //-----------------------------------------------------
127  // According to the current sInstrumentState, set
128  // ProbeSelection
129  // FreqMin
130  // FreqMax
131  // NbAveragedMeasurements
132 
133  if (l_ConfigurationChanged(m_LastConfigured, rInstrState))
134  {
135  LOG("Reconfiguration needed", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
136  try
137  {
138  switch (rInstrState.OperatingMode)
139  {
141  // Set selection mode to restricted probe set in the camera
142  if (!m_PT2026.ChannelsSetLimitedListState(true))
143  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set limited list state", MTL__LOCATION__);
144  break;
145  default:
146  // Set selection mode to entire probe set in the camera
147  if (!m_PT2026.ChannelsSetLimitedListState(false))
148  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set limited list state", MTL__LOCATION__);
149  break;
150  }
151 
152  // Select channel(s)
153  switch (rInstrState.ProbeSelection.SelectionMode)
154  {
156  {
157  // Select the camera
158  SCPI::tChannelList l_CameraChannelList;
159  l_CameraChannelList.push_back(m_PAChannel);
160  if (!m_PT2026.ChannelsSelect(l_CameraChannelList))
161  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not select camera", MTL__LOCATION__);
162  // In camera measurement, the number of results to fetch are defined by the number of measurement heads
163  switch (rInstrState.OperatingMode)
164  {
166  m_NbOfMeasurementsToFetch = m_NbOfSearchHeads;
167  break;
168  default:
169  m_NbOfMeasurementsToFetch = m_NbOfMeasHeads;
170  break;
171  }
172  }
173  break;
175  {
176  // Select the single camera head
177  // Compute channel of the single head
178  SCPI::tChannel l_SingleHeadChannel = m_PAChannel;
179  l_SingleHeadChannel.push_back(rInstrState.ProbeSelection.ProbeNumber);
180  // Compute channel list of the single head
181  SCPI::tChannelList l_SingleHeadChannelList;
182  l_SingleHeadChannelList.push_back(l_SingleHeadChannel);
183  // Select the single head
184  if (!m_PT2026.ChannelsSelect(l_SingleHeadChannelList))
185  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not select camera", MTL__LOCATION__);
186  // In single probe measurement, there is only one result to fetch
187  m_NbOfMeasurementsToFetch = 1;
188  }
189  break;
190  default:
191  // Unhandled case
192  MTL_Assert(false);
193  throw sMFCDeviceError(sMFCDeviceError::eLevel::kFatal, "Unhandled selection mode", MTL__LOCATION__);
194  break;
195  }
196 
197  // Set search limits
198  if (!m_PT2026.ParmSearchSetLimits(rInstrState.FreqMin, rInstrState.FreqMax))
199  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set search limits", MTL__LOCATION__);
200 
201  // Set measurement averaging
203  if (rInstrState.NbAveragedMeasurements <= 1)
204  {
206  l_MeasAvg.NoPoints = 1;
207  }
208  else if (rInstrState.NbAveragedMeasurements >= 1500)
209  {
211  l_MeasAvg.NoPoints = 1500;
212  }
213  else
214  {
216  l_MeasAvg.NoPoints = rInstrState.NbAveragedMeasurements;
217  }
218  if (!m_PT2026.ParmAveragingMeasurementSet(l_MeasAvg))
219  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not set measurement averaging", MTL__LOCATION__);
220  }
221  catch (sMFCDeviceError & rE)
222  {
223  //if (nullptr != m_pPT2026)
224  // std::vector<sError> l_2026ErrorList = m_pPT2026->ErrorList();
225  rError = rE;
226  return false;
227  }
228  }
229  else {
230  LOG("No reconfiguration needed", CInstrumentCatalog::eLogLevel::kDebug, MTL__LOCATION__);
231  }
232  m_LastConfigured = rInstrState;
233  return true;
234 }
235 
236 // Compute the average of the measurements made during the search operation on the set of selected heads.
237 void CMFC2x46Device::l_ComputeAveraging (const std::vector<tFlux> & rFluxList, F64 & rReturnedAveraging, F64 & rReturnedStdDev)
238 {
239  // Compute the mean of the measurements.
240  U8 l_ValidCount = 0;
241  rReturnedAveraging = 0.0l;
242  rReturnedStdDev = 0.0l;
243 
244  try
245  {
246  // Check content
247  if (rFluxList.empty())
248  throw false;
249 
250  // Compute averaging
251  for (std::vector<tFlux>::const_iterator l_it = rFluxList.begin(); l_it != rFluxList.end(); l_it++)
252  {
253  // Make sure that the measurement taken to compute the mean are valid.
254  // An invalid measurement is marked with a mean value being equal to NaN.
255  if (!std::isnan(*l_it))
256  {
257  // Sum up all the NMR frequencies measured.
258  rReturnedAveraging += *l_it;
259  // Update the number of valid heads.
260  l_ValidCount++;
261  }
262  }
263  // If we had some valid heads, compute the average.
264  if (l_ValidCount > 0)
265  rReturnedAveraging = rReturnedAveraging / l_ValidCount;
266  else
267  rReturnedAveraging = DPqNaN;
268 
269  // We already know how many valid heads are available.
270  if (l_ValidCount > 1)
271  {
272  for (std::vector<tFlux>::const_iterator l_it = rFluxList.begin(); l_it != rFluxList.end(); l_it++)
273  {
274  // Make sure that the measurement taken to compute the mean are valid.
275  // An invalid measurement is marked with a mean value being equal to NaN.
276  if (!std::isnan(*l_it))
277  {
278  F64 l_Value = *l_it - rReturnedAveraging;
279  rReturnedStdDev += l_Value * l_Value;
280  }
281  }
282  // Compute the standard deviation in ppm from the computed mean.
283  rReturnedStdDev = sqrt(rReturnedStdDev / (l_ValidCount - 1)) / rReturnedAveraging * 1e6;
284  }
285  else
286  rReturnedStdDev = DPqNaN;
287  }
288  catch (bool & rE)
289  {
290  MTL_Unused(rE)
291  rReturnedAveraging = DPqNaN;
292  rReturnedStdDev = DPqNaN;
293  }
294 }
295 
297 {
298  bool l_ReturnSucceeded = m_PT2026.Abort(true);
299 
300  // Flush RemoteBoxStart button status bit
301  bool l_RemoteBoxPressed(false);
302  RemoteBoxButtonStatus(l_RemoteBoxPressed);
303  return l_ReturnSucceeded;
304 }
305 
307 {
308  std::string l_IDN;
309  return (m_PT2026.GetIdentification(l_IDN));
310 }
311 
312 //--------------------------------------------------------------------------//
313 // Available Operations
314 //--------------------------------------------------------------------------//
315 // connect to PT2026 main unit and get instrument information
317 {
318  try
319  {
320  m_ChanList.clear();
321  if (!m_PT2026.Connect(5000))
322  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot connect to requested resource", MTL__LOCATION__);
323  if (!m_PT2026.Abort(true))
324  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot abort instrument", MTL__LOCATION__);
325  std::string l_IDN;
326  if (!m_PT2026.GetIdentification(l_IDN))
327  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve instrument identification", MTL__LOCATION__);
328  // Parse identification: according to 488.2 10.14.3, *IDN? format is Manufacturer,Model,SerialNumber,FirmwareLevel
329  std::regex l_reg("([^,]+)+");
330  std::sregex_token_iterator l_IdnTokIt(l_IDN.begin(), l_IDN.end(), l_reg);
331  std::vector<std::string> l_IdnTokens(l_IdnTokIt, std::sregex_token_iterator());
332  if (l_IdnTokens.size() < 4)
333  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot parse identification", MTL__LOCATION__);
334 
335  std::string l_ManDateStr, l_CalDateStr;
336  time_t l_ManDate, l_CalDateUTC;
337  if (!m_PT2026.ReadInformationDates(l_ManDateStr, l_ManDate, l_CalDateStr, l_CalDateUTC))
338  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot read information dates", MTL__LOCATION__);
339  if(!l_UtcToStrDateISO8601(l_CalDateUTC, rInstrInfo.CalibrationDate)) // convert time_t UTC to YYYY-MM-DDTHH:MM:SSZ ISO8601 UTC format
340  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot parse date", MTL__LOCATION__);
341 
342  //rInstrInfo.InstrumentConnection is filled in MFCManager
344  rInstrInfo.SerialNumber = l_IdnTokens[2];
345  if (!l_IDN.empty() && l_IDN[l_IDN.length()-1] == '\n') {
346  l_IDN.erase(l_IDN.length()-1);
347  }
348  rInstrInfo.Description = l_IDN;
349  }
350  catch (sMFCDeviceError & rE)
351  {
352  return rE;
353  }
354  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Instrument Connection done.", MTL__LOCATION__);
355 }
356 
357 // Scan FCA and Probe Array connected to main unit and get information
359  CInstrumentCatalog::sInstrumentConfiguration & rInstrConfig, bool &rPaInfoChanged)
360 {
362 
363  try
364  {
365  CExtendedChannelList l_NewChanList;
366  rPaInfoChanged = false;
367  if (!m_PT2026.ChannelsGetList(l_NewChanList))
368  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not retrieve channel list", MTL__LOCATION__);
369  // If the channel list changed
370  if (l_NewChanList != m_ChanList)
371  {
372  m_LastConfigured = CInstrumentCatalog::sInstrumentState(); // Clear last known configuration
373  m_PAChannel.clear(); // Clear last known camera channel
374  m_ChanList = l_NewChanList; // Save new Channel list
375  try
376  {
377  // Read acquisition period
378  sPulse<uParm> l_RFPulse;
379  if (!m_PT2026.ParmRFPulseGet(l_RFPulse))
380  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Cannot retrieve RF pulse parms", MTL__LOCATION__);
381  rInstrConfig.AcquisitionPeriod = l_RFPulse.Period_s;
382 
383  // If there is no available channel
384  if (m_ChanList.empty())
385  throw false;
386 
387  std::vector<sChannelIformation> l_FCAChanInfoVect;
388  SCPI::tChannelList l_FCAChannelListVect;
389  //check in Channels List to find FCA and PA channels
390  for (auto & l_ChanIt : m_ChanList)
391  {
392  // Check that we have a PA
393  if (l_ChanIt.Type == kPwCamera)
394  {
395  m_PAChannel = l_ChanIt.Channel;
396  break; //break at first PA channel
397  }
398  //Check that we have a FCA
399  else if (kPwFCA == l_ChanIt.Type || kPwMultiplexer == l_ChanIt.Type) //todo: for next PT2026 firmware ARM version remove kPwMultiplexer == l_ChanIt.Type
400  {//todo: For next PT2026 Firmware ARM version, modify FCA type to kPwFCA. An FCA must not anymore be detected as kPwMultiplexer. The PT2026TypeConversions.cpp must be modified as well.
401  l_FCAChannelListVect.clear(); //clear history to keep only the last peripheral FCA
402  l_FCAChannelListVect.push_back(l_ChanIt.Channel); // fill with FCA channel list
403  }
404  }
405 
406  // get FCA information if exists
407  if(!l_FCAChannelListVect.empty())
408  {
409  if(!m_PT2026.ChannelsGetInfo(l_FCAChannelListVect, l_FCAChanInfoVect))
410  {
411  l_FCAChanInfoVect.clear();
412  }
413  else
414  {
415  if(!l_FCAChanInfoVect.empty())
416  {
417  l_FCAInfo.Description = l_FCAChanInfoVect.at(0).Designation;
418  l_FCAInfo.SerialNumber = std::to_string(l_FCAChanInfoVect.at(0).SN);
419  l_FCAInfo.FCAFwVersion = l_FCAChanInfoVect.at(0).FirmwareVersion;
420  }
421  }
422  }
423 
424  // If we don't have a camera
425  if (m_PAChannel.empty())
426  throw false;
427 
428  // Select the camera
429  SCPI::tChannelList l_CameraChannelList;
430  l_CameraChannelList.push_back(m_PAChannel);
431  if (!m_PT2026.ChannelsSelect(l_CameraChannelList))
432  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not select camera", MTL__LOCATION__);
433 
434  // Set units in kMHz
435  if (!m_PT2026.ParmUnitsSet(UNITS))
436  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not set units", MTL__LOCATION__);
437 
438  // Retrieve frequency limits
439  sSearch<sBoundedParm> l_SearchParms;
440  if (!m_PT2026.ParmSearchGet(l_SearchParms))
441  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not retrieve search parms", MTL__LOCATION__);
442 
443  // Retrieve PA information
444  // Read ROM
445  std::vector<U8> l_ROMContent;
446  if (!m_PT2026.DeviceROMRead(m_PAChannel, l_ROMContent))
447  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not retrieve PA ROM content", MTL__LOCATION__);
448  // Parse ROM
449  CPT2026PeripheralROM::Parser l_ROM(l_ROMContent.begin(), l_ROMContent.end());
450  if (!l_ROM.Parse())
451  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
452  // Get Identification
453  CPT2026PeripheralROM::sIdentification l_Identification;
454  if(!l_ROM.HasIdentification(l_Identification))
455  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
456  // Get PW Camera Physical Information
457  U16 l_ParmAddr;
458  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwCamPhysicalInformation), l_ParmAddr))
459  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
461  if (!l_ROM.ParsePwCamPhysInfo(l_ParmAddr, l_PwCamPhysInfo))
462  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
463  // Get Search Head List
464  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kSearchHeads), l_ParmAddr))
465  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
466  CPT2026PeripheralROM::tHeadList l_SearchHeadList;
467  if (!l_ROM.ParseHeadList(l_ParmAddr, l_SearchHeadList))
468  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
469  // Get Meas Head List
470  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kMeasHeads), l_ParmAddr))
471  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
472  CPT2026PeripheralROM::tHeadList l_MeasHeadList;
473  if (!l_ROM.ParseHeadList(l_ParmAddr, l_MeasHeadList))
474  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
475  // Get Multi Head Information
476  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kMultiHeadInformation), l_ParmAddr))
477  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
478  CPT2026PeripheralROM::sMultiHeadInfo l_MultiHeadInfo;
479  if (!l_ROM.ParseMultiHeadInfo(l_ParmAddr, l_MultiHeadInfo))
480  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
481  // Get PW Physical Information Set
482  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwPhysicalInformationSet), l_ParmAddr))
483  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
485  if (!l_ROM.ParsePwPhysInfoSet(l_ParmAddr, l_PwPhysInfoSet))
486  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
487  // Get Manufacture Information
488  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kManufactureInformation), l_ParmAddr))
489  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
491  if (!l_ROM.ParseManufactureInformation(l_ParmAddr, l_ManInfo))
492  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
493 
494  // Execute configuration script for this PA
496  if (!l_ExecuteConfigurationScript(l_Identification.Model, l_Identification.SN, l_Error))
497  throw l_Error;
498 
499  // Prepare new PA Info to be returned
500  switch (l_Identification.Model) {
501  case 9046:
503  break;
504  case 9146:
506  break;
507  default:
509  break;
510  }
511  rPAInfo.SerialNumber = std::to_string(l_Identification.SN);
512 
513 
514 
515  // Available frequency range depends on the main unit, the FCA, and the PA, so we retrieve the intersection through the search limits
516  rPAInfo.FreqMin = l_PwCamPhysInfo.LowFreq / 1e6; // From [Hz] to [MHz]
517  rPAInfo.FreqMax = l_PwCamPhysInfo.HighFreq / 1e6; // From [Hz] to [MHz]
518  rPAInfo.FreqCentral = l_PwCamPhysInfo.NominalFreq / 1e6; // From [Hz] to [MHz]
519  rPAInfo.GyroRatio = l_PwCamPhysInfo.GyroRatio / 1e6; // From [Hz/T] to [MHz/T]
520  rPAInfo.Description = l_ManInfo.Designation;
521 
522  m_NbOfSearchHeads = static_cast<U8>(l_SearchHeadList.size());
523  m_NbOfMeasHeads = static_cast<U8>(l_MeasHeadList.size());
524 
525  U8 l_ProbeNo = 1;
526  rPAInfo.ProbeList.clear();
527  for (auto & l_it : l_MultiHeadInfo.MultiHeadInfo)
528  {
529  CPT2026PeripheralROM::sPwPhysicalInformation & l_rPhysInfo = l_PwPhysInfoSet[l_it.PhysInfoSetIndex];
531  l_PI.ProbeNumber = l_ProbeNo++;
532  l_PI.FreqMin = l_rPhysInfo.MinFreq / 1e6; // From [Hz] to [MHz]
533  l_PI.FreqMax = l_rPhysInfo.MaxFreq / 1e6; // From [Hz] to [MHz]
534  rPAInfo.ProbeList.push_back(l_PI);
535  }
536 
537  //update FCA Info (must be done after last throw)
538  rPAInfo.FCAInfo = l_FCAInfo;
539 
540  //Get MFC9046 probe array Normalization date. If we failed to get it we just send a warning!
541  std::match_results<std::string::const_iterator> l_DateMatch;
542  // MFC9046 normalization date & time string format ISO8601 UTC is: YYYY-MM-DDTHH:MM:SSZ
543  if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{4}-[0-9]{2}-[0-9]{2})(T[0-9]{2}:[0-9]{2}:[0-9]{2})(Z?)")))
544  {
545  rPAInfo.NormalizationDate = l_DateMatch[1].str() + l_DateMatch[2].str() + "Z";
546  }
547  else if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{4}-[0-9]{2}-[0-9]{2})(.*)"))) //YYYY-MM-DD
548  { // if only normalization date exists (no time). String format date ISO8601 is: YYYY-MM-DD
549  rPAInfo.NormalizationDate = l_DateMatch[1].str() + "T00:00:00Z"; // convert "YYYY-MM-DD" to "YYYY-MM-DDTHH:MM:SSZ" UTC ISO8601 format
550  }
551  else if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{2})(-[0-9]{2}-)([0-9]{4})(.*)"))) //DD-MM-YYYY
552  { //if year and day has been inversed
553  rPAInfo.NormalizationDate = l_DateMatch[3].str() + l_DateMatch[2].str() + l_DateMatch[1].str() + "T00:00:00Z"; // convert "DD-MM-YYYY" to "YYYY-MM-DDTHH:MM:SSZ" UTC ISO8601 format
554  }
555  else
556  {
557  rPAInfo.NormalizationDate ="";
558  LOG("Failed to parse Porbe Array normalization date", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
559  }
560 
561  // Ok to send new PA Info
562  rPaInfoChanged = true;
563  }
564  // There is no error but camera is not available
565  catch (bool & rUsableCamera)
566  {
567  MTL_Unused(rUsableCamera)
568 
569  //if FCA has changed
570  if((l_FCAInfo.SerialNumber != rPAInfo.SerialNumber) || (l_FCAInfo.Description != rPAInfo.FCAInfo.Description))
571  rPaInfoChanged = true;
572 
573  // If we previously had a PA
574  if (!rPAInfo.ProbeList.empty())
575  {
576  // Clear PA Info (it also clears FCAInfo)
578  // Clear Camera Channel
579  m_PAChannel = SCPI::tChannel();
580  m_NbOfSearchHeads = 0;
581  m_NbOfMeasHeads = 0;
582  m_NbOfMeasurementsToFetch = 0;
583  rPaInfoChanged = true;
584  }
585  //update FCA Info
586  rPAInfo.FCAInfo = l_FCAInfo; // (restore FCA Info if cleared in rPAInfo)
587  }
588  }
589  }
590  catch (sMFCDeviceError & rE)
591  {
592  //if (nullptr != m_pPT2026)
593  // std::vector<sError> l_2026ErrorList = m_pPT2026->ErrorList();
594 
595  m_ChanList = CExtendedChannelList(); // clear last channel list
596  //if FCAInfo has changed
597  if((l_FCAInfo.SerialNumber != rPAInfo.SerialNumber) || (l_FCAInfo.Description != rPAInfo.FCAInfo.Description))
598  rPaInfoChanged = true;
599 
600  // If we previously had a PA
601  if (!rPAInfo.ProbeList.empty())
602  {
603  // Update PA Info (empty)
605  // Clear Camera Channel
606  m_PAChannel = SCPI::tChannel();
607  rPaInfoChanged = true;
608  }
609  //update FCA Info
610  rPAInfo.FCAInfo = l_FCAInfo; // (restore FCA Info if cleared in rPAInfo)
611 
612  // If the error is not too bad but instrument is not responding anymore
613  std::string l_Identification;
614  if (rE.Level > sMFCDeviceError::eLevel::kError
615  && !m_PT2026.GetIdentification(l_Identification))
616  {
617  // Return an error
618  return sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Instrument is not responding", MTL__LOCATION__);
619  }
620  else
621  return rE; // Return received error
622  }
623  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Scan PA done.", MTL__LOCATION__);
624 }
625 
627 {
628  sMFCDeviceError l_ReturnError;
629  try
630  {
631  // Check initial conditions
632  // Check that we have a PA
633  if (m_PAChannel.empty())
634  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No available PA", MTL__LOCATION__);
635 
636  sMFCDeviceError l_Error;
637  if(!l_ConfigureForOperation(rInstrState, l_Error))
638  throw l_Error;
639 
640  // Search
641  bool l_InitiatedContinuous = (CInstrumentCatalog::eRepeatMode::kContinuous == rInstrState.RepeatMode);
642  if (!m_PT2026.Initiate(l_InitiatedContinuous))
643  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not initiate measurements", MTL__LOCATION__);
644 
645  uOPERation l_OperCond, l_OperEvent;
646  do
647  {
648  // Read status operation register
650  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
652  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
653 
654  // Read STB conntinuously while
655  // - we are not requested to stop
656  // - we don't have our measurement results
657  // - we are still INITiated
658  // If system indicates Searching, report search progress.
659  for (;
660  !m_rMFCController.l_IsAbortRequested() && l_OperCond.OPERation.INITiated && !l_OperEvent.OPERation.NewMeasAvail;
661  )
662  {
663  // If we don't have our result yet and we are searching
664  if (l_OperCond.OPERation.SWEeping)
665  {
666  U8 l_SPR;
667  F64 l_HallMeas;
668  if (!m_PT2026.GetSearchProgress(l_SPR, l_HallMeas))
669  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read search progress", MTL__LOCATION__);
670  m_rMFCController.l_SendSearchProgress(l_SPR);//notify controller for search progress
671  }
672 
673  std::this_thread::sleep_for(std::chrono::milliseconds(SEARCH_POLLING_PERIOD_MS));
674 
675  // Read status operation register
677  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
679  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
680  }
681 
682  // If we have a result to read, read search result and return it
683  if (!m_rMFCController.l_IsAbortRequested())
684  {
685  // If the search succeeded...
686  if (l_OperEvent.OPERation.NewMeasAvail)
687  {
688  std::vector<tFlux> l_Flux;
689  eUnits l_Units;
690  if (!m_PT2026.MeasurementsGet(m_NbOfMeasurementsToFetch, l_Flux, l_Units))
691  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch search result", MTL__LOCATION__);
692 
693  MTL_Assert(!l_Flux.empty() && l_Units == UNITS);
694  if (l_Flux.empty() || l_Units != UNITS)
695  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid search result", MTL__LOCATION__);
696 
697  // Compute result
698  F64 l_Average, l_StdDev;
699  l_ComputeAveraging(l_Flux, l_Average, l_StdDev);
700 
701  // Send result
702  CInstrumentCatalog::sSearchResult l_SearchResult;
703  l_SearchResult.Freq = l_Average;
704  l_SearchResult.StdDev = static_cast<F32>(l_StdDev);
705  m_rMFCController.l_SendSearchResult(l_SearchResult);
706  }
707  else
708  {//No error but no measurement result available from instrument.
709  LOG("No measurement result returned by instrument", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
710  }
711  }
712  } while (!m_rMFCController.l_IsAbortRequested() && l_OperCond.OPERation.INITiated && l_InitiatedContinuous);
713  l_ReturnError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Search operation done.", MTL__LOCATION__);
714  }
715  catch (sMFCDeviceError & rE)
716  {
717  //if (nullptr != m_pPT2026)
718  // std::vector<sError> l_2026ErrorList = m_pPT2026->ErrorList();
719 
720  // Signal error
721  l_ReturnError = rE;
722  }
723  return l_ReturnError;
724 }
725 
727 {
728  sMFCDeviceError l_ReturnError;
729  try
730  {
731  // Check initial conditions
732  // Check that we have a PA
733  if (m_PAChannel.empty())
734  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "No available PA", MTL__LOCATION__);
735 
736  sMFCDeviceError l_Error;
737  if(!l_ConfigureForOperation(rInstrState,l_Error))
738  throw l_Error;
739 
740  // Measure
741  bool l_InitiatedContinuous = (CInstrumentCatalog::eRepeatMode::kContinuous == rInstrState.RepeatMode);
742  if (!m_PT2026.Initiate(l_InitiatedContinuous))
743  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not initiate measurements", MTL__LOCATION__);
744 
745  uOPERation l_OperCond, l_OperEvent;
746  do
747  {
748  // Read status operation register
750  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
752  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
753 
754  // Read STB conntinuously while
755  // - we are not requested to stop
756  // - we don't have our measurement results
757  // - we are still INITiated
758  // If system indicates Searching, report search progress.
759  for (;
760  !m_rMFCController.l_IsAbortRequested() && l_OperCond.OPERation.INITiated && !l_OperEvent.OPERation.NewMeasAvail;
761  )
762  {
763  // If we don't have our result yet and we are searching
764  if (l_OperCond.OPERation.SWEeping)
765  {
766  U8 l_SPR;
767  F64 l_HallMeas;
768  if (!m_PT2026.GetSearchProgress(l_SPR, l_HallMeas))
769  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read search progress", MTL__LOCATION__);
770  m_rMFCController.l_SendSearchProgress(l_SPR);//notify controller for search progress
771  }
772 
773  std::this_thread::sleep_for(std::chrono::milliseconds(MEAS_POLLING_PERIOD_MS));
774  // Read status operation register
776  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
778  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not read status operation register", MTL__LOCATION__);
779  }
780 
781  // Quit on an abort requested?
782  if (!m_rMFCController.l_IsAbortRequested())
783  {
784  // If we have a result to read, read measurement result and return it
785  if(l_OperEvent.OPERation.NewMeasAvail)
786  {
787  eUnits l_Units;
788  sArbitraryMeasurements l_ArbMeas;
789  sAllMeasurements l_Measurements;
790  l_ArbMeas.Flux = true;
791  l_ArbMeas.Deviation = true;
792  l_ArbMeas.Uniformity = true;
793  l_ArbMeas.Channel = true;
794  l_ArbMeas.Timestamp = true;
795  l_ArbMeas.Status = true;
796  l_ArbMeas.NbValidMeas = true;
797  if (!m_PT2026.MeasurementsGet(m_NbOfMeasurementsToFetch, l_ArbMeas, l_Measurements, l_Units))
798  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Could not fetch result", MTL__LOCATION__);
799 
800  MTL_Assert(l_Measurements.AdvMeas.Basic.size() == m_NbOfMeasurementsToFetch && l_Units == UNITS);
801  if (l_Measurements.AdvMeas.Basic.size() != m_NbOfMeasurementsToFetch || l_Units != UNITS)
802  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid measurement result", MTL__LOCATION__);
803 
804  // Prepare result
806  l_MeasResult.Timestamp = l_Measurements.AdvMeas.Basic.front().Timestamp;
807  for (auto & l_MeasIt : l_Measurements.AdvMeas.Basic)
808  {
810  l_Meas.ProbeNumber = l_MeasIt.Channel.back();
811  l_Meas.Freq = l_MeasIt.Flux_UNITS;
812  l_Meas.NbValidMeasurements = l_MeasIt.NbValidMeas;
813  l_Meas.StdDev = l_MeasIt.Deviation_ppm;
814  l_MeasResult.MeasurementList.push_back(l_Meas);
815  }
816  //Send measurement result
817  m_rMFCController.l_SendMeasResult(l_MeasResult);
818  }
819  else
820  {//No error but no measurement result available from instrument.
821  LOG("No measurement result returned by instrument", CInstrumentCatalog::eLogLevel::kWarning, MTL__LOCATION__);
822  }
823  }
824  } while (!m_rMFCController.l_IsAbortRequested() && l_OperCond.OPERation.INITiated && l_InitiatedContinuous);
825  l_ReturnError = sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Measure operation done.", MTL__LOCATION__);
826  }
827  catch (sMFCDeviceError & rE)
828  {
829  //if (nullptr != m_pPT2026)
830  // std::vector<sError> l_2026ErrorList = m_pPT2026->ErrorList();
831 
832  l_ReturnError = rE;
833  }
834  return l_ReturnError;
835 }
836 
838  CInstrumentCatalog::sNormalization & rReturnedNormalization)
839 {
840  try
841  {
842  rReturnedNormalization.Access = rNewNormalizationRequest.Access;
843  rReturnedNormalization.Table.clear();
844 
845  switch (rNewNormalizationRequest.Access)
846  {
848  {
849  // Read Normalization
850  tNormalizationTable l_MFC2x46Normalization;
851  if (!m_PT2026.NormalizationGet(m_PAChannel, l_MFC2x46Normalization))
852  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve normalization table", MTL__LOCATION__);
853  // Convert units and fill Normalization table
854  for (auto&& Factor_Hz : l_MFC2x46Normalization)
855  rReturnedNormalization.Table.push_back(Factor_Hz * 1e-6f); // From [Hz] to [MHz]
856  break;
857  }
859  {
860  // Read Normalization
861  // Read ROM
862  std::vector<U8> l_ROMContent;
863  if (!m_PT2026.DeviceROMRead(m_PAChannel, l_ROMContent))
864  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve device ROM", MTL__LOCATION__);
865  // Parse ROM
866  CPT2026PeripheralROM::Parser l_ROM(l_ROMContent.begin(), l_ROMContent.end());
867  if (!l_ROM.Parse())
868  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot parse device ROM", MTL__LOCATION__);
869  U16 l_ParmAddr;
870  // Get PW Camera Physical Information
871  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwCamPhysicalInformation), l_ParmAddr))
872  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
874  if (!l_ROM.ParsePwCamPhysInfo(l_ParmAddr, l_PwCamPhysInfo))
875  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
876 
877  // Convert units
878  for (auto&& Factor_Hz : l_PwCamPhysInfo.NormalizationTable)
879  rReturnedNormalization.Table.push_back(Factor_Hz * 1e-6f); // From [Hz] to [MHz]
880  break;
881  }
883  {
884  tNormalizationTable l_PT2026Normalization;
885  // Convert units
886  for (auto&& Factor_MHz : rNewNormalizationRequest.Table)
887  l_PT2026Normalization.push_back(Factor_MHz * 1e6f); // From [MHz] to [Hz]
888  // Write Normalization to temporary memory
889  if (!m_PT2026.NormalizationSet(m_PAChannel, l_PT2026Normalization))
890  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot set normalization table in RAM", MTL__LOCATION__);
891  break;
892  }
894  {
895  // Write Normalization
896  // Read ROM
897  std::vector<U8> l_ROMContent;
898  if (!m_PT2026.DeviceROMRead(m_PAChannel, l_ROMContent))
899  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot retrieve device ROM", MTL__LOCATION__);
900  // Parse ROM
901  CPT2026PeripheralROM::Parser l_ROM(l_ROMContent.begin(), l_ROMContent.end());
902  if (!l_ROM.Parse())
903  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Cannot parse device ROM", MTL__LOCATION__);
904  // Get Identification
905  CPT2026PeripheralROM::sIdentification l_Identification;
906  if (!l_ROM.HasIdentification(l_Identification))
907  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
908  U16 l_ParmAddr;
909  // Get Manufacture information
910  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kManufactureInformation), l_ParmAddr))
911  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
913  if (!l_ROM.ParseManufactureInformation(l_ParmAddr, l_ManuInfo))
914  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
915  // Get Multi Head Information
916  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kMultiHeadInformation), l_ParmAddr))
917  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
918  CPT2026PeripheralROM::sMultiHeadInfo l_MultiHeadInfo;
919  if (!l_ROM.ParseMultiHeadInfo(l_ParmAddr, l_MultiHeadInfo))
920  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
921  // Get Search Heads
922  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kSearchHeads), l_ParmAddr))
923  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
924  CPT2026PeripheralROM::tHeadList l_SearchHeadList;
925  if (!l_ROM.ParseHeadList(l_ParmAddr, l_SearchHeadList))
926  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
927  // Get Measurement Heads
928  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kMeasHeads), l_ParmAddr))
929  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
930  CPT2026PeripheralROM::tHeadList l_MeasHeadList;
931  if (!l_ROM.ParseHeadList(l_ParmAddr, l_MeasHeadList))
932  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
933  // Get PW Camera Physical Information
934  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwCamPhysicalInformation), l_ParmAddr))
935  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
937  if (!l_ROM.ParsePwCamPhysInfo(l_ParmAddr, l_PwCamPhysInfo))
938  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
939  // Get PW Physical Information Set
940  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwPhysicalInformationSet), l_ParmAddr))
941  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
943  if (!l_ROM.ParsePwPhysInfoSet(l_ParmAddr, l_PwPhysInfoSet))
944  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Invalid device ROM", MTL__LOCATION__);
945 
946  // Set normalization date
947  auto l_TimeNow = std::chrono::system_clock::now(); // get current time at UTC
948  std::string l_StrDate;
949  l_StrDate= date::format("%FT%TZ", date::floor<std::chrono::seconds>(l_TimeNow)); // Date & Time in UTC ISO8601 format: YYYY-MM-DDTHH:MM:SSZ
950  if(l_StrDate.empty())
951  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError, "Fail to format time & date to string", MTL__LOCATION__);
952  l_PwCamPhysInfo.NormalizationDate = l_StrDate;
953 
954  // Convert units and fill Normalization table
955  l_PwCamPhysInfo.NormalizationTable.clear();
956  for (auto&& Factor_MHz : rNewNormalizationRequest.Table)
957  l_PwCamPhysInfo.NormalizationTable.push_back(Factor_MHz * 1e6F); // From [MHz] to [Hz]
958 
959  // Write new ROM
960  std::vector<U8> l_NewROMContent;
961  CPT2026PeripheralROM::Builder::Build9046ROM(l_NewROMContent, l_Identification, l_ManuInfo, l_MultiHeadInfo, l_SearchHeadList, l_MeasHeadList, l_PwCamPhysInfo, l_PwPhysInfoSet);
962  if (!m_PT2026.DeviceROMWrite(m_PAChannel, l_NewROMContent))
963  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError,"Cannot write device ROM", MTL__LOCATION__);
964  break;
965  }
966  default:
967  MTL_Assert(false);
968  throw sMFCDeviceError(sMFCDeviceError::eLevel::kError,"Software error. Unhandled case", MTL__LOCATION__);
969  break;
970  }
971  }
972  catch (sMFCDeviceError & rE)
973  {
974  return rE;
975  }
976  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "New normalization request done.", MTL__LOCATION__);
977 }
978 
980 {
981  try
982  {
983  // Retrieve PA information
984  // Read ROM
985  std::vector<U8> l_ROMContent;
986  if (!m_PT2026.DeviceROMRead(m_PAChannel, l_ROMContent))
987  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not retrieve PA ROM content", MTL__LOCATION__);
988  // Parse ROM
989  CPT2026PeripheralROM::Parser l_ROM(l_ROMContent.begin(), l_ROMContent.end());
990  if (!l_ROM.Parse())
991  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
992  // Get PW Camera Physical Information
993  U16 l_ParmAddr;
994  if (!l_ROM.ParmAddress(static_cast<U8>(CPT2026PeripheralROM::e9046ROMParm::kPwCamPhysicalInformation), l_ParmAddr))
995  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
997  if (!l_ROM.ParsePwCamPhysInfo(l_ParmAddr, l_PwCamPhysInfo))
998  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not parse PA ROM content", MTL__LOCATION__);
999 
1000  std::match_results<std::string::const_iterator> l_DateMatch;
1001  // PT2026 normalization date & time string format ISO8601 UTC is: YYYY-MM-DDTHH:MM:SSZ
1002  if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{4}-[0-9]{2}-[0-9]{2})(T[0-9]{2}:[0-9]{2}:[0-9]{2})(Z?)")))
1003  rNormDate = l_DateMatch[1].str() + l_DateMatch[2].str() + "Z";
1004  else if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{4}-[0-9]{2}-[0-9]{2})(.*)"))) //YYYY-MM-DD
1005  { // if only normalization date exists (no time info). String format date ISO8601 is: YYYY-MM-DD
1006  rNormDate = l_DateMatch[1].str() + "T00:00:00Z"; // convert "YYYY-MM-DD" to "YYYY-MM-DDTHH:MM:SSZ" UTC ISO8601 format
1007  }
1008  else if (std::regex_match(l_PwCamPhysInfo.NormalizationDate, l_DateMatch, std::regex("^([0-9]{2})(-[0-9]{2}-)([0-9]{4})(.*)"))) //DD-MM-YYYY
1009  { //if year and day has been inversed
1010  rNormDate = l_DateMatch[3].str() + l_DateMatch[2].str() + l_DateMatch[1].str() + "T00:00:00Z"; // convert "DD-MM-YYYY" to "YYYY-MM-DDTHH:MM:SSZ" UTC ISO8601 format
1011  }
1012  else
1013  {
1014  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Cannot parse normalization date", MTL__LOCATION__);
1015  }
1016  }
1017  catch (sMFCDeviceError & rE)
1018  {
1019  return rE;
1020  }
1021  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Get normalization date done.", MTL__LOCATION__);
1022 }
1023 
1025 {
1026  try
1027  {
1028  eRemoteBusyLEDmode l_MFC2x46RemoteLedState;
1029  switch (rRBBusyLedState)
1030  {
1032  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kOff;
1033  break;
1035  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kOnWhenMeasuring;
1036  break;
1038  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kClearsAfterMeasurement;
1039  break;
1041  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kOn;
1042  break;
1044  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kBlinkSlow;
1045  break;
1047  l_MFC2x46RemoteLedState = eRemoteBusyLEDmode::kBlinkFast;
1048  break;
1049  default:
1050  MTL_Assert(false);
1051  throw sMFCDeviceError(sMFCDeviceError::eLevel::kFatal, "Unhandled busy led mode", MTL__LOCATION__);
1052  break;
1053  }
1054  if (!m_PT2026.ChannelSetRemoteLEDMode(l_MFC2x46RemoteLedState))
1055  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not set remote box busy led state", MTL__LOCATION__);
1056  }
1057  catch (sMFCDeviceError & rE)
1058  {
1059  return rE;
1060  }
1061  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Set remote box busy led state done.", MTL__LOCATION__);
1062 }
1063 
1065 {
1066  try
1067  {
1068  uOPERationBIT12 l_OPERBIT12_Event;
1070  throw sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "Could not read OPER:BIT12 event register", MTL__LOCATION__);
1071  if (l_OPERBIT12_Event.OPERationBIT12.RemoteBoxStart)
1072  rRemoteStartPressed = true;
1073  else
1074  rRemoteStartPressed = false;
1075  }
1076  catch (sMFCDeviceError & rE)
1077  {
1078  rRemoteStartPressed = false;
1079  return rE;
1080  }
1081  return sMFCDeviceError(sMFCDeviceError::eLevel::kNoError, "Check RemoteBox Status button done.", MTL__LOCATION__);
1082 }
1083 
1085 {
1086  MTL_Unused(rNewSerialSetting)
1087  return sMFCDeviceError(sMFCDeviceError::eLevel::kWarning, "No serial COM port on MFC2x46 device.", MTL__LOCATION__);
1088 }
MTL::CInstrumentCatalog::eNormalizationAccess::kReadROM
@ kReadROM
MTL::Instrument::PT2026Types::kStatusEvent
@ kStatusEvent
Definition: PT2026Types.h:30
MTL::CInstrumentCatalog::tISO8601DateTime
std::string tISO8601DateTime
Definition: InstrumentCatalog.h:28
MTL::CPT2026PeripheralROM::sMultiHeadInfo::MultiHeadInfo
std::vector< sHeadInfo > MultiHeadInfo
Definition: CPT2026PeripheralROM.h:191
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::NormalizationTable
tNormalizationTable NormalizationTable
Definition: CPT2026PeripheralROM.h:220
MTL::CInstrumentCatalog::eNormalizationAccess::kReadRAM
@ kReadRAM
MTL::Instrument::PT2026Types::sStatusRegister
Definition: PT2026Types.h:34
MTL::CInstrumentCatalog::sProbeInformation::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:134
MTL::CInstrumentCatalog::sMeasurementResults::MeasurementList
tMeasurementList MeasurementList
Definition: InstrumentCatalog.h:269
MTL::Instrument::CPT2026Instrument::DeviceROMWrite
bool DeviceROMWrite(const MTL::SCPI::tChannel &rChannel, const std::vector< U8 > &rROMContent)
Definition: PT2026.cpp:3688
MTL::CPT2026PeripheralROM::sIdentification::SN
U32 SN
Definition: CPT2026PeripheralROM.h:46
MTL::CInstrumentCatalog::sProbeArrayInformation::GyroRatio
F64 GyroRatio
Definition: InstrumentCatalog.h:153
MTL::CPT2026PeripheralROM::e9046ROMParm::kManufactureInformation
@ kManufactureInformation
MTL::CInstrumentCatalog::sMeasurement::StdDev
F32 StdDev
Definition: InstrumentCatalog.h:261
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Channel
bool Channel
Definition: PT2026Types.h:621
MTL::CInstrumentCatalog::sInstrumentState::ProbeSelection
sMeasureProbeSelection ProbeSelection
Definition: InstrumentCatalog.h:215
MTL::SCPI::tChannelList
std::vector< tChannel > tChannelList
SCPI channel list
Definition: SCPIParsing.h:26
MTL::Instrument::CPT2026Instrument::ParmSearchSetLimits
bool ParmSearchSetLimits(F64 LowLimit_UNITS, F64 HighLimit_UNITS)
Set the search bounds in the selected unit.
Definition: PT2026.cpp:850
MTL::Instrument::CPT2026Instrument::GetIdentification
bool GetIdentification(std::string &rIdentification)
Returns the instrument identification string including its serial number and make....
Definition: PT2026.cpp:3514
MTL::CInstrumentCatalog::sSearchResult::Freq
F64 Freq
Definition: InstrumentCatalog.h:251
MTL::CInstrumentCatalog::sInstrumentState::RepeatMode
eRepeatMode RepeatMode
Definition: InstrumentCatalog.h:214
MTL::CInstrumentCatalog::sMeasurement
Definition: InstrumentCatalog.h:257
MTL::CInstrumentCatalog::eMeasureSelectionMode::kProbeArray
@ kProbeArray
MTL::CPT2026PeripheralROM::Parser::ParmAddress
bool ParmAddress(U8 ParmNo, U16 &rParmAddress)
Definition: CPT2026PeripheralROM.cpp:187
MTL::CInstrumentCatalog::eMeasureSelectionMode::kSingleProbe
@ kSingleProbe
MTL::CMFC2x46Device::~CMFC2x46Device
virtual ~CMFC2x46Device()
Definition: MFC2x46Device.cpp:44
MTL::CInstrumentCatalog::eRepeatMode::kContinuous
@ kContinuous
LOG
#define LOG(__msg__, __level__, __location__)
Definition: MFC2x46Device.cpp:25
MTL::CMFC2x46Device::Search
sMFCDeviceError Search(const CInstrumentCatalog::sInstrumentState &rInstrState)
Definition: MFC2x46Device.cpp:626
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedBlinkSlow
@ kRemoteBusyLedBlinkSlow
MTL::CPT2026PeripheralROM::sPwPhysicalInformationSet
Definition: CPT2026PeripheralROM.h:112
DIR_SEP
#define DIR_SEP
Definition: MFC2x46Device.cpp:22
MTL::Instrument::PT2026Types::sSearch
Definition: PT2026Types.h:333
MTL::Instrument::PT2026Types::kOff
@ kOff
Definition: PT2026Types.h:508
MTL::Instrument::PT2026Types::kOn
@ kOn
Definition: PT2026Types.h:511
MTL::CMFC2x46Device::Connect
sMFCDeviceError Connect(CInstrumentCatalog::sInstrumentInformation &rInstrInfo)
Definition: MFC2x46Device.cpp:316
MTL::CInstrumentCatalog::sSearchResult::StdDev
F32 StdDev
Definition: InstrumentCatalog.h:252
MTL::CPT2026PeripheralROM::sPwPhysicalInformation
Definition: CPT2026PeripheralROM.h:90
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOffEndMeas
@ kRemoteBusyLedOffEndMeas
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::GyroRatio
F64 GyroRatio
Definition: CPT2026PeripheralROM.h:218
MTL::Instrument::PT2026Types::kBlinkFast
@ kBlinkFast
Definition: PT2026Types.h:513
MTL::Instrument::CPT2026Instrument::ParmUnitsSet
bool ParmUnitsSet(eUnits Units)
Definition: PT2026.cpp:2134
MTL::Instrument::CPT2026Instrument::StatusGet
bool StatusGet(sStatusRegister Reg, U16 &rStatus)
Definition: PT2026.cpp:3196
MTL::Instrument::PT2026Types::eUnits
eUnits
Definition: PT2026Types.h:156
MTL::CInstrumentCatalog::eProbeArrayType::kUnknown
@ kUnknown
MTL::Instrument::PT2026Types::uOPERation::sOPERation::INITiated
U16 INITiated
Definition: PT2026Types.h:109
MTL::CInstrumentCatalog::eNormalizationAccess::kWriteRAM
@ kWriteRAM
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Uniformity
bool Uniformity
Definition: PT2026Types.h:620
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo
Definition: CPT2026PeripheralROM.h:213
MTL::Instrument::PT2026Types::kMeasRepeat
@ kMeasRepeat
Definition: PT2026Types.h:214
MTL::CInstrumentCatalog::sMeasurementResults
Definition: InstrumentCatalog.h:267
MTL::CMFC2x46Device::ScanPA
sMFCDeviceError ScanPA(CInstrumentCatalog::sProbeArrayInformation &rPAInfo, CInstrumentCatalog::sInstrumentConfiguration &rInstrConfig, bool &rPaInfoChanged)
Definition: MFC2x46Device.cpp:358
MTL::CInstrumentCatalog::sFCAInformation::SerialNumber
std::string SerialNumber
Definition: InstrumentCatalog.h:123
MTL::CPT2026PeripheralROM::e9046ROMParm::kPwPhysicalInformationSet
@ kPwPhysicalInformationSet
MTL::CPT2026PeripheralROM::sManufactureInformation::Designation
std::string Designation
Definition: CPT2026PeripheralROM.h:54
MTL::CInstrumentCatalog::sSearchResult
Definition: InstrumentCatalog.h:250
MTL::CInstrumentCatalog::sInstrumentInformation::SerialNumber
std::string SerialNumber
Definition: InstrumentCatalog.h:109
MTL::CPT2026PeripheralROM::sManufactureInformation
Definition: CPT2026PeripheralROM.h:52
MTL::CInstrumentCatalog::sMeasurement::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:258
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:150
MTL::CInstrumentCatalog::sMeasureProbeSelection::SelectionMode
eMeasureSelectionMode SelectionMode
Definition: InstrumentCatalog.h:199
MTL::Instrument::PT2026Types::uOPERationBIT12::OPERationBIT12
struct MTL::Instrument::PT2026Types::uOPERationBIT12::sOPERationBIT12 OPERationBIT12
MTL::Instrument::CPT2026Instrument::NormalizationSet
bool NormalizationSet(const MTL::SCPI::tChannel &rChannel, const tNormalizationTable &rNormalizationTable)
Definition: PT2026.cpp:3740
MTL::Instrument::CPT2026Instrument::Initiate
bool Initiate(bool Continuous=false)
Starts the search operation and then immediately after NMR resonance detection proceed to NMR measure...
Definition: PT2026.cpp:2673
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqCentral
F64 FreqCentral
Definition: InstrumentCatalog.h:152
MTL::Instrument::PT2026Types::sAdvancedMeasurements::Basic
std::vector< sBasicMeasurement > Basic
Definition: PT2026Types.h:567
MFC2x46Device.h
MTL::CPT2026PeripheralROM::e9046ROMParm::kMeasHeads
@ kMeasHeads
MTL::CPT2026PeripheralROM::sIdentification::Model
U16 Model
Definition: CPT2026PeripheralROM.h:45
MTL::CInstrumentCatalog::sProbeArrayInformation::Type
eProbeArrayType Type
Definition: InstrumentCatalog.h:146
MTL::Instrument::PT2026Types::sMeasurementAveraging
Definition: PT2026Types.h:217
MTL::SCPI::tChannel
std::vector< unsigned char > tChannel
SCPI channel
Definition: SCPIParsing.h:25
MTL::Instrument::PT2026Types::uOPERationBIT12::sOPERationBIT12::RemoteBoxStart
U16 RemoteBoxStart
Definition: PT2026Types.h:148
MTL::CInstrumentCatalog::sInstrumentInformation::Description
std::string Description
Definition: InstrumentCatalog.h:110
MTL::CInstrumentCatalog::eLogLevel::kDebug
@ kDebug
MTL::CInstrumentCatalog::sMeasurement::Freq
F64 Freq
Definition: InstrumentCatalog.h:259
MTL::Instrument::PT2026Types::kOnWhenMeasuring
@ kOnWhenMeasuring
Definition: PT2026Types.h:509
MTL::CMFC2x46Device::GetNormalizationDate
sMFCDeviceError GetNormalizationDate(CInstrumentCatalog::tISO8601DateTime &rNormDate)
Definition: MFC2x46Device.cpp:979
MTL::CInstrumentCatalog::sProbeInformation::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:133
MTL::CPT2026PeripheralROM::Parser::ParsePwCamPhysInfo
bool ParsePwCamPhysInfo(size_t ParmAddress, sPwCamPhysicalInfo &rPhysInfo)
Definition: CPT2026PeripheralROM.cpp:399
MTL::CInstrumentCatalog::sNormalization::Access
eNormalizationAccess Access
Definition: InstrumentCatalog.h:283
MTL::Instrument::CPT2026Instrument::ParmRFPulseGet
bool ParmRFPulseGet(sPulse< uParm > &rPulse)
Definition: PT2026.cpp:1834
CPT2026PeripheralROM.h
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::NominalFreq
F64 NominalFreq
Definition: CPT2026PeripheralROM.h:216
MTL::CPT2026PeripheralROM::sIdentification
Definition: CPT2026PeripheralROM.h:41
date::format
auto format(const std::locale &loc, const CharT *fmt, const Streamable &tp) -> decltype(to_stream(std::declval< std::basic_ostream< CharT > & >(), fmt, tp), std::basic_string< CharT >
Definition: date.h:6005
MTL::CPT2026PeripheralROM::Parser
Definition: CPT2026PeripheralROM.h:310
MTL_Assert
#define MTL_Assert
Definition: Helpers.h:44
MTL::CInstrumentCatalog::sInstrumentState
Definition: InstrumentCatalog.h:212
MTL::CMFC2x46Device::SetRBBusyLedState
sMFCDeviceError SetRBBusyLedState(const CInstrumentCatalog::eRemoteBoxBusyLedState &rRBBusyLedState)
Definition: MFC2x46Device.cpp:1024
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Flux
bool Flux
Definition: PT2026Types.h:618
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::NormalizationDate
std::string NormalizationDate
Definition: CPT2026PeripheralROM.h:219
MTL::Instrument::CPT2026Instrument::ChannelsSelect
bool ChannelsSelect(const MTL::SCPI::tChannelList &rChanList)
Definition: PT2026.cpp:479
MTL::CMFCDevice::sMFCDeviceError
Definition: MFCDevice.h:30
MTL::Instrument::PT2026Types::sPulse
Definition: PT2026Types.h:319
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOff
@ kRemoteBusyLedOff
MTL::CPT2026PeripheralROM::e9046ROMParm::kMultiHeadInformation
@ kMultiHeadInformation
MTL::CMFCDevice::sMFCDeviceError::Level
enum MTL::CMFCDevice::sMFCDeviceError::eLevel Level
MTL::CInstrumentCatalog::sProbeArrayInformation::Description
std::string Description
Definition: InstrumentCatalog.h:148
MTL::CInstrumentCatalog::sMFC3045SerialPortSettings
Definition: InstrumentCatalog.h:81
MTL::Instrument::PT2026Types::kClearsAfterMeasurement
@ kClearsAfterMeasurement
Definition: PT2026Types.h:510
date.h
MTL::Instrument::CPT2026Instrument::Connect
bool Connect(U32 InitialTimeout_ms)
Definition: PT2026.cpp:274
MTL::CInstrumentCatalog::sInstrumentState::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:217
MTL::Instrument::PT2026Types::uOPERation::sOPERation::SWEeping
U16 SWEeping
Definition: PT2026Types.h:103
MTL::CInstrumentCatalog::eLogLevel::kWarning
@ kWarning
MTL::CInstrumentCatalog::eNormalizationAccess::kWriteROM
@ kWriteROM
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState
eRemoteBoxBusyLedState
Definition: InstrumentCatalog.h:242
MTL::Instrument::PT2026Types::kStatusOperation
@ kStatusOperation
Definition: PT2026Types.h:24
MTL::CInstrumentCatalog::sInstrumentInformation::CalibrationDate
tISO8601DateTime CalibrationDate
Definition: InstrumentCatalog.h:111
MTL::CInstrumentCatalog::eInstrumentType::kPT2026
@ kPT2026
MTL::Instrument::PT2026Types::uOPERationBIT12
Definition: PT2026Types.h:138
MTL::CPT2026PeripheralROM::e9046ROMParm::kSearchHeads
@ kSearchHeads
MTL::CMFC2x46Device::Measure
sMFCDeviceError Measure(const CInstrumentCatalog::sInstrumentState &rInstrState)
Definition: MFC2x46Device.cpp:726
MTL::Instrument::PT2026Types::kStatusOperationBit12
@ kStatusOperationBit12
Definition: PT2026Types.h:26
MTL::CInstrumentCatalog::sProbeInformation::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:132
MTL::Instrument::PT2026Types::uOPERation::sOPERation::NewMeasAvail
U16 NewMeasAvail
Definition: PT2026Types.h:108
MTL::Instrument::PT2026Types::kStatusCondition
@ kStatusCondition
Definition: PT2026Types.h:31
MTL::CPT2026PeripheralROM::Parser::ParseManufactureInformation
bool ParseManufactureInformation(size_t ParmAddress, sManufactureInformation &rManuInfo)
Definition: CPT2026PeripheralROM.cpp:328
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Deviation
bool Deviation
Definition: PT2026Types.h:619
MTL::Instrument::PT2026Types::sMeasurementAveraging::NoPoints
ParmType< U32 > NoPoints
Definition: PT2026Types.h:219
MTL::CPT2026PeripheralROM::tHeadList
std::vector< U8 > tHeadList
Definition: CPT2026PeripheralROM.h:194
MTL::Instrument::CPT2026Instrument::DeviceROMRead
bool DeviceROMRead(const MTL::SCPI::tChannel &rChannel, std::vector< U8 > &rROMContent)
Definition: PT2026.cpp:3657
MTL::CInstrumentCatalog::eProbeArrayType::kMFC9146
@ kMFC9146
MTL::Instrument::PT2026Types::eRemoteBusyLEDmode
eRemoteBusyLEDmode
Definition: PT2026Types.h:507
MTL::CInstrumentCatalog::sProbeArrayInformation
Definition: InstrumentCatalog.h:145
MTL::CInstrumentCatalog::sInstrumentInformation::Type
eInstrumentType Type
Definition: InstrumentCatalog.h:108
MTL::Instrument::PT2026Types::sArbitraryMeasurements
Definition: PT2026Types.h:617
MTL::CInstrumentCatalog::sMeasureProbeSelection::ProbeNumber
U8 ProbeNumber
Definition: InstrumentCatalog.h:200
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedBlinkFast
@ kRemoteBusyLedBlinkFast
MTL::CPT2026PeripheralROM::Parser::ParseMultiHeadInfo
bool ParseMultiHeadInfo(size_t ParmAddress, sMultiHeadInfo &rMultiHeadInfo)
Definition: CPT2026PeripheralROM.cpp:350
MTL::Instrument::CPT2026Instrument::GetSearchProgress
bool GetSearchProgress(U8 &rSPR, F64 &rHallMeasurement_UNITS)
Definition: PT2026.cpp:3124
MTL::Instrument::PT2026Types::sAllMeasurements
Definition: PT2026Types.h:633
MTL::CInstrumentCatalog::sProbeInformation
Definition: InstrumentCatalog.h:131
MTL::Instrument::PT2026Types::uOPERation
Definition: PT2026Types.h:97
MTL::Instrument::PT2026Types::kBlinkSlow
@ kBlinkSlow
Definition: PT2026Types.h:512
MTL::CPT2026PeripheralROM::e9046ROMParm::kPwCamPhysicalInformation
@ kPwCamPhysicalInformation
MTL::Instrument::CPT2026Instrument::ChannelsSetLimitedListState
bool ChannelsSetLimitedListState(bool State)
Definition: PT2026.cpp:433
MTL::CMFC2x46Device::NewNormalizationRequest
sMFCDeviceError NewNormalizationRequest(const CInstrumentCatalog::sNormalization &rNewNormalizationRequest, CInstrumentCatalog::sNormalization &rReturnedNormalization)
Definition: MFC2x46Device.cpp:837
MTL::Instrument::CPT2026Instrument::ChannelsGetList
bool ChannelsGetList(MTL::SCPI::tChannelList &rChanList)
Definition: PT2026.cpp:353
MTL::CInstrumentCatalog::sMeasurementResults::Timestamp
U64 Timestamp
Definition: InstrumentCatalog.h:268
MTL::CPT2026PeripheralROM::Parser::ParsePwPhysInfoSet
bool ParsePwPhysInfoSet(size_t ParmAddress, sPwPhysicalInformationSet &rPwPhysInfoSet)
Definition: CPT2026PeripheralROM.cpp:479
MTL::Instrument::PT2026Types::sMeasurementAveraging::Type
eMeasurementAveragingType Type
Definition: PT2026Types.h:218
MTL::Instrument::PT2026Types::uOPERation::RawOPER
U16 RawOPER
Definition: PT2026Types.h:98
MTL::CMFC2x46Device::ChangeSerialParmsOnConnectedInstr
sMFCDeviceError ChangeSerialParmsOnConnectedInstr(const CInstrumentCatalog::sMFC3045SerialPortSettings &rNewSerialSetting)
Definition: MFC2x46Device.cpp:1084
MTL::CInstrumentCatalog::sFCAInformation::FCAFwVersion
U16 FCAFwVersion
Definition: InstrumentCatalog.h:125
MTL::CInstrumentCatalog::eProbeArrayType::kMFC9046
@ kMFC9046
MTL::CPT2026PeripheralROM::Parser::Parse
bool Parse()
Definition: CPT2026PeripheralROM.cpp:136
MTL::CPT2026PeripheralROM::sPwPhysicalInformation::MaxFreq
F64 MaxFreq
Definition: CPT2026PeripheralROM.h:93
MTL::Instrument::PT2026Types::uOPERation::OPERation
struct MTL::Instrument::PT2026Types::uOPERation::sOPERation OPERation
MTL::Instrument::tResourceName
std::string tResourceName
Definition: VISAInstrumentTypes.h:21
MTL::CInstrumentCatalog::sInstrumentState::NbAveragedMeasurements
U32 NbAveragedMeasurements
Definition: InstrumentCatalog.h:218
MTL::Instrument::CPT2026Instrument::NormalizationGet
bool NormalizationGet(const MTL::SCPI::tChannel &rChannel, tNormalizationTable &rNormalizationTable)
Definition: PT2026.cpp:3708
MTL::CMFC2x46Device::RemoteBoxButtonStatus
sMFCDeviceError RemoteBoxButtonStatus(bool &rRemoteStartPressed)
Definition: MFC2x46Device.cpp:1064
MTL::CMFCController
Definition: MFCController.h:34
MTL::CInstrumentCatalog::sInstrumentState::OperatingMode
eOperatingMode OperatingMode
Definition: InstrumentCatalog.h:213
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedMeasuring
@ kRemoteBusyLedMeasuring
MTL::Instrument::PT2026Types::kPwCamera
@ kPwCamera
Definition: PT2026Types.h:397
MTL::Instrument::CPT2026Instrument::ParmAveragingMeasurementSet
bool ParmAveragingMeasurementSet(const sMeasurementAveraging< uParm > &rMeasAvg)
Definition: PT2026.cpp:1218
MTL::Instrument::CPT2026Instrument::MeasurementsGet
bool MeasurementsGet(U32 NoMeasurements, std::vector< tFlux > &rFlux, eUnits &rUnits)
Returns the NMR magnetic field density measurements, including the unit used. A measurement vector is...
Definition: PT2026.cpp:2711
MTL::Instrument::CPT2026Instrument::ChannelsGetInfo
bool ChannelsGetInfo(const MTL::SCPI::tChannelList &rChanList, std::vector< sChannelIformation > &rChanInfo)
Definition: PT2026.cpp:500
MTL::Instrument::CPT2026Instrument::ChannelSetRemoteLEDMode
bool ChannelSetRemoteLEDMode(eRemoteBusyLEDmode Mode)
Definition: PT2026.cpp:686
MTL::Instrument::PT2026Types::sAllMeasurements::AdvMeas
sAdvancedMeasurements AdvMeas
Definition: PT2026Types.h:634
MTL::CPT2026PeripheralROM::Parser::ParseHeadList
bool ParseHeadList(size_t ParmAddress, tHeadList &rHeadList)
Definition: CPT2026PeripheralROM.cpp:381
MTL::CInstrumentCatalog::sProbeArrayInformation::NormalizationDate
tISO8601DateTime NormalizationDate
Definition: InstrumentCatalog.h:149
MTL::CMFC2x46Device::AbortInstrument
bool AbortInstrument()
Definition: MFC2x46Device.cpp:296
MTL::CPT2026PeripheralROM::Builder::Build9046ROM
static void Build9046ROM(std::vector< U8 > &rOutputROM, const CPT2026PeripheralROM::sIdentification &rIdentification, const CPT2026PeripheralROM::sManufactureInformation &rManInfo, const CPT2026PeripheralROM::sMultiHeadInfo &rMultiHeadInfo, const CPT2026PeripheralROM::tHeadList &rSearchHeadList, const CPT2026PeripheralROM::tHeadList &rMeasHeadList, const CPT2026PeripheralROM::sPwCamPhysicalInfo &rPwCamPhysInfo, const CPT2026PeripheralROM::sPwPhysicalInformationSet &rPwPhysInfoSet)
Definition: CPT2026PeripheralROM.cpp:878
MTL::CInstrumentCatalog::sProbeArrayInformation::SerialNumber
std::string SerialNumber
Definition: InstrumentCatalog.h:147
MTL::Instrument::PT2026Types::CExtendedChannelList
Definition: PT2026Types.h:446
MTL::CInstrumentCatalog::sInstrumentInformation
Definition: InstrumentCatalog.h:106
MTL::CInstrumentCatalog::eOperatingMode::kSearch
@ kSearch
MTL::Instrument::CPT2026Instrument::Abort
bool Abort(bool CancelContinuous=true)
Abort the current operation (Search or measure). Once the operation is aborted, the instrument will b...
Definition: PT2026.cpp:2682
MTL::CPT2026PeripheralROM::sPwPhysicalInformation::MinFreq
F64 MinFreq
Definition: CPT2026PeripheralROM.h:92
MTL::Instrument::CPT2026Instrument::WriteCustomCommand
bool WriteCustomCommand(const std::string &rWriteStr)
Definition: PT2026.cpp:3792
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Status
bool Status
Definition: PT2026Types.h:623
Exception.h
Exception handling utilities.
MTL::CInstrumentCatalog::sInstrumentState::FreqMin
F64 FreqMin
Definition: InstrumentCatalog.h:216
MTL::CInstrumentCatalog::sNormalization::Table
tNormalizationTable Table
Definition: InstrumentCatalog.h:284
MTL::Instrument::CPT2026Instrument::ParmSearchGet
bool ParmSearchGet(sSearch< uParm > &rSearch)
Definition: PT2026.cpp:728
MTL::CInstrumentCatalog::eRemoteBoxBusyLedState::kRemoteBusyLedOn
@ kRemoteBusyLedOn
MTL::Instrument::PT2026Types::uOPERationBIT12::RawOPER12
U16 RawOPER12
Definition: PT2026Types.h:139
MTL::CPT2026PeripheralROM::Parser::HasIdentification
bool HasIdentification(sIdentification &rID)
Definition: CPT2026PeripheralROM.cpp:173
MTL::Instrument::PT2026Types::sArbitraryMeasurements::NbValidMeas
bool NbValidMeas
Definition: PT2026Types.h:624
MTL::Instrument::PT2026Types::sPulse::Period_s
ParmType< F64 > Period_s
Definition: PT2026Types.h:321
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::HighFreq
F64 HighFreq
Definition: CPT2026PeripheralROM.h:217
MTL::CPT2026PeripheralROM::sMultiHeadInfo
Definition: CPT2026PeripheralROM.h:185
MTL::Instrument::CPT2026Instrument::ReadInformationDates
bool ReadInformationDates(std::string &rSManufacturingDate, std::time_t &rManufacturingDate, std::string &rSCalibrationDate, std::time_t &rCalibrationDate)
Returns the manufacturing and calibration date in plain text or a number representing the amount of s...
Definition: PT2026.cpp:3598
MTL::CInstrumentCatalog::sProbeArrayInformation::FCAInfo
sFCAInformation FCAInfo
Definition: InstrumentCatalog.h:155
MTL::CMFC2x46Device::IsInstrumentConnected
bool IsInstrumentConnected()
Definition: MFC2x46Device.cpp:306
MTL_Unused
#define MTL_Unused(x)
Definition: Helpers.h:47
MTL::CInstrumentCatalog::sFCAInformation
Definition: InstrumentCatalog.h:122
MTL::CInstrumentCatalog::sMeasurement::NbValidMeasurements
U32 NbValidMeasurements
Definition: InstrumentCatalog.h:260
MTL::CInstrumentCatalog::eLogLevel::kInfo
@ kInfo
MTL::CInstrumentCatalog::sFCAInformation::Description
std::string Description
Definition: InstrumentCatalog.h:124
MTL::Instrument::PT2026Types::sArbitraryMeasurements::Timestamp
bool Timestamp
Definition: PT2026Types.h:622
MTL::Instrument::CVISAResourceManager
VISA Resource Manager class.
Definition: VISAInstrument.h:35
MTL::CPT2026PeripheralROM::sPwCamPhysicalInfo::LowFreq
F64 LowFreq
Definition: CPT2026PeripheralROM.h:215
MTL::CInstrumentCatalog::sInstrumentConfiguration
Definition: InstrumentCatalog.h:116
MTL::Instrument::PT2026Types::kMeasNone
@ kMeasNone
Definition: PT2026Types.h:211
MTL__LOCATION__
#define MTL__LOCATION__
Definition: Helpers.h:22
MTL::CInstrumentCatalog::sNormalization
Definition: InstrumentCatalog.h:282
MTL::Instrument::PT2026Types::tNormalizationTable
std::vector< tNormalizationFactor_Hz > tNormalizationTable
Definition: PT2026Types.h:667
MTL::CInstrumentCatalog::sProbeArrayInformation::FreqMax
F64 FreqMax
Definition: InstrumentCatalog.h:151
MTL::CInstrumentCatalog::sProbeArrayInformation::ProbeList
std::vector< sProbeInformation > ProbeList
Definition: InstrumentCatalog.h:154
MTL::Instrument::PT2026Types::kPwMultiplexer
@ kPwMultiplexer
Definition: PT2026Types.h:399
MTL::CInstrumentCatalog::sInstrumentConfiguration::AcquisitionPeriod
F64 AcquisitionPeriod
Definition: InstrumentCatalog.h:117
MTL::Instrument::PT2026Types::kPwFCA
@ kPwFCA
Definition: PT2026Types.h:400