HighLAND
KinematicsUtils.cxx
1 #include "KinematicsUtils.hxx"
2 
3 
4 //********************************************************************
5 Float_t anaUtils::GetParticleMass(ParticleId::ParticleEnum partID ) {
6 //********************************************************************
7 
8  Float_t mass = -1;
9 
10  if (partID == ParticleId::kElectron || partID == ParticleId::kPositron) {
11  mass = units::mass_electron;
12  } else if (partID == ParticleId::kPionPlus || partID == ParticleId::kPionMinus) {
13  mass = units::mass_pion_charged;
14  } else if (partID == ParticleId::kMuon || partID == ParticleId::kAntiMuon) {
15  mass = units::mass_muon;
16  } else if (partID == ParticleId::kProton || partID == ParticleId::kAntiProton) {
17  mass = units::mass_proton;
18  } else if (partID == ParticleId::kKaonPlus || partID == ParticleId::kKaonMinus) {
19  mass = units::mass_kaon_charged;
20  } else {
21  // std::cout << "Tried to compute mass for invalid particle hypothesis" << std::endl;
22  return -1;
23  }
24  return mass;
25 }
26 
27 //********************************************************************
28 Float_t anaUtils::ComputeBetaGamma(Float_t mom, ParticleId::ParticleEnum partID ) {
29 //********************************************************************
30 
31  Float_t mass = GetParticleMass(partID);
32  if (mass<0) return -1;
33 
34  Float_t bg = mom / mass;
35  return bg;
36 }
37 
38 //********************************************************************
39 Float_t anaUtils::ComputeBeta(Float_t mom, ParticleId::ParticleEnum partID ) {
40 //********************************************************************
41 
42  Float_t mass = GetParticleMass(partID);
43  if (mass<0) return -1;
44 
45  Float_t bg = mom / mass;
46  Float_t beta = bg / sqrt(1. + bg * bg);
47 
48  return beta;
49 }
50 
51 
52 //********************************************************************
53 Float_t anaUtils::ComputeInvariantMass(const AnaParticleMomB &part1, const AnaParticleMomB &part2, Float_t mass1, Float_t mass2) {
54 //********************************************************************
55 
56  if (mass1 < 0. || mass2 < 0.)
57  return -999.;
58 
59  TVector3 vect = anaUtils::ArrayToTVector3(part1.DirectionStart);
60  vect *= part1.Momentum;
61 
62  Float_t energy = sqrt(mass1*mass1 + pow(part1.Momentum, 2));
63 
64  TLorentzVector lvect1(vect, energy);
65 
66  vect = anaUtils::ArrayToTVector3(part2.DirectionStart);
67  vect *= part2.Momentum;
68 
69  energy = sqrt(mass2*mass2 + pow(part2.Momentum, 2));
70 
71  TLorentzVector lvect2(vect, energy);
72 
73  return (lvect1 + lvect2).M();
74 
75 }
76 
77 //********************************************************************
79 //********************************************************************
80 
81  Float_t u_t = sqrt(1-pow(part.DirectionStart[0],2));
82  Float_t pt = u_t*(part.Momentum);
83  if (pt!=0)
84  return 1/pt;
85  else
86  return -999;
87 }
88 
89 
90 //********************************************************************
91 Float_t anaUtils::ComputeInversePT(const AnaParticleB &part, Float_t mom) {
92 //********************************************************************
93 
94  Float_t u_t = sqrt(1-pow(part.DirectionStart[0],2));
95  Float_t pt = u_t*mom;
96  if (pt!=0)
97  return 1/pt;
98  else
99  return -999;
100 }
101 
102 //********************************************************************
103 Float_t anaUtils::ComputeMomentumFromInversePT(const AnaParticleB &part, Float_t PTinv) {
104 //********************************************************************
105 
106  if (PTinv==0) return -999;
107  Float_t pt = 1/PTinv;
108  Float_t u_t = sqrt(1-pow(part.DirectionStart[0],2));
109  if (u_t==0) return -999;
110 
111  Float_t p = pt/u_t;
112  return p;
113 }
114 
115 //********************************************************************
117 //********************************************************************
118 
119  Float_t u_t = sqrt(1-pow(part.Direction[0],2));
120  Float_t pt = u_t*(part.Momentum);
121  if (pt!=0)
122  return 1/pt;
123  else
124  return -999;
125 }
126 
127 //********************************************************************
128 Float_t anaUtils::NeutrinoERecCCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton) {
129 //********************************************************************
130  Float_t mass_proton = 938.272;
131  Float_t ene_lepton = sqrt(mom_lepton * mom_lepton + mass_lepton * mass_lepton);
132  return 0.5 * (2 * mass_proton * ene_lepton - mass_lepton * mass_lepton) /
133  (mass_proton - ene_lepton + mom_lepton * costheta_lepton);
134 
135 }
136 
137 //********************************************************************
138 Float_t anaUtils::ComputeRecNuEnergyCCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t bindingEnergy) {
139 //********************************************************************
140 
141  // computes the reconstructed neutrino energy using only muon kinematics
142  // all masses in MeV
143  // bindingEnergy = - nuclear potential = 25 MeV for Carbon (default)
144 
145  Float_t reduced_nMass = units::mass_neutron - bindingEnergy;
146 
147  // muon energy
148  Float_t Emu = sqrt( (mass_lepton*mass_lepton) + (mom_lepton*mom_lepton) );
149 
150  // reconstructed neutrino energy
151  Float_t eNuRec = ( (units::mass_proton*units::mass_proton)
152  - (mass_lepton*mass_lepton)
153  - (reduced_nMass*reduced_nMass)
154  + (2 * Emu * reduced_nMass)
155  ) / (
156  2*(reduced_nMass + (mom_lepton * costheta_lepton) - Emu)
157  );
158 
159  return eNuRec;
160 }
161 
162 //********************************************************************
163 Float_t anaUtils::ComputeRecQ2CCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton) {
164 //********************************************************************
165 
166  // computes the reconstructed Q2 using reconstructed quantities
167 
168  // reconstructed neutrino energy using only the kinematic of the muon
169  Float_t eNuRec = ComputeRecNuEnergyCCQE(mom_lepton, mass_lepton, costheta_lepton);
170 
171  // Q2 (using reconstructed neutrino energy). In GeV^2
172  Float_t Q2 = ComputeQ2(mom_lepton, mass_lepton,costheta_lepton,eNuRec);
173 
174  return Q2;
175 }
176 
177 //********************************************************************
178 Float_t anaUtils::ComputeQ2(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t e_neutrino) {
179 //********************************************************************
180 
181  // computes the Q2
182 
183  // reconstructed muon energy
184  Float_t Emu = sqrt( pow(mass_lepton,2) + pow(mom_lepton,2) );
185 
186  // Q2. In GeV^2
187  Float_t Q2 = (2 * e_neutrino * (Emu - (mom_lepton * costheta_lepton)) - pow(mass_lepton,2)) / 1e6;
188 
189  return Q2;
190 }
191 
192 //********************************************************************
193 Float_t* anaUtils::GetSLineDir(Float_t* start, Float_t* end){
194  //********************************************************************
195  static Float_t uf[3] = {0, 0, 0};
196  TVector3 u(end[0]-start[0], end[1]-start[1], end[2]-start[2]);
197  if (u.Mag()!=0){
198  u *= 1/(u.Mag());
199  uf[0] = u.X();
200  uf[1] = u.Y();
201  uf[2] = u.Z();
202  }
203  return uf;
204 }
205 
206 //********************************************************************
207 Float_t anaUtils::ComputeKineticEnergy(Float_t mom, Float_t mass){
208  //********************************************************************
209  return sqrt(pow(mom, 2) + pow(mass, 2)) - mass;
210 }
211 
212 
213 //***************************************************************
214 TVector3 anaUtils::ProjectTransverse(TVector3& nudir, TVector3& thisvec){
215 //***************************************************************
216  return thisvec - thisvec.Dot(nudir)/nudir.Mag2() * nudir;
217 }
218 
219 //***************************************************************
220 Float_t anaUtils::GetDPhi(const Float_t* nudir, const Float_t* mudir, const Float_t* pdir) {
221 //***************************************************************
222  TVector3 nudirv = TVector3(nudir);
223  TVector3 mudirv = TVector3(mudir);
224  TVector3 pdirv = TVector3(pdir);
225  return TMath::Pi()-ProjectTransverse(nudirv, mudirv).Angle(ProjectTransverse(nudirv, pdirv));
226 }
227 
228 //***************************************************************
229 Float_t anaUtils::GetTransverseMom(const Float_t* nudir, const Float_t* thisdir, Float_t thismom){
230 //***************************************************************
231  TVector3 nudirv = TVector3(nudir);
232  TVector3 thisdirv = TVector3(thisdir);
233  TVector3 projectedv = anaUtils::ProjectTransverse(nudirv, thisdirv);
234  return (thismom * projectedv).Mag();
235 }
236 
Float_t NeutrinoERecCCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton)
Float_t ComputeRecQ2CCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton)
/// Extension to AnaParticleB containing momentum and charge info
Float_t ComputeQ2(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t energy_neutrino)
Float_t ComputeMomentumFromInversePT(const AnaParticleB &part, Float_t PTinv)
compute the total momentum given the part and the inverse transverse momentum
Float_t ComputeRecNuEnergyCCQE(Float_t mom_lepton, Float_t mass_lepton, Float_t costheta_lepton, Float_t bindingEnergy=25.)
Float_t Momentum
The initial momentum of the true particle.
TVector3 ProjectTransverse(TVector3 &nudir, TVector3 &thisvec)
Float_t Momentum
The reconstructed momentum of the particle, at the start position.
Representation of a true Monte Carlo trajectory/particle.
Float_t ComputeInversePT(const AnaDetCrossingB &cross, bool entrance=true)
Compute inverse PT given an AnaDetCrossing.
Float_t GetTransverseMom(const Float_t *nudir, const Float_t *thisdir, Float_t thismom)
Get the transverse momentum.
Float_t ComputeInvariantMass(const AnaParticleMomB &part1, const AnaParticleMomB &part2, Float_t mass1, Float_t mass2)
Get invariant mass given two AnaParticleB&#39;s and corresponding masses.
Float_t DirectionStart[3]
The reconstructed start direction of the particle.
Float_t * GetSLineDir(Float_t *start, Float_t *end)
Direction assuming straight line between given start and end points.
Float_t ComputeKineticEnergy(Float_t mom, Float_t mass)
Compute kinetic energy given momentum and mass.
Representation of a reconstructed particle (track or shower).
Float_t Direction[3]
The initial direction of the true particle.
Float_t GetDPhi(const Float_t *nudir, const Float_t *mudir, const Float_t *pdir)
Returns pi-(the angle between muon and proton). Should be delta-fn in ideal back2back.