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
00061
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;
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
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;
00160 Chi2MeasurementEstimator estimator(1e10, 3.);
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 }