Commit 18c328e4 authored by dino's avatar dino
Browse files

EventBuilder can now produce the list of timestamps for each input queue.

Added LOOP-ENDLOOP mechanism to define detector in femul's Topology file.

git-svn-id: svn://gal-serv.lnl.infn.it/agata/trunk/narval_emulator@1120 170316e4-aea8-4b27-aad4-0380ec0519c9
parent 63407da5
......@@ -12,6 +12,7 @@ using namespace ADF;
// end with a CONSUMER (possibly a fake one)
// or with a DISPATCHER
// If defined, the DISPATCHER sends the producer data in the synchronization object thisLocker
// BUILDER chains are completely equivalent to PRODUCER chains up to the fact that their data
// comes from the thisLocker objects and not from file
// Access to thisLocker has to follow the model Lock-Work-Unlock and takes place in Dispatch(),
......@@ -79,11 +80,7 @@ void ChainOfActors::Run()
ptrActor = &theActors[indActor];
size_of_output_buffer = ptrActor->sizeOut;
#ifdef EVB_INHERITS_FROM_NARVAL_PRODUCER
if(ptrActor->libType == PRODUCER || ptrActor->libType == BUILDER) {
#else
if(ptrActor->libType == PRODUCER) {
#endif
static_cast<NarvalProducer *>(ptrActor->nrvPointer)->process_block(
bufout, size_of_output_buffer, &used_of_output_buffer,
&error_code);
......@@ -99,9 +96,12 @@ void ChainOfActors::Run()
size_of_input_buffer = used_of_output_buffer;
}
#ifndef EVB_INHERITS_FROM_NARVAL_PRODUCER
else if(ptrActor->libType == BUILDER) {
#ifdef EVB_INHERITS_FROM_NARVAL_PRODUCER
static_cast<NarvalProducer *>(ptrActor->nrvPointer)->process_block(
#else
ptrActor->evbPointer->process_block(
#endif
bufout, size_of_output_buffer, &used_of_output_buffer,
&error_code);
if(error_code)
......@@ -115,7 +115,6 @@ void ChainOfActors::Run()
pong = (ping+1)%2; bufout = (void *)ioBuffs[pong];
size_of_input_buffer = used_of_output_buffer;
}
#endif
else if(ptrActor->libType == FILTER) {
static_cast<NarvalFilter *>(ptrActor->nrvPointer)->process_block(
......
......@@ -352,6 +352,7 @@ void getparams(int argc, char *argv[])
#ifdef WCT_THREADED
cout << " -nothr run the non-threaded event loop" << endl ;
#endif
cout << " -vadf nn adf LogMessage level (0=kError, 1=kWarning, 2=kInfo, 3=kOut)" << endl ;
cout << " " << endl ;
if(argc > 1 || ok < 0)
exit(EXIT_FAILURE);
......@@ -434,18 +435,79 @@ bool topologyRead(string topo)
cout << endl << "Reading topology from --> " << topo << endl;
bool loopState = false;
size_t loopIndValue = 0;
size_t loopIndActor = 0;
string loopSymbol;
vector<string> loopValues;
vector<string> loopActors;
string line, keyw, data;
while(getline(ifs, line)) {
while(true) {
// read new line or get it from stored loop statements
loopState &= loopIndValue < loopValues.size();
if(loopState) {
line = loopActors.at(loopIndActor++);
if(loopIndActor >= loopActors.size()) {
loopIndValue++;
loopIndActor = 0;
}
}
else {
if(!getline(ifs, line))
break;
}
if(!stringSplit(line, " \t", keyw, data))
continue; // empty or comment lines
cout << line << endl;
if( stringEq(keyw, "Loop") ) {
cout << line << endl;
string values, value1, value2;
if(!stringSplit(data, " \t", loopSymbol, values)) {
cout << "Format is: Loop Name Value1 Value2 ..." << endl;
return false;
}
// tokenize values
while(stringSplit(values, " \t", value1, value2)) {
loopValues.push_back(value1);
values = value2;
}
// read and store until EndLoop
bool hasEndLoop = false;
while(getline(ifs, line)) {
if(!stringSplit(line, " \t", keyw, data))
continue; // empty or comment lines
cout << line << endl;
if(stringEq(keyw, "EndLoop") ) {
hasEndLoop = true;
break;
}
loopActors.push_back(line);
}
if(!hasEndLoop) {
cout << "Missing ENDLOOP statement" << endl;
return false;
}
loopIndValue = 0;
loopIndActor = 0;
loopState = true;
cout << endl;
continue;
}
if( stringEq(keyw, "Chain") ) {
cout << line;
string count, conf;
if(!stringSplit(data, " \t", count, conf)) {
cout << "Format is: Chain numActors confDir" << endl;
cout << "\nFormat is: Chain numActors confDir" << endl;
return false;
}
if(loopState && conf==loopSymbol) { // replace conf with the next entry in loopNames
conf = loopValues[loopIndValue];
cout << " ==> " << conf;
}
cout << endl;
int nacts = atoi(count.c_str());
if(nacts < 2) {
cout << "There should be at least 2 actors per chain" << endl;
......@@ -460,9 +522,19 @@ bool topologyRead(string topo)
for(int nn = 0; nn < nacts; ) {
actor theActor(nn);
if(!getline(ifs, line)) {
cout << "Error reading line " << nn << " of chain " << theChains.size() << endl;
return false;
// read new line or get it from stored loop statements
if(loopState) {
line = loopActors[loopIndActor++];
if(loopIndActor >= loopActors.size()) {
loopIndValue++;
loopIndActor = 0;
}
}
else {
if(!getline(ifs, line)) {
cout << "Error reading line " << nn << " of chain " << theChains.size() << endl;
return false;
}
}
if(!stringSplit(line, " \t", keyw, data))
continue; // empty or comment lines
......
......@@ -24,7 +24,7 @@ EventBuilder::EventBuilder(std::string name, unsigned int nch) :
tsumbus = 100;
minFold = 1;
verbose = false;
details = false;
details = 0;
fActualClass = gActualClass = name;
......@@ -44,6 +44,13 @@ EventBuilder::EventBuilder(std::string name, unsigned int nch) :
}
EventBuilder::~EventBuilder() {
if(details&2) {
for(unsigned int nn = 0; nn < nchains; nn++) {
if(evq[nn].sTstDiff)
delete evq[nn].sTstDiff;
evq[nn].sTstDiff = NULL;
}
}
if(sTstamps)
delete sTstamps;
sTstamps = NULL;
......@@ -72,6 +79,12 @@ bool EventBuilder::Reset(int nch, int wminfold, int wsumbus)
evq[nn].inpKey = uKeyIn[nn];
else
evq[nn].inpKey = 0;
if(details&2) {
std::ostringstream sfn;
sfn << "EvB_tstdiff__000-UI__"+gActualClass+"_" << setfill('0') << setw(2) << nn << setfill(' ') << ".bdat";
evq[nn].sTstDiff = new sAppend<UInt_t>(fOdirPrefix+sfn.str(), 2048);
evq[nn].tstOld = 0;
}
}
inqLocker = new ChainLocker * [nchains];
......@@ -538,7 +551,7 @@ bool EventBuilder::InitBuilder()
EvbSpecTdiff->setFileName(fOdirPrefix+"Evb?"+gActualClass+".spec");
EvbSpecTdiff->setComment("timestamp differences");
hGroup.add(EvbSpecTdiff);
if(details) {
if(details&1) {
std::ostringstream sfn;
sfn << "Evb__000-" << nchains+2 << "-UI__";
sTstamps = new sAppend<UInt_t>(fOdirPrefix+sfn.str()+gActualClass+".bdat", 1000*(nchains+2) );
......@@ -620,12 +633,20 @@ void EventBuilder::GetParameters(UInt_t *error_code)
}
else if( stringEq(keyw, "TimestampCorrect") ) {
UInt_t ind(nchains);
Int_t val(0);
Int_t val(0);
ok = 2 == sscanf(data.c_str(), "%d %d", &ind, &val);
if(ok && ind < nchains) {
vCorrection[ind] = val;
}
}
else if( stringEq(keyw, "TimestampFixBug24") ) {
UInt_t ind(nchains);
Int_t val(0);
ok = 1 == sscanf(data.c_str(), "%d", &ind);
if(ok && ind < nchains) {
vCorrection[ind] = 0x7FFFFFFF;
}
}
else if( stringEq(keyw, "NoMultiHist") || stringEq(keyw, "NoLocalSpectra") ) {
fUseMultiHist = false;
ok = true;
......@@ -635,8 +656,7 @@ void EventBuilder::GetParameters(UInt_t *error_code)
ok = true;
}
else if( stringEq(keyw, "Details") ) {
details = true;
ok = true;
ok = 1 == sscanf(data.c_str(), "%d", &details);
}
else {
cout << " --> ignored";
......
......@@ -57,7 +57,7 @@ public:
ULong64_t tsumbus;
UInt_t minFold;
Bool_t verbose;
Bool_t details;
Int_t details;
std::vector<std::string> sKeyIn;
std::vector<unsigned int> uKeyIn;
......
......@@ -46,6 +46,8 @@ UInt_t EventQueue::addData(UInt_t * i4dat, UInt_t n4dat, Int_t tstCorr)
i4Add += i4len;
if(tstCorr)
addTstamp(data + indLast + 3, tstCorr);
if(sTstDiff)
addTstDiff(getTstamp(data + indLast + 3));
numEvts++;
added++;
}
......
......@@ -3,6 +3,7 @@
#include "ADFConfig.h"
#include <memory.h>
#include "sAppend.h"
const UInt_t queueSize = 4*1024*1024; // size of input queues in sizeof(Int_t) units
//const UInt_t queueSize = 128*1024; // size of input queues in sizeof(Int_t) units
......@@ -18,7 +19,8 @@ public:
tstFirst(0), tstLast(0), evnFirst(0), evnLast(0),
indFirst(0), indLast(0), indNext(0), numEvts(0),
endCount(0), errCount(0), totCount(0), statChan(0),
maxInputSize(0), maxQueueSize(0), badKeys(0), EodInserted(false), validSize(queueSize-5)
maxInputSize(0), maxQueueSize(0), badKeys(0), EodInserted(false), validSize(queueSize-5),
sTstDiff(NULL), tstOld(0)
{
memset(data, 0, sizeof(data));
}
......@@ -32,11 +34,38 @@ public:
return ibuf[0];
}
void addTstamp(UInt_t *ibuf, Int_t val) {
if(ibuf[0]==0xFFFFFFFF && ibuf[1]==0xFFFFFFFF)
return; // not for the EOD mark
ULong64_t tstnew = ((ULong64_t)ibuf[1] << 32) | (ULong64_t)ibuf[0];
#if 0
tstnew += val;
#else
if(val != 0x7FFFFFFF)
tstnew += val;
else
tstnew = (tstnew>>8)&0xFFFFFF000000 | tstnew&0xFFFFFF;
#endif
ibuf[0] = (UInt_t)( tstnew & 0XFFFFFFFF);
ibuf[1] = (UInt_t)((tstnew >> 32) & 0XFFFFFFFF);
}
void addTstDiff(ULong64_t timestamp) {
if(tstOld == 0) {
#if 1
// seconds and fraction of seconds of first timestamp, assuming 100 Ms/s
sTstDiff->add(UInt_t(timestamp/100000000));
sTstDiff->add(UInt_t(timestamp-100000000*(timestamp/100000000)));
#else
// time stamp of first event, written in little endian
sTstDiff->add(UInt_t(timestamp & 0xFFFFFFFF));
sTstDiff->add(UInt_t(timestamp >> 32));
#endif
}
else {
ULong64_t tstdiff = timestamp - tstOld;
sTstDiff->add(UInt_t(tstdiff & 0xFFFFFFFF));
}
tstOld = timestamp;
}
UInt_t getKey() {
return data[indFirst+1];
}
......@@ -85,6 +114,8 @@ public:
UInt_t validSize; // queueSize with some margin
Bool_t EodInserted; //
std::string myBuilder; // name of the specific EventBuilder
sAppend<UInt_t> *sTstDiff; // to generate the distribution of timestamp differences between events
ULong64_t tstOld; // ""
};
#endif // EVENTQUEUE_H_INCLUDED
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment