All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
helper_math.cxx
Go to the documentation of this file.
3 
4 namespace single_photon
5 {
6  //-----------------HELPER FUNCTIONS -----------
7  ////line between x1 and x2, point x0;
8  double dist_line_point( std::vector<double>&X1, std::vector<double>& X2, std::vector<double>& point){
9  double x1 =X1.at(0);
10  double y1 =X1.at(1);
11  double z1 =X1.at(2);
12 
13  double x2 =X2.at(0);
14  double y2 =X2.at(1);
15  double z2 =X2.at(2);
16 
17  double x0 =point.at(0);
18  double y0 =point.at(1);
19  double z0 =point.at(2);
20 
21  double x10 = x1-x0;
22  double y10 = y1-y0;
23  double z10 = z1-z0;
24 
25  double x21 = x2-x1;
26  double y21 = y2-y1;
27  double z21 = z2-z1;
28 
29  double t = -(x10*x21+y10*y21+z10*z21)/fabs(x21*x21+y21*y21+z21*z21 );
30  // right, but can be simplified
31  double d2 = pow(x1-x0,2)+pow(y1-y0,2)+pow(z1-z0,2)+2*t*((x2-x1)*(x1-x0)+(y2-y1)*(y1-y0)+(z2-z1)*(z1-z0))+t*t*( pow(x2-x1,2)+pow(y2-y1,2)+pow(z2-z1,2));
32 
33  return sqrt(d2);
34  }
35 
36 
37  //--------------- end of copying from bad_channel_matching.h
38 
39  double impact_paramater_shr(double x, double y, double z, art::Ptr<recob::Shower> & shr){
40 
41  std::vector<double> vert = {x,y,z};
42  std::vector<double> start = {shr->ShowerStart().X(), shr->ShowerStart().Y(),shr->ShowerStart().Z()};
43  std::vector<double> abit = {shr->ShowerStart().X() + shr->Direction().X(), shr->ShowerStart().Y()+shr->Direction().Y(), shr->ShowerStart().Z()+shr->Direction().Z()};
44 
45  return dist_line_point(start, abit, vert);
46 
47  }
48 
49  // invariant mass of a particle that decays to two showers
50  double implied_invar_mass(double vx, double vy, double vz, art::Ptr<recob::Shower> & s1, double E1, art::Ptr<recob::Shower> &s2, double E2){
51 
52  double s1x = s1->ShowerStart().X()-vx;
53  double s1y = s1->ShowerStart().Y()-vy;
54  double s1z = s1->ShowerStart().Z()-vz;
55  double norm1 = std::hypot(s1x,s1y,s1z);//distance btw two points with coordinate difference s1x, s1y, s1z
56  s1x = s1x/norm1; //unit vector pointing to shower start from point (vx, vy,vz)
57  s1y = s1y/norm1;
58  s1z = s1z/norm1;
59 
60  double s2x = s2->ShowerStart().X()-vx;
61  double s2y = s2->ShowerStart().Y()-vy;
62  double s2z = s2->ShowerStart().Z()-vz;
63  double norm2 = std::hypot(s2x,s2y,s2z);
64  s2x = s2x/norm2; // unit vector pointing to shower start from point (vx, vy, vz)
65  s2y = s2y/norm2;
66  s2z = s2z/norm2;
67 
68  return sqrt(2.0*E1*E2*(1.0-(s1x*s2x+s1y*s2y+s1z*s2z)));
69 
70 
71  }
72 
73  // invariant mass of two showers, calculated directly from shower directions
74  double invar_mass(art::Ptr<recob::Shower> & s1, double E1, art::Ptr<recob::Shower> &s2, double E2){
75 
76  double s1x = s1->Direction().X();
77  double s1y = s1->Direction().Y();
78  double s1z = s1->Direction().Z();
79 
80  double s2x = s2->Direction().X();
81  double s2y = s2->Direction().Y();
82  double s2z = s2->Direction().Z();
83 
84  return sqrt(2.0*E1*E2*(1.0-(s1x*s2x+s1y*s2y+s1z*s2z)));
85 
86  }
87 
88  double getMedian(std::vector<double> thisvector){
89  size_t len = thisvector.size();
90  if(len < 1) return NAN;
91 
92  std::sort(thisvector.begin(), thisvector.end());
93  if(len % 2 != 0){//even - return average of two at median
94  return 0.5*(thisvector[len/2]+thisvector[len/2+1]);
95  }else{//odd - return the median
96  return thisvector[len/2];
97  }
98  }
99 
100  /* returns (generally) best median dEdx of all 3
101  * planes, usually plane 2 */
103  double angle_wrt_plane0,
104  double angle_wrt_plane1,
105  double angle_wrt_plane2,
106  double median_plane0,
107  double median_plane1,
108  double median_plane2,
109  int plane0_nhits,
110  int plane1_nhits,
111  int plane2_nhits){
112  //if the shower is within 10 degrees of the wires on plane 2, consider planes 1 and 0
113  if(angle_wrt_plane2< degToRad(10)){
114  //if it's too close to the wires on either of the planes, then stick with plane 2
115  if (angle_wrt_plane1> degToRad(20)|| angle_wrt_plane0>degToRad(20) ){
116  //but if it's outside of the range on plane 1, choose that
117  if(angle_wrt_plane1> angle_wrt_plane0){
118  return median_plane1;
119  } else{
120  return median_plane0;
121  }
122  }
123  }
124  if (plane2_nhits< 2){
125  if (plane1_nhits >=2 ){
126  return median_plane1;
127  } else if (plane0_nhits >=2 ){
128  return median_plane0;
129  }
130  }
131  return median_plane2;
132  }
133 
134  /* returns the number of hits on the plane picked by function getAmalgamateddEdx */
136  double amalgamateddEdx,
137  double median_plane0,
138  double median_plane1,
139  double median_plane2,
140  int plane0_nhits,
141  int plane1_nhits,
142  int plane2_nhits){
143  if (amalgamateddEdx == median_plane0){
144  return plane0_nhits;
145  }
146  if (amalgamateddEdx == median_plane1){
147  return plane1_nhits;
148  }
149  if (amalgamateddEdx == median_plane2){
150  return plane2_nhits;
151  }
152  return -999;
153  }
154 
155 
156  /**
157  *@brief Calculates the four corners of a rectangle of given length and width around a cluster given the start point and axis direction
158  *@param cluster_start - the start position of a cluster in CM
159  *@param cluster_axis - calculated from the cluster end minus the cluster start
160  *@param width - typically ~1cm
161  *@param length - typically a few cm
162  *
163  * */
164  std::vector<std::vector<double>> buildRectangle(std::vector<double> cluster_start, std::vector<double> cluster_axis, double width, double length){
165  std::vector<std::vector<double>> corners;
166 
167  //get the axis perpedicular to the cluster axis
168  double perp_axis[2] = {-cluster_axis[1], cluster_axis[0]};
169 
170  //create a vector for each corner of the rectangle on the plane
171  //c1 = bottom left corner
172  std::vector<double> c1 = {cluster_start[0] + perp_axis[0] * width / 2, cluster_start[1] + perp_axis[1] * width / 2};
173  //c2 = top left corner
174  std::vector<double> c2 = {c1[0] + cluster_axis[0] * length, c1[1] + cluster_axis[1] * length};
175  //c3 = bottom right corner
176  std::vector<double> c3 = {cluster_start[0] - perp_axis[0] * width / 2, cluster_start[1] - perp_axis[1] * width / 2};
177  //c4 = top right corner
178  std::vector<double> c4 ={c3[0] + cluster_axis[0] * length, c3[1] + cluster_axis[1] * length};
179 
180  //save each of the vectors
181  corners.push_back(c1);
182  corners.push_back(c2);
183  corners.push_back(c4);
184  corners.push_back(c3);
185  return corners;
186  }
187 
188 }
process_name opflash particleana ie ie ie z
process_name opflash particleana ie x
int getAmalgamateddEdxNHits(double amalgamateddEdx, double median_plane0, double median_plane1, double median_plane2, int plane0_nhits, int plane1_nhits, int plane2_nhits)
double degToRad(double deg)
Definition: helper_math.h:64
double dist_line_point(std::vector< double > &X1, std::vector< double > &X2, std::vector< double > &point)
Definition: helper_math.cxx:8
double invar_mass(art::Ptr< recob::Shower > &s1, double E1, art::Ptr< recob::Shower > &s2, double E2)
Definition: helper_math.cxx:74
double implied_invar_mass(double vx, double vy, double vz, art::Ptr< recob::Shower > &s1, double E1, art::Ptr< recob::Shower > &s2, double E2)
Definition: helper_math.cxx:50
process_name opflash particleana ie ie y
std::vector< std::vector< double > > buildRectangle(std::vector< double > cluster_start, std::vector< double > cluster_axis, double width, double length)
Calculates the four corners of a rectangle of given length and width around a cluster given the start...
double getAmalgamateddEdx(double angle_wrt_plane0, double angle_wrt_plane1, double angle_wrt_plane2, double median_plane0, double median_plane1, double median_plane2, int plane0_nhits, int plane1_nhits, int plane2_nhits)
double impact_paramater_shr(double x, double y, double z, art::Ptr< recob::Shower > &shr)
Definition: helper_math.cxx:39
double getMedian(std::vector< double > thisvector)
Definition: helper_math.cxx:88
helper function for LArPandoraInterface producer module