LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
GenieOutput_module.cc
Go to the documentation of this file.
3 
8 
11 
15 
18 
19 // GENIE includes
20 #ifdef GENIE_PRE_R3
21  #include "GENIE/Messenger/Messenger.h"
22  #include "Ntuple/NtpMCFormat.h"
23  #include "Ntuple/NtpWriter.h"
24  #include "Ntuple/NtpMCEventRecord.h"
25  //#include "Ntuple/NtpMCTreeHeader.h"
26  #include "PDG/PDGLibrary.h"
27  #include "GHEP/GHepRecord.h"
28 #else
29  #include "GENIE/Framework/Messenger/Messenger.h"
30  // careful: potential conflict LOG_INFO w/ messagefacility
31  #include "GENIE/Framework/GHEP/GHepRecord.h"
32  #include "GENIE/Framework/Ntuple/NtpMCFormat.h"
33  #include "GENIE/Framework/Ntuple/NtpWriter.h"
34  #include "GENIE/Framework/Ntuple/NtpMCEventRecord.h"
35  // #include "GENIE/Framework/Ntuple/NtpMCTreeHeader.h"
36 #endif
37 
38 #include <iostream>
39 #include <iomanip>
40 #include <fstream>
41 #include <sstream>
42 
43 // Necessary because the GENIE LOG_* macros don't fully qualify Messenger
44 using genie::Messenger;
45 
46 namespace evg {
47  class GenieOutput;
48 
50  // hold/document fcl parameters
51  template<class T> using Atom = fhicl::Atom<T>;
52  template<class T> using Sequence = fhicl::Sequence<T>;
53  template<class T> using Table = fhicl::Table<T>;
55  using Name = fhicl::Name;
56 
58  Name("inputModuleLabels"),
59  Comment("list of input module labels to use, if empty use everything")
60  // { } // how to default this to empty ??
61  };
63  Name("outputGHEPFile"),
64  Comment("name of file to write in std GENIE gntp.*.ghep.root format\n"
65  "if blank don't write file, if name contains '%l' then\n"
66  "events from different input labels will go to separate outputs\n"),
67  ""
68  };
70  Name("dumpFilePattern"),
71  Comment("name of file for formatted dumps; if name contains '%l' then\n"
72  "events from different input labels will go to separate streams\n"
73  "if blank use std::cout"),
74  ""
75  };
77  Name("dumpGeniePrintLevel"),
78  Comment("print fetched genie::EventRecord -1=no, 13=max info\n"
79  "see GENIE manual for legal values"),
80  -1
81  };
83  Name("dumpMCTruth"),
84  Comment("dump the MCTruth objects (std:cout) as they're retrieved"),
85  false
86  };
88  Name("dumpGTruth"),
89  Comment("dump the GTruth objects (std:cout) as they're retrieved"),
90  false
91  };
93  Name("dumpMCFlux"),
94  Comment("dump the MCFlux objects (std:cout) as they're retrieved"),
95  false
96  };
97  }; // end-of GenieOutputParams
98 }
99 
101 
102 public:
103 
104  // Allow 'art --print-description' to work
106 
107  //explicit GenieOutput(fhicl::ParameterSet const & p);
108  explicit GenieOutput(const Parameters& params);
109 
110  // The destructor generated by the compiler is fine for classes
111  // without bare pointers or other resource use.
112  ~GenieOutput();
113 
114  // Plugins should not be copied or assigned.
115  GenieOutput(GenieOutput const &) = delete;
116  GenieOutput(GenieOutput &&) = delete;
117  GenieOutput & operator = (GenieOutput const &) = delete;
118  GenieOutput & operator = (GenieOutput &&) = delete;
119 
120  // Required functions.
121  void analyze(art::Event const & e) override;
122 
123  // Selected optional functions.
124  /*
125  void beginJob() override;
126  void beginRun(art::Run const & r) override;
127  void beginSubRun(art::SubRun const & sr) override;
128  void endJob() override;
129  void endRun(art::Run const & r) override;
130  void endSubRun(art::SubRun const & sr) override;
131  void reconfigure(fhicl::ParameterSet const & p) override;
132  void respondToCloseInputFile(art::FileBlock const & fb) override;
133  void respondToCloseOutputFiles(art::FileBlock const & fb) override;
134  void respondToOpenInputFile(art::FileBlock const & fb) override;
135  void respondToOpenOutputFiles(art::FileBlock const & fb) override;
136  */
137 
138 private:
139 
140  // private methods
141  genie::NtpWriter* FetchNtpWriter(const std::string& label);
142  std::ostream* FetchDumpStream(const std::string& label);
143 
144 
145  // member data here.
146 
148 
149  std::vector<std::string> fInputModuleLabels;
151  std::string fDumpFilePattern;
153 
157 
160 
161  std::map<std::string,genie::NtpWriter*> fOutputNtpWriters;
162  std::map<std::string,std::ostream*> fDumpStreams;
163 
164 };
165 
166 
167 //evg::GenieOutput::GenieOutput(fhicl::ParameterSet const & pset)
168 // : EDAnalyzer(pset)
170  : EDAnalyzer(params)
171  , fParams(params)
172  , fSeparateOutputNtpWriters(false)
173  , fSeparateDumpStreams(false)
174 {
175 #ifdef GENIE_PRE_R3
176  // trigger early initialization of PDG database & GENIE message service
177  // just to get it out of the way and not intermixed with other output
178  genie::PDGLibrary::Instance();
179 #else
180  // get the GENIE banner out of the way
181  // no longer can use genie::PDGLibrary::Instance() to do this
182  // because that must happen, in some cases in v3_02_xx, after the tune
183  // is determined
184  // banner is triggered by first use of GENIE Messenger
185  // avoid using GENIE macros (possible conflict with mf macros)
186  // LOG("GENIE",pInfo) << "Trigger GENIE banner";
187  (*genie::Messenger::Instance())("GENIE") << log4cpp::Priority::INFO
188  << "Trigger GENIE banner";
189 #endif
190 
191 
192  fInputModuleLabels = fParams().inputModuleLabels();
193  fOutputGHEPFilePattern = fParams().outputGHEPFilePattern();
194  fDumpFilePattern = fParams().dumpFilePattern();
195  fDumpGeniePrintLevel = fParams().dumpGeniePrintLevel();
196 
198  ( fOutputGHEPFilePattern.find("%l") != std::string::npos );
200  ( fDumpFilePattern.find("%l") != std::string::npos );
201 
202  fDumpMCTruth = fParams().dumpMCTruth();
203  fDumpGTruth = fParams().dumpGTruth();
204  fDumpMCFlux = fParams().dumpMCFlux();
205 
206  /*
207  mf::LogInfo("GenieOutput") << "##### Dump options "
208  << fDumpMCTruth << " "
209  << fDumpGTruth << " "
210  << fDumpMCFlux << " " ;
211  */
212 
213 }
214 
216 {
217 
218  // release resources
220  fOutputNtpWriters.begin();
221  for ( ; mitro != fOutputNtpWriters.end(); ++mitro ) {
222  std::string label = mitro->first;
223  genie::NtpWriter* ntpw = mitro->second;
224  if ( ntpw ) {
225  // close out the file
226  ntpw->Save();
227  delete ntpw;
228  }
229  mitro->second = 0;
230  }
231 
233  for ( ; mitrd != fDumpStreams.end(); ++mitrd ) {
234  std::string label = mitrd->first;
235  std::ofstream* fout = dynamic_cast<std::ofstream*>(mitrd->second);
236  if ( fout ) {
237  fout->flush();
238  fout->close();
239  delete fout;
240  }
241  mitrd->second = 0;
242  }
243 }
244 
246 {
247  //std::cerr << "evg::GenieOutput::analyze " << std::endl;
248 
250 
251  bool flag = true;
252  int indx = -1;
253  while ( ( flag = mcitr.Next() ) ) {
254  ++indx;
255  std::string label = mcitr.GetLabel();
256  const simb::MCTruth* pmctruth = mcitr.GetMCTruth();
257  const simb::GTruth* pgtruth = mcitr.GetGTruth();
258  const simb::MCFlux* pmcflux = mcitr.GetMCFlux();
259 
260  static int ievt = -1; // ! bah!
261  ++ievt;
262 
263  static const simb::GTruth nullGTruth;
264  if ( ! pgtruth ) {
265  mf::LogInfo("GenieOutput") << "##### no GTruth ";
266  pgtruth = &nullGTruth;
267  }
268 
269  genie::EventRecord* grec = evgb::RetrieveGHEP(*pmctruth,*pgtruth);
270 
271  genie::NtpWriter* ntpWriter = FetchNtpWriter(label);
272  if ( ntpWriter ) {
273  // check ownership! (might need copy)
274  ntpWriter->AddEventRecord(ievt,grec);
275  }
276 
277  std::ostream* osdump = FetchDumpStream(label);
278  if ( osdump ) {
279  *osdump
280  << " ** Event: GenieOutput_module " << ievt
281  << *grec;
282  osdump->flush();
283  }
284 
285  if ( fDumpMCTruth || fDumpGTruth || fDumpMCFlux ) {
286  std::ostringstream dumpSimBaseObj;
287  dumpSimBaseObj << " after Next() " << indx << " " << flag
288  << std::endl;;
289  if ( fDumpMCTruth ) {
290  if ( pmctruth ) dumpSimBaseObj << *pmctruth << std::endl;
291  else dumpSimBaseObj << "no simb::MCTruth available" << std::endl;
292  }
293  if ( fDumpGTruth ) {
294  if ( pgtruth ) {
295  dumpSimBaseObj << *pgtruth << std::endl;
296  //dumpSimBaseObj << "sorry no operator<< exists for simb::GTruth"
297  // << " - someone should write one" << std::endl;
298  } else dumpSimBaseObj << "no simb::GTruth available" << std::endl;
299  }
300  if ( fDumpMCFlux ) {
301  if ( pmcflux ) dumpSimBaseObj << *pmcflux << std::endl;
302  else dumpSimBaseObj << "no simb::MCFlux available" << std::endl;
303  }
304  mf::LogInfo("GenieOutput") << dumpSimBaseObj.str();
305  }
306 
307  delete grec; // don't leak stuff
308  } // loop over MCTruthAndFriends
309 
310 }
311 
312 genie::NtpWriter* evg::GenieOutput::FetchNtpWriter(const std::string& label) {
313 
314  if ( fOutputGHEPFilePattern == "" ) return 0;
315 
316  genie::NtpWriter* ntpwret = 0;
317  if ( fSeparateOutputNtpWriters ) ntpwret = fOutputNtpWriters[label];
318  else ntpwret = fOutputNtpWriters["*"];
319 
320  if ( ntpwret ) return ntpwret; // already openned
321 
322  // nope?? okay
323 
324  std::string finalFileName = fOutputGHEPFilePattern;
326  size_t posl = finalFileName.find("%l");
327  if ( posl != std::string::npos ) {
328  finalFileName.replace(posl,2,label);
329  }
330  }
331  ntpwret = new genie::NtpWriter(genie::kNFGHEP,0);
332  ntpwret->CustomizeFilename(finalFileName);
333  ntpwret->Initialize();
334 
335  if ( fSeparateOutputNtpWriters ) fOutputNtpWriters[label] = ntpwret;
336  else fOutputNtpWriters["*"] = ntpwret;
337 
338  return ntpwret;
339 
340 
341 }
342 
343 
344 std::ostream* evg::GenieOutput::FetchDumpStream(const std::string& label) {
345  if (fDumpGeniePrintLevel < 0 ) return 0;
346  genie::GHepRecord::SetPrintLevel(fDumpGeniePrintLevel);
347 
348  std::ostream* osret = 0;
349  if ( fSeparateDumpStreams ) osret = fDumpStreams[label];
350  else osret = fDumpStreams["*"];
351 
352  if ( osret ) return osret; // already openned
353 
354  // nope?? okay
355 
356  if ( fDumpFilePattern == "" ||
357  fDumpFilePattern == "--" ||
358  fDumpFilePattern == "cout" ||
359  fDumpFilePattern == "std::cout" ) {
360  // standardize so we don't check all these again
361  fDumpFilePattern = "std::cout";
362  osret = &(std::cout);
363  } else {
364  std::string finalFileName = fDumpFilePattern;
365  if ( fSeparateDumpStreams ) {
366  size_t posl = finalFileName.find("%l");
367  if ( posl != std::string::npos ) {
368  finalFileName.replace(posl,2,label);
369  }
370  }
371  osret = new std::ofstream(finalFileName.c_str(),
372  std::ios_base::trunc|std::ios_base::out);
373 
374  }
375  if ( fSeparateDumpStreams ) fDumpStreams[label] = osret;
376  else fDumpStreams["*"] = osret;
377 
378  return osret;
379 
380 }
381 
382 /*
383 void evg::GenieOutput::beginJob()
384 {
385  // Implementation of optional member function here.
386 }
387 
388 void evg::GenieOutput::beginRun(art::Run const & r)
389 {
390  // Implementation of optional member function here.
391 }
392 
393 void evg::GenieOutput::beginSubRun(art::SubRun const & sr)
394 {
395  // Implementation of optional member function here.
396 }
397 
398 void evg::GenieOutput::endJob()
399 {
400  // Implementation of optional member function here.
401 }
402 
403 void evg::GenieOutput::endRun(art::Run const & r)
404 {
405  // Implementation of optional member function here.
406 }
407 
408 void evg::GenieOutput::endSubRun(art::SubRun const & sr)
409 {
410  // Implementation of optional member function here.
411 }
412 
413 void evg::GenieOutput::reconfigure(fhicl::ParameterSet const & p)
414 {
415  // Implementation of optional member function here.
416 }
417 
418 void evg::GenieOutput::respondToCloseInputFile(art::FileBlock const & fb)
419 {
420  // Implementation of optional member function here.
421 }
422 
423 void evg::GenieOutput::respondToCloseOutputFiles(art::FileBlock const & fb)
424 {
425  // Implementation of optional member function here.
426 }
427 
428 void evg::GenieOutput::respondToOpenInputFile(art::FileBlock const & fb)
429 {
430  // Implementation of optional member function here.
431 }
432 
433 void evg::GenieOutput::respondToOpenOutputFiles(art::FileBlock const & fb)
434 {
435  // Implementation of optional member function here.
436 }
437 */
438 
intermediate_table::iterator iterator
std::vector< std::string > fInputModuleLabels
label(s) of existing MCTruth/GTruth/MCFlux
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
genie::EventRecord * RetrieveGHEP(const simb::MCTruth &truth, const simb::GTruth &gtruth, bool useFirstTrajPosition=true)
return genie::EventRecord pointer; callee takes possession
Definition: GENIE2ART.cxx:540
std::string fDumpFilePattern
const simb::MCTruth * GetMCTruth() const
Functions for transforming GENIE objects into ART objects (and back)
std::map< std::string, genie::NtpWriter * > fOutputNtpWriters
object containing MC flux information
std::map< std::string, std::ostream * > fDumpStreams
Atom< std::string > outputGHEPFilePattern
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
const simb::MCFlux * GetMCFlux() const
genie::NtpWriter * FetchNtpWriter(const std::string &label)
GenieOutput(const Parameters &params)
const simb::GTruth * GetGTruth() const
std::ostream * FetchDumpStream(const std::string &label)
void analyze(art::Event const &e) override
Atom< std::string > dumpFilePattern
TCEvent evt
Definition: DataStructs.cxx:8
Event generator information.
Definition: MCTruth.h:32
Sequence< std::string > inputModuleLabels
Float_t e
Definition: plot.C:35
std::string GetLabel() const
std::string fOutputGHEPFilePattern