Commit 3a6478ff authored by yannick legoc's avatar yannick legoc
Browse files

Implemented a new mode for sending data from remote dpp live process...

Implemented a new mode for sending data from remote dpp live process controllers: reading data file with live reader.
parent bdfe8f28
......@@ -364,9 +364,6 @@ void DPPAcquisitionController::writeParams() {
// starting DPPCoincidence
if (useListMode() && m_liveProcessController.isAssigned()) {
m_liveProcessController->numberOfADCs = totalAdc;
m_liveProcessController->numberOfChannels = (1 << nbBits());
// set the lst context
setContext();
......
/*
* 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 "DPPCoincidence.h"
#include "InstrumentAbstraction/CommandNames.h"
#include "DataProvider/ChangeAspect.h"
#include <common/base/Convert.h>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <boost/format.hpp>
#include <string>
#include <cstdlib>
#include <common/base/ServerProperties.h>
namespace npp {
const std::string DPPCoincidence::NOMADCOINCIDENCE = "nomadcoincidencev";
const char DPPCoincidence::SHARED_MEMORY_NAME[] = "CoincidenceSharedMemory";
const char DPPCoincidence::SHARED_MEMORY_DATA_NAME[] = "data";
const char DPPCoincidence::SHARED_MEMORY_MATRIX_NAME[] = "matrix";
const char DPPCoincidence::SHARED_MEMORY_ADCRATES_NAME[] = "adc_rates";
using namespace common;
using namespace std;
using namespace boost;
using namespace boost::interprocess;
const std::string DPPCoincidence::TYPE = "dpp_coincidence";
DPPCoincidence::DPPCoincidence(const std::string& name) :
DPPLiveProcess(name),
_data(0),
_xData(0),
_ADCRates(0),
_segment(0),
_liveCoincidenceThread(0),
_liveRunning(false),
_liveRefreshThread(0) {
dT.init(this, SAVE, "dT");
cleanDT.init(this, SAVE, "clean_dT");
processBlockSize.init(this, SAVE, "process_block_size");
test.init(this, SAVE, "test");
testFileName.init(this, SAVE, "test_file_name");
xData.init(this, NOSAVE, "x_data");
coincidenceResolution.init(this, SAVE, "coincidence_resolution");
coincidenceData.init(this, NOSAVE, "coincidence_data");
nOrder.init(this, NOSAVE, "n_order");
refreshTimeS.init(this, SAVE, "refresh_time_s");
one.init(this, NOSAVE, "one");
order.init(this, NOSAVE, "order");
globalRate.init(this, NOSAVE, "global_rate");
globalCleanRate.init(this, NOSAVE, "global_clean_rate");
detectorRate.init(this, NOSAVE, "detector_rate");
detectorCleanRate.init(this, NOSAVE, "detector_clean_rate");
ADCId.init(this, NOSAVE, "adc_id");
ADCRate.init(this, NOSAVE, "adc_rate");
}
DPPCoincidence::DPPCoincidence(const DPPCoincidence& controller) :
DPPLiveProcess(controller),
_data(0),
_xData(0),
_ADCRates(0),
_segment(0),
_liveCoincidenceThread(0),
_liveRunning(false),
_liveRefreshThread(0){
}
DPPCoincidence::~DPPCoincidence() {
shared_memory_object::remove(SHARED_MEMORY_NAME);
delete _segment;
}
void DPPCoincidence::postConfiguration() {
int32 matrixBits = coincidenceResolution();
// ADC X data
int32 matrixSize = 1 << matrixBits;
_xData = new int32[matrixSize];
// initializing
for (int32 i = 0; i < matrixSize; ++i) {
_xData[i] = i;
}
xData.set(_xData);
xData.setSize(matrixSize);
// matrix data
shared_memory_object::remove(SHARED_MEMORY_NAME);
const int32 segmentSize = (int32) ((1 << (matrixBits * 2)) * sizeof(int32_t) + 256 * sizeof(float64) + 128 * sizeof(float64));
_segment = new managed_shared_memory(create_only, SHARED_MEMORY_NAME, segmentSize);
// allocating first
int32_t * matrix = _segment->construct<int32_t>(SHARED_MEMORY_MATRIX_NAME)[matrixSize * matrixSize](0);
// allocating first
_data = _segment->construct<float64>(SHARED_MEMORY_DATA_NAME)[4 * 7](0);
// order
nOrder.set(7);
order.resize(7);
globalRate.resize(7);
globalCleanRate.resize(7);
detectorRate.resize(7);
detectorCleanRate.resize(7);
// properties
for (int32 i = 0; i < 7; i++) {
order.set(i, i + 2);
}
coincidenceData.set((int32 *)matrix);
coincidenceData.setSize(matrixSize * matrixSize);
_ADCRates = _segment->construct<float64>(SHARED_MEMORY_ADCRATES_NAME)[128](0);
ADCId.resize(MAX_ADC);
ADCRate.resize(MAX_ADC);
for (int32 i = 0; i < MAX_ADC; i++) {
ADCId.set(i, i);
}
resetData();
}
void DPPCoincidence::start() {
resetData();
startLiveProcess();
}
void DPPCoincidence::stop() {
stopLiveProcess();
}
void DPPCoincidence::raz() {
resetData();
}
void DPPCoincidence::resetData() {
// resetting values
for (int32 i = 0; i < 7; ++i) {
globalRate.set(i, 0.0);
globalCleanRate.set(i, 0.0);
detectorRate.set(i, 0.0);
detectorCleanRate.set(i, 0.0);
}
// setting dynamic properties
for (int32 i = 0; i < MAX_ADC; i++) {
ADCRate.set(i, 0.0);
}
}
void DPPCoincidence::startLiveProcess() {
// if stop is taking time, waiting here
cout << "waiting for synchronization before launching " << NOMADCOINCIDENCE << endl;
boost::mutex::scoped_lock lock(_mutex);
_liveRunning = true;
_liveCoincidenceThread = new thread(bind(&DPPCoincidence::executeLiveProcess, this));
_liveRefreshThread = new thread(bind(&DPPCoincidence::executeRefreshProcess, this));
}
void DPPCoincidence::stopLiveProcess() {
boost::mutex::scoped_lock lock(_mutex);
_liveRunning = false;
if (_liveCoincidenceThread != 0) {
string command("kill -2 `pidof ");
command += NOMADCOINCIDENCE + "`";
::system(command.c_str());
_liveCoincidenceThread->join();
delete _liveCoincidenceThread;
_liveCoincidenceThread = 0;
cout << "terminated " << NOMADCOINCIDENCE << endl;
}
if (_liveRefreshThread != 0) {
_liveRefreshThread->join();
delete _liveRefreshThread;
_liveRefreshThread = 0;
}
}
void DPPCoincidence::executeLiveProcess() {
string command;
command += NOMADCOINCIDENCE + " ";
if (!test()) {
size_t size = fileName().size();
if (size < 6) {
string prefix(6 - size, '0');
command += common::ServerProperties::getInstance()->getNomadDataPath() + prefix + fileName() + ".lst ";
} else {
command += common::ServerProperties::getInstance()->getNomadDataPath() + fileName() + ".lst ";
}
} else {
command += testFileName() + " ";
}
command += to<string>(dT() / 10) + " ";
command += to<string>(cleanDT() / 10) + " ";
command += "$HOME/.nomadserver/crateboardcoincidence.txt $HOME/.nomadserver/detectoradc.txt ";
command += to<string>(coincidenceResolution()) + " ";
command += to<string>(processBlockSize()) + " ";
cout << command << endl;
::system(command.c_str());
}
void DPPCoincidence::executeRefreshProcess() {
while (_liveRunning) {
sleep(refreshTimeS());
// copying values
for (int32 i = 0; i < 7; ++i) {
globalRate.set(i, _data[i]);
globalCleanRate.set(i, _data[7 + i]);
detectorRate.set(i, _data[7 * 2 + i]);
detectorCleanRate.set(i, _data[7 * 3 + i]);
}
coincidenceData.sendEvent();
// setting dynamic properties
for (int32 i = 0; i < numberOfADCs(); i++) {
ADCRate.set(i, _ADCRates[i]);
}
}
float64 crystalRate2 = globalRate(0);
float64 crystalCleanRate2 = globalCleanRate(0);
float64 detectorRate2 = detectorRate(0);
float64 detectorCleanRate2 = detectorCleanRate(0);
float64 crystalRate3 = globalRate(1);
float64 crystalCleanRate3 = globalCleanRate(1);
float64 detectorRate3 = detectorRate(1);
float64 detectorCleanRate3 = detectorCleanRate(1);
ostringstream ss1, ss2, ss3;
ss1 << " Order"
<< " Crystal (c/s)"
<< " Crystal clean (c/s)"
<< " Detector (c/s)"
<< " Detector clean (c/s)";
ss2 << " 2 " << boost::format("%20.3d") % crystalRate2 << " " << boost::format("%20.3d") % crystalCleanRate2 << " " << boost::format("%20.3d") % detectorRate2 << " " << boost::format("%20.3d") % detectorCleanRate2;
ss3 << " 3 " << boost::format("%20.3d") % crystalRate3 << " " << boost::format("%20.3d") % crystalCleanRate3 << " " << boost::format("%20.3d") % detectorRate3 << " " << boost::format("%20.3d") % detectorCleanRate3;
log(Level::s_Info) << ss1.str() << endlog;
log(Level::s_Info) << ss2.str() << endlog;
log(Level::s_Info) << ss3.str() << endlog;
}
}
/*
* 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 NPP_DPPCOINCIDENCE_H
#define NPP_DPPCOINCIDENCE_H
#include "DPPLiveProcess.h"
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/thread.hpp>
#include <stdint.h>
namespace npp {
class DPPCoincidence : public DPPLiveProcess {
public:
//! Type of controller
static const std::string TYPE;
DPPCoincidence(const std::string& name);
DPPCoincidence(const DPPCoincidence& controller);
virtual ~DPPCoincidence();
virtual void postConfiguration();
virtual void start();
virtual void stop();
virtual void raz();
private:
static const std::string NOMADCOINCIDENCE;
static const char SHARED_MEMORY_NAME[];
static const char SHARED_MEMORY_DATA_NAME[];
static const char SHARED_MEMORY_MATRIX_NAME[];
static const char SHARED_MEMORY_ADCRATES_NAME[];
void resetData();
void startLiveProcess();
void stopLiveProcess();
void executeLiveProcess();
void executeRefreshProcess();
Property<int32> dT;
Property<int32> cleanDT;
Property<int32> processBlockSize;
Property<bool> test;
Property<std::string> testFileName;
ArrayProperty<int32> xData;
Property<int32> coincidenceResolution;
ArrayProperty<int32> coincidenceData;
Property<int32> nOrder;
Property<int32> refreshTimeS;
Property<int32> one;
DynamicProperty<int32> order;
DynamicProperty<float64> globalRate;
DynamicProperty<float64> globalCleanRate;
DynamicProperty<float64> detectorRate;
DynamicProperty<float64> detectorCleanRate;
DynamicProperty<int32> ADCId;
DynamicProperty<float64> ADCRate;
float64 * _data;
int32 * _xData;
float64 * _ADCRates;
boost::interprocess::managed_shared_memory * _segment;
boost::mutex _mutex;
boost::thread * _liveCoincidenceThread;
bool _liveRunning;
boost::thread * _liveRefreshThread;
static const int32 MAX_ADC = 128;
};
}
#endif
/*
* 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 "DPPHistogram.h"
#include "InstrumentAbstraction/CommandNames.h"
#include "DataProvider/ChangeAspect.h"
#include <common/base/Convert.h>
#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include <cstdlib>
#include <common/base/ServerProperties.h>
namespace npp {
/*
* Property names
*/
const std::string DPPHistogram::LIVEHISTO = "nomadhisto";
const char DPPHistogram::SHARED_MEMORY_NAME[] = "HistogramSharedMemory";
const char DPPHistogram::SHARED_MEMORY_DATA_NAME[] = "data";
const char DPPHistogram::SHARED_MEMORY_ADCRATES_NAME[] = "adc_rates";
const std::string DPPHistogram::HISTOGRAM = "histogram";
using namespace common;
using namespace boost;
using namespace boost::interprocess;
const std::string DPPHistogram::TYPE = "dpp_histogram";
DPPHistogram::DPPHistogram(const std::string& name) :
DPPLiveProcess(name),
_xData(0),
_ADCRates(0),
_segment(0),
_liveCoincidenceThread(0),
_liveRunning(false),
_liveRefreshThread(0) {
triggerChannel.init(this, SAVE, "trigger_channel");
delay.init(this, SAVE, "delay");
dT.init(this, SAVE, "dT");
maxBlock.init(this, SAVE, "max_block");
blockSize.init(this, SAVE, "block_size");
test.init(this, SAVE, "test");
testFileName.init(this, SAVE, "test_file_name");
xData.init(this, NOSAVE, "x_data");
one.init(this, NOSAVE, "one");
refreshTimeS.init(this, SAVE, "refresh_time_s");
histogram.init(this, NOSAVE, "histogram");
ADCId.init(this, NOSAVE, "adc_id");
ADCRate.init(this, NOSAVE, "adc_rate");
}
DPPHistogram::DPPHistogram(const DPPHistogram& controller) :
DPPLiveProcess(controller),
_xData(0),
_ADCRates(0),
_segment(0),
_liveCoincidenceThread(0),
_liveRunning(false),
_liveRefreshThread(0) {
}
DPPHistogram::~DPPHistogram() {
shared_memory_object::remove(SHARED_MEMORY_NAME);
delete _segment;
}
void DPPHistogram::postConfiguration() {
// ADC X data
_xData = new int32[1];
xData.set(_xData);
xData.setSize(1);
// ADC Y data
shared_memory_object::remove(SHARED_MEMORY_NAME);
_segment = new managed_shared_memory(create_only, SHARED_MEMORY_NAME, SEGMENT_SIZE);
// allocating first
_segment->construct<int32_t>(SHARED_MEMORY_DATA_NAME)[1](0);
_ADCRates = _segment->construct<float64>(SHARED_MEMORY_ADCRATES_NAME)[128](0);
histogram.resize(MAX_ADC);
ADCId.resize(MAX_ADC);
ADCRate.resize(MAX_ADC);
// allocating
for (int32 i = 0; i < MAX_ADC; i++) {
ADCId.set(i, i);
}
resetData();
}
void DPPHistogram::start() {
resetData();
startLiveHisto();
}
void DPPHistogram::stop() {
stopLiveHisto();
}
void DPPHistogram::raz() {
resetData();
}
void DPPHistogram::resetData() {
// number of elements
int32_t size = numberOfChannels() * numberOfADCs();
// ADC X data
delete [] _xData;
_xData = new int32[numberOfChannels()];
// initializing
for (int32 i = 0; i < numberOfChannels(); ++i) {
_xData[i] = i;
}
xData.set(_xData);
xData.setSize(numberOfChannels());
// ADC Y data
// destroying last array
_segment->destroy<int32_t>(SHARED_MEMORY_DATA_NAME);
// allocating new array
int32_t * array = _segment->construct<int32_t>(SHARED_MEMORY_DATA_NAME)[size](0);
// setting dynamic properties
for (int32 i = 0; i < numberOfADCs(); i++) {
histogram.set(i, (int32 *)&array[i * numberOfChannels()]);
histogram.setSize(i, numberOfChannels());
}
for (int32 i = numberOfADCs(); i < MAX_ADC; i++) {
histogram.set(i, 0);
histogram.setSize(i, 0);
}
for (int32 i = 0; i < MAX_ADC; i++) {
ADCRate.set(i, 0.0);
}
}
void DPPHistogram::startLiveHisto() {
sendProgressEvent(0);
// if stop is taking time, waiting here
cout << "waiting for synchronization before launching " << LIVEHISTO << endl;
boost::mutex::scoped_lock lock(_mutex);
_liveRunning = true;
_liveCoincidenceThread = new thread(bind(&DPPHistogram::executeLiveHisto, this));
_liveRefreshThread = new thread(bind(&DPPHistogram::executeRefreshHisto, this));
sendProgressEvent(100);
}
void DPPHistogram::stopLiveHisto() {
boost::mutex::scoped_lock lock(_mutex);
_liveRunning = false;
if (_liveCoincidenceThread != 0) {
string command("kill -2 `pidof ");
command += LIVEHISTO + "`";
::system(command.c_str());
_liveCoincidenceThread->join();
delete _liveCoincidenceThread;
_liveCoincidenceThread = 0;
cout << "terminated " << LIVEHISTO << endl;