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