diff --git a/FTagDumper/src/JetDumperConfig.cxx b/FTagDumper/src/JetDumperConfig.cxx index d68e8601dc2c145b46b785b9259f5b6b9747faa8..558fda353edcc1a872de8d496a46abf0df8550e6 100644 --- a/FTagDumper/src/JetDumperConfig.cxx +++ b/FTagDumper/src/JetDumperConfig.cxx @@ -261,6 +261,8 @@ namespace { if (name == "truth_hadrons") return p::hadron; if (name == "truth_leptons") return p::lepton; if (name == "truth_fromBC") return p::fromBC; + // See Athena/../FlavoUrTagDiscriminants/TruthVertexDecoratorAlg.h + if (name == "truth_any") return p::any; #define TRY(KEY) if (name == #KEY) return p::KEY TRY(overlapLepton); TRY(promptLepton); @@ -339,7 +341,7 @@ namespace { output.throw_if_unused("output"); cfg.decorate = json.get("decorate_summary", false); - + cfg.vars = json.get<VariablesByType>("vars", {}); json.throw_if_unused("truth config"); return cfg; diff --git a/FTagDumper/src/JetDumperConfig.hh b/FTagDumper/src/JetDumperConfig.hh index 305dd5e05625c8b5b65ca4dcbe82916c0c0f21e8..2a86b50030aaa043489808a0bf695276fcf4e1e9 100644 --- a/FTagDumper/src/JetDumperConfig.hh +++ b/FTagDumper/src/JetDumperConfig.hh @@ -56,6 +56,7 @@ struct TruthConfig { std::string association_name; std::optional<TruthOutputConfig> output; bool decorate; + VariablesByType vars; }; struct DecorateConfig { @@ -136,6 +137,7 @@ struct JetDumperConfig { std::vector<SubjetConfig> subjet_configs; DecorateConfig decorate; bool force_full_precision = false; + bool write_info_to_truth_particles = true; // TODO make this configurable std::vector<JetLinkWriterConfig> flow; }; diff --git a/FTagDumper/src/JetDumperTools.cxx b/FTagDumper/src/JetDumperTools.cxx index ad010c6fd1cbed6add08f22bc0461cf399c5132a..b7b10ffd77dd7669986986b12a95e03f4692d2d4 100644 --- a/FTagDumper/src/JetDumperTools.cxx +++ b/FTagDumper/src/JetDumperTools.cxx @@ -333,7 +333,7 @@ JetDumperOutputs::JetDumperOutputs(const JetDumperConfig& jobcfg, // TODO: TruthWriter needs a config struct truths.emplace_back(output, oc.n_to_save, cfg.association_name, oc.name, - oc.sort_order); + oc.sort_order, cfg.vars); } } if (jobcfg.hits) { diff --git a/FTagDumper/src/TruthWriter.cxx b/FTagDumper/src/TruthWriter.cxx index 807caca725019d9131363a9b393660e0249c5bdc..57e78a62cee0523157565039626e376b20e10742 100644 --- a/FTagDumper/src/TruthWriter.cxx +++ b/FTagDumper/src/TruthWriter.cxx @@ -10,10 +10,17 @@ #include "xAODTruth/TruthParticle.h" #include "xAODTruth/TruthParticleContainer.h" #include "xAODTruth/TruthVertex.h" - - +template <typename T> +using Acc = SG::AuxElement::ConstAccessor<T>; typedef std::function<float(const TruthOutputs&)> FloatFiller; typedef std::function<int(const TruthOutputs&)> IntFiller; +typedef std::function<char(const TruthOutputs&)> CharFiller; +typedef std::function<unsigned char(const TruthOutputs&)> UCharFiller; +typedef std::function<unsigned int(const TruthOutputs&)> UIntFiller; +typedef std::function<short(const TruthOutputs&)> HalfFiller; +typedef std::function<double(const TruthOutputs&)> DoubleFiller; + + class TruthConsumers: public H5Utils::Consumers<const TruthOutputs&> {}; class TruthOutputWriter: public H5Utils::Writer<1,const TruthOutputs&> { @@ -30,10 +37,12 @@ TruthWriter::TruthWriter( const std::size_t output_size, const std::string& link_name, const std::string& output_name, - TrackSortOrder order): + TrackSortOrder order, + const VariablesByType& vars): m_hdf5_truth_writer(nullptr), m_acc(link_name), - m_output_size(output_size) + m_output_size(output_size), + m_vars(vars) { if ( order == TrackSortOrder::PT ) { m_sort = [](const xAOD::TruthParticle* p1, const xAOD::TruthParticle* p2) { @@ -45,81 +54,169 @@ TruthWriter::TruthWriter( TruthConsumers fillers; - // hard coded fillers + + + // IntFiller tpDecayType = [acc=Acc<int>("ftagTPDecayVertexType")](const TruthOutputs& t) -> int { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayVertexType", tpDecayType, -1); + + // IntFiller tpVertID = [acc=Acc<int>("ftagTPDecayVertexID")](const TruthOutputs& t) -> int { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayVertexID", tpVertID, -1); + + // IntFiller tpParentID = [acc=Acc<int>("ftagTPDecayVertexParentID")](const TruthOutputs& t) -> int { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayVertexParentID", tpParentID, -1); + + // IntFiller tpNCharged = [acc=Acc<int>("ftagTPDecayVertexNCharged")](const TruthOutputs& t) -> int { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayVertexNCharged", tpNCharged, -1); + + // IntFiller tpNNeut = [acc=Acc<int>("ftagTPDecayVertexNNeutral")](const TruthOutputs& t) -> int { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayVertexNNeutral", tpNNeut, -1); + + // FloatFiller distToPV = [acc=Acc<float>("ftagTPDecayPVDistance")](const TruthOutputs& t) -> float { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayPVDistance", distToPV, NAN); + + // FloatFiller distToParent = [acc=Acc<float>("ftagTPDecayDistance")](const TruthOutputs& t) -> float { + // return acc(*t.truth); + // }; + // fillers.add("ftagTPDecayDistance", distToParent, NAN); + + + // IntFiller tpValid = [acc=Acc<bool>("ftagTPValid")](const TruthOutputs& t) -> int { + // bool valid = acc(*t.truth); + // if (valid) return 1; + // return 0; + + // }; + // fillers.add("ftagTPValid", tpValid, -1); + + // hard coded fillers FloatFiller pt = [](const TruthOutputs& t) -> float { return t.truth->pt(); }; - fillers.add("pt", pt, NAN); - FloatFiller mass = [](const TruthOutputs& t) -> float { return t.truth->m(); }; - fillers.add("mass", mass, NAN); - FloatFiller e = [](const TruthOutputs& t) -> float { return t.truth->e(); }; - fillers.add("energy", e, NAN); - FloatFiller eta = [](const TruthOutputs& t) -> float { return t.truth->eta(); }; - fillers.add("eta", eta, NAN); - FloatFiller phi = [](const TruthOutputs& t) -> float { return t.truth->phi(); }; - fillers.add("phi", phi, NAN); - FloatFiller deta = [](const TruthOutputs& t) -> float { return t.jet->eta() - t.truth->eta(); }; - fillers.add("deta", deta, NAN); - FloatFiller dphi = [](const TruthOutputs& t) -> float { return t.jet->p4().DeltaPhi(t.truth->p4()); }; - fillers.add("dphi", dphi, NAN); - FloatFiller dr = [](const TruthOutputs& t) -> float { return t.jet->p4().DeltaR(t.truth->p4()); }; - fillers.add("dr", dr, NAN); - FloatFiller Lxy = [](const TruthOutputs& t) -> float { if ( t.truth->decayVtx() ) { return t.truth->decayVtx()->perp(); } else return INFINITY; }; - fillers.add("Lxy", Lxy, NAN); IntFiller charge = [](const TruthOutputs& t) -> int { return t.truth->charge(); }; - fillers.add("charge", charge, -2); - IntFiller flavour = [](const TruthOutputs& t) -> int { if ( t.truth->isBottomHadron() ) { return 5; } if ( t.truth->isCharmHadron() ) { return 4; } return -1; }; - fillers.add("flavour", flavour, -1); - IntFiller pdgId = [](const TruthOutputs& t) -> int { return t.truth->pdgId(); }; - fillers.add("pdgId", pdgId, -1); - IntFiller barcode = [](const TruthOutputs& t) -> int { return t.truth->barcode(); }; - fillers.add("barcode", barcode, -1); - IntFiller parent_barcode = [](const TruthOutputs& t) -> int { return t.truth->parent() ? t.truth->parent()->barcode() : -1; }; - fillers.add("parentBarcode", parent_barcode, -1); - // add valid flag, for more robust selection, true for any track + for(const auto& var: m_vars.ints){ + if(var == "charge") fillers.add("charge", charge, -2); + else if(var == "flavour") fillers.add("flavour", flavour, -1); + else if(var == "pdgId") fillers.add("pdgId", pdgId, -1); + else if(var == "barcode") fillers.add("barcode", barcode, -1); + else if(var == "parentBarcode") fillers.add("parentBarcode", parent_barcode, -1); + else{ + IntFiller ff = [acc=Acc<int>(var)](const TruthOutputs& t) -> int { + return acc(*t.truth); + }; + fillers.add(var, ff, -1); + } + } + for(const auto& var: m_vars.floats){ + if(var == "pt") fillers.add("pt", pt, NAN); + else if(var == "mass") fillers.add("mass", mass, NAN); + else if(var == "energy") fillers.add("energy", e, NAN); + else if(var == "eta") fillers.add("eta", eta, NAN); + else if(var == "phi") fillers.add("phi", phi, NAN); + else if(var == "deta") fillers.add("deta", deta, NAN); + else if(var == "dphi") fillers.add("dphi", dphi, NAN); + else if(var == "dr") fillers.add("dr", dr, NAN); + else if(var == "Lxy") fillers.add("Lxy", Lxy, NAN); + else{ + FloatFiller ff = [acc=Acc<float>(var)](const TruthOutputs& t) -> float { + return acc(*t.truth); + }; + fillers.add(var, ff, NAN); + } + } + for(const auto& var: m_vars.doubles){ + DoubleFiller df = [acc=Acc<double>(var)](const TruthOutputs& t) -> double { + return acc(*t.truth); + }; + fillers.add(var, df, NAN); + } + for(const auto& var: m_vars.ints_as_halves){ + HalfFiller hf = [acc=Acc<float>(var)](const TruthOutputs& t) -> short { + return (short)acc(*t.truth); + }; + } + for(const auto& var: m_vars.halves){ + HalfFiller hf = [acc=Acc<float>(var)](const TruthOutputs& t) -> short { + return acc(*t.truth); + }; + fillers.add(var, hf, -1); + } + for(const auto& var: m_vars.chars){ + CharFiller cf = [acc=Acc<char>(var)](const TruthOutputs& t) -> char { + return acc(*t.truth); + }; + fillers.add(var, cf, -1); + } + for(const auto& var: m_vars.uchars){ + UCharFiller ucf = [acc=Acc<unsigned char>(var)](const TruthOutputs& t) -> unsigned char { + return acc(*t.truth); + }; + fillers.add(var, ucf, -1); + } + for(const auto& var: m_vars.uints){ + UIntFiller uif = [acc=Acc<unsigned int>(var)](const TruthOutputs& t) -> unsigned int { + return acc(*t.truth); + }; + fillers.add(var, uif, -1); + } + + + + // add valid flag, for more robust selection, true for any truth particle // that is defined. fillers.add("valid", [](const auto&) { return true; }, false); diff --git a/FTagDumper/src/TruthWriter.hh b/FTagDumper/src/TruthWriter.hh index 72bf4ae34b68c92ab3f7717c6c57bd7eed393da6..5050c1acbd1c74950016dc89e5189122c54c1573 100644 --- a/FTagDumper/src/TruthWriter.hh +++ b/FTagDumper/src/TruthWriter.hh @@ -1,15 +1,15 @@ #ifndef TRUTH_WRITER_HH #define TRUTH_WRITER_HH - +#include "StoreGate/ReadDecorHandleKey.h" +#include "xAODTruth/TruthParticleContainerFwd.h" #include "TrackSortOrder.hh" - #include "xAODJet/JetFwd.h" #include "xAODTruth/TruthParticleFwd.h" - #include "xAODBase/IParticleContainer.h" #include "AthContainers/AuxElement.h" #include "AthLinks/ElementLink.h" +#include "VariablesByType.hh" // Standard Library things #include <string> #include <vector> @@ -27,6 +27,9 @@ struct TruthOutputs { const xAOD::Jet* jet; }; +// template <typename T> +// using Acc = SG::AuxElement::ConstAccessor<T>; + class TruthWriter { public: @@ -40,7 +43,8 @@ public: const std::size_t output_size, const std::string& link_name, const std::string& output_name, - TrackSortOrder order); + TrackSortOrder order, + const VariablesByType& vars); ~TruthWriter(); TruthWriter(TruthWriter&) = delete; @@ -59,6 +63,7 @@ private: std::unique_ptr<TruthOutputWriter> m_hdf5_truth_writer; AE::ConstAccessor<PartLinks> m_acc; const std::size_t& m_output_size; + VariablesByType m_vars; std::function<bool(const xAOD::TruthParticle* p1, const xAOD::TruthParticle* p2)> m_sort; diff --git a/configs/EMPFlowTruth.json b/configs/EMPFlowTruth.json index 99acc49842b4df1d86fac9df1d329874a4b8a75f..1b94d4f0b65c6c7689da28e2288dfbf51b5cba4d 100644 --- a/configs/EMPFlowTruth.json +++ b/configs/EMPFlowTruth.json @@ -34,7 +34,8 @@ "file": "fragments/pflow-track-variables-all.json", "ints" : [ "ftagTruthBarcode", - "ftagTruthParentBarcode" + "ftagTruthParentBarcode", + "ftagTrackDecayVertexID" ] }, "ip_prefix": "btagIp_" @@ -44,44 +45,21 @@ { "association": { "file": "fragments/baseline-truth-kinematics.json", - "particles": "truth_hadrons" + "particles": "truth_any" }, "output": { - "n_to_save": 5, + "n_to_save": 25, "sort_order": "pt" - } - }, - { - "association": { - "file": "fragments/baseline-truth-kinematics.json", - "particles": "truth_leptons" }, - "output": { - "n_to_save": 5, - "sort_order": "pt" + "vars" : { + "file": "fragments/truth-variables.json" } - }, - { - "association": { - "file": "fragments/baseline-truth-kinematics.json", - "particles": "truth_fromBC" - }, - "output": { - "n_to_save": 5, - "sort_order": "pt" - } - }, + } + ], + "ca_blocks" : [ { - "merge": [ - "ConeExclTausFinal", - "ConeExclCHadronsFinal", - "ConeExclBHadronsFinal" - ], - "association_name": "ConeExclFinalLabels", - "output": { - "n_to_save": 5, - "sort_order": "pt" - } + "block": "TruthVertexGenerator" } + ] } diff --git a/configs/fragments/truth-variables.json b/configs/fragments/truth-variables.json new file mode 100644 index 0000000000000000000000000000000000000000..639f9090e477ef732746cb1850b746fe83a5e262 --- /dev/null +++ b/configs/fragments/truth-variables.json @@ -0,0 +1,20 @@ +{ + "ints" : [ + "charge", + "flavour", + "pdgId", + "barcode", + "parentBarcode" + ], + "floats" : [ + "pt", + "mass", + "energy", + "eta", + "phi", + "deta", + "dphi", + "dr", + "Lxy" + ] +} \ No newline at end of file