Pointers to canvases lost when function is called

Hello,

I am trying to write a script to generate plots to examine correlation of variables in a TTree. My problem is that the script seems to loose the pointers to the canvases that I pass in. I would like to make two plots, one generated from a signal data file, and one from a background data file. I pass in pointers to two canvases (there is also an overloaded function that creates two canvases and returns pointers to them if canvases are not given). The script works fine the first time, but if I try to run the script a second time, I receive an error message that the pointers to the canvases no longer exist. The canvases themselves remain open, however.

Another aspect of this problem that is confusing to me is that I recently wrote a similar plotting function as part of a class that did not experience this problem (code below).

I’m not sure whether this problem has to do with the Draw function in root, some other method that I’m using, or is just a result of my lack of familiarity with C++. If this is a novice C++ blunder, I apologize in advance.

Thanks very much,
Adrian

The script that currently does NOT work:

TCanvas * MakeCanvas(TString CanTitle)
{
  TCanvas * can = new TCanvas(CanTitle, CanTitle, 0, 0, 720, 720);
  return can;
}

void MakePlot(TFile* f, TCanvas* can, TString PlotStr, TCut MyCut, TString XLabel, TString YLabel, TString Title)
{
  f->cd();
  can->cd();

  ntp2->Draw(PlotStr, MyCut);
  TH2D * htemp = (TH2D*)gPad->GetPrimitive("htemp");
  htemp->GetXaxis()->SetTitle(XLabel);
  htemp->GetYaxis()->SetTitle(YLabel);
  htemp->SetTitle(Title);
}

TCanvas ** Corr_Hist(TString XVar, TString YVar, TCut MyCut, TString XLabel, TString YLabel)
{
  TCanvas * cans[2];
  cans[0] = MakeCanvas("DM e- MC Signal");
  cans[1] = MakeCanvas("Run 1 On peak background");

  Corr_Hist(XVar, YVar, MyCut, XLabel, YLabel, can1, can2);

  return cans;
}

void Corr_Hist(TString XVar, TString YVar, TCut MyCut, TString XLabel, TString YLabel, TCanvas * can1, TCanvas * can2)
{

  gROOT->Reset();
  gStyle->SetOptStat("");
  gStyle->SetCanvasColor(10);
  gStyle->SetTitleFillColor(10);

  can1->Clear();
  can2->Clear();

  TFile * f1 = new  TFile("$myroot/DMT_new.dm.e-.root");
  TFile * f2 = new  TFile("$myroot/DMT_new.run.on.root");

  TString PlotStr = YVar+":"+XVar;
  
  MakePlot(f1, can1, PlotStr, MyCut, XLabel, YLabel, "");
  MakePlot(f2, can2, PlotStr, MyCut, XLabel, YLabel, "");

}

The method from a class that DOES work (i.e. the pointer to the canvas is not deleted):

void EventListWithPlots::CutNPlot(TCanvas * can, TString MyVar, TCut MyCut, Bool_t Printing, Int_t Logging, TString OutputFile)
{
  ApplyCut(MyCut);   // apply and store the cut in the event list

  if (Printing)      // if the printing flag is set, print output
      PrintToScreen();

  if (Logging)       // if the logging flag is set, print the output to a file
      PrintToFile(OutputFile, Logging-1);

  can->Clear();      // prepare the canvas
  can->Divide(3,4);

  can->cd(1);        // plot the signal data file 
  SetFile(GetSignalIndex());
  ntp2->Draw(MyVar, MyCut);

  can->cd(2);        // plot the bhabha data file
  SetFile(2);
  ntp2->Draw(MyVar, MyCut);

  for (int i = 3; i <= 10; i++) // plot the background data
      {
	can->cd(i);
	SetFile(i+1);
	ntp2->Draw(MyVar, MyCut);
      }

  for (int i = 11; i <= 12; i++) // plot the run data
      {
	can->cd(i);
	SetFile(i+2);
	ntp2->Draw(MyVar, MyCut);
      }
}

Remove the “gROOT->Reset” statement.
This should be used only in unnamed macros.

Rene

Thank you, Rene. Removing the gROOT->Reset() command allows me to run the script twice. However, a problem with the pointers remains. Now, the pointers still exist on exit, but are set to null, so that when I run the script a second time, there is a segmentation violation on the can1->Clear() command, as can1 is a null pointer.

Adrian

TCanvas * MakeCanvas(TString CanTitle)
{
  TCanvas * can = new TCanvas(CanTitle, CanTitle, 0, 0, 720, 720);
  return can;
}

void MakePlot(TFile* f, TCanvas* can, TString PlotStr, TCut MyCut, TString XLabel, TString YLabel, TString Title)
{
  f->cd();
  can->cd();

  ntp2->Draw(PlotStr, MyCut);
  TH2D * htemp = (TH2D*)gPad->GetPrimitive("htemp");
  htemp->GetXaxis()->SetTitle(XLabel);
  htemp->GetYaxis()->SetTitle(YLabel);
  htemp->SetTitle(Title);
}

TCanvas ** Corr_Hist(TString XVar, TString YVar, TCut MyCut, TString XLabel, TString YLabel)
{
  TCanvas * cans[2];
  cans[0] = MakeCanvas("DM e- MC Signal");
  cans[1] = MakeCanvas("Run 1 On peak background");

  Corr_Hist(XVar, YVar, MyCut, XLabel, YLabel, cans[0], cans[1]);

  return cans;
}

void Corr_Hist(TString XVar, TString YVar, TCut MyCut, TString XLabel, TString YLabel, TCanvas * can1, TCanvas * can2)
{
  cout << "Clearing" << endl;
  can1->Clear();
  can2->Clear();
  cout << "Opening files" << endl;
  TFile * f1 = new  TFile("$myroot/DMT_new.dm.e-.root");
  TFile * f2 = new  TFile("$myroot/DMT_new.run.on.root");

  TString PlotStr = YVar+":"+XVar;
  cout << "Making plots" << endl;
  MakePlot(f1, can1, PlotStr, MyCut, XLabel, YLabel, "");
  MakePlot(f2, can2, PlotStr, MyCut, XLabel, YLabel, "");
}

My script is working now as intended. The problem described in the previous message was due to a mistake on my part.

Thanks for the assistance,
Adrian