CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PoolOutputModule.cc
Go to the documentation of this file.
2 
5 
17 
18 #include "TTree.h"
19 #include "TBranchElement.h"
20 #include "TObjArray.h"
21 
22 #include <fstream>
23 #include <iomanip>
24 #include <sstream>
25 
26 namespace edm {
28  OutputModule(pset),
29  rootServiceChecker_(),
30  auxItems_(),
31  selectedOutputItemList_(),
32  fileName_(pset.getUntrackedParameter<std::string>("fileName")),
33  logicalFileName_(pset.getUntrackedParameter<std::string>("logicalFileName")),
34  catalog_(pset.getUntrackedParameter<std::string>("catalog")),
35  maxFileSize_(pset.getUntrackedParameter<int>("maxSize")),
36  compressionLevel_(pset.getUntrackedParameter<int>("compressionLevel")),
37  basketSize_(pset.getUntrackedParameter<int>("basketSize")),
38  eventAutoFlushSize_(pset.getUntrackedParameter<int>("eventAutoFlushCompressedSize")),
39  splitLevel_(std::min<int>(pset.getUntrackedParameter<int>("splitLevel") + 1, 99)),
40  basketOrder_(pset.getUntrackedParameter<std::string>("sortBaskets")),
41  treeMaxVirtualSize_(pset.getUntrackedParameter<int>("treeMaxVirtualSize")),
42  whyNotFastClonable_(pset.getUntrackedParameter<bool>("fastCloning") ? FileBlock::CanFastClone : FileBlock::DisabledInConfigFile),
43  dropMetaData_(DropNone),
44  moduleLabel_(pset.getParameter<std::string>("@module_label")),
45  initializedFromInput_(false),
46  outputFileCount_(0),
47  inputFileCount_(0),
48  childIndex_(0U),
49  numberOfDigitsInIndex_(0U),
50  overrideInputFileSplitLevels_(pset.getUntrackedParameter<bool>("overrideInputFileSplitLevels")),
51  rootOutputFile_(),
52  statusFileName_() {
53 
54  if (pset.getUntrackedParameter<bool>("writeStatusFile")) {
55  std::ostringstream statusfilename;
56  statusfilename << moduleLabel_ << '_' << getpid();
57  statusFileName_ = statusfilename.str();
58  }
59 
60  std::string dropMetaData(pset.getUntrackedParameter<std::string>("dropMetaData"));
61  if(dropMetaData.empty()) dropMetaData_ = DropNone;
62  else if(dropMetaData == std::string("NONE")) dropMetaData_ = DropNone;
63  else if(dropMetaData == std::string("DROPPED")) dropMetaData_ = DropDroppedPrior;
64  else if(dropMetaData == std::string("PRIOR")) dropMetaData_ = DropPrior;
65  else if(dropMetaData == std::string("ALL")) dropMetaData_ = DropAll;
66  else {
67  throw edm::Exception(errors::Configuration, "Illegal dropMetaData parameter value: ")
68  << dropMetaData << ".\n"
69  << "Legal values are 'NONE', 'DROPPED', 'PRIOR', and 'ALL'.\n";
70  }
71 
72  if (!wantAllEvents()) {
74  }
75 
76  // We don't use this next parameter, but we read it anyway because it is part
77  // of the configuration of this module. An external parser creates the
78  // configuration by reading this source code.
79  pset.getUntrackedParameterSet("dataset");
80  }
81 
82  std::string const& PoolOutputModule::currentFileName() const {
83  return rootOutputFile_->fileName();
84  }
85 
86 
88  basketSize_(BranchDescription::invalidBasketSize) {}
89 
91  branchDescription_(0),
92  product_(0),
93  splitLevel_(BranchDescription::invalidSplitLevel),
94  basketSize_(BranchDescription::invalidBasketSize) {}
95 
97  branchDescription_(bd),
98  product_(0),
99  splitLevel_(splitLevel),
100  basketSize_(basketSize) {}
101 
102 
103  PoolOutputModule::OutputItem::Sorter::Sorter(TTree* tree) : treeMap_(new std::map<std::string, int>) {
104  // Fill a map mapping branch names to an index specifying the order in the tree.
105  if(tree != 0) {
106  TObjArray* branches = tree->GetListOfBranches();
107  for(int i = 0; i < branches->GetEntries(); ++i) {
108  TBranchElement* br = (TBranchElement*)branches->At(i);
109  treeMap_->insert(std::make_pair(std::string(br->GetName()), i));
110  }
111  }
112  }
113 
114  bool
116  // Provides a comparison for sorting branches according to the index values in treeMap_.
117  // Branches not found are always put at the end (i.e. not found > found).
118  if(treeMap_->empty()) return lh < rh;
119  std::string const& lstring = lh.branchDescription_->branchName();
120  std::string const& rstring = rh.branchDescription_->branchName();
121  std::map<std::string, int>::const_iterator lit = treeMap_->find(lstring);
122  std::map<std::string, int>::const_iterator rit = treeMap_->find(rstring);
123  bool lfound = (lit != treeMap_->end());
124  bool rfound = (rit != treeMap_->end());
125  if(lfound && rfound) {
126  return lit->second < rit->second;
127  } else if(lfound) {
128  return true;
129  } else if(rfound) {
130  return false;
131  }
132  return lh < rh;
133  }
134 
136 
137  Selections const& keptVector = keptProducts()[branchType];
139  AuxItem& auxItem = auxItems_[branchType];
140 
141  // Fill AuxItem
142  if (theInputTree != 0 && !overrideInputFileSplitLevels_) {
143  TBranch* auxBranch = theInputTree->GetBranch(BranchTypeToAuxiliaryBranchName(branchType).c_str());
144  if (auxBranch) {
145  auxItem.basketSize_ = auxBranch->GetBasketSize();
146  } else {
147  auxItem.basketSize_ = basketSize_;
148  }
149  } else {
150  auxItem.basketSize_ = basketSize_;
151  }
152 
153  // Fill outputItemList with an entry for each branch.
154  for(Selections::const_iterator it = keptVector.begin(), itEnd = keptVector.end(); it != itEnd; ++it) {
157 
158  BranchDescription const& prod = **it;
159  TBranch* theBranch = ((!prod.produced() && theInputTree != 0 && !overrideInputFileSplitLevels_) ? theInputTree->GetBranch(prod.branchName().c_str()) : 0);
160 
161  if(theBranch != 0) {
162  splitLevel = theBranch->GetSplitLevel();
163  basketSize = theBranch->GetBasketSize();
164  } else {
165  splitLevel = (prod.splitLevel() == BranchDescription::invalidSplitLevel ? splitLevel_ : prod.splitLevel());
166  basketSize = (prod.basketSize() == BranchDescription::invalidBasketSize ? basketSize_ : prod.basketSize());
167  }
168  outputItemList.push_back(OutputItem(&prod, splitLevel, basketSize));
169  }
170 
171  // Sort outputItemList to allow fast copying.
172  // The branches in outputItemList must be in the same order as in the input tree, with all new branches at the end.
173  sort_all(outputItemList, OutputItem::Sorter(theInputTree));
174  }
175 
177  if(isFileOpen()) {
178  rootOutputFile_->beginInputFile(fb, remainingEvents());
179  }
180  }
181 
183  if(!isFileOpen()) {
184  doOpenFile();
185  beginInputFile(fb);
186  }
187  }
188 
190  if(!initializedFromInput_) {
191  for(int i = InEvent; i < NumBranchTypes; ++i) {
192  BranchType branchType = static_cast<BranchType>(i);
193  TTree* theInputTree = (branchType == InEvent ? fb.tree() :
194  (branchType == InLumi ? fb.lumiTree() :
195  fb.runTree()));
196  fillSelectedItemList(branchType, theInputTree);
197  }
198  initializedFromInput_ = true;
199  }
200  ++inputFileCount_;
201  beginInputFile(fb);
202  }
203 
205  if(rootOutputFile_) rootOutputFile_->respondToCloseInputFile(fb);
206  }
207 
208  void PoolOutputModule::postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren) {
209  childIndex_ = iChildIndex;
210  while (iNumberOfChildren != 0) {
212  iNumberOfChildren /= 10;
213  }
214  if (numberOfDigitsInIndex_ == 0) {
215  numberOfDigitsInIndex_ = 3; // Protect against zero iNumberOfChildren
216  }
217  }
218 
220  }
221 
223  rootOutputFile_->writeOne(e);
224  if (!statusFileName_.empty()) {
225  std::ofstream statusFile(statusFileName_.c_str());
226  statusFile << e.id() << " time: " << std::setprecision(3) << TimeOfDay() << '\n';
227  statusFile.close();
228  }
229  }
230 
232  rootOutputFile_->writeLuminosityBlock(lb);
233  Service<JobReport> reportSvc;
234  reportSvc->reportLumiSection(lb.id().run(), lb.id().luminosityBlock());
235  }
236 
238  rootOutputFile_->writeRun(r);
239  Service<JobReport> reportSvc;
240  reportSvc->reportRunNumber(r.run());
241  }
242 
243  // At some later date, we may move functionality from finishEndFile() to here.
245 
246 
247  void PoolOutputModule::writeFileFormatVersion() { rootOutputFile_->writeFileFormatVersion(); }
248  void PoolOutputModule::writeFileIdentifier() { rootOutputFile_->writeFileIdentifier(); }
249  void PoolOutputModule::writeIndexIntoFile() { rootOutputFile_->writeIndexIntoFile(); }
250  void PoolOutputModule::writeProcessConfigurationRegistry() { rootOutputFile_->writeProcessConfigurationRegistry(); }
251  void PoolOutputModule::writeProcessHistoryRegistry() { rootOutputFile_->writeProcessHistoryRegistry(); }
252  void PoolOutputModule::writeParameterSetRegistry() { rootOutputFile_->writeParameterSetRegistry(); }
253  void PoolOutputModule::writeProductDescriptionRegistry() { rootOutputFile_->writeProductDescriptionRegistry(); }
254  void PoolOutputModule::writeParentageRegistry() { rootOutputFile_->writeParentageRegistry(); }
255  void PoolOutputModule::writeBranchIDListRegistry() { rootOutputFile_->writeBranchIDListRegistry(); }
256  void PoolOutputModule::writeProductDependencies() { rootOutputFile_->writeProductDependencies(); }
258  bool PoolOutputModule::isFileOpen() const { return rootOutputFile_.get() != 0; }
259  bool PoolOutputModule::shouldWeCloseFile() const { return rootOutputFile_->shouldWeCloseFile(); }
260 
262  if(inputFileCount_ == 0) {
264  << "Attempt to open output file before input file. "
265  << "Please report this to the core framework developers.\n";
266  }
267  std::string suffix(".root");
268  std::string::size_type offset = fileName().rfind(suffix);
269  bool ext = (offset == fileName().size() - suffix.size());
270  if(!ext) suffix.clear();
271  std::string fileBase(ext ? fileName().substr(0, offset) : fileName());
272  std::ostringstream ofilename;
273  std::ostringstream lfilename;
274  ofilename << fileBase;
275  lfilename << logicalFileName();
277  ofilename << '_' << std::setw(numberOfDigitsInIndex_) << std::setfill('0') << childIndex_;
278  if(!logicalFileName().empty()) {
279  lfilename << '_' << std::setw(numberOfDigitsInIndex_) << std::setfill('0') << childIndex_;
280  }
281  }
282  if(outputFileCount_) {
283  ofilename << std::setw(3) << std::setfill('0') << outputFileCount_;
284  if(!logicalFileName().empty()) {
285  lfilename << std::setw(3) << std::setfill('0') << outputFileCount_;
286  }
287  }
288  ofilename << suffix;
289  rootOutputFile_.reset(new RootOutputFile(this, ofilename.str(), lfilename.str()));
291  }
292 
293  void
295  std::string defaultString;
297  desc.setComment("Writes runs, lumis, and events into EDM/ROOT files.");
298  desc.addUntracked<std::string>("fileName")
299  ->setComment("Name of output file.");
300  desc.addUntracked<std::string>("logicalFileName", defaultString)
301  ->setComment("Passed to job report. Otherwise unused by module.");
302  desc.addUntracked<std::string>("catalog", defaultString)
303  ->setComment("Passed to job report. Otherwise unused by module.");
304  desc.addUntracked<int>("maxSize", 0x7f000000)
305  ->setComment("Maximum output file size, in kB.\n"
306  "If over maximum, new output file will be started at next input file transition.");
307  desc.addUntracked<int>("compressionLevel", 7)
308  ->setComment("ROOT compression level of output file.");
309  desc.addUntracked<int>("basketSize", 16384)
310  ->setComment("Default ROOT basket size in output file.");
311  desc.addUntracked<int>("eventAutoFlushCompressedSize",-1)->setComment("Set ROOT auto flush stored data size (in bytes) for event TTree. The value sets how large the compressed buffer is allowed to get. The uncompressed buffer can be quite a bit larger than this depending on the average compression ratio. The value of -1 just uses ROOT's default value. The value of 0 turns off this feature.");
312  desc.addUntracked<int>("splitLevel", 99)
313  ->setComment("Default ROOT branch split level in output file.");
314  desc.addUntracked<std::string>("sortBaskets", std::string("sortbasketsbyoffset"))
315  ->setComment("Legal values: 'sortbasketsbyoffset', 'sortbasketsbybranch', 'sortbasketsbyentry'.\n"
316  "Used by ROOT when fast copying. Affects performance.");
317  desc.addUntracked<int>("treeMaxVirtualSize", -1)
318  ->setComment("Size of ROOT TTree TBasket cache. Affects performance.");
319  desc.addUntracked<bool>("fastCloning", true)
320  ->setComment("True: Allow fast copying, if possible.\n"
321  "False: Disable fast copying.");
322  desc.addUntracked<bool>("overrideInputFileSplitLevels", false)
323  ->setComment("False: Use branch split levels and basket sizes from input file, if possible.\n"
324  "True: Always use specified or default split levels and basket sizes.");
325  desc.addUntracked<bool>("writeStatusFile", false)
326  ->setComment("Write a status file. Intended for use by workflow management.");
327  desc.addUntracked<std::string>("dropMetaData", defaultString)
328  ->setComment("Determines handling of per product per event metadata. Options are:\n"
329  "'NONE': Keep all of it.\n"
330  "'DROPPED': Keep it for products produced in current process and all kept products. Drop it for dropped products produced in prior processes.\n"
331  "'PRIOR': Keep it for products produced in current process. Drop it for products produced in prior processes.\n"
332  "'ALL': Drop all of it.");
333  ParameterSetDescription dataSet;
334  dataSet.setAllowAnything();
335  desc.addUntracked<ParameterSetDescription>("dataset", dataSet)
336  ->setComment("PSet is only used by Data Operations and not by this module.");
337 
339 
340  descriptions.add("edmOutput", desc);
341  }
342 }
virtual void writeParentageRegistry()
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const &branchType)
Definition: BranchType.cc:108
BranchDescription const * branchDescription_
int const & basketSize() const
SelectionsArray const & keptProducts() const
Definition: OutputModule.h:56
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
static int const invalidSplitLevel
std::string & branchName() const
void setAllowAnything()
allow any parameter label/value pairs
static int const invalidBasketSize
DropMetaData const & dropMetaData() const
virtual bool isFileOpen() const
int remainingEvents() const
Definition: OutputModule.h:50
bool & produced() const
EventID const & id() const
std::vector< OutputItem > OutputItemList
std::string const & fileName() const
std::string const moduleLabel_
virtual void write(EventPrincipal const &e)
RunNumber_t run() const
Definition: RunPrincipal.h:47
bool int lh
Definition: SSEVec.h:37
virtual bool shouldWeCloseFile() const
allow inheriting classes to override but still be able to call this method in the overridden version ...
uint16_t size_type
std::string const & logicalFileName() const
virtual void writeParameterSetRegistry()
BranchType
Definition: BranchType.h:11
boost::scoped_ptr< RootOutputFile > rootOutputFile_
void fillSelectedItemList(BranchType branchtype, TTree *theInputTree)
bool wantAllEvents() const
Definition: OutputModule.h:65
PoolOutputModule(ParameterSet const &ps)
virtual void respondToOpenInputFile(FileBlock const &fb)
void setComment(std::string const &value)
virtual void respondToCloseInputFile(FileBlock const &fb)
bool operator()(OutputItem const &lh, OutputItem const &rh) const
std::string const & currentFileName() const
virtual void writeFileFormatVersion()
virtual void writeLuminosityBlock(LuminosityBlockPrincipal const &lb)
OutputItemListArray selectedOutputItemList_
iterator end()
Definition: Selections.h:367
ParameterSet const & getUntrackedParameterSet(std::string const &name, ParameterSet const &defaultValue) const
RunNumber_t run() const
virtual void writeProcessConfigurationRegistry()
int const & splitLevel() const
iterator begin()
Definition: Selections.h:366
EventID const & min(EventID const &lh, EventID const &rh)
Definition: EventID.h:132
virtual void writeProductDependencies()
unsigned int offset(bool)
virtual void writeIndexIntoFile()
unsigned int numberOfDigitsInIndex_
void sort_all(RandomAccessSequence &s)
wrappers for std::sort
Definition: Algorithms.h:120
TTree *const tree() const
Definition: FileBlock.h:92
virtual void writeBranchIDListRegistry()
virtual void writeProcessHistoryRegistry()
virtual void openFile(FileBlock const &fb)
LuminosityBlockNumber_t luminosityBlock() const
void add(std::string const &label, ParameterSetDescription const &psetDescription)
virtual void postForkReacquireResources(unsigned int iChildIndex, unsigned int iNumberOfChildren)
static void fillDescription(ParameterSetDescription &desc)
virtual void writeFileIdentifier()
virtual void finishEndFile()
TTree *const lumiTree() const
Definition: FileBlock.h:94
void beginInputFile(FileBlock const &fb)
virtual void startEndFile()
TTree *const runTree() const
Definition: FileBlock.h:96
virtual void writeProductDescriptionRegistry()
boost::shared_ptr< std::map< std::string, int > > treeMap_
static void fillDescriptions(ConfigurationDescriptions &descriptions)
virtual void writeRun(RunPrincipal const &r)