All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
WeightedRayTraceBox_tool.cc
Go to the documentation of this file.
1 /**
2  *
3  */
4 
5 // Framework Includes
6 #include "art/Framework/Principal/Event.h"
7 #include "art/Framework/Principal/Handle.h"
8 #include "art/Framework/Services/Registry/ServiceHandle.h"
9 #include "art/Persistency/Common/PtrMaker.h"
10 #include "art/Utilities/ToolMacros.h"
11 #include "cetlib/cpu_timer.h"
12 #include "fhiclcpp/ParameterSet.h"
13 #include "messagefacility/MessageLogger/MessageLogger.h"
14 
15 // local includes
16 #include "IRayTrace.h"
19 
20 // LArSoft includes
25 
26 // for testing
27 #include "dk2nu/tree/calcLocationWeights.h"
28 #include "dk2nu/tree/dkmeta.h"
29 #include "dk2nu/tree/dk2nu.h"
30 
31 // std includes
32 #include <string>
33 #include <iostream>
34 #include <memory>
35 
36 //------------------------------------------------------------------------------------------------------------------------------------------
37 // implementation follows
38 
39 namespace evgen {
40 namespace ldm {
41 
42 /**
43  * @brief WeightedRayTraceBox class definiton
44  */
46 {
47 public:
48  /**
49  * @brief Constructor
50  */
51  WeightedRayTraceBox(fhicl::ParameterSet const &pset);
52 
53  /**
54  * @brief Destructor
55  */
57 
58  void configure(const fhicl::ParameterSet&) override;
59 
60  bool IntersectDetector(MeVPrtlFlux &flux, std::array<TVector3, 2> &intersection, double &weight) override;
61 
62  // always thrown at least once
63  double MaxWeight() override {
64  return fMaxWeight;
65  }
66 
67 private:
73 
74  void CalculateMaxWeight();
75 
76  double fMaxWeight;
77 
78  double SolidAngle(TVector3 loc);
79  TVector3 RandomIntersectionPoint(TVector3 loc);
80 };
81 
82 WeightedRayTraceBox::WeightedRayTraceBox(fhicl::ParameterSet const &pset):
83  IMeVPrtlStage("WeightedRayTraceBox")
84 {
85  this->configure(pset);
86 }
87 
88 //------------------------------------------------------------------------------------------------------------------------------------------
89 
91 {
92 }
93 
94 //------------------------------------------------------------------------------------------------------------------------------------------
95 void WeightedRayTraceBox::configure(fhicl::ParameterSet const &pset)
96 {
97  if (pset.has_key("Box")) {
98  std::array<double, 6> box_config = pset.get<std::array<double, 6>>("Box");
99  // xmin, xmax, ymin, ymax, zmin, zmax
100  fBox = geo::BoxBoundedGeo(box_config[0], box_config[1], box_config[2], box_config[3], box_config[4], box_config[5]);
101  }
102  else {
103  const geo::GeometryCore *geometry = lar::providerFrom<geo::Geometry>();
104  fBox = geometry->DetectorEnclosureBox(pset.get<std::string>("Volume"));
105  }
106 
107  std::cout << "Detector Box." << std::endl;
108  std::cout << "X " << fBox.MinX() << " " << fBox.MaxX() << std::endl;
109  std::cout << "Y " << fBox.MinY() << " " << fBox.MaxY() << std::endl;
110  std::cout << "Z " << fBox.MinZ() << " " << fBox.MaxZ() << std::endl;
111 
112  fReferenceLabSolidAngle = pset.get<double>("ReferenceLabSolidAngle");
113  fReferencePrtlMass = pset.get<double>("ReferencePrtlMass");
114  fReferenceScndPDG = pset.get<int>("ReferenceScndPDG");
115  fReferenceKaonEnergy = pset.get<double>("ReferenceKaonEnergy");
116 
118 
119  // TEST: compare this weight calc to calcENuWeight
120  // uncomment to run
121  /*
122  double p = twobody_momentum(kaonp_mass, pionp_mass, 0.);
123 
124  {
125  double beta = sqrt(fReferenceKaonEnergy*fReferenceKaonEnergy - kaonp_mass*kaonp_mass) / fReferenceKaonEnergy;
126  // Doen't affect weight
127  double rand = 1.;
128 
129  // For the maxweight, make the kaon and daughter direction aligned
130  TVector3 dir(0., 0, 1.);
131  TVector3 boost(0., 0., beta);
132  double lab_frame_p, costh_rest, weight;
133  int err = calcPrtlRayWgt(p, 0., dir, boost, rand, lab_frame_p, costh_rest, weight);
134  (void) err;
135 
136  std::cout << "REST FRAME P: " << p << std::endl;
137  std::cout << "THIS WEIGHT: " << weight << std::endl;
138  std::cout << "THIS P: " << lab_frame_p << std::endl;
139  }
140 
141  {
142  TVector3 start(0, 0, 0);
143  TVector3 end(0, 0, 100e2);
144 
145  bsim::Decay decay;
146  decay.ptype = 321;
147  decay.pdpx = 0.;
148  decay.pdpy = 0.;
149  decay.pdpz = sqrt(fReferenceKaonEnergy*fReferenceKaonEnergy - kaonp_mass*kaonp_mass);
150  decay.necm = p;
151  decay.vx = start.X();
152  decay.vy = start.Y();
153  decay.vz = start.Z();
154  decay.ndecay = 0;
155 
156  double weight, enu;
157  int err = bsim::calcEnuWgt(decay, end, enu, weight);
158  (void) err;
159 
160  std::cout << "BSIM WEIGHT: " << weight << std::endl;
161  std::cout << "BSIM P: " << enu << std::endl;
162  }
163  */
164 
165 }
166 
168  double kplus_mass = Constants::Instance().kplus_mass;
169  double secondary_mass = secPDG2Mass(fReferenceScndPDG);
170 
171  double p = twobody_momentum(kplus_mass, secondary_mass, fReferencePrtlMass);
172  double beta = sqrt(fReferenceKaonEnergy*fReferenceKaonEnergy - kplus_mass*kplus_mass) / fReferenceKaonEnergy;
173 
174  // Doen't affect weight
175  double rand = 1.;
176 
177  // For the maxweight, make the kaon and daughter direction aligned
178  TVector3 dir(1, 0, 0);
179  TVector3 boost(beta, 0., 0.);
180 
181  double lab_frame_p, costh_rest, weight;
182  int err = calcPrtlRayWgt(p, fReferencePrtlMass, dir, boost, rand, lab_frame_p, costh_rest, weight);
183 
184  if (err) { // Shouldn't happen
185  throw cet::exception("Weighted Ray Trace: Bad max weight calculation.");
186  }
187 
188  // Normalize the weight
189  fMaxWeight = weight * fReferenceLabSolidAngle / (4*M_PI);
190 }
191 
193  // In each dimension, figure out which of the face the location would intesect
194  bool intersect_MinX = loc.X() < fBox.MinX();
195  bool intersect_MinY = loc.Y() < fBox.MinY();
196  bool intersect_MinZ = loc.Z() < fBox.MinZ();
197 
198  bool intersect_MaxX = loc.X() > fBox.MaxX();
199  bool intersect_MaxY = loc.Y() > fBox.MaxY();
200  bool intersect_MaxZ = loc.Z() > fBox.MaxZ();
201 
202  // Solid angle of each surface
203  double solid_angleX = 0.;
204  double solid_angleY = 0.;
205  double solid_angleZ = 0.;
206 
207  // Compute the contribution to the solid angle of each face
208  if (intersect_MinX) {
209  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxZ() - fBox.MinZ());
210  TVector3 center(fBox.MinX(), fBox.CenterY(), fBox.CenterZ());
211 
212  solid_angleX = area * abs((center-loc).Unit().X()) / (center-loc).Mag2();
213  }
214  else if (intersect_MaxX) {
215  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxZ() - fBox.MinZ());
216  TVector3 center(fBox.MaxX(), fBox.CenterY(), fBox.CenterZ());
217 
218  solid_angleX = area * abs((center-loc).Unit().X()) / (center-loc).Mag2();
219  }
220 
221  if (intersect_MinY) {
222  double area = (fBox.MaxX() - fBox.MinX()) * (fBox.MaxZ() - fBox.MinZ());
223  TVector3 center(fBox.CenterX(), fBox.MinY(), fBox.CenterZ());
224 
225  solid_angleY = area * abs((center-loc).Unit().Y()) / (center-loc).Mag2();
226  }
227  else if (intersect_MaxY) {
228  double area = (fBox.MaxX() - fBox.MinX()) * (fBox.MaxZ() - fBox.MinZ());
229  TVector3 center(fBox.CenterX(), fBox.MaxY(), fBox.CenterZ());
230 
231  solid_angleY = area * abs((center-loc).Unit().Y()) / (center-loc).Mag2();
232  }
233 
234  if (intersect_MinZ) {
235  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxX() - fBox.MinX());
236  TVector3 center(fBox.CenterX(), fBox.CenterY(), fBox.MinZ());
237 
238  solid_angleZ = area * abs((center-loc).Unit().Z()) / (center-loc).Mag2();
239  }
240  else if (intersect_MaxZ) {
241  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxX() - fBox.MinX());
242  TVector3 center(fBox.CenterX(), fBox.CenterY(), fBox.MaxZ());
243 
244  solid_angleZ = area * abs((center-loc).Unit().Z()) / (center-loc).Mag2();
245  }
246 
247  // Pick which face to intersect
248  double rand = GetRandom();
249 
250  bool select_X = rand < solid_angleX / (solid_angleX + solid_angleY + solid_angleZ);
251  bool select_Y = !select_X && (rand < (solid_angleX + solid_angleY) / (solid_angleX + solid_angleY + solid_angleZ));
252  bool select_Z = !select_X && !select_Y;
253 
254  double X, Y, Z;
255  if (select_X) {
256  X = (intersect_MinX) ? fBox.MinX() : fBox.MaxX();
257  Y = (fBox.MaxY() - fBox.MinY()) * GetRandom() + fBox.MinY();
258  Z = (fBox.MaxZ() - fBox.MinZ()) * GetRandom() + fBox.MinZ();
259  }
260  if (select_Y) {
261  X = (fBox.MaxX() - fBox.MinX()) * GetRandom() + fBox.MinX();
262  Y = (intersect_MinY) ? fBox.MinY() : fBox.MaxY();
263  Z = (fBox.MaxZ() - fBox.MinZ()) * GetRandom() + fBox.MinZ();
264  }
265  if (select_Z) {
266  X = (fBox.MaxX() - fBox.MinX()) * GetRandom() + fBox.MinX();
267  Y = (fBox.MaxY() - fBox.MinY()) * GetRandom() + fBox.MinY();
268  Z = (intersect_MinZ) ? fBox.MinZ() : fBox.MaxZ();
269  }
270 
271  TVector3 ret(X, Y, Z);
272  return ret;
273 }
274 
276  // In each dimension, figure out which of the face the location would intesect
277  bool intersect_MinX = loc.X() < fBox.MinX();
278  bool intersect_MinY = loc.Y() < fBox.MinY();
279  bool intersect_MinZ = loc.Z() < fBox.MinZ();
280 
281  bool intersect_MaxX = loc.X() > fBox.MaxX();
282  bool intersect_MaxY = loc.Y() > fBox.MaxY();
283  bool intersect_MaxZ = loc.Z() > fBox.MaxZ();
284 
285  double solid_angle = 0.;
286 
287  // Compute the contribution to the solid angle of each face
288  if (intersect_MinX) {
289  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxZ() - fBox.MinZ());
290  TVector3 center(fBox.MinX(), fBox.CenterY(), fBox.CenterZ());
291 
292  solid_angle += area * abs((center-loc).Unit().X()) / (center-loc).Mag2();
293  }
294  if (intersect_MinY) {
295  double area = (fBox.MaxX() - fBox.MinX()) * (fBox.MaxZ() - fBox.MinZ());
296  TVector3 center(fBox.CenterX(), fBox.MinY(), fBox.CenterZ());
297 
298  solid_angle += area * abs((center-loc).Unit().Y()) / (center-loc).Mag2();
299  }
300  if (intersect_MinZ) {
301  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxX() - fBox.MinX());
302  TVector3 center(fBox.CenterX(), fBox.CenterY(), fBox.MinZ());
303 
304  solid_angle += area * abs((center-loc).Unit().Z()) / (center-loc).Mag2();
305  }
306 
307  if (intersect_MaxX) {
308  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxZ() - fBox.MinZ());
309  TVector3 center(fBox.MaxX(), fBox.CenterY(), fBox.CenterZ());
310 
311  solid_angle += area * abs((center-loc).Unit().X()) / (center-loc).Mag2();
312  }
313  if (intersect_MaxY) {
314  double area = (fBox.MaxX() - fBox.MinX()) * (fBox.MaxZ() - fBox.MinZ());
315  TVector3 center(fBox.CenterX(), fBox.MaxY(), fBox.CenterZ());
316 
317  solid_angle += area * abs((center-loc).Unit().Y()) / (center-loc).Mag2();
318  }
319  if (intersect_MaxZ) {
320  double area = (fBox.MaxY() - fBox.MinY()) * (fBox.MaxX() - fBox.MinX());
321  TVector3 center(fBox.CenterX(), fBox.CenterY(), fBox.MaxZ());
322 
323  solid_angle += area * abs((center-loc).Unit().Z()) / (center-loc).Mag2();
324  }
325 
326  return solid_angle;
327 
328 }
329 
330 bool WeightedRayTraceBox::IntersectDetector(MeVPrtlFlux &flux, std::array<TVector3, 2> &intersection, double &weight) {
331  // Randomly pick a location in the detector to send this particle to.
332  //
333  // Ensure that the point is picked uniformly in the lab-frame solid angle of the parent kaon
334  TVector3 detloc = RandomIntersectionPoint(flux.pos.Vect());
335 
336  // NOTE: picking a point uniformly in the volume does __not__ work!!!
337  // double detX = (fBox.MaxX() - fBox.MinX()) * GetRandom() + fBox.MinX();
338  // double detY = (fBox.MaxY() - fBox.MinY()) * GetRandom() + fBox.MinY();
339  // double detZ = (fBox.MaxZ() - fBox.MinZ()) * GetRandom() + fBox.MinZ();
340  // TVector3 detloc(detX, detY, detZ);
341 
342  // calculate the weight and kinematics of sending the flux here
343  TLorentzVector flux_mom_rest = flux.mom;
344  flux_mom_rest.Boost(-flux.kmom.BoostVector());
345  double rest_frame_p = flux_mom_rest.Vect().Mag();
346  double p_lab, costh_rest;
347  int err = calcPrtlRayWgt(rest_frame_p, flux.mom.M(), detloc - flux.pos.Vect(), flux.kmom.BoostVector(), GetRandom(),
348  p_lab, costh_rest, weight);
349 
350  // Kinematics don't work
351  if (err) return false;
352 
353  // Adjust the input flux to the computed kinematics
354  flux.mom.SetVectM(p_lab * (detloc - flux.pos.Vect()).Unit(), flux.mom.M());
355 
356  // And correct all the other variables
357  flux.mom_beamcoord = flux.mom;
358  flux.mom_beamcoord.Boost(-flux.kmom.BoostVector());
359  flux.mom_beamcoord.Boost(flux.kmom_beamcoord.BoostVector());
360 
361  flux.sec = flux.kmom - flux.mom;
362  flux.sec_beamcoord = flux.kmom_beamcoord - flux.mom_beamcoord;
363 
364  // Compute the intersections for the selected point
365  std::vector<TVector3> box_intersections = fBox.GetIntersections(flux.pos.Vect(), flux.mom.Vect().Unit());
366  TVector3 A = box_intersections.at(0);
367  TVector3 B = box_intersections.at(1);
368  if ((flux.pos.Vect() - A).Mag() < (flux.pos.Vect() - B).Mag()) {
369  intersection = {A, B}; // A is entry, B is exit
370  }
371  else {
372  intersection = {B, A}; // reversed
373  }
374 
375  // Turn the weight into an event weight
376  weight *= SolidAngle(flux.pos.Vect()) / (4*M_PI);
377 
378  std::cout << "From: " << flux.pos.X() << " " << flux.pos.Y() << " " << flux.pos.Z() << std::endl;
379  std::cout << "Solid Angle ratio is: " << (SolidAngle(flux.pos.Vect()) / (4*M_PI)) << std::endl;
380 
381  std::cout << "Kaon 4P: " << flux.kmom.E() << " " << flux.kmom.Px() << " " << flux.kmom.Py() << " " << flux.kmom.Pz() << std::endl;
382  std::cout << "Selected Prtl 4P: " << flux.mom.E() << " " << flux.mom.Px() << " " << flux.mom.Py() << " " << flux.mom.Pz() << std::endl;
383  std::cout << "Selected Scdy 4P: " << flux.sec.E() << " " << flux.sec.Px() << " " << flux.sec.Py() << " " << flux.sec.Pz() << std::endl;
384 
385  // check the costh calc
386  TLorentzVector flux_rest = flux.mom;
387  flux_rest.Boost(-flux.kmom.BoostVector());
388  std::cout << "Prtl lab costh: " << costh_rest << " " << flux.kmom.Vect().Unit().Dot(flux_rest.Vect().Unit()) << std::endl;
389 
390  return true;
391 }
392 
393 DEFINE_ART_CLASS_TOOL(WeightedRayTraceBox)
394 
395 } // namespace ldm
396 } // namespace evgen
TLorentzVector sec_beamcoord
Definition: MeVPrtlFlux.h:17
Utilities related to art service access.
TLorentzVector mom
Definition: MeVPrtlFlux.h:14
const geo::GeometryCore * geometry
double secPDG2Mass(int pdg)
Definition: Constants.cpp:236
TLorentzVector mom_beamcoord
Definition: MeVPrtlFlux.h:15
EResult err(const char *call)
pdgs p
Definition: selectors.fcl:22
double MinX() const
Returns the world x coordinate of the start of the box.
Definition: BoxBoundedGeo.h:88
geo::BoxBoundedGeo DetectorEnclosureBox(std::string const &name="volDetEnclosure") const
double CenterX() const
Returns the world x coordinate of the center of the box.
Definition: BoxBoundedGeo.h:94
double CenterZ() const
Returns the world z coordinate of the center of the box.
double twobody_momentum(double parent_mass, double childA_mass, double childB_mass)
Definition: Constants.cpp:73
double MaxX() const
Returns the world x coordinate of the end of the box.
Definition: BoxBoundedGeo.h:91
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
Access the description of detector geometry.
void configure(const fhicl::ParameterSet &) override
Interface for configuring the particular algorithm tool.
T abs(T value)
TLorentzVector kmom
Definition: MeVPrtlFlux.h:13
double MinZ() const
Returns the world z coordinate of the start of the box.
WeightedRayTraceBox class definiton.
IMeVPrtlStage interface class definiton. General interface behind each stage. Provides random number ...
Definition: IMeVPrtlStage.h:36
Description of geometry of one entire detector.
IRayTrace interface class definiton.
Definition: IRayTrace.h:39
TVector3 RandomIntersectionPoint(TVector3 loc)
Provides a base class aware of world box coordinates.
double MaxY() const
Returns the world y coordinate of the end of the box.
tuple dir
Definition: dropbox.py:28
static const Constants & Instance()
Definition: Constants.h:68
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
Definition: BoxBoundedGeo.h:33
double CenterY() const
Returns the world y coordinate of the center of the box.
double MaxZ() const
Returns the world z coordinate of the end of the box.
TLorentzVector pos
Definition: MeVPrtlFlux.h:11
std::vector< TVector3 > GetIntersections(TVector3 const &TrajectoryStart, TVector3 const &TrajectoryDirect) const
Calculates the entry and exit points of a trajectory on the box surface.
float A
Definition: dedx.py:137
This provides an interface for an art tool which ray traces &quot;Prtl&quot; (massive) particles from their pro...
double MinY() const
Returns the world y coordinate of the start of the box.
WeightedRayTraceBox(fhicl::ParameterSet const &pset)
Constructor.
TLorentzVector kmom_beamcoord
Definition: MeVPrtlFlux.h:12
art framework interface to geometry description
BEGIN_PROLOG could also be cout
TLorentzVector sec
Definition: MeVPrtlFlux.h:16
bool IntersectDetector(MeVPrtlFlux &flux, std::array< TVector3, 2 > &intersection, double &weight) override
int calcPrtlRayWgt(double rest_frame_p, double M, TVector3 dir, TVector3 boost, double rand, double &lab_frame_p_out, double &costh_rest_out, double &wgt)
Definition: Constants.cpp:102