57 class Buffer:
public IBuffer
60 Buffer(VariableFillers& vars, TTree&
tt,
const std::string&
name);
67 class VBuf:
public IBuffer
71 VBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
72 const std::string&
name,
T default_value =
T());
80 class VVBuf:
public IBuffer
83 VVBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
84 const std::string&
name, T default_value =
T());
87 std::vector<std::vector<T> >*
m_buffer;
128 std::vector<std::unique_ptr<IBuffer> > buffers;
131 std::set<std::string> skipped;
142 std::vector<size_t> idx_dummy;
150 std::vector<size_t>
idx(1,0);
154 std::vector<size_t> idx2(2,0);
159 TIter
next(
tt.GetListOfLeaves());
161 std::set<std::string> leaf_names;
162 while ((leaf =
dynamic_cast<TLeaf*
>(
next()))) {
163 leaf_names.insert(leaf->GetName());
165 if (leaf_names.size() == 0)
throw std::logic_error(
"no branches found");
171 tt.SetBranchStatus(
"*",
false);
172 for (
const auto& lname: leaf_names) {
174 if (
opts.branch_regex.size() > 0) {
175 keep = std::regex_search(lname, branch_filter);
178 std::cout << (
keep ?
"found " :
"rejecting ") << lname << std::endl;
182 leaf =
tt.GetLeaf(lname.c_str());
183 std::string branchName = leaf->GetBranch()->GetName();
184 std::string leaf_type = leaf->GetTypeName();
185 if (leaf_type ==
"Int_t") {
186 buffers.emplace_back(
new Buffer<int>(vars,
tt, branchName));
187 }
else if (leaf_type ==
"Float_t") {
188 buffers.emplace_back(
new Buffer<float>(vars,
tt, branchName));
189 }
else if (leaf_type ==
"Double_t") {
190 buffers.emplace_back(
new Buffer<double>(vars,
tt, branchName));
191 }
else if (leaf_type ==
"Bool_t") {
192 buffers.emplace_back(
new Buffer<bool>(vars,
tt, branchName));
193 }
else if (leaf_type ==
"Long64_t") {
194 buffers.emplace_back(
new Buffer<long long>(vars,
tt, branchName));
195 }
else if (leaf_type ==
"ULong64_t") {
196 buffers.emplace_back(
new Buffer<unsigned long long>(vars,
tt, branchName));
197 }
else if (leaf_type ==
"UInt_t") {
198 buffers.emplace_back(
new Buffer<unsigned int>(vars,
tt, branchName));
199 }
else if (leaf_type ==
"UChar_t") {
200 buffers.emplace_back(
new Buffer<unsigned char>(vars,
tt, branchName));
201 }
else if (leaf_type ==
"vector<float>") {
202 buffers.emplace_back(
new VBuf<float>(vars2d,
idx,
tt, branchName, NAN));
203 }
else if (leaf_type ==
"vector<double>") {
204 buffers.emplace_back(
new VBuf<double>(vars2d,
idx,
tt, branchName, NAN));
205 }
else if (leaf_type ==
"vector<int>") {
206 buffers.emplace_back(
new VBuf<int>(vars2d,
idx,
tt, branchName, 0));
207 }
else if (leaf_type ==
"vector<unsigned int>") {
208 buffers.emplace_back(
new VBuf<unsigned int>(vars2d,
idx,
tt, branchName, 0));
209 }
else if (leaf_type ==
"vector<unsigned char>") {
210 buffers.emplace_back(
new VBuf<unsigned char>(vars2d,
idx,
tt, branchName, 0));
211 }
else if (leaf_type ==
"vector<bool>") {
212 buffers.emplace_back(
new VBuf<bool>(vars2d,
idx,
tt, branchName, 0));
213 }
else if (leaf_type ==
"vector<vector<int> >") {
214 buffers.emplace_back(
new VVBuf<int>(vars3d, idx2,
tt, branchName, 0));
215 }
else if (leaf_type ==
"vector<vector<unsigned int> >") {
216 buffers.emplace_back(
new VVBuf<unsigned int>(vars3d, idx2,
tt, branchName, 0));
217 }
else if (leaf_type ==
"vector<vector<unsigned char> >") {
218 buffers.emplace_back(
new VVBuf<unsigned char>(vars3d, idx2,
tt, branchName, 0));
219 }
else if (leaf_type ==
"vector<vector<float> >") {
220 buffers.emplace_back(
new VVBuf<float>(vars3d, idx2,
tt, branchName, NAN));
221 }
else if (leaf_type ==
"vector<vector<double> >") {
222 buffers.emplace_back(
new VVBuf<double>(vars3d, idx2,
tt, branchName, NAN));
223 }
else if (leaf_type ==
"vector<vector<bool> >") {
224 buffers.emplace_back(
new VVBuf<bool>(vars3d, idx2,
tt, branchName, 0));
226 skipped.insert(leaf_type);
237 const std::string tree_name =
tt.GetName();
239 std::unique_ptr<WriterXd> writer1d;
240 std::unique_ptr<WriterXd> writer2d;
241 std::unique_ptr<WriterXd> writer3d;
242 std::unique_ptr<H5::Group> top_group;
243 if (
opts.vector_lengths.size() > 0) {
244 if (
opts.vector_lengths.size() > 2)
throw std::logic_error(
245 "we don't support outputs with rank > 3");
247 top_group.reset(
new H5::Group(fg.createGroup(tree_name)));
248 if (
opts.vector_lengths.size() > 1) {
249 size_t length2 =
opts.vector_lengths.at(1);
250 if (vars3d.size() > 0) {
251 writer3d.reset(
new WriterXd(*top_group,
"3d", vars3d,
255 if (vars2d.size() > 0) {
256 writer2d.reset(
new WriterXd(*top_group,
"2d", vars2d,
259 if (vars.size() > 0) {
260 writer1d.reset(
new WriterXd(*top_group,
"1d",
261 vars, {},
opts.chunk_size));
264 if (vars.size() > 0) {
265 writer1d.reset(
new WriterXd(fg, tree_name, vars, {},
opts.chunk_size));
276 std::string cut_string =
opts.selection;
277 const char * cut_char = cut_string.c_str();
278 TTreeFormula *
cut =0;
279 if(!cut_string.empty()){
282 tt.SetBranchStatus(
"*",
true);
283 cut =
new TTreeFormula(
"selection", cut_char, &
tt);
286 size_t n_entries =
tt.GetEntries();
288 int print_interval =
opts.print_interval;
289 if (print_interval == -1) {
290 print_interval =
std::max(1UL, n_entries / 100);
293 for (
size_t iii = 0; iii < n_entries; iii++) {
294 if (print_interval && (iii % print_interval == 0)) {
295 std::cout <<
"events processed: " << iii
297 << n_entries <<
")" << std::endl;
300 if(
cut)
cut->UpdateFormulaLeaves();
310 if (writer1d) writer1d->
flush();
311 if (writer2d) writer2d->
flush();
312 if (writer3d) writer3d->
flush();
317 for (
const auto&
name: skipped) {
318 std::cerr <<
"could not read branch of type " <<
name << std::endl;
329 template <
typename T>
331 const std::string&
name)
333 tt.SetBranchStatus(
name.c_str(),
true);
336 vars.add<T>(
name, [&buf](){
return buf;});
340 template <
typename T>
341 VBuf<T>::VBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
342 const std::string&
name, T default_value):
345 tt.SetBranchStatus(
name.c_str(),
true);
348 auto filler = [&
buf, &
idx, default_value]() -> T {
349 if (
idx.at(0) <
buf.size()) {
352 return default_value;
355 vars.add<
T>(
name, filler);
357 template <
typename T>
364 template <
typename T>
365 VVBuf<T>::VVBuf(VariableFillers& vars, std::vector<size_t>&
idx, TTree&
tt,
366 const std::string&
name,
T default_value):
369 tt.SetBranchStatus(
name.c_str(),
true);
372 auto filler = [&
buf, &
idx, default_value]() -> T {
373 size_t idx1 =
idx.at(0);
374 size_t idx2 =
idx.at(1);
375 if (idx1 <
buf.size()) {
376 if (idx2 <
buf.at(idx1).size()) {
377 return buf.at(idx1).at(idx2);
380 return default_value;
382 vars.add<
T>(
name, filler);
384 template <
typename T>