# Fitting IV curve with a combination of pol1 and pol2

Hi ROOTers,

I acquired some IV curve and im trying to fit them using a combination of linear and parabola fit. The macro used

``````bool reject = false;

double splitline(const double *x, const double *p) {
// y = a + b * (x - x0) + c * (x - x0) * (x - x0)
double x0 = p[0]; // "point of split"
double a = p[1]; // "left" and "right" (linear and parabolic)
double b_left = p[2]; // "left" (linear)
double b_right = p[3]; // "right" (parabolic)
double c_right = p[4]; // "right" (parabolic)
double dx = x[0] - x0;
// when fitting, exclude points which are close to the "point of split"
if (reject && (dx > -1.075) && (dx < 0.3)) // note: asymmetric range, change it in order to obtain the best chi squared
TF1::RejectPoint();
return (a + ((dx < 0.) ? b_left : b_right + c_right * dx) * dx);
}

void hamamatsu(const char *fname = "1_inversa.txt") {
if (!(fname && fname[0])) return; // just a precaution

TGraphErrors *g = new TGraphErrors(fname);
if (!(g->GetN())) return; // just a precaution
g->Sort(); // just a precaution
g->SetTitle("Curve I-V;Reverse-bias [V];Current [nA]");
g->GetXaxis()->SetNdivisions(1925);
g->GetYaxis()->SetNdivisions(748);

TCanvas *c = new TCanvas("c", "Curve I-V");

c->SetFillColor(0);
c->SetBorderMode(0);
c->SetBorderSize(2);
c->SetFrameBorderMode(0);
c->SetGrid(1, 1);
c->SetTicks(1, 1);
c->SetLogy();

gStyle->SetOptFit(000); // 111 per vedere i parametri di fit

TF1 *f = new TF1("f_splitline", splitline, g->GetX()[0], g->GetX()[(g->GetN() - 1)], 5);

f->SetParNames("x0", "a", "b_left", "b_right", "c_right");
f->SetNpx(8000);
// note: one should always set "reasonable" initial values for all parameters
f->SetParameters((g->GetX()[0] + g->GetX()[(g->GetN() - 1)]) / 2., g->GetY()[0], 0., 0., 0.);
// f->SetParameters(50., 0.1, 0., 10., 10.);
#if 0 /* 0 or 1 */
// try to make the fit more "robust" (when initial parameters are not good)
// f->SetParLimits(0, g->GetX()[0], g->GetX()[(g->GetN() - 1)]); // x0
// f->SetParLimits(1, 0., 1000.); // a >= 0
f->SetParLimits(2, 0., 1000.); // b_left >= 0
f->SetParLimits(3, 0., 1000.); // b_right >= 0
f->SetParLimits(4, 0., 1000.); // c_right >= 0
#endif /* 0 or 1 */

reject = true;
g->Fit(f, "QN"); // first "initial pre-fit"
g->Fit(f, "QN"); // second "initial pre-fit"
g->Fit(f, "QN"); // third "initial pre-fit"
g->Fit(f, "QN"); // fourth "initial pre-fit"
g->Fit(f, ""); // "final fit"
reject = false;

g->Draw("ALP");

}
``````

works perfectly for some kind of curve like HPK_S13_anode10_25C_inv.txt (6,5 KB):

but not the same for another kind of IV curve like Ch1_inv.txt (3,2 KB):

Hi Samuele,

Interesting use case, thanks for sharing.

By looking at your second plot, my first question would be whether you tried to reduce the range in which you perform the fit. For example, your functional form seems to reproduce your data but after 2 or so, judging by some qualitative by-eye analysisâ€¦

I hope this helps.

Best,
D

1 Like

I tried but doesnâ€™t work:

@Danilo do you tried to run locally the macro and second file?

I donâ€™t understand why doesnâ€™t workâ€¦

Hi,

maybe setting the initial value of the parameters could help?

D

Noâ€¦ maybe Iâ€™m doing wrong somethingâ€¦

This code was written thanks the help of @Wile_E_Coyote some times agoâ€¦maybe He can give some suggestion.

Hi,
I think the main issue is the fit of the split parameter, I set the parameter p0 manually to 39.5 and the fit is slightly better as you can see from the figure. Look for a sharp change of the first derivative could be a good way to estimate the split point.

On the other hand I am not sure the same parameter `a` is good both the linear part and parabolic one.

PS

Looking at the graph with linear y scale, the left part doesnâ€™t seem completely linear.

1 Like

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