Copying specific leaves from one file to another

I have a root file with a single tree named “Board” with 4 branches named p1, p2, p3 and p4, all have the same structure, that is several leavws, among which I am interested in 3 of them. I want to create another root file where I want to copy only 3 branches p1, p2 and p3 from the old file with only 3 leaves, old names of those leaves are: “CT”, “BT” and “ET”. How can I achieve that?

Thanks

Root version 5.34/36
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Ubuntu 16.04.4 LTS


ROOT Version (e.g. 6.12/02):
Platform, compiler (e.g. CentOS 7.3, gcc6.2):


Hi,
in your terminal, you can use rooteventselector to copy subsets of trees from a ROOT file to another.
You can check the usage with rooteventselector --help.
You can also use rooteventselector from a bash script.

If that doesn’t cut it, you can use TDataFrame to easily manipulate datasets from a C++ or python program:

#include <ROOT/TDataFrame.hxx>
using namespace ROOT::Experimental; // TDF lives here (until ROOT v6.14)

int main() {
  TDataFrame df("treename", "filename.root");
  df.Snapshot("newtree", "newfile.root", {"CT", "BT", "ET"});
  return 0;
}

Hope this helps! Check out TDataFrame’s tutorials for more documented, working examples.

Cheers,
Enrico

1 Like

Hi Enrico,

thanks very much for your answer. I tried your code on my root-5.34/36, didn’t compile but worked on 6.13/02, It compiled well but I get this error

What(): Column "CT" is not in a file and has not been defined.
Aborted (core dumped)

And thanks for the links, I am going through the tutorial right now.

Thanks

Hi,
TDataFrame is a fairly recent addition to ROOT and is available since ROOT v6.10 (with many of the features actually added in v6.12, and more coming in v6.14). So it’s expected that v5.34 does not have it.

Regarding the error: TDataFrame does not find a leaf named "CT". Maybe that’s because the full name is something like "branchname.CT"?

Cheers,
Enrico

Right! Stupid me. Of course I should have tried that. It seems like working, the root file is too big (9 GB) so I expect it to take some time.

Thanks a lot

Good,
you can test that your program is doing what you want by running on just the first e.g. 1000 events:

  TDataFrame df("treename", "filename.root");
  df.Range(1000).Snapshot("newtree", "newfile.root", {"CT", "BT", "ET"});

Cheers,
Enrico

Great. Is there also a way to apply conditions? Like greater than certain value etc.

Hi,
it should be obvious from the user guide I linked in my first answer (if it’s not, let us know!):

// select "good" values, e.g. only the ones greater than 0.
bool IsGood(double x) { return x > 0.; }

int main() {
  TDataFrame d("treename", "fname.root");
  df.Filter(IsGood, {"columnName"}).Snapshot("newtree", "newfname.root", "columnName");
  return 0;

Cheers,
Enrico

1 Like

Thanks Enrico for all the help… I really appreciate, I was exactly reading about filters just after posting the last reply, but as I rarely use c++ or root, things are not that obvious for me yet but I am trying to learn.

Don’t worry!
If you are more comfortable with python you can see from the tutorials I linked above that most functionality is available in pyROOT:

import ROOT as R
df = R.TDataFrame("treename", "fname.root")
df.Filter("branch0 > 0.").Snapshot("newtree", "newfname.root", {"branch0", "branch1"})

Feel free ask your questions as new posts in this forum!
Cheers,
Enrico

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.