SurfXYZPlane.cxx
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////
2 ///
3 /// \file SurfXYZPlane.cxx
4 ///
5 /// \brief General planar surface.
6 ///
7 /// \author H. Greenlee
8 ///
9 ////////////////////////////////////////////////////////////////////////
10 
11 #include <cmath>
13 #include "cetlib_except/exception.h"
14 #include "TVector2.h"
15 
16 namespace trkf {
17 
18  // Static attributes.
19 
20  double SurfXYZPlane::fPhiTolerance = 1.e-10;
21  double SurfXYZPlane::fThetaTolerance = 1.e-10;
22  double SurfXYZPlane::fSepTolerance = 1.e-6;
23 
24  /// Default constructor.
26  fX0(0.),
27  fY0(0.),
28  fZ0(0.),
29  fPhi(0.),
30  fTheta(0.)
31  {}
32 
33  /// Initializing constructor.
34  ///
35  /// Arguments:
36  ///
37  /// x0, y0, z0 - Global coordinates of local origin.
38  /// phi - Rotation angle about x-axis (wire angle).
39  /// theta - Rotation angle about y'-axis (projected Lorentz angle).
40  ///
41  SurfXYZPlane::SurfXYZPlane(double x0, double y0, double z0, double phi, double theta) :
42  fX0(x0),
43  fY0(y0),
44  fZ0(z0),
45  fPhi(phi),
46  fTheta(theta)
47  {}
48 
49  /// Initializing constructor (normal vector).
50  ///
51  /// Arguments:
52  ///
53  /// x0, y0, z0 - Global coordinates of local origin.
54  /// nx, ny, nz - Normal vector in global coordinate system.
55  ///
56  SurfXYZPlane::SurfXYZPlane(double x0, double y0, double z0,
57  double nx, double ny, double nz) :
58  fX0(x0),
59  fY0(y0),
60  fZ0(z0),
61  fPhi(0.),
62  fTheta(0.)
63  {
64  // Calculate angles.
65 
66  double nyz = std::hypot(ny, nz);
67  fTheta = atan2(nx, nyz);
68  fPhi = 0.;
69  if(nyz != 0.)
70  fPhi = atan2(-ny, nz);
71  }
72 
73  /// Destructor.
75  {}
76 
77  /// Clone method.
79  {
80  return new SurfXYZPlane(*this);
81  }
82 
83  /// Surface-specific tests of validity of track parameters.
84  bool SurfXYZPlane::isTrackValid(const TrackVector& vec) const
85  {
86  return true;
87  }
88 
89  /// Transform global to local coordinates.
90  ///
91  /// Arguments:
92  ///
93  /// xyz - Cartesian coordinates in global coordinate system.
94  /// uvw - Cartesian coordinates in local coordinate system.
95  ///
96  void SurfXYZPlane::toLocal(const double xyz[3], double uvw[3]) const
97  {
98  double sinth = std::sin(fTheta);
99  double costh = std::cos(fTheta);
100  double sinphi = std::sin(fPhi);
101  double cosphi = std::cos(fPhi);
102 
103  // u = (x-x0)*cos(theta) + (y-y0)*sin(theta)*sin(phi) - (z-z0)*sin(theta)*cos(phi)
104  uvw[0] = (xyz[0]-fX0)*costh + (xyz[1]-fY0)*sinth*sinphi - (xyz[2]-fZ0)*sinth*cosphi;
105 
106  // v = (y-y0)*cos(phi) + (z-z0)*sin(phi)
107  uvw[1] = (xyz[1]-fY0)*cosphi + (xyz[2]-fZ0)*sinphi;
108 
109  // w = (x-x0)*sin(theta) - (y-y0)*cos(theta)*sin(phi) + (z-z0)*cos(theta)*cos(phi)
110  uvw[2] = (xyz[0]-fX0)*sinth - (xyz[1]-fY0)*costh*sinphi + (xyz[2]-fZ0)*costh*cosphi;
111  }
112 
113  /// Transform local to global coordinates.
114  ///
115  /// Arguments:
116  ///
117  /// uvw - Cartesian coordinates in local coordinate system.
118  /// xyz - Cartesian coordinates in global coordinate system.
119  ///
120  void SurfXYZPlane::toGlobal(const double uvw[3], double xyz[3]) const
121  {
122  double sinth = std::sin(fTheta);
123  double costh = std::cos(fTheta);
124  double sinphi = std::sin(fPhi);
125  double cosphi = std::cos(fPhi);
126 
127  // x = x0 + u*cos(theta) + w*sin(theta)
128  xyz[0] = fX0 + uvw[0]*costh + uvw[2]*sinth;
129 
130  // y = y0 + u*sin(theta)*sin(phi) + v*cos(phi) - w*cos(theta)*sin(phi)
131  xyz[1] = fY0 + uvw[0]*sinth*sinphi + uvw[1]*cosphi - uvw[2]*costh*sinphi;
132 
133  // z = z0 - u*sin(theta)*cos(phi) + v*sin(phi) + w*cos(theta)*cos(phi)
134  xyz[2] = fZ0 - uvw[0]*sinth*cosphi + uvw[1]*sinphi + uvw[2]*costh*cosphi;
135  }
136 
137  /// Get position of track.
138  ///
139  /// Arguments:
140  ///
141  /// vec - Track state vector.
142  /// xyz - Position in global coordinate system.
143  ///
144  void SurfXYZPlane::getPosition(const TrackVector& vec, double xyz[3]) const
145  {
146  // Get position in local coordinate system.
147 
148  double uvw[3];
149  uvw[0] = vec(0);
150  uvw[1] = vec(1);
151  uvw[2] = 0.;
152 
153  // Transform to global coordinate system.
154 
155  toGlobal(uvw, xyz);
156  return;
157  }
158 
159  /// Get momentum vector of track.
160  ///
161  /// Arguments:
162  ///
163  /// vec - Track state vector.
164  /// mom - Momentum vector in global coordinate system.
165  /// dir - Track direction.
166  ///
167  void SurfXYZPlane::getMomentum(const TrackVector& vec, double mom[3],
168  TrackDirection dir) const
169  {
170 
171  // Get momentum.
172 
173  double invp = std::abs(vec(4));
174  double p = 1. / std::max(invp, 1.e-3); // Capped at 1000. GeV/c.
175 
176  // Get track slope parameters.
177 
178  double dudw = vec(2);
179  double dvdw = vec(3);
180 
181  // Calculate dw/ds.
182 
183  double dwds = 1. / std::sqrt(1. + dudw*dudw + dvdw*dvdw);
184  TrackDirection realdir = getDirection(vec, dir); // Should be same as original direction.
185  if(realdir == BACKWARD)
186  dwds = -dwds;
187  else if(realdir != FORWARD)
188  throw cet::exception("SurfXYZPlane") << "Track direction not specified.\n";
189 
190  // Calculate momentum vector in local coordinate system.
191 
192  double pu = p * dudw * dwds;
193  double pv = p * dvdw * dwds;
194  double pw = p * dwds;
195 
196  // Rotate momentum to global coordinte system.
197 
198  double sinth = std::sin(fTheta);
199  double costh = std::cos(fTheta);
200  double sinphi = std::sin(fPhi);
201  double cosphi = std::cos(fPhi);
202 
203  mom[0] = pu*costh + pw*sinth;
204  mom[1] = pu*sinth*sinphi + pv*cosphi - pw*costh*sinphi;
205  mom[2] = -pu*sinth*cosphi + pv*sinphi + pw*costh*cosphi;
206 
207  return;
208  }
209 
210  /// Test whether two surfaces are parallel, within tolerance.
211  /// This method will only return true if the other surface
212  /// is a SurfXYZPlane.
213  ///
214  /// Arguments:
215  ///
216  /// surf - Other surface.
217  ///
218  /// Returned value: true if parallel.
219  ///
220  bool SurfXYZPlane::isParallel(const Surface& surf) const
221  {
222  bool result = false;
223 
224  // Test if the other surface is a SurfXYZPlane.
225 
226  const SurfXYZPlane* psurf = dynamic_cast<const SurfXYZPlane*>(&surf);
227  if(psurf != 0) {
228 
229  // Test whether surface angle parameters are the same
230  // with tolerance.
231 
232  double delta_phi = TVector2::Phi_mpi_pi(fPhi - psurf->phi());
233  double delta_theta = fTheta - psurf->theta();
234  if(std::abs(delta_phi) <= fPhiTolerance && std::abs(delta_theta) <= fThetaTolerance)
235  result = true;
236  }
237  return result;
238  }
239 
240  /// Find perpendicular forward distance to a parallel surface.
241  ///
242  /// Throw an exception if the other surface is not parallel.
243  ///
244  /// Assuming the other surface is parallel, the distance is
245  /// simply the w-coordinate of the other surface, and is signed.
246  ///
247  /// Arguments:
248  ///
249  /// surf - Other surface.
250  ///
251  /// Returned value: Distance.
252  ///
253  double SurfXYZPlane::distanceTo(const Surface& surf) const
254  {
255  // Check if the other surface is parallel to this one.
256 
257  bool parallel = isParallel(surf);
258  if(!parallel)
259  throw cet::exception("SurfXYZPlane") << "Attempt to find distance to non-parallel surface.\n";
260 
261  // Find the origin of the other surface in global coordinates,
262  // then convert to our local coordinates.
263 
264  double otheruvw[3] = {0., 0., 0.};
265  double xyz[3];
266  double myuvw[3];
267  surf.toGlobal(otheruvw, xyz);
268  toLocal(xyz, myuvw);
269 
270  // Distance is local w-coordinate of other surface origin.
271 
272  return myuvw[2];
273  }
274 
275  /// Test two surfaces for equality, within tolerance.
276  /// Here equal is defined as parallel and having zero separation,
277  /// within tolerance. Note that this definition of equality allows
278  /// the two surfaces to have different origins.
279  ///
280  /// Arguments:
281  ///
282  /// surf - Other surface.
283  ///
284  /// Returned values: true if equal.
285  ///
286  bool SurfXYZPlane::isEqual(const Surface& surf) const
287  {
288  bool result = false;
289 
290  // Test if the other surface is parallel.
291 
292  bool parallel = isParallel(surf);
293  if(parallel) {
294  double dist = distanceTo(surf);
295  if(std::abs(dist) <= fSepTolerance)
296  result = true;
297  }
298 
299  return result;
300  }
301 
302  /// Printout
303  std::ostream& SurfXYZPlane::Print(std::ostream& out) const
304  {
305  out << "SurfXYZPlane{ x0=" << fX0 << ", y0=" << fY0 << ", z0=" << fZ0
306  << ", phi=" << fPhi << ", theta=" << fTheta << "}";
307  return out;
308  }
309 
310 } // end namespace trkf
virtual void getPosition(const TrackVector &vec, double xyz[3]) const
Get position of track.
TrackDirection
Track direction enum.
Definition: Surface.h:56
virtual bool isEqual(const Surface &surf) const
Test two surfaces for equality, within tolerance.
static QCString result
General planar surface.
double y0() const
Y origin.
Definition: SurfXYZPlane.h:102
virtual std::ostream & Print(std::ostream &out) const
Printout.
string dir
std::enable_if_t< std::is_arithmetic_v< T >, T > hypot(T x, T y)
Definition: hypot.h:60
static double fPhiTolerance
Phi tolerance for parallel.
Definition: SurfXYZPlane.h:142
virtual bool isParallel(const Surface &surf) const
Test whether two surfaces are parallel, within tolerance.
T abs(T value)
static double fSepTolerance
Separation tolerance for equal.
Definition: SurfXYZPlane.h:144
virtual bool isTrackValid(const TrackVector &vec) const
Surface-specific tests of validity of track parameters.
const double e
virtual double distanceTo(const Surface &surf) const
Find perpendicular forward distance to a parallel surface.
double fX0
X origin.
Definition: SurfXYZPlane.h:148
p
Definition: test.py:223
double phi() const
Rot. angle about x-axis (wire angle).
Definition: SurfXYZPlane.h:104
double x0() const
X origin.
Definition: SurfXYZPlane.h:101
virtual void toLocal(const double xyz[3], double uvw[3]) const
Transform global to local coordinates.
SurfXYZPlane()
Default constructor.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
static int max(int a, int b)
double theta() const
Rot. angle about y&#39;-axis (projected Lorentz angle).
Definition: SurfXYZPlane.h:105
virtual void toGlobal(const double uvw[3], double xyz[3]) const
Transform local to global coordinates.
double fY0
Y origin.
Definition: SurfXYZPlane.h:149
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
double fTheta
Rotation angle about y&#39;-axis (projected Lorentz angle).
Definition: SurfXYZPlane.h:152
static double fThetaTolerance
Theta tolerance for parallel.
Definition: SurfXYZPlane.h:143
virtual TrackDirection getDirection(const TrackVector &, TrackDirection dir=UNKNOWN) const
Get direction of track (default UNKNOWN).
Definition: Surface.h:85
double z0() const
Z origin.
Definition: SurfXYZPlane.h:103
virtual void toGlobal(const double uvw[3], double xyz[3]) const =0
Transform local to global coordinates.
virtual ~SurfXYZPlane()
Destructor.
double fPhi
Rotation angle about x-axis (wire angle).
Definition: SurfXYZPlane.h:151
virtual void getMomentum(const TrackVector &vec, double mom[3], TrackDirection dir=UNKNOWN) const
Get momentum vector of track.
virtual Surface * clone() const
Clone method.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double fZ0
Z origin.
Definition: SurfXYZPlane.h:150