CMS 3D CMS Logo

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