CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoMuon/MuonSeedGenerator/src/MuonDTSeedFromRecHits.cc

Go to the documentation of this file.
00001 
00011 #include "RecoMuon/MuonSeedGenerator/src/MuonDTSeedFromRecHits.h"
00012 #include "RecoMuon/MuonSeedGenerator/src/MuonSeedPtExtractor.h"
00013 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00014 
00015 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
00016 
00017 #include "DataFormats/Common/interface/OwnVector.h"
00018 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00019 #include "DataFormats/Math/interface/deltaPhi.h"
00020 
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022 
00023 #include "gsl/gsl_statistics.h"
00024 
00025 using namespace std;
00026 
00027 
00028 
00029 MuonDTSeedFromRecHits::MuonDTSeedFromRecHits()
00030 : MuonSeedFromRecHits()
00031 {
00032 }
00033 
00034 
00035 TrajectorySeed MuonDTSeedFromRecHits::seed() const {
00036   double pt[16] = { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. };
00037   // these weights are supposed to be 1/sigma^2(pt), but they're so small.
00038   // Instead of the 0.2-0.5 GeV here, we'll add something extra in quadrature later
00039   double spt[8] = { 1/0.048 , 1/0.075 , 1/0.226 , 1/0.132 , 1/0.106 , 1/0.175 , 1/0.125 , 1/0.185 }; 
00040 
00041   const std::string metname = "Muon|RecoMuon|MuonDTSeedFromRecHits";
00042 
00044   computePtWithVtx(pt, spt);
00045 
00047   computePtWithoutVtx(pt, spt);
00048 
00049   // some dump...
00050   LogTrace(metname) << " Pt MB1 @vtx: " << pt[0] << " w: " << spt[0] << "\n" 
00051                     << " Pt MB2 @vtx: " << pt[1] << " w: " << spt[1]<< endl ;
00052   
00053   LogTrace(metname) << " Pt MB2-MB1 " << pt[2] << " w: " << spt[2]<< "\n" 
00054                     << " Pt MB3-MB1 " << pt[3] << " w: " << spt[3]<< "\n" 
00055                     << " Pt MB3-MB2 " << pt[4] << " w: " << spt[4]<< "\n" 
00056                     << " Pt MB4-MB1 " << pt[5] << " w: " << spt[5]<< "\n" 
00057                     << " Pt MB4-MB2 " << pt[6] << " w: " << spt[6]<< "\n" 
00058                     << " Pt MB4-MB3 " << pt[7] << " w: " << spt[7]<< endl  ;
00059   
00061   float ptmean=0.;
00062   float sptmean=0.;
00063   //@@ Use Shih-Chuan's
00064   computeBestPt(pt, spt, ptmean, sptmean);
00065   
00066   // add an extra term to the error in quadrature, 30% of pT per point
00067   int npoints = 0;
00068   for(int i = 0; i < 8; ++i)
00069     if(pt[i] != 0) ++npoints;
00070   if(npoints != 0) {
00071     sptmean = sqrt(sptmean*sptmean + 0.09*ptmean*ptmean/npoints);
00072   }
00073 
00074   LogTrace(metname) << " Seed Pt: " << ptmean << " +/- " << sptmean << endl;
00075   // take the best candidate
00076   ConstMuonRecHitPointer last = bestBarrelHit(theRhits);
00077   return createSeed(ptmean, sptmean,last);
00078 }
00079 
00080 
00081 MuonDTSeedFromRecHits::ConstMuonRecHitPointer 
00082 MuonDTSeedFromRecHits::bestBarrelHit(const MuonRecHitContainer & barrelHits) const {
00083 
00084   int alt_npt = 0;
00085   int best_npt = 0;
00086   int cur_npt = 0;
00087   MuonRecHitPointer best = 0;
00088   MuonRecHitPointer alter=0;
00089 
00090   for (MuonRecHitContainer::const_iterator iter=barrelHits.begin();
00091        iter!=barrelHits.end(); iter++ ) {
00092 
00093     bool hasZed = ((*iter)->projectionMatrix()[1][1]==1);
00094 
00095     cur_npt = 0;
00096     vector<TrackingRecHit*> slrhs=(*iter)->recHits();
00097     for (vector<TrackingRecHit*>::const_iterator slrh=slrhs.begin(); slrh!=slrhs.end(); ++slrh ) {
00098       cur_npt+=(*slrh)->recHits().size();
00099     }
00100     float radius1 = (*iter)->det()->position().perp();
00101 
00102     if (hasZed) {
00103       if ( cur_npt > best_npt ) {
00104         best = (*iter);
00105         best_npt = cur_npt;
00106       }
00107       else if ( best && cur_npt == best_npt ) {
00108         float radius2 = best->det()->position().perp();
00109        if (radius1 < radius2) {
00110           best = (*iter);
00111           best_npt = cur_npt;
00112        }
00113       }
00114     }
00115 
00116     if ( cur_npt > alt_npt ) {
00117       alter = (*iter);
00118       alt_npt = cur_npt;
00119     }
00120     else if ( alter && cur_npt == alt_npt ) {
00121       float radius2 = alter->det()->position().perp();
00122       if (radius1 < radius2) {
00123         alter = (*iter);
00124         alt_npt = cur_npt;
00125       }
00126     }
00127   }
00128 
00129   if ( !best ) best = alter;
00130 
00131   return best;
00132 }
00133 
00134 
00135 float MuonDTSeedFromRecHits::bestEta() const {
00136 
00137   int Maxseg = 0;
00138   float Msdeta = 100.;
00139   float result = (*theRhits.begin())->globalPosition().eta();
00140 
00141   for (MuonRecHitContainer::const_iterator iter=theRhits.begin(); iter!=theRhits.end(); iter++ ) {
00142 
00143     float eta1= (*iter)->globalPosition().eta(); 
00144 
00145     int Nseg = 0;
00146     float sdeta = .0;
00147 
00148     for (MuonRecHitContainer::const_iterator iter2=theRhits.begin();  iter2!=theRhits.end(); iter2++ ) {
00149 
00150       if ( iter2 == iter )  continue;
00151 
00152       float eta2 = (*iter2)->globalPosition().eta(); 
00153 
00154       if ( fabs (eta1-eta2) > .2 ) continue;
00155 
00156       Nseg++;
00157       sdeta += fabs (eta1-eta2); 
00158 
00159       if ( Nseg > Maxseg ||  (Nseg == Maxseg && sdeta < Msdeta) ) {
00160         Maxseg = Nseg;
00161         Msdeta = sdeta;
00162         result = eta1;
00163       }
00164 
00165     }
00166   }   //  +v.
00167   return result;
00168 }
00169 
00170 
00171 void MuonDTSeedFromRecHits::computePtWithVtx(double* pt, double* spt) const {
00172 
00173   float eta0 = bestEta();
00174 
00175   for (MuonRecHitContainer::const_iterator iter=theRhits.begin(); iter!=theRhits.end(); iter++ ) {
00176 
00177  //+vvp !:
00178 
00179     float eta1= (*iter)->globalPosition().eta(); 
00180     if ( fabs (eta1-eta0) > .2 ) continue;  //   !!! +vvp
00181 
00182     // assign Pt from MB1 & vtx   
00183     unsigned int stat = DTChamberId((**iter).geographicalId()).station();
00184     if(stat > 2) continue;
00185 
00186     double thispt = thePtExtractor->pT_extract(*iter, *iter)[0];
00187     float ptmax = 2000.;
00188     if(thispt > ptmax) thispt = ptmax;
00189     if(thispt < -ptmax) thispt = -ptmax;
00190 
00191     if( stat==1 ) {
00192       pt[0] = thispt;
00193     }
00194     // assign Pt from MB2 & vtx
00195     if( stat==2 ) {
00196       pt[1] = thispt;
00197     } 
00198   }
00199 }
00200 
00201 
00202 void MuonDTSeedFromRecHits::computePtWithoutVtx(double* pt, double* spt) const {
00203   float eta0 = bestEta();
00204 
00205   for (MuonRecHitContainer::const_iterator iter=theRhits.begin(); 
00206         iter!=theRhits.end(); iter++ ) {
00207     //+vvp !:
00208     float eta1= (*iter)->globalPosition().eta(); 
00209     if ( fabs (eta1-eta0) > .2 ) continue;  //   !!! +vvp
00210 
00211     for (MuonRecHitContainer::const_iterator iter2=theRhits.begin(); 
00212           iter2!=iter; iter2++ ) {
00213       //+vvp !:
00214       float eta2= (*iter2)->globalPosition().eta(); 
00215       if ( fabs (eta2-eta0) > .2 ) continue;  //   !!! +vvp
00216 
00217       unsigned int stat1 = DTChamberId((*iter)->geographicalId()).station();
00218       unsigned int stat2 = DTChamberId((*iter2)->geographicalId()).station();
00219 
00220       if ( stat1>stat2) {
00221         int tmp = stat1;
00222         stat1 = stat2;
00223         stat2 = tmp;
00224       }
00225       unsigned int st = stat1*10+stat2;
00226       double thispt = thePtExtractor->pT_extract(*iter, *iter2)[0];
00227       switch (st) {
00228       case  12 : {//MB1-MB2
00229         pt[2] = thispt;
00230         break;
00231       }
00232       case  13 : {//MB1-MB3
00233         pt[3] = thispt;
00234         break;
00235       }
00236       case  14 : {//MB1-MB4
00237         pt[5] = thispt;
00238         break;
00239       }
00240       case  23 : {//MB2-MB3
00241         pt[4] = thispt;
00242         break;
00243       }
00244       case  24 : {//MB2-MB4
00245         pt[6] = thispt;
00246         break;
00247       }
00248       case  34 : {//MB3-MB4
00249         pt[7] = thispt;
00250         break;
00251       }
00252       default: {
00253         break;
00254       }
00255       }  
00256     }
00257   }
00258 }
00259 
00260 void MuonDTSeedFromRecHits::computeBestPt(double* pt,
00261                                            double* spt,
00262                                            float& ptmean,
00263                                            float& sptmean) const {
00264 
00265   const std::string metname = "Muon|RecoMuon|MuonDTSeedFromRecHits";
00266 
00267   int nTotal=8;
00268   int igood=-1;
00269   for (int i=0;i<=7;i++) {
00270     if(pt[i]==0) {
00271       spt[i]=0.;
00272       nTotal--;
00273     } else {
00274       igood=i;
00275     }
00276   }
00277 
00278   if (nTotal==1) {
00280     ptmean=pt[igood];
00281     sptmean=1/sqrt(spt[igood]);
00282   } else if (nTotal==0) {
00283     // No estimate (e.g. only one rechit!)
00284     ptmean=50;
00285     sptmean=30;
00286   } else {
00288     // calculate pt with vertex
00289     float ptvtx=0.0;
00290     float sptvtx=0.0;
00291     computeMean(pt, spt, 2, false, ptvtx, sptvtx);
00292     LogTrace(metname) << " GSL: Pt w vtx :" << ptvtx << "+/-" <<
00293       sptvtx << endl;
00294       
00295     // FIXME: temp hack
00296     if(ptvtx != 0.) {
00297       ptmean = ptvtx;
00298       sptmean = sptvtx;
00299       return;
00300       //
00301     }
00302     // calculate pt w/o vertex
00303     float ptMB=0.0;
00304     float sptMB=0.0;
00305     computeMean(pt+2, spt+2, 6, false, ptMB, sptMB);
00306     LogTrace(metname) << " GSL: Pt w/o vtx :" << ptMB << "+/-" <<
00307         sptMB << endl;
00308 
00309     // decide wheter the muon comes or not from vertex 
00310     float ptpool=0.0;
00311     if((ptvtx+ptMB)!=0.0) ptpool=(ptvtx-ptMB)/(ptvtx+ptMB);
00312     bool fromvtx=true;
00313     if(fabs(ptpool)>0.2) fromvtx=false; 
00314     LogTrace(metname) << "From vtx? " <<fromvtx << " ptpool "<< ptpool << endl;
00315 
00316     // now choose the "right" pt => weighted mean
00317     computeMean(pt, spt, 8, true, ptmean, sptmean);
00318     LogTrace(metname) << " GSL Pt :" << ptmean << "+/-" << sptmean << endl;
00319 
00320   }
00321 }
00322 
00323 
00324 void MuonDTSeedFromRecHits::computeMean(const double* pt, const double * weights, int sz,
00325                                         bool tossOutlyers, float& ptmean, float & sptmean) const
00326 {
00327   int n=0;
00328   double ptTmp[8];
00329   double wtTmp[8];
00330   assert(sz<=8);
00331 
00332   for (int i=0; i<sz; ++i) {
00333     ptTmp[i] = 0.;
00334     wtTmp[i] = 0;
00335     if (pt[i]!=0) {
00336       ptTmp[n]=pt[i];
00337       wtTmp[n]=weights[i];
00338       ++n;
00339     }
00340   }
00341   if(n != 0) 
00342   {
00343     if (n==1) {
00344       ptmean=ptTmp[0];
00345       sptmean=1/sqrt(wtTmp[0]);
00346     } else {
00347       ptmean = gsl_stats_wmean(wtTmp, 1, ptTmp, 1, n);
00348       sptmean = sqrt( gsl_stats_wvariance_m (wtTmp, 1, ptTmp, 1, n, ptmean) );
00349     }
00350 
00351     if(tossOutlyers)
00352     {
00353       // Recompute mean with a cut at 3 sigma
00354       for ( int nm =0; nm<8; nm++ ){
00355         if ( ptTmp[nm]!=0 && fabs(ptTmp[nm]-ptmean)>3*(sptmean) ) {
00356           wtTmp[nm]=0.;
00357         }
00358       }
00359       ptmean = gsl_stats_wmean(wtTmp, 1, ptTmp, 1, n);
00360       sptmean = sqrt( gsl_stats_wvariance_m (wtTmp, 1, ptTmp, 1, n, ptmean) );
00361     }
00362   }
00363 
00364 }
00365