LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
GFDetPlane.cxx
Go to the documentation of this file.
1 /* Copyright 2008-2010, Technische Universitaet Muenchen,
2  Authors: Christian Hoeppner & Sebastian Neubert
3 
4  This file is part of GENFIT.
5 
6  GENFIT is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  GENFIT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18 */
22 
23 #include <cmath>
24 #include <iostream>
25 
26 #include "Rtypes.h"
27 #include "TMath.h"
28 #include "TPolyLine3D.h"
29 #include "TPolyMarker3D.h"
30 #include "TRandom3.h"
31 
32 //ClassImp(GFDetPlane)
33 
34 genf::GFDetPlane::GFDetPlane(const TVector3& o,
35  const TVector3& u,
36  const TVector3& v,
37  GFAbsFinitePlane* finite)
38  : fO(o), fU(u), fV(v), fFinitePlane(finite)
39 {
40  sane();
41 }
43 {
44  static TRandom3 r(0);
45  fO.SetXYZ(0., 0., 0.);
46  fU.SetXYZ(r.Uniform(), r.Uniform(), 0.);
47  fV.SetXYZ(r.Uniform(), r.Uniform(), 0.);
48  sane();
49 }
50 
51 genf::GFDetPlane::GFDetPlane(const TVector3& o, const TVector3& n, GFAbsFinitePlane* finite)
52  : fO(o), fFinitePlane(finite)
53 {
54  setNormal(n);
55 }
56 
58 {
59  if (fFinitePlane != NULL) delete fFinitePlane;
60 }
61 
63 {
64  if (rhs.fFinitePlane != NULL)
66  else
67  fFinitePlane = NULL;
68  fO = rhs.fO;
69  fU = rhs.fU;
70  fV = rhs.fV;
71 }
73 {
74  if (this == &rhs) return *this;
75  if (fFinitePlane != NULL) { delete fFinitePlane; }
76  if (rhs.fFinitePlane != NULL) { fFinitePlane = rhs.fFinitePlane->clone(); }
77  else {
78  fFinitePlane = NULL;
79  }
80  fO = rhs.fO;
81  fU = rhs.fU;
82  fV = rhs.fV;
83  return *this;
84 }
85 
86 void genf::GFDetPlane::set(const TVector3& o, const TVector3& u, const TVector3& v)
87 {
88  fO = o;
89  fU = u;
90  fV = v;
91  sane();
92 }
93 
94 void genf::GFDetPlane::setO(const TVector3& o)
95 {
96  fO = o;
97  sane();
98 }
99 void genf::GFDetPlane::setO(double X, double Y, double Z)
100 {
101  fO.SetXYZ(X, Y, Z);
102  sane();
103 }
104 
105 void genf::GFDetPlane::setU(const TVector3& u)
106 {
107  fU = u;
108  sane();
109 }
110 void genf::GFDetPlane::setU(double X, double Y, double Z)
111 {
112  fU.SetXYZ(X, Y, Z);
113  sane();
114 }
115 
116 void genf::GFDetPlane::setV(const TVector3& v)
117 {
118  fV = v;
119  sane();
120 }
121 void genf::GFDetPlane::setV(double X, double Y, double Z)
122 {
123  fV.SetXYZ(X, Y, Z);
124  sane();
125 }
126 void genf::GFDetPlane::setUV(const TVector3& u, const TVector3& v)
127 {
128  fU = u;
129  fV = v;
130  sane();
131 }
132 
134 {
135  TVector3 result = fU.Cross(fV);
136  result.SetMag(1.);
137  return result;
138 }
139 
140 void genf::GFDetPlane::setON(const TVector3& o, const TVector3& n)
141 {
142  fO = o;
143  setNormal(n);
144 }
145 
146 void genf::GFDetPlane::setNormal(double X, double Y, double Z)
147 {
148  TVector3 N(X, Y, Z);
149  setNormal(N);
150 }
152 {
153  n.SetMag(1.);
154  if (fabs(n.X()) > 0.1) {
155  fU.SetXYZ(1. / n.X() * (-1. * n.Y() - 1. * n.Z()), 1., 1.);
156  fU.SetMag(1.);
157  }
158  else {
159  if (fabs(n.Y()) > 0.1) {
160  fU.SetXYZ(1., 1. / n.Y() * (-1. * n.X() - 1. * n.Z()), 1.);
161  fU.SetMag(1.);
162  }
163  else {
164  fU.SetXYZ(1., 1., 1. / n.Z() * (-1. * n.X() - 1. * n.Y()));
165  fU.SetMag(1.);
166  }
167  }
168  fV = n.Cross(fU);
169 }
170 
171 void genf::GFDetPlane::setNormal(const double& theta, const double& phi)
172 {
173  TVector3 n(
174  TMath::Sin(theta) * TMath::Cos(phi), TMath::Sin(theta) * TMath::Sin(phi), TMath::Cos(theta));
175  setNormal(n);
176 }
177 
178 TVector2 genf::GFDetPlane::project(const TVector3& x) const
179 {
180  Double_t xfU = fU * x;
181  Double_t xfV = fV * x;
182  return TVector2(xfU, xfV);
183 }
184 
185 TVector2 genf::GFDetPlane::LabToPlane(const TVector3& x) const
186 {
187  TVector3 d = x - fO;
188  return project(d);
189 }
190 
191 TVector3 genf::GFDetPlane::toLab(const TVector2& x) const
192 {
193  TVector3 d(fO);
194  d += x.X() * fU;
195  d += x.Y() * fV;
196  return d;
197 }
198 
199 TVector3 genf::GFDetPlane::dist(const TVector3& x) const
200 {
201  TVector2 p = LabToPlane(x);
202  TVector3 xplane = toLab(p);
203  return xplane - x;
204 }
205 
207 {
208  if (fU == fV)
209  throw GFException("genf::GFDetPlane::sane() sanity check failed", __LINE__, __FILE__)
210  .setFatal();
211  // ensure unit vectors
212  fU.SetMag(1.);
213  fV.SetMag(1.);
214  // ensure orthogonal system
215  // fV should be reached by
216  // rotating fU around _n in a counterclockwise direction
217 
218  TVector3 n = getNormal();
219  fV = n.Cross(fU);
220 
221  TVector3 v = fU;
222  v.Rotate(TMath::Pi() * 0.5, n);
223  TVector3 null = v - fV;
224  if (null.Mag() >= 1E-6)
225  throw GFException("genf::GFDetPlane::sane(): non orthogonal!", __LINE__, __FILE__).setFatal();
226 }
227 
228 void genf::GFDetPlane::Print(std::ostream& out /* = std::cout */) const
229 {
230  out << "GFDetPlane: "
231  << "O(" << fO.X() << "," << fO.Y() << "," << fO.Z() << ") "
232  << "u(" << fU.X() << "," << fU.Y() << "," << fU.Z() << ") "
233  << "v(" << fV.X() << "," << fV.Y() << "," << fV.Z() << ") "
234  << "n(" << getNormal().X() << "," << getNormal().Y() << "," << getNormal().Z() << ") "
235  << std::endl;
236  out << fFinitePlane << std::endl;
237  if (fFinitePlane != NULL) fFinitePlane->Print(out);
238 }
239 
240 /*
241  I could write pages of comments about correct equality checking for
242  floating point numbers, but: When two planes are as close as 10E-5 cm
243  in all nine numbers that define the plane, this will be enough for all
244  practical purposes
245  */
246 
247 // == and != are friends, not members, hence not "genf::GFDetPlane::operater==" below.
248 #define DETPLANE_EPSILON 1.E-5
249 bool genf::operator==(const GFDetPlane& lhs, const GFDetPlane& rhs)
250 {
251  if (fabs((lhs.fO.X() - rhs.fO.X())) > DETPLANE_EPSILON ||
252  fabs((lhs.fO.Y() - rhs.fO.Y())) > DETPLANE_EPSILON ||
253  fabs((lhs.fO.Z() - rhs.fO.Z())) > DETPLANE_EPSILON)
254  return false;
255  else if (fabs((lhs.fU.X() - rhs.fU.X())) > DETPLANE_EPSILON ||
256  fabs((lhs.fU.Y() - rhs.fU.Y())) > DETPLANE_EPSILON ||
257  fabs((lhs.fU.Z() - rhs.fU.Z())) > DETPLANE_EPSILON)
258  return false;
259  else if (fabs((lhs.fV.X() - rhs.fV.X())) > DETPLANE_EPSILON ||
260  fabs((lhs.fV.Y() - rhs.fV.Y())) > DETPLANE_EPSILON ||
261  fabs((lhs.fV.Z() - rhs.fV.Z())) > DETPLANE_EPSILON)
262  return false;
263  return true;
264 }
265 
266 bool genf::operator!=(const GFDetPlane& lhs, const GFDetPlane& rhs)
267 {
268  return !(lhs == rhs);
269 }
270 
272  double length,
273  TPolyMarker3D** pl,
274  TPolyLine3D** plLine,
275  TPolyLine3D** u,
276  TPolyLine3D** v,
277  TPolyLine3D** n)
278 {
279  *pl = new TPolyMarker3D(21 * 21, 24);
280  (*pl)->SetMarkerSize(0.1);
281  (*pl)->SetMarkerColor(kBlue);
282  int nI = 10;
283  int nJ = 10;
284  *plLine = new TPolyLine3D(5);
285 
286  {
287  TVector3 linevec;
288  int i, j;
289  i = -1 * nI;
290  j = -1 * nJ;
291  linevec = (fO + (mesh * i) * fU + (mesh * j) * fV);
292  (*plLine)->SetPoint(0, linevec.X(), linevec.Y(), linevec.Z());
293  i = -1 * nI;
294  j = 1 * nJ;
295  linevec = (fO + (mesh * i) * fU + (mesh * j) * fV);
296  (*plLine)->SetPoint(0, linevec.X(), linevec.Y(), linevec.Z());
297  i = 1 * nI;
298  j = -1 * nJ;
299  linevec = (fO + (mesh * i) * fU + (mesh * j) * fV);
300  (*plLine)->SetPoint(2, linevec.X(), linevec.Y(), linevec.Z());
301  i = 1 * nI;
302  j = 1 * nJ;
303  linevec = (fO + (mesh * i) * fU + (mesh * j) * fV);
304  (*plLine)->SetPoint(1, linevec.X(), linevec.Y(), linevec.Z());
305  i = -1 * nI;
306  j = -1 * nJ;
307  linevec = (fO + (mesh * i) * fU + (mesh * j) * fV);
308  (*plLine)->SetPoint(4, linevec.X(), linevec.Y(), linevec.Z());
309  }
310  for (int i = -1 * nI; i <= nI; ++i) {
311  for (int j = -1 * nJ; j <= nJ; ++j) {
312  TVector3 vec(fO + (mesh * i) * fU + (mesh * j) * fV);
313  int id = (i + 10) * 21 + j + 10;
314  (*pl)->SetPoint(id, vec.X(), vec.Y(), vec.Z());
315  }
316  }
317 
318  *u = new TPolyLine3D(2);
319  (*u)->SetPoint(0, fO.X(), fO.Y(), fO.Z());
320  (*u)->SetPoint(1, fO.X() + length * fU.X(), fO.Y() + length * fU.Y(), fO.Z() + length * fU.Z());
321  (*u)->SetLineWidth(2);
322  (*u)->SetLineColor(kGreen);
323 
324  *v = new TPolyLine3D(2);
325  (*v)->SetPoint(0, fO.X(), fO.Y(), fO.Z());
326  (*v)->SetPoint(1, fO.X() + length * fV.X(), fO.Y() + length * fV.Y(), fO.Z() + length * fV.Z());
327  (*v)->SetLineWidth(2);
328  (*v)->SetLineColor(kRed);
329 
330  if (n != NULL) {
331  *n = new TPolyLine3D(2);
332  TVector3 _n = getNormal();
333  (*n)->SetPoint(0, fO.X(), fO.Y(), fO.Z());
334  (*n)->SetPoint(1, fO.X() + length * _n.X(), fO.Y() + length * _n.Y(), fO.Z() + length * _n.Z());
335  (*n)->SetLineWidth(2);
336  (*n)->SetLineColor(kBlue);
337  }
338 }
339 
340 double genf::GFDetPlane::distance(TVector3& v) const
341 {
342  double s = (v - fO) * fU;
343  double t = (v - fO) * fV;
344  TVector3 distanceVector = v - fO - (s * fU) - (t * fV);
345  return distanceVector.Mag();
346 }
347 double genf::GFDetPlane::distance(double x, double y, double z) const
348 {
349  TVector3 v(x, y, z);
350  double s = (v - fO) * fU;
351  double t = (v - fO) * fV;
352  TVector3 distanceVector = v - fO - (s * fU) - (t * fV);
353  return distanceVector.Mag();
354 }
355 
356 TVector2 genf::GFDetPlane::straightLineToPlane(const TVector3& point, const TVector3& dir) const
357 {
358  TVector3 dirNorm(dir);
359  dirNorm.SetMag(1.);
360  TVector3 normal = getNormal();
361  double dirTimesN = dirNorm * normal;
362  if (fabs(dirTimesN) < 1.E-6) { //straight line is parallel to plane, so return infinity
363  //doesnt parallel mean that they cross in infinity ;-)
364  return TVector2(1.E100, 1.E100);
365  }
366  double t = 1 / dirTimesN * ((fO - point) * normal);
367  return project(point - fO + t * dirNorm);
368 }
Float_t x
Definition: compare.C:6
TRandom r
Definition: spectrum.C:23
void set(const TVector3 &o, const TVector3 &u, const TVector3 &v)
Definition: GFDetPlane.cxx:86
void setON(const TVector3 &o, const TVector3 &n)
Definition: GFDetPlane.cxx:140
void setU(const TVector3 &u)
Definition: GFDetPlane.cxx:105
GFDetPlane & operator=(const genf::GFDetPlane &)
Definition: GFDetPlane.cxx:72
bool operator!=(const genf::GFDetPlane &, const genf::GFDetPlane &)
Definition: GFDetPlane.cxx:266
void getGraphics(double mesh, double length, TPolyMarker3D **pl, TPolyLine3D **plLine, TPolyLine3D **u, TPolyLine3D **v, TPolyLine3D **n=NULL)
for poor attempts of making an event display. There is a lot of room for improvements.
Definition: GFDetPlane.cxx:271
TVector3 dist(const TVector3 &point) const
Definition: GFDetPlane.cxx:199
Float_t y
Definition: compare.C:6
Double_t z
Definition: plot.C:276
Float_t Y
Definition: plot.C:37
void setO(const TVector3 &o)
Definition: GFDetPlane.cxx:94
void setUV(const TVector3 &u, const TVector3 &v)
Definition: GFDetPlane.cxx:126
void Print(std::ostream &out=std::cout) const
Definition: GFDetPlane.cxx:228
#define DETPLANE_EPSILON
Definition: GFDetPlane.cxx:248
TVector2 project(const TVector3 &x) const
projecting a direction onto the plane:
Definition: GFDetPlane.cxx:178
Float_t Z
Definition: plot.C:37
virtual void Print(std::ostream &out=std::cout) const =0
TVector3 getNormal() const
Definition: GFDetPlane.cxx:133
void setV(const TVector3 &v)
Definition: GFDetPlane.cxx:116
double distance(TVector3 &) const
Definition: GFDetPlane.cxx:340
Float_t E
Definition: plot.C:20
bool operator==(const genf::GFDetPlane &, const genf::GFDetPlane &)
Definition: GFDetPlane.cxx:249
genf::GFAbsFinitePlane * fFinitePlane
Definition: GFDetPlane.h:160
TVector3 toLab(const TVector2 &x) const
transform from plane coordinates to lab system
Definition: GFDetPlane.cxx:191
TVector2 LabToPlane(const TVector3 &x) const
transform from Lab system into plane
Definition: GFDetPlane.cxx:185
Float_t d
Definition: plot.C:235
virtual ~GFDetPlane()
Definition: GFDetPlane.cxx:57
TVector2 straightLineToPlane(const TVector3 &point, const TVector3 &dir) const
gives u,v coordinates of the intersection point of a straight line with plane
Definition: GFDetPlane.cxx:356
Exception class for error handling in GENFIT (provides storage for diagnostic information) ...
Definition: GFException.h:47
TDirectory * dir
Definition: macro.C:5
void setNormal(TVector3 n)
Definition: GFDetPlane.cxx:151
GFException & setFatal(bool b=true)
set fatal flag. if this is true, the fit stops for this current track repr.
Definition: GFException.h:75
Char_t n[5]
Float_t X
Definition: plot.C:37
virtual GFAbsFinitePlane * clone() const =0
Deep copy ctor for polymorphic class.
GFDetPlane(genf::GFAbsFinitePlane *finite=NULL)
Definition: GFDetPlane.cxx:42