CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/Alignment/MuonAlignmentAlgorithms/src/MuonResidualsFromTrack.cc

Go to the documentation of this file.
00001 /*
00002  * $Id: MuonResidualsFromTrack.cc,v 1.5 2011/10/12 23:40:24 khotilov Exp $ 
00003  */
00004 
00005 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonResidualsFromTrack.h"
00006 #include "DataFormats/TrackReco/interface/Track.h"
00007 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00008 
00009 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonDT13ChamberResidual.h"
00010 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonDT2ChamberResidual.h"
00011 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonCSCChamberResidual.h"
00012 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonTrackDT13ChamberResidual.h"
00013 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonTrackDT2ChamberResidual.h"
00014 #include "Alignment/MuonAlignmentAlgorithms/interface/MuonTrackCSCChamberResidual.h"
00015 
00016 #include "TDecompChol.h"
00017 
00018 
00019 void MuonResidualsFromTrack::addTrkCovMatrix(DetId chamberId, TrajectoryStateOnSurface &tsos)
00020 {
00021   const AlgebraicSymMatrix55 cov55 = tsos.localError().matrix();
00022   TMatrixDSym cov44(4);
00023   // change indices from q/p,dxdz,dydz,x,y   to   x,y,dxdz,dydz
00024   int subs[4] = { 3, 4, 1, 2 };
00025   for (int i=0;i<4;i++) for (int j=0;j<4;j++)  cov44(i,j) = cov55( subs[i], subs[j] );
00026   m_trkCovMatrix[chamberId] = cov44;
00027 }
00028 
00029 
00030 MuonResidualsFromTrack::MuonResidualsFromTrack(edm::ESHandle<GlobalTrackingGeometry> globalGeometry,
00031                                                const Trajectory *traj,
00032                                                const reco::Track* trk,
00033                                                AlignableNavigator *navigator, double maxResidual)
00034   : track(trk)
00035 {
00036   clear();
00037 
00038   std::vector<TrajectoryMeasurement> measurements = traj->measurements();
00039   for (std::vector<TrajectoryMeasurement>::const_iterator im = measurements.begin();  im != measurements.end();  ++im) {
00040     TrajectoryMeasurement meas = *im;
00041     const TransientTrackingRecHit *hit = &(*meas.recHit());
00042     DetId id = hit->geographicalId();
00043 
00044     if (hit->isValid()) {
00045       TrajectoryStateOnSurface tsos = m_tsoscomb(meas.forwardPredictedState(), meas.backwardPredictedState());
00046       if (tsos.isValid()  &&  fabs(tsos.localPosition().x() - hit->localPosition().x()) < maxResidual) {
00047 
00048         if (id.det() == DetId::Tracker) {
00049           double xresid = tsos.localPosition().x() - hit->localPosition().x();
00050           double xresiderr2 = tsos.localError().positionError().xx() + hit->localPositionError().xx();
00051 
00052           m_tracker_numHits++;
00053           m_tracker_chi2 += xresid * xresid / xresiderr2;
00054 
00055           if (id.subdetId() == StripSubdetector::TID  ||  id.subdetId() == StripSubdetector::TEC) m_contains_TIDTEC = true;
00056         }
00057 
00058         else if (id.det() == DetId::Muon  &&  id.subdetId() == MuonSubdetId::DT) {
00059           const DTChamberId chamberId(id.rawId());
00060           const DTSuperLayerId superLayerId(id.rawId());
00061 
00062           // have we seen this chamber before?
00063           if (m_dt13.find(chamberId) == m_dt13.end()  &&  m_dt2.find(chamberId) == m_dt2.end()) {
00064             m_chamberIds.push_back(chamberId);
00065             //addTrkCovMatrix(chamberId, tsos); // only for the 1st hit
00066           }
00067 
00068           if (superLayerId.superlayer() == 2) {
00069             if (m_dt2.find(chamberId) == m_dt2.end()) {
00070               AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00071               m_dt2[chamberId] = new MuonDT2ChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00072             }
00073 
00074             m_dt2[chamberId]->addResidual(&tsos, hit);
00075           }
00076 
00077           else {
00078             if (m_dt13.find(chamberId) == m_dt13.end()) {
00079               AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00080               m_dt13[chamberId] = new MuonDT13ChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00081             }
00082 
00083             m_dt13[chamberId]->addResidual(&tsos, hit);
00084           }
00085         }
00086 
00087         else if (id.det() == DetId::Muon  &&  id.subdetId() == MuonSubdetId::CSC) {
00088           const CSCDetId cscDetId(id.rawId());
00089           const CSCDetId chamberId(cscDetId.endcap(), cscDetId.station(), cscDetId.ring(), cscDetId.chamber());
00090 
00091           // not sure why we sometimes get layer == 0
00092           if (cscDetId.layer() == 0) continue;
00093 
00094           // have we seen this chamber before?
00095           if (m_csc.find(chamberId) == m_csc.end())
00096           {
00097             m_chamberIds.push_back(chamberId);
00098             //addTrkCovMatrix(chamberId, tsos); // only for the 1st hit
00099             AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00100             m_csc[chamberId] = new MuonCSCChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00101           }
00102 
00103           m_csc[chamberId]->addResidual(&tsos, hit);
00104         }
00105 
00106       } // end if track propagation is valid
00107     } // end if hit is valid
00108   } // end loop over measurments
00109 }
00110 
00111 
00112 MuonResidualsFromTrack::MuonResidualsFromTrack(edm::ESHandle<GlobalTrackingGeometry> globalGeometry, const reco::Muon *mu, AlignableNavigator *navigator, double maxResidual)
00113   : muon(mu)
00114 {
00115   clear();
00116   assert( muon->isTrackerMuon() && muon->innerTrack().isNonnull());
00117   track = muon->innerTrack().get();
00118   
00119   m_tracker_chi2 = muon->innerTrack()->chi2();
00120   m_tracker_numHits = muon->innerTrack()->ndof() + 5;
00121   m_tracker_numHits = m_tracker_numHits > 0 ? m_tracker_numHits : 0 ;
00122   
00123   /*
00124   for (trackingRecHit_iterator hit = muon->innerTrack()->recHitsBegin();  hit != muon->innerTrack()->recHitsEnd();  ++hit)
00125   {
00126     DetId id = (*hit)->geographicalId();
00127     if (id.det() == DetId::Tracker)
00128     {
00129       m_tracker_numHits++;
00130       if (id.subdetId() == StripSubdetector::TID  ||  id.subdetId() == StripSubdetector::TEC) m_contains_TIDTEC = true;
00131     }
00132   }
00133   */
00134   
00135   for (std::vector<reco::MuonChamberMatch>::const_iterator chamberMatch = muon->matches().begin();  
00136        chamberMatch != muon->matches().end();  chamberMatch++)
00137   {
00138     if (chamberMatch->id.det() != DetId::Muon ) continue;
00139     
00140     for (std::vector<reco::MuonSegmentMatch>::const_iterator segMatch = chamberMatch->segmentMatches.begin();
00141          segMatch != chamberMatch->segmentMatches.end();  ++segMatch)
00142     {
00143       // select the only segment that belongs to track and is the best in station by dR
00144       if (! (segMatch->isMask(reco::MuonSegmentMatch::BestInStationByDR) &&
00145              segMatch->isMask(reco::MuonSegmentMatch::BelongsToTrackByDR)) ) continue;
00146       
00147       if (chamberMatch->id.subdetId() == MuonSubdetId::DT)
00148       {
00149         const DTChamberId chamberId(chamberMatch->id.rawId());
00150 
00151         DTRecSegment4DRef segmentDT = segMatch->dtSegmentRef;
00152         const DTRecSegment4D* segment = segmentDT.get();
00153         if (segment == 0)  continue;
00154         
00155         if ( segment->hasPhi()  &&  fabs(chamberMatch->x - segMatch->x) > maxResidual ) continue;
00156         if ( segment->hasZed()  &&  fabs(chamberMatch->y - segMatch->y) > maxResidual ) continue;
00157           
00158         // have we seen this chamber before?
00159         if (m_dt13.find(chamberId) == m_dt13.end()  &&  m_dt2.find(chamberId) == m_dt2.end()) {
00160           m_chamberIds.push_back(chamberId);
00161         }
00162 
00163         if (segment->hasZed())
00164         {
00165           if (m_dt2.find(chamberId) == m_dt2.end())
00166           {
00167             AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00168             m_dt2[chamberId] = new MuonTrackDT2ChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00169           }
00170           else std::cout<<"multi segment match to tmuon: dt2  -- should not happen!"<<std::endl;
00171           m_dt2[chamberId]->setSegmentResidual(&(*chamberMatch), &(*segMatch));
00172         }
00173         if (segment->hasPhi())
00174         {
00175           if (m_dt13.find(chamberId) == m_dt13.end())
00176           {
00177             AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00178             m_dt13[chamberId] = new MuonTrackDT13ChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00179           }
00180           else std::cout<<"multi segment match to tmuon: dt13  -- should not happen!"<<std::endl;
00181           m_dt13[chamberId]->setSegmentResidual(&(*chamberMatch), &(*segMatch));
00182         }
00183       }
00184 
00185       else if (chamberMatch->id.subdetId() == MuonSubdetId::CSC) 
00186       {
00187         const CSCDetId cscDetId(chamberMatch->id.rawId());
00188         const CSCDetId chamberId(cscDetId.chamberId());
00189 
00190         if ( fabs(chamberMatch->x - segMatch->x) > maxResidual ) continue;
00191 
00192         // have we seen this chamber before?
00193         if (m_csc.find(chamberId) == m_csc.end())
00194         {
00195           m_chamberIds.push_back(chamberId);
00196           AlignableDetOrUnitPtr chamberAlignable = navigator->alignableFromDetId(chamberId);
00197           m_csc[chamberId] = new MuonTrackCSCChamberResidual(globalGeometry, navigator, chamberId, chamberAlignable);
00198         }
00199         else std::cout<<"multi segment match to tmuon: csc  -- should not happen!"<<std::endl;
00200         m_csc[chamberId]->setSegmentResidual(&(*chamberMatch), &(*segMatch));
00201       }
00202 
00203     }
00204   }
00205 }
00206 
00207 
00208 MuonResidualsFromTrack::~MuonResidualsFromTrack() 
00209 {
00210   for (std::map<DetId,MuonChamberResidual*>::const_iterator residual = m_dt13.begin();  residual != m_dt13.end();  ++residual) {
00211     delete residual->second;
00212   }
00213   for (std::map<DetId,MuonChamberResidual*>::const_iterator residual = m_dt2.begin();  residual != m_dt2.end();  ++residual) {
00214     delete residual->second;
00215   }
00216   for (std::map<DetId,MuonChamberResidual*>::const_iterator residual = m_csc.begin();  residual != m_csc.end();  ++residual) {
00217     delete residual->second;
00218   }
00219 }
00220 
00221 
00222 void MuonResidualsFromTrack::clear()
00223 {
00224   m_tracker_numHits = 0;
00225   m_tracker_chi2 = 0.;
00226   m_contains_TIDTEC = false;
00227   m_chamberIds.clear();
00228   m_dt13.clear();
00229   m_dt2.clear();
00230   m_csc.clear();
00231   m_trkCovMatrix.clear();
00232 }
00233 
00234 
00235 double MuonResidualsFromTrack::trackerRedChi2() const 
00236 {
00237   if (m_tracker_numHits > 5) return m_tracker_chi2 / double(m_tracker_numHits - 5);
00238   else return -1.;
00239 }
00240 
00241 
00242 double MuonResidualsFromTrack::normalizedChi2() const 
00243 {
00244   if (muon) return track->normalizedChi2();
00245   return trackerRedChi2();
00246 }
00247 
00248 
00249 MuonChamberResidual * MuonResidualsFromTrack::chamberResidual(DetId chamberId, int type)
00250 {
00251   if (type == MuonChamberResidual::kDT13) {
00252     if (m_dt13.find(chamberId) == m_dt13.end()) return NULL;
00253     return m_dt13[chamberId];
00254   }
00255   else if (type == MuonChamberResidual::kDT2) {
00256     if (m_dt2.find(chamberId) == m_dt2.end()) return NULL;
00257     return m_dt2[chamberId];
00258   }
00259   else if (type == MuonChamberResidual::kCSC) {
00260     if (m_csc.find(chamberId) == m_csc.end()) return NULL;
00261     return m_csc[chamberId];
00262   }
00263   else return NULL;
00264 }
00265 
00266 
00267 TMatrixDSym MuonResidualsFromTrack::covMatrix(DetId chamberId)
00268 {
00269   TMatrixDSym result(4);
00270   std::cout<<"MuonResidualsFromTrack:: cov initial:"<<std::endl;
00271   result.Print();
00272   if (m_trkCovMatrix.find(chamberId) == m_trkCovMatrix.end())
00273   {
00274     std::cout<<"MuonResidualsFromTrack:: cov does not exist!"<<std::endl;
00275     return result;
00276   }
00277   result = m_trkCovMatrix[chamberId];
00278 
00279   std::cout<<"MuonResidualsFromTrack:: cov before:"<<std::endl;
00280   result.Print();
00281 
00282   // add segment's errors in quadratures to track's covariance matrix
00283   double r_err;
00284   if (m_csc.find(chamberId) == m_csc.end())
00285   {
00286     r_err = m_csc[chamberId]->residual_error();
00287     result(0,0) += r_err*r_err;
00288     r_err = m_csc[chamberId]->resslope_error();
00289     result(2,2) += r_err*r_err;
00290   }
00291   if (m_dt13.find(chamberId) == m_dt13.end())
00292   {
00293     r_err = m_dt13[chamberId]->residual_error();
00294     result(0,0) += r_err*r_err;
00295     r_err = m_dt13[chamberId]->resslope_error();
00296     result(2,2) += r_err*r_err;
00297   }
00298   if (m_dt2.find(chamberId) == m_dt2.end())
00299   {
00300     r_err = m_dt2[chamberId]->residual_error();
00301     result(1,1) += r_err*r_err;
00302     r_err = m_dt2[chamberId]->resslope_error();
00303     result(3,3) += r_err*r_err;
00304   }
00305   std::cout<<"MuonResidualsFromTrack:: cov after:"<<std::endl;
00306   result.Print();
00307 
00308   return result;
00309 }
00310 
00311 TMatrixDSym MuonResidualsFromTrack::corrMatrix(DetId chamberId)
00312 {
00313   TMatrixDSym result(4);
00314   TMatrixDSym cov44 = covMatrix(chamberId);
00315 
00316   // invert it using cholesky decomposition
00317   TDecompChol decomp(cov44);
00318   bool ok = decomp.Invert(result);
00319   std::cout<<"MuonResidualsFromTrack:: corr after:"<<std::endl;
00320   result.Print();
00321 
00322   if (!ok){std::cout<<"MuonResidualsFromTrack:: cov inversion failed!"<<std::endl;}
00323   return result;
00324 }
00325 
00326 TMatrixD MuonResidualsFromTrack::choleskyCorrMatrix(DetId chamberId)
00327 {
00328   TMatrixD result(4,4);
00329   TMatrixDSym corr44 = corrMatrix(chamberId);
00330 
00331   // get an upper triangular matrix U such that corr = U^T * U
00332   TDecompChol decomp(corr44);
00333   bool ok = decomp.Decompose();
00334   result = decomp.GetU();
00335 
00336   std::cout<<"MuonResidualsFromTrack:: corr cholesky after:"<<std::endl;
00337   result.Print();
00338 
00339   if (!ok){std::cout<<"MuonResidualsFromTrack:: corr decomposition failed!"<<std::endl;}
00340   return result;
00341 }