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