3 #include "ScopeController.h"
4 #include "ScopeControllerModes.h"
5 #include "ScopeDefines.h"
7 #include "scanmodes/ScannerVectorFrameBasic.h"
8 #include "scanmodes/ScannerVectorFrameSaw.h"
9 #include "scanmodes/ScannerVectorFrameBiDi.h"
10 #include "scanmodes/ScannerVectorFramePlaneHopper.h"
11 #include "scanmodes/ScannerVectorFrameResonanceBiDi.h"
12 #include "scanmodes/ScannerVectorFrameResonanceHopper.h"
13 #include "helpers/ScopeMultiImage.h"
14 #include "helpers/ScopeMultiImageResonanceSW.h"
15 #include "DaqController.h"
16 #include "PipelineController.h"
17 #include "DisplayController.h"
18 #include "StorageController.h"
19 #include "helpers/ScopeException.h"
20 #include "FPUController.h"
21 #include "ScopeLogger.h"
22 #include "gui/ChannelFrame.h"
23 #include "gui/HistogramFrame.h"
24 #include "devices/xyz/XYZControl.h"
25 #include "devices/xyz/XYZControlGalil.h"
26 #include "devices/xyz/XYZControlSutter.h"
27 #include "devices/GaterDAQmx.h"
37 std::array<SynchronizedQueue<ScopeMessage<SCOPE_DAQCHUNKPTR_T>>, SCOPE_NAREAS>
daq_to_pipeline;
84 std::vector<std::function<void(const uint32_t&, const ScannerVectorType&)>>
scanmodecallbacks;
99 std::wstring msg(L
"");
101 case RunStateHelper::RunningContinuous:
103 msg += L
"Live scan (saving)";
105 case RunStateHelper::RunningSingle:
106 msg += L
"Single scan";
108 case RunStateHelper::RunningStack:
109 msg += L
"Stack scan";
111 case RunStateHelper::RunningTimeseries:
112 msg = L
"Timeseries scan";
114 case RunStateHelper::RunningBehavior:
115 msg = L
"Behavior scan";
118 scope_logger.
Log(msg, log_info);
124 time = ::timeGetTime();
139 ControllerReturnStatus sdisp = theDisplay.
WaitForAll(500);
142 ControllerReturnStatus sstor = theStorage.
WaitForAll(500);
145 ControllerReturnStatus spipe = thePipeline.
WaitForAll(2000);
148 ControllerReturnStatus sdaq = theDaq.
WaitForAll(2000);
150 time = ::timeGetTime() -
time;
163 for (
auto& d : daq_to_pipeline )
165 pipeline_to_display.
Clear();
166 pipeline_to_storage.
Clear();
171 DBOUT(L
"ScopeControllerImpl::SetScannerVectorParameters");
172 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ )
180 DBOUT(L
"ScopeController::RunLive()");
182 return ControllerReturnStatus::finished;
193 return ControllerReturnStatus::finished;
213 ap->daq.requested_frames = 1;
223 theStage.MoveAbsolute(theStage.CurrentXPosition(), theStage.CurrentYPosition(),
parameters.
stack.
planes___[p][0].position());
225 std::this_thread::sleep_for(std::chrono::milliseconds(1000));
228 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
236 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
254 if ( repeat_abort.
IsSet() )
267 return ControllerReturnStatus::finished;
289 std::unique_lock<std::mutex> lock(waitbetweenrepeats_mutex);
292 waitbetweenrepeats_cond.wait_for(lock, waittime);
300 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ )
306 if ( repeat_abort.
IsSet() ) {
313 return ControllerReturnStatus::finished;
322 DWORD starttime = ::timeGetTime();
331 if ( !gater.WaitFor(
true) )
341 TotalTime =
static_cast<double>(::timeGetTime() - starttime) / 1000;
344 if ( !gater.WaitFor(
false) )
351 TotalTime =
static_cast<double>(::timeGetTime() - starttime) / 1000;
355 return ControllerReturnStatus::finished;
360 DBOUT(L
"ScopeControllerImpl::CleanAfterStop");
362 repeat_abort.
Set(
false);
372 SCOPE_XYZCONTROL_T theStage;
380 , pipeline_to_display()
381 , pipeline_to_storage()
383 , thePipeline(&daq_to_pipeline, &pipeline_to_storage, &pipeline_to_display,
parameters)
384 , theStorage(&pipeline_to_storage,
parameters)
385 , theDisplay(&pipeline_to_display,
parameters)
386 , repeat_abort(false)
387 , onlineupdate_running(false)
389 , initialparametersloaded(false, false, true)
390 , currentconfigfile(L
"NONE")
399 StopButton.Connect(std::bind(&
Impl::Stop,
this));
407 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
416 if ( !ThisIsSlaveArea(a) ) {
446 StopButton.Enable(
false);
447 theStage.StopPolling();
457 std::wstring revstr = CA2W(STR(LASTGITCOMMIT));
458 revstr = L
"Scope (Last Git commit " + revstr + L
")";
459 DBOUT(revstr.c_str());
521 for ( uint32_t a = 1 ; a < SCOPE_NAREAS ; ++a )
527 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ )
552 DBOUT(L
"ScopeController::stop()\n");
556 repeat_abort.
Set(
true);
560 waitbetweenrepeats_cond.notify_one();
564 if ( onlineupdate_future.valid() )
565 onlineupdate_future.get();
569 if ( static_cast<RunState>(
parameters.
run_state()) == RunStateHelper::Mode::RunningContinuous ) {
574 DBOUT(L
"ScopeController::stop end()\n");
579 DBOUT(L
"ScopeController::update_parameters_from_gui()\n");
585 if ( onlineupdate_running ) {
586 DBOUT(L
"ScopeController::UpdateAreaParametersFromGui aborting previous online update");
591 if ( onlineupdate_future.valid() )
592 onlineupdate_future.get();
597 if ( !onlineupdate_running ) {
598 onlineupdate_future = std::async([&]() {
599 DBOUT(L
"ScopeController::UpdateAreaParametersFromGui starting new online update");
600 onlineupdate_running =
true;
616 onlineupdate_running =
false;
624 currentconfigfile = _filepath.substr(_filepath.find_last_of(L
'\\')+1, std::wstring::npos);
629 initialparametersloaded =
true;
657 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
671 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
686 DBOUT(L
"Zeroing galvo outputs\n");
713 for (
auto& b :
FPU ) {
714 b.LeftButton.Enable(state);
715 b.RightButton.Enable(state);
716 b.UpButton.Enable(state);
717 b.DownButton.Enable(state);
731 const bool buttonenabler = (
parameters.
run_state()==RunStateHelper::Mode::Stopped)?
true:
false;
733 StartSingleButton.Enable(buttonenabler);
734 StartLiveButton.Enable(buttonenabler);
735 StartStackButton.Enable(buttonenabler);
736 StartTimeseriesButton.Enable(buttonenabler);
737 StartBehaviorButton.Enable(buttonenabler);
739 for ( uint32_t a = 0 ; a < SCOPE_NAREAS ; a++ ) {
741 if ( !ThisIsSlaveArea(a) ) {
748 b.second.Enable(
false);
752 StackStartHereButton.Enable(buttonenabler || (
parameters.
run_state() == RunStateHelper::Mode::RunningContinuous));
753 StackStopHereButton.Enable(buttonenabler || (
parameters.
run_state() == RunStateHelper::Mode::RunningContinuous));
787 void SetHistogramLimits(
const uint32_t& _area,
const uint32_t& _channel,
const uint16_t& _lower,
const uint16_t& _upper) {
804 for (
auto& c : scanmodecallbacks )
807 throw ScopeException(
"Choosen ScanMode is not supported by built-in scanner type");
814 scanmodecallbacks.push_back(_callback);
ScopeLogger scope_logger
a logger kept handy
std::condition_variable waitbetweenrepeats_cond
for abortable waiting between timeseries repeats
void StopAllControllers()
Stops all controllers in the correct order and waits for them to finish.
void StartBehavior()
Starts a behavior triggered acquisition by running RunBehavior asynchronously.
void OpenCloseShutter(const uint32_t &_area, const bool &_open)
Opens/closes the shutter.
parameters::Scope parameters
the Controller's own set of ScopeParameters
void AttachFrame(gui::CChannelFrame *const cframe)
Attach a CChannelFrame as observer.
void StopAll()
Stop the controller, calls BaseController::Impl::StopAll.
void ResolutionChange(const uint32_t &_area)
Called via change of GuiParameters.areas[x].framesaw.scanvec.xres etc.
std::future< void > onlineupdate_future
future for the online update thread
void SetScannerVector(const uint32_t &_area, ScannerVectorFrameBasicPtr _sv)
Sets a scanner vector.
ScopeNumber< bool > unlimited_repeats
Should acquisition go on until Stop pressed (true) or until repeats done (false)? ...
void DetachFrame(gui::CChannelFrame *const cframe)
Detach an observing CChannelFrame.
static ScopeButton StageZeroButton
Button to zero main stage coordinates.
void SetGuiCtrlState()
Sets the state of GUI controls (via the corresponding ScopeNumbers).
static ScopeNumber< double > TrialCounter
Updated from ScopeControllerImpl::RunBehavior, connected to edit control in CBehaviorSettingsPage.
ControllerReturnStatus RunSingle(StopCondition *const sc)
Worker function to control a single scan.
Thread-safe lock-free bool to signal a requested stop to the worker function currently executed in th...
virtual T Set(const T &_v, const bool &_callguisignal=true, const bool &_callothersignal=true, const bool &_callatnochange=false)
Sets the value and calls both change signals if the value actually changed.
ScopeValue< ZDevice > zdevicetype
type of z device to use
ScopeNumber< bool > autosave
autosave all acquisitions (except live scan)
static std::array< ScopeNumber< double >, SCOPE_NAREAS > FrameCounter
Updated from PipelineControllerImpl::Run, connected to progress indicator in CTimeSeriesSettingsPage ...
Impl operator=(const Impl &i)
disable assignment
Simple exception class for Scope.
~Impl()
Stop whatever is running.
ScopeString date
current date
void SetFPUButtonsState(const bool &state)
Sets the state of the GUI buttons for FPU control (via the corresponding ScopeButtons).
void SetScannerVector(const uint32_t &_area, ScannerVectorFrameBasicPtr _sv)
Sets a scanner vector.
void Initialize(const parameters::Scope &_params)
Initialize the FPU's hardware.
std::array< PlaneProperties, SCOPE_NAREAS > startat
Start plane, measured with the zdevicetype.
void StartTimeseries()
Starts a timeseries by running RunTimeseries asynchronously.
bool GetShutterState(const uint32_t &_area) const
Stack stack
the StackParameters
The PipelineController controls everything from pixels to complete images, i.e.
WindowCollection frames
The parameters for windows on the screen.
std::array< std::unique_ptr< Area >, SCOPE_NAREAS > areas
holds AreaParameters for all areas.
ScopeNumber< uint32_t > repeats
How often should the timeseries be repeated.
void LogRun()
Logs the current scan (not live scans)
void Clear()
Clears the queue.
ScopeNumber< bool > savelive
autosave live scan acquisitions
bool LoadParameters(const std::wstring &_filepath)
Loads current parameter set from disk.
void RegisterScanmodeCallback(std::function< void(const uint32_t &, const ScannerVectorType &)> _callback)
Registers a function to call when scanmode is changed.
void AbortOnlineParameterUpdate(const uint32_t &_area)
Aborts a potentially currently running online update.
ControllerReturnStatus RunTimeseries(StopCondition *const sc)
Worker function to control a timeseries scan.
std::mutex waitbetweenrepeats_mutex
for abortable waiting between timeseries repeats
ControllerReturnStatus WaitForAll(const int32_t &_wait_time=-1)
Wait until the controller threads finished, calls BaseController::Impl::WaitForAll.
void UpdateAreaParametersFromGui(const uint32_t &_area)
Updates area parameters and scanner vectors in the controllers from the GuiParameters set without sto...
std::array< StopCondition, N_ACTIVES > stops
handed to the asynchronous Run worker functions
void SetStageZero()
Sets the current xyz stage position as zero.
The DaqController controls the data acquisition hardware, both outputs for scanners as well as input ...
void ResolutionChange(const parameters::Area &_parameters)
Request resize of CChannelFrame observers to cope with new image size.
void OpenCloseShutter(const uint32_t &_area, const bool &_open)
Opens/closes the shutter.
void Version() const
Prints out the last Git commit date of the currently running version (see description at ScopeControl...
SCOPE_XYZCONTROL_T stage
the parameters for the xyz stage (set type in ScopeDefines.h)
static bool IsBuiltinSupported(const ScannerVectorTypeHelper::Mode &_scanmode)
Returns true if a given scannervector/scanmode is supported by the builtin/hardcoded (see ScopeDefine...
void ZeroGalvoOutputs()
Sets all galvos to zero position, needed for microscope alignment.
Starts a DAQmx task that waits until the digital line is either high or low (depending on _waitforhig...
void Load(const std::wstring &filename)
Load all from file.
std::array< ScopeNumber< uint32_t >, SCOPE_NAREAS > frames
number of frames in timeseries for each area
Impl()
Initializes and connects stuff.
Base class for all Scope datatypes here, provides a uniform interface (and saves typing...).
Manages the display of images.
void AddWindow(const std::wstring &_type, const uint32_t &_area, HWND _hwnd)
Add a window to the collection.
StopCondition repeat_abort
thread-safe bool to signal a requested abort of a stack scan
T SetWithLimits(const T &v, const T &ll, const T &ul)
Sets new value and new limits at the same time.
std::array< std::shared_future< ControllerReturnStatus >, N_ACTIVES > futures
futures from the asynchronous Run worker functions
void SetHistogramLimits(const uint32_t &_area, const uint32_t &_channel, const uint16_t &_lower, const uint16_t &_upper)
Sets the color limits for displaying imgages, calls DisplayController::SetHistogramLimits.
Timeseries timeseries
the TimeseriesParameters
std::vector< std::array< PlaneProperties, SCOPE_NAREAS > > planes___
Vector with properties for every plane.
Behavior behavior
the BehaviorParameters
Storage storage
the StorageParameters
bool GetShutterState(const uint32_t &_area) const
A logger class to log various messages and user comments.
void StackStopHere()
Sets the stop stack position to the current z position.
The display controller handles displaying images and histograms.
std::array< ScannerVectorFrameBasicPtr, SCOPE_NAREAS > framescannervecs
Scanner vectors.
void DetachFrame(gui::CChannelFrame *const cframe)
Detaches a CChannelFrame as an observer.
void DetachFrame(gui::CHistogramFrame *const hframe)
Detach an observing CHistogramFrame.
void StartStack()
Start a stack scan by running RunStack asynchronously.
bool SaveParameters(const std::wstring &_filepath)
Saves the current parameter set to disk.
ScopeValue< DaqMode > requested_mode
requested acquisition mode (see DaqModeHelper)
void Log(const std::wstring &message, const log_message_type &msgtype)
Logs a message.
std::wstring currentconfigfile
currently loaded config
ScopeNumber< uint32_t > repeats
How many repeats should be acquired if not unlimited_repeats?
void StartAllControllers()
Starts all controllers with the current parameters.
SynchronizedQueue< ScopeMessage< SCOPE_MULTIIMAGEPTR_T > > pipeline_to_display
queue from the pipelines to the display
std::atomic< bool > onlineupdate_running
set if an online update is currently running, to prevent to simultaneous online update threads ...
void Stop()
Stops whatever scanning is going on and clears the queues.
void OnlineParameterUpdate(const parameters::Area &_areaparameters)
Changes daq parameters during live scan.
std::wstring GetCurrentDateString()
void SetScannerVectorParameters()
Set parameters for scanner vectors, since these are shared_ptr in DaqControllerDAQmx and PipelineCont...
DWORD time
stores the time to run a scan
void InitializeHardware()
(Re-)Initializes ScopeControllers own hardware components (XYControl/Stage, ZControl, and FPU stuff)
static ScopeNumber< double > PlaneCounter
Updated from ScopeControllerImpl::RunStack, connected to progress indicator in CStackSettingsPage.
bool GetSwitchResonanceState(const uint32_t &_area) const
ScopeNumber< bool > initialparametersloaded
true after parameter set on program start is loaded
void SetReadOnlyWhileScanning(const RunState &_runstate) override
set values that must not be changed to read-only during scanning.
std::wstring CurrentConfigFile() const
static std::unique_ptr< ScannerVectorFrameBasic > Factory(const ScannerVectorType &_type, const ScannerVectorFillType &_filltype)
A static factory method for scan vectors.
#define DBOUT(s)
A debug output to the debug console.
void Save(const std::wstring &filename) const
Save all to file.
void SetHistogramLimits(const uint32_t &_area, const uint32_t &_channel, const uint16_t &_lower, const uint16_t &_upper)
calls DisplayController::Impl::SetHistogramLimits
The StorageController controls the conversion of multi images to TIFF and the storage of those...
void ScopeExceptionHandler(const std::string &_origin, const bool &_log, const bool &_showmessagebox, const bool &_trace, const bool &_rethrow)
Handles all exceptions and does nice logging.
void Start(const parameters::Scope &_parameters)
Start the controller, calls BaseController::Impl::Start.
Manages the display of histograms.
void ClearAfterStop()
Clears queues, resets run state, and reenables controls.
ControllerReturnStatus RunStack(StopCondition *const sc)
Worker function to control a stack scan.
static ScopeNumber< double > TotalTime
Updated from e.g.
void WaitForAllControllers()
Waits for all controllers to intrinsically finish.
static std::array< ScanModeButtons, SCOPE_NAREAS > ScanMode
Buttons for switching the scan mode.
void StackStartHere()
Sets the start stack position to the current z position.
void AttachFrame(gui::CHistogramFrame *const hframe)
Attach a CHistogramFrame as observer.
void StartLive()
Starts live scanning by running RunLive asynchronously.
void AttachFrame(gui::CChannelFrame *const cframe)
Attaches a CChannelFrame as an observer.
A synchronized, thread-safe queue was modeled after ringbuffer example from boost?! and/or a Herb Sutter column?!
void StartSingle()
Starts a single frame scan by running RunSingle asynchronously.
ScopeString time
current time
ScopeValue< RunState > run_state
current RunState
ControllerReturnStatus RunLive(StopCondition *const sc)
Worker function to control live scanning (basically only starting everything up)
void TurnOnOffSwitchResonance(const uint32_t &_area, const bool &_on)
Turns the resonance scanner relay on and off.
void SetScanMode(const uint32_t &_area, const ScannerVectorType &_mode)
Sets the type of scanning.
void Set(const bool &_a=true)
void PrepareQuit()
Called via CMainDialogFrame::QuitApplication.
parameters::WindowCollection GetWindowCollection() const
Adds frames to WindowCollection of ScopeController::GuiParameters.
std::array< PlaneProperties, SCOPE_NAREAS > stopat
Stop plane, measured with the zdevicetype.
std::vector< std::array< PlaneProperties, SCOPE_NAREAS > > planes
vector with properties for all planes, for alternating planes on repeating timeseries, one for each area
void SaveCurrentWindowPositions()
Saves current positions of windows by adding frames to WindowCollection of ScopeController::GuiParame...
static std::array< FPUButtons, SCOPE_NAREAS > FPU
Buttons for FPU nudge.
ScopeNumber< double > betweenrepeats
Time in seconds between the beginning of one and beginning of the next timeseries.
std::array< SynchronizedQueue< ScopeMessage< SCOPE_DAQCHUNKPTR_T > >, SCOPE_NAREAS > daq_to_pipeline
queues from the daqs to the pipelines
static std::array< ScopeNumber< double >, SCOPE_NAREAS > SingleFrameProgress
Updated from PipelineControllerImpl::Run.
std::vector< std::function< void(const uint32_t &, const ScannerVectorType &)> > scanmodecallbacks
list of callbacks for scan mode switching
static parameters::Scope GuiParameters
The complete pseudo-global parameter set of the microscope.
Base class for all controllers.
void TurnOnOffSwitchResonance(const uint32_t &_area, const bool &_on)
Turns the resonance scanner relay on and off.
void ZeroGalvoOutputs()
Calls the DaqController to set Galvo outputs to zero.
bool HistogramAlreadyAttached(const uint32_t &_area) const
std::array< std::unique_ptr< SCOPE_FPUXYCONTROL_T >, SCOPE_NAREAS > theXYStages
for xy movement of FPU stages
ControllerReturnStatus RunBehavior(StopCondition *const sc)
Worker function to control a behavior triggered scan.
bool HistogramAlreadyAttached(const uint32_t &_area)
static ScopeNumber< bool > ReadOnlyWhileScanning
Set to true while scanning, GUI elements can connect to this to disable buttons and controls (that ar...
static ScopeNumber< double > RepeatCounter
Updated from ScopeControllerImpl::RunTimeseries, connected to progress indicator in CTimeSeriesSettin...
ScopeString gateline
The DAQmx digital line for gating.
void ClearAllQueues()
Clear all queues between controllers.
SynchronizedQueue< ScopeMessage< SCOPE_MULTIIMAGEPTR_T > > pipeline_to_storage
queue from the pipelines to the storage
HWND GetLogFrameWindow()
Saves log frame parameters into Window (for recreating windows on startup).
std::wstring GetCurrentTimeString(const bool &_filenamecompatible)
static std::vector< ScannerVectorTypeHelper::Mode > List(const ScannerTypeHelper::Mode &_scannertype=SCOPE_SCANNERTYPE)
Returns a vector with all supported scannervectors for a given scannertype.
The implementation class of the ScopeController.
bool GetSwitchResonanceState(const uint32_t &_area) const