/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

RootIOCnvSvc.cc
Go to the documentation of this file.
00001 #include "RootIOSvc/RootIOCnvSvc.h"
00002 #include "RootIOSvc/RootIOAddress.h"
00003 #include "RootIOSvc/RootIOBaseCnv.h"
00004 #include "RootOutputFileManager.h"
00005 
00006 #include "GaudiKernel/DataObject.h"
00007 #include "GaudiKernel/SmartIF.h"
00008 #include "GaudiKernel/IRegistry.h"
00009 #include "GaudiKernel/IDataProviderSvc.h"
00010 #include "GaudiKernel/IDataManagerSvc.h"
00011 #include "GaudiKernel/IIncidentSvc.h"
00012 #include "GaudiKernel/ISvcManager.h"
00013 #include "GaudiKernel/MsgStream.h"
00014 
00015 #include "Event/RegistrationSequence.h"
00016 
00017 using namespace std;
00018 
00019 RootIOCnvSvc::RootIOCnvSvc(const string& name, ISvcLocator* svc)
00020     : ConversionSvc(name,svc,ROOT_StorageType)
00021     , m_dataSvc(0)
00022 {
00023     declareProperty("OutputStreams",m_outputFileMap,
00024                     "Map of TES location to output filename");
00025     declareProperty("DefaultOutput",m_defaultOutputFilename="",
00026                     "Name of output file to store unregistered paths.");
00027 
00028     declareProperty("InputStreams",m_inputFileMap,
00029                     "Map of TES location to input filename");
00030     declareProperty("DefaultInput",m_defaultInputFilenames,
00031                     "Name of input file to store unregistered paths.");
00032 
00033     declareProperty("EventDataService",m_dataSvcName="EventDataSvc",
00034                     "Name of event data service.");
00035 
00036     declareProperty("MajorIndexExpression",m_majorIndex="execNumber",
00037                     "Expression to use for building the tree's index.");
00038     declareProperty("MinorIndexExpression",m_minorIndex="0",
00039                     "Expression to use for building the tree's index.");
00040 }
00041 RootIOCnvSvc::~RootIOCnvSvc()
00042 {
00043 }
00044 
00045 StatusCode RootIOCnvSvc::reinitialize()
00046 {
00047     MsgStream log(msgSvc(), "RootIOCnvSvc");
00048     log << MSG::DEBUG << "reinitializing @" << (void*)this << endreq;
00049     StatusCode sc = ConversionSvc::initialize();
00050     if (sc.isFailure()) {
00051         log << MSG::ERROR << "parent class failed to initialize" << endreq;
00052         return sc;
00053     }
00054     sc= this->doInitialize();
00055     log << MSG::DEBUG << "reinitialized @" << (void*)this << endreq;
00056     return sc;
00057 }
00058 StatusCode RootIOCnvSvc::initialize()
00059 {
00060     MsgStream log(msgSvc(), "RootIOCnvSvc");
00061     log << MSG::DEBUG << "initializing @" << (void*)this << endreq;
00062     StatusCode sc = ConversionSvc::initialize();
00063     if (sc.isFailure()) {
00064         log << MSG::ERROR << "parent class failed to initialize" << endreq;
00065         return sc;
00066     }
00067     sc= this->doInitialize();
00068     log << MSG::DEBUG << "initialized @" << (void*)this << endreq;
00069     return sc;
00070 }
00071 
00072 StatusCode RootIOCnvSvc::doInitialize()
00073 {
00074     MsgStream log(msgSvc(), "RootIOCnvSvc");
00075 
00076     if (0 == m_defaultInputFilenames.size()  && 0 == m_inputFileMap.size() &&
00077         "" == m_defaultOutputFilename && 0 == m_outputFileMap.size())
00078     {
00079         log << MSG::WARNING 
00080             << "No input nor output files specified.  Why am I here?"
00081             << endreq;
00082         return StatusCode::FAILURE;
00083     }
00084         
00085 
00086     // --- ouput --- //
00087     {                           
00088         map<string,string>::iterator it, done = m_outputFileMap.end();
00089         log << MSG::INFO 
00090             << " default output = \"" << m_defaultOutputFilename << "\""
00091             << " output file map (" << m_outputFileMap.size() << " entries):";
00092         for (it = m_outputFileMap.begin(); it != done; ++it) {
00093             log << "\n\t\"" << it->first << "\" ==> \"" << it->second << "\"";
00094         }
00095         log << endreq;
00096     }
00097     if (m_defaultOutputFilename.size()) { // if set, it should override "default" in map
00098         m_outputFileMap["default"] = m_defaultOutputFilename;
00099     }
00100     else { 
00101         map<string,string>::iterator it = m_outputFileMap.find("default");
00102         if (it == m_outputFileMap.end()) {
00103             log << MSG::WARNING 
00104                 << " no \"default\" output file name specified, "
00105                 "unregistered TES paths will not be saved." << endreq;
00106         }
00107         else {
00108             m_defaultOutputFilename = it->second;
00109         }
00110     }
00111     
00112     // If we have output, configure the output file manager
00113     if (m_outputFileMap.size()) {
00114         IIncidentSvc *incsvc = 0;
00115         StatusCode sc = service("IncidentSvc", incsvc, true);
00116         if(sc.isFailure()){
00117             log << MSG::ERROR << "Unable start IncidentSvc service" 
00118                 << endreq;
00119             return sc;
00120         }
00121         RootOutputFileManager::get().setIncidentSvc(incsvc);
00122 
00123         // make sure we get finalized before IncidentSvc does.
00124         // SmartIF<ISvcManager> mgr(IID_ISvcManager, serviceLocator());
00125         // int pri_inc = mgr->getPriority("IncidentSvc");
00126         // log << MSG::INFO << "Setting my priority to one more than IncidentSvc (" << pri_inc << ")" << endreq;
00127         // mgr->setPriority("RootIOCnvSvc",pri_inc + 1);
00128     }
00129 
00130 
00131     // --- input --- //
00132     {
00133         map<string,vector<string> >::iterator it, done = m_inputFileMap.end();
00134         string defin =  "";
00135         if (m_defaultInputFilenames.size()) defin = m_defaultInputFilenames[0];
00136         log << MSG::INFO
00137             << " default input = \"" << defin << "\""
00138             << " input file map (" << m_inputFileMap.size() << " entries):";
00139         for (it = m_inputFileMap.begin(); it != done; ++it) {
00140             log << "\t" << it->first << " : [";
00141             vector<string>& vec = it->second;
00142             for (size_t ind = 0; ind < vec.size(); ++ind) {
00143                 log << " " << vec[ind];
00144             }
00145             log << "]\n";
00146         }
00147         log << endreq;
00148     }
00149 
00150     if (0 == m_defaultInputFilenames.size()) {
00151         map<string,vector<string> >::iterator it = m_inputFileMap.find("default");
00152         if (it == m_inputFileMap.end()) {
00153             log << MSG::WARNING
00154                 << " no \"default\" input file name specified, "
00155                 "unregistered TES paths will not be saved." << endreq;
00156         }
00157         else {
00158             m_defaultInputFilenames = it->second;
00159         }
00160     }
00161     {
00162         map<string,vector<string> >::iterator it, done = m_inputFileMap.end();
00163         for (it = m_inputFileMap.begin(); it != done; ++it) {
00164             if (it->first == "default") continue;
00165             if (!it->second.size()) {
00166                 log << MSG::WARNING
00167                     << "Skipping input stream with no files: "
00168                     << it->first << endreq;
00169                 continue;
00170             }
00171             initializeInputStream(it->first,it->second);
00172         }
00173         if (m_defaultInputFilenames.size())
00174             initializeInputStream("default",m_defaultInputFilenames);
00175     }
00176     
00177     log << MSG::DEBUG << "Initialized input and output streams." << endreq;
00178 
00179     // Get DataSvc
00180     log << MSG::DEBUG << "Getting " << m_dataSvcName << " as IService" << endreq;
00181     IService* isvc = 0;
00182     StatusCode sc = service(m_dataSvcName, isvc, true);
00183     if(sc.isFailure()){
00184         log << MSG::ERROR << "Unable start EventData service" 
00185             << m_dataSvcName << endreq;
00186         return sc;
00187     }
00188     isvc->addRef();
00189 
00190     log << MSG::DEBUG << "Querying " << m_dataSvcName << " for IID_IDataProviderSvc" << endreq;
00191     sc = isvc->queryInterface(IID_IDataProviderSvc, (void**)&m_dataSvc);
00192     if(sc.isFailure()){
00193         log << MSG::ERROR << "EventData service " << m_dataSvcName 
00194             << "not an IDataProviderSvc" << endreq;
00195         return sc;
00196     }
00197 
00198     log << MSG::DEBUG << "Querying " << m_dataSvcName << " for IID_IDataManagerSvc" << endreq;
00199     sc = isvc->queryInterface(IDataManagerSvc::interfaceID(),
00200                               (void**)(&m_dataMgr));
00201     if (sc.isFailure()) {
00202         log << MSG::ERROR << "EventData service " << m_dataSvcName 
00203             << "not an IDataManagerSvc" << endreq;
00204         return sc;
00205     }
00206 
00207     return StatusCode::SUCCESS;
00208 }
00209 
00210 void RootIOCnvSvc::initializeInputStream(const string& path, 
00211                                          const string& filename)
00212 {
00213     vector<string> vec;
00214     vec.push_back(filename);
00215     this->initializeInputStream(path,vec);
00216 }
00217 
00218 void RootIOCnvSvc::initializeInputStream(const string& path, 
00219                                          const vector<string>& filenames)
00220 {
00221     MsgStream log(msgSvc(), "RootIOCnvSvc");
00222 
00223     // If "default" root through all paths in the file and register them.
00224     if (path == "default") {
00225         // Use the first filename to find all TES paths it represents.
00226         // This could be a problem if a series of files get written
00227         // and a particular path doesn't show up until after the first
00228         // file.....
00229         vector<string> tespaths = RootInputFile::TreePaths(filenames[0]);
00230 
00231         if (!tespaths.size()) {
00232             log << MSG::WARNING 
00233                 << "initializeInputStream found no Trees in " << filenames[0]
00234                 << endreq;
00235             return;
00236         }
00237         for (size_t ind=0; ind<tespaths.size(); ++ind) {
00238             log << MSG::DEBUG << "found " << tespaths[ind] << " in file " 
00239                 << filenames[0] << endreq;
00240             initializeInputStream(tespaths[ind],filenames);
00241         }
00242         return;
00243     }
00244 
00245     map<string,RootInputStream*>::iterator it = m_inputStreamMap.find(path);
00246     if (it != m_inputStreamMap.end()) {
00247         log << MSG::WARNING << "path " 
00248             << path << " already has an input stream so not reinitializing file " 
00249             << filenames[0] << ", ..." << endreq;
00250         return;
00251     }
00252     
00253     // Sanity check
00254     string branchname = RootIO::branchname(path);
00255     int clid = RootInputFile::TestForObject(filenames[0],path,branchname);
00256     if (!clid) {
00257         log << MSG::WARNING << "failed to get nonzero class id from path "
00258             << path << ", branch " << branchname << " in file " << filenames[0] << endreq;
00259         return;
00260     }
00261     
00262     RootInputAddress ria(clid,path);
00263     
00264     RootInputStream* ris = this->inputStream(ria);
00265     if (!ris) {
00266         log << MSG::WARNING << "failed to get input stream for " << path
00267             << " in " << filenames[0] << endreq;
00268         return;
00269     }
00270     
00271     m_inputStreamMap[path] = ris;
00272     log << MSG::DEBUG << "retrieving " << path 
00273         << " from " << filenames[0] << endreq;
00274     return;
00275 }
00276 
00277 
00278 void RootIOCnvSvc::associateOutput(const char* filename, const char* streamname)
00279 {
00280     m_outputFileMap[streamname] = filename;
00281     if (string("default") == streamname) {
00282         m_defaultOutputFilename = filename;
00283     }
00284 }
00285 IRootIOSvc::FileMap RootIOCnvSvc::fileMap()
00286 {
00287     return m_outputFileMap;
00288 }
00289 
00290 RootOutputStream* RootIOCnvSvc::outputStream(const RootOutputAddress& roa)
00291 {
00292     MsgStream log(msgSvc(), "RootIOCnvSvc");
00293 
00294     const string& filename = this->outputFilename(roa.tespath());
00295     if ("" == filename) {
00296         log << MSG::ERROR << "Bad (empty) output filename, no ouput stream for " 
00297             << roa.tespath() << endreq;
00298         return 0;
00299     }
00300 
00301     RootOutputStream* os = m_outputStreamMap[roa.tespath()];
00302     if (os) {
00303         os->newFile(filename); // noop unless filename differs from old one
00304         log << MSG::DEBUG << "outputStream for " << roa.tespath() 
00305             << " cached, file = " << filename << endreq;
00306         return os;
00307     }
00308 
00309     IConverter*  cnv  = converter(roa.clID());
00310     if (!cnv) {
00311         log << MSG::WARNING
00312             << "Failed to get converter for class ID = " << roa.clID()
00313             << " tespath = " << roa.tespath() << endreq;
00314         return 0;
00315     }
00316 
00317     RootIOBaseCnv* riocnv = dynamic_cast<RootIOBaseCnv*>(cnv);
00318     if (!riocnv) {
00319         log << MSG::WARNING 
00320             << "Converter not a RootIOBaseCnv for class ID = " << roa.clID()
00321             << " tespath = " << roa.tespath() << endreq;
00322         return 0;
00323     }
00324 
00325     os = riocnv->makeOutputStream(roa);
00326     if (!os) {
00327         log << MSG::WARNING
00328             << "Converter failed to make new output stream for class ID = " 
00329             << roa.clID()
00330             << " tespath = " << roa.tespath() << endreq;
00331         return 0;
00332     }
00333 
00334     if (roa.clID() != DayaBay::RegistrationSequence::classID()) {
00335         log << MSG::DEBUG
00336             << "outputStream for " << roa.tespath() 
00337             << " gets major=\"" << m_majorIndex << "\", "
00338             << "minor=\"" << m_minorIndex << "\"" << endreq;
00339         os->setIndexExpression(m_majorIndex,m_minorIndex);
00340     }
00341 
00342     m_outputStreamMap[roa.tespath()] = os;
00343     os->newFile(filename);
00344     log << MSG::DEBUG << "outputStream for " << roa.tespath() 
00345         << " new, file = " << filename << endreq;
00346     return os;
00347 }
00348 
00349 RootInputStream* RootIOCnvSvc::inputStream(const RootInputAddress& ria)
00350 {
00351     MsgStream log(msgSvc(), "RootIOCnvSvc");
00352 
00353     vector<string> filenames = this->inputFilenames(ria.tespath());
00354     if (0 == filenames.size()) {
00355         log << MSG::DEBUG << "Bad (empty) input filename, no input stream for " 
00356             << ria.tespath() << endreq;
00357         return 0;
00358     }
00359 
00360     RootInputStream* ris = m_inputStreamMap[ria.tespath()];
00361     if (ris) {
00362         log << MSG::DEBUG << "inputStream for " << ria.tespath()
00363             << " cached, files = [";
00364         for (size_t ind=0; ind<filenames.size(); ++ind) {
00365             log << " " << filenames[ind];
00366         }
00367         log << "]" << endreq;
00368         return ris;
00369     }
00370 
00371     IConverter*  cnv  = converter(ria.clID());
00372     if (!cnv) {
00373         log << MSG::WARNING
00374             << "Failed to get converter for class ID = " << ria.clID()
00375             << " tespath = " << ria.tespath() << endreq;
00376         return 0;
00377     }
00378 
00379     RootIOBaseCnv* riocnv = dynamic_cast<RootIOBaseCnv*>(cnv);
00380     if (!riocnv) {
00381         log << MSG::WARNING 
00382             << "Converter not a RootIOBaseCnv for class ID = " << ria.clID()
00383             << " tespath = " << ria.tespath() << endreq;
00384         return 0;
00385     }
00386 
00387     ris = riocnv->makeInputStream(ria);
00388     if (!ris) {
00389         log << MSG::WARNING
00390             << "Converter failed to make new input stream for class ID = " 
00391             << ria.clID()
00392             << " tespath = " << ria.tespath() << endreq;
00393         return 0;
00394     }
00395 
00396     for (size_t ind = 0; ind < filenames.size(); ++ind) {
00397         bool okay = ris->append(filenames[ind], true);
00398         if (!okay) {
00399             log << MSG::ERROR
00400                 << "failed to append file " << filenames[ind] << " to input stream for " 
00401                 << ria.tespath() << endreq;
00402             return 0;
00403         }
00404     }
00405 
00406     m_inputStreamMap[ria.tespath()] = ris;
00407 
00408     log << MSG::DEBUG << "inputStream for " << ria.tespath() 
00409         << " new, files = [";
00410     for (size_t ind=0; ind<filenames.size(); ++ind) {
00411         log << " " << filenames[ind];
00412     }
00413     log << "]" << endreq;
00414 
00415     return ris;    
00416 }
00417 
00418 const string& RootIOCnvSvc::outputFilename(const string& tespath)
00419 {
00420     map<string,string>::iterator it = m_outputFileMap.find(tespath);
00421     if (it == m_outputFileMap.end()) return m_defaultOutputFilename;
00422     return it->second;
00423 }
00424 
00425 vector<string> RootIOCnvSvc::inputFilenames(const string& tespath)
00426 {
00427     map<string,vector<string> >::iterator it = m_inputFileMap.find(tespath);
00428     if (it == m_inputFileMap.end()) {
00429         return m_defaultInputFilenames;
00430     }
00431     return it->second;
00432 }
00433 
00434 StatusCode RootIOCnvSvc::createAddress(long svc_type,
00435                                        const CLID& clid,
00436                                        const string* par, 
00437                                        const unsigned long* ip,
00438                                        IOpaqueAddress*& refpAddress)
00439 {
00440     MsgStream log(msgSvc(), "RootIOCnvSvc");
00441     log << MSG::ERROR << "generic createAddress("
00442         << svc_type << ", " << clid 
00443         << ",[" << par[0] << "," << par[1] << "], " << ip[0] << ")"
00444         << " unimplemented"
00445         << endreq;
00446     //refpAddress = new RootIOAddress(svc_type,clid,par[0],par[1],ip[0]);
00447     refpAddress = 0;
00448     return StatusCode::FAILURE;
00449 }
00450 
00451 
00452 StatusCode RootIOCnvSvc::createAddress(DataObject* obj, RootOutputAddress*& newAddr)
00453 {
00454     // wangzhe: There is no ObjectReg created for RegistrationSequence
00455     // So there is no ganrantee there is Registry alive for each RegistrationSequence
00456     string tespath;
00457     if(obj->clID()==DayaBay::RegistrationSequence::classID()) {
00458       tespath=DayaBay::RegistrationSequence::defaultLocation();
00459     } else {
00460       tespath = obj->registry()->identifier();
00461     }
00462     // wz
00463 
00464     string filename = m_defaultOutputFilename;
00465     map<string,string>::iterator it = m_outputFileMap.find(tespath);
00466     if (it != m_outputFileMap.end()) 
00467         filename = it->second;
00468 
00469     if ("" == filename) {
00470         MsgStream log(msgSvc(), "RootIOCnvSvc");
00471         static map<string,int> errorMap;
00472         if (!errorMap[tespath]) {
00473             log << MSG::WARNING
00474                 << "Can not create address for " << tespath
00475                 << " no output file specified, I won't tell you again." 
00476                 << endreq;
00477             errorMap[tespath] = 1;
00478         }
00479         return StatusCode::FAILURE;
00480     }
00481 
00482     newAddr = new RootOutputAddress(obj->clID(),tespath);
00483     return StatusCode::SUCCESS;
00484 }
00485 
00486 
00487 StatusCode RootIOCnvSvc::finalize()
00488 {
00489     map<string,RootOutputStream*>::iterator it, done = m_outputStreamMap.end();
00490     for (it = m_outputStreamMap.begin(); it != done; ++it) {
00491         bool okay = it->second->close();
00492         if (!okay) {
00493             MsgStream log(msgSvc(), "RootIOCnvSvc");
00494             log << MSG::WARNING
00495                 << "error in closing file for " << it->first
00496                 << endreq;
00497         }            
00498     }
00499     if (m_outputStreamMap.size()) {
00500         RootOutputFileManager::get().setIncidentSvc(0); // trigger a release
00501     }
00502     return ConversionSvc::finalize();
00503 }
00504 
00505 StatusCode RootIOCnvSvc::queryInterface(const InterfaceID& riid, void** ppint)
00506 {
00507     MsgStream log(msgSvc(), "RootIOCnvSvc");
00508 
00509     if (IID_IRootIOSvc.versionMatch(riid)) {
00510         log << MSG::DEBUG << "queryInterface("<<riid<<") --> (IRootIOSvc*)" 
00511             << (void*)this
00512             << endreq;
00513         *ppint = (IRootIOSvc*)this;
00514     }
00515     else if (IID_IConversionSvc.versionMatch(riid)) {
00516         log << MSG::DEBUG << "queryInterface("<<riid<<") --> (IConversionSvc*)"
00517             << (void*)this
00518             << endreq;        
00519         *ppint = (IConversionSvc*)this;
00520     }
00521     else {
00522         return this->ConversionSvc::queryInterface(riid,ppint);
00523     }
00524     addRef();
00525     return StatusCode::SUCCESS;
00526 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Fri May 16 2014 09:58:18 for RootIOSvc by doxygen 1.7.4