source: trunk/MagicSoft/Mars/manalysis/MMinuitInterface.cc@ 2304

Last change on this file since 2304 was 2300, checked in by wittek, 21 years ago
*** empty log message ***
File size: 10.9 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): Wolfgang Wittek 7/2003 <mailto:wittek@mppmu.mpg.de>
19!
20! Copyright: MAGIC Software Development, 2000-2003
21!
22!
23\* ======================================================================== */
24
25/////////////////////////////////////////////////////////////////////////////
26// //
27// MMinuitInterface //
28// //
29// Class for interfacing with Minuit //
30// //
31// //
32// //
33/////////////////////////////////////////////////////////////////////////////
34#include "MMinuitInterface.h"
35
36#include <math.h> // fabs
37
38#include <TMinuit.h>
39#include <TStopwatch.h>
40
41#include "MLog.h"
42#include "MLogManip.h"
43#include "MParContainer.h"
44
45
46ClassImp(MMinuitInterface);
47
48using namespace std;
49
50
51// --------------------------------------------------------------------------
52//
53// Default constructor.
54//
55MMinuitInterface::MMinuitInterface(const char *name, const char *title)
56{
57 fName = name ? name : "MMinuitInterface";
58 fTitle = title ? title : "Interface for Minuit";
59
60}
61
62// --------------------------------------------------------------------------
63//
64// Default destructor.
65//
66MMinuitInterface::~MMinuitInterface()
67{
68}
69
70
71// -----------------------------------------------------------------------
72//
73// Interface to MINUIT
74//
75//
76Bool_t MMinuitInterface::CallMinuit(
77 void (*fcn)(Int_t &, Double_t *, Double_t &, Double_t *, Int_t),
78 UInt_t npar, char name[80][100],
79 Double_t vinit[80], Double_t step[80],
80 Double_t limlo[80], Double_t limup[80], Int_t fix[80],
81 TObject *objectfit , TString method, Bool_t nulloutput)
82{
83 TString str(method);
84
85 //
86 // Be carefull: This is not thread safe
87 //
88 UInt_t maxpar = 100;
89
90 if (npar > maxpar)
91 {
92 *fLog << "CallMinuit : too many parameters, npar = " << npar
93 << ", maxpar = " << maxpar << endl;
94 return kFALSE;
95 }
96
97
98
99 //..............................................
100 // Set the maximum number of parameters
101 TMinuit &minuit = *(new TMinuit(maxpar));
102 minuit.SetName("MinuitSupercuts");
103 //TMinuit minuit(maxpar);
104 //gMinuit = new TMinuit(maxpar);
105 //TMinuit &minuit = *gMinuit;
106
107
108 //..............................................
109 // Set the print level
110 // -1 no output except SHOW comands
111 // 0 minimum output
112 // 1 normal output (default)
113 // 2 additional ouput giving intermediate results
114 // 3 maximum output, showing progress of minimizations
115 //
116 //Int_t printLevel = -1;
117 Int_t printLevel = 1;
118 minuit.SetPrintLevel(printLevel);
119
120 //..............................................
121 // Printout for warnings
122 // SET WAR print warnings
123 // SET NOW suppress warnings
124 Int_t errWarn;
125 Double_t tmpwar = 0;
126 minuit.mnexcm("SET NOW", &tmpwar, 0, errWarn);
127 //minuit.mnexcm("SET WAR", &tmpwar, 0, errWarn);
128
129 //..............................................
130 // Set the address of the minimization function
131 minuit.SetFCN(fcn);
132
133
134 //..............................................
135 // Store address of object to be used in fcn
136 minuit.SetObjectFit(objectfit );
137
138
139 //..............................................
140 // Set starting values and step sizes for parameters
141 for (UInt_t i=0; i<npar; i++)
142 {
143 if (minuit.DefineParameter(i, &name[i][0], vinit[i], step[i],
144 limlo[i], limup[i]))
145 {
146 *fLog << "CallMinuit: Error in defining parameter "
147 << name[i][0] << endl;
148 return kFALSE;
149 }
150 }
151
152 //..............................................
153 //Int_t NumPars;
154 //NumPars = minuit.GetNumPars();
155 //*fLog << "CallMinuit : number of free parameters = "
156 // << NumPars << endl;
157
158
159 //..............................................
160 // Error definition :
161 //
162 // for chisquare function :
163 // up = 1.0 means calculate 1-standard deviation error
164 // = 4.0 means calculate 2-standard deviation error
165 //
166 // for log(likelihood) function :
167 // up = 0.5 means calculate 1-standard deviation error
168 // = 2.0 means calculate 2-standard deviation error
169 Double_t up = 1.0;
170 minuit.SetErrorDef(up);
171
172
173
174 // Int_t errMigrad;
175 // Double_t tmp = 0;
176 // minuit.mnexcm("MIGRAD", &tmp, 0, errMigrad);
177
178
179 //..............................................
180 // fix a parameter
181 for (UInt_t i=0; i<npar; i++)
182 {
183 if (fix[i] > 0)
184 {
185 Int_t parNo = i;
186 minuit.FixParameter(parNo);
187 step[parNo] = 0.0;
188 }
189 }
190
191 //..............................................
192 //NumPars = minuit.GetNumPars();
193 //*fLog << "CallMinuit : number of free parameters = "
194 // << NumPars << endl;
195
196 //..............................................
197 // Set maximum number of iterations (default = 500)
198 //Int_t maxiter = 100000;
199 Int_t maxiter = 10;
200 minuit.SetMaxIterations(maxiter);
201
202 //..............................................
203 // minimization by the method of Migrad
204 if (str.Contains("Migrad", TString::kIgnoreCase))
205 {
206 //*fLog << "call MIGRAD" << endl;
207 if (nulloutput)
208 fLog->SetNullOutput(kTRUE);
209 Double_t tmp = 0;
210 minuit.mnexcm("MIGRAD", &tmp, 0, fErrMinimize);
211 if (nulloutput)
212 fLog->SetNullOutput(kFALSE);
213 //*fLog << "return from MIGRAD" << endl;
214 }
215
216 //..............................................
217 // same minimization as by Migrad
218 // but switches to the SIMPLEX method if MIGRAD fails to converge
219 if (str.Contains("Minimize", TString::kIgnoreCase))
220 {
221 *fLog << "call MINIMIZE" << endl;
222 Double_t tmp = 0;
223 minuit.mnexcm("MINIMIZE", &tmp, 0, fErrMinimize);
224 *fLog << "return from MINIMIZE" << endl;
225 }
226
227 //..............................................
228 // minimization by the SIMPLEX method
229 if (str.Contains("Simplex", TString::kIgnoreCase))
230 {
231 *fLog << "call SIMPLEX" << endl;
232 if (nulloutput)
233 fLog->SetNullOutput(kTRUE);
234 Double_t tmp = 0;
235 minuit.mnexcm("SIMPLEX", &tmp, 0, fErrMinimize);
236 if (nulloutput)
237 fLog->SetNullOutput(kFALSE);
238 //*fLog << "return from SIMPLEX" << endl;
239 }
240
241 //..............................................
242 // check quality of minimization
243 // istat = 0 covariance matrix not calculated
244 // 1 diagonal approximation only (not accurate)
245 // 2 full matrix, but forced positive-definite
246 // 3 full accurate covariance matrix
247 // (indication of normal convergence)
248 minuit.mnstat(fMin, fEdm, fErrdef, fNpari, fNparx, fIstat);
249
250 //if (fErrMinimize != 0 || fIstat < 3)
251 if (fErrMinimize != 0)
252 {
253 *fLog << "CallMinuit : Minimization failed" << endl;
254 *fLog << " fMin = " << fMin << ", fEdm = " << fEdm
255 << ", fErrdef = " << fErrdef << ", fIstat = " << fIstat
256 << ", fErrMinimize = " << fErrMinimize << endl;
257 return kFALSE;
258 }
259
260 //*fLog << "CallMinuit : Minimization was successful" << endl;
261 //*fLog << " fMin = " << fMin << ", fEdm = " << fEdm
262 // << ", fErrdef = " << fErrdef << ", fIstat = " << fIstat
263 // << ", fErrMinimize = " << fErrMinimize << endl;
264
265
266 //..............................................
267 // minimization by the method of Migrad
268 if (str.Contains("Hesse", TString::kIgnoreCase))
269 {
270 //*fLog << "call HESSE" << endl;
271 Double_t tmp = 0;
272 minuit.mnexcm("HESSE", &tmp, 0, fErrMinimize);
273 //*fLog << "return from HESSE" << endl;
274 }
275
276 //..............................................
277 // Minos error analysis
278 if (str.Contains("Minos", TString::kIgnoreCase))
279 {
280 //*fLog << "call MINOS" << endl;
281 Double_t tmp = 0;
282 minuit.mnexcm("MINOS", &tmp, 0, fErrMinimize);
283 //*fLog << "return from MINOS" << endl;
284 }
285
286 //..............................................
287 // Print current status of minimization
288 // if nkode = 0 only function value
289 // 1 parameter values, errors, limits
290 // 2 values, errors, step sizes, internal values
291 // 3 values, errors, step sizes, 1st derivatives
292 // 4 values, paraboloc errors, MINOS errors
293
294 //Int_t nkode = 4;
295 //minuit.mnprin(nkode, fmin);
296
297 //..............................................
298 // call fcn with IFLAG = 3 (final calculation : calculate p(chi2))
299 // iflag = 1 initial calculations only
300 // 2 calculate 1st derivatives and function
301 // 3 calculate function only
302 // 4 calculate function + final calculations
303 const char *command = "CALL";
304 Double_t iflag = 3;
305 Int_t errfcn3;
306 minuit.mnexcm(command, &iflag, 1, errfcn3);
307
308 //*fLog << "Exit CallMinuit" << endl;
309
310 return kTRUE;
311}
312
313
314//===========================================================================
315
316
317
318
319
320
321
322
323
324
325
Note: See TracBrowser for help on using the repository browser.