00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "DybIODaqSvc.h"
00010
00011 #include "DaqReadoutFormat/ByteBuffer.h"
00012 #include "DaqFormatModules/DaqReadoutSvc.h"
00013 #include "DaqXml/DaqXmlStream.h"
00014 #include "Event/DaqBlock.h"
00015 #include "Event/DaqBlockHeader.h"
00016 #include "FileReadoutFormat/DaqFromStrStream.h"
00017 #include "FileReadoutFormat/FileBuffer.h"
00018 #include "FileReadoutFormat/FileTraits.h"
00019 #include "GaudiKernel/MsgStream.h"
00020 #include "GaudiKernel/IConversionSvc.h"
00021 #include <string>
00022
00023 using DayaBay::DaqBlock;
00024 using DayaBay::DaqBlockHeader;
00025 using DybDaq::ByteBuffer;
00026 using DybDaq::DaqFromStrStream;
00027 using DybDaq::DaqXmlStream;
00028 using DybDaq::FileBuffer;
00029 using DybDaq::FileEndRecord;
00030 using DybDaq::FileTraits;
00031 using std::string;
00032
00033 static const string kTwoSpaces(" ");
00034
00035 DybIODaqSvc::DybIODaqSvc(const std::string& name,
00036 ISvcLocator* svc) :
00037 Service(name,
00038 svc),
00039 m_rioSvc(0),
00040 m_input(0),
00041 m_convSvc(0),
00042 m_daqSvc(0),
00043 m_daqBlockCnv(0),
00044 m_nextInsertion(0),
00045 m_entry(0),
00046 m_pendingHeader(0) {
00047 declareProperty("DaqBlockLocation",
00048 m_daqBlockLocation=DayaBay::DaqBlockHeaderLocation::Default,
00049 "Location in file where DAQ block will be saved.");
00050 }
00051
00052 StatusCode DybIODaqSvc::queryInterface(const InterfaceID& id,
00053 void** interface) {
00054 if (IDybIODaqSvc::interfaceID().versionMatch(id)) {
00055
00056 *interface = dynamic_cast<IDybIODaqSvc*>(this);
00057 addRef();
00058 return StatusCode::SUCCESS;
00059 }
00060
00061 return Service::queryInterface(id,
00062 interface);
00063 }
00064
00065 StatusCode DybIODaqSvc::finalize() {
00066 if (0 != m_pendingHeader) {
00067 delete m_pendingHeader;
00068 }
00069 if (0 != m_daqSvc) {
00070 m_daqSvc->release();
00071 }
00072 if (0 != m_convSvc) {
00073 m_convSvc->release();
00074 }
00075 if (0 != m_rioSvc) {
00076 m_rioSvc->release();
00077 }
00078 return Service::finalize();
00079 }
00080
00081 StatusCode DybIODaqSvc::setEventEntry(const unsigned int entry) {
00082 findDaqReadoutSvc();
00083 if (0 != m_daqSvc) {
00084 m_daqSvc->setFileRecord((const FileEndRecord*)0);
00085 }
00086 while (m_nextInsertion == entry) {
00087 if (0 != m_pendingHeader) {
00088 parseDaqBlock(*(m_pendingHeader->daqBlock()));
00089 delete m_pendingHeader;
00090 }
00091 m_pendingHeader = readDaqBlockHeader();
00092 if (0 == m_pendingHeader) {
00093 return StatusCode::FAILURE;
00094 }
00095 m_nextInsertion += m_pendingHeader->deltaEvents();
00096 }
00097 return StatusCode::SUCCESS;
00098 }
00099
00100 StatusCode DybIODaqSvc::parseDaqBlock(const DaqBlock& daqBlock) {
00101 string content((const char*)(&((*(daqBlock.bytes()))[0])),
00102 daqBlock.size() * ByteBuffer::BYTES_IN_INT);
00103 DaqFromStrStream reader;
00104 reader.openWithString(content);
00105 const FileBuffer* record = reader.nextRecord();
00106 while (0 != record) {
00107 if(record->isMarked(FileTraits::kDataSeparatorRecord)) {
00108 return StatusCode::FAILURE;
00109 } else {
00110 if (0 != m_daqSvc) {
00111 m_daqSvc->setFileRecord(record);
00112 }
00113 std::stringstream message;
00114 message << '\n';
00115 DaqXmlStream xmlStream(message,
00116 kTwoSpaces,
00117 true);
00118 xmlStream.dumpElement(*record);
00119 MsgStream log(msgSvc(),
00120 "DaqFormatContext");
00121 log << MSG::INFO << message.str() << endreq;
00122 }
00123 record = reader.nextRecord();
00124 }
00125 return StatusCode::SUCCESS;
00126 }
00127
00128 StatusCode DybIODaqSvc::findDaqReadoutSvc() {
00129 if (0 != m_daqSvc) {
00130 return StatusCode::SUCCESS;
00131 }
00132 MsgStream log(msgSvc(),
00133 "DybIODaqSvc");
00134 IService* isvc = 0;
00135 StatusCode status = service("DaqReadoutSvc",
00136 "DaqReadoutSvc",
00137 isvc);
00138 if (status.isFailure() ) {
00139 log << MSG::ERROR
00140 << "Failed to get IDaqReadoutSvc as IService"
00141 << endreq;
00142 return status;
00143 }
00144 IDaqReadoutSvc* daqSvc = 0;
00145 status = isvc->queryInterface(IDaqReadoutSvc::interfaceID(),
00146 (void**)&daqSvc);
00147 if (status.isFailure()) {
00148 log << MSG::ERROR
00149 << "Service does not implement IDaqReadoutSvc interface"
00150 << endreq;
00151 return status;
00152 }
00153 m_daqSvc = dynamic_cast<DaqReadoutSvc*>(daqSvc);
00154 return StatusCode::SUCCESS;
00155 }
00156
00157 StatusCode DybIODaqSvc::findInputStream() {
00158 if (0 != m_input) {
00159 return StatusCode::SUCCESS;
00160 }
00161 MsgStream log(msgSvc(),
00162 "DybIODaqSvc");
00163 IService* isvc = 0;
00164 StatusCode sc = service("RootIOCnvSvc",
00165 isvc,
00166 true);
00167 if(sc.isFailure()){
00168 log << MSG::ERROR
00169 << "Failed to get RootIOCnvSvc as IService"
00170 << endreq;
00171 return sc;
00172 }
00173 sc = isvc->queryInterface(IRootIOSvc::interfaceID(),
00174 (void**)&m_rioSvc);
00175 if (sc.isFailure()) {
00176 log << MSG::ERROR
00177 << "Conversion service RootIOCnvSvc"
00178 << " does not implement IRootIOCnvSvc"
00179 << endreq;
00180 return sc;
00181 }
00182
00183 IRootIOSvc::InputStreamMap& ism = m_rioSvc->inputStreams();
00184 const IRootIOSvc::InputStreamMap::iterator finished = ism.end();
00185 for (IRootIOSvc::InputStreamMap::iterator it = ism.begin();
00186 finished != it;
00187 ++it) {
00188 log << MSG::DEBUG
00189 << "checking input stream: "
00190 << it->first << endreq;
00191 if( it->first == m_daqBlockLocation ){
00192 m_input = it->second;
00193 return StatusCode::SUCCESS;
00194 }
00195 }
00196 return StatusCode::FAILURE;
00197 }
00198
00199 StatusCode DybIODaqSvc::findConverter() {
00200 if (0 != m_daqBlockCnv) {
00201 return StatusCode::SUCCESS;
00202 }
00203 MsgStream log(msgSvc(),
00204 "DybIODaqSvc");
00205 IService* isvc = 0;
00206 StatusCode sc = service("RootIOCnvSvc",
00207 isvc,
00208 true);
00209 if(sc.isFailure()){
00210 log << MSG::ERROR
00211 << "Failed to get RootIOCnvSvc as IService"
00212 << endreq;
00213 return sc;
00214 }
00215 sc = isvc->queryInterface(IConversionSvc::interfaceID(),
00216 (void**)&m_convSvc);
00217 if (sc.isFailure()) {
00218 log << MSG::ERROR
00219 << "Conversion service RootIOCnvSvc"
00220 << " does not implement IConversionSvc"
00221 << endreq;
00222 return sc;
00223 }
00224
00225 DaqBlockHeader daqBlockHeader;
00226 IConverter* converter = m_convSvc->converter(daqBlockHeader.classID());
00227 if (0 == converter) {
00228 log << MSG::ERROR
00229 << "Failed to get DaqBlockHeader converter"
00230 << endreq;
00231 return StatusCode::FAILURE;
00232 }
00233 m_daqBlockCnv = dynamic_cast< RootIOTypedCnv<PerDaqBlockHeader, DaqBlockHeader>* >(converter);
00234 if (0 == m_daqBlockCnv) {
00235 log << MSG::ERROR
00236 << "Failed to cast DaqBlockHeader converter"
00237 << endreq;
00238 return StatusCode::FAILURE;
00239 }
00240 return StatusCode::SUCCESS;
00241 }
00242
00243 DaqBlockHeader* DybIODaqSvc::readDaqBlockHeader() {
00244 MsgStream log(msgSvc(),
00245 "DybIODaqSvc");
00246
00247 StatusCode sc = findInputStream();
00248 if (sc.isFailure()) {
00249 return 0;
00250 }
00251 sc = findConverter();
00252 if (sc.isFailure()) {
00253 return 0;
00254 }
00255
00256 m_input->setEntry(m_entry);
00257 log << MSG::DEBUG
00258 << "Return status of read: "
00259 << m_input->read()
00260 << "\t"
00261 << m_input->obj()
00262 << endreq;
00263 PerDaqBlockHeader* perDaqBlockHeader = (PerDaqBlockHeader*)(m_input->obj());
00264 if(0 == perDaqBlockHeader){
00265 log << MSG::ERROR
00266 << "Failed to get persistent DaqBlockHeader"
00267 << endreq;
00268 return 0;
00269 }
00270
00271 DaqBlockHeader* result = new DaqBlockHeader;
00272 sc = m_daqBlockCnv->PerToTran(*perDaqBlockHeader,
00273 *result);
00274 if (sc.isFailure()) {
00275 log << MSG::ERROR
00276 << "Failed to translate persistent DaqBlockHeader"
00277 << endreq;
00278 return 0;
00279 } else {
00280 ++m_entry;
00281 }
00282 return result;
00283 }