00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "DaqFormatContext.h"
00010
00011 #include <sstream>
00012
00013 #include "DaqFormatModules/DaqReadoutSvc.h"
00014 #include "DaqXml/DaqXmlStream.h"
00015 #include "EventReadoutFormat/EventHeader.h"
00016 #include "EventReadoutFormat/EventReadout.h"
00017 #include "FileReadoutFormat/DataSeparatorRecord.h"
00018 #include "FileReadoutFormat/FileBuffer.h"
00019 #include "FileReadoutFormat/DaqFromFStream.h"
00020 #include "FileReadoutFormat/FileTraits.h"
00021 #include "GaudiKernel/MsgStream.h"
00022
00023 using DybDaq::DaqFormatContext;
00024 using DybDaq::DaqXmlStream;
00025 using DybDaq::DataSeparatorRecord;
00026 using DybDaq::EventHeader;
00027 using DybDaq::EventReadout;
00028 using DybDaq::FileBuffer;
00029 using DybDaq::DaqFromFStream;
00030 using DybDaq::FileTraits;
00031 using std::vector;
00032 using std::string;
00033
00034 const unsigned int DaqFormatContext::kExitOnInvalid = 0;
00035 const unsigned int DaqFormatContext::kSkipInvalid = DaqFormatContext::kExitOnInvalid + 1;
00036 const unsigned int DaqFormatContext::kProcessInvalid = DaqFormatContext::kSkipInvalid + 1;
00037
00038 static const string kTwoSpaces(" ");
00039
00040 DaqFormatContext::DaqFormatContext(const std::vector<std::string>& inputFiles,
00041 const unsigned int actionOnInvalid,
00042 IMessageSvc& msgSvc,
00043 IDaqReadoutSvc& daqSvc) :
00044 m_messageSvc(msgSvc),
00045 m_daqSvc(dynamic_cast<DaqReadoutSvc*>(&daqSvc)),
00046 m_expiredEndRecord(true),
00047 m_reader(0),
00048 m_event(0),
00049 m_nextFile(inputFiles.begin()),
00050 m_endFile(inputFiles.end()),
00051 m_warnedAboutSkip(false),
00052 m_actionOnInvalid(actionOnInvalid) {
00053 }
00054
00055 DaqFormatContext::~DaqFormatContext() {
00056 }
00057
00058 void* DaqFormatContext::identifier() const {
00059 return 0;
00060 }
00061
00062 const EventReadout* DaqFormatContext::event() const {
00063 return m_event;
00064 }
00065
00066 StatusCode DaqFormatContext::jump(const int distance) {
00067 if (0 > distance) {
00068 MsgStream log(&m_messageSvc,
00069 "DaqFormatContext");
00070 log << MSG::ERROR << "Can not move backward in a file" << endreq;
00071 return StatusCode::FAILURE;
00072 }
00073 for (int count = 0;
00074 distance != count;
00075 ++count) {
00076 StatusCode status = moveToNextEvent();
00077 if (status.isFailure()) {
00078 return status;
00079 }
00080 }
00081 if ((kProcessInvalid != m_actionOnInvalid) && (m_event->header().invalidData())) {
00082 MsgStream log(&m_messageSvc,
00083 "DaqFormatContext");
00084 if (kExitOnInvalid == m_actionOnInvalid) {
00085 delete m_event;
00086 m_event = 0;
00087 log << MSG::ERROR << "Exiting as Invalid Event has been detected" << endreq;
00088 return StatusCode::FAILURE;
00089 }
00090 if (kSkipInvalid == m_actionOnInvalid) {
00091 if (!m_warnedAboutSkip) {
00092 log << MSG::WARNING << "One or more Invalid Event has been detected, they will be skipped" << endreq;
00093 m_warnedAboutSkip = true;
00094 }
00095 do {
00096 delete m_event;
00097 StatusCode status = moveToNextEvent();
00098 if (status.isFailure()) {
00099 return status;
00100 }
00101 } while (m_event->header().invalidData());
00102 }
00103 }
00104 return StatusCode::SUCCESS;
00105 }
00106
00107 StatusCode DaqFormatContext::isGoodEvent() const {
00108 if (0 == m_event) {
00109 return StatusCode::FAILURE;
00110 }
00111 return StatusCode::SUCCESS;
00112 }
00113
00114 StatusCode DaqFormatContext::moveToNextEvent() {
00115 m_event = 0;
00116 while (0 == m_event) {
00117 if(0 == m_reader){
00118 m_reader = openNextFile();
00119 if(0 == m_reader){
00120 return StatusCode::FAILURE;
00121 }
00122 }
00123
00124 const FileBuffer* record = m_reader->nextRecord();
00125 if(0 == record){
00126 MsgStream log(&m_messageSvc,
00127 "DaqFormatContext");
00128 log << MSG::ERROR << "Failed to read next record from file: " << (*m_nextFile) << endreq;
00129 return StatusCode::FAILURE;
00130 }
00131
00132
00133
00134 if (m_expiredEndRecord && (0 != m_daqSvc)) {
00135 m_daqSvc->setFileRecord((const FileEndRecord*)0);
00136 }
00137 if(record->isMarked(FileTraits::kDataSeparatorRecord)) {
00138 const DataSeparatorRecord* dataSeparator = dynamic_cast<const DataSeparatorRecord*>(record);
00139 m_event = dataSeparator->extractBlock();
00140 delete record;
00141 m_expiredEndRecord = true;
00142 } else {
00143 if (0 != m_daqSvc) {
00144 m_daqSvc->setFileRecord(record);
00145 }
00146 if(record->isMarked(FileTraits::kFileEndRecord)) {
00147 m_expiredEndRecord = false;
00148 }
00149 std::stringstream message;
00150 message << '\n';
00151 DaqXmlStream xmlStream(message,
00152 kTwoSpaces,
00153 true);
00154 xmlStream.dumpElement(*record);
00155 MsgStream log(&m_messageSvc,
00156 "DaqFormatContext");
00157 log << MSG::INFO << message.str() << endreq;
00158 if(record->isMarked(FileTraits::kFileEndRecord)) {
00159 delete m_reader;
00160 m_reader = 0;
00161 ++m_nextFile;
00162 }
00163 }
00164 }
00165 return StatusCode::SUCCESS;
00166 }
00167
00168 DybDaq::DaqFromFStream* DaqFormatContext::openNextFile() {
00169 DaqFromFStream* result = 0;
00170
00171 if (m_nextFile == m_endFile) {
00172 MsgStream log(&m_messageSvc,
00173 "DaqFormatContext");
00174 log << MSG::INFO << "End of input file list" << endreq;
00175 return result;
00176 }
00177
00178 result = new DaqFromFStream();
00179 if(0 == result){
00180 MsgStream log(&m_messageSvc,
00181 "DaqFormatContext");
00182 log << MSG::ERROR << "Failed to create new file reader" << endreq;
00183 return result;
00184 }
00185
00186 const bool opened = result->openFile((*m_nextFile).c_str());
00187 if (!opened) {
00188 MsgStream log(&m_messageSvc,
00189 "DaqFormatContext");
00190 log << MSG::ERROR << "Failed to open input file: " << (*m_nextFile) << endreq;
00191 delete result;
00192 result = 0;
00193 }
00194 return result;
00195 }