CMS 3D CMS Logo

ClosestApproachInRPhi.cc
Go to the documentation of this file.
5 
6 using namespace std;
7 
9  TrackCharge chargeA = sta.charge();
10  TrackCharge chargeB = stb.charge();
11  GlobalVector momentumA = sta.globalMomentum();
12  GlobalVector momentumB = stb.globalMomentum();
13  GlobalPoint positionA = sta.globalPosition();
14  GlobalPoint positionB = stb.globalPosition();
15  paramA = sta.globalParameters();
16  paramB = stb.globalParameters();
17  // compute magnetic field ONCE
18  bz = sta.freeState()->parameters().magneticField().inTesla(positionA).z() * 2.99792458e-3;
19 
20  return compute(chargeA, momentumA, positionA, chargeB, momentumB, positionB);
21 }
22 
24  TrackCharge chargeA = sta.charge();
25  TrackCharge chargeB = stb.charge();
26  GlobalVector momentumA = sta.momentum();
27  GlobalVector momentumB = stb.momentum();
28  GlobalPoint positionA = sta.position();
29  GlobalPoint positionB = stb.position();
30  paramA = sta.parameters();
31  paramB = stb.parameters();
32  // compute magnetic field ONCE
33  bz = sta.parameters().magneticField().inTesla(positionA).z() * 2.99792458e-3;
34 
35  return compute(chargeA, momentumA, positionA, chargeB, momentumB, positionB);
36 }
37 
38 pair<GlobalPoint, GlobalPoint> ClosestApproachInRPhi::points() const {
39  if (!status_)
40  throw cms::Exception(
41  "TrackingTools/PatternTools",
42  "ClosestApproachInRPhi::could not compute track crossing. Check status before calling this method!");
43  return pair<GlobalPoint, GlobalPoint>(posA, posB);
44 }
45 
47  if (!status_)
48  throw cms::Exception(
49  "TrackingTools/PatternTools",
50  "ClosestApproachInRPhi::could not compute track crossing. Check status before calling this method!");
51  return GlobalPoint(0.5 * (posA.basicVector() + posB.basicVector()));
52 }
53 
55  if (!status_)
56  throw cms::Exception(
57  "TrackingTools/PatternTools",
58  "ClosestApproachInRPhi::could not compute track crossing. Check status before calling this method!");
59  return (posB - posA).mag();
60 }
61 
63  const GlobalVector& momentumA,
64  const GlobalPoint& positionA,
65  const TrackCharge& chargeB,
66  const GlobalVector& momentumB,
67  const GlobalPoint& positionB) {
68  // centres and radii of track circles
69  double xca, yca, ra;
70  circleParameters(chargeA, momentumA, positionA, xca, yca, ra, bz);
71  double xcb, ycb, rb;
72  circleParameters(chargeB, momentumB, positionB, xcb, ycb, rb, bz);
73 
74  // points of closest approach in transverse plane
75  double xg1, yg1, xg2, yg2;
76  int flag = transverseCoord(xca, yca, ra, xcb, ycb, rb, xg1, yg1, xg2, yg2);
77  if (flag == 0) {
78  status_ = false;
79  return false;
80  }
81 
82  double xga, yga, zga, xgb, ygb, zgb;
83 
84  if (flag == 1) {
85  // two crossing points on each track in transverse plane
86  // select point for which z-coordinates on the 2 tracks are the closest
87  double za1 = zCoord(momentumA, positionA, ra, xca, yca, xg1, yg1);
88  double zb1 = zCoord(momentumB, positionB, rb, xcb, ycb, xg1, yg1);
89  double za2 = zCoord(momentumA, positionA, ra, xca, yca, xg2, yg2);
90  double zb2 = zCoord(momentumB, positionB, rb, xcb, ycb, xg2, yg2);
91 
92  if (abs(zb1 - za1) < abs(zb2 - za2)) {
93  xga = xg1;
94  yga = yg1;
95  zga = za1;
96  zgb = zb1;
97  } else {
98  xga = xg2;
99  yga = yg2;
100  zga = za2;
101  zgb = zb2;
102  }
103  xgb = xga;
104  ygb = yga;
105  } else {
106  // one point of closest approach on each track in transverse plane
107  xga = xg1;
108  yga = yg1;
109  zga = zCoord(momentumA, positionA, ra, xca, yca, xga, yga);
110  xgb = xg2;
111  ygb = yg2;
112  zgb = zCoord(momentumB, positionB, rb, xcb, ycb, xgb, ygb);
113  }
114 
115  posA = GlobalPoint(xga, yga, zga);
116  posB = GlobalPoint(xgb, ygb, zgb);
117  status_ = true;
118  return true;
119 }
120 
121 pair<GlobalTrajectoryParameters, GlobalTrajectoryParameters> ClosestApproachInRPhi::trajectoryParameters() const {
122  if (!status_)
123  throw cms::Exception(
124  "TrackingTools/PatternTools",
125  "ClosestApproachInRPhi::could not compute track crossing. Check status before calling this method!");
126  pair<GlobalTrajectoryParameters, GlobalTrajectoryParameters> ret(newTrajectory(posA, paramA, bz),
127  newTrajectory(posB, paramB, bz));
128  return ret;
129 }
130 
132  const GlobalTrajectoryParameters& oldgtp,
133  double bz) {
134  // First we need the centers of the circles.
135  double qob = oldgtp.charge() / bz;
136  double xc = oldgtp.position().x() + qob * oldgtp.momentum().y();
137  double yc = oldgtp.position().y() - qob * oldgtp.momentum().x();
138 
139  // and of course....
140  double npx = (newpt.y() - yc) * (bz / oldgtp.charge());
141  double npy = (xc - newpt.x()) * (bz / oldgtp.charge());
142 
143  /*
144  * old code: slow and wrong
145  *
146  // now we do a translation, move the center of circle to (0,0,0).
147  double dx1 = oldgtp.position().x() - xc;
148  double dy1 = oldgtp.position().y() - yc;
149  double dx2 = newpt.x() - xc;
150  double dy2 = newpt.y() - yc;
151 
152  // now for the angles:
153  double cosphi = ( dx1 * dx2 + dy1 * dy2 ) /
154  ( sqrt ( dx1 * dx1 + dy1 * dy1 ) * sqrt ( dx2 * dx2 + dy2 * dy2 ));
155  double sinphi = - oldgtp.charge() * sqrt ( 1 - cosphi * cosphi );
156 
157  // Finally, the new momenta:
158  double px = cosphi * oldgtp.momentum().x() - sinphi * oldgtp.momentum().y();
159  double py = sinphi * oldgtp.momentum().x() + cosphi * oldgtp.momentum().y();
160 
161  std::cout << px-npx << " " << py-npy << ", " << oldgtp.charge() << std::endl;
162  */
163 
164  GlobalVector vta(npx, npy, oldgtp.momentum().z());
165  GlobalTrajectoryParameters gta(newpt, vta, oldgtp.charge(), &(oldgtp.magneticField()));
166  return gta;
167 }
168 
170  const GlobalVector& momentum,
171  const GlobalPoint& position,
172  double& xc,
173  double& yc,
174  double& r,
175  double bz) {
176  // compute radius of circle
180  // double bz = MagneticField::inInverseGeV(position).z();
181 
182  // signed_r directed towards circle center, along F_Lorentz = q*v X B
183  double qob = charge / bz;
184  double signed_r = qob * momentum.transverse();
185  r = abs(signed_r);
189  // compute centre of circle
190  // double phi = momentum.phi();
191  // xc = signed_r*sin(phi) + position.x();
192  // yc = -signed_r*cos(phi) + position.y();
193  xc = position.x() + qob * momentum.y();
194  yc = position.y() - qob * momentum.x();
195 }
196 
198  double cya,
199  double ra,
200  double cxb,
201  double cyb,
202  double rb,
203  double& xg1,
204  double& yg1,
205  double& xg2,
206  double& yg2) {
207  int flag = 0;
208  double x1, y1, x2, y2;
209 
210  // new reference frame with origin in (cxa, cya) and x-axis
211  // directed from (cxa, cya) to (cxb, cyb)
212 
213  double d_ab = sqrt((cxb - cxa) * (cxb - cxa) + (cyb - cya) * (cyb - cya));
214  if (d_ab == 0) { // concentric circles
215  return 0;
216  }
217  // elements of rotation matrix
218  double u = (cxb - cxa) / d_ab;
219  double v = (cyb - cya) / d_ab;
220 
221  // conditions for circle intersection
222  if (d_ab <= ra + rb && d_ab >= abs(rb - ra)) {
223  // circles cross each other
224  flag = 1;
225 
226  // triangle (ra, rb, d_ab)
227  double cosphi = (ra * ra - rb * rb + d_ab * d_ab) / (2 * ra * d_ab);
228  double sinphi2 = 1. - cosphi * cosphi;
229  if (sinphi2 < 0.) {
230  sinphi2 = 0.;
231  cosphi = 1.;
232  }
233 
234  // intersection points in new frame
235  double sinphi = sqrt(sinphi2);
236  x1 = ra * cosphi;
237  y1 = ra * sinphi;
238  x2 = x1;
239  y2 = -y1;
240  } else if (d_ab > ra + rb) {
241  // circles are external to each other
242  flag = 2;
243 
244  // points of closest approach in new frame
245  // are on line between 2 centers
246  x1 = ra;
247  y1 = 0;
248  x2 = d_ab - rb;
249  y2 = 0;
250  } else if (d_ab < abs(rb - ra)) {
251  // circles are inside each other
252  flag = 2;
253 
254  // points of closest approach in new frame are on line between 2 centers
255  // choose 2 closest points
256  double sign = 1.;
257  if (ra <= rb)
258  sign = -1.;
259  x1 = sign * ra;
260  y1 = 0;
261  x2 = d_ab + sign * rb;
262  y2 = 0;
263  } else {
264  return 0;
265  }
266 
267  // intersection points in global frame, transverse plane
268  xg1 = u * x1 - v * y1 + cxa;
269  yg1 = v * x1 + u * y1 + cya;
270  xg2 = u * x2 - v * y2 + cxa;
271  yg2 = v * x2 + u * y2 + cya;
272 
273  return flag;
274 }
275 
277  const GlobalVector& mom, const GlobalPoint& pos, double r, double xc, double yc, double xg, double yg) {
278  // starting point
279  double x = pos.x();
280  double y = pos.y();
281  double z = pos.z();
282 
283  double px = mom.x();
284  double py = mom.y();
285  double pz = mom.z();
286 
287  // rotation angle phi from starting point to crossing point (absolute value)
288  // -- compute sin(phi/2) if phi smaller than pi/4,
289  // -- cos(phi) if phi larger than pi/4
290  double phi = 0.;
291  double sinHalfPhi = sqrt((x - xg) * (x - xg) + (y - yg) * (y - yg)) / (2 * r);
292  if (sinHalfPhi < 0.383) { // sin(pi/8)
293  phi = 2 * asin(sinHalfPhi);
294  } else {
295  double cosPhi = ((x - xc) * (xg - xc) + (y - yc) * (yg - yc)) / (r * r);
296  if (std::abs(cosPhi) > 1)
297  cosPhi = (cosPhi > 0 ? 1 : -1);
298  phi = abs(acos(cosPhi));
299  }
300  // -- sign of phi
301  double signPhi = ((x - xc) * (yg - yc) - (xg - xc) * (y - yc) > 0) ? 1. : -1.;
302 
303  // sign of track angular momentum
304  // if rotation is along angular momentum, delta z is along pz
305  double signOmega = ((x - xc) * py - (y - yc) * px > 0) ? 1. : -1.;
306 
307  // delta z
308  // -- |dz| = |cos(theta) * path along helix|
309  // = |cos(theta) * arc length along circle / sin(theta)|
310  double dz = signPhi * signOmega * (pz / mom.transverse()) * phi * r;
311 
312  return z + dz;
313 }
static int transverseCoord(double cxa, double cya, double ra, double cxb, double cyb, double rb, double &xg1, double &yg1, double &xg2, double &yg2)
static void circleParameters(const TrackCharge &charge, const GlobalVector &momemtum, const GlobalPoint &position, double &xc, double &yc, double &r, double bz)
float distance() const override
T z() const
Definition: PV3DBase.h:61
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
ret
prodAgent to be discontinued
const GlobalTrajectoryParameters & globalParameters() const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
const GlobalTrajectoryParameters & parameters() const
GlobalPoint position() const
bool compute(const TrackCharge &chargeA, const GlobalVector &momentumA, const GlobalPoint &positionA, const TrackCharge &chargeB, const GlobalVector &momentumB, const GlobalPoint &positionB)
int TrackCharge
Definition: TrackCharge.h:4
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
GlobalPoint crossingPoint() const override
GlobalPoint globalPosition() const
bool calculate(const TrajectoryStateOnSurface &sta, const TrajectoryStateOnSurface &stb) override
T sqrt(T t)
Definition: SSEVec.h:23
TrackCharge charge() const
std::pair< GlobalTrajectoryParameters, GlobalTrajectoryParameters > trajectoryParameters() const
GlobalVector momentum() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static double zCoord(const GlobalVector &mom, const GlobalPoint &pos, double r, double xc, double yc, double xg, double yg)
T transverse() const
Definition: PV3DBase.h:70
def compute(min, max)
const MagneticField & magneticField() const
std::pair< GlobalPoint, GlobalPoint > points() const override
GlobalVector globalMomentum() const
static GlobalTrajectoryParameters newTrajectory(const GlobalPoint &newpt, const GlobalTrajectoryParameters &oldpar, double bz)
static int position[264][3]
Definition: ReadPGInfo.cc:289
FreeTrajectoryState const * freeState(bool withErrors=true) const
float x