00001
00002
00003
00004
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <memory>
00022
00023
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
00043
00044 MuonTimingFiller::MuonTimingFiller(const edm::ParameterSet& iConfig)
00045 {
00046
00047 edm::ParameterSet dtTimingParameters = iConfig.getParameter<edm::ParameterSet>("DTTimingParameters");
00048 theDTTimingExtractor_ = new DTTimingExtractor(dtTimingParameters);
00049
00050
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
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
00089 fillTimeFromMeasurements(dtTmSeq, dtTime);
00090
00091
00092 fillTimeFromMeasurements(cscTmSeq, cscTime);
00093
00094
00095 TimeMeasurementSequence combinedTmSeq;
00096 combineTMSequences(muon,dtTmSeq,cscTmSeq,combinedTmSeq);
00097
00098 if (useECAL_) addEcalTime(muon,combinedTmSeq);
00099
00100
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
00199
00200 if (muonE.emMax<ecalEcut_) return;
00201
00202
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