BOSS 8.0.0
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"
15#include "TrkBase/TrkHelixUtils.h"
16// #include "PatBField/BField.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 "MdcGeom/BesAngle.h"
22#include "MdcGeom/Constants.h"
23#include "MdcRecoUtil/BesPointErr.h"
24#include "MdcRecoUtil/BesVectorErr.h"
25#include "MdcRecoUtil/DifArray.h"
26#include "MdcRecoUtil/DifNumber.h"
27#include "TrkBase/NeutParams.h"
28#include "TrkBase/TrkExchangePar.h"
29#include <math.h>
30const double pi = Constants::pi;
31
33
34//------------------------------------------------------------------------
35HepMatrix TrkHelixUtils::jacobianExtrapolate( const TrkExchangePar& par, double fltNew ) {
36 //------------------------------------------------------------------------
37
38 //----------------------------------------------------------------------
39 // Compute and return the jacobian that takes the covariance matrix
40 // from fltOld to fltNew
41 //
42 // "fltLen" -- the signed 3-d pathlength a particle travels
43 // along the orbit starting from the point on the orbit
44 // close to the origin.
45 //
46 // Each element in this matrix is a partial derivative of an orbit
47 // parameter at some reference point to an orbit parameter at
48 // the fit point. What is kept fixed in taking these partial
49 // derivatives is that the orbit parameters are those at the point
50 // on the orbit that is closest in the x-y plane to the reference point.
51 // This transform matrix has the property that transform(-arclength)
52 // is the inverse of transform(arclength).
53 // (repaired by Gerry Lynch, I think -- sfs)
54 //----------------------------------------------------------------------
55
56 HepMatrix transform( 5, 5, 0 );
57
58 double tanDip = par.tanDip();
59 double omega = par.omega();
60 // Convert to 2-d arclength
61 double darc = fltNew / sqrt( 1. + tanDip * tanDip );
62 double dphi = omega * darc;
63 double cosDphi = cos( dphi );
64 double sinDphi = sin( dphi );
65
66 // partials of d0
67
68 transform[0][0] = cosDphi;
69 transform[0][1] = sinDphi / omega;
70 transform[0][2] = ( 1.0 - cosDphi ) / ( omega * omega );
71
72 // partials of phi0
73
74 transform[1][0] = -sinDphi * omega;
75 transform[1][1] = cosDphi;
76 transform[1][2] = sinDphi / omega;
77
78 // partials of omega
79
80 transform[2][2] = 1.0;
81
82 // partials of z0
83
84 transform[3][0] = -tanDip * sinDphi;
85 transform[3][1] = -tanDip * ( 1.0 - cosDphi ) / omega;
86 transform[3][2] = -tanDip * ( dphi - sinDphi ) / ( omega * omega );
87 transform[3][3] = 1.;
88 transform[3][4] = darc;
89
90 // partials of tanDip
91
92 transform[4][4] = 1.;
93
94 return transform;
95}
96
97//----------------------------------------------------------------------
98HepSymMatrix TrkHelixUtils::extrapolateCov( TrkExchangePar& par, double fltNew ) {
99 //----------------------------------------------------------------------
100
101 return par.covariance().similarity( jacobianExtrapolate( par, fltNew ) );
102}
103
104//----------------------------------------------------------------------
105TrkExchangePar TrkHelixUtils::helixFromMom( const HepPoint3D& pos, const Hep3Vector& pmom,
106 double sign, const BField& fieldmap ) {
107 //----------------------------------------------------------------------
108 // As documented in
109 // R.~Luchsinger and C.~Grab, Comp.~Phys.~Comm.~{\bf 76}, 263-280 (1993).
110 // Equation 14 on page 270.
111 // Note: We use the opposite sign for d0.
112 // We use tandip and not the dip angle itself.
113
114 register double phip, gamma, rho, pt;
115 static HepVector pars( 5 );
116
117 double px = pmom.x();
118 double py = pmom.y();
119 pt = sqrt( px * px + py * py );
120
121 if ( pt < 1.e-7 ) pt = 1.e-7; // hack to avoid pt=0 tracks
122 if ( fabs( px ) < 1.e-7 ) px = ( px < 0.0 ) ? -1.e-7 : 1.e-7; // hack to avoid pt=0 tracks
123
124 double Bval = fieldmap.bFieldNominal();
125
126 pars( 3 ) = -BField::cmTeslaToGeVc * Bval * sign / pt; // omega
127 pars( 5 ) = pmom.z() / pt; // tandip
128
129 rho = 1. / pars( 3 );
130 phip = atan2( py, px );
131 double cosphip = cos( phip );
132 double sinphip = sin( phip );
133
134 gamma =
135 atan( ( pos.x() * cosphip + pos.y() * sinphip ) /
136 ( pos.x() * sinphip - pos.y() * cosphip - rho ) ); // NOTE: do NOT use atan2 here!
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,
148 double sign, 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 =
194 atan( ( xDF * cosphip + yDF * sinphip ) / -pars( 1 ) ); // NOTE: do NOT use atan2 here
195
196 pars( 1 ) /= cos( gamma );
197 pars( 1 ) -= rho;
198
199 // pars(2) = phip+gamma; //phi0
200 pars( 2 ) = phip;
201 pars( 2 ) += gamma;
202 // pars(2).mod(0., Constants::twoPi);
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 // Get error matrix for position and momentum
211
212 static HepSymMatrix posandmomErr( 6 );
213 static HepVector parsVec( 5 );
214
215 int i;
216 for ( i = 1; i <= 3; ++i )
217 {
218 int j;
219 for ( j = 1; j <= i; ++j )
220 {
221 // with "fast" access, row should be >= col
222 posandmomErr.fast( i, j ) = pos.covMatrix().fast( i, j );
223 posandmomErr.fast( i + 3, j + 3 ) = pmom.covMatrix().fast( i, j );
224 }
225 for ( j = 1; j <= 3; ++j ) { posandmomErr.fast( j + 3, i ) = cxp( i, j ); }
226 }
227 for ( i = 1; i <= 5; ++i )
228 {
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 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 // pars(5) = pzDF / pt; //tandip
277 pars( 5 ) = pzDF;
278 pars( 5 ) *= invpt;
279
280 pars( 2 ) = atan2( pyDF, pxDF ); // phi0
281
282 // pars(1) = yDF*pvxDF - xDF*pvyDF;//d0
283 pars( 1 ) = yDF;
284 pars( 1 ) *= pvxDF;
285 pars( 1 ) -= xDF * pvyDF;
286
287 // pars(4) = zDF -pars(5)*(xDF*pvxDF+yDF*pvyDF) ; //z0
288 pars( 4 ) = xDF;
289 pars( 4 ) *= pvxDF;
290 pars( 4 ) += yDF * pvyDF;
291
292 // insert this in the middle for speed
293 // pars(6) = (xDF*pvxDF+yDF*pvyDF)*pars(3)/pt;//s0
294 pars( 6 ) = pars( 4 );
295 pars( 6 ) *= pars( 3 );
296 pars( 6 ) *= invpt;
297
298 pars( 4 ) *= -pars( 5 );
299 pars( 4 ) += zDF;
300
301 // Get error matrix for position and momentum
302
303 static HepSymMatrix posandmomErr( 6 );
304 static HepVector parsVec( 6 );
305
306 int i;
307 for ( i = 1; i <= 3; ++i )
308 {
309 int j;
310 for ( j = 1; j <= i; ++j )
311 {
312 // with "fast" access, row should be >= col
313 posandmomErr.fast( i, j ) = pos.covMatrix().fast( i, j );
314 posandmomErr.fast( i + 3, j + 3 ) = pmom.covMatrix().fast( i, j );
315 }
316 for ( j = 1; j <= 3; ++j ) { posandmomErr.fast( j + 3, i ) = cxp( i, j ); }
317 }
318 for ( i = 1; i <= 6; ++i )
319 {
320 // make the array of DifNums into a HepVector
321 // (needed for TrkExchangePar init)
322 parsVec( i ) = pars( i ).number();
323 }
324 // Now calculate error on the helix pars--the real calculation
325 return NeutParams( parsVec, posandmomErr.similarity( pars.jacobian() ) );
326}
327
328//------------------------------------------------------------------------
329double TrkHelixUtils::fltToRad( const TrkExchangePar& hel, double rad ) {
330 //------------------------------------------------------------------------
331 double d0 = hel.d0();
332 double omega = hel.omega();
333 double tanDip = hel.tanDip();
334 // std::cout<< "omega "<<omega << std::endl;
335 // GS To be able to use this with straight lines:
336 // if( fabs(omega) < 0.0001 ) omega=copysign(0.0001,omega); // assume the pt= 1000 GeV
337 if ( fabs( omega ) < 0.0001 ) omega = ( omega < 0.0 ) ? -0.0001 : 0.0001;
338
339 double stuff = ( rad * rad - d0 * d0 ) / ( 1 + omega * d0 );
340 if ( stuff <= 0.0 ) return 0.;
341 // std::cout<< "in TrkHelixUtils::fltToRad "<< stuff << std::endl;
342 if ( omega == 0. ) return sqrt( stuff );
343 double sinAngle = 0.5 * omega * sqrt( stuff );
344 double dist2d = 0;
345 if ( sinAngle < -1.0 || sinAngle > 1.0 ) { dist2d = Constants::pi / fabs( omega ); }
346 else { dist2d = 2. * asin( sinAngle ) / omega; }
347 // std::cout<< "in TrkHelixUtils::fltToRad dist2d "<< dist2d << std::endl;
348 return dist2d * sqrt( 1. + tanDip * tanDip );
349}
double pi
HepMatrix jacobian() const
Definition DifArray.cxx:70
void cosAndSin(DifNumber &c, DifNumber &s) 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 &)