source: trunk/MagicSoft/Mars/manalysis/MCerPhotEvt.cc@ 4836

Last change on this file since 4836 was 4702, checked in by tbretz, 20 years ago
*** empty log message ***
File size: 16.6 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, 1/2001
20!
21! Copyright: MAGIC Software Development, 2000-2003
22!
23!
24\* ======================================================================== */
25
26/////////////////////////////////////////////////////////////////////////////
27//
28// MCerPhotEvt
29//
30// NOTE: This container is NOT ment for I/O. Write it to a file on your own
31// risk!
32//
33// Class Version 3:
34// ----------------
35// - added fNumIslands
36//
37// Class Version 2:
38// ----------------
39// - added fLut to accelerate GetPixById a lot
40//
41// Class Version 1:
42// ----------------
43// - first version
44//
45/////////////////////////////////////////////////////////////////////////////
46#include "MCerPhotEvt.h"
47
48#include <math.h>
49#include <limits.h>
50#include <fstream>
51
52#include <TArrayD.h>
53#include <TCanvas.h>
54
55#include "MLog.h"
56#include "MLogManip.h"
57
58#include "MGeomCam.h"
59#include "MGeomPix.h"
60
61ClassImp(MCerPhotEvt);
62ClassImp(MCerPhotEvtIter);
63
64using namespace std;
65
66// --------------------------------------------------------------------------
67//
68// Creates a MCerPhotPix object for each pixel in the event
69//
70MCerPhotEvt::MCerPhotEvt(const char *name, const char *title) : fNumPixels(0)
71{
72 fName = name ? name : "MCerPhotEvt";
73 fTitle = title ? title : "(Number of Photon)-Event Information";
74
75 fPixels = new TClonesArray("MCerPhotPix", 0);
76}
77
78// --------------------------------------------------------------------------
79//
80// This is not yet implemented like it should.
81//
82/*
83void MCerPhotEvt::Draw(Option_t* option)
84{
85 //
86 // FIXME!!! Here the Draw function of the CamDisplay
87 // should be called to add the CamDisplay to the Pad.
88 // The drawing should be done in MCamDisplay::Paint
89 //
90
91 // MGeomCam *geom = fType ? new MGeomCamMagic : new MGeomCamCT1;
92 // MCamDisplay *disp = new MCamDisplay(geom);
93 // delete geom;
94 // disp->DrawPhotNum(this);
95}
96*/
97
98// --------------------------------------------------------------------------
99//
100// reset counter and delete netries in list.
101//
102void MCerPhotEvt::Reset()
103{
104 fNumPixels = 0;
105 fMaxIndex = -1;
106 fNumIslands = -1;
107 fLut.Set(0);
108 // fPixels->Delete();
109}
110
111void MCerPhotEvt::FixSize()
112{
113 fLut.Set(fMaxIndex+1);
114
115 if (fPixels->GetEntriesFast() == (Int_t)fNumPixels)
116 return;
117
118 fPixels->ExpandCreateFast(fNumPixels);
119}
120
121// --------------------------------------------------------------------------
122//
123// Dump the cerenkov photon event to *fLog
124//
125void MCerPhotEvt::Print(Option_t *) const
126{
127 const Int_t entries = fPixels->GetEntries();
128
129 *fLog << GetDescriptor() << dec << endl;
130 *fLog << " Number of Pixels: " << fNumPixels << "(" << entries << ")" << endl;
131
132 for (Int_t i=0; i<entries; i++ )
133 (*this)[i].Print();
134}
135
136// --------------------------------------------------------------------------
137//
138// Checks if in the pixel list is an entry with pixel id
139//
140Bool_t MCerPhotEvt::IsPixelExisting(Int_t id) const
141{
142 return GetPixById(id) ? kTRUE : kFALSE;
143}
144
145// --------------------------------------------------------------------------
146//
147// Checks if in the pixel list is an entry with pixel id
148//
149Bool_t MCerPhotEvt::IsPixelUsed(Int_t id) const
150{
151 const MCerPhotPix *pix = GetPixById(id);
152 return pix ? pix->IsPixelUsed() : kFALSE;
153}
154
155// --------------------------------------------------------------------------
156//
157// Checks if in the pixel list is an entry with pixel id
158//
159Bool_t MCerPhotEvt::IsPixelCore(Int_t id) const
160{
161 const MCerPhotPix *pix = GetPixById(id);
162 return pix ? pix->IsPixelCore() : kFALSE;
163}
164
165// --------------------------------------------------------------------------
166//
167// get the minimum number of photons of all valid pixels in the list
168// If you specify a geometry the number of photons is weighted with the
169// area of the pixel
170//
171Float_t MCerPhotEvt::GetNumPhotonsMin(const MGeomCam *geom) const
172{
173 if (fNumPixels <= 0)
174 return -5.;
175
176 const UInt_t n = geom->GetNumPixels();
177
178 Float_t minval = FLT_MAX;
179
180 for (UInt_t i=0; i<fNumPixels; i++)
181 {
182 const MCerPhotPix &pix = (*this)[i];
183 if (!pix.IsPixelUsed())
184 continue;
185
186 const UInt_t id = pix.GetPixId();
187 if (id<0 || id>=n)
188 continue;
189
190 Float_t testval = pix.GetNumPhotons();
191
192 if (geom)
193 testval *= geom->GetPixRatio(id);
194
195 if (testval < minval)
196 minval = testval;
197 }
198
199 return minval;
200}
201
202// --------------------------------------------------------------------------
203//
204// get the maximum number of photons of all valid pixels in the list
205// If you specify a geometry the number of photons is weighted with the
206// area of the pixel
207//
208Float_t MCerPhotEvt::GetNumPhotonsMax(const MGeomCam *geom) const
209{
210 if (fNumPixels <= 0)
211 return 50.;
212
213 const UInt_t n = geom->GetNumPixels();
214
215 Float_t maxval = -FLT_MAX;
216
217 for (UInt_t i=0; i<fNumPixels; i++)
218 {
219 const MCerPhotPix &pix = (*this)[i];
220 if (!pix.IsPixelUsed())
221 continue;
222
223 const UInt_t id = pix.GetPixId();
224 if (id<0 || id>=n)
225 continue;
226
227 Float_t testval = pix.GetNumPhotons();
228 if (geom)
229 testval *= geom->GetPixRatio(id);
230
231 if (testval > maxval)
232 maxval = testval;
233 }
234 return maxval;
235}
236
237// --------------------------------------------------------------------------
238//
239// get the minimum ratio of photons/error
240//
241Float_t MCerPhotEvt::GetRatioMin(const MGeomCam *geom) const
242{
243 if (fNumPixels <= 0)
244 return -5.;
245
246 Float_t minval = FLT_MAX;
247
248 for (UInt_t i=0; i<fNumPixels; i++)
249 {
250 const MCerPhotPix &pix = (*this)[i];
251 if (!pix.IsPixelUsed())
252 continue;
253
254 Float_t testval = pix.GetNumPhotons()/pix.GetErrorPhot();
255 if (geom)
256 testval *= TMath::Sqrt(geom->GetPixRatio(pix.GetPixId()));
257
258 if (testval < minval)
259 minval = testval;
260 }
261
262 return minval;
263}
264
265// --------------------------------------------------------------------------
266//
267// get the maximum ratio of photons/error
268//
269Float_t MCerPhotEvt::GetRatioMax(const MGeomCam *geom) const
270{
271 if (fNumPixels <= 0)
272 return -5.;
273
274 Float_t maxval = -FLT_MAX;
275
276 for (UInt_t i=0; i<fNumPixels; i++)
277 {
278 const MCerPhotPix &pix = (*this)[i];
279 if (!pix.IsPixelUsed())
280 continue;
281
282 Float_t testval = pix.GetNumPhotons()/pix.GetErrorPhot();
283 if (geom)
284 testval *= TMath::Sqrt(geom->GetPixRatio(pix.GetPixId()));
285
286 if (testval > maxval)
287 maxval = testval;
288 }
289
290 return maxval;
291}
292
293// --------------------------------------------------------------------------
294//
295// get the minimum of error
296// If you specify a geometry the number of photons is weighted with the
297// area of the pixel
298//
299Float_t MCerPhotEvt::GetErrorPhotMin(const MGeomCam *geom) const
300{
301 if (fNumPixels <= 0)
302 return 50.;
303
304 Float_t minval = FLT_MAX;
305
306 for (UInt_t i=0; i<fNumPixels; i++)
307 {
308 const MCerPhotPix &pix = (*this)[i];
309 if (!pix.IsPixelUsed())
310 continue;
311
312 Float_t testval = pix.GetErrorPhot();
313
314 if (geom)
315 testval *= geom->GetPixRatio(pix.GetPixId());
316
317 if (testval < minval)
318 minval = testval;
319 }
320 return minval;
321}
322
323// --------------------------------------------------------------------------
324//
325// get the maximum ratio of photons/error
326// If you specify a geometry the number of photons is weighted with the
327// area of the pixel
328//
329Float_t MCerPhotEvt::GetErrorPhotMax(const MGeomCam *geom) const
330{
331 if (fNumPixels <= 0)
332 return 50.;
333
334 Float_t maxval = -FLT_MAX;
335
336 for (UInt_t i=0; i<fNumPixels; i++)
337 {
338 const MCerPhotPix &pix = (*this)[i];
339 if (!pix.IsPixelUsed())
340 continue;
341
342 Float_t testval = pix.GetErrorPhot();
343
344 if (geom)
345 testval *= geom->GetPixRatio(pix.GetPixId());
346
347 if (testval > maxval)
348 maxval = testval;
349 }
350 return maxval;
351}
352
353void MCerPhotEvt::RemoveUnusedPixels()
354{
355 // Create iterator
356 TIter Next(fPixels);
357 MCerPhotPix *pix = NULL;
358
359 fMaxIndex = -1;
360
361 // Remove all unused pixels from list, calculate new fMaxIndex
362 while ((pix=(MCerPhotPix*)Next()))
363 {
364 if (!pix->IsPixelUsed())
365 fPixels->Remove(pix);
366 else
367 fMaxIndex = TMath::Max(fMaxIndex, pix->GetPixId());
368 }
369
370 // Crompress array
371 fPixels->Compress();
372
373 // Get new number of entries in array
374 fNumPixels=fPixels->GetEntriesFast();
375
376 // Rebuild lookup table
377 RebuildLut();
378}
379
380// --------------------------------------------------------------------------
381//
382// Return a pointer to the pixel with the requested idx. NULL if it doesn't
383// exist. The Look-up-table fLut is used. If its size is zero (according
384// to Rene this will happen if an old class object is loaded) we still
385// try to search in the array.
386//
387MCerPhotPix *MCerPhotEvt::GetPixById(Int_t idx) const
388{
389 if (idx<0)
390 return 0;
391
392 if (fLut.GetSize()>0)
393 {
394 if (idx>=fLut.GetSize())
395 return 0;
396 return fLut[idx]<0 ? 0 : (MCerPhotPix*)(fPixels->UncheckedAt(fLut[idx]));
397 }
398
399 TIter Next(fPixels);
400 MCerPhotPix *pix = NULL;
401
402 while ((pix=(MCerPhotPix*)Next()))
403 if (pix->GetPixId()==idx)
404 return pix;
405
406 return NULL;
407}
408
409MCerPhotPix *MCerPhotEvt::AddPixel(Int_t idx, Float_t nph, Float_t er)
410 {
411 //
412 // If this is too slow or takes to much space we might use
413 // MGeomApply and an InitSize member function instead.
414 //
415 if (idx>=fLut.GetSize())
416 {
417 const Int_t n = fLut.GetSize();
418 fLut.Set(idx*2+1); //idx+1 is slower than idx*2+1
419 for (int i=n; i<idx*2+1; i++)
420 fLut[i] = -1;
421 }
422
423 fLut[idx] = fNumPixels;
424 if (idx>fMaxIndex)
425 fMaxIndex=idx;
426
427 return new ((*fPixels)[fNumPixels++]) MCerPhotPix(idx, nph, er);
428 }
429
430// --------------------------------------------------------------------------
431//
432// This function recursively finds all pixels of one island and assigns
433// the number num as island number to the pixel.
434//
435// 1) Check whether a pixel with the index idx exists, is unused
436// and has not yet a island number assigned.
437// 2) Assign the island number num to the pixel
438// 3) Loop over all its neighbors taken from the geometry geom. For all
439// neighbors recursively call this function (CalcIsland)
440// 4) Sum the size of the pixel and all neighbors newly assigned
441// (by CalcIsland) to this island
442//
443// Returns the sum of the pixel size.
444//
445Double_t MCerPhotEvt::CalcIsland(const MGeomCam &geom, Int_t idx, Int_t num)
446{
447 // Try to get the pixel information of a pixel with this index
448 MCerPhotPix *pix = GetPixById(idx);
449
450 // If a pixel with this index is not existing... do nothing.
451 if (!pix)
452 return 0;
453
454 // If an island number was already assigned to this pixel... do nothing.
455 if (pix->GetIdxIsland()>=0)
456 return 0;
457
458 // If the pixel is an unused pixel... do nothing.
459 if (!pix->IsPixelUsed())
460 return 0;
461
462 // Assign the new island number num to this used pixel
463 pix->SetIdxIsland(num);
464
465 // Get the geometry information (neighbors) of this pixel
466 const MGeomPix &gpix = geom[idx];
467
468 // Get the size of this pixel
469 Double_t size = pix->GetNumPhotons();
470
471 // Now do the same with all its neighbors and sum the
472 // sizes which they correspond to
473 const Int_t n = gpix.GetNumNeighbors();
474 for (int i=0; i<n; i++)
475 size += CalcIsland(geom, gpix.GetNeighbor(i), num);
476
477 // return size of this (sub)cluster
478 return size;
479}
480
481// --------------------------------------------------------------------------
482//
483// Each pixel which is maked as used is assigned an island number
484// (starting from 0). A pixel without an island number assigned
485// has island number -1.
486//
487// The index 0 corresponds to the island with the highest size (sum
488// of GetNumPhotons() in island). The size is decreasing with
489// increasing indices.
490//
491// The information about pixel neighbory is taken from the geometry
492// MGeomCam geom;
493//
494// You can access this island number of a pixel with a call to
495// MCerPhotPix->GetIdxIsland. The total number of islands available
496// can be accessed with MCerPhotEvt->GetNumIslands.
497//
498// CalcIslands returns the number of islands found. If an error occurs,
499// eg the geometry has less pixels than the highest index stored, -1 is
500// returned.
501//
502Int_t MCerPhotEvt::CalcIslands(const MGeomCam &geom)
503{
504 if (fMaxIndex<0 || fNumPixels<=0)
505 {
506 *fLog << err << "ERROR - MCerPhotEvt doesn't contain pixels!" << endl;
507 fNumIslands = 0;
508 return -1;
509 }
510
511 if ((UInt_t)fMaxIndex>=geom.GetNumPixels())
512 {
513 *fLog << err << "ERROR - MCerPhotEvt::CalcIslands: Size mismatch - geometry too small!" << endl;
514 return -1;
515 }
516
517 // Create a list to hold the sizes of the islands (The maximum
518 // number of islands possible is rougly fNumPixels/4)
519 TArrayD size(fNumPixels/3);
520
521 // Calculate Islands
522 Int_t n=0;
523
524 // We could loop over all indices which looks more straight
525 // forward but should be a lot slower (assuming zero supression)
526 MCerPhotPix *pix=0;
527
528 TIter Next(*this);
529 while ((pix=static_cast<MCerPhotPix*>(Next())))
530 {
531 // This 'if' is necessary (although it is done in GetIsland, too)
532 // because otherwise the counter (n) would be wrong.
533 // So only 'start' a new island for used pixels (selected by
534 // using the Iterator) which do not yet belong to another island.
535 if (pix->GetIdxIsland()<0)
536 {
537 Double_t sz = CalcIsland(geom, pix->GetPixId(), n);
538 size[n++] = sz;
539 }
540 }
541
542 // Create an array holding the indices
543 TArrayI idx(n);
544
545 // Sort the sizes descending
546 TMath::Sort(n, size.GetArray(), idx.GetArray(), kTRUE);
547
548 // Replace island numbers by size indices -- After this
549 // islands indices are sorted by the island size
550 Next.Reset();
551 while ((pix=static_cast<MCerPhotPix*>(Next())))
552 {
553 const Short_t i = pix->GetIdxIsland();
554
555 // Find new index
556 Short_t j;
557 for (j=0; j<n; j++)
558 if (idx[j]==i)
559 break;
560
561 pix->SetIdxIsland(j==n ? -1 : j);
562 }
563
564 // Now assign number of islands found
565 fNumIslands = n;
566
567 // return number of island
568 return fNumIslands;
569}
570
571// --------------------------------------------------------------------------
572//
573// Returns, depending on the type flag:
574//
575// 0: Number of Photons*PixRatio
576// 1: Error*sqrt(PixRatio)
577// 2: Cleaning level = Num Photons*sqrt(PixRatio)/Error
578// 3: Number of Photons
579// 4: Error
580// 5: Island index
581//
582Bool_t MCerPhotEvt::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
583{
584 MCerPhotPix *pix = GetPixById(idx);
585
586 if (!pix || !pix->IsPixelUsed())
587 return kFALSE;
588
589 const Double_t ratio = cam.GetPixRatio(idx);
590
591 switch (type)
592 {
593 case 1:
594 val = pix->GetErrorPhot()*TMath::Sqrt(ratio);
595 return kTRUE;
596 case 2:
597 if (pix->GetErrorPhot()<=0)
598 return kFALSE;
599 val = pix->GetNumPhotons()*TMath::Sqrt(ratio)/pix->GetErrorPhot();
600 return kTRUE;
601 case 3:
602 val = pix->GetNumPhotons();
603 break;
604 case 4:
605 val = pix->GetErrorPhot();
606 break;
607 case 5:
608 val = pix->GetIdxIsland();
609 break;
610 default:
611 val = pix->GetNumPhotons()*ratio;
612 return kTRUE;
613 }
614 return kTRUE;
615}
616
617void MCerPhotEvt::DrawPixelContent(Int_t num) const
618{
619 *fLog << warn << "MCerPhotEvt::DrawPixelContent - not available." << endl;
620}
621
622TObject *MCerPhotEvtIter::Next()
623{
624 if (!fUsedOnly)
625 return TObjArrayIter::Next();
626
627 MCerPhotPix *pix;
628 while ((pix = (MCerPhotPix*)TObjArrayIter::Next()))
629 if (pix->IsPixelUsed())
630 return pix;
631 return pix;
632}
Note: See TracBrowser for help on using the repository browser.