11#include "GaudiKernel/ISvcLocator.h"
13#include "GaudiKernel/SystemOfUnits.h"
24#include "CLHEP/Geometry/Point3D.h"
33 if (!p)
return std::vector<HepMC::GenParticlePtr>();
34 const auto& v = p->end_vertex();
35 if (!v)
return std::vector<HepMC::GenParticlePtr>();
37 std::vector<HepMC::GenParticlePtr> ret = v->particles_out();
39 std::vector<HepMC::GenParticlePtr> ret;
40 for (
auto pp=v->particles_out_const_begin();pp!=v->particles_out_const_end();++pp) ret.push_back(*pp);
42 if (ret.size()==1)
if (ret.at(0)->pdg_id()==p->pdg_id()) ret =
findChildren(ret.at(0));
62 ATH_MSG_DEBUG(
"--------------------------------------------------------");
67 return StatusCode::FAILURE;
77 if(truthStrategy->appliesToRegion(geoID)) {
85 unsigned short nStrat(0);
86 for (
unsigned short i = 0; i < curNumStrategies; ++i) {
100 return StatusCode::SUCCESS;
108 return StatusCode::SUCCESS;
116 return StatusCode::SUCCESS;
120 return StatusCode::SUCCESS;
136 const auto& position = ti.
position();
137 ATH_MSG_ERROR(
"Unable to register truth incident with unknown SimGeoID="<< geoID
138 <<
" at position z=" << position.z() <<
" r=" << position.perp());
149 <<
" will not record this TruthIncident.");
156 ATH_MSG_VERBOSE(
"Parent particle in TruthIncident does not have an id,"
157 <<
" will not record this TruthIncident.");
163 for (
unsigned short stratID=0; (!pass) && (stratID<
m_numStrategies[geoID]); stratID++) {
179 ATH_MSG_VERBOSE(
"No TruthStrategies passed and parent destroyed - create end vertex.");
185 ATH_MSG_INFO(
"TruthSvc: " << vtxType <<
" vertex + " << survival
206 ATH_MSG_WARNING (
"Attempting to record a TruthIncident for a particle which has already decayed!");
217 ATH_MSG_INFO(
"TruthSvc: " << vtxType <<
" vertex + " << survival
231 newPrimaryBC =
m_barcodeSvc->newGeneratedParticle(parentBC);
238 if(parentAfterIncident) {
246 ATH_MSG_WARNING (
"recordIncidentToMCTruth - check parentAfterIncident: " << parentAfterIncident );
249 vtxFromTI->add_particle_out( parentAfterIncident );
262 for (
unsigned short i=0; i<numSec; ++i) {
263 bool writeOutChild = isQuasiStableVertex || passWholeVertex || ti.
childPassedFilters(i);
267 int secondaryParticleBC = (isQuasiStableVertex) ?
271 ATH_MSG_WARNING(
"Unable to generate new Secondary Particle Barcode. Continuing due to 'IgnoreUndefinedBarcodes'==True");
273 ATH_MSG_ERROR(
"Unable to generate new Secondary Particle Barcode. Aborting");
280 vtxFromTI->add_particle_out( p);
296 ATH_MSG_VERBOSE(
"--------------------------------------------------------");
305 std::vector<double>
weights(1);
307 weights[0] =
static_cast<double>( primaryBC );
315 ATH_MSG_ERROR(
"Unable to write particle interaction to MC truth due to missing parent HepMC::GenParticle instance");
318 HepMC::GenEvent *mcEvent = parent->parent_event();
320 ATH_MSG_ERROR(
"Unable to write particle interaction to MC truth due to missing parent HepMC::GenEvent instance");
328 ATH_MSG_WARNING(
"Unable to generate new Truth Vertex Barcode. Continuing due to 'IgnoreUndefinedBarcodes'==True");
330 ATH_MSG_ERROR(
"Unable to generate new Truth Vertex Barcode. Aborting");
339 std::unique_ptr<HepMC::GenVertex> newVtx = std::make_unique<HepMC::GenVertex>( ti.
position(), vtxStatus,
weights );
343 if (parent->end_vertex()){
344 ATH_MSG_ERROR (
"createGVfromTI: Parent particle found with an end vertex attached. This should not happen!");
346 ATH_MSG_ERROR (
"createGVfromTI: parent->end_vertex(): " << parent->end_vertex() <<
", barcode: " <<
HepMC::barcode(parent->end_vertex()) );
353 newVtx->add_particle_in( parent );
355 ATH_MSG_VERBOSE (
"createGVfromTI End Vertex representing process: " << processCode <<
", for parent with barcode "<<parentBC<<
". Creating." );
359 mcEvent->add_vertex(newVtx);
361 newVtx->add_attribute(
"weights",std::make_shared<HepMC3::VectorDoubleAttribute>(
weights));
363 mcEvent->add_vertex( newVtx.release() );
367 return parent->end_vertex();
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
bool validAtlasRegion(AtlasDetDescr::AtlasRegion region)
Check a given AtlasRegion for its validity.
ATLAS-specific HepMC functions.
std::vector< HepMC::GenParticlePtr > findChildren(const HepMC::GenParticlePtr &p)
static const char * getName(int region)
ISF interface class for TruthIncidents.
virtual int physicsProcessCategory() const =0
Return category of the physics process represented by the truth incident (eg hadronic,...
virtual int physicsProcessCode() const =0
Return specific physics process code of the truth incident (eg ionisation, bremsstrahlung,...
virtual ISF::InteractionClass_t interactionClassification() const
The interaction classifications are described as follows: STD_VTX: interaction of a particle without ...
virtual int parentBarcode()=0
Return the barcode of the parent particle.
virtual HepMC::GenParticlePtr parentParticle()=0
Return the parent particle as a HepMC particle type (only called for particles that will enter the He...
bool childPassedFilters(unsigned short index) const
Should a particular child be written out to the GenEvent.
virtual HepMC::GenParticlePtr childParticle(unsigned short index, int bc=HepMC::UNDEFINED_ID)=0
Return the i-th child as a HepMC particle type and assign the given Barcode to the simulator particle...
unsigned short numberOfChildren() const
Return total number of child particles.
AtlasDetDescr::AtlasRegion geoID()
Return the SimGeoID corresponding to the vertex of the truth incident.
virtual int parentUniqueID()=0
Return the unique ID of the parent particle.
virtual HepMC::GenParticlePtr parentParticleAfterIncident(int newBC)=0
Return the parent particle after the TruthIncident vertex (and assign a new barcode to it)
void setPassWholeVertices(bool passWholeVertex)
Set whether this TruthIncident should pass the vertex as a whole or individual children.
virtual bool parentSurvivesIncident() const =0
Return a boolean whether or not the parent particle survives the incident.
virtual int childBarcode(unsigned short index) const =0
Return the barcode of the i-th child particle (if defined as part of the TruthIncident) otherwise ret...
virtual const HepMC::FourVector & position() const =0
Return HepMC position of the truth vertex.
StatusCode initializeTruthCollection(int largestGeneratedParticleBC=0, int largestGeneratedVertexBC=0) override
Initialize the Truth Svc at the beginning of each event.
Gaudi::Property< bool > m_passWholeVertex
ServiceHandle< Barcode::IBarcodeSvc > m_barcodeSvc
The Barcode service.
void registerTruthIncident(ITruthIncident &truthincident, bool saveAllChildren=false) const override
Register a truth incident.
unsigned short m_numStrategies[AtlasDetDescr::fNumAtlasRegions]
HepMC::GenVertexPtr createGenVertexFromTruthIncident(ITruthIncident &truthincident) const
Record and end vertex to the MC Truth for the parent particle.
Gaudi::Property< std::vector< unsigned int > > m_forceEndVtxRegionsVec
property containing AtlasRegions for which
StatusCode finalize() override
Athena algorithm's interface method finalize()
StatusCode releaseEvent() override
Finalize the Truth Svc at the end of each event.
TruthSvc(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
void recordIncidentToMCTruth(ITruthIncident &truthincident, bool passWholeVertex) const
Record the given truth incident to the MC Truth.
Gaudi::Property< bool > m_skipIfNoChildren
MCTruth steering.
ITruthStrategy ** m_geoStrategies[AtlasDetDescr::fNumAtlasRegions]
for faster access: using an internal pointer to the actual ITruthStrategy instances
ToolHandleArray< ITruthStrategy > m_truthStrategies
the truth strategies applied (as AthenaToolHandle Array)
Gaudi::Property< bool > m_ignoreUndefinedBarcodes
do/don't abort if retrieve an undefined barcode
std::array< bool, AtlasDetDescr::fNumAtlasRegions > m_forceEndVtx
attach end vertex to
StatusCode initialize() override
Athena algorithm's interface method initialize()
Gaudi::Property< bool > m_skipIfNoParentId
do not record if parentId == HepMC::UNDEFINED_ID
AtlasRegion
A simple enum of ATLAS regions and sub-detectors.
constexpr int UNDEFINED_ID
HepMC::GenVertex * GenVertexPtr
constexpr int SIM_STATUS_THRESHOLD
Constant definiting the status threshold for simulated particles, eg. can be used to separate generat...
bool suggest_barcode(T &p, int i)
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
GenParticle * GenParticlePtr
constexpr int SIM_REGENERATION_INCREMENT
Constant defining the barcode threshold for regenerated particles, i.e. particles surviving an intera...
InteractionClass_t
The interaction classifications are described as follows: STD_VTX: interaction of a particle without ...
bool isDecayed(const T &p)
Identify if the particle decayed.