source: trunk/MagicSoft/Mars/mgeom/MGeomCam.cc@ 8785

Last change on this file since 8785 was 8756, checked in by tbretz, 17 years ago
*** empty log message ***
File size: 14.7 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 12/2000 <mailto:tbretz@astro.uni-wuerzburg.de>
19! Author(s): Harald Kornmayer 01/2001
20! Author(s): Markus Gaug 03/2004 <mailto:markus@ifae.es>
21!
22! Copyright: MAGIC Software Development, 2000-2007
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MGeomCam
29//
30// This is the base class of different camera geometries. It creates
31// a pixel object for a given number of pixels and defines the
32// interface of how to acccess the geometry information.
33//
34// We use a TObjArray for possible future usage (it is much more flexible
35// than a TClonesArray so that it can store more types of pixels (eg
36// fake pixels which are not really existing)
37//
38// Version 1:
39// ----------
40// - first implementation
41//
42// Version 2:
43// ----------
44// - added fPixRatio
45// - added fPixRatioSqrt
46//
47// Version 3:
48// ----------
49// - added fNumAreas
50// - added fNumSectors
51//
52// Version 4:
53// ----------
54// - added fMaxRadius
55// - added fMinRadius
56//
57// Version 5:
58// ----------
59// - added fNumPixInSector
60// - added fNumPixWithAidx
61// - removed fNumSectors
62// - removed fNumAreas
63//
64/////////////////////////////////////////////////////////////////////////////
65#include "MGeomCam.h"
66
67#include <TClass.h> // IsA()->New()
68#include <TArrayI.h> // TArrayI
69#include <TVector2.h> // TVector2
70
71#include "MLog.h"
72#include "MLogManip.h"
73
74#include "MGeomPix.h"
75
76ClassImp(MGeomCam);
77
78using namespace std;
79
80// --------------------------------------------------------------------------
81//
82// Default Constructor. Initializes a Camera Geometry with npix pixels. All
83// pixels are deleted when the corresponding array is deleted.
84//
85MGeomCam::MGeomCam(UInt_t npix, Float_t dist, const char *name, const char *title)
86 : fNumPixels(npix), fCamDist(dist), fConvMm2Deg(kRad2Deg/(dist*1000)),
87 fPixels(npix), fMaxRadius(1), fMinRadius(1), fPixRatio(npix), fPixRatioSqrt(npix)
88{
89 fName = name ? name : "MGeomCam";
90 fTitle = title ? title : "Storage container for a camera geometry";
91
92 //
93 // make sure that the destructor delete all contained objects
94 //
95 fPixels.SetOwner();
96
97 for (UInt_t i=0; i<npix; i++)
98 fPixels[i] = new MGeomPix;
99}
100
101// --------------------------------------------------------------------------
102//
103// Returns a reference of the i-th entry (the pixel with the software idx i)
104// The access is unchecked (for speed reasons!) accesing non existing
105// entries may crash the program!
106//
107MGeomPix &MGeomCam::operator[](Int_t i)
108{
109 return *static_cast<MGeomPix*>(fPixels.UncheckedAt(i));
110}
111
112// --------------------------------------------------------------------------
113//
114// Returns a reference of the i-th entry (the pixel with the software idx i)
115// The access is unchecked (for speed reasons!) accesing non existing
116// entries may crash the program!
117//
118MGeomPix &MGeomCam::operator[](Int_t i) const
119{
120 return *static_cast<MGeomPix*>(fPixels.UncheckedAt(i));
121}
122
123// --------------------------------------------------------------------------
124//
125// Calculate and fill the arrays storing the ratio of the area of a pixel
126// i to the pixel 0 and its square root.
127// The precalculation is done for speed reasons. Having an event the
128// ratio would be calculated at least once for each pixel which is
129// an enormous amount of numerical calculations, which are time
130// consuming and which can be avoided doing the precalculation.
131//
132void MGeomCam::CalcPixRatio()
133{
134 const Double_t a0 = (*this)[0].GetA();
135
136 for (UInt_t i=0; i<fNumPixels; i++)
137 {
138 fPixRatio[i] = a0/(*this)[i].GetA();
139 fPixRatioSqrt[i] = TMath::Sqrt(fPixRatio[i]);
140 }
141}
142
143// --------------------------------------------------------------------------
144//
145// Set the kIsOuterRing flag for all pixels which have a outermost pixel
146// as Next Neighbor and don't have the kIsOutermostRing flag itself.
147//
148void MGeomCam::InitOuterRing()
149{
150 fPixels.R__FOR_EACH(MGeomPix, CheckOuterRing)(*this);
151}
152
153// --------------------------------------------------------------------------
154//
155// Calculate the highest sector index+1 of all pixels, please make sure
156// the the sector numbers are continous.
157//
158void MGeomCam::CalcNumSectors()
159{
160 for (UInt_t i=0; i<fNumPixels; i++)
161 {
162 const Int_t s = (*this)[i].GetSector();
163
164 if (s>=fNumPixInSector.GetSize())
165 fNumPixInSector.Set(s+1);
166
167 fNumPixInSector[s]++;
168 }
169}
170
171// --------------------------------------------------------------------------
172//
173// Calculate the highest area index+1 of all pixels, please make sure
174// the the area indices are continous.
175//
176void MGeomCam::CalcNumAreas()
177{
178 for (UInt_t i=0; i<fNumPixels; i++)
179 {
180 const Int_t s = (*this)[i].GetAidx();
181
182 if (s>=fNumPixWithAidx.GetSize())
183 fNumPixWithAidx.Set(s+1);
184
185 fNumPixWithAidx[s]++;
186 }
187}
188
189// --------------------------------------------------------------------------
190//
191// Calculate the maximum radius of the camera. This is ment for GUI layout.
192//
193void MGeomCam::CalcMaxRadius()
194{
195 fMaxRadius.Set(GetNumAreas()+1);
196 fMinRadius.Set(GetNumAreas()+1);
197
198 for (UInt_t i=0; i<GetNumAreas()+1; i++)
199 {
200 fMaxRadius[i] = 0.;
201 fMinRadius[i] = FLT_MAX;
202 }
203
204 for (UInt_t i=0; i<fNumPixels; i++)
205 {
206 const MGeomPix &pix = (*this)[i];
207
208 const UInt_t s = pix.GetAidx();
209
210 const Float_t d = pix.GetD();
211 const Float_t r = pix.GetDist();
212
213 const Float_t maxr = r + d;
214 const Float_t minr = r>d ? r-d : 0;
215
216 if (maxr>fMaxRadius[s+1])
217 fMaxRadius[s+1] = maxr;
218
219 if (minr<fMinRadius[s+1])
220 fMinRadius[s+1] = minr;
221
222 if (minr<fMinRadius[0])
223 fMinRadius[0] = minr;
224
225 if (maxr>fMaxRadius[0])
226 fMaxRadius[0] = maxr;
227 }
228}
229
230// --------------------------------------------------------------------------
231//
232// sort neighbours from angle of -180 degree to -180 degree
233//
234// where right side of main pixel contains negative degrees
235// and left side positive degrees
236//
237// angle measured from top (0 degree) to bottom (180 degree)
238// ^ - | + //
239// | _ | _ //
240// | / \|/ \ //
241// 30 degree -+- | | | //
242// | / \ / \ / \ //
243// 90 degree -+- | | X | | //
244// | \ / \ / \ / //
245// 150 degree -+- | | | //
246// | \_/|\_/ //
247// | | //
248// | - | + //
249// ------------------> //
250// //
251void MGeomCam::SortNeighbors()
252{
253 for (unsigned int i=0; i<fNumPixels; i++)
254 {
255 MGeomPix &gpix = (*this)[i];
256
257 Double_t phi[6];
258 Int_t idx[7] = { 0, 0, 0, 0, 0, 0, -1 };
259
260 const Int_t n2 = gpix.GetNumNeighbors();
261 for (int j=0; j<n2; j++)
262 {
263 idx[j] = gpix.GetNeighbor(j);
264 phi[j] = (*this)[idx[j]].GetAngle(gpix);
265 }
266
267 Int_t sort[6] = { 6, 6, 6, 6, 6, 6 };
268
269 TMath::Sort(n2, phi, sort, kFALSE);
270
271 gpix.SetNeighbors(idx[sort[0]], idx[sort[1]], idx[sort[2]],
272 idx[sort[3]], idx[sort[4]], idx[sort[5]]);
273 }
274}
275
276// --------------------------------------------------------------------------
277//
278// Returns the distance between the pixels i and j. -1 if an index
279// doesn't exist. The default for j is 0. Assuming that 0 is the index
280// for a central pixel you can get the distance to the camera center.
281//
282Float_t MGeomCam::GetDist(UShort_t i, UShort_t j) const
283{
284 if (i>=fNumPixels || j>=fNumPixels)
285 return -1;
286
287 return (*this)[i].GetDist((*this)[j]);
288}
289
290// --------------------------------------------------------------------------
291//
292// Returns the angle between of pixels i wrt pixel j (default=0). The angle
293// is returned in the range between -pi and pi (atan2) and 2*pi if i or j
294// is out of range.
295//
296Float_t MGeomCam::GetAngle(UShort_t i, UShort_t j) const
297{
298 if (i>=fNumPixels || j>=fNumPixels)
299 return TMath::TwoPi();
300
301 return (*this)[i].GetAngle((*this)[j]);
302}
303
304// --------------------------------------------------------------------------
305//
306// Have to call the radii of the subcameras starting to count from 1
307//
308Float_t MGeomCam::GetMaxRadius(const Int_t i) const
309{
310 return i<-1 || i>=(Int_t)GetNumAreas() ? -1 : fMaxRadius[i+1];
311}
312
313// --------------------------------------------------------------------------
314//
315// Have to call the radii of the subcameras starting to count from 1
316//
317Float_t MGeomCam::GetMinRadius(const Int_t i) const
318{
319 return i<-1 || i>=(Int_t)GetNumAreas() ? -1 : fMinRadius[i+1];
320}
321
322
323// --------------------------------------------------------------------------
324//
325// returns the ratio of the area of the pixel with index 0 to the pixel
326// with the specified index i. 0 Is returned if the index argument is
327// out of range.
328//
329Float_t MGeomCam::GetPixRatio(UInt_t i) const
330{
331 // Former: (*this)[0].GetA()/(*this)[i].GetA();
332 // The const_cast is necessary to support older root version
333 return i<fNumPixels ? const_cast<TArrayF&>(fPixRatio)[i] : 0;
334}
335
336// --------------------------------------------------------------------------
337//
338// returns the square root of the ratio of the area of the pixel with
339// index 0 to the pixel with the specified index i. 0 Is returned if
340// the index argument is out of range.
341//
342Float_t MGeomCam::GetPixRatioSqrt(UInt_t i) const
343{
344 // The const_cast is necessary to support older root version
345 return i<fNumPixels ? const_cast<TArrayF&>(fPixRatioSqrt)[i] : 0;
346}
347
348// --------------------------------------------------------------------------
349//
350// Prints the Geometry information of all pixels in the camera
351//
352void MGeomCam::Print(Option_t *) const
353{
354 //
355 // Print Information about the Geometry of the camera
356 //
357 *fLog << all << " Number of Pixels (" << GetTitle() << "): " << fNumPixels << endl;
358 *fLog << " Number of Sectors: " << GetNumSectors() << " Area-Indices: " << GetNumAreas() << endl;
359 *fLog << " Min.Radius: " << GetMinRadius() << " Max.Radius: " << GetMaxRadius() << endl;
360
361 fPixels.Print();
362}
363
364// --------------------------------------------------------------------------
365//
366// Create a clone of this container. This is very easy, because we
367// simply have to create a new object of the same type.
368//
369TObject *MGeomCam::Clone(const char *newname) const
370{
371 if (IsA()==MGeomCam::Class())
372 {
373 MGeomCam *cam = new MGeomCam(fNumPixels, fCamDist);
374 for (UInt_t i=0; i<fNumPixels; i++)
375 {
376 //if (fPixels.UncheckedAt(i))
377 (*this)[i].Copy((*cam)[i]);
378 }
379 cam->InitGeometry();
380 return cam;
381 }
382
383 return (TObject*)IsA()->New();
384}
385
386// --------------------------------------------------------------------------
387//
388// Return the pixel index corresponding to the coordinates given in x, y.
389// The coordinates are given in pixel units (millimeters)
390// If no pixel exists return -1;
391//
392Int_t MGeomCam::GetPixelIdxXY(Float_t x, Float_t y) const
393{
394 for (unsigned int i=0; i<fNumPixels; i++)
395 if ((*this)[i].IsInside(x, y))
396 return i;
397
398 return -1;
399}
400
401Int_t MGeomCam::GetPixelIdx(const TVector2 &v) const
402{
403 return GetPixelIdxXY(v.X(), v.Y());
404}
405
406Int_t MGeomCam::GetPixelIdxDeg(const TVector2 &v) const
407{
408 return GetPixelIdxXYdeg(v.X(), v.Y());
409}
410
411// --------------------------------------------------------------------------
412//
413// Add all indices to arr of all neighbors around pix in a radius r.
414// The center pixel is also returned.
415//
416void MGeomCam::GetNeighbors(TArrayI &arr, const MGeomPix &pix, Float_t r) const
417{
418 arr.Set(GetNumPixels());
419
420 Int_t n = 0;
421
422 for (unsigned int i=0; i<GetNumPixels(); i++)
423 {
424 if (r>TMath::Hypot(pix.GetX()-(*this)[i].GetX(), pix.GetY()-(*this)[i].GetY()))
425 arr[n++] = i;
426 }
427
428 arr.Set(n);
429}
430
431// --------------------------------------------------------------------------
432//
433// Add all indices to arr of all neighbors around idx in a radius r.
434// The center pixel is also returned.
435//
436void MGeomCam::GetNeighbors(TArrayI &arr, UInt_t idx, Float_t r) const
437{
438 if (idx>=GetNumPixels())
439 {
440 arr.Set(0);
441 return;
442 }
443
444 const MGeomPix &pix = (*this)[idx];
445 GetNeighbors(arr, pix, r);
446}
447
448// --------------------------------------------------------------------------
449//
450// Add all pixels to list of all neighbors around pix in a radius r.
451// The center pixel is also returned.
452//
453void MGeomCam::GetNeighbors(TList &arr, const MGeomPix &pix, Float_t r) const
454{
455 for (unsigned int i=0; i<GetNumPixels(); i++)
456 {
457 if (r>TMath::Hypot(pix.GetX()-(*this)[i].GetX(), pix.GetY()-(*this)[i].GetY()))
458 arr.Add(fPixels.UncheckedAt(i));
459 }
460}
461
462// --------------------------------------------------------------------------
463//
464// Add all pixels to list of all neighbors around idx in a radius r.
465// The center pixel is also returned.
466//
467void MGeomCam::GetNeighbors(TList &arr, UInt_t idx, Float_t r) const
468{
469 if (idx>=GetNumPixels())
470 return;
471
472 const MGeomPix &pix = (*this)[idx];
473 GetNeighbors(arr, pix, r);
474}
475
476// --------------------------------------------------------------------------
477//
478// Return direction of p2 w.r.t. p1. For more details
479// see MGeomPix::GetDirection
480//
481Int_t MGeomCam::GetDirection(UInt_t p1, UInt_t p2) const
482{
483 if (p1>fNumPixels || p2>fNumPixels)
484 return -1;
485
486 return operator[](p1).GetDirection(operator[](p2));
487}
488
489// --------------------------------------------------------------------------
490//
491// Get index of neighbor of pixel idx in direction dir, if existing.
492//
493Int_t MGeomCam::GetNeighbor(UInt_t idx, Int_t dir) const
494{
495 if (idx>fNumPixels)
496 return -1;
497
498 const MGeomPix &pix=operator[](idx);
499
500 //
501 // search for the neighbor in the given direction
502 //
503 int i;
504 for (i=0; i<pix.GetNumNeighbors(); i++)
505 if (GetDirection(idx, pix.GetNeighbor(i))==dir)
506 return pix.GetNeighbor(i);
507
508 return -1;
509}
Note: See TracBrowser for help on using the repository browser.