00001
00024 #include "RecoMuon/GlobalTrackingTools/interface/GlobalTrajectoryBuilderBase.h"
00025
00026
00027
00028
00029
00030 #include <iostream>
00031 #include <algorithm>
00032
00033
00034
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
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
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
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
00170
00171 MuonCandidate::CandidateContainer
00172 GlobalTrajectoryBuilderBase::build(const TrackCand& staCand,
00173 MuonCandidate::CandidateContainer& tkTrajs) const {
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 LogTrace(theCategory) << "build begin. ";
00185
00186 if ( tkTrajs.empty() ) return CandidateContainer();
00187
00188
00189 CandidateContainer refittedResult;
00190
00191 if ( theMuonHitsOption > 0 ) {
00192
00193 vector<int> stationHits(4,0);
00194 ConstRecHitContainer muonRecHits1;
00195 ConstRecHitContainer muonRecHits2;
00196 ConstRecHitContainer muonRecHits3;
00197
00198
00199
00200 checkMuonHits(*(staCand.second), muonRecHits1, muonRecHits2, stationHits);
00201
00202 for ( CandidateContainer::const_iterator it = tkTrajs.begin(); it != tkTrajs.end(); it++ ) {
00203
00204
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
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
00227
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
00251 refit[0] = (*it)->trackerTrajectory();
00252 ConstRecHitContainer rechits(trackerRecHits);
00253
00254
00255 if ( theMuonHitsOption == 1 || theMuonHitsOption == 3 || theMuonHitsOption == 4 || theMuonHitsOption == 5 ) {
00256 refitted1 = glbTrajectory((*it)->trackerTrajectory()->seed(),trackerRecHits, muonRecHits1,innerTsos);
00257 }
00258
00259
00260 if ( theMuonHitsOption == 2 || theMuonHitsOption == 4 || theMuonHitsOption == 5 ) {
00261 refitted2 = glbTrajectory((*it)->trackerTrajectory()->seed(),trackerRecHits, muonRecHits2,innerTsos);
00262 }
00263
00264
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
00292
00293
00294
00295
00296
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
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
00335
00336 vector<GlobalTrajectoryBuilderBase::TrackCand>
00337 GlobalTrajectoryBuilderBase::chooseRegionalTrackerTracks(const TrackCand& staCand,
00338 const vector<TrackCand>& tkTs) {
00339
00340
00341 RectangularEtaPhiTrackingRegion regionOfInterest = defineRegionOfInterest(staCand.second);
00342
00343
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
00353
00354
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
00361
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
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
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
00415
00416
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
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 }
00444 if ( hitUnique ) all2dRecHits.push_back((*ir).get());
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 }
00454 }
00455 if ( hitUnique )
00456 all2dRecHits.push_back(*iir);
00457 break;
00458 }
00459 }
00460 }
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 }
00467 }
00468
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
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 }
00505
00506 all.push_back((*imrh).get());
00507
00508 }
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
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
00536 first.push_back(*ihit);
00537
00538 ConstMuonRecHitPointer immrh = dynamic_cast<const MuonTransientTrackingRecHit*>((*ihit).get());
00539 DetId id = immrh->geographicalId();
00540
00541
00542 if ( (*immrh).isDT() ) {
00543 DTChamberId did(id.rawId());
00544 station1 = did.station();
00545 }
00546
00547 else if ( (*immrh).isCSC() ) {
00548 CSCDetId did(id.rawId());
00549 station1 = did.station();
00550 }
00551
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
00561 if ( (*immrh2).isDT() ) {
00562 DTChamberId did2(id2.rawId());
00563 station2 = did2.station();
00564 }
00565
00566 else if ( (*immrh2).isCSC() ) {
00567 CSCDetId did2(id2.rawId());
00568 station2 = did2.station();
00569 }
00570
00571
00572
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
00594 first.clear();
00595
00596 return;
00597
00598 }
00599
00600
00601
00602
00603
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
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
00627 if ( (*immrh).isDT() ) {
00628 DTChamberId did(id.rawId());
00629 station = did.station();
00630 threshold = theHitThreshold;
00631 chi2Cut = theDTChi2Cut;
00632 }
00633
00634 else if ( (*immrh).isCSC() ) {
00635 CSCDetId did(id.rawId());
00636 station = did.station();
00637 threshold = theHitThreshold;
00638 chi2Cut = theCSCChi2Cut;
00639 }
00640
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
00670 reverse(muonRecHits.begin(),muonRecHits.end());
00671
00672 return muonRecHits;
00673
00674 }
00675
00676
00677
00678
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
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
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
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
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
00863
00864 vector<Trajectory>
00865 GlobalTrajectoryBuilderBase::refitTrajectory(const Trajectory& tkTraj) const {
00866
00867
00868 PTrajectoryStateOnDet garbage1;
00869 edm::OwnVector<TrackingRecHit> garbage2;
00870
00871 ConstRecHitContainer trackerRecHits = tkTraj.recHits();
00872
00873 RefitDirection recHitDir = checkRecHitsOrdering(trackerRecHits);
00874
00875 if ( recHitDir == inToOut ) reverse(trackerRecHits.begin(),trackerRecHits.end());
00876
00877
00878 PropagationDirection refitDir = oppositeToMomentum;
00879
00880 TrajectorySeed seed(garbage1,garbage2,refitDir);
00881
00882
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
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
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 }