CMS 3D CMS Logo

TableOutputFields.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_NanoAOD_TableOutputFields_h
2 #define PhysicsTools_NanoAOD_TableOutputFields_h
3 
4 #include "RNTupleFieldPtr.h"
5 
9 
10 #include <algorithm>
11 
12 #include <ROOT/RNTuple.hxx>
13 #include <ROOT/RNTupleModel.hxx>
14 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
15 using ROOT::Experimental::RCollectionNTupleWriter;
16 #else
17 #include <ROOT/RNTupleCollectionWriter.hxx>
18 using ROOT::Experimental::RNTupleCollectionWriter;
19 #endif
20 using ROOT::Experimental::RNTupleModel;
21 using ROOT::Experimental::RNTupleWriter;
22 
23 template <typename T>
25 public:
26  FlatTableField() = default;
27  FlatTableField(const nanoaod::FlatTable& table, std::size_t i, RNTupleModel& model) {
28  m_flatTableName = table.columnName(i);
29  // case 1: field has a name (table may or may not have a name)
30  if (!table.columnName(i).empty()) {
31  m_field = RNTupleFieldPtr<T>(table.columnName(i), table.columnDoc(i), model);
32  return;
33  }
34  // case 2: field doesn't have a name: use the table name as the RNTuple field name
35  if (table.name().empty()) {
36  throw cms::Exception("LogicError", "Empty FlatTable name and field name");
37  }
38  m_field = RNTupleFieldPtr<T>(table.name(), table.doc(), model);
39  }
40  // For collection fields and singleton fields
41  void fill(const nanoaod::FlatTable& table, std::size_t i) {
42  int col_idx = table.columnIndex(m_flatTableName);
43  if (col_idx == -1) {
44  throw cms::Exception("LogicError", "Missing column in input for " + table.name() + "_" + m_flatTableName);
45  }
46  m_field.fill(table.columnData<T>(col_idx)[i]);
47  }
48  // For vector fields without a collection, we have to buffer the results
49  // internally and then fill the RNTuple field
51  int col_idx = table.columnIndex(m_flatTableName);
52  if (col_idx == -1) {
53  throw cms::Exception("LogicError", "Missing column in input for " + table.name() + "_" + m_flatTableName);
54  }
55  std::vector<typename T::value_type> buf(table.size());
56  for (std::size_t i = 0; i < table.size(); i++) {
57  buf[i] = table.columnData<typename T::value_type>(col_idx)[i];
58  }
59  m_field.fill(buf);
60  }
61  const std::string& getFlatTableName() const { return m_flatTableName; }
62 
63 private:
66 };
67 
69 public:
70  TableOutputFields() = default;
72  void print() const;
73  void createFields(const edm::EventForOutput& event, RNTupleModel& model);
74  void fillEntry(const nanoaod::FlatTable& table, std::size_t i);
75  const edm::EDGetToken& getToken() const;
76 
77 private:
79  std::vector<FlatTableField<float>> m_floatFields;
80  std::vector<FlatTableField<int>> m_intFields;
81  std::vector<FlatTableField<std::uint8_t>> m_uint8Fields;
82  std::vector<FlatTableField<bool>> m_boolFields;
83 };
84 
86 public:
87  TableOutputVectorFields() = default;
89  void createFields(const edm::EventForOutput& event, RNTupleModel& model);
90  void fill(const edm::EventForOutput& event);
91 
92 private:
94  std::vector<FlatTableField<std::vector<float>>> m_vfloatFields;
95  std::vector<FlatTableField<std::vector<int>>> m_vintFields;
96  std::vector<FlatTableField<std::vector<std::uint8_t>>> m_vuint8Fields;
97  std::vector<FlatTableField<std::vector<bool>>> m_vboolFields;
98 };
99 
101 public:
102  TableCollection() = default;
103  // Invariants:
104  // * table has a non-empty base name
105  // * table has at least one column
106  void add(const edm::EDGetToken& table_token, const nanoaod::FlatTable& table);
107  // Invariants:
108  // * m_main not null
109  // * m_collectionName not empty
110  void createFields(const edm::EventForOutput& event, RNTupleModel& eventModel);
111  void fill(const edm::EventForOutput& event);
112  void print() const;
113  bool hasMainTable();
114  const std::string& getCollectionName() const;
115 
116 private:
118 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 31, 0)
119  std::shared_ptr<RCollectionNTupleWriter> m_collection;
120 #else
121  std::shared_ptr<RNTupleCollectionWriter> m_collection;
122 #endif
124  std::vector<TableOutputFields> m_extensions;
125 };
126 
128 public:
129  void add(const edm::EDGetToken& table_token, const nanoaod::FlatTable& table);
130  void createFields(const edm::EventForOutput& event, RNTupleModel& eventModel);
131  void fill(const edm::EventForOutput& event);
132  void print() const;
133 
134 private:
135  // Returns true if the FlatTable has an anonymous column. Throws a cms::Exception
136  // if there is more than one anonymous column.
137  static bool hasAnonymousColumn(const nanoaod::FlatTable& table);
138  std::vector<TableCollection> m_collections;
139  std::vector<TableOutputFields> m_singletonFields;
140  std::vector<TableOutputVectorFields> m_vectorFields;
141 };
142 
143 #endif
RNTupleFieldPtr< T > m_field
TableOutputVectorFields()=default
void fillEntry(const nanoaod::FlatTable &table, std::size_t i)
TableOutputFields m_main
const edm::EDGetToken & getToken() const
TableOutputFields(const edm::EDGetToken &token)
TableOutputVectorFields(const edm::EDGetToken &token)
std::vector< TableOutputFields > m_singletonFields
TableCollection()=default
std::vector< FlatTableField< std::vector< float > > > m_vfloatFields
void createFields(const edm::EventForOutput &event, RNTupleModel &eventModel)
FlatTableField()=default
edm::EDGetToken m_token
std::vector< FlatTableField< bool > > m_boolFields
std::string m_collectionName
std::shared_ptr< RNTupleCollectionWriter > m_collection
std::vector< FlatTableField< std::vector< bool > > > m_vboolFields
const std::string & getCollectionName() const
std::vector< FlatTableField< std::uint8_t > > m_uint8Fields
void fill(const edm::EventForOutput &event)
std::vector< TableOutputVectorFields > m_vectorFields
std::vector< TableOutputFields > m_extensions
std::vector< FlatTableField< int > > m_intFields
const std::string & getFlatTableName() const
std::vector< FlatTableField< std::vector< int > > > m_vintFields
std::string m_flatTableName
void createFields(const edm::EventForOutput &event, RNTupleModel &model)
std::vector< FlatTableField< float > > m_floatFields
void fill(const edm::EventForOutput &event)
void add(const edm::EDGetToken &table_token, const nanoaod::FlatTable &table)
FlatTableField(const nanoaod::FlatTable &table, std::size_t i, RNTupleModel &model)
static bool hasAnonymousColumn(const nanoaod::FlatTable &table)
void add(const edm::EDGetToken &table_token, const nanoaod::FlatTable &table)
std::vector< FlatTableField< std::vector< std::uint8_t > > > m_vuint8Fields
void fill(const edm::EventForOutput &event)
long double T
std::vector< TableCollection > m_collections
void createFields(const edm::EventForOutput &event, RNTupleModel &model)
void fill(const nanoaod::FlatTable &table, std::size_t i)
void createFields(const edm::EventForOutput &event, RNTupleModel &eventModel)
void fillVectored(const nanoaod::FlatTable &table)
Definition: event.py:1
TableOutputFields()=default