26 std::cout <<
"handling signal no. " << sig <<
" ";
27 std::cout <<
"(press ctrl-\\ to abort now)\n";
32 std::cout <<
"handling signal no. " << sig <<
"\n";
33 std::cout <<
"Restarts the event loop in online mode." << std::endl;
37#include "THaCodaFile.h"
39#include "THaEtClient.h"
92 (
"online", po::value<bool>()->default_bool_value(
false),
93 "use online data stream");
95 (
"online.RunNumber", po::value<int>()->default_bool_value(0),
96 "Effective run number to be used by online system to find the parameter files");
98 (
"run,r", po::value<string>()->default_value(
"0:0"),
99 "run range in format #[:#]");
102 "data directory, also $QW_DATA");
104 (
"runlist", po::value<string>()->default_value(
""),
105 "run list file name");
107 (
"event,e", po::value<string>()->default_value(
"0:"),
108 "event range in format #[:#]");
110 (
"segment,s", po::value<string>()->default_value(
"0:"),
111 "run segment range in format #[:#]");
113 (
"chainfiles", po::value<bool>()->default_bool_value(
false),
114 "chain file segments together, do not analyze them separately");
117 "stem of the input CODA filename");
120 "extension of the input CODA filename");
122 (
"directfile", po::value<string>(),
123 "Run over single event file");
126 (
"allow-low-subbank-ids", po::value<bool>()->default_bool_value(
false),
127 "allow the sub-bank ids to be 31 or less, when using this flag, all ROCs must be sub-banked");
130 (
"ET.hostname", po::value<string>(),
131 "Name of the ET session's host machine --- Only used in online mode\nDefaults to the environment variable $HOSTNAME");
133 (
"ET.session", po::value<string>(),
134 "ET session name --- Only used in online mode\nDefaults to the environment variable $SESSION");
136 (
"ET.station", po::value<string>(),
137 "ET station name --- Only used in online mode");
139 (
"ET.waitmode", po::value<int>()->default_value(0),
140 "ET system wait mode: 0 is wait-forever, 1 is timeout \"quickly\" --- Only used in online mode");
142 (
"ET.exit-on-end", po::value<bool>()->default_value(
false),
143 "Exit the event loop if the end event is found. JAPAN remains open and waits for the next run. --- Only used in online mode");
145 (
"coda-version", po::value<int>()->default_value(3),
146 "Sets the Coda Version. Allowed values = {2,3}. \nThis is needed for writing and reading mock data. Mock data needs to be written and read with the same Coda Version.");
148 (
"max-event-rate", po::value<double>()->default_value(0.0),
149 "Maximum event write rate in Hz (0 = disabled, no rate limiting)");
159 QwError <<
"Online mode will not work without the CODA libraries!"
163 if (options.
HasValue(
"online.RunNumber")) {
166 if (options.
HasValue(
"ET.station")) {
171 if (options.
HasValue(
"ET.hostname")) {
176 if (options.
HasValue(
"ET.session")) {
184 tmp +=
" \"HOSTNAME\"";
186 if (tmp.Length() > 0)
188 tmp +=
" ET \"SESSION\"";
191 <<
" variable(s) is(are) not defined in your environment.\n"
192 <<
" This is needed to run the online analysis."
206 QwError <<
"ERROR: Can't get the data directory in the QwEventBuffer creator."
226 QwError <<
"Invalid Coda Version. Only versions 2 and 3 are supported. "
227 <<
"Please set using --coda-version 2(3)" <<
QwLog::endl;
231 decoder->SetAllowLowSubbankIDs( options.
GetValue<
bool>(
"allow-low-subbank-ids") );
239 <<
"(minimum interval: " << (1000.0 /
fMaxEventRate) <<
" ms)"
279 if (nevents==0) nevents=1;
283 <<
"CPU time used: " <<
fRunTimer.CpuTime() <<
" s "
285 <<
"Real time used: " <<
fRunTimer.RealTime() <<
" s "
296 std::string eventrange;
316 std::string runrange;
324 QwWarning <<
"No valid event range in run list file: "
326 <<
"Assuming the full event range." <<
QwLog::endl;
363 Int_t status = CODA_ERROR;
384 Int_t status = CODA_ERROR;
394 QwMessage <<
"Try to open the ET station with HOSTNAME=="
409 if (status == CODA_ERROR){
412 QwError <<
"ERROR: Unable to find data files for run "
457 Int_t status = CODA_OK;
480 if (
decoder->GetEvtNumber() > 1000) status = EOF;
497 }
while (status == CODA_OK &&
511 QwMessage << efficiency <<
"% efficiency)";
515 }
else if (
decoder->GetEvtNumber() > 0 &&
decoder->GetEvtNumber() % 100 == 0) {
532 if (status == CODA_OK){
534 UInt_t* evBuffer = (UInt_t*)
fEvStream->getEvBuffer();
538 decoder->DecodeEventIDBank(evBuffer);
550 if(buffer[0] == 0)
return;
551 UInt_t header = buffer[1];
552 int top = (header & 0xff000000) >> 24;
553 int bot = (header & 0xff );
555 if( (top == 0xff) && (bot != 0xcc) ){
557 }
else if( (top != 0xff) && (bot == 0xcc) ){
564 <<
", but it looks like the data is from Coda Version "
574 Int_t status = CODA_OK;
592 Int_t status = CODA_OK;
596 if (status != CODA_OK) {
610 auto now = std::chrono::steady_clock::now();
620 if (actual_sleep > std::chrono::duration<double>(0)) {
622 auto sleep_until_time = now + actual_sleep;
623 std::this_thread::sleep_until(sleep_until_time);
657 Int_t status = CODA_OK;
660 status = ((THaCodaFile*)
fEvStream)->codaWrite((UInt_t*) buffer);
666 Int_t status = CODA_OK;
671 UInt_t* ubuffer = (UInt_t*)buffer;
672 UInt_t event_length = ubuffer[0];
674 if( event_length == 0 || event_length > MAXEVLEN ) {
679 status = ((THaEtClient*)
fEvStream)->codaWrite(ubuffer, event_length);
680 if( status != CODA_OK ) {
694 std::vector<UInt_t> buffer;
695 std::vector<ROCID_t> ROCList;
699 std::vector<UInt_t> header =
decoder->EncodePHYSEventHeader(ROCList);
704 int* codabuffer =
new int[header.size() + buffer.size() + 1];
707 codabuffer[k++] = header.size() + buffer.size();
708 for (
size_t i = 0; i < header.size(); i++)
709 codabuffer[k++] = header.at(i);
710 for (
size_t i = 0; i < buffer.size(); i++)
711 codabuffer[k++] = buffer.at(i);
724 decoder->ResetControlParameters();
733 return decoder->GetStartSQLTime();
738 return decoder->GetEndSQLTime();
743 return decoder->GetStartUnixTime();
748 return decoder->GetEndUnixTime();
754 int localtime = (int)time(0);
755 decoder->EncodePrestartEventHeader(buffer, runnumber, runtype, localtime);
761 int localtime = (int)time(0);
763 decoder->EncodeGoEventHeader(buffer, eventcount, localtime);
769 int localtime = (int)time(0);
771 decoder->EncodePauseEventHeader(buffer, eventcount, localtime);
777 int localtime = (int)time(0);
779 decoder->EncodeEndEventHeader(buffer, eventcount, localtime);
796 UInt_t rocnum =
decoder->GetEvtType() - 0x90;
797 QwMessage <<
"QwEventBuffer::FillSubsystemConfigurationData: "
798 <<
"Found configuration event for ROC"
803 UInt_t *localbuff = (UInt_t*)(
fEvStream->getEvBuffer());
804 decoder->DecodeEventIDBank(localbuff);
805 while ((okay =
decoder->DecodeSubbankHeader(&localbuff[
decoder->GetWordsSoFar()]))){
807 if (
decoder->GetSubbankType() == 0x10) {
814 decoder->AddWordsSoFarAndFragLength();
828 &localbuff[
decoder->GetWordsSoFar()],
830 decoder->AddWordsSoFarAndFragLength();
831 QwDebug <<
"QwEventBuffer::FillSubsystemConfigurationData: "
832 <<
"Ending loop: fWordsSoFar=="<<
decoder->GetWordsSoFar()
846 UInt_t *localbuff = (UInt_t*)(
fEvStream->getEvBuffer());
848 decoder->DecodeEventIDBank(localbuff);
867 while ((okay =
decoder->DecodeSubbankHeader(&localbuff[
decoder->GetWordsSoFar()]))){
870 if (
decoder->GetSubbankType() == 0x10)
continue;
875 decoder->AddWordsSoFarAndFragLength();
915 for (
size_t i=0; i<nmarkers; i++){
918 tmpbank = ((tmpbank)<<32) +
decoder->GetSubbankTag();
921 &localbuff[
decoder->GetWordsSoFar()+offset],
922 decoder->GetFragLength()-offset);
925 QwDebug <<
"QwEventBuffer::FillSubsystemData: "
926 <<
"fROC=="<<
decoder->GetROC() <<
", GetSubbankTag()==" <<
decoder->GetSubbankTag()
929 &localbuff[
decoder->GetWordsSoFar()],
932 decoder->AddWordsSoFarAndFragLength();
960 QwVerbose <<
"QwEventBuffer::FillEPICSData: "
963 UInt_t *localbuff = (UInt_t*)(
fEvStream->getEvBuffer());
964 if (
decoder->GetBankDataType()==0x10){
965 while ((okay =
decoder->DecodeSubbankHeader(&localbuff[
decoder->GetWordsSoFar()]))){
967 if (
decoder->GetSubbankType() == 0x10)
continue;
971 decoder->AddWordsSoFarAndFragLength();
975 if (
decoder->GetSubbankType() == 0x3){
978 char* tmpchar = (Char_t*)&localbuff[
decoder->GetWordsSoFar()];
986 decoder->AddWordsSoFarAndFragLength();
997 if (
decoder->GetBankDataType() == 0x3){
1000 Char_t* tmpchar = (Char_t*)&localbuff[
decoder->GetWordsSoFar()];
1011 QwVerbose <<
"QwEventBuffer::FillEPICSData: End of routine"
1036 Int_t local_segment;
1038 std::vector<Int_t> tmp_segments;
1039 std::vector<Int_t> local_index;
1042 tmp_segments.clear();
1048 glob(searchpath.Data(), GLOB_ERR, NULL, &globbuf);
1054 }
else if (globbuf.gl_pathc == 1){
1063 <<
" Trying to find run segments for run "
1066 searchpath.Append(
".[0-9]*");
1067 glob(searchpath.Data(), GLOB_ERR, NULL, &globbuf);
1069 if (globbuf.gl_pathc == 0){
1087 for (
size_t iloop=0;iloop<globbuf.gl_pathc;++iloop){
1089 sscanf(globbuf.gl_pathv[iloop], scanvalue.Data(), &local_segment);
1090 tmp_segments.push_back(local_segment);
1092 local_index.resize(tmp_segments.size(),0);
1095 TMath::Sort(
static_cast<int>(tmp_segments.size()),&(tmp_segments[0]),&(local_index[0]),
1101 for (
size_t iloop=0; iloop<tmp_segments.size(); ++iloop){
1102 local_segment = tmp_segments[local_index[iloop]];
1105 if (local_segment == 0 ||
1121 QwError <<
"First requested run segment "
1138 Int_t last_runsegment;
1143 QwMessage <<
"Closing run segment " << last_runsegment <<
"."
1183 status = CODA_ERROR;
1224 QwDebug <<
"QwEventBuffer::OpenDataFile: File handle doesn't exist.\n"
1225 <<
" Try to open a new file handle!"
1230 QwError <<
"QwEventBuffer::OpenDataFile: The stream is not configured as an input\n"
1231 <<
" file stream! Can't deal with this!\n"
1237 if (rw.Contains(
"w",TString::kIgnoreCase)) {
1244 glob(
fDataFile.Data(), GLOB_ERR, NULL, &globbuf);
1245 if (globbuf.gl_pathc == 0){
1248 glob(
fDataFile.Data(), GLOB_ERR, NULL, &globbuf);
1250 if (globbuf.gl_pathc == 0){
1253 glob(
fDataFile.Data(), GLOB_ERR, NULL, &globbuf);
1255 if (globbuf.gl_pathc == 0){
1258 glob(
fDataFile.Data(), GLOB_ERR, NULL, &globbuf);
1260 if (globbuf.gl_pathc == 1){
1265 << filename.Data() <<
" or "
1286 const TString stationname)
1288 Int_t status = CODA_OK;
1291 if (stationname !=
""){
1292 fEvStream =
new THaEtClient(computer, session, mode, stationname.Data());
1294 fEvStream =
new THaEtClient(computer, session, mode);
1320 std::vector<UInt_t> tmpvec;
1325 QwDebug <<
"QwEventBuffer::GetMarkerWordList: fMarkerList.count(fThisRocBankLabel)=="
1327 <<
" fMarkerList.at(fThisRocBankLabel).size()=="
1341 if (markerpos < num_words && buffer[markerpos] == markerval){
1345 for (
size_t i=0; i<num_words; i++){
1346 if (buffer[i] == markerval){
void sigint_handler(int sig)
void sigusr_handler(int sig)
Definition of the pure virtual base class of all subsystems.
Array container for managing multiple subsystems.
An options class which parses command line, config file and environment.
#define QwVerbose
Predefined log drain for verbose messages.
#define QwError
Predefined log drain for errors.
#define QwWarning
Predefined log drain for warnings.
#define QwMessage
Predefined log drain for regular messages.
#define QwDebug
Predefined log drain for debugging output.
Event buffer management for reading and processing CODA data.
EPICS data event handling and storage.
CODA version 2 event decoder implementation.
CODA version 3 event decoder implementation.
EPICS slow controls data management.
void ExtractEPICSValues(const string &data, int event)
TString GetRunLabel() const
Returns a string like <run#> or <run#>.<file#>
Int_t EncodeSubsystemData(QwSubsystemArray &subsystems)
static const Int_t kRunNotSegmented
time_t GetStartUnixTime()
UInt_t fStartingPhysicsEvent
static std::string fDefaultDataDirectory
std::unordered_map< RocBankLabel_t, std::vector< UInt_t > > fMarkerList
enum QwEventBuffer::CodaStreamMode fEvStreamMode
Int_t CloseStream()
Closes a currently open event stream.
Int_t WriteEtEvent(int *buffer)
Int_t OpenETStream(TString computer, TString session, int mode, const TString stationname="")
Bool_t GetNextRunRange()
Read the next requested run range, return true if success.
Int_t EncodePrestartEvent(int runnumber, int runtype=0)
QwEventBuffer()
Default constructor.
void VerifyCodaVersion(const UInt_t *buffer)
Int_t WriteFileEvent(int *buffer)
Int_t OpenNextStream()
Opens the event stream (file or ET) based on the internal flags.
static const Int_t kFileHandleNotConfigured
std::vector< Int_t >::iterator fRunSegmentIterator
std::chrono::duration< double > fAccumulatedDelay
void ProcessOptions(QwOptions &options)
Sets internal flags based on the QwOptions.
Bool_t FillSubsystemData(QwSubsystemArray &subsystems)
TStopwatch fStopwatch
Timer used for internal timing.
Int_t WriteEvent(int *buffer)
Int_t GetSegmentNumber() const
Return CODA file segment number.
std::unique_ptr< QwParameterFile > fEventListFile
void ResetControlParameters()
const TString & DataFile(const UInt_t run, const Short_t seg)
TString GetStartSQLTime()
Bool_t fEventRateLimitEnabled
static void DefineOptions(QwOptions &options)
std::unordered_map< RocBankLabel_t, std::vector< UInt_t > > fOffsetList
Double_t fCleanParameter[3]
Scan data/clean data from the green monster.
UInt_t FindMarkerWord(UInt_t markerID, UInt_t *buffer, UInt_t num_words)
TString fDataFileExtension
Int_t GetRunNumber() const
Return CODA file run number.
static const UInt_t kNullDataWord
static const Int_t kNoNextDataFile
RocBankLabel_t fThisRocBankLabel
Bool_t GetNextEventRange()
Read the next requested event range, return true if success.
Bool_t DataFileIsSegmented()
std::pair< Int_t, Int_t > fRunRange
std::pair< UInt_t, UInt_t > fEventRange
Int_t OpenDataFile(UInt_t current_run, Short_t seg)
static std::string fDefaultDataFileExtension
std::string fRunListFileName
TStopwatch fRunTimer
Timer used for runlet processing loop.
static std::string fDefaultDataFileStem
Bool_t GetNextRunNumber()
Get the next run in the active run range, proceed to next range if needed.
std::chrono::duration< double > fMinEventInterval
Bool_t FillEPICSData(QwEPICSEvent &epics)
std::pair< Int_t, Int_t > fSegmentRange
std::unique_ptr< QwParameterFile > fRunListFile
std::size_t CheckForMarkerWords(QwSubsystemArray &subsystems)
std::chrono::steady_clock::time_point fLastEventTime
std::vector< Int_t > fRunSegments
Bool_t FillSubsystemConfigurationData(QwSubsystemArray &subsystems)
UInt_t GetMarkerWord(UInt_t markerID)
static std::ostream & endl(std::ostream &)
End of the line.
Command-line and configuration file options processor.
std::pair< int, int > GetIntValuePair(const std::string &key)
Get a pair of integer values.
po::options_description_easy_init AddDefaultOptions()
Add a default option.
T GetValue(const std::string &key)
Get a templated value.
bool HasValue(const std::string &key)
Has this key been defined.
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
static std::pair< int, int > ParseIntRange(const std::string &separatorchars, const std::string &range)
Parse a range of integers as #:# where either can be missing.
Container for managing multiple subsystems with common operations.
void SetCodaRunNumber(UInt_t runnum)
Set the internal record of the CODA run number.
void SetCleanParameters(Double_t cleanparameter[3])
Set the internal record of the CODA event number.
UInt_t GetEventTypeMask() const
Get event type mask.
void GetMarkerWordList(const ROCID_t roc_id, const BankID_t bank_id, std::vector< UInt_t > &marker) const
void EncodeEventData(std::vector< UInt_t > &buffer)
Encode the data in this event.
void SetCodaSegmentNumber(UInt_t segnum)
Set the internal record of the CODA segment number.
Int_t ProcessEvBuffer(const UInt_t event_type, const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words)
Process the event buffer for events.
void SetCodaEventNumber(UInt_t evtnum)
Set the internal record of the CODA event number.
void SetCodaEventType(UInt_t evttype)
Set the internal record of the CODA event type.
Int_t ProcessConfigurationBuffer(const ROCID_t roc_id, const BankID_t bank_id, UInt_t *buffer, UInt_t num_words)
Process the event buffer for configuration events.
void GetROCIDList(std::vector< ROCID_t > &list)
Get the ROCID list.