File indexing completed on 2023-10-25 09:39:36
0001 #ifndef DataFormats_NanoAOD_FlatTable_h
0002 #define DataFormats_NanoAOD_FlatTable_h
0003
0004 #include "DataFormats/Math/interface/libminifloat.h"
0005 #include "FWCore/Utilities/interface/Exception.h"
0006 #include "FWCore/Utilities/interface/Span.h"
0007
0008 #include <cstdint>
0009 #include <vector>
0010 #include <string>
0011 #include <type_traits>
0012
0013 namespace nanoaod {
0014
0015 namespace flatTableHelper {
0016 template <typename T>
0017 struct MaybeMantissaReduce {
0018 MaybeMantissaReduce(int mantissaBits) {}
0019 inline T one(const T &val) const { return val; }
0020 template <typename Span>
0021 inline void bulk(Span const &data) const {}
0022 };
0023 template <>
0024 struct MaybeMantissaReduce<float> {
0025 int bits_;
0026 MaybeMantissaReduce(int mantissaBits) : bits_(mantissaBits) {}
0027 inline float one(const float &val) const {
0028 return (bits_ > 0 ? MiniFloatConverter::reduceMantissaToNbitsRounding(val, bits_) : val);
0029 }
0030 template <typename Span>
0031 inline void bulk(Span &&data) const {
0032 if (bits_ > 0)
0033 MiniFloatConverter::reduceMantissaToNbitsRounding(bits_, data.begin(), data.end(), data.begin());
0034 }
0035 };
0036 }
0037
0038 class FlatTable {
0039 public:
0040 enum class ColumnType {
0041 Int8,
0042 UInt8,
0043 Int16,
0044 UInt16,
0045 Int32,
0046 UInt32,
0047 Bool,
0048 Float,
0049 Double,
0050 };
0051
0052 FlatTable() : size_(0) {}
0053 FlatTable(unsigned int size, const std::string &name, bool singleton, bool extension = false)
0054 : size_(size), name_(name), singleton_(singleton), extension_(extension) {}
0055 ~FlatTable() {}
0056
0057 unsigned int nColumns() const { return columns_.size(); };
0058 unsigned int nRows() const { return size_; };
0059 unsigned int size() const { return size_; }
0060 bool singleton() const { return singleton_; }
0061 bool extension() const { return extension_; }
0062 const std::string &name() const { return name_; }
0063
0064 const std::string &columnName(unsigned int col) const { return columns_[col].name; }
0065 int columnIndex(const std::string &name) const;
0066
0067 ColumnType columnType(unsigned int col) const { return columns_[col].type; }
0068
0069 void setDoc(const std::string &doc) { doc_ = doc; }
0070 const std::string &doc() const { return doc_; }
0071 const std::string &columnDoc(unsigned int col) const { return columns_[col].doc; }
0072
0073
0074 template <typename T>
0075 auto columnData(unsigned int column) const {
0076 auto begin = beginData<T>(column);
0077 return edm::Span(begin, begin + size_);
0078 }
0079
0080
0081 template <typename T>
0082 auto columnData(unsigned int column) {
0083 auto begin = beginData<T>(column);
0084 return edm::Span(begin, begin + size_);
0085 }
0086
0087
0088 template <typename T>
0089 const auto &columValue(unsigned int column) const {
0090 if (!singleton())
0091 throw cms::Exception("LogicError", "columnValue works only for singleton tables");
0092 return *beginData<T>(column);
0093 }
0094
0095 double getAnyValue(unsigned int row, unsigned int column) const;
0096
0097 class RowView {
0098 public:
0099 RowView() {}
0100 RowView(const FlatTable &table, unsigned int row) : table_(&table), row_(row) {}
0101 double getAnyValue(unsigned int column) const { return table_->getAnyValue(row_, column); }
0102 double getAnyValue(const std::string &column) const {
0103 return table_->getAnyValue(row_, table_->columnIndex(column));
0104 }
0105 const FlatTable &table() const { return *table_; }
0106 unsigned int row() const { return row_; }
0107
0108 private:
0109 const FlatTable *table_;
0110 unsigned int row_;
0111 };
0112 RowView row(unsigned int row) const { return RowView(*this, row); }
0113
0114 template <typename T, typename C>
0115 void addColumn(const std::string &name, const C &values, const std::string &docString, int mantissaBits = -1) {
0116 if (columnIndex(name) != -1)
0117 throw cms::Exception("LogicError", "Duplicated column: " + name);
0118 if (values.size() != size())
0119 throw cms::Exception("LogicError", "Mismatched size for " + name);
0120 auto &vec = bigVector<T>();
0121 columns_.emplace_back(name, docString, defaultColumnType<T>(), vec.size());
0122 vec.insert(vec.end(), values.begin(), values.end());
0123 flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).bulk(columnData<T>(columns_.size() - 1));
0124 }
0125
0126 template <typename T, typename C>
0127 void addColumnValue(const std::string &name, const C &value, const std::string &docString, int mantissaBits = -1) {
0128 if (!singleton())
0129 throw cms::Exception("LogicError", "addColumnValue works only for singleton tables");
0130 if (columnIndex(name) != -1)
0131 throw cms::Exception("LogicError", "Duplicated column: " + name);
0132 auto &vec = bigVector<T>();
0133 columns_.emplace_back(name, docString, defaultColumnType<T>(), vec.size());
0134 vec.push_back(flatTableHelper::MaybeMantissaReduce<T>(mantissaBits).one(value));
0135 }
0136
0137 void addExtension(const FlatTable &extension);
0138
0139 template <class T>
0140 struct dependent_false : std::false_type {};
0141 template <typename T>
0142 static ColumnType defaultColumnType() {
0143 if constexpr (std::is_same<T, int8_t>())
0144 return ColumnType::Int8;
0145 else if constexpr (std::is_same<T, uint8_t>())
0146 return ColumnType::UInt8;
0147 else if constexpr (std::is_same<T, int16_t>())
0148 return ColumnType::Int16;
0149 else if constexpr (std::is_same<T, uint16_t>())
0150 return ColumnType::UInt16;
0151 else if constexpr (std::is_same<T, int32_t>())
0152 return ColumnType::Int32;
0153 else if constexpr (std::is_same<T, uint32_t>())
0154 return ColumnType::UInt32;
0155 else if constexpr (std::is_same<T, bool>())
0156 return ColumnType::Bool;
0157 else if constexpr (std::is_same<T, float>())
0158 return ColumnType::Float;
0159 else if constexpr (std::is_same<T, double>())
0160 return ColumnType::Double;
0161 else
0162 static_assert(dependent_false<T>::value, "unsupported type");
0163 }
0164
0165
0166 struct Column {
0167 std::string name, doc;
0168 ColumnType type;
0169 unsigned int firstIndex;
0170 Column() {}
0171 Column(const std::string &aname, const std::string &docString, ColumnType atype, unsigned int anIndex)
0172 : name(aname), doc(docString), type(atype), firstIndex(anIndex) {}
0173 };
0174
0175 private:
0176 template <typename T>
0177 auto beginData(unsigned int column) const {
0178 return bigVector<T>().cbegin() + columns_[column].firstIndex;
0179 }
0180 template <typename T>
0181 auto beginData(unsigned int column) {
0182 return bigVector<T>().begin() + columns_[column].firstIndex;
0183 }
0184
0185 template <typename T>
0186 auto const &bigVector() const {
0187 return bigVectorImpl<T>(*this);
0188 }
0189 template <typename T>
0190 auto &bigVector() {
0191 return bigVectorImpl<T>(*this);
0192 }
0193
0194 template <typename T, class This>
0195 static auto &bigVectorImpl(This &table) {
0196
0197 if constexpr (std::is_same<T, int8_t>())
0198 return table.int8s_;
0199 else if constexpr (std::is_same<T, uint8_t>())
0200 return table.uint8s_;
0201 else if constexpr (std::is_same<T, int16_t>())
0202 return table.int16s_;
0203 else if constexpr (std::is_same<T, uint16_t>())
0204 return table.uint16s_;
0205 else if constexpr (std::is_same<T, int32_t>())
0206 return table.int32s_;
0207 else if constexpr (std::is_same<T, uint32_t>())
0208 return table.uint32s_;
0209 else if constexpr (std::is_same<T, bool>())
0210 return table.uint8s_;
0211 else if constexpr (std::is_same<T, float>())
0212 return table.floats_;
0213 else if constexpr (std::is_same<T, double>())
0214 return table.doubles_;
0215 else
0216 static_assert(dependent_false<T>::value, "unsupported type");
0217 }
0218
0219 unsigned int size_;
0220 std::string name_, doc_;
0221 bool singleton_, extension_;
0222 std::vector<Column> columns_;
0223 std::vector<int8_t> int8s_;
0224 std::vector<uint8_t> uint8s_;
0225 std::vector<int16_t> int16s_;
0226 std::vector<uint16_t> uint16s_;
0227 std::vector<int32_t> int32s_;
0228 std::vector<uint32_t> uint32s_;
0229 std::vector<float> floats_;
0230 std::vector<double> doubles_;
0231 };
0232
0233 }
0234
0235 #endif