00001 #include "DybInputLoadTool.h"
00002
00003 #include "RootIOSvc/IRootIOSvc.h"
00004 #include "RootIOSvc/RootIOAddress.h"
00005 #include "RootIOSvc/RootIOBaseCnv.h"
00006 #include "RootIOSvc/RootInputStream.h"
00007 #include "PerBaseEvent/PerHeaderObject.h"
00008 #include "PerBaseEvent/PerRegistrationSequence.h"
00009
00010 #include "GaudiKernel/MsgStream.h"
00011 #include "GaudiKernel/IConversionSvc.h"
00012 #include "GaudiKernel/DataObject.h"
00013
00014 #include <vector>
00015
00016 using namespace DayaBay;
00017
00018 DybInputLoadTool::DybInputLoadTool(const std::string& type,
00019 const std::string& name,
00020 const IInterface* parent)
00021 : GaudiTool(type,name,parent)
00022 , m_rioSvc(0)
00023 , m_convSvc(0)
00024 , m_cache_hos(false)
00025 {
00026 declareInterface<IDybInputLoadTool>(this);
00027 declareProperty("RootIOSvc",m_rioSvcName="RootIOCnvSvc",
00028 "Name of the IRootIOSvc to use");
00029 declareProperty("ConversionSvc",m_convSvcName="RootIOCnvSvc",
00030 "Name of the IConversionSvc to use");
00031 }
00032
00033 DybInputLoadTool::~DybInputLoadTool()
00034 {
00035 }
00036
00037 StatusCode DybInputLoadTool::queryInterface( const InterfaceID& riid, void** ppvIf )
00038 {
00039 if ( riid == IDybInputLoadTool::interfaceID() ) {
00040 *ppvIf = (IDybInputLoadTool*)this;
00041 addRef();
00042 return StatusCode::SUCCESS;
00043 }
00044 return AlgTool::queryInterface( riid, ppvIf );
00045 }
00046
00047
00048 StatusCode DybInputLoadTool::initialize()
00049 {
00050 MsgStream log(msgSvc(), "DybInputLoadTool");
00051 {
00052 IService* isvc = 0;
00053 StatusCode sc = this->service(m_rioSvcName,isvc,true);
00054 if(sc.isFailure()){
00055 log << MSG::ERROR << "Failed to get "<<m_rioSvcName<<" RootIOCnvSvc" << endreq;
00056 return sc;
00057 }
00058
00059 sc = isvc->queryInterface(IRootIOSvc::interfaceID(), (void**)&m_rioSvc);
00060 if (sc.isFailure()) {
00061 log << MSG::ERROR << "Service " << m_rioSvcName
00062 << " does not implement IRootIOSvc" << endreq;
00063 return sc;
00064 }
00065 }
00066
00067 {
00068 IService* isvc = 0;
00069 StatusCode sc = this->service(m_convSvcName,isvc,true);
00070 if(sc.isFailure()){
00071 log << MSG::ERROR << "Failed to get "<<m_convSvcName<<" ConversionSvc" << endreq;
00072 return sc;
00073 }
00074
00075 sc = isvc->queryInterface(IConversionSvc::interfaceID(), (void**)&m_convSvc);
00076 if (sc.isFailure()) {
00077 log << MSG::ERROR << "Service " << m_convSvcName
00078 << " does not implement IConversionSvc" << endreq;
00079 return sc;
00080 }
00081 }
00082 return StatusCode::SUCCESS;
00083 }
00084
00085 StatusCode DybInputLoadTool::finalize()
00086 {
00087 return StatusCode::SUCCESS;
00088 }
00089
00090 RootInputStream* DybInputLoadTool::get_stream(const std::string& path)
00091 {
00092 IRootIOSvc::InputStreamMap& ism = m_rioSvc->inputStreams();
00093 IRootIOSvc::InputStreamMap::iterator it = ism.find(path);
00094 if (it != ism.end()) {
00095 return it->second;
00096 }
00097 it = ism.find("default");
00098 if (it != ism.end()) {
00099 return it->second;
00100 }
00101 return 0;
00102 }
00103
00104
00105
00106
00107
00108
00109 template<class PerType>
00110 PerType* DybInputLoadTool::get_pobj(int entry, const std::string& path, int fileNumber)
00111 {
00112 MsgStream log(msgSvc(), "DybInputLoadTool");
00113
00114 RootInputStream* ris = this->get_stream(path);
00115 if (!ris) {
00116 log << MSG::ERROR << "Failed to get input stream for " << path << endreq;
00117 return 0;
00118 }
00119
00120 if (fileNumber == -1) {
00121 bool ok = ris->setEntry(entry);
00122 if (!ok) {
00123 log << MSG::ERROR << "Failed to setEntry(" << entry
00124 << ") with stream \"" << path << "\"" << endreq;
00125 return 0;
00126 }
00127 }
00128 else {
00129 bool ok = ris->setFileEntry(fileNumber,entry);
00130 if (!ok) {
00131 log << MSG::ERROR << "Failed to setFileEntry(" << fileNumber << "," << entry
00132 << ") with stream \"" << path << "\"" << endreq;
00133 return 0;
00134 }
00135 }
00136
00137 PerType* pto = dynamic_cast<PerType*>(ris->obj());
00138 if (!pto) {
00139 log << MSG::ERROR << "Cast failed for object at entry = " << entry
00140 << " in stream \"" << path << "\"" << endreq;
00141 return 0;
00142 }
00143
00144 return pto;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 DataObject* DybInputLoadTool::get_dataobject(int clID, const std::string& path)
00156 {
00157 MsgStream log(msgSvc(), "DybInputLoadTool");
00158
00159 IConverter* converter = m_convSvc->converter(clID);
00160 if (!converter) {
00161 log << MSG::ERROR << "Failed to get converter for class ID = " << clID
00162 << " in stream \"" << path << "\"" << endreq;
00163 return 0;
00164 }
00165
00166 RootIOBaseCnv* riocnv = dynamic_cast<RootIOBaseCnv*>(converter);
00167 if (!riocnv) {
00168 log << MSG::ERROR << "Converter not a RootIOBaseCnv for class ID = " << clID
00169 << " in stream \"" << path << "\"" << endreq;
00170 return 0;
00171 }
00172
00173 RootInputStream* ris = this->get_stream(path);
00174 if (!ris) {
00175 log << MSG::ERROR << "Failed to get input stream for " << path << endreq;
00176 return 0;
00177 }
00178
00179 RootInputAddress ria(clID,path);
00180 ria.setStream(ris);
00181 ria.readDone();
00182
00183
00184
00185
00186 DataObject* dobj = 0;
00187 StatusCode sc = riocnv->createObj(&ria,dobj);
00188 if (sc.isFailure()) {
00189 log << MSG::ERROR << "Failed to createObj for class ID = " << clID
00190 << " in stream \"" << path << "\"" << endreq;
00191 return 0;
00192 }
00193 return dobj;
00194 }
00195
00196 HeaderObject* DybInputLoadTool::get_header(int entry, const std::string& path,
00197 bool input_headers, int fileNumber)
00198 {
00199 MsgStream log(msgSvc(), "DybInputLoadTool");
00200
00201
00202 if (m_cache_hos) {
00203 HoID id(entry,path);
00204 HoCache::iterator it = m_hocache.find(id);
00205 if (it != m_hocache.end()) {
00206 return it->second;
00207 }
00208 }
00209
00210 PerHeaderObject* pho = this->get_pobj<PerHeaderObject>(entry,path,fileNumber);
00211 if (!pho) return 0;
00212
00213 log << MSG::DEBUG << "get_header("<<entry<<",\"" << path << "\","
00214 << " id=" << pho->clID
00215 << " w/ "
00216 << pho->inputHeaders.size()
00217 << " inputHeaders, " << input_headers<<",f#"<<fileNumber
00218 <<") -> ho @ " << pho->context.GetTimeStamp()
00219 <<endreq;
00220
00221 std::vector<PerRef> pinputHeaders = pho->inputHeaders;
00222 pho->inputHeaders.clear();
00223
00224 std::vector<const IHeader*> tinputHeaders;
00225 if (input_headers) {
00226
00227 if (fileNumber == -1) {
00228
00229 RootInputStream* ris = this->get_stream(path);
00230 fileNumber = ris->fileNumber();
00231 log << MSG::DEBUG << "get_header: using file number " << fileNumber << endreq;
00232 }
00233
00234 for (size_t ind=0; ind< pinputHeaders.size(); ++ind) {
00235 HeaderObject* ho = this->get_header(pinputHeaders[ind].entry(),
00236 pinputHeaders[ind].path(),
00237 input_headers, fileNumber);
00238 if (ho) tinputHeaders.push_back(ho);
00239 }
00240 }
00241 log << MSG::DEBUG << "get_header: restored " << tinputHeaders.size()
00242 << " inputHeaders out of a possible "
00243 << pinputHeaders.size() << endreq;
00244
00245 DataObject* dobj = this->get_dataobject(pho->clID, path);
00246 if (!dobj) return 0;
00247
00248 HeaderObject* ho = dynamic_cast<HeaderObject*>(dobj);
00249 if (input_headers) ho->setInputHeaders(tinputHeaders);
00250
00251 log << MSG::DEBUG << "get_header: got HO: id#" << ho->clID()
00252 << " \"" << ho->defLoc() << "\" @ " << ho->context().AsString()
00253 << endreq;
00254
00255
00256 if (m_cache_hos) {
00257 m_hocache[HoID(entry,path)] = ho;
00258 }
00259
00260 return ho;
00261 }
00262
00263
00264 IDybInputLoadTool::ExecutionFrame DybInputLoadTool::get_frame(int entry, const std::string& path,
00265 bool input_headers)
00266 {
00267 MsgStream log(msgSvc(), "DybInputLoadTool");
00268
00269 IDybInputLoadTool::ExecutionFrame ef;
00270
00271 PerRegistrationSequence* prs = this->get_pobj<PerRegistrationSequence>(entry,path);
00272 if (!prs) return ef;
00273
00274 m_cache_hos = true;
00275 m_hocache.clear();
00276 for (size_t ind=0; ind < prs->reglist.size(); ++ind) {
00277 RootInputStream* ris = this->get_stream(path);
00278 int fileNumber = ris->fileNumber();
00279
00280 HeaderObject* ho = this->get_header(prs->reglist[ind].entry,
00281 prs->reglist[ind].path,
00282 input_headers, fileNumber);
00283 if (!ho) {
00284 log << MSG::ERROR << "Failed to get Header object at entry "
00285 << prs->reglist[ind].entry << " and path " << prs->reglist[ind].path << endreq;
00286 continue;
00287 }
00288
00289 IDybInputLoadTool::ExecutionFrameEntry entry(prs->reglist[ind].path,ho);
00290 ef.push_back(entry);
00291 }
00292 m_cache_hos = false;
00293 m_hocache.clear();
00294 return ef;
00295 }
00296
00297 int DybInputLoadTool::get_entries(const std::string& path)
00298 {
00299 IRootIOSvc::InputStreamMap& ism = m_rioSvc->inputStreams();
00300 IRootIOSvc::InputStreamMap::iterator it = ism.find(path);
00301 if (it != ism.end()) {
00302 return it->second->entries();
00303 }
00304 return -1;
00305 }