ROOT  6.06/09
Reference Guide
TGeoHelix.cxx
Go to the documentation of this file.
1 // @(#)root/geom:$Id$
2 // Author: Andrei Gheata 28/04/04
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 
13 ////////////////////////////////////////////////////////////////////////////////
14 // TGeoHelix - class representing a helix curve
15 //
16 // A helix is a curve defined by the following equations:
17 // x = (1/c) * COS(q*phi)
18 // y = (1/c) * SIN(q*phi)
19 // z = s * alfa
20 // where:
21 // c = 1/Rxy - curvature in XY plane
22 // phi - phi angle
23 // S = 2*PI*s - vertical separation between helix loops
24 // q = +/- 1 - (+)=left-handed, (-)=right-handed
25 //
26 // In particular, a helix describes the trajectory of a charged particle in magnetic
27 // field. In such case, the helix is right-handed for negative particle charge.
28 // To define a helix, one must define:
29 // - the curvature - positive defined
30 // - the Z step made after one full turn of the helix
31 // - the particle charge sign
32 // - the initial particle position and direction (force normalization to unit)
33 // - the magnetic field direction
34 //
35 // A helix provides:
36 // - propagation to a given Z position (in global frame)
37 // Double_t *point = TGeoHelix::PropagateToZ(Double_t z);
38 // - propagation to an arbitrary plane, returning also the new point
39 // - propagation in a geometry until the next crossed surface
40 // - computation of the total track length along a helix
41 
42 #include "TMath.h"
43 #include "TGeoShape.h"
44 #include "TGeoMatrix.h"
45 #include "TGeoHelix.h"
46 
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 /// Dummy constructor
51 
53 {
54  fC = 0.;
55  fS = 0.;
56  fStep = 0.;
57  fPhi = 0.;
58  fPointInit[0] = fPointInit[1] = fPointInit[2] = 0.;
59  fDirInit[0] = fDirInit[1] = fDirInit[2] = 0.;
60  fPoint[0] = fPoint[1] = fPoint[2] = 0.;
61  fDir[0] = fDir[1] = fDir[2] = 0.;
62  fB[0] = fB[1] = fB[2] = 0.;
63  fQ = 0;
64  fMatrix = 0;
65  TObject::SetBit(kHelixNeedUpdate, kTRUE);
66  TObject::SetBit(kHelixStraigth, kFALSE);
67  TObject::SetBit(kHelixCircle, kFALSE);
68 }
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Normal constructor
72 
73 TGeoHelix::TGeoHelix(Double_t curvature, Double_t hstep, Int_t charge)
74 {
75  SetXYcurvature(curvature);
76  SetHelixStep(hstep);
77  fQ = 0;
78  SetCharge(charge);
79  fStep = 0.;
80  fPhi = 0.;
81  fPointInit[0] = fPointInit[1] = fPointInit[2] = 0.;
82  fDirInit[0] = fDirInit[1] = fDirInit[2] = 0.;
83  fPoint[0] = fPoint[1] = fPoint[2] = 0.;
84  fDir[0] = fDir[1] = fDir[2] = 0.;
85  fB[0] = fB[1] = fB[2] = 0.;
86  fMatrix = new TGeoHMatrix();
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Destructor
94 
96 {
97  if (fMatrix) delete fMatrix;
98 }
99 
100 ////////////////////////////////////////////////////////////////////////////////
101 /// Compute safe linear step that can be made such that the error
102 /// between linear-helix extrapolation is less than EPSIL.
103 
105 {
106  if (TestBit(kHelixStraigth) || TMath::Abs(fC)<TGeoShape::Tolerance()) return 1.E30;
108  Double_t step = TMath::Sqrt(2.*epsil/c);
109  return step;
110 }
111 
112 ////////////////////////////////////////////////////////////////////////////////
113 /// Initialize coordinates of a point on the helix
114 
116 {
117  fPointInit[0] = x0;
118  fPointInit[1] = y0;
119  fPointInit[2] = z0;
121 }
122 
123 ////////////////////////////////////////////////////////////////////////////////
124 /// Set initial point on the helix.
125 
127 {
128  InitPoint(point[0], point[1], point[2]);
129 }
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// Initialize particle direction (tangent on the helix in initial point)
133 
134 void TGeoHelix::InitDirection(Double_t dirx, Double_t diry, Double_t dirz, Bool_t is_normalized)
135 {
136  fDirInit[0] = dirx;
137  fDirInit[1] = diry;
138  fDirInit[2] = dirz;
140  if (is_normalized) return;
141  Double_t norm = 1./TMath::Sqrt(dirx*dirx+diry*diry+dirz*dirz);
142  for (Int_t i=0; i<3; i++) fDirInit[i] *= norm;
143 }
144 
145 ////////////////////////////////////////////////////////////////////////////////
146 /// Initialize particle direction (tangent on the helix in initial point)
147 
148 void TGeoHelix::InitDirection(Double_t *dir, Bool_t is_normalized)
149 {
150  InitDirection(dir[0], dir[1], dir[2], is_normalized);
151 }
152 
153 ////////////////////////////////////////////////////////////////////////////////
154 /// Compute helix total curvature
155 
157 {
158  Double_t k = fC/(1.+fC*fC*fS*fS);
159  return k;
160 }
161 
162 ////////////////////////////////////////////////////////////////////////////////
163 /// Set XY curvature: c = 1/Rxy
164 
166 {
167  fC = curvature;
169  if (fC < 0) {
170  Error("SetXYcurvature", "Curvature %f not valid. Must be positive.", fC);
171  return;
172  }
174  Warning("SetXYcurvature", "Curvature is zero. Helix is a straigth line.");
176  }
177 }
178 
179 ////////////////////////////////////////////////////////////////////////////////
180 /// Positive charge means left-handed helix.
181 
183 {
184  if (charge==0) {
185  Error("ctor", "charge cannot be 0 - define it positive for a left-handed helix, negative otherwise");
186  return;
187  }
188  Int_t q = TMath::Sign(1, charge);
189  if (q == fQ) return;
190  fQ = q;
192 }
193 
194 ////////////////////////////////////////////////////////////////////////////////
195 /// Initialize particle direction (tangent on the helix in initial point)
196 
197 void TGeoHelix::SetField(Double_t bx, Double_t by, Double_t bz, Bool_t is_normalized)
198 {
199  fB[0] = bx;
200  fB[1] = by;
201  fB[2] = bz;
203  if (is_normalized) return;
204  Double_t norm = 1./TMath::Sqrt(bx*bx+by*by+bz*bz);
205  for (Int_t i=0; i<3; i++) fB[i] *= norm;
206 }
207 
208 ////////////////////////////////////////////////////////////////////////////////
209 /// Set Z step of the helix on a complete turn. Positive or null.
210 
212 {
213  if (step < 0) {
214  Error("ctor", "Z step %f not valid. Must be positive.", step);
215  return;
216  }
218  fS = 0.5*step/TMath::Pi();
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Reset current point/direction to initial values
224 
226 {
227  fStep = 0.;
228  memcpy(fPoint, fPointInit, 3*sizeof(Double_t));
229  memcpy(fDir, fDirInit, 3*sizeof(Double_t));
230 }
231 
232 ////////////////////////////////////////////////////////////////////////////////
233 /// Make a step from current point along the helix and compute new point, direction and angle
234 /// To reach a plane/ shape boundary, one has to:
235 /// 1. Compute the safety to the plane/boundary
236 /// 2. Define / update a helix according local field and particle state (position, direction, charge)
237 /// 3. Compute the magnetic safety (maximum distance for which the field can be considered constant)
238 /// 4. Call TGeoHelix::Step() having as argument the minimum between 1. and 3.
239 /// 5. Repeat from 1. until the step to be made is small enough.
240 /// 6. Add to the total step the distance along a straigth line from the last point
241 /// to the plane/shape boundary
242 
244 {
245  Int_t i;
246  fStep += step;
248  for (i=0; i<3; i++) {
249  fPoint[i] = fPointInit[i]+fStep*fDirInit[i];
250  fDir[i] = fDirInit[i];
251  }
252  return;
253  }
255  Double_t r = 1./fC;
256  fPhi = fStep/TMath::Sqrt(r*r+fS*fS);
257  Double_t vect[3];
258  vect[0] = r * TMath::Cos(fPhi);
259  vect[1] = -fQ * r * TMath::Sin(fPhi);
260  vect[2] = fS * fPhi;
261  fMatrix->LocalToMaster(vect, fPoint);
262 
263  Double_t ddb = fDirInit[0]*fB[0]+fDirInit[1]*fB[1]+fDirInit[2]*fB[2];
264  Double_t f = -TMath::Sqrt(1.-ddb*ddb);
265  vect[0] = f*TMath::Sin(fPhi);
266  vect[1] = fQ*f*TMath::Cos(fPhi);
267  vect[2] = ddb;
268  TMath::Normalize(vect);
270 }
271 
272 ////////////////////////////////////////////////////////////////////////////////
273 /// Propagate initial point up to a given Z position in MARS.
274 
276 {
277  Double_t step = 0.;
278  Double_t snext = 1.E30;
279  Double_t dx, dy, dz;
280  Double_t ddn, pdn;
282  dx = point[0] - fPoint[0];
283  dy = point[1] - fPoint[1];
284  dz = point[2] - fPoint[2];
285  pdn = dx*norm[0]+dy*norm[1]+dz*norm[2];
286  ddn = fDir[0]*norm[0]+fDir[1]*norm[1]+fDir[2]*norm[2];
288  // propagate straigth line to plane
289  if ((pdn*ddn) <= 0) return snext;
290  snext = pdn/ddn;
291  Step(snext);
292  return snext;
293  }
294 
295  Double_t r = 1./fC;
296  Double_t dist;
297  Double_t safety = TMath::Abs(pdn);
298  Double_t safestep = ComputeSafeStep();
299  snext = 1.E30;
300  Bool_t approaching = (ddn*pdn>0)?kTRUE:kFALSE;
301  if (approaching) snext = pdn/ddn;
302  else if (safety > 2.*r) return snext;
303  while (snext > safestep) {
304  dist = TMath::Max(safety, safestep);
305  Step(dist);
306  step += dist;
307  dx = point[0] - fPoint[0];
308  dy = point[1] - fPoint[1];
309  dz = point[2] - fPoint[2];
310  pdn = dx*norm[0]+dy*norm[1]+dz*norm[2];
311  ddn = fDir[0]*norm[0]+fDir[1]*norm[1]+fDir[2]*norm[2];
312  safety = TMath::Abs(pdn);
313  approaching = (ddn*pdn>0)?kTRUE:kFALSE;
314  snext = 1.E30;
315  if (approaching) snext = pdn/ddn;
316  else if (safety > 2.*r) {
317  ResetStep();
318  return snext;
319  }
320  }
321  step += snext;
322  Step(snext);
323  return step;
324 }
325 
326 ////////////////////////////////////////////////////////////////////////////////
327 /// Update the local helix matrix.
328 
330 {
332  fStep = 0.;
333  memcpy(fPoint, fPointInit, 3*sizeof(Double_t));
334  memcpy(fDir, fDirInit, 3*sizeof(Double_t));
335  Double_t rot[9];
336  Double_t tr[3];
337  Double_t ddb = fDirInit[0]*fB[0]+fDirInit[1]*fB[1]+fDirInit[2]*fB[2];
339  // helix is just a straigth line
341  fMatrix->Clear();
342  return;
343  }
344  rot[2] = fB[0];
345  rot[5] = fB[1];
346  rot[8] = fB[2];
347  if (ddb < 0) fS = -TMath::Abs(fS);
348  Double_t fy = - fQ*TMath::Sqrt(1.-ddb*ddb);
349  fy = 1./fy;
350  rot[1] = fy*(fDirInit[0]-fB[0]*ddb);
351  rot[4] = fy*(fDirInit[1]-fB[1]*ddb);
352  rot[7] = fy*(fDirInit[2]-fB[2]*ddb);
353 
354  rot[0] = rot[4]*rot[8] - rot[7]*rot[5];
355  rot[3] = rot[7]*rot[2] - rot[1]*rot[8];
356  rot[6] = rot[1]*rot[5] - rot[4]*rot[2];
357 
358  tr[0] = fPointInit[0] - rot[0]/fC;
359  tr[1] = fPointInit[1] - rot[3]/fC;
360  tr[2] = fPointInit[2] - rot[6]/fC;
361 
362  fMatrix->SetTranslation(tr);
363  fMatrix->SetRotation(rot);
364 
365 }
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
#define snext(osub1, osub2)
Definition: triangle.c:1167
Float_t Normalize(Float_t v[3])
Normalize a vector v in place.
Definition: TMath.cxx:499
T1 Sign(T1 a, T2 b)
Definition: TMathBase.h:155
void SetCharge(Int_t charge)
Positive charge means left-handed helix.
Definition: TGeoHelix.cxx:182
void SetTranslation(const Double_t *vect)
Definition: TGeoMatrix.h:450
void UpdateHelix()
Update the local helix matrix.
Definition: TGeoHelix.cxx:329
Double_t GetTotalCurvature() const
Compute helix total curvature.
Definition: TGeoHelix.cxx:156
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
void SetHelixStep(Double_t hstep)
Set Z step of the helix on a complete turn. Positive or null.
Definition: TGeoHelix.cxx:211
const Bool_t kFALSE
Definition: Rtypes.h:92
void Step(Double_t step)
Make a step from current point along the helix and compute new point, direction and angle To reach a ...
Definition: TGeoHelix.cxx:243
virtual void LocalToMasterVect(const Double_t *local, Double_t *master) const
convert a vector by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:370
void SetField(Double_t bx, Double_t by, Double_t bz, Bool_t is_normalized=kTRUE)
Initialize particle direction (tangent on the helix in initial point)
Definition: TGeoHelix.cxx:197
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Double_t StepToPlane(Double_t *point, Double_t *norm)
Propagate initial point up to a given Z position in MARS.
Definition: TGeoHelix.cxx:275
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
Double_t fB[3]
Definition: TGeoHelix.h:46
static Double_t Tolerance()
Definition: TGeoShape.h:101
Double_t ComputeSafeStep(Double_t epsil=1E-6) const
Compute safe linear step that can be made such that the error between linear-helix extrapolation is l...
Definition: TGeoHelix.cxx:104
Double_t fPhi
Definition: TGeoHelix.h:41
Double_t fPoint[3]
Definition: TGeoHelix.h:44
virtual ~TGeoHelix()
Destructor.
Definition: TGeoHelix.cxx:95
Int_t fQ
Definition: TGeoHelix.h:47
Double_t fC
Definition: TGeoHelix.h:38
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
Double_t fStep
Definition: TGeoHelix.h:40
void ResetStep()
Reset current point/direction to initial values.
Definition: TGeoHelix.cxx:225
ROOT::R::TRInterface & r
Definition: Object.C:4
void Clear(Option_t *option="")
clear the data for this matrix
virtual void LocalToMaster(const Double_t *local, Double_t *master) const
convert a point by multiplying its column vector (x, y, z, 1) to matrix inverse
Definition: TGeoMatrix.cxx:346
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
Double_t fS
Definition: TGeoHelix.h:39
Double_t Cos(Double_t)
Definition: TMath.h:424
void SetXYcurvature(Double_t curvature)
Set XY curvature: c = 1/Rxy.
Definition: TGeoHelix.cxx:165
Double_t Pi()
Definition: TMath.h:44
Double_t fDir[3]
Definition: TGeoHelix.h:45
void InitDirection(Double_t dirx, Double_t diry, Double_t dirz, Bool_t is_normalized=kTRUE)
Initialize particle direction (tangent on the helix in initial point)
Definition: TGeoHelix.cxx:134
double f(double x)
double Double_t
Definition: RtypesCore.h:55
Double_t fPointInit[3]
Definition: TGeoHelix.h:42
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
void SetRotation(const Double_t *matrix)
Definition: TGeoMatrix.h:451
TGeoHMatrix * fMatrix
Definition: TGeoHelix.h:48
Double_t Sin(Double_t)
Definition: TMath.h:421
TGMatrixLayout * fMatrix
void InitPoint(Double_t x0, Double_t y0, Double_t z0)
Initialize coordinates of a point on the helix.
Definition: TGeoHelix.cxx:115
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
const Bool_t kTRUE
Definition: Rtypes.h:91
float * q
Definition: THbookFile.cxx:87
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
ClassImp(TGeoHelix) TGeoHelix
Dummy constructor.
Definition: TGeoHelix.cxx:47
Double_t fDirInit[3]
Definition: TGeoHelix.h:43
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904