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 
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 }
283 
284 
#define LogDebug(id)
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Definition: LayerTriplets.cc:4
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:142
LayerNavigator(const Geometry &geometry)
Constructor.
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
#define nullptr
double remainingProperLifeTimeC() const
Return the particle&#39;s remaining proper lifetime[in ct].
Definition: Particle.h:152
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:69
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:81
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:130
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:34
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:18
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
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
Definition: Particle.h:19
bool isOnLayer(bool isForward, int index)
Check if particle is on layer.
Definition: Particle.h:170
double getMagneticFieldZ(const math::XYZTLorentzVector &position) const
Initializes the tracker geometry.
Definition: Geometry.cc:161
static const std::string MESSAGECATEGORY