Trouble reading .root files


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.30/06
_Platform: Ubuntu 20.04
_Compiler: g++ (Ubuntu 13.2.0-23ubuntu4) 13.2.0
Madgraph 3.5.6

Hello all,
So I have some .root files from madgraph+delphes. The cluster I’m working on just updated and I have just reinstalled and recompiled ROOT, madgraph, and madgraph software like Delphes and ExROOTAnalysis. Before all of this my code worked as expected. However now something is going wrong.

My main analysis code begins with this

int main(int argc, const char * argv[])
{
    
    //Pulls and arranges data as needed.
    TChain chain("Delphes");

    const char* EventType = argv[1];
    cout << EventType<< endl;

    for(int i=2; i<argc; i++)
    {
        chain.Add(argv[i]);
        cout << argv[i]<< endl;
    }

    ExRootTreeReader *treeReader = new ExRootTreeReader(&chain);
    Long64_t NumEntries = treeReader->GetEntries();
    cout << "There are "<< NumEntries <<" Entries." <<endl;
    TClonesArray *branchJet = treeReader->UseBranch("Jet"); 
    TClonesArray *branchElectron = treeReader->UseBranch("Electron");
    TClonesArray *branchMuon;
    if (hasMu) branchMuon = treeReader->UseBranch("Muon");
    TClonesArray *branchMET;
    if (hasMET) branchMET = treeReader->UseBranch("MET");

...

When I try to pass a single file it gives this

<bash stuff>$ <path to analysis>/JetFake/main <path to data>/Events/run_21/tag_1_delphes_events.root
Warning in <TClassTable::Add>: class ExRootTreeReader already in TClassTable
Warning in <TClassTable::Add>: class ExRootTreeWriter already in TClassTable
Warning in <TClassTable::Add>: class ExRootTreeBranch already in TClassTable
Warning in <TClassTable::Add>: class ExRootResult already in TClassTable
Warning in <TClassTable::Add>: class ExRootClassifier already in TClassTable
Warning in <TClassTable::Add>: class ExRootFilter already in TClassTable
<path to data>/Events/run_21/tag_1_delphes_events.root
There are 0 Entries.
** WARNING: cannot access branch 'Jet', return NULL pointer
** WARNING: cannot access branch 'Electron', return NULL pointer
** WARNING: cannot access branch 'Muon', return NULL pointer
  ------------------
  no event analyzed
  ------------------

I have another file that just opens and counts the number of events, called read_root_file which begins like this

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "Usage: " << argv[0] << " <path_to_root_file>" << std::endl;
        return 1;
    }

    const char* file_path = argv[1];
    TFile* file = TFile::Open(file_path);

    if (!file || file->IsZombie()) {
        std::cerr << "Error opening ROOT file: " << file_path << std::endl;
        return 1;
    }

    TKey* key;
    TIter next(file->GetListOfKeys());

    while ((key = (TKey*)next())) {
        TObject* obj = key->ReadObj();
        if (obj->IsA()->InheritsFrom(TTree::Class())) {
            TTree* tree = (TTree*)obj;
            std::cout << "Tree name: " << tree->GetName() << std::endl;
            std::cout << "Number of entries: " << tree->GetEntries() << std::endl;

            TObjArray* branches = tree->GetListOfBranches();
            for (int i = 0; i < branches->GetEntries(); ++i) {
                TBranch* branch = (TBranch*)branches->At(i);
                // std::cout << "  Branch name: " << branch->GetName() << std::endl;

                TObjArray* leaves = branch->GetListOfLeaves();
                for (int j = 0; j < leaves->GetEntries(); ++j) {
                    TLeaf* leaf = (TLeaf*)leaves->At(j);
                    // std::cout << "    Leaf name: " << leaf->GetName() << std::endl;
                }
            }
        }
    }

This file confirms that the file I’m passing to the analysis file is not empty.

If I pass more than one file into the analysis file, then it counts only events in the files other than the first file, and then breaks in a segmentation violation when I get to this line TStyle *st1 = new TStyle("st1","my style");

(venv2) <bash stuff>:<path to analysis>/JetFake/main <path to data>/Events/run_21/tag_1_delphes_events.root <path to data>/Events/run_02/tag_1_delphes_events.root <path to data>/Events/run_01/tag_2_delphes_events.root
Warning in <TClassTable::Add>: class ExRootTreeReader already in TClassTable
Warning in <TClassTable::Add>: class ExRootTreeWriter already in TClassTable
Warning in <TClassTable::Add>: class ExRootTreeBranch already in TClassTable
Warning in <TClassTable::Add>: class ExRootResult already in TClassTable
Warning in <TClassTable::Add>: class ExRootClassifier already in TClassTable
Warning in <TClassTable::Add>: class ExRootFilter already in TClassTable
<path to data>/Events/run_21/tag_1_delphes_events.root
<path to data>/Events/run_02/tag_1_delphes_events.root
<path to data>/Events/run_01/tag_2_delphes_events.root
There are 387 Entries.
Loading Events ...
Histo time

 *** Break *** segmentation violation
Segmentation fault (core dumped)

I don’t know if this is one problem, two, or more. I didn’t change anything about the code since it ran properly before the update. I tried changing the for-loop over the arguments to start at 1, but that didn’t seem to change anything.

Thanks,
Dyson

In your case:

Warning in <TClassTable::Add>: class ExRootTreeReader already in TClassTable

are fatal. You need to load the Delphes libraries in order to run this code. It should ‘as simple’ as linking against those libraries.

When I compile the code, this is the output. Which If I’m reading the end correctly means I am loading the Delphes Library. So I’m not exactly sure how to follow your advice

g++ -c -pthread -std=c++17 -m64 -I/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/include/root -L/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/lib/root -lGui -lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lROOTDataFrame -Wl,-rpath,/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/lib/root -pthread -lm -ldl -rdynamic -lEG -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/ExRootAnalysis/ExRootAnalysis  -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/Delphes/external -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/Delphes/display -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/Delphes -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/Delphes/external/fastjet -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/fastjet-3.4.2 -I/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/fastjet-3.4.2/fastjet-install/include    main.cpp
In file included from main.cpp:66:
observables.h:47:13: warning: ‘template<class _Arg1, class _Arg2, class _Result> struct std::binary_function’ is deprecated [-Wdeprecated-declarations]
   47 | public std::binary_function<const PseudoJet & , const PseudoJet &, bool>
      |             ^~~~~~~~~~~~~~~
In file included from /usr/include/c++/13/string:49,
                 from /usr/include/c++/13/bits/locale_classes.h:40,
                 from /usr/include/c++/13/bits/ios_base.h:41,
                 from /usr/include/c++/13/ios:44,
                 from /usr/include/c++/13/ostream:40,
                 from /usr/include/c++/13/iostream:41,
                 from main.cpp:2:
/usr/include/c++/13/bits/stl_function.h:131:12: note: declared here
  131 |     struct binary_function
      |            ^~~~~~~~~~~~~~~
observables.h:76:13: warning: ‘template<class _Arg1, class _Arg2, class _Result> struct std::binary_function’ is deprecated [-Wdeprecated-declarations]
   76 | public std::binary_function<const chi2<double> &, const chi2<double> &, bool>
      |             ^~~~~~~~~~~~~~~
/usr/include/c++/13/bits/stl_function.h:131:12: note: declared here
  131 |     struct binary_function
      |            ^~~~~~~~~~~~~~~
observables.h:101:13: warning: ‘template<class _Arg1, class _Arg2, class _Result> struct std::binary_function’ is deprecated [-Wdeprecated-declarations]
  101 | public std::binary_function<const mw_mass&, const mw_mass, bool>
      |             ^~~~~~~~~~~~~~~
/usr/include/c++/13/bits/stl_function.h:131:12: note: declared here
  131 |     struct binary_function
      |            ^~~~~~~~~~~~~~~
observables.h:135:13: warning: ‘template<class _Arg1, class _Arg2, class _Result> struct std::binary_function’ is deprecated [-Wdeprecated-declarations]
  135 | public std::binary_function<const mtop_sort<double>, mtop_sort<double>, bool>
      |             ^~~~~~~~~~~~~~~
/usr/include/c++/13/bits/stl_function.h:131:12: note: declared here
  131 |     struct binary_function
      |            ^~~~~~~~~~~~~~~
make: /home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/fastjet-3.4.2/fastjet-install/bin/fastjet-config: No such file or directory
g++ *.o  -pthread -std=c++17 -m64 -I/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/include/root -L/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/lib/root -lGui -lCore -lImt -lRIO -lNet -lHist -lGraf -lGraf3d -lGpad -lROOTVecOps -lTree -lTreePlayer -lRint -lPostscript -lMatrix -lPhysics -lMathCore -lThread -lMultiProc -lROOTDataFrame -Wl,-rpath,/modules/spack/packages/linux-ubuntu24.04-x86_64_v3/gcc-13.2.0/root-6.30.06-thrfpcvvbuqgtwvd3qvuythhw4jppu57/lib/root -pthread -lm -ldl -rdynamic -lEG -L/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/ExRootAnalysis -lExRootAnalysis  -L/home/dkennedy_umass_edu/Software/MG5_aMC_v3_5_6/Delphes -lDelphes  -o  main

Thank you

Looking back through my records, It seems like back before the OS update, I got those warnings regularly and it didn’t effect anything.

Do you know why the first file in the command line would be ignored?

Do you know why the first file in the command line would be ignored?

Which line?

Warning in <TClassTable::Add>: class ExRootTreeReader already in TClassTable

Oups. I mis-read the warning. That warnings means that the dictionary for ExRootTreeReader is being loaded twice (from 2 distinct libraries).

Most likely this means that after the OS update, something changes such that 2 incompatible version of the library is being linked in (or automatically loaded). For example one from a previous installation and the new one from the current build. If there is any difference in the ABI/API/class-content of those libraries problems will appear.

Check your LD_LIBRARY_PATH and the output of ldd on your executable.

Hello, I solved one issue regarding the input command.
I had modified the file so that another parameter designating which type of event I am analyzing should be specified in the command line like so

<path to script>/main <event type> <file1> <file2> ...

I had forgotten about this change, and I’ve rectified it. The segmentation fault is due to my use of TFile.

This is the section of the code that breaks it

TCanvas *c1 = new TCanvas("c1", "ROOT Canvas", 900, 20, 540, 550);

        const char* ImagePath = "/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/";

        char FullPathM2jW[100];
        char FullPathM2jW_root[100];

        strcpy(FullPathM2jW, ImagePath);
        strcat(FullPathM2jW, EventType);
        strcat(FullPathM2jW_root, FullPathM2jW);
        strcat(FullPathM2jW, "/plots/Mass_2jW.png");
        strcat(FullPathM2jW_root, "/plots/Mass_2jW.root");
        // MW2j
        MW2j->GetXaxis()->SetTitle("GeV");
        MW2j->Draw();
        cout << "Made it. Gotta save it"<< endl;
        c1->SaveAs(FullPathM2jW);
        cout << "boutta save root file" <<endl;
        cout << FullPathM2jW_root << endl;
        unique_ptr<TFile> MW2j_rootfile( TFile::Open(FullPathM2jW_root, "RECREATE"));
        MW2j_rootfile->WriteObject(&MW2j, "MW2j");

I get this

...
Made it. Gotta save it
Info in <TCanvas::Print>: png file /work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.png has been created
boutta save root file
F[?]/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.root
SysError in <TFile::TFile>: file /home/dkennedy_umass_edu/LNV/MyFiles/LFVLNV/AnalysisAndSuch/JetFake/F[?]/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.root can not be opened No such file or directory

 *** Break *** segmentation violation

so the variable FullPathM2jW_root gives me the path I want with the exception of F[?] at the start. The copy and paste didn’t capture the ? in a box, so I typed in [?] in its place. Then on the next line, it seems to be attaching the path to the script directory, but I don’t know why. My goal is to save the histograms as .root files, so that another script can open the root files and make a THStack of multiple histograms.

Hello,

I noticed that the path that’s printed is 150 characters long. It looks like that won’t fit in

char FullPathM2jW[100];
char FullPathM2jW_root[100];

so my guess is an array overflow. You could try to make the arrays larger (unsafe, because they can overflow again), or you could try moving to std::string or similar, which allocate on demand.

Thanks for your help. From a quick check, the path that’s printed is 76 characters.
this line: cout << FullPathM2jW_root << endl; gives /work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.root which is 76 characters. However, the same variable in the next line:
unique_ptr<TFile> MW2j_rootfile( TFile::Open(FullPathM2jW_root, "RECREATE")); gives this error SysError in <TFile::TFile>: file /home/dkennedy_umass_edu/LNV/MyFiles/LFVLNV/AnalysisAndSuch/JetFake/F[?]/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.root can not be opened No such file or directory which is about 150 characters.
That’s the crux of my confusion, but I don’t know why the latter line is attempting to use a different path than I’m giving it. Specifically, it slaps the local path in front of the absolute path I give it.

Hello,
After a few iterations of attempts, I solved it by initializing the char arrays as “” and using SaveAs with the canvas.

const char* ImagePath = "/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/";

        char FullPathM2jW[100] = "";
        char FullPathM2jW_root[100] = "";

        strcpy(FullPathM2jW, ImagePath);
        strcat(FullPathM2jW, EventType);
        strcat(FullPathM2jW_root, FullPathM2jW);
        strcat(FullPathM2jW, "/plots/Mass_2jW.png");
        strcat(FullPathM2jW_root, "/plots/Mass_2jW.root");
        // MW2j
        MW2j->GetXaxis()->SetTitle("GeV");
        MW2j->Draw();
        cout << "Made it. Gotta save it"<< endl;
        c1->SaveAs(FullPathM2jW);
        cout << "boutta save root file" <<endl;
        // cout << FullPathM2jW_root << endl;
        c1->SaveAs(FullPathM2jW_root);

Hello,

that’s great! :slightly_smiling_face:

Just in case that you need to go back at some point, I don’t understand what went wrong before. TFile::Open should correctly handle a null-terminated string, so my suspicion is that it wasn’t null-terminated or that there is a bug in ROOT. In case you need TFile::Open again and the problem comes back, check that strlen(FullPathM2jW_root) is actually what you expect. Or use std::string.
If they are null-terminated correctly, you might have found a bug in ROOT, and then you would be very welcome to report it. :slightly_smiling_face:

It was odd for a few reasons. I have a similar block of code for a handful of histograms. And when I changed the first block to using SaveAs, it worked fine and then broke for the ones I didn’t change. This is what I expected. I noticed that when the PATHs printed it was fine like in the above exchange, but then when it tried to open it, it had extra junk TFile::Open("<U+0010><CE><U+0006><E4><FF><U+007F>/work/pi_mjrm_umass_edu/LNV_collider/AnalysisOutput/LNVF/plots/Mass_2jW.root","recreate");
Then when i changed it all to use SaveAs and I ran it again, it had extra junk for all of them and failed including the first one which had worked before. So it seemed that when SaveAs fails it keeps going, which wasn’t happening for Open.
So the final fix was just to initialize it as empty. For some reason, when I was running the code before, it was filling the space in the uninitialized char with the local path, but later it was doing junk. I’m not formally well-versed enough to know if that’s a null-terminated string or not though.

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