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

Generated on Mon Apr 11 20:18:19 2011 for RootIOSvc by doxygen 1.4.7