CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoMuon/MuonSeedGenerator/src/MuonSeedPtExtractor.cc

Go to the documentation of this file.
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   // load pT seed parameters
00020   // DT combinations
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   // CSC combinations
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   // Overlap combinations
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   // Single segments (CSC)
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   // Single segments (DT)
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   // ways in which the hits could be in the wrong order
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   //std::cout<<" inner pos = "<< innerPoint << " phi eta " << phiInner << " " << etaInner << std::endl;
00154   //std::cout<<" outer pos = "<< outerPoint << " phi eta " << phiOuter << " " << etaOuter << std::endl;
00155   //double thetaInner = firstHit->globalPosition().theta();
00156   // if some of the segments is missing r-phi measurement then we should
00157   // use only the 4D phi estimate (also use 4D eta estimate only)
00158   // the direction is not so important (it will be corrected) 
00159   /*
00160     bool firstOK = (4==allValidSets[iSet][firstMeasurement]->hit->dimension());
00161     bool lastOK = (4==allValidSets[iSet][lastMeasurement]->hit->dimension());
00162     if(!(firstOK * lastOK)){
00163     if(!firstOK){
00164     }
00165     if(!firstOK){
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);// what if it is 2D segment? use inner?
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   //std::cout<<" st1 = "<<stationCoded[0]<<" st2 = "<<stationCoded[1]<<std::endl;
00203   //std::cout<<" detId_inner = "<<detId_inner.rawId()<<"  detId_outer = "<< detId_outer.rawId()<<std::endl;
00204   std::string  combination = "0";
00205   std::string init_combination = combination;
00206   bool singleSegment = false;
00207   //if(detId_first == detId_second){
00208   if( stationCoded[0] == stationCoded[1]){
00209     // single segment - DT or CSC
00210     singleSegment = true;
00211     //eta = innerPoint.eta();
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     // Psi is angle between the segment origin and segment direction
00216     // Use dot product between two vectors to get Psi in global x-y plane
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         // DT-DT
00262         combination = "DT_" + os0.str() + os1.str();
00263       }
00264       else{
00265         // DT-CSC
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             // can not be 
00280             break;
00281           }
00282         }
00283         else if (-2==stationCoded[0]){
00284           if(1==stationCoded[1]){
00285             combination = "OL_2213";
00286           }
00287           else{
00288             // can not be (not coded?)
00289             combination = "OL_2222";// in case
00290           }
00291         }
00292         else{
00293           // can not be
00294         }
00295       }
00296     }
00297     else{
00298       if(stationCoded[1]<0){
00299         // CSC-DT
00300         // can not be
00301       }
00302       else{
00303         // CSC-CSC
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   //std::cout<<" combination = "<<combination<<std::endl;
00314   if(init_combination!=combination){
00315         //std::cout<<" combination = "<<combination<<" eta = "<<eta<<" dPhi = "<<dPhi<<std::endl;
00316     ParametersMap::const_iterator parametersItr = theParametersForCombo.find(combination);
00317     if(parametersItr == theParametersForCombo.end()) {
00318       //      edm::LogWarning("RecoMuon|MuonSeedGenerator|MuonSeedPtExtractor") << "Cannot find parameters for combo " << combination;
00319       edm::LogWarning("BadSegmentCombination") << "Cannot find parameters for combo " << combination;
00320       pTestimate[0] = pTestimate[1] = 100;
00321       //       throw cms::Exception("MuonSeedPtEstimator") << "Cannot find parameters for combo " << combination;
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     // often a MB3 - ME1/3 seed
00342     pTestimate[0] = pTestimate[1] = 100;
00343     // hmm
00344   }
00345   // std::cout<<" pTestimate[0] = "<<pTestimate[0]<<" pTestimate[1] = "<<pTestimate[1]<<std::endl;
00346   /*
00347                               MuonRecHitContainer_clusters[cluster][iHit+1]->isDT());
00348           if(specialCase){
00349             DTChamberId dtCh(detId);
00350             DTChamberId dtCh_2(detId_2);
00351             specialCase =  (dtCh.station() == dtCh_2.station());
00352           }
00353   */
00354   //return vPara;
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     //std::cout<<"first (DT) St/W/S = "<<dtCh.station()<<"/"<<dtCh.wheel()<<"/"<<dtCh.sector()<<"/"<<std::endl;
00366     result = -1 * dtCh.station();
00367   }
00368   else if( hit->isCSC() ){
00369     CSCDetId cscID(detId);
00370     //std::cout<<"first (CSC) E/S/R/C = "<<cscID.endcap()<<"/"<<cscID.station()<<"/"<<cscID.ring()<<"/"<<cscID.chamber()<<std::endl;
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    //std::cout<<" eta = "<<eta<<" dPhi = "<<dPhi<<" vPara[0] = "<<vPara[0]<<" vPara[1] = "<<vPara[1]<<" vPara[2] = "<<vPara[2]<<std::endl;
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   // std::cout<<"estPt = "<<estPt<<std::endl;
00387   std::vector<double> paraPt ;
00388   paraPt.push_back( estPt );
00389   paraPt.push_back( estSPt ) ;
00390   return paraPt ;
00391 }
00392 
00393 // combined pt parameterization and pt scale 
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   // changed by S.C.
00399   double estSPt = ( vPara[3] + vPara[4]*h + vPara[5]*h*h ) / dPhi;
00400 
00401   // scale the pt and spt , changed by S.C.
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   // std::cout<<"estPt = "<<estPt<<std::endl;
00420   std::vector<double> paraPt ;
00421   paraPt.push_back( estPt );
00422   paraPt.push_back( estSPt ) ;
00423   return paraPt ;
00424 }
00425