CMS 3D CMS Logo

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