CMS 3D CMS Logo

GlobalTrajectoryBuilderBase.cc

Go to the documentation of this file.
00001 
00024 #include "RecoMuon/GlobalTrackingTools/interface/GlobalTrajectoryBuilderBase.h"
00025 
00026 //---------------
00027 // C++ Headers --
00028 //---------------
00029 
00030 #include <iostream>
00031 #include <algorithm>
00032 
00033 //-------------------------------
00034 // Collaborating Class Headers --
00035 //-------------------------------
00036 
00037 #include "FWCore/Framework/interface/Event.h"
00038 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00039 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00040 
00041 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
00042 #include "TrackingTools/TrackFitters/interface/RecHitLessByDet.h"
00043 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00044 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00045 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00046 #include "TrackingTools/TrackRefitter/interface/TrackTransformer.h"
00047 
00048 #include "DataFormats/Math/interface/deltaR.h"
00049 
00050 #include "DataFormats/DetId/interface/DetId.h"
00051 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
00052 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00053 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00054 
00055 #include "DataFormats/TrackReco/interface/Track.h"
00056 #include "DataFormats/TrackReco/interface/TrackExtraFwd.h"
00057 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00058 
00059 #include "RecoTracker/TkTrackingRegions/interface/RectangularEtaPhiTrackingRegion.h"
00060 
00061 #include "RecoMuon/GlobalTrackingTools/interface/GlobalMuonTrackMatcher.h"
00062 #include "RecoMuon/MeasurementDet/interface/MuonDetLayerMeasurements.h"
00063 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHitBuilder.h"
00064 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
00065 #include "RecoMuon/TrackingTools/interface/MuonCandidate.h"
00066 #include "RecoMuon/TrackingTools/interface/MuonServiceProxy.h"
00067 
00068 #include "RecoMuon/GlobalTrackingTools/interface/MuonTrackingRegionBuilder.h"
00069 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00070 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00071 #include "TrackingTools/PatternTools/interface/TrajectoryFitter.h"
00072 #include "TrackingTools/TransientTrackingRecHit/interface/TransientTrackingRecHitBuilder.h"
00073 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
00074 
00075 #include "RecoTracker/TkTrackingRegions/interface/TkTrackingRegionsMargin.h"
00076 #include "RecoTracker/TkMSParametrization/interface/PixelRecoRange.h"
00077 
00078 using namespace std;
00079 using namespace edm;
00080 
00081 //----------------
00082 // Constructors --
00083 //----------------
00084 GlobalTrajectoryBuilderBase::GlobalTrajectoryBuilderBase(const edm::ParameterSet& par,
00085                                                          const MuonServiceProxy* service) : 
00086  theService(service) {
00087 
00088   theCategory = par.getUntrackedParameter<string>("Category", "Muon|RecoMuon|GlobalMuon|GlobalTrajectoryBuilderBase");
00089 
00090   theLayerMeasurements = new MuonDetLayerMeasurements(par.getParameter<InputTag>("DTRecSegmentLabel"),
00091                                                       par.getParameter<InputTag>("CSCRecSegmentLabel"),
00092                                                       par.getParameter<InputTag>("RPCRecSegmentLabel"));
00093   
00094   string MatcherOutPropagator = par.getParameter<string>("MatcherOutPropagator");
00095   string TransformerOutPropagator = par.getParameter<string>("TransformerOutPropagator");
00096   
00097   ParameterSet trackMatcherPSet = par.getParameter<ParameterSet>("GlobalMuonTrackMatcher");
00098   trackMatcherPSet.addParameter<string>("Propagator",MatcherOutPropagator);
00099   theTrackMatcher = new GlobalMuonTrackMatcher(trackMatcherPSet,theService);
00100   
00101   theTrackerPropagatorName = par.getParameter<string>("TrackerPropagator");
00102 
00103   ParameterSet trackTransformerPSet = par.getParameter<ParameterSet>("TrackTransformer");
00104   trackTransformerPSet.addParameter<string>("Propagator",TransformerOutPropagator);
00105   theTrackTransformer = new TrackTransformer(trackTransformerPSet);
00106 
00107   ParameterSet regionBuilderPSet = par.getParameter<ParameterSet>("MuonTrackingRegionBuilder");
00108   regionBuilderPSet.addParameter<bool>("RegionalSeedFlag",false);
00109 
00110   theRegionBuilder = new MuonTrackingRegionBuilder(regionBuilderPSet,theService);
00111 
00112   theTrackerRecHitBuilderName = par.getParameter<string>("TrackerRecHitBuilder");
00113   theMuonRecHitBuilderName = par.getParameter<string>("MuonRecHitBuilder");  
00114 
00115   theRPCInTheFit = par.getParameter<bool>("RefitRPCHits");
00116 
00117   theMuonHitsOption = par.getParameter<int>("MuonHitsOption");
00118   thePtCut = par.getParameter<double>("PtCut");
00119   theProbCut = par.getParameter<double>("Chi2ProbabilityCut");
00120   theHitThreshold = par.getParameter<int>("HitThreshold");
00121   theDTChi2Cut  = par.getParameter<double>("Chi2CutDT");
00122   theCSCChi2Cut = par.getParameter<double>("Chi2CutCSC");
00123   theRPCChi2Cut = par.getParameter<double>("Chi2CutRPC");
00124   theKFFitterName = par.getParameter<string>("KFFitter");
00125   theTkTrajsAvailableFlag = true; 
00126 
00127   theCacheId_TRH = 0;
00128 
00129 }
00130 
00131 
00132 //--------------
00133 // Destructor --
00134 //--------------
00135 GlobalTrajectoryBuilderBase::~GlobalTrajectoryBuilderBase() {
00136 
00137   if (theTrackMatcher) delete theTrackMatcher;
00138   if (theLayerMeasurements) delete theLayerMeasurements;
00139   if (theRegionBuilder) delete theRegionBuilder;
00140   if (theTrackTransformer) delete theTrackTransformer;
00141 
00142 }
00143 
00144 
00145 //
00146 // set Event
00147 //
00148 void GlobalTrajectoryBuilderBase::setEvent(const edm::Event& event) {
00149   
00150   theEvent = &event;
00151   theLayerMeasurements->setEvent(event);  
00152   theService->eventSetup().get<TrackingComponentsRecord>().get(theKFFitterName,theKFFitter);
00153   theTrackTransformer->setServices(theService->eventSetup());
00154   theRegionBuilder->setEvent(event);
00155 
00156   unsigned long long newCacheId_TRH = theService->eventSetup().get<TransientRecHitRecord>().cacheIdentifier();
00157   if ( newCacheId_TRH != theCacheId_TRH ) {
00158     LogDebug(theCategory) << "TransientRecHitRecord changed!";
00159     theCacheId_TRH = newCacheId_TRH;
00160     theService->eventSetup().get<TransientRecHitRecord>().get(theTrackerRecHitBuilderName,theTrackerRecHitBuilder);
00161     theService->eventSetup().get<TransientRecHitRecord>().get(theMuonRecHitBuilderName,theMuonRecHitBuilder);
00162 
00163   }
00164 
00165 }
00166 
00167 
00168 //
00169 // build a combined tracker-muon trajectory
00170 //
00171 MuonCandidate::CandidateContainer 
00172 GlobalTrajectoryBuilderBase::build(const TrackCand& staCand,
00173                                    MuonCandidate::CandidateContainer& tkTrajs) const {
00174 
00175   // MuonHitsOption: 0 - tracker only
00176   //                 1 - include all muon hits
00177   //                 2 - include only first muon hit(s)
00178   //                 3 - include only selected muon hits
00179   //                 4 - combined
00180   //                 5 - new combined
00181   //
00182 
00183   // tracker trajectory should be built and refit before this point
00184   LogTrace(theCategory) << "build begin. ";
00185 
00186   if ( tkTrajs.empty() ) return CandidateContainer();
00187 
00188   // add muon hits and refit/smooth trajectories
00189   CandidateContainer refittedResult;
00190   
00191   if ( theMuonHitsOption > 0 ) {
00192 
00193     vector<int> stationHits(4,0);
00194     ConstRecHitContainer muonRecHits1; // all muon rechits
00195     ConstRecHitContainer muonRecHits2; // only first muon rechits
00196     ConstRecHitContainer muonRecHits3; // selected muon rechits
00197 
00198     // check and select muon measurements and
00199     // measure occupancy in muon stations
00200     checkMuonHits(*(staCand.second), muonRecHits1, muonRecHits2, stationHits);
00201     
00202     for ( CandidateContainer::const_iterator it = tkTrajs.begin(); it != tkTrajs.end(); it++ ) {
00203 
00204       // cut on tracks with low momenta
00205       const GlobalVector& mom = (*it)->trackerTrajectory()->lastMeasurement().updatedState().globalMomentum();
00206       if ( mom.mag() < 2.5 || mom.perp() < thePtCut ) continue;
00207 
00208       TransientTrackingRecHit::ConstRecHitContainer trackerRecHits;
00209       if((*it)->trackerTrack().isNonnull()){
00210         reco::TransientTrack track(*(*it)->trackerTrack(),&*(theService->magneticField()),theService->trackingGeometry());    LogDebug(theCategory);  
00211         trackerRecHits = getTransientRecHits(track);      LogDebug(theCategory);  
00212       } else {
00213         trackerRecHits = (*it)->trackerTrajectory()->recHits();
00214       }
00215 
00216       // check for single TEC RecHits in trajectories in the overalp region
00217       if ( fabs(mom.eta()) > 0.95 && fabs(mom.eta()) < 1.15 ) trackerRecHits = selectTrackerHits(trackerRecHits);
00218                   
00219       RefitDirection recHitDir = checkRecHitsOrdering(trackerRecHits);
00220       if ( recHitDir == outToIn ) reverse(trackerRecHits.begin(),trackerRecHits.end());
00221 
00222       TrajectoryMeasurement innerTM = ( (*it)->trackerTrajectory()->direction() == alongMomentum ) ? (*it)->trackerTrajectory()->firstMeasurement() : (*it)->trackerTrajectory()->lastMeasurement();
00223       
00224       TrajectoryStateOnSurface innerTsos = innerTM.updatedState();
00225       
00226       // for cases when the tracker trajectory has not been smoothed
00227           // propagate the outer state to the innermost measurment surface      
00228       LogTrace(theCategory)<<"BackwardPredictedState "<<innerTM.backwardPredictedState().isValid();
00229       if ( !innerTM.backwardPredictedState().isValid() ) {
00230             TrajectoryMeasurement outerTM = ((*it)->trackerTrajectory()->direction() == alongMomentum) ? (*it)->trackerTrajectory()->lastMeasurement() : (*it)->trackerTrajectory()->firstMeasurement();
00231                 TrajectoryStateOnSurface outerTsos = outerTM.updatedState();
00232 
00233            TrajectoryStateOnSurface innerTsos2;
00234            if ( trackerRecHits.front()->geographicalId().det() == DetId::Tracker ) {
00235              innerTsos2 = theService->propagator(theTrackerPropagatorName)->propagate(outerTsos,trackerRecHits.front()->det()->surface());
00236            }
00237            if ( innerTsos2.isValid() ) innerTsos = innerTsos2;
00238       }
00239 
00240       if ( !innerTsos.isValid() ) {
00241             LogTrace(theCategory) << "inner Trajectory State is invalid. ";
00242             continue;
00243       }
00244       innerTsos.rescaleError(100.);
00245                   
00246       TC refitted1,refitted2,refitted3;
00247       vector<Trajectory*> refit(4);
00248       MuonCandidate* finalTrajectory = 0;
00249       
00250       // tracker only track
00251       refit[0] = (*it)->trackerTrajectory();
00252       ConstRecHitContainer rechits(trackerRecHits);
00253 
00254       // full track with all muon hits
00255       if ( theMuonHitsOption == 1 || theMuonHitsOption == 3 || theMuonHitsOption == 4 ||  theMuonHitsOption == 5 ) {
00256         refitted1 = glbTrajectory((*it)->trackerTrajectory()->seed(),trackerRecHits, muonRecHits1,innerTsos);
00257       }
00258 
00259       // only first muon hits
00260       if ( theMuonHitsOption == 2 || theMuonHitsOption == 4 || theMuonHitsOption == 5 ) {
00261         refitted2 = glbTrajectory((*it)->trackerTrajectory()->seed(),trackerRecHits, muonRecHits2,innerTsos);
00262       }
00263 
00264       // only selected muon hits
00265       if ( (theMuonHitsOption == 3 || theMuonHitsOption == 4 || theMuonHitsOption == 5) && refitted1.size() == 1 ) {
00266         muonRecHits3 = selectMuonHits(*refitted1.begin(),stationHits);
00267         refitted3 = glbTrajectory((*it)->trackerTrajectory()->seed(),trackerRecHits, muonRecHits3,innerTsos);
00268       }
00269 
00270       refit[1] = ( refitted1.empty() ) ? 0 : &(*refitted1.begin());
00271       refit[2] = ( refitted2.empty() ) ? 0 : &(*refitted2.begin());
00272       refit[3] = ( refitted3.empty() ) ? 0 : &(*refitted3.begin());
00273 
00274       const Trajectory* chosenTrajectory = chooseTrajectory(refit, theMuonHitsOption);
00275       if (chosenTrajectory) {
00276             Trajectory *tmpTrajectory = new Trajectory(*chosenTrajectory);
00277             tmpTrajectory->setSeedRef((*it)->trackerTrajectory()->seedRef());
00278             finalTrajectory = new MuonCandidate(tmpTrajectory, (*it)->muonTrack(), (*it)->trackerTrack(), new Trajectory(*(*it)->trackerTrajectory()));
00279       } else {
00280             LogError(theCategory)<<"could not choose a valid trajectory. skipping the muon. no final trajectory.";
00281       }
00282 
00283       if ( finalTrajectory ) {
00284         refittedResult.push_back(finalTrajectory);
00285       }
00286     }
00287   }
00288   else {
00289     LogTrace(theCategory)<<"theMuonHitsOption="<<theMuonHitsOption<<"\n"
00290                       <<tkTrajs.size()<<" total trajectories.";
00291     // do not just copy the collection over
00292         // we need to refit it for the smoother to work properly
00293 
00294         // refittedResult = tkTrajs;
00295           
00296     // loop over tracker trajectories and refit them
00297     for ( CandidateContainer::const_iterator it = tkTrajs.begin(); it != tkTrajs.end(); it++ ) {
00298       vector<Trajectory> tmp = refitTrajectory(*((*it)->trackerTrajectory()));
00299       for (vector<Trajectory>::iterator nit = tmp.begin(); nit != tmp.end(); ++nit) {
00300         refittedResult.push_back(new MuonCandidate(new Trajectory(*nit),(*it)->muonTrack(),(*it)->trackerTrack(), new Trajectory(*nit)));
00301       }
00302     }
00303   }
00304 
00305   // choose the best global fit for this Standalone Muon based on the track probability
00306   CandidateContainer selectedResult;
00307   MuonCandidate* tmpCand = 0;
00308   if ( refittedResult.size() > 0 ) tmpCand = *(refittedResult.begin());
00309   double minProb = 9999;
00310 
00311   for (CandidateContainer::const_iterator iter=refittedResult.begin(); iter != refittedResult.end(); iter++) {
00312     double prob = trackProbability(*(*iter)->trajectory());
00313     if (prob < minProb) {
00314       minProb = prob;
00315       tmpCand = (*iter);
00316     }
00317   }
00318 
00319   if ( tmpCand )  selectedResult.push_back(new MuonCandidate(new Trajectory(*(tmpCand->trajectory())), tmpCand->muonTrack(), tmpCand->trackerTrack(), new Trajectory( *(tmpCand->trackerTrajectory()) ) ) );
00320 
00321   for (CandidateContainer::const_iterator it = refittedResult.begin(); it != refittedResult.end(); ++it) {
00322     if ( (*it)->trajectory() ) delete (*it)->trajectory();
00323     if ( (*it)->trackerTrajectory() ) delete (*it)->trackerTrajectory();
00324     if ( *it ) delete (*it);
00325   }
00326   refittedResult.clear();
00327 
00328   return selectedResult;
00329 
00330 }
00331 
00332 
00333 //
00334 // select tracker tracks within a region of interest
00335 //
00336 vector<GlobalTrajectoryBuilderBase::TrackCand> 
00337 GlobalTrajectoryBuilderBase::chooseRegionalTrackerTracks(const TrackCand& staCand, 
00338                                                          const vector<TrackCand>& tkTs) {
00339   
00340   // define eta-phi region
00341   RectangularEtaPhiTrackingRegion regionOfInterest = defineRegionOfInterest(staCand.second);
00342   
00343   // get region's etaRange and phiMargin
00344   PixelRecoRange<float> etaRange = regionOfInterest.etaRange();
00345   TkTrackingRegionsMargin<float> phiMargin = regionOfInterest.phiMargin();
00346 
00347   vector<TrackCand> result;
00348 
00349   double deltaR_max = 1.0;
00350 
00351   for ( vector<TrackCand>::const_iterator is = tkTs.begin(); is != tkTs.end(); ++is ) {
00352     // check if each trackCand is in region of interest
00353 //    bool inEtaRange = etaRange.inside(is->second->eta());
00354 //    bool inPhiRange = (fabs(Geom::Phi<float>(is->second->phi()) - Geom::Phi<float>(regionOfInterest.direction().phi())) < phiMargin.right() ) ? true : false ;
00355 
00356     double deltaR_tmp = deltaR(static_cast<double>(regionOfInterest.direction().eta()),
00357                                                            static_cast<double>(regionOfInterest.direction().phi()),
00358                                                            is->second->eta(), is->second->phi());
00359 
00360     // for each trackCand in region, add trajectory and add to result
00361     //if ( inEtaRange && inPhiRange ) {
00362     if (deltaR_tmp < deltaR_max) {
00363       TrackCand tmpCand = TrackCand(*is);
00364       LogTrace(theCategory) << "Adding Traj to Tk";
00365       addTraj(tmpCand);
00366       result.push_back(tmpCand);
00367     }
00368   }
00369 
00370   return result; 
00371 
00372 }
00373 
00374 
00375 //
00376 // define a region of interest within the tracker
00377 //
00378 RectangularEtaPhiTrackingRegion 
00379 GlobalTrajectoryBuilderBase::defineRegionOfInterest(const reco::TrackRef& staTrack) const {
00380 
00381   RectangularEtaPhiTrackingRegion* region1 = theRegionBuilder->region(staTrack);
00382   
00383   TkTrackingRegionsMargin<float> etaMargin(fabs(region1->etaRange().min() - region1->etaRange().mean()),
00384                                            fabs(region1->etaRange().max() - region1->etaRange().mean()));
00385   
00386   RectangularEtaPhiTrackingRegion region2(region1->direction(),
00387                                           region1->origin(),
00388                                           region1->ptMin(),
00389                                           region1->originRBound(),
00390                                           region1->originZBound(),
00391                                           etaMargin,
00392                                           region1->phiMargin());
00393   
00394   delete region1;
00395   return region2;
00396   
00397 }
00398 
00399 
00400 //
00401 // check muon RecHits, calculate chamber occupancy and select hits to be used in the final fit
00402 //
00403 void GlobalTrajectoryBuilderBase::checkMuonHits(const reco::Track& muon, 
00404                                                 ConstRecHitContainer& all,
00405                                                 ConstRecHitContainer& first,
00406                                                 std::vector<int>& hits) const {
00407 
00408   int dethits[4];
00409   for ( int i=0; i<4; i++ ) hits[i]=dethits[i]=0;
00410   
00411   reco::TransientTrack track(muon,&*(theService->magneticField()),theService->trackingGeometry());
00412   TransientTrackingRecHit::ConstRecHitContainer muonRecHits = getTransientRecHits(track);
00413 
00414 //  all.assign(muonRecHits.begin(),muonRecHits.end()); //FIXME: should use this
00415 
00416   // loop through all muon hits and calculate the maximum # of hits in each chamber      
00417   for (ConstRecHitContainer::const_iterator imrh = muonRecHits.begin(); imrh != muonRecHits.end(); imrh++ ) {
00418 
00419     if ( (*imrh != 0 ) && !(*imrh)->isValid() ) continue;
00420 
00421     if ( theMuonHitsOption == 3 || theMuonHitsOption == 4 || theMuonHitsOption == 5 ) {
00422       
00423       int station = 0;
00424       int detRecHits = 0;
00425       
00426       DetId id = (*imrh)->geographicalId();
00427       const DetLayer* layer = theService->detLayerGeometry()->idToLayer(id);
00428       MuonRecHitContainer dRecHits = theLayerMeasurements->recHits(layer);
00429       // get station of hit if it is in DT
00430       if ( id.subdetId() == MuonSubdetId::DT ) {
00431         DTChamberId did(id.rawId());
00432         station = did.station();
00433         float coneSize = 10.0;
00434         
00435         bool hitUnique = false;
00436         ConstRecHitContainer all2dRecHits;
00437         for (MuonRecHitContainer::const_iterator ir = dRecHits.begin(); ir != dRecHits.end(); ir++ ) {
00438           if ( (**ir).dimension() == 2 ) {
00439             hitUnique = true;
00440             if ( all2dRecHits.size() > 0 ) {
00441               for (ConstRecHitContainer::const_iterator iir = all2dRecHits.begin(); iir != all2dRecHits.end(); iir++ ) 
00442                 if (((*iir)->localPosition()-(*ir)->localPosition()).mag()<0.01) hitUnique = false;
00443             } //end of if ( all2dRecHits.size() > 0 )
00444             if ( hitUnique ) all2dRecHits.push_back((*ir).get()); //FIXME!!
00445           } else {
00446             ConstRecHitContainer sRecHits = (**ir).transientHits();
00447             for (ConstRecHitContainer::const_iterator iir = sRecHits.begin(); iir != sRecHits.end(); iir++ ) {
00448               if ( (*iir)->dimension() == 2 ) {
00449                 hitUnique = true;
00450                 if ( !all2dRecHits.empty() ) {
00451                   for (ConstRecHitContainer::const_iterator iiir = all2dRecHits.begin(); iiir != all2dRecHits.end(); iiir++ ) 
00452                     if (((*iiir)->localPosition()-(*iir)->localPosition()).mag()<0.01) hitUnique = false;
00453                 }//end of if ( all2dRecHits.size() > 0 )
00454               }//end of if ( (*iir).dimension() == 2 ) 
00455               if ( hitUnique )
00456                 all2dRecHits.push_back(*iir);
00457               break;
00458             }//end of for sRecHits
00459           }// end of else
00460         }// end of for loop over dRecHits
00461         for (ConstRecHitContainer::const_iterator ir = all2dRecHits.begin(); ir != all2dRecHits.end(); ir++ ) {
00462           double rhitDistance = ((*ir)->localPosition()-(**imrh).localPosition()).mag();
00463           if ( rhitDistance < coneSize ) detRecHits++;
00464           LogTrace(theCategory) << " Station " << station << " DT "<<(*ir)->dimension()<<" " << (*ir)->localPosition()
00465                                                       << " Distance: "<< rhitDistance<<" recHits: "<< detRecHits;
00466         }// end of for all2dRecHits
00467       }// end of if DT
00468       // get station of hit if it is in CSC
00469       else if ( id.subdetId() == MuonSubdetId::CSC ) {
00470         CSCDetId did(id.rawId());
00471         station = did.station();
00472         
00473         float coneSize = 10.0;
00474         
00475         for (MuonRecHitContainer::const_iterator ir = dRecHits.begin(); ir != dRecHits.end(); ir++ ) {
00476           double rhitDistance = ((**ir).localPosition()-(**imrh).localPosition()).mag();
00477           if ( rhitDistance < coneSize ) detRecHits++;
00478           LogTrace(theCategory) << " Station " << station << " CSC "<<(**ir).dimension()<<" "<<(**ir).localPosition()
00479                                                   << " Distance: "<< rhitDistance<<" recHits: "<<detRecHits;
00480         }
00481       }
00482       // get station of hit if it is in RPC
00483       else if ( id.subdetId() == MuonSubdetId::RPC ) {
00484         RPCDetId rpcid(id.rawId());
00485         station = rpcid.station();
00486         float coneSize = 100.0;
00487         for (MuonRecHitContainer::const_iterator ir = dRecHits.begin(); ir != dRecHits.end(); ir++ ) {
00488           double rhitDistance = ((**ir).localPosition()-(**imrh).localPosition()).mag();
00489           if ( rhitDistance < coneSize ) detRecHits++;
00490           LogTrace(theCategory)<<" Station "<<station<<" RPC "<<(**ir).dimension()<<" "<< (**ir).localPosition()
00491                                                      <<" Distance: "<<rhitDistance<<" recHits: "<<detRecHits;
00492         }
00493       }
00494       else {
00495         LogError(theCategory)<<" Wrong Hit Type ";
00496         continue;      
00497       }
00498       
00499       if ( (station > 0) && (station < 5) ) {
00500         int detHits = dRecHits.size();
00501         dethits[station-1] += detHits;
00502         if ( detRecHits > hits[station-1] ) hits[station-1] = detRecHits;
00503       }
00504     } //end of if option 3, 4, 5
00505 
00506     all.push_back((*imrh).get()); //FIXME: may need fast assignment on above
00507 
00508   } // end of loop over muon rechits
00509   if ( theMuonHitsOption == 3 || theMuonHitsOption == 4 || theMuonHitsOption == 5 )  {
00510     for ( int i = 0; i < 4; i++ ) {
00511       LogTrace(theCategory) <<"Station "<<i+1<<": "<<hits[i]<<" "<<dethits[i]; 
00512     }
00513   }     
00514   
00515   //
00516   // check order of muon measurements
00517   //
00518   LogTrace(theCategory) << "CheckMuonHits "<<all.size();
00519 
00520   if ( (all.size() > 1) &&
00521        ( all.front()->globalPosition().mag() >
00522          all.back()->globalPosition().mag() ) ) {
00523     LogTrace(theCategory)<< "reverse order: ";
00524     stable_sort(all.begin(),all.end(),RecHitLessByDet(alongMomentum));
00525   }
00526 
00527   stable_sort(all.begin(),all.end(),ComparatorInOut());
00528   
00529   int station1 = -999;
00530   int station2 = -999;
00531   for (ConstRecHitContainer::const_iterator ihit = all.begin(); ihit != all.end(); ihit++ ) {
00532 
00533     if ( !(*ihit)->isValid() ) continue;
00534     station1 = -999; station2 = -999;
00535     // store muon hits one at a time.
00536     first.push_back(*ihit);
00537     
00538     ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*ihit).get()); //FIXME
00539     DetId id = immrh->geographicalId();
00540     
00541     // get station of 1st hit if it is in DT
00542     if ( (*immrh).isDT()  ) {
00543       DTChamberId did(id.rawId());
00544       station1 = did.station();
00545     }
00546     // otherwise get station of 1st hit if it is in CSC
00547     else if  ( (*immrh).isCSC() ) {
00548       CSCDetId did(id.rawId());
00549       station1 = did.station();
00550     }
00551     // check next RecHit
00552     ConstRecHitContainer::const_iterator nexthit(ihit);
00553     nexthit++;
00554     
00555     if ( ( nexthit != all.end()) && (*nexthit)->isValid() ) {
00556       
00557       ConstMuonRecHitPointer immrh2 = dynamic_cast<const MuonTransientTrackingRecHit*>((*nexthit).get());
00558       DetId id2 = immrh2->geographicalId();
00559       
00560       // get station of 1st hit if it is in DT
00561       if ( (*immrh2).isDT()  ) {
00562         DTChamberId did2(id2.rawId());
00563         station2 = did2.station();
00564       }
00565       // otherwise get station of 1st hit if it is in CSC
00566       else if  ( (*immrh2).isCSC() ) {
00567         CSCDetId did2(id2.rawId());
00568         station2 = did2.station();
00569       }
00570       
00571       // 1st hit is in station 1 and second hit is in a different station
00572       // or an rpc (if station = -999 it could be an rpc hit)
00573       if ( (station1 != -999) && ((station2 == -999) || (station2 > station1)) ) {
00574         LogTrace(theCategory) << "checkMuonHits:";
00575         LogTrace(theCategory) << " station 1 = "<<station1 
00576                                                    <<", r = "<< (*ihit)->globalPosition().perp()
00577                                                    <<", z = "<< (*ihit)->globalPosition().z() << ", "; 
00578         
00579         LogTrace(theCategory) << " station 2 = " << station2
00580                                                    <<", r = "<<(*(nexthit))->globalPosition().perp()
00581                                                    <<", z = "<<(*(nexthit))->globalPosition().z() << ", ";
00582         return;
00583       }
00584     }
00585     else if ( (nexthit == all.end()) && (station1 != -999) ) {
00586       LogTrace(theCategory) << "checkMuonHits:";
00587       LogTrace(theCategory) << " station 1 = "<< station1
00588                                               << ", r = " << (*ihit)->globalPosition().perp()
00589                                               << ", z = " << (*ihit)->globalPosition().z() << ", "; 
00590       return;
00591     }
00592   }
00593   // if none of the above is satisfied, return blank vector
00594   first.clear();
00595 
00596   return; 
00597 
00598 }
00599 
00600 
00601 //
00602 // select muon hits compatible with trajectory; 
00603 // check hits in chambers with showers
00604 //
00605 GlobalTrajectoryBuilderBase::ConstRecHitContainer 
00606 GlobalTrajectoryBuilderBase::selectMuonHits(const Trajectory& traj, 
00607                                             const std::vector<int>& hits) const {
00608 
00609   ConstRecHitContainer muonRecHits;
00610   const double globalChi2Cut = 200.0;
00611 
00612   vector<TrajectoryMeasurement> muonMeasurements = traj.measurements(); 
00613 
00614   // loop through all muon hits and skip hits with bad chi2 in chambers with high occupancy      
00615   for (vector<TrajectoryMeasurement>::const_iterator im = muonMeasurements.begin(); im != muonMeasurements.end(); im++ ) {
00616 
00617     if ( !(*im).recHit()->isValid() ) continue;
00618     if ( (*im).recHit()->det()->geographicalId().det() != DetId::Muon ) continue;
00619     ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*im).recHit().get());
00620 
00621     DetId id = immrh->geographicalId();
00622     int station = 0;
00623     int threshold = 0;
00624     double chi2Cut = 0.0;
00625 
00626     // get station of hit if it is in DT
00627     if ( (*immrh).isDT() ) {
00628       DTChamberId did(id.rawId());
00629       station = did.station();
00630       threshold = theHitThreshold;
00631       chi2Cut = theDTChi2Cut;
00632     }
00633     // get station of hit if it is in CSC
00634     else if ( (*immrh).isCSC() ) {
00635       CSCDetId did(id.rawId());
00636       station = did.station();
00637       threshold = theHitThreshold;
00638       chi2Cut = theCSCChi2Cut;
00639     }
00640     // get station of hit if it is in RPC
00641     else if ( (*immrh).isRPC() ) {
00642       RPCDetId rpcid(id.rawId());
00643       station = rpcid.station();
00644       threshold = theHitThreshold;
00645       chi2Cut = theRPCChi2Cut;
00646     }
00647     else {
00648       continue;
00649     }
00650 
00651     double chi2ndf = (*im).estimate()/(*im).recHit()->dimension();  
00652 
00653     bool keep = true;
00654     if ( (station > 0) && (station < 5) ) {
00655       if ( hits[station-1] > threshold ) keep = false;
00656     }   
00657     
00658     if ( (keep || ( chi2ndf < chi2Cut )) && ( chi2ndf < globalChi2Cut ) ) {
00659       muonRecHits.push_back((*im).recHit());
00660     } else {
00661       LogTrace(theCategory)
00662         << "Skip hit: " << id.det() << " " << station << ", " 
00663         << chi2ndf << " (" << chi2Cut << " chi2 threshold) " 
00664         << hits[station-1] << endl;
00665     }
00666 
00667   }
00668   
00669   // check order of rechits
00670   reverse(muonRecHits.begin(),muonRecHits.end());
00671 
00672   return muonRecHits;
00673 
00674 }
00675 
00676 
00677 //
00678 // choose final trajectory
00679 //
00680 const Trajectory* 
00681 GlobalTrajectoryBuilderBase::chooseTrajectory(const std::vector<Trajectory*>& t, 
00682                                               int muonHitsOption) const {
00683 
00684   Trajectory* result = 0;
00685   
00686   if ( muonHitsOption == 0 ) {
00687     if (t[0]) result = t[0];
00688     return result;
00689   } else if ( muonHitsOption == 1 ) {
00690     if (t[1]) result = t[1];
00691     return result;
00692   } else if ( muonHitsOption == 2 ) {
00693     if (t[2]) result = t[2];
00694     return result;
00695   } else if ( muonHitsOption == 3 ) {
00696     if (t[3]) result = t[3];
00697     return result;
00698   } else if ( muonHitsOption == 4 ) {
00699     double prob0 = ( t[0] ) ? trackProbability(*t[0]) : 0.0;
00700     double prob1 = ( t[1] ) ? trackProbability(*t[1]) : 0.0;
00701     double prob2 = ( t[2] ) ? trackProbability(*t[2]) : 0.0;
00702     double prob3 = ( t[3] ) ? trackProbability(*t[3]) : 0.0; 
00703     
00704     LogTrace(theCategory) << "Probabilities: " << prob0 << " " << prob1 << " " << prob2 << " " << prob3 << endl;
00705     
00706     if ( t[1] ) result = t[1];
00707     if ( (t[1] == 0) && t[3] ) result = t[3];
00708   
00709     if ( t[1] && t[3] && ( (prob1 - prob3) > 0.05 )  )  result = t[3];
00710 
00711     if ( t[0] && t[2] && fabs(prob2 - prob0) > theProbCut ) {
00712       LogTrace(theCategory) << "select Tracker only: -log(prob) = " << prob0 << endl;
00713       result = t[0];
00714       return result;
00715     }
00716 
00717     if ( (t[1] == 0) && (t[3] == 0) && t[2] ) result = t[2];
00718 
00719     Trajectory* tmin = 0;
00720     double probmin = 0.0;
00721     if ( t[1] && t[3] ) {
00722       probmin = prob3; tmin = t[3];
00723       if ( prob1 < prob3 ) { probmin = prob1; tmin = t[1]; }
00724     }
00725     else if ( (t[3] == 0) && t[1] ) { 
00726       probmin = prob1; tmin = t[1]; 
00727     }
00728     else if ( (t[1] == 0) && t[3] ) {
00729       probmin = prob3; tmin = t[3]; 
00730     }
00731 
00732     if ( tmin && t[2] && ( (probmin - prob2) > 3.5 )  ) {
00733       result = t[2];
00734     }
00735 
00736   } else if ( muonHitsOption == 5 ) {
00737 
00738     double prob[4];
00739     int chosen=3;
00740     for (int i=0;i<4;i++) 
00741       prob[i] = (t[i]) ? trackProbability(*t[i]) : 0.0; 
00742 
00743     if (!t[3])
00744       if (t[2]) chosen=2; else
00745         if (t[1]) chosen=1; else
00746           if (t[0]) chosen=0;
00747 
00748     if ( t[0] && t[3] && ((prob[3]-prob[0]) > 48.) ) chosen=0;
00749     if ( t[0] && t[1] && ((prob[1]-prob[0]) < 3.) ) chosen=1;
00750     if ( t[2] && ((prob[chosen]-prob[2]) > 9.) ) chosen=2;
00751     
00752     LogTrace(theCategory) << "Chosen Trajectory " << chosen;
00753     
00754     result=t[chosen];
00755   }
00756   else {
00757     LogTrace(theCategory) << "Wrong Hits Option in Choosing Trajectory ";
00758   } 
00759   return result;
00760 
00761 }
00762 
00763 
00764 //
00765 // calculate the tail probability (-ln(P)) of a fit
00766 //
00767 double 
00768 GlobalTrajectoryBuilderBase::trackProbability(const Trajectory& track) const {
00769 
00770   int nDOF = 0;
00771   ConstRecHitContainer rechits = track.recHits();
00772   for ( ConstRecHitContainer::const_iterator i = rechits.begin(); i != rechits.end(); ++i ) {
00773     if ((*i)->isValid()) nDOF += (*i)->dimension();
00774   }
00775   
00776   nDOF = max(nDOF - 5, 0);
00777   double prob = -LnChiSquaredProbability(track.chiSquared(), nDOF);
00778   
00779   return prob;
00780 
00781 }
00782 
00783 
00784 //
00785 // print RecHits
00786 //
00787 void GlobalTrajectoryBuilderBase::printHits(const ConstRecHitContainer& hits) const {
00788 
00789   LogTrace(theCategory) << "Used RecHits: " << hits.size();
00790   for (ConstRecHitContainer::const_iterator ir = hits.begin(); ir != hits.end(); ir++ ) {
00791     if ( !(*ir)->isValid() ) {
00792       LogTrace(theCategory) << "invalid RecHit";
00793       continue; 
00794     }
00795     
00796     const GlobalPoint& pos = (*ir)->globalPosition();
00797     
00798     LogTrace(theCategory) 
00799       << "r = " << sqrt(pos.x() * pos.x() + pos.y() * pos.y())
00800       << "  z = " << pos.z()
00801       << "  dimension = " << (*ir)->dimension()
00802       << "  " << (*ir)->det()->geographicalId().det()
00803       << "  " << (*ir)->det()->subDetector();
00804 
00805   }
00806 
00807 }
00808 
00809 
00810 //
00811 // add Trajectory* to TrackCand if not already present
00812 //
00813 void GlobalTrajectoryBuilderBase::addTraj(TrackCand& candIn) {
00814 
00815   if ( candIn.first == 0 ) {
00816     theTkTrajsAvailableFlag = false;
00817     LogTrace(theCategory) << "Making new trajectory from TrackRef " << (*candIn.second).pt();
00818 
00819     TC staTrajs = theTrackTransformer->transform(*(candIn.second));
00820     if (staTrajs.empty()) {
00821         LogTrace(theCategory) << "Transformer: Add Traj failed!";
00822         candIn = TrackCand(0,candIn.second); 
00823     } else {
00824         Trajectory * tmpTrajectory = new Trajectory(staTrajs.front());
00825         tmpTrajectory->setSeedRef(candIn.second->seedRef());
00826         candIn = TrackCand(tmpTrajectory,candIn.second);
00827     }
00828   }
00829 }
00830 
00831 
00832 //
00833 // check order of RechIts on a trajectory
00834 //
00835 GlobalTrajectoryBuilderBase::RefitDirection
00836 GlobalTrajectoryBuilderBase::checkRecHitsOrdering(const TransientTrackingRecHit::ConstRecHitContainer& recHits) const {
00837 
00838   if ( !recHits.empty() ) {
00839     ConstRecHitContainer::const_iterator frontHit = recHits.begin();
00840     ConstRecHitContainer::const_iterator backHit  = recHits.end() - 1;
00841     while ( !(*frontHit)->isValid() && frontHit != backHit ) {frontHit++;}
00842     while ( !(*backHit)->isValid() && backHit != frontHit )  {backHit--;}
00843 
00844     double rFirst = (*frontHit)->globalPosition().mag();
00845     double rLast  = (*backHit) ->globalPosition().mag();
00846 
00847     if ( rFirst < rLast ) return inToOut;
00848     else if (rFirst > rLast) return outToIn;
00849     else {
00850       LogError(theCategory) << "Impossible to determine the rechits order" << endl;
00851       return undetermined;
00852     }
00853   }
00854   else {
00855     LogError(theCategory) << "Impossible to determine the rechits order" << endl;
00856     return undetermined;
00857   }
00858 }
00859 
00860 
00861 //
00862 // refit a trajectory
00863 //
00864 vector<Trajectory> 
00865 GlobalTrajectoryBuilderBase::refitTrajectory(const Trajectory& tkTraj) const {
00866 
00867   // this is the only way to get a TrajectorySeed with settable propagation direction
00868   PTrajectoryStateOnDet garbage1;
00869   edm::OwnVector<TrackingRecHit> garbage2;
00870 
00871   ConstRecHitContainer trackerRecHits = tkTraj.recHits();
00872   
00873   RefitDirection recHitDir = checkRecHitsOrdering(trackerRecHits);
00874   // force the rechits to be ordered from outside-in
00875   if ( recHitDir == inToOut ) reverse(trackerRecHits.begin(),trackerRecHits.end());
00876 
00877   // force the refit direction to be opposite to momentum due to the rechit ordering  
00878   PropagationDirection refitDir = oppositeToMomentum;
00879   
00880   TrajectorySeed seed(garbage1,garbage2,refitDir);
00881   
00882   // take the outermost state as the initial state for refitting
00883   TrajectoryMeasurement outerTM = (tkTraj.direction() == alongMomentum) ? tkTraj.lastMeasurement() : tkTraj.firstMeasurement();
00884   TrajectoryStateOnSurface outerTsos = outerTM.updatedState();
00885   outerTsos.rescaleError(100.);
00886   
00887   vector<Trajectory> refitted1 = theKFFitter->fit(seed,trackerRecHits,outerTsos);
00888 
00889   if ( !refitted1.empty() ) {
00890     for (vector<Trajectory>::iterator nit = refitted1.begin(); nit != refitted1.end(); ++nit) {
00891       (*nit).setSeedRef(tkTraj.seedRef());
00892     }
00893   }
00894   
00895   return refitted1;
00896 
00897 }
00898 
00899 
00900 //
00901 //  build a global trajectory from tracker and muon hits
00902 //
00903 vector<Trajectory> 
00904 GlobalTrajectoryBuilderBase::glbTrajectory(const TrajectorySeed& seed,
00905                                            const ConstRecHitContainer& tkhits,
00906                                            const ConstRecHitContainer& muonhits,
00907                                            const TrajectoryStateOnSurface& firstPredTsos) const {
00908 
00909   ConstRecHitContainer hits = tkhits;
00910   hits.insert(hits.end(), muonhits.begin(), muonhits.end());
00911 
00912   if ( hits.empty() ) return vector<Trajectory>();
00913 
00914   PTrajectoryStateOnDet PTSOD = seed.startingState();
00915 
00916   edm::OwnVector<TrackingRecHit> garbage2;
00917 
00918   RefitDirection recHitDir = checkRecHitsOrdering(hits);
00919   PropagationDirection refitDir = (recHitDir == outToIn) ? oppositeToMomentum : alongMomentum ;
00920   TrajectorySeed newSeed(PTSOD,garbage2,refitDir);
00921 
00922   TrajectoryStateOnSurface firstTsos = firstPredTsos;
00923   firstTsos.rescaleError(10.);
00924 
00925   vector<Trajectory> theTrajs = theKFFitter->fit(newSeed,hits,firstTsos);
00926 
00927   return theTrajs;
00928 
00929 }
00930 
00931 
00932 //
00933 // select trajectories with only a single TEC hit
00934 //
00935 GlobalTrajectoryBuilderBase::ConstRecHitContainer 
00936 GlobalTrajectoryBuilderBase::selectTrackerHits(const ConstRecHitContainer& all) const {
00937  
00938   int nTEC(0);
00939 
00940   ConstRecHitContainer hits;
00941   for (ConstRecHitContainer::const_iterator i = all.begin(); i != all.end(); i++) {
00942     if( !(*i)->isValid() ) continue;
00943     if ( (*i)->det()->geographicalId().det() == DetId::Tracker &&
00944          (*i)->det()->geographicalId().subdetId() == StripSubdetector::TEC) {
00945       nTEC++;
00946     } else {
00947       hits.push_back((*i).get());
00948     }
00949     if ( nTEC > 1 ) return all;
00950   }
00951 
00952   return hits;
00953 
00954 }
00955 
00956 TransientTrackingRecHit::ConstRecHitContainer
00957 GlobalTrajectoryBuilderBase::getTransientRecHits(const reco::TransientTrack& track) const {
00958   TransientTrackingRecHit::ConstRecHitContainer result;
00959   
00960   for (trackingRecHit_iterator hit = track.recHitsBegin(); hit != track.recHitsEnd(); ++hit)
00961     if((*hit)->isValid())
00962       if ( (*hit)->geographicalId().det() == DetId::Tracker )
00963         result.push_back(theTrackerRecHitBuilder->build(&**hit));
00964       else if ( (*hit)->geographicalId().det() == DetId::Muon ){
00965         if( (*hit)->geographicalId().subdetId() == 3 && !theRPCInTheFit){
00966           LogDebug(theCategory) << "RPC Rec Hit discarged"; 
00967           continue;
00968         }
00969         result.push_back(theMuonRecHitBuilder->build(&**hit));
00970       }
00971 
00972   return result;
00973 }

Generated on Tue Jun 9 17:44:15 2009 for CMSSW by  doxygen 1.5.4