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){
Definition of the pure virtual base class of all 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.
Array container for managing multiple subsystems.
EPICS data event handling and storage.
Event buffer management for reading and processing CODA data.
void sigint_handler(int sig)
void sigusr_handler(int sig)
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.