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