CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoMuon/MuonIdentification/src/MuonTimingFiller.cc

Go to the documentation of this file.
00001 //
00002 // Package:    MuonTimingFiller
00003 // Class:      MuonTimingFiller
00004 // 
00012 //
00013 // Original Author:  Piotr Traczyk, CERN
00014 //         Created:  Mon Mar 16 12:27:22 CET 2009
00015 // $Id: MuonTimingFiller.cc,v 1.9 2010/03/25 14:08:50 jribnik Exp $
00016 //
00017 //
00018 
00019 
00020 // system include files
00021 #include <memory>
00022 
00023 // user include files
00024 #include "FWCore/Framework/interface/Frameworkfwd.h"
00025 #include "FWCore/Framework/interface/EDProducer.h"
00026 
00027 #include "FWCore/Framework/interface/Event.h"
00028 #include "FWCore/Framework/interface/MakerMacros.h"
00029 
00030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00031 
00032 #include "DataFormats/MuonReco/interface/Muon.h" 
00033 #include "DataFormats/MuonReco/interface/MuonFwd.h" 
00034 #include "DataFormats/MuonReco/interface/MuonTimeExtra.h"
00035 #include "DataFormats/MuonReco/interface/MuonTimeExtraMap.h"
00036 
00037 #include "RecoMuon/MuonIdentification/interface/MuonTimingFiller.h"
00038 #include "RecoMuon/MuonIdentification/interface/TimeMeasurementSequence.h"
00039 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00040 
00041 //
00042 // constructors and destructor
00043 //
00044 MuonTimingFiller::MuonTimingFiller(const edm::ParameterSet& iConfig)
00045 {
00046    // Load parameters for the DTTimingExtractor
00047    edm::ParameterSet dtTimingParameters = iConfig.getParameter<edm::ParameterSet>("DTTimingParameters");
00048    theDTTimingExtractor_ = new DTTimingExtractor(dtTimingParameters);
00049 
00050    // Load parameters for the CSCTimingExtractor
00051    edm::ParameterSet cscTimingParameters = iConfig.getParameter<edm::ParameterSet>("CSCTimingParameters");
00052    theCSCTimingExtractor_ = new CSCTimingExtractor(cscTimingParameters);
00053    
00054    errorDT_ = iConfig.getParameter<double>("ErrorDT");
00055    errorCSC_ = iConfig.getParameter<double>("ErrorCSC");
00056    errorEB_ = iConfig.getParameter<double>("ErrorEB");
00057    errorEE_ = iConfig.getParameter<double>("ErrorEE");
00058    ecalEcut_ = iConfig.getParameter<double>("EcalEnergyCut");
00059    
00060    useDT_ = iConfig.getParameter<bool>("UseDT");
00061    useCSC_ = iConfig.getParameter<bool>("UseCSC");
00062    useECAL_ = iConfig.getParameter<bool>("UseECAL");
00063    
00064 }
00065 
00066 
00067 MuonTimingFiller::~MuonTimingFiller()
00068 {
00069   if (theDTTimingExtractor_) delete theDTTimingExtractor_;
00070   if (theCSCTimingExtractor_) delete theCSCTimingExtractor_;
00071 }
00072 
00073 
00074 //
00075 // member functions
00076 //
00077 
00078 void 
00079 MuonTimingFiller::fillTiming( const reco::Muon& muon, reco::MuonTimeExtra& dtTime, reco::MuonTimeExtra& cscTime, reco::MuonTimeExtra& combinedTime, edm::Event& iEvent, const edm::EventSetup& iSetup )
00080 {
00081   TimeMeasurementSequence dtTmSeq,cscTmSeq;
00082      
00083   if ( !(muon.standAloneMuon().isNull()) ) {
00084     theDTTimingExtractor_->fillTiming(dtTmSeq, muon.standAloneMuon(), iEvent, iSetup);
00085     theCSCTimingExtractor_->fillTiming(cscTmSeq, muon.standAloneMuon(), iEvent, iSetup);
00086   }
00087   
00088   // Fill DT-specific timing information block     
00089   fillTimeFromMeasurements(dtTmSeq, dtTime);
00090 
00091   // Fill CSC-specific timing information block     
00092   fillTimeFromMeasurements(cscTmSeq, cscTime);
00093        
00094   // Combine the TimeMeasurementSequences from all subdetectors
00095   TimeMeasurementSequence combinedTmSeq;
00096   combineTMSequences(muon,dtTmSeq,cscTmSeq,combinedTmSeq);
00097   // add ECAL info
00098   if (useECAL_) addEcalTime(muon,combinedTmSeq);
00099 
00100   // Fill the master timing block
00101   fillTimeFromMeasurements(combinedTmSeq, combinedTime);
00102     
00103   LogTrace("MuonTime") << "Global 1/beta: " << combinedTime.inverseBeta() << " +/- " << combinedTime.inverseBetaErr()<<std::endl;
00104   LogTrace("MuonTime") << "  Free 1/beta: " << combinedTime.freeInverseBeta() << " +/- " << combinedTime.freeInverseBetaErr()<<std::endl;
00105   LogTrace("MuonTime") << "  Vertex time (in-out): " << combinedTime.timeAtIpInOut() << " +/- " << combinedTime.timeAtIpInOutErr()
00106                        << "  # of points: " << combinedTime.nDof() <<std::endl;
00107   LogTrace("MuonTime") << "  Vertex time (out-in): " << combinedTime.timeAtIpOutIn() << " +/- " << combinedTime.timeAtIpOutInErr()<<std::endl;
00108   LogTrace("MuonTime") << "  direction: "   << combinedTime.direction() << std::endl;
00109      
00110 }
00111 
00112 
00113 void 
00114 MuonTimingFiller::fillTimeFromMeasurements( TimeMeasurementSequence tmSeq, reco::MuonTimeExtra &muTime ) {
00115 
00116   std::vector <double> x,y;
00117   double invbeta=0, invbetaerr=0;
00118   double vertexTime=0, vertexTimeErr=0, vertexTimeR=0, vertexTimeRErr=0;    
00119   double freeBeta, freeBetaErr, freeTime, freeTimeErr;
00120 
00121   if (tmSeq.dstnc.size()<=1) return;
00122 
00123   for (unsigned int i=0;i<tmSeq.dstnc.size();i++) {
00124     invbeta+=(1.+tmSeq.local_t0.at(i)/tmSeq.dstnc.at(i)*30.)*tmSeq.weight.at(i)/tmSeq.totalWeight;
00125     x.push_back(tmSeq.dstnc.at(i)/30.);
00126     y.push_back(tmSeq.local_t0.at(i)+tmSeq.dstnc.at(i)/30.);
00127     vertexTime+=tmSeq.local_t0.at(i)*tmSeq.weight.at(i)/tmSeq.totalWeight;
00128     vertexTimeR+=(tmSeq.local_t0.at(i)+2*tmSeq.dstnc.at(i)/30.)*tmSeq.weight.at(i)/tmSeq.totalWeight;
00129   }
00130 
00131   double diff;
00132   for (unsigned int i=0;i<tmSeq.dstnc.size();i++) {
00133     diff=(1.+tmSeq.local_t0.at(i)/tmSeq.dstnc.at(i)*30.)-invbeta;
00134     invbetaerr+=diff*diff*tmSeq.weight.at(i);
00135     diff=tmSeq.local_t0.at(i)-vertexTime;
00136     vertexTimeErr+=diff*diff*tmSeq.weight.at(i);
00137     diff=tmSeq.local_t0.at(i)+2*tmSeq.dstnc.at(i)/30.-vertexTimeR;
00138     vertexTimeRErr+=diff*diff*tmSeq.weight.at(i);
00139   }
00140   
00141   double cf = 1./(tmSeq.dstnc.size()-1);
00142   invbetaerr=sqrt(invbetaerr/tmSeq.totalWeight*cf);
00143   vertexTimeErr=sqrt(vertexTimeErr/tmSeq.totalWeight*cf);
00144   vertexTimeRErr=sqrt(vertexTimeRErr/tmSeq.totalWeight*cf);
00145 
00146   muTime.setInverseBeta(invbeta);
00147   muTime.setInverseBetaErr(invbetaerr);
00148   muTime.setTimeAtIpInOut(vertexTime);
00149   muTime.setTimeAtIpInOutErr(vertexTimeErr);
00150   muTime.setTimeAtIpOutIn(vertexTimeR);
00151   muTime.setTimeAtIpOutInErr(vertexTimeRErr);
00152       
00153   rawFit(freeBeta, freeBetaErr, freeTime, freeTimeErr, x, y);
00154 
00155   muTime.setFreeInverseBeta(freeBeta);
00156   muTime.setFreeInverseBetaErr(freeBetaErr);
00157     
00158   muTime.setNDof(tmSeq.dstnc.size());
00159 }
00160 
00161 void 
00162 MuonTimingFiller::combineTMSequences( const reco::Muon& muon, 
00163                                       TimeMeasurementSequence dtSeq, 
00164                                       TimeMeasurementSequence cscSeq, 
00165                                       TimeMeasurementSequence &cmbSeq ) {
00166   double hitWeight;
00167                                         
00168   if (useDT_) for (unsigned int i=0;i<dtSeq.dstnc.size();i++) {
00169     hitWeight=dtSeq.weight.at(i) / (errorDT_*errorDT_);
00170     
00171     cmbSeq.dstnc.push_back(dtSeq.dstnc.at(i));
00172     cmbSeq.local_t0.push_back(dtSeq.local_t0.at(i));
00173     cmbSeq.weight.push_back(hitWeight);
00174 
00175     cmbSeq.totalWeight+=hitWeight;
00176   }
00177 
00178   if (useCSC_) for (unsigned int i=0;i<cscSeq.dstnc.size();i++) {
00179     hitWeight=1./(errorCSC_*errorCSC_);
00180  
00181     cmbSeq.dstnc.push_back(cscSeq.dstnc.at(i));
00182     cmbSeq.local_t0.push_back(cscSeq.local_t0.at(i));
00183     cmbSeq.weight.push_back(hitWeight);
00184 
00185     cmbSeq.totalWeight+=hitWeight;
00186   }
00187 }
00188 
00189 
00190 void 
00191 MuonTimingFiller::addEcalTime( const reco::Muon& muon, 
00192                                TimeMeasurementSequence &cmbSeq ) {
00193 
00194   reco::MuonEnergy muonE;
00195   if (muon.isEnergyValid())  
00196     muonE = muon.calEnergy();
00197   
00198   // Cut on the crystal energy and restrict to the ECAL barrel for now
00199 //  if (muonE.emMax<ecalEcut_ || fabs(muon.eta())>1.5) return;    
00200   if (muonE.emMax<ecalEcut_) return;    
00201   
00202   // A simple parametrization of the error on the ECAL time measurement
00203   double emErr;
00204   if (muonE.ecal_id.subdetId()==EcalBarrel) emErr= errorEB_/muonE.emMax; else
00205     emErr=errorEE_/muonE.emMax;
00206   double hitWeight = 1/(emErr*emErr);
00207         
00208   cmbSeq.local_t0.push_back(muonE.ecal_time);
00209   cmbSeq.weight.push_back(hitWeight);
00210 
00211   cmbSeq.dstnc.push_back(muonE.ecal_position.r());
00212   
00213   cmbSeq.totalWeight+=hitWeight;
00214                                       
00215 }
00216 
00217 
00218 
00219 void 
00220 MuonTimingFiller::rawFit(double &a, double &da, double &b, double &db, const std::vector<double> hitsx, const std::vector<double> hitsy) {
00221 
00222   double s=0,sx=0,sy=0,x,y;
00223   double sxx=0,sxy=0;
00224 
00225   a=b=0;
00226   if (hitsx.size()==0) return;
00227   if (hitsx.size()==1) {
00228     b=hitsy[0];
00229   } else {
00230     for (unsigned int i = 0; i != hitsx.size(); i++) {
00231       x=hitsx[i];
00232       y=hitsy[i];
00233       sy += y;
00234       sxy+= x*y;
00235       s += 1.;
00236       sx += x;
00237       sxx += x*x;
00238     }
00239 
00240     double d = s*sxx - sx*sx;
00241     b = (sxx*sy- sx*sxy)/ d;
00242     a = (s*sxy - sx*sy) / d;
00243     da = sqrt(sxx/d);
00244     db = sqrt(s/d);
00245   }
00246 }
00247