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

Last change on this file since 6987 was 6979, checked in by tbretz, 20 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. Actually, the calculation
33// is done here. Muons are searched by fitting the image with a circle.
34// (This function will be called by using the class of MMuonSearchParCalc.)
35// This container especially holds the information of the results of the
36// search (fit of a image by a circle).
37//
38// In order to use further information of muons such as the width of arcs,
39// the arc length along it, the muons size. Use the infomation stored in
40// MMuonCalibPar. The information will be available by using the task of
41// MMuonCalibParCalc.
42//
43// --- How to search muons ---
44// (This information is a little bit technical. You can skip to read if you
45// don't need the technical information.)
46//
47// 1. A temporal center position of a circle is determined by using
48// the Hillas parameters. Assumed that the center position will be on the
49// line which is perpendicular to the longitudinal image axis and the
50// distance from the gravity center of the image to the center position of
51// a ring is approximately 1 deg. (corresponding to the Cherenkov angle.).
52// Therefore, we will have two candidates of the center positions.
53//
54// 2. Find the ring radius which gives the minimum RMS between the camera
55// images and the estimated circle.
56//
57// 3. Select one temporal position which gives smaller RMS as a true temporal
58// center position.
59//
60// 4. Changing the center position of a circle on the camera plane from the
61// determined temporal center position, find the position which gives the
62// minimum RMS of the fit.
63//
64//
65// Input Containers:
66// MGeomCam
67// MHillas
68// MSignalCam
69//
70/////////////////////////////////////////////////////////////////////////////
71#include "MMuonSearchPar.h"
72
73#include <TMinuit.h>
74
75#include "MLog.h"
76#include "MLogManip.h"
77
78#include "MHillas.h"
79
80#include "MGeomCam.h"
81#include "MGeomPix.h"
82
83#include "MSignalPix.h"
84#include "MSignalCam.h"
85
86using namespace std;
87
88ClassImp(MMuonSearchPar);
89
90// --------------------------------------------------------------------------
91//
92// Default constructor.
93//
94MMuonSearchPar::MMuonSearchPar(const char *name, const char *title)
95{
96 fName = name ? name : "MMuonSearchPar";
97 fTitle = title ? title : "Muon search parameters";
98}
99
100// --------------------------------------------------------------------------
101//
102void MMuonSearchPar::Reset()
103{
104 fRadius = -1;
105 fDeviation = -1;
106 fCenterX = 0;
107 fCenterY = 0;
108}
109
110// --------------------------------------------------------------------------
111//
112// This is a wrapper function to have direct access to the data members
113// in the function calculating the minimization value.
114//
115void MMuonSearchPar::fcn(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag)
116{
117 const MMuonSearchPar *optim = (MMuonSearchPar*)gMinuit->GetObjectFit();
118 f = optim->Fcn(par);
119}
120
121// --------------------------------------------------------------------------
122//
123// This function gives you the ring radius fitted best to the camera image
124// and its RMS for the input position.
125//
126Double_t MMuonSearchPar::Fcn(Double_t *par) const
127{
128 const Int_t entries = fSignal.GetSize();
129
130 Double_t meanr=0;
131 Double_t devr =0;
132 Double_t sums =0;
133
134 // It seems that the loop is easy enough for a compiler optimization.
135 // Using pointer arithmetics doesn't improve the speed of the fit.
136 for (Int_t i=0; i<entries; i++ )
137 {
138 Double_t tmp = TMath::Hypot(fX[i]-par[0], fY[i]-par[1]);
139
140 sums += fSignal[i];
141 meanr += fSignal[i] * tmp;
142 devr += fSignal[i] * tmp*tmp;
143 }
144
145 par[2] = meanr/sums;
146 par[3] = devr/sums - par[2]*par[2];
147
148 return par[3];
149}
150
151// --------------------------------------------------------------------------
152//
153// This function finds the center position of the circle which gives minimum
154// RMS of the fit, changing the center position of the circle.
155//
156void MMuonSearchPar::CalcMinimumDeviation(const MGeomCam &geom,
157 const MSignalCam &evt,
158 Double_t &x, Double_t &y,
159 Double_t &sigma, Double_t &radius)
160{
161 // ------- Make a temporaray copy of the signal ---------
162 const Int_t n = geom.GetNumPixels();
163
164 fSignal.Set(n);
165 fX.Set(n);
166 fY.Set(n);
167
168 Int_t p=0;
169 for (int i=0; i<n; i++)
170 {
171 const MSignalPix &pix = evt[i];
172 if (pix.IsPixelUsed())
173 {
174 fSignal[p] = pix.GetNumPhotons();
175
176 fX[p] = geom[i].GetX();
177 fY[p] = geom[i].GetY();
178 p++;
179 }
180 }
181 fSignal.Set(p);
182
183
184 // ----------------- Setup and call minuit -------------------
185 const Float_t delta = 30.; // 3 mm (1/10 of an inner pixel size) Step to move.
186 const Double_t r = geom.GetMaxRadius()*2;
187
188 // Save gMinuit
189 TMinuit *minsave = gMinuit;
190
191 // Initialize TMinuit with 4 parameters
192 TMinuit minuit;
193 minuit.SetPrintLevel(-1); // Switch off printing
194 minuit.Command("set nowarn"); // Switch off warning
195 // Define Parameters
196 minuit.DefineParameter(0, "x", x, delta, -r, r);
197 minuit.DefineParameter(1, "y", y, delta, -r, r);
198 minuit.DefineParameter(2, "r", 0, 1, 0, 0);
199 minuit.DefineParameter(3, "sigma", 0, 1, 0, 0);
200 // Fix return parameters
201 minuit.FixParameter(2);
202 minuit.FixParameter(3);
203 // Setup Minuit for 'this' and use fit function fcn
204 minuit.SetObjectFit(this);
205 minuit.SetFCN(fcn);
206
207 // Perform Simplex minimization
208 Int_t err;
209 Double_t tmp[2] = { 0, 0 };
210 minuit.mnexcm("simplex", tmp, 2, err);
211
212 // Get resulting parameters
213 Double_t error;
214 minuit.GetParameter(0, x, error);
215 minuit.GetParameter(1, y, error);
216 minuit.GetParameter(2, radius, error);
217 minuit.GetParameter(3, sigma, error);
218
219 sigma = sigma>0 ? TMath::Sqrt(sigma) : 0;
220
221 gMinuit = minsave;
222}
223
224// --------------------------------------------------------------------------
225//
226// Calculation of muon parameters
227//
228void MMuonSearchPar::Calc(const MGeomCam &geom, const MSignalCam &evt,
229 const MHillas &hillas)
230{
231 Double_t x = hillas.GetMeanX();
232 Double_t y = hillas.GetMeanY();
233
234 // -------------------------------------------------
235 // Keiichi suggested trying to precalculate the Muon
236 // center a bit better, but it neither improves the
237 // fit result nor the speed
238 //
239 // const Float_t tmpr = 300.; // assume that the temporal cherenkov angle is 1 deg. (300 mm).
240 //
241 // const Double_t a = TMath::Tan(hillas.GetDelta());
242 //
243 // const Double_t dx = a/TMath::Sqrt(tmpr+a*a)/3.;
244 // const Double_t dy = -tmpr/TMath::Sqrt(1+a*a)/3.;
245 //
246 // Double_t par1[] = { x+dx, y+dy, 0, 0 };
247 // Double_t par2[] = { x-dx, y-dy, 0, 0 };
248 //
249 // const Double_t dev1 = MMuonSearchPar::Fcn(par1);
250 // const Double_t dev2 = MMuonSearchPar::Fcn(par2);
251 //
252 // if (dev1<dev2)
253 // {
254 // x += dx;
255 // y += dy;
256 // }
257 // else
258 // {
259 // x -= dx;
260 // y -= dy;
261 // }
262 // -------------------------------------------------
263
264 Double_t sigma, rad;
265
266 // find the best fit.
267 CalcMinimumDeviation(geom, evt, x, y, sigma, rad);
268
269 fCenterX = x;
270 fCenterY = y;
271 fRadius = rad;
272 fDeviation = sigma;
273
274 //SetReadyToSave();
275}
276
277void MMuonSearchPar::Print(Option_t *) const
278{
279 *fLog << all;
280 *fLog << "Muon Parameters (" << GetName() << ")" << endl;
281 *fLog << " - Est. Radius [mm] = " << fRadius << endl;
282 *fLog << " - Deviation [mm] = " << fDeviation << endl;
283 *fLog << " - Center Pos. X [mm] = " << fCenterX << endl;
284 *fLog << " - Center Pos. Y [mm] = " << fCenterY << endl;
285}
286
287void MMuonSearchPar::Print(const MGeomCam &geom, Option_t *) const
288{
289 *fLog << all;
290 *fLog << "Muon Parameters (" << GetName() << ")" << endl;
291 *fLog << " - Est. Radius [deg] = " << fRadius*geom.GetConvMm2Deg() << endl;
292 *fLog << " - Deviation [deg] = " << fDeviation*geom.GetConvMm2Deg() << endl;
293 *fLog << " - Center Pos. X [deg] = " << fCenterX*geom.GetConvMm2Deg() << endl;
294 *fLog << " - Center Pos. Y [deg] = " << fCenterY*geom.GetConvMm2Deg() << endl;
295}
Note: See TracBrowser for help on using the repository browser.