CMS 3D CMS Logo

List of all members | Public Member Functions | Private Attributes | Static Private Attributes
fastsim::LayerNavigator Class Reference

Handles/tracks (possible) intersections of particle's trajectory and tracker layers. More...

#include <LayerNavigator.h>

Public Member Functions

 LayerNavigator (const Geometry &geometry)
 Constructor. More...
 
bool moveParticleToNextLayer (Particle &particle, const SimplifiedGeometry *&layer)
 Move particle along its trajectory to the next intersection with any of the tracker layers. More...
 

Private Attributes

const Geometry *const geometry_
 The geometry of the tracker material. More...
 
const BarrelSimplifiedGeometrynextBarrelLayer_
 Pointer to the next (direction of the particle's momentum) barrel layer. More...
 
const ForwardSimplifiedGeometrynextForwardLayer_
 Pointer to the next (direction of the particle's momentum) forward layer. More...
 
const BarrelSimplifiedGeometrypreviousBarrelLayer_
 Pointer to the previous (opposite direction of the particle's momentum) barrel layer. More...
 
const ForwardSimplifiedGeometrypreviousForwardLayer_
 Pointer to the previous (opposite direction of the particle's momentum) forward layer. More...
 

Static Private Attributes

static const std::string MESSAGECATEGORY = "FastSimulation"
 

Detailed Description

Handles/tracks (possible) intersections of particle's trajectory and tracker layers.

the geometry is described by 2 sets of layers:

principle

Definition at line 48 of file LayerNavigator.h.

Constructor & Destructor Documentation

◆ LayerNavigator()

fastsim::LayerNavigator::LayerNavigator ( const Geometry geometry)

Constructor.

Parameters
geometryThe geometry of the tracker material.

Definition at line 60 of file LayerNavigator.cc.

61  : geometry_(&geometry),
62  nextBarrelLayer_(nullptr),
63  previousBarrelLayer_(nullptr),
64  nextForwardLayer_(nullptr),
65  previousForwardLayer_(nullptr) {
66  ;
67 }
const BarrelSimplifiedGeometry * previousBarrelLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) barrel layer.
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.
const ForwardSimplifiedGeometry * previousForwardLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) forward layer.
const ForwardSimplifiedGeometry * nextForwardLayer_
Pointer to the next (direction of the particle&#39;s momentum) forward layer.

Member Function Documentation

◆ moveParticleToNextLayer()

bool fastsim::LayerNavigator::moveParticleToNextLayer ( fastsim::Particle particle,
const SimplifiedGeometry *&  layer 
)

Move particle along its trajectory to the next intersection with any of the tracker layers.

Parameters
particleThe particle that has to be moved to the next layer.
layerThe layer to which the particle was moved in the previous call of this function (0 if first call). Returns the layer this particle was then moved to.
Returns
true / false if propagation succeeded / failed.

Definition at line 69 of file LayerNavigator.cc.

References funct::abs(), electrons_cff::bool, fastsim::Trajectory::createTrajectory(), MillePedeFileConverter_cfg::e, Exception, fastsim::Particle::gamma(), fastsim::Particle::isOnLayer(), fastsim::Particle::isStable(), hgcalTopologyTester_cfi::layers, LogDebug, CaloMaterial_cfi::magneticFieldZ, fastsim::Particle::momentum(), fastsim::Particle::position(), fastsim::Particle::remainingProperLifeTimeC(), fastsim::Particle::resetOnLayer(), fastsim::Particle::setOnLayer(), and fastsim::Particle::setRemainingProperLifeTimeC().

Referenced by FastSimProducer::createFSimTrack(), and FastSimProducer::produce().

70  {
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 
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 }
bool isStable() const
Returns true if particle is considered stable.
Definition: Particle.h:171
const BarrelSimplifiedGeometry * previousBarrelLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) barrel layer.
double gamma() const
Return Lorentz&#39; gamma factor.
Definition: Particle.h:180
const BarrelSimplifiedGeometry * previousLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:120
const std::vector< std::unique_ptr< BarrelSimplifiedGeometry > > & barrelLayers() const
Return the vector of barrel layers.
Definition: Geometry.h:60
const math::XYZTLorentzVector & position() const
Return position of the particle.
Definition: Particle.h:140
void setRemainingProperLifeTimeC(double remainingProperLifeTimeC)
Set the particle&#39;s remaining proper lifetime if not stable [in ct].
Definition: Particle.h:64
double remainingProperLifeTimeC() const
Return the particle&#39;s remaining proper lifetime[in ct].
Definition: Particle.h:150
constexpr std::array< uint8_t, layerIndexSize > layer
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
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const ForwardSimplifiedGeometry * previousForwardLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) forward layer.
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
Definition: Particle.h:143
const std::vector< std::unique_ptr< ForwardSimplifiedGeometry > > & forwardLayers() const
Return the vector of forward layers (disks).
Definition: Geometry.h:67
double getMagneticFieldZ(const math::XYZTLorentzVector &position) const
Initializes the tracker geometry.
Definition: Geometry.cc:156
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)...
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 BarrelSimplifiedGeometry * nextLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:92
bool isOnLayer(bool isForward, int index)
Check if particle is on layer.
Definition: Particle.h:168
static const std::string MESSAGECATEGORY
#define LogDebug(id)

Member Data Documentation

◆ geometry_

const Geometry* const fastsim::LayerNavigator::geometry_
private

The geometry of the tracker material.

Definition at line 65 of file LayerNavigator.h.

◆ MESSAGECATEGORY

const std::string fastsim::LayerNavigator::MESSAGECATEGORY = "FastSimulation"
staticprivate

find the next layer that the particle will cross

motivation for a new algorithm

  • old algorithm is flawed
  • the new algorithm allows to put material and instruments on any plane perpendicular to z, or on any cylinder with the z-axis as axis
  • while the old algorith, with the requirement of nested layers, forbids the introduction of long narrow cylinders, required for a decent simulation of material in front of HF

definitions the geometry is described by 2 sets of layers:

  • forward layers: flat layers, perpendicular to the z-axis, positioned at a given z these layers have material / instruments between a given materialMinR and materialMaxR no 2 forward layers should have the same z-position
  • barrel layers: cylindrically shaped layers, with the z-axis as axis, infinitely long these layers have material / instruments for |z| < materialMaxAbsZ no 2 barrel layers should have the same radius
  • forward(barrel) layers are ordered according to increasing z (r)

principle

  • neutral particles follow a straight trajectory
  • charged particles follow a helix-shaped trajectory: constant speed along the z-axis circular path in the x-y plane => the next layer that the particle will cross is among the following 3 layers
  • closest forward layer with
  • z >(<) particle.z() for particles moving in the positive(negative) direction
  • closest barrel layer with r < particle.r
  • closest barrel layer with r > particle.r
    algorithm
  • find the 3 candidate layers
  • find the earliest positive intersection time for each of the 3 candidate layers
  • move the particle to the earliest intersection time
  • select and return the layer with the earliest positive intersection time

notes

  • the implementation of the algorithm can probably be optimised, e.g.
  • one can probably gain time in moveToNextLayer if LayerNavigator is aware of the candidate layers of the previous call to moveToNextLayer
  • for straight tracks, the optimal strategy to find the next layer might be very different

Definition at line 74 of file LayerNavigator.h.

◆ nextBarrelLayer_

const BarrelSimplifiedGeometry* fastsim::LayerNavigator::nextBarrelLayer_
private

Pointer to the next (direction of the particle's momentum) barrel layer.

Definition at line 67 of file LayerNavigator.h.

◆ nextForwardLayer_

const ForwardSimplifiedGeometry* fastsim::LayerNavigator::nextForwardLayer_
private

Pointer to the next (direction of the particle's momentum) forward layer.

Definition at line 71 of file LayerNavigator.h.

◆ previousBarrelLayer_

const BarrelSimplifiedGeometry* fastsim::LayerNavigator::previousBarrelLayer_
private

Pointer to the previous (opposite direction of the particle's momentum) barrel layer.

Definition at line 69 of file LayerNavigator.h.

◆ previousForwardLayer_

const ForwardSimplifiedGeometry* fastsim::LayerNavigator::previousForwardLayer_
private

Pointer to the previous (opposite direction of the particle's momentum) forward layer.

Definition at line 73 of file LayerNavigator.h.