ASCII file input, Branches and TLorentzVectors

Hi ROOTers,
I would like to read an ASCII file in which every event is stored as

ch_tag, ch_t , delta, plab1x, plab1y, plab1z, plab1e,…,plab4e

and save the events in a TTree with 7 different branches: ch1, ch2, deltaM, par1, par2, par3, par4, where par* are TLorentzVectors.
Here’s my code:

#include "Riostream.h"

void myFunc(TString decayName="4p") {
  //   example of macro to read data from an ascii file and
  //   create a root file with an histogram and an ntuple.
  gROOT->Reset();
  gSystem->Load("libPhysics"); 

  ifstream in;
  // we assume a file basic.dat in the current directory
  // this file has 3 columns of float data
  in.open(decayName+".dat");
  
  Int_t nlines = 0;
  Double_t ch_tag, ch_t, delta;
  Double_t plab1x,plab1y,plab1z,plab1e;
  Double_t plab2x,plab2y,plab2z,plab2e;
  Double_t plab3x,plab3y,plab3z,plab3e;
  Double_t plab4x,plab4y,plab4z,plab4e;
  
  TLorentzVector *plab1 = new TLorentzVector();
  TLorentzVector *plab2 = new TLorentzVector();
  TLorentzVector *plab3 = new TLorentzVector();
  TLorentzVector *plab4 = new TLorentzVector();
  
  TFile *f = new TFile("test"+decayName+"s.root","RECREATE");
  TTree *myTree = new TTree("myTree","data from "+decayName);
  myTree->Branch("ch_tag.",&ch_tag,"ch_tag/D");
  myTree->Branch("ch_t.",&ch_t,"ch_t/D");
  myTree->Branch("delta.",&delta,"delta/D");
  myTree->Branch("par1","TLorentzVector",&plab1,32000,0);
  myTree->Branch("par2","TLorentzVector",&plab2,32000,0);
  myTree->Branch("par3","TLorentzVector",&plab3,32000,0);
  myTree->Branch("par4","TLorentzVector",&plab4,32000,0);

  while (1) {
    in >> ch_tag >> ch_t >> delta >>
      plab1x >> plab1y >> plab1z >> plab1e >>
      plab2x >> plab2y >> plab2z >> plab2e >>
      plab3x >> plab3y >> plab3z >> plab3e >>
      plab4x >> plab4y >> plab4z >> plab4e;
    if (!in.good()) break;

    plab1->SetPxPyPzE(plab1x,plab1y,plab1z,plab1e);
    plab2->SetPxPyPzE(plab2x,plab2y,plab2z,plab2e);
    plab3->SetPxPyPzE(plab3x,plab3y,plab3z,plab3e);
    plab4->SetPxPyPzE(plab4x,plab4y,plab4z,plab4e);
    
    myTree->Fill();
    nlines++;
  }
  printf(" read %d events\n",nlines);

  in.close();
  
  f->Write();
}

in root I load the function

# .L myFunc.cc
# myFunc()
 read # events
#

But when I look into the ntuple with a TBrowser, many Leaves into the par# branches are not readable, taking me to a Segmentation Violation.
Where am I wrong?

Hi,

The Tree is bound (when you can TTree::Branch) to local variables of your function. To use the TTree object after the end of the function you must call myTree->ResetBranchAddresses();just before the end of the function.

Cheers,
Philippe

Also please do not use gROOT->Reset();from within a function; this unloads all script loaded since the start of your ROOT session including the function being executed …

Hi Philippe,
I tried to implement your hint, but I still can’t get what I want.
I can use the Lorentz Vectors in my analysis building a Class with MakeClass(I could do it also before applying your hint), but it seems strange to me that using TBrowser i can see the leaves for LorentzVector invariant mass or component, but I can’t use them.
Fortunately is not a problem for my analysis, but what I want to understand is if am I doing something wrong or it is the typical behaviour of Object such a TLorentzVector in trees.
Thank you

Maurizio

Hi,

MakeClass explicitly flatten out the data organization of your TTree into ints, floats, doubles, etc. and you can not use objects. To tweak the MakeClass to be able to use only objects you need to remove the line SetMakeClass(1) in the produced code. You may want to consider use TTree::MakeProxy instead; MakeProxy will allow both the data member access and the object access without tweaks.

Cheers,
Philippe.