namespace std {} using namespace std;
#include <stdio.h>
#include <iostream>
#include <errno.h>
#include "mbsio.h"
#include "mbsio_protos.h"
#include "TEnv.h"
#include "TMrbNamedX.h"
#include "TMrbTransport.h"
#include "TMrbLogger.h"
#include "SetColor.h"
extern pthread_mutex_t global_data_mutex;
TMrbTransport * gMrbTransport = NULL;
static Char_t mbs_error_string[1024];
static SMrbNamedXShort kMrbXptLofTransportModes[] = {
{TMrbTransport::kSync, "SYNCHRONOUS" },
{TMrbTransport::kAsync, "ASYNCHRONOUS" },
{TMrbTransport::kFile, "FILE" },
{TMrbTransport::kRemote, "REMOTEFILE" },
{0, NULL }
};
static SMrbNamedXShort kMrbXptLofBufferElements[] = {
{TMrbTransport::kBufferHeader, "BUFFERHEADER" },
{TMrbTransport::kFileHeader, "FILEHEADER" },
{TMrbTransport::kEventHeader, "EVENTHEADER" },
{TMrbTransport::kSubeventHeader, "SUBEVENTHEADER" },
{TMrbTransport::kSubeventData, "DATA" },
{0, NULL }
};
extern TMrbLogger * gMrbLog;
ClassImp(TMrbTransport)
TMrbTransport::TMrbTransport(const Char_t * XptName, const Char_t * XptTitle) {
if (gMrbLog == NULL) gMrbLog = new TMrbLogger();
if (*XptTitle == '\0') {
SetTitle("MARaBOU transport");
} else {
SetTitle(XptTitle);
}
SetName(XptName);
fInputFile.Remove(0);
fTransportMode = kUndefined;
fBufferSize = -1;
fMBSDataIO = NULL;
fStopFlag = kFALSE;
mbs_pass_errors(mbs_error_string);
fLofTransportModes.SetName("Transport Modes");
fLofTransportModes.SetPatternMode();
fLofTransportModes.AddNamedX(kMrbXptLofTransportModes);
fLofBufferElements.SetName("Buffer Elements");
fLofBufferElements.SetPatternMode();
fLofBufferElements.AddNamedX(kMrbXptLofBufferElements);
gMrbTransport = this;
}
Bool_t TMrbTransport::Open(const Char_t * File, const Char_t * Mode, Int_t BufferSize) {
MBSDataIO *mbs;
TMrbNamedX * pmod;
ClearError();
pmod = fLofTransportModes.FindByName(Mode, TMrbLofNamedX::kFindUnique | TMrbLofNamedX::kFindIgnoreCase);
if (BufferSize <= 0) {
gMrbLog->Err() << "Illegal buffer size - " << BufferSize << endl;
gMrbLog->Flush(this->ClassName(), "Open");
SetError();
return(kFALSE);
} else if (pmod == NULL) {
gMrbLog->Err() << "Illegal transport mode - " << Mode << endl;
gMrbLog->Flush(this->ClassName(), "Open");
SetError();
return(kFALSE);
} else if ((mbs = mbs_open_file((Char_t *) File, (Char_t *) pmod->GetName(), BufferSize, NULL)) != NULL) {
fInputFile = File;
fTransportMode = (TMrbTransport::EMrbTransportMode) pmod->GetIndex();
fBufferSize = BufferSize;
fMBSDataIO = mbs;
Int_t scaleDown = gEnv->GetValue("TMrbTransport.ScaleDown", 100);
Int_t dumpInterval = gEnv->GetValue("TMrbTransport.DumpInterval", 0);
TString showItems = gEnv->GetValue("TMrbTransport.ShowItems", "ES");
this->SetShow(showItems.Data(), scaleDown);
this->SetDumpInterval(dumpInterval);
this->SetStat(scaleDown);
return(kTRUE);
} else {
PrintMbsIoError("Open");
SetError();
return(kFALSE);
}
}
Bool_t TMrbTransport::Close() {
ClearError();
if (fMBSDataIO == NULL || fMBSDataIO->fileno == -1) return(kTRUE);
if (!mbs_close_file(fMBSDataIO)) {
PrintMbsIoError("Close");
SetError();
return(kFALSE);
} else {
return(kTRUE);
}
}
Bool_t TMrbTransport::FreeBuffers() {
ClearError();
if (fMBSDataIO == NULL) return(kTRUE);
mbs_free_dbase(fMBSDataIO);
fMBSDataIO = NULL;
return(kTRUE);
}
Int_t TMrbTransport::ReadEvents(Int_t NofEvents) {
Int_t i;
Int_t nofEventsProcessed;
Int_t nofErrors;
Int_t abortOnError;
UInt_t eventType = 0;
ClearError();
nofEventsProcessed = 0;
nofErrors = 0;
if (fMBSDataIO == NULL) {
gMrbLog->Err() << "MBSIO not active" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
return(kFALSE);
}
abortOnError = 0;
if (NofEvents == 0) {
for (;;) {
do {
eventType = mbs_next_event(fMBSDataIO);
if (this->IsToBeStopped()) {
gMrbLog->Out() << "Detecting STOP flag" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
eventType = MBS_ETYPE_EOW;
}
} while (eventType == MBS_ETYPE_WAIT);
if (eventType == MBS_ETYPE_EOF) {
gMrbLog->Out() << "End of file " << fInputFile << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
Close();
break;
} else if (eventType == MBS_ETYPE_ERROR) {
nofErrors++;
SetError();
abortOnError++;
if (abortOnError > TMrbTransport::kMaxErrors) {
gMrbLog->Err() << "Aborting after " << abortOnError << " subsequent errors" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
eventType = MBS_ETYPE_ABORT;
break;
}
} else if (eventType == MBS_ETYPE_ABORT) {
nofErrors++;
SetError();
PrintMbsIoError("ReadEvents");
gMrbLog->Err() << "Aborting" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
break;
} else {
if (eventType == MBS_ETYPE_START) {
gMrbLog->Out() << "Event START (trigger 14)" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
} else if (eventType == MBS_ETYPE_STOP) {
gMrbLog->Out() << "Event STOP (trigger 15)" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
}
if (!ProcessEvent((s_vehe *) fMBSDataIO->evt_data)) {
eventType = MBS_ETYPE_ERROR;
break;
}
abortOnError = 0;
nofEventsProcessed++;
}
}
} else {
for (i = 0; i < NofEvents; i++) {
eventType = MBS_ETYPE_WAIT;
while (eventType == MBS_ETYPE_WAIT) {
eventType = mbs_next_event(fMBSDataIO);
if (this->IsToBeStopped()) {
gMrbLog->Out() << "Detecting STOP flag" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
eventType = MBS_ETYPE_EOF; break;
}
}
if (eventType == MBS_ETYPE_EOF) {
gMrbLog->Out() << "End of file " << fInputFile << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
Close();
SetError();
break;
} else if (eventType == MBS_ETYPE_ERROR) {
nofErrors++;
PrintMbsIoError("ReadEvents");
SetError();
abortOnError++;
if (abortOnError > TMrbTransport::kMaxErrors) {
gMrbLog->Err() << "Aborting after " << abortOnError << " subsequent errors" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
eventType = MBS_ETYPE_ABORT;
break;
}
} else if (eventType == MBS_ETYPE_ABORT) {
nofErrors++;
PrintMbsIoError("ReadEvents");
SetError();
gMrbLog->Err() << "Aborting" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
break;
} else {
if (eventType == MBS_ETYPE_START) {
gMrbLog->Out() << "Event START (trigger 14)" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
} else if (eventType == MBS_ETYPE_STOP) {
gMrbLog->Out() << "Event STOP (trigger 15)" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
SetError();
}
if (!this->ProcessEvent((s_vehe *) fMBSDataIO->evt_data)) {
eventType = MBS_ETYPE_ERROR;
break;
}
abortOnError = 0;
nofEventsProcessed++;
}
}
}
if (nofErrors > 0) {
gMrbLog->Err() << this->ClassName() << "::ReadEvents(): " << nofEventsProcessed
<< " event(s), " << nofErrors
<< " error(s)" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents");
} else {
gMrbLog->Out() << this->ClassName() << "::ReadEvents(): " << nofEventsProcessed
<< " event(s), " << " no errors" << endl;
gMrbLog->Flush(this->ClassName(), "ReadEvents", setblue);
}
return(eventType);
}
UInt_t TMrbTransport::NextSubevent(UShort_t * SevtData) {
UInt_t SevtType;
ClearError();
SevtType = mbs_next_sevent(fMBSDataIO);
if (SevtType == MBS_STYPE_EOE) {
return(0);
} else if (SevtType == MBS_STYPE_ERROR || SevtType == MBS_STYPE_ABORT) {
PrintMbsIoError("NextSubevent");
SetError();
return(0xffffffff);
} else {
mbs_pass_sevent(fMBSDataIO, SevtData);
return(fMBSDataIO->sevt_wc);
}
}
Bool_t TMrbTransport::ProcessEvent(s_vehe * EventData) {
UShort_t Data[1024];
for (;;) {
if (NextSubevent(Data) <= 0) break;
}
return(kTRUE);
}
const UShort_t * TMrbTransport::NextSubevent() {
UInt_t SevtType;
ClearError();
SevtType = mbs_next_sevent(fMBSDataIO);
if (SevtType == MBS_STYPE_EOE) {
return(NULL);
} else if (SevtType == MBS_STYPE_ERROR || SevtType == MBS_STYPE_ABORT) {
PrintMbsIoError("NextSubevent");
SetError();
return(NULL);
} else {
return((UShort_t *) fMBSDataIO->sevt_data);
}
}
Bool_t TMrbTransport::Show(const Char_t * BufElemKey, const Char_t * Output) {
FILE * out;
Bool_t sts;
TMrbNamedX *pbe;
TString keyName;
ClearError();
if (Output != NULL) {
out = fopen(Output, "a");
if (out == NULL) {
gMrbLog->Err() << "Can't open file \"" << Output << "\"" << endl;
gMrbLog->Flush(this->ClassName(), "Show");
SetError();
return(kFALSE);
}
} else {
out = stdout;
}
if ((pbe = fLofBufferElements.FindByName(BufElemKey, TMrbLofNamedX::kFindUnique | TMrbLofNamedX::kFindIgnoreCase)) == NULL) {
gMrbLog->Err() << "Illegal buffer element - " << BufElemKey << endl;
gMrbLog->Flush(this->ClassName(), "Show");
return(kFALSE);
}
keyName = pbe->GetName();
keyName.Resize(1);
sts = mbs_show(fMBSDataIO, keyName.Data(), out);
if (Output != NULL) fclose(out);
if (!sts) {
PrintMbsIoError("Show");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::SetShow(const Char_t * BufElemStr, Int_t ScaleDown, const Char_t * Output) {
FILE *out;
Bool_t sts;
UInt_t xbe;
TString sbe;
ClearError();
if (Output != NULL) {
out = fopen(Output, "a");
if (out == NULL) {
gMrbLog->Err() << "Can't open file \"" << Output << "\"" << endl;
gMrbLog->Flush(this->ClassName(), "SetShow");
SetError();
return(kFALSE);
}
} else {
out = stdout;
}
xbe = fLofBufferElements.FindPattern(BufElemStr, TMrbLofNamedX::kFindUnique | TMrbLofNamedX::kFindIgnoreCase);
if (xbe == 0) {
gMrbLog->Err() << "Illegal buffer element(s) - " << BufElemStr << endl;
gMrbLog->Flush(this->ClassName(), "SetShow");
return(kFALSE);
}
sbe.Remove(0);
if (xbe & kBufferHeader) sbe += 'B';
if (xbe & kFileHeader) sbe += 'F';
if (xbe & kEventHeader) sbe += 'E';
if (xbe & kSubeventHeader) sbe += 'S';
sts = mbs_set_show(fMBSDataIO, sbe.Data(), ScaleDown, out);
if (!sts) {
PrintMbsIoError("SetShow");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::ShowStat(const Char_t * Output) {
FILE *out;
Bool_t sts;
ClearError();
if (Output != NULL) {
out = fopen(Output, "a");
if (out == NULL) {
gMrbLog->Err() << "Can't open file \"" << Output << "\"" << endl;
gMrbLog->Flush(this->ClassName(), "ShowStat");
SetError();
return(kFALSE);
}
} else {
out = stdout;
}
sts = mbs_show_stat(fMBSDataIO, out);
if (Output != NULL) fclose(out);
if (!sts) {
PrintMbsIoError("ShowStat");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::SetStat(Int_t ScaleDown, const Char_t * Output) {
FILE *out;
Bool_t sts;
ClearError();
if (Output != NULL) {
out = fopen(Output, "a");
if (out == NULL) {
gMrbLog->Err() << "Can't open file \"" << Output << "\"" << endl;
gMrbLog->Flush(this->ClassName(), "SetStat");
SetError();
return(kFALSE);
}
} else {
out = stdout;
}
sts = mbs_set_stat(fMBSDataIO, ScaleDown, out);
if (!sts) {
PrintMbsIoError("SetStat");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::SetStream(Int_t MaxStreams, Int_t SlowDown) {
Bool_t sts;
ClearError();
sts = mbs_set_stream(fMBSDataIO, MaxStreams, SlowDown);
if (!sts) {
PrintMbsIoError("SetStream");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::SetDumpInterval(Int_t NofRecs) {
ClearError();
mbs_set_dump(fMBSDataIO, NofRecs);
return(kTRUE);
}
Bool_t TMrbTransport::OpenMEDFile(const Char_t * MEDFile) {
Bool_t sts;
ClearError();
sts = mbs_open_med(MEDFile);
if (sts) {
gMrbLog->Out() << "Writing MBS event data to file " << MEDFile << endl;
gMrbLog->Flush(this->ClassName(), "OpenMEDFile", setblue);
} else {
PrintMbsIoError("OpenMEDFile");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::CloseMEDFile() {
ClearError();
mbs_close_med();
gMrbLog->Out() << "MED file closed" << endl;
gMrbLog->Flush(this->ClassName(), "CloseMEDFile", setblue);
return(kTRUE);
}
Bool_t TMrbTransport::OpenLMDFile(const Char_t * LMDFile) {
Bool_t sts;
ClearError();
sts = mbs_open_lmd(LMDFile);
if (sts) {
gMrbLog->Out() << "Writing LMD data to file " << LMDFile << endl;
gMrbLog->Flush(this->ClassName(), "OpenLMDFile", setblue);
} else {
PrintMbsIoError("OpenLMDFile");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::CloseLMDFile() {
ClearError();
mbs_close_lmd();
gMrbLog->Out() << "LMD file closed" << endl;
gMrbLog->Flush(this->ClassName(), "CloseLMDFile", setblue);
return(kTRUE);
}
Bool_t TMrbTransport::OpenLogFile(const Char_t * LogFile) {
Bool_t sts;
ClearError();
sts = mbs_open_log(LogFile);
if (!sts) {
PrintMbsIoError("OpenLogFile");
SetError();
}
return(sts);
}
Bool_t TMrbTransport::PrintMbsIoError(const Char_t * Prefix) {
fErrorString = (Char_t *) mbs_error_string;
gMrbLog->Err() << Prefix << "(): Error in mbsio package -" << endl;
gMrbLog->Flush(this->ClassName(), "PrintMbsIoError");
gMrbLog->Err() << fErrorString << endl;
gMrbLog->Flush(this->ClassName(), "PrintMbsIoError");
fErrorString.Remove(0);
return(kTRUE);
}
Bool_t TMrbTransport::Version() {
TString vtext;
TString frame;
Int_t fl, i1, i2;
frame = "+--------------------------------------------+";
vtext = "TMrbTransport v%I% (%G%)";
fl = frame.Length() - 2;
i1 = (fl - vtext.Length())/2;
i2 = fl - vtext.Length() - i1;
cout << " " << frame << endl;
cout << " |";
cout << setw(i1) << " ";
cout << vtext;
cout << setw(i2) << " ";
cout << "|" << endl;
cout << " | TMrbTransport |" << endl;
cout << " | MARaBOU class to connect to MBS data |" << endl;
cout << " | via file or tcp server |" << endl;
cout << " | (c) R. Lutter |" << endl;
cout << " " << frame << endl << endl;
return(kTRUE);
}