/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
*
* MAUS is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MAUS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MAUS. If not, see .
*
*/
#include "MDprocessManager.h"
#include
using namespace std;
MDprocessManager::MDprocessManager()
:_eMap(), _status(OK), _runNumber((uint32_t)-1), _timeStamp(0), _eventId(0),
_spillNumber(-1), _eventSizes(1,0), _gdcId(-1), _ldcId(-1), _eventType(0), _physEventNumber(-1),
_equipmentType(0), _boardId(-1), _firstEventProc(0), _startOfRunProc(0),
_endOfRunProc(0), _startOfSpillProc(0), _endOfSpillProc(0), _superHeaderProc(0),
_eventHeaderProc(0), _equipmentHeaderProc(0)
{
// Enable all equipments by default
equipMap_t::iterator it=MDequipMap::begin();
while ( it != MDequipMap::end() ){
// cout << " Enable equipment ID " << it->first << endl;
_enableMap[it->first] = true;
++it;
}
}
void MDprocessManager::SetTest(DataTestCallback funk)
{
// set the test function for all fragments
equipMap_t::iterator it=MDequipMap::begin();
while ( it != MDequipMap::end() ){
// cout << " Enable equipment ID " << it->first << endl;
(it->second)->GetFragmentPtr()->SetTest( funk );
++it;
}
}
void MDprocessManager::SetFragmentProc(unsigned int aType,MDprocessor* aProc){
if (MDequipMap::IsDefined(aType)){
_fragmentProc[aType] = aProc;
aProc->SetProcessManager(this);
} else {
stringstream ss;
ss << "WARNING in MDprocessManager::SetFragmentProc : Type " ;
ss << dec << aType << " not found in the map, ignored." << endl;
throw MDexception( ss.str() );
}
}
void MDprocessManager::SetFragmentProc(string aName,MDprocessor* aProc){
SetFragmentProc(MDequipMap::GetType(aName), aProc);
}
void MDprocessManager::SetPartEventProc(unsigned int aType,MDprocessor* aProc){
if (MDequipMap::IsDefined(aType)){
_partEventProc[aType] = aProc;
aProc->SetProcessManager(this);
} else {
stringstream ss;
ss << "WARNING in MDprocessManager::SetPartEventProc : Type " ;
ss << dec << aType << " not found in the map, ignored." << endl;
throw MDexception( ss.str() );
}
}
void MDprocessManager::SetPartEventProc(string aName,MDprocessor* aProc){
SetPartEventProc(MDequipMap::GetType(aName), aProc);
}
void MDprocessManager::DumpContextData()
{
cout << " *** Process Manager Context Data ***" << dec << endl;
cout << " Run Number : " << GetRunNumber();
cout << " ; GDC Id : " << GetGdcId();
cout << " ; LDC Id : " << GetLdcId();
cout << " ; Event Type : " << GetEventType();
cout << " ; Physics Event Number : " << GetPhysEventNumber();
cout << " ; Equipment Type : " << GetEquipmentType();
cout << " ; Board Id : " << GetBoardId() ;
cout << " ; Spill Number : " << GetSpillNumber() ;
cout << " ; Time Stamp : " << GetTimeString();
cout << " ; EventId : " << GetEventId() << endl;
}
string MDprocessManager::GetTimeString()
{
time_t xMyTime = _timeStamp;
return ctime( &xMyTime );
}
void MDprocessManager::SetTimeStamp() {
time_t rawtime;
// get the time:
time(&rawtime);
uint32_t t = rawtime;
this->SetTimeStamp(t);
}
int MDprocessManager::Process(unsigned char* aDataPtr) {
_status = OK;
MDevent theEvent(aDataPtr);
uint32_t oldType = GetEventType();
SetEventType(theEvent.EventType());
SetTimeStamp( *(theEvent.TimeStampPtr()) );
SetEventId( *(theEvent.EventIdPtr()) );
// cout << "\nRun: " << GetRunNumber() << " Spill: " << GetSpillNumber() << " Evt Type: " << GetEventType() << endl;
if (_runNumber != theEvent.RunNb()) { // first event
if ( GetEventType() != START_OF_RUN ) {
cerr << "WARNING : The first event is not a START_OF_RUN. Spill count and Event count not accurate. " << endl;
_spillNumber = -1;
}
if (_firstEventProc) {
try { _status = _firstEventProc->Process(&theEvent);}
catch(...) {throw MDexception("ERROR processing First Event");}
}
if (theEvent.IsSuperEvent()) {
_nLdcs = theEvent.NsubEvent();
_eventSizes.resize(_nLdcs+1);
} else {
_nLdcs = 1;
}
}
SetRunNumber(theEvent.RunNb());
switch ( GetEventType() ) {
case START_OF_RUN:
if ( oldType != START_OF_RUN ) { // There are two consecutive START_OF_RUN events per LDC.
// Only the first one generates a call to the
// startOfRun Procedure
_spillNumber = -1;
if (_startOfRunProc) {
try { _status = _startOfRunProc->Process(&theEvent);}
catch(...) {throw MDexception("ERROR processing Start of Run");}
}
}
break;
case END_OF_RUN:
if ( oldType != END_OF_RUN ) {
if (_endOfRunProc) {
try { _status = _endOfRunProc->Process(&theEvent);}
catch(...) {throw MDexception("ERROR processing End of Run");}
}
}
break;
case START_OF_BURST: // MICE start of Spill corresponds to DATE START_OF_BURST (clash of name space)
if ( oldType != START_OF_BURST ) { // There might be several consecutive START_OF_BURST
// events (one per LDC if no building)
// Only the first one generates a call to the
// startOfSpill Procedure
++_spillNumber;
if (_startOfSpillProc) {
try { _status = _startOfSpillProc->Process(&theEvent);}
catch(...) {throw MDexception("ERROR processing Start of Spill");}
}
}
break;
case END_OF_BURST:
if ( oldType != END_OF_BURST ) {
if (_endOfSpillProc) {
try {_status = _endOfSpillProc->Process(&theEvent);}
catch(...) {throw MDexception("ERROR processing End of Spill");}
}
}
break;
/*
case PHYSICS_EVENT:
if ( oldType != PHYSICS_EVENT ) {
++_physEventNumber;
} else {
//cerr << "WARNING : Two consecutive DAQ events found in data file (no event building?)" << endl;
//cout<<"WARNING : Two consecutive DAQ events found in data file (no event building?)" << endl;
}
break;
*/
case PHYSICS_EVENT:
++_physEventNumber;
break;
default:
break;
}
int nPart(0), xPart(0);
if (theEvent.IsSuperEvent()) {
SetGdcId(theEvent.GdcId());
_eventSizes[0] = theEvent.GetSize();
if (_superHeaderProc) {
try {
_status = _superHeaderProc->Process(&theEvent);
}
catch(...) {throw MDexception("ERROR processing Superevent header.");}
}
if (theEvent.NsubEvent() != _nLdcs) {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessEvent :"<< endl;
ss << "Sub Event Mismatch (nLdcs: " << _nLdcs << "!=" << theEvent.NsubEvent() << ").";
throw MDexception( ss.str() );
}
nPart = ProcessSubEvent((unsigned char*)theEvent.GetSubEventPtr(0));
// cout << "nPart: " << nPart << endl;
for (unsigned int iEvt=1; iEvt<_nLdcs; iEvt++){
if (_status != OK) return _status;
xPart = ProcessSubEvent((unsigned char*)theEvent.GetSubEventPtr(iEvt));
if (nPart != xPart) {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessEvent :"<< endl;
ss << "Trigger Mismatch (nEvts " << nPart << "!=" << xPart << ").";
throw MDexception( ss.str() );
}
// cout << "nPart: " << nPart << " " << xPart << endl;
}
} else {
return ProcessSubEvent(theEvent.GetDataPtr());
}
return nPart;
}
int MDprocessManager::ProcessSubEvent(unsigned char* aDataPtr){
MDevent theEvent(aDataPtr);
MDeventFragment theEquipmentHeader;
MDfragment* myFragPtr;
int32_t nPart(-1), nPart_this(0), xLdc(0);
xLdc = theEvent.LdcId();
this->SetLdcId(xLdc);
_eventSizes[xLdc+1] = theEvent.GetSize();
if (_eventHeaderProc) {
try {
_status = _eventHeaderProc->Process(&theEvent);
}
catch(MDexception & lExc) {
string message = lExc.GetDescription();
throw MDexception(message + "\nExeption while processing event header.");
}
if (_status != OK) throw MDexception("ERROR in MDprocessManager::ProcessSubEvent from _eventHeaderProc->Process");
}
// loop over equipments
if ( theEvent.PayLoadSize() ) { // There is some data loop over eventFragments
for (unsigned int ifr=0; ifrProcess(&theEquipmentHeader);
}
catch(...) {throw MDexception("Exeption while processing equipment header.");}
if(_status != OK) throw MDexception("ERROR in MDprocessManager::ProcessSubEvent from _equipmentHeaderProc->Process ");
}
// Check if the user wants this equipment to be decoded
if (IsEnabled(GetEquipmentType())) {
// Get a pointer to the dynamically assigned pointer from the map
myFragPtr = MDequipMap::GetFragmentPtr(GetEquipmentType());
// Get the data pointer
unsigned char* myFragDataPtr = theEquipmentHeader.EquipmentDataPtr();
// Get the data size
uint32_t myFragDataSize = theEquipmentHeader.EquipmentDataSize();
// cout << ifr << " Equipment " << MDequipMap::GetName(GetEquipmentType())
// << " found, size: " << myFragDataSize << endl;
if (nPart > 0 && myFragDataSize==0)
if (MDequipMap::GetName(GetEquipmentType())!="VRB") {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessSubEvent :"<< endl;
ss << "In fragment " << MDequipMap::GetName(GetEquipmentType()) << " (board Id: " << GetBoardId()
<< ") Event size is 0.";
throw MDexception( ss.str() );
}
if (myFragPtr && myFragDataSize) { // the equipment is defined in the map and filled with data
try {
myFragPtr->SetDataPtr(myFragDataPtr, myFragDataSize);
myFragPtr->SetBoardID(_boardId);
if ( myFragPtr->IsMadeOfParticles() || MDequipMap::GetName(GetEquipmentType())=="VLSBMaster") {
int xPart = myFragPtr->InitPartEventVector();
if (nPart<0) nPart = xPart;
else {
nPart_this = xPart;
if (nPart != nPart_this) {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessSubEvent :"<< endl;
ss << "Trigger Mismatch (nEvts " << nPart << "!=" << nPart_this << ").";
throw MDexception( ss.str() );
}
}
// cout << "@ nPart: " << nPart << " " << nPart_this << endl;
}
}
catch (MDexception lExc)
{
stringstream ss;
ss << lExc.GetDescription() << endl;
ss << "*** Unpacking exception in MDprocessManager::ProcessSubEvent :"<< endl;
ss << "while initializing the fragment";
throw MDexception( ss.str() );
}
if (_fragmentProc[GetEquipmentType()]) {
try {
// cout << " Equipment " << MDequipMap::GetName(GetEquipmentType())
// << " going to call the fragment processor." << endl;
_status = _fragmentProc[GetEquipmentType()]->Process(myFragPtr);
}
catch(MDexception lExc){
stringstream ss;
ss << lExc.GetDescription() << endl;
ss << "*** Unpacking exception in MDprocessManager::ProcessSubEvent : "<< endl;
ss << "while processing fragment in board " << MDequipMap::GetName( this->GetEquipmentType() );
ss << " Geo " << this->GetBoardId();
throw MDexception( ss.str() );
}
}
if (_status != OK) {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessSubEvent : "<< endl;
ss << "while processing fragment in board " << MDequipMap::GetName( this->GetEquipmentType() );
ss << " Geo " << this->GetBoardId() << endl;
ss << "The status is : " << _status;
throw MDexception( ss.str() );
}
// loop over particle events if there are
for (int32_t iPart=0 ; iPartProcess(myFragPtr->GetPartEventPtr(iPart));
}
catch(MDexception lExc){
stringstream ss;
ss << lExc.GetDescription() << endl;
ss << "*** Unpacking exception in MDprocessManager::ProcessSubEvent : "<< endl;
ss << "while processing particle event in board ";
ss << MDequipMap::GetName( this->GetEquipmentType() ) << " Geo " << this->GetBoardId();
throw MDexception( ss.str() );
}
}
if (_status != OK) {
stringstream ss;
ss << "ERROR in MDprocessManager::ProcessSubEvent : "<< endl;
ss << "while processing particle event in board ";
ss << MDequipMap::GetName( this->GetEquipmentType() ) << " Geo " << this->GetBoardId() << endl;
ss << "The status is : " << _status;
throw MDexception( ss.str() );
}
}
}
}
}
}
if (nPart < 0) return 0;
return nPart;
}
void MDprocessManager::DumpProcessors()
{
procMap_t::iterator it;
cout<<"+++++++ Dump Processors +++++++"<