00001
00015 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonRefitter.h"
00016
00017
00018
00019
00020
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <algorithm>
00024
00025
00026
00027
00028
00029 #include "FWCore/Framework/interface/Event.h"
00030
00031 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00032 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00033 #include "TrackingTools/TrackFitters/interface/RecHitLessByDet.h"
00034 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00035 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00036 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00037 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00038 #include "TrackingTools/TrackFitters/interface/TrajectoryFitter.h"
00039 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00040
00041
00042 #include "DataFormats/DetId/interface/DetId.h"
00043 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00044 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00045 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00046 #include "Geometry/DTGeometry/interface/DTGeometry.h"
00047 #include "Geometry/DTGeometry/interface/DTLayer.h"
00048 #include <Geometry/CSCGeometry/interface/CSCLayer.h>
00049 #include <DataFormats/CSCRecHit/interface/CSCRecHit2D.h>
00050 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00051 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00052
00053 #include "DataFormats/TrackReco/interface/Track.h"
00054 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00055
00056 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00057 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBuilder.h"
00058 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00059 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00060 #include "RecoMuon/TrackingTools/interface/MuonCandidate.h"
00061 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00062 #include "RecoMuon/GlobalTrackingTools/interface/DynamicTruncation.h"
00063
00064 using namespace std;
00065 using namespace edm;
00066
00067
00068
00069
00070
00071 GlobalMuonRefitter::GlobalMuonRefitter(const edm::ParameterSet& par,
00072 const MuonServiceProxy* service) :
00073 theCosmicFlag(par.getParameter<bool>("PropDirForCosmics")),
00074 theDTRecHitLabel(par.getParameter<InputTag>("DTRecSegmentLabel")),
00075 theCSCRecHitLabel(par.getParameter<InputTag>("CSCRecSegmentLabel")),
00076 theService(service) {
00077
00078 theCategory = par.getUntrackedParameter<string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalMuonRefitter");
00079
00080 theHitThreshold = par.getParameter<int>("HitThreshold");
00081 theDTChi2Cut = par.getParameter<double>("Chi2CutDT");
00082 theCSCChi2Cut = par.getParameter<double>("Chi2CutCSC");
00083 theRPCChi2Cut = par.getParameter<double>("Chi2CutRPC");
00084
00085
00086 string refitDirectionName = par.getParameter<string>("RefitDirection");
00087
00088 if (refitDirectionName == "insideOut" ) theRefitDirection = insideOut;
00089 else if (refitDirectionName == "outsideIn" ) theRefitDirection = outsideIn;
00090 else
00091 throw cms::Exception("TrackTransformer constructor")
00092 <<"Wrong refit direction chosen in TrackTransformer ParameterSet"
00093 << "\n"
00094 << "Possible choices are:"
00095 << "\n"
00096 << "RefitDirection = insideOut or RefitDirection = outsideIn";
00097
00098 theFitterName = par.getParameter<string>("Fitter");
00099 thePropagatorName = par.getParameter<string>("Propagator");
00100
00101 theSkipStation = par.getParameter<int>("SkipStation");
00102 theTrackerSkipSystem = par.getParameter<int>("TrackerSkipSystem");
00103 theTrackerSkipSection = par.getParameter<int>("TrackerSkipSection");
00104
00105 theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
00106 theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
00107
00108 theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
00109
00110 theDYTthrs = par.getParameter< std::vector<int> >("DYTthrs");
00111
00112 if (par.existsAs<double>("RescaleErrorFactor")) {
00113 theRescaleErrorFactor = par.getParameter<double>("RescaleErrorFactor");
00114 edm::LogWarning("GlobalMuonRefitter") << "using error rescale factor " << theRescaleErrorFactor;
00115 }
00116 else
00117 theRescaleErrorFactor = 1000.;
00118
00119
00120 theCacheId_TRH = 0;
00121
00122 }
00123
00124
00125
00126
00127
00128 GlobalMuonRefitter::~GlobalMuonRefitter() {
00129 }
00130
00131
00132
00133
00134
00135 void GlobalMuonRefitter::setEvent(const edm::Event& event) {
00136
00137 theEvent = &event;
00138 event.getByLabel(theDTRecHitLabel, theDTRecHits);
00139 event.getByLabel(theCSCRecHitLabel, theCSCRecHits);
00140 }
00141
00142
00143 void GlobalMuonRefitter::setServices(const EventSetup& setup) {
00144
00145 theService->eventSetup().get<TrajectoryFitter::Record>().get(theFitterName,theFitter);
00146
00147
00148 unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
00149 if ( newCacheId_TRH != theCacheId_TRH ) {
00150 LogDebug(theCategory) << "TransientRecHitRecord changed!";
00151 setup.get<TransientRecHitRecord>().get(theTrackerRecHitBuilderName,theTrackerRecHitBuilder);
00152 setup.get<TransientRecHitRecord>().get(theMuonRecHitBuilderName,theMuonRecHitBuilder);
00153 }
00154 }
00155
00156
00157
00158
00159
00160 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack,
00161 const int theMuonHitsOption,
00162 const TrackerTopology *tTopo) const {
00163 LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
00164
00165 ConstRecHitContainer allRecHitsTemp;
00166
00167 reco::TransientTrack track(globalTrack,&*(theService->magneticField()),theService->trackingGeometry());
00168
00169 for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit)
00170 if ((*hit)->isValid()) {
00171 if ((*hit)->geographicalId().det() == DetId::Tracker)
00172 allRecHitsTemp.push_back(theTrackerRecHitBuilder->build(&**hit));
00173 else if ((*hit)->geographicalId().det() == DetId::Muon) {
00174 if ((*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
00175 LogTrace(theCategory) << "RPC Rec Hit discarged";
00176 continue;
00177 }
00178 allRecHitsTemp.push_back(theMuonRecHitBuilder->build(&**hit));
00179 }
00180 }
00181 vector<Trajectory> refitted = refit(globalTrack,track,allRecHitsTemp,theMuonHitsOption, tTopo);
00182 return refitted;
00183 }
00184
00185
00186
00187
00188 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack,
00189 const reco::TransientTrack track,
00190 const TransientTrackingRecHit::ConstRecHitContainer& allRecHitsTemp,
00191 const int theMuonHitsOption,
00192 const TrackerTopology *tTopo) const {
00193
00194
00195
00196
00197
00198
00199
00200 vector<int> stationHits(4,0);
00201 map<DetId, int> hitMap;
00202
00203 ConstRecHitContainer allRecHits;
00204 ConstRecHitContainer fmsRecHits;
00205 ConstRecHitContainer selectedRecHits;
00206 ConstRecHitContainer DYTRecHits;
00207
00208 LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
00209 LogTrace(theCategory) << " Track momentum before refit: " << globalTrack.pt() << endl;
00210 LogTrace(theCategory) << " Hits size before : " << allRecHitsTemp.size() << endl;
00211
00212 allRecHits = getRidOfSelectStationHits(allRecHitsTemp, tTopo);
00213
00214 LogTrace(theCategory) << " Hits size: " << allRecHits.size() << endl;
00215
00216 vector <Trajectory> outputTraj;
00217
00218 if ((theMuonHitsOption == 1) || (theMuonHitsOption == 3) || (theMuonHitsOption == 4) ) {
00219
00220 vector <Trajectory> globalTraj = transform(globalTrack, track, allRecHits);
00221
00222 if (!globalTraj.size()) {
00223 LogTrace(theCategory) << "No trajectory from the TrackTransformer!" << endl;
00224 return vector<Trajectory>();
00225 }
00226
00227 LogTrace(theCategory) << " Initial trajectory state: "
00228 << globalTraj.front().lastMeasurement().updatedState().freeState()->parameters() << endl;
00229
00230 if (theMuonHitsOption == 1 )
00231 outputTraj.push_back(globalTraj.front());
00232
00233 if (theMuonHitsOption == 3 ) {
00234 checkMuonHits(globalTrack, allRecHits, hitMap);
00235 selectedRecHits = selectMuonHits(globalTraj.front(),hitMap);
00236 LogTrace(theCategory) << " Selected hits size: " << selectedRecHits.size() << endl;
00237 outputTraj = transform(globalTrack, track, selectedRecHits);
00238 }
00239
00240 if (theMuonHitsOption == 4 ) {
00241
00242
00243 DynamicTruncation dytRefit(*theEvent,*theService);
00244 dytRefit.setThr(theDYTthrs.at(0),theDYTthrs.at(1),theDYTthrs.at(2));
00245 DYTRecHits = dytRefit.filter(globalTraj.front());
00246
00247 if ((DYTRecHits.size() > 1) && (DYTRecHits.front()->globalPosition().mag() > DYTRecHits.back()->globalPosition().mag()))
00248 stable_sort(DYTRecHits.begin(),DYTRecHits.end(),RecHitLessByDet(alongMomentum));
00249 outputTraj = transform(globalTrack, track, DYTRecHits);
00250 }
00251
00252 } else if (theMuonHitsOption == 2 ) {
00253 getFirstHits(globalTrack, allRecHits, fmsRecHits);
00254 outputTraj = transform(globalTrack, track, fmsRecHits);
00255 }
00256
00257
00258 if (outputTraj.size()) {
00259 LogTrace(theCategory) << "Refitted pt: " << outputTraj.front().firstMeasurement().updatedState().globalParameters().momentum().perp() << endl;
00260 return outputTraj;
00261 } else {
00262 LogTrace(theCategory) << "No refitted Tracks... " << endl;
00263 return vector<Trajectory>();
00264 }
00265
00266 }
00267
00268
00269
00270
00271
00272 void GlobalMuonRefitter::checkMuonHits(const reco::Track& muon,
00273 ConstRecHitContainer& all,
00274 map<DetId, int> &hitMap) const {
00275
00276 LogTrace(theCategory) << " GlobalMuonRefitter::checkMuonHits " << endl;
00277
00278 float coneSize = 20.0;
00279
00280
00281 for (ConstRecHitContainer::const_iterator imrh = all.begin(); imrh != all.end(); imrh++ ) {
00282
00283 if ( (*imrh != 0 ) && !(*imrh)->isValid() ) continue;
00284
00285 int detRecHits = 0;
00286 MuonRecHitContainer dRecHits;
00287
00288 DetId id = (*imrh)->geographicalId();
00289 DetId chamberId;
00290
00291
00292 if (id.det()!=DetId::Muon) continue;
00293
00294 if ( id.subdetId() == MuonSubdetId::DT ) {
00295 DTChamberId did(id.rawId());
00296 chamberId=did;
00297
00298 if ((*imrh)->recHits().size()>1) {
00299 std::vector <const TrackingRecHit*> hits2d = (*imrh)->recHits();
00300 for (std::vector <const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d!= hits2d.end(); hit2d++) {
00301 if ((*imrh)->recHits().size()>1) {
00302 std::vector <const TrackingRecHit*> hits1d = (*hit2d)->recHits();
00303 for (std::vector <const TrackingRecHit*>::const_iterator hit1d = hits1d.begin(); hit1d!= hits1d.end(); hit1d++) {
00304 DetId id1 = (*hit1d)->geographicalId();
00305 DTLayerId lid(id1.rawId());
00306
00307 DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
00308 int layerHits=0;
00309 for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00310 double rhitDistance = fabs(ir->localPosition().x()-(**hit1d).localPosition().x());
00311 if ( rhitDistance < coneSize ) layerHits++;
00312 LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**hit1d).localPosition()
00313 << " Distance: " << rhitDistance << " recHits: " << layerHits << " SL: " << lid.superLayer() << endl;
00314 }
00315 if (layerHits>detRecHits) detRecHits=layerHits;
00316 }
00317 }
00318 }
00319
00320 } else {
00321 DTLayerId lid(id.rawId());
00322
00323
00324 DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
00325
00326 for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00327 double rhitDistance = fabs(ir->localPosition().x()-(**imrh).localPosition().x());
00328 if ( rhitDistance < coneSize ) detRecHits++;
00329 LogTrace(theCategory) << " " << (ir)->localPosition() << " " << (**imrh).localPosition()
00330 << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00331 }
00332 }
00333 }
00334 else if ( id.subdetId() == MuonSubdetId::CSC ) {
00335 CSCDetId did(id.rawId());
00336 chamberId=did.chamberId();
00337
00338 if ((*imrh)->recHits().size()>1) {
00339 std::vector <const TrackingRecHit*> hits2d = (*imrh)->recHits();
00340 for (std::vector <const TrackingRecHit*>::const_iterator hit2d = hits2d.begin(); hit2d!= hits2d.end(); hit2d++) {
00341 DetId id1 = (*hit2d)->geographicalId();
00342 CSCDetId lid(id1.rawId());
00343
00344
00345 CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(lid);
00346 int layerHits=0;
00347
00348 for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00349 double rhitDistance = (ir->localPosition()-(**hit2d).localPosition()).mag();
00350 if ( rhitDistance < coneSize ) layerHits++;
00351 LogTrace(theCategory) << ir->localPosition() << " " << (**hit2d).localPosition()
00352 << " Distance: " << rhitDistance << " recHits: " << layerHits << endl;
00353 }
00354 if (layerHits>detRecHits) detRecHits=layerHits;
00355 }
00356 } else {
00357
00358 CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);
00359
00360 for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00361 double rhitDistance = (ir->localPosition()-(**imrh).localPosition()).mag();
00362 if ( rhitDistance < coneSize ) detRecHits++;
00363 LogTrace(theCategory) << ir->localPosition() << " " << (**imrh).localPosition()
00364 << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00365 }
00366 }
00367 }
00368 else {
00369 if ( id.subdetId() != MuonSubdetId::RPC ) LogError(theCategory)<<" Wrong Hit Type ";
00370 continue;
00371 }
00372
00373 map<DetId,int>::iterator imap=hitMap.find(chamberId);
00374 if (imap!=hitMap.end()) {
00375 if (detRecHits>imap->second) imap->second=detRecHits;
00376 } else hitMap[chamberId]=detRecHits;
00377
00378 }
00379
00380 for (map<DetId,int>::iterator imap=hitMap.begin(); imap!=hitMap.end(); imap++ )
00381 LogTrace(theCategory) << " Station " << imap->first.rawId() << ": " << imap->second <<endl;
00382
00383 LogTrace(theCategory) << "CheckMuonHits: "<<all.size();
00384
00385
00386 if ( (all.size() > 1) &&
00387 ( all.front()->globalPosition().mag() >
00388 all.back()->globalPosition().mag() ) ) {
00389 LogTrace(theCategory)<< "reverse order: ";
00390 stable_sort(all.begin(),all.end(),RecHitLessByDet(alongMomentum));
00391 }
00392 }
00393
00394
00395
00396
00397
00398 void GlobalMuonRefitter::getFirstHits(const reco::Track& muon,
00399 ConstRecHitContainer& all,
00400 ConstRecHitContainer& first) const {
00401
00402 LogTrace(theCategory) << " GlobalMuonRefitter::getFirstHits\nall rechits length:" << all.size() << endl;
00403 first.clear();
00404
00405 int station_to_keep = 999;
00406 vector<int> stations;
00407 for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ++ihit) {
00408
00409 int station = 0;
00410 bool use_it = true;
00411 DetId id = (*ihit)->geographicalId();
00412 unsigned raw_id = id.rawId();
00413 if (!(*ihit)->isValid()) station = -1;
00414 else {
00415 if (id.det() == DetId::Muon) {
00416 switch (id.subdetId()) {
00417 case MuonSubdetId::DT: station = DTChamberId(raw_id).station(); break;
00418 case MuonSubdetId::CSC: station = CSCDetId(raw_id).station(); break;
00419 case MuonSubdetId::RPC: station = RPCDetId(raw_id).station(); use_it = false; break;
00420 }
00421 }
00422 }
00423
00424 if (use_it && station > 0 && station < station_to_keep) station_to_keep = station;
00425 stations.push_back(station);
00426
00427 LogTrace(theCategory) << "rawId: " << raw_id << " station = " << station << " station_to_keep is now " << station_to_keep;
00428 }
00429
00430 if (station_to_keep <= 0 || station_to_keep > 4 || stations.size() != all.size())
00431 LogInfo(theCategory) << "failed to getFirstHits (all muon hits are outliers/bad ?)! station_to_keep = "
00432 << station_to_keep << " stations.size " << stations.size() << " all.size " << all.size();
00433
00434 for (unsigned i = 0; i < stations.size(); ++i)
00435 if (stations[i] >= 0 && stations[i] <= station_to_keep) first.push_back(all[i]);
00436
00437 return;
00438 }
00439
00440
00441
00442
00443
00444
00445 GlobalMuonRefitter::ConstRecHitContainer
00446 GlobalMuonRefitter::selectMuonHits(const Trajectory& traj,
00447 const map<DetId, int> &hitMap) const {
00448
00449 ConstRecHitContainer muonRecHits;
00450 const double globalChi2Cut = 200.0;
00451
00452 vector<TrajectoryMeasurement> muonMeasurements = traj.measurements();
00453
00454
00455 for (std::vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end(); im++ ) {
00456
00457 if ( !(*im).recHit()->isValid() ) continue;
00458 if ( (*im).recHit()->det()->geographicalId().det() != DetId::Muon ) {
00459
00460 muonRecHits.push_back((*im).recHit());
00461 continue;
00462 }
00463 ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
00464
00465 DetId id = immrh->geographicalId();
00466 DetId chamberId;
00467 int threshold = 0;
00468 double chi2Cut = 0.0;
00469
00470
00471 if ( (*immrh).isDT() ) {
00472 DTChamberId did(id.rawId());
00473 chamberId = did;
00474 threshold = theHitThreshold;
00475 chi2Cut = theDTChi2Cut;
00476 }
00477
00478 else if ( (*immrh).isCSC() ) {
00479 CSCDetId did(id.rawId());
00480 chamberId = did.chamberId();
00481 threshold = theHitThreshold;
00482 chi2Cut = theCSCChi2Cut;
00483 }
00484
00485 else if ( (*immrh).isRPC() ) {
00486 RPCDetId rpcid(id.rawId());
00487 chamberId = rpcid;
00488 threshold = theHitThreshold;
00489 chi2Cut = theRPCChi2Cut;
00490 } else
00491 continue;
00492
00493 double chi2ndf = (*im).estimate()/(*im).recHit()->dimension();
00494
00495 bool keep = true;
00496 map<DetId,int>::const_iterator imap=hitMap.find(chamberId);
00497 if ( imap!=hitMap.end() )
00498 if (imap->second>threshold) keep = false;
00499
00500 if ( (keep || (chi2ndf<chi2Cut)) && (chi2ndf<globalChi2Cut) ) {
00501 muonRecHits.push_back((*im).recHit());
00502 } else {
00503 LogTrace(theCategory)
00504 << "Skip hit: " << id.rawId() << " chi2="
00505 << chi2ndf << " ( threshold: " << chi2Cut << ") Det: "
00506 << imap->second << endl;
00507 }
00508 }
00509
00510
00511 reverse(muonRecHits.begin(),muonRecHits.end());
00512 return muonRecHits;
00513 }
00514
00515
00516
00517
00518
00519 void GlobalMuonRefitter::printHits(const ConstRecHitContainer& hits) const {
00520
00521 LogTrace(theCategory) << "Used RecHits: " << hits.size();
00522 for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00523 if ( !(*ir)->isValid() ) {
00524 LogTrace(theCategory) << "invalid RecHit";
00525 continue;
00526 }
00527
00528 const GlobalPoint& pos = (*ir)->globalPosition();
00529
00530 LogTrace(theCategory)
00531 << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
00532 << " z = " << pos.z()
00533 << " dimension = " << (*ir)->dimension()
00534 << " det = " << (*ir)->det()->geographicalId().det()
00535 << " subdet = " << (*ir)->det()->subDetector()
00536 << " raw id = " << (*ir)->det()->geographicalId().rawId();
00537 }
00538
00539 }
00540
00541
00542
00543
00544
00545 GlobalMuonRefitter::RefitDirection
00546 GlobalMuonRefitter::checkRecHitsOrdering(const TransientTrackingRecHit::ConstRecHitContainer& recHits) const {
00547
00548 if (!recHits.empty()){
00549 ConstRecHitContainer::const_iterator frontHit = recHits.begin();
00550 ConstRecHitContainer::const_iterator backHit = recHits.end() - 1;
00551 while( !(*frontHit)->isValid() && frontHit != backHit) {frontHit++;}
00552 while( !(*backHit)->isValid() && backHit != frontHit) {backHit--;}
00553
00554 double rFirst = (*frontHit)->globalPosition().mag();
00555 double rLast = (*backHit) ->globalPosition().mag();
00556
00557 if(rFirst < rLast) return insideOut;
00558 else if(rFirst > rLast) return outsideIn;
00559 else {
00560 LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00561 return undetermined;
00562 }
00563 } else {
00564 LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00565 return undetermined;
00566 }
00567 }
00568
00569
00570
00571
00572
00573 vector<Trajectory> GlobalMuonRefitter::transform(const reco::Track& newTrack,
00574 const reco::TransientTrack track,
00575 const TransientTrackingRecHit::ConstRecHitContainer& urecHitsForReFit) const {
00576
00577 TransientTrackingRecHit::ConstRecHitContainer recHitsForReFit = urecHitsForReFit;
00578 LogTrace(theCategory) << "GlobalMuonRefitter::transform: " << recHitsForReFit.size() << " hits:";
00579 printHits(recHitsForReFit);
00580
00581 if(recHitsForReFit.size() < 2) return vector<Trajectory>();
00582
00583
00584 RefitDirection recHitsOrder = checkRecHitsOrdering(recHitsForReFit);
00585
00586 LogTrace(theCategory) << "checkRecHitsOrdering() returned " << recHitsOrder
00587 << ", theRefitDirection is " << theRefitDirection
00588 << " (insideOut == " << insideOut << ", outsideIn == " << outsideIn << ")";
00589
00590
00591 if(theRefitDirection != recHitsOrder) reverse(recHitsForReFit.begin(),recHitsForReFit.end());
00592
00593
00594
00595
00596
00597 TrajectoryStateOnSurface firstTSOS, lastTSOS;
00598 unsigned int innerId;
00599 bool order_swapped = track.outermostMeasurementState().globalPosition().mag() < track.innermostMeasurementState().globalPosition().mag();
00600 bool inner_is_first;
00601 LogTrace(theCategory) << "order swapped? " << order_swapped;
00602
00603
00604 if ((theRefitDirection == insideOut && !order_swapped) || (theRefitDirection == outsideIn && order_swapped)) {
00605 innerId = newTrack.innerDetId();
00606
00607 firstTSOS = track.innermostMeasurementState();
00608 lastTSOS = track.outermostMeasurementState();
00609 inner_is_first = true;
00610 }
00611 else {
00612 innerId = newTrack.outerDetId();
00613
00614 firstTSOS = track.outermostMeasurementState();
00615 lastTSOS = track.innermostMeasurementState();
00616 inner_is_first = false;
00617 }
00618
00619 LogTrace(theCategory) << "firstTSOS: inner_is_first? " << inner_is_first
00620 << " globalPosition is " << firstTSOS.globalPosition()
00621 << " innerId is " << innerId;
00622
00623 if(!firstTSOS.isValid()){
00624 LogWarning(theCategory) << "Error wrong initial state!" << endl;
00625 return vector<Trajectory>();
00626 }
00627
00628 firstTSOS.rescaleError(theRescaleErrorFactor);
00629
00630
00631 PTrajectoryStateOnDet garbage1;
00632 edm::OwnVector<TrackingRecHit> garbage2;
00633 PropagationDirection propDir =
00634 (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00635
00636
00637
00638
00639
00640
00641 const TrajectoryStateOnSurface& tsosForDir = inner_is_first ? lastTSOS : firstTSOS;
00642 propDir = (tsosForDir.globalPosition().basicVector().dot(tsosForDir.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00643 LogTrace(theCategory) << "propDir based on firstTSOS x dot p is " << propDir
00644 << " (alongMomentum == " << alongMomentum << ", oppositeToMomentum == " << oppositeToMomentum << ")";
00645
00646
00647 if (theCosmicFlag) {
00648 PropagationDirection propDir_first = (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00649 PropagationDirection propDir_last = (lastTSOS .globalPosition().basicVector().dot(lastTSOS .globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00650 LogTrace(theCategory) << "propDir_first " << propDir_first << ", propdir_last " << propDir_last
00651 << " : they " << (propDir_first == propDir_last ? "agree" : "disagree");
00652
00653 int y_count = 0;
00654 for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = recHitsForReFit.begin(); it != recHitsForReFit.end(); ++it) {
00655 if ((*it)->globalPosition().y() > 0) ++y_count;
00656 else --y_count;
00657 }
00658
00659 PropagationDirection propDir_ycount = alongMomentum;
00660 if (y_count > 0) {
00661 if (theRefitDirection == insideOut) propDir_ycount = oppositeToMomentum;
00662 else if (theRefitDirection == outsideIn) propDir_ycount = alongMomentum;
00663 }
00664 else {
00665 if (theRefitDirection == insideOut) propDir_ycount = alongMomentum;
00666 else if (theRefitDirection == outsideIn) propDir_ycount = oppositeToMomentum;
00667 }
00668
00669 LogTrace(theCategory) << "y_count = " << y_count
00670 << "; based on geometrically-outermost TSOS, propDir is " << propDir << ": "
00671 << (propDir == propDir_ycount ? "agrees" : "disagrees")
00672 << " with ycount determination";
00673
00674 if (propDir_first != propDir_last) {
00675 LogTrace(theCategory) << "since first/last disagreed, using y_count propDir";
00676 propDir = propDir_ycount;
00677 }
00678 }
00679
00680 TrajectorySeed seed(garbage1,garbage2,propDir);
00681
00682 if(recHitsForReFit.front()->geographicalId() != DetId(innerId)){
00683 LogDebug(theCategory)<<"Propagation occured"<<endl;
00684 LogTrace(theCategory) << "propagating firstTSOS at " << firstTSOS.globalPosition()
00685 << " to first rechit with surface pos " << recHitsForReFit.front()->det()->surface().toGlobal(LocalPoint(0,0,0));
00686 firstTSOS = theService->propagator(thePropagatorName)->propagate(firstTSOS, recHitsForReFit.front()->det()->surface());
00687 if(!firstTSOS.isValid()){
00688 LogDebug(theCategory)<<"Propagation error!"<<endl;
00689 return vector<Trajectory>();
00690 }
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 vector<Trajectory> trajectories = theFitter->fit(seed,recHitsForReFit,firstTSOS);
00711
00712 if(trajectories.empty()){
00713 LogDebug(theCategory) << "No Track refitted!" << endl;
00714 return vector<Trajectory>();
00715 }
00716
00717 return trajectories;
00718 }
00719
00720
00721
00722
00723
00724 GlobalMuonRefitter::ConstRecHitContainer GlobalMuonRefitter::getRidOfSelectStationHits(const ConstRecHitContainer& hits,
00725 const TrackerTopology *tTopo) const
00726 {
00727 ConstRecHitContainer results;
00728 ConstRecHitContainer::const_iterator it = hits.begin();
00729 for (; it!=hits.end(); it++) {
00730
00731 DetId id = (*it)->geographicalId();
00732
00733
00734
00735 if (id.det() == DetId::Tracker && theTrackerSkipSystem > 0) {
00736 int layer = -999;
00737 int disk = -999;
00738 int wheel = -999;
00739 if ( id.subdetId() == theTrackerSkipSystem){
00740
00741
00742 if (theTrackerSkipSystem == PXB) {
00743
00744 layer = tTopo->pxbLayer(id);
00745 }
00746 if (theTrackerSkipSystem == TIB) {
00747
00748 layer = tTopo->tibLayer(id);
00749 }
00750
00751 if (theTrackerSkipSystem == TOB) {
00752
00753 layer = tTopo->tobLayer(id);
00754 }
00755 if (theTrackerSkipSystem == PXF) {
00756
00757 disk = tTopo->pxfDisk(id);
00758 }
00759 if (theTrackerSkipSystem == TID) {
00760
00761 wheel = tTopo->tidWheel(id);
00762 }
00763 if (theTrackerSkipSystem == TEC) {
00764
00765 wheel = tTopo->tecWheel(id);
00766 }
00767 if (theTrackerSkipSection >= 0 && layer == theTrackerSkipSection) continue;
00768 if (theTrackerSkipSection >= 0 && disk == theTrackerSkipSection) continue;
00769 if (theTrackerSkipSection >= 0 && wheel == theTrackerSkipSection) continue;
00770 }
00771 }
00772
00773 if (id.det() == DetId::Muon && theSkipStation) {
00774 int station = -999;
00775
00776 if ( id.subdetId() == MuonSubdetId::DT ) {
00777 DTChamberId did(id.rawId());
00778 station = did.station();
00779
00780 } else if ( id.subdetId() == MuonSubdetId::CSC ) {
00781 CSCDetId did(id.rawId());
00782 station = did.station();
00783 } else if ( id.subdetId() == MuonSubdetId::RPC ) {
00784 RPCDetId rpcid(id.rawId());
00785 station = rpcid.station();
00786 }
00787 if(station == theSkipStation) continue;
00788 }
00789 results.push_back(*it);
00790 }
00791 return results;
00792 }
00793