Commit 20ac8cf7 authored by yannick legoc's avatar yannick legoc
Browse files

Implemented LISTMODE_S data block without the need to specify the list of board controllers.

Corrected remote DPP controllers to read live data from the lst file.
parent 0eb96c72
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
*/ */
#include "DPPAcquisitionController.h" #include "DPPAcquisitionController.h"
#include "ListModeBlock.h"
#include "controllers/common/datafile/AsciiDataFileManager.h"
#include "controllers/common/datafile/AsciiDataFile.h"
#include "controllers/common/family/Families.h" #include "controllers/common/family/Families.h"
#include <lstdpp128/lstdpp.h> #include <lstdpp128/lstdpp.h>
...@@ -32,6 +35,8 @@ const string DPPAcquisitionController::NO_LIVE_PROCESS = "none"; ...@@ -32,6 +35,8 @@ const string DPPAcquisitionController::NO_LIVE_PROCESS = "none";
const string DPPAcquisitionController::HISTOGRAM_PROCESS = "histogram"; const string DPPAcquisitionController::HISTOGRAM_PROCESS = "histogram";
const string DPPAcquisitionController::COINCIDENCE_PROCESS = "coincidence"; const string DPPAcquisitionController::COINCIDENCE_PROCESS = "coincidence";
DataBlock* decodeListModeBlock(AsciiDataFileManager* dataFileManager, AsciiDataFile* dataFile, string blockType, typename boost::tokenizer<boost::char_separator<char> >::iterator iter, typename boost::tokenizer<boost::char_separator<char> >::iterator end);
/* /*
* Constructor * Constructor
*/ */
...@@ -62,6 +67,8 @@ DPPAcquisitionController::DPPAcquisitionController(const string& name) : ...@@ -62,6 +67,8 @@ DPPAcquisitionController::DPPAcquisitionController(const string& name) :
m_coincidenceController.init(this, "coincidence_controller"); m_coincidenceController.init(this, "coincidence_controller");
registerRefresher(nbAdcControllers, &DPPAcquisitionController::refreshNbAdcControllersProperty, this); registerRefresher(nbAdcControllers, &DPPAcquisitionController::refreshNbAdcControllersProperty, this);
dynamic_cast<AsciiDataFileManager *>(DataFileManager::getAsciiInstance())->addDataBlockFunction("LISTMODE_S", &decodeListModeBlock);
} }
/* /*
...@@ -104,6 +111,45 @@ void DPPAcquisitionController::postConfiguration() { ...@@ -104,6 +111,45 @@ void DPPAcquisitionController::postConfiguration() {
setCrateNumber(); setCrateNumber();
registerRefresher(liveProcessType, &DPPAcquisitionController::refreshLiveProcessTypeProperty, this); registerRefresher(liveProcessType, &DPPAcquisitionController::refreshLiveProcessTypeProperty, this);
// DPP Context.
// Warning: we suppose that the list mode block is ordered like the ADC controllers
releaseListModeContext(listModeContext);
int32 nbCrates = 0;
for (int32 adc = 0; adc < nbAdcControllers(); ++adc) {
int32 crate = adcController[adc]->crateNumber();
if (crate >= nbCrates) {
nbCrates = crate + 1;
}
}
listModeContext.crateBoard.nbCrates = nbCrates;
listModeContext.crateBoard.crates = new Crate[nbCrates];
for (int32 crate = 0; crate < nbCrates; ++crate) {
int32 nbBoards = 0;
for (int32 board = 0; board < nbAdcControllers(); ++board) {
if (board >= nbBoards) {
nbBoards = board + 1;
}
}
listModeContext.crateBoard.crates[crate].nbBoards = nbBoards;
listModeContext.crateBoard.crates[crate].boards = new Board[nbBoards];
for (int32 board = 0; board < nbAdcControllers(); ++board) {
listModeContext.crateBoard.crates[0].boards[board].boardType = (BoardType)adcController[board]->cardType();
listModeContext.crateBoard.crates[0].boards[board].crate = crate;
listModeContext.crateBoard.crates[0].boards[board].eventType = 0;
listModeContext.crateBoard.crates[0].boards[board].nbChannels = adcController[board]->nbChannels();
}
}
cout << "DPP context" << endl;
cout << listModeContext << endl;
} }
/* /*
...@@ -498,4 +544,57 @@ void DPPAcquisitionController::setContext() { ...@@ -498,4 +544,57 @@ void DPPAcquisitionController::setContext() {
// cout << listModeContext << endl; // cout << listModeContext << endl;
} }
DataBlock* decodeListModeBlock(AsciiDataFileManager* dataFileManager, AsciiDataFile* dataFile, string blockType, typename boost::tokenizer<boost::char_separator<char> >::iterator iter, typename boost::tokenizer<boost::char_separator<char> >::iterator end) {
cout << "decodeListModeBlock" << endl;
// Change
// - tok1.end() into end
// - getAbstractController into dataFileManager->getAbstractController
// - m_DataFile into dataFile
// - creation of the block to copy and return the block
// - goto error into return NULL
// Get number of GEGE
if (++iter == end) {
return NULL;
}
uint32 nbgeges = (uint32) strtol((*iter).c_str(), NULL, 10);
vector<AbstractController*> gegecontrollers;
for(uint32 i=0;i<nbgeges;++i) {
AbstractController* controller = NULL;
if (++iter == end) {
return NULL;
}
if ((*iter).empty() == false) {
controller = dataFileManager->getAbstractController(*iter);
}
gegecontrollers.push_back(controller);
}
// Get number of detector controller
if (++iter == end) {
return NULL;
}
uint32 nbdetectors = (uint32) strtol((*iter).c_str(), NULL, 10);
vector<AbstractController*> detectorcontrollers;
for(uint32 i=0;i<nbdetectors;++i) {
if (++iter == end) {
return NULL;
}
AbstractController* detector = NULL;
if ((*iter).empty() == false) {
detector = dataFileManager->getAbstractController(*iter);
}
detectorcontrollers.push_back(detector);
}
npp::ListModeBlock * newBlock = new npp::ListModeBlock(nbgeges, gegecontrollers, nbdetectors, detectorcontrollers);
dataFile->addDataBlock(newBlock);
return newBlock;
}
} }
/*
* 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 "ListModeBlock.h"
#include "InstrumentAbstraction/AbstractController.h"
#include <common/base/ServerProperties.h>
#include <lstdpp128/lstdpp.h>
#include <boost/format.hpp>
using namespace boost;
using namespace lstdpp128;
namespace npp {
ListModeBlock::ListModeBlock(uint32 nbgeges, const vector<AbstractController*>& gegeControllers, uint32 nbdetectors,
const vector<AbstractController*>& detectorControllers) :
DataBlock(true), m_NbGeges(nbgeges), m_GegeControllers(gegeControllers), m_NbDetectors(nbdetectors), m_DetectorControllers(
detectorControllers), m_Oldlistmodedatasize(0) {
// Empty
}
ListModeBlock::~ListModeBlock() {
// Empty
}
void ListModeBlock::writeBlock(std::ofstream & file) {
cout << "ListModeBlock write" << endl;
int32 *listmodedata = 0;
uint32 listmodedatasize = 0;
uint32 totallistmodedatasize = 0;
ostringstream filename;
filename << common::ServerProperties::getInstance()->getNomadDataPath() << boost::format("%06i") % m_RecordNumber << ".lst";
ofstream dataFile;
// Open data file
dataFile.open(filename.str().c_str(), std::ios::app | std::ios::binary);
if (dataFile) {
// Verify if first write
if (dataFile.tellp() == 0) {
// cout << "DPP context (ListModeBlock)" << endl;
// cout << listModeContext << endl;
// Write header
// uint32 buffer[4 + m_NbGeges];
// buffer[0] = 1;
// buffer[1] = 9;
// buffer[2] = 0;
// buffer[3] = m_NbGeges;
// for (uint32 i = 0; i < m_NbGeges; ++i) {
// if (m_GegeControllers[i] != NULL) {
// int32 evtype = 0; //any_cast<int32>(m_GegeControllers[i]->getValue("display_channel"));
// int32 card = any_cast<int32>(m_GegeControllers[i]->getValue("crate_number"));
// int32 channels = any_cast<int32>(m_GegeControllers[i]->getValue("nb_channels"));
// int32 type = any_cast<int32>(m_GegeControllers[i]->getValue("card_type"));
// buffer[4 + i] = type & 0x3F;
// buffer[4 + i] |= (channels & 0x3F) << 6;
// buffer[4 + i] |= (card & 0xF) << 12;
// buffer[4 + i] |= (evtype & 0xFFFF) << 16;
// }
// }
// dataFile.write((const char *) buffer, (4 + m_NbGeges) * sizeof(uint32));
string buffer = writeListModeContextToBinary(listModeContext);
dataFile.write(buffer.c_str(), buffer.size());
m_Oldlistmodedatasize = 0;
}
for (uint32 i = 0; i < m_NbDetectors; ++i) {
// Write list mode
if (m_DetectorControllers[i] != NULL) {
listmodedata = any_cast<int32*>(m_DetectorControllers[i]->getValue("list_mode_data"));
listmodedatasize = any_cast<int32>(m_DetectorControllers[i]->getValue("list_mode_data_size"));
if ((listmodedatasize != 0) && (listmodedata != NULL)) {
totallistmodedatasize += listmodedatasize / 4;
dataFile.write((const char *) listmodedata, listmodedatasize * sizeof(int32));
m_DetectorControllers[i]->setValue("list_mode_data_size", (int32) 0);
}
}
}
dataFile.close();
}
fstream dataFile1;
dataFile1.open(filename.str().c_str(), ios_base::in | ios_base::out | std::ios::binary);
if (dataFile1) {
dataFile1.seekp(2 * sizeof(uint32), ios_base::beg);
totallistmodedatasize += m_Oldlistmodedatasize;
dataFile1.write((const char *) &totallistmodedatasize, sizeof(uint32));
m_Oldlistmodedatasize = totallistmodedatasize;
dataFile1.close();
}
}
}
/*
* 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_LISTMODEBLOCK_H
#define NPP_LISTMODEBLOCK_H
#include <iostream>
#include <vector>
#include <string>
#include "controllers/common/datafile/DataBlock.h"
class AbstractController;
namespace npp {
class ListModeBlock: public DataBlock {
public:
ListModeBlock(uint32 nbgeges, const vector<AbstractController*>& gegeControllers, uint32 nbdetectors,
const vector<AbstractController*>& detectorControllers);
virtual ~ListModeBlock();
void writeBlock(std::ofstream & file);
private:
uint32 m_NbGeges;
std::vector<AbstractController*> m_GegeControllers;
uint32 m_NbDetectors;
std::vector<AbstractController*> m_DetectorControllers;
uint32 m_Oldlistmodedatasize;
};
}
#endif
...@@ -105,130 +105,120 @@ void RemoteDPPCoincidence::setDetectorControllers(const std::vector<ControllerPt ...@@ -105,130 +105,120 @@ void RemoteDPPCoincidence::setDetectorControllers(const std::vector<ControllerPt
void RemoteDPPCoincidence::start() { void RemoteDPPCoincidence::start() {
initFileReading(); // Need a mutex to avoid having two start at the same time.
resetData(); {
boost::mutex::scoped_lock lock(m_mutex);
// Numor initFileReading();
string numor; resetData();
size_t size = fileName().size();
if (size < 6) { // Numor
string prefix(6 - size, '0'); string numor;
numor = prefix + fileName(); size_t size = fileName().size();
} else {
numor = fileName();
}
// Setting the parameters if (size < 6) {
ptree parameters; string prefix(6 - size, '0');
numor = prefix + fileName();
} else {
numor = fileName();
}
parameters.put("numor", numor); // Setting the parameters
parameters.put("dT", dT() / 10); ptree parameters;
parameters.put("cleanDT", cleanDT() / 10);
// detector channels parameters.put("numor", numor);
ptree detectorChannelArray; parameters.put("dT", dT() / 10);
ptree channel; parameters.put("cleanDT", cleanDT() / 10);
int32 detectorChannelSize = detectorChannel.getSize();
for (int32 i = 0; i < detectorChannelSize; ++i) {
channel.put("", detectorChannel(i));
detectorChannelArray.push_back(std::make_pair("", channel));
}
parameters.put_child("detectorChannels", detectorChannelArray);
parameters.put("matrixResolution", coincidenceResolution()); // detector channels
parameters.put("maxBlocks", maxBlock()); ptree detectorChannelArray;
parameters.put("blockSize", blockSize()); ptree channel;
parameters.put("refreshTime", refreshTimeS()); int32 detectorChannelSize = detectorChannel.getSize();
for (int32 i = 0; i < detectorChannelSize; ++i) {
channel.put("", detectorChannel(i));
detectorChannelArray.push_back(std::make_pair("", channel));
}
parameters.put_child("detectorChannels", detectorChannelArray);
ptree context = writeListModeContextToPropertyTree(listModeContext); parameters.put("matrixResolution", coincidenceResolution());
parameters.put("maxBlocks", maxBlock());
parameters.put("blockSize", blockSize());
parameters.put("refreshTime", refreshTimeS());
parameters.put_child("context", context); ptree context = writeListModeContextToPropertyTree(listModeContext);
// Serialize the parameters parameters.put_child("context", context);
stringstream os;
write_json(os, parameters, false);
// Serialize the parameters
stringstream os;
write_json(os, parameters, false);
// Kill the application if one remains
m_server->killAllAndWaitFor("ncoincidence");
vector<string> args; // Kill the application if one remains
args.push_back(os.str()); m_server->killAllAndWaitFor("ncoincidence");
// Start the application vector<string> args;
m_coincidenceApplication = m_server->start("ncoincidence", args); args.push_back(os.str());
// Test if application started // Start the application
if (!m_coincidenceApplication->exists()) { m_coincidenceApplication = m_server->start("ncoincidence", args);
log(Level::s_Error) << "cannot start coincidence application" << endlog;
return;
}
// Create the publisher after the start of the application, because it is a blocking call // Test if application started
m_publisher.reset(); if (!m_coincidenceApplication->exists()) {
m_publisher = application::Publisher::create("dpp_publisher", 1); log(Level::s_Error) << "cannot start coincidence application" << endlog;
return;
}
cout << "publisher " << *m_publisher << endl; // Create the publisher after the start of the application, because it is a blocking call
m_publisher.reset();
m_publisher = application::Publisher::create("dpp_publisher", 1);
// Wait for the subscriber cout << "publisher " << *m_publisher << endl;
bool sync = m_publisher->waitForSubscribers();
// Create the subscriber after the publisher // Wait for the subscriber
auto_ptr<cameo::application::Subscriber> subscriber = application::Subscriber::create(*m_coincidenceApplication, "dpp_coincidence_results"); bool sync = m_publisher->waitForSubscribers();
cout << "subscriber " << *subscriber << endl;
// Start the test thread if necessary // Create the subscriber after the publisher
auto_ptr<boost::thread> thread = startFileReading(); auto_ptr<cameo::application::Subscriber> subscriber = application::Subscriber::create(*m_coincidenceApplication, "dpp_coincidence_results");
cout << "subscriber " << *subscriber << endl;
// Listen to the result stream // Start the test thread if necessary
vector<double> channelRates; auto_ptr<boost::thread> thread = startFileReading();
while (subscriber->receive(channelRates)) {
// copying the rates
for (int32 i = 0; i < totalNumberOfChannels(); i++) {
channelRate.set(i, channelRates[i]);
}
vector<double> coincidenceRates; // Listen to the result stream
if (!subscriber->receive(coincidenceRates)) { vector<double> channelRates;
break; while (subscriber->receive(channelRates)) {
} // copying the rates
for (int32 i = 0; i < totalNumberOfChannels(); i++) {
channelRate.set(i, channelRates[i]);
}
if (coincidenceRates.size() <= 4 * 7) { vector<double> coincidenceRates;
// Copying values if (!subscriber->receive(coincidenceRates)) {
for (int32 i = 0; i < 7; ++i) { break;
globalRate.set(i, coincidenceRates[i]);
globalCleanRate.set(i, coincidenceRates[7 + i]);
detectorRate.set(i, coincidenceRates[7 * 2 + i]);
detectorCleanRate.set(i, coincidenceRates[7 * 3 + i]);
} }
} else { if (coincidenceRates.size() <= 4 * 7) {
cerr << "problem with coincidence rates size" << endl; // Copying values
for (int32 i = 0; i < 7; ++i) {
globalRate.set(i, coincidenceRates[i]);
globalCleanRate.set(i, coincidenceRates[7 + i]);
detectorRate.set(i, coincidenceRates[7 * 2 + i]);
detectorCleanRate.set(i, coincidenceRates[7 * 3 + i]);
}
} else {
cerr << "problem with coincidence rates size" << endl;
}
} }
}
// Wait for the termination of the application
application::State state = m_coincidenceApplication->waitFor();
cout << "coincidence application terminated with state " << state << endl; // Wait for the termination of the application
application::State state = m_coincidenceApplication->waitFor();
// Join the test thread // Join the test thread
finishFileReading(thread); finishFileReading(thread);
}
void RemoteDPPCoincidence::stop() {
// Test the coincidence application and the publisher
if (m_coincidenceApplication.get() != 0 && m_publisher.get() != 0) {
if (fileReadingMode()) {
m_reader->stop();
}
cout << *m_publisher << " end of stream" << endl; cout << "coincidence application terminated with state " << state << endl;
m_publisher->sendEnd();
// we do not stop the application because the termination of the publisher will do it.
} }
} }
......
...@@ -40,7 +40,6 @@ public: ...@@ -40,7 +40,6 @@ public:
virtual void setDetectorControllers(const std::vector<ControllerPtr<acquisition::DetectorController> > & detectorControllers); virtual void setDetectorControllers(const std::vector<ControllerPtr<acquisition::DetectorController> > & detectorControllers);
virtual void start(); virtual void start();
virtual void stop();
virtual void raz(); virtual void raz();
void refreshNumberOfDetectorChannels(int32 value); void refreshNumberOfDetectorChannels(int32 value);
......
...@@ -37,42 +37,42 @@ RemoteDPPContext::~RemoteDPPContext() { ...@@ -37,42 +37,42 @@ RemoteDPPContext::~RemoteDPPContext() {
void RemoteDPPContext::postConfiguration() { void RemoteDPPContext::postConfiguration() {
// Warning: we suppose that the list mode block is ordered like the ADC controllers // Warning: we suppose that the list mode block is ordered like the ADC controllers
releaseListModeContext(listModeContext); // releaseListModeContext(listModeContext);
//
int32 nbCrates = 0; // int32 nbCrates = 0;
//
for (int32 adc = 0; adc < acquisitionController->nbAdcControllers(); ++adc) { // for (int32 adc = 0; adc < acquisitionController->nbAdcControllers(); ++adc) {
int32 crate = acquisitionController->adcController[adc]->crateNumber(); // int32 crate = acquisitionController->adcController[adc]->crateNumber();
if (crate >= nbCrates) { // if (crate >= nbCrates) {
nbCrates = crate + 1; // nbCrates = crate + 1;
} // }
} // }
//
listModeContext.crateBoard.nbCrates = nbCrates; // listModeContext.crateBoard.nbCrates = nbCrates;
listModeContext.crateBoard.crates = new Crate[nbCrates]; // listModeContext.crateBoard.crates = new Crate[nbCrates];
//