CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_13_patch3/src/RecoMuon/TrackingTools/plugins/MuonErrorMatrixAdjuster.cc

Go to the documentation of this file.
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   //register your products
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   // do anything here that needs to be done at desctruction time
00036   // (e.g. close files, deallocate resources etc.)
00037 
00038 }
00039 
00040 
00041 //
00042 // member functions
00043 //
00044 
00045 //take the error matrix and rescale it or just replace it
00046 reco::TrackBase::CovarianceMatrix MuonErrorMatrixAdjuster::fix_cov_matrix(const reco::TrackBase::CovarianceMatrix& error_matrix,const GlobalVector& momentum)
00047 {   
00048   //CovarianceMatrix is template for SMatrix
00049   reco::TrackBase::CovarianceMatrix revised_matrix( theMatrixProvider->get(momentum));
00050    
00051   if( theRescale){
00052     //rescale old error matrix up by a factor
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   //scale term by term the matrix
00060   // the true type of the matrix is such that [i][j] is the same memory object as [j][i]: looping i:0-5, j:0-5 double multiply the terms
00061   // need to loop only on i:0-5, j:i-5
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   //divide term by term the matrix
00068   // the true type of the matrix is such that [i][j] is the same memory object as [j][i]: looping i:0-5, j:0-5 double multiply the terms
00069   // need to loop only on i:0-5, j:i-5
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   //get the parameters of the track so I can reconstruct it
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   //get the 5x5 matrix of recotrack/recotrack_orig
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   //copy the outer state. rescaling the error matrix
00114   reco::TrackBase::CovarianceMatrix outerCov(trackExtra_orig->outerStateCovariance());
00115   multiply(outerCov,scale_matrix);
00116 
00117   //copy the inner state, rescaling the error matrix
00118   reco::TrackBase::CovarianceMatrix innerCov(trackExtra_orig->innerStateCovariance());
00119   multiply(innerCov,scale_matrix);
00120 
00121   //put the trackExtra
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   //add a reference to the trackextra on the track
00129   recotrack.setExtra(edm::Ref<reco::TrackExtraCollection>( theRefprodTE, theTEi++));
00130   
00131   //return the reference to the last inserted then
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   //loop over the hits of the original track
00141   trackingRecHit_iterator recHit = recotrack_orig.recHitsBegin();
00142   unsigned int irh=0;
00143   for (; recHit!=recotrack_orig.recHitsEnd();++recHit){
00144     //clone it. this is meandatory
00145     TrackingRecHit * hit = (*recHit)->clone();
00146     
00147     //put it on the new track
00148     recotrack.setHitPattern(*hit,irh++);
00149     //copy them in the new collection
00150     RHcol.push_back(hit);
00151     //do something with the trackextra 
00152     trackextra.add(TrackingRecHitRef( theRefprodRH, theRHi++));
00153 
00154   }//loop over original rechits
00155   
00156   return true; //if nothing fails
00157 }
00158 
00159 bool MuonErrorMatrixAdjuster::selectTrack(const reco::Track & recotrack_orig){return true;}
00160 
00161 // ------------ method called to produce the data  ------------
00162 void
00163 MuonErrorMatrixAdjuster::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
00164 {
00165   using namespace edm;
00166 
00167   //open a collection of track
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   //get the mag field
00173   iSetup.get<IdealMagneticFieldRecord>().get( theField);
00174   
00175   //prepare the output collection
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   
00185   
00186   for(unsigned int it=0;it!=tracks->size();it++)
00187     {
00188       const reco::Track & recotrack_orig = (*tracks)[it];
00189       FreeTrajectoryState PCAstate = trajectoryStateTransform::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       //create a reco::Track
00194       reco::Track recotrack = makeTrack(recotrack_orig,PCAstate);
00195       
00196       //make a selection on the create reco::Track
00197       if (!selectTrack(recotrack)) continue;
00198       
00199       Toutput->push_back(recotrack);
00200       reco::Track & recotrackref = Toutput->back();
00201       
00202       //build the track extra
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         //pop the inserted track
00207         Toutput->pop_back();
00208         continue;}
00209       
00210       //attach the collection of rechits
00211       if (!attachRecHits(recotrack_orig,recotrackref,*extra,*TRHoutput)){
00212         edm::LogError( theCategory)<<"cannot attach any rechits on this track";
00213         //pop the inserted track
00214         Toutput->pop_back();
00215         //pop the track extra
00216         TEoutput->pop_back();
00217         theTEi--;
00218         continue;}
00219       
00220     }//loop over the original reco tracks
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 // ------------ method called once each job just before starting event loop  ------------
00231 void 
00232 MuonErrorMatrixAdjuster::beginJob()
00233 {
00234   theMatrixProvider = new MuonErrorMatrix(theMatrixProvider_pset);
00235 }
00236 
00237 // ------------ method called once each job just after ending the event loop  ------------
00238 void 
00239 MuonErrorMatrixAdjuster::endJob() {
00240   if ( theMatrixProvider) delete theMatrixProvider;
00241 }