CMS 3D CMS Logo

MuonSeedCreator.cc
Go to the documentation of this file.
1 
9 
11 
13 
16 
19 
25 
29 
30 #include "gsl/gsl_statistics.h"
31 
32 /*
33  * Constructor
34  */
36  theMinMomentum = pset.getParameter<double>("minimumSeedPt");
37  theMaxMomentum = pset.getParameter<double>("maximumSeedPt");
38  defaultMomentum = pset.getParameter<double>("defaultSeedPt");
39  debug = pset.getParameter<bool>("DebugMuonSeed");
40  sysError = pset.getParameter<double>("SeedPtSystematics");
41  // load seed PT parameters
42  DT12 = pset.getParameter<std::vector<double> >("DT_12");
43  DT13 = pset.getParameter<std::vector<double> >("DT_13");
44  DT14 = pset.getParameter<std::vector<double> >("DT_14");
45  DT23 = pset.getParameter<std::vector<double> >("DT_23");
46  DT24 = pset.getParameter<std::vector<double> >("DT_24");
47  DT34 = pset.getParameter<std::vector<double> >("DT_34");
48 
49  CSC01 = pset.getParameter<std::vector<double> >("CSC_01");
50  CSC12 = pset.getParameter<std::vector<double> >("CSC_12");
51  CSC02 = pset.getParameter<std::vector<double> >("CSC_02");
52  CSC13 = pset.getParameter<std::vector<double> >("CSC_13");
53  CSC03 = pset.getParameter<std::vector<double> >("CSC_03");
54  CSC14 = pset.getParameter<std::vector<double> >("CSC_14");
55  CSC23 = pset.getParameter<std::vector<double> >("CSC_23");
56  CSC24 = pset.getParameter<std::vector<double> >("CSC_24");
57  CSC34 = pset.getParameter<std::vector<double> >("CSC_34");
58 
59  OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
60  OL1222 = pset.getParameter<std::vector<double> >("OL_1222");
61  OL1232 = pset.getParameter<std::vector<double> >("OL_1232");
62  OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
63  OL2222 = pset.getParameter<std::vector<double> >("OL_1222");
64 
65  SME11 = pset.getParameter<std::vector<double> >("SME_11");
66  SME12 = pset.getParameter<std::vector<double> >("SME_12");
67  SME13 = pset.getParameter<std::vector<double> >("SME_13");
68  SME21 = pset.getParameter<std::vector<double> >("SME_21");
69  SME22 = pset.getParameter<std::vector<double> >("SME_22");
70  SME31 = pset.getParameter<std::vector<double> >("SME_31");
71  SME32 = pset.getParameter<std::vector<double> >("SME_32");
72  SME41 = pset.getParameter<std::vector<double> >("SME_41");
73 
74  SMB10 = pset.getParameter<std::vector<double> >("SMB_10");
75  SMB11 = pset.getParameter<std::vector<double> >("SMB_11");
76  SMB12 = pset.getParameter<std::vector<double> >("SMB_12");
77  SMB20 = pset.getParameter<std::vector<double> >("SMB_20");
78  SMB21 = pset.getParameter<std::vector<double> >("SMB_21");
79  SMB22 = pset.getParameter<std::vector<double> >("SMB_22");
80  SMB30 = pset.getParameter<std::vector<double> >("SMB_30");
81  SMB31 = pset.getParameter<std::vector<double> >("SMB_31");
82  SMB32 = pset.getParameter<std::vector<double> >("SMB_32");
83 
84  // Load dphi scale parameters
85  CSC01_1 = pset.getParameter<std::vector<double> >("CSC_01_1_scale");
86  CSC12_1 = pset.getParameter<std::vector<double> >("CSC_12_1_scale");
87  CSC12_2 = pset.getParameter<std::vector<double> >("CSC_12_2_scale");
88  CSC12_3 = pset.getParameter<std::vector<double> >("CSC_12_3_scale");
89  CSC13_2 = pset.getParameter<std::vector<double> >("CSC_13_2_scale");
90  CSC13_3 = pset.getParameter<std::vector<double> >("CSC_13_3_scale");
91  CSC14_3 = pset.getParameter<std::vector<double> >("CSC_14_3_scale");
92  CSC23_1 = pset.getParameter<std::vector<double> >("CSC_23_1_scale");
93  CSC23_2 = pset.getParameter<std::vector<double> >("CSC_23_2_scale");
94  CSC24_1 = pset.getParameter<std::vector<double> >("CSC_24_1_scale");
95  CSC34_1 = pset.getParameter<std::vector<double> >("CSC_34_1_scale");
96 
97  DT12_1 = pset.getParameter<std::vector<double> >("DT_12_1_scale");
98  DT12_2 = pset.getParameter<std::vector<double> >("DT_12_2_scale");
99  DT13_1 = pset.getParameter<std::vector<double> >("DT_13_1_scale");
100  DT13_2 = pset.getParameter<std::vector<double> >("DT_13_2_scale");
101  DT14_1 = pset.getParameter<std::vector<double> >("DT_14_1_scale");
102  DT14_2 = pset.getParameter<std::vector<double> >("DT_14_2_scale");
103  DT23_1 = pset.getParameter<std::vector<double> >("DT_23_1_scale");
104  DT23_2 = pset.getParameter<std::vector<double> >("DT_23_2_scale");
105  DT24_1 = pset.getParameter<std::vector<double> >("DT_24_1_scale");
106  DT24_2 = pset.getParameter<std::vector<double> >("DT_24_2_scale");
107  DT34_1 = pset.getParameter<std::vector<double> >("DT_34_1_scale");
108  DT34_2 = pset.getParameter<std::vector<double> >("DT_34_2_scale");
109 
110  OL_1213 = pset.getParameter<std::vector<double> >("OL_1213_0_scale");
111  OL_1222 = pset.getParameter<std::vector<double> >("OL_1222_0_scale");
112  OL_1232 = pset.getParameter<std::vector<double> >("OL_1232_0_scale");
113  OL_2213 = pset.getParameter<std::vector<double> >("OL_2213_0_scale");
114  OL_2222 = pset.getParameter<std::vector<double> >("OL_2222_0_scale");
115 
116  SMB_10S = pset.getParameter<std::vector<double> >("SMB_10_0_scale");
117  SMB_11S = pset.getParameter<std::vector<double> >("SMB_11_0_scale");
118  SMB_12S = pset.getParameter<std::vector<double> >("SMB_12_0_scale");
119  SMB_20S = pset.getParameter<std::vector<double> >("SMB_20_0_scale");
120  SMB_21S = pset.getParameter<std::vector<double> >("SMB_21_0_scale");
121  SMB_22S = pset.getParameter<std::vector<double> >("SMB_22_0_scale");
122  SMB_30S = pset.getParameter<std::vector<double> >("SMB_30_0_scale");
123  SMB_31S = pset.getParameter<std::vector<double> >("SMB_31_0_scale");
124  SMB_32S = pset.getParameter<std::vector<double> >("SMB_32_0_scale");
125 
126  SME_11S = pset.getParameter<std::vector<double> >("SME_11_0_scale");
127  SME_12S = pset.getParameter<std::vector<double> >("SME_12_0_scale");
128  SME_13S = pset.getParameter<std::vector<double> >("SME_13_0_scale");
129  SME_21S = pset.getParameter<std::vector<double> >("SME_21_0_scale");
130  SME_22S = pset.getParameter<std::vector<double> >("SME_22_0_scale");
131 }
132 
133 /*
134  * Destructor
135  */
137 
138 /*
139  * createSeed
140  *
141  * Note type = 1 --> CSC
142  * = 2 --> Overlap
143  * = 3 --> DT
144  */
146  int type, const SegmentContainer& seg, const std::vector<int>& layers, int NShowers, int NShowerSegments) {
147  // The index of the station closest to the IP
148  int last = 0;
149 
150  double ptmean = theMinMomentum;
151  double sptmean = theMinMomentum;
152 
153  AlgebraicVector t(4);
154  AlgebraicSymMatrix mat(5, 0);
155  LocalPoint segPos;
156 
157  // Compute the pt according to station types used;
158  if (type == 1)
159  estimatePtCSC(seg, layers, ptmean, sptmean);
160  if (type == 2)
161  estimatePtOverlap(seg, layers, ptmean, sptmean);
162  if (type == 3)
163  estimatePtDT(seg, layers, ptmean, sptmean);
164  if (type == 4)
165  estimatePtSingle(seg, layers, ptmean, sptmean);
166  // type 5 are the seeding for ME1/4
167  if (type == 5)
168  estimatePtCSC(seg, layers, ptmean, sptmean);
169 
170  // for certain clear showering case, set-up the minimum value
171  if (NShowers > 0)
172  estimatePtShowering(NShowers, NShowerSegments, ptmean, sptmean);
173  //if ( NShowers > 0 ) std::cout<<" Showering happened "<<NShowers<<" times w/ "<< NShowerSegments<<std::endl; ;
174 
175  // Minimal pt
176  double charge = 1.0;
177  if (ptmean < 0.)
178  charge = -1.0;
179  if ((charge * ptmean) < theMinMomentum) {
180  ptmean = theMinMomentum * charge;
181  sptmean = theMinMomentum;
182  } else if ((charge * ptmean) > theMaxMomentum) {
183  ptmean = theMaxMomentum * charge;
184  sptmean = theMaxMomentum * 0.25;
185  }
186 
188 
189  double p_err = 0.0;
190  // determine the seed layer
191  int best_seg = 0;
192  double chi2_dof = 9999.0;
193  unsigned int ini_seg = 0;
194  // avoid generating seed from 1st layer(ME1/1)
195  if (type == 5)
196  ini_seg = 1;
197  for (size_t i = ini_seg; i < seg.size(); i++) {
198  double dof = static_cast<double>(seg[i]->degreesOfFreedom());
199  if (chi2_dof < (seg[i]->chi2() / dof))
200  continue;
201  chi2_dof = seg[i]->chi2() / dof;
202  best_seg = static_cast<int>(i);
203  }
204 
205  if (type == 1 || type == 5 || type == 4) {
206  // Fill the LocalTrajectoryParameters
208  last = best_seg;
209  // last = 0;
210  GlobalVector mom = seg[last]->globalPosition() - GlobalPoint();
211  segPos = seg[last]->localPosition();
213 
214  GlobalVector polar(GlobalVector::Spherical(mom.theta(), seg[last]->globalDirection().phi(), 1.));
215 
217  polar *= fabs(ptmean) / polar.perp();
219  LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
220  int chargeI = static_cast<int>(charge);
221  LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
222  param = param1;
223  p_err = (sptmean * sptmean) / (polar.mag() * polar.mag() * ptmean * ptmean);
224  mat = seg[last]->parametersError().similarityT(seg[last]->projectionMatrix());
225  mat[0][0] = p_err;
226  if (type == 5) {
227  mat[0][0] = mat[0][0] / fabs(tan(mom.theta()));
228  mat[1][1] = mat[1][1] / fabs(tan(mom.theta()));
229  mat[3][3] = 2.25 * mat[3][3];
230  mat[4][4] = 2.25 * mat[4][4];
231  }
232  if (type == 4) {
233  mat[0][0] = mat[0][0] / fabs(tan(mom.theta()));
234  mat[1][1] = mat[1][1] / fabs(tan(mom.theta()));
235  mat[2][2] = 2.25 * mat[2][2];
236  mat[3][3] = 2.25 * mat[3][3];
237  mat[4][4] = 2.25 * mat[4][4];
238  }
239  double dh = fabs(seg[last]->globalPosition().eta()) - 1.6;
240  if (fabs(dh) < 0.1 && type == 1) {
241  mat[1][1] = 4. * mat[1][1];
242  mat[2][2] = 4. * mat[2][2];
243  mat[3][3] = 9. * mat[3][3];
244  mat[4][4] = 9. * mat[4][4];
245  }
246 
247  //if ( !highPt && type != 1 ) mat[1][1]= 2.25*mat[1][1];
248  //if ( highPt && type != 1 ) mat[3][3]= 2.25*mat[1][1];
249  //mat[2][2]= 3.*mat[2][2];
250  //mat[3][3]= 2.*mat[3][3];
251  //mat[4][4]= 2.*mat[4][4];
252  } else {
253  // Fill the LocalTrajectoryParameters
255  last = 0;
256  segPos = seg[last]->localPosition();
257  GlobalVector mom = seg[last]->globalPosition() - GlobalPoint();
259  GlobalVector polar(GlobalVector::Spherical(mom.theta(), seg[last]->globalDirection().phi(), 1.));
260  //GlobalVector polar(GlobalVector::Spherical(seg[last]->globalDirection().theta(),seg[last]->globalDirection().phi(),1.));
261 
263  //double ptRatio = 1.0 - (2.808/(fabs(ptmean) -1)) + (4.546/( (fabs(ptmean)-1)*(fabs(ptmean)-1)) );
264  //ptmean = ptmean*ptRatio ;
265 
267  polar *= fabs(ptmean) / polar.perp();
269  LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
270  int chargeI = static_cast<int>(charge);
271  LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
272  param = param1;
273  p_err = (sptmean * sptmean) / (polar.mag() * polar.mag() * ptmean * ptmean);
274  mat = seg[last]->parametersError().similarityT(seg[last]->projectionMatrix());
275  //mat[0][0]= 1.44 * p_err;
276  mat[0][0] = p_err;
277  }
278 
279  if (debug) {
280  GlobalPoint gp = seg[last]->globalPosition();
281  float Geta = gp.eta();
282 
283  std::cout << "Type " << type << " Nsegments " << layers.size() << " ";
284  std::cout << "pt " << ptmean << " errpt " << sptmean << " eta " << Geta << " charge " << charge << std::endl;
285  }
286 
287  // this perform H.T() * parErr * H, which is the projection of the
288  // the measurement error (rechit rf) to the state error (TSOS rf)
289  // Legend:
290  // H => is the 4x5 projection matrix
291  // parError the 4x4 parameter error matrix of the RecHit
292 
293  LocalTrajectoryError error(asSMatrix<5>(mat));
294 
295  // Create the TrajectoryStateOnSurface
296  TrajectoryStateOnSurface tsos(param, error, seg[last]->det()->surface(), &*BField);
297 
298  // Take the DetLayer on which relies the segment
299  DetId id = seg[last]->geographicalId();
300 
301  // Transform it in a TrajectoryStateOnSurface
302 
304 
306  for (unsigned l = 0; l < seg.size(); l++) {
307  container.push_back(seg[l]->hit()->clone());
308  //container.push_back(seg[l]->hit());
309  }
310 
311  TrajectorySeed theSeed(seedTSOS, container, alongMomentum);
312  return theSeed;
313 }
314 
315 /*
316  * estimatePtCSC
317  *
318  * Look at delta phi to determine pt as:
319  * pt = (c_1 * eta + c_2) / dphi
320  *
321  * Note that only segment pairs with one segment in the ME1 layers give sensitive results
322  *
323  */
325  const std::vector<int>& layers,
326  double& thePt,
327  double& theSpt) {
328  unsigned size = seg.size();
329  if (size < 2)
330  return;
331 
332  // reverse the segment and layer container first for pure CSC case
333  //if ( layers[0] > layers[ layers.size()-1 ] ) {
334  // reverse( layers.begin(), layers.end() );
335  // reverse( seg.begin(), seg.end() );
336  //}
337 
338  std::vector<double> ptEstimate;
339  std::vector<double> sptEstimate;
340 
341  thePt = defaultMomentum;
342  theSpt = defaultMomentum;
343 
344  double pt = 0.;
345  double spt = 0.;
346  GlobalPoint segPos[2];
347 
348  int layer0 = layers[0];
349  segPos[0] = seg[0]->globalPosition();
350  float eta = fabs(segPos[0].eta());
351  //float corr = fabs( tan(segPos[0].theta()) );
352  // use pt from vertex information
353  /*
354  if ( layer0 == 0 ) {
355  SegmentContainer seg0;
356  seg0.push_back(seg[0]);
357  std::vector<int> lyr0(1,0);
358  estimatePtSingle( seg0, lyr0, thePt, theSpt);
359  ptEstimate.push_back( thePt );
360  sptEstimate.push_back( theSpt );
361  }
362  */
363 
364  //std::cout<<" estimate CSC "<<std::endl;
365 
366  unsigned idx1 = size;
367  if (size > 1) {
368  while (idx1 > 1) {
369  idx1--;
370  int layer1 = layers[idx1];
371  if (layer0 == layer1)
372  continue;
373  segPos[1] = seg[idx1]->globalPosition();
374 
375  double dphi = segPos[0].phi() - segPos[1].phi();
376  //double temp_dphi = dphi/corr;
377  double temp_dphi = dphi;
378 
379  double sign = 1.0;
380  if (temp_dphi < 0.) {
381  temp_dphi = -1.0 * temp_dphi;
382  sign = -1.0;
383  }
384 
385  // Ensure that delta phi is not too small to prevent pt from blowing up
386  if (temp_dphi < 0.0001) {
387  temp_dphi = 0.0001;
388  pt = theMaxMomentum;
389  spt = theMaxMomentum * 0.25;
390  ptEstimate.push_back(pt * sign);
391  sptEstimate.push_back(spt);
392  }
393  // ME1 is inner-most
394  if (layer0 == 0 && temp_dphi >= 0.0001) {
395  // ME1/2 is outer-most
396  if (layer1 == 1) {
397  //temp_dphi = scaledPhi(temp_dphi, CSC01_1[3] );
398  pt = getPt(CSC01, eta, temp_dphi)[0];
399  spt = getPt(CSC01, eta, temp_dphi)[1];
400  }
401  // ME2 is outer-most
402  else if (layer1 == 2) {
403  //temp_dphi = scaledPhi(temp_dphi, CSC12_3[3] );
404  pt = getPt(CSC02, eta, temp_dphi)[0];
405  spt = getPt(CSC02, eta, temp_dphi)[1];
406  }
407  // ME3 is outer-most
408  else if (layer1 == 3) {
409  //temp_dphi = scaledPhi(temp_dphi, CSC13_3[3] );
410  pt = getPt(CSC03, eta, temp_dphi)[0];
411  spt = getPt(CSC03, eta, temp_dphi)[1];
412  }
413  // ME4 is outer-most
414  else {
415  //temp_dphi = scaledPhi(temp_dphi, CSC14_3[3]);
416  pt = getPt(CSC14, eta, temp_dphi)[0];
417  spt = getPt(CSC14, eta, temp_dphi)[1];
418  }
419  ptEstimate.push_back(pt * sign);
420  sptEstimate.push_back(spt);
421  }
422 
423  // ME1/2,ME1/3 is inner-most
424  if (layer0 == 1) {
425  // ME2 is outer-most
426  if (layer1 == 2) {
427  //if ( eta <= 1.2 ) { temp_dphi = scaledPhi(temp_dphi, CSC12_1[3]); }
428  //if ( eta > 1.2 ) { temp_dphi = scaledPhi(temp_dphi, CSC12_2[3]); }
429  pt = getPt(CSC12, eta, temp_dphi)[0];
430  spt = getPt(CSC12, eta, temp_dphi)[1];
431  }
432  // ME3 is outer-most
433  else if (layer1 == 3) {
434  temp_dphi = scaledPhi(temp_dphi, CSC13_2[3]);
435  pt = getPt(CSC13, eta, temp_dphi)[0];
436  spt = getPt(CSC13, eta, temp_dphi)[1];
437  }
438  // ME4 is outer-most
439  else {
440  temp_dphi = scaledPhi(temp_dphi, CSC14_3[3]);
441  pt = getPt(CSC14, eta, temp_dphi)[0];
442  spt = getPt(CSC14, eta, temp_dphi)[1];
443  }
444  ptEstimate.push_back(pt * sign);
445  sptEstimate.push_back(spt);
446  }
447 
448  // ME2 is inner-most
449  if (layer0 == 2 && temp_dphi > 0.0001) {
450  // ME4 is outer-most
451  if (layer1 == 4) {
452  temp_dphi = scaledPhi(temp_dphi, CSC24_1[3]);
453  pt = getPt(CSC24, eta, temp_dphi)[0];
454  spt = getPt(CSC24, eta, temp_dphi)[1];
455  }
456  // ME3 is outer-most
457  else {
458  // if ME2-4 is availabe , discard ME2-3
459  if (eta <= 1.7) {
460  temp_dphi = scaledPhi(temp_dphi, CSC23_1[3]);
461  }
462  if (eta > 1.7) {
463  temp_dphi = scaledPhi(temp_dphi, CSC23_2[3]);
464  }
465  pt = getPt(CSC23, eta, temp_dphi)[0];
466  spt = getPt(CSC23, eta, temp_dphi)[1];
467  }
468  ptEstimate.push_back(pt * sign);
469  sptEstimate.push_back(spt);
470  }
471 
472  // ME3 is inner-most
473  if (layer0 == 3 && temp_dphi > 0.0001) {
474  temp_dphi = scaledPhi(temp_dphi, CSC34_1[3]);
475  pt = getPt(CSC34, eta, temp_dphi)[0];
476  spt = getPt(CSC34, eta, temp_dphi)[1];
477  ptEstimate.push_back(pt * sign);
478  sptEstimate.push_back(spt);
479  }
480  }
481  }
482 
483  // Compute weighted average if have more than one estimator
484  if (!ptEstimate.empty())
485  weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
486 }
487 
488 /*
489  * estimatePtDT
490  *
491  * Look at delta phi between segments to determine pt as:
492  * pt = (c_1 * eta + c_2) / dphi
493  */
495  const std::vector<int>& layers,
496  double& thePt,
497  double& theSpt) {
498  unsigned size = seg.size();
499  if (size < 2)
500  return;
501 
502  std::vector<double> ptEstimate;
503  std::vector<double> sptEstimate;
504 
505  thePt = defaultMomentum;
506  theSpt = defaultMomentum;
507 
508  double pt = 0.;
509  double spt = 0.;
510  GlobalPoint segPos[2];
511 
512  int layer0 = layers[0];
513  segPos[0] = seg[0]->globalPosition();
514  float eta = fabs(segPos[0].eta());
515 
516  //std::cout<<" estimate DT "<<std::endl;
517  // inner-most layer
518  //for ( unsigned idx0 = 0; idx0 < size-1; ++idx0 ) {
519  // layer0 = layers[idx0];
520  // segPos[0] = seg[idx0]->globalPosition();
521  // outer-most layer
522  // for ( unsigned idx1 = idx0+1; idx1 < size; ++idx1 ) {
523  for (unsigned idx1 = 1; idx1 < size; ++idx1) {
524  int layer1 = layers[idx1];
525  segPos[1] = seg[idx1]->globalPosition();
526 
527  //eta = fabs(segPos[1].eta());
528  //if (layer1 == -4) eta = fabs(segPos[0].eta());
529 
530  double dphi = segPos[0].phi() - segPos[1].phi();
531  double temp_dphi = dphi;
532 
533  // Ensure that delta phi is not too small to prevent pt from blowing up
534 
535  double sign = 1.0;
536  if (temp_dphi < 0.) {
537  temp_dphi = -temp_dphi;
538  sign = -1.0;
539  }
540 
541  if (temp_dphi < 0.0001) {
542  temp_dphi = 0.0001;
543  pt = theMaxMomentum;
544  spt = theMaxMomentum * 0.25;
545  ptEstimate.push_back(pt * sign);
546  sptEstimate.push_back(spt);
547  }
548 
549  // MB1 is inner-most
550  if (layer0 == -1 && temp_dphi > 0.0001) {
551  // MB2 is outer-most
552  if (layer1 == -2) {
553  if (eta <= 0.7) {
554  temp_dphi = scaledPhi(temp_dphi, DT12_1[3]);
555  }
556  if (eta > 0.7) {
557  temp_dphi = scaledPhi(temp_dphi, DT12_2[3]);
558  }
559  pt = getPt(DT12, eta, temp_dphi)[0];
560  spt = getPt(DT12, eta, temp_dphi)[1];
561  }
562  // MB3 is outer-most
563  else if (layer1 == -3) {
564  if (eta <= 0.6) {
565  temp_dphi = scaledPhi(temp_dphi, DT13_1[3]);
566  }
567  if (eta > 0.6) {
568  temp_dphi = scaledPhi(temp_dphi, DT13_2[3]);
569  }
570  pt = getPt(DT13, eta, temp_dphi)[0];
571  spt = getPt(DT13, eta, temp_dphi)[1];
572  }
573  // MB4 is outer-most
574  else {
575  if (eta <= 0.52) {
576  temp_dphi = scaledPhi(temp_dphi, DT14_1[3]);
577  }
578  if (eta > 0.52) {
579  temp_dphi = scaledPhi(temp_dphi, DT14_2[3]);
580  }
581  pt = getPt(DT14, eta, temp_dphi)[0];
582  spt = getPt(DT14, eta, temp_dphi)[1];
583  }
584  ptEstimate.push_back(pt * sign);
585  sptEstimate.push_back(spt);
586  }
587 
588  // MB2 is inner-most
589  if (layer0 == -2 && temp_dphi > 0.0001) {
590  // MB3 is outer-most
591  if (layer1 == -3) {
592  if (eta <= 0.6) {
593  temp_dphi = scaledPhi(temp_dphi, DT23_1[3]);
594  }
595  if (eta > 0.6) {
596  temp_dphi = scaledPhi(temp_dphi, DT23_2[3]);
597  }
598  pt = getPt(DT23, eta, temp_dphi)[0];
599  spt = getPt(DT23, eta, temp_dphi)[1];
600  }
601  // MB4 is outer-most
602  else {
603  if (eta <= 0.52) {
604  temp_dphi = scaledPhi(temp_dphi, DT24_1[3]);
605  }
606  if (eta > 0.52) {
607  temp_dphi = scaledPhi(temp_dphi, DT24_2[3]);
608  }
609  pt = getPt(DT24, eta, temp_dphi)[0];
610  spt = getPt(DT24, eta, temp_dphi)[1];
611  }
612  ptEstimate.push_back(pt * sign);
613  sptEstimate.push_back(spt);
614  }
615 
616  // MB3 is inner-most -> only marginally useful to pick up the charge
617  if (layer0 == -3 && temp_dphi > 0.0001) {
618  // MB4 is outer-most
619 
620  if (eta <= 0.51) {
621  temp_dphi = scaledPhi(temp_dphi, DT34_1[3]);
622  }
623  if (eta > 0.51) {
624  temp_dphi = scaledPhi(temp_dphi, DT34_2[3]);
625  }
626  pt = getPt(DT34, eta, temp_dphi)[0];
627  spt = getPt(DT34, eta, temp_dphi)[1];
628  ptEstimate.push_back(pt * sign);
629  sptEstimate.push_back(spt);
630  }
631  }
632  //}
633 
634  // Compute weighted average if have more than one estimator
635  if (!ptEstimate.empty())
636  weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
637 }
638 
639 /*
640  * estimatePtOverlap
641  *
642  */
644  const std::vector<int>& layers,
645  double& thePt,
646  double& theSpt) {
647  int size = layers.size();
648 
649  thePt = defaultMomentum;
650  theSpt = defaultMomentum;
651 
652  SegmentContainer segCSC;
653  std::vector<int> layersCSC;
654  SegmentContainer segDT;
655  std::vector<int> layersDT;
656 
657  // DT layers are numbered as -4 to -1, whereas CSC layers go from 0 to 4:
658  for (unsigned j = 0; j < layers.size(); ++j) {
659  if (layers[j] > -1) {
660  segCSC.push_back(seg[j]);
661  layersCSC.push_back(layers[j]);
662  } else {
663  segDT.push_back(seg[j]);
664  layersDT.push_back(layers[j]);
665  }
666  }
667 
668  std::vector<double> ptEstimate;
669  std::vector<double> sptEstimate;
670 
671  GlobalPoint segPos[2];
672  int layer0 = layers[0];
673  segPos[0] = seg[0]->globalPosition();
674  float eta = fabs(segPos[0].eta());
675  //std::cout<<" estimate OL "<<std::endl;
676 
677  if (!segDT.empty() && !segCSC.empty()) {
678  int layer1 = layers[size - 1];
679  segPos[1] = seg[size - 1]->globalPosition();
680 
681  double dphi = segPos[0].phi() - segPos[1].phi();
682  double temp_dphi = dphi;
683 
684  // Ensure that delta phi is not too small to prevent pt from blowing up
685 
686  double sign = 1.0;
687  if (temp_dphi < 0.) {
688  temp_dphi = -temp_dphi;
689  sign = -1.0;
690  }
691 
692  if (temp_dphi < 0.0001) {
693  temp_dphi = 0.0001;
694  thePt = theMaxMomentum;
695  theSpt = theMaxMomentum * 0.25;
696  ptEstimate.push_back(thePt * sign);
697  sptEstimate.push_back(theSpt);
698  }
699 
700  // MB1 is inner-most
701  if (layer0 == -1 && temp_dphi > 0.0001) {
702  // ME1/3 is outer-most
703  if (layer1 == 1) {
704  temp_dphi = scaledPhi(temp_dphi, OL_1213[3]);
705  thePt = getPt(OL1213, eta, temp_dphi)[0];
706  theSpt = getPt(OL1213, eta, temp_dphi)[1];
707  }
708  // ME2 is outer-most
709  else if (layer1 == 2) {
710  temp_dphi = scaledPhi(temp_dphi, OL_1222[3]);
711  thePt = getPt(OL1222, eta, temp_dphi)[0];
712  theSpt = getPt(OL1222, eta, temp_dphi)[1];
713  }
714  // ME3 is outer-most
715  else {
716  temp_dphi = scaledPhi(temp_dphi, OL_1232[3]);
717  thePt = getPt(OL1232, eta, temp_dphi)[0];
718  theSpt = getPt(OL1232, eta, temp_dphi)[1];
719  }
720  ptEstimate.push_back(thePt * sign);
721  sptEstimate.push_back(theSpt);
722  }
723  // MB2 is inner-most
724  if (layer0 == -2 && temp_dphi > 0.0001) {
725  // ME1/3 is outer-most
726  if (layer1 == 1) {
727  temp_dphi = scaledPhi(temp_dphi, OL_2213[3]);
728  thePt = getPt(OL2213, eta, temp_dphi)[0];
729  theSpt = getPt(OL2213, eta, temp_dphi)[1];
730  ptEstimate.push_back(thePt * sign);
731  sptEstimate.push_back(theSpt);
732  }
733  // ME2 is outer-most
734  if (layer1 == 2) {
735  temp_dphi = scaledPhi(temp_dphi, OL_2222[3]);
736  thePt = getPt(OL2222, eta, temp_dphi)[0];
737  theSpt = getPt(OL2222, eta, temp_dphi)[1];
738  }
739  }
740  }
741 
742  if (segDT.size() > 1) {
743  estimatePtDT(segDT, layersDT, thePt, theSpt);
744  ptEstimate.push_back(thePt);
745  sptEstimate.push_back(theSpt);
746  }
747 
748  /*
749  // not useful ....and pt estimation is bad
750  if ( segCSC.size() > 1 ) {
751  // don't estimate pt without ME1 information
752  bool CSCLayer1=false;
753  for (unsigned i=0; i< layersCSC.size(); i++) {
754  if ( layersCSC[i]==0 || layersCSC[i]==1 ) CSCLayer1 = true;
755  }
756  if (CSCLayer1) {
757  estimatePtCSC(segCSC, layersCSC, thePt, theSpt);
758  ptEstimate.push_back(thePt);
759  sptEstimate.push_back(theSpt);
760  }
761  }
762  */
763 
764  // Compute weighted average if have more than one estimator
765  if (!ptEstimate.empty())
766  weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
767 }
768 /*
769  *
770  * estimate Pt for single segment events
771  *
772  */
774  const std::vector<int>& layers,
775  double& thePt,
776  double& theSpt) {
777  thePt = defaultMomentum;
778  theSpt = defaultMomentum;
779 
780  GlobalPoint segPos = seg[0]->globalPosition();
781  double eta = segPos.eta();
782  GlobalVector gv = seg[0]->globalDirection();
783 
784  // Psi is angle between the segment origin and segment direction
785  // Use dot product between two vectors to get Psi in global x-y plane
786  double cosDpsi = (gv.x() * segPos.x() + gv.y() * segPos.y());
787  cosDpsi /= sqrt(segPos.x() * segPos.x() + segPos.y() * segPos.y());
788  cosDpsi /= sqrt(gv.x() * gv.x() + gv.y() * gv.y());
789 
790  double axb = (segPos.x() * gv.y()) - (segPos.y() * gv.x());
791  double sign = (axb < 0.) ? 1.0 : -1.0;
792 
793  double dpsi = fabs(acos(cosDpsi));
794  if (dpsi > 1.570796) {
795  dpsi = 3.141592 - dpsi;
796  sign = -1. * sign;
797  }
798  if (fabs(dpsi) < 0.00005) {
799  dpsi = 0.00005;
800  }
801 
802  // the 1st layer
803  if (layers[0] == -1) {
804  // MB10
805  if (fabs(eta) < 0.3) {
806  dpsi = scaledPhi(dpsi, SMB_10S[3]);
807  thePt = getPt(SMB10, eta, dpsi)[0];
808  theSpt = getPt(SMB10, eta, dpsi)[1];
809  }
810  // MB11
811  if (fabs(eta) >= 0.3 && fabs(eta) < 0.82) {
812  dpsi = scaledPhi(dpsi, SMB_11S[3]);
813  thePt = getPt(SMB11, eta, dpsi)[0];
814  theSpt = getPt(SMB11, eta, dpsi)[1];
815  }
816  // MB12
817  if (fabs(eta) >= 0.82 && fabs(eta) < 1.2) {
818  dpsi = scaledPhi(dpsi, SMB_12S[3]);
819  thePt = getPt(SMB12, eta, dpsi)[0];
820  theSpt = getPt(SMB12, eta, dpsi)[1];
821  }
822  }
823  if (layers[0] == 1) {
824  // ME13
825  if (fabs(eta) > 0.92 && fabs(eta) < 1.16) {
826  dpsi = scaledPhi(dpsi, SME_13S[3]);
827  thePt = getPt(SME13, eta, dpsi)[0];
828  theSpt = getPt(SME13, eta, dpsi)[1];
829  }
830  // ME12
831  if (fabs(eta) >= 1.16 && fabs(eta) <= 1.6) {
832  dpsi = scaledPhi(dpsi, SME_12S[3]);
833  thePt = getPt(SME12, eta, dpsi)[0];
834  theSpt = getPt(SME12, eta, dpsi)[1];
835  }
836  }
837  if (layers[0] == 0) {
838  // ME11
839  if (fabs(eta) > 1.6) {
840  dpsi = scaledPhi(dpsi, SMB_11S[3]);
841  thePt = getPt(SME11, eta, dpsi)[0];
842  theSpt = getPt(SME11, eta, dpsi)[1];
843  }
844  }
845  // the 2nd layer
846  if (layers[0] == -2) {
847  // MB20
848  if (fabs(eta) < 0.25) {
849  dpsi = scaledPhi(dpsi, SMB_20S[3]);
850  thePt = getPt(SMB20, eta, dpsi)[0];
851  theSpt = getPt(SMB20, eta, dpsi)[1];
852  }
853  // MB21
854  if (fabs(eta) >= 0.25 && fabs(eta) < 0.72) {
855  dpsi = scaledPhi(dpsi, SMB_21S[3]);
856  thePt = getPt(SMB21, eta, dpsi)[0];
857  theSpt = getPt(SMB21, eta, dpsi)[1];
858  }
859  // MB22
860  if (fabs(eta) >= 0.72 && fabs(eta) < 1.04) {
861  dpsi = scaledPhi(dpsi, SMB_22S[3]);
862  thePt = getPt(SMB22, eta, dpsi)[0];
863  theSpt = getPt(SMB22, eta, dpsi)[1];
864  }
865  }
866  if (layers[0] == 2) {
867  // ME22
868  if (fabs(eta) > 0.95 && fabs(eta) <= 1.6) {
869  dpsi = scaledPhi(dpsi, SME_22S[3]);
870  thePt = getPt(SME22, eta, dpsi)[0];
871  theSpt = getPt(SME22, eta, dpsi)[1];
872  }
873  // ME21
874  if (fabs(eta) > 1.6 && fabs(eta) < 2.45) {
875  dpsi = scaledPhi(dpsi, SME_21S[3]);
876  thePt = getPt(SME21, eta, dpsi)[0];
877  theSpt = getPt(SME21, eta, dpsi)[1];
878  }
879  }
880 
881  // the 3rd layer
882  if (layers[0] == -3) {
883  // MB30
884  if (fabs(eta) <= 0.22) {
885  dpsi = scaledPhi(dpsi, SMB_30S[3]);
886  thePt = getPt(SMB30, eta, dpsi)[0];
887  theSpt = getPt(SMB30, eta, dpsi)[1];
888  }
889  // MB31
890  if (fabs(eta) > 0.22 && fabs(eta) <= 0.6) {
891  dpsi = scaledPhi(dpsi, SMB_31S[3]);
892  thePt = getPt(SMB31, eta, dpsi)[0];
893  theSpt = getPt(SMB31, eta, dpsi)[1];
894  }
895  // MB32
896  if (fabs(eta) > 0.6 && fabs(eta) < 0.95) {
897  dpsi = scaledPhi(dpsi, SMB_32S[3]);
898  thePt = getPt(SMB32, eta, dpsi)[0];
899  theSpt = getPt(SMB32, eta, dpsi)[1];
900  }
901  }
902  thePt = fabs(thePt) * sign;
903  theSpt = fabs(theSpt);
904 
905  return;
906 }
907 
908 // setup the minimum value for obvious showering cases
909 void MuonSeedCreator::estimatePtShowering(int& NShowers, int& NShowerSegments, double& thePt, double& theSpt) {
910  if (NShowers > 2 && thePt < 300.) {
911  thePt = 800.;
912  theSpt = 200.;
913  }
914  if (NShowers == 2 && NShowerSegments > 11 && thePt < 150.) {
915  thePt = 280.;
916  theSpt = 70.;
917  }
918  if (NShowers == 2 && NShowerSegments <= 11 && thePt < 50.) {
919  thePt = 80.;
920  theSpt = 40.;
921  }
922  if (NShowers == 1 && NShowerSegments <= 5 && thePt < 10.) {
923  thePt = 16.;
924  theSpt = 8.;
925  }
926 }
927 
928 /*
929  * weightedPt
930  *
931  * Look at delta phi between segments to determine pt as:
932  * pt = (c_1 * eta + c_2) / dphi
933  */
934 void MuonSeedCreator::weightedPt(const std::vector<double>& ptEstimate,
935  const std::vector<double>& sptEstimate,
936  double& thePt,
937  double& theSpt) {
938  int size = ptEstimate.size();
939 
940  // If only one element, by-pass computation below
941  if (size < 2) {
942  thePt = ptEstimate[0];
943  theSpt = sptEstimate[0];
944  return;
945  }
946 
947  double charge = 0.;
948  // If have more than one pt estimator, first look if any estimator is biased
949  // by comparing the charge of each estimator
950 
951  for (unsigned j = 0; j < ptEstimate.size(); j++) {
952  //std::cout<<" weighting pt: "<< ptEstimate[j] <<std::endl;
953  if (ptEstimate[j] < 0.) {
954  // To prevent from blowing up, add 0.1
955  // weight by relative error on pt
956  charge -= 1. * (ptEstimate[j] * ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
957  } else {
958  // weight by relative error on pt
959  charge += 1. * (ptEstimate[j] * ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
960  }
961  }
962 
963  // No need to normalize as we want to know only sign ( + or - )
964  if (charge < 0.) {
965  charge = -1.;
966  } else {
967  charge = 1.;
968  }
969 
970  //int n = 0;
971  double weightPtSum = 0.;
972  double sigmaSqr_sum = 0.;
973 
974  // Now, we want to compute average Pt using estimators with "correct" charge
975  // This is to remove biases
976  for (unsigned j = 0; j < ptEstimate.size(); ++j) {
977  //if ( (minpt_ratio < 0.5) && (fabs(ptEstimate[j]) < 5.0) ) continue;
978  //if ( ptEstimate[j] * charge > 0. ) {
979  //n++;
980  sigmaSqr_sum += 1.0 / (sptEstimate[j] * sptEstimate[j]);
981  weightPtSum += fabs(ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
982  //}
983  }
984  /*
985  if (n < 1) {
986  thePt = defaultMomentum*charge;
987  theSpt = defaultMomentum;
988  return;
989  }
990  */
991  // Compute weighted mean and error
992 
993  thePt = (charge * weightPtSum) / sigmaSqr_sum;
994  theSpt = sqrt(1.0 / sigmaSqr_sum);
995 
996  //std::cout<<" final weighting : "<< thePt <<" ~ "<< fabs( theSpt/thePt ) <<std::endl;
997 
998  return;
999 }
1000 
1001 std::vector<double> MuonSeedCreator::getPt(const std::vector<double>& vPara, double eta, double dPhi) {
1002  double h = fabs(eta);
1003  double estPt = (vPara[0] + vPara[1] * h + vPara[2] * h * h) / dPhi;
1004  double estSPt = (vPara[3] + vPara[4] * h + vPara[5] * h * h) * estPt;
1005  std::vector<double> paraPt;
1006  paraPt.push_back(estPt);
1007  paraPt.push_back(estSPt);
1008 
1009  //std::cout<<" pt:"<<estPt<<" +/-"<< estSPt<<" h:"<<eta<<" df:"<<dPhi<<std::endl;
1010  return paraPt;
1011 }
1012 
1013 double MuonSeedCreator::scaledPhi(double dphi, double t1) {
1014  if (dphi != 0.) {
1015  double oPhi = 1. / dphi;
1016  dphi = dphi / (1. + t1 / (oPhi + 10.));
1017  return dphi;
1018 
1019  } else {
1020  return dphi;
1021  }
1022 }
std::vector< double > OL2213
size
Write out results.
std::vector< double > DT13_2
std::vector< double > SMB32
T perp() const
Definition: PV3DBase.h:69
std::vector< double > CSC23_1
std::vector< double > SMB_30S
std::vector< double > SMB_21S
std::vector< double > DT14_2
std::vector< double > DT23_2
std::vector< double > DT34_1
std::vector< double > DT14_1
std::vector< double > SME_22S
std::vector< double > SMB22
std::vector< double > OL1232
std::vector< double > DT34_2
std::vector< double > CSC24
void estimatePtDT(const SegmentContainer &seg, const std::vector< int > &layers, double &pt, double &spt)
Estimate transverse momentum of track from DT measurements.
void weightedPt(const std::vector< double > &ptEstimate, const std::vector< double > &sptEstimate, double &ptAvg, double &sptAvg)
Compute weighted mean pt from different pt estimators.
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
std::vector< double > CSC23_2
T eta() const
Definition: PV3DBase.h:73
std::vector< double > SMB20
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< double > CSC14
PTrajectoryStateOnDet persistentState(const TrajectoryStateOnSurface &ts, unsigned int detid)
std::vector< double > DT34
std::vector< double > CSC12_2
std::vector< double > CSC13_2
std::vector< double > CSC12_1
std::vector< double > SME12
std::vector< double > SME22
TrajectorySeed createSeed(int type, const SegmentContainer &seg, const std::vector< int > &layers, int NShower, int NShowerSeg)
Create a seed from set of segments.
MuonTransientTrackingRecHit::MuonRecHitContainer SegmentContainer
std::vector< double > SME21
void estimatePtOverlap(const SegmentContainer &seg, const std::vector< int > &layers, double &pt, double &spt)
Estimate transverse momentum of track from CSC + DT measurements.
std::vector< double > CSC13_3
MuonSeedCreator(const edm::ParameterSet &pset)
Constructor.
const MagneticField * BField
void estimatePtSingle(const SegmentContainer &seg, const std::vector< int > &layers, double &pt, double &spt)
Estimate transverse momentum of track from single segment.
std::vector< double > CSC34
void estimatePtCSC(const SegmentContainer &seg, const std::vector< int > &layers, double &pt, double &spt)
Estimate transverse momentum of track from CSC measurements.
std::vector< double > SME13
std::vector< double > DT13
std::vector< double > CSC12_3
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
void push_back(D *&d)
Definition: OwnVector.h:326
std::vector< double > SMB10
std::vector< double > CSC12
std::vector< double > DT12_2
std::vector< double > OL_1222
std::vector< double > OL1222
void estimatePtShowering(int &NShowers, int &NShowerSeg, double &pt, double &spt)
Estimate transverse momentum of track from showering segment.
T sqrt(T t)
Definition: SSEVec.h:23
std::vector< double > CSC23
std::vector< double > CSC13
std::vector< double > DT23_1
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
std::vector< double > SMB30
std::vector< double > SMB_10S
std::vector< double > DT24_2
std::vector< double > SMB_31S
std::vector< double > SMB_32S
std::vector< double > DT12_1
std::vector< double > CSC14_3
std::vector< double > DT12
std::vector< double > SMB_20S
std::vector< double > SMB_11S
std::vector< double > OL1213
std::vector< double > getPt(const std::vector< double > &vParameters, double eta, double dPhi)
Compute pt from parameters.
Definition: DetId.h:17
CLHEP::HepVector AlgebraicVector
std::vector< double > SMB12
std::vector< double > SME_21S
std::vector< double > SME_12S
std::vector< double > OL2222
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
std::vector< double > SME_11S
std::vector< double > DT14
std::vector< double > DT13_1
std::vector< double > SME31
std::vector< double > DT24
std::vector< double > OL_2213
std::vector< double > DT23
std::vector< double > SME32
std::vector< double > CSC24_1
std::vector< double > SMB21
CLHEP::HepSymMatrix AlgebraicSymMatrix
std::vector< double > CSC01_1
double scaledPhi(double dphi, double t1)
Scale the dPhi from segment position.
~MuonSeedCreator()
Destructor.
std::vector< double > SME_13S
std::vector< double > OL_2222
std::vector< double > SMB31
std::vector< double > CSC03
std::vector< double > CSC02
dh
Definition: cuy.py:354
std::vector< double > DT24_1
std::vector< double > CSC34_1
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
std::vector< double > SME11
std::vector< double > SMB11
std::vector< double > OL_1232
std::vector< double > SMB_12S
std::vector< double > SME41
Definition: QTest.h:565
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72
std::vector< double > OL_1213
std::vector< double > SMB_22S