File indexing completed on 2025-04-22 06:27:33
0001 #include "IOPool/Output/interface/PoolOutputModule.h"
0002
0003 #include "IOPool/Output/src/RootOutputFile.h"
0004
0005 #include "FWCore/Framework/interface/EventForOutput.h"
0006 #include "FWCore/Framework/interface/LuminosityBlockForOutput.h"
0007 #include "FWCore/Framework/interface/RunForOutput.h"
0008 #include "FWCore/Framework/interface/FileBlock.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0012 #include "FWCore/ServiceRegistry/interface/Service.h"
0013 #include "DataFormats/Provenance/interface/ProductDescription.h"
0014 #include "DataFormats/Provenance/interface/Parentage.h"
0015 #include "DataFormats/Provenance/interface/ParentageRegistry.h"
0016 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0017 #include "FWCore/Framework/interface/ProductProvenanceRetriever.h"
0018 #include "FWCore/Utilities/interface/Algorithms.h"
0019 #include "FWCore/Utilities/interface/EDMException.h"
0020 #include "FWCore/Utilities/interface/TimeOfDay.h"
0021 #include "FWCore/Utilities/interface/WrappedClassName.h"
0022
0023 #include "TTree.h"
0024 #include "TBranchElement.h"
0025 #include "TObjArray.h"
0026 #include "RVersion.h"
0027 #include "TDictAttributeMap.h"
0028
0029 #include <fstream>
0030 #include <iomanip>
0031 #include <sstream>
0032 #include "boost/algorithm/string.hpp"
0033
0034 namespace edm {
0035 PoolOutputModule::PoolOutputModule(ParameterSet const& pset)
0036 : edm::one::OutputModuleBase::OutputModuleBase(pset),
0037 one::OutputModule<WatchInputFiles>(pset),
0038 rootServiceChecker_(),
0039 auxItems_(),
0040 selectedOutputItemList_(),
0041 fileName_(pset.getUntrackedParameter<std::string>("fileName")),
0042 logicalFileName_(pset.getUntrackedParameter<std::string>("logicalFileName")),
0043 catalog_(pset.getUntrackedParameter<std::string>("catalog")),
0044 maxFileSize_(pset.getUntrackedParameter<int>("maxSize")),
0045 compressionLevel_(pset.getUntrackedParameter<int>("compressionLevel")),
0046 compressionAlgorithm_(pset.getUntrackedParameter<std::string>("compressionAlgorithm")),
0047 basketSize_(pset.getUntrackedParameter<int>("basketSize")),
0048 eventAuxBasketSize_(pset.getUntrackedParameter<int>("eventAuxiliaryBasketSize")),
0049 eventAutoFlushSize_(pset.getUntrackedParameter<int>("eventAutoFlushCompressedSize")),
0050 splitLevel_(std::min<int>(pset.getUntrackedParameter<int>("splitLevel") + 1, 99)),
0051 basketOrder_(pset.getUntrackedParameter<std::string>("sortBaskets")),
0052 treeMaxVirtualSize_(pset.getUntrackedParameter<int>("treeMaxVirtualSize")),
0053 whyNotFastClonable_(pset.getUntrackedParameter<bool>("fastCloning") ? FileBlock::CanFastClone
0054 : FileBlock::DisabledInConfigFile),
0055 dropMetaData_(DropNone),
0056 moduleLabel_(pset.getParameter<std::string>("@module_label")),
0057 initializedFromInput_(false),
0058 outputFileCount_(0),
0059 inputFileCount_(0),
0060 branchParents_(),
0061 productDependencies_(),
0062 overrideInputFileSplitLevels_(pset.getUntrackedParameter<bool>("overrideInputFileSplitLevels")),
0063 compactEventAuxiliary_(pset.getUntrackedParameter<bool>("compactEventAuxiliary")),
0064 mergeJob_(pset.getUntrackedParameter<bool>("mergeJob")),
0065 rootOutputFile_(),
0066 statusFileName_(),
0067 overrideGUID_(pset.getUntrackedParameter<std::string>("overrideGUID")) {
0068 if (pset.getUntrackedParameter<bool>("writeStatusFile")) {
0069 std::ostringstream statusfilename;
0070 statusfilename << moduleLabel_ << '_' << getpid();
0071 statusFileName_ = statusfilename.str();
0072 }
0073
0074 std::string dropMetaData(pset.getUntrackedParameter<std::string>("dropMetaData"));
0075 if (dropMetaData.empty())
0076 dropMetaData_ = DropNone;
0077 else if (dropMetaData == std::string("NONE"))
0078 dropMetaData_ = DropNone;
0079 else if (dropMetaData == std::string("DROPPED"))
0080 dropMetaData_ = DropDroppedPrior;
0081 else if (dropMetaData == std::string("PRIOR"))
0082 dropMetaData_ = DropPrior;
0083 else if (dropMetaData == std::string("ALL"))
0084 dropMetaData_ = DropAll;
0085 else {
0086 throw edm::Exception(errors::Configuration, "Illegal dropMetaData parameter value: ")
0087 << dropMetaData << ".\n"
0088 << "Legal values are 'NONE', 'DROPPED', 'PRIOR', and 'ALL'.\n";
0089 }
0090
0091 if (!wantAllEvents()) {
0092 whyNotFastClonable_ += FileBlock::EventSelectionUsed;
0093 }
0094
0095 auto const& specialSplit{pset.getUntrackedParameterSetVector("overrideBranchesSplitLevel")};
0096
0097 specialSplitLevelForBranches_.reserve(specialSplit.size());
0098 for (auto const& s : specialSplit) {
0099 specialSplitLevelForBranches_.emplace_back(s.getUntrackedParameter<std::string>("branch"),
0100 s.getUntrackedParameter<int>("splitLevel"));
0101 }
0102
0103 auto const& branchAliases{pset.getUntrackedParameterSetVector("branchAliases")};
0104 aliasForBranches_.reserve(branchAliases.size());
0105 for (auto const& a : branchAliases) {
0106 aliasForBranches_.emplace_back(a.getUntrackedParameter<std::string>("branch"),
0107 a.getUntrackedParameter<std::string>("alias"));
0108 }
0109
0110
0111
0112 pset.getUntrackedParameterSet("dataset");
0113 }
0114
0115 void PoolOutputModule::beginJob() {}
0116
0117 void PoolOutputModule::initialRegistry(edm::ProductRegistry const& iReg) {
0118 reg_ = std::make_unique<ProductRegistry>(iReg.productList());
0119 }
0120
0121 std::string const& PoolOutputModule::currentFileName() const { return rootOutputFile_->fileName(); }
0122
0123 PoolOutputModule::AuxItem::AuxItem() : basketSize_(ProductDescription::invalidBasketSize) {}
0124
0125 PoolOutputModule::OutputItem::OutputItem(ProductDescription const* bd,
0126 EDGetToken const& token,
0127 int splitLevel,
0128 int basketSize)
0129 : productDescription_(bd), token_(token), product_(nullptr), splitLevel_(splitLevel), basketSize_(basketSize) {}
0130
0131 PoolOutputModule::OutputItem::Sorter::Sorter(TTree* tree) : treeMap_(new std::map<std::string, int>) {
0132
0133 if (tree != nullptr) {
0134 TObjArray* branches = tree->GetListOfBranches();
0135 for (int i = 0; i < branches->GetEntries(); ++i) {
0136 TBranchElement* br = (TBranchElement*)branches->At(i);
0137 treeMap_->insert(std::make_pair(std::string(br->GetName()), i));
0138 }
0139 }
0140 }
0141
0142 bool PoolOutputModule::OutputItem::Sorter::operator()(OutputItem const& lh, OutputItem const& rh) const {
0143
0144
0145 if (treeMap_->empty())
0146 return lh < rh;
0147 std::string const& lstring = lh.productDescription_->branchName();
0148 std::string const& rstring = rh.productDescription_->branchName();
0149 std::map<std::string, int>::const_iterator lit = treeMap_->find(lstring);
0150 std::map<std::string, int>::const_iterator rit = treeMap_->find(rstring);
0151 bool lfound = (lit != treeMap_->end());
0152 bool rfound = (rit != treeMap_->end());
0153 if (lfound && rfound) {
0154 return lit->second < rit->second;
0155 } else if (lfound) {
0156 return true;
0157 } else if (rfound) {
0158 return false;
0159 }
0160 return lh < rh;
0161 }
0162
0163 namespace {
0164 std::regex convertBranchExpression(std::string const& iGlobBranchExpression) {
0165 std::string tmp(iGlobBranchExpression);
0166 boost::replace_all(tmp, "*", ".*");
0167 boost::replace_all(tmp, "?", ".");
0168 return std::regex(tmp);
0169 }
0170 }
0171
0172 inline bool PoolOutputModule::SpecialSplitLevelForBranch::match(std::string const& iBranchName) const {
0173 return std::regex_match(iBranchName, branch_);
0174 }
0175
0176 std::regex PoolOutputModule::SpecialSplitLevelForBranch::convert(std::string const& iGlobBranchExpression) const {
0177 return convertBranchExpression(iGlobBranchExpression);
0178 }
0179
0180 bool PoolOutputModule::AliasForBranch::match(std::string const& iBranchName) const {
0181 return std::regex_match(iBranchName, branch_);
0182 }
0183
0184 std::regex PoolOutputModule::AliasForBranch::convert(std::string const& iGlobBranchExpression) const {
0185 return convertBranchExpression(iGlobBranchExpression);
0186 }
0187
0188 void PoolOutputModule::fillSelectedItemList(BranchType branchType,
0189 std::string const& processName,
0190 TTree* theInputTree,
0191 OutputItemList& outputItemList) {
0192 SelectedProducts const& keptVector = keptProducts()[branchType];
0193
0194 if (branchType != InProcess) {
0195 AuxItem& auxItem = auxItems_[branchType];
0196
0197 auto basketSize = (InEvent == branchType) ? eventAuxBasketSize_ : basketSize_;
0198
0199
0200 if (theInputTree != nullptr && !overrideInputFileSplitLevels_) {
0201 TBranch* auxBranch = theInputTree->GetBranch(BranchTypeToAuxiliaryBranchName(branchType).c_str());
0202 if (auxBranch) {
0203 auxItem.basketSize_ = auxBranch->GetBasketSize();
0204 } else {
0205 auxItem.basketSize_ = basketSize;
0206 }
0207 } else {
0208 auxItem.basketSize_ = basketSize;
0209 }
0210 }
0211
0212
0213 for (auto const& kept : keptVector) {
0214 int splitLevel = ProductDescription::invalidSplitLevel;
0215 int basketSize = ProductDescription::invalidBasketSize;
0216
0217 ProductDescription const& prod = *kept.first;
0218 if (branchType == InProcess && processName != prod.processName()) {
0219 continue;
0220 }
0221 TBranch* theBranch = ((!prod.produced() && theInputTree != nullptr && !overrideInputFileSplitLevels_)
0222 ? theInputTree->GetBranch(prod.branchName().c_str())
0223 : nullptr);
0224
0225 if (theBranch != nullptr) {
0226 splitLevel = theBranch->GetSplitLevel();
0227 basketSize = theBranch->GetBasketSize();
0228 } else {
0229 auto wp = prod.wrappedType().getClass()->GetAttributeMap();
0230 auto wpSplitLevel = ProductDescription::invalidSplitLevel;
0231 if (wp && wp->HasKey("splitLevel")) {
0232 wpSplitLevel = strtol(wp->GetPropertyAsString("splitLevel"), nullptr, 0);
0233 if (wpSplitLevel < 0) {
0234 throw cms::Exception("IllegalSplitLevel") << "' An illegal ROOT split level of " << wpSplitLevel
0235 << " is specified for class " << prod.wrappedName() << ".'\n";
0236 }
0237 wpSplitLevel += 1;
0238 }
0239 splitLevel = (wpSplitLevel == ProductDescription::invalidSplitLevel ? splitLevel_ : wpSplitLevel);
0240 for (auto const& b : specialSplitLevelForBranches_) {
0241 if (b.match(prod.branchName())) {
0242 splitLevel = b.splitLevel_;
0243 }
0244 }
0245 auto wpBasketSize = ProductDescription::invalidBasketSize;
0246 if (wp && wp->HasKey("basketSize")) {
0247 wpBasketSize = strtol(wp->GetPropertyAsString("basketSize"), nullptr, 0);
0248 if (wpBasketSize <= 0) {
0249 throw cms::Exception("IllegalBasketSize") << "' An illegal ROOT basket size of " << wpBasketSize
0250 << " is specified for class " << prod.wrappedName() << "'.\n";
0251 }
0252 }
0253 basketSize = (wpBasketSize == ProductDescription::invalidBasketSize ? basketSize_ : wpBasketSize);
0254 }
0255 outputItemList.emplace_back(&prod, kept.second, splitLevel, basketSize);
0256 }
0257
0258
0259
0260 sort_all(outputItemList, OutputItem::Sorter(theInputTree));
0261 }
0262
0263 void PoolOutputModule::beginInputFile(FileBlock const& fb) {
0264 if (isFileOpen()) {
0265
0266
0267 auto const& branchToChildMap = fb.productDependencies().childLookup();
0268 for (auto const& parentToChildren : branchToChildMap) {
0269 for (auto const& child : parentToChildren.second) {
0270 productDependencies_.insertChild(parentToChildren.first, child);
0271 }
0272 }
0273 rootOutputFile_->beginInputFile(fb, remainingEvents());
0274 }
0275 }
0276
0277 void PoolOutputModule::openFile(FileBlock const& fb) {
0278 if (!isFileOpen()) {
0279 reallyOpenFile();
0280 beginInputFile(fb);
0281 }
0282 }
0283
0284 void PoolOutputModule::respondToOpenInputFile(FileBlock const& fb) {
0285 if (!initializedFromInput_) {
0286 std::vector<std::string> const& processesWithProcessBlockProducts =
0287 outputProcessBlockHelper().processesWithProcessBlockProducts();
0288 unsigned int numberOfProcessesWithProcessBlockProducts = processesWithProcessBlockProducts.size();
0289 unsigned int numberOfTTrees = numberOfRunLumiEventProductTrees + numberOfProcessesWithProcessBlockProducts;
0290 selectedOutputItemList_.resize(numberOfTTrees);
0291
0292 for (unsigned int i = InEvent; i < NumBranchTypes; ++i) {
0293 BranchType branchType = static_cast<BranchType>(i);
0294 if (branchType != InProcess) {
0295 std::string processName;
0296 TTree* theInputTree =
0297 (branchType == InEvent ? fb.tree() : (branchType == InLumi ? fb.lumiTree() : fb.runTree()));
0298 OutputItemList& outputItemList = selectedOutputItemList_[branchType];
0299 fillSelectedItemList(branchType, processName, theInputTree, outputItemList);
0300 } else {
0301
0302 for (unsigned int k = InProcess; k < numberOfTTrees; ++k) {
0303 OutputItemList& outputItemList = selectedOutputItemList_[k];
0304 std::string const& processName = processesWithProcessBlockProducts[k - InProcess];
0305 TTree* theInputTree = fb.processBlockTree(processName);
0306 fillSelectedItemList(branchType, processName, theInputTree, outputItemList);
0307 }
0308 }
0309 }
0310 initializedFromInput_ = true;
0311 }
0312 ++inputFileCount_;
0313 beginInputFile(fb);
0314 }
0315
0316 void PoolOutputModule::respondToCloseInputFile(FileBlock const& fb) {
0317 if (rootOutputFile_)
0318 rootOutputFile_->respondToCloseInputFile(fb);
0319 }
0320
0321 void PoolOutputModule::setProcessesWithSelectedMergeableRunProducts(std::set<std::string> const& processes) {
0322 processesWithSelectedMergeableRunProducts_.assign(processes.begin(), processes.end());
0323 }
0324
0325 PoolOutputModule::~PoolOutputModule() {}
0326
0327 void PoolOutputModule::write(EventForOutput const& e) {
0328 updateBranchParents(e);
0329 rootOutputFile_->writeOne(e);
0330 if (!statusFileName_.empty()) {
0331 std::ofstream statusFile(statusFileName_.c_str());
0332 statusFile << e.id() << " time: " << std::setprecision(3) << TimeOfDay() << '\n';
0333 statusFile.close();
0334 }
0335 }
0336
0337 void PoolOutputModule::writeLuminosityBlock(LuminosityBlockForOutput const& lb) {
0338 rootOutputFile_->writeLuminosityBlock(lb);
0339 }
0340
0341 void PoolOutputModule::writeRun(RunForOutput const& r) {
0342 if (!reg_ or (reg_->size() < r.productRegistry().size())) {
0343 reg_ = std::make_unique<ProductRegistry>(r.productRegistry().productList());
0344 }
0345 rootOutputFile_->writeRun(r);
0346 }
0347
0348 void PoolOutputModule::writeProcessBlock(ProcessBlockForOutput const& pb) { rootOutputFile_->writeProcessBlock(pb); }
0349
0350 void PoolOutputModule::reallyCloseFile() {
0351 writeEventAuxiliary();
0352 fillDependencyGraph();
0353 branchParents_.clear();
0354 startEndFile();
0355 writeFileFormatVersion();
0356 writeFileIdentifier();
0357 writeIndexIntoFile();
0358 writeStoredMergeableRunProductMetadata();
0359 writeProcessHistoryRegistry();
0360 writeParameterSetRegistry();
0361 writeProductDescriptionRegistry();
0362 writeParentageRegistry();
0363 writeBranchIDListRegistry();
0364 writeThinnedAssociationsHelper();
0365 writeProductDependencies();
0366 writeProcessBlockHelper();
0367 productDependencies_.clear();
0368 finishEndFile();
0369
0370 doExtrasAfterCloseFile();
0371 }
0372
0373
0374 void PoolOutputModule::startEndFile() {}
0375
0376 void PoolOutputModule::writeFileFormatVersion() { rootOutputFile_->writeFileFormatVersion(); }
0377 void PoolOutputModule::writeFileIdentifier() { rootOutputFile_->writeFileIdentifier(); }
0378 void PoolOutputModule::writeIndexIntoFile() { rootOutputFile_->writeIndexIntoFile(); }
0379 void PoolOutputModule::writeStoredMergeableRunProductMetadata() {
0380 rootOutputFile_->writeStoredMergeableRunProductMetadata();
0381 }
0382 void PoolOutputModule::writeProcessHistoryRegistry() { rootOutputFile_->writeProcessHistoryRegistry(); }
0383 void PoolOutputModule::writeParameterSetRegistry() { rootOutputFile_->writeParameterSetRegistry(); }
0384 void PoolOutputModule::writeProductDescriptionRegistry() {
0385 assert(reg_);
0386 rootOutputFile_->writeProductDescriptionRegistry(*reg_);
0387 }
0388 void PoolOutputModule::writeParentageRegistry() { rootOutputFile_->writeParentageRegistry(); }
0389 void PoolOutputModule::writeBranchIDListRegistry() { rootOutputFile_->writeBranchIDListRegistry(); }
0390 void PoolOutputModule::writeThinnedAssociationsHelper() { rootOutputFile_->writeThinnedAssociationsHelper(); }
0391 void PoolOutputModule::writeProductDependencies() { rootOutputFile_->writeProductDependencies(); }
0392 void PoolOutputModule::writeEventAuxiliary() { rootOutputFile_->writeEventAuxiliary(); }
0393 void PoolOutputModule::writeProcessBlockHelper() { rootOutputFile_->writeProcessBlockHelper(); }
0394 void PoolOutputModule::finishEndFile() {
0395 rootOutputFile_->finishEndFile();
0396 rootOutputFile_ = nullptr;
0397 }
0398 void PoolOutputModule::doExtrasAfterCloseFile() {}
0399 bool PoolOutputModule::isFileOpen() const { return rootOutputFile_.get() != nullptr; }
0400 bool PoolOutputModule::shouldWeCloseFile() const { return rootOutputFile_->shouldWeCloseFile(); }
0401
0402 std::pair<std::string, std::string> PoolOutputModule::physicalAndLogicalNameForNewFile() {
0403 if (inputFileCount_ == 0) {
0404 throw edm::Exception(errors::LogicError) << "Attempt to open output file before input file. "
0405 << "Please report this to the core framework developers.\n";
0406 }
0407 std::string suffix(".root");
0408 std::string::size_type offset = fileName().rfind(suffix);
0409 bool ext = (offset == fileName().size() - suffix.size());
0410 if (!ext)
0411 suffix.clear();
0412 std::string fileBase(ext ? fileName().substr(0, offset) : fileName());
0413 std::ostringstream ofilename;
0414 std::ostringstream lfilename;
0415 ofilename << fileBase;
0416 lfilename << logicalFileName();
0417 if (outputFileCount_) {
0418 ofilename << std::setw(3) << std::setfill('0') << outputFileCount_;
0419 if (!logicalFileName().empty()) {
0420 lfilename << std::setw(3) << std::setfill('0') << outputFileCount_;
0421 }
0422 }
0423 ofilename << suffix;
0424 ++outputFileCount_;
0425
0426 return std::make_pair(ofilename.str(), lfilename.str());
0427 }
0428
0429 void PoolOutputModule::reallyOpenFile() {
0430 auto names = physicalAndLogicalNameForNewFile();
0431 rootOutputFile_ = std::make_unique<RootOutputFile>(this,
0432 names.first,
0433 names.second,
0434 processesWithSelectedMergeableRunProducts_,
0435 overrideGUID_);
0436
0437
0438 overrideGUID_.clear();
0439 }
0440
0441 void PoolOutputModule::updateBranchParentsForOneBranch(ProductProvenanceRetriever const* provRetriever,
0442 BranchID const& branchID) {
0443 ProductProvenance const* provenance = provRetriever->branchIDToProvenanceForProducedOnly(branchID);
0444 if (provenance != nullptr) {
0445 BranchParents::iterator it = branchParents_.find(branchID);
0446 if (it == branchParents_.end()) {
0447 it = branchParents_.insert(std::make_pair(branchID, std::set<ParentageID>())).first;
0448 }
0449 it->second.insert(provenance->parentageID());
0450 }
0451 }
0452
0453 void PoolOutputModule::updateBranchParents(EventForOutput const& e) {
0454 ProductProvenanceRetriever const* provRetriever = e.productProvenanceRetrieverPtr();
0455 if (producedBranches_.empty()) {
0456 for (auto const& prod : e.productRegistry().productList()) {
0457 ProductDescription const& desc = prod.second;
0458 if (desc.produced() && desc.branchType() == InEvent && !desc.isAlias()) {
0459 producedBranches_.emplace_back(desc.branchID());
0460 }
0461 }
0462 }
0463 for (auto const& bid : producedBranches_) {
0464 updateBranchParentsForOneBranch(provRetriever, bid);
0465 }
0466 }
0467
0468 void PoolOutputModule::preActionBeforeRunEventAsync(WaitingTaskHolder iTask,
0469 ModuleCallingContext const& iModuleCallingContext,
0470 Principal const& iPrincipal) const noexcept {
0471 if (DropAll != dropMetaData_) {
0472 auto const* ep = dynamic_cast<EventPrincipal const*>(&iPrincipal);
0473 if (ep) {
0474 auto pr = ep->productProvenanceRetrieverPtr();
0475 if (pr) {
0476 pr->readProvenanceAsync(iTask, &iModuleCallingContext);
0477 }
0478 }
0479 }
0480 }
0481
0482 void PoolOutputModule::fillDependencyGraph() {
0483 for (auto const& branchParent : branchParents_) {
0484 BranchID const& child = branchParent.first;
0485 std::set<ParentageID> const& eIds = branchParent.second;
0486 for (auto const& eId : eIds) {
0487 Parentage entryDesc;
0488 ParentageRegistry::instance()->getMapped(eId, entryDesc);
0489 std::vector<BranchID> const& parents = entryDesc.parents();
0490 for (auto const& parent : parents) {
0491 productDependencies_.insertChild(parent, child);
0492 }
0493 }
0494 }
0495 }
0496
0497 void PoolOutputModule::fillDescription(ParameterSetDescription& desc) {
0498 std::string defaultString;
0499
0500 desc.setComment("Writes runs, lumis, and events into EDM/ROOT files.");
0501 desc.addUntracked<std::string>("fileName")->setComment("Name of output file.");
0502 desc.addUntracked<std::string>("logicalFileName", defaultString)
0503 ->setComment("Passed to job report. Otherwise unused by module.");
0504 desc.addUntracked<std::string>("catalog", defaultString)
0505 ->setComment("Passed to job report. Otherwise unused by module.");
0506 desc.addUntracked<int>("maxSize", 0x7f000000)
0507 ->setComment(
0508 "Maximum output file size, in kB.\n"
0509 "If over maximum, new output file will be started at next input file transition.");
0510 desc.addUntracked<int>("compressionLevel", 4)->setComment("ROOT compression level of output file.");
0511 desc.addUntracked<std::string>("compressionAlgorithm", "ZSTD")
0512 ->setComment(
0513 "Algorithm used to compress data in the ROOT output file, allowed values are ZLIB, LZMA, LZ4, and ZSTD");
0514 desc.addUntracked<int>("basketSize", 16384)->setComment("Default ROOT basket size in output file.");
0515 desc.addUntracked<int>("eventAuxiliaryBasketSize", 16384)
0516 ->setComment("Default ROOT basket size in output file for EventAuxiliary branch.");
0517 desc.addUntracked<int>("eventAutoFlushCompressedSize", 20 * 1024 * 1024)
0518 ->setComment(
0519 "Set ROOT auto flush stored data size (in bytes) for event TTree. The value sets how large the compressed "
0520 "buffer is allowed to get. The uncompressed buffer can be quite a bit larger than this depending on the "
0521 "average compression ratio. The value of -1 just uses ROOT's default value. The value of 0 turns off this "
0522 "feature. A value of -N changes the behavior to flush after every Nth event.");
0523 desc.addUntracked<int>("splitLevel", 99)->setComment("Default ROOT branch split level in output file.");
0524 desc.addUntracked<std::string>("sortBaskets", std::string("sortbasketsbyoffset"))
0525 ->setComment(
0526 "Legal values: 'sortbasketsbyoffset', 'sortbasketsbybranch', 'sortbasketsbyentry'.\n"
0527 "Used by ROOT when fast copying. Affects performance.");
0528 desc.addUntracked<int>("treeMaxVirtualSize", -1)
0529 ->setComment("Size of ROOT TTree TBasket cache. Affects performance.");
0530 desc.addUntracked<bool>("fastCloning", true)
0531 ->setComment(
0532 "True: Allow fast copying, if possible.\n"
0533 "False: Disable fast copying.");
0534 desc.addUntracked("mergeJob", false)
0535 ->setComment(
0536 "If set to true and fast copying is disabled, copy input file compression and basket sizes to the output "
0537 "file.");
0538 desc.addUntracked<bool>("compactEventAuxiliary", false)
0539 ->setComment(
0540 "False: Write EventAuxiliary as we go like any other event metadata branch.\n"
0541 "True: Optimize the file layout by deferring writing the EventAuxiliary branch until the output file is "
0542 "closed.");
0543 desc.addUntracked<bool>("overrideInputFileSplitLevels", false)
0544 ->setComment(
0545 "False: Use branch split levels and basket sizes from input file, if possible.\n"
0546 "True: Always use specified or default split levels and basket sizes.");
0547 desc.addUntracked<bool>("writeStatusFile", false)
0548 ->setComment("Write a status file. Intended for use by workflow management.");
0549 desc.addUntracked<std::string>("dropMetaData", defaultString)
0550 ->setComment(
0551 "Determines handling of per product per event metadata. Options are:\n"
0552 "'NONE': Keep all of it.\n"
0553 "'DROPPED': Keep it for products produced in current process and all kept products. Drop it for dropped "
0554 "products produced in prior processes.\n"
0555 "'PRIOR': Keep it for products produced in current process. Drop it for products produced in prior "
0556 "processes.\n"
0557 "'ALL': Drop all of it.");
0558 desc.addUntracked<std::string>("overrideGUID", defaultString)
0559 ->setComment(
0560 "Allows to override the GUID of the file. Intended to be used only in Tier0 for re-creating files.\n"
0561 "The GUID needs to be of the proper format. If a new output file is started (see maxSize), the GUID of\n"
0562 "the first file only is overridden, i.e. the subsequent output files have different, generated GUID.");
0563 {
0564 ParameterSetDescription dataSet;
0565 dataSet.setAllowAnything();
0566 desc.addUntracked<ParameterSetDescription>("dataset", dataSet)
0567 ->setComment("PSet is only used by Data Operations and not by this module.");
0568 }
0569 {
0570 ParameterSetDescription specialSplit;
0571 specialSplit.addUntracked<std::string>("branch")->setComment(
0572 "Name of branch needing a special split level. The name can contain wildcards '*' and '?'");
0573 specialSplit.addUntracked<int>("splitLevel")->setComment("The special split level for the branch");
0574 desc.addVPSetUntracked("overrideBranchesSplitLevel", specialSplit, std::vector<ParameterSet>());
0575 }
0576 {
0577 ParameterSetDescription alias;
0578 alias.addUntracked<std::string>("branch")->setComment(
0579 "Name of branch which will get alias. The name can contain wildcards '*' and '?'");
0580 alias.addUntracked<std::string>("alias")->setComment("The alias to give to the TBranch");
0581 desc.addVPSetUntracked("branchAliases", alias, std::vector<ParameterSet>());
0582 }
0583 OutputModule::fillDescription(desc);
0584 }
0585
0586 void PoolOutputModule::fillDescriptions(ConfigurationDescriptions& descriptions) {
0587 ParameterSetDescription desc;
0588 PoolOutputModule::fillDescription(desc);
0589 descriptions.add("edmOutput", desc);
0590 }
0591 }