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