From 66aed4fba32d0378d03f252483fde4f0bdd92068 Mon Sep 17 00:00:00 2001
From: camolezi <camolezi@usp.br>
Date: Wed, 17 Jun 2020 16:00:11 +0200
Subject: [PATCH 1/9] Replaced boost::ptr_vector for std::vector

---
 .../interface/SimpleFlatTableProducer.h       | 40 ++++++++++---------
 .../plugins/GlobalVariablesTableProducer.cc   | 26 +++++++-----
 2 files changed, 36 insertions(+), 30 deletions(-)

diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
index 3da6bd5700bc3..bca33c8809793 100644
--- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
+++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
@@ -8,8 +8,8 @@
 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
 #include "CommonTools/Utils/interface/StringObjectFunction.h"
 
+#include <memory>
 #include <vector>
-#include <boost/ptr_container/ptr_vector.hpp>
 
 template <typename T, typename TProd>
 class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
@@ -24,13 +24,13 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
       const std::string &type = varPSet.getParameter<std::string>("type");
       if (type == "int")
-        vars_.push_back(new IntVar(vname, nanoaod::FlatTable::IntColumn, varPSet));
+        vars_.push_back(std::make_unique<IntVar>(vname, nanoaod::FlatTable::IntColumn, varPSet));
       else if (type == "float")
-        vars_.push_back(new FloatVar(vname, nanoaod::FlatTable::FloatColumn, varPSet));
+        vars_.push_back(std::make_unique<FloatVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet));
       else if (type == "uint8")
-        vars_.push_back(new UInt8Var(vname, nanoaod::FlatTable::UInt8Column, varPSet));
+        vars_.push_back(std::make_unique<UInt8Var>(vname, nanoaod::FlatTable::UInt8Column, varPSet));
       else if (type == "bool")
-        vars_.push_back(new BoolVar(vname, nanoaod::FlatTable::BoolColumn, varPSet));
+        vars_.push_back(std::make_unique<BoolVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet));
       else
         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
     }
@@ -111,7 +111,7 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
   typedef FuncVariable<StringObjectFunction<T>, float> FloatVar;
   typedef FuncVariable<StringObjectFunction<T>, uint8_t> UInt8Var;
   typedef FuncVariable<StringCutObjectSelector<T>, uint8_t> BoolVar;
-  boost::ptr_vector<Variable> vars_;
+  std::vector<std::unique_ptr<Variable>> vars_;
 };
 
 template <typename T>
@@ -131,18 +131,20 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
         const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
         const std::string &type = varPSet.getParameter<std::string>("type");
         if (type == "int")
-          extvars_.push_back(new IntExtVar(vname, nanoaod::FlatTable::IntColumn, varPSet, this->consumesCollector()));
-        else if (type == "float")
           extvars_.push_back(
-              new FloatExtVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
+              std::make_unique<IntExtVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, this->consumesCollector()));
+        else if (type == "float")
+          extvars_.push_back(std::make_unique<FloatExtVar>(
+              vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
         else if (type == "double")
-          extvars_.push_back(
-              new DoubleExtVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<DoubleExtVar>(
+              vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
         else if (type == "uint8")
-          extvars_.push_back(
-              new UInt8ExtVar(vname, nanoaod::FlatTable::UInt8Column, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<UInt8ExtVar>(
+              vname, nanoaod::FlatTable::UInt8Column, varPSet, this->consumesCollector()));
         else if (type == "bool")
-          extvars_.push_back(new BoolExtVar(vname, nanoaod::FlatTable::BoolColumn, varPSet, this->consumesCollector()));
+          extvars_.push_back(
+              std::make_unique<BoolExtVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet, this->consumesCollector()));
         else
           throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
       }
@@ -174,9 +176,9 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
     }
     auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, singleton_, this->extension_);
     for (const auto &var : this->vars_)
-      var.fill(selobjs, *out);
+      var->fill(selobjs, *out);
     for (const auto &var : this->extvars_)
-      var.fill(iEvent, selptrs, *out);
+      var->fill(iEvent, selptrs, *out);
     return out;
   }
 
@@ -218,7 +220,7 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
   typedef ValueMapVariable<double, float> DoubleExtVar;
   typedef ValueMapVariable<bool, uint8_t> BoolExtVar;
   typedef ValueMapVariable<int, uint8_t> UInt8ExtVar;
-  boost::ptr_vector<ExtVariable> extvars_;
+  std::vector<std::unique_ptr<ExtVariable>> extvars_;
 };
 
 template <typename T>
@@ -232,7 +234,7 @@ class EventSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBase
     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
     std::vector<const T *> selobjs(1, prod.product());
     for (const auto &var : this->vars_)
-      var.fill(selobjs, *out);
+      var->fill(selobjs, *out);
     return out;
   }
 };
@@ -250,7 +252,7 @@ class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T,
     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
     std::vector<const T *> selobjs(1, &(*prod)[0]);
     for (const auto &var : this->vars_)
-      var.fill(selobjs, *out);
+      var->fill(selobjs, *out);
     return out;
   }
 };
diff --git a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
index 80ee9e17cdb63..9271a26422948 100644
--- a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
@@ -4,9 +4,9 @@
 #include "FWCore/Framework/interface/ConsumesCollector.h"
 #include "DataFormats/Candidate/interface/Candidate.h"
 
+#include <memory>
 #include <utility>
 #include <vector>
-#include <boost/ptr_container/ptr_vector.hpp>
 
 class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
 public:
@@ -16,20 +16,24 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
       const auto& varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
       const std::string& type = varPSet.getParameter<std::string>("type");
       if (type == "int")
-        vars_.push_back(new IntVar(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<IntVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
       else if (type == "float")
-        vars_.push_back(new FloatVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+        vars_.push_back(
+            std::make_unique<FloatVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
       else if (type == "double")
-        vars_.push_back(new DoubleVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+        vars_.push_back(
+            std::make_unique<DoubleVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
       else if (type == "bool")
-        vars_.push_back(new BoolVar(vname, nanoaod::FlatTable::BoolColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<BoolVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet, consumesCollector()));
       else if (type == "candidatescalarsum")
-        vars_.push_back(
-            new CandidateScalarSumVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<CandidateScalarSumVar>(
+            vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
       else if (type == "candidatesize")
-        vars_.push_back(new CandidateSizeVar(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
+        vars_.push_back(
+            std::make_unique<CandidateSizeVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
       else if (type == "candidatesummass")
-        vars_.push_back(new CandidateSumMassVar(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<CandidateSumMassVar>(
+            vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
       else
         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
     }
@@ -43,7 +47,7 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
     auto out = std::make_unique<nanoaod::FlatTable>(1, "", true);
 
     for (const auto& var : vars_)
-      var.fill(iEvent, *out);
+      var->fill(iEvent, *out);
 
     iEvent.put(std::move(out));
   }
@@ -157,7 +161,7 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
       CandidateScalarSumVar;
   typedef VariableT<edm::View<reco::Candidate>, float, MassSum<float, edm::View<reco::Candidate>>> CandidateSumMassVar;
   typedef VariableT<edm::View<reco::Candidate>, int, Size<edm::View<reco::Candidate>>> CandidateSizeVar;
-  boost::ptr_vector<Variable> vars_;
+  std::vector<std::unique_ptr<Variable>> vars_;
 };
 
 #include "FWCore/Framework/interface/MakerMacros.h"

From ec6e81ab2899510d0169b260642d75c4a342e37b Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Mon, 23 Sep 2019 23:33:09 +0200
Subject: [PATCH 2/9] don't handle column types redundantly anymore

---
 DataFormats/NanoAOD/interface/FlatTable.h     |  76 ++++------
 DataFormats/NanoAOD/src/FlatTable.cc          |  10 +-
 .../interface/SimpleFlatTableProducer.h       |  51 +++----
 .../NanoAOD/plugins/BTagSFProducer.cc         |   5 +-
 .../plugins/CandMCMatchTableProducer.cc       |   8 +-
 .../plugins/EnergyRingsTableProducer.cc       | 135 +++++-------------
 .../plugins/GenJetFlavourTableProducer.cc     |   5 +-
 .../plugins/GenWeightsTableProducer.cc        |  31 ++--
 .../plugins/GlobalVariablesTableProducer.cc   |  33 ++---
 .../NanoAOD/plugins/LHETablesProducer.cc      |  44 +++---
 .../NanoAOD/plugins/MuonIDTableProducer.cc    |  15 +-
 .../NanoAOD/plugins/NPUTablesProducer.cc      |  15 +-
 .../plugins/NanoAODBaseCrossCleaner.cc        |  10 +-
 .../plugins/NativeArrayTableProducer.cc       |  12 +-
 .../plugins/TriggerObjectTableProducer.cc     |  22 ++-
 .../NanoAOD/plugins/VertexTableProducer.cc    |  43 ++----
 16 files changed, 185 insertions(+), 330 deletions(-)

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index 9df088e25a786..dd8a9cbd0c9e6 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -10,6 +10,8 @@
 #include <vector>
 #include <string>
 
+#include <type_traits>
+
 namespace nanoaod {
 
   namespace flatTableHelper {
@@ -104,40 +106,43 @@ namespace nanoaod {
     };
     RowView row(unsigned int row) const { return RowView(*this, row); }
 
-    template <typename T, typename C = std::vector<T>>
-    void addColumn(const std::string &name,
-                   const C &values,
-                   const std::string &docString,
-                   ColumnType type = defaultColumnType<T>(),
-                   int mantissaBits = -1) {
+    template <typename T, typename C>
+    void addColumn(const std::string &name, const C &values, const std::string &docString, int mantissaBits = -1) {
       if (columnIndex(name) != -1)
         throw cms::Exception("LogicError", "Duplicated column: " + name);
       if (values.size() != size())
         throw cms::Exception("LogicError", "Mismatched size for " + name);
-      check_type<T>(type);  // throws if type is wrong
-      auto &vec = bigVector<T>();
-      columns_.emplace_back(name, docString, type, vec.size());
-      vec.insert(vec.end(), values.begin(), values.end());
-      if (type == FloatColumn) {
-        flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).bulk(columnData<T>(columns_.size() - 1));
+      if constexpr (std::is_same<T, bool>()) {
+        columns_.emplace_back(name, docString, ColumnType::BoolColumn, uint8s_.size());
+        uint8s_.insert(uint8s_.end(), values.begin(), values.end());
+      } else if constexpr (std::is_same<T, float>()) {
+        columns_.emplace_back(name, docString, ColumnType::FloatColumn, floats_.size());
+        floats_.insert(floats_.end(), values.begin(), values.end());
+        flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).bulk(columnData<float>(columns_.size() - 1));
+      } else {
+        ColumnType type = defaultColumnType<T>();
+        auto &vec = bigVector<T>();
+        columns_.emplace_back(name, docString, type, vec.size());
+        vec.insert(vec.end(), values.begin(), values.end());
       }
     }
+
     template <typename T, typename C>
-    void addColumnValue(const std::string &name,
-                        const C &value,
-                        const std::string &docString,
-                        ColumnType type = defaultColumnType<T>(),
-                        int mantissaBits = -1) {
+    void addColumnValue(const std::string &name, const C &value, const std::string &docString, int mantissaBits = -1) {
       if (!singleton())
         throw cms::Exception("LogicError", "addColumnValue works only for singleton tables");
       if (columnIndex(name) != -1)
         throw cms::Exception("LogicError", "Duplicated column: " + name);
-      check_type<T>(type);  // throws if type is wrong
-      auto &vec = bigVector<T>();
-      columns_.emplace_back(name, docString, type, vec.size());
-      if (type == FloatColumn) {
-        vec.push_back(flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).one(value));
+      if constexpr (std::is_same<T, bool>()) {
+        columns_.emplace_back(name, docString, ColumnType::BoolColumn, uint8s_.size());
+        uint8s_.push_back(value);
+      } else if constexpr (std::is_same<T, float>()) {
+        columns_.emplace_back(name, docString, ColumnType::FloatColumn, floats_.size());
+        floats_.push_back(flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).one(value));
       } else {
+        ColumnType type = defaultColumnType<T>();
+        auto &vec = bigVector<T>();
+        columns_.emplace_back(name, docString, type, vec.size());
         vec.push_back(value);
       }
     }
@@ -146,6 +151,10 @@ namespace nanoaod {
 
     template <typename T>
     static ColumnType defaultColumnType() {
+      if constexpr (std::is_same<T, int>())
+        return ColumnType::IntColumn;
+      if constexpr (std::is_same<T, uint8_t>())
+        return ColumnType::UInt8Column;
       throw cms::Exception("unsupported type");
     }
 
@@ -163,13 +172,11 @@ namespace nanoaod {
     template <typename T>
     typename std::vector<T>::const_iterator beginData(unsigned int column) const {
       const Column &col = columns_[column];
-      check_type<T>(col.type);  // throws if type is wrong
       return bigVector<T>().begin() + col.firstIndex;
     }
     template <typename T>
     typename std::vector<T>::iterator beginData(unsigned int column) {
       const Column &col = columns_[column];
-      check_type<T>(col.type);  // throws if type is wrong
       return bigVector<T>().begin() + col.firstIndex;
     }
 
@@ -189,29 +196,8 @@ namespace nanoaod {
     std::vector<float> floats_;
     std::vector<int> ints_;
     std::vector<uint8_t> uint8s_;
-
-    template <typename T>
-    static void check_type(FlatTable::ColumnType type) {
-      throw cms::Exception("unsupported type");
-    }
   };
 
-  template <>
-  inline void FlatTable::check_type<float>(FlatTable::ColumnType type) {
-    if (type != FlatTable::FloatColumn)
-      throw cms::Exception("mismatched type");
-  }
-  template <>
-  inline void FlatTable::check_type<int>(FlatTable::ColumnType type) {
-    if (type != FlatTable::IntColumn)
-      throw cms::Exception("mismatched type");
-  }
-  template <>
-  inline void FlatTable::check_type<uint8_t>(FlatTable::ColumnType type) {
-    if (type != FlatTable::UInt8Column && type != FlatTable::BoolColumn)
-      throw cms::Exception("mismatched type");
-  }
-
   template <>
   inline const std::vector<float> &FlatTable::bigVector<float>() const {
     return floats_;
diff --git a/DataFormats/NanoAOD/src/FlatTable.cc b/DataFormats/NanoAOD/src/FlatTable.cc
index 1e057859b2fb1..0e3a85827df2d 100644
--- a/DataFormats/NanoAOD/src/FlatTable.cc
+++ b/DataFormats/NanoAOD/src/FlatTable.cc
@@ -14,14 +14,16 @@ void nanoaod::FlatTable::addExtension(const nanoaod::FlatTable& other) {
   for (unsigned int i = 0, n = other.nColumns(); i < n; ++i) {
     switch (other.columnType(i)) {
       case FloatColumn:
-        addColumn<float>(other.columnName(i), other.columnData<float>(i), other.columnDoc(i), other.columnType(i));
+        addColumn<float>(other.columnName(i), other.columnData<float>(i), other.columnDoc(i));
         break;
       case IntColumn:
-        addColumn<int>(other.columnName(i), other.columnData<int>(i), other.columnDoc(i), other.columnType(i));
+        addColumn<int>(other.columnName(i), other.columnData<int>(i), other.columnDoc(i));
+        break;
+      case BoolColumn:
+        addColumn<bool>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
         break;
-      case BoolColumn:  // as UInt8
       case UInt8Column:
-        addColumn<uint8_t>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i), other.columnType(i));
+        addColumn<uint8_t>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
         break;
     }
   }
diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
index bca33c8809793..f3c8ef7ceefb4 100644
--- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
+++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
@@ -24,13 +24,13 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
       const std::string &type = varPSet.getParameter<std::string>("type");
       if (type == "int")
-        vars_.push_back(std::make_unique<IntVar>(vname, nanoaod::FlatTable::IntColumn, varPSet));
+        vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
       else if (type == "float")
-        vars_.push_back(std::make_unique<FloatVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet));
+        vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
       else if (type == "uint8")
-        vars_.push_back(std::make_unique<UInt8Var>(vname, nanoaod::FlatTable::UInt8Column, varPSet));
+        vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
       else if (type == "bool")
-        vars_.push_back(std::make_unique<BoolVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet));
+        vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
       else
         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
     }
@@ -62,32 +62,30 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
 
   class VariableBase {
   public:
-    VariableBase(const std::string &aname, nanoaod::FlatTable::ColumnType atype, const edm::ParameterSet &cfg)
+    VariableBase(const std::string &aname, const edm::ParameterSet &cfg)
         : name_(aname),
           doc_(cfg.getParameter<std::string>("doc")),
-          type_(atype),
           precision_(cfg.existsAs<int>("precision") ? cfg.getParameter<int>("precision")
                                                     : (cfg.existsAs<std::string>("precision") ? -2 : -1)) {}
     virtual ~VariableBase() {}
     const std::string &name() const { return name_; }
-    const nanoaod::FlatTable::ColumnType &type() const { return type_; }
 
   protected:
     std::string name_, doc_;
-    nanoaod::FlatTable::ColumnType type_;
     int precision_;
   };
+
   class Variable : public VariableBase {
   public:
-    Variable(const std::string &aname, nanoaod::FlatTable::ColumnType atype, const edm::ParameterSet &cfg)
-        : VariableBase(aname, atype, cfg) {}
+    Variable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
     virtual void fill(std::vector<const T *> selobjs, nanoaod::FlatTable &out) const = 0;
   };
+
   template <typename StringFunctor, typename ValType>
   class FuncVariable : public Variable {
   public:
-    FuncVariable(const std::string &aname, nanoaod::FlatTable::ColumnType atype, const edm::ParameterSet &cfg)
-        : Variable(aname, atype, cfg),
+    FuncVariable(const std::string &aname, const edm::ParameterSet &cfg)
+        : Variable(aname, cfg),
           func_(cfg.getParameter<std::string>("expr"), true),
           precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
                          true) {}
@@ -100,7 +98,7 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
         } else
           vals[i] = func_(*selobjs[i]);
       }
-      out.template addColumn<ValType>(this->name_, vals, this->doc_, this->type_, this->precision_);
+      out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
     }
 
   protected:
@@ -110,7 +108,7 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
   typedef FuncVariable<StringObjectFunction<T>, int> IntVar;
   typedef FuncVariable<StringObjectFunction<T>, float> FloatVar;
   typedef FuncVariable<StringObjectFunction<T>, uint8_t> UInt8Var;
-  typedef FuncVariable<StringCutObjectSelector<T>, uint8_t> BoolVar;
+  typedef FuncVariable<StringCutObjectSelector<T>, bool> BoolVar;
   std::vector<std::unique_ptr<Variable>> vars_;
 };
 
@@ -132,19 +130,19 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
         const std::string &type = varPSet.getParameter<std::string>("type");
         if (type == "int")
           extvars_.push_back(
-              std::make_unique<IntExtVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, this->consumesCollector()));
+              std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector()));
         else if (type == "float")
           extvars_.push_back(std::make_unique<FloatExtVar>(
-              vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
+              vname, varPSet, this->consumesCollector()));
         else if (type == "double")
           extvars_.push_back(std::make_unique<DoubleExtVar>(
-              vname, nanoaod::FlatTable::FloatColumn, varPSet, this->consumesCollector()));
+              vname, varPSet, this->consumesCollector()));
         else if (type == "uint8")
           extvars_.push_back(std::make_unique<UInt8ExtVar>(
-              vname, nanoaod::FlatTable::UInt8Column, varPSet, this->consumesCollector()));
+              vname, varPSet, this->consumesCollector()));
         else if (type == "bool")
           extvars_.push_back(
-              std::make_unique<BoolExtVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet, this->consumesCollector()));
+              std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector()));
         else
           throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
       }
@@ -189,19 +187,14 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
 
   class ExtVariable : public base::VariableBase {
   public:
-    ExtVariable(const std::string &aname, nanoaod::FlatTable::ColumnType atype, const edm::ParameterSet &cfg)
-        : base::VariableBase(aname, atype, cfg) {}
+    ExtVariable(const std::string &aname, const edm::ParameterSet &cfg) : base::VariableBase(aname, cfg) {}
     virtual void fill(const edm::Event &iEvent, std::vector<edm::Ptr<T>> selptrs, nanoaod::FlatTable &out) const = 0;
   };
   template <typename TIn, typename ValType = TIn>
   class ValueMapVariable : public ExtVariable {
   public:
-    ValueMapVariable(const std::string &aname,
-                     nanoaod::FlatTable::ColumnType atype,
-                     const edm::ParameterSet &cfg,
-                     edm::ConsumesCollector &&cc)
-        : ExtVariable(aname, atype, cfg),
-          token_(cc.consumes<edm::ValueMap<TIn>>(cfg.getParameter<edm::InputTag>("src"))) {}
+    ValueMapVariable(const std::string &aname, const edm::ParameterSet &cfg, edm::ConsumesCollector &&cc)
+        : ExtVariable(aname, cfg), token_(cc.consumes<edm::ValueMap<TIn>>(cfg.getParameter<edm::InputTag>("src"))) {}
     void fill(const edm::Event &iEvent, std::vector<edm::Ptr<T>> selptrs, nanoaod::FlatTable &out) const override {
       edm::Handle<edm::ValueMap<TIn>> vmap;
       iEvent.getByToken(token_, vmap);
@@ -209,7 +202,7 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
       for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
         vals[i] = (*vmap)[selptrs[i]];
       }
-      out.template addColumn<ValType>(this->name_, vals, this->doc_, this->type_, this->precision_);
+      out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
     }
 
   protected:
@@ -218,7 +211,7 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
   typedef ValueMapVariable<int> IntExtVar;
   typedef ValueMapVariable<float> FloatExtVar;
   typedef ValueMapVariable<double, float> DoubleExtVar;
-  typedef ValueMapVariable<bool, uint8_t> BoolExtVar;
+  typedef ValueMapVariable<bool> BoolExtVar;
   typedef ValueMapVariable<int, uint8_t> UInt8ExtVar;
   std::vector<std::unique_ptr<ExtVariable>> extvars_;
 };
diff --git a/PhysicsTools/NanoAOD/plugins/BTagSFProducer.cc b/PhysicsTools/NanoAOD/plugins/BTagSFProducer.cc
index 448461540e0af..22ffb347eae5c 100644
--- a/PhysicsTools/NanoAOD/plugins/BTagSFProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/BTagSFProducer.cc
@@ -227,10 +227,7 @@ void BTagSFProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup)
         EventWt *= SF;
       }
 
-      out->addColumnValue<float>(discShortNames_[iDisc],
-                                 EventWt,
-                                 "b-tag event weight for " + discShortNames_[iDisc],
-                                 nanoaod::FlatTable::FloatColumn);
+      out->addColumnValue<float>(discShortNames_[iDisc], EventWt, "b-tag event weight for " + discShortNames_[iDisc]);
     }
   }
 
diff --git a/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc b/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc
index ec8efa17b93e7..6a947bed593d6 100644
--- a/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/CandMCMatchTableProducer.cc
@@ -138,12 +138,8 @@ class CandMCMatchTableProducer : public edm::global::EDProducer<> {
       };
     }
 
-    tab->addColumn<int>(
-        branchName_ + "Idx", key, "Index into genParticle list for " + doc_, nanoaod::FlatTable::IntColumn);
-    tab->addColumn<uint8_t>(branchName_ + "Flav",
-                            flav,
-                            "Flavour of genParticle for " + doc_ + ": " + flavDoc_,
-                            nanoaod::FlatTable::UInt8Column);
+    tab->addColumn<int>(branchName_ + "Idx", key, "Index into genParticle list for " + doc_);
+    tab->addColumn<uint8_t>(branchName_ + "Flav", flav, "Flavour of genParticle for " + doc_ + ": " + flavDoc_);
 
     iEvent.put(std::move(tab));
   }
diff --git a/PhysicsTools/NanoAOD/plugins/EnergyRingsTableProducer.cc b/PhysicsTools/NanoAOD/plugins/EnergyRingsTableProducer.cc
index c2c5f5e3ab3f1..8cdde2266453b 100644
--- a/PhysicsTools/NanoAOD/plugins/EnergyRingsTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/EnergyRingsTableProducer.cc
@@ -89,108 +89,39 @@ void EnergyRingsTableProducer::produce(edm::Event& iEvent, const edm::EventSetup
     numdaughterspt03.push_back(numDaughtersPt03);
   }                                                                            //end of jet loop
   auto tab = std::make_unique<nanoaod::FlatTable>(ncand, name_, false, true);  //extension to Jet collection set to true
-  tab->addColumn<int>(
-      "numDaughtersPt03", numdaughterspt03, "number of jet daughters with pT>0.3 GeV", nanoaod::FlatTable::IntColumn);
-
-  tab->addColumn<float>("EmFractionEnergyRing0",
-                        EmFractionEnergyRings[0],
-                        "Em energy fraction in ring in dR 0-0.05",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("EmFractionEnergyRing1",
-                        EmFractionEnergyRings[1],
-                        "Em energy fraction in ring in dR 0.05-0.1",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("EmFractionEnergyRing2",
-                        EmFractionEnergyRings[2],
-                        "Em energy fraction in ring in dR 0.1-0.2",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("EmFractionEnergyRing3",
-                        EmFractionEnergyRings[3],
-                        "Em energy fraction in ring in dR 0.2-0.3",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("EmFractionEnergyRing4",
-                        EmFractionEnergyRings[4],
-                        "Em energy fraction in ring in dR 0.3-0.4",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("EmFractionEnergyRing5",
-                        EmFractionEnergyRings[5],
-                        "Em energy fraction in ring in dR 0.4 overflow",
-                        nanoaod::FlatTable::FloatColumn);
-
-  tab->addColumn<float>("ChFractionEnergyRing0",
-                        ChFractionEnergyRings[0],
-                        "Ch energy fraction in ring in dR 0-0.05",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("ChFractionEnergyRing1",
-                        ChFractionEnergyRings[1],
-                        "Ch energy fraction in ring in dR 0.05-0.1",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("ChFractionEnergyRing2",
-                        ChFractionEnergyRings[2],
-                        "Ch energy fraction in ring in dR 0.1-0.2",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("ChFractionEnergyRing3",
-                        ChFractionEnergyRings[3],
-                        "Ch energy fraction in ring in dR 0.2-0.3",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("ChFractionEnergyRing4",
-                        ChFractionEnergyRings[4],
-                        "Ch energy fraction in ring in dR 0.3-0.4",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("ChFractionEnergyRing5",
-                        ChFractionEnergyRings[5],
-                        "Ch energy fraction in ring in dR 0.4 overflow",
-                        nanoaod::FlatTable::FloatColumn);
-
-  tab->addColumn<float>("MuFractionEnergyRing0",
-                        MuFractionEnergyRings[0],
-                        "Mu energy fraction in ring in dR 0-0.05",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("MuFractionEnergyRing1",
-                        MuFractionEnergyRings[1],
-                        "Mu energy fraction in ring in dR 0.05-0.1",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("MuFractionEnergyRing2",
-                        MuFractionEnergyRings[2],
-                        "Mu energy fraction in ring in dR 0.1-0.2",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("MuFractionEnergyRing3",
-                        MuFractionEnergyRings[3],
-                        "Mu energy fraction in ring in dR 0.2-0.3",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("MuFractionEnergyRing4",
-                        MuFractionEnergyRings[4],
-                        "Mu energy fraction in ring in dR 0.3-0.4",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("MuFractionEnergyRing5",
-                        MuFractionEnergyRings[5],
-                        "Mu energy fraction in ring in dR 0.4 overflow",
-                        nanoaod::FlatTable::FloatColumn);
-
-  tab->addColumn<float>("NeFractionEnergyRing0",
-                        NeFractionEnergyRings[0],
-                        "Ne energy fraction in ring in dR 0-0.05",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("NeFractionEnergyRing1",
-                        NeFractionEnergyRings[1],
-                        "Ne energy fraction in ring in dR 0.05-0.1",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("NeFractionEnergyRing2",
-                        NeFractionEnergyRings[2],
-                        "Ne energy fraction in ring in dR 0.1-0.2",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("NeFractionEnergyRing3",
-                        NeFractionEnergyRings[3],
-                        "Ne energy fraction in ring in dR 0.2-0.3",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("NeFractionEnergyRing4",
-                        NeFractionEnergyRings[4],
-                        "Ne energy fraction in ring in dR 0.3-0.4",
-                        nanoaod::FlatTable::FloatColumn);
-  tab->addColumn<float>("NeFractionEnergyRing5",
-                        NeFractionEnergyRings[5],
-                        "Ne energy fraction in ring in dR 0.4 overflow",
-                        nanoaod::FlatTable::FloatColumn);
+  tab->addColumn<int>("numDaughtersPt03", numdaughterspt03, "number of jet daughters with pT>0.3 GeV");
+
+  tab->addColumn<float>("EmFractionEnergyRing0", EmFractionEnergyRings[0], "Em energy fraction in ring in dR 0-0.05");
+  tab->addColumn<float>("EmFractionEnergyRing1", EmFractionEnergyRings[1], "Em energy fraction in ring in dR 0.05-0.1");
+  tab->addColumn<float>("EmFractionEnergyRing2", EmFractionEnergyRings[2], "Em energy fraction in ring in dR 0.1-0.2");
+  tab->addColumn<float>("EmFractionEnergyRing3", EmFractionEnergyRings[3], "Em energy fraction in ring in dR 0.2-0.3");
+  tab->addColumn<float>("EmFractionEnergyRing4", EmFractionEnergyRings[4], "Em energy fraction in ring in dR 0.3-0.4");
+  tab->addColumn<float>(
+      "EmFractionEnergyRing5", EmFractionEnergyRings[5], "Em energy fraction in ring in dR 0.4 overflow");
+
+  tab->addColumn<float>("ChFractionEnergyRing0", ChFractionEnergyRings[0], "Ch energy fraction in ring in dR 0-0.05");
+  tab->addColumn<float>("ChFractionEnergyRing1", ChFractionEnergyRings[1], "Ch energy fraction in ring in dR 0.05-0.1");
+  tab->addColumn<float>("ChFractionEnergyRing2", ChFractionEnergyRings[2], "Ch energy fraction in ring in dR 0.1-0.2");
+  tab->addColumn<float>("ChFractionEnergyRing3", ChFractionEnergyRings[3], "Ch energy fraction in ring in dR 0.2-0.3");
+  tab->addColumn<float>("ChFractionEnergyRing4", ChFractionEnergyRings[4], "Ch energy fraction in ring in dR 0.3-0.4");
+  tab->addColumn<float>(
+      "ChFractionEnergyRing5", ChFractionEnergyRings[5], "Ch energy fraction in ring in dR 0.4 overflow");
+
+  tab->addColumn<float>("MuFractionEnergyRing0", MuFractionEnergyRings[0], "Mu energy fraction in ring in dR 0-0.05");
+  tab->addColumn<float>("MuFractionEnergyRing1", MuFractionEnergyRings[1], "Mu energy fraction in ring in dR 0.05-0.1");
+  tab->addColumn<float>("MuFractionEnergyRing2", MuFractionEnergyRings[2], "Mu energy fraction in ring in dR 0.1-0.2");
+  tab->addColumn<float>("MuFractionEnergyRing3", MuFractionEnergyRings[3], "Mu energy fraction in ring in dR 0.2-0.3");
+  tab->addColumn<float>("MuFractionEnergyRing4", MuFractionEnergyRings[4], "Mu energy fraction in ring in dR 0.3-0.4");
+  tab->addColumn<float>(
+      "MuFractionEnergyRing5", MuFractionEnergyRings[5], "Mu energy fraction in ring in dR 0.4 overflow");
+
+  tab->addColumn<float>("NeFractionEnergyRing0", NeFractionEnergyRings[0], "Ne energy fraction in ring in dR 0-0.05");
+  tab->addColumn<float>("NeFractionEnergyRing1", NeFractionEnergyRings[1], "Ne energy fraction in ring in dR 0.05-0.1");
+  tab->addColumn<float>("NeFractionEnergyRing2", NeFractionEnergyRings[2], "Ne energy fraction in ring in dR 0.1-0.2");
+  tab->addColumn<float>("NeFractionEnergyRing3", NeFractionEnergyRings[3], "Ne energy fraction in ring in dR 0.2-0.3");
+  tab->addColumn<float>("NeFractionEnergyRing4", NeFractionEnergyRings[4], "Ne energy fraction in ring in dR 0.3-0.4");
+  tab->addColumn<float>(
+      "NeFractionEnergyRing5", NeFractionEnergyRings[5], "Ne energy fraction in ring in dR 0.4 overflow");
 
   iEvent.put(std::move(tab));
 }
diff --git a/PhysicsTools/NanoAOD/plugins/GenJetFlavourTableProducer.cc b/PhysicsTools/NanoAOD/plugins/GenJetFlavourTableProducer.cc
index 887004e301ab2..9ebe624ea258f 100644
--- a/PhysicsTools/NanoAOD/plugins/GenJetFlavourTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/GenJetFlavourTableProducer.cc
@@ -87,9 +87,8 @@ void GenJetFlavourTableProducer::produce(edm::Event& iEvent, const edm::EventSet
   }
 
   auto tab = std::make_unique<nanoaod::FlatTable>(ncand, name_, false, true);
-  tab->addColumn<int>("partonFlavour", partonFlavour, "flavour from parton matching", nanoaod::FlatTable::IntColumn);
-  tab->addColumn<uint8_t>(
-      "hadronFlavour", hadronFlavour, "flavour from hadron ghost clustering", nanoaod::FlatTable::UInt8Column);
+  tab->addColumn<int>("partonFlavour", partonFlavour, "flavour from parton matching");
+  tab->addColumn<uint8_t>("hadronFlavour", hadronFlavour, "flavour from hadron ghost clustering");
 
   iEvent.put(std::move(tab));
 }
diff --git a/PhysicsTools/NanoAOD/plugins/GenWeightsTableProducer.cc b/PhysicsTools/NanoAOD/plugins/GenWeightsTableProducer.cc
index 96a62c9e29e54..aa7b1adf53291 100644
--- a/PhysicsTools/NanoAOD/plugins/GenWeightsTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/GenWeightsTableProducer.cc
@@ -288,7 +288,7 @@ class GenWeightsTableProducer : public edm::global::EDProducer<edm::StreamCache<
     // table for gen info, always available
     auto out = std::make_unique<nanoaod::FlatTable>(1, "genWeight", true);
     out->setDoc("generator weight");
-    out->addColumnValue<float>("", weight, "generator weight", nanoaod::FlatTable::FloatColumn);
+    out->addColumnValue<float>("", weight, "generator weight");
     iEvent.put(std::move(out));
 
     std::string model_label = streamCache(id)->countermap.getLabel();
@@ -399,31 +399,23 @@ class GenWeightsTableProducer : public edm::global::EDProducer<edm::StreamCache<
                             vectorSize > 1 ? "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 "
                                              "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 "
                                            : "dummy PS weight (1.0) ",
-                            nanoaod::FlatTable::FloatColumn,
                             lheWeightPrecision_);
 
     outScale.reset(new nanoaod::FlatTable(wScale.size(), "LHEScaleWeight", false));
-    outScale->addColumn<float>(
-        "", wScale, weightChoice->scaleWeightsDoc, nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+    outScale->addColumn<float>("", wScale, weightChoice->scaleWeightsDoc, lheWeightPrecision_);
 
     outPdf.reset(new nanoaod::FlatTable(wPDF.size(), "LHEPdfWeight", false));
-    outPdf->addColumn<float>(
-        "", wPDF, weightChoice->pdfWeightsDoc, nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+    outPdf->addColumn<float>("", wPDF, weightChoice->pdfWeightsDoc, lheWeightPrecision_);
 
     outRwgt.reset(new nanoaod::FlatTable(wRwgt.size(), "LHEReweightingWeight", false));
-    outRwgt->addColumn<float>(
-        "", wRwgt, weightChoice->rwgtWeightDoc, nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+    outRwgt->addColumn<float>("", wRwgt, weightChoice->rwgtWeightDoc, lheWeightPrecision_);
 
     outNamed.reset(new nanoaod::FlatTable(1, "LHEWeight", true));
-    outNamed->addColumnValue<float>("originalXWGTUP",
-                                    lheProd.originalXWGTUP(),
-                                    "Nominal event weight in the LHE file",
-                                    nanoaod::FlatTable::FloatColumn);
+    outNamed->addColumnValue<float>("originalXWGTUP", lheProd.originalXWGTUP(), "Nominal event weight in the LHE file");
     for (unsigned int i = 0, n = wNamed.size(); i < n; ++i) {
       outNamed->addColumnValue<float>(namedWeightLabels_[i],
                                       wNamed[i],
                                       "LHE weight for id " + namedWeightIDs_[i] + ", relative to nominal",
-                                      nanoaod::FlatTable::FloatColumn,
                                       lheWeightPrecision_);
     }
 
@@ -460,12 +452,10 @@ class GenWeightsTableProducer : public edm::global::EDProducer<edm::StreamCache<
       wPS.push_back(1.0);
 
     outScale.reset(new nanoaod::FlatTable(wScale.size(), "LHEScaleWeight", false));
-    outScale->addColumn<float>(
-        "", wScale, weightChoice->scaleWeightsDoc, nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+    outScale->addColumn<float>("", wScale, weightChoice->scaleWeightsDoc, lheWeightPrecision_);
 
     outPdf.reset(new nanoaod::FlatTable(wPDF.size(), "LHEPdfWeight", false));
-    outPdf->addColumn<float>(
-        "", wPDF, weightChoice->pdfWeightsDoc, nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+    outPdf->addColumn<float>("", wPDF, weightChoice->pdfWeightsDoc, lheWeightPrecision_);
 
     outPS.reset(new nanoaod::FlatTable(wPS.size(), "PSWeight", false));
     outPS->addColumn<float>("",
@@ -473,14 +463,12 @@ class GenWeightsTableProducer : public edm::global::EDProducer<edm::StreamCache<
                             wPS.size() > 1 ? "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 "
                                              "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 "
                                            : "dummy PS weight (1.0) ",
-                            nanoaod::FlatTable::FloatColumn,
                             lheWeightPrecision_);
 
     outNamed.reset(new nanoaod::FlatTable(1, "LHEWeight", true));
-    outNamed->addColumnValue<float>(
-        "originalXWGTUP", originalXWGTUP, "Nominal event weight in the LHE file", nanoaod::FlatTable::FloatColumn);
+    outNamed->addColumnValue<float>("originalXWGTUP", originalXWGTUP, "Nominal event weight in the LHE file");
     /*for (unsigned int i = 0, n = wNamed.size(); i < n; ++i) {
-      outNamed->addColumnValue<float>(namedWeightLabels_[i], wNamed[i], "LHE weight for id "+namedWeightIDs_[i]+", relative to nominal", nanoaod::FlatTable::FloatColumn, lheWeightPrecision_);
+      outNamed->addColumnValue<float>(namedWeightLabels_[i], wNamed[i], "LHE weight for id "+namedWeightIDs_[i]+", relative to nominal", lheWeightPrecision_);
       }*/
 
     counter->incLHE(genWeight, wScale, wPDF, std::vector<double>(), std::vector<double>(), wPS);
@@ -506,7 +494,6 @@ class GenWeightsTableProducer : public edm::global::EDProducer<edm::StreamCache<
                             vectorSize > 1 ? "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 "
                                              "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 "
                                            : "dummy PS weight (1.0) ",
-                            nanoaod::FlatTable::FloatColumn,
                             lheWeightPrecision_);
 
     counter->incGenOnly(genWeight);
diff --git a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
index 9271a26422948..f6d125afa9512 100644
--- a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
@@ -16,24 +16,24 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
       const auto& varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
       const std::string& type = varPSet.getParameter<std::string>("type");
       if (type == "int")
-        vars_.push_back(std::make_unique<IntVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<IntVar>(vname, varPSet, consumesCollector()));
       else if (type == "float")
         vars_.push_back(
-            std::make_unique<FloatVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+            std::make_unique<FloatVar>(vname, varPSet, consumesCollector()));
       else if (type == "double")
         vars_.push_back(
-            std::make_unique<DoubleVar>(vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+            std::make_unique<DoubleVar>(vname, varPSet, consumesCollector()));
       else if (type == "bool")
-        vars_.push_back(std::make_unique<BoolVar>(vname, nanoaod::FlatTable::BoolColumn, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<BoolVar>(vname, varPSet, consumesCollector()));
       else if (type == "candidatescalarsum")
         vars_.push_back(std::make_unique<CandidateScalarSumVar>(
-            vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+            vname, varPSet, consumesCollector()));
       else if (type == "candidatesize")
         vars_.push_back(
-            std::make_unique<CandidateSizeVar>(vname, nanoaod::FlatTable::IntColumn, varPSet, consumesCollector()));
+            std::make_unique<CandidateSizeVar>(vname, varPSet, consumesCollector()));
       else if (type == "candidatesummass")
         vars_.push_back(std::make_unique<CandidateSumMassVar>(
-            vname, nanoaod::FlatTable::FloatColumn, varPSet, consumesCollector()));
+            vname, varPSet, consumesCollector()));
       else
         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
     }
@@ -55,16 +55,14 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
 protected:
   class Variable {
   public:
-    Variable(const std::string& aname, nanoaod::FlatTable::ColumnType atype, const edm::ParameterSet& cfg)
-        : name_(aname), doc_(cfg.getParameter<std::string>("doc")), type_(atype) {}
+    Variable(const std::string& aname, const edm::ParameterSet& cfg)
+        : name_(aname), doc_(cfg.getParameter<std::string>("doc")) {}
     virtual void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const = 0;
     virtual ~Variable() {}
     const std::string& name() const { return name_; }
-    const nanoaod::FlatTable::ColumnType& type() const { return type_; }
 
   protected:
     std::string name_, doc_;
-    nanoaod::FlatTable::ColumnType type_;
   };
   template <typename ValType>
   class Identity {
@@ -138,16 +136,11 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
   template <typename ValType, typename ColType = ValType, typename Converter = Identity<ValType>>
   class VariableT : public Variable {
   public:
-    VariableT(const std::string& aname,
-              nanoaod::FlatTable::ColumnType atype,
-              const edm::ParameterSet& cfg,
-              edm::ConsumesCollector&& cc)
-        : Variable(aname, atype, cfg), src_(cc.consumes<ValType>(cfg.getParameter<edm::InputTag>("src"))) {}
+    VariableT(const std::string& aname, const edm::ParameterSet& cfg, edm::ConsumesCollector&& cc)
+        : Variable(aname, cfg), src_(cc.consumes<ValType>(cfg.getParameter<edm::InputTag>("src"))) {}
     ~VariableT() override {}
     void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const override {
-      edm::Handle<ValType> handle;
-      iEvent.getByToken(src_, handle);
-      out.template addColumnValue<ColType>(this->name_, Converter::convert(*handle), this->doc_, this->type_);
+      out.template addColumnValue<ColType>(this->name_, Converter::convert(iEvent.get(src_)), this->doc_);
     }
 
   protected:
@@ -156,7 +149,7 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
   typedef VariableT<int> IntVar;
   typedef VariableT<float> FloatVar;
   typedef VariableT<double, float> DoubleVar;
-  typedef VariableT<bool, uint8_t> BoolVar;
+  typedef VariableT<bool> BoolVar;
   typedef VariableT<edm::View<reco::Candidate>, float, ScalarPtSum<float, edm::View<reco::Candidate>>>
       CandidateScalarSumVar;
   typedef VariableT<edm::View<reco::Candidate>, float, MassSum<float, edm::View<reco::Candidate>>> CandidateSumMassVar;
diff --git a/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc b/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
index 76dd25838adec..7ea3d53b6e1e6 100644
--- a/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
@@ -131,38 +131,30 @@ class LHETablesProducer : public edm::global::EDProducer<> {
       lheVpt = std::hypot(pup[v.first][0] + pup[v.second][0], pup[v.first][1] + pup[v.second][1]);
     }
 
-    out.addColumnValue<uint8_t>(
-        "Njets", lheNj, "Number of jets (partons) at LHE step", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<uint8_t>("Nb", lheNb, "Number of b partons at LHE step", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<uint8_t>("Nc", lheNc, "Number of c partons at LHE step", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<uint8_t>(
-        "Nuds", lheNuds, "Number of u,d,s partons at LHE step", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<uint8_t>(
-        "Nglu", lheNglu, "Number of gluon partons at LHE step", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<float>("HT", lheHT, "HT, scalar sum of parton pTs at LHE step", nanoaod::FlatTable::FloatColumn);
+    out.addColumnValue<uint8_t>("Njets", lheNj, "Number of jets (partons) at LHE step");
+    out.addColumnValue<uint8_t>("Nb", lheNb, "Number of b partons at LHE step");
+    out.addColumnValue<uint8_t>("Nc", lheNc, "Number of c partons at LHE step");
+    out.addColumnValue<uint8_t>("Nuds", lheNuds, "Number of u,d,s partons at LHE step");
+    out.addColumnValue<uint8_t>("Nglu", lheNglu, "Number of gluon partons at LHE step");
+    out.addColumnValue<float>("HT", lheHT, "HT, scalar sum of parton pTs at LHE step");
     out.addColumnValue<float>("HTIncoming",
                               lheHTIncoming,
                               "HT, scalar sum of parton pTs at LHE step, restricted to partons",
                               nanoaod::FlatTable::FloatColumn);
-    out.addColumnValue<float>("Vpt", lheVpt, "pT of the W or Z boson at LHE step", nanoaod::FlatTable::FloatColumn);
-    out.addColumnValue<uint8_t>("NpNLO", lheProd.npNLO(), "number of partons at NLO", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<uint8_t>("NpLO", lheProd.npLO(), "number of partons at LO", nanoaod::FlatTable::UInt8Column);
-    out.addColumnValue<float>("AlphaS", alphaS, "Per-event alphaS", nanoaod::FlatTable::FloatColumn);
+    out.addColumnValue<float>("Vpt", lheVpt, "pT of the W or Z boson at LHE step");
+    out.addColumnValue<uint8_t>("NpNLO", lheProd.npNLO(), "number of partons at NLO");
+    out.addColumnValue<uint8_t>("NpLO", lheProd.npLO(), "number of partons at LO");
+    out.addColumnValue<float>("AlphaS", alphaS, "Per-event alphaS");
 
     auto outPart = std::make_unique<nanoaod::FlatTable>(vals_pt.size(), "LHEPart", false);
-    outPart->addColumn<float>("pt", vals_pt, "Pt of LHE particles", nanoaod::FlatTable::FloatColumn, this->precision_);
-    outPart->addColumn<float>(
-        "eta", vals_eta, "Pseodorapidity of LHE particles", nanoaod::FlatTable::FloatColumn, this->precision_);
-    outPart->addColumn<float>(
-        "phi", vals_phi, "Phi of LHE particles", nanoaod::FlatTable::FloatColumn, this->precision_);
-    outPart->addColumn<float>(
-        "mass", vals_mass, "Mass of LHE particles", nanoaod::FlatTable::FloatColumn, this->precision_);
-    outPart->addColumn<float>(
-        "incomingpz", vals_pz, "Pz of incoming LHE particles", nanoaod::FlatTable::FloatColumn, this->precision_);
-    outPart->addColumn<int>("pdgId", vals_pid, "PDG ID of LHE particles", nanoaod::FlatTable::IntColumn);
-    outPart->addColumn<int>(
-        "status", vals_status, "LHE particle status; -1:incoming, 1:outgoing", nanoaod::FlatTable::IntColumn);
-    outPart->addColumn<int>("spin", vals_spin, "Spin of LHE particles", nanoaod::FlatTable::IntColumn);
+    outPart->addColumn<float>("pt", vals_pt, "Pt of LHE particles", this->precision_);
+    outPart->addColumn<float>("eta", vals_eta, "Pseodorapidity of LHE particles", this->precision_);
+    outPart->addColumn<float>("phi", vals_phi, "Phi of LHE particles", this->precision_);
+    outPart->addColumn<float>("mass", vals_mass, "Mass of LHE particles", this->precision_);
+    outPart->addColumn<float>("incomingpz", vals_pz, "Pz of incoming LHE particles", this->precision_);
+    outPart->addColumn<int>("pdgId", vals_pid, "PDG ID of LHE particles");
+    outPart->addColumn<int>("status", vals_status, "LHE particle status; -1:incoming, 1:outgoing");
+    outPart->addColumn<int>("spin", vals_spin, "Spin of LHE particles");
 
     return outPart;
   }
diff --git a/PhysicsTools/NanoAOD/plugins/MuonIDTableProducer.cc b/PhysicsTools/NanoAOD/plugins/MuonIDTableProducer.cc
index f6da6c063f812..83bf37760b74f 100644
--- a/PhysicsTools/NanoAOD/plugins/MuonIDTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/MuonIDTableProducer.cc
@@ -70,22 +70,19 @@ void MuonIDTableProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::
   }
 
   auto tab = std::make_unique<nanoaod::FlatTable>(ncand, name_, false, true);
-  tab->addColumn<uint8_t>("tightId", tight, "POG Tight muon ID", nanoaod::FlatTable::BoolColumn);
+  tab->addColumn<bool>("tightId", tight, "POG Tight muon ID");
   tab->addColumn<uint8_t>(
       "highPtId",
       highPt,
-      "POG highPt muon ID (1 = tracker high pT, 2 = global high pT, which includes tracker high pT)",
-      nanoaod::FlatTable::UInt8Column);
-  tab->addColumn<uint8_t>(
+      "POG highPt muon ID (1 = tracker high pT, 2 = global high pT, which includes tracker high pT)");
+  tab->addColumn<bool>(
       "softId",
       soft,
-      "POG Soft muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)",
-      nanoaod::FlatTable::BoolColumn);
-  tab->addColumn<uint8_t>(
+      "POG Soft muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)");
+  tab->addColumn<bool>(
       "mediumId",
       medium,
-      "POG Medium muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)",
-      nanoaod::FlatTable::BoolColumn);
+      "POG Medium muon ID (using the relaxed cuts in the data Run 2016 B-F periods, and standard cuts elsewhere)");
 
   iEvent.put(std::move(tab));
 }
diff --git a/PhysicsTools/NanoAOD/plugins/NPUTablesProducer.cc b/PhysicsTools/NanoAOD/plugins/NPUTablesProducer.cc
index 5dd6eb4ab6804..d8bd6999647df 100644
--- a/PhysicsTools/NanoAOD/plugins/NPUTablesProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/NPUTablesProducer.cc
@@ -77,18 +77,15 @@ class NPUTablesProducer : public edm::global::EDProducer<> {
     out.addColumnValue<float>("nTrueInt",
                               nt,
                               "the true mean number of the poisson distribution for this event from which the number "
-                              "of interactions each bunch crossing has been sampled",
-                              nanoaod::FlatTable::FloatColumn);
+                              "of interactions each bunch crossing has been sampled");
     out.addColumnValue<int>(
         "nPU",
         npu,
-        "the number of pileup interactions that have been added to the event in the current bunch crossing",
-        nanoaod::FlatTable::IntColumn);
-    out.addColumnValue<int>("sumEOOT", eoot, "number of early out of time pileup", nanoaod::FlatTable::IntColumn);
-    out.addColumnValue<int>("sumLOOT", loot, "number of late out of time pileup", nanoaod::FlatTable::IntColumn);
-    out.addColumnValue<float>("pudensity", pudensity, "PU vertices / mm", nanoaod::FlatTable::FloatColumn);
-    out.addColumnValue<float>(
-        "gpudensity", gpudensity, "Generator-level PU vertices / mm", nanoaod::FlatTable::FloatColumn);
+        "the number of pileup interactions that have been added to the event in the current bunch crossing");
+    out.addColumnValue<int>("sumEOOT", eoot, "number of early out of time pileup");
+    out.addColumnValue<int>("sumLOOT", loot, "number of late out of time pileup");
+    out.addColumnValue<float>("pudensity", pudensity, "PU vertices / mm");
+    out.addColumnValue<float>("gpudensity", gpudensity, "Generator-level PU vertices / mm");
   }
 
   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
diff --git a/PhysicsTools/NanoAOD/plugins/NanoAODBaseCrossCleaner.cc b/PhysicsTools/NanoAOD/plugins/NanoAODBaseCrossCleaner.cc
index 8a21d62fc551b..ec83884986568 100644
--- a/PhysicsTools/NanoAOD/plugins/NanoAODBaseCrossCleaner.cc
+++ b/PhysicsTools/NanoAOD/plugins/NanoAODBaseCrossCleaner.cc
@@ -104,11 +104,11 @@ void NanoAODBaseCrossCleaner::produce(edm::Event& iEvent, const edm::EventSetup&
 
   objectSelection(*jetsIn, *muonsIn, *electronsIn, *tausIn, *photonsIn, jets, muons, eles, taus, photons);
 
-  muonsTable->addColumn<uint8_t>(name_, muons, doc_, nanoaod::FlatTable::UInt8Column);
-  jetsTable->addColumn<uint8_t>(name_, jets, doc_, nanoaod::FlatTable::UInt8Column);
-  electronsTable->addColumn<uint8_t>(name_, eles, doc_, nanoaod::FlatTable::UInt8Column);
-  tausTable->addColumn<uint8_t>(name_, taus, doc_, nanoaod::FlatTable::UInt8Column);
-  photonsTable->addColumn<uint8_t>(name_, photons, doc_, nanoaod::FlatTable::UInt8Column);
+  muonsTable->addColumn<uint8_t>(name_, muons, doc_);
+  jetsTable->addColumn<uint8_t>(name_, jets, doc_);
+  electronsTable->addColumn<uint8_t>(name_, eles, doc_);
+  tausTable->addColumn<uint8_t>(name_, taus, doc_);
+  photonsTable->addColumn<uint8_t>(name_, photons, doc_);
 
   iEvent.put(std::move(jetsTable), "jets");
   iEvent.put(std::move(muonsTable), "muons");
diff --git a/PhysicsTools/NanoAOD/plugins/NativeArrayTableProducer.cc b/PhysicsTools/NanoAOD/plugins/NativeArrayTableProducer.cc
index ac163bce4b685..d4c0ff429ebbb 100644
--- a/PhysicsTools/NanoAOD/plugins/NativeArrayTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/NativeArrayTableProducer.cc
@@ -4,7 +4,7 @@
 
 #include <vector>
 
-template <typename TIn, typename TCol, nanoaod::FlatTable::ColumnType CT>
+template <typename TIn, typename TCol>
 class NativeArrayTableProducer : public edm::stream::EDProducer<> {
 public:
   NativeArrayTableProducer(edm::ParameterSet const& params)
@@ -23,7 +23,7 @@ class NativeArrayTableProducer : public edm::stream::EDProducer<> {
     const auto& in = *src;
     auto out = std::make_unique<nanoaod::FlatTable>(in.size(), name_, false, false);
     out->setDoc(doc_);
-    (*out).template addColumn<TCol>(this->name_, in, this->doc_, CT);
+    (*out).template addColumn<TCol>(this->name_, in, this->doc_);
     iEvent.put(std::move(out));
   }
 
@@ -33,10 +33,10 @@ class NativeArrayTableProducer : public edm::stream::EDProducer<> {
   const edm::EDGetTokenT<TIn> src_;
 };
 
-typedef NativeArrayTableProducer<std::vector<float>, float, nanoaod::FlatTable::FloatColumn> FloatArrayTableProducer;
-typedef NativeArrayTableProducer<std::vector<double>, float, nanoaod::FlatTable::FloatColumn> DoubleArrayTableProducer;
-typedef NativeArrayTableProducer<std::vector<int>, int, nanoaod::FlatTable::IntColumn> IntArrayTableProducer;
-typedef NativeArrayTableProducer<std::vector<bool>, uint8_t, nanoaod::FlatTable::UInt8Column> BoolArrayTableProducer;
+typedef NativeArrayTableProducer<std::vector<float>, float> FloatArrayTableProducer;
+typedef NativeArrayTableProducer<std::vector<double>, float> DoubleArrayTableProducer;
+typedef NativeArrayTableProducer<std::vector<int>, int> IntArrayTableProducer;
+typedef NativeArrayTableProducer<std::vector<bool>, bool> BoolArrayTableProducer;
 
 #include "FWCore/Framework/interface/MakerMacros.h"
 DEFINE_FWK_MODULE(FloatArrayTableProducer);
diff --git a/PhysicsTools/NanoAOD/plugins/TriggerObjectTableProducer.cc b/PhysicsTools/NanoAOD/plugins/TriggerObjectTableProducer.cc
index 98497d06c3b87..e13d8edcdaa9a 100644
--- a/PhysicsTools/NanoAOD/plugins/TriggerObjectTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/TriggerObjectTableProducer.cc
@@ -282,18 +282,16 @@ void TriggerObjectTableProducer::produce(edm::Event &iEvent, const edm::EventSet
   }
 
   auto tab = std::make_unique<nanoaod::FlatTable>(nobj, name_, false, false);
-  tab->addColumn<int>("id", id, idDoc_, nanoaod::FlatTable::IntColumn);
-  tab->addColumn<float>("pt", pt, "pt", nanoaod::FlatTable::FloatColumn, 12);
-  tab->addColumn<float>("eta", eta, "eta", nanoaod::FlatTable::FloatColumn, 12);
-  tab->addColumn<float>("phi", phi, "phi", nanoaod::FlatTable::FloatColumn, 12);
-  tab->addColumn<float>("l1pt", l1pt, "pt of associated L1 seed", nanoaod::FlatTable::FloatColumn, 8);
-  tab->addColumn<int>("l1iso", l1iso, "iso of associated L1 seed", nanoaod::FlatTable::IntColumn);
-  tab->addColumn<int>("l1charge", l1charge, "charge of associated L1 seed", nanoaod::FlatTable::IntColumn);
-  tab->addColumn<float>("l1pt_2", l1pt_2, "pt of associated secondary L1 seed", nanoaod::FlatTable::FloatColumn, 8);
-  tab->addColumn<float>(
-      "l2pt", l2pt, "pt of associated 'L2' seed (i.e. HLT before tracking/PF)", nanoaod::FlatTable::FloatColumn, 10);
-  tab->addColumn<int>(
-      "filterBits", bits, "extra bits of associated information: " + bitsDoc_, nanoaod::FlatTable::IntColumn);
+  tab->addColumn<int>("id", id, idDoc_);
+  tab->addColumn<float>("pt", pt, "pt", 12);
+  tab->addColumn<float>("eta", eta, "eta", 12);
+  tab->addColumn<float>("phi", phi, "phi", 12);
+  tab->addColumn<float>("l1pt", l1pt, "pt of associated L1 seed", 8);
+  tab->addColumn<int>("l1iso", l1iso, "iso of associated L1 seed");
+  tab->addColumn<int>("l1charge", l1charge, "charge of associated L1 seed");
+  tab->addColumn<float>("l1pt_2", l1pt_2, "pt of associated secondary L1 seed", 8);
+  tab->addColumn<float>("l2pt", l2pt, "pt of associated 'L2' seed (i.e. HLT before tracking/PF)", 10);
+  tab->addColumn<int>("filterBits", bits, "extra bits of associated information: " + bitsDoc_);
   iEvent.put(std::move(tab));
 }
 
diff --git a/PhysicsTools/NanoAOD/plugins/VertexTableProducer.cc b/PhysicsTools/NanoAOD/plugins/VertexTableProducer.cc
index 4793abd344c0d..415e0846d93d6 100644
--- a/PhysicsTools/NanoAOD/plugins/VertexTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/VertexTableProducer.cc
@@ -117,39 +117,27 @@ void VertexTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe
   iEvent.getByToken(pvs_, pvsIn);
   iEvent.getByToken(pvsScore_, pvsScoreIn);
   auto pvTable = std::make_unique<nanoaod::FlatTable>(1, pvName_, true);
-  pvTable->addColumnValue<float>(
-      "ndof", (*pvsIn)[0].ndof(), "main primary vertex number of degree of freedom", nanoaod::FlatTable::FloatColumn, 8);
-  pvTable->addColumnValue<float>(
-      "x", (*pvsIn)[0].position().x(), "main primary vertex position x coordinate", nanoaod::FlatTable::FloatColumn, 10);
-  pvTable->addColumnValue<float>(
-      "y", (*pvsIn)[0].position().y(), "main primary vertex position y coordinate", nanoaod::FlatTable::FloatColumn, 10);
-  pvTable->addColumnValue<float>(
-      "z", (*pvsIn)[0].position().z(), "main primary vertex position z coordinate", nanoaod::FlatTable::FloatColumn, 16);
-  pvTable->addColumnValue<float>(
-      "chi2", (*pvsIn)[0].normalizedChi2(), "main primary vertex reduced chi2", nanoaod::FlatTable::FloatColumn, 8);
+  pvTable->addColumnValue<float>("ndof", (*pvsIn)[0].ndof(), "main primary vertex number of degree of freedom", 8);
+  pvTable->addColumnValue<float>("x", (*pvsIn)[0].position().x(), "main primary vertex position x coordinate", 10);
+  pvTable->addColumnValue<float>("y", (*pvsIn)[0].position().y(), "main primary vertex position y coordinate", 10);
+  pvTable->addColumnValue<float>("z", (*pvsIn)[0].position().z(), "main primary vertex position z coordinate", 16);
+  pvTable->addColumnValue<float>("chi2", (*pvsIn)[0].normalizedChi2(), "main primary vertex reduced chi2", 8);
   int goodPVs = 0;
   for (const auto& pv : *pvsIn)
     if (goodPvCut_(pv))
       goodPVs++;
+  pvTable->addColumnValue<int>("npvs", pvsIn->size(), "total number of reconstructed primary vertices");
   pvTable->addColumnValue<int>(
-      "npvs", (*pvsIn).size(), "total number of reconstructed primary vertices", nanoaod::FlatTable::IntColumn);
-  pvTable->addColumnValue<int>("npvsGood",
-                               goodPVs,
-                               "number of good reconstructed primary vertices. selection:" + goodPvCutString_,
-                               nanoaod::FlatTable::IntColumn);
-  pvTable->addColumnValue<float>("score",
-                                 (*pvsScoreIn).get(pvsIn.id(), 0),
-                                 "main primary vertex score, i.e. sum pt2 of clustered objects",
-                                 nanoaod::FlatTable::FloatColumn,
-                                 8);
+      "npvsGood", goodPVs, "number of good reconstructed primary vertices. selection:" + goodPvCutString_);
+  pvTable->addColumnValue<float>(
+      "score", pvsScoreIn->get(pvsIn.id(), 0), "main primary vertex score, i.e. sum pt2 of clustered objects", 8);
 
   auto otherPVsTable =
       std::make_unique<nanoaod::FlatTable>((*pvsIn).size() > 4 ? 3 : (*pvsIn).size() - 1, "Other" + pvName_, false);
   std::vector<float> pvsz;
   for (size_t i = 1; i < (*pvsIn).size() && i < 4; i++)
     pvsz.push_back((*pvsIn)[i - 1].position().z());
-  otherPVsTable->addColumn<float>(
-      "z", pvsz, "Z position of other primary vertices, excluding the main PV", nanoaod::FlatTable::FloatColumn, 8);
+  otherPVsTable->addColumn<float>("z", pvsz, "Z position of other primary vertices, excluding the main PV", 8);
 
   edm::Handle<edm::View<reco::VertexCompositePtrCandidate>> svsIn;
   iEvent.getByToken(svs_, svsIn);
@@ -183,12 +171,11 @@ void VertexTableProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSe
 
   auto svsTable = std::make_unique<nanoaod::FlatTable>(selCandSv->size(), svName_, false);
   // For SV we fill from here only stuff that cannot be created with the SimpleFlatTableProducer
-  svsTable->addColumn<float>("dlen", dlen, "decay length in cm", nanoaod::FlatTable::FloatColumn, 10);
-  svsTable->addColumn<float>("dlenSig", dlenSig, "decay length significance", nanoaod::FlatTable::FloatColumn, 10);
-  svsTable->addColumn<float>("dxy", dxy, "2D decay length in cm", nanoaod::FlatTable::FloatColumn, 10);
-  svsTable->addColumn<float>("dxySig", dxySig, "2D decay length significance", nanoaod::FlatTable::FloatColumn, 10);
-  svsTable->addColumn<float>(
-      "pAngle", pAngle, "pointing angle, i.e. acos(p_SV * (SV - PV)) ", nanoaod::FlatTable::FloatColumn, 10);
+  svsTable->addColumn<float>("dlen", dlen, "decay length in cm", 10);
+  svsTable->addColumn<float>("dlenSig", dlenSig, "decay length significance", 10);
+  svsTable->addColumn<float>("dxy", dxy, "2D decay length in cm", 10);
+  svsTable->addColumn<float>("dxySig", dxySig, "2D decay length significance", 10);
+  svsTable->addColumn<float>("pAngle", pAngle, "pointing angle, i.e. acos(p_SV * (SV - PV)) ", 10);
 
   iEvent.put(std::move(pvTable), "pv");
   iEvent.put(std::move(otherPVsTable), "otherPVs");

From 88a35e092dd9bf96ed4d24a4b4a1b5e07b9bb701 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Fri, 13 Mar 2020 16:23:31 +0100
Subject: [PATCH 3/9] make ColumnType and enum class for type safety

---
 DataFormats/NanoAOD/interface/FlatTable.h     | 22 +++++++++----------
 DataFormats/NanoAOD/src/FlatTable.cc          | 16 +++++++-------
 .../interface/SimpleFlatTableProducer.h       | 15 +++++--------
 .../plugins/GlobalVariablesTableProducer.cc   | 15 +++++--------
 .../NanoAOD/plugins/LHETablesProducer.cc      |  6 ++---
 PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc    |  8 +++----
 .../NanoAOD/plugins/TableOutputBranches.cc    |  8 +++----
 7 files changed, 39 insertions(+), 51 deletions(-)

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index dd8a9cbd0c9e6..282ef52c669a0 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -37,11 +37,11 @@ namespace nanoaod {
 
   class FlatTable {
   public:
-    enum ColumnType {
-      FloatColumn,
-      IntColumn,
-      UInt8Column,
-      BoolColumn
+    enum class ColumnType {
+      Float,
+      Int,
+      UInt8,
+      Bool
     };  // We could have other Float types with reduced mantissa, and similar
 
     FlatTable() : size_(0) {}
@@ -113,10 +113,10 @@ namespace nanoaod {
       if (values.size() != size())
         throw cms::Exception("LogicError", "Mismatched size for " + name);
       if constexpr (std::is_same<T, bool>()) {
-        columns_.emplace_back(name, docString, ColumnType::BoolColumn, uint8s_.size());
+        columns_.emplace_back(name, docString, ColumnType::Bool, uint8s_.size());
         uint8s_.insert(uint8s_.end(), values.begin(), values.end());
       } else if constexpr (std::is_same<T, float>()) {
-        columns_.emplace_back(name, docString, ColumnType::FloatColumn, floats_.size());
+        columns_.emplace_back(name, docString, ColumnType::Float, floats_.size());
         floats_.insert(floats_.end(), values.begin(), values.end());
         flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).bulk(columnData<float>(columns_.size() - 1));
       } else {
@@ -134,10 +134,10 @@ namespace nanoaod {
       if (columnIndex(name) != -1)
         throw cms::Exception("LogicError", "Duplicated column: " + name);
       if constexpr (std::is_same<T, bool>()) {
-        columns_.emplace_back(name, docString, ColumnType::BoolColumn, uint8s_.size());
+        columns_.emplace_back(name, docString, ColumnType::Bool, uint8s_.size());
         uint8s_.push_back(value);
       } else if constexpr (std::is_same<T, float>()) {
-        columns_.emplace_back(name, docString, ColumnType::FloatColumn, floats_.size());
+        columns_.emplace_back(name, docString, ColumnType::Float, floats_.size());
         floats_.push_back(flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).one(value));
       } else {
         ColumnType type = defaultColumnType<T>();
@@ -152,9 +152,9 @@ namespace nanoaod {
     template <typename T>
     static ColumnType defaultColumnType() {
       if constexpr (std::is_same<T, int>())
-        return ColumnType::IntColumn;
+        return ColumnType::Int;
       if constexpr (std::is_same<T, uint8_t>())
-        return ColumnType::UInt8Column;
+        return ColumnType::UInt8;
       throw cms::Exception("unsupported type");
     }
 
diff --git a/DataFormats/NanoAOD/src/FlatTable.cc b/DataFormats/NanoAOD/src/FlatTable.cc
index 0e3a85827df2d..b09ea215c98fc 100644
--- a/DataFormats/NanoAOD/src/FlatTable.cc
+++ b/DataFormats/NanoAOD/src/FlatTable.cc
@@ -13,16 +13,16 @@ void nanoaod::FlatTable::addExtension(const nanoaod::FlatTable& other) {
     throw cms::Exception("LogicError", "Mismatch in adding extension");
   for (unsigned int i = 0, n = other.nColumns(); i < n; ++i) {
     switch (other.columnType(i)) {
-      case FloatColumn:
+      case ColumnType::Float:
         addColumn<float>(other.columnName(i), other.columnData<float>(i), other.columnDoc(i));
         break;
-      case IntColumn:
+      case ColumnType::Int:
         addColumn<int>(other.columnName(i), other.columnData<int>(i), other.columnDoc(i));
         break;
-      case BoolColumn:
+      case ColumnType::Bool:
         addColumn<bool>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
         break;
-      case UInt8Column:
+      case ColumnType::UInt8:
         addColumn<uint8_t>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
         break;
     }
@@ -33,13 +33,13 @@ double nanoaod::FlatTable::getAnyValue(unsigned int row, unsigned int column) co
   if (column >= nColumns())
     throw cms::Exception("LogicError", "Invalid column");
   switch (columnType(column)) {
-    case FloatColumn:
+    case ColumnType::Float:
       return *(beginData<float>(column) + row);
-    case IntColumn:
+    case ColumnType::Int:
       return *(beginData<int>(column) + row);
-    case BoolColumn:
+    case ColumnType::Bool:
       return *(beginData<uint8_t>(column) + row);
-    case UInt8Column:
+    case ColumnType::UInt8:
       return *(beginData<uint8_t>(column) + row);
   }
   throw cms::Exception("LogicError", "Unsupported type");
diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
index f3c8ef7ceefb4..4c2003ef22866 100644
--- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
+++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
@@ -129,20 +129,15 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<
         const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
         const std::string &type = varPSet.getParameter<std::string>("type");
         if (type == "int")
-          extvars_.push_back(
-              std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector()));
         else if (type == "float")
-          extvars_.push_back(std::make_unique<FloatExtVar>(
-              vname, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<FloatExtVar>(vname, varPSet, this->consumesCollector()));
         else if (type == "double")
-          extvars_.push_back(std::make_unique<DoubleExtVar>(
-              vname, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<DoubleExtVar>(vname, varPSet, this->consumesCollector()));
         else if (type == "uint8")
-          extvars_.push_back(std::make_unique<UInt8ExtVar>(
-              vname, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<UInt8ExtVar>(vname, varPSet, this->consumesCollector()));
         else if (type == "bool")
-          extvars_.push_back(
-              std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector()));
+          extvars_.push_back(std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector()));
         else
           throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
       }
diff --git a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
index f6d125afa9512..dc17ebd2e6e3e 100644
--- a/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/GlobalVariablesTableProducer.cc
@@ -18,22 +18,17 @@ class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
       if (type == "int")
         vars_.push_back(std::make_unique<IntVar>(vname, varPSet, consumesCollector()));
       else if (type == "float")
-        vars_.push_back(
-            std::make_unique<FloatVar>(vname, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<FloatVar>(vname, varPSet, consumesCollector()));
       else if (type == "double")
-        vars_.push_back(
-            std::make_unique<DoubleVar>(vname, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet, consumesCollector()));
       else if (type == "bool")
         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet, consumesCollector()));
       else if (type == "candidatescalarsum")
-        vars_.push_back(std::make_unique<CandidateScalarSumVar>(
-            vname, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<CandidateScalarSumVar>(vname, varPSet, consumesCollector()));
       else if (type == "candidatesize")
-        vars_.push_back(
-            std::make_unique<CandidateSizeVar>(vname, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<CandidateSizeVar>(vname, varPSet, consumesCollector()));
       else if (type == "candidatesummass")
-        vars_.push_back(std::make_unique<CandidateSumMassVar>(
-            vname, varPSet, consumesCollector()));
+        vars_.push_back(std::make_unique<CandidateSumMassVar>(vname, varPSet, consumesCollector()));
       else
         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
     }
diff --git a/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc b/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
index 7ea3d53b6e1e6..735b78858e14b 100644
--- a/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
+++ b/PhysicsTools/NanoAOD/plugins/LHETablesProducer.cc
@@ -137,10 +137,8 @@ class LHETablesProducer : public edm::global::EDProducer<> {
     out.addColumnValue<uint8_t>("Nuds", lheNuds, "Number of u,d,s partons at LHE step");
     out.addColumnValue<uint8_t>("Nglu", lheNglu, "Number of gluon partons at LHE step");
     out.addColumnValue<float>("HT", lheHT, "HT, scalar sum of parton pTs at LHE step");
-    out.addColumnValue<float>("HTIncoming",
-                              lheHTIncoming,
-                              "HT, scalar sum of parton pTs at LHE step, restricted to partons",
-                              nanoaod::FlatTable::FloatColumn);
+    out.addColumnValue<float>(
+        "HTIncoming", lheHTIncoming, "HT, scalar sum of parton pTs at LHE step, restricted to partons");
     out.addColumnValue<float>("Vpt", lheVpt, "pT of the W or Z boson at LHE step");
     out.addColumnValue<uint8_t>("NpNLO", lheProd.npNLO(), "number of partons at NLO");
     out.addColumnValue<uint8_t>("NpLO", lheProd.npLO(), "number of partons at LO");
diff --git a/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc b/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
index 630a82271a8eb..0f4c19aadf1af 100644
--- a/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
+++ b/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
@@ -84,16 +84,16 @@ class NanoAODDQM : public DQMEDAnalyzer {
       if (icol == -1)
         return;  // columns may be missing (e.g. mc-only)
       switch (table.columnType(icol)) {
-        case FlatTable::FloatColumn:
+        case FlatTable::ColumnType::Float:
           vfill<float>(table, icol, rowsel);
           break;
-        case FlatTable::IntColumn:
+        case FlatTable::ColumnType::Int:
           vfill<int>(table, icol, rowsel);
           break;
-        case FlatTable::UInt8Column:
+        case FlatTable::ColumnType::UInt8:
           vfill<uint8_t>(table, icol, rowsel);
           break;
-        case FlatTable::BoolColumn:
+        case FlatTable::ColumnType::Bool:
           vfill<uint8_t>(table, icol, rowsel);
           break;
       }
diff --git a/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc b/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
index 1c72a63cb4fdb..f97ec27439a16 100644
--- a/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
+++ b/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
@@ -13,16 +13,16 @@ void TableOutputBranches::defineBranchesFromFirstEvent(const nanoaod::FlatTable
   for (size_t i = 0; i < tab.nColumns(); i++) {
     const std::string &var = tab.columnName(i);
     switch (tab.columnType(i)) {
-      case (nanoaod::FlatTable::FloatColumn):
+      case nanoaod::FlatTable::ColumnType::Float:
         m_floatBranches.emplace_back(var, tab.columnDoc(i), "F");
         break;
-      case (nanoaod::FlatTable::IntColumn):
+      case nanoaod::FlatTable::ColumnType::Int:
         m_intBranches.emplace_back(var, tab.columnDoc(i), "I");
         break;
-      case (nanoaod::FlatTable::UInt8Column):
+      case nanoaod::FlatTable::ColumnType::UInt8:
         m_uint8Branches.emplace_back(var, tab.columnDoc(i), "b");
         break;
-      case (nanoaod::FlatTable::BoolColumn):
+      case nanoaod::FlatTable::ColumnType::Bool:
         m_uint8Branches.emplace_back(var, tab.columnDoc(i), "O");
         break;
     }

From ffc5cd6e02b9d80aed10e32bb1fe41ed0085bd96 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Sat, 27 Jun 2020 12:22:53 +0200
Subject: [PATCH 4/9] fix clang warning in SimpleFlatTableProducer.h

---
 .../NanoAOD/interface/SimpleFlatTableProducer.h      | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
index 4c2003ef22866..92b704a89bef4 100644
--- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
+++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h
@@ -93,10 +93,16 @@ class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
     void fill(std::vector<const T *> selobjs, nanoaod::FlatTable &out) const override {
       std::vector<ValType> vals(selobjs.size());
       for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
-        if (this->precision_ == -2) {
-          vals[i] = MiniFloatConverter::reduceMantissaToNbitsRounding(func_(*selobjs[i]), precisionFunc_(*selobjs[i]));
-        } else
+        if constexpr (std::is_same<ValType, float>()) {
+          if (this->precision_ == -2) {
+            vals[i] =
+                MiniFloatConverter::reduceMantissaToNbitsRounding(func_(*selobjs[i]), precisionFunc_(*selobjs[i]));
+          } else {
+            vals[i] = func_(*selobjs[i]);
+          }
+        } else {
           vals[i] = func_(*selobjs[i]);
+        }
       }
       out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
     }

From 12bf18dd145e1795aef5c679d90a7215cba5e623 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Tue, 30 Jun 2020 04:38:16 +0200
Subject: [PATCH 5/9] reorganize more redundant checks in FlatTable

---
 DataFormats/NanoAOD/interface/FlatTable.h | 117 ++++++++--------------
 DataFormats/NanoAOD/src/FlatTable.cc      |   4 +-
 FWCore/Utilities/interface/Range.h        |   6 ++
 3 files changed, 52 insertions(+), 75 deletions(-)

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index 282ef52c669a0..c0049dcdde2fb 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -3,13 +3,11 @@
 
 #include "DataFormats/Math/interface/libminifloat.h"
 #include "FWCore/Utilities/interface/Exception.h"
-
-#include <boost/range/sub_range.hpp>
+#include "FWCore/Utilities/interface/Range.h"
 
 #include <cstdint>
 #include <vector>
 #include <string>
-
 #include <type_traits>
 
 namespace nanoaod {
@@ -19,7 +17,8 @@ namespace nanoaod {
     struct MaybeMantissaReduce {
       MaybeMantissaReduce(int mantissaBits) {}
       inline T one(const T &val) const { return val; }
-      inline void bulk(boost::sub_range<std::vector<T>> data) const {}
+      template <typename Range>
+      inline void bulk(Range &&data) const {}
     };
     template <>
     struct MaybeMantissaReduce<float> {
@@ -28,7 +27,8 @@ namespace nanoaod {
       inline float one(const float &val) const {
         return (bits_ > 0 ? MiniFloatConverter::reduceMantissaToNbitsRounding(val, bits_) : val);
       }
-      inline void bulk(boost::sub_range<std::vector<float>> data) const {
+      template <typename Range>
+      inline void bulk(Range &&data) const {
         if (bits_ > 0)
           MiniFloatConverter::reduceMantissaToNbitsRounding(bits_, data.begin(), data.end(), data.begin());
       }
@@ -67,21 +67,21 @@ namespace nanoaod {
 
     /// get a column by index (const)
     template <typename T>
-    boost::sub_range<const std::vector<T>> columnData(unsigned int column) const {
+    auto columnData(unsigned int column) const {
       auto begin = beginData<T>(column);
-      return boost::sub_range<const std::vector<T>>(begin, begin + size_);
+      return edm::Range(begin, begin + size_);
     }
 
     /// get a column by index (non-const)
     template <typename T>
-    boost::sub_range<std::vector<T>> columnData(unsigned int column) {
+    auto columnData(unsigned int column) {
       auto begin = beginData<T>(column);
-      return boost::sub_range<std::vector<T>>(begin, begin + size_);
+      return edm::Range(begin, begin + size_);
     }
 
     /// get a column value for singleton (const)
     template <typename T>
-    const T &columValue(unsigned int column) const {
+    const auto &columValue(unsigned int column) const {
       if (!singleton())
         throw cms::Exception("LogicError", "columnValue works only for singleton tables");
       return *beginData<T>(column);
@@ -112,19 +112,10 @@ namespace nanoaod {
         throw cms::Exception("LogicError", "Duplicated column: " + name);
       if (values.size() != size())
         throw cms::Exception("LogicError", "Mismatched size for " + name);
-      if constexpr (std::is_same<T, bool>()) {
-        columns_.emplace_back(name, docString, ColumnType::Bool, uint8s_.size());
-        uint8s_.insert(uint8s_.end(), values.begin(), values.end());
-      } else if constexpr (std::is_same<T, float>()) {
-        columns_.emplace_back(name, docString, ColumnType::Float, floats_.size());
-        floats_.insert(floats_.end(), values.begin(), values.end());
-        flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).bulk(columnData<float>(columns_.size() - 1));
-      } else {
-        ColumnType type = defaultColumnType<T>();
-        auto &vec = bigVector<T>();
-        columns_.emplace_back(name, docString, type, vec.size());
-        vec.insert(vec.end(), values.begin(), values.end());
-      }
+      auto &vec = bigVector<T>();
+      columns_.emplace_back(name, docString, defaultColumnType<T>(), vec.size());
+      vec.insert(vec.end(), values.begin(), values.end());
+      flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).bulk(columnData<T>(columns_.size() - 1));
     }
 
     template <typename T, typename C>
@@ -133,29 +124,27 @@ namespace nanoaod {
         throw cms::Exception("LogicError", "addColumnValue works only for singleton tables");
       if (columnIndex(name) != -1)
         throw cms::Exception("LogicError", "Duplicated column: " + name);
-      if constexpr (std::is_same<T, bool>()) {
-        columns_.emplace_back(name, docString, ColumnType::Bool, uint8s_.size());
-        uint8s_.push_back(value);
-      } else if constexpr (std::is_same<T, float>()) {
-        columns_.emplace_back(name, docString, ColumnType::Float, floats_.size());
-        floats_.push_back(flatTableHelper::MaybeMantissaReduce<float>(mantissaBits).one(value));
-      } else {
-        ColumnType type = defaultColumnType<T>();
-        auto &vec = bigVector<T>();
-        columns_.emplace_back(name, docString, type, vec.size());
-        vec.push_back(value);
-      }
+      auto &vec = bigVector<T>();
+      columns_.emplace_back(name, docString, defaultColumnType<T>(), vec.size());
+      vec.push_back(flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).one(value));
     }
 
     void addExtension(const FlatTable &extension);
 
+    template <class T>
+    struct dependent_false : std::false_type {};
     template <typename T>
     static ColumnType defaultColumnType() {
-      if constexpr (std::is_same<T, int>())
+      if constexpr (std::is_same<T, float>())
+        return ColumnType::Float;
+      else if constexpr (std::is_same<T, int>())
         return ColumnType::Int;
-      if constexpr (std::is_same<T, uint8_t>())
+      else if constexpr (std::is_same<T, uint8_t>())
         return ColumnType::UInt8;
-      throw cms::Exception("unsupported type");
+      else if constexpr (std::is_same<T, bool>())
+        return ColumnType::Bool;
+      else
+        static_assert(dependent_false<T>::value, "unsupported type");
     }
 
     // this below needs to be public for ROOT, but it is to be considered private otherwise
@@ -170,23 +159,30 @@ namespace nanoaod {
 
   private:
     template <typename T>
-    typename std::vector<T>::const_iterator beginData(unsigned int column) const {
-      const Column &col = columns_[column];
-      return bigVector<T>().begin() + col.firstIndex;
+    auto beginData(unsigned int column) const {
+      return bigVector<T>().cbegin() + columns_[column].firstIndex;
     }
     template <typename T>
-    typename std::vector<T>::iterator beginData(unsigned int column) {
-      const Column &col = columns_[column];
-      return bigVector<T>().begin() + col.firstIndex;
+    auto beginData(unsigned int column) {
+      return bigVector<T>().begin() + columns_[column].firstIndex;
     }
 
     template <typename T>
-    const std::vector<T> &bigVector() const {
-      throw cms::Exception("unsupported type");
+    auto const &bigVector() const {
+      return const_cast<FlatTable *>(this)->bigVector<T>();
     }
     template <typename T>
-    std::vector<T> &bigVector() {
-      throw cms::Exception("unsupported type");
+    auto &bigVector() {
+      if constexpr (std::is_same<T, float>())
+        return floats_;
+      else if constexpr (std::is_same<T, int>())
+        return ints_;
+      else if constexpr (std::is_same<T, uint8_t>())
+        return uint8s_;
+      else if constexpr (std::is_same<T, bool>())
+        return uint8s_;
+      else
+        static_assert(dependent_false<T>::value, "unsupported type");
     }
 
     unsigned int size_;
@@ -198,31 +194,6 @@ namespace nanoaod {
     std::vector<uint8_t> uint8s_;
   };
 
-  template <>
-  inline const std::vector<float> &FlatTable::bigVector<float>() const {
-    return floats_;
-  }
-  template <>
-  inline const std::vector<int> &FlatTable::bigVector<int>() const {
-    return ints_;
-  }
-  template <>
-  inline const std::vector<uint8_t> &FlatTable::bigVector<uint8_t>() const {
-    return uint8s_;
-  }
-  template <>
-  inline std::vector<float> &FlatTable::bigVector<float>() {
-    return floats_;
-  }
-  template <>
-  inline std::vector<int> &FlatTable::bigVector<int>() {
-    return ints_;
-  }
-  template <>
-  inline std::vector<uint8_t> &FlatTable::bigVector<uint8_t>() {
-    return uint8s_;
-  }
-
 }  // namespace nanoaod
 
 #endif
diff --git a/DataFormats/NanoAOD/src/FlatTable.cc b/DataFormats/NanoAOD/src/FlatTable.cc
index b09ea215c98fc..e60b739851796 100644
--- a/DataFormats/NanoAOD/src/FlatTable.cc
+++ b/DataFormats/NanoAOD/src/FlatTable.cc
@@ -20,7 +20,7 @@ void nanoaod::FlatTable::addExtension(const nanoaod::FlatTable& other) {
         addColumn<int>(other.columnName(i), other.columnData<int>(i), other.columnDoc(i));
         break;
       case ColumnType::Bool:
-        addColumn<bool>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
+        addColumn<bool>(other.columnName(i), other.columnData<bool>(i), other.columnDoc(i));
         break;
       case ColumnType::UInt8:
         addColumn<uint8_t>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
@@ -38,7 +38,7 @@ double nanoaod::FlatTable::getAnyValue(unsigned int row, unsigned int column) co
     case ColumnType::Int:
       return *(beginData<int>(column) + row);
     case ColumnType::Bool:
-      return *(beginData<uint8_t>(column) + row);
+      return *(beginData<bool>(column) + row);
     case ColumnType::UInt8:
       return *(beginData<uint8_t>(column) + row);
   }
diff --git a/FWCore/Utilities/interface/Range.h b/FWCore/Utilities/interface/Range.h
index 59fc1a23de9d4..3f9aad861ee23 100644
--- a/FWCore/Utilities/interface/Range.h
+++ b/FWCore/Utilities/interface/Range.h
@@ -16,6 +16,12 @@ namespace edm {
     T end() const { return end_; }
 
     bool empty() const { return begin_ == end_; }
+    auto size() const { return end_ - begin_; }
+
+    auto const& operator[](std::size_t idx) const { return *(begin_ + idx); }
+
+    auto const& front() const { return *begin_; }
+    auto const& back() const { return *(end_ - 1); }
 
   private:
     const T begin_;

From aec5fec895d2a8132913051f0412b5b4d0e789a6 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Tue, 30 Jun 2020 19:10:49 +0200
Subject: [PATCH 6/9] throw exceptions in NanoAOD if column type not supported

---
 DataFormats/NanoAOD/src/FlatTable.cc                | 2 ++
 FWCore/Utilities/interface/Range.h                  | 2 ++
 PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc          | 4 +++-
 PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc | 2 ++
 4 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/DataFormats/NanoAOD/src/FlatTable.cc b/DataFormats/NanoAOD/src/FlatTable.cc
index e60b739851796..85c9d4c699fdc 100644
--- a/DataFormats/NanoAOD/src/FlatTable.cc
+++ b/DataFormats/NanoAOD/src/FlatTable.cc
@@ -25,6 +25,8 @@ void nanoaod::FlatTable::addExtension(const nanoaod::FlatTable& other) {
       case ColumnType::UInt8:
         addColumn<uint8_t>(other.columnName(i), other.columnData<uint8_t>(i), other.columnDoc(i));
         break;
+      default:
+        throw cms::Exception("LogicError", "Unsupported type");
     }
   }
 }
diff --git a/FWCore/Utilities/interface/Range.h b/FWCore/Utilities/interface/Range.h
index 3f9aad861ee23..e876b10334c34 100644
--- a/FWCore/Utilities/interface/Range.h
+++ b/FWCore/Utilities/interface/Range.h
@@ -1,6 +1,8 @@
 #ifndef FWCore_Utilities_Range_h
 #define FWCore_Utilities_Range_h
 
+#include <cstddef>
+
 namespace edm {
   /*
       *class which implements begin() and end() to use range-based loop with
diff --git a/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc b/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
index 0f4c19aadf1af..83159774dbb50 100644
--- a/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
+++ b/PhysicsTools/NanoAOD/plugins/NanoAODDQM.cc
@@ -94,8 +94,10 @@ class NanoAODDQM : public DQMEDAnalyzer {
           vfill<uint8_t>(table, icol, rowsel);
           break;
         case FlatTable::ColumnType::Bool:
-          vfill<uint8_t>(table, icol, rowsel);
+          vfill<bool>(table, icol, rowsel);
           break;
+        default:
+          throw cms::Exception("LogicError", "Unsupported type");
       }
     }
 
diff --git a/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc b/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
index f97ec27439a16..5744b329f7bbf 100644
--- a/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
+++ b/PhysicsTools/NanoAOD/plugins/TableOutputBranches.cc
@@ -25,6 +25,8 @@ void TableOutputBranches::defineBranchesFromFirstEvent(const nanoaod::FlatTable
       case nanoaod::FlatTable::ColumnType::Bool:
         m_uint8Branches.emplace_back(var, tab.columnDoc(i), "O");
         break;
+      default:
+        throw cms::Exception("LogicError", "Unsupported type");
     }
   }
 }

From b6f40d20cdcee1bd69e39592d205059f1f808e9a Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Wed, 1 Jul 2020 23:35:09 +0200
Subject: [PATCH 7/9] Avoid use of const_cast with helper function

---
 DataFormats/NanoAOD/interface/FlatTable.h | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index c0049dcdde2fb..c2be6b19264fd 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -169,18 +169,24 @@ namespace nanoaod {
 
     template <typename T>
     auto const &bigVector() const {
-      return const_cast<FlatTable *>(this)->bigVector<T>();
+      return bigVectorImpl<T>(*this);
     }
     template <typename T>
     auto &bigVector() {
+      return bigVectorImpl<T>(*this);
+    }
+
+    template <typename T, class This>
+    static auto &bigVectorImpl(This &table) {
+      // helper function to avoid code duplication, for the two accessor functions that differ only in const-ness
       if constexpr (std::is_same<T, float>())
-        return floats_;
+        return table.floats_;
       else if constexpr (std::is_same<T, int>())
-        return ints_;
+        return table.ints_;
       else if constexpr (std::is_same<T, uint8_t>())
-        return uint8s_;
+        return table.uint8s_;
       else if constexpr (std::is_same<T, bool>())
-        return uint8s_;
+        return table.uint8s_;
       else
         static_assert(dependent_false<T>::value, "unsupported type");
     }

From 43b9b401fe8c8830294c4c1a28dbfdabaf3ddba6 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Wed, 8 Jul 2020 20:04:28 +0200
Subject: [PATCH 8/9] introduce edm::Span

---
 DataFormats/NanoAOD/interface/FlatTable.h | 14 ++++-----
 FWCore/Utilities/interface/Range.h        |  8 -----
 FWCore/Utilities/interface/Span.h         | 37 +++++++++++++++++++++++
 3 files changed, 44 insertions(+), 15 deletions(-)
 create mode 100644 FWCore/Utilities/interface/Span.h

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index c2be6b19264fd..e7f62817bc99d 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -3,7 +3,7 @@
 
 #include "DataFormats/Math/interface/libminifloat.h"
 #include "FWCore/Utilities/interface/Exception.h"
-#include "FWCore/Utilities/interface/Range.h"
+#include "FWCore/Utilities/interface/Span.h"
 
 #include <cstdint>
 #include <vector>
@@ -17,8 +17,8 @@ namespace nanoaod {
     struct MaybeMantissaReduce {
       MaybeMantissaReduce(int mantissaBits) {}
       inline T one(const T &val) const { return val; }
-      template <typename Range>
-      inline void bulk(Range &&data) const {}
+      template <typename Span>
+      inline void bulk(Span &&data) const {}
     };
     template <>
     struct MaybeMantissaReduce<float> {
@@ -27,8 +27,8 @@ namespace nanoaod {
       inline float one(const float &val) const {
         return (bits_ > 0 ? MiniFloatConverter::reduceMantissaToNbitsRounding(val, bits_) : val);
       }
-      template <typename Range>
-      inline void bulk(Range &&data) const {
+      template <typename Span>
+      inline void bulk(Span &&data) const {
         if (bits_ > 0)
           MiniFloatConverter::reduceMantissaToNbitsRounding(bits_, data.begin(), data.end(), data.begin());
       }
@@ -69,14 +69,14 @@ namespace nanoaod {
     template <typename T>
     auto columnData(unsigned int column) const {
       auto begin = beginData<T>(column);
-      return edm::Range(begin, begin + size_);
+      return edm::Span(begin, begin + size_);
     }
 
     /// get a column by index (non-const)
     template <typename T>
     auto columnData(unsigned int column) {
       auto begin = beginData<T>(column);
-      return edm::Range(begin, begin + size_);
+      return edm::Span(begin, begin + size_);
     }
 
     /// get a column value for singleton (const)
diff --git a/FWCore/Utilities/interface/Range.h b/FWCore/Utilities/interface/Range.h
index e876b10334c34..59fc1a23de9d4 100644
--- a/FWCore/Utilities/interface/Range.h
+++ b/FWCore/Utilities/interface/Range.h
@@ -1,8 +1,6 @@
 #ifndef FWCore_Utilities_Range_h
 #define FWCore_Utilities_Range_h
 
-#include <cstddef>
-
 namespace edm {
   /*
       *class which implements begin() and end() to use range-based loop with
@@ -18,12 +16,6 @@ namespace edm {
     T end() const { return end_; }
 
     bool empty() const { return begin_ == end_; }
-    auto size() const { return end_ - begin_; }
-
-    auto const& operator[](std::size_t idx) const { return *(begin_ + idx); }
-
-    auto const& front() const { return *begin_; }
-    auto const& back() const { return *(end_ - 1); }
 
   private:
     const T begin_;
diff --git a/FWCore/Utilities/interface/Span.h b/FWCore/Utilities/interface/Span.h
new file mode 100644
index 0000000000000..9d4f16b2b17e8
--- /dev/null
+++ b/FWCore/Utilities/interface/Span.h
@@ -0,0 +1,37 @@
+#ifndef FWCore_Utilities_Span_h
+#define FWCore_Utilities_Span_h
+
+#include <cstddef>
+
+namespace edm {
+  /*
+      *An edm::Span wraps begin() and end() iterators to a contiguous sequence
+      of objects with the first element of the sequence at position zero,
+      In other words the iterators should refer to random-access containers.
+
+      To be replaced with std::Span in C++20.
+      */
+
+  template <class T>
+  class Span {
+  public:
+    Span(T begin, T end) : begin_(begin), end_(end) {}
+
+    T begin() const { return begin_; }
+    T end() const { return end_; }
+
+    bool empty() const { return begin_ == end_; }
+    auto size() const { return end_ - begin_; }
+
+    auto const& operator[](std::size_t idx) const { return *(begin_ + idx); }
+
+    auto const& front() const { return *begin_; }
+    auto const& back() const { return *(end_ - 1); }
+
+  private:
+    const T begin_;
+    const T end_;
+  };
+};  // namespace edm
+
+#endif

From 4dbd8d19cf3ab08f3c6d8525d96943c6a12fee49 Mon Sep 17 00:00:00 2001
From: Jonas Rembser <jonas.rembser@cern.ch>
Date: Tue, 21 Jul 2020 14:23:35 +0200
Subject: [PATCH 9/9] change unneeded universal reference to const&

---
 DataFormats/NanoAOD/interface/FlatTable.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/DataFormats/NanoAOD/interface/FlatTable.h b/DataFormats/NanoAOD/interface/FlatTable.h
index e7f62817bc99d..3a3934cc7dafe 100644
--- a/DataFormats/NanoAOD/interface/FlatTable.h
+++ b/DataFormats/NanoAOD/interface/FlatTable.h
@@ -18,7 +18,7 @@ namespace nanoaod {
       MaybeMantissaReduce(int mantissaBits) {}
       inline T one(const T &val) const { return val; }
       template <typename Span>
-      inline void bulk(Span &&data) const {}
+      inline void bulk(Span const &data) const {}
     };
     template <>
     struct MaybeMantissaReduce<float> {