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::WrapperBase const*
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_ = std::shared_ptr<ChainEvent> (new ChainEvent(iFileNames1));
63  event2_ = std::shared_ptr<ChainEvent> (new ChainEvent(iFileNames2));
64 
65  getter_ = std::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 
363 {
364  // First try the first file
365  edm::WrapperBase const* edp = event1_->getByProductID(iID);
366  // Did not find the product, try secondary file
367  if (edp == nullptr) {
368  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
369  edp = event2_->getByProductID(iID);
370  if (edp == nullptr) {
371  throw cms::Exception("ProductNotFound") << "Cannot find product " << iID;
372  }
373  }
374  return edp;
375 }
376 
377 
378 bool
380 {
381  return event1_->isValid();
382 }
384 {
385  return *event1_;
386 }
387 
388 bool
390 {
391  return event1_->atEnd();
392 }
393 
394 Long64_t
396 {
397  return event1_->size();
398 }
399 
400 edm::TriggerNames const&
402 {
403  edm::TriggerNames const* names = triggerNames_(triggerResults);
404  if (names != 0) return *names;
405 
406  event1_->fillParameterSetRegistry();
407  names = triggerNames_(triggerResults);
408  if (names != 0) return *names;
409 
410  // If we cannot find it in the primary file, this probably will
411  // not help but try anyway
412  event2_->to(event1_->id());
413  event2_->fillParameterSetRegistry();
414  names = triggerNames_(triggerResults);
415  if (names != 0) return *names;
416 
417  throw cms::Exception("TriggerNamesNotFound")
418  << "TriggerNames not found in ParameterSet registry";
419  return *names;
420 }
421 
424 
425  fwlite::Handle<edm::TriggerResults> hTriggerResults;
426  hTriggerResults.getByLabel(*this,"TriggerResults","",process.c_str());
427  if (!hTriggerResults.isValid()) {
428  return edm::TriggerResultsByName(0,0);
429  }
430 
431  edm::TriggerNames const* names = triggerNames_(*hTriggerResults);
432 
433  if (names == 0) {
434  event1_->fillParameterSetRegistry();
435  names = triggerNames_(*hTriggerResults);
436  }
437 
438  if (names == 0) {
439  event2_->to(event1_->id());
440  event2_->fillParameterSetRegistry();
441  names = triggerNames_(*hTriggerResults);
442  }
443 
444  return edm::TriggerResultsByName(hTriggerResults.product(), names);
445 }
446 
447 //
448 // static member functions
449 //
450 void
452  char const* iModule,
453  char const* iInstance,
454  char const* iProcess) {
455  ChainEvent::throwProductNotFoundException(iType,iModule,iInstance,iProcess);
456 }
457 }
std::vector< edm::BranchDescription > const & getBranchDescriptions() const
static const HistoName names[]
bool isValid() const
Definition: Handle.h:64
unsigned int EventNumber_t
Definition: EventRange.h:30
MultiProductGetter(MultiChainEvent const *iEvent)
tuple lumi
Definition: fjr2json.py:35
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:59
virtual unsigned int transitionIndex_() const override
const MultiChainEvent & operator++()
unsigned int LuminosityBlockNumber_t
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
Definition: ChainEvent.cc:327
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.
edm::WrapperBase const * getByProductID(edm::ProductID const &) 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
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
static std::string const triggerResults
Definition: EdmProvDump.cc:41
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
virtual edm::WrapperBase const * getIt(edm::ProductID const &iID) const override
static TriggerNames const * triggerNames_(edm::TriggerResults const &triggerResults)
Definition: EventBase.cc:48
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
std::shared_ptr< ChainEvent > event2_
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
std::shared_ptr< ChainEvent > event1_