50 #include "Compression.h"
59 bool sorterForJobReportHash(BranchDescription
const*
lh, BranchDescription
const* rh) {
60 return lh->fullClassName() < rh->fullClassName() ?
true
61 :
lh->fullClassName() > rh->fullClassName() ?
false
62 :
lh->moduleLabel() < rh->moduleLabel() ?
true
63 :
lh->moduleLabel() > rh->moduleLabel() ?
false
64 :
lh->productInstanceName() < rh->productInstanceName() ?
true
65 :
lh->productInstanceName() > rh->productInstanceName() ?
false
66 :
lh->processName() < rh->processName() ?
true
73 if (
e != std::exception_ptr()) {
75 std::rethrow_exception(
e);
84 std::vector<std::string>
const& processesWithSelectedMergeableRunProducts)
86 logicalFile_(logicalFileName),
89 whyNotFastClonable_(om_->whyNotFastClonable()),
90 canFastCloneAux_(
false),
93 eventEntryNumber_(0
LL),
94 lumiEntryNumber_(0
LL),
97 storedMergeableRunProductMetadata_(processesWithSelectedMergeableRunProducts),
99 metaDataTree_(nullptr),
100 parameterSetsTree_(nullptr),
101 parentageTree_(nullptr),
105 pLumiAux_(&lumiAux_),
107 eventEntryInfoVector_(),
108 pEventEntryInfoVector_(&eventEntryInfoVector_),
109 pBranchListIndexes_(nullptr),
110 pEventSelectionIDs_(nullptr),
113 runTree_(filePtr(),
InRun, om_->
splitLevel(), om_->treeMaxVirtualSize()),
114 dataTypeReported_(
false),
115 processHistoryRegistry_(),
117 branchesWithStoredHistory_(),
118 wrapperBaseTClass_(TClass::GetClass(
"edm::WrapperBase")) {
119 std::vector<std::string>
const& processesWithProcessBlockProducts =
120 om_->outputProcessBlockHelper().processesWithProcessBlockProducts();
121 for (
auto const&
processName : processesWithProcessBlockProducts) {
127 filePtr_->SetCompressionAlgorithm(ROOT::kZLIB);
129 filePtr_->SetCompressionAlgorithm(ROOT::kLZMA);
131 filePtr_->SetCompressionAlgorithm(ROOT::kZSTD);
134 <<
"PoolOutputModule configured with unknown compression algorithm '" <<
om_->compressionAlgorithm() <<
"'\n"
135 <<
"Allowed compression algorithms are ZLIB, LZMA, and ZSTD\n";
140 if (
om_->compactEventAuxiliary()) {
158 if (
om_->outputProcessBlockHelper().productsFromInputKept()) {
179 for (
auto&
item :
om_->selectedOutputItemList()[
i]) {
180 item.setProduct(
nullptr);
187 item.branchDescription()->produced());
204 std::vector<std::string> branchNames;
205 std::vector<BranchDescription const*> branches;
206 branchNames.reserve(
om_->selectedOutputItemList()[
InEvent].size());
209 branchNames.push_back(
item.branchDescription()->branchName());
210 branches.push_back(
item.branchDescription());
213 sort_all(branches, sorterForJobReportHash);
215 std::ostringstream oss;
216 char const underscore =
'_';
217 for (
auto const&
branch : branches) {
219 oss <<
bd.fullClassName() << underscore <<
bd.moduleLabel() << underscore <<
bd.productInstanceName()
220 << underscore <<
bd.processName() << underscore;
241 void maybeIssueWarning(
int whyNotFastClonable,
std::string const& ifileName,
std::string const& ofileName) {
251 bool isWarning =
true;
252 std::ostringstream message;
253 message <<
"Fast copying of file " << ifileName <<
" to file " << ofileName <<
" is disabled because:\n";
255 message <<
"a SecondaryFileSequence was specified.\n";
260 message <<
"the input file is in an old format.\n";
265 message <<
"events need to be sorted.\n";
269 message <<
"a run or a lumi is not contiguous in the input file.\n";
273 message <<
"events or lumis were selected or skipped by ID.\n";
278 message <<
"initial events, lumis or runs were skipped.\n";
283 message <<
"some events were skipped because of duplicate checking.\n";
287 message <<
"some events were not copied because of maxEvents limit.\n";
292 message <<
"some events were not copied because of maxLumis limit.\n";
297 message <<
"parallel processing was specified.\n";
302 message <<
"an EventSelector was specified.\n";
307 message <<
"some events were not copied because of maxEvents output limit.\n";
312 message <<
"the split level or basket size of a branch or branches was modified.\n";
316 message <<
"The format of a data product has changed.\n";
321 LogWarning(
"FastCloningDisabled") << message.str();
323 LogInfo(
"FastCloningDisabled") << message.str();
333 if (fb.
tree() !=
nullptr) {
336 if (remainingEvents >= 0 && remainingEvents < fb.
tree()->GetEntries()) {
342 if (
om_->overrideInputFileSplitLevels()) {
353 <<
"Merge failure because input file " <<
file_ <<
" has different ROOT split levels or basket sizes\n"
354 <<
"than previous files. To allow merging in splite of this, use the configuration parameter\n"
355 <<
"overrideInputFileSplitLevels=cms.untracked.bool(True)\n"
356 <<
"in every PoolOutputModule.\n";
407 if (
om_->compactEventAuxiliary() &&
410 long long int reserve = remainingEvents;
411 if (fb.
tree() !=
nullptr) {
412 reserve = reserve > 0 ?
std::min(fb.
tree()->GetEntries(), reserve) : fb.
tree()->GetEntries();
422 if (not
om_->compactEventAuxiliary()) {
430 unsigned int const oneK = 1024;
432 return (
size >=
om_->maxFileSize());
452 if (reg->anyProductProduced() || !
om_->wantAllEvents()) {
453 esids.push_back(
om_->selectorConfig());
458 unsigned int ttreeIndex =
InEvent;
480 if (
om_->compactEventAuxiliary()) {
486 reportSvc->eventWrittenToFile(
reportToken_,
e.id().run(),
e.id().event());
503 unsigned int ttreeIndex =
InLumi;
526 unsigned int ttreeIndex =
InRun;
536 std::vector<std::string>
const& processesWithProcessBlockProducts =
537 om_->outputProcessBlockHelper().processesWithProcessBlockProducts();
538 std::vector<std::string>::const_iterator it =
539 std::find(processesWithProcessBlockProducts.cbegin(), processesWithProcessBlockProducts.cend(),
processName);
540 if (it == processesWithProcessBlockProducts.cend()) {
545 treePointers_[ttreeIndex]->optimizeBaskets(10ULL * 1024 * 1024);
558 orderedIDs[parentageID.second] = parentageID.first;
561 for (
auto const& orderedID : orderedIDs) {
589 ex <<
"The number of entries in at least one output TBranch whose entries\n"
590 "were copied from the input does not match the number of events\n"
591 "recorded in IndexIntoFile. This might (or might not) indicate a\n"
592 "problem related to fast copy.";
593 ex.
addContext(
"Calling RootOutputFile::writeIndexIntoFile");
640 ProductList& pList = const_cast<ProductList&>(pReg.productList());
641 for (
auto const&
prod : pList) {
642 if (
prod.second.branchID() !=
prod.second.originalBranchID()) {
649 for (ProductList::iterator it = pList.begin(); it != pList.end();) {
652 ProductList::iterator itCopy = it;
683 constexpr std::size_t maxEaBasketSize = 4 * 1024 * 1024;
685 if (
om_->compactEventAuxiliary()) {
689 tree->SetBranchStatus(bname,
true);
693 tree->SetBasketSize(bname, basketsize);
694 auto b =
tree->GetBranch(bname);
698 LogDebug(
"writeEventAuxiliary") <<
"EventAuxiliary ratio extras/GUIDs/all = "
703 const auto ea =
aux.eventAuxiliary();
713 if (!
om_->outputProcessBlockHelper().processesWithProcessBlockProducts().empty()) {
715 om_->outputProcessBlockHelper().processesWithProcessBlockProducts());
716 om_->outputProcessBlockHelper().fillCacheIndices(storedProcessBlockHelper);
740 branchType = static_cast<BranchType>(
i);
752 treePointer->close();
753 treePointer =
nullptr;
766 if (
tree &&
tree->GetNbranches() != 0) {
788 std::set<BranchID>
const& iProducedIDs,
789 std::set<StoredProductProvenance>& oToFill) {
795 for (
auto const& parentID : parentIDs) {
800 (iProducedIDs.end() != iProducedIDs.find(
info->branchID()))) {
812 unsigned int ttreeIndex,
815 std::vector<std::unique_ptr<WrapperBase> > dummies;
819 bool const doProvenance =
824 std::set<StoredProductProvenance> provenanceToKeep;
830 std::set<BranchID> producedBranches;
833 for (
auto bd : preg->allBranchDescriptions()) {
834 if (
bd->produced() &&
bd->branchType() ==
InEvent) {
835 producedBranches.insert(
bd->branchID());
842 BranchID const&
id =
item.branchDescription()->branchID();
845 bool produced =
item.branchDescription()->produced();
848 bool keepProvenance = doProvenance && (produced || keepProvenanceForPrior);
854 product =
result.wrapper();
855 if (
result.isValid() && keepProvenance) {
856 productProvenance =
result.provenance()->productProvenance();
858 if (product ==
nullptr) {
861 TClass*
cp =
item.branchDescription()->wrappedType().getClass();
866 product =
dummy.get();
869 item.setProduct(product);
871 if (keepProvenance && productProvenance ==
nullptr) {
874 if (productProvenance) {
876 insertAncestors(*productProvenance, provRetriever, produced, producedBranches, provenanceToKeep);
881 productProvenanceVecPtr->assign(provenanceToKeep.begin(), provenanceToKeep.end());
884 productProvenanceVecPtr->clear();
888 std::set<edm::StoredProductProvenance>& oToInsert) {
891 std::set<edm::StoredProductProvenance>::iterator itFound = oToInsert.find(toStore);
892 if (itFound == oToInsert.end()) {
894 std::pair<std::map<edm::ParentageID, unsigned int>::iterator,
bool>
i =
899 <<
"RootOutputFile::insertProductProvenance\n"
901 <<
" is out of bounds. The maximum value is currently " <<
parentageIDs_.size() - 1 <<
".\n"
902 <<
"This should never happen.\n"
903 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
906 oToInsert.insert(toStore);