Gaudi Framework, version v20r4

Generated: 8 Jan 2009

EventCollectionSelector.cpp

Go to the documentation of this file.
00001 //$Id: EventCollectionSelector.cpp,v 1.16 2007/01/09 16:54:47 hmd Exp $
00002 
00003 // Include files
00004 #include "GaudiKernel/SmartIF.h"
00005 #include "GaudiKernel/SvcFactory.h"
00006 #include "GaudiKernel/ObjectFactory.h"
00007 #include "GaudiKernel/GenericAddress.h"
00008 #include "GaudiKernel/MsgStream.h"
00009 #include "GaudiKernel/IRegistry.h"
00010 #include "GaudiKernel/INTupleSvc.h"
00011 #include "GaudiKernel/ISvcLocator.h"
00012 #include "GaudiKernel/IDataSourceMgr.h"
00013 #include "GaudiKernel/IAddressCreator.h"
00014 #include "GaudiKernel/ISelectStatement.h"
00015 #include "GaudiKernel/NTuple.h"
00016 #include "GaudiKernel/EventSelectorDataStream.h"
00017 
00018 #include "EventCollectionSelector.h"
00019 
00020 #include <memory>
00021 
00022 DECLARE_SERVICE_FACTORY(EventCollectionSelector)
00023 
00024 
00029 class EventCollectionContext : public IEvtSelector::Context {
00030 public:
00031   typedef std::list<std::string> ListName;
00032 private:
00033   GenericAddress*                m_pAddressBuffer;
00034   const EventCollectionSelector* m_pSelector;
00035   ListName                      m_files;
00036   std::string                   m_criteria;
00037   ListName::const_iterator      m_fileIterator;
00038   std::string                   m_currentInput;
00039 
00040 public:
00042   EventCollectionContext(const EventCollectionSelector* pSelector);
00044   virtual ~EventCollectionContext();
00045   const std::string& currentInput() const {
00046     return m_currentInput;
00047   }
00048   void setCurrentInput(const std::string& v) {
00049     m_currentInput = v;
00050   }
00051   ListName& files() {
00052     return m_files;
00053   }
00054   virtual void* identifier() const {
00055     return (void*)m_pSelector;
00056   }
00057   void setCriteria(const std::string& crit) {
00058     m_criteria = crit;
00059   }
00060   ListName::const_iterator fileIterator()        {
00061     return m_fileIterator;
00062   }
00063   void setFileIterator(ListName::const_iterator new_iter)
00064   {  m_fileIterator = new_iter;   }
00065 };
00066 
00067 EventCollectionContext::~EventCollectionContext() {
00068   m_pAddressBuffer->release();
00069 }
00070 
00071 EventCollectionContext::EventCollectionContext(const EventCollectionSelector* pSelector)
00072   : m_pSelector(pSelector)
00073 {
00074   m_pAddressBuffer = new GenericAddress();
00075   m_pAddressBuffer->addRef();
00076 }
00077 
00078 // Standard constructor
00079 EventCollectionSelector::EventCollectionSelector(const std::string& name, ISvcLocator* svcloc ) 
00080   : Service( name, svcloc), m_tupleSvc(0)
00081 {
00082   m_pAddrCreator = 0;
00083   declareProperty("CnvService",    m_tupleSvcName = "EvtTupleSvc");
00084   declareProperty("Authentication",m_authentication= "");
00085   declareProperty("Container",     m_cntName  = "B2PiPi");
00086   declareProperty("Item",          m_itemName = "Address");
00087   declareProperty("Criteria",      m_criteria = "");
00088   declareProperty("DB",            m_database = "");
00089   declareProperty("DbType",        m_dbType   = "");
00090   declareProperty("Function",      m_statement= "NTuple::Selector");
00091 }
00092 
00093 EventCollectionSelector::~EventCollectionSelector()   {
00094 }
00095 
00096 // IService implementation: Db event selector override
00097 StatusCode EventCollectionSelector::initialize()    {
00098   // Initialize base class
00099   StatusCode status = Service::initialize();
00100   MsgStream log(messageService(), name());
00101   if ( !status.isSuccess() )    {
00102     log << MSG::ERROR << "Error initializing base class Service!" << endreq;
00103     return status;
00104   }
00105   status = serviceLocator()->service("EventPersistencySvc", m_pAddrCreator, true );
00106   if( !status.isSuccess() )   {
00107     log << MSG::ERROR << "Unable to locate IAddressCreator interface of " << "EventPersistencySvc" << endreq;
00108     return status;
00109   }
00110   status = serviceLocator()->service(m_tupleSvcName, m_tupleSvc, true );
00111   if( !status.isSuccess() )   {
00112     log << MSG::ERROR << "Unable to locate INTupleSvc interface of " << m_tupleSvcName << endreq;
00113     return status;
00114   }
00115   return status;
00116 }
00117 
00118 // Connect collection to selector
00119 StatusCode 
00120 EventCollectionSelector::connectDataSource(const std::string& db, const std::string& /* typ */ )  const {
00121   StatusCode status = StatusCode::FAILURE;
00122   SmartIF<IDataSourceMgr> svc(IID_IDataSourceMgr, m_tupleSvc);
00123   if ( svc.isValid( ) && db.length() > 0 )   {
00124     std::string ident = name() + ' ';
00125     ident += "DATAFILE='" + m_database.substr(5,m_database.length()) + "' ";
00126     ident += "TYP='" + m_dbType + "' ";
00127     ident += "OPT='READ' ";
00128     if ( m_authentication.length() > 0 )    {
00129       ident += "AUTH='" + m_authentication + "' ";
00130     }
00131     status = svc->connect(ident);
00132   }
00133   return status;
00134 }
00135 
00137 StatusCode 
00138 EventCollectionSelector::connectTuple(const std::string& nam, const std::string& itName, NTuple::Tuple*& tup, NTuple::Item<IOpaqueAddress*>*& item)  const {
00139   std::string top = "/NTUPLES/" + name() + '/' + nam;
00140   StatusCode status = m_tupleSvc->retrieveObject(top, (DataObject*&)tup);
00141   if ( status.isSuccess() )    {
00142     item = new NTuple::Item<IOpaqueAddress*>();
00143     status = tup->item(itName, *item);
00144     if ( status.isSuccess() )   {
00145       return status;
00146     }
00147     else    {
00148       MsgStream log(msgSvc(), name());
00149       log << MSG::ERROR << "Item " << itName << " is not part of the collection:" << top << endreq;
00150     }
00151     delete item;
00152     item = 0;
00153   }
00154   else  {
00155     MsgStream err(msgSvc(), name());
00156     err << MSG::ERROR << "Cannot connect to collection:" << top << endreq;
00157   }
00158   tup = 0;
00159   return status;
00160 }
00161 
00163 StatusCode 
00164 EventCollectionSelector::connectStatement(const std::string& typ, const std::string& crit, INTuple* tuple)  const {
00165   std::string seltyp = typ;
00166   if ( seltyp.length() > 0 || crit.length() > 0 )   {
00167     if ( crit.length() > 0 && seltyp.length() == 0 ) seltyp = "NTuple::Selector";
00168     SmartIF<ISelectStatement> stmt(IID_ISelectStatement, 
00169       ROOT::Reflex::PluginService::Create<IInterface*>(seltyp, (IInterface*)serviceLocator()));
00170     if ( stmt.isValid( ) )    {
00171       if ( crit.length() > 0 ) stmt->setCriteria(crit);
00172       tuple->attachSelector(stmt).ignore();
00173       return StatusCode::SUCCESS;
00174     }
00175     return StatusCode::FAILURE;
00176   }
00177   return StatusCode::SUCCESS;
00178 }
00179 
00181 StatusCode EventCollectionSelector::getNextRecord(NTuple::Tuple* tuple)   const {
00182   StatusCode status = StatusCode::FAILURE;
00183   if ( 0 != tuple )   {
00184     do {
00185       status = m_tupleSvc->readRecord(tuple);
00186       if ( status.isSuccess() )   {
00187         ISelectStatement* statement = tuple->selector();
00188         bool use_it = (statement) ? (*statement)(tuple) : true;
00189         if ( use_it )   {
00190           return status;
00191         }
00192       }
00193     } while ( status.isSuccess() );
00194   }
00195   return status;
00196 }
00197 
00199 StatusCode EventCollectionSelector::getPreviousRecord(NTuple::Tuple* tuple )  const  {
00200   StatusCode status = StatusCode::FAILURE;
00201   if ( tuple )  {
00202     IRegistry* pReg = tuple->registry();
00203     if ( pReg )  {
00204       IOpaqueAddress* pAddr = pReg->address();
00205       if ( pAddr )  {
00206         long* ip = (long*)pAddr->ipar();
00207         do {
00208           if ( ip[1] > 1 )  {
00209             ip[1] -= 2;
00210             status = m_tupleSvc->readRecord(tuple);
00211             if ( status.isSuccess() )   {
00212               ISelectStatement* statement = tuple->selector();
00213               bool use_it = (statement) ? (*statement)(tuple) : true;
00214               if ( use_it )   {
00215                 return status;
00216               }
00217             }
00218           }
00219           else  {
00220             return StatusCode::FAILURE;
00221           }
00222         } while ( status.isSuccess() );
00223       }
00224     }
00225   }
00226   return StatusCode::FAILURE;
00227 }
00228 
00229 // Connect collection to selector
00230 StatusCode EventCollectionSelector::connectCollection(MyContextType* ctxt) const  
00231 {
00232   if ( ctxt )  {
00233     StatusCode status = connectDataSource(m_database, m_dbType);
00234     if ( status.isSuccess() )   {
00235       status = connectTuple(m_cntName, m_itemName, ctxt->tuple, ctxt->item);
00236       if ( status.isSuccess() )   {
00237         status = connectStatement(m_statement, m_criteria, ctxt->tuple);
00238         if ( status.isSuccess() )   {
00239           *(ctxt->item) = 0;
00240           return status;
00241         }
00242       }
00243     }
00244     return status;
00245   }
00246   return StatusCode::FAILURE;
00247 }
00248 
00249 // Finalize service
00250 StatusCode EventCollectionSelector::finalize()    {
00251   if ( m_pAddrCreator )  {
00252     m_pAddrCreator->release();
00253     m_pAddrCreator = 0;
00254   }
00255   if ( m_tupleSvc )  {
00256     m_tupleSvc->release();
00257     m_tupleSvc = 0;
00258   }
00259   return Service::finalize();
00260 }
00261 
00263 StatusCode 
00264 EventCollectionSelector::createContext(Context*& refpCtxt) const
00265 {
00266   refpCtxt = 0;
00267   std::auto_ptr<MyContextType> ctxt(new MyContextType());
00268   StatusCode status = connectCollection(ctxt.get());
00269   if( !status.isSuccess() )  {
00270     MsgStream log(msgSvc(), name());
00271     log << MSG::ERROR << "Unable to connect Collection file \"" << m_database << "\"" << endreq;
00272     return status;
00273   }
00274   refpCtxt = ctxt.release();
00275   return StatusCode::SUCCESS;
00276 }
00277 
00279 StatusCode 
00280 EventCollectionSelector::next(Context& refCtxt) const
00281 {
00282   return next(refCtxt, 1);
00283 }
00284 
00286 StatusCode 
00287 EventCollectionSelector::next(Context& refCtxt,int jump) const
00288 {
00289   MyContextType *ctxt  = dynamic_cast<MyContextType*>(&refCtxt);
00290   if ( ctxt )    {
00291     *(ctxt->item) = ctxt->addressBuffer;
00292     StatusCode sc = StatusCode::SUCCESS;
00293     for ( int i=0; i<jump && sc.isSuccess(); ++i ) {
00294       sc = getNextRecord(ctxt->tuple);
00295     }
00296     return sc;
00297   }
00298   return StatusCode::FAILURE;
00299 }
00300 
00302 StatusCode 
00303 EventCollectionSelector::previous(Context& refCtxt) const
00304 {
00305   return previous(refCtxt, 1);
00306 }
00307 
00309 StatusCode 
00310 EventCollectionSelector::previous(Context& refCtxt,int jump) const
00311 {
00312   MyContextType *ctxt  = dynamic_cast<MyContextType*>(&refCtxt);
00313   if ( ctxt )    {
00314     *(ctxt->item) = ctxt->addressBuffer;
00315     StatusCode sc = StatusCode::SUCCESS;
00316     for ( int i=0; i<jump && sc.isSuccess(); ++i ) {
00317       sc = getPreviousRecord(ctxt->tuple);
00318     }
00319     return sc;
00320   }
00321   return StatusCode::FAILURE;
00322 }
00323 
00325 StatusCode 
00326 EventCollectionSelector::rewind(Context& /* refCtxt */ ) const
00327 {
00328   return StatusCode::FAILURE;
00329 }
00330 
00332 StatusCode 
00333 EventCollectionSelector::createAddress(const Context& refCtxt, IOpaqueAddress*& refpAddr) const
00334 {
00335   const MyContextType* ctxt = dynamic_cast<const MyContextType*>(&refCtxt);
00336   if ( ctxt )   {
00337     IOpaqueAddress* pA = *(ctxt->item);
00338     if ( pA )  {
00339       IOpaqueAddress* pAddress = 0;
00340       StatusCode status = m_pAddrCreator->createAddress(pA->svcType(), 
00341                                                         pA->clID(),
00342                                                         pA->par(),
00343                                                         pA->ipar(),
00344                                                         pAddress);
00345       if ( status.isSuccess() )   {
00346         refpAddr = pAddress;
00347         return StatusCode::SUCCESS;
00348       }
00349       else    {
00350         MsgStream log(msgSvc(), name());
00351         log << MSG::ERROR << "Failed to access " << pA->par()[0] 
00352             << ":" << pA->par()[1]
00353             << " SvcTyp:" << long(pA->svcType()) 
00354             << " CLID:"   << pA->clID()
00355             << endreq;
00356       }
00357     }
00358   }
00359   return StatusCode::FAILURE;
00360 }
00361 
00363 StatusCode 
00364 EventCollectionSelector::releaseContext(Context*& refCtxt) const
00365 {
00366   MyContextType *ctxt  = dynamic_cast<MyContextType*>(refCtxt);
00367   if ( ctxt )   {
00368     delete ctxt;
00369     ctxt = 0;
00370     return StatusCode::SUCCESS;
00371   }
00372   return StatusCode::FAILURE;
00373 }
00374 
00377 StatusCode 
00378 EventCollectionSelector::resetCriteria(const std::string& cr,Context& refCtxt) const
00379 {
00380   MyContextType *ctxt  = dynamic_cast<MyContextType*>(&refCtxt);
00381   if ( ctxt )   {
00382     ctxt->criteria = cr;
00383     return StatusCode::SUCCESS;
00384   }
00385   return StatusCode::FAILURE;
00386 }
00387 
00389 StatusCode 
00390 EventCollectionSelector::last(Context& /* refCtxt */ ) const
00391 {
00392   return StatusCode::FAILURE;
00393 }
00394 
00395 // Service override: queryInterface
00396 StatusCode EventCollectionSelector::queryInterface(const InterfaceID& riid, void** ppvInterface)  {
00397   if ( riid == IID_IEvtSelector )  {
00398     *ppvInterface = (IEvtSelector*)this;
00399     addRef();
00400     return SUCCESS;
00401   }
00402   return Service::queryInterface( riid, ppvInterface );
00403 }
00404 

Generated at Thu Jan 8 17:44:23 2009 for Gaudi Framework, version v20r4 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004