/* ======================================================================== *\ ! ! * ! * 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-2005 ! ! \* ======================================================================== */ ////////////////////////////////////////////////////////////////////////////// // // MHexagonalFT // // This is a class representating a (fast) fourier transformation explicitly // for hexagonal geometries as described in astro-ph/0409388. // // // WARNING: // ======== // Be carefull using the fast transformation (Prepare())! The precalculation // consumes a lot of memory. fPsi has the size of 2*n^4 (while n is the // number of rows in fourier space). For the enhanced MAGIC camery fPsi has // the size 27691682*sizeof(float) = 105.6MB (Std MAGIC: ~12MB) // // The runtime is more or less determined by the speed of accessing a // huge amount of memory (see above) sequentially. // // // Coordinate systems: // =================== // // original hexagonal structure enhanced hexagonal structure // ---------------------------- ---------------------------- // // structure // --------- // // h h h f f h h h f f // h h h h f h h h h f // h h h h h -----> h h h h h // h h h h h h h h // h h h h h h // f f // f // // numbering // --------- // d c b m n o p q r s // e 4 3 a g h i j k l // f 5 1 2 9 -----> b c d e f // g 6 7 8 7 8 9 a // h i j 4 5 6 // 2 3 // 1 // // In reality the fourier space looks like because of symmetries: // // real part imaginary part // --------- -------------- // m n o p o n m m n o 0 -o -n -m // g h i i h g g h i -i -h -g // b c d c b b c 0 -c -b // 7 8 8 7 7 8 -8 -7 // 4 5 4 4 0 -4 // 2 2 2 -2 // 1 0 // // column: GetK() row: GetM() // -------------- ----------- // 6 5 4 3 2 1 0 0 1 2 3 4 5 6 // 5 4 3 2 1 0 0 1 2 3 4 5 // 4 3 2 1 0 0 1 2 3 4 // 3 2 1 0 0 1 2 3 // 2 1 0 0 1 2 // 1 0 0 1 // 0 0 // // row: GetRow() (m+k) column: GetCol() (m-k) // ------------------- ---------------------- // 6 6 6 6 6 6 6 -6 -4 -2 0 2 4 6 // 5 5 5 5 5 5 -5 -3 -1 1 3 5 // 4 4 4 4 4 -4 -2 0 2 4 // 3 3 3 3 -3 -1 1 3 // 2 2 2 -2 0 2 // 1 1 -1 1 // 0 0 // // // The coordinates of the pixels in the triangle are: // // Double_t dx; // Distance of too pixels in x // Double_t dy; // Distance of to pixel rows in y // Int_t idx; // Index of pixel in triangle (see above) // // const Float_t x = dx*GetCol(idx); // const Float_t y = dy*Int_t(GetRow(idx)-2*GetNumRows()/3); // // You can use MGeomCam::GetPixelIdxXY(x, y) to get the corresponding index // in space space. // ////////////////////////////////////////////////////////////////////////////// #include "MHexagonalFT.h" #include #include "MLog.h" #include "MLogManip.h" #include "MArrayD.h" ClassImp(MHexagonalFT); using namespace std; // --------------------------------------------------------------------------- // // Default Constructor - empty // MHexagonalFT::MHexagonalFT() { } // --------------------------------------------------------------------------- // // Default Constructor - num is the number of lines the fourier space has. // It calls Prepare to fill the arrays with the necessary coefficients. // // Here are some simple rules to calculate parameters in a hexagonal space: // // 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 // MHexagonalFT::MHexagonalFT(Int_t num) { Prepare(num); } // --------------------------------------------------------------------------- // // Calculate the contents of: fM, fK, fP, fIdx and fPsi. // // While fPsi are the fourier coefficients, fM and fK are the hexagonal x and // y coordinates of the pixel corresponding to the index i which is the // common index of all arrays. fP is P(i,j) for all pixels. // // fIdx is also filled and used for reverse mapping. Due to the geometry // the right and left side of the fourier space triangle has identical // values. fIdx 'maps' the indices from the right to the left side. // void MHexagonalFT::Prepare(Int_t num) { fNumRows = num; fPsi.Set(num*num*num*num*2); Int_t lim = num*(num+1)/2; fM.Set(lim); fK.Set(lim); fP.Set(lim); fIdx.Set(lim); for(int j=0; jfM[idx1]) continue; Double_t sumre=0; Double_t sumim=0; Float_t *psi = fPsi.GetArray() + idx1*num*2; Float_t *p = fP.GetArray(); Double_t *re = inre.GetArray(); // 1st access to psi: const Float_t psire = *psi++; // 2nd access to psi: const Float_t psiim = *psi++; // sumre += f * *psire; // sumim += f * *psiim; while (p0 && fwd) continue; Double_t sumre=0; Double_t sumim=0; for(int k=0; k