source: trunk/MagicSoft/Mars/mhft/MHexagonalFTCalc.cc@ 9449

Last change on this file since 9449 was 9374, checked in by tbretz, 16 years ago
*** empty log message ***
File size: 9.6 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): Christoph Kolodziejski, 11/2004 <mailto:>
19! Author(s): Thomas Bretz, 11/2004 <mailto:tbretz@astro.uni-wuerzburg.de>
20!
21! Copyright: MAGIC Software Development, 2004
22!
23!
24\* ======================================================================== */
25
26//////////////////////////////////////////////////////////////////////////////
27//
28// MHexagonalFTCalc
29//
30// Task to perform forward transformation, cuts in fourier space and
31// backward tranformation.
32//
33// If you don't want to copy the rsult back to any MSignalCam call
34// SetNameSignalCamOut()
35//
36// Currently - this will change in the future! - there are two output
37// containers:
38// - MHexagonalFreqSpace1
39// real part: input values in triangle space
40// imaginary part: output values in triangle space
41//
42// - MHexagonalFreqSpace2
43// real part: real part of frequency space
44// imaginary part: imaginary part of frequency space
45//
46// To be done:
47// Flags to perform forward/backward trafo only to be able to cut outside!
48//
49//////////////////////////////////////////////////////////////////////////////
50#include "MHexagonalFTCalc.h"
51
52#include <TMath.h>
53
54#include "MLog.h"
55#include "MLogManip.h"
56
57#include "MParList.h"
58
59#include "MGeomCam.h"
60#include "MGeom.h"
61
62#include "MSignalCam.h"
63#include "MSignalPix.h"
64
65#include "MHexagonFreqSpace.h"
66
67#include "MArrayD.h"
68
69ClassImp(MHexagonalFTCalc);
70
71using namespace std;
72
73const char *MHexagonalFTCalc::fgNameGeomCam = "MGeomCam";
74const char *MHexagonalFTCalc::fgNameSignalCamIn = "MSignalCam";
75const char *MHexagonalFTCalc::fgNameSignalCamOut = "MSignalCam";
76
77// ---------------------------------------------------------------------------
78//
79// Default Constructor - empty. Initialize
80// fMaxAmplitude = 0.08
81// fMaxRowFraction = 0.75
82//
83MHexagonalFTCalc::MHexagonalFTCalc(const char *name, const char *title)
84 : fNameGeomCam(fgNameGeomCam),
85 fNameSignalCamIn(fgNameSignalCamIn), fNameSignalCamOut(fgNameSignalCamOut),
86 fEvtIn(0), fEvtOut(0),
87 fMaxAmplitude(0.08), fMaxRowFraction(0.75), fSkipBwdTrafo(kFALSE)
88{
89 fName = name ? name : "MHexagonalFTCalc";
90 fTitle = title ? title : "Task to calculate Hexagonal Fourier Transformation";
91}
92
93// ---------------------------------------------------------------------------
94//
95// Search for all necessary containers.
96//
97// Do a forward transformation for a flat camera, eg:
98//
99// 0 0 1 0 0
100// 0 1 1 0
101// 1 1 1
102// 1 1
103// 1
104//
105// The result (fOffset) is treated as a offset in the fourier space comming
106// from the fact that the camera doesn't extend the whole triangle.
107//
108// Before cutting in the fourier space it is substracted. After cutting it
109// is added again. Scaling is done by the constant-frequency-pixel (index 0)
110//
111// Create the LookUpTable which tells you which fourier space (triangle)
112// pixel index corresponds to which camera pixel index.
113//
114Int_t MHexagonalFTCalc::PreProcess(MParList *plist)
115{
116 fEvtIn = (MSignalCam*)plist->FindObject(fNameSignalCamIn, "MSignalCam");
117 if (!fEvtIn)
118 {
119 *fLog << err << fNameSignalCamIn << " [MSignalCam] not found... abort." << endl;
120 return kFALSE;
121 }
122
123 fEvtOut=0;
124 if (!fNameSignalCamOut.IsNull())
125 {
126 fEvtOut = (MSignalCam*)plist->FindCreateObj(fNameSignalCamOut, "MSignalCam");
127 if (!fEvtOut)
128 return kFALSE;
129 }
130
131 fFreq1 = (MHexagonFreqSpace*)plist->FindCreateObj("MHexagonFreqSpace","MHexagonFreqSpace1");
132 if (!fFreq1)
133 return kFALSE;
134 fFreq2 = (MHexagonFreqSpace*)plist->FindCreateObj("MHexagonFreqSpace","MHexagonFreqSpace2");
135 if (!fFreq2)
136 return kFALSE;
137
138 MGeomCam *geom = (MGeomCam*)plist->FindObject(fNameGeomCam, "MGeomCam");
139 if (!geom)
140 {
141 *fLog << err << fNameGeomCam << " [MGeomCam] not found... abort." << endl;
142 return kFALSE;
143 }
144
145 // Number of Rings (r) ---> Number of Pixels (p)
146 // p = 3*r*(r-1)+1
147
148 // Number of Pixels (p) ---> Number of Rings (r)
149 // p = (sqrt(9+12*(p-1))+3)/6
150
151 // Number of pixels at one border == number of rings (r)
152 // Row of border == number of rings (r)
153
154 // Number of rows to get a triangle: 3r-2
155
156 // One additional line on all three sides, number of rows: 3r-2+3 = 3r+1
157 Int_t num = 0;
158 for (UInt_t i=0; i<geom->GetNumPixels(); i++)
159 if ((*geom)[i].GetAidx()==0)
160 num++;
161
162 cout << "Number of pixels with Area Idx==0: " << num << endl;
163
164 const Int_t numrows = (Int_t)((sqrt(9.+12.*(num-1))+3)/2+1); //61;//34;
165 fHFT.Prepare(numrows);
166
167 cout << "Number of rows: " << numrows << endl;
168
169 const Int_t lim = fHFT.GetNumKnots();
170
171 fOffset.Set(lim);
172 fOffset.Reset();
173
174 //fMap.Set(lim);
175 //for (int i=0; i<lim; i++)
176 // fMap[i]=-1;
177
178 const Double_t dx = (*geom)[2].GetX(); // -(*geom)[0].GetX()
179 const Double_t dy = (*geom)[2].GetY(); // -(*geom)[0].GetY()
180
181 for (int i=0; i<lim; i++)
182 {
183 const Float_t x = dx*fHFT.GetCol(i);
184 const Float_t y = dy*Int_t(fHFT.GetRow(i)-2*fHFT.GetNumRows()/3);
185
186 const Int_t idx = geom->GetPixelIdxXY(x, y);
187 if (idx<0)
188 continue;
189
190 if ((*geom)[idx].GetAidx()==0)
191 {
192 //fMap[idx] = i;
193 fOffset[i] = 1;
194 }
195 }
196
197 fFreq1->Set(MArrayD(lim), MArrayD(lim));
198 fFreq2->Set(MArrayD(lim), MArrayD(lim));
199
200 // Calculate fourier tranformation of a constant field for all
201 // 'valid' pixels
202 MArrayD freqre;
203 MArrayD freqim;
204 fHFT.TransformFastFWD(fOffset, freqre, freqim);
205 fOffset = freqre;
206
207 return kTRUE;
208}
209
210// ---------------------------------------------------------------------------
211//
212// Do cuts in frequence space (fOffset already sustracted), eg:
213// fMaxRowFraction = 0.5
214// fMaxAmplitude = 0.3
215//
216// 0.1 0.2 0.1 0.3 0.4 0 0 0 0 0
217// 0.4 0.3 0.2 0.1 0 0 0 0
218// 0.6 0.4 0.8 -----> 0.6 0 0.8
219// 0.4 0.9 0 0.9
220// 0 0
221//
222// The result (fOffset) is treated as a offset in the fourier space comming
223// from the fact that the camera doesn't extend the whole triangle.
224//
225// Before cutting in the fourier space it is substracted. After cutting it
226// is added again. Scaling is done by the constant-frequency-pixel (index 0)
227//
228void MHexagonalFTCalc::CleanFreqSpace(MArrayD &outre, MArrayD &outim)
229{
230 // Do cut in frequency space
231 for (unsigned int i=0; i<outre.GetSize(); i++)
232 {
233 if (fHFT.GetRow(i)>(Int_t)fHFT.GetNumRows()*fMaxRowFraction)
234 outre[i]=outim[i]=0;
235 if (TMath::Hypot(outre[i], outim[i])<fMaxAmplitude)
236 outre[i]=outim[i]=0;
237 }
238}
239
240// ---------------------------------------------------------------------------
241//
242// - Copy input MSignalCam using the pixel mapping into an array
243// - Do forward transformation
244// - substract fourier offset
245// - perform cuts in fourier space
246// - add fourier offset
247// - do backward tranformation
248// - copy result back into output MSignalCam
249//
250Int_t MHexagonalFTCalc::Process()
251{
252 const Int_t lim = fHFT.GetNumKnots();
253
254 MArrayD re(lim);
255
256 // MSignalPix *pix=0;
257 // MSignalCamIter Next(fEvtIn, kFALSE);
258 // while ((pix = (MSignalPix*)Next()))
259 // Copy data from MSignalCam into array
260 const UInt_t npix = fEvtIn->GetNumPixels();
261 for (UInt_t idx=0; idx<npix; idx++)
262 {
263 //const Int_t idx = pix->GetPixId();
264 //if (fMap[idx]>=0)
265 re[idx] = (*fEvtIn)[idx].GetNumPhotons();
266 }
267
268 MArrayD freqre, freqim;
269
270 // Do forward transformation
271 fHFT.TransformFastFWD(re, freqre, freqim);
272
273 // Substract the 'structure of the hexagon'
274 Double_t scale = TMath::Abs(freqre[0]/fOffset[0]);
275 for (int i=0; i<lim; i++)
276 freqre[i] -= scale*fOffset[i];
277
278 // Put result in output container
279 fFreq2->Set(freqre, freqim);
280
281 // ----------------------------------------------------
282 // Do we need a backward transformation?
283 // ----------------------------------------------------
284 if (fSkipBwdTrafo)
285 return kTRUE;
286
287 // Clean image in frequency space
288 CleanFreqSpace(freqre, freqim);
289
290 // Add the 'structure of the hexagon'
291 for (int i=0; i<lim; i++)
292 freqre[i] += scale*fOffset[i];
293
294
295 MArrayD out;
296
297 // Do backward transformation
298 fHFT.TransformFastBWD(freqre, freqim, out);
299
300 // Write output into Mars container
301 fFreq1->Set(re, out);
302
303 // ----------------------------------------------------
304 // Do we have to copy the result back into MSignalCam?
305 // ----------------------------------------------------
306 if (!fEvtOut)
307 return kTRUE;
308
309 fEvtOut->InitSize(lim); // necessary?
310 for (int i=0; i<lim; i++)
311 {
312 //const Int_t map = fMap[i];
313 //if (map>=0)
314 fEvtOut->AddPixel(i, out[i]);
315 }
316 //fEvtOut->FixSize();
317 fEvtOut->SetReadyToSave();
318
319 return kTRUE;
320}
321
Note: See TracBrowser for help on using the repository browser.