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

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