CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
NanoAODOutputModule.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PhysicsTools/NanoAODOutput
4 // Class : NanoAODOutputModule
5 //
6 // Implementation:
7 // [Notes on implementation]
8 //
9 // Original Author: Christopher Jones
10 // Created: Mon, 07 Aug 2017 14:21:41 GMT
11 //
12 
13 // system include files
14 #include <string>
15 #include "TFile.h"
16 #include "TTree.h"
17 #include "TROOT.h"
18 #include "TObjString.h"
19 #include "Compression.h"
20 
21 // user include files
42 
43 #include <iostream>
44 
46 public:
48  ~NanoAODOutputModule() override;
49 
50  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
51 
52 private:
53  void write(edm::EventForOutput const& e) override;
55  void writeRun(edm::RunForOutput const&) override;
56  bool isFileOpen() const override;
57  void openFile(edm::FileBlock const&) override;
58  void reallyCloseFile() override;
59 
65  bool m_fakeName; //crab workaround, remove after crab is fixed
69  std::unique_ptr<TFile> m_file;
71 
73  public:
74  void branch(TTree &tree) {
75  tree.Branch("run", & m_run, "run/i");
76  tree.Branch("luminosityBlock", & m_luminosityBlock, "luminosityBlock/i");
77  tree.Branch("event", & m_event, "event/l");
78  }
79  void fill(const edm::EventID & id) {
80  m_run = id.run(); m_luminosityBlock = id.luminosityBlock(); m_event = id.event();
81  }
82  private:
83  UInt_t m_run; UInt_t m_luminosityBlock; ULong64_t m_event;
85 
87  public:
88  void branch(TTree &tree) {
89  tree.Branch("run", & m_run, "run/i");
90  tree.Branch("luminosityBlock", & m_luminosityBlock, "luminosityBlock/i");
91  }
92  void fill(const edm::LuminosityBlockID & id) {
93  m_run = id.run();
94  m_luminosityBlock = id.value();
95  }
96  private:
97  UInt_t m_run; UInt_t m_luminosityBlock;
99 
101  public:
102  void branch(TTree &tree) {
103  tree.Branch("run", & m_run, "run/i");
104  }
105  void fill(const edm::RunID & id) {
106  m_run = id.run();
107  }
108  private:
109  UInt_t m_run;
111 
112 
113  std::vector<TableOutputBranches> m_tables;
114  std::vector<TriggerOutputBranches> m_triggers;
115 
116  std::vector<SummaryTableOutputBranches> m_runTables;
117 
118  std::vector<std::pair<std::string,edm::EDGetToken>> m_nanoMetadata;
119 
120 };
121 
122 
123 //
124 // constants, enums and typedefs
125 //
126 
127 //
128 // static data member definitions
129 //
130 
131 //
132 // constructors and destructor
133 //
136  edm::one::OutputModule<>(pset),
137  m_fileName(pset.getUntrackedParameter<std::string>("fileName")),
138  m_logicalFileName(pset.getUntrackedParameter<std::string>("logicalFileName")),
139  m_compressionLevel(pset.getUntrackedParameter<int>("compressionLevel")),
140  m_compressionAlgorithm(pset.getUntrackedParameter<std::string>("compressionAlgorithm")),
141  m_writeProvenance(pset.getUntrackedParameter<bool>("saveProvenance", true)),
142  m_fakeName(pset.getUntrackedParameter<bool>("fakeNameForCrab", false)),
143  m_autoFlush(pset.getUntrackedParameter<int>("autoFlush", -10000000)),
145 {
146 }
147 
149 {
150 }
151 
152 void
154  //Get data from 'e' and write it to the file
156  jr->eventWrittenToFile(m_jrToken, iEvent.id().run(), iEvent.id().event());
157 
158  m_commonBranches.fill(iEvent.id());
159  // fill all tables, starting from main tables and then doing extension tables
160  for (unsigned int extensions = 0; extensions <= 1; ++extensions) {
161  for (auto & t : m_tables) t.fill(iEvent,*m_tree,extensions);
162  }
163  // fill triggers
164  for (auto & t : m_triggers) t.fill(iEvent,*m_tree);
165  m_tree->Fill();
166 
168 }
169 
170 void
173  jr->reportLumiSection(m_jrToken, iLumi.id().run(), iLumi.id().value());
174 
175  m_commonLumiBranches.fill(iLumi.id());
176  m_lumiTree->Fill();
177 
179 }
180 
181 void
184  jr->reportRunNumber(m_jrToken, iRun.id().run());
185 
186  m_commonRunBranches.fill(iRun.id());
187 
188  for (auto & t : m_runTables) t.fill(iRun,*m_runTree);
189 
191  for (const auto & p : m_nanoMetadata) {
192  iRun.getByToken(p.second, hstring);
193  TObjString *tos = dynamic_cast<TObjString *>(m_file->Get(p.first.c_str()));
194  if (tos) {
195  if (hstring->str() != tos->GetString()) throw cms::Exception("LogicError", "Inconsistent nanoMetadata " + p.first + " (" + hstring->str() +")");
196  } else {
197  auto ostr = std::make_unique<TObjString>(hstring->str().c_str());
198  m_file->WriteTObject(ostr.release(), p.first.c_str());
199  }
200  }
201 
202  m_runTree->Fill();
203 
205 }
206 
207 bool
209  return nullptr != m_file.get();
210 }
211 
212 void
214  m_file = std::make_unique<TFile>(m_fileName.c_str(),"RECREATE","",m_compressionLevel);
216  cms::Digest branchHash;
217  m_jrToken = jr->outputFileOpened(m_fileName,
219  std::string(),
220  m_fakeName?"PoolOutputModule":"NanoAODOutputModule",
221  description().moduleLabel(),
223  std::string(),
224  branchHash.digest().toString(),
225  std::vector<std::string>()
226  );
227 
228  if (m_compressionAlgorithm == std::string("ZLIB")) {
229  m_file->SetCompressionAlgorithm(ROOT::kZLIB);
230  } else if (m_compressionAlgorithm == std::string("LZMA")) {
231  m_file->SetCompressionAlgorithm(ROOT::kLZMA);
232  } else {
233  throw cms::Exception("Configuration") << "NanoAODOutputModule configured with unknown compression algorithm '" << m_compressionAlgorithm << "'\n"
234  << "Allowed compression algorithms are ZLIB and LZMA\n";
235  }
236  /* Setup file structure here */
237  m_tables.clear();
238  m_triggers.clear();
239  m_runTables.clear();
240  const auto & keeps = keptProducts();
241  for (const auto & keep : keeps[edm::InEvent]) {
242  if(keep.first->className() == "nanoaod::FlatTable" )
243  m_tables.emplace_back(keep.first, keep.second);
244  else if(keep.first->className() == "edm::TriggerResults" )
245  {
246  m_triggers.emplace_back(keep.first, keep.second);
247  }
248  else throw cms::Exception("Configuration", "NanoAODOutputModule cannot handle class " + keep.first->className());
249  }
250 
251  for (const auto & keep : keeps[edm::InRun]) {
252  if(keep.first->className() == "nanoaod::MergeableCounterTable" )
253  m_runTables.push_back(SummaryTableOutputBranches(keep.first, keep.second));
254  else if(keep.first->className() == "nanoaod::UniqueString" && keep.first->moduleLabel() == "nanoMetadata")
255  m_nanoMetadata.emplace_back(keep.first->productInstanceName(), keep.second);
256  else throw cms::Exception("Configuration", "NanoAODOutputModule cannot handle class " + keep.first->className() + " in Run branch");
257  }
258 
259 
260  // create the trees
261  m_tree.reset(new TTree("Events","Events"));
263  m_tree->SetAutoFlush(m_autoFlush);
265 
266  m_lumiTree.reset(new TTree("LuminosityBlocks","LuminosityBlocks"));
269 
270  m_runTree.reset(new TTree("Runs","Runs"));
273 
274  if (m_writeProvenance) {
275  m_metaDataTree.reset(new TTree(edm::poolNames::metaDataTreeName().c_str(),"Job metadata"));
277  m_parameterSetsTree.reset(new TTree(edm::poolNames::parameterSetsTreeName().c_str(),"Parameter sets"));
279  }
280 }
281 void
283  if (m_writeProvenance) {
284  int basketSize = 16384; // fixme configurable?
287  if (m_metaDataTree->GetNbranches() != 0) {
288  m_metaDataTree->SetEntries(-1);
289  }
290  if (m_parameterSetsTree->GetNbranches() != 0) {
291  m_parameterSetsTree->SetEntries(-1);
292  }
293  }
294  m_file->Write();
295  m_file->Close();
296  m_file.reset();
297  m_tree.release(); // apparently root has ownership
298  m_lumiTree.release(); //
299  m_runTree.release(); //
300  m_metaDataTree.release(); //
301  m_parameterSetsTree.release(); //
304 }
305 
306 void
309 
310  desc.addUntracked<std::string>("fileName");
311  desc.addUntracked<std::string>("logicalFileName","");
312 
313  desc.addUntracked<int>("compressionLevel", 9)
314  ->setComment("ROOT compression level of output file.");
315  desc.addUntracked<std::string>("compressionAlgorithm", "ZLIB")
316  ->setComment("Algorithm used to compress data in the ROOT output file, allowed values are ZLIB and LZMA");
317  desc.addUntracked<bool>("saveProvenance", true)
318  ->setComment("Save process provenance information, e.g. for edmProvDump");
319  desc.addUntracked<bool>("fakeNameForCrab", false)
320  ->setComment("Change the OutputModule name in the fwk job report to fake PoolOutputModule. This is needed to run on cran (and publish) till crab is fixed");
321 
322  //replace with whatever you want to get from the EDM by default
323  const std::vector<std::string> keep = {"drop *", "keep nanoaodFlatTable_*Table_*_*", "keep edmTriggerResults_*_*_*", "keep nanoaodMergeableCounterTable_*Table_*_*", "keep nanoaodUniqueString_nanoMetadata_*_*"};
325 
326  //Used by Workflow management for their own meta data
328  dataSet.setAllowAnything();
329  desc.addUntracked<edm::ParameterSetDescription>("dataset", dataSet)
330  ->setComment("PSet is only used by Data Operations and not by this module.");
331 
333  branchSet.setAllowAnything();
334  desc.add<edm::ParameterSetDescription>("branches", branchSet);
335 
336 
337 
338  descriptions.addDefault(desc);
339 
340 }
341 
RunNumber_t run() const
Definition: EventID.h:39
std::unique_ptr< TTree > m_runTree
EventNumber_t event() const
Definition: EventID.h:41
virtual ProcessHistory const & processHistory() const
std::unique_ptr< TTree > m_lumiTree
EventID const & id() const
boost::uint64_t value() const
ModuleDescription const & description() const
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
bool isFileOpen() const override
RunNumber_t run() const
Definition: RunID.h:39
std::unique_ptr< TTree > m_tree
void setAllowAnything()
allow any parameter label/value pairs
RunID const & id() const
Definition: RunForOutput.h:45
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void fillParameterSetBranch(TTree *parameterSetsTree, int basketSize)
bool registerProcessHistory(ProcessHistory const &processHistory)
void fillProcessHistoryBranch(TTree *metaDataTree, int basketSize, ProcessHistoryRegistry const &processHistoryRegistry)
NanoAODOutputModule(edm::ParameterSet const &pset)
void fill(const edm::LuminosityBlockID &id)
MD5Result digest() const
Definition: Digest.cc:194
void reportRunNumber(JobReport::Token token, unsigned int run)
Definition: JobReport.cc:497
std::vector< std::pair< std::string, edm::EDGetToken > > m_nanoMetadata
std::string const & parameterSetsTreeName()
Definition: BranchType.cc:251
std::unique_ptr< TTree > m_parameterSetsTree
void writeRun(edm::RunForOutput const &) override
class NanoAODOutputModule::CommonLumiBranches m_commonLumiBranches
std::unique_ptr< TTree > m_metaDataTree
const int keep
std::unique_ptr< TFile > m_file
bool getByToken(EDGetToken token, TypeID const &typeID, BasicHandle &result) const
int iEvent
Definition: GenABIO.cc:230
void addDefault(ParameterSetDescription const &psetDescription)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static void fillDescription(ParameterSetDescription &desc, std::vector< std::string > const &iDefaultOutputCommands=ProductSelectorRules::defaultSelectionStrings())
std::vector< SummaryTableOutputBranches > m_runTables
std::vector< TableOutputBranches > m_tables
std::vector< TriggerOutputBranches > m_triggers
RunNumber_t run() const
SelectedProductsForBranchType const & keptProducts() const
std::string const & metaDataTreeName()
Definition: BranchType.cc:168
ParameterDescriptionBase * add(U const &iLabel, T const &value)
std::size_t Token
Definition: JobReport.h:107
void openFile(edm::FileBlock const &) override
void reallyCloseFile() override
void eventWrittenToFile(Token fileToken, RunNumber_t run, EventNumber_t event)
Definition: JobReport.cc:455
std::string toString() const
Definition: Digest.cc:87
HLT enums.
void outputFileClosed(Token fileToken)
Definition: JobReport.cc:461
void write(edm::EventForOutput const &e) override
class NanoAODOutputModule::CommonRunBranches m_commonRunBranches
edm::JobReport::Token m_jrToken
class NanoAODOutputModule::CommonEventBranches m_commonBranches
const std::string & str() const
Definition: UniqueString.h:12
Definition: tree.py:1
edm::ProcessHistoryRegistry m_processHistoryRegistry
LuminosityBlockID const & id() const
OutputModule(edm::ParameterSet const &iPSet)
Definition: OutputModule.h:35
std::string m_compressionAlgorithm
std::string createGlobalIdentifier()
void reportLumiSection(JobReport::Token token, unsigned int run, unsigned int lumiSectId, unsigned long nEvents=0)
Definition: JobReport.cc:487
void writeLuminosityBlock(edm::LuminosityBlockForOutput const &) override