CMS 3D CMS Logo

ThirdHitPrediction.cc
Go to the documentation of this file.
12 
13 inline float sqr(float x) { return x*x; }
14 
15 using namespace std;
16 
17 /*****************************************************************************/
20  const edm::EventSetup& es,
22  string builderName)
23 {
24  using namespace edm;
25  ESHandle<MagneticField> magfield;
26  es.get<IdealMagneticFieldRecord>().get(magfield);
27 
29  es.get<TransientRecHitRecord>().get(builderName,ttrhbESH);
30  theTTRecHitBuilder = ttrhbESH.product();
31 
32  Bz = fabs(magfield->inInverseGeV(GlobalPoint(0,0,0)).z());
33 
34  c0 = Global2DVector(region.origin().x(),
35  region.origin().y());
36 
37  r0 = region.originRBound();
38  rm = region.ptMin() / Bz;
39 
40  g1 = inner;
41  g2 = outer;
42 
43  p1 = Global2DVector(g1.x(), g1.y());
44  p2 = Global2DVector(g2.x(), g2.y());
45 
46  dif = p1 - p2;
47 
48  // Prepare circles of minimal pt (rm) and cylinder of origin (r0)
49  keep = true;
50  arc_0m = findArcIntersection(findMinimalCircles (rm),
51  findTouchingCircles(r0), keep);
52 
54  maxRatio = maxAngleRatio;
55 }
56 
57 /*****************************************************************************/
59 {
60 }
61 
62 /*****************************************************************************/
64 {
65  float s = dif.mag2() / ((c - p1).mag2() - sqr(r));
66 
67  c = p1 + (c - p1)*s;
68  r *= fabsf(s);
69 }
70 
71 /*****************************************************************************/
73 {
74  float s = dif.mag2() / (p - p1).mag2();
75 
76  p = p1 + (p - p1)*s;
77 }
78 
79 /*****************************************************************************/
80 pair<float,float> ThirdHitPrediction::findMinimalCircles(float r)
81 {
82  pair<float,float> a(0.,0.);
83 
84  if(dif.mag2() < 2 * sqr(r))
85  a = pair<float,float>( dif.phi(),
86  0.5*acos(1 - 0.5 * dif.mag2()/sqr(r)) );
87 
88  return a;
89 }
90 
91 /*****************************************************************************/
93 {
95  invertCircle(c,r);
96 
97  pair<float,float> a(0.,0.);
98  a = pair<float,float>( (c - p2).phi(),
99  0.5*acos(1 - 2*sqr(r)/(c - p2).mag2()) );
100 
101  return a;
102 }
103 
104 /*****************************************************************************/
106  (pair<float,float> a, pair<float,float> b, bool& keep)
107 {
108  // spin closer
109  while(b.first < a.first - M_PI) b.first += 2*M_PI;
110  while(b.first > a.first + M_PI) b.first -= 2*M_PI;
111 
112  float min,max;
113 
114  if(a.first - a.second > b.first - b.second)
115  min = a.first - a.second;
116  else
117  { min = b.first - b.second; keep = false; }
118 
119  if(a.first + a.second < b.first + b.second)
120  max = a.first + a.second;
121  else
122  { max = b.first + b.second; keep = false; }
123 
124  pair<float,float> c(0.,0.);
125 
126  if(min < max)
127  {
128  c.first = 0.5*(max + min);
129  c.second = 0.5*(max - min);
130  }
131 
132  return c;
133 }
134 
135 /*****************************************************************************/
137  (const float x[3], const float y[3], float par[3])
138 {
139  float s2 = sqr(x[0]) * (y[1] - y[2]) +
140  sqr(x[1]) * (y[2] - y[0]) +
141  sqr(x[2]) * (y[0] - y[1]);
142 
143  float s1 = x[0] * (y[1] - y[2]) +
144  x[1] * (y[2] - y[0]) +
145  x[2] * (y[0] - y[1]);
146 
147  float s3 = (x[0] - x[1]) * (x[1] - x[2]) * (x[2] - x[0]);
148  float s4 = x[0]*x[1]*y[2] * (x[0] - x[1]) +
149  x[0]*y[1]*x[2] * (x[2] - x[0]) +
150  y[0]*x[1]*x[2] * (x[1] - x[2]);
151 
152  par[2] = s1 / s3; // a2
153  par[1] = -s2 / s3; // a1
154  par[0] = -s4 / s3; // a0
155 }
156 
157 /*****************************************************************************/
159  (const float x[3], const float y[3], const float par[3],
160  float phi[2],float z[2])
161 {
162  // Initial guess
163  phi[0] = min(x[0],x[2]); z[0] = min(y[0],y[2]);
164  phi[1] = max(x[0],x[2]); z[1] = max(y[0],y[2]);
165 
166  // Extremum: position and value
167  float xe = -par[1]/(2*par[2]);
168  float ye = par[0] - sqr(par[1])/(4*par[2]);
169 
170  // Check if extremum is inside the phi range
171  if(phi[0] < xe && xe < phi[1])
172  {
173  if(ye < z[0]) z[0] = ye;
174  if(ye > z[1]) z[1] = ye;
175  }
176 }
177 
178 /*****************************************************************************/
180  (const Global2DVector& a, const Global2DVector& b)
181 {
182  return a.x() * b.y() - a.y() * b.x();
183 }
184 
185 /*****************************************************************************/
188 {
189  float rad2 = (p1 - c).mag2();
190 
191  float a12 = asin(fabsf(areaParallelogram(p1 - c, p2 - c)) / rad2);
192  float a23 = asin(fabsf(areaParallelogram(p2 - c, p3 - c)) / rad2);
193 
194  return a23/a12;
195 }
196 
197 /*****************************************************************************/
199 {
200  while(phi[1] < phi[0] - M_PI) phi[1] += 2*M_PI;
201  while(phi[1] > phi[0] + M_PI) phi[1] -= 2*M_PI;
202 
203  while(phi[2] < phi[1] - M_PI) phi[2] += 2*M_PI;
204  while(phi[2] > phi[1] + M_PI) phi[2] -= 2*M_PI;
205 }
206 
207 /*****************************************************************************/
209  (float r3, float phi[2],float z[2], bool keep)
210 {
211  pair<float,float> arc_all =
212  findArcIntersection(arc_0m, findTouchingCircles(r3), keep);
213 
214  if(arc_all.second != 0.)
215  {
216  Global2DVector c3(0.,0.); // barrel at r3
217  invertCircle(c3,r3); // inverted
218 
219  float angle[3]; // prepare angles
220  angle[0] = arc_all.first - arc_all.second;
221  angle[1] = arc_all.first;
222  angle[2] = arc_all.first + arc_all.second;
223 
224  float phi3[3], z3[3];
225  Global2DVector delta = c3 - p2;
226 
227  for(int i=0; i<3; i++)
228  {
229  Global2DVector vec(cos(angle[i]), sin(angle[i])); // unit vector
230  float lambda = delta*vec - sqrt(sqr(delta*vec) - delta*delta + sqr(r3));
231 
232  Global2DVector p3 = p2 + lambda * vec; // inverted third hit
233  invertPoint(p3); // third hit
234  phi3[i] = p3.phi(); // phi of third hit
235 
236  float ratio;
237 
238  if(keep && i==1)
239  { // Straight line
240  ratio = (p2 - p3).mag() / (p1 - p2).mag();
241  }
242  else
243  { // Circle
244  Global2DVector c = p2 - vec * (vec * (p2 - p1)); // inverted antipodal
245  invertPoint(c); // antipodal
246  c = 0.5*(p1 + c); // center
247 
248  ratio = angleRatio(p3,c);
249  }
250 
251  z3[i] = g2.z() + (g2.z() - g1.z()) * ratio; // z of third hit
252  }
253 
254  spinCloser(phi3);
255 
256  // Parabola on phi - z
257  float par[3];
258  fitParabola (phi3,z3, par);
259  findRectangle(phi3,z3, par, phi,z);
260  }
261 }
262 
263 /*****************************************************************************/
265  (float z3, float phi[2],float r[2], bool keep)
266 {
267  float angle[3]; // prepare angles
268  angle[0] = arc_0m.first - arc_0m.second;
269  angle[1] = arc_0m.first;
270  angle[2] = arc_0m.first + arc_0m.second;
271 
272  float ratio = (z3 - g2.z()) / (g2.z() - g1.z());
273 
274  if(0 < ratio && ratio < maxRatio)
275  {
276  float phi3[3], r3[3];
277 
278  for(int i=0; i<3; i++)
279  {
281 
282  if(keep && i==1)
283  { // Straight line
284  p3 = p2 + ratio * (p2 - p1);
285  }
286  else
287  { // Circle
288  Global2DVector vec(cos(angle[i]), sin(angle[i])); // unit vector
289 
290  Global2DVector c = p2 - vec * (vec * (p2 - p1)); // inverted antipodal
291  invertPoint(c); // antipodal
292  c = 0.5*(p1 + c); // center
293 
294  float rad2 = (p1 - c).mag2();
295 
296  float a12 = asin(areaParallelogram(p1 - c, p2 - c) / rad2);
297  float a23 = ratio * a12;
298 
299  p3 = c + Global2DVector((p2-c).x()*cos(a23) - (p2-c).y()*sin(a23),
300  (p2-c).x()*sin(a23) + (p2-c).y()*cos(a23));
301  }
302 
303  phi3[i] = p3.phi();
304  r3[i] = p3.mag();
305  }
306 
307  spinCloser(phi3);
308 
309  // Parabola on phi - z
310  float par[3];
311  fitParabola (phi3,r3, par);
312  findRectangle(phi3,r3, par, phi,r);
313  }
314 }
315 
316 /*****************************************************************************/
318  (float rz3, float phi[2],float rz[2])
319 {
320  // Clear
321  phi[0] = 0.; rz[0] = 0.;
322  phi[1] = 0.; rz[1] = 0.;
323 
324  // Calculate
325  if(theBarrel) calculateRangesBarrel (rz3, phi,rz, keep);
326  else calculateRangesForward(rz3, phi,rz, keep);
327 }
328 
329 /*****************************************************************************/
331  (const DetLayer *layer, float phi[],float rz[])
332 {
333  theLayer = layer;
334 
335  if (layer) initLayer(layer);
336 
337  float phi_inner[2],rz_inner[2];
338  calculateRanges(theDetRange.min(), phi_inner,rz_inner);
339 
340  float phi_outer[2],rz_outer[2];
341  calculateRanges(theDetRange.max(), phi_outer,rz_outer);
342 
343  if( (phi_inner[0] == 0. && phi_inner[1] == 0.) ||
344  (phi_outer[0] == 0. && phi_outer[1] == 0.) )
345  {
346  phi[0] = 0.;
347  phi[1] = 0.;
348 
349  rz[0] = 0.;
350  rz[1] = 0.;
351  }
352  else
353  {
354  while(phi_outer[0] > phi_inner[0] + M_PI)
355  { phi_outer[0] -= 2*M_PI; phi_outer[1] -= 2*M_PI; }
356 
357  while(phi_outer[0] < phi_inner[0] - M_PI)
358  { phi_outer[0] += 2*M_PI; phi_outer[1] += 2*M_PI; }
359 
360  phi[0] = min(phi_inner[0],phi_outer[0]);
361  phi[1] = max(phi_inner[1],phi_outer[1]);
362 
363  rz[0] = min( rz_inner[0], rz_outer[0]);
364  rz[1] = max( rz_inner[1], rz_outer[1]);
365  }
366 }
367 
368 /*****************************************************************************/
370  (float rz3, float phi[],float rz[])
371 {
372  calculateRanges(rz3, phi,rz);
373 }
374 
375 /*****************************************************************************/
377  (GlobalPoint g3, const vector<const TrackingRecHit*>& h,
378  vector<GlobalVector>& globalDirs, const edm::EventSetup& es)
379 {
380  Global2DVector p1(g1.x(),g1.y());
381  Global2DVector p2(g2.x(),g2.y());
382  Global2DVector p3(g3.x(),g3.y());
383 
384  CircleFromThreePoints circle(g1,g2,g3);
385 
386  if(circle.curvature() != 0.)
387  {
388  Global2DVector c (circle.center().x(), circle.center().y());
389 
390  float rad2 = (p1 - c).mag2();
391  float a12 = asin(fabsf(areaParallelogram(p1 - c, p2 - c)) / rad2);
392  float a23 = asin(fabsf(areaParallelogram(p2 - c, p3 - c)) / rad2);
393 
394  float slope = (g2.z() - g1.z()) / a12;
395 
396  float rz3 = g2.z() + slope * a23;
397  float delta_z = g3.z() - rz3;
398 
399  // Transform to tt
400  vector<TransientTrackingRecHit::RecHitPointer> th;
401  for(vector<const TrackingRecHit*>::const_iterator ih = h.begin(); ih!= h.end(); ih++)
402  th.push_back(theTTRecHitBuilder->build(*ih));
403 
404  float sigma1_le2 = max(th[0]->parametersError()[0][0],
405  th[0]->parametersError()[1][1]);
406  float sigma2_le2 = max(th[1]->parametersError()[0][0],
407  th[1]->parametersError()[1][1]);
408 
409  float sigma_z2 = (1 + a23/a12)*(1 + a23/a12) * sigma2_le2 +
410  ( a23/a12)*( a23/a12) * sigma1_le2;
411 
412  float cotTheta = slope * circle.curvature(); // == sinhEta
413  float coshEta = sqrt(1 + sqr(cotTheta)); // == 1/sinTheta
414 
415  float pt = Bz / circle.curvature();
416  float p = pt * coshEta;
417 
418  float m_pi = 0.13957018;
419  float beta = p / sqrt(sqr(p) + sqr(m_pi));
420 
422  PixelRecoPointRZ rz2(g2.perp(), g2.z());
423 
424  float sigma_z = msp(pt, cotTheta, rz2) / beta;
425 
426  // Calculate globalDirs
427  float sinTheta = 1. / coshEta;
428  float cosTheta = cotTheta * sinTheta;
429 
430  int dir;
431  if(areaParallelogram(p1 - c, p2 - c) > 0) dir = 1; else dir = -1;
432 
433  float curvature = circle.curvature();
434 
435  {
436  Global2DVector v = (p1 - c)*curvature*dir;
437  globalDirs.push_back(GlobalVector(-v.y()*sinTheta,v.x()*sinTheta,cosTheta));
438  }
439 
440  {
441  Global2DVector v = (p2 - c)*curvature*dir;
442  globalDirs.push_back(GlobalVector(-v.y()*sinTheta,v.x()*sinTheta,cosTheta));
443  }
444 
445  {
446  Global2DVector v = (p3 - c)*curvature*dir;
447  globalDirs.push_back(GlobalVector(-v.y()*sinTheta,v.x()*sinTheta,cosTheta));
448  }
449 
450  // Multiple scattering
451  float sigma_ms = sigma_z * coshEta;
452 
453  // Local error squared
454  float sigma_le2 = max(th[2]->parametersError()[0][0],
455  th[2]->parametersError()[1][1]);
456 
457  return (delta_z*delta_z / (sigma_ms*sigma_ms + sigma_le2 + sigma_z2)
458  < nSigma * nSigma);
459  }
460 
461  return false;
462 }
463 
464 /*****************************************************************************/
466 {
467  if ( layer->location() == GeomDetEnumerators::barrel) {
468  theBarrel = true;
469  theForward = false;
470  const BarrelDetLayer& bl = dynamic_cast<const BarrelDetLayer&>(*layer);
471  float halfThickness = bl.surface().bounds().thickness()/2;
472  float radius = bl.specificSurface().radius();
473  theDetRange = Range(radius-halfThickness, radius+halfThickness);
474  } else if ( layer->location() == GeomDetEnumerators::endcap) {
475  theBarrel= false;
476  theForward = true;
477  const ForwardDetLayer& fl = dynamic_cast<const ForwardDetLayer&>(*layer);
478  float halfThickness = fl.surface().bounds().thickness()/2;
479  float zLayer = fl.position().z() ;
480  theDetRange = Range(zLayer-halfThickness, zLayer+halfThickness);
481  }
482 }
dbl * delta
Definition: mlp_gen.cc:36
float originRBound() const
bounds the particle vertex in the transverse plane
void findRectangle(const float x[3], const float y[3], const float par[3], float phi[2], float z[2])
void invertCircle(Global2DVector &c, float &r)
T y() const
Definition: PV2DBase.h:46
void initLayer(const DetLayer *layer)
GlobalPoint const & origin() const
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
PixelRecoRange< float > Range
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
static const double slope[3]
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
void calculateRangesForward(float z3, float phi[2], float r[2], bool keep)
virtual Location location() const =0
Which part of the detector (barrel, endcap)
T mag() const
Definition: PV2DBase.h:49
void calculateRangesBarrel(float r3, float phi[2], float z[2], bool keep)
T y() const
Definition: PV3DBase.h:63
const Bounds & bounds() const
Definition: Surface.h:120
virtual const BoundCylinder & specificSurface() const final
Extension of the interface.
float angleRatio(const Global2DVector &p3, const Global2DVector &c)
const int keep
GlobalVector inInverseGeV(const GlobalPoint &gp) const
Field value ad specified global point, in 1/Gev.
Definition: MagneticField.h:41
Geom::Phi< T > phi() const
Definition: PV2DBase.h:51
T curvature(T InversePt, const edm::EventSetup &iSetup)
susybsm::MuonSegmentRefProd msp
Definition: classes.h:34
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
float areaParallelogram(const Global2DVector &a, const Global2DVector &b)
std::pair< float, float > findMinimalCircles(float r)
T min(T a, T b)
Definition: MathUtil.h:58
double p2[4]
Definition: TauolaWrapper.h:90
#define M_PI
virtual float thickness() const =0
virtual const Surface::PositionType & position() const
Returns position of the surface.
float ptMin() const
minimal pt of interest
double b
Definition: hdecay.h:120
ThirdHitPrediction(const TrackingRegion &region, GlobalPoint inner, GlobalPoint outer, const edm::EventSetup &es, double nSigMultipleScattering, double maxAngleRatio, std::string builderName)
void spinCloser(float phi[3])
HLT enums.
const BoundSurface & surface() const final
The surface of the GeometricSearchDet.
double p1[4]
Definition: TauolaWrapper.h:89
std::pair< float, float > findArcIntersection(std::pair< float, float > a, std::pair< float, float > b, bool &keep)
double a
Definition: hdecay.h:121
T get() const
Definition: EventSetup.h:71
void invertPoint(Global2DVector &p)
void fitParabola(const float x[3], const float y[3], float par[3])
void calculateRanges(float rz3, float phi[2], float rz[2])
dbl *** dir
Definition: mlp_gen.cc:35
bool isCompatibleWithMultipleScattering(GlobalPoint g3, const std::vector< const TrackingRecHit * > &h, std::vector< GlobalVector > &localDirs, const edm::EventSetup &es)
void getRanges(const DetLayer *layer, float phi[], float rz[])
std::pair< float, float > findTouchingCircles(float r)
rm
Definition: submit.py:77
T x() const
Definition: PV2DBase.h:45
T x() const
Definition: PV3DBase.h:62
T const * product() const
Definition: ESHandle.h:86
const BoundSurface & surface() const final
GeometricSearchDet interface.
Global3DVector GlobalVector
Definition: GlobalVector.h:10
Vector2DBase< float, GlobalTag > Global2DVector
double p3[4]
Definition: TauolaWrapper.h:91
#define m_pi
Definition: RPCConst.cc:8
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
float sqr(float x)