Dear experts,
I’ve been having a problem with working with friends trees and GetEntryWithIndex
.
I have a class CellsProfiler
that I wrote in C++. This class, basically, loops over lots of trees and creates histograms. Moreover, this class was compiled and I made a library that can be called from a python file.
This class takes as input, for example, 2 trees. The main tree has approx 15 branches that I need to read, while for the second one, I’m only interested in 3.
The second tree has almost the same events as the first one, but it has these 3 extra branches that I need. In what they match is in the EventNumber
, so I activate these branches
m_tree_main->SetBranchStatus("EventInfo.eventNumber", 1);
m_tree_cell->SetBranchStatus("EventNumber", 1);
and set as index of the second tree (m_tree_cells
) the branch "EventNumber"
, and then I add them as friends:
m_tree_cell->BuildIndex("EventNumber");
m_tree_main->AddFriend(m_tree_cell);
In order to loop over these trees I created a TTreeReader
object
TTreeReader * m_reader = nullptr; //In CellsProfiler.h
m_reader = new TTreeReader(m_tree_main); //In CellsProfiler.cxx
and set the branches I want to read with TTreeReaderValue<type>
. For example, for the event number branches of both trees I did:
m_eventNumber_main = new TTreeReaderValue<int> (*m_reader, "EventInfo.eventNumber");
m_eventNumber_cell = new TTreeReaderValue<int> (*m_reader, "EventNumber");
So far so good, it loops over events of both trees, as long as **m_eventNumber_cell = **m_eventNumber_main
. However, if they don’t match, I need to look in the second tree for that entry that satisfies that condition. To do so, in my main loop I call the function getSameEntry
while (m_reader->Next()) {
if (!getSameEntry()) {
no_cells_info ++;
continue;
}
if (!isHealthyCluster()) {
not_health_cluster ++;
continue;
}
...
}
And the functions is
bool getSameEntry()
{
/*Check if both trees have the same event with same event-number*/
// First get event numbers
int event_number_main = **m_eventNumber_main;
int event_number_cell = **m_eventNumber_cell;
// //cout << "Enum main="<<event_number_main << " Enum cell="<<event_number_cell << endl;
//vector<float> tmp_E = **m_ph_ClusterCells_7x11_L2_E;
//cout<< "Energy38before="<<tmp_E[38]<<endl;
// Check if they are the same. If they are not, look for the entry in m_tree_cell that
// has the same event number as in m_tree_main
if (event_number_main != event_number_cell) {
int st = m_tree_cell->GetEntryWithIndex(event_number_main);
// cout << "st="<<st<<endl;
if (st<=0) {
return false; // This is for the case it doesn't find any entry in m_tree_cell
}
}
// Recompute cell event number, because it may be changed from the previous if-clause
// with GetEntryWithIndex()
event_number_cell = **m_eventNumber_cell;
// cout << "Enum main="<<**m_eventNumber_main << " Enum cell="<<event_number_cell << endl;
// tmp_E = **m_ph_ClusterCells_7x11_L2_E;
// cout<< "Energy38after="<<tmp_E[38]<<endl;
// Just a check that it's really the same event number
if (event_number_main != event_number_cell) {
return false;
}
return true;
}
It basically checks if both event numbers are the same, and if they aren’t, it looks into m_tree_cell
and searches for the entry that satisfies the previous condition.
The problem is the following. If at the beginning they are not the same event (equal event number), it should change the entry at which m_reader
points in m_tree_cell
, leaving intact the entry at which it points in m_tree_main
. This is the case ONLY INSIDE getSameEntry
AND in the function that called getSameEntry
(i.e. the function that has the main while-loop). However, once I enter another function, m_reader
points to the old entry in m_tree_cell
. I checked that looking at the value of one of the branches of m_tree_cell
inside another function, for example in isHealthyCluster
, and they were indeed, the old ones.
Just to check that’s the case I implemented the same class in python (although super slow) and it works correctly (I can verify it with other methods external to these functions, after the whole loop is finished). The function in python is:
def getSameEntry(self, tree_Main, tree_Cell, entry):
tree_Main.GetEntry(entry)
event_number_main = getattr(tree_Main, 'EventInfo.eventNumber')
event_number_cells = tree_Cell.EventNumber
if (event_number_main != event_number_cells):
st = tree_Cell.GetEntryWithIndex(int(event_number_main))
if st <= 0:
return False
event_number_cells = tree_Cell.EventNumber
if event_number_main != event_number_cells:
return False
# If none of previous if-statements were entered->both entries have the same event number
return True
Does anyone can guess what’s the problem here? I’ve been struggling with this for a whole day and I can’t figure out why this problem appears, or how I can fix it, since I don’t want to loop in python (it’s more than 3x slower)…
Thank you very much for your help!!, and sorry for the long post, I tried to be as detailed as possible…
Cheers,
Francisco
ROOT Version: root 6.20.06-x86_64-centos7-gcc8-op
Platform: lxplus