Commit 1901a3fc authored by Cristina Cocho's avatar Cristina Cocho
Browse files

New version of D22SampleSequencer added to be tested

parent c16f6991
......@@ -138,16 +138,6 @@ D22SpectroSampleSequencer::D22SpectroSampleSequencer(const D22SpectroSampleSeque
m_sampleChanger.copy(controller.m_sampleChanger);
m_dataParams.copy(controller.m_dataParams);
yDataArray1.init(this, NOSAVE, "yData_array1");
yDataArray2.init(this, NOSAVE, "yData_array2");
yDataArraySecondChannel1.init(this, NOSAVE, "yDataArray_secondChannel1");
yDataArraySecondChannel2.init(this, NOSAVE, "yDataArray_secondChannel2");
m_yDataArray1 = NULL;
m_yDataArraySecondChannel1 = NULL;
m_yDataArray2 = NULL;
m_yDataArraySecondChannel2 = NULL;
}
void D22SpectroSampleSequencer::postConfiguration() {
......
......@@ -87,19 +87,6 @@ private:
bool m_ChangerStarted;
bool m_CountStarted;
ArrayProperty<int32> yDataArray1;
ArrayProperty<int32> yDataArraySecondChannel1;
ArrayProperty<int32> yDataArray2;
ArrayProperty<int32> yDataArraySecondChannel2;
int32* m_yDataArray1;
int32* m_yDataArraySecondChannel1;
int32* m_yDataArray2;
int32* m_yDataArraySecondChannel2;
};
}
......
......@@ -3,4 +3,5 @@
<controller class="d22special::CountWithSpectro"/>
<controller class="d22special::DualSwitchSpectroController"/>
<controller class="d22special::D22SpectroSampleSequencer"/>
<controller class="d22special::SpectroSampleSequencer"/>
</module>
\ No newline at end of file
/*
* 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 "SpectroSampleSequencer.h"
#include "controllers/common/datafile/NexusDataFile.h"
using namespace boost;
namespace d22special {
const std::string SpectroSampleSequencer::TYPE = "spectroSampleSequencer";
const int32 SpectroSampleSequencer::ONLY_SPECTRO = 0;
const int32 SpectroSampleSequencer::ONLY_SANS = 1;
const int32 SpectroSampleSequencer::BOTH_SANS_SPECTRO = 2;
SpectroSampleSequencer::SpectroSampleSequencer(const std::string& name) :
lss::SampleSequencer(name) {
// Reuse the super class constructor but initialize the countWithSpectro controller specifically
spectro.init(this, "spectro");
useCountWithSpectro.init(this, SAVE, "use_countWithSpectro");
integrationTime.init(this, SAVE, "integration_time"); //in microseconds!
scansToAverage.init(this, SAVE, "scans_average");
spectrumDataForActualSlot.init(this, NOSAVE, "spectrum_data");
m_CountStarted = false;
m_ChangerStarted = false;
m_yDataArray = nullptr;
}
SpectroSampleSequencer::SpectroSampleSequencer(const SpectroSampleSequencer& controller) :
lss::SampleSequencer(controller) {
spectro.copy(controller.spectro);
useCountWithSpectro.copy(this, controller.useCountWithSpectro);
integrationTime.copy(this, controller.integrationTime); //in microseconds!
scansToAverage.copy(this, controller.scansToAverage);
spectrumDataForActualSlot.copy(this, controller.spectrumDataForActualSlot);
m_CountStarted = false;
m_ChangerStarted = false;
m_yDataArray = nullptr;
}
SpectroSampleSequencer::~SpectroSampleSequencer() {
}
void SpectroSampleSequencer::postConfiguration() {
lss::SampleSequencer::postConfiguration();
}
void SpectroSampleSequencer::start() {
if (useCountWithSpectro()) {
startUsingCountWithSpectro();
} else {
lss::SampleSequencer::start();
}
}
void SpectroSampleSequencer::stop() {
if (useCountWithSpectro()) {
stopUsingCountWithSpectro();
} else {
lss::SampleSequencer::stop();
}
}
void SpectroSampleSequencer::pause() {
if (useCountWithSpectro()) {
pauseUsingCountWithSpectro();
} else {
lss::SampleSequencer::pause();
}
}
void SpectroSampleSequencer::resume() {
if (useCountWithSpectro()) {
resumeUsingCountWithSpectro();
} else {
lss::SampleSequencer::resume();
}
}
void SpectroSampleSequencer::updateIntegrationTime() {
std::cout << "updating integration time " << spectro->integrationTime() << std::endl;
integrationTime = spectro->integrationTime();
}
void SpectroSampleSequencer::updateScansToAverage() {
scansToAverage = spectro->scansToAverage();
}
void SpectroSampleSequencer::startUsingCountWithSpectro() {
commandStatus.setRunning();
// Load data
int32 apply_nbSlot = slot.setpoint();
std::string apply_timeType = timeType();
int32 apply_samplePosition[apply_nbSlot];
float64 apply_acquisitionTime[apply_nbSlot];
float64 apply_Transmission[apply_nbSlot];
float64 apply_Thickness[apply_nbSlot];
std::string apply_acquisitionTitle[apply_nbSlot];
for (int32 i = 0; i < apply_nbSlot; i++) {
apply_samplePosition[i] = samplePosition.get(i);
apply_acquisitionTime[i] = acquisitionTime.get(i);
apply_Transmission[i] = transmission.get(i);
apply_Thickness[i] = thickness.get(i);
apply_acquisitionTitle[i] = acquisitionTitle.get(i);
}
obtainSlotsAndActions();
// configure countWithSpectro
bool countControllerOk = true;
commandProgression = 0;
try {
count->mode = BaseCount::TIME_MODE;
count->saveData = true;
count->timeType = apply_timeType;
} catch (CannotSetValue &e) {
log(Level::s_Error) << name << emptycursor << "Cannot set value for acquisition controller" << endlog;
countControllerOk = false;
}
log(Level::s_Info) << name << cursor << apply_nbSlot << " slots" << endlog;
// Common stuff for each position
sampleChanger->useAdjust = false;
sampleChanger->changer = changer();
for (int32 i = 0; i < m_executionOrder.size(); i++) {
std::list<std::pair<int32, int32>> pointsToExecute = m_executionOrder[i];
for (std::list<std::pair<int32, int32>>::const_iterator it = pointsToExecute.begin(); it != pointsToExecute.end(); ++it) {
int32 slotPosition = it->first;
int32 slotAction = it->second;
std::cout << "-> Executing slot at index " << i << std::endl;
// (1) Only load count parameters if a SANS measure is going to be taken
if (slotAction != ONLY_SPECTRO) {
// Obtain index related of the position ! -> WE ASUME A POSITION IS NOT REPEATED! ASK! IS IT LOGIC TO HAVE REPEATED SLOTS WITH DIFFERENT params?
currentAcquisitionTime = apply_acquisitionTime[i];
try {
count->time.setpoint = apply_acquisitionTime[i];
count->subtitle = apply_acquisitionTitle[i];
// Set total repetition to 1 by default
count->totalReps = 1;
} catch (CannotSetValue&) {
log(Level::s_Error) << name << emptycursor << "Cannot set value for acquisition controller" << endlog;
countControllerOk = false;
}
// Set values for transmission and thickness
// try {
// dataParams->setValue(dataparamsTransmission(), apply_Transmission[i]);
// dataParams->setValue(dataparamsThickness(), apply_Thickness[i]);
// } catch (...) {
// std::cerr << "error in setting dataParams properties" << std::endl;
// }
}
std::cout << "-> Changer in position " << slotPosition << std::endl;
// (2) Move sampleChanger
// Move changer to position
sampleChanger->slot.setpoint = slotPosition;
m_ChangerStarted = true;
sampleChanger->startCommand();
m_ChangerStarted = false;
if (commandStatus.isWarning()) {
//the state warning means the controller has been stopped during its execution
break;
}
// (3) Do SANS and/or spectro measure
if (slotAction == ONLY_SPECTRO) {
std::cout << "--> measuring only spectro " << std::endl;
// Position the spectro
spectro->startCommand();
// Store spectro measured
storeSpectrum(i);
} else if (slotAction == ONLY_SANS) {
std::cout << "--> measuring only SANS " << std::endl;
// Move changer to slotPOsition but ONLY do a SANS measure
count->startCommand();
// Store the slot index and its related numor
std::cout << " numor " << count->numor() << std::endl;
m_numors[i] = count->numor();
} else {
std::cout << "--> measuring both SANS and spectro " << std::endl;
// Do both measures
startSpectroAndCount();
// Store spectro measured but first get the correct slot index for the spectro done in this slot (remember shift of +2)
int32 slotValueAtCurrentIndex = samplePosition.get(i);
int32 realSlotValueOfSpectrumData = slotValueAtCurrentIndex + 2;
// Get closest slot index (not executed yet) where we find "realSlotValueOfSpectrumData"
bool found = false;
int32 index;
for (int32 j = i; j < slot.setpoint(); j++) {
if (!found && samplePosition.get(j) == realSlotValueOfSpectrumData) {
found = true;
index = j;
}
}
if (found) {
storeSpectrum(index);
}
// Store the slot index and its related numor
std::cout << " numor " << count->numor() << std::endl;
m_numors[i] = count->numor();
}
}
}
// At the very end do all needed appends of spectrum data
appendSpectrumInDataFile();
// log stuff
log(Level::s_Info) << name << emptycursor << apply_nbSlot << " slots" << endlog;
commandStatus.setIdle();
commandProgression = 100;
}
void SpectroSampleSequencer::stopUsingCountWithSpectro() {
commandStatus.setWarning();
if (count->commandStatus.isRunning()) { //verify we set the commandStatus property
count->stopCommand();
} else if (sampleChanger->commandStatus.isRunning()) {
sampleChanger->stopCommand();
}
log(Level::s_Info) << name << emptycursor << "stopped" << endlog;
}
void SpectroSampleSequencer::pauseUsingCountWithSpectro() {
// TODO
}
void SpectroSampleSequencer::resumeUsingCountWithSpectro() {
//TODO
}
void SpectroSampleSequencer::startSpectroAndCount() {
// Like in CountWithSpectro
//Launch count and spectro at the same time
// Run the threads in parallel in a group
boost::thread_group group;
group.create_thread(boost::bind(&SpectroSampleSequencer::startCount, this));
group.create_thread(boost::bind(&SpectroSampleSequencer::startSpectro, this));
// Wait for the termination of the threads
group.join_all();
}
void SpectroSampleSequencer::startCount() {
count->startCommand();
}
void SpectroSampleSequencer::startSpectro() {
// TO ASK! NO MULTIPLE SPECTRA MEASURES IN THIS MODE but average is possible
if (commandStatus.isRunning()) {
spectro->startCommand();
// m_yDataArray = spectro->yData();
}
// Store it using as index the slot position
// m_spectrum[slot()] = m_yDataArray;
}
void SpectroSampleSequencer::obtainSlotsAndActions() {
// Clean former sequencer
m_executionOrder.clear();
// The slot position refers to the slot where a SANS measure is going to be taken
for (int32 i = 0; i < slot.setpoint(); i++) { //slot.setpoint == number of lines to execute
std::list<std::pair<int32, int32>> positionsToExecuteForLine;
int32 slotPosition = samplePosition.get(i);
int32 slotPositionMinusTwo = slotPosition - 2;
int32 slotPositionPlusTwo = slotPosition + 2;
// We can do both SANS and spectro if we found the (slotPosition + 2) value if the sequence not yet executed
// We should validate than the characteristics are the same
bool foundPlusTwo = false;
for (int32 j = i; j < slot.setpoint(); j++) {
if (slotPositionPlusTwo == samplePosition.get(j)) {
foundPlusTwo = true;
}
}
// Maybe we cannot do both measures at the same time but we can do a spectro measure previously but moving the sampler two positions to the left
if (slotPositionMinusTwo > 0 && !checkPositionIsHasNotBeenAlreadyMeasured(slotPositionMinusTwo)) {
positionsToExecuteForLine.push_back(std::pair<int32, int32>(slotPositionMinusTwo, ONLY_SPECTRO)); // extra position added!
}
if (slotPosition > 2) {
if (foundPlusTwo) {
positionsToExecuteForLine.push_back(std::pair<int32, int32>(slotPosition, BOTH_SANS_SPECTRO));
} else {
positionsToExecuteForLine.push_back(std::pair<int32, int32>(slotPosition, ONLY_SANS));
}
}
m_executionOrder[i] = positionsToExecuteForLine;
}
// Verify content
for (int32 i = 0; i < m_executionOrder.size(); i++) {
std::list<std::pair<int32, int32>> pointsToExecute = m_executionOrder[i];
for (std::list<std::pair<int32, int32>>::const_iterator it = pointsToExecute.begin(); it != pointsToExecute.end(); ++it) {
}
}
}
bool SpectroSampleSequencer::checkPositionIsHasNotBeenAlreadyMeasured(int32 slotPositionMinusTwo) {
// std::cout << "has position " << slotPositionMinusTwo << "been already measured? " << std::endl;
for (int32 i = 0; i < m_executionOrder.size(); i++) {
std::list<std::pair<int32, int32>> pointsToExecute = m_executionOrder[i];
for (std::list<std::pair<int32, int32>>::const_iterator it = pointsToExecute.begin(); it != pointsToExecute.end(); ++it) {
int32 slotToMeasure = it->first;
int32 typeOfMeasureToDoInSlot = it->second;
if ((slotToMeasure == slotPositionMinusTwo) && (typeOfMeasureToDoInSlot == BOTH_SANS_SPECTRO)) {
// std::cout << "yes!" << std::endl;
return true;
}
}
}
// std::cout << "no!" << std::endl;
return false;
}
void SpectroSampleSequencer::storeSpectrum(int32 executionLine) {
// int32 expectedNumorForSpectrum = count->numor() + 2;
float64* spectrum = spectro->yData();
std::cout << "Saving locally spectrum for execution slot " << executionLine << std::endl;
m_spectrum.insert(std::pair<int32, float64*>(executionLine, spectrum));
}
void SpectroSampleSequencer::appendSpectrumInDataFile() {
for (int32 i = 0; i < slot.setpoint(); i++) {
// If we have same slot in both maps
if ((m_numors.find(i) != m_numors.end()) && (m_spectrum.find(i) != m_spectrum.end())) {
int32 numor = m_numors[i];
spectrumDataForActualSlot.update(m_spectrum.at(i));
spectrumDataForActualSlot.setSize(1044);
NexusDataFile::appendTo(numor, "NxD22SpecialServerFile.xml", "NxD22SpecialClientFile.xml");
std::cout << "appending spectrum related to numor " << numor << " related to execution line " << i << std::endl;
} else {
// Error? Or it is just a special case
}
}
}
/*
* setEnabled
*/
void SpectroSampleSequencer::setEnabledForLoading(bool all, bool postconf) {
if (useCountWithSpectro()) {
addExcludeSetEnableController(dataParams.getRole());
addExcludeSetEnableController(count.getRole());
ExperimentController::setEnabledForLoading(all, postconf);
} else {
lss::SampleSequencer::setEnabledForLoading(all, postconf);
}
}
/*
* setDisabled
*/
void SpectroSampleSequencer::setDisabled(bool all) {
if (useCountWithSpectro()) {
addExcludeSetEnableController(dataParams.getRole());
addExcludeSetEnableController(count.getRole());
ExperimentController::setDisabled(all);
} else {
lss::SampleSequencer::setDisabled(all);
}
}
}
/*
* 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_SPECTROSAMPLESEQUENCER_H_
#define SRC_CONTROLLERS_LSS_D22SPECIAL_SPECTROSAMPLESEQUENCER_H_
#include <Controller.h>
#include "controllers/lss/common/SampleSequencer.h"
#include "CountWithSpectro.h"
#include "controllers/spectrometer/QE65000Controller.h"
namespace d22special {
class SpectroSampleSequencer: public lss::SampleSequencer {
public:
static const std::string TYPE;
SpectroSampleSequencer(const std::string& name);
SpectroSampleSequencer(const SpectroSampleSequencer& controller);
virtual ~SpectroSampleSequencer();
Property<bool> useCountWithSpectro;
Property<int32> integrationTime;
Property<int32> scansToAverage;
ArrayProperty<float64> spectrumDataForActualSlot;
virtual void setEnabledForLoading(bool all, bool postconf = true);
virtual void setDisabled(bool all = false);
protected:
virtual void start();
virtual void stop();
virtual void pause();
virtual void resume();
virtual void postConfiguration();
private:
ControllerPtr<QE65000Controller> spectro;
void startUsingCountWithSpectro();
void stopUsingCountWithSpectro();
void pauseUsingCountWithSpectro();
void resumeUsingCountWithSpectro();
void updateIntegrationTime();
void updateScansToAverage();
void startSpectroAndCount();
void startCount();
void startSpectro();
void obtainSlotsAndActions();
bool checkPositionIsHasNotBeenAlreadyMeasured(int32 slotPositionMinusTwo);
void storeSpectrum(int32 executionLine);
void appendSpectrumInDataFile();
bool m_CountStarted;
bool m_ChangerStarted;
float64* m_yDataArray;
std::map<int32, float64*> m_spectrum; // key = slot execution line/index, value = chromato
std::map<int32, int32> m_numors; // key = slot execution line/index, value = numor of SANS measure done in specific slot index
std::map<int32, std::list<std::pair<int32, int32>>> m_executionOrder;
static const int32 ONLY_SPECTRO;
static const int32 ONLY_SANS;
static const int32 BOTH_SANS_SPECTRO;
};
}
#endif /* SRC_CONTROLLERS_LSS_D22SPECIAL_SPECTROSAMPLESEQUENCER_H_ */
sample_sequencer.changer_numberPrefix=Changer
sample_sequencer.wanted_numSlotLabel=Wanted number of positions
sample_sequencer.maxSlotLabel= Max Slots
sample_sequencer.integration_time=Time
sample_sequencer.integration_timeSuffix=~mus
sample_sequencer.scan_average=Num. Averages per measure
sample_sequencer.numSpectro=Num. Measures
sample_sequencer.countTime=Time
#groups names
sample_sequencer.spectroGroup=Spectro
sample_sequencer.countGroup=Count
# Radio buttons h/m/s
sample_sequencer.hValue=h
sample_sequencer.hLabel=h
sample_sequencer.mValue=m
sample_sequencer.mLabel=m
sample_sequencer.sValue=s
sample_sequencer.sLabel=s
# Time-Monitor switcher
sample_sequencer.timeValue=time
sample_sequencer.timeLabel=Time
sample_sequencer.timeImage=MODE_TIME
sample_sequencer.countsImage=MODE_COUNTS
sample_sequencer.countsValue=counts
sample_sequencer.countsLabel=Monitor
# Check box
sample_sequencer.useCountWithSpectro=Use spectro
sample_sequencer.useCountSpectroCheckedValue=true
sample_sequencer.useCountSpectroUncheckedValue=false
<plugin>
<controller type="spectroSampleSequencer" role="spectroSampleSequencer1" />