TGraph doesn't work with sprintf

Hello,

I’m writing a code to read some stopping powers from GEANT4 and compare to NIST data. I’m trying to call TGraph for the different stopping powers vectors I have:

const char *Particle[n_particles];
Particle[0] = "Alpha";
Particle[1] = "Proton";
Particle[2] = "Electron";

const char *Material[n_materials];
Material[0] = "Aluminium";
Material[1] = "Silicon";
Material[2] = "Polyethylene";
Material[3] = "Tungsten";

for(int i=0;i<n_particles;i++){
    for(int j=0;j<n_materials;j++){

      NGEANT = sprintf(GEANTFile,"%s_%s_stopping_power",Particle[i],Material[j]);

      TGraph *Gra2 = new TGraph(37,energy,GEANTFile);
      Gra2->SetMarkerColor(2);
      Gra2->SetMarkerStyle(21);
      Gra2->SetMarkerSize(1.2);
      }
}

I always get an error when using TGraph with sprintf. I can, however, use sprintf in everything else inside the loop.

Any help?

Thanks a lot :slight_smile:

What is the size of your buffer GEANTFile? It might be too small.
Try to avoid sprintf!
Either use snprintf (if you want to write C-style code) or avoid the cstdio functions all-together if you want C++.
ROOT provides TString::Format which you can use instead.

Also, which TGraph constructor do you want to call? -> TGraph takes N + 2 pointers to float/double arrays or filename/format/option. (or am I missing a constructor?)

Thank you very much for your answer!

Increasing the GEANTFile buffer doesn’t help.

I will try both snprintf and TSring::Format then, thanks :slight_smile:

The TGraph constructor I’m using is TGraph *Gra2 = new TGraph(37,energy,GEANTFile); where:

NGEANT = sprintf(GEANTFile,"%s_%s_stopping_power",Particle[i],Material[j]);

const char *Particle[n_particles];
Particle[0] = “Alpha”;
Particle[1] = “Proton”;
Particle[2] = “Electron”;

const char *Material[n_materials];
Material[0] = “Aluminium”;
Material[1] = “Silicon”;
Material[2] = “Polyethylene”;
Material[3] = “Tungsten”;

Thank you again.

My question was: which of the available TGraph constructors are you calling / do you want to call?
So I just know that you are calling TGraph::TGraph(int, ?, ?)
where the first ? is the type of the variable “energy”, and where the second ? is either char * or char[N] (which will convert to char*)

Available constructors are for example (see https://root.cern.ch/doc/master/classTGraph.html)
TGraph(int, const float*, const float )
TGraph(int, const double
, const double )
TGraph(const char
, const char*, const Option_t *)

Which of these do you want to call? Your parameters don’t seem to fit to any of these.

Also, you are just saying [quote=“lghizoni_dk, post:1, topic:24223”]
I always get an error
[/quote]
it would be very helpful to know what kind of error you get! (copy+paste full error message!)

Also, I don’t see any connection between TGraph and s(n)printf.

According to your first post it looks like you are trying to construct your TGraph from a file. There is only one constructor allowing this and the syntax you are using is wrong.

Ok, I think it’s easier to post my code. I have a number of ROOT files that I’m calling and creating vectors of Stopping Power:

void Shielding_Validation(){

  const int n_materials = 4;
  const int n_particles = 3;
  const int n_points = 37;

  double energy [n_points] = {0.01,0.02,0.03,0.04,0.05,0.06,0.07,0.08,0.09,0.1,
  0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0,2.0,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,20.0,30.0,40.0,50.0,60.0,70.0,
  80.0,90.0,100.0};

  const char *Particle[n_particles];
  Particle[0] = "Alpha";
  Particle[1] = "Proton";
  Particle[2] = "Electron";

  const char *Material[n_materials];
  Material[0] = "Aluminium";
  Material[1] = "Silicon";
  Material[2] = "Polyethylene";
  Material[3] = "Tungsten";

  double d_Al = 2.70;  // g/cm3
  double d_Si = 2.329; // g/cm3
  double d_Py = 0.94;  // g/cm3
  double d_W  = 19.25; // g/cm3

  double Stopping_Power_Matrix[n_particles][n_materials][n_points];

  double Alpha_Aluminium_stopping_power[n_points];
  double Alpha_Silicon_stopping_power[n_points];
  double Alpha_Polyethylene_stopping_power[n_points];
  double Alpha_Tungsten_stopping_power[n_points];

  double Proton_Aluminium_stopping_power[n_points];
  double Proton_Silicon_stopping_power[n_points];
  double Proton_Polyethylene_stopping_power[n_points];
  double Proton_Tungsten_stopping_power[n_points];

  double Electron_Aluminium_stopping_power[n_points];
  double Electron_Silicon_stopping_power[n_points];
  double Electron_Polyethylene_stopping_power[n_points];
  double Electron_Tungsten_stopping_power[n_points];

  char File1[60],File2[60],File3[60],File4[60],File5[60];
  int N1,N2,N3,N4,N5;

  for(int i=0;i<n_particles;i++){
    for(int j=0;j<n_materials;j++){
      for(int k=0;k<9;k++){
        N1 = sprintf(File1,"MonteCarlo/%s/%s/%d0keV.root",Material[j],Particle[i],k+1);
        N2 = sprintf(File2,"MonteCarlo/%s/%s/%d00keV.root",Material[j],Particle[i],k+1);
        N3 = sprintf(File3,"MonteCarlo/%s/%s/%dMeV.root",Material[j],Particle[i],k+1);
        N4 = sprintf(File4,"MonteCarlo/%s/%s/%d0MeV.root",Material[j],Particle[i],k+1);

        TFile *file1 = new TFile(File1);
        TFile *file2 = new TFile(File2);
        TFile *file3 = new TFile(File3);
        TFile *file4 = new TFile(File4);

        TTree *tree1 = (TTree*)file1->Get("LET_Box_tuple_LET");
        TTree *tree2 = (TTree*)file2->Get("LET_Box_tuple_LET");
        TTree *tree3 = (TTree*)file3->Get("LET_Box_tuple_LET");
        TTree *tree4 = (TTree*)file4->Get("LET_Box_tuple_LET");

        tree1->Draw("let>>hist1");
        tree2->Draw("let>>hist2");
        tree3->Draw("let>>hist3");
        tree4->Draw("let>>hist4");

        TH1F *hist1 = gDirectory->Get("hist1");
        TH1F *hist2 = gDirectory->Get("hist2");
        TH1F *hist3 = gDirectory->Get("hist3");
        TH1F *hist4 = gDirectory->Get("hist4");

        Stopping_Power_Matrix[i][j][k] = hist1->GetMean();
        Stopping_Power_Matrix[i][j][k+9] = hist2->GetMean();
        Stopping_Power_Matrix[i][j][k+18] = hist3->GetMean();
        Stopping_Power_Matrix[i][j][k+27] = hist4->GetMean();
      }
      N5 = sprintf(File5,"MonteCarlo/%s/%s/100MeV.root",Material[j],Particle[i]);
      TFile *file5 = new TFile(File5);
      TTree *tree5 = (TTree*)file5->Get("LET_Box_tuple_LET");
      tree5->Draw("let>>hist5");
      TH1F *hist5 = gDirectory->Get("hist5");
      Stopping_Power_Matrix[i][j][36] = hist5->GetMean();
    }
  }

  for(int i=0;i<n_points;i++){
    Alpha_Aluminium_stopping_power[i] = Stopping_Power_Matrix[0][0][i]/d_Al;
    Alpha_Silicon_stopping_power[i] = Stopping_Power_Matrix[0][1][i]/d_Si;
    Alpha_Polyethylene_stopping_power[i] = Stopping_Power_Matrix[0][2][i]/d_Py;
    Alpha_Tungsten_stopping_power[i] = Stopping_Power_Matrix[0][3][i]/d_W;

    Proton_Aluminium_stopping_power[i] = Stopping_Power_Matrix[1][0][i]/d_Al;
    Proton_Silicon_stopping_power[i] = Stopping_Power_Matrix[1][1][i]/d_Si;
    Proton_Polyethylene_stopping_power[i] = Stopping_Power_Matrix[1][2][i]/d_Py;
    Proton_Tungsten_stopping_power[i] = Stopping_Power_Matrix[1][3][i]/d_W;

    Electron_Aluminium_stopping_power[i] = Stopping_Power_Matrix[2][0][i]/d_Al;
    Electron_Silicon_stopping_power[i] = Stopping_Power_Matrix[2][1][i]/d_Si;
    Electron_Polyethylene_stopping_power[i] = Stopping_Power_Matrix[2][2][i]/d_Py;
    Electron_Tungsten_stopping_power[i] = Stopping_Power_Matrix[2][3][i]/d_W;
  }

  // PLOTTING SECTION

  char Canvas[5];     int Ncanvas;
  char NISTFile[80];  int NNIST;
  char GEANTFile[180]; int NGEANT;
  char Title[80];     int TITLE;

  for(int i=0;i<n_particles;i++){
    for(int j=0;j<n_materials;j++){
      Ncanvas = snprintf(Canvas,"%s_%s",Material[j],Particle[i]);
      NNIST = snprintf(NISTFile,"NIST_StoppingPowers/%s_%s_StoppingPower.dat",Particle[i],Material[j]);
      NGEANT = sprintf(GEANTFile,"%s_%s_stopping_power",Particle[i],Material[j]);
      TITLE = snprintf(Title,"%s Stopping Power for %s Particles",Material[j],Particle[i]);

      cout<<GEANTFile<<endl;

      TCanvas *c = new TCanvas(Canvas);
      c->SetFillColor(10);
      c->SetGrid();
      c->SetLogx();
      c->SetLogy();

      TMultiGraph *mg = new TMultiGraph();

      TGraph *Gra1 = new TGraph(NISTFile,"%lg %lg");
      Gra1->SetLineColor(4);
      Gra1->SetLineWidth(4);

      TGraph *Gra2 = new TGraph(37,energy,GEANTFile);
      Gra2->SetMarkerColor(2);
      Gra2->SetMarkerStyle(21);
      Gra2->SetMarkerSize(1.2);

      mg->Add(Gra1,"cp");
      mg->Add(Gra2,"p");
      mg->Draw("a");

      mg->SetTitle(Title);
      mg->GetXaxis()->SetTitle("Energy[MeV]");
      mg->GetYaxis()->SetTitle("Stopping Power [MeV.cm2/g]");

      gPad->Modified();

      leg = new TLegend(0.1,0.7,0.3,0.9);
      leg->SetFillColor(0);
      leg->AddEntry(Gra1,"NIST Database","l");
      leg->AddEntry(Gra2,"GEANT4","p");
      leg->Draw();
    }
  }
}

My error comes on the Plotting Section, when I try to Plot all the 12 graphs from the loop. I was able to plot every single graph like this - for which I had no errors:

TCanvas *c1 = new TCanvas("c1");
  c1->SetFillColor(10);
  c1->SetGrid();
  c1->SetLogx();
  c1->SetLogy();

  TMultiGraph *mg = new TMultiGraph();

  TGraph *Gra1 = new TGraph("NIST_StoppingPowers/Alpha_Aluminium_StoppingPower.dat","%lg %lg");
  Gra1->SetLineColor(4);
  Gra1->SetLineWidth(4);

  TGraph *Gra2 = new TGraph(37,energy,Alpha_Aluminium_stopping_power);
  Gra2->SetMarkerColor(2);
  Gra2->SetMarkerStyle(21);
  Gra2->SetMarkerSize(1.2);

  mg->Add(Gra1,"cp");
  mg->Add(Gra2,"p");
  mg->Draw("a");

  mg->SetTitle("Aluminium Stopping Power for Alpha Particles");
  mg->GetXaxis()->SetTitle("Energy[MeV]");
  mg->GetYaxis()->SetTitle("Stopping Power [MeV.cm2/g]");

  gPad->Modified();

  leg = new TLegend(0.1,0.7,0.3,0.9);
  leg->SetFillColor(0);
  leg->AddEntry(Gra1,"NIST Database","l");
  leg->AddEntry(Gra2,"GEANT4","p");
  leg->Draw();

Finally, the error I get when trying to plot through the loop is:

Error in <TGraph::TGraph>: Cannot open file: Alpha, TGraph is Zombie
Error: Can't call TGraph::TGraph(37,energy,GEANTFile) in current scope Shielding_Validation.C:142:
Possible candidates are...
(in TGraph)
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(void);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Int_t* x,const Int_t* y);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Float_t* x,const Float_t* y);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Double_t* x,const Double_t* y);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TGraph& gr);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TVectorF& vx,const TVectorF& vy);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TVectorD& vx,const TVectorD& vy);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TH1* h);
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TF1* f,Option_t* option="");
/usr/lib/x86_64-linux-gnu/root5.34/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const char* filename,const char* format="%lg %lg",Option_t* option="");
*** Interpreter error recovered ***

Thanks again for the help.

BR,
Leonardo.

The line:

TGraph *Gra2 = new TGraph(37,energy,GEANTFile);

is invalid… GEANTFile is not an array of double or float … it is a array of char:

char GEANTFile[180];

Thanks for the answer!

Do you have a suggestion on how can I call the double arrays under the for loop?

Leonardo.

Well, I cannot suggest you more than what the doc says. The available TGraph constructors are
listed here you have to choose among this list.

An other approach could be to use SetPoint.

   TGraph *g1 = new TGraph();
   for (int i=0; i<10; i++) g1->SetPoint(i,(double)i,(double)i);
1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.