diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthClassificationDecorator.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthClassificationDecorator.cxx index fd60c91856d9327d007bf0694a7b5659b48a33e0..035be1d8d349d400bee5001f5da015b0cbe946ce 100644 --- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthClassificationDecorator.cxx +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthClassificationDecorator.cxx @@ -73,22 +73,30 @@ StatusCode DerivationFramework::TruthClassificationDecorator::addBranches() cons SG::AuxElement::Decorator< unsigned int > typeDecorator("classifierParticleType"); SG::AuxElement::Decorator< unsigned int > outcomeDecorator("classifierParticleOutCome"); + SG::AuxElement::Decorator< unsigned int > classificationDecorator("Classification"); + for (unsigned int i=0; i<nParticles; ++i) { #ifdef MCTRUTHCLASSIFIER_CONST IMCTruthClassifier::Info info; std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> classification = m_classifier->particleTruthClassifier((*importedTruthParticles)[i], &info); - unsigned int particleOutCome = info.particleOutCome; + unsigned int particleOutCome = info.particleOutCome; + + unsigned int result = (unsigned int)m_classifier->classify((*importedTruthParticles)[i]); #else std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> classification = m_classifier->particleTruthClassifier((*importedTruthParticles)[i]); unsigned int particleOutCome = m_classifier->getParticleOutCome(); + + unsigned int result = (unsigned int)m_classifier->classify((*importedTruthParticles)[i]); #endif unsigned int particleType = classification.first; unsigned int particleOrigin = classification.second; typeDecorator(*((*importedTruthParticles)[i])) = particleType; originDecorator(*((*importedTruthParticles)[i])) = particleOrigin; outcomeDecorator(*((*importedTruthParticles)[i])) = particleOutCome; + + classificationDecorator(*((*importedTruthParticles)[i])) = result; } return StatusCode::SUCCESS; diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h index 4d3032486cdf3e71dbc769be53c7f52b387b076e..e9f6e0413a0ec8940a517966d5d3c29089055239 100644 --- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h +++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/IMCTruthClassifier.h @@ -110,10 +110,18 @@ public: virtual const xAOD::TruthParticle* isHadronFromB(const xAOD::TruthParticle*) const = 0; + /// \brief main function used in \ref MCTruthClassifier returning the value from defOrigofParticle to \ref TruthClassificationDecorator + virtual unsigned int classify(const xAOD::TruthParticle *) const = 0; + + /// \brief function used in \ref MCTruthClassifier classifying truth particles with HepMC status 1 & 2 + virtual unsigned int defOrigOfParticle(const xAOD::TruthParticle*) const = 0; + + #ifndef XAOD_ANALYSIS /*This can not run in Analysis Base*/ virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier( HepMC::ConstGenParticlePtr, Info* info = nullptr) const = 0; + #endif // #ifndef GENERATIONBASE /*These can not run in Generation only release*/ @@ -136,6 +144,7 @@ public: particleTruthClassifier(const xAOD::Jet*, bool DR, Info* info = nullptr) const = 0; virtual const xAOD::TruthParticle* getGenPart(const xAOD::TrackParticle*, Info* info = nullptr) const = 0; + #endif }; diff --git a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h index e62e9a8c7dcf943bff11fd55a9b10ba25703b1fa..81d0f257f64c16eaea0129c3becde2857578a5e3 100644 --- a/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h +++ b/PhysicsAnalysis/MCTruthClassifier/MCTruthClassifier/MCTruthClassifier.h @@ -83,6 +83,29 @@ public: virtual const xAOD::TruthParticle* isHadronFromB(const xAOD::TruthParticle*) const override; const xAOD::TruthParticle* getMother(const xAOD::TruthParticle*) const; + virtual unsigned int classify(const xAOD::TruthParticle *) const override; + + enum MCTC_bits { HadTau=0, Tau, hadron, frombsm, uncat, isbsm, isgeant, stable, totalBits }; + + /// \brief These helper functions return the value that the respective bit is set to in \ref MCTruthClassifier + static unsigned int isGeant(const unsigned int classify) { return std::bitset<MCTC_bits::totalBits> (classify).test(MCTC_bits::isgeant); } + static unsigned int isBSM(const unsigned int classify) { return std::bitset<MCTC_bits::totalBits> (classify).test(MCTC_bits::isbsm); } + static unsigned int fromBSM(const unsigned int classify) { return std::bitset<MCTC_bits::totalBits> (classify).test(MCTC_bits::frombsm); } + + /*! \brief This helper function returns the value -1 by checking the bit set in \ref MCTruthClassifier. + * It returns the value -1 if uncategorised, 0 if non-prompt, 1 if prompt + * It also checks for prompt taus + */ + + static int isPrompt(const unsigned int classify, bool allow_prompt_tau_decays = true) { + std::bitset<MCTC_bits::totalBits> res(classify); + if (res.test(MCTC_bits::uncat)) return -1; + bool fromPromptTau = res.test(MCTC_bits::Tau) && !res.test(MCTC_bits::HadTau); + if (fromPromptTau) return int(allow_prompt_tau_decays); + return !res.test(MCTC_bits::hadron); + } + + #ifndef XAOD_ANALYSIS /*This can not run in Analysis Base*/ virtual std::pair<MCTruthPartClassifier::ParticleType, MCTruthPartClassifier::ParticleOrigin> particleTruthClassifier( HepMC::ConstGenParticlePtr, @@ -110,6 +133,7 @@ public: particleTruthClassifier(const xAOD::Jet*, bool DR, Info* info = nullptr) const override; virtual const xAOD::TruthParticle* getGenPart(const xAOD::TrackParticle*, Info* info = nullptr) const override; + #endif private: @@ -150,6 +174,9 @@ private: const xAOD::TruthParticle*, bool& isPrompt, Info* info) const; + //MCTruthPartClassifier::ParticleOrigin + virtual unsigned int defOrigOfParticle(const xAOD::TruthParticle*) const override; + // MCTruthPartClassifier::ParticleOrigin defHadronType(long); static bool isHadron(const xAOD::TruthParticle*); @@ -232,6 +259,7 @@ this, "xAODTruthLinks", "ReadHandleKey for xAODTruthParticleLinkVector" }; + #endif #ifndef GENERATIONBASE /*Disable when no recostruction packages are expected*/ float m_deltaRMatchCut; diff --git a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx index eaf341374baf40c4f22137d2dd6b7f4f19085ebf..aef379a04271e9cee96d3e175243d9bd444381ce 100644 --- a/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx +++ b/PhysicsAnalysis/MCTruthClassifier/Root/MCTruthClassifierGen.cxx @@ -312,6 +312,102 @@ MCTruthClassifier::findAllJetMothers(const xAOD::TruthParticle* thePart, } } } + +//-------------------------------------------------------------------------------------- +unsigned int MCTruthClassifier::classify(const xAOD::TruthParticle *thePart) const { +//-------------------------------------------------------------------------------------- + + ATH_MSG_DEBUG( "Executing classify" ); + + if(!thePart){ATH_MSG_WARNING( "Passed a nullptr" ); return 0;} + + return defOrigOfParticle(thePart); +} + +//------------------------------------------------------------------------------- +unsigned int MCTruthClassifier::defOrigOfParticle(const xAOD::TruthParticle *thePart) const { +//------------------------------------------------------------------------------- + + ATH_MSG_DEBUG( "Executing DefOrigOfParticle " ); + + int iParticlePDG = std::abs(thePart->pdgId()); + int iParticleStat = std::abs(thePart->status()); + + unsigned int outputvalue; + + bool isStable=0; bool fromhad = 0; bool uncat = 0; bool isHadTau=0; bool mybeam=0; bool fromTau=0; bool fromBSM=0; bool isGeant=0; bool isBSM=0; + + if(iParticleStat == 1 || iParticleStat == 2){ + isStable = 1; + } + if(isStable == 1){ + const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():0; + if( partOriVert!=0 ) { + for (unsigned int ipIn=0; ipIn<partOriVert->nIncomingParticles(); ++ipIn) { + const xAOD::TruthParticle* theMother=partOriVert->incomingParticle(ipIn); + if(!theMother) continue; + + if(std::abs(thePart->barcode()) >= m_barcodeG4Shift){ + isGeant = 1; break; + } + if(MC::PID::isBSM(iParticlePDG) && abs(iParticleStat) == 1){ + isBSM=1; + } + + while (mybeam==0){ + const xAOD::TruthVertex* partOriVert=thePart->hasProdVtx() ? thePart->prodVtx():0; + if( partOriVert!=0 ) { + const xAOD::TruthParticle* theMother=partOriVert->incomingParticle(0); + if(!theMother) continue; + + if(std::abs(theMother->pdgId()) == 2212){ + mybeam = 1; break; + } + if(MC::PID::isTau(theMother->pdgId()) && theMother->status() == 2 ){ + fromTau = 1; isHadTau =0; + } + if(isHadron(theMother) == true && theMother->status() == 2 ) { + fromhad = 1; + if(fromTau == 1){ + isHadTau = 1; + } + } + + if(MC::PID::isBSM(theMother->pdgId())){ + fromBSM = 1; + } + thePart = theMother; + } + else{break;} + } + } + } + else{ + uncat=1; + } + std::bitset<MCTC_bits::totalBits> status; + + status[MCTC_bits::stable] = isStable; + status[MCTC_bits::isgeant] = isGeant; + status[MCTC_bits::isbsm] = isBSM; + status[MCTC_bits::uncat] = uncat; + status[MCTC_bits::frombsm] = fromBSM; + status[MCTC_bits::hadron] = fromhad; + status[MCTC_bits::Tau] = fromTau; + status[MCTC_bits::HadTau] = isHadTau; + + outputvalue = static_cast<unsigned int>(status.to_ulong()); + } + else { + std::bitset<MCTC_bits::totalBits> unclass; + unclass[MCTC_bits::stable] = isStable; + + outputvalue = static_cast<unsigned int>(unclass.to_ulong()); + } + + return outputvalue; +} + //------------------------------------------------------------------------------- ParticleType MCTruthClassifier::defTypeOfElectron(ParticleOrigin EleOrig, bool isPrompt) const