61 : geometry_(&geometry),
62 nextBarrelLayer_(nullptr),
63 previousBarrelLayer_(nullptr),
64 nextForwardLayer_(nullptr),
65 previousForwardLayer_(nullptr) {
71 LogDebug(MESSAGECATEGORY) <<
" moveToNextLayer called";
76 throw cms::Exception(
"FastSimulation") <<
"If layer is provided, particle must be on layer."
77 <<
"\n Layer: " << *layer <<
"\n Particle: " << particle;
83 double magneticFieldZ =
85 LogDebug(MESSAGECATEGORY) <<
" magnetic field z component:" << magneticFieldZ;
88 bool particleMovesInwards =
99 LogDebug(MESSAGECATEGORY) <<
" called for first time";
104 for (
const auto& layer : geometry_->barrelLayers()) {
107 if (particleMovesInwards) {
108 nextBarrelLayer_ = layer.get();
115 if (particle.
position().Pt() < layer->getRadius()) {
116 nextBarrelLayer_ = layer.get();
120 previousBarrelLayer_ = layer.get();
125 for (
const auto& layer : geometry_->forwardLayers()) {
128 nextForwardLayer_ = layer.get();
135 if (particle.
position().Z() < layer->getZ()) {
136 nextForwardLayer_ = layer.get();
140 previousForwardLayer_ = layer.get();
147 LogDebug(MESSAGECATEGORY) <<
" ordinary call";
150 if (layer == nextBarrelLayer_) {
151 if (!particleMovesInwards) {
152 previousBarrelLayer_ = nextBarrelLayer_;
153 nextBarrelLayer_ = geometry_->nextLayer(nextBarrelLayer_);
155 }
else if (layer == previousBarrelLayer_) {
156 if (particleMovesInwards) {
157 nextBarrelLayer_ = previousBarrelLayer_;
158 previousBarrelLayer_ = geometry_->previousLayer(previousBarrelLayer_);
162 else if (layer == nextForwardLayer_) {
164 previousForwardLayer_ = nextForwardLayer_;
165 nextForwardLayer_ = geometry_->nextLayer(nextForwardLayer_);
167 }
else if (layer == previousForwardLayer_) {
169 nextForwardLayer_ = previousForwardLayer_;
170 previousForwardLayer_ = geometry_->previousLayer(previousForwardLayer_);
182 LogDebug(MESSAGECATEGORY) <<
" particle between BarrelLayers: "
183 << (previousBarrelLayer_ ? previousBarrelLayer_->index() : -1) <<
"/"
184 << (nextBarrelLayer_ ? nextBarrelLayer_->index() : -1)
185 <<
" (total: " << geometry_->barrelLayers().size() <<
")"
186 <<
"\n particle between ForwardLayers: "
187 << (previousForwardLayer_ ? previousForwardLayer_->index() : -1) <<
"/"
188 << (nextForwardLayer_ ? nextForwardLayer_->index() : -1)
189 <<
" (total: " << geometry_->forwardLayers().size() <<
")";
195 std::vector<const fastsim::SimplifiedGeometry*>
layers;
196 if (nextBarrelLayer_) {
197 layers.push_back(nextBarrelLayer_);
199 if (previousBarrelLayer_) {
200 layers.push_back(previousBarrelLayer_);
204 if (nextForwardLayer_) {
205 layers.push_back(nextForwardLayer_);
208 if (previousForwardLayer_) {
209 layers.push_back(previousForwardLayer_);
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)) {
222 deltaTimeC = tempDeltaTime;
227 double properDeltaTimeC = deltaTimeC / particle.
gamma();
232 trajectory->move(deltaTimeC);
233 particle.
position() = trajectory->getPosition();
234 particle.
momentum() = trajectory->getMomentum();
240 LogDebug(MESSAGECATEGORY) <<
" particle about to decay. Will not be moved all the way to the next layer.";
246 trajectory->move(deltaTimeC);
247 particle.
position() = trajectory->getPosition();
248 particle.
momentum() = trajectory->getMomentum();
255 LogDebug(MESSAGECATEGORY) <<
" moved particle to layer: " << *
layer;
262 LogDebug(MESSAGECATEGORY) <<
" success: " << bool(layer);
std::vector< LayerSetAndLayers > layers(const SeedingLayerSetsHits &sets)
Implementation of a generic detector layer (base class for forward/barrel layers).
virtual const double getMagneticFieldZ(const math::XYZTLorentzVector &position) const =0
Return magnetic field (field only has Z component!) on the layer.
const math::XYZTLorentzVector & position() const
Return position of the particle.
LayerNavigator(const Geometry &geometry)
Constructor.
double remainingProperLifeTimeC() const
Return the particle's remaining proper lifetime[in ct].
void setRemainingProperLifeTimeC(double remainingProperLifeTimeC)
Set the particle's remaining proper lifetime if not stable [in ct].
bool moveParticleToNextLayer(Particle &particle, const SimplifiedGeometry *&layer)
Move particle along its trajectory to the next intersection with any of the tracker layers...
constexpr std::array< uint8_t, layerIndexSize > layer
void resetOnLayer()
Reset layer this particle is currently on (i.e. particle is not on a layer anyomre) ...
Abs< T >::type abs(const T &t)
virtual bool isForward() const =0
Returns false/true depending if the object is a (non-abstract) barrel/forward layer.
Definition the tracker geometry (vectors of forward/barrel layers).
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.
void setOnLayer(bool isForward, int index)
Set layer this particle is currently on.
static std::unique_ptr< Trajectory > createTrajectory(const fastsim::Particle &particle, const double magneticFieldZ)
Calls constructor of derived classes.
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
double gamma() const
Return Lorentz' gamma factor.
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
bool isOnLayer(bool isForward, int index)
Check if particle is on layer.
static const std::string MESSAGECATEGORY