10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "art/Utilities/make_tool.h"
17 #include "art_root_io/TFileService.h"
19 #include "canvas/Utilities/InputTag.h"
20 #include "fhiclcpp/ParameterSet.h"
21 #include "messagefacility/MessageLogger/MessageLogger.h"
24 #include "nurandom/RandomUtils/NuRandomService.h"
25 #include "CLHEP/Random/JamesRandom.h"
26 #include "CLHEP/Random/RandFlat.h"
28 #include "nusimdata/SimulationBase/MCTruth.h"
29 #include "nusimdata/SimulationBase/MCFlux.h"
30 #include "nusimdata/SimulationBase/GTruth.h"
71 void produce(art::Event&
e)
override;
74 void beginRun(art::Run& run)
override ;
75 void endSubRun(art::SubRun& sr)
override ;
77 bool Deweight(
double &weight,
double &max_weight);
96 std::unique_ptr<evgen::ldm::IMesonGen>
fGenTool;
97 std::unique_ptr<evgen::ldm::IMeVPrtlFlux>
fFluxTool;
98 std::unique_ptr<evgen::ldm::IRayTrace>
fRayTool;
123 fProduce =
p.get<
bool>(
"Produce",
true);
124 fAnaOutput =
p.get<
bool>(
"AnaOutput",
false);
126 fDoDeweight =
p.get<
bool>(
"Deweight",
false);
133 fGenTool = art::make_tool<IMesonGen>(
p.get<fhicl::ParameterSet>(
"MesonGen"));
134 fFluxTool = art::make_tool<IMeVPrtlFlux>(
p.get<fhicl::ParameterSet>(
"Flux"));
135 fRayTool = art::make_tool<IRayTrace>(
p.get<fhicl::ParameterSet>(
"RayTrace"));
136 fDecayTool = art::make_tool<IMeVPrtlDecay>(
p.get<fhicl::ParameterSet>(
"Decay"));
138 fGenMaxWeight = fGenTool->MaxWeight();
139 std::cout <<
"Gen max weight: " << fGenMaxWeight << std::endl;
141 fFluxMaxWeight = fFluxTool->MaxWeight();
142 std::cout <<
"Flux max weight: " << fFluxMaxWeight << std::endl;
144 fRayMaxWeight = fRayTool->MaxWeight();
145 std::cout <<
"Ray max weight: " << fRayMaxWeight << std::endl;
147 fDecayMaxWeight = fDecayTool->MaxWeight();
148 std::cout <<
"Decay max weight: " << fDecayMaxWeight << std::endl;
150 fRayDecayMaxWeight = fDecayMaxWeight*fRayMaxWeight;
154 produces< std::vector<simb::MCTruth> >();
155 produces< std::vector<simb::MCFlux> >();
157 produces< sumdata::POTSummary, art::InSubRun >();
158 produces< art::Assns<simb::MCTruth, simb::MCFlux> >();
159 produces< std::vector<sim::BeamGateInfo> >();
162 produces< std::vector<evgen::ldm::MeVPrtlTruth> >();
166 art::ServiceHandle<rndm::NuRandomService> seedSvc;
167 fEngine =
new CLHEP::HepJamesRandom;
168 seedSvc->registerEngine(rndm::NuRandomService::CLHEPengineSeeder(
fEngine),
"MeVPrtlGen");
171 art::ServiceHandle<art::TFileService>
tfs;
172 fTree = tfs->make<TTree>(
"mevprtl_gen",
"mevprtl_gen");
174 fTree->Branch(
"mevprtl", &fMeVPrtl);
177 fNCalls = {0, 0, 0, 0};
178 fNTime = {0., 0., 0., 0.};
182 art::ServiceHandle<geo::Geometry const> geo;
183 if (fProduce) run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
187 auto p = std::make_unique<sumdata::POTSummary>();
188 p->totpot = fSubRunPOT;
189 p->totgoodpot = fSubRunPOT;
191 if (fProduce) sr.put(std::move(
p));
197 if (!fDoDeweight || max_weight < 0) {
210 if (max_weight < weight) {
211 std::cerr <<
"ERROR: weight (" << weight <<
") with max weight (" << max_weight <<
"). Reconfiguration needed.\n";
212 std::cout <<
"ERROR: weight (" << weight <<
") with max weight (" << max_weight <<
"). Reconfiguration needed.\n";
213 std::cout <<
"Updating max_weight to new value!\n";
219 double rand = CLHEP::RandFlat::shoot(
fEngine, 0, max_weight);
220 double test = weight;
229 std::unique_ptr<std::vector<simb::MCFlux>> mcfluxColl(
new std::vector<simb::MCFlux>);
230 std::unique_ptr<std::vector<simb::MCTruth>> mctruthColl(
new std::vector<simb::MCTruth>);
231 std::unique_ptr<art::Assns<simb::MCTruth, simb::MCFlux>> truth2fluxAssn(
new art::Assns<simb::MCTruth, simb::MCFlux>);
232 std::unique_ptr<std::vector<sim::BeamGateInfo>> beamgateColl(
new std::vector<sim::BeamGateInfo>);
234 std::unique_ptr<std::vector<evgen::ldm::MeVPrtlTruth>> mevprtlColl(
new std::vector<evgen::ldm::MeVPrtlTruth>);
242 simb::MCFlux kaon = fGenTool->GetNext();
245 std::chrono::duration<double, std::milli> duration = t2 - t1;
246 fNTime[0] = duration.count();
253 std::cout <<
"Flux is kaon (" << is_kaon <<
"). Weight: " << kaonp.
weight <<
". Produced with energy: " << kaonp.
mom.E()
254 <<
" M=" << kaonp.
mom.M() <<
" P=(" << kaonp.
mom.Px() <<
", " << kaonp.
mom.Py() <<
", " << kaonp.
mom.Pz() <<
") At: ("
255 << kaonp.
pos.X() <<
", " << kaonp.
pos.Y() <<
", " << kaonp.
pos.Z() <<
")" << std::endl;
265 success = fFluxTool->MakeFlux(kaon, flux, flux_weight) && Deweight(flux_weight, fFluxMaxWeight);
268 fNTime[1] += duration.count();
270 if (!success)
continue;
272 std::cout <<
"New flux. E=" << flux.
mom.E() <<
" At: (" << flux.
pos.X() <<
", " << flux.
pos.Y() <<
", " << flux.
pos.Z() <<
")" << std::endl;
273 std::cout <<
"P=(" << flux.
mom.Px() <<
", " << flux.
mom.Py() <<
", " << flux.
mom.Pz() <<
")" << std::endl;
274 std::cout <<
"Flux weight: " << flux_weight << std::endl;
276 std::array<TVector3, 2> intersection;
281 success = fRayTool->IntersectDetector(flux, intersection, ray_weight);
284 fNTime[2] += duration.count();
286 if (!success)
continue;
287 std::cout <<
"Ray weight: " << ray_weight << std::endl;
294 success = fDecayTool->Decay(flux, intersection[0], intersection[1], decay, decay_weight);
297 fNTime[3] += duration.count();
299 if (!success)
continue;
301 std::cout <<
"Decay weight: " << decay_weight << std::endl;
304 double ray_decay_weight = ray_weight * decay_weight;
305 success = Deweight(ray_decay_weight, fRayDecayMaxWeight);
307 if (!success)
continue;
309 std::cout <<
"RayDecay weight: " << ray_decay_weight << std::endl;
314 double thisPOT = fGenTool->GetPOT();
318 thisPOT = thisPOT / (flux_weight * ray_decay_weight);
322 ray_decay_weight = 1.;
325 fSubRunPOT += thisPOT;
336 mevprtlColl->push_back(mevprtl_truth);
338 simb::MCTruth mctruth;
343 simb::MCParticle fakenu(0, kaon.fntype,
"primary", -1, 0, -1);
346 mctruth.SetNeutrino(-1, -1, -1, -1, -1, -1,
349 for (
unsigned i_d = 0; i_d < mevprtl_truth.
daughter_mom.size(); i_d++) {
351 simb::MCParticle d(0, mevprtl_truth.
daughter_pdg[i_d],
"primary", -1, daughter4p.M());
352 d.AddTrajectoryPoint(mevprtl_truth.
decay_pos, daughter4p);
366 mctruthColl->push_back(mctruth);
367 mcfluxColl->push_back(kaon);
372 art::PtrMaker<simb::MCFlux> MCFluxPtrMaker {evt};
373 art::PtrMaker<simb::MCTruth> MCTruthPtrMaker {evt};
375 art::Ptr<simb::MCTruth> MCTruthPtr = MCTruthPtrMaker(mctruthColl->size() - 1);
376 art::Ptr<simb::MCFlux> MCFluxPtr = MCFluxPtrMaker(mcfluxColl->size() - 1);
377 truth2fluxAssn->addSingle(MCTruthPtr, MCFluxPtr);
382 beamgateColl->push_back(gate);
385 *fMeVPrtl = mevprtl_truth;
393 evt.put(std::move(mctruthColl));
394 evt.put(std::move(mcfluxColl));
395 evt.put(std::move(truth2fluxAssn));
396 evt.put(std::move(beamgateColl));
398 evt.put(std::move(mevprtlColl));
void beginRun(art::Run &run) override
BEGIN_PROLOG could also be cerr
std::vector< double > daughter_e
CLHEP::HepJamesRandom * fEngine
produces< sumdata::RunData, art::InRun >()
std::array< double, 4 > fNTime
std::unique_ptr< evgen::ldm::IMeVPrtlDecay > fDecayTool
std::vector< TVector3 > daughter_mom
MeVPrtlGen & operator=(MeVPrtlGen const &)=delete
static void Configure(const fhicl::ParameterSet &p)
This is an interface for an art Tool which sources MCFlux objects for downstream processing and tabul...
bool Deweight(double &weight, double &max_weight)
std::vector< int > daughter_pdg
fEngine(art::ServiceHandle< rndm::NuRandomService >() ->createEngine(*this, pset,"Seed"))
MeVPrtlGen(fhicl::ParameterSet const &p)
std::unique_ptr< evgen::ldm::IRayTrace > fRayTool
std::array< uint64_t, 4 > fNCalls
void endSubRun(art::SubRun &sr) override
This is an interface for an art Tool which turns MCFlux objects (which is a meson decay to neutrinos)...
art::ServiceHandle< art::TFileService > tfs
BEGIN_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree showermakertwo END_PROLOG hitmakerfive clustermakerfour pfparticlemakerthree sequence::inline_paths sequence::inline_paths sequence::inline_paths showermakers test
double fRayDecayMaxWeight
This provides an interface for an art tool which ray traces "Prtl" (massive) particles from their pro...
art framework interface to geometry description
BEGIN_PROLOG could also be cout
std::unique_ptr< evgen::ldm::IMesonGen > fGenTool
This is an interface for an art Tool which decays "Prtl" inside a detector volume. It maps MeVPrtlFlux to MeVPrtlDecay.
std::unique_ptr< evgen::ldm::IMeVPrtlFlux > fFluxTool
void produce(art::Event &e) override