diff --git a/src/gui/nisettingswidget.cpp b/src/gui/nisettingswidget.cpp index b6149f8..b8b3a14 100644 --- a/src/gui/nisettingswidget.cpp +++ b/src/gui/nisettingswidget.cpp @@ -5,6 +5,7 @@ #include "spim.h" #include "tasks.h" +#include #include #include #include @@ -24,6 +25,8 @@ void NISettingsWidget::setupUI() QComboBox *comboBox; + QCheckBox *checkBox; + CameraTrigger *cameraTrigger = spim().getTasks()->getCameraTrigger(); QStringList terminals = NI::getTerminals().filter("PFI"); @@ -36,6 +39,7 @@ void NISettingsWidget::setupUI() QList galvoRampComboBoxList; QList blankingComboBoxList; QList cameraTriggerPulseComboBoxList; + QList checkBoxes; int row = 0; for (int i = 0; i < SPIM_NCAMS; ++i) { @@ -59,12 +63,18 @@ void NISettingsWidget::setupUI() grid->addWidget(new QLabel("Galvo"), row, i * 2 + 0); comboBox = new QComboBox(); comboBox->addItems(NI::getAOPhysicalChans()); + #ifdef DEMO_MODE comboBox->addItems({"DemoDev/ao0", "DemoDev/ao1"}); #endif comboBox->setCurrentText(spim().getTasks()->getGalvoRamp()->getPhysicalChannels().at(i)); grid->addWidget(comboBox, row++, i * 2 + 1); galvoRampComboBoxList.insert(i, comboBox); + + grid->addWidget(new QLabel("Enabled"), row, i * 2 + 0); + checkBox = new QCheckBox(); + grid->addWidget(checkBox, row++, i * 2 + 1); + checkBoxes.insert(i, checkBox); } QFrame *line = new QFrame; @@ -111,4 +121,13 @@ void NISettingsWidget::setupUI() for (QComboBox *combo : allCombos) { connect(combo, QOverload::of(&QComboBox::activated), [=]() { apply(); }); } + + int i = 0; + for (QCheckBox *checkBox : checkBoxes) { + connect(checkBox, &QCheckBox::toggled, [=](bool checked) { + spim().setCameraEnabled(i, checkBox->QCheckBox::isChecked()); + }); + checkBox->setChecked(spim().isCameraEnabled(i)); + i++; + } } diff --git a/src/gui/progresswidget.cpp b/src/gui/progresswidget.cpp index bf40eb5..e632846 100644 --- a/src/gui/progresswidget.cpp +++ b/src/gui/progresswidget.cpp @@ -84,8 +84,10 @@ void ProgressWidget::setupUI() connect(timer, &QTimer::timeout, this, [=]() { for (int i = 0; i < SPIM_NCAMS; ++i) { - stackPbList.at(i)->setRange(0, spim().getSSWorker(i)->getFrameCount()); - stackPbList.at(i)->setValue(spim().getSSWorker(i)->getReadFrames()); + if (spim().isCameraEnabled(i)) { + stackPbList.at(i)->setRange(0, spim().getSSWorker(i)->getFrameCount()); + stackPbList.at(i)->setValue(spim().getSSWorker(i)->getReadFrames()); + } } }); @@ -94,7 +96,8 @@ void ProgressWidget::setupUI() timer->start(1000); for (int i = 0; i < SPIM_NCAMS; ++i) { stackPbList.at(i)->reset(); - }}); + } + }); connect(s, &QState::exited, timer, &QTimer::stop); connect(s, &QState::exited, this, [=]() { @@ -115,7 +118,9 @@ void ProgressWidget::setupUI() etaLabel->setText(startDateTime->addSecs(remainingSeconds).toString()); progressBar->setValue(currentStep); for (int i = 0; i < SPIM_NCAMS; ++i) { - stackPbList.at(i)->setValue(spim().getSSWorker(i)->getReadFrames()); + if (spim().isCameraEnabled(i)) { + stackPbList.at(i)->setValue(spim().getSSWorker(i)->getReadFrames()); + } } }); } diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index a47cbb8..af0559c 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -52,6 +52,7 @@ #define SETTING_EXPTIME "exposureTime" #define SETTING_RUN_NAME "runName" #define SETTING_BINNING "binning" +#define SETTING_ENABLED_CAMERAS "CameraEnabled" #define SETTING_TURN_OFF_LASERS_AT_END_OF_ACQUISITION "turnOffLasersAtEndOfAcquisition" @@ -144,9 +145,19 @@ void Settings::loadSettings() SET_VALUE(group, SETTING_EXPTIME, 0.15); SET_VALUE(group, SETTING_RUN_NAME, QString()); SET_VALUE(group, SETTING_BINNING, 1); - settings.endGroup(); + groups.clear(); + for (int i = 0; i < SPIM_NCAMS; ++i) { + groups << SETTINGSGROUP_CAMERAS(i); + } + + for (const QString &group : groups) { + settings.beginGroup(group); + SET_VALUE(group, SETTING_ENABLED_CAMERAS, false); + settings.endGroup(); + } + groups.clear(); for (int i = 0; i < SPIM_NCOBOLT; ++i) { groups << SETTINGSGROUP_COBOLT(i); @@ -255,6 +266,11 @@ void Settings::loadSettings() spim().setRunName(value(group, SETTING_RUN_NAME).toString()); spim().setBinning(value(group, SETTING_BINNING).toUInt()); + for (int i = 0; i < SPIM_NCAMS; ++i) { + group = SETTINGSGROUP_CAMERAS(i); + spim().setCameraEnabled(i, value(group, SETTING_ENABLED_CAMERAS).toBool()); + } + #endif group = SETTINGSGROUP_OTHERSETTINGS; @@ -330,6 +346,11 @@ void Settings::saveSettings() setValue(group, SETTING_EXPTIME, spim().getExposureTime()); setValue(group, SETTING_RUN_NAME, spim().getRunName()); setValue(group, SETTING_BINNING, spim().getBinning()); + + for (int i = 0; i < SPIM_NCAMS; ++i) { + group = SETTINGSGROUP_CAMERAS(i); + setValue(group, SETTING_ENABLED_CAMERAS, spim().isCameraEnabled(i)); + } #endif group = SETTINGSGROUP_OTHERSETTINGS; #ifdef MASTER_SPIM diff --git a/src/gui/settings.h b/src/gui/settings.h index 5ba9d5a..47a2513 100644 --- a/src/gui/settings.h +++ b/src/gui/settings.h @@ -7,6 +7,7 @@ #define SETTINGSGROUP_OTHERSETTINGS "OtherSettings" #define SETTINGSGROUP_AXIS(n) QString("AXIS_%1").arg(n) +#define SETTINGSGROUP_CAMERAS(n) QString("CAMERA_%1").arg(n) #define SETTINGSGROUP_FILTERWHEEL(n) QString("FilterWheel_%1").arg(n) #define SETTING_LUTPATH "LUTPath" diff --git a/src/gui/spim.cpp b/src/gui/spim.cpp index bc90210..f11804d 100644 --- a/src/gui/spim.cpp +++ b/src/gui/spim.cpp @@ -23,6 +23,7 @@ #include #include #include + #endif static Logger *logger = getLogger("SPIM"); @@ -87,6 +88,10 @@ SPIM::SPIM(QObject *parent) enabledMosaicStageMap[dev] = false; } + for (int i = 0; i < SPIM_NCAMS; ++i) { + camEnabled << false; + } + PIDevice *xaxis = getPIDevice(PI_DEVICE_X_AXIS); connect(xaxis, &PIDevice::connected, this, [=]() { xaxis->setTriggerOutput(PIDevice::OUTPUT_1, PIDevice::Axis, 1); @@ -224,6 +229,22 @@ void SPIM::setMosaicStageEnabled(SPIM_PI_DEVICES dev, bool enable) enabledMosaicStageMap[dev] = enable; } +bool SPIM::isCameraEnabled(uint camera) +{ + return camEnabled[camera]; +} + +void SPIM::setCameraEnabled(uint camera, bool enable) +{ + camEnabled[camera] = enable; +} + +int SPIM::nEnabledCameras() +{ + int nEnabledCameras = std::count(camEnabled.begin(), camEnabled.end(), true); + return nEnabledCameras; +} + QString SPIM::getRunName() const { return runName; @@ -292,63 +313,82 @@ OrcaFlash *SPIM::getCamera(int camNumber) const } void SPIM::startFreeRun() { - freeRun = true; - logger->info("Start free run"); - _startCapture(); + try { + if (nEnabledCameras() == 0) { + throw std::runtime_error( + QString("Can't start free run with no cameras enabled").toStdString()); + } + freeRun = true; + logger->info("Start free run"); + _startCapture(); + } catch (std::runtime_error e) { + onError(e.what()); + return; + } } bool SPIM::startAcquisition() { - freeRun = false; - logger->info("Start acquisition"); + try { + if (nEnabledCameras() == 0) { + throw std::runtime_error( + QString("Can't start capture with no cameras enabled").toStdString()); + } + freeRun = false; + logger->info("Start acquisition"); #ifdef MASTER_SPIM - enabledMosaicStages.clear(); - for (const SPIM_PI_DEVICES d_enum : mosaicStages) { - if (enabledMosaicStageMap[d_enum]) { - enabledMosaicStages << d_enum; + enabledMosaicStages.clear(); + for (const SPIM_PI_DEVICES d_enum : mosaicStages) { + if (enabledMosaicStageMap[d_enum]) { + enabledMosaicStages << d_enum; + } } - } - QList stageEnumList; - stageEnumList << enabledMosaicStages << stackStage; + QList stageEnumList; + stageEnumList << enabledMosaicStages << stackStage; - QList stageList; - for (const SPIM_PI_DEVICES d_enum : stageEnumList) { - stageList << getPIDevice(d_enum); + QList stageList; + for (const SPIM_PI_DEVICES d_enum : stageEnumList) { + stageList << getPIDevice(d_enum); + + int from = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_FROM_IDX) + * pow(10, SPIM_SCAN_DECIMALS)); + int to = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_TO_IDX) + * pow(10, SPIM_SCAN_DECIMALS)); + int step = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_STEP_IDX) + * pow(10, SPIM_SCAN_DECIMALS)); - int from = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_FROM_IDX) - * pow(10, SPIM_SCAN_DECIMALS)); - int to = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_TO_IDX) - * pow(10, SPIM_SCAN_DECIMALS)); - int step = static_cast(scanRangeMap[d_enum]->at(SPIM_RANGE_STEP_IDX) - * pow(10, SPIM_SCAN_DECIMALS)); - - if (step == 0) { - nSteps[d_enum] = 1; - } else { - nSteps[d_enum] = static_cast(ceil((to - from) / step) + 1); + if (step == 0) { + nSteps[d_enum] = 1; + } else { + nSteps[d_enum] = static_cast(ceil((to - from) / step) + 1); + } } - } - totalSteps = 1; - for (const SPIM_PI_DEVICES d_enum : enabledMosaicStages) { - totalSteps *= nSteps[d_enum]; - currentSteps[d_enum] = 0; - } - logger->info(QString("Total number of stacks to acquire: %1 (with %2 frames in each)") - .arg(totalSteps) - .arg(nSteps[stackStage])); + totalSteps = 1; + for (const SPIM_PI_DEVICES d_enum : enabledMosaicStages) { + totalSteps *= nSteps[d_enum]; + currentSteps[d_enum] = 0; + } + logger->info(QString("Total number of stacks to acquire: %1 (with %2 frames in each)") + .arg(totalSteps) + .arg(nSteps[stackStage])); - currentStep = 0; + currentStep = 0; #endif - // create output directories - for (int i = 0; i < SPIM_NCAMS; ++i) { - getFullOutputDir(i).mkpath("."); - } + // create output directories + for (int i = 0; i < SPIM_NCAMS; ++i) { + getFullOutputDir(i).mkpath("."); + } - _startCapture(); + _startCapture(); + + } catch (std::runtime_error e) { + onError(e.what()); + return false; + } return true; } @@ -411,8 +451,10 @@ void SPIM::setupStateMachine() QState *freeRunState = newState(STATE_FREERUN, capturingState); connect(freeRunState, &QState::entered, this, [=]() { try { - for (OrcaFlash *orca : camList) { - orca->cap_start(); + for (int i = 0; i < SPIM_NCAMS; ++i) { + if (camEnabled[i]) { + camList[i]->cap_start(); + } } #ifdef MASTER_SPIM @@ -580,17 +622,21 @@ void SPIM::setupStateMachine() // prepare and start acquisition thread for (int i = 0; i < SPIM_NCAMS; ++i) { - SaveStackWorker *ssWorker = ssWorkerList.at(i); - ssWorker->setTimeout(2 * 1e6 / getTriggerRate()); - ssWorker->setOutputPath(getFullOutputDir(i).absolutePath()); - ssWorker->setOutputFileName(outputFname + "_cam_" + side.at(i)); - ssWorker->setFrameCount(frameCount); - ssWorker->setBinning(binning); + if (camEnabled[i]) { + SaveStackWorker *ssWorker = ssWorkerList.at(i); + ssWorker->setTimeout(2 * 1e6 / getTriggerRate()); + ssWorker->setOutputPath(getFullOutputDir(i).absolutePath()); + ssWorker->setOutputFileName(outputFname + "_cam_" + side.at(i)); + ssWorker->setFrameCount(frameCount); + ssWorker->setBinning(binning); + } } for (int i = 0; i < SPIM_NCAMS; ++i) { - camList.at(i)->cap_start(); - QMetaObject::invokeMethod(ssWorkerList.at(i), &SaveStackWorker::start); + if (camEnabled[i]) { + camList.at(i)->cap_start(); + QMetaObject::invokeMethod(ssWorkerList.at(i), &SaveStackWorker::start); + } } #ifdef MASTER_SPIM tasks->start(); @@ -686,7 +732,7 @@ void SPIM::_setExposureTime(double expTime) void SPIM::incrementCompleted(bool ok) { -#define EXPECTED_N_JOBS SPIM_NCAMS +#define EXPECTED_N_JOBS nEnabledCameras() if (freeRun) { return; } diff --git a/src/gui/spim.h b/src/gui/spim.h index 58e521d..a2d2e29 100644 --- a/src/gui/spim.h +++ b/src/gui/spim.h @@ -101,6 +101,10 @@ class SPIM : public QObject bool isMosaicStageEnabled(SPIM_PI_DEVICES dev) const; void setMosaicStageEnabled(SPIM_PI_DEVICES dev, bool enable); + bool isCameraEnabled(uint dev); + void setCameraEnabled(uint camera, bool enable); + int nEnabledCameras(); + int getBinning() const; bool setBinning(uint value); @@ -168,6 +172,7 @@ public slots: QList camList; QList ssWorkerList; + QList camEnabled; QStateMachine *sm = nullptr;