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