File indexing completed on 2024-04-06 12:11:21
0001 #include "FastSimulation/SimplifiedGeometryPropagator/interface/LayerNavigator.h"
0002 #include "FastSimulation/SimplifiedGeometryPropagator/interface/Constants.h"
0003
0004 #include <vector>
0005
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007
0008 #include "FastSimulation/SimplifiedGeometryPropagator/interface/Geometry.h"
0009 #include "FastSimulation/SimplifiedGeometryPropagator/interface/BarrelSimplifiedGeometry.h"
0010 #include "FastSimulation/SimplifiedGeometryPropagator/interface/ForwardSimplifiedGeometry.h"
0011 #include "FastSimulation/SimplifiedGeometryPropagator/interface/LayerNavigator.h"
0012 #include "FastSimulation/SimplifiedGeometryPropagator/interface/Trajectory.h"
0013 #include "FastSimulation/SimplifiedGeometryPropagator/interface/Particle.h"
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 const std::string fastsim::LayerNavigator::MESSAGECATEGORY = "FastSimulation";
0059
0060 fastsim::LayerNavigator::LayerNavigator(const fastsim::Geometry& geometry)
0061 : geometry_(&geometry),
0062 nextBarrelLayer_(nullptr),
0063 previousBarrelLayer_(nullptr),
0064 nextForwardLayer_(nullptr),
0065 previousForwardLayer_(nullptr) {
0066 ;
0067 }
0068
0069 bool fastsim::LayerNavigator::moveParticleToNextLayer(fastsim::Particle& particle,
0070 const fastsim::SimplifiedGeometry*& layer) {
0071 LogDebug(MESSAGECATEGORY) << " moveToNextLayer called";
0072
0073
0074 if (layer) {
0075 if (!particle.isOnLayer(layer->isForward(), layer->index())) {
0076 throw cms::Exception("FastSimulation") << "If layer is provided, particle must be on layer."
0077 << "\n Layer: " << *layer << "\n Particle: " << particle;
0078 }
0079 }
0080
0081
0082
0083 double magneticFieldZ =
0084 layer ? layer->getMagneticFieldZ(particle.position()) : geometry_->getMagneticFieldZ(particle.position());
0085 LogDebug(MESSAGECATEGORY) << " magnetic field z component:" << magneticFieldZ;
0086
0087
0088 bool particleMovesInwards =
0089 particle.momentum().X() * particle.position().X() + particle.momentum().Y() * particle.position().Y() < 0;
0090
0091
0092
0093
0094
0095
0096
0097
0098 if (!layer) {
0099 LogDebug(MESSAGECATEGORY) << " called for first time";
0100
0101
0102
0103
0104 for (const auto& layer : geometry_->barrelLayers()) {
0105 if (particle.isOnLayer(false, layer->index()) ||
0106 std::abs(layer->getRadius() - particle.position().Rho()) < 1e-2) {
0107 if (particleMovesInwards) {
0108 nextBarrelLayer_ = layer.get();
0109 break;
0110 } else {
0111 continue;
0112 }
0113 }
0114
0115 if (particle.position().Pt() < layer->getRadius()) {
0116 nextBarrelLayer_ = layer.get();
0117 break;
0118 }
0119
0120 previousBarrelLayer_ = layer.get();
0121 }
0122
0123
0124
0125 for (const auto& layer : geometry_->forwardLayers()) {
0126 if (particle.isOnLayer(true, layer->index()) || std::abs(layer->getZ() - particle.position().Z()) < 1e-3) {
0127 if (particle.momentum().Z() < 0) {
0128 nextForwardLayer_ = layer.get();
0129 break;
0130 } else {
0131 continue;
0132 }
0133 }
0134
0135 if (particle.position().Z() < layer->getZ()) {
0136 nextForwardLayer_ = layer.get();
0137 break;
0138 }
0139
0140 previousForwardLayer_ = layer.get();
0141 }
0142 }
0143
0144
0145
0146 else {
0147 LogDebug(MESSAGECATEGORY) << " ordinary call";
0148
0149
0150 if (layer == nextBarrelLayer_) {
0151 if (!particleMovesInwards) {
0152 previousBarrelLayer_ = nextBarrelLayer_;
0153 nextBarrelLayer_ = geometry_->nextLayer(nextBarrelLayer_);
0154 }
0155 } else if (layer == previousBarrelLayer_) {
0156 if (particleMovesInwards) {
0157 nextBarrelLayer_ = previousBarrelLayer_;
0158 previousBarrelLayer_ = geometry_->previousLayer(previousBarrelLayer_);
0159 }
0160 }
0161
0162 else if (layer == nextForwardLayer_) {
0163 if (particle.momentum().Z() > 0) {
0164 previousForwardLayer_ = nextForwardLayer_;
0165 nextForwardLayer_ = geometry_->nextLayer(nextForwardLayer_);
0166 }
0167 } else if (layer == previousForwardLayer_) {
0168 if (particle.momentum().Z() < 0) {
0169 nextForwardLayer_ = previousForwardLayer_;
0170 previousForwardLayer_ = geometry_->previousLayer(previousForwardLayer_);
0171 }
0172 }
0173
0174
0175 layer = nullptr;
0176 }
0177
0178
0179
0180
0181
0182 LogDebug(MESSAGECATEGORY) << " particle between BarrelLayers: "
0183 << (previousBarrelLayer_ ? previousBarrelLayer_->index() : -1) << "/"
0184 << (nextBarrelLayer_ ? nextBarrelLayer_->index() : -1)
0185 << " (total: " << geometry_->barrelLayers().size() << ")"
0186 << "\n particle between ForwardLayers: "
0187 << (previousForwardLayer_ ? previousForwardLayer_->index() : -1) << "/"
0188 << (nextForwardLayer_ ? nextForwardLayer_->index() : -1)
0189 << " (total: " << geometry_->forwardLayers().size() << ")";
0190
0191
0192 std::unique_ptr<fastsim::Trajectory> trajectory = Trajectory::createTrajectory(particle, magneticFieldZ);
0193
0194
0195 std::vector<const fastsim::SimplifiedGeometry*> layers;
0196 if (nextBarrelLayer_) {
0197 layers.push_back(nextBarrelLayer_);
0198 }
0199 if (previousBarrelLayer_) {
0200 layers.push_back(previousBarrelLayer_);
0201 }
0202
0203 if (particle.momentum().Z() > 0) {
0204 if (nextForwardLayer_) {
0205 layers.push_back(nextForwardLayer_);
0206 }
0207 } else {
0208 if (previousForwardLayer_) {
0209 layers.push_back(previousForwardLayer_);
0210 }
0211 }
0212
0213
0214
0215 double deltaTimeC = -1;
0216 for (auto _layer : layers) {
0217 double tempDeltaTime =
0218 trajectory->nextCrossingTimeC(*_layer, particle.isOnLayer(_layer->isForward(), _layer->index()));
0219 LogDebug(MESSAGECATEGORY) << " particle crosses layer " << *_layer << " in time " << tempDeltaTime;
0220 if (tempDeltaTime > 0 && (layer == nullptr || tempDeltaTime < deltaTimeC || deltaTimeC < 0)) {
0221 layer = _layer;
0222 deltaTimeC = tempDeltaTime;
0223 }
0224 }
0225
0226
0227 double properDeltaTimeC = deltaTimeC / particle.gamma();
0228 if (!particle.isStable() && properDeltaTimeC > particle.remainingProperLifeTimeC()) {
0229
0230 deltaTimeC = particle.remainingProperLifeTimeC() * particle.gamma();
0231
0232 trajectory->move(deltaTimeC);
0233 particle.position() = trajectory->getPosition();
0234 particle.momentum() = trajectory->getMomentum();
0235
0236 particle.setRemainingProperLifeTimeC(0.);
0237
0238
0239 particle.resetOnLayer();
0240 LogDebug(MESSAGECATEGORY) << " particle about to decay. Will not be moved all the way to the next layer.";
0241 return false;
0242 }
0243
0244 if (layer) {
0245
0246 trajectory->move(deltaTimeC);
0247 particle.position() = trajectory->getPosition();
0248 particle.momentum() = trajectory->getMomentum();
0249
0250 if (!particle.isStable())
0251 particle.setRemainingProperLifeTimeC(particle.remainingProperLifeTimeC() - properDeltaTimeC);
0252
0253
0254 particle.setOnLayer(layer->isForward(), layer->index());
0255 LogDebug(MESSAGECATEGORY) << " moved particle to layer: " << *layer;
0256 } else {
0257
0258 particle.resetOnLayer();
0259 }
0260
0261
0262 LogDebug(MESSAGECATEGORY) << " success: " << bool(layer);
0263 return layer;
0264 }