46 #include "Compression.h" 56 sorterForJobReportHash(BranchDescription
const*
lh, BranchDescription
const* rh) {
58 lh->fullClassName() < rh->fullClassName() ?
true :
59 lh->fullClassName() > rh->fullClassName() ?
false :
60 lh->moduleLabel() < rh->moduleLabel() ?
true :
61 lh->moduleLabel() > rh->moduleLabel() ?
false :
62 lh->productInstanceName() < rh->productInstanceName() ?
true :
63 lh->productInstanceName() > rh->productInstanceName() ?
false :
64 lh->processName() < rh->processName() ?
true :
70 TFile*
file = TFile::Open(name,
"recreate",
"", compressionLevel);
72 if(e != std::exception_ptr()) {
74 std::rethrow_exception(e);
82 std::vector<std::string>
const& processesWithSelectedMergeableRunProducts) :
84 logicalFile_(logicalFileName),
87 whyNotFastClonable_(om_->whyNotFastClonable()),
88 canFastCloneAux_(
false),
89 filePtr_(openTFile(file_.c_str(), om_->compressionLevel())),
91 eventEntryNumber_(0LL),
92 lumiEntryNumber_(0LL),
95 storedMergeableRunProductMetadata_(processesWithSelectedMergeableRunProducts),
103 pLumiAux_(&lumiAux_),
105 eventEntryInfoVector_(),
106 pEventEntryInfoVector_(&eventEntryInfoVector_),
111 runTree_(filePtr(),
InRun, om_->
splitLevel(), om_->treeMaxVirtualSize()),
113 dataTypeReported_(
false),
114 processHistoryRegistry_(),
116 branchesWithStoredHistory_(),
117 wrapperBaseTClass_(TClass::GetClass(
"edm::WrapperBase")) {
119 filePtr_->SetCompressionAlgorithm(ROOT::kZLIB);
121 filePtr_->SetCompressionAlgorithm(ROOT::kLZMA);
124 <<
"Allowed compression algorithms are ZLIB and LZMA\n";
151 for(
auto const& item :
om_->selectedOutputItemList()[
branchType]) {
152 item.product_ =
nullptr;
159 item.branchDescription_->produced());
176 std::vector<std::string> branchNames;
177 std::vector<BranchDescription const*> branches;
178 branchNames.reserve(
om_->selectedOutputItemList()[
InEvent].size());
180 for(
auto const& item :
om_->selectedOutputItemList()[
InEvent]) {
181 branchNames.push_back(item.branchDescription_->branchName());
182 branches.push_back(item.branchDescription_);
185 sort_all(branches, sorterForJobReportHash);
187 std::ostringstream oss;
188 char const underscore =
'_';
189 for(
auto const&
branch : branches) {
219 if ((whyNotFastClonable &
227 bool isWarning =
true;
228 std::ostringstream message;
229 message <<
"Fast copying of file " << ifileName <<
" to file " << ofileName <<
" is disabled because:\n";
231 message <<
"a SecondaryFileSequence was specified.\n";
236 message <<
"the input file is in an old format.\n";
241 message <<
"events need to be sorted.\n";
245 message <<
"a run or a lumi is not contiguous in the input file.\n";
249 message <<
"events or lumis were selected or skipped by ID.\n";
254 message <<
"initial events, lumis or runs were skipped.\n";
259 message <<
"some events were skipped because of duplicate checking.\n";
263 message <<
"some events were not copied because of maxEvents limit.\n";
268 message <<
"some events were not copied because of maxLumis limit.\n";
273 message <<
"parallel processing was specified.\n";
278 message <<
"an EventSelector was specified.\n";
283 message <<
"some events were not copied because of maxEvents output limit.\n";
288 message <<
"the split level or basket size of a branch or branches was modified.\n";
292 message <<
"The format of a data product has changed.\n";
297 LogWarning(
"FastCloningDisabled") << message.str();
299 LogInfo(
"FastCloningDisabled") << message.str();
310 if(fb.
tree() !=
nullptr) {
314 if(remainingEvents >= 0 && remainingEvents < fb.
tree()->GetEntries()) {
320 if(
om_->overrideInputFileSplitLevels()) {
329 assert(
om_->inputFileCount() > 1);
331 "Merge failure because input file " <<
file_ <<
" has different ROOT split levels or basket sizes\n" <<
332 "than previous files. To allow merging in splite of this, use the configuration parameter\n" <<
333 "overrideInputFileSplitLevels=cms.untracked.bool(True)\n" <<
334 "in every PoolOutputModule.\n";
392 unsigned int const oneK = 1024;
394 return(size >=
om_->maxFileSize());
413 if (reg->anyProductProduced() || !
om_->wantAllEvents()) {
414 esids.push_back(
om_->selectorConfig());
418 assert(provRetriever);
490 &desc,
om_->basketSize(), 0))
492 <<
"Failed to create a branch for Parentages in the output file";
498 orderedIDs[parentageID.second] = parentageID.first;
501 for(
auto const& orderedID : orderedIDs) {
528 ex <<
"The number of entries in at least one output TBranch whose entries\n" 529 "were copied from the input does not match the number of events\n" 530 "recorded in IndexIntoFile. This might (or might not) indicate a\n" 531 "problem related to fast copy.";
532 ex.
addContext(
"Calling RootOutputFile::writeIndexIntoFile");
577 ProductList& pList =
const_cast<ProductList &
>(pReg.productList());
578 for(
auto const&
prod : pList) {
579 if(
prod.second.branchID() !=
prod.second.originalBranchID()) {
586 for(ProductList::iterator it = pList.begin(); it != pList.end();) {
589 ProductList::iterator itCopy = it;
631 treePointer->close();
632 treePointer =
nullptr;
645 if(tree && tree->GetNbranches() != 0) {
652 tree->SetAlias(alias.c_str(), full.c_str());
655 tree->SetAlias(
alias.c_str(), full.c_str());
666 std::set<BranchID>
const &iProducedIDs,
667 std::set<StoredProductProvenance>& oToFill) {
672 for(
auto const& parentID : parentIDs) {
692 std::vector<std::unique_ptr<WrapperBase> > dummies;
700 std::set<StoredProductProvenance> provenanceToKeep;
706 std::set<BranchID> producedBranches;
709 for(
auto bd : preg->allBranchDescriptions()) {
710 if(bd->produced() && bd->branchType() ==
InEvent) {
711 producedBranches.insert(bd->branchID());
717 for(
auto const& item : items) {
719 BranchID const&
id = item.branchDescription_->branchID();
722 bool produced = item.branchDescription_->produced();
723 bool getProd = (produced || !fastCloning ||
treePointers_[
branchType]->uncloned(item.branchDescription_->branchName()));
724 bool keepProvenance = doProvenance && (produced || keepProvenanceForPrior);
732 if(found && keepProvenance) {
735 if(product ==
nullptr) {
738 TClass*
cp = item.branchDescription_->wrappedType().getClass();
739 assert(cp !=
nullptr);
743 product = dummy.get();
746 item.product_ = product;
748 if (keepProvenance && productProvenance ==
nullptr) {
749 productProvenance = provRetriever->
branchIDToProvenance(item.branchDescription_->originalBranchID());
751 if(productProvenance) {
753 insertAncestors(*productProvenance, provRetriever, produced, producedBranches, provenanceToKeep);
757 if(doProvenance) productProvenanceVecPtr->assign(provenanceToKeep.begin(), provenanceToKeep.end());
759 if(doProvenance) productProvenanceVecPtr->clear();
764 std::set<edm::StoredProductProvenance>& oToInsert) {
767 std::set<edm::StoredProductProvenance>::iterator itFound = oToInsert.find(toStore);
768 if(itFound == oToInsert.end()) {
774 <<
"RootOutputFile::insertProductProvenance\n" 775 <<
"The parentage ID index value " << toStore.
parentageIDIndex_ <<
" is out of bounds. The maximum value is currently " <<
parentageIDs_.size()-1 <<
".\n" 776 <<
"This should never happen.\n" 777 <<
"Please report this to the framework hypernews forum 'hn-cms-edmFramework@cern.ch'.\n";
780 oToInsert.insert(toStore);
EventNumber_t event() const
std::string const & branchName() const
void beginInputFile(FileBlock const &fb, int remainingEvents)
BranchID const & branchID() const
virtual ProcessHistory const & processHistory() const
LuminosityBlockAuxiliary lumiAux_
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
EventID const & id() const
std::string const & parentageTreeName()
std::vector< BranchIDList > BranchIDLists
int eventAutoFlushSize() const
EventAuxiliary const & eventAuxiliary() const
void writeProcessHistoryRegistry()
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)
void fillProcessHistoryBranch(TTree *metaDataTree, int basketSize, ProcessHistoryRegistry const &processHistoryRegistry)
int whyNotFastClonable() const
std::string const & fileFormatVersionBranchName()
edm::propagate_const< TTree * > metaDataTree_
unsigned long nEventsInLumi_
OutputItemListArray const & selectedOutputItemList() const
ProcessHistoryRegistry processHistoryRegistry_
std::string const & processName() const
BranchListIndexes const & branchListIndexes() const
ProductProvenance const * productProvenance() const
std::string const & eventSelectionsBranchName()
void writeLuminosityBlock(LuminosityBlockForOutput const &lb)
void setAutoFlush(Long64_t size)
bool shouldWeCloseFile() const
LuminosityBlockAuxiliary const & luminosityBlockAuxiliary() const
bool checkIfFastClonable(TTree *inputTree) const
std::set< BranchID > branchesWithStoredHistory_
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()
unsigned int parentageIDIndex_
std::map< ParentageID, unsigned int > parentageIDs_
bool getByToken(EDGetToken token, TypeID const &typeID, BasicHandle &result) const
RootOutputTree eventTree_
EventSelectionIDVector const & eventSelectionIDs() const
Provenance const * provenance() const
std::vector< BranchListIndex > BranchListIndexes
std::string moduleName(Provenance const &provenance)
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_
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)
WrapperBase const * wrapper() const
ProductProvenanceRetriever const * productProvenanceRetrieverPtr() const
int getFileFormatVersion()
bool checkEntriesInReadBranches(Long64_t expectedNumberOfEntries) const
ProcessHistoryID const & reducedProcessHistoryID(ProcessHistoryID const &fullID) const
void setProcessHistoryID(ProcessHistoryID const &phid)
std::string const & metaDataTreeName()
PoolOutputModule::OutputItemList OutputItemList
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_
void writeProductDependencies()
void writeBranchIDListRegistry()
static TTree * makeTTree(TFile *filePtr, std::string const &name, int splitLevel)
element_type const * get() const
std::string const & fullClassName() const
EventSelectionIDVector const * pEventSelectionIDs_
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_
void setBranchAliases(TTree *tree, SelectedProducts const &branches) const
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_
std::string const & productDescriptionBranchName()
IndexIntoFile::EntryNumber_t runEntryNumber_
ParentageID const & parentageID() const
static void writeTTree(TTree *tree)
ProcessHistoryID const & processHistoryID() const
EventAuxiliary const * pEventAux_
ProcessHistoryID const & processHistoryID() const
void writeParentageRegistry()
ProductProvenance const * branchIDToProvenance(BranchID const &bid) const
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()
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
RootOutputTreePtrArray treePointers_
BranchListIndexes const * pBranchListIndexes_
void maybeFastCloneTree(bool canFastClone, bool canFastCloneAux, TTree *tree, std::string const &option)
LuminosityBlockID const & id() const
static ParentageRegistry * instance()
IndexIntoFile::EntryNumber_t lumiEntryNumber_
void optimizeBaskets(ULong64_t size)
void writeRun(RunForOutput const &r)
std::string const & fileIdentifierBranchName()
MergeableRunProductMetadata const * mergeableRunProductMetadata() const
RunAuxiliary const * pRunAux_
std::string const & wrappedName() const
EventNumber_t event() const
def branchType(schema, name)
JobReport::Token reportToken_
std::string createGlobalIdentifier()
void fillBranches(BranchType const &branchType, OccurrenceForOutput const &occurrence, StoredProductProvenanceVector *productProvenanceVecPtr=0, ProductProvenanceRetriever const *provRetriever=0)
std::string const & fileName() const
std::string match(BranchDescription const &a, BranchDescription const &b, std::string const &fileName)