source: trunk/MagicSoft/Mars/mtemp/mifae/library/MIslandsCalc.cc@ 5379

Last change on this file since 5379 was 5379, checked in by aliu, 20 years ago
*** empty log message ***
File size: 18.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): Ester Aliu, 2/2004 <aliu@ifae.es>
19|
20! Last Update: 7/2004
21!
22!
23! Copyright: MAGIC Software Development, 2000-2004
24!
25!
26\* ======================================================================== */
27
28/////////////////////////////////////////////////////////////////////////////
29//
30// MIslandsCalc
31//
32// The Island Calc task calculates some islands parameters for each
33// of the events such as:
34//
35// - fPixNum // number of pixels in the island
36// - fSigToNoise // signal to noise of the island
37// - fTimeSpread // mean arrival time spread of the island
38// - fMeanX // mean X position of the island
39// - fMeanY // mean Y position of the island
40// - fDist // dist between an island and the continent
41// - fLength // major axis of the larger island ellipse
42// - fWidth // minor axis of the larger island ellipse
43// - fDistL // dist divided by lenght of the larger island
44// - fDistW // dist divided by width of the larger island
45// - fDistS // dist divided by size of the larger island
46//
47// - fPixList // list of pixels in the island (TArrayI)
48// - fPeakPulse // mean arrival time of the pixels in the island (TArrayF)
49//
50// Input Containers:
51// MGeomCam
52// MCerPhotEvt
53// MPedestalCam
54// MArrivalTimeCam
55//
56// Output Containers:
57// MIslands
58// MImgIsland
59//
60/////////////////////////////////////////////////////////////////////////////
61#include "MIslandsCalc.h"
62
63#include <stdlib.h> // atof
64#include <fstream> // ofstream, SavePrimitive
65
66#include "MLog.h"
67#include "MLogManip.h"
68
69#include "MIslands.h"
70#include "MImgIsland.h"
71
72#include "MParList.h"
73
74#include "MGeomPix.h"
75#include "MGeomCam.h"
76
77#include "MCerPhotPix.h"
78#include "MCerPhotEvt.h"
79
80#include "MPedestalCam.h"
81#include "MPedestalPix.h"
82
83#include "MArrivalTimeCam.h"
84#include "MArrivalTimePix.h"
85
86ClassImp(MIslandsCalc);
87
88
89using namespace std;
90
91// --------------------------------------------------------------------------
92//
93// Default constructor.
94//
95MIslandsCalc::MIslandsCalc(const char* name, const char* title)
96 : fIsl(NULL)
97{
98 fName = name ? name : "MIslandsCalc";
99 fTitle = title ? title : "Calculate island parameters";
100}
101
102
103// --------------------------------------------------------------------------
104Int_t MIslandsCalc::PreProcess (MParList *pList)
105{
106 fCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam"));
107 if (!fCam)
108 {
109 *fLog << dbginf << "MGeomCam not found (no geometry information available)... aborting." << endl;
110 return kFALSE;
111 }
112
113 fEvt = (MCerPhotEvt*)pList->FindObject(AddSerialNumber("MCerPhotEvt"));
114 if (!fEvt)
115 {
116 *fLog << dbginf << "MCerPhotEvt not found... aborting." << endl;
117 return kFALSE;
118 }
119
120 fPed = (MPedestalCam*)pList->FindObject(AddSerialNumber("MPedestalCam"));
121 if (!fPed)
122 {
123 *fLog << dbginf << "MPedestalCam not found... aborting." << endl;
124 return kFALSE;
125 }
126
127 fTime = (MArrivalTimeCam*)pList->FindObject(AddSerialNumber("MArrivalTimeCam"));
128 if (!fTime)
129 {
130 *fLog << dbginf << "MArrivalTimeCam not found... aborting." << endl;
131 return kFALSE;
132 }
133
134 if (strlen(fIslName) > 0)
135 {
136 fIsl = (MIslands*)pList->FindCreateObj("MIslands", AddSerialNumber(fIslName));
137 }
138 else
139 {
140 fIsl = (MIslands*)pList->FindCreateObj(AddSerialNumber("MIslands"));
141 }
142 if (!fIsl)
143 return kFALSE;
144
145 return kTRUE;
146}
147
148
149Int_t MIslandsCalc::Process(){
150
151 fIsl->GetList()->Delete();
152 IslandPar();
153
154 return kTRUE;
155}
156
157
158Int_t MIslandsCalc::IslandPar(){
159
160 //calculates all the island parameters
161
162 const Int_t nPix=fCam->GetNumPixels();
163 const Int_t nVect=50;
164 Int_t numisl;
165
166 Int_t** vect;
167 vect = new Int_t*[nVect];
168 for(Int_t i=0;i<nVect;i++)
169 vect[i]= new Int_t[nPix];
170
171 Int_t* num;
172 num = new Int_t[nVect];
173
174 if (fIslandAlgorithm == 1)
175 Calc1(numisl,nVect,nPix,vect,num);
176 if (fIslandAlgorithm == 2)
177 Calc2(numisl,nVect,nPix,vect,num);
178
179 //set the number of islands in one event
180 fIsl->SetIslNum(numisl);
181
182 //cout << "code numisl " << numisl << endl;
183 //examine each island...
184
185 Float_t noise;
186 Float_t signal;
187
188 Int_t PixelNumIsl[numisl];
189 Float_t SigToNoise[numisl];
190 Float_t time[nPix];
191 Float_t timeVariance[numisl];
192 Float_t meanX[numisl];
193 Float_t meanY[numisl];
194 Float_t dist[numisl];
195 Float_t distL[numisl];
196 Float_t distW[numisl];
197 Float_t distS[numisl];
198
199 Float_t size[numisl], sizeLargeIsl, length, width, distance, alpha, alphaW, sizetot;
200
201 Float_t X = 0;
202 Float_t Y = 0;
203 sizeLargeIsl = 0;
204 alphaW = 0;
205 sizetot = 0;
206
207 for(Int_t i = 1; i<=numisl ; i++)
208 {
209
210 MImgIsland *imgIsl = new MImgIsland;
211
212 imgIsl->InitSize(num[i]);
213
214 Int_t n = 0;
215
216 Float_t MIN = 10000.;
217 Float_t MAX = 0.;
218
219 signal = 0;
220 noise = 0;
221
222 size[i-1] = 0;
223 meanX[i-1] = 0;
224 meanY[i-1] = 0;
225 dist[i-1] = 0;
226
227 PixelNumIsl[i-1] = 0;
228 timeVariance[i-1] = 0;
229
230
231 for(Int_t idx=0 ; idx<nPix ; idx++)
232 {
233 MCerPhotPix *pix = fEvt->GetPixById(idx);
234 if(!pix) continue;
235 const MGeomPix &gpix2 = (*fCam)[pix->GetPixId()];
236 const MPedestalPix &ped = (*fPed)[idx];
237 const MArrivalTimePix &timepix = (*fTime)[idx];
238 const Float_t nphot = pix->GetNumPhotons();
239
240 if (vect[i][idx]==1){
241
242 PixelNumIsl[i-1]++;
243 signal += nphot * (fCam->GetPixRatio(idx));
244 noise += pow(ped.GetPedestalRms(),2);
245
246 size[i-1] += nphot;
247 if (i == 1)
248 sizeLargeIsl += nphot;
249
250 meanX[i-1] += nphot * gpix2.GetX();
251 meanY[i-1] += nphot * gpix2.GetY();
252
253 time[i-1] = timepix.IsLoGainUsed() ? timepix.GetArrivalTimeLoGain() : timepix.GetArrivalTimeHiGain();
254
255 imgIsl->SetPixList(PixelNumIsl[i-1]-1,pix->GetPixId());
256 imgIsl->SetPeakPulse(PixelNumIsl[i-1]-1,time[i-1]);
257
258 //calculates the time spread only for core pixels
259 if (fEvt->IsPixelCore(idx)){
260
261 if (time[i-1] > MAX)
262 MAX = time[i-1];
263 if (time[i-1] < MIN)
264 MIN = time[i-1];
265
266 }
267
268 n++;
269 }
270 }
271
272 meanX[i-1] /= size[i-1];
273 meanY[i-1] /= size[i-1];
274
275
276 if (i == 1){
277 X = meanX[i-1];
278 Y = meanY[i-1];
279 }
280
281 dist[i-1] = TMath::Power(meanX[i-1]-X,2) + TMath::Power(meanY[i-1]-Y,2);
282 dist[i-1] = TMath::Sqrt(dist[i-1]);
283
284 timeVariance[i-1] = MAX-MIN;
285
286 //noise = 0, in the case of MC w/o noise
287 if (noise == 0) noise = 1;
288
289 SigToNoise[i-1]= (Float_t)signal/(Float_t)sqrt(noise);
290
291 imgIsl->SetPixNum(PixelNumIsl[i-1]);
292 imgIsl->SetSigToNoise(SigToNoise[i-1]);
293 imgIsl->SetTimeSpread(timeVariance[i-1]);
294 imgIsl->SetMeanX(meanX[i-1]);
295 imgIsl->SetMeanY(meanY[i-1]);
296 imgIsl->SetDist(dist[i-1]);
297 imgIsl->SetSizeIsl(size[i-1]);
298
299 fIsl->GetList()->Add(imgIsl);
300
301 }
302
303
304 //Length and Width of the larger island according the definition of the hillas parameters
305
306 // calculate 2nd moments
307 // ---------------------
308 Double_t corrxx=0; // [m^2]
309 Double_t corrxy=0; // [m^2]
310 Double_t corryy=0; // [m^2]
311
312 for(Int_t idx=0 ; idx<nPix ; idx++)
313 {
314 MCerPhotPix *pix = fEvt->GetPixById(idx);
315 if(!pix) continue;
316 const MGeomPix &gpix3 = (*fCam)[pix->GetPixId()];
317 const Float_t nphot = pix->GetNumPhotons();
318
319 // if (pix == NULL) break;
320
321 if (vect[1][idx]==1){
322
323 const Float_t dx = gpix3.GetX() - X; // [mm]
324 const Float_t dy = gpix3.GetY() - Y; // [mm]
325
326
327 corrxx += nphot * dx*dx; // [mm^2]
328 corrxy += nphot * dx*dy; // [mm^2]
329 corryy += nphot * dy*dy; // [mm^2]
330
331 }
332 }
333
334
335 // calculate the hillas parameters Width and Length
336
337 MImgIsland *imgIsl = new MImgIsland;
338 TIter Next(fIsl->GetList());
339 //Next.Reset();
340
341 Int_t i = 1;
342 while ((imgIsl=(MImgIsland*)Next())) {
343
344 const Double_t d0 = corryy - corrxx;
345 const Double_t d1 = corrxy*2;
346 const Double_t d2 = d0 + TMath::Sqrt(d0*d0 + d1*d1);
347 const Double_t tand = d2 / d1;
348 const Double_t tand2 = tand*tand;
349
350 const Double_t s2 = tand2+1;
351 const Double_t s = TMath::Sqrt(s2);
352
353 const Double_t CosDelta = 1.0/s; // need these in derived classes
354 const Double_t SinDelta = tand/s; // like MHillasExt
355
356 const Double_t axis1 = (tand2*corryy + d2 + corrxx)/s2/size[i-1];
357 const Double_t axis2 = (tand2*corrxx - d2 + corryy)/s2/size[i-1];
358
359 //
360 // fLength^2 is the second moment along the major axis of the ellipse
361 // fWidth^2 is the second moment along the minor axis of the ellipse
362 //
363 // From the algorithm we get: fWidth <= fLength is always true
364 //
365 // very small numbers can get negative by rounding
366 //
367 length = axis1<0 ? 0 : TMath::Sqrt(axis1); // [mm]
368 width = axis2<0 ? 0 : TMath::Sqrt(axis2); // [mm]
369
370
371 // alpha calculation
372
373 const Double_t mx = imgIsl->GetMeanX(); // [mm]
374 const Double_t my = imgIsl->GetMeanY(); // [mm]
375
376 //FIXME: xpos, ypos from MSrcPos
377 const Double_t xpos = 0.;
378 const Double_t ypos = 0.;
379
380 const Double_t sx = mx - xpos; // [mm]
381 const Double_t sy = my - ypos; // [mm]
382
383 const Double_t sd = SinDelta; // [1]
384 const Double_t cd = CosDelta; // [1]
385
386 //
387 // Distance from source position to center of ellipse.
388 // If the distance is 0 distance, Alpha is not specified.
389 // The calculation has failed and returnes kFALSE.
390 //
391 distance = TMath::Sqrt(sx*sx + sy*sy); // [mm]
392 if (distance==0)
393 return 1;
394
395 //
396 // Calculate Alpha and Cosda = cos(d,a)
397 // The sign of Cosda will be used for quantities containing
398 // a head-tail information
399 //
400 // *OLD* const Double_t arg = (sy-tand*sx) / (dist*sqrt(tand*tand+1));
401 // *OLD* fAlpha = asin(arg)*kRad2Deg;
402 //
403 const Double_t arg2 = cd*sx + sd*sy; // [mm]
404 if (arg2==0)
405 return 2;
406
407 const Double_t arg1 = cd*sy - sd*sx; // [mm]
408
409 //
410 // Due to numerical uncertanties in the calculation of the
411 // square root (dist) and arg1 it can happen (in less than 1e-5 cases)
412 // that the absolute value of arg exceeds 1. Because this uncertainty
413 // results in an Delta Alpha which is still less than 1e-3 we don't care
414 // about this uncertainty in general and simply set values which exceed
415 // to 1 saving its sign.
416 //
417 const Double_t arg = arg1/distance;
418 alpha = TMath::Abs(arg)>1 ? TMath::Sign(90., arg) : TMath::ASin(arg)*TMath::RadToDeg(); // [deg]
419
420 alphaW += alpha*size[i-1];
421 sizetot += size[i-1];
422
423 ////////////////////////////////////////
424
425 distL[i-1]=dist[i-1]/length;
426 distW[i-1]=dist[i-1]/width;
427 distS[i-1]= dist[i-1]/size[i-1];
428
429 imgIsl->SetLength(length);
430 imgIsl->SetWidth(width);
431
432 imgIsl->SetDistL(distL[i-1]);
433 imgIsl->SetDistW(distW[i-1]);
434 imgIsl->SetDistS(distS[i-1]);
435
436 imgIsl->SetAlpha(alpha);
437 i++;
438 }
439
440
441 fIsl->SetAlphaW(alphaW/sizetot);
442 //fIsl->SetReadyToSave();
443
444 for (Int_t i = 0; i< nVect; i++)
445 delete [] vect[i];
446
447 delete vect;
448
449 return kTRUE;
450}
451
452//------------------------------------------------------------------------------------------
453void MIslandsCalc::Calc1(Int_t& numisl, const Int_t nv, const Int_t npix, Int_t** vect, Int_t* num){
454
455
456 /////////////////////////////
457 //
458 // ALGORITHM # 1
459 // counts the number of islands as you can see in
460 // the event display after doing the std image cleaning
461 //
462 /////////////////////////////
463
464 Int_t sflag;
465 Int_t control = 0;
466
467 Int_t nvect = 0;
468
469 numisl = 0;
470
471 Int_t zeros[nv];
472
473 for(Int_t m = 0; m < nv ; m++)
474 for(Int_t n = 0; n < npix ; n++)
475 vect[m][n] = 0;
476
477 for(Int_t n = 0; n < nv ; n++)
478 zeros[n] = 0;
479
480 //cout << "new event" <<endl;
481 MCerPhotPix *pix;
482
483 //loop over all pixels
484 MCerPhotEvtIter Next(fEvt, kFALSE);
485
486 while ((pix=static_cast<MCerPhotPix*>(Next())))
487 {
488 const Int_t idx = pix->GetPixId();
489
490 const MGeomPix &gpix = (*fCam)[idx];
491 const Int_t nnmax = gpix.GetNumNeighbors();
492
493 if( fEvt->IsPixelUsed(idx))
494 {
495 //cout << idx <<endl;
496 sflag = 0;
497
498 for(Int_t j=0; j < nnmax ; j++)
499 {
500 const Int_t idx2 = gpix.GetNeighbor(j);
501
502 if (idx2 < idx)
503 {
504 for(Int_t k = 1; k <= nvect; k++)
505 {
506 if (vect[k][idx2] == 1)
507 {
508 sflag = 1;
509 vect[k][idx] = 1;
510 }
511 }
512 }
513 }
514
515 if (sflag == 0)
516 {
517 nvect++;
518 vect[nvect][idx] = 1;
519 }
520
521 }
522 }
523
524 numisl = nvect;
525
526
527 // Repeated Chain Corrections
528
529 Int_t jmin = 0;
530
531 for(Int_t i = 1; i <= nvect; i++){
532 control=0;
533 for(Int_t j = i+1; j <= nvect; j++){
534 control = 0;
535 for(Int_t k = 0; k < npix; k++){
536 if (vect[i][k] == 1 && vect[j][k] == 1){
537 control = 1;
538 k=npix;
539 }
540 }
541 if (control == 1){
542 for(Int_t k = 0; k < npix; k++){
543 if(vect[j][k] == 1) vect[i][k] = 1;
544 vect[j][k] = 0;
545 zeros[j] = 1;
546 }
547 numisl = numisl-1;
548 }
549 }
550
551 for(Int_t j = 1; j <= i-1; j++){
552 for(Int_t k = 0; k < npix; k++){
553 if (vect[i][k] == 1 && vect[j][k] == 1){
554 control = 2;
555 jmin=j;
556 k=npix;
557 j=i;
558 }
559 }
560
561 if (control == 2){
562 for (Int_t k = 0; k < npix; k++){
563 if(vect[i][k]==1) vect[jmin][k]=1;
564 vect[i][k] = 0;
565 zeros[i] = 1;
566 }
567 numisl = numisl-1;
568 }
569 }
570 }
571
572 Int_t pixMAX = 0;
573 Int_t idMAX = 1;
574 Int_t l = 1;
575 Int_t numpixels;
576
577 for(Int_t i = 1; i<= nvect ; i++)
578 {
579 numpixels = 0;
580
581 if (zeros[i] == 0)
582 {
583 for(Int_t k=0; k<npix; k++)
584 {
585 vect[l][k] = vect[i][k];
586 if (vect[l][k] == 1)
587 numpixels++;
588 }
589
590 num[l] = numpixels;
591
592 if (numpixels>pixMAX)
593 {
594 pixMAX = numpixels;
595 idMAX = l;
596 }
597 l++;
598 }
599 }
600
601
602 //the larger island will correspond to the 1st component of the vector
603
604 num[nvect+1] = num[1];
605 num[1] = num[idMAX];
606 num[idMAX] = num[nvect+1];
607
608
609 for(Int_t k = 0; k<npix; k++)
610 {
611 vect[nvect+1][k] = vect[1][k];
612 vect[1][k] = vect[idMAX][k];
613 vect[idMAX][k] = vect[nvect+1][k];
614 }
615}
616
617//------------------------------------------------------------------------------------------
618
619void MIslandsCalc::Calc2(Int_t& numisl, const Int_t nv, const Int_t npix, Int_t** vect, Int_t* num){
620
621
622 /////////////////////////////
623 //
624 // ALGORITHM # 2
625 // counts the number of islands considering as the same
626 // islands the ones separated for 2 or less pixels
627 //
628 /////////////////////////////
629
630 Int_t sflag;
631 Int_t control;
632
633 Int_t nvect = 0;
634 numisl = 0;
635
636 Int_t zeros[nv];
637
638 Int_t kk[npix];
639
640 for(Int_t m = 0; m < nv ; m++)
641 for(Int_t n = 0; n < npix ; n++)
642 vect[m][n] = 0;
643
644 for(Int_t n = 0; n < nv ; n++)
645 zeros[n] = 0;
646
647 for(Int_t n = 0; n < npix ; n++)
648 kk[n] = 0;
649
650 MCerPhotPix *pix;
651
652 //1st loop over all pixels
653 MCerPhotEvtIter Next0(fEvt, kFALSE);
654
655 while ((pix=static_cast<MCerPhotPix*>(Next0())))
656 {
657 const Int_t idx = pix->GetPixId();
658
659 const MGeomPix &gpix = (*fCam)[idx];
660 const Int_t nnmax = gpix.GetNumNeighbors();
661
662 if( fEvt->IsPixelUsed(idx))
663 {
664 kk[idx] = 1 ;
665 for(Int_t j=0; j< nnmax; j++)
666 {
667 kk[gpix.GetNeighbor(j)] = 1;
668 }
669 }
670
671 }
672
673 //2nd loop over all pixels
674 MCerPhotEvtIter Next(fEvt, kFALSE);
675
676 while ((pix=static_cast<MCerPhotPix*>(Next())))
677 {
678 const Int_t idx = pix->GetPixId();
679
680 const MGeomPix &gpix = (*fCam)[idx];
681 const Int_t nnmax = gpix.GetNumNeighbors();
682
683 if ( kk[idx] > 0)
684 {
685 sflag = 0;
686
687 for(Int_t j=0; j < nnmax ; j++)
688 {
689 const Int_t idx2 = gpix.GetNeighbor(j);
690
691 if (idx2 < idx)
692 {
693 for(Int_t k = 1; k <= nvect; k++)
694 {
695 if (vect[k][idx2] == 1)
696 {
697 sflag = 1;
698 vect[k][idx] = 1;
699 }
700 }
701 }
702 }
703
704 if (sflag == 0)
705 {
706 nvect++;
707 vect[nvect][idx] = 1;
708 }
709
710 }
711 }
712
713 numisl = nvect;
714
715
716 // Repeated Chain Corrections
717
718 Int_t ii, jj;
719
720 for(Int_t i = 1; i <= nvect; i++) {
721 for(Int_t j = 1; j <= nvect; j++) {
722 if (i!=j && zeros[j]!=1){
723 control = 0;
724 for(Int_t k = 0; k < npix; k++) {
725 if (vect[i][k] == 1 && vect[j][k] == 1) {
726 control = 1;
727 break;
728 }
729 }
730 if(i<j) {
731 ii=i;
732 jj=j;
733 }
734 else{
735 ii=j;
736 jj=i;
737 }
738 if (control == 1) {
739 for(Int_t k = 0; k < npix; k++) {
740 if(vect[jj][k] == 1) vect[ii][k] = 1;
741 vect[jj][k] = 0;
742 zeros[jj] = 1;
743 }
744 numisl = numisl-1;
745 }
746 }
747 }
748 }
749
750 Int_t l = 1;
751 Int_t numpixels;
752 Int_t pixMAX = 0;
753 Int_t idMAX = 1;
754
755 for(Int_t i = 1; i<= nvect ; i++)
756 {
757 numpixels = 0;
758
759 if (zeros[i] == 0)
760 {
761 for(Int_t k = 0; k<npix; k++)
762 {
763 vect[l][k] = vect[i][k];
764 if (vect[l][k] == 1)
765 numpixels++;
766 }
767
768 num[l] = numpixels;
769
770 if (numpixels>pixMAX)
771 {
772 pixMAX = numpixels;
773 idMAX = l;
774 }
775 l++;
776 }
777 }
778
779
780 //the larger island will correspond to the 1st component of the vector
781
782 num[nvect +1] = num[1];
783 num[1] = num[idMAX];
784 num[idMAX]=num[nvect+1];
785
786 for(Int_t k = 0; k<npix; k++)
787 {
788 vect[nvect+1][k] = vect[1][k];
789 vect[1][k] = vect[idMAX][k];
790 vect[idMAX][k] = vect[nvect+1][k];
791 }
792
793}
794
Note: See TracBrowser for help on using the repository browser.