From fce2d4ab2021023a1ac1638f8bcedc8a6a84bde8 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Feb 2026 11:58:08 +0100 Subject: [PATCH 01/13] support index-based selection --- analyzers/dataframe/FCCAnalyses/MCParticle.h | 42 +++++--- .../FCCAnalyses/ReconstructedParticle2MC.h | 35 +++++-- analyzers/dataframe/FCCAnalyses/Utils.h | 30 +++++- .../dataframe/FCCAnalyses/VertexingUtils.h | 17 +++- analyzers/dataframe/src/MCParticle.cc | 97 ++++++++++++------- .../dataframe/src/ReconstructedParticle2MC.cc | 61 ++++++++---- analyzers/dataframe/src/VertexingUtils.cc | 45 ++++++++- 7 files changed, 255 insertions(+), 72 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index 93dcdf2e296..43f6d005497 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -4,6 +4,7 @@ #include #include +#include #include "ROOT/RVec.hxx" #include "TLorentzVector.h" @@ -30,26 +31,41 @@ namespace MCParticle{ bool operator() (ROOT::VecOps::RVec in); }; + /// @brief Helper struct to select entries matching a certain predicate. + /// Supports two signatures - either a list of candidates is passed and a list of accepted candidates returned, + /// Or a list of indices in a vector of candidates is passed and a list of accepted indices returned. + /// The latter is more compatible with index-based selection logic. + struct selByPredicate{ + selByPredicate(std::function thePredicate):m_predicate(thePredicate){} + std::function m_predicate; + ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & in); + ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in); + ROOT::VecOps::RVec> operator() (const ROOT::VecOps::RVec> & indices, const ROOT::VecOps::RVec & in); + }; + /// select MCParticles with transverse momentum greater than a minimum value [GeV] - struct sel_pt { + struct sel_pt : selByPredicate{ sel_pt(float arg_min_pt); - float m_min_pt = 20; //> transverse momentum threshold [GeV] - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec in); + }; + + /// select MCParticles with absolute pseudorapidity less than a max value + struct sel_eta : selByPredicate { + sel_eta(float arg_max_eta); }; /// select MCParticles with their status - struct sel_genStatus { + struct sel_genStatus : selByPredicate { sel_genStatus(int arg_status); - int m_status = 1; //> Generator status - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec in); }; /// select MCParticles with their PDG id - struct sel_pdgID { + struct sel_pdgID : selByPredicate { sel_pdgID(int arg_pdg, bool arg_chargeconjugate); - int m_pdg = 13; - bool m_chargeconjugate = true; - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec in); + }; + + /// select MCParticles with a non-zero charge + struct sel_charged : selByPredicate { + sel_charged(); }; /// get MC history tree for a given MCParticle index @@ -116,7 +132,6 @@ namespace MCParticle{ ROOT::VecOps::RVec in , ROOT::VecOps::RVec ind); - /// return the parent index of a given list of MC particles ROOT::VecOps::RVec get_parentid(ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec mc, ROOT::VecOps::RVec parents); @@ -210,6 +225,11 @@ namespace MCParticle{ /// return the list of stable particles from the decay of a mother particle, looking at the full decay chain recursively. i is the mother index in the Particle block std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + /// return the list of stable particles from the decays of a mother particle, looking at the full decay chain recursively. + /// i is the list of mother indices to process in the Particle block. + /// Will return a vector of vectors - each vector is the set of children for one of the mothers in the input vector + ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays( ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + /// return the list of particles from the decay of a mother particle. i is the mother index in the Particle block. std::vector get_list_of_particles_from_decay( int i, ROOT::VecOps::RVec in, diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h index 61845d91999..149e2132ba8 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h @@ -125,12 +125,35 @@ namespace ReconstructedParticle2MC{ ROOT::VecOps::RVec reco, ROOT::VecOps::RVec mc) ; - /// select ReconstructedParticles matched to the (stable) MC particles whose indices are passed in a list - ROOT::VecOps::RVec selRP_matched_to_list( ROOT::VecOps::RVec mcParticles_indices, - ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) ; + /// select ReconstructedParticles matched to the MC particles whose indices are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations + /// @param reco: full reco particle list (ReconstructedParticles) + /// @param mc: full mc particle list (Particles) + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a dummy particle will be inserted. If 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & reco, + const ROOT::VecOps::RVec & mc, + bool require_stable = true) ; + /// select indices of ReconstructedParticles matched to the MC particles whose indices are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations + /// @param mc: full mc particle list (Particles) + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a "-1" entry will be inserted. If 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & mc, + bool require_stable = true + ) ; /// return the index of the MC particle that is associated to a given track (via the track-reco association) int getTrack2MC_index ( int track_index, diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index 78c5616d0d7..5840ce29c27 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -2,12 +2,40 @@ #define UTILS_ANALYZERS_H #include +#include namespace FCCAnalyses { namespace Utils { template inline auto getsize( T& vec){ return vec.size();}; - template inline ROOT::VecOps::RVec > as_vector(const ROOT::VecOps::RVec& in){return ROOT::VecOps::RVec >(1, in);}; + template inline ROOT::VecOps::RVec > as_vector(const ROOT::VecOps::RVec& in){return ROOT::VecOps::RVec >(1, in);}; + template inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec indices(in.size()); + std::iota(indices.begin(),indices.end(), 0); + return indices; + }; + /// @brief count the number of valid (>=0, < size of collection) indices in an index list + /// @param in: index list + /// @param ref: particle vector to which the indices refer. + /// @return integer count of valid indices + template inline int count_valid_indices(const ROOT::VecOps::RVec & in, + const ROOT::VecOps::RVec & ref){ + int maxSize = ref.size(); + return std::count_if(in.begin(),in.end(),[maxSize](const int & i){return (i >=0 && i < maxSize);}); + }; + + // @brief for a given list of indices, returns a list of particle (copies) + /// @param idx : Indices of desired particles within the full set ("in") + /// @param in : Full set of particles + /// @return A vector of particles with the desired indices. + template inline ROOT::VecOps::RVec sel_byIndex( const ROOT::VecOps::RVec & idx, const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec found; + for (int index : idx){ + if (index < 0 || index >= in.size()) continue; + found.push_back(in.at(index)); + } + return found; + } } } diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index 96721fde586..f913f0ea0e5 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -107,7 +107,22 @@ namespace VertexingUtils{ /// Retrieve the indices of the tracks fitted to that vertex, but now in the collection of RecoParticles ROOT::VecOps::RVec get_VertexRecoParticlesInd( FCCAnalysesVertex TheVertex, const ROOT::VecOps::RVec& reco ); - + + /// Retrieve the indices of the tracks fitted to a vector of vertices, but now in the collection of RecoParticles + ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec& reco ); + + /// @brief Find (by index) a vertex that is made of reco particles from a passed list. + /// @param vertices: List of possible vertices to match + /// @param recoParticleIndices: Indices of the reco particles to find in the vertex + /// @param reco: list of all reco particles (ReconstructedParticles) + /// @param require_all: If set, require one vertex to contain all recoParticleIndices (no 'missed' tracks). Else only require that all tracks in the vertex come from the vector (but allow for unused tracks) + /// @return: Index within the list of the (first) vertex fulfilling the criteria. If none are found, return -1 + int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, + const ROOT::VecOps::RVec & recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all = false); + /// Return the number of tracks in a given track collection int get_nTracks(ROOT::VecOps::RVec tracks); diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 009d0d4c255..0f6832066fe 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -8,35 +8,66 @@ namespace FCCAnalyses{ namespace MCParticle{ -sel_genStatus::sel_genStatus(int arg_status) : m_status(arg_status) {}; -ROOT::VecOps::RVec sel_genStatus::operator() (ROOT::VecOps::RVec in) { + +ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec & in){ ROOT::VecOps::RVec result; result.reserve(in.size()); - for (size_t i = 0; i < in.size(); ++i) { - auto & p = in[i]; - if (p.generatorStatus == m_status) { - result.emplace_back(p); - } - } - return result; + for (auto & p : in) { + if (m_predicate(p)) result.emplace_back(p); + } + return result; } -sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) : m_pdg(arg_pdg), m_chargeconjugate( arg_chargeconjugate ) {}; -ROOT::VecOps::RVec sel_pdgID::operator() (ROOT::VecOps::RVec in) { - ROOT::VecOps::RVec result; +ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec& indices, const ROOT::VecOps::RVec &in){ + ROOT::VecOps::RVec result; result.reserve(in.size()); - for (size_t i = 0; i < in.size(); ++i) { - auto & p = in[i]; - if ( m_chargeconjugate ) { - if ( std::abs( p.PDG ) == std::abs( m_pdg) ) result.emplace_back(p); - } - else { - if ( p.PDG == m_pdg ) result.emplace_back(p); - } + for (int index : indices) { + if (index < 0 || index >= in.size()) continue; + if (m_predicate(in[index])) result.emplace_back(index); + } + return result; +} +ROOT::VecOps::RVec> selByPredicate::operator() (const ROOT::VecOps::RVec>& setsOfIndices, const ROOT::VecOps::RVec &in){ + ROOT::VecOps::RVec> result(setsOfIndices.size()); + for (int elem = 0; elem < setsOfIndices.size(); ++elem){ + result[elem] = this->operator()(setsOfIndices[elem], in); } - return result; + return result; +} + +sel_pt::sel_pt(float arg_min_pt) : + selByPredicate([arg_min_pt](const edm4hep::MCParticleData & p)->bool{ + return (p.momentum.x*p.momentum.x + p.momentum.y*p.momentum.y > arg_min_pt*arg_min_pt); + }){ +} + +sel_eta::sel_eta(float arg_max_eta) : + selByPredicate([arg_max_eta](const edm4hep::MCParticleData & p)->bool{ + ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); + return std::abs(vec.Eta()) < std::abs(arg_max_eta); + }){ } +sel_genStatus::sel_genStatus(int arg_status): + selByPredicate([arg_status](const edm4hep::MCParticleData & p)->bool{ + return p.generatorStatus == arg_status; + }){ +} + +sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate): + selByPredicate([arg_pdg, arg_chargeconjugate](const edm4hep::MCParticleData & p)->bool{ + if (arg_chargeconjugate) return std::abs( p.PDG ) == std::abs( arg_pdg); + else return p.PDG == arg_pdg; + }){ +} + +sel_charged::sel_charged(): + selByPredicate([](const edm4hep::MCParticleData & p)->bool{ + // try to avoid floating comp to zero + // and thank you for the person who gave some neutral particles a -999 charge! + return std::abs(p.charge) > 1e-6 && p.charge != -999; + }){ +} get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf){m_mother=arg_mother; m_daughters=arg_daughters; m_inf=arg_inf;}; @@ -59,19 +90,6 @@ bool get_decay::operator() (ROOT::VecOps::RVec in, ROO return result; } -sel_pt::sel_pt(float arg_min_pt) : m_min_pt(arg_min_pt) {}; -ROOT::VecOps::RVec sel_pt::operator() (ROOT::VecOps::RVec in) { - ROOT::VecOps::RVec result; - result.reserve(in.size()); - for (size_t i = 0; i < in.size(); ++i) { - auto & p = in[i]; - if (std::sqrt(std::pow(p.momentum.x,2) + std::pow(p.momentum.y,2)) > m_min_pt) { - result.emplace_back(p); - } - } - return result; -} - filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs){m_pdgid = arg_pdgid; m_abs = arg_abs;}; bool filter_pdgID::operator() (ROOT::VecOps::RVec in) { @@ -540,6 +558,16 @@ std::vector get_list_of_particles_from_decay(int i, ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays(ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { + + ROOT::VecOps::RVec> ret; + ret.reserve(i.size()); + for (int ix : i){ + ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); + } + return ret; +} + // ---------------------------------------------------------------------------------------------------------------------------------- @@ -560,6 +588,7 @@ std::vector list_of_particles_from_decay(int i, ROOT::VecOps::RVec get_indices_MotherByIndex ( int imother, diff --git a/analyzers/dataframe/src/ReconstructedParticle2MC.cc b/analyzers/dataframe/src/ReconstructedParticle2MC.cc index 45abccdd4e8..244b716785c 100644 --- a/analyzers/dataframe/src/ReconstructedParticle2MC.cc +++ b/analyzers/dataframe/src/ReconstructedParticle2MC.cc @@ -337,26 +337,23 @@ selRP_ChargedHadrons (ROOT::VecOps::RVec recind, // ------------------------------------------------------------------------------------------------- -// -- select RecoParticles associated with a list of MC particles (passed by their index in the Particle block) - -ROOT::VecOps::RVec -selRP_matched_to_list( ROOT::VecOps::RVec mcParticles_indices, - ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { - - ROOT::VecOps::RVec results; - - edm4hep::ReconstructedParticleData dummy; - dummy.energy = -9999; - dummy.tracks_begin = -9999 ; +// -- select indices of RecoParticles associated with a list of MC particles (passed by their index in the Particle block) +ROOT::VecOps::RVec +selRP_indices_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & mc, + bool require_stable) { + + ROOT::VecOps::RVec results; for ( auto & idx: mcParticles_indices ) { // exclude unstable particles - e.g. the list may contain the index of // the mother - if ( mc.at(idx).generatorStatus != 1 ) continue ; + // MG: Should we push_back -1 here for consistency? + if (require_stable && mc.at(idx).generatorStatus != 1 ) continue ; // is this MC particle associated with a Reco particle : bool found = false; @@ -365,17 +362,45 @@ selRP_matched_to_list( ROOT::VecOps::RVec mcParticles_indices, int mc_idx = mcind.at(i); if ( mc_idx == idx ) { found = true; - results.push_back( reco.at( reco_idx ) ); + results.push_back( reco_idx ); break; } } // no Reco particle has been found for idx: add a dummy particle such that // one preserves the mapping with the input list - if ( ! found) results.push_back( dummy ); + // Note: This is inconsistent, the mapping will be + // lost whenever there is an unstable particle in the input list. + // Will keep current behaviour for backward compatibility... + if ( ! found) results.push_back( -1 ); + } // loop over the indices in the list + return results; - } // loop over the indices in the list +} +// -- select RecoParticles associated with a list of MC particles (passed by their index in the Particle block) + +ROOT::VecOps::RVec +selRP_matched_to_list( const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & reco, + const ROOT::VecOps::RVec & mc, + bool require_stable) { + edm4hep::ReconstructedParticleData dummy; + dummy.energy = -9999; + dummy.tracks_begin = -9999 ; + + ROOT::VecOps::RVec results; + ROOT::VecOps::RVec indices = selRP_indices_matched_to_list(mcParticles_indices, + recind, + mcind, + mc, + require_stable); + for (int reco_idx : indices){ + if (reco_idx < 0) results.push_back( dummy ); + else results.push_back( reco.at( reco_idx ) ); + } return results; } diff --git a/analyzers/dataframe/src/VertexingUtils.cc b/analyzers/dataframe/src/VertexingUtils.cc index f60ccfba7e9..80520b256c7 100644 --- a/analyzers/dataframe/src/VertexingUtils.cc +++ b/analyzers/dataframe/src/VertexingUtils.cc @@ -1,6 +1,6 @@ #include "FCCAnalyses/VertexingUtils.h" #include "FCCAnalyses/VertexFitterSimple.h" - +#include #include "TrkUtil.h" // from delphes namespace FCCAnalyses { @@ -369,6 +369,49 @@ ROOT::VecOps::RVec get_VertexRecoParticlesInd( return result; } +ROOT::VecOps::RVec get_VerticesRecoParticlesInd( + ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec &reco) { + + ROOT::VecOps::RVec result; + for (int j = 0; j < vertices.size(); ++j){ + ROOT::VecOps::RVec indices_tracks = vertices[j].reco_ind; + for (int i = 0; i < indices_tracks.size(); i++) { + int tk_index = indices_tracks[i]; + for (int j = 0; j < reco.size(); j++) { + auto &p = reco[j]; + if (p.tracks_begin == p.tracks_end) + continue; + if (p.tracks_begin == tk_index) { + result.push_back(j); + break; + } + } + } + } + + return result; +} + +int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, + const ROOT::VecOps::RVec & recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all){ + std::set indicesWeWant; + indicesWeWant.insert(recoParticleIndices.begin(),recoParticleIndices.end()); + // correct for "-1" representing missed tracks in the recoParticleIndices + int correctMissing = indicesWeWant.count(-1); + for (int iVX = 0; iVX < vertices.size(); ++iVX){ + auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX],reco); + int nFound = std::count_if(vxParticleIndices.begin(), vxParticleIndices.end(),[&](int recoIndex){ + return indicesWeWant.count(recoIndex); + }) ; + if (require_all && nFound == indicesWeWant.size() - correctMissing || nFound == vxParticleIndices.size()) return iVX; + } + return -1; +} + + TVectorD ParToACTS(TVectorD Par) { TVectorD pACTS(6); // Return vector From 858326098deaae43c1364c8610a7bcb39e835f85 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Feb 2026 15:21:02 +0100 Subject: [PATCH 02/13] fix a bug --- analyzers/dataframe/src/MCParticle.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 0f6832066fe..025cb050042 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -520,6 +520,8 @@ std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::R //for (int idaughter = d1; idaughter <= d2; idaughter++) { for (int id = db; id < de; id++) { int idaughter = ind[ id ]; + // prevent endless loop in case of looping MC record + if (idaughter == i) continue; std::vector rr = get_list_of_stable_particles_from_decay( idaughter, in, ind) ; res.insert( res.end(), rr.begin(), rr.end() ); } From a1413ca51be018a217093c72b862a0bf32188900 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Feb 2026 15:22:02 +0100 Subject: [PATCH 03/13] add one more helper --- analyzers/dataframe/FCCAnalyses/Utils.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index 5840ce29c27..70f305faa87 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -36,6 +36,17 @@ namespace FCCAnalyses { } return found; } + // @brief merge (concatenate) two collections of arbitrary content + /// @param x : first collection - entries will be copied in-order + /// @param y : second collection - entries will be copied in-order after the last element of the first + /// @return A combined collection of size (x.size()+y.size()), containing the content of x followed by that of y + template inline ROOT::VecOps::RVec merge( const ROOT::VecOps::RVec & x, const ROOT::VecOps::RVec & y){ + ROOT::VecOps::RVec merged; + merged.reserve(x.size()+y.size()); + merged.insert(merged.end(), x.begin(), x.end()); + merged.insert(merged.end(), y.begin(), y.end()); + return merged; + } } } From 24fc8512abfc363a8162d3cea8ecea70124f068f Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Feb 2026 15:24:12 +0100 Subject: [PATCH 04/13] clang_format --- analyzers/dataframe/FCCAnalyses/MCParticle.h | 560 ++++++----- .../FCCAnalyses/ReconstructedParticle2MC.h | 321 +++--- analyzers/dataframe/FCCAnalyses/Utils.h | 102 +- .../dataframe/FCCAnalyses/VertexingUtils.h | 682 +++++++------ analyzers/dataframe/src/MCParticle.cc | 942 ++++++++++-------- .../dataframe/src/ReconstructedParticle2MC.cc | 514 +++++----- analyzers/dataframe/src/VertexingUtils.cc | 44 +- 7 files changed, 1736 insertions(+), 1429 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index 43f6d005497..ef24b04c630 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -1,10 +1,10 @@ -#ifndef MCPARTICLE_ANALYZERS_H -#define MCPARTICLE_ANALYZERS_H +#ifndef MCPARTICLE_ANALYZERS_H +#define MCPARTICLE_ANALYZERS_H #include -#include #include +#include #include "ROOT/RVec.hxx" #include "TLorentzVector.h" @@ -13,7 +13,7 @@ #include "edm4hep/Vector3d.h" #include "edm4hep/Vector3f.h" -namespace FCCAnalyses{ +namespace FCCAnalyses { /** * Analyzers operating on/with Monte Carlo particles. @@ -21,246 +21,314 @@ namespace FCCAnalyses{ * This represents a set functions and utilities to access and perform * operations on the MCParticle collection. */ -namespace MCParticle{ - - /// Filter events based on a MCParticles PDGID - struct filter_pdgID { - filter_pdgID(int arg_pdgid, bool arg_abs); - int m_pdgid; //> Generator pdgid - bool m_abs;//> Use absolute value for pdgig - bool operator() (ROOT::VecOps::RVec in); - }; - - /// @brief Helper struct to select entries matching a certain predicate. - /// Supports two signatures - either a list of candidates is passed and a list of accepted candidates returned, - /// Or a list of indices in a vector of candidates is passed and a list of accepted indices returned. - /// The latter is more compatible with index-based selection logic. - struct selByPredicate{ - selByPredicate(std::function thePredicate):m_predicate(thePredicate){} - std::function m_predicate; - ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & in); - ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in); - ROOT::VecOps::RVec> operator() (const ROOT::VecOps::RVec> & indices, const ROOT::VecOps::RVec & in); - }; - - /// select MCParticles with transverse momentum greater than a minimum value [GeV] - struct sel_pt : selByPredicate{ - sel_pt(float arg_min_pt); - }; - - /// select MCParticles with absolute pseudorapidity less than a max value - struct sel_eta : selByPredicate { - sel_eta(float arg_max_eta); - }; - - /// select MCParticles with their status - struct sel_genStatus : selByPredicate { - sel_genStatus(int arg_status); - }; - - /// select MCParticles with their PDG id - struct sel_pdgID : selByPredicate { - sel_pdgID(int arg_pdg, bool arg_chargeconjugate); - }; - - /// select MCParticles with a non-zero charge - struct sel_charged : selByPredicate { - sel_charged(); - }; - - /// get MC history tree for a given MCParticle index - struct get_tree{ - get_tree(int arg_index); - int m_index; //> MC Particle index to build the tree from - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind); - }; - - /// get the decay of a given particle - struct get_decay { - get_decay(int arg_mother, int arg_daughters, bool arg_inf); - int m_mother = 0; //> mother pdg id - int m_daughters = 0;//> daughters pdg id - bool m_inf = false;//> boolean to check if the pdgid is below a value rather than equal - bool operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind); - }; - - /// return the event primary vertex (mm) - struct get_EventPrimaryVertex { - get_EventPrimaryVertex( int arg_genstatus ); - int m_genstatus = 21; // Pythia8 code of the incoming particles of the hardest subprocess - TVector3 operator() (ROOT::VecOps::RVec in); - }; - - /// return the event primary vertex position and time (mm) - struct get_EventPrimaryVertexP4 { - get_EventPrimaryVertexP4(); - int m_genstatus = 21; // Pythia8 code of the incoming particles of the hardest subprocess - TLorentzVector operator() (ROOT::VecOps::RVec in); - }; - - - /// return a list of indices that correspond to a given MC decay. The list contains the index of the mother, followed by the indices of the daughters, in the order specified. If m_inclusiveDecay is true, the list of daughters is the minimum required for the mother's decay (otherwise, the list is the exact daughters required for the mother's decay). In case there are several such decays in the event, keep only the first one. - struct get_indices{ - get_indices( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugateMother, bool chargeConjugateDaughters, bool inclusiveDecay ) ; - int m_pdg_mother; - std::vector m_pdg_daughters; - bool m_stableDaughters; - bool m_chargeConjugateMother; - bool m_chargeConjugateDaughters; - bool m_inclusiveDecay; - ROOT::VecOps::RVec operator() ( ROOT::VecOps::RVec in , ROOT::VecOps::RVec ind); - }; - - /// A shorthand for get_indices, with m_chargeConjugateDaughters=false, inclusiveDecay=false - struct get_indices_ExclusiveDecay: get_indices{ - get_indices_ExclusiveDecay( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugate ) ; - }; - - /// return a list of indices that correspond to a given MC decay - ROOT::VecOps::RVec get_indices_MotherByIndex( int imother, - std::vector m_pdg_daughters, - bool m_stableDaughters, - bool m_chargeConjugateDaughters, - bool m_inclusiveDecay, - ROOT::VecOps::RVec in , - ROOT::VecOps::RVec ind); - - /// a shorthand for get_indices_MotherByIndex with m_chargeConjugateDaughters=false, m_inclusiveDecay =false - ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( int imother, - std::vector m_pdg_daughters, - bool m_stableDaughters, - ROOT::VecOps::RVec in , - ROOT::VecOps::RVec ind); - - /// return the parent index of a given list of MC particles - ROOT::VecOps::RVec get_parentid(ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec mc, ROOT::VecOps::RVec parents); - - /// return the time of the input MCParticles - ROOT::VecOps::RVec get_time(ROOT::VecOps::RVec in); - - /// return the PDG of the input MCParticles - ROOT::VecOps::RVec get_pdg(ROOT::VecOps::RVec in); - - /// return the generator status of the input MCParticles - ROOT::VecOps::RVec get_genStatus(ROOT::VecOps::RVec in); - - /// return the simulation status of the input MCParticles - ROOT::VecOps::RVec get_simStatus(ROOT::VecOps::RVec in); - - /// return the production vertex of the input MCParticles - ROOT::VecOps::RVec get_vertex(ROOT::VecOps::RVec in); - - /// return the production vertex x of the input MCParticles - ROOT::VecOps::RVec get_vertex_x(ROOT::VecOps::RVec in); - - /// return the production vertex y of the input MCParticles - ROOT::VecOps::RVec get_vertex_y(ROOT::VecOps::RVec in); - - /// return the production vertex z of the input MCParticles - ROOT::VecOps::RVec get_vertex_z(ROOT::VecOps::RVec in); - - /// return the end point of the input MCParticles - ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in); - - /// return the end point of the input MCParticles (not using the "endpoint" that is currently not filled) - ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind ); - - /// return the end point x of the input MCParticles - ROOT::VecOps::RVec get_endPoint_x(ROOT::VecOps::RVec in); - - /// return the end point y of the input MCParticles - ROOT::VecOps::RVec get_endPoint_y(ROOT::VecOps::RVec in); - - /// return the z of the input MCParticles - ROOT::VecOps::RVec get_endPoint_z(ROOT::VecOps::RVec in); - - /// return the transverse momenta of the input MCParticles - ROOT::VecOps::RVec get_pt(ROOT::VecOps::RVec in); - - /// return the momenta of the input MCParticles - ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in); - - /// return the momenta of the input MCParticles - ROOT::VecOps::RVec get_px(ROOT::VecOps::RVec in); - - /// return the momenta of the input MCParticles - ROOT::VecOps::RVec get_py(ROOT::VecOps::RVec in); - - /// return the momenta of the input MCParticles - ROOT::VecOps::RVec get_pz(ROOT::VecOps::RVec in); - - /// return the pseudo-rapidity of the input MCParticles - ROOT::VecOps::RVec get_eta(ROOT::VecOps::RVec in); - - /// return the rapidity of the input MCParticles - ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in); - - /// return the theta of the input MCParticles - ROOT::VecOps::RVec get_theta(ROOT::VecOps::RVec in); - - /// return the phi of the input MCParticles - ROOT::VecOps::RVec get_phi(ROOT::VecOps::RVec in); - - /// return the energy of the input MCParticles - ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in); - - /// return the masses of the input MCParticles - ROOT::VecOps::RVec get_mass(ROOT::VecOps::RVec in); - - /// return the charges of the input MCParticles - ROOT::VecOps::RVec get_charge(ROOT::VecOps::RVec in); - - /// return the TlorentzVector of the input MCParticles - ROOT::VecOps::RVec get_tlv(ROOT::VecOps::RVec in); - - /// concatenate both input vectors and return the resulting vector - ROOT::VecOps::RVec mergeParticles(ROOT::VecOps::RVec x, ROOT::VecOps::RVec y); - - /// return the size of the input collection - int get_n(ROOT::VecOps::RVec in); - - /// return the angle (3D) between two MCParticles : - ROOT::VecOps::RVec AngleBetweenTwoMCParticles( ROOT::VecOps::RVec p1, ROOT::VecOps::RVec p2 ); - - /// return the list of stable particles from the decay of a mother particle, looking at the full decay chain recursively. i is the mother index in the Particle block - std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; - - /// return the list of stable particles from the decays of a mother particle, looking at the full decay chain recursively. - /// i is the list of mother indices to process in the Particle block. - /// Will return a vector of vectors - each vector is the set of children for one of the mothers in the input vector - ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays( ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; - - /// return the list of particles from the decay of a mother particle. i is the mother index in the Particle block. - std::vector get_list_of_particles_from_decay( int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - - /// returns one MCParticle selected by its index in the particle block - edm4hep::MCParticleData sel_byIndex( int idx, ROOT::VecOps::RVec in); - - /// obsolete: should use get_list_of_stable_particles_from_decay instead - std::vector list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; - /// obsolete: should use get_list_of_particles_from_decay instead - std::vector list_of_particles_from_decay( int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - - - /// return the pdg ID of the parent of a lepton (pre-FSR) - int get_lepton_origin(int idx, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - - int get_lepton_origin(const edm4hep::MCParticleData &p, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - - ROOT::VecOps::RVec get_leptons_origin(const ROOT::VecOps::RVec &particles, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - - -}//end NS MCParticle - -}//end NS FCCAnalyses +namespace MCParticle { + +/// Filter events based on a MCParticles PDGID +struct filter_pdgID { + filter_pdgID(int arg_pdgid, bool arg_abs); + int m_pdgid; //> Generator pdgid + bool m_abs; //> Use absolute value for pdgig + bool operator()(ROOT::VecOps::RVec in); +}; + +/// @brief Helper struct to select entries matching a certain predicate. +/// Supports two signatures - either a list of candidates is passed and a list +/// of accepted candidates returned, Or a list of indices in a vector of +/// candidates is passed and a list of accepted indices returned. The latter is +/// more compatible with index-based selection logic. +struct selByPredicate { + selByPredicate( + std::function thePredicate) + : m_predicate(thePredicate) {} + std::function m_predicate; + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &in); + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &indices, + const ROOT::VecOps::RVec &in); + ROOT::VecOps::RVec> + operator()(const ROOT::VecOps::RVec> &indices, + const ROOT::VecOps::RVec &in); +}; + +/// select MCParticles with transverse momentum greater than a minimum value +/// [GeV] +struct sel_pt : selByPredicate { + sel_pt(float arg_min_pt); +}; + +/// select MCParticles with absolute pseudorapidity less than a max value +struct sel_eta : selByPredicate { + sel_eta(float arg_max_eta); +}; + +/// select MCParticles with their status +struct sel_genStatus : selByPredicate { + sel_genStatus(int arg_status); +}; + +/// select MCParticles with their PDG id +struct sel_pdgID : selByPredicate { + sel_pdgID(int arg_pdg, bool arg_chargeconjugate); +}; + +/// select MCParticles with a non-zero charge +struct sel_charged : selByPredicate { + sel_charged(); +}; + +/// get MC history tree for a given MCParticle index +struct get_tree { + get_tree(int arg_index); + int m_index; //> MC Particle index to build the tree from + ROOT::VecOps::RVec + operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); +}; + +/// get the decay of a given particle +struct get_decay { + get_decay(int arg_mother, int arg_daughters, bool arg_inf); + int m_mother = 0; //> mother pdg id + int m_daughters = 0; //> daughters pdg id + bool m_inf = false; //> boolean to check if the pdgid is below a value rather + //than equal + bool operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); +}; + +/// return the event primary vertex (mm) +struct get_EventPrimaryVertex { + get_EventPrimaryVertex(int arg_genstatus); + int m_genstatus = + 21; // Pythia8 code of the incoming particles of the hardest subprocess + TVector3 operator()(ROOT::VecOps::RVec in); +}; + +/// return the event primary vertex position and time (mm) +struct get_EventPrimaryVertexP4 { + get_EventPrimaryVertexP4(); + int m_genstatus = + 21; // Pythia8 code of the incoming particles of the hardest subprocess + TLorentzVector operator()(ROOT::VecOps::RVec in); +}; + +/// return a list of indices that correspond to a given MC decay. The list +/// contains the index of the mother, followed by the indices of the daughters, +/// in the order specified. If m_inclusiveDecay is true, the list of daughters +/// is the minimum required for the mother's decay (otherwise, the list is the +/// exact daughters required for the mother's decay). In case there are several +/// such decays in the event, keep only the first one. +struct get_indices { + get_indices(int pdg_mother, std::vector pdg_daughters, + bool stableDaughters, bool chargeConjugateMother, + bool chargeConjugateDaughters, bool inclusiveDecay); + int m_pdg_mother; + std::vector m_pdg_daughters; + bool m_stableDaughters; + bool m_chargeConjugateMother; + bool m_chargeConjugateDaughters; + bool m_inclusiveDecay; + ROOT::VecOps::RVec + operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); +}; + +/// A shorthand for get_indices, with m_chargeConjugateDaughters=false, +/// inclusiveDecay=false +struct get_indices_ExclusiveDecay : get_indices { + get_indices_ExclusiveDecay(int pdg_mother, std::vector pdg_daughters, + bool stableDaughters, bool chargeConjugate); +}; + +/// return a list of indices that correspond to a given MC decay +ROOT::VecOps::RVec get_indices_MotherByIndex( + int imother, std::vector m_pdg_daughters, bool m_stableDaughters, + bool m_chargeConjugateDaughters, bool m_inclusiveDecay, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// a shorthand for get_indices_MotherByIndex with +/// m_chargeConjugateDaughters=false, m_inclusiveDecay =false +ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( + int imother, std::vector m_pdg_daughters, bool m_stableDaughters, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// return the parent index of a given list of MC particles +ROOT::VecOps::RVec +get_parentid(ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents); + +/// return the time of the input MCParticles +ROOT::VecOps::RVec +get_time(ROOT::VecOps::RVec in); + +/// return the PDG of the input MCParticles +ROOT::VecOps::RVec +get_pdg(ROOT::VecOps::RVec in); + +/// return the generator status of the input MCParticles +ROOT::VecOps::RVec +get_genStatus(ROOT::VecOps::RVec in); + +/// return the simulation status of the input MCParticles +ROOT::VecOps::RVec +get_simStatus(ROOT::VecOps::RVec in); + +/// return the production vertex of the input MCParticles +ROOT::VecOps::RVec +get_vertex(ROOT::VecOps::RVec in); + +/// return the production vertex x of the input MCParticles +ROOT::VecOps::RVec +get_vertex_x(ROOT::VecOps::RVec in); + +/// return the production vertex y of the input MCParticles +ROOT::VecOps::RVec +get_vertex_y(ROOT::VecOps::RVec in); + +/// return the production vertex z of the input MCParticles +ROOT::VecOps::RVec +get_vertex_z(ROOT::VecOps::RVec in); + +/// return the end point of the input MCParticles +ROOT::VecOps::RVec +get_endPoint(ROOT::VecOps::RVec in); + +/// return the end point of the input MCParticles (not using the "endpoint" that +/// is currently not filled) +ROOT::VecOps::RVec +get_endPoint(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// return the end point x of the input MCParticles +ROOT::VecOps::RVec +get_endPoint_x(ROOT::VecOps::RVec in); + +/// return the end point y of the input MCParticles +ROOT::VecOps::RVec +get_endPoint_y(ROOT::VecOps::RVec in); + +/// return the z of the input MCParticles +ROOT::VecOps::RVec +get_endPoint_z(ROOT::VecOps::RVec in); + +/// return the transverse momenta of the input MCParticles +ROOT::VecOps::RVec +get_pt(ROOT::VecOps::RVec in); + +/// return the momenta of the input MCParticles +ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in); + +/// return the momenta of the input MCParticles +ROOT::VecOps::RVec +get_px(ROOT::VecOps::RVec in); + +/// return the momenta of the input MCParticles +ROOT::VecOps::RVec +get_py(ROOT::VecOps::RVec in); + +/// return the momenta of the input MCParticles +ROOT::VecOps::RVec +get_pz(ROOT::VecOps::RVec in); + +/// return the pseudo-rapidity of the input MCParticles +ROOT::VecOps::RVec +get_eta(ROOT::VecOps::RVec in); + +/// return the rapidity of the input MCParticles +ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in); + +/// return the theta of the input MCParticles +ROOT::VecOps::RVec +get_theta(ROOT::VecOps::RVec in); + +/// return the phi of the input MCParticles +ROOT::VecOps::RVec +get_phi(ROOT::VecOps::RVec in); + +/// return the energy of the input MCParticles +ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in); + +/// return the masses of the input MCParticles +ROOT::VecOps::RVec +get_mass(ROOT::VecOps::RVec in); + +/// return the charges of the input MCParticles +ROOT::VecOps::RVec +get_charge(ROOT::VecOps::RVec in); + +/// return the TlorentzVector of the input MCParticles +ROOT::VecOps::RVec +get_tlv(ROOT::VecOps::RVec in); + +/// concatenate both input vectors and return the resulting vector +ROOT::VecOps::RVec +mergeParticles(ROOT::VecOps::RVec x, + ROOT::VecOps::RVec y); + +/// return the size of the input collection +int get_n(ROOT::VecOps::RVec in); + +/// return the angle (3D) between two MCParticles : +ROOT::VecOps::RVec +AngleBetweenTwoMCParticles(ROOT::VecOps::RVec p1, + ROOT::VecOps::RVec p2); + +/// return the list of stable particles from the decay of a mother particle, +/// looking at the full decay chain recursively. i is the mother index in the +/// Particle block +std::vector get_list_of_stable_particles_from_decay( + int i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// return the list of stable particles from the decays of a mother particle, +/// looking at the full decay chain recursively. i is the list of mother indices +/// to process in the Particle block. Will return a vector of vectors - each +/// vector is the set of children for one of the mothers in the input vector +ROOT::VecOps::RVec> +get_lists_of_stable_particles_from_decays( + ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// return the list of particles from the decay of a mother particle. i is the +/// mother index in the Particle block. +std::vector +get_list_of_particles_from_decay(int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// returns one MCParticle selected by its index in the particle block +edm4hep::MCParticleData +sel_byIndex(int idx, ROOT::VecOps::RVec in); + +/// obsolete: should use get_list_of_stable_particles_from_decay instead +std::vector list_of_stable_particles_from_decay( + int i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); +/// obsolete: should use get_list_of_particles_from_decay instead +std::vector +list_of_particles_from_decay(int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + +/// return the pdg ID of the parent of a lepton (pre-FSR) +int get_lepton_origin(int idx, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + +int get_lepton_origin(const edm4hep::MCParticleData &p, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + +ROOT::VecOps::RVec +get_leptons_origin(const ROOT::VecOps::RVec &particles, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + +} // namespace MCParticle + +} // namespace FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h index 149e2132ba8..e3470af9f1c 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h @@ -1,167 +1,174 @@ -#ifndef RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H -#define RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H +#ifndef RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H +#define RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H #include #include #include "ROOT/RVec.hxx" -#include "edm4hep/ReconstructedParticleData.h" +#include "TLorentzVector.h" #include "edm4hep/MCParticleData.h" +#include "edm4hep/ReconstructedParticleData.h" #include "podio/ObjectID.h" -#include "TLorentzVector.h" -namespace FCCAnalyses{ - -namespace ReconstructedParticle2MC{ - - /// select ReconstructedParticles matched with a MC particle of a given PDG_id - struct selRP_PDG { - selRP_PDG(int arg_PDG, bool arg_chargedOnly); - int m_PDG = 13 ; - bool m_chargedOnly = true; - std::vector operator() (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) ; - }; - - /// select ReconstructedParticles matched with a MC particle of a given PDG_id - struct selRP_PDG_index { - selRP_PDG_index(int arg_PDG, bool arg_chargedOnly); - int m_PDG = 13 ; - bool m_chargedOnly = true; - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) ; - }; - - - /// select ReconstructedParticles with transverse momentum greater than a minimum value [GeV] - struct getRP2MC_p_func { - ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - }; - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_p (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_px (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_py (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_pz (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_mass (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_charge (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_pdg (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_tlv (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_index (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec> getRP2MC_indexVec (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_index_test (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents); - - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2MC_parentid (ROOT::VecOps::RVec recin, - ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents); - - /// select ReconstructedParticles matched with a MC charged hadrons - std::vector selRP_ChargedHadrons ( ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) ; - - /// select ReconstructedParticles matched to the MC particles whose indices are passed in a list - /// @param mcParticles_indices indices of the MC particles to look up - /// @param recind: reco index component of the MCRecoAssociations - /// @param mcind: mc index component of the MCRecoAssociations - /// @param reco: full reco particle list (ReconstructedParticles) - /// @param mc: full mc particle list (Particles) - /// @param require_stable: if set to true, will only match stable particles. - /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a dummy particle will be inserted. If 1:1 length correspondence is required, set require_stable to false. - ROOT::VecOps::RVec selRP_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & reco, - const ROOT::VecOps::RVec & mc, - bool require_stable = true) ; - /// select indices of ReconstructedParticles matched to the MC particles whose indices are passed in a list - /// @param mcParticles_indices indices of the MC particles to look up - /// @param recind: reco index component of the MCRecoAssociations - /// @param mcind: mc index component of the MCRecoAssociations - /// @param mc: full mc particle list (Particles) - /// @param require_stable: if set to true, will only match stable particles. - /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a "-1" entry will be inserted. If 1:1 length correspondence is required, set require_stable to false. - ROOT::VecOps::RVec selRP_indices_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & mc, - bool require_stable = true - ) ; - - /// return the index of the MC particle that is associated to a given track (via the track-reco association) - int getTrack2MC_index ( int track_index, - ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco); - -}//end NS ReconstructedParticle2MC - -}//end NS FCCAnalyses +namespace FCCAnalyses { + +namespace ReconstructedParticle2MC { + +/// select ReconstructedParticles matched with a MC particle of a given PDG_id +struct selRP_PDG { + selRP_PDG(int arg_PDG, bool arg_chargedOnly); + int m_PDG = 13; + bool m_chargedOnly = true; + std::vector + operator()(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); +}; + +/// select ReconstructedParticles matched with a MC particle of a given PDG_id +struct selRP_PDG_index { + selRP_PDG_index(int arg_PDG, bool arg_chargedOnly); + int m_PDG = 13; + bool m_chargedOnly = true; + ROOT::VecOps::RVec + operator()(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); +}; + +/// select ReconstructedParticles with transverse momentum greater than a +/// minimum value [GeV] +struct getRP2MC_p_func { + ROOT::VecOps::RVec + operator()(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); +}; + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_p(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_px(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_py(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_pz(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_mass(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_charge(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_pdg(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_tlv(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_index(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec> +getRP2MC_indexVec(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_index_test(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2MC_parentid(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents); + +/// select ReconstructedParticles matched with a MC charged hadrons +std::vector selRP_ChargedHadrons( + ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + +/// select ReconstructedParticles matched to the MC particles whose indices are +/// passed in a list +/// @param mcParticles_indices indices of the MC particles to look up +/// @param recind: reco index component of the MCRecoAssociations +/// @param mcind: mc index component of the MCRecoAssociations +/// @param reco: full reco particle list (ReconstructedParticles) +/// @param mc: full mc particle list (Particles) +/// @param require_stable: if set to true, will only match stable particles. +/// @return List of ReconstructedParticle candidates with length corresponding +/// to the number of *stable* MC particles in the mcParticles_indices vector. In +/// presence of unstable particles, no 1:1 correspondence. For non-reconstructed +/// stable MC particles, a dummy particle will be inserted. If 1:1 length +/// correspondence is required, set require_stable to false. +ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &reco, + const ROOT::VecOps::RVec &mc, + bool require_stable = true); +/// select indices of ReconstructedParticles matched to the MC particles whose +/// indices are passed in a list +/// @param mcParticles_indices indices of the MC particles to look up +/// @param recind: reco index component of the MCRecoAssociations +/// @param mcind: mc index component of the MCRecoAssociations +/// @param mc: full mc particle list (Particles) +/// @param require_stable: if set to true, will only match stable particles. +/// @return List of ReconstructedParticle candidates with length corresponding +/// to the number of *stable* MC particles in the mcParticles_indices vector. In +/// presence of unstable particles, no 1:1 correspondence. For non-reconstructed +/// stable MC particles, a "-1" entry will be inserted. If 1:1 length +/// correspondence is required, set require_stable to false. +ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &mc, + bool require_stable = true); + +/// return the index of the MC particle that is associated to a given track (via +/// the track-reco association) +int getTrack2MC_index( + int track_index, ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco); + +} // namespace ReconstructedParticle2MC + +} // namespace FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index 70f305faa87..ad645cb6aaa 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -1,53 +1,69 @@ -#ifndef UTILS_ANALYZERS_H -#define UTILS_ANALYZERS_H +#ifndef UTILS_ANALYZERS_H +#define UTILS_ANALYZERS_H -#include #include +#include namespace FCCAnalyses { - namespace Utils { +namespace Utils { - template inline auto getsize( T& vec){ return vec.size();}; - template inline ROOT::VecOps::RVec > as_vector(const ROOT::VecOps::RVec& in){return ROOT::VecOps::RVec >(1, in);}; - template inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec & in){ - ROOT::VecOps::RVec indices(in.size()); - std::iota(indices.begin(),indices.end(), 0); - return indices; - }; - /// @brief count the number of valid (>=0, < size of collection) indices in an index list - /// @param in: index list - /// @param ref: particle vector to which the indices refer. - /// @return integer count of valid indices - template inline int count_valid_indices(const ROOT::VecOps::RVec & in, - const ROOT::VecOps::RVec & ref){ - int maxSize = ref.size(); - return std::count_if(in.begin(),in.end(),[maxSize](const int & i){return (i >=0 && i < maxSize);}); - }; +template inline auto getsize(T &vec) { return vec.size(); }; +template +inline ROOT::VecOps::RVec> +as_vector(const ROOT::VecOps::RVec &in) { + return ROOT::VecOps::RVec>(1, in); +}; +template +inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec indices(in.size()); + std::iota(indices.begin(), indices.end(), 0); + return indices; +}; +/// @brief count the number of valid (>=0, < size of collection) indices in an +/// index list +/// @param in: index list +/// @param ref: particle vector to which the indices refer. +/// @return integer count of valid indices +template +inline int count_valid_indices(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ref) { + int maxSize = ref.size(); + return std::count_if(in.begin(), in.end(), [maxSize](const int &i) { + return (i >= 0 && i < maxSize); + }); +}; - // @brief for a given list of indices, returns a list of particle (copies) - /// @param idx : Indices of desired particles within the full set ("in") - /// @param in : Full set of particles - /// @return A vector of particles with the desired indices. - template inline ROOT::VecOps::RVec sel_byIndex( const ROOT::VecOps::RVec & idx, const ROOT::VecOps::RVec & in){ - ROOT::VecOps::RVec found; - for (int index : idx){ - if (index < 0 || index >= in.size()) continue; - found.push_back(in.at(index)); - } - return found; - } - // @brief merge (concatenate) two collections of arbitrary content - /// @param x : first collection - entries will be copied in-order - /// @param y : second collection - entries will be copied in-order after the last element of the first - /// @return A combined collection of size (x.size()+y.size()), containing the content of x followed by that of y - template inline ROOT::VecOps::RVec merge( const ROOT::VecOps::RVec & x, const ROOT::VecOps::RVec & y){ - ROOT::VecOps::RVec merged; - merged.reserve(x.size()+y.size()); - merged.insert(merged.end(), x.begin(), x.end()); - merged.insert(merged.end(), y.begin(), y.end()); - return merged; - } +// @brief for a given list of indices, returns a list of particle (copies) +/// @param idx : Indices of desired particles within the full set ("in") +/// @param in : Full set of particles +/// @return A vector of particles with the desired indices. +template +inline ROOT::VecOps::RVec sel_byIndex(const ROOT::VecOps::RVec &idx, + const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec found; + for (int index : idx) { + if (index < 0 || index >= in.size()) + continue; + found.push_back(in.at(index)); } + return found; +} +// @brief merge (concatenate) two collections of arbitrary content +/// @param x : first collection - entries will be copied in-order +/// @param y : second collection - entries will be copied in-order after the +/// last element of the first +/// @return A combined collection of size (x.size()+y.size()), containing the +/// content of x followed by that of y +template +inline ROOT::VecOps::RVec merge(const ROOT::VecOps::RVec &x, + const ROOT::VecOps::RVec &y) { + ROOT::VecOps::RVec merged; + merged.reserve(x.size() + y.size()); + merged.insert(merged.end(), x.begin(), x.end()); + merged.insert(merged.end(), y.begin(), y.end()); + return merged; } +} // namespace Utils +} // namespace FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index f913f0ea0e5..5e8cddd194e 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -1,342 +1,420 @@ -#ifndef VERTEXINGUTILS_ANALYZERS_H -#define VERTEXINGUTILS_ANALYZERS_H +#ifndef VERTEXINGUTILS_ANALYZERS_H +#define VERTEXINGUTILS_ANALYZERS_H #include #include #include "ROOT/RVec.hxx" -#include "edm4hep/ReconstructedParticleData.h" #include "edm4hep/MCParticleData.h" +#include "edm4hep/ReconstructedParticleData.h" #include "edm4hep/TrackState.h" -#include "edm4hep/VertexData.h" #include "edm4hep/Vertex.h" +#include "edm4hep/VertexData.h" #include "TLorentzVector.h" -#include "TVectorD.h" -#include "TVector3.h" #include "TMatrixDSym.h" +#include "TVector3.h" +#include "TVectorD.h" #include "fastjet/JetDefinition.hh" - -namespace FCCAnalyses{ +namespace FCCAnalyses { /** * Vertexing utilities. */ -namespace VertexingUtils{ - - /// from delphes: returns track state parameters (delphes convention) for a given vertex (x), momentum (p) and charge - TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q); - - /// from delphes: returns the momentum corresponding to a given track state - TVector3 ParToP(TVectorD Par); - - - /// Structure to keep useful track information that is related to the vertex - struct FCCAnalysesVertex{ - edm4hep::VertexData vertex; - int ntracks; - int mc_ind; ///index in the MC vertex collection if any - ROOT::VecOps::RVec reco_ind; // indices of the tracks fitted to that vertex, in the collection of all tracks - ROOT::VecOps::RVec reco_chi2; - ROOT::VecOps::RVec< TVector3 > updated_track_momentum_at_vertex; - ROOT::VecOps::RVec< TVectorD > updated_track_parameters; - ROOT::VecOps::RVec final_track_phases; - }; - - /// Structure to keep useful information that is related to the V0 - struct FCCAnalysesV0{ - ROOT::VecOps::RVec vtx; // vertex object - ROOT::VecOps::RVec pdgAbs; // pdg ID from reconstructions - ROOT::VecOps::RVec invM; // invariant mass - ROOT::VecOps::RVec nSV_jet; // no of V0s per jet - }; - - /// Structure to keep useful track information that is related to the vertex - struct FCCAnalysesVertexMC{ - TVector3 vertex; - ROOT::VecOps::RVec mc_ind; - ROOT::VecOps::RVec mc_indneutral; - ROOT::VecOps::RVec mother_ind; - ROOT::VecOps::RVec gmother_ind; - }; - - /// Selection of particles based on the d0 / z0 significances of the associated track - struct selTracks { - selTracks( float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, float arg_z0sig_max) ; - float m_d0sig_min = 0; - float m_d0sig_max = 3; - float m_z0sig_min = 0; - float m_z0sig_max = 3; - ROOT::VecOps::RVec operator() ( ROOT::VecOps::RVec recop, - ROOT::VecOps::RVec tracks ) ; - }; - - /// Selection of primary particles : - ROOT::VecOps::RVec SelPrimaryTracks( ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - TVector3 MC_EventPrimaryVertex) ; - - /// Retrieve the number of reconstructed vertices from the collection of vertex object - int get_Nvertex( ROOT::VecOps::RVec TheVertexColl ); - - /// Retrieve a single FCCAnalyses vertex from the collection of vertex object - FCCAnalysesVertex get_FCCAnalysesVertex(ROOT::VecOps::RVec TheVertexColl, int index ); - - /// Retrieve the edm4hep::VertexData from the vertex object - edm4hep::VertexData get_VertexData( FCCAnalysesVertex TheVertex ) ; - - /// Retrieve a vector of edm4hep::VertexData from the collection of vertex object - ROOT::VecOps::RVec get_VertexData( ROOT::VecOps::RVec TheVertexColl ) ; - - /// Retrieve a edm4hep::VertexData from the collection of vertex object at a given index - edm4hep::VertexData get_VertexData( ROOT::VecOps::RVec TheVertexColl, int index); - - /// Retrieve the number of tracks from FCCAnalysesVertex - int get_VertexNtrk( FCCAnalysesVertex TheVertex ) ; - - ROOT::VecOps::RVec get_VertexNtrk( ROOT::VecOps::RVec vertices ) ; - - /// Retrieve the tracks indices from FCCAnalysesVertex - ROOT::VecOps::RVec get_VertexRecoInd( FCCAnalysesVertex TheVertex ) ; - - /// Retrieve the indices of the tracks fitted to that vertex, but now in the collection of RecoParticles - ROOT::VecOps::RVec get_VertexRecoParticlesInd( FCCAnalysesVertex TheVertex, - const ROOT::VecOps::RVec& reco ); - - /// Retrieve the indices of the tracks fitted to a vector of vertices, but now in the collection of RecoParticles - ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, - const ROOT::VecOps::RVec& reco ); - - /// @brief Find (by index) a vertex that is made of reco particles from a passed list. - /// @param vertices: List of possible vertices to match - /// @param recoParticleIndices: Indices of the reco particles to find in the vertex - /// @param reco: list of all reco particles (ReconstructedParticles) - /// @param require_all: If set, require one vertex to contain all recoParticleIndices (no 'missed' tracks). Else only require that all tracks in the vertex come from the vector (but allow for unused tracks) - /// @return: Index within the list of the (first) vertex fulfilling the criteria. If none are found, return -1 - int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, - const ROOT::VecOps::RVec & recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all = false); - - /// Return the number of tracks in a given track collection - int get_nTracks(ROOT::VecOps::RVec tracks); - - /// compare two track states - bool compare_Tracks( const edm4hep::TrackState& tr1, const edm4hep::TrackState& tr2 ) ; - - /////////////////////////////////////////////////// - /// functions used for SV reconstruction - - /** returns a vector of all vertices (PV and SVs), e.g to use in myUtils::get_Vertex_d2PV - * first entry: PV, all subsequent entries: SVs - */ - ROOT::VecOps::RVec get_all_vertices( FCCAnalysesVertex PV, - ROOT::VecOps::RVec SV ); - - ROOT::VecOps::RVec get_all_vertices( FCCAnalysesVertex PV, - ROOT::VecOps::RVec> SV ); - - /** returns the invariant mass of a two-track vertex - * CAUTION: m1 -> mass of first track, m2 -> mass of second track - * by default both pions - */ - double get_invM_pairs( FCCAnalysesVertex vertex, - double m1 = 0.13957039, - double m2 = 0.13957039) ; - - ROOT::VecOps::RVec get_invM_pairs( ROOT::VecOps::RVec vertices, - double m1 = 0.13957039, - double m2 = 0.13957039 ) ; - - /** returns the invariant mass of a vertex - * assuming all tracks to be pions - */ - double get_invM( FCCAnalysesVertex vertex ) ; - - /** returns the invariant mass of a vector of vertices - * assuming all tracks to be pions - */ - ROOT::VecOps::RVec get_invM( ROOT::VecOps::RVec vertices ) ; - - /** returns the cos of the angle b/n V0 candidate's (or any vtx's) momentum & PV to V0 (vtx) displacement vector */ - double get_PV2V0angle( FCCAnalysesVertex V0, - FCCAnalysesVertex PV) ; - - /** returns cos of the angle b/n track (that form the vtx) momentum sum & PV to vtx displacement vector */ - double get_PV2vtx_angle( ROOT::VecOps::RVec tracks, - FCCAnalysesVertex vtx, - FCCAnalysesVertex PV ) ; - - /** returns a track's energy - * assuming the track to be a pion - */ - double get_trackE( edm4hep::TrackState track ) ; - - /////////////////////////////////////////////////// - /// V0 Reconstruction - /// Return the number of reconstructed V0s - int get_n_SV( FCCAnalysesV0 SV ); - - /// Return the vertex position of all reconstructed V0s (in mm) - ROOT::VecOps::RVec get_position_SV( FCCAnalysesV0 SV ); - - /// Return the PDG IDs of all reconstructed V0s - ROOT::VecOps::RVec get_pdg_V0( FCCAnalysesV0 V0 ); +namespace VertexingUtils { + +/// from delphes: returns track state parameters (delphes convention) for a +/// given vertex (x), momentum (p) and charge +TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q); + +/// from delphes: returns the momentum corresponding to a given track state +TVector3 ParToP(TVectorD Par); + +/// Structure to keep useful track information that is related to the vertex +struct FCCAnalysesVertex { + edm4hep::VertexData vertex; + int ntracks; + int mc_ind; /// index in the MC vertex collection if any + ROOT::VecOps::RVec reco_ind; // indices of the tracks fitted to that + // vertex, in the collection of all tracks + ROOT::VecOps::RVec reco_chi2; + ROOT::VecOps::RVec updated_track_momentum_at_vertex; + ROOT::VecOps::RVec updated_track_parameters; + ROOT::VecOps::RVec final_track_phases; +}; + +/// Structure to keep useful information that is related to the V0 +struct FCCAnalysesV0 { + ROOT::VecOps::RVec vtx; // vertex object + ROOT::VecOps::RVec pdgAbs; // pdg ID from reconstructions + ROOT::VecOps::RVec invM; // invariant mass + ROOT::VecOps::RVec nSV_jet; // no of V0s per jet +}; + +/// Structure to keep useful track information that is related to the vertex +struct FCCAnalysesVertexMC { + TVector3 vertex; + ROOT::VecOps::RVec mc_ind; + ROOT::VecOps::RVec mc_indneutral; + ROOT::VecOps::RVec mother_ind; + ROOT::VecOps::RVec gmother_ind; +}; + +/// Selection of particles based on the d0 / z0 significances of the associated +/// track +struct selTracks { + selTracks(float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, + float arg_z0sig_max); + float m_d0sig_min = 0; + float m_d0sig_max = 3; + float m_z0sig_min = 0; + float m_z0sig_max = 3; + ROOT::VecOps::RVec + operator()(ROOT::VecOps::RVec recop, + ROOT::VecOps::RVec tracks); +}; + +/// Selection of primary particles : +ROOT::VecOps::RVec +SelPrimaryTracks(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + TVector3 MC_EventPrimaryVertex); + +/// Retrieve the number of reconstructed vertices from the collection of vertex +/// object +int get_Nvertex(ROOT::VecOps::RVec TheVertexColl); + +/// Retrieve a single FCCAnalyses vertex from the collection of vertex object +FCCAnalysesVertex +get_FCCAnalysesVertex(ROOT::VecOps::RVec TheVertexColl, + int index); + +/// Retrieve the edm4hep::VertexData from the vertex object +edm4hep::VertexData get_VertexData(FCCAnalysesVertex TheVertex); + +/// Retrieve a vector of edm4hep::VertexData from the collection of vertex +/// object +ROOT::VecOps::RVec +get_VertexData(ROOT::VecOps::RVec TheVertexColl); + +/// Retrieve a edm4hep::VertexData from the collection of vertex object at a +/// given index +edm4hep::VertexData +get_VertexData(ROOT::VecOps::RVec TheVertexColl, int index); + +/// Retrieve the number of tracks from FCCAnalysesVertex +int get_VertexNtrk(FCCAnalysesVertex TheVertex); + +ROOT::VecOps::RVec +get_VertexNtrk(ROOT::VecOps::RVec vertices); + +/// Retrieve the tracks indices from FCCAnalysesVertex +ROOT::VecOps::RVec get_VertexRecoInd(FCCAnalysesVertex TheVertex); + +/// Retrieve the indices of the tracks fitted to that vertex, but now in the +/// collection of RecoParticles +ROOT::VecOps::RVec get_VertexRecoParticlesInd( + FCCAnalysesVertex TheVertex, + const ROOT::VecOps::RVec &reco); + +/// Retrieve the indices of the tracks fitted to a vector of vertices, but now +/// in the collection of RecoParticles +ROOT::VecOps::RVec get_VerticesRecoParticlesInd( + ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec &reco); + +/// @brief Find (by index) a vertex that is made of reco particles from a passed +/// list. +/// @param vertices: List of possible vertices to match +/// @param recoParticleIndices: Indices of the reco particles to find in the +/// vertex +/// @param reco: list of all reco particles (ReconstructedParticles) +/// @param require_all: If set, require one vertex to contain all +/// recoParticleIndices (no 'missed' tracks). Else only require that all tracks +/// in the vertex come from the vector (but allow for unused tracks) +/// @return: Index within the list of the (first) vertex fulfilling the +/// criteria. If none are found, return -1 +int getVertex_matching_recoParticles( + const ROOT::VecOps::RVec &vertices, + const ROOT::VecOps::RVec &recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all = false); + +/// Return the number of tracks in a given track collection +int get_nTracks(ROOT::VecOps::RVec tracks); + +/// compare two track states +bool compare_Tracks(const edm4hep::TrackState &tr1, + const edm4hep::TrackState &tr2); + +/////////////////////////////////////////////////// +/// functions used for SV reconstruction + +/** returns a vector of all vertices (PV and SVs), e.g to use in + * myUtils::get_Vertex_d2PV first entry: PV, all subsequent entries: SVs + */ +ROOT::VecOps::RVec +get_all_vertices(FCCAnalysesVertex PV, + ROOT::VecOps::RVec SV); - /// Return the invariant masses of all reconstructed V0s - ROOT::VecOps::RVec get_invM_V0( FCCAnalysesV0 V0 ); - - /// Return the momentum of all reconstructed V0s - ROOT::VecOps::RVec get_p_SV( FCCAnalysesV0 SV ); - - /// Return chi2 of all reconstructed V0s - ROOT::VecOps::RVec get_chi2_SV( FCCAnalysesV0 SV ); - - /////////////////////////////////////////////////// - - /// Passing a vector of FCCAnalysesVertex instead of FCCAnalysesV0 - /// Return the number of reconstructed SVs - int get_n_SV( ROOT::VecOps::RVec vertices ); - - /// Return the momentum of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_p_SV( ROOT::VecOps::RVec vertices ); - - /// Return the vertex position of all reconstructed SVs (in mm) - ROOT::VecOps::RVec get_position_SV( ROOT::VecOps::RVec vertices ); - - /// Return the momentum magnitude of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_pMag_SV( ROOT::VecOps::RVec vertices ); - - /// Return chi2 of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_chi2_SV( ROOT::VecOps::RVec vertices ); - - /// Return normalised chi2 of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_norm_chi2_SV( ROOT::VecOps::RVec vertices ); - - /// Return no of DOF of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_nDOF_SV( ROOT::VecOps::RVec vertices ); - - /// Return polar angle (theta) of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_theta_SV( ROOT::VecOps::RVec vertices ); - - /// Return azimuthal angle (phi) of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_phi_SV( ROOT::VecOps::RVec vertices ); - - /// Return polar angle (theta) of all reconstructed vertices wrt jets (or V0.vtx) - ROOT::VecOps::RVec get_relTheta_SV( ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet, - ROOT::VecOps::RVec jets ); - - /// Return azimuthal angle (phi) of all reconstructed vertices wrt jets (or V0.vtx) - ROOT::VecOps::RVec get_relPhi_SV( ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet, - ROOT::VecOps::RVec jets ); - - /// Return the pointing angle of all reconstructed vertices (or V0.vtx) - ROOT::VecOps::RVec get_pointingangle_SV( ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV ); - - /// Return the distances of all reconstructed vertices from PV in xy plane [mm] (or V0.vtx) - ROOT::VecOps::RVec get_dxy_SV( ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV ); - - /// Return the distances of all reconstructed vertices from PV in 3D [mm] (or V0.vtx) - ROOT::VecOps::RVec get_d3d_SV( ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV ); - - /// Return the distances of all reconstructed verteces from given TVector3d object in 3D [mm] (or V0.vtx) - ROOT::VecOps::RVec get_d3d_SV_obj( ROOT::VecOps::RVec vertices, - TVector3 location ); - - /// Return the distances of all reconstructed verteces from given edm4hep::Vector3d object in 3D [mm] (or V0.vtx) - ROOT::VecOps::RVec get_d3d_SV_obj( ROOT::VecOps::RVec vertices, - edm4hep::Vector3d location ); - - /// Return the distance in R of all reconstructed verteces from given TVector3d object in 3D [mm] (or V0.vtx) - ROOT::VecOps::RVec get_dR_SV_obj( ROOT::VecOps::RVec vertices, - TVector3 location ); - - /// Return the distances in R of all reconstructed verteces from given edm4hep::Vector3d object in 3D [mm] (or V0.vtx) - ROOT::VecOps::RVec get_dR_SV_obj( ROOT::VecOps::RVec vertices, - edm4hep::Vector3d location ); - - /////////////////////////////////////////////////// +ROOT::VecOps::RVec +get_all_vertices(FCCAnalysesVertex PV, + ROOT::VecOps::RVec> SV); - /// For get_SV_jets /// - - /// Return the number of reconstructed SVs - ROOT::VecOps::RVec get_all_SVs( ROOT::VecOps::RVec> vertices ); +/** returns the invariant mass of a two-track vertex + * CAUTION: m1 -> mass of first track, m2 -> mass of second track + * by default both pions + */ +double get_invM_pairs(FCCAnalysesVertex vertex, double m1 = 0.13957039, + double m2 = 0.13957039); - /// Return the total number of reconstructed SVs - int get_n_SV( ROOT::VecOps::RVec> vertices ); +ROOT::VecOps::RVec +get_invM_pairs(ROOT::VecOps::RVec vertices, + double m1 = 0.13957039, double m2 = 0.13957039); - /// Return the number of reconstructed SVs per jet - ROOT::VecOps::RVec get_n_SV_jets( ROOT::VecOps::RVec> vertices ); +/** returns the invariant mass of a vertex + * assuming all tracks to be pions + */ +double get_invM(FCCAnalysesVertex vertex); - /// Return the tracks separated by jets - std::vector> get_tracksInJets( ROOT::VecOps::RVec recoparticles, - ROOT::VecOps::RVec thetracks, - ROOT::VecOps::RVec jets, - std::vector> jet_consti ); +/** returns the invariant mass of a vector of vertices + * assuming all tracks to be pions + */ +ROOT::VecOps::RVec +get_invM(ROOT::VecOps::RVec vertices); - /// Return V0s separated by jets - ROOT::VecOps::RVec> get_svInJets( ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet ); +/** returns the cos of the angle b/n V0 candidate's (or any vtx's) momentum & PV + * to V0 (vtx) displacement vector */ +double get_PV2V0angle(FCCAnalysesVertex V0, FCCAnalysesVertex PV); - // --- for get_SV_jets --- // - ROOT::VecOps::RVec> get_invM( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_p_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_pMag_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_VertexNtrk( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_chi2_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_norm_chi2_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_nDOF_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_theta_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_phi_SV( ROOT::VecOps::RVec> vertices ); - ROOT::VecOps::RVec> get_relTheta_SV( ROOT::VecOps::RVec> vertices, ROOT::VecOps::RVec jets ); - ROOT::VecOps::RVec> get_relPhi_SV( ROOT::VecOps::RVec> vertices, ROOT::VecOps::RVec jets ); - ROOT::VecOps::RVec> get_pointingangle_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); - ROOT::VecOps::RVec> get_dxy_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); - ROOT::VecOps::RVec> get_d3d_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); - ROOT::VecOps::RVec> get_pdg_V0( ROOT::VecOps::RVec pdg, ROOT::VecOps::RVec nSV_jet ); - ROOT::VecOps::RVec> get_invM_V0( ROOT::VecOps::RVec invM, ROOT::VecOps::RVec nSV_jet ); - /// Return the vertex position of all reconstructed SVs (in mm) - ROOT::VecOps::RVec> get_position_SV( ROOT::VecOps::RVec> vertices ); - // --- for get_SV_jets --- // - - float get_trackMom( edm4hep::TrackState & atrack ); +/** returns cos of the angle b/n track (that form the vtx) momentum sum & PV to + * vtx displacement vector */ +double get_PV2vtx_angle(ROOT::VecOps::RVec tracks, + FCCAnalysesVertex vtx, FCCAnalysesVertex PV); +/** returns a track's energy + * assuming the track to be a pion + */ +double get_trackE(edm4hep::TrackState track); + +/////////////////////////////////////////////////// +/// V0 Reconstruction +/// Return the number of reconstructed V0s +int get_n_SV(FCCAnalysesV0 SV); + +/// Return the vertex position of all reconstructed V0s (in mm) +ROOT::VecOps::RVec get_position_SV(FCCAnalysesV0 SV); + +/// Return the PDG IDs of all reconstructed V0s +ROOT::VecOps::RVec get_pdg_V0(FCCAnalysesV0 V0); + +/// Return the invariant masses of all reconstructed V0s +ROOT::VecOps::RVec get_invM_V0(FCCAnalysesV0 V0); + +/// Return the momentum of all reconstructed V0s +ROOT::VecOps::RVec get_p_SV(FCCAnalysesV0 SV); + +/// Return chi2 of all reconstructed V0s +ROOT::VecOps::RVec get_chi2_SV(FCCAnalysesV0 SV); + +/////////////////////////////////////////////////// + +/// Passing a vector of FCCAnalysesVertex instead of FCCAnalysesV0 +/// Return the number of reconstructed SVs +int get_n_SV(ROOT::VecOps::RVec vertices); + +/// Return the momentum of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_p_SV(ROOT::VecOps::RVec vertices); + +/// Return the vertex position of all reconstructed SVs (in mm) +ROOT::VecOps::RVec +get_position_SV(ROOT::VecOps::RVec vertices); + +/// Return the momentum magnitude of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_pMag_SV(ROOT::VecOps::RVec vertices); + +/// Return chi2 of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_chi2_SV(ROOT::VecOps::RVec vertices); + +/// Return normalised chi2 of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_norm_chi2_SV(ROOT::VecOps::RVec vertices); + +/// Return no of DOF of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_nDOF_SV(ROOT::VecOps::RVec vertices); + +/// Return polar angle (theta) of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_theta_SV(ROOT::VecOps::RVec vertices); + +/// Return azimuthal angle (phi) of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_phi_SV(ROOT::VecOps::RVec vertices); + +/// Return polar angle (theta) of all reconstructed vertices wrt jets (or +/// V0.vtx) +ROOT::VecOps::RVec +get_relTheta_SV(ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet, + ROOT::VecOps::RVec jets); + +/// Return azimuthal angle (phi) of all reconstructed vertices wrt jets (or +/// V0.vtx) +ROOT::VecOps::RVec +get_relPhi_SV(ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet, + ROOT::VecOps::RVec jets); + +/// Return the pointing angle of all reconstructed vertices (or V0.vtx) +ROOT::VecOps::RVec +get_pointingangle_SV(ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV); + +/// Return the distances of all reconstructed vertices from PV in xy plane [mm] +/// (or V0.vtx) +ROOT::VecOps::RVec +get_dxy_SV(ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV); + +/// Return the distances of all reconstructed vertices from PV in 3D [mm] (or +/// V0.vtx) +ROOT::VecOps::RVec +get_d3d_SV(ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV); + +/// Return the distances of all reconstructed verteces from given TVector3d +/// object in 3D [mm] (or V0.vtx) +ROOT::VecOps::RVec +get_d3d_SV_obj(ROOT::VecOps::RVec vertices, + TVector3 location); + +/// Return the distances of all reconstructed verteces from given +/// edm4hep::Vector3d object in 3D [mm] (or V0.vtx) +ROOT::VecOps::RVec +get_d3d_SV_obj(ROOT::VecOps::RVec vertices, + edm4hep::Vector3d location); + +/// Return the distance in R of all reconstructed verteces from given TVector3d +/// object in 3D [mm] (or V0.vtx) +ROOT::VecOps::RVec +get_dR_SV_obj(ROOT::VecOps::RVec vertices, + TVector3 location); + +/// Return the distances in R of all reconstructed verteces from given +/// edm4hep::Vector3d object in 3D [mm] (or V0.vtx) +ROOT::VecOps::RVec +get_dR_SV_obj(ROOT::VecOps::RVec vertices, + edm4hep::Vector3d location); + +/////////////////////////////////////////////////// + +/// For get_SV_jets /// + +/// Return the number of reconstructed SVs +ROOT::VecOps::RVec +get_all_SVs(ROOT::VecOps::RVec> vertices); + +/// Return the total number of reconstructed SVs +int get_n_SV( + ROOT::VecOps::RVec> vertices); + +/// Return the number of reconstructed SVs per jet +ROOT::VecOps::RVec get_n_SV_jets( + ROOT::VecOps::RVec> vertices); + +/// Return the tracks separated by jets +std::vector> get_tracksInJets( + ROOT::VecOps::RVec recoparticles, + ROOT::VecOps::RVec thetracks, + ROOT::VecOps::RVec jets, + std::vector> jet_consti); + +/// Return V0s separated by jets +ROOT::VecOps::RVec> +get_svInJets(ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet); + +// --- for get_SV_jets --- // +ROOT::VecOps::RVec> +get_invM(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> +get_p_SV(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> +get_pMag_SV(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> get_VertexNtrk( + ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> +get_chi2_SV(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> get_norm_chi2_SV( + ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> +get_nDOF_SV(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> get_theta_SV( + ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> +get_phi_SV(ROOT::VecOps::RVec> vertices); +ROOT::VecOps::RVec> get_relTheta_SV( + ROOT::VecOps::RVec> vertices, + ROOT::VecOps::RVec jets); +ROOT::VecOps::RVec> get_relPhi_SV( + ROOT::VecOps::RVec> vertices, + ROOT::VecOps::RVec jets); +ROOT::VecOps::RVec> get_pointingangle_SV( + ROOT::VecOps::RVec> vertices, + FCCAnalysesVertex PV); +ROOT::VecOps::RVec> +get_dxy_SV(ROOT::VecOps::RVec> vertices, + FCCAnalysesVertex PV); +ROOT::VecOps::RVec> +get_d3d_SV(ROOT::VecOps::RVec> vertices, + FCCAnalysesVertex PV); +ROOT::VecOps::RVec> +get_pdg_V0(ROOT::VecOps::RVec pdg, ROOT::VecOps::RVec nSV_jet); +ROOT::VecOps::RVec> +get_invM_V0(ROOT::VecOps::RVec invM, ROOT::VecOps::RVec nSV_jet); +/// Return the vertex position of all reconstructed SVs (in mm) +ROOT::VecOps::RVec> get_position_SV( + ROOT::VecOps::RVec> vertices); +// --- for get_SV_jets --- // + +float get_trackMom(edm4hep::TrackState &atrack); // --- Conversion methods between the Delphes and edm4hep conventions -/// convert track parameters, from edm4hep to delphes conventions - TVectorD Edm4hep2Delphes_TrackParam( const TVectorD& param, bool Units_mm ); +/// convert track parameters, from edm4hep to delphes conventions +TVectorD Edm4hep2Delphes_TrackParam(const TVectorD ¶m, bool Units_mm); /// convert track parameters, from delphes to edm4hep conventions - TVectorD Delphes2Edm4hep_TrackParam( const TVectorD& param, bool Units_mm ); +TVectorD Delphes2Edm4hep_TrackParam(const TVectorD ¶m, bool Units_mm); /// convert track covariance matrix, from edm4hep to delphes conventions - TMatrixDSym Edm4hep2Delphes_TrackCovMatrix( const std::array& covMatrix, bool Units_mm ); +TMatrixDSym +Edm4hep2Delphes_TrackCovMatrix(const std::array &covMatrix, + bool Units_mm); #if __has_include("edm4hep/CovMatrix6f.h") - TMatrixDSym Edm4hep2Delphes_TrackCovMatrix( const edm4hep::CovMatrix6f& covMatrix, bool Units_mm ); +TMatrixDSym +Edm4hep2Delphes_TrackCovMatrix(const edm4hep::CovMatrix6f &covMatrix, + bool Units_mm); #endif /// convert track covariance matrix, from delphes to edm4hep conventions - std::array Delphes2Edm4hep_TrackCovMatrix( const TMatrixDSym& cov, bool Units_mm ) ; - - - /// --- Internal methods needed by the code of Franco B: - TVectorD get_trackParam( edm4hep::TrackState & atrack, bool Units_mm = false) ; - TMatrixDSym get_trackCov( const edm4hep::TrackState & atrack, bool Units_mm = false) ; - - TVectorD ParToACTS(TVectorD Par); - TMatrixDSym CovToACTS(TMatrixDSym Cov,TVectorD Par); +std::array Delphes2Edm4hep_TrackCovMatrix(const TMatrixDSym &cov, + bool Units_mm); +/// --- Internal methods needed by the code of Franco B: +TVectorD get_trackParam(edm4hep::TrackState &atrack, bool Units_mm = false); +TMatrixDSym get_trackCov(const edm4hep::TrackState &atrack, + bool Units_mm = false); +TVectorD ParToACTS(TVectorD Par); +TMatrixDSym CovToACTS(TMatrixDSym Cov, TVectorD Par); -}//end NS VertexingUtils +} // namespace VertexingUtils -}//end NS FCCAnalyses +} // namespace FCCAnalyses #endif diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 025cb050042..0de05fd85c7 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -1,173 +1,209 @@ #include "FCCAnalyses/MCParticle.h" -#include #include +#include #include +namespace FCCAnalyses { -namespace FCCAnalyses{ - -namespace MCParticle{ - +namespace MCParticle { -ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec & in){ +ROOT::VecOps::RVec selByPredicate::operator()( + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); - for (auto & p : in) { - if (m_predicate(p)) result.emplace_back(p); - } - return result; + for (auto &p : in) { + if (m_predicate(p)) + result.emplace_back(p); + } + return result; } -ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec& indices, const ROOT::VecOps::RVec &in){ +ROOT::VecOps::RVec selByPredicate::operator()( + const ROOT::VecOps::RVec &indices, + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); for (int index : indices) { - if (index < 0 || index >= in.size()) continue; - if (m_predicate(in[index])) result.emplace_back(index); - } - return result; -} -ROOT::VecOps::RVec> selByPredicate::operator() (const ROOT::VecOps::RVec>& setsOfIndices, const ROOT::VecOps::RVec &in){ - ROOT::VecOps::RVec> result(setsOfIndices.size()); - for (int elem = 0; elem < setsOfIndices.size(); ++elem){ - result[elem] = this->operator()(setsOfIndices[elem], in); + if (index < 0 || index >= in.size()) + continue; + if (m_predicate(in[index])) + result.emplace_back(index); } - return result; -} - -sel_pt::sel_pt(float arg_min_pt) : - selByPredicate([arg_min_pt](const edm4hep::MCParticleData & p)->bool{ - return (p.momentum.x*p.momentum.x + p.momentum.y*p.momentum.y > arg_min_pt*arg_min_pt); - }){ -} - -sel_eta::sel_eta(float arg_max_eta) : - selByPredicate([arg_max_eta](const edm4hep::MCParticleData & p)->bool{ - ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); - return std::abs(vec.Eta()) < std::abs(arg_max_eta); - }){ -} - -sel_genStatus::sel_genStatus(int arg_status): - selByPredicate([arg_status](const edm4hep::MCParticleData & p)->bool{ - return p.generatorStatus == arg_status; - }){ -} - -sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate): - selByPredicate([arg_pdg, arg_chargeconjugate](const edm4hep::MCParticleData & p)->bool{ - if (arg_chargeconjugate) return std::abs( p.PDG ) == std::abs( arg_pdg); - else return p.PDG == arg_pdg; - }){ -} - -sel_charged::sel_charged(): - selByPredicate([](const edm4hep::MCParticleData & p)->bool{ - // try to avoid floating comp to zero - // and thank you for the person who gave some neutral particles a -999 charge! - return std::abs(p.charge) > 1e-6 && p.charge != -999; - }){ + return result; } +ROOT::VecOps::RVec> selByPredicate::operator()( + const ROOT::VecOps::RVec> &setsOfIndices, + const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec> result(setsOfIndices.size()); + for (int elem = 0; elem < setsOfIndices.size(); ++elem) { + result[elem] = this->operator()(setsOfIndices[elem], in); + } + return result; +} + +sel_pt::sel_pt(float arg_min_pt) + : selByPredicate([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { + return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > + arg_min_pt * arg_min_pt); + }) {} + +sel_eta::sel_eta(float arg_max_eta) + : selByPredicate([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { + ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, + p.mass); + return std::abs(vec.Eta()) < std::abs(arg_max_eta); + }) {} + +sel_genStatus::sel_genStatus(int arg_status) + : selByPredicate([arg_status](const edm4hep::MCParticleData &p) -> bool { + return p.generatorStatus == arg_status; + }) {} + +sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) + : selByPredicate([arg_pdg, arg_chargeconjugate]( + const edm4hep::MCParticleData &p) -> bool { + if (arg_chargeconjugate) + return std::abs(p.PDG) == std::abs(arg_pdg); + else + return p.PDG == arg_pdg; + }) {} + +sel_charged::sel_charged() + : selByPredicate([](const edm4hep::MCParticleData &p) -> bool { + // try to avoid floating comp to zero + // and thank you for the person who gave some neutral particles a -999 + // charge! + return std::abs(p.charge) > 1e-6 && p.charge != -999; + }) {} + +get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf) { + m_mother = arg_mother; + m_daughters = arg_daughters; + m_inf = arg_inf; +}; +bool get_decay::operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - -get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf){m_mother=arg_mother; m_daughters=arg_daughters; m_inf=arg_inf;}; -bool get_decay::operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind){ - - bool result=false; + bool result = false; for (size_t i = 0; i < in.size(); ++i) { - if (in[i].PDG!=m_mother)continue; - int ndaughters=0; - for (unsigned j = in.at(i).daughters_begin; j != in.at(i).daughters_end; ++j) { - if (std::abs(in[ind.at(j)].PDG)==m_daughters && m_inf==false)ndaughters+=1; - else if (std::abs(in[ind.at(j)].PDG)<=m_daughters && m_inf==true)ndaughters+=1; + if (in[i].PDG != m_mother) + continue; + int ndaughters = 0; + for (unsigned j = in.at(i).daughters_begin; j != in.at(i).daughters_end; + ++j) { + if (std::abs(in[ind.at(j)].PDG) == m_daughters && m_inf == false) + ndaughters += 1; + else if (std::abs(in[ind.at(j)].PDG) <= m_daughters && m_inf == true) + ndaughters += 1; } - //if (ndaughters>1){ - if (ndaughters>=1){ - result=true; + // if (ndaughters>1){ + if (ndaughters >= 1) { + result = true; return result; } } return result; } - -filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs){m_pdgid = arg_pdgid; m_abs = arg_abs;}; -bool filter_pdgID::operator() (ROOT::VecOps::RVec in) { +filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs) { + m_pdgid = arg_pdgid; + m_abs = arg_abs; +}; +bool filter_pdgID::operator()(ROOT::VecOps::RVec in) { for (size_t i = 0; i < in.size(); ++i) { - auto & p = in[i]; - if ((m_abs && abs(p.PDG) == m_pdgid) || (p.PDG == m_pdgid)) return true; + auto &p = in[i]; + if ((m_abs && abs(p.PDG) == m_pdgid) || (p.PDG == m_pdgid)) + return true; } return false; } - -get_EventPrimaryVertex::get_EventPrimaryVertex( int arg_genstatus) { m_genstatus = arg_genstatus; }; -TVector3 get_EventPrimaryVertex::operator() ( ROOT::VecOps::RVec in ) { - TVector3 result(-1e12,-1e12,-1e12); - int i=0; - for (auto & p: in) { - i++; - if ( p.generatorStatus == m_genstatus ) { // generator status code for the incoming particles of the hardest subprocess - TVector3 res( p.vertex.x, p.vertex.y, p.vertex.z ); - result = res; - break; - } - } +get_EventPrimaryVertex::get_EventPrimaryVertex(int arg_genstatus) { + m_genstatus = arg_genstatus; +}; +TVector3 get_EventPrimaryVertex::operator()( + ROOT::VecOps::RVec in) { + TVector3 result(-1e12, -1e12, -1e12); + int i = 0; + for (auto &p : in) { + i++; + if (p.generatorStatus == + m_genstatus) { // generator status code for the incoming particles of + // the hardest subprocess + TVector3 res(p.vertex.x, p.vertex.y, p.vertex.z); + result = res; + break; + } + } return result; } get_EventPrimaryVertexP4::get_EventPrimaryVertexP4() {}; -TLorentzVector get_EventPrimaryVertexP4::operator() ( ROOT::VecOps::RVec in ) { - TLorentzVector result(-1e12,-1e12,-1e12,-1e12); +TLorentzVector get_EventPrimaryVertexP4::operator()( + ROOT::VecOps::RVec in) { + TLorentzVector result(-1e12, -1e12, -1e12, -1e12); Bool_t found_py8 = false; - //std::cout<<"-------------------------------------------"< 1.e-12 ) { // generator status code for the incoming particles of the hardest subprocess - // vertex.time is in s, convert in mm here. - TLorentzVector res( p.vertex.x, p.vertex.y, p.vertex.z, p.time * 1.0e3 * 2.99792458e+8); - result = res; - break; - } + // std::cout<<"-------------------------------------------"< 1.e-12) { // generator status code for the incoming + // particles of the hardest subprocess + // vertex.time is in s, convert in mm here. + TLorentzVector res(p.vertex.x, p.vertex.y, p.vertex.z, + p.time * 1.0e3 * 2.99792458e+8); + result = res; + break; } - } - //std::cout< get_tree::operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind){ +ROOT::VecOps::RVec +get_tree::operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { ROOT::VecOps::RVec result; - auto & particle = in[m_index]; - - //for (unsigned j = in.at(i).parents_begin; j != in.at(i).parents_end; ++j){ - // if - // result.push_back(ind.at(j)); + auto &particle = in[m_index]; + // for (unsigned j = in.at(i).parents_begin; j != in.at(i).parents_end; ++j){ + // if + // result.push_back(ind.at(j)); - std::cout << "Thomas logic"< get_tree::operator() (ROOT::VecOps::RVec get_pt(ROOT::VecOps::RVec in){ - ROOT::VecOps::RVec result; - for (size_t i = 0; i < in.size(); ++i) { - result.push_back(sqrt(in[i].momentum.x * in[i].momentum.x + in[i].momentum.y * in[i].momentum.y)); - } - return result; +ROOT::VecOps::RVec +get_pt(ROOT::VecOps::RVec in) { + ROOT::VecOps::RVec result; + for (size_t i = 0; i < in.size(); ++i) { + result.push_back(sqrt(in[i].momentum.x * in[i].momentum.x + + in[i].momentum.y * in[i].momentum.y)); + } + return result; } -ROOT::VecOps::RVec mergeParticles(ROOT::VecOps::RVec x, ROOT::VecOps::RVec y) { - //to be keept as std::vector +ROOT::VecOps::RVec +mergeParticles(ROOT::VecOps::RVec x, + ROOT::VecOps::RVec y) { + // to be keept as std::vector std::vector result; result.reserve(x.size() + y.size()); - result.insert( result.end(), x.begin(), x.end() ); - result.insert( result.end(), y.begin(), y.end() ); + result.insert(result.end(), x.begin(), x.end()); + result.insert(result.end(), y.begin(), y.end()); return ROOT::VecOps::RVec(result); } - -ROOT::VecOps::RVec get_time(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_time(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.time); } return result; } -ROOT::VecOps::RVec get_pdg(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_pdg(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.PDG); } return result; } -ROOT::VecOps::RVec get_genStatus(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_genStatus(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.generatorStatus); } return result; } -ROOT::VecOps::RVec get_simStatus(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_simStatus(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.simulatorStatus); } return result; } -ROOT::VecOps::RVec get_vertex(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_vertex(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.vertex); } return result; } -ROOT::VecOps::RVec get_vertex_x(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_vertex_x(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.vertex.x); } return result; } -ROOT::VecOps::RVec get_vertex_y(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_vertex_y(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.vertex.y); } return result; } -ROOT::VecOps::RVec get_vertex_z(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_vertex_z(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.vertex.z); } return result; } -ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_endPoint(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.endpoint); } return result; @@ -283,61 +327,68 @@ ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind ) { - // ( carefull : if a Bs has oscillated into a Bsbar, this returns the production vertex of the Bsbar ) +ROOT::VecOps::RVec +get_endPoint(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { + // ( carefull : if a Bs has oscillated into a Bsbar, this returns the + // production vertex of the Bsbar ) ROOT::VecOps::RVec result; - for (auto & p: in) { - edm4hep::Vector3d vertex(1e12, 1e12, 1e12); // a default value for stable particles - int db = p.daughters_begin ; + for (auto &p : in) { + edm4hep::Vector3d vertex(1e12, 1e12, + 1e12); // a default value for stable particles + int db = p.daughters_begin; int de = p.daughters_end; - if (db != de) { // particle unstable - int d1 = ind[db] ; // first daughter - if ( d1 >= 0 && d1 < in.size() ) { - vertex = in.at(d1).vertex ; - } + if (db != de) { // particle unstable + int d1 = ind[db]; // first daughter + if (d1 >= 0 && d1 < in.size()) { + vertex = in.at(d1).vertex; + } } result.push_back(vertex); } return result; } - - -ROOT::VecOps::RVec get_endPoint_x(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_endPoint_x(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.endpoint.x); } return result; } -ROOT::VecOps::RVec get_endPoint_y(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_endPoint_y(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.endpoint.y); } return result; } -ROOT::VecOps::RVec get_endPoint_z(ROOT::VecOps::RVec in){ +ROOT::VecOps::RVec +get_endPoint_z(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.endpoint.z); } return result; } -ROOT::VecOps::RVec get_mass(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_mass(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.mass); } return result; } -ROOT::VecOps::RVec get_eta(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_eta(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Eta()); @@ -345,9 +396,10 @@ ROOT::VecOps::RVec get_eta(ROOT::VecOps::RVec in return result; } -ROOT::VecOps::RVec get_phi(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_phi(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Phi()); @@ -355,9 +407,10 @@ ROOT::VecOps::RVec get_phi(ROOT::VecOps::RVec in return result; } -ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_e(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.E()); @@ -365,9 +418,10 @@ ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in) return result; } -ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_p(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.P()); @@ -375,41 +429,46 @@ ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in) return result; } -ROOT::VecOps::RVec get_px(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_px(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.momentum.x); } return result; } -ROOT::VecOps::RVec get_py(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_py(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.momentum.y); } return result; } -ROOT::VecOps::RVec get_pz(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_pz(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.momentum.z); } return result; } -ROOT::VecOps::RVec get_charge(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_charge(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { result.push_back(p.charge); } return result; } -ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_y(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Rapidity()); @@ -417,9 +476,10 @@ ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in) return result; } -ROOT::VecOps::RVec get_theta(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_theta(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Theta()); @@ -427,9 +487,10 @@ ROOT::VecOps::RVec get_theta(ROOT::VecOps::RVec return result; } -ROOT::VecOps::RVec get_tlv(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec +get_tlv(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto & p: in) { + for (auto &p : in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv); @@ -438,104 +499,118 @@ ROOT::VecOps::RVec get_tlv(ROOT::VecOps::RVec x) { - int result = x.size(); + int result = x.size(); return result; } - - - - -ROOT::VecOps::RVec get_parentid(ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec mc, ROOT::VecOps::RVec parents){ +ROOT::VecOps::RVec +get_parentid(ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents) { ROOT::VecOps::RVec result; /*std::cout <<"================== Full Truth=================" <1) { - //std::cout << "-999" << std::endl; + // std::cout << mc.at(mcind.at(i)).parents_begin <<"---"<< + // mc.at(mcind.at(i)).parents_end<< std::endl; + if (mc.at(mcind.at(i)).parents_end - mc.at(mcind.at(i)).parents_begin > 1) { + // std::cout << "-999" << std::endl; result.push_back(-999); - } - else { - //std::cout << "not -999 "<< parents.at(mc.at(mcind.at(i)).parents_begin) << std::endl; + } else { + // std::cout << "not -999 "<< parents.at(mc.at(mcind.at(i)).parents_begin) + // << std::endl; result.push_back(parents.at(mc.at(mcind.at(i)).parents_begin)); } } return result; } - // ---------------------------------------------------------------------------------------------------------------------------------- // returns one MCParticle selected by its index in the particle block -edm4hep::MCParticleData sel_byIndex( int idx, ROOT::VecOps::RVec in) { - edm4hep::MCParticleData dummy; - if ( idx >= 0 && idx < in.size() ) { - return in.at(idx) ; - } - else { - std::cout << " !!!! in sel_byIndex : index = " << idx << " is larger than the size of the MCParticle block " << in.size() << std::endl; - } - return dummy; +edm4hep::MCParticleData +sel_byIndex(int idx, ROOT::VecOps::RVec in) { + edm4hep::MCParticleData dummy; + if (idx >= 0 && idx < in.size()) { + return in.at(idx); + } else { + std::cout << " !!!! in sel_byIndex : index = " << idx + << " is larger than the size of the MCParticle block " + << in.size() << std::endl; + } + return dummy; } - // ---------------------------------------------------------------------------------------------------------------------------------- -std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { +std::vector get_list_of_stable_particles_from_decay( + int i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { std::vector res; // i = index of a MC particle in the Particle block // in = the Particle collection // ind = the block with the indices for the daughters, Particle#1.index - // returns a vector with the indices (in the Particle block) of the stable daughters of the particle i, - // from the complete decay chain. + // returns a vector with the indices (in the Particle block) of the stable + // daughters of the particle i, from the complete decay chain. - if ( i < 0 || i >= in.size() ) return res; + if (i < 0 || i >= in.size()) + return res; - int db = in.at(i).daughters_begin ; + int db = in.at(i).daughters_begin; int de = in.at(i).daughters_end; - if ( db != de ) {// particle is unstable - //int d1 = ind[db] ; - //int d2 = ind[de-1]; - //for (int idaughter = d1; idaughter <= d2; idaughter++) { + if (db != de) { // particle is unstable + // int d1 = ind[db] ; + // int d2 = ind[de-1]; + // for (int idaughter = d1; idaughter <= d2; idaughter++) { for (int id = db; id < de; id++) { - int idaughter = ind[ id ]; + int idaughter = ind[id]; // prevent endless loop in case of looping MC record - if (idaughter == i) continue; - std::vector rr = get_list_of_stable_particles_from_decay( idaughter, in, ind) ; - res.insert( res.end(), rr.begin(), rr.end() ); + if (idaughter == i) + continue; + std::vector rr = + get_list_of_stable_particles_from_decay(idaughter, in, ind); + res.insert(res.end(), rr.begin(), rr.end()); } - } - else { // particle is stable - res.push_back( i ) ; - return res ; + } else { // particle is stable + res.push_back(i); + return res; } return res; } // ---------------------------------------------------------------------------------------------------------------------------------- -std::vector get_list_of_particles_from_decay(int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { +std::vector +get_list_of_particles_from_decay(int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { std::vector res; @@ -543,178 +618,201 @@ std::vector get_list_of_particles_from_decay(int i, ROOT::VecOps::RVec= in.size() ) return res; + if (i < 0 || i >= in.size()) + return res; - int db = in.at(i).daughters_begin ; + int db = in.at(i).daughters_begin; int de = in.at(i).daughters_end; - if ( db == de ) return res; // particle is stable - //int d1 = ind[db] ; - //int d2 = ind[de-1]; - //for (int idaughter = d1; idaughter <= d2; idaughter++) { - //res.push_back( idaughter); + if (db == de) + return res; // particle is stable + // int d1 = ind[db] ; + // int d2 = ind[de-1]; + // for (int idaughter = d1; idaughter <= d2; idaughter++) { + // res.push_back( idaughter); for (int id = db; id < de; id++) { - res.push_back( ind[id] ) ; + res.push_back(ind[id]); } return res; } -ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays(ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec> +get_lists_of_stable_particles_from_decays( + ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - ROOT::VecOps::RVec> ret; - ret.reserve(i.size()); - for (int ix : i){ - ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); + ROOT::VecOps::RVec> ret; + ret.reserve(i.size()); + for (int ix : i) { + ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); } - return ret; + return ret; } - // ---------------------------------------------------------------------------------------------------------------------------------- // obsolete: keep for the while, for backward compatibility -std::vector list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { - std::cout << " -------- OBSOLETE ----- call to get_list_of_stable_particles_from_decay , please update your code ----- " << std::endl; - return get_list_of_stable_particles_from_decay( i, in, ind ); +std::vector list_of_stable_particles_from_decay( + int i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { + std::cout << " -------- OBSOLETE ----- call to " + "get_list_of_stable_particles_from_decay , please update your " + "code ----- " + << std::endl; + return get_list_of_stable_particles_from_decay(i, in, ind); } -std::vector list_of_particles_from_decay(int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { - std::cout << " -------- OBSOLETE ----- call to get_list_of_particles_from_decay , please update your code ----- " << std::endl; - return get_list_of_particles_from_decay( i, in, ind ); +std::vector +list_of_particles_from_decay(int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { + std::cout + << " -------- OBSOLETE ----- call to get_list_of_particles_from_decay " + ", please update your code ----- " + << std::endl; + return get_list_of_particles_from_decay(i, in, ind); } - - - - - - // ---------------------------------------------------------------------------------------------------------------------------------- -ROOT::VecOps::RVec get_indices_MotherByIndex ( int imother, - std::vector m_pdg_daughters, - bool m_stableDaughters, - bool m_chargeConjugateDaughters, - bool m_inclusiveDecay, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec get_indices_MotherByIndex( + int imother, std::vector m_pdg_daughters, bool m_stableDaughters, + bool m_chargeConjugateDaughters, bool m_inclusiveDecay, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - // Look for a specific decay specified by the mother index in the Particle block, - // and by the PDG_ids of the daughters - // If m_inclusiveDecay is true, then at least this list of daughters must be included in the decay - // Returns a vector with the indices, in the Particle block, of the mother and of - // the daughters - in the order defined by std::vector pdg_daughters. + // Look for a specific decay specified by the mother index in the Particle + // block, and by the PDG_ids of the daughters If m_inclusiveDecay is true, + // then at least this list of daughters must be included in the decay Returns + // a vector with the indices, in the Particle block, of the mother and of the + // daughters - in the order defined by std::vector pdg_daughters. + ROOT::VecOps::RVec result; - ROOT::VecOps::RVec result; - - std::vector products ; - if ( m_stableDaughters ) { - products = get_list_of_stable_particles_from_decay( imother, in, ind ) ; - } - else { - products = get_list_of_particles_from_decay( imother, in, ind ) ; + std::vector products; + if (m_stableDaughters) { + products = get_list_of_stable_particles_from_decay(imother, in, ind); + } else { + products = get_list_of_particles_from_decay(imother, in, ind); } std::vector found; - for (auto & pdg_d: m_pdg_daughters ) { - for (auto & idx_d: products) { - if ( (m_chargeConjugateDaughters && abs(in[idx_d].PDG) == abs(pdg_d)) || in[idx_d].PDG == pdg_d) { - // careful, there can be several particles with the same PDG ! - if (std::find(found.begin(), found.end(), idx_d) == found.end()) { // idx_d has NOT already been "used" - found.push_back( idx_d ); + for (auto &pdg_d : m_pdg_daughters) { + for (auto &idx_d : products) { + if ((m_chargeConjugateDaughters && abs(in[idx_d].PDG) == abs(pdg_d)) || + in[idx_d].PDG == pdg_d) { + // careful, there can be several particles with the same PDG ! + if (std::find(found.begin(), found.end(), idx_d) == + found.end()) { // idx_d has NOT already been "used" + found.push_back(idx_d); break; - } + } } } } - if ( (m_inclusiveDecay && found.size() >= m_pdg_daughters.size() && products.size() >= m_pdg_daughters.size()) || //for inclusive decay: at least this list of daughters - (!m_inclusiveDecay && found.size() == m_pdg_daughters.size() && products.size() == m_pdg_daughters.size()) ) //for exclusive decay: exactly this list of daughters - { // all daughters have been found. That's the decay mode looked for. - result.push_back( imother ); - for ( auto & idx_d: found) { // use "found" and not "products", to get the right ordering - result.push_back( idx_d ); - } + if ((m_inclusiveDecay && found.size() >= m_pdg_daughters.size() && + products.size() >= + m_pdg_daughters.size()) || // for inclusive decay: at least this list + // of daughters + (!m_inclusiveDecay && found.size() == m_pdg_daughters.size() && + products.size() == + m_pdg_daughters + .size())) // for exclusive decay: exactly this list of daughters + { // all daughters have been found. That's the decay mode looked for. + result.push_back(imother); + for (auto &idx_d : + found) { // use "found" and not "products", to get the right ordering + result.push_back(idx_d); } + } return result; - } -ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( int imother, - std::vector m_pdg_daughters, - bool m_stableDaughters, - ROOT::VecOps::RVec in , - ROOT::VecOps::RVec ind) { - return get_indices_MotherByIndex( - imother, - m_pdg_daughters, - m_stableDaughters, - false /* m_chargeConjuigateDaughters */, - false /* m_inclusiveDecay */, - in, - ind); +ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( + int imother, std::vector m_pdg_daughters, bool m_stableDaughters, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { + return get_indices_MotherByIndex(imother, m_pdg_daughters, m_stableDaughters, + false /* m_chargeConjuigateDaughters */, + false /* m_inclusiveDecay */, in, ind); } // ---------------------------------------------------------------------------------------------------------------------------------- -get_indices::get_indices( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugateMother, bool chargeConjugateDaughters, bool inclusiveDecay) { +get_indices::get_indices(int pdg_mother, std::vector pdg_daughters, + bool stableDaughters, bool chargeConjugateMother, + bool chargeConjugateDaughters, bool inclusiveDecay) { m_pdg_mother = pdg_mother; m_pdg_daughters = pdg_daughters; m_stableDaughters = stableDaughters; m_chargeConjugateMother = chargeConjugateMother; m_chargeConjugateDaughters = chargeConjugateDaughters; m_inclusiveDecay = inclusiveDecay; -} ; - -ROOT::VecOps::RVec get_indices::operator() ( ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { +}; - // Look for a specific decay specified by the mother PDG_id and - // the PDG_ids of the daughters - // Returns a vector with the indices, in the Particle block, of the mother and of - // the daughters - in the order defined by std::vector pdg_daughters. - // - // In case there are several such decays in the event, keep only the first one. +ROOT::VecOps::RVec +get_indices::operator()(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - ROOT::VecOps::RVec result; + // Look for a specific decay specified by the mother PDG_id and + // the PDG_ids of the daughters + // Returns a vector with the indices, in the Particle block, of the mother and + // of the daughters - in the order defined by std::vector pdg_daughters. + // + // In case there are several such decays in the event, keep only the first + // one. - for ( int imother =0; imother < in.size(); imother ++){ - int pdg = in[imother].PDG ; - bool found_a_mother = false; - if ( ! m_chargeConjugateMother ) found_a_mother = ( pdg == m_pdg_mother ); - if ( m_chargeConjugateMother ) found_a_mother = ( abs(pdg) == abs(m_pdg_mother) ) ; - if ( ! found_a_mother ) continue; + ROOT::VecOps::RVec result; - ROOT::VecOps::RVec a = get_indices_MotherByIndex( imother, m_pdg_daughters, m_stableDaughters, m_chargeConjugateDaughters, m_inclusiveDecay, in, ind ); - if ( a.size() != 0 ) { - result = a; - break; // return the first decay found - } + for (int imother = 0; imother < in.size(); imother++) { + int pdg = in[imother].PDG; + bool found_a_mother = false; + if (!m_chargeConjugateMother) + found_a_mother = (pdg == m_pdg_mother); + if (m_chargeConjugateMother) + found_a_mother = (abs(pdg) == abs(m_pdg_mother)); + if (!found_a_mother) + continue; - } - return result; + ROOT::VecOps::RVec a = get_indices_MotherByIndex( + imother, m_pdg_daughters, m_stableDaughters, m_chargeConjugateDaughters, + m_inclusiveDecay, in, ind); + if (a.size() != 0) { + result = a; + break; // return the first decay found + } + } + return result; } -get_indices_ExclusiveDecay::get_indices_ExclusiveDecay( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugate) : get_indices(pdg_mother, pdg_daughters, stableDaughters, chargeConjugate, chargeConjugate, false) { -}; - +get_indices_ExclusiveDecay::get_indices_ExclusiveDecay( + int pdg_mother, std::vector pdg_daughters, bool stableDaughters, + bool chargeConjugate) + : get_indices(pdg_mother, pdg_daughters, stableDaughters, chargeConjugate, + chargeConjugate, false) {}; // -------------------------------------------------------------------------------------------------- -ROOT::VecOps::RVec AngleBetweenTwoMCParticles( ROOT::VecOps::RVec p1, ROOT::VecOps::RVec p2 ) { +ROOT::VecOps::RVec +AngleBetweenTwoMCParticles(ROOT::VecOps::RVec p1, + ROOT::VecOps::RVec p2) { ROOT::VecOps::RVec result; - if ( p1.size() != p2.size() ) { - std::cout << " !!! in AngleBetweenTwoMCParticles: the arguments p1 and p2 should have the same size " << std::endl; - return result; + if (p1.size() != p2.size()) { + std::cout << " !!! in AngleBetweenTwoMCParticles: the arguments p1 and p2 " + "should have the same size " + << std::endl; + return result; } - for (int i=0; i < p1.size(); i++) { - TVector3 q1( p1[i].momentum.x, p1[i].momentum.y, p1[i].momentum.z ); - TVector3 q2( p2[i].momentum.x, p2[i].momentum.y, p2[i].momentum.z ); - float delta = fabs( q1.Angle( q2 ) ) ; - result.push_back( delta ); + for (int i = 0; i < p1.size(); i++) { + TVector3 q1(p1[i].momentum.x, p1[i].momentum.y, p1[i].momentum.z); + TVector3 q2(p2[i].momentum.x, p2[i].momentum.y, p2[i].momentum.z); + float delta = fabs(q1.Angle(q2)); + result.push_back(delta); } return result; @@ -722,90 +820,100 @@ ROOT::VecOps::RVec AngleBetweenTwoMCParticles( ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind){ + const ROOT::VecOps::RVec &ind) { - // std::cout << std::endl << " enter in MCParticle::get_lepton_origin PDG = " << p.PDG << std::endl; + // std::cout << std::endl << " enter in MCParticle::get_lepton_origin PDG = + // " << p.PDG << std::endl; - int pdg = std::abs( p.PDG ) ; - if ( pdg != 11 && pdg != 13 && pdg != 15 ) return -1; + int pdg = std::abs(p.PDG); + if (pdg != 11 && pdg != 13 && pdg != 15) + return -1; - int result = 0; + int result = 0; - // std::cout << " p.parents_begin p.parents_end " << p.parents_begin << " " << p.parents_end << std::endl; - for (unsigned j = p.parents_begin; j != p.parents_end; ++j) { - int index = ind.at(j); - int pdg_parent = in.at(index).PDG ; - // std::cout << " parent has pdg = " << in.at(index).PDG << " status = " << in.at(index).generatorStatus << std::endl; - - if ( abs( pdg_parent ) == 23 || abs( pdg_parent ) == 24 ) { - result = pdg_parent ; - //std::cout << " ... Lepton is from W or Z , return code = " << result << std::endl; - break; - } + // std::cout << " p.parents_begin p.parents_end " << p.parents_begin << " " + // << p.parents_end << std::endl; + for (unsigned j = p.parents_begin; j != p.parents_end; ++j) { + int index = ind.at(j); + int pdg_parent = in.at(index).PDG; + // std::cout << " parent has pdg = " << in.at(index).PDG << " status = " + // << in.at(index).generatorStatus << std::endl; - if ( abs( pdg_parent ) == 22 ) { - result = pdg_parent ; - //std::cout << " ... Lepton is from a virtual photon , return code = " << result << std::endl; - break; - } + if (abs(pdg_parent) == 23 || abs(pdg_parent) == 24) { + result = pdg_parent; + // std::cout << " ... Lepton is from W or Z , return code = " << result + // << std::endl; + break; + } - if ( abs( pdg_parent ) == 15 ) { - result = pdg_parent ; - //std::cout << " ... Lepton is from a tau, return code = " << result << std::endl; - break; - } + if (abs(pdg_parent) == 22) { + result = pdg_parent; + // std::cout << " ... Lepton is from a virtual photon , return code = " + // << result << std::endl; + break; + } - if ( abs( pdg_parent ) == 11 ) { // beam particle ? - // beam particles should have generatorStatus = 4, - // but that is not the case in files produced from Whizard + p6 - if ( in.at(index).generatorStatus == 4 || ind.at ( in.at(index).parents_begin ) == 0 ) { - result = 0; - //std::cout << " ... Lepton is from the hard subprocess, return code = " << result << std::endl; - break; - } - } + if (abs(pdg_parent) == 15) { + result = pdg_parent; + // std::cout << " ... Lepton is from a tau, return code = " << result << + // std::endl; + break; + } - if ( pdg == 11 && abs( pdg_parent ) == 13 ) { // mu -> e - result = pdg_parent; - //std::cout << " ... Electron from a muon decay, return code = " << result << std::endl; - break; + if (abs(pdg_parent) == 11) { // beam particle ? + // beam particles should have generatorStatus = 4, + // but that is not the case in files produced from Whizard + p6 + if (in.at(index).generatorStatus == 4 || + ind.at(in.at(index).parents_begin) == 0) { + result = 0; + // std::cout << " ... Lepton is from the hard subprocess, return code = + // " << result << std::endl; + break; } + } - if ( abs( pdg_parent ) == pdg ) { - //std::cout << " ... iterate ... " << std::endl; - return get_lepton_origin( in.at(index), in, ind ); - } - // This must come from a hadron decay + if (pdg == 11 && abs(pdg_parent) == 13) { // mu -> e result = pdg_parent; - //std::cout << " ... Lepton from a hadron decay " << std::endl; + // std::cout << " ... Electron from a muon decay, return code = " << + // result << std::endl; + break; } - return result; -} + if (abs(pdg_parent) == pdg) { + // std::cout << " ... iterate ... " << std::endl; + return get_lepton_origin(in.at(index), in, ind); + } + // This must come from a hadron decay + result = pdg_parent; + // std::cout << " ... Lepton from a hadron decay " << std::endl; + } + return result; +} int get_lepton_origin(int index, const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind){ - if ( index < 0 || index >= in.size() ) return -1; + const ROOT::VecOps::RVec &ind) { + if (index < 0 || index >= in.size()) + return -1; edm4hep::MCParticleData p = in[index]; - return get_lepton_origin( p, in, ind ); + return get_lepton_origin(p, in, ind); } - -ROOT::VecOps::RVec get_leptons_origin(const ROOT::VecOps::RVec &particles, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind) { +ROOT::VecOps::RVec +get_leptons_origin(const ROOT::VecOps::RVec &particles, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind) { ROOT::VecOps::RVec result; result.reserve(particles.size()); for (size_t i = 0; i < particles.size(); ++i) { - auto & p = particles[i]; - int origin = MCParticle::get_lepton_origin( p, in, ind ); - result.push_back( origin ); + auto &p = particles[i]; + int origin = MCParticle::get_lepton_origin(p, in, ind); + result.push_back(origin); } return result; } -}//end NS MCParticle +} // namespace MCParticle -}//end NS FCCAnalyses +} // namespace FCCAnalyses diff --git a/analyzers/dataframe/src/ReconstructedParticle2MC.cc b/analyzers/dataframe/src/ReconstructedParticle2MC.cc index 244b716785c..317e6c77e26 100644 --- a/analyzers/dataframe/src/ReconstructedParticle2MC.cc +++ b/analyzers/dataframe/src/ReconstructedParticle2MC.cc @@ -1,153 +1,143 @@ #include "FCCAnalyses/ReconstructedParticle2MC.h" #include -namespace FCCAnalyses{ - -namespace ReconstructedParticle2MC{ +namespace FCCAnalyses { +namespace ReconstructedParticle2MC { ROOT::VecOps::RVec -getRP2MC_p(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_p(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); + result.resize(reco.size(), -1.); - for (unsigned int i=0; i -getRP2MC_tlv(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_tlv(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),TLorentzVector()); + result.resize(reco.size(), TLorentzVector()); - for (unsigned int i=0; i -getRP2MC_px(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_px(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_py(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_py(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_pz(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_pz(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_pdg(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_pdg(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_charge(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_charge(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_mass(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_mass(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i -getRP2MC_index(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { +getRP2MC_index(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (size_t i=0; i > -getRP2MC_indexVec(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { +ROOT::VecOps::RVec> +getRP2MC_indexVec(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { ROOT::VecOps::RVec> result; - for (size_t i=0; i tmp; result.push_back(tmp); } - for (size_t i=0; i recind, ROOT::VecOps::RVec getRP2MC_index_test(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents) { - std::cout <<"=========NEW EVENT========="< mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents) { + std::cout << "=========NEW EVENT=========" << std::endl; ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (size_t i=0; i-1){ - auto & p_prev = mc.at(result[recind.at(i)]); - auto & p_now = mc.at(mcind.at(i)); - auto & p_reco = reco.at(recind.at(i)); + result.resize(reco.size(), -1.); + for (size_t i = 0; i < recind.size(); i++) { + if (result[recind.at(i)] > -1) { + auto &p_prev = mc.at(result[recind.at(i)]); + auto &p_now = mc.at(mcind.at(i)); + auto &p_reco = reco.at(recind.at(i)); TLorentzVector tlv_prev; TLorentzVector tlv_now; TLorentzVector tlv_reco; - tlv_prev.SetXYZM(p_prev.momentum.x, p_prev.momentum.y, p_prev.momentum.z, p_prev.mass); - tlv_now.SetXYZM(p_now.momentum.x, p_now.momentum.y, p_now.momentum.z, p_now.mass); - tlv_reco.SetXYZM(p_reco.momentum.x, p_reco.momentum.y, p_reco.momentum.z, p_reco.mass); - - std::cout << "reco energy " << tlv_reco.E() << " eta " << tlv_reco.Eta() << " phi " << tlv_reco.Phi() << " previous PDG " << p_prev.PDG << " energy " << tlv_prev.E() << " eta " << tlv_prev.Eta() << " phi " << tlv_prev.Phi() << " dR reco " << tlv_reco.DeltaR(tlv_prev) << " new PDG " << p_now.PDG << " energy " << tlv_now.E() << " eta " << tlv_now.Eta() << " phi " << tlv_now.Phi() << " dR reco " << tlv_reco.DeltaR(tlv_now) < -getRP2MC_parentid (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents){ +getRP2MC_parentid(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); - for (unsigned int i=0; i recind, for (unsigned int i=0; i -getRP2MC_p_func::operator() (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +ROOT::VecOps::RVec getRP2MC_p_func::operator()( + ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(),-1.); + result.resize(reco.size(), -1.); - for (unsigned int i=0; ireco.size()){ - std::cout << recind.size() <<"========="< reco.size()) { + std::cout << recind.size() << "=========" << reco.size() << std::endl; + for (unsigned int i = 0; i < recind.size(); i++) { + TLorentzVector tlv; + tlv.SetXYZM(mc.at(mcind.at(i)).momentum.x, mc.at(mcind.at(i)).momentum.y, + mc.at(mcind.at(i)).momentum.z, mc.at(mcind.at(i)).mass); + TLorentzVector tlv2; + tlv2.SetXYZM( + reco.at(recind.at(i)).momentum.x, reco.at(recind.at(i)).momentum.y, + reco.at(recind.at(i)).momentum.z, reco.at(recind.at(i)).mass); + std::cout << "n mc " << mc.size() << " rec ind " << recind.at(i) + << " reco P " << tlv2.P() << " mc ind " << mcind.at(i) + << " truth P " << tlv.P() << " pdg_id " + << mc.at(mcind.at(i)).PDG << " parent_begin " + << mc.at(mcind.at(i)).parents_begin << " parent_end " + << mc.at(mcind.at(i)).parents_end << " daut_begin " + << mc.at(mcind.at(i)).daughters_begin << " daut_end " + << mc.at(mcind.at(i)).daughters_end << std::endl; + } } return result; } - // ------------------------------------------------------------------------------------------------- // -- select RecoParticles associated with MC particles of a given PDG_id -// Example use case: muons from JPsi, can not use the Muon collection because it oontains only the isolated muons +// Example use case: muons from JPsi, can not use the Muon collection because +// it oontains only the isolated muons -selRP_PDG::selRP_PDG( int arg_pdg, - bool arg_chargedOnly ): m_PDG(arg_pdg), m_chargedOnly(arg_chargedOnly) {} ; -std::vector -selRP_PDG::operator() (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +selRP_PDG::selRP_PDG(int arg_pdg, bool arg_chargedOnly) + : m_PDG(arg_pdg), m_chargedOnly(arg_chargedOnly) {}; +std::vector selRP_PDG::operator()( + ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { std::vector result; - for (int i=0; i -selRP_PDG_index::operator() (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +selRP_PDG_index::selRP_PDG_index(int arg_pdg, bool arg_chargedOnly) + : m_PDG(arg_pdg), m_chargedOnly(arg_chargedOnly) {}; +ROOT::VecOps::RVec selRP_PDG_index::operator()( + ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - for (int i=0; i recind, // -- select RecoParticles associated with a charged hadron : // -- take all charged RecoParticles that are not associated with a MC lepton -std::vector -selRP_ChargedHadrons (ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +std::vector selRP_ChargedHadrons( + ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { std::vector result; - for (int i=0; i recind, // ------------------------------------------------------------------------------------------------- -// -- select indices of RecoParticles associated with a list of MC particles (passed by their index in the Particle block) +// -- select indices of RecoParticles associated with a list of MC particles +// (passed by their index in the Particle block) -ROOT::VecOps::RVec -selRP_indices_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & mc, - bool require_stable) { +ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &mc, + bool require_stable) { - ROOT::VecOps::RVec results; - for ( auto & idx: mcParticles_indices ) { + ROOT::VecOps::RVec results; + for (auto &idx : mcParticles_indices) { // exclude unstable particles - e.g. the list may contain the index of // the mother - // MG: Should we push_back -1 here for consistency? - if (require_stable && mc.at(idx).generatorStatus != 1 ) continue ; + // MG: Should we push_back -1 here for consistency? + if (require_stable && mc.at(idx).generatorStatus != 1) + continue; // is this MC particle associated with a Reco particle : bool found = false; - for (int i=0; i -selRP_matched_to_list( const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & reco, - const ROOT::VecOps::RVec & mc, - bool require_stable) { +ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &reco, + const ROOT::VecOps::RVec &mc, + bool require_stable) { edm4hep::ReconstructedParticleData dummy; dummy.energy = -9999; - dummy.tracks_begin = -9999 ; - - ROOT::VecOps::RVec results; - ROOT::VecOps::RVec indices = selRP_indices_matched_to_list(mcParticles_indices, - recind, - mcind, - mc, - require_stable); - for (int reco_idx : indices){ - if (reco_idx < 0) results.push_back( dummy ); - else results.push_back( reco.at( reco_idx ) ); + dummy.tracks_begin = -9999; + + ROOT::VecOps::RVec results; + ROOT::VecOps::RVec indices = selRP_indices_matched_to_list( + mcParticles_indices, recind, mcind, mc, require_stable); + for (int reco_idx : indices) { + if (reco_idx < 0) + results.push_back(dummy); + else + results.push_back(reco.at(reco_idx)); } return results; - } - - - // ------------------------------------------------------------------------------------------------- -int getTrack2MC_index (int track_index, - ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { +int getTrack2MC_index( + int track_index, ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { int mc_index = -1; - for (int i=0; i #include "TrkUtil.h" // from delphes +#include namespace FCCAnalyses { @@ -26,7 +26,7 @@ TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q) { selTracks::selTracks(float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, float arg_z0sig_max) : m_d0sig_min(arg_d0sig_min), m_d0sig_max(arg_d0sig_max), - m_z0sig_min(arg_z0sig_min), m_z0sig_max(arg_z0sig_max){}; + m_z0sig_min(arg_z0sig_min), m_z0sig_max(arg_z0sig_max) {}; ROOT::VecOps::RVec selTracks::operator()( ROOT::VecOps::RVec recop, ROOT::VecOps::RVec tracks) { @@ -370,11 +370,11 @@ ROOT::VecOps::RVec get_VertexRecoParticlesInd( } ROOT::VecOps::RVec get_VerticesRecoParticlesInd( - ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec vertices, const ROOT::VecOps::RVec &reco) { ROOT::VecOps::RVec result; - for (int j = 0; j < vertices.size(); ++j){ + for (int j = 0; j < vertices.size(); ++j) { ROOT::VecOps::RVec indices_tracks = vertices[j].reco_ind; for (int i = 0; i < indices_tracks.size(); i++) { int tk_index = indices_tracks[i]; @@ -389,29 +389,31 @@ ROOT::VecOps::RVec get_VerticesRecoParticlesInd( } } } - + return result; -} +} -int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, - const ROOT::VecOps::RVec & recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all){ - std::set indicesWeWant; - indicesWeWant.insert(recoParticleIndices.begin(),recoParticleIndices.end()); +int getVertex_matching_recoParticles( + const ROOT::VecOps::RVec &vertices, + const ROOT::VecOps::RVec &recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all) { + std::set indicesWeWant; + indicesWeWant.insert(recoParticleIndices.begin(), recoParticleIndices.end()); // correct for "-1" representing missed tracks in the recoParticleIndices - int correctMissing = indicesWeWant.count(-1); - for (int iVX = 0; iVX < vertices.size(); ++iVX){ - auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX],reco); - int nFound = std::count_if(vxParticleIndices.begin(), vxParticleIndices.end(),[&](int recoIndex){ - return indicesWeWant.count(recoIndex); - }) ; - if (require_all && nFound == indicesWeWant.size() - correctMissing || nFound == vxParticleIndices.size()) return iVX; + int correctMissing = indicesWeWant.count(-1); + for (int iVX = 0; iVX < vertices.size(); ++iVX) { + auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX], reco); + int nFound = std::count_if( + vxParticleIndices.begin(), vxParticleIndices.end(), + [&](int recoIndex) { return indicesWeWant.count(recoIndex); }); + if (require_all && nFound == indicesWeWant.size() - correctMissing || + nFound == vxParticleIndices.size()) + return iVX; } - return -1; + return -1; } - TVectorD ParToACTS(TVectorD Par) { TVectorD pACTS(6); // Return vector From 547242a3aa0c97aa995e21625ddf6aacfdebed40 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Tue, 17 Feb 2026 17:11:16 +0100 Subject: [PATCH 05/13] Revert "clang_format" This reverts commit 24fc8512abfc363a8162d3cea8ecea70124f068f. --- analyzers/dataframe/FCCAnalyses/MCParticle.h | 560 +++++------ .../FCCAnalyses/ReconstructedParticle2MC.h | 321 +++--- analyzers/dataframe/FCCAnalyses/Utils.h | 102 +- .../dataframe/FCCAnalyses/VertexingUtils.h | 682 ++++++------- analyzers/dataframe/src/MCParticle.cc | 942 ++++++++---------- .../dataframe/src/ReconstructedParticle2MC.cc | 514 +++++----- analyzers/dataframe/src/VertexingUtils.cc | 44 +- 7 files changed, 1429 insertions(+), 1736 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index ef24b04c630..43f6d005497 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -1,10 +1,10 @@ -#ifndef MCPARTICLE_ANALYZERS_H -#define MCPARTICLE_ANALYZERS_H +#ifndef MCPARTICLE_ANALYZERS_H +#define MCPARTICLE_ANALYZERS_H #include -#include #include +#include #include "ROOT/RVec.hxx" #include "TLorentzVector.h" @@ -13,7 +13,7 @@ #include "edm4hep/Vector3d.h" #include "edm4hep/Vector3f.h" -namespace FCCAnalyses { +namespace FCCAnalyses{ /** * Analyzers operating on/with Monte Carlo particles. @@ -21,314 +21,246 @@ namespace FCCAnalyses { * This represents a set functions and utilities to access and perform * operations on the MCParticle collection. */ -namespace MCParticle { - -/// Filter events based on a MCParticles PDGID -struct filter_pdgID { - filter_pdgID(int arg_pdgid, bool arg_abs); - int m_pdgid; //> Generator pdgid - bool m_abs; //> Use absolute value for pdgig - bool operator()(ROOT::VecOps::RVec in); -}; - -/// @brief Helper struct to select entries matching a certain predicate. -/// Supports two signatures - either a list of candidates is passed and a list -/// of accepted candidates returned, Or a list of indices in a vector of -/// candidates is passed and a list of accepted indices returned. The latter is -/// more compatible with index-based selection logic. -struct selByPredicate { - selByPredicate( - std::function thePredicate) - : m_predicate(thePredicate) {} - std::function m_predicate; - ROOT::VecOps::RVec - operator()(const ROOT::VecOps::RVec &in); - ROOT::VecOps::RVec - operator()(const ROOT::VecOps::RVec &indices, - const ROOT::VecOps::RVec &in); - ROOT::VecOps::RVec> - operator()(const ROOT::VecOps::RVec> &indices, - const ROOT::VecOps::RVec &in); -}; - -/// select MCParticles with transverse momentum greater than a minimum value -/// [GeV] -struct sel_pt : selByPredicate { - sel_pt(float arg_min_pt); -}; - -/// select MCParticles with absolute pseudorapidity less than a max value -struct sel_eta : selByPredicate { - sel_eta(float arg_max_eta); -}; - -/// select MCParticles with their status -struct sel_genStatus : selByPredicate { - sel_genStatus(int arg_status); -}; - -/// select MCParticles with their PDG id -struct sel_pdgID : selByPredicate { - sel_pdgID(int arg_pdg, bool arg_chargeconjugate); -}; - -/// select MCParticles with a non-zero charge -struct sel_charged : selByPredicate { - sel_charged(); -}; - -/// get MC history tree for a given MCParticle index -struct get_tree { - get_tree(int arg_index); - int m_index; //> MC Particle index to build the tree from - ROOT::VecOps::RVec - operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); -}; - -/// get the decay of a given particle -struct get_decay { - get_decay(int arg_mother, int arg_daughters, bool arg_inf); - int m_mother = 0; //> mother pdg id - int m_daughters = 0; //> daughters pdg id - bool m_inf = false; //> boolean to check if the pdgid is below a value rather - //than equal - bool operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); -}; - -/// return the event primary vertex (mm) -struct get_EventPrimaryVertex { - get_EventPrimaryVertex(int arg_genstatus); - int m_genstatus = - 21; // Pythia8 code of the incoming particles of the hardest subprocess - TVector3 operator()(ROOT::VecOps::RVec in); -}; - -/// return the event primary vertex position and time (mm) -struct get_EventPrimaryVertexP4 { - get_EventPrimaryVertexP4(); - int m_genstatus = - 21; // Pythia8 code of the incoming particles of the hardest subprocess - TLorentzVector operator()(ROOT::VecOps::RVec in); -}; - -/// return a list of indices that correspond to a given MC decay. The list -/// contains the index of the mother, followed by the indices of the daughters, -/// in the order specified. If m_inclusiveDecay is true, the list of daughters -/// is the minimum required for the mother's decay (otherwise, the list is the -/// exact daughters required for the mother's decay). In case there are several -/// such decays in the event, keep only the first one. -struct get_indices { - get_indices(int pdg_mother, std::vector pdg_daughters, - bool stableDaughters, bool chargeConjugateMother, - bool chargeConjugateDaughters, bool inclusiveDecay); - int m_pdg_mother; - std::vector m_pdg_daughters; - bool m_stableDaughters; - bool m_chargeConjugateMother; - bool m_chargeConjugateDaughters; - bool m_inclusiveDecay; - ROOT::VecOps::RVec - operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); -}; - -/// A shorthand for get_indices, with m_chargeConjugateDaughters=false, -/// inclusiveDecay=false -struct get_indices_ExclusiveDecay : get_indices { - get_indices_ExclusiveDecay(int pdg_mother, std::vector pdg_daughters, - bool stableDaughters, bool chargeConjugate); -}; - -/// return a list of indices that correspond to a given MC decay -ROOT::VecOps::RVec get_indices_MotherByIndex( - int imother, std::vector m_pdg_daughters, bool m_stableDaughters, - bool m_chargeConjugateDaughters, bool m_inclusiveDecay, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// a shorthand for get_indices_MotherByIndex with -/// m_chargeConjugateDaughters=false, m_inclusiveDecay =false -ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( - int imother, std::vector m_pdg_daughters, bool m_stableDaughters, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// return the parent index of a given list of MC particles -ROOT::VecOps::RVec -get_parentid(ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents); - -/// return the time of the input MCParticles -ROOT::VecOps::RVec -get_time(ROOT::VecOps::RVec in); - -/// return the PDG of the input MCParticles -ROOT::VecOps::RVec -get_pdg(ROOT::VecOps::RVec in); - -/// return the generator status of the input MCParticles -ROOT::VecOps::RVec -get_genStatus(ROOT::VecOps::RVec in); - -/// return the simulation status of the input MCParticles -ROOT::VecOps::RVec -get_simStatus(ROOT::VecOps::RVec in); - -/// return the production vertex of the input MCParticles -ROOT::VecOps::RVec -get_vertex(ROOT::VecOps::RVec in); - -/// return the production vertex x of the input MCParticles -ROOT::VecOps::RVec -get_vertex_x(ROOT::VecOps::RVec in); - -/// return the production vertex y of the input MCParticles -ROOT::VecOps::RVec -get_vertex_y(ROOT::VecOps::RVec in); - -/// return the production vertex z of the input MCParticles -ROOT::VecOps::RVec -get_vertex_z(ROOT::VecOps::RVec in); - -/// return the end point of the input MCParticles -ROOT::VecOps::RVec -get_endPoint(ROOT::VecOps::RVec in); - -/// return the end point of the input MCParticles (not using the "endpoint" that -/// is currently not filled) -ROOT::VecOps::RVec -get_endPoint(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// return the end point x of the input MCParticles -ROOT::VecOps::RVec -get_endPoint_x(ROOT::VecOps::RVec in); - -/// return the end point y of the input MCParticles -ROOT::VecOps::RVec -get_endPoint_y(ROOT::VecOps::RVec in); - -/// return the z of the input MCParticles -ROOT::VecOps::RVec -get_endPoint_z(ROOT::VecOps::RVec in); - -/// return the transverse momenta of the input MCParticles -ROOT::VecOps::RVec -get_pt(ROOT::VecOps::RVec in); - -/// return the momenta of the input MCParticles -ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in); - -/// return the momenta of the input MCParticles -ROOT::VecOps::RVec -get_px(ROOT::VecOps::RVec in); - -/// return the momenta of the input MCParticles -ROOT::VecOps::RVec -get_py(ROOT::VecOps::RVec in); - -/// return the momenta of the input MCParticles -ROOT::VecOps::RVec -get_pz(ROOT::VecOps::RVec in); - -/// return the pseudo-rapidity of the input MCParticles -ROOT::VecOps::RVec -get_eta(ROOT::VecOps::RVec in); - -/// return the rapidity of the input MCParticles -ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in); - -/// return the theta of the input MCParticles -ROOT::VecOps::RVec -get_theta(ROOT::VecOps::RVec in); - -/// return the phi of the input MCParticles -ROOT::VecOps::RVec -get_phi(ROOT::VecOps::RVec in); - -/// return the energy of the input MCParticles -ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in); - -/// return the masses of the input MCParticles -ROOT::VecOps::RVec -get_mass(ROOT::VecOps::RVec in); - -/// return the charges of the input MCParticles -ROOT::VecOps::RVec -get_charge(ROOT::VecOps::RVec in); - -/// return the TlorentzVector of the input MCParticles -ROOT::VecOps::RVec -get_tlv(ROOT::VecOps::RVec in); - -/// concatenate both input vectors and return the resulting vector -ROOT::VecOps::RVec -mergeParticles(ROOT::VecOps::RVec x, - ROOT::VecOps::RVec y); - -/// return the size of the input collection -int get_n(ROOT::VecOps::RVec in); - -/// return the angle (3D) between two MCParticles : -ROOT::VecOps::RVec -AngleBetweenTwoMCParticles(ROOT::VecOps::RVec p1, - ROOT::VecOps::RVec p2); - -/// return the list of stable particles from the decay of a mother particle, -/// looking at the full decay chain recursively. i is the mother index in the -/// Particle block -std::vector get_list_of_stable_particles_from_decay( - int i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// return the list of stable particles from the decays of a mother particle, -/// looking at the full decay chain recursively. i is the list of mother indices -/// to process in the Particle block. Will return a vector of vectors - each -/// vector is the set of children for one of the mothers in the input vector -ROOT::VecOps::RVec> -get_lists_of_stable_particles_from_decays( - ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// return the list of particles from the decay of a mother particle. i is the -/// mother index in the Particle block. -std::vector -get_list_of_particles_from_decay(int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// returns one MCParticle selected by its index in the particle block -edm4hep::MCParticleData -sel_byIndex(int idx, ROOT::VecOps::RVec in); - -/// obsolete: should use get_list_of_stable_particles_from_decay instead -std::vector list_of_stable_particles_from_decay( - int i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); -/// obsolete: should use get_list_of_particles_from_decay instead -std::vector -list_of_particles_from_decay(int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind); - -/// return the pdg ID of the parent of a lepton (pre-FSR) -int get_lepton_origin(int idx, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - -int get_lepton_origin(const edm4hep::MCParticleData &p, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - -ROOT::VecOps::RVec -get_leptons_origin(const ROOT::VecOps::RVec &particles, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind); - -} // namespace MCParticle - -} // namespace FCCAnalyses +namespace MCParticle{ + + /// Filter events based on a MCParticles PDGID + struct filter_pdgID { + filter_pdgID(int arg_pdgid, bool arg_abs); + int m_pdgid; //> Generator pdgid + bool m_abs;//> Use absolute value for pdgig + bool operator() (ROOT::VecOps::RVec in); + }; + + /// @brief Helper struct to select entries matching a certain predicate. + /// Supports two signatures - either a list of candidates is passed and a list of accepted candidates returned, + /// Or a list of indices in a vector of candidates is passed and a list of accepted indices returned. + /// The latter is more compatible with index-based selection logic. + struct selByPredicate{ + selByPredicate(std::function thePredicate):m_predicate(thePredicate){} + std::function m_predicate; + ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & in); + ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in); + ROOT::VecOps::RVec> operator() (const ROOT::VecOps::RVec> & indices, const ROOT::VecOps::RVec & in); + }; + + /// select MCParticles with transverse momentum greater than a minimum value [GeV] + struct sel_pt : selByPredicate{ + sel_pt(float arg_min_pt); + }; + + /// select MCParticles with absolute pseudorapidity less than a max value + struct sel_eta : selByPredicate { + sel_eta(float arg_max_eta); + }; + + /// select MCParticles with their status + struct sel_genStatus : selByPredicate { + sel_genStatus(int arg_status); + }; + + /// select MCParticles with their PDG id + struct sel_pdgID : selByPredicate { + sel_pdgID(int arg_pdg, bool arg_chargeconjugate); + }; + + /// select MCParticles with a non-zero charge + struct sel_charged : selByPredicate { + sel_charged(); + }; + + /// get MC history tree for a given MCParticle index + struct get_tree{ + get_tree(int arg_index); + int m_index; //> MC Particle index to build the tree from + ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind); + }; + + /// get the decay of a given particle + struct get_decay { + get_decay(int arg_mother, int arg_daughters, bool arg_inf); + int m_mother = 0; //> mother pdg id + int m_daughters = 0;//> daughters pdg id + bool m_inf = false;//> boolean to check if the pdgid is below a value rather than equal + bool operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind); + }; + + /// return the event primary vertex (mm) + struct get_EventPrimaryVertex { + get_EventPrimaryVertex( int arg_genstatus ); + int m_genstatus = 21; // Pythia8 code of the incoming particles of the hardest subprocess + TVector3 operator() (ROOT::VecOps::RVec in); + }; + + /// return the event primary vertex position and time (mm) + struct get_EventPrimaryVertexP4 { + get_EventPrimaryVertexP4(); + int m_genstatus = 21; // Pythia8 code of the incoming particles of the hardest subprocess + TLorentzVector operator() (ROOT::VecOps::RVec in); + }; + + + /// return a list of indices that correspond to a given MC decay. The list contains the index of the mother, followed by the indices of the daughters, in the order specified. If m_inclusiveDecay is true, the list of daughters is the minimum required for the mother's decay (otherwise, the list is the exact daughters required for the mother's decay). In case there are several such decays in the event, keep only the first one. + struct get_indices{ + get_indices( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugateMother, bool chargeConjugateDaughters, bool inclusiveDecay ) ; + int m_pdg_mother; + std::vector m_pdg_daughters; + bool m_stableDaughters; + bool m_chargeConjugateMother; + bool m_chargeConjugateDaughters; + bool m_inclusiveDecay; + ROOT::VecOps::RVec operator() ( ROOT::VecOps::RVec in , ROOT::VecOps::RVec ind); + }; + + /// A shorthand for get_indices, with m_chargeConjugateDaughters=false, inclusiveDecay=false + struct get_indices_ExclusiveDecay: get_indices{ + get_indices_ExclusiveDecay( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugate ) ; + }; + + /// return a list of indices that correspond to a given MC decay + ROOT::VecOps::RVec get_indices_MotherByIndex( int imother, + std::vector m_pdg_daughters, + bool m_stableDaughters, + bool m_chargeConjugateDaughters, + bool m_inclusiveDecay, + ROOT::VecOps::RVec in , + ROOT::VecOps::RVec ind); + + /// a shorthand for get_indices_MotherByIndex with m_chargeConjugateDaughters=false, m_inclusiveDecay =false + ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( int imother, + std::vector m_pdg_daughters, + bool m_stableDaughters, + ROOT::VecOps::RVec in , + ROOT::VecOps::RVec ind); + + /// return the parent index of a given list of MC particles + ROOT::VecOps::RVec get_parentid(ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec mc, ROOT::VecOps::RVec parents); + + /// return the time of the input MCParticles + ROOT::VecOps::RVec get_time(ROOT::VecOps::RVec in); + + /// return the PDG of the input MCParticles + ROOT::VecOps::RVec get_pdg(ROOT::VecOps::RVec in); + + /// return the generator status of the input MCParticles + ROOT::VecOps::RVec get_genStatus(ROOT::VecOps::RVec in); + + /// return the simulation status of the input MCParticles + ROOT::VecOps::RVec get_simStatus(ROOT::VecOps::RVec in); + + /// return the production vertex of the input MCParticles + ROOT::VecOps::RVec get_vertex(ROOT::VecOps::RVec in); + + /// return the production vertex x of the input MCParticles + ROOT::VecOps::RVec get_vertex_x(ROOT::VecOps::RVec in); + + /// return the production vertex y of the input MCParticles + ROOT::VecOps::RVec get_vertex_y(ROOT::VecOps::RVec in); + + /// return the production vertex z of the input MCParticles + ROOT::VecOps::RVec get_vertex_z(ROOT::VecOps::RVec in); + + /// return the end point of the input MCParticles + ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in); + + /// return the end point of the input MCParticles (not using the "endpoint" that is currently not filled) + ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind ); + + /// return the end point x of the input MCParticles + ROOT::VecOps::RVec get_endPoint_x(ROOT::VecOps::RVec in); + + /// return the end point y of the input MCParticles + ROOT::VecOps::RVec get_endPoint_y(ROOT::VecOps::RVec in); + + /// return the z of the input MCParticles + ROOT::VecOps::RVec get_endPoint_z(ROOT::VecOps::RVec in); + + /// return the transverse momenta of the input MCParticles + ROOT::VecOps::RVec get_pt(ROOT::VecOps::RVec in); + + /// return the momenta of the input MCParticles + ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in); + + /// return the momenta of the input MCParticles + ROOT::VecOps::RVec get_px(ROOT::VecOps::RVec in); + + /// return the momenta of the input MCParticles + ROOT::VecOps::RVec get_py(ROOT::VecOps::RVec in); + + /// return the momenta of the input MCParticles + ROOT::VecOps::RVec get_pz(ROOT::VecOps::RVec in); + + /// return the pseudo-rapidity of the input MCParticles + ROOT::VecOps::RVec get_eta(ROOT::VecOps::RVec in); + + /// return the rapidity of the input MCParticles + ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in); + + /// return the theta of the input MCParticles + ROOT::VecOps::RVec get_theta(ROOT::VecOps::RVec in); + + /// return the phi of the input MCParticles + ROOT::VecOps::RVec get_phi(ROOT::VecOps::RVec in); + + /// return the energy of the input MCParticles + ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in); + + /// return the masses of the input MCParticles + ROOT::VecOps::RVec get_mass(ROOT::VecOps::RVec in); + + /// return the charges of the input MCParticles + ROOT::VecOps::RVec get_charge(ROOT::VecOps::RVec in); + + /// return the TlorentzVector of the input MCParticles + ROOT::VecOps::RVec get_tlv(ROOT::VecOps::RVec in); + + /// concatenate both input vectors and return the resulting vector + ROOT::VecOps::RVec mergeParticles(ROOT::VecOps::RVec x, ROOT::VecOps::RVec y); + + /// return the size of the input collection + int get_n(ROOT::VecOps::RVec in); + + /// return the angle (3D) between two MCParticles : + ROOT::VecOps::RVec AngleBetweenTwoMCParticles( ROOT::VecOps::RVec p1, ROOT::VecOps::RVec p2 ); + + /// return the list of stable particles from the decay of a mother particle, looking at the full decay chain recursively. i is the mother index in the Particle block + std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + + /// return the list of stable particles from the decays of a mother particle, looking at the full decay chain recursively. + /// i is the list of mother indices to process in the Particle block. + /// Will return a vector of vectors - each vector is the set of children for one of the mothers in the input vector + ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays( ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + + /// return the list of particles from the decay of a mother particle. i is the mother index in the Particle block. + std::vector get_list_of_particles_from_decay( int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + + /// returns one MCParticle selected by its index in the particle block + edm4hep::MCParticleData sel_byIndex( int idx, ROOT::VecOps::RVec in); + + /// obsolete: should use get_list_of_stable_particles_from_decay instead + std::vector list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + /// obsolete: should use get_list_of_particles_from_decay instead + std::vector list_of_particles_from_decay( int i, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); + + + /// return the pdg ID of the parent of a lepton (pre-FSR) + int get_lepton_origin(int idx, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + + int get_lepton_origin(const edm4hep::MCParticleData &p, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + + ROOT::VecOps::RVec get_leptons_origin(const ROOT::VecOps::RVec &particles, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind); + + +}//end NS MCParticle + +}//end NS FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h index e3470af9f1c..149e2132ba8 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h @@ -1,174 +1,167 @@ -#ifndef RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H -#define RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H +#ifndef RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H +#define RECONSTRUCTEDPARTICLE2MC_ANALYZERS_H #include #include #include "ROOT/RVec.hxx" -#include "TLorentzVector.h" -#include "edm4hep/MCParticleData.h" #include "edm4hep/ReconstructedParticleData.h" +#include "edm4hep/MCParticleData.h" #include "podio/ObjectID.h" +#include "TLorentzVector.h" -namespace FCCAnalyses { - -namespace ReconstructedParticle2MC { - -/// select ReconstructedParticles matched with a MC particle of a given PDG_id -struct selRP_PDG { - selRP_PDG(int arg_PDG, bool arg_chargedOnly); - int m_PDG = 13; - bool m_chargedOnly = true; - std::vector - operator()(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); -}; - -/// select ReconstructedParticles matched with a MC particle of a given PDG_id -struct selRP_PDG_index { - selRP_PDG_index(int arg_PDG, bool arg_chargedOnly); - int m_PDG = 13; - bool m_chargedOnly = true; - ROOT::VecOps::RVec - operator()(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); -}; - -/// select ReconstructedParticles with transverse momentum greater than a -/// minimum value [GeV] -struct getRP2MC_p_func { - ROOT::VecOps::RVec - operator()(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); -}; - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_p(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_px(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_py(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_pz(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_mass(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_charge(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_pdg(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_tlv(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_index(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec> -getRP2MC_indexVec(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_index_test(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents); - -/// Return the D0 of a track to a reconstructed particle -ROOT::VecOps::RVec -getRP2MC_parentid(ROOT::VecOps::RVec recin, ROOT::VecOps::RVec mcin, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents); - -/// select ReconstructedParticles matched with a MC charged hadrons -std::vector selRP_ChargedHadrons( - ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc); - -/// select ReconstructedParticles matched to the MC particles whose indices are -/// passed in a list -/// @param mcParticles_indices indices of the MC particles to look up -/// @param recind: reco index component of the MCRecoAssociations -/// @param mcind: mc index component of the MCRecoAssociations -/// @param reco: full reco particle list (ReconstructedParticles) -/// @param mc: full mc particle list (Particles) -/// @param require_stable: if set to true, will only match stable particles. -/// @return List of ReconstructedParticle candidates with length corresponding -/// to the number of *stable* MC particles in the mcParticles_indices vector. In -/// presence of unstable particles, no 1:1 correspondence. For non-reconstructed -/// stable MC particles, a dummy particle will be inserted. If 1:1 length -/// correspondence is required, set require_stable to false. -ROOT::VecOps::RVec selRP_matched_to_list( - const ROOT::VecOps::RVec &mcParticles_indices, - const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, - const ROOT::VecOps::RVec &reco, - const ROOT::VecOps::RVec &mc, - bool require_stable = true); -/// select indices of ReconstructedParticles matched to the MC particles whose -/// indices are passed in a list -/// @param mcParticles_indices indices of the MC particles to look up -/// @param recind: reco index component of the MCRecoAssociations -/// @param mcind: mc index component of the MCRecoAssociations -/// @param mc: full mc particle list (Particles) -/// @param require_stable: if set to true, will only match stable particles. -/// @return List of ReconstructedParticle candidates with length corresponding -/// to the number of *stable* MC particles in the mcParticles_indices vector. In -/// presence of unstable particles, no 1:1 correspondence. For non-reconstructed -/// stable MC particles, a "-1" entry will be inserted. If 1:1 length -/// correspondence is required, set require_stable to false. -ROOT::VecOps::RVec selRP_indices_matched_to_list( - const ROOT::VecOps::RVec &mcParticles_indices, - const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, - const ROOT::VecOps::RVec &mc, - bool require_stable = true); - -/// return the index of the MC particle that is associated to a given track (via -/// the track-reco association) -int getTrack2MC_index( - int track_index, ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco); - -} // namespace ReconstructedParticle2MC - -} // namespace FCCAnalyses +namespace FCCAnalyses{ + +namespace ReconstructedParticle2MC{ + + /// select ReconstructedParticles matched with a MC particle of a given PDG_id + struct selRP_PDG { + selRP_PDG(int arg_PDG, bool arg_chargedOnly); + int m_PDG = 13 ; + bool m_chargedOnly = true; + std::vector operator() (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) ; + }; + + /// select ReconstructedParticles matched with a MC particle of a given PDG_id + struct selRP_PDG_index { + selRP_PDG_index(int arg_PDG, bool arg_chargedOnly); + int m_PDG = 13 ; + bool m_chargedOnly = true; + ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) ; + }; + + + /// select ReconstructedParticles with transverse momentum greater than a minimum value [GeV] + struct getRP2MC_p_func { + ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + }; + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_p (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_px (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_py (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_pz (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_mass (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_charge (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_pdg (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_tlv (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_index (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec> getRP2MC_indexVec (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco); + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_index_test (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents); + + + /// Return the D0 of a track to a reconstructed particle + ROOT::VecOps::RVec getRP2MC_parentid (ROOT::VecOps::RVec recin, + ROOT::VecOps::RVec mcin, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents); + + /// select ReconstructedParticles matched with a MC charged hadrons + std::vector selRP_ChargedHadrons ( ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) ; + + /// select ReconstructedParticles matched to the MC particles whose indices are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations + /// @param reco: full reco particle list (ReconstructedParticles) + /// @param mc: full mc particle list (Particles) + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a dummy particle will be inserted. If 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & reco, + const ROOT::VecOps::RVec & mc, + bool require_stable = true) ; + /// select indices of ReconstructedParticles matched to the MC particles whose indices are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations + /// @param mc: full mc particle list (Particles) + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a "-1" entry will be inserted. If 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & mc, + bool require_stable = true + ) ; + + /// return the index of the MC particle that is associated to a given track (via the track-reco association) + int getTrack2MC_index ( int track_index, + ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco); + +}//end NS ReconstructedParticle2MC + +}//end NS FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index ad645cb6aaa..70f305faa87 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -1,69 +1,53 @@ -#ifndef UTILS_ANALYZERS_H -#define UTILS_ANALYZERS_H +#ifndef UTILS_ANALYZERS_H +#define UTILS_ANALYZERS_H -#include #include +#include namespace FCCAnalyses { -namespace Utils { + namespace Utils { -template inline auto getsize(T &vec) { return vec.size(); }; -template -inline ROOT::VecOps::RVec> -as_vector(const ROOT::VecOps::RVec &in) { - return ROOT::VecOps::RVec>(1, in); -}; -template -inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec &in) { - ROOT::VecOps::RVec indices(in.size()); - std::iota(indices.begin(), indices.end(), 0); - return indices; -}; -/// @brief count the number of valid (>=0, < size of collection) indices in an -/// index list -/// @param in: index list -/// @param ref: particle vector to which the indices refer. -/// @return integer count of valid indices -template -inline int count_valid_indices(const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ref) { - int maxSize = ref.size(); - return std::count_if(in.begin(), in.end(), [maxSize](const int &i) { - return (i >= 0 && i < maxSize); - }); -}; + template inline auto getsize( T& vec){ return vec.size();}; + template inline ROOT::VecOps::RVec > as_vector(const ROOT::VecOps::RVec& in){return ROOT::VecOps::RVec >(1, in);}; + template inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec indices(in.size()); + std::iota(indices.begin(),indices.end(), 0); + return indices; + }; + /// @brief count the number of valid (>=0, < size of collection) indices in an index list + /// @param in: index list + /// @param ref: particle vector to which the indices refer. + /// @return integer count of valid indices + template inline int count_valid_indices(const ROOT::VecOps::RVec & in, + const ROOT::VecOps::RVec & ref){ + int maxSize = ref.size(); + return std::count_if(in.begin(),in.end(),[maxSize](const int & i){return (i >=0 && i < maxSize);}); + }; -// @brief for a given list of indices, returns a list of particle (copies) -/// @param idx : Indices of desired particles within the full set ("in") -/// @param in : Full set of particles -/// @return A vector of particles with the desired indices. -template -inline ROOT::VecOps::RVec sel_byIndex(const ROOT::VecOps::RVec &idx, - const ROOT::VecOps::RVec &in) { - ROOT::VecOps::RVec found; - for (int index : idx) { - if (index < 0 || index >= in.size()) - continue; - found.push_back(in.at(index)); + // @brief for a given list of indices, returns a list of particle (copies) + /// @param idx : Indices of desired particles within the full set ("in") + /// @param in : Full set of particles + /// @return A vector of particles with the desired indices. + template inline ROOT::VecOps::RVec sel_byIndex( const ROOT::VecOps::RVec & idx, const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec found; + for (int index : idx){ + if (index < 0 || index >= in.size()) continue; + found.push_back(in.at(index)); + } + return found; + } + // @brief merge (concatenate) two collections of arbitrary content + /// @param x : first collection - entries will be copied in-order + /// @param y : second collection - entries will be copied in-order after the last element of the first + /// @return A combined collection of size (x.size()+y.size()), containing the content of x followed by that of y + template inline ROOT::VecOps::RVec merge( const ROOT::VecOps::RVec & x, const ROOT::VecOps::RVec & y){ + ROOT::VecOps::RVec merged; + merged.reserve(x.size()+y.size()); + merged.insert(merged.end(), x.begin(), x.end()); + merged.insert(merged.end(), y.begin(), y.end()); + return merged; + } } - return found; -} -// @brief merge (concatenate) two collections of arbitrary content -/// @param x : first collection - entries will be copied in-order -/// @param y : second collection - entries will be copied in-order after the -/// last element of the first -/// @return A combined collection of size (x.size()+y.size()), containing the -/// content of x followed by that of y -template -inline ROOT::VecOps::RVec merge(const ROOT::VecOps::RVec &x, - const ROOT::VecOps::RVec &y) { - ROOT::VecOps::RVec merged; - merged.reserve(x.size() + y.size()); - merged.insert(merged.end(), x.begin(), x.end()); - merged.insert(merged.end(), y.begin(), y.end()); - return merged; } -} // namespace Utils -} // namespace FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index 5e8cddd194e..f913f0ea0e5 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -1,420 +1,342 @@ -#ifndef VERTEXINGUTILS_ANALYZERS_H -#define VERTEXINGUTILS_ANALYZERS_H +#ifndef VERTEXINGUTILS_ANALYZERS_H +#define VERTEXINGUTILS_ANALYZERS_H #include #include #include "ROOT/RVec.hxx" -#include "edm4hep/MCParticleData.h" #include "edm4hep/ReconstructedParticleData.h" +#include "edm4hep/MCParticleData.h" #include "edm4hep/TrackState.h" -#include "edm4hep/Vertex.h" #include "edm4hep/VertexData.h" +#include "edm4hep/Vertex.h" #include "TLorentzVector.h" -#include "TMatrixDSym.h" -#include "TVector3.h" #include "TVectorD.h" +#include "TVector3.h" +#include "TMatrixDSym.h" #include "fastjet/JetDefinition.hh" -namespace FCCAnalyses { + +namespace FCCAnalyses{ /** * Vertexing utilities. */ -namespace VertexingUtils { - -/// from delphes: returns track state parameters (delphes convention) for a -/// given vertex (x), momentum (p) and charge -TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q); - -/// from delphes: returns the momentum corresponding to a given track state -TVector3 ParToP(TVectorD Par); - -/// Structure to keep useful track information that is related to the vertex -struct FCCAnalysesVertex { - edm4hep::VertexData vertex; - int ntracks; - int mc_ind; /// index in the MC vertex collection if any - ROOT::VecOps::RVec reco_ind; // indices of the tracks fitted to that - // vertex, in the collection of all tracks - ROOT::VecOps::RVec reco_chi2; - ROOT::VecOps::RVec updated_track_momentum_at_vertex; - ROOT::VecOps::RVec updated_track_parameters; - ROOT::VecOps::RVec final_track_phases; -}; - -/// Structure to keep useful information that is related to the V0 -struct FCCAnalysesV0 { - ROOT::VecOps::RVec vtx; // vertex object - ROOT::VecOps::RVec pdgAbs; // pdg ID from reconstructions - ROOT::VecOps::RVec invM; // invariant mass - ROOT::VecOps::RVec nSV_jet; // no of V0s per jet -}; - -/// Structure to keep useful track information that is related to the vertex -struct FCCAnalysesVertexMC { - TVector3 vertex; - ROOT::VecOps::RVec mc_ind; - ROOT::VecOps::RVec mc_indneutral; - ROOT::VecOps::RVec mother_ind; - ROOT::VecOps::RVec gmother_ind; -}; - -/// Selection of particles based on the d0 / z0 significances of the associated -/// track -struct selTracks { - selTracks(float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, - float arg_z0sig_max); - float m_d0sig_min = 0; - float m_d0sig_max = 3; - float m_z0sig_min = 0; - float m_z0sig_max = 3; - ROOT::VecOps::RVec - operator()(ROOT::VecOps::RVec recop, - ROOT::VecOps::RVec tracks); -}; - -/// Selection of primary particles : -ROOT::VecOps::RVec -SelPrimaryTracks(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - TVector3 MC_EventPrimaryVertex); - -/// Retrieve the number of reconstructed vertices from the collection of vertex -/// object -int get_Nvertex(ROOT::VecOps::RVec TheVertexColl); - -/// Retrieve a single FCCAnalyses vertex from the collection of vertex object -FCCAnalysesVertex -get_FCCAnalysesVertex(ROOT::VecOps::RVec TheVertexColl, - int index); - -/// Retrieve the edm4hep::VertexData from the vertex object -edm4hep::VertexData get_VertexData(FCCAnalysesVertex TheVertex); - -/// Retrieve a vector of edm4hep::VertexData from the collection of vertex -/// object -ROOT::VecOps::RVec -get_VertexData(ROOT::VecOps::RVec TheVertexColl); - -/// Retrieve a edm4hep::VertexData from the collection of vertex object at a -/// given index -edm4hep::VertexData -get_VertexData(ROOT::VecOps::RVec TheVertexColl, int index); - -/// Retrieve the number of tracks from FCCAnalysesVertex -int get_VertexNtrk(FCCAnalysesVertex TheVertex); - -ROOT::VecOps::RVec -get_VertexNtrk(ROOT::VecOps::RVec vertices); - -/// Retrieve the tracks indices from FCCAnalysesVertex -ROOT::VecOps::RVec get_VertexRecoInd(FCCAnalysesVertex TheVertex); - -/// Retrieve the indices of the tracks fitted to that vertex, but now in the -/// collection of RecoParticles -ROOT::VecOps::RVec get_VertexRecoParticlesInd( - FCCAnalysesVertex TheVertex, - const ROOT::VecOps::RVec &reco); - -/// Retrieve the indices of the tracks fitted to a vector of vertices, but now -/// in the collection of RecoParticles -ROOT::VecOps::RVec get_VerticesRecoParticlesInd( - ROOT::VecOps::RVec vertices, - const ROOT::VecOps::RVec &reco); - -/// @brief Find (by index) a vertex that is made of reco particles from a passed -/// list. -/// @param vertices: List of possible vertices to match -/// @param recoParticleIndices: Indices of the reco particles to find in the -/// vertex -/// @param reco: list of all reco particles (ReconstructedParticles) -/// @param require_all: If set, require one vertex to contain all -/// recoParticleIndices (no 'missed' tracks). Else only require that all tracks -/// in the vertex come from the vector (but allow for unused tracks) -/// @return: Index within the list of the (first) vertex fulfilling the -/// criteria. If none are found, return -1 -int getVertex_matching_recoParticles( - const ROOT::VecOps::RVec &vertices, - const ROOT::VecOps::RVec &recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all = false); - -/// Return the number of tracks in a given track collection -int get_nTracks(ROOT::VecOps::RVec tracks); - -/// compare two track states -bool compare_Tracks(const edm4hep::TrackState &tr1, - const edm4hep::TrackState &tr2); - -/////////////////////////////////////////////////// -/// functions used for SV reconstruction - -/** returns a vector of all vertices (PV and SVs), e.g to use in - * myUtils::get_Vertex_d2PV first entry: PV, all subsequent entries: SVs - */ -ROOT::VecOps::RVec -get_all_vertices(FCCAnalysesVertex PV, - ROOT::VecOps::RVec SV); +namespace VertexingUtils{ + + /// from delphes: returns track state parameters (delphes convention) for a given vertex (x), momentum (p) and charge + TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q); + + /// from delphes: returns the momentum corresponding to a given track state + TVector3 ParToP(TVectorD Par); + + + /// Structure to keep useful track information that is related to the vertex + struct FCCAnalysesVertex{ + edm4hep::VertexData vertex; + int ntracks; + int mc_ind; ///index in the MC vertex collection if any + ROOT::VecOps::RVec reco_ind; // indices of the tracks fitted to that vertex, in the collection of all tracks + ROOT::VecOps::RVec reco_chi2; + ROOT::VecOps::RVec< TVector3 > updated_track_momentum_at_vertex; + ROOT::VecOps::RVec< TVectorD > updated_track_parameters; + ROOT::VecOps::RVec final_track_phases; + }; + + /// Structure to keep useful information that is related to the V0 + struct FCCAnalysesV0{ + ROOT::VecOps::RVec vtx; // vertex object + ROOT::VecOps::RVec pdgAbs; // pdg ID from reconstructions + ROOT::VecOps::RVec invM; // invariant mass + ROOT::VecOps::RVec nSV_jet; // no of V0s per jet + }; + + /// Structure to keep useful track information that is related to the vertex + struct FCCAnalysesVertexMC{ + TVector3 vertex; + ROOT::VecOps::RVec mc_ind; + ROOT::VecOps::RVec mc_indneutral; + ROOT::VecOps::RVec mother_ind; + ROOT::VecOps::RVec gmother_ind; + }; + + /// Selection of particles based on the d0 / z0 significances of the associated track + struct selTracks { + selTracks( float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, float arg_z0sig_max) ; + float m_d0sig_min = 0; + float m_d0sig_max = 3; + float m_z0sig_min = 0; + float m_z0sig_max = 3; + ROOT::VecOps::RVec operator() ( ROOT::VecOps::RVec recop, + ROOT::VecOps::RVec tracks ) ; + }; + + /// Selection of primary particles : + ROOT::VecOps::RVec SelPrimaryTracks( ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + TVector3 MC_EventPrimaryVertex) ; + + /// Retrieve the number of reconstructed vertices from the collection of vertex object + int get_Nvertex( ROOT::VecOps::RVec TheVertexColl ); + + /// Retrieve a single FCCAnalyses vertex from the collection of vertex object + FCCAnalysesVertex get_FCCAnalysesVertex(ROOT::VecOps::RVec TheVertexColl, int index ); + + /// Retrieve the edm4hep::VertexData from the vertex object + edm4hep::VertexData get_VertexData( FCCAnalysesVertex TheVertex ) ; + + /// Retrieve a vector of edm4hep::VertexData from the collection of vertex object + ROOT::VecOps::RVec get_VertexData( ROOT::VecOps::RVec TheVertexColl ) ; + + /// Retrieve a edm4hep::VertexData from the collection of vertex object at a given index + edm4hep::VertexData get_VertexData( ROOT::VecOps::RVec TheVertexColl, int index); + + /// Retrieve the number of tracks from FCCAnalysesVertex + int get_VertexNtrk( FCCAnalysesVertex TheVertex ) ; + + ROOT::VecOps::RVec get_VertexNtrk( ROOT::VecOps::RVec vertices ) ; + + /// Retrieve the tracks indices from FCCAnalysesVertex + ROOT::VecOps::RVec get_VertexRecoInd( FCCAnalysesVertex TheVertex ) ; + + /// Retrieve the indices of the tracks fitted to that vertex, but now in the collection of RecoParticles + ROOT::VecOps::RVec get_VertexRecoParticlesInd( FCCAnalysesVertex TheVertex, + const ROOT::VecOps::RVec& reco ); + + /// Retrieve the indices of the tracks fitted to a vector of vertices, but now in the collection of RecoParticles + ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec& reco ); + + /// @brief Find (by index) a vertex that is made of reco particles from a passed list. + /// @param vertices: List of possible vertices to match + /// @param recoParticleIndices: Indices of the reco particles to find in the vertex + /// @param reco: list of all reco particles (ReconstructedParticles) + /// @param require_all: If set, require one vertex to contain all recoParticleIndices (no 'missed' tracks). Else only require that all tracks in the vertex come from the vector (but allow for unused tracks) + /// @return: Index within the list of the (first) vertex fulfilling the criteria. If none are found, return -1 + int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, + const ROOT::VecOps::RVec & recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all = false); + + /// Return the number of tracks in a given track collection + int get_nTracks(ROOT::VecOps::RVec tracks); + + /// compare two track states + bool compare_Tracks( const edm4hep::TrackState& tr1, const edm4hep::TrackState& tr2 ) ; + + /////////////////////////////////////////////////// + /// functions used for SV reconstruction + + /** returns a vector of all vertices (PV and SVs), e.g to use in myUtils::get_Vertex_d2PV + * first entry: PV, all subsequent entries: SVs + */ + ROOT::VecOps::RVec get_all_vertices( FCCAnalysesVertex PV, + ROOT::VecOps::RVec SV ); + + ROOT::VecOps::RVec get_all_vertices( FCCAnalysesVertex PV, + ROOT::VecOps::RVec> SV ); + + /** returns the invariant mass of a two-track vertex + * CAUTION: m1 -> mass of first track, m2 -> mass of second track + * by default both pions + */ + double get_invM_pairs( FCCAnalysesVertex vertex, + double m1 = 0.13957039, + double m2 = 0.13957039) ; + + ROOT::VecOps::RVec get_invM_pairs( ROOT::VecOps::RVec vertices, + double m1 = 0.13957039, + double m2 = 0.13957039 ) ; + + /** returns the invariant mass of a vertex + * assuming all tracks to be pions + */ + double get_invM( FCCAnalysesVertex vertex ) ; + + /** returns the invariant mass of a vector of vertices + * assuming all tracks to be pions + */ + ROOT::VecOps::RVec get_invM( ROOT::VecOps::RVec vertices ) ; + + /** returns the cos of the angle b/n V0 candidate's (or any vtx's) momentum & PV to V0 (vtx) displacement vector */ + double get_PV2V0angle( FCCAnalysesVertex V0, + FCCAnalysesVertex PV) ; + + /** returns cos of the angle b/n track (that form the vtx) momentum sum & PV to vtx displacement vector */ + double get_PV2vtx_angle( ROOT::VecOps::RVec tracks, + FCCAnalysesVertex vtx, + FCCAnalysesVertex PV ) ; -ROOT::VecOps::RVec -get_all_vertices(FCCAnalysesVertex PV, - ROOT::VecOps::RVec> SV); + /** returns a track's energy + * assuming the track to be a pion + */ + double get_trackE( edm4hep::TrackState track ) ; -/** returns the invariant mass of a two-track vertex - * CAUTION: m1 -> mass of first track, m2 -> mass of second track - * by default both pions - */ -double get_invM_pairs(FCCAnalysesVertex vertex, double m1 = 0.13957039, - double m2 = 0.13957039); + /////////////////////////////////////////////////// + /// V0 Reconstruction + /// Return the number of reconstructed V0s + int get_n_SV( FCCAnalysesV0 SV ); -ROOT::VecOps::RVec -get_invM_pairs(ROOT::VecOps::RVec vertices, - double m1 = 0.13957039, double m2 = 0.13957039); + /// Return the vertex position of all reconstructed V0s (in mm) + ROOT::VecOps::RVec get_position_SV( FCCAnalysesV0 SV ); -/** returns the invariant mass of a vertex - * assuming all tracks to be pions - */ -double get_invM(FCCAnalysesVertex vertex); + /// Return the PDG IDs of all reconstructed V0s + ROOT::VecOps::RVec get_pdg_V0( FCCAnalysesV0 V0 ); -/** returns the invariant mass of a vector of vertices - * assuming all tracks to be pions - */ -ROOT::VecOps::RVec -get_invM(ROOT::VecOps::RVec vertices); + /// Return the invariant masses of all reconstructed V0s + ROOT::VecOps::RVec get_invM_V0( FCCAnalysesV0 V0 ); + + /// Return the momentum of all reconstructed V0s + ROOT::VecOps::RVec get_p_SV( FCCAnalysesV0 SV ); + + /// Return chi2 of all reconstructed V0s + ROOT::VecOps::RVec get_chi2_SV( FCCAnalysesV0 SV ); + + /////////////////////////////////////////////////// + + /// Passing a vector of FCCAnalysesVertex instead of FCCAnalysesV0 + /// Return the number of reconstructed SVs + int get_n_SV( ROOT::VecOps::RVec vertices ); + + /// Return the momentum of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_p_SV( ROOT::VecOps::RVec vertices ); + + /// Return the vertex position of all reconstructed SVs (in mm) + ROOT::VecOps::RVec get_position_SV( ROOT::VecOps::RVec vertices ); + + /// Return the momentum magnitude of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_pMag_SV( ROOT::VecOps::RVec vertices ); + + /// Return chi2 of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_chi2_SV( ROOT::VecOps::RVec vertices ); + + /// Return normalised chi2 of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_norm_chi2_SV( ROOT::VecOps::RVec vertices ); + + /// Return no of DOF of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_nDOF_SV( ROOT::VecOps::RVec vertices ); + + /// Return polar angle (theta) of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_theta_SV( ROOT::VecOps::RVec vertices ); + + /// Return azimuthal angle (phi) of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_phi_SV( ROOT::VecOps::RVec vertices ); + + /// Return polar angle (theta) of all reconstructed vertices wrt jets (or V0.vtx) + ROOT::VecOps::RVec get_relTheta_SV( ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet, + ROOT::VecOps::RVec jets ); + + /// Return azimuthal angle (phi) of all reconstructed vertices wrt jets (or V0.vtx) + ROOT::VecOps::RVec get_relPhi_SV( ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet, + ROOT::VecOps::RVec jets ); + + /// Return the pointing angle of all reconstructed vertices (or V0.vtx) + ROOT::VecOps::RVec get_pointingangle_SV( ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV ); + + /// Return the distances of all reconstructed vertices from PV in xy plane [mm] (or V0.vtx) + ROOT::VecOps::RVec get_dxy_SV( ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV ); + + /// Return the distances of all reconstructed vertices from PV in 3D [mm] (or V0.vtx) + ROOT::VecOps::RVec get_d3d_SV( ROOT::VecOps::RVec vertices, + FCCAnalysesVertex PV ); + + /// Return the distances of all reconstructed verteces from given TVector3d object in 3D [mm] (or V0.vtx) + ROOT::VecOps::RVec get_d3d_SV_obj( ROOT::VecOps::RVec vertices, + TVector3 location ); + + /// Return the distances of all reconstructed verteces from given edm4hep::Vector3d object in 3D [mm] (or V0.vtx) + ROOT::VecOps::RVec get_d3d_SV_obj( ROOT::VecOps::RVec vertices, + edm4hep::Vector3d location ); + + /// Return the distance in R of all reconstructed verteces from given TVector3d object in 3D [mm] (or V0.vtx) + ROOT::VecOps::RVec get_dR_SV_obj( ROOT::VecOps::RVec vertices, + TVector3 location ); + + /// Return the distances in R of all reconstructed verteces from given edm4hep::Vector3d object in 3D [mm] (or V0.vtx) + ROOT::VecOps::RVec get_dR_SV_obj( ROOT::VecOps::RVec vertices, + edm4hep::Vector3d location ); + + /////////////////////////////////////////////////// -/** returns the cos of the angle b/n V0 candidate's (or any vtx's) momentum & PV - * to V0 (vtx) displacement vector */ -double get_PV2V0angle(FCCAnalysesVertex V0, FCCAnalysesVertex PV); + /// For get_SV_jets /// + + /// Return the number of reconstructed SVs + ROOT::VecOps::RVec get_all_SVs( ROOT::VecOps::RVec> vertices ); -/** returns cos of the angle b/n track (that form the vtx) momentum sum & PV to - * vtx displacement vector */ -double get_PV2vtx_angle(ROOT::VecOps::RVec tracks, - FCCAnalysesVertex vtx, FCCAnalysesVertex PV); + /// Return the total number of reconstructed SVs + int get_n_SV( ROOT::VecOps::RVec> vertices ); + + /// Return the number of reconstructed SVs per jet + ROOT::VecOps::RVec get_n_SV_jets( ROOT::VecOps::RVec> vertices ); + + /// Return the tracks separated by jets + std::vector> get_tracksInJets( ROOT::VecOps::RVec recoparticles, + ROOT::VecOps::RVec thetracks, + ROOT::VecOps::RVec jets, + std::vector> jet_consti ); + + /// Return V0s separated by jets + ROOT::VecOps::RVec> get_svInJets( ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec nSV_jet ); + + // --- for get_SV_jets --- // + ROOT::VecOps::RVec> get_invM( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_p_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_pMag_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_VertexNtrk( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_chi2_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_norm_chi2_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_nDOF_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_theta_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_phi_SV( ROOT::VecOps::RVec> vertices ); + ROOT::VecOps::RVec> get_relTheta_SV( ROOT::VecOps::RVec> vertices, ROOT::VecOps::RVec jets ); + ROOT::VecOps::RVec> get_relPhi_SV( ROOT::VecOps::RVec> vertices, ROOT::VecOps::RVec jets ); + ROOT::VecOps::RVec> get_pointingangle_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); + ROOT::VecOps::RVec> get_dxy_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); + ROOT::VecOps::RVec> get_d3d_SV( ROOT::VecOps::RVec> vertices, FCCAnalysesVertex PV ); + ROOT::VecOps::RVec> get_pdg_V0( ROOT::VecOps::RVec pdg, ROOT::VecOps::RVec nSV_jet ); + ROOT::VecOps::RVec> get_invM_V0( ROOT::VecOps::RVec invM, ROOT::VecOps::RVec nSV_jet ); + /// Return the vertex position of all reconstructed SVs (in mm) + ROOT::VecOps::RVec> get_position_SV( ROOT::VecOps::RVec> vertices ); + // --- for get_SV_jets --- // + + float get_trackMom( edm4hep::TrackState & atrack ); -/** returns a track's energy - * assuming the track to be a pion - */ -double get_trackE(edm4hep::TrackState track); - -/////////////////////////////////////////////////// -/// V0 Reconstruction -/// Return the number of reconstructed V0s -int get_n_SV(FCCAnalysesV0 SV); - -/// Return the vertex position of all reconstructed V0s (in mm) -ROOT::VecOps::RVec get_position_SV(FCCAnalysesV0 SV); - -/// Return the PDG IDs of all reconstructed V0s -ROOT::VecOps::RVec get_pdg_V0(FCCAnalysesV0 V0); - -/// Return the invariant masses of all reconstructed V0s -ROOT::VecOps::RVec get_invM_V0(FCCAnalysesV0 V0); - -/// Return the momentum of all reconstructed V0s -ROOT::VecOps::RVec get_p_SV(FCCAnalysesV0 SV); - -/// Return chi2 of all reconstructed V0s -ROOT::VecOps::RVec get_chi2_SV(FCCAnalysesV0 SV); - -/////////////////////////////////////////////////// - -/// Passing a vector of FCCAnalysesVertex instead of FCCAnalysesV0 -/// Return the number of reconstructed SVs -int get_n_SV(ROOT::VecOps::RVec vertices); - -/// Return the momentum of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_p_SV(ROOT::VecOps::RVec vertices); - -/// Return the vertex position of all reconstructed SVs (in mm) -ROOT::VecOps::RVec -get_position_SV(ROOT::VecOps::RVec vertices); - -/// Return the momentum magnitude of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_pMag_SV(ROOT::VecOps::RVec vertices); - -/// Return chi2 of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_chi2_SV(ROOT::VecOps::RVec vertices); - -/// Return normalised chi2 of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_norm_chi2_SV(ROOT::VecOps::RVec vertices); - -/// Return no of DOF of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_nDOF_SV(ROOT::VecOps::RVec vertices); - -/// Return polar angle (theta) of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_theta_SV(ROOT::VecOps::RVec vertices); - -/// Return azimuthal angle (phi) of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_phi_SV(ROOT::VecOps::RVec vertices); - -/// Return polar angle (theta) of all reconstructed vertices wrt jets (or -/// V0.vtx) -ROOT::VecOps::RVec -get_relTheta_SV(ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet, - ROOT::VecOps::RVec jets); - -/// Return azimuthal angle (phi) of all reconstructed vertices wrt jets (or -/// V0.vtx) -ROOT::VecOps::RVec -get_relPhi_SV(ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet, - ROOT::VecOps::RVec jets); - -/// Return the pointing angle of all reconstructed vertices (or V0.vtx) -ROOT::VecOps::RVec -get_pointingangle_SV(ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV); - -/// Return the distances of all reconstructed vertices from PV in xy plane [mm] -/// (or V0.vtx) -ROOT::VecOps::RVec -get_dxy_SV(ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV); - -/// Return the distances of all reconstructed vertices from PV in 3D [mm] (or -/// V0.vtx) -ROOT::VecOps::RVec -get_d3d_SV(ROOT::VecOps::RVec vertices, - FCCAnalysesVertex PV); - -/// Return the distances of all reconstructed verteces from given TVector3d -/// object in 3D [mm] (or V0.vtx) -ROOT::VecOps::RVec -get_d3d_SV_obj(ROOT::VecOps::RVec vertices, - TVector3 location); - -/// Return the distances of all reconstructed verteces from given -/// edm4hep::Vector3d object in 3D [mm] (or V0.vtx) -ROOT::VecOps::RVec -get_d3d_SV_obj(ROOT::VecOps::RVec vertices, - edm4hep::Vector3d location); - -/// Return the distance in R of all reconstructed verteces from given TVector3d -/// object in 3D [mm] (or V0.vtx) -ROOT::VecOps::RVec -get_dR_SV_obj(ROOT::VecOps::RVec vertices, - TVector3 location); - -/// Return the distances in R of all reconstructed verteces from given -/// edm4hep::Vector3d object in 3D [mm] (or V0.vtx) -ROOT::VecOps::RVec -get_dR_SV_obj(ROOT::VecOps::RVec vertices, - edm4hep::Vector3d location); - -/////////////////////////////////////////////////// - -/// For get_SV_jets /// - -/// Return the number of reconstructed SVs -ROOT::VecOps::RVec -get_all_SVs(ROOT::VecOps::RVec> vertices); - -/// Return the total number of reconstructed SVs -int get_n_SV( - ROOT::VecOps::RVec> vertices); - -/// Return the number of reconstructed SVs per jet -ROOT::VecOps::RVec get_n_SV_jets( - ROOT::VecOps::RVec> vertices); - -/// Return the tracks separated by jets -std::vector> get_tracksInJets( - ROOT::VecOps::RVec recoparticles, - ROOT::VecOps::RVec thetracks, - ROOT::VecOps::RVec jets, - std::vector> jet_consti); - -/// Return V0s separated by jets -ROOT::VecOps::RVec> -get_svInJets(ROOT::VecOps::RVec vertices, - ROOT::VecOps::RVec nSV_jet); - -// --- for get_SV_jets --- // -ROOT::VecOps::RVec> -get_invM(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> -get_p_SV(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> -get_pMag_SV(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> get_VertexNtrk( - ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> -get_chi2_SV(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> get_norm_chi2_SV( - ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> -get_nDOF_SV(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> get_theta_SV( - ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> -get_phi_SV(ROOT::VecOps::RVec> vertices); -ROOT::VecOps::RVec> get_relTheta_SV( - ROOT::VecOps::RVec> vertices, - ROOT::VecOps::RVec jets); -ROOT::VecOps::RVec> get_relPhi_SV( - ROOT::VecOps::RVec> vertices, - ROOT::VecOps::RVec jets); -ROOT::VecOps::RVec> get_pointingangle_SV( - ROOT::VecOps::RVec> vertices, - FCCAnalysesVertex PV); -ROOT::VecOps::RVec> -get_dxy_SV(ROOT::VecOps::RVec> vertices, - FCCAnalysesVertex PV); -ROOT::VecOps::RVec> -get_d3d_SV(ROOT::VecOps::RVec> vertices, - FCCAnalysesVertex PV); -ROOT::VecOps::RVec> -get_pdg_V0(ROOT::VecOps::RVec pdg, ROOT::VecOps::RVec nSV_jet); -ROOT::VecOps::RVec> -get_invM_V0(ROOT::VecOps::RVec invM, ROOT::VecOps::RVec nSV_jet); -/// Return the vertex position of all reconstructed SVs (in mm) -ROOT::VecOps::RVec> get_position_SV( - ROOT::VecOps::RVec> vertices); -// --- for get_SV_jets --- // - -float get_trackMom(edm4hep::TrackState &atrack); // --- Conversion methods between the Delphes and edm4hep conventions -/// convert track parameters, from edm4hep to delphes conventions -TVectorD Edm4hep2Delphes_TrackParam(const TVectorD ¶m, bool Units_mm); +/// convert track parameters, from edm4hep to delphes conventions + TVectorD Edm4hep2Delphes_TrackParam( const TVectorD& param, bool Units_mm ); /// convert track parameters, from delphes to edm4hep conventions -TVectorD Delphes2Edm4hep_TrackParam(const TVectorD ¶m, bool Units_mm); + TVectorD Delphes2Edm4hep_TrackParam( const TVectorD& param, bool Units_mm ); /// convert track covariance matrix, from edm4hep to delphes conventions -TMatrixDSym -Edm4hep2Delphes_TrackCovMatrix(const std::array &covMatrix, - bool Units_mm); + TMatrixDSym Edm4hep2Delphes_TrackCovMatrix( const std::array& covMatrix, bool Units_mm ); #if __has_include("edm4hep/CovMatrix6f.h") -TMatrixDSym -Edm4hep2Delphes_TrackCovMatrix(const edm4hep::CovMatrix6f &covMatrix, - bool Units_mm); + TMatrixDSym Edm4hep2Delphes_TrackCovMatrix( const edm4hep::CovMatrix6f& covMatrix, bool Units_mm ); #endif /// convert track covariance matrix, from delphes to edm4hep conventions -std::array Delphes2Edm4hep_TrackCovMatrix(const TMatrixDSym &cov, - bool Units_mm); + std::array Delphes2Edm4hep_TrackCovMatrix( const TMatrixDSym& cov, bool Units_mm ) ; + + + /// --- Internal methods needed by the code of Franco B: + TVectorD get_trackParam( edm4hep::TrackState & atrack, bool Units_mm = false) ; + TMatrixDSym get_trackCov( const edm4hep::TrackState & atrack, bool Units_mm = false) ; + + TVectorD ParToACTS(TVectorD Par); + TMatrixDSym CovToACTS(TMatrixDSym Cov,TVectorD Par); -/// --- Internal methods needed by the code of Franco B: -TVectorD get_trackParam(edm4hep::TrackState &atrack, bool Units_mm = false); -TMatrixDSym get_trackCov(const edm4hep::TrackState &atrack, - bool Units_mm = false); -TVectorD ParToACTS(TVectorD Par); -TMatrixDSym CovToACTS(TMatrixDSym Cov, TVectorD Par); -} // namespace VertexingUtils +}//end NS VertexingUtils -} // namespace FCCAnalyses +}//end NS FCCAnalyses #endif diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 0de05fd85c7..025cb050042 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -1,209 +1,173 @@ #include "FCCAnalyses/MCParticle.h" -#include #include +#include #include -namespace FCCAnalyses { -namespace MCParticle { +namespace FCCAnalyses{ + +namespace MCParticle{ + -ROOT::VecOps::RVec selByPredicate::operator()( - const ROOT::VecOps::RVec &in) { +ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec & in){ ROOT::VecOps::RVec result; result.reserve(in.size()); - for (auto &p : in) { - if (m_predicate(p)) - result.emplace_back(p); - } - return result; + for (auto & p : in) { + if (m_predicate(p)) result.emplace_back(p); + } + return result; } -ROOT::VecOps::RVec selByPredicate::operator()( - const ROOT::VecOps::RVec &indices, - const ROOT::VecOps::RVec &in) { +ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec& indices, const ROOT::VecOps::RVec &in){ ROOT::VecOps::RVec result; result.reserve(in.size()); for (int index : indices) { - if (index < 0 || index >= in.size()) - continue; - if (m_predicate(in[index])) - result.emplace_back(index); - } - return result; + if (index < 0 || index >= in.size()) continue; + if (m_predicate(in[index])) result.emplace_back(index); + } + return result; } -ROOT::VecOps::RVec> selByPredicate::operator()( - const ROOT::VecOps::RVec> &setsOfIndices, - const ROOT::VecOps::RVec &in) { +ROOT::VecOps::RVec> selByPredicate::operator() (const ROOT::VecOps::RVec>& setsOfIndices, const ROOT::VecOps::RVec &in){ ROOT::VecOps::RVec> result(setsOfIndices.size()); - for (int elem = 0; elem < setsOfIndices.size(); ++elem) { - result[elem] = this->operator()(setsOfIndices[elem], in); - } - return result; -} - -sel_pt::sel_pt(float arg_min_pt) - : selByPredicate([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { - return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > - arg_min_pt * arg_min_pt); - }) {} - -sel_eta::sel_eta(float arg_max_eta) - : selByPredicate([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { - ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, - p.mass); - return std::abs(vec.Eta()) < std::abs(arg_max_eta); - }) {} - -sel_genStatus::sel_genStatus(int arg_status) - : selByPredicate([arg_status](const edm4hep::MCParticleData &p) -> bool { - return p.generatorStatus == arg_status; - }) {} - -sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) - : selByPredicate([arg_pdg, arg_chargeconjugate]( - const edm4hep::MCParticleData &p) -> bool { - if (arg_chargeconjugate) - return std::abs(p.PDG) == std::abs(arg_pdg); - else - return p.PDG == arg_pdg; - }) {} - -sel_charged::sel_charged() - : selByPredicate([](const edm4hep::MCParticleData &p) -> bool { - // try to avoid floating comp to zero - // and thank you for the person who gave some neutral particles a -999 - // charge! - return std::abs(p.charge) > 1e-6 && p.charge != -999; - }) {} - -get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf) { - m_mother = arg_mother; - m_daughters = arg_daughters; - m_inf = arg_inf; -}; -bool get_decay::operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { + for (int elem = 0; elem < setsOfIndices.size(); ++elem){ + result[elem] = this->operator()(setsOfIndices[elem], in); + } + return result; +} + +sel_pt::sel_pt(float arg_min_pt) : + selByPredicate([arg_min_pt](const edm4hep::MCParticleData & p)->bool{ + return (p.momentum.x*p.momentum.x + p.momentum.y*p.momentum.y > arg_min_pt*arg_min_pt); + }){ +} - bool result = false; +sel_eta::sel_eta(float arg_max_eta) : + selByPredicate([arg_max_eta](const edm4hep::MCParticleData & p)->bool{ + ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); + return std::abs(vec.Eta()) < std::abs(arg_max_eta); + }){ +} + +sel_genStatus::sel_genStatus(int arg_status): + selByPredicate([arg_status](const edm4hep::MCParticleData & p)->bool{ + return p.generatorStatus == arg_status; + }){ +} + +sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate): + selByPredicate([arg_pdg, arg_chargeconjugate](const edm4hep::MCParticleData & p)->bool{ + if (arg_chargeconjugate) return std::abs( p.PDG ) == std::abs( arg_pdg); + else return p.PDG == arg_pdg; + }){ +} + +sel_charged::sel_charged(): + selByPredicate([](const edm4hep::MCParticleData & p)->bool{ + // try to avoid floating comp to zero + // and thank you for the person who gave some neutral particles a -999 charge! + return std::abs(p.charge) > 1e-6 && p.charge != -999; + }){ +} + + +get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf){m_mother=arg_mother; m_daughters=arg_daughters; m_inf=arg_inf;}; +bool get_decay::operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind){ + + bool result=false; for (size_t i = 0; i < in.size(); ++i) { - if (in[i].PDG != m_mother) - continue; - int ndaughters = 0; - for (unsigned j = in.at(i).daughters_begin; j != in.at(i).daughters_end; - ++j) { - if (std::abs(in[ind.at(j)].PDG) == m_daughters && m_inf == false) - ndaughters += 1; - else if (std::abs(in[ind.at(j)].PDG) <= m_daughters && m_inf == true) - ndaughters += 1; + if (in[i].PDG!=m_mother)continue; + int ndaughters=0; + for (unsigned j = in.at(i).daughters_begin; j != in.at(i).daughters_end; ++j) { + if (std::abs(in[ind.at(j)].PDG)==m_daughters && m_inf==false)ndaughters+=1; + else if (std::abs(in[ind.at(j)].PDG)<=m_daughters && m_inf==true)ndaughters+=1; } - // if (ndaughters>1){ - if (ndaughters >= 1) { - result = true; + //if (ndaughters>1){ + if (ndaughters>=1){ + result=true; return result; } } return result; } -filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs) { - m_pdgid = arg_pdgid; - m_abs = arg_abs; -}; -bool filter_pdgID::operator()(ROOT::VecOps::RVec in) { + +filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs){m_pdgid = arg_pdgid; m_abs = arg_abs;}; +bool filter_pdgID::operator() (ROOT::VecOps::RVec in) { for (size_t i = 0; i < in.size(); ++i) { - auto &p = in[i]; - if ((m_abs && abs(p.PDG) == m_pdgid) || (p.PDG == m_pdgid)) - return true; + auto & p = in[i]; + if ((m_abs && abs(p.PDG) == m_pdgid) || (p.PDG == m_pdgid)) return true; } return false; } -get_EventPrimaryVertex::get_EventPrimaryVertex(int arg_genstatus) { - m_genstatus = arg_genstatus; -}; -TVector3 get_EventPrimaryVertex::operator()( - ROOT::VecOps::RVec in) { - TVector3 result(-1e12, -1e12, -1e12); - int i = 0; - for (auto &p : in) { - i++; - if (p.generatorStatus == - m_genstatus) { // generator status code for the incoming particles of - // the hardest subprocess - TVector3 res(p.vertex.x, p.vertex.y, p.vertex.z); - result = res; - break; - } - } + +get_EventPrimaryVertex::get_EventPrimaryVertex( int arg_genstatus) { m_genstatus = arg_genstatus; }; +TVector3 get_EventPrimaryVertex::operator() ( ROOT::VecOps::RVec in ) { + TVector3 result(-1e12,-1e12,-1e12); + int i=0; + for (auto & p: in) { + i++; + if ( p.generatorStatus == m_genstatus ) { // generator status code for the incoming particles of the hardest subprocess + TVector3 res( p.vertex.x, p.vertex.y, p.vertex.z ); + result = res; + break; + } + } return result; } get_EventPrimaryVertexP4::get_EventPrimaryVertexP4() {}; -TLorentzVector get_EventPrimaryVertexP4::operator()( - ROOT::VecOps::RVec in) { - TLorentzVector result(-1e12, -1e12, -1e12, -1e12); +TLorentzVector get_EventPrimaryVertexP4::operator() ( ROOT::VecOps::RVec in ) { + TLorentzVector result(-1e12,-1e12,-1e12,-1e12); Bool_t found_py8 = false; - // std::cout<<"-------------------------------------------"< 1.e-12) { // generator status code for the incoming - // particles of the hardest subprocess - // vertex.time is in s, convert in mm here. - TLorentzVector res(p.vertex.x, p.vertex.y, p.vertex.z, - p.time * 1.0e3 * 2.99792458e+8); - result = res; - break; + //std::cout<<"-------------------------------------------"< 1.e-12 ) { // generator status code for the incoming particles of the hardest subprocess + // vertex.time is in s, convert in mm here. + TLorentzVector res( p.vertex.x, p.vertex.y, p.vertex.z, p.time * 1.0e3 * 2.99792458e+8); + result = res; + break; + } } - } - } - // std::cout< -get_tree::operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec get_tree::operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind){ ROOT::VecOps::RVec result; - auto &particle = in[m_index]; + auto & particle = in[m_index]; + + //for (unsigned j = in.at(i).parents_begin; j != in.at(i).parents_end; ++j){ + // if + // result.push_back(ind.at(j)); - // for (unsigned j = in.at(i).parents_begin; j != in.at(i).parents_end; ++j){ - // if - // result.push_back(ind.at(j)); - std::cout << "Thomas logic" << std::endl; + std::cout << "Thomas logic"< in, return result; } -ROOT::VecOps::RVec -get_pt(ROOT::VecOps::RVec in) { - ROOT::VecOps::RVec result; - for (size_t i = 0; i < in.size(); ++i) { - result.push_back(sqrt(in[i].momentum.x * in[i].momentum.x + - in[i].momentum.y * in[i].momentum.y)); - } - return result; + + + + +ROOT::VecOps::RVec get_pt(ROOT::VecOps::RVec in){ + ROOT::VecOps::RVec result; + for (size_t i = 0; i < in.size(); ++i) { + result.push_back(sqrt(in[i].momentum.x * in[i].momentum.x + in[i].momentum.y * in[i].momentum.y)); + } + return result; } -ROOT::VecOps::RVec -mergeParticles(ROOT::VecOps::RVec x, - ROOT::VecOps::RVec y) { - // to be keept as std::vector +ROOT::VecOps::RVec mergeParticles(ROOT::VecOps::RVec x, ROOT::VecOps::RVec y) { + //to be keept as std::vector std::vector result; result.reserve(x.size() + y.size()); - result.insert(result.end(), x.begin(), x.end()); - result.insert(result.end(), y.begin(), y.end()); + result.insert( result.end(), x.begin(), x.end() ); + result.insert( result.end(), y.begin(), y.end() ); return ROOT::VecOps::RVec(result); } -ROOT::VecOps::RVec -get_time(ROOT::VecOps::RVec in) { + +ROOT::VecOps::RVec get_time(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.time); } return result; } -ROOT::VecOps::RVec -get_pdg(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_pdg(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.PDG); } return result; } -ROOT::VecOps::RVec -get_genStatus(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_genStatus(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.generatorStatus); } return result; } -ROOT::VecOps::RVec -get_simStatus(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_simStatus(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.simulatorStatus); } return result; } -ROOT::VecOps::RVec -get_vertex(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_vertex(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.vertex); } return result; } -ROOT::VecOps::RVec -get_vertex_x(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_vertex_x(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.vertex.x); } return result; } -ROOT::VecOps::RVec -get_vertex_y(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_vertex_y(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.vertex.y); } return result; } -ROOT::VecOps::RVec -get_vertex_z(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_vertex_z(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.vertex.z); } return result; } -ROOT::VecOps::RVec -get_endPoint(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.endpoint); } return result; @@ -327,68 +283,61 @@ get_endPoint(ROOT::VecOps::RVec in) { // E.P : "endpoint" is currenly not filled in the Particle block :-( // hence retrieve the decay vertices differently : -ROOT::VecOps::RVec -get_endPoint(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { - // ( carefull : if a Bs has oscillated into a Bsbar, this returns the - // production vertex of the Bsbar ) +ROOT::VecOps::RVec get_endPoint(ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind ) { + // ( carefull : if a Bs has oscillated into a Bsbar, this returns the production vertex of the Bsbar ) ROOT::VecOps::RVec result; - for (auto &p : in) { - edm4hep::Vector3d vertex(1e12, 1e12, - 1e12); // a default value for stable particles - int db = p.daughters_begin; + for (auto & p: in) { + edm4hep::Vector3d vertex(1e12, 1e12, 1e12); // a default value for stable particles + int db = p.daughters_begin ; int de = p.daughters_end; - if (db != de) { // particle unstable - int d1 = ind[db]; // first daughter - if (d1 >= 0 && d1 < in.size()) { - vertex = in.at(d1).vertex; - } + if (db != de) { // particle unstable + int d1 = ind[db] ; // first daughter + if ( d1 >= 0 && d1 < in.size() ) { + vertex = in.at(d1).vertex ; + } } result.push_back(vertex); } return result; } -ROOT::VecOps::RVec -get_endPoint_x(ROOT::VecOps::RVec in) { + + +ROOT::VecOps::RVec get_endPoint_x(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.endpoint.x); } return result; } -ROOT::VecOps::RVec -get_endPoint_y(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_endPoint_y(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.endpoint.y); } return result; } -ROOT::VecOps::RVec -get_endPoint_z(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_endPoint_z(ROOT::VecOps::RVec in){ ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.endpoint.z); } return result; } -ROOT::VecOps::RVec -get_mass(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_mass(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.mass); } return result; } -ROOT::VecOps::RVec -get_eta(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_eta(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Eta()); @@ -396,10 +345,9 @@ get_eta(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_phi(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_phi(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Phi()); @@ -407,10 +355,9 @@ get_phi(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_e(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_e(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.E()); @@ -418,10 +365,9 @@ get_e(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_p(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_p(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.P()); @@ -429,46 +375,41 @@ get_p(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_px(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_px(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.momentum.x); } return result; } -ROOT::VecOps::RVec -get_py(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_py(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.momentum.y); } return result; } -ROOT::VecOps::RVec -get_pz(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_pz(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.momentum.z); } return result; } -ROOT::VecOps::RVec -get_charge(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_charge(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { result.push_back(p.charge); } return result; } -ROOT::VecOps::RVec -get_y(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_y(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Rapidity()); @@ -476,10 +417,9 @@ get_y(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_theta(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_theta(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv.Theta()); @@ -487,10 +427,9 @@ get_theta(ROOT::VecOps::RVec in) { return result; } -ROOT::VecOps::RVec -get_tlv(ROOT::VecOps::RVec in) { +ROOT::VecOps::RVec get_tlv(ROOT::VecOps::RVec in) { ROOT::VecOps::RVec result; - for (auto &p : in) { + for (auto & p: in) { TLorentzVector tlv; tlv.SetXYZM(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); result.push_back(tlv); @@ -499,118 +438,104 @@ get_tlv(ROOT::VecOps::RVec in) { } int get_n(ROOT::VecOps::RVec x) { - int result = x.size(); + int result = x.size(); return result; } -ROOT::VecOps::RVec -get_parentid(ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents) { + + + + +ROOT::VecOps::RVec get_parentid(ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec mc, ROOT::VecOps::RVec parents){ ROOT::VecOps::RVec result; /*std::cout <<"================== Full Truth=================" < 1) { - // std::cout << "-999" << std::endl; + //std::cout << mc.at(mcind.at(i)).parents_begin <<"---"<< mc.at(mcind.at(i)).parents_end<< std::endl; + if (mc.at(mcind.at(i)).parents_end - mc.at(mcind.at(i)).parents_begin>1) { + //std::cout << "-999" << std::endl; result.push_back(-999); - } else { - // std::cout << "not -999 "<< parents.at(mc.at(mcind.at(i)).parents_begin) - // << std::endl; + } + else { + //std::cout << "not -999 "<< parents.at(mc.at(mcind.at(i)).parents_begin) << std::endl; result.push_back(parents.at(mc.at(mcind.at(i)).parents_begin)); } } return result; } + // ---------------------------------------------------------------------------------------------------------------------------------- // returns one MCParticle selected by its index in the particle block -edm4hep::MCParticleData -sel_byIndex(int idx, ROOT::VecOps::RVec in) { - edm4hep::MCParticleData dummy; - if (idx >= 0 && idx < in.size()) { - return in.at(idx); - } else { - std::cout << " !!!! in sel_byIndex : index = " << idx - << " is larger than the size of the MCParticle block " - << in.size() << std::endl; - } - return dummy; +edm4hep::MCParticleData sel_byIndex( int idx, ROOT::VecOps::RVec in) { + edm4hep::MCParticleData dummy; + if ( idx >= 0 && idx < in.size() ) { + return in.at(idx) ; + } + else { + std::cout << " !!!! in sel_byIndex : index = " << idx << " is larger than the size of the MCParticle block " << in.size() << std::endl; + } + return dummy; } + // ---------------------------------------------------------------------------------------------------------------------------------- -std::vector get_list_of_stable_particles_from_decay( - int i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { std::vector res; // i = index of a MC particle in the Particle block // in = the Particle collection // ind = the block with the indices for the daughters, Particle#1.index - // returns a vector with the indices (in the Particle block) of the stable - // daughters of the particle i, from the complete decay chain. + // returns a vector with the indices (in the Particle block) of the stable daughters of the particle i, + // from the complete decay chain. - if (i < 0 || i >= in.size()) - return res; + if ( i < 0 || i >= in.size() ) return res; - int db = in.at(i).daughters_begin; + int db = in.at(i).daughters_begin ; int de = in.at(i).daughters_end; - if (db != de) { // particle is unstable - // int d1 = ind[db] ; - // int d2 = ind[de-1]; - // for (int idaughter = d1; idaughter <= d2; idaughter++) { + if ( db != de ) {// particle is unstable + //int d1 = ind[db] ; + //int d2 = ind[de-1]; + //for (int idaughter = d1; idaughter <= d2; idaughter++) { for (int id = db; id < de; id++) { - int idaughter = ind[id]; + int idaughter = ind[ id ]; // prevent endless loop in case of looping MC record - if (idaughter == i) - continue; - std::vector rr = - get_list_of_stable_particles_from_decay(idaughter, in, ind); - res.insert(res.end(), rr.begin(), rr.end()); + if (idaughter == i) continue; + std::vector rr = get_list_of_stable_particles_from_decay( idaughter, in, ind) ; + res.insert( res.end(), rr.begin(), rr.end() ); } - } else { // particle is stable - res.push_back(i); - return res; + } + else { // particle is stable + res.push_back( i ) ; + return res ; } return res; } // ---------------------------------------------------------------------------------------------------------------------------------- -std::vector -get_list_of_particles_from_decay(int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +std::vector get_list_of_particles_from_decay(int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { std::vector res; @@ -618,201 +543,178 @@ get_list_of_particles_from_decay(int i, // in = the Particle collection // ind = the block with the indices for the daughters, Particle#1.index - // returns a vector with the indices (in the Particle block) of the daughters - // of the particle i + // returns a vector with the indices (in the Particle block) of the daughters of the particle i - if (i < 0 || i >= in.size()) - return res; + if ( i < 0 || i >= in.size() ) return res; - int db = in.at(i).daughters_begin; + int db = in.at(i).daughters_begin ; int de = in.at(i).daughters_end; - if (db == de) - return res; // particle is stable - // int d1 = ind[db] ; - // int d2 = ind[de-1]; - // for (int idaughter = d1; idaughter <= d2; idaughter++) { - // res.push_back( idaughter); + if ( db == de ) return res; // particle is stable + //int d1 = ind[db] ; + //int d2 = ind[de-1]; + //for (int idaughter = d1; idaughter <= d2; idaughter++) { + //res.push_back( idaughter); for (int id = db; id < de; id++) { - res.push_back(ind[id]); + res.push_back( ind[id] ) ; } return res; } -ROOT::VecOps::RVec> -get_lists_of_stable_particles_from_decays( - ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays(ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { - ROOT::VecOps::RVec> ret; - ret.reserve(i.size()); - for (int ix : i) { - ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); + ROOT::VecOps::RVec> ret; + ret.reserve(i.size()); + for (int ix : i){ + ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); } - return ret; + return ret; } + // ---------------------------------------------------------------------------------------------------------------------------------- // obsolete: keep for the while, for backward compatibility -std::vector list_of_stable_particles_from_decay( - int i, ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { - std::cout << " -------- OBSOLETE ----- call to " - "get_list_of_stable_particles_from_decay , please update your " - "code ----- " - << std::endl; - return get_list_of_stable_particles_from_decay(i, in, ind); +std::vector list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { + std::cout << " -------- OBSOLETE ----- call to get_list_of_stable_particles_from_decay , please update your code ----- " << std::endl; + return get_list_of_stable_particles_from_decay( i, in, ind ); } -std::vector -list_of_particles_from_decay(int i, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { - std::cout - << " -------- OBSOLETE ----- call to get_list_of_particles_from_decay " - ", please update your code ----- " - << std::endl; - return get_list_of_particles_from_decay(i, in, ind); +std::vector list_of_particles_from_decay(int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { + std::cout << " -------- OBSOLETE ----- call to get_list_of_particles_from_decay , please update your code ----- " << std::endl; + return get_list_of_particles_from_decay( i, in, ind ); } + + + + + + // ---------------------------------------------------------------------------------------------------------------------------------- -ROOT::VecOps::RVec get_indices_MotherByIndex( - int imother, std::vector m_pdg_daughters, bool m_stableDaughters, - bool m_chargeConjugateDaughters, bool m_inclusiveDecay, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec get_indices_MotherByIndex ( int imother, + std::vector m_pdg_daughters, + bool m_stableDaughters, + bool m_chargeConjugateDaughters, + bool m_inclusiveDecay, + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - // Look for a specific decay specified by the mother index in the Particle - // block, and by the PDG_ids of the daughters If m_inclusiveDecay is true, - // then at least this list of daughters must be included in the decay Returns - // a vector with the indices, in the Particle block, of the mother and of the - // daughters - in the order defined by std::vector pdg_daughters. + // Look for a specific decay specified by the mother index in the Particle block, + // and by the PDG_ids of the daughters + // If m_inclusiveDecay is true, then at least this list of daughters must be included in the decay + // Returns a vector with the indices, in the Particle block, of the mother and of + // the daughters - in the order defined by std::vector pdg_daughters. - ROOT::VecOps::RVec result; - std::vector products; - if (m_stableDaughters) { - products = get_list_of_stable_particles_from_decay(imother, in, ind); - } else { - products = get_list_of_particles_from_decay(imother, in, ind); + ROOT::VecOps::RVec result; + + std::vector products ; + if ( m_stableDaughters ) { + products = get_list_of_stable_particles_from_decay( imother, in, ind ) ; + } + else { + products = get_list_of_particles_from_decay( imother, in, ind ) ; } std::vector found; - for (auto &pdg_d : m_pdg_daughters) { - for (auto &idx_d : products) { - if ((m_chargeConjugateDaughters && abs(in[idx_d].PDG) == abs(pdg_d)) || - in[idx_d].PDG == pdg_d) { - // careful, there can be several particles with the same PDG ! - if (std::find(found.begin(), found.end(), idx_d) == - found.end()) { // idx_d has NOT already been "used" - found.push_back(idx_d); + for (auto & pdg_d: m_pdg_daughters ) { + for (auto & idx_d: products) { + if ( (m_chargeConjugateDaughters && abs(in[idx_d].PDG) == abs(pdg_d)) || in[idx_d].PDG == pdg_d) { + // careful, there can be several particles with the same PDG ! + if (std::find(found.begin(), found.end(), idx_d) == found.end()) { // idx_d has NOT already been "used" + found.push_back( idx_d ); break; - } + } } } } - if ((m_inclusiveDecay && found.size() >= m_pdg_daughters.size() && - products.size() >= - m_pdg_daughters.size()) || // for inclusive decay: at least this list - // of daughters - (!m_inclusiveDecay && found.size() == m_pdg_daughters.size() && - products.size() == - m_pdg_daughters - .size())) // for exclusive decay: exactly this list of daughters - { // all daughters have been found. That's the decay mode looked for. - result.push_back(imother); - for (auto &idx_d : - found) { // use "found" and not "products", to get the right ordering - result.push_back(idx_d); + if ( (m_inclusiveDecay && found.size() >= m_pdg_daughters.size() && products.size() >= m_pdg_daughters.size()) || //for inclusive decay: at least this list of daughters + (!m_inclusiveDecay && found.size() == m_pdg_daughters.size() && products.size() == m_pdg_daughters.size()) ) //for exclusive decay: exactly this list of daughters + { // all daughters have been found. That's the decay mode looked for. + result.push_back( imother ); + for ( auto & idx_d: found) { // use "found" and not "products", to get the right ordering + result.push_back( idx_d ); + } } - } return result; + } -ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( - int imother, std::vector m_pdg_daughters, bool m_stableDaughters, - ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { - return get_indices_MotherByIndex(imother, m_pdg_daughters, m_stableDaughters, - false /* m_chargeConjuigateDaughters */, - false /* m_inclusiveDecay */, in, ind); +ROOT::VecOps::RVec get_indices_ExclusiveDecay_MotherByIndex( int imother, + std::vector m_pdg_daughters, + bool m_stableDaughters, + ROOT::VecOps::RVec in , + ROOT::VecOps::RVec ind) { + return get_indices_MotherByIndex( + imother, + m_pdg_daughters, + m_stableDaughters, + false /* m_chargeConjuigateDaughters */, + false /* m_inclusiveDecay */, + in, + ind); } // ---------------------------------------------------------------------------------------------------------------------------------- -get_indices::get_indices(int pdg_mother, std::vector pdg_daughters, - bool stableDaughters, bool chargeConjugateMother, - bool chargeConjugateDaughters, bool inclusiveDecay) { +get_indices::get_indices( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugateMother, bool chargeConjugateDaughters, bool inclusiveDecay) { m_pdg_mother = pdg_mother; m_pdg_daughters = pdg_daughters; m_stableDaughters = stableDaughters; m_chargeConjugateMother = chargeConjugateMother; m_chargeConjugateDaughters = chargeConjugateDaughters; m_inclusiveDecay = inclusiveDecay; -}; +} ; -ROOT::VecOps::RVec -get_indices::operator()(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec get_indices::operator() ( ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { - // Look for a specific decay specified by the mother PDG_id and - // the PDG_ids of the daughters - // Returns a vector with the indices, in the Particle block, of the mother and - // of the daughters - in the order defined by std::vector pdg_daughters. - // - // In case there are several such decays in the event, keep only the first - // one. + // Look for a specific decay specified by the mother PDG_id and + // the PDG_ids of the daughters + // Returns a vector with the indices, in the Particle block, of the mother and of + // the daughters - in the order defined by std::vector pdg_daughters. + // + // In case there are several such decays in the event, keep only the first one. - ROOT::VecOps::RVec result; + ROOT::VecOps::RVec result; - for (int imother = 0; imother < in.size(); imother++) { - int pdg = in[imother].PDG; - bool found_a_mother = false; - if (!m_chargeConjugateMother) - found_a_mother = (pdg == m_pdg_mother); - if (m_chargeConjugateMother) - found_a_mother = (abs(pdg) == abs(m_pdg_mother)); - if (!found_a_mother) - continue; + for ( int imother =0; imother < in.size(); imother ++){ + int pdg = in[imother].PDG ; + bool found_a_mother = false; + if ( ! m_chargeConjugateMother ) found_a_mother = ( pdg == m_pdg_mother ); + if ( m_chargeConjugateMother ) found_a_mother = ( abs(pdg) == abs(m_pdg_mother) ) ; + if ( ! found_a_mother ) continue; - ROOT::VecOps::RVec a = get_indices_MotherByIndex( - imother, m_pdg_daughters, m_stableDaughters, m_chargeConjugateDaughters, - m_inclusiveDecay, in, ind); - if (a.size() != 0) { - result = a; - break; // return the first decay found - } - } - return result; + ROOT::VecOps::RVec a = get_indices_MotherByIndex( imother, m_pdg_daughters, m_stableDaughters, m_chargeConjugateDaughters, m_inclusiveDecay, in, ind ); + if ( a.size() != 0 ) { + result = a; + break; // return the first decay found + } + + } + return result; } -get_indices_ExclusiveDecay::get_indices_ExclusiveDecay( - int pdg_mother, std::vector pdg_daughters, bool stableDaughters, - bool chargeConjugate) - : get_indices(pdg_mother, pdg_daughters, stableDaughters, chargeConjugate, - chargeConjugate, false) {}; +get_indices_ExclusiveDecay::get_indices_ExclusiveDecay( int pdg_mother, std::vector pdg_daughters, bool stableDaughters, bool chargeConjugate) : get_indices(pdg_mother, pdg_daughters, stableDaughters, chargeConjugate, chargeConjugate, false) { +}; + // -------------------------------------------------------------------------------------------------- -ROOT::VecOps::RVec -AngleBetweenTwoMCParticles(ROOT::VecOps::RVec p1, - ROOT::VecOps::RVec p2) { +ROOT::VecOps::RVec AngleBetweenTwoMCParticles( ROOT::VecOps::RVec p1, ROOT::VecOps::RVec p2 ) { ROOT::VecOps::RVec result; - if (p1.size() != p2.size()) { - std::cout << " !!! in AngleBetweenTwoMCParticles: the arguments p1 and p2 " - "should have the same size " - << std::endl; - return result; + if ( p1.size() != p2.size() ) { + std::cout << " !!! in AngleBetweenTwoMCParticles: the arguments p1 and p2 should have the same size " << std::endl; + return result; } - for (int i = 0; i < p1.size(); i++) { - TVector3 q1(p1[i].momentum.x, p1[i].momentum.y, p1[i].momentum.z); - TVector3 q2(p2[i].momentum.x, p2[i].momentum.y, p2[i].momentum.z); - float delta = fabs(q1.Angle(q2)); - result.push_back(delta); + for (int i=0; i < p1.size(); i++) { + TVector3 q1( p1[i].momentum.x, p1[i].momentum.y, p1[i].momentum.z ); + TVector3 q2( p2[i].momentum.x, p2[i].momentum.y, p2[i].momentum.z ); + float delta = fabs( q1.Angle( q2 ) ) ; + result.push_back( delta ); } return result; @@ -820,100 +722,90 @@ AngleBetweenTwoMCParticles(ROOT::VecOps::RVec p1, int get_lepton_origin(const edm4hep::MCParticleData &p, const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind) { + const ROOT::VecOps::RVec &ind){ - // std::cout << std::endl << " enter in MCParticle::get_lepton_origin PDG = - // " << p.PDG << std::endl; + // std::cout << std::endl << " enter in MCParticle::get_lepton_origin PDG = " << p.PDG << std::endl; - int pdg = std::abs(p.PDG); - if (pdg != 11 && pdg != 13 && pdg != 15) - return -1; + int pdg = std::abs( p.PDG ) ; + if ( pdg != 11 && pdg != 13 && pdg != 15 ) return -1; - int result = 0; + int result = 0; - // std::cout << " p.parents_begin p.parents_end " << p.parents_begin << " " - // << p.parents_end << std::endl; - for (unsigned j = p.parents_begin; j != p.parents_end; ++j) { - int index = ind.at(j); - int pdg_parent = in.at(index).PDG; - // std::cout << " parent has pdg = " << in.at(index).PDG << " status = " - // << in.at(index).generatorStatus << std::endl; + // std::cout << " p.parents_begin p.parents_end " << p.parents_begin << " " << p.parents_end << std::endl; + for (unsigned j = p.parents_begin; j != p.parents_end; ++j) { + int index = ind.at(j); + int pdg_parent = in.at(index).PDG ; + // std::cout << " parent has pdg = " << in.at(index).PDG << " status = " << in.at(index).generatorStatus << std::endl; - if (abs(pdg_parent) == 23 || abs(pdg_parent) == 24) { - result = pdg_parent; - // std::cout << " ... Lepton is from W or Z , return code = " << result - // << std::endl; - break; - } + if ( abs( pdg_parent ) == 23 || abs( pdg_parent ) == 24 ) { + result = pdg_parent ; + //std::cout << " ... Lepton is from W or Z , return code = " << result << std::endl; + break; + } - if (abs(pdg_parent) == 22) { - result = pdg_parent; - // std::cout << " ... Lepton is from a virtual photon , return code = " - // << result << std::endl; - break; - } + if ( abs( pdg_parent ) == 22 ) { + result = pdg_parent ; + //std::cout << " ... Lepton is from a virtual photon , return code = " << result << std::endl; + break; + } - if (abs(pdg_parent) == 15) { - result = pdg_parent; - // std::cout << " ... Lepton is from a tau, return code = " << result << - // std::endl; - break; - } + if ( abs( pdg_parent ) == 15 ) { + result = pdg_parent ; + //std::cout << " ... Lepton is from a tau, return code = " << result << std::endl; + break; + } - if (abs(pdg_parent) == 11) { // beam particle ? - // beam particles should have generatorStatus = 4, - // but that is not the case in files produced from Whizard + p6 - if (in.at(index).generatorStatus == 4 || - ind.at(in.at(index).parents_begin) == 0) { - result = 0; - // std::cout << " ... Lepton is from the hard subprocess, return code = - // " << result << std::endl; - break; + if ( abs( pdg_parent ) == 11 ) { // beam particle ? + // beam particles should have generatorStatus = 4, + // but that is not the case in files produced from Whizard + p6 + if ( in.at(index).generatorStatus == 4 || ind.at ( in.at(index).parents_begin ) == 0 ) { + result = 0; + //std::cout << " ... Lepton is from the hard subprocess, return code = " << result << std::endl; + break; + } } - } - if (pdg == 11 && abs(pdg_parent) == 13) { // mu -> e - result = pdg_parent; - // std::cout << " ... Electron from a muon decay, return code = " << - // result << std::endl; - break; - } + if ( pdg == 11 && abs( pdg_parent ) == 13 ) { // mu -> e + result = pdg_parent; + //std::cout << " ... Electron from a muon decay, return code = " << result << std::endl; + break; + } - if (abs(pdg_parent) == pdg) { - // std::cout << " ... iterate ... " << std::endl; - return get_lepton_origin(in.at(index), in, ind); + if ( abs( pdg_parent ) == pdg ) { + //std::cout << " ... iterate ... " << std::endl; + return get_lepton_origin( in.at(index), in, ind ); + } + // This must come from a hadron decay + result = pdg_parent; + //std::cout << " ... Lepton from a hadron decay " << std::endl; } - // This must come from a hadron decay - result = pdg_parent; - // std::cout << " ... Lepton from a hadron decay " << std::endl; - } - return result; + return result; } + int get_lepton_origin(int index, const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind) { - if (index < 0 || index >= in.size()) - return -1; + const ROOT::VecOps::RVec &ind){ + if ( index < 0 || index >= in.size() ) return -1; edm4hep::MCParticleData p = in[index]; - return get_lepton_origin(p, in, ind); + return get_lepton_origin( p, in, ind ); } -ROOT::VecOps::RVec -get_leptons_origin(const ROOT::VecOps::RVec &particles, - const ROOT::VecOps::RVec &in, - const ROOT::VecOps::RVec &ind) { + +ROOT::VecOps::RVec get_leptons_origin(const ROOT::VecOps::RVec &particles, + const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ind) { ROOT::VecOps::RVec result; result.reserve(particles.size()); for (size_t i = 0; i < particles.size(); ++i) { - auto &p = particles[i]; - int origin = MCParticle::get_lepton_origin(p, in, ind); - result.push_back(origin); + auto & p = particles[i]; + int origin = MCParticle::get_lepton_origin( p, in, ind ); + result.push_back( origin ); } return result; } -} // namespace MCParticle +}//end NS MCParticle -} // namespace FCCAnalyses +}//end NS FCCAnalyses diff --git a/analyzers/dataframe/src/ReconstructedParticle2MC.cc b/analyzers/dataframe/src/ReconstructedParticle2MC.cc index 317e6c77e26..244b716785c 100644 --- a/analyzers/dataframe/src/ReconstructedParticle2MC.cc +++ b/analyzers/dataframe/src/ReconstructedParticle2MC.cc @@ -1,143 +1,153 @@ #include "FCCAnalyses/ReconstructedParticle2MC.h" #include -namespace FCCAnalyses { +namespace FCCAnalyses{ + +namespace ReconstructedParticle2MC{ -namespace ReconstructedParticle2MC { ROOT::VecOps::RVec -getRP2MC_p(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_p(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); + result.resize(reco.size(),-1.); - for (unsigned int i = 0; i < recind.size(); i++) { + for (unsigned int i=0; i -getRP2MC_tlv(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_tlv(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), TLorentzVector()); + result.resize(reco.size(),TLorentzVector()); - for (unsigned int i = 0; i < recind.size(); i++) { + for (unsigned int i=0; i -getRP2MC_px(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_px(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).momentum.x; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_py(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_py(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).momentum.y; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_pz(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_pz(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).momentum.z; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_pdg(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_pdg(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).PDG; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_charge(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_charge(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).charge; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_mass(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +getRP2MC_mass(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mc.at(mcind.at(i)).mass; + result.resize(reco.size(),-1.); + for (unsigned int i=0; i -getRP2MC_index(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { +getRP2MC_index(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (size_t i = 0; i < recind.size(); i++) { - result[recind.at(i)] = mcind.at(i); + result.resize(reco.size(),-1.); + for (size_t i=0; i> -getRP2MC_indexVec(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { + +ROOT::VecOps::RVec< ROOT::VecOps::RVec > +getRP2MC_indexVec(ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { ROOT::VecOps::RVec> result; - for (size_t i = 0; i < reco.size(); i++) { + for (size_t i=0; i tmp; result.push_back(tmp); } - for (size_t i = 0; i < recind.size(); i++) { + for (size_t i=0; i recind, ROOT::VecOps::RVec mcind, ROOT::VecOps::RVec getRP2MC_index_test(ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents) { - std::cout << "=========NEW EVENT=========" << std::endl; + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents) { + std::cout <<"=========NEW EVENT========="< result; - result.resize(reco.size(), -1.); - for (size_t i = 0; i < recind.size(); i++) { - if (result[recind.at(i)] > -1) { - auto &p_prev = mc.at(result[recind.at(i)]); - auto &p_now = mc.at(mcind.at(i)); - auto &p_reco = reco.at(recind.at(i)); + result.resize(reco.size(),-1.); + for (size_t i=0; i-1){ + auto & p_prev = mc.at(result[recind.at(i)]); + auto & p_now = mc.at(mcind.at(i)); + auto & p_reco = reco.at(recind.at(i)); TLorentzVector tlv_prev; TLorentzVector tlv_now; TLorentzVector tlv_reco; - tlv_prev.SetXYZM(p_prev.momentum.x, p_prev.momentum.y, p_prev.momentum.z, - p_prev.mass); - tlv_now.SetXYZM(p_now.momentum.x, p_now.momentum.y, p_now.momentum.z, - p_now.mass); - tlv_reco.SetXYZM(p_reco.momentum.x, p_reco.momentum.y, p_reco.momentum.z, - p_reco.mass); - - std::cout << "reco energy " << tlv_reco.E() << " eta " << tlv_reco.Eta() - << " phi " << tlv_reco.Phi() << " previous PDG " << p_prev.PDG - << " energy " << tlv_prev.E() << " eta " << tlv_prev.Eta() - << " phi " << tlv_prev.Phi() << " dR reco " - << tlv_reco.DeltaR(tlv_prev) << " new PDG " << p_now.PDG - << " energy " << tlv_now.E() << " eta " << tlv_now.Eta() - << " phi " << tlv_now.Phi() << " dR reco " - << tlv_reco.DeltaR(tlv_now) << std::endl; - for (unsigned j = mc.at(result[recind.at(i)]).parents_begin; - j != mc.at(result[recind.at(i)]).parents_end; ++j) { - std::cout << " prev==index " << j << " parents " << parents.at(j) - << " PDGID " << mc.at(parents.at(j)).PDG << " px " - << mc.at(parents.at(j)).momentum.x << " status " - << mc.at(parents.at(j)).generatorStatus << std::endl; - for (unsigned k = mc.at(parents.at(j)).parents_begin; - k != mc.at(parents.at(j)).parents_end; ++k) - std::cout << " prev==index " << k << " grandparents " - << parents.at(k) << " PDGID " << mc.at(parents.at(k)).PDG - << " px " << mc.at(parents.at(k)).momentum.x << " status " - << mc.at(parents.at(k)).generatorStatus << std::endl; + tlv_prev.SetXYZM(p_prev.momentum.x, p_prev.momentum.y, p_prev.momentum.z, p_prev.mass); + tlv_now.SetXYZM(p_now.momentum.x, p_now.momentum.y, p_now.momentum.z, p_now.mass); + tlv_reco.SetXYZM(p_reco.momentum.x, p_reco.momentum.y, p_reco.momentum.z, p_reco.mass); + + std::cout << "reco energy " << tlv_reco.E() << " eta " << tlv_reco.Eta() << " phi " << tlv_reco.Phi() << " previous PDG " << p_prev.PDG << " energy " << tlv_prev.E() << " eta " << tlv_prev.Eta() << " phi " << tlv_prev.Phi() << " dR reco " << tlv_reco.DeltaR(tlv_prev) << " new PDG " << p_now.PDG << " energy " << tlv_now.E() << " eta " << tlv_now.Eta() << " phi " << tlv_now.Phi() << " dR reco " << tlv_reco.DeltaR(tlv_now) < -getRP2MC_parentid(ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc, - ROOT::VecOps::RVec parents) { +getRP2MC_parentid (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc, + ROOT::VecOps::RVec parents){ ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); - for (unsigned int i = 0; i < recind.size(); i++) { - if (mc.at(mcind.at(i)).parents_begin != mc.at(mcind.at(i)).parents_end) { - result[recind.at(i)] = parents.at(mc.at(mcind.at(i)).parents_begin); + result.resize(reco.size(),-1.); + for (unsigned int i=0; i recind, ROOT::VecOps::RVec mcind, for (unsigned int i=0; i getRP2MC_p_func::operator()( - ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { + +ROOT::VecOps::RVec +getRP2MC_p_func::operator() (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - result.resize(reco.size(), -1.); + result.resize(reco.size(),-1.); - for (unsigned int i = 0; i < recind.size(); i++) { + for (unsigned int i=0; i reco.size()) { - std::cout << recind.size() << "=========" << reco.size() << std::endl; - for (unsigned int i = 0; i < recind.size(); i++) { - TLorentzVector tlv; - tlv.SetXYZM(mc.at(mcind.at(i)).momentum.x, mc.at(mcind.at(i)).momentum.y, - mc.at(mcind.at(i)).momentum.z, mc.at(mcind.at(i)).mass); - TLorentzVector tlv2; - tlv2.SetXYZM( - reco.at(recind.at(i)).momentum.x, reco.at(recind.at(i)).momentum.y, - reco.at(recind.at(i)).momentum.z, reco.at(recind.at(i)).mass); - std::cout << "n mc " << mc.size() << " rec ind " << recind.at(i) - << " reco P " << tlv2.P() << " mc ind " << mcind.at(i) - << " truth P " << tlv.P() << " pdg_id " - << mc.at(mcind.at(i)).PDG << " parent_begin " - << mc.at(mcind.at(i)).parents_begin << " parent_end " - << mc.at(mcind.at(i)).parents_end << " daut_begin " - << mc.at(mcind.at(i)).daughters_begin << " daut_end " - << mc.at(mcind.at(i)).daughters_end << std::endl; - } + if (recind.size()>reco.size()){ + std::cout << recind.size() <<"========="< selRP_PDG::operator()( - ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +selRP_PDG::selRP_PDG( int arg_pdg, + bool arg_chargedOnly ): m_PDG(arg_pdg), m_chargedOnly(arg_chargedOnly) {} ; +std::vector +selRP_PDG::operator() (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { std::vector result; - for (int i = 0; i < recind.size(); i++) { - int reco_idx = recind.at(i); - int mc_idx = mcind.at(i); - int pdg = mc.at(mc_idx).PDG; - if (m_chargedOnly) { - if (reco.at(reco_idx).charge == 0) - continue; - } - if (std::abs(pdg) == std::abs(m_PDG)) { - result.push_back(reco.at(reco_idx)); - } + for (int i=0; i selRP_PDG_index::operator()( - ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +selRP_PDG_index::selRP_PDG_index( int arg_pdg, + bool arg_chargedOnly ): m_PDG(arg_pdg), m_chargedOnly(arg_chargedOnly) {} ; +ROOT::VecOps::RVec +selRP_PDG_index::operator() (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { ROOT::VecOps::RVec result; - for (int i = 0; i < recind.size(); i++) { - int reco_idx = recind.at(i); - int mc_idx = mcind.at(i); - int pdg = mc.at(mc_idx).PDG; - if (m_chargedOnly) { - if (reco.at(reco_idx).charge == 0) - continue; - } - if (std::abs(pdg) == std::abs(m_PDG)) { - result.push_back(reco_idx); - } + for (int i=0; i selRP_PDG_index::operator()( // -- select RecoParticles associated with a charged hadron : // -- take all charged RecoParticles that are not associated with a MC lepton -std::vector selRP_ChargedHadrons( - ROOT::VecOps::RVec recind, ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco, - ROOT::VecOps::RVec mc) { +std::vector +selRP_ChargedHadrons (ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco, + ROOT::VecOps::RVec mc) { std::vector result; - for (int i = 0; i < recind.size(); i++) { - int reco_idx = recind.at(i); - int mc_idx = mcind.at(i); - int pdg = mc.at(mc_idx).PDG; - if (reco.at(reco_idx).charge == 0) - continue; - if (std::abs(pdg) == 11 || std::abs(pdg) == 13 || std::abs(pdg) == 15) - continue; - result.push_back(reco.at(reco_idx)); + for (int i=0; i selRP_ChargedHadrons( // ------------------------------------------------------------------------------------------------- -// -- select indices of RecoParticles associated with a list of MC particles -// (passed by their index in the Particle block) +// -- select indices of RecoParticles associated with a list of MC particles (passed by their index in the Particle block) -ROOT::VecOps::RVec selRP_indices_matched_to_list( - const ROOT::VecOps::RVec &mcParticles_indices, - const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, - const ROOT::VecOps::RVec &mc, - bool require_stable) { +ROOT::VecOps::RVec +selRP_indices_matched_to_list( + const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & mc, + bool require_stable) { - ROOT::VecOps::RVec results; - for (auto &idx : mcParticles_indices) { + ROOT::VecOps::RVec results; + for ( auto & idx: mcParticles_indices ) { // exclude unstable particles - e.g. the list may contain the index of // the mother - // MG: Should we push_back -1 here for consistency? - if (require_stable && mc.at(idx).generatorStatus != 1) - continue; + // MG: Should we push_back -1 here for consistency? + if (require_stable && mc.at(idx).generatorStatus != 1 ) continue ; // is this MC particle associated with a Reco particle : bool found = false; - for (int i = 0; i < recind.size(); i++) { + for (int i=0; i selRP_matched_to_list( - const ROOT::VecOps::RVec &mcParticles_indices, - const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, - const ROOT::VecOps::RVec &reco, - const ROOT::VecOps::RVec &mc, - bool require_stable) { +ROOT::VecOps::RVec +selRP_matched_to_list( const ROOT::VecOps::RVec & mcParticles_indices, + const ROOT::VecOps::RVec & recind, + const ROOT::VecOps::RVec & mcind, + const ROOT::VecOps::RVec & reco, + const ROOT::VecOps::RVec & mc, + bool require_stable) { edm4hep::ReconstructedParticleData dummy; dummy.energy = -9999; - dummy.tracks_begin = -9999; - - ROOT::VecOps::RVec results; - ROOT::VecOps::RVec indices = selRP_indices_matched_to_list( - mcParticles_indices, recind, mcind, mc, require_stable); - for (int reco_idx : indices) { - if (reco_idx < 0) - results.push_back(dummy); - else - results.push_back(reco.at(reco_idx)); + dummy.tracks_begin = -9999 ; + + ROOT::VecOps::RVec results; + ROOT::VecOps::RVec indices = selRP_indices_matched_to_list(mcParticles_indices, + recind, + mcind, + mc, + require_stable); + for (int reco_idx : indices){ + if (reco_idx < 0) results.push_back( dummy ); + else results.push_back( reco.at( reco_idx ) ); } return results; + } + + + // ------------------------------------------------------------------------------------------------- -int getTrack2MC_index( - int track_index, ROOT::VecOps::RVec recind, - ROOT::VecOps::RVec mcind, - ROOT::VecOps::RVec reco) { +int getTrack2MC_index (int track_index, + ROOT::VecOps::RVec recind, + ROOT::VecOps::RVec mcind, + ROOT::VecOps::RVec reco) { int mc_index = -1; - for (int i = 0; i < recind.size(); i++) { - int reco_idx = recind.at(i); - // keep only charged particles - if (reco.at(reco_idx).charge == 0) - continue; - mc_index = mcind.at(i); - if (reco.at(reco_idx).tracks_begin == track_index) - return mc_index; - } - return mc_index; + for (int i=0; i #include "TrkUtil.h" // from delphes -#include namespace FCCAnalyses { @@ -26,7 +26,7 @@ TVectorD XPtoPar(TVector3 x, TVector3 p, Double_t Q) { selTracks::selTracks(float arg_d0sig_min, float arg_d0sig_max, float arg_z0sig_min, float arg_z0sig_max) : m_d0sig_min(arg_d0sig_min), m_d0sig_max(arg_d0sig_max), - m_z0sig_min(arg_z0sig_min), m_z0sig_max(arg_z0sig_max) {}; + m_z0sig_min(arg_z0sig_min), m_z0sig_max(arg_z0sig_max){}; ROOT::VecOps::RVec selTracks::operator()( ROOT::VecOps::RVec recop, ROOT::VecOps::RVec tracks) { @@ -370,11 +370,11 @@ ROOT::VecOps::RVec get_VertexRecoParticlesInd( } ROOT::VecOps::RVec get_VerticesRecoParticlesInd( - ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec vertices, const ROOT::VecOps::RVec &reco) { ROOT::VecOps::RVec result; - for (int j = 0; j < vertices.size(); ++j) { + for (int j = 0; j < vertices.size(); ++j){ ROOT::VecOps::RVec indices_tracks = vertices[j].reco_ind; for (int i = 0; i < indices_tracks.size(); i++) { int tk_index = indices_tracks[i]; @@ -389,31 +389,29 @@ ROOT::VecOps::RVec get_VerticesRecoParticlesInd( } } } - + return result; -} +} -int getVertex_matching_recoParticles( - const ROOT::VecOps::RVec &vertices, - const ROOT::VecOps::RVec &recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all) { - std::set indicesWeWant; - indicesWeWant.insert(recoParticleIndices.begin(), recoParticleIndices.end()); +int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, + const ROOT::VecOps::RVec & recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all){ + std::set indicesWeWant; + indicesWeWant.insert(recoParticleIndices.begin(),recoParticleIndices.end()); // correct for "-1" representing missed tracks in the recoParticleIndices - int correctMissing = indicesWeWant.count(-1); - for (int iVX = 0; iVX < vertices.size(); ++iVX) { - auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX], reco); - int nFound = std::count_if( - vxParticleIndices.begin(), vxParticleIndices.end(), - [&](int recoIndex) { return indicesWeWant.count(recoIndex); }); - if (require_all && nFound == indicesWeWant.size() - correctMissing || - nFound == vxParticleIndices.size()) - return iVX; + int correctMissing = indicesWeWant.count(-1); + for (int iVX = 0; iVX < vertices.size(); ++iVX){ + auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX],reco); + int nFound = std::count_if(vxParticleIndices.begin(), vxParticleIndices.end(),[&](int recoIndex){ + return indicesWeWant.count(recoIndex); + }) ; + if (require_all && nFound == indicesWeWant.size() - correctMissing || nFound == vxParticleIndices.size()) return iVX; } - return -1; + return -1; } + TVectorD ParToACTS(TVectorD Par) { TVectorD pACTS(6); // Return vector From 67704a94c5d4f94aa936915476fe851c917db63c Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Tue, 17 Feb 2026 17:12:32 +0100 Subject: [PATCH 06/13] format fixes --- analyzers/dataframe/FCCAnalyses/MCParticle.h | 45 ++- .../FCCAnalyses/ReconstructedParticle2MC.h | 61 ++-- .../FCCAnalyses/ReconstructedParticle2Track.h | 321 ++++++++++-------- analyzers/dataframe/FCCAnalyses/Utils.h | 79 +++-- .../FCCAnalyses/VertexFitterSimple.h | 1 - .../dataframe/FCCAnalyses/VertexingUtils.h | 22 +- analyzers/dataframe/FCCAnalyses/myUtils.h | 3 +- analyzers/dataframe/src/MCParticle.cc | 137 ++++---- .../dataframe/src/ReconstructedParticle2MC.cc | 75 ++-- analyzers/dataframe/src/VertexingUtils.cc | 36 +- 10 files changed, 431 insertions(+), 349 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index 43f6d005497..bb1f1114343 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -3,8 +3,8 @@ #define MCPARTICLE_ANALYZERS_H #include -#include #include +#include #include "ROOT/RVec.hxx" #include "TLorentzVector.h" @@ -31,20 +31,28 @@ namespace MCParticle{ bool operator() (ROOT::VecOps::RVec in); }; - /// @brief Helper struct to select entries matching a certain predicate. - /// Supports two signatures - either a list of candidates is passed and a list of accepted candidates returned, - /// Or a list of indices in a vector of candidates is passed and a list of accepted indices returned. - /// The latter is more compatible with index-based selection logic. - struct selByPredicate{ - selByPredicate(std::function thePredicate):m_predicate(thePredicate){} - std::function m_predicate; - ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & in); - ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in); - ROOT::VecOps::RVec> operator() (const ROOT::VecOps::RVec> & indices, const ROOT::VecOps::RVec & in); + /// @brief Helper struct to select entries matching a certain predicate. + /// Supports two signatures - either a list of candidates is passed and a list + /// of accepted candidates returned, Or a list of indices in a vector of + /// candidates is passed and a list of accepted indices returned. The latter + /// is more compatible with index-based selection logic. + struct selByPredicate { + selByPredicate( + std::function thePredicate) + : m_predicate(thePredicate) {} + std::function m_predicate; + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &in); + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &indices, + const ROOT::VecOps::RVec &in); + ROOT::VecOps::RVec> + operator()(const ROOT::VecOps::RVec> &indices, + const ROOT::VecOps::RVec &in); }; /// select MCParticles with transverse momentum greater than a minimum value [GeV] - struct sel_pt : selByPredicate{ + struct sel_pt : selByPredicate { sel_pt(float arg_min_pt); }; @@ -225,10 +233,15 @@ namespace MCParticle{ /// return the list of stable particles from the decay of a mother particle, looking at the full decay chain recursively. i is the mother index in the Particle block std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; - /// return the list of stable particles from the decays of a mother particle, looking at the full decay chain recursively. - /// i is the list of mother indices to process in the Particle block. - /// Will return a vector of vectors - each vector is the set of children for one of the mothers in the input vector - ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays( ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) ; + /// return the list of stable particles from the decays of a mother particle, + /// looking at the full decay chain recursively. i is the list of mother + /// indices to process in the Particle block. Will return a vector of vectors + /// - each vector is the set of children for one of the mothers in the input + /// vector + ROOT::VecOps::RVec> + get_lists_of_stable_particles_from_decays( + ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind); /// return the list of particles from the decay of a mother particle. i is the mother index in the Particle block. std::vector get_list_of_particles_from_decay( int i, diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h index 149e2132ba8..d1c5f1a20fc 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2MC.h @@ -125,35 +125,44 @@ namespace ReconstructedParticle2MC{ ROOT::VecOps::RVec reco, ROOT::VecOps::RVec mc) ; - /// select ReconstructedParticles matched to the MC particles whose indices are passed in a list - /// @param mcParticles_indices indices of the MC particles to look up - /// @param recind: reco index component of the MCRecoAssociations - /// @param mcind: mc index component of the MCRecoAssociations + /// select ReconstructedParticles matched to the MC particles whose indices + /// are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations /// @param reco: full reco particle list (ReconstructedParticles) /// @param mc: full mc particle list (Particles) - /// @param require_stable: if set to true, will only match stable particles. - /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a dummy particle will be inserted. If 1:1 length correspondence is required, set require_stable to false. - ROOT::VecOps::RVec selRP_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & reco, - const ROOT::VecOps::RVec & mc, - bool require_stable = true) ; - /// select indices of ReconstructedParticles matched to the MC particles whose indices are passed in a list - /// @param mcParticles_indices indices of the MC particles to look up - /// @param recind: reco index component of the MCRecoAssociations - /// @param mcind: mc index component of the MCRecoAssociations + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding + /// to the number of *stable* MC particles in the mcParticles_indices vector. + /// In presence of unstable particles, no 1:1 correspondence. For + /// non-reconstructed stable MC particles, a dummy particle will be inserted. + /// If 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, + const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &reco, + const ROOT::VecOps::RVec &mc, + bool require_stable = true); + /// select indices of ReconstructedParticles matched to the MC particles whose + /// indices are passed in a list + /// @param mcParticles_indices indices of the MC particles to look up + /// @param recind: reco index component of the MCRecoAssociations + /// @param mcind: mc index component of the MCRecoAssociations /// @param mc: full mc particle list (Particles) - /// @param require_stable: if set to true, will only match stable particles. - /// @return List of ReconstructedParticle candidates with length corresponding to the number of *stable* MC particles in the mcParticles_indices vector. In presence of unstable particles, no 1:1 correspondence. For non-reconstructed stable MC particles, a "-1" entry will be inserted. If 1:1 length correspondence is required, set require_stable to false. - ROOT::VecOps::RVec selRP_indices_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & mc, - bool require_stable = true - ) ; + /// @param require_stable: if set to true, will only match stable particles. + /// @return List of ReconstructedParticle candidates with length corresponding + /// to the number of *stable* MC particles in the mcParticles_indices vector. + /// In presence of unstable particles, no 1:1 correspondence. For + /// non-reconstructed stable MC particles, a "-1" entry will be inserted. If + /// 1:1 length correspondence is required, set require_stable to false. + ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, + const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &mc, + bool require_stable = true); /// return the index of the MC particle that is associated to a given track (via the track-reco association) int getTrack2MC_index ( int track_index, diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h index 44f898c220f..6693c39a82b 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h @@ -28,147 +28,186 @@ namespace FCCAnalyses{ namespace ReconstructedParticle2Track{ - /// Return the momentum of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_mom (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the charge of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_charge(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - //compute the magnetic field Bz - ROOT::VecOps::RVec getRP2TRK_Bz(const ROOT::VecOps::RVec& rps, - const ROOT::VecOps::RVec& tracks); //here computed for all particles passed - - float Bz(const ROOT::VecOps::RVec& rps, - const ROOT::VecOps::RVec& tracks); //here only computed for the first charged particle encountered - - ROOT::VecOps::RVec XPtoPar_dxy(const ROOT::VecOps::RVec& in, - const ROOT::VecOps::RVec& tracks, - const TLorentzVector& V, // primary vertex - const float& Bz); - - ROOT::VecOps::RVec XPtoPar_dz(const ROOT::VecOps::RVec& in, - const ROOT::VecOps::RVec& tracks, - const TLorentzVector& V, // primary vertex - const float& Bz); - - ROOT::VecOps::RVec XPtoPar_phi(const ROOT::VecOps::RVec& in, - const ROOT::VecOps::RVec& tracks, - const TLorentzVector& V, // primary vertex - const float& Bz); - - ROOT::VecOps::RVec XPtoPar_C(const ROOT::VecOps::RVec& in, - const ROOT::VecOps::RVec& tracks, - const float& Bz); - - ROOT::VecOps::RVec XPtoPar_ct(const ROOT::VecOps::RVec& in, - const ROOT::VecOps::RVec& tracks, - const float& Bz); - - /// Return the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_D0 (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the Z0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_Z0 (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the Phi of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_phi (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the omega of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_omega (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the tanLambda of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_tanLambda (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the D0 significance of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_D0_sig (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the Z0 significance of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_Z0_sig (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - - /// Return the variance (not the sigma) of the the D0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_D0_cov (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the variance (not the sigma) of the the Z0 of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_Z0_cov (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the variance (not the sigma) of the the Phi of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_phi_cov (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the variance (not the sigma) of the omega of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_omega_cov (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the variance (not the sigma) of the tanLambda of a track to a reconstructed particle - ROOT::VecOps::RVec getRP2TRK_tanLambda_cov (ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (d0, phi0) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_d0_phi0_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (d0, omega) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_d0_omega_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (d0,z0) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_d0_z0_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (d0,tanlambda) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_d0_tanlambda_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (phi0,omega) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_phi0_omega_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (phi0,z0) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_phi0_z0_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - /// Return the off-diag term (phi0,tanlambda) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_phi0_tanlambda_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks) ; - - /// Return the off-diag term (omega,z0) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_omega_z0_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks) ; - - /// Return the off-diag term (omega,tanlambda) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_omega_tanlambda_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks) ; - - /// Return the off-diag term (z0,tanlambda) of the covariance matrix - ROOT::VecOps::RVec getRP2TRK_z0_tanlambda_cov(ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks); - - - /// Return the tracks associated to reco'ed particles - ROOT::VecOps::RVec getRP2TRK( ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks ) ; - - /// Return the reco indices of particles that have tracks - ROOT::VecOps::RVec get_recoindTRK( ROOT::VecOps::RVec in, - ROOT::VecOps::RVec tracks ) ; - - /// Return the size of a collection of TrackStates - int getTK_n(ROOT::VecOps::RVec x) ; - - /// Return if a Reco particle have an associated track - ROOT::VecOps::RVec hasTRK( ROOT::VecOps::RVec in ) ; +/// Return the momentum of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_mom(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the charge of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_charge(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +// compute the magnetic field Bz +ROOT::VecOps::RVec +getRP2TRK_Bz(const ROOT::VecOps::RVec &rps, + const ROOT::VecOps::RVec + &tracks); // here computed for all particles passed + +float Bz(const ROOT::VecOps::RVec &rps, + const ROOT::VecOps::RVec + &tracks); // here only computed for the first charged particle + // encountered + +ROOT::VecOps::RVec +XPtoPar_dxy(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &tracks, + const TLorentzVector &V, // primary vertex + const float &Bz); + +ROOT::VecOps::RVec +XPtoPar_dz(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &tracks, + const TLorentzVector &V, // primary vertex + const float &Bz); + +ROOT::VecOps::RVec +XPtoPar_phi(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &tracks, + const TLorentzVector &V, // primary vertex + const float &Bz); + +ROOT::VecOps::RVec +XPtoPar_C(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &tracks, + const float &Bz); + +ROOT::VecOps::RVec +XPtoPar_ct(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &tracks, + const float &Bz); + +/// Return the D0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_D0(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the Z0 of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_Z0(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the Phi of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_phi(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the omega of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_omega(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the tanLambda of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_tanLambda(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the D0 significance of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_D0_sig(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the Z0 significance of a track to a reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_Z0_sig(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the variance (not the sigma) of the the D0 of a track to a +/// reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_D0_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the variance (not the sigma) of the the Z0 of a track to a +/// reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_Z0_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the variance (not the sigma) of the the Phi of a track to a +/// reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_phi_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the variance (not the sigma) of the omega of a track to a +/// reconstructed particle +ROOT::VecOps::RVec +getRP2TRK_omega_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the variance (not the sigma) of the tanLambda of a track to a +/// reconstructed particle +ROOT::VecOps::RVec getRP2TRK_tanLambda_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (d0, phi0) of the covariance matrix +ROOT::VecOps::RVec +getRP2TRK_d0_phi0_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (d0, omega) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_d0_omega_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (d0,z0) of the covariance matrix +ROOT::VecOps::RVec +getRP2TRK_d0_z0_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (d0,tanlambda) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_d0_tanlambda_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (phi0,omega) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_phi0_omega_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (phi0,z0) of the covariance matrix +ROOT::VecOps::RVec +getRP2TRK_phi0_z0_cov(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (phi0,tanlambda) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_phi0_tanlambda_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (omega,z0) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_omega_z0_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (omega,tanlambda) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_omega_tanlambda_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the off-diag term (z0,tanlambda) of the covariance matrix +ROOT::VecOps::RVec getRP2TRK_z0_tanlambda_cov( + ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the tracks associated to reco'ed particles +ROOT::VecOps::RVec +getRP2TRK(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the reco indices of particles that have tracks +ROOT::VecOps::RVec +get_recoindTRK(ROOT::VecOps::RVec in, + ROOT::VecOps::RVec tracks); + +/// Return the size of a collection of TrackStates +int getTK_n(ROOT::VecOps::RVec x); + +/// Return if a Reco particle have an associated track +ROOT::VecOps::RVec +hasTRK(ROOT::VecOps::RVec in); }//end NS ReconstructedParticle2Track diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index 70f305faa87..eb0b3106dc9 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -1,51 +1,68 @@ #ifndef UTILS_ANALYZERS_H #define UTILS_ANALYZERS_H -#include #include +#include namespace FCCAnalyses { namespace Utils { template inline auto getsize( T& vec){ return vec.size();}; - template inline ROOT::VecOps::RVec > as_vector(const ROOT::VecOps::RVec& in){return ROOT::VecOps::RVec >(1, in);}; - template inline ROOT::VecOps::RVec index_range(const ROOT::VecOps::RVec & in){ - ROOT::VecOps::RVec indices(in.size()); - std::iota(indices.begin(),indices.end(), 0); - return indices; - }; - /// @brief count the number of valid (>=0, < size of collection) indices in an index list + template + inline ROOT::VecOps::RVec> + as_vector(const ROOT::VecOps::RVec &in) { + return ROOT::VecOps::RVec>(1, in); + }; + template + inline ROOT::VecOps::RVec + index_range(const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec indices(in.size()); + std::iota(indices.begin(), indices.end(), 0); + return indices; + }; + /// @brief count the number of valid (>=0, < size of collection) indices in + /// an index list /// @param in: index list - /// @param ref: particle vector to which the indices refer. - /// @return integer count of valid indices - template inline int count_valid_indices(const ROOT::VecOps::RVec & in, - const ROOT::VecOps::RVec & ref){ - int maxSize = ref.size(); - return std::count_if(in.begin(),in.end(),[maxSize](const int & i){return (i >=0 && i < maxSize);}); + /// @param ref: particle vector to which the indices refer. + /// @return integer count of valid indices + template + inline int count_valid_indices(const ROOT::VecOps::RVec &in, + const ROOT::VecOps::RVec &ref) { + int maxSize = ref.size(); + return std::count_if(in.begin(), in.end(), [maxSize](const int &i) { + return (i >= 0 && i < maxSize); + }); }; - // @brief for a given list of indices, returns a list of particle (copies) + // @brief for a given list of indices, returns a list of particle (copies) /// @param idx : Indices of desired particles within the full set ("in") - /// @param in : Full set of particles - /// @return A vector of particles with the desired indices. - template inline ROOT::VecOps::RVec sel_byIndex( const ROOT::VecOps::RVec & idx, const ROOT::VecOps::RVec & in){ - ROOT::VecOps::RVec found; - for (int index : idx){ - if (index < 0 || index >= in.size()) continue; - found.push_back(in.at(index)); + /// @param in : Full set of particles + /// @return A vector of particles with the desired indices. + template + inline ROOT::VecOps::RVec sel_byIndex(const ROOT::VecOps::RVec &idx, + const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec found; + for (int index : idx) { + if (index < 0 || index >= in.size()) + continue; + found.push_back(in.at(index)); } - return found; + return found; } - // @brief merge (concatenate) two collections of arbitrary content + // @brief merge (concatenate) two collections of arbitrary content /// @param x : first collection - entries will be copied in-order - /// @param y : second collection - entries will be copied in-order after the last element of the first - /// @return A combined collection of size (x.size()+y.size()), containing the content of x followed by that of y - template inline ROOT::VecOps::RVec merge( const ROOT::VecOps::RVec & x, const ROOT::VecOps::RVec & y){ + /// @param y : second collection - entries will be copied in-order after the + /// last element of the first + /// @return A combined collection of size (x.size()+y.size()), containing + /// the content of x followed by that of y + template + inline ROOT::VecOps::RVec merge(const ROOT::VecOps::RVec &x, + const ROOT::VecOps::RVec &y) { ROOT::VecOps::RVec merged; - merged.reserve(x.size()+y.size()); - merged.insert(merged.end(), x.begin(), x.end()); - merged.insert(merged.end(), y.begin(), y.end()); - return merged; + merged.reserve(x.size() + y.size()); + merged.insert(merged.end(), x.begin(), x.end()); + merged.insert(merged.end(), y.begin(), y.end()); + return merged; } } } diff --git a/analyzers/dataframe/FCCAnalyses/VertexFitterSimple.h b/analyzers/dataframe/FCCAnalyses/VertexFitterSimple.h index a3a401aa86b..948a630eaa1 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexFitterSimple.h +++ b/analyzers/dataframe/FCCAnalyses/VertexFitterSimple.h @@ -71,7 +71,6 @@ namespace VertexFitterSimple{ ROOT::VecOps::RVec IsPrimary_forTracks( ROOT::VecOps::RVec allTracks, ROOT::VecOps::RVec primaryTracks ) ; - /* Double_t FastRv(TVectorD p1, TVectorD p2) ; TMatrixDSym RegInv3(TMatrixDSym &Smat0) ; diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index f913f0ea0e5..bc4686659e7 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -112,16 +112,22 @@ namespace VertexingUtils{ ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, const ROOT::VecOps::RVec& reco ); - /// @brief Find (by index) a vertex that is made of reco particles from a passed list. + /// @brief Find (by index) a vertex that is made of reco particles from a + /// passed list. /// @param vertices: List of possible vertices to match - /// @param recoParticleIndices: Indices of the reco particles to find in the vertex + /// @param recoParticleIndices: Indices of the reco particles to find in the + /// vertex /// @param reco: list of all reco particles (ReconstructedParticles) - /// @param require_all: If set, require one vertex to contain all recoParticleIndices (no 'missed' tracks). Else only require that all tracks in the vertex come from the vector (but allow for unused tracks) - /// @return: Index within the list of the (first) vertex fulfilling the criteria. If none are found, return -1 - int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, - const ROOT::VecOps::RVec & recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all = false); + /// @param require_all: If set, require one vertex to contain all + /// recoParticleIndices (no 'missed' tracks). Else only require that all + /// tracks in the vertex come from the vector (but allow for unused tracks) + /// @return: Index within the list of the (first) vertex fulfilling the + /// criteria. If none are found, return -1 + int getVertex_matching_recoParticles( + const ROOT::VecOps::RVec &vertices, + const ROOT::VecOps::RVec &recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all = false); /// Return the number of tracks in a given track collection int get_nTracks(ROOT::VecOps::RVec tracks); diff --git a/analyzers/dataframe/FCCAnalyses/myUtils.h b/analyzers/dataframe/FCCAnalyses/myUtils.h index 2b8f3a6ded2..fbff7eaffb1 100644 --- a/analyzers/dataframe/FCCAnalyses/myUtils.h +++ b/analyzers/dataframe/FCCAnalyses/myUtils.h @@ -1,8 +1,8 @@ #ifndef MYUTILS_ANALYZERS_H #define MYUTILS_ANALYZERS_H #include "ROOT/RVec.hxx" -#include "edm4hep/ReconstructedParticleData.h" #include "edm4hep/MCParticleData.h" +#include "edm4hep/ReconstructedParticleData.h" #include "edm4hep/TrackState.h" #include "edm4hep/VertexData.h" @@ -77,7 +77,6 @@ namespace myUtils{ ROOT::VecOps::RVec operator() (ROOT::VecOps::RVec recop); }; - ROOT::VecOps::RVec get_pseudotrack(ROOT::VecOps::RVec vertex, ROOT::VecOps::RVec recop); diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 025cb050042..7b163496e45 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -8,67 +8,74 @@ namespace FCCAnalyses{ namespace MCParticle{ - -ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec & in){ +ROOT::VecOps::RVec selByPredicate::operator()( + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); - for (auto & p : in) { - if (m_predicate(p)) result.emplace_back(p); - } - return result; + for (auto &p : in) { + if (m_predicate(p)) + result.emplace_back(p); + } + return result; } -ROOT::VecOps::RVec selByPredicate::operator() (const ROOT::VecOps::RVec& indices, const ROOT::VecOps::RVec &in){ +ROOT::VecOps::RVec selByPredicate::operator()( + const ROOT::VecOps::RVec &indices, + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); for (int index : indices) { - if (index < 0 || index >= in.size()) continue; - if (m_predicate(in[index])) result.emplace_back(index); - } - return result; -} -ROOT::VecOps::RVec> selByPredicate::operator() (const ROOT::VecOps::RVec>& setsOfIndices, const ROOT::VecOps::RVec &in){ - ROOT::VecOps::RVec> result(setsOfIndices.size()); - for (int elem = 0; elem < setsOfIndices.size(); ++elem){ - result[elem] = this->operator()(setsOfIndices[elem], in); + if (index < 0 || index >= in.size()) + continue; + if (m_predicate(in[index])) + result.emplace_back(index); } - return result; -} - -sel_pt::sel_pt(float arg_min_pt) : - selByPredicate([arg_min_pt](const edm4hep::MCParticleData & p)->bool{ - return (p.momentum.x*p.momentum.x + p.momentum.y*p.momentum.y > arg_min_pt*arg_min_pt); - }){ -} - -sel_eta::sel_eta(float arg_max_eta) : - selByPredicate([arg_max_eta](const edm4hep::MCParticleData & p)->bool{ - ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); - return std::abs(vec.Eta()) < std::abs(arg_max_eta); - }){ -} - -sel_genStatus::sel_genStatus(int arg_status): - selByPredicate([arg_status](const edm4hep::MCParticleData & p)->bool{ - return p.generatorStatus == arg_status; - }){ -} - -sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate): - selByPredicate([arg_pdg, arg_chargeconjugate](const edm4hep::MCParticleData & p)->bool{ - if (arg_chargeconjugate) return std::abs( p.PDG ) == std::abs( arg_pdg); - else return p.PDG == arg_pdg; - }){ -} - -sel_charged::sel_charged(): - selByPredicate([](const edm4hep::MCParticleData & p)->bool{ - // try to avoid floating comp to zero - // and thank you for the person who gave some neutral particles a -999 charge! - return std::abs(p.charge) > 1e-6 && p.charge != -999; - }){ + return result; } - +ROOT::VecOps::RVec> selByPredicate::operator()( + const ROOT::VecOps::RVec> &setsOfIndices, + const ROOT::VecOps::RVec &in) { + ROOT::VecOps::RVec> result(setsOfIndices.size()); + for (int elem = 0; elem < setsOfIndices.size(); ++elem) { + result[elem] = this->operator()(setsOfIndices[elem], in); + } + return result; +} + +sel_pt::sel_pt(float arg_min_pt) + : selByPredicate([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { + return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > + arg_min_pt * arg_min_pt); + }) {} + +sel_eta::sel_eta(float arg_max_eta) + : selByPredicate([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { + ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, + p.mass); + return std::abs(vec.Eta()) < std::abs(arg_max_eta); + }) {} + +sel_genStatus::sel_genStatus(int arg_status) + : selByPredicate([arg_status](const edm4hep::MCParticleData &p) -> bool { + return p.generatorStatus == arg_status; + }) {} + +sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) + : selByPredicate([arg_pdg, arg_chargeconjugate]( + const edm4hep::MCParticleData &p) -> bool { + if (arg_chargeconjugate) + return std::abs(p.PDG) == std::abs(arg_pdg); + else + return p.PDG == arg_pdg; + }) {} + +sel_charged::sel_charged() + : selByPredicate([](const edm4hep::MCParticleData &p) -> bool { + // try to avoid floating comp to zero + // and thank you for the person who gave some neutral particles a -999 + // charge! + return std::abs(p.charge) > 1e-6 && p.charge != -999; + }) {} get_decay::get_decay(int arg_mother, int arg_daughters, bool arg_inf){m_mother=arg_mother; m_daughters=arg_daughters; m_inf=arg_inf;}; bool get_decay::operator() (ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind){ @@ -90,7 +97,6 @@ bool get_decay::operator() (ROOT::VecOps::RVec in, ROO return result; } - filter_pdgID::filter_pdgID(int arg_pdgid, bool arg_abs){m_pdgid = arg_pdgid; m_abs = arg_abs;}; bool filter_pdgID::operator() (ROOT::VecOps::RVec in) { for (size_t i = 0; i < in.size(); ++i) { @@ -521,7 +527,8 @@ std::vector get_list_of_stable_particles_from_decay( int i, ROOT::VecOps::R for (int id = db; id < de; id++) { int idaughter = ind[ id ]; // prevent endless loop in case of looping MC record - if (idaughter == i) continue; + if (idaughter == i) + continue; std::vector rr = get_list_of_stable_particles_from_decay( idaughter, in, ind) ; res.insert( res.end(), rr.begin(), rr.end() ); } @@ -560,17 +567,19 @@ std::vector get_list_of_particles_from_decay(int i, ROOT::VecOps::RVec> get_lists_of_stable_particles_from_decays(ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, ROOT::VecOps::RVec ind) { +ROOT::VecOps::RVec> +get_lists_of_stable_particles_from_decays( + ROOT::VecOps::RVec i, ROOT::VecOps::RVec in, + ROOT::VecOps::RVec ind) { - ROOT::VecOps::RVec> ret; - ret.reserve(i.size()); - for (int ix : i){ - ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); + ROOT::VecOps::RVec> ret; + ret.reserve(i.size()); + for (int ix : i) { + ret.push_back(get_list_of_stable_particles_from_decay(ix, in, ind)); } - return ret; + return ret; } - // ---------------------------------------------------------------------------------------------------------------------------------- // obsolete: keep for the while, for backward compatibility @@ -585,12 +594,6 @@ std::vector list_of_particles_from_decay(int i, ROOT::VecOps::RVec get_indices_MotherByIndex ( int imother, diff --git a/analyzers/dataframe/src/ReconstructedParticle2MC.cc b/analyzers/dataframe/src/ReconstructedParticle2MC.cc index 244b716785c..6a6d510082a 100644 --- a/analyzers/dataframe/src/ReconstructedParticle2MC.cc +++ b/analyzers/dataframe/src/ReconstructedParticle2MC.cc @@ -337,23 +337,23 @@ selRP_ChargedHadrons (ROOT::VecOps::RVec recind, // ------------------------------------------------------------------------------------------------- -// -- select indices of RecoParticles associated with a list of MC particles (passed by their index in the Particle block) +// -- select indices of RecoParticles associated with a list of MC particles +// (passed by their index in the Particle block) -ROOT::VecOps::RVec -selRP_indices_matched_to_list( - const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & mc, - bool require_stable) { - - ROOT::VecOps::RVec results; +ROOT::VecOps::RVec selRP_indices_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &mc, + bool require_stable) { + + ROOT::VecOps::RVec results; for ( auto & idx: mcParticles_indices ) { // exclude unstable particles - e.g. the list may contain the index of // the mother - // MG: Should we push_back -1 here for consistency? - if (require_stable && mc.at(idx).generatorStatus != 1 ) continue ; + // MG: Should we push_back -1 here for consistency? + if (require_stable && mc.at(idx).generatorStatus != 1) + continue; // is this MC particle associated with a Reco particle : bool found = false; @@ -362,52 +362,47 @@ selRP_indices_matched_to_list( int mc_idx = mcind.at(i); if ( mc_idx == idx ) { found = true; - results.push_back( reco_idx ); + results.push_back(reco_idx); break; } } // no Reco particle has been found for idx: add a dummy particle such that // one preserves the mapping with the input list - // Note: This is inconsistent, the mapping will be + // Note: This is inconsistent, the mapping will be // lost whenever there is an unstable particle in the input list. - // Will keep current behaviour for backward compatibility... - if ( ! found) results.push_back( -1 ); + // Will keep current behaviour for backward compatibility... + if (!found) + results.push_back(-1); } // loop over the indices in the list return results; - } -// -- select RecoParticles associated with a list of MC particles (passed by their index in the Particle block) +// -- select RecoParticles associated with a list of MC particles (passed by +// their index in the Particle block) -ROOT::VecOps::RVec -selRP_matched_to_list( const ROOT::VecOps::RVec & mcParticles_indices, - const ROOT::VecOps::RVec & recind, - const ROOT::VecOps::RVec & mcind, - const ROOT::VecOps::RVec & reco, - const ROOT::VecOps::RVec & mc, - bool require_stable) { +ROOT::VecOps::RVec selRP_matched_to_list( + const ROOT::VecOps::RVec &mcParticles_indices, + const ROOT::VecOps::RVec &recind, const ROOT::VecOps::RVec &mcind, + const ROOT::VecOps::RVec &reco, + const ROOT::VecOps::RVec &mc, + bool require_stable) { edm4hep::ReconstructedParticleData dummy; dummy.energy = -9999; - dummy.tracks_begin = -9999 ; - - ROOT::VecOps::RVec results; - ROOT::VecOps::RVec indices = selRP_indices_matched_to_list(mcParticles_indices, - recind, - mcind, - mc, - require_stable); - for (int reco_idx : indices){ - if (reco_idx < 0) results.push_back( dummy ); - else results.push_back( reco.at( reco_idx ) ); + dummy.tracks_begin = -9999; + + ROOT::VecOps::RVec results; + ROOT::VecOps::RVec indices = selRP_indices_matched_to_list( + mcParticles_indices, recind, mcind, mc, require_stable); + for (int reco_idx : indices) { + if (reco_idx < 0) + results.push_back(dummy); + else + results.push_back(reco.at(reco_idx)); } return results; - } - - - // ------------------------------------------------------------------------------------------------- int getTrack2MC_index (int track_index, diff --git a/analyzers/dataframe/src/VertexingUtils.cc b/analyzers/dataframe/src/VertexingUtils.cc index 80520b256c7..074d71b369c 100644 --- a/analyzers/dataframe/src/VertexingUtils.cc +++ b/analyzers/dataframe/src/VertexingUtils.cc @@ -1,7 +1,7 @@ #include "FCCAnalyses/VertexingUtils.h" #include "FCCAnalyses/VertexFitterSimple.h" -#include #include "TrkUtil.h" // from delphes +#include namespace FCCAnalyses { @@ -391,27 +391,29 @@ ROOT::VecOps::RVec get_VerticesRecoParticlesInd( } return result; -} +} -int getVertex_matching_recoParticles(const ROOT::VecOps::RVec & vertices, - const ROOT::VecOps::RVec & recoParticleIndices, - const ROOT::VecOps::RVec &reco, - bool require_all){ - std::set indicesWeWant; - indicesWeWant.insert(recoParticleIndices.begin(),recoParticleIndices.end()); +int getVertex_matching_recoParticles( + const ROOT::VecOps::RVec &vertices, + const ROOT::VecOps::RVec &recoParticleIndices, + const ROOT::VecOps::RVec &reco, + bool require_all) { + std::set indicesWeWant; + indicesWeWant.insert(recoParticleIndices.begin(), recoParticleIndices.end()); // correct for "-1" representing missed tracks in the recoParticleIndices - int correctMissing = indicesWeWant.count(-1); - for (int iVX = 0; iVX < vertices.size(); ++iVX){ - auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX],reco); - int nFound = std::count_if(vxParticleIndices.begin(), vxParticleIndices.end(),[&](int recoIndex){ - return indicesWeWant.count(recoIndex); - }) ; - if (require_all && nFound == indicesWeWant.size() - correctMissing || nFound == vxParticleIndices.size()) return iVX; + int correctMissing = indicesWeWant.count(-1); + for (int iVX = 0; iVX < vertices.size(); ++iVX) { + auto vxParticleIndices = get_VertexRecoParticlesInd(vertices[iVX], reco); + int nFound = std::count_if( + vxParticleIndices.begin(), vxParticleIndices.end(), + [&](int recoIndex) { return indicesWeWant.count(recoIndex); }); + if (require_all && nFound == indicesWeWant.size() - correctMissing || + nFound == vxParticleIndices.size()) + return iVX; } - return -1; + return -1; } - TVectorD ParToACTS(TVectorD Par) { TVectorD pACTS(6); // Return vector From 598ad75880fe9f275e5a993d1957936103a34da8 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Fri, 20 Feb 2026 11:53:08 +0100 Subject: [PATCH 07/13] the formatter strikes again --- analyzers/dataframe/FCCAnalyses/VertexingUtils.h | 5 +++-- analyzers/dataframe/src/VertexingUtils.cc | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index bc4686659e7..fe88c5454c8 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -109,8 +109,9 @@ namespace VertexingUtils{ const ROOT::VecOps::RVec& reco ); /// Retrieve the indices of the tracks fitted to a vector of vertices, but now in the collection of RecoParticles - ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, - const ROOT::VecOps::RVec& reco ); + ROOT::VecOps::RVec get_VerticesRecoParticlesInd( + ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec& reco); /// @brief Find (by index) a vertex that is made of reco particles from a /// passed list. diff --git a/analyzers/dataframe/src/VertexingUtils.cc b/analyzers/dataframe/src/VertexingUtils.cc index 074d71b369c..feac0b5af89 100644 --- a/analyzers/dataframe/src/VertexingUtils.cc +++ b/analyzers/dataframe/src/VertexingUtils.cc @@ -370,11 +370,11 @@ ROOT::VecOps::RVec get_VertexRecoParticlesInd( } ROOT::VecOps::RVec get_VerticesRecoParticlesInd( - ROOT::VecOps::RVec vertices, + ROOT::VecOps::RVec vertices, const ROOT::VecOps::RVec &reco) { ROOT::VecOps::RVec result; - for (int j = 0; j < vertices.size(); ++j){ + for (int j = 0; j < vertices.size(); ++j) { ROOT::VecOps::RVec indices_tracks = vertices[j].reco_ind; for (int i = 0; i < indices_tracks.size(); i++) { int tk_index = indices_tracks[i]; @@ -389,7 +389,7 @@ ROOT::VecOps::RVec get_VerticesRecoParticlesInd( } } } - + return result; } From 4ff8c17184abfdd59a4d6451dfe1df023cfa38d1 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 2 Mar 2026 10:59:24 +0100 Subject: [PATCH 08/13] while (!CI_happy) run(formatter) --- .../dataframe/FCCAnalyses/ReconstructedParticle2Track.h | 4 ++-- analyzers/dataframe/FCCAnalyses/VertexingUtils.h | 7 ++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h index 6693c39a82b..bd862994810 100644 --- a/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h +++ b/analyzers/dataframe/FCCAnalyses/ReconstructedParticle2Track.h @@ -26,7 +26,7 @@ namespace edm4hep { namespace FCCAnalyses{ -namespace ReconstructedParticle2Track{ +namespace ReconstructedParticle2Track { /// Return the momentum of a track to a reconstructed particle ROOT::VecOps::RVec @@ -209,7 +209,7 @@ int getTK_n(ROOT::VecOps::RVec x); ROOT::VecOps::RVec hasTRK(ROOT::VecOps::RVec in); -}//end NS ReconstructedParticle2Track +} // namespace ReconstructedParticle2Track }//end NS FCCAnalyses #endif diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index fe88c5454c8..36e485155f3 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -108,10 +108,11 @@ namespace VertexingUtils{ ROOT::VecOps::RVec get_VertexRecoParticlesInd( FCCAnalysesVertex TheVertex, const ROOT::VecOps::RVec& reco ); - /// Retrieve the indices of the tracks fitted to a vector of vertices, but now in the collection of RecoParticles + /// Retrieve the indices of the tracks fitted to a vector of vertices, but now + /// in the collection of RecoParticles ROOT::VecOps::RVec get_VerticesRecoParticlesInd( - ROOT::VecOps::RVec vertices, - const ROOT::VecOps::RVec& reco); + ROOT::VecOps::RVec vertices, + const ROOT::VecOps::RVec &reco); /// @brief Find (by index) a vertex that is made of reco particles from a /// passed list. From 1637717f9aaaea38c80dee82d45829abf6119f5b Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Wed, 4 Mar 2026 10:09:48 +0100 Subject: [PATCH 09/13] yay --- analyzers/dataframe/FCCAnalyses/VertexingUtils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h index 36e485155f3..fdbbb456340 100644 --- a/analyzers/dataframe/FCCAnalyses/VertexingUtils.h +++ b/analyzers/dataframe/FCCAnalyses/VertexingUtils.h @@ -108,7 +108,7 @@ namespace VertexingUtils{ ROOT::VecOps::RVec get_VertexRecoParticlesInd( FCCAnalysesVertex TheVertex, const ROOT::VecOps::RVec& reco ); - /// Retrieve the indices of the tracks fitted to a vector of vertices, but now + /// Retrieve the indices of the tracks fitted to a vector of vertices, but now /// in the collection of RecoParticles ROOT::VecOps::RVec get_VerticesRecoParticlesInd( ROOT::VecOps::RVec vertices, From 7f736d23d4fbe18bc3d9d3a640bc1c12192dd44f Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Wed, 4 Mar 2026 10:11:20 +0100 Subject: [PATCH 10/13] document how to use clang format --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 103171fab8d..4329d85f45a 100644 --- a/README.md +++ b/README.md @@ -77,3 +77,9 @@ To apply formatting to a file: ``` clang-format -i -style=file /path/to/file.cpp ``` +Note that this will reformat the entire file. +If you are preparing a PR, you can instead use +``` + git clang-format --style=file $(git merge-base upstream/master HEAD) +``` +to only format the lines you changed (otherwise you will reformat the entire file). From 5dcba2302cac6aa9ba50bfeac96af4d2e63b35fe Mon Sep 17 00:00:00 2001 From: Max Goblirsch <98332675+goblirsc@users.noreply.github.com> Date: Wed, 4 Mar 2026 11:51:57 +0100 Subject: [PATCH 11/13] clarify readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4329d85f45a..6c9282e4aeb 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,4 @@ If you are preparing a PR, you can instead use ``` git clang-format --style=file $(git merge-base upstream/master HEAD) ``` -to only format the lines you changed (otherwise you will reformat the entire file). +to only format the lines you changed (avoids bloating your MR - unless you wish to clean up the whole file 😉). From 609d6e4867630fef7519c40a912e6af1724662d4 Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Mar 2026 11:56:02 +0100 Subject: [PATCH 12/13] move selByPredicate to Utils, add more doc --- README.md | 2 +- analyzers/dataframe/FCCAnalyses/MCParticle.h | 32 ++---- analyzers/dataframe/FCCAnalyses/Utils.h | 113 +++++++++++++++++++ analyzers/dataframe/src/MCParticle.cc | 48 ++------ 4 files changed, 129 insertions(+), 66 deletions(-) diff --git a/README.md b/README.md index 6c9282e4aeb..fd0d2a89b2e 100644 --- a/README.md +++ b/README.md @@ -82,4 +82,4 @@ If you are preparing a PR, you can instead use ``` git clang-format --style=file $(git merge-base upstream/master HEAD) ``` -to only format the lines you changed (avoids bloating your MR - unless you wish to clean up the whole file 😉). +to only format the lines you changed (avoids bloating your PR - unless you wish to clean up the whole file 😉). diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index bb1f1114343..768708352a2 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -6,6 +6,7 @@ #include #include +#include "FCCAnalyses/Utils.h" #include "ROOT/RVec.hxx" #include "TLorentzVector.h" #include "edm4hep/MCParticleData.h" @@ -31,48 +32,31 @@ namespace MCParticle{ bool operator() (ROOT::VecOps::RVec in); }; - /// @brief Helper struct to select entries matching a certain predicate. - /// Supports two signatures - either a list of candidates is passed and a list - /// of accepted candidates returned, Or a list of indices in a vector of - /// candidates is passed and a list of accepted indices returned. The latter - /// is more compatible with index-based selection logic. - struct selByPredicate { - selByPredicate( - std::function thePredicate) - : m_predicate(thePredicate) {} - std::function m_predicate; - ROOT::VecOps::RVec - operator()(const ROOT::VecOps::RVec &in); - ROOT::VecOps::RVec - operator()(const ROOT::VecOps::RVec &indices, - const ROOT::VecOps::RVec &in); - ROOT::VecOps::RVec> - operator()(const ROOT::VecOps::RVec> &indices, - const ROOT::VecOps::RVec &in); - }; + /// Template implementation for basic selection function on MC particle data. + using MCParticleSelection = Utils::selByPredicate; /// select MCParticles with transverse momentum greater than a minimum value [GeV] - struct sel_pt : selByPredicate { + struct sel_pt : MCParticleSelection { sel_pt(float arg_min_pt); }; /// select MCParticles with absolute pseudorapidity less than a max value - struct sel_eta : selByPredicate { + struct sel_eta : MCParticleSelection { sel_eta(float arg_max_eta); }; /// select MCParticles with their status - struct sel_genStatus : selByPredicate { + struct sel_genStatus : MCParticleSelection { sel_genStatus(int arg_status); }; /// select MCParticles with their PDG id - struct sel_pdgID : selByPredicate { + struct sel_pdgID : MCParticleSelection { sel_pdgID(int arg_pdg, bool arg_chargeconjugate); }; /// select MCParticles with a non-zero charge - struct sel_charged : selByPredicate { + struct sel_charged : MCParticleSelection { sel_charged(); }; diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index eb0b3106dc9..36066f38ec0 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -3,10 +3,123 @@ #include #include +#include "ROOT/RVec.hxx" namespace FCCAnalyses { namespace Utils { + + /// @brief Helper struct to select entries matching a certain predicate. + /// When instantiated with a function that gives a "yes / no" decision + /// based on an input object, will support three functionalities: + /// - select accepted objects from a list of inputs, return as list + /// - select indices of selected objects from list of inputs and indices to study, + /// return index ist + /// - select indicises of objects passing for a set of input lists (nested selection) + /// This allows to consistently apply the same selection in multiple ways, + /// and to easily write new cuts without having to write a lot of + /// boilerplate code. + /// @tparam thingToSelect: The type of object our decision will be based on + /// For example: edm4hep::MCParticleData (for selecting MC particles). + /// + /// One pattern is to create a selector class inheriting from `selByPredicate`, + /// where the selection function is specified within the constructor. + /// Constructor arguments can be passed via lambda capture or `std::bind` + /// to parametrise cuts where needed. + /// This can look like + /// @code + /// struct myPtCut : selByPredicate{/// + /// myPtCut(double ptCutVal): selByPredicate( + /// [ptCutVal](const edm4hep::MCParticleData & mc){ + /// return mc.pt() > ptCutVal; + /// }){ + /// } + /// }; + /// @endcode + /// Or, assuming you have an existing selection function + /// `doesThisPass(const edm4hep::MCParticleData &, double, int)` + /// with some customizable cut parameters + /// @code + /// struct myDoesThisPass : selByPredicate{/// + /// myPtCut(double par1, int par2): selByPredicate( + /// std::bind(doesThisPass,std::placeholders::_1, par1, par2)){ + /// } + /// }; + /// @endcode + /// Examples for practical usage can be found in `MCParticle.h`, see for example #sel_pt. + /// In the python steering, you would then typically instantiate the + /// derived cut classes, for example + /// @code + /// df = df.Define("particles_passing","myPtCut(10)(particles_to_check)") + /// @endcode + /// or (for indices) + /// @code + /// df = df.Define("particle_indices_passing","myPtCut(10)(particle_indices_to_check, allParticles)") + /// @endcode + template + struct selByPredicate { + /// @brief constructor - instantiate by passing a selection function. + /// For implementing selections with configurable parameters + /// (e.g. cut values), look at lambda captures or `std::bind`. + selByPredicate( + std::function thePredicate) + : m_predicate(thePredicate){} + + /// @brief Select passing objects from a list of candidates, + /// return by (deep-)copy + /// @param in: List of candidates to run the selection on + /// @return A list of candidates for which `m_predicate` evaluates + /// as `true`. + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &in){ + ROOT::VecOps::RVec result; + result.reserve(in.size()); + for (auto & p : in) { + if (m_predicate(p)) result.emplace_back(p); + } + return result; + } + + /// @brief Select passing objects from a list of candidates, + /// return by index + /// @param indices: List of indices of candidates within `in` + // to consider for selection + /// @param in: List of candidates to which indices in `indices` refer. + /// @return A list of indices of candidates within the `in` + // vector for which `m_predicate` evaluates as `true`. + ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec result; + result.reserve(in.size()); + for (int index : indices) { + if (index < 0 || index >= in.size()) continue; + if (m_predicate(in[index])) result.emplace_back(index); + } + return result; + } + + /// @brief Select (several) lists of passing objects from (several) lists of candidates, + /// return by lists of indices. Used to select on several (similar) lists at once. + /// For example: Track selection within (many) vertex candidates. + /// @param setsOfIndices: Multiple lists of indices referring to `in` + /// @param in: List of candidates to which indices in `setsOfIndices` refer. + /// @return A list of index lists of similar size as `setsOfIndices`. + /// For each element, the list contains the output of `operator()` + /// run on the indices of the given element of `setsOfIndices`. + ROOT::VecOps::RVec> operator() ( + const ROOT::VecOps::RVec> & setsOfIndices, + const ROOT::VecOps::RVec & in){ + ROOT::VecOps::RVec> result(setsOfIndices.size()); + for (int elem = 0; elem < setsOfIndices.size(); ++elem){ + result[elem] = this->operator()(setsOfIndices[elem], in); + } + return result; + } + private: + /// Stored selection function. + std::function m_predicate; + }; + + template inline auto getsize( T& vec){ return vec.size();}; template inline ROOT::VecOps::RVec> diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 7b163496e45..5173cd78688 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -7,61 +7,27 @@ namespace FCCAnalyses{ namespace MCParticle{ - -ROOT::VecOps::RVec selByPredicate::operator()( - const ROOT::VecOps::RVec &in) { - ROOT::VecOps::RVec result; - result.reserve(in.size()); - for (auto &p : in) { - if (m_predicate(p)) - result.emplace_back(p); - } - return result; -} - -ROOT::VecOps::RVec selByPredicate::operator()( - const ROOT::VecOps::RVec &indices, - const ROOT::VecOps::RVec &in) { - ROOT::VecOps::RVec result; - result.reserve(in.size()); - for (int index : indices) { - if (index < 0 || index >= in.size()) - continue; - if (m_predicate(in[index])) - result.emplace_back(index); - } - return result; -} -ROOT::VecOps::RVec> selByPredicate::operator()( - const ROOT::VecOps::RVec> &setsOfIndices, - const ROOT::VecOps::RVec &in) { - ROOT::VecOps::RVec> result(setsOfIndices.size()); - for (int elem = 0; elem < setsOfIndices.size(); ++elem) { - result[elem] = this->operator()(setsOfIndices[elem], in); - } - return result; -} - + sel_pt::sel_pt(float arg_min_pt) - : selByPredicate([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { + : MCParticleSelection([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > arg_min_pt * arg_min_pt); }) {} sel_eta::sel_eta(float arg_max_eta) - : selByPredicate([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { + : MCParticleSelection([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, p.mass); return std::abs(vec.Eta()) < std::abs(arg_max_eta); }) {} sel_genStatus::sel_genStatus(int arg_status) - : selByPredicate([arg_status](const edm4hep::MCParticleData &p) -> bool { + : MCParticleSelection([arg_status](const edm4hep::MCParticleData &p) -> bool { return p.generatorStatus == arg_status; }) {} sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) - : selByPredicate([arg_pdg, arg_chargeconjugate]( + : MCParticleSelection([arg_pdg, arg_chargeconjugate]( const edm4hep::MCParticleData &p) -> bool { if (arg_chargeconjugate) return std::abs(p.PDG) == std::abs(arg_pdg); @@ -70,9 +36,9 @@ sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) }) {} sel_charged::sel_charged() - : selByPredicate([](const edm4hep::MCParticleData &p) -> bool { + : MCParticleSelection([](const edm4hep::MCParticleData &p) -> bool { // try to avoid floating comp to zero - // and thank you for the person who gave some neutral particles a -999 + // and I am sad that some neutral particles carry a -999 // charge! return std::abs(p.charge) > 1e-6 && p.charge != -999; }) {} From 6ff7a38686768ce05108216be54c1c47a393334b Mon Sep 17 00:00:00 2001 From: Maximilian Emanuel Goblirsch-Kolb Date: Mon, 16 Mar 2026 11:56:29 +0100 Subject: [PATCH 13/13] clang format --- analyzers/dataframe/FCCAnalyses/MCParticle.h | 4 +- analyzers/dataframe/FCCAnalyses/Utils.h | 140 ++++++++++--------- analyzers/dataframe/src/MCParticle.cc | 31 ++-- 3 files changed, 92 insertions(+), 83 deletions(-) diff --git a/analyzers/dataframe/FCCAnalyses/MCParticle.h b/analyzers/dataframe/FCCAnalyses/MCParticle.h index 768708352a2..c3e627f301e 100644 --- a/analyzers/dataframe/FCCAnalyses/MCParticle.h +++ b/analyzers/dataframe/FCCAnalyses/MCParticle.h @@ -32,8 +32,8 @@ namespace MCParticle{ bool operator() (ROOT::VecOps::RVec in); }; - /// Template implementation for basic selection function on MC particle data. - using MCParticleSelection = Utils::selByPredicate; + /// Template implementation for basic selection function on MC particle data. + using MCParticleSelection = Utils::selByPredicate; /// select MCParticles with transverse momentum greater than a minimum value [GeV] struct sel_pt : MCParticleSelection { diff --git a/analyzers/dataframe/FCCAnalyses/Utils.h b/analyzers/dataframe/FCCAnalyses/Utils.h index 36066f38ec0..3739545e9bd 100644 --- a/analyzers/dataframe/FCCAnalyses/Utils.h +++ b/analyzers/dataframe/FCCAnalyses/Utils.h @@ -1,32 +1,31 @@ #ifndef UTILS_ANALYZERS_H #define UTILS_ANALYZERS_H +#include "ROOT/RVec.hxx" #include #include -#include "ROOT/RVec.hxx" namespace FCCAnalyses { namespace Utils { - /// @brief Helper struct to select entries matching a certain predicate. /// When instantiated with a function that gives a "yes / no" decision - /// based on an input object, will support three functionalities: + /// based on an input object, will support three functionalities: /// - select accepted objects from a list of inputs, return as list - /// - select indices of selected objects from list of inputs and indices to study, - /// return index ist - /// - select indicises of objects passing for a set of input lists (nested selection) - /// This allows to consistently apply the same selection in multiple ways, - /// and to easily write new cuts without having to write a lot of - /// boilerplate code. - /// @tparam thingToSelect: The type of object our decision will be based on + /// - select indices of selected objects from list of inputs and indices to + /// study, + /// return index ist + /// - select indicises of objects passing for a set of input lists (nested + /// selection) This allows to consistently apply the same selection in + /// multiple ways, and to easily write new cuts without having to write a lot + /// of boilerplate code. + /// @tparam thingToSelect: The type of object our decision will be based on /// For example: edm4hep::MCParticleData (for selecting MC particles). - /// - /// One pattern is to create a selector class inheriting from `selByPredicate`, - /// where the selection function is specified within the constructor. - /// Constructor arguments can be passed via lambda capture or `std::bind` - /// to parametrise cuts where needed. - /// This can look like + /// + /// One pattern is to create a selector class inheriting from + /// `selByPredicate`, where the selection function is specified within the + /// constructor. Constructor arguments can be passed via lambda capture or + /// `std::bind` to parametrise cuts where needed. This can look like /// @code /// struct myPtCut : selByPredicate{/// /// myPtCut(double ptCutVal): selByPredicate( @@ -35,91 +34,98 @@ namespace FCCAnalyses { /// }){ /// } /// }; - /// @endcode - /// Or, assuming you have an existing selection function + /// @endcode + /// Or, assuming you have an existing selection function /// `doesThisPass(const edm4hep::MCParticleData &, double, int)` /// with some customizable cut parameters /// @code /// struct myDoesThisPass : selByPredicate{/// - /// myPtCut(double par1, int par2): selByPredicate( + /// myPtCut(double par1, int par2): + /// selByPredicate( /// std::bind(doesThisPass,std::placeholders::_1, par1, par2)){ /// } /// }; - /// @endcode - /// Examples for practical usage can be found in `MCParticle.h`, see for example #sel_pt. - /// In the python steering, you would then typically instantiate the - /// derived cut classes, for example + /// @endcode + /// Examples for practical usage can be found in `MCParticle.h`, see for + /// example #sel_pt. In the python steering, you would then typically + /// instantiate the derived cut classes, for example /// @code /// df = df.Define("particles_passing","myPtCut(10)(particles_to_check)") - /// @endcode + /// @endcode /// or (for indices) /// @code - /// df = df.Define("particle_indices_passing","myPtCut(10)(particle_indices_to_check, allParticles)") - /// @endcode - template - struct selByPredicate { - /// @brief constructor - instantiate by passing a selection function. + /// df = + /// df.Define("particle_indices_passing","myPtCut(10)(particle_indices_to_check, + /// allParticles)") + /// @endcode + template struct selByPredicate { + /// @brief constructor - instantiate by passing a selection function. /// For implementing selections with configurable parameters - /// (e.g. cut values), look at lambda captures or `std::bind`. - selByPredicate( - std::function thePredicate) - : m_predicate(thePredicate){} + /// (e.g. cut values), look at lambda captures or `std::bind`. + selByPredicate(std::function thePredicate) + : m_predicate(thePredicate) {} /// @brief Select passing objects from a list of candidates, - /// return by (deep-)copy - /// @param in: List of candidates to run the selection on + /// return by (deep-)copy + /// @param in: List of candidates to run the selection on /// @return A list of candidates for which `m_predicate` evaluates - /// as `true`. + /// as `true`. ROOT::VecOps::RVec - operator()(const ROOT::VecOps::RVec &in){ + operator()(const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); - for (auto & p : in) { - if (m_predicate(p)) result.emplace_back(p); - } - return result; + for (auto &p : in) { + if (m_predicate(p)) + result.emplace_back(p); + } + return result; } /// @brief Select passing objects from a list of candidates, /// return by index - /// @param indices: List of indices of candidates within `in` - // to consider for selection - /// @param in: List of candidates to which indices in `indices` refer. - /// @return A list of indices of candidates within the `in` - // vector for which `m_predicate` evaluates as `true`. - ROOT::VecOps::RVec operator() (const ROOT::VecOps::RVec & indices, const ROOT::VecOps::RVec & in){ + /// @param indices: List of indices of candidates within `in` + // to consider for selection + /// @param in: List of candidates to which indices in `indices` refer. + /// @return A list of indices of candidates within the `in` + // vector for which `m_predicate` evaluates as `true`. + ROOT::VecOps::RVec + operator()(const ROOT::VecOps::RVec &indices, + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec result; result.reserve(in.size()); for (int index : indices) { - if (index < 0 || index >= in.size()) continue; - if (m_predicate(in[index])) result.emplace_back(index); - } - return result; + if (index < 0 || index >= in.size()) + continue; + if (m_predicate(in[index])) + result.emplace_back(index); + } + return result; } - /// @brief Select (several) lists of passing objects from (several) lists of candidates, - /// return by lists of indices. Used to select on several (similar) lists at once. - /// For example: Track selection within (many) vertex candidates. - /// @param setsOfIndices: Multiple lists of indices referring to `in` - /// @param in: List of candidates to which indices in `setsOfIndices` refer. - /// @return A list of index lists of similar size as `setsOfIndices`. + /// @brief Select (several) lists of passing objects from (several) lists of + /// candidates, return by lists of indices. Used to select on several + /// (similar) lists at once. For example: Track selection within (many) + /// vertex candidates. + /// @param setsOfIndices: Multiple lists of indices referring to `in` + /// @param in: List of candidates to which indices in `setsOfIndices` refer. + /// @return A list of index lists of similar size as `setsOfIndices`. /// For each element, the list contains the output of `operator()` - /// run on the indices of the given element of `setsOfIndices`. - ROOT::VecOps::RVec> operator() ( - const ROOT::VecOps::RVec> & setsOfIndices, - const ROOT::VecOps::RVec & in){ + /// run on the indices of the given element of `setsOfIndices`. + ROOT::VecOps::RVec> + operator()(const ROOT::VecOps::RVec> &setsOfIndices, + const ROOT::VecOps::RVec &in) { ROOT::VecOps::RVec> result(setsOfIndices.size()); - for (int elem = 0; elem < setsOfIndices.size(); ++elem){ - result[elem] = this->operator()(setsOfIndices[elem], in); + for (int elem = 0; elem < setsOfIndices.size(); ++elem) { + result[elem] = this->operator()(setsOfIndices[elem], in); } - return result; + return result; } - private: + + private: /// Stored selection function. - std::function m_predicate; + std::function m_predicate; }; - template inline auto getsize( T& vec){ return vec.size();}; template inline ROOT::VecOps::RVec> diff --git a/analyzers/dataframe/src/MCParticle.cc b/analyzers/dataframe/src/MCParticle.cc index 5173cd78688..0c75dff8653 100644 --- a/analyzers/dataframe/src/MCParticle.cc +++ b/analyzers/dataframe/src/MCParticle.cc @@ -7,28 +7,31 @@ namespace FCCAnalyses{ namespace MCParticle{ - + sel_pt::sel_pt(float arg_min_pt) - : MCParticleSelection([arg_min_pt](const edm4hep::MCParticleData &p) -> bool { - return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > - arg_min_pt * arg_min_pt); - }) {} + : MCParticleSelection( + [arg_min_pt](const edm4hep::MCParticleData &p) -> bool { + return (p.momentum.x * p.momentum.x + p.momentum.y * p.momentum.y > + arg_min_pt * arg_min_pt); + }) {} sel_eta::sel_eta(float arg_max_eta) - : MCParticleSelection([arg_max_eta](const edm4hep::MCParticleData &p) -> bool { - ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, - p.mass); - return std::abs(vec.Eta()) < std::abs(arg_max_eta); - }) {} + : MCParticleSelection( + [arg_max_eta](const edm4hep::MCParticleData &p) -> bool { + ROOT::Math::PxPyPzM4D vec(p.momentum.x, p.momentum.y, p.momentum.z, + p.mass); + return std::abs(vec.Eta()) < std::abs(arg_max_eta); + }) {} sel_genStatus::sel_genStatus(int arg_status) - : MCParticleSelection([arg_status](const edm4hep::MCParticleData &p) -> bool { - return p.generatorStatus == arg_status; - }) {} + : MCParticleSelection( + [arg_status](const edm4hep::MCParticleData &p) -> bool { + return p.generatorStatus == arg_status; + }) {} sel_pdgID::sel_pdgID(int arg_pdg, bool arg_chargeconjugate) : MCParticleSelection([arg_pdg, arg_chargeconjugate]( - const edm4hep::MCParticleData &p) -> bool { + const edm4hep::MCParticleData &p) -> bool { if (arg_chargeconjugate) return std::abs(p.PDG) == std::abs(arg_pdg); else