Plotting two TGraphs from a different root file on the same graph

Hi all! I’m trying to plot graphs from two different root files on the same graph. I get a segmentation violation when I try it like this:

#include <TH2.h>

#include <TStyle.h>

#include <TCanvas.h>

#include "TGraph.h"

#include <TROOT.h>

#include <TFile.h>

#include "TCanvas.h"

#include "TStyle.h"

#include <string>

#include "TH1.h"

#include "TH2F.h"

#include "TDirectory.h"

#include "TStyle.h"

#include "TF1.h"

#include "TSystem.h"

void combineROCCurves(){

TFile *ROCCombined = new TFile("ROCCombined.root","RECREATE");

TFile *f1 = new TFile("ROC.root","recreate");

TGraph* graph = (TGraph*)f1->Get("Graph");

graph->Draw("ACP");

graph->Write();

f1->Close();

TFile *f2= new TFile("SherpaRoc.root","recreate");

TGraph* graph2 = (TGraph*)f2->Get("Graph");

graph2->SetLineColor(2);

graph2->Draw("same");

graph2->Write();

f2->Close();

}

Where have I gone wrong? Thanks!

You create an empty TFile, and then you try to read an empty TGraph from it. That cannot work (idem for the second one)…

I had tried to use read not recreate for f1 and f2, but that gave me an error about tfile::init could not read type, or something along those lines :frowning: So that would’ve been the right thing to use though?

The problem is that I really don’t understand what you’re trying to do… Did you try any of the tutorials?

Not in tutorials, although what I was basing the code on was this:

I have two files, ROC.root and SherpaRoc.root. They each contain Multiple TGraphs which show up in a TBrowser as Graph;1, Graph;2 … Graph;10. So I need to get Graph;10 from each file and plot them on the same graph (with different coloured lines). I’m not sure how to get Graph;10 rather than Graph;1, say, but then I can’t get it working at all yet.

I changed it back to “read” for the two existing files and get some weird output like this:

Processing combineROCCurves.C...

gdb.printing.register_pretty_printer(gdb.current_objfile(),

gdb.printing.register_pretty_printer(gdb.current_objfile(),

#0 0x00007f4b7708e41c in waitpid () from /lib64/libc.so.6

#1 0x00007f4b7700bf12 in do_system () from /lib64/libc.so.6

#2 0x00007f4b77bfe644 in TUnixSystem::StackTrace() () from /usr/lib64/root/libCore.so.6.18

#3 0x00007f4b71fb8d95 in cling::MultiplexInterpreterCallbacks::PrintStackTrace() () from /usr/lib64/root/libCling.so

#4 0x00007f4b71fb823b in cling_runtime_internal_throwIfInvalidPointer () from /usr/lib64/root/libCling.so

#5 0x00007f4b7835819e in ?? ()

#6 0x00007fffb560b5d0 in ?? ()

#7 0x00007fffb560b5cf in ?? ()

#8 0x00007fffb560b5e0 in ?? ()

#9 0x0000000c00000000 in ?? ()

#10 0x0000000001bae8e0 in ?? ()

#11 0x0000000001b8f640 in ?? ()

#12 0x00000000019819a8 in ?? ()

#13 0x0000000001980ff8 in ?? ()

#14 0x0000000001a67cc0 in ?? ()

#15 0x0000000001981008 in ?? ()

#16 0x0000000001bae850 in ?? ()

#17 0x00007fffb560b830 in ?? ()

#18 0x0000000000000000 in ?? ()

Error in <HandleInterpreterException>: Trying to dereference null pointer or trying to call routine taking non-null arguments.

Execution of your code was aborted.

In file included from input_line_8:1:

**/home/atlas/krybacki/Pythia/Test/combineROCCurves.C:43:1:** **warning:** **null passed to a callee that requires a non-null argument [-Wnonnull]**

graph->Draw();

which I’m guessing is it complaining that ‘graph’ doesn’t exist or something?

If you opened the files once in “RECREATE” mode, then you might have deleted the content of the files… Could you try, in the ROOT command prompt:

root [0] TFile *f1 = TFile::Open("ROC.root");
root [1] f1->ls();

To see what is inside the file?
And FYI, to read an object from a file, you should do something like this:

TGraph *graph = nullptr;
TFile *f1 = TFile::Open("ROC.root");
if (f1) f1->GetObject("Graph", graph);
if (graph) {
   graph->Draw();
}
1 Like

Ahh, thank you, that was the problem! The output was this:
TFile** ROC.root
TFile* ROC.root

So yeah, all my graphs had gone! Lucky I made copies of the files before messing with them! Fixing that and changing the code as above :

void combineROCCurves(){

TFile *ROCCombined = new TFile("ROCCombined.root","RECREATE");

TGraph *graph = nullptr;

TFile *f1 = TFile::Open("PythiaRoc.root");

if (f1) f1->GetObject("Graph", graph);

if (graph) {

graph->Draw();

}

TGraph *graph2 = nullptr;

TFile *f2 = TFile::Open("SherpaRoc.root");

if (f2) f2->GetObject("Graph", graph2);

if (graph2) {

graph2->Draw();

}

It does run but I get a blank file :frowning: How would it differentiate between all the different objects called “Graph”? Should I add the semicolon?

Edit: actually, just tried that, and it doesn’t throw an error but there’s also still nothing in that output file ROCCombined.root

But it does enter the if part, a print statement before draw does show up

ROCCombined->cd();
if (graph) graph->Write("PythiaGraph");
if (graph2) graph2->Write("SherpaGraph");
delete ROCCombined;
2 Likes

Thank you! :slight_smile: Like this?

void combineROCCurves(){

TFile *ROCCombined = new TFile("ROCCombined.root","RECREATE");

ROCCombined->cd();

TGraph *graph = nullptr;

TFile *f1 = TFile::Open("PythiaRoc.root");

if (f1) f1->GetObject("Graph;10", graph);

if (graph) {

std::cout<<"Check"<<endl;

graph->Draw();

graph->Write("PythiaGraph");

}

TGraph *graph2 = nullptr;

TFile *f2 = TFile::Open("SherpaRoc.root");

if (f2) f2->GetObject("Graph;10", graph2);

if (graph2) {

graph2->Draw("same");

graph2->Write();

}

delete ROCCombined;
}

Why delete ROCCombined? Not close?

In principle not, the semicolon and number are called cycles. They are “backup” copies of the object. When you write several times an object with the same name into a file, root appends a cycle number. These numbers are different “revision” of the object.

Well, at some point you have to write the objects in the file (as @Wile_E_Coyote just showed) … And I think you should definitively look at the tutorials

Can you try graph->Draw("ACP");

1 Like

It works! Thank you both for your help, I really appreciate it! :smiley:

1 Like