Jpp  master_rocky
the software that should make you happy
JTreeWriter.hh
Go to the documentation of this file.
1 #ifndef __JROOT__JTREEWRITER__
2 #define __JROOT__JTREEWRITER__
3 
4 #pragma GCC diagnostic push
5 #pragma GCC diagnostic ignored "-Wall"
6 #include "TTree.h"
7 #include "TBranch.h"
8 #pragma GCC diagnostic pop
9 
10 #include "JIO/JSerialisable.hh"
11 #include "JLang/JException.hh"
12 #include "JROOT/JRootClass.hh"
14 #include "JROOT/JTreeParameters.hh"
15 #include "TRealData.h"
16 
17 namespace JROOT {}
18 namespace JPP { using namespace JROOT; }
19 
20 /**
21  * \file
22  * TTree writing for template data type.
23  * \author mdejong
24  */
25 namespace JROOT {
26 
27  using JIO::JReader;
28  using JLANG::JException;
29 
30 
31  /**
32  * Auxiliary class for default template TTree writing.
33  */
34  template<class T, bool flat = false>
35  class JTreeWriter :
36  public virtual TTree,
37  public JTreeParameters
38  {
39  public:
40  /**
41  * Constructor.
42  *
43  * Note that the default TTree parameters are obtained using method JROOT::getTreeParameters.
44  *
45  * \param parameters parameters of TTree
46  */
47  JTreeWriter(const JTreeParameters& parameters = JROOT::getTreeParameters<T>()) :
48  JTreeParameters(parameters),
49  address(NULL)
50  {
51  SetNameTitle(this->getTreeName(), this->getTreeTitle());
52 
53  branch = Branch(this->getBranchName(),
54  T::Class_Name(),
55  &address,
56  this->getBasketSize(),
57  this->getSplitLevel());
58 
59  branch->SetCompressionLevel(this->getCompressionLevel());
60  }
61 
62 
63  /**
64  * Get the pointer to the unique TBranch belonging this TTree.
65  *
66  * \return pointer to TBranch
67  */
68  const TBranch* GetBranch() const
69  {
70  return branch;
71  }
72 
73 
74  /**
75  * Data object output equivalent of TTree::Fill().
76  *
77  * \param object data object
78  * \return as TTree::Fill
79  */
80  Int_t Write(const T& object)
81  {
82  address = &object;
83 
84  return this->Fill();
85  }
86 
87  protected:
88  using TTree::GetBranch;
89  using TTree::Write;
90 
91  private:
92  TBranch* branch; //!< Pointer to unique branch belonging to this TTree.
93  const T* address; //!< Pointer to unique object belonging to this TTree.
94  };
95 
96 
97  /**
98  * Template specialisation for flat template TTree writing.
99  */
100  template<class T>
101  class JTreeWriter<T, true> : public virtual TTree
102  {
103  public:
104  /**
105  * Constructor.
106  *
107  * \param parameters parameters of TTree
108  */
109  JTreeWriter(const JTreeParameters& parameters)
110  {
111  SetNameTitle(parameters.getTreeName(), parameters.getTreeTitle());
112 
113  // if more than one branch, check those are the data members of T
114 
115  TClass* t_class = TClass::GetClass<T>();
116 
117  if (t_class == nullptr) {
118  THROW(JException, "Could not get class " << typeid(T).name());
119  }
120 
121  TIter next(t_class->GetListOfRealData());
122  TRealData* data{nullptr};
123  T object;
124 
125  auto* base = reinterpret_cast<uint8_t*>(&object);
126 
127  while ((data = dynamic_cast<TRealData*>(next())) != nullptr) {
128 
129  if (!JRootClass::is_tobject_member(data->GetName())) {
130 
131  auto* member = data->GetDataMember();
132  auto* address = reinterpret_cast<uint8_t*>(base + member->GetOffset());
133  std::string type_name = data->GetDataMember()->GetTypeName();
134 
135  if (member->GetArrayDim() > 0) {
136  type_name += "[]";
137  }
138 
139  std::string type_code = JRootPrimitiveTypes::getTypeCode(type_name);
140 
141  if (type_code.empty()) {
142  THROW(JException, "unknown type " << type_name);
143  }
144 
145  std::string leaf = data->GetName();
146  leaf += "/" + type_code;
147  auto branch = Branch(data->GetName(), address, leaf.c_str());
148 
149  branches_.push_back(branch);
150  offsets_ .push_back(member->GetOffset());
151  }
152  }
153  }
154 
155  /**
156  * Data object output equivalent of TTree::Fill().
157  *
158  * \param object data object
159  * \return as TTree::Fill
160  */
161  Int_t Write(const T& object)
162  {
163  auto* base = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&object));
164 
165  for (size_t i = 0; i < branches_.size(); i++) {
166  branches_[i]->SetAddress(reinterpret_cast<uint8_t*>(base + offsets_[i]));
167  }
168 
169  return this->Fill();
170  }
171 
172  protected:
173  using TTree::Write;
174 
175  private:
177 #if ROOT_VERSION_CODE <= ROOT_VERSION(6,26,0)
179 #else
180  std::vector<Longptr_t> offsets_;
181 #endif
182  };
183 
184  /**
185  * Interface for template TTree writing and copying.
186  */
188  public virtual TTree
189  {
190  /**
191  * Copy data.
192  *
193  * \param in binary reader
194  */
195  virtual Int_t copy(JReader& in) = 0;
196  };
197 
198 
199  /**
200  * Implementation for template TTree writing and copying.
201  * This class implements the JTreeCopyWriter interface.
202  */
203  template<class T>
205  public JTreeWriter<T>,
207  {
208  protected:
209  /**
210  * Constructor.
211  *
212  * \param tree parameters of TTree
213  */
215  JTreeWriter<T>(tree)
216  {}
217 
218 
219  /**
220  * Hide copy constructor.
221  *
222  * \param writer TTree writer object
223  */
225 
226 
227  public:
228  /**
229  * Get reference to unique instance of this class object.
230  *
231  * \return reference to this class object
232  */
234  {
235  static JTreeCopyWriter<T> writer(getTreeParameters<T>());
236 
237  return writer;
238  }
239 
240 
241  /**
242  * Copy data.
243  *
244  * \param in binary reader
245  */
246  virtual Int_t copy(JReader& in) override
247  {
248  in >> object;
249 
250  return static_cast<JTreeWriter<T>&>(*this).Write(object);
251  }
252 
253 
254  protected:
256  };
257 
258 
259  /**
260  * Get the TTree writer and copy for this type of object.
261  *
262  * \return TTree writer and copy for this type of object
263  */
264  template<class T>
266  {
268  }
269 } // namespace JROOT
270 
271 #endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:712
Interface for binary input.
General exception.
Definition: JException.hh:24
Implementation for template TTree writing and copying.
Definition: JTreeWriter.hh:207
virtual Int_t copy(JReader &in) override
Copy data.
Definition: JTreeWriter.hh:246
JTreeCopyWriter(const JTreeCopyWriter< T > &writer)
Hide copy constructor.
static JTreeCopyWriter< T > & getInstance()
Get reference to unique instance of this class object.
Definition: JTreeWriter.hh:233
JTreeCopyWriter(const JTreeParameters &tree)
Constructor.
Definition: JTreeWriter.hh:214
Data structure for TTree parameters.
int getBasketSize() const
Get basket size.
const TString & getBranchName() const
Get TBranch name.
int getCompressionLevel() const
Get compression level.
int getSplitLevel() const
Get split level.
const TString & getTreeName() const
Get TTree name.
const TString & getTreeTitle() const
Get TTree title.
std::vector< TBranch * > branches_
Definition: JTreeWriter.hh:176
JTreeWriter(const JTreeParameters &parameters)
Constructor.
Definition: JTreeWriter.hh:109
std::vector< Long_t > offsets_
Definition: JTreeWriter.hh:178
Int_t Write(const T &object)
Data object output equivalent of TTree::Fill().
Definition: JTreeWriter.hh:161
Auxiliary class for default template TTree writing.
Definition: JTreeWriter.hh:38
JTreeWriter(const JTreeParameters &parameters=JROOT::getTreeParameters< T >())
Constructor.
Definition: JTreeWriter.hh:47
const TBranch * GetBranch() const
Get the pointer to the unique TBranch belonging this TTree.
Definition: JTreeWriter.hh:68
const T * address
Pointer to unique object belonging to this TTree.
Definition: JTreeWriter.hh:93
TBranch * branch
Pointer to unique branch belonging to this TTree.
Definition: JTreeWriter.hh:92
Int_t Write(const T &object)
Data object output equivalent of TTree::Fill().
Definition: JTreeWriter.hh:80
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
JTreeCopyWriter< T > & getTreeCopyWriter()
Get the TTree writer and copy for this type of object.
Definition: JTreeWriter.hh:265
static bool is_tobject_member(const char *name)
Check if name is one of TObject own data members (fBits or fUniqueID, for Root <= 6....
Definition: JRootClass.hh:138
static std::string getTypeCode(const std::string &type_name)
Return the type code (used to create primitive leaves in basic Root tree branches) corresponding to t...
Interface for template TTree writing and copying.
Definition: JTreeWriter.hh:189
virtual Int_t copy(JReader &in)=0
Copy data.