Commit 47da5e7e authored by yannick legoc's avatar yannick legoc
Browse files
parents f55bea81 ae8e527f
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#include "HplcControllerTest.h"
#include "drivers/knauer/foxy/FoxyR1DriverDef.h"
namespace d22special {
const std::string HplcControllerTest::TYPE = "hplc_test";
const int32 HplcControllerTest::VALVE_LOAD_POS = 1;
const int32 HplcControllerTest::VALVE_INJECT_POS = 2;
const char HplcControllerTest::COLUMN_H[] = "H";
const char HplcControllerTest::COLUMN_D[] = "D";
HplcControllerTest::HplcControllerTest(const std::string& controllerName) :
ExperimentController(controllerName), controller::Stoppable(this) {
columnMeasured.init(this, SAVE | SPY, "column_measured", "Column");
valvePositionForElution.init(this, SAVE, "valve_pos_elution");
valvePositionForEquilibration.init(this, SAVE, "valve_pos_equilibration");
doEquilibrationPhase.init(this, SAVE, "doEquilibration_phase");
equilibrationFlowRate.init(this, SAVE, "equil_flowRate");
elutionFlowRate.init(this, SAVE, "elution_flowRate");
sampleName.init(this, NOSAVE, "sample_name");
sampleVolume.init(this, SAVE, "sample_volume");
samplePosition.init(this, SAVE, "sample_position");
collectSample.init(this, SAVE, "collect_sample");
collectInInitialPos.init(this, SAVE, "collect_in_initial_pos");
fractionVolume.init(this, SAVE, "fraction_volume");
numExposures.init(this, SAVE, "num_exposures");
exposureTime.init(this, SAVE, "exposure_time");
saveCountData.init(this, SAVE, "save_countData");
m_pumpH.init(this, "pumpH");
m_pumpD.init(this, "pumpD");
m_alias.init(this, "alias");
m_collector.init(this, "collector");
m_detector.init(this, "detector");
m_valveH.init(this, "valveH");
m_valveD.init(this, "valveD");
m_valvePOST.init(this, "valvePOST");
m_valveANTE.init(this, "valveANTE");
m_count.init(this, "count");
}
HplcControllerTest::~HplcControllerTest() {
}
void HplcControllerTest::start() {
commandStatus.setRunning();
// (1) Configure all controllers involved
configureControllers();
// (2) Start Injection + Elution in columnMeasured() and Equilibration (if setup) in the other column
// Move valves
m_valveANTE->start();
m_valvePOST->start();
m_valveH->start();
m_valveD->start();
// Start pumps
if (doEquilibrationPhase()) {
m_pumpH->start();
m_pumpD->start();
} else {
if (columnMeasured() == COLUMN_H) {
m_pumpH->start();
} else if (columnMeasured() == COLUMN_D) {
m_pumpD->start();
} else {
// Error
}
}
// Make autozero of detector once the pumps are running
// m_detector->calculateI0();
// Do injection (check order of execution)
m_alias->start();
// Check condition for data acquisition start -> this is done by the detector
// m_detector->flowRate = elutionFlowRate(); // IMPORTANT!! When the thresholdCondition is a slope, the detector needs to know the current flowRate
// Modification 06/02/2019: Start data acquisition measure from the start. Threshold condition ONLY USED to change flow rate.
doDataAcquisition();
// Stop everything
stop();
}
void HplcControllerTest::stop() {
if (m_pumpH->commandStatus.isRunning()) {
m_pumpH->stopParallel();
}
if (m_pumpD->commandStatus.isRunning()) {
m_pumpD->stopParallel();
}
m_detector->stopParallel();
m_count->stopParallel();
// if (m_alias->deviceStatus() != knauer_alias::NO_RUNNING_STATUS) {
//only stop alias if there is a problem
m_alias->stopParallel();
// }
// Pause behaviour of the collector has been changed!
if (m_collector->commandStatus.isRunning()) {
m_collector->stopAtPosition();
}
commandStatus.setIdle();
commandProgression = 100;
log(Level::s_Info) << name << emptycursor << "stopped " << endlog;
}
void HplcControllerTest::configureControllers() {
if (columnMeasured() == COLUMN_H) {
std::cout << "Doing measure in column H" << std::endl;
// ValveANTE = I, valvePOST = L. ValveH + PumpH->Elution + Data Measurement. ValveD + PumpD -> equilibration
// Set up valves
m_valveANTE->valveValue.setpoint = VALVE_INJECT_POS;
m_valvePOST->valveValue.setpoint = VALVE_LOAD_POS;
m_valveH->valveValue.setpoint = valvePositionForElution();
m_valveD->valveValue.setpoint = valvePositionForEquilibration();
// Set up pumps flow rates
m_pumpH->flowRate.setpoint = elutionFlowRate();
m_pumpD->flowRate.setpoint = equilibrationFlowRate();
// timeOutValue = (1.5 * columnVolumeH() / elutionFlowRate()) * 60;
} else if (columnMeasured() == COLUMN_D) {
std::cout << "Doing measure in column D" << std::endl;
// Set up valves
m_valveANTE->valveValue.setpoint = VALVE_LOAD_POS;
m_valvePOST->valveValue.setpoint = VALVE_INJECT_POS;
m_valveH->valveValue.setpoint = valvePositionForEquilibration();
m_valveD->valveValue.setpoint = valvePositionForElution();
// Set up pumps flow rates
m_pumpH->flowRate.setpoint = equilibrationFlowRate();
m_pumpD->flowRate.setpoint = elutionFlowRate();
// timeOutValue = (1.5 * columnVolumeD() / elutionFlowRate()) * 60;
} else {
// ERROR
}
// Set up Injector
m_alias->firstPosition = samplePosition();
m_alias->injectionVolume = sampleVolume();
// Set up Collector (this can be done later during the data acquisition phase)
if (collectSample()) {
m_collector->collectionMode = foxy_r1::TIME_MODE; // Default set up
m_collector->fractionVolume = fractionVolume() * 60; // In seconds
m_collector->flowDelay = 0;
if (collectInInitialPos()) {
m_collector->resetPosition();
}
}
std::cout << "setting flow delay to " << m_collector->flowDelay() << std::endl;
// Set up UV Detector -> simple case NO THRESHOLD
m_detector->timeOfMeasure = (numExposures() * exposureTime()) - 2; // timeOfMeasure is in seconds
// m_detector->timeOutValue = timeOutValue; //in seconds!
// Set up Count
m_count->time.setpoint = exposureTime();
m_count->timeType = "s";
m_count->totalReps = numExposures();
m_count->saveData = saveCountData();
m_count->subtitle = sampleName();
}
void HplcControllerTest::doDataAcquisition() {
// (1) Start collector if collectSample() == true
if (collectSample()) {
m_collector->start();
}
// (2) Do measure
boost::thread_group group;
group.create_thread(boost::bind(&HplcControllerTest::startCount, this));
group.create_thread(boost::bind(&HplcControllerTest::startDetector, this));
// Wait for the termination of the threads
group.join_all();
}
void HplcControllerTest::startCount() {
m_count->startCommand();
}
void HplcControllerTest::startDetector() {
m_detector->doContinuousMeasurement();
}
}
/*
* Nomad Instrument Control Software
*
* Copyright 2011 Institut Laue-Langevin
*
* Licensed under the EUPL, Version 1.1 only (the "License");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://joinup.ec.europa.eu/software/page/eupl
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the Licence is distributed on an "AS IS" basis,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Licence for the specific language governing permissions and
* limitations under the Licence.
*/
#ifndef SRC_CONTROLLERS_LSS_D22SPECIAL_HPLCCONTROLLERTEST_H_
#define SRC_CONTROLLERS_LSS_D22SPECIAL_HPLCCONTROLLERTEST_H_
#include <Controller.h>
#include "controllers/lss/d22/hplc/PumpController.h"
#include "controllers/lss/d22/hplc/AliasController.h"
#include "controllers/lss/d22/hplc/CollectorController.h"
#include "controllers/spectrometer/QE65000Controller.h"
#include "controllers/lss/d22/hplc/HplcValveController.h"
#include "controllers/common/acquisition/TimeCount.h"
namespace d22special {
/*
* THIS CLASS IS USED TO DO TESTS USING THE QE65000 controller as a replacement of the Knauer detector!
*
*/
class HplcControllerTest : public ExperimentController, public controller::Stoppable {
public:
static const std::string TYPE;
HplcControllerTest(const std::string& controllerName);
virtual ~HplcControllerTest();
virtual void start();
virtual void stop();
Property<std::string> columnMeasured;
Property<int32> valvePositionForElution;
Property<int32> valvePositionForEquilibration;
Property<bool> doEquilibrationPhase;
Property<float64> equilibrationFlowRate;
Property<float64> elutionFlowRate;
Property<std::string> sampleName;
Property<std::string> samplePosition;
Property<int32> sampleVolume;
Property<bool> collectSample;
Property<bool> collectInInitialPos;
Property<float64> fractionVolume;
Property<int32> numExposures; // For count management
Property<int32> exposureTime; // For count management
Property<bool> saveCountData; // For count management
ControllerPtr<d22::PumpController> m_pumpH;
ControllerPtr<d22::PumpController> m_pumpD;
ControllerPtr<d22::AliasController> m_alias;
ControllerPtr<d22::CollectorController> m_collector;
ControllerPtr<spectrometer::QE65000Controller> m_detector; // Using QE65000 detector
ControllerPtr<ValveController> m_valveH; // Be careful with the type of valve
ControllerPtr<ValveController> m_valveD;
ControllerPtr<d22::HplcValveController> m_valvePOST;
ControllerPtr<d22::HplcValveController> m_valveANTE;
ControllerPtr<acquisition::TimeCount> m_count;
private:
void configureControllers();
void doDataAcquisition();
void startCount();
void startDetector();
static const int32 VALVE_LOAD_POS;
static const int32 VALVE_INJECT_POS;
static const char COLUMN_H[];
static const char COLUMN_D[];
};
}
#endif /* SRC_CONTROLLERS_LSS_D22SPECIAL_HPLCCONTROLLERTEST_H_ */
......@@ -3,4 +3,5 @@
<controller class="d22special::CountWithSpectro"/>
<controller class="d22special::DualSwitchSpectroController"/>
<controller class="d22special::D22SpectroSampleSequencer"/>
<controller class="d22special::HplcControllerTest" />
</module>
\ No newline at end of file
#Prefixes, suffixes and labels
hplc_test.injectionPhasePrefix= Injection
hplc_test.elutionPhasePrefix= Elution
hplc_test.equilibrationPhasePrefix= Equilibration
hplc_test.dataRecordingPhasePrefix= Data Recording
hplc_test.fractionCollectionPhasePrefix=Fraction Collection
hplc_test.sampleVolumePrefix=Injection of
hplc_test.samplePositionPrefix=of sample in position
hplc_test.columnTypePrefix=on column
hplc_test.valveElutionPosPrefix=Elution with buffer
hplc_test.elutionFlowRatePrefix=at a flow rate of
hplc_test.valveEquilibrationPosPrefix= Simultaneous equilibration of the other column with buffer
hplc_test.equilibrationFlowRatePrefix=at a flow rate of
hplc_test.numExposuresPrefix=SANS exposure:
hplc_test.fractionVolumePrefix=Fractions of
hplc_test.sampleNamePrefix=Title
hplc_test.flowRateUnitSuffix=mL/min
hplc_test.numExposuresSuffix= frames of
hplc_test.timeSuffix=sec
hplc_test.nanometerCommaSuffix=nm,
hplc_test.nanometerSuffix=nm
hplc_test.doCollectionSuffix=Collect Eluant
hplc_test.startAtInitialPosSuffix= Start at tube 1
hplc_test.microLiter=~muL
hplc_test.milliLiter=mL
hplc_test.bar=Bar
hplc_test.drops=drops
hplc_test.min=min
# Column type combo
hplc_test.columnHValue=H
hplc_test.columnDValue=D
hplc_test.columnHLabel=H
hplc_test.columnDLabel=D
# Elution Valve position combo
hplc_test.pos1Value=1
hplc_test.pos2Value=2
hplc_test.pos3Value=3
hplc_test.pos4Value=4
hplc_test.pos5Value=5
hplc_test.pos6Value=6
hplc_test.pos1Label=1
hplc_test.pos2Label=2
hplc_test.pos3Label=3
hplc_test.pos4Label=4
hplc_test.pos5Label=5
hplc_test.pos6Label=6
# Do equilibration check box values
hplc_test.doEquilibrationCheckedValue=true
hplc_test.doEquilibrationUncheckedValue=false
# Do collection check box
hplc_test.collectSampleCheckedValue=true
hplc_test.collectSampleUncheckedValue=false
# Start at initial position check box
hplc_test.collectInInitalPositionCheckedValue=true
hplc_test.collectInInitalPositionUncheckedValue=false
\ No newline at end of file
<controller_plugin_config type="hplc_test">
<image key="UV_SPECTRO" />
<settings view="hplc_testView.xml"/>
</controller_plugin_config>
\ No newline at end of file
<controller type="hplc_test">
</controller>
\ No newline at end of file
<plugin>
<controller type="hplc_test" role="hplc_test1" />
<newLine />
<!-- <text role="hplc_test1" property="column_vol_h" prefix="hplc_test.columnVolumeHPrefix" suffix="hplc_test.milliLiter" />
<text role="hplc_test1" property="column_vol_d" prefix="hplc_test.columnVolumeDPrefix" suffix="hplc_test.milliLiter" />
<text role="hplc_test1" property="max_pressure" prefix="hplc_test.maxPressurePrefix" suffix="hplc_test.bar" />
<newLine />
-->
<simple_label prefix="hplc_test.injectionPhasePrefix" font_style="BOLD" hAlignment="center" />
<newLine />
<text role="hplc_test1" property="sample_volume" prefix="hplc_test.sampleVolumePrefix" suffix="hplc_test.microLiter"/>
<text role="hplc_test1" property="sample_position" prefix="hplc_test.samplePositionPrefix" />
<combo role="hplc_test1" property="column_measured" prefix="hplc_test.columnTypePrefix" valuesAndLabels="hplc_test.columnH,hplc_test.columnD" />
<newLine />
<simple_label prefix="hplc_test.elutionPhasePrefix" font_style="BOLD" hAlignment="center" />
<newLine />
<combo role="hplc_test1" property="valve_pos_elution" prefix="hplc_test.valveElutionPosPrefix" valuesAndLabels="hplc_test.pos1,hplc_test.pos2,hplc_test.pos3,hplc_test.pos4,hplc_test.pos5,hplc_test.pos6" />
<text role="hplc_test1" property="elution_flowRate" prefix="hplc_test.elutionFlowRatePrefix" suffix="hplc_test.flowRateUnitSuffix" />
<newLine />
<newLine />
<simple_label prefix="hplc_test.equilibrationPhasePrefix" font_style="BOLD" hAlignment="center" />
<newLine />
<check role="hplc_test1" property="doEquilibration_phase" checkBoxValues="hplc_test.doEquilibration" />
<combo role="hplc_test1" property="valve_pos_equilibration" prefix="hplc_test.valveEquilibrationPosPrefix" valuesAndLabels="hplc_test.pos1,hplc_test.pos2,hplc_test.pos3,hplc_test.pos4,hplc_test.pos5,hplc_test.pos6" />
<text role="hplc_test1" property="equil_flowRate" prefix="hplc_test.flowRateUnitSuffix" />
<newLine />
<simple_label prefix="hplc_test.dataRecordingPhasePrefix" font_style="BOLD" hAlignment="center" />
<newLine />
<text role="hplc_test1" property="num_exposures" prefix="hplc_test.numExposuresPrefix" suffix="hplc_test.numExposuresSuffix"/>
<text role="hplc_test1" property="exposure_time" suffix="hplc_test.timeSuffix" />
<text role="hplc_test1" property="sample_name" prefix="hplc_test.sampleNamePrefix" />
<newLine />
<simple_label prefix="hplc_test.fractionCollectionPhasePrefix" font_style="BOLD" hAlignment="center" />
<newLine />
<check role="hplc_test1" property="collect_sample" checkBoxValues="hplc_test.collectSample" suffix="hplc_test.doCollectionSuffix"/>
<check role="hplc_test1" property="collect_in_initial_pos" checkBoxValues="hplc_test.collectInInitalPosition" suffix="hplc_test.startAtInitialPosSuffix"/>
<newLine />
<text role="hplc_test1" property="fraction_volume" prefix="hplc_test.fractionVolumePrefix" suffix="hplc_test.min" />
</plugin>
\ No newline at end of file
......@@ -42,7 +42,10 @@ QE65000Controller::QE65000Controller(const std::string& name) :
integrationTime.init(this, SAVE, "integration_time");
xData.init(this, NOSAVE, "x_data");
yData.init(this, NOSAVE, "y_data");
yDataBlock.init(this, NOSAVE, "y_data_block");
size.init(this, SAVE, "size");
blockSize.init(this, SAVE, "block_size");
zSize.init(this, SAVE, "z_size");
spectroStatus.init(this, SAVE, "spectro_status");
spectroStatusMessage.init(this, SAVE, "spectro_status_message");
spectroOpenErrorMessage.init(this, SAVE, "spectro_open_error_message");
......@@ -52,6 +55,8 @@ QE65000Controller::QE65000Controller(const std::string& name) :
numor.init(this, SAVE, "numor");
scansToAverage.init(this, SAVE, "scans_average");
timeOfMeasure.init(this, NOSAVE, "measure_time");
registerFunction(TYPE);
spectroDriver.init(this, "driver");
......@@ -81,6 +86,7 @@ void QE65000Controller::postConfiguration() {
//Get size from driver
size = spectroDriver->size();
zSize = 1;
}
void QE65000Controller::refreshIntegrationTime(int32 time) {
......@@ -123,7 +129,6 @@ void QE65000Controller::start() {
//Get size from driver
size = spectroDriver->size();
if (isConnected() && (!spectroDriver->openError())) {
common::Date startTime = common::Date();
......@@ -181,7 +186,6 @@ void QE65000Controller::start() {
finalYData[j] = finalYData[j] / scansToAverage();
}
}
}
}
......@@ -223,5 +227,74 @@ void QE65000Controller::setPlotName(int32 plotId) {
numor.update(plotId);
}
/*
* This method is called from HPLC system
*/
void QE65000Controller::doContinuousMeasurement() {
m_StopActivated = false;
// Move the init to another place
spectroDriver.execute("init", false);
// Initialize arrays of data and vectors
float64* tempYData = new float64[size()];
memset(tempYData, 0, size() * sizeof(float64));
yDataVector.clear();
// We assume to average measures
scansToAverage = 1;
// Measure until time is reached
common::Date startTime = common::Date();
common::Date actualTime = startTime;
common::Duration duration = actualTime - startTime;
while ((duration.getSeconds() < timeOfMeasure()) && (!m_StopActivated)) {
spectroDriver.execute("start", true);
// Last size of data measured
int32 yDataSize = spectroDriver->size();
tempYData = spectroDriver->yData();
for (int32 j = 0; j < yDataSize; j++) {
yDataVector.push_back(tempYData[j]);
}
// Update time
actualTime = common::Date();
duration = (actualTime - startTime);
// Update data used for graphical purposes
xData.update(spectroDriver->xData());
xData.setSize(size());
yData.update(spectroDriver->yData());
yData.setSize(size());
xData.sendEvent();
yData.sendEvent();
// Clear content
// tempYData = {0};
}
// Once finished copy data in property
int32 vectorSize = yDataVector.size();
float64* tempYBlockData = new float64[vectorSize];
memset(tempYBlockData, 0, vectorSize * sizeof(float64));
std::copy(yDataVector.begin(), yDataVector.end(), tempYBlockData);
yDataBlock.update(tempYBlockData);
yDataBlock.setSize(vectorSize);
blockSize = vectorSize / size();
// Stop measurement
spectroDriver.execute("stop", false);
}
}
......@@ -46,12 +46,18 @@ public:
Property<std::string> spectroOpenErrorMessage;
Property<int32> scansToAverage;
Property<int32> size;
Property<int32> blockSize;
Property<int32> zSize;
ArrayProperty<float64> xData;
ArrayProperty<float64> yData;
Property<std::string> mode; //this property is used for nexus files to indicate how was used the spectro when saving the data (when being used with a count)
ArrayProperty<float64> yDataBlock; // This property is used in continuous measurement
Property<std::string> mode; // This property is used for nexus files to indicate how was used the spectro when saving the data (when being used with a count)
// possible values are: SEQUENCE, COUNT_SINGLE, COUNT_SWITCHER and idle.
Property<int32> timeOfMeasure; // For continuous measurement
QE65000Controller(const std::string& name);
virtual ~QE65000Controller();
......@@ -74,8 +80,11 @@ public:
void setPlotName(int32 plotId);
void doContinuousMeasurement();
private: