CMS 3D CMS Logo

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  edm::WrapperBase const* getIt(edm::ProductID const& iID) const override { return event_->getByProductID(iID); }
35 
36  std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> getThinnedProduct(
37  edm::ProductID const& pid, unsigned int key) const override {
38  return event_->getThinnedProduct(pid, key);
39  }
40 
42  std::vector<edm::WrapperBase const*>& foundContainers,
43  std::vector<unsigned int>& keys) const override {
44  event_->getThinnedProducts(pid, foundContainers, keys);
45  }
46 
48  unsigned int key,
49  edm::ProductID const& thinned) const override {
50  return event_->getThinnedKeyFrom(parent, key, thinned);
51  }
52 
53  private:
54  unsigned int transitionIndex_() const override { return 0U; }
55 
57  };
58  } // namespace internal
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  event1_ = std::make_shared<ChainEvent>(iFileNames1);
75  event2_ = std::make_shared<ChainEvent>(iFileNames2);
76 
77  getter_ = std::make_shared<internal::MultiProductGetter>(this);
78 
79  if (event1_->size() == 0) {
80  std::cout << "------------------------------------------------------------------------" << std::endl;
81  std::cout << "WARNING! MultiChainEvent: all primary files have zero events." << std::endl;
82  std::cout << "Trying to access the events may lead to a crash. " << std::endl;
83  std::cout << "------------------------------------------------------------------------" << std::endl;
84  } else {
85  event1_->setGetter(getter_);
86  event2_->setGetter(getter_);
87  }
88 
89  useSecFileMapSorted_ = useSecFileMapSorted;
90 
91  if (!useSecFileMapSorted_) {
92  std::cout << "------------------------------------------------------------------------" << std::endl;
93  std::cout << "WARNING! What you are about to do may be very slow." << std::endl;
94  std::cout << "The 2-file solution in FWLite works with very simple assumptions." << std::endl;
95  std::cout << "It will linearly search through the files in the secondary file list for Products." << std::endl;
96  std::cout << "There are speed improvements available to make this run faster." << std::endl;
97  std::cout << "***If your secondary files are sorted with a run-range within a file, (almost always the case) "
98  << std::endl;
99  std::cout << "***please use the option useSecFileMapSorted=true in this constructor. " << std::endl;
100  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, true);" << std::endl;
101  std::cout << "------------------------------------------------------------------------" << std::endl;
102  }
103 
104  if (useSecFileMapSorted_) {
105  std::cout << "------------------------------------------------------------------------" << std::endl;
106  std::cout << "This MultiChainEvent is now creating a (run_range)_2 ---> file_index_2 map" << std::endl;
107  std::cout << "for the 2-file solution. " << std::endl;
108  std::cout
109  << "This is assuming the files you are giving me are sorted by run,event pairs within each secondary file."
110  << std::endl;
111  std::cout << "If this is not true (rarely the case), set this option to false." << std::endl;
112  std::cout << " > usage: MultiChainEvent(primaryFiles, secondaryFiles, false);" << std::endl;
113  std::cout << "------------------------------------------------------------------------" << std::endl;
114  // speed up secondary file access with a (run,event)_1 ---> index_2 map
115 
116  // Loop over events, when a new file is encountered, store the first run number from this file,
117  // and the last run number from the last file.
118  TFile* lastFile = nullptr;
119  std::pair<event_id_range, Long64_t> eventRange;
120  bool firstFile = true;
121 
122  bool foundAny = false;
123 
124  for (event2_->toBegin(); !event2_->atEnd(); ++(*event2_)) {
125  // if we have a new file, cache the "first"
126  if (lastFile != event2_->getTFile()) {
127  // if this is not the first file, we have an entry.
128  // Add it to the list.
129  if (!firstFile) {
130  foundAny = true;
133  }
134  // always add the "first" event id to the cached event range
135  eventRange.first.first = event2_->event()->id();
136  lastFile = event2_->getTFile();
137  }
138  // otherwise, cache the "second" event id in the cached event range.
139  // Upon the discovery of a new file, this will be used as the
140  // "last" event id in the cached event range.
141  else {
142  eventRange.first.second = event2_->event()->id();
143  eventRange.second = event2_->eventIndex();
144  }
145  firstFile = false;
146  }
147  // due to the invailability of a "look ahead" operation, we have one additional "put" to make
148  // after the loop (which puts the "last" event, not "this" event.
149  if (foundAny) {
152  }
153  // std::cout << "Dumping run range to event id list:" << std::endl;
154  // for (sec_file_range_index_map::const_iterator mBegin = secFileMapSorted_.begin(),
155  // mEnd = secFileMapSorted_.end(),
156  // mit = mBegin;
157  // mit != mEnd; ++mit) {
158  // char buff[1000];
159  // event2_->to(mit->second);
160  // sprintf(buff, "[%10d,%10d - %10d,%10d] ---> %10d",
161  // mit->first.first.run(),
162  // mit->first.first.event(),
163  // mit->first.second.run(),
164  // mit->first.second.event(),
165  // mit->second);
166  // std::cout << buff << std::endl;
167  // }
168  }
169  }
170 
171  // MultiChainEvent::MultiChainEvent(const MultiChainEvent& rhs)
172  // {
173  // // do actual copying here;
174  // }
175 
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 
195  event1_->operator++();
196  return *this;
197  }
198 
200  bool MultiChainEvent::to(Long64_t iIndex) { return event1_->to(iIndex); }
201 
203  bool MultiChainEvent::to(edm::EventID id) { return to(id.run(), id.luminosityBlock(), id.event()); }
204 
207  return event1_->to(run, lumi, event);
208  }
209 
212 
214  bool MultiChainEvent::toSec(Long64_t iIndex) { return event2_->to(iIndex); }
215 
216  // Go to event with event id "id"
218  // First try this file.
219  if (event2_->event_->to(id)) {
220  // Found it, return.
221  return true;
222  }
223  // Second, assume that the secondary files are each in run/event
224  // order. So, let's loop over all files and see if we can figure
225  // out where the event ought to be.
226  for (sec_file_range_index_map::const_iterator mBegin = secFileMapSorted_.begin(),
227  mEnd = secFileMapSorted_.end(),
228  mit = mBegin;
229  mit != mEnd;
230  ++mit) {
231  if (id < mit->first.first || id > mit->first.second) {
232  // We don't expect this event to be in this file, so don't
233  // bother checking it right now.
234  continue;
235  }
236  // If we're here, then we have a reasonable belief that this
237  // event is in this secondary file. This part is
238  // expensive. switchToFile does memory allocations and opens the
239  // files which becomes very time consuming. This should be done
240  // as infrequently as possible.
241  event2_->switchToFile(mit->second);
242  // Is it here?
243  if (event2_->to(id)) {
244  // Yes!
245  return true;
246  }
247  // if we assumed that the secondary files were not each in
248  // order, but were non-overlapping, we could break here. But at
249  // this point, we might as well keep going.
250  } // for loop over files
251 
252  // if we are still here, then we did not find the id in question,
253  // do it the old fashioned way. This will open up each secondary
254  // file and explicitly check to see if the event is there.
255  if (event2_->to(id)) {
256  return true;
257  }
258  // if we're still here, then there really is no matching event in
259  // the secondary files. Throw.
260  throw cms::Exception("ProductNotFound")
261  << "Cannot find id " << id.run() << ", " << id.event() << " in secondary list. Exiting." << std::endl;
262  // to make the compiler happy
263  return false;
264  }
265 
268  return toSec(edm::EventID(run, lumi, event));
269  }
270 
271  // Go to the very first Event
274  return toSec(edm::EventID(run, 0U, event));
275  }
276 
277  // Go to the very first Event
279  event1_->toBegin();
280  return *this;
281  }
282 
283  //
284  // const member functions
285  //
286  std::string const MultiChainEvent::getBranchNameFor(std::type_info const& iType,
287  char const* iModule,
288  char const* iInstance,
289  char const* iProcess) const {
290  return event1_->getBranchNameFor(iType, iModule, iInstance, iProcess);
291  }
292 
293  std::vector<edm::BranchDescription> const& MultiChainEvent::getBranchDescriptions() const {
294  return event1_->getBranchDescriptions();
295  }
296 
297  std::vector<std::string> const& MultiChainEvent::getProcessHistory() const { return event1_->getProcessHistory(); }
298 
299  edm::ProcessHistory const& MultiChainEvent::processHistory() const { return event1_->processHistory(); }
300 
301  edm::EventAuxiliary const& MultiChainEvent::eventAuxiliary() const { return event1_->eventAuxiliary(); }
302 
303  bool MultiChainEvent::getByLabel(std::type_info const& iType,
304  char const* iModule,
305  char const* iInstance,
306  char const* iProcess,
307  void* iValue) const {
308  bool ret1 = event1_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
309  if (!ret1) {
310  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
311  bool ret2 = event2_->getByLabel(iType, iModule, iInstance, iProcess, iValue);
312  if (!ret2)
313  return false;
314  }
315  return true;
316  }
317 
319  // First try the first file
320  edm::WrapperBase const* edp = event1_->getByProductID(iID);
321  // Did not find the product, try secondary file
322  if (edp == nullptr) {
323  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
324  edp = event2_->getByProductID(iID);
325  }
326  return edp;
327  }
328 
329  std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> MultiChainEvent::getThinnedProduct(
330  edm::ProductID const& pid, unsigned int key) const {
331  // First try the first file
332  auto edp = event1_->getThinnedProduct(pid, key);
333  // Did not find the product, try secondary file
334  if (not edp.has_value()) {
335  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
336  edp = event2_->getThinnedProduct(pid, key);
337  }
338  return edp;
339  }
340 
342  std::vector<edm::WrapperBase const*>& wrappers,
343  std::vector<unsigned int>& keys) const {
344  // First try the first file
345  event1_->getThinnedProducts(pid, wrappers, keys);
346  // Did not find all the products, try secondary file
347  if (std::find(wrappers.begin(), wrappers.end(), nullptr) != wrappers.end()) {
348  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
349  event2_->getThinnedProducts(pid, wrappers, keys);
350  }
351  }
352 
354  unsigned int key,
355  edm::ProductID const& thinned) const {
356  // First try the first file
357  auto edp = event1_->getThinnedKeyFrom(parent, key, thinned);
358  // Did not find the product, try secondary file
359  if (std::holds_alternative<std::monostate>(edp)) {
360  (const_cast<MultiChainEvent*>(this))->toSec(event1_->id());
361  edp = event2_->getThinnedKeyFrom(parent, key, thinned);
362  }
363  return edp;
364  }
365 
366  bool MultiChainEvent::isValid() const { return event1_->isValid(); }
367  MultiChainEvent::operator bool() const { return *event1_; }
368 
369  bool MultiChainEvent::atEnd() const { return event1_->atEnd(); }
370 
371  Long64_t MultiChainEvent::size() const { return event1_->size(); }
372 
375  if (names != nullptr)
376  return *names;
377 
378  event1_->fillParameterSetRegistry();
380  if (names != nullptr)
381  return *names;
382 
383  // If we cannot find it in the primary file, this probably will
384  // not help but try anyway
385  event2_->to(event1_->id());
386  event2_->fillParameterSetRegistry();
388  if (names != nullptr)
389  return *names;
390 
391  throw cms::Exception("TriggerNamesNotFound") << "TriggerNames not found in ParameterSet registry";
392  return *names;
393  }
394 
397 
398  if (names == nullptr) {
399  event1_->fillParameterSetRegistry();
401  }
402 
403  if (names == nullptr) {
404  event2_->to(event1_->id());
405  event2_->fillParameterSetRegistry();
407  }
408 
410  }
411 
413  auto pset = event1_->parameterSet(psID);
414  if (nullptr == pset) {
415  pset = event2_->parameterSet(psID);
416  }
417  return pset;
418  }
419  //
420  // static member functions
421  //
422  void MultiChainEvent::throwProductNotFoundException(std::type_info const& iType,
423  char const* iModule,
424  char const* iInstance,
425  char const* iProcess) {
426  ChainEvent::throwProductNotFoundException(iType, iModule, iInstance, iProcess);
427  }
428 } // namespace fwlite
fwlite::internal::MultiProductGetter
Definition: MultiChainEvent.cc:30
edm::RunNumber_t
unsigned int RunNumber_t
Definition: RunLumiEventNumber.h:14
fwlite::MultiChainEvent::getProcessHistory
std::vector< std::string > const & getProcessHistory() const
Definition: MultiChainEvent.cc:297
electrons_cff.bool
bool
Definition: electrons_cff.py:366
Handle.h
TriggerResults.h
fwlite
Definition: TFileDirectory.h:16
fwlite::MultiChainEvent::operator++
const MultiChainEvent & operator++() override
Definition: MultiChainEvent.cc:194
fwlite::MultiChainEvent::atEnd
bool atEnd() const override
Definition: MultiChainEvent.cc:369
fwlite::internal::MultiProductGetter::getThinnedProduct
std::optional< std::tuple< edm::WrapperBase const *, unsigned int > > getThinnedProduct(edm::ProductID const &pid, unsigned int key) const override
Definition: MultiChainEvent.cc:36
gather_cfg.cout
cout
Definition: gather_cfg.py:144
fwlite::MultiChainEvent::event1_
std::shared_ptr< ChainEvent > event1_
Definition: MultiChainEvent.h:150
triggerResults
static const std::string triggerResults
Definition: EdmProvDump.cc:45
fwlite::ChainEvent::throwProductNotFoundException
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
Definition: ChainEvent.cc:269
relativeConstraints.keys
keys
Definition: relativeConstraints.py:89
fwlite::MultiChainEvent
Definition: MultiChainEvent.h:50
spr::find
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
edm::LuminosityBlockNumber_t
unsigned int LuminosityBlockNumber_t
Definition: RunLumiEventNumber.h:13
fwlite::MultiChainEvent::isValid
bool isValid() const
Definition: MultiChainEvent.cc:366
fwlite::MultiChainEvent::getByLabel
bool getByLabel(std::type_info const &, char const *, char const *, char const *, void *) const override
Definition: MultiChainEvent.cc:303
fwlite::internal::MultiProductGetter::transitionIndex_
unsigned int transitionIndex_() const override
Definition: MultiChainEvent.cc:54
Utilities.operator
operator
Definition: Utilities.py:24
edm::EDProductGetter
Definition: EDProductGetter.h:41
fwlite::MultiChainEvent::getBranchNameFor
const std::string getBranchNameFor(std::type_info const &, char const *, char const *, char const *) const override
Definition: MultiChainEvent.cc:286
fwlite::MultiChainEvent::MultiChainEvent
MultiChainEvent(std::vector< std::string > const &iFileNames1, std::vector< std::string > const &iFileNames2, bool useSecFileMapSorted=false)
Definition: MultiChainEvent.cc:71
fwlite::MultiChainEvent::useSecFileMapSorted_
bool useSecFileMapSorted_
Definition: MultiChainEvent.h:158
MultiChainEvent.h
ProcessHistory.h
names
const std::string names[nVars_]
Definition: PhotonIDValueMapProducer.cc:124
fwlite::internal::MultiProductGetter::getThinnedProducts
void getThinnedProducts(edm::ProductID const &pid, std::vector< edm::WrapperBase const * > &foundContainers, std::vector< unsigned int > &keys) const override
Definition: MultiChainEvent.cc:41
edm::Hash< ParameterSetType >
edm::EventNumber_t
unsigned long long EventNumber_t
Definition: RunLumiEventNumber.h:12
first
auto first
Definition: CAHitNtupletGeneratorKernelsImpl.h:112
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
edm::EventAuxiliary
Definition: EventAuxiliary.h:14
AlCaHLTBitMon_QueryRunRegistry.string
string
Definition: AlCaHLTBitMon_QueryRunRegistry.py:256
fwlite::MultiChainEvent::throwProductNotFoundException
static void throwProductNotFoundException(std::type_info const &, char const *, char const *, char const *)
Definition: MultiChainEvent.cc:422
fwlite::MultiChainEvent::getThinnedProducts
void getThinnedProducts(edm::ProductID const &pid, std::vector< edm::WrapperBase const * > &foundContainers, std::vector< unsigned int > &keys) const
Definition: MultiChainEvent.cc:341
fwlite::MultiChainEvent::getByProductID
edm::WrapperBase const * getByProductID(edm::ProductID const &) const override
Definition: MultiChainEvent.cc:318
fwlite::MultiChainEvent::getBranchDescriptions
std::vector< edm::BranchDescription > const & getBranchDescriptions() const
Definition: MultiChainEvent.cc:293
edm::ParameterSet
Definition: ParameterSet.h:47
fwlite::MultiChainEvent::getter_
std::shared_ptr< internal::MultiProductGetter const > getter_
Definition: MultiChainEvent.h:152
edm::EventBase::luminosityBlock
edm::LuminosityBlockNumber_t luminosityBlock() const
Definition: EventBase.h:61
fwlite::MultiChainEvent::to
bool to(Long64_t iIndex)
Go to the event at index iIndex.
Definition: MultiChainEvent.cc:200
edmPickEvents.event
event
Definition: edmPickEvents.py:273
iEvent
int iEvent
Definition: GenABIO.cc:224
edm::TriggerResultsByName
Definition: TriggerResultsByName.h:48
fwlite::internal::MultiProductGetter::event_
MultiChainEvent const * event_
Definition: MultiChainEvent.cc:56
edm::WrapperBase
Definition: WrapperBase.h:23
fwlite::internal::MultiProductGetter::getIt
edm::WrapperBase const * getIt(edm::ProductID const &iID) const override
Definition: MultiChainEvent.cc:34
fwlite::MultiChainEvent::triggerNames
edm::TriggerNames const & triggerNames(edm::TriggerResults const &triggerResults) const override
Definition: MultiChainEvent.cc:373
fwlite::internal::MultiProductGetter::MultiProductGetter
MultiProductGetter(MultiChainEvent const *iEvent)
Definition: MultiChainEvent.cc:32
fwlite::MultiChainEvent::triggerResultsByName
edm::TriggerResultsByName triggerResultsByName(edm::TriggerResults const &triggerResults) const override
Definition: MultiChainEvent.cc:395
edm::OptionalThinnedKey
std::variant< unsigned int, detail::GetThinnedKeyFromExceptionFactory, std::monostate > OptionalThinnedKey
Definition: EDProductGetter.h:39
writedatasetfile.run
run
Definition: writedatasetfile.py:27
fwlite::MultiChainEvent::size
Long64_t size() const
Definition: MultiChainEvent.cc:371
fwlite::MultiChainEvent::parameterSet
edm::ParameterSet const * parameterSet(edm::ParameterSetID const &psID) const override
Definition: MultiChainEvent.cc:412
fwlite::MultiChainEvent::toSec
bool toSec(Long64_t iIndex)
Go to the event from secondary files at index iIndex.
Definition: MultiChainEvent.cc:214
Exception
Definition: hltDiff.cc:245
fwlite::MultiChainEvent::toBegin
const MultiChainEvent & toBegin() override
Definition: MultiChainEvent.cc:278
edm::TriggerNames
Definition: TriggerNames.h:55
fwlite::MultiChainEvent::getThinnedKeyFrom
edm::OptionalThinnedKey getThinnedKeyFrom(edm::ProductID const &parent, unsigned int key, edm::ProductID const &thinned) const
Definition: MultiChainEvent.cc:353
fwlite::MultiChainEvent::event2_
std::shared_ptr< ChainEvent > event2_
Definition: MultiChainEvent.h:151
unittestinputsource_cfi.eventRange
eventRange
Definition: unittestinputsource_cfi.py:115
internal
Definition: ROOTFilePB.pb.h:38
edm::EventBase::triggerNames_
static TriggerNames const * triggerNames_(edm::TriggerResults const &triggerResults)
Definition: EventBase.cc:45
EDProductGetter.h
fwlite::MultiChainEvent::secFileMapSorted_
sec_file_range_index_map secFileMapSorted_
Definition: MultiChainEvent.h:159
edm::ProcessHistory
Definition: ProcessHistory.h:13
fwlite::MultiChainEvent::event_id_range
std::pair< edm::EventID, edm::EventID > event_id_range
Definition: MultiChainEvent.h:53
fwlite::MultiChainEvent::~MultiChainEvent
~MultiChainEvent() override
Definition: MultiChainEvent.cc:176
fwlite::internal::MultiProductGetter::getThinnedKeyFrom
edm::OptionalThinnedKey getThinnedKeyFrom(edm::ProductID const &parent, unsigned int key, edm::ProductID const &thinned) const override
Definition: MultiChainEvent.cc:47
event
Definition: event.py:1
edm::EventID
Definition: EventID.h:31
crabWrapper.key
key
Definition: crabWrapper.py:19
lumi
Definition: LumiSectionData.h:20
HLT_FULL_cff.toAdd
toAdd
Definition: HLT_FULL_cff.py:52132
TriggerResultsByName.h
fwlite::MultiChainEvent::getThinnedProduct
std::optional< std::tuple< edm::WrapperBase const *, unsigned int > > getThinnedProduct(edm::ProductID const &pid, unsigned int key) const
Definition: MultiChainEvent.cc:329
class-composition.parent
parent
Definition: class-composition.py:88
edm::TriggerResults
Definition: TriggerResults.h:35
fwlite::MultiChainEvent::processHistory
edm::ProcessHistory const & processHistory() const override
Definition: MultiChainEvent.cc:299
edm::ProductID
Definition: ProductID.h:27
muonDTDigis_cfi.pset
pset
Definition: muonDTDigis_cfi.py:27
fwlite::MultiChainEvent::eventAuxiliary
edm::EventAuxiliary const & eventAuxiliary() const override
Definition: MultiChainEvent.cc:301