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
00038
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
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
00064 computeBestPt(pt, spt, ptmean, sptmean);
00065
00066
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
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 }
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
00178
00179 float eta1= (*iter)->globalPosition().eta();
00180 if ( fabs (eta1-eta0) > .2 ) continue;
00181
00182
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
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
00208 float eta1= (*iter)->globalPosition().eta();
00209 if ( fabs (eta1-eta0) > .2 ) continue;
00210
00211 for (MuonRecHitContainer::const_iterator iter2=theRhits.begin();
00212 iter2!=iter; iter2++ ) {
00213
00214 float eta2= (*iter2)->globalPosition().eta();
00215 if ( fabs (eta2-eta0) > .2 ) continue;
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 : {
00229 pt[2] = thispt;
00230 break;
00231 }
00232 case 13 : {
00233 pt[3] = thispt;
00234 break;
00235 }
00236 case 14 : {
00237 pt[5] = thispt;
00238 break;
00239 }
00240 case 23 : {
00241 pt[4] = thispt;
00242 break;
00243 }
00244 case 24 : {
00245 pt[6] = thispt;
00246 break;
00247 }
00248 case 34 : {
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
00284 ptmean=50;
00285 sptmean=30;
00286 } else {
00288
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
00296 if(ptvtx != 0.) {
00297 ptmean = ptvtx;
00298 sptmean = sptvtx;
00299 return;
00300
00301 }
00302
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
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
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
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