40 Double_t ellipse_fcn(Double_t x, Double_t y,
41 Double_t x0, Double_t y0,
42 Double_t a, Double_t b,
46 if ((a == 0.0) || (b == 0.0))
return v;
51 theta *= TMath::Pi() / 180.0;
53 x = x * std::cos(theta) + y * std::sin(theta);
54 y = y * std::cos(theta) - v * std::sin(theta);
73 Double_t ellipse_fcn(
const Double_t *x,
const Double_t *params)
75 return ellipse_fcn(x[0], x[1],
84 TGraph *ellipse_TGraph = ((TGraph *)0);
92 Double_t ellipse_TGraph_chi2(
const Double_t *x)
95 if (!ellipse_TGraph)
return v;
96 for (Int_t i = 0; i < ellipse_TGraph->GetN(); i++) {
97 Double_t r = ellipse_fcn((ellipse_TGraph->GetX())[i],
98 (ellipse_TGraph->GetY())[i],
112 ROOT::Math::Minimizer *ellipse_TGraph_minimize(TGraph *g)
115 if (g->GetN() < 6)
return 0;
122 ROOT::Math::Minimizer* m =
123 ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Migrad");
125 ROOT::Math::Minimizer* m =
126 ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Simplex");
128 ROOT::Math::Minimizer* m =
129 ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Combined");
131 ROOT::Math::Minimizer* m =
132 ROOT::Math::Factory::CreateMinimizer(
"Minuit2",
"Scan");
136 m->SetMaxFunctionCalls(1000000);
137 m->SetMaxIterations(100000);
138 m->SetTolerance(0.001);
144 ROOT::Math::Functor f(&ellipse_TGraph_chi2, 5);
152 Double_t xmin, xmax, ymin, ymax;
153 Double_t x0, y0, a, b, theta;
154 ellipse_TGraph->ComputeRange(xmin, ymin, xmax, ymax);
155 x0 = (xmax + xmin) / 2.0;
156 y0 = (ymax + ymin) / 2.0;
157 a = (ellipse_TGraph->GetX())[0] - x0;
158 b = (ellipse_TGraph->GetY())[0] - y0;
159 theta = ((std::abs(b) > 9999.9 * std::abs(a)) ? 9999.9 : (b / a));
162 for (Int_t i = 1; i < ellipse_TGraph->GetN(); i++) {
163 Double_t dx = (ellipse_TGraph->GetX())[i] - x0;
164 Double_t dy = (ellipse_TGraph->GetY())[i] - y0;
165 Double_t d = dx * dx + dy * dy;
169 theta = ((std::abs(dy) > 9999.9 * std::abs(dx)) ? 9999.9 : (dy / dx));
173 a = std::sqrt(a);
if (!(a > 0)) a = 0.001;
174 b = std::sqrt(b);
if (!(b > 0)) b = 0.001;
175 theta = std::atan(theta) * 180.0 / TMath::Pi();
176 if (theta < -45.0) theta += 180.0;
179 m->SetVariable(0,
"x0", x0, (xmax - xmin) / 100.0);
180 m->SetVariable(1,
"y0", y0, (ymax - ymin) / 100.0);
181 m->SetVariable(2,
"a", a, a / 100.0);
182 m->SetVariable(3,
"b", b, b / 100.0);
183 m->SetVariable(4,
"theta", theta, 1);
187 m->SetVariableLimits(0, xmin, xmax);
188 m->SetVariableLimits(1, ymin, ymax);
190 if (a < ((xmax - xmin) / 2.0)) a = (xmax - xmin) / 2.0;
191 if (b < ((ymax - ymin) / 2.0)) b = (ymax - ymin) / 2.0;
193 if (a < ((ymax - ymin) / 2.0)) a = (ymax - ymin) / 2.0;
194 if (b < ((xmax - xmin) / 2.0)) b = (xmax - xmin) / 2.0;
196 m->SetVariableLimits(2, 0, a * 3.0);
197 m->SetVariableLimits(3, 0, b * 3.0);
199 m->SetVariableLimits(4, theta - 45.0, theta + 45.0);
206 const Double_t *xm = m->X();
207 std::cout <<
"Minimum ( "
208 << xm[0] <<
" , " << xm[1] <<
" , "
209 << xm[2] <<
" , " << xm[3] <<
" , "
221 TGraph *TestGraphRMM(Bool_t randomize = kFALSE) {
229 Double_t theta = 100;
233 x0 = 10.0 - 20.0 * gRandom->Rndm();
234 y0 = 10.0 - 20.0 * gRandom->Rndm();
235 a = 0.5 + 4.5 * gRandom->Rndm();
236 b = 0.5 + 4.5 * gRandom->Rndm();
237 theta = 180.0 - 360.0 * gRandom->Rndm();
242 Double_t dt = TMath::TwoPi() / Double_t(n);
244 theta *= TMath::PiOver2() / 90.0;
245 for (i = 0; i < n; i++) {
246 x[i] = a * (std::cos(dt * Double_t(i)) + 0.1 * gRandom->Rndm() - 0.05);
247 y[i] = b * (std::sin(dt * Double_t(i)) + 0.1 * gRandom->Rndm() - 0.05);
250 x[i] = x[i] * std::cos(theta) - y[i] * std::sin(theta);
251 y[i] = y[i] * std::cos(theta) + tmp * std::sin(theta);
258 TGraph *g = ((TGraph *)(gROOT->FindObject(
"g")));
260 g =
new TGraph(n, x, y);
261 g->SetNameTitle(
"g",
"test ellipse");
269 void fitEllipseTGraphRMM(TGraph *g = ((TGraph *)0))
271 if (!g) g = TestGraphRMM(kTRUE);
275 TF2 *ellipse = ((TF2 *)(gROOT->GetListOfFunctions()->FindObject(
"ellipse")));
276 if (ellipse)
delete ellipse;
277 ellipse =
new TF2(
"ellipse", ellipse_fcn, -1, 1, -1, 1, 5);
278 ellipse->SetMaximum(2.0);
279 ellipse->SetParNames(
"x0",
"y0",
"a",
"b",
"theta");
280 ellipse->SetParameters(0.4, 0.3, 0.2, 0.1, 10);
284 ROOT::Math::Minimizer *m = ellipse_TGraph_minimize(g);
288 TCanvas *c = ((TCanvas *)(gROOT->GetListOfCanvases()->FindObject(
"c")));
289 if (c) { c->Clear(); }
else { c =
new TCanvas(
"c",
"c"); }
292 if ( m && (!(m->Status())) ) {
293 const Double_t *xm = m->X();
294 TEllipse *e =
new TEllipse(xm[0], xm[1],
301 c->Modified(); c->Update();