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
70 TFile* openTFile(
char const*
name,
int compressionLevel) {
71 TFile*
file = TFile::Open(name,
"recreate",
"", compressionLevel);
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),
91 filePtr_(openTFile(file_.c_str(), om_->compressionLevel())),
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);
133 filePtr_->SetCompressionAlgorithm(ROOT::kLZ4);
136 <<
"PoolOutputModule configured with unknown compression algorithm '" <<
om_->compressionAlgorithm() <<
"'\n"
137 <<
"Allowed compression algorithms are ZLIB, LZMA, LZ4, and ZSTD\n";
142 if (
om_->compactEventAuxiliary()) {
160 if (
om_->outputProcessBlockHelper().productsFromInputKept()) {
181 for (
auto&
item :
om_->selectedOutputItemList()[
i]) {
182 item.setProduct(
nullptr);
189 item.branchDescription()->produced());
207 std::vector<BranchDescription const*> branches;
208 branchNames.reserve(
om_->selectedOutputItemList()[
InEvent].size());
211 branchNames.push_back(
item.branchDescription()->branchName());
212 branches.push_back(
item.branchDescription());
215 sort_all(branches, sorterForJobReportHash);
217 std::ostringstream oss;
218 char const underscore =
'_';
219 for (
auto const& branch : branches) {
243 void maybeIssueWarning(
int whyNotFastClonable,
std::string const& ifileName,
std::string const& ofileName) {
253 bool isWarning =
true;
254 std::ostringstream message;
255 message <<
"Fast copying of file " << ifileName <<
" to file " << ofileName <<
" is disabled because:\n";
257 message <<
"a SecondaryFileSequence was specified.\n";
262 message <<
"the input file is in an old format.\n";
267 message <<
"events need to be sorted.\n";
271 message <<
"a run or a lumi is not contiguous in the input file.\n";
275 message <<
"events or lumis were selected or skipped by ID.\n";
280 message <<
"initial events, lumis or runs were skipped.\n";
285 message <<
"some events were skipped because of duplicate checking.\n";
289 message <<
"some events were not copied because of maxEvents limit.\n";
294 message <<
"some events were not copied because of maxLumis limit.\n";
299 message <<
"parallel processing was specified.\n";
304 message <<
"an EventSelector was specified.\n";
309 message <<
"some events were not copied because of maxEvents output limit.\n";
314 message <<
"the split level or basket size of a branch or branches was modified.\n";
318 message <<
"The format of a data product has changed.\n";
323 LogWarning(
"FastCloningDisabled") << message.str();
325 LogInfo(
"FastCloningDisabled") << message.str();
335 if (fb.
tree() !=
nullptr) {
338 if (remainingEvents >= 0 && remainingEvents < fb.
tree()->GetEntries()) {
344 if (
om_->overrideInputFileSplitLevels()) {
355 <<
"Merge failure because input file " <<
file_ <<
" has different ROOT split levels or basket sizes\n"
356 <<
"than previous files. To allow merging in spite of this, use the configuration parameter\n"
357 <<
"overrideInputFileSplitLevels=cms.untracked.bool(True)\n"
358 <<
"in every PoolOutputModule.\n";
370 constexpr
auto setSubBranchBasketConditions =
371 FileBlock::EventsOrLumisSelectedByID | FileBlock::InitialEventsSkipped | FileBlock::MaxEventsTooSmall |
372 FileBlock::MaxLumisTooSmall | FileBlock::EventSelectionUsed | FileBlock::OutputMaxEventsTooSmall |
375 if (
om_->inputFileCount() == 1) {
376 if (
om_->mergeJob()) {
380 filePtr_->SetCompressionSettings(
infile->GetCompressionSettings());
435 if (
om_->compactEventAuxiliary() &&
436 (
whyNotFastClonable_ & (FileBlock::EventsOrLumisSelectedByID | FileBlock::InitialEventsSkipped |
438 long long int reserve = remainingEvents;
439 if (fb.
tree() !=
nullptr) {
440 reserve = reserve > 0 ?
std::min(fb.
tree()->GetEntries(), reserve) : fb.
tree()->GetEntries();
450 if (not
om_->compactEventAuxiliary()) {
458 unsigned int const oneK = 1024;
460 return (size >=
om_->maxFileSize());
480 if (reg->anyProductProduced() || !
om_->wantAllEvents()) {
481 esids.push_back(
om_->selectorConfig());
486 unsigned int ttreeIndex =
InEvent;
508 if (
om_->compactEventAuxiliary()) {
531 unsigned int ttreeIndex =
InLumi;
554 unsigned int ttreeIndex =
InRun;
564 std::vector<std::string>
const& processesWithProcessBlockProducts =
565 om_->outputProcessBlockHelper().processesWithProcessBlockProducts();
566 std::vector<std::string>::const_iterator it =
567 std::find(processesWithProcessBlockProducts.cbegin(), processesWithProcessBlockProducts.cend(),
processName);
568 if (it == processesWithProcessBlockProducts.cend()) {
573 treePointers_[ttreeIndex]->optimizeBaskets(10ULL * 1024 * 1024);
586 orderedIDs[parentageID.second] = parentageID.first;
589 for (
auto const& orderedID : orderedIDs) {
617 ex <<
"The number of entries in at least one output TBranch whose entries\n"
618 "were copied from the input does not match the number of events\n"
619 "recorded in IndexIntoFile. This might (or might not) indicate a\n"
620 "problem related to fast copy.";
621 ex.
addContext(
"Calling RootOutputFile::writeIndexIntoFile");
668 ProductList& pList =
const_cast<ProductList&
>(pReg.productList());
669 for (
auto const& prod : pList) {
670 if (prod.second.branchID() != prod.second.originalBranchID()) {
677 for (ProductList::iterator it = pList.begin(); it != pList.end();) {
680 ProductList::iterator itCopy = it;
711 constexpr std::size_t maxEaBasketSize = 4 * 1024 * 1024;
713 if (
om_->compactEventAuxiliary()) {
717 tree->SetBranchStatus(bname,
true);
721 tree->SetBasketSize(bname, basketsize);
722 auto b =
tree->GetBranch(bname);
726 LogDebug(
"writeEventAuxiliary") <<
"EventAuxiliary ratio extras/GUIDs/all = "
731 const auto ea =
aux.eventAuxiliary();
741 if (!
om_->outputProcessBlockHelper().processesWithProcessBlockProducts().empty()) {
743 om_->outputProcessBlockHelper().processesWithProcessBlockProducts());
744 om_->outputProcessBlockHelper().fillCacheIndices(storedProcessBlockHelper);
770 processName =
om_->outputProcessBlockHelper().processesWithProcessBlockProducts()[
i -
InProcess];
780 treePointer->close();
781 treePointer =
nullptr;
794 if (tree && tree->GetNbranches() != 0) {
803 tree->SetAlias(alias.c_str(), full.c_str());
806 tree->SetAlias(
alias.c_str(), full.c_str());
816 std::set<BranchID>
const& iProducedIDs,
817 std::set<StoredProductProvenance>& oToFill) {
823 for (
auto const& parentID : parentIDs) {
828 (iProducedIDs.end() != iProducedIDs.find(info->
branchID()))) {
840 unsigned int ttreeIndex,
843 std::vector<std::unique_ptr<WrapperBase> > dummies;
847 bool const doProvenance =
852 std::set<StoredProductProvenance> provenanceToKeep;
858 std::set<BranchID> producedBranches;
861 for (
auto bd : preg->allBranchDescriptions()) {
862 if (
bd->produced() &&
bd->branchType() ==
InEvent) {
863 producedBranches.insert(
bd->branchID());
869 for (
auto&
item : items) {
870 BranchID const&
id =
item.branchDescription()->branchID();
873 bool produced =
item.branchDescription()->produced();
875 (produced || !fastCloning ||
treePointers_[ttreeIndex]->uncloned(
item.branchDescription()->branchName()));
876 bool keepProvenance = doProvenance && (produced || keepProvenanceForPrior);
883 if (result.
isValid() && keepProvenance) {
886 if (product ==
nullptr) {
889 TClass*
cp =
item.branchDescription()->wrappedType().getClass();
894 product = dummy.get();
897 item.setProduct(product);
899 if (keepProvenance && productProvenance ==
nullptr) {
902 if (productProvenance) {
904 insertAncestors(*productProvenance, provRetriever, produced, producedBranches, provenanceToKeep);
909 productProvenanceVecPtr->assign(provenanceToKeep.begin(), provenanceToKeep.end());
912 productProvenanceVecPtr->clear();
916 std::set<edm::StoredProductProvenance>& oToInsert) {
919 std::set<edm::StoredProductProvenance>::iterator itFound = oToInsert.find(toStore);
920 if (itFound == oToInsert.end()) {
922 std::pair<std::map<edm::ParentageID, unsigned int>::iterator,
bool>
i =
927 <<
"RootOutputFile::insertProductProvenance\n"
929 <<
" is out of bounds. The maximum value is currently " <<
parentageIDs_.size() - 1 <<
".\n"
930 <<
"This should never happen.\n"
931 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
934 oToInsert.insert(toStore);
PoolOutputModule::OutputItemList OutputItemList
EventNumber_t event() const
std::string const & branchName() const
void beginInputFile(FileBlock const &fb, int remainingEvents)
BranchID const & branchID() const
LuminosityBlockAuxiliary lumiAux_
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
EventID const & id() const
std::string const & processName() const
BranchType const & branchType() const
std::string const & parentageTreeName()
std::vector< BranchIDList > BranchIDLists
int eventAutoFlushSize() const
EventAuxiliary const & eventAuxiliary() const
void writeProcessHistoryRegistry()
void push_back(const EventAuxiliary &ea)
EventToProcessBlockIndexes const & eventToProcessBlockIndexes() const
size_type extrasSize() const
void insertAncestors(ProductProvenance const &iGetParents, ProductProvenanceRetriever const *iMapper, bool produced, std::set< BranchID > const &producedBranches, std::set< StoredProductProvenance > &oToFill)
void fillParameterSetBranch(TTree *parameterSetsTree, int basketSize)
std::map< BranchKey, BranchDescription > ProductList
bool checkSplitLevelsAndBasketSizes(TTree *inputTree) const
bool registerProcessHistory(ProcessHistory const &processHistory)
TTree const * tree() const
std::map< ParentageID, unsigned int > parentageIDs_
void fillProcessHistoryBranch(TTree *metaDataTree, int basketSize, ProcessHistoryRegistry const &processHistoryRegistry)
int whyNotFastClonable() const
void writeEventAuxiliary()
std::string const & fileFormatVersionBranchName()
edm::propagate_const< TTree * > metaDataTree_
unsigned long nEventsInLumi_
ProcessHistoryRegistry processHistoryRegistry_
ProductProvenance const * branchIDToProvenance(BranchID const &bid) const
std::string const & processName() const
ProductProvenance const * productProvenance() const
std::string const & eventSelectionsBranchName()
void writeLuminosityBlock(LuminosityBlockForOutput const &lb)
void reserve(std::size_t size)
void setAutoFlush(Long64_t size)
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
bool shouldWeCloseFile() const
constexpr Matriplex::idx_t LL
LuminosityBlockAuxiliary const & luminosityBlockAuxiliary() const
bool checkIfFastClonable(TTree *inputTree) const
void writeProcessBlockHelper()
std::set< BranchID > branchesWithStoredHistory_
std::vector< edm::propagate_const< RootOutputTree * > > treePointers_
std::vector< EventSelectionID > EventSelectionIDVector
void sortVector_Run_Or_Lumi_Entries()
LuminosityBlockNumber_t luminosityBlock() const
std::string const & parameterSetsTreeName()
RootOutputFile(PoolOutputModule *om, std::string const &fileName, std::string const &logicalFileName, std::vector< std::string > const &processesWithSelectedMergeableRunProducts)
std::vector< std::pair< BranchDescription const *, EDGetToken > > SelectedProducts
std::vector< BranchID > const & parents() const
void writeThinnedAssociationsHelper()
size_type guidsSize() const
unsigned int parentageIDIndex_
std::shared_ptr< TFile const > filePtr() const
RootOutputTree eventTree_
std::vector< BranchListIndex > BranchListIndexes
std::vector< OutputItemList > const & selectedOutputItemList() const
bool getMapped(key_type const &k, value_type &result) const
void addBranch(std::string const &branchName, std::string const &className, void const *&pProd, int splitLevel, int basketSize, bool produced)
edm::propagate_const< PoolOutputModule * > om_
virtual ProcessHistory const & processHistory() const
std::string const & moduleLabel() const
IndexIntoFile::EntryNumber_t eventEntryNumber_
std::string const & productInstanceName() const
std::string const & mergeableRunProductMetadataBranchName()
LuminosityBlockAuxiliary const * pLumiAux_
std::string const & indexIntoFileBranchName()
edm::propagate_const< std::shared_ptr< TFile > > filePtr_
void writeOne(EventForOutput const &e)
ProductProvenanceRetriever const * productProvenanceRetrieverPtr() const
int getFileFormatVersion()
EventSelectionIDVector const & eventSelectionIDs() const
bool checkEntriesInReadBranches(Long64_t expectedNumberOfEntries) const
void fillBranches(BranchType const &branchType, OccurrenceForOutput const &occurrence, unsigned int ttreeIndex, StoredProductProvenanceVector *productProvenanceVecPtr=nullptr, ProductProvenanceRetriever const *provRetriever=nullptr)
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
void setProcessHistoryID(ProcessHistoryID const &phid)
std::string const & metaDataTreeName()
CompactEventAuxiliaryVector compactEventAuxiliary_
LuminosityBlockNumber_t luminosityBlock() const
void addEntry(ProcessHistoryID const &processHistoryID, RunNumber_t run, LuminosityBlockNumber_t lumi, EventNumber_t event, EntryNumber_t entry)
edm::propagate_const< TClass * > wrapperBaseTClass_
bool isValid() const noexcept(true)
void writeProductDependencies()
void writeBranchIDListRegistry()
std::string const & eventToProcessBlockIndexesBranchName()
static TTree * makeTTree(TFile *filePtr, std::string const &name, int splitLevel)
ProcessHistoryID const & processHistoryID() const
std::string const & fullClassName() const
EventSelectionIDVector const * pEventSelectionIDs_
void setSubBranchBasketSizes(TTree *inputTree) const
std::string createGlobalIdentifier(bool binary=false)
Log< level::Info, false > LogInfo
edm::propagate_const< TTree * > parameterSetsTree_
StoredMergeableRunProductMetadata storedMergeableRunProductMetadata_
void writeStoredMergeableRunProductMetadata()
void writeIndexIntoFile()
void writeFileIdentifier()
RunAuxiliary const & runAuxiliary() const
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
edm::propagate_const< StoredProductProvenanceVector * > pEventEntryInfoVector_
WrapperBase const * wrapper() const noexcept(true)
std::string toString() const
std::string const & parentageBranchName()
LuminosityBlockNumber_t luminosityBlock() const
void addContext(std::string const &context)
edm::propagate_const< TTree * > parentageTree_
std::set< std::string > const & branchAliases() const
bool insertProductProvenance(const ProductProvenance &, std::set< StoredProductProvenance > &oToInsert)
void setException(std::exception_ptr e)
void addAuxiliary(std::string const &branchName, T const *&pAux, int bufSize, bool allowCloning=true)
std::vector< StoredProductProvenance > StoredProductProvenanceVector
void writeParameterSetRegistry()
void respondToCloseInputFile(FileBlock const &fb)
IndexIntoFile indexIntoFile_
BasicHandle getByToken(EDGetToken token, TypeID const &typeID) const
constexpr element_type const * get() const
std::string const & productDescriptionBranchName()
IndexIntoFile::EntryNumber_t runEntryNumber_
ParentageID const & parentageID() const
static void writeTTree(TTree *tree)
ProcessHistoryID const & processHistoryID() const
std::string moduleName(StableProvenance const &provenance, ProcessHistory const &history)
EventAuxiliary const * pEventAux_
void writeParentageRegistry()
std::exception_ptr getException()
void writeProductDescriptionRegistry()
std::string const & BranchTypeToProductProvenanceBranchName(BranchType const &BranchType)
std::string const & productDependenciesBranchName()
StoredProductProvenanceVector const * pEventEntryInfoVector() const
std::string const & thinnedAssociationsHelperBranchName()
BranchListIndexes const & branchListIndexes() const
void writeProcessBlock(ProcessBlockForOutput const &)
std::unique_ptr< WrapperBase > getWrapperBasePtr(void *p, int offset)
std::string const & branchIDListBranchName()
void setProcessHistoryID(ProcessHistoryID const &phid)
std::string const & branchListIndexesBranchName()
void writeFileFormatVersion()
Parentage const & parentage() const
BranchListIndexes const * pBranchListIndexes_
Log< level::Warning, false > LogWarning
void maybeFastCloneTree(bool canFastClone, bool canFastCloneAux, TTree *tree, std::string const &option)
LuminosityBlockID const & id() const
std::vector< edm::propagate_const< std::unique_ptr< RootOutputTree > > > processBlockTrees_
static ParentageRegistry * instance()
IndexIntoFile::EntryNumber_t lumiEntryNumber_
Provenance const * provenance() const noexcept(true)
void optimizeBaskets(ULong64_t size)
void writeRun(RunForOutput const &r)
std::string const & fileIdentifierBranchName()
MergeableRunProductMetadata const * mergeableRunProductMetadata() const
RunAuxiliary const * pRunAux_
std::string const & processBlockHelperBranchName()
std::string const & wrappedName() const
tuple size
Write out results.
EventNumber_t event() const
void setBranchAliases(TTree *tree, SelectedProducts const &branches, std::string const &processName) const
JobReport::Token reportToken_
EventToProcessBlockIndexes const * pEventToProcessBlockIndexes_
std::string const & fileName() const
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)