CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RootFile.cc
Go to the documentation of this file.
1 /*----------------------------------------------------------------------
2 ----------------------------------------------------------------------*/
3 
4 #include "RootFile.h"
5 #include "DuplicateChecker.h"
6 #include "InputFile.h"
7 #include "ProvenanceAdaptor.h"
8 
42 
43 //used for backward compatibility
49 
50 #include "TROOT.h"
51 #include "Rtypes.h"
52 #include "TClass.h"
53 #include "TString.h"
54 #include "TTree.h"
55 #include "TTreeCache.h"
56 
57 #include <algorithm>
58 #include <list>
59 
60 namespace edm {
61 
62  // Algorithm classes for making ProvenanceReader:
64  public:
65  virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
66  };
68  public:
69  virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
70  };
72  public:
73  virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
74  };
76  public:
77  MakeReducedProvenanceReader(std::vector<ParentageID> const& parentageIDLookup) : parentageIDLookup_(parentageIDLookup) {}
78  virtual std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree, DaqProvenanceHelper const* daqProvenanceHelper) const;
79  private:
80  std::vector<ParentageID> const& parentageIDLookup_;
81  };
82 
83  namespace {
84  int
85  forcedRunOffset(RunNumber_t const& forcedRunNumber, IndexIntoFile::IndexIntoFileItr inxBegin, IndexIntoFile::IndexIntoFileItr inxEnd) {
86  if(inxBegin == inxEnd) return 0;
87  int defaultOffset = (inxBegin.run() != 0 ? 0 : 1);
88  int offset = (forcedRunNumber != 0U ? forcedRunNumber - inxBegin.run() : defaultOffset);
89  if(offset < 0) {
91  << "The value of the 'setRunNumber' parameter must not be\n"
92  << "less than the first run number in the first input file.\n"
93  << "'setRunNumber' was " << forcedRunNumber <<", while the first run was "
94  << forcedRunNumber - offset << ".\n";
95  }
96  return offset;
97  }
98  }
99 
100  // This is a helper class for IndexIntoFile.
102  public:
103  explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
104  virtual ~RootFileEventFinder() {}
105  virtual
108  eventTree_.setEntryNumber(entry);
109  EventAuxiliary eventAux;
110  EventAuxiliary *pEvAux = &eventAux;
112  eventTree_.setEntryNumber(saveEntry);
113  return eventAux.event();
114  }
115 
116  private:
118  };
119 
120 //---------------------------------------------------------------------
122  ProcessConfiguration const& processConfiguration,
123  std::string const& logicalFileName,
124  boost::shared_ptr<InputFile> filePtr,
125  boost::shared_ptr<EventSkipperByID> eventSkipperByID,
126  bool skipAnyEvents,
127  int remainingEvents,
128  int remainingLumis,
129  unsigned int treeCacheSize,
130  int treeMaxVirtualSize,
132  RunNumber_t const& forcedRunNumber,
133  bool noEventSort,
134  ProductSelectorRules const& productSelectorRules,
135  InputType::InputType inputType,
136  boost::shared_ptr<BranchIDListHelper> branchIDListHelper,
137  boost::shared_ptr<DuplicateChecker> duplicateChecker,
138  bool dropDescendants,
139  std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
140  std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile,
141  std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
142  bool labelRawDataLikeMC,
143  bool usingGoToEvent,
144  bool enablePrefetching) :
145  file_(fileName),
146  logicalFile_(logicalFileName),
147  processConfiguration_(processConfiguration),
148  processConfigurations_(),
149  filePtr_(filePtr),
150  eventSkipperByID_(eventSkipperByID),
151  fileFormatVersion_(),
152  fid_(),
153  indexIntoFileSharedPtr_(new IndexIntoFile),
154  indexIntoFile_(*indexIntoFileSharedPtr_),
155  orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
156  indexIntoFileBegin_(indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder)),
157  indexIntoFileEnd_(indexIntoFileBegin_),
158  indexIntoFileIter_(indexIntoFileBegin_),
159  eventProcessHistoryIDs_(),
160  eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
161  savedRunAuxiliary_(),
162  skipAnyEvents_(skipAnyEvents),
163  noEventSort_(noEventSort),
164  whyNotFastClonable_(0),
165  hasNewlyDroppedBranch_(),
166  branchListIndexesUnchanged_(false),
167  eventAux_(),
168  eventTree_(filePtr_, InEvent, treeMaxVirtualSize, treeCacheSize, roottree::defaultLearningEntries, enablePrefetching),
169  lumiTree_(filePtr_, InLumi, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries, enablePrefetching),
170  runTree_(filePtr_, InRun, treeMaxVirtualSize, roottree::defaultNonEventCacheSize, roottree::defaultNonEventLearningEntries, enablePrefetching),
171  treePointers_(),
172  lastEventEntryNumberRead_(-1LL),
173  productRegistry_(),
174  branchIDLists_(),
175  branchIDListHelper_(branchIDListHelper),
176  processingMode_(processingMode),
177  forcedRunOffset_(0),
178  newBranchToOldBranch_(),
179  eventHistoryTree_(nullptr),
180  eventSelectionIDs_(new EventSelectionIDVector),
181  branchListIndexes_(new BranchListIndexes),
182  history_(),
183  branchChildren_(new BranchChildren),
184  duplicateChecker_(duplicateChecker),
185  provenanceAdaptor_(),
186  provenanceReaderMaker_(),
187  eventBranchMapper_(),
188  parentageIDLookup_(),
189  daqProvenanceHelper_() {
190 
191  hasNewlyDroppedBranch_.fill(false);
192 
196 
197  // Read the metadata tree.
198  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
199  std::unique_ptr<TTree> metaDataTree(dynamic_cast<TTree *>(filePtr_->Get(poolNames::metaDataTreeName().c_str())));
200  if(nullptr == metaDataTree.get()) {
201  throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::metaDataTreeName()
202  << " in the input file.\n";
203  }
204 
205  // To keep things simple, we just read in every possible branch that exists.
206  // We don't pay attention to which branches exist in which file format versions
207 
209  if(metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
210  TBranch *fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
211  fft->SetAddress(&fftPtr);
212  roottree::getEntry(fft, 0);
213  metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
214  }
215 
216  FileID *fidPtr = &fid_;
217  if(metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != nullptr) {
218  metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
219  }
220 
221  IndexIntoFile *iifPtr = &indexIntoFile_;
222  if(metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != nullptr) {
223  metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
224  }
225 
226  // Need to read to a temporary registry so we can do a translation of the BranchKeys.
227  // This preserves backward compatibility against friendly class name algorithm changes.
228  ProductRegistry inputProdDescReg;
229  ProductRegistry *ppReg = &inputProdDescReg;
230  metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
231 
232  typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
233  PsetMap psetMap;
234  PsetMap *psetMapPtr = &psetMap;
235  if(metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
236  //backward compatibility
237  assert(!fileFormatVersion().parameterSetsTree());
238  metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
239  } else {
240  assert(fileFormatVersion().parameterSetsTree());
241  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
242  std::unique_ptr<TTree> psetTree(dynamic_cast<TTree *>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str())));
243  if(nullptr == psetTree.get()) {
244  throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parameterSetsTreeName()
245  << " in the input file.\n";
246  }
247 
248  typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
249  IdToBlobs idToBlob;
250  IdToBlobs* pIdToBlob = &idToBlob;
251  psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
252 
253  std::unique_ptr<TTreeCache> psetTreeCache = roottree::trainCache(psetTree.get(), *filePtr_, roottree::defaultNonEventCacheSize, "*");
254  psetTreeCache->SetEnablePrefetching(false);
255  filePtr_->SetCacheRead(psetTreeCache.get());
256  for(Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
257  psetTree->GetEntry(i);
258  psetMap.insert(idToBlob);
259  }
260  filePtr_->SetCacheRead(0);
261  }
262 
263  // backward compatibility
265  ProcessHistoryRegistry::collection_type *pHistMapPtr = &pHistMap;
266  if(metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != nullptr) {
267  metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
268  }
269 
271  ProcessHistoryRegistry::vector_type *pHistVectorPtr = &pHistVector;
272  if(metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != nullptr) {
273  metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
274  }
275 
276  ProcessConfigurationVector* procConfigVectorPtr = &processConfigurations_;
277  if(metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != nullptr) {
278  metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
279  }
280 
281  std::unique_ptr<BranchIDLists> branchIDListsAPtr(new BranchIDLists);
282  BranchIDLists* branchIDListsPtr = branchIDListsAPtr.get();
283  if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != nullptr) {
284  metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
285  }
286 
287  BranchChildren* branchChildrenBuffer = branchChildren_.get();
288  if(metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != nullptr) {
289  metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
290  }
291 
292  // backward compatibility
293  std::vector<EventProcessHistoryID> *eventHistoryIDsPtr = &eventProcessHistoryIDs_;
294  if(metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != nullptr) {
295  metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
296  }
297 
298  if(metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != nullptr) {
299  if(metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
300  metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), 0);
301  } else {
302  metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), 0);
303  }
304  }
305 
306  // Here we read the metadata tree
307  roottree::getEntry(metaDataTree.get(), 0);
308 
310 
312 
313  // Here we read the event history tree, if we have one.
315 
317  if(!fileFormatVersion().triggerPathsTracked()) {
318  ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
319  } else {
320  // Merge into the parameter set registry.
321  pset::Registry& psetRegistry = *pset::Registry::instance();
322  for(auto const& psetEntry : psetMap) {
323  ParameterSet pset(psetEntry.second.pset());
324  pset.setID(psetEntry.first);
325  psetRegistry.insertMapped(pset);
326  }
327  }
328  if(!fileFormatVersion().splitProductIDs()) {
329  // Old provenance format input file. Create a provenance adaptor.
331  inputProdDescReg, pHistMap, pHistVector, processConfigurations_, psetIdConverter, true));
332  // Fill in the branchIDLists branch from the provenance adaptor
333  branchIDLists_ = provenanceAdaptor_->branchIDLists();
334  } else {
335  if(!fileFormatVersion().triggerPathsTracked()) {
336  // New provenance format, but change in ParameterSet Format. Create a provenance adaptor.
338  inputProdDescReg, pHistMap, pHistVector, processConfigurations_, psetIdConverter, false));
339  }
340  // New provenance format input file. The branchIDLists branch was read directly from the input file.
341  if(metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == nullptr) {
343  << "Failed to find branchIDLists branch in metaData tree.\n";
344  }
345  branchIDLists_.reset(branchIDListsAPtr.release());
346  }
347 
348  if(labelRawDataLikeMC) {
349  std::string const rawData("FEDRawDataCollection");
350  std::string const source("source");
351  ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
352  BranchKey finder(rawData, source, "", "");
353  ProductRegistry::ProductList::iterator it = pList.lower_bound(finder);
354  if(it != pList.end() && it->first.friendlyClassName_ == rawData && it->first.moduleLabel_ == source) {
355  // We found raw data with a module label of source.
356  // We need to change the module label and process name.
357  // Create helper.
358  it->second.init();
359  daqProvenanceHelper_.reset(new DaqProvenanceHelper(it->second.unwrappedTypeID()));
360  // Create the new branch description
361  BranchDescription const& newBD = daqProvenanceHelper_->constBranchDescription_.me();
362  // Save info from the old and new branch descriptions
363  daqProvenanceHelper_->saveInfo(it->second, newBD);
364  // Map the new branch name to the old branch name.
365  it->second.init();
366  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), it->second.branchName()));
367  // Remove the old branch description from the product Registry.
368  pList.erase(it);
369  // Check that there was only one.
370  it = pList.lower_bound(finder);
371  assert(!(it != pList.end() && it->first.friendlyClassName_ == rawData && it->first.moduleLabel_ == source));
372  // Insert the new branch description into the product registry.
373  inputProdDescReg.copyProduct(newBD);
374  // Fix up other per file metadata.
375  daqProvenanceHelper_->fixMetaData(processConfigurations_, pHistVector);
376  daqProvenanceHelper_->fixMetaData(*branchIDLists_);
377  daqProvenanceHelper_->fixMetaData(*branchChildren_);
378  }
379  }
380 
383 
385 
386  validateFile(inputType, usingGoToEvent);
387 
388  // Read the parentage tree. Old format files are handled internally in readParentageTree().
390 
391  // Merge into the hashed registries.
392  if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
394  }
395 
396  initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
398  indexIntoFileEnd_ = indexIntoFile_.end(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
399  forcedRunOffset_ = forcedRunOffset(forcedRunNumber, indexIntoFileBegin_, indexIntoFileEnd_);
401 
402  // Set product presence information in the product registry.
403  ProductRegistry::ProductList const& pList = inputProdDescReg.productList();
404  for(auto const& product : pList) {
405  BranchDescription const& prod = product.second;
406  prod.init();
407  treePointers_[prod.branchType()]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
408  }
409 
411 
412  std::unique_ptr<ProductRegistry> newReg(new ProductRegistry);
413 
414  // Do the translation from the old registry to the new one
415  {
416  ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
417  for(auto const& product : prodList) {
418  BranchDescription const& prod = product.second;
419  std::string newFriendlyName = friendlyname::friendlyName(prod.className());
420  if(newFriendlyName == prod.friendlyClassName()) {
421  newReg->copyProduct(prod);
422  } else {
423  if(fileFormatVersion().splitProductIDs()) {
425  << "Cannot change friendly class name algorithm without more development work\n"
426  << "to update BranchIDLists. Contact the framework group.\n";
427  }
428  BranchDescription newBD(prod);
429  newBD.updateFriendlyClassName();
430  newReg->copyProduct(newBD);
431  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
432  }
433  }
434  dropOnInput(*newReg, productSelectorRules, dropDescendants, inputType);
435  // freeze the product registry
436  newReg->setFrozen(inputType != InputType::Primary);
437  productRegistry_.reset(newReg.release());
438  }
439 
440  // Here, we make the class that will make the ProvenanceReader
442 
443  // Set up information from the product registry.
444  ProductRegistry::ProductList const& prodList = productRegistry()->productList();
445  for(auto const& product : prodList) {
446  BranchDescription const& prod = product.second;
447  treePointers_[prod.branchType()]->addBranch(product.first, prod,
449  }
450 
451  // Determine if this file is fast clonable.
452  setIfFastClonable(remainingEvents, remainingLumis);
453 
454  // Update the branch id info.
455  if(inputType == InputType::Primary) {
457  }
458 
459  setRefCoreStreamer(true); // backward compatibility
460 
461  // We are done with our initial reading of EventAuxiliary.
463 
464  // Tell the event tree to begin training at the next read.
466 
467  // Train the run and lumi trees.
468  runTree_.trainCache("*");
469  lumiTree_.trainCache("*");
470  }
471 
473  }
474 
475  void
477  // Called only for old format files.
478  if(!fileFormatVersion().perEventProductIDs()) return;
479  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
480  std::unique_ptr<TTree> entryDescriptionTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str())));
481  if(nullptr == entryDescriptionTree.get()) {
482  throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::entryDescriptionTreeName()
483  << " in the input file.\n";
484  }
485 
486  EntryDescriptionID idBuffer;
487  EntryDescriptionID* pidBuffer = &idBuffer;
488  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
489 
491 
492  EventEntryDescription entryDescriptionBuffer;
493  EventEntryDescription *pEntryDescriptionBuffer = &entryDescriptionBuffer;
494  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
495 
496  // Fill in the parentage registry.
498 
499  for(Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
500  roottree::getEntry(entryDescriptionTree.get(), i);
501  if(idBuffer != entryDescriptionBuffer.id()) {
502  throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
503  }
504  oldregistry.insertMapped(entryDescriptionBuffer);
506  parents.parents() = entryDescriptionBuffer.parents();
508  ParentageID const oldID = parents.id();
509  daqProvenanceHelper_->fixMetaData(parents.parents());
510  ParentageID newID = parents.id();
511  if(newID != oldID) {
512  daqProvenanceHelper_->parentageIDMap_.insert(std::make_pair(oldID, newID));
513  }
514  }
515  registry.insertMapped(parents);
516  }
517  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), nullptr);
518  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), nullptr);
519  }
520 
521  void
523  if(!fileFormatVersion().splitProductIDs()) {
524  // Old format file.
526  return;
527  }
528  // New format file
529  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
530  std::unique_ptr<TTree> parentageTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str())));
531  if(nullptr == parentageTree.get()) {
532  throw Exception(errors::FileReadError) << "Could not find tree " << poolNames::parentageTreeName()
533  << " in the input file.\n";
534  }
535 
537  Parentage *pParentageBuffer = &parents;
538  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
539 
541 
542  parentageIDLookup_.reserve(parentageTree->GetEntries());
543  for(Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
544  roottree::getEntry(parentageTree.get(), i);
546  ParentageID const oldID = parents.id();
547  daqProvenanceHelper_->fixMetaData(parents.parents());
548  ParentageID newID = parents.id();
549  if(newID != oldID) {
550  daqProvenanceHelper_->parentageIDMap_.insert(std::make_pair(oldID, newID));
551  }
552  }
553  registry.insertMapped(parents);
554  parentageIDLookup_.push_back(parents.id());
555  }
556  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), nullptr);
557  }
558 
559  void
560  RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
561  if(fileFormatVersion().noMetaDataTrees() and !fileFormatVersion().storedProductProvenanceUsed()) {
562  //we must avoid copying the old branch which stored the per product per event provenance
564  return;
565  }
566  if(!fileFormatVersion().splitProductIDs()) {
568  return;
569  }
572  return;
573  }
574  // Find entry for first event in file
576  while(it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
577  ++it;
578  }
579  if(it == indexIntoFileEnd_) {
581  return;
582  }
583 
584  // From here on, record all reasons we can't fast clone.
588  }
589  if(skipAnyEvents_) {
591  }
592  if(remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
594  }
595  if(remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
597  }
598  // We no longer fast copy the EventAuxiliary branch, so there
599  // is no longer any need to disable fast copying because the run
600  // number is being modified. Also, this check did not work anyway
601  // because this function is called before forcedRunOffset_ is set.
602 
603  // if(forcedRunOffset_ != 0) {
604  // whyNotFastClonable_ += FileBlock::RunNumberModified;
605  // }
606  if(duplicateChecker_ &&
607  !duplicateChecker_->checkDisabled() &&
608  !duplicateChecker_->noDuplicatesInFile()) {
610  }
611  }
612 
613  std::unique_ptr<FileBlock>
615  return std::unique_ptr<FileBlock>(new FileBlock(fileFormatVersion(),
616  eventTree_.tree(),
618  lumiTree_.tree(),
620  runTree_.tree(),
621  runTree_.metaTree(),
624  file_,
626  modifiedIDs(),
628  branchIDLists_));
629  }
630 
631  std::string const&
632  RootFile::newBranchToOldBranch(std::string const& newBranch) const {
633  std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
634  if(it != newBranchToOldBranch_.end()) {
635  return it->second;
636  }
637  return newBranch;
638  }
639 
642  return indexIntoFileIter_;
643  }
644 
645  void
648  }
649 
650  bool
653  return false;
654  }
655  if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
656 
657  // See first if the entire lumi or run is skipped, so we won't have to read the event Auxiliary in that case.
659  return true;
660  }
661 
662  // The Lumi is not skipped. If this is an event, see if the event is skipped.
667  eventAux_.id().event())) {
668  return true;
669  }
670  }
671 
672  // Skip runs with no lumis if either lumisToSkip or lumisToProcess have been set to select lumis
674  eventSkipperByID_->skippingLumis()) {
676 
677  // There are no lumis in this run, not even ones we will skip
678  if(iterLumi.peekAheadAtLumi() == IndexIntoFile::invalidLumi) {
679  return true;
680  }
681  // If we get here there are lumis in the run, check to see if we are skipping all of them
682  do {
683  if(!eventSkipperByID_->skipIt(iterLumi.run(), iterLumi.peekAheadAtLumi(), 0U)) {
684  return false;
685  }
686  }
687  while(iterLumi.skipLumiInRun());
688  return true;
689  }
690  }
691  return false;
692  }
693 
696  while(skipThisEntry()) {
699  }
702  }
703  else {
705  }
706  }
708  }
709 
710  bool
713  if(duplicateChecker_.get() == nullptr) {
714  return false;
715  }
717  return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
719  }
720 
724  if(entryType == IndexIntoFile::kEnd) {
725  return IndexIntoFile::kEnd;
726  }
727  if(entryType == IndexIntoFile::kRun) {
728  return IndexIntoFile::kRun;
729  } else if(processingMode_ == InputSource::Runs) {
731  return getNextEntryTypeWanted();
732  }
733  if(entryType == IndexIntoFile::kLumi) {
734  return IndexIntoFile::kLumi;
737  return getNextEntryTypeWanted();
738  }
739  if(isDuplicateEvent()) {
741  return getNextEntryTypeWanted();
742  }
743  return IndexIntoFile::kEvent;
744  }
745 
746  bool
749  itr.advanceToEvent();
750  return itr.getEntryType() == IndexIntoFile::kEnd;
751  }
752 
753  bool
756  int phIndex;
759  IndexIntoFile::EntryNumber_t eventEntry;
760  itr.skipEventBackward(phIndex,
761  run,
762  lumi,
763  eventEntry);
764  itr.skipEventBackward(phIndex,
765  run,
766  lumi,
767  eventEntry);
768  return eventEntry == IndexIntoFile::invalidEntry;
769  }
770 
771  namespace {
772  typedef IndexIntoFile::EntryNumber_t EntryNumber_t;
773  struct RunItem {
774  RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) :
775  phid_(phid), run_(run) {}
776  ProcessHistoryID phid_;
777  RunNumber_t run_;
778  };
779  struct RunItemSortByRun {
780  bool operator()(RunItem const& a, RunItem const& b) const {
781  return a.run_ < b.run_;
782  }
783  };
784  struct RunItemSortByRunPhid {
785  bool operator()(RunItem const& a, RunItem const& b) const {
786  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
787  }
788  };
789  struct LumiItem {
790  LumiItem(ProcessHistoryID const& phid, RunNumber_t const& run,
791  LuminosityBlockNumber_t const& lumi, EntryNumber_t const& entry) :
792  phid_(phid), run_(run), lumi_(lumi), firstEventEntry_(entry),
793  lastEventEntry_(entry == -1LL ? -1LL : entry + 1) {}
794  ProcessHistoryID phid_;
795  RunNumber_t run_;
797  EntryNumber_t firstEventEntry_;
798  EntryNumber_t lastEventEntry_;
799  };
800  struct LumiItemSortByRunLumi {
801  bool operator()(LumiItem const& a, LumiItem const& b) const {
802  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
803  }
804  };
805  struct LumiItemSortByRunLumiPhid {
806  bool operator()(LumiItem const& a, LumiItem const& b) const {
807  if(a.run_ < b.run_) return true;
808  if(b.run_ < a.run_) return false;
809  if(a.lumi_ < b.lumi_) return true;
810  if(b.lumi_ < a.lumi_) return false;
811  return a.phid_ < b.phid_;
812  }
813  };
814  }
815 
816  void
818  // This function is for backward compatibility.
819  // If reading a current format file, indexIntoFile_ is read from the input
820  // file and should always be there. Note that the algorithm below will work
821  // sometimes but often fail with the new format introduced in release 3_8_0.
822  // If it ever becomes necessary to rebuild IndexIntoFile from the new format,
823  // probably a separate function should be written to deal with the task.
824  // This is possible just not implemented yet.
825  assert(!fileFormatVersion().hasIndexIntoFile());
826 
827  typedef std::list<LumiItem> LumiList;
828  LumiList lumis; // (declare 1)
829 
830  typedef std::set<LuminosityBlockID> RunLumiSet;
831  RunLumiSet runLumiSet; // (declare 2)
832 
833  typedef std::list<RunItem> RunList;
834  RunList runs; // (declare 5)
835 
836  typedef std::set<RunNumber_t> RunSet;
837  RunSet runSet; // (declare 4)
838 
839  typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
840  RunItemSet runItemSet; // (declare 3)
841 
842  typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
843  PHIDMap phidMap;
844 
845  RunNumber_t prevRun = 0;
846  LuminosityBlockNumber_t prevLumi = 0;
847  ProcessHistoryID prevPhid;
848  bool iFirst = true;
849 
850  indexIntoFile_.unsortedEventNumbers().clear(); // should already be empty, just being careful
852 
853  // First, loop through the event tree.
854  while(eventTree_.next()) {
855  bool newRun = false;
856  bool newLumi = false;
858  fillHistory();
859 
860  // Save the event numbers as we loop through the event auxiliary to avoid
861  // having to read through the event auxiliary again later. These event numbers
862  // are not actually used in this function, but could be needed elsewhere.
864 
865  ProcessHistoryID reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(eventAux().processHistoryID());
866 
867  if(iFirst || prevPhid != reducedPHID || prevRun != eventAux().run()) {
868  iFirst = false;
869  newRun = newLumi = true;
870  } else if(prevLumi != eventAux().luminosityBlock()) {
871  newLumi = true;
872  }
873  prevPhid = reducedPHID;
874  prevRun = eventAux().run();
875  prevLumi = eventAux().luminosityBlock();
876  if(newLumi) {
877  lumis.emplace_back(reducedPHID,
878  eventAux().run(), eventAux().luminosityBlock(), eventTree_.entryNumber()); // (insert 1)
879  runLumiSet.insert(LuminosityBlockID(eventAux().run(), eventAux().luminosityBlock())); // (insert 2)
880  } else {
881  LumiItem& currentLumi = lumis.back();
882  assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
883  ++currentLumi.lastEventEntry_;
884  }
885  if(newRun) {
886  // Insert run in list if it is not already there.
887  RunItem item(reducedPHID, eventAux().run());
888  if(runItemSet.insert(item).second) { // (check 3, insert 3)
889  runs.push_back(std::move(item)); // (insert 5)
890  runSet.insert(eventAux().run()); // (insert 4)
891  phidMap.insert(std::make_pair(eventAux().run(), reducedPHID));
892  }
893  }
894  }
895  // now clean up.
899 
900  // Loop over run entries and fill information.
901 
902  typedef std::map<RunNumber_t, EntryNumber_t> RunMap;
903  RunMap runMap; // (declare 11)
904 
905  typedef std::vector<RunItem> RunVector;
906  RunVector emptyRuns; // (declare 12)
907 
908  if(runTree_.isValid()) {
909  while(runTree_.next()) {
910  // Note: adjacent duplicates will be skipped without an explicit check.
911 
912  boost::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
913  ProcessHistoryID reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(runAux->processHistoryID());
914 
915  if(runSet.insert(runAux->run()).second) { // (check 4, insert 4)
916  // This run was not associated with any events.
917  emptyRuns.emplace_back(reducedPHID, runAux->run()); // (insert 12)
918  }
919  runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber())); // (insert 11)
920  phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
921  }
922  // now clean up.
924  }
925 
926  // Insert the ordered empty runs into the run list.
927  RunItemSortByRun runItemSortByRun;
928  stable_sort_all(emptyRuns, runItemSortByRun);
929 
930  RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
931  for(auto const& emptyRun : emptyRuns) {
932  for(; itRuns != endRuns; ++itRuns) {
933  if(runItemSortByRun(emptyRun, *itRuns)) {
934  break;
935  }
936  }
937  runs.insert(itRuns, emptyRun);
938  }
939 
940  // Loop over luminosity block entries and fill information.
941 
942  typedef std::vector<LumiItem> LumiVector;
943  LumiVector emptyLumis; // (declare 7)
944 
945  typedef std::map<LuminosityBlockID, EntryNumber_t> RunLumiMap;
946  RunLumiMap runLumiMap; // (declare 6)
947 
948  if(lumiTree_.isValid()) {
949  while(lumiTree_.next()) {
950  // Note: adjacent duplicates will be skipped without an explicit check.
951  boost::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
952  LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
953  if(runLumiSet.insert(lumiID).second) { // (check 2, insert 2)
954  // This lumi was not associated with any events.
955  // Use the process history ID from the corresponding run. In cases of practical
956  // importance, this should be the correct process history ID, but it is possible
957  // to construct files where this is not the correct process history ID ...
958  PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
959  assert(iPhidMap != phidMap.end());
960  emptyLumis.emplace_back(iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), -1LL); // (insert 7)
961  }
962  runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
963  }
964  // now clean up.
966  }
967 
968  // Insert the ordered empty lumis into the lumi list.
969  LumiItemSortByRunLumi lumiItemSortByRunLumi;
970  stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
971 
972  LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
973  for(auto const& emptyLumi : emptyLumis) {
974  for(; itLumis != endLumis; ++itLumis) {
975  if(lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
976  break;
977  }
978  }
979  lumis.insert(itLumis, emptyLumi);
980  }
981 
982  // Create a map of RunItems that gives the order of first appearance in the list.
983  // Also fill in the vector of process history IDs
984  typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
985  RunCountMap runCountMap; // Declare (17)
986  std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
987  assert(phids.empty());
988  std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
989  assert(entries.empty());
990  int rcount = 0;
991  for(auto& run : runs) {
992  RunCountMap::const_iterator countMapItem = runCountMap.find(run);
993  if(countMapItem == runCountMap.end()) {
994  countMapItem = runCountMap.insert(std::make_pair(run, rcount)).first; // Insert (17)
995  assert(countMapItem != runCountMap.end());
996  ++rcount;
997  }
998  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, run.phid_);
999  if(phidItem == phids.end()) {
1000  phids.push_back(run.phid_);
1001  phidItem = phids.end() - 1;
1002  }
1003  entries.emplace_back(
1004  countMapItem->second, // use (17)
1005  -1LL,
1006  runMap[run.run_], // use (11)
1007  phidItem - phids.begin(),
1008  run.run_,
1009  0U,
1010  -1LL,
1011  -1LL);
1012  }
1013 
1014  // Create a map of LumiItems that gives the order of first appearance in the list.
1015  typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1016  LumiCountMap lumiCountMap; // Declare (19)
1017  int lcount = 0;
1018  for(auto& lumi : lumis) {
1019  RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(lumi.phid_, lumi.run_));
1020  assert(runCountMapItem != runCountMap.end());
1021  LumiCountMap::const_iterator countMapItem = lumiCountMap.find(lumi);
1022  if(countMapItem == lumiCountMap.end()) {
1023  countMapItem = lumiCountMap.insert(std::make_pair(lumi, lcount)).first; // Insert (17)
1024  assert(countMapItem != lumiCountMap.end());
1025  ++lcount;
1026  }
1027  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, lumi.phid_);
1028  assert(phidItem != phids.end());
1029  entries.emplace_back(
1030  runCountMapItem->second,
1031  countMapItem->second,
1032  runLumiMap[LuminosityBlockID(lumi.run_, lumi.lumi_)],
1033  phidItem - phids.begin(),
1034  lumi.run_,
1035  lumi.lumi_,
1036  lumi.firstEventEntry_,
1037  lumi.lastEventEntry_);
1038  }
1039  stable_sort_all(entries);
1040  }
1041 
1042  void
1043  RootFile::validateFile(InputType::InputType inputType, bool usingGoToEvent) {
1044  if(!fid_.isValid()) {
1046  }
1047  if(!eventTree_.isValid()) {
1049  "'Events' tree is corrupted or not present\n" << "in the input file.\n";
1050  }
1051 
1052  if(fileFormatVersion().hasIndexIntoFile()) {
1053  if(runTree().entries() > 0) {
1054  assert(!indexIntoFile_.empty());
1055  }
1057  if(daqProvenanceHelper_) {
1058  std::vector<ProcessHistoryID>& phidVec = indexIntoFile_.setProcessHistoryIDs();
1059  for(auto& phid : phidVec) {
1060  phid = daqProvenanceHelper_->mapProcessHistoryID(phid);
1061  }
1062  }
1064  }
1065  }
1066  else {
1067  assert(indexIntoFile_.empty());
1069  }
1070 
1073  indexIntoFile_.setEventFinder(boost::shared_ptr<IndexIntoFile::EventFinder>(new RootFileEventFinder(eventTree_)));
1074  // We fill the event numbers explicitly if we need to find events in closed files,
1075  // such as for secondary files (or secondary sources) or if duplicate checking across files.
1076  bool needEventNumbers = false;
1077  bool needIndexesForDuplicateChecker = duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
1078  if(inputType != InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1079  needEventNumbers = true;
1080  }
1081  bool needEventEntries = false;
1082  if(inputType != InputType::Primary || !noEventSort_) {
1083  // We need event entries for sorting or for secondary files or sources.
1084  needEventEntries = true;
1085  }
1086  indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
1087  }
1088 
1089  void
1091  // Report file opened.
1092  std::string const label = "source";
1093  std::string moduleName = "PoolSource";
1094  filePtr_->inputFileOpened(
1095  logicalFile_,
1096  inputType,
1097  moduleName,
1098  label,
1099  fid_.fid(),
1101  }
1102 
1103  void
1105  // Just to play it safe, zero all pointers to objects in the InputFile to be closed.
1106  eventHistoryTree_ = nullptr;
1107  for(auto& treePointer : treePointers_) {
1108  treePointer->close();
1109  treePointer = nullptr;
1110  }
1111  filePtr_->Close();
1112  filePtr_.reset();
1113  }
1114 
1115  void
1118  // Already read.
1119  return;
1120  }
1122  EventAuxiliary *pEvAux = &eventAux_;
1124  } else {
1125  // for backward compatibility.
1127  EventAux *pEvAux = &eventAux;
1128  eventTree_.fillAux<EventAux>(pEvAux);
1129  conversion(eventAux, eventAux_);
1130  }
1132  }
1133 
1134  void
1138  }
1139 
1140  void
1142  // We could consider doing delayed reading, but because we have to
1143  // store this History object in a different tree than the event
1144  // data tree, this is too hard to do in this first version.
1145 
1146  if(fileFormatVersion().eventHistoryBranch()) {
1147  // Lumi block number was not in EventID for the relevant releases.
1148  EventID id(eventAux().id().run(), 0, eventAux().id().event());
1149  if(eventProcessHistoryIter_->eventID() != id) {
1152  assert(eventProcessHistoryIter_->eventID() == id);
1153  }
1156  } else if(fileFormatVersion().eventHistoryTree()) {
1157  // for backward compatibility.
1158  History* pHistory = history_.get();
1159  TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
1160  if(!eventHistoryBranch) {
1162  << "Failed to find history branch in event history tree.\n";
1163  }
1164  eventHistoryBranch->SetAddress(&pHistory);
1166  eventAux_.setProcessHistoryID(history_->processHistoryID());
1167  eventSelectionIDs_.reset(&history_->eventSelectionIDs(), do_nothing_deleter());
1168  branchListIndexes_.reset(&history_->branchListIndexes(), do_nothing_deleter());
1169  } else if(fileFormatVersion().noMetaDataTrees()) {
1170  // Current format
1172  TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
1173  assert(eventSelectionIDBranch != nullptr);
1174  eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
1175  BranchListIndexes* pBLI = branchListIndexes_.get();
1176  TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
1177  assert(branchListIndexesBranch != nullptr);
1178  eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
1179  }
1180  if(provenanceAdaptor_) {
1181  eventAux_.setProcessHistoryID(provenanceAdaptor_->convertID(eventAux().processHistoryID()));
1182  for(auto& esID : *eventSelectionIDs_) {
1183  esID = provenanceAdaptor_->convertID(esID);
1184  }
1185  }
1186  if(daqProvenanceHelper_) {
1188  }
1190  // old format. branchListIndexes_ must be filled in from the ProvenanceAdaptor.
1191  provenanceAdaptor_->branchListIndexes(*branchListIndexes_);
1192  }
1193  branchIDListHelper_->fixBranchListIndexes(*branchListIndexes_);
1194  }
1195 
1196  boost::shared_ptr<LuminosityBlockAuxiliary>
1198  boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary(new LuminosityBlockAuxiliary);
1199  if(fileFormatVersion().newAuxiliary()) {
1200  LuminosityBlockAuxiliary *pLumiAux = lumiAuxiliary.get();
1202  } else {
1203  LuminosityBlockAux lumiAux;
1204  LuminosityBlockAux *pLumiAux = &lumiAux;
1206  conversion(lumiAux, *lumiAuxiliary);
1207  }
1208  if(provenanceAdaptor_) {
1209  lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1210  }
1211  if(daqProvenanceHelper_) {
1212  lumiAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1213  }
1214  if(lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
1215  lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
1216  }
1217  return lumiAuxiliary;
1218  }
1219 
1220  boost::shared_ptr<RunAuxiliary>
1222  boost::shared_ptr<RunAuxiliary> runAuxiliary(new RunAuxiliary);
1223  if(fileFormatVersion().newAuxiliary()) {
1224  RunAuxiliary *pRunAux = runAuxiliary.get();
1225  runTree_.fillAux<RunAuxiliary>(pRunAux);
1226  } else {
1227  RunAux runAux;
1228  RunAux *pRunAux = &runAux;
1229  runTree_.fillAux<RunAux>(pRunAux);
1230  conversion(runAux, *runAuxiliary);
1231  }
1232  if(provenanceAdaptor_) {
1233  runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1234  }
1235  if(daqProvenanceHelper_) {
1236  runAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1237  }
1238  return runAuxiliary;
1239  }
1240 
1241  bool
1243  while(offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
1244 
1245  int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
1246  RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
1249 
1250  indexIntoFileIter_.skipEventForward(phIndexOfSkippedEvent,
1251  runOfSkippedEvent,
1252  lumiOfSkippedEvent,
1253  skippedEventEntry);
1254 
1255  // At the end of the file and there were no more events to skip
1256  if(skippedEventEntry == IndexIntoFile::invalidEntry) break;
1257 
1258  if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1259  eventTree_.setEntryNumber(skippedEventEntry);
1261  if(eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, eventAux_.id().event())) {
1262  continue;
1263  }
1264  }
1265  if(duplicateChecker_ &&
1266  !duplicateChecker_->checkDisabled() &&
1267  !duplicateChecker_->noDuplicatesInFile()) {
1268 
1269  eventTree_.setEntryNumber(skippedEventEntry);
1271  if(duplicateChecker_->isDuplicateAndCheckActive(phIndexOfSkippedEvent,
1272  runOfSkippedEvent,
1273  lumiOfSkippedEvent,
1274  eventAux_.id().event(),
1275  file_)) {
1276  continue;
1277  }
1278  }
1279  --offset;
1280  }
1281 
1282  while(offset < 0) {
1283 
1284  if(duplicateChecker_) {
1285  duplicateChecker_->disable();
1286  }
1287 
1288  int phIndexOfEvent = IndexIntoFile::invalidIndex;
1291  EntryNumber_t eventEntry = IndexIntoFile::invalidEntry;
1292 
1293  indexIntoFileIter_.skipEventBackward(phIndexOfEvent,
1294  runOfEvent,
1295  lumiOfEvent,
1296  eventEntry);
1297 
1298  if(eventEntry == IndexIntoFile::invalidEntry) break;
1299 
1300  if(eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1301  eventTree_.setEntryNumber(eventEntry);
1303  if(eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, eventAux_.id().event())) {
1304  continue;
1305  }
1306  }
1307  ++offset;
1308  }
1310  }
1311 
1312  bool
1313  RootFile::goToEvent(EventID const& eventID) {
1314 
1316 
1317  if(duplicateChecker_) {
1318  duplicateChecker_->disable();
1319  }
1320 
1323 
1325  indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
1326 
1327  if(iter == indexIntoFile_.end(sortOrder)) {
1328  return false;
1329  }
1330  indexIntoFileIter_ = iter;
1331  return true;
1332  }
1333 
1334  // readEvent() is responsible for creating, and setting up, the
1335  // EventPrincipal.
1336  //
1337  // 1. create an EventPrincipal with a unique EventID
1338  // 2. For each entry in the provenance, put in one ProductHolder,
1339  // holding the Provenance for the corresponding EDProduct.
1340  // 3. set up the caches in the EventPrincipal to know about this
1341  // ProductHolder.
1342  //
1343  // We do *not* create the EDProduct instance (the equivalent of reading
1344  // the branch containing this EDProduct. That will be done by the Delayed Reader,
1345  // when it is asked to do so.
1346  //
1351  // Set the entry in the tree, and read the event at that entry.
1353  EventPrincipal* ep = readCurrentEvent(cache);
1354 
1355  assert(ep != nullptr);
1356  assert(eventAux().run() == indexIntoFileIter_.run() + forcedRunOffset_);
1357  assert(eventAux().luminosityBlock() == indexIntoFileIter_.lumi());
1358 
1359  // If this next assert shows up in performance profiling or significantly affects memory, then these three lines should be deleted.
1360  // The IndexIntoFile should guarantee that it never fails.
1362  ProcessHistoryID const& reducedPHID = ProcessHistoryRegistry::instance()->extra().reduceProcessHistoryID(idToCheck);
1364 
1366  return ep;
1367  }
1368 
1369  // Reads event at the current entry in the event tree
1372  if(!eventTree_.current()) {
1373  return nullptr;
1374  }
1376  if(!fileFormatVersion().lumiInEventID()) {
1377  //ugly, but will disappear when the backward compatibility is done with schema evolution.
1378  const_cast<EventID&>(eventAux_.id()).setLuminosityBlockNumber(eventAux_.oldLuminosityBlock());
1380  }
1381  fillHistory();
1383 
1384  // We're not done ... so prepare the EventPrincipal
1385  cache.fillEventPrincipal(eventAux(),
1388  makeBranchMapper(),
1390 
1391  // report event read from file
1392  filePtr_->eventReadFromFile(eventID().run(), eventID().event());
1393  return &cache;
1394  }
1395 
1396  void
1398  eventTree_.setEntryNumber(entry);
1399  }
1400 
1401  boost::shared_ptr<RunAuxiliary>
1405 
1406  // Begin code for backward compatibility before the existence of run trees.
1407  if(!runTree_.isValid()) {
1408 
1409  // prior to the support of run trees.
1410  // RunAuxiliary did not contain a valid timestamp. Take it from the next event.
1412  assert(eventEntry != IndexIntoFile::invalidEntry);
1414  eventTree_.setEntryNumber(eventEntry);
1415  assert(eventTree_.current());
1417  eventTree_.setEntryNumber(savedEntry);
1418 
1420  overrideRunNumber(run);
1421  return boost::shared_ptr<RunAuxiliary>(new RunAuxiliary(run.run(), eventAux().time(), Timestamp::invalidTimestamp()));
1422  }
1423  // End code for backward compatibility before the existence of run trees.
1425  boost::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
1426  assert(runAuxiliary->run() == indexIntoFileIter_.run());
1427  overrideRunNumber(runAuxiliary->id());
1428  filePtr_->reportInputRunNumber(runAuxiliary->run());
1429  // If RunAuxiliary did not contain a valid begin timestamp, invalidate any end timestamp.
1430  if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1431  runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1432  }
1433 
1434  // If RunAuxiliary did not contain a valid timestamp, or if this an old format file from
1435  // when the Run's ProcessHistory included only processes where products were added to the Run itself,
1436  // we attempt to read the first event in the run to get appropriate info.
1437  if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp() ||
1439 
1441  // If we have a valid event, use its information.
1442  if(eventEntry != IndexIntoFile::invalidEntry) {
1444  eventTree_.setEntryNumber(eventEntry);
1445  assert(eventTree_.current());
1447 
1448  // RunAuxiliary did not contain a valid timestamp. Take it from the next event in this run if there is one.
1449  if(runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1450  runAuxiliary->setBeginTime(eventAux().time());
1451  }
1452 
1453  // For backwards compatibility when the Run's ProcessHistory included only processes where products were added to the
1454  // Run, and then the Run and Event auxiliaries could be different. Use the event ProcessHistoryID if there is one. It should
1455  // almost always be correct by the current definition (processes included if any products are added. This makes the run, lumi,
1456  // and event ProcessHistory's always be the same if no file merging occurs).
1457  if(!fileFormatVersion().processHistorySameWithinRun()) {
1458  fillHistory();
1459  runAuxiliary->setProcessHistoryID(eventAux().processHistoryID());
1460  savedRunAuxiliary_ = runAuxiliary;
1461  }
1462  eventTree_.setEntryNumber(savedEntry);
1463  } else {
1464  // No valid event, just use what is there, because it is the best we can do.
1465  savedRunAuxiliary_ = runAuxiliary;
1466  }
1467  }
1468  return runAuxiliary;
1469  }
1470 
1471  boost::shared_ptr<RunPrincipal>
1472  RootFile::readRun_(boost::shared_ptr<RunPrincipal> runPrincipal) {
1475  // Begin code for backward compatibility before the existence of run trees.
1476  if(!runTree_.isValid()) {
1478  return runPrincipal;
1479  }
1480  // End code for backward compatibility before the existence of run trees.
1481  runPrincipal->fillRunPrincipal(runTree_.rootDelayedReader());
1482  // Read in all the products now.
1483  runPrincipal->readImmediate();
1485  return runPrincipal;
1486  }
1487 
1488  boost::shared_ptr<LuminosityBlockAuxiliary>
1492  // Begin code for backward compatibility before the existence of lumi trees.
1493  if(!lumiTree_.isValid()) {
1495  assert(eventEntry != IndexIntoFile::invalidEntry);
1497  eventTree_.setEntryNumber(eventEntry);
1498  assert(eventTree_.current());
1500  eventTree_.setEntryNumber(savedEntry);
1501 
1503  overrideRunNumber(lumi);
1504  return boost::shared_ptr<LuminosityBlockAuxiliary>(new LuminosityBlockAuxiliary(lumi.run(), lumi.luminosityBlock(), eventAux().time(), Timestamp::invalidTimestamp()));
1505  }
1506  // End code for backward compatibility before the existence of lumi trees.
1508  boost::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
1509  assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
1510  assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
1511  overrideRunNumber(lumiAuxiliary->id());
1512  filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1513  if(lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1515  if(eventEntry != IndexIntoFile::invalidEntry) {
1517  eventTree_.setEntryNumber(eventEntry);
1518  assert(eventTree_.current());
1520  eventTree_.setEntryNumber(savedEntry);
1521 
1522  lumiAuxiliary->setBeginTime(eventAux().time());
1523  }
1524  lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1525  }
1526  if(!fileFormatVersion().processHistorySameWithinRun() && savedRunAuxiliary_) {
1527  lumiAuxiliary->setProcessHistoryID(savedRunAuxiliary_->processHistoryID());
1528  }
1529  return lumiAuxiliary;
1530  }
1531 
1532  boost::shared_ptr<LuminosityBlockPrincipal>
1533  RootFile::readLumi(boost::shared_ptr<LuminosityBlockPrincipal> lumiPrincipal) {
1536  // Begin code for backward compatibility before the existence of lumi trees.
1537  if(!lumiTree_.isValid()) {
1539  return lumiPrincipal;
1540  }
1541  // End code for backward compatibility before the existence of lumi trees.
1543  lumiPrincipal->fillLuminosityBlockPrincipal(lumiTree_.rootDelayedReader());
1544  // Read in all the products now.
1545  lumiPrincipal->readImmediate();
1547  return lumiPrincipal;
1548  }
1549 
1550  bool
1553  if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
1555  return true;
1556  }
1557 
1558  bool
1561  if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
1563  return true;
1564  }
1565 
1566  bool
1569  if(indexIntoFileIter_ == indexIntoFileEnd_) return false;
1571  return true;
1572  }
1573 
1574  bool
1578  }
1581  if(run != indexIntoFileIter_.run()) return false;
1582  if(lumi != indexIntoFileIter_.lumi()) return false;
1584  return true;
1585  }
1586 
1587  void
1589  if(forcedRunOffset_ != 0) {
1590  id = RunID(id.run() + forcedRunOffset_);
1591  }
1592  if(id < RunID::firstValidRun()) id = RunID::firstValidRun();
1593  }
1594 
1595  void
1597  if(forcedRunOffset_ != 0) {
1598  id = LuminosityBlockID(id.run() + forcedRunOffset_, id.luminosityBlock());
1599  }
1600  if(RunID(id.run()) < RunID::firstValidRun()) id = LuminosityBlockID(RunID::firstValidRun().run(), id.luminosityBlock());
1601  }
1602 
1603  void
1604  RootFile::overrideRunNumber(EventID& id, bool isRealData) {
1605  if(forcedRunOffset_ != 0) {
1606  if(isRealData) {
1607  throw Exception(errors::Configuration, "RootFile::RootFile()")
1608  << "The 'setRunNumber' parameter of PoolSource cannot be used with real data.\n";
1609  }
1610  id = EventID(id.run() + forcedRunOffset_, id.luminosityBlock(), id.event());
1611  }
1612  if(RunID(id.run()) < RunID::firstValidRun()) {
1614  }
1615  }
1616 
1617 
1618  void
1620  // Read in the event history tree, if we have one...
1621  if(fileFormatVersion().eventHistoryTree()) {
1622  history_.reset(new History);
1623  eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
1624  if(!eventHistoryTree_) {
1626  << "Failed to find the event history tree.\n";
1627  }
1628  }
1629  }
1630 
1631  void
1633  std::string releaseVersion = getReleaseVersion();
1634  releaseversion::DecomposedReleaseVersion currentRelease(releaseVersion);
1635  for(auto const& pc : processConfigurations_) {
1636  if(releaseversion::isEarlierRelease(currentRelease, pc.releaseVersion())) {
1638  << "The release you are using, " << getReleaseVersion() << " , predates\n"
1639  << "a release (" << pc.releaseVersion() << ") used in writing the input file, " << file() <<".\n"
1640  << "Forward compatibility cannot be supported.\n";
1641  }
1642  }
1643  }
1644 
1645  void
1647  std::vector<boost::shared_ptr<IndexIntoFile> > const& indexesIntoFiles,
1648  std::vector<boost::shared_ptr<IndexIntoFile> >::size_type currentIndexIntoFile) {
1649  if(duplicateChecker_) {
1650  if(eventTree_.next()) {
1652  duplicateChecker_->inputFileOpened(eventAux().isRealData(),
1654  indexesIntoFiles,
1655  currentIndexIntoFile);
1656  }
1658  }
1659  }
1660 
1661  void
1663  // This is the selector for drop on input.
1664  ProductSelector productSelector;
1665  productSelector.initialize(rules, reg.allBranchDescriptions());
1666 
1668  // Do drop on input. On the first pass, just fill in a set of branches to be dropped.
1669  std::set<BranchID> branchesToDrop;
1670  for(auto const& product : prodList) {
1671  BranchDescription const& prod = product.second;
1672  if(!productSelector.selected(prod)) {
1673  if(dropDescendants) {
1674  branchChildren_->appendToDescendants(prod.branchID(), branchesToDrop);
1675  } else {
1676  branchesToDrop.insert(prod.branchID());
1677  }
1678  }
1679  }
1680 
1681  // On this pass, actually drop the branches.
1682  std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
1683  for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1684  BranchDescription const& prod = it->second;
1685  bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
1686  if(drop) {
1687  if(productSelector.selected(prod)) {
1688  LogWarning("RootFile")
1689  << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
1690  << "of file '" << file_ << "' because it is dependent on a branch\n"
1691  << "that was explicitly dropped.\n";
1692  }
1693  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
1694  hasNewlyDroppedBranch_[prod.branchType()] = true;
1695  ProductRegistry::ProductList::iterator icopy = it;
1696  ++it;
1697  prodList.erase(icopy);
1698  } else {
1699  ++it;
1700  }
1701  }
1702 
1703  // Drop on input mergeable run and lumi products, this needs to be invoked for secondary file input
1704  if(inputType == InputType::SecondaryFile) {
1705  TString tString;
1706  for(ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1707  BranchDescription const& prod = it->second;
1708  if(prod.branchType() != InEvent) {
1709  TClass *cp = gROOT->GetClass(prod.wrappedName().c_str());
1710  WrapperOwningHolder edp(cp->New(), prod.getInterface());
1711  if(edp.isMergeable()) {
1712  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
1713  ProductRegistry::ProductList::iterator icopy = it;
1714  ++it;
1715  prodList.erase(icopy);
1716  } else {
1717  ++it;
1718  }
1719  }
1720  else ++it;
1721  }
1722  }
1723  }
1724 
1725  std::unique_ptr<MakeProvenanceReader>
1728  return std::unique_ptr<MakeProvenanceReader>(new MakeReducedProvenanceReader(parentageIDLookup_));
1729  } else if(fileFormatVersion_.splitProductIDs()) {
1730  return std::unique_ptr<MakeProvenanceReader>(new MakeFullProvenanceReader);
1731  } else if(fileFormatVersion_.perEventProductIDs()) {
1732  return std::unique_ptr<MakeProvenanceReader>(new MakeOldProvenanceReader);
1733  } else {
1734  return std::unique_ptr<MakeProvenanceReader>(new MakeDummyProvenanceReader);
1735  }
1736  }
1737 
1738  boost::shared_ptr<BranchMapper>
1740  if(!eventBranchMapper_) {
1742  }
1743  eventBranchMapper_->reset();
1744  return eventBranchMapper_;
1745  }
1746 
1748  public:
1749  ReducedProvenanceReader(RootTree* iRootTree, std::vector<ParentageID> const& iParentageIDLookup, DaqProvenanceHelper const* daqProvenanceHelper);
1750  private:
1751  virtual void readProvenance(BranchMapper const& mapper) const;
1753  TBranch* provBranch_;
1756  std::vector<ParentageID> const& parentageIDLookup_;
1758  };
1759 
1761  RootTree* iRootTree,
1762  std::vector<ParentageID> const& iParentageIDLookup,
1763  DaqProvenanceHelper const* daqProvenanceHelper) :
1765  rootTree_(iRootTree),
1766  pProvVector_(&provVector_),
1767  parentageIDLookup_(iParentageIDLookup),
1768  daqProvenanceHelper_(daqProvenanceHelper) {
1770  }
1771 
1772  void
1774  ReducedProvenanceReader* me = const_cast<ReducedProvenanceReader*>(this);
1776  setRefCoreStreamer(true);
1777  if(daqProvenanceHelper_) {
1778  for(auto const& prov : provVector_) {
1779  BranchID bid(prov.branchID_);
1781  daqProvenanceHelper_->mapParentageID(parentageIDLookup_[prov.parentageIDIndex_])));
1782  }
1783  } else {
1784  for(auto const& prov : provVector_) {
1785  if(prov.parentageIDIndex_ >= parentageIDLookup_.size()) {
1787  << "ReducedProvenanceReader::ReadProvenance\n"
1788  << "The parentage ID index value " << prov.parentageIDIndex_ << " is out of bounds. The maximum value is " << parentageIDLookup_.size()-1 << ".\n"
1789  << "This should never happen.\n"
1790  << "Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
1791  }
1792  mapper.insertIntoSet(ProductProvenance(BranchID(prov.branchID_), parentageIDLookup_[prov.parentageIDIndex_]));
1793  }
1794  }
1795  }
1796 
1798  public:
1799  explicit FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
1801  private:
1802  virtual void readProvenance(BranchMapper const& mapper) const;
1807  };
1808 
1811  rootTree_(rootTree),
1812  infoVector_(),
1813  pInfoVector_(&infoVector_),
1814  daqProvenanceHelper_(daqProvenanceHelper) {
1815  }
1816 
1817  void
1820  setRefCoreStreamer(true);
1821  if(daqProvenanceHelper_) {
1822  for(auto const& info : infoVector_) {
1824  daqProvenanceHelper_->mapParentageID(info.parentageID())));
1825  }
1826  } else {
1827  for(auto const& info : infoVector_) {
1828  mapper.insertIntoSet(info);
1829  }
1830  }
1831  }
1832 
1834  public:
1835  explicit OldProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
1837  private:
1838  virtual void readProvenance(BranchMapper const& mapper) const;
1840  std::vector<EventEntryInfo> infoVector_;
1841  mutable std::vector<EventEntryInfo> *pInfoVector_;
1843  };
1844 
1847  rootTree_(rootTree),
1848  infoVector_(),
1849  pInfoVector_(&infoVector_),
1850  daqProvenanceHelper_(daqProvenanceHelper) {
1851  }
1852 
1853  void
1855  rootTree_->branchEntryInfoBranch()->SetAddress(&pInfoVector_);
1857  setRefCoreStreamer(true);
1858  for(auto const& info : infoVector_) {
1860  EntryDescriptionRegistry::instance()->getMapped(info.entryDescriptionID(), eed);
1861  Parentage parentage(eed.parents());
1862  if(daqProvenanceHelper_) {
1864  daqProvenanceHelper_->mapParentageID(parentage.id()));
1865  mapper.insertIntoSet(entry);
1866  } else {
1867  ProductProvenance entry(info.branchID(), parentage.id());
1868  mapper.insertIntoSet(entry);
1869  }
1870 
1871  }
1872  }
1873 
1875  public:
1878  private:
1879  virtual void readProvenance(BranchMapper const& mapper) const;
1880  };
1881 
1884  }
1885 
1886  void
1888  // Not providing parentage!!!
1889  }
1890 
1891  std::unique_ptr<ProvenanceReaderBase>
1893  return std::unique_ptr<ProvenanceReaderBase>(new DummyProvenanceReader);
1894  }
1895 
1896  std::unique_ptr<ProvenanceReaderBase>
1897  MakeOldProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
1898  return std::unique_ptr<ProvenanceReaderBase>(new OldProvenanceReader(&rootTree, daqProvenanceHelper));
1899  }
1900 
1901  std::unique_ptr<ProvenanceReaderBase>
1902  MakeFullProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
1903  return std::unique_ptr<ProvenanceReaderBase>(new FullProvenanceReader(&rootTree, daqProvenanceHelper));
1904  }
1905 
1906  std::unique_ptr<ProvenanceReaderBase>
1907  MakeReducedProvenanceReader::makeReader(RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
1908  return std::unique_ptr<ProvenanceReaderBase>(new ReducedProvenanceReader(&rootTree, parentageIDLookup_, daqProvenanceHelper));
1909  }
1910 }
RunNumber_t run() const
Definition: EventID.h:42
EventID const & eventID() const
Definition: RootFile.h:100
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:446
void fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const
virtual void readProvenance(BranchMapper const &mapper) const
Definition: RootFile.cc:1773
EventNumber_t event() const
Definition: EventID.h:44
std::string const & idToParameterSetBlobsBranchName()
Definition: BranchType.cc:249
std::unique_ptr< ProvenanceAdaptor > provenanceAdaptor_
Definition: RootFile.h:210
int i
Definition: DBlmapReader.cc:9
boost::shared_ptr< BranchChildren > branchChildren_
Definition: RootFile.h:208
StoredProductProvenanceVector provVector_
Definition: RootFile.cc:1754
bool isRealData() const
bool selected(BranchDescription const &desc) const
void fillEventPrincipal(EventAuxiliary const &aux, boost::shared_ptr< EventSelectionIDVector > eventSelectionIDs=boost::shared_ptr< EventSelectionIDVector >(), boost::shared_ptr< BranchListIndexes > branchListIndexes=boost::shared_ptr< BranchListIndexes >(), boost::shared_ptr< BranchMapper > mapper=boost::shared_ptr< BranchMapper >(new BranchMapper), DelayedReader *reader=0)
boost::shared_ptr< BranchListIndexes > branchListIndexes_
Definition: RootFile.h:206
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:114
unsigned int const defaultNonEventLearningEntries
Definition: RootTree.h:38
boost::shared_ptr< RunAuxiliary > savedRunAuxiliary_
Definition: RootFile.h:186
virtual void readProvenance(BranchMapper const &mapper) const
Definition: RootFile.cc:1854
std::unique_ptr< History > history_
Definition: RootFile.h:207
void doneFileInitialization() const
Clears the temporary vector of event numbers to reduce memory usage.
static int const invalidIndex
TPRegexp parents
Definition: eve_filter.cc:24
BranchType const & branchType() const
std::string const & parentageTreeName()
Definition: BranchType.cc:158
static LuminosityBlockID firstValidLuminosityBlock()
std::vector< BranchIDList > BranchIDLists
Definition: BranchIDList.h:19
std::string const & entryDescriptionBranchName()
Definition: BranchType.cc:153
bool skipEvents(int &offset)
Definition: RootFile.cc:1242
FileFormatVersion fileFormatVersion() const
Definition: RootFile.h:104
ProductProvenanceVector infoVector_
Definition: RootFile.cc:1804
ForwardSequence::const_iterator lower_bound_all(ForwardSequence const &s, Datum const &d)
wrappers for std::lower_bound
Definition: Algorithms.h:91
bool branchListIndexesUnchanged() const
Definition: RootFile.h:107
RunNumber_t run() const
Definition: RunID.h:44
std::vector< std::string > const & branchNames() const
Definition: RootTree.h:89
bool setEntryAtNextEventInLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1575
ProcessConfigurationVector processConfigurations_
Definition: RootFile.h:173
StoredProductProvenanceVector * pProvVector_
Definition: RootFile.cc:1755
unsigned int EventNumber_t
Definition: EventID.h:30
std::string & branchName() const
void readParentageTree()
Definition: RootFile.cc:522
int whyNotFastClonable_
Definition: RootFile.h:189
static ThreadSafeRegistry * instance()
void checkReleaseVersion()
Definition: RootFile.cc:1632
ParentageID id() const
Definition: Parentage.cc:20
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:1806
tuple lumi
Definition: fjr2json.py:35
std::map< std::string, std::string > newBranchToOldBranch_
Definition: RootFile.h:203
EntryNumber_t firstEventEntryThisRun() const
IndexIntoFile::EntryType getEntryTypeWithSkipping()
Definition: RootFile.cc:695
bool empty() const
True if no runs, lumis, or events are in the file.
std::map< BranchKey, BranchDescription > ProductList
void fillEventAuxiliary()
Definition: RootFile.cc:1135
BranchID const & mapBranchID(BranchID const &branchID) const
#define nullptr
bool setEntryAtRun(RunNumber_t run)
Definition: RootFile.cc:1567
ProductProvenanceVector * pInfoVector_
Definition: RootFile.cc:1805
RootTree lumiTree_
Definition: RootFile.h:194
Timestamp const & time() const
std::unique_ptr< MakeProvenanceReader > provenanceReaderMaker_
Definition: RootFile.h:211
EntryNumber const & entries() const
Definition: RootTree.h:87
RunNumber_t run() const
bool getMapped(key_type const &k, value_type &result) const
void setRefCoreStreamer(bool resetAll=false)
std::string const & fileFormatVersionBranchName()
Definition: BranchType.cc:212
void reduceProcessHistoryIDs()
IndexIntoFileItr begin(SortOrder sortOrder) const
FullProvenanceReader(RootTree *rootTree, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:1809
std::vector< BranchID > const & parents() const
boost::shared_ptr< BranchIDLists const > branchIDLists_
Definition: RootFile.h:199
std::string const & eventSelectionsBranchName()
Definition: BranchType.cc:237
virtual std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const
Definition: RootFile.cc:1902
InputSource::ProcessingMode processingMode_
Definition: RootFile.h:201
boost::shared_ptr< LuminosityBlockPrincipal > readLumi(boost::shared_ptr< LuminosityBlockPrincipal > lumiPrincipal)
Definition: RootFile.cc:1533
IndexIntoFile::IndexIntoFileItr indexIntoFileIter_
Definition: RootFile.h:183
boost::shared_ptr< RunAuxiliary > fillRunAuxiliary()
Definition: RootFile.cc:1221
void stable_sort_all(RandomAccessSequence &s)
wrappers for std::stable_sort
Definition: Algorithms.h:135
static RunID firstValidRun()
Definition: RunID.h:82
LuminosityBlockNumber_t lumi() const
boost::shared_ptr< BranchMapper > eventBranchMapper_
Definition: RootFile.h:212
void fillBranchEntryMeta(TBranch *branch, T *&pbuf)
Definition: RootTree.h:97
std::unique_ptr< FileBlock > createFileBlock() const
Definition: RootFile.cc:614
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:43
void trainCache(char const *branchNames)
Definition: RootTree.cc:415
bool insertMapped(value_type const &v)
uint16_t size_type
unsigned int LuminosityBlockNumber_t
Definition: EventID.h:31
virtual ~OldProvenanceReader()
Definition: RootFile.cc:1836
IndexIntoFileItr findRunPosition(RunNumber_t run) const
Same as findPosition.
TBranch * branchEntryInfoBranch() const
Definition: RootTree.h:119
long long EntryNumber_t
static int position[TOTALCHAMBERS][3]
Definition: ReadPGInfo.cc:509
void fillProductRegistryTransients(std::vector< ProcessConfiguration > const &pcVec, ProductRegistry const &preg, bool okToRegister=false)
MakeReducedProvenanceReader(std::vector< ParentageID > const &parentageIDLookup)
Definition: RootFile.cc:77
virtual ~DummyProvenanceReader()
Definition: RootFile.cc:1877
IndexIntoFileItr findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi=0U, EventNumber_t event=0U) const
std::vector< EventSelectionID > EventSelectionIDVector
LuminosityBlockNumber_t luminosityBlock() const
FileFormatVersion fileFormatVersion_
Definition: RootFile.h:176
TTree const * metaTree() const
Definition: RootTree.h:115
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:245
void setID(ParameterSetID const &id) const
virtual void readProvenance(BranchMapper const &mapper) const
Definition: RootFile.cc:1887
void setPosition(IndexIntoFile::IndexIntoFileItr const &position)
Definition: RootFile.cc:646
ProcessConfigurationRegistry::vector_type ProcessConfigurationVector
tuple runs
Definition: gather_cfg.py:87
std::vector< BranchID > const & parents() const
Definition: Parentage.h:38
ProductList const & productList() const
U second(std::pair< T, U > const &p)
std::vector< EventProcessHistoryID >::const_iterator eventProcessHistoryIter_
Definition: RootFile.h:185
bool skipThisEntry()
Definition: RootFile.cc:651
IndexIntoFile::EntryType getNextEntryTypeWanted()
Definition: RootFile.cc:722
TTree const * tree() const
Definition: RootTree.h:113
FileID fid_
Definition: RootFile.h:177
boost::shared_ptr< DuplicateChecker > duplicateChecker_
Definition: RootFile.h:209
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:1757
std::string const logicalFile_
Definition: RootFile.h:171
std::map< key_type, value_type > collection_type
std::vector< BranchListIndex > BranchListIndexes
IndexIntoFile::IndexIntoFileItr indexIntoFileEnd_
Definition: RootFile.h:182
std::string const & processHistoryMapBranchName()
Definition: BranchType.cc:192
std::vector< ProcessHistoryID > & setProcessHistoryIDs()
bool next()
Definition: RootTree.h:81
virtual std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const
Definition: RootFile.cc:1897
bool noEventSort_
Definition: RootFile.h:188
std::string const & className() const
bool wasLastEventJustRead() const
Definition: RootFile.cc:747
bool setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1559
std::string friendlyName(std::string const &iFullName)
static RunNumber_t const invalidRun
std::string const & entryDescriptionTreeName()
Definition: BranchType.cc:145
void close()
Definition: RootFile.cc:1104
std::string const & fid() const
Definition: FileID.h:19
RootTree const & runTree() const
Definition: RootFile.h:103
boost::shared_ptr< BranchIDListHelper > branchIDListHelper_
Definition: RootFile.h:200
bool modifiedIDs() const
Definition: RootFile.h:108
IndexIntoFile::EntryNumber_t lastEventEntryNumberRead_
Definition: RootFile.h:197
void copyPosition(IndexIntoFileItr const &position)
Copy the position without modifying the pointer to the IndexIntoFile or size.
std::string const & indexIntoFileBranchName()
Definition: BranchType.cc:227
IndexIntoFileItr end(SortOrder sortOrder) const
Used to end an iteration over the Runs, Lumis, and Events in a file.
virtual EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const
Definition: RootFile.cc:106
OldProvenanceReader(RootTree *rootTree, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:1845
std::string const & eventHistoryBranchName()
Definition: BranchType.cc:232
RootFile(std::string const &fileName, ProcessConfiguration const &processConfiguration, std::string const &logicalFileName, boost::shared_ptr< InputFile > filePtr, boost::shared_ptr< EventSkipperByID > eventSkipperByID, bool skipAnyEvents, int remainingEvents, int remainingLumis, unsigned int treeCacheSize, int treeMaxVirtualSize, InputSource::ProcessingMode processingMode, RunNumber_t const &forcedRunNumber, bool noEventSort, ProductSelectorRules const &productSelectorRules, InputType::InputType inputType, boost::shared_ptr< BranchIDListHelper > branchIDListHelper, boost::shared_ptr< DuplicateChecker > duplicateChecker, bool dropDescendantsOfDroppedProducts, std::vector< boost::shared_ptr< IndexIntoFile > > const &indexesIntoFiles, std::vector< boost::shared_ptr< IndexIntoFile > >::size_type currentIndexIntoFile, std::vector< ProcessHistoryID > &orderedProcessHistoryIDs, bool labelRawDataLikeMC, bool usingGoToEvent, bool enablePrefetching)
Definition: RootFile.cc:121
EventPrincipal * readEvent(EventPrincipal &cache)
Definition: RootFile.cc:1348
void skipEventBackward(int &phIndexOfEvent, RunNumber_t &runOfEvent, LuminosityBlockNumber_t &lumiOfEvent, EntryNumber_t &eventEntry)
Long64_t numEntries(TFile *hdl, std::string const &trname)
Definition: CollUtil.cc:50
std::pair< std::string, MonitorElement * > entry
Definition: ME_MAP.h:8
EventAuxiliary const & eventAux() const
Definition: RootFile.h:96
bool eventHistoryTree() const
bool isEarlierRelease(std::string const &a, std::string const &b)
int whyNotFastClonable() const
Definition: RootFile.h:105
BranchType branchType() const
Definition: RootTree.h:127
RunNumber_t run() const
bool skipAnyEvents_
Definition: RootFile.h:187
RootTree eventTree_
Definition: RootFile.h:193
std::vector< BranchDescription const * > allBranchDescriptions() const
std::map< ParameterSetID, ParameterSetID > ParameterSetIdConverter
bool isValid() const
Definition: FileID.h:18
bool iterationWillBeInEntryOrder(SortOrder sortOrder) const
Used to determine whether or not to disable fast cloning.
std::string const & friendlyClassName() const
BranchID const & branchID() const
WrapperInterfaceBase const * getInterface() const
std::array< bool, NumBranchTypes > const & hasNewlyDroppedBranch() const
Definition: RootFile.h:106
std::string const & metaDataTreeName()
Definition: BranchType.cc:167
std::string & wrappedName() const
void fillHistory()
Definition: RootFile.cc:1141
bool isDuplicateEvent()
Definition: RootFile.cc:711
LuminosityBlockNumber_t oldLuminosityBlock() const
EntryDescriptionID id() const
unsigned int offset(bool)
void insertCollection(collection_type const &c)
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 wasFirstEventJustRead() const
Definition: RootFile.cc:754
std::string const & parameterSetMapBranchName()
Definition: BranchType.cc:182
Hash< ProcessHistoryType > ProcessHistoryID
std::vector< ProductProvenance > ProductProvenanceVector
const int drop
boost::shared_ptr< EventSelectionIDVector > eventSelectionIDs_
Definition: RootFile.h:205
std::string const & processHistoryBranchName()
Definition: BranchType.cc:197
IndexIntoFile & indexIntoFile_
Definition: RootFile.h:179
virtual ~FullProvenanceReader()
Definition: RootFile.cc:1800
RootTree runTree_
Definition: RootFile.h:195
EntryNumber const & entryNumber() const
Definition: RootTree.h:86
bool goToEvent(EventID const &eventID)
Definition: RootFile.cc:1313
std::string getReleaseVersion()
void setAtEventEntry(IndexIntoFile::EntryNumber_t entry)
Definition: RootFile.cc:1397
bool storedProductProvenanceUsed() const
void fixIndexes(std::vector< ProcessHistoryID > &processHistoryIDs)
DelayedReader * rootDelayedReader() const
Definition: RootTree.cc:99
std::vector< RunOrLumiEntry > & setRunOrLumiEntries()
void conversion(EventAux const &from, EventAuxiliary &to)
Definition: EventAux.cc:9
virtual std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const
Definition: RootFile.cc:1907
std::array< bool, NumBranchTypes > hasNewlyDroppedBranch_
Definition: RootFile.h:190
std::vector< EventNumber_t > & unsortedEventNumbers() const
static Timestamp const & invalidTimestamp()
Definition: Timestamp.cc:83
static EntryNumber_t const invalidEntry
ForwardSequence::const_iterator find_in_all(ForwardSequence const &s, Datum const &d)
wrappers for std::find
Definition: Algorithms.h:32
void setIfFastClonable(int remainingEvents, int remainingLumis)
Definition: RootFile.cc:560
std::unique_ptr< MakeProvenanceReader > makeProvenanceReaderMaker() const
Definition: RootFile.cc:1726
void fillBranchEntry(TBranch *branch, T *&pbuf)
Definition: RootTree.h:108
static LuminosityBlockNumber_t const invalidLumi
IndexIntoFileItr findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const
void readEntryDescriptionTree()
Definition: RootFile.cc:476
std::string const & parentageBranchName()
Definition: BranchType.cc:162
boost::shared_ptr< LuminosityBlockAuxiliary > fillLumiAuxiliary()
Definition: RootFile.cc:1197
boost::shared_ptr< LuminosityBlockAuxiliary > readLuminosityBlockAuxiliary_()
Definition: RootFile.cc:1489
double b
Definition: hdecay.h:120
LuminosityBlockNumber_t luminosityBlock() const
bool processHistorySameWithinRun() const
ProcessHistoryID const & processHistoryID(int i) const
ProductList & productListUpdator()
void setProcessHistoryID(ProcessHistoryID const &phid)
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:1756
bool isValid() const
Definition: RootTree.cc:87
std::vector< StoredProductProvenance > StoredProductProvenanceVector
std::string const & file() const
Definition: RootFile.h:92
std::string const & productDescriptionBranchName()
Definition: BranchType.cc:172
std::string const & processConfigurationBranchName()
Definition: BranchType.cc:202
IndexIntoFile::IndexIntoFileItr indexIntoFileBegin_
Definition: RootFile.h:181
void insertIntoSet(ProductProvenance const &provenanceProduct) const
Definition: BranchMapper.cc:44
boost::shared_ptr< RunPrincipal > readRun_(boost::shared_ptr< RunPrincipal > runPrincipal)
Definition: RootFile.cc:1472
EntryNumber_t firstEventEntryThisLumi() const
ProcessHistoryID const & processHistoryID() const
EventID const & id() const
std::unique_ptr< DaqProvenanceHelper > daqProvenanceHelper_
Definition: RootFile.h:214
bool branchListIndexesUnchanged_
Definition: RootFile.h:191
void setEventFinder(boost::shared_ptr< EventFinder > ptr) const
void fillIndexIntoFile()
Definition: RootFile.cc:817
#define begin
Definition: vmac.h:31
std::vector< EventEntryInfo > * pInfoVector_
Definition: RootFile.cc:1841
unsigned int const defaultNonEventCacheSize
Definition: RootTree.h:36
std::vector< value_type > vector_type
RootTreePtrArray treePointers_
Definition: RootFile.h:196
void fillEventNumbers() const
double a
Definition: hdecay.h:121
void initialize(ProductSelectorRules const &rules, std::vector< BranchDescription const * > const &branchDescriptions)
boost::shared_ptr< ProductRegistry const > productRegistry_
Definition: RootFile.h:198
bool perEventProductIDs() const
Long64_t EntryNumber
Definition: RootTree.h:39
std::string const & BranchTypeToProductProvenanceBranchName(BranchType const &BranchType)
Definition: BranchType.cc:130
std::vector< ProcessHistoryID > & orderedProcessHistoryIDs_
Definition: RootFile.h:180
std::string const & productDependenciesBranchName()
Definition: BranchType.cc:177
void setNumberOfEvents(EntryNumber_t nevents) const
void overrideRunNumber(RunID &id)
Definition: RootFile.cc:1588
boost::shared_ptr< BranchMapper > makeBranchMapper()
Definition: RootFile.cc:1739
std::string const & entryDescriptionIDBranchName()
Definition: BranchType.cc:149
bool useReducedProcessHistoryID() const
boost::shared_ptr< InputFile > filePtr_
Definition: RootFile.h:174
void initializeDuplicateChecker(std::vector< boost::shared_ptr< IndexIntoFile > > const &indexesIntoFiles, std::vector< boost::shared_ptr< IndexIntoFile > >::size_type currentIndexIntoFile)
Definition: RootFile.cc:1646
std::string const & branchIDListBranchName()
Definition: BranchType.cc:207
unsigned int RunNumber_t
Definition: EventRange.h:32
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:241
std::vector< ParentageID > parentageIDLookup_
Definition: RootFile.h:213
EventAuxiliary eventAux_
Definition: RootFile.h:192
void fillThisEventAuxiliary()
Definition: RootFile.cc:1116
void resetTraining()
Definition: RootTree.h:125
bool setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
Definition: RootFile.cc:1551
EventPrincipal * readCurrentEvent(EventPrincipal &cache)
Definition: RootFile.cc:1371
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:80
ReducedProvenanceReader(RootTree *iRootTree, std::vector< ParentageID > const &iParentageIDLookup, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:1760
std::string const & eventHistoryTreeName()
Definition: BranchType.cc:262
static Interceptor::Registry registry("Interceptor")
RootFileEventFinder(RootTree &eventTree)
Definition: RootFile.cc:103
ParentageID const & mapParentageID(ParentageID const &phid) const
IndexIntoFile::IndexIntoFileItr indexIntoFileIter() const
Definition: RootFile.cc:641
std::string const & newBranchToOldBranch(std::string const &newBranch) const
Definition: RootFile.cc:632
std::unique_ptr< TTreeCache > trainCache(TTree *tree, InputFile &file, unsigned int cacheSize, char const *branchNames)
Definition: RootTree.cc:470
virtual void readProvenance(BranchMapper const &mapper) const
Definition: RootFile.cc:1818
IndexIntoFileItr findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
unsigned int const defaultLearningEntries
Definition: RootTree.h:37
boost::shared_ptr< EventSkipperByID > eventSkipperByID_
Definition: RootFile.h:175
std::vector< EventEntryInfo > infoVector_
Definition: RootFile.cc:1840
TTree * eventHistoryTree_
Definition: RootFile.h:204
void dropOnInput(ProductRegistry &reg, ProductSelectorRules const &rules, bool dropDescendants, InputType::InputType inputType)
Definition: RootFile.cc:1662
LuminosityBlockNumber_t peekAheadAtLumi() const
std::string const & fileIdentifierBranchName()
Definition: BranchType.cc:217
boost::shared_ptr< ProductRegistry const > productRegistry() const
Definition: RootFile.h:93
void validateFile(InputType::InputType inputType, bool usingGoToEvent)
Definition: RootFile.cc:1043
virtual std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const
Definition: RootFile.cc:1892
virtual ~RootFileEventFinder()
Definition: RootFile.cc:104
EventNumber_t event() const
std::string const & moduleDescriptionMapBranchName()
Definition: BranchType.cc:187
std::string const file_
Definition: RootFile.h:170
boost::shared_ptr< RunAuxiliary > readRunAuxiliary_()
Definition: RootFile.cc:1402
void skipEventForward(int &phIndexOfSkippedEvent, RunNumber_t &runOfSkippedEvent, LuminosityBlockNumber_t &lumiOfSkippedEvent, EntryNumber_t &skippedEventEntry)
std::vector< EventProcessHistoryID > eventProcessHistoryIDs_
Definition: RootFile.h:184
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:1842
std::string createGlobalIdentifier()
void copyProduct(BranchDescription const &productdesc)
void readEventHistoryTree()
Definition: RootFile.cc:1619
int forcedRunOffset_
Definition: RootFile.h:202
void fillAux(T *&pAux)
Definition: RootTree.h:92
void setEntryNumber(EntryNumber theEntryNumber)
Definition: RootTree.cc:175
void reportOpened(std::string const &inputType)
Definition: RootFile.cc:1090
roottree::EntryNumber EntryNumber
Definition: RootTree.h:60
bool current()
Definition: RootTree.h:83