CbmRoot
Loading...
Searching...
No Matches
LKFMinuit.cxx
Go to the documentation of this file.
1/* Copyright (C) 2015-2020 PI-UHd, GSI
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Norbert Herrmann [committer] */
4
5#include "LKFMinuit.h"
6
7#include <Logger.h>
8
9#include <TFitter.h>
10#include <TGraph2D.h>
11#include <TMath.h>
12#include <TPolyLine3D.h>
13
14#include <Math/Vector3D.h>
15
16using namespace ROOT::Math;
17
20TFitter* LKFMinuit::fMyFit = 0;
21TGraph2DErrors* LKFMinuit::fgr = 0;
22
24{
25 LOG(info) << "LKFMinuit::Initialize ";
26 fMyFit = new TFitter(2);
28
29 Double_t arglist[10];
30 arglist[0] = -2;
31 fMyFit->ExecuteCommand("SET PRINT", arglist, 1);
32 fMyFit->ExecuteCommand("SIMPLEX", 0, 0);
33 return 0;
34}
35
36int LKFMinuit::DoFit(TGraph2DErrors* gr, double pStart[])
37{
38 fgr = gr;
39 //TFitter* min = new TFitter(2);
40 TFitter* min = fMyFit;
41 if (NULL == min) LOG(fatal) << "DoFit: no TFitter specified!";
42
43 min->SetObjectFit(gr);
44
45 //double pStart[4] = {0.,0.,0.,0.};
46 min->SetParameter(0, "x0", pStart[0], 0.1, -10000., 10000.);
47 min->SetParameter(1, "Ax", pStart[1], 0.01, -10., 10.);
48 min->SetParameter(2, "y0", pStart[2], 0.1, -10000.0, 10000.);
49 min->SetParameter(3, "Ay", pStart[3], 0.01, -10., 10.);
50
51 Double_t arglist[10];
52 arglist[0] = 10000; // number of function calls
53 arglist[1] = 0.001; // tolerance
54 min->ExecuteCommand("MIGRAD", arglist, 2);
55 arglist[0] = 0;
56 arglist[1] = 0;
57 arglist[2] = 0;
58 min->ExecuteCommand("SET NOWarnings", arglist, 3); //turn off warning messages
59 //if (minos) min->ExecuteCommand("MINOS",arglist,0);
60 int nvpar, nparx;
61 double amin, edm, errdef;
62 min->GetStats(amin, edm, errdef, nvpar, nparx);
63 fChi2 = amin;
64 fChi2DoF = amin / (double) nvpar;
65 //min->PrintResults(1,amin);
66 // get fit parameters
67 //double parFit[4];
68 for (int i = 0; i < 4; ++i)
69 fparFit[i] = min->GetParameter(i);
70
71 return 0;
72}
73
74double LKFMinuit::myFunction(double /*par*/)
75{
76 double result = 0;
77
78 return result;
79}
80
81// Temporary add on
82//Fitting of a TGraph2D with a 3D straight line
83//
84// run this macro by doing:
85//
86// root>.x line3Dfit.C+
87//
88//Author: L. Moneta
89//
90
91// define the parameteric line equation
92void LKFMinuit::line(double t, double* p, double& x, double& y, double& z)
93{
94 // a parameteric line is define from 6 parameters but 4 are independent
95 // x0,y0,z0,z1,y1,z1 which are the coordinates of two points on the line
96 // can choose z0 = 0 if line not parallel to x-y plane and z1 = 1;
97 x = p[0] + p[1] * t;
98 y = p[2] + p[3] * t;
99 z = t;
100}
101
102// calculate distance line-point
103double LKFMinuit::distance2(double x, double y, double z, double* p)
104{
105 // distance line point is D= | (xp-x0) cross ux |
106 // where ux is direction of line and x0 is a point in the line (like t = 0)
107 XYZVector xp(x, y, z);
108 XYZVector x0(p[0], p[2], 0.);
109 XYZVector x1(p[0] + p[1], p[2] + p[3], 1.);
110 XYZVector u = (x1 - x0).Unit();
111 double d2 = ((xp - x0).Cross(u)).Mag2();
112 return d2;
113}
114
115// calculate distance line-point with errors
116double LKFMinuit::distance2err(double x, double y, double z, double ex, double ey, double ez, double* p)
117{
118 // distance line point is D= | (xp-x0) cross ux |
119 // where ux is direction of line and x0 is a point in the line (like t = 0)
120 XYZVector xp(x, y, z);
121 XYZVector x0(p[0], p[2], 0.);
122 XYZVector x1(p[0] + p[1], p[2] + p[3], 1.);
123 XYZVector u = (x1 - x0).Unit();
124 XYZVector xr = xp - x0;
125 XYZVector D = xr.Cross(u);
126 // double d2 = D.Mag2();
127 double d2e = TMath::Power(D.X(), 2) / ex / ex;
128 d2e += TMath::Power(D.Y(), 2) / ey / ey;
129 d2e += TMath::Power(D.Z(), 2) / ez / ez;
130 return d2e;
131 /*
132 // previous inconsistent version ...
133 //XYZVector v = (xp-x0).Unit();
134 //XYZVector xpe(ex,ey,ez);
135 XYZVector xpe(ex,ey,0.);
136 // v *= xpe.Dot(v);
137 //double d2e = 1./(xpe.Cross(u)).Mag2();
138 XYZVector xre(xr.X(),xr.Y(),0.);
139 double er = TMath::Abs( (xre.Unit()).Dot(xpe) ); // error in xr direction
140 er = TMath::Max(er, 1.E-1); // prevent dividing by zero, avoid too strong weights
141 double d2e = 1./ er / er;
142 //double d2e = 1.;
143 //XYZVector v = xr.Unit();
144 //std::cout << "distance2err: d2 "<<d2<<", d2e "<<d2e<<"\t "<<v.X()<<"\t"<<v.Y()<<"\t"<<v.Z()<<"\t "<<u.X()<<"\t"<<u.Y()<<"\t"<<u.Z()<<std::endl;
145 return d2*d2e;
146 */
147}
148
149bool first = true;
150double LKFMinuit::SumDistance2(double par[])
151{
152 // the TGraph must be a global variable
153 if (NULL == fgr) LOG(fatal) << "Invalid TGraph2Errors";
154 TGraph2DErrors* gr = fgr; //dynamic_cast<TGraph2D*>( (TVirtualFitter::GetFitter())->GetObjectFit() );
155 assert(gr != 0);
156 double* x = gr->GetX();
157 double* y = gr->GetY();
158 double* z = gr->GetZ();
159 double* ex = gr->GetEX();
160 double* ey = gr->GetEY();
161 double* ez = gr->GetEZ();
162 int npoints = gr->GetN();
163 double sum = 0;
164 for (int i = 0; i < npoints; ++i) {
165 //double d = distance2(x[i],y[i],z[i],par);
166 double d = distance2err(x[i], y[i], z[i], ex[i], ey[i], ez[i], par);
167 sum += d;
168 //#ifdef DEBUG
169 if (0)
170 if (first)
171 std::cout << " -D- LKFMinuit::SumDistance2: point " << i << "\t" << x[i] << "\t" << ex[i] << "\t" << y[i]
172 << "\t" << ey[i] << "\t" << z[i] << "\t" << ez[i] << "\t" << std::sqrt(d) << std::endl;
173 //#endif
174 }
175 if (0)
176 if (first) std::cout << " -D- LKFMinuit::SumDistance2: Total sum2 = " << sum << std::endl;
177 first = false;
178 return sum;
179}
180
181
182void LKFMinuit::minuitFunction(int& /*nDim*/, double* /*gout*/, double& result, double par[], int /*flg*/)
183{
184 // result = LKF_obj->myFunction(par[0]);
185 result = LKF_obj->SumDistance2(par);
186}
187
189 : // fgr(NULL),
190 // fMyFit(NULL),
191 fChi2(0.)
192 , fChi2DoF(0.)
193{
194 //std::cout << "LKFMinuit at " << this << std::endl;
195 LKF_obj = this;
196 if (!fInstance) fInstance = this;
197}
Char_t * gr
static LKFMinuit * LKF_obj
Definition LKFMinuit.cxx:18
bool first
static TGraph2DErrors * fgr
Definition LKFMinuit.h:44
static TFitter * fMyFit
Definition LKFMinuit.h:45
double myFunction(double)
Definition LKFMinuit.cxx:74
double distance2err(double x, double y, double z, double ex, double ey, double ez, double *p)
double distance2(double x, double y, double z, double *p)
double fChi2DoF
Definition LKFMinuit.h:48
int DoFit(TGraph2DErrors *gr, double pStart[])
Definition LKFMinuit.cxx:36
int Initialize()
Definition LKFMinuit.cxx:23
void line(double t, double *p, double &x, double &y, double &z)
Definition LKFMinuit.cxx:92
static void minuitFunction(int &nDim, double *gout, double &result, double par[], int flg)
double SumDistance2(double par[])
double fChi2
Definition LKFMinuit.h:47
static LKFMinuit * fInstance
Definition LKFMinuit.h:42
double fparFit[4]
Definition LKFMinuit.h:46