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

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