CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoMuon/MuonIdentification/src/CSCTimingExtractor.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    MuonIdentification
00004 // Class:      CSCTimingExtractor
00005 // 
00011 //
00012 // Original Author:  Traczyk Piotr
00013 //         Created:  Thu Oct 11 15:01:28 CEST 2007
00014 // $Id: CSCTimingExtractor.cc,v 1.10 2011/04/16 20:30:57 ptraczyk Exp $
00015 //
00016 //
00017 
00018 #include "RecoMuon/MuonIdentification/interface/CSCTimingExtractor.h"
00019 
00020 
00021 // user include files
00022 #include "FWCore/Framework/interface/Frameworkfwd.h"
00023 #include "FWCore/Framework/interface/EDProducer.h"
00024 
00025 #include "FWCore/Framework/interface/Event.h"
00026 #include "FWCore/Framework/interface/MakerMacros.h"
00027 
00028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00029 
00030 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00031 
00032 #include "Geometry/Records/interface/MuonGeometryRecord.h"
00033 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00034 
00035 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
00036 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
00037 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00038 
00039 #include "DataFormats/MuonReco/interface/Muon.h"
00040 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00041 #include "DataFormats/CSCRecHit/interface/CSCSegment.h"
00042 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00043 #include "DataFormats/CSCRecHit/interface/CSCRecHit2D.h"
00044 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00045 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00046 
00047 #include "DataFormats/TrackReco/interface/Track.h"
00048 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00049 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00050 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00051 
00052 
00053 // system include files
00054 #include <memory>
00055 #include <vector>
00056 #include <string>
00057 #include <iostream>
00058 
00059 namespace edm {
00060   class ParameterSet;
00061   class EventSetup;
00062   class InputTag;
00063 }
00064 
00065 class MuonServiceProxy;
00066 
00067 //
00068 // constructors and destructor
00069 //
00070 CSCTimingExtractor::CSCTimingExtractor(const edm::ParameterSet& iConfig)
00071   :
00072   CSCSegmentTags_(iConfig.getParameter<edm::InputTag>("CSCsegments")),
00073   thePruneCut_(iConfig.getParameter<double>("PruneCut")),
00074   theStripTimeOffset_(iConfig.getParameter<double>("CSCStripTimeOffset")),
00075   theWireTimeOffset_(iConfig.getParameter<double>("CSCWireTimeOffset")),
00076   theStripError_(iConfig.getParameter<double>("CSCStripError")),
00077   theWireError_(iConfig.getParameter<double>("CSCWireError")),
00078   UseWireTime(iConfig.getParameter<bool>("UseWireTime")),
00079   UseStripTime(iConfig.getParameter<bool>("UseStripTime")),
00080   debug(iConfig.getParameter<bool>("debug"))
00081 {
00082   edm::ParameterSet serviceParameters = iConfig.getParameter<edm::ParameterSet>("ServiceParameters");
00083   theService = new MuonServiceProxy(serviceParameters);
00084   
00085   edm::ParameterSet matchParameters = iConfig.getParameter<edm::ParameterSet>("MatchParameters");
00086 
00087   theMatcher = new MuonSegmentMatcher(matchParameters, theService);
00088 }
00089 
00090 
00091 CSCTimingExtractor::~CSCTimingExtractor()
00092 {
00093   if (theService) delete theService;
00094   if (theMatcher) delete theMatcher;
00095 }
00096 
00097 
00098 //
00099 // member functions
00100 //
00101 
00102 // ------------ method called to produce the data  ------------
00103 void
00104 CSCTimingExtractor::fillTiming(TimeMeasurementSequence &tmSequence, reco::TrackRef muonTrack, const edm::Event& iEvent, const edm::EventSetup& iSetup)
00105 {
00106 
00107   if (debug) 
00108     std::cout << " *** CSC Timimng Extractor ***" << std::endl;
00109 
00110   theService->update(iSetup);
00111 
00112   const GlobalTrackingGeometry *theTrackingGeometry = &*theService->trackingGeometry();
00113   
00114   edm::ESHandle<Propagator> propagator;
00115   iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny", propagator);
00116   const Propagator *propag = propagator.product();
00117 
00118   double invbeta=0;
00119   double invbetaerr=0;
00120   double totalWeightInvbeta=0;
00121   double totalWeightVertex=0;
00122   std::vector<TimeMeasurement> tms;
00123 
00124   math::XYZPoint  pos=muonTrack->innerPosition();
00125   math::XYZVector mom=muonTrack->innerMomentum();
00126 
00127   if (sqrt(muonTrack->innerPosition().mag2()) > sqrt(muonTrack->outerPosition().mag2())){
00128      pos=muonTrack->outerPosition();
00129      mom=-1*muonTrack->outerMomentum();
00130   }
00131 
00132   GlobalPoint  posp(pos.x(), pos.y(), pos.z());
00133   GlobalVector momv(mom.x(), mom.y(), mom.z());
00134   FreeTrajectoryState muonFTS(posp, momv, (TrackCharge)muonTrack->charge(), theService->magneticField().product());
00135 
00136   // get the CSC segments that were used to construct the muon
00137   std::vector<const CSCSegment*> range = theMatcher->matchCSC(*muonTrack,iEvent);
00138 
00139   // create a collection on TimeMeasurements for the track        
00140   for (std::vector<const CSCSegment*>::iterator rechit = range.begin(); rechit!=range.end();++rechit) {
00141 
00142     // Create the ChamberId
00143     DetId id = (*rechit)->geographicalId();
00144     CSCDetId chamberId(id.rawId());
00145     //    int station = chamberId.station();
00146 
00147     if (!(*rechit)->specificRecHits().size()) continue;
00148 
00149     const std::vector<CSCRecHit2D> hits2d = (*rechit)->specificRecHits();
00150 
00151     // store all the hits from the segment
00152     for (std::vector<CSCRecHit2D>::const_iterator hiti=hits2d.begin(); hiti!=hits2d.end(); hiti++) {
00153 
00154       const GeomDet* cscDet = theTrackingGeometry->idToDet(hiti->geographicalId());
00155       TimeMeasurement thisHit;
00156 
00157       std::pair< TrajectoryStateOnSurface, double> tsos;
00158       tsos=propag->propagateWithPath(muonFTS,cscDet->surface());
00159 
00160       double dist;            
00161       if (tsos.first.isValid()) dist = tsos.second+posp.mag(); 
00162         else dist = cscDet->toGlobal(hiti->localPosition()).mag();
00163 
00164       thisHit.distIP = dist;
00165       if (UseStripTime) {
00166         thisHit.weightInvbeta = dist*dist/(theStripError_*theStripError_*30.*30.);
00167         thisHit.weightVertex = 1./(theStripError_*theStripError_);
00168         thisHit.timeCorr = hiti->tpeak()-theStripTimeOffset_;
00169         tms.push_back(thisHit);
00170       }
00171 
00172       if (UseWireTime) {
00173         thisHit.weightInvbeta = dist*dist/(theWireError_*theWireError_*30.*30.);
00174         thisHit.weightVertex = 1./(theWireError_*theWireError_);
00175         thisHit.timeCorr = hiti->wireTime()-theWireTimeOffset_;
00176         tms.push_back(thisHit);
00177       }
00178 
00179       
00180 //      std::cout << " CSC Hit. Dist= " << dist << "    Time= " << thisHit.timeCorr 
00181 //           << "   invBeta= " << (1.+thisHit.timeCorr/dist*30.) << std::endl;
00182     }
00183 
00184   } // rechit
00185       
00186   bool modified = false;
00187   std::vector <double> dstnc, dsegm, dtraj, hitWeightInvbeta, hitWeightVertex;
00188 
00189   // Now loop over the measurements, calculate 1/beta and cut away outliers
00190   do {    
00191 
00192     modified = false;
00193     dstnc.clear();
00194     dsegm.clear();
00195     dtraj.clear();
00196     hitWeightInvbeta.clear();
00197     hitWeightVertex.clear();
00198       
00199     totalWeightInvbeta=0;
00200     totalWeightVertex=0;
00201       
00202         for (std::vector<TimeMeasurement>::iterator tm=tms.begin(); tm!=tms.end(); ++tm) {
00203           dstnc.push_back(tm->distIP);
00204           dsegm.push_back(tm->timeCorr);
00205           hitWeightInvbeta.push_back(tm->weightInvbeta);
00206           hitWeightVertex.push_back(tm->weightVertex);
00207           totalWeightInvbeta+=tm->weightInvbeta;
00208           totalWeightVertex+=tm->weightVertex;
00209         }
00210           
00211     if (totalWeightInvbeta==0) break;        
00212 
00213     // calculate the value and error of 1/beta from the complete set of 1D hits
00214     if (debug)
00215       std::cout << " Points for global fit: " << dstnc.size() << std::endl;
00216 
00217     // inverse beta - weighted average of the contributions from individual hits
00218     invbeta=0;
00219     for (unsigned int i=0;i<dstnc.size();i++) 
00220       invbeta+=(1.+dsegm.at(i)/dstnc.at(i)*30.)*hitWeightInvbeta.at(i)/totalWeightInvbeta;
00221 
00222     double chimax=0.;
00223     std::vector<TimeMeasurement>::iterator tmmax;
00224     
00225     // the dispersion of inverse beta
00226     double diff;
00227     for (unsigned int i=0;i<dstnc.size();i++) {
00228       diff=(1.+dsegm.at(i)/dstnc.at(i)*30.)-invbeta;
00229       diff=diff*diff*hitWeightInvbeta.at(i);
00230       invbetaerr+=diff;
00231       if (diff>chimax) { 
00232         tmmax=tms.begin()+i;
00233         chimax=diff;
00234       }
00235     }
00236     
00237     invbetaerr=sqrt(invbetaerr/totalWeightInvbeta); 
00238  
00239     // cut away the outliers
00240     if (chimax>thePruneCut_) {
00241       tms.erase(tmmax);
00242       modified=true;
00243     }    
00244 
00245     if (debug)
00246       std::cout << " Measured 1/beta: " << invbeta << " +/- " << invbetaerr << std::endl;
00247 
00248   } while (modified);
00249 
00250   // std::cout << " *** FINAL Measured 1/beta: " << invbeta << " +/- " << invbetaerr << std::endl;
00251 
00252   for (unsigned int i=0;i<dstnc.size();i++) {
00253     tmSequence.dstnc.push_back(dstnc.at(i));
00254     tmSequence.local_t0.push_back(dsegm.at(i));
00255     tmSequence.weightInvbeta.push_back(hitWeightInvbeta.at(i));
00256     tmSequence.weightVertex.push_back(hitWeightVertex.at(i));
00257   }
00258 
00259   tmSequence.totalWeightInvbeta=totalWeightInvbeta;
00260   tmSequence.totalWeightVertex=totalWeightVertex;
00261 
00262 }
00263 
00264 //define this as a plug-in
00265 //DEFINE_FWK_MODULE(CSCTimingExtractor);