00001 #include "RecoMuon/MuonSeedGenerator/src/MuonSeedPtExtractor.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00004 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00005
00006 #include "TMath.h"
00007 #include <sstream>
00008
00009 MuonSeedPtExtractor::MuonSeedPtExtractor(const edm::ParameterSet& par)
00010 : theBeamSpot(0.,0.,0.),
00011 scaleDT_( par.getParameter<bool>("scaleDT") )
00012 {
00013 init(par);
00014 }
00015
00016
00017 void MuonSeedPtExtractor::init(const edm::ParameterSet& par)
00018 {
00019
00020
00021 fillParametersForCombo("DT_12", par);
00022 fillParametersForCombo("DT_13", par);
00023 fillParametersForCombo("DT_14", par);
00024 fillParametersForCombo("DT_23", par);
00025 fillParametersForCombo("DT_24", par);
00026 fillParametersForCombo("DT_34", par);
00027
00028 fillParametersForCombo("CSC_01", par);
00029 fillParametersForCombo("CSC_12", par);
00030 fillParametersForCombo("CSC_02", par);
00031 fillParametersForCombo("CSC_13", par);
00032 fillParametersForCombo("CSC_03", par);
00033 fillParametersForCombo("CSC_14", par);
00034 fillParametersForCombo("CSC_23", par);
00035 fillParametersForCombo("CSC_24", par);
00036 fillParametersForCombo("CSC_34", par);
00037
00038
00039 fillParametersForCombo("OL_1213", par);
00040 fillParametersForCombo("OL_1222", par);
00041 fillParametersForCombo("OL_1232", par);
00042 fillParametersForCombo("OL_2213", par);
00043 fillParametersForCombo("OL_2222", par);
00044
00045
00046 fillParametersForCombo("SME_11", par);
00047 fillParametersForCombo("SME_12", par);
00048 fillParametersForCombo("SME_13", par);
00049 fillParametersForCombo("SME_21", par);
00050 fillParametersForCombo("SME_22", par);
00051 fillParametersForCombo("SME_31", par);
00052 fillParametersForCombo("SME_32", par);
00053 fillParametersForCombo("SME_41", par);
00054 fillParametersForCombo("SME_42", par);
00055
00056
00057 fillParametersForCombo("SMB_10", par);
00058 fillParametersForCombo("SMB_11", par);
00059 fillParametersForCombo("SMB_12", par);
00060 fillParametersForCombo("SMB_20", par);
00061 fillParametersForCombo("SMB_21", par);
00062 fillParametersForCombo("SMB_22", par);
00063 fillParametersForCombo("SMB_30", par);
00064 fillParametersForCombo("SMB_31", par);
00065 fillParametersForCombo("SMB_32", par);
00066
00067 fillScalesForCombo("CSC_01_1_scale", par);
00068 fillScalesForCombo("CSC_12_1_scale", par);
00069 fillScalesForCombo("CSC_12_2_scale", par);
00070 fillScalesForCombo("CSC_12_3_scale", par);
00071 fillScalesForCombo("CSC_13_2_scale", par);
00072 fillScalesForCombo("CSC_13_3_scale", par);
00073 fillScalesForCombo("CSC_14_3_scale", par);
00074 fillScalesForCombo("CSC_23_1_scale", par);
00075 fillScalesForCombo("CSC_23_2_scale", par);
00076 fillScalesForCombo("CSC_24_1_scale", par);
00077 fillScalesForCombo("CSC_34_1_scale", par);
00078 fillScalesForCombo("DT_12_1_scale", par);
00079 fillScalesForCombo("DT_12_2_scale", par);
00080 fillScalesForCombo("DT_13_1_scale", par);
00081 fillScalesForCombo("DT_13_2_scale", par);
00082 fillScalesForCombo("DT_14_1_scale", par);
00083 fillScalesForCombo("DT_14_2_scale", par);
00084 fillScalesForCombo("DT_23_1_scale", par);
00085 fillScalesForCombo("DT_23_2_scale", par);
00086 fillScalesForCombo("DT_24_1_scale", par);
00087 fillScalesForCombo("DT_24_2_scale", par);
00088 fillScalesForCombo("DT_34_1_scale", par);
00089 fillScalesForCombo("DT_34_2_scale", par);
00090 fillScalesForCombo("OL_1213_0_scale", par);
00091 fillScalesForCombo("OL_1222_0_scale", par);
00092 fillScalesForCombo("OL_1232_0_scale", par);
00093 fillScalesForCombo("OL_2213_0_scale", par);
00094 fillScalesForCombo("OL_2222_0_scale", par);
00095 fillScalesForCombo("SMB_10_0_scale", par);
00096 fillScalesForCombo("SMB_11_0_scale", par);
00097 fillScalesForCombo("SMB_12_0_scale", par);
00098 fillScalesForCombo("SMB_20_0_scale", par);
00099 fillScalesForCombo("SMB_21_0_scale", par);
00100 fillScalesForCombo("SMB_22_0_scale", par);
00101 fillScalesForCombo("SMB_30_0_scale", par);
00102 fillScalesForCombo("SMB_31_0_scale", par);
00103 fillScalesForCombo("SMB_32_0_scale", par);
00104 fillScalesForCombo("SME_11_0_scale", par);
00105 fillScalesForCombo("SME_12_0_scale", par);
00106 fillScalesForCombo("SME_13_0_scale", par);
00107 fillScalesForCombo("SME_21_0_scale", par);
00108 fillScalesForCombo("SME_22_0_scale", par);
00109
00110 }
00111
00112
00113 MuonSeedPtExtractor::~MuonSeedPtExtractor(){
00114 }
00115
00116
00117 void MuonSeedPtExtractor::fillParametersForCombo(const std::string & name, const edm::ParameterSet & pset)
00118 {
00119 theParametersForCombo[name] = pset.getParameter<std::vector<double> >(name);
00120 }
00121
00122
00123 void MuonSeedPtExtractor::fillScalesForCombo(const std::string & name, const edm::ParameterSet & pset)
00124 {
00125 theScalesForCombo[name] = pset.getParameter<std::vector<double> >(name);
00126 }
00127
00128
00129 std::vector<double> MuonSeedPtExtractor::pT_extract(MuonTransientTrackingRecHit::ConstMuonRecHitPointer firstHit,
00130 MuonTransientTrackingRecHit::ConstMuonRecHitPointer secondHit) const
00131 {
00132 GlobalPoint innerPoint = firstHit->globalPosition() - theBeamSpot;
00133 GlobalPoint outerPoint = secondHit->globalPosition() - theBeamSpot;
00134 MuonTransientTrackingRecHit::ConstMuonRecHitPointer innerHit = firstHit;
00135 MuonTransientTrackingRecHit::ConstMuonRecHitPointer outerHit = secondHit;
00136
00137
00138 if( (outerHit->isDT() && innerHit->isCSC())
00139 || (outerHit->isDT() && innerHit->isDT() && (innerPoint.perp() > outerPoint.perp()))
00140 || (outerHit->isCSC() && innerHit->isCSC() && (fabs(innerPoint.z()) > fabs(outerPoint.z()))) )
00141 {
00142 innerHit = secondHit;
00143 outerHit = firstHit;
00144 innerPoint = innerHit->globalPosition() - theBeamSpot;
00145 outerPoint = outerHit->globalPosition() - theBeamSpot;
00146 }
00147
00148 double phiInner = innerPoint.phi();
00149 double phiOuter = outerPoint.phi();
00150
00151 double etaInner = innerPoint.eta();
00152 double etaOuter = outerPoint.eta();
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 double dPhi = phiInner - phiOuter;
00170 if(dPhi < -TMath::Pi()){
00171 dPhi += 2*TMath::Pi();
00172 }
00173 else if(dPhi > TMath::Pi()){
00174 dPhi -= 2*TMath::Pi();
00175 }
00176 int sign = 1;
00177 if ( dPhi< 0.) {
00178 dPhi = -dPhi;
00179 sign = -1;
00180 }
00181
00182 if (dPhi < 1.0e-6){
00183 dPhi = 1.0e-6;
00184 }
00185 double eta = fabs(etaOuter);
00186
00187
00188 std::vector <int> stationCoded(2);
00189 stationCoded[0] = stationCoded[1] = 999;
00190
00191 DetId detId_inner = innerHit->hit()->geographicalId();
00192 DetId detId_outer = outerHit->hit()->geographicalId();
00193
00194 stationCoded[0] = stationCode(innerHit);
00195 stationCoded[1] = stationCode(outerHit);
00196
00197 std::ostringstream os0 ;
00198 std::ostringstream os1 ;
00199 os0 << abs(stationCoded[0]);
00200 os1 << abs(stationCoded[1]);
00201
00202
00203
00204 std::string combination = "0";
00205 std::string init_combination = combination;
00206 bool singleSegment = false;
00207
00208 if( stationCoded[0] == stationCoded[1]){
00209
00210 singleSegment = true;
00211
00212 GlobalVector gv = innerHit->globalDirection();
00213 double gvPerpPos = gv.x()*gv.x() + gv.y()*gv.y();
00214 if (gvPerpPos < 1e-32) gvPerpPos = 1e-32; gvPerpPos=sqrt(gvPerpPos);
00215
00216
00217 double cosDpsi = (gv.x()*innerPoint.x() + gv.y()*innerPoint.y());
00218 if (cosDpsi!=0){
00219 cosDpsi /= sqrt(innerPoint.x()*innerPoint.x() + innerPoint.y()*innerPoint.y());
00220 cosDpsi /= gvPerpPos;
00221 cosDpsi = cosDpsi > 1 ? 1 : cosDpsi;
00222 cosDpsi = cosDpsi < -1 ? -1 : cosDpsi;
00223 }
00224
00225 double axb = ( innerPoint.x()*gv.y() ) - ( innerPoint.y()*gv.x() ) ;
00226 sign = (axb < 0.) ? 1 : -1;
00227
00228 double dpsi = fabs(acos(cosDpsi)) ;
00229 if ( dpsi > TMath::Pi()/2.) {
00230 dpsi = TMath::Pi() - dpsi;
00231 }
00232 if (fabs(dpsi) < 0.00005) {
00233 dpsi = 0.00005;
00234 }
00235 dPhi = dpsi;
00236
00237 if(innerHit->isDT())
00238 {
00239 DTChamberId dtCh(detId_inner);
00240 std::ostringstream os;
00241 os << dtCh.station() << abs(dtCh.wheel());
00242 combination = "SMB_"+os.str();
00243 }
00244 else if(innerHit->isCSC())
00245 {
00246 CSCDetId cscId(detId_inner);
00247 std::ostringstream os;
00248 int ring = cscId.ring();
00249 if(ring == 4) ring = 1;
00250 os << cscId.station() << ring;
00251 combination = "SME_"+os.str();
00252 }
00253 else
00254 {
00255 throw cms::Exception("MuonSeedPtExtractor") << "Bad hit DetId";
00256 }
00257 }
00258 else{
00259 if(stationCoded[0]<0){
00260 if(stationCoded[1]<0){
00261
00262 combination = "DT_" + os0.str() + os1.str();
00263 }
00264 else{
00265
00266 eta = fabs(etaInner);
00267 if(-1==stationCoded[0]){
00268 switch (stationCoded[1]){
00269 case 1:
00270 combination = "OL_1213";
00271 break;
00272 case 2:
00273 combination = "OL_1222";
00274 break;
00275 case 3:
00276 combination = "OL_1232";
00277 break;
00278 default:
00279
00280 break;
00281 }
00282 }
00283 else if (-2==stationCoded[0]){
00284 if(1==stationCoded[1]){
00285 combination = "OL_2213";
00286 }
00287 else{
00288
00289 combination = "OL_2222";
00290 }
00291 }
00292 else{
00293
00294 }
00295 }
00296 }
00297 else{
00298 if(stationCoded[1]<0){
00299
00300
00301 }
00302 else{
00303
00304 combination = "CSC_" + os0.str() + os1.str();
00305 if("CSC_04" == combination){
00306 combination = "CSC_14";
00307 }
00308 }
00309 }
00310 }
00311
00312 std::vector<double> pTestimate(2);
00313
00314 if(init_combination!=combination){
00315
00316 ParametersMap::const_iterator parametersItr = theParametersForCombo.find(combination);
00317 if(parametersItr == theParametersForCombo.end()) {
00318
00319 edm::LogWarning("BadSegmentCombination") << "Cannot find parameters for combo " << combination;
00320 pTestimate[0] = pTestimate[1] = 100;
00321
00322 } else {
00323
00324 if(scaleDT_ && outerHit->isDT() )
00325 {
00326 pTestimate = getPt(parametersItr->second, eta, dPhi, combination, detId_outer);
00327 }
00328 else
00329 {
00330 pTestimate = getPt(parametersItr->second, eta, dPhi);
00331 }
00332
00333 if(singleSegment){
00334 pTestimate[0] = fabs(pTestimate[0]);
00335 pTestimate[1] = fabs(pTestimate[1]);
00336 }
00337 pTestimate[0] *= double(sign);
00338 }
00339 }
00340 else{
00341
00342 pTestimate[0] = pTestimate[1] = 100;
00343
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 return pTestimate;
00356 }
00357
00358
00359 int MuonSeedPtExtractor::stationCode(MuonTransientTrackingRecHit::ConstMuonRecHitPointer hit) const
00360 {
00361 DetId detId(hit->hit()->geographicalId());
00362 int result = -999;
00363 if(hit->isDT() ){
00364 DTChamberId dtCh(detId);
00365
00366 result = -1 * dtCh.station();
00367 }
00368 else if( hit->isCSC() ){
00369 CSCDetId cscID(detId);
00370
00371 result = cscID.station();
00372 if(result == 1 && (1 == cscID.ring() || 4 == cscID.ring()) )
00373 result = 0;
00374 }
00375 else if(hit->isRPC()){
00376 }
00377 return result;
00378 }
00379
00380
00381 std::vector<double> MuonSeedPtExtractor::getPt(const std::vector<double> & vPara, double eta, double dPhi ) const {
00382
00383 double h = fabs(eta);
00384 double estPt = ( vPara[0] + vPara[1]*h + vPara[2]*h*h ) / dPhi;
00385 double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) / dPhi;
00386
00387 std::vector<double> paraPt ;
00388 paraPt.push_back( estPt );
00389 paraPt.push_back( estSPt ) ;
00390 return paraPt ;
00391 }
00392
00393
00394 std::vector<double> MuonSeedPtExtractor::getPt(const std::vector<double> & vPara, double eta, double dPhi,
00395 const std::string & combination, const DTChamberId & outerDetId ) const {
00396 double h = fabs(eta);
00397 double estPt = ( vPara[0] + vPara[1]*h + vPara[2]*h*h ) / dPhi;
00398
00399 double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) / dPhi;
00400
00401
00402 int wheel = 0;
00403 if(combination[0] == 'D') {
00404 wheel = abs(outerDetId.wheel());
00405 }
00406
00407 std::ostringstream os;
00408 os << combination << "_" << wheel << "_scale";
00409
00410 ScalesMap::const_iterator scalesItr = theScalesForCombo.find(os.str());
00411 if ( scalesItr != theScalesForCombo.end()) {
00412 double t1 = scalesItr->second[0];
00413 double scaleFactor = 1./( 1. + t1/( estPt + 10. ) ) ;
00414
00415 estSPt = estSPt * scaleFactor ;
00416 estPt = estPt * scaleFactor ;
00417 }
00418
00419
00420 std::vector<double> paraPt ;
00421 paraPt.push_back( estPt );
00422 paraPt.push_back( estSPt ) ;
00423 return paraPt ;
00424 }
00425