CMS 3D CMS Logo

PropagateToMuon.cc
Go to the documentation of this file.
2 
3 #include <cmath>
4 
13 
19  bool useSimpleGeometry,
20  bool useMB2,
21  bool fallbackToME1,
22  WhichTrack whichTrack,
23  WhichState whichState,
24  bool cosmicPropagation,
25  bool useMB2InOverlap)
26  : magfield_(magfield),
27  propagator_(propagator),
28  propagatorAny_(propagatorAny),
29  propagatorOpposite_(propagatorOpposite),
30  muonGeometry_(muonGeometry),
31  useSimpleGeometry_(useSimpleGeometry),
32  useMB2_(useMB2),
33  fallbackToME1_(fallbackToME1),
34  whichTrack_(whichTrack),
35  whichState_(whichState),
36  cosmicPropagation_(cosmicPropagation),
37  useMB2InOverlap_(useMB2InOverlap) {
38  // Get the barrel cylinder
39  const DetLayer *dtLay = muonGeometry_->allDTLayers()[useMB2_ ? 1 : 0];
40  barrelCylinder_ = dynamic_cast<const BoundCylinder *>(&dtLay->surface());
41  barrelHalfLength_ = barrelCylinder_->bounds().length() / 2;
42  ;
43  //std::cout << "L1MuonMatcher: barrel radius = " << barrelCylinder_->radius() << ", half length = " << barrelHalfLength_ << std::endl;
44 
45  // Get the endcap disks. Note that ME1 has two disks (ME1/1 and ME2/1-ME3/2-ME4/1), so there's one more index
46  for (size_t i = 0; i <= (useMB2_ ? 2 : 1); ++i) {
47  endcapDiskPos_[i] = dynamic_cast<const BoundDisk *>(&muonGeometry_->forwardCSCLayers()[i]->surface());
48  endcapDiskNeg_[i] = dynamic_cast<const BoundDisk *>(&muonGeometry_->backwardCSCLayers()[i]->surface());
50  //std::cout << "L1MuonMatcher: endcap " << i << " Z = " << endcapDiskPos_[i]->position().z() << ", radii = " << endcapRadii_[i].first << "," << endcapRadii_[i].second << std::endl;
51  }
52 
54  barrelHalfLength_ = endcapDiskPos_[2]->position().z();
55 }
56 
59  if (whichTrack_ != None) {
60  const reco::RecoCandidate *rc = dynamic_cast<const reco::RecoCandidate *>(&reco);
61  if (rc == nullptr)
62  throw cms::Exception("Invalid Data") << "Input object is not a RecoCandidate.\n";
63  reco::TrackRef tk;
64  switch (whichTrack_) {
65  case TrackerTk:
66  tk = rc->track();
67  break;
68  case MuonTk:
69  tk = rc->standAloneMuon();
70  break;
71  case GlobalTk:
72  tk = rc->combinedMuon();
73  break;
74  default:
75  break; // just to make gcc happy
76  }
77  if (tk.isNull()) {
79  } else {
80  ret = startingState(*tk);
81  }
82  } else {
83  ret = FreeTrajectoryState(GlobalPoint(reco.vx(), reco.vy(), reco.vz()),
84  GlobalVector(reco.px(), reco.py(), reco.pz()),
85  reco.charge(),
86  magfield_.product());
87  }
88  return ret;
89 }
90 
92  if (!magfield_.isValid())
93  throw cms::Exception("NotInitialized")
94  << "PropagateToMuon: You must call init(const edm::EventSetup &iSetup) before using this object.\n";
96  if (cosmicPropagation_) {
97  if (whichState_ == Innermost) {
98  state = tk.innerPosition().Mag2() <= tk.outerPosition().Mag2() ? Innermost : Outermost;
99  } else if (whichState_ == Outermost) {
100  state = tk.innerPosition().Mag2() <= tk.outerPosition().Mag2() ? Outermost : Innermost;
101  }
102  }
103  switch (state) {
104  case Innermost:
106  case Outermost:
108 
109  case AtVertex:
110  default:
112  }
113 }
114 
116  if (!magfield_.isValid())
117  throw cms::Exception("NotInitialized")
118  << "PropagateToMuon: You must call init(const edm::EventSetup &iSetup) before using this object.\n";
119  if (tk.noVertex())
120  throw cms::Exception("UnsupportedOperation")
121  << "I can't propagate simtracks without a vertex, I don't know where to start from.\n";
122  const math::XYZTLorentzVectorD &vtx = (vtxs)[tk.vertIndex()].position();
123  return FreeTrajectoryState(GlobalPoint(vtx.X(), vtx.Y(), vtx.Z()),
124  GlobalVector(tk.momentum().X(), tk.momentum().Y(), tk.momentum().Z()),
125  int(tk.charge()),
126  magfield_.product());
127 }
128 
130  if (!magfield_.isValid() || barrelCylinder_ == nullptr) {
131  throw cms::Exception("NotInitialized")
132  << "PropagateToMuon: You must call init(const edm::EventSetup &iSetup) before using this object.\n";
133  }
134 
136  if (start.momentum().mag() == 0)
137  return final;
138  double eta = start.momentum().eta();
139 
140  const Propagator *propagatorBarrel = &*propagator_;
141  const Propagator *propagatorEndcaps = &*propagator_;
142  if (whichState_ != AtVertex) {
143  if (start.position().perp() > barrelCylinder_->radius())
144  propagatorBarrel = &*propagatorOpposite_;
145  if (fabs(start.position().z()) > endcapDiskPos_[useMB2_ ? 2 : 1]->position().z())
146  propagatorEndcaps = &*propagatorOpposite_;
147  }
148  if (cosmicPropagation_) {
149  if (start.momentum().dot(GlobalVector(start.position().x(), start.position().y(), start.position().z())) < 0) {
150  // must flip the propagations
151  propagatorBarrel = (propagatorBarrel == &*propagator_ ? &*propagatorOpposite_ : &*propagator_);
152  propagatorEndcaps = (propagatorEndcaps == &*propagator_ ? &*propagatorOpposite_ : &*propagator_);
153  }
154  }
155 
156  TrajectoryStateOnSurface tsos = propagatorBarrel->propagate(start, *barrelCylinder_);
157  if (tsos.isValid()) {
158  if (useSimpleGeometry_) {
159  //std::cout << " propagated to barrel, z = " << tsos.globalPosition().z() << ", bound = " << barrelHalfLength_ << std::endl;
160  if (fabs(tsos.globalPosition().z()) <= barrelHalfLength_)
161  final = tsos;
162  } else {
163  final = getBestDet(tsos, muonGeometry_->allDTLayers()[1]);
164  }
165  }
166  if (!final.isValid()) {
167  for (int ie = (useMB2_ ? 2 : 1); ie >= 0; --ie) {
168  tsos = propagatorEndcaps->propagate(start, (eta > 0 ? *endcapDiskPos_[ie] : *endcapDiskNeg_[ie]));
169  if (tsos.isValid()) {
170  if (useSimpleGeometry_) {
171  float rho = tsos.globalPosition().perp();
172  //std::cout << " propagated to endcap " << ie << ", rho = " << rho << ", bounds [ " << endcapRadii_[ie].first << ", " << endcapRadii_[ie].second << "]" << std::endl;
173  if ((rho >= endcapRadii_[ie].first) && (rho <= endcapRadii_[ie].second))
174  final = tsos;
175  } else {
176  final = getBestDet(
177  tsos, (eta > 0 ? muonGeometry_->forwardCSCLayers()[ie] : muonGeometry_->backwardCSCLayers()[ie]));
178  }
179  } //else //std::cout << " failed to propagated to endcap " << ie << std::endl;
180  if (final.isValid())
181  break;
182  if (ie == 2 && !fallbackToME1_)
183  break;
184  }
185  }
186  return final;
187 }
188 
190  const DetLayer *layer) const {
191  TrajectoryStateOnSurface ret; // start as null
192  // require compatibility at 3 sigma
194  std::vector<GeometricSearchDet::DetWithState> dets = layer->compatibleDets(tsos, *propagatorAny_, estimator);
195  if (!dets.empty()) {
196  ret = dets.front().second;
197  }
198  return ret;
199 }
const BoundDisk * endcapDiskNeg_[3]
Definition: start.py:1
WhichTrack whichTrack_
Labels for input collections.
const std::vector< const DetLayer * > & forwardCSCLayers() const
return the forward (+Z) CSC DetLayers, inside-out
edm::ESHandle< Propagator > propagator_
virtual const BoundSurface & surface() const =0
The surface of the GeometricSearchDet.
const BoundCylinder * barrelCylinder_
T perp() const
Definition: PV3DBase.h:69
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
const math::XYZPoint & outerPosition() const
position of the outermost hit
Definition: Track.h:62
WhichState whichState_
T z() const
Definition: PV3DBase.h:61
ret
prodAgent to be discontinued
FreeTrajectoryState startingState(const reco::Candidate &reco) const
Starting state for the propagation.
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
WhichTrack
const std::vector< const DetLayer * > & allDTLayers() const
return the DT DetLayers (barrel), inside-out
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:50
WhichState
float charge() const
charge
Definition: CoreSimTrack.cc:17
const math::XYZTLorentzVectorD & momentum() const
Definition: CoreSimTrack.h:19
edm::ESHandle< Propagator > propagatorAny_
constexpr std::array< uint8_t, layerIndexSize > layer
U second(std::pair< T, U > const &p)
int vertIndex() const
index of the vertex in the Event container (-1 if no vertex)
Definition: SimTrack.h:33
edm::ESHandle< Propagator > propagatorOpposite_
T const * product() const
Definition: ESHandle.h:86
GlobalPoint globalPosition() const
TrajectoryStateOnSurface getBestDet(const TrajectoryStateOnSurface &tsos, const DetLayer *station) const
Get the best TSOS on one of the chambres of this DetLayer, or an invalid TSOS if none match...
edm::ESHandle< MagneticField > magfield_
bool isNull() const
Checks for null.
Definition: Ref.h:235
bool isValid() const
Definition: ESHandle.h:44
bool cosmicPropagation_
for cosmics, some things change: the along-opposite is not in-out, nor the innermost/outermost states...
bool noVertex() const
Definition: SimTrack.h:34
const std::vector< const DetLayer * > & backwardCSCLayers() const
return the backward (-Z) CSC DetLayers, inside-out
std::vector< SimVertex > SimVertexContainer
std::pair< float, float > endcapRadii_[3]
fixed size matrix
edm::ESHandle< MuonDetLayerGeometry > muonGeometry_
static int position[264][3]
Definition: ReadPGInfo.cc:289
virtual reco::TrackRef track() const
reference to a Track
bool fallbackToME1_
Fallback to ME1 if propagation to ME2 fails.
virtual reco::TrackRef combinedMuon() const
reference to a stand-alone muon Track
const BoundDisk * endcapDiskPos_[3]
double barrelHalfLength_
FreeTrajectoryState innerFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
TrajectoryStateOnSurface extrapolate(const reco::Track &tk) const
Extrapolate reco::Track to the muon station 2, return an invalid TSOS if it fails.
const math::XYZPoint & innerPosition() const
position of the innermost hit
Definition: Track.h:56
FreeTrajectoryState outerFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
FreeTrajectoryState initialFreeState(const reco::Track &tk, const MagneticField *field, bool withErr=true)
Global3DVector GlobalVector
Definition: GlobalVector.h:10
virtual reco::TrackRef standAloneMuon() const
reference to a stand-alone muon Track