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
13 #include "RootCnv/RootEvtSelector.h"
14 #include <vector>
15 
16 // Forward declarations
17 class TBranch;
18 
19 /*
20 * Gaudi namespace declaration
21 */
22 namespace Gaudi {
23 
33  public:
35  typedef std::vector<std::string> Files;
36  private:
40  Files m_files;
42  Files::const_iterator m_fiter;
44  long m_entry;
46  TBranch* m_branch;
48  std::string m_fid;
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"
86 #include "GaudiKernel/AttribStringParser.h"
87 #include "GaudiKernel/TypeNameString.h"
88 #include "GaudiKernel/IDataManagerSvc.h"
89 #include "GaudiKernel/IPersistencySvc.h"
90 #include "GaudiKernel/ISvcLocator.h"
91 #include "RootCnv/RootCnvSvc.h"
92 #include "RootCnv/RootDataConnection.h"
93 #include "TBranch.h"
94 
95 using namespace Gaudi;
96 using namespace std;
97 
98 // Service Constructor
100 : base_class(name, svcloc), m_rootCLID(CLID_NULL)
101 {
102  m_cnvSvcName = "Gaudi::RootCnvSvc/RootCnvSvc";
103  m_persName = "EventPersistencySvc";
104  declareProperty("EvtPersistencySvc",m_persName="EventPersistencySvc");
105  declareProperty("DbType",m_dummy);
106 }
107 
108 // Helper method to issue error messages
109 StatusCode RootEvtSelector::error(const string& msg) const {
110  MsgStream log(msgSvc(), name());
111  log << MSG::ERROR << msg << endmsg;
112  return StatusCode::FAILURE;
113 }
114 
115 // IService implementation: Db event selector override
117  // Initialize base class
118  StatusCode status = Service::initialize();
119  if ( !status.isSuccess() ) {
120  return error("Error initializing base class Service!");
121  }
122 
123  auto ipers = serviceLocator()->service<IPersistencySvc>(m_persName);
124  if( !ipers ) {
125  return error("Unable to locate IPersistencySvc interface of "+m_persName);
126  }
127  IConversionSvc *cnvSvc = nullptr;
129  status = ipers->getService(itm.name(),cnvSvc);
130  if( !status.isSuccess() ) {
131  status = ipers->getService(itm.type(),cnvSvc);
132  if( !status.isSuccess() ) {
133  return error("Unable to locate IConversionSvc interface of database type "+m_cnvSvcName);
134  }
135  }
136  m_dbMgr = dynamic_cast<RootCnvSvc*>(cnvSvc);
137  if( !m_dbMgr ) {
138  cnvSvc->release();
139  return error("Unable to localize service:"+m_cnvSvcName);
140  }
141  m_dbMgr->addRef();
142 
143  // Get DataSvc
144  auto eds = serviceLocator()->service<IDataManagerSvc>("EventDataSvc");
145  if( !eds ) {
146  return error("Unable to localize service EventDataSvc");
147  }
148  m_rootCLID = eds->rootCLID();
149  m_rootName = eds->rootName();
150  MsgStream log(msgSvc(), name());
151  log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
152  return status;
153 }
154 
155 // IService implementation: Service finalization
157  // Initialize base class
158  if ( m_dbMgr ) m_dbMgr->release();
159  m_dbMgr = nullptr; // release
160  return Service::finalize();
161 }
162 
163 // Create a new event loop context
164 StatusCode RootEvtSelector::createContext(Context*& refpCtxt) const {
165  refpCtxt = new RootEvtSelectorContext(this);
166  return StatusCode::SUCCESS;
167 }
168 
169 // Access last item in the iteration
170 StatusCode RootEvtSelector::last(Context& /*refContext*/) const {
171  return StatusCode::FAILURE;
172 }
173 
174 // Get next iteration item from the event loop context
175 StatusCode RootEvtSelector::next(Context& ctxt) const {
176  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
177  if ( pCtxt ) {
178  TBranch* b = pCtxt->branch();
179  if ( !b ) {
180  auto fileit = pCtxt->fileIterator();
181  pCtxt->setBranch(nullptr);
182  pCtxt->setEntry(-1);
183  if ( fileit != pCtxt->files().end() ) {
184  RootDataConnection* con=nullptr;
185  string in = *fileit;
187  if ( sc.isSuccess() ) {
188  string section = m_rootName[0] == '/' ? m_rootName.substr(1) : m_rootName;
189  b = con->getBranch(section,m_rootName);
190  if ( b ) {
191  pCtxt->setFID(con->fid());
192  pCtxt->setBranch(b);
193  return next(ctxt);
194  }
195  }
196  m_dbMgr->disconnect(in).ignore();
197  pCtxt->setFileIterator(++fileit);
198  return next(ctxt);
199  }
200  return StatusCode::FAILURE;
201  }
202  long ent = pCtxt->entry();
203  Long64_t nent = b->GetEntries();
204  if ( nent > (ent+1) ) {
205  pCtxt->setEntry(++ent);
206  return StatusCode::SUCCESS;
207  }
208  auto fit = pCtxt->fileIterator();
209  pCtxt->setFileIterator(++fit);
210  pCtxt->setEntry(-1);
211  pCtxt->setBranch(nullptr);
212  pCtxt->setFID("");
213  return next(ctxt);
214  }
215  return StatusCode::FAILURE;
216 }
217 
218 // Get next iteration item from the event loop context
219 StatusCode RootEvtSelector::next(Context& ctxt,int jump) const {
220  if ( jump > 0 ) {
221  for ( int i = 0; i < jump; ++i ) {
222  StatusCode status = next(ctxt);
223  if ( !status.isSuccess() ) {
224  return status;
225  }
226  }
227  return StatusCode::SUCCESS;
228  }
229  return StatusCode::FAILURE;
230 }
231 
232 // Get previous iteration item from the event loop context
233 StatusCode RootEvtSelector::previous(Context& /* ctxt */) const {
234  return error("EventSelector Iterator, operator -- not supported ");
235 }
236 
237 // Get previous iteration item from the event loop context
238 StatusCode RootEvtSelector::previous(Context& ctxt, int jump) const {
239  if ( jump > 0 ) {
240  for ( int i = 0; i < jump; ++i ) {
241  StatusCode status = previous(ctxt);
242  if ( !status.isSuccess() ) {
243  return status;
244  }
245  }
246  return StatusCode::SUCCESS;
247  }
248  return StatusCode::FAILURE;
249 }
250 
251 // Rewind the dataset
252 StatusCode RootEvtSelector::rewind(Context& ctxt) const {
253  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
254  if ( pCtxt ) {
255  auto fileit = pCtxt->fileIterator();
256  if ( fileit != pCtxt->files().end() ) {
257  string input = *fileit;
258  m_dbMgr->disconnect(input).ignore();
259  }
260  pCtxt->setFID("");
261  pCtxt->setEntry(-1);
262  pCtxt->setBranch(nullptr);
263  pCtxt->setFileIterator(pCtxt->files().begin());
264  return StatusCode::SUCCESS;
265  }
266  return StatusCode::FAILURE;
267 }
268 
269 // Create new Opaque address corresponding to the current record
271 RootEvtSelector::createAddress(const Context& ctxt, IOpaqueAddress*& pAddr) const {
272  const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>(&ctxt);
273  if ( pctxt ) {
274  long ent = pctxt->entry();
275  if ( ent >= 0 ) {
276  auto fileit = pctxt->fileIterator();
277  if ( fileit != pctxt->files().end() ) {
278  const string par[2] = {pctxt->fid(), m_rootName};
279  const unsigned long ipar[2] = {0,(unsigned long)ent};
280  return m_dbMgr->createAddress(m_dbMgr->repSvcType(),m_rootCLID,&par[0],&ipar[0],pAddr);
281  }
282  }
283  }
284  pAddr = nullptr;
285  return StatusCode::FAILURE;
286 }
287 
288 // Release existing event iteration context
290  RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(ctxt);
291  if ( pCtxt ) {
292  delete pCtxt;
293  return StatusCode::SUCCESS;
294  }
295  return StatusCode::FAILURE;
296 }
297 
298 // Will set a new criteria for the selection of the next list of events and will change
299 // the state of the context in a way to point to the new list.
301 RootEvtSelector::resetCriteria(const string& criteria, Context& context) const
302 {
303  MsgStream log(msgSvc(), name());
304  RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>(&context);
305  string db, typ, item, sel, stmt, aut, addr;
306  if ( ctxt ) {
307  if ( criteria.compare(0,5,"FILE ")==0 ) {
308  // The format for the criteria is:
309  // FILE filename1, filename2 ...
310  db = criteria.substr(5);
311  }
312  else {
313  using Parser = Gaudi::Utils::AttribStringParser;
314  for(auto attrib: Parser(criteria)) {
315  string tmp = attrib.tag.substr(0,3);
316  if(tmp=="DAT") {
317  db = std::move(attrib.value);
318  }
319  else if(tmp=="OPT") {
320  if(attrib.value.compare(0, 3,"REA") != 0) {
321  log << MSG::ERROR << "Option:\"" << attrib.value << "\" not valid" << endmsg;
322  return StatusCode::FAILURE;
323  }
324  }
325  else if (tmp=="TYP") {
326  typ = std::move(attrib.value);
327  }
328  else if(tmp=="ADD") {
329  item = std::move(attrib.value);
330  }
331  else if(tmp=="SEL") {
332  sel = std::move(attrib.value);
333  }
334  else if(tmp=="FUN") {
335  stmt = std::move(attrib.value);
336  }
337  else if(tmp=="AUT") {
338  aut = std::move(attrib.value);
339  }
340  else if(tmp=="COL") {
341  addr = std::move(attrib.value);
342  }
343  }
344  }
345  // It's now time to parse the criteria for the event selection
346  // The format for the criteria is:
347  // FILE filename1, filename2 ...
348  // JOBID number1-number2, number3, ...
350  string rest = db;
351  files.clear();
352  while(true) {
353  int ipos = rest.find_first_not_of(" ,");
354  if (ipos == -1 ) break;
355  rest = rest.substr(ipos,string::npos);// remove blanks before
356  int lpos = rest.find_first_of(" ,"); // locate next blank
357  files.push_back(rest.substr(0,lpos )); // insert in list
358  if (lpos == -1 ) break;
359  rest = rest.substr(lpos,string::npos);// get the rest
360  }
361  ctxt->setFiles(files);
362  ctxt->setFileIterator(ctxt->files().begin());
363  return StatusCode::SUCCESS;
364  }
365  return error("Invalid iteration context.");
366 }
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
const Files & files() const
Access to the file container.
std::string m_persName
Property; Name of the persistency service to search for conversion service.
virtual StatusCode rewind(Context &refCtxt) const
Rewind the dataset.
virtual StatusCode initialize()
IService implementation: Db event selector override.
Files::const_iterator fileIterator() const
Access to the file iterator.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
const std::string & fid() const
Access file id.
virtual StatusCode last(Context &refContext) const
Access last item in the iteration.
RootEvtSelectorContext(const RootEvtSelector *s)
Standard constructor with initialization.
StatusCode finalize() override
Definition: Service.cpp:188
tuple itm
Definition: ana.py:57
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress)
IAddressCreator implementation: Address creation.
Definition: RootCnvSvc.cpp:389
std::vector< std::string > Files
Definition of the file container.
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:76
std::string m_fid
Connection fid.
Description:
Definition: RootCnvSvc.h:52
STL namespace.
virtual StatusCode resetCriteria(const std::string &cr, Context &c) const
Will set a new criteria for the selection of the next list of events and will change the state of the...
std::string m_dummy
Property: dummy to fake backwards compatibility.
virtual StatusCode previous(Context &refCtxt) const
Get previous iteration item from the event loop context.
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
~RootEvtSelectorContext() override=default
Standard destructor.
void * identifier() const override
Context identifier.
virtual StatusCode finalize()
IService implementation: Service finalization.
Helper class to parse a string of format "type/name".
Definition: TypeNameString.h:9
virtual long repSvcType() const
Retrieve the class type of the data store the converter uses.
std::string m_cnvSvcName
Property; Name of the concversion service used to create opaque addresses.
ROOT specific event selector context.
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
TBranch * getBranch(const std::string &section, const std::string &branch_name)
Access data branch by name: Get existing branch in read only mode.
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 connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
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.
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
StatusCode error(const std::string &msg) const
Helper method to issue error messages.
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
tuple item
print s1,s2
Definition: ana.py:146
RootCnvSvc * m_dbMgr
Reference to the corresponding conversion service.
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.
const std::string & name() const
RootEvtSelector(const std::string &name, ISvcLocator *svcloc)
Service Constructor.
Opaque address interface definition.
void ignore() const
Definition: StatusCode.h:108
Files m_files
The file container managed by this context.
virtual StatusCode createAddress(const Context &refCtxt, IOpaqueAddress *&) const
Create new Opaque address corresponding to the current record.
virtual StatusCode releaseContext(Context *&refCtxt) const
Release existing event iteration context.
CLID m_rootCLID
Class id of root node to create opaque address.
list i
Definition: ana.py:128
Concrete implementation of the IDataConnection interface to access ROOT files.
TBranch * m_branch
Reference to the top level branch (typically /Event) used to iterate.
Helper functions to set/get the application return code.
Definition: __init__.py:1
long entry() const
Access to the current event entry number.
virtual StatusCode next(Context &refCtxt) const
Get next iteration item from the event loop context.
virtual StatusCode createContext(Context *&refpCtxt) const
Create a new event loop context.
std::string m_rootName
Property: Name of the ROOT entry name.
long m_entry
Current entry of current file.