Read vectors as variables for a TGraph

Hi,
I’m quite unexperienced with ROOT…
I store data (x,y and error of y values) in vectors and want to draw “y : x” with TGraph. Somehow it seems that TGraph doesn’t recognize my vectors.

As a second step I want to add a second graph in my plot with TGraphAsymmErrors; that’s why I use TGraph and not simply a histogram.

#include <fstream>
#include <string>
#include <iostream>
#include <vector>
#include <TGraph.h>
#include <TGraphAsymmErrors.h>
#include <TFile.h>
#include <TCanvas.h>
#include <TH1.h>

using namespace std;
using std::ifstream;

vector<double> xp;
vector<double> F2;
vector<double> errF2;

void plotting(){
//make filenames
	string name,file_mod,file_dat,file_root;
	
		name = "Q1100b394";
		file_mod = "model/" + name + ".dat";

//read model
		int i = 0;
		double mtest;

		ifstream modfile(file_mod.c_str());
		
		while (modfile >> mtest){
			i++;
			if (i%3 == 2){
				F2.push_back(mtest);
			}
			else if (i%3 == 0){
				errF2.push_back(mtest);
			}
			else{
				xp.push_back(mtest);
			}
		}		
		modfile.close();

//TCanvas
	 	gROOT ->SetStyle("Plain");
		TCanvas *c1 = new TCanvas("c1",name.c_str(),200,10,700,500);
	 	gPad->SetLogx(1);
	
// draw a frame to define the range
		TH1F *h = c1->DrawFrame(0.0001,0,0.01,1);

//TGraph
		TGraph *g_mod = new TGraph(xp.size(),xp,F2);

		g_mod ->SetLineColor(1);
	 	g_mod ->SetLineWidth(2);
	 	g_mod ->SetMarkerColor(1);
	 	g_mod ->SetMarkerStyle(1);
	 	g_mod ->GetXaxis()->SetTitle("x_{P}");
	 	g_mod ->GetYaxis()->SetTitle("F2");
	 	g_mod ->GetXaxis()->CenterTitle();
	 	g_mod ->GetYaxis()->CenterTitle();
	 	g_mod ->Draw("CP");

		delete xp;
		delete F2;
		delete errF2;
}

This is my error message:

Error: Can't call TGraph::TGraph(xp.size(),xp,F2) in current scope plotting.cpp:49:
Possible candidates are...
(in TGraph)
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(void);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Int_t* x,const Int_t* y);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Float_t* x,const Float_t* y);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(Int_t n,const Double_t* x,const Double_t* y);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TGraph& gr);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TVectorF& vx,const TVectorF& vy);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TVectorD& vx,const TVectorD& vy);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TH1* h);
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const TF1* f,Option_t* option="");
/Users/***/Programs/root/lib/libHist.so  -1:-1   0 public: TGraph TGraph::TGraph(const char* filename,const char* format="%lg %lg",Option_t* option="");

Thanks a lot for help!
Boginja

Hi,

There is no TGraph constructor taking vectors as arguments. Try this syntax:

   TGraph *g_mod = new TGraph(xp.size(), &xp[0], &F2[0]);

Cheers, Bertrand.

That works perfectly fine Bertrand, thank you!
Can you explain me why?

Boginja

Hi Boginja,

The STL vector is designed to give direct access to its internal array of type (double in this case) by using &vec[0], which is similar to a double *

Cheers, Bertrand.

Should be fixed now

1 Like

@bellenot

I have similar problem. I know we don’t have a graph constructor for a vector. I attach the code here.

AlphaData_Si.txt (7.9 KB)

teststatement.C (4.1 KB)

I want to choose only the energy range between 1 and 4 together with 4 and 10 from the text file I read. First column in the text represents the alpha particle energy, and the another column I read is the range.

Problematic part:

vector x_AlphaCalculated_Si;
vector y_AlphaCalculated_Si;

for(int i=0; i<number2 ; i++){
    
    if(x_AlphaData_Si[i] > 1 && x_AlphaData_Si[i] <=4 )      {
        x_AlphaCalculated_Si.push_back(x_AlphaData_Si[i]) ;
        y_AlphaCalculated_Si.push_back( exp(1.61*sqrt(x_AlphaData_Si[i] )) )   ; }
    
    else if(x_AlphaData_Si[i] >4 && x_AlphaData_Si[i] <= 10) {
        x_AlphaCalculated_Si.push_back(x_AlphaData_Si[i]) ;
        y_AlphaCalculated_Si.push_back( ( (0.05*x_AlphaData_Si[i] ) + 2.85)* pow(x_AlphaData_Si[i], 1.5) ) ; }
    
    else cout << "sucks!" << endl;
    
    cout << "x: "<< x_AlphaData_Si[i] << "  y_data:  " << y_AlphaData_Si[i] << "  y_calculated:  " << y_AlphaCalculated_Si[i]  <<endl;
    
}

TGraph *gr18 = new TGraph(x_AlphaCalculated_Si.size(), &x_AlphaCalculated_Si[0], &y_AlphaCalculated_Si[0]);
//?????  TGraph (const TVectorD &vx, const TVectorD &vy)

And what is “problematic”?

You could simplify it (no need for any vectors):

    TGraph *gr18 = new TGraph();
    for (int i = 0; i < number2; i++) {
      if (x_AlphaData_Si[i] > 1. && x_AlphaData_Si[i] <= 4.)
        gr18->SetPoint(gr18->GetN(), x_AlphaData_Si[i], exp(1.61 * sqrt(x_AlphaData_Si[i])));
      else if (x_AlphaData_Si[i] > 4. && x_AlphaData_Si[i] <= 10.)
        gr18->SetPoint(gr18->GetN(), x_AlphaData_Si[i], (0.05 * x_AlphaData_Si[i] + 2.85) * pow(x_AlphaData_Si[i], 1.5));
      else cout << i << " sucks!" << endl;
    }