CMS 3D CMS Logo

LayerNavigator.cc
Go to the documentation of this file.
3 
4 #include <vector>
5 
7 
14 
59 
61  : geometry_(&geometry),
62  nextBarrelLayer_(nullptr),
63  previousBarrelLayer_(nullptr),
64  nextForwardLayer_(nullptr),
65  previousForwardLayer_(nullptr) {
66  ;
67 }
68 
70  const fastsim::SimplifiedGeometry*& layer) {
71  LogDebug(MESSAGECATEGORY) << " moveToNextLayer called";
72 
73  // if the layer is provided, the particle must be on it
74  if (layer) {
75  if (!particle.isOnLayer(layer->isForward(), layer->index())) {
76  throw cms::Exception("FastSimulation") << "If layer is provided, particle must be on layer."
77  << "\n Layer: " << *layer << "\n Particle: " << particle;
78  }
79  }
80 
81  // magnetic field at the current position of the particle
82  // considered constant between the layers
83  double magneticFieldZ =
84  layer ? layer->getMagneticFieldZ(particle.position()) : geometry_->getMagneticFieldZ(particle.position());
85  LogDebug(MESSAGECATEGORY) << " magnetic field z component:" << magneticFieldZ;
86 
87  // particle moves inwards?
88  bool particleMovesInwards =
89  particle.momentum().X() * particle.position().X() + particle.momentum().Y() * particle.position().Y() < 0;
90 
91  //
92  // update nextBarrelLayer and nextForwardLayer
93  //
94 
96  // first time method is called
98  if (!layer) {
99  LogDebug(MESSAGECATEGORY) << " called for first time";
100 
101  // find the narrowest barrel layers with
102  // layer.r > particle.r (the closest layer with layer.r < particle.r will then be considered, too)
103  // assume barrel layers are ordered with increasing r
104  for (const auto& layer : geometry_->barrelLayers()) {
105  if (particle.isOnLayer(false, layer->index()) ||
106  std::abs(layer->getRadius() - particle.position().Rho()) < 1e-2) {
107  if (particleMovesInwards) {
108  nextBarrelLayer_ = layer.get();
109  break;
110  } else {
111  continue;
112  }
113  }
114 
115  if (particle.position().Pt() < layer->getRadius()) {
116  nextBarrelLayer_ = layer.get();
117  break;
118  }
119 
120  previousBarrelLayer_ = layer.get();
121  }
122 
123  // find the forward layer with smallest z with
124  // layer.z > particle z (the closest layer with layer.z < particle.z will then be considered, too)
125  for (const auto& layer : geometry_->forwardLayers()) {
126  if (particle.isOnLayer(true, layer->index()) || std::abs(layer->getZ() - particle.position().Z()) < 1e-3) {
127  if (particle.momentum().Z() < 0) {
128  nextForwardLayer_ = layer.get();
129  break;
130  } else {
131  continue;
132  }
133  }
134 
135  if (particle.position().Z() < layer->getZ()) {
136  nextForwardLayer_ = layer.get();
137  break;
138  }
139 
140  previousForwardLayer_ = layer.get();
141  }
142  }
144  // last move worked, let's update
146  else {
147  LogDebug(MESSAGECATEGORY) << " ordinary call";
148 
149  // barrel layer was hit
150  if (layer == nextBarrelLayer_) {
151  if (!particleMovesInwards) {
154  }
155  } else if (layer == previousBarrelLayer_) {
156  if (particleMovesInwards) {
159  }
160  }
161  // forward layer was hit
162  else if (layer == nextForwardLayer_) {
163  if (particle.momentum().Z() > 0) {
166  }
167  } else if (layer == previousForwardLayer_) {
168  if (particle.momentum().Z() < 0) {
171  }
172  }
173 
174  // reset layer
175  layer = nullptr;
176  }
177 
179  // move particle to first hit with one of the enclosing layers
181 
182  LogDebug(MESSAGECATEGORY) << " particle between BarrelLayers: "
183  << (previousBarrelLayer_ ? previousBarrelLayer_->index() : -1) << "/"
185  << " (total: " << geometry_->barrelLayers().size() << ")"
186  << "\n particle between ForwardLayers: "
189  << " (total: " << geometry_->forwardLayers().size() << ")";
190 
191  // calculate and store some variables related to the particle's trajectory
192  std::unique_ptr<fastsim::Trajectory> trajectory = Trajectory::createTrajectory(particle, magneticFieldZ);
193 
194  // push back all possible candidates
195  std::vector<const fastsim::SimplifiedGeometry*> layers;
196  if (nextBarrelLayer_) {
197  layers.push_back(nextBarrelLayer_);
198  }
199  if (previousBarrelLayer_) {
200  layers.push_back(previousBarrelLayer_);
201  }
202 
203  if (particle.momentum().Z() > 0) {
204  if (nextForwardLayer_) {
205  layers.push_back(nextForwardLayer_);
206  }
207  } else {
208  if (previousForwardLayer_) {
209  layers.push_back(previousForwardLayer_);
210  }
211  }
212 
213  // calculate time until each possible intersection
214  // -> pick layer that is hit first
215  double deltaTimeC = -1;
216  for (auto _layer : layers) {
217  double tempDeltaTime =
218  trajectory->nextCrossingTimeC(*_layer, particle.isOnLayer(_layer->isForward(), _layer->index()));
219  LogDebug(MESSAGECATEGORY) << " particle crosses layer " << *_layer << " in time " << tempDeltaTime;
220  if (tempDeltaTime > 0 && (layer == nullptr || tempDeltaTime < deltaTimeC || deltaTimeC < 0)) {
221  layer = _layer;
222  deltaTimeC = tempDeltaTime;
223  }
224  }
225 
226  // if particle decays on the way to the next layer, stop propagation there and return
227  double properDeltaTimeC = deltaTimeC / particle.gamma();
228  if (!particle.isStable() && properDeltaTimeC > particle.remainingProperLifeTimeC()) {
229  // move particle in space, time and momentum until it decays
230  deltaTimeC = particle.remainingProperLifeTimeC() * particle.gamma();
231 
232  trajectory->move(deltaTimeC);
233  particle.position() = trajectory->getPosition();
234  particle.momentum() = trajectory->getMomentum();
235 
236  particle.setRemainingProperLifeTimeC(0.);
237 
238  // particle no longer is on a layer
239  particle.resetOnLayer();
240  LogDebug(MESSAGECATEGORY) << " particle about to decay. Will not be moved all the way to the next layer.";
241  return false;
242  }
243 
244  if (layer) {
245  // move particle in space, time and momentum so it is on the next layer
246  trajectory->move(deltaTimeC);
247  particle.position() = trajectory->getPosition();
248  particle.momentum() = trajectory->getMomentum();
249 
250  if (!particle.isStable())
251  particle.setRemainingProperLifeTimeC(particle.remainingProperLifeTimeC() - properDeltaTimeC);
252 
253  // link the particle to the layer
254  particle.setOnLayer(layer->isForward(), layer->index());
255  LogDebug(MESSAGECATEGORY) << " moved particle to layer: " << *layer;
256  } else {
257  // particle no longer is on a layer
258  particle.resetOnLayer();
259  }
260 
261  // return true / false if propagations succeeded /failed
262  LogDebug(MESSAGECATEGORY) << " success: " << bool(layer);
263  return layer;
264 }
#define LogDebug(id)
Implementation of a generic detector layer (base class for forward/barrel layers).
const BarrelSimplifiedGeometry * previousBarrelLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) barrel layer.
const math::XYZTLorentzVector & position() const
Return position of the particle.
Definition: Particle.h:140
LayerNavigator(const Geometry &geometry)
Constructor.
const std::vector< std::unique_ptr< ForwardSimplifiedGeometry > > & forwardLayers() const
Return the vector of forward layers (disks).
Definition: Geometry.h:69
const BarrelSimplifiedGeometry * nextLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:94
#define nullptr
double remainingProperLifeTimeC() const
Return the particle&#39;s remaining proper lifetime[in ct].
Definition: Particle.h:150
virtual bool isForward() const =0
Returns false/true depending if the object is a (non-abstract) barrel/forward layer.
void setRemainingProperLifeTimeC(double remainingProperLifeTimeC)
Set the particle&#39;s remaining proper lifetime if not stable [in ct].
Definition: Particle.h:64
bool moveParticleToNextLayer(Particle &particle, const SimplifiedGeometry *&layer)
Move particle along its trajectory to the next intersection with any of the tracker layers...
const BarrelSimplifiedGeometry * nextBarrelLayer_
Pointer to the next (direction of the particle&#39;s momentum) barrel layer.
const Geometry *const geometry_
The geometry of the tracker material.
void resetOnLayer()
Reset layer this particle is currently on (i.e. particle is not on a layer anyomre) ...
Definition: Particle.h:78
virtual const double getMagneticFieldZ(const math::XYZTLorentzVector &position) const =0
Return magnetic field (field only has Z component!) on the layer.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const BarrelSimplifiedGeometry * previousLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:122
const ForwardSimplifiedGeometry * previousForwardLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) forward layer.
Definition the tracker geometry (vectors of forward/barrel layers).
Definition: Geometry.h:32
const std::vector< std::unique_ptr< BarrelSimplifiedGeometry > > & barrelLayers() const
Return the vector of barrel layers.
Definition: Geometry.h:62
const ForwardSimplifiedGeometry * nextForwardLayer_
Pointer to the next (direction of the particle&#39;s momentum) forward layer.
int index() const
Return index of this layer (layers are numbered according to their position in the detector)...
bool isStable() const
Returns true if particle is considered stable.
Definition: Particle.h:171
void setOnLayer(bool isForward, int index)
Set layer this particle is currently on.
Definition: Particle.h:72
static std::unique_ptr< Trajectory > createTrajectory(const fastsim::Particle &particle, const double magneticFieldZ)
Calls constructor of derived classes.
Definition: Trajectory.cc:17
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
Definition: Particle.h:143
double gamma() const
Return Lorentz&#39; gamma factor.
Definition: Particle.h:180
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
Definition: Particle.h:16
bool isOnLayer(bool isForward, int index)
Check if particle is on layer.
Definition: Particle.h:168
double getMagneticFieldZ(const math::XYZTLorentzVector &position) const
Initializes the tracker geometry.
Definition: Geometry.cc:154
static const std::string MESSAGECATEGORY