CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoMuon/MuonIdentification/src/MuonKinkFinder.cc

Go to the documentation of this file.
00001 #include "RecoMuon/MuonIdentification/interface/MuonKinkFinder.h"
00002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00003 #include "TrackingTools/PatternTools/interface/Trajectory.h"
00004 
00005 MuonKinkFinder::MuonKinkFinder(const edm::ParameterSet &iConfig) :
00006     diagonalOnly_(iConfig.getParameter<bool>("diagonalOnly")),
00007     usePosition_(iConfig.getParameter<bool>("usePosition")),
00008     refitter_(iConfig)
00009 { 
00010 }
00011 
00012 MuonKinkFinder::~MuonKinkFinder() { }
00013 
00014 void MuonKinkFinder::init(const edm::EventSetup &iSetup) { 
00015     refitter_.setServices(iSetup);
00016 }
00017 
00018 bool MuonKinkFinder::fillTrkKink(reco::MuonQuality & quality, const reco::Track &track) const {
00019     std::vector<Trajectory> traj  = refitter_.transform(track);
00020     if (traj.size() != 1) {
00021         quality.trkKink = 999;
00022         quality.tkKink_position = math::XYZPoint(0,0,0);
00023         return false;
00024     }
00025     return fillTrkKink(quality, traj.front());
00026 }
00027 
00028 bool MuonKinkFinder::fillTrkKink(reco::MuonQuality & quality, const Trajectory &trajectory) const {
00029     const std::vector<TrajectoryMeasurement> &tms = trajectory.measurements();
00030     quality.trkKink = -1.0;
00031     quality.tkKink_position = math::XYZPoint(0,0,0);
00032     bool found = false; 
00033     for (int itm = 3, nm = tms.size() - 3;  itm < nm; ++itm) {
00034         TrajectoryStateOnSurface pre  = tms[itm].forwardPredictedState();
00035         TrajectoryStateOnSurface post = tms[itm].backwardPredictedState();
00036         if (!pre.isValid() || !post.isValid()) continue;
00037         found = true;
00038         double c2f = getChi2(pre,post);
00039         if (c2f > quality.trkKink) { 
00040             quality.trkKink = c2f; 
00041             GlobalPoint pos = (tms[itm].updatedState().isValid() ? tms[itm].updatedState() : pre).globalPosition();
00042             quality.tkKink_position = math::XYZPoint(pos.x(), pos.y(), pos.z());
00043         }
00044     }
00045     if (!found) quality.trkKink = 999;
00046     return found;
00047 }
00048 
00049 double MuonKinkFinder::getChi2(const TrajectoryStateOnSurface &start, const TrajectoryStateOnSurface &other) const {
00050     if (!start.hasError() && !other.hasError()) throw cms::Exception("LogicError") << "At least one of the two states must have errors to make chi2s.\n";
00051     AlgebraicSymMatrix55 cov;
00052     if (start.hasError()) cov += start.localError().matrix();
00053     if (other.hasError()) cov += other.localError().matrix();
00054     cropAndInvert(cov);
00055     AlgebraicVector5 diff(start.localParameters().mixedFormatVector() - other.localParameters().mixedFormatVector());
00056     return ROOT::Math::Similarity(diff, cov);
00057 }
00058 
00059 void MuonKinkFinder::cropAndInvert(AlgebraicSymMatrix55 &cov) const {
00060     if (usePosition_) {
00061         if (diagonalOnly_) {
00062             for (size_t i = 0; i < 5; ++i) { for (size_t j = i+1; j < 5; ++j) {
00063                 cov(i,j) = 0;
00064             } }
00065         }
00066         cov.Invert();
00067     } else {
00068         // get 3x3 covariance
00069         AlgebraicSymMatrix33 momCov = cov.Sub<AlgebraicSymMatrix33>(0,0); // get 3x3 matrix
00070         if (diagonalOnly_) { momCov(0,1) = 0; momCov(0,2) = 0; momCov(1,2) = 0; }
00071         // invert        
00072         momCov.Invert();
00073         // place it
00074         cov.Place_at(momCov,0,0);
00075         // zero the rest
00076         for (size_t i = 3; i < 5; ++i) { for (size_t j = i; j < 5; ++j) { 
00077             cov(i,j) = 0;
00078         } }
00079     }
00080 }
00081