I have a problem regarding root trees through PyRoot.
I have created 3 branches which correspond to 3 numpy arrays with approximately 85 values in it. I am looping through a folder of files and I am hoping that I am able to put an array of values to represent individual leaf of the branch. In other words, each individual file has a single array of values in a branch call. The total number of entries should be the number of files in the tree rather than each individual datapoint.
How do I do this?
The code currently has problems where there are 30 entries as expected. However, inside the entry branches, each branch returns a singular value with each value being 0 rather than an entire array.
f = ROOT.TFile("tree.root", "recreate")
t = ROOT.TTree( 't1', 'tree with histos' )
//I created a structure to reference as a memory address which may be a mistake?
ROOT.gROOT.ProcessLine(
"struct tc_t {\
Double_t var_vol;\
Double_t var_time;\
Int_t var_res;\
}" )
tc = ROOT.tc_t()
//Loop through the files
for i in range(files_total):
... Prior calculations on file
........................................
//Below, the second parameters of np_time_values and np_voltage_values are numpy python arrays of type float and type int for resistance_value_i
time_values_c = array.array('d', np_time_values )
voltage_values_c = array.array('d', np_voltage_values)
resistance_value_i_c = array.array('i', resistance_value_i)
//The below prints confirmed the arrays were returning values I expected i.e. ~85 values of unique values or repeating in case of resistance_values
print run_count
print time_values_c
print voltage_values_c
print resistance_value_i_c
t.Branch('time_values',time_values_c,'time_values/D')
t.Branch('voltage_values',voltage_values_c,'voltage_values/D')
t.Branch('resistance_values',resistance_value_i_c,'resistance_values/I')
t.SetBranchAddress("voltage_values",ROOT.AddressOf(tc, 'var_vol'))
t.SetBranchAddress("time_values",ROOT.AddressOf(tc, 'var_time'))
t.SetBranchAddress("resistance_values",ROOT.AddressOf(tc, 'var_res'))
t.Fill()
............ End of File Loop
f.Write()
f.Fill()
so you have N*3 files, each containing an array. You would like to have a TTree with N entries and 3 branches therefore storing for each entry 3 arrays, which come from 3 different files. Is this correct?
I have a subjective amount of files I’m looping through in a folder.
Each File has around ~85 data points in an array. Each individual branch entry I am hoping for it to be an array such that I can access each entry as an individual array. There are 3 branches for each file representing voltages, times, and resistances that should correlate to each other as an individual file.
In more clarity, if I have 90 files in the folder, I hope to have 90 entries where each entry (individual file) has 3 branches of voltages, times, and resistances and is condensed into a single array. If I call t->GetEntry(0), I hope to be able to call an array out of it in C++ using a format similar to as follows:
TFile f(“tree.root”);
TTree t = (TTree)f.Get(“t1”);
Int_t n_data_points_total = (Int_t)t->GetEntries();
Double_t* Voltage = new Double_t[n_data_points_total];
Double_t* Time_ = new Double_t[n_data_points_total];
Double_t* Resistance = new Double_t[n_data_points_total];
for (Int_t i=0; i < t->GetEntries(); i++)
{
t->GetEntry(i);
Voltage[i] = var_vol;
Time_[i] = var_time;
Resistance[i] = var_res;
}
In the above code, I would hope that Voltage[0], Resistance[0], Time_[0] are all arrays of values that correlate with the first file, the second file correlates with an array in Voltage[1], Resistance[1], Time_[1], etc.
There are not 3 files as I am looping through a folder of N size to get through. There are 3 branches but an N amount of entries.
I apologize for not being clear in my initial statement. Let me know if I am still being unclear.
Hi Aaron, What you need then is to have 3 arrays for each TTree entry (one per file in the directory). I have changed a bit the PyROOT code to achieve it.
import ROOT
import numpy as np
import array
f = ROOT.TFile("tree.root", "recreate")
t = ROOT.TTree( 't1', 'tree with vectors' )
ROOT.gInterpreter.ProcessLine("""
struct tc_t {
std::vector<Double_t> var_vol {30};
std::vector<Double_t> var_time {30};
std::vector<Int_t> var_res {30};
void set_vol(Double_t* v, size_t len) {var_vol.assign(v,v+len);}
void set_time(Double_t* v, size_t len) {var_time.assign(v,v+len);}
void set_res(Int_t* v, size_t len) {var_res.assign(v,v+len);}
};
""" )
tc = ROOT.tc_t()
t.Branch('values',tc)
files_total = 10
#---Loop through the files
for i in range(files_total):
#---Get the np arrays from somewhere...
np_time_values = np.linspace(0.,100.,30)
np_voltage_values = np.fromfunction(lambda i: i * i, (30,))
np_resistance_values = array.array('i',np.ones(30,dtype=int)) # Cannot use np arrays of 'integers' directly. It is bug :-()
print np_time_values
print np_voltage_values
print np_resistance_values
tc.set_vol(np_voltage_values, len(np_voltage_values))
tc.set_time(np_time_values, len(np_time_values))
tc.set_res(np_resistance_values, len(np_resistance_values))
t.Fill()
t.Write()