source: trunk/MagicSoft/Mars/manalysis/MHillas.cc@ 770

Last change on this file since 770 was 765, checked in by tbretz, 24 years ago
*** empty log message ***
  • Property svn:executable set to *
File size: 7.4 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): Harald Kornmayer 1/2001 (harald@mppmu.mpg.de)
19! Author(s): Thomas Bretz 12/2000 (tbretz@uni-sw.gwdg.de)
20!
21! Copyright: MAGIC Software Development, 2000-2001
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27// //
28// MHillas //
29// //
30// Storage Container for the Hillas parameter //
31// //
32// FIXME: Here everybody should find an explanation of the parameters //
33// //
34/////////////////////////////////////////////////////////////////////////////
35#include "MHillas.h"
36
37#include <math.h>
38
39#include <TEllipse.h>
40
41#include "MCerPhotEvt.h"
42#include "MCerPhotPix.h"
43#include "MGeomCam.h"
44
45#include "MLog.h"
46
47ClassImp(MHillas)
48
49// --------------------------------------------------------------------------
50//
51// Default constructor.
52//
53MHillas::MHillas(const char *name, const char *title) :
54 fAlpha(0), fTheta(0), fWidth(0), fLength(0), fSize(0), fDist(0), fEllipse(NULL)
55{
56 *fName = name ? name : "MHillas";
57 *fTitle = title ? title : "Storage container for Hillas parameter of one event";
58
59 // FIXME: Initialization of values missing
60}
61
62// --------------------------------------------------------------------------
63//
64// Destructor. Deletes the TEllipse if one exists.
65//
66MHillas::~MHillas()
67{
68 Clear();
69}
70
71// --------------------------------------------------------------------------
72//
73// Print the hillas Parameters to *fLog
74//
75void MHillas::Print(Option_t *)
76{
77 *fLog << "Hillas Parameter:" << endl;
78 *fLog << " - Alpha = " << fabs(fAlpha) << endl;
79 *fLog << " - Width = " << fWidth << endl;
80 *fLog << " - Length = " << fLength << endl;
81 *fLog << " - Size = " << fSize << endl;
82 *fLog << " - Dist = " << fDist << endl;
83}
84
85// --------------------------------------------------------------------------
86//
87// call the Paint function of the Ellipse if a TEllipse exists
88//
89void MHillas::Paint(Option_t *)
90{
91 if (!fEllipse)
92 return;
93
94 fEllipse->Paint();
95}
96
97// --------------------------------------------------------------------------
98//
99// Instead of adding MHillas itself to the Pad
100// (s. AppendPad in TObject) we create an ellipse,
101// which is added to the Pad by it's Draw function
102// You can remove it by deleting the Ellipse Object
103// (s. Clear() )
104//
105void MHillas::Draw(Option_t *)
106{
107 Clear();
108
109 fEllipse = new TEllipse(cos(fTheta)*fDist, sin(fTheta)*fDist,
110 fLength, fWidth,
111 0, 360, fTheta*kRad2Deg+fAlpha-180);
112
113 fEllipse->SetLineWidth(2);
114 fEllipse->Draw();
115
116 /*
117 This is from TH1
118 TString opt = option;
119 opt.ToLower();
120 if (gPad && !opt.Contains("same")) {
121 //the following statement is necessary in case one attempts to draw
122 //a temporary histogram already in the current pad
123 if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
124 gPad->Clear();
125 }
126 AppendPad(opt.Data());
127 */
128}
129
130// --------------------------------------------------------------------------
131//
132// If a TEllipse object exists it is deleted
133//
134void MHillas::Clear(Option_t *)
135{
136 if (!fEllipse)
137 return;
138
139 delete fEllipse;
140
141 fEllipse = NULL;
142}
143
144// --------------------------------------------------------------------------
145//
146// Calculate the Hillas parameters from a cerenkov photon event
147// (The calcualtion is some kind of two dimentional statistics)
148//
149Bool_t MHillas::Calc(MGeomCam &geom, MCerPhotEvt &evt)
150{
151 const UInt_t nevt = evt.GetNumPixels();
152
153 //
154 // sanity check
155 //
156 if (nevt <= 2)
157 return kFALSE;
158
159 //
160 // calculate mean valu of pixels
161 //
162 float xmean =0;
163 float ymean =0;
164
165 fSize = 0;
166
167 //
168 // FIXME! npix should be retrieved from MCerPhotEvt
169 //
170 UShort_t npix=0;
171 for (UInt_t i=0; i<nevt; i++)
172 {
173 const MCerPhotPix &pix = evt[i];
174
175 if (!pix.IsPixelUsed())
176 continue;
177
178 const MGeomPix &gpix = geom[pix.GetPixId()];
179
180 const float nphot = pix.GetNumPhotons();
181
182 fSize += nphot;
183 xmean += nphot * gpix.GetX(); // [mm]
184 ymean += nphot * gpix.GetY(); // [mm]
185
186 npix++;
187 }
188
189 //
190 // sanity check
191 //
192 if (fSize==0 || npix<=2)
193 return kFALSE;
194
195 xmean /= fSize; // [mm]
196 ymean /= fSize; // [mm]
197
198 //
199 // calculate sdev
200 //
201 float sigmaxx=0;
202 float sigmaxy=0;
203 float sigmayy=0;
204
205 for (UInt_t i=0; i<nevt; i++)
206 {
207 const MCerPhotPix &pix = evt[i];
208
209 if (!pix.IsPixelUsed())
210 continue;
211
212 const MGeomPix &gpix = geom[pix.GetPixId()];
213
214 const float dx = gpix.GetX() - xmean;
215 const float dy = gpix.GetY() - ymean;
216
217 const float nphot = pix.GetNumPhotons();
218
219 sigmaxx += nphot * dx*dx; // [mm^2]
220 sigmaxy += nphot * dx*dy; // [mm^2]
221 sigmayy += nphot * dy*dy; // [mm^2]
222 }
223
224 //
225 // check for orientation
226 //
227 const float theta = atan(sigmaxy/(sigmaxx-sigmayy)*2)/2;
228
229 float c = cos(theta); // [1]
230 float s = sin(theta); // [1]
231
232 //
233 // calculate the length of the two axis
234 //
235 float axis1 = 2.0*c*s*sigmaxy + c*c*sigmaxx + s*s*sigmayy; // [mm^2]
236 float axis2 = -2.0*c*s*sigmaxy + s*s*sigmaxx + c*c*sigmayy; // [mm^2]
237
238 axis1 /= fSize; // [mm^2]
239 axis2 /= fSize; // [mm^2]
240
241 //
242 // check for numerical negatives
243 // (very small number can get negative by chance)
244 //
245 if (axis1 < 0) axis1=0;
246 if (axis2 < 0) axis2=0;
247
248 //
249 // calculate the main Hillas parameters
250 //
251 // fLength, fWidth describes the two axis of the ellipse
252 // fAlpha is the angle between the length-axis and the center
253 // of the camera
254 // fDist is the distance between the center of the camera and the
255 // denter of the ellipse
256 //
257 const int rotation = axis1<axis2;
258
259 fLength = rotation ? sqrt(axis2) : sqrt(axis1); // [mm]
260 fWidth = rotation ? sqrt(axis1) : sqrt(axis2); // [mm]
261
262 const float a = c*xmean + s*ymean;
263 const float b = c*ymean - s*xmean;
264
265 fAlpha = rotation ? atan(a/b) : atan(-b/a); // [rad]
266 fAlpha *= kRad2Deg; // [deg]
267
268 fDist = sqrt(xmean*xmean + ymean*ymean); // [mm]
269
270 fTheta = atan(ymean/xmean); // [rad]
271 if (xmean<0) fTheta += kPI; // [rad]
272
273 return kTRUE;
274}
Note: See TracBrowser for help on using the repository browser.