Long friendship list delays compiled macro execution

Dear root experts

I have an input root file with several trees, called ch0…ch9

I do each tree friends of each other to be able to do some arithmetics. In reality I only need each channel to be made friends with only one other tree at a time.

I found that when the list of friends of the current tree grows, so does the execution time. I have the following code:

#include <iostream>
#include <vector>

#include "TFile.h"
#include "TTree.h"
#include "TString.h"
#include "TStyle.h"
#include "TSystem.h"
#include "TH1.h"
#include "TH2.h"
#include "TLegend.h"
#include "TMath.h"

void Alignment( TString fnm ) {
  TFile *fin = new TFile( fnm ) ;
  //Signal threshold
  vector<Double_t> vVmin ;

    vVmin.push_back(0.02)  ; //ch0
    vVmin.push_back(0.02)  ; //ch1
    vVmin.push_back(0.02)  ; //ch2
    vVmin.push_back(0.02)  ; //ch3
    vVmin.push_back(0.02)  ; //ch4
    vVmin.push_back(0.02)  ; //ch5
    vVmin.push_back(0.00)  ; //ch6
    vVmin.push_back(0.05)  ; //ch7
    vVmin.push_back(0.05)  ; //ch8
    vVmin.push_back(0.05)  ; //ch9
  Int_t NPads=vVmin.size()     ;
  vector<TTree *> vch ;
  for (Int_t it=0;it<NPads;it++) {
   TTree *tree = (TTree *) fin->Get( Form("ch%d",it) ) ;
   vch.push_back( tree ) ;
  Int_t Nevs = vch[0]->GetEntries();
  TH1D *h = new TH1D("h","",100,0,Nevs) ;
  TH2D *hal = new TH2D("hal","alignment",NPads, -0.5,NPads-0.5,NPads, -0.5,NPads-0.5) ;
  for ( Int_t ix=0 ; ix<NPads ; ix++ ) {
    for ( Int_t iy=0 ; iy<ix ; iy++ ) {
      if (ix==iy) continue;
      vch[ix]->AddFriend( vch[iy],Form("ch%d",iy) );
      TString sel = Form( "NPeaks==1 && -(Vmin-BlineMean)<%f && ch%d->NPeaks==1 && -(ch%d->Vmin-ch%d->BlineMean)<%f" , vVmin[ix] , iy ,iy,iy,vVmin[iy]);
      vch[ix]->Draw("event>>h",sel,"goff") ;
      Int_t ncoinc = TMath::Nint( h->GetEntries() ) ;
      hal->SetBinContent(ix+1,iy+1,ncoinc) ;
      cout<<"Done ... h("<<ix<<","<<iy<<")="<<ncoinc<<endl;
      TTree *oldfr = (TTree*) vch[ix]->GetListOfFriends()->FindObject(Form("ch%d",iy));

When the last 2 lines in the loop (those containing “TTree *oldfr” and “Remove(oldfr)”) are there the execution takes few seconds. Without these 2 lines, the execution took almost 1 h.

Is this a normal behaviour? Why a long list of friends does slow down the execution even if only 2 of those trees are involved each time?

Thank you very much


Please read tips for efficient and successful posting and posting code

Please fill also the fields below. Note that root -b -q will tell you this info, and starting from 6.28/06 upwards, you can call .forum bug from the ROOT prompt to pre-populate a topic.

_ROOT Version: 6.24/08
_Platform: Ubuntu 22.04.4 LTS
_Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0

Hi Marcos,

Without the remove, each tree becomes direct friends with all the other trees. In addition the friendship is transitive. Each Draw then need to search through all the trees in the list of friends (present at that time) to find the branch corresponding to the identifiers in the selection. Because of the transitivity (even-though there is a mechanism to avoid circular iteration) this means that for each search (at the end), we need to look at the main tree and its 9 friends, for each of those friends we need to look at its 9 friends (and so on until the anti-circular iteration mechanism kicks in) … so roughly 9^9 …

Instead you could use just:

 for ( Int_t ix=1 ; ix<NPads ; ix++ )
   vch[0]->AddFriend( vch[ix],Form("ch%d",ix) );
TString sel = Form( "ch%d->NPeaks==1 && -(ch%d->Vmin-ch%d->BlineMean)<%f && ch%d->NPeaks==1 && -(ch%d->Vmin-ch%d->BlineMean)<%f" , ix, ix, ix, vVmin[ix] , iy ,iy,iy,vVmin[iy]);
vch[0]->Draw("event>>h",sel,"goff") ;

i.e. simply use the fact that the name of each of the tree is different to find the right branches without having to modify the list of friends.b

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