00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
00011 #define GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
00012
00013
00014 #include "RootCnv/RootEvtSelector.h"
00015 #include <vector>
00016
00017
00018 class TBranch;
00019
00020
00021
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
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
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
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
00117 StatusCode RootEvtSelector::initialize() {
00118
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
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
00157 StatusCode RootEvtSelector::finalize() {
00158
00159 if ( m_dbMgr ) m_dbMgr->release();
00160 m_dbMgr = 0;
00161 return Service::finalize();
00162 }
00163
00164
00165 StatusCode RootEvtSelector::createContext(Context*& refpCtxt) const {
00166 refpCtxt = new RootEvtSelectorContext(this);
00167 return StatusCode::SUCCESS;
00168 }
00169
00170
00171 StatusCode RootEvtSelector::last(Context& ) const {
00172 return StatusCode::FAILURE;
00173 }
00174
00175
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
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
00234 StatusCode RootEvtSelector::previous(Context& ) const {
00235 return error("EventSelector Iterator, operator -- not supported ");
00236 }
00237
00238
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
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
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
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
00300
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
00310
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
00348
00349
00350
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);
00358 int lpos = rest.find_first_of(" ,");
00359 files.push_back(rest.substr(0,lpos ));
00360 if (lpos == -1 ) break;
00361 rest = rest.substr(lpos,string::npos);
00362 }
00363 ctxt->setFiles(files);
00364 ctxt->setFileIterator(ctxt->files().begin());
00365 return StatusCode::SUCCESS;
00366 }
00367 return error("Invalid iteration context.");
00368 }