CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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)