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