CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RootOutputFile.cc
Go to the documentation of this file.
1 
3 
5 
6 
33 
34 #include "TROOT.h"
35 #include "TTree.h"
36 #include "TFile.h"
37 #include "TClass.h"
38 #include "Rtypes.h"
39 #include "RVersion.h"
40 
41 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,30,0)
42 #include "Compression.h"
43 #endif
44 
45 #include <algorithm>
46 #include <iomanip>
47 #include <sstream>
48 
49 namespace edm {
50 
51  namespace {
52  bool
53  sorterForJobReportHash(BranchDescription const* lh, BranchDescription const* rh) {
54  return
55  lh->fullClassName() < rh->fullClassName() ? true :
56  lh->fullClassName() > rh->fullClassName() ? false :
57  lh->moduleLabel() < rh->moduleLabel() ? true :
58  lh->moduleLabel() > rh->moduleLabel() ? false :
59  lh->productInstanceName() < rh->productInstanceName() ? true :
60  lh->productInstanceName() > rh->productInstanceName() ? false :
61  lh->processName() < rh->processName() ? true :
62  false;
63  }
64  }
65 
67  file_(fileName),
68  logicalFile_(logicalFileName),
69  reportToken_(0),
70  om_(om),
71  whyNotFastClonable_(om_->whyNotFastClonable()),
72  canFastCloneAux_(false),
73  filePtr_(TFile::Open(file_.c_str(), "recreate", "", om_->compressionLevel())),
74  fid_(),
75  eventEntryNumber_(0LL),
76  lumiEntryNumber_(0LL),
77  runEntryNumber_(0LL),
78  indexIntoFile_(),
79  nEventsInLumi_(0),
80  metaDataTree_(nullptr),
81  parameterSetsTree_(nullptr),
82  parentageTree_(nullptr),
83  lumiAux_(),
84  runAux_(),
85  pEventAux_(nullptr),
86  pLumiAux_(&lumiAux_),
87  pRunAux_(&runAux_),
88  eventEntryInfoVector_(),
89  pEventEntryInfoVector_(&eventEntryInfoVector_),
90  pBranchListIndexes_(nullptr),
91  pEventSelectionIDs_(nullptr),
92  eventTree_(filePtr_, InEvent, om_->splitLevel(), om_->treeMaxVirtualSize()),
93  lumiTree_(filePtr_, InLumi, om_->splitLevel(), om_->treeMaxVirtualSize()),
94  runTree_(filePtr_, InRun, om_->splitLevel(), om_->treeMaxVirtualSize()),
95  treePointers_(),
96  dataTypeReported_(false),
97  processHistoryRegistry_(),
98  parentageIDs_(),
99  branchesWithStoredHistory_() {
100 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,30,0)
101  if (om_->compressionAlgorithm() == std::string("ZLIB")) {
102  filePtr_->SetCompressionAlgorithm(ROOT::kZLIB);
103  } else if (om_->compressionAlgorithm() == std::string("LZMA")) {
104  filePtr_->SetCompressionAlgorithm(ROOT::kLZMA);
105  } else {
106  throw Exception(errors::Configuration) << "PoolOutputModule configured with unknown compression algorithm '" << om_->compressionAlgorithm() << "'\n"
107  << "Allowed compression algorithms are ZLIB and LZMA\n";
108  }
109 #endif
110  if (-1 != om->eventAutoFlushSize()) {
112  }
114  pEventAux_, om_->auxItems()[InEvent].basketSize_);
116  pEventEntryInfoVector_, om_->auxItems()[InEvent].basketSize_);
118  pEventSelectionIDs_, om_->auxItems()[InEvent].basketSize_,false);
120  pBranchListIndexes_, om_->auxItems()[InEvent].basketSize_);
121 
123  pLumiAux_, om_->auxItems()[InLumi].basketSize_);
124 
126  pRunAux_, om_->auxItems()[InRun].basketSize_);
127 
129  treePointers_[InLumi] = &lumiTree_;
130  treePointers_[InRun] = &runTree_;
131 
132  for(int i = InEvent; i < NumBranchTypes; ++i) {
133  BranchType branchType = static_cast<BranchType>(i);
134  RootOutputTree *theTree = treePointers_[branchType];
135  for(auto const& item : om_->selectedOutputItemList()[branchType]) {
136  item.product_ = nullptr;
137  BranchDescription const& desc = *item.branchDescription_;
138  theTree->addBranch(desc.branchName(),
139  desc.wrappedName(),
140  desc.getInterface(),
141  item.product_,
142  item.splitLevel_,
143  item.basketSize_,
144  item.branchDescription_->produced());
145  //make sure we always store product registry info for all branches we create
146  branchesWithStoredHistory_.insert(item.branchID());
147  }
148  }
149  // Don't split metadata tree or event description tree
153 
155 
156  // For the Job Report, get a vector of branch names in the "Events" tree.
157  // Also create a hash of all the branch names in the "Events" tree
158  // in a deterministic order, except use the full class name instead of the friendly class name.
159  // To avoid extra string copies, we create a vector of pointers into the product registry,
160  // and use a custom comparison operator for sorting.
161  std::vector<std::string> branchNames;
162  std::vector<BranchDescription const*> branches;
163  branchNames.reserve(om_->selectedOutputItemList()[InEvent].size());
164  branches.reserve(om->selectedOutputItemList()[InEvent].size());
165  for(auto const& item : om_->selectedOutputItemList()[InEvent]) {
166  branchNames.push_back(item.branchDescription_->branchName());
167  branches.push_back(item.branchDescription_);
168  }
169  // Now sort the branches for the hash.
170  sort_all(branches, sorterForJobReportHash);
171  // Now, make a concatenated string.
172  std::ostringstream oss;
173  char const underscore = '_';
174  for(auto const& branch : branches) {
175  BranchDescription const& bd = *branch;
176  oss << bd.fullClassName() << underscore
177  << bd.moduleLabel() << underscore
178  << bd.productInstanceName() << underscore
179  << bd.processName() << underscore;
180  }
181  std::string stringrep = oss.str();
182  cms::Digest md5alg(stringrep);
183 
184  // Register the output file with the JobReport service
185  // and get back the token for it.
186  std::string moduleName = "PoolOutputModule";
187  Service<JobReport> reportSvc;
188  reportToken_ = reportSvc->outputFileOpened(
189  file_, logicalFile_, // PFN and LFN
190  om_->catalog(), // catalog
191  moduleName, // module class name
192  om_->moduleLabel(), // module label
193  fid_.fid(), // file id (guid)
194  std::string(), // data type (not yet known, so string is empty).
195  md5alg.digest().toString(), // branch hash
196  branchNames); // branch names being written
197  }
198 
199  namespace {
200  void
201  maybeIssueWarning(int whyNotFastClonable, std::string const& ifileName, std::string const& ofileName) {
202 
203  // No message if fast cloning was deliberately disabled, or if there are no events to copy anyway.
204  if ((whyNotFastClonable &
206  return;
207  }
208 
209  // There will be a message stating every reason that fast cloning was not possible.
210  // If at one or more of the reasons was because of something the user explicitly specified (e.g. event selection, skipping events),
211  // or if the input file was in an old format, the message will be informational. Otherwise, the message will be a warning.
212  bool isWarning = true;
213  std::ostringstream message;
214  message << "Fast copying of file " << ifileName << " to file " << ofileName << " is disabled because:\n";
215  if((whyNotFastClonable & FileBlock::HasSecondaryFileSequence) != 0) {
216  message << "a SecondaryFileSequence was specified.\n";
217  whyNotFastClonable &= ~(FileBlock::HasSecondaryFileSequence);
218  isWarning = false;
219  }
220  if((whyNotFastClonable & FileBlock::FileTooOld) != 0) {
221  message << "the input file is in an old format.\n";
222  whyNotFastClonable &= ~(FileBlock::FileTooOld);
223  isWarning = false;
224  }
225  if((whyNotFastClonable & FileBlock::EventsToBeSorted) != 0) {
226  message << "events need to be sorted.\n";
227  whyNotFastClonable &= ~(FileBlock::EventsToBeSorted);
228  }
229  if((whyNotFastClonable & FileBlock::RunOrLumiNotContiguous) != 0) {
230  message << "a run or a lumi is not contiguous in the input file.\n";
231  whyNotFastClonable &= ~(FileBlock::RunOrLumiNotContiguous);
232  }
233  if((whyNotFastClonable & FileBlock::EventsOrLumisSelectedByID) != 0) {
234  message << "events or lumis were selected or skipped by ID.\n";
235  whyNotFastClonable &= ~(FileBlock::EventsOrLumisSelectedByID);
236  isWarning = false;
237  }
238  if((whyNotFastClonable & FileBlock::InitialEventsSkipped) != 0) {
239  message << "initial events, lumis or runs were skipped.\n";
240  whyNotFastClonable &= ~(FileBlock::InitialEventsSkipped);
241  isWarning = false;
242  }
243  if((whyNotFastClonable & FileBlock::DuplicateEventsRemoved) != 0) {
244  message << "some events were skipped because of duplicate checking.\n";
245  whyNotFastClonable &= ~(FileBlock::DuplicateEventsRemoved);
246  }
247  if((whyNotFastClonable & FileBlock::MaxEventsTooSmall) != 0) {
248  message << "some events were not copied because of maxEvents limit.\n";
249  whyNotFastClonable &= ~(FileBlock::MaxEventsTooSmall);
250  isWarning = false;
251  }
252  if((whyNotFastClonable & FileBlock::MaxLumisTooSmall) != 0) {
253  message << "some events were not copied because of maxLumis limit.\n";
254  whyNotFastClonable &= ~(FileBlock::MaxLumisTooSmall);
255  isWarning = false;
256  }
257  if((whyNotFastClonable & FileBlock::ParallelProcesses) != 0) {
258  message << "parallel processing was specified.\n";
259  whyNotFastClonable &= ~(FileBlock::ParallelProcesses);
260  isWarning = false;
261  }
262  if((whyNotFastClonable & FileBlock::EventSelectionUsed) != 0) {
263  message << "an EventSelector was specified.\n";
264  whyNotFastClonable &= ~(FileBlock::EventSelectionUsed);
265  isWarning = false;
266  }
267  if((whyNotFastClonable & FileBlock::OutputMaxEventsTooSmall) != 0) {
268  message << "some events were not copied because of maxEvents output limit.\n";
269  whyNotFastClonable &= ~(FileBlock::OutputMaxEventsTooSmall);
270  isWarning = false;
271  }
272  if((whyNotFastClonable & FileBlock::SplitLevelMismatch) != 0) {
273  message << "the split level or basket size of a branch or branches was modified.\n";
274  whyNotFastClonable &= ~(FileBlock::SplitLevelMismatch);
275  }
276  if((whyNotFastClonable & FileBlock::BranchMismatch) != 0) {
277  message << "The format of a data product has changed.\n";
278  whyNotFastClonable &= ~(FileBlock::BranchMismatch);
279  }
280  assert(whyNotFastClonable == FileBlock::CanFastClone);
281  if (isWarning) {
282  LogWarning("FastCloningDisabled") << message.str();
283  } else {
284  LogInfo("FastCloningDisabled") << message.str();
285  }
286  }
287  }
288 
289  void RootOutputFile::beginInputFile(FileBlock const& fb, int remainingEvents) {
290 
291  // Reset per input file information
293  canFastCloneAux_ = false;
294 
295  if(fb.tree() != nullptr) {
296 
298 
299  if(remainingEvents >= 0 && remainingEvents < fb.tree()->GetEntries()) {
301  }
302 
304  if(!match) {
306  // We may be fast copying. We must disable fast copying if the split levels
307  // or basket sizes do not match.
309  } else {
310  // We are using the input split levels and basket sizes from the first input file
311  // for copied output branches. In this case, we throw an exception if any branches
312  // have different split levels or basket sizes in a subsequent input file.
313  // If the mismatch is in the first file, there is a bug somewhere, so we assert.
314  assert(om_->inputFileCount() > 1);
315  throw Exception(errors::MismatchedInputFiles, "RootOutputFile::beginInputFile()") <<
316  "Merge failure because input file " << file_ << " has different ROOT split levels or basket sizes\n" <<
317  "than previous files. To allow merging in splite of this, use the configuration parameter\n" <<
318  "overrideInputFileSplitLevels=cms.untracked.bool(True)\n" <<
319  "in every PoolOutputModule.\n";
320  }
321  }
322 
323  // Since this check can be time consuming, we do it only if we would otherwise fast clone.
325  if(!eventTree_.checkIfFastClonable(fb.tree())) {
327  }
328  }
329  // We now check if we can fast copy the auxiliary branches.
330  // We can do so only if we can otherwise fast copy,
331  // the input file has the current format (these branches are in the Events Tree),
332  // there are no newly dropped or produced products,
333  // no metadata has been dropped,
334  // ID's have not been modified,
335  // and the branch list indexes do not need modification.
336 
337  // Note: Fast copy of the EventProductProvenance branch is unsafe
338  // unless we can enforce that the parentage information for a fully copied
339  // output file will be the same as for the input file, with nothing dropped.
340  // This has never been enforced, and, withthe EDAlias feature, it may no longer
341  // work by accident.
342  // So, for now, we do not enable fast cloning of the non-product branches.
343 /*
344  Service<ConstProductRegistry> reg;
345  canFastCloneAux_ = (whyNotFastClonable_ == FileBlock::CanFastClone) &&
346  fb.fileFormatVersion().noMetaDataTrees() &&
347  !om_->hasNewlyDroppedBranch()[InEvent] &&
348  !fb.hasNewlyDroppedBranch()[InEvent] &&
349  om_->dropMetaData() == PoolOutputModule::DropNone &&
350  !reg->anyProductProduced() &&
351  !fb.modifiedIDs() &&
352  fb.branchListIndexesUnchanged();
353 */
354 
355  // Report the fast copying status.
356  Service<JobReport> reportSvc;
357  reportSvc->reportFastCopyingStatus(reportToken_, fb.fileName(), whyNotFastClonable_ == FileBlock::CanFastClone);
358  } else {
360  }
361 
363 
364  // Possibly issue warning or informational message if we haven't fast cloned.
365  if(fb.tree() != nullptr && whyNotFastClonable_ != FileBlock::CanFastClone) {
366  maybeIssueWarning(whyNotFastClonable_, fb.fileName(), file_);
367  }
368  }
369 
374  }
375 
377  unsigned int const oneK = 1024;
378  Long64_t size = filePtr_->GetSize()/oneK;
379  return(size >= om_->maxFileSize());
380  }
381 
383  ModuleCallingContext const* mcc) {
384  // Auxiliary branch
385  pEventAux_ = &e.aux();
386 
387  // Because getting the data may cause an exception to be thrown we want to do that
388  // first before writing anything to the file about this event
389  // NOTE: pEventAux_, pBranchListIndexes_, pEventSelectionIDs_, and pEventEntryInfoVector_
390  // must be set before calling fillBranches since they get written out in that routine.
391  assert(pEventAux_->processHistoryID() == e.processHistoryID());
393 
394  // Note: The EventSelectionIDVector should have a one to one correspondence with the processes in the process history.
395  // Therefore, a new entry should be added if and only if the current process has been added to the process history,
396  // which is done if and only if there is a produced product.
399  if (reg->anyProductProduced() || !om_->wantAllEvents()) {
400  esids.push_back(om_->selectorConfig());
401  }
402  pEventSelectionIDs_ = &esids;
404 
405  // Add the dataType to the job report if it hasn't already been done
406  if(!dataTypeReported_) {
407  Service<JobReport> reportSvc;
408  std::string dataType("MC");
409  if(pEventAux_->isRealData()) dataType = "Data";
410  reportSvc->reportDataType(reportToken_, dataType);
411  dataTypeReported_ = true;
412  }
413 
414  // Store the process history.
416  // Store the reduced ID in the IndexIntoFile
418  // Add event to index
421 
422  // Report event written
423  Service<JobReport> reportSvc;
424  reportSvc->eventWrittenToFile(reportToken_, e.id().run(), e.id().event());
425  ++nEventsInLumi_;
426  }
427 
429  // Auxiliary branch
430  // NOTE: lumiAux_ must be filled before calling fillBranches since it gets written out in that routine.
431  lumiAux_ = lb.aux();
432  // Use the updated process historyID
434  // Store the process history.
436  // Store the reduced ID in the IndexIntoFile
438  // Add lumi to index.
441  fillBranches(InLumi, lb, nullptr, mcc);
442  lumiTree_.optimizeBaskets(10ULL*1024*1024);
443 
444  Service<JobReport> reportSvc;
445  reportSvc->reportLumiSection(reportToken_, lb.id().run(), lb.id().luminosityBlock(),nEventsInLumi_);
446  nEventsInLumi_ = 0;
447  }
448 
450  // Auxiliary branch
451  // NOTE: runAux_ must be filled before calling fillBranches since it gets written out in that routine.
452  runAux_ = r.aux();
453  // Use the updated process historyID
455  // Store the process history.
457  // Store the reduced ID in the IndexIntoFile
459  // Add run to index.
460  indexIntoFile_.addEntry(reducedPHID, runAux_.run(), 0U, 0U, runEntryNumber_);
461  ++runEntryNumber_;
462  fillBranches(InRun, r, nullptr, mcc);
463  runTree_.optimizeBaskets(10ULL*1024*1024);
464 
465  Service<JobReport> reportSvc;
466  reportSvc->reportRunNumber(reportToken_, r.run());
467  }
468 
470  Parentage const* desc(nullptr);
471 
472  if(!parentageTree_->Branch(poolNames::parentageBranchName().c_str(),
473  &desc, om_->basketSize(), 0))
475  << "Failed to create a branch for Parentages in the output file";
476 
478 
479  std::vector<ParentageID> orderedIDs(parentageIDs_.size());
480  for(auto const& parentageID : parentageIDs_) {
481  orderedIDs[parentageID.second] = parentageID.first;
482  }
483  //now put them into the TTree in the correct order
484  for(auto const& orderedID : orderedIDs) {
485  desc = ptReg.getMapped(orderedID);
486  //NOTE: some old format files have missing Parentage info
487  // so a null value of desc can't be fatal.
488  // Root will default construct an object in that case.
489  parentageTree_->Fill();
490  }
491  }
492 
494  FileFormatVersion fileFormatVersion(getFileFormatVersion());
495  FileFormatVersion* pFileFmtVsn = &fileFormatVersion;
496  TBranch* b = metaDataTree_->Branch(poolNames::fileFormatVersionBranchName().c_str(), &pFileFmtVsn, om_->basketSize(), 0);
497  assert(b);
498  b->Fill();
499  }
500 
502  FileID* fidPtr = &fid_;
503  TBranch* b = metaDataTree_->Branch(poolNames::fileIdentifierBranchName().c_str(), &fidPtr, om_->basketSize(), 0);
504  assert(b);
505  b->Fill();
506  }
507 
511  ex << "The number of entries in at least one output TBranch whose entries\n"
512  "were copied from the input does not match the number of events\n"
513  "recorded in IndexIntoFile. This might (or might not) indicate a\n"
514  "problem related to fast copy.";
515  ex.addContext("Calling RootOutputFile::writeIndexIntoFile");
516  throw ex;
517  }
519  IndexIntoFile* iifPtr = &indexIntoFile_;
520  TBranch* b = metaDataTree_->Branch(poolNames::indexIntoFileBranchName().c_str(), &iifPtr, om_->basketSize(), 0);
521  assert(b);
522  b->Fill();
523  }
524 
526  ProcessHistoryVector procHistoryVector;
527  for(auto const& ph : processHistoryRegistry_) {
528  procHistoryVector.push_back(ph.second);
529  }
530  ProcessHistoryVector* p = &procHistoryVector;
531  TBranch* b = metaDataTree_->Branch(poolNames::processHistoryBranchName().c_str(), &p, om_->basketSize(), 0);
532  assert(b);
533  b->Fill();
534  }
535 
537  BranchIDLists const* p = om_->branchIDLists();
538  TBranch* b = metaDataTree_->Branch(poolNames::branchIDListBranchName().c_str(), &p, om_->basketSize(), 0);
539  assert(b);
540  b->Fill();
541  }
542 
544  std::pair<ParameterSetID, ParameterSetBlob> idToBlob;
545  std::pair<ParameterSetID, ParameterSetBlob>* pIdToBlob = &idToBlob;
546  TBranch* b = parameterSetsTree_->Branch(poolNames::idToParameterSetBlobsBranchName().c_str(),&pIdToBlob,om_->basketSize(), 0);
547 
548  for(auto const& pset : *pset::Registry::instance()) {
549  idToBlob.first = pset.first;
550  idToBlob.second.pset() = pset.second.toString();
551 
552  b->Fill();
553  }
554  }
555 
557  // Make a local copy of the ProductRegistry, removing any transient or pruned products.
558  typedef ProductRegistry::ProductList ProductList;
560  ProductRegistry pReg(reg->productList());
561  ProductList& pList = const_cast<ProductList &>(pReg.productList());
562  for(auto const& prod : pList) {
563  if(prod.second.branchID() != prod.second.originalBranchID()) {
564  if(branchesWithStoredHistory_.find(prod.second.branchID()) != branchesWithStoredHistory_.end()) {
565  branchesWithStoredHistory_.insert(prod.second.originalBranchID());
566  }
567  }
568  }
569  std::set<BranchID>::iterator end = branchesWithStoredHistory_.end();
570  for(ProductList::iterator it = pList.begin(); it != pList.end();) {
571  if(branchesWithStoredHistory_.find(it->second.branchID()) == end) {
572  // avoid invalidating iterator on deletion
573  ProductList::iterator itCopy = it;
574  ++it;
575  pList.erase(itCopy);
576 
577  } else {
578  ++it;
579  }
580  }
581 
582  ProductRegistry* ppReg = &pReg;
583  TBranch* b = metaDataTree_->Branch(poolNames::productDescriptionBranchName().c_str(), &ppReg, om_->basketSize(), 0);
584  assert(b);
585  b->Fill();
586  }
588  BranchChildren& pDeps = const_cast<BranchChildren&>(om_->branchChildren());
589  BranchChildren* ppDeps = &pDeps;
590  TBranch* b = metaDataTree_->Branch(poolNames::productDependenciesBranchName().c_str(), &ppDeps, om_->basketSize(), 0);
591  assert(b);
592  b->Fill();
593  }
594 
596  metaDataTree_->SetEntries(-1);
599 
601 
602  // Create branch aliases for all the branches in the
603  // events/lumis/runs trees. The loop is over all types of data
604  // products.
605  for(int i = InEvent; i < NumBranchTypes; ++i) {
606  BranchType branchType = static_cast<BranchType>(i);
608  treePointers_[branchType]->writeTree();
609  }
610 
611  // close the file -- mfp
612  // Just to play it safe, zero all pointers to objects in the TFile to be closed.
613  metaDataTree_ = parentageTree_ = nullptr;
614  for(auto& treePointer : treePointers_) {
615  treePointer->close();
616  treePointer = nullptr;
617  }
618  filePtr_->Close();
619  filePtr_.reset();
620 
621  // report that file has been closed
622  Service<JobReport> reportSvc;
623  reportSvc->outputFileClosed(reportToken_);
624 
625  }
626 
627  void
628  RootOutputFile::setBranchAliases(TTree* tree, SelectedProducts const& branches) const {
629  if(tree && tree->GetNbranches() != 0) {
630  for(auto const& selection : branches) {
631  BranchDescription const& pd = *selection;
632  std::string const& full = pd.branchName() + "obj";
633  if(pd.branchAliases().empty()) {
634  std::string const& alias =
635  (pd.productInstanceName().empty() ? pd.moduleLabel() : pd.productInstanceName());
636  tree->SetAlias(alias.c_str(), full.c_str());
637  } else {
638  for(auto const& alias : pd.branchAliases()) {
639  tree->SetAlias(alias.c_str(), full.c_str());
640  }
641  }
642  }
643  }
644  }
645 
646  void
648  EventPrincipal const& principal,
649  bool produced,
650  std::set<StoredProductProvenance>& oToFill,
651  ModuleCallingContext const* mcc) {
653  assert(produced || om_->dropMetaData() != PoolOutputModule::DropPrior);
655  ProductProvenanceRetriever const& iMapper = *principal.productProvenanceRetrieverPtr();
656  std::vector<BranchID> const& parentIDs = iGetParents.parentage().parents();
657  for(auto const& parentID : parentIDs) {
658  branchesWithStoredHistory_.insert(parentID);
659  ProductProvenance const* info = iMapper.branchIDToProvenance(parentID);
660  if(info) {
662  principal.getProvenance(info->branchID(), mcc).product().produced()) {
663  if(insertProductProvenance(*info,oToFill) ) {
664  //haven't seen this one yet
665  insertAncestors(*info, principal, produced, oToFill, mcc);
666  }
667  }
668  }
669  }
670  }
671 
673  BranchType const& branchType,
674  Principal const& principal,
675  StoredProductProvenanceVector* productProvenanceVecPtr,
676  ModuleCallingContext const* mcc) {
677 
678  typedef std::vector<std::pair<TClass*, void const*> > Dummies;
679  Dummies dummies;
680 
681  bool const fastCloning = (branchType == InEvent) && (whyNotFastClonable_ == FileBlock::CanFastClone);
682 
684 
685  std::set<StoredProductProvenance> provenanceToKeep;
686 
687  // Loop over EDProduct branches, fill the provenance, and write the branch.
688  for(auto const& item : items) {
689 
690  BranchID const& id = item.branchDescription_->branchID();
691  branchesWithStoredHistory_.insert(id);
692 
693  bool produced = item.branchDescription_->produced();
694  bool keepProvenance = productProvenanceVecPtr != nullptr &&
698  bool getProd = (produced || !fastCloning ||
699  treePointers_[branchType]->uncloned(item.branchDescription_->branchName()));
700 
701  void const* product = nullptr;
702  OutputHandle const oh = principal.getForOutput(id, getProd, mcc);
703  if(keepProvenance && oh.productProvenance()) {
704  insertProductProvenance(*oh.productProvenance(),provenanceToKeep);
705  //provenanceToKeep.insert(*oh.productProvenance());
706  EventPrincipal const& eventPrincipal = dynamic_cast<EventPrincipal const&>(principal);
707  assert(eventPrincipal.productProvenanceRetrieverPtr());
708  insertAncestors(*oh.productProvenance(), eventPrincipal, produced, provenanceToKeep, mcc);
709  }
710  product = oh.wrapper();
711  if(getProd) {
712  if(product == nullptr) {
713  // No product with this ID is in the event.
714  // Add a null product.
715  TClass* cp = gROOT->GetClass(item.branchDescription_->wrappedName().c_str());
716  product = cp->New();
717  dummies.emplace_back(cp, product);
718  }
719  item.product_ = product;
720  }
721  }
722 
723  if(productProvenanceVecPtr != nullptr) productProvenanceVecPtr->assign(provenanceToKeep.begin(), provenanceToKeep.end());
724  treePointers_[branchType]->fillTree();
725  if(productProvenanceVecPtr != nullptr) productProvenanceVecPtr->clear();
726  for(auto& dummy : dummies) {
727  dummy.first->Destructor(const_cast<void *>(dummy.second));
728  }
729  }
730 
731  bool
733  std::set<edm::StoredProductProvenance>& oToInsert) {
734  StoredProductProvenance toStore;
735  toStore.branchID_ = iProv.branchID().id();
736  std::set<edm::StoredProductProvenance>::iterator itFound = oToInsert.find(toStore);
737  if(itFound == oToInsert.end()) {
738  //get the index to the ParentageID or insert a new value if not already present
739  std::pair<std::map<edm::ParentageID,unsigned int>::iterator,bool> i = parentageIDs_.insert(std::make_pair(iProv.parentageID(),static_cast<unsigned int>(parentageIDs_.size())));
740  toStore.parentageIDIndex_ = i.first->second;
741  if(toStore.parentageIDIndex_ >= parentageIDs_.size()) {
743  << "RootOutputFile::insertProductProvenance\n"
744  << "The parentage ID index value " << toStore.parentageIDIndex_ << " is out of bounds. The maximum value is currently " << parentageIDs_.size()-1 << ".\n"
745  << "This should never happen.\n"
746  << "Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
747  }
748 
749  oToInsert.insert(toStore);
750  return true;
751  }
752  return false;
753  }
754 }
BranchIDLists const * branchIDLists() const
RunNumber_t run() const
Definition: EventID.h:42
std::vector< ProcessHistory > ProcessHistoryVector
EventNumber_t event() const
Definition: EventID.h:44
void fillBranches(BranchType const &branchType, Principal const &principal, StoredProductProvenanceVector *productProvenanceVecPtr, ModuleCallingContext const *)
std::string const & idToParameterSetBlobsBranchName()
Definition: BranchType.cc:249
int i
Definition: DBlmapReader.cc:9
std::string const & branchName() const
bool isRealData() const
void beginInputFile(FileBlock const &fb, int remainingEvents)
BranchID const & branchID() const
LuminosityBlockAuxiliary lumiAux_
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:114
int const & basketSize() const
static const TGPicture * info(bool iBackgroundIsBlack)
EventSelectionIDVector const & eventSelectionIDs() const
bool const & overrideInputFileSplitLevels() const
std::string const & parentageTreeName()
Definition: BranchType.cc:158
std::vector< BranchIDList > BranchIDLists
Definition: BranchIDList.h:19
int eventAutoFlushSize() const
std::string const & catalog() const
void writeProcessHistoryRegistry()
std::string const & moduleLabel() const
void writeRun(RunPrincipal const &r, ModuleCallingContext const *)
DropMetaData const & dropMetaData() const
std::map< BranchKey, BranchDescription > ProductList
bool checkSplitLevelsAndBasketSizes(TTree *inputTree) const
bool registerProcessHistory(ProcessHistory const &processHistory)
selection
main part
Definition: corrVsCorr.py:98
void writeOne(EventPrincipal const &e, ModuleCallingContext const *)
EventID const & id() const
Provenance getProvenance(ProductID const &pid, ModuleCallingContext const *mcc) const
ProductProvenance const * productProvenance() const
Definition: OutputHandle.h:101
int whyNotFastClonable() const
Definition: FileBlock.h:104
RunNumber_t run() const
LuminosityBlockAuxiliary const & aux() const
std::string const & fileFormatVersionBranchName()
Definition: BranchType.cc:212
unsigned long nEventsInLumi_
OutputItemListArray const & selectedOutputItemList() const
ProcessHistoryRegistry processHistoryRegistry_
std::string const & processName() const
std::string const & eventSelectionsBranchName()
Definition: BranchType.cc:237
RunNumber_t run() const
Definition: RunPrincipal.h:61
bool int lh
Definition: SIMDVec.h:19
unsigned int const & maxFileSize() const
MD5Result digest() const
Definition: Digest.cc:194
void setAutoFlush(Long64_t size)
#define nullptr
ParameterSetID selectorConfig() const
BranchListIndexes const & branchListIndexes() const
bool shouldWeCloseFile() const
unsigned int id() const
Definition: BranchID.h:23
bool checkIfFastClonable(TTree *inputTree) const
ProcessHistory const & processHistory() const
Definition: Principal.h:139
void addBranch(std::string const &branchName, std::string const &className, WrapperInterfaceBase const *interface, void const *&pProd, int splitLevel, int basketSize, bool produced)
BranchType
Definition: BranchType.h:11
std::set< BranchID > branchesWithStoredHistory_
std::vector< EventSelectionID > EventSelectionIDVector
void sortVector_Run_Or_Lumi_Entries()
LuminosityBlockNumber_t luminosityBlock() const
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:245
std::vector< BranchID > const & parents() const
Definition: Parentage.h:37
std::map< ParentageID, unsigned int > parentageIDs_
RootOutputTree eventTree_
std::vector< BranchListIndex > BranchListIndexes
std::string moduleName(Provenance const &provenance)
Definition: Provenance.cc:27
bool getMapped(key_type const &k, value_type &result) const
PoolOutputModule const * om_
std::string const & compressionAlgorithm() const
std::string const & moduleLabel() const
IndexIntoFile::EntryNumber_t eventEntryNumber_
std::string const & productInstanceName() const
ProcessHistoryID const & processHistoryID() const
Definition: Principal.h:143
void insertAncestors(ProductProvenance const &iGetParents, EventPrincipal const &principal, bool produced, std::set< StoredProductProvenance > &oToFill, ModuleCallingContext const *)
LuminosityBlockAuxiliary const * pLumiAux_
std::string const & indexIntoFileBranchName()
Definition: BranchType.cc:227
std::string const & basketOrder() const
Definition: GenABIO.cc:180
RunNumber_t run() const
int getFileFormatVersion()
void const * wrapper() const
Definition: OutputHandle.h:89
std::string logicalFile_
SelectedProductsForBranchType const & keptProducts() const
bool checkEntriesInReadBranches(Long64_t expectedNumberOfEntries) const
WrapperInterfaceBase const * getInterface() const
RunAuxiliary const & aux() const
Definition: RunPrincipal.h:57
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
void setProcessHistoryID(ProcessHistoryID const &phid)
#define end
Definition: vmac.h:37
std::string const & metaDataTreeName()
Definition: BranchType.cc:167
PoolOutputModule::OutputItemList OutputItemList
LuminosityBlockNumber_t luminosityBlock() const
void addEntry(ProcessHistoryID const &processHistoryID, RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry)
static TTree * makeTTree(TFile *filePtr, std::string const &name, int splitLevel)
int const & whyNotFastClonable() const
std::string const & fullClassName() const
std::string const & processHistoryBranchName()
Definition: BranchType.cc:197
EventSelectionIDVector const * pEventSelectionIDs_
StoredProductProvenanceVector * pEventEntryInfoVector_
OutputHandle getForOutput(BranchID const &bid, bool getProd, ModuleCallingContext const *mcc) const
Definition: Principal.cc:716
eventsetup::produce::Produce produced
Definition: ESProducts.cc:20
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:120
BranchChildren const & branchChildren() const
void setBranchAliases(TTree *tree, SelectedProducts const &branches) const
boost::shared_ptr< ProductProvenanceRetriever > productProvenanceRetrieverPtr() const
RootOutputTree runTree_
std::string toString() const
Definition: Digest.cc:87
std::string const & parentageBranchName()
Definition: BranchType.cc:162
double b
Definition: hdecay.h:120
LuminosityBlockNumber_t luminosityBlock() const
string const
Definition: compareJSON.py:14
void addContext(std::string const &context)
Definition: Exception.cc:227
AuxItemArray const & auxItems() const
std::set< std::string > const & branchAliases() const
bool insertProductProvenance(const ProductProvenance &, std::set< StoredProductProvenance > &oToInsert)
void addAuxiliary(std::string const &branchName, T const *&pAux, int bufSize, bool allowCloning=true)
std::vector< StoredProductProvenance > StoredProductProvenanceVector
void respondToCloseInputFile(FileBlock const &fb)
IndexIntoFile indexIntoFile_
std::string const & productDescriptionBranchName()
Definition: BranchType.cc:172
IndexIntoFile::EntryNumber_t runEntryNumber_
ParentageID const & parentageID() const
static void writeTTree(TTree *tree)
ProcessHistoryID const & processHistoryID() const
EventAuxiliary const * pEventAux_
RunAuxiliary runAux_
std::vector< BranchDescription const * > SelectedProducts
ProductProvenance const * branchIDToProvenance(BranchID const &bid) const
void writeProductDescriptionRegistry()
std::string const & BranchTypeToProductProvenanceBranchName(BranchType const &BranchType)
Definition: BranchType.cc:130
std::string const & productDependenciesBranchName()
Definition: BranchType.cc:177
RootOutputFile(PoolOutputModule *om, std::string const &fileName, std::string const &logicalFileName)
std::string const & branchIDListBranchName()
Definition: BranchType.cc:207
void setProcessHistoryID(ProcessHistoryID const &phid)
Definition: RunAuxiliary.h:36
std::string const & branchListIndexesBranchName()
Definition: BranchType.cc:241
Parentage const & parentage() const
RootOutputTreePtrArray treePointers_
volatile std::atomic< bool > shutdown_flag false
BranchListIndexes const * pBranchListIndexes_
void writeLuminosityBlock(LuminosityBlockPrincipal const &lb, ModuleCallingContext const *)
void maybeFastCloneTree(bool canFastClone, bool canFastCloneAux, TTree *tree, std::string const &option)
static ParentageRegistry * instance()
IndexIntoFile::EntryNumber_t lumiEntryNumber_
RootOutputTree lumiTree_
boost::shared_ptr< TFile > filePtr_
void optimizeBaskets(ULong64_t size)
EventAuxiliary const & aux() const
TTree * tree() const
Definition: FileBlock.h:97
std::string const & fileIdentifierBranchName()
Definition: BranchType.cc:217
RunAuxiliary const * pRunAux_
std::string const & wrappedName() const
tuple size
Write out results.
EventNumber_t event() const
RunNumber_t run() const
Definition: RunAuxiliary.h:41
int const & inputFileCount() const
static Registry * instance()
Definition: Registry.cc:14
JobReport::Token reportToken_
std::string createGlobalIdentifier()
std::string const & fileName() const
Definition: FileBlock.h:106
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)