00001 #include "RecoMuon/TrackingTools/plugins/MuonErrorMatrixAdjuster.h"
00002
00003 #include "TString.h"
00004 #include "TMath.h"
00005 #include <MagneticField/Records/interface/IdealMagneticFieldRecord.h>
00006 #include <MagneticField/Engine/interface/MagneticField.h>
00007
00008 #include <TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h>
00009 #include "RecoMuon/TrackingTools/interface/MuonErrorMatrix.h"
00010
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012
00013 #include <TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h>
00014 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00015
00016 MuonErrorMatrixAdjuster::MuonErrorMatrixAdjuster(const edm::ParameterSet& iConfig)
00017 {
00018 theCategory="MuonErrorMatrixAdjuster";
00019 theInstanceName = iConfig.getParameter<std::string>("instanceName");
00020
00021 produces<reco::TrackCollection>( theInstanceName);
00022 produces<TrackingRecHitCollection>();
00023 produces<reco::TrackExtraCollection>();
00024
00025 theTrackLabel = iConfig.getParameter<edm::InputTag>("trackLabel");
00026 theRescale = iConfig.getParameter<bool>("rescale");
00027
00028 theMatrixProvider_pset = iConfig.getParameter<edm::ParameterSet>("errorMatrix_pset");
00029 }
00030
00031
00032 MuonErrorMatrixAdjuster::~MuonErrorMatrixAdjuster()
00033 {
00034
00035
00036
00037
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 reco::TrackBase::CovarianceMatrix MuonErrorMatrixAdjuster::fix_cov_matrix(const reco::TrackBase::CovarianceMatrix& error_matrix,const GlobalVector& momentum)
00047 {
00048
00049 reco::TrackBase::CovarianceMatrix revised_matrix( theMatrixProvider->get(momentum));
00050
00051 if( theRescale){
00052
00053 multiply(revised_matrix,error_matrix);
00054 }
00055 return revised_matrix;
00056 }
00057
00058 void MuonErrorMatrixAdjuster::multiply(reco::TrackBase::CovarianceMatrix & revised_matrix, const reco::TrackBase::CovarianceMatrix & scale_matrix){
00059
00060
00061
00062 for(int i = 0;i!=5;i++){for(int j = i;j!=5;j++){
00063 revised_matrix(i,j)*=scale_matrix(i,j);
00064 }}
00065 }
00066 bool MuonErrorMatrixAdjuster::divide(reco::TrackBase::CovarianceMatrix & num_matrix, const reco::TrackBase::CovarianceMatrix & denom_matrix){
00067
00068
00069
00070 for(int i = 0;i!=5;i++){for(int j = i;j!=5;j++){
00071 if (denom_matrix(i,j)==0) return false;
00072 num_matrix(i,j)/=denom_matrix(i,j);
00073 }}
00074 return true;
00075 }
00076
00077 reco::Track MuonErrorMatrixAdjuster::makeTrack(const reco::Track & recotrack_orig,
00078 const FreeTrajectoryState & PCAstate){
00079
00080 double chi2 = recotrack_orig.chi2();
00081 double ndof = recotrack_orig.ndof();
00082 math::XYZPoint refpos = recotrack_orig.referencePoint();
00083 math::XYZVector mom = recotrack_orig.momentum();
00084 int charge = recotrack_orig.charge();
00085
00086 reco::TrackBase::CovarianceMatrix covariance_matrix = fix_cov_matrix(recotrack_orig.covariance(),PCAstate.momentum());
00087
00088 LogDebug(theCategory)<<"chi2: "<<chi2
00089 <<"\n ndof: "<<ndof
00090 <<"\n refpos: "<<refpos
00091 <<"\n mom: "<<mom
00092 <<"\n charge: "<<charge
00093 <<"\n covariance:\n"<<recotrack_orig.covariance()
00094 <<"\n replaced by:\n"<<covariance_matrix;
00095
00096 return reco::Track(chi2,ndof,refpos,mom,charge,covariance_matrix);
00097 }
00098
00099 reco::TrackExtra * MuonErrorMatrixAdjuster::makeTrackExtra(const reco::Track & recotrack_orig,
00100 reco::Track & recotrack,
00101 reco::TrackExtraCollection& TEcol){
00102
00103 reco::TrackBase::CovarianceMatrix scale_matrix(recotrack.covariance());
00104 if (!divide(scale_matrix,recotrack_orig.covariance())){
00105 edm::LogError( theCategory)<<"original track error matrix has term ==0... skipping.";
00106 return 0; }
00107
00108 const reco::TrackExtraRef & trackExtra_orig = recotrack_orig.extra();
00109 if (trackExtra_orig.isNull()) {
00110 edm::LogError( theCategory)<<"original track has no track extra... skipping.";
00111 return 0;}
00112
00113
00114 reco::TrackBase::CovarianceMatrix outerCov(trackExtra_orig->outerStateCovariance());
00115 multiply(outerCov,scale_matrix);
00116
00117
00118 reco::TrackBase::CovarianceMatrix innerCov(trackExtra_orig->innerStateCovariance());
00119 multiply(innerCov,scale_matrix);
00120
00121
00122 TEcol.push_back(reco::TrackExtra (trackExtra_orig->outerPosition(), trackExtra_orig->outerMomentum(), true,
00123 trackExtra_orig->innerPosition(), trackExtra_orig->innerMomentum(), true,
00124 outerCov, trackExtra_orig->outerDetId(),
00125 innerCov, trackExtra_orig->innerDetId(),
00126 trackExtra_orig->seedDirection()));
00127
00128
00129 recotrack.setExtra(edm::Ref<reco::TrackExtraCollection>( theRefprodTE, theTEi++));
00130
00131
00132 return &(TEcol.back());
00133 }
00134
00135
00136 bool MuonErrorMatrixAdjuster::attachRecHits(const reco::Track & recotrack_orig,
00137 reco::Track & recotrack,
00138 reco::TrackExtra & trackextra,
00139 TrackingRecHitCollection& RHcol){
00140
00141 trackingRecHit_iterator recHit = recotrack_orig.recHitsBegin();
00142 unsigned int irh=0;
00143 for (; recHit!=recotrack_orig.recHitsEnd();++recHit){
00144
00145 TrackingRecHit * hit = (*recHit)->clone();
00146
00147
00148 recotrack.setHitPattern(*hit,irh++);
00149
00150 RHcol.push_back(hit);
00151
00152 trackextra.add(TrackingRecHitRef( theRefprodRH, theRHi++));
00153
00154 }
00155
00156 return true;
00157 }
00158
00159 bool MuonErrorMatrixAdjuster::selectTrack(const reco::Track & recotrack_orig){return true;}
00160
00161
00162 void
00163 MuonErrorMatrixAdjuster::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00164 {
00165 using namespace edm;
00166
00167
00168 edm::Handle<reco::TrackCollection> tracks;
00169 iEvent.getByLabel( theTrackLabel,tracks);
00170 LogDebug( theCategory)<<"considering: "<<tracks->size()<<" uncorrected reco::Track from the event.("<< theTrackLabel<<")";
00171
00172
00173 iSetup.get<IdealMagneticFieldRecord>().get( theField);
00174
00175
00176 std::auto_ptr<reco::TrackCollection> Toutput(new reco::TrackCollection());
00177 std::auto_ptr<TrackingRecHitCollection> TRHoutput(new TrackingRecHitCollection());
00178 std::auto_ptr<reco::TrackExtraCollection> TEoutput(new reco::TrackExtraCollection());
00179 theRefprodTE = iEvent.getRefBeforePut<reco::TrackExtraCollection>();
00180 theTEi=0;
00181 theRefprodRH =iEvent.getRefBeforePut<TrackingRecHitCollection>();
00182 theRHi=0;
00183
00184 TrajectoryStateTransform transformer;
00185
00186 for(unsigned int it=0;it!=tracks->size();it++)
00187 {
00188 const reco::Track & recotrack_orig = (*tracks)[it];
00189 FreeTrajectoryState PCAstate = transformer.initialFreeState(recotrack_orig, theField.product());
00190 if (PCAstate.position().mag()==0)
00191 {edm::LogError( theCategory)<<"invalid state from track initial state in "<< theTrackLabel <<". skipping.";continue;}
00192
00193
00194 reco::Track recotrack = makeTrack(recotrack_orig,PCAstate);
00195
00196
00197 if (!selectTrack(recotrack)) continue;
00198
00199 Toutput->push_back(recotrack);
00200 reco::Track & recotrackref = Toutput->back();
00201
00202
00203 reco::TrackExtra * extra = makeTrackExtra(recotrack_orig,recotrackref,*TEoutput);
00204 if (!extra){
00205 edm::LogError( theCategory)<<"cannot create the track extra for this track.";
00206
00207 Toutput->pop_back();
00208 continue;}
00209
00210
00211 if (!attachRecHits(recotrack_orig,recotrackref,*extra,*TRHoutput)){
00212 edm::LogError( theCategory)<<"cannot attach any rechits on this track";
00213
00214 Toutput->pop_back();
00215
00216 TEoutput->pop_back();
00217 theTEi--;
00218 continue;}
00219
00220 }
00221
00222 LogDebug( theCategory)<<"writing: "<<Toutput->size()<<" corrected reco::Track to the event.";
00223
00224 iEvent.put(Toutput, theInstanceName);
00225 iEvent.put(TEoutput);
00226 iEvent.put(TRHoutput);
00227
00228 }
00229
00230
00231 void
00232 MuonErrorMatrixAdjuster::beginJob()
00233 {
00234 theMatrixProvider = new MuonErrorMatrix(theMatrixProvider_pset);
00235 }
00236
00237
00238 void
00239 MuonErrorMatrixAdjuster::endJob() {
00240 if ( theMatrixProvider) delete theMatrixProvider;
00241 }