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

algorithm

Definition at line 51 of file LayerNavigator.h.

Constructor & Destructor Documentation

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

Constructor.

Parameters
geometryThe geometry of the tracker material.

Definition at line 60 of file LayerNavigator.cc.

62  , nextBarrelLayer_(nullptr)
63  , previousBarrelLayer_(nullptr)
64  , nextForwardLayer_(nullptr)
65  , previousForwardLayer_(nullptr)
66 {;}
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

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 68 of file LayerNavigator.cc.

References funct::abs(), fastsim::Geometry::barrelLayers(), electrons_cff::bool, fastsim::Trajectory::createTrajectory(), MillePedeFileConverter_cfg::e, Exception, fastsim::Geometry::forwardLayers(), fastsim::Particle::gamma(), geometry_, fastsim::Geometry::getMagneticFieldZ(), fastsim::SimplifiedGeometry::getMagneticFieldZ(), fastsim::SimplifiedGeometry::index(), fastsim::SimplifiedGeometry::isForward(), fastsim::Particle::isOnLayer(), fastsim::Particle::isStable(), LayerTriplets::layers(), LogDebug, MESSAGECATEGORY, fastsim::Particle::momentum(), nextBarrelLayer_, nextForwardLayer_, fastsim::Geometry::nextLayer(), fastsim::Particle::position(), previousBarrelLayer_, previousForwardLayer_, fastsim::Geometry::previousLayer(), fastsim::Particle::remainingProperLifeTimeC(), fastsim::Particle::resetOnLayer(), fastsim::Particle::setOnLayer(), and fastsim::Particle::setRemainingProperLifeTimeC().

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

69 {
70  LogDebug(MESSAGECATEGORY) << " moveToNextLayer called";
71 
72  // if the layer is provided, the particle must be on it
73  if(layer)
74  {
75  if(!particle.isOnLayer(layer->isForward(), layer->index()))
76  {
77  throw cms::Exception("FastSimulation") << "If layer is provided, particle must be on layer."
78  << "\n Layer: " << *layer
79  << "\n Particle: " << particle;
80  }
81  }
82 
83  // magnetic field at the current position of the particle
84  // considered constant between the layers
85  double magneticFieldZ = layer ? layer->getMagneticFieldZ(particle.position()) : geometry_->getMagneticFieldZ(particle.position());
86  LogDebug(MESSAGECATEGORY) << " magnetic field z component:" << magneticFieldZ;
87 
88  // particle moves inwards?
89  bool particleMovesInwards = 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  {
100  LogDebug(MESSAGECATEGORY) << " called for first time";
101 
102  // find the narrowest barrel layers with
103  // layer.r > particle.r (the closest layer with layer.r < particle.r will then be considered, too)
104  // assume barrel layers are ordered with increasing r
105  for(const auto & layer : geometry_->barrelLayers())
106  {
107  if(particle.isOnLayer(false, layer->index()) || std::abs(layer->getRadius() - particle.position().Rho()) < 1e-2){
108  if(particleMovesInwards){
109  nextBarrelLayer_ = layer.get();
110  break;
111  }else{
112  continue;
113  }
114  }
115 
116  if(particle.position().Pt() < layer->getRadius())
117  {
118  nextBarrelLayer_ = layer.get();
119  break;
120  }
121 
122  previousBarrelLayer_ = layer.get();
123  }
124 
125  // find the forward layer with smallest z with
126  // layer.z > particle z (the closest layer with layer.z < particle.z will then be considered, too)
127  for(const auto & layer : geometry_->forwardLayers())
128  {
129  if(particle.isOnLayer(true, layer->index()) || std::abs(layer->getZ() - particle.position().Z()) < 1e-3){
130  if(particle.momentum().Z() < 0){
131  nextForwardLayer_ = layer.get();
132  break;
133  }else{
134  continue;
135  }
136  }
137 
138  if(particle.position().Z() < layer->getZ())
139  {
140  nextForwardLayer_ = layer.get();
141  break;
142  }
143 
144  previousForwardLayer_ = layer.get();
145  }
146  }
148  // last move worked, let's update
150  else
151  {
152  LogDebug(MESSAGECATEGORY) << " ordinary call";
153 
154  // barrel layer was hit
155  if(layer == nextBarrelLayer_)
156  {
157  if(!particleMovesInwards)
158  {
161  }
162  }
163  else if(layer == previousBarrelLayer_)
164  {
165  if(particleMovesInwards)
166  {
169  }
170  }
171  // forward layer was hit
172  else if(layer == nextForwardLayer_)
173  {
174  if(particle.momentum().Z() > 0)
175  {
178  }
179  }
180  else if(layer == previousForwardLayer_)
181  {
182  if(particle.momentum().Z() < 0)
183  {
186  }
187  }
188 
189  // reset layer
190  layer = nullptr;
191  }
192 
194  // move particle to first hit with one of the enclosing layers
196 
197  LogDebug(MESSAGECATEGORY) << " particle between BarrelLayers: " << (previousBarrelLayer_ ? previousBarrelLayer_->index() : -1) << "/" << (nextBarrelLayer_ ? nextBarrelLayer_->index() : -1) << " (total: "<< geometry_->barrelLayers().size() <<")"
198  << "\n particle between ForwardLayers: " << (previousForwardLayer_ ? previousForwardLayer_->index() : -1) << "/" << (nextForwardLayer_ ? nextForwardLayer_->index() : -1) << " (total: "<< geometry_->forwardLayers().size() <<")";
199 
200  // calculate and store some variables related to the particle's trajectory
201  std::unique_ptr<fastsim::Trajectory> trajectory = Trajectory::createTrajectory(particle,magneticFieldZ);
202 
203  // push back all possible candidates
204  std::vector<const fastsim::SimplifiedGeometry*> layers;
205  if(nextBarrelLayer_)
206  {
207  layers.push_back(nextBarrelLayer_);
208  }
210  {
211  layers.push_back(previousBarrelLayer_);
212  }
213 
214  if(particle.momentum().Z() > 0)
215  {
217  {
218  layers.push_back(nextForwardLayer_);
219  }
220  }
221  else
222  {
224  {
225  layers.push_back(previousForwardLayer_);
226  }
227  }
228 
229  // calculate time until each possible intersection
230  // -> pick layer that is hit first
231  double deltaTimeC = -1;
232  for(auto _layer : layers)
233  {
234  double tempDeltaTime = trajectory->nextCrossingTimeC(*_layer, particle.isOnLayer(_layer->isForward(), _layer->index()));
235  LogDebug(MESSAGECATEGORY) << " particle crosses layer " << *_layer << " in time " << tempDeltaTime;
236  if(tempDeltaTime > 0 && (layer == nullptr || tempDeltaTime<deltaTimeC || deltaTimeC < 0))
237  {
238  layer = _layer;
239  deltaTimeC = tempDeltaTime;
240  }
241  }
242 
243  // if particle decays on the way to the next layer, stop propagation there and return
244  double properDeltaTimeC = deltaTimeC / particle.gamma();
245  if(!particle.isStable() && properDeltaTimeC > particle.remainingProperLifeTimeC())
246  {
247  // move particle in space, time and momentum until it decays
248  deltaTimeC = particle.remainingProperLifeTimeC() * particle.gamma();
249 
250  trajectory->move(deltaTimeC);
251  particle.position() = trajectory->getPosition();
252  particle.momentum() = trajectory->getMomentum();
253 
254  particle.setRemainingProperLifeTimeC(0.);
255 
256  // particle no longer is on a layer
257  particle.resetOnLayer();
258  LogDebug(MESSAGECATEGORY) << " particle about to decay. Will not be moved all the way to the next layer.";
259  return false;
260  }
261 
262  if(layer)
263  {
264  // move particle in space, time and momentum so it is on the next layer
265  trajectory->move(deltaTimeC);
266  particle.position() = trajectory->getPosition();
267  particle.momentum() = trajectory->getMomentum();
268 
269  if(!particle.isStable()) particle.setRemainingProperLifeTimeC(particle.remainingProperLifeTimeC() - properDeltaTimeC);
270 
271  // link the particle to the layer
272  particle.setOnLayer(layer->isForward(), layer->index());
273  LogDebug(MESSAGECATEGORY) << " moved particle to layer: " << *layer;
274  }else{
275  // particle no longer is on a layer
276  particle.resetOnLayer();
277  }
278 
279  // return true / false if propagations succeeded /failed
280  LogDebug(MESSAGECATEGORY) << " success: " << bool(layer);
281  return layer;
282 }
#define LogDebug(id)
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
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:142
const std::vector< std::unique_ptr< ForwardSimplifiedGeometry > > & forwardLayers() const
Return the vector of forward layers (disks).
Definition: Geometry.h:73
const BarrelSimplifiedGeometry * nextLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:98
double remainingProperLifeTimeC() const
Return the particle&#39;s remaining proper lifetime[in ct].
Definition: Particle.h:152
void setRemainingProperLifeTimeC(double remainingProperLifeTimeC)
Set the particle&#39;s remaining proper lifetime if not stable [in ct].
Definition: Particle.h:69
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:81
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double getMagneticFieldZ(const math::XYZTLorentzVector &position) const
Initializes the tracker geometry.
Definition: Geometry.cc:161
const BarrelSimplifiedGeometry * previousLayer(const BarrelSimplifiedGeometry *layer) const
Helps to navigate through the vector of barrel layers.
Definition: Geometry.h:130
const ForwardSimplifiedGeometry * previousForwardLayer_
Pointer to the previous (opposite direction of the particle&#39;s momentum) forward layer.
const std::vector< std::unique_ptr< BarrelSimplifiedGeometry > > & barrelLayers() const
Return the vector of barrel layers.
Definition: Geometry.h:66
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:175
void setOnLayer(bool isForward, int index)
Set layer this particle is currently on.
Definition: Particle.h:75
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:145
double gamma() const
Return Lorentz&#39; gamma factor.
Definition: Particle.h:184
bool isOnLayer(bool isForward, int index)
Check if particle is on layer.
Definition: Particle.h:170
static const std::string MESSAGECATEGORY

Member Data Documentation

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

The geometry of the tracker material.

Definition at line 69 of file LayerNavigator.h.

Referenced by moveParticleToNextLayer().

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.

Referenced by moveParticleToNextLayer().

const BarrelSimplifiedGeometry* fastsim::LayerNavigator::nextBarrelLayer_
private

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

Definition at line 70 of file LayerNavigator.h.

Referenced by moveParticleToNextLayer().

const ForwardSimplifiedGeometry* fastsim::LayerNavigator::nextForwardLayer_
private

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

Definition at line 72 of file LayerNavigator.h.

Referenced by moveParticleToNextLayer().

const BarrelSimplifiedGeometry* fastsim::LayerNavigator::previousBarrelLayer_
private

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

Definition at line 71 of file LayerNavigator.h.

Referenced by moveParticleToNextLayer().

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.

Referenced by moveParticleToNextLayer().