| # Gaudi Framework, version v23r1 |

Home |  | Generated: Wed Feb 29 2012

# RootEvtSelector.cpp

Go to the documentation of this file.

    00001 // $Id: RootEvtSelector.cpp,v 1.11 2010-09-27 15:43:53 frankb Exp $
    00002 //====================================================================
    00003 //      RootEvtSelector.cpp
    00004 //--------------------------------------------------------------------
    00005 //
    00006 //      Package    : RootCnv
    00007 //
    00008 //      Author     : M.Frank
    00009 //====================================================================
    00010 #ifndef GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
    00011 #define GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
    00012
    00013 // Include files
    00014 #include "RootCnv/RootEvtSelector.h"
    00015 #include <vector>
    00016
    00017 // Forward declarations
    00018 class TBranch;
    00019
    00020 /*
    00021 *  Gaudi namespace declaration
    00022 */
    00023 namespace Gaudi {
    00024
    00033   class RootEvtSelectorContext : public IEvtSelector::Context {
    00034   public:
    00036     typedef std::vector<std::string> Files;
    00037   private:
    00039     const RootEvtSelector*        m_sel;
    00041     Files                         m_files;
    00043     Files::const_iterator         m_fiter;
    00045     long                          m_entry;
    00047     TBranch*                      m_branch;
    00049     std::string                   m_fid;
    00050   public:
    00052     RootEvtSelectorContext(const RootEvtSelector* s) : m_sel(s),m_entry(-1),m_branch(0){}
    00054     virtual ~RootEvtSelectorContext()                {                        }
    00056     const Files& files() const                       { return m_files;        }
    00058     void setFiles(const Files& f)                    {
    00059       m_files = f;
    00060       m_fiter = m_files.begin();
    00061     }
    00063     virtual void* identifier() const                 { return (void*)m_sel;   }
    00065     Files::const_iterator fileIterator() const       { return m_fiter;        }
    00067     void setFileIterator(Files::const_iterator i)    { m_fiter = i;           }
    00069     long entry() const                               { return m_entry;        }
    00071     void setEntry(long e)                            { m_entry = e;           }
    00073     void setFID(const std::string& fid)              { m_fid = fid;           }
    00075     const std::string& fid() const                   { return m_fid;          }
    00077     TBranch* branch() const                          { return m_branch;       }
    00079     void setBranch(TBranch* b)                       { m_branch = b;          }
    00080   };
    00081 }
    00082 #endif // GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
    00083
    00084 // Include files
    00085 #include "GaudiKernel/ClassID.h"
    00086 #include "GaudiKernel/MsgStream.h"
    00087 #include "GaudiKernel/Tokenizer.h"
    00088 #include "GaudiKernel/TypeNameString.h"
    00089 #include "GaudiKernel/IDataManagerSvc.h"
    00090 #include "GaudiKernel/IPersistencySvc.h"
    00091 #include "GaudiKernel/ISvcLocator.h"
    00092 #include "RootCnv/RootCnvSvc.h"
    00093 #include "RootCnv/RootDataConnection.h"
    00094 #include "TBranch.h"
    00095
    00096 using namespace Gaudi;
    00097 using namespace std;
    00098
    00099 // Service Constructor
    00100 RootEvtSelector::RootEvtSelector(const string& name,ISvcLocator* svcloc)
    00101 : base_class(name, svcloc), m_rootCLID(CLID_NULL)
    00102 {
    00103   m_cnvSvcName = "Gaudi::RootCnvSvc/RootCnvSvc";
    00104   m_persName   = "EventPersistencySvc";
    00105   declareProperty("EvtPersistencySvc",m_persName="EventPersistencySvc");
    00106   declareProperty("DbType",m_dummy);
    00107 }
    00108
    00109 // Helper method to issue error messages
    00110 StatusCode RootEvtSelector::error(const string& msg) const   {
    00111   MsgStream log(msgSvc(), name());
    00112   log << MSG::ERROR << msg << endmsg;
    00113   return StatusCode::FAILURE;
    00114 }
    00115
    00116 // IService implementation: Db event selector override
    00117 StatusCode RootEvtSelector::initialize()    {
    00118   // Initialize base class
    00119   StatusCode status = Service::initialize();
    00120   if ( !status.isSuccess() ) {
    00121     return error("Error initializing base class Service!");
    00122   }
    00123
    00124   SmartIF<IPersistencySvc> ipers(serviceLocator()->service(m_persName));
    00125   if( !ipers.isValid() )   {
    00126     return error("Unable to locate IPersistencySvc interface of "+m_persName);
    00127   }
    00128   IConversionSvc *cnvSvc = 0;
    00129   Gaudi::Utils::TypeNameString itm(m_cnvSvcName);
    00130   status = ipers->getService(itm.name(),cnvSvc);
    00131   if( !status.isSuccess() )   {
    00132     status = ipers->getService(itm.type(),cnvSvc);
    00133     if( !status.isSuccess() )   {
    00134       return error("Unable to locate IConversionSvc interface of database type "+m_cnvSvcName);
    00135     }
    00136   }
    00137   m_dbMgr = dynamic_cast<RootCnvSvc*>(cnvSvc);
    00138   if( !m_dbMgr ) {
    00139     cnvSvc->release();
    00140     return error("Unable to localize service:"+m_cnvSvcName);
    00141   }
    00142   m_dbMgr->addRef();
    00143
    00144   // Get DataSvc
    00145   SmartIF<IDataManagerSvc> eds(serviceLocator()->service("EventDataSvc"));
    00146   if( !eds.isValid() ) {
    00147     return error("Unable to localize service EventDataSvc");
    00148   }
    00149   m_rootCLID = eds->rootCLID();
    00150   m_rootName = eds->rootName();
    00151   MsgStream log(msgSvc(), name());
    00152   log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
    00153   return status;
    00154 }
    00155
    00156 // IService implementation: Service finalization
    00157 StatusCode RootEvtSelector::finalize()    {
    00158   // Initialize base class
    00159   if ( m_dbMgr ) m_dbMgr->release();
    00160   m_dbMgr = 0; // release
    00161   return Service::finalize();
    00162 }
    00163
    00164 // Create a new event loop context
    00165 StatusCode RootEvtSelector::createContext(Context*& refpCtxt) const  {
    00166   refpCtxt = new RootEvtSelectorContext(this);
    00167   return StatusCode::SUCCESS;
    00168 }
    00169
    00170 // Access last item in the iteration
    00171 StatusCode RootEvtSelector::last(Context& /*refContext*/) const  {
    00172   return StatusCode::FAILURE;
    00173 }
    00174
    00175 // Get next iteration item from the event loop context
    00176 StatusCode RootEvtSelector::next(Context& ctxt) const  {
    00177   RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
    00178   if ( pCtxt ) {
    00179     TBranch* b = pCtxt->branch();
    00180     if ( !b ) {
    00181       RootEvtSelectorContext::Files::const_iterator fileit = pCtxt->fileIterator();
    00182       pCtxt->setBranch(0);
    00183       pCtxt->setEntry(-1);
    00184       if ( fileit != pCtxt->files().end() ) {
    00185         RootDataConnection* con=0;
    00186         string     in = *fileit;
    00187         StatusCode sc = m_dbMgr->connectDatabase(in,IDataConnection::READ,&con);
    00188         if ( sc.isSuccess() ) {
    00189           string section = m_rootName[0] == '/' ? m_rootName.substr(1) : m_rootName;
    00190           b = con->getBranch(section,m_rootName);
    00191           if ( b ) {
    00192             pCtxt->setFID(con->fid());
    00193             pCtxt->setBranch(b);
    00194             return next(ctxt);
    00195           }
    00196         }
    00197         m_dbMgr->disconnect(in).ignore();
    00198         pCtxt->setFileIterator(++fileit);
    00199         return next(ctxt);
    00200       }
    00201       return StatusCode::FAILURE;
    00202     }
    00203     long ent = pCtxt->entry();
    00204     Long64_t nent = b->GetEntries();
    00205     if ( nent > (ent+1) ) {
    00206       pCtxt->setEntry(++ent);
    00207       return StatusCode::SUCCESS;
    00208     }
    00209     RootEvtSelectorContext::Files::const_iterator fit = pCtxt->fileIterator();
    00210     pCtxt->setFileIterator(++fit);
    00211     pCtxt->setEntry(-1);
    00212     pCtxt->setBranch(0);
    00213     pCtxt->setFID("");
    00214     return next(ctxt);
    00215   }
    00216   return StatusCode::FAILURE;
    00217 }
    00218
    00219 // Get next iteration item from the event loop context
    00220 StatusCode RootEvtSelector::next(Context& ctxt,int jump) const  {
    00221   if ( jump > 0 ) {
    00222     for ( int i = 0; i < jump; ++i ) {
    00223       StatusCode status = next(ctxt);
    00224       if ( !status.isSuccess() ) {
    00225         return status;
    00226       }
    00227     }
    00228     return StatusCode::SUCCESS;
    00229   }
    00230   return StatusCode::FAILURE;
    00231 }
    00232
    00233 // Get previous iteration item from the event loop context
    00234 StatusCode RootEvtSelector::previous(Context& /* ctxt */) const   {
    00235   return error("EventSelector Iterator, operator -- not supported ");
    00236 }
    00237
    00238 // Get previous iteration item from the event loop context
    00239 StatusCode RootEvtSelector::previous(Context& ctxt, int jump) const  {
    00240   if ( jump > 0 ) {
    00241     for ( int i = 0; i < jump; ++i ) {
    00242       StatusCode status = previous(ctxt);
    00243       if ( !status.isSuccess() ) {
    00244         return status;
    00245       }
    00246     }
    00247     return StatusCode::SUCCESS;
    00248   }
    00249   return StatusCode::FAILURE;
    00250 }
    00251
    00252 // Rewind the dataset
    00253 StatusCode RootEvtSelector::rewind(Context& ctxt) const   {
    00254   RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
    00255   if ( pCtxt ) {
    00256     RootEvtSelectorContext::Files::const_iterator fileit = pCtxt->fileIterator();
    00257     if ( fileit != pCtxt->files().end() ) {
    00258       string input = *fileit;
    00259       m_dbMgr->disconnect(input).ignore();
    00260     }
    00261     pCtxt->setFID("");
    00262     pCtxt->setEntry(-1);
    00263     pCtxt->setBranch(0);
    00264     pCtxt->setFileIterator(pCtxt->files().begin());
    00265     return StatusCode::SUCCESS;
    00266   }
    00267   return StatusCode::FAILURE;
    00268 }
    00269
    00270 // Create new Opaque address corresponding to the current record
    00271 StatusCode
    00272 RootEvtSelector::createAddress(const Context& ctxt, IOpaqueAddress*& pAddr) const  {
    00273   const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>(&ctxt);
    00274   if ( pctxt ) {
    00275     long ent = pctxt->entry();
    00276     if ( ent >= 0 )  {
    00277       RootEvtSelectorContext::Files::const_iterator fileit = pctxt->fileIterator();
    00278       if ( fileit != pctxt->files().end() ) {
    00279         const string par[2] = {pctxt->fid(), m_rootName};
    00280         const unsigned long ipar[2] = {0,ent};
    00281         return m_dbMgr->createAddress(m_dbMgr->repSvcType(),m_rootCLID,&par[0],&ipar[0],pAddr);
    00282       }
    00283     }
    00284   }
    00285   pAddr = 0;
    00286   return StatusCode::FAILURE;
    00287 }
    00288
    00289 // Release existing event iteration context
    00290 StatusCode RootEvtSelector::releaseContext(Context*& ctxt) const   {
    00291   RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(ctxt);
    00292   if ( pCtxt ) {
    00293     delete pCtxt;
    00294     return StatusCode::SUCCESS;
    00295   }
    00296   return StatusCode::FAILURE;
    00297 }
    00298
    00299 // Will set a new criteria for the selection of the next list of events and will change
    00300 // the state of the context in a way to point to the new list.
    00301 StatusCode
    00302 RootEvtSelector::resetCriteria(const string& criteria, Context& context)  const
    00303 {
    00304   MsgStream log(msgSvc(), name());
    00305   RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>(&context);
    00306   string db, typ, item, sel, stmt, aut, addr;
    00307   if ( ctxt )  {
    00308     if ( criteria.substr(0,5) == "FILE " )  {
    00309       // The format for the criteria is:
    00310       //        FILE  filename1, filename2 ...
    00311       db = criteria.substr(5);
    00312     }
    00313     else  {
    00314       Tokenizer tok(true);
    00315       tok.analyse(criteria," ","","","=","'","'");
    00316       for(Tokenizer::Items::iterator i=tok.items().begin(); i!=tok.items().end();i++) {
    00317         string tmp = (*i).tag().substr(0,3);
    00318         if(tmp=="DAT")  {
    00319           db = (*i).value();
    00320         }
    00321         if(tmp=="OPT")   {
    00322           if((*i).value() != "REA")   {
    00323             log << MSG::ERROR << "Option:\"" << (*i).value() << "\" not valid" << endmsg;
    00324             return StatusCode::FAILURE;
    00325           }
    00326         }
    00327         if (tmp=="TYP") {
    00328           typ = (*i).value();
    00329         }
    00330         if(tmp=="ADD")  {
    00331           item = (*i).value();
    00332         }
    00333         if(tmp=="SEL")  {
    00334           sel = (*i).value();
    00335         }
    00336         if(tmp=="FUN")  {
    00337           stmt = (*i).value();
    00338         }
    00339         if(tmp=="AUT")  {
    00340           aut = (*i).value();
    00341         }
    00342         if(tmp=="COL")  {
    00343           addr = (*i).value();
    00344         }
    00345       }
    00346     }
    00347     // It's now time to parse the criteria for the event selection
    00348     // The format for the criteria is:
    00349     //        FILE  filename1, filename2 ...
    00350     //        JOBID number1-number2, number3, ...
    00351     RootEvtSelectorContext::Files files;
    00352     string rest = db;
    00353     files.clear();
    00354     while(true)  {
    00355       int ipos = rest.find_first_not_of(" ,");
    00356       if (ipos == -1 ) break;
    00357       rest = rest.substr(ipos,string::npos);// remove blanks before
    00358       int lpos  = rest.find_first_of(" ,");       // locate next blank
    00359       files.push_back(rest.substr(0,lpos )); // insert in list
    00360       if (lpos == -1 ) break;
    00361       rest = rest.substr(lpos,string::npos);// get the rest
    00362     }
    00363     ctxt->setFiles(files);
    00364     ctxt->setFileIterator(ctxt->files().begin());
    00365     return StatusCode::SUCCESS;
    00366   }
    00367   return error("Invalid iteration context.");
    00368 }

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines