20#include "GaudiKernel/SystemOfUnits.h"
28using Gaudi::Units::GeV;
42 const std::string& t,
const std::string& n,
const IInterface* p ) :
53 "truth jet minumum pt");
56 "truth jet maximum abs(eta)");
59 "jet constituent minimum pt");
62 "jet constituent photon minimum pt");
65 "list of abs(pdgID) to keep");
67 declareProperty(
"IsolRadius",
m_isolR,
68 "isolation radius for leptons and photons");
71 "isolation particle minimum pt");
73 declareProperty(
"MaxCount",
75 "maximum number of events to print");
105 return StatusCode::SUCCESS;
115 ATH_MSG_INFO(
"No TruthHard/TruthEvent pdgId mismatches");
118 return StatusCode::SUCCESS;
141 return StatusCode::FAILURE;
149 std::vector<const xAOD::TruthParticle*> hardPart;
150 std::vector<TLorentzVector> pLepGam;
152 for (
const auto* pItr : *inHardParts) {
154 hardPart.push_back(pItr);
156 int ida = pItr->absPdgId();
158 pLepGam.push_back( pItr->p4() );
165 long long int evtNum{};
170 return StatusCode::FAILURE;
172 evtNum = evt->eventNumber();
181 std::vector<bool> partMask;
182 std::vector<bool> vertMask;
183 unsigned int inPartNum = inTruthParts->size();
184 unsigned int inVertNum = inTruthVerts->size();
185 partMask.assign(inPartNum,
false);
186 vertMask.assign(inVertNum,
false);
188 ATH_MSG_DEBUG(
"Initial particles/vertices = " <<inPartNum <<
" " <<inVertNum);
197 std::vector<const xAOD::TruthParticle*> kids;
199 for (
const auto* pItr : *inTruthParts) {
203 for(
unsigned int i=0; i<hardPart.size(); ++i){
206 if( pItr->pdgId() != (hardPart[i])->pdgId() ){
210 <<
" " <<(hardPart[i])->pdgId());
218 partMask[ pItr->index() ] =
true;
222 int ida = pItr->absPdgId();
224 for(
unsigned int i=0; i<
m_keepIds.size(); ++i){
232 partMask[pItr->index()] =
true;
234 for(
int i=0; i<nkids; ++i){
237 partMask[ (kids[i])->
index() ] =
true;
239 if( v ) vertMask[ v->index() ] =
true;
244 if( !pLepGam.empty() && pItr->pt() >
m_isolPtCut ){
245 TLorentzVector pp4 = pItr->p4();
246 for(
unsigned int lep=0; lep<pLepGam.size(); ++lep){
247 double r = pp4.DeltaR( pLepGam[lep] );
250 partMask[ pItr->index() ] =
true;
266 return StatusCode::FAILURE;
269 std::vector<int> uidJetConst;
271 for(
const auto* ajet : *inJets){
273 if( std::abs(ajet->eta()) >
m_jetEtaCut )
continue;
278 for( ; aItr != aItrE; ++aItr){
296 for (
const auto* pItr : *inTruthParts) {
299 for(
unsigned int i=0; i<uidJetConst.size(); ++i){
300 if( uid == uidJetConst[i] ){
307 partMask[ pItr->index() ] =
true;
315 inTruthParts.
keep (partMask);
316 inTruthVerts.
keep (vertMask);
320 for(
unsigned int i=0; i<partMask.size(); ++i){
321 if( partMask[i] ) ++outPartNum;
324 for(
unsigned int i=0; i<vertMask.size(); ++i){
325 if( vertMask[i] ) ++outVertNum;
328 ATH_MSG_DEBUG(
"Final particles/vertices = " <<outPartNum <<
" " <<outVertNum);
331 std::cout <<
"======================================================================================" <<std::endl;
332 std::cout <<
"HardTruthThinning complete for event " <<evtNum <<std::endl;
333 std::cout <<
"Saved " <<outPartNum <<
" particles" <<std::endl;
334 std::cout <<
"Particle unique IDs = ";
335 for(
unsigned int i=0; i<partMask.size(); ++i){
336 if( partMask[i] ) std::cout <<
HepMC::uniqueID((*inTruthParts)[i]) <<
" ";
338 std::cout <<std::endl;
340 std::cout <<
"Saved " <<outVertNum <<
" vertices" <<std::endl;
341 std::cout <<
"Vertex unique IDs = ";
342 for(
unsigned int i=0; i<vertMask.size(); ++i){
343 if( vertMask[i] ) std::cout <<
HepMC::uniqueID((*inTruthVerts)[i]) <<
" ";
345 std::cout <<std::endl;
346 std::cout <<
"======================================================================================" <<std::endl;
349 return StatusCode::SUCCESS;
365 std::vector<const xAOD::TruthParticle*>& descendants ) {
367 if( ! (p->hasDecayVtx()) )
return 0;
369 if( !dvtx )
return 0;
372 const std::vector< ElementLink< xAOD::TruthParticleContainer > >& outPart =
374 for(
unsigned int k=0; k<outPart.size(); ++k){
375 if( ! (outPart[k]).
isValid() )
continue;
377 descendants.push_back(kid);
381 int nstop = descendants.size();
383 while( nstop > nstart ){
384 for(
int i=nstart; i<nstop; ++i){
391 const std::vector< ElementLink< xAOD::TruthParticleContainer > >&
393 for(
unsigned int k=0; k<outPart2.size(); ++k){
394 if( ! (outPart2[k]).
isValid() )
continue;
398 for(
unsigned int kk=0; kk<descendants.size(); ++kk){
399 if(kpp==descendants[kk]) isIn =
true;
401 if( !isIn ) descendants.push_back(kpp);
405 nstop = descendants.size();
418 std::vector<int> uidPars;
419 std::vector<int> uidKids;
421 std::cout <<
"======================================================================================\n" ;
422 std::cout <<
"xAODTruth Event " <<evnum <<
"\n";
423 std::cout <<
" Unique ID PDG Id Status px(GeV) py(GeV) pz(GeV) E(GeV) Parent: Decay\n" ;
424 std::cout <<
" -----------------------------------------------------------------------------------\n" ;
426 for (
const auto* tpItr : *truths) {
429 int id = tpItr->pdgId();
430 int stat = tpItr->status();
431 float px = tpItr->px()/
GeV;
432 float py = tpItr->py()/
GeV;
433 float pz = tpItr->pz()/
GeV;
434 float e = tpItr->e()/
GeV;
438 if( tpItr->hasProdVtx() ){
441 const std::vector< ElementLink< xAOD::TruthParticleContainer > >& pars =
443 for(
unsigned int k=0; k<pars.size(); ++k){
444 if( ! (pars[k]).
isValid() )
continue;
450 if( tpItr->hasDecayVtx() ){
453 const std::vector< ElementLink< xAOD::TruthParticleContainer > >& kids =
455 for(
unsigned int k=0; k<kids.size(); ++k){
456 if( ! (kids[k]).
isValid() )
continue;
463 std::cout << std::format(
"{:>10}{:>12}{:>8}{:>10.2f}{:>10.2f}{:>10.2f}{:>10.2f} P: ",
464 uid,
id, stat, px, py, pz, e);
465 for(
unsigned int k=0; k<uidPars.size(); ++k){
466 std::cout <<uidPars[k] <<
" ";
469 for(
unsigned int k=0; k<uidKids.size(); ++k){
470 std::cout <<uidKids[k] <<
" ";
474 std::cout <<
"======================================================================================" <<std::endl;
#define ATH_CHECK
Evaluate an expression and check for errors.
bool isValid() const
Test to see if the link can be dereferenced.
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
ATLAS-specific HepMC functions.
Handle for requesting thinning for a data object.
SG::ThinningHandleKey< xAOD::TruthVertexContainer > m_truthVertexName
virtual StatusCode initialize() override
static void printxAODTruth(long long evnum, const xAOD::TruthParticleContainer *truths)
std::atomic< int > m_errCount
HardTruthThinning(const std::string &t, const std::string &n, const IInterface *p)
SG::ThinningHandleKey< xAOD::TruthParticleContainer > m_truthParticleName
virtual StatusCode finalize() override
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
SG::ReadHandleKey< xAOD::TruthParticleContainer > m_hardParticleKey
std::atomic< int > m_evtCount
virtual ~HardTruthThinning()
virtual StatusCode doThinning(const EventContext &ctx) const override
SG::ReadHandleKey< xAOD::JetContainer > m_truthJetsKey
StringProperty m_streamName
std::vector< int > m_keepIds
static int getDescendants(const xAOD::TruthParticle *p, std::vector< const xAOD::TruthParticle * > &d)
virtual bool isValid() override final
Can the handle be successfully dereferenced?
void keep(size_t ndx)
Mark that index ndx in the container should be kept (not thinned away).
Handle for requesting thinning for a data object.
Class providing the definition of the 4-vector interface.
A vector of jet constituents at the scale used during jet finding.
iterator begin() const
iterator on the first constituent
iterator end() const
iterator after the last constituent
4-vector of jet constituent at the scale used during jet finding.
const IParticle * rawConstituent() const
Access the real underlying IParticle.
const TruthVertex_v1 * decayVtx() const
The decay vertex of this particle.
bool hasDecayVtx() const
Check for a decay vertex on this particle.
virtual double pt() const override final
The transverse momentum ( ) of the particle.
const TPLinks_t & outgoingParticleLinks() const
Get all the outgoing particles.
size_t nOutgoingParticles() const
Get the number of outgoing particles.
const TPLinks_t & incomingParticleLinks() const
Get all the incoming particles.
bool is_simulation_vertex(const T &v)
Method to establish if the vertex was created during simulation (TODO migrate to be based on status).
bool is_simulation_particle(const T &p)
Method to establish if a particle (or barcode) was created during the simulation (TODO update to be s...
bool isPhoton(const T &p)
bool isElectron(const T &p)
bool isStable(const T &p)
Identify if the particle is stable, i.e. has not decayed.
TruthVertex_v1 TruthVertex
Typedef to implementation.
TruthParticle_v1 TruthParticle
Typedef to implementation.
TruthParticleContainer_v1 TruthParticleContainer
Declare the latest version of the truth particle container.