00001
00002
00003
00004
00005
00011
00012
00013
00014
00015
00016
00017
00018 #include "RecoMuon/MuonIdentification/interface/DTTimingExtractor.h"
00019
00020
00021
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 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00035 #include "Geometry/DTGeometry/interface/DTLayer.h"
00036 #include "Geometry/DTGeometry/interface/DTChamber.h"
00037 #include "Geometry/DTGeometry/interface/DTSuperLayer.h"
00038 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
00039 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
00040
00041 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
00042 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
00043 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00044
00045 #include "DataFormats/MuonReco/interface/Muon.h"
00046 #include "DataFormats/MuonReco/interface/MuonFwd.h"
00047 #include "DataFormats/DTRecHit/interface/DTRecSegment2D.h"
00048 #include "DataFormats/DTRecHit/interface/DTRecSegment4DCollection.h"
00049 #include "DataFormats/DTRecHit/interface/DTRecSegment2DCollection.h"
00050 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00051 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00052
00053 #include "DataFormats/TrackReco/interface/Track.h"
00054 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00055 #include "DataFormats/TrackReco/interface/TrackExtra.h"
00056 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00057
00058
00059
00060 #include <memory>
00061 #include <vector>
00062 #include <string>
00063 #include <iostream>
00064
00065 namespace edm {
00066 class ParameterSet;
00067 class EventSetup;
00068 class InputTag;
00069 }
00070
00071 class MuonServiceProxy;
00072
00073
00074
00075
00076 DTTimingExtractor::DTTimingExtractor(const edm::ParameterSet& iConfig)
00077 :
00078 DTSegmentTags_(iConfig.getParameter<edm::InputTag>("DTsegments")),
00079 theHitsMin_(iConfig.getParameter<int>("HitsMin")),
00080 thePruneCut_(iConfig.getParameter<double>("PruneCut")),
00081 theTimeOffset_(iConfig.getParameter<double>("DTTimeOffset")),
00082 useSegmentT0_(iConfig.getParameter<bool>("UseSegmentT0")),
00083 doWireCorr_(iConfig.getParameter<bool>("DoWireCorr")),
00084 requireBothProjections_(iConfig.getParameter<bool>("RequireBothProjections")),
00085 debug(iConfig.getParameter<bool>("debug"))
00086 {
00087 edm::ParameterSet serviceParameters = iConfig.getParameter<edm::ParameterSet>("ServiceParameters");
00088 theService = new MuonServiceProxy(serviceParameters);
00089
00090 edm::ParameterSet matchParameters = iConfig.getParameter<edm::ParameterSet>("MatchParameters");
00091
00092 theMatcher = new MuonSegmentMatcher(matchParameters, theService);
00093 }
00094
00095
00096 DTTimingExtractor::~DTTimingExtractor()
00097 {
00098 if (theService) delete theService;
00099 if (theMatcher) delete theMatcher;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108 void
00109 DTTimingExtractor::fillTiming(TimeMeasurementSequence &tmSequence, reco::TrackRef muonTrack, const edm::Event& iEvent, const edm::EventSetup& iSetup)
00110 {
00111
00112
00113
00114 if (debug)
00115 std::cout << " *** Muon Timimng Extractor ***" << std::endl;
00116
00117 theService->update(iSetup);
00118
00119 const GlobalTrackingGeometry *theTrackingGeometry = &*theService->trackingGeometry();
00120
00121
00122 edm::ESHandle<DTGeometry> theDTGeom;
00123 iSetup.get<MuonGeometryRecord>().get(theDTGeom);
00124
00125 edm::ESHandle<Propagator> propagator;
00126 iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny", propagator);
00127 const Propagator *propag = propagator.product();
00128
00129 double invbeta=0;
00130 double invbetaerr=0;
00131 int totalWeight=0;
00132 std::vector<TimeMeasurement> tms;
00133
00134 math::XYZPoint pos=muonTrack->innerPosition();
00135 math::XYZVector mom=muonTrack->innerMomentum();
00136 GlobalPoint posp(pos.x(), pos.y(), pos.z());
00137 GlobalVector momv(mom.x(), mom.y(), mom.z());
00138 FreeTrajectoryState muonFTS(posp, momv, (TrackCharge)muonTrack->charge(), theService->magneticField().product());
00139
00140
00141 std::vector<const DTRecSegment4D*> range = theMatcher->matchDT(*muonTrack,iEvent);
00142
00143
00144 for (std::vector<const DTRecSegment4D*>::iterator rechit = range.begin(); rechit!=range.end();++rechit) {
00145
00146
00147 DetId id = (*rechit)->geographicalId();
00148 DTChamberId chamberId(id.rawId());
00149 int station = chamberId.station();
00150
00151
00152 bool bothProjections = ( ((*rechit)->hasPhi()) && ((*rechit)->hasZed()) );
00153 if (requireBothProjections_ && !bothProjections) continue;
00154
00155
00156 for (int phi=0; phi<2; phi++) {
00157
00158 const DTRecSegment2D* segm;
00159 if (phi) segm = dynamic_cast<const DTRecSegment2D*>((*rechit)->phiSegment());
00160 else segm = dynamic_cast<const DTRecSegment2D*>((*rechit)->zSegment());
00161
00162 if(segm == 0) continue;
00163 if (!segm->specificRecHits().size()) continue;
00164
00165 const GeomDet* geomDet = theTrackingGeometry->idToDet(segm->geographicalId());
00166 const std::vector<DTRecHit1D> hits1d = segm->specificRecHits();
00167
00168
00169 for (std::vector<DTRecHit1D>::const_iterator hiti=hits1d.begin(); hiti!=hits1d.end(); hiti++) {
00170
00171 const GeomDet* dtcell = theTrackingGeometry->idToDet(hiti->geographicalId());
00172 TimeMeasurement thisHit;
00173
00174 std::pair< TrajectoryStateOnSurface, double> tsos;
00175 tsos=propag->propagateWithPath(muonFTS,dtcell->surface());
00176
00177 double dist;
00178 if (tsos.first.isValid()) dist = tsos.second+posp.mag();
00179 else dist = dtcell->toGlobal(hiti->localPosition()).mag();
00180
00181 thisHit.driftCell = hiti->geographicalId();
00182 if (hiti->lrSide()==DTEnums::Left) thisHit.isLeft=true; else thisHit.isLeft=false;
00183 thisHit.isPhi = phi;
00184 thisHit.posInLayer = geomDet->toLocal(dtcell->toGlobal(hiti->localPosition())).x();
00185 thisHit.distIP = dist;
00186 thisHit.station = station;
00187 if (useSegmentT0_ && segm->ist0Valid()) thisHit.timeCorr=segm->t0();
00188 else thisHit.timeCorr=0.;
00189 thisHit.timeCorr += theTimeOffset_;
00190
00191
00192
00193 if (doWireCorr_ && !bothProjections && tsos.first.isValid()) {
00194 const DTLayer* layer = theDTGeom->layer(hiti->wireId());
00195 float propgL = layer->toLocal( tsos.first.globalPosition() ).y();
00196 float wirePropCorr = propgL/24.4*0.00543;
00197 if (thisHit.isLeft) wirePropCorr=-wirePropCorr;
00198 thisHit.posInLayer += wirePropCorr;
00199 }
00200
00201 tms.push_back(thisHit);
00202 }
00203 }
00204 }
00205
00206 bool modified = false;
00207 std::vector <double> dstnc, dsegm, dtraj, hitWeight, left;
00208
00209
00210 do {
00211
00212 modified = false;
00213 dstnc.clear();
00214 dsegm.clear();
00215 dtraj.clear();
00216 hitWeight.clear();
00217 left.clear();
00218
00219 std::vector <int> hit_idx;
00220 totalWeight=0;
00221
00222
00223 for (int sta=1;sta<5;sta++)
00224 for (int phi=0;phi<2;phi++) {
00225 std::vector <TimeMeasurement> seg;
00226 std::vector <int> seg_idx;
00227 int tmpos=0;
00228 for (std::vector<TimeMeasurement>::iterator tm=tms.begin(); tm!=tms.end(); ++tm) {
00229 if ((tm->station==sta) && (tm->isPhi==phi)) {
00230 seg.push_back(*tm);
00231 seg_idx.push_back(tmpos);
00232 }
00233 tmpos++;
00234 }
00235
00236 unsigned int segsize = seg.size();
00237
00238 if (segsize<theHitsMin_) continue;
00239
00240 double a=0, b=0;
00241 std::vector <double> hitxl,hitxr,hityl,hityr;
00242
00243 for (std::vector<TimeMeasurement>::iterator tm=seg.begin(); tm!=seg.end(); ++tm) {
00244
00245 DetId id = tm->driftCell;
00246 const GeomDet* dtcell = theTrackingGeometry->idToDet(id);
00247 DTChamberId chamberId(id.rawId());
00248 const GeomDet* dtcham = theTrackingGeometry->idToDet(chamberId);
00249
00250 double celly=dtcham->toLocal(dtcell->position()).z();
00251
00252 if (tm->isLeft) {
00253 hitxl.push_back(celly);
00254 hityl.push_back(tm->posInLayer);
00255 } else {
00256 hitxr.push_back(celly);
00257 hityr.push_back(tm->posInLayer);
00258 }
00259 }
00260
00261 if (!fitT0(a,b,hitxl,hityl,hitxr,hityr)) {
00262 if (debug)
00263 std::cout << " t0 = zero, Left hits: " << hitxl.size() << " Right hits: " << hitxr.size() << std::endl;
00264 continue;
00265 }
00266
00267
00268 if ((!hitxl.size()) || (!hityl.size())) continue;
00269
00270 int segidx=0;
00271 for (std::vector<TimeMeasurement>::const_iterator tm=seg.begin(); tm!=seg.end(); ++tm) {
00272
00273 DetId id = tm->driftCell;
00274 const GeomDet* dtcell = theTrackingGeometry->idToDet(id);
00275 DTChamberId chamberId(id.rawId());
00276 const GeomDet* dtcham = theTrackingGeometry->idToDet(chamberId);
00277
00278 double layerZ = dtcham->toLocal(dtcell->position()).z();
00279 double segmLocalPos = b+layerZ*a;
00280 double hitLocalPos = tm->posInLayer;
00281 int hitSide = -tm->isLeft*2+1;
00282 double t0_segm = (-(hitSide*segmLocalPos)+(hitSide*hitLocalPos))/0.00543+tm->timeCorr;
00283
00284 dstnc.push_back(tm->distIP);
00285 dsegm.push_back(t0_segm);
00286 left.push_back(hitSide);
00287 hitWeight.push_back(((double)seg.size()-2.)/(double)seg.size());
00288 hit_idx.push_back(seg_idx.at(segidx));
00289 segidx++;
00290 }
00291
00292 totalWeight+=seg.size()-2;
00293 }
00294
00295 if (totalWeight==0) break;
00296
00297
00298 if (debug)
00299 std::cout << " Points for global fit: " << dstnc.size() << std::endl;
00300
00301
00302 invbeta=0;
00303 for (unsigned int i=0;i<dstnc.size();i++)
00304 invbeta+=(1.+dsegm.at(i)/dstnc.at(i)*30.)*hitWeight.at(i)/totalWeight;
00305
00306 double chimax=0.;
00307 std::vector<TimeMeasurement>::iterator tmmax;
00308
00309
00310 double diff;
00311 for (unsigned int i=0;i<dstnc.size();i++) {
00312 diff=(1.+dsegm.at(i)/dstnc.at(i)*30.)-invbeta;
00313 diff=diff*diff*hitWeight.at(i);
00314 invbetaerr+=diff;
00315 if (diff/totalWeight>chimax) {
00316 tmmax=tms.begin()+hit_idx.at(i);
00317 chimax=diff;
00318 }
00319 }
00320
00321 invbetaerr=sqrt(invbetaerr/totalWeight);
00322
00323
00324 if (chimax>thePruneCut_) {
00325 tms.erase(tmmax);
00326 modified=true;
00327 }
00328
00329 if (debug)
00330 std::cout << " Measured 1/beta: " << invbeta << " +/- " << invbetaerr << std::endl;
00331
00332 } while (modified);
00333
00334 for (unsigned int i=0;i<dstnc.size();i++) {
00335 tmSequence.dstnc.push_back(dstnc.at(i));
00336 tmSequence.local_t0.push_back(dsegm.at(i));
00337 tmSequence.weight.push_back(hitWeight.at(i));
00338 }
00339
00340 tmSequence.totalWeight=totalWeight;
00341
00342 }
00343
00344 double
00345 DTTimingExtractor::fitT0(double &a, double &b, std::vector<double> xl, std::vector<double> yl, std::vector<double> xr, std::vector<double> yr ) {
00346
00347 double sx=0,sy=0,sxy=0,sxx=0,ssx=0,ssy=0,s=0,ss=0;
00348
00349 for (unsigned int i=0; i<xl.size(); i++) {
00350 sx+=xl[i];
00351 sy+=yl[i];
00352 sxy+=xl[i]*yl[i];
00353 sxx+=xl[i]*xl[i];
00354 s++;
00355 ssx+=xl[i];
00356 ssy+=yl[i];
00357 ss++;
00358 }
00359
00360 for (unsigned int i=0; i<xr.size(); i++) {
00361 sx+=xr[i];
00362 sy+=yr[i];
00363 sxy+=xr[i]*yr[i];
00364 sxx+=xr[i]*xr[i];
00365 s++;
00366 ssx-=xr[i];
00367 ssy-=yr[i];
00368 ss--;
00369 }
00370
00371 double delta = ss*ss*sxx+s*sx*sx+s*ssx*ssx-s*s*sxx-2*ss*sx*ssx;
00372
00373 double t0_corr=0.;
00374
00375 if (delta) {
00376 a=(ssy*s*ssx+sxy*ss*ss+sy*sx*s-sy*ss*ssx-ssy*sx*ss-sxy*s*s)/delta;
00377 b=(ssx*sy*ssx+sxx*ssy*ss+sx*sxy*s-sxx*sy*s-ssx*sxy*ss-sx*ssy*ssx)/delta;
00378 t0_corr=(ssx*s*sxy+sxx*ss*sy+sx*sx*ssy-sxx*s*ssy-sx*ss*sxy-ssx*sx*sy)/delta;
00379 }
00380
00381
00382 t0_corr/=-0.00543;
00383
00384 return t0_corr;
00385 }
00386
00387
00388
00389