| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootEvtSelector.cpp
Go to the documentation of this file.
1 // $Id: RootEvtSelector.cpp,v 1.11 2010-09-27 15:43:53 frankb Exp $
2 //====================================================================
3 // RootEvtSelector.cpp
4 //--------------------------------------------------------------------
5 //
6 // Package : RootCnv
7 //
8 // Author : M.Frank
9 //====================================================================
10 #ifndef GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
11 #define GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
12
13 // Include files
14 #include "RootCnv/RootEvtSelector.h"
15 #include <vector>
16
17 // Forward declarations
18 class TBranch;
19
20 /*
21 * Gaudi namespace declaration
22 */
23 namespace Gaudi {
24
33 class RootEvtSelectorContext : public IEvtSelector::Context {
34 public:
36 typedef std::vector<std::string> Files;
37 private:
39 const RootEvtSelector* m_sel;
41 Files m_files;
43 Files::const_iterator m_fiter;
45 long m_entry;
47 TBranch* m_branch;
49 std::string m_fid;
50 public:
52 RootEvtSelectorContext(const RootEvtSelector* s) : m_sel(s),m_entry(-1),m_branch(0){}
54 virtual ~RootEvtSelectorContext() { }
56 const Files& files() const { return m_files; }
58 void setFiles(const Files& f) {
59 m_files = f;
60 m_fiter = m_files.begin();
61 }
63 virtual void* identifier() const { return (void*)m_sel; }
65 Files::const_iterator fileIterator() const { return m_fiter; }
67 void setFileIterator(Files::const_iterator i) { m_fiter = i; }
69 long entry() const { return m_entry; }
71 void setEntry(long e) { m_entry = e; }
73 void setFID(const std::string& fid) { m_fid = fid; }
75 const std::string& fid() const { return m_fid; }
77 TBranch* branch() const { return m_branch; }
79 void setBranch(TBranch* b) { m_branch = b; }
80 };
81 }
82 #endif // GAUDIROOTCNV_ROOTEVTSELECTORCONTEXT_H
83
84 // Include files
85 #include "GaudiKernel/ClassID.h"
86 #include "GaudiKernel/MsgStream.h"
87 #include "GaudiKernel/Tokenizer.h"
88 #include "GaudiKernel/TypeNameString.h"
89 #include "GaudiKernel/IDataManagerSvc.h"
90 #include "GaudiKernel/IPersistencySvc.h"
91 #include "GaudiKernel/ISvcLocator.h"
92 #include "RootCnv/RootCnvSvc.h"
93 #include "RootCnv/RootDataConnection.h"
94 #include "TBranch.h"
95
96 using namespace Gaudi;
97 using namespace std;
98
99 // Service Constructor
100 RootEvtSelector::RootEvtSelector(const string& name,ISvcLocator* svcloc)
101 : base_class(name, svcloc), m_rootCLID(CLID_NULL)
102 {
103 m_cnvSvcName = "Gaudi::RootCnvSvc/RootCnvSvc";
104 m_persName = "EventPersistencySvc";
105 declareProperty("EvtPersistencySvc",m_persName="EventPersistencySvc");
106 declareProperty("DbType",m_dummy);
107 }
108
109 // Helper method to issue error messages
110 StatusCode RootEvtSelector::error(const string& msg) const {
111 MsgStream log(msgSvc(), name());
112 log << MSG::ERROR << msg << endmsg;
113 return StatusCode::FAILURE;
114 }
115
116 // IService implementation: Db event selector override
117 StatusCode RootEvtSelector::initialize() {
118 // Initialize base class
119 StatusCode status = Service::initialize();
120 if ( !status.isSuccess() ) {
121 return error("Error initializing base class Service!");
122 }
123
124 SmartIF<IPersistencySvc> ipers(serviceLocator()->service(m_persName));
125 if( !ipers.isValid() ) {
126 return error("Unable to locate IPersistencySvc interface of "+m_persName);
127 }
128 IConversionSvc *cnvSvc = 0;
129 Gaudi::Utils::TypeNameString itm(m_cnvSvcName);
130 status = ipers->getService(itm.name(),cnvSvc);
131 if( !status.isSuccess() ) {
132 status = ipers->getService(itm.type(),cnvSvc);
133 if( !status.isSuccess() ) {
134 return error("Unable to locate IConversionSvc interface of database type "+m_cnvSvcName);
135 }
136 }
137 m_dbMgr = dynamic_cast<RootCnvSvc*>(cnvSvc);
138 if( !m_dbMgr ) {
139 cnvSvc->release();
140 return error("Unable to localize service:"+m_cnvSvcName);
141 }
142 m_dbMgr->addRef();
143
144 // Get DataSvc
145 SmartIF<IDataManagerSvc> eds(serviceLocator()->service("EventDataSvc"));
146 if( !eds.isValid() ) {
147 return error("Unable to localize service EventDataSvc");
148 }
149 m_rootCLID = eds->rootCLID();
150 m_rootName = eds->rootName();
151 MsgStream log(msgSvc(), name());
152 log << MSG::DEBUG << "Selection root:" << m_rootName << " CLID:" << m_rootCLID << endmsg;
153 return status;
154 }
155
156 // IService implementation: Service finalization
157 StatusCode RootEvtSelector::finalize() {
158 // Initialize base class
159 if ( m_dbMgr ) m_dbMgr->release();
160 m_dbMgr = 0; // release
161 return Service::finalize();
162 }
163
164 // Create a new event loop context
165 StatusCode RootEvtSelector::createContext(Context*& refpCtxt) const {
166 refpCtxt = new RootEvtSelectorContext(this);
167 return StatusCode::SUCCESS;
168 }
169
170 // Access last item in the iteration
171 StatusCode RootEvtSelector::last(Context& /*refContext*/) const {
172 return StatusCode::FAILURE;
173 }
174
175 // Get next iteration item from the event loop context
176 StatusCode RootEvtSelector::next(Context& ctxt) const {
177 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
178 if ( pCtxt ) {
179 TBranch* b = pCtxt->branch();
180 if ( !b ) {
181 RootEvtSelectorContext::Files::const_iterator fileit = pCtxt->fileIterator();
182 pCtxt->setBranch(0);
183 pCtxt->setEntry(-1);
184 if ( fileit != pCtxt->files().end() ) {
185 RootDataConnection* con=0;
186 string in = *fileit;
187 StatusCode sc = m_dbMgr->connectDatabase(in,IDataConnection::READ,&con);
188 if ( sc.isSuccess() ) {
189 string section = m_rootName[0] == '/' ? m_rootName.substr(1) : m_rootName;
190 b = con->getBranch(section,m_rootName);
191 if ( b ) {
192 pCtxt->setFID(con->fid());
193 pCtxt->setBranch(b);
194 return next(ctxt);
195 }
196 }
197 m_dbMgr->disconnect(in).ignore();
198 pCtxt->setFileIterator(++fileit);
199 return next(ctxt);
200 }
201 return StatusCode::FAILURE;
202 }
203 long ent = pCtxt->entry();
204 Long64_t nent = b->GetEntries();
205 if ( nent > (ent+1) ) {
206 pCtxt->setEntry(++ent);
207 return StatusCode::SUCCESS;
208 }
209 RootEvtSelectorContext::Files::const_iterator fit = pCtxt->fileIterator();
210 pCtxt->setFileIterator(++fit);
211 pCtxt->setEntry(-1);
212 pCtxt->setBranch(0);
213 pCtxt->setFID("");
214 return next(ctxt);
215 }
216 return StatusCode::FAILURE;
217 }
218
219 // Get next iteration item from the event loop context
220 StatusCode RootEvtSelector::next(Context& ctxt,int jump) const {
221 if ( jump > 0 ) {
222 for ( int i = 0; i < jump; ++i ) {
223 StatusCode status = next(ctxt);
224 if ( !status.isSuccess() ) {
225 return status;
226 }
227 }
228 return StatusCode::SUCCESS;
229 }
230 return StatusCode::FAILURE;
231 }
232
233 // Get previous iteration item from the event loop context
234 StatusCode RootEvtSelector::previous(Context& /* ctxt */) const {
235 return error("EventSelector Iterator, operator -- not supported ");
236 }
237
238 // Get previous iteration item from the event loop context
239 StatusCode RootEvtSelector::previous(Context& ctxt, int jump) const {
240 if ( jump > 0 ) {
241 for ( int i = 0; i < jump; ++i ) {
242 StatusCode status = previous(ctxt);
243 if ( !status.isSuccess() ) {
244 return status;
245 }
246 }
247 return StatusCode::SUCCESS;
248 }
249 return StatusCode::FAILURE;
250 }
251
252 // Rewind the dataset
253 StatusCode RootEvtSelector::rewind(Context& ctxt) const {
254 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(&ctxt);
255 if ( pCtxt ) {
256 RootEvtSelectorContext::Files::const_iterator fileit = pCtxt->fileIterator();
257 if ( fileit != pCtxt->files().end() ) {
258 string input = *fileit;
259 m_dbMgr->disconnect(input).ignore();
260 }
261 pCtxt->setFID("");
262 pCtxt->setEntry(-1);
263 pCtxt->setBranch(0);
264 pCtxt->setFileIterator(pCtxt->files().begin());
265 return StatusCode::SUCCESS;
266 }
267 return StatusCode::FAILURE;
268 }
269
270 // Create new Opaque address corresponding to the current record
271 StatusCode
272 RootEvtSelector::createAddress(const Context& ctxt, IOpaqueAddress*& pAddr) const {
273 const RootEvtSelectorContext* pctxt = dynamic_cast<const RootEvtSelectorContext*>(&ctxt);
274 if ( pctxt ) {
275 long ent = pctxt->entry();
276 if ( ent >= 0 ) {
277 RootEvtSelectorContext::Files::const_iterator fileit = pctxt->fileIterator();
278 if ( fileit != pctxt->files().end() ) {
279 const string par[2] = {pctxt->fid(), m_rootName};
280 const unsigned long ipar[2] = {0,(unsigned long)ent};
281 return m_dbMgr->createAddress(m_dbMgr->repSvcType(),m_rootCLID,&par[0],&ipar[0],pAddr);
282 }
283 }
284 }
285 pAddr = 0;
286 return StatusCode::FAILURE;
287 }
288
289 // Release existing event iteration context
290 StatusCode RootEvtSelector::releaseContext(Context*& ctxt) const {
291 RootEvtSelectorContext* pCtxt = dynamic_cast<RootEvtSelectorContext*>(ctxt);
292 if ( pCtxt ) {
293 delete pCtxt;
294 return StatusCode::SUCCESS;
295 }
296 return StatusCode::FAILURE;
297 }
298
299 // Will set a new criteria for the selection of the next list of events and will change
300 // the state of the context in a way to point to the new list.
301 StatusCode
302 RootEvtSelector::resetCriteria(const string& criteria, Context& context) const
303 {
304 MsgStream log(msgSvc(), name());
305 RootEvtSelectorContext* ctxt = dynamic_cast<RootEvtSelectorContext*>(&context);
306 string db, typ, item, sel, stmt, aut, addr;
307 if ( ctxt ) {
308 if ( criteria.substr(0,5) == "FILE " ) {
309 // The format for the criteria is:
310 // FILE filename1, filename2 ...
311 db = criteria.substr(5);
312 }
313 else {
314 Tokenizer tok(true);
315 tok.analyse(criteria," ","","","=","'","'");
316 for(Tokenizer::Items::iterator i=tok.items().begin(); i!=tok.items().end();i++) {
317 string tmp = (*i).tag().substr(0,3);
318 if(tmp=="DAT") {
319 db = (*i).value();
320 }
321 if(tmp=="OPT") {
322 if((*i).value() != "REA") {
323 log << MSG::ERROR << "Option:\"" << (*i).value() << "\" not valid" << endmsg;
324 return StatusCode::FAILURE;
325 }
326 }
327 if (tmp=="TYP") {
328 typ = (*i).value();
329 }
330 if(tmp=="ADD") {
331 item = (*i).value();
332 }
333 if(tmp=="SEL") {
334 sel = (*i).value();
335 }
336 if(tmp=="FUN") {
337 stmt = (*i).value();
338 }
339 if(tmp=="AUT") {
340 aut = (*i).value();
341 }
342 if(tmp=="COL") {
343 addr = (*i).value();
344 }
345 }
346 }
347 // It's now time to parse the criteria for the event selection
348 // The format for the criteria is:
349 // FILE filename1, filename2 ...
350 // JOBID number1-number2, number3, ...
351 RootEvtSelectorContext::Files files;
352 string rest = db;
353 files.clear();
354 while(true) {
355 int ipos = rest.find_first_not_of(" ,");
356 if (ipos == -1 ) break;
357 rest = rest.substr(ipos,string::npos);// remove blanks before
358 int lpos = rest.find_first_of(" ,"); // locate next blank
359 files.push_back(rest.substr(0,lpos )); // insert in list
360 if (lpos == -1 ) break;
361 rest = rest.substr(lpos,string::npos);// get the rest
362 }
363 ctxt->setFiles(files);
364 ctxt->setFileIterator(ctxt->files().begin());
365 return StatusCode::SUCCESS;
366 }
367 return error("Invalid iteration context.");
368 }