#include <string.h>
#include "Riostream.h"
#include "TROOT.h"
#include "TEnv.h"
#include "TGraph.h"
#include "TGaxis.h"
#include "TH1.h"
#include "TF1.h"
#include "TStyle.h"
#include "TMath.h"
#include "TFrame.h"
#include "TVector.h"
#include "TVectorD.h"
#include "Foption.h"
#include "TRandom.h"
#include "TSpline.h"
#include "TPaveStats.h"
#include "TVirtualFitter.h"
#include "TVirtualPad.h"
#include "TVirtualGraphPainter.h"
#include "TBrowser.h"
#include "TClass.h"
#include "TSystem.h"
#include "TPluginManager.h"
#include <stdlib.h>
#include <string>
extern void H1LeastSquareSeqnd(Int_t n, Double_t *a, Int_t idim, Int_t &ifail, Int_t k, Double_t *b);
ClassImp(TGraph)
TGraph::TGraph(): TNamed(), TAttLine(), TAttFill(1,1001), TAttMarker()
{
fNpoints = -1;
CtorAllocate();
}
TGraph::TGraph(Int_t n)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
fNpoints = n;
if (!CtorAllocate()) return;
FillZero(0, fNpoints);
}
TGraph::TGraph(Int_t n, const Int_t *x, const Int_t *y)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
if (!x || !y) {
fNpoints = 0;
} else {
fNpoints = n;
}
if (!CtorAllocate()) return;
for (Int_t i=0;i<n;i++) {
fX[i] = (Double_t)x[i];
fY[i] = (Double_t)y[i];
}
}
TGraph::TGraph(Int_t n, const Float_t *x, const Float_t *y)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
if (!x || !y) {
fNpoints = 0;
} else {
fNpoints = n;
}
if (!CtorAllocate()) return;
for (Int_t i=0;i<n;i++) {
fX[i] = x[i];
fY[i] = y[i];
}
}
TGraph::TGraph(Int_t n, const Double_t *x, const Double_t *y)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
if (!x || !y) {
fNpoints = 0;
} else {
fNpoints = n;
}
if (!CtorAllocate()) return;
n = fNpoints*sizeof(Double_t);
memcpy(fX, x, n);
memcpy(fY, y, n);
}
TGraph::TGraph(const TGraph &gr)
: TNamed(gr), TAttLine(gr), TAttFill(gr), TAttMarker(gr)
{
fNpoints = gr.fNpoints;
fMaxSize = gr.fMaxSize;
if (gr.fFunctions) fFunctions = (TList*)gr.fFunctions->Clone();
else fFunctions = new TList;
fHistogram = 0;
fMinimum = gr.fMinimum;
fMaximum = gr.fMaximum;
if (!fMaxSize) {
fX = fY = 0;
return;
} else {
fX = new Double_t[fMaxSize];
fY = new Double_t[fMaxSize];
}
Int_t n = gr.GetN()*sizeof(Double_t);
memcpy(fX, gr.fX, n);
memcpy(fY, gr.fY, n);
}
TGraph& TGraph::operator=(const TGraph &gr)
{
if(this!=&gr) {
TNamed::operator=(gr);
TAttLine::operator=(gr);
TAttFill::operator=(gr);
TAttMarker::operator=(gr);
fNpoints = gr.fNpoints;
fMaxSize = gr.fMaxSize;
if (gr.fFunctions) fFunctions = (TList*)gr.fFunctions->Clone();
else fFunctions = new TList;
if (gr.fHistogram) fHistogram = new TH1F(*(gr.fHistogram));
else fHistogram = 0;
fMinimum = gr.fMinimum;
fMaximum = gr.fMaximum;
if (!fMaxSize) {
fX = fY = 0;
return *this;
} else {
fX = new Double_t[fMaxSize];
fY = new Double_t[fMaxSize];
}
Int_t n = gr.GetN()*sizeof(Double_t);
if (n>0) {
memcpy(fX, gr.fX, n);
memcpy(fY, gr.fY, n);
}
}
return *this;
}
TGraph::TGraph(const TVectorF &vx, const TVectorF &vy)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
if (!CtorAllocate()) return;
Int_t ivxlow = vx.GetLwb();
Int_t ivylow = vy.GetLwb();
for (Int_t i=0;i<fNpoints;i++) {
fX[i] = vx(i+ivxlow);
fY[i] = vy(i+ivylow);
}
}
TGraph::TGraph(const TVectorD &vx, const TVectorD &vy)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
if (!CtorAllocate()) return;
Int_t ivxlow = vx.GetLwb();
Int_t ivylow = vy.GetLwb();
for (Int_t i=0;i<fNpoints;i++) {
fX[i] = vx(i+ivxlow);
fY[i] = vy(i+ivylow);
}
}
TGraph::TGraph(const TH1 *h)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
if (!h) {
Error("TGraph", "Pointer to histogram is null");
fNpoints = 0;
}
if (h->GetDimension() != 1) {
Error("TGraph", "Histogram must be 1-D; h %s is %d-D",h->GetName(),h->GetDimension());
fNpoints = 0;
} else {
fNpoints = ((TH1*)h)->GetXaxis()->GetNbins();
}
if (!CtorAllocate()) return;
TAxis *xaxis = ((TH1*)h)->GetXaxis();
for (Int_t i=0;i<fNpoints;i++) {
fX[i] = xaxis->GetBinCenter(i+1);
fY[i] = h->GetBinContent(i+1);
}
h->TAttLine::Copy(*this);
h->TAttFill::Copy(*this);
h->TAttMarker::Copy(*this);
std::string gname = "Graph_from_" + std::string(h->GetName() );
SetName(gname.c_str());
SetTitle(h->GetTitle());
}
TGraph::TGraph(const TF1 *f, Option_t *option)
: TNamed("Graph","Graph"), TAttLine(), TAttFill(1,1001), TAttMarker()
{
char coption = ' ';
if (!f) {
Error("TGraph", "Pointer to function is null");
fNpoints = 0;
} else {
fNpoints = f->GetNpx();
if (option) coption = *option;
if (coption == 'i' || coption == 'I') fNpoints++;
}
if (!CtorAllocate()) return;
Double_t xmin = f->GetXmin();
Double_t xmax = f->GetXmax();
Double_t dx = (xmax-xmin)/fNpoints;
Double_t integ = 0;
Int_t i;
for (i=0;i<fNpoints;i++) {
if (coption == 'i' || coption == 'I') {
fX[i] = xmin +i*dx;
if (i == 0) fY[i] = 0;
else fY[i] = integ + ((TF1*)f)->Integral(fX[i]-dx,fX[i]);
integ = fY[i];
} else if (coption == 'd' || coption == 'D') {
fX[i] = xmin + (i+0.5)*dx;
fY[i] = ((TF1*)f)->Derivative(fX[i]);
} else {
fX[i] = xmin + (i+0.5)*dx;
fY[i] = ((TF1*)f)->Eval(fX[i]);
}
}
if (integ != 0 && coption == 'I') {
for (i=1;i<fNpoints;i++) fY[i] /= integ;
}
f->TAttLine::Copy(*this);
f->TAttFill::Copy(*this);
f->TAttMarker::Copy(*this);
SetName(f->GetName());
SetTitle(f->GetTitle());
}
TGraph::TGraph(const char *filename, const char *format, Option_t *)
: TNamed("Graph",filename), TAttLine(), TAttFill(1,1001), TAttMarker()
{
Double_t x,y;
ifstream infile(filename);
if(!infile.good()){
MakeZombie();
Error("TGraph", "Cannot open file: %s, TGraph is Zombie",filename);
fNpoints = 0;
} else {
fNpoints = 100;
}
if (!CtorAllocate()) return;
std::string line;
Int_t np=0;
while(std::getline(infile,line,'\n')){
if(2 != sscanf(line.c_str(),format,&x,&y) ) {
continue;
}
SetPoint(np,x,y);
np++;
}
Set(np);
}
TGraph::~TGraph()
{
delete [] fX;
delete [] fY;
if (fFunctions) {
fFunctions->SetBit(kInvalidObject);
TObject *obj;
while ((obj = fFunctions->First())) {
while(fFunctions->Remove(obj)) { }
delete obj;
}
delete fFunctions;
fFunctions = 0;
}
delete fHistogram;
}
Double_t** TGraph::AllocateArrays(Int_t Narrays, Int_t arraySize)
{
if (arraySize < 0) { arraySize = 0; }
Double_t **newarrays = new Double_t*[Narrays];
if (!arraySize) {
for (Int_t i = 0; i < Narrays; ++i)
newarrays[i] = 0;
} else {
for (Int_t i = 0; i < Narrays; ++i)
newarrays[i] = new Double_t[arraySize];
}
fMaxSize = arraySize;
return newarrays;
}
void TGraph::Apply(TF1 *f)
{
for (Int_t i=0;i<fNpoints;i++) {
fY[i] = f->Eval(fX[i],fY[i]);
}
}
void TGraph::Browse(TBrowser *b)
{
TString opt = gEnv->GetValue("TGraph.BrowseOption","");
if (opt.IsNull()) {
opt = b ? b->GetDrawOption() : "alp";
}
Draw(opt.Data());
gPad->Update();
}
Double_t TGraph::Chisquare(const TF1 *f1) const
{
// #frac{(y-f1(x))^{2}}{ey^{2}+(#frac{1}{2}(exl+exh)f1'(x))^{2}}
// End_latex
if (!f1) return 0;
Double_t cu,eu,exh,exl,ey,eux,fu,fsum;
Double_t x[1];
Double_t chi2 = 0;
TF1 *func = (TF1*)f1;
for (Int_t i=0;i<fNpoints;i++) {
func->InitArgs(x,0);
x[0] = fX[i];
if (!func->IsInside(x)) continue;
cu = fY[i];
TF1::RejectPoint(kFALSE);
fu = func->EvalPar(x);
if (TF1::RejectedPoint()) continue;
fsum = (cu-fu);
exh = GetErrorXhigh(i);
exl = GetErrorXlow(i);
if (fsum < 0)
ey = GetErrorYhigh(i);
else
ey = GetErrorYlow(i);
if (exl < 0) exl = 0;
if (exh < 0) exh = 0;
if (ey < 0) ey = 0;
if (exh > 0 || exl > 0) {
eux = 0.5*(exl + exh)*func->Derivative(x[0]);
} else
eux = 0.;
eu = ey*ey+eux*eux;
if (eu <= 0) eu = 1;
chi2 += fsum*fsum/eu;
}
return chi2;
}
Bool_t TGraph::CompareArg(const TGraph* gr, Int_t left, Int_t right)
{
Double_t xl,yl,xr,yr;
gr->GetPoint(left,xl,yl);
gr->GetPoint(right,xr,yr);
return (TMath::ATan2(yl, xl) > TMath::ATan2(yr, xr));
}
Bool_t TGraph::CompareX(const TGraph* gr, Int_t left, Int_t right)
{
return gr->fX[left]>gr->fX[right];
}
Bool_t TGraph::CompareY(const TGraph* gr, Int_t left, Int_t right)
{
return gr->fY[left]>gr->fY[right];
}
Bool_t TGraph::CompareRadius(const TGraph* gr, Int_t left, Int_t right)
{
return gr->fX[left]*gr->fX[left]+gr->fY[left]*gr->fY[left]
>gr->fX[right]*gr->fX[right]+gr->fY[right]*gr->fY[right];
}
void TGraph::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
{
if (fNpoints <= 0) {
xmin=xmax=ymin=ymax = 0;
return;
}
xmin = xmax = fX[0];
ymin = ymax = fY[0];
for (Int_t i=1;i<fNpoints;i++) {
if (fX[i] < xmin) xmin = fX[i];
if (fX[i] > xmax) xmax = fX[i];
if (fY[i] < ymin) ymin = fY[i];
if (fY[i] > ymax) ymax = fY[i];
}
}
void TGraph::CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend,
Int_t obegin)
{
CopyPoints(newarrays, ibegin, iend, obegin);
if (newarrays) {
delete[] fX;
fX = newarrays[0];
delete[] fY;
fY = newarrays[1];
delete[] newarrays;
}
}
Bool_t TGraph::CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend,
Int_t obegin)
{
if (ibegin < 0 || iend <= ibegin || obegin < 0) {
return kFALSE;
}
if (!arrays && ibegin == obegin) {
return kFALSE;
}
Int_t n = (iend - ibegin)*sizeof(Double_t);
if (arrays) {
memmove(&arrays[0][obegin], &fX[ibegin], n);
memmove(&arrays[1][obegin], &fY[ibegin], n);
} else {
memmove(&fX[obegin], &fX[ibegin], n);
memmove(&fY[obegin], &fY[ibegin], n);
}
return kTRUE;
}
Bool_t TGraph::CtorAllocate()
{
fHistogram = 0;
fMaximum = -1111;
fMinimum = -1111;
SetBit(kClipFrame);
fFunctions = 0;
if (fNpoints >= 0) fFunctions = new TList;
if (fNpoints <= 0) {
fNpoints = 0;
fMaxSize = 0;
fX = 0;
fY = 0;
return kFALSE;
} else {
fMaxSize = fNpoints;
fX = new Double_t[fMaxSize];
fY = new Double_t[fMaxSize];
}
return kTRUE;
}
void TGraph::Draw(Option_t *option)
{
TString opt = option;
opt.ToLower();
if (opt.Contains("same")) {
opt.ReplaceAll("same","");
}
Ssiz_t pos;
if ((pos = opt.Index("*")) != kNPOS) {
SetMarkerStyle(3);
opt.Replace(pos, 1, "p");
}
if (gPad) {
if (!gPad->IsEditable()) gROOT->MakeDefCanvas();
if (opt.Contains("a")) gPad->Clear();
}
AppendPad(opt);
}
Int_t TGraph::DistancetoPrimitive(Int_t px, Int_t py)
{
return TVirtualGraphPainter::GetPainter()->DistancetoPrimitiveHelper(this, px,py);
}
void TGraph::DrawGraph(Int_t n, const Int_t *x, const Int_t *y, Option_t *option)
{
TGraph *newgraph = new TGraph(n, x, y);
TAttLine::Copy(*newgraph);
TAttFill::Copy(*newgraph);
TAttMarker::Copy(*newgraph);
newgraph->SetBit(kCanDelete);
newgraph->AppendPad(option);
}
void TGraph::DrawGraph(Int_t n, const Float_t *x, const Float_t *y, Option_t *option)
{
TGraph *newgraph = new TGraph(n, x, y);
TAttLine::Copy(*newgraph);
TAttFill::Copy(*newgraph);
TAttMarker::Copy(*newgraph);
newgraph->SetBit(kCanDelete);
newgraph->AppendPad(option);
}
void TGraph::DrawGraph(Int_t n, const Double_t *x, const Double_t *y, Option_t *option)
{
const Double_t *xx = x;
const Double_t *yy = y;
if (!xx) xx = fX;
if (!yy) yy = fY;
TGraph *newgraph = new TGraph(n, xx, yy);
TAttLine::Copy(*newgraph);
TAttFill::Copy(*newgraph);
TAttMarker::Copy(*newgraph);
newgraph->SetBit(kCanDelete);
newgraph->AppendPad(option);
}
void TGraph::DrawPanel()
{
TVirtualGraphPainter::GetPainter()->DrawPanelHelper(this);
}
Double_t TGraph::Eval(Double_t x, TSpline *spline, Option_t *option) const
{
if (!spline) {
TString opt = option;
opt.ToLower();
if (opt.Contains("s")) {
TSpline3 *s = new TSpline3("",this);
Double_t result = s->Eval(x);
delete s;
return result;
}
Int_t low = TMath::BinarySearch(fNpoints,fX,x);
Int_t up = low+1;
if (low == fNpoints-1) {up=low; low = up-1;}
if (low == -1) {low=0; up=1;}
if (fX[low] == fX[up]) return fY[low];
Double_t yn = x*(fY[low]-fY[up]) +fX[low]*fY[up] - fX[up]*fY[low];
return yn/(fX[low]-fX[up]);
} else {
return spline->Eval(x);
}
}
void TGraph::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
TVirtualGraphPainter::GetPainter()->ExecuteEventHelper(this, event, px, py);
}
void TGraph::Expand(Int_t newsize)
{
Double_t **ps = ExpandAndCopy(newsize, fNpoints);
CopyAndRelease(ps, 0, 0, 0);
}
void TGraph::Expand(Int_t newsize, Int_t step)
{
if (newsize <= fMaxSize) {
return;
}
Double_t **ps = Allocate(step*(newsize/step + (newsize%step?1:0)));
CopyAndRelease(ps, 0, fNpoints, 0);
}
Double_t **TGraph::ExpandAndCopy(Int_t size, Int_t iend)
{
if (size <= fMaxSize) { return 0; }
Double_t **newarrays = Allocate(2*size);
CopyPoints(newarrays, 0, iend, 0);
return newarrays;
}
void TGraph::FillZero(Int_t begin, Int_t end, Bool_t)
{
memset(fX + begin, 0, (end - begin)*sizeof(Double_t));
memset(fY + begin, 0, (end - begin)*sizeof(Double_t));
}
TObject *TGraph::FindObject(const char *name) const
{
if (fFunctions) return fFunctions->FindObject(name);
return 0;
}
TObject *TGraph::FindObject(const TObject *obj) const
{
if (fFunctions) return fFunctions->FindObject(obj);
return 0;
}
Int_t TGraph::Fit(const char *fname, Option_t *option, Option_t *, Axis_t xmin, Axis_t xmax)
{
char *linear;
linear= (char*) strstr(fname, "++");
TF1 *f1=0;
if (linear)
f1=new TF1(fname, fname, xmin, xmax);
else {
f1 = (TF1*)gROOT->GetFunction(fname);
if (!f1) { Printf("Unknown function: %s",fname); return -1; }
}
return Fit(f1,option,"",xmin,xmax);
}
Int_t TGraph::Fit(TF1 *f1, Option_t *option, Option_t *goption, Axis_t rxmin, Axis_t rxmax)
{
// #frac{(y-f(x))^{2}}{ey^{2}+(#frac{1}{2}(exl+exh)f'(x))^{2}}
// End_Latex
return DoFit( f1 , option , goption, rxmin, rxmax);
}
void TGraph::FitPanel()
{
if (!gPad)
gROOT->MakeDefCanvas();
if (!gPad) {
Error("FitPanel", "Unable to create a default canvas");
return;
}
TPluginHandler *handler = gROOT->GetPluginManager()->FindHandler("TFitEditor");
if (handler && handler->LoadPlugin() != -1) {
if (handler->ExecPlugin(2, gPad, this) == 0)
Error("FitPanel", "Unable to crate the FitPanel");
}
else
Error("FitPanel", "Unable to find the FitPanel plug-in");
}
Double_t TGraph::GetCorrelationFactor() const
{
Double_t rms1 = GetRMS(1);
if (rms1 == 0) return 0;
Double_t rms2 = GetRMS(2);
if (rms2 == 0) return 0;
return GetCovariance()/rms1/rms2;
}
Double_t TGraph::GetCovariance() const
{
if (fNpoints <= 0) return 0;
Double_t sum = fNpoints, sumx = 0, sumy = 0, sumxy = 0;
for (Int_t i=0;i<fNpoints;i++) {
sumx += fX[i];
sumy += fY[i];
sumxy += fX[i]*fY[i];
}
return sumxy/sum - sumx/sum*sumy/sum;
}
Double_t TGraph::GetMean(Int_t axis) const
{
if (axis < 1 || axis > 2) return 0;
if (fNpoints <= 0) return 0;
Double_t sumx = 0;
for (Int_t i=0;i<fNpoints;i++) {
if (axis == 1) sumx += fX[i];
else sumx += fY[i];
}
return sumx/fNpoints;
}
Double_t TGraph::GetRMS(Int_t axis) const
{
if (axis < 1 || axis > 2) return 0;
if (fNpoints <= 0) return 0;
Double_t sumx = 0, sumx2 = 0;
for (Int_t i=0;i<fNpoints;i++) {
if (axis == 1) {sumx += fX[i]; sumx2 += fX[i]*fX[i];}
else {sumx += fY[i]; sumx2 += fY[i]*fY[i];}
}
Double_t x = sumx/fNpoints;
Double_t rms2 = TMath::Abs(sumx2/fNpoints -x*x);
return TMath::Sqrt(rms2);
}
Double_t TGraph::GetErrorX(Int_t) const
{
return -1;
}
Double_t TGraph::GetErrorY(Int_t) const
{
return -1;
}
Double_t TGraph::GetErrorXhigh(Int_t) const
{
return -1;
}
Double_t TGraph::GetErrorXlow(Int_t) const
{
return -1;
}
Double_t TGraph::GetErrorYhigh(Int_t) const
{
return -1;
}
Double_t TGraph::GetErrorYlow(Int_t) const
{
return -1;
}
TF1 *TGraph::GetFunction(const char *name) const
{
if (!fFunctions) return 0;
return (TF1*)fFunctions->FindObject(name);
}
TH1F *TGraph::GetHistogram() const
{
if (fHistogram) return fHistogram;
Double_t rwxmin,rwxmax, rwymin, rwymax, maximum, minimum, dx, dy;
Double_t uxmin, uxmax;
ComputeRange(rwxmin, rwymin, rwxmax, rwymax);
if (rwxmin == rwxmax) rwxmax += 1.;
if (rwymin == rwymax) rwymax += 1.;
dx = 0.1*(rwxmax-rwxmin);
dy = 0.1*(rwymax-rwymin);
uxmin = rwxmin - dx;
uxmax = rwxmax + dx;
minimum = rwymin - dy;
maximum = rwymax + dy;
if (fMinimum != -1111) minimum = fMinimum;
if (fMaximum != -1111) maximum = fMaximum;
if (uxmin < 0 && rwxmin >= 0) {
if (gPad && gPad->GetLogx()) uxmin = 0.9*rwxmin;
else uxmin = 0;
}
if (uxmax > 0 && rwxmax <= 0) {
if (gPad && gPad->GetLogx()) uxmax = 1.1*rwxmax;
else uxmax = 0;
}
if (minimum < 0 && rwymin >= 0) {
if(gPad && gPad->GetLogy()) minimum = 0.9*rwymin;
else minimum = 0;
}
if (minimum <= 0 && gPad && gPad->GetLogy()) minimum = 0.001*maximum;
if (uxmin <= 0 && gPad && gPad->GetLogx()) {
if (uxmax > 1000) uxmin = 1;
else uxmin = 0.001*uxmax;
}
rwxmin = uxmin;
rwxmax = uxmax;
Int_t npt = 100;
if (fNpoints > npt) npt = fNpoints;
const char *gname = GetName();
if (strlen(gname) == 0) gname = "Graph";
((TGraph*)this)->fHistogram = new TH1F(gname,GetTitle(),npt,rwxmin,rwxmax);
if (!fHistogram) return 0;
fHistogram->SetMinimum(minimum);
fHistogram->SetBit(TH1::kNoStats);
fHistogram->SetMaximum(maximum);
fHistogram->GetYaxis()->SetLimits(minimum,maximum);
fHistogram->SetDirectory(0);
return fHistogram;
}
Int_t TGraph::GetPoint(Int_t i, Double_t &x, Double_t &y) const
{
if (i < 0 || i >= fNpoints) return -1;
if (!fX || !fY) return -1;
x = fX[i];
y = fY[i];
return i;
}
TAxis *TGraph::GetXaxis() const
{
TH1 *h = GetHistogram();
if (!h) return 0;
return h->GetXaxis();
}
TAxis *TGraph::GetYaxis() const
{
TH1 *h = GetHistogram();
if (!h) return 0;
return h->GetYaxis();
}
void TGraph::InitGaus(Double_t xmin, Double_t xmax)
{
Double_t allcha, sumx, sumx2, x, val, rms, mean;
Int_t bin;
const Double_t sqrtpi = 2.506628;
if (xmax <= xmin) {xmin = fX[0]; xmax = fX[fNpoints-1];}
Int_t np = 0;
allcha = sumx = sumx2 = 0;
for (bin=0;bin<fNpoints;bin++) {
x = fX[bin];
if (x < xmin || x > xmax) continue;
np++;
val = fY[bin];
sumx += val*x;
sumx2 += val*x*x;
allcha += val;
}
if (np == 0 || allcha == 0) return;
mean = sumx/allcha;
rms = TMath::Sqrt(sumx2/allcha - mean*mean);
Double_t binwidx = TMath::Abs((xmax-xmin)/np);
if (rms == 0) rms = 1;
TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
TF1 *f1 = (TF1*)grFitter->GetUserFunc();
f1->SetParameter(0,binwidx*allcha/(sqrtpi*rms));
f1->SetParameter(1,mean);
f1->SetParameter(2,rms);
f1->SetParLimits(2,0,10*rms);
}
void TGraph::InitExpo(Double_t xmin, Double_t xmax)
{
Double_t constant, slope;
Int_t ifail;
if (xmax <= xmin) {xmin = fX[0]; xmax = fX[fNpoints-1];}
Int_t nchanx = fNpoints;
LeastSquareLinearFit(-nchanx, constant, slope, ifail, xmin, xmax);
TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
TF1 *f1 = (TF1*)grFitter->GetUserFunc();
f1->SetParameter(0,constant);
f1->SetParameter(1,slope);
}
void TGraph::InitPolynom(Double_t xmin, Double_t xmax)
{
Double_t fitpar[25];
TVirtualFitter *grFitter = TVirtualFitter::GetFitter();
TF1 *f1 = (TF1*)grFitter->GetUserFunc();
Int_t npar = f1->GetNpar();
if (xmax <= xmin) {xmin = fX[0]; xmax = fX[fNpoints-1];}
LeastSquareFit(npar, fitpar, xmin, xmax);
for (Int_t i=0;i<npar;i++) f1->SetParameter(i, fitpar[i]);
}
Int_t TGraph::InsertPoint()
{
Int_t px = gPad->GetEventX();
Int_t py = gPad->GetEventY();
Int_t ipoint = -2;
Int_t i,d=0;
for (i=0;i<fNpoints-1;i++) {
d = DistancetoLine(px, py, gPad->XtoPad(fX[i]), gPad->YtoPad(fY[i]), gPad->XtoPad(fX[i+1]), gPad->YtoPad(fY[i+1]));
if (d < 5) {ipoint = i+1; break;}
}
if (ipoint == -2) {
for (i=0;i<fNpoints-1;i++) {
d = DistancetoLine(px, py, gPad->XtoPad(fX[i]), gPad->YtoPad(fY[i]), gPad->XtoPad(fX[i+1]), gPad->YtoPad(fY[i+1]));
if (d < 10) {ipoint = i+1; break;}
}
}
if (ipoint == -2) {
Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[0]));
Int_t dpy = py - gPad->YtoAbsPixel(gPad->XtoPad(fY[0]));
if (dpx*dpx+dpy*dpy < 25) ipoint = 0;
else ipoint = fNpoints;
}
Double_t **ps = ExpandAndCopy(fNpoints + 1, ipoint);
CopyAndRelease(ps, ipoint, fNpoints++, ipoint + 1);
FillZero(ipoint, ipoint + 1);
fX[ipoint] = gPad->PadtoX(gPad->AbsPixeltoX(px));
fY[ipoint] = gPad->PadtoY(gPad->AbsPixeltoY(py));
gPad->Modified();
return ipoint;
}
void TGraph::LeastSquareFit(Int_t m, Double_t *a, Double_t xmin, Double_t xmax)
{
const Double_t zero = 0.;
const Double_t one = 1.;
const Int_t idim = 20;
Double_t b[400] ;
Int_t i, k, l, ifail;
Double_t power;
Double_t da[20], xk, yk;
Int_t n = fNpoints;
if (xmax <= xmin) {xmin = fX[0]; xmax = fX[fNpoints-1];}
if (m <= 2) {
LeastSquareLinearFit(n, a[0], a[1], ifail, xmin, xmax);
return;
}
if (m > idim || m > n) return;
da[0] = zero;
for (l = 2; l <= m; ++l) {
b[l-1] = zero;
b[m + l*20 - 21] = zero;
da[l-1] = zero;
}
Int_t np = 0;
for (k = 0; k < fNpoints; ++k) {
xk = fX[k];
if (xk < xmin || xk > xmax) continue;
np++;
yk = fY[k];
power = one;
da[0] += yk;
for (l = 2; l <= m; ++l) {
power *= xk;
b[l-1] += power;
da[l-1] += power*yk;
}
for (l = 2; l <= m; ++l) {
power *= xk;
b[m + l*20 - 21] += power;
}
}
b[0] = Double_t(np);
for (i = 3; i <= m; ++i) {
for (k = i; k <= m; ++k) {
b[k - 1 + (i-1)*20 - 21] = b[k + (i-2)*20 - 21];
}
}
H1LeastSquareSeqnd(m, b, idim, ifail, 1, da);
if (ifail < 0) {
a[0] = fY[0];
for (i=1; i<m; ++i) a[i] = 0;
return;
}
for (i=0; i<m; ++i) a[i] = da[i];
}
void TGraph::LeastSquareLinearFit(Int_t ndata, Double_t &a0, Double_t &a1, Int_t &ifail, Double_t xmin, Double_t xmax)
{
Double_t xbar, ybar, x2bar;
Int_t i;
Double_t xybar;
Double_t fn, xk, yk;
Double_t det;
if (xmax <= xmin) {xmin = fX[0]; xmax = fX[fNpoints-1];}
ifail = -2;
xbar = ybar = x2bar = xybar = 0;
Int_t np = 0;
for (i = 0; i < fNpoints; ++i) {
xk = fX[i];
if (xk < xmin || xk > xmax) continue;
np++;
yk = fY[i];
if (ndata < 0) {
if (yk <= 0) yk = 1e-9;
yk = TMath::Log(yk);
}
xbar += xk;
ybar += yk;
x2bar += xk*xk;
xybar += xk*yk;
}
fn = Double_t(np);
det = fn*x2bar - xbar*xbar;
ifail = -1;
if (det <= 0) {
if (fn > 0) a0 = ybar/fn;
else a0 = 0;
a1 = 0;
return;
}
ifail = 0;
a0 = (x2bar*ybar - xbar*xybar) / det;
a1 = (fn*xybar - xbar*ybar) / det;
}
void TGraph::Paint(Option_t *option)
{
TVirtualGraphPainter::GetPainter()->PaintHelper(this, option);
}
void TGraph::PaintGraph(Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
{
TVirtualGraphPainter::GetPainter()->PaintGraph(this, npoints, x, y, chopt);
}
void TGraph::PaintGrapHist(Int_t npoints, const Double_t *x, const Double_t *y, Option_t *chopt)
{
TVirtualGraphPainter::GetPainter()->PaintGrapHist(this, npoints, x, y, chopt);
}
void TGraph::PaintStats(TF1 *fit)
{
TVirtualGraphPainter::GetPainter()->PaintStats(this, fit);
}
void TGraph::Print(Option_t *) const
{
for (Int_t i=0;i<fNpoints;i++) {
printf("x[%d]=%g, y[%d]=%g\n",i,fX[i],i,fY[i]);
}
}
void TGraph::RecursiveRemove(TObject *obj)
{
if (fFunctions) {
if (!fFunctions->TestBit(kInvalidObject)) fFunctions->RecursiveRemove(obj);
}
}
Int_t TGraph::RemovePoint()
{
Int_t px = gPad->GetEventX();
Int_t py = gPad->GetEventY();
Int_t ipoint = -2;
Int_t i;
for (i=0;i<fNpoints;i++) {
Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
if (dpx*dpx+dpy*dpy < 100) {ipoint = i; break;}
}
return RemovePoint(ipoint);
}
Int_t TGraph::RemovePoint(Int_t ipoint)
{
if (ipoint < 0) return -1;
if (ipoint >= fNpoints) return -1;
Double_t **ps = ShrinkAndCopy(fNpoints - 1, ipoint);
CopyAndRelease(ps, ipoint+1, fNpoints--, ipoint);
if (gPad) gPad->Modified();
return ipoint;
}
void TGraph::SavePrimitive(ostream &out, Option_t *option )
{
char quote = '"';
out<<" "<<endl;
if (gROOT->ClassSaved(TGraph::Class())) {
out<<" ";
} else {
out<<" TGraph *";
}
out<<"graph = new TGraph("<<fNpoints<<");"<<endl;
out<<" graph->SetName("<<quote<<GetName()<<quote<<");"<<endl;
out<<" graph->SetTitle("<<quote<<GetTitle()<<quote<<");"<<endl;
SaveFillAttributes(out,"graph",0,1001);
SaveLineAttributes(out,"graph",1,1,1);
SaveMarkerAttributes(out,"graph",1,1,1);
for (Int_t i=0;i<fNpoints;i++) {
out<<" graph->SetPoint("<<i<<","<<fX[i]<<","<<fY[i]<<");"<<endl;
}
static Int_t frameNumber = 0;
if (fHistogram) {
frameNumber++;
TString hname = fHistogram->GetName();
hname += frameNumber;
fHistogram->SetName(hname.Data());
fHistogram->SavePrimitive(out,"nodraw");
out<<" graph->SetHistogram("<<fHistogram->GetName()<<");"<<endl;
out<<" "<<endl;
}
TIter next(fFunctions);
TObject *obj;
while ((obj=next())) {
obj->SavePrimitive(out,"nodraw");
if (obj->InheritsFrom("TPaveStats")) {
out<<" graph->GetListOfFunctions()->Add(ptstats);"<<endl;
out<<" ptstats->SetParent(graph->GetListOfFunctions());"<<endl;
} else {
out<<" graph->GetListOfFunctions()->Add("<<obj->GetName()<<");"<<endl;
}
}
const char *l = strstr(option,"multigraph");
if (l) {
out<<" multigraph->Add(graph,"<<quote<<l+10<<quote<<");"<<endl;
} else {
out<<" graph->Draw("<<quote<<option<<quote<<");"<<endl;
}
}
void TGraph::Set(Int_t n)
{
if (n < 0) n = 0;
if (n == fNpoints) return;
Double_t **ps = Allocate(n);
CopyAndRelease(ps, 0, TMath::Min(fNpoints,n), 0);
if (n > fNpoints) {
FillZero(fNpoints, n, kFALSE);
}
fNpoints = n;
}
Bool_t TGraph::GetEditable() const
{
return TestBit(kNotEditable) ? kFALSE : kTRUE;
}
void TGraph::SetEditable(Bool_t editable)
{
if (editable) ResetBit(kNotEditable);
else SetBit(kNotEditable);
}
void TGraph::SetMaximum(Double_t maximum)
{
fMaximum = maximum;
GetHistogram()->SetMaximum(maximum);
}
void TGraph::SetMinimum(Double_t minimum)
{
fMinimum = minimum;
GetHistogram()->SetMinimum(minimum);
}
void TGraph::SetPoint(Int_t i, Double_t x, Double_t y)
{
if (i < 0) return;
if (fHistogram) {
delete fHistogram;
fHistogram = 0;
}
if (i >= fMaxSize) {
Double_t **ps = ExpandAndCopy(i+1, fNpoints);
CopyAndRelease(ps, 0,0,0);
}
if (i >= fNpoints) {
FillZero(fNpoints, i + 1);
fNpoints = i+1;
}
fX[i] = x;
fY[i] = y;
if (gPad) gPad->Modified();
}
void TGraph::SetTitle(const char* title)
{
fTitle = title;
if (fHistogram) fHistogram->SetTitle(title);
}
Double_t **TGraph::ShrinkAndCopy(Int_t size, Int_t oend)
{
if (size*2 > fMaxSize || !fMaxSize) {
return 0;
}
Double_t **newarrays = Allocate(size);
CopyPoints(newarrays, 0, oend, 0);
return newarrays;
}
void TGraph::Sort(Bool_t (*greaterfunc)(const TGraph*, Int_t, Int_t) ,
Bool_t ascending , Int_t low , Int_t high )
{
if (high == -1111) high = GetN()-1;
if (high <= low) return;
int left, right;
left = low;
right = high;
while (left < right) {
while(left <= high && greaterfunc(this, left, low) != ascending)
left++;
while(right > low && greaterfunc(this, right, low) == ascending)
right--;
if (left < right && left < high && right > low)
SwapPoints(left, right);
}
if (right > low)
SwapPoints(low, right);
Sort( greaterfunc, ascending, low, right-1 );
Sort( greaterfunc, ascending, right+1, high );
}
void TGraph::Streamer(TBuffer &b)
{
if (b.IsReading()) {
UInt_t R__s, R__c;
Version_t R__v = b.ReadVersion(&R__s, &R__c);
if (R__v > 2) {
b.ReadClassBuffer(TGraph::Class(), this, R__v, R__s, R__c);
if (fHistogram) fHistogram->SetDirectory(0);
TIter next(fFunctions);
TObject *obj;
while ((obj = next())) {
if (obj->InheritsFrom(TF1::Class())) {
TF1 *f1 = (TF1*)obj;
f1->SetParent(this);
}
}
fMaxSize = fNpoints;
return;
}
TNamed::Streamer(b);
TAttLine::Streamer(b);
TAttFill::Streamer(b);
TAttMarker::Streamer(b);
b >> fNpoints;
fMaxSize = fNpoints;
fX = new Double_t[fNpoints];
fY = new Double_t[fNpoints];
if (R__v < 2) {
Float_t *x = new Float_t[fNpoints];
Float_t *y = new Float_t[fNpoints];
b.ReadFastArray(x,fNpoints);
b.ReadFastArray(y,fNpoints);
for (Int_t i=0;i<fNpoints;i++) {
fX[i] = x[i];
fY[i] = y[i];
}
delete [] y;
delete [] x;
} else {
b.ReadFastArray(fX,fNpoints);
b.ReadFastArray(fY,fNpoints);
}
b >> fFunctions;
b >> fHistogram;
if (fHistogram) fHistogram->SetDirectory(0);
if (R__v < 2) {
Float_t mi,ma;
b >> mi;
b >> ma;
fMinimum = mi;
fMaximum = ma;
} else {
b >> fMinimum;
b >> fMaximum;
}
b.CheckByteCount(R__s, R__c, TGraph::IsA());
} else {
b.WriteClassBuffer(TGraph::Class(),this);
}
}
void TGraph::SwapPoints(Int_t pos1, Int_t pos2)
{
SwapValues(fX, pos1, pos2);
SwapValues(fY, pos1, pos2);
}
void TGraph::SwapValues(Double_t* arr, Int_t pos1, Int_t pos2)
{
Double_t tmp=arr[pos1];
arr[pos1]=arr[pos2];
arr[pos2]=tmp;
}
void TGraph::UseCurrentStyle()
{
if (gStyle->IsReading()) {
SetFillColor(gStyle->GetHistFillColor());
SetFillStyle(gStyle->GetHistFillStyle());
SetLineColor(gStyle->GetHistLineColor());
SetLineStyle(gStyle->GetHistLineStyle());
SetLineWidth(gStyle->GetHistLineWidth());
SetMarkerColor(gStyle->GetMarkerColor());
SetMarkerStyle(gStyle->GetMarkerStyle());
SetMarkerSize(gStyle->GetMarkerSize());
} else {
gStyle->SetHistFillColor(GetFillColor());
gStyle->SetHistFillStyle(GetFillStyle());
gStyle->SetHistLineColor(GetLineColor());
gStyle->SetHistLineStyle(GetLineStyle());
gStyle->SetHistLineWidth(GetLineWidth());
gStyle->SetMarkerColor(GetMarkerColor());
gStyle->SetMarkerStyle(GetMarkerStyle());
gStyle->SetMarkerSize(GetMarkerSize());
}
if (fHistogram) fHistogram->UseCurrentStyle();
TIter next(GetListOfFunctions());
TObject *obj;
while ((obj = next())) {
obj->UseCurrentStyle();
}
}
Int_t TGraph::Merge(TCollection* li)
{
TIter next(li);
while (TObject* o = next()) {
TGraph *g = dynamic_cast<TGraph*> (o);
if (!g) {
Error("Merge",
"Cannot merge - an object which doesn't inherit from TGraph found in the list");
return -1;
}
Double_t x, y;
for (Int_t i = 0 ; i < g->GetN(); i++) {
g->GetPoint(i, x, y);
SetPoint(GetN(), x, y);
}
}
return GetN();
}
void TGraph::Zero(Int_t &k,Double_t AZ,Double_t BZ,Double_t E2,Double_t &X,Double_t &Y
,Int_t maxiterations)
{
static Double_t a, b, ya, ytest, y1, x1, h;
static Int_t j1, it, j3, j2;
Double_t yb, x2;
yb = 0;
if (k <= 0) {
a = AZ;
b = BZ;
X = a;
j1 = 1;
it = 1;
k = j1;
return;
}
if (TMath::Abs(Y) <= E2) { k = 2; return; }
if (j1 == 1) {
ya = Y;
X = b;
j1 = 2;
return;
}
if (j1 != 2) goto L100;
if (ya*Y < 0) goto L120;
x1 = a;
y1 = ya;
j1 = 3;
h = b - a;
j2 = 1;
x2 = a + 0.5*h;
j3 = 1;
it++;
if (it >= maxiterations) k = j1;
else X = x2;
return;
L100:
if (j1 > 3) goto L170;
if (ya*Y >= 0) {
if (j3 >= j2) {
h = 0.5*h; j2 = 2*j2;
a = x1; ya = y1; x2 = a + 0.5*h; j3 = 1;
}
else {
a = X; ya = Y; x2 = X + h; j3++;
}
it++;
if (it >= maxiterations) k = j1;
else X = x2;
return;
}
L120:
b = X;
yb = Y;
j1 = 4;
L130:
if (TMath::Abs(ya) > TMath::Abs(yb)) { x1 = a; y1 = ya; X = b; Y = yb; }
else { x1 = b; y1 = yb; X = a; Y = ya; }
L150:
x2 = X-Y*(X-x1)/(Y-y1);
x1 = X;
y1 = Y;
ytest = 0.5*TMath::Min(TMath::Abs(ya),TMath::Abs(yb));
if ((x2-a)*(x2-b) < 0) {
it++;
if (it >= maxiterations) k = j1;
else X = x2;
return;
}
L160:
x2 = 0.5*(a+b);
ytest = 0;
if ((x2-a)*(x2-b) >= 0) { k = 2; return; }
it++;
if (it >= maxiterations) k = j1;
else X = x2;
return;
L170:
if (j1 != 4) return;
if (ya*Y < 0) { b = X; yb = Y; }
else { a = X; ya = Y; }
if (ytest <= 0) goto L130;
if (TMath::Abs(Y)-ytest <= 0) goto L150;
goto L160;
}
Last change: Fri Dec 5 09:53:07 2008
Last generated: 2008-12-05 09:53
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.