source: trunk/MagicSoft/Mars/macros/CT1EnergyEst.C@ 2097

Last change on this file since 2097 was 1886, checked in by moralejo, 22 years ago
*** empty log message ***
File size: 10.8 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, 09/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Abelardo Moralejo, 03/2003 <mailto:moralejo@pd.infn.it>
20!
21! Copyright: MAGIC Software Development, 2000-2002
22!
23!
24\* ======================================================================== */
25
26//
27// fcn is the function to be minimized using TMinuit::Migrad
28//
29void fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
30{
31 MEvtLoop *evtloop = (MEvtLoop*)gMinuit->GetObjectFit();
32
33 MTaskList *tlist = (MTaskList*)evtloop->GetParList()->FindObject("MTaskList"); // GetTaskList();
34
35 MChisqEval *eval = (MChisqEval*) tlist->FindObject("MChisqEval");
36 MEnergyEstParam *eest = (MEnergyEstParam*)tlist->FindObject("MEnergyEstParam");
37
38 eest->SetCoeff(TArrayD(eest->GetNumCoeff(), par));
39
40 evtloop->Eventloop();
41
42 f = eval->GetChisq();
43}
44
45//------------------------------------------------------------------------
46
47void CT1EnergyEst(Float_t maxhadronness=0.22, Float_t maxdist = 1.)
48{
49 //
50 // Upper cut in Maxdist taken from D. Kranich's Ph D.
51 // We have to convert maxdist from degrees to mm:
52 //
53
54 MGeomCamCT1 gct1;
55 maxdist /= gct1.GetConvMm2Deg();
56
57 //
58 // Fill events into a MHMatrix
59 //
60 MParList parlist;
61 MHMatrix matrix;
62
63 //
64 // colenergy and colimpact are the indexes of the matrix columns containing
65 // the MC energy and impact parameter.
66 //
67 Int_t colenergy = matrix.AddColumn("MMcEvt.fEnergy");
68 Int_t colimpact = matrix.AddColumn("MMcEvt.fImpact");
69
70 MEnergyEstParam eest("Hillas");
71 eest.Add("HillasSrc");
72 eest.InitMapping(&matrix);
73
74 //
75 // Here we read in the events for the training. Second argument of AddFile is
76 // the number of events. With 2000 it is rather fast, but only the lowest zenith
77 // angles will enter in the minimization.
78 //
79 MReadTree read("Events");
80 read.AddFile("MC_ON2.root",2000);
81 read.DisableAutoScheme();
82
83 //
84 // Filter to keep the most gamma-like events:
85 //
86 TString hcut("MHadronness.fHadronness<");
87 hcut += maxhadronness;
88 hcut += " && HillasSrc.fDist < ";
89 hcut += maxdist;
90
91 MF filterhadrons(hcut);
92
93 //
94 // Fill the matrix used later in the minimization loop by Minuit:
95 //
96 if (!matrix.Fill(&parlist, &read, &filterhadrons))
97 return;
98
99 //
100 // Setup the tasklist used to evaluate the needed chisq
101 //
102 MTaskList tasklist;
103 parlist.AddToList(&tasklist);
104
105 MMatrixLoop loop(&matrix);
106
107 MChisqEval eval;
108
109 eval.SetY1(new MDataElement(&matrix, colenergy));
110 eval.SetY2(new MDataMember("MEnergyEst.fEnergy"));
111
112 eval.SetOwner();
113
114 tasklist.AddToList(&loop);
115 tasklist.AddToList(&eest);
116 tasklist.AddToList(&eval);
117
118 MEvtLoop evtloop;
119 evtloop.SetParList(&parlist);
120
121 //
122 // Be careful: This is not thread safe
123 //
124 TMinuit minuit(12);
125 minuit.SetPrintLevel(-1);
126 minuit.SetFCN(fcn);
127
128 // Ready for: minuit.mnexcm("SET ERR", arglist, 1, ierflg)
129
130 if (minuit.SetErrorDef(1))
131 {
132 cout << "SetErrorDef failed." << endl;
133 return;
134 }
135
136 //
137 // Set initial values of the parameters (close enough to the final ones, taken
138 // from previous runs of the procedure). Parameter fA[4] is not used in the default
139 // energy estimation model (from D. Kranich).
140 //
141 TArrayD fA(5);
142 TArrayD fB(7);
143
144 fA[0] = 21006.2;
145 fA[1] = -43.2648;
146 fA[2] = -690.403;
147 fA[3] = -0.0428544;
148 fA[4] = 1.;
149 fB[0] = -3391.05;
150 fB[1] = 136.58;
151 fB[2] = 0.253807;
152 fB[3] = 254.363;
153 fB[4] = 61.0386;
154 fB[5] = -0.0190984;
155 fB[6] = -421695;
156
157 //
158 // Set starting values and step sizes for parameters
159 //
160 for (Int_t i=0; i<fA.GetSize(); i++)
161 {
162 TString name = "fA[";
163 name += i;
164 name += "]";
165 Double_t vinit = fA[i];
166 Double_t step = fabs(fA[i]/3);
167
168 Double_t limlo = 0; // limlo=limup=0: no limits
169 Double_t limup = 0;
170
171 Bool_t rc = minuit.DefineParameter(i, name, vinit, step, limlo, limup);
172 if (!rc)
173 continue;
174
175 cout << "Error in defining parameter #" << i << endl;
176 return;
177 }
178
179 for (Int_t i=0; i<fB.GetSize(); i++)
180 {
181 TString name = "fB[";
182 name += i;
183 name += "]";
184 Double_t vinit = fB[i];
185 Double_t step = fabs(fB[i]/3);
186
187 Double_t limlo = 0; // limlo=limup=0: no limits
188 Double_t limup = 0;
189
190 Bool_t rc = minuit.DefineParameter(i+fA.GetSize(), name, vinit, step, limlo, limup);
191 if (!rc)
192 continue;
193
194 cout << "Error in defining parameter #" << i+fA.GetSize() << endl;
195 return;
196 }
197
198 //
199 // Setup globals used in FCN
200 //
201 minuit.SetObjectFit(&evtloop);
202
203 TStopwatch clock;
204 clock.Start();
205
206 // Now ready for minimization step:
207
208 gLog.SetNullOutput(kTRUE);
209 Bool_t rc = minuit.Migrad();
210 gLog.SetNullOutput(kFALSE);
211
212 if (rc)
213 {
214 cout << "Migrad failed." << endl;
215 return;
216 }
217
218 cout << endl;
219 clock.Stop();
220 clock.Print();
221 cout << endl;
222
223 cout << "Resulting Chisq: " << minuit.fAmin << endl;
224
225 for (Int_t i=0; i<fA.GetSize()+fB.GetSize(); i++)
226 {
227 Double_t val;
228 Double_t er;
229
230 if (!minuit.GetParameter(i, val, er))
231 {
232 cout << "Error getting parameter #" << i << endl;
233 return;
234 }
235
236 cout << i << ": " << val << endl;
237 // " +- " << er << endl;
238 }
239
240 /*
241 // Print results
242 Double_t amin, edm, errdef;
243 Int_t nvpar, nparx, icstat;
244 minuit.mnstat(amin, edm, errdef, nvpar, nparx, icstat);
245 minuit.mnprin(3, amin);
246 eest.Print();
247 */
248
249 eest.StopMapping();
250
251
252 //
253 // Now write the parameters of the energy estimator to file:
254 //
255 TVector* EnergyParams = new TVector(12);
256 for (Int_t i=0; i<eest.GetNumCoeff(); i++)
257 EnergyParams(i) = eest.GetCoeff(i);
258 TFile out("energyest.root", "recreate");
259 EnergyParams->Write("EnergyParams");
260 out.Close();
261
262 //
263 // End of Part 1 (estimation of the parameters)
264 //
265
266
267 ////////////////////////////////////////////////////////////////////////////
268 ////////////////////////////////////////////////////////////////////////////
269 ////////////////////////////////////////////////////////////////////////////
270 ////////////////////////////////////////////////////////////////////////////
271
272
273 //
274 // Part 2: Now test how the energy estimation method works.
275 //
276 //
277 // Create a empty Parameter List and an empty Task List
278 // The tasklist is identified in the eventloop by its name
279 //
280
281 MTaskList tlist2;
282 MParList parlist2;
283
284 parlist2.AddToList(&tlist2);
285
286 //
287 // Now setup the tasks and tasklist:
288 // ---------------------------------
289 //
290
291 MReadTree read2("Events");
292 read2.AddFile("MC_ON2.root");
293 read2.DisableAutoScheme();
294
295 //
296 // Create some histograms to display the results:
297 //
298
299 MH3 mh3ed("log10(MMcEvt.fEnergy)", "MEnergyEst.fEnergy/MMcEvt.fEnergy-1");
300 MH3 mh3ed2("log10(MEnergyEst.fEnergy)", "MEnergyEst.fEnergy/MMcEvt.fEnergy-1");
301 MH3 mhe("log10(MMcEvt.fEnergy)", "log10(MEnergyEst.fEnergy)");
302
303 MFillH hfilled(&mh3ed);
304 MFillH hfilled2(&mh3ed2);
305 MFillH hfillee(&mhe);
306
307 mhe.SetName("HistEE");
308 mh3ed.SetName("HistEnergyDelta");
309 mh3ed2.SetName("HistEnergyDelta");
310
311 MBinning binsedx("BinningHistEnergyDeltaX");
312 MBinning binsedy("BinningHistEnergyDeltaY");
313 MBinning binseex("BinningHistEEX");
314 MBinning binseey("BinningHistEEY");
315
316 binsedx.SetEdges(25, 2.5, 5.);
317 binsedy.SetEdges(30, -1., 1.);
318 binseex.SetEdges(25, 2.5, 5.);
319 binseey.SetEdges(30, 2., 5.);
320
321 parlist2.AddToList(&binsedx);
322 parlist2.AddToList(&binsedy);
323 parlist2.AddToList(&binseex);
324 parlist2.AddToList(&binseey);
325
326 //
327 // Create energy estimator task, add necessary containers and
328 // initialize parameters read from file:
329 //
330
331 MEnergyEstParam eest2("Hillas");
332 eest2.Add("HillasSrc");
333
334 TFile enparam("energyest.root");
335 TArrayD parA(5);
336 TArrayD parB(7);
337
338 for (Int_t i=0; i<parA.GetSize(); i++)
339 parA[i] = EnergyParams(i);
340 for (Int_t i=0; i<parB.GetSize(); i++)
341 parB[i] = EnergyParams(i+parA.GetSize());
342
343 eest2.SetCoeffA(parA);
344 eest2.SetCoeffB(parB);
345
346 enparam.Close();
347
348 //
349 // Setup tasklists
350 //
351
352 tlist2.AddToList(&read2);
353
354 //
355 // Include filter on hadronness and maximum value of dist:
356 //
357 TString hcut2("MHadronness.fHadronness>");
358 hcut2 += maxhadronness;
359 hcut2 += "|| HillasSrc.fDist > ";
360 hcut2 += maxdist;
361
362 MContinue cont(hcut2);
363
364 tlist2.AddToList(&cont);
365 tlist2.AddToList(&eest2);
366
367 // tlist2.AddToList(new MPrint("MMcEvt"));
368 // tlist2.AddToList(new MPrint("MEnergyEst"));
369
370 tlist2.AddToList(&hfilled);
371 tlist2.AddToList(&hfilled2);
372 tlist2.AddToList(&hfillee);
373
374 //
375 // Create and setup the eventloop
376 //
377 MProgressBar bar;
378
379 MEvtLoop evtloop2;
380 evtloop2.SetProgressBar(&bar);
381 evtloop2.SetParList(&parlist2);
382
383 //
384 // Execute your analysis
385 //
386 if (!evtloop2.Eventloop())
387 return;
388
389 //
390 // Plot results:
391 //
392 mhe.GetHist()->GetXaxis()->SetTitle("log_{10} E_{MC} (GeV)");
393 mhe.GetHist()->GetYaxis()->SetTitle("log_{10} E_{EST} (GeV)");
394 mhe.GetHist()->GetXaxis()->SetTitleOffset(1.2);
395
396 TCanvas *c = new TCanvas("energy","CT1 Energy estimation");
397 c->Divide(2,2);
398 c->cd(1);
399 energy_1->SetBottomMargin(0.12);
400 mhe.DrawClone("PROFXnonew");
401
402 mh3ed.GetHist()->GetXaxis()->SetTitle("log_{10} E_{MC} (GeV)");
403 mh3ed.GetHist()->GetYaxis()->SetTitle("\\frac{E_{EST} - E_{MC}}{E_{MC}}");
404 mh3ed.GetHist()->GetXaxis()->SetTitleOffset(1.2);
405 mh3ed.GetHist()->GetYaxis()->SetTitleOffset(1.5);
406 c->cd(2);
407 energy_2->SetLeftMargin(0.15);
408 energy_2->SetBottomMargin(0.12);
409 mh3ed.DrawClone("PROFXnonew");
410
411 mh3ed2.GetHist()->GetXaxis()->SetTitle("log_{10} E_{EST} (GeV)");
412 mh3ed2.GetHist()->GetYaxis()->SetTitle("\\frac{E_{EST} - E_{MC}}{E_{MC}}");
413 mh3ed2.GetHist()->GetXaxis()->SetTitleOffset(1.2);
414 mh3ed2.GetHist()->GetYaxis()->SetTitleOffset(1.5);
415 c->cd(3);
416 energy_3->SetLeftMargin(0.15);
417 energy_3->SetBottomMargin(0.12);
418 mh3ed2.DrawClone("PROFXnonew");
419
420 ((TH2*)mh3ed2.GetHist())->ProjectionY("deltae");
421
422 c->cd(4);
423 energy_4->SetLeftMargin(0.1);
424 energy_4->SetRightMargin(0.05);
425 energy_4->SetBottomMargin(0.12);
426 deltae.GetXaxis()->SetTitleOffset(1.2);
427 deltae.GetXaxis()->SetTitle("(E_{EST} - E_{MC}) / E_{MC}");
428 deltae.Draw("e");
429
430 TFile out2("energyest.root", "update");
431 ((TH2*)mh3ed.GetHist())->Write("mh3ed");
432 ((TH2*)mh3ed2.GetHist())->Write("mh3ed2");
433 ((TH2*)mhe.GetHist())->Write("mhe");
434 deltae.Write();
435 out2.Close();
436
437 return;
438
439}
Note: See TracBrowser for help on using the repository browser.