Modify the title of a plot

Dear all,

I have a file that contains a couple of plots. This is the output of .ls in root:

TFile** dstar_kspipi_sigPS_Sel_allSignalEvents.plots.root
TFile* dstar_kspipi_sigPS_Sel_allSignalEvents.plots.root
KEY: TCanvas Dstar_KsPiPi_mD;1
KEY: TCanvas Dstar_KsPiPi_Deltam;1

I want to modify the legend of these plots, so I access the TH1D object this way:

root [0] TFile* file = TFile::Open( "dstar_kspipi_sigPS_Sel_allSignalEvents.plots.root" ); root [1] TCanvas* canvas = (TCanvas*) file ->Get( "Dstar_KsPiPi_Deltam" ); root [2] TPad* pad = (TPad*) canvas->GetListOfPrimitives()->At( 0 ); root [3] TH1D* hist = (TH1D*) pad ->GetListOfPrimitives()->At( 1 ); root [4] hist->SetTitle( "#Delta m for K_{s} #pi #pi signal events" ); root [5] canvas->Draw(); root [6] canvas->Print( "output.png" ); Info in <TCanvas::Print>: file output.png has been created

In the files, the pad is the 0th primitive of the canvas, and the histogram is the 1st primitive of the pad. This piece of code looks a bit arbitrary, but the plots are saved like this in all the MANY files that I need to modify.

The code presented works for me if I use the root interpreter. However, since I have many files, I would like to reuse this piece of code. Therefore, I wrote this piece of c++ code:

[code]#include

#include <root/TFile.h>
#include <root/TCanvas.h>
#include <root/TList.h>
#include <root/TPad.h>
#include <root/TH1D.h>

int main( int argc, char** argv )
{
// Ensure right number of arguments.
if ( argc < 4 )
return 1;

// Open the data file.
TFile* file = TFile::Open( argv[ 1 ] );

// Get the pointer to the histogram.
TCanvas* canvas = (TCanvas*) file ->Get( argv[ 2 ] );
TPad* pad = (TPad*) canvas->GetListOfPrimitives()->At( 0 );
TH1D* hist = (TH1D*) pad ->GetListOfPrimitives()->At( 1 );

// Change the title of the histogram.
hist->SetTitle( argv[ 4 ] );

// Save the output to a picture file.
canvas->Draw();
canvas->Print( argv[ 3 ] );

return 0;
}[/code]

I compile it with the following command:

g++ -o titol titol.cc -O -Wall -fPIC -L /usr/lib/root -L $ROOFIT/pkg/RooFitCore/tmp -lCore -lCint -lHist -lGraf -lGraf3d -lGpad -lTree -lMinuit -lpthread -lm -ldl -lRooFitCore

The compilation works, but when I run the program, I get this:

[code]./titol dstar_kspipi_sigPS_Sel_allSignalEvents.plots.root Dstar_KsPiPi_Deltam output.png "#Delta m for K_{s} #pi #pi signal events"
Warning in TPad::ResizePad: cPlotAndResid_1 width changed from 0 to 10

Warning in TPad::ResizePad: cPlotAndResid_1 height changed from 0 to 10

Warning in TPad::ResizePad: cPlotAndResid_2 width changed from 0 to 10

Warning in TPad::ResizePad: cPlotAndResid_2 height changed from 0 to 10

Warning in TCanvas::ResizePad: cPlotAndResid width changed from 0 to 10

Warning in TCanvas::ResizePad: cPlotAndResid height changed from 0 to 10[/code]

It does not create the file output.png. If it exists, it also prints “Info in TCanvas::Print: file output.png has been created”, but it does not create the file at all.

It is a bit strange that the same code works in root, but not in c++. Any idea on how to make the c++ program work, as the root code does?

Thanks in advance and regards,

                                  - Jordi.

Hi,

You are missing a TApplication object in your main.

I actually simply recommend that you use a compileable script. In your example simply replace ‘int main( int argc, char** argv )’ with ‘int titol(const char *arg1, const char *arg2, const char *arg3, const char *arg4)’ (and of course change the use of argv[X] to argX) and simply use as:root.exe -b -l -q 'titol.cc+("dstar_kspipi_sigPS_Sel_allSignalEvents.plots.root","Dstar_KsPiPi_Deltam","output.png", "#Delta m for K_{s} #pi #pi signal")'

Cheers,
Philippe.

Thank you, Philippe,

it works fine now, but I still have a small issue: the program (I have preferred to build a binary application with g++) pops a window with the plot, which gets closed in a fraction of a second. I guess it would also happen if I was running root.exe with the program as a script.

I don’t want this, since I may need to run this program remotely, and therefore, popping windows would trigger a display message from the X server.

I have tried to set it to batch mode, but TApplication::MakeBatch() is protected.

Is there any solution to avoid the popping window?

Thanks in advance.

                                - Jordi.

Hi,

Try gROOT->SetBatch(kTRUE); or try to pass -b to the TApplication object.

Cheers,
Philippe.

PS. Anyway if the environment variable DISPLAY is not set, ROOT will not attempt to display anything (X11 wise)