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 52 of file TrackerSimHitProducer.cc.

Constructor & Destructor Documentation

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

Constructor.

Definition at line 106 of file TrackerSimHitProducer.cc.

References doHitsFromInboundParticles_, edm::ParameterSet::getParameter(), and minMomentum_.

108  // Set the minimal momentum
109  minMomentum_ = cfg.getParameter<double>("minMomentumCut");
110  // - if not set, particles from outside the beampipe with a negative speed in R direction are propagated but no SimHits
111  // - particle with positive (negative) z and negative (positive) speed in z direction: no SimHits
112  // -> this is not neccesary since a track reconstruction is not possible in this case anyways
113  doHitsFromInboundParticles_ = cfg.getParameter<bool>("doHitsFromInboundParticles");
114 }
T getParameter(std::string const &) const
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...
fastsim::TrackerSimHitProducer::~TrackerSimHitProducer ( )
inlineoverride

Member Function Documentation

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 254 of file TrackerSimHitProducer.cc.

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

Referenced by interact(), and ~TrackerSimHitProducer().

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

References anyDirection, fastsim::Particle::charge(), GeometricSearchDet::compatibleDets(), GeomDet::components(), createHitOnDetector(), hgcalTestNeighbor_cfi::detector, doHitsFromInboundParticles_, fastsim::SimplifiedGeometry::getDetLayer(), fastsim::Particle::getEnergyDeposit(), fastsim::SimplifiedGeometry::getMagneticFieldZ(), fastsim::Particle::getMotherSimTrackIndex(), fastsim::SimplifiedGeometry::getThickness(), fastsim::SimplifiedGeometry::isForward(), GeomDet::isLeaf(), fastsim::Particle::isLooper(), HLT_2018_cff::magneticField, genParticles_cff::map, minMomentum_, fastsim::Particle::momentum(), eostools::move(), EgammaValidation_cff::pdgId, fastsim::Particle::pdgId(), fastsim::Particle::position(), position, TrackCandidateProducer_cfi::propagator, fastsim::Particle::setEnergyDeposit(), fastsim::Particle::setLooper(), simHitContainer_, fastsim::Particle::simTrackIndex(), GeometricSearchDet::surface(), and Surface::tangentPlane().

Referenced by ~TrackerSimHitProducer().

128  {
129  // the energy deposit in the layer
130  double energyDeposit = particle.getEnergyDeposit();
131  particle.setEnergyDeposit(0);
132 
133  //
134  // 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)
135  //
137  if (particle.isLooper()) {
138  return;
139  }
140  if (particle.momentum().X() * particle.position().X() + particle.momentum().Y() * particle.position().Y() < 0) {
141  particle.setLooper();
142  return;
143  }
144  if (layer.isForward() && ((particle.position().Z() > 0 && particle.momentum().Z() < 0) ||
145  (particle.position().Z() < 0 && particle.momentum().Z() > 0))) {
146  particle.setLooper();
147  return;
148  }
149  }
150 
151  //
152  // check that layer has tracker modules
153  //
154  if (!layer.getDetLayer()) {
155  return;
156  }
157 
158  //
159  // no material
160  //
161  if (layer.getThickness(particle.position(), particle.momentum()) < 1E-10) {
162  return;
163  }
164 
165  //
166  // only charged particles
167  //
168  if (particle.charge() == 0) {
169  return;
170  }
171 
172  //
173  // save hit only if momentum higher than threshold
174  //
175  if (particle.momentum().Perp2() < minMomentum_ * minMomentum_) {
176  return;
177  }
178 
179  // create the trajectory of the particle
180  UniformMagneticField magneticField(layer.getMagneticFieldZ(particle.position()));
181  GlobalPoint position(particle.position().X(), particle.position().Y(), particle.position().Z());
182  GlobalVector momentum(particle.momentum().Px(), particle.momentum().Py(), particle.momentum().Pz());
183  auto plane = layer.getDetLayer()->surface().tangentPlane(position);
184  TrajectoryStateOnSurface trajectory(
185  GlobalTrajectoryParameters(position, momentum, TrackCharge(particle.charge()), &magneticField), *plane);
186 
187  // find detectors compatible with the particle's trajectory
190  std::vector<DetWithState> compatibleDetectors = layer.getDetLayer()->compatibleDets(trajectory, propagator, est);
191 
193  // You have to sort the simHits in the order they occur!
195 
196  // The old algorithm (sorting by distance to IP) doesn't seem to make sense to me (what if particle moves inwards?)
197 
198  // Detector layers have to be sorted by proximity to particle.position
199  // Propagate particle backwards a bit to make sure it's outside any components
200  std::map<double, std::unique_ptr<PSimHit>> distAndHits;
201  // Position relative to which the hits should be sorted
202  GlobalPoint positionOutside(particle.position().x() - particle.momentum().x() / particle.momentum().P() * 10.,
203  particle.position().y() - particle.momentum().y() / particle.momentum().P() * 10.,
204  particle.position().z() - particle.momentum().z() / particle.momentum().P() * 10.);
205 
206  // FastSim: cheat tracking -> assign hits to closest charged daughter if particle decays
207  int pdgId = particle.pdgId();
208  int simTrackId =
209  particle.getMotherSimTrackIndex() >= 0 ? particle.getMotherSimTrackIndex() : particle.simTrackIndex();
210 
211  // loop over the compatible detectors
212  for (const auto& detectorWithState : compatibleDetectors) {
213  const GeomDet& detector = *detectorWithState.first;
214  const TrajectoryStateOnSurface& particleState = detectorWithState.second;
215 
216  // if the detector has no components
217  if (detector.isLeaf()) {
218  std::pair<double, std::unique_ptr<PSimHit>> hitPair = createHitOnDetector(particleState,
219  pdgId,
220  layer.getThickness(particle.position()),
221  energyDeposit,
222  simTrackId,
223  detector,
224  positionOutside);
225  if (hitPair.second) {
226  distAndHits.insert(distAndHits.end(), std::move(hitPair));
227  }
228  } else {
229  // if the detector has components
230  for (const auto component : detector.components()) {
231  std::pair<double, std::unique_ptr<PSimHit>> hitPair =
232  createHitOnDetector(particleState,
233  pdgId,
234  layer.getThickness(particle.position()),
235  energyDeposit,
236  simTrackId,
237  *component,
238  positionOutside);
239  if (hitPair.second) {
240  distAndHits.insert(distAndHits.end(), std::move(hitPair));
241  }
242  }
243  }
244  }
245 
246  // Fill simHitContainer
247  for (std::map<double, std::unique_ptr<PSimHit>>::const_iterator it = distAndHits.begin(); it != distAndHits.end();
248  it++) {
249  simHitContainer_->push_back(*(it->second));
250  }
251 }
double Px() const
Definition: Particle.h:79
double Py() const
Definition: Particle.h:84
virtual std::vector< const GeomDet * > components() const
Returns direct components, if any.
Definition: GeomDet.h:73
std::unique_ptr< edm::PSimHitContainer > simHitContainer_
The SimHit.
double X() const
Definition: Particle.h:59
double Z() const
Definition: Particle.h:69
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 Pz() const
Definition: Particle.h:89
virtual bool isLeaf() const
is a Unit
Definition: GeomDet.h:70
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
double Y() const
Definition: Particle.h:64
void fastsim::TrackerSimHitProducer::registerProducts ( edm::ProducesCollector  producesCollector) const
overridevirtual

Register the SimHit collection.

Reimplemented from fastsim::InteractionModel.

Definition at line 116 of file TrackerSimHitProducer.cc.

References edm::ProducesCollector::produces().

Referenced by ~TrackerSimHitProducer().

116  {
117  producesCollector.produces<edm::PSimHitContainer>("TrackerHits");
118 }
ProductRegistryHelper::BranchAliasSetterT< ProductType > produces()
std::vector< PSimHit > PSimHitContainer
void fastsim::TrackerSimHitProducer::storeProducts ( edm::Event iEvent)
overridevirtual

Store the SimHit collection.

Reimplemented from fastsim::InteractionModel.

Definition at line 120 of file TrackerSimHitProducer.cc.

References eostools::move(), edm::Event::put(), and simHitContainer_.

Referenced by ~TrackerSimHitProducer().

120  {
121  iEvent.put(std::move(simHitContainer_), "TrackerHits");
123 }
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
std::unique_ptr< edm::PSimHitContainer > simHitContainer_
The SimHit.
std::vector< PSimHit > PSimHitContainer
def move(src, dest)
Definition: eostools.py:511

Member Data Documentation

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 102 of file TrackerSimHitProducer.cc.

Referenced by interact(), and TrackerSimHitProducer().

double fastsim::TrackerSimHitProducer::minMomentum_
private

Set the minimal momentum of incoming particle.

Definition at line 101 of file TrackerSimHitProducer.cc.

Referenced by interact(), and TrackerSimHitProducer().

const double fastsim::TrackerSimHitProducer::onSurfaceTolerance_
private

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

Definition at line 99 of file TrackerSimHitProducer.cc.

Referenced by createHitOnDetector().

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

The SimHit.

Definition at line 100 of file TrackerSimHitProducer.cc.

Referenced by interact(), and storeProducts().