CMS 3D CMS Logo

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