3 #include "HepMC/GenEvent.h"
4 #include "HepMC/Units.h"
5 #include "HepPDT/ParticleDataTable.hh"
19 double beamPipeRadius,
20 double deltaRchargedMother,
22 std::vector<SimTrack>& simTracks,
23 std::vector<SimVertex>& simVertices)
24 : genEvent_(&genEvent),
25 genParticleIterator_(genEvent_->particles_begin()),
26 genParticleEnd_(genEvent_->particles_end()),
28 particleDataTable_(&particleDataTable),
29 beamPipeRadius2_(beamPipeRadius * beamPipeRadius),
30 deltaRchargedMother_(deltaRchargedMother),
31 particleFilter_(&particleFilter),
32 simTracks_(&simTracks),
33 simVertices_(&simVertices)
43 momentumUnitConversionFactor_(conversion_factor(genEvent_->momentum_unit(), HepMC::Units::GEV)),
44 lengthUnitConversionFactor_(conversion_factor(genEvent_->length_unit(), HepMC::Units::LengthUnit::CM)),
45 lengthUnitConversionFactor2_(lengthUnitConversionFactor_ * lengthUnitConversionFactor_),
50 if (genEvent.vertices_begin() !=
genEvent_->vertices_end()) {
51 const HepMC::FourVector&
position = (*genEvent.vertices_begin())->
position();
63 std::unique_ptr<fastsim::Particle> particle;
66 if (!particleBuffer_.empty()) {
67 particle =
std::move(particleBuffer_.back());
68 particleBuffer_.pop_back();
72 particle = nextGenParticle();
78 if (!particleFilter_->accepts(*particle)) {
79 return nextParticle(random);
83 if (!particle->remainingProperLifeTimeIsSet() || !particle->chargeIsSet()) {
85 const HepPDT::ParticleData* particleData = particleDataTable_->particle(HepPDT::ParticleID(particle->pdgId()));
89 particle->setRemainingProperLifeTimeC(0.);
90 particle->setCharge(0.);
94 if (!particle->remainingProperLifeTimeIsSet()) {
97 double width = particleData->totalWidth().value();
98 if (width > 1.0
e-35) {
99 particle->setRemainingProperLifeTimeC(-
log(random.
flatShoot()) * 6.582119
e-25 / width / 10.);
101 particle->setStable();
106 if (!particle->chargeIsSet()) {
107 particle->setCharge(particleData->charge());
112 unsigned simTrackIndex = addSimTrack(particle.get());
113 particle->setSimTrackIndex(simTrackIndex);
120 int parentSimTrackIndex,
121 std::vector<std::unique_ptr<Particle> >& secondaries,
124 if (!particleFilter_->acceptsVtx(vertexPosition)) {
129 if (secondaries.empty()) {
134 unsigned simVertexIndex = addSimVertex(vertexPosition, parentSimTrackIndex);
138 double distMin = 99999.;
141 for (
auto& secondary : secondaries) {
143 if (secondary->getMotherDeltaR() != -1) {
144 if (secondary->getMotherDeltaR() > deltaRchargedMother_) {
146 secondary->resetMother();
148 if (secondary->getMotherDeltaR() < distMin) {
149 distMin = secondary->getMotherDeltaR();
158 for (
auto& secondary : secondaries) {
162 if (secondary->getMotherDeltaR() != -1 && idx != idxMin) {
163 secondary->resetMother();
168 secondary->setSimVertexIndex(simVertexIndex);
174 particleBuffer_.push_back(
std::move(secondary));
183 int simVertexIndex = simVertices_->size();
184 simVertices_->emplace_back(position.Vect(), position.T(), parentSimTrackIndex, simVertexIndex);
185 return simVertexIndex;
189 int simTrackIndex = simTracks_->size();
190 simTracks_->emplace_back(
192 simTracks_->back().setTrackId(simTrackIndex);
193 return simTrackIndex;
204 for (; genParticleIterator_ != genParticleEnd_; ++genParticleIterator_, ++genParticleIndex_) {
207 const HepMC::GenVertex* productionVertex = particle.production_vertex();
208 const HepMC::GenVertex* endVertex = particle.end_vertex();
211 if (!productionVertex) {
214 if (
std::abs(particle.pdg_id()) < 10 ||
std::abs(particle.pdg_id()) == 21) {
218 int exoticRelativeId = 0;
219 const bool producedWithinBeamPipe =
220 productionVertex->position().perp2() * lengthUnitConversionFactor2_ < beamPipeRadius2_;
221 if (!producedWithinBeamPipe) {
222 exoticRelativesChecker(productionVertex, exoticRelativeId, 0);
229 const bool decayedWithinBeamPipe =
230 endVertex && endVertex->position().perp2() * lengthUnitConversionFactor2_ < beamPipeRadius2_;
231 if (decayedWithinBeamPipe) {
236 if (producedWithinBeamPipe && !decayedWithinBeamPipe) {
237 exoticRelativesChecker(productionVertex, exoticRelativeId, 0);
241 std::unique_ptr<Particle> newParticle(
244 productionVertex->position().y() * lengthUnitConversionFactor_,
245 productionVertex->position().z() * lengthUnitConversionFactor_,
246 productionVertex->position().t() * timeUnitConversionFactor_),
248 particle.momentum().y() * momentumUnitConversionFactor_,
249 particle.momentum().z() * momentumUnitConversionFactor_,
250 particle.momentum().e() * momentumUnitConversionFactor_)));
251 newParticle->setGenParticleIndex(genParticleIndex_);
253 newParticle->setMotherPdgId(exoticRelativeId);
258 double labFrameLifeTime =
259 (endVertex->position().t() - productionVertex->position().t()) * timeUnitConversionFactor_;
260 newParticle->setRemainingProperLifeTimeC(labFrameLifeTime / newParticle->gamma() *
266 bool foundVtx =
false;
267 for (
const auto& simVtx : *simVertices_) {
268 if (
std::abs(simVtx.position().x() - newParticle->position().x()) < 1E-3 &&
269 std::abs(simVtx.position().y() - newParticle->position().y()) < 1E-3 &&
270 std::abs(simVtx.position().z() - newParticle->position().z()) < 1E-3) {
271 newParticle->setSimVertexIndex(simVtx.vertexId());
277 newParticle->setSimVertexIndex(addSimVertex(newParticle->position(), -1));
280 ++genParticleIterator_;
286 return std::unique_ptr<Particle>();
290 int& exoticRelativeId_,
292 if (ngendepth > 99 || exoticRelativeId_ == -1 ||
isExotic(
std::abs(exoticRelativeId_)))
295 std::vector<HepMC::GenParticle*>::const_iterator relativesIterator_ = originVertex->particles_in_const_begin();
296 std::vector<HepMC::GenParticle*>::const_iterator relativesIteratorEnd_ = originVertex->particles_in_const_end();
297 for (; relativesIterator_ != relativesIteratorEnd_; ++relativesIterator_) {
300 exoticRelativeId_ = genRelative.pdg_id();
301 if (ngendepth == 100)
302 exoticRelativeId_ = -1;
305 const HepMC::GenVertex* vertex_ = genRelative.production_vertex();
308 exoticRelativesChecker(vertex_, exoticRelativeId_, ngendepth);
static std::vector< std::string > checklist log
Implementation of a generic detector layer (base class for forward/barrel layers).
const math::XYZTLorentzVector & position() const
Return position of the particle.
double flatShoot(double xmin=0.0, double xmax=1.0) const
HepPDT::ParticleDataTable ParticleDataTable
int genParticleIndex() const
Return index of the particle in the genParticle vector.
static double constexpr speedOfLight
Speed of light [cm / ns].
int pdgId() const
Return pdgId of the particle.
const HepMC::GenEvent *const genEvent_
The GenEvent.
unsigned addSimTrack(const Particle *particle)
Add a simTrack (simTrack contains some basic info about the particle, e.g. pdgId).
constexpr std::array< uint8_t, layerIndexSize > layer
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
int simVertexIndex() const
Return index of the origin vertex.
bool isExotic(int pdgid_)
ParticleManager(const HepMC::GenEvent &genEvent, const HepPDT::ParticleDataTable &particleDataTable, double beamPipeRadius, double deltaRchargedMother, const ParticleFilter &particleFilter, std::vector< SimTrack > &simTracks, std::vector< SimVertex > &simVertices)
Constructor.
~ParticleManager()
Default destructor.
Abs< T >::type abs(const T &t)
void addSecondaries(const math::XYZTLorentzVector &vertexPosition, int motherSimTrackId, std::vector< std::unique_ptr< Particle > > &secondaries, const SimplifiedGeometry *layer=nullptr)
Adds secondaries that are produced by any of the interactions (or particle decay) to the buffer...
std::unique_ptr< Particle > nextParticle(const RandomEngineAndDistribution &random)
Returns the next particle that has to be propagated (secondary or genParticle).
void exoticRelativesChecker(const HepMC::GenVertex *originVertex, int &hasExoticAssociation, int ngendepth)
HepPDT::ParticleData ParticleData
int simTrackIndex() const
Return index of the SimTrack.
virtual bool isForward() const =0
Returns false/true depending if the object is a (non-abstract) barrel/forward layer.
std::unique_ptr< Particle > nextGenParticle()
Returns next particle from the GenEvent that has to be propagated.
double lengthUnitConversionFactor_
Convert pythia unis to cm (FastSim standard)
double timeUnitConversionFactor_
Convert pythia unis to ns (FastSim standard)
int index() const
Return index of this layer (layers are numbered according to their position in the detector)...
static int position[264][3]
const math::XYZTLorentzVector & momentum() const
Return momentum of the particle.
(Kinematic) cuts on the particles that are propagated.
Definition of a generic FastSim Particle which can be propagated through the detector (formerly Parti...
unsigned addSimVertex(const math::XYZTLorentzVector &position, int motherIndex)
Add a simVertex (simVertex contains information about the track it was produced). ...
unsigned addEndVertex(const Particle *particle)
Necessary to add an end vertex to a particle.