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 
53 
56 
57 //used for backward compatibility
62 
63 #include "Rtypes.h"
64 #include "TClass.h"
65 #include "TString.h"
66 #include "TTree.h"
67 #include "TTreeCache.h"
68 
69 #include <algorithm>
70 #include <cassert>
71 #include <list>
72 
73 namespace edm {
74 
75  // Algorithm classes for making ProvenanceReader:
77  public:
78  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
79  DaqProvenanceHelper const* daqProvenanceHelper) const override;
80  };
82  public:
83  MakeOldProvenanceReader(std::unique_ptr<EntryDescriptionMap>&& entryDescriptionMap)
84  : MakeProvenanceReader(), entryDescriptionMap_(std::move(entryDescriptionMap)) {}
85  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
86  DaqProvenanceHelper const* daqProvenanceHelper) const override;
87 
88  private:
90  };
92  public:
93  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
94  DaqProvenanceHelper const* daqProvenanceHelper) const override;
95  };
97  public:
98  MakeReducedProvenanceReader(std::vector<ParentageID> const& parentageIDLookup)
99  : parentageIDLookup_(parentageIDLookup) {}
100  std::unique_ptr<ProvenanceReaderBase> makeReader(RootTree& eventTree,
101  DaqProvenanceHelper const* daqProvenanceHelper) const override;
102 
103  private:
104  std::vector<ParentageID> const& parentageIDLookup_;
105  };
106 
107  namespace {
108  void checkReleaseVersion(std::vector<ProcessHistory> processHistoryVector, std::string const& fileName) {
109  std::string releaseVersion = getReleaseVersion();
110  releaseversion::DecomposedReleaseVersion currentRelease(releaseVersion);
111  for (auto const& ph : processHistoryVector) {
112  for (auto const& pc : ph) {
113  if (releaseversion::isEarlierRelease(currentRelease, pc.releaseVersion())) {
115  << "The release you are using, " << getReleaseVersion() << " , predates\n"
116  << "a release (" << pc.releaseVersion() << ") used in writing the input file, " << fileName << ".\n"
117  << "Forward compatibility cannot be supported.\n";
118  }
119  }
120  }
121  }
122  } // namespace
123 
124  // This is a helper class for IndexIntoFile.
126  public:
127  explicit RootFileEventFinder(RootTree& eventTree) : eventTree_(eventTree) {}
128  ~RootFileEventFinder() override {}
129 
133  EventAuxiliary eventAux;
134  EventAuxiliary* pEvAux = &eventAux;
136  eventTree_.setEntryNumber(saveEntry);
137  return eventAux.event();
138  }
139 
140  private:
142  };
143 
144  //---------------------------------------------------------------------
146  ProcessConfiguration const& processConfiguration,
147  std::string const& logicalFileName,
148  std::shared_ptr<InputFile> filePtr,
149  std::shared_ptr<EventSkipperByID> eventSkipperByID,
150  bool skipAnyEvents,
151  int remainingEvents,
152  int remainingLumis,
153  unsigned int nStreams,
154  unsigned int treeCacheSize,
155  int treeMaxVirtualSize,
157  RunHelperBase* runHelper,
158  bool noRunLumiSort,
159  bool noEventSort,
160  ProductSelectorRules const& productSelectorRules,
161  InputType inputType,
162  std::shared_ptr<BranchIDListHelper> branchIDListHelper,
163  ProcessBlockHelper* processBlockHelper,
164  std::shared_ptr<ThinnedAssociationsHelper> thinnedAssociationsHelper,
165  std::vector<BranchID> const* associationsFromSecondary,
166  std::shared_ptr<DuplicateChecker> duplicateChecker,
167  bool dropDescendants,
168  ProcessHistoryRegistry& processHistoryRegistry,
169  std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
170  std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile,
171  std::vector<ProcessHistoryID>& orderedProcessHistoryIDs,
172  bool bypassVersionCheck,
173  bool labelRawDataLikeMC,
174  bool usingGoToEvent,
175  bool enablePrefetching,
176  bool enforceGUIDInFileName)
177  : file_(fileName),
178  logicalFile_(logicalFileName),
179  processConfiguration_(processConfiguration),
180  processHistoryRegistry_(&processHistoryRegistry),
181  filePtr_(filePtr),
182  eventSkipperByID_(eventSkipperByID),
183  fileFormatVersion_(),
184  fid_(),
185  indexIntoFileSharedPtr_(new IndexIntoFile),
186  indexIntoFile_(*indexIntoFileSharedPtr_),
187  orderedProcessHistoryIDs_(orderedProcessHistoryIDs),
188  indexIntoFileBegin_(indexIntoFile_.begin(
189  noRunLumiSort ? IndexIntoFile::entryOrder
190  : (noEventSort ? IndexIntoFile::firstAppearanceOrder : IndexIntoFile::numericalOrder))),
191  indexIntoFileEnd_(indexIntoFileBegin_),
192  indexIntoFileIter_(indexIntoFileBegin_),
193  storedMergeableRunProductMetadata_((inputType == InputType::Primary) ? new StoredMergeableRunProductMetadata
194  : nullptr),
195  eventProcessHistoryIDs_(),
196  eventProcessHistoryIter_(eventProcessHistoryIDs_.begin()),
197  savedRunAuxiliary_(),
198  skipAnyEvents_(skipAnyEvents),
199  noRunLumiSort_(noRunLumiSort),
200  noEventSort_(noEventSort),
201  enforceGUIDInFileName_(enforceGUIDInFileName),
202  whyNotFastClonable_(0),
203  hasNewlyDroppedBranch_(),
204  branchListIndexesUnchanged_(false),
205  eventAuxCache_(),
206  eventTree_(filePtr,
207  InEvent,
208  nStreams,
209  treeMaxVirtualSize,
210  treeCacheSize,
211  roottree::defaultLearningEntries,
212  enablePrefetching,
213  inputType),
214  lumiTree_(filePtr,
215  InLumi,
216  1,
217  treeMaxVirtualSize,
218  roottree::defaultNonEventCacheSize,
220  enablePrefetching,
221  inputType),
222  runTree_(filePtr,
223  InRun,
224  1,
225  treeMaxVirtualSize,
226  roottree::defaultNonEventCacheSize,
228  enablePrefetching,
229  inputType),
230  treePointers_(),
231  lastEventEntryNumberRead_(IndexIntoFile::invalidEntry),
232  productRegistry_(),
233  branchIDLists_(),
234  branchIDListHelper_(branchIDListHelper),
235  processBlockHelper_(processBlockHelper),
236  fileThinnedAssociationsHelper_(),
237  thinnedAssociationsHelper_(thinnedAssociationsHelper),
238  processingMode_(processingMode),
239  runHelper_(runHelper),
240  newBranchToOldBranch_(),
241  eventHistoryTree_(nullptr),
242  eventToProcessBlockIndexesBranch_(
243  inputType == InputType::Primary
244  ? eventTree_.tree()->GetBranch(poolNames::eventToProcessBlockIndexesBranchName().c_str())
245  : nullptr),
246  history_(),
247  branchChildren_(new BranchChildren),
248  duplicateChecker_(duplicateChecker),
249  provenanceAdaptor_(),
250  provenanceReaderMaker_(),
251  eventProductProvenanceRetrievers_(),
252  parentageIDLookup_(),
253  daqProvenanceHelper_(),
254  edProductClass_(TypeWithDict::byName("edm::WrapperBase").getClass()),
255  inputType_(inputType) {
256  hasNewlyDroppedBranch_.fill(false);
257 
258  treePointers_.resize(3);
262 
263  // Read the metadata tree.
264  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
265  std::unique_ptr<TTree> metaDataTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::metaDataTreeName().c_str())));
266  if (nullptr == metaDataTree.get()) {
268  << "Could not find tree " << poolNames::metaDataTreeName() << " in the input file.\n";
269  }
270 
271  // To keep things simple, we just read in every possible branch that exists.
272  // We don't pay attention to which branches exist in which file format versions
273 
275  if (metaDataTree->FindBranch(poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
276  TBranch* fft = metaDataTree->GetBranch(poolNames::fileFormatVersionBranchName().c_str());
277  fft->SetAddress(&fftPtr);
278  roottree::getEntry(fft, 0);
279  metaDataTree->SetBranchAddress(poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
280  }
281 
282  FileID* fidPtr = &fid_;
283  if (metaDataTree->FindBranch(poolNames::fileIdentifierBranchName().c_str()) != nullptr) {
284  metaDataTree->SetBranchAddress(poolNames::fileIdentifierBranchName().c_str(), &fidPtr);
285  }
286 
287  IndexIntoFile* iifPtr = &indexIntoFile_;
288  if (metaDataTree->FindBranch(poolNames::indexIntoFileBranchName().c_str()) != nullptr) {
289  metaDataTree->SetBranchAddress(poolNames::indexIntoFileBranchName().c_str(), &iifPtr);
290  }
291 
292  storedProcessBlockHelper_ = std::make_unique<StoredProcessBlockHelper>();
293  StoredProcessBlockHelper& storedProcessBlockHelper = *storedProcessBlockHelper_;
294  StoredProcessBlockHelper* pStoredProcessBlockHelper = storedProcessBlockHelper_.get();
295  if (inputType == InputType::Primary) {
296  if (metaDataTree->FindBranch(poolNames::processBlockHelperBranchName().c_str()) != nullptr) {
297  metaDataTree->SetBranchAddress(poolNames::processBlockHelperBranchName().c_str(), &pStoredProcessBlockHelper);
298  }
299  }
300 
301  StoredMergeableRunProductMetadata* smrc = nullptr;
302  if (inputType == InputType::Primary) {
304  if (metaDataTree->FindBranch(poolNames::mergeableRunProductMetadataBranchName().c_str()) != nullptr) {
305  metaDataTree->SetBranchAddress(poolNames::mergeableRunProductMetadataBranchName().c_str(), &smrc);
306  }
307  }
308 
309  // Need to read to a temporary registry so we can do a translation of the BranchKeys.
310  // This preserves backward compatibility against friendly class name algorithm changes.
311  ProductRegistry inputProdDescReg;
312  ProductRegistry* ppReg = &inputProdDescReg;
313  metaDataTree->SetBranchAddress(poolNames::productDescriptionBranchName().c_str(), (&ppReg));
314 
315  using PsetMap = std::map<ParameterSetID, ParameterSetBlob>;
316  PsetMap psetMap;
317  PsetMap* psetMapPtr = &psetMap;
318  if (metaDataTree->FindBranch(poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
319  //backward compatibility
320  assert(!fileFormatVersion().parameterSetsTree());
321  metaDataTree->SetBranchAddress(poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
322  } else {
323  assert(fileFormatVersion().parameterSetsTree());
324  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
325  std::unique_ptr<TTree> psetTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parameterSetsTreeName().c_str())));
326  if (nullptr == psetTree.get()) {
328  << "Could not find tree " << poolNames::parameterSetsTreeName() << " in the input file.\n";
329  }
330 
331  using IdToBlobs = std::pair<ParameterSetID, ParameterSetBlob>;
332  IdToBlobs idToBlob;
333  IdToBlobs* pIdToBlob = &idToBlob;
334  psetTree->SetBranchAddress(poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
335 
336  std::unique_ptr<TTreeCache> psetTreeCache =
338  psetTreeCache->SetEnablePrefetching(false);
339  filePtr_->SetCacheRead(psetTreeCache.get());
340  for (Long64_t i = 0; i != psetTree->GetEntries(); ++i) {
341  psetTree->GetEntry(i);
342  psetMap.insert(idToBlob);
343  }
344  filePtr_->SetCacheRead(nullptr);
345  }
346 
347  // backward compatibility
349  ProcessHistoryRegistry::collection_type* pHistMapPtr = &pHistMap;
350  if (metaDataTree->FindBranch(poolNames::processHistoryMapBranchName().c_str()) != nullptr) {
351  metaDataTree->SetBranchAddress(poolNames::processHistoryMapBranchName().c_str(), &pHistMapPtr);
352  }
353 
355  ProcessHistoryRegistry::vector_type* pHistVectorPtr = &pHistVector;
356  if (metaDataTree->FindBranch(poolNames::processHistoryBranchName().c_str()) != nullptr) {
357  metaDataTree->SetBranchAddress(poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
358  }
359 
360  // backward compatibility
361  ProcessConfigurationVector processConfigurations;
362  ProcessConfigurationVector* procConfigVectorPtr = &processConfigurations;
363  if (metaDataTree->FindBranch(poolNames::processConfigurationBranchName().c_str()) != nullptr) {
364  metaDataTree->SetBranchAddress(poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
365  }
366 
367  auto branchIDListsAPtr = std::make_unique<BranchIDLists>();
368  BranchIDLists* branchIDListsPtr = branchIDListsAPtr.get();
369  if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) != nullptr) {
370  metaDataTree->SetBranchAddress(poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
371  }
372 
373  ThinnedAssociationsHelper* thinnedAssociationsHelperPtr; // must remain in scope through getEntry()
374  if (inputType != InputType::SecondarySource) {
376  std::make_unique<ThinnedAssociationsHelper>(); // propagate_const<T> has no reset() function
377  thinnedAssociationsHelperPtr = fileThinnedAssociationsHelper_.get();
378  if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) != nullptr) {
379  metaDataTree->SetBranchAddress(poolNames::thinnedAssociationsHelperBranchName().c_str(),
380  &thinnedAssociationsHelperPtr);
381  }
382  }
383 
384  BranchChildren* branchChildrenBuffer = branchChildren_.get();
385  if (metaDataTree->FindBranch(poolNames::productDependenciesBranchName().c_str()) != nullptr) {
386  metaDataTree->SetBranchAddress(poolNames::productDependenciesBranchName().c_str(), &branchChildrenBuffer);
387  }
388 
389  // backward compatibility
390  std::vector<EventProcessHistoryID>* eventHistoryIDsPtr = &eventProcessHistoryIDs_;
391  if (metaDataTree->FindBranch(poolNames::eventHistoryBranchName().c_str()) != nullptr) {
392  metaDataTree->SetBranchAddress(poolNames::eventHistoryBranchName().c_str(), &eventHistoryIDsPtr);
393  }
394 
395  if (metaDataTree->FindBranch(poolNames::moduleDescriptionMapBranchName().c_str()) != nullptr) {
396  if (metaDataTree->GetBranch(poolNames::moduleDescriptionMapBranchName().c_str())->GetSplitLevel() != 0) {
397  metaDataTree->SetBranchStatus((poolNames::moduleDescriptionMapBranchName() + ".*").c_str(), false);
398  } else {
399  metaDataTree->SetBranchStatus(poolNames::moduleDescriptionMapBranchName().c_str(), false);
400  }
401  }
402 
403  // Here we read the metadata tree
404  roottree::getEntry(metaDataTree.get(), 0);
405 
407 
408  // Here we read the event history tree, if we have one.
410 
412  if (!fileFormatVersion().triggerPathsTracked()) {
413  ParameterSetConverter converter(psetMap, psetIdConverter, fileFormatVersion().parameterSetsByReference());
414  } else {
415  // Merge into the parameter set registry.
416  pset::Registry& psetRegistry = *pset::Registry::instance();
417  for (auto const& psetEntry : psetMap) {
418  ParameterSet pset(psetEntry.second.pset());
419  pset.setID(psetEntry.first);
420  // For thread safety, don't update global registries when a secondary source opens a file.
421  if (inputType != InputType::SecondarySource) {
422  psetRegistry.insertMapped(pset);
423  }
424  }
425  }
426  if (!fileFormatVersion().splitProductIDs()) {
427  // Old provenance format input file. Create a provenance adaptor.
428  // propagate_const<T> has no reset() function
429  provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
430  inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, true);
431  // Fill in the branchIDLists branch from the provenance adaptor
432  branchIDLists_ = provenanceAdaptor_->branchIDLists();
433  } else {
434  if (!fileFormatVersion().triggerPathsTracked()) {
435  // New provenance format, but change in ParameterSet Format. Create a provenance adaptor.
436  // propagate_const<T> has no reset() function
437  provenanceAdaptor_ = std::make_unique<ProvenanceAdaptor>(
438  inputProdDescReg, pHistMap, pHistVector, processConfigurations, psetIdConverter, false);
439  }
440  // New provenance format input file. The branchIDLists branch was read directly from the input file.
441  if (metaDataTree->FindBranch(poolNames::branchIDListBranchName().c_str()) == nullptr) {
442  throw Exception(errors::EventCorruption) << "Failed to find branchIDLists branch in metaData tree.\n";
443  }
444  branchIDLists_.reset(branchIDListsAPtr.release());
445  }
446 
448  if (metaDataTree->FindBranch(poolNames::thinnedAssociationsHelperBranchName().c_str()) == nullptr) {
450  << "Failed to find thinnedAssociationsHelper branch in metaData tree.\n";
451  }
452  }
453 
454  if (!bypassVersionCheck) {
455  checkReleaseVersion(pHistVector, file());
456  }
457 
458  if (labelRawDataLikeMC) {
459  std::string const rawData("FEDRawDataCollection");
460  std::string const source("source");
461  ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
462  BranchKey finder(rawData, source, "", "");
463  ProductRegistry::ProductList::iterator it = pList.lower_bound(finder);
464  if (it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source) {
465  // We found raw data with a module label of source.
466  // We need to change the module label and process name.
467  // Create helper.
468  it->second.init();
469  // propagate_const<T> has no reset() function
470  daqProvenanceHelper_ = std::make_unique<DaqProvenanceHelper>(it->second.unwrappedTypeID());
471  // Create the new branch description
472  BranchDescription const& newBD = daqProvenanceHelper_->branchDescription();
473  // Save info from the old and new branch descriptions
474  daqProvenanceHelper_->saveInfo(it->second, newBD);
475  // Map the new branch name to the old branch name.
476  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), it->second.branchName()));
477  // Remove the old branch description from the product Registry.
478  pList.erase(it);
479  // Check that there was only one.
480  it = pList.lower_bound(finder);
481  assert(!(it != pList.end() && it->first.friendlyClassName() == rawData && it->first.moduleLabel() == source));
482  // Insert the new branch description into the product registry.
483  inputProdDescReg.copyProduct(newBD);
484  // Fix up other per file metadata.
485  daqProvenanceHelper_->fixMetaData(processConfigurations, pHistVector);
486  daqProvenanceHelper_->fixMetaData(*branchIDLists_);
487  daqProvenanceHelper_->fixMetaData(*branchChildren_);
488  }
489  }
490 
491  for (auto const& history : pHistVector) {
492  processHistoryRegistry.registerProcessHistory(history);
493  }
494 
496 
497  // Update the branch id info. This has to be done before validateFile since
498  // depending on the file format, the branchIDListHelper_ may have its fixBranchListIndexes call made
499  if (inputType == InputType::Primary) {
501  }
502 
503  validateFile(inputType, usingGoToEvent);
504 
505  // Here, we make the class that will make the ProvenanceReader
506  // It reads whatever trees it needs.
507  // propagate_const<T> has no reset() function
508  provenanceReaderMaker_ = std::unique_ptr<MakeProvenanceReader>(makeProvenanceReaderMaker(inputType).release());
509 
510  // Merge into the hashed registries.
511  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
513  }
514 
515  initializeDuplicateChecker(indexesIntoFiles, currentIndexIntoFile);
517  noRunLumiSort ? IndexIntoFile::entryOrder
520  noRunLumiSort ? IndexIntoFile::entryOrder
524 
525  makeProcessBlockRootTrees(filePtr, treeMaxVirtualSize, enablePrefetching, inputType, storedProcessBlockHelper);
526 
527  setPresenceInProductRegistry(inputProdDescReg, storedProcessBlockHelper);
528 
529  auto newReg = std::make_unique<ProductRegistry>();
530 
531  // Do the translation from the old registry to the new one
532  {
533  ProductRegistry::ProductList const& prodList = inputProdDescReg.productList();
534  for (auto const& product : prodList) {
535  BranchDescription const& prod = product.second;
536  std::string newFriendlyName = friendlyname::friendlyName(prod.className());
537  if (newFriendlyName == prod.friendlyClassName()) {
538  newReg->copyProduct(prod);
539  } else {
540  if (fileFormatVersion().splitProductIDs()) {
542  << "Cannot change friendly class name algorithm without more development work\n"
543  << "to update BranchIDLists and ThinnedAssociationsHelper. Contact the framework group.\n";
544  }
545  BranchDescription newBD(prod);
546  newBD.updateFriendlyClassName();
547  newReg->copyProduct(newBD);
548  newBranchToOldBranch_.insert(std::make_pair(newBD.branchName(), prod.branchName()));
549  }
550  }
551 
553  *newReg, productSelectorRules, dropDescendants, inputType, storedProcessBlockHelper, processBlockHelper);
554 
555  if (inputType == InputType::SecondaryFile) {
556  thinnedAssociationsHelper->updateFromSecondaryInput(*fileThinnedAssociationsHelper_,
557  *associationsFromSecondary);
558  } else if (inputType == InputType::Primary) {
559  processBlockHelper->initializeFromPrimaryInput(storedProcessBlockHelper);
560  thinnedAssociationsHelper->updateFromPrimaryInput(*fileThinnedAssociationsHelper_);
561  }
562 
563  if (inputType == InputType::Primary) {
564  for (auto& product : newReg->productListUpdator()) {
565  setIsMergeable(product.second);
566  }
567  }
568  //inform system we want to use DelayedReader
569  for (auto& product : newReg->productListUpdator()) {
570  product.second.setOnDemand(true);
571  }
572 
573  for (auto& processBlockTree : processBlockTrees_) {
574  treePointers_.push_back(processBlockTree.get());
575  }
576 
577  // freeze the product registry
578  newReg->setFrozen(inputType != InputType::Primary);
579  productRegistry_.reset(newReg.release());
580  }
581 
582  // Set up information from the product registry.
583  ProductRegistry::ProductList const& prodList = productRegistry()->productList();
584 
585  {
586  std::vector<size_t> nBranches(treePointers_.size(), 0);
587  for (auto const& product : prodList) {
588  if (product.second.branchType() == InProcess) {
589  std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
590  auto it = std::find(processes.begin(), processes.end(), product.second.processName());
591  if (it != processes.end()) {
592  auto index = std::distance(processes.begin(), it);
594  }
595  } else {
596  ++nBranches[product.second.branchType()];
597  }
598  }
599 
600  int i = 0;
601  for (auto& t : treePointers_) {
602  t->numberOfBranchesToAdd(nBranches[i]);
603  ++i;
604  }
605  }
606  for (auto const& product : prodList) {
607  BranchDescription const& prod = product.second;
608  if (prod.branchType() == InProcess) {
609  std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
610  auto it = std::find(processes.begin(), processes.end(), prod.processName());
611  if (it != processes.end()) {
612  auto index = std::distance(processes.begin(), it);
614  newBranchToOldBranch(prod.branchName()));
615  }
616  } else {
617  treePointers_[prod.branchType()]->addBranch(prod, newBranchToOldBranch(prod.branchName()));
618  }
619  }
620 
621  // Determine if this file is fast clonable.
622  setIfFastClonable(remainingEvents, remainingLumis);
623 
624  // We are done with our initial reading of EventAuxiliary.
626 
627  // Tell the event tree to begin training at the next read.
629 
630  // Train the run and lumi trees.
631  runTree_.trainCache("*");
632  lumiTree_.trainCache("*");
633  for (auto& processBlockTree : processBlockTrees_) {
634  processBlockTree->trainCache("*");
635  }
636  }
637 
639 
640  void RootFile::readEntryDescriptionTree(EntryDescriptionMap& entryDescriptionMap, InputType inputType) {
641  // Called only for old format files.
642  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
643  std::unique_ptr<TTree> entryDescriptionTree(
644  dynamic_cast<TTree*>(filePtr_->Get(poolNames::entryDescriptionTreeName().c_str())));
645  if (nullptr == entryDescriptionTree.get()) {
647  << "Could not find tree " << poolNames::entryDescriptionTreeName() << " in the input file.\n";
648  }
649 
650  EntryDescriptionID idBuffer;
651  EntryDescriptionID* pidBuffer = &idBuffer;
652  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), &pidBuffer);
653 
654  EventEntryDescription entryDescriptionBuffer;
655  EventEntryDescription* pEntryDescriptionBuffer = &entryDescriptionBuffer;
656  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), &pEntryDescriptionBuffer);
657 
658  // Fill in the parentage registry.
660 
661  for (Long64_t i = 0, numEntries = entryDescriptionTree->GetEntries(); i < numEntries; ++i) {
662  roottree::getEntry(entryDescriptionTree.get(), i);
663  if (idBuffer != entryDescriptionBuffer.id()) {
664  throw Exception(errors::EventCorruption) << "Corruption of EntryDescription tree detected.\n";
665  }
666  entryDescriptionMap.insert(std::make_pair(entryDescriptionBuffer.id(), entryDescriptionBuffer));
668  parents.setParents(entryDescriptionBuffer.parents());
669  if (daqProvenanceHelper_) {
670  ParentageID const oldID = parents.id();
671  daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
672  ParentageID newID = parents.id();
673  if (newID != oldID) {
674  daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
675  }
676  }
677  // For thread safety, don't update global registries when a secondary source opens a file.
678  if (inputType != InputType::SecondarySource) {
679  registry.insertMapped(parents);
680  }
681  }
682  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionIDBranchName().c_str(), nullptr);
683  entryDescriptionTree->SetBranchAddress(poolNames::entryDescriptionBranchName().c_str(), nullptr);
684  }
685 
687  // New format file
688  // We use a smart pointer so the tree will be deleted after use, and not kept for the life of the file.
689  std::unique_ptr<TTree> parentageTree(dynamic_cast<TTree*>(filePtr_->Get(poolNames::parentageTreeName().c_str())));
690  if (nullptr == parentageTree.get()) {
692  << "Could not find tree " << poolNames::parentageTreeName() << " in the input file.\n";
693  }
694 
696  Parentage* pParentageBuffer = &parents;
697  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), &pParentageBuffer);
698 
700 
701  parentageIDLookup_.reserve(parentageTree->GetEntries());
702  for (Long64_t i = 0, numEntries = parentageTree->GetEntries(); i < numEntries; ++i) {
703  roottree::getEntry(parentageTree.get(), i);
704  if (daqProvenanceHelper_) {
705  ParentageID const oldID = parents.id();
706  daqProvenanceHelper_->fixMetaData(parents.parentsForUpdate());
707  ParentageID newID = parents.id();
708  if (newID != oldID) {
709  daqProvenanceHelper_->setOldParentageIDToNew(oldID, newID);
710  }
711  }
712  // For thread safety, don't update global registries when a secondary source opens a file.
713  if (inputType != InputType::SecondarySource) {
714  registry.insertMapped(parents);
715  }
716  parentageIDLookup_.push_back(parents.id());
717  }
718  parentageTree->SetBranchAddress(poolNames::parentageBranchName().c_str(), nullptr);
719  }
720 
721  void RootFile::setIfFastClonable(int remainingEvents, int remainingLumis) {
722  if (fileFormatVersion().noMetaDataTrees() and !fileFormatVersion().storedProductProvenanceUsed()) {
723  //we must avoid copying the old branch which stored the per product per event provenance
725  return;
726  }
727  if (!fileFormatVersion().splitProductIDs()) {
729  return;
730  }
733  return;
734  }
735  // Find entry for first event in file
737  while (it != indexIntoFileEnd_ && it.getEntryType() != IndexIntoFile::kEvent) {
738  ++it;
739  }
740  if (it == indexIntoFileEnd_) {
742  return;
743  }
744 
745  // From here on, record all reasons we can't fast clone.
746  IndexIntoFile::SortOrder sortOrder =
751  }
752  if (skipAnyEvents_) {
754  }
755  if (remainingEvents >= 0 && eventTree_.entries() > remainingEvents) {
757  }
758  if (remainingLumis >= 0 && lumiTree_.entries() > remainingLumis) {
760  }
761  if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
763  }
764  }
765 
766  std::shared_ptr<FileBlock> RootFile::createFileBlock() {
767  std::vector<TTree*> processBlockTrees;
768  std::vector<std::string> processesWithProcessBlockTrees;
769  processBlockTrees.reserve(processBlockTrees_.size());
770  processesWithProcessBlockTrees.reserve(processBlockTrees_.size());
771  for (auto& processBlockTree : processBlockTrees_) {
772  processBlockTrees.push_back(processBlockTree->tree());
773  processesWithProcessBlockTrees.push_back(processBlockTree->processName());
774  }
775  return std::make_shared<FileBlock>(fileFormatVersion(),
776  eventTree_.tree(),
778  lumiTree_.tree(),
780  runTree_.tree(),
781  runTree_.metaTree(),
782  std::move(processBlockTrees),
783  std::move(processesWithProcessBlockTrees),
786  file_,
788  modifiedIDs(),
789  branchChildren());
790  }
791 
793  std::vector<TTree*> processBlockTrees;
794  std::vector<std::string> processesWithProcessBlockTrees;
795  processBlockTrees.reserve(processBlockTrees_.size());
796  processesWithProcessBlockTrees.reserve(processBlockTrees_.size());
797  for (auto& processBlockTree : processBlockTrees_) {
798  processBlockTrees.push_back(processBlockTree->tree());
799  processesWithProcessBlockTrees.push_back(processBlockTree->processName());
800  }
801  fileBlock.updateTTreePointers(eventTree_.tree(),
803  lumiTree_.tree(),
805  runTree_.tree(),
806  runTree_.metaTree(),
807  std::move(processBlockTrees),
808  std::move(processesWithProcessBlockTrees));
809  }
810 
811  std::string const& RootFile::newBranchToOldBranch(std::string const& newBranch) const {
812  std::map<std::string, std::string>::const_iterator it = newBranchToOldBranch_.find(newBranch);
813  if (it != newBranchToOldBranch_.end()) {
814  return it->second;
815  }
816  return newBranch;
817  }
818 
820 
823  }
824 
825  void RootFile::initAssociationsFromSecondary(std::vector<BranchID> const& associationsFromSecondary) {
826  thinnedAssociationsHelper_->initAssociationsFromSecondary(associationsFromSecondary,
828  }
829 
832  return false;
833  }
834 
835  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
836  // See first if the entire lumi or run is skipped, so we won't have to read the event Auxiliary in that case.
838  return true;
839  }
840 
841  // The Lumi is not skipped. If this is an event, see if the event is skipped.
843  auto eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
844  if (eventSkipperByID_->skipIt(indexIntoFileIter_.run(), indexIntoFileIter_.lumi(), eventAux.id().event())) {
845  return true;
846  }
847  }
848 
849  // Skip runs with no lumis if either lumisToSkip or lumisToProcess have been set to select lumis
851  // There are no lumis in this run, not even ones we will skip
853  return true;
854  }
855  // If we get here there are lumis in the run, check to see if we are skipping all of them
856  do {
858  return false;
859  }
860  } while (indexIntoFileIter_.skipLumiInRun());
861  return true;
862  }
863  }
864  return false;
865  }
866 
869  if (duplicateChecker_.get() == nullptr) {
870  return false;
871  }
872  auto const eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
873  return duplicateChecker_->isDuplicateAndCheckActive(indexIntoFileIter_.processHistoryIDIndex(),
876  eventAux.id().event(),
877  file_);
878  }
879 
882  }
883 
886  EventNumber_t& event) {
887  // First, account for consecutive skipped entries.
888  while (skipThisEntry()) {
893  } else {
895  }
896  }
897  // OK, we have an entry that is not skipped.
899  if (entryType == IndexIntoFile::kEnd) {
900  return IndexIntoFile::kEnd;
901  }
902  if (entryType == IndexIntoFile::kRun) {
904  runHelper_->checkForNewRun(run, indexIntoFileIter_.peekAheadAtLumi());
905  return IndexIntoFile::kRun;
906  } else if (processingMode_ == InputSource::Runs) {
908  return getNextItemType(run, lumi, event);
909  }
910  if (entryType == IndexIntoFile::kLumi) {
913  return IndexIntoFile::kLumi;
916  return getNextItemType(run, lumi, event);
917  }
918  if (isDuplicateEvent()) {
920  return getNextItemType(run, lumi, event);
921  }
924  auto eventAux = fillEventAuxiliary(indexIntoFileIter_.entry());
925  event = eventAux.event();
926  return IndexIntoFile::kEvent;
927  }
928 
931  itr.advanceToEvent();
932  return itr.getEntryType() == IndexIntoFile::kEnd;
933  }
934 
937  int phIndex;
940  IndexIntoFile::EntryNumber_t eventEntry;
941  itr.skipEventBackward(phIndex, run, lumi, eventEntry);
942  itr.skipEventBackward(phIndex, run, lumi, eventEntry);
943  return eventEntry == IndexIntoFile::invalidEntry;
944  }
945 
946  namespace {
947  struct RunItem {
948  RunItem(ProcessHistoryID const& phid, RunNumber_t const& run) : phid_(phid), run_(run) {}
949  ProcessHistoryID phid_;
950  RunNumber_t run_;
951  };
952  struct RunItemSortByRun {
953  bool operator()(RunItem const& a, RunItem const& b) const { return a.run_ < b.run_; }
954  };
955  struct RunItemSortByRunPhid {
956  bool operator()(RunItem const& a, RunItem const& b) const {
957  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.phid_ < b.phid_);
958  }
959  };
960  struct LumiItem {
961  LumiItem(ProcessHistoryID const& phid,
962  RunNumber_t const& run,
965  : phid_(phid),
966  run_(run),
967  lumi_(lumi),
968  firstEventEntry_(entry),
969  lastEventEntry_(entry == IndexIntoFile::invalidEntry ? IndexIntoFile::invalidEntry : entry + 1) {}
970  ProcessHistoryID phid_;
971  RunNumber_t run_;
973  IndexIntoFile::EntryNumber_t firstEventEntry_;
974  IndexIntoFile::EntryNumber_t lastEventEntry_;
975  };
976  struct LumiItemSortByRunLumi {
977  bool operator()(LumiItem const& a, LumiItem const& b) const {
978  return a.run_ < b.run_ || (!(b.run_ < a.run_) && a.lumi_ < b.lumi_);
979  }
980  };
981  struct LumiItemSortByRunLumiPhid {
982  bool operator()(LumiItem const& a, LumiItem const& b) const {
983  if (a.run_ < b.run_)
984  return true;
985  if (b.run_ < a.run_)
986  return false;
987  if (a.lumi_ < b.lumi_)
988  return true;
989  if (b.lumi_ < a.lumi_)
990  return false;
991  return a.phid_ < b.phid_;
992  }
993  };
994  } // namespace
995 
997  // This function is for backward compatibility.
998  // If reading a current format file, indexIntoFile_ is read from the input
999  // file and should always be there. Note that the algorithm below will work
1000  // sometimes but often fail with the new format introduced in release 3_8_0.
1001  // If it ever becomes necessary to rebuild IndexIntoFile from the new format,
1002  // probably a separate function should be written to deal with the task.
1003  // This is possible just not implemented yet.
1004  assert(!fileFormatVersion().hasIndexIntoFile());
1005 
1006  typedef std::list<LumiItem> LumiList;
1007  LumiList lumis; // (declare 1)
1008 
1009  typedef std::set<LuminosityBlockID> RunLumiSet;
1010  RunLumiSet runLumiSet; // (declare 2)
1011 
1012  typedef std::list<RunItem> RunList;
1013  RunList runs; // (declare 5)
1014 
1015  typedef std::set<RunNumber_t> RunSet;
1016  RunSet runSet; // (declare 4)
1017 
1018  typedef std::set<RunItem, RunItemSortByRunPhid> RunItemSet;
1019  RunItemSet runItemSet; // (declare 3)
1020 
1021  typedef std::map<RunNumber_t, ProcessHistoryID> PHIDMap;
1022  PHIDMap phidMap;
1023 
1024  RunNumber_t prevRun = 0;
1025  LuminosityBlockNumber_t prevLumi = 0;
1026  ProcessHistoryID prevPhid;
1027  bool iFirst = true;
1028 
1029  indexIntoFile_.unsortedEventNumbers().clear(); // should already be empty, just being careful
1031 
1032  // First, loop through the event tree.
1033  EventSelectionIDVector eventSelectionIDs;
1034  BranchListIndexes branchListIndexes;
1035  while (eventTree_.next()) {
1036  bool newRun = false;
1037  bool newLumi = false;
1038  auto evtAux = fillThisEventAuxiliary();
1039  fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes);
1040 
1041  // Save the event numbers as we loop through the event auxiliary to avoid
1042  // having to read through the event auxiliary again later. These event numbers
1043  // are not actually used in this function, but could be needed elsewhere.
1044  indexIntoFile_.unsortedEventNumbers().push_back(evtAux.event());
1045 
1046  ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(evtAux.processHistoryID());
1047 
1048  if (iFirst || prevPhid != reducedPHID || prevRun != evtAux.run()) {
1049  iFirst = false;
1050  newRun = newLumi = true;
1051  } else if (prevLumi != evtAux.luminosityBlock()) {
1052  newLumi = true;
1053  }
1054  prevPhid = reducedPHID;
1055  prevRun = evtAux.run();
1056  prevLumi = evtAux.luminosityBlock();
1057  if (newLumi) {
1058  lumis.emplace_back(
1059  reducedPHID, evtAux.run(), evtAux.luminosityBlock(), eventTree_.entryNumber()); // (insert 1)
1060  runLumiSet.insert(LuminosityBlockID(evtAux.run(), evtAux.luminosityBlock())); // (insert 2)
1061  } else {
1062  LumiItem& currentLumi = lumis.back();
1063  assert(currentLumi.lastEventEntry_ == eventTree_.entryNumber());
1064  ++currentLumi.lastEventEntry_;
1065  }
1066  if (newRun) {
1067  // Insert run in list if it is not already there.
1068  RunItem item(reducedPHID, evtAux.run());
1069  if (runItemSet.insert(item).second) { // (check 3, insert 3)
1070  runs.push_back(std::move(item)); // (insert 5)
1071  runSet.insert(evtAux.run()); // (insert 4)
1072  phidMap.insert(std::make_pair(evtAux.run(), reducedPHID));
1073  }
1074  }
1075  }
1076  // now clean up.
1079 
1080  // Loop over run entries and fill information.
1081 
1082  typedef std::map<RunNumber_t, IndexIntoFile::EntryNumber_t> RunMap;
1083  RunMap runMap; // (declare 11)
1084 
1085  typedef std::vector<RunItem> RunVector;
1086  RunVector emptyRuns; // (declare 12)
1087 
1088  if (runTree_.isValid()) {
1089  while (runTree_.next()) {
1090  // Note: adjacent duplicates will be skipped without an explicit check.
1091 
1092  std::shared_ptr<RunAuxiliary> runAux = fillRunAuxiliary();
1093  ProcessHistoryID reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(runAux->processHistoryID());
1094 
1095  if (runSet.insert(runAux->run()).second) { // (check 4, insert 4)
1096  // This run was not associated with any events.
1097  emptyRuns.emplace_back(reducedPHID, runAux->run()); // (insert 12)
1098  }
1099  runMap.insert(std::make_pair(runAux->run(), runTree_.entryNumber())); // (insert 11)
1100  phidMap.insert(std::make_pair(runAux->run(), reducedPHID));
1101  }
1102  // now clean up.
1104  }
1105 
1106  // Insert the ordered empty runs into the run list.
1107  RunItemSortByRun runItemSortByRun;
1108  stable_sort_all(emptyRuns, runItemSortByRun);
1109 
1110  RunList::iterator itRuns = runs.begin(), endRuns = runs.end();
1111  for (auto const& emptyRun : emptyRuns) {
1112  for (; itRuns != endRuns; ++itRuns) {
1113  if (runItemSortByRun(emptyRun, *itRuns)) {
1114  break;
1115  }
1116  }
1117  runs.insert(itRuns, emptyRun);
1118  }
1119 
1120  // Loop over luminosity block entries and fill information.
1121 
1122  typedef std::vector<LumiItem> LumiVector;
1123  LumiVector emptyLumis; // (declare 7)
1124 
1125  typedef std::map<LuminosityBlockID, IndexIntoFile::EntryNumber_t> RunLumiMap;
1126  RunLumiMap runLumiMap; // (declare 6)
1127 
1128  if (lumiTree_.isValid()) {
1129  while (lumiTree_.next()) {
1130  // Note: adjacent duplicates will be skipped without an explicit check.
1131  std::shared_ptr<LuminosityBlockAuxiliary> lumiAux = fillLumiAuxiliary();
1132  LuminosityBlockID lumiID = LuminosityBlockID(lumiAux->run(), lumiAux->luminosityBlock());
1133  if (runLumiSet.insert(lumiID).second) { // (check 2, insert 2)
1134  // This lumi was not associated with any events.
1135  // Use the process history ID from the corresponding run. In cases of practical
1136  // importance, this should be the correct process history ID, but it is possible
1137  // to construct files where this is not the correct process history ID ...
1138  PHIDMap::const_iterator iPhidMap = phidMap.find(lumiAux->run());
1139  assert(iPhidMap != phidMap.end());
1140  emptyLumis.emplace_back(
1141  iPhidMap->second, lumiAux->run(), lumiAux->luminosityBlock(), IndexIntoFile::invalidEntry); // (insert 7)
1142  }
1143  runLumiMap.insert(std::make_pair(lumiID, lumiTree_.entryNumber()));
1144  }
1145  // now clean up.
1147  }
1148 
1149  // Insert the ordered empty lumis into the lumi list.
1150  LumiItemSortByRunLumi lumiItemSortByRunLumi;
1151  stable_sort_all(emptyLumis, lumiItemSortByRunLumi);
1152 
1153  LumiList::iterator itLumis = lumis.begin(), endLumis = lumis.end();
1154  for (auto const& emptyLumi : emptyLumis) {
1155  for (; itLumis != endLumis; ++itLumis) {
1156  if (lumiItemSortByRunLumi(emptyLumi, *itLumis)) {
1157  break;
1158  }
1159  }
1160  lumis.insert(itLumis, emptyLumi);
1161  }
1162 
1163  // Create a map of RunItems that gives the order of first appearance in the list.
1164  // Also fill in the vector of process history IDs
1165  typedef std::map<RunItem, int, RunItemSortByRunPhid> RunCountMap;
1166  RunCountMap runCountMap; // Declare (17)
1167  std::vector<ProcessHistoryID>& phids = indexIntoFile_.setProcessHistoryIDs();
1168  assert(phids.empty());
1169  std::vector<IndexIntoFile::RunOrLumiEntry>& entries = indexIntoFile_.setRunOrLumiEntries();
1170  assert(entries.empty());
1171  int rcount = 0;
1172  for (auto& run : runs) {
1173  RunCountMap::const_iterator countMapItem = runCountMap.find(run);
1174  if (countMapItem == runCountMap.end()) {
1175  countMapItem = runCountMap.insert(std::make_pair(run, rcount)).first; // Insert (17)
1176  assert(countMapItem != runCountMap.end());
1177  ++rcount;
1178  }
1179  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, run.phid_);
1180  if (phidItem == phids.end()) {
1181  phids.push_back(run.phid_);
1182  phidItem = phids.end() - 1;
1183  }
1184  entries.emplace_back(countMapItem->second, // use (17)
1186  runMap[run.run_], // use (11)
1187  phidItem - phids.begin(),
1188  run.run_,
1189  0U,
1192  }
1193 
1194  // Create a map of LumiItems that gives the order of first appearance in the list.
1195  typedef std::map<LumiItem, int, LumiItemSortByRunLumiPhid> LumiCountMap;
1196  LumiCountMap lumiCountMap; // Declare (19)
1197  int lcount = 0;
1198  for (auto& lumi : lumis) {
1199  RunCountMap::const_iterator runCountMapItem = runCountMap.find(RunItem(lumi.phid_, lumi.run_));
1200  assert(runCountMapItem != runCountMap.end());
1201  LumiCountMap::const_iterator countMapItem = lumiCountMap.find(lumi);
1202  if (countMapItem == lumiCountMap.end()) {
1203  countMapItem = lumiCountMap.insert(std::make_pair(lumi, lcount)).first; // Insert (17)
1204  assert(countMapItem != lumiCountMap.end());
1205  ++lcount;
1206  }
1207  std::vector<ProcessHistoryID>::const_iterator phidItem = find_in_all(phids, lumi.phid_);
1208  assert(phidItem != phids.end());
1209  entries.emplace_back(runCountMapItem->second,
1210  countMapItem->second,
1211  runLumiMap[LuminosityBlockID(lumi.run_, lumi.lumi_)],
1212  phidItem - phids.begin(),
1213  lumi.run_,
1214  lumi.lumi_,
1215  lumi.firstEventEntry_,
1216  lumi.lastEventEntry_);
1217  }
1218  stable_sort_all(entries);
1219  }
1220 
1221  void RootFile::validateFile(InputType inputType, bool usingGoToEvent) {
1222  if (!fid_.isValid()) {
1224  }
1225  if (!eventTree_.isValid()) {
1226  throw Exception(errors::EventCorruption) << "'Events' tree is corrupted or not present\n"
1227  << "in the input file.\n";
1228  }
1229  if (enforceGUIDInFileName_) {
1230  auto guidFromName = stemFromPath(file_);
1231  if (guidFromName != fid_.fid()) {
1233  << "GUID " << guidFromName << " extracted from file name " << file_
1234  << " is inconsistent with the GUID read from the file " << fid_.fid();
1235  }
1236  }
1237 
1238  if (fileFormatVersion().hasIndexIntoFile()) {
1239  if (runTree().entries() > 0) {
1241  }
1243  if (daqProvenanceHelper_) {
1244  std::vector<ProcessHistoryID>& phidVec = indexIntoFile_.setProcessHistoryIDs();
1245  for (auto& phid : phidVec) {
1246  phid = daqProvenanceHelper_->mapProcessHistoryID(phid);
1247  }
1248  }
1250  }
1251  } else {
1254  }
1255 
1259  std::shared_ptr<IndexIntoFile::EventFinder>(std::make_shared<RootFileEventFinder>(eventTree_)));
1260  // We fill the event numbers explicitly if we need to find events in closed files,
1261  // such as for secondary files (or secondary sources) or if duplicate checking across files.
1262  bool needEventNumbers = false;
1263  bool needIndexesForDuplicateChecker =
1264  duplicateChecker_ && duplicateChecker_->checkingAllFiles() && !duplicateChecker_->checkDisabled();
1265  if (inputType != InputType::Primary || needIndexesForDuplicateChecker || usingGoToEvent) {
1266  needEventNumbers = true;
1267  }
1268  bool needEventEntries = false;
1269  if (inputType != InputType::Primary || !noEventSort_) {
1270  // We need event entries for sorting or for secondary files or sources.
1271  needEventEntries = true;
1272  }
1273  indexIntoFile_.fillEventNumbersOrEntries(needEventNumbers, needEventEntries);
1274  }
1275 
1276  void RootFile::reportOpened(std::string const& inputType) {
1277  // Report file opened.
1278  std::string const label = "source";
1279  std::string moduleName = "PoolSource";
1280  filePtr_->inputFileOpened(logicalFile_, inputType, moduleName, label, fid_.fid(), eventTree_.branchNames());
1281  }
1282 
1284  // Just to play it safe, zero all pointers to objects in the InputFile to be closed.
1285  eventHistoryTree_ = nullptr;
1286  for (auto& treePointer : treePointers_) {
1287  treePointer->close();
1288  treePointer = nullptr;
1289  }
1290  filePtr_->Close();
1291  filePtr_ = nullptr; // propagate_const<T> has no reset() function
1292  }
1293 
1296  // Already read.
1297  return eventAuxCache_;
1298  }
1299  if (fileFormatVersion().newAuxiliary()) {
1300  EventAuxiliary* pEvAux = &eventAuxCache_;
1302  } else {
1303  // for backward compatibility.
1304  EventAux eventAux;
1305  EventAux* pEvAux = &eventAux;
1306  eventTree_.fillAux<EventAux>(pEvAux);
1307  conversion(eventAux, eventAuxCache_);
1308  }
1310  return eventAuxCache_;
1311  }
1312 
1315  return fillThisEventAuxiliary();
1316  }
1317 
1319  TBranch* eventToProcessBlockIndexesBranch = get_underlying_safe(eventToProcessBlockIndexesBranch_);
1320  if (eventToProcessBlockIndexesBranch == nullptr) {
1321  if (processBlockHelper_.get() == nullptr) {
1323  } else {
1325  }
1326  } else {
1327  if (processBlockHelper_->cacheIndexVectorsPerFile().back() == 1u) {
1329  } else {
1330  EventToProcessBlockIndexes* pEventToProcessBlockIndexes = &eventToProcessBlockIndexes_;
1331  eventTree_.fillBranchEntry(eventToProcessBlockIndexesBranch, pEventToProcessBlockIndexes);
1332  unsigned int updatedIndex = eventToProcessBlockIndexes_.index() + processBlockHelper_->outerOffset();
1333  eventToProcessBlockIndexes_.setIndex(updatedIndex);
1334  }
1335  }
1336  }
1337 
1339  EventSelectionIDVector& eventSelectionIDs,
1340  BranchListIndexes& branchListIndexes,
1341  bool assertOnFailure) {
1342  // We could consider doing delayed reading, but because we have to
1343  // store this History object in a different tree than the event
1344  // data tree, this is too hard to do in this first version.
1345  if (fileFormatVersion().eventHistoryBranch()) {
1346  // Lumi block number was not in EventID for the relevant releases.
1347  EventID id(evtAux.id().run(), 0, evtAux.id().event());
1348  if (eventProcessHistoryIter_->eventID() != id) {
1351  assert(eventProcessHistoryIter_->eventID() == id);
1352  }
1353  evtAux.setProcessHistoryID(eventProcessHistoryIter_->processHistoryID());
1355  } else if (fileFormatVersion().eventHistoryTree()) {
1356  // for backward compatibility.
1357  History* pHistory = history_.get();
1358  TBranch* eventHistoryBranch = eventHistoryTree_->GetBranch(poolNames::eventHistoryBranchName().c_str());
1359  if (!eventHistoryBranch) {
1360  throw Exception(errors::EventCorruption) << "Failed to find history branch in event history tree.\n";
1361  }
1362  eventHistoryBranch->SetAddress(&pHistory);
1364  evtAux.setProcessHistoryID(history_->processHistoryID());
1365  eventSelectionIDs.swap(history_->eventSelectionIDs());
1366  branchListIndexes.swap(history_->branchListIndexes());
1367  } else if (fileFormatVersion().noMetaDataTrees()) {
1368  // Current format
1369  EventSelectionIDVector* pESV = &eventSelectionIDs;
1370  TBranch* eventSelectionIDBranch = eventTree_.tree()->GetBranch(poolNames::eventSelectionsBranchName().c_str());
1371  assert(eventSelectionIDBranch != nullptr);
1372  eventTree_.fillBranchEntry(eventSelectionIDBranch, pESV);
1373  BranchListIndexes* pBLI = &branchListIndexes;
1374  TBranch* branchListIndexesBranch = eventTree_.tree()->GetBranch(poolNames::branchListIndexesBranchName().c_str());
1375  assert(branchListIndexesBranch != nullptr);
1376  eventTree_.fillBranchEntry(branchListIndexesBranch, pBLI);
1377  }
1378  if (provenanceAdaptor_) {
1379  evtAux.setProcessHistoryID(provenanceAdaptor_->convertID(evtAux.processHistoryID()));
1380  for (auto& esID : eventSelectionIDs) {
1381  esID = provenanceAdaptor_->convertID(esID);
1382  }
1383  }
1384  if (daqProvenanceHelper_) {
1385  evtAux.setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(evtAux.processHistoryID()));
1386  }
1388  // old format. branchListIndexes_ must be filled in from the ProvenanceAdaptor.
1389  provenanceAdaptor_->branchListIndexes(branchListIndexes);
1390  }
1391  if (branchIDListHelper_) {
1392  return branchIDListHelper_->fixBranchListIndexes(branchListIndexes, assertOnFailure);
1393  }
1394  return true;
1395  }
1396 
1397  std::shared_ptr<LuminosityBlockAuxiliary> RootFile::fillLumiAuxiliary() {
1398  auto lumiAuxiliary = std::make_shared<LuminosityBlockAuxiliary>();
1399  if (fileFormatVersion().newAuxiliary()) {
1400  LuminosityBlockAuxiliary* pLumiAux = lumiAuxiliary.get();
1402  } else {
1403  LuminosityBlockAux lumiAux;
1404  LuminosityBlockAux* pLumiAux = &lumiAux;
1406  conversion(lumiAux, *lumiAuxiliary);
1407  }
1408  if (provenanceAdaptor_) {
1409  lumiAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(lumiAuxiliary->processHistoryID()));
1410  }
1411  if (daqProvenanceHelper_) {
1412  lumiAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(lumiAuxiliary->processHistoryID()));
1413  }
1414  if (lumiAuxiliary->luminosityBlock() == 0 && !fileFormatVersion().runsAndLumis()) {
1415  lumiAuxiliary->id() = LuminosityBlockID(RunNumber_t(1), LuminosityBlockNumber_t(1));
1416  }
1417  return lumiAuxiliary;
1418  }
1419 
1420  std::shared_ptr<RunAuxiliary> RootFile::fillRunAuxiliary() {
1421  auto runAuxiliary = std::make_shared<RunAuxiliary>();
1422  if (fileFormatVersion().newAuxiliary()) {
1423  RunAuxiliary* pRunAux = runAuxiliary.get();
1424  runTree_.fillAux<RunAuxiliary>(pRunAux);
1425  } else {
1426  RunAux runAux;
1427  RunAux* pRunAux = &runAux;
1428  runTree_.fillAux<RunAux>(pRunAux);
1429  conversion(runAux, *runAuxiliary);
1430  }
1431  if (provenanceAdaptor_) {
1432  runAuxiliary->setProcessHistoryID(provenanceAdaptor_->convertID(runAuxiliary->processHistoryID()));
1433  }
1434  if (daqProvenanceHelper_) {
1435  runAuxiliary->setProcessHistoryID(daqProvenanceHelper_->mapProcessHistoryID(runAuxiliary->processHistoryID()));
1436  }
1437  return runAuxiliary;
1438  }
1439 
1441  while (offset > 0 && indexIntoFileIter_ != indexIntoFileEnd_) {
1442  int phIndexOfSkippedEvent = IndexIntoFile::invalidIndex;
1443  RunNumber_t runOfSkippedEvent = IndexIntoFile::invalidRun;
1446 
1448  phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, skippedEventEntry);
1449 
1450  // At the end of the file and there were no more events to skip
1451  if (skippedEventEntry == IndexIntoFile::invalidEntry)
1452  break;
1453 
1454  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1455  auto const evtAux = fillEventAuxiliary(skippedEventEntry);
1456  if (eventSkipperByID_->skipIt(runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event())) {
1457  continue;
1458  }
1459  }
1460  if (duplicateChecker_ && !duplicateChecker_->checkDisabled() && !duplicateChecker_->noDuplicatesInFile()) {
1461  auto const evtAux = fillEventAuxiliary(skippedEventEntry);
1462  if (duplicateChecker_->isDuplicateAndCheckActive(
1463  phIndexOfSkippedEvent, runOfSkippedEvent, lumiOfSkippedEvent, evtAux.id().event(), file_)) {
1464  continue;
1465  }
1466  }
1467  --offset;
1468  }
1469 
1470  while (offset < 0) {
1471  if (duplicateChecker_) {
1472  duplicateChecker_->disable();
1473  }
1474 
1475  int phIndexOfEvent = IndexIntoFile::invalidIndex;
1479 
1480  indexIntoFileIter_.skipEventBackward(phIndexOfEvent, runOfEvent, lumiOfEvent, eventEntry);
1481 
1482  if (eventEntry == IndexIntoFile::invalidEntry)
1483  break;
1484 
1485  if (eventSkipperByID_ && eventSkipperByID_->somethingToSkip()) {
1486  auto const evtAux = fillEventAuxiliary(eventEntry);
1487  if (eventSkipperByID_->skipIt(runOfEvent, lumiOfEvent, evtAux.id().event())) {
1488  continue;
1489  }
1490  }
1491  ++offset;
1492  }
1494  }
1495 
1496  bool RootFile::goToEvent(EventID const& eventID) {
1498 
1499  if (duplicateChecker_) {
1500  duplicateChecker_->disable();
1501  }
1502 
1504  if (noEventSort_)
1506  if (noRunLumiSort_) {
1507  sortOrder = IndexIntoFile::entryOrder;
1508  }
1509 
1511  indexIntoFile_.findPosition(sortOrder, eventID.run(), eventID.luminosityBlock(), eventID.event());
1512 
1513  if (iter == indexIntoFile_.end(sortOrder)) {
1514  return false;
1515  }
1516  indexIntoFileIter_ = iter;
1517  return true;
1518  }
1519 
1520  // readEvent() is responsible for creating, and setting up, the
1521  // EventPrincipal.
1522  //
1523  // 1. create an EventPrincipal with a unique EventID
1524  // 2. For each entry in the provenance, put in one ProductResolver,
1525  // holding the Provenance for the corresponding EDProduct.
1526  // 3. set up the the EventPrincipal to know about this ProductResolver.
1527  //
1528  // We do *not* create the EDProduct instance (the equivalent of reading
1529  // the branch containing this EDProduct. That will be done by the Delayed Reader,
1530  // when it is asked to do so.
1531  //
1535  // read the event
1536  auto [found, succeeded] = readCurrentEvent(principal, false);
1537  auto const& evtAux = principal.aux();
1538 
1539  runHelper_->checkRunConsistency(evtAux.run(), indexIntoFileIter_.run());
1540  runHelper_->checkLumiConsistency(evtAux.luminosityBlock(), indexIntoFileIter_.lumi());
1541 
1543  return succeeded;
1544  }
1545 
1546  // Reads event at the current entry in the event tree
1547  std::tuple<bool, bool> RootFile::readCurrentEvent(EventPrincipal& principal, bool assertOnFailure) {
1548  bool found = true;
1549  bool succeeded = true;
1550  if (!eventTree_.current()) {
1551  found = false;
1552  return {found, succeeded};
1553  }
1554  auto evtAux = fillThisEventAuxiliary();
1555  if (!fileFormatVersion().lumiInEventID()) {
1556  //ugly, but will disappear when the backward compatibility is done with schema evolution.
1557  const_cast<EventID&>(evtAux.id()).setLuminosityBlockNumber(evtAux.oldLuminosityBlock());
1558  evtAux.resetObsoleteInfo();
1559  }
1561  EventSelectionIDVector eventSelectionIDs;
1562  BranchListIndexes branchListIndexes;
1563  if (!fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes, assertOnFailure)) {
1564  succeeded = false;
1565  }
1566  runHelper_->overrideRunNumber(evtAux.id(), evtAux.isRealData());
1567 
1568  // We're not done ... so prepare the EventPrincipal
1570  auto history = processHistoryRegistry_->getMapped(evtAux.processHistoryID());
1571  principal.fillEventPrincipal(evtAux,
1572  history,
1573  std::move(eventSelectionIDs),
1574  std::move(branchListIndexes),
1576  *(makeProductProvenanceRetriever(principal.streamID().value())),
1578 
1579  // If this next assert shows up in performance profiling or significantly affects memory, then these three lines should be deleted.
1580  // The IndexIntoFile should guarantee that it never fails.
1582  ? *daqProvenanceHelper_->oldProcessHistoryID()
1583  : evtAux.processHistoryID());
1584  ProcessHistoryID const& reducedPHID = processHistoryRegistry_->reducedProcessHistoryID(idToCheck);
1586 
1587  // report event read from file
1588  filePtr_->eventReadFromFile();
1589  return {found, succeeded};
1590  }
1591 
1593 
1594  std::shared_ptr<RunAuxiliary> RootFile::readRunAuxiliary_() {
1595  if (runHelper_->fakeNewRun()) {
1596  auto runAuxiliary = std::make_shared<RunAuxiliary>(*savedRunAuxiliary());
1597  runHelper_->overrideRunNumber(runAuxiliary->id());
1598  return runAuxiliary;
1599  }
1602 
1603  // Begin code for backward compatibility before the existence of run trees.
1604  if (!runTree_.isValid()) {
1605  // prior to the support of run trees.
1606  // RunAuxiliary did not contain a valid timestamp. Take it from the next event.
1608  assert(eventEntry != IndexIntoFile::invalidEntry);
1609  assert(eventTree_.current(eventEntry));
1610  auto const evtAux = fillEventAuxiliary(eventEntry);
1611 
1613  runHelper_->overrideRunNumber(run);
1614  savedRunAuxiliary_ = std::make_shared<RunAuxiliary>(run.run(), evtAux.time(), Timestamp::invalidTimestamp());
1615  return savedRunAuxiliary();
1616  }
1617  // End code for backward compatibility before the existence of run trees.
1619  std::shared_ptr<RunAuxiliary> runAuxiliary = fillRunAuxiliary();
1620  assert(runAuxiliary->run() == indexIntoFileIter_.run());
1621  runHelper_->overrideRunNumber(runAuxiliary->id());
1622  filePtr_->reportInputRunNumber(runAuxiliary->run());
1623  // If RunAuxiliary did not contain a valid begin timestamp, invalidate any end timestamp.
1624  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1625  runAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1626  }
1627 
1628  // If RunAuxiliary did not contain a valid timestamp, or if this an old format file from
1629  // when the Run's ProcessHistory included only processes where products were added to the Run itself,
1630  // we attempt to read the first event in the run to get appropriate info.
1631  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp() ||
1634  // If we have a valid event, use its information.
1635  if (eventEntry != IndexIntoFile::invalidEntry) {
1636  assert(eventTree_.current(eventEntry));
1637  auto evtAux = fillEventAuxiliary(eventEntry);
1638 
1639  // RunAuxiliary did not contain a valid timestamp. Take it from the next event in this run if there is one.
1640  if (runAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1641  runAuxiliary->setBeginTime(evtAux.time());
1642  }
1643 
1644  // For backwards compatibility when the Run's ProcessHistory included only processes where products were added to the
1645  // Run, and then the Run and Event auxiliaries could be different. Use the event ProcessHistoryID if there is one. It should
1646  // almost always be correct by the current definition (processes included if any products are added. This makes the run, lumi,
1647  // and event ProcessHistory's always be the same if no file merging occurs).
1649  EventSelectionIDVector eventSelectionIDs;
1650  BranchListIndexes branchListIndexes;
1651  fillEventHistory(evtAux, eventSelectionIDs, branchListIndexes);
1652  runAuxiliary->setProcessHistoryID(evtAux.processHistoryID());
1653  }
1654  }
1655  }
1656  savedRunAuxiliary_ = runAuxiliary;
1657  return runAuxiliary;
1658  }
1659 
1662  std::vector<unsigned int> nEntries;
1663  nEntries.reserve(processBlockTrees_.size());
1664  for (auto const& processBlockTree : processBlockTrees_) {
1665  nEntries.push_back(processBlockTree->entries());
1666  }
1667  processBlockHelper_->fillFromPrimaryInput(*storedProcessBlockHelper_, nEntries);
1669  std::make_unique<StoredProcessBlockHelper>(); // propagate_const<T> has no reset() function
1670  }
1671 
1674  processBlockTrees_[currentProcessBlockTree_]->setEntryNumber(0);
1676  return true;
1677  }
1678  return false;
1679  }
1680 
1682 
1685  if (endOfProcessBlocksReached()) {
1686  return false;
1687  }
1689  return true;
1690  }
1691  // With the current design, the RootFile should always be
1692  // set to a valid ProcessBlock entry in one of the TTrees
1693  // if it not at the end.
1695  // Try for next entry in the same TTree
1696  if (processBlockTrees_[currentProcessBlockTree_]->nextWithCache()) {
1697  return true;
1698  }
1699  // Next ProcessBlock TTree
1701  if (endOfProcessBlocksReached()) {
1702  return false;
1703  }
1704  // With current design there should always be at least one entry.
1705  // Initialize for that entry.
1706  processBlockTrees_[currentProcessBlockTree_]->setEntryNumber(0);
1708  return true;
1709  }
1710 
1714  rootTree->insertEntryForIndex(0);
1715  assert(!rootTree->processName().empty());
1716  processBlockPrincipal.fillProcessBlockPrincipal(rootTree->processName(), rootTree->resetAndGetRootDelayedReader());
1717  }
1718 
1719  bool RootFile::readRun_(RunPrincipal& runPrincipal) {
1720  bool shouldProcessRun = indexIntoFileIter_.shouldProcessRun();
1721 
1722  MergeableRunProductMetadata* mergeableRunProductMetadata = nullptr;
1723  if (shouldProcessRun) {
1724  if (inputType_ == InputType::Primary) {
1725  mergeableRunProductMetadata = runPrincipal.mergeableRunProductMetadata();
1726  RootTree::EntryNumber const& entryNumber = runTree_.entryNumber();
1727  assert(entryNumber >= 0);
1728  mergeableRunProductMetadata->readRun(
1730  }
1731  }
1732 
1733  if (!runHelper_->fakeNewRun()) {
1737  }
1738  // Begin code for backward compatibility before the existence of run trees.
1739  if (!runTree_.isValid()) {
1740  return shouldProcessRun;
1741  }
1742  // End code for backward compatibility before the existence of run trees.
1743  if (shouldProcessRun) {
1744  // NOTE: we use 0 for the index since do not do delayed reads for RunPrincipals
1747  // Read in all the products now.
1748  runPrincipal.readAllFromSourceAndMergeImmediately(mergeableRunProductMetadata);
1749  runPrincipal.setShouldWriteRun(RunPrincipal::kYes);
1750  } else {
1751  runPrincipal.fillRunPrincipal(*processHistoryRegistry_, nullptr);
1752  if (runPrincipal.shouldWriteRun() != RunPrincipal::kYes) {
1753  runPrincipal.setShouldWriteRun(RunPrincipal::kNo);
1754  }
1755  }
1756  return shouldProcessRun;
1757  }
1758 
1759  std::shared_ptr<LuminosityBlockAuxiliary> RootFile::readLuminosityBlockAuxiliary_() {
1762  // Begin code for backward compatibility before the existence of lumi trees.
1763  if (!lumiTree_.isValid()) {
1765  assert(eventEntry != IndexIntoFile::invalidEntry);
1766  assert(eventTree_.current(eventEntry));
1767  auto const evtAux = fillEventAuxiliary(eventEntry);
1768 
1770  runHelper_->overrideRunNumber(lumi);
1771  return std::make_shared<LuminosityBlockAuxiliary>(
1772  lumi.run(), lumi.luminosityBlock(), evtAux.time(), Timestamp::invalidTimestamp());
1773  }
1774  // End code for backward compatibility before the existence of lumi trees.
1776  std::shared_ptr<LuminosityBlockAuxiliary> lumiAuxiliary = fillLumiAuxiliary();
1777  assert(lumiAuxiliary->run() == indexIntoFileIter_.run());
1778  assert(lumiAuxiliary->luminosityBlock() == indexIntoFileIter_.lumi());
1779  runHelper_->overrideRunNumber(lumiAuxiliary->id());
1780  filePtr_->reportInputLumiSection(lumiAuxiliary->run(), lumiAuxiliary->luminosityBlock());
1781  if (lumiAuxiliary->beginTime() == Timestamp::invalidTimestamp()) {
1783  if (eventEntry != IndexIntoFile::invalidEntry) {
1784  assert(eventTree_.current(eventEntry));
1785  auto const evtAux = fillEventAuxiliary(eventEntry);
1786 
1787  lumiAuxiliary->setBeginTime(evtAux.time());
1788  }
1789  lumiAuxiliary->setEndTime(Timestamp::invalidTimestamp());
1790  }
1791  if (!fileFormatVersion().processHistorySameWithinRun() && savedRunAuxiliary_) {
1792  lumiAuxiliary->setProcessHistoryID(savedRunAuxiliary_->processHistoryID());
1793  }
1794  return lumiAuxiliary;
1795  }
1796 
1798  bool shouldProcessLumi = indexIntoFileIter_.shouldProcessLumi();
1801  // Begin code for backward compatibility before the existence of lumi trees.
1802  if (!lumiTree_.isValid()) {
1804  return shouldProcessLumi;
1805  }
1806  // End code for backward compatibility before the existence of lumi trees.
1807  if (shouldProcessLumi) {
1809  // NOTE: we use 0 for the index since do not do delayed reads for LuminosityBlockPrincipals
1811  auto history = processHistoryRegistry_->getMapped(lumiPrincipal.aux().processHistoryID());
1813  // Read in all the products now.
1814  lumiPrincipal.readAllFromSourceAndMergeImmediately();
1816  } else {
1817  auto history = processHistoryRegistry_->getMapped(lumiPrincipal.aux().processHistoryID());
1818  lumiPrincipal.fillLuminosityBlockPrincipal(history, nullptr);
1819  if (lumiPrincipal.shouldWriteLumi() != LuminosityBlockPrincipal::kYes) {
1821  }
1822  }
1824  return shouldProcessLumi;
1825  }
1826 
1830  return false;
1832  return true;
1833  }
1834 
1838  return false;
1840  return true;
1841  }
1842 
1846  return false;
1848  return true;
1849  }
1850 
1854  }
1857  return false;
1858  if (run != indexIntoFileIter_.run())
1859  return false;
1860  if (lumi != indexIntoFileIter_.lumi())
1861  return false;
1862  //The following is used for its side effect of advancing the
1863  // eventTree entry.
1865  return true;
1866  }
1867 
1869  // Read in the event history tree, if we have one...
1870  if (fileFormatVersion().eventHistoryTree()) {
1871  history_ = std::make_unique<History>(); // propagate_const<T> has no reset() function
1872  eventHistoryTree_ = dynamic_cast<TTree*>(filePtr_->Get(poolNames::eventHistoryTreeName().c_str()));
1873  if (!eventHistoryTree_) {
1874  throw Exception(errors::EventCorruption) << "Failed to find the event history tree.\n";
1875  }
1876  }
1877  }
1878 
1880  std::vector<std::shared_ptr<IndexIntoFile>> const& indexesIntoFiles,
1881  std::vector<std::shared_ptr<IndexIntoFile>>::size_type currentIndexIntoFile) {
1882  if (duplicateChecker_ && !duplicateChecker_->checkDisabled()) {
1883  if (eventTree_.next()) {
1884  auto const evtAux = fillThisEventAuxiliary();
1885 
1886  duplicateChecker_->inputFileOpened(evtAux.isRealData(), indexIntoFile_, indexesIntoFiles, currentIndexIntoFile);
1887  }
1889  }
1890  }
1891 
1893  StoredProcessBlockHelper const& storedProcessBlockHelper) {
1894  // Set product presence information in the product registry.
1895  // "Presence" is a boolean that is true if and only if the TBranch exists
1896  // in the TTree (except it will be false for ProcessBlock products in non-Primary
1897  // input files).
1898  ProductRegistry::ProductList& pList = inputProdDescReg.productListUpdator();
1899  for (auto& product : pList) {
1900  BranchDescription& prod = product.second;
1901  // Initialize BranchDescription from dictionary only if the
1902  // branch is present. This allows a subsequent job to process
1903  // data where a dictionary of a transient parent branch has been
1904  // removed from the release after the file has been written.
1905  prod.initBranchName();
1906  if (prod.branchType() == InProcess) {
1907  std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
1908  auto it = std::find(processes.begin(), processes.end(), prod.processName());
1909  if (it != processes.end()) {
1910  auto index = std::distance(processes.begin(), it);
1911  processBlockTrees_[index]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
1912  } else {
1913  // Given current rules for saving BranchDescriptions, this case should only occur
1914  // in non-Primary sequences.
1915  prod.setDropped(true);
1916  }
1917  } else {
1918  treePointers_[prod.branchType()]->setPresence(prod, newBranchToOldBranch(prod.branchName()));
1919  }
1920  if (prod.present()) {
1921  prod.initFromDictionary();
1922  }
1923  }
1924  }
1925 
1926  void RootFile::markBranchToBeDropped(bool dropDescendants,
1927  BranchDescription const& branch,
1928  std::set<BranchID>& branchesToDrop,
1929  std::map<BranchID, BranchID> const& droppedToKeptAlias) const {
1930  if (dropDescendants) {
1931  branchChildren_->appendToDescendants(branch, branchesToDrop, droppedToKeptAlias);
1932  } else {
1933  branchesToDrop.insert(branch.branchID());
1934  }
1935  }
1936 
1938  ProductSelectorRules const& rules,
1939  bool dropDescendants,
1940  InputType inputType,
1941  StoredProcessBlockHelper& storedProcessBlockHelper,
1942  ProcessBlockHelper const* processBlockHelper) {
1944 
1945  // First fill in a map we will need to navigate to descendants
1946  // in the case of EDAliases.
1947  std::map<BranchID, BranchID> droppedToKeptAlias;
1948  for (auto const& product : prodList) {
1949  BranchDescription const& prod = product.second;
1950  if (prod.branchID() != prod.originalBranchID() && prod.present()) {
1951  droppedToKeptAlias[prod.originalBranchID()] = prod.branchID();
1952  }
1953  }
1954 
1955  // This object will select products based on the branchName and the
1956  // keep and drop statements which are in the source configuration.
1957  ProductSelector productSelector;
1958  productSelector.initialize(rules, reg.allBranchDescriptions());
1959 
1960  // In this pass, fill in a set of branches to be dropped.
1961  // Don't drop anything yet.
1962  std::set<BranchID> branchesToDrop;
1963  std::vector<BranchDescription const*> associationDescriptions;
1964  for (auto const& product : prodList) {
1965  BranchDescription const& prod = product.second;
1966  if (inputType != InputType::Primary && prod.branchType() == InProcess) {
1967  markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1968  } else if (prod.unwrappedType() == typeid(ThinnedAssociation) && prod.present()) {
1969  // Special handling for ThinnedAssociations
1970  if (inputType != InputType::SecondarySource) {
1971  associationDescriptions.push_back(&prod);
1972  } else {
1973  markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1974  }
1975  } else if (!productSelector.selected(prod)) {
1976  markBranchToBeDropped(dropDescendants, prod, branchesToDrop, droppedToKeptAlias);
1977  }
1978  }
1979 
1980  if (inputType != InputType::SecondarySource) {
1981  // Decide whether to keep the thinned associations and corresponding
1982  // entries in the helper. For secondary source they are all dropped,
1983  // but in other cases we look for thinned collections the associations
1984  // redirect a Ref or Ptr to when dereferencing them.
1985 
1986  // Need a list of kept products in order to determine which thinned associations
1987  // are kept.
1988  std::set<BranchID> keptProductsInEvent;
1989  for (auto const& product : prodList) {
1990  BranchDescription const& prod = product.second;
1991  if (branchesToDrop.find(prod.branchID()) == branchesToDrop.end() && prod.present() &&
1992  prod.branchType() == InEvent) {
1993  keptProductsInEvent.insert(prod.branchID());
1994  }
1995  }
1996 
1997  // Decide which ThinnedAssociations to keep and store the decision in keepAssociation
1998  std::map<BranchID, bool> keepAssociation;
1999  fileThinnedAssociationsHelper_->selectAssociationProducts(
2000  associationDescriptions, keptProductsInEvent, keepAssociation);
2001 
2002  for (auto association : associationDescriptions) {
2003  if (!keepAssociation[association->branchID()]) {
2004  markBranchToBeDropped(dropDescendants, *association, branchesToDrop, droppedToKeptAlias);
2005  }
2006  }
2007 
2008  // Also delete the dropped associations from the ThinnedAssociationsHelper
2009  auto temp = std::make_unique<ThinnedAssociationsHelper>();
2010  for (auto const& associationBranches : fileThinnedAssociationsHelper_->data()) {
2011  auto iter = keepAssociation.find(associationBranches.association());
2012  if (iter != keepAssociation.end() && iter->second) {
2013  temp->addAssociation(associationBranches);
2014  }
2015  }
2016  // propagate_const<T> has no reset() function
2017  fileThinnedAssociationsHelper_ = std::unique_ptr<ThinnedAssociationsHelper>(temp.release());
2018  }
2019 
2020  // On this pass, actually drop the branches.
2021  std::set<std::string> processesWithKeptProcessBlockProducts;
2022  std::set<BranchID>::const_iterator branchesToDropEnd = branchesToDrop.end();
2023  for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
2024  BranchDescription const& prod = it->second;
2025  bool drop = branchesToDrop.find(prod.branchID()) != branchesToDropEnd;
2026  if (drop) {
2027  if (!prod.dropped()) {
2028  if (productSelector.selected(prod) && prod.unwrappedType() != typeid(ThinnedAssociation) &&
2029  prod.branchType() != InProcess) {
2030  LogWarning("RootFile") << "Branch '" << prod.branchName() << "' is being dropped from the input\n"
2031  << "of file '" << file_ << "' because it is dependent on a branch\n"
2032  << "that was explicitly dropped.\n";
2033  }
2034  if (prod.branchType() == InProcess) {
2035  std::vector<std::string> const& processes = storedProcessBlockHelper.processesWithProcessBlockProducts();
2036  auto it = std::find(processes.begin(), processes.end(), prod.processName());
2037  assert(it != processes.end());
2038  auto index = std::distance(processes.begin(), it);
2039  processBlockTrees_[index]->dropBranch(newBranchToOldBranch(prod.branchName()));
2040  } else {
2041  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
2042  }
2043  hasNewlyDroppedBranch_[prod.branchType()] = true;
2044  }
2045  ProductRegistry::ProductList::iterator icopy = it;
2046  ++it;
2047  prodList.erase(icopy);
2048  } else {
2049  if (prod.branchType() == InProcess && prod.present()) {
2050  processesWithKeptProcessBlockProducts.insert(prod.processName());
2051  }
2052  ++it;
2053  }
2054  }
2055 
2056  dropProcessesAndReorder(storedProcessBlockHelper, processesWithKeptProcessBlockProducts, processBlockHelper);
2057 
2058  // Drop on input mergeable run and lumi products, this needs to be invoked for secondary file input
2059  if (inputType == InputType::SecondaryFile) {
2060  TString tString;
2061  for (ProductRegistry::ProductList::iterator it = prodList.begin(), itEnd = prodList.end(); it != itEnd;) {
2062  BranchDescription const& prod = it->second;
2063  if (prod.present() and prod.branchType() != InEvent and prod.branchType() != InProcess) {
2064  TClass* cp = prod.wrappedType().getClass();
2065  void* p = cp->New();
2066  int offset = cp->GetBaseClassOffset(edProductClass_);
2067  std::unique_ptr<WrapperBase> edp = getWrapperBasePtr(p, offset);
2068  if (edp->isMergeable()) {
2069  treePointers_[prod.branchType()]->dropBranch(newBranchToOldBranch(prod.branchName()));
2070  ProductRegistry::ProductList::iterator icopy = it;
2071  ++it;
2072  prodList.erase(icopy);
2073  } else {
2074  ++it;
2075  }
2076  } else
2077  ++it;
2078  }
2079  }
2080  }
2081 
2083  std::set<std::string> const& processesWithKeptProcessBlockProducts,
2084  ProcessBlockHelper const* processBlockHelper) {
2085  // Modify storedProcessBlockHelper and processBlockTrees_
2086  // This should account for dropOnInput and also make the
2087  // order of process blocks in input files after the first
2088  // be the same as the first. Processes with no ProcessBlock
2089  // products should be removed. After this executes,
2090  // the items in storedProcessBlockHelper
2091  // and processBlockTrees should be in exact one to one
2092  // correspondence and in the same order. For input files
2093  // after the first, these items should be either the same
2094  // as or a subset of the items in processBlockHelper and in
2095  // the same order.
2096 
2097  if (processBlockTrees_.empty()) {
2098  return;
2099  }
2100 
2101  std::vector<unsigned int> nEntries;
2102  nEntries.reserve(processBlockTrees_.size());
2103  for (auto const& processBlockTree : processBlockTrees_) {
2104  nEntries.push_back(processBlockTree->entries());
2105  }
2106 
2107  bool firstInputFile = !processBlockHelper->initializedFromInput();
2108  bool isModified = false;
2109  std::vector<unsigned int> finalIndexToStoredIndex;
2110 
2111  if (firstInputFile) {
2112  isModified = processBlockHelper->firstFileDropProcessesAndReorderStored(
2113  storedProcessBlockHelper, processesWithKeptProcessBlockProducts, nEntries, finalIndexToStoredIndex);
2114  } else {
2115  isModified =
2116  processBlockHelper->dropProcessesAndReorderStored(storedProcessBlockHelper,
2117  processesWithKeptProcessBlockProducts,
2118  nEntries,
2119  finalIndexToStoredIndex,
2120  processBlockHelper->processesWithProcessBlockProducts());
2121  }
2122 
2123  // At this point, any modifications to storedProcessBlockHelper are done.
2124  // Make consistent changes to processBlockTrees_ and this will cause
2125  // unneeded RootTrees to be deleted.
2126  if (isModified) {
2127  std::vector<edm::propagate_const<std::unique_ptr<RootTree>>> newProcessBlockTrees;
2128  unsigned int nFinalProducts = storedProcessBlockHelper.processesWithProcessBlockProducts().size();
2129  for (unsigned int j = 0; j < nFinalProducts; ++j) {
2130  unsigned int iStored = finalIndexToStoredIndex[j];
2131  newProcessBlockTrees.push_back(std::move(processBlockTrees_[iStored]));
2132  }
2133  processBlockTrees_.swap(newProcessBlockTrees);
2134  }
2135  }
2136 
2138  signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* preEventReadSource,
2139  signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* postEventReadSource) {
2140  eventTree_.setSignals(preEventReadSource, postEventReadSource);
2141  }
2142 
2143  void RootFile::makeProcessBlockRootTrees(std::shared_ptr<InputFile> filePtr,
2144  int treeMaxVirtualSize,
2145  bool enablePrefetching,
2146  InputType inputType,
2147  StoredProcessBlockHelper const& storedProcessBlockHelper) {
2148  // When this functions returns there will be exactly a 1-to-1 correspondence between the
2149  // processes listed in storedProcessBlockHelper and the RootTree objects created. processBlockTrees_
2150  // has pointers to the RootTree's and will be filled in the same order. The RootTree constructor
2151  // will throw an exception if one of these TTree's is not in the file and this should be all of
2152  // the ProcessBlock TTree's in the file. (later in the RootFile constructor, dropOnInput might
2153  // remove some and also reordering may occur).
2154  for (auto const& process : storedProcessBlockHelper.processesWithProcessBlockProducts()) {
2155  processBlockTrees_.emplace_back(std::make_unique<RootTree>(filePtr,
2156  InProcess,
2157  process,
2158  1,
2159  treeMaxVirtualSize,
2162  enablePrefetching,
2163  inputType));
2164  }
2165  }
2166 
2167  std::unique_ptr<MakeProvenanceReader> RootFile::makeProvenanceReaderMaker(InputType inputType) {
2169  readParentageTree(inputType);
2170  return std::make_unique<MakeReducedProvenanceReader>(parentageIDLookup_);
2171  } else if (fileFormatVersion_.splitProductIDs()) {
2172  readParentageTree(inputType);
2173  return std::make_unique<MakeFullProvenanceReader>();
2174  } else if (fileFormatVersion_.perEventProductIDs()) {
2175  auto entryDescriptionMap = std::make_unique<EntryDescriptionMap>();
2176  readEntryDescriptionTree(*entryDescriptionMap, inputType);
2177  return std::make_unique<MakeOldProvenanceReader>(std::move(entryDescriptionMap));
2178  } else {
2179  return std::make_unique<MakeDummyProvenanceReader>();
2180  }
2181  }
2182 
2183  std::shared_ptr<ProductProvenanceRetriever> RootFile::makeProductProvenanceRetriever(unsigned int iStreamID) {
2184  if (eventProductProvenanceRetrievers_.size() <= iStreamID) {
2185  eventProductProvenanceRetrievers_.resize(iStreamID + 1);
2186  }
2187  if (!eventProductProvenanceRetrievers_[iStreamID]) {
2188  // propagate_const<T> has no reset() function
2189  eventProductProvenanceRetrievers_[iStreamID] = std::make_shared<ProductProvenanceRetriever>(
2191  }
2192  eventProductProvenanceRetrievers_[iStreamID]->reset();
2193  return eventProductProvenanceRetriever(iStreamID);
2194  }
2195 
2197  public:
2198  ReducedProvenanceReader(RootTree* iRootTree,
2199  std::vector<ParentageID> const& iParentageIDLookup,
2200  DaqProvenanceHelper const* daqProvenanceHelper);
2201 
2202  std::set<ProductProvenance> readProvenance(unsigned int) const override;
2203 
2204  private:
2206  ModuleCallingContext const* moduleCallingContext,
2207  unsigned int transitionIndex,
2208  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2209 
2214  std::vector<ParentageID> const& parentageIDLookup_;
2216  std::shared_ptr<std::recursive_mutex> mutex_;
2218  };
2219 
2221  std::vector<ParentageID> const& iParentageIDLookup,
2222  DaqProvenanceHelper const* daqProvenanceHelper)
2224  rootTree_(iRootTree),
2225  pProvVector_(&provVector_),
2226  parentageIDLookup_(iParentageIDLookup),
2227  daqProvenanceHelper_(daqProvenanceHelper),
2228  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2229  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {
2230  provBranch_ =
2231  rootTree_->tree()->GetBranch(BranchTypeToProductProvenanceBranchName(rootTree_->branchType()).c_str());
2232  }
2233 
2234  namespace {
2236  template <typename R>
2237  void readProvenanceAsyncImpl(R const* iThis,
2238  SerialTaskQueueChain& chain,
2240  unsigned int transitionIndex,
2241  std::atomic<const std::set<ProductProvenance>*>& writeTo,
2242  ModuleCallingContext const* iContext,
2243  SignalType const* pre,
2244  SignalType const* post) {
2245  if (nullptr == writeTo.load()) {
2246  //need to be sure the task isn't run until after the read
2247  WaitingTaskHolder taskHolder{task};
2248  auto pWriteTo = &writeTo;
2249 
2250  auto serviceToken = ServiceRegistry::instance().presentToken();
2251 
2252  chain.push(
2253  *taskHolder.group(),
2254  [holder = std::move(taskHolder),
2255  pWriteTo,
2256  iThis,
2257  transitionIndex,
2258  iContext,
2259  pre,
2260  post,
2261  serviceToken]() mutable {
2262  if (nullptr == pWriteTo->load()) {
2263  ServiceRegistry::Operate operate(serviceToken);
2264  std::unique_ptr<const std::set<ProductProvenance>> prov;
2265  try {
2266  if (pre) {
2267  pre->emit(*(iContext->getStreamContext()), *iContext);
2268  }
2269  prov = std::make_unique<const std::set<ProductProvenance>>(iThis->readProvenance(transitionIndex));
2270  if (post) {
2271  post->emit(*(iContext->getStreamContext()), *iContext);
2272  }
2273 
2274  } catch (...) {
2275  if (post) {
2276  post->emit(*(iContext->getStreamContext()), *iContext);
2277  }
2278 
2279  holder.doneWaiting(std::current_exception());
2280  return;
2281  }
2282  const std::set<ProductProvenance>* expected = nullptr;
2283 
2284  if (pWriteTo->compare_exchange_strong(expected, prov.get())) {
2285  prov.release();
2286  }
2287  }
2288  holder.doneWaiting(std::exception_ptr());
2289  });
2290  }
2291  }
2292  } // namespace
2293 
2295  ModuleCallingContext const* moduleCallingContext,
2296  unsigned int transitionIndex,
2297  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2298  readProvenanceAsyncImpl(this,
2300  task,
2301  transitionIndex,
2302  writeTo,
2303  moduleCallingContext,
2304  rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2305  rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2306  }
2307 
2308  std::set<ProductProvenance> ReducedProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2309  {
2310  std::lock_guard<std::recursive_mutex> guard(*mutex_);
2311  ReducedProvenanceReader* me = const_cast<ReducedProvenanceReader*>(this);
2312  me->rootTree_->fillBranchEntry(
2313  me->provBranch_, me->rootTree_->entryNumberForIndex(transitionIndex), me->pProvVector_);
2314  }
2315  std::set<ProductProvenance> retValue;
2316  if (daqProvenanceHelper_) {
2317  for (auto const& prov : provVector_) {
2318  BranchID bid(prov.branchID_);
2319  retValue.emplace(daqProvenanceHelper_->mapBranchID(BranchID(prov.branchID_)),
2320  daqProvenanceHelper_->mapParentageID(parentageIDLookup_[prov.parentageIDIndex_]));
2321  }
2322  } else {
2323  for (auto const& prov : provVector_) {
2324  if (prov.parentageIDIndex_ >= parentageIDLookup_.size()) {
2326  << "ReducedProvenanceReader::ReadProvenance\n"
2327  << "The parentage ID index value " << prov.parentageIDIndex_
2328  << " is out of bounds. The maximum value is " << parentageIDLookup_.size() - 1 << ".\n"
2329  << "This should never happen.\n"
2330  << "Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
2331  }
2332  retValue.emplace(BranchID(prov.branchID_), parentageIDLookup_[prov.parentageIDIndex_]);
2333  }
2334  }
2335  return retValue;
2336  }
2337 
2339  public:
2340  explicit FullProvenanceReader(RootTree* rootTree, DaqProvenanceHelper const* daqProvenanceHelper);
2342  std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
2343 
2344  private:
2346  ModuleCallingContext const* moduleCallingContext,
2347  unsigned int transitionIndex,
2348  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2349 
2352  //All access to a ROOT file is serialized
2355  std::shared_ptr<std::recursive_mutex> mutex_;
2357  };
2358 
2361  rootTree_(rootTree),
2362  infoVector_(),
2363  pInfoVector_(&infoVector_),
2364  daqProvenanceHelper_(daqProvenanceHelper),
2365  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2366  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2367 
2369  ModuleCallingContext const* moduleCallingContext,
2370  unsigned int transitionIndex,
2371  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2372  readProvenanceAsyncImpl(this,
2374  task,
2375  transitionIndex,
2376  writeTo,
2377  moduleCallingContext,
2380  }
2381 
2382  std::set<ProductProvenance> FullProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2383  {
2384  std::lock_guard<std::recursive_mutex> guard(*mutex_);
2387  }
2388  std::set<ProductProvenance> retValue;
2389  if (daqProvenanceHelper_) {
2390  for (auto const& info : infoVector_) {
2391  retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2392  daqProvenanceHelper_->mapParentageID(info.parentageID()));
2393  }
2394  } else {
2395  for (auto const& info : infoVector_) {
2396  retValue.emplace(info);
2397  }
2398  }
2399  return retValue;
2400  }
2401 
2403  public:
2404  explicit OldProvenanceReader(RootTree* rootTree,
2405  EntryDescriptionMap const& theMap,
2406  DaqProvenanceHelper const* daqProvenanceHelper);
2407  ~OldProvenanceReader() override {}
2408  std::set<ProductProvenance> readProvenance(unsigned int transitionIndex) const override;
2409 
2410  private:
2412  ModuleCallingContext const* moduleCallingContext,
2413  unsigned int transitionIndex,
2414  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2415 
2417  std::vector<EventEntryInfo> infoVector_;
2418  //All access to ROOT file are serialized
2419  CMS_SA_ALLOW mutable std::vector<EventEntryInfo>* pInfoVector_;
2422  std::shared_ptr<std::recursive_mutex> mutex_;
2424  };
2425 
2427  EntryDescriptionMap const& theMap,
2428  DaqProvenanceHelper const* daqProvenanceHelper)
2430  rootTree_(rootTree),
2431  infoVector_(),
2432  pInfoVector_(&infoVector_),
2433  entryDescriptionMap_(theMap),
2434  daqProvenanceHelper_(daqProvenanceHelper),
2435  mutex_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().second),
2436  acquirer_(SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader().first) {}
2437 
2439  ModuleCallingContext const* moduleCallingContext,
2440  unsigned int transitionIndex,
2441  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2442  readProvenanceAsyncImpl(this,
2444  task,
2445  transitionIndex,
2446  writeTo,
2447  moduleCallingContext,
2448  rootTree_->rootDelayedReader()->preEventReadFromSourceSignal(),
2449  rootTree_->rootDelayedReader()->postEventReadFromSourceSignal());
2450  }
2451 
2452  std::set<ProductProvenance> OldProvenanceReader::readProvenance(unsigned int transitionIndex) const {
2453  {
2454  std::lock_guard<std::recursive_mutex> guard(*mutex_);
2455  rootTree_->branchEntryInfoBranch()->SetAddress(&pInfoVector_);
2456  roottree::getEntry(rootTree_->branchEntryInfoBranch(), rootTree_->entryNumberForIndex(transitionIndex));
2457  }
2458  std::set<ProductProvenance> retValue;
2459  for (auto const& info : infoVector_) {
2460  EntryDescriptionMap::const_iterator iter = entryDescriptionMap_.find(info.entryDescriptionID());
2461  assert(iter != entryDescriptionMap_.end());
2462  Parentage parentage(iter->second.parents());
2463  if (daqProvenanceHelper_) {
2464  retValue.emplace(daqProvenanceHelper_->mapBranchID(info.branchID()),
2465  daqProvenanceHelper_->mapParentageID(parentage.id()));
2466  } else {
2467  retValue.emplace(info.branchID(), parentage.id());
2468  }
2469  }
2470  return retValue;
2471  }
2472 
2474  public:
2477 
2478  private:
2479  std::set<ProductProvenance> readProvenance(unsigned int) const override;
2481  ModuleCallingContext const* moduleCallingContext,
2482  unsigned int transitionIndex,
2483  std::atomic<const std::set<ProductProvenance>*>& writeTo) const override;
2484  };
2485 
2487 
2488  std::set<ProductProvenance> DummyProvenanceReader::readProvenance(unsigned int) const {
2489  // Not providing parentage!!!
2490  return std::set<ProductProvenance>{};
2491  }
2493  ModuleCallingContext const* moduleCallingContext,
2494  unsigned int transitionIndex,
2495  std::atomic<const std::set<ProductProvenance>*>& writeTo) const {
2496  if (nullptr == writeTo.load()) {
2497  auto emptyProv = std::make_unique<const std::set<ProductProvenance>>();
2498  const std::set<ProductProvenance>* expected = nullptr;
2499  if (writeTo.compare_exchange_strong(expected, emptyProv.get())) {
2500  emptyProv.release();
2501  }
2502  }
2503  }
2504 
2505  std::unique_ptr<ProvenanceReaderBase> MakeDummyProvenanceReader::makeReader(RootTree&,
2506  DaqProvenanceHelper const*) const {
2507  return std::make_unique<DummyProvenanceReader>();
2508  }
2509 
2510  std::unique_ptr<ProvenanceReaderBase> MakeOldProvenanceReader::makeReader(
2511  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2512  return std::make_unique<OldProvenanceReader>(&rootTree, *entryDescriptionMap_, daqProvenanceHelper);
2513  }
2514 
2515  std::unique_ptr<ProvenanceReaderBase> MakeFullProvenanceReader::makeReader(
2516  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2517  return std::make_unique<FullProvenanceReader>(&rootTree, daqProvenanceHelper);
2518  }
2519 
2520  std::unique_ptr<ProvenanceReaderBase> MakeReducedProvenanceReader::makeReader(
2521  RootTree& rootTree, DaqProvenanceHelper const* daqProvenanceHelper) const {
2522  return std::make_unique<ReducedProvenanceReader>(&rootTree, parentageIDLookup_, daqProvenanceHelper);
2523  }
2524 } // namespace edm
void initializeFromPrimaryInput(StoredProcessBlockHelper const &storedProcessBlockHelper)
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: RootTree.cc:527
IndexIntoFileItr end(SortOrder sortOrder) const
Used to end an iteration over the Runs, Lumis, and Events in a file.
std::vector< BranchDescription const * > allBranchDescriptions() const
IndexIntoFileItr begin(SortOrder sortOrder) const
void setShouldWriteRun(ShouldWriteRun value)
Definition: RunPrincipal.h:87
bool noRunLumiSort_
Definition: RootFile.h:377
edm::propagate_const< std::unique_ptr< ThinnedAssociationsHelper > > fileThinnedAssociationsHelper_
Definition: RootFile.h:397
std::string const & processName() const
Definition: RootTree.h:185
std::vector< ProcessConfiguration > ProcessConfigurationVector
void setShouldWriteLumi(ShouldWriteLumi value)
StoredProductProvenanceVector provVector_
Definition: RootFile.cc:2212
std::string const & metaDataTreeName()
Definition: BranchType.cc:159
unsigned int const defaultNonEventLearningEntries
Definition: RootTree.h:41
std::string const & fid() const
Definition: FileID.h:19
IndexIntoFileItr findLumiPosition(RunNumber_t run, LuminosityBlockNumber_t lumi) const
InputType
Definition: InputType.h:5
EventToProcessBlockIndexes eventToProcessBlockIndexes_
Definition: RootFile.h:403
static const TGPicture * info(bool iBackgroundIsBlack)
std::string const & fileIdentifierBranchName()
Definition: BranchType.cc:192
#define CMS_SA_ALLOW
static constexpr int invalidIndex
TPRegexp parents
Definition: eve_filter.cc:21
std::string const & mergeableRunProductMetadataBranchName()
Definition: BranchType.cc:201
std::vector< BranchIDList > BranchIDLists
Definition: BranchIDList.h:19
std::string const & processBlockHelperBranchName()
Definition: BranchType.cc:204
std::shared_ptr< BranchIDLists const > branchIDLists_
Definition: RootFile.h:393
roottree::EntryNumber EntryNumber
Definition: RootTree.h:82
bool skipEvents(int &offset)
Definition: RootFile.cc:1440
edm::propagate_const< std::shared_ptr< DuplicateChecker > > duplicateChecker_
Definition: RootFile.h:407
TTree const * tree() const
Definition: RootTree.h:169
EntryDescriptionID id() const
std::shared_ptr< LuminosityBlockAuxiliary > fillLumiAuxiliary()
Definition: RootFile.cc:1397
EventNumber_t event() const
bool wasLastEventJustRead() const
Definition: RootFile.cc:929
ProductProvenanceVector infoVector_
Definition: RootFile.cc:2351
static std::string const source("source")
static Timestamp invalidTimestamp()
Definition: Timestamp.h:75
ForwardSequence::const_iterator lower_bound_all(ForwardSequence const &s, Datum const &d)
wrappers for std::lower_bound
Definition: Algorithms.h:69
EventAuxiliary const & aux() const
void readEntryDescriptionTree(EntryDescriptionMap &entryDescriptionMap, InputType inputType)
Definition: RootFile.cc:640
void fillBranchEntryMeta(TBranch *branch, EntryNumber entryNumber, T *&pbuf)
Definition: RootTree.h:153
ProductList const & productList() const
TTree const * metaTree() const
Definition: RootTree.h:171
EntryNumber const & entryNumber() const
Definition: RootTree.h:132
void fillEventNumbers() const
EventAuxiliary fillEventAuxiliary(IndexIntoFile::EntryNumber_t entry)
Definition: RootFile.cc:1313
std::vector< std::string > const & processesWithProcessBlockProducts() const
bool setEntryAtNextEventInLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1851
void fillLuminosityBlockPrincipal(ProcessHistory const *processHistory, DelayedReader *reader=nullptr)
bool enforceGUIDInFileName_
Definition: RootFile.h:379
EntryNumber const & entryNumberForIndex(unsigned int index) const
Definition: RootTree.cc:113
static PFTauRenderPlugin instance
std::shared_ptr< RunAuxiliary const > savedRunAuxiliary() const
Definition: RootFile.h:345
FileFormatVersion fileFormatVersion() const
Definition: RootFile.h:245
MakeOldProvenanceReader(std::unique_ptr< EntryDescriptionMap > &&entryDescriptionMap)
Definition: RootFile.cc:83
int whyNotFastClonable_
Definition: RootFile.h:380
edm::propagate_const< std::shared_ptr< EventSkipperByID > > eventSkipperByID_
Definition: RootFile.h:363
edm::propagate_const< std::shared_ptr< ThinnedAssociationsHelper > > thinnedAssociationsHelper_
Definition: RootFile.h:398
ProcessHistoryID const & processHistoryID() const
std::array< bool, NumBranchTypes > const & hasNewlyDroppedBranch() const
Definition: RootFile.h:247
std::string const & moduleDescriptionMapBranchName()
Definition: BranchType.cc:171
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:2354
std::map< std::string, std::string > newBranchToOldBranch_
Definition: RootFile.h:401
constexpr unsigned int numberOfRunLumiEventProductTrees
Definition: BranchType.h:15
std::map< BranchKey, BranchDescription > ProductList
std::string const & newBranchToOldBranch(std::string const &newBranch) const
Definition: RootFile.cc:811
bool registerProcessHistory(ProcessHistory const &processHistory)
std::shared_ptr< ProductRegistry const > productRegistry() const
Definition: RootFile.h:238
bool setEntryAtRun(RunNumber_t run)
Definition: RootFile.cc:1843
std::string_view stemFromPath(std::string_view path)
Definition: stemFromPath.cc:4
ProductProvenanceVector * pInfoVector_
Definition: RootFile.cc:2353
RootTree lumiTree_
Definition: RootFile.h:385
InputType inputType_
Definition: RootFile.h:414
edm::propagate_const< ProcessHistoryRegistry * > processHistoryRegistry_
Definition: RootFile.h:361
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2510
edm::propagate_const< std::unique_ptr< DaqProvenanceHelper > > daqProvenanceHelper_
Definition: RootFile.h:412
void updateTTreePointers(TTree *ev, TTree *meta, TTree *lumi, TTree *lumiMeta, TTree *run, TTree *runMeta, std::vector< TTree *> processBlockTrees, std::vector< std::string > processesWithProcessBlockTrees)
Definition: FileBlock.cc:6
edm::propagate_const< std::shared_ptr< RunAuxiliary > > savedRunAuxiliary_
Definition: RootFile.h:375
unsigned long long EventNumber_t
void setSignals(signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *preEventReadSource, signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *postEventReadSource)
Definition: RootTree.cc:520
void dropProcessesAndReorder(StoredProcessBlockHelper &, std::set< std::string > const &processesWithKeptProcessBlockProducts, ProcessBlockHelper const *)
Definition: RootFile.cc:2082
std::string const & processHistoryBranchName()
Definition: BranchType.cc:177
bool isValid() const
Definition: RootTree.cc:123
FullProvenanceReader(RootTree *rootTree, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:2359
EventAuxiliary eventAuxCache_
Definition: RootFile.h:383
EntryDescriptionMap const & entryDescriptionMap_
Definition: RootFile.cc:2420
std::shared_ptr< ProductProvenanceRetriever const > eventProductProvenanceRetriever(size_t index) const
Definition: RootFile.h:351
bool initializeFirstProcessBlockEntry()
Definition: RootFile.cc:1672
std::string const & productDependenciesBranchName()
Definition: BranchType.cc:165
edm::propagate_const< std::unique_ptr< EntryDescriptionMap > > entryDescriptionMap_
Definition: RootFile.cc:89
void initializeDuplicateChecker(std::vector< std::shared_ptr< IndexIntoFile >> const &indexesIntoFiles, std::vector< std::shared_ptr< IndexIntoFile >>::size_type currentIndexIntoFile)
Definition: RootFile.cc:1879
InputSource::ProcessingMode processingMode_
Definition: RootFile.h:399
~RootFileEventFinder() override
Definition: RootFile.cc:128
constexpr std::shared_ptr< T > & get_underlying_safe(propagate_const< std::shared_ptr< T >> &iP)
IndexIntoFile::IndexIntoFileItr indexIntoFileIter_
Definition: RootFile.h:371
void initialize(ProductSelectorRules const &rules, std::vector< BranchDescription const *> const &branchDescriptions)
void markBranchToBeDropped(bool dropDescendants, BranchDescription const &branch, std::set< BranchID > &branchesToDrop, std::map< BranchID, BranchID > const &droppedToKeptAlias) const
Definition: RootFile.cc:1926
bool fillEventHistory(EventAuxiliary &evtAux, EventSelectionIDVector &eventSelectionIDs, BranchListIndexes &branchListIndexes, bool assertOnFailure=true)
Definition: RootFile.cc:1338
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2505
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:2422
IndexIntoFile::IndexIntoFileItr indexIntoFileIter() const
Definition: RootFile.cc:819
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
StreamID streamID() const
assert(be >=bs)
void trainCache(char const *branchNames)
Definition: RootTree.cc:490
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:2423
~FullProvenanceReader() override
Definition: RootFile.cc:2341
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2515
std::string const & parameterSetMapBranchName()
Definition: BranchType.cc:168
uint16_t size_type
unsigned int LuminosityBlockNumber_t
DelayedReader * rootDelayedReader() const
Definition: RootTree.cc:147
edm::propagate_const< ProcessBlockHelper * > processBlockHelper_
Definition: RootFile.h:395
IndexIntoFileItr findEventPosition(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
std::shared_ptr< BranchChildren const > branchChildren() const
Definition: RootFile.h:348
std::string const & fileFormatVersionBranchName()
Definition: BranchType.cc:189
bool iterationWillBeInEntryOrder(SortOrder sortOrder) const
Used to determine whether or not to disable fast cloning.
MakeReducedProvenanceReader(std::vector< ParentageID > const &parentageIDLookup)
Definition: RootFile.cc:98
std::vector< EventSelectionID > EventSelectionIDVector
std::string const & productDescriptionBranchName()
Definition: BranchType.cc:162
edm::propagate_const< TClass * > edProductClass_
Definition: RootFile.h:413
FileFormatVersion fileFormatVersion_
Definition: RootFile.h:364
unsigned int currentProcessBlockTree_
Definition: RootFile.h:388
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
LuminosityBlockNumber_t luminosityBlock() const
Definition: EventID.h:39
void fillEventToProcessBlockIndexes()
Definition: RootFile.cc:1318
void setPosition(IndexIntoFile::IndexIntoFileItr const &position)
Definition: RootFile.cc:821
std::string const & branchIDListBranchName()
Definition: BranchType.cc:183
void updateFileBlock(FileBlock &)
Definition: RootFile.cc:792
void readProvenanceAsync(WaitingTaskHolder task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > *> &writeTo) const override
Definition: RootFile.cc:2492
void fillProcessBlockPrincipal(std::string const &processName, DelayedReader *reader=nullptr)
TBranch * branchEntryInfoBranch() const
Definition: RootTree.h:176
EventID const & id() const
std::vector< edm::propagate_const< std::shared_ptr< ProductProvenanceRetriever > > > eventProductProvenanceRetrievers_
Definition: RootFile.h:410
edm::propagate_const< RootTree * > rootTree_
Definition: RootFile.cc:2416
void setNumberOfEvents(EntryNumber_t nevents)
U second(std::pair< T, U > const &p)
std::vector< EventProcessHistoryID >::const_iterator eventProcessHistoryIter_
Definition: RootFile.h:374
void reduceProcessHistoryIDs(ProcessHistoryRegistry const &processHistoryRegistry)
std::string const & processHistoryMapBranchName()
Definition: BranchType.cc:174
bool skipThisEntry()
Definition: RootFile.cc:830
char const * label
bool dropProcessesAndReorderStored(StoredProcessBlockHelper &storedProcessBlockHelper, std::set< std::string > const &processesToKeep, std::vector< unsigned int > const &nEntries, std::vector< unsigned int > &finalIndexToStoredIndex, std::vector< std::string > const &firstFileFinalProcesses) const
FileID fid_
Definition: RootFile.h:365
long long EntryNumber_t
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:2215
std::string const logicalFile_
Definition: RootFile.h:359
std::vector< BranchListIndex > BranchListIndexes
IndexIntoFile::IndexIntoFileItr indexIntoFileEnd_
Definition: RootFile.h:370
void readParentageTree(InputType inputType)
Definition: RootFile.cc:686
std::vector< ProcessHistoryID > & setProcessHistoryIDs()
bool next()
Definition: RootTree.h:124
edm::propagate_const< std::unique_ptr< StoredMergeableRunProductMetadata > > storedMergeableRunProductMetadata_
Definition: RootFile.h:372
bool noEventSort_
Definition: RootFile.h:378
BranchID const & mapBranchID(BranchID const &branchID) const
void insertEntryForIndex(unsigned int index)
Definition: RootTree.cc:118
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
std::unique_ptr< ProvenanceReaderBase > makeReader(RootTree &eventTree, DaqProvenanceHelper const *daqProvenanceHelper) const override
Definition: RootFile.cc:2520
bool setEntryAtLumi(RunNumber_t run, LuminosityBlockNumber_t lumi)
Definition: RootFile.cc:1835
void setPresenceInProductRegistry(ProductRegistry &, StoredProcessBlockHelper const &)
Definition: RootFile.cc:1892
std::string friendlyName(std::string const &iFullName)
static constexpr RunNumber_t invalidRun
EventNumber_t getEventNumberOfEntry(roottree::EntryNumber entry) const override
Definition: RootFile.cc:130
void close()
Definition: RootFile.cc:1283
std::string const & branchName() const
bool hasThinnedAssociations() const
std::shared_ptr< std::recursive_mutex > mutex_
Definition: RootFile.cc:2355
std::set< ProductProvenance > readProvenance(unsigned int transitionIndex) const override
Definition: RootFile.cc:2452
IndexIntoFile::EntryNumber_t lastEventEntryNumberRead_
Definition: RootFile.h:391
void copyPosition(IndexIntoFileItr const &position)
Copy the position without modifying the pointer to the IndexIntoFile or size.
ShouldWriteRun shouldWriteRun() const
Definition: RunPrincipal.h:86
void skipEventBackward(int &phIndexOfEvent, RunNumber_t &runOfEvent, LuminosityBlockNumber_t &lumiOfEvent, EntryNumber_t &eventEntry)
void readProvenanceAsync(WaitingTaskHolder task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > *> &writeTo) const override
Definition: RootFile.cc:2294
Long64_t numEntries(TFile *hdl, std::string const &trname)
Definition: CollUtil.cc:50
edm::propagate_const< RootTree * > rootTree_
Definition: RootFile.cc:2210
bool useReducedProcessHistoryID() const
std::shared_ptr< RunAuxiliary > readRunAuxiliary_()
Definition: RootFile.cc:1594
SerialTaskQueueChain & serialQueueChain() const
std::shared_ptr< LuminosityBlockAuxiliary > readLuminosityBlockAuxiliary_()
Definition: RootFile.cc:1759
bool isEarlierRelease(std::string const &a, std::string const &b)
bool containsItem(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event) const
Definition: RootFile.cc:880
StoredProductProvenanceVector const * pProvVector_
Definition: RootFile.cc:2213
void fillProcessBlockHelper_()
Definition: RootFile.cc:1660
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:216
std::set< ProductProvenance > readProvenance(unsigned int transitionIndex) const override
Definition: RootFile.cc:2382
edm::propagate_const< std::unique_ptr< ProvenanceAdaptor > > provenanceAdaptor_
Definition: RootFile.h:408
std::set< ProductProvenance > readProvenance(unsigned int) const override
Definition: RootFile.cc:2308
bool processHistorySameWithinRun() const
static ServiceRegistry & instance()
std::string const & entryDescriptionBranchName()
Definition: BranchType.cc:151
edm::propagate_const< TBranch * > eventToProcessBlockIndexesBranch_
Definition: RootFile.h:404
EntryNumber const & entries() const
Definition: RootTree.h:134
std::shared_ptr< RunAuxiliary > fillRunAuxiliary()
Definition: RootFile.cc:1420
bool skipAnyEvents_
Definition: RootFile.h:376
void setSignals(signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *preEventReadSource, signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const *postEventReadSource)
Definition: RootFile.cc:2137
std::string const & BranchTypeToProductProvenanceBranchName(BranchType const &BranchType)
Definition: BranchType.cc:139
std::vector< std::string > const & processesWithProcessBlockProducts() const
bool empty() const
True if no runs, lumis, or events are in the file.
RootTree eventTree_
Definition: RootFile.h:384
std::map< ParameterSetID, ParameterSetID > ParameterSetIdConverter
void readProvenanceAsync(WaitingTaskHolder task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > *> &writeTo) const override
Definition: RootFile.cc:2368
ProcessHistoryID const & processHistoryID(int i) const
std::shared_ptr< FileBlock > createFileBlock()
Definition: RootFile.cc:766
std::vector< edm::propagate_const< RootTree * > > treePointers_
Definition: RootFile.h:389
unsigned int transitionIndex() const
bool insertMapped(value_type const &v, bool forceUpdate=false)
Definition: Registry.cc:32
bool storedProductProvenanceUsed() const
std::string const & parentageBranchName()
Definition: BranchType.cc:156
IndexIntoFile::EntryType getNextItemType(RunNumber_t &run, LuminosityBlockNumber_t &lumi, EventNumber_t &event)
Definition: RootFile.cc:884
bool isDuplicateEvent()
Definition: RootFile.cc:867
EventAuxiliary const & fillThisEventAuxiliary()
Definition: RootFile.cc:1294
std::string const & eventToProcessBlockIndexesBranchName()
Definition: BranchType.cc:214
bool isValid() const
Definition: FileID.h:18
bool selected(BranchDescription const &desc) const
bool nextProcessBlock_(ProcessBlockPrincipal &)
Definition: RootFile.cc:1683
ParentageID const & mapParentageID(ParentageID const &phid) const
std::string const & idToParameterSetBlobsBranchName()
Definition: BranchType.cc:218
std::vector< BranchID > const & parents() const
Hash< ProcessHistoryType > ProcessHistoryID
LuminosityBlockNumber_t lumi() const
edm::propagate_const< std::unique_ptr< History > > history_
Definition: RootFile.h:405
std::vector< ProductProvenance > ProductProvenanceVector
ProcessHistoryID const & processHistoryID() const
const int drop
std::string const & eventHistoryTreeName()
Definition: BranchType.cc:224
bool firstFileDropProcessesAndReorderStored(StoredProcessBlockHelper &storedProcessBlockHelper, std::set< std::string > const &processesToKeep, std::vector< unsigned int > const &nEntries, std::vector< unsigned int > &finalIndexToStoredIndex) const
virtual signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * preEventReadFromSourceSignal() const =0
IndexIntoFile & indexIntoFile_
Definition: RootFile.h:367
RootTree runTree_
Definition: RootFile.h:386
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:2356
edm::propagate_const< std::unique_ptr< MakeProvenanceReader > > provenanceReaderMaker_
Definition: RootFile.h:409
std::string const & file() const
Definition: RootFile.h:237
bool goToEvent(EventID const &eventID)
Definition: RootFile.cc:1496
std::string createGlobalIdentifier(bool binary=false)
std::string getReleaseVersion()
RunNumber_t run() const
Definition: EventID.h:38
void setAtEventEntry(IndexIntoFile::EntryNumber_t entry)
Definition: RootFile.cc:1592
void fixIndexes(std::vector< ProcessHistoryID > &processHistoryIDs)
std::string const & eventSelectionsBranchName()
Definition: BranchType.cc:210
std::vector< RunOrLumiEntry > & setRunOrLumiEntries()
void conversion(EventAux const &from, EventAuxiliary &to)
Definition: EventAux.cc:9
std::array< bool, NumBranchTypes > hasNewlyDroppedBranch_
Definition: RootFile.h:381
bool current() const
Definition: RootTree.h:126
std::string const & entryDescriptionIDBranchName()
Definition: BranchType.cc:149
bool wasFirstEventJustRead() const
Definition: RootFile.cc:935
static constexpr EntryNumber_t invalidEntry
LuminosityBlockNumber_t peekAheadAtLumi() const
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:392
void setIfFastClonable(int remainingEvents, int remainingLumis)
Definition: RootFile.cc:721
int whyNotFastClonable() const
Definition: RootFile.h:246
std::string const & processConfigurationBranchName()
Definition: BranchType.cc:180
std::vector< EventNumber_t > & unsortedEventNumbers()
bool readLuminosityBlock_(LuminosityBlockPrincipal &lumiPrincipal)
Definition: RootFile.cc:1797
MergeableRunProductMetadata * mergeableRunProductMetadata()
Definition: RunPrincipal.h:81
void fillBranchEntry(TBranch *branch, T *&pbuf)
Definition: RootTree.h:147
static constexpr LuminosityBlockNumber_t invalidLumi
bool modifiedIDs() const
Definition: RootFile.h:249
edm::propagate_const< std::shared_ptr< BranchChildren > > branchChildren_
Definition: RootFile.h:406
edm::propagate_const< std::shared_ptr< InputFile > > filePtr_
Definition: RootFile.h:362
std::string const & parentageTreeName()
Definition: BranchType.cc:154
void dropOnInputAndReorder(ProductRegistry &, ProductSelectorRules const &, bool dropDescendants, InputType, StoredProcessBlockHelper &, ProcessBlockHelper const *)
Definition: RootFile.cc:1937
std::vector< edm::propagate_const< std::unique_ptr< RootTree > > > processBlockTrees_
Definition: RootFile.h:387
double b
Definition: hdecay.h:118
bool readRun_(RunPrincipal &runPrincipal)
Definition: RootFile.cc:1719
ProductList & productListUpdator()
void setProcessHistoryID(ProcessHistoryID const &phid)
IndexIntoFile::EntryNumber_t EntryNumber
Definition: RootTree.h:42
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:2214
std::shared_ptr< std::recursive_mutex > mutex_
Definition: RootFile.cc:2216
~OldProvenanceReader() override
Definition: RootFile.cc:2407
std::shared_ptr< ProductProvenanceRetriever > makeProductProvenanceRetriever(unsigned int iStreamIndex)
Definition: RootFile.cc:2183
std::vector< StoredProductProvenance > StoredProductProvenanceVector
ShouldWriteLumi shouldWriteLumi() const
void readProcessBlock_(ProcessBlockPrincipal &)
Definition: RootFile.cc:1711
IndexIntoFile::IndexIntoFileItr indexIntoFileBegin_
Definition: RootFile.h:369
void fillEventPrincipal(EventAuxiliary const &aux, ProcessHistory const *processHistory, DelayedReader *reader=nullptr)
void doneFileInitialization()
Clears the temporary vector of event numbers to reduce memory usage.
std::string const & eventHistoryBranchName()
Definition: BranchType.cc:207
edm::propagate_const< RunHelperBase * > runHelper_
Definition: RootFile.h:400
bool branchListIndexesUnchanged_
Definition: RootFile.h:382
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:27
void fillIndexIntoFile()
Definition: RootFile.cc:996
HLT enums.
edm::propagate_const< TTree * > eventHistoryTree_
Definition: RootFile.h:402
void readAllFromSourceAndMergeImmediately(MergeableRunProductMetadata const *mergeableRunProductMetadata=nullptr)
Definition: Principal.cc:1004
std::vector< EventEntryInfo > * pInfoVector_
Definition: RootFile.cc:2419
unsigned int const defaultNonEventCacheSize
Definition: RootTree.h:39
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 noRunLumiSort, bool noEventSort, ProductSelectorRules const &productSelectorRules, InputType inputType, std::shared_ptr< BranchIDListHelper > branchIDListHelper, ProcessBlockHelper *, 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:145
double a
Definition: hdecay.h:119
static int position[264][3]
Definition: ReadPGInfo.cc:289
bool branchListIndexesUnchanged() const
Definition: RootFile.h:248
IndexIntoFileItr findRunPosition(RunNumber_t run) const
Same as findPosition.
RootTree const & runTree() const
Definition: RootFile.h:244
std::tuple< bool, bool > readCurrentEvent(EventPrincipal &cache, bool assertOnFailure=true)
Definition: RootFile.cc:1547
std::vector< ProcessHistoryID > & orderedProcessHistoryIDs_
Definition: RootFile.h:368
std::string const & entryDescriptionTreeName()
Definition: BranchType.cc:147
void initAssociationsFromSecondary(std::vector< BranchID > const &)
Definition: RootFile.cc:825
~DummyProvenanceReader() override
Definition: RootFile.cc:2476
IndexIntoFileItr findPosition(RunNumber_t run, LuminosityBlockNumber_t lumi=0U, EventNumber_t event=0U) const
void makeProcessBlockRootTrees(std::shared_ptr< InputFile > filePtr, int treeMaxVirtualSize, bool enablePrefetching, InputType inputType, StoredProcessBlockHelper const &storedProcessBlockHelper)
Definition: RootFile.cc:2143
edm::propagate_const< TBranch * > provBranch_
Definition: RootFile.cc:2211
std::unique_ptr< MakeProvenanceReader > makeProvenanceReaderMaker(InputType inputType)
Definition: RootFile.cc:2167
bool readEvent(EventPrincipal &cache)
Definition: RootFile.cc:1532
std::unique_ptr< WrapperBase > getWrapperBasePtr(void *p, int offset)
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:212
unsigned int RunNumber_t
std::vector< ParentageID > parentageIDLookup_
Definition: RootFile.h:411
LuminosityBlockAuxiliary const & aux() const
void fillRunPrincipal(ProcessHistoryRegistry const &processHistoryRegistry, DelayedReader *reader=nullptr)
Definition: RunPrincipal.cc:25
unsigned int value() const
Definition: StreamID.h:43
void resetTraining()
Definition: RootTree.h:182
bool setEntryAtEvent(RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event)
Definition: RootFile.cc:1827
Definition: tree.py:1
std::map< EntryDescriptionID, EventEntryDescription > EntryDescriptionMap
Definition: RootFile.h:62
std::vector< ParentageID > const & parentageIDLookup_
Definition: RootFile.cc:104
ReducedProvenanceReader(RootTree *iRootTree, std::vector< ParentageID > const &iParentageIDLookup, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:2220
Log< level::Warning, false > LogWarning
RootFileEventFinder(RootTree &eventTree)
Definition: RootFile.cc:127
edm::propagate_const< std::shared_ptr< BranchIDListHelper > > branchIDListHelper_
Definition: RootFile.h:394
std::string const & indexIntoFileBranchName()
Definition: BranchType.cc:198
bool endOfProcessBlocksReached() const
Definition: RootFile.cc:1681
void validateFile(InputType inputType, bool usingGoToEvent)
Definition: RootFile.cc:1221
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:116
std::set< ProductProvenance > readProvenance(unsigned int) const override
Definition: RootFile.cc:2488
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:547
static ParentageRegistry * instance()
OldProvenanceReader(RootTree *rootTree, EntryDescriptionMap const &theMap, DaqProvenanceHelper const *daqProvenanceHelper)
Definition: RootFile.cc:2426
SharedResourcesAcquirer acquirer_
Definition: RootFile.cc:2217
unsigned int const defaultLearningEntries
Definition: RootTree.h:40
void setEventFinder(std::shared_ptr< EventFinder > ptr)
void readProvenanceAsync(WaitingTaskHolder task, ModuleCallingContext const *moduleCallingContext, unsigned int transitionIndex, std::atomic< const std::set< ProductProvenance > *> &writeTo) const override
Definition: RootFile.cc:2438
std::vector< EventEntryInfo > infoVector_
Definition: RootFile.cc:2417
DelayedReader * resetAndGetRootDelayedReader() const
Definition: RootTree.cc:142
edm::propagate_const< std::unique_ptr< StoredProcessBlockHelper > > storedProcessBlockHelper_
Definition: RootFile.h:396
virtual signalslot::Signal< void(StreamContext const &, ModuleCallingContext const &)> const * postEventReadFromSourceSignal() const =0
void fillEventNumbersOrEntries(bool needEventNumbers, bool needEventEntries) const
ServiceToken presentToken() const
void setIsMergeable(BranchDescription &)
bool insertMapped(value_type const &v)
std::string const file_
Definition: RootFile.h:358
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:373
static Registry * instance()
Definition: Registry.cc:12
EventNumber_t event() const
Definition: EventID.h:40
DaqProvenanceHelper const * daqProvenanceHelper_
Definition: RootFile.cc:2421
Definition: event.py:1
void copyProduct(BranchDescription const &productdesc)
void readEventHistoryTree()
Definition: RootFile.cc:1868
void fillAux(T *&pAux)
Definition: RootTree.h:141
void push(oneapi::tbb::task_group &iGroup, T &&iAction)
asynchronously pushes functor iAction into queue
void setEntryNumber(EntryNumber theEntryNumber)
Definition: RootTree.cc:219
std::string const & thinnedAssociationsHelperBranchName()
Definition: BranchType.cc:186
std::vector< std::string > const & branchNames() const
Definition: RootTree.h:137
void reportOpened(std::string const &inputType)
Definition: RootFile.cc:1276