DynExp
Highly flexible laboratory automation for dynamically changing experiments.
ZI_MFLI.cpp
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
3 #include "stdafx.h"
4 #include "ZI_MFLI.h"
5 
6 namespace DynExpInstr
7 {
9  {
10  auto InstrParams = DynExp::dynamic_Params_cast<ZI_MFLI>(Instance.ParamsGetter());
11  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
12 
13  Instance.LockObject(InstrParams->HardwareAdapter, InstrData->HardwareAdapter);
14 
15  InstrData->HardwareAdapter->ConfigureInput(GetUsedSignalInput(), GetUsedDemodulator());
16 
18  }
19 
21  {
22  ExitFuncImpl(dispatch_tag<ExitTask>(), Instance);
23 
24  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
25 
26  try
27  {
28  InstrData->HardwareAdapter->StopAcquisition();
29  InstrData->HardwareAdapter->SetEnabled(GetUsedDemodulator(), false);
30  }
31  catch (...)
32  {
33  // Swallow any exception which might arise from instrument shutdown since a failure
34  // of this function is not considered a severe error.
35  }
36 
37  Instance.UnlockObject(InstrData->HardwareAdapter);
38  }
39 
41  {
42  try
43  {
44  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
45  bool UpdateError = false;
46 
47  try
48  {
49  InstrData->SetSensitivity(InstrData->HardwareAdapter->GetInputRange(GetUsedSignalInput()));
50  InstrData->SetPhase(InstrData->HardwareAdapter->GetDemodPhase(GetUsedDemodulator()));
51  InstrData->SetTimeConstant(InstrData->HardwareAdapter->GetDemodTimeConstant(GetUsedDemodulator()));
52  InstrData->SetFilterOrder(InstrData->HardwareAdapter->GetDemodFilterOrder(GetUsedDemodulator()));
53  InstrData->SetTriggerMode(InstrData->HardwareAdapter->GetTriggerMode());
54  InstrData->SetTriggerEdge(InstrData->HardwareAdapter->GetTriggerEdge());
55  InstrData->SetSamplingRate(InstrData->HardwareAdapter->GetDemodSamplingRate(GetUsedDemodulator()));
56  InstrData->SetEnable(InstrData->HardwareAdapter->GetEnabled(GetUsedDemodulator()));
57 
58  InstrData->NegInputLoad = InstrData->HardwareAdapter->GetNegInputLoad(GetUsedSignalInput());
59  InstrData->PosInputLoad = InstrData->HardwareAdapter->GetPosInputLoad(GetUsedSignalInput());
60  InstrData->Overload = DynExpHardware::ZILabOneHardwareAdapter::DetermineOverload(InstrData->PosInputLoad, InstrData->NegInputLoad);
61  InstrData->OscillatorFrequency = InstrData->HardwareAdapter->GetOscillatorFrequency(0);
62  InstrData->AcquisitionProgress = InstrData->HardwareAdapter->GetAcquisitionProgress();
63  }
64  catch ([[maybe_unused]] const DynExpHardware::ZILabOneException& e)
65  {
66  UpdateError = true;
67 
68  // Swallow if just one or two subsequent updates failed.
69  if (InstrData->NumFailedStatusUpdateAttempts++ >= 3)
70  throw;
71  }
72 
73  if (!UpdateError)
74  InstrData->NumFailedStatusUpdateAttempts = 0;
75  }
76  // Issued if a mutex is blocked by another operation.
77  catch (const Util::TimeoutException& e)
78  {
79  Instance.GetOwner().SetWarning(e);
80 
81  return;
82  }
83  // Issued if reading data from ZI_MFLI controller failed.
84  catch (const DynExpHardware::ZILabOneException& e)
85  {
86  Instance.GetOwner().SetWarning(e);
87 
88  return;
89  }
90 
91  UpdateFuncImpl(dispatch_tag<UpdateTask>(), Instance);
92  }
93 
95  {
96  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
97 
98  auto SampleStream = InstrData->GetCastSampleStream<LockinAmplifierData::SampleStreamType>();
99  auto LockinSamples = InstrData->HardwareAdapter->GetAcquiredData();
100 
101  for (const auto& Sample : LockinSamples)
102  SampleStream->WriteSample({ Sample.GetDisambiguatedValue(InstrData->GetSignalType()), Sample.Time });
103 
104  return {};
105  }
106 
108  {
109  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
110 
111  InstrData->HardwareAdapter->ClearAcquiredData();
112 
113  return {};
114  }
115 
117  {
118  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
119 
120  InstrData->HardwareAdapter->StartAcquisition(GetUsedDemodulator(), InstrData->GetSampleStream()->GetStreamSizeWrite());
121 
122  return {};
123  }
124 
126  {
127  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
128 
129  InstrData->HardwareAdapter->StopAcquisition();
130 
131  return {};
132  }
133 
135  {
136  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
137 
138  InstrData->HardwareAdapter->SetInputRange(GetUsedSignalInput(), Sensitivity);
139 
140  return {};
141  }
142 
144  {
145  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
146 
147  InstrData->HardwareAdapter->AutoAdjustInputRange(GetUsedSignalInput());
148 
149  return {};
150  }
151 
153  {
154  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
155 
156  InstrData->HardwareAdapter->SetDemodPhase(GetUsedDemodulator(), Phase);
157 
158  return {};
159  }
160 
162  {
163  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
164 
165  InstrData->HardwareAdapter->AutoAdjustDemodPhase(GetUsedDemodulator());
166 
167  return {};
168  }
169 
171  {
172  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
173 
174  InstrData->HardwareAdapter->SetDemodTimeConstant(GetUsedDemodulator(), TimeConstant);
175 
176  return {};
177  }
178 
180  {
181  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
182 
183  InstrData->HardwareAdapter->SetDemodFilterOrder(GetUsedDemodulator(), FilterOrder);
184 
185  return {};
186  }
187 
189  {
190  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
191 
192  InstrData->HardwareAdapter->SetTriggerMode(TriggerMode, GetUsedDemodulator(), TriggerChannel);
193 
194  return {};
195  }
196 
198  {
199  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
200 
201  InstrData->HardwareAdapter->SetTriggerEdge(TriggerEdge);
202 
203  return {};
204  }
205 
207  {
208  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
209 
210  InstrData->SetSignalType(SignalType);
211 
212  return {};
213  }
214 
216  {
217  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
218 
219  InstrData->HardwareAdapter->SetDemodSamplingRate(GetUsedDemodulator(), SamplingRate);
220 
221  return {};
222  }
223 
225  {
226  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
227 
228  InstrData->HardwareAdapter->SetEnabled(GetUsedDemodulator(), Enable);
229 
230  return {};
231  }
232 
234  {
235  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(Instance.InstrumentDataGetter());
236 
237  InstrData->HardwareAdapter->ForceTrigger();
238 
239  return {};
240  }
241 
243  {
244  Sensitivity = 1;
245  Phase = 0;
246  TimeConstant = 1e-3;
247  FilterOrder = 1;
251  SamplingRate = 1000;
252  Enable = false;
253 
254  Overload = false;
255  NegInputLoad = 0;
256  PosInputLoad = 0;
257  OscillatorFrequency = 0;
258  AcquisitionProgress = -1;
259 
260  NumFailedStatusUpdateAttempts = 0;
261 
262  ResetImpl(dispatch_tag<ZI_MFLIData>());
263  }
264 
266  {
268  { "Voltage", DynExpHardware::ZILabOneHardwareAdapter::SignalInputType::Voltage },
269  { "Differential voltage", DynExpHardware::ZILabOneHardwareAdapter::SignalInputType::DifferentialVoltage },
270  { "Current", DynExpHardware::ZILabOneHardwareAdapter::SignalInputType::Current },
271  };
272 
273  return List;
274  }
275 
276  ZI_MFLI::ZI_MFLI(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType&& Params)
277  : LockinAmplifier(OwnerThreadID, std::move(Params)),
278  SignalInput(DynExpHardware::ZILabOneHardwareAdapter::SignalInputType::Voltage), UsedDemodulator(0), TriggerChannel(1)
279  {
280  }
281 
283  {
284  auto InstrData = DynExp::dynamic_InstrumentData_cast<ZI_MFLI>(GetInstrumentData());
285 
286  return InstrData->HardwareAdapter->HasFinishedAcquisition();
287  }
288 
290  {
291  return !HasFinished();
292  }
293 
295  {
296  {
297  auto InstrParams = DynExp::dynamic_Params_cast<ZI_MFLI>(GetParams());
298 
299  SignalInput = InstrParams->SignalInput;
300  UsedDemodulator = InstrParams->Demodulator;
301  TriggerChannel = InstrParams->TriggerChannel;
302  } // InstrParams unlocked here.
303 
305  }
306 
308  {
309  auto InstrParams = DynExp::dynamic_Params_cast<ZI_MFLI>(GetParams());
310 
311  if (InstrParams->AutoApplyParams == LockinAmplifierParams::AutoApplyParamsType::AutoApply)
312  {
313  SetSensitivity(InstrParams->Sensitivity);
314  SetPhase(InstrParams->Phase);
315  SetTimeConstant(InstrParams->TimeConstant);
316  SetFilterOrder(Util::NumToT<uint8_t>(InstrParams->FilterOrder));
317  SetTriggerMode(InstrParams->TriggerMode);
318  SetTriggerEdge(InstrParams->TriggerEdge);
319  SetSignalType(InstrParams->Signal);
320  SetSamplingRate(InstrParams->SamplingRate);
321  SetEnable(InstrParams->Enable.Get());
322  }
323  }
324 }
Implementation of an instrument to control the Zurich Instruments MFLI lock-in amplifier.
constexpr static bool DetermineOverload(double PosInputLoad, double NegInputLoad)
Implements a circular data stream based on Util::circularbuf using samples of type BasicSample.
void WriteSample(const SampleT &Sample)
Writes a single sample to the stream's buffer StreamBuffer.
Meta instrument for a lock-in amplifier based on the data stream meta instrument.
void ResetImpl(dispatch_tag< LockinAmplifierData >) override final
Definition: ZI_MFLI.cpp:242
static Util::TextValueListType< DynExpHardware::ZILabOneHardwareAdapter::SignalInputType > SignalInputTypeStrList()
Definition: ZI_MFLI.cpp:265
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:161
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:143
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:107
void ExitFuncImpl(dispatch_tag< LockinAmplifierTasks::ExitTask >, DynExp::InstrumentInstance &Instance) override final
Deinitializes the respective instrument within the instrument inheritance hierarchy....
Definition: ZI_MFLI.cpp:20
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:233
void InitFuncImpl(dispatch_tag< LockinAmplifierTasks::InitTask >, DynExp::InstrumentInstance &Instance) override final
Initializes the respective instrument within the instrument inheritance hierarchy....
Definition: ZI_MFLI.cpp:8
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:94
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:224
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:179
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:152
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:215
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:134
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:206
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:170
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:197
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:188
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:116
virtual DynExp::TaskResultType RunChild(DynExp::InstrumentInstance &Instance) override
Runs the task. Override RunChild() to define a derived task's action(s). Any exception leaving RunChi...
Definition: ZI_MFLI.cpp:125
void UpdateFuncImpl(dispatch_tag< LockinAmplifierTasks::UpdateTask >, DynExp::InstrumentInstance &Instance) override final
Updates the respective instrument within the instrument inheritance hierarchy. Call UpdateFuncImpl() ...
Definition: ZI_MFLI.cpp:40
auto GetUsedSignalInput() const noexcept
Definition: ZI_MFLI.h:29
auto GetUsedDemodulator() const noexcept
Definition: ZI_MFLI.h:30
uint8_t UsedDemodulator
Definition: ZI_MFLI.h:412
virtual void SetPhase(double Phase, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the phase of the lock-in amplifier's demodulator.
Definition: ZI_MFLI.h:388
virtual void SetTriggerMode(LockinAmplifierDefs::TriggerModeType TriggerMode, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the lock-in amplifier's trigger mode.
Definition: ZI_MFLI.h:392
virtual void SetEnable(bool Enable, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Enables or disables the lock-in amplifier's demodulator.
Definition: ZI_MFLI.h:396
uint8_t TriggerChannel
Definition: ZI_MFLI.h:413
virtual void SetFilterOrder(uint8_t FilterOrder, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the filter order/quality of the lock-in amplifier's low-poss filter.
Definition: ZI_MFLI.h:391
virtual Util::OptionalBool HasFinished() const override
Determines whether the underlying hardware adapter finished data acquisition or writing data.
Definition: ZI_MFLI.cpp:282
virtual void SetSamplingRate(double SamplingRate, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the lock-in amplifier's sampling rate.
Definition: ZI_MFLI.h:395
virtual void ApplyFromParamsImpl(dispatch_tag< LockinAmplifier >) const override
Refer to ApplyFromParams(). Using tag dispatch mechanism to ensure that ApplyFromParamsImpl() of ever...
Definition: ZI_MFLI.cpp:307
ZI_MFLI(const std::thread::id OwnerThreadID, DynExp::ParamsBasePtrType &&Params)
Definition: ZI_MFLI.cpp:276
std::atomic< DynExpHardware::ZILabOneHardwareAdapter::SignalInputType > SignalInput
Definition: ZI_MFLI.h:410
virtual void SetSignalType(LockinAmplifierDefs::SignalType SignalType, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the lock-in amplifier's signal coordinate type to read out.
Definition: ZI_MFLI.h:394
void ResetImpl(dispatch_tag< LockinAmplifier >) override final
Refer to DynExp::Object::Reset(). Using tag dispatch mechanism to ensure that ResetImpl() of every de...
Definition: ZI_MFLI.cpp:294
virtual void SetTimeConstant(double TimeConstant, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the time constant of the lock-in amplifier's low-poss filter.
Definition: ZI_MFLI.h:390
virtual void SetTriggerEdge(LockinAmplifierDefs::TriggerEdgeType TriggerEdge, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the lock-in amplifier's trigger edge.
Definition: ZI_MFLI.h:393
virtual Util::OptionalBool IsRunning() const override
Determines whether the underlying hardware adapter is running a data acquisition or writing data.
Definition: ZI_MFLI.cpp:289
virtual void SetSensitivity(double Sensitivity, DynExp::TaskBase::CallbackType CallbackFunc=nullptr) const override
Sets the lock-in amplifier's sensitivity/amplification.
Definition: ZI_MFLI.h:386
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1151
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1120
InstrumentDataTypeSyncPtrType GetInstrumentData(const std::chrono::milliseconds Timeout=GetInstrumentDataTimeoutDefault)
Locks the mutex of the instrument data class instance InstrumentData assigned to this InstrumentBase ...
Definition: Instrument.cpp:222
Refer to ParamsBase::dispatch_tag.
Definition: Instrument.h:146
Defines data for a thread belonging to a InstrumentBase instance. Refer to RunnableInstance.
Definition: Instrument.h:772
const InstrumentBase::InstrumentDataGetterType InstrumentDataGetter
Getter for instrument's data. Refer to InstrumentBase::InstrumentDataGetterType.
Definition: Instrument.h:791
ParamsConstTypeSyncPtrType GetParams(const std::chrono::milliseconds Timeout=GetParamsTimeoutDefault) const
Locks the mutex of the parameter class instance Params assigned to this Object instance and returns a...
Definition: Object.cpp:436
Refer to ParamsBase::dispatch_tag.
Definition: Object.h:2018
const Object::ParamsGetterType ParamsGetter
Invoke to obtain the parameters (derived from ParamsBase) of Owner.
Definition: Object.h:3671
void UnlockObject(LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer)
Unlocks an Object instance stored in the LinkedObjectWrapperContainer ObjectWrapperContainer....
Definition: Object.h:3570
void LockObject(const ParamsBase::Param< ObjectLink< ObjectT >> &LinkParam, LinkedObjectWrapperContainer< ObjectT > &ObjectWrapperContainer, std::chrono::milliseconds Timeout=ObjectLinkBase::LockObjectTimeoutDefault)
Locks an Object instance referenced by a parameter LinkParam of type ParamsBase::Param< ObjectLink< O...
Definition: Object.h:3554
const auto & GetOwner() const noexcept
Returns Owner.
Definition: Object.h:3524
Defines the return type of task functions.
Definition: Instrument.h:824
Refer to DynExp::ParamsBase::dispatch_tag.
Definition: Instrument.h:1182
Data type which stores an optional bool value (unknown, false, true). The type evaluates to bool whil...
Definition: Util.h:549
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
DynExp's hardware namespace contains the implementation of DynExp hardware adapters which extend DynE...
@ Fall
Trigger on falling edge.
SignalType
Type specifying different signal coordinates a lock-in amplifier can record. Not a strongly-typed enu...
@ R
Radial component of the signal in polar coordinates.
@ ExternSingle
Run once after an external trigger signal has been detected.
DynExp's instrument namespace contains the implementation of DynExp instruments which extend DynExp's...
Definition: Instrument.h:1254
std::unique_ptr< ParamsBase > ParamsBasePtrType
Alias for a pointer to the parameter system base class ParamsBase.
Definition: Object.h:1807
std::vector< std::pair< TextType, ValueType > > TextValueListType
Type of a list containing key-value pairs where key is a text of type Util::TextType.
Definition: QtUtil.h:37
Accumulates include statements to provide a precompiled header.