CMS 3D CMS Logo

MuonSeedPtExtractor.cc
Go to the documentation of this file.
6 
7 #include "TMath.h"
8 #include <sstream>
9 
11 : theBeamSpot(0.,0.,0.),
12  scaleDT_( par.getParameter<bool>("scaleDT") )
13 {
14  init(par);
15 }
16 
17 
19 {
20  // load pT seed parameters
21  // DT combinations
22  fillParametersForCombo("DT_12", par);
23  fillParametersForCombo("DT_13", par);
24  fillParametersForCombo("DT_14", par);
25  fillParametersForCombo("DT_23", par);
26  fillParametersForCombo("DT_24", par);
27  fillParametersForCombo("DT_34", par);
28  // CSC combinations
29  fillParametersForCombo("CSC_01", par);
30  fillParametersForCombo("CSC_12", par);
31  fillParametersForCombo("CSC_02", par);
32  fillParametersForCombo("CSC_13", par);
33  fillParametersForCombo("CSC_03", par);
34  fillParametersForCombo("CSC_14", par);
35  fillParametersForCombo("CSC_23", par);
36  fillParametersForCombo("CSC_24", par);
37  fillParametersForCombo("CSC_34", par);
38 
39  // Overlap combinations
40  fillParametersForCombo("OL_1213", par);
41  fillParametersForCombo("OL_1222", par);
42  fillParametersForCombo("OL_1232", par);
43  fillParametersForCombo("OL_2213", par);
44  fillParametersForCombo("OL_2222", par);
45 
46  // Single segments (CSC)
47  fillParametersForCombo("SME_11", par);
48  fillParametersForCombo("SME_12", par);
49  fillParametersForCombo("SME_13", par);
50  fillParametersForCombo("SME_21", par);
51  fillParametersForCombo("SME_22", par);
52  fillParametersForCombo("SME_31", par);
53  fillParametersForCombo("SME_32", par);
54  fillParametersForCombo("SME_41", par);
55  fillParametersForCombo("SME_42", par);
56 
57  // Single segments (DT)
58  fillParametersForCombo("SMB_10", par);
59  fillParametersForCombo("SMB_11", par);
60  fillParametersForCombo("SMB_12", par);
61  fillParametersForCombo("SMB_20", par);
62  fillParametersForCombo("SMB_21", par);
63  fillParametersForCombo("SMB_22", par);
64  fillParametersForCombo("SMB_30", par);
65  fillParametersForCombo("SMB_31", par);
66  fillParametersForCombo("SMB_32", par);
67 
68  fillScalesForCombo("CSC_01_1_scale", par);
69  fillScalesForCombo("CSC_12_1_scale", par);
70  fillScalesForCombo("CSC_12_2_scale", par);
71  fillScalesForCombo("CSC_12_3_scale", par);
72  fillScalesForCombo("CSC_13_2_scale", par);
73  fillScalesForCombo("CSC_13_3_scale", par);
74  fillScalesForCombo("CSC_14_3_scale", par);
75  fillScalesForCombo("CSC_23_1_scale", par);
76  fillScalesForCombo("CSC_23_2_scale", par);
77  fillScalesForCombo("CSC_24_1_scale", par);
78  fillScalesForCombo("CSC_34_1_scale", par);
79  fillScalesForCombo("DT_12_1_scale", par);
80  fillScalesForCombo("DT_12_2_scale", par);
81  fillScalesForCombo("DT_13_1_scale", par);
82  fillScalesForCombo("DT_13_2_scale", par);
83  fillScalesForCombo("DT_14_1_scale", par);
84  fillScalesForCombo("DT_14_2_scale", par);
85  fillScalesForCombo("DT_23_1_scale", par);
86  fillScalesForCombo("DT_23_2_scale", par);
87  fillScalesForCombo("DT_24_1_scale", par);
88  fillScalesForCombo("DT_24_2_scale", par);
89  fillScalesForCombo("DT_34_1_scale", par);
90  fillScalesForCombo("DT_34_2_scale", par);
91  fillScalesForCombo("OL_1213_0_scale", par);
92  fillScalesForCombo("OL_1222_0_scale", par);
93  fillScalesForCombo("OL_1232_0_scale", par);
94  fillScalesForCombo("OL_2213_0_scale", par);
95  fillScalesForCombo("OL_2222_0_scale", par);
96  fillScalesForCombo("SMB_10_0_scale", par);
97  fillScalesForCombo("SMB_11_0_scale", par);
98  fillScalesForCombo("SMB_12_0_scale", par);
99  fillScalesForCombo("SMB_20_0_scale", par);
100  fillScalesForCombo("SMB_21_0_scale", par);
101  fillScalesForCombo("SMB_22_0_scale", par);
102  fillScalesForCombo("SMB_30_0_scale", par);
103  fillScalesForCombo("SMB_31_0_scale", par);
104  fillScalesForCombo("SMB_32_0_scale", par);
105  fillScalesForCombo("SME_11_0_scale", par);
106  fillScalesForCombo("SME_12_0_scale", par);
107  fillScalesForCombo("SME_13_0_scale", par);
108  fillScalesForCombo("SME_21_0_scale", par);
109  fillScalesForCombo("SME_22_0_scale", par);
110 
111 }
112 
113 
115 }
116 
117 
119 {
120  theParametersForCombo[name] = pset.getParameter<std::vector<double> >(name);
121 }
122 
123 
125 {
126  theScalesForCombo[name] = pset.getParameter<std::vector<double> >(name);
127 }
128 
129 
132 {
133  GlobalPoint innerPoint = firstHit->globalPosition() - theBeamSpot;
134  GlobalPoint outerPoint = secondHit->globalPosition() - theBeamSpot;
137 
138  // ways in which the hits could be in the wrong order
139  if( (outerHit->isDT() && innerHit->isCSC())
140  || (outerHit->isDT() && innerHit->isDT() && (innerPoint.perp() > outerPoint.perp()))
141  || (outerHit->isCSC() && innerHit->isCSC() && (fabs(innerPoint.z()) > fabs(outerPoint.z()))) )
142  {
143  innerHit = secondHit;
144  outerHit = firstHit;
145  innerPoint = innerHit->globalPosition() - theBeamSpot;
146  outerPoint = outerHit->globalPosition() - theBeamSpot;
147  }
148 
149  double phiInner = innerPoint.phi();
150  double phiOuter = outerPoint.phi();
151 
152  double etaInner = innerPoint.eta();
153  double etaOuter = outerPoint.eta();
154  //std::cout<<" inner pos = "<< innerPoint << " phi eta " << phiInner << " " << etaInner << std::endl;
155  //std::cout<<" outer pos = "<< outerPoint << " phi eta " << phiOuter << " " << etaOuter << std::endl;
156  //double thetaInner = firstHit->globalPosition().theta();
157  // if some of the segments is missing r-phi measurement then we should
158  // use only the 4D phi estimate (also use 4D eta estimate only)
159  // the direction is not so important (it will be corrected)
160  /*
161  bool firstOK = (4==allValidSets[iSet][firstMeasurement]->hit->dimension());
162  bool lastOK = (4==allValidSets[iSet][lastMeasurement]->hit->dimension());
163  if(!(firstOK * lastOK)){
164  if(!firstOK){
165  }
166  if(!firstOK){
167  }
168  }
169  */
170  double dPhi = phiInner - phiOuter;
171  if(dPhi < -TMath::Pi()){
172  dPhi += 2*TMath::Pi();
173  }
174  else if(dPhi > TMath::Pi()){
175  dPhi -= 2*TMath::Pi();
176  }
177  int sign = 1;
178  if ( dPhi< 0.) {
179  dPhi = -dPhi;
180  sign = -1;
181  }
182 
183  if (dPhi < 1.0e-6){
184  dPhi = 1.0e-6;
185  }
186  double eta = fabs(etaOuter);// what if it is 2D segment? use inner?
187 
188 
189  std::vector <int> stationCoded(2);
190  stationCoded[0] = stationCoded[1] = 999;
191 
192  DetId detId_inner = innerHit->hit()->geographicalId();
193  DetId detId_outer = outerHit->hit()->geographicalId();
194 
195  stationCoded[0] = stationCode(innerHit);
196  stationCoded[1] = stationCode(outerHit);
197 
198  std::ostringstream os0 ;
199  std::ostringstream os1 ;
200  os0 << abs(stationCoded[0]);
201  os1 << abs(stationCoded[1]);
202 
203  //std::cout<<" st1 = "<<stationCoded[0]<<" st2 = "<<stationCoded[1]<<std::endl;
204  //std::cout<<" detId_inner = "<<detId_inner.rawId()<<" detId_outer = "<< detId_outer.rawId()<<std::endl;
205  std::string combination = "0";
206  std::string init_combination = combination;
207  bool singleSegment = false;
208  //if(detId_first == detId_second){
209  if( stationCoded[0] == stationCoded[1]){
210  // single segment - DT or CSC
211  singleSegment = true;
212  //eta = innerPoint.eta();
213  GlobalVector gv = innerHit->globalDirection();
214  double gvPerpPos = gv.x()*gv.x() + gv.y()*gv.y();
215  if (gvPerpPos < 1e-32) gvPerpPos = 1e-32;
216  gvPerpPos=sqrt(gvPerpPos);
217  // Psi is angle between the segment origin and segment direction
218  // Use dot product between two vectors to get Psi in global x-y plane
219  double cosDpsi = (gv.x()*innerPoint.x() + gv.y()*innerPoint.y());
220  if (cosDpsi!=0){
221  cosDpsi /= sqrt(innerPoint.x()*innerPoint.x() + innerPoint.y()*innerPoint.y());
222  cosDpsi /= gvPerpPos;
223  cosDpsi = cosDpsi > 1 ? 1 : cosDpsi;
224  cosDpsi = cosDpsi < -1 ? -1 : cosDpsi;
225  }
226 
227  double axb = ( innerPoint.x()*gv.y() ) - ( innerPoint.y()*gv.x() ) ;
228  sign = (axb < 0.) ? 1 : -1;
229 
230  double dpsi = fabs(acos(cosDpsi)) ;
231  if ( dpsi > TMath::Pi()/2.) {
232  dpsi = TMath::Pi() - dpsi;
233  }
234  if (fabs(dpsi) < 0.00005) {
235  dpsi = 0.00005;
236  }
237  dPhi = dpsi;
238 
239  if(innerHit->isDT())
240  {
241  DTChamberId dtCh(detId_inner);
242  std::ostringstream os;
243  os << dtCh.station() << abs(dtCh.wheel());
244  combination = "SMB_"+os.str();
245  }
246  else if(innerHit->isCSC())
247  {
248  CSCDetId cscId(detId_inner);
249  std::ostringstream os;
250  int ring = cscId.ring();
251  if(ring == 4) ring = 1;
252  os << cscId.station() << ring;
253  combination = "SME_"+os.str();
254  }
255  else if(innerHit->isME0())
256  {
257  ME0DetId me0Id(detId_inner);
258  std::ostringstream os;
259  int ring = 1;//me0Id.ring(); me0 only in ring 1
260  os << me0Id.station() << ring;
261  combination = "SME_"+os.str();
262  }
263  else
264  {
265  throw cms::Exception("MuonSeedPtExtractor") << "Bad hit DetId";
266  }
267  }
268  else{
269  if(stationCoded[0]<0){
270  if(stationCoded[1]<0){
271  // DT-DT
272  combination = "DT_" + os0.str() + os1.str();
273  }
274  else{
275  // DT-CSC
276  eta = fabs(etaInner);
277  if(-1==stationCoded[0]){
278  switch (stationCoded[1]){
279  case 1:
280  combination = "OL_1213";
281  break;
282  case 2:
283  combination = "OL_1222";
284  break;
285  case 3:
286  combination = "OL_1232";
287  break;
288  default:
289  // can not be
290  break;
291  }
292  }
293  else if (-2==stationCoded[0]){
294  if(1==stationCoded[1]){
295  combination = "OL_2213";
296  }
297  else{
298  // can not be (not coded?)
299  combination = "OL_2222";// in case
300  }
301  }
302  else{
303  // can not be
304  }
305  }
306  }
307  else{
308  if(stationCoded[1]<0){
309  // CSC-DT
310  // can not be
311  }
312  else{
313  // CSC-CSC
314  combination = "CSC_" + os0.str() + os1.str();
315  if("CSC_04" == combination){
316  combination = "CSC_14";
317  }
318  }
319  }
320  }
321 
322  std::vector<double> pTestimate(2);//
323  //std::cout<<" combination = "<<combination<<std::endl;
324  if(init_combination!=combination){
325  //std::cout<<" combination = "<<combination<<" eta = "<<eta<<" dPhi = "<<dPhi<<std::endl;
326  ParametersMap::const_iterator parametersItr = theParametersForCombo.find(combination);
327  if(parametersItr == theParametersForCombo.end()) {
328  // edm::LogWarning("RecoMuon|MuonSeedGenerator|MuonSeedPtExtractor") << "Cannot find parameters for combo " << combination;
329  edm::LogWarning("BadSegmentCombination") << "Cannot find parameters for combo " << combination;
330  pTestimate[0] = pTestimate[1] = 100;
331  // throw cms::Exception("MuonSeedPtEstimator") << "Cannot find parameters for combo " << combination;
332  } else {
333 
334  if(scaleDT_ && outerHit->isDT() )
335  {
336  pTestimate = getPt(parametersItr->second, eta, dPhi, combination, detId_outer);
337  }
338  else
339  {
340  pTestimate = getPt(parametersItr->second, eta, dPhi);
341  }
342 
343  if(singleSegment){
344  pTestimate[0] = fabs(pTestimate[0]);
345  pTestimate[1] = fabs(pTestimate[1]);
346  }
347  pTestimate[0] *= double(sign);
348  }
349  }
350  else{
351  // often a MB3 - ME1/3 seed
352  pTestimate[0] = pTestimate[1] = 100;
353  // hmm
354  }
355  // std::cout<<" pTestimate[0] = "<<pTestimate[0]<<" pTestimate[1] = "<<pTestimate[1]<<std::endl;
356  /*
357  MuonRecHitContainer_clusters[cluster][iHit+1]->isDT());
358  if(specialCase){
359  DTChamberId dtCh(detId);
360  DTChamberId dtCh_2(detId_2);
361  specialCase = (dtCh.station() == dtCh_2.station());
362  }
363  */
364  //return vPara;
365  return pTestimate;
366 }
367 
368 
370 {
371  DetId detId(hit->hit()->geographicalId());
372  int result = -999;
373  if(hit->isDT() ){
374  DTChamberId dtCh(detId);
375  //std::cout<<"first (DT) St/W/S = "<<dtCh.station()<<"/"<<dtCh.wheel()<<"/"<<dtCh.sector()<<"/"<<std::endl;
376  result = -1 * dtCh.station();
377  }
378  else if( hit->isCSC() ){
379  CSCDetId cscID(detId);
380  //std::cout<<"first (CSC) E/S/R/C = "<<cscID.endcap()<<"/"<<cscID.station()<<"/"<<cscID.ring()<<"/"<<cscID.chamber()<<std::endl;
381  result = cscID.station();
382  if(result == 1 && (1 == cscID.ring() || 4 == cscID.ring()) )
383  result = 0;
384  }
385  else if( hit->isME0() ){
386  result = 0;
387  }
388  else if(hit->isRPC()){
389  }
390  return result;
391 }
392 
393 
394 std::vector<double> MuonSeedPtExtractor::getPt(const std::vector<double> & vPara, double eta, double dPhi ) const {
395  //std::cout<<" eta = "<<eta<<" dPhi = "<<dPhi<<" vPara[0] = "<<vPara[0]<<" vPara[1] = "<<vPara[1]<<" vPara[2] = "<<vPara[2]<<std::endl;
396  double h = fabs(eta);
397  double estPt = ( vPara[0] + vPara[1]*h + vPara[2]*h*h ) / dPhi;
398  double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) / dPhi;
399  // std::cout<<"estPt = "<<estPt<<std::endl;
400  std::vector<double> paraPt ;
401  paraPt.push_back( estPt );
402  paraPt.push_back( estSPt ) ;
403  return paraPt ;
404 }
405 
406 // combined pt parameterization and pt scale
407 std::vector<double> MuonSeedPtExtractor::getPt(const std::vector<double> & vPara, double eta, double dPhi,
408  const std::string & combination, const DTChamberId & outerDetId ) const {
409  double h = fabs(eta);
410  double estPt = ( vPara[0] + vPara[1]*h + vPara[2]*h*h ) / dPhi;
411  // changed by S.C.
412  double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) / dPhi;
413 
414  // scale the pt and spt , changed by S.C.
415  int wheel = 0;
416  if(combination[0] == 'D') {
417  wheel = abs(outerDetId.wheel());
418  }
419 
420  std::ostringstream os;
421  os << combination << "_" << wheel << "_scale";
422 
423  ScalesMap::const_iterator scalesItr = theScalesForCombo.find(os.str());
424  if ( scalesItr != theScalesForCombo.end()) {
425  double t1 = scalesItr->second[0];
426  double scaleFactor = 1./( 1. + t1/( estPt + 10. ) ) ;
427 
428  estSPt = estSPt * scaleFactor ;
429  estPt = estPt * scaleFactor ;
430  }
431 
432  // std::cout<<"estPt = "<<estPt<<std::endl;
433  std::vector<double> paraPt ;
434  paraPt.push_back( estPt );
435  paraPt.push_back( estSPt ) ;
436  return paraPt ;
437 }
438 
virtual ~MuonSeedPtExtractor()
Destructor.
const double Pi
T getParameter(std::string const &) const
T perp() const
Definition: PV3DBase.h:72
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
void fillParametersForCombo(const std::string &name, const edm::ParameterSet &pset)
Geom::Phi< T > phi() const
Definition: PV3DBase.h:69
T y() const
Definition: PV3DBase.h:63
void init(const edm::ParameterSet &par)
void fillScalesForCombo(const std::string &name, const edm::ParameterSet &pset)
int station() const
Definition: ME0DetId.h:76
T sqrt(T t)
Definition: SSEVec.h:18
T z() const
Definition: PV3DBase.h:64
int stationCode(MuonTransientTrackingRecHit::ConstMuonRecHitPointer hit) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int ring() const
Definition: CSCDetId.h:75
ParametersMap theParametersForCombo
Definition: DetId.h:18
T eta() const
Definition: PV3DBase.h:76
MuonSeedPtExtractor(const edm::ParameterSet &)
Constructor with Parameter set and MuonServiceProxy.
int station() const
Definition: CSCDetId.h:86
std::shared_ptr< MuonTransientTrackingRecHit const > ConstMuonRecHitPointer
virtual std::vector< double > pT_extract(MuonTransientTrackingRecHit::ConstMuonRecHitPointer firstHit, MuonTransientTrackingRecHit::ConstMuonRecHitPointer secondHit) const
int station() const
Return the station number.
Definition: DTChamberId.h:51
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:45
T x() const
Definition: PV3DBase.h:62
std::vector< double > getPt(const std::vector< double > &vPara, double eta, double dPhi) const