/* ======================================================================== *\ ! ! * ! * 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): Christoph Kolodziejski, 11/2004 ! Author(s): Thomas Bretz, 11/2004 ! ! Copyright: MAGIC Software Development, 2004 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MHexagonalFTCalc // // Task to perform forward transformation, cuts in fourier space and // backward tranformation. // // If you don't want to copy the rsult back to any MSignalCam call // SetNameSignalCamOut() // // Currently - this will change in the future! - there are two output // containers: // - MHexagonalFreqSpace1 // real part: input values in triangle space // imaginary part: output values in triangle space // // - MHexagonalFreqSpace2 // real part: real part of frequency space // imaginary part: imaginary part of frequency space // // To be done: // Flags to perform forward/backward trafo only to be able to cut outside! // ////////////////////////////////////////////////////////////////////////////// #include "MHexagonalFTCalc.h" #include #include "MLog.h" #include "MLogManip.h" #include "MParList.h" #include "MGeomCam.h" #include "MGeom.h" #include "MSignalCam.h" #include "MSignalPix.h" #include "MHexagonFreqSpace.h" #include "MArrayD.h" ClassImp(MHexagonalFTCalc); using namespace std; const char *MHexagonalFTCalc::fgNameGeomCam = "MGeomCam"; const char *MHexagonalFTCalc::fgNameSignalCamIn = "MSignalCam"; const char *MHexagonalFTCalc::fgNameSignalCamOut = "MSignalCam"; // --------------------------------------------------------------------------- // // Default Constructor - empty. Initialize // fMaxAmplitude = 0.08 // fMaxRowFraction = 0.75 // MHexagonalFTCalc::MHexagonalFTCalc(const char *name, const char *title) : fNameGeomCam(fgNameGeomCam), fNameSignalCamIn(fgNameSignalCamIn), fNameSignalCamOut(fgNameSignalCamOut), fEvtIn(0), fEvtOut(0), fMaxAmplitude(0.08), fMaxRowFraction(0.75), fSkipBwdTrafo(kFALSE) { fName = name ? name : "MHexagonalFTCalc"; fTitle = title ? title : "Task to calculate Hexagonal Fourier Transformation"; } // --------------------------------------------------------------------------- // // Search for all necessary containers. // // Do a forward transformation for a flat camera, eg: // // 0 0 1 0 0 // 0 1 1 0 // 1 1 1 // 1 1 // 1 // // The result (fOffset) is treated as a offset in the fourier space comming // from the fact that the camera doesn't extend the whole triangle. // // Before cutting in the fourier space it is substracted. After cutting it // is added again. Scaling is done by the constant-frequency-pixel (index 0) // // Create the LookUpTable which tells you which fourier space (triangle) // pixel index corresponds to which camera pixel index. // Int_t MHexagonalFTCalc::PreProcess(MParList *plist) { fEvtIn = (MSignalCam*)plist->FindObject(fNameSignalCamIn, "MSignalCam"); if (!fEvtIn) { *fLog << err << fNameSignalCamIn << " [MSignalCam] not found... abort." << endl; return kFALSE; } fEvtOut=0; if (!fNameSignalCamOut.IsNull()) { fEvtOut = (MSignalCam*)plist->FindCreateObj(fNameSignalCamOut, "MSignalCam"); if (!fEvtOut) return kFALSE; } fFreq1 = (MHexagonFreqSpace*)plist->FindCreateObj("MHexagonFreqSpace","MHexagonFreqSpace1"); if (!fFreq1) return kFALSE; fFreq2 = (MHexagonFreqSpace*)plist->FindCreateObj("MHexagonFreqSpace","MHexagonFreqSpace2"); if (!fFreq2) return kFALSE; MGeomCam *geom = (MGeomCam*)plist->FindObject(fNameGeomCam, "MGeomCam"); if (!geom) { *fLog << err << fNameGeomCam << " [MGeomCam] not found... abort." << endl; return kFALSE; } // Number of Rings (r) ---> Number of Pixels (p) // p = 3*r*(r-1)+1 // Number of Pixels (p) ---> Number of Rings (r) // p = (sqrt(9+12*(p-1))+3)/6 // Number of pixels at one border == number of rings (r) // Row of border == number of rings (r) // Number of rows to get a triangle: 3r-2 // One additional line on all three sides, number of rows: 3r-2+3 = 3r+1 Int_t num = 0; for (UInt_t i=0; iGetNumPixels(); i++) if ((*geom)[i].GetAidx()==0) num++; cout << "Number of pixels with Area Idx==0: " << num << endl; const Int_t numrows = (Int_t)((sqrt(9.+12.*(num-1))+3)/2+1); //61;//34; fHFT.Prepare(numrows); cout << "Number of rows: " << numrows << endl; const Int_t lim = fHFT.GetNumKnots(); fOffset.Set(lim); fOffset.Reset(); //fMap.Set(lim); //for (int i=0; iGetPixelIdxXY(x, y); if (idx<0) continue; if ((*geom)[idx].GetAidx()==0) { //fMap[idx] = i; fOffset[i] = 1; } } fFreq1->Set(MArrayD(lim), MArrayD(lim)); fFreq2->Set(MArrayD(lim), MArrayD(lim)); // Calculate fourier tranformation of a constant field for all // 'valid' pixels MArrayD freqre; MArrayD freqim; fHFT.TransformFastFWD(fOffset, freqre, freqim); fOffset = freqre; return kTRUE; } // --------------------------------------------------------------------------- // // Do cuts in frequence space (fOffset already sustracted), eg: // fMaxRowFraction = 0.5 // fMaxAmplitude = 0.3 // // 0.1 0.2 0.1 0.3 0.4 0 0 0 0 0 // 0.4 0.3 0.2 0.1 0 0 0 0 // 0.6 0.4 0.8 -----> 0.6 0 0.8 // 0.4 0.9 0 0.9 // 0 0 // // The result (fOffset) is treated as a offset in the fourier space comming // from the fact that the camera doesn't extend the whole triangle. // // Before cutting in the fourier space it is substracted. After cutting it // is added again. Scaling is done by the constant-frequency-pixel (index 0) // void MHexagonalFTCalc::CleanFreqSpace(MArrayD &outre, MArrayD &outim) { // Do cut in frequency space for (unsigned int i=0; i(Int_t)fHFT.GetNumRows()*fMaxRowFraction) outre[i]=outim[i]=0; if (TMath::Hypot(outre[i], outim[i])GetNumPixels(); for (UInt_t idx=0; idxGetPixId(); //if (fMap[idx]>=0) re[idx] = (*fEvtIn)[idx].GetNumPhotons(); } MArrayD freqre, freqim; // Do forward transformation fHFT.TransformFastFWD(re, freqre, freqim); // Substract the 'structure of the hexagon' Double_t scale = TMath::Abs(freqre[0]/fOffset[0]); for (int i=0; iSet(freqre, freqim); // ---------------------------------------------------- // Do we need a backward transformation? // ---------------------------------------------------- if (fSkipBwdTrafo) return kTRUE; // Clean image in frequency space CleanFreqSpace(freqre, freqim); // Add the 'structure of the hexagon' for (int i=0; iSet(re, out); // ---------------------------------------------------- // Do we have to copy the result back into MSignalCam? // ---------------------------------------------------- if (!fEvtOut) return kTRUE; fEvtOut->InitSize(lim); // necessary? for (int i=0; i=0) fEvtOut->AddPixel(i, out[i]); } //fEvtOut->FixSize(); fEvtOut->SetReadyToSave(); return kTRUE; }