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_(0LL),
94 lumiEntryNumber_(0LL),
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());
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) {
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() &&
408 (
whyNotFastClonable_ & (FileBlock::EventsOrLumisSelectedByID | FileBlock::InitialEventsSkipped |
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()) {
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);
742 processName =
om_->outputProcessBlockHelper().processesWithProcessBlockProducts()[
i -
InProcess];
752 treePointer->close();
753 treePointer =
nullptr;
766 if (tree && tree->GetNbranches() != 0) {
775 tree->SetAlias(alias.c_str(), full.c_str());
778 tree->SetAlias(
alias.c_str(), full.c_str());
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());
841 for (
auto&
item : items) {
842 BranchID const&
id =
item.branchDescription()->branchID();
845 bool produced =
item.branchDescription()->produced();
847 (produced || !fastCloning ||
treePointers_[ttreeIndex]->uncloned(
item.branchDescription()->branchName()));
848 bool keepProvenance = doProvenance && (produced || keepProvenanceForPrior);
855 if (result.
isValid() && keepProvenance) {
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);
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
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_
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)