void ExperimentController::holdStepCallback(Poco::Timer &) { bool isLast = false; { Poco::RWLock::ScopedWriteLock lock(*_machineMutex); if (_machineState != RunningMachineState) return; if (_experiment.protocol()->currentStage()->type() != Stage::Meltcurve) _dbControl->addFluorescenceData(_experiment, OpticsInstance::getInstance()->getFluorescenceData()); if (_experiment.protocol()->hasNextStep()) { _experiment.protocol()->advanceNextStep(); Stage *stage = _experiment.protocol()->currentStage(); double temperature = stage->currentStep()->temperature(); if (stage->autoDelta() && stage->currentCycle() > stage->autoDeltaStartCycle()) { temperature += stage->currentStep()->deltaTemperature() * (stage->currentCycle() - stage->autoDeltaStartCycle()); if (temperature < HeatBlockInstance::getInstance()->minTargetTemperature()) temperature = HeatBlockInstance::getInstance()->minTargetTemperature(); else if (temperature > HeatBlockInstance::getInstance()->maxTargetTemperature()) temperature = HeatBlockInstance::getInstance()->maxTargetTemperature(); } if (stage->currentRamp()->collectData()) { OpticsInstance::getInstance()->setCollectData(true, stage->type() == Stage::Meltcurve); if (stage->type() == Stage::Meltcurve) { _meltCurveTimer->setPeriodicInterval(STORE_MELT_CURVE_DATA_INTERVAL); _meltCurveTimer->start(Poco::TimerCallback<ExperimentController>(*this, &ExperimentController::meltCurveCallback)); } } _thermalState = HeatBlockInstance::getInstance()->temperature() < temperature ? HeatingThermalState : CoolingThermalState; OpticsInstance::getInstance()->getLedController()->setIntensity(stage->currentRamp()->excitationIntensity()); HeatBlockInstance::getInstance()->setTargetTemperature(temperature, stage->currentRamp()->rate()); HeatBlockInstance::getInstance()->enableStepProcessing(); } else isLast = true; } if (!isLast) calculateEstimatedDuration(); else { complete(); stop(); } }
void ExperimentController::stop() { MachineState state = IdleMachineState; { Poco::RWLock::ScopedWriteLock lock(*_machineMutex); if (_machineState == IdleMachineState) return; else if (_machineState == CompleteMachineState && _experiment.protocol()->currentStage()->type() != Stage::Meltcurve) { //Check if it was infinite hold step Stage *stage = _experiment.protocol()->currentStage(); std::time_t holdTime = stage->currentStep()->holdTime(); if (stage->autoDelta() && stage->currentCycle() > stage->autoDeltaStartCycle()) { holdTime += stage->currentStep()->deltaDuration() * (stage->currentCycle() - stage->autoDeltaStartCycle()); if (holdTime < 0) holdTime = 0; } if (holdTime == 0) _dbControl->addFluorescenceData(_experiment, OpticsInstance::getInstance()->getFluorescenceData()); } LidInstance::getInstance()->setEnableMode(false); HeatBlockInstance::getInstance()->setEnableMode(false); OpticsInstance::getInstance()->setCollectData(false); if (_machineState != CompleteMachineState) { _experiment.setCompletionStatus(Experiment::Aborted); _experiment.setCompletedAt(boost::posix_time::microsec_clock::local_time()); _dbControl->completeExperiment(_experiment); } state = _machineState; _machineState = IdleMachineState; _thermalState = IdleThermalState; _experiment = Experiment(); } if (state != CompleteMachineState) { stopLogging(); _holdStepTimer->stop(); _meltCurveTimer->stop(); } }
void ExperimentController::stepBegun() { bool onPause = false; _holdStepTimer->stop(); { Poco::RWLock::ScopedWriteLock lock(*_machineMutex); if (_machineState != RunningMachineState) return; Stage *stage = _experiment.protocol()->currentStage(); if (!stage->currentStep()->pauseState()) { std::time_t holdTime = stage->currentStep()->holdTime(); if (stage->autoDelta() && stage->currentCycle() > stage->autoDeltaStartCycle()) { holdTime += stage->currentStep()->deltaDuration() * (stage->currentCycle() - stage->autoDeltaStartCycle()); if (holdTime < 0) holdTime = 0; } if (holdTime > 0 || _experiment.protocol()->hasNextStep()) { _holdStepTimer->setStartInterval(holdTime * 1000); _holdStepTimer->start(Poco::TimerCallback<ExperimentController>(*this, &ExperimentController::holdStepCallback)); return; } } else { _experiment.setPauseTime(boost::posix_time::microsec_clock::local_time()); _machineState = PausedMachineState; onPause = true; } } if (!onPause) complete(); else calculateEstimatedDuration(); }
void ExperimentController::calculateEstimatedDuration() { Experiment experiment = this->experiment(); double duration = (boost::posix_time::microsec_clock::local_time() - experiment.startedAt()).total_milliseconds() - (experiment.pausedDuration() * 1000); double previousTargetTemp = HeatBlockInstance::getInstance()->temperature(); do { Stage *stage = experiment.protocol()->currentStage(); std::time_t holdTime = stage->currentStep()->holdTime(); double temperature = stage->currentStep()->temperature(); if (stage->autoDelta() && stage->currentCycle() > stage->autoDeltaStartCycle()) { holdTime += stage->currentStep()->deltaDuration() * (stage->currentCycle() - stage->autoDeltaStartCycle()); if (holdTime < 0) holdTime = 0; temperature += stage->currentStep()->deltaTemperature() * (stage->currentCycle() - stage->autoDeltaStartCycle()); if (temperature < HeatBlockInstance::getInstance()->minTargetTemperature()) temperature = HeatBlockInstance::getInstance()->minTargetTemperature(); else if (temperature > HeatBlockInstance::getInstance()->maxTargetTemperature()) temperature = HeatBlockInstance::getInstance()->maxTargetTemperature(); } double rate = stage->currentRamp()->rate(); rate = rate > 0 && rate <= kDurationCalcHeatBlockRampSpeed ? rate : kDurationCalcHeatBlockRampSpeed; if (previousTargetTemp < temperature) duration += (((temperature - previousTargetTemp) / rate) + holdTime) * 1000; else duration += (((previousTargetTemp - temperature) / rate) + holdTime) * 1000; previousTargetTemp = temperature; } while (experiment.protocol()->advanceNextStep()); { Poco::RWLock::ScopedWriteLock lock(*_machineMutex); _experiment.setEstimatedDuration(std::round(duration / 1000)); } }