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

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