CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MultiChainEvent.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWLite
4 // Class : MultiChainEvent
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Salvatore Rappoccio
10 // Created: Thu Jul 9 22:05:56 CDT 2009
11 //
12 
13 // system include files
14 
15 // user include files
22 
23 namespace fwlite {
24 
25  namespace internal {
26 
28 public:
30 
31  virtual edm::WrapperHolder
32  getIt(edm::ProductID const& iID) const {
33 
34  return event_->getByProductID(iID);
35  }
36 private:
38 
39  };
40  }
41 
42 //
43 // constants, enums and typedefs
44 //
45 
46 //
47 // static data member definitions
48 //
49 
50 //
51 // constructors and destructor
52 //
53  MultiChainEvent::MultiChainEvent(std::vector<std::string> const& iFileNames1,
54  std::vector<std::string> const& iFileNames2,
55  bool useSecFileMapSorted)
56 {
57  event1_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames1));
58  event2_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames2));
59 
60  getter_ = boost::shared_ptr<internal::MultiProductGetter>(new internal::MultiProductGetter(this));
61 
62  event1_->setGetter(getter_);
63  event2_->setGetter(getter_);
64 
65  useSecFileMapSorted_ = useSecFileMapSorted;
66 
67  if (!useSecFileMapSorted_) {
68  std::cout << "------------------------------------------------------------------------" << std::endl;
69  std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
70  std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
71  std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
72  std::cout << "There are speed improvements available to make this run faster." << std::endl;
73  std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) " << std::endl;
74  std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
75  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, true);" << std::endl;
76  std::cout << "------------------------------------------------------------------------" << std::endl;
77 
78  }
79 
81 
82  std::cout << "------------------------------------------------------------------------" << std::endl;
83  std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
84  std::cout << "for the 2-file solution. " << std::endl;
85  std::cout << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file." << std::endl;
86  std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
87  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, false);" << std::endl;
88  std::cout << "------------------------------------------------------------------------" << std::endl;
89  // speed up secondary file access with a (run,event)_1 ---> index_2 map
90 
91 
92  // Loop over events, when a new file is encountered, store the first run number from this file,
93  // and the last run number from the last file.
94  TFile * lastFile = 0;
95  std::pair<event_id_range,Long64_t> eventRange;
96  bool firstFile = true;
97 
98  bool foundAny = false;
99 
100  for(event2_->toBegin();
101  ! event2_->atEnd();
102  ++(*event2_)) {
103  // if we have a new file, cache the "first"
104  if (lastFile != event2_->getTFile()) {
105 
106  // if this is not the first file, we have an entry.
107  // Add it to the list.
108  if (!firstFile) {
109  foundAny = true;
110  event_id_range toAdd = eventRange.first;
111  secFileMapSorted_[ toAdd ] = eventRange.second;
112  }
113  // always add the "first" event id to the cached event range
114  eventRange.first.first = event2_->event()->id();
115  lastFile = event2_->getTFile();
116  }
117  // otherwise, cache the "second" event id in the cached event range.
118  // Upon the discovery of a new file, this will be used as the
119  // "last" event id in the cached event range.
120  else {
121  eventRange.first.second = event2_->event()->id();
122  eventRange.second = event2_->eventIndex();
123  }
124  firstFile = false;
125  }
126  // due to the invailability of a "look ahead" operation, we have one additional "put" to make
127  // after the loop (which puts the "last" event, not "this" event.
128  if (foundAny) {
129  event_id_range toAdd = eventRange.first;
130  secFileMapSorted_[ toAdd ] = eventRange.second;
131  }
132 // std::cout << "Dumping run range to event id list:" << std::endl;
133 // for (sec_file_range_index_map::const_iterator mBegin = secFileMapSorted_.begin(),
134 // mEnd = secFileMapSorted_.end(),
135 // mit = mBegin;
136 // mit != mEnd; ++mit) {
137 // char buff[1000];
138 // event2_->to(mit->second);
139 // sprintf(buff, "[%10d,%10d - %10d,%10d] ---> %10d",
140 // mit->first.first.run(),
141 // mit->first.first.event(),
142 // mit->first.second.run(),
143 // mit->first.second.event(),
144 // mit->second);
145 // std::cout << buff << std::endl;
146 // }
147  }
148 
149 }
150 
151 // MultiChainEvent::MultiChainEvent(const MultiChainEvent& rhs)
152 // {
153 // // do actual copying here;
154 // }
155 
157 {
158 }
159 
160 //
161 // assignment operators
162 //
163 // const MultiChainEvent& MultiChainEvent::operator=(const MultiChainEvent& rhs)
164 // {
165 // //An exception safe implementation is
166 // MultiChainEvent temp(rhs);
167 // swap(rhs);
168 //
169 // return *this;
170 // }
171 
172 //
173 // member functions
174 //
175 
176 const MultiChainEvent&
178 {
179  event1_->operator++();
180  return *this;
181 }
182 
184 bool
185 MultiChainEvent::to(Long64_t iIndex)
186 {
187  return event1_->to(iIndex);
188 }
189 
190 
192 bool
194 {
195  return to(id.run(), id.luminosityBlock(), id.event());
196 }
197 
199 bool
201 {
202  return event1_->to(run, lumi, event);
203 }
204 
206 bool
208 {
209  return to(run, 0U, event);
210 }
211 
212 
214 bool
215 MultiChainEvent::toSec(Long64_t iIndex)
216 {
217  return event2_->to(iIndex);
218 }
219 
220 // Go to event with event id "id"
221 bool
223 {
224  // First try this file.
225  if (event2_->event_->to(id))
226  {
227  // Found it, return.
228  return true;
229  }
230  // Second, assume that the secondary files are each in run/event
231  // order. So, let's loop over all files and see if we can figure
232  // out where the event ought to be.
233  for (sec_file_range_index_map::const_iterator mBegin =
234  secFileMapSorted_.begin(),
235  mEnd = secFileMapSorted_.end(),
236  mit = mBegin;
237  mit != mEnd;
238  ++mit)
239  {
240  if (id < mit->first.first || id > mit->first.second)
241  {
242  // We don't expect this event to be in this file, so don't
243  // bother checking it right now.
244  continue;
245  }
246  // If we're here, then we have a reasonable belief that this
247  // event is in this secondary file. This part is
248  // expensive. switchToFile does memory allocations and opens the
249  // files which becomes very time consuming. This should be done
250  // as infrequently as possible.
251  event2_->switchToFile(mit->second);
252  // Is it here?
253  if (event2_->to(id))
254  {
255  // Yes!
256  return true;
257  }
258  // if we assumed that the secondary files were not each in
259  // order, but were non-overlapping, we could break here. But at
260  // this point, we might as well keep going.
261  } // for loop over files
262 
263  // if we are still here, then we did not find the id in question,
264  // do it the old fashioned way. This will open up each secondary
265  // file and explicitly check to see if the event is there.
266  if (event2_->to(id))
267  {
268  return true;
269  }
270  // if we're still here, then there really is no matching event in
271  // the secondary files. Throw.
272  throw cms::Exception("ProductNotFound") << "Cannot find id "
273  << id.run() << ", "
274  << id.event()
275  << " in secondary list. Exiting."
276  << std::endl;
277  // to make the compiler happy
278  return false;
279 }
280 
282 bool
284 {
285  return toSec(edm::EventID(run, lumi, event));
286 }
287 
288 // Go to the very first Event
290 bool
292 {
293  return toSec(edm::EventID(run, 0U, event));
294 }
295 
296 // Go to the very first Event
297 const MultiChainEvent&
299 {
300  event1_->toBegin();
301  return *this;
302 }
303 
304 //
305 // const member functions
306 //
307 std::string const
308 MultiChainEvent::getBranchNameFor(std::type_info const& iType,
309  char const* iModule,
310  char const* iInstance,
311  char const* iProcess) const
312 {
313  return event1_->getBranchNameFor(iType,iModule,iInstance,iProcess);
314 }
315 
316 std::vector<edm::BranchDescription> const&
318 {
319  return event1_->getBranchDescriptions();
320 }
321 
322 std::vector<std::string> const&
324 {
325  return event1_->getProcessHistory();
326 }
327 
328 edm::ProcessHistory const&
330 {
331  return event1_->processHistory();
332 }
333 
334 edm::EventAuxiliary const&
336 {
337  return event1_->eventAuxiliary();
338 }
339 
340 bool
342  std::type_info const& iType,
343  char const* iModule,
344  char const* iInstance,
345  char const* iProcess,
346  void* iValue) const
347 {
348  bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
349  if (!ret1) {
350  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
351  bool ret2 = event2_->getByLabel(iType,iModule,iInstance,iProcess,iValue);
352  if (!ret2) return false;
353  }
354  return true;
355 }
356 
357 bool
359  std::type_info const& iType,
360  char const* iModule,
361  char const* iInstance,
362  char const* iProcess,
363  edm::WrapperHolder& holder) const {
364  bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, holder);
365  if(!ret1) {
366  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
367  bool ret2 = event2_->getByLabel(iType, iModule, iInstance, iProcess, holder);
368  if(!ret2) return false;
369  }
370  return true;
371 }
372 
374 {
375  // First try the first file
376  edm::WrapperHolder edp = event1_->getByProductID(iID);
377  // Did not find the product, try secondary file
378  if (!edp.isValid()) {
379  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
380  edp = event2_->getByProductID(iID);
381  if (!edp.isValid()) {
382  throw cms::Exception("ProductNotFound") << "Cannot find product " << iID;
383  }
384  }
385  return edp;
386 }
387 
388 
389 bool
391 {
392  return event1_->isValid();
393 }
395 {
396  return *event1_;
397 }
398 
399 bool
401 {
402  return event1_->atEnd();
403 }
404 
405 Long64_t
407 {
408  return event1_->size();
409 }
410 
411 edm::TriggerNames const&
413 {
414  edm::TriggerNames const* names = triggerNames_(triggerResults);
415  if (names != 0) return *names;
416 
417  event1_->fillParameterSetRegistry();
418  names = triggerNames_(triggerResults);
419  if (names != 0) return *names;
420 
421  // If we cannot find it in the primary file, this probably will
422  // not help but try anyway
423  event2_->to(event1_->id());
424  event2_->fillParameterSetRegistry();
425  names = triggerNames_(triggerResults);
426  if (names != 0) return *names;
427 
428  throw cms::Exception("TriggerNamesNotFound")
429  << "TriggerNames not found in ParameterSet registry";
430  return *names;
431 }
432 
435 
436  fwlite::Handle<edm::TriggerResults> hTriggerResults;
437  hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
438  if (!hTriggerResults.isValid()) {
439  return edm::TriggerResultsByName(0,0);
440  }
441 
442  edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
443 
444  if (names == 0) {
445  event1_->fillParameterSetRegistry();
446  names = triggerNames_(*hTriggerResults);
447  }
448 
449  if (names == 0) {
450  event2_->to(event1_->id());
451  event2_->fillParameterSetRegistry();
452  names = triggerNames_(*hTriggerResults);
453  }
454 
455  return edm::TriggerResultsByName(hTriggerResults.product(), names);
456 }
457 
458 //
459 // static member functions
460 //
461 void
463  char const* iModule,
464  char const* iInstance,
465  char const* iProcess) {
466  ChainEvent::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
467 }
468 }
edm::WrapperHolder getByProductID(edm::ProductID const &) const
std::vector< edm::BranchDescription > const & getBranchDescriptions() const
bool isValid() const
Definition: Handle.h:64
unsigned int EventNumber_t
Definition: EventID.h:30
MultiProductGetter(MultiChainEvent const *iEvent)
tuple lumi
Definition: fjr2json.py:35
boost::shared_ptr< ChainEvent > event2_
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:59
const MultiChainEvent & operator++()
unsigned int LuminosityBlockNumber_t
Definition: EventID.h:31
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
Definition: ChainEvent.cc:337
bool to(Long64_t iIndex)
Go to the event at index iIndex.
virtual edm::WrapperHolder getIt(edm::ProductID const &iID) const
void getByLabel(const P &iP, const char *iModuleLabel, const char *iProductInstanceLabel=0, const char *iProcessLabel=0)
Definition: Handle.h:94
const MultiChainEvent & toBegin()
Long64_t size() const
int iEvent
Definition: GenABIO.cc:243
bool toSec(Long64_t iIndex)
Go to the event from secondary files at index iIndex.
virtual edm::TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const
edm::ProcessHistory const & processHistory() const
std::vector< std::string > const & getProcessHistory() const
boost::shared_ptr< ChainEvent > event1_
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
boost::shared_ptr< internal::MultiProductGetter > getter_
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool first
Definition: L1TdeRCT.cc:94
sec_file_range_index_map secFileMapSorted_
virtual std::string const getBranchNameFor(std::type_info const &, char const *, char const *, char const *) const
static TriggerNames const * triggerNames_(edm::TriggerResults const &triggerResults)
Definition: EventBase.cc:42
virtual edm::EventAuxiliary const & eventAuxiliary() const
MultiChainEvent(std::vector< std::string > const &iFileNames1, std::vector< std::string > const &iFileNames2, bool useSecFileMapSorted=false)
std::pair< edm::EventID, edm::EventID > event_id_range
virtual edm::TriggerResultsByName triggerResultsByName(std::string const &process) const
bool isValid() const
Definition: WrapperHolder.h:27
tuple cout
Definition: gather_cfg.py:121
unsigned int RunNumber_t
Definition: EventRange.h:32
T const * product() const
Definition: Handle.h:69
tuple process
Definition: LaserDQM_cfg.py:3
static const HistoName names[]
virtual bool getByLabel(std::type_info const &, char const *, char const *, char const *, void *) const