source: trunk/MagicSoft/Mars/mmuon/MMuonSearchPar.cc@ 8550

Last change on this file since 8550 was 8535, checked in by tbretz, 18 years ago
*** empty log message ***
File size: 9.3 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): Keiichi Mase 10/2004 <mailto:mase@mppmu.mpg.de>
19! Author(s): Markus Meyer 10/2004 <mailto:meyer@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2000-2005
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MMuonSearchPar
29//
30// Storage Container for muon
31//
32// This class is the container for muon parameters. The calculation
33// of Radius and center of the ring is done here.
34// Muons are searched by fitting the image with a circle.
35//
36// In order to use further information of muons such as the width of arcs,
37// the size of the fraction of the ring and the muons size, use the
38// infomation stored in
39//
40// MMuonCalibPar.
41//
42// The information will be available by using the task of
43//
44// MMuonCalibParCalc.
45//
46// Version 2:
47// ----------
48// + Float_t fTime; // Mean arrival time of core pixels
49// + Float_t fTimeRms; // Rms of arrival time of core pixels
50//
51// Input Containers:
52// MGeomCam
53// MHillas
54// MSignalCam
55//
56/////////////////////////////////////////////////////////////////////////////
57#include "MMuonSearchPar.h"
58
59#include <TMinuit.h>
60#include <TEllipse.h>
61
62#include "MLog.h"
63#include "MLogManip.h"
64
65#include "MHillas.h"
66
67#include "MGeomCam.h"
68#include "MGeomPix.h"
69
70#include "MSignalPix.h"
71#include "MSignalCam.h"
72
73using namespace std;
74
75ClassImp(MMuonSearchPar);
76
77// --------------------------------------------------------------------------
78//
79// Default constructor.
80//
81MMuonSearchPar::MMuonSearchPar(const char *name, const char *title)
82{
83 fName = name ? name : "MMuonSearchPar";
84 fTitle = title ? title : "Parameters to find Muons";
85}
86
87// --------------------------------------------------------------------------
88//
89void MMuonSearchPar::Reset()
90{
91 fRadius = -1;
92 fDeviation = -1;
93 fCenterX = 0;
94 fCenterY = 0;
95 fTime = 0;
96 fTimeRms = -1;
97}
98
99// --------------------------------------------------------------------------
100//
101// This is a wrapper function to have direct access to the data members
102// in the function calculating the minimization value.
103//
104void MMuonSearchPar::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
105{
106 const MMuonSearchPar *optim = (MMuonSearchPar*)gMinuit->GetObjectFit();
107 f = optim->Fcn(par);
108}
109
110// --------------------------------------------------------------------------
111//
112// This function gives you the ring radius fitted best to the camera image
113// and its RMS for the input position.
114//
115Double_t MMuonSearchPar::Fcn(Double_t *par) const
116{
117 const Int_t entries = fSignal.GetSize();
118
119 Double_t meanr=0;
120 Double_t devr =0;
121 Double_t sums =0;
122
123 // It seems that the loop is easy enough for a compiler optimization.
124 // Using pointer arithmetics doesn't improve the speed of the fit.
125 for (Int_t i=0; i<entries; i++ )
126 {
127 const Double_t dx = fX[i]-par[0];
128 const Double_t dy = fY[i]-par[1];
129
130 const Double_t sq = dx*dx + dy*dy;
131
132 sums += fSignal[i];
133 meanr += fSignal[i] * TMath::Sqrt(sq);
134 devr += fSignal[i] * sq;
135 }
136
137 par[2] = meanr/sums;
138 par[3] = devr/sums - par[2]*par[2];
139
140 return par[3];
141}
142
143// --------------------------------------------------------------------------
144//
145// This function finds the center position of the circle which gives minimum
146// RMS of the fit, changing the center position of the circle.
147//
148void MMuonSearchPar::CalcMinimumDeviation(const MGeomCam &geom,
149 const MSignalCam &evt,
150 Double_t &x, Double_t &y,
151 Double_t &sigma, Double_t &radius)
152{
153 // ------- Make a temporaray copy of the signal ---------
154 // ------- and calculate arrival time parameters --------
155 const Int_t n = geom.GetNumPixels();
156
157 fSignal.Set(n);
158 fX.Set(n);
159 fY.Set(n);
160
161 Int_t p=0;
162 Int_t q=0;
163
164 Double_t mean=0;
165 Double_t sq =0;
166
167 for (int i=0; i<n; i++)
168 {
169 const MSignalPix &pix = evt[i];
170 if (!pix.IsPixelUsed())
171 continue;
172
173 fSignal[p] = pix.GetNumPhotons();
174
175 fX[p] = geom[i].GetX();
176 fY[p] = geom[i].GetY();
177 p++;
178
179 //timing
180 if (!pix.IsPixelCore())
181 continue;
182
183 mean += pix.GetArrivalTime();
184 sq += pix.GetArrivalTime()*pix.GetArrivalTime();
185 q++;
186 }
187
188 mean /= q;
189 sq /= q;
190
191 fTime = mean;
192 fTimeRms = TMath::Sqrt(sq-mean*mean);
193
194 fSignal.Set(p);
195
196
197 // ----------------- Setup and call minuit -------------------
198 const Float_t delta = 30.; // 3 mm (1/10 of an inner pixel size) Step to move.
199 const Double_t r = geom.GetMaxRadius()*2;
200
201 // Save gMinuit
202 TMinuit *minsave = gMinuit;
203
204 // Initialize TMinuit with 4 parameters
205 TMinuit minuit;
206 minuit.SetPrintLevel(-1); // Switch off printing
207 minuit.Command("set nowarn"); // Switch off warning
208 // Define Parameters
209 minuit.DefineParameter(0, "x", x, delta, -r, r);
210 minuit.DefineParameter(1, "y", y, delta, -r, r);
211 minuit.DefineParameter(2, "r", 0, 1, 0, 0);
212 minuit.DefineParameter(3, "sigma", 0, 1, 0, 0);
213 // Fix return parameters
214 minuit.FixParameter(2);
215 minuit.FixParameter(3);
216 // Setup Minuit for 'this' and use fit function fcn
217 minuit.SetObjectFit(this);
218 minuit.SetFCN(fcn);
219
220 // Perform Simplex minimization
221 Int_t err;
222 Double_t tmp[2] = { 0, 0 };
223 minuit.mnexcm("simplex", tmp, 2, err);
224
225 // Get resulting parameters
226 Double_t error;
227 minuit.GetParameter(0, x, error);
228 minuit.GetParameter(1, y, error);
229 minuit.GetParameter(2, radius, error);
230 minuit.GetParameter(3, sigma, error);
231
232 sigma = sigma>0 ? TMath::Sqrt(sigma) : 0;
233
234 gMinuit = minsave;
235}
236
237// --------------------------------------------------------------------------
238//
239// Calculation of muon parameters
240//
241void MMuonSearchPar::Calc(const MGeomCam &geom, const MSignalCam &evt,
242 const MHillas &hillas)
243{
244 Double_t x = hillas.GetMeanX();
245 Double_t y = hillas.GetMeanY();
246
247 // -------------------------------------------------
248 // Keiichi suggested trying to precalculate the Muon
249 // center a bit better, but it neither improves the
250 // fit result nor the speed
251 //
252 // const Float_t tmpr = 300.; // assume that the temporal cherenkov angle is 1 deg. (300 mm).
253 //
254 // const Double_t a = TMath::Tan(hillas.GetDelta());
255 //
256 // const Double_t dx = a/TMath::Sqrt(tmpr+a*a)/3.;
257 // const Double_t dy = -tmpr/TMath::Sqrt(1+a*a)/3.;
258 //
259 // Double_t par1[] = { x+dx, y+dy, 0, 0 };
260 // Double_t par2[] = { x-dx, y-dy, 0, 0 };
261 //
262 // const Double_t dev1 = MMuonSearchPar::Fcn(par1);
263 // const Double_t dev2 = MMuonSearchPar::Fcn(par2);
264 //
265 // if (dev1<dev2)
266 // {
267 // x += dx;
268 // y += dy;
269 // }
270 // else
271 // {
272 // x -= dx;
273 // y -= dy;
274 // }
275 // -------------------------------------------------
276
277 Double_t sigma, rad;
278
279 // find the best fit.
280 CalcMinimumDeviation(geom, evt, x, y, sigma, rad);
281
282 fCenterX = x;
283 fCenterY = y;
284 fRadius = rad;
285 fDeviation = sigma;
286
287 //SetReadyToSave();
288}
289
290void MMuonSearchPar::Print(Option_t *) const
291{
292 *fLog << all;
293 *fLog << GetDescriptor() << endl;
294 *fLog << " - Est. Radius [mm] = " << fRadius << endl;
295 *fLog << " - Deviation [mm] = " << fDeviation << endl;
296 *fLog << " - Center Pos. X [mm] = " << fCenterX << endl;
297 *fLog << " - Center Pos. Y [mm] = " << fCenterY << endl;
298}
299
300void MMuonSearchPar::Print(const MGeomCam &geom, Option_t *) const
301{
302 *fLog << all;
303 *fLog << GetDescriptor() << endl;
304 *fLog << " - Est. Radius [deg] = " << fRadius*geom.GetConvMm2Deg() << endl;
305 *fLog << " - Deviation [deg] = " << fDeviation*geom.GetConvMm2Deg() << endl;
306 *fLog << " - Center Pos. X [deg] = " << fCenterX*geom.GetConvMm2Deg() << endl;
307 *fLog << " - Center Pos. Y [deg] = " << fCenterY*geom.GetConvMm2Deg() << endl;
308}
309
310// --------------------------------------------------------------------------
311//
312// Paint the ellipse corresponding to the parameters
313//
314void MMuonSearchPar::Paint(Option_t *opt)
315{
316 if (fRadius<180 || fRadius>400 || fDeviation>45)
317 return;
318
319 TEllipse e1(fCenterX, fCenterY, fRadius-fDeviation, fRadius-fDeviation);
320 TEllipse e2(fCenterX, fCenterY, fRadius+fDeviation, fRadius+fDeviation);
321 e1.SetLineWidth(1);
322 e2.SetLineWidth(1);
323 e1.SetLineColor(kYellow);
324 e2.SetLineColor(kYellow);
325 e1.Paint();
326 e2.Paint();
327}
Note: See TracBrowser for help on using the repository browser.