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 #include <iostream>
15 
16 // user include files
23 
24 namespace fwlite {
25 
26  namespace internal {
27 
29 public:
31 
32  virtual edm::WrapperHolder
33  getIt(edm::ProductID const& iID) const override {
34  return event_->getByProductID(iID);
35  }
36 
37 private:
38  virtual unsigned int transitionIndex_() const override {
39  return 0U;
40  }
41 
43 
44  };
45  }
46 
47 //
48 // constants, enums and typedefs
49 //
50 
51 //
52 // static data member definitions
53 //
54 
55 //
56 // constructors and destructor
57 //
58  MultiChainEvent::MultiChainEvent(std::vector<std::string> const& iFileNames1,
59  std::vector<std::string> const& iFileNames2,
60  bool useSecFileMapSorted)
61 {
62  event1_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames1));
63  event2_ = boost::shared_ptr<ChainEvent> (new ChainEvent(iFileNames2));
64 
65  getter_ = boost::shared_ptr<internal::MultiProductGetter>(new internal::MultiProductGetter(this));
66 
67  event1_->setGetter(getter_);
68  event2_->setGetter(getter_);
69 
70  useSecFileMapSorted_ = useSecFileMapSorted;
71 
72  if (!useSecFileMapSorted_) {
73  std::cout << "------------------------------------------------------------------------" << std::endl;
74  std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
75  std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
76  std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
77  std::cout << "There are speed improvements available to make this run faster." << std::endl;
78  std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) " << std::endl;
79  std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
80  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, true);" << std::endl;
81  std::cout << "------------------------------------------------------------------------" << std::endl;
82 
83  }
84 
86 
87  std::cout << "------------------------------------------------------------------------" << std::endl;
88  std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
89  std::cout << "for the 2-file solution. " << std::endl;
90  std::cout << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file." << std::endl;
91  std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
92  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, false);" << std::endl;
93  std::cout << "------------------------------------------------------------------------" << std::endl;
94  // speed up secondary file access with a (run,event)_1 ---> index_2 map
95 
96 
97  // Loop over events, when a new file is encountered, store the first run number from this file,
98  // and the last run number from the last file.
99  TFile * lastFile = 0;
100  std::pair<event_id_range,Long64_t> eventRange;
101  bool firstFile = true;
102 
103  bool foundAny = false;
104 
105  for(event2_->toBegin();
106  ! event2_->atEnd();
107  ++(*event2_)) {
108  // if we have a new file, cache the "first"
109  if (lastFile != event2_->getTFile()) {
110 
111  // if this is not the first file, we have an entry.
112  // Add it to the list.
113  if (!firstFile) {
114  foundAny = true;
115  event_id_range toAdd = eventRange.first;
116  secFileMapSorted_[ toAdd ] = eventRange.second;
117  }
118  // always add the "first" event id to the cached event range
119  eventRange.first.first = event2_->event()->id();
120  lastFile = event2_->getTFile();
121  }
122  // otherwise, cache the "second" event id in the cached event range.
123  // Upon the discovery of a new file, this will be used as the
124  // "last" event id in the cached event range.
125  else {
126  eventRange.first.second = event2_->event()->id();
127  eventRange.second = event2_->eventIndex();
128  }
129  firstFile = false;
130  }
131  // due to the invailability of a "look ahead" operation, we have one additional "put" to make
132  // after the loop (which puts the "last" event, not "this" event.
133  if (foundAny) {
134  event_id_range toAdd = eventRange.first;
135  secFileMapSorted_[ toAdd ] = eventRange.second;
136  }
137 // std::cout << "Dumping run range to event id list:" << std::endl;
138 // for (sec_file_range_index_map::const_iterator mBegin = secFileMapSorted_.begin(),
139 // mEnd = secFileMapSorted_.end(),
140 // mit = mBegin;
141 // mit != mEnd; ++mit) {
142 // char buff[1000];
143 // event2_->to(mit->second);
144 // sprintf(buff, "[%10d,%10d - %10d,%10d] ---> %10d",
145 // mit->first.first.run(),
146 // mit->first.first.event(),
147 // mit->first.second.run(),
148 // mit->first.second.event(),
149 // mit->second);
150 // std::cout << buff << std::endl;
151 // }
152  }
153 
154 }
155 
156 // MultiChainEvent::MultiChainEvent(const MultiChainEvent& rhs)
157 // {
158 // // do actual copying here;
159 // }
160 
162 {
163 }
164 
165 //
166 // assignment operators
167 //
168 // const MultiChainEvent& MultiChainEvent::operator=(const MultiChainEvent& rhs)
169 // {
170 // //An exception safe implementation is
171 // MultiChainEvent temp(rhs);
172 // swap(rhs);
173 //
174 // return *this;
175 // }
176 
177 //
178 // member functions
179 //
180 
181 const MultiChainEvent&
183 {
184  event1_->operator++();
185  return *this;
186 }
187 
189 bool
190 MultiChainEvent::to(Long64_t iIndex)
191 {
192  return event1_->to(iIndex);
193 }
194 
195 
197 bool
199 {
200  return to(id.run(), id.luminosityBlock(), id.event());
201 }
202 
204 bool
206 {
207  return event1_->to(run, lumi, event);
208 }
209 
211 bool
213 {
214  return to(run, 0U, event);
215 }
216 
217 
219 bool
220 MultiChainEvent::toSec(Long64_t iIndex)
221 {
222  return event2_->to(iIndex);
223 }
224 
225 // Go to event with event id "id"
226 bool
228 {
229  // First try this file.
230  if (event2_->event_->to(id))
231  {
232  // Found it, return.
233  return true;
234  }
235  // Second, assume that the secondary files are each in run/event
236  // order. So, let's loop over all files and see if we can figure
237  // out where the event ought to be.
238  for (sec_file_range_index_map::const_iterator mBegin =
239  secFileMapSorted_.begin(),
240  mEnd = secFileMapSorted_.end(),
241  mit = mBegin;
242  mit != mEnd;
243  ++mit)
244  {
245  if (id < mit->first.first || id > mit->first.second)
246  {
247  // We don't expect this event to be in this file, so don't
248  // bother checking it right now.
249  continue;
250  }
251  // If we're here, then we have a reasonable belief that this
252  // event is in this secondary file. This part is
253  // expensive. switchToFile does memory allocations and opens the
254  // files which becomes very time consuming. This should be done
255  // as infrequently as possible.
256  event2_->switchToFile(mit->second);
257  // Is it here?
258  if (event2_->to(id))
259  {
260  // Yes!
261  return true;
262  }
263  // if we assumed that the secondary files were not each in
264  // order, but were non-overlapping, we could break here. But at
265  // this point, we might as well keep going.
266  } // for loop over files
267 
268  // if we are still here, then we did not find the id in question,
269  // do it the old fashioned way. This will open up each secondary
270  // file and explicitly check to see if the event is there.
271  if (event2_->to(id))
272  {
273  return true;
274  }
275  // if we're still here, then there really is no matching event in
276  // the secondary files. Throw.
277  throw cms::Exception("ProductNotFound") << "Cannot find id "
278  << id.run() << ", "
279  << id.event()
280  << " in secondary list. Exiting."
281  << std::endl;
282  // to make the compiler happy
283  return false;
284 }
285 
287 bool
289 {
290  return toSec(edm::EventID(run, lumi, event));
291 }
292 
293 // Go to the very first Event
295 bool
297 {
298  return toSec(edm::EventID(run, 0U, event));
299 }
300 
301 // Go to the very first Event
302 const MultiChainEvent&
304 {
305  event1_->toBegin();
306  return *this;
307 }
308 
309 //
310 // const member functions
311 //
312 std::string const
313 MultiChainEvent::getBranchNameFor(std::type_info const& iType,
314  char const* iModule,
315  char const* iInstance,
316  char const* iProcess) const
317 {
318  return event1_->getBranchNameFor(iType,iModule,iInstance,iProcess);
319 }
320 
321 std::vector<edm::BranchDescription> const&
323 {
324  return event1_->getBranchDescriptions();
325 }
326 
327 std::vector<std::string> const&
329 {
330  return event1_->getProcessHistory();
331 }
332 
333 edm::ProcessHistory const&
335 {
336  return event1_->processHistory();
337 }
338 
339 edm::EventAuxiliary const&
341 {
342  return event1_->eventAuxiliary();
343 }
344 
345 bool
347  std::type_info const& iType,
348  char const* iModule,
349  char const* iInstance,
350  char const* iProcess,
351  void* iValue) const
352 {
353  bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
354  if (!ret1) {
355  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
356  bool ret2 = event2_->getByLabel(iType,iModule,iInstance,iProcess,iValue);
357  if (!ret2) return false;
358  }
359  return true;
360 }
361 
362 bool
364  std::type_info const& iType,
365  char const* iModule,
366  char const* iInstance,
367  char const* iProcess,
368  edm::WrapperHolder& holder) const {
369  bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, holder);
370  if(!ret1) {
371  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
372  bool ret2 = event2_->getByLabel(iType, iModule, iInstance, iProcess, holder);
373  if(!ret2) return false;
374  }
375  return true;
376 }
377 
379 {
380  // First try the first file
381  edm::WrapperHolder edp = event1_->getByProductID(iID);
382  // Did not find the product, try secondary file
383  if (!edp.isValid()) {
384  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
385  edp = event2_->getByProductID(iID);
386  if (!edp.isValid()) {
387  throw cms::Exception("ProductNotFound") << "Cannot find product " << iID;
388  }
389  }
390  return edp;
391 }
392 
393 
394 bool
396 {
397  return event1_->isValid();
398 }
400 {
401  return *event1_;
402 }
403 
404 bool
406 {
407  return event1_->atEnd();
408 }
409 
410 Long64_t
412 {
413  return event1_->size();
414 }
415 
416 edm::TriggerNames const&
418 {
419  edm::TriggerNames const* names = triggerNames_(triggerResults);
420  if (names != 0) return *names;
421 
422  event1_->fillParameterSetRegistry();
423  names = triggerNames_(triggerResults);
424  if (names != 0) return *names;
425 
426  // If we cannot find it in the primary file, this probably will
427  // not help but try anyway
428  event2_->to(event1_->id());
429  event2_->fillParameterSetRegistry();
430  names = triggerNames_(triggerResults);
431  if (names != 0) return *names;
432 
433  throw cms::Exception("TriggerNamesNotFound")
434  << "TriggerNames not found in ParameterSet registry";
435  return *names;
436 }
437 
440 
441  fwlite::Handle<edm::TriggerResults> hTriggerResults;
442  hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
443  if (!hTriggerResults.isValid()) {
444  return edm::TriggerResultsByName(0,0);
445  }
446 
447  edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
448 
449  if (names == 0) {
450  event1_->fillParameterSetRegistry();
451  names = triggerNames_(*hTriggerResults);
452  }
453 
454  if (names == 0) {
455  event2_->to(event1_->id());
456  event2_->fillParameterSetRegistry();
457  names = triggerNames_(*hTriggerResults);
458  }
459 
460  return edm::TriggerResultsByName(hTriggerResults.product(), names);
461 }
462 
463 //
464 // static member functions
465 //
466 void
468  char const* iModule,
469  char const* iInstance,
470  char const* iProcess) {
471  ChainEvent::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
472 }
473 }
edm::WrapperHolder getByProductID(edm::ProductID const &) const
std::vector< edm::BranchDescription > const & getBranchDescriptions() const
static const HistoName names[]
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
virtual edm::WrapperHolder getIt(edm::ProductID const &iID) const override
boost::shared_ptr< ChainEvent > event2_
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:59
virtual unsigned int transitionIndex_() const override
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.
string firstFile
Definition: archive.py:470
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:230
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 *)
static std::string const triggerResults
Definition: EdmProvDump.cc:41
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:75
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:49
tuple lastFile
Definition: archive.py:471
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
virtual bool getByLabel(std::type_info const &, char const *, char const *, char const *, void *) const