source: trunk/MagicSoft/Mars/mmontecarlo/MMcEnergyEst.cc@ 2687

Last change on this file since 2687 was 2357, checked in by wittek, 21 years ago
*** empty log message ***
File size: 9.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 1/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Wolfgang Wittek 1/2002 <mailto:wittek@mppmu.mpg.de>
20! Author(s): Abelardo Moralejo 4/2003 <mailto:moralejo@pd.infn.it>
21!
22! Copyright: MAGIC Software Development, 2000-2003
23!
24!
25\* ======================================================================== */
26
27/////////////////////////////////////////////////////////////////////////////
28// //
29// MMcEnergyEst //
30// //
31// Class for otimizing the parameters of the energy estimator //
32// //
33// FIXME: the class must be made more flexible, allowing for different //
34// parametrizations to be used. Also a new class is needed, a container //
35// for the parameters of the energy estimator. //
36// FIXME: the starting values of the parameters are now fixed. //
37// //
38// //
39/////////////////////////////////////////////////////////////////////////////
40#include "MMcEnergyEst.h"
41
42#include <math.h> // fabs on Alpha
43
44#include <TMinuit.h>
45#include <TStopwatch.h>
46#include <TVirtualFitter.h>
47
48#include "MParList.h"
49#include "MTaskList.h"
50#include "MGeomCamCT1.h"
51#include "MFEventSelector.h"
52#include "MReadTree.h"
53#include "MFCT1SelFinal.h"
54#include "MHMatrix.h"
55#include "MEnergyEstParam.h"
56#include "MMatrixLoop.h"
57#include "MChisqEval.h"
58#include "MEvtLoop.h"
59#include "MDataElement.h"
60#include "MDataMember.h"
61#include "MLog.h"
62#include "MLogManip.h"
63
64ClassImp(MMcEnergyEst);
65
66using namespace std;
67
68//------------------------------------------------------------------------
69//
70// fcn calculates the function to be minimized (using TMinuit::Migrad)
71//
72static void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
73{
74 MEvtLoop *evtloop = (MEvtLoop*)gMinuit->GetObjectFit();
75
76 MTaskList *tlist = (MTaskList*)evtloop->GetParList()->FindObject("MTaskList"); // GetTaskList();
77
78 MChisqEval *eval = (MChisqEval*) tlist->FindObject("MChisqEval");
79 MEnergyEstParam *eest = (MEnergyEstParam*)tlist->FindObject("MEnergyEstParam");
80
81 eest->SetCoeff(TArrayD(eest->GetNumCoeff(), par));
82
83 evtloop->Eventloop();
84
85 f = eval->GetChisq();
86}
87
88// --------------------------------------------------------------------------
89//
90// Default constructor.
91//
92MMcEnergyEst::MMcEnergyEst(const char *name, const char *title)
93{
94 fName = name ? name : "MMcEnergyEst";
95 fTitle = title ? title : "Optimizer of the energy estimator";
96
97 SetHillasName("MHillas");
98 SetHillasSrcName("MHillasSrc");
99
100 //
101 // Set initial values of the parameters (close enough to the final
102 // ones, taken from previous runs of the procedure). Parameter
103 // fA[4] is not used in the default energy estimation model (from
104 // D. Kranich).
105 //
106 fA.Set(5);
107 fB.Set(7);
108
109 fA[0] = 21006.2;
110 fA[1] = -43.2648;
111 fA[2] = -690.403;
112 fA[3] = -0.0428544;
113 fA[4] = 1.;
114 fB[0] = -3391.05;
115 fB[1] = 136.58;
116 fB[2] = 0.253807;
117 fB[3] = 254.363;
118 fB[4] = 61.0386;
119 fB[5] = -0.0190984;
120 fB[6] = -421695;
121}
122
123Bool_t MMcEnergyEst::SetCoeff(TArrayD &coeff)
124{
125 if (coeff.GetSize() != fA.GetSize()+fB.GetSize())
126 {
127 *fLog << err << dbginf << "Wrong number of parameters!" << endl;
128 return(kFALSE);
129 }
130
131 for (Int_t i = 0; i < fA.GetSize(); i++)
132 fA[i] = coeff[i];
133 for (Int_t i = 0; i < fB.GetSize(); i++)
134 fB[i] = coeff[i+fA.GetSize()];
135
136 return(kTRUE);
137
138}
139
140//------------------------------------------------------------------------
141//
142// Optimization (via migrad minimization) of parameters of energy estimation.
143//
144void MMcEnergyEst::FindParams()
145{
146 MParList parlist;
147
148 MFEventSelector selector;
149 selector.SetNumSelectEvts(fNevents);
150 *fLog << inf << "Read events from file '" << fInFile << "'" << endl;
151
152 MReadTree read("Events");
153 read.AddFile(fInFile);
154 read.DisableAutoScheme();
155 read.SetSelector(&selector);
156
157 *fLog << inf << "Define columns of matrix" << endl;
158 MHMatrix matrix;
159 Int_t colenergy = matrix.AddColumn("MMcEvt.fEnergy");
160 Int_t colimpact = matrix.AddColumn("MMcEvt.fImpact");
161
162 if (colenergy < 0 || colimpact < 0)
163 {
164 *fLog << err << dbginf << "colenergy, colimpact = " << colenergy << ", "
165 << colimpact << endl;
166 return;
167 }
168
169 MEnergyEstParam eest(fHillasName);
170 eest.Add(fHillasSrcName);
171 eest.InitMapping(&matrix);
172
173 *fLog << inf << "--------------------------------------" << endl;
174 *fLog << inf << "Fill events into the matrix" << endl;
175 if ( !matrix.Fill(&parlist, &read, fEventFilter) )
176 return;
177 *fLog << inf << "Matrix was filled with " << matrix.GetNumRows()
178 << inf << " events" << endl;
179
180 //-----------------------------------------------------------------------
181 //
182 // Setup the eventloop which will be executed in the fcn of MINUIT
183 //
184 *fLog << inf << "--------------------------------------" << endl;
185 *fLog << inf << "Setup event loop to be used in 'fcn'" << endl;
186
187 MTaskList tasklist;
188
189 MMatrixLoop loop(&matrix);
190
191 MChisqEval eval;
192 eval.SetY1(new MDataElement(&matrix, colenergy));
193 eval.SetY2(new MDataMember("MEnergyEst.fEnergy"));
194 eval.SetOwner();
195
196 //
197 // Entries in MParList
198
199 parlist.AddToList(&tasklist);
200
201 //
202 // Entries in MTaskList
203
204 tasklist.AddToList(&loop);
205 tasklist.AddToList(&eest);
206 tasklist.AddToList(&eval);
207
208
209 *fLog << inf << "Event loop was setup" << endl;
210 MEvtLoop evtloop;
211 evtloop.SetParList(&parlist);
212
213 //
214 //---------- Start of minimization part --------------------
215 //
216 // Do the minimization with MINUIT
217 //
218 // Be careful: This is not thread safe
219 //
220 *fLog << inf << "--------------------------------------" << endl;
221 *fLog << inf << "Start minimization for the energy estimator" << endl;
222
223 gMinuit = new TMinuit(12);
224 gMinuit->SetPrintLevel(-1);
225
226 gMinuit->SetFCN(fcn);
227 gMinuit->SetObjectFit(&evtloop);
228
229 // Ready for: gMinuit->mnexcm("SET ERR", arglist, 1, ierflg)
230
231 if (gMinuit->SetErrorDef(1))
232 {
233 *fLog << err << dbginf << "SetErrorDef failed." << endl;
234 return;
235 }
236
237 //
238 // Set starting values and step sizes for parameters
239 //
240 for (Int_t i=0; i<fA.GetSize(); i++)
241 {
242 TString name = "fA[";
243 name += i;
244 name += "]";
245 Double_t vinit = fA[i];
246 Double_t step = fabs(fA[i]/3);
247
248 Double_t limlo = 0; // limlo=limup=0: no limits
249 Double_t limup = 0;
250
251 Bool_t rc = gMinuit->DefineParameter(i, name, vinit, step, limlo, limup);
252 if (!rc)
253 continue;
254
255 *fLog << err << dbginf << "Error in defining parameter #" << i << endl;
256 return;
257 }
258
259 for (Int_t i=0; i<fB.GetSize(); i++)
260 {
261 TString name = "fB[";
262 name += i;
263 name += "]";
264 Double_t vinit = fB[i];
265 Double_t step = fabs(fB[i]/3);
266
267 Double_t limlo = 0; // limlo=limup=0: no limits
268 Double_t limup = 0;
269
270 Bool_t rc = gMinuit->DefineParameter(i+fA.GetSize(), name, vinit, step, limlo, limup);
271 if (!rc)
272 continue;
273
274 *fLog << err << dbginf << "Error in defining parameter #" << i+fA.GetSize() << endl;
275 return;
276 }
277
278 TStopwatch clock;
279 clock.Start();
280
281 // Now ready for minimization step:
282
283 gLog.SetNullOutput(kTRUE);
284 Bool_t rc = gMinuit->Migrad();
285 gLog.SetNullOutput(kFALSE);
286
287 if (rc)
288 {
289 *fLog << err << dbginf << "Migrad failed." << endl;
290 return;
291 }
292
293 *fLog << inf << endl;
294 clock.Stop();
295 clock.Print();
296 *fLog << inf << endl;
297
298 *fLog << inf << "Resulting Chisq: " << gMinuit->fAmin << endl;
299
300 //
301 // Update values of fA, fB:
302 //
303 for (Int_t i = 0; i < fA.GetSize(); i++)
304 {
305 Double_t x1, x2;
306 gMinuit->GetParameter(i,x1,x2);
307 fA[i] = x1;
308 }
309 for (Int_t i = fA.GetSize(); i < fA.GetSize()+fB.GetSize(); i++)
310 {
311 Double_t x1, x2;
312 gMinuit->GetParameter(i,x1,x2);
313 fB[i-fA.GetSize()] = x1;
314 }
315
316 // eest.Print();
317 eest.StopMapping();
318 *fLog << inf << "Minimization for the energy estimator finished" << endl;
319
320}
321
322//------------------------------------------------------------------------
323//
324// Print current values of parameters
325//
326void MMcEnergyEst::Print(Option_t *o) const
327{
328 for (Int_t i = 0; i < fA.GetSize(); i++)
329 *fLog << inf << "Parameter " << i << ": " << const_cast<TArrayD&>(fA)[i] << endl;
330
331 for (Int_t i = fA.GetSize(); i < fA.GetSize()+fB.GetSize(); i++)
332 *fLog << inf << "Parameter " << i << ": " << const_cast<TArrayD&>(fB)[i-fA.GetSize()] << endl;
333
334 /*
335 // Print results
336 Double_t amin, edm, errdef;
337 Int_t nvpar, nparx, icstat;
338 gMinuit->mnstat(amin, edm, errdef, nvpar, nparx, icstat);
339 gMinuit->mnprin(3, amin);
340 */
341
342}
343
344
Note: See TracBrowser for help on using the repository browser.