CMS 3D CMS Logo

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

Produces SimHits in the tracker layers. More...

Inheritance diagram for fastsim::TrackerSimHitProducer:
fastsim::InteractionModel

Public Member Functions

std::pair< double, std::unique_ptr< PSimHit > > createHitOnDetector (const TrajectoryStateOnSurface &particle, int pdgId, double layerThickness, double eLoss, int simTrackId, const GeomDet &detector, GlobalPoint &refPos)
 Helper funtion to create the actual SimHit on a detector (sub-) module. More...
 
void interact (Particle &particle, const SimplifiedGeometry &layer, std::vector< std::unique_ptr< Particle >> &secondaries, const RandomEngineAndDistribution &random) override
 Perform the interaction. More...
 
void registerProducts (edm::ProducesCollector) const override
 Register the SimHit collection. More...
 
void storeProducts (edm::Event &iEvent) override
 Store the SimHit collection. More...
 
 TrackerSimHitProducer (const std::string &name, const edm::ParameterSet &cfg)
 Constructor. More...
 
 ~TrackerSimHitProducer () override
 Default destructor. More...
 
- Public Member Functions inherited from fastsim::InteractionModel
const std::string getName ()
 Return (unique) name of this interaction. More...
 
virtual void interact (Particle &particle, const SimplifiedGeometry &layer, std::vector< std::unique_ptr< Particle > > &secondaries, const RandomEngineAndDistribution &random)=0
 Perform the interaction. More...
 
 InteractionModel (std::string name)
 Constructor. More...
 
virtual ~InteractionModel ()
 Default destructor. More...
 

Private Attributes

bool doHitsFromInboundParticles_
 If not set, incoming particles (negative speed relative to center of detector) don't create a SimHits since reconstruction anyways not possible. More...
 
double minMomentum_
 Set the minimal momentum of incoming particle. More...
 
const double onSurfaceTolerance_
 Max distance between particle and active (sub-) module. Otherwise particle has to be propagated. More...
 
std::unique_ptr< edm::PSimHitContainersimHitContainer_
 The SimHit. More...
 

Detailed Description

Produces SimHits in the tracker layers.

Also assigns the energy loss of the particle (ionization) with the SimHit. Furthermore, SimHits from different SubModules have to be sorted by their occurance!

See also
EnergyLoss

Definition at line 54 of file TrackerSimHitProducer.cc.

Constructor & Destructor Documentation

◆ TrackerSimHitProducer()

fastsim::TrackerSimHitProducer::TrackerSimHitProducer ( const std::string &  name,
const edm::ParameterSet cfg 
)

Constructor.

Definition at line 108 of file TrackerSimHitProducer.cc.

References looper::cfg, doHitsFromInboundParticles_, and minMomentum_.

110  // Set the minimal momentum
111  minMomentum_ = cfg.getParameter<double>("minMomentumCut");
112  // - if not set, particles from outside the beampipe with a negative speed in R direction are propagated but no SimHits
113  // - particle with positive (negative) z and negative (positive) speed in z direction: no SimHits
114  // -> this is not neccesary since a track reconstruction is not possible in this case anyways
115  doHitsFromInboundParticles_ = cfg.getParameter<bool>("doHitsFromInboundParticles");
116 }
std::unique_ptr< edm::PSimHitContainer > simHitContainer_
The SimHit.
Base class for any interaction model between a particle and a tracker layer.
bool doHitsFromInboundParticles_
If not set, incoming particles (negative speed relative to center of detector) don&#39;t create a SimHits...
double minMomentum_
Set the minimal momentum of incoming particle.
std::vector< PSimHit > PSimHitContainer
const double onSurfaceTolerance_
Max distance between particle and active (sub-) module. Otherwise particle has to be propagated...

◆ ~TrackerSimHitProducer()

fastsim::TrackerSimHitProducer::~TrackerSimHitProducer ( )
inlineoverride

Default destructor.

Definition at line 60 of file TrackerSimHitProducer.cc.

60 { ; }

Member Function Documentation

◆ createHitOnDetector()

std::pair< double, std::unique_ptr< PSimHit > > fastsim::TrackerSimHitProducer::createHitOnDetector ( const TrajectoryStateOnSurface particle,
int  pdgId,
double  layerThickness,
double  eLoss,
int  simTrackId,
const GeomDet detector,
GlobalPoint refPos 
)

Helper funtion to create the actual SimHit on a detector (sub-) module.

Parameters
particleRepresentation of the particle's trajectory
pdgIdThe pdgId of the particle
layerThicknessThe thickness of the layer (in radLengths)
eLossThe energy that particle deposited in the detector (lost via ionisation)
simTrackIdThe SimTrack this hit should be assigned to
detectorThe detector element that is hit
refPosReference position that is used to sort the hits if layer consists of sub-detectors \ return Returns the SimHit and the distance relative to refPos since hits have to be ordered (in time) afterwards.

Definition at line 256 of file TrackerSimHitProducer.cc.

References anyDirection, PV3DBase< T, PVType, FrameType >::basicVector(), Surface::bounds(), hgcalTestNeighbor_cfi::detector, simKBmtfDigis_cfi::eLoss, mps_splice::entry, beamvalidation::exit(), TrajectoryStateOnSurface::globalMomentum(), TrajectoryStateOnSurface::globalPosition(), Bounds::length(), TrajectoryStateOnSurface::localMomentum(), TrajectoryStateOnSurface::localPosition(), PV3DBase< T, PVType, FrameType >::mag(), mag(), castor_dqm_sourceclient_file_cfg::path, EgammaValidation_cff::pdgId, PV3DBase< T, PVType, FrameType >::perp(), PV3DBase< T, PVType, FrameType >::phi(), GloballyPositioned< T >::position(), fastsim::Constants::speedOfLight, PV3DBase< T, PVType, FrameType >::theta(), Bounds::thickness(), TrajectoryStateOnSurface::transverseCurvature(), Vector3DBase< T, FrameTag >::unit(), Bounds::width(), PV3DBase< T, PVType, FrameType >::x(), PV3DBase< T, PVType, FrameType >::y(), and PV3DBase< T, PVType, FrameType >::z().

263  {
264  // determine position and momentum of particle in the coordinate system of the detector
265  LocalPoint localPosition;
266  LocalVector localMomentum;
267 
268  // if the particle is close enough, no further propagation is needed
269  if (fabs(detector.toLocal(particle.globalPosition()).z()) < onSurfaceTolerance_) {
270  localPosition = particle.localPosition();
271  localMomentum = particle.localMomentum();
272  }
273  // else, propagate
274  else {
275  // find crossing of particle with detector layer
277  particle.globalMomentum().basicVector(),
278  particle.transverseCurvature(),
279  anyDirection);
280  std::pair<bool, double> path = crossing.pathLength(detector.surface());
281  // case propagation succeeds
282  if (path.first) {
283  localPosition = detector.toLocal(GlobalPoint(crossing.position(path.second)));
284  localMomentum = detector.toLocal(GlobalVector(crossing.direction(path.second)));
285  localMomentum = localMomentum.unit() * particle.localMomentum().mag();
286  }
287  // case propagation fails
288  else {
289  return std::pair<double, std::unique_ptr<PSimHit>>(0, std::unique_ptr<PSimHit>(nullptr));
290  }
291  }
292 
293  // find entry and exit point of particle in detector
294  const Plane& detectorPlane = detector.surface();
295  double halfThick = 0.5 * detectorPlane.bounds().thickness();
296  double pZ = localMomentum.z();
297  LocalPoint entry = localPosition + (-halfThick / pZ) * localMomentum;
298  LocalPoint exit = localPosition + (halfThick / pZ) * localMomentum;
299  double tof = particle.globalPosition().mag() / fastsim::Constants::speedOfLight; // in nanoseconds
300 
301  // make sure the simhit is physically on the module
302  double boundX = detectorPlane.bounds().width() / 2.;
303  double boundY = detectorPlane.bounds().length() / 2.;
304  // Special treatment for TID and TEC trapeziodal modules
305  unsigned subdet = DetId(detector.geographicalId()).subdetId();
306  if (subdet == 4 || subdet == 6)
307  boundX *= 1. - localPosition.y() / detectorPlane.position().perp();
308  if (fabs(localPosition.x()) > boundX || fabs(localPosition.y()) > boundY) {
309  return std::pair<double, std::unique_ptr<PSimHit>>(0, std::unique_ptr<PSimHit>(nullptr));
310  }
311 
312  // Create the hit: the energy loss rescaled to the module thickness
313  // Total thickness is in radiation lengths, 1 radlen = 9.36 cm
314  // Sensitive module thickness is about 30 microns larger than
315  // the module thickness itself
316  eLoss *= (2. * halfThick - 0.003) / (9.36 * layerThickness);
317 
318  // Position of the hit in global coordinates
319  GlobalPoint hitPos(detector.surface().toGlobal(localPosition));
320 
321  return std::pair<double, std::unique_ptr<PSimHit>>((hitPos - refPos).mag(),
322  std::make_unique<PSimHit>(entry,
323  exit,
324  localMomentum.mag(),
325  tof,
326  eLoss,
327  pdgId,
328  detector.geographicalId().rawId(),
329  simTrackId,
330  localMomentum.theta(),
331  localMomentum.phi()));
332 }
T perp() const
Definition: PV3DBase.h:69
virtual float length() const =0
T z() const
Definition: PV3DBase.h:61
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
static double constexpr speedOfLight
Speed of light [cm / ns].
Definition: Constants.h:12
Definition: Plane.h:16
virtual float thickness() const =0
T x() const
Definition: PV3DBase.h:59
T y() const
Definition: PV3DBase.h:60
GlobalPoint globalPosition() const
T mag() const
Definition: PV3DBase.h:64
const BasicVectorType & basicVector() const
Definition: PV3DBase.h:53
Definition: DetId.h:17
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
const PositionType & position() const
GlobalVector globalMomentum() const
Vector3DBase unit() const
Definition: Vector3DBase.h:54
virtual float width() const =0
Global3DVector GlobalVector
Definition: GlobalVector.h:10
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72
const double onSurfaceTolerance_
Max distance between particle and active (sub-) module. Otherwise particle has to be propagated...
def exit(msg="")
const Bounds & bounds() const
Definition: Surface.h:87

◆ interact()

void fastsim::TrackerSimHitProducer::interact ( Particle particle,
const SimplifiedGeometry layer,
std::vector< std::unique_ptr< Particle >> &  secondaries,
const RandomEngineAndDistribution random 
)
override

Perform the interaction.

Parameters
particleThe particle that interacts with the matter.
layerThe detector layer that interacts with the particle.
secondariesParticles that are produced in the interaction (if any).
randomThe Random Engine.

Definition at line 127 of file TrackerSimHitProducer.cc.

References anyDirection, fastsim::Particle::charge(), hgcalTestNeighbor_cfi::detector, fastsim::Particle::getEnergyDeposit(), fastsim::Particle::getMotherSimTrackIndex(), fastsim::Particle::isLooper(), HLT_2023v12_cff::magneticField, genParticles_cff::map, fastsim::Particle::momentum(), eostools::move(), EgammaValidation_cff::pdgId, fastsim::Particle::pdgId(), fastsim::Particle::position(), position, TrackCandidateProducer_cfi::propagator, fastsim::Particle::setEnergyDeposit(), fastsim::Particle::setLooper(), and fastsim::Particle::simTrackIndex().

130  {
131  // the energy deposit in the layer
132  double energyDeposit = particle.getEnergyDeposit();
133  particle.setEnergyDeposit(0);
134 
135  //
136  // don't save hits from particle that did a loop or are inbound (coming from the outer part of the tracker, going towards the center)
137  //
139  if (particle.isLooper()) {
140  return;
141  }
142  if (particle.momentum().X() * particle.position().X() + particle.momentum().Y() * particle.position().Y() < 0) {
143  particle.setLooper();
144  return;
145  }
146  if (layer.isForward() && ((particle.position().Z() > 0 && particle.momentum().Z() < 0) ||
147  (particle.position().Z() < 0 && particle.momentum().Z() > 0))) {
148  particle.setLooper();
149  return;
150  }
151  }
152 
153  //
154  // check that layer has tracker modules
155  //
156  if (!layer.getDetLayer()) {
157  return;
158  }
159 
160  //
161  // no material
162  //
163  if (layer.getThickness(particle.position(), particle.momentum()) < 1E-10) {
164  return;
165  }
166 
167  //
168  // only charged particles
169  //
170  if (particle.charge() == 0) {
171  return;
172  }
173 
174  //
175  // save hit only if momentum higher than threshold
176  //
177  if (particle.momentum().Perp2() < minMomentum_ * minMomentum_) {
178  return;
179  }
180 
181  // create the trajectory of the particle
182  UniformMagneticField magneticField(layer.getMagneticFieldZ(particle.position()));
183  GlobalPoint position(particle.position().X(), particle.position().Y(), particle.position().Z());
184  GlobalVector momentum(particle.momentum().Px(), particle.momentum().Py(), particle.momentum().Pz());
185  auto plane = layer.getDetLayer()->surface().tangentPlane(position);
186  TrajectoryStateOnSurface trajectory(
187  GlobalTrajectoryParameters(position, momentum, TrackCharge(particle.charge()), &magneticField), *plane);
188 
189  // find detectors compatible with the particle's trajectory
192  std::vector<DetWithState> compatibleDetectors = layer.getDetLayer()->compatibleDets(trajectory, propagator, est);
193 
195  // You have to sort the simHits in the order they occur!
197 
198  // The old algorithm (sorting by distance to IP) doesn't seem to make sense to me (what if particle moves inwards?)
199 
200  // Detector layers have to be sorted by proximity to particle.position
201  // Propagate particle backwards a bit to make sure it's outside any components
202  std::map<double, std::unique_ptr<PSimHit>> distAndHits;
203  // Position relative to which the hits should be sorted
204  GlobalPoint positionOutside(particle.position().x() - particle.momentum().x() / particle.momentum().P() * 10.,
205  particle.position().y() - particle.momentum().y() / particle.momentum().P() * 10.,
206  particle.position().z() - particle.momentum().z() / particle.momentum().P() * 10.);
207 
208  // FastSim: cheat tracking -> assign hits to closest charged daughter if particle decays
209  int pdgId = particle.pdgId();
210  int simTrackId =
211  particle.getMotherSimTrackIndex() >= 0 ? particle.getMotherSimTrackIndex() : particle.simTrackIndex();
212 
213  // loop over the compatible detectors
214  for (const auto& detectorWithState : compatibleDetectors) {
215  const GeomDet& detector = *detectorWithState.first;
216  const TrajectoryStateOnSurface& particleState = detectorWithState.second;
217 
218  // if the detector has no components
219  if (detector.isLeaf()) {
220  std::pair<double, std::unique_ptr<PSimHit>> hitPair = createHitOnDetector(particleState,
221  pdgId,
222  layer.getThickness(particle.position()),
223  energyDeposit,
224  simTrackId,
225  detector,
226  positionOutside);
227  if (hitPair.second) {
228  distAndHits.insert(distAndHits.end(), std::move(hitPair));
229  }
230  } else {
231  // if the detector has components
232  for (const auto component : detector.components()) {
233  std::pair<double, std::unique_ptr<PSimHit>> hitPair =
234  createHitOnDetector(particleState,
235  pdgId,
236  layer.getThickness(particle.position()),
237  energyDeposit,
238  simTrackId,
239  *component,
240  positionOutside);
241  if (hitPair.second) {
242  distAndHits.insert(distAndHits.end(), std::move(hitPair));
243  }
244  }
245  }
246  }
247 
248  // Fill simHitContainer
249  for (std::map<double, std::unique_ptr<PSimHit>>::const_iterator it = distAndHits.begin(); it != distAndHits.end();
250  it++) {
251  simHitContainer_->push_back(*(it->second));
252  }
253 }
std::unique_ptr< edm::PSimHitContainer > simHitContainer_
The SimHit.
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
int TrackCharge
Definition: TrackCharge.h:4
bool doHitsFromInboundParticles_
If not set, incoming particles (negative speed relative to center of detector) don&#39;t create a SimHits...
std::pair< double, std::unique_ptr< PSimHit > > createHitOnDetector(const TrajectoryStateOnSurface &particle, int pdgId, double layerThickness, double eLoss, int simTrackId, const GeomDet &detector, GlobalPoint &refPos)
Helper funtion to create the actual SimHit on a detector (sub-) module.
double minMomentum_
Set the minimal momentum of incoming particle.
static int position[264][3]
Definition: ReadPGInfo.cc:289
def move(src, dest)
Definition: eostools.py:511

◆ registerProducts()

void fastsim::TrackerSimHitProducer::registerProducts ( edm::ProducesCollector  producesCollector) const
overridevirtual

Register the SimHit collection.

Reimplemented from fastsim::InteractionModel.

Definition at line 118 of file TrackerSimHitProducer.cc.

References edm::ProducesCollector::produces().

118  {
119  producesCollector.produces<edm::PSimHitContainer>("TrackerHits");
120 }
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
std::vector< PSimHit > PSimHitContainer

◆ storeProducts()

void fastsim::TrackerSimHitProducer::storeProducts ( edm::Event iEvent)
overridevirtual

Store the SimHit collection.

Reimplemented from fastsim::InteractionModel.

Definition at line 122 of file TrackerSimHitProducer.cc.

References iEvent, and eostools::move().

122  {
123  iEvent.put(std::move(simHitContainer_), "TrackerHits");
124  simHitContainer_ = std::make_unique<edm::PSimHitContainer>();
125 }
std::unique_ptr< edm::PSimHitContainer > simHitContainer_
The SimHit.
int iEvent
Definition: GenABIO.cc:224
def move(src, dest)
Definition: eostools.py:511

Member Data Documentation

◆ doHitsFromInboundParticles_

bool fastsim::TrackerSimHitProducer::doHitsFromInboundParticles_
private

If not set, incoming particles (negative speed relative to center of detector) don't create a SimHits since reconstruction anyways not possible.

Definition at line 104 of file TrackerSimHitProducer.cc.

Referenced by TrackerSimHitProducer().

◆ minMomentum_

double fastsim::TrackerSimHitProducer::minMomentum_
private

Set the minimal momentum of incoming particle.

Definition at line 103 of file TrackerSimHitProducer.cc.

Referenced by TrackerSimHitProducer().

◆ onSurfaceTolerance_

const double fastsim::TrackerSimHitProducer::onSurfaceTolerance_
private

Max distance between particle and active (sub-) module. Otherwise particle has to be propagated.

Definition at line 101 of file TrackerSimHitProducer.cc.

◆ simHitContainer_

std::unique_ptr<edm::PSimHitContainer> fastsim::TrackerSimHitProducer::simHitContainer_
private

The SimHit.

Definition at line 102 of file TrackerSimHitProducer.cc.