58 class Buffer:
public IBuffer
61 Buffer(VariableFillers& vars, TTree&
tt,
const std::string&
name);
68 class VBuf:
public IBuffer
72 VBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
73 const std::string&
name,
T default_value =
T());
81 class VVBuf:
public IBuffer
84 VVBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
85 const std::string&
name, T default_value =
T());
88 std::vector<std::vector<T> >*
m_buffer;
129 std::vector<std::unique_ptr<IBuffer> > buffers;
132 std::set<std::string> skipped;
143 std::vector<size_t> idx_dummy;
151 std::vector<size_t>
idx(1,0);
155 std::vector<size_t> idx2(2,0);
160 TIter
next(
tt.GetListOfLeaves());
162 std::set<std::string> leaf_names;
163 while ((leaf =
dynamic_cast<TLeaf*
>(
next()))) {
164 leaf_names.insert(leaf->GetName());
166 if (leaf_names.size() == 0)
throw std::logic_error(
"no branches found");
172 tt.SetBranchStatus(
"*",
false);
173 for (
const auto& lname: leaf_names) {
175 if (
opts.branch_regex.size() > 0) {
176 keep = std::regex_search(lname, branch_filter);
179 std::cout << (
keep ?
"found " :
"rejecting ") << lname << std::endl;
183 leaf =
tt.GetLeaf(lname.c_str());
184 std::string branchName = leaf->GetBranch()->GetName();
185 std::string leaf_type = leaf->GetTypeName();
186 if (leaf_type ==
"Int_t") {
187 buffers.emplace_back(
new Buffer<int>(vars,
tt, branchName));
188 }
else if (leaf_type ==
"Float_t") {
189 buffers.emplace_back(
new Buffer<float>(vars,
tt, branchName));
190 }
else if (leaf_type ==
"Double_t") {
191 buffers.emplace_back(
new Buffer<double>(vars,
tt, branchName));
192 }
else if (leaf_type ==
"Bool_t") {
193 buffers.emplace_back(
new Buffer<bool>(vars,
tt, branchName));
194 }
else if (leaf_type ==
"Long64_t") {
195 buffers.emplace_back(
new Buffer<long long>(vars,
tt, branchName));
196 }
else if (leaf_type ==
"ULong64_t") {
197 buffers.emplace_back(
new Buffer<unsigned long long>(vars,
tt, branchName));
198 }
else if (leaf_type ==
"UInt_t") {
199 buffers.emplace_back(
new Buffer<unsigned int>(vars,
tt, branchName));
200 }
else if (leaf_type ==
"UChar_t") {
201 buffers.emplace_back(
new Buffer<unsigned char>(vars,
tt, branchName));
202 }
else if (leaf_type ==
"vector<float>") {
203 buffers.emplace_back(
new VBuf<float>(vars2d,
idx,
tt, branchName, NAN));
204 }
else if (leaf_type ==
"vector<double>") {
205 buffers.emplace_back(
new VBuf<double>(vars2d,
idx,
tt, branchName, NAN));
206 }
else if (leaf_type ==
"vector<int>") {
207 buffers.emplace_back(
new VBuf<int>(vars2d,
idx,
tt, branchName, 0));
208 }
else if (leaf_type ==
"vector<unsigned int>") {
209 buffers.emplace_back(
new VBuf<unsigned int>(vars2d,
idx,
tt, branchName, 0));
210 }
else if (leaf_type ==
"vector<unsigned char>") {
211 buffers.emplace_back(
new VBuf<unsigned char>(vars2d,
idx,
tt, branchName, 0));
212 }
else if (leaf_type ==
"vector<bool>") {
213 buffers.emplace_back(
new VBuf<bool>(vars2d,
idx,
tt, branchName, 0));
214 }
else if (leaf_type ==
"vector<vector<int> >") {
215 buffers.emplace_back(
new VVBuf<int>(vars3d, idx2,
tt, branchName, 0));
216 }
else if (leaf_type ==
"vector<vector<unsigned int> >") {
217 buffers.emplace_back(
new VVBuf<unsigned int>(vars3d, idx2,
tt, branchName, 0));
218 }
else if (leaf_type ==
"vector<vector<unsigned char> >") {
219 buffers.emplace_back(
new VVBuf<unsigned char>(vars3d, idx2,
tt, branchName, 0));
220 }
else if (leaf_type ==
"vector<vector<float> >") {
221 buffers.emplace_back(
new VVBuf<float>(vars3d, idx2,
tt, branchName, NAN));
222 }
else if (leaf_type ==
"vector<vector<double> >") {
223 buffers.emplace_back(
new VVBuf<double>(vars3d, idx2,
tt, branchName, NAN));
224 }
else if (leaf_type ==
"vector<vector<bool> >") {
225 buffers.emplace_back(
new VVBuf<bool>(vars3d, idx2,
tt, branchName, 0));
227 skipped.insert(leaf_type);
238 const std::string tree_name =
tt.GetName();
240 std::unique_ptr<WriterXd> writer1d;
241 std::unique_ptr<WriterXd> writer2d;
242 std::unique_ptr<WriterXd> writer3d;
243 std::unique_ptr<H5::Group> top_group;
244 if (
opts.vector_lengths.size() > 0) {
245 if (
opts.vector_lengths.size() > 2)
throw std::logic_error(
246 "we don't support outputs with rank > 3");
248 top_group.reset(
new H5::Group(fg.createGroup(tree_name)));
249 if (
opts.vector_lengths.size() > 1) {
250 size_t length2 =
opts.vector_lengths.at(1);
251 if (vars3d.size() > 0) {
252 writer3d.reset(
new WriterXd(*top_group,
"3d", vars3d,
256 if (vars2d.size() > 0) {
257 writer2d.reset(
new WriterXd(*top_group,
"2d", vars2d,
260 if (vars.size() > 0) {
261 writer1d.reset(
new WriterXd(*top_group,
"1d",
262 vars, {},
opts.chunk_size));
265 if (vars.size() > 0) {
266 writer1d.reset(
new WriterXd(fg, tree_name, vars, {},
opts.chunk_size));
277 std::string cut_string =
opts.selection;
278 const char * cut_char = cut_string.c_str();
279 TTreeFormula *
cut =0;
280 if(!cut_string.empty()){
283 tt.SetBranchStatus(
"*",
true);
284 cut =
new TTreeFormula(
"selection", cut_char, &
tt);
287 size_t n_entries =
tt.GetEntries();
289 int print_interval =
opts.print_interval;
290 if (print_interval == -1) {
291 print_interval =
std::max(1UL, n_entries / 100);
294 for (
size_t iii = 0; iii < n_entries; iii++) {
295 if (print_interval && (iii % print_interval == 0)) {
296 std::cout <<
"events processed: " << iii
298 << n_entries <<
")" << std::endl;
301 if(
cut)
cut->UpdateFormulaLeaves();
311 if (writer1d) writer1d->
flush();
312 if (writer2d) writer2d->
flush();
313 if (writer3d) writer3d->
flush();
318 for (
const auto&
name: skipped) {
319 std::cerr <<
"could not read branch of type " <<
name << std::endl;
330 template <
typename T>
332 const std::string&
name)
334 tt.SetBranchStatus(
name.c_str(),
true);
337 vars.add<T>(
name, [&buf](){
return buf;});
341 template <
typename T>
342 VBuf<T>::VBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
343 const std::string&
name, T default_value):
346 tt.SetBranchStatus(
name.c_str(),
true);
349 auto filler = [&
buf, &
idx, default_value]() -> T {
350 if (
idx.at(0) <
buf.size()) {
353 return default_value;
356 vars.add<
T>(
name, filler);
358 template <
typename T>
365 template <
typename T>
366 VVBuf<T>::VVBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
367 const std::string&
name,
T default_value):
370 tt.SetBranchStatus(
name.c_str(),
true);
373 auto filler = [&
buf, &
idx, default_value]() -> T {
374 size_t idx1 =
idx.at(0);
375 size_t idx2 =
idx.at(1);
376 if (idx1 <
buf.size()) {
377 if (idx2 <
buf.at(idx1).size()) {
378 return buf.at(idx1).at(idx2);
381 return default_value;
383 vars.add<
T>(
name, filler);
385 template <
typename T>