CMS 3D CMS Logo

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 #include "RunHelper.h"
9 
49 
52 
53 //used for backward compatibility
58 
59 #include "Rtypes.h"
60 #include "TClass.h"
61 #include "TString.h"
62 #include "TTree.h"
63 #include "TTreeCache.h"
64 
65 #include <algorithm>
66 #include <list>
67 
68 namespace edm {
69 
70  // Algorithm classes for making ProvenanceReader:
72  public:
73  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
74  DaqProvenanceHelper const* daqProvenanceHelper) const override;
75  };
77  public:
78  MakeOldProvenanceReader(std::unique_ptr<EntryDescriptionMap>&& entryDescriptionMap)
79  : MakeProvenanceReader(), entryDescriptionMap_(std::move(entryDescriptionMap)) {}
80  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
81  DaqProvenanceHelper const* daqProvenanceHelper) const override;
82 
83  private:
85  };
87  public:
88  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
89  DaqProvenanceHelper const* daqProvenanceHelper) const override;
90  };
92  public:
93  MakeReducedProvenanceReader(std::vector<ParentageID> const& parentageIDLookup)
94  : parentageIDLookup_(parentageIDLookup) {}
95  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
96  DaqProvenanceHelper const* daqProvenanceHelper) const override;
97 
98  private:
99  std::vector<ParentageID> const& parentageIDLookup_;
100  };
101 
102  namespace {
103  void checkReleaseVersion(std::vector<ProcessHistory> processHistoryVector, std::string const& fileName) {
104  std::string releaseVersion = getReleaseVersion();
105  releaseversion::DecomposedReleaseVersion currentRelease(releaseVersion);
106  for (auto const& ph : processHistoryVector) {
107  for (auto const& pc : ph) {
108  if (releaseversion::isEarlierRelease(currentRelease, pc.releaseVersion())) {
110  << "The release you are using, " << getReleaseVersion() << " , predates\n"
111  << "a release (" << pc.releaseVersion() << ") used in writing the input file, " << fileName << ".\n"
112  << "Forward compatibility cannot be supported.\n";
113  }
114  }
115  }
116  }
117  } // namespace
118 
119  // This is a helper class for IndexIntoFile.
121  public:
122  explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
123  ~RootFileEventFinder() override {}
124 
126  roottree::EntryNumber saveEntry = eventTree_.entryNumber();
127  eventTree_.setEntryNumber(entry);
128  EventAuxiliary eventAux;
129  EventAuxiliary* pEvAux = &eventAux;
130  eventTree_.fillAux<EventAuxiliary>(pEvAux);
131  eventTree_.setEntryNumber(saveEntry);
132  return eventAux.event();
133  }
134 
135  private:
137  };
138 
139  //---------------------------------------------------------------------
141  ProcessConfiguration const& processConfiguration,
142  std::string const& logicalFileName,
143  std::shared_ptr<InputFile> filePtr,
144  std::shared_ptr<EventSkipperByID> eventSkipperByID,
145  bool skipAnyEvents,
146  int remainingEvents,
147  int remainingLumis,
148  unsigned int nStreams,
149  unsigned int treeCacheSize,
150  int treeMaxVirtualSize,
151  InputSource::ProcessingMode processingMode,
152  RunHelperBase* runHelper,
153  bool noEventSort,
154  ProductSelectorRules const& productSelectorRules,
155  InputType inputType,
156  std::shared_ptr<BranchIDListHelper> branchIDListHelper,
157  std::shared_ptr<ThinnedAssociationsHelper> thinnedAssociationsHelper,
158  std::vector<BranchID> const* associationsFromSecondary,
159  std::shared_ptr<DuplicateChecker> duplicateChecker,
160  bool dropDescendants,
161  ProcessHistoryRegistry& processHistoryRegistry,
162  std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
163  std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile,
164  std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
165  bool bypassVersionCheck,
166  bool labelRawDataLikeMC,
167  bool usingGoToEvent,
168  bool enablePrefetching,
169  bool enforceGUIDInFileName)
170  : file_(fileName),
171  logicalFile_(logicalFileName),
172  processConfiguration_(processConfiguration),
173  processHistoryRegistry_(&processHistoryRegistry),
174  filePtr_(filePtr),
175  eventSkipperByID_(eventSkipperByID),
176  fileFormatVersion_(),
177  fid_(),
178  indexIntoFileSharedPtr_(new IndexIntoFile),
179  indexIntoFile_(*indexIntoFileSharedPtr_),
180  orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
181  indexIntoFileBegin_(
182  indexIntoFile_.begin(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder)),
183  indexIntoFileEnd_(indexIntoFileBegin_),
184  indexIntoFileIter_(indexIntoFileBegin_),
185  storedMergeableRunProductMetadata_((inputType == InputType::Primary) ? new StoredMergeableRunProductMetadata
186  : nullptr),
187  eventProcessHistoryIDs_(),
188  eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
189  savedRunAuxiliary_(),
190  skipAnyEvents_(skipAnyEvents),
191  noEventSort_(noEventSort),
192  enforceGUIDInFileName_(enforceGUIDInFileName),
193  whyNotFastClonable_(0),
194  hasNewlyDroppedBranch_(),
195  branchListIndexesUnchanged_(false),
196  eventAux_(),
197  eventTree_(filePtr,
198  InEvent,
199  nStreams,
200  treeMaxVirtualSize,
201  treeCacheSize,
202  roottree::defaultLearningEntries,
203  enablePrefetching,
204  inputType),
205  lumiTree_(filePtr,
206  InLumi,
207  1,
208  treeMaxVirtualSize,
209  roottree::defaultNonEventCacheSize,
211  enablePrefetching,
212  inputType),
213  runTree_(filePtr,
214  InRun,
215  1,
216  treeMaxVirtualSize,
217  roottree::defaultNonEventCacheSize,
219  enablePrefetching,
220  inputType),
221  treePointers_(),
222  lastEventEntryNumberRead_(IndexIntoFile::invalidEntry),
223  productRegistry_(),
224  branchIDLists_(),
225  branchIDListHelper_(branchIDListHelper),
226  fileThinnedAssociationsHelper_(),
227  thinnedAssociationsHelper_(thinnedAssociationsHelper),
228  processingMode_(processingMode),
229  runHelper_(runHelper),
230  newBranchToOldBranch_(),
231  eventHistoryTree_(nullptr),
232  eventSelectionIDs_(),
233  branchListIndexes_(),
234  history_(),
235  branchChildren_(new BranchChildren),
236  duplicateChecker_(duplicateChecker),
237  provenanceAdaptor_(),
238  provenanceReaderMaker_(),
239  eventProductProvenanceRetrievers_(),
240  parentageIDLookup_(),
241  daqProvenanceHelper_(),
242  edProductClass_(TypeWithDict::byName("edm::WrapperBase").getClass()),
243  inputType_(inputType) {
244  hasNewlyDroppedBranch_.fill(false);
245 
249 
250  // Read the metadata tree.
251  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
252  std::unique_ptr<TTree> metaDataTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::metaDataTreeName().c_str())));
253  if (nullptr == metaDataTree.get()) {
255  << "Could not find tree " << poolNames::metaDataTreeName() << " in the input file.\n";
256  }
257 
258  // To keep things simple, we just read in every possible branch that exists.
259  // We don't pay attention to which branches exist in which file format versions
260 
262  if (metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
263  TBranch* fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
264  fft->SetAddress(&fftPtr);
265  roottree::getEntry(fft, 0);
266  metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
267  }
268 
269  FileID* fidPtr = &fid_;
270  if (metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != nullptr) {
271  metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
272  }
273 
274  IndexIntoFile* iifPtr = &indexIntoFile_;
275  if (metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != nullptr) {
276  metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
277  }
278 
279  StoredMergeableRunProductMetadata* smrc = nullptr;
280  if (inputType == InputType::Primary) {
282  if (metaDataTree->FindBranch(poolNames::mergeableRunProductMetadataBranchName().c_str()) != nullptr) {
283  metaDataTree->SetBranchAddress(poolNames::mergeableRunProductMetadataBranchName().c_str(), &smrc);
284  }
285  }
286 
287  // Need to read to a temporary registry so we can do a translation of the BranchKeys.
288  // This preserves backward compatibility against friendly class name algorithm changes.
289  ProductRegistry inputProdDescReg;
290  ProductRegistry* ppReg = &inputProdDescReg;
291  metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
292 
293  typedef std::map<ParameterSetID, ParameterSetBlob> PsetMap;
294  PsetMap psetMap;
295  PsetMap* psetMapPtr = &psetMap;
296  if (metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
297  //backward compatibility
298  assert(!fileFormatVersion().parameterSetsTree());
299  metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
300  } else {
301  assert(fileFormatVersion().parameterSetsTree());
302  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
303  std::unique_ptr<TTree> psetTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str())));
304  if (nullptr == psetTree.get()) {
306  << "Could not find tree " << poolNames::parameterSetsTreeName() << " in the input file.\n";
307  }
308 
309  typedef std::pair<ParameterSetID, ParameterSetBlob> IdToBlobs;
310  IdToBlobs idToBlob;
311  IdToBlobs* pIdToBlob = &idToBlob;
312  psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
313 
314  std::unique_ptr<TTreeCache> psetTreeCache =
316  psetTreeCache->SetEnablePrefetching(false);
317  filePtr_->SetCacheRead(psetTreeCache.get());
318  for (Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
319  psetTree->GetEntry(i);
320  psetMap.insert(idToBlob);
321  }
322  filePtr_->SetCacheRead(nullptr);
323  }
324 
325  // backward compatibility
327  ProcessHistoryRegistry::collection_type* pHistMapPtr = &pHistMap;
328  if (metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != nullptr) {
329  metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
330  }
331 
333  ProcessHistoryRegistry::vector_type* pHistVectorPtr = &pHistVector;
334  if (metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != nullptr) {
335  metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
336  }
337 
338  // backward compatibility
339  ProcessConfigurationVector processConfigurations;
340  ProcessConfigurationVector* procConfigVectorPtr = &processConfigurations;
341  if (metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != nullptr) {
342  metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
343  }
344 
345  auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
346  BranchIDLists* branchIDListsPtr = branchIDListsAPtr.get();
347  if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != nullptr) {
348  metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
349  }
350 
351  if (inputType != InputType::SecondarySource) {
353  std::make_unique<ThinnedAssociationsHelper>(); // propagate_const<T> has no reset() function
354  ThinnedAssociationsHelper* thinnedAssociationsHelperPtr = fileThinnedAssociationsHelper_.get();
355  if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) != nullptr) {
356  metaDataTree->SetBranchAddress(poolNames::thinnedAssociationsHelperBranchName().c_str(),
357  &thinnedAssociationsHelperPtr);
358  }
359  }
360 
361  BranchChildren* branchChildrenBuffer = branchChildren_.get();
362  if (metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != nullptr) {
363  metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
364  }
365 
366  // backward compatibility
367  std::vector<EventProcessHistoryID>* eventHistoryIDsPtr = &eventProcessHistoryIDs_;
368  if (metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != nullptr) {
369  metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
370  }
371 
372  if (metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != nullptr) {
373  if (metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
374  metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), false);
375  } else {
376  metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), false);
377  }
378  }
379 
380  // Here we read the metadata tree
381  roottree::getEntry(metaDataTree.get(), 0);
382 
384 
385  // Here we read the event history tree, if we have one.
387 
389  if (!fileFormatVersion().triggerPathsTracked()) {
390  ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
391  } else {
392  // Merge into the parameter set registry.
393  pset::Registry& psetRegistry = *pset::Registry::instance();
394  for (auto const& psetEntry : psetMap) {
395  ParameterSet pset(psetEntry.second.pset());
396  pset.setID(psetEntry.first);
397  // For thread safety, don't update global registries when a secondary source opens a file.
398  if (inputType != InputType::SecondarySource) {
399  psetRegistry.insertMapped(pset);
400  }
401  }
402  }
403  if (!fileFormatVersion().splitProductIDs()) {
404  // Old provenance format input file. Create a provenance adaptor.
405  // propagate_const<T> has no reset() function
406  provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
407  inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, true);
408  // Fill in the branchIDLists branch from the provenance adaptor
409  branchIDLists_ = provenanceAdaptor_->branchIDLists();
410  } else {
411  if (!fileFormatVersion().triggerPathsTracked()) {
412  // New provenance format, but change in ParameterSet Format. Create a provenance adaptor.
413  // propagate_const<T> has no reset() function
414  provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
415  inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, false);
416  }
417  // New provenance format input file. The branchIDLists branch was read directly from the input file.
418  if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == nullptr) {
419  throw Exception(errors::EventCorruption) << "Failed to find branchIDLists branch in metaData tree.\n";
420  }
421  branchIDLists_.reset(branchIDListsAPtr.release());
422  }
423 
425  if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) == nullptr) {
427  << "Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
428  }
429  }
430 
431  if (!bypassVersionCheck) {
432  checkReleaseVersion(pHistVector, file());
433  }
434 
435  if (labelRawDataLikeMC) {
436  std::string const rawData("FEDRawDataCollection");
437  std::string const source("source");
438  ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
439  BranchKey finder(rawData, source, "", "");
440  ProductRegistry::ProductList::iterator it = pList.lower_bound(finder);
441  if (it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source) {
442  // We found raw data with a module label of source.
443  // We need to change the module label and process name.
444  // Create helper.
445  it->second.init();
446  // propagate_const<T> has no reset() function
447  daqProvenanceHelper_ = std::make_unique<DaqProvenanceHelper>(it->second.unwrappedTypeID());
448  // Create the new branch description
449  BranchDescription const& newBD = daqProvenanceHelper_->branchDescription();
450  // Save info from the old and new branch descriptions
451  daqProvenanceHelper_->saveInfo(it->second, newBD);
452  // Map the new branch name to the old branch name.
453  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), it->second.branchName()));
454  // Remove the old branch description from the product Registry.
455  pList.erase(it);
456  // Check that there was only one.
457  it = pList.lower_bound(finder);
458  assert(!(it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source));
459  // Insert the new branch description into the product registry.
460  inputProdDescReg.copyProduct(newBD);
461  // Fix up other per file metadata.
462  daqProvenanceHelper_->fixMetaData(processConfigurations, pHistVector);
463  daqProvenanceHelper_->fixMetaData(*branchIDLists_);
464  daqProvenanceHelper_->fixMetaData(*branchChildren_);
465  }
466  }
467 
468  for (auto const& history : pHistVector) {
469  processHistoryRegistry.registerProcessHistory(history);
470  }
471 
473 
474  // Update the branch id info. This has to be done before validateFile since
475  // depending on the file format, the branchIDListHelper_ may have its fixBranchListIndexes call made
476  if (inputType == InputType::Primary) {
478  }
479 
480  validateFile(inputType, usingGoToEvent);
481 
482  // Here, we make the class that will make the ProvenanceReader
483  // It reads whatever trees it needs.
484  // propagate_const<T> has no reset() function
485  provenanceReaderMaker_ = std::unique_ptr<MakeProvenanceReader>(makeProvenanceReaderMaker(inputType).release());
486 
487  // Merge into the hashed registries.
488  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
490  }
491 
492  initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
496  indexIntoFile_.end(noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder);
498  eventProcessHistoryIter_ = eventProcessHistoryIDs_.begin();
499 
500  // Set product presence information in the product registry.
501  ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
502  for (auto& product : pList) {
503  BranchDescription& prod = product.second;
504  prod.init();
505  treePointers_[prod.branchType()]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
506  }
507 
508  auto newReg = std::make_unique<ProductRegistry>();
509 
510  // Do the translation from the old registry to the new one
511  {
512  ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
513  for (auto const& product : prodList) {
514  BranchDescription const& prod = product.second;
515  std::string newFriendlyName = friendlyname::friendlyName(prod.className());
516  if (newFriendlyName == prod.friendlyClassName()) {
517  newReg->copyProduct(prod);
518  } else {
519  if (fileFormatVersion().splitProductIDs()) {
521  << "Cannot change friendly class name algorithm without more development work\n"
522  << "to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
523  }
524  BranchDescription newBD(prod);
525  newBD.updateFriendlyClassName();
526  newReg->copyProduct(newBD);
527  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
528  }
529  }
530  dropOnInput(*newReg, productSelectorRules, dropDescendants, inputType);
531  if (inputType == InputType::SecondaryFile) {
532  thinnedAssociationsHelper->updateFromSecondaryInput(*fileThinnedAssociationsHelper_,
533  *associationsFromSecondary);
534  } else if (inputType == InputType::Primary) {
535  thinnedAssociationsHelper->updateFromPrimaryInput(*fileThinnedAssociationsHelper_);
536  }
537 
538  if (inputType == InputType::Primary) {
539  for (auto& product : newReg->productListUpdator()) {
540  setIsMergeable(product.second);
541  }
542  }
543 
544  // freeze the product registry
545  newReg->setFrozen(inputType != InputType::Primary);
546  productRegistry_.reset(newReg.release());
547  }
548 
549  // Set up information from the product registry.
550  ProductRegistry::ProductList const& prodList = productRegistry()->productList();
551 
552  {
553  std::array<size_t, NumBranchTypes> nBranches;
554  nBranches.fill(0);
555  for (auto const& product : prodList) {
556  ++nBranches[product.second.branchType()];
557  }
558 
559  int i = 0;
560  for (auto t : treePointers_) {
561  t->numberOfBranchesToAdd(nBranches[i]);
562  ++i;
563  }
564  }
565  for (auto const& product : prodList) {
566  BranchDescription const& prod = product.second;
567  treePointers_[prod.branchType()]->addBranch(prod, newBranchToOldBranch(prod.branchName()));
568  }
569 
570  // Determine if this file is fast clonable.
571  setIfFastClonable(remainingEvents, remainingLumis);
572 
573  // We are done with our initial reading of EventAuxiliary.
575 
576  // Tell the event tree to begin training at the next read.
578 
579  // Train the run and lumi trees.
580  runTree_.trainCache("*");
581  lumiTree_.trainCache("*");
582  }
583 
585 
586  void RootFile::readEntryDescriptionTree(EntryDescriptionMap& entryDescriptionMap, InputType inputType) {
587  // Called only for old format files.
588  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
589  std::unique_ptr<TTree> entryDescriptionTree(
590  dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str())));
591  if (nullptr == entryDescriptionTree.get()) {
593  << "Could not find tree " << poolNames::entryDescriptionTreeName() << " in the input file.\n";
594  }
595 
596  EntryDescriptionID idBuffer;
597  EntryDescriptionID* pidBuffer = &idBuffer;
598  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
599 
600  EventEntryDescription entryDescriptionBuffer;
601  EventEntryDescription* pEntryDescriptionBuffer = &entryDescriptionBuffer;
602  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
603 
604  // Fill in the parentage registry.
606 
607  for (Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
608  roottree::getEntry(entryDescriptionTree.get(), i);
609  if (idBuffer != entryDescriptionBuffer.id()) {
610  throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
611  }
612  entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.id(), entryDescriptionBuffer));
614  parents.setParents(entryDescriptionBuffer.parents());
615  if (daqProvenanceHelper_) {
616  ParentageID const oldID = parents.id();
617  daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
618  ParentageID newID = parents.id();
619  if (newID != oldID) {
620  daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
621  }
622  }
623  // For thread safety, don't update global registries when a secondary source opens a file.
624  if (inputType != InputType::SecondarySource) {
625  registry.insertMapped(parents);
626  }
627  }
628  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), nullptr);
629  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), nullptr);
630  }
631 
633  // New format file
634  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
635  std::unique_ptr<TTree> parentageTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str())));
636  if (nullptr == parentageTree.get()) {
638  << "Could not find tree " << poolNames::parentageTreeName() << " in the input file.\n";
639  }
640 
642  Parentage* pParentageBuffer = &parents;
643  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
644 
646 
647  parentageIDLookup_.reserve(parentageTree->GetEntries());
648  for (Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
649  roottree::getEntry(parentageTree.get(), i);
650  if (daqProvenanceHelper_) {
651  ParentageID const oldID = parents.id();
652  daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
653  ParentageID newID = parents.id();
654  if (newID != oldID) {
655  daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
656  }
657  }
658  // For thread safety, don't update global registries when a secondary source opens a file.
659  if (inputType != InputType::SecondarySource) {
660  registry.insertMapped(parents);
661  }
662  parentageIDLookup_.push_back(parents.id());
663  }
664  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), nullptr);
665  }
666 
667  void RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
668  if (fileFormatVersion().noMetaDataTrees() and !fileFormatVersion().storedProductProvenanceUsed()) {
669  //we must avoid copying the old branch which stored the per product per event provenance
671  return;
672  }
673  if (!fileFormatVersion().splitProductIDs()) {
675  return;
676  }
679  return;
680  }
681  // Find entry for first event in file
683  while (it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
684  ++it;
685  }
686  if (it == indexIntoFileEnd_) {
688  return;
689  }
690 
691  // From here on, record all reasons we can't fast clone.
692  IndexIntoFile::SortOrder sortOrder =
696  }
697  if (skipAnyEvents_) {
699  }
700  if (remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
702  }
703  if (remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
705  }
706  if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
708  }
709  }
710 
711  std::unique_ptr<FileBlock> RootFile::createFileBlock() const {
712  return std::make_unique<FileBlock>(fileFormatVersion(),
713  eventTree_.tree(),
715  lumiTree_.tree(),
717  runTree_.tree(),
718  runTree_.metaTree(),
721  file_,
723  modifiedIDs(),
724  branchChildren());
725  }
726 
727  std::string const& RootFile::newBranchToOldBranch(std::string const& newBranch) const {
728  std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
729  if (it != newBranchToOldBranch_.end()) {
730  return it->second;
731  }
732  return newBranch;
733  }
734 
736 
739  }
740 
741  void RootFile::initAssociationsFromSecondary(std::vector<BranchID> const& associationsFromSecondary) {
742  thinnedAssociationsHelper_->initAssociationsFromSecondary(associationsFromSecondary,
744  }
745 
748  return false;
749  }
750  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
751  // See first if the entire lumi or run is skipped, so we won't have to read the event Auxiliary in that case.
753  return true;
754  }
755 
756  // The Lumi is not skipped. If this is an event, see if the event is skipped.
760  return true;
761  }
762  }
763 
764  // Skip runs with no lumis if either lumisToSkip or lumisToProcess have been set to select lumis
767 
768  // There are no lumis in this run, not even ones we will skip
769  if (iterLumi.peekAheadAtLumi() == IndexIntoFile::invalidLumi) {
770  return true;
771  }
772  // If we get here there are lumis in the run, check to see if we are skipping all of them
773  do {
774  if (!eventSkipperByID_->skipIt(iterLumi.run(), iterLumi.peekAheadAtLumi(), 0U)) {
775  return false;
776  }
777  } while (iterLumi.skipLumiInRun());
778  return true;
779  }
780  }
781  return false;
782  }
783 
786  if (duplicateChecker_.get() == nullptr) {
787  return false;
788  }
790  return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
793  eventAux_.id().event(),
794  file_);
795  }
796 
798  return indexIntoFile_.containsItem(run, lumi, event);
799  }
800 
803  EventNumber_t& event) {
804  // First, account for consecutive skipped entries.
805  while (skipThisEntry()) {
810  } else {
812  }
813  }
814  // OK, we have an entry that is not skipped.
816  if (entryType == IndexIntoFile::kEnd) {
817  return IndexIntoFile::kEnd;
818  }
819  if (entryType == IndexIntoFile::kRun) {
820  run = indexIntoFileIter_.run();
821  runHelper_->checkForNewRun(run);
822  return IndexIntoFile::kRun;
823  } else if (processingMode_ == InputSource::Runs) {
825  return getNextItemType(run, lumi, event);
826  }
827  if (entryType == IndexIntoFile::kLumi) {
828  run = indexIntoFileIter_.run();
829  lumi = indexIntoFileIter_.lumi();
830  return IndexIntoFile::kLumi;
833  return getNextItemType(run, lumi, event);
834  }
835  if (isDuplicateEvent()) {
837  return getNextItemType(run, lumi, event);
838  }
839  run = indexIntoFileIter_.run();
840  lumi = indexIntoFileIter_.lumi();
842  event = eventAux_.event();
843  return IndexIntoFile::kEvent;
844  }
845 
848  itr.advanceToEvent();
849  return itr.getEntryType() == IndexIntoFile::kEnd;
850  }
851 
854  int phIndex;
857  IndexIntoFile::EntryNumber_t eventEntry;
858  itr.skipEventBackward(phIndex, run, lumi, eventEntry);
859  itr.skipEventBackward(phIndex, run, lumi, eventEntry);
860  return eventEntry == IndexIntoFile::invalidEntry;
861  }
862 
863  namespace {
864  struct RunItem {
865  RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) : phid_(phid), run_(run) {}
866  ProcessHistoryID phid_;
867  RunNumber_t run_;
868  };
869  struct RunItemSortByRun {
870  bool operator()(RunItem const& a, RunItem const& b) const { return a.run_ < b.run_; }
871  };
872  struct RunItemSortByRunPhid {
873  bool operator()(RunItem const& a, RunItem const& b) const {
874  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
875  }
876  };
877  struct LumiItem {
878  LumiItem(ProcessHistoryID const& phid,
879  RunNumber_t const& run,
882  : phid_(phid),
883  run_(run),
884  lumi_(lumi),
885  firstEventEntry_(entry),
886  lastEventEntry_(entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry : entry + 1) {}
887  ProcessHistoryID phid_;
888  RunNumber_t run_;
890  IndexIntoFile::EntryNumber_t firstEventEntry_;
891  IndexIntoFile::EntryNumber_t lastEventEntry_;
892  };
893  struct LumiItemSortByRunLumi {
894  bool operator()(LumiItem const& a, LumiItem const& b) const {
895  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
896  }
897  };
898  struct LumiItemSortByRunLumiPhid {
899  bool operator()(LumiItem const& a, LumiItem const& b) const {
900  if (a.run_ < b.run_)
901  return true;
902  if (b.run_ < a.run_)
903  return false;
904  if (a.lumi_ < b.lumi_)
905  return true;
906  if (b.lumi_ < a.lumi_)
907  return false;
908  return a.phid_ < b.phid_;
909  }
910  };
911  } // namespace
912 
914  // This function is for backward compatibility.
915  // If reading a current format file, indexIntoFile_ is read from the input
916  // file and should always be there. Note that the algorithm below will work
917  // sometimes but often fail with the new format introduced in release 3_8_0.
918  // If it ever becomes necessary to rebuild IndexIntoFile from the new format,
919  // probably a separate function should be written to deal with the task.
920  // This is possible just not implemented yet.
921  assert(!fileFormatVersion().hasIndexIntoFile());
922 
923  typedef std::list<LumiItem> LumiList;
924  LumiList lumis; // (declare 1)
925 
926  typedef std::set<LuminosityBlockID> RunLumiSet;
927  RunLumiSet runLumiSet; // (declare 2)
928 
929  typedef std::list<RunItem> RunList;
930  RunList runs; // (declare 5)
931 
932  typedef std::set<RunNumber_t> RunSet;
933  RunSet runSet; // (declare 4)
934 
935  typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
936  RunItemSet runItemSet; // (declare 3)
937 
938  typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
939  PHIDMap phidMap;
940 
941  RunNumber_t prevRun = 0;
942  LuminosityBlockNumber_t prevLumi = 0;
943  ProcessHistoryID prevPhid;
944  bool iFirst = true;
945 
946  indexIntoFile_.unsortedEventNumbers().clear(); // should already be empty, just being careful
948 
949  // First, loop through the event tree.
950  while (eventTree_.next()) {
951  bool newRun = false;
952  bool newLumi = false;
955 
956  // Save the event numbers as we loop through the event auxiliary to avoid
957  // having to read through the event auxiliary again later. These event numbers
958  // are not actually used in this function, but could be needed elsewhere.
960 
961  ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(eventAux().processHistoryID());
962 
963  if (iFirst || prevPhid != reducedPHID || prevRun != eventAux().run()) {
964  iFirst = false;
965  newRun = newLumi = true;
966  } else if (prevLumi != eventAux().luminosityBlock()) {
967  newLumi = true;
968  }
969  prevPhid = reducedPHID;
970  prevRun = eventAux().run();
971  prevLumi = eventAux().luminosityBlock();
972  if (newLumi) {
973  lumis.emplace_back(
974  reducedPHID, eventAux().run(), eventAux().luminosityBlock(), eventTree_.entryNumber()); // (insert 1)
975  runLumiSet.insert(LuminosityBlockID(eventAux().run(), eventAux().luminosityBlock())); // (insert 2)
976  } else {
977  LumiItem& currentLumi = lumis.back();
978  assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
979  ++currentLumi.lastEventEntry_;
980  }
981  if (newRun) {
982  // Insert run in list if it is not already there.
983  RunItem item(reducedPHID, eventAux().run());
984  if (runItemSet.insert(item).second) { // (check 3, insert 3)
985  runs.push_back(std::move(item)); // (insert 5)
986  runSet.insert(eventAux().run()); // (insert 4)
987  phidMap.insert(std::make_pair(eventAux().run(), reducedPHID));
988  }
989  }
990  }
991  // now clean up.
995 
996  // Loop over run entries and fill information.
997 
998  typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
999  RunMap runMap; // (declare 11)
1000 
1001  typedef std::vector<RunItem> RunVector;
1002  RunVector emptyRuns; // (declare 12)
1003 
1004  if (runTree_.isValid()) {
1005  while (runTree_.next()) {
1006  // Note: adjacent duplicates will be skipped without an explicit check.
1007 
1008  std::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
1009  ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(runAux->processHistoryID());
1010 
1011  if (runSet.insert(runAux->run()).second) { // (check 4, insert 4)
1012  // This run was not associated with any events.
1013  emptyRuns.emplace_back(reducedPHID, runAux->run()); // (insert 12)
1014  }
1015  runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber())); // (insert 11)
1016  phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1017  }
1018  // now clean up.
1020  }
1021 
1022  // Insert the ordered empty runs into the run list.
1023  RunItemSortByRun runItemSortByRun;
1024  stable_sort_all(emptyRuns, runItemSortByRun);
1025 
1026  RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
1027  for (auto const& emptyRun : emptyRuns) {
1028  for (; itRuns != endRuns; ++itRuns) {
1029  if (runItemSortByRun(emptyRun, *itRuns)) {
1030  break;
1031  }
1032  }
1033  runs.insert(itRuns, emptyRun);
1034  }
1035 
1036  // Loop over luminosity block entries and fill information.
1037 
1038  typedef std::vector<LumiItem> LumiVector;
1039  LumiVector emptyLumis; // (declare 7)
1040 
1041  typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1042  RunLumiMap runLumiMap; // (declare 6)
1043 
1044  if (lumiTree_.isValid()) {
1045  while (lumiTree_.next()) {
1046  // Note: adjacent duplicates will be skipped without an explicit check.
1047  std::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
1048  LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
1049  if (runLumiSet.insert(lumiID).second) { // (check 2, insert 2)
1050  // This lumi was not associated with any events.
1051  // Use the process history ID from the corresponding run. In cases of practical
1052  // importance, this should be the correct process history ID, but it is possible
1053  // to construct files where this is not the correct process history ID ...
1054  PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1055  assert(iPhidMap != phidMap.end());
1056  emptyLumis.emplace_back(
1057  iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), IndexIntoFile::invalidEntry); // (insert 7)
1058  }
1059  runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
1060  }
1061  // now clean up.
1063  }
1064 
1065  // Insert the ordered empty lumis into the lumi list.
1066  LumiItemSortByRunLumi lumiItemSortByRunLumi;
1067  stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
1068 
1069  LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
1070  for (auto const& emptyLumi : emptyLumis) {
1071  for (; itLumis != endLumis; ++itLumis) {
1072  if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1073  break;
1074  }
1075  }
1076  lumis.insert(itLumis, emptyLumi);
1077  }
1078 
1079  // Create a map of RunItems that gives the order of first appearance in the list.
1080  // Also fill in the vector of process history IDs
1081  typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1082  RunCountMap runCountMap; // Declare (17)
1083  std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
1084  assert(phids.empty());
1085  std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
1086  assert(entries.empty());
1087  int rcount = 0;
1088  for (auto& run : runs) {
1089  RunCountMap::const_iterator countMapItem = runCountMap.find(run);
1090  if (countMapItem == runCountMap.end()) {
1091  countMapItem = runCountMap.insert(std::make_pair(run, rcount)).first; // Insert (17)
1092  assert(countMapItem != runCountMap.end());
1093  ++rcount;
1094  }
1095  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, run.phid_);
1096  if (phidItem == phids.end()) {
1097  phids.push_back(run.phid_);
1098  phidItem = phids.end() - 1;
1099  }
1100  entries.emplace_back(countMapItem->second, // use (17)
1102  runMap[run.run_], // use (11)
1103  phidItem - phids.begin(),
1104  run.run_,
1105  0U,
1108  }
1109 
1110  // Create a map of LumiItems that gives the order of first appearance in the list.
1111  typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1112  LumiCountMap lumiCountMap; // Declare (19)
1113  int lcount = 0;
1114  for (auto& lumi : lumis) {
1115  RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(lumi.phid_, lumi.run_));
1116  assert(runCountMapItem != runCountMap.end());
1117  LumiCountMap::const_iterator countMapItem = lumiCountMap.find(lumi);
1118  if (countMapItem == lumiCountMap.end()) {
1119  countMapItem = lumiCountMap.insert(std::make_pair(lumi, lcount)).first; // Insert (17)
1120  assert(countMapItem != lumiCountMap.end());
1121  ++lcount;
1122  }
1123  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, lumi.phid_);
1124  assert(phidItem != phids.end());
1125  entries.emplace_back(runCountMapItem->second,
1126  countMapItem->second,
1127  runLumiMap[LuminosityBlockID(lumi.run_, lumi.lumi_)],
1128  phidItem - phids.begin(),
1129  lumi.run_,
1130  lumi.lumi_,
1131  lumi.firstEventEntry_,
1132  lumi.lastEventEntry_);
1133  }
1134  stable_sort_all(entries);
1135  }
1136 
1137  void RootFile::validateFile(InputType inputType, bool usingGoToEvent) {
1138  if (!fid_.isValid()) {
1140  }
1141  if (!eventTree_.isValid()) {
1142  throw Exception(errors::EventCorruption) << "'Events' tree is corrupted or not present\n"
1143  << "in the input file.\n";
1144  }
1145  if (enforceGUIDInFileName_) {
1146  auto guidFromName = stemFromPath(file_);
1147  if (guidFromName != fid_.fid()) {
1149  << "GUID " << guidFromName << " extracted from file name " << file_
1150  << " is inconsistent with the GUID read from the file " << fid_.fid();
1151  }
1152  }
1153 
1154  if (fileFormatVersion().hasIndexIntoFile()) {
1155  if (runTree().entries() > 0) {
1156  assert(!indexIntoFile_.empty());
1157  }
1159  if (daqProvenanceHelper_) {
1160  std::vector<ProcessHistoryID>& phidVec = indexIntoFile_.setProcessHistoryIDs();
1161  for (auto& phid : phidVec) {
1162  phid = daqProvenanceHelper_->mapProcessHistoryID(phid);
1163  }
1164  }
1166  }
1167  } else {
1168  assert(indexIntoFile_.empty());
1170  }
1171 
1175  std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(eventTree_)));
1176  // We fill the event numbers explicitly if we need to find events in closed files,
1177  // such as for secondary files (or secondary sources) or if duplicate checking across files.
1178  bool needEventNumbers = false;
1179  bool needIndexesForDuplicateChecker =
1180  duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
1181  if (inputType != InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1182  needEventNumbers = true;
1183  }
1184  bool needEventEntries = false;
1185  if (inputType != InputType::Primary || !noEventSort_) {
1186  // We need event entries for sorting or for secondary files or sources.
1187  needEventEntries = true;
1188  }
1189  indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
1190  }
1191 
1192  void RootFile::reportOpened(std::string const& inputType) {
1193  // Report file opened.
1194  std::string const label = "source";
1195  std::string moduleName = "PoolSource";
1196  filePtr_->inputFileOpened(logicalFile_, inputType, moduleName, label, fid_.fid(), eventTree_.branchNames());
1197  }
1198 
1200  // Just to play it safe, zero all pointers to objects in the InputFile to be closed.
1201  eventHistoryTree_ = nullptr;
1202  for (auto& treePointer : treePointers_) {
1203  treePointer->close();
1204  treePointer = nullptr;
1205  }
1206  filePtr_->Close();
1207  filePtr_ = nullptr; // propagate_const<T> has no reset() function
1208  }
1209 
1212  // Already read.
1213  return;
1214  }
1215  if (fileFormatVersion().newAuxiliary()) {
1216  EventAuxiliary* pEvAux = &eventAux_;
1218  } else {
1219  // for backward compatibility.
1221  EventAux* pEvAux = &eventAux;
1222  eventTree_.fillAux<EventAux>(pEvAux);
1223  conversion(eventAux, eventAux_);
1224  }
1226  }
1227 
1229  if (!eventTree_.current(entry)) {
1230  return false;
1231  }
1232  eventTree_.setEntryNumber(entry);
1234  return true;
1235  }
1236 
1238  // We could consider doing delayed reading, but because we have to
1239  // store this History object in a different tree than the event
1240  // data tree, this is too hard to do in this first version.
1241 
1242  if (fileFormatVersion().eventHistoryBranch()) {
1243  // Lumi block number was not in EventID for the relevant releases.
1244  EventID id(eventAux().id().run(), 0, eventAux().id().event());
1245  if (eventProcessHistoryIter_->eventID() != id) {
1248  assert(eventProcessHistoryIter_->eventID() == id);
1249  }
1252  } else if (fileFormatVersion().eventHistoryTree()) {
1253  // for backward compatibility.
1254  History* pHistory = history_.get();
1255  TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
1256  if (!eventHistoryBranch) {
1257  throw Exception(errors::EventCorruption) << "Failed to find history branch in event history tree.\n";
1258  }
1259  eventHistoryBranch->SetAddress(&pHistory);
1261  eventAux_.setProcessHistoryID(history_->processHistoryID());
1262  eventSelectionIDs_.swap(history_->eventSelectionIDs());
1263  branchListIndexes_.swap(history_->branchListIndexes());
1264  } else if (fileFormatVersion().noMetaDataTrees()) {
1265  // Current format
1267  TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
1268  assert(eventSelectionIDBranch != nullptr);
1269  eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
1271  TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
1272  assert(branchListIndexesBranch != nullptr);
1273  eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
1274  }
1275  if (provenanceAdaptor_) {
1276  eventAux_.setProcessHistoryID(provenanceAdaptor_->convertID(eventAux().processHistoryID()));
1277  for (auto& esID : eventSelectionIDs_) {
1278  esID = provenanceAdaptor_->convertID(esID);
1279  }
1280  }
1281  if (daqProvenanceHelper_) {
1283  }
1285  // old format. branchListIndexes_ must be filled in from the ProvenanceAdaptor.
1286  provenanceAdaptor_->branchListIndexes(branchListIndexes_);
1287  }
1288  if (branchIDListHelper_) {
1289  branchIDListHelper_->fixBranchListIndexes(branchListIndexes_);
1290  }
1291  }
1292 
1293  std::shared_ptr<LuminosityBlockAuxiliary> RootFile::fillLumiAuxiliary() {
1294  auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1295  if (fileFormatVersion().newAuxiliary()) {
1296  LuminosityBlockAuxiliary* pLumiAux = lumiAuxiliary.get();
1298  } else {
1299  LuminosityBlockAux lumiAux;
1300  LuminosityBlockAux* pLumiAux = &lumiAux;
1302  conversion(lumiAux, *lumiAuxiliary);
1303  }
1304  if (provenanceAdaptor_) {
1305  lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1306  }
1307  if (daqProvenanceHelper_) {
1308  lumiAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1309  }
1310  if (lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
1311  lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
1312  }
1313  return lumiAuxiliary;
1314  }
1315 
1316  std::shared_ptr<RunAuxiliary> RootFile::fillRunAuxiliary() {
1317  auto runAuxiliary = std::make_shared<RunAuxiliary>();
1318  if (fileFormatVersion().newAuxiliary()) {
1319  RunAuxiliary* pRunAux = runAuxiliary.get();
1320  runTree_.fillAux<RunAuxiliary>(pRunAux);
1321  } else {
1322  RunAux runAux;
1323  RunAux* pRunAux = &runAux;
1324  runTree_.fillAux<RunAux>(pRunAux);
1325  conversion(runAux, *runAuxiliary);
1326  }
1327  if (provenanceAdaptor_) {
1328  runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1329  }
1330  if (daqProvenanceHelper_) {
1331  runAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1332  }
1333  return runAuxiliary;
1334  }
1335 
1337  while (offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
1338  int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
1339  RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
1342 
1344  phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1345 
1346  // At the end of the file and there were no more events to skip
1347  if (skippedEventEntry == IndexIntoFile::invalidEntry)
1348  break;
1349 
1350  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1351  fillEventAuxiliary(skippedEventEntry);
1352  if (eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, eventAux_.id().event())) {
1353  continue;
1354  }
1355  }
1356  if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
1357  fillEventAuxiliary(skippedEventEntry);
1358  if (duplicateChecker_->isDuplicateAndCheckActive(
1359  phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, eventAux_.id().event(), file_)) {
1360  continue;
1361  }
1362  }
1363  --offset;
1364  }
1365 
1366  while (offset < 0) {
1367  if (duplicateChecker_) {
1368  duplicateChecker_->disable();
1369  }
1370 
1371  int phIndexOfEvent = IndexIntoFile::invalidIndex;
1375 
1376  indexIntoFileIter_.skipEventBackward(phIndexOfEvent, runOfEvent, lumiOfEvent, eventEntry);
1377 
1378  if (eventEntry == IndexIntoFile::invalidEntry)
1379  break;
1380 
1381  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1382  fillEventAuxiliary(eventEntry);
1383  if (eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, eventAux_.id().event())) {
1384  continue;
1385  }
1386  }
1387  ++offset;
1388  }
1390  }
1391 
1394 
1395  if (duplicateChecker_) {
1396  duplicateChecker_->disable();
1397  }
1398 
1400  if (noEventSort_)
1402 
1404  indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
1405 
1406  if (iter == indexIntoFile_.end(sortOrder)) {
1407  return false;
1408  }
1409  indexIntoFileIter_ = iter;
1410  return true;
1411  }
1412 
1413  // readEvent() is responsible for creating, and setting up, the
1414  // EventPrincipal.
1415  //
1416  // 1. create an EventPrincipal with a unique EventID
1417  // 2. For each entry in the provenance, put in one ProductResolver,
1418  // holding the Provenance for the corresponding EDProduct.
1419  // 3. set up the the EventPrincipal to know about this ProductResolver.
1420  //
1421  // We do *not* create the EDProduct instance (the equivalent of reading
1422  // the branch containing this EDProduct. That will be done by the Delayed Reader,
1423  // when it is asked to do so.
1424  //
1428  // read the event auxiliary if not alrady read.
1430 
1431  // read the event
1432  readCurrentEvent(principal);
1433 
1434  runHelper_->checkRunConsistency(eventAux().run(), indexIntoFileIter_.run());
1435  runHelper_->checkLumiConsistency(eventAux().luminosityBlock(), indexIntoFileIter_.lumi());
1436 
1437  // If this next assert shows up in performance profiling or significantly affects memory, then these three lines should be deleted.
1438  // The IndexIntoFile should guarantee that it never fails.
1440  ? *daqProvenanceHelper_->oldProcessHistoryID()
1441  : eventAux().processHistoryID());
1442  ProcessHistoryID const& reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(idToCheck);
1444 
1446  }
1447 
1448  // Reads event at the current entry in the event tree
1450  if (!eventTree_.current()) {
1451  return false;
1452  }
1454  if (!fileFormatVersion().lumiInEventID()) {
1455  //ugly, but will disappear when the backward compatibility is done with schema evolution.
1456  const_cast<EventID&>(eventAux_.id()).setLuminosityBlockNumber(eventAux_.oldLuminosityBlock());
1458  }
1459  fillEventHistory();
1460  runHelper_->overrideRunNumber(eventAux_.id(), eventAux().isRealData());
1461 
1462  // We're not done ... so prepare the EventPrincipal
1464  principal.fillEventPrincipal(eventAux(),
1468  *(makeProductProvenanceRetriever(principal.streamID().value())),
1470 
1471  // report event read from file
1472  filePtr_->eventReadFromFile();
1473  return true;
1474  }
1475 
1477 
1478  std::shared_ptr<RunAuxiliary> RootFile::readRunAuxiliary_() {
1479  if (runHelper_->fakeNewRun()) {
1480  runHelper_->overrideRunNumber(savedRunAuxiliary_->id());
1481  return savedRunAuxiliary();
1482  }
1485 
1486  // Begin code for backward compatibility before the existence of run trees.
1487  if (!runTree_.isValid()) {
1488  // prior to the support of run trees.
1489  // RunAuxiliary did not contain a valid timestamp. Take it from the next event.
1491  assert(eventEntry != IndexIntoFile::invalidEntry);
1492  assert(eventTree_.current(eventEntry));
1493  fillEventAuxiliary(eventEntry);
1494 
1496  runHelper_->overrideRunNumber(run);
1497  savedRunAuxiliary_ = std::make_shared<RunAuxiliary>(run.run(), eventAux().time(), Timestamp::invalidTimestamp());
1498  return savedRunAuxiliary();
1499  }
1500  // End code for backward compatibility before the existence of run trees.
1502  std::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
1503  assert(runAuxiliary->run() == indexIntoFileIter_.run());
1504  runHelper_->overrideRunNumber(runAuxiliary->id());
1505  filePtr_->reportInputRunNumber(runAuxiliary->run());
1506  // If RunAuxiliary did not contain a valid begin timestamp, invalidate any end timestamp.
1507  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1508  runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1509  }
1510 
1511  // If RunAuxiliary did not contain a valid timestamp, or if this an old format file from
1512  // when the Run's ProcessHistory included only processes where products were added to the Run itself,
1513  // we attempt to read the first event in the run to get appropriate info.
1514  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp() ||
1517  // If we have a valid event, use its information.
1518  if (eventEntry != IndexIntoFile::invalidEntry) {
1519  assert(eventTree_.current(eventEntry));
1520  fillEventAuxiliary(eventEntry);
1521 
1522  // RunAuxiliary did not contain a valid timestamp. Take it from the next event in this run if there is one.
1523  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1524  runAuxiliary->setBeginTime(eventAux().time());
1525  }
1526 
1527  // For backwards compatibility when the Run's ProcessHistory included only processes where products were added to the
1528  // Run, and then the Run and Event auxiliaries could be different. Use the event ProcessHistoryID if there is one. It should
1529  // almost always be correct by the current definition (processes included if any products are added. This makes the run, lumi,
1530  // and event ProcessHistory's always be the same if no file merging occurs).
1531  if (!fileFormatVersion().processHistorySameWithinRun()) {
1532  fillEventHistory();
1533  runAuxiliary->setProcessHistoryID(eventAux().processHistoryID());
1534  }
1535  }
1536  }
1537  savedRunAuxiliary_ = runAuxiliary;
1538  return runAuxiliary;
1539  }
1540 
1541  void RootFile::readRun_(RunPrincipal& runPrincipal) {
1542  MergeableRunProductMetadata* mergeableRunProductMetadata = nullptr;
1543  if (inputType_ == InputType::Primary) {
1544  mergeableRunProductMetadata = runPrincipal.mergeableRunProductMetadata();
1545  RootTree::EntryNumber const& entryNumber = runTree_.entryNumber();
1546  assert(entryNumber >= 0);
1547  mergeableRunProductMetadata->readRun(
1549  }
1550 
1551  if (!runHelper_->fakeNewRun()) {
1555  }
1556  // Begin code for backward compatibility before the existence of run trees.
1557  if (!runTree_.isValid()) {
1558  return;
1559  }
1560  // End code for backward compatibility before the existence of run trees.
1561  // NOTE: we use 0 for the index since do not do delayed reads for RunPrincipals
1564  // Read in all the products now.
1565  runPrincipal.readAllFromSourceAndMergeImmediately(mergeableRunProductMetadata);
1566  }
1567 
1568  std::shared_ptr<LuminosityBlockAuxiliary> RootFile::readLuminosityBlockAuxiliary_() {
1571  // Begin code for backward compatibility before the existence of lumi trees.
1572  if (!lumiTree_.isValid()) {
1574  assert(eventEntry != IndexIntoFile::invalidEntry);
1575  assert(eventTree_.current(eventEntry));
1576  fillEventAuxiliary(eventEntry);
1577 
1579  runHelper_->overrideRunNumber(lumi);
1580  return std::make_shared<LuminosityBlockAuxiliary>(
1582  }
1583  // End code for backward compatibility before the existence of lumi trees.
1585  std::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
1586  assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
1587  assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
1588  runHelper_->overrideRunNumber(lumiAuxiliary->id());
1589  filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1590  if (lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1592  if (eventEntry != IndexIntoFile::invalidEntry) {
1593  assert(eventTree_.current(eventEntry));
1594  fillEventAuxiliary(eventEntry);
1595 
1596  lumiAuxiliary->setBeginTime(eventAux().time());
1597  }
1598  lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1599  }
1600  if (!fileFormatVersion().processHistorySameWithinRun() && savedRunAuxiliary_) {
1601  lumiAuxiliary->setProcessHistoryID(savedRunAuxiliary_->processHistoryID());
1602  }
1603  return lumiAuxiliary;
1604  }
1605 
1609  // Begin code for backward compatibility before the existence of lumi trees.
1610  if (!lumiTree_.isValid()) {
1612  return;
1613  }
1614  // End code for backward compatibility before the existence of lumi trees.
1616  // NOTE: we use 0 for the index since do not do delayed reads for LuminosityBlockPrincipals
1619  // Read in all the products now.
1620  lumiPrincipal.readAllFromSourceAndMergeImmediately();
1622  }
1623 
1627  return false;
1629  return true;
1630  }
1631 
1635  return false;
1637  return true;
1638  }
1639 
1643  return false;
1645  return true;
1646  }
1647 
1651  }
1654  return false;
1655  if (run != indexIntoFileIter_.run())
1656  return false;
1657  if (lumi != indexIntoFileIter_.lumi())
1658  return false;
1660  return true;
1661  }
1662 
1664  // Read in the event history tree, if we have one...
1665  if (fileFormatVersion().eventHistoryTree()) {
1666  history_ = std::make_unique<History>(); // propagate_const<T> has no reset() function
1667  eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
1668  if (!eventHistoryTree_) {
1669  throw Exception(errors::EventCorruption) << "Failed to find the event history tree.\n";
1670  }
1671  }
1672  }
1673 
1675  std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
1676  std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile) {
1677  if (duplicateChecker_ && !duplicateChecker_->checkDisabled()) {
1678  if (eventTree_.next()) {
1680  duplicateChecker_->inputFileOpened(
1681  eventAux().isRealData(), indexIntoFile_, indexesIntoFiles, currentIndexIntoFile);
1682  }
1684  }
1685  }
1686 
1687  void RootFile::markBranchToBeDropped(bool dropDescendants,
1688  BranchDescription const& branch,
1689  std::set<BranchID>& branchesToDrop,
1690  std::map<BranchID, BranchID> const& droppedToKeptAlias) const {
1691  if (dropDescendants) {
1692  branchChildren_->appendToDescendants(branch, branchesToDrop, droppedToKeptAlias);
1693  } else {
1694  branchesToDrop.insert(branch.branchID());
1695  }
1696  }
1697 
1699  ProductSelectorRules const& rules,
1700  bool dropDescendants,
1701  InputType inputType) {
1702  // This is the selector for drop on input.
1703  ProductSelector productSelector;
1704  productSelector.initialize(rules, reg.allBranchDescriptions());
1705 
1706  std::vector<BranchDescription const*> associationDescriptions;
1707 
1709  // Do drop on input. On the first pass, just fill in a set of branches to be dropped.
1710  std::set<BranchID> branchesToDrop;
1711  std::map<BranchID, BranchID> droppedToKeptAlias;
1712  for (auto const& product : prodList) {
1713  BranchDescription const& prod = product.second;
1714  if (prod.branchID() != prod.originalBranchID() && prod.present()) {
1715  droppedToKeptAlias[prod.originalBranchID()] = prod.branchID();
1716  }
1717  }
1718  for (auto const& product : prodList) {
1719  BranchDescription const& prod = product.second;
1720  // Special handling for ThinnedAssociations
1721  if (prod.unwrappedType() == typeid(ThinnedAssociation) && prod.present()) {
1722  if (inputType != InputType::SecondarySource) {
1723  associationDescriptions.push_back(&prod);
1724  } else {
1725  markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1726  }
1727  } else if (!productSelector.selected(prod)) {
1728  markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1729  }
1730  }
1731 
1732  if (inputType != InputType::SecondarySource) {
1733  // Decide whether to keep the thinned associations and corresponding
1734  // entries in the helper. For secondary source they are all dropped,
1735  // but in other cases we look for thinned collections the associations
1736  // redirect a Ref or Ptr to when dereferencing them.
1737 
1738  // Need a list of kept products in order to determine which thinned associations
1739  // are kept.
1740  std::set<BranchID> keptProductsInEvent;
1741  for (auto const& product : prodList) {
1742  BranchDescription const& prod = product.second;
1743  if (branchesToDrop.find(prod.branchID()) == branchesToDrop.end() && prod.present() &&
1744  prod.branchType() == InEvent) {
1745  keptProductsInEvent.insert(prod.branchID());
1746  }
1747  }
1748 
1749  // Decide which ThinnedAssociations to keep and store the decision in keepAssociation
1750  std::map<BranchID, bool> keepAssociation;
1751  fileThinnedAssociationsHelper_->selectAssociationProducts(
1752  associationDescriptions, keptProductsInEvent, keepAssociation);
1753 
1754  for (auto association : associationDescriptions) {
1755  if (!keepAssociation[association->branchID()]) {
1756  markBranchToBeDropped(dropDescendants, *association, branchesToDrop, droppedToKeptAlias);
1757  }
1758  }
1759 
1760  // Also delete the dropped associations from the ThinnedAssociationsHelper
1761  auto temp = std::make_unique<ThinnedAssociationsHelper>();
1762  for (auto const& associationBranches : fileThinnedAssociationsHelper_->data()) {
1763  auto iter = keepAssociation.find(associationBranches.association());
1764  if (iter != keepAssociation.end() && iter->second) {
1765  temp->addAssociation(associationBranches);
1766  }
1767  }
1768  // propagate_const<T> has no reset() function
1769  fileThinnedAssociationsHelper_ = std::unique_ptr<ThinnedAssociationsHelper>(temp.release());
1770  }
1771 
1772  // On this pass, actually drop the branches.
1773  std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
1774  for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1775  BranchDescription const& prod = it->second;
1776  bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
1777  if (drop) {
1778  if (!prod.dropped()) {
1779  if (productSelector.selected(prod) && prod.unwrappedType() != typeid(ThinnedAssociation)) {
1780  LogWarning("RootFile") << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
1781  << "of file '" << file_ << "' because it is dependent on a branch\n"
1782  << "that was explicitly dropped.\n";
1783  }
1784  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
1785  hasNewlyDroppedBranch_[prod.branchType()] = true;
1786  }
1787  ProductRegistry::ProductList::iterator icopy = it;
1788  ++it;
1789  prodList.erase(icopy);
1790  } else {
1791  ++it;
1792  }
1793  }
1794 
1795  // Drop on input mergeable run and lumi products, this needs to be invoked for secondary file input
1796  if (inputType == InputType::SecondaryFile) {
1797  TString tString;
1798  for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
1799  BranchDescription const& prod = it->second;
1800  if (prod.branchType() != InEvent) {
1801  TClass* cp = prod.wrappedType().getClass();
1802  void* p = cp->New();
1803  int offset = cp->GetBaseClassOffset(edProductClass_);
1804  std::unique_ptr<WrapperBase> edp = getWrapperBasePtr(p, offset);
1805  if (edp->isMergeable()) {
1806  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
1807  ProductRegistry::ProductList::iterator icopy = it;
1808  ++it;
1809  prodList.erase(icopy);
1810  } else {
1811  ++it;
1812  }
1813  } else
1814  ++it;
1815  }
1816  }
1817  }
1818 
1820  signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* preEventReadSource,
1821  signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* postEventReadSource) {
1822  eventTree_.setSignals(preEventReadSource, postEventReadSource);
1823  }
1824 
1825  std::unique_ptr<MakeProvenanceReader> RootFile::makeProvenanceReaderMaker(InputType inputType) {
1827  readParentageTree(inputType);
1828  return std::make_unique<MakeReducedProvenanceReader>(parentageIDLookup_);
1829  } else if (fileFormatVersion_.splitProductIDs()) {
1830  readParentageTree(inputType);
1831  return std::make_unique<MakeFullProvenanceReader>();
1832  } else if (fileFormatVersion_.perEventProductIDs()) {
1833  auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
1834  readEntryDescriptionTree(*entryDescriptionMap, inputType);
1835  return std::make_unique<MakeOldProvenanceReader>(std::move(entryDescriptionMap));
1836  } else {
1837  return std::make_unique<MakeDummyProvenanceReader>();
1838  }
1839  }
1840 
1841  std::shared_ptr<ProductProvenanceRetriever> RootFile::makeProductProvenanceRetriever(unsigned int iStreamID) {
1842  if (eventProductProvenanceRetrievers_.size() <= iStreamID) {
1843  eventProductProvenanceRetrievers_.resize(iStreamID + 1);
1844  }
1845  if (!eventProductProvenanceRetrievers_[iStreamID]) {
1846  // propagate_const<T> has no reset() function
1847  eventProductProvenanceRetrievers_[iStreamID] = std::make_shared<ProductProvenanceRetriever>(
1849  }
1850  eventProductProvenanceRetrievers_[iStreamID]->reset();
1851  return eventProductProvenanceRetriever(iStreamID);
1852  }
1853 
1855  public:
1856  ReducedProvenanceReader(RootTree* iRootTree,
1857  std::vector<ParentageID> const& iParentageIDLookup,
1858  DaqProvenanceHelper const* daqProvenanceHelper);
1859 
1860  std::set<ProductProvenance> readProvenance(unsigned int) const override;
1861 
1862  private:
1863  void readProvenanceAsync(WaitingTask* task,
1864  ModuleCallingContext const* moduleCallingContext,
1865  unsigned int transitionIndex,
1866  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
1867 
1872  std::vector<ParentageID> const& parentageIDLookup_;
1874  std::shared_ptr<std::recursive_mutex> mutex_;
1876  };
1877 
1879  std::vector<ParentageID> const& iParentageIDLookup,
1880  DaqProvenanceHelper const* daqProvenanceHelper)
1882  rootTree_(iRootTree),
1883  pProvVector_(&provVector_),
1884  parentageIDLookup_(iParentageIDLookup),
1885  daqProvenanceHelper_(daqProvenanceHelper),
1886  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
1887  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {
1888  provBranch_ =
1889  rootTree_->tree()->GetBranch(BranchTypeToProductProvenanceBranchName(rootTree_->branchType()).c_str());
1890  }
1891 
1892  namespace {
1894  template <typename R>
1895  void readProvenanceAsyncImpl(R const* iThis,
1897  WaitingTask* task,
1898  unsigned int transitionIndex,
1899  std::atomic<const std::set<ProductProvenance>*>& writeTo,
1900  ModuleCallingContext const* iContext,
1901  SignalType const* pre,
1902  SignalType const* post) {
1903  if (nullptr == writeTo.load()) {
1904  //need to be sure the task isn't run until after the read
1905  WaitingTaskHolder taskHolder{task};
1906  auto pWriteTo = &writeTo;
1907 
1908  auto serviceToken = ServiceRegistry::instance().presentToken();
1909 
1910  chain.push([holder = std::move(taskHolder),
1911  pWriteTo,
1912  iThis,
1913  transitionIndex,
1914  iContext,
1915  pre,
1916  post,
1917  serviceToken]() mutable {
1918  if (nullptr == pWriteTo->load()) {
1919  ServiceRegistry::Operate operate(serviceToken);
1920  std::unique_ptr<const std::set<ProductProvenance>> prov;
1921  try {
1922  if (pre) {
1923  pre->emit(*(iContext->getStreamContext()), *iContext);
1924  }
1925  prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
1926  if (post) {
1927  post->emit(*(iContext->getStreamContext()), *iContext);
1928  }
1929 
1930  } catch (...) {
1931  if (post) {
1932  post->emit(*(iContext->getStreamContext()), *iContext);
1933  }
1934 
1935  holder.doneWaiting(std::current_exception());
1936  return;
1937  }
1938  const std::set<ProductProvenance>* expected = nullptr;
1939 
1940  if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
1941  prov.release();
1942  }
1943  }
1944  holder.doneWaiting(std::exception_ptr());
1945  });
1946  }
1947  }
1948  } // namespace
1949 
1951  ModuleCallingContext const* moduleCallingContext,
1952  unsigned int transitionIndex,
1953  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
1954  readProvenanceAsyncImpl(this,
1956  task,
1957  transitionIndex,
1958  writeTo,
1959  moduleCallingContext,
1960  rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
1961  rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
1962  }
1963 
1964  std::set<ProductProvenance> ReducedProvenanceReader::readProvenance(unsigned int transitionIndex) const {
1965  {
1966  std::lock_guard<std::recursive_mutex> guard(*mutex_);
1967  ReducedProvenanceReader* me = const_cast<ReducedProvenanceReader*>(this);
1968  me->rootTree_->fillBranchEntry(
1969  me->provBranch_, me->rootTree_->entryNumberForIndex(transitionIndex), me->pProvVector_);
1970  }
1971  std::set<ProductProvenance> retValue;
1972  if (daqProvenanceHelper_) {
1973  for (auto const& prov : provVector_) {
1974  BranchID bid(prov.branchID_);
1975  retValue.emplace(daqProvenanceHelper_->mapBranchID(BranchID(prov.branchID_)),
1976  daqProvenanceHelper_->mapParentageID(parentageIDLookup_[prov.parentageIDIndex_]));
1977  }
1978  } else {
1979  for (auto const& prov : provVector_) {
1980  if (prov.parentageIDIndex_ >= parentageIDLookup_.size()) {
1982  << "ReducedProvenanceReader::ReadProvenance\n"
1983  << "The parentage ID index value " << prov.parentageIDIndex_
1984  << " is out of bounds. The maximum value is " << parentageIDLookup_.size() - 1 << ".\n"
1985  << "This should never happen.\n"
1986  << "Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
1987  }
1988  retValue.emplace(BranchID(prov.branchID_), parentageIDLookup_[prov.parentageIDIndex_]);
1989  }
1990  }
1991  return retValue;
1992  }
1993 
1995  public:
1996  explicit FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
1998  std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
1999 
2000  private:
2002  ModuleCallingContext const* moduleCallingContext,
2003  unsigned int transitionIndex,
2004  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2005 
2010  std::shared_ptr<std::recursive_mutex> mutex_;
2012  };
2013 
2016  rootTree_(rootTree),
2017  infoVector_(),
2018  pInfoVector_(&infoVector_),
2019  daqProvenanceHelper_(daqProvenanceHelper),
2020  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2021  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2022 
2024  ModuleCallingContext const* moduleCallingContext,
2025  unsigned int transitionIndex,
2026  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2027  readProvenanceAsyncImpl(this,
2029  task,
2030  transitionIndex,
2031  writeTo,
2032  moduleCallingContext,
2035  }
2036 
2037  std::set<ProductProvenance> FullProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2038  {
2039  std::lock_guard<std::recursive_mutex> guard(*mutex_);
2042  }
2043  std::set<ProductProvenance> retValue;
2044  if (daqProvenanceHelper_) {
2045  for (auto const& info : infoVector_) {
2046  retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2047  daqProvenanceHelper_->mapParentageID(info.parentageID()));
2048  }
2049  } else {
2050  for (auto const& info : infoVector_) {
2051  retValue.emplace(info);
2052  }
2053  }
2054  return retValue;
2055  }
2056 
2058  public:
2059  explicit OldProvenanceReader(RootTree* rootTree,
2060  EntryDescriptionMap const& theMap,
2061  DaqProvenanceHelper const* daqProvenanceHelper);
2062  ~OldProvenanceReader() override {}
2063  std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
2064 
2065  private:
2067  ModuleCallingContext const* moduleCallingContext,
2068  unsigned int transitionIndex,
2069  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2070 
2072  std::vector<EventEntryInfo> infoVector_;
2073  mutable std::vector<EventEntryInfo>* pInfoVector_;
2076  std::shared_ptr<std::recursive_mutex> mutex_;
2078  };
2079 
2081  EntryDescriptionMap const& theMap,
2082  DaqProvenanceHelper const* daqProvenanceHelper)
2084  rootTree_(rootTree),
2085  infoVector_(),
2087  entryDescriptionMap_(theMap),
2088  daqProvenanceHelper_(daqProvenanceHelper),
2089  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2090  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2091 
2093  ModuleCallingContext const* moduleCallingContext,
2094  unsigned int transitionIndex,
2095  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2096  readProvenanceAsyncImpl(this,
2098  task,
2099  transitionIndex,
2100  writeTo,
2101  moduleCallingContext,
2102  rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2103  rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2104  }
2105 
2106  std::set<ProductProvenance> OldProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2107  {
2108  std::lock_guard<std::recursive_mutex> guard(*mutex_);
2109  rootTree_->branchEntryInfoBranch()->SetAddress(&pInfoVector_);
2110  roottree::getEntry(rootTree_->branchEntryInfoBranch(), rootTree_->entryNumberForIndex(transitionIndex));
2111  }
2112  std::set<ProductProvenance> retValue;
2113  for (auto const& info : infoVector_) {
2114  EntryDescriptionMap::const_iterator iter = entryDescriptionMap_.find(info.entryDescriptionID());
2115  assert(iter != entryDescriptionMap_.end());
2116  Parentage parentage(iter->second.parents());
2117  if (daqProvenanceHelper_) {
2118  retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2119  daqProvenanceHelper_->mapParentageID(parentage.id()));
2120  } else {
2121  retValue.emplace(info.branchID(), parentage.id());
2122  }
2123  }
2124  return retValue;
2125  }
2126 
2128  public:
2131 
2132  private:
2133  std::set<ProductProvenance> readProvenance(unsigned int) const override;
2135  ModuleCallingContext const* moduleCallingContext,
2136  unsigned int transitionIndex,
2137  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2138  };
2139 
2141 
2142  std::set<ProductProvenance> DummyProvenanceReader::readProvenance(unsigned int) const {
2143  // Not providing parentage!!!
2144  return std::set<ProductProvenance>{};
2145  }
2147  ModuleCallingContext const* moduleCallingContext,
2148  unsigned int transitionIndex,
2149  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2150  if (nullptr == writeTo.load()) {
2151  auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2152  const std::set<ProductProvenance>* expected = nullptr;
2153  if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2154  emptyProv.release();
2155  }
2156  }
2157  }
2158 
2159  std::unique_ptr<ProvenanceReaderBase> MakeDummyProvenanceReader::makeReader(RootTree&,
2160  DaqProvenanceHelper const*) const {
2161  return std::make_unique<DummyProvenanceReader>();
2162  }
2163 
2164  std::unique_ptr<ProvenanceReaderBase> MakeOldProvenanceReader::makeReader(
2165  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2166  return std::make_unique<OldProvenanceReader>(&rootTree, *entryDescriptionMap_, daqProvenanceHelper);
2167  }
2168 
2169  std::unique_ptr<ProvenanceReaderBase> MakeFullProvenanceReader::makeReader(
2170  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2171  return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2172  }
2173 
2174  std::unique_ptr<ProvenanceReaderBase> MakeReducedProvenanceReader::makeReader(
2175  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2176  return std::make_unique<ReducedProvenanceReader>(&rootTree, parentageIDLookup_, daqProvenanceHelper);
2177  }
2178 } // namespace edm
void dropOnInput(ProductRegistry &reg, ProductSelectorRules const &rules, bool dropDescendants, InputType inputType)
Definition: RootFile.cc:1698
RunNumber_t run() const
Definition: EventID.h:39
EventID const & eventID() const
Definition: RootFile.h:220
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:495
void fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const
EventNumber_t event() const
Definition: EventID.h:41
std::string const & idToParameterSetBlobsBranchName()
Definition: BranchType.cc:261
edm::propagate_const< std::unique_ptr< ThinnedAssociationsHelper > > fileThinnedAssociationsHelper_
Definition: RootFile.h:346
std::vector< ProcessConfiguration > ProcessConfigurationVector
void setEventFinder(std::shared_ptr< EventFinder > ptr) const
std::string const & branchName() const
StoredProductProvenanceVector provVector_
Definition: RootFile.cc:1870
bool isRealData() const
bool selected(BranchDescription const &desc) const
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:116
unsigned int const defaultNonEventLearningEntries
Definition: RootTree.h:49
InputType
Definition: InputType.h:5
static const TGPicture * info(bool iBackgroundIsBlack)
void doneFileInitialization() const
Clears the temporary vector of event numbers to reduce memory usage.
static constexpr int invalidIndex
TPRegexp parents
Definition: eve_filter.cc:21
BranchType const & branchType() const
std::string const & parentageTreeName()
Definition: BranchType.cc:160
std::vector< BranchIDList > BranchIDLists
Definition: BranchIDList.h:19
std::shared_ptr< BranchIDLists const > branchIDLists_
Definition: RootFile.h:344
std::string const & entryDescriptionBranchName()
Definition: BranchType.cc:155
bool skipEvents(int &offset)
Definition: RootFile.cc:1336
StreamContext const * getStreamContext() const
edm::propagate_const< std::shared_ptr< DuplicateChecker > > duplicateChecker_
Definition: RootFile.h:356
FileFormatVersion fileFormatVersion() const
Definition: RootFile.h:224
std::shared_ptr< LuminosityBlockAuxiliary > fillLumiAuxiliary()
Definition: RootFile.cc:1293
ProductProvenanceVector infoVector_
Definition: RootFile.cc:2007
static std::string const source("source")
static Timestamp invalidTimestamp()
Definition: Timestamp.h:101
ForwardSequence::const_iterator lower_bound_all(ForwardSequence const &s, Datum const &d)
wrappers for std::lower_bound
Definition: Algorithms.h:69
Definition: chain.py:1
void readEntryDescriptionTree(EntryDescriptionMap &entryDescriptionMap, InputType inputType)
Definition: RootFile.cc:586
bool branchListIndexesUnchanged() const
Definition: RootFile.h:227
RunNumber_t run() const
Definition: RunID.h:39
std::vector< std::string > const & branchNames() const
Definition: RootTree.h:138
bool setEntryAtNextEventInLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1648
bool enforceGUIDInFileName_
Definition: RootFile.h:333
static PFTauRenderPlugin instance
MakeOldProvenanceReader(std::unique_ptr< EntryDescriptionMap > &&entryDescriptionMap)
Definition: RootFile.cc:78
int whyNotFastClonable_
Definition: RootFile.h:334
std::vector< BranchID > & parentsForUpdate()
Definition: Parentage.h:45
edm::propagate_const< std::shared_ptr< EventSkipperByID > > eventSkipperByID_
Definition: RootFile.h:318
edm::propagate_const< std::shared_ptr< ThinnedAssociationsHelper > > thinnedAssociationsHelper_
Definition: RootFile.h:347
ParentageID id() const
Definition: Parentage.cc:23
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:2009
std::map< std::string, std::string > newBranchToOldBranch_
Definition: RootFile.h:350
bool empty() const
True if no runs, lumis, or events are in the file.
std::map< BranchKey, BranchDescription > ProductList
BranchID const & mapBranchID(BranchID const &branchID) const
#define nullptr
bool registerProcessHistory(ProcessHistory const &processHistory)
bool setEntryAtRun(RunNumber_t run)
Definition: RootFile.cc:1640
void readRun_(RunPrincipal &runPrincipal)
Definition: RootFile.cc:1541
std::string_view stemFromPath(std::string_view path)
Definition: stemFromPath.cc:4
ProductProvenanceVector * pInfoVector_
Definition: RootFile.cc:2008
RootTree lumiTree_
Definition: RootFile.h:339
Timestamp const & time() const
InputType inputType_
Definition: RootFile.h:363
edm::propagate_const< ProcessHistoryRegistry * > processHistoryRegistry_
Definition: RootFile.h:316
edm::propagate_const< std::unique_ptr< DaqProvenanceHelper > > daqProvenanceHelper_
Definition: RootFile.h:361
edm::propagate_const< std::shared_ptr< RunAuxiliary > > savedRunAuxiliary_
Definition: RootFile.h:330
unsigned long long EventNumber_t
EntryNumber const & entries() const
Definition: RootTree.h:135
RunNumber_t run() const
void setSignals(signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *preEventReadSource, signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *postEventReadSource)
Definition: RootTree.cc:488
std::string const & fileFormatVersionBranchName()
Definition: BranchType.cc:219
IndexIntoFileItr begin(SortOrder sortOrder) const
FullProvenanceReader(RootTree *rootTree, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:2014
EntryDescriptionMap const & entryDescriptionMap_
Definition: RootFile.cc:2074
std::vector< BranchID > const & parents() const
std::string const & eventSelectionsBranchName()
Definition: BranchType.cc:249
edm::propagate_const< std::unique_ptr< EntryDescriptionMap > > entryDescriptionMap_
Definition: RootFile.cc:84
void initializeDuplicateChecker(std::vector< std::shared_ptr< IndexIntoFile >> const &indexesIntoFiles, std::vector< std::shared_ptr< IndexIntoFile >>::size_type currentIndexIntoFile)
Definition: RootFile.cc:1674
void push(T &&iAction)
asynchronously pushes functor iAction into queue
InputSource::ProcessingMode processingMode_
Definition: RootFile.h:348
~RootFileEventFinder() override
Definition: RootFile.cc:123
IndexIntoFile::IndexIntoFileItr indexIntoFileIter_
Definition: RootFile.h:326
std::shared_ptr< ProductProvenanceRetriever const > eventProductProvenanceRetriever(size_t index) const
Definition: RootFile.h:306
bool current() const
Definition: RootTree.h:128
void fillRunPrincipal(ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
Definition: RunPrincipal.cc:26
void stable_sort_all(RandomAccessSequence &s)
wrappers for std::stable_sort
Definition: Algorithms.h:103
std::shared_ptr< std::recursive_mutex > mutex_
Definition: RootFile.cc:2076
LuminosityBlockNumber_t lumi() const
void fillBranchEntryMeta(TBranch *branch, T *&pbuf)
Definition: RootTree.h:147
std::unique_ptr< FileBlock > createFileBlock() const
Definition: RootFile.cc:711
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:40
void trainCache(char const *branchNames)
Definition: RootTree.cc:460
bool readCurrentEvent(EventPrincipal &cache)
Definition: RootFile.cc:1449
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:2077
~FullProvenanceReader() override
Definition: RootFile.cc:1997
ServiceToken presentToken() const
std::shared_ptr< ProductRegistry const > productRegistry() const
Definition: RootFile.h:215
uint16_t size_type
unsigned int LuminosityBlockNumber_t
IndexIntoFileItr findRunPosition(RunNumber_t run) const
Same as findPosition.
void readProvenanceAsync(WaitingTask *task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > * > &writeTo) const override
Definition: RootFile.cc:2092
void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const *mergeableRunProductMetadata=0)
Definition: Principal.cc:904
TBranch * branchEntryInfoBranch() const
Definition: RootTree.h:186
bool fillEventAuxiliary(IndexIntoFile::EntryNumber_t entry)
Definition: RootFile.cc:1228
MakeReducedProvenanceReader(std::vector< ParentageID > const &parentageIDLookup)
Definition: RootFile.cc:93
IndexIntoFileItr findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi=0U, EventNumber_t event=0U) const
std::vector< EventSelectionID > EventSelectionIDVector
edm::propagate_const< TClass * > edProductClass_
Definition: RootFile.h:362
LuminosityBlockNumber_t luminosityBlock() const
FileFormatVersion fileFormatVersion_
Definition: RootFile.h:319
TTree const * metaTree() const
Definition: RootTree.h:182
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:257
void setPosition(IndexIntoFile::IndexIntoFileItr const &position)
Definition: RootFile.cc:737
std::vector< edm::propagate_const< std::shared_ptr< ProductProvenanceRetriever > > > eventProductProvenanceRetrievers_
Definition: RootFile.h:359
edm::propagate_const< RootTree * > rootTree_
Definition: RootFile.cc:2071
ProductList const & productList() const
U second(std::pair< T, U > const &p)
std::vector< EventProcessHistoryID >::const_iterator eventProcessHistoryIter_
Definition: RootFile.h:329
void reduceProcessHistoryIDs(ProcessHistoryRegistry const &processHistoryRegistry)
bool skipThisEntry()
Definition: RootFile.cc:746
char const * label
TTree const * tree() const
Definition: RootTree.h:180
FileID fid_
Definition: RootFile.h:320
long long EntryNumber_t
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
Definition: RootFile.cc:797
void setParents(std::vector< BranchID > const &parents)
Definition: Parentage.h:46
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:1873
std::string const logicalFile_
Definition: RootFile.h:314
def principal(options)
std::vector< BranchListIndex > BranchListIndexes
IndexIntoFile::IndexIntoFileItr indexIntoFileEnd_
Definition: RootFile.h:325
std::string moduleName(Provenance const &provenance)
Definition: Provenance.cc:27
void fillLuminosityBlockPrincipal(ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
void readParentageTree(InputType inputType)
Definition: RootFile.cc:632
std::string const & processHistoryMapBranchName()
Definition: BranchType.cc:194
std::vector< ProcessHistoryID > & setProcessHistoryIDs()
bool next()
Definition: RootTree.h:125
edm::propagate_const< std::unique_ptr< StoredMergeableRunProductMetadata > > storedMergeableRunProductMetadata_
Definition: RootFile.h:327
TClass * getClass() const
bool noEventSort_
Definition: RootFile.h:332
std::string const & className() const
bool wasLastEventJustRead() const
Definition: RootFile.cc:846
void insertEntryForIndex(unsigned int index)
Definition: RootTree.cc:104
DelayedReader * resetAndGetRootDelayedReader() const
Definition: RootTree.cc:122
bool setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1632
std::string friendlyName(std::string const &iFullName)
static constexpr RunNumber_t invalidRun
std::string const & entryDescriptionTreeName()
Definition: BranchType.cc:147
void close()
Definition: RootFile.cc:1199
virtual signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * postEventReadFromSourceSignal() const =0
std::string const & fid() const
Definition: FileID.h:19
std::shared_ptr< std::recursive_mutex > mutex_
Definition: RootFile.cc:2010
std::string const & mergeableRunProductMetadataBranchName()
Definition: BranchType.cc:239
RootTree const & runTree() const
Definition: RootFile.h:223
bool modifiedIDs() const
Definition: RootFile.h:228
IndexIntoFile::EntryNumber_t lastEventEntryNumberRead_
Definition: RootFile.h:342
void copyPosition(IndexIntoFileItr const &position)
Copy the position without modifying the pointer to the IndexIntoFile or size.
std::string const & indexIntoFileBranchName()
Definition: BranchType.cc:234
IndexIntoFileItr end(SortOrder sortOrder) const
Used to end an iteration over the Runs, Lumis, and Events in a file.
std::string const & eventHistoryBranchName()
Definition: BranchType.cc:244
std::set< ProductProvenance > readProvenance(unsigned int transitionIndex) const override
Definition: RootFile.cc:2037
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
edm::propagate_const< RootTree * > rootTree_
Definition: RootFile.cc:1868
std::shared_ptr< RunAuxiliary > readRunAuxiliary_()
Definition: RootFile.cc:1478
EventAuxiliary const & eventAux() const
Definition: RootFile.h:216
EventSelectionIDVector eventSelectionIDs_
Definition: RootFile.h:352
std::shared_ptr< LuminosityBlockAuxiliary > readLuminosityBlockAuxiliary_()
Definition: RootFile.cc:1568
bool eventHistoryTree() const
bool isEarlierRelease(std::string const &a, std::string const &b)
StoredProductProvenanceVector const * pProvVector_
Definition: RootFile.cc:1871
int whyNotFastClonable() const
Definition: RootFile.h:225
edm::propagate_const< std::unique_ptr< ProvenanceAdaptor > > provenanceAdaptor_
Definition: RootFile.h:357
StreamID streamID() const
static ServiceRegistry & instance()
RunNumber_t run() const
std::shared_ptr< RunAuxiliary > fillRunAuxiliary()
Definition: RootFile.cc:1316
bool skipAnyEvents_
Definition: RootFile.h:331
void setSignals(signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *preEventReadSource, signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *postEventReadSource)
Definition: RootFile.cc:1819
RootTree eventTree_
Definition: RootFile.h:338
std::vector< BranchDescription const * > allBranchDescriptions() const
EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const override
Definition: RootFile.cc:125
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
TypeWithDict const & unwrappedType() const
bool insertMapped(value_type const &v, bool forceUpdate=false)
Definition: Registry.cc:32
std::array< bool, NumBranchTypes > const & hasNewlyDroppedBranch() const
Definition: RootFile.h:226
IndexIntoFile::EntryType getNextItemType(RunNumber_t &run, LuminosityBlockNumber_t &lumi, EventNumber_t &event)
Definition: RootFile.cc:801
BranchListIndexes branchListIndexes_
Definition: RootFile.h:353
std::string const & metaDataTreeName()
Definition: BranchType.cc:169
virtual signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * preEventReadFromSourceSignal() const =0
bool isDuplicateEvent()
Definition: RootFile.cc:784
LuminosityBlockNumber_t oldLuminosityBlock() const
EntryDescriptionID id() const
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
IndexIntoFile::EntryNumber_t EntryNumber
Definition: RootTree.h:50
bool wasFirstEventJustRead() const
Definition: RootFile.cc:852
std::string const & parameterSetMapBranchName()
Definition: BranchType.cc:184
Hash< ProcessHistoryType > ProcessHistoryID
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2159
edm::propagate_const< std::unique_ptr< History > > history_
Definition: RootFile.h:354
SerialTaskQueueChain & serialQueueChain() const
std::vector< ProductProvenance > ProductProvenanceVector
const int drop
std::string const & processHistoryBranchName()
Definition: BranchType.cc:199
IndexIntoFile & indexIntoFile_
Definition: RootFile.h:322
void readEvent(EventPrincipal &cache)
Definition: RootFile.cc:1425
RootTree runTree_
Definition: RootFile.h:340
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:2011
edm::propagate_const< std::unique_ptr< MakeProvenanceReader > > provenanceReaderMaker_
Definition: RootFile.h:358
EntryNumber const & entryNumber() const
Definition: RootTree.h:133
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
bool goToEvent(EventID const &eventID)
Definition: RootFile.cc:1392
std::string getReleaseVersion()
std::shared_ptr< RunAuxiliary const > savedRunAuxiliary() const
Definition: RootFile.h:300
std::set< ProductProvenance > readProvenance(unsigned int) const override
Definition: RootFile.cc:1964
RootFile(std::string const &fileName, ProcessConfiguration const &processConfiguration, std::string const &logicalFileName, std::shared_ptr< InputFile > filePtr, std::shared_ptr< EventSkipperByID > eventSkipperByID, bool skipAnyEvents, int remainingEvents, int remainingLumis, unsigned int nStreams, unsigned int treeCacheSize, int treeMaxVirtualSize, InputSource::ProcessingMode processingMode, RunHelperBase *runHelper, bool noEventSort, ProductSelectorRules const &productSelectorRules, InputType inputType, std::shared_ptr< BranchIDListHelper > branchIDListHelper, std::shared_ptr< ThinnedAssociationsHelper > thinnedAssociationsHelper, std::vector< BranchID > const *associationsFromSecondary, std::shared_ptr< DuplicateChecker > duplicateChecker, bool dropDescendantsOfDroppedProducts, ProcessHistoryRegistry &processHistoryRegistry, std::vector< std::shared_ptr< IndexIntoFile >> const &indexesIntoFiles, std::vector< std::shared_ptr< IndexIntoFile >>::size_type currentIndexIntoFile, std::vector< ProcessHistoryID > &orderedProcessHistoryIDs, bool bypassVersionCheck, bool labelRawDataLikeMC, bool usingGoToEvent, bool enablePrefetching, bool enforceGUIDInFileName)
Definition: RootFile.cc:140
void setAtEventEntry(IndexIntoFile::EntryNumber_t entry)
Definition: RootFile.cc:1476
bool storedProductProvenanceUsed() const
void fixIndexes(std::vector< ProcessHistoryID > &processHistoryIDs)
DelayedReader * rootDelayedReader() const
Definition: RootTree.cc:127
std::vector< RunOrLumiEntry > & setRunOrLumiEntries()
EntryNumber const & entryNumberForIndex(unsigned int index) const
Definition: RootTree.cc:99
void conversion(EventAux const &from, EventAuxiliary &to)
Definition: EventAux.cc:9
std::array< bool, NumBranchTypes > hasNewlyDroppedBranch_
Definition: RootFile.h:335
std::vector< EventNumber_t > & unsortedEventNumbers() const
unsigned int value() const
Definition: StreamID.h:42
static constexpr EntryNumber_t invalidEntry
ForwardSequence::const_iterator find_in_all(ForwardSequence const &s, Datum const &d)
wrappers for std::find
Definition: Algorithms.h:26
std::shared_ptr< ProductRegistry const > productRegistry_
Definition: RootFile.h:343
void setIfFastClonable(int remainingEvents, int remainingLumis)
Definition: RootFile.cc:667
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2174
MergeableRunProductMetadata * mergeableRunProductMetadata()
Definition: RunPrincipal.h:78
void fillBranchEntry(TBranch *branch, T *&pbuf)
Definition: RootTree.h:158
static constexpr LuminosityBlockNumber_t invalidLumi
IndexIntoFileItr findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const
std::map< EntryDescriptionID, EventEntryDescription > EntryDescriptionMap
Definition: RootFile.h:52
edm::propagate_const< std::shared_ptr< BranchChildren > > branchChildren_
Definition: RootFile.h:355
std::string const & parentageBranchName()
Definition: BranchType.cc:164
edm::propagate_const< std::shared_ptr< InputFile > > filePtr_
Definition: RootFile.h:317
std::shared_ptr< BranchChildren const > branchChildren() const
Definition: RootFile.h:303
double b
Definition: hdecay.h:120
LuminosityBlockNumber_t luminosityBlock() const
bool processHistorySameWithinRun() const
void fillEventHistory()
Definition: RootFile.cc:1237
ProcessHistoryID const & processHistoryID(int i) const
ProductList & productListUpdator()
void setProcessHistoryID(ProcessHistoryID const &phid)
unsigned int transitionIndex() const
void readProvenanceAsync(WaitingTask *task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > * > &writeTo) const override
Definition: RootFile.cc:2146
void readProvenanceAsync(WaitingTask *task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > * > &writeTo) const override
Definition: RootFile.cc:1950
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:1872
std::shared_ptr< std::recursive_mutex > mutex_
Definition: RootFile.cc:1874
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2164
bool isValid() const
Definition: RootTree.cc:109
~OldProvenanceReader() override
Definition: RootFile.cc:2062
std::shared_ptr< ProductProvenanceRetriever > makeProductProvenanceRetriever(unsigned int iStreamIndex)
Definition: RootFile.cc:1841
std::vector< StoredProductProvenance > StoredProductProvenanceVector
std::string const & file() const
Definition: RootFile.h:214
std::string const & productDescriptionBranchName()
Definition: BranchType.cc:174
std::string const & processConfigurationBranchName()
Definition: BranchType.cc:204
IndexIntoFile::IndexIntoFileItr indexIntoFileBegin_
Definition: RootFile.h:324
ProcessHistoryID const & processHistoryID() const
EventID const & id() const
edm::propagate_const< RunHelperBase * > runHelper_
Definition: RootFile.h:349
bool branchListIndexesUnchanged_
Definition: RootFile.h:336
void fillEventPrincipal(EventAuxiliary const &aux, ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=0)
void fillIndexIntoFile()
Definition: RootFile.cc:913
#define begin
Definition: vmac.h:32
HLT enums.
edm::propagate_const< TTree * > eventHistoryTree_
Definition: RootFile.h:351
void readLuminosityBlock_(LuminosityBlockPrincipal &lumiPrincipal)
Definition: RootFile.cc:1606
std::vector< EventEntryInfo > * pInfoVector_
Definition: RootFile.cc:2073
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2169
unsigned int const defaultNonEventCacheSize
Definition: RootTree.h:47
RootTreePtrArray treePointers_
Definition: RootFile.h:341
void fillEventNumbers() const
double a
Definition: hdecay.h:121
void initialize(ProductSelectorRules const &rules, std::vector< BranchDescription const * > const &branchDescriptions)
static int position[264][3]
Definition: ReadPGInfo.cc:509
bool perEventProductIDs() const
std::string const & BranchTypeToProductProvenanceBranchName(BranchType const &BranchType)
Definition: BranchType.cc:132
std::vector< ProcessHistoryID > & orderedProcessHistoryIDs_
Definition: RootFile.h:323
std::string const & productDependenciesBranchName()
Definition: BranchType.cc:179
void setNumberOfEvents(EntryNumber_t nevents) const
void initAssociationsFromSecondary(std::vector< BranchID > const &)
Definition: RootFile.cc:741
std::string const & thinnedAssociationsHelperBranchName()
Definition: BranchType.cc:214
std::string const & entryDescriptionIDBranchName()
Definition: BranchType.cc:151
~DummyProvenanceReader() override
Definition: RootFile.cc:2130
bool useReducedProcessHistoryID() const
edm::propagate_const< TBranch * > provBranch_
Definition: RootFile.cc:1869
std::unique_ptr< MakeProvenanceReader > makeProvenanceReaderMaker(InputType inputType)
Definition: RootFile.cc:1825
std::unique_ptr< WrapperBase > getWrapperBasePtr(void *p, int offset)
std::string const & branchIDListBranchName()
Definition: BranchType.cc:209
BranchID const & originalBranchID() const
unsigned int RunNumber_t
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:253
std::vector< ParentageID > parentageIDLookup_
Definition: RootFile.h:360
EventAuxiliary eventAux_
Definition: RootFile.h:337
void readProvenanceAsync(WaitingTask *task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > * > &writeTo) const override
Definition: RootFile.cc:2023
void fillThisEventAuxiliary()
Definition: RootFile.cc:1210
void resetTraining()
Definition: RootTree.h:192
bool setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
Definition: RootFile.cc:1624
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:99
ReducedProvenanceReader(RootTree *iRootTree, std::vector< ParentageID > const &iParentageIDLookup, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:1878
std::string const & eventHistoryTreeName()
Definition: BranchType.cc:274
static Interceptor::Registry registry("Interceptor")
RootFileEventFinder(RootTree &eventTree)
Definition: RootFile.cc:122
ParentageID const & mapParentageID(ParentageID const &phid) const
edm::propagate_const< std::shared_ptr< BranchIDListHelper > > branchIDListHelper_
Definition: RootFile.h:345
void validateFile(InputType inputType, bool usingGoToEvent)
Definition: RootFile.cc:1137
IndexIntoFile::IndexIntoFileItr indexIntoFileIter() const
Definition: RootFile.cc:735
std::string const & newBranchToOldBranch(std::string const &newBranch) const
Definition: RootFile.cc:727
void readRun(long long inputRunEntry, StoredMergeableRunProductMetadata const &inputStoredMergeableRunProductMetadata, IndexIntoFileItrHolder const &inputIndexIntoFileItr)
T first(std::pair< T, U > const &p)
std::unique_ptr< TTreeCache > trainCache(TTree *tree, InputFile &file, unsigned int cacheSize, char const *branchNames)
Definition: RootTree.cc:515
static ParentageRegistry * instance()
OldProvenanceReader(RootTree *rootTree, EntryDescriptionMap const &theMap, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:2080
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:1875
IndexIntoFileItr findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
unsigned int const defaultLearningEntries
Definition: RootTree.h:48
std::vector< EventEntryInfo > infoVector_
Definition: RootFile.cc:2072
void markBranchToBeDropped(bool dropDescendants, BranchDescription const &branch, std::set< BranchID > &branchesToDrop, std::map< BranchID, BranchID > const &droppedToKeptAlias) const
Definition: RootFile.cc:1687
LuminosityBlockNumber_t peekAheadAtLumi() const
bool hasThinnedAssociations() const
std::string const & fileIdentifierBranchName()
Definition: BranchType.cc:224
void setIsMergeable(BranchDescription &)
EventNumber_t event() const
std::string const & moduleDescriptionMapBranchName()
Definition: BranchType.cc:189
bool insertMapped(value_type const &v)
std::string const file_
Definition: RootFile.h:313
def move(src, dest)
Definition: eostools.py:511
void skipEventForward(int &phIndexOfSkippedEvent, RunNumber_t &runOfSkippedEvent, LuminosityBlockNumber_t &lumiOfSkippedEvent, EntryNumber_t &skippedEventEntry)
std::vector< EventProcessHistoryID > eventProcessHistoryIDs_
Definition: RootFile.h:328
static Registry * instance()
Definition: Registry.cc:12
std::set< ProductProvenance > readProvenance(unsigned int transitionIndex) const override
Definition: RootFile.cc:2106
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:2075
std::string createGlobalIdentifier()
Definition: event.py:1
TypeWithDict const & wrappedType() const
void copyProduct(BranchDescription const &productdesc)
void readEventHistoryTree()
Definition: RootFile.cc:1663
void fillAux(T *&pAux)
Definition: RootTree.h:142
std::set< ProductProvenance > readProvenance(unsigned int) const override
Definition: RootFile.cc:2142
void setEntryNumber(EntryNumber theEntryNumber)
Definition: RootTree.cc:201
void reportOpened(std::string const &inputType)
Definition: RootFile.cc:1192
def operate(timelog, memlog, json_f, num)
roottree::EntryNumber EntryNumber
Definition: RootTree.h:104