35 #include "art/Framework/Core/EDProducer.h"
36 #include "art/Framework/Core/ModuleMacros.h"
37 #include "art/Framework/Principal/Event.h"
38 #include "art/Framework/Principal/Run.h"
39 #include "art/Framework/Services/Registry/ServiceHandle.h"
40 #include "fhiclcpp/ParameterSet.h"
41 #include "messagefacility/MessageLogger/MessageLogger.h"
44 #include "Framework/Algorithm/AlgFactory.h"
45 #include "Framework/EventGen/EventRecordVisitorI.h"
46 #include "Framework/EventGen/EventRecord.h"
47 #include "Physics/NNBarOscillation/NNBarOscMode.h"
48 #include "Framework/ParticleData/PDGLibrary.h"
49 #include "Framework/GHEP/GHepParticle.h"
50 #include "Framework/Utils/AppInit.h"
53 #include "nusimdata/SimulationBase/MCTruth.h"
54 #include "nusimdata/SimulationBase/MCParticle.h"
56 #include "nugen/EventGeneratorBase/GENIE/GENIE2ART.h"
60 #include "nurandom/RandomUtils/NuRandomService.h"
66 #include "CLHEP/Random/RandFlat.h"
85 void produce(art::Event &
e)
override;
88 void beginRun(art::Run& run)
override;
96 const genie::EventRecordVisitorI *
mcgen;
107 , flatDist{art::ServiceHandle<rndm::NuRandomService>{}->createEngine(*
this,
p,
"Seed")}
109 genie::PDGLibrary::Instance();
111 string sname =
"genie::EventGenerator";
115 evgb::SetEventGeneratorListAndTune(
"Default",
"Default");
117 genie::AlgFactory *
algf = genie::AlgFactory::Instance();
119 dynamic_cast<const genie::EventRecordVisitorI *
> (algf->GetAlgorithm(sname,sconfig));
121 throw cet::exception(
"NeutronOsc") <<
"Couldn't instantiate the neutron-antineutron oscillation generator";
126 produces< std::vector<simb::MCTruth> >();
127 produces< sumdata::RunData, art::InRun >();
129 unsigned int seed = art::ServiceHandle<rndm::NuRandomService>()->getSeed();
130 genie::utils::app_init::RandGen(seed);
136 genie::EventRecord *
event =
new genie::EventRecord;
137 int target = 1000180400;
138 int decay = SelectAnnihilationMode(target);
139 genie::Interaction * interaction = genie::Interaction::NOsc(target,decay);
140 event->AttachSummary(interaction);
143 mcgen->ProcessEventRecord(event);
150 MF_LOG_DEBUG(
"NeutronOsc")
151 <<
"Generated event: " << *event;
153 std::unique_ptr< std::vector<simb::MCTruth> > truthcol(
new std::vector<simb::MCTruth>);
156 art::ServiceHandle<geo::Geometry const> geo;
165 for (
size_t i = 0; i<geo->NTPC(); ++i){
167 if (minx>tpc.
MinX()) minx = tpc.
MinX();
168 if (maxx<tpc.
MaxX()) maxx = tpc.
MaxX();
169 if (miny>tpc.
MinY()) miny = tpc.
MinY();
170 if (maxy<tpc.
MaxY()) maxy = tpc.
MaxY();
171 if (minz>tpc.
MinZ()) minz = tpc.
MinZ();
172 if (maxz<tpc.
MaxZ()) maxz = tpc.
MaxZ();
176 double X0 = flatDist.fire( minx, maxx );
177 double Y0 = flatDist.fire( miny, maxy );
178 double Z0 = flatDist.fire( minz, maxz );
180 TIter partitr(event);
181 genie::GHepParticle *part = 0;
186 std::string primary(
"primary");
188 while( (part = dynamic_cast<genie::GHepParticle *>(partitr.Next())) ){
190 simb::MCParticle tpart(trackid,
197 TLorentzVector pos(X0, Y0, Z0, 0);
198 TLorentzVector mom(part->Px(), part->Py(), part->Pz(), part->E());
199 tpart.AddTrajectoryPoint(pos,mom);
200 if(part->PolzIsSet()) {
202 part->GetPolarization(polz);
203 tpart.SetPolarization(polz);
209 truth.SetOrigin(simb::kUnknown);
210 truthcol->push_back(truth);
212 e.put(std::move(truthcol));
219 art::ServiceHandle<geo::Geometry const> geo;
220 run.put(std::make_unique<sumdata::RunData>(geo->DetectorName()));
230 std::string pdg_string =
std::to_string(static_cast<long long>(pdg_code));
231 if (pdg_string.size() != 10) {
232 std::cout <<
"Expecting PDG code to be a 10-digit integer; instead, it's the following: " << pdg_string << std::endl;
237 int n_nucleons = std::stoi(pdg_string.substr(6,3)) - 1;
238 int n_protons = std::stoi(pdg_string.substr(3,3));
241 double proton_frac = ((double)n_protons) / ((double)n_nucleons);
242 double neutron_frac = 1 - proton_frac;
245 const int n_modes = 16;
246 double br [n_modes] = { 0.010, 0.080, 0.100, 0.220,
247 0.360, 0.160, 0.070, 0.020,
248 0.015, 0.065, 0.110, 0.280,
249 0.070, 0.240, 0.100, 0.100 };
251 for (
int i = 0; i < n_modes; i++) {
253 br[i] *= proton_frac;
255 br[i] *= neutron_frac;
259 double p = flatDist.fire();
262 double threshold = 0;
263 for (
int i = 0; i < n_modes; i++) {
273 std::cout <<
"Random selection of final state failed!" << std::endl;
NeutronOsc(fhicl::ParameterSet const &p)
void beginRun(art::Run &run) override
process_name opdaq physics producers generator physics producers generator physics producers generator Z0
double MinX() const
Returns the world x coordinate of the start of the box.
Geometry information for a single TPC.
double MaxX() const
Returns the world x coordinate of the end of the box.
process_name opdaq physics producers generator physics producers generator Y0
int SelectAnnihilationMode(int pdg_code)
standard_singlep gaussian distribution X0
double MinZ() const
Returns the world z coordinate of the start of the box.
void produce(art::Event &e) override
double MaxY() const
Returns the world y coordinate of the end of the box.
const genie::EventRecordVisitorI * mcgen
std::string to_string(WindowPattern const &pattern)
genie::NNBarOscMode_t gOptDecayMode
double MaxZ() const
Returns the world z coordinate of the end of the box.
double MinY() const
Returns the world y coordinate of the start of the box.
art framework interface to geometry description
BEGIN_PROLOG could also be cout
NeutronOsc & operator=(NeutronOsc const &)=delete