BOSS 6.6.4.p01
BESIII Offline Software System
Loading...
Searching...
No Matches
TrkHelixUtils.cxx
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2// File and Version Information:
3// $Id: TrkHelixUtils.cxx,v 1.4 2007/12/07 07:04:14 zhangy Exp $
4//
5// Description:
6//
7//
8// Environment:
9// Software developed for the BaBar Detector at the SLAC B-Factory.
10//
11// Author(s): Steve Schaffner, code stolen from TrkParms class
12//
13//------------------------------------------------------------------------
14//#include "BaBar/BaBar.h"
16#include "TrkBase/NeutParams.h"
17#include "CLHEP/Geometry/Point3D.h"
18#include "CLHEP/Matrix/Matrix.h"
19#include "CLHEP/Matrix/SymMatrix.h"
20#include "CLHEP/Vector/ThreeVector.h"
21#include <math.h>
23#include "BField/BField.h"
24#include "MdcGeom/BesAngle.h"
29#include "MdcGeom/Constants.h"
30const double pi = Constants::pi;
31
32//------------------------------------------------------------------------
34 double fltNew) {
35//------------------------------------------------------------------------
36
37//----------------------------------------------------------------------
38// Compute and return the jacobian that takes the covariance matrix
39// from fltOld to fltNew
40//
41// "fltLen" -- the signed 3-d pathlength a particle travels
42// along the orbit starting from the point on the orbit
43// close to the origin.
44//
45// Each element in this matrix is a partial derivative of an orbit
46// parameter at some reference point to an orbit parameter at
47// the fit point. What is kept fixed in taking these partial
48// derivatives is that the orbit parameters are those at the point
49// on the orbit that is closest in the x-y plane to the reference point.
50// This transform matrix has the property that transform(-arclength)
51// is the inverse of transform(arclength).
52// (repaired by Gerry Lynch, I think -- sfs)
53//----------------------------------------------------------------------
54
55 HepMatrix transform(5, 5, 0);
56
57 double tanDip = par.tanDip();
58 double omega = par.omega();
59 // Convert to 2-d arclength
60 double darc = fltNew / sqrt(1. + tanDip * tanDip);
61 double dphi = omega * darc;
62 double cosDphi = cos(dphi);
63 double sinDphi = sin(dphi);
64
65 // partials of d0
66
67 transform[0][0] = cosDphi;
68 transform[0][1] = sinDphi / omega;
69 transform[0][2] = (1.0-cosDphi) / (omega * omega);
70
71 // partials of phi0
72
73 transform[1][0] = -sinDphi * omega;
74 transform[1][1] = cosDphi;
75 transform[1][2] = sinDphi / omega;
76
77 // partials of omega
78
79 transform[2][2] = 1.0;
80
81 // partials of z0
82
83 transform[3][0] = -tanDip * sinDphi;
84 transform[3][1] = -tanDip * (1.0-cosDphi) / omega;
85 transform[3][2] = -tanDip * (dphi-sinDphi) / (omega*omega);
86 transform[3][3] = 1.;
87 transform[3][4] = darc;
88
89 // partials of tanDip
90
91 transform[4][4] = 1.;
92
93 return transform;
94}
95
96
97//----------------------------------------------------------------------
99 double fltNew) {
100//----------------------------------------------------------------------
101
102 return par.covariance().similarity(jacobianExtrapolate(par, fltNew));
103}
104
105//----------------------------------------------------------------------
107 const Hep3Vector& pmom, double sign, const BField& fieldmap) {
108//----------------------------------------------------------------------
109 //As documented in
110 //R.~Luchsinger and C.~Grab, Comp.~Phys.~Comm.~{\bf 76}, 263-280 (1993).
111 //Equation 14 on page 270.
112 //Note: We use the opposite sign for d0.
113 //We use tandip and not the dip angle itself.
114
115 register double phip,gamma,rho,pt;
116 static HepVector pars(5);
117
118 double px = pmom.x();
119 double py = pmom.y();
120 pt=sqrt(px*px+py*py);
121
122 if (pt < 1.e-7) pt = 1.e-7; // hack to avoid pt=0 tracks
123 if (fabs(px) < 1.e-7) px = (px<0.0) ? -1.e-7 : 1.e-7; // hack to avoid pt=0 tracks
124
125 double Bval = fieldmap.bFieldNominal();
126
127 pars(3)=-BField::cmTeslaToGeVc*Bval*sign/pt; //omega
128 pars(5)=pmom.z()/pt; //tandip
129
130 rho=1./pars(3);
131 phip=atan2(py,px);
132 double cosphip=cos(phip); double sinphip=sin(phip);
133
134 gamma=atan((pos.x()*cosphip+pos.y()*sinphip)/
135 (pos.x()*sinphip-pos.y()*cosphip-rho)); // NOTE: do NOT use atan2 here!
136
137
138 pars(2)=BesAngle(phip+gamma).rad(); //phi0
139 pars(1)=(rho+pos.y()*cosphip-pos.x()*sinphip)/cos(gamma)-rho; //d0
140 pars(4)=pos.z()+rho*gamma*pars(5); //z0
141
142 return TrkExchangePar(pars);
143}
144
145//----------------------------------------------------------------------
147 const BesVectorErr& pmom,const HepMatrix& cxp, double sign,
148 const BField& fieldmap) {
149//----------------------------------------------------------------------
150
151 DifNumber xDF(pos.x(),1,6), yDF(pos.y(),2,6), zDF(pos.z(),3,6);
152 DifNumber pxDF(pmom.x(), 4, 6);
153 DifNumber pyDF(pmom.y(), 5, 6);
154 DifNumber pzDF(pmom.z(), 6, 6);
155
156 static DifNumber phip, cosphip, sinphip, gamma;
157 static DifArray pars(5,6);
158
159 DifNumber invpt = pxDF;
160 invpt *= pxDF;
161 invpt += pyDF*pyDF;
162 invpt = sqrt(invpt);
163
164 if (invpt < 1.e-7) invpt = 1.e-7; // hack to avoid pt=0 tracks
165 if (fabs(pxDF) < 1.e-7) pxDF = pxDF<0?-1e-7:1e-7; // hack to avoid pt=0 tracks
166 invpt = 1./invpt;
167
168 //omega
169 double Bval = fieldmap.bFieldNominal();
170 // if (fabs(Bval) < 1.e-7) { // hack to avoid B=0 tracks (very far Z)
171 // Bval = 1.e-7;
172 // }
173
174// pars(3) = -BField::cmTeslaToGeVc*Bval*sign/pt;
175 pars(3) = invpt;
176 pars(3) *= sign;
177 pars(3) *= Bval;
178 pars(3) *= -BField::cmTeslaToGeVc;
179
180// pars(5) = pzDF / pt; //tandip
181 pars(5) = pzDF;
182 pars(5) *= invpt;
183
184 DifNumber rho = 1./pars[2];
185 phip=atan2(pyDF,pxDF);
186 phip.cosAndSin(cosphip,sinphip);
187
188// pars(1) = (rho + yDF*cosphip - xDF*sinphip)/cos(gamma) - rho;//d0
189 pars(1) = rho;
190 pars(1) += yDF*cosphip;
191 pars(1) -= xDF*sinphip; // continued below ...
192
193 gamma=atan((xDF*cosphip+yDF*sinphip)/ -pars(1)); // NOTE: do NOT use atan2 here
194
195 pars(1) /= cos(gamma);
196 pars(1) -= rho;
197
198// pars(2) = phip+gamma; //phi0
199 pars(2) = phip;
200 pars(2) += gamma;
201 // pars(2).mod(0., Constants::twoPi);
202
203
204// pars(4) = zDF + rho*gamma*pars[4]; //z0
205 pars(4) = pars[4]; // weird
206 pars(4) *= gamma;
207 pars(4) *= rho;
208 pars(4) += zDF;
209
210
211// Get error matrix for position and momentum
212
213 static HepSymMatrix posandmomErr(6);
214 static HepVector parsVec(5);
215
216 int i;
217 for (i = 1; i <= 3; ++i) {
218 int j;
219 for (j = 1; j <= i; ++j) {
220 // with "fast" access, row should be >= col
221 posandmomErr.fast(i,j) = pos.covMatrix().fast(i,j);
222 posandmomErr.fast(i+3,j+3) = pmom.covMatrix().fast(i,j);
223 }
224 for (j = 1; j <= 3; ++j) {
225 posandmomErr.fast(j+3,i) = cxp(i,j);
226 }
227 }
228 for (i = 1; i <= 5; ++i) {
229 // make the array of DifNums into a HepVector
230 // (needed for TrkExchangePar init)
231 parsVec(i) = pars(i).number();
232 }
233// Now calculate error on the helix pars--the real calculation
234
235 return TrkExchangePar(parsVec,posandmomErr.similarity(pars.jacobian()) );
236}
237//----------------------------------------------------------------------
239 const BesVectorErr& pmom,const HepMatrix& cxp, double sign,
240 const BField& fieldmap) {
241//----------------------------------------------------------------------
242
243 DifNumber xDF(pos.x(),1,6), yDF(pos.y(),2,6), zDF(pos.z(),3,6);
244 DifNumber pxDF(pmom.x(), 4, 6);
245 DifNumber pyDF(pmom.y(), 5, 6);
246 DifNumber pzDF(pmom.z(), 6, 6);
247
248 static DifArray pars(6,6);
249
250 DifNumber pt = pxDF;
251 pt *= pxDF;
252 pt += pyDF*pyDF;
253
254 if (pt < 1.e-14) pt = 1.e-14; // hack to avoid pt=0 tracks
255 if (fabs(pxDF) < 1.e-7) pxDF = pxDF<0?-1e-7:1e-7; // hack to avoid pt=0 tracks
256
257// pars(3) = sqrt(pt*pt+pzDF*pzDF); // Magnitude of p
258 pars(3) = pzDF;
259 pars(3) *= pzDF;
260 pars(3) += pt;
261 pars(3) = sqrt(pars(3));
262
263 pt = sqrt(pt);
264 DifNumber invpt = 1./pt;
265
266 //Next lines modified by Eugenio Paoloni 19-XI-98
267
268// DifNumber pvxDF=pxDF/pt; // versor along pt x
269 DifNumber pvxDF=pxDF;
270 pvxDF *= invpt;
271
272// DifNumber pvyDF=pyDF/pt; // and y component
273 DifNumber pvyDF=pyDF;
274 pvyDF *= invpt;
275
276
277// pars(5) = pzDF / pt; //tandip
278 pars(5) = pzDF;
279 pars(5) *= invpt;
280
281 pars(2) = atan2(pyDF,pxDF); //phi0
282
283// pars(1) = yDF*pvxDF - xDF*pvyDF;//d0
284 pars(1) = yDF;
285 pars(1) *= pvxDF;
286 pars(1) -= xDF*pvyDF;
287
288// pars(4) = zDF -pars(5)*(xDF*pvxDF+yDF*pvyDF) ; //z0
289 pars(4) = xDF;
290 pars(4) *= pvxDF;
291 pars(4) += yDF*pvyDF;
292
293// insert this in the middle for speed
294// pars(6) = (xDF*pvxDF+yDF*pvyDF)*pars(3)/pt;//s0
295 pars(6) = pars(4);
296 pars(6) *= pars(3);
297 pars(6) *= invpt;
298
299
300 pars(4) *= -pars(5);
301 pars(4) += zDF;
302
303
304
305
306// Get error matrix for position and momentum
307
308 static HepSymMatrix posandmomErr(6);
309 static HepVector parsVec(6);
310
311 int i;
312 for (i = 1; i <= 3; ++i) {
313 int j;
314 for (j = 1; j <= i; ++j) {
315 // with "fast" access, row should be >= col
316 posandmomErr.fast(i,j) = pos.covMatrix().fast(i,j);
317 posandmomErr.fast(i+3,j+3) = pmom.covMatrix().fast(i,j);
318 }
319 for (j = 1; j <= 3; ++j) {
320 posandmomErr.fast(j+3,i) = cxp(i,j);
321 }
322 }
323 for (i = 1; i <= 6; ++i) {
324 // make the array of DifNums into a HepVector
325 // (needed for TrkExchangePar init)
326 parsVec(i) = pars(i).number();
327 }
328// Now calculate error on the helix pars--the real calculation
329 return NeutParams(parsVec,posandmomErr.similarity(pars.jacobian()) );
330}
331
332//------------------------------------------------------------------------
333double TrkHelixUtils::fltToRad(const TrkExchangePar& hel, double rad) {
334//------------------------------------------------------------------------
335 double d0 = hel.d0();
336 double omega = hel.omega();
337 double tanDip = hel.tanDip();
338 //std::cout<< "omega "<<omega << std::endl;
339 // GS To be able to use this with straight lines:
340// if( fabs(omega) < 0.0001 ) omega=copysign(0.0001,omega); // assume the pt= 1000 GeV
341 if( fabs(omega) < 0.0001 ) omega = (omega<0.0) ? -0.0001 : 0.0001 ;
342
343 double stuff = ( rad*rad - d0*d0 ) / (1 + omega * d0);
344 if (stuff <= 0.0) return 0.;
345 //std::cout<< "in TrkHelixUtils::fltToRad "<< stuff << std::endl;
346 if (omega == 0.) return sqrt(stuff);
347 double sinAngle = 0.5 * omega * sqrt(stuff);
348 double dist2d = 0;
349 if (sinAngle < -1.0 || sinAngle > 1.0) {
350 dist2d = Constants::pi / fabs(omega);
351 } else {
352 dist2d = 2. * asin(sinAngle) / omega;
353 }
354 //std::cout<< "in TrkHelixUtils::fltToRad dist2d "<< dist2d << std::endl;
355 return dist2d * sqrt(1. + tanDip*tanDip);
356}
double sin(const BesAngle a)
Definition: BesAngle.h:210
double cos(const BesAngle a)
Definition: BesAngle.h:213
const double pi
double rad() const
Definition: BesAngle.h:118
const BesError & covMatrix() const
Definition: BesPointErr.h:84
const BesError & covMatrix() const
Definition: BesVectorErr.h:121
static const double pi
Definition: Constants.h:38
HepMatrix jacobian() const
Definition: DifArray.cxx:72
void cosAndSin(DifNumber &c, DifNumber &s) const
double omega() const
double d0() const
double tanDip() const
const HepSymMatrix & covariance() const
static HepMatrix jacobianExtrapolate(const TrkExchangePar &, double fltNew)
static NeutParams lineFromMomErr(const BesPointErr &vertex, const BesVectorErr &p, const HepMatrix &cxp, double sign, const BField &)
static double fltToRad(const TrkExchangePar &hel, double rad)
static HepSymMatrix extrapolateCov(TrkExchangePar &, double fltNew)
static TrkExchangePar helixFromMom(const HepPoint3D &vertex, const Hep3Vector &p, double sign, const BField &)
static TrkExchangePar helixFromMomErr(const BesPointErr &vertex, const BesVectorErr &p, const HepMatrix &cxp, double sign, const BField &)
const float rad
Definition: vector3.h:134