CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/HLTriggerOffline/Muon/src/PropagateToMuon.cc

Go to the documentation of this file.
00001 #include "HLTriggerOffline/Muon/interface/PropagateToMuon.h"
00002 
00003 #include <iostream>
00004 #include <cmath>
00005 
00006 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00007 
00008 #include "RecoMuon/Records/interface/MuonRecoGeometryRecord.h"
00009 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00010 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00011 #include "DataFormats/GeometrySurface/interface/TrapezoidalPlaneBounds.h"
00012 #include "TrackingTools/DetLayers/interface/DetLayer.h" 
00013 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00014 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00015 
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017 
00018 PropagateToMuon::PropagateToMuon(const edm::ParameterSet & iConfig) :
00019     useSimpleGeometry_(iConfig.getParameter<bool>("useSimpleGeometry")),
00020     whichTrack_(None), whichState_(AtVertex),
00021     cosmicPropagation_(iConfig.existsAs<bool>("cosmicPropagationHypothesis") ? iConfig.getParameter<bool>("cosmicPropagationHypothesis") : false)
00022 {
00023     std::string whichTrack = iConfig.getParameter<std::string>("useTrack");
00024     if      (whichTrack == "none")    { whichTrack_ = None; }
00025     else if (whichTrack == "tracker") { whichTrack_ = TrackerTk; }
00026     else if (whichTrack == "muon")    { whichTrack_ = MuonTk; }
00027     else if (whichTrack == "global")  { whichTrack_ = GlobalTk; }
00028     else throw cms::Exception("Configuration") << "Parameter 'useTrack' must be 'none', 'tracker', 'muon', 'global'\n";
00029     if (whichTrack_ != None) {
00030         std::string whichState = iConfig.getParameter<std::string>("useState");
00031         if      (whichState == "atVertex")  { whichState_ = AtVertex; }
00032         else if (whichState == "innermost") { whichState_ = Innermost; }
00033         else if (whichState == "outermost") { whichState_ = Outermost; }
00034         else throw cms::Exception("Configuration") << "Parameter 'useState' must be 'atVertex', 'innermost', 'outermost'\n";
00035     }
00036     if (cosmicPropagation_ && (whichTrack_ == None || whichState_ == AtVertex)) {
00037         throw cms::Exception("Configuration") << "When using 'cosmicPropagationHypothesis' useTrack must not be 'none', and the state must not be 'atVertex'\n";
00038     }
00039 }
00040 
00041 PropagateToMuon::~PropagateToMuon() {}
00042 
00043 void
00044 PropagateToMuon::init(const edm::EventSetup & iSetup) {
00045     iSetup.get<IdealMagneticFieldRecord>().get(magfield_);
00046     iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAlong",    propagator_);
00047     iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorOpposite", propagatorOpposite_);
00048     iSetup.get<TrackingComponentsRecord>().get("SteppingHelixPropagatorAny",      propagatorAny_);
00049     iSetup.get<MuonRecoGeometryRecord>().get(muonGeometry_);
00050 
00051     const DetLayer * dt2 = muonGeometry_->allDTLayers()[1];
00052     const DetLayer * csc2Pos = muonGeometry_->forwardCSCLayers()[2];
00053     const DetLayer * csc2Neg = muonGeometry_->backwardCSCLayers()[2];
00054     barrelCylinder_ = dynamic_cast<const BoundCylinder *>(&dt2->surface());
00055     endcapDiskPos_  = dynamic_cast<const BoundDisk *>(& csc2Pos->surface());
00056     endcapDiskNeg_  = dynamic_cast<const BoundDisk *>(& csc2Neg->surface());
00057     if (barrelCylinder_==0 || endcapDiskPos_==0 || endcapDiskNeg_==0) throw cms::Exception("Geometry") << "Bad muon geometry!?";
00058     barrelHalfLength_ = barrelCylinder_->bounds().length()/2;;
00059     endcapRadii_ = std::make_pair(endcapDiskPos_->innerRadius(), endcapDiskPos_->outerRadius());
00060     //std::cout << "L1MuonMatcher: barrel radius = " << barrelCylinder_->radius() << ", half length = " << barrelHalfLength_ <<
00061     //             "; endcap Z = " << endcapDiskPos_->position().z() << ", radii = " << endcapRadii_.first << "," << endcapRadii_.second << std::std::endl;
00062 }
00063 
00064 FreeTrajectoryState 
00065 PropagateToMuon::startingState(const reco::Candidate &reco) const {
00066     FreeTrajectoryState ret;
00067     if (whichTrack_ != None) {
00068         const reco::RecoCandidate *rc = dynamic_cast<const reco::RecoCandidate *>(&reco);
00069         if (rc == 0) throw cms::Exception("Invalid Data") << "Input object is not a RecoCandidate.\n";
00070         reco::TrackRef tk;
00071         switch (whichTrack_) {
00072             case TrackerTk: tk = rc->track();          break; 
00073             case MuonTk   : tk = rc->standAloneMuon(); break;
00074             case GlobalTk : tk = rc->combinedMuon();   break;
00075             default: break; // just to make gcc happy
00076         }
00077         if (tk.isNull()) {
00078             ret = FreeTrajectoryState();
00079         } else {
00080             ret = startingState(*tk);
00081         }
00082     } else {
00083         ret = FreeTrajectoryState(  GlobalPoint( reco.vx(), reco.vy(), reco.vz()),
00084                                     GlobalVector(reco.px(), reco.py(), reco.pz()),
00085                                     reco.charge(),
00086                                     magfield_.product());
00087     }
00088     return ret;
00089 }
00090 
00091 FreeTrajectoryState 
00092 PropagateToMuon::startingState(const reco::Track &tk) const {
00093     WhichState state = whichState_;
00094     if (cosmicPropagation_) { 
00095         if (whichState_ == Innermost) {
00096             state = tk.innerPosition().Mag2() <= tk.outerPosition().Mag2()  ? Innermost : Outermost;
00097         } else if (whichState_ == Outermost) {
00098             state = tk.innerPosition().Mag2() <= tk.outerPosition().Mag2()  ? Outermost : Innermost;
00099         }
00100     }
00101     switch (state) {
00102         case Innermost: return TrajectoryStateTransform().innerFreeState(  tk, magfield_.product()); 
00103         case Outermost: return TrajectoryStateTransform().outerFreeState(  tk, magfield_.product()); 
00104 
00105         case AtVertex:  
00106         default:
00107             return TrajectoryStateTransform().initialFreeState(tk, magfield_.product()); 
00108     }
00109     
00110 }
00111 
00112 
00113 TrajectoryStateOnSurface
00114 PropagateToMuon::extrapolate(const FreeTrajectoryState &start) const {
00115     TrajectoryStateOnSurface final;
00116     if (start.momentum().mag() == 0) return final;
00117     double eta = start.momentum().eta();
00118 
00119     const Propagator * propagatorBarrel  = &*propagator_;
00120     const Propagator * propagatorEndcaps = &*propagator_;
00121 
00122     if (whichState_ != AtVertex) { 
00123         if (start.position().perp()    > barrelCylinder_->radius())      propagatorBarrel  = &*propagatorOpposite_;
00124         if (fabs(start.position().z()) > endcapDiskPos_->position().z()) propagatorEndcaps = &*propagatorOpposite_;
00125     }
00126     if (cosmicPropagation_) {
00127         if (start.momentum().dot(GlobalVector(start.position().x(), start.position().y(), start.position().z())) < 0) {
00128             // must flip the propagations
00129             propagatorBarrel  = (propagatorBarrel  == &*propagator_ ? &*propagatorOpposite_ : &*propagator_);
00130             propagatorEndcaps = (propagatorEndcaps == &*propagator_ ? &*propagatorOpposite_ : &*propagator_);
00131         }
00132     }
00133 
00134     TrajectoryStateOnSurface tsos = propagatorBarrel->propagate(start, *barrelCylinder_);
00135     if (tsos.isValid()) {
00136         if (useSimpleGeometry_) {
00137             if (fabs(tsos.globalPosition().z()) <= barrelHalfLength_) final = tsos;
00138         } else {
00139             final = getBestDet(tsos, muonGeometry_->allDTLayers()[1]);
00140         }
00141     } 
00142 
00143     if (!final.isValid()) { 
00144         tsos = propagatorEndcaps->propagate(start, (eta > 0 ? *endcapDiskPos_ : *endcapDiskNeg_));
00145         if (tsos.isValid()) {
00146             if (useSimpleGeometry_) {
00147                 float rho = tsos.globalPosition().perp();
00148                 if ((rho >= endcapRadii_.first) && (rho <= endcapRadii_.second)) final = tsos;
00149             } else {
00150                 final = getBestDet(tsos, (eta > 0 ? muonGeometry_->forwardCSCLayers()[2] : muonGeometry_->backwardCSCLayers()[2]));
00151             }
00152         }
00153     }
00154     return final;
00155 }
00156 
00157 TrajectoryStateOnSurface 
00158 PropagateToMuon::getBestDet(const TrajectoryStateOnSurface &tsos, const DetLayer *layer) const {
00159     TrajectoryStateOnSurface ret; // start as null
00160     Chi2MeasurementEstimator estimator(1e10, 3.); // require compatibility at 3 sigma
00161     std::vector<GeometricSearchDet::DetWithState> dets = layer->compatibleDets(tsos, *propagatorAny_, estimator);
00162     if (!dets.empty()) {
00163         ret = dets.front().second;
00164     }
00165     return ret;
00166 }