LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
DK2NuInterface.cxx
Go to the documentation of this file.
2 #include "dk2nu/tree/NuChoice.h"
3 #include "dk2nu/tree/calcLocationWeights.h"
4 #include "dk2nu/tree/dk2nu.h"
5 #include "dk2nu/tree/dkmeta.h"
6 
7 #include "TFile.h"
8 #include "TTree.h"
9 
10 #include "TMath.h"
11 #include "TRandom.h"
12 
13 #include <iomanip>
14 
15 namespace fluxr {
16  void DK2NuInterface::SetRootFile(TFile* rootFile)
17  {
18  fDk2NuTree = dynamic_cast<TTree*>(rootFile->Get("dk2nuTree"));
19  fDkMetaTree = dynamic_cast<TTree*>(rootFile->Get("dkmetaTree"));
20 
21  fDk2Nu = new bsim::Dk2Nu;
22  fDkMeta = new bsim::DkMeta;
23  fNuChoice = new bsim::NuChoice;
24  fDk2NuTree->SetBranchAddress("dk2nu", &fDk2Nu);
25  fDkMetaTree->SetBranchAddress("dkmeta", &fDkMeta);
26 
27  fNEntries = fDk2NuTree->GetEntries();
28  fDkMetaTree->GetEntry(0);
29  fRun = fDkMeta->job;
30  fPOT = fDkMeta->pots;
31  }
32 
34  {
35  // Code to handle flux window adapted from
36  // GENIE_R21210/src/FluxDrivers/GNuMIFlux.cxx
37  if (ps.is_key_to_table("rotmatrix")) {
38  // Matrix defined with series of rotations
39  fhicl::ParameterSet rotps = ps.get<fhicl::ParameterSet>("rotmatrix");
40  fTempRot.RotateX(rotps.get<double>("x"));
41  fTempRot.RotateY(rotps.get<double>("y"));
42  fTempRot.RotateZ(rotps.get<double>("z"));
43  }
44  else {
45  std::vector<double> rotmat = ps.get<std::vector<double>>("rotmatrix");
46  TVector3 newX, newY, newZ;
47 
48  if (rotmat.size() == 9) {
49  // Matrix defined with new axis values
50  newX = TVector3(rotmat[0], rotmat[1], rotmat[2]);
51  newY = TVector3(rotmat[3], rotmat[4], rotmat[5]);
52  newZ = TVector3(rotmat[6], rotmat[7], rotmat[8]);
53  }
54  else if (rotmat.size() == 6) {
55  // Matrix defined with theta phi rotations
56  newX = AnglesToAxis(rotmat[0], rotmat[1]);
57  newY = AnglesToAxis(rotmat[2], rotmat[3]);
58  newZ = AnglesToAxis(rotmat[4], rotmat[5]);
59  fTempRot.RotateAxes(newX, newY, newZ);
61  }
62 
63  fTempRot.RotateAxes(newX, newY, newZ);
64  }
65 
66  fBeamRotXML = fTempRot.Inverse();
67  fBeamRot = TLorentzRotation(fBeamRotXML);
68  fBeamRotInv = fBeamRot.Inverse();
69 
70  int w = 10, p = 6;
71  std::cout << " fBeamRotXML: " << std::setprecision(p) << std::endl;
72  std::cout << " [ " << std::setw(w) << fBeamRotXML.XX() << " " << std::setw(w)
73  << fBeamRotXML.XY() << " " << std::setw(w) << fBeamRotXML.XZ() << std::endl
74  << " " << std::setw(w) << fBeamRotXML.YX() << " " << std::setw(w)
75  << fBeamRotXML.YY() << " " << std::setw(w) << fBeamRotXML.YZ() << std::endl
76  << " " << std::setw(w) << fBeamRotXML.ZX() << " " << std::setw(w)
77  << fBeamRotXML.ZY() << " " << std::setw(w) << fBeamRotXML.ZZ() << " ] " << std::endl;
78  std::cout << std::endl;
79 
80  std::vector<double> detxyz = ps.get<std::vector<double>>("userbeam");
81  if (detxyz.size() == 3) { fBeamPosXML = TVector3(detxyz[0], detxyz[1], detxyz[2]); }
82  else if (detxyz.size() == 6) {
83  TVector3 userpos = TVector3(detxyz[0], detxyz[1], detxyz[2]);
84  TVector3 beampos = TVector3(detxyz[3], detxyz[4], detxyz[5]);
85  fBeamPosXML = userpos - fBeamRotXML * beampos;
86  }
87  else {
88  std::cout << "userbeam needs 3 or 6 numbers to be properly defined" << std::endl;
89  }
90 
91  fBeamZero = TLorentzVector(fBeamPosXML, 0);
92 
93  w = 16;
94  p = 10;
95  std::cout << " fBeamPosXML: [ " << std::setprecision(p) << std::setw(w) << fBeamPosXML.X()
96  << " , " << std::setw(w) << fBeamPosXML.Y() << " , " << std::setw(w)
97  << fBeamPosXML.Z() << " ] " << std::endl;
98 
101  //
102  // calculation from flux window
103  // discontinued in favor of random point in active volume
104 
105  //
108 
109  // calculation from random point in detector
110 
111  std::vector<double> x_detAV = ps.get<std::vector<double>>("x_detAV");
112  std::vector<double> y_detAV = ps.get<std::vector<double>>("y_detAV");
113  std::vector<double> z_detAV = ps.get<std::vector<double>>("z_detAV");
114 
115  // assign random point
116 
117  detAV_rand_user[0] = gRandom->Uniform(x_detAV[0], x_detAV[1]);
118  detAV_rand_user[1] = gRandom->Uniform(y_detAV[0], y_detAV[1]);
119  detAV_rand_user[2] = gRandom->Uniform(z_detAV[0], z_detAV[1]);
120 
121  // convert to beam coordinates
122  fRandUser = TLorentzVector(detAV_rand_user, 0);
124 
125  // this will serve as the input point for calcEnuWgt function
126 
129 
130  //overwrite dkmeta
131  fDkMeta->location.clear();
132  fDkMeta->location.resize(2);
133  fDkMeta->location[0].x = 0;
134  fDkMeta->location[0].y = 0;
135  fDkMeta->location[0].z = 0;
136  TLorentzVector detVec;
137  User2BeamPos(TLorentzVector(0, 0, 0, 0), detVec);
138  fDkMeta->location[1].x = detVec.Vect().X();
139  fDkMeta->location[1].y = detVec.Vect().Y();
140  fDkMeta->location[1].z = detVec.Vect().Z();
141 
142  std::cout << "Locations " << std::endl;
143  for (unsigned int i = 0; i < fDkMeta->location.size(); i++) {
144  std::cout << i << "\t" << fDkMeta->location[i].x << "\t" << fDkMeta->location[i].y << "\t"
145  << fDkMeta->location[i].z << std::endl;
146  }
147  }
148  void DK2NuInterface::User2BeamPos(const TLorentzVector& usrxyz, TLorentzVector& beamxyz) const
149  {
150  beamxyz = fBeamRotInv * (usrxyz - fBeamZero);
151  }
152  void DK2NuInterface::Beam2UserPos(const TLorentzVector& beamxyz, TLorentzVector& usrxyz) const
153  {
154  usrxyz = fBeamRot * beamxyz + fBeamZero;
155  }
156  void DK2NuInterface::Beam2UserP4(const TLorentzVector& beamp4, TLorentzVector& usrp4) const
157  {
158  usrp4 = fBeamRot * beamp4;
159  }
160 
161  TVector3 DK2NuInterface::AnglesToAxis(double theta, double phi)
162  {
163  //theta,phi in rad
164  double xyz[3];
165  xyz[0] = TMath::Cos(phi) * TMath::Sin(theta);
166  xyz[1] = TMath::Sin(phi) * TMath::Sin(theta);
167  xyz[2] = TMath::Cos(theta);
168  // condition vector to eliminate most floating point errors
169  for (int i = 0; i < 3; ++i) {
170  const double eps = 1.0e-15;
171  if (TMath::Abs(xyz[i]) < eps) xyz[i] = 0;
172  if (TMath::Abs(xyz[i] - 1) < eps) xyz[i] = 1;
173  if (TMath::Abs(xyz[i] + 1) < eps) xyz[i] = -1;
174  }
175  return TVector3(xyz[0], xyz[1], xyz[2]);
176  }
177 
178  bool DK2NuInterface::FillMCFlux(Long64_t ientry, simb::MCFlux& flux)
179 
180  {
181  if (!fDk2NuTree->GetEntry(ientry)) return false;
182 
183  // error handling
184  // Veto the neutrons and unphysical muon decay
185  // Returns default mcflux with nu id = -999
186  if (fDk2Nu->decay.ptype == 2112) return true;
187  if ((fDk2Nu->decay.ptype == 13 || fDk2Nu->decay.ptype == -13) &&
188  (fDk2Nu->decay.ntype == 14 || fDk2Nu->decay.ntype == -14)) {
189  // Calculate xnu
190  double xnu = (2 * fDk2Nu->decay.necm) / 0.105658389; //
191  if (xnu > 1) return true;
192  }
193 
194  // bypass flux window method in favor of random point in detector
195  TLorentzVector x4beam = fRandBeam;
196 
197  // enu = resulting energy when the neutrino is redirected
198  // wgt = output probability weight
199  double enu, wgt;
200  bsim::calcEnuWgt(fDk2Nu, x4beam.Vect(), enu, wgt);
201 
202  TLorentzVector x4usr;
203  Beam2UserPos(x4beam, x4usr);
204 
205  bsim::NuRay rndnuray = fDk2Nu->nuray[0];
206  fDk2Nu->nuray.clear();
207 
208  TVector3 xyzDk(fDk2Nu->decay.vx, fDk2Nu->decay.vy, fDk2Nu->decay.vz); // origin of decay
209  TVector3 p3beam = enu * (x4beam.Vect() - xyzDk).Unit();
210 
211  // divide output wgt by pi so it is in unit area (output wgt is returned as flux/(pi*m^2))
212  wgt *= 1 / TMath::Pi();
213 
214  // with the recalculated energy, compute the momentum components
215  bsim::NuRay anuray(p3beam.x(), p3beam.y(), p3beam.z(), enu, wgt);
216  fDk2Nu->nuray.push_back(rndnuray);
217  fDk2Nu->nuray.push_back(anuray);
218 
219  TLorentzVector p4beam(p3beam, enu);
220  TLorentzVector p4usr;
221  Beam2UserP4(p4beam, p4usr);
222 
223  fNuPos = TLorentzVector(x4usr);
224  fNuMom = TLorentzVector(p4usr);
225 
226  x4usr.SetX(x4usr.X() / 100.); // from cm --> m
227  x4usr.SetY(x4usr.Y() / 100.);
228  x4usr.SetZ(x4usr.Z() / 100.);
229 
230  // overwrite nuchoice
231  fNuChoice->clear();
232  fNuChoice->pdgNu = fDk2Nu->decay.ntype;
233  fNuChoice->xyWgt = fDk2Nu->nuray[1].wgt;
234  fNuChoice->impWgt = fDk2Nu->decay.nimpwt;
235  fNuChoice->x4NuBeam = x4beam;
236  fNuChoice->p4NuBeam = TLorentzVector(
237  fDk2Nu->nuray[1].px, fDk2Nu->nuray[1].py, fDk2Nu->nuray[1].pz, fDk2Nu->nuray[1].E);
238  //need rotation matrix here to fill these
239  fNuChoice->x4NuUser = x4usr;
240  fNuChoice->p4NuUser = p4usr;
241 
242  flux.fntype = fDk2Nu->decay.ntype;
243  flux.fnimpwt = fDk2Nu->decay.nimpwt;
244  flux.fvx = fDk2Nu->decay.vx;
245  flux.fvy = fDk2Nu->decay.vy;
246  flux.fvz = fDk2Nu->decay.vz;
247  flux.fpdpx = fDk2Nu->decay.pdpx;
248  flux.fpdpy = fDk2Nu->decay.pdpy;
249  flux.fpdpz = fDk2Nu->decay.pdpz;
250  flux.fppdxdz = fDk2Nu->decay.ppdxdz;
251  flux.fppdydz = fDk2Nu->decay.ppdydz;
252  flux.fpppz = fDk2Nu->decay.pppz;
253  flux.fppmedium = fDk2Nu->decay.ppmedium;
254  flux.fptype = fDk2Nu->decay.ptype;
255  flux.fndecay = fDk2Nu->decay.ndecay;
256  flux.fmuparpx = fDk2Nu->decay.muparpx;
257  flux.fmuparpy = fDk2Nu->decay.muparpy;
258  flux.fmuparpz = fDk2Nu->decay.muparpz;
259  flux.fmupare = fDk2Nu->decay.mupare;
260  flux.fnecm = fDk2Nu->decay.necm;
261 
262  flux.ftpx = fDk2Nu->tgtexit.tpx;
263  flux.ftpy = fDk2Nu->tgtexit.tpy;
264  flux.ftpz = fDk2Nu->tgtexit.tpz;
265  flux.ftptype = fDk2Nu->tgtexit.tptype;
266  flux.ftgen = fDk2Nu->tgtexit.tgen;
267 
268  flux.frun = fDk2Nu->job;
269  flux.fevtno = fDk2Nu->potnum;
270  flux.fnenergyn = flux.fnenergyf = enu;
271  flux.fnwtnear = flux.fnwtfar = wgt;
272  flux.fdk2gen = (x4beam.Vect() - xyzDk).Mag();
273  flux.ftgptype = fDk2Nu->ancestor[1].pdg;
274 
275  return true;
276  }
277 }
int frun
Definition: MCFlux.h:35
double fpdpx
Definition: MCFlux.h:55
bool FillMCFlux(Long64_t ientry, simb::MCFlux &mcflux)
double ftpx
Definition: MCFlux.h:79
bsim::DkMeta * fDkMeta
int fppmedium
Definition: MCFlux.h:62
TLorentzVector fNuPos
int ftptype
Definition: MCFlux.h:82
double fvx
Definition: MCFlux.h:52
double fnwtfar
Definition: MCFlux.h:48
TLorentzVector fBeamZero
TLorentzVector fRandBeam
double fppdxdz
Definition: MCFlux.h:58
int ftgen
Definition: MCFlux.h:83
double fdk2gen
distance from decay to ray origin
Definition: MCFlux.h:103
bsim::NuChoice * fNuChoice
TLorentzVector fNuMom
int ftgptype
Definition: MCFlux.h:84
double fnenergyf
Definition: MCFlux.h:47
bool is_key_to_table(std::string const &key) const
Definition: ParameterSet.h:208
double fnwtnear
Definition: MCFlux.h:44
int fptype
Definition: MCFlux.h:63
int fndecay
Definition: MCFlux.h:50
double fpdpz
Definition: MCFlux.h:57
T get(std::string const &key) const
Definition: ParameterSet.h:314
TLorentzVector fRandUser
void User2BeamPos(const TLorentzVector &usrxyz, TLorentzVector &beamxyz) const
TVector3 AnglesToAxis(double theta, double phi)
double fmuparpz
Definition: MCFlux.h:69
int fevtno
Definition: MCFlux.h:36
double fppdydz
Definition: MCFlux.h:59
double ftpz
Definition: MCFlux.h:81
double fpdpy
Definition: MCFlux.h:56
void Beam2UserPos(const TLorentzVector &beamxyz, TLorentzVector &usrxyz) const
double fvy
Definition: MCFlux.h:53
double fmupare
Definition: MCFlux.h:70
int fntype
Definition: MCFlux.h:51
double fnecm
Definition: MCFlux.h:71
TLorentzRotation fBeamRotInv
double fmuparpy
Definition: MCFlux.h:68
double fpppz
Definition: MCFlux.h:60
double ftpy
Definition: MCFlux.h:80
double fvz
Definition: MCFlux.h:54
void Init(fhicl::ParameterSet const &ps)
Float_t w
Definition: plot.C:20
void Beam2UserP4(const TLorentzVector &beamp4, TLorentzVector &usrp4) const
void SetRootFile(TFile *rootFile)
double fmuparpx
Definition: MCFlux.h:67
bsim::Dk2Nu * fDk2Nu
TLorentzRotation fBeamRot
double fnenergyn
Definition: MCFlux.h:43
double fnimpwt
Definition: MCFlux.h:72