00001
00002
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
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
00063 if (m_dt13.find(chamberId) == m_dt13.end() && m_dt2.find(chamberId) == m_dt2.end()) {
00064 m_chamberIds.push_back(chamberId);
00065
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
00092 if (cscDetId.layer() == 0) continue;
00093
00094
00095 if (m_csc.find(chamberId) == m_csc.end())
00096 {
00097 m_chamberIds.push_back(chamberId);
00098
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 }
00107 }
00108 }
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
00125
00126
00127
00128
00129
00130
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
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
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
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
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
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
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 }