diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
index 8f65864f88a0841eb355341f439a20aff687caef..9fd0c235caf7820084799b5021cb79dc6148640b 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedRatiosTool.h
@@ -27,7 +27,8 @@ class EnergyCorrelatorGeneralizedRatiosTool :
     ASG_TOOL_CLASS(EnergyCorrelatorGeneralizedRatiosTool, IJetModifier)
     
     public:
-      // Constructor and destructor
+      
+      /// Constructor
       EnergyCorrelatorGeneralizedRatiosTool(std::string name);
 
       virtual StatusCode initialize() override;
@@ -35,12 +36,106 @@ class EnergyCorrelatorGeneralizedRatiosTool :
       int modifyJet(xAOD::Jet &jet) const override;
 
     private:
+
+      /// ECFG ratio moments structure
+      struct moments_t;
+      
+      /// Configurable as properties
+      bool m_doM3;
       bool m_doN3;
       bool m_doLSeries;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment accessors and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+      /// ConstAccessors for L-series ECFs
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_2_1_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_1_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_2_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_2_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_3_3_1;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_4_2_2;
+      std::unique_ptr< SG::AuxElement::ConstAccessor<float> > m_acc_ECFG_4_4_1;
+      
+      /// Decorator for L-series ECFRs
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L3;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L4;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_L5;
+
+};
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelatorGeneralized ratio calculations. This includes the prefix and 
+ * suffix, beta, and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorGeneralizedRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECFG accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_2_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_4_1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_4_2;
+
+  /// ECFG ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_2_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECFG_3_2_ungroomed;
+  
+  /// M and N series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N3;
+
+  /// Dichroic M and N series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_M2_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_N2_dichroic;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    acc_ECFG_2_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_2_1"+suffix);
+    acc_ECFG_3_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_1"+suffix);
+    acc_ECFG_3_2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_2"+suffix);
+    acc_ECFG_4_1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_4_1"+suffix);
+    acc_ECFG_4_2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_4_2"+suffix);
+
+    acc_ECFG_2_1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_2_1_ungroomed"+suffix);
+    acc_ECFG_3_1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_1_ungroomed"+suffix);
+    acc_ECFG_3_2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECFG_3_2_ungroomed"+suffix);
+    
+    dec_M2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M2"+suffix);
+    dec_M3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M3"+suffix);
+    dec_N2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N2"+suffix);
+    dec_N3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N3"+suffix);
+    
+    dec_M2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"M2_dichroic"+suffix);
+    dec_N2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"N2_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
index 7f4169048884d3e0a80eb634c4550bc1a2207949..c997afcbc51b53c5700b1065f36bbf412ebaf1dd 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorGeneralizedTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorGeneralizedTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+
+      /// Constructor
       EnergyCorrelatorGeneralizedTool(std::string name);
 
       virtual StatusCode initialize() override;
@@ -35,13 +36,82 @@ class EnergyCorrelatorGeneralizedTool :
       int modifyJet(xAOD::Jet &injet) const override;
 
     private:
+
+      /// ECFG moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Beta;
+      bool m_doM3;
       bool m_doN3;
       bool m_doLSeries;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+      /// Decorators for L-series ECFs
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_2_1_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_1_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_2_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_2_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_3_3_1;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_4_2_2;
+      std::unique_ptr< SG::AuxElement::Decorator<float> > m_dec_ECFG_4_4_1;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of 
+ * EnergyCorrelatorGeneralized calculations. This includes the prefix and suffix, 
+ * beta, and the necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorGeneralizedTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECFG decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_2_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_4_1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_4_2;
+  
+  /// ECFG ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_2_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECFG_3_2_ungroomed;
+  
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    dec_ECFG_2_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_2_1"+suffix);
+    dec_ECFG_3_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_1"+suffix);
+    dec_ECFG_3_2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_2"+suffix);
+    dec_ECFG_4_1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_4_1"+suffix);
+    dec_ECFG_4_2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_4_2"+suffix);
+    
+    dec_ECFG_2_1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_2_1_ungroomed"+suffix);
+    dec_ECFG_3_1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_1_ungroomed"+suffix);
+    dec_ECFG_3_2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECFG_3_2_ungroomed"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
index 6148b1e3210488420183ea10934258d3b155002a..3ec8f99a473156b02e79627620f78d65ed7b138f 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorRatiosTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorRatiosTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorRatiosTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+
+      /// Constructor
       EnergyCorrelatorRatiosTool(std::string name);
      
       virtual StatusCode initialize() override;
@@ -35,12 +36,89 @@ class EnergyCorrelatorRatiosTool :
       int modifyJet(xAOD::Jet &jet) const override;
 
     private:
+
+      /// ECF ratio moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       bool m_doC3;
       bool m_doC4;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
 
+      /// Map of moment accessors and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelator ratio calculations. This includes the prefix and suffix, beta,
+ * and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECF accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF3;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF4;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF5;
+
+  /// ECF ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF1_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF2_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_ECF3_ungroomed;
+
+  /// C and D series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_C4;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_D2;
+
+  /// Dichroic C and D series decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_D2_dichroic;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    acc_ECF1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF1"+suffix);
+    acc_ECF2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF2"+suffix);
+    acc_ECF3 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF3"+suffix);
+    acc_ECF4 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF4"+suffix);
+    acc_ECF5 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF5"+suffix);
+
+    acc_ECF1_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF1_ungroomed"+suffix);
+    acc_ECF2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF2_ungroomed"+suffix);
+    acc_ECF3_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"ECF3_ungroomed"+suffix);
+
+    dec_C1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C1"+suffix);
+    dec_C2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C2"+suffix);
+    dec_C3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C3"+suffix);
+    dec_C4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"C4"+suffix);
+    dec_D2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"D2"+suffix);
+
+    dec_D2_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"D2_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
index 10653bc77b8ebad5da5a280dc663e4fbf6fb0682..66159e793a8d773e42c672c7c64ebf4785013219 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/EnergyCorrelatorTool.h
@@ -25,9 +25,10 @@
 class EnergyCorrelatorTool :
   public JetSubStructureMomentToolsBase {
     ASG_TOOL_CLASS(EnergyCorrelatorTool, IJetModifier)
-    
+
     public:
-      // Constructor and destructor
+      
+      /// Constructor
       EnergyCorrelatorTool(std::string name);
      
       virtual StatusCode initialize() override;
@@ -35,12 +36,71 @@ class EnergyCorrelatorTool :
       int modifyJet(xAOD::Jet &injet) const override;
 
     private:
+
+      /// ECF moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Beta;
       bool m_doC3;
       bool m_doC4;
       std::vector<float> m_rawBetaVals; /// Vector of input values before cleaning
-      std::vector<float> m_betaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
+      
+      /// Map of moment calculators and decorators using beta as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * EnergyCorrelator calculations. This includes the prefix and suffix, beta, and
+ * the necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct EnergyCorrelatorTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float beta;
+
+  /// ECF decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF4;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF5;
+
+  /// ECF ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF1_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF2_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_ECF3_ungroomed;
+
+  moments_t (float Beta, std::string Prefix) {
+
+    prefix = Prefix;
+    beta = Beta;
+
+    suffix = GetBetaSuffix(beta);
+
+    dec_ECF1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF1"+suffix);
+    dec_ECF2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF2"+suffix);
+    dec_ECF3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF3"+suffix);
+    dec_ECF4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF4"+suffix);
+    dec_ECF5 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF5"+suffix);
+
+    dec_ECF1_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF1_ungroomed"+suffix);
+    dec_ECF2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF2_ungroomed"+suffix);
+    dec_ECF3_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"ECF3_ungroomed"+suffix);
+
+  }
 
 };
 
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
index 49bdf099de909ee959fb9be9888c10cb7fc33a1c..8262e7c0f7949d075a34a967ca49b28d509c69f3 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessRatiosTool.h
@@ -27,7 +27,8 @@ class NSubjettinessRatiosTool :
     ASG_TOOL_CLASS(NSubjettinessRatiosTool, IJetModifier)
 
     public:
-      // Constructor and destructor
+
+      /// Constructor
       NSubjettinessRatiosTool(std::string name);
 
       StatusCode initialize();
@@ -35,9 +36,123 @@ class NSubjettinessRatiosTool :
       int modifyJet(xAOD::Jet &jet) const;
 
     private:
+
+      /// N-subjettiness ratio moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       std::vector<float> m_rawAlphaVals; /// Vector of input values before cleaning
-      std::vector<float> m_alphaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
+  
+      /// Map of moment accessors and decorators using alpha as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * NSubjettiness ratio calculations. This includes the prefix and suffix, alpha, 
+ * and the necessary accessors and decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct NSubjettinessRatiosTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Suffix for decorations
+  std::string suffix;
+
+  /// Beta value for calculations
+  float alpha;
+
+  /// NSubjettiness accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau1;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4;
+
+  /// NSubjettiness ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_ungroomed;
+
+  /// WTA NSubjettiness accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau1_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_wta;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_wta;
+
+  /// WTA NSubjettiness ungroomed accessors
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau2_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau3_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::ConstAccessor<float> > acc_Tau4_wta_ungroomed;
+
+  /// NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42;
+
+  /// Dichroic NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_dichroic;
+
+  /// WTA NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_wta;
+
+  /// WTA Dichroic NSubjettiness Ratios decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau21_wta_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau32_wta_dichroic;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau42_wta_dichroic;
+
+  moments_t (float Alpha, std::string Prefix) {
+
+    prefix = Prefix;
+    alpha = Alpha;
+
+    suffix = GetAlphaSuffix(alpha);
+
+    acc_Tau1 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau1"+suffix);
+    acc_Tau2 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2"+suffix);
+    acc_Tau3 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3"+suffix);
+    acc_Tau4 = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4"+suffix);
+
+    acc_Tau2_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_ungroomed"+suffix);
+    acc_Tau3_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_ungroomed"+suffix);
+    acc_Tau4_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_ungroomed"+suffix);
+
+    acc_Tau1_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau1_wta"+suffix);
+    acc_Tau2_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_wta"+suffix);
+    acc_Tau3_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_wta"+suffix);
+    acc_Tau4_wta = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_wta"+suffix);
+
+    acc_Tau2_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau2_wta_ungroomed"+suffix);
+    acc_Tau3_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau3_wta_ungroomed"+suffix);
+    acc_Tau4_wta_ungroomed = std::make_unique< SG::AuxElement::ConstAccessor<float> >(prefix+"Tau4_wta_ungroomed"+suffix);
+
+    dec_Tau21 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21"+suffix);
+    dec_Tau32 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32"+suffix);
+    dec_Tau42 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42"+suffix);
+
+    dec_Tau21_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_dichroic"+suffix);
+    dec_Tau32_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_dichroic"+suffix);
+    dec_Tau42_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_dichroic"+suffix);
+
+    dec_Tau21_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_wta"+suffix);
+    dec_Tau32_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_wta"+suffix);
+    dec_Tau42_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_wta"+suffix);
+
+    dec_Tau21_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau21_wta_dichroic"+suffix);
+    dec_Tau32_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau32_wta_dichroic"+suffix);
+    dec_Tau42_wta_dichroic = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau42_wta_dichroic"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
index df9087ef86d7945db1d0509105e7311d6db66960..500b645d794a9d6f568ee7728b68aab4dff3a81a 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/JetSubStructureMomentTools/NSubjettinessTool.h
@@ -35,11 +35,85 @@ class NSubjettinessTool :
       int modifyJet(xAOD::Jet &injet) const;
 
     private:
+
+      /// N-subjettiness moments structure
+      struct moments_t;
+
+      /// Configurable as properties
       float m_Alpha;
       std::vector<float> m_rawAlphaVals; /// Vector of input values before cleaning
-      std::vector<float> m_alphaVals; /// Local vector for cleaned up inputs
       bool m_doDichroic;
-      
+
+      /// Map of decorators using alpha as the key
+      std::map< float, moments_t > m_moments;
+
+  };
+
+/**
+ * --------------------------------------------------------------------------------
+ * Structure to hold all of the necessary moment information for a single set of
+ * NSubjettiness calculations. This includes the prefix and suffix, alpha, and the
+ * necessary decorators.
+ * --------------------------------------------------------------------------------
+ **/
+
+struct NSubjettinessTool::moments_t {
+
+  /// Prefix for decorations
+  std::string prefix;
+
+  /// Alpha value for calculations
+  float alpha;
+
+  /// NSubjettiness decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau1;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4;
+
+  /// NSubjettiness ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_ungroomed;
+
+  /// WTA NSubjettiness decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau1_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_wta;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_wta;
+
+  /// WTA NSubjettiness ungroomed decorators
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau2_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau3_wta_ungroomed;
+  std::unique_ptr< SG::AuxElement::Decorator<float> > dec_Tau4_wta_ungroomed;
+
+  moments_t (float Alpha, std::string Prefix) {
+
+    prefix = Prefix;
+    alpha = Alpha;
+
+    std::string suffix = GetAlphaSuffix(alpha);
+
+    dec_Tau1 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau1"+suffix);
+    dec_Tau2 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2"+suffix);
+    dec_Tau3 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3"+suffix);
+    dec_Tau4 = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4"+suffix);
+
+    dec_Tau2_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_ungroomed"+suffix);
+    dec_Tau3_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_ungroomed"+suffix);
+    dec_Tau4_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_ungroomed"+suffix);
+
+    dec_Tau1_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau1_wta"+suffix);
+    dec_Tau2_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_wta"+suffix);
+    dec_Tau3_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_wta"+suffix);
+    dec_Tau4_wta = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_wta"+suffix);
+
+    dec_Tau2_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau2_wta_ungroomed"+suffix);
+    dec_Tau3_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau3_wta_ungroomed"+suffix);
+    dec_Tau4_wta_ungroomed = std::make_unique< SG::AuxElement::Decorator<float> >(prefix+"Tau4_wta_ungroomed"+suffix);
+
+  }
+
 };
 
 #endif
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
index c0438a37449a499a5a27698c1254d51fec292d3d..ac2ade3f53e2b8225ac15c3afb1f8d3fc16393e7 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedRatiosTool.cxx
@@ -8,214 +8,261 @@
 EnergyCorrelatorGeneralizedRatiosTool::EnergyCorrelatorGeneralizedRatiosTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoN3", m_doN3 = false);
-  declareProperty("DoLSeries", m_doLSeries = false);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoM3",       m_doM3 = false);
+  declareProperty("DoN3",       m_doN3 = false);
+  declareProperty("DoLSeries",  m_doLSeries = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorGeneralizedRatiosTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-    // Round to the nearest 0.1
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// Initialize accessors for L-series
+  m_acc_ECFG_2_1_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_2_1_2");
+  m_acc_ECFG_3_1_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_1_1");
+  m_acc_ECFG_3_2_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_2_1");
+  m_acc_ECFG_3_2_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_2_2");
+  m_acc_ECFG_3_3_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_3_3_1");
+  m_acc_ECFG_4_2_2 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_4_2_2");
+  m_acc_ECFG_4_4_1 = std::make_unique< SG::AuxElement::Accessor<float> >(m_prefix+"ECFG_4_4_1");
+
+  /// Initialize decorators for L-series
+  m_dec_L1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L1");
+  m_dec_L2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L2");
+  m_dec_L3 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L3");
+  m_dec_L4 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L4");
+  m_dec_L5 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"L5");
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorGeneralizedRatiosTool::modifyJet(xAOD::Jet &jet) const {
 
-  for(float beta : m_betaVals) {
-    std::string suffix = GetBetaSuffix(beta);
+  for( auto const& moment : m_moments ) {
+
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_2_1" << suffix << "' is not available. Exiting..");
+    /// Check to make sure all of the necessary ECFG decorations are available
+    if( !moment.second.acc_ECFG_2_1->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_2_1" << suffix << "' is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_3_2"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_2" << suffix << "' is not available. Exiting..");
+    if( !moment.second.acc_ECFG_3_2->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_2" << suffix << "' is not available. Exiting." );
       return 1;
     }
 
-    if(m_doN3) {
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_3_1"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_1" << suffix << "' is not available. Exiting..");
+    if( m_doM3 || m_doN3 ) {
+      if( !moment.second.acc_ECFG_3_1->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_1" << suffix << "' is not available. Exiting." );
         return 1;
       }
+    }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_4_2"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_4_2" << suffix << "' is not available. Exiting..");
+    if( m_doM3 ) {
+      if( !moment.second.acc_ECFG_4_1->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_4_1" << suffix << "' is not available. Exiting." );
         return 1;
       }
     }
 
-    if (m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_2_1_ungroomed" << suffix << "' is not available. Exiting..");
+    if( m_doN3 ) {
+      if( !moment.second.acc_ECFG_4_2->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_4_2" << suffix << "' is not available. Exiting." );
         return 1;
       }
+    }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECFG_3_1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_1_ungroomed" << suffix << "' is not available. Exiting..");
+    if( m_doDichroic ) {
+      if( !moment.second.acc_ECFG_2_1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_2_1_ungroomed" << suffix << "' is not available. Exiting." );
         return 1;
       }
 
-      if(m_doN3) {
-        if (!jet.isAvailable<float>(m_prefix+"ECFG_3_2_ungroomed"+suffix)) {
-          ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECFG_3_2_ungroomed" << suffix << "' is not available. Exiting..");
-          return 1;
-        }
+      if( !moment.second.acc_ECFG_3_1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_1_ungroomed" << suffix << "' is not available. Exiting." );
+        return 1;
       }
-    }
 
-    float ecfg_2_1 = jet.getAttribute<float>(m_prefix+"ECFG_2_1"+suffix);
-    float ecfg_3_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_1"+suffix);
-    float ecfg_3_2 = jet.getAttribute<float>(m_prefix+"ECFG_3_2"+suffix);
-    float ecfg_4_2 = jet.getAttribute<float>(m_prefix+"ECFG_4_2"+suffix);
+      if( !moment.second.acc_ECFG_3_2_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECFG_3_2_ungroomed" << suffix << "' is not available. Exiting." );
+        return 1;
+      }
+    }
 
+    float ecfg_2_1 = (*moment.second.acc_ECFG_2_1)(jet);
+    float ecfg_3_1 = (*moment.second.acc_ECFG_3_1)(jet);
+    float ecfg_3_2 = (*moment.second.acc_ECFG_3_2)(jet);
+    float ecfg_4_1 = (*moment.second.acc_ECFG_4_2)(jet);
+    float ecfg_4_2 = (*moment.second.acc_ECFG_4_2)(jet);
+    
     float ecfg_2_1_ungroomed = -999.0;
     float ecfg_3_1_ungroomed = -999.0;
     float ecfg_3_2_ungroomed = -999.0;
 
-    if (m_doDichroic) {
-      ecfg_2_1_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_2_1_ungroomed"+suffix);
-      ecfg_3_1_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_3_1_ungroomed"+suffix);
-      ecfg_3_2_ungroomed = jet.getAttribute<float>(m_prefix+"ECFG_3_2_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      ecfg_2_1_ungroomed = (*moment.second.acc_ECFG_2_1_ungroomed)(jet);
+      ecfg_3_1_ungroomed = (*moment.second.acc_ECFG_3_1_ungroomed)(jet);
+      ecfg_3_2_ungroomed = (*moment.second.acc_ECFG_3_2_ungroomed)(jet);
     }
 
-    // N2
-    if(ecfg_2_1 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"N2"+suffix, ecfg_3_2 / (pow(ecfg_2_1, 2.0)));
+    float M2 = -999.0;
+    float M3 = -999.0;
+
+    float N2 = -999.0;
+    float N3 = -999.0;
+    
+    float M2_dichroic = -999.0;
+    float N2_dichroic = -999.0;
 
-      if(ecfg_3_2_ungroomed > 1e-8 && ecfg_2_1_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"N2_dichroic"+suffix, ecfg_3_2_ungroomed / (ecfg_2_1_ungroomed * ecfg_2_1));
-      else
-        jet.setAttribute(m_prefix+"N2_dichroic"+suffix, -999.0);
+    /// M2
+    if( ecfg_2_1 > 1e-8 ) /// Prevent div-0
+    {
+     
+      M2 = ecfg_3_1 / ecfg_2_1;
+
+      if( ecfg_3_1_ungroomed > 1e-8 )
+      {
+        M2_dichroic = ecfg_3_1_ungroomed / ecfg_2_1;
+      }
+    
     }
-    else {
-      jet.setAttribute(m_prefix+"N2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"N2_dichroic"+suffix, -999.0);
+    
+    /// M3
+    if( m_doM3 && ecfg_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      M3 = ecfg_4_1 / ecfg_3_1;
     }
 
-    // N3
-    if(m_doN3 && ecfg_3_1 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"N3"+suffix, ecfg_4_2 / (pow(ecfg_3_1, 2.0)));
-    else
-      jet.setAttribute(m_prefix+"N3"+suffix, -999.0);
+    /// N2
+    if( ecfg_2_1 > 1e-8 ) /// Prevent div-0
+    {
+      
+      N2 = ecfg_3_2 / pow( ecfg_2_1, 2.0 );
 
-    // M2
-    if(ecfg_2_1 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"M2"+suffix, ecfg_3_1 / ecfg_2_1);
+      if( ecfg_3_2_ungroomed > 1e-8 && ecfg_2_1_ungroomed > 1e-8 )
+      {
+        N2_dichroic = ecfg_3_2_ungroomed / ( ecfg_2_1_ungroomed * ecfg_2_1 );
+      }
 
-      if(ecfg_3_1_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"M2_dichroic"+suffix, ecfg_3_1_ungroomed / ecfg_2_1);
-      else
-        jet.setAttribute(m_prefix+"M2_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"M2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"M2_dichroic"+suffix, -999.0);
+
+    /// N3
+    if( m_doN3 && ecfg_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      N3 = ecfg_4_2 / pow( ecfg_3_1, 2.0 );
     }
 
+    (*moment.second.dec_M2)(jet) = M2;
+    (*moment.second.dec_M3)(jet) = M3;
+    
+    (*moment.second.dec_N2)(jet) = N2;
+    (*moment.second.dec_N3)(jet) = N3;
+    
+    (*moment.second.dec_M2_dichroic)(jet) = M2_dichroic;
+    (*moment.second.dec_N2_dichroic)(jet) = N2_dichroic;
+
   }
 
-  if (m_doLSeries) {
-    // These are for t/H discrimination
-    if (!jet.isAvailable<float>(m_prefix+"ECFG_2_1_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_1_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_2_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_2_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_4_2_2") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_3_3_1") ||
-        !jet.isAvailable<float>(m_prefix+"ECFG_4_4_1")) {
+  /**
+   * ------------------------------------------------------------------
+   * L-series ECFG ratios (experimental for ttH t/H discrimination)
+   *
+   * The exponents E are determined in order to make the ratios dimensionless
+   *
+   * E = (a*n) / (b*m)
+   * for an ECFG_X_Y_Z, a=Y, n=Z
+   *
+   * e.g. for L1
+   * ecfg_3_3_1 / ecfg_2_1_2
+   * E = (3*1) / (1*2) = 3./2.
+   * ------------------------------------------------------------------
+   */
+
+  float L1 = -999.0;
+  float L2 = -999.0;
+  float L3 = -999.0;
+  float L4 = -999.0;
+  float L5 = -999.0;
+
+  if( m_doLSeries ) {
+
+    if( !m_acc_ECFG_2_1_2->isAvailable(jet) ||
+        !m_acc_ECFG_3_1_1->isAvailable(jet) ||
+        !m_acc_ECFG_3_2_1->isAvailable(jet) ||
+        !m_acc_ECFG_3_2_2->isAvailable(jet) ||
+        !m_acc_ECFG_3_3_1->isAvailable(jet) ||
+        !m_acc_ECFG_4_2_2->isAvailable(jet) ||
+        !m_acc_ECFG_4_4_1->isAvailable(jet) ) {
       ATH_MSG_WARNING("L series energy correlation functions with prefix '" << m_prefix << "' are not all available. Exiting..");
       return 1;
     }
-  }
-
-  float ecfg_2_1_2 = -999.0;
-  float ecfg_3_1_1 = -999.0;
-  float ecfg_3_2_1 = -999.0;
-  float ecfg_3_2_2 = -999.0;
-  float ecfg_4_2_2 = -999.0;
-  float ecfg_3_3_1 = -999.0;
-  float ecfg_4_4_1 = -999.0;
-
-  if (m_doLSeries) {
-    ecfg_2_1_2 = jet.getAttribute<float>(m_prefix+"ECFG_2_1_2");
-    ecfg_3_1_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_1_1");
-    ecfg_3_2_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_2_1");  
-    ecfg_3_2_2 = jet.getAttribute<float>(m_prefix+"ECFG_3_2_2");
-    ecfg_4_2_2 = jet.getAttribute<float>(m_prefix+"ECFG_4_2_2");
-    ecfg_3_3_1 = jet.getAttribute<float>(m_prefix+"ECFG_3_3_1");
-    ecfg_4_4_1 = jet.getAttribute<float>(m_prefix+"ECFG_4_4_1");
-  }
-
-  // L-series variables
-  // (experimental for ttH t/H discrimination)
-
-  /*
-     The exponents are determined in order to make 
-     the whole thing dimensionless
 
-     E = (a*n) / (b*m)
-     for an ECFG_X_Y_Z, a=Y, n=Z
+    float ecfg_2_1_2 = (*m_acc_ECFG_2_1_2)(jet);
+    float ecfg_3_1_1 = (*m_acc_ECFG_3_1_1)(jet);
+    float ecfg_3_2_1 = (*m_acc_ECFG_3_2_1)(jet);
+    float ecfg_3_2_2 = (*m_acc_ECFG_3_2_2)(jet);
+    float ecfg_3_3_1 = (*m_acc_ECFG_3_3_1)(jet);
+    float ecfg_4_2_2 = (*m_acc_ECFG_4_2_2)(jet);
+    float ecfg_4_4_1 = (*m_acc_ECFG_4_4_1)(jet);
+
+    if( ecfg_2_1_2 > 1e-8 ) /// Prevent div-0
+    {
+      L1 = ecfg_3_2_1 / pow( ecfg_2_1_2, 1.0 );
+      L2 = ecfg_3_3_1 / pow( ecfg_2_1_2, (3.0/2.0) );
+    }
 
-     e.g. for L1
+    if( ecfg_3_3_1 > 1e-8 ) /// Prevent div-0
+    {
+      L3 = ecfg_3_1_1 / pow( ecfg_3_3_1, (1.0/3.0) );
+      L4 = ecfg_3_2_2 / pow( ecfg_3_3_1, (4.0/3.0) );
+    }
 
-     ecfg_3_3_1 / ecfg_2_1_2
-     E = (3*1) / (1*2) = 3./2.
-     */
+    if( ecfg_4_4_1 > 1e-8 ) /// Prevent div-0
+    {
+      L5 = ecfg_4_2_2 / pow( ecfg_4_4_1, 1.0 );
+    }
 
-  if(ecfg_2_1_2 > 1e-8) // Prevent div-0
-  {
-    jet.setAttribute(m_prefix+"L1", ecfg_3_2_1 / (pow(ecfg_2_1_2, (1.) )));
-    jet.setAttribute(m_prefix+"L2", ecfg_3_3_1 / (pow(ecfg_2_1_2, (3./2.) )));
-  }
-  else
-  {
-    jet.setAttribute(m_prefix+"L1",-999.0);
-    jet.setAttribute(m_prefix+"L2",-999.0);
-  }
 
-  if(ecfg_3_3_1 > 1e-8) // Prevent div-0
-  {  
-    jet.setAttribute(m_prefix+"L3", ecfg_3_1_1 / (pow(ecfg_3_3_1, (1./3.) )) );
-    jet.setAttribute(m_prefix+"L4", ecfg_3_2_2 / (pow(ecfg_3_3_1, (4./3.) )) );
-  }
-  else
-  {
-    jet.setAttribute(m_prefix+"L3",-999.0);
-    jet.setAttribute(m_prefix+"L4",-999.0);
   }
 
-  if(ecfg_4_4_1 > 1e-8) // Prevent div-0
-    jet.setAttribute(m_prefix+"L5", ecfg_4_2_2 / (pow(ecfg_4_4_1, (1.) )) );
-  else
-    jet.setAttribute(m_prefix+"L5",-999.0);
+  (*m_dec_L1)(jet) = L1;
+  (*m_dec_L2)(jet) = L2;
+  (*m_dec_L3)(jet) = L3;
+  (*m_dec_L4)(jet) = L4;
+  (*m_dec_L5)(jet) = L5;
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
index 8bff896e130cdcd57dbdb9351ccac6a58b7882d6..bf5143f67fd7190323a307ce5eb5360e9f3523b2 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorGeneralizedTool.cxx
@@ -3,181 +3,255 @@
 */
 
 #include "JetSubStructureMomentTools/EnergyCorrelatorGeneralizedTool.h"
-#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h" 
-#include "JetSubStructureUtils/EnergyCorrelator.h" 
+#include "JetSubStructureUtils/EnergyCorrelatorGeneralized.h"
+#include "JetSubStructureUtils/EnergyCorrelator.h"
 
 EnergyCorrelatorGeneralizedTool::EnergyCorrelatorGeneralizedTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Beta", m_Beta = 1.0);
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoN3", m_doN3 = false);
-  declareProperty("DoLSeries", m_doLSeries = false);
+  declareProperty("Beta",       m_Beta = 1.0);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoM3",       m_doM3 = false);
+  declareProperty("DoN3",       m_doN3 = false);
+  declareProperty("DoLSeries",  m_doLSeries = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorGeneralizedTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Add beta = m_Beta by default to keep backwards compatibility
-  if( std::abs(m_Beta-1.0) > 1.0e-5 ) m_betaVals.push_back(m_Beta);
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = m_Beta by default to keep backwards compatibility
+  if( std::abs(m_Beta-1.0) > 1.0e-5 ) {
 
-    // Round to the nearest 0.1
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Beta property is deprecated, please use the BetaList property to provide a list of values" );
+
+    /// Use m_Beta to not break analysis code
+    m_moments.emplace( m_Beta, moments_t(m_Beta, m_prefix) );
+
+  }
+
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// Initialize decorators for L-series
+  m_dec_ECFG_2_1_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_2_1_2");
+  m_dec_ECFG_3_1_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_1_1");
+  m_dec_ECFG_3_2_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_2_1");
+  m_dec_ECFG_3_2_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_2_2");
+  m_dec_ECFG_3_3_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_3_3_1");
+  m_dec_ECFG_4_2_2 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_4_2_2");
+  m_dec_ECFG_4_4_1 = std::make_unique< SG::AuxElement::Decorator<float> >(m_prefix+"ECFG_4_4_1");
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorGeneralizedTool::modifyJet(xAOD::Jet &injet) const {
-  
+
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
-  
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
+
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
+
+  if( m_doDichroic ) {
+
+    /// Get parent jet
     ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
 
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
-  }
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
 
-  for(float beta : m_betaVals) {
+  }
 
-    std::string suffix = GetBetaSuffix(beta);
+  /// Loop over all of the moments
+  for( auto const& moment : m_moments ) {
 
-    // These are used for N2 and M2
-    float ECFG_2_1_value = -999, ECFG_3_2_value = -999;
-    float ECFG_2_1_value_ungroomed = -999, ECFG_3_2_value_ungroomed = -999;
+    float beta = moment.first;
 
-    // These are used for N3
-    float ECFG_3_1_value = -999, ECFG_4_2_value = -999;
-    float ECFG_3_1_value_ungroomed = -999;
+    /// These are used for M2 and N2
+    float ECFG_2_1_value = -999.0;
+    float ECFG_3_2_value = -999.0;
+    
+    /// These are used for dichroic M2 and N2
+    float ECFG_2_1_ungroomed_value = -999.0;
+    float ECFG_3_1_ungroomed_value = -999.0;
+    float ECFG_3_2_ungroomed_value = -999.0;
 
-    if (decorate) {
+    /// These are used for M3 and N3
+    float ECFG_3_1_value = -999.0;
+    float ECFG_4_1_value = -999.0;
+    float ECFG_4_2_value = -999.0;
 
-      // These are used for N2 and M2
+    if( calculate ) {
 
+      /// These are used for N2 and M2
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2(2, 3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1(1, 2, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+
       ECFG_2_1_value = ECFG_2_1.result(jet);
       ECFG_3_2_value = ECFG_3_2.result(jet);
 
-      if (decorate_ungroomed) {
-        ECFG_2_1_value_ungroomed = ECFG_2_1.result(jet_ungroomed);
-        ECFG_3_2_value_ungroomed = ECFG_3_2.result(jet_ungroomed);
+      /// These are used for dichroic N2 and M2
+      if( calculate_ungroomed ) {
+        ECFG_2_1_ungroomed_value = ECFG_2_1.result(jet_ungroomed);
+        ECFG_3_2_ungroomed_value = ECFG_3_2.result(jet_ungroomed);
       }
 
-      // These are used for N3
+      /// These are used for M3 and N3
+      if( m_doM3 || m_doN3 ) {
 
-      if(m_doN3) {
-        JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2(2, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
         JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1(1, 3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+
         ECFG_3_1_value = ECFG_3_1.result(jet);
-        ECFG_4_2_value = ECFG_4_2.result(jet);
 
-        if (decorate_ungroomed) {
-          ECFG_3_1_value_ungroomed = ECFG_3_1.result(jet_ungroomed);
+        if( calculate_ungroomed ) {
+          ECFG_3_1_ungroomed_value = ECFG_3_1.result(jet_ungroomed);
+        }
+
+        /// This is used for M3
+        if( m_doM3 ) {
+          JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_1(1, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+          ECFG_4_1_value = ECFG_4_1.result(jet);
+        }
+
+        /// This is used for N3
+        if( m_doN3 ) {
+          JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2(2, 4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
+          ECFG_4_2_value = ECFG_4_2.result(jet);
         }
 
       }
 
     }
 
-    injet.setAttribute(m_prefix+"ECFG_2_1"+suffix, ECFG_2_1_value);
-    injet.setAttribute(m_prefix+"ECFG_3_2"+suffix, ECFG_3_2_value);
-    injet.setAttribute(m_prefix+"ECFG_3_1"+suffix, ECFG_3_1_value);
-    injet.setAttribute(m_prefix+"ECFG_4_2"+suffix, ECFG_4_2_value);
+    (*moment.second.dec_ECFG_2_1)(injet) = ECFG_2_1_value;
+    (*moment.second.dec_ECFG_3_1)(injet) = ECFG_3_1_value;
+    (*moment.second.dec_ECFG_3_2)(injet) = ECFG_3_2_value;
+    (*moment.second.dec_ECFG_4_1)(injet) = ECFG_4_1_value;
+    (*moment.second.dec_ECFG_4_2)(injet) = ECFG_4_2_value;
 
-    injet.setAttribute(m_prefix+"ECFG_2_1_ungroomed"+suffix, ECFG_2_1_value_ungroomed);
-    injet.setAttribute(m_prefix+"ECFG_3_2_ungroomed"+suffix, ECFG_3_2_value_ungroomed);
-    injet.setAttribute(m_prefix+"ECFG_3_1_ungroomed"+suffix, ECFG_3_1_value_ungroomed);
+    (*moment.second.dec_ECFG_2_1_ungroomed)(injet) = ECFG_2_1_ungroomed_value;
+    (*moment.second.dec_ECFG_3_1_ungroomed)(injet) = ECFG_3_1_ungroomed_value;
+    (*moment.second.dec_ECFG_3_2_ungroomed)(injet) = ECFG_3_2_ungroomed_value;
 
   }
 
-  // These are for t/H discrimination
-  float ECFG_3_3_2_value = -999, ECFG_3_2_2_value = -999, ECFG_3_3_1_value = -999,
-        ECFG_4_2_2_value = -999, ECFG_4_4_1_value = -999, ECFG_2_1_2_value = -999, ECFG_3_2_1_value =  -999,
-        ECFG_3_1_1_value = -999;
-  // N.B. ECFG_angles_n_beta !!
-
-  if (decorate) {
+  /// ECFGs for L-series ratios that are for t/H discrimination
+  float ECFG_2_1_2_value = -999;
+  float ECFG_3_1_1_value = -999;
+  float ECFG_3_2_1_value = -999;
+  float ECFG_3_2_2_value = -999;
+  float ECFG_3_3_1_value = -999;
+  float ECFG_4_2_2_value = -999;
+  float ECFG_4_4_1_value = -999;
+
+  /// N.B. ECFG_angles_n_beta !!
+
+  if( calculate && m_doLSeries ) {
+
+    /**
+     * ------------------------------------------------------
+     * Some of the ECFGs for the L-series ratios may already have been calculated
+     * depending on which beta values are included. Checks are put in place for
+     * each one and if it has already been calculated the value is simply copied.
+     * This is meant to prevent duplicating CPU intensive calculations that have
+     * already been performed.
+     * ------------------------------------------------------
+     */
+
+    /// 212
+    if( m_moments.count(2.0) ) {
+      ECFG_2_1_2_value = (*m_moments.at(2.0).dec_ECFG_2_1)(injet);
+    }
+    else {
+      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1_2(1, 2, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
+      ECFG_2_1_2_value = ECFG_2_1_2.result(jet);
+    }
 
-    // These are for t/H discrimination
+    /// 311
+    if( m_doN3 ) {
+      ECFG_3_1_1_value = (*m_moments.at(1.0).dec_ECFG_3_1)(injet);
+    }
+    else {
+      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1_1(1, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+      ECFG_3_1_1_value = ECFG_3_1_1.result(jet);
+    }
 
-    if(m_doLSeries) {
-      // 332
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_2(3, 3, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_3_2_value = ECFG_3_3_2.result(jet);
+    /// 321
+    ECFG_3_2_1_value = (*m_moments.at(1.0).dec_ECFG_3_2)(injet);
 
-      // 322
+    /// 322
+    if( m_moments.count(2.0) ) {
+      ECFG_3_2_2_value = (*m_moments.at(2.0).dec_ECFG_3_2)(injet);
+    }
+    else {
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2_2(2, 3, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_2_2_value =  ECFG_3_2_2.result(jet);
+      ECFG_3_2_2_value = ECFG_3_2_2.result(jet);
+    }
 
-      // 331
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_1(3, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_3_1_value = ECFG_3_3_1.result(jet);
+    /// 331
+    JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_3_1(3, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+    ECFG_3_3_1_value = ECFG_3_3_1.result(jet);
 
-      // 422
+    /// 422
+    if( m_doN3 && m_moments.count(2.0) ) {
+      ECFG_4_2_2_value = (*m_moments.at(2.0).dec_ECFG_4_2)(injet);
+    }
+    else {
       JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_2_2(2, 4, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
       ECFG_4_2_2_value = ECFG_4_2_2.result(jet);
-
-      // 441
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_4_1(4, 4, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_4_4_1_value = ECFG_4_4_1.result(jet);
-
-      // 212
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_2_1_2(1, 2, 2, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_2_1_2_value = ECFG_2_1_2.result(jet);
-
-      // 321
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_2_1(2, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_2_1_value = ECFG_3_2_1.result(jet);
-
-      // 311
-      JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_3_1_1(1, 3, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
-      ECFG_3_1_1_value = ECFG_3_1_1.result(jet);
     }
 
+    /// 441
+    JetSubStructureUtils::EnergyCorrelatorGeneralized ECFG_4_4_1(4, 4, 1, JetSubStructureUtils::EnergyCorrelator::pt_R);
+    ECFG_4_4_1_value = ECFG_4_4_1.result(jet);
+  
   }
 
-  injet.setAttribute(m_prefix+"ECFG_3_3_2", ECFG_3_3_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_2_2", ECFG_3_2_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_3_1", ECFG_3_3_1_value);
-  injet.setAttribute(m_prefix+"ECFG_4_2_2", ECFG_4_2_2_value);
-  injet.setAttribute(m_prefix+"ECFG_4_4_1", ECFG_4_4_1_value);
-  injet.setAttribute(m_prefix+"ECFG_2_1_2", ECFG_2_1_2_value);
-  injet.setAttribute(m_prefix+"ECFG_3_2_1", ECFG_3_2_1_value);
-  injet.setAttribute(m_prefix+"ECFG_3_1_1", ECFG_3_1_1_value);
+  (*m_dec_ECFG_2_1_2)(injet) = ECFG_2_1_2_value;
+  (*m_dec_ECFG_3_1_1)(injet) = ECFG_3_1_1_value;
+  (*m_dec_ECFG_3_2_1)(injet) = ECFG_3_2_1_value;
+  (*m_dec_ECFG_3_2_2)(injet) = ECFG_3_2_2_value;
+  (*m_dec_ECFG_3_3_1)(injet) = ECFG_3_3_1_value;
+  (*m_dec_ECFG_4_2_2)(injet) = ECFG_4_2_2_value;
+  (*m_dec_ECFG_4_4_1)(injet) = ECFG_4_4_1_value;
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
index 67c6b03e30eef7c460a7e153a3bfa1a211fa4fd0..0f1fb76f891d109cee0f327e9a1e25b3f144db9f 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorRatiosTool.cxx
@@ -16,149 +16,177 @@ EnergyCorrelatorRatiosTool::EnergyCorrelatorRatiosTool(std::string name) :
 
 StatusCode EnergyCorrelatorRatiosTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-    // Round to the nearest 0.1
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
+  
   }
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
   }
 
-  // If DoC4 is set to true, set DoC3 to true by default since it won't
-  // add any additional computational overhead
-  if(m_doC4) m_doC3 = true;
-
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// If DoC4 is set to true, set DoC3 to true by default since it won't
+  /// add any additional computational overhead
+  if( m_doC4 ) m_doC3 = true;
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorRatiosTool::modifyJet(xAOD::Jet &jet) const {
   
-  for(float beta : m_betaVals) {
-    std::string suffix = GetBetaSuffix(beta);
+  for( auto const& moment : m_moments ) {
+ 
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF1"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF1" << suffix << " is not available. Exiting..");
+    /// Check to make sure all of the necessary ECF decorations are available
+    if( !moment.second.acc_ECF1->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF1" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF2"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF2" << suffix << " is not available. Exiting..");
+    if( !moment.second.acc_ECF2->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF2" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (!jet.isAvailable<float>(m_prefix+"ECF3"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF3" << suffix << " is not available. Exiting..");
+    if( !moment.second.acc_ECF3->isAvailable(jet) ) {
+      ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF3" << suffix << " is not available. Exiting." );
       return 1;
     }
 
-    if (m_doC3 && !jet.isAvailable<float>(m_prefix+"ECF4"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF4" << suffix << " is not available. Exiting..");
-      return 1;
+    if( m_doC3 ) {
+      if( !moment.second.acc_ECF4->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF4" << suffix << " is not available. Exiting." );
+        return 1;
+      }
     }
 
-    if (m_doC4 && !jet.isAvailable<float>(m_prefix+"ECF5"+suffix)) {
-      ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF5" << suffix << " is not available. Exiting..");
-      return 1;
+    if( m_doC4 ) {
+      if( !moment.second.acc_ECF5->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF5" << suffix << " is not available. Exiting." );
+        return 1;
+      }
     }
 
     if(m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"ECF1_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF1_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF1_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF1_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECF2_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF2_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF2_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF2_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
 
-      if (!jet.isAvailable<float>(m_prefix+"ECF3_ungroomed"+suffix)) {
-        ATH_MSG_WARNING("Energy correlation function " << m_prefix << "ECF3_ungroomed" << suffix << " is not available. Exiting..");
+      if( !moment.second.acc_ECF3_ungroomed->isAvailable(jet) ) {
+        ATH_MSG_WARNING( "Energy correlation function " << m_prefix << "ECF3_ungroomed" << suffix << " is not available. Exiting." );
         return 1;
       }
     }
 
-    float ecf1 = jet.getAttribute<float>(m_prefix+"ECF1"+suffix);
-    float ecf2 = jet.getAttribute<float>(m_prefix+"ECF2"+suffix);
-    float ecf3 = jet.getAttribute<float>(m_prefix+"ECF3"+suffix);
+    float ecf1 = (*moment.second.acc_ECF1)(jet);
+    float ecf2 = (*moment.second.acc_ECF2)(jet);
+    float ecf3 = (*moment.second.acc_ECF3)(jet);
 
     float ecf4 = -999.0;
-    if(m_doC3) {
-      ecf4 = jet.getAttribute<float>(m_prefix+"ECF4"+suffix);
+    if( m_doC3 ) {
+      ecf4 = (*moment.second.acc_ECF4)(jet);
     }
 
     float ecf5 = -999.0;
-    if(m_doC4) {
-      ecf5 = jet.getAttribute<float>(m_prefix+"ECF5"+suffix);
+    if( m_doC4 ) {
+      ecf5 = (*moment.second.acc_ECF5)(jet);
     }
 
     float ecf1_ungroomed = -999.0;
     float ecf2_ungroomed = -999.0;
     float ecf3_ungroomed = -999.0;
 
-    if(m_doDichroic) {
-      ecf1_ungroomed = jet.getAttribute<float>(m_prefix+"ECF1_ungroomed"+suffix);
-      ecf2_ungroomed = jet.getAttribute<float>(m_prefix+"ECF2_ungroomed"+suffix);
-      ecf3_ungroomed = jet.getAttribute<float>(m_prefix+"ECF3_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      ecf1_ungroomed = (*moment.second.acc_ECF1_ungroomed)(jet);
+      ecf2_ungroomed = (*moment.second.acc_ECF2_ungroomed)(jet);
+      ecf3_ungroomed = (*moment.second.acc_ECF3_ungroomed)(jet);
     }
 
-    // D2
-    if(ecf2 > 1e-8) { // Prevent div-0
-      jet.setAttribute(m_prefix+"D2"+suffix, ecf3 * pow(ecf1, 3.0) / pow(ecf2, 3.0));
+    float C1 = -999.0;
+    float C2 = -999.0;
+    float C3 = -999.0;
+    float C4 = -999.0;
+    
+    float D2 = -999.0;
+    
+    float D2_dichroic = -999.0;
+
+    /// C1
+    if( ecf1 > 1e-8 ) /// Prevent div-0
+    {
+      C1 = ecf2 / pow( ecf1, 2.0 );
+    }
 
-      if(ecf2_ungroomed > 1e-8 && ecf3_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"D2_dichroic"+suffix, ecf3_ungroomed * ecf1_ungroomed * pow(ecf1, 2.0) / ( pow(ecf2_ungroomed, 2.0) * ecf2 ));
-      else
-        jet.setAttribute(m_prefix+"D2_dichroic"+suffix, -999.0);
+    /// C2
+    if( ecf2 > 1e-8 ) /// Prevent div-0
+    {
+      C2 = ecf3 * ecf1 / pow( ecf2, 2.0 );
+    }
 
+    /// C3
+    if( m_doC3 && ecf3 > 1e-8 ) /// Prevent div-0
+    {
+      C3 = ecf4 * ecf2 / pow( ecf3, 2.0 );
     }
-    else {
-      jet.setAttribute(m_prefix+"D2"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"D2_dichroic"+suffix, -999.0);
+
+    /// C4
+    if( m_doC4 && ecf4 > 1e-8 ) /// Prevent div-0
+    {
+      C4 = ecf5 * ecf3 / pow( ecf4, 2.0 );
     }
 
-    // C1
-    if(ecf1 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C1"+suffix, ecf2 / pow(ecf1, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C1"+suffix, -999.0);
-
-    // C2
-    if(ecf2 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C2"+suffix, ecf3 * ecf1 / pow(ecf2, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C2"+suffix, -999.0);
-
-    // C3
-    if(m_doC3 && ecf3 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C3"+suffix, ecf4 * ecf2 / pow(ecf3, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C3"+suffix, -999.0);
-
-    // C4
-    if(m_doC4 && ecf4 > 1e-8) // Prevent div-0
-      jet.setAttribute(m_prefix+"C4"+suffix, ecf5 * ecf3 / pow(ecf4, 2.0));
-    else
-      jet.setAttribute(m_prefix+"C4"+suffix, -999.0);
+    /// D2
+    if( ecf2 > 1e-8 ) /// Prevent div-0
+    {
+
+      D2 = ecf3 * pow( ecf1, 3.0 ) / pow( ecf2, 3.0 );
+
+      if( ecf2_ungroomed > 1e-8 && ecf3_ungroomed > 1e-8 )
+      {
+        D2_dichroic = ecf3_ungroomed * ecf1_ungroomed * pow( ecf1, 2.0 ) / ( pow( ecf2_ungroomed, 2.0 ) * ecf2 );
+      }
+
+    }
+
+    (*moment.second.dec_C1)(jet) = C1;
+    (*moment.second.dec_C2)(jet) = C2;
+    (*moment.second.dec_C3)(jet) = C3;
+    (*moment.second.dec_C4)(jet) = C4;
+    
+    (*moment.second.dec_D2)(jet) = D2;
+
+    (*moment.second.dec_D2_dichroic)(jet) = D2_dichroic;
+
   }
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
index 23cc78c2d22ffc815b6f1a03aec444fb1c88b700..44cd07c5bc7498aafe919abd1f7fbb43648c24db 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/EnergyCorrelatorTool.cxx
@@ -3,54 +3,66 @@
 */
 
 #include "JetSubStructureMomentTools/EnergyCorrelatorTool.h"
-#include "JetSubStructureUtils/EnergyCorrelator.h" 
+#include "JetSubStructureUtils/EnergyCorrelator.h"
 
 EnergyCorrelatorTool::EnergyCorrelatorTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Beta", m_Beta = 1.0);
-  declareProperty("BetaList", m_rawBetaVals = {});
-  declareProperty("DoC3", m_doC3 = false);
-  declareProperty("DoC4", m_doC4 = false);
+  declareProperty("Beta",       m_Beta = 1.0);
+  declareProperty("BetaList",   m_rawBetaVals = {});
+  declareProperty("DoC3",       m_doC3 = false);
+  declareProperty("DoC4",       m_doC4 = false);
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode EnergyCorrelatorTool::initialize() {
 
-  // Add beta = 1.0 by default
-  m_betaVals.push_back(1.0);
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
 
-  // Add beta = m_Beta by default to keep backwards compatibility
-  if( std::abs(m_Beta-1.0) > 1.0e-5 ) m_betaVals.push_back(m_Beta);
+  /// Add beta = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
 
-  // Clean up input list of beta values
-  for(float beta : m_rawBetaVals) {
+  /// Add beta = m_Beta by default to keep backwards compatibility
+  if( std::abs(m_Beta-1.0) > 1.0e-5 ) {
 
-    // Round to the nearest 0.1
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Beta property is deprecated, please use the BetaList property to provide a list of values");
+
+    /// Use m_Beta to not break analysis code
+    m_moments.emplace( m_Beta, moments_t(m_Beta, m_prefix) );
+
+  }
+
+  /// Clean up input list of beta values
+  for( float beta : m_rawBetaVals ) {
+
+    /// Round to the nearest 0.1
     float betaFix = round( beta * 10.0 ) / 10.0;
-    if(std::abs(beta-betaFix) > 1.0e-5) ATH_MSG_DEBUG("beta = " << beta << " has been rounded to " << betaFix);
+    if( std::abs(beta-betaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "beta = " << beta << " has been rounded to " << betaFix );
 
-    // Skip negative values of beta
-    if(betaFix < 0.0) {
-      ATH_MSG_WARNING("beta must be positive. Skipping beta = " << beta);
+    /// Skip negative values of beta
+    if( betaFix < 0.0 ) {
+      ATH_MSG_WARNING( "beta must be positive. Skipping beta = " << beta );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_betaVals.begin(), m_betaVals.end(), betaFix) == m_betaVals.end() ) m_betaVals.push_back(betaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( betaFix, moments_t(betaFix, m_prefix) );
 
-  for(float beta : m_betaVals) {
-    ATH_MSG_DEBUG("Including beta = " << beta);
   }
 
-  // If DoC4 is set to true, set DoC3 to true by default since it won't
-  // add any additional computational overhead
-  if(m_doC4) m_doC3 = true;
+  /// Print out list of beta values to debug stream
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including beta = " << moment.first );
+  }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  /// If DoC4 is set to true, set DoC3 to true by default since it won't
+  /// add any additional computational overhead
+  if( m_doC4 ) m_doC3 = true;
 
   return StatusCode::SUCCESS;
+
 }
 
 int EnergyCorrelatorTool::modifyJet(xAOD::Jet &injet) const {
@@ -58,81 +70,82 @@ int EnergyCorrelatorTool::modifyJet(xAOD::Jet &injet) const {
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
 
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
+
+  if( m_doDichroic ) {
+
+    /// Get parent jet
     ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
 
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
-  }
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
 
-  for(float beta : m_betaVals) {
+  }
 
-    if(beta < 0.0) {
-      ATH_MSG_WARNING("Negative beta values are not supported. Skipping " << beta);
-      continue;
-    }
+  for( auto const& moment : m_moments ) {
 
-    std::string suffix = GetBetaSuffix(beta);
+    float beta = moment.first;
 
-    float result_ECF1 = -999;
-    float result_ECF2 = -999;
-    float result_ECF3 = -999;
-    float result_ECF4 = -999;
-    float result_ECF5 = -999;
+    float ECF1_value = -999;
+    float ECF2_value = -999;
+    float ECF3_value = -999;
+    float ECF4_value = -999;
+    float ECF5_value = -999;
 
-    float result_ECF1_ungroomed = -999;
-    float result_ECF2_ungroomed = -999;
-    float result_ECF3_ungroomed = -999;
+    float ECF1_ungroomed_value = -999;
+    float ECF2_ungroomed_value = -999;
+    float ECF3_ungroomed_value = -999;
 
-    if(decorate) {
+    if( calculate ) {
 
       JetSubStructureUtils::EnergyCorrelator ECF1(1, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelator ECF2(2, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
       JetSubStructureUtils::EnergyCorrelator ECF3(3, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
 
-      result_ECF1 = ECF1.result(jet);
-      result_ECF2 = ECF2.result(jet);
-      result_ECF3 = ECF3.result(jet);
+      ECF1_value = ECF1.result(jet);
+      ECF2_value = ECF2.result(jet);
+      ECF3_value = ECF3.result(jet);
 
-      if(m_doC3) {
+      if( m_doC3 ) {
         JetSubStructureUtils::EnergyCorrelator ECF4(4, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
-        result_ECF4 = ECF4.result(jet);
+        ECF4_value = ECF4.result(jet);
       }
 
-      if(m_doC4) {
+      if( m_doC4 ) {
         JetSubStructureUtils::EnergyCorrelator ECF5(5, beta, JetSubStructureUtils::EnergyCorrelator::pt_R);
-        result_ECF5 = ECF5.result(jet);
+        ECF5_value = ECF5.result(jet);
       }
 
-      if(decorate_ungroomed) {
-        result_ECF1_ungroomed = ECF1.result(jet_ungroomed);
-        result_ECF2_ungroomed = ECF2.result(jet_ungroomed);
-        result_ECF3_ungroomed = ECF3.result(jet_ungroomed);
+      if( calculate_ungroomed ) {
+        ECF1_ungroomed_value = ECF1.result(jet_ungroomed);
+        ECF2_ungroomed_value = ECF2.result(jet_ungroomed);
+        ECF3_ungroomed_value = ECF3.result(jet_ungroomed);
       }
 
     }
 
-    injet.setAttribute(m_prefix+"ECF1"+suffix, result_ECF1);
-    injet.setAttribute(m_prefix+"ECF2"+suffix, result_ECF2);
-    injet.setAttribute(m_prefix+"ECF3"+suffix, result_ECF3);
-    injet.setAttribute(m_prefix+"ECF4"+suffix, result_ECF4);
-    injet.setAttribute(m_prefix+"ECF5"+suffix, result_ECF5);
+    (*moment.second.dec_ECF1)(injet) = ECF1_value;
+    (*moment.second.dec_ECF2)(injet) = ECF2_value;
+    (*moment.second.dec_ECF3)(injet) = ECF3_value;
+    (*moment.second.dec_ECF4)(injet) = ECF4_value;
+    (*moment.second.dec_ECF5)(injet) = ECF5_value;
 
-    injet.setAttribute(m_prefix+"ECF1_ungroomed"+suffix, result_ECF1_ungroomed);
-    injet.setAttribute(m_prefix+"ECF2_ungroomed"+suffix, result_ECF2_ungroomed);
-    injet.setAttribute(m_prefix+"ECF3_ungroomed"+suffix, result_ECF3_ungroomed);
+    (*moment.second.dec_ECF1_ungroomed)(injet) = ECF1_ungroomed_value;
+    (*moment.second.dec_ECF2_ungroomed)(injet) = ECF2_ungroomed_value;
+    (*moment.second.dec_ECF3_ungroomed)(injet) = ECF3_ungroomed_value;
 
   }
 
   return 0;
-}
 
+}
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
index a4c36cd9f4e7c392a3e370f40c601f6dcf1038f4..4e00035896ce04fbfdc8d8c5c519e64f025f903c 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessRatiosTool.cxx
@@ -12,170 +12,195 @@ NSubjettinessRatiosTool::NSubjettinessRatiosTool(std::string name) :
 }
 
 StatusCode NSubjettinessRatiosTool::initialize() {
-  // Add alpha = 1.0 by default
-  m_alphaVals.push_back(1.0);
 
-  // Clean up input list of alpha values
-  for(float alpha : m_rawAlphaVals) {
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+
+  /// Add alpha = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
+
+  /// Clean up input list of alpha values
+  for( float alpha : m_rawAlphaVals ) {
 
-    // Round to the nearest 0.1
+    /// Round to the nearest 0.1
     float alphaFix = round( alpha * 10.0 ) / 10.0;
-    if(std::abs(alpha-alphaFix) > 1.0e-5) ATH_MSG_DEBUG("alpha = " << alpha << " has been rounded to " << alphaFix);
+    if( std::abs(alpha-alphaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "alpha = " << alpha << " has been rounded to " << alphaFix );
 
-    // Skip negative values of alpha
-    if(alphaFix < 0.0) {
-      ATH_MSG_WARNING("alpha must be positive. Skipping alpha = " << alpha);
+    /// Skip negative values of alpha
+    if( alphaFix < 0.0 ) {
+      ATH_MSG_WARNING( "alpha must be positive. Skipping alpha = " << alpha );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_alphaVals.begin(), m_alphaVals.end(), alphaFix) == m_alphaVals.end() ) m_alphaVals.push_back(alphaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( alphaFix, moments_t(alphaFix, m_prefix) );
 
-  for(float alpha : m_alphaVals) {
-    ATH_MSG_DEBUG("Including alpha = " << alpha);
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including alpha = " << moment.first );
+  }
 
   return StatusCode::SUCCESS;
+
 }
 
 int NSubjettinessRatiosTool::modifyJet(xAOD::Jet &jet) const {
 
-  for(float alpha : m_alphaVals) {
-    std::string suffix = GetAlphaSuffix(alpha);
+  for( auto const& moment : m_moments ) {
+
+    std::string suffix = moment.second.suffix;
 
-    if (!jet.isAvailable<float>(m_prefix+"Tau1"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau2"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau3"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau4"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau1_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau2_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau3_wta"+suffix) ||
-        !jet.isAvailable<float>(m_prefix+"Tau4_wta"+suffix)) {
+    if( !moment.second.acc_Tau1->isAvailable(jet) ||
+        !moment.second.acc_Tau2->isAvailable(jet) ||
+        !moment.second.acc_Tau3->isAvailable(jet) ||
+        !moment.second.acc_Tau4->isAvailable(jet) ||
+        !moment.second.acc_Tau1_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau2_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau3_wta->isAvailable(jet) ||
+        !moment.second.acc_Tau4_wta->isAvailable(jet)) {
 
-      ATH_MSG_ERROR("Tau decorations for " << m_prefix << " with " << suffix << " are not all available. Exiting..");
+      ATH_MSG_ERROR( "Not all " << m_prefix << " Tau decorations with " << suffix << " are available. Exiting." );
       return 1;
+
     }
 
-    if (m_doDichroic) {
-      if (!jet.isAvailable<float>(m_prefix+"Tau2_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau3_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau4_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau2_wta_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau3_wta_ungroomed"+suffix) ||
-          !jet.isAvailable<float>(m_prefix+"Tau4_wta_ungroomed"+suffix)) {
+    if( m_doDichroic ) {
+
+      if( !moment.second.acc_Tau2_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau3_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau4_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau2_wta_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau3_wta_ungroomed->isAvailable(jet) ||
+          !moment.second.acc_Tau4_wta_ungroomed->isAvailable(jet)) {
 
-        ATH_MSG_ERROR("Ungroomed tau decorations for " << m_prefix << " with " << suffix << " are not all available. Exiting..");
+        ATH_MSG_ERROR( "Not all ungroomed " << m_prefix << " Tau decorations with " << suffix << " are available. Exiting." );
         return 1;
+
       }
+
     }
 
-    // Regular
-    float tau1 = jet.getAttribute<float>(m_prefix+"Tau1"+suffix);
-    float tau2 = jet.getAttribute<float>(m_prefix+"Tau2"+suffix);
-    float tau3 = jet.getAttribute<float>(m_prefix+"Tau3"+suffix);
-    float tau4 = jet.getAttribute<float>(m_prefix+"Tau4"+suffix);
+    /// Regular NSubjettiness
+    float Tau1 = (*moment.second.acc_Tau1)(jet);
+    float Tau2 = (*moment.second.acc_Tau2)(jet);
+    float Tau3 = (*moment.second.acc_Tau3)(jet);
+    float Tau4 = (*moment.second.acc_Tau4)(jet);
 
-    float tau2_ungroomed = -999.0;
-    float tau3_ungroomed = -999.0;
-    float tau4_ungroomed = -999.0;
+    float Tau2_ungroomed = -999.0;
+    float Tau3_ungroomed = -999.0;
+    float Tau4_ungroomed = -999.0;
 
-    if (m_doDichroic) {
-      tau2_ungroomed = jet.getAttribute<float>(m_prefix+"Tau2_ungroomed"+suffix);
-      tau3_ungroomed = jet.getAttribute<float>(m_prefix+"Tau3_ungroomed"+suffix);
-      tau4_ungroomed = jet.getAttribute<float>(m_prefix+"Tau4_ungroomed"+suffix);
+    if( m_doDichroic ) {
+      Tau2_ungroomed = (*moment.second.acc_Tau2_ungroomed)(jet);
+      Tau3_ungroomed = (*moment.second.acc_Tau3_ungroomed)(jet);
+      Tau4_ungroomed = (*moment.second.acc_Tau4_ungroomed)(jet);
     }
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau1 > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau21"+suffix, tau2/tau1);
-      if(tau2_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, tau2_ungroomed/tau1);
-      else
-        jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, -999.0);
-    }
-    else {
-      jet.setAttribute(m_prefix+"Tau21"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau21_dichroic"+suffix, -999.0);
-    }
+    float Tau21 = -999.0;
+    float Tau32 = -999.0;
+    float Tau42 = -999.0;
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau2 > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau32"+suffix, tau3/tau2);
-      jet.setAttribute(m_prefix+"Tau42"+suffix, tau4/tau2);
+    float Tau21_dichroic = -999.0;
+    float Tau32_dichroic = -999.0;
+    float Tau42_dichroic = -999.0;
 
-      if(tau3_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, tau3_ungroomed/tau2);
-      else
-        jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau1 > 1e-8 ) {
 
-      if(tau4_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, tau4_ungroomed/tau2);
-      else
-        jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, -999.0);
-    }
-    else {
-      jet.setAttribute(m_prefix+"Tau32"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42"+suffix, -999.0);
+      Tau21 = Tau2 / Tau1;
+
+      if( Tau2_ungroomed > 1e-8 ) {
+        Tau21_dichroic = Tau2_ungroomed/Tau1;
+      }
 
-      jet.setAttribute(m_prefix+"Tau32_dichroic"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_dichroic"+suffix, -999.0);
     }
 
-    float tau1_wta = jet.getAttribute<float>(m_prefix+"Tau1_wta"+suffix);
-    float tau2_wta = jet.getAttribute<float>(m_prefix+"Tau2_wta"+suffix);
-    float tau3_wta = jet.getAttribute<float>(m_prefix+"Tau3_wta"+suffix);
-    float tau4_wta = jet.getAttribute<float>(m_prefix+"Tau4_wta"+suffix);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau2 > 1e-8 ) {
 
-    float tau2_wta_ungroomed = -999.0;
-    float tau3_wta_ungroomed = -999.0;
-    float tau4_wta_ungroomed = -999.0;
+      Tau32 = Tau3 / Tau2;
+      Tau42 = Tau4 / Tau2;
 
-    if (m_doDichroic) {
-      tau2_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau2_wta_ungroomed"+suffix);
-      tau3_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau3_wta_ungroomed"+suffix);
-      tau4_wta_ungroomed = jet.getAttribute<float>(m_prefix+"Tau4_wta_ungroomed"+suffix);
-    }
+      if(Tau3_ungroomed > 1e-8) {
+        Tau32_dichroic = Tau3_ungroomed / Tau2;
+      }
+
+      if(Tau4_ungroomed > 1e-8) {
+        Tau42_dichroic = Tau4_ungroomed / Tau2;
+      }
 
-    // WTA
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau1_wta > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau21_wta"+suffix, tau2_wta/tau1_wta);
-      if(tau2_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, tau2_wta_ungroomed/tau1_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"Tau21_wta"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau21_wta_dichroic"+suffix, -999.0);
+
+    /// WTA NSubjettiness
+    float Tau1_wta = (*moment.second.acc_Tau1_wta)(jet);
+    float Tau2_wta = (*moment.second.acc_Tau2_wta)(jet);
+    float Tau3_wta = (*moment.second.acc_Tau3_wta)(jet);
+    float Tau4_wta = (*moment.second.acc_Tau4_wta)(jet);
+
+    float Tau2_wta_ungroomed = -999.0;
+    float Tau3_wta_ungroomed = -999.0;
+    float Tau4_wta_ungroomed = -999.0;
+
+    if( m_doDichroic ) {
+      Tau2_wta_ungroomed = (*moment.second.acc_Tau2_wta_ungroomed)(jet);
+      Tau3_wta_ungroomed = (*moment.second.acc_Tau3_wta_ungroomed)(jet);
+      Tau4_wta_ungroomed = (*moment.second.acc_Tau4_wta_ungroomed)(jet);
     }
 
-    //Prevent div-0 and check against default value (-999) of the decoration
-    if(tau2_wta > 1e-8) {
-      jet.setAttribute(m_prefix+"Tau32_wta"+suffix, tau3_wta/tau2_wta);
-      jet.setAttribute(m_prefix+"Tau42_wta"+suffix, tau4_wta/tau2_wta);
+    float Tau21_wta = -999.0;
+    float Tau32_wta = -999.0;
+    float Tau42_wta = -999.0;
+
+    float Tau21_wta_dichroic = -999.0;
+    float Tau32_wta_dichroic = -999.0;
+    float Tau42_wta_dichroic = -999.0;
 
-      if(tau3_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, tau3_wta_ungroomed/tau2_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau1_wta > 1e-8 ) {
+
+      Tau21_wta = Tau2_wta / Tau1_wta;
+
+      if( Tau2_wta_ungroomed > 1e-8 ) {
+        Tau21_wta_dichroic = Tau2_wta_ungroomed / Tau1_wta;
+      }
 
-      if(tau4_wta_ungroomed > 1e-8)
-        jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, tau4_wta_ungroomed/tau2_wta);
-      else
-        jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, -999.0);
     }
-    else {
-      jet.setAttribute(m_prefix+"Tau32_wta"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_wta"+suffix, -999.0);
 
-      jet.setAttribute(m_prefix+"Tau32_wta_dichroic"+suffix, -999.0);
-      jet.setAttribute(m_prefix+"Tau42_wta_dichroic"+suffix, -999.0);
+    /// Prevent div-0 and check against default value (-999) of the decoration
+    if( Tau2_wta > 1e-8 ) {
+
+      Tau32_wta = Tau3_wta / Tau2_wta;
+      Tau42_wta = Tau4_wta / Tau2_wta;
+
+      if( Tau3_wta_ungroomed > 1e-8 ) {
+        Tau32_wta_dichroic = Tau3_wta_ungroomed / Tau2_wta;
+      }
+
+      if(Tau4_wta_ungroomed > 1e-8) {
+        Tau42_wta_dichroic = Tau4_wta_ungroomed / Tau2_wta;
+      }
+
     }
+
+    (*moment.second.dec_Tau21)(jet) = Tau21;
+    (*moment.second.dec_Tau32)(jet) = Tau32;
+    (*moment.second.dec_Tau42)(jet) = Tau42;
+
+    (*moment.second.dec_Tau21_dichroic)(jet) = Tau21_dichroic;
+    (*moment.second.dec_Tau32_dichroic)(jet) = Tau32_dichroic;
+    (*moment.second.dec_Tau42_dichroic)(jet) = Tau42_dichroic;
+
+    (*moment.second.dec_Tau21_wta)(jet) = Tau21_wta;
+    (*moment.second.dec_Tau32_wta)(jet) = Tau32_wta;
+    (*moment.second.dec_Tau42_wta)(jet) = Tau42_wta;
+
+    (*moment.second.dec_Tau21_wta_dichroic)(jet) = Tau21_wta_dichroic;
+    (*moment.second.dec_Tau32_wta_dichroic)(jet) = Tau32_wta_dichroic;
+    (*moment.second.dec_Tau42_wta_dichroic)(jet) = Tau42_wta_dichroic;
+
   }
 
   return 0;
+
 }
diff --git a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
index b71d2b1d160703d5420f72dbd7d7dca0bc193faf..3999d0d7909192a2497bcbff51755a7ecf32c304 100644
--- a/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
+++ b/Reconstruction/Jet/JetSubStructureMomentTools/Root/NSubjettinessTool.cxx
@@ -9,42 +9,54 @@
 NSubjettinessTool::NSubjettinessTool(std::string name) : 
   JetSubStructureMomentToolsBase(name)
 {
-  declareProperty("Alpha", m_Alpha = 1.0);
-  declareProperty("AlphaList", m_rawAlphaVals = {});
+  declareProperty("Alpha",      m_Alpha = 1.0);
+  declareProperty("AlphaList",  m_rawAlphaVals = {});
   declareProperty("DoDichroic", m_doDichroic = false);
 }
 
 StatusCode NSubjettinessTool::initialize() {
-  // Add alpha = 1.0 by default
-  m_alphaVals.push_back(1.0);
+  
+  /// Call base class initialize to fix up m_prefix
+  ATH_CHECK( JetSubStructureMomentToolsBase::initialize() );
+
+  /// Add alpha = 1.0 by default
+  m_moments.emplace( 1.0, moments_t(1.0, m_prefix) );
+
+  /// Add alpha = m_Alpha by default to keep backwards compatibility
+  if( std::abs(m_Alpha-1.0) > 1.0e-5 ) {
+    
+    /// Give warning about deprecation
+    ATH_MSG_WARNING( "The Alpha property is deprecated, please use the AlphaList property to provide a list of values" );
 
-  // Add alpha = m_Alpha by default to keep backwards compatibility
-  if( std::abs(m_Alpha-1.0) > 1.0e-5 ) m_alphaVals.push_back(m_Alpha);
+    /// Use m_Alpha to not break analysis code
+    m_moments.emplace( m_Alpha, moments_t(m_Alpha, m_prefix) );
+  
+  }
 
-  // Clean up input list of alpha values
-  for(float alpha : m_rawAlphaVals) {
+  /// Clean up input list of alpha values
+  for( float alpha : m_rawAlphaVals ) {
     
-    // Round to the nearest 0.1
+    /// Round to the nearest 0.1
     float alphaFix = round( alpha * 10.0 ) / 10.0;
-    if(std::abs(alpha-alphaFix) > 1.0e-5) ATH_MSG_DEBUG("alpha = " << alpha << " has been rounded to " << alphaFix);
+    if( std::abs(alpha-alphaFix) > 1.0e-5 ) ATH_MSG_DEBUG( "alpha = " << alpha << " has been rounded to " << alphaFix );
 
-    // Skip negative values of alpha
-    if(alphaFix < 0.0) {
-      ATH_MSG_WARNING("alpha must be positive. Skipping alpha = " << alpha);
+    /// Skip negative values of alpha
+    if( alphaFix < 0.0 ) {
+      ATH_MSG_WARNING( "alpha must be positive. Skipping alpha = " << alpha );
       continue;
     }
 
-    // Only store value if it is not already in the list
-    if( std::find(m_alphaVals.begin(), m_alphaVals.end(), alphaFix) == m_alphaVals.end() ) m_alphaVals.push_back(alphaFix);
-  }
+    /// Store value. std::map::emplace prevents duplicate entries
+    m_moments.emplace( alphaFix, moments_t(alphaFix, m_prefix) );
 
-  for(float alpha : m_alphaVals) {
-    ATH_MSG_DEBUG("Including alpha = " << alpha);
   }
 
-  ATH_CHECK(JetSubStructureMomentToolsBase::initialize());
+  for( auto const& moment : m_moments ) {
+    ATH_MSG_DEBUG( "Including alpha = " << moment.first );
+  }
 
   return StatusCode::SUCCESS;
+
 }
 
 int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
@@ -52,20 +64,25 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
   fastjet::PseudoJet jet;
   fastjet::PseudoJet jet_ungroomed;
 
-  bool decorate = SetupDecoration(jet,injet);
-  bool decorate_ungroomed = false;
-  if(m_doDichroic) {
-    // Get parent jet here and replace injet
-    ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
+  /// Bool to decide whether calculation should be performed
+  bool calculate = SetupDecoration(jet,injet);
+
+  /// Bool to decide if ungroomed jet moments should be calculated
+  bool calculate_ungroomed = false;
   
-    // Return error is parent element link is broken
-    if(!parentLink.isValid()) {
-      ATH_MSG_ERROR("Parent element link is not valid. Aborting");
+  if( m_doDichroic ) {
+
+    /// Get parent jet
+    ElementLink<xAOD::JetContainer> parentLink = injet.auxdata<ElementLink<xAOD::JetContainer> >("Parent");
+
+    /// Return error is parent element link is broken
+    if( !parentLink.isValid() ) {
+      ATH_MSG_ERROR( "Parent element link is not valid. Aborting" );
       return 1;
     }
 
     const xAOD::Jet* parentJet = *(parentLink);
-    decorate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
+    calculate_ungroomed = SetupDecoration(jet_ungroomed,*parentJet);
   }
 
   // Supress a warning about undefined behavior in the fastjet
@@ -76,27 +93,35 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
   std::call_once (oflag, CxxUtils::ubsan_suppress,
                   []() { fastjet::contrib::WTA_KT_Axes x; });
 
-  for(float alpha : m_alphaVals) {
-
-    if(alpha < 0.0) {
-      ATH_MSG_WARNING("Negative alpha values are not supported. Skipping " << alpha);
-      continue;
-    }
+  for( auto const& moment : m_moments ) {
 
-    std::string suffix = GetAlphaSuffix(alpha);
+    float alpha = moment.first;
 
+    /// This needs to be redone for each jet since it depends on the size parameter
     fastjet::contrib::NormalizedCutoffMeasure normalized_measure(alpha, injet.getSizeParameter(), 1000000);
 
-    // Groomed jet moments
-    float Tau1_value = -999, Tau2_value = -999, Tau3_value = -999, Tau4_value = -999,
-          Tau1_wta_value = -999, Tau2_wta_value = -999, Tau3_wta_value = -999, Tau4_wta_value = -999;
+    float Tau1_value = -999;
+    float Tau2_value = -999;
+    float Tau3_value = -999;
+    float Tau4_value = -999;
+    
+    float Tau2_ungroomed_value = -999;
+    float Tau3_ungroomed_value = -999;
+    float Tau4_ungroomed_value = -999;
+    
+    float Tau1_wta_value = -999;
+    float Tau2_wta_value = -999;
+    float Tau3_wta_value = -999;
+    float Tau4_wta_value = -999;
 
-    // Ungroomed jet moments
-    float Tau2_ungroomed_value = -999, Tau3_ungroomed_value = -999, Tau4_ungroomed_value = -999,
-          Tau2_wta_ungroomed_value = -999, Tau3_wta_ungroomed_value = -999, Tau4_wta_ungroomed_value = -999;
+    float Tau2_wta_ungroomed_value = -999;
+    float Tau3_wta_ungroomed_value = -999;
+    float Tau4_wta_ungroomed_value = -999;
 
-    if (decorate) {
+    if( calculate ) {
 
+      /// These calculators need to be created for each jet due to
+      /// the jet size parameter dependence in the normalized measure
       fastjet::contrib::KT_Axes kt_axes;
       JetSubStructureUtils::Nsubjettiness tau1(1, kt_axes, normalized_measure);
       JetSubStructureUtils::Nsubjettiness tau2(2, kt_axes, normalized_measure);
@@ -108,12 +133,14 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
       Tau3_value = tau3.result(jet);
       Tau4_value = tau4.result(jet);
 
-      if(decorate_ungroomed) {
+      if( calculate_ungroomed ) {
         Tau2_ungroomed_value = tau2.result(jet_ungroomed);
         Tau3_ungroomed_value = tau3.result(jet_ungroomed);
         Tau4_ungroomed_value = tau4.result(jet_ungroomed);
       }
 
+      /// These calculators need to be created for each jet due to
+      /// the jet size parameter dependence in the normalized measure
       fastjet::contrib::WTA_KT_Axes wta_kt_axes;
       JetSubStructureUtils::Nsubjettiness tau1_wta(1, wta_kt_axes, normalized_measure);
       JetSubStructureUtils::Nsubjettiness tau2_wta(2, wta_kt_axes, normalized_measure);
@@ -125,7 +152,7 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
       Tau3_wta_value = tau3_wta.result(jet);
       Tau4_wta_value = tau4_wta.result(jet);
 
-      if(decorate_ungroomed) {
+      if( calculate_ungroomed ) {
         Tau2_wta_ungroomed_value = tau2_wta.result(jet_ungroomed);
         Tau3_wta_ungroomed_value = tau3_wta.result(jet_ungroomed);
         Tau4_wta_ungroomed_value = tau4_wta.result(jet_ungroomed);
@@ -133,27 +160,26 @@ int NSubjettinessTool::modifyJet(xAOD::Jet &injet) const {
 
     }
 
-    // Groomed jet moments
-    injet.setAttribute(m_prefix+"Tau1"+suffix, Tau1_value);
-    injet.setAttribute(m_prefix+"Tau2"+suffix, Tau2_value);
-    injet.setAttribute(m_prefix+"Tau3"+suffix, Tau3_value);
-    injet.setAttribute(m_prefix+"Tau4"+suffix, Tau4_value);
-
-    injet.setAttribute(m_prefix+"Tau1_wta"+suffix, Tau1_wta_value);
-    injet.setAttribute(m_prefix+"Tau2_wta"+suffix, Tau2_wta_value);
-    injet.setAttribute(m_prefix+"Tau3_wta"+suffix, Tau3_wta_value);
-    injet.setAttribute(m_prefix+"Tau4_wta"+suffix, Tau4_wta_value);
+    (*moment.second.dec_Tau1)(injet) = Tau1_value;
+    (*moment.second.dec_Tau2)(injet) = Tau2_value;
+    (*moment.second.dec_Tau3)(injet) = Tau3_value;
+    (*moment.second.dec_Tau4)(injet) = Tau4_value;
+    
+    (*moment.second.dec_Tau2_ungroomed)(injet) = Tau2_ungroomed_value;
+    (*moment.second.dec_Tau3_ungroomed)(injet) = Tau3_ungroomed_value;
+    (*moment.second.dec_Tau4_ungroomed)(injet) = Tau4_ungroomed_value;
 
-    // Ungroomed jet moments
-    injet.setAttribute(m_prefix+"Tau2_ungroomed"+suffix, Tau2_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau3_ungroomed"+suffix, Tau3_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau4_ungroomed"+suffix, Tau4_ungroomed_value);
+    (*moment.second.dec_Tau1_wta)(injet) = Tau1_wta_value;
+    (*moment.second.dec_Tau2_wta)(injet) = Tau2_wta_value;
+    (*moment.second.dec_Tau3_wta)(injet) = Tau3_wta_value;
+    (*moment.second.dec_Tau4_wta)(injet) = Tau4_wta_value;
 
-    injet.setAttribute(m_prefix+"Tau2_wta_ungroomed"+suffix, Tau2_wta_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau3_wta_ungroomed"+suffix, Tau3_wta_ungroomed_value);
-    injet.setAttribute(m_prefix+"Tau4_wta_ungroomed"+suffix, Tau4_wta_ungroomed_value);
+    (*moment.second.dec_Tau2_wta_ungroomed)(injet) = Tau2_wta_ungroomed_value;
+    (*moment.second.dec_Tau3_wta_ungroomed)(injet) = Tau3_wta_ungroomed_value;
+    (*moment.second.dec_Tau4_wta_ungroomed)(injet) = Tau4_wta_ungroomed_value;
 
   }
 
   return 0;
+
 }