3 #include "TDatabasePDG.h"
5 #include "nusimdata/SimulationBase/MCTruth.h"
6 #include "nusimdata/SimulationBase/MCNeutrino.h"
11 #include "ubcore/LLBasicTool/GeoAlgo/GeoAABox.h"
12 #include "ubcore/LLBasicTool/GeoAlgo/GeoAlgo.h"
13 #include "ubcore/LLBasicTool/GeoAlgo/GeoLineSegment.h"
22 std::cout <<
"Hello SBNOsc!" << std::endl;
30 const simb::MCNeutrino&
nu = mctruth.GetNeutrino();
34 const simb::MCParticle& lepton = nu.Lepton();
35 interaction.
lepton.
pdg = lepton.PdgCode();
40 for (
int iparticle=0; iparticle<interaction.
finalstate.size(); iparticle++) {
42 const simb::MCParticle& particle = mctruth.GetParticle(iparticle);
44 if (particle.Process() !=
"primary") {
48 fsp.
pdg = particle.PdgCode();
49 fsp.
energy = particle.Momentum(0).Energy();
50 fsp.
momentum = particle.Momentum(0).Vect();
59 double ECCQE(
const TVector3& l_momentum,
double l_energy,
60 double energy_distortion,
double angle_distortion) {
62 double M_n = 0.939565;
63 double M_p = 0.938272;
64 double M_e = 0.000511;
65 double bindingE = 0.0300;
67 double mp2 = M_p * M_p;
68 double me2 = M_e * M_e;
69 double mnb = M_n - bindingE;
72 TVector3 v(l_momentum);
73 v.SetTheta( v.Theta() + angle_distortion);
74 l_energy = l_energy + energy_distortion;
75 double l_mom = sqrt(l_energy*l_energy - me2);
77 acos(v.Pz() / sqrt(v.Px()*v.Px() + v.Py()*v.Py() + v.Pz()*v.Pz()));
78 double enu_top = mp2 - mnb*mnb - me2 + 2.0 * mnb * l_energy;
79 double enu_bot = 2.0 * (mnb - l_energy + l_mom * cos(l_theta));
80 return enu_top / enu_bot;
85 double osc_dm2,
double osc_angle) {
86 double overlap = sin(2*osc_angle);
87 double energy_factor = sin(1.27 * osc_dm2 * numu_dist / numu_energy);
88 return 1 - overlap * overlap * energy_factor * energy_factor;
93 const std::vector<geoalgo::AABox> &boxes) {
97 if ((v0 - v1).Mag() < 1
e-6)
return 0;
110 for (
auto const &box: boxes) {
111 int n_contained = box.Contain(p0) + box.Contain(p1);
113 if (n_contained == 2) {
114 length = (v1 - v0).Mag();
118 if (n_contained == 1) {
123 if (intersections.size() == 0) {
126 bool p0_edge = algo.
SqDist(p0, box) <
tol;
127 bool p1_edge = algo.
SqDist(p1, box) <
tol;
128 assert(p0_edge || p1_edge);
132 if ((p0_edge && box.Contain(p0)) || (box.Contain(p1) && p1_edge))
135 else if ((p0_edge && box.Contain(p1)) || (box.Contain(p0) && p1_edge)) {
136 length = (v1 - v0).Mag();
148 else if (intersections.size() == 2) {
149 length += (intersections.at(0).ToTLorentzVector().Vect() - intersections.at(1).ToTLorentzVector().Vect()).Mag();
153 else if (intersections.size() == 1) {
155 TVector3 int_tv(intersections.at(0).ToTLorentzVector().Vect());
156 length += ( box.Contain(p0) ? (v0 - int_tv).Mag() : (v1 - int_tv).Mag() );
161 if (n_contained == 0) {
163 if (!(intersections.size() == 0 || intersections.size() == 2)) {
168 bool p0_edge = algo.
SqDist(p0, box) <
tol;
169 bool p1_edge = algo.
SqDist(p1, box) <
tol;
171 TVector3 vint = intersections.at(0).ToTLorentzVector().Vect();
172 bool p0_int = (v0 - vint).Mag() <
tol;
173 bool p1_int = (v1 - vint).Mag() <
tol;
175 assert((p0_int && p0_edge) != (p1_int && p1_edge));
177 if (p0_edge && p1_edge) {
178 length += (v0 - v1).Mag();
184 else if (intersections.size() == 2) {
185 TVector3 start(intersections.at(0).ToTLorentzVector().Vect());
186 TVector3
end(intersections.at(1).ToTLorentzVector().Vect());
187 length += (start -
end).Mag();
198 for (
int iparticle=0; iparticle<mctruth.NParticles(); iparticle++) {
199 const simb::MCParticle& particle = mctruth.GetParticle(iparticle);
201 int pdg = particle.PdgCode();
204 if (
PDGMass(pdg) < 0)
continue;
206 double track_energy = (particle.Momentum().E() -
PDGMass(pdg) / 1000. );
207 double smear_energy = track_energy;
212 if (
abs(pdg) == 321) {
213 track_energy = particle.Momentum().E();
214 smear_energy = track_energy;
217 if (
abs(pdg) == 211) {
218 smear_energy = particle.Momentum().E();
231 this_smeared_energy = std::max(this_smeared_energy, 0.);
234 if (!
isFromNuVertex(mctruth, particle) || particle.Process() !=
"primary") {
238 if (!(
abs(pdg) == 2212 ||
abs(pdg) == 211 ||
abs(pdg) == 321)) {
246 total += this_smeared_energy;
253 total += lepton_energy;
267 for (
unsigned ind = 0; ind < mctrack_list.size(); ind++) {
268 auto const &mct = mctrack_list[ind];
269 int pdg = mct.PdgCode();
271 double track_energy = (mct.Start().E() -
PDGMass(pdg)) / 1000. ;
272 double smear_energy = track_energy;
277 if (
abs(pdg) == 321) {
278 track_energy = mct.Start().E() / 1000.;
279 smear_energy = track_energy;
282 if (
abs(pdg) == 211) {
283 smear_energy = mct.Start().E() / 1000.;
296 this_smeared_energy = std::max(this_smeared_energy, 0.);
299 if (!
isFromNuVertex(mctruth, mct) || mct.Process() !=
"primary") {
303 if (!(
abs(pdg) == 2212 ||
abs(pdg) == 211 ||
abs(pdg) == 321)) {
315 total += this_smeared_energy;
322 total += lepton_energy;
330 double visibleEnergy(TRandom &rand,
const simb::MCTruth &mctruth,
const std::vector<sim::MCTrack> &mctrack_list,
const std::vector<sim::MCShower> &mcshower_list,
332 double visible_E = 0;
336 bool lepton_track_exists =
false;
339 double track_visible_energy = 0.;
340 for (
unsigned ind = 0; ind < mctrack_list.size(); ind++) {
341 auto const &mct = mctrack_list[ind];
346 if ((
abs(mct.PdgCode()) == 13 ||
abs(mct.PdgCode()) == 11) && calculator.
lepton_index == ind) {
355 double this_visible_energy = (mct.Start().E() -
mass) / 1000. ;
357 track_visible_energy += this_visible_energy;
363 track_visible_energy = rand.Gaus(track_visible_energy, track_visible_energy*calculator.
track_energy_distortion);
365 track_visible_energy = std::max(track_visible_energy, 0.);
369 double shower_visible_energy = 0.;
370 if (include_showers) {
371 for (
auto const &mcs: mcshower_list) {
380 double this_visible_energy = (mcs.Start().E() -
mass) / 1000. ;
383 shower_visible_energy += this_visible_energy;
390 shower_visible_energy = rand.Gaus(shower_visible_energy, shower_visible_energy*calculator.
shower_energy_distortion);
392 shower_visible_energy = std::max(shower_visible_energy, 0.);
395 visible_E = track_visible_energy + shower_visible_energy;
414 double smearing_percentage;
423 double lepton_visible_energy = (mct.
Start().
E()) / 1000.;
424 double smeared_lepton_visible_energy = rand.Gaus(lepton_visible_energy, smearing_percentage * lepton_visible_energy);
426 smeared_lepton_visible_energy = std::max(smeared_lepton_visible_energy, 0.);
430 return smeared_lepton_visible_energy;
435 static const TDatabasePDG *
PDGTable(
new TDatabasePDG);
440 if (pdg < 1000000000) {
441 TParticlePDG* ple =
PDGTable->GetParticle(pdg);
442 if (ple == NULL)
return -1;
443 return ple->Mass() * 1000.0;
447 int p = (pdg % 10000000) / 10000;
448 int n = (pdg % 10000) / 10 - p;
449 return (
PDGTable->GetParticle(2212)->Mass() * p +
450 PDGTable->GetParticle(2112)->Mass() *
n) * 1000.0;
457 if (pdg < 1000000000) {
458 TParticlePDG* ple =
PDGTable->GetParticle(pdg);
459 return ple->Charge();
463 int p = (pdg % 10000000) / 10000;
469 TVector3 nuVtx = mc.GetNeutrino().Nu().Position().Vect();
470 TVector3 partStart = mcp.Position().Vect();
471 return (partStart - nuVtx).Mag() <
distance;
476 TVector3 nuVtx = mc.GetNeutrino().Nu().Trajectory().Position(0).Vect();
478 return (showStart - nuVtx).Mag() <
distance;
484 TVector3 nuVtx = mc.GetNeutrino().Nu().Trajectory().Position(0).Vect();
486 return (trkStart - nuVtx).Mag() <
distance;
493 double length2 = (line0 - line1).Mag2();
494 if (length2 == 0.0)
return (line0 - p).Mag();
499 double t = std::max(0., std::min(1., (p - line0).Dot(line1 - line0) / length2));
500 TVector3 projection = line0 + t * (line1 - line0);
501 return (projection - p).Mag();
505 double l0 = line0[dim];
506 double l1 = line1[dim];
509 if ((l0 < pp && pp < l1) || (l1 < pp && pp < l0))
return 0.;
510 return std::min(
abs(l0 - pp) ,
abs(l1 - pp));
double visibleEnergyProposalMCParticles(TRandom &rand, const simb::MCTruth &mctruth, const std::vector< sim::MCTrack > mctrack_list, const VisibleEnergyCalculator &calculator)
int lepton_index
Index of lepton in the mctrack object.
Algorithm to compute various geometrical relation among geometrical objects. In particular functions ...
double track_energy_distortion
Distortion of energies of tracks (%).
double visibleEnergyProposal(TRandom &rand, const simb::MCTruth &mctruth, const std::vector< sim::MCTrack > &mctrack_list, const VisibleEnergyCalculator &calculator)
TVector3 momentum
Three-momentum.
double lepton_energy_distortion_leaving_A
Parameter in function to calculate primary lepton energy resolution.
Final state particle information.
FinalStateParticle lepton
The primary final state lepton.
bool isFromNuVertex(const simb::MCTruth &mc, const simb::MCParticle &mcp, float distance)
double SqDist(const Line_t &line, const Point_t &pt) const
double closestDistance(const TVector3 &line0, const TVector3 &line1, const TVector3 &p)
Representation of a simple 3D line segment Defines a finite 3D straight line by having the start and ...
Neutrino neutrino
The neutrino.
double lepton_energy_distortion_contained
Distortion of energies of primary lepton whose tracks are contained within the TPC (%)...
process_name use argoneut_mc_hitfinder track
double visibleEnergy(TRandom &rand, const simb::MCTruth &mctruth, const std::vector< sim::MCTrack > &mctrack_list, const std::vector< sim::MCShower > &mcshower_list, const VisibleEnergyCalculator &calculator, bool include_showers)
process_name opflashCryoW ana
double shower_threshold
Energy threshold of shower energy counted in calculation [GeV].
double lepton_energy_distortion_leaving_B
Parameter in function to calculate primary lepton energy resolution.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
double smearLeptonEnergy(TRandom &rand, const sim::MCTrack &mct, const VisibleEnergyCalculator &calculator)
auto end(FixedBins< T, C > const &) noexcept
event::Interaction TruthReco(const simb::MCTruth &mctruth)
double PDGCharge(int pdg)
double track_threshold
Energy threshold of track energy counted in calculation [GeV].
const MCStep & Start() const
double shower_energy_distortion
Distortion of energies of showers (%).
double NuMuOscillation(double numu_energy, double numu_dist, double osc_dm2, double osc_angle)
std::vector< FinalStateParticle > finalstate
Other final state particles.
static const TDatabasePDG * PDGTable(new TDatabasePDG)
double ECCQE(const TVector3 &l_momentum, double l_energy, double energy_distortion, double angle_distortion)
double containedLength(const TVector3 &v0, const TVector3 &v1, const std::vector< geoalgo::AABox > &boxes)
float energy
Neutrino energy (GeV)
double lepton_contained_length
Length of section of primary lepton's track that is contained within the TPC.
double closestDistanceDim(const TVector3 &line0, const TVector3 &line1, const TVector3 &p, int dim)
const MCStep & Start() const
const TLorentzVector & Position() const
std::vector< Point_t > Intersection(const AABox_t &box, const HalfLine_t &line, bool back=false) const
Intersection between a HalfLine and an AABox.
physics associatedGroupsWithLeft p1
All truth information associated with one neutrino interaction.
BEGIN_PROLOG could also be cout
bool lepton_contained
True if primary lepton's track is contained within TPC.