CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/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 
00194   ConstRecHitContainer allRecHits; // all muon rechits
00195   ConstRecHitContainer fmsRecHits; // only first muon rechits
00196   ConstRecHitContainer selectedRecHits; // selected muon rechits
00197   ConstRecHitContainer DYTRecHits; // rec hits from dynamic truncation algorithm
00198 
00199    LogTrace(theCategory) << " *** GlobalMuonRefitter *** option " << theMuonHitsOption << endl;
00200 
00201    LogTrace(theCategory) << " Track momentum before refit: " << globalTrack.pt() << endl;
00202 
00203   LogTrace(theCategory) << " Hits size before : " << allRecHitsTemp.size() << endl;
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, stationHits);
00227       selectedRecHits = selectMuonHits(globalTraj.front(),stationHits);
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                                        std::vector<int>& hits) const {
00267 
00268   LogTrace(theCategory) << " GlobalMuonRefitter::checkMuonHits " << endl;
00269 
00270   float coneSize = 20.0;
00271   int dethits[4];
00272   for ( int i=0; i<4; i++ ) hits[i]=dethits[i]=0;
00273 
00274   // loop through all muon hits and calculate the maximum # of hits in each chamber
00275   for (ConstRecHitContainer::const_iterator imrh = all.begin(); imrh != all.end(); imrh++ ) {
00276         
00277     if ( (*imrh != 0 ) && !(*imrh)->isValid() ) continue;
00278   
00279     int station = 0;
00280     int detRecHits = 0;
00281     MuonRecHitContainer dRecHits;
00282       
00283     DetId id = (*imrh)->geographicalId();
00284 
00285     // Skip tracker hits
00286     if (id.det()!=DetId::Muon) continue;
00287 
00288     if ( id.subdetId() == MuonSubdetId::DT ) {
00289       DTChamberId did(id.rawId());
00290       DTLayerId lid(id.rawId());
00291       station = did.station();
00292 
00293       // Get the 1d DT RechHits from this layer
00294       DTRecHitCollection::range dRecHits = theDTRecHits->get(lid);
00295 
00296       for (DTRecHitCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00297         double rhitDistance = fabs(ir->localPosition().x()-(**imrh).localPosition().x());
00298         if ( rhitDistance < coneSize ) detRecHits++;
00299         LogTrace(theCategory)   << "       " << (ir)->localPosition() << "  " << (**imrh).localPosition()
00300                << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00301       }
00302     }// end of if DT
00303     else if ( id.subdetId() == MuonSubdetId::CSC ) {
00304     
00305       CSCDetId did(id.rawId());
00306       station = did.station();
00307 
00308       // Get the CSC Rechits from this layer
00309       CSCRecHit2DCollection::range dRecHits = theCSCRecHits->get(did);      
00310 
00311       for (CSCRecHit2DCollection::const_iterator ir = dRecHits.first; ir != dRecHits.second; ir++ ) {
00312         double rhitDistance = (ir->localPosition()-(**imrh).localPosition()).mag();
00313         if ( rhitDistance < coneSize ) detRecHits++;
00314         LogTrace(theCategory)   << ir->localPosition() << "  " << (**imrh).localPosition()
00315                << " Distance: " << rhitDistance << " recHits: " << detRecHits << endl;
00316       }
00317     }
00318     else {
00319       if ( id.subdetId() != MuonSubdetId::RPC ) LogError(theCategory)<<" Wrong Hit Type ";
00320       continue;      
00321     }
00322       
00323     if ( (station > 0) && (station < 5) ) {
00324       if ( detRecHits > hits[station-1] ) hits[station-1] = detRecHits;
00325     }
00326 
00327   } // end of loop over muon rechits
00328 
00329   for ( int i = 0; i < 4; i++ ) 
00330     LogTrace(theCategory) <<" Station "<<i+1<<": "<<hits[i]<<" "<<dethits[i] <<endl; 
00331 
00332   LogTrace(theCategory) << "CheckMuonHits: "<<all.size();
00333 
00334   // check order of muon measurements
00335   if ( (all.size() > 1) &&
00336        ( all.front()->globalPosition().mag() >
00337          all.back()->globalPosition().mag() ) ) {
00338     LogTrace(theCategory)<< "reverse order: ";
00339     stable_sort(all.begin(),all.end(),RecHitLessByDet(alongMomentum));
00340   }
00341 }
00342 
00343 
00344 //
00345 // Get the hits from the first muon station (containing hits)
00346 //
00347 void GlobalMuonRefitter::getFirstHits(const reco::Track& muon, 
00348                                        ConstRecHitContainer& all,
00349                                        ConstRecHitContainer& first) const {
00350 
00351   LogTrace(theCategory) << " GlobalMuonRefitter::getFirstHits\nall rechits length:" << all.size() << endl;
00352   first.clear();
00353 
00354   int station_to_keep = 999;
00355   vector<int> stations;
00356   for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ++ihit) {
00357   
00358     int station = 0;
00359     bool use_it = true;
00360     DetId id = (*ihit)->geographicalId();
00361     unsigned raw_id = id.rawId();
00362     if (!(*ihit)->isValid()) station = -1;
00363       else {
00364         if (id.det() == DetId::Muon) {
00365           switch (id.subdetId()) {
00366           case MuonSubdetId::DT:  station = DTChamberId(raw_id).station(); break;
00367           case MuonSubdetId::CSC: station = CSCDetId(raw_id).station(); break;
00368           case MuonSubdetId::RPC: station = RPCDetId(raw_id).station(); use_it = false; break;
00369           }
00370         }
00371       }
00372 
00373     if (use_it && station > 0 && station < station_to_keep) station_to_keep = station;
00374     stations.push_back(station);
00375 
00376     LogTrace(theCategory) << "rawId: " << raw_id << " station = " << station << " station_to_keep is now " << station_to_keep;
00377   }
00378 
00379   if (station_to_keep <= 0 || station_to_keep > 4 || stations.size() != all.size())
00380     LogInfo(theCategory) << "failed to getFirstHits (all muon hits are outliers/bad ?)! station_to_keep = " 
00381                             << station_to_keep << " stations.size " << stations.size() << " all.size " << all.size();
00382 
00383   for (unsigned i = 0; i < stations.size(); ++i)
00384     if (stations[i] >= 0 && stations[i] <= station_to_keep) first.push_back(all[i]);
00385 
00386   return;
00387 }
00388 
00389 
00390 //
00391 // select muon hits compatible with trajectory; 
00392 // check hits in chambers with showers
00393 //
00394 GlobalMuonRefitter::ConstRecHitContainer 
00395 GlobalMuonRefitter::selectMuonHits(const Trajectory& traj, 
00396                                    const std::vector<int>& hits) const {
00397 
00398   ConstRecHitContainer muonRecHits;
00399   const double globalChi2Cut = 200.0;
00400 
00401   vector<TrajectoryMeasurement> muonMeasurements = traj.measurements(); 
00402 
00403   // loop through all muon hits and skip hits with bad chi2 in chambers with high occupancy      
00404   for (std::vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end(); im++ ) {
00405 
00406     if ( !(*im).recHit()->isValid() ) continue;
00407     if ( (*im).recHit()->det()->geographicalId().det() != DetId::Muon ) {
00408       //      if ( ( chi2ndf < globalChi2Cut ) )
00409       muonRecHits.push_back((*im).recHit());
00410       continue;
00411     }  
00412     ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
00413 
00414     DetId id = immrh->geographicalId();
00415     int station = 0;
00416     int threshold = 0;
00417     double chi2Cut = 0.0;
00418 
00419     // get station of hit if it is in DT
00420     if ( (*immrh).isDT() ) {
00421       DTChamberId did(id.rawId());
00422       station = did.station();
00423       threshold = theHitThreshold;
00424       chi2Cut = theDTChi2Cut;
00425     }
00426     // get station of hit if it is in CSC
00427     else if ( (*immrh).isCSC() ) {
00428       CSCDetId did(id.rawId());
00429       station = did.station();
00430       threshold = theHitThreshold;
00431       chi2Cut = theCSCChi2Cut;
00432     }
00433     // get station of hit if it is in RPC
00434     else if ( (*immrh).isRPC() ) {
00435       RPCDetId rpcid(id.rawId());
00436       station = rpcid.station();
00437       threshold = theHitThreshold;
00438       chi2Cut = theRPCChi2Cut;
00439     }
00440     else
00441       continue;
00442 
00443     double chi2ndf = (*im).estimate()/(*im).recHit()->dimension();  
00444 
00445     bool keep = true;
00446     if ( (station>0) && (station<5) ) {
00447       if (hits[station-1]>threshold) keep = false;
00448     }   
00449     
00450     if ( (keep || (chi2ndf<chi2Cut)) && (chi2ndf<globalChi2Cut) ) {
00451       muonRecHits.push_back((*im).recHit());
00452     } else {
00453       LogTrace(theCategory)
00454         << "Skip hit: " << id.det() << " " << station << ", " 
00455         << chi2ndf << " (" << chi2Cut << " chi2 threshold) " 
00456         << hits[station-1] << endl;
00457     }
00458   }
00459   
00460   // check order of rechits
00461   reverse(muonRecHits.begin(),muonRecHits.end());
00462   return muonRecHits;
00463 }
00464 
00465 
00466 //
00467 // print RecHits
00468 //
00469 void GlobalMuonRefitter::printHits(const ConstRecHitContainer& hits) const {
00470 
00471   LogTrace(theCategory) << "Used RecHits: " << hits.size();
00472   for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00473     if ( !(*ir)->isValid() ) {
00474       LogTrace(theCategory) << "invalid RecHit";
00475       continue; 
00476     }
00477     
00478     const GlobalPoint& pos = (*ir)->globalPosition();
00479     
00480     LogTrace(theCategory) 
00481       << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
00482       << "  z = " << pos.z()
00483       << "  dimension = " << (*ir)->dimension()
00484       << "  det = " << (*ir)->det()->geographicalId().det()
00485       << "  subdet = " << (*ir)->det()->subDetector()
00486       << "  raw id = " << (*ir)->det()->geographicalId().rawId();
00487   }
00488 
00489 }
00490 
00491 
00492 //
00493 // add Trajectory* to TrackCand if not already present
00494 //
00495 GlobalMuonRefitter::RefitDirection
00496 GlobalMuonRefitter::checkRecHitsOrdering(const TransientTrackingRecHit::ConstRecHitContainer& recHits) const {
00497 
00498   if (!recHits.empty()){
00499     ConstRecHitContainer::const_iterator frontHit = recHits.begin();
00500     ConstRecHitContainer::const_iterator backHit  = recHits.end() - 1;
00501     while( !(*frontHit)->isValid() && frontHit != backHit) {frontHit++;}
00502     while( !(*backHit)->isValid() && backHit != frontHit)  {backHit--;}
00503 
00504     double rFirst = (*frontHit)->globalPosition().mag();
00505     double rLast  = (*backHit) ->globalPosition().mag();
00506 
00507     if(rFirst < rLast) return insideOut;
00508     else if(rFirst > rLast) return outsideIn;
00509     else {
00510       LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00511       return undetermined;
00512     }
00513   } else {
00514     LogError(theCategory) << "Impossible determine the rechits order" <<endl;
00515     return undetermined;
00516   }
00517 }
00518 
00519 
00520 //
00521 // Convert Tracks into Trajectories with a given set of hits
00522 //
00523 vector<Trajectory> GlobalMuonRefitter::transform(const reco::Track& newTrack,
00524                                                  const reco::TransientTrack track,
00525                                                  TransientTrackingRecHit::ConstRecHitContainer recHitsForReFit) const {
00526 
00527   LogTrace(theCategory) << "GlobalMuonRefitter::transform: " << recHitsForReFit.size() << " hits:";
00528   printHits(recHitsForReFit);
00529 
00530   if(recHitsForReFit.size() < 2) return vector<Trajectory>();
00531 
00532   // Check the order of the rechits
00533   RefitDirection recHitsOrder = checkRecHitsOrdering(recHitsForReFit);
00534 
00535   LogTrace(theCategory) << "checkRecHitsOrdering() returned " << recHitsOrder
00536                         << ", theRefitDirection is " << theRefitDirection
00537                         << " (insideOut == " << insideOut << ", outsideIn == " << outsideIn << ")";
00538 
00539   // Reverse the order in the case of inconsistency between the fit direction and the rechit order
00540   if(theRefitDirection != recHitsOrder) reverse(recHitsForReFit.begin(),recHitsForReFit.end());
00541 
00542   // Even though we checked the rechits' ordering above, we may have
00543   // already flipped them elsewhere (getFirstHits() is such a
00544   // culprit). Use the global positions of the states and the desired
00545   // refit direction to find the starting TSOS.
00546   TrajectoryStateOnSurface firstTSOS, lastTSOS;
00547   unsigned int innerId, outerId;
00548   bool order_swapped = track.outermostMeasurementState().globalPosition().mag() < track.innermostMeasurementState().globalPosition().mag();
00549   bool inner_is_first;
00550   LogTrace(theCategory) << "order swapped? " << order_swapped;
00551 
00552   // Fill the starting state, depending on the ordering above.
00553   if ((theRefitDirection == insideOut && !order_swapped) || (theRefitDirection == outsideIn && order_swapped)) {
00554     innerId   = newTrack.innerDetId();
00555     outerId   = newTrack.outerDetId();
00556     firstTSOS = track.innermostMeasurementState();
00557     lastTSOS  = track.outermostMeasurementState();
00558     inner_is_first = true;
00559   }
00560   else {
00561     innerId   = newTrack.outerDetId();
00562     outerId   = newTrack.innerDetId();
00563     firstTSOS = track.outermostMeasurementState();
00564     lastTSOS  = track.innermostMeasurementState();
00565     inner_is_first = false;
00566   } 
00567 
00568   LogTrace(theCategory) << "firstTSOS: inner_is_first? " << inner_is_first
00569                         << " globalPosition is " << firstTSOS.globalPosition()
00570                         << " innerId is " << innerId;
00571 
00572   if(!firstTSOS.isValid()){
00573     LogWarning(theCategory) << "Error wrong initial state!" << endl;
00574     return vector<Trajectory>();
00575   }
00576 
00577   firstTSOS.rescaleError(1000.);
00578 
00579   // This is the only way to get a TrajectorySeed with settable propagation direction
00580   PTrajectoryStateOnDet garbage1;
00581   edm::OwnVector<TrackingRecHit> garbage2;
00582   PropagationDirection propDir = 
00583     (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00584 
00585   // These lines cause the code to ignore completely what was set
00586   // above, and force propDir for tracks from collisions!
00587 //  if(propDir == alongMomentum && theRefitDirection == outsideIn)  propDir=oppositeToMomentum;
00588 //  if(propDir == oppositeToMomentum && theRefitDirection == insideOut) propDir=alongMomentum;
00589 
00590   const TrajectoryStateOnSurface& tsosForDir = inner_is_first ? lastTSOS : firstTSOS;
00591   propDir = (tsosForDir.globalPosition().basicVector().dot(tsosForDir.globalMomentum().basicVector())>0) ? alongMomentum : oppositeToMomentum;
00592   LogTrace(theCategory) << "propDir based on firstTSOS x dot p is " << propDir
00593                         << " (alongMomentum == " << alongMomentum << ", oppositeToMomentum == " << oppositeToMomentum << ")";
00594 
00595   // Additional propagation diretcion determination logic for cosmic muons
00596   if (theCosmicFlag) {
00597     PropagationDirection propDir_first = (firstTSOS.globalPosition().basicVector().dot(firstTSOS.globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00598     PropagationDirection propDir_last  = (lastTSOS .globalPosition().basicVector().dot(lastTSOS .globalMomentum().basicVector()) > 0) ? alongMomentum : oppositeToMomentum;
00599     LogTrace(theCategory) << "propDir_first " << propDir_first << ", propdir_last " << propDir_last
00600                           << " : they " << (propDir_first == propDir_last ? "agree" : "disagree");
00601 
00602     int y_count = 0;
00603     for (TransientTrackingRecHit::ConstRecHitContainer::const_iterator it = recHitsForReFit.begin(); it != recHitsForReFit.end(); ++it) {
00604       if ((*it)->globalPosition().y() > 0) ++y_count;
00605       else --y_count;
00606     }
00607     
00608     PropagationDirection propDir_ycount = alongMomentum;
00609     if (y_count > 0) {
00610       if      (theRefitDirection == insideOut) propDir_ycount = oppositeToMomentum;
00611       else if (theRefitDirection == outsideIn) propDir_ycount = alongMomentum;
00612     }
00613     else {
00614       if      (theRefitDirection == insideOut) propDir_ycount = alongMomentum;
00615       else if (theRefitDirection == outsideIn) propDir_ycount = oppositeToMomentum;
00616     }
00617     
00618     LogTrace(theCategory) << "y_count = " << y_count
00619                           << "; based on geometrically-outermost TSOS, propDir is " << propDir << ": "
00620                           << (propDir == propDir_ycount ? "agrees" : "disagrees")
00621                           << " with ycount determination";
00622     
00623     if (propDir_first != propDir_last) {
00624       LogTrace(theCategory) << "since first/last disagreed, using y_count propDir";
00625       propDir = propDir_ycount;
00626     }
00627   }
00628 
00629   TrajectorySeed seed(garbage1,garbage2,propDir);
00630 
00631   if(recHitsForReFit.front()->geographicalId() != DetId(innerId)){
00632     LogDebug(theCategory)<<"Propagation occured"<<endl;
00633     LogTrace(theCategory) << "propagating firstTSOS at " << firstTSOS.globalPosition()
00634                           << " to first rechit with surface pos " << recHitsForReFit.front()->det()->surface().toGlobal(LocalPoint(0,0,0));
00635     firstTSOS = theService->propagator(thePropagatorName)->propagate(firstTSOS, recHitsForReFit.front()->det()->surface());
00636     if(!firstTSOS.isValid()){
00637       LogDebug(theCategory)<<"Propagation error!"<<endl;
00638       return vector<Trajectory>();
00639     }
00640   }
00641 
00642 /*  
00643   cout << " GlobalMuonRefitter : theFitter " << propDir << endl;
00644   cout << "                      First TSOS: " 
00645        << firstTSOS.globalPosition() << "  p="
00646        << firstTSOS.globalMomentum() << " = "
00647        << firstTSOS.globalMomentum().mag() << endl;
00648        
00649   cout << "                      Starting seed: "
00650        << " nHits= " << seed.nHits()
00651        << " tsos: "
00652        << seed.startingState().parameters().position() << "  p="
00653        << seed.startingState().parameters().momentum() << endl;
00654        
00655   cout << "                      RecHits: "
00656        << recHitsForReFit.size() << endl;
00657 */
00658        
00659   vector<Trajectory> trajectories = theFitter->fit(seed,recHitsForReFit,firstTSOS);
00660   
00661   if(trajectories.empty()){
00662     LogDebug(theCategory) << "No Track refitted!" << endl;
00663     return vector<Trajectory>();
00664   }
00665   
00666   return trajectories;
00667 }
00668 
00669 
00670 //
00671 // Remove Selected Station Rec Hits
00672 //
00673 GlobalMuonRefitter::ConstRecHitContainer GlobalMuonRefitter::getRidOfSelectStationHits(ConstRecHitContainer hits) const
00674 {
00675   ConstRecHitContainer results;
00676   ConstRecHitContainer::const_iterator it = hits.begin();
00677   for (; it!=hits.end(); it++) {
00678 
00679     DetId id = (*it)->geographicalId();
00680 
00681     //Check that this is a Muon hit that we're toying with -- else pass on this because the hacker is a moron / not careful
00682 
00683     if (id.det() == DetId::Tracker && theTrackerSkipSystem > 0) {
00684       int layer = -999;
00685       int disk  = -999;
00686       int wheel = -999;
00687       if ( id.subdetId() == theTrackerSkipSystem){
00688         //                              continue;  //caveat that just removes the whole system from refitting
00689 
00690         if (theTrackerSkipSystem == PXB) {
00691           PXBDetId did(id.rawId());
00692           layer = did.layer();
00693         }
00694         if (theTrackerSkipSystem == TIB) {
00695           TIBDetId did(id.rawId());
00696           layer = did.layer();
00697         }
00698 
00699         if (theTrackerSkipSystem == TOB) {
00700           TOBDetId did(id.rawId());
00701           layer = did.layer();
00702         }
00703         if (theTrackerSkipSystem == PXF) {
00704           PXFDetId did(id.rawId());
00705           disk = did.disk();
00706         }
00707         if (theTrackerSkipSystem == TID) {
00708           TIDDetId did(id.rawId());
00709           wheel = did.wheel();
00710         }
00711         if (theTrackerSkipSystem == TEC) {
00712           TECDetId did(id.rawId());
00713           wheel = did.wheel();
00714         }
00715         if (theTrackerSkipSection >= 0 && layer == theTrackerSkipSection) continue;
00716         if (theTrackerSkipSection >= 0 && disk == theTrackerSkipSection) continue;
00717         if (theTrackerSkipSection >= 0 && wheel == theTrackerSkipSection) continue;
00718       }
00719     }
00720 
00721     if (id.det() == DetId::Muon && theSkipStation) {
00722       int station = -999;
00723       int wheel = -999;
00724       if ( id.subdetId() == MuonSubdetId::DT ) {
00725         DTChamberId did(id.rawId());
00726         station = did.station();
00727         wheel = did.wheel();
00728       } else if ( id.subdetId() == MuonSubdetId::CSC ) {
00729         CSCDetId did(id.rawId());
00730         station = did.station();
00731       } else if ( id.subdetId() == MuonSubdetId::RPC ) {
00732         RPCDetId rpcid(id.rawId());
00733         station = rpcid.station();
00734       }
00735       if(station == theSkipStation) continue;
00736     }
00737     results.push_back(*it);
00738   }
00739   return results;
00740 }
00741