CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
IndexIntoFile.cc
Go to the documentation of this file.
5 
6 #include <algorithm>
7 #include <iomanip>
8 #include <ostream>
9 
10 namespace edm {
11 
17 
18  IndexIntoFile::Transients::Transients() : previousAddedIndex_(invalidIndex),
19  runToFirstEntry_(),
20  lumiToFirstEntry_(),
21  beginEvents_(invalidEntry),
22  endEvents_(invalidEntry),
23  currentIndex_(invalidIndex),
24  currentRun_(invalidRun),
25  currentLumi_(invalidLumi),
26  numberOfEvents_(0),
27  eventFinder_(),
28  runOrLumiIndexes_(),
29  eventNumbers_(),
30  eventEntries_(),
31  unsortedEventNumbers_() {
32  }
33 
34  void
36  previousAddedIndex_ = invalidIndex;
37  runToFirstEntry_.clear();
38  lumiToFirstEntry_.clear();
39  beginEvents_ = invalidEntry;
40  endEvents_ = invalidEntry;
41  currentIndex_ = invalidIndex;
42  currentRun_ = invalidRun;
43  currentLumi_ = invalidLumi;
44  numberOfEvents_ = 0;
45  eventFinder_ = nullptr; // propagate_const<T> has no reset() function
46  runOrLumiIndexes_.clear();
47  eventNumbers_.clear();
48  eventEntries_.clear();
49  unsortedEventNumbers_.clear();
50  }
51 
55  }
56 
58  }
59 
61  return processHistoryIDs_.at(i);
62  }
63 
64  std::vector<ProcessHistoryID> const& IndexIntoFile::processHistoryIDs() const {
65  return processHistoryIDs_;
66  }
67 
68  void
69  IndexIntoFile::addEntry(ProcessHistoryID const& processHistoryID,
74  int index = 0;
75  // First see if the ProcessHistoryID is the same as the previous one.
76  // This is just a performance optimization. We expect to usually get
77  // many in a row that are the same.
79  processHistoryID == processHistoryIDs_[previousAddedIndex()]) {
80  index = previousAddedIndex();
81  } else {
82  // If it was not the same as the previous one then search through the
83  // entire vector. If it is not there, it needs to be added at the
84  // end.
85  index = 0;
86  while(index < static_cast<int>(processHistoryIDs_.size()) &&
87  processHistoryIDs_[index] != processHistoryID) {
88  ++index;
89  }
90  if(index == static_cast<int>(processHistoryIDs_.size())) {
91  processHistoryIDs_.push_back(processHistoryID);
92  }
93  }
95 
96  assert((currentRun() == run && currentIndex() == index) || currentRun() == invalidRun);
97  if(lumi == invalidLumi) {
98  if(currentLumi() != invalidLumi) {
100  << "In IndexIntoFile::addEntry. Entries were added in illegal order.\n"
101  << "This means the IndexIntoFile product in the output file will be corrupted.\n"
102  << "The output file will be unusable for most purposes.\n"
103  << "If this occurs after an unrelated exception was thrown in\n"
104  << "endLuminosityBlock or endRun then ignore this exception and fix\n"
105  << "the primary exception. This is an expected side effect.\n"
106  << "Otherwise please report this to the core framework developers\n";
107  }
111  std::pair<IndexRunKey, EntryNumber_t> firstRunEntry(IndexRunKey(index, run), entry);
112  runToFirstEntry().insert(firstRunEntry);
113  RunOrLumiEntry runEntry(runToFirstEntry()[IndexRunKey(index, run)], invalidEntry, entry, index, run, lumi, invalidEntry, invalidEntry);
114  runOrLumiEntries_.push_back(runEntry);
115  } else {
116  assert(currentLumi() == lumi || currentLumi() == invalidLumi);
117  if(currentRun() == invalidRun) {
118  currentRun() = run;
119  currentIndex() = index;
120  }
121  if(event == invalidEvent) {
123  std::pair<IndexRunLumiKey, EntryNumber_t> firstLumiEntry(IndexRunLumiKey(index, run, lumi), entry);
124  lumiToFirstEntry().insert(firstLumiEntry);
125  RunOrLumiEntry lumiEntry(invalidEntry, lumiToFirstEntry()[IndexRunLumiKey(index, run, lumi)],
126  entry, index, run, lumi, beginEvents(), endEvents());
127  runOrLumiEntries_.push_back(lumiEntry);
130  } else {
132  if(beginEvents() == invalidEntry) {
133  currentLumi() = lumi;
134  beginEvents() = entry;
135  endEvents() = beginEvents() + 1;
136  }
137  else {
138  assert(currentLumi() == lumi);
139  assert(entry == endEvents());
140  ++endEvents();
141  }
142  }
143  }
144  }
145 
147  if(runOrLumiEntries_.empty() || !runOrLumiIndexes().empty()) {
148  return;
149  }
150  runOrLumiIndexes().reserve(runOrLumiEntries_.size());
151 
152  int index = 0;
153  for(RunOrLumiEntry const& item : runOrLumiEntries_) {
154  runOrLumiIndexes().emplace_back(item.processHistoryIDIndex(),
155  item.run(),
156  item.lumi(),
157  index);
158  ++index;
159  }
161 
162  long long beginEventNumbers = 0;
163 
164  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
165  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
166  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
167  while(true) {
168  while(beginOfLumi != iEnd && beginOfLumi->isRun()) {
169  ++beginOfLumi;
170  }
171  if(beginOfLumi == iEnd) break;
172 
173  endOfLumi = beginOfLumi + 1;
174  while(endOfLumi != iEnd &&
175  beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
176  beginOfLumi->run() == endOfLumi->run() &&
177  beginOfLumi->lumi() == endOfLumi->lumi()) {
178  ++endOfLumi;
179  }
180  int nEvents = 0;
181  for(std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi;
182  iter != endOfLumi;
183  ++iter) {
184  if(runOrLumiEntries_[iter->indexToGetEntry()].beginEvents() != invalidEntry) {
185  nEvents += runOrLumiEntries_[iter->indexToGetEntry()].endEvents() -
186  runOrLumiEntries_[iter->indexToGetEntry()].beginEvents();
187  }
188  }
189  for(std::vector<RunOrLumiIndexes>::iterator iter = beginOfLumi;
190  iter != endOfLumi;
191  ++iter) {
192  iter->setBeginEventNumbers(beginEventNumbers);
193  iter->setEndEventNumbers(beginEventNumbers + nEvents);
194  }
195  beginEventNumbers += nEvents;
196  beginOfLumi = endOfLumi;
197  }
198  assert(runOrLumiIndexes().size() == runOrLumiEntries_.size());
199  }
200 
201  void
203  fillEventNumbersOrEntries(true, false);
204  }
205 
206  void
208  fillEventNumbersOrEntries(false, true);
209  }
210 
211  void
212  IndexIntoFile::fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const {
213  if(numberOfEvents() == 0) {
214  return;
215  }
216 
217  if(needEventNumbers && !eventNumbers().empty()) {
218  needEventNumbers = false;
219  }
220 
221  if(needEventEntries && !eventEntries().empty()) {
222  needEventEntries = false;
223  }
224 
225  if(needEventNumbers && !eventEntries().empty()) {
227  eventNumbers().reserve(eventEntries().size());
229  eventNumbers().push_back(eventEntries()[entry].event());
230  }
231  return;
232  }
233 
234  if(!needEventNumbers && !needEventEntries) {
235  return;
236  }
237 
239 
240  if(needEventNumbers) {
242  }
243  if(needEventEntries) {
244  eventEntries().resize(numberOfEvents());
245  }
246 
247  long long offset = 0;
248  long long previousBeginEventNumbers = -1LL;
249 
250  for(SortedRunOrLumiItr runOrLumi = beginRunOrLumi(), runOrLumiEnd = endRunOrLumi();
251  runOrLumi != runOrLumiEnd; ++runOrLumi) {
252 
253  if(runOrLumi.isRun()) continue;
254 
255  long long beginEventNumbers = 0;
256  long long endEventNumbers = 0;
257  EntryNumber_t beginEventEntry = invalidEntry;
258  EntryNumber_t endEventEntry = invalidEntry;
259  runOrLumi.getRange(beginEventNumbers, endEventNumbers, beginEventEntry, endEventEntry);
260 
261  // This is true each time one hits a new lumi section (except if the previous lumi had
262  // no events, in which case the offset is still 0 anyway)
263  if(beginEventNumbers != previousBeginEventNumbers) offset = 0;
264 
265  for(EntryNumber_t entry = beginEventEntry; entry != endEventEntry; ++entry) {
266  if(needEventNumbers) {
267  eventNumbers().at((entry - beginEventEntry) + offset + beginEventNumbers) = unsortedEventNumbers().at(entry);
268  }
269  if(needEventEntries) {
270  eventEntries().at((entry - beginEventEntry) + offset + beginEventNumbers) =
272  }
273  }
274 
275  previousBeginEventNumbers = beginEventNumbers;
276  offset += endEventEntry - beginEventEntry;
277  }
278  if(needEventNumbers) {
279  sortEvents();
281  }
282  if(needEventEntries) {
285  }
286  }
287 
288  void
290  if(numberOfEvents() == 0 || !unsortedEventNumbers().empty()) {
291  return;
292  }
294 
295  // The main purpose for the existence of the unsortedEventNumbers
296  // vector is that it can easily be filled by reading through
297  // the EventAuxiliary branch in the same order as the TTree
298  // entries. fillEventNumbersOrEntries can then use this information
299  // instead of using getEventNumberOfEntry directly and reading
300  // the branch in a different order.
303  }
304  }
305 
306  // We are closing the input file, but we need to keep event numbers.
307  // We can delete the other transient collections by using the swap trick.
308 
309  void
311  std::vector<EventEntry>().swap(eventEntries());
312  std::vector<RunOrLumiIndexes>().swap(runOrLumiIndexes());
313  std::vector<EventNumber_t>().swap(unsortedEventNumbers());
315  }
316 
317  void
319  std::vector<EventNumber_t>().swap(unsortedEventNumbers());
320  }
321 
322  void
324 
325  std::vector<ProcessHistoryID> reducedPHIDs;
326 
327  std::map<ProcessHistoryID, int> reducedPHIDToIndex;
328  std::pair<ProcessHistoryID, int> mapEntry(ProcessHistoryID(), 0);
329  std::pair<std::map<ProcessHistoryID, int>::iterator, bool> insertResult;
330 
331  std::vector<int> phidIndexConverter;
332  for(auto const& phid : processHistoryIDs_) {
333 
334  ProcessHistoryID const& reducedPHID = processHistoryRegistry.reducedProcessHistoryID(phid);
335  mapEntry.first = reducedPHID;
336  insertResult = reducedPHIDToIndex.insert(mapEntry);
337 
338  if(insertResult.second) {
339  insertResult.first->second = reducedPHIDs.size();
340  reducedPHIDs.push_back(reducedPHID);
341  }
342  phidIndexConverter.push_back(insertResult.first->second);
343  }
344  processHistoryIDs_.swap(reducedPHIDs);
345 
346  // If the size of the vector of IDs does not change
347  // then their indexes and the ordering of the Runs and
348  // and Lumis does not change, so we are done.
349  if(processHistoryIDs_.size() == reducedPHIDs.size()) {
350  return;
351  }
352 
353  std::map<IndexIntoFile::IndexRunKey, int> runOrderMap;
354  std::pair<std::map<IndexIntoFile::IndexRunKey, int>::iterator, bool> runInsertResult;
355 
356  std::map<IndexIntoFile::IndexRunLumiKey, int> lumiOrderMap;
357  std::pair<std::map<IndexIntoFile::IndexRunLumiKey, int>::iterator, bool> lumiInsertResult;
358 
359  // loop over all the RunOrLumiEntry's
360  for(auto& item : runOrLumiEntries_) {
361 
362  // Convert the process history index so it points into the new vector of reduced IDs
363  item.setProcessHistoryIDIndex(phidIndexConverter.at(item.processHistoryIDIndex()));
364 
365  // Convert the phid-run order
366  IndexIntoFile::IndexRunKey runKey(item.processHistoryIDIndex(), item.run());
367  runInsertResult = runOrderMap.insert(std::pair<IndexIntoFile::IndexRunKey, int>(runKey,0));
368  if(runInsertResult.second) {
369  runInsertResult.first->second = item.orderPHIDRun();
370  } else {
371  item.setOrderPHIDRun(runInsertResult.first->second);
372  }
373 
374  // Convert the phid-run-lumi order for the lumi entries
375  if(item.lumi() != 0) {
376  IndexIntoFile::IndexRunLumiKey lumiKey(item.processHistoryIDIndex(), item.run(), item.lumi());
377  lumiInsertResult = lumiOrderMap.insert(std::pair<IndexIntoFile::IndexRunLumiKey, int>(lumiKey,0));
378  if(lumiInsertResult.second) {
379  lumiInsertResult.first->second = item.orderPHIDRunLumi();
380  } else {
381  item.setOrderPHIDRunLumi(lumiInsertResult.first->second);
382  }
383  }
384  }
385  std::stable_sort(runOrLumiEntries_.begin(), runOrLumiEntries_.end());
386  }
387 
388  void
389  IndexIntoFile::fixIndexes(std::vector<ProcessHistoryID> & processHistoryIDs) {
390 
391  std::map<int, int> oldToNewIndex;
392  for(std::vector<ProcessHistoryID>::const_iterator iter = processHistoryIDs_.begin(),
393  iEnd = processHistoryIDs_.end();
394  iter != iEnd;
395  ++iter) {
396  std::vector<ProcessHistoryID>::const_iterator iterExisting =
397  std::find(processHistoryIDs.begin(), processHistoryIDs.end(), *iter);
398  if(iterExisting == processHistoryIDs.end()) {
399  oldToNewIndex[iter - processHistoryIDs_.begin()] = processHistoryIDs.size();
400  processHistoryIDs.push_back(*iter);
401  } else {
402  oldToNewIndex[iter - processHistoryIDs_.begin()] = iterExisting - processHistoryIDs.begin();
403  }
404  }
406 
407  for(RunOrLumiEntry& item : runOrLumiEntries_) {
408  item.setProcessHistoryIDIndex(oldToNewIndex[item.processHistoryIDIndex()]);
409  }
410  }
411 
413  for(RunOrLumiEntry& item : runOrLumiEntries_) {
414  std::map<IndexRunKey, EntryNumber_t>::const_iterator firstRunEntry =
415  runToFirstEntry().find(IndexRunKey(item.processHistoryIDIndex(), item.run()));
416  if(firstRunEntry == runToFirstEntry().end()) {
418  << "In IndexIntoFile::sortVector_Run_Or_Lumi_Entries. A run entry is missing.\n"
419  << "This means the IndexIntoFile product in the output file will be corrupted.\n"
420  << "The output file will be unusable for most purposes.\n"
421  << "If this occurs after an unrelated exception was thrown in\n"
422  << "endLuminosityBlock or endRun then ignore this exception and fix\n"
423  << "the primary exception. This is an expected side effect.\n"
424  << "Otherwise please report this to the core framework developers\n";
425  }
426  item.setOrderPHIDRun(firstRunEntry->second);
427  }
428  stable_sort_all(runOrLumiEntries_);
429  }
430 
433  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
434  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
435  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
436  while(true) {
437  while(beginOfLumi != iEnd && beginOfLumi->isRun()) {
438  ++beginOfLumi;
439  }
440  if(beginOfLumi == iEnd) break;
441 
442  endOfLumi = beginOfLumi + 1;
443  while(endOfLumi != iEnd &&
444  beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
445  beginOfLumi->run() == endOfLumi->run() &&
446  beginOfLumi->lumi() == endOfLumi->lumi()) {
447  ++endOfLumi;
448  }
449  assert(beginOfLumi->endEventNumbers() >= 0);
450  assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventNumbers().size()));
451  std::sort(eventNumbers().begin() + beginOfLumi->beginEventNumbers(),
452  eventNumbers().begin() + beginOfLumi->endEventNumbers());
453  beginOfLumi = endOfLumi;
454  }
455  }
456 
459  std::vector<RunOrLumiIndexes>::iterator beginOfLumi = runOrLumiIndexes().begin();
460  std::vector<RunOrLumiIndexes>::iterator endOfLumi = beginOfLumi;
461  std::vector<RunOrLumiIndexes>::iterator iEnd = runOrLumiIndexes().end();
462  while(true) {
463  while(beginOfLumi != iEnd && beginOfLumi->isRun()) {
464  ++beginOfLumi;
465  }
466  if(beginOfLumi == iEnd) break;
467 
468  endOfLumi = beginOfLumi + 1;
469  while(endOfLumi != iEnd &&
470  beginOfLumi->processHistoryIDIndex() == endOfLumi->processHistoryIDIndex() &&
471  beginOfLumi->run() == endOfLumi->run() &&
472  beginOfLumi->lumi() == endOfLumi->lumi()) {
473  ++endOfLumi;
474  }
475  assert(beginOfLumi->endEventNumbers() >= 0);
476  assert(beginOfLumi->endEventNumbers() <= static_cast<long long>(eventEntries().size()));
477  std::sort(eventEntries().begin() + beginOfLumi->beginEventNumbers(),
478  eventEntries().begin() + beginOfLumi->endEventNumbers());
479  beginOfLumi = endOfLumi;
480  }
481  }
482 
484  if(empty()) {
485  return end(sortOrder);
486  }
487  IndexIntoFileItr iter(this,
488  sortOrder,
489  kRun,
490  0,
491  invalidIndex,
492  invalidIndex,
493  0,
494  0);
495  iter.initializeRun();
496  return iter;
497  }
498 
500  return IndexIntoFileItr(this,
501  sortOrder,
502  kEnd,
503  invalidIndex,
504  invalidIndex,
505  invalidIndex,
506  0,
507  0);
508  }
509 
511  EntryNumber_t maxEntry = invalidEntry;
512  for(IndexIntoFileItr it = begin(sortOrder), itEnd = end(sortOrder); it != itEnd; ++it) {
513  if(it.getEntryType() == kEvent) {
514  if(it.entry() < maxEntry) {
515  return false;
516  }
517  maxEntry = it.entry();
518  }
519  }
520  return true;
521  }
522 
523  bool IndexIntoFile::empty() const {
524  return runOrLumiEntries().empty();
525  }
526 
530 
531  bool lumiMissing = (lumi == 0 && event != 0);
532 
533  std::vector<RunOrLumiIndexes>::const_iterator it;
534  std::vector<RunOrLumiIndexes>::const_iterator iEnd = runOrLumiIndexes().end();
535  std::vector<RunOrLumiIndexes>::const_iterator phEnd;
536 
537  // Loop over ranges of entries with the same ProcessHistoryID
538  for(std::vector<RunOrLumiIndexes>::const_iterator phBegin = runOrLumiIndexes().begin();
539  phBegin != iEnd;
540  phBegin = phEnd) {
541 
542  RunOrLumiIndexes el(phBegin->processHistoryIDIndex(), run, lumi, 0);
543  phEnd = std::upper_bound(phBegin, iEnd, el, Compare_Index());
544 
545  std::vector<RunOrLumiIndexes>::const_iterator iRun = std::lower_bound(phBegin, phEnd, el, Compare_Index_Run());
546 
547  if(iRun == phEnd || iRun->run() != run) continue;
548 
549  if(lumi == invalidLumi && event == invalidEvent) {
550  IndexIntoFileItr indexItr(this,
552  kRun,
553  iRun - runOrLumiIndexes().begin(),
554  invalidIndex,
555  invalidIndex,
556  0,
557  0);
558  indexItr.initializeRun();
559  return indexItr;
560  }
561 
562  std::vector<RunOrLumiIndexes>::const_iterator iRunEnd = std::upper_bound(iRun, phEnd, el, Compare_Index_Run());
563  if(!lumiMissing) {
564 
565  std::vector<RunOrLumiIndexes>::const_iterator iLumi = std::lower_bound(iRun, iRunEnd, el);
566  if(iLumi == iRunEnd || iLumi->lumi() != lumi) continue;
567 
568  if(event == invalidEvent) {
569  IndexIntoFileItr indexItr(this,
571  kRun,
572  iRun - runOrLumiIndexes().begin(),
573  iLumi - runOrLumiIndexes().begin(),
574  invalidIndex,
575  0,
576  0);
577  indexItr.initializeLumi();
578  return indexItr;
579  }
580 
581  long long beginEventNumbers = iLumi->beginEventNumbers();
582  long long endEventNumbers = iLumi->endEventNumbers();
583  if(beginEventNumbers >= endEventNumbers) continue;
584 
585 
586  long long indexToEvent = 0;
587  if(!eventEntries().empty()) {
588  std::vector<EventEntry>::const_iterator eventIter = std::lower_bound(eventEntries().begin() + beginEventNumbers,
589  eventEntries().begin() + endEventNumbers,
590  EventEntry(event, invalidEntry));
591  if(eventIter == (eventEntries().begin() + endEventNumbers) ||
592  eventIter->event() != event) continue;
593 
594  indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
595  } else {
597  std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(eventNumbers().begin() + beginEventNumbers,
598  eventNumbers().begin() + endEventNumbers,
599  event);
600  if(eventIter == (eventNumbers().begin() + endEventNumbers) ||
601  *eventIter != event) continue;
602 
603  indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
604  }
605  return IndexIntoFileItr(this,
607  kRun,
608  iRun - runOrLumiIndexes().begin(),
609  iLumi - runOrLumiIndexes().begin(),
610  iLumi - runOrLumiIndexes().begin(),
611  indexToEvent,
612  endEventNumbers - beginEventNumbers);
613  }
614  if(lumiMissing) {
615 
616  std::vector<RunOrLumiIndexes>::const_iterator iLumi = iRun;
617  while(iLumi != iRunEnd && iLumi->lumi() == invalidLumi) {
618  ++iLumi;
619  }
620  if(iLumi == iRunEnd) continue;
621 
622  std::vector<RunOrLumiIndexes>::const_iterator lumiEnd;
623  for( ;
624  iLumi != iRunEnd;
625  iLumi = lumiEnd) {
626 
627  RunOrLumiIndexes elWithLumi(phBegin->processHistoryIDIndex(), run, iLumi->lumi(), 0);
628  lumiEnd = std::upper_bound(iLumi, iRunEnd, elWithLumi);
629 
630  long long beginEventNumbers = iLumi->beginEventNumbers();
631  long long endEventNumbers = iLumi->endEventNumbers();
632  if(beginEventNumbers >= endEventNumbers) continue;
633 
634  long long indexToEvent = 0;
635  if(!eventEntries().empty()) {
636  std::vector<EventEntry>::const_iterator eventIter = std::lower_bound(eventEntries().begin() + beginEventNumbers,
637  eventEntries().begin() + endEventNumbers,
638  EventEntry(event, invalidEntry));
639  if(eventIter == (eventEntries().begin() + endEventNumbers) ||
640  eventIter->event() != event) continue;
641  indexToEvent = eventIter - eventEntries().begin() - beginEventNumbers;
642  } else {
644  std::vector<EventNumber_t>::const_iterator eventIter = std::lower_bound(eventNumbers().begin() + beginEventNumbers,
645  eventNumbers().begin() + endEventNumbers,
646  event);
647  if(eventIter == (eventNumbers().begin() + endEventNumbers) ||
648  *eventIter != event) continue;
649  indexToEvent = eventIter - eventNumbers().begin() - beginEventNumbers;
650  }
651  return IndexIntoFileItr(this,
653  kRun,
654  iRun - runOrLumiIndexes().begin(),
655  iLumi - runOrLumiIndexes().begin(),
656  iLumi - runOrLumiIndexes().begin(),
657  indexToEvent,
658  endEventNumbers - beginEventNumbers);
659  }
660  }
661  } // Loop over ProcessHistoryIDs
662 
663  return IndexIntoFileItr(this,
665  kEnd,
666  invalidIndex,
667  invalidIndex,
668  invalidIndex,
669  0,
670  0);
671 
672  }
673 
676  if(sortOrder == IndexIntoFile::numericalOrder) {
677  return findPosition(run, lumi, event); // a faster algorithm
678  }
679  IndexIntoFileItr itr = begin(sortOrder);
680  IndexIntoFileItr itrEnd = end(sortOrder);
681 
682  while(itr != itrEnd) {
683  if(itr.run() != run) {
684  itr.advanceToNextRun();
685  } else {
686  if(lumi == invalidLumi && event == invalidEvent) {
687  return itr;
688  } else if(lumi != invalidLumi && itr.peekAheadAtLumi() != lumi) {
689  if(!itr.skipLumiInRun()) {
690  itr.advanceToNextRun();
691  }
692  } else {
693  if(event == invalidEvent) {
694  return itr;
695  } else {
697  if(eventNumber == event) {
698  return itr;
699  } else {
700  if(!itr.skipToNextEventInLumi()) {
701  if(!itr.skipLumiInRun()) {
702  itr.advanceToNextRun();
703  }
704  }
705  }
706  }
707  }
708  }
709  }
710  return itrEnd;
711  }
712 
715  assert(event != invalidEvent);
716  IndexIntoFileItr iter = findPosition(run, lumi, event);
717  iter.advanceToEvent();
718  return iter;
719  }
720 
723  assert(lumi != invalidLumi);
724  IndexIntoFileItr iter = findPosition(run, lumi, 0U);
725  iter.advanceToLumi();
726  return iter;
727  }
728 
731  return findPosition(run, 0U, 0U);
732  }
733 
734  bool
736  return (event != 0) ? containsEvent(run, lumi, event) : (lumi ? containsLumi(run, lumi) : containsRun(run));
737  }
738 
739  bool
741  return findEventPosition(run, lumi, event).getEntryType() != kEnd;
742  }
743 
744  bool
746  return findLumiPosition(run, lumi).getEntryType() != kEnd;
747  }
748 
749  bool
751  return findRunPosition(run).getEntryType() != kEnd;
752  }
753 
755  return SortedRunOrLumiItr(this, 0);
756  }
757 
759  return SortedRunOrLumiItr(this, runOrLumiEntries().size());
760  }
761 
763  std::set<IndexRunLumiEventKey> & intersection) const {
764 
765  if(empty() || indexIntoFile.empty()) return;
767  indexIntoFile.fillRunOrLumiIndexes();
768  RunOrLumiIndexes const& back1 = runOrLumiIndexes().back();
769  RunOrLumiIndexes const& back2 = indexIntoFile.runOrLumiIndexes().back();
770 
771  // Very quick decision if the run ranges in the two files do not overlap
772  if(back2 < runOrLumiIndexes().front()) return;
773  if(back1 < indexIntoFile.runOrLumiIndexes().front()) return;
774 
777 
778  SortedRunOrLumiItr iter2 = indexIntoFile.beginRunOrLumi();
779  SortedRunOrLumiItr iEnd2 = indexIntoFile.endRunOrLumi();
780 
781  // Quick decision if the lumi ranges in the two files do not overlap
782  while(iter1 != iEnd1 && iter1.isRun()) ++iter1;
783  if(iter1 == iEnd1) return;
784  if(back2 < iter1.runOrLumiIndexes()) return;
785 
786  while(iter2 != iEnd2 && iter2.isRun()) ++iter2;
787  if(iter2 == iEnd2) return;
788  if(back1 < iter2.runOrLumiIndexes()) return;
789 
790  RunOrLumiIndexes const* previousIndexes = 0;
791 
792  // Loop through the both IndexIntoFile objects and look for matching lumis
793  while(iter1 != iEnd1 && iter2 != iEnd2) {
794 
795  RunOrLumiIndexes const& indexes1 = iter1.runOrLumiIndexes();
796  RunOrLumiIndexes const& indexes2 = iter2.runOrLumiIndexes();
797  if(indexes1 < indexes2) {
798  ++iter1;
799  } else if(indexes2 < indexes1) {
800  ++iter2;
801  } else { // they are equal
802 
803  // Skip them if it is a run or the same lumi
804  if(indexes1.isRun() ||
805  (previousIndexes && !(*previousIndexes < indexes1))) {
806  ++iter1;
807  ++iter2;
808  } else {
809  previousIndexes = &indexes1;
810 
811  // Found a matching lumi, now look for matching events
812 
813  long long beginEventNumbers1 = indexes1.beginEventNumbers();
814  long long endEventNumbers1 = indexes1.endEventNumbers();
815 
816  long long beginEventNumbers2 = indexes2.beginEventNumbers();
817  long long endEventNumbers2 = indexes2.endEventNumbers();
818 
819  // there must be at least 1 event in each lumi for there to be any matches
820  if((beginEventNumbers1 >= endEventNumbers1) ||
821  (beginEventNumbers2 >= endEventNumbers2)) {
822  ++iter1;
823  ++iter2;
824  continue;
825  }
826 
827  if(!eventEntries().empty() && !indexIntoFile.eventEntries().empty()) {
828  std::vector<EventEntry> matchingEvents;
829  std::insert_iterator<std::vector<EventEntry> > insertIter(matchingEvents, matchingEvents.begin());
830  std::set_intersection(eventEntries().begin() + beginEventNumbers1,
831  eventEntries().begin() + endEventNumbers1,
832  indexIntoFile.eventEntries().begin() + beginEventNumbers2,
833  indexIntoFile.eventEntries().begin() + endEventNumbers2,
834  insertIter);
835  for(EventEntry const& entry : matchingEvents) {
836  intersection.insert(IndexRunLumiEventKey(indexes1.processHistoryIDIndex(),
837  indexes1.run(),
838  indexes1.lumi(),
839  entry.event()));
840  }
841  } else {
843  indexIntoFile.fillEventNumbers();
844  std::vector<EventNumber_t> matchingEvents;
845  std::insert_iterator<std::vector<EventNumber_t> > insertIter(matchingEvents, matchingEvents.begin());
846  std::set_intersection(eventNumbers().begin() + beginEventNumbers1,
847  eventNumbers().begin() + endEventNumbers1,
848  indexIntoFile.eventNumbers().begin() + beginEventNumbers2,
849  indexIntoFile.eventNumbers().begin() + endEventNumbers2,
850  insertIter);
851  for(EventNumber_t const& eventNumber : matchingEvents) {
852  intersection.insert(IndexRunLumiEventKey(indexes1.processHistoryIDIndex(),
853  indexes1.run(),
854  indexes1.lumi(),
855  eventNumber));
856  }
857  }
858  }
859  }
860  }
861  }
862 
864 
865  RunOrLumiIndexes const* previousIndexes = 0;
866 
867  for(SortedRunOrLumiItr iter = beginRunOrLumi(),
868  iEnd = endRunOrLumi();
869  iter != iEnd; ++iter) {
870 
871  RunOrLumiIndexes const& indexes = iter.runOrLumiIndexes();
872 
873  // Skip it if it is a run or the same lumi
874  if(indexes.isRun() ||
875  (previousIndexes && !(*previousIndexes < indexes))) {
876  continue;
877  }
878  previousIndexes = &indexes;
879 
880  long long beginEventNumbers = indexes.beginEventNumbers();
881  long long endEventNumbers = indexes.endEventNumbers();
882 
883  // there must be more than 1 event in the lumi for there to be any duplicates
884  if(beginEventNumbers + 1 >= endEventNumbers) continue;
885 
886  if(!eventEntries().empty()) {
887  std::vector<EventEntry>::iterator last = eventEntries().begin() + endEventNumbers;
888  if(std::adjacent_find(eventEntries().begin() + beginEventNumbers, last) != last) {
889  return true;
890  }
891  } else {
893  std::vector<EventNumber_t>::iterator last = eventNumbers().begin() + endEventNumbers;
894  if(std::adjacent_find(eventNumbers().begin() + beginEventNumbers, last) != last) {
895  return true;
896  }
897  }
898  }
899  return false;
900  }
901 
903  orderPHIDRun_(invalidEntry),
904  orderPHIDRunLumi_(invalidEntry),
905  entry_(invalidEntry),
906  processHistoryIDIndex_(invalidIndex),
907  run_(invalidRun),
908  lumi_(invalidLumi),
909  beginEvents_(invalidEntry),
910  endEvents_(invalidEntry) {
911  }
912 
914  EntryNumber_t orderPHIDRunLumi,
916  int processHistoryIDIndex,
921  orderPHIDRun_(orderPHIDRun),
922  orderPHIDRunLumi_(orderPHIDRunLumi),
923  entry_(entry),
924  processHistoryIDIndex_(processHistoryIDIndex),
925  run_(run),
926  lumi_(lumi),
927  beginEvents_(beginEvents),
928  endEvents_(endEvents) {
929  }
930 
934  int indexToGetEntry) :
935  processHistoryIDIndex_(processHistoryIDIndex),
936  run_(run),
937  lumi_(lumi),
938  indexToGetEntry_(indexToGetEntry),
939  beginEventNumbers_(-1),
940  endEventNumbers_(-1)
941  {
942  }
943 
944  IndexIntoFile::SortedRunOrLumiItr::SortedRunOrLumiItr(IndexIntoFile const* indexIntoFile, unsigned runOrLumi) :
945  indexIntoFile_(indexIntoFile), runOrLumi_(runOrLumi) {
946  assert(runOrLumi_ <= indexIntoFile_->runOrLumiEntries().size());
948  }
949 
951  return indexIntoFile_ == right.indexIntoFile() &&
952  runOrLumi_ == right.runOrLumi();
953  }
954 
956  return indexIntoFile_ != right.indexIntoFile() ||
957  runOrLumi_ != right.runOrLumi();
958  }
959 
961  if(runOrLumi_ != indexIntoFile_->runOrLumiEntries().size()) {
962  ++runOrLumi_;
963  }
964  return *this;
965  }
966 
968  return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).lumi() == invalidLumi;
969  }
970 
971  void IndexIntoFile::SortedRunOrLumiItr::getRange(long long & beginEventNumbers,
972  long long & endEventNumbers,
973  EntryNumber_t & beginEventEntry,
974  EntryNumber_t & endEventEntry) {
975  beginEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).beginEventNumbers();
976  endEventNumbers = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).endEventNumbers();
977 
978  int indexToGetEntry = indexIntoFile_->runOrLumiIndexes().at(runOrLumi_).indexToGetEntry();
979  beginEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).beginEvents();
980  endEventEntry = indexIntoFile_->runOrLumiEntries_.at(indexToGetEntry).endEvents();
981  }
982 
985  return indexIntoFile_->runOrLumiIndexes().at(runOrLumi_);
986  }
987 
989  EntryType entryType,
990  int indexToRun,
991  int indexToLumi,
992  int indexToEventRange,
993  long long indexToEvent,
994  long long nEvents) :
995  indexIntoFile_(indexIntoFile),
996  size_(static_cast<int>(indexIntoFile_->runOrLumiEntries_.size())),
997  type_(entryType),
998  indexToRun_(indexToRun),
999  indexToLumi_(indexToLumi),
1000  indexToEventRange_(indexToEventRange),
1001  indexToEvent_(indexToEvent),
1002  nEvents_(nEvents) {
1003  }
1004 
1006 
1008 
1009  if(type_ == kEvent) {
1010  if((indexToEvent_ + 1) < nEvents_) {
1011  ++indexToEvent_;
1012  } else {
1013  bool found = nextEventRange();
1014 
1015  if(!found) {
1016  type_ = getRunOrLumiEntryType(indexToLumi_ + 1);
1017 
1018  if(type_ == kLumi) {
1019  ++indexToLumi_;
1020  initializeLumi();
1021  } else if(type_ == kRun) {
1022  indexToRun_ = indexToLumi_ + 1;
1023  initializeRun();
1024  } else {
1025  setInvalid(); // type_ is kEnd
1026  }
1027  }
1028  }
1029  } else if(type_ == kLumi) {
1030 
1031  if(indexToLumi_ + 1 == size_) {
1032  if(indexToEvent_ < nEvents_) {
1033  type_ = kEvent;
1034  } else {
1035  setInvalid();
1036  }
1037  } else {
1038 
1039  EntryType nextType = getRunOrLumiEntryType(indexToLumi_ + 1);
1040 
1041  if(nextType == kLumi && isSameLumi(indexToLumi_, indexToLumi_ + 1)) {
1042  ++indexToLumi_;
1043  } else if(indexToEvent_ < nEvents_) {
1044  type_ = kEvent;
1045  } else if(nextType == kRun) {
1046  type_ = kRun;
1047  indexToRun_ = indexToLumi_ + 1;
1048  initializeRun();
1049  } else {
1050  ++indexToLumi_;
1051  initializeLumi();
1052  }
1053  }
1054  } else if(type_ == kRun) {
1055  EntryType nextType = getRunOrLumiEntryType(indexToRun_ + 1);
1056  bool sameRun = isSameRun(indexToRun_, indexToRun_ + 1);
1057  if(nextType == kRun && sameRun) {
1058  ++indexToRun_;
1059  } else if(nextType == kRun && !sameRun) {
1060  ++indexToRun_;
1061  initializeRun();
1062  } else if(nextType == kLumi) {
1063  type_ = kLumi;
1064  } else {
1065  setInvalid();
1066  }
1067  }
1068  }
1069 
1071  RunNumber_t & runOfSkippedEvent,
1072  LuminosityBlockNumber_t & lumiOfSkippedEvent,
1073  EntryNumber_t & skippedEventEntry) {
1074  if(indexToEvent_ < nEvents_) {
1075  phIndexOfSkippedEvent = processHistoryIDIndex();
1076  runOfSkippedEvent = run();
1077  lumiOfSkippedEvent = peekAheadAtLumi();
1078  skippedEventEntry = peekAheadAtEventEntry();
1079 
1080  if((indexToEvent_ + 1) < nEvents_) {
1081  ++indexToEvent_;
1082  return;
1083  } else if(nextEventRange()) {
1084  return;
1085  } else if(type_ == kRun || type_ == kLumi) {
1086  if(skipLumiInRun()) {
1087  return;
1088  }
1089  } else if(type_ == kEvent) {
1090  next();
1091  return;
1092  }
1093  advanceToNextRun();
1094  return;
1095  }
1096 
1097  if(type_ == kRun) {
1098  while(skipLumiInRun()) {
1099  if(indexToEvent_ < nEvents_) {
1100  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1101  return;
1102  }
1103  }
1104  }
1105 
1106  while(indexToEvent_ >= nEvents_ && type_ != kEnd) {
1107  while(skipLumiInRun()) {
1108  if(indexToEvent_ < nEvents_) {
1109  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1110  return;
1111  }
1112  }
1113  advanceToNextRun();
1114  }
1115  if(type_ == kEnd) {
1116  phIndexOfSkippedEvent = invalidIndex;
1117  runOfSkippedEvent = invalidRun;
1118  lumiOfSkippedEvent = invalidLumi;
1119  skippedEventEntry = invalidEntry;
1120  return;
1121  }
1122  skipEventForward(phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1123  return;
1124  }
1125 
1127  RunNumber_t& runOfEvent,
1128  LuminosityBlockNumber_t& lumiOfEvent,
1129  EntryNumber_t& eventEntry) {
1130  // Look for previous events in the current lumi
1131  if(indexToEvent_ > 0) {
1132  --indexToEvent_;
1133  } else if(!previousEventRange()) {
1134 
1135  // Look for previous events in previous lumis
1136  if(!previousLumiWithEvents()) {
1137 
1138  // If we get here there are no previous events in the file
1139 
1140  if(!indexIntoFile_->empty()) {
1141  // Set the iterator to the beginning of the file
1142  type_ = kRun;
1143  indexToRun_ = 0;
1144  initializeRun();
1145  }
1146  phIndexOfEvent = invalidIndex;
1147  runOfEvent = invalidRun;
1148  lumiOfEvent = invalidLumi;
1149  eventEntry = invalidEntry;
1150  return;
1151  }
1152  }
1153  // Found a previous event and we have set the iterator so that this event
1154  // will be the next event process. (There may or may not be a run and/or
1155  // a lumi processed first).
1156  // Return information about this event
1157  phIndexOfEvent = processHistoryIDIndex();
1158  runOfEvent = run();
1159  lumiOfEvent = peekAheadAtLumi();
1160  eventEntry = peekAheadAtEventEntry();
1161  }
1162 
1164  // Find the correct place to start the search
1165  int newLumi = indexToLumi();
1166  if(newLumi == invalidIndex) {
1167  newLumi = indexToRun() == invalidIndex ? size() - 1 : indexToRun();
1168  } else {
1169  while(getRunOrLumiEntryType(newLumi - 1) == kLumi &&
1170  isSameLumi(newLumi, newLumi - 1)) {
1171  --newLumi;
1172  }
1173  --newLumi;
1174  }
1175  if(newLumi <= 0) return false;
1176 
1177  // Look backwards for a lumi with events
1178  for( ; newLumi > 0; --newLumi) {
1179  if(getRunOrLumiEntryType(newLumi) == kRun) {
1180  continue;
1181  }
1182  if(setToLastEventInRange(newLumi)) {
1183  break; // found it
1184  }
1185  }
1186  if(newLumi == 0) return false;
1187 
1188  // Finish initializing the iterator
1189  while(getRunOrLumiEntryType(newLumi - 1) == kLumi &&
1190  isSameLumi(newLumi, newLumi - 1)) {
1191  --newLumi;
1192  }
1193  setIndexToLumi(newLumi);
1194 
1195  if(type() != kEnd &&
1196  isSameRun(newLumi, indexToRun())) {
1197  if(type() == kEvent) type_ = kLumi;
1198  return true;
1199  }
1200  int newRun = newLumi;
1201  while(newRun > 0 && getRunOrLumiEntryType(newRun - 1) == kLumi) {
1202  --newRun;
1203  }
1204  --newRun;
1205  assert(getRunOrLumiEntryType(newRun) == kRun);
1206  while(getRunOrLumiEntryType(newRun - 1) == kRun &&
1207  isSameRun(newRun - 1, newLumi)) {
1208  --newRun;
1209  }
1210  indexToRun_ = newRun;
1211  type_ = kRun;
1212  return true;
1213  }
1214 
1216  if(indexToLumi() == invalidIndex) return invalidEntry;
1217 
1218  int saveIndexToLumi = indexToLumi();
1219  int saveIndexToEventRange = indexToEventRange();
1220  long long saveIndexToEvent = indexToEvent();
1221  long long saveNEvents = nEvents();
1222 
1223  initializeRun();
1224 
1226 
1227  do {
1228  if(indexToEvent() < nEvents()) {
1229  returnValue = peekAheadAtEventEntry();
1230  break;
1231  }
1232  } while(skipLumiInRun());
1233 
1234  setIndexToLumi(saveIndexToLumi);
1235  setIndexToEventRange(saveIndexToEventRange);
1236  setIndexToEvent(saveIndexToEvent);
1237  setNEvents(saveNEvents);
1238 
1239  return returnValue;
1240  }
1241 
1243  if(indexToLumi() == invalidIndex) return invalidEntry;
1244 
1245  int saveIndexToLumi = indexToLumi();
1246  int saveIndexToEventRange = indexToEventRange();
1247  long long saveIndexToEvent = indexToEvent();
1248  long long saveNEvents = nEvents();
1249 
1250  for(int i = 1; indexToLumi() - i > 0; ++i) {
1251  if(getRunOrLumiEntryType(indexToLumi_ - i) == kRun) break;
1252  if(!isSameLumi(indexToLumi(), indexToLumi() - i)) break;
1253  indexToLumi_ = indexToLumi_ - i;
1254  }
1255  initializeLumi();
1256 
1258 
1259  if(indexToEvent() < nEvents()) {
1260  returnValue = peekAheadAtEventEntry();
1261  }
1262 
1263  setIndexToLumi(saveIndexToLumi);
1264  setIndexToEventRange(saveIndexToEventRange);
1265  setIndexToEvent(saveIndexToEvent);
1266  setNEvents(saveNEvents);
1267 
1268  return returnValue;
1269  }
1270 
1272  if(type_ == kEnd) return;
1273  for(int i = 1; indexToRun_ + i < size_; ++i) {
1274  if(getRunOrLumiEntryType(indexToRun_ + i) == kRun) {
1275  if(!isSameRun(indexToRun_, indexToRun_ + i)) {
1276  type_ = kRun;
1277  indexToRun_ += i;
1278  initializeRun();
1279  return;
1280  }
1281  }
1282  }
1283  setInvalid();
1284  }
1285 
1287  if(type_ == kEnd) return;
1288  assert(indexToRun_ != invalidIndex);
1289 
1290  // A preliminary step is to advance to the last run entry for
1291  // this run (actually this step is not needed in the
1292  // context I expect this to be called in, just being careful)
1293  int startSearch = indexToRun_;
1294  for(int i = 1; startSearch + i < size_; ++i) {
1295  if(getRunOrLumiEntryType(startSearch + i) == kRun &&
1296  isSameRun(indexToRun_, startSearch + i)) {
1297  indexToRun_ = startSearch + i;
1298  } else {
1299  break;
1300  }
1301  }
1302 
1303  if(type_ == kRun && indexToLumi_ != invalidIndex) {
1304  type_ = kLumi;
1305  return;
1306  }
1307 
1308  startSearch = indexToLumi_;
1309  if(startSearch == invalidIndex) startSearch = indexToRun_;
1310  for(int i = 1; startSearch + i < size_; ++i) {
1311  if(getRunOrLumiEntryType(startSearch + i) == kRun) {
1312  if(!isSameRun(indexToRun_, startSearch + i)) {
1313  type_ = kRun;
1314  indexToRun_ = startSearch + i;
1315  initializeRun();
1316  return;
1317  }
1318  } else if(indexToLumi_ != invalidIndex) {
1319  if(!isSameLumi(indexToLumi_, startSearch + i)) {
1320  type_ = kLumi;
1321  indexToLumi_ = startSearch + i;
1322  initializeLumi();
1323  return;
1324  }
1325  }
1326  }
1327  setInvalid();
1328  }
1329 
1331  if(indexToEvent_ >= nEvents_) return false;
1332  if((indexToEvent_ + 1) < nEvents_) {
1333  ++indexToEvent_;
1334  return true;
1335  }
1336  return nextEventRange();
1337  }
1338 
1340 
1341  indexToLumi_ = invalidIndex;
1342  indexToEventRange_ = invalidIndex;
1343  indexToEvent_ = 0;
1344  nEvents_ = 0;
1345 
1346  for(int i = 1; (i + indexToRun_) < size_; ++i) {
1347  EntryType entryType = getRunOrLumiEntryType(indexToRun_ + i);
1348  bool sameRun = isSameRun(indexToRun_, indexToRun_ + i);
1349 
1350  if(entryType == kRun) {
1351  if(sameRun) {
1352  continue;
1353  } else {
1354  break;
1355  }
1356  } else {
1357  indexToLumi_ = indexToRun_ + i;
1358  initializeLumi();
1359  return;
1360  }
1361  }
1362  }
1363 
1365  return (indexIntoFile_ == right.indexIntoFile_ &&
1366  size_ == right.size_ &&
1367  type_ == right.type_ &&
1368  indexToRun_ == right.indexToRun_ &&
1369  indexToLumi_ == right.indexToLumi_ &&
1370  indexToEventRange_ == right.indexToEventRange_ &&
1371  indexToEvent_ == right.indexToEvent_ &&
1372  nEvents_ == right.nEvents_);
1373  }
1374 
1375  void
1377  type_ = position.type_;
1378  indexToRun_ = position.indexToRun_;
1379  indexToLumi_ = position.indexToLumi_;
1380  indexToEventRange_ = position.indexToEventRange_;
1381  indexToEvent_ = position.indexToEvent_;
1382  nEvents_ = position.nEvents_;
1383  }
1384 
1386  type_ = kEnd;
1387  indexToRun_ = invalidIndex;
1388  indexToLumi_ = invalidIndex;
1389  indexToEventRange_ = invalidIndex;
1390  indexToEvent_ = 0;
1391  nEvents_ = 0;
1392  }
1393 
1395  EntryType entryType,
1396  int indexToRun,
1397  int indexToLumi,
1398  int indexToEventRange,
1399  long long indexToEvent,
1400  long long nEvents) :
1401  IndexIntoFileItrImpl(indexIntoFile,
1402  entryType,
1403  indexToRun,
1404  indexToLumi,
1405  indexToEventRange,
1406  indexToEvent,
1407  nEvents)
1408  {
1409  }
1410 
1413  return new IndexIntoFileItrNoSort(*this);
1414  }
1415 
1416  int
1418  if(type() == kEnd) return invalidIndex;
1419  return indexIntoFile()->runOrLumiEntries()[indexToRun()].processHistoryIDIndex();
1420  }
1421 
1423  if(type() == kEnd) return invalidRun;
1424  return indexIntoFile()->runOrLumiEntries()[indexToRun()].run();
1425  }
1426 
1428  if(type() == kEnd || type() == kRun) return invalidLumi;
1429  return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
1430  }
1431 
1433  if(type() == kEnd) return invalidEntry;
1434  if(type() == kRun) return indexIntoFile()->runOrLumiEntries()[indexToRun()].entry();
1435  if(type() == kLumi) return indexIntoFile()->runOrLumiEntries()[indexToLumi()].entry();
1436  return
1437  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() +
1438  indexToEvent();
1439  }
1440 
1442  if(indexToLumi() == invalidIndex) return invalidLumi;
1443  return indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi();
1444  }
1445 
1447  if(indexToLumi() == invalidIndex) return invalidEntry;
1448  if(indexToEvent() >= nEvents()) return invalidEntry;
1449  return
1450  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents() +
1451  indexToEvent();
1452  }
1453 
1455  assert(indexToLumi() != invalidIndex);
1456 
1457  setIndexToEventRange(invalidIndex);
1458  setIndexToEvent(0);
1459  setNEvents(0);
1460 
1461  for(int i = 0; indexToLumi() + i < size(); ++i) {
1462  if(indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].isRun()) {
1463  break;
1464  } else if(indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].lumi() ==
1465  indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
1466  if(indexIntoFile()->runOrLumiEntries()[indexToLumi() + i].beginEvents() == invalidEntry) {
1467  continue;
1468  }
1469  setIndexToEventRange(indexToLumi() + i);
1470  setIndexToEvent(0);
1471  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1472  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1473  break;
1474  } else {
1475  break;
1476  }
1477  }
1478  }
1479 
1481  if(indexToEventRange() == invalidIndex) return false;
1482 
1483  // Look for the next event range, same lumi but different entry
1484  for(int i = 1; indexToEventRange() + i < size(); ++i) {
1485  if(indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i ].isRun()) {
1486  return false; // hit next run
1487  } else if(indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].lumi() ==
1488  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].lumi()) {
1489  if(indexIntoFile()->runOrLumiEntries()[indexToEventRange() + i].beginEvents() == invalidEntry) {
1490  continue; // same lumi but has no events, keep looking
1491  }
1492  setIndexToEventRange(indexToEventRange() + i);
1493  setIndexToEvent(0);
1494  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1495  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1496  return true; // found more events in this lumi
1497  }
1498  return false; // hit next lumi
1499  }
1500  return false; // hit the end of the IndexIntoFile
1501  }
1502 
1504  if(indexToEventRange() == invalidIndex) return false;
1505  assert(indexToEventRange() < size());
1506 
1507  // Look backward for a previous event range with events, same lumi but different entry
1508  for(int i = 1; indexToEventRange() - i > 0; ++i) {
1509  int newRange = indexToEventRange() - i;
1510  if(indexIntoFile()->runOrLumiEntries()[newRange].isRun()) {
1511  return false; // hit run
1512  } else if(isSameLumi(newRange, indexToEventRange())) {
1513  if(indexIntoFile()->runOrLumiEntries()[newRange].beginEvents() == invalidEntry) {
1514  continue; // same lumi but has no events, keep looking
1515  }
1516  setIndexToEventRange(newRange);
1517  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1518  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1519  setIndexToEvent(nEvents() - 1);
1520  return true; // found previous event in this lumi
1521  }
1522  return false; // hit previous lumi
1523  }
1524  return false; // hit the beginning of the IndexIntoFile, 0th entry has to be a run
1525  }
1526 
1528  if(indexIntoFile()->runOrLumiEntries()[index].beginEvents() == invalidEntry) {
1529  return false;
1530  }
1531  setIndexToEventRange(index);
1532  setNEvents(indexIntoFile()->runOrLumiEntries()[indexToEventRange()].endEvents() -
1533  indexIntoFile()->runOrLumiEntries()[indexToEventRange()].beginEvents());
1534  assert(nEvents() > 0);
1535  setIndexToEvent(nEvents() - 1);
1536  return true;
1537  }
1538 
1540  if(indexToLumi() == invalidIndex) return false;
1541  for(int i = 1; indexToLumi() + i < size(); ++i) {
1542  int newLumi = indexToLumi() + i;
1543  if(indexIntoFile()->runOrLumiEntries()[newLumi].isRun()) {
1544  return false; // hit next run
1545  } else if(indexIntoFile()->runOrLumiEntries()[newLumi].lumi() ==
1546  indexIntoFile()->runOrLumiEntries()[indexToLumi()].lumi()) {
1547  continue;
1548  }
1549  setIndexToLumi(newLumi);
1550  initializeLumi();
1551  return true; // hit next lumi
1552  }
1553  return false; // hit the end of the IndexIntoFile
1554  }
1555 
1557  if(index < 0 || index >= size()) {
1558  return kEnd;
1559  } else if(indexIntoFile()->runOrLumiEntries()[index].isRun()) {
1560  return kRun;
1561  }
1562  return kLumi;
1563  }
1564 
1565  bool IndexIntoFile::IndexIntoFileItrNoSort::isSameLumi(int index1, int index2) const {
1566  if(index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1567  return false;
1568  }
1569  return indexIntoFile()->runOrLumiEntries()[index1].lumi() ==
1570  indexIntoFile()->runOrLumiEntries()[index2].lumi();
1571  }
1572 
1573  bool IndexIntoFile::IndexIntoFileItrNoSort::isSameRun(int index1, int index2) const {
1574  if(index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1575  return false;
1576  }
1577  return indexIntoFile()->runOrLumiEntries()[index1].run() ==
1578  indexIntoFile()->runOrLumiEntries()[index2].run() &&
1579  indexIntoFile()->runOrLumiEntries()[index1].processHistoryIDIndex() ==
1580  indexIntoFile()->runOrLumiEntries()[index2].processHistoryIDIndex();
1581  }
1582 
1584  EntryType entryType,
1585  int indexToRun,
1586  int indexToLumi,
1587  int indexToEventRange,
1588  long long indexToEvent,
1589  long long nEvents) :
1590  IndexIntoFileItrImpl(indexIntoFile,
1591  entryType,
1592  indexToRun,
1593  indexToLumi,
1594  indexToEventRange,
1595  indexToEvent,
1596  nEvents) {
1597  indexIntoFile->fillRunOrLumiIndexes();
1598  }
1599 
1601  return new IndexIntoFileItrSorted(*this);
1602  }
1603 
1605  if(type() == kEnd) return invalidIndex;
1606  return indexIntoFile()->runOrLumiIndexes()[indexToRun()].processHistoryIDIndex();
1607  }
1608 
1610  if(type() == kEnd) return invalidRun;
1611  return indexIntoFile()->runOrLumiIndexes()[indexToRun()].run();
1612  }
1613 
1615  if(type() == kEnd || type() == kRun) return invalidLumi;
1616  return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
1617  }
1618 
1620  if(type() == kEnd) return invalidEntry;
1621  if(type() == kRun) {
1622  int i = indexIntoFile()->runOrLumiIndexes()[indexToRun()].indexToGetEntry();
1623  return indexIntoFile()->runOrLumiEntries()[i].entry();
1624  }
1625  if(type() == kLumi) {
1626  int i = indexIntoFile()->runOrLumiIndexes()[indexToLumi()].indexToGetEntry();
1627  return indexIntoFile()->runOrLumiEntries()[i].entry();
1628  }
1629  long long eventNumberIndex =
1630  indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() +
1631  indexToEvent();
1632  indexIntoFile()->fillEventEntries();
1633  return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
1634  }
1635 
1637  if(indexToLumi() == invalidIndex) return invalidLumi;
1638  return indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi();
1639  }
1640 
1642  if(indexToLumi() == invalidIndex) return invalidEntry;
1643  if(indexToEvent() >= nEvents()) return invalidEntry;
1644  long long eventNumberIndex =
1645  indexIntoFile()->runOrLumiIndexes()[indexToEventRange()].beginEventNumbers() +
1646  indexToEvent();
1647  indexIntoFile()->fillEventEntries();
1648  return indexIntoFile()->eventEntries().at(eventNumberIndex).entry();
1649  }
1650 
1652  assert(indexToLumi() != invalidIndex);
1653  setIndexToEventRange(indexToLumi());
1654  setIndexToEvent(0);
1655  setNEvents(
1656  indexIntoFile()->runOrLumiIndexes()[indexToLumi()].endEventNumbers() -
1657  indexIntoFile()->runOrLumiIndexes()[indexToLumi()].beginEventNumbers());
1658  if(nEvents() == 0){
1659  setIndexToEventRange(invalidIndex);
1660  }
1661  }
1662 
1664  return false;
1665  }
1666 
1668  return false;
1669  }
1670 
1672  long long nEventsInRange =
1673  indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
1674  indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers();
1675  if(nEventsInRange == 0) {
1676  return false;
1677  }
1678  while(index > 0 &&
1679  !indexIntoFile()->runOrLumiIndexes()[index - 1].isRun() &&
1680  isSameLumi(index, index - 1)) {
1681  --index;
1682  }
1683  assert(nEventsInRange ==
1684  indexIntoFile()->runOrLumiIndexes()[index].endEventNumbers() -
1685  indexIntoFile()->runOrLumiIndexes()[index].beginEventNumbers());
1686 
1687  setIndexToEventRange(index);
1688  setNEvents(nEventsInRange);
1689  assert(nEvents() > 0);
1690  setIndexToEvent(nEventsInRange - 1);
1691  return true;
1692  }
1693 
1695  if(indexToLumi() == invalidIndex) return false;
1696  for(int i = 1; indexToLumi() + i < size(); ++i) {
1697  int newLumi = indexToLumi() + i;
1698  if(indexIntoFile()->runOrLumiIndexes()[newLumi].isRun()) {
1699  return false; // hit next run
1700  } else if(indexIntoFile()->runOrLumiIndexes()[newLumi].lumi() ==
1701  indexIntoFile()->runOrLumiIndexes()[indexToLumi()].lumi()) {
1702  continue;
1703  }
1704  setIndexToLumi(newLumi);
1705  initializeLumi();
1706  return true; // hit next lumi
1707  }
1708  return false; // hit the end of the IndexIntoFile
1709  }
1710 
1712  if(index < 0 || index >= size()) {
1713  return kEnd;
1714  } else if(indexIntoFile()->runOrLumiIndexes()[index].isRun()) {
1715  return kRun;
1716  }
1717  return kLumi;
1718  }
1719 
1720  bool IndexIntoFile::IndexIntoFileItrSorted::isSameLumi(int index1, int index2) const {
1721  if(index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1722  return false;
1723  }
1724  return indexIntoFile()->runOrLumiIndexes()[index1].lumi() ==
1725  indexIntoFile()->runOrLumiIndexes()[index2].lumi();
1726  }
1727 
1728  bool IndexIntoFile::IndexIntoFileItrSorted::isSameRun(int index1, int index2) const {
1729  if(index1 < 0 || index1 >= size() || index2 < 0 || index2 >= size()) {
1730  return false;
1731  }
1732  return indexIntoFile()->runOrLumiIndexes()[index1].run() ==
1733  indexIntoFile()->runOrLumiIndexes()[index2].run() &&
1734  indexIntoFile()->runOrLumiIndexes()[index1].processHistoryIDIndex() ==
1735  indexIntoFile()->runOrLumiIndexes()[index2].processHistoryIDIndex();
1736  }
1737 
1739  SortOrder sortOrder,
1740  EntryType entryType,
1741  int indexToRun,
1742  int indexToLumi,
1743  int indexToEventRange,
1744  long long indexToEvent,
1745  long long nEvents) :
1746  impl_() {
1747  if(sortOrder == numericalOrder) {
1749  entryType,
1750  indexToRun,
1751  indexToLumi,
1752  indexToEventRange,
1753  indexToEvent,
1754  nEvents
1755  ));
1756  swap(temp, impl_);
1757  } else {
1759  entryType,
1760  indexToRun,
1761  indexToLumi,
1762  indexToEventRange,
1763  indexToEvent,
1764  nEvents));
1765  swap(temp, impl_);
1766  }
1767  }
1768 
1770  for(EntryType entryType = getEntryType();
1771  entryType != kEnd && entryType != kEvent;
1772  entryType = getEntryType()) {
1773  impl_->next();
1774  }
1775  }
1776 
1778  for(EntryType entryType = getEntryType();
1779  entryType != kEnd && entryType != kLumi;
1780  entryType = getEntryType()) {
1781  impl_->next();
1782  }
1783  }
1784 
1785  void
1787  impl_->copyPosition(*position.impl_);
1788  }
1789 
1791  if(lh.processHistoryIDIndex() == rh.processHistoryIDIndex()) {
1792  return lh.run() < rh.run();
1793  }
1794  return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
1795  }
1796 
1798  return lh.processHistoryIDIndex() < rh.processHistoryIDIndex();
1799  }
1800 }
void initializeRun()
Should only be used internally and for tests.
void fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const
RunNumber_t & currentRun() const
type
Definition: HCALResponse.h:21
virtual bool isSameLumi(int index1, int index2) const
virtual EntryNumber_t entry() const
int i
Definition: DBlmapReader.cc:9
EntryNumber_t peekAheadAtEventEntry() const
void doneFileInitialization() const
Clears the temporary vector of event numbers to reduce memory usage.
static int const invalidIndex
virtual LuminosityBlockNumber_t lumi() const
virtual EntryNumber_t peekAheadAtEventEntry() const
virtual EntryNumber_t entry() const
virtual bool isSameRun(int index1, int index2) const
std::vector< EventEntry > & eventEntries() const
Definition: Hash.h:42
tuple lumi
Definition: fjr2json.py:35
virtual EntryType getRunOrLumiEntryType(int index) const
SortedRunOrLumiItr beginRunOrLumi() const
bool empty() const
True if no runs, lumis, or events are in the file.
LuminosityBlockNumber_t & currentLumi() const
virtual LuminosityBlockNumber_t peekAheadAtLumi() const
assert(m_qm.get())
bool operator==(SortedRunOrLumiItr const &right) const
unsigned long long EventNumber_t
std::vector< RunOrLumiIndexes > & runOrLumiIndexes() const
void sortEvents() const
void fillUnsortedEventNumbers() const
IndexIntoFileItr begin(SortOrder sortOrder) const
void swap(Hash< I > &other)
Definition: Hash.h:206
LuminosityBlockNumber_t lumi() const
bool int lh
Definition: SIMDVec.h:21
std::vector< RunOrLumiEntry > const & runOrLumiEntries() const
Used internally and for test purposes.
void stable_sort_all(RandomAccessSequence &s)
wrappers for std::stable_sort
Definition: Algorithms.h:135
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
virtual IndexIntoFileItrImpl * clone() const
uint16_t size_type
unsigned int LuminosityBlockNumber_t
IndexIntoFileItr findRunPosition(RunNumber_t run) const
Same as findPosition.
std::vector< ProcessHistoryID > const & processHistoryIDs() const
long long EntryNumber_t
static EventNumber_t const invalidEvent
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
IndexIntoFileItr findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi=0U, EventNumber_t event=0U) const
int & previousAddedIndex() const
void sortVector_Run_Or_Lumi_Entries()
size_t numberOfEvents() const
void reduceProcessHistoryIDs(ProcessHistoryRegistry const &processHistoryRegistry)
IndexIntoFile const * indexIntoFile() const
int & currentIndex() const
RunOrLumiIndexes(int processHistoryIDIndex, RunNumber_t run, LuminosityBlockNumber_t lumi, int indexToGetEntry)
static RunNumber_t const invalidRun
void skipEventBackward(int &phIndexOfEvent, RunNumber_t &runOfEvent, LuminosityBlockNumber_t &lumiOfEvent, EntryNumber_t &eventEntry)
std::vector< RunOrLumiEntry > runOrLumiEntries_
void copyPosition(IndexIntoFileItr const &position)
Copy the position without modifying the pointer to the IndexIntoFile or size.
IndexIntoFileItr end(SortOrder sortOrder) const
Used to end an iteration over the Runs, Lumis, and Events in a file.
void skipEventForward(int &phIndexOfSkippedEvent, RunNumber_t &runOfSkippedEvent, LuminosityBlockNumber_t &lumiOfSkippedEvent, EntryNumber_t &skippedEventEntry)
std::vector< ProcessHistoryID > processHistoryIDs_
void fillEventEntries() const
IndexIntoFileItrImpl(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
virtual EntryNumber_t peekAheadAtEventEntry() const
void fillRunOrLumiIndexes() const
virtual bool isSameRun(int index1, int index2) const
bool operator==(IndexIntoFileItrImpl const &right) const
void set_intersection(IndexIntoFile const &indexIntoFile, std::set< IndexRunLumiEventKey > &intersection) const
bool iterationWillBeInEntryOrder(SortOrder sortOrder) const
Used to determine whether or not to disable fast cloning.
virtual IndexIntoFileItrImpl * clone() const
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
bool operator()(IndexIntoFile::RunOrLumiIndexes const &lh, IndexIntoFile::RunOrLumiIndexes const &rh)
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 operator!=(SortedRunOrLumiItr const &right) const
void addEntry(ProcessHistoryID const &processHistoryID, RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry)
SortedRunOrLumiItr(IndexIntoFile const *indexIntoFile, unsigned runOrLumi)
Hash< ProcessHistoryType > ProcessHistoryID
void sortEventEntries() const
bool containsLumi(RunNumber_t run, LuminosityBlockNumber_t lumi) const
bool containsDuplicateEvents() const
Returns true if the IndexIntoFile contains 2 events with the same ProcessHistoryID index...
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
void inputFileClosed() const
void fixIndexes(std::vector< ProcessHistoryID > &processHistoryIDs)
void resetEventFinder() const
std::map< IndexRunKey, EntryNumber_t > & runToFirstEntry() const
std::vector< EventNumber_t > & unsortedEventNumbers() const
static EntryNumber_t const invalidEntry
virtual bool isSameLumi(int index1, int index2) const
virtual EntryType getRunOrLumiEntryType(int index) const
IndexIntoFileItrSorted(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
virtual LuminosityBlockNumber_t peekAheadAtLumi() const
static LuminosityBlockNumber_t const invalidLumi
IndexIntoFileItr findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const
void initializeLumi()
Should only be used internally and for tests.
ProcessHistoryID const & processHistoryID(int i) const
void copyPosition(IndexIntoFileItrImpl const &position)
EventNumber_t getEventNumberOfEntry(EntryNumber_t entry) const
virtual LuminosityBlockNumber_t lumi() const
void fillEventNumbers() const
static int position[264][3]
Definition: ReadPGInfo.cc:509
void setNumberOfEvents(EntryNumber_t nevents) const
list entry
Definition: mps_splice.py:62
bool containsEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
std::vector< EventNumber_t > & eventNumbers() const
IndexIntoFileItr(IndexIntoFile const *indexIntoFile, SortOrder sortOrder, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
size_(0)
Definition: OwnArray.h:181
unsigned int RunNumber_t
SortedRunOrLumiItr endRunOrLumi() const
bool operator()(IndexIntoFile::RunOrLumiIndexes const &lh, IndexIntoFile::RunOrLumiIndexes const &rh)
UInt_t nEvents
Definition: hcalCalib.cc:42
std::map< IndexRunLumiKey, EntryNumber_t > & lumiToFirstEntry() const
bool containsRun(RunNumber_t run) const
IndexIntoFileItr findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
void getRange(long long &beginEventNumbers, long long &endEventNumbers, EntryNumber_t &beginEventEntry, EntryNumber_t &endEventEntry)
EntryNumber_t & endEvents() const
LuminosityBlockNumber_t peekAheadAtLumi() const
EntryNumber_t & beginEvents() const
value_ptr< IndexIntoFileItrImpl > impl_
tuple size
Write out results.
IndexIntoFileItrNoSort(IndexIntoFile const *indexIntoFile, EntryType entryType, int indexToRun, int indexToLumi, int indexToEventRange, long long indexToEvent, long long nEvents)
RunOrLumiIndexes const & runOrLumiIndexes() const