Jpp  master_rocky-40-g5f0272dcd
the software that should make you happy
JDataFrame.hh
Go to the documentation of this file.
1 #ifndef __JROOT__JDATAFRAME__
2 #define __JROOT__JDATAFRAME__
3 
4 #include <string>
5 #include <memory>
6 #include <map>
7 #include <vector>
8 
9 #include "TROOT.h"
10 #include "TClass.h"
11 #include "TDataMember.h"
12 #include "ROOT/RDF/RInterfaceBase.hxx"
13 #include "ROOT/RDataFrame.hxx"
14 
15 #include "JLang/JSingleton.hh"
16 #include "JLang/JException.hh"
17 #include "JTools/JRange.hh"
18 
19 
20 /**
21  * \author mdejong
22  */
23 
24 namespace JROOT {}
25 namespace JPP { using namespace JROOT; }
26 
27 namespace JROOT {
28 
29  using JLANG::JSingleton;
30  using JLANG::JException;
31 
32 
33  /**
34  * Auxiliary class for parsing data from ROOT data frame.
35  */
36  class JDataFrame {
37  public:
38  /**
39  * Type definition for range.
40  */
42 
43  private:
44  /**
45  * Interface for output.
46  */
47  struct JOutput {
48  /**
49  * Virtual destructor.
50  */
51  virtual ~JOutput()
52  {}
53 
54 
55  /**
56  * Get address.
57  *
58  * \param i index
59  * \return address
60  */
61  virtual char* getAddress(const size_t i) = 0;
62 
63 
64  /**
65  * Put value at given index.
66  *
67  * \param i index
68  * \param value value
69  */
70  template<class T>
71  void put(const size_t i, const T& value)
72  {
73  * ((T*) getAddress(i)) = value;
74  }
75  };
76 
77 
78  /**
79  * Interface for parsing data from ROOT data frame to output.
80  */
81  struct JParser {
82  /**
83  * Virtual destructor.
84  */
85  virtual ~JParser()
86  {}
87 
88 
89  /**
90  * Parse data.
91  *
92  * \param in input
93  * \param column column name
94  * \param range range
95  * \param out output
96  * \return number of entries parsed
97  */
98  virtual size_t parse(ROOT::RDataFrame& in, const char* const column, const range_type& range, JOutput& out) const = 0;
99  };
100 
101 
102  /**
103  * Template implementation for parsing data from ROOT data frame to output.
104  */
105  template<class T>
106  struct JParser_t :
107  public JParser
108  {
109  /**
110  * Parse data.
111  *
112  * \param in input
113  * \param column column name
114  * \param range range
115  * \param out output
116  * \return number of entries parsed
117  */
118  virtual size_t parse(ROOT::RDataFrame& in, const char* const column, const range_type& range, JOutput& out) const override
119  {
120  size_t i = 0;
121 
122  in.Range(range.getLowerLimit(), range.getUpperLimit()).Foreach([&](T value) { out.put(i++, value); }, { column });
123 
124  return i;
125  }
126  };
127 
128  public:
129  /**
130  * Dictionary for parsing data from ROOT data frame to output.
131  */
132  struct JDictionary :
133  public std::map<std::string, std::unique_ptr<JParser> >,
134  public JSingleton<JDictionary>
135  {
137  {
138  add<bool>();
139  add<char>();
140  add<unsigned char>();
141  add<short>();
142  add<unsigned short>();
143  add<int>();
144  add<unsigned int>();
145  add<long int>();
146  add<unsigned long int>();
147  add<long long int>();
148  add<unsigned long long int>();
149  add<float>();
150  add<double>();
151  add<std::string>();
152  }
153 
154 
155  /**
156  * Get typename for given template class.
157  *
158  * This method uses the TDictionary class to get the name of the given class.
159  *
160  * \return type name
161  */
162  template<class T>
163  static const char* getTypename()
164  {
165  const TDictionary* pDictionary = TDictionary::GetDictionary(typeid(T));
166 
167  if (pDictionary != NULL)
168  return pDictionary->GetName();
169  else
170  THROW(JException, "Data type not implemented.");
171  }
172 
173 
174  /**
175  * Add parser for given class to dictionary.
176  */
177  template<class T>
178  void add()
179  {
180  (*this)[getTypename<T>()].reset(new JDataFrame::JParser_t<T>());
181  }
182  };
183 
184 
185  /**
186  * Auxiliary buffer for parsing data from ROOT data frame.
187  */
188  template<class T>
189  struct JBuffer :
190  public std::vector<T>
191  {
192  /**
193  * Default constructor.
194  */
196  cs(TClass::GetClass<T>())
197  {
198  if (!cs) {
199  THROW(JException, "Data type not defined via ROOT TClass.");
200  }
201  }
202 
203 
204  /**
205  * Parse data.
206  *
207  * \param in input
208  * \param range range
209  * \return number of entries parsed
210  */
211  size_t operator()(ROOT::RDataFrame& in, const range_type& range)
212  {
213  size_t N = range.getUpperLimit() - range.getLowerLimit();
214 
215  if (N != 0) {
216 
217  this->resize(N);
218 
219  for (const std::string& column : in.GetColumnNames()) {
220 
221  TDataMember* ps = cs->GetDataMember(column.c_str());
222 
223  if (ps != NULL && JDictionary::getInstance().count(ps->GetTypeName()) != 0) {
224 
225  JOutput_t out(*this, ps->GetOffset());
226 
227  N = std::min(N, JDictionary::getInstance()[ps->GetTypeName()]->parse(in, column.c_str(), range, out));
228 
229  } else {
230 
231  THROW(JException, "Data type not implemented for column " << column);
232  }
233  }
234  }
235 
236  return N;
237  }
238 
239  private:
240 
241  TClass* cs = NULL;
242 
243  /**
244  * Template implementation for output.
245  */
246  struct JOutput_t :
247  public JDataFrame::JOutput
248  {
249  /**
250  * Constructor
251  *
252  * \param data data
253  * \param offset offset
254  */
256  data(data),
257  offset(offset)
258  {}
259 
260 
261  /**
262  * Get address.
263  *
264  * \param i index
265  * \return address
266  */
267  virtual char* getAddress(const size_t i) override
268  {
269  return ((char*) &(data[i])) + offset;
270  }
271 
272  private:
274  const int offset;
275  };
276  };
277  };
278 }
279 
280 #endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
Auxiliary class to define a range between two values.
General exception.
Definition: JException.hh:24
Auxiliary class for parsing data from ROOT data frame.
Definition: JDataFrame.hh:36
JTOOLS::JRange< unsigned int > range_type
Type definition for range.
Definition: JDataFrame.hh:41
Range of values.
Definition: JRange.hh:42
T getLowerLimit() const
Get lower limit.
Definition: JRange.hh:202
T getUpperLimit() const
Get upper limit.
Definition: JRange.hh:213
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
Simple singleton class.
Definition: JSingleton.hh:18
static data_type & getInstance()
Get unique instance of template class.
Definition: JSingleton.hh:27
Template implementation for output.
Definition: JDataFrame.hh:248
virtual char * getAddress(const size_t i) override
Get address.
Definition: JDataFrame.hh:267
JOutput_t(std::vector< T > &data, const int offset)
Constructor.
Definition: JDataFrame.hh:255
Auxiliary buffer for parsing data from ROOT data frame.
Definition: JDataFrame.hh:191
size_t operator()(ROOT::RDataFrame &in, const range_type &range)
Parse data.
Definition: JDataFrame.hh:211
JBuffer()
Default constructor.
Definition: JDataFrame.hh:195
Dictionary for parsing data from ROOT data frame to output.
Definition: JDataFrame.hh:135
static const char * getTypename()
Get typename for given template class.
Definition: JDataFrame.hh:163
void add()
Add parser for given class to dictionary.
Definition: JDataFrame.hh:178
Interface for output.
Definition: JDataFrame.hh:47
virtual ~JOutput()
Virtual destructor.
Definition: JDataFrame.hh:51
void put(const size_t i, const T &value)
Put value at given index.
Definition: JDataFrame.hh:71
virtual char * getAddress(const size_t i)=0
Get address.
Template implementation for parsing data from ROOT data frame to output.
Definition: JDataFrame.hh:108
virtual size_t parse(ROOT::RDataFrame &in, const char *const column, const range_type &range, JOutput &out) const override
Parse data.
Definition: JDataFrame.hh:118
Interface for parsing data from ROOT data frame to output.
Definition: JDataFrame.hh:81
virtual size_t parse(ROOT::RDataFrame &in, const char *const column, const range_type &range, JOutput &out) const =0
Parse data.
virtual ~JParser()
Virtual destructor.
Definition: JDataFrame.hh:85