/* * 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 "CountWithSpectro.h" #include "controllers/common/family/Families.h" #include "PersistenceServices/DataFile/NexusDataFile.h" namespace d22special { const std::string CountWithSpectro::TYPE = "count_with_spectro"; const int32 CountWithSpectro::XSIZE = 1044; //should be retrieved directly from the driver... const int32 CountWithSpectro::YSIZE = 1044; CountWithSpectro::CountWithSpectro(const std::string & name) : ExperimentController(name), controller::Stoppable(this) { setFamily(family::SAMPLE_ENVIRONMENT); registerFunction(TYPE); spectro.init(this, "spectro"); count.init(this, "count"); integrationTime.init(this, SAVE, "integration_time"); //It is in seconds! numSpectroMeasures.init(this, SAVE, "num_spectro"); timeType.init(this, SAVE, "time_type"); countTime.init(this, SAVE, "count_time"); xSize.init(this, SAVE, "x_size"); ySize.init(this, SAVE, "y_size"); zSize.init(this, SAVE, "z_size"); totalYData.init(this, NOSAVE, "total_yData"); } CountWithSpectro::~CountWithSpectro() { } void CountWithSpectro::postConfiguration() { xSize = XSIZE; ySize = numSpectroMeasures(); zSize = 1; registerRefresher(numSpectroMeasures, &CountWithSpectro::refreshNumSpectroMeasures, this); registerProgression(count, &CountWithSpectro::updateProgression, this); } void CountWithSpectro::refreshNumSpectroMeasures(int32 number) { ySize = number; //This property is only used to save the data in nexus file } void CountWithSpectro::updateProgression() { commandProgression = count->commandProgression(); } void CountWithSpectro::start() { //Important! convert the time (seconds) into microseconds -> the driver needs it in that unit float64 timeInMicrosec = integrationTime() * 1000000; spectro->integrationTime = timeInMicrosec; //check the total time of spectro measurement is smaller than the count time float64 spectroTime = integrationTime() * numSpectroMeasures(); float64 countTime = getCountTimeInSec(); //count->time.setpoint(); if (spectroTime < countTime) { setupCountParams(); initArray(); commandStatus.setRunning(); //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(&CountWithSpectro::startCount, this)); group.create_thread(boost::bind(&CountWithSpectro::startSpectro, this)); // Wait for the termination of the threads group.join_all(); //Get data saveSpectroData(); commandStatus.setIdle(); } else { //error } } void CountWithSpectro::stop() { if (commandStatus.isRunning()) { count->stopCommand(); spectro->stopCommand(); } commandStatus.setWarning(); } void CountWithSpectro::saveSpectroData() { int32 totalSize = YSIZE * numSpectroMeasures(); totalYData.update(m_totalYData); totalYData.setSize(totalSize); int32 numor = any_cast(count->getValue("numor")); NexusDataFile::appendTo(numor, "NxD22SpecialServerFile.xml", "NxD22SpecialClientFile.xml"); } void CountWithSpectro::startCount() { count->startCommand(); } void CountWithSpectro::startSpectro() { for (int i = 0; i < numSpectroMeasures(); i++) { spectro->startCommand(); int32 ySize = spectro->yData.getSize(); //be careful, maybe the driver gives us a different size float64* tempYData = spectro->yData(); for (int32 j = 0; j < ySize; j++) { m_totalYData[ySize * i + j] = tempYData[j]; } } } void CountWithSpectro::setupCountParams() { count->time.setpoint = countTime(); count->timeType = timeType(); } void CountWithSpectro::initArray() { if (m_totalYData) { delete[] m_totalYData; } int32 totalSize = YSIZE * numSpectroMeasures(); m_totalYData = new int32[totalSize]; memset(m_totalYData, 0, totalSize * sizeof(int32)); //set to zero totalYData.update(m_totalYData); totalYData.setSize(totalSize); } float64 CountWithSpectro::getCountTimeInSec() { float64 time; if (timeType() == "h") { time = countTime() * 3600.; } else if (timeType() == "m") { time = countTime() * 60.; } else if (timeType() == "s") { time = countTime(); } return time; } }