*Break* segmentation violation and failed to access leaf in array from tree contains CORSIKA data

Hello Everyone,
I have recently started data analysis with ROOT. It is a good platform for data analysis. I have simulated cosmic ray event with CORSIKA which generated binary output file. The .root file contains a TTree “cor” with two branches with some leaves in which all leaves are in array, find a screenshot for cor->Print() below.

I would like to extract the momenta data for each particle ID(for example muon particle ID i.e. PId=6 in CORSIKA program) from the TTree. When I try to run the attached macro in root to get the output nevent, PId and Px. The nevent output is fine but the outputs in array seem break segmentation violation. Is there anything in the code that could be causing the violation? Kindly have a look and help me for that. Any help would be appreciated.
Find the attached macro and violation screenshot.
readfile.cpp (1015 Bytes)

I am running ROOT v6.24/06 on ubuntu 20.04 LTS.

Cheers!
Anil


_ROOT Version: 6.24/06
_Platform: ubuntu 20.04 LTS
Compiler: Not Provided


ROOT::RDataFrame Class Reference + Dataframe tutorials

Thank you @Wile_E_Coyote for replying. I have gone through the links, unfortunately did not get proper way how to access Px[np]/F one is an array leaf of particle branch. After the execuation it breaks. Please have a look into the attached macro screenshot below.

Kindly let me know where I am missing something on that or a proper way to access the array leaf. Will be appreciate.
Thanks!

Try to use source code files generated by (see the new “cor.C” for instructions on how to use them):
root -b -l -q DAT000002.root -e 'cor->MakeClass();'

UPDATE: I’m afraid you need to talk to your colleagues who are familiar with your data. @pcanal The source code generated by the TTree::MakeClass method (and other similar methods) will be broken/misbehaving for all variable size arrays in the non-split “Particle” branch.

Thank you @Wile_E_Coyote . Somehow did not get.

Hii!
I have gone through the links, unfortunately did not get proper way how to access Px[np]/F one is an array leaf of particle branch. Please have a look into the attached macro screenshot below.

How to access Px[np]/F an array leaf of particle branch. Here is the Tree print screenshot. Is there any modification to the code would be appreciated.

Thanks.

Hi Anil,
In your first macro readfile.cpp, which you have attached in the 1st message:
I see two main problems:

  1. You try to define array length of Px and PId to be np size
	Int_t np;
//	Float_t Px[1000000], Py[1000000], Pz[1000000];
	Int_t *PId = new Int_t[np];
    Float_t *Px = new Float_t[np];

At this point np variable is not defined, so array length might appear to be even negative, which doesn’t make a lot of sense.

Instead you should define array length with some constant length large enough, so you are sure, there can’t be more particles in your data.
You even have the correct line in your code commented:
// Float_t Px[1000000], Py[1000000], Pz[1000000]; but I think 1000000 is overkill :slight_smile:.

  1. Inside SetAddress() method you pass a pointer to a pointer, while you should just pass a pointer to the first array element. The array Px is already a pointer type Int_t* by definition of arrays in C++ , so you don’t need to extract its pointer with & operator as you do with &np, its already a pointer. So you should do either SetAddress(Px), or SetAddress(&Px[0]) - take a pointer of the 1st element

Can you check if this version works:

#include <stdio.h>
#include <iostream>
#include "TFile.h"
#include <fstream>
#include "TTree.h"
#include "TH2F.h"
#include "TCanvas.h"
#include "TBranch.h"
#include "TLeaf.h"
#include "TTreeReader.h"
using namespace std;
void readfile()
{
	Int_t np;
    Float_t PId[1000];
	Float_t Px[1000], Py[1000], Pz[1000];

	TFile *f = new TFile("DAT000002.root");
	TTree *tr = (TTree*)f->Get("cor");

	TBranch *b = (TBranch*)tr->GetBranch("Particle");
    b->GetLeaf("np")->SetAddress(&np);
	b->GetLeaf("PId")->SetAddress(PId);
	b->GetLeaf("Px")->SetAddress(Px);

	Int_t nevent = tr->GetEntries();
	cout << nevent << endl;

	for(Int_t i=0; i<nevent; i++){
		tr->GetEntry(i);
        cout << np << endl;
		for(int j=0; j<np; j++){
			if(PId[j]==6){
				cout << PId[j] << Px[j] << endl;
				// break;
			}
		}
    }
}

if not, then it would be helpful, if you attach your root file somewhere, with few events, so we can try to debug your problem.

cheers,
Bohdan

Hi Bohdan,
Thank you for look through this. I try to complied your modified code. The outputs of nEvent and np are fine as my previous one. But it breaks segmentation to execute second for loop output such as PId[j], Px[j].
I have attached the root file as per your reference.
DAT000002.root (121.7 KB)

Have a nice day.
Thanks
Anil

Ok, you do have events with more than 1000 particles, setting array length to e.g. 10 000 works for me w/o any seg. faults.

P.S. I also changed the type of PId, it should be Int_t instead of Float_t.

#include <stdio.h>
#include <iostream>
#include "TFile.h"
#include <fstream>
#include "TTree.h"
#include "TH2F.h"
#include "TCanvas.h"
#include "TBranch.h"
#include "TLeaf.h"
#include "TTreeReader.h"
using namespace std;
void test()
{
	Int_t np;
    Int_t PId[10000];
	Float_t Px[10000], Py[10000], Pz[10000];

	TFile *f = new TFile("DAT000002.root");
	TTree *tr = (TTree*)f->Get("cor");

	TBranch *b = (TBranch*)tr->GetBranch("Particle");
    b->GetLeaf("np")->SetAddress(&np);
	b->GetLeaf("PId")->SetAddress(PId);
	b->GetLeaf("Px")->SetAddress(Px);

	Int_t nevent = tr->GetEntries();
	cout<<"Total numer of events: "<<nevent<<endl;

	for(Int_t i=0; i<nevent; i++){
        cout<<"Event: "<<i+1<<endl;
		tr->GetEntry(i);
        cout<<"Number of particles: "<<np<<endl;
		for(int j=0; j<np; j++){
            cout<<"    Particle: "<<j+1<<endl;
            cout<<"    PID: "<<PId[j]<<"    Px: "<<Px[j]<<endl;
			if(PId[j]==6){
                cout<<"My PID is 6"<<endl;
			}
		}
    }
    cout<<" end "<<endl;
}

The previous seg. fault I observed was caused by the small array length. And it was breaking at the exit of the function after cout<<" end "<<endl;. While reading the data was fine, except some missing particles due to concatenation at 1000

yeah… there is seg. fault after reading some data yet.
Thank you @FoxWise for helping. Now it is solved somewhere.

cheers!
Anil