# Problem when plotting a function

I was given a translated version of a FORTRAN/PAW macro (kumac) in ROOT/C++ (which all my code is in). The macro itself first reads in data, this is then passed to a function (TF1), which is then plotted onto a canvas.

The problem is that the resulting plots (see attachments) look very different. Using my root version, I seem to get a very sharp kink at x=10^-2 and can’t figure out why. Odd behaviour can also be seen right at the top, at y=0.8, where the central (bright red) curve seems to bend into the axis.

Is there a difference in the way that root and paw deal with plotting functions which could explain this? Do I have to change a “smoothness”/number of points setting (SetNumberFitPoints doesn’t seem to work)?

The translated ROOT/C++ function:

``````#ifndef _fcalc_h
#define _fcalc_h 1

double fcalc(double* x, double* pars)
{

double Q2     = pars[0];
double f2Type = pars[1];

double Q2G1, Q2G2, XG1, XG2;
int    IQ2L, IQ2H, IXL, IXH;
double TQ, TX, F2H, F2L, F2;

if((Q2<0.39) || (x[0]<1E-6))
{
return 1.0;
}

// calculate grid points

for(int i=0; i<160; i++)
{

if(i<=71)
{
Q2G1 = pow(10,(5.0*i/120.0))-0.7;
Q2G2 = pow(10,(5.0*(i+1)/120.0))-0.7;
}
else if(i==72)
{
Q2G1 = pow(10,(5.0*i/120.0))-0.7;
Q2G2 = pow(10,(((2.0*(i-71.0)/88.0)+3.0)));
}
else
{
Q2G1 = pow(10,(((2.0*(i-72.0)/88.0)+3.0)));
Q2G2 = pow(10,(((2.0*(i-71.0)/88.0)+3.0)));
}

if((Q2>=Q2G1) && (Q2<Q2G2))
{

IQ2L = i+1;
IQ2H = i+2;
TQ   = (Q2-Q2G1)/(Q2G2-Q2G1);
}
}

for(int i=0; i<160; i++)
{
if(i<=79)
{
XG1 = pow(10,((6.0*i/120.0)-6.0));
XG2 = pow(10,((6.0*(i+1)/120.0)-6.0));

}
else if(i == 80)
{
XG1 = pow(10,((6.0*i/120.0)-6.0));
XG2 = pow(10,((2.0/80.0*(i-79))-2.0));
}
else
{
XG1 = pow(10,((2.0/80.0*(i-80))-2.0));
XG2 = pow(10,((2.0/80.0*(i-79))-2.0));
}

if((x[0]>=XG1) && (x[0]<XG2))
{
IXL = i+1;
IXH = i+2;
TX  = (x[0]-XG1)/(XG2-XG1);

}
}

double f2High, f2Low;

if(f2Type == 0)
{
F2H = (1-TX)*f2p[IXL][IQ2H]+TX*f2p[IXH][IQ2H];
F2L = (1-TX)*f2p[IXL][IQ2L]+TX*f2p[IXH][IQ2L];
}
if(f2Type == 1)
{
F2H = (1-TX)*f2up[IXL][IQ2H]+TX*f2up[IXH][IQ2H];
F2L = (1-TX)*f2up[IXL][IQ2L]+TX*f2up[IXH][IQ2L];
}
if(f2Type == 2)
{
F2H = (1-TX)*f2dn[IXL][IQ2H]+TX*f2dn[IXH][IQ2H];
F2L = (1-TX)*f2dn[IXL][IQ2L]+TX*f2dn[IXH][IQ2L];
}

F2 = (1-TQ)*F2L+TQ*F2H;

if(F2>0)
{

return F2;
}
else
{
return 1E-4;
}

};

#endif``````

The original FORTRAN function:

``````      REAL FUNCTION FCALC(X)

VECTOR F2V(161,161)
VECTOR Q2PASS(1)
VECTOR RESULT(1)

Q2=Q2PASS(1)

IF (Q2.LT.0.39.OR.X.LT.1E-6) THEN
FCALC=1.
RESULT(1)=1.
RETURN
ENDIF

c     calculate grid points

DO I=0,159
IF(I.LE.71)THEN
Q2G1=10**(5.*I/120.)-0.7
Q2G2=10**(5.*(I+1)/120.)-0.7
ELSEIF(I.EQ.72)THEN
Q2G1=10**(5*I/120)-0.7
Q2G2=10**(2*(I-71)/88 +3.)
ELSE
Q2G1=10**(2.*(I-72)/88. +3.)
Q2G2=10**(2.*(I-71)/88. +3.)
ENDIF

IF (Q2.GE.Q2G1.AND.Q2.LT.Q2G2) THEN
IQ2L=I+1
IQ2H=I+2
TQ=(Q2-Q2G1)/(Q2G2-Q2G1)

ENDIF
ENDDO

DO I=0,159
IF(I.LE.79)THEN
XG1=10**(6.*I/120.-6.)
XG2=10**(6.*(I+1)/120.-6.)

if(I.EQ.0)then

end if

ELSEIF(I.EQ.80)THEN
XG1=10**(6*I/120-6.)
XG2=10**(2./80.*(I-79)-2.)
ELSE
XG1=10**(2./80.*(I-80)-2.)
XG2=10**(2./80.*(I-79)-2.)
ENDIF

IF (X.GE.XG1.AND.X.LT.XG2) THEN
IXL=I+1
IXH=I+2
TX=(X-XG1)/(XG2-XG1)

ENDIF
ENDDO

F2H=(1-TX)*F2V(IXL,IQ2H)+TX*F2V(IXH,IQ2H)
F2L=(1-TX)*F2V(IXL,IQ2L)+TX*F2V(IXH,IQ2L)
FCALC=(1-TQ)*F2L+TQ*F2H

IF (FCALC.GT.0) THEN
RESULT(1)=FCALC
ELSE
RESULT(1)=1E-4
ENDIF

RETURN
END``````

My root macro (I’ve attached the relevant data file):

``````#include "fcalc.h"

double f2p[162][162];
double f2up[162][162];
double f2dn[162][162];

int fplot()
{

TString filename = "ff_tot.dat";
ifstream datafile(filename);

if(!datafile.is_open())
{
cerr<<endl<<"Error: can not open file called "<<filename<<endl;
return -1;
}

int i=0, j=0;
while(datafile.good())
{

datafile>>f2p[i][j]>>f2up[i][j]>>f2dn[i][j];

i++;

if(i==161)
{
i=0;
j++;
}
}

datafile.close();

// Plot the functions using fcalc
TCanvas* c1 = new TCanvas("c1","c1",100,100,1000,1000);

TF1* funcP;
TF1* funcUp;
TF1* funcDn;

c1->cd();

double xmin = 0.0001;
double xmax = 0.99;

funP = new TF1("funP",fcalc,xmin,xmax,2);
funP->SetParameter(0,100.0);
funP->SetParameter(1,0);
funP->SetLineColor(50);
funP->SetLineWidth(1.0);
funP->SetMinimum(0.0);
funP->SetMaximum(0.8);
funP->SetNumberFitPoints(2000);
funP->Draw("C");

funUp = new TF1("funUp",fcalc,xmin,xmax,2);
funUp->SetParameter(0,100.0);
funUp->SetParameter(1,1);
funUp->SetLineColor(48);
funUp->SetLineWidth(1.0);
funUp->Draw("C same");

funDn = new TF1("funDn",fcalc,xmin,xmax,2);
funDn->SetParameter(0,100.0);
funDn->SetParameter(1,2);
funDn->SetLineColor(45);
funDn->SetLineWidth(1.0);
funDn->Draw("C same");

c1->Print("c1.eps");

return 0;
}``````

c1.eps.gz (3.31 KB)
paw1.eps.gz (3.66 KB)
ff_tot.txt (987 KB)

Are you sure that your first function parameter (that you set=280) is correct?
I can obtain the PAW result by setting it to around 100.

Rene

I changed the first parameter to 100 and still get the same problems as outlined in my original post (see attachment), such as the prominent kink at 10^-2 and the strange behaviour at the top with the curve bending across the axis. Can you post the root plot that you get Rene?

cheers
c_p0_100.eps.gz (3.27 KB)

The kink at around 10^-2 seems to be due to wrong values of IXL and IXH in fcal.c
If you change the statements

``` IXL = i+1; IXH = i+2; ```to

``` IXL = i+0; IXH = i+1; ```
you will see that this kink nearly disappears like in PAW.
Up to you to continue the investigation. In attachement the plot I obtain.

Rene
c1.eps.gz (4.02 KB)

I define a function here which I want to plot

{
Int_t m=1;
TF1 *gr = new TF1 (“plot”,“m-sin(x)”,-1,1);
gr->Draw();
}

I want to write the m specifically as it is written above. Can somebody tell me why ROOT is it not plotting it?

[quote=“bajarang”]I define a function here which I want to plot

{
Int_t m=1;
TF1 *gr = new TF1 (“plot”,“m-sin(x)”,-1,1);
gr->Draw();
}

I want to write the m specifically as it is written above. Can somebody tell me why ROOT is it not plotting it?
```{ Int_t m=1; TF1 *gr = new TF1 ("plot","[0]-sin(x)",-1,1,1); gr->SetParameter(0,m); gr->Draw(); }```