All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
RootEvtSelector.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RootEvtSelector.cpp
3 //--------------------------------------------------------------------
4 //
5 // Package : RootCnv
6 //
7 // Author : M.Frank
8 //====================================================================
9 #ifndef GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
10 #define GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
11 
12 // Include files
14 #include <vector>
15 
16 // Forward declarations
17 class TBranch;
18 
19 /*
20 * Gaudi namespace declaration
21 */
22 namespace Gaudi {
23 
33  public:
36  private:
40  Files m_files;
42  Files::const_iterator m_fiter;
44  long m_entry;
46  TBranch* m_branch;
49  public:
51  RootEvtSelectorContext(const RootEvtSelector* s) : m_sel(s),m_entry(-1),m_branch(nullptr){}
53  ~RootEvtSelectorContext() override = default;
55  const Files& files() const { return m_files; }
57  void setFiles(const Files& f) {
58  m_files = f;
59  m_fiter = m_files.begin();
60  }
62  void* identifier() const override { return const_cast<RootEvtSelector*>(m_sel); }
64  Files::const_iterator fileIterator() const { return m_fiter; }
66  void setFileIterator(Files::const_iterator i) { m_fiter = i; }
68  long entry() const { return m_entry; }
70  void setEntry(long e) { m_entry = e; }
72  void setFID(const std::string& fid) { m_fid = fid; }
74  const std::string& fid() const { return m_fid; }
76  TBranch* branch() const { return m_branch; }
78  void setBranch(TBranch* b) { m_branch = b; }
79  };
80 }
81 #endif // GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
82 
83 // Include files
84 #include "GaudiKernel/ClassID.h"
85 #include "GaudiKernel/MsgStream.h"
91 #include "RootCnv/RootCnvSvc.h"
93 #include "TBranch.h"
94 
95 using namespace Gaudi;
96 using namespace std;
97 
98 // Helper method to issue error messages
99 StatusCode RootEvtSelector::error(const string& msg) const {
100  MsgStream log(msgSvc(), name());
101  log << MSG::ERROR << msg << endmsg;
102  return StatusCode::FAILURE;
103 }
104 
105 // IService implementation: Db event selector override
107  // Initialize base class
108  StatusCode status = Service::initialize();
109  if ( !status.isSuccess() ) {
110  return error("Error initializing base class Service!");
111  }
112 
113  auto ipers = serviceLocator()->service<IPersistencySvc>(m_persName);
114  if( !ipers ) {
115  return error("Unable to locate IPersistencySvc interface of "+m_persName);
116  }
117  IConversionSvc *cnvSvc = nullptr;
118  Gaudi::Utils::TypeNameString itm(m_cnvSvcName);
119  status = ipers->getService(itm.name(),cnvSvc);
120  if( !status.isSuccess() ) {
121  status = ipers->getService(itm.type(),cnvSvc);
122  if( !status.isSuccess() ) {
123  return error("Unable to locate IConversionSvc interface of database type "+m_cnvSvcName);
124  }
125  }
126  m_dbMgr = dynamic_cast<RootCnvSvc*>(cnvSvc);
127  if( !m_dbMgr ) {
128  cnvSvc->release();
129  return error("Unable to localize service:"+m_cnvSvcName);
130  }
131  m_dbMgr->addRef();
132 
133  // Get DataSvc
134  auto eds = serviceLocator()->service<IDataManagerSvc>("EventDataSvc");
135  if( !eds ) {
136  return error("Unable to localize service EventDataSvc");
137  }
138  m_rootCLID = eds->rootCLID();
139  m_rootName = eds->rootName();
140  MsgStream log(msgSvc(), name());
141  log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
142  return status;
143 }
144 
145 // IService implementation: Service finalization
147  // Initialize base class
148  if ( m_dbMgr ) m_dbMgr->release();
149  m_dbMgr = nullptr; // release
150  return Service::finalize();
151 }
152 
153 // Create a new event loop context
154 StatusCode RootEvtSelector::createContext(Context*& refpCtxt) const {
155  refpCtxt = new RootEvtSelectorContext(this);
156  return StatusCode::SUCCESS;
157 }
158 
159 // Access last item in the iteration
160 StatusCode RootEvtSelector::last(Context& /*refContext*/) const {
161  return StatusCode::FAILURE;
162 }
163 
164 // Get next iteration item from the event loop context
165 StatusCode RootEvtSelector::next(Context& ctxt) const {
166  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
167  if ( pCtxt ) {
168  TBranch* b = pCtxt->branch();
169  if ( !b ) {
170  auto fileit = pCtxt->fileIterator();
171  pCtxt->setBranch(nullptr);
172  pCtxt->setEntry(-1);
173  if ( fileit != pCtxt->files().end() ) {
174  RootDataConnection* con=nullptr;
175  string in = *fileit;
176  StatusCode sc = m_dbMgr->connectDatabase(in,IDataConnection::READ,&con);
177  if ( sc.isSuccess() ) {
178  string section = m_rootName[0] == '/' ? m_rootName.substr(1) : m_rootName;
179  b = con->getBranch(section,m_rootName);
180  if ( b ) {
181  pCtxt->setFID(con->fid());
182  pCtxt->setBranch(b);
183  return next(ctxt);
184  }
185  }
186  m_dbMgr->disconnect(in).ignore();
187  pCtxt->setFileIterator(++fileit);
188  return next(ctxt);
189  }
190  return StatusCode::FAILURE;
191  }
192  long ent = pCtxt->entry();
193  Long64_t nent = b->GetEntries();
194  if ( nent > (ent+1) ) {
195  pCtxt->setEntry(++ent);
196  return StatusCode::SUCCESS;
197  }
198  auto fit = pCtxt->fileIterator();
199  pCtxt->setFileIterator(++fit);
200  pCtxt->setEntry(-1);
201  pCtxt->setBranch(nullptr);
202  pCtxt->setFID("");
203  return next(ctxt);
204  }
205  return StatusCode::FAILURE;
206 }
207 
208 // Get next iteration item from the event loop context
209 StatusCode RootEvtSelector::next(Context& ctxt,int jump) const {
210  if ( jump > 0 ) {
211  for ( int i = 0; i < jump; ++i ) {
212  StatusCode status = next(ctxt);
213  if ( !status.isSuccess() ) {
214  return status;
215  }
216  }
217  return StatusCode::SUCCESS;
218  }
219  return StatusCode::FAILURE;
220 }
221 
222 // Get previous iteration item from the event loop context
223 StatusCode RootEvtSelector::previous(Context& /* ctxt */) const {
224  return error("EventSelector Iterator, operator -- not supported ");
225 }
226 
227 // Get previous iteration item from the event loop context
228 StatusCode RootEvtSelector::previous(Context& ctxt, int jump) const {
229  if ( jump > 0 ) {
230  for ( int i = 0; i < jump; ++i ) {
231  StatusCode status = previous(ctxt);
232  if ( !status.isSuccess() ) {
233  return status;
234  }
235  }
236  return StatusCode::SUCCESS;
237  }
238  return StatusCode::FAILURE;
239 }
240 
241 // Rewind the dataset
242 StatusCode RootEvtSelector::rewind(Context& ctxt) const {
243  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
244  if ( pCtxt ) {
245  auto fileit = pCtxt->fileIterator();
246  if ( fileit != pCtxt->files().end() ) {
247  string input = *fileit;
248  m_dbMgr->disconnect(input).ignore();
249  }
250  pCtxt->setFID("");
251  pCtxt->setEntry(-1);
252  pCtxt->setBranch(nullptr);
253  pCtxt->setFileIterator(pCtxt->files().begin());
254  return StatusCode::SUCCESS;
255  }
256  return StatusCode::FAILURE;
257 }
258 
259 // Create new Opaque address corresponding to the current record
261 RootEvtSelector::createAddress(const Context& ctxt, IOpaqueAddress*& pAddr) const {
262  const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>(&ctxt);
263  if ( pctxt ) {
264  long ent = pctxt->entry();
265  if ( ent >= 0 ) {
266  auto fileit = pctxt->fileIterator();
267  if ( fileit != pctxt->files().end() ) {
268  const string par[2] = {pctxt->fid(), m_rootName};
269  const unsigned long ipar[2] = {0,(unsigned long)ent};
270  return m_dbMgr->createAddress(m_dbMgr->repSvcType(),m_rootCLID,&par[0],&ipar[0],pAddr);
271  }
272  }
273  }
274  pAddr = nullptr;
275  return StatusCode::FAILURE;
276 }
277 
278 // Release existing event iteration context
280  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(ctxt);
281  if ( pCtxt ) {
282  delete pCtxt;
283  return StatusCode::SUCCESS;
284  }
285  return StatusCode::FAILURE;
286 }
287 
288 // Will set a new criteria for the selection of the next list of events and will change
289 // the state of the context in a way to point to the new list.
291 RootEvtSelector::resetCriteria(const string& criteria, Context& context) const
292 {
293  MsgStream log(msgSvc(), name());
294  RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>(&context);
295  string db, typ, item, sel, stmt, aut, addr;
296  if ( ctxt ) {
297  if ( criteria.compare(0,5,"FILE ")==0 ) {
298  // The format for the criteria is:
299  // FILE filename1, filename2 ...
300  db = criteria.substr(5);
301  }
302  else {
303  using Parser = Gaudi::Utils::AttribStringParser;
304  for(auto attrib: Parser(criteria)) {
305  string tmp = attrib.tag.substr(0,3);
306  if(tmp=="DAT") {
307  db = std::move(attrib.value);
308  }
309  else if(tmp=="OPT") {
310  if(attrib.value.compare(0, 3,"REA") != 0) {
311  log << MSG::ERROR << "Option:\"" << attrib.value << "\" not valid" << endmsg;
312  return StatusCode::FAILURE;
313  }
314  }
315  else if (tmp=="TYP") {
316  typ = std::move(attrib.value);
317  }
318  else if(tmp=="ADD") {
319  item = std::move(attrib.value);
320  }
321  else if(tmp=="SEL") {
322  sel = std::move(attrib.value);
323  }
324  else if(tmp=="FUN") {
325  stmt = std::move(attrib.value);
326  }
327  else if(tmp=="AUT") {
328  aut = std::move(attrib.value);
329  }
330  else if(tmp=="COL") {
331  addr = std::move(attrib.value);
332  }
333  }
334  }
335  // It's now time to parse the criteria for the event selection
336  // The format for the criteria is:
337  // FILE filename1, filename2 ...
338  // JOBID number1-number2, number3, ...
340  string rest = db;
341  files.clear();
342  while(true) {
343  int ipos = rest.find_first_not_of(" ,");
344  if (ipos == -1 ) break;
345  rest = rest.substr(ipos,string::npos);// remove blanks before
346  int lpos = rest.find_first_of(" ,"); // locate next blank
347  files.push_back(rest.substr(0,lpos )); // insert in list
348  if (lpos == -1 ) break;
349  rest = rest.substr(lpos,string::npos);// get the rest
350  }
351  ctxt->setFiles(files);
352  ctxt->setFileIterator(ctxt->files().begin());
353  return StatusCode::SUCCESS;
354  }
355  return error("Invalid iteration context.");
356 }
Parse attribute strings allowing iteration over the various attributes.
StatusCode resetCriteria(const std::string &cr, Context &c) const override
Will set a new criteria for the selection of the next list of events and will change the state of the...
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:64
const Files & files() const
Access to the file container.
Files::const_iterator fileIterator() const
Access to the file iterator.
const std::string & fid() const
Access file id.
RootEvtSelectorContext(const RootEvtSelector *s)
Standard constructor with initialization.
T find_first_not_of(T...args)
StatusCode finalize() override
Definition: Service.cpp:174
std::vector< std::string > Files
Definition of the file container.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
std::string m_fid
Connection fid.
sel
Definition: IOTest.py:84
Description:
Definition: RootCnvSvc.h:53
STL namespace.
T end(T...args)
StatusCode last(Context &refContext) const override
Access last item in the iteration.
STL class.
StatusCode releaseContext(Context *&refCtxt) const override
Release existing event iteration context.
~RootEvtSelectorContext() override=default
Standard destructor.
T push_back(T...args)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
Helper class to parse a string of format "type/name".
StatusCode rewind(Context &refCtxt) const override
Rewind the dataset.
ROOT specific event selector context.
T next(T...args)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
StatusCode finalize() override
IService implementation: Service finalization.
TBranch * getBranch(const std::string &section, const std::string &branch_name)
Access data branch by name: Get existing branch in read only mode.
T find_first_of(T...args)
void * identifier() const override
Context identifier.
T clear(T...args)
T move(T...args)
const RootEvtSelector * m_sel
Reference to the hosting event selector instance.
void setFiles(const Files &f)
Set the file container.
void setBranch(TBranch *b)
Set the top level branch (typically /Event) used to iterate.
StatusCode next(Context &refCtxt) const override
Get next iteration item from the event loop context.
Concrete event selector implementation to access ROOT files.
void setEntry(long e)
Set current event entry number.
virtual unsigned long release()=0
Release Interface instance.
StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const override
Create new Opaque address corresponding to the current record.
T begin(T...args)
const std::string & type() const
const std::string & fid() const
Access connection fid.
void setFID(const std::string &fid)
Set connection FID.
Files::const_iterator m_fiter
The iterator to the.
string s
Definition: gaudirun.py:245
T substr(T...args)
Data persistency service interface.
void setFileIterator(Files::const_iterator i)
Set file iterator.
TBranch * branch() const
Access to the top level branch (typically /Event) used to iterate.
StatusCode createContext(Context *&refpCtxt) const override
Create a new event loop context.
const std::string & name() const
Opaque address interface definition.
StatusCode initialize() override
IService implementation: Db event selector override.
Files m_files
The file container managed by this context.
Concrete implementation of the IDataConnection interface to access ROOT files.
TBranch * m_branch
Reference to the top level branch (typically /Event) used to iterate.
StatusCode previous(Context &refCtxt) const override
Get previous iteration item from the event loop context.
Helper functions to set/get the application return code.
Definition: __init__.py:1
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
long entry() const
Access to the current event entry number.
T compare(T...args)
long m_entry
Current entry of current file.