HDTree  0.5.2
HDTree C++ API
Tree.h
1 #pragma once
2 
3 #include "hdtree/Branch.h"
4 
5 namespace hdtree {
6 
10 class Tree {
11  public:
12  static Tree load(const std::string& file_path, const std::string& tree_path);
13  static Tree save(const std::string& file_path, const std::string& tree_path);
14  static Tree inplace(const std::string& file_path,
15  const std::string& tree_path);
16  static Tree transform(const std::pair<std::string, std::string>& src,
17  const std::pair<std::string, std::string>& dest);
18 
22  template <typename DataType>
23  Branch<DataType>& branch(const std::string& branch_name) {
24  if (branches_.find(branch_name) != branches_.end()) {
25  throw HDTreeException(
26  "Branch named '" + branch_name + "' was already initialized.",
27  "This usually originates from more than one call to `tree.branch` "
28  "and/or `tree.get` with the same input branch name.");
29  }
30  if (not writer_) {
31  throw HDTreeException(
32  "Attempting to sprout a new branch without writing.",
33  "While it could make sense to have a \"tracking\" branch that "
34  "only exists in memory, HDTree has decided to not support that.\n"
35  "You should not call `tree.branch` on a tree that is not going "
36  "to be writing its data into an output file.");
37  }
38  branches_[branch_name] = std::make_unique<Branch<DataType>>(branch_name);
39  branches_[branch_name]->attach(*writer_);
40  return dynamic_cast<Branch<DataType>&>(*branches_[branch_name]);
41  }
42 
46  template <typename DataType>
47  const Branch<DataType>& get(const std::string& branch_name,
48  bool write = false) {
49  if (not reader_) {
50  throw HDTreeException(
51  "Attempting to 'get' a branch without reading.",
52  "There is no reference for a tree to know how to retrieve a "
53  "branch for you if there is no input file to try to get a branch "
54  "from. Make sure you've loaded a tree if you wish to 'get' a branch."
55  );
56  }
57  if (branches_.find(branch_name) != branches_.end()) {
58  throw HDTreeException(
59  "Branch named '" + branch_name + "' was already initialized.",
60  "This usually originates from more than one call to `tree.branch` "
61  "and/or `tree.get` with the same input branch name.");
62  }
63  branches_[branch_name] = std::make_unique<Branch<DataType>>(branch_name);
64  branches_[branch_name]->attach(*reader_);
65  if (not inplace_ and writer_ and write)
66  branches_[branch_name]->attach(*writer_);
67  return dynamic_cast<Branch<DataType>&>(*branches_[branch_name]);
68  }
69 
80  template <class UnaryFunction>
81  void for_each(UnaryFunction body) {
82  if (not reader_) {
83  throw HDTreeException(
84  "No reader configured, so I don't know how many entries to loop for.",
85  "While the 'for_each' helper function is useful for trees being read "
86  "from a file, WITHOUT an input file, YOU must decide how many entries "
87  "will be in the tree.\n"
88  "REMEMBER: make sure to call tree.save() whenever you want an entry "
89  "to be stored (for example at the end of the body of a for-loop)."
90  );
91  }
92  for (std::size_t i{0}; i < this->entries_; i++) {
93  this->load();
94  body();
95  this->save();
96  }
97  }
98 
110  void save();
111 
117  void load();
118 
119  private:
124  Tree(const std::pair<std::string, std::string>& src,
125  const std::pair<std::string, std::string>& dest);
126 
127  private:
129  std::unordered_map<std::string, std::unique_ptr<BaseBranch>> branches_;
131  std::optional<std::size_t> entries_;
133  std::unique_ptr<Reader> reader_;
135  std::unique_ptr<Writer> writer_;
137  bool inplace_{false};
138 };
139 
140 } // namespace hdtree
Common include for users interacting with Branches.
General data set.
Definition: GeneralBranch.h:46
user-facing exception class for hdtree
Definition: Exception.h:15
A container for many branches.
Definition: Tree.h:10
Branch< DataType > & branch(const std::string &branch_name)
Create a new branch on the tree.
Definition: Tree.h:23
void load()
start-of-event call back
Definition: Tree.cxx:35
const Branch< DataType > & get(const std::string &branch_name, bool write=false)
get a branch, this only really makes sense if reading
Definition: Tree.h:47
Tree(const std::pair< std::string, std::string > &src, const std::pair< std::string, std::string > &dest)
The tree constructor is private because it is complicated, use the static factory functions for acces...
Definition: Tree.cxx:39
std::unordered_map< std::string, std::unique_ptr< BaseBranch > > branches_
the branches in this tree
Definition: Tree.h:129
bool inplace_
are we reading from and writing to the same file?
Definition: Tree.h:137
std::optional< std::size_t > entries_
the number of entries in this tree (if reading from a file)
Definition: Tree.h:131
void save()
end-of-event call back
Definition: Tree.cxx:27
std::unique_ptr< Reader > reader_
reader if loading from a file
Definition: Tree.h:133
void for_each(UnaryFunction body)
loop over all entries in the tree, executing the provided function on each call
Definition: Tree.h:81
std::unique_ptr< Writer > writer_
writer if writing to a file
Definition: Tree.h:135
Geant4 does a GLOBAL definition of the keyword TRUE.
Definition: Atomic.cxx:3