/* ======================================================================== *\ ! ! * ! * This file is part of MARS, the MAGIC Analysis and Reconstruction ! * Software. It is distributed to you in the hope that it can be a useful ! * and timesaving tool in analysing Data of imaging Cerenkov telescopes. ! * It is distributed WITHOUT ANY WARRANTY. ! * ! * Permission to use, copy, modify and distribute this software and its ! * documentation for any purpose is hereby granted without fee, ! * provided that the above copyright notice appear in all copies and ! * that both that copyright notice and this permission notice appear ! * in supporting documentation. It is provided "as is" without express ! * or implied warranty. ! * ! ! ! Author(s): Ester Aliu, 2/2004 | ! Last Update: 7/2004 ! ! ! Copyright: MAGIC Software Development, 2000-2004 ! ! \* ======================================================================== */ ///////////////////////////////////////////////////////////////////////////// // // MIslandCalc // // The Island Calc task calculates the some islands parameters for each // of the events such as: // // - fIslNum // number of islands // - fIslId[577] // island Id // - fPixNum[numisl] // number of pixels in the island // - fSigToNoise[numisl] // signal to noise of the island // - ftime[numisl][577] // mean of the arrival time // - fTimeSpread[numisl] // mean arrival time spread of the island // - fMeanX[numisl] // mean X position of the island // - fMeanY[numisl] // mean Y position of the island // - fDist[numisl] // dist between an island and the continent // - fLength // major axis of the larger island ellipse // - fWidth // minor axis of the larger island ellipse // - fDistL[numisl] // dist divided by lenght of the larger island // - fDistW[numisl] // dist divided by width of the larger island // // Input Containers: // MGeomCam // MCerPhotEvt // MPedestalCam // MArrivalTimeCam // // Output Containers: // MIslands // ///////////////////////////////////////////////////////////////////////////// #include "MIslandCalc.h" #include // atof #include // ofstream, SavePrimitive #include "MLog.h" #include "MLogManip.h" #include "MIslands.h" #include "MParList.h" #include "MGeomPix.h" #include "MGeomCam.h" #include "MCerPhotPix.h" #include "MCerPhotEvt.h" #include "MPedestalCam.h" #include "MPedestalPix.h" #include "MArrivalTimeCam.h" #include "MArrivalTimePix.h" ClassImp(MIslandCalc); using namespace std; // -------------------------------------------------------------------------- // // Default constructor. // MIslandCalc::MIslandCalc(const char* name, const char* title) : fIsl(NULL) { fName = name ? name : "MIslandCalc"; fTitle = title ? title : "Calculate island parameters"; } // -------------------------------------------------------------------------- Int_t MIslandCalc::PreProcess (MParList *pList) { fCam = (MGeomCam*)pList->FindObject(AddSerialNumber("MGeomCam")); if (!fCam) { *fLog << dbginf << "MGeomCam not found (no geometry information available)... aborting." << endl; return kFALSE; } fEvt = (MCerPhotEvt*)pList->FindObject(AddSerialNumber("MCerPhotEvt")); if (!fEvt) { *fLog << dbginf << "MCerPhotEvt not found... aborting." << endl; return kFALSE; } fPed = (MPedestalCam*)pList->FindObject(AddSerialNumber("MPedestalCam")); if (!fPed) { *fLog << dbginf << "MPedestalCam not found... aborting." << endl; return kFALSE; } fTime = (MArrivalTimeCam*)pList->FindObject(AddSerialNumber("MArrivalTimeCam")); if (!fTime) { *fLog << dbginf << "MArrivalTimeCam not found... aborting." << endl; return kFALSE; } if (strlen(fIslName) > 0) { fIsl = (MIslands*)pList->FindCreateObj("MIslands", AddSerialNumber(fIslName)); //cout << "kk1" << endl; } else { fIsl = (MIslands*)pList->FindCreateObj(AddSerialNumber("MIslands")); //cout << "kk2" << endl; } if (!fIsl) return kFALSE; return kTRUE; } Int_t MIslandCalc::Process(){ IslandPar(); return kTRUE; } Int_t MIslandCalc::IslandPar(){ //calculates all the island parameters const Int_t nPix=577; const Int_t nVect=50; Int_t numisl; Int_t** vect; vect = new Int_t*[nVect]; for(Int_t i=0;iSetIslNum(numisl); //examine each island... Float_t noise; Float_t signal; /* Float_t** ftime; ftime = new Float_t*[numisl]; Int_t pixNumIsl = 0; for(Int_t i=0;iSetIslNum(0); for(Int_t i = 0; i<10 ;i++){ for(Int_t idx = 0; idxSetIslId(idx, -1); fIsl->SetArrivalTime(i, idx, -1 ); } } Float_t X = 0; Float_t Y = 0; sizeLargeIsl = 0; for(Int_t i = 1; i<=numisl ; i++) { Int_t n = 0; //Int_t ncore = 0; Float_t MIN = 10000.; Float_t MAX = 0.; signal = 0; noise = 0; size = 0; meanX[i-1] = 0; meanY[i-1] = 0; dist[i-1] = 0; fPixNum[i-1] = 0; timeVariance[i-1] = 0; for(Int_t idx=0 ; idxGetPixById(idx); if(!pix) continue; const MGeomPix &gpix2 = (*fCam)[pix->GetPixId()]; const MPedestalPix &ped = (*fPed)[idx]; const MArrivalTimePix &timepix = (*fTime)[idx]; const Float_t nphot = pix->GetNumPhotons(); // if (pix == NULL) break; if (vect[i][idx]==1){ fPixNum[i-1]++; signal += nphot * (fCam->GetPixRatio(idx)); noise += pow(ped.GetPedestalRms(),2); size += nphot; if (i == 1) sizeLargeIsl += nphot; meanX[i-1] += nphot * gpix2.GetX(); meanY[i-1] += nphot * gpix2.GetY(); time[i-1] = timepix.IsLoGainUsed() ? timepix.GetArrivalTimeLoGain() : timepix.GetArrivalTimeHiGain(); // ftime[i-1][n] = time[i-1]; // fIslId[i-1][n] = idx; //calculates the time spread only for core pixels if (fEvt->IsPixelCore(idx)){ if (time[i-1] > MAX) MAX = time[i-1]; if (time[i-1] < MIN) MIN = time[i-1]; // ncore++; } fIsl->SetIslId(idx, i-1); fIsl->SetArrivalTime(i-1, idx, time[n]); n++; } } meanX[i-1] /= size; meanY[i-1] /= size; if (i == 1){ X = meanX[i-1]; Y = meanY[i-1]; } dist[i-1] = TMath::Power(meanX[i-1]-X,2) + TMath::Power(meanY[i-1]-Y,2); dist[i-1] = TMath::Sqrt(dist[i-1]); timeVariance[i-1] = MAX-MIN; //noise = 0, in the case of MC w/o noise if (noise == 0) noise = 1; fSigToNoise[i-1]= (Float_t)signal/(Float_t)sqrt(noise); } //fIsl->SetIslId(fIslId); //fIsl->SetArrivalTime(ftime); fIsl->SetPixNum(fPixNum); fIsl->SetSigToNoise(fSigToNoise); fIsl->SetTimeSpread(timeVariance); fIsl->SetMeanX(meanX); fIsl->SetMeanY(meanY); fIsl->SetDist(dist); //Length and Width of the larger island according the definition of the hillas parameters // calculate 2nd moments // --------------------- Double_t corrxx=0; // [m^2] Double_t corrxy=0; // [m^2] Double_t corryy=0; // [m^2] for(Int_t idx=0 ; idxGetPixById(idx); if(!pix) continue; const MGeomPix &gpix3 = (*fCam)[pix->GetPixId()]; const Float_t nphot = pix->GetNumPhotons(); // if (pix == NULL) break; if (vect[1][idx]==1){ const Float_t dx = gpix3.GetX() - X; // [mm] const Float_t dy = gpix3.GetY() - Y; // [mm] corrxx += nphot * dx*dx; // [mm^2] corrxy += nphot * dx*dy; // [mm^2] corryy += nphot * dy*dy; // [mm^2] } } // calculate the hillas parameters Width and Length const Double_t d0 = corryy - corrxx; const Double_t d1 = corrxy*2; const Double_t d2 = d0 + TMath::Sqrt(d0*d0 + d1*d1); const Double_t tand = d2 / d1; const Double_t tand2 = tand*tand; const Double_t s2 = tand2+1; const Double_t axis1 = (tand2*corryy + d2 + corrxx)/s2/sizeLargeIsl; const Double_t axis2 = (tand2*corrxx - d2 + corryy)/s2/sizeLargeIsl; // // fLength^2 is the second moment along the major axis of the ellipse // fWidth^2 is the second moment along the minor axis of the ellipse // // From the algorithm we get: fWidth <= fLength is always true // // very small numbers can get negative by rounding // length = axis1<0 ? 0 : TMath::Sqrt(axis1); // [mm] width = axis2<0 ? 0 : TMath::Sqrt(axis2); // [mm] fIsl->SetLength(length); fIsl->SetWidth(width); // for(Int_t i = 1; i<=numisl ; i++){ // fIsl->SetDistL(fIsl->GetDist(i-1)/length, i-1); // fIsl->SetDistW(fIsl->GetDist(i-1)/width, i-1); // } for(Int_t i = 1; i<=numisl ; i++){ distL[i-1]=dist[i-1]/length; distW[i-1]=dist[i-1]/width; } fIsl->SetDistL(distL); fIsl->SetDistW(distW); fIsl->SetReadyToSave(); for (Int_t i = 0; i< nVect; i++) delete [] vect[i]; delete vect; return kTRUE; } //------------------------------------------------------------------------------------------ void MIslandCalc::Calc1(Int_t& numisl, const Int_t nv, const Int_t npix, Int_t** vect, Int_t* num){ ///////////////////////////// // // ALGORITHM # 1 // counts the number of islands as you can see in // the event display after doing the std image cleaning // ///////////////////////////// Int_t sflag; Int_t control; Int_t nvect = 0; numisl = 0; Int_t zeros[nv]; for(Int_t m = 0; m < nv ; m++) for(Int_t n = 0; n < npix ; n++) vect[m][n] = 0; for(Int_t n = 0; n < nv ; n++) zeros[n] = 0; //cout << "new event" <(Next()))) { const Int_t idx = pix->GetPixId(); const MGeomPix &gpix = (*fCam)[idx]; const Int_t nnmax = gpix.GetNumNeighbors(); if( fEvt->IsPixelUsed(idx)) { //cout << idx <pixMAX) { pixMAX = numpixels; idMAX = l; } l++; } num[i] = numpixels; } //the larger island will correspond to the 1st component of the vector num[nvect +1] = num[1]; num[1] = num[idMAX]; num[idMAX]=num[1]; for(Int_t k = 0; k(Next0()))) { const Int_t idx = pix->GetPixId(); const MGeomPix &gpix = (*fCam)[idx]; const Int_t nnmax = gpix.GetNumNeighbors(); if( fEvt->IsPixelUsed(idx)) { kk[idx] = 1 ; for(Int_t j=0; j< nnmax; j++) { kk[gpix.GetNeighbor(j)] = 1; } } } //2nd loop over all pixels MCerPhotEvtIter Next(fEvt, kFALSE); while ((pix=static_cast(Next()))) { const Int_t idx = pix->GetPixId(); const MGeomPix &gpix = (*fCam)[idx]; const Int_t nnmax = gpix.GetNumNeighbors(); if ( kk[idx] > 0) { sflag = 0; for(Int_t j=0; j < nnmax ; j++) { const Int_t idx2 = gpix.GetNeighbor(j); if (idx2 < idx) { for(Int_t k = 1; k <= nvect; k++) { if (vect[k][idx2] == 1) { sflag = 1; vect[k][idx] = 1; } } } } if (sflag == 0) { nvect++; vect[nvect][idx] = 1; } } } numisl = nvect; // Repeated Chain Corrections for(Int_t i = 1; i <= nvect; i++) { for(Int_t j = i+1; j <= nvect; j++) { control = 0; for(Int_t k = 0; k < npix; k++) { if (vect[i][k] == 1 && vect[j][k] == 1) { control = 1; break; } } if (control == 1) { for(Int_t k = 0; k < npix; k++) { if(vect[j][k] == 1) vect[i][k] = 1; vect[j][k] = 0; zeros[j] = 1; } numisl = numisl-1; } } } Int_t l = 1; Int_t numpixels; Int_t pixMAX = 0; Int_t idMAX = 1; for(Int_t i = 1; i<= nvect ; i++) { numpixels = 0; if (zeros[i] == 0) { for(Int_t k = 0; kpixMAX) { pixMAX = numpixels; idMAX = l; } l++; } num[i] = numpixels; } //the larger island will correspond to the 1st component of the vector num[nvect +1] = num[1]; num[1] = num[idMAX]; num[idMAX]=num[1]; for(Int_t k = 0; k