All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NuMiKaonGen_tool.cc
Go to the documentation of this file.
1 /**
2  *
3  */
4 
5 // Framework Includes
6 #include "art/Framework/Core/EDProducer.h"
7 #include "art/Framework/Principal/Event.h"
8 #include "art/Framework/Principal/Handle.h"
9 #include "art/Framework/Services/Registry/ServiceHandle.h"
10 #include "art/Persistency/Common/PtrMaker.h"
11 #include "art/Utilities/ToolMacros.h"
12 #include "cetlib/cpu_timer.h"
13 #include "fhiclcpp/ParameterSet.h"
14 #include "messagefacility/MessageLogger/MessageLogger.h"
15 #include "CLHEP/Random/RandFlat.h"
16 #include "ifdh_art/IFDHService/IFDH_service.h"
17 
18 #include "nusimdata/SimulationBase/MCFlux.h"
19 
20 // local includes
21 #include "IMesonGen.h"
22 
23 // LArSoft includes
24 #include "dk2nu/tree/dk2nu.h"
25 #include "dk2nu/tree/dkmeta.h"
26 #include "dk2nu/tree/NuChoice.h"
27 
28 // ROOT
29 #include "TVector3.h"
30 #include "TTree.h"
31 #include "TFile.h"
32 #include "TTreeReader.h"
33 #include "TTreeReaderValue.h"
34 
35 // std includes
36 #include <string>
37 #include <iostream>
38 #include <memory>
39 
40 //------------------------------------------------------------------------------------------------------------------------------------------
41 // implementation follows
42 
43 namespace evgen {
44 namespace ldm {
45 /**
46  * @brief NuMiKaonGen class definiton
47  */
48 class NuMiKaonGen : public IMesonGen
49 {
50 public:
51  /**
52  * @brief Constructor
53  */
54  NuMiKaonGen(fhicl::ParameterSet const &pset);
55 
56  /**
57  * @brief Destructor
58  */
59  ~NuMiKaonGen();
60 
61  double GetPOT() override;
62  simb::MCFlux GetNext() override;
63 
64  void configure(const fhicl::ParameterSet&) override;
65 
66  const bsim::Dk2Nu *GetNextEntry();
67  std::vector<std::string> LoadFluxFiles();
68  simb::MCFlux MakeMCFlux(const bsim::Dk2Nu &dk2nu);
69  double LoadPOT();
70 
71  // no weights
72  double MaxWeight() override { return -1.; }
73 
74 private:
75  // config
76  std::string fSearchPath;
77  std::vector<std::string> fSearchPatterns;
78  unsigned long fMaxFluxFileMB;
79  std::string fFluxCopyMethod;
81 
82  std::string fTreeName;
83  std::string fMetaTreeName;
84 
85  // info for tracking files
86  unsigned fFileIndex;
87  bool fNewFile;
88  std::vector<std::string> fFluxFiles;
89 
90  // info for tracking entry in file
91  unsigned fEntry;
92  unsigned fEntryStart;
93 
94  // ROOT Holders
95  TTree *fFluxTree;
96  TFile *fFluxFile;
97  bsim::Dk2Nu *fDk2Nu;
98 
99  // count POT
101  double fThisFilePOT;
102 
103 };
104 
105 NuMiKaonGen::NuMiKaonGen(fhicl::ParameterSet const &pset):
106  IMeVPrtlStage("NuMiKaonGen")
107 {
108  configure(pset);
109 
110  // copy the flux files locally
112 
113  // setup indices
114  fFileIndex = 0;
115  fEntry = 0;
116  fEntryStart = 0;
117  fNewFile = true;
118  fFluxTree = NULL;
119  fFluxFile = NULL;
120  fDk2Nu = new bsim::Dk2Nu;
121 
122  fAccumulatedPOT = 0.;
123  fThisFilePOT = 0.;
124 
125 }
126 
127 //------------------------------------------------------------------------------------------------------------------------------------------
128 
130 {
131 
132  if (fDk2Nu) delete fDk2Nu;
133 }
134 
135 //------------------------------------------------------------------------------------------------------------------------------------------
136 void NuMiKaonGen::configure(fhicl::ParameterSet const &pset)
137 {
138  fSearchPath = pset.get<std::string>("SearchPath");
139  fSearchPatterns = pset.get<std::vector<std::string>>("FluxFiles");
140  fMaxFluxFileMB = pset.get<unsigned long>("MaxFluxFileMB", 2 * 1024);
141  fFluxCopyMethod = pset.get<std::string>("FluxCopyMethod", "IFDH");
142  fTreeName = pset.get<std::string>("TreeName");
143  fMetaTreeName = pset.get<std::string>("MetaTreeName");
144  fRandomizeFiles = pset.get<bool>("RandomizeFiles");
145 
146  std::cout << "Searching for flux files at path: " << fSearchPath << std::endl;
147  std::cout << "With patterns:\n";
148  for (const std::string &s: fSearchPatterns) std::cout << s << std::endl;
149  std::cout << "With copy method: " << fFluxCopyMethod << std::endl;
150 }
151 
152 std::vector<std::string> NuMiKaonGen::LoadFluxFiles() {
153  art::ServiceHandle<IFDH> ifdhp;
154 
155  std::vector<std::pair<std::string, long>> allFiles;
156 
157  // find the flux files
158  for (unsigned i = 0; i < fSearchPatterns.size(); i++) {
159  std::vector<std::pair<std::string, long>> thisList = ifdhp->findMatchingFiles(fSearchPath, fSearchPatterns[i]);
160  std::copy (thisList.begin(), thisList.end(), std::back_inserter(allFiles));
161  }
162 
163  // first randomize the flux files
164  std::vector<unsigned long> order(allFiles.size(), 0);
165  if (fRandomizeFiles) {
166  std::vector<double> rand(allFiles.size(), 0.);
167  CLHEP::RandFlat::shootArray(fEngine, rand.size(), &rand[0]);
168  TMath::Sort(allFiles.size(), &rand[0], &order[0], false);
169  }
170  else {
171  for (unsigned i = 0; i < order.size(); i++) {
172  order[i] = i;
173  }
174  }
175 
176  // If we are directly accessing the files, no need to copy
177  if (fFluxCopyMethod == "DIRECT") {
178  std::cout << "DIRECTLY ACCESSING FLUX FILES.\n";
179  std::vector<std::string> files(allFiles.size());
180  for (unsigned i = 0; i < order.size(); i++) {
181  files[i] = allFiles[order[i]].first;
182  }
183  return files;
184  }
185 
186  // copy over up to the provided limit
187  std::vector<std::pair<std::string, long>> selected;
188  unsigned long totalBytes = 0;
189  unsigned ind = 0;
190  while (totalBytes < (fMaxFluxFileMB * 1024 * 1024) && ind < allFiles.size()) {
191  selected.push_back(allFiles[order[ind]]);
192  totalBytes += allFiles[order[ind]].second;
193  ind ++;
194  }
195 
196  // copy the files locally
197  std::vector<std::pair<std::string, long>> localFiles = ifdhp->fetchSharedFiles(selected, fFluxCopyMethod);
198 
199  std::vector<std::string> files(localFiles.size());
200  for (unsigned i = 0; i < localFiles.size(); i++) {
201  files[i] = localFiles[i].first;
202  }
203 
204  return files;
205 }
206 
208  TTreeReader metaReader(fMetaTreeName.c_str(), fFluxFile);
209  TTreeReaderValue<double> pot(metaReader, "pots");
210 
211  double total_pot = 0.;
212 
213  while (metaReader.Next()) {
214  total_pot += *pot;
215  }
216 
217  return total_pot;
218 }
219 
220 
222  double ret = fAccumulatedPOT;
223  fAccumulatedPOT = 0.;
224  return ret;
225 }
226 
227 const bsim::Dk2Nu *NuMiKaonGen::GetNextEntry() {
228  // new file -- set the start entry
229  if (fNewFile) {
230  // wrap file index around
231  if (fFileIndex >= fFluxFiles.size()) {
232  fFileIndex = 0;
233  }
234  // if (fFileIndex >= fFluxFiles.size()) {
235  // throw cet::exception("FluxReader Out of Files",
236  // "At file index (" + std::to_string(fFileIndex) + ") of available files (" + std::to_string(fFluxFiles.size()) + ").");
237  // }
238 
239  std::cout << "New file: " << fFluxFiles[fFileIndex] << " at index: " << fFileIndex << " of: " << fFluxFiles.size() << std::endl;
240  if (fFluxFile) delete fFluxFile;
241  fFluxFile = new TFile(fFluxFiles[fFileIndex].c_str());
242  fFluxTree = (TTree*)fFluxFile->Get(fTreeName.c_str());
243  fFluxTree->SetBranchAddress("dk2nu",&fDk2Nu);
244 
245  // Start at a random index in this file
246  fEntryStart = CLHEP::RandFlat::shootInt(fEngine, fFluxTree->GetEntries()-1);
248 
249  // load the POT in this file
250  fThisFilePOT = LoadPOT();
251  fNewFile = false;
252  }
253  else {
254  fEntry = (fEntry + 1) % fFluxTree->GetEntries();
255  // if this is the last entry, get ready for the next file
256  if ((fEntry + 1) % fFluxTree->GetEntries() == fEntryStart) {
257  fFileIndex ++;
258  fNewFile = true;
259  }
260  }
261 
262  // count the POT
263  fAccumulatedPOT += fThisFilePOT / fFluxTree->GetEntries();
264 
265  fFluxTree->GetEntry(fEntry);
266  return fDk2Nu;
267 }
268 
269 simb::MCFlux NuMiKaonGen::GetNext() {
270  const bsim::Dk2Nu *flux = GetNextEntry();
271  return MakeMCFlux(*flux);
272 }
273 
274 simb::MCFlux NuMiKaonGen::MakeMCFlux(const bsim::Dk2Nu &dk2nu) {
275  simb::MCFlux flux;
276 
277  flux.fFluxType = simb::kDk2Nu;
278  flux.fntype = dk2nu.decay.ntype;
279  flux.fnimpwt = dk2nu.decay.nimpwt;
280  flux.fvx = dk2nu.decay.vx;
281  flux.fvy = dk2nu.decay.vy;
282  flux.fvz = dk2nu.decay.vz;
283  flux.fpdpx = dk2nu.decay.pdpx;
284  flux.fpdpy = dk2nu.decay.pdpy;
285  flux.fpdpz = dk2nu.decay.pdpz;
286  flux.fppdxdz = dk2nu.decay.ppdxdz;
287  flux.fppdydz = dk2nu.decay.ppdydz;
288  flux.fpppz = dk2nu.decay.pppz;
289  flux.fppenergy = dk2nu.decay.ppenergy;
290  flux.fppmedium = dk2nu.decay.ppmedium;
291  flux.fptype = dk2nu.decay.ptype;
292  flux.fndecay = dk2nu.decay.ndecay;
293  flux.fmuparpx = dk2nu.decay.muparpx;
294  flux.fmuparpy = dk2nu.decay.muparpy;
295  flux.fmuparpz = dk2nu.decay.muparpz;
296  flux.fmupare = dk2nu.decay.mupare;
297  flux.fnecm = dk2nu.decay.necm;
298 
299  flux.fppvx = dk2nu.ppvx;
300  flux.fppvy = dk2nu.ppvy;
301  flux.fppvz = dk2nu.ppvz;
302 
303  flux.ftvx = dk2nu.tgtexit.tvx;
304  flux.ftvy = dk2nu.tgtexit.tvy;
305  flux.ftvz = dk2nu.tgtexit.tvz;
306  flux.ftpx = dk2nu.tgtexit.tpx;
307  flux.ftpy = dk2nu.tgtexit.tpy;
308  flux.ftpz = dk2nu.tgtexit.tpz;
309  flux.ftptype = dk2nu.tgtexit.tptype;
310  flux.ftgen = dk2nu.tgtexit.tgen;
311 
312  flux.frun = dk2nu.job;
313  flux.fevtno = dk2nu.potnum;
314  flux.ftgptype = dk2nu.ancestor[1].pdg;
315 
316  // flux.fnenergyn = flux.fnenergyf = enu;
317  // flux.fnwtnear = flux.fnwtfar = wgt;
318  // ignore variables dealing with the neutrino
319  flux.fnenergyn = -1;
320  flux.fnwtnear = flux.fnwtfar = -1;
321  flux.fdk2gen = -1;
322 
323  // placeholder for time
324  flux.fxpoint = dk2nu.ancestor.back().startt;
325 
326  return flux;
327 }
328 
329 DEFINE_ART_CLASS_TOOL(NuMiKaonGen)
330 
331 } // namespace ldm
332 } // namespace evgen
NuMiKaonGen(fhicl::ParameterSet const &pset)
Constructor.
const bsim::Dk2Nu * GetNextEntry()
simb::MCFlux GetNext() override
simb::MCFlux MakeMCFlux(const bsim::Dk2Nu &dk2nu)
CLHEP::HepRandomEngine * fEngine
Definition: IMeVPrtlStage.h:79
IMesonGen interface class definiton.
Definition: IMesonGen.h:31
This is an interface for an art Tool which sources MCFlux objects for downstream processing and tabul...
IMeVPrtlStage interface class definiton. General interface behind each stage. Provides random number ...
Definition: IMeVPrtlStage.h:36
double MaxWeight() override
std::vector< std::string > fSearchPatterns
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
double GetPOT() override
std::vector< std::string > fFluxFiles
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
NuMiKaonGen class definiton.
T copy(T const &v)
std::vector< std::string > LoadFluxFiles()
BEGIN_PROLOG could also be cout