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