TSelector::Notify question

Hi - I’m running 3.04/02. I’m using a selector in this fashion:

[code] TChain *ntp1 = new TChain(“ntp1”);
ntp1->Add(“myfile1.root/ntp1”);
ntp1->Add(“myfile2.root/ntp1”);
edSelector mySelector();

ntp1->Process(&mySelector);[/code]

where edSelector inherits from TSelector, and inside edSelector::ProcessCut(), I always have the following:

The default selector created from MakeSelector has a whole bunch of code in Notify() related to loading branches.

If the only usage of TSelector is as above, can I just delete all that code in Notify? Thanks.

Hi Ed,

NO, you should not delete this code that recomputes the actual branch pointers and addresses whenever a new file is connected in the TChain.

Rene

Hi Rene - thanks for the response. On a related note, I’ve just discovered another problem, and was wondering if it was due to not having this sort of code.

I’m taking a TTree which is a chain of a couple hundred files, and doing an event selection, saving the output to one file. I’m also computing a few new variables and saving their values as new branches in the TTree. I’ve recently found out that the filtered TTree has incorrect values (compared versus a log file dump, for example). Definitely incorrect in the new branches, but not necessarily in the old branches. The values were subtly wrong enough that the problem wasn’t caught until now, when recently, one filtering job resulted in values of 0.

The example format of the code is this:

void filterTree(TString myOldChain,TString myNewName){

  TString myFullSelect = "chain/"+myOldChain+".cc";
  gROOT->Macro(myFullSelect);

  TString myNewFile = "rfile/"+myNewName;
  TTree *oldtree = ntp1;  // ntp1 created in the chain file
  Int_t nentries = (Int_t)oldtree->GetEntries();

  //Declaration of leaves types
  Int_t           nevent;
  Int_t           neventrun;
 
  fChain    = oldtree;
  fChain->SetMakeClass(1);

  fChain->SetBranchAddress("nevent",&nevent);
  fChain->SetBranchAddress("neventrun",&neventrun);
  fChain->SetBranchStatus("*",0);
  
  fChain->SetBranchStatus("nevent",1);
  fChain->SetBranchStatus("neventrun",1);

  //Create a new file + a clone of old tree in new file
  TFile *newfile = new TFile(myNewFile,"recreate");
  TTree *newtree = oldtree->CloneTree(0);

  Float_t nuEPN;
  
  TBranch * b_nuEPN = newtree->Branch("nuEPN",&nuEPN,"nuEPN/F");
  newtree->AutoSave();

  for (Int_t i=0;i<nentries; i++) {       
      oldtree->GetEntry(i);
      nuEPN = some expression;
        
      if (passes some event selection){
          newtree->Fill();
      }
          
  } // End if for int t
  
  newfile->Write();
  newfile->Close();
  delete newfile;
}

I’m going to try to get a 4 version of ROOT installed at Caltech, so I can try this out on a new version, but nonetheless, is there something I’m doing wrong here that’s causing things to go bad? Do I also need to worry about loading branches like in TSelector::Notify because I have multiple files in my chain? Thanks.

Ed,

If oldtree is a TChain, you should replace the lines:
for (Int_t i=0;i<nentries; i++) {
oldtree->GetEntry(i);
by
for (Int_t i=0;i<nentries; i++) {
if (oldtree->LoadTree(i) < 0) break;
oldtree->GetEntry(i);

Rene

Hi Rene - it actually looks like my problem was due to the following:

My original filter code used:

TTree *newtree = oldtree->CloneTree(0);

but did not have the line:

fChain->SetBranchStatus("*",0);

What I didn’t realize was that the TChain oldtree had a branch with the same name as one of the new branches I was declaring for newtree. So there was some sort of interference going on, which resulted in the strange values I saw in my filtered ntuple.

In addition, it looks like, even though I have multiple files in my TChain, no problems were caused by my lacking the line:

if (oldtree->LoadTree(i) < 0) break;

Not sure why. But I will leave that line in there just in case.

BTW - 4.00/08 seems to read my old ntuples fine so far.

Thanks.