CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoMuon/GlobalTrackingTools/src/GlobalMuonRefitter.cc

Go to the documentation of this file.
00001 
00015 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonRefitter.h"
00016 
00017 //---------------
00018 // C++ Headers --
00019 //---------------
00020 
00021 #include <iostream>
00022 #include <iomanip>
00023 #include <algorithm>
00024 
00025 //-------------------------------
00026 // Collaborating Class Headers --
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 // Constructors --
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   // Refit direction
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");//layer, wheel, or disk depending on the system
00108 
00109   theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
00110   theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");
00111 
00112   theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
00113 
00114   theCacheId_TRH = 0;
00115 
00116 }
00117 
00118 //--------------
00119 // Destructor --
00120 //--------------
00121 
00122 GlobalMuonRefitter::~GlobalMuonRefitter() {
00123 }
00124 
00125 
00126 //
00127 // set Event
00128 //
00129 void GlobalMuonRefitter::setEvent(const edm::Event& event) {
00130 
00131   theEvent = &event;
00132   event.getByLabel(theDTRecHitLabel, theDTRecHits);
00133   event.getByLabel(theCSCRecHitLabel, theCSCRecHits);
00134 }
00135 
00136 
00137 void GlobalMuonRefitter::setServices(const EventSetup& setup) {
00138 
00139   theService->eventSetup().get<TrajectoryFitter::Record>().get(theFitterName,theFitter);
00140 
00141   // Transient Rechit Builders
00142   unsigned long long newCacheId_TRH = setup.get<TransientRecHitRecord>().cacheIdentifier();
00143   if ( newCacheId_TRH != theCacheId_TRH ) {
00144     LogDebug(theCategory) << "TransientRecHitRecord changed!";
00145     setup.get<TransientRecHitRecord>().get(theTrackerRecHitBuilderName,theTrackerRecHitBuilder);
00146     setup.get<TransientRecHitRecord>().get(theMuonRecHitBuilderName,theMuonRecHitBuilder);
00147   }
00148 }
00149 
00150 
00151 //
00152 // build a combined tracker-muon trajectory
00153 //
00154 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack, 
00155                                              const int theMuonHitsOption) const {
00156   LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
00157     
00158   ConstRecHitContainer allRecHitsTemp; // all muon rechits temp
00159 
00160   reco::TransientTrack track(globalTrack,&*(theService->magneticField()),theService->trackingGeometry());
00161   
00162   for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit)
00163     if ((*hit)->isValid()) {
00164       if ((*hit)->geographicalId().det() == DetId::Tracker)
00165         allRecHitsTemp.push_back(theTrackerRecHitBuilder->build(&**hit));
00166       else if ((*hit)->geographicalId().det() == DetId::Muon) {
00167         if ((*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit) {
00168           LogTrace(theCategory) << "RPC Rec Hit discarged"; 
00169           continue;
00170         }
00171         allRecHitsTemp.push_back(theMuonRecHitBuilder->build(&**hit));
00172       }
00173     }  
00174   vector<Trajectory> refitted = refit(globalTrack,track,allRecHitsTemp,theMuonHitsOption);
00175   return refitted;
00176 }
00177 
00178 //
00179 // build a combined tracker-muon trajectory
00180 //
00181 vector<Trajectory> GlobalMuonRefitter::refit(const reco::Track& globalTrack,
00182                                              const reco::TransientTrack track,
00183                                              TransientTrackingRecHit::ConstRecHitContainer allRecHitsTemp,
00184                                              const int theMuonHitsOption) const {
00185 
00186   // MuonHitsOption: 0 - tracker only
00187   //                 1 - include all muon hits
00188   //                 2 - include only first muon hit(s)
00189   //                 3 - include only selected muon hits
00190   //                 4 - redo pattern recognition with dynamic truncation
00191 
00192   vector<int> stationHits(4,0);
00193   map<DetId, int> hitMap;
00194 
00195   ConstRecHitContainer allRecHits; // all muon rechits
00196   ConstRecHitContainer fmsRecHits; // only first muon rechits
00197   ConstRecHitContainer selectedRecHits; // selected muon rechits
00198   ConstRecHitContainer DYTRecHits; // rec hits from dynamic truncation algorithm
00199 
00200   LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
00201   LogTrace(theCategory) << " Track momentum before refit: " << globalTrack.pt() << endl;
00202   LogTrace(theCategory) << " Hits size before : " << allRecHitsTemp.size() << endl;
00203 
00204   allRecHits = getRidOfSelectStationHits(allRecHitsTemp);  
00205   //    printHits(allRecHits);
00206   LogTrace(theCategory) << " Hits size: " << allRecHits.size() << endl;
00207 
00208   vector <Trajectory> outputTraj;
00209 
00210   if ((theMuonHitsOption == 1) || (theMuonHitsOption == 3) || (theMuonHitsOption == 4) ) {
00211     // refit the full track with all muon hits
00212     vector <Trajectory> globalTraj = transform(globalTrack, track, allRecHits);
00213 
00214     if (!globalTraj.size()) {
00215       LogTrace(theCategory) << "No trajectory from the TrackTransformer!" << endl;
00216       return vector<Trajectory>();
00217     }
00218 
00219     LogTrace(theCategory) << " Initial trajectory state: " 
00220                           << globalTraj.front().lastMeasurement().updatedState().freeState()->parameters() << endl;
00221   
00222     if (theMuonHitsOption == 1 )
00223       outputTraj.push_back(globalTraj.front());
00224     
00225     if (theMuonHitsOption == 3 ) {
00226       checkMuonHits(globalTrack, allRecHits, hitMap);
00227       selectedRecHits = selectMuonHits(globalTraj.front(),hitMap);
00228       LogTrace(theCategory) << " Selected hits size: " << selectedRecHits.size() << endl;  
00229       outputTraj = transform(globalTrack, track, selectedRecHits);
00230     }     
00231 
00232     if (theMuonHitsOption == 4 ) {
00233       // here we use the single thr per subdetector (better performance can be obtained using thr as function of eta)
00234         
00235       DynamicTruncation dytRefit(*theEvent,*theService);
00236       dytRefit.setThr(30,15);                                
00237       //dytRefit.setThr(20,20,20,20,20,15,15,15,15,15,15,15,15);
00238       DYTRecHits = dytRefit.filter(globalTraj.front());
00239       if ((DYTRecHits.size() > 1) && (DYTRecHits.front()->globalPosition().mag() > DYTRecHits.back()->globalPosition().mag()))
00240         stable_sort(DYTRecHits.begin(),DYTRecHits.end(),RecHitLessByDet(alongMomentum));
00241       outputTraj = transform(globalTrack, track, DYTRecHits);
00242     }
00243 
00244   } else if (theMuonHitsOption == 2 )  {
00245       getFirstHits(globalTrack, allRecHits, fmsRecHits);
00246       outputTraj = transform(globalTrack, track, fmsRecHits);
00247     } 
00248 
00249 
00250   if (outputTraj.size()) {
00251     LogTrace(theCategory) << "Refitted pt: " << outputTraj.front().firstMeasurement().updatedState().globalParameters().momentum().perp() << endl;
00252     return outputTraj;
00253   } else {
00254     LogTrace(theCategory) << "No refitted Tracks... " << endl;
00255     return vector<Trajectory>();
00256   }
00257   
00258 }
00259 
00260 
00261 //
00262 //
00263 //
00264 void GlobalMuonRefitter::checkMuonHits(const reco::Track& muon, 
00265                                        ConstRecHitContainer& all,
00266                                        map<DetId, int> &hitMap) const {
00267 
00268   LogTrace(theCategory) << " GlobalMuonRefitter::checkMuonHits " << endl;
00269 
00270   float coneSize = 20.0;
00271 
00272   // loop through all muon hits and calculate the maximum # of hits in each chamber
00273   for (ConstRecHitContainer::const_iterator imrh = all.begin(); imrh != all.end(); imrh++ ) {
00274         
00275     if ( (*imrh != 0 ) && !(*imrh)->isValid() ) continue;
00276   
00277     int detRecHits = 0;
00278     MuonRecHitContainer dRecHits;
00279       
00280     DetId id = (*imrh)->geographicalId();
00281     DetId chamberId;
00282 
00283     // Skip tracker hits
00284     if (id.det()!=DetId::Muon) continue;
00285 
00286     if ( id.subdetId() == MuonSubdetId::DT ) {
00287       DTChamberId did(id.rawId());
00288       DTLayerId lid(id.rawId());
00289       chamberId=did;
00290 
00291       // Get the 1d DT RechHits from this layer
00292       DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
00293 
00294       for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00295         double rhitDistance = fabs(ir->localPosition().x()-(**imrh).localPosition().x());
00296         if ( rhitDistance < coneSize ) detRecHits++;
00297         LogTrace(theCategory)   << "       " << (ir)->localPosition() << "  " << (**imrh).localPosition()
00298                << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00299       }
00300     }// end of if DT
00301     else if ( id.subdetId() == MuonSubdetId::CSC ) {
00302     
00303       CSCDetId did(id.rawId());
00304       chamberId=did.chamberId();
00305 
00306       // Get the CSC Rechits from this layer
00307       CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);      
00308 
00309       for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00310         double rhitDistance = (ir->localPosition()-(**imrh).localPosition()).mag();
00311         if ( rhitDistance < coneSize ) detRecHits++;
00312         LogTrace(theCategory)   << ir->localPosition() << "  " << (**imrh).localPosition()
00313                << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00314       }
00315     }
00316     else {
00317       if ( id.subdetId() != MuonSubdetId::RPC ) LogError(theCategory)<<" Wrong Hit Type ";
00318       continue;      
00319     }
00320       
00321     map<DetId,int>::iterator imap=hitMap.find(chamberId);
00322     if (imap!=hitMap.end()) {
00323       if (detRecHits>imap->second) imap->second=detRecHits;
00324     } else hitMap[chamberId]=detRecHits;
00325 
00326   } // end of loop over muon rechits
00327 
00328   for (map<DetId,int>::iterator imap=hitMap.begin(); imap!=hitMap.end(); imap++ ) 
00329     LogTrace(theCategory) << " Station " << imap->first.rawId() << ": " << imap->second <<endl; 
00330 
00331   LogTrace(theCategory) << "CheckMuonHits: "<<all.size();
00332 
00333   // check order of muon measurements
00334   if ( (all.size() > 1) &&
00335        ( all.front()->globalPosition().mag() >
00336          all.back()->globalPosition().mag() ) ) {
00337     LogTrace(theCategory)<< "reverse order: ";
00338     stable_sort(all.begin(),all.end(),RecHitLessByDet(alongMomentum));
00339   }
00340 }
00341 
00342 
00343 //
00344 // Get the hits from the first muon station (containing hits)
00345 //
00346 void GlobalMuonRefitter::getFirstHits(const reco::Track& muon, 
00347                                        ConstRecHitContainer& all,
00348                                        ConstRecHitContainer& first) const {
00349 
00350   LogTrace(theCategory) << " GlobalMuonRefitter::getFirstHits\nall rechits length:" << all.size() << endl;
00351   first.clear();
00352 
00353   int station_to_keep = 999;
00354   vector<int> stations;
00355   for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ++ihit) {
00356   
00357     int station = 0;
00358     bool use_it = true;
00359     DetId id = (*ihit)->geographicalId();
00360     unsigned raw_id = id.rawId();
00361     if (!(*ihit)->isValid()) station = -1;
00362       else {
00363         if (id.det() == DetId::Muon) {
00364           switch (id.subdetId()) {
00365           case MuonSubdetId::DT:  station = DTChamberId(raw_id).station(); break;
00366           case MuonSubdetId::CSC: station = CSCDetId(raw_id).station(); break;
00367           case MuonSubdetId::RPC: station = RPCDetId(raw_id).station(); use_it = false; break;
00368           }
00369         }
00370       }
00371 
00372     if (use_it && station > 0 && station < station_to_keep) station_to_keep = station;
00373     stations.push_back(station);
00374 
00375     LogTrace(theCategory) << "rawId: " << raw_id << " station = " << station << " station_to_keep is now " << station_to_keep;
00376   }
00377 
00378   if (station_to_keep <= 0 || station_to_keep > 4 || stations.size() != all.size())
00379     LogInfo(theCategory) << "failed to getFirstHits (all muon hits are outliers/bad ?)! station_to_keep = " 
00380                             << station_to_keep << " stations.size " << stations.size() << " all.size " << all.size();
00381 
00382   for (unsigned i = 0; i < stations.size(); ++i)
00383     if (stations[i] >= 0 && stations[i] <= station_to_keep) first.push_back(all[i]);
00384 
00385   return;
00386 }
00387 
00388 
00389 //
00390 // select muon hits compatible with trajectory; 
00391 // check hits in chambers with showers
00392 //
00393 GlobalMuonRefitter::ConstRecHitContainer 
00394 GlobalMuonRefitter::selectMuonHits(const Trajectory& traj, 
00395                                    const map<DetId, int> &hitMap) const {
00396 
00397   ConstRecHitContainer muonRecHits;
00398   const double globalChi2Cut = 200.0;
00399 
00400   vector<TrajectoryMeasurement> muonMeasurements = traj.measurements(); 
00401 
00402   // loop through all muon hits and skip hits with bad chi2 in chambers with high occupancy      
00403   for (std::vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end(); im++ ) {
00404 
00405     if ( !(*im).recHit()->isValid() ) continue;
00406     if ( (*im).recHit()->det()->geographicalId().det() != DetId::Muon ) {
00407       //      if ( ( chi2ndf < globalChi2Cut ) )
00408       muonRecHits.push_back((*im).recHit());
00409       continue;
00410     }  
00411     ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
00412 
00413     DetId id = immrh->geographicalId();
00414     DetId chamberId;
00415     int threshold = 0;
00416     double chi2Cut = 0.0;
00417 
00418     // get station of hit if it is in DT
00419     if ( (*immrh).isDT() ) {
00420       DTChamberId did(id.rawId());
00421       chamberId = did;
00422       threshold = theHitThreshold;
00423       chi2Cut = theDTChi2Cut;
00424     }
00425     // get station of hit if it is in CSC
00426     else if ( (*immrh).isCSC() ) {
00427       CSCDetId did(id.rawId());
00428       chamberId = did.chamberId();
00429       threshold = theHitThreshold;
00430       chi2Cut = theCSCChi2Cut;
00431     }
00432     // get station of hit if it is in RPC
00433     else if ( (*immrh).isRPC() ) {
00434       RPCDetId rpcid(id.rawId());
00435       chamberId = rpcid;
00436       threshold = theHitThreshold;
00437       chi2Cut = theRPCChi2Cut;
00438     } else
00439       continue;
00440 
00441     double chi2ndf = (*im).estimate()/(*im).recHit()->dimension();  
00442 
00443     bool keep = true;
00444     map<DetId,int>::const_iterator imap=hitMap.find(chamberId);
00445     if ( imap!=hitMap.end() ) 
00446       if (imap->second>threshold) keep = false;
00447     
00448     if ( (keep || (chi2ndf<chi2Cut)) && (chi2ndf<globalChi2Cut) ) {
00449       muonRecHits.push_back((*im).recHit());
00450     } else {
00451       LogTrace(theCategory)
00452         << "Skip hit: " << id.rawId() << " chi2=" 
00453         << chi2ndf << " ( threshold: " << chi2Cut << ") Det: " 
00454         << imap->second << endl;
00455     }
00456   }
00457   
00458   // check order of rechits
00459   reverse(muonRecHits.begin(),muonRecHits.end());
00460   return muonRecHits;
00461 }
00462 
00463 
00464 //
00465 // print RecHits
00466 //
00467 void GlobalMuonRefitter::printHits(const ConstRecHitContainer& hits) const {
00468 
00469   LogTrace(theCategory) << "Used RecHits: " << hits.size();
00470   for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00471     if ( !(*ir)->isValid() ) {
00472       LogTrace(theCategory) << "invalid RecHit";
00473       continue; 
00474     }
00475     
00476     const GlobalPoint& pos = (*ir)->globalPosition();
00477     
00478     LogTrace(theCategory) 
00479       << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
00480       << "  z = " << pos.z()
00481       << "  dimension = " << (*ir)->dimension()
00482       << "  det = " << (*ir)->det()->geographicalId().det()
00483       << "  subdet = " << (*ir)->det()->subDetector()
00484       << "  raw id = " << (*ir)->det()->geographicalId().rawId();
00485   }
00486 
00487 }
00488 
00489 
00490 //
00491 // add Trajectory* to TrackCand if not already present
00492 //
00493 GlobalMuonRefitter::RefitDirection
00494 GlobalMuonRefitter::checkRecHitsOrdering(const TransientTrackingRecHit::ConstRecHitContainer& recHits) const {
00495 
00496   if (!recHits.empty()){
00497     ConstRecHitContainer::const_iterator frontHit = recHits.begin();
00498     ConstRecHitContainer::const_iterator backHit  = recHits.end() - 1;
00499     while( !(*frontHit)->isValid() && frontHit != backHit) {frontHit++;}
00500     while( !(*backHit)->isValid() && backHit != frontHit)  {backHit--;}
00501 
00502     double rFirst = (*frontHit)->globalPosition().mag();
00503     double rLast  = (*backHit) ->globalPosition().mag();
00504 
00505     if(rFirst < rLast) return insideOut;
00506     else if(rFirst > rLast) return outsideIn;
00507     else {
00508       LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00509       return undetermined;
00510     }
00511   } else {
00512     LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00513     return undetermined;
00514   }
00515 }
00516 
00517 
00518 //
00519 // Convert Tracks into Trajectories with a given set of hits
00520 //
00521 vector<Trajectory> GlobalMuonRefitter::transform(const reco::Track& newTrack,
00522                                                  const reco::TransientTrack track,
00523                                                  TransientTrackingRecHit::ConstRecHitContainer recHitsForReFit) const {
00524 
00525   LogTrace(theCategory) << "GlobalMuonRefitter::transform: " << recHitsForReFit.size() << " hits:";
00526   printHits(recHitsForReFit);
00527 
00528   if(recHitsForReFit.size() < 2) return vector<Trajectory>();
00529 
00530   // Check the order of the rechits
00531   RefitDirection recHitsOrder = checkRecHitsOrdering(recHitsForReFit);
00532 
00533   LogTrace(theCategory) << "checkRecHitsOrdering() returned " << recHitsOrder
00534                         << ", theRefitDirection is " << theRefitDirection
00535                         << " (insideOut == " << insideOut << ", outsideIn == " << outsideIn << ")";
00536 
00537   // Reverse the order in the case of inconsistency between the fit direction and the rechit order
00538   if(theRefitDirection != recHitsOrder) reverse(recHitsForReFit.begin(),recHitsForReFit.end());
00539 
00540   // Even though we checked the rechits' ordering above, we may have
00541   // already flipped them elsewhere (getFirstHits() is such a
00542   // culprit). Use the global positions of the states and the desired
00543   // refit direction to find the starting TSOS.
00544   TrajectoryStateOnSurface firstTSOS, lastTSOS;
00545   unsigned int innerId, outerId;
00546   bool order_swapped = track.outermostMeasurementState().globalPosition().mag() < track.innermostMeasurementState().globalPosition().mag();
00547   bool inner_is_first;
00548   LogTrace(theCategory) << "order swapped? " << order_swapped;
00549 
00550   // Fill the starting state, depending on the ordering above.
00551   if ((theRefitDirection == insideOut && !order_swapped) || (theRefitDirection == outsideIn && order_swapped)) {
00552     innerId   = newTrack.innerDetId();
00553     outerId   = newTrack.outerDetId();
00554     firstTSOS = track.innermostMeasurementState();
00555     lastTSOS  = track.outermostMeasurementState();
00556     inner_is_first = true;
00557   }
00558   else {
00559     innerId   = newTrack.outerDetId();
00560     outerId   = newTrack.innerDetId();
00561     firstTSOS = track.outermostMeasurementState();
00562     lastTSOS  = track.innermostMeasurementState();
00563     inner_is_first = false;
00564   } 
00565 
00566   LogTrace(theCategory) << "firstTSOS: inner_is_first? " << inner_is_first
00567                         << " globalPosition is " << firstTSOS.globalPosition()
00568                         << " innerId is " << innerId;
00569 
00570   if(!firstTSOS.isValid()){
00571     LogWarning(theCategory) << "Error wrong initial state!" << endl;
00572     return vector<Trajectory>();
00573   }
00574 
00575   firstTSOS.rescaleError(1000.);
00576 
00577   // This is the only way to get a TrajectorySeed with settable propagation direction
00578   PTrajectoryStateOnDet garbage1;
00579   edm::OwnVector<TrackingRecHit> garbage2;
00580   PropagationDirection propDir = 
00581     (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00582 
00583   // These lines cause the code to ignore completely what was set
00584   // above, and force propDir for tracks from collisions!
00585 //  if(propDir == alongMomentum && theRefitDirection == outsideIn)  propDir=oppositeToMomentum;
00586 //  if(propDir == oppositeToMomentum && theRefitDirection == insideOut) propDir=alongMomentum;
00587 
00588   const TrajectoryStateOnSurface& tsosForDir = inner_is_first ? lastTSOS : firstTSOS;
00589   propDir = (tsosForDir.globalPosition().basicVector().dot(tsosForDir.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00590   LogTrace(theCategory) << "propDir based on firstTSOS x dot p is " << propDir
00591                         << " (alongMomentum == " << alongMomentum << ", oppositeToMomentum == " << oppositeToMomentum << ")";
00592 
00593   // Additional propagation diretcion determination logic for cosmic muons
00594   if (theCosmicFlag) {
00595     PropagationDirection propDir_first = (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00596     PropagationDirection propDir_last  = (lastTSOS .globalPosition().basicVector().dot(lastTSOS .globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00597     LogTrace(theCategory) << "propDir_first " << propDir_first << ", propdir_last " << propDir_last
00598                           << " : they " << (propDir_first == propDir_last ? "agree" : "disagree");
00599 
00600     int y_count = 0;
00601     for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = recHitsForReFit.begin(); it != recHitsForReFit.end(); ++it) {
00602       if ((*it)->globalPosition().y() > 0) ++y_count;
00603       else --y_count;
00604     }
00605     
00606     PropagationDirection propDir_ycount = alongMomentum;
00607     if (y_count > 0) {
00608       if      (theRefitDirection == insideOut) propDir_ycount = oppositeToMomentum;
00609       else if (theRefitDirection == outsideIn) propDir_ycount = alongMomentum;
00610     }
00611     else {
00612       if      (theRefitDirection == insideOut) propDir_ycount = alongMomentum;
00613       else if (theRefitDirection == outsideIn) propDir_ycount = oppositeToMomentum;
00614     }
00615     
00616     LogTrace(theCategory) << "y_count = " << y_count
00617                           << "; based on geometrically-outermost TSOS, propDir is " << propDir << ": "
00618                           << (propDir == propDir_ycount ? "agrees" : "disagrees")
00619                           << " with ycount determination";
00620     
00621     if (propDir_first != propDir_last) {
00622       LogTrace(theCategory) << "since first/last disagreed, using y_count propDir";
00623       propDir = propDir_ycount;
00624     }
00625   }
00626 
00627   TrajectorySeed seed(garbage1,garbage2,propDir);
00628 
00629   if(recHitsForReFit.front()->geographicalId() != DetId(innerId)){
00630     LogDebug(theCategory)<<"Propagation occured"<<endl;
00631     LogTrace(theCategory) << "propagating firstTSOS at " << firstTSOS.globalPosition()
00632                           << " to first rechit with surface pos " << recHitsForReFit.front()->det()->surface().toGlobal(LocalPoint(0,0,0));
00633     firstTSOS = theService->propagator(thePropagatorName)->propagate(firstTSOS, recHitsForReFit.front()->det()->surface());
00634     if(!firstTSOS.isValid()){
00635       LogDebug(theCategory)<<"Propagation error!"<<endl;
00636       return vector<Trajectory>();
00637     }
00638   }
00639 
00640 /*  
00641   cout << " GlobalMuonRefitter : theFitter " << propDir << endl;
00642   cout << "                      First TSOS: " 
00643        << firstTSOS.globalPosition() << "  p="
00644        << firstTSOS.globalMomentum() << " = "
00645        << firstTSOS.globalMomentum().mag() << endl;
00646        
00647   cout << "                      Starting seed: "
00648        << " nHits= " << seed.nHits()
00649        << " tsos: "
00650        << seed.startingState().parameters().position() << "  p="
00651        << seed.startingState().parameters().momentum() << endl;
00652        
00653   cout << "                      RecHits: "
00654        << recHitsForReFit.size() << endl;
00655 */
00656        
00657   vector<Trajectory> trajectories = theFitter->fit(seed,recHitsForReFit,firstTSOS);
00658   
00659   if(trajectories.empty()){
00660     LogDebug(theCategory) << "No Track refitted!" << endl;
00661     return vector<Trajectory>();
00662   }
00663   
00664   return trajectories;
00665 }
00666 
00667 
00668 //
00669 // Remove Selected Station Rec Hits
00670 //
00671 GlobalMuonRefitter::ConstRecHitContainer GlobalMuonRefitter::getRidOfSelectStationHits(ConstRecHitContainer hits) const
00672 {
00673   ConstRecHitContainer results;
00674   ConstRecHitContainer::const_iterator it = hits.begin();
00675   for (; it!=hits.end(); it++) {
00676 
00677     DetId id = (*it)->geographicalId();
00678 
00679     //Check that this is a Muon hit that we're toying with -- else pass on this because the hacker is a moron / not careful
00680 
00681     if (id.det() == DetId::Tracker && theTrackerSkipSystem > 0) {
00682       int layer = -999;
00683       int disk  = -999;
00684       int wheel = -999;
00685       if ( id.subdetId() == theTrackerSkipSystem){
00686         //                              continue;  //caveat that just removes the whole system from refitting
00687 
00688         if (theTrackerSkipSystem == PXB) {
00689           PXBDetId did(id.rawId());
00690           layer = did.layer();
00691         }
00692         if (theTrackerSkipSystem == TIB) {
00693           TIBDetId did(id.rawId());
00694           layer = did.layer();
00695         }
00696 
00697         if (theTrackerSkipSystem == TOB) {
00698           TOBDetId did(id.rawId());
00699           layer = did.layer();
00700         }
00701         if (theTrackerSkipSystem == PXF) {
00702           PXFDetId did(id.rawId());
00703           disk = did.disk();
00704         }
00705         if (theTrackerSkipSystem == TID) {
00706           TIDDetId did(id.rawId());
00707           wheel = did.wheel();
00708         }
00709         if (theTrackerSkipSystem == TEC) {
00710           TECDetId did(id.rawId());
00711           wheel = did.wheel();
00712         }
00713         if (theTrackerSkipSection >= 0 && layer == theTrackerSkipSection) continue;
00714         if (theTrackerSkipSection >= 0 && disk == theTrackerSkipSection) continue;
00715         if (theTrackerSkipSection >= 0 && wheel == theTrackerSkipSection) continue;
00716       }
00717     }
00718 
00719     if (id.det() == DetId::Muon && theSkipStation) {
00720       int station = -999;
00721       int wheel = -999;
00722       if ( id.subdetId() == MuonSubdetId::DT ) {
00723         DTChamberId did(id.rawId());
00724         station = did.station();
00725         wheel = did.wheel();
00726       } else if ( id.subdetId() == MuonSubdetId::CSC ) {
00727         CSCDetId did(id.rawId());
00728         station = did.station();
00729       } else if ( id.subdetId() == MuonSubdetId::RPC ) {
00730         RPCDetId rpcid(id.rawId());
00731         station = rpcid.station();
00732       }
00733       if(station == theSkipStation) continue;
00734     }
00735     results.push_back(*it);
00736   }
00737   return results;
00738 }
00739