26 #define DEBUG_MTL_INSTRUMENT_THM1176 1
27 #define DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY 0
28 #if (defined(_DEBUG) && defined(DEBUG_MTL_INSTRUMENT_THM1176) && DEBUG_MTL_INSTRUMENT_THM1176)
29 #if (defined(DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY) && DEBUG_MTL_INSTRUMENT_THM1176_ERRORS_ONLY)
30 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__)
32 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__) std::cout << __X__
34 #define MTL_INSTRUMENT_THM1176_DEBUG_CERR(__X__) std::cerr << __X__
36 #define MTL_INSTRUMENT_THM1176_DEBUG_COUT(__X__)
37 #define MTL_INSTRUMENT_THM1176_DEBUG_CERR(__X__)
54 {
"",
"",
":STAT:QUES:ENAB" },
55 {
"",
"",
":STAT:OPER:ENAB" }
60 {
"*STB?",
"",
"*SRE?" },
61 {
"*ESR?",
"",
"*ESE?" },
62 {
":STAT:QUES:EVEN?",
":STAT:QUES:COND?",
":STAT:QUES:ENAB?" },
63 {
":STAT:OPER:EVEN?",
":STAT:OPER:COND?",
":STAT:OPER:ENAB?" }
68 std::string(
"TFM1186")
84 static std::string
l_ToString(
F32 number,
int precision = 7,
const char * locale =
"C")
86 std::locale l_locale = std::locale(locale);
87 std::ostringstream l_oss;
89 l_oss.imbue(l_locale);
90 l_oss << std::scientific << std::setprecision(precision);
96 static std::string
l_ToString(
F64 number,
int precision = 15,
const char * locale =
"C")
98 std::locale l_locale = std::locale(locale);
99 std::ostringstream l_oss;
101 l_oss.imbue(l_locale);
102 l_oss << std::scientific << std::setprecision(precision);
114 size_t l_Comma = rErrStr.find_first_of(
',');
115 rError.
Code = std::stoi(rErrStr.substr(0, l_Comma));
117 size_t l_OpenQuote = rErrStr.find_first_of(
'"', l_Comma + 1);
118 size_t l_CloseQuote = rErrStr.find_last_of(
'"');
119 rError.
Description = rErrStr.substr(l_OpenQuote + 1, l_CloseQuote - (l_OpenQuote + 1));
125 std::vector<std::string> lErrorList;
126 if (rE.code() & std::regex_constants::error_badrepeat)
127 lErrorList.push_back (
"error_badrepeat");
128 if (rE.code() & std::regex_constants::error_ctype)
129 lErrorList.push_back (
"error_ctype");
130 if (rE.code() & std::regex_constants::error_escape)
131 lErrorList.push_back (
"error_escape");
132 if (rE.code() & std::regex_constants::error_backref)
133 lErrorList.push_back (
"error_backref");
134 if (rE.code() & std::regex_constants::error_brack)
135 lErrorList.push_back (
"error_brack");
136 if (rE.code() & std::regex_constants::error_paren)
137 lErrorList.push_back (
"error_paren");
138 if (rE.code() & std::regex_constants::error_brace)
139 lErrorList.push_back (
"error_brace");
140 if (rE.code() & std::regex_constants::error_badbrace)
141 lErrorList.push_back (
"error_badbrace");
142 if (rE.code() & std::regex_constants::error_range)
143 lErrorList.push_back (
"error_range");
144 if (rE.code() & std::regex_constants::error_space)
145 lErrorList.push_back (
"error_space");
146 if (rE.code() & std::regex_constants::error_badrepeat)
147 lErrorList.push_back (
"error_badrepeat");
148 if (rE.code() & std::regex_constants::error_complexity)
149 lErrorList.push_back (
"error_complexity");
150 if (rE.code() & std::regex_constants::error_stack)
151 lErrorList.push_back (
"error_stack");
153 std::string lErrors = lErrorList.front();
154 for (
auto lpError = lErrorList.begin() + 1; lpError < lErrorList.end(); lpError++)
155 lErrors +=
" | " + *lpError;
162 template <
class InstrType,
class RsrcMgrType>
170 if (!WriteAndRead(
"*IDN?", m_ReadBuffer))
173 rIdentification = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
178 rIdentification.clear();
184 template <
class InstrType,
class RsrcMgrType>
191 std::regex l_Regex(
"([^,]+),([^,]+),([^,]+),([^,]+)");
193 if (!std::regex_match(m_Identification, l_Match, l_Regex))
197 rIdentification.
Model = l_Match[2].str();
198 rIdentification.
SerialNumber =
static_cast<U32>(stoul(l_Match[3].str()));
200 std::string l_Versions = l_Match[4].str();
201 l_Regex =
"el(([A-Z])([0-9]+))-pr(([A-Z])([0-9]+))-fw(([0-9]+)\\.([0-9]+))\\n";
202 if (!std::regex_match(l_Versions, l_Match, l_Regex))
222 catch (std::regex_error& rE)
230 template <
class InstrType,
class RsrcMgrType>
240 if (!InstrType::ReadSTB(l_STB.
RawSTB))
248 enum eRetry { kRetryErrorRetrieving };
251 if (!InstrType::Write(
":SYST:ERR?"))
252 throw kRetryErrorRetrieving;
253 if (!InstrType::Read(l_Error))
254 throw kRetryErrorRetrieving;
256 catch (eRetry & rRetry)
258 if (rRetry == kRetryErrorRetrieving)
261 if (!InstrType::Clear())
264 if (!InstrType::Write(
":SYST:ERR?"))
266 if (!InstrType::Read(l_Error))
271 std::string l_ErrStr = std::string(l_Error.data(), l_Error.size());
274 rList.push_back(l_Err);
276 if (!InstrType::ReadSTB(l_STB.
RawSTB))
286 #if (defined(_DEBUG))
287 for (
auto it = rList.begin(); it != rList.end(); it++)
289 CERR(
"THM1176Error " << it->Code <<
" : " << it->Description <<
" in " << it->Context << std::endl);
295 template <
class InstrType,
class RsrcMgrType>
301 bool l_InitialLockState = InstrType::LockedExclusive();
308 if (!l_InitialLockState && !InstrType::LockExclusive(m_Timeout))
313 bool l_OPCAppended = !std::regex_match(rWriteStr, std::regex(
"\\*IDN\\?"));
316 l_Query = rWriteStr +
";*OPC?";
321 if (!InstrType::Write(l_Query))
326 if (!InstrType::ReadSTB(l_STB.
RawSTB))
333 bool l_Timeout =
false;
340 if (InstrType::Read(rReadBuffer,
true))
346 l_Timeout = InstrType::Timeout();
351 if (!InstrType::ReadSTB(l_STB.
RawSTB))
362 std::size_t l_MaxSizeToMatch = std::strlen(
";1\n");
363 std::match_results<std::vector<char>::iterator> m;
365 if (std::regex_match((rReadBuffer.
size() <= l_MaxSizeToMatch) ? rReadBuffer.
begin() : rReadBuffer.
end() - l_MaxSizeToMatch, rReadBuffer.
end(), m, std::regex(
";?1\\n?$")))
366 rReadBuffer.
resize(rReadBuffer.
size() - m.length());
370 if (!l_InitialLockState && !InstrType::Unlock())
380 InstrType::Write(
":ABOR");
387 InstrType::Read(rReadBuffer,
true);
390 GetErrorList(m_ErrorList, rWriteStr);
393 if (!l_InitialLockState) InstrType::Unlock();
400 catch (std::regex_error& rE)
408 template <
class InstrType,
class RsrcMgrType>
417 if (!WriteAndRead(
"*RST;:INIT;:FETC:TIM?", m_ReadBuffer))
419 std::string l_TimestampString(m_ReadBuffer.begin(), m_ReadBuffer.end());
420 U64 l_Timestamp = std::stoull(l_TimestampString,
nullptr, 0);
424 std::time_t l_CurrentTime = std::time(
nullptr);
438 template <
class InstrType,
class RsrcMgrType>
446 if (!WriteAndRead(
":SENS:ALL?", m_ReadBuffer))
451 if (l_Tokens.size() < 1)
456 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
458 std::string l_StrRange(it->begin, it->end - 2);
461 rRanges.push_back(std::stof(l_StrRange));
463 catch (
const std::invalid_argument& ia)
478 template <
class InstrType,
class RsrcMgrType>
486 if (!WriteAndRead(
":UNIT:ALL?", m_ReadBuffer))
491 if (l_Tokens.size() < 2 || (l_Tokens.size() % 2) == 1)
496 for (
auto it = l_Tokens.begin(); it != l_Tokens.end(); it++)
498 std::string l_StrUnit(it->begin, it->end);
500 std::string l_StrDivisor(it->begin, it->end);
504 U32 l_Divisor =
static_cast<U32>(std::stoul(l_StrDivisor));
505 rAllUnits.insert(std::pair<eUnits, U32>(l_Units, l_Divisor));
517 template <
class InstrType,
class RsrcMgrType>
525 if (!WriteAndRead(
":CAL:STAT?", m_ReadBuffer))
528 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
529 if (l_Answer ==
"ON")
531 else if (l_Answer ==
"OFF")
544 template <
class InstrType,
class RsrcMgrType>
549 std::string l_CalFileContent;
556 rDate = std::string(l_CalFileContent, 100, 10);
568 template <
class InstrType,
class RsrcMgrType>
573 std::string l_CalFileContent;
580 rCalibrationDate = std::string(l_CalFileContent, 64, 10);
583 char * l_pMatrix =
const_cast<char *
>(l_CalFileContent.c_str());
594 I32 l_IntMatrix[3][3];
595 for (
int i = 0; i < 3; i++)
596 for (
int j = 0; j < 3; j++)
599 l_pMatrix +=
sizeof (
I32);
603 const F32 l_C =
static_cast<F32>(0x7FFFFFFF);
604 rMatrix << l_IntMatrix[0][0]/l_C, l_IntMatrix[0][1]/l_C, l_IntMatrix[0][2]/l_C,
605 l_IntMatrix[1][0]/l_C, l_IntMatrix[1][1]/l_C, l_IntMatrix[1][2]/l_C,
606 l_IntMatrix[2][0]/l_C, l_IntMatrix[2][1]/l_C, l_IntMatrix[2][2]/l_C;
611 rCalibrationDate =
"";
617 template <
class InstrType,
class RsrcMgrType>
623 if (!m_UseCalibration)
627 Vector3f l_B(rBx, rBy, rBz);
628 l_B = m_RotationMatrix * l_B;
642 template <
class InstrType,
class RsrcMgrType>
648 if (!m_UseCalibration)
652 if (rBx.size() != rBy.size() || rBx.size() != rBz.size())
658 for (
auto l_pBx = rBx.begin(), l_pBy = rBy.begin(), l_pBz = rBz.begin();
660 l_pBx++, l_pBy++, l_pBz++)
662 Vector3f l_B(*l_pBx, *l_pBy, *l_pBz);
663 l_B = m_RotationMatrix * l_B;
677 template <
class InstrType,
class RsrcMgrType>
684 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
685 if (!rBP.
GetNext(l_tokenbeg, l_tokenend,
';'))
696 tFlux l_DivisorReal = 1.;
697 if (m_UseCalibration)
698 l_DivisorReal =
static_cast<tFlux>(m_Units.at(Units));
701 if (l_tokenbeg[1] ==
'6')
704 l_len >= 4 && rMeas.size() < NoMeasurements;
705 l_len -= 4, l_off += 4)
708 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
713 else if (l_tokenbeg[1] ==
'5')
716 size_t l_Pack = (l_tokenbeg[l_off] ==
'1') ? 1 :
717 (l_tokenbeg[l_off] ==
'2') ? 2 : 0;
724 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
727 for (l_len -= 4, l_off += 4;
728 l_len >= l_Pack && rMeas.size() < NoMeasurements;
729 l_len -= l_Pack, l_off += l_Pack)
732 l_MeasI32 +=
static_cast<I8>(*(&*l_tokenbeg + l_off));
735 rMeas.push_back(
static_cast<tFlux>(l_MeasI32) / l_DivisorReal);
746 std::vector<char>::const_iterator l_measbeg, l_measend;
748 for (l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
',');
749 l_GetNextRet && rMeas.size() < NoMeasurements;
750 l_GetNextRet = l_FluxParser.GetNext(l_measbeg, l_measend,
','))
752 std::string l_Measurement(l_measbeg, l_measend);
753 rMeas.push_back(std::stof(l_Measurement));
758 if (rMeas.size() != NoMeasurements)
773 template <
class InstrType,
class RsrcMgrType>
775 : InstrType(rResourceManager, ResourceName),
776 m_Timeout(0), m_ReadBuffer(65535), m_Sleep(false), m_UseCalibration(true), m_AbortRead(false)
780 template <
class InstrType,
class RsrcMgrType>
783 if (InstrType::IsOpen())
793 template <
class InstrType,
class RsrcMgrType>
799 template <
class InstrType,
class RsrcMgrType>
811 template <
class InstrType,
class RsrcMgrType>
828 m_Timeout = InitialTimeout;
829 if (!InstrType::Open())
831 if (Exclusive && !InstrType::LockExclusive(m_Timeout))
833 if (!InstrType::Clear())
835 if (!WriteAndRead(
"*CLS", m_ReadBuffer))
837 if (!ReadIdentification(m_Identification))
839 if (!ParseIdentification(m_IdentificationStruct))
841 if (m_IdentificationStruct.FirmwareVersion.Major < l_MinMajor || m_IdentificationStruct.FirmwareVersion.Minor < l_MinMinor ||
842 m_IdentificationStruct.FirmwareVersion.Major > l_MaxMajor || m_IdentificationStruct.FirmwareVersion.Minor > l_MaxMinor)
844 if (!ReadBootTime(m_BootTime))
846 if (!ReadAllUnits(m_Units))
848 if (!ReadAllRanges(m_Ranges))
850 if (!ReadManufacturingDate(m_ManufacturingDate))
852 if (!ReadRotationMatrix(m_RotationMatrix, m_CalibrationDate))
854 if (!ReadUseCalibration(m_UseCalibration))
856 if (!ParmUnitsGet(m_UnitsParms))
858 if (!ParmAveragingGet(m_AveragingParms))
860 if (!ParmTriggerInputGet(m_TriggerParms))
862 if (!ParmRangeGet(m_RangeParms))
864 if (!GetFormat(m_Format))
871 if (InstrType::IsOpen())
878 template <
class InstrType,
class RsrcMgrType>
884 if (InstrType::IsOpen())
891 template <
class InstrType,
class RsrcMgrType>
897 std::string l_Command =
":AVER:COUN " + std::to_string(rAvg.
NoPoints);
898 bool l_Success = WriteAndRead(l_Command, m_ReadBuffer);
899 if (l_Success) m_AveragingParms = rAvg;
903 template <
class InstrType,
class RsrcMgrType>
911 if (!WriteAndRead(
":AVER:COUN?", m_ReadBuffer))
914 rAvg.
NoPoints =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
924 template <
class InstrType,
class RsrcMgrType>
932 if (!WriteAndRead(
":AVER:COUN?;:AVER:COUN? MIN;:AVER:COUN? MAX;:AVER:COUN? DEF", m_ReadBuffer))
937 if (l_Tokens.size() != 4)
940 rAvg.
NoPoints.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[0].begin, l_Tokens[0].end)));
941 rAvg.
NoPoints.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[1].begin, l_Tokens[1].end)));
942 rAvg.
NoPoints.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
943 rAvg.
NoPoints.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[3].begin, l_Tokens[3].end)));
953 template <
class InstrType,
class RsrcMgrType>
963 template <
class InstrType,
class RsrcMgrType>
973 template <
class InstrType,
class RsrcMgrType>
979 std::string l_Command =
":TRIG:SOUR ";
980 switch (rInputTrig.
Source)
984 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
988 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
993 l_Command +=
";COUN " + std::to_string(rInputTrig.
Count);
997 if (WriteAndRead(l_Command, m_ReadBuffer))
999 m_TriggerParms = rInputTrig;
1005 ParmTriggerInputGet(m_TriggerParms);
1006 m_ErrorList = l_ErrorList;
1011 template <
class InstrType,
class RsrcMgrType>
1019 if (!WriteAndRead(
":TRIG:SOUR?"
1027 if (l_Tokens.size() != 3)
1031 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1032 if (l_Source ==
"IMMEDIATE")
1034 else if (l_Source ==
"TIMER")
1036 else if (l_Source ==
"BUS")
1042 rInputTrig.
Period_s = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1045 rInputTrig.
Count =
static_cast<U16>(std::stoi(std::string(l_Tokens[2].begin, l_Tokens[2].end)));
1055 template <
class InstrType,
class RsrcMgrType>
1063 if (!WriteAndRead(
":TRIG:SOUR?"
1064 ";TIM?;TIM? MIN;TIM? MAX;TIM? DEF"
1065 ";COUN?;COUN? MIN;COUN? MAX;COUN? DEF",
1071 if (l_Tokens.size() != 9)
1075 std::string l_Source(l_Tokens[0].begin, l_Tokens[0].end);
1076 if (l_Source ==
"IMMEDIATE")
1078 else if (l_Source ==
"TIMER")
1080 else if (l_Source ==
"BUS")
1086 rInputTrig.
Period_s.Val = std::stod(std::string(l_Tokens[1].begin, l_Tokens[1].end));
1087 rInputTrig.
Period_s.Min = std::stod(std::string(l_Tokens[2].begin, l_Tokens[2].end));
1088 rInputTrig.
Period_s.Max = std::stod(std::string(l_Tokens[3].begin, l_Tokens[3].end));
1089 rInputTrig.
Period_s.Def = std::stod(std::string(l_Tokens[4].begin, l_Tokens[4].end));
1092 rInputTrig.
Count.Val =
static_cast<U16>(std::stoi(std::string(l_Tokens[5].begin, l_Tokens[5].end)));
1093 rInputTrig.
Count.Min =
static_cast<U16>(std::stoi(std::string(l_Tokens[6].begin, l_Tokens[6].end)));
1094 rInputTrig.
Count.Max =
static_cast<U16>(std::stoi(std::string(l_Tokens[7].begin, l_Tokens[7].end)));
1095 rInputTrig.
Count.Def =
static_cast<U16>(std::stoi(std::string(l_Tokens[8].begin, l_Tokens[8].end)));
1105 template <
class InstrType,
class RsrcMgrType>
1113 if (WriteAndRead(l_Command, m_ReadBuffer))
1115 m_UnitsParms = Units;
1121 ParmUnitsGet(m_UnitsParms);
1122 m_ErrorList = l_ErrorList;
1127 template <
class InstrType,
class RsrcMgrType>
1135 if (!WriteAndRead(
":UNIT?", m_ReadBuffer))
1138 std::string l_Answer(m_ReadBuffer.begin(), m_ReadBuffer.end());
1150 template <
class InstrType,
class RsrcMgrType>
1156 std::string l_Command = std::string(
":CAL:STAT ") + (UseCal ?
"ON" :
"OFF");
1158 if (WriteAndRead(l_Command, m_ReadBuffer))
1160 m_UseCalibration = UseCal;
1167 template <
class InstrType,
class RsrcMgrType>
1173 rUseCal = m_UseCalibration;
1177 template <
class InstrType,
class RsrcMgrType>
1183 std::string l_Command;
1185 l_Command =
":SENS:AUTO ON";
1187 l_Command =
":SENS:AUTO OFF;:SENS " +
l_ToString(rRange.
Range, 1) +
" T";
1189 if (WriteAndRead(l_Command, m_ReadBuffer))
1191 m_RangeParms = rRange;
1197 ParmRangeGet(m_RangeParms);
1198 m_ErrorList = l_ErrorList;
1203 template <
class InstrType,
class RsrcMgrType>
1211 if (!WriteAndRead(
":SENS:AUTO?;:SENS?", m_ReadBuffer))
1216 if (l_Tokens.size() != 2)
1220 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1223 else if (l_Auto ==
"OFF")
1224 rRange.
Auto =
false;
1229 std::string l_Range(l_Tokens[1].begin, l_Tokens[1].end - 2);
1230 rRange.
Range = std::stof(l_Range);
1240 template <
class InstrType,
class RsrcMgrType>
1248 if (!WriteAndRead(
":SENS:AUTO?;:SENS?;:SENS? MIN;:SENS? MAX;:SENS? DEF", m_ReadBuffer))
1253 if (l_Tokens.size() != 5)
1257 std::string l_Auto(l_Tokens[0].begin, l_Tokens[0].end);
1260 else if (l_Auto ==
"OFF")
1261 rRange.
Auto =
false;
1266 std::string l_Val(l_Tokens[1].begin, l_Tokens[1].end - 2);
1267 rRange.
Range.Val = std::stof(l_Val);
1270 std::string l_Min(l_Tokens[2].begin, l_Tokens[2].end - 2);
1271 rRange.
Range.Min = std::stof(l_Min);
1274 std::string l_Max(l_Tokens[3].begin, l_Tokens[3].end - 2);
1275 rRange.
Range.Max = std::stof(l_Max);
1278 std::string l_Def(l_Tokens[4].begin, l_Tokens[4].end - 2);
1279 rRange.
Range.Def = std::stof(l_Def);
1292 template <
class InstrType,
class RsrcMgrType>
1299 m_ErrorList.clear();
1308 if (!WriteAndRead(
":MMEM?", m_ReadBuffer))
1313 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1316 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1318 rUsedBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1321 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1323 rAvailableBytes =
static_cast<U32>(std::stoul(std::string(l_tokenbeg, l_tokenend)));
1326 while (l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1330 l_File.
Path = std::string(l_tokenbeg, l_tokenend);
1332 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1334 l_File.
Size = std::stoul(std::string(l_tokenbeg, l_tokenend));
1336 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
','))
1338 l_File.
Type = std::string(l_tokenbeg, l_tokenend);
1340 rFileList.push_back(l_File);
1344 if (!InstrType::SetTimeout(m_Timeout))
1350 InstrType::SetTimeout(m_Timeout);
1356 template <
class InstrType,
class RsrcMgrType>
1362 m_ErrorList.clear();
1366 std::string l_Command;
1367 l_Command =
":MMEM:DATA? " "\"" + Path +
"\"";
1374 if (!WriteAndRead(l_Command, m_ReadBuffer))
1378 size_t l_off, l_len;
1379 if (!
IsArbitraryBlock(m_ReadBuffer.begin(), m_ReadBuffer.end(), l_off, l_len))
1381 rContent = std::string(m_ReadBuffer.begin() + l_off, m_ReadBuffer.begin() + l_off + l_len);
1384 if (!InstrType::SetTimeout(m_Timeout))
1390 InstrType::SetTimeout(m_Timeout);
1399 template <
class InstrType,
class RsrcMgrType>
1406 m_AveragingParmsAtInit = m_AveragingParms;
1407 m_TriggerParmsAtInit = m_TriggerParms;
1408 m_TriggerTimes.clear();
1411 std::string l_Command = Continuous ?
":INIT:CONT 1;:INIT" :
":INIT:CONT 0;:INIT";
1412 return WriteAndRead(l_Command, m_ReadBuffer);
1415 template <
class InstrType,
class RsrcMgrType>
1421 return WriteAndRead(
":ABOR", m_ReadBuffer);
1424 template <
class InstrType,
class RsrcMgrType>
1430 m_ErrorList.clear();
1433 std::chrono::high_resolution_clock::time_point l_T = std::chrono::high_resolution_clock::now();
1434 m_TriggerTimes.push_back(l_T);
1437 return InstrType::AssertTrigger();
1443 template <
class InstrType,
class RsrcMgrType>
1453 l_ArbSelect.
Bx =
true;
1454 l_ArbSelect.
By =
true;
1455 l_ArbSelect.
Bz =
true;
1460 return MeasurementsGet(l_ArbSelect, rBx, rBy, rBz, rUnits, rTemp, rTimestampList, pMeasurementConditions);
1463 template <
class InstrType,
class RsrcMgrType>
1475 std::string l_Command =
":UNIT?";
1476 if (ArbSelect.
Bx) l_Command +=
";:FETC:ARR:X? " + std::to_string(ArbSelect.
NoMeasurements);
1477 if (ArbSelect.
By) l_Command +=
";:FETC:ARR:Y? " + std::to_string(ArbSelect.
NoMeasurements);
1478 if (ArbSelect.
Bz) l_Command +=
";:FETC:ARR:Z? " + std::to_string(ArbSelect.
NoMeasurements);
1479 if (ArbSelect.
Temperature) l_Command +=
";:FETC:TEMP?";
1480 if (ArbSelect.
Timestamp) l_Command +=
";:FETC:TIM?";
1481 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1484 if (!WriteAndRead(l_Command, m_ReadBuffer))
1487 auto l_pError = m_ErrorList.begin();
1488 for (; l_pError < m_ErrorList.end(); l_pError++)
1490 if (l_pError < m_ErrorList.end())
1496 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1497 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1499 if (!
StringToUnits(std::string(l_tokenbeg, l_tokenend), rUnits))
1506 if (!ParseMeasurements(l_BP, rUnits, rBx, ArbSelect.
NoMeasurements))
1514 if (!ParseMeasurements(l_BP, rUnits, rBy, ArbSelect.
NoMeasurements))
1522 if (!ParseMeasurements(l_BP, rUnits, rBz, ArbSelect.
NoMeasurements))
1527 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1530 m_ErrorList.push_back(l_Error);
1537 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1539 std::string l_TemperatureString(l_tokenbeg, l_tokenend);
1540 rTemp =
static_cast<U16>(stoul(l_TemperatureString));
1544 rTimestampList.clear();
1548 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1550 std::string l_TimestampString(l_tokenbeg, l_tokenend);
1551 U64 l_LastTimestamp = std::stoull(l_TimestampString,
nullptr, 0);
1555 switch (m_TriggerParmsAtInit.Source)
1563 GetImmediateMeasurementPeriod (m_AveragingParmsAtInit, l_Period);
1564 U64 l_TimeOffset =
static_cast<U64> (i * l_Period * 1E9 + 0.5);
1565 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1573 U64 l_TimeOffset =
static_cast<U64> (i * m_TriggerParmsAtInit.Period_s * 1E9 + 0.5);
1574 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset);
1581 auto l_LastTriggerTime = m_TriggerTimes.back();
1582 for (
auto l_pTime = m_TriggerTimes.begin(); l_pTime < m_TriggerTimes.begin() + ArbSelect.
NoMeasurements; l_pTime++)
1584 std::chrono::nanoseconds l_TimeOffset = l_LastTriggerTime - *l_pTime;
1585 rTimestampList.push_back(l_LastTimestamp - l_TimeOffset.count());
1593 if (pMeasurementConditions)
1596 switch (m_TriggerParmsAtInit.Source)
1599 GetImmediateMeasurementPeriod(m_AveragingParmsAtInit, m_TriggerParmsAtInit.Period_s);
1605 m_TriggerParmsAtInit.Period_s *= 1E-9;
1610 pMeasurementConditions->
TriggerParms = m_TriggerParmsAtInit;
1624 template <
class InstrType,
class RsrcMgrType>
1630 std::string l_Command;
1635 l_Command +=
":FORM ASC";
1638 l_Command +=
":FORM INT";
1641 l_Command +=
":FORM PACK,2";
1644 l_Command +=
":FORM PACK,1";
1647 if (WriteAndRead(l_Command, m_ReadBuffer))
1655 GetFormat(m_Format);
1656 m_ErrorList = l_ErrorList;
1661 template <
class InstrType,
class RsrcMgrType>
1670 std::string l_Command =
":FORM?";
1671 if (!WriteAndRead(l_Command, m_ReadBuffer))
1675 std::string l_Format = std::string(m_ReadBuffer.begin(), m_ReadBuffer.end());
1676 if (std::string(
"ASCII") == l_Format)
1678 else if (std::string(
"INTEGER") == l_Format)
1680 else if (std::string(
"PACKED,2") == l_Format)
1682 else if (std::string(
"PACKED,1") == l_Format)
1697 template <
class InstrType,
class RsrcMgrType>
1699 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1701 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1708 l_Command += DefaultParms ?
";:MEAS:X?" :
";:READ:X?";
1709 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
" ";
1710 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1711 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1712 l_Command +=
";:FETC:Y?";
1713 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1715 if (NoDigits != 0) l_Command +=
" " + std::to_string(NoDigits);
1716 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1719 if (!WriteAndRead(l_Command, m_ReadBuffer))
1725 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1730 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1735 if (!ParseMeasurements(l_BP, Units, l_Meas, 1))
1740 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1743 m_ErrorList.push_back(l_Error);
1754 template <
class InstrType,
class RsrcMgrType>
1756 bool DefaultParms,
eUnits Units,
tFlux ExpectedField,
unsigned int NoDigits)
1758 MTL_INSTRUMENT_THM1176_DEBUG_COUT(MTL__FUNCTION_NAME__ <<
" nmeas=" << NoMeasurements <<
" default=" << DefaultParms <<
" units=" << Units <<
" expect=" << ExpectedField <<
" ndigits=" << NoDigits << std::endl);
1765 l_Command += (DefaultParms ?
";:MEAS:ARR:X? " :
";:READ:ARR:X? ") +
1766 std::to_string(NoMeasurements);
1767 if (ExpectedField > 0.f || NoDigits != 0) l_Command +=
",";
1768 if (ExpectedField > 0.f) l_Command +=
l_ToString(ExpectedField);
1769 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1770 l_Command +=
";:FETC:ARR:Y? " + std::to_string(NoMeasurements);
1771 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1772 l_Command +=
";Z? " + std::to_string(NoMeasurements);
1773 if (NoDigits != 0) l_Command +=
"," + std::to_string(NoDigits);
1774 if (m_Sleep) l_Command +=
";:SYST:SLEE";
1777 if (!WriteAndRead(l_Command, m_ReadBuffer))
1783 if (!ParseMeasurements(l_BP, Units, rBx, NoMeasurements))
1787 if (!ParseMeasurements(l_BP, Units, rBy, NoMeasurements))
1791 if (!ParseMeasurements(l_BP, Units, rBz, NoMeasurements))
1795 if (!ApplyRotationMatrix(rBx, rBy, rBz))
1798 m_ErrorList.push_back(l_Error);
1812 template <
class InstrType,
class RsrcMgrType>
1818 return WriteAndRead(
":STAT:PRES", m_ReadBuffer);
1821 template <
class InstrType,
class RsrcMgrType>
1827 m_ErrorList.clear();
1831 if (0 == l_Command.size())
1834 if (!InstrType::Write(l_Command) ||
1835 !InstrType::Read(m_ReadBuffer) ||
1836 !GetErrorList(m_ErrorList, l_Command))
1839 rStatus =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1850 template <
class InstrType,
class RsrcMgrType>
1856 m_ErrorList.clear();
1859 std::string l_CompleteCommand;
1860 for (
auto l_Reg : Regs)
1863 if (0 == l_Command.size())
1865 if (l_CompleteCommand.size() > 0) l_CompleteCommand +=
";";
1866 l_CompleteCommand += l_Command;
1869 if (!InstrType::Write(l_CompleteCommand) ||
1870 !InstrType::Read(m_ReadBuffer) ||
1871 !GetErrorList(m_ErrorList, l_CompleteCommand))
1877 std::vector<char>::const_iterator l_tokenbeg, l_tokenend;
1879 for (
size_t i = Regs.size(); i > 0; i--)
1881 if (!l_BP.
GetNext(l_tokenbeg, l_tokenend,
';'))
1883 rStatus.push_back(
static_cast<U16>(std::stoi(std::string(l_tokenbeg, l_tokenend))));
1894 template <
class InstrType,
class RsrcMgrType>
1904 if (!WriteAndRead(l_Command, m_ReadBuffer))
1907 U16 l_StatusEnab =
static_cast<U16>(std::stoi(std::string(m_ReadBuffer.begin(), m_ReadBuffer.end())));
1910 l_StatusEnab &= ~DisableMask;
1911 l_StatusEnab |= EnableMask;
1915 if (!WriteAndRead(l_Command, m_ReadBuffer))
1929 template <
class InstrType,
class RsrcMgrType>
1935 rIdentification = m_Identification;
1939 template <
class InstrType,
class RsrcMgrType>
1945 rIdentification = m_IdentificationStruct;
1949 template <
class InstrType,
class RsrcMgrType>
1956 for (
auto l_Range : m_Ranges)
1957 rRanges.push_back(l_Range);
1961 template <
class InstrType,
class RsrcMgrType>
1968 for (
auto l_Unit : m_Units)
1969 rUnits.push_back(l_Unit.first);
1973 template <
class InstrType,
class RsrcMgrType>
1981 rDivisor = m_Units.at(Units);
1983 catch (
const std::out_of_range& oor)
1992 template <
class InstrType,
class RsrcMgrType>
1995 Matrix = m_RotationMatrix;
1999 template <
class InstrType,
class RsrcMgrType>
2014 template <
class InstrType,
class RsrcMgrType>
2021 if (!ForceCalibration &&
2025 m_ErrorList.clear();
2034 if (!WriteAndRead(
"*RST;:CAL:INIT", m_ReadBuffer))
2039 if (!ParmUnitsSet(m_UnitsParms) ||
2040 !ParmAveragingSet(m_AveragingParms) ||
2041 !ParmTriggerInputSet(m_TriggerParms) ||
2042 !ParmRangeSet(m_RangeParms) ||
2043 !ParmSleepSet(m_Sleep) ||
2044 !ParmUseCalibrationSet(m_UseCalibration) ||
2045 !SetFormat(m_Format))
2049 if (!InstrType::SetTimeout(m_Timeout))
2058 ParmUnitsSet(m_UnitsParms);
2059 ParmAveragingSet(m_AveragingParms);
2060 ParmTriggerInputSet(m_TriggerParms);
2061 ParmRangeSet(m_RangeParms);
2062 ParmSleepSet(m_Sleep);
2063 ParmUseCalibrationSet(m_UseCalibration);
2064 SetFormat(m_Format);
2065 m_ErrorList = l_ErrorList;
2067 InstrType::SetTimeout(m_Timeout);
2073 template <
class InstrType,
class RsrcMgrType>
2079 m_ErrorList.clear();
2087 if (!WriteAndRead(
":CAL:ZERO", m_ReadBuffer))
2091 if (!InstrType::SetTimeout(m_Timeout))
2097 InstrType::SetTimeout(m_Timeout);
2103 template <
class InstrType,
class RsrcMgrType>
2110 m_TriggerTimes.clear();
2111 m_ErrorList.clear();
2113 m_UseCalibration =
true;
2114 m_AbortRead =
false;
2119 if (!InstrType::Write(
"*RST;*CLS"))
2123 if (!ReadUseCalibration(m_UseCalibration))
2125 if (!ParmUnitsGet(m_UnitsParms))
2127 if (!ParmAveragingGet(m_AveragingParms))
2129 if (!ParmTriggerInputGet(m_TriggerParms))
2131 if (!ParmRangeGet(m_RangeParms))
2133 if (!GetFormat(m_Format))
2142 ReadUseCalibration(m_UseCalibration);
2143 ParmUnitsGet(m_UnitsParms);
2144 ParmAveragingGet(m_AveragingParms);
2145 ParmTriggerInputGet(m_TriggerParms);
2146 ParmRangeGet(m_RangeParms);
2147 GetFormat(m_Format);
2148 m_ErrorList = l_ErrorList;
2155 template <
class InstrType,
class RsrcMgrType>
2161 m_ErrorList.clear();
2162 return InstrType::Write(
":DIAG:UPGR");
2165 template <
class InstrType,
class RsrcMgrType>
2174 rSManufacturingDate = m_ManufacturingDate;
2177 std::match_results<std::string::const_iterator> l_Mm;
2178 if (!std::regex_match(rSManufacturingDate, l_Mm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2180 struct std::tm l_ManDateStruct = { };
2181 l_ManDateStruct.tm_year = std::stoi(l_Mm[1]) - 1900;
2182 l_ManDateStruct.tm_mon = std::stoi(l_Mm[2]) - 1;
2183 l_ManDateStruct.tm_mday = std::stoi(l_Mm[3]);
2184 if ((rManufacturingDate = mktime(&l_ManDateStruct)) < 0)
2188 rSCalibrationDate = m_CalibrationDate;
2191 std::match_results<std::string::const_iterator> l_Cm;
2192 if (!std::regex_match(rSCalibrationDate, l_Cm, std::regex(
"^([0-9]{4})-([0-9]{2})-([0-9]{2})")))
2194 struct tm l_CalDateStruct = { };
2195 l_CalDateStruct.tm_year = std::stoi(l_Cm[1]) - 1900;
2196 l_CalDateStruct.tm_mon = std::stoi(l_Cm[2]) - 1;
2197 l_CalDateStruct.tm_mday = std::stoi(l_Cm[3]);
2198 if ((rCalibrationDate = mktime(&l_CalDateStruct)) < 0)
2204 rSManufacturingDate.clear();
2205 rManufacturingDate = -1;
2206 rSCalibrationDate.clear();
2207 rCalibrationDate = -1;
2210 catch (std::regex_error& rE)
2218 template <
class InstrType,
class RsrcMgrType>
2232 U32 l_CurrentTimeout = InstrType::GetTimeout();
2233 std::this_thread::sleep_for(std::chrono::milliseconds(2 * l_CurrentTimeout));
2242 m_AbortRead =
false;