Error in executing simple code for a TTree with TClonesArray Branches

Hello, I am facing a problem in running a simple code on ROOT . The TTree(“LHEF”) was generated using MG5 .I am trying to plot a histogram giving invariant mass of all the particles in the TBranch(or TTree). The TBranch (named “Particles”) is a TClonesArray containing particle objects (where ‘M’ is one of the leaf) and there are 10000 events in all.
Following is the code:

#include "iostream"
#include "TH1F.h"
#include "TStyle.h"
#include "TCanvas.h"
#include "TLorentzVector.h"
#include "TClonesArray.h"
#include "TFile.h"
#include "TTree.h"
using namespace std;
void mass()
{

TFile *hfile = new TFile("unweighted.root","read");
TTree *LHEF=(TTree*)hfile->Get("LHEF");

LHEF->SetBranchStatus("*",0);
LHEF->SetBranchStatus("Particle.M",1);
LHEF->SetBranchStatus("Event_size",1);
Long64_t nentries = LHEF->GetEntries();

Double_t *Particle_M[8];

LHEF->SetBranchAddress("Particle.M",Particle_M);
TH1F *invm = new TH1F("H_invmass","GeV",100,0,150);
Double_t k;
for (Int_t i=0; i<10000;i++) 
{
LHEF->GetEntry(i);
for (Int_t j=0; j<8 ;j++)
{
k=*(Particle_M[j]);
cout<< Particle_M[j]<<endl;
invm->Fill(k);
}
cout<<i<<endl;
}
invm->Draw();

}

I get an output with 80000 entries(same for histogram) all near zero(sort of junk values):(Following are the last two entries displayed)

9997
2.24415e-316
9.74242e-233
1.69855e-313
6.95268e-310
9.57008e-317
5.66304e+74
6.93664e-310
6.93664e-310
9998
2.24415e-316
9.74242e-233
1.69855e-313
6.95268e-310
9.57008e-317
5.66304e+74
6.93664e-310
6.93664e-310
9999

And their histogram when actually using LHEF->Draw(“M”) or LHEF->Draw(“Partcicle.M”) gives me a plot (as expected) of signal of higgs to 4 leptons (that is what the TTree consisted of!)

So what is wrong with the code?

Please help.

Thank you in advance!

You need to loop over the actual, entry specific, size of the array, so try something like: for (Int_t j = 0; j < Particle->GetEntriesFast(); j++)

Sir, the following error message gets displayed:
error: member reference base type ‘Double_t *’
(aka ‘double *’) is not a structure or union
for (Int_t j = 0; j < Particle_M->GetEntriesFast(); j++)
~~~~~~~~~~^ ~~~~~~~~~~~~~~

Most likely you might have meant the branch “Particles” is a TClonesArray containing particle objects.

To set a sub-branch is that type of case to a array of double, you need to set the TTree or at the least the branch in MakeClass mode.

It may actually be easier in your case to use ROOT v6 and a TTreeReader object.

Cheers,
Philippe.

1 Like

Thanks! I have edited the post. I tried to solve this issue by using MakeClass but I am getting two errors while loading the makeclass.c file :
error: invalid use of non-static data
member 'kMaxParticle’
Int_t Particle_Status[kMaxParticle]; //[Particle_]
^~~~~~~~~~~~
error: invalid use of non-static data
member 'kMaxParticle’
Int_t Particle_Mother1[kMaxParticle]; //[Particle_]
^~~~~~~~~~~~
And so on for Declaration of all Leaf types from the header file.Also I get an error:
use of undeclared identifier
’hfile’
hfile = new TFile(“unweighted.root”, “RECREATE”, “ROOT histograms”);
^
even though the class TTree is included in the header file.

So how should I go about from here…

Make your root file available somewhere so that one can “inspect” it.

here is the link to the .root file.

Sir, even if I make a MakeFile and load it without making any changes to it, still the above mentioned errors get displayed.

Thanking youunweighted.h (9.9 KB)
unweighted.C (2.4 KB)
Here are Makefiles generated using the TTree uploaded(code for histogram plotting was added by me)

LHEF.h (9.8 KB)
LHEF.C (2.1 KB)

1 Like

Thanks a lot Sir. Also I tried to get the same plot(for the same .root file/TTree) using class TTreeReader as suggested by Phillipe Sir (@pcanal) but I am getting an error in loading it. I am attaching the .c file of the code written by me. The error message which gets displayed is : error:
indirection requires pointer operand (‘TTreeReaderArray’ invalid)
{ double k = *(ParticleM)
^~~~~~~~~~~~
tests.c (657 Bytes)

Thank you in advance!

Which version of ROOT are you using?

Cheers,
Philippe.

PS. When mentioning MakeClass I meant to say that adding

LHEF->SetMakeClass(true);

should have been enough.

1 Like

The ROOT version is 6.08/00. Sir, on using the command you gave me, the moment I complete the second ‘for’ loop(i.e. looping over all entries, I get a huge written error of which the last statements are : Error in HandleInterpreterException>: Trying to dereference null pointer or trying to call routine taking non-null arguments.
Execution of your code was aborted.
ROOT_prompt_49:1:4: warning: null passed to a callee that requires a non-null argument [-Wnonnull]
k=*(Particle_M[j]);
^~~~~~~~~~~~~~~
Also Sir, could you also help me to correct the code I wrote using TTrreReader object which I had attached to my previous reply…

Thanking you,
Krunal

Actually I think that in both case you need use the line

j = Particle_M[j];

(i.e. why use the operator star?)

Cheers,
Philippe.

1 Like

With refernce to the usage of C++ code which I had written(file attached:massclass.c) -
On removing the star , I get the error : error: assigning to ‘Double_t’ (aka ‘double’) from incompatible type ‘Double_t *’
(aka ‘double *’); dereference with *
k=(Particle_M[j]);
^~~~~~~~~~~~~~~~
*
And on putting the star back, the system crashes while the execution. I am attaching the .c file for your refernce.

With reference to the usage of TTreeReader object (file:tests.c) I am encountering following error while loading it:
error: no viable conversion from ‘TTreeReaderArray’ to ‘double’
double k = ParticleM
^ ~~~~~~~~~

Sir, I had attached the DropBox link in one of my replies which had the .root file with the TTree in it.
Thanking you
Krunal

tests.c (663 Bytes)
massclass.c (803 Bytes)

As an important side note, this statement is actually incorrect. The number of particles in the file you provide is often 8 but is also sometimes 7 and, ‘worse’, sometimes 9 (which means that if you use a fixed size array of 8 to read the date you will get memory over-write and hence crashes).

Cheers,
Philippe.

1 Like

TTree::MakeClass has a fatal problem in ROOT v6. It is fixed by updating the header file produced with

// Fixed size dimensions of array or collections stored in the TTree if any.
   static constexpr Int_t kMaxEvent = 1;
   static constexpr Int_t kMaxRwgt = 1;
   static constexpr Int_t kMaxParticle = 9;

This has been fixed in the master branch.

Note that MakeClass is per se deprecated and using TTree::MakeSelector works much better.

Cheers,
Philippe.

1 Like

In your original source, the array of double was incorrectly defined. Rather than

Double_t *Particle_M[8];

you meant

Double_t Particle_M[9]; // remove start and increase size

In your use of the TTreeReaderArray, the following works:

         Double_t k = ParticleM.At(j);

It was also missing the loop of the elements:

      for (size_t j=0; j< ParticleM.GetSize() ;j++)
      {
         Double_t k = ParticleM.At(j);
         invm->Fill(k);
      }

See attached file an example of working code.

Cheers,
Philippe.

t1.C (1.6 KB)

1 Like

Thanks a lot Philippe Sir (as well as @Wile_E_Coyote Sir) for your help. Now, all the codes ( original C++ code, using MakeClass and using TTreeReader object) are working fine. I did learn a lot. Once again thank you for help :slight_smile:
Krunal

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