source: trunk/MagicSoft/Mars/mfit/MTFitLoop.cc@ 4238

Last change on this file since 4238 was 3582, checked in by tbretz, 21 years ago
*** empty log message ***
File size: 6.5 KB
Line 
1/* ======================================================================== *\
2!
3! *
4! * This file is part of MARS, the MAGIC Analysis and Reconstruction
5! * Software. It is distributed to you in the hope that it can be a useful
6! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
7! * It is distributed WITHOUT ANY WARRANTY.
8! *
9! * Permission to use, copy, modify and distribute this software and its
10! * documentation for any purpose is hereby granted without fee,
11! * provided that the above copyright notice appear in all copies and
12! * that both that copyright notice and this permission notice appear
13! * in supporting documentation. It is provided "as is" without express
14! * or implied warranty.
15! *
16!
17!
18! Author(s): Thomas Bretz, 3/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2004
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26//
27// MTFitLoop
28//
29// This class optimized parameters which are calculated in an eventloop.
30// For this it is unimportant whether the loop reads from a file a
31// matrix or from somewhere else...
32//
33// The parameters which are optimized must be stored in a MParContainer
34// which overwrites SetVariables(). Eg. a MDataChain or MF overwrites
35// SetVariables(). In a MF all arguments given as [0], [1] are
36// set by SetVariables (in MDataValue).
37// eg: In you loop you have a cut like this:
38// MF filter("MHillas.fWidth<[0]");
39// filter.SetName("MyParameters");
40//
41// Now for each time the eventloop is executed
42// (MEvtLoop::Eventloop(fNumEvents)) the parameters from TMinuit are
43// passed to MF::SetVariables and changed.
44//
45//
46/////////////////////////////////////////////////////////////////////////////
47#include "MTFitLoop.h"
48
49#include <TMinuit.h>
50#include <TStopwatch.h>
51
52#include "MParList.h"
53#include "MRead.h"
54#include "MEvtLoop.h"
55
56#include "MLog.h"
57#include "MLogManip.h"
58
59//------------------------------------------------------------------------
60//
61// fcn calculates the function to be minimized (using TMinuit::Migrad)
62//
63void MTFitLoop::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
64{
65 MTFitLoop *optim = (MTFitLoop*)gMinuit->GetObjectFit();
66
67 TMinuit *minuit = gMinuit;
68 f = optim->Fcn(npar, gin, par, iflag);
69 gMinuit = minuit;
70
71}
72Double_t MTFitLoop::Fcn(Int_t &npar, Double_t *gin, Double_t *par, Int_t iflag)
73{
74 MParList *plist = fEvtLoop->GetParList();
75
76 MParameterD *eval = (MParameterD*)plist->FindCreateObj("MParameterD", fFitParameter);
77 MParContainer *pars = plist->FindObject(fParametersName);
78
79 MRead *read = (MRead*)plist->FindObject("MTaskList")->FindObject("MRead");
80 if (read)
81 read->Rewind();
82
83 if (fDebug>=1)
84 {
85 Double_t fmin, fedm, errdef;
86 Int_t n1, n2, istat;
87 gMinuit->mnstat(fmin, fedm, errdef, n1, n2, istat);
88 *fLog << inf << underline << "Minimization Status so far:" << endl;
89 *fLog << " Calls: " << gMinuit->fNfcn << endl;
90 *fLog << " Func min: " << fmin << endl;
91 *fLog << " Found edm: " << fedm << endl;
92 *fLog << " ErrDef: " << errdef << endl;
93 *fLog << " Status: ";
94 switch (istat)
95 {
96 case 0: *fLog << "n/a" << endl; break;
97 case 1: *fLog << "approximation only, not accurate" << endl; break;
98 case 2: *fLog << "full matrix, but forced positive-definite" << endl; break;
99 case 3: *fLog << "full accurate covariance matrix" << endl; break;
100 default: *fLog << "undefined" << endl; break;
101 }
102 }
103
104 if (fDebug>=0)
105 {
106 *fLog << inf << "Set: ";
107 for (Int_t i=0; i<7; i++)
108 *fLog << par[i] << " ";
109 *fLog << endl;
110 }
111
112 pars->SetVariables(TArrayD(gMinuit->fMaxpar, par));
113
114 if (fDebug<3)
115 gLog.SetNullOutput(kTRUE);
116 fEvtLoop->Eventloop(fNumEvents);
117 if (fDebug<3)
118 gLog.SetNullOutput(kFALSE);
119
120 const Double_t f = eval->GetVal();
121
122 if (fDebug>=0)
123 *fLog << inf << "F=" << f << endl;
124
125 if (fDebug>=1)
126 fEvtLoop->GetTaskList()->PrintStatistics();
127
128 return f;
129}
130
131MTFitLoop::MTFitLoop()
132{
133 fDebug = -1;
134 fNumEvents = -1;
135}
136
137void MTFitLoop::Optimize(MEvtLoop &loop)
138{
139 *fLog << inf << "Event loop was setup" << endl;
140 MParList *parlist = loop->GetParList();
141 if (!parlist)
142 return;
143
144 MParContainer *pars = plist->FindObject(fParametersName);
145 if (!pars)
146 return;
147
148 fEvtLoop = evtloop;
149
150 MParContainer &parameters = *pars;
151
152 TMinuit *minsave = gMinuit;
153
154 gMinuit = new TMinuit(parameters.GetSize());
155 gMinuit->SetPrintLevel(-1);
156
157 gMinuit->SetFCN(fcn);
158 gMinuit->SetObjectFit(this);
159
160 // For chisq fits call this // seems to be something like %)
161 //
162 // The default tolerance is 0.1, and the minimization will stop");
163 // when the estimated vertical distance to the minimum (EDM) is");
164 // less than 0.001*[tolerance]*UP (see [SET ERRordef]).");
165 //
166 if (gMinuit->SetErrorDef(1000))
167 {
168 *fLog << err << dbginf << "SetErrorDef failed." << endl;
169 return;
170 }
171
172 //
173 // Set starting values and step sizes for parameters
174 //
175 for (Int_t i=0; i<parameters.GetSize(); i++)
176 {
177 TString name = "par[";
178 name += i;
179 name += "]";
180 Double_t vinit = parameters[i];
181 Double_t step = fabs(parameters[i]/3);
182
183 Double_t limlo = 0; // limlo=limup=0: no limits
184 Double_t limup = 2*vinit;
185
186 Bool_t rc = gMinuit->DefineParameter(i, name, vinit, step, 0, limup);
187 if (!rc)
188 continue;
189
190 *fLog << err << dbginf << "Error in defining parameter #" << i << endl;
191 return;
192 }
193
194 for (int i=0; i<parameters.GetSize(); i++)
195 if (i<fFixParams.GetSize() && fFixParams[i]!=0)
196 gMinuit->FixParameter(i);
197 else
198 gMinuit->Release(i);
199
200 // Now ready for minimization step:
201
202 TStopwatch clock;
203 clock.Start();
204 const Bool_t rc = gMinuit->Migrad();
205 clock.Stop();
206 clock.Print();
207
208 if (rc)
209 {
210 *fLog << err << dbginf << "Migrad failed." << endl;
211 return;
212 }
213
214 *fLog << inf << "Resulting Chisq: " << gMinuit->fAmin << endl;
215
216 //
217 // Update values of fA, fB:
218 //
219 for (Int_t i=0; i<parameters.GetSize(); i++)
220 {
221 Double_t x1, x2;
222 gMinuit->GetParameter(i,x1,x2);
223 parameters[i] = x1;
224 cout << i << ": " << parameters[i] << endl;
225 }
226
227 list.SetVariables(parameters);
228
229 gMinuit = minsave;
230}
Note: See TracBrowser for help on using the repository browser.