Hi, I have a working function that makes a TCanvas, draws some stuff, and saves it to a file. I’d like to convert the function to instead return the TCanvas (or better, a TPad) so that I can put it on a Pad of a greater canvas outside the function before saving.
Unfortunately with my first attempt, a bunch of objects on the stack disappear when the function returns, and I am not sure how to make the TPad “own” these objects. Ideally a TPad * would be returned that I could ->Draw onto another canvas, and when I delete the TPad *, all the previously-on-stack objects would be cleaned up automatically.
Here is the original function, with proper includes, and a test() function that makes a file with the produced graph.
#include "TVectorD.h"
#include <vector>
#include "TString.h"
#include "TCanvas.h"
#include "TLine.h"
#include "TMath.h"
#include "TMarker.h"
#include "TH1.h"
void MakePlot(TVectorD quantity, Double_t threshold,
const std::vector<Int_t>& clusters,TString filename)
{
TCanvas c1("c_makeplot","c_makeplot");
quantity.Draw();
TLine threshline(0,threshold,quantity.GetNoElements(),threshold);
threshline.SetBit(kCanDelete);
threshline.SetLineWidth(1);
threshline.SetLineStyle(10);
threshline.SetLineColor(kRed);
if(TMath::Finite(threshold))
{
threshline.Draw();
}
TMarker tm;
tm.SetBit(kCanDelete);
tm.SetMarkerColor(kGreen);
tm.SetMarkerStyle(4);
tm.SetMarkerSize(1);
for(auto c : clusters)
{
tm.DrawMarker(c,quantity[c]);
}
TString title = TString::Format("N Clusters: %lu",clusters.size());
std::unique_ptr<TH1D> h_vec(static_cast<TH1D*>(c1.FindObject("TVectorD")));
h_vec->SetTitle(title);
auto oldlevel = gErrorIgnoreLevel;
gErrorIgnoreLevel = kInfo+1;
if(filename=="") filename = "default_name.pdf";
c1.SaveAs(filename);
gErrorIgnoreLevel = oldlevel;
return;
}
void test()
{
double vals[] = {4,5,6,7,8,9};
TVectorD tv(6,vals);
std::vector<int> clusters{5,1};
MakePlot(tv,4.5,clusters,"test_MakePlot.pdf");
}
To make the function return a TPad *, I know I’d have to “new” the TPad instead of using a TCanvas on the stack, but what about the TLine and TMarkers, and the temporary “TVectorD” histogram that is created when I do quantity.Draw()? How do I ensure that the TPad owns them and carries them outside the function? And how do I make sure that when the TPad * is eventually deleted, the owned items are also deleted?
Thanks,
Jean-François