3 #include "DaqController.h"
4 #include "BaseController_p.h"
5 #include "helpers/SyncQueues.h"
6 #include "devices/Shutter.h"
7 #include "devices/SwitchResonance.h"
8 #include "parameters/IO.h"
9 #include "helpers/ScopeException.h"
10 #include "devices/StimulationVector.h"
11 #include "scanmodes/ScannerVectorFrameBasic.h"
13 #include "helpers/DaqChunk.h"
14 #include "helpers/DaqChunkResonance.h"
15 #include "ScopeLogger.h"
16 #include "devices/OutputsDAQmx.h"
17 #include "devices/OutputsDAQmxLineClock.h"
18 #include "devices/OutputsDAQmxResonance.h"
19 #include "devices/OutputsDAQmxSlave.h"
20 #include "devices/InputsDAQmx.h"
21 #include "devices/InputsFPGA.h"
22 #include "devices/StimulationsDAQmx.h"
23 #include "devices/GaterDAQmx.h"
33 std::array<SynchronizedQueue<ScopeMessage<SCOPE_DAQCHUNKPTR_T>>, SCOPE_NAREAS>*
const output_queues;
36 std::array<std::unique_ptr<Outputs>, SCOPE_NAREAS>
outputs;
39 std::array<std::unique_ptr<Inputs>, SCOPE_NAREAS>
inputs;
48 std::array<SwitchResonance, SCOPE_NAREAS>
switches;
51 std::array<ScannerVectorFrameBasicPtr, SCOPE_NAREAS>
scannervecs;
81 DBOUT(L
"DaqController::Impl::Run area " << _area << L
" beginning");
82 ControllerReturnStatus returnstatus(ControllerReturnStatus::none);
85 uint32_t chunksize = inputs[_area]->StandardChunkSize();
86 const uint32_t requested_samples = inputs[_area]->RequestedSamples();
87 uint32_t readsamples = 0;
88 int32_t currentlyread = 0;
89 bool timedout =
false;
92 while ( !sc->
IsSet() ) {
94 if ( requested_mode == DaqModeHelper::nframes ) {
95 if ( (readsamples + chunksize) > requested_samples )
96 chunksize = requested_samples - readsamples;
100 auto chunk = std::make_shared<SCOPE_DAQCHUNK_T>(chunksize,
parameters.
areas[_area]->daq.inputs->channels(), _area);
107 currentlyread = inputs[_area]->Read(*chunk, timedout, 1);
108 DBOUT(L
"DaqController::Impl::Run read");
110 }
while ( timedout && !sc->
IsSet() );
114 msg.
tag = ScopeMessageTag::nothing;
118 output_queues->at(_area).Enqueue(msg);
121 readsamples += currentlyread;
122 DBOUT(L
"DaqController::Impl::Run area " << _area << L
" read " << readsamples << L
" of requested " << requested_samples);
125 if ( (requested_mode == DaqModeHelper::nframes) && (readsamples == requested_samples) ) {
128 returnstatus = ControllerReturnStatus::finished;
129 DBOUT(L
"DaqController::Impl::Run area " << _area << L
" - all requested pixels read\n");
134 outputs[_area]->AbortWrite();
136 outputs[_area]->Stop();
137 inputs[_area]->Stop();
140 for (
auto& s : shutters )
144 for (
auto& s : switches )
147 ATLTRACE(L
"DaqController::DaqControllerImpl::Run end\n");
157 , output_queues(_oqueues)
158 , stimulation(nullptr) {
159 std::fill(std::begin(chunksizes), std::end(chunksizes), 16000);
160 std::fill(std::begin(online_update_done_flag), std::end(online_update_done_flag),
false);
162 for (
auto& sh : shutters )
165 for (
auto& sw : switches )
176 DBOUT(L
"DaqController::Impl::~DaqControllerImpl");
184 DBOUT(L
"DaqController::Impl::Start");
188 for ( uint32_t a = 0; a < SCOPE_NAREAS ; a++ ) {
191 outputs[a].reset(
new SCOPE_SLAVEOUTPUTS_T(a, *dynamic_cast<parameters::SCOPE_SLAVEOUTPUTS_T*>(
parameters.
areas[a]->daq.outputs.get()),
parameters));
193 outputs[a].reset(
new SCOPE_OUTPUTS_T(a, *dynamic_cast<parameters::SCOPE_OUTPUTS_T*>(
parameters.
areas[a]->daq.outputs.get()),
parameters));
195 inputs[a].reset(
new SCOPE_INPUTS_T(a, dynamic_cast<parameters::SCOPE_INPUTS_T*>(scope_controller.
GuiParameters.
areas[a]->daq.inputs.get()),
parameters));
200 stimulation.reset(
new SCOPE_STIMULATIONS_T(
parameters));
203 stimulation->Start();
206 stimulation.reset(
nullptr);
209 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ )
210 outputs[a]->Write(scannervecs[a]->GetInterleavedVector(), 1);
213 for (
auto& s : shutters )
217 for (
auto& s : switches )
225 std::function<void(void)> start_inputs = [&](){
226 for ( uint32_t a = 1 ; a < SCOPE_NAREAS ; a++ )
230 std::function<void(void)> start_outputs = [&](){
231 for ( uint32_t a = 1 ; a < SCOPE_NAREAS ; a++ )
246 for( uint32_t a = 0; a < SCOPE_NAREAS ; a++ ) {
257 uint32_t area = _areaparameters.
area();
264 std::unique_lock<std::mutex> lock(online_update_done_mutexe[area]);
271 while ( !online_update_done_flag[area] )
272 online_update_done[area].wait(lock);
277 DBOUT(L
"WorkerOnlineParameterUpdate starting");
278 auto scannervec = scannervecs[_area]->GetInterleavedVector();
281 uint32_t blocks = round2ui32(4.0 *
parameters.
areas[_area]->FrameTime());
283 DBOUT(L
"WorkerOnlineParameterUpdate blocks" << blocks);
284 online_update_done_flag[_area] =
false;
287 outputs[_area]->Write(scannervec, blocks);
290 online_update_done_flag[_area] =
true;
291 online_update_done[_area].notify_all();
292 DBOUT(L
"WorkerOnlineParameterUpdate ended");
299 outputs[_area]->AbortWrite();
305 for (
auto& o : outputs ) {
306 if ( o.get() != nullptr )
309 for (
auto& i : inputs ) {
310 if ( i.get() != nullptr )
313 stimulation.reset(
nullptr);
318 SCOPE_ZEROOUTPUTSSLAVE_T zero(*dynamic_cast<parameters::SCOPE_SLAVEOUTPUTS_T*>(ap->daq.outputs.get()));
320 SCOPE_ZEROOUTPUTS_T zero(*dynamic_cast<parameters::SCOPE_OUTPUTS_T*>(ap->daq.outputs.get()));
326 scannervecs[_area] = _sv;
331 for (
auto& s : shutters )
337 return shutters[_area].GetState();
342 for (
auto& s : switches )
348 return switches[_area].GetState();
Main controller of microscope hardware and acquisition, also interface to the GUI.
Parameters for a whole area (includes a daq and a fpu)
parameters::Scope parameters
the Controller's own set of ScopeParameters
Impl(std::array< SynchronizedQueue< ScopeMessage< SCOPE_DAQCHUNKPTR_T >>, SCOPE_NAREAS > *const _oqueues, const parameters::Scope &_parameters)
Sets the output queues, generates initial ScannerVectors and initializes the shutters and the resonan...
The implementation class of the DaqController.
Thread-safe lock-free bool to signal a requested stop to the worker function currently executed in th...
std::unique_ptr< SCOPE_STIMULATIONS_T > stimulation
The stimulation output.
The master parameters class.
Impl(const Impl &i)
disable copy
std::array< std::unique_ptr< Area >, SCOPE_NAREAS > areas
holds AreaParameters for all areas.
std::shared_ptr< const std::vector< uint8_t > > GetVector() const
std::array< std::unique_ptr< Inputs >, SCOPE_NAREAS > inputs
The inputs (pointers to base class)
Calculates a basic digital stimulation pattern.
void ZeroGalvoOutputs()
Zeros galvo outputs.
std::array< StopCondition, N_ACTIVES > stops
handed to the asynchronous Run worker functions
ControllerReturnStatus Run(StopCondition *const sc, const uint32_t &_area) override
Main function for running data acquisition.
ScopeLogger scope_logger
a ScopeLogger kept handy here
ScopeMessageTag tag
the tag of the message, at the moment only nothing or abort
ScopeNumber< bool > enable
stimulation enabled/disabled
void AbortOnlineParameterUpdate(const uint32_t &_area)
Aborts a running online parameters update (aborts the block-wise Outputs::Write operation) ...
Base class for all Scope datatypes here, provides a uniform interface (and saves typing...).
std::array< std::shared_future< ControllerReturnStatus >, N_ACTIVES > futures
futures from the asynchronous Run worker functions
StimulationVector stimvec
stimulation
virtual ~Impl()
Stops and interrupts everything and zeros galvo outputs.
void Start(const parameters::Scope &_params) override
Starts the DaqController.
A logger class to log various messages and user comments.
std::array< std::unique_ptr< Outputs >, SCOPE_NAREAS > outputs
The outputs (pointers to base class)
std::array< uint32_t, SCOPE_NAREAS > chunksizes
size of a read chunk in samples per channel
std::array< std::condition_variable, SCOPE_NAREAS > online_update_done
condition variables to wait for until online updates is done (new frame is completely written to buff...
ScopeValue< DaqMode > requested_mode
requested acquisition mode (see DaqModeHelper)
std::array< Shutter, SCOPE_NAREAS > shutters
array holding shutter class for every area
void OnlineParameterUpdate(const parameters::Area &_areaparameters)
Handles update of parameters during scanning.
In here all declarations for all kinds of datatypes Scope needs.
void SetScannerVector(const uint32_t &_area, ScannerVectorFrameBasicPtr _sv)
Sets a scanner vector.
virtual ControllerReturnStatus WaitForAll(const int32_t &_wait_time)
Wait for the futures of all async worker functions.
virtual void StopAll()
Request all async worker function to stop.
void OpenCloseShutter(const uint32_t &_area, const bool &_open)
Opens/closes the shutter.
#define DBOUT(s)
A debug output to the debug console.
Impl operator=(const Impl &i)
disable assignment
std::array< std::mutex, SCOPE_NAREAS > online_update_done_mutexe
mutexe for the condition variables
A synchronized, thread-safe queue was modeled after ringbuffer example from boost?! and/or a Herb Sutter column?!
void TurnOnOffSwitchResonance(const uint32_t &_area, const bool &_on)
Turns the resonance scanner relay on and off.
std::array< ScannerVectorFrameBasicPtr, SCOPE_NAREAS > scannervecs
The scanner vector for frame scanning.
void Set(const bool &_a=true)
ScopeNumber< uint32_t > area
the number of this area
bool GetShutterState(const uint32_t _area) const
std::array< std::atomic< bool >, SCOPE_NAREAS > online_update_done_flag
bool flag to set after online update is done
std::array< SynchronizedQueue< ScopeMessage< SCOPE_DAQCHUNKPTR_T > >, SCOPE_NAREAS > *const output_queues
array holding the output queues to the PipelineControllers
void SetParameters(const parameters::Stimulation &_parameters)
Sets parameters.
ScopeNumber< bool > startinputsfirst
true: start inputs first, then outputs with output of area 0 as last, so it (e.g. ...
std::array< SwitchResonance, SCOPE_NAREAS > switches
array holding SwitchResonance class for every area
static parameters::Scope GuiParameters
The complete pseudo-global parameter set of the microscope.
Base class for all controllers.
void WorkerOnlineParameterUpdate(const uint32_t _area)
Does the actual writing to device for an online update.
Stimulation stimulation
the StimulationParameters
bool GetSwitchResonanceState(const uint32_t _area) const