Draw() confusion

Hello,
I have the following class method to draw a series of TMultigraph 's on TCanvas 's
void graph::draw(){
canvas = static_cast<TCanvas*>(::operator new(sizeof(TCanvas[num_graphs])));
for (int i = 0; i < num_graphs; i++){
new (canvas + i) TCanvas(names[i], names[i]);
multigraph[i] . Draw(“AP”);
(canvas + i) -> Update ();
}
};

However, the last one of the histograms processed gets drawn on top of the TMultigraph. There is no instruction for the histogram to be drawn anywhere. I am having a hard time with this, because I cannot explain the bug from the code alone.
I use g++ to compile the code and TApplication to display the drawings.

Hi,

it is not clear from your post what histogram you are referring to.

Danilo

I call a series histogram and then do a fit on them:
{
TH1F * h_process = (h1 + offset); //h1 is a TH1F* pointing to an array of TH1F*
h_process -> Fit(“gaus”);
}
I expect h_process 's lifetime to end after the exit from the block. However, the last one of this series of histograms gets drawn on my canvas.
By the way, the ghost histogram appears on my canvas after the exit from the class methods. Using TCanvas::GetListofPrimitives::Print() method I can see clearly that the histogram wasn’t on the canvas during the lifetime of the class method.

Hi,

this is not entirely true. Extrapolating from this code, the lifetime of h_process is decoupled form the actual scope since, de facto, you are using a “comfortable alias” (h_process) to a pointer to a TH1F located in some array.
Could you post a full reproducer?

Danilo

Ok, the array continues to exist after h_process disappeared, but I no longer call any method of those histograms of that array.
I often use the Draw method on canvases in class methods. In all cases the canvas draws normally while the class method is alive, but in some cases it goes blank after the exit from the class method. However, to my relief the canvas saves normally contrary to what is seen on the screen.
In the case which is the topic of this forum the canvas also gets saved with the ghost on.
Secondly (which really deserves opening another post), I have noticed that calling Fit on histograms calls a canvas:
TCanvas::MakeDefCanvas: created default TCanvas with name c1
This canvas creates an unnecessary confusion and other ghosts get plotted on it in the end. I would like to get rid of it.

Hi,

I am afraid that without a standalone reproducer I cannot help you any further.

Best regards,
Danilo

Hello,
As I said I use TApplication to display canvases.
I use the following structure:
int main{
TApplication app(“myapp”, 0, 0);


TCanvas *stop_canvas = new TCanvas(“stop_canvas”, “stop_canvas”);
stop_canvas -> WaitPrimitive();
}
The call of stop_canvas ->WaitPrimitive() command allows me to get access to the toolbars of canvases that were made in the course of the program, so that I can save, zoom, and make fits (I find this command somewhat obscure and awkward to get access to the said functionality).

I have observed that the evocation of this command at program termination actually messes the canvases.
I tried out using cin.get() at program termination. In this cases all canvas remained intact, but I cannot access the toolbars.

Thanks.

Hi,

Do you call TApplication::Run() in your application?

And about this point:[quote=“Viesturs”]There is no instruction for the histogram to be drawn anywhere.[/quote]To draw an histogram in a given canvas (or pad) just call your_canvas->cd() before your_histo->Draw()
And BTW, a reproducer (a running macro showing the problem) is always better to understand what you’re trying to achieve…

Cheers, Bertrand.

Hello,
No, I´m not calling TApplication::Run().
I tried to do it now, but the program appeared to stop, doing nothing.

I don´t know how I could prepare a reproducer. If you mean relevant fragments of code, that would mean a lot of code, too much to post here.

Regards,
Viesturs

Hi,

TApplication::Run() is needed to perform event processing. There are other options, but without any piece of code to refer to, I’m afraid it will be impossible to give any advice. [quote=“Viesturs”]I don´t know how I could prepare a reproducer. If you mean relevant fragments of code, that would mean a lot of code, too much to post here. [/quote]Even attaching a tar file? Or making it available somewhere else? How many lines of code do you have in your application? Can’t you just reduce it to simply have a couple of histograms reproducing the same behavior?

Cheers, Bertrand.

Hello,
I inserted TApplication::Run() at the end of program. It appears to do the same thing as TCanvas::WaitPrimitive() - the toolbars appear and canvases get messed up.

I am working with thousands of lines of code and more than ten libraries. In addition I am processing several gigabytes of data and have a thousand histograms stored in the heap.

The problem I am describing is somewhat erratic in nature. It does not surge with a handful of canvases, but appears when there are many of them. Furthermore, it is stochastic - one cannot know at what conditions it will appear or disappear. Yesterday I created two knew classes that create canvases, and both of them get spoiled.

Thanks,
Viesturs

[quote=“Viesturs”]the toolbars appear and canvases get messed up[/quote] Meaning?

[quote=“Viesturs”]The problem I am describing is somewhat erratic in nature. It does not surge with a handful of canvases, but appears when there are many of them. Furthermore, it is stochastic - one cannot know at what conditions it will appear or disappear. Yesterday I created two knew classes that create canvases, and both of them get spoiled.[/quote]OK, but do you really expect us trying to find where the problem is in your code without actually seeing it?

Cheers, Bertrand.

Hello,
Happily after investigating more deeply the problem I managed to create a small application that reproduces it:

int main()
{
	TApplication app("myapp", 0, 0);
	const int size = 3; 
	double FWHM[] = {3, 4, 2};
	double number_singles_top[] = {6, 7, 8};
	double number_singles_bot[] = {2, 1, 0.1};

	TGraph *graph[2] = {new TGraph(size, FWHM, number_singles_top), new TGraph(size, FWHM, number_singles_bot)};
	TCanvas *c_graph  = new TCanvas("FWHM_number_singles", "FWHM_number_singles");
	c_graph -> Divide(1, 2);
	c_graph -> cd(1);
	graph[0] -> Draw("A*");
	c_graph -> cd(2);
	graph[1] -> Draw("A*"); 
	c_graph -> Update();
	 
	TH1F *h = new TH1F("h1", "h1", 4, 0, 3); 
	h -> Fit("gaus", "O");
	cin.get();
	app.Run();
}

before cin.get() c_graph looks normal. After pressing Enter, the lower part of it gets substituted by the result of h-> Fit (I was trying to use option “O” to avoid it).
Needless to say if we comment the h->Fit line we don’t observe any artifacts.

Hi Viesturs,

I cannot reproduce the problem with the head of 5-34-00-patches on Windows (i.e. each pad displays its graph, as expected), but at least we have something to start with.
Obviously I forgot to ask the usual (and very important) questions: Which version of ROOT? Which OS? Which compiler & compiler version?
And another question: why do you need the cin.get() statement?

Cheers, Bertrand.

Hello,
I use ROOT 5.17/06 (trunk@21138, Feb 08 2011, 16:48:00 on linuxx8664gcc)
CINT/ROOT C/C++ Interpreter version 5.16.27, Oct 25, 2007

I work in Linux 2.6.18-348.el5.centos.plus

I compile my code with g++

I use cin.get() to control the execution of the program.

I previously made fits on histograms stored in the heap (not drawn) using only “Q” option. After identifying TH1F::Fit() as a potential source of problem, I introduced the letter “O” in the option. After my post, a friend of mine sent me an e-mail to change O to 0. I did so and consequently don’t see any artifacts on canvases.

Unfortunately, introducing the option “0” I no longer see fits on histograms saved in Root file. I need to see the fits for quality control purposes. Is there a way how it can be achieved, i.e. see fits done on histograms in Root file without producing artifacts on canvases?

I have noticed that calling TSpectrum::Search(const TH1* hist, Double_t sigma = 2, Option_t* option = “”, Double_t threshold = 0.05) creates a Canvas :
TCanvas::MakeDefCanvas: created default TCanvas with name c1
Besides being an unnecessary object in my workspace, the canvas could be a source of further problems. I would like to avoid creating this canvas.
Thanks

According to the help:
root.cern.ch/root/htmldoc/TSpect … rum:Search

you need the option “goff” tu turn off the graphics.

Hello couet,
goff is used “to disable the storage and drawing of the polymarker”. However, I save my processed histograms in a root a file, and there I definitely want to see on a case to case basis if Spectrum search was successful.
I tried the “nodraw” option but it appears that it doesn’t work with my root version.
Regarding the used of TApplication::Run() is there a graceful way to terminate the program, otherwise than breaking it by Ctrl +C?

Thank you,
Viesturs