Line data Source code
1 : // -*- C++ -*-
2 : //# AWConvFunc.cc: Implementation of the AWConvFunc class
3 : //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003
4 : //# Associated Universities, Inc. Washington DC, USA.
5 : //#
6 : //# This library is free software; you can redistribute it and/or modify it
7 : //# under the terms of the GNU Library General Public License as published by
8 : //# the Free Software Foundation; either version 2 of the License, or (at your
9 : //# option) any later version.
10 : //#
11 : //# This library is distributed in the hope that it will be useful, but WITHOUT
12 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
14 : //# License for more details.
15 : //#
16 : //# You should have received a copy of the GNU Library General Public License
17 : //# along with this library; if not, write to the Free Software Foundation,
18 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
19 : //#
20 : //# Correspondence concerning AIPS++ should be addressed as follows:
21 : //# Internet email: aips2-request@nrao.edu.
22 : //# Postal address: AIPS++ Project Office
23 : //# National Radio Astronomy Observatory
24 : //# 520 Edgemont Road
25 : //# Charlottesville, VA 22903-2475 USA
26 : //#
27 : //# $Id$
28 : //
29 : #include <synthesis/TransformMachines/AWConvFunc.h>
30 : #include <synthesis/TransformMachines/AWProjectFT.h>
31 : #include <synthesis/TransformMachines/SynthesisError.h>
32 : #include <casacore/images/Images/ImageInterface.h>
33 : #include <synthesis/TransformMachines/Utils.h>
34 : #include <synthesis/TransformMachines/BeamCalc.h>
35 : #include <synthesis/TransformMachines/CFStore.h>
36 : #include <synthesis/TransformMachines/CFStore2.h>
37 : #include <synthesis/TransformMachines/PSTerm.h>
38 : #include <synthesis/TransformMachines/WTerm.h>
39 : #include <synthesis/TransformMachines/ATerm.h>
40 : #include <synthesis/TransformMachines/VLACalcIlluminationConvFunc.h>
41 : #include <synthesis/TransformMachines/ConvolutionFunction.h>
42 : #include <synthesis/TransformMachines/PolOuterProduct.h>
43 : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
44 : #include <casacore/coordinates/Coordinates/LinearCoordinate.h>
45 : #include <casacore/coordinates/Coordinates/SpectralCoordinate.h>
46 : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
47 : #include <casacore/casa/System/ProgressMeter.h>
48 : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
49 : #include <casacore/casa/Utilities/CompositeNumber.h>
50 : #include <casacore/casa/OS/Directory.h>
51 : #include <casacore/casa/OS/Timer.h>
52 : #include <ostream>
53 : #ifdef _OPENMP
54 : #include <omp.h>
55 : #endif
56 :
57 : #define MAX_FREQ 1e30
58 :
59 : using namespace casacore;
60 : namespace casa{
61 0 : AWConvFunc::AWConvFunc(const casacore::CountedPtr<ATerm> aTerm,
62 : const casacore::CountedPtr<PSTerm> psTerm,
63 : const casacore::CountedPtr<WTerm> wTerm,
64 : const casacore::Bool wbAWP,
65 0 : const casacore::Bool conjPB):
66 : ConvolutionFunction(),aTerm_p(aTerm),psTerm_p(psTerm), wTerm_p(wTerm), pixFieldGrad_p(),
67 0 : wbAWP_p(wbAWP), conjPB_p(conjPB), baseCFB_p()
68 : {
69 0 : LogIO log_l(LogOrigin("AWConvFunc", "AWConvFunc"));
70 0 : if (psTerm->isNoOp() && aTerm->isNoOp())
71 0 : log_l << "Both, psterm and aterm cannot be set to NoOp. " << LogIO::EXCEPTION;
72 :
73 0 : if (wbAWP && aTerm->isNoOp())
74 : {
75 : //log_l << "wbawp=True is ineffective when aterm is OFF. Setting wbawp to False." << LogIO::NORMAL1;
76 0 : wbAWP_p=false;
77 : }
78 :
79 0 : pixFieldGrad_p.resize(2);pixFieldGrad_p=0.0;
80 0 : }
81 : //
82 : //----------------------------------------------------------------------
83 : //
84 0 : AWConvFunc& AWConvFunc::operator=(const AWConvFunc& other)
85 : {
86 0 : if(this!=&other)
87 : {
88 0 : aTerm_p = other.aTerm_p;
89 0 : psTerm_p = other.psTerm_p;
90 0 : wTerm_p = other.wTerm_p;
91 : }
92 0 : return *this;
93 :
94 : }
95 : //
96 : //----------------------------------------------------------------------
97 : //
98 0 : void AWConvFunc::makePBSq(ImageInterface<Complex>& PB)
99 : {
100 0 : IPosition pbShape=PB.shape();
101 0 : IPosition cursorShape(4, pbShape(0), pbShape(1), 1, 1), axisPath(4,0,1,2,3);
102 0 : Array<Complex> buf; PB.get(buf,false);
103 0 : ArrayLattice<Complex> lat(buf, true);
104 0 : LatticeStepper latStepper(lat.shape(), cursorShape,axisPath);
105 0 : LatticeIterator<Complex> latIter(lat, latStepper);
106 :
107 0 : IPosition start0(4,0,0,0,0), start1(4,0,0,1,0), length(4, pbShape(0), pbShape(1),1,1);
108 0 : Slicer slicePol0(start0, length), slicePol1(start1, length);
109 0 : if (pbShape(2) > 1)
110 : {
111 0 : Array<Complex> pol0, pol1,tmp;
112 :
113 0 : lat.getSlice(pol0, slicePol0);
114 0 : lat.getSlice(pol1, slicePol1);
115 0 : tmp = pol0;
116 0 : pol0 = pol0*conj(pol1);
117 0 : pol1 = tmp*conj(pol1);
118 0 : lat.putSlice(pol0,start0);
119 0 : lat.putSlice(pol1,start1);
120 : }
121 : else
122 : {
123 : // Array<Complex> pol0;
124 : // lat.getSlice(pol0,slicePol0);
125 : // pol0 = pol0*conj(pol0);
126 0 : buf = buf * conj(buf);
127 : }
128 0 : }
129 : //
130 : //----------------------------------------------------------------------
131 : //
132 0 : void AWConvFunc::makeConjPolAxis(CoordinateSystem& cs,
133 : Int conjStokes_in)
134 : {
135 0 : LogIO log_l(LogOrigin("AWConvFunc", "makeConjPolAxis[R&D]"));
136 0 : IPosition dummy;
137 0 : Vector<String> csList;
138 0 : Vector<Int> stokes, conjStokes;
139 :
140 : // cout << "CoordSys: ";
141 : // csList = cs.list(log_l,MDoppler::RADIO,dummy,dummy);
142 : // cout << csList << endl;
143 0 : Int stokesIndex=cs.findCoordinate(Coordinate::STOKES);
144 0 : StokesCoordinate sc=cs.stokesCoordinate(stokesIndex);
145 :
146 0 : if (conjStokes_in == -1)
147 : {
148 0 : stokes=sc.stokes();
149 0 : conjStokes.resize(stokes.shape());
150 0 : for (uInt i=0; i<stokes.nelements(); i++)
151 : {
152 0 : if (stokes(i) == Stokes::RR) conjStokes(i) = Stokes::LL;
153 0 : if (stokes(i) == Stokes::LL) conjStokes(i) = Stokes::RR;
154 0 : if (stokes(i) == Stokes::LR) conjStokes(i) = Stokes::RL;
155 0 : if (stokes(i) == Stokes::RL) conjStokes(i) = Stokes::LR;
156 :
157 0 : if (stokes(i) == Stokes::XX) conjStokes(i) = Stokes::YY;
158 0 : if (stokes(i) == Stokes::YY) conjStokes(i) = Stokes::XX;
159 0 : if (stokes(i) == Stokes::YX) conjStokes(i) = Stokes::XY;
160 0 : if (stokes(i) == Stokes::XY) conjStokes(i) = Stokes::YX;
161 : }
162 : }
163 : else
164 : {
165 0 : conjStokes.resize(1);
166 0 : conjStokes[0]=conjStokes_in;
167 : }
168 0 : sc.setStokes(conjStokes);
169 0 : cs.replaceCoordinate(sc,stokesIndex);
170 0 : }
171 : //
172 : //----------------------------------------------------------------------
173 : //
174 0 : void AWConvFunc::fillConvFuncBuffer(CFBuffer& cfb, CFBuffer& cfWtb,
175 : const Int& nx, const Int& ny,
176 : const Vector<Double>& freqValues,
177 : const Vector<Double>& wValues,
178 : const Double& wScale,
179 : const Double& vbPA, const Double& freqHi,
180 : const PolMapType& muellerElements,
181 : const PolMapType& muellerElementsIndex,
182 : const VisBuffer& vb,
183 : const Float& psScale,
184 : PSTerm& psTerm, WTerm& wTerm, ATerm& aTerm,
185 : Bool isDryRun)
186 : {
187 : // Unused variable from the dark-ages era interface that should ultimately go.
188 : (void)psScale;
189 : (void)muellerElementsIndex;
190 : (void)freqHi;
191 0 : LogIO log_l(LogOrigin("AWConvFunc", "fillConvFuncBuffer[R&D]"));
192 : // Int ttt=0;
193 0 : Complex cfNorm, cfWtNorm;
194 : //Double vbPA = getPA(vb);
195 0 : Complex cpeak,wtcpeak;
196 0 : aTerm.cacheVBInfo(vb);
197 :
198 0 : for (uInt imx=0;imx<muellerElements.nelements();imx++) // Loop over all MuellerElements
199 0 : for (uInt imy=0;imy<muellerElements(imx).nelements();imy++)
200 : {
201 : {
202 0 : for (uInt inu=0;inu<freqValues.nelements();inu++) // All freq. channels
203 : {
204 : Float sampling, samplingWt;
205 : Int xSupport, ySupport, xSupportWt, ySupportWt;
206 0 : CoordinateSystem cs_l;
207 : // Extract the parameters index by (MuellerElement, Freq, W)
208 0 : cfWtb.getParams(cs_l, samplingWt, xSupportWt, ySupportWt,
209 0 : freqValues(inu),
210 : // wValues(iw),
211 0 : wValues(0),
212 0 : muellerElements(imx)(imy));
213 0 : cfb.getParams(cs_l, sampling, xSupport, ySupport,
214 0 : freqValues(inu),
215 0 : wValues(0),
216 0 : muellerElements(imx)(imy));
217 0 : IPosition pbshp(4,nx,ny,1,1);
218 : //
219 : // Cache the A-Term for this polarization and frequency
220 : //
221 0 : Double conjFreq=SynthesisUtils::conjFreq(freqValues(inu),imRefFreq_p);
222 : Int conjFreqIndex;
223 0 : conjFreq=SynthesisUtils::nearestValue(freqValues, conjFreq, conjFreqIndex);
224 :
225 : // cout<<"Muller Array = "<<muellerElements(imx)(imy)<<"\n" ;
226 : // USEFUL DEBUG MESSAGE
227 : // cerr << "Freq. values: "
228 : // << freqValues(inu) << " "
229 : // << imRefFreq_p << " "
230 : // << conjFreq << " "
231 : // << endl;
232 :
233 0 : CoordinateSystem conjPolCS_l=cs_l; AWConvFunc::makeConjPolAxis(conjPolCS_l);
234 0 : TempImage<Complex> ftATerm_l(pbshp, cs_l), ftATermSq_l(pbshp,conjPolCS_l);
235 : Int index;
236 0 : Vector<Int> conjPol;
237 0 : index = conjPolCS_l.findCoordinate(Coordinate::STOKES);
238 0 : conjPol = conjPolCS_l.stokesCoordinate(index).stokes();
239 : //cerr << "ConjPol = " << conjPol << endl;
240 :
241 : // {
242 : // // Vector<Double> chanFreq = vb.frequency();
243 : // CoordinateSystem skyCS(ftATerm_l.coordinates());
244 : // Int index = skyCS.findCoordinate(Coordinate::SPECTRAL);
245 : // SpectralCoordinate SpC = skyCS.spectralCoordinate(index);
246 : // Vector<Double> refVal = SpC.referenceValue();
247 :
248 : // Double ff = refVal[0];
249 : // cerr << "Freq, ConjFreq: " << freqValues(inu) << " " << conjFreq << " " << ff << endl;
250 : // }
251 :
252 :
253 0 : Bool doSquint=true;
254 : // Bool doSquint=false; Complex tt;
255 0 : ftATerm_l.set(Complex(1.0,0.0)); ftATermSq_l.set(Complex(1.0,0.0));
256 :
257 0 : Int me=muellerElements(imx)(imy);
258 0 : if (!isDryRun)
259 : {
260 0 : aTerm.applySky(ftATerm_l, vb, doSquint, 0, me, freqValues(inu));//freqHi);
261 : // {
262 : // ostringstream name;
263 : // name << "ftATerm" << "_" << inu << "_" << muellerElements(imx)(imy) <<".im";
264 : // storeImg(name,ftATerm_l);
265 : // }
266 : //tt=max(ftATerm_l.get()); ftATerm_l.put(ftATerm_l.get()/tt);
267 0 : if (conjPB_p) aTerm.applySky(ftATermSq_l, vb, doSquint, 0,me,conjFreq);
268 0 : else aTerm.applySky(ftATermSq_l, vb, doSquint, 0,me,freqValues(inu));
269 : }
270 :
271 : //tt=max(ftATermSq_l.get()); ftATermSq_l.put(abs(ftATermSq_l.get()/tt));
272 :
273 : //{
274 : // ostringstream name;
275 : // name << "ftTermSq" << "_" << muellerElements(imx)(imy) <<".im";
276 : // storeImg(name,ftATermSq_l);
277 : //}
278 : // TempImage<Complex> ftATermSq_l(pbshp,cs_l);
279 : // ftATermSq_l.set(Complex(1.0,0.0));
280 : // aTerm.applySky(ftATermSq_l, vb, false, 0);
281 : // tt=max(ftATermSq_l.get());
282 : // ftATermSq_l.put(ftATermSq_l.get()/tt);
283 :
284 0 : Int directionIndex=cs_l.findCoordinate(Coordinate::DIRECTION);
285 0 : DirectionCoordinate dc=cs_l.directionCoordinate(directionIndex);
286 0 : Vector<Double> cellSize;
287 0 : cellSize = dc.increment();
288 :
289 : //
290 : // Now compute the PS x W-Term and apply the cached
291 : // A-Term to build the full CF.
292 : //
293 0 : for (uInt iw=0;iw<wValues.nelements();iw++) // All w-planes
294 : {
295 0 : if (!isDryRun)
296 : log_l << " CF("
297 0 : << "M:"<<muellerElements(imx)(imy)
298 : << ",C:" << inu
299 0 : << ",W:" << iw << "): ";
300 : // {
301 : // CountedPtr<CFCell> thisCell=cfb.getCFCellPtr(freqValues(inu), wValues(iw), muellerElements(imx)(imy));
302 : // thisCell->conjFreq_p = conjFreq;
303 : // cerr << "ConjFreq: " << thisCell->conjFreq_p << " " << inu << " " << iw << " " << muellerElements(imx)(imy) << endl;
304 : // }
305 :
306 0 : Array<Complex> &cfWtBuf=(*(cfWtb.getCFCellPtr(freqValues(inu), wValues(iw),
307 0 : muellerElements(imx)(imy))->storage_p));
308 0 : Array<Complex> &cfBuf=(*(cfb.getCFCellPtr(freqValues(inu), wValues(iw),
309 0 : muellerElements(imx)(imy))->storage_p));
310 : // IPosition cfWtBufShape= cfWtb.getCFCellPtr(freqValues(inu), wValues(iw),
311 : // muellerElements(imx)(imy))->shape_p;
312 : // IPosition cfBufShape=cfb.getCFCellPtr(freqValues(inu), wValues(iw),
313 : // muellerElements(imx)(imy))->shape_p;
314 :
315 0 : cfWtBuf.resize(pbshp);
316 0 : cfBuf.resize(pbshp);
317 :
318 0 : const Vector<Double> sampling_l(2,sampling);
319 : // Double wval = wValues[iw];
320 0 : Matrix<Complex> cfBufMat(cfBuf.nonDegenerate()),
321 0 : cfWtBufMat(cfWtBuf.nonDegenerate());
322 : //
323 : // Apply the Prolate Spheroidal and W-Term kernels
324 : //
325 :
326 0 : Vector<Double> s(2); s=sampling;
327 : // Int inner = cfBufMat.shape()(0)/aTerm.getOversampling();
328 : // Float inner = 2.0*aTerm.getOversampling()/cfBufMat.shape()(0);
329 :
330 : //Timer tim;
331 : //tim.mark();
332 0 : if (psTerm.isNoOp() || isDryRun)
333 0 : cfBufMat = cfWtBufMat = 1.0;
334 : else
335 : {
336 : // psTerm.applySky(cfBufMat, False); // Assign (psScale set in psTerm.init()
337 : // psTerm.applySky(cfWtBufMat, False); // Assign
338 0 : psTerm.applySky(cfBufMat, s, cfBufMat.shape()(0)/s(0)); // Assign (psScale set in psTerm.init()
339 0 : psTerm.applySky(cfWtBufMat, s, cfWtBufMat.shape()(0)/s(0)); // Assign
340 0 : cfWtBuf *= cfWtBuf;
341 : }
342 : //tim.show("PSTerm*2: ");
343 :
344 : // WBAWP CODE BEGIN -- make PS*PS for Weights
345 : // psTerm.applySky(cfWtBufMat, true); // Multiply
346 : // WBAWP CODE END
347 :
348 : // psTerm.applySky(cfBufMat, s, inner/2.0);//pbshp(0)/(os));
349 : // psTerm.applySky(cfWtBufMat, s, inner/2.0);//pbshp(0)/(os));
350 :
351 : // W-term is a unit-amplitude term in the image
352 : // doimain. No need to apply it to the
353 : // wt-functions.
354 :
355 : //tim.mark();
356 0 : if (!isDryRun)
357 : {
358 0 : wTerm.applySky(cfBufMat, iw, cellSize, wScale, cfBuf.shape()(0));///4);
359 : }
360 : //tim.show("WTerm: ");
361 : // wTerm.applySky(cfWtBufMat, iw, cellSize, wScale, cfWtBuf.shape()(0)/4);
362 :
363 0 : IPosition PolnPlane(4,0,0,0,0),
364 0 : pbShape(4, cfBuf.shape()(0), cfBuf.shape()(1), 1, 1);
365 : //
366 : // Make TempImages and copy the buffers with PS *
367 : // WKernel applied (too bad that TempImages can't be
368 : // made with existing buffers)
369 : //
370 : //-------------------------------------------------------------
371 0 : TempImage<Complex> twoDPB_l(pbShape, cs_l);
372 0 : TempImage<Complex> twoDPBSq_l(pbShape,cs_l);
373 : //-------------------------------------------------------------
374 : // WBAWP CODE BEGIN -- ftATermSq_l has conj. PolCS
375 0 : cfWtBuf *= ftATerm_l.get()*conj(ftATermSq_l.get());
376 :
377 : //tim.mark();
378 : //UUU cfWtBuf *= ftATerm_l.get();
379 0 : cfBuf *= ftATerm_l.get();
380 : //tim.show("W*A*2: ");
381 : // WBAWP CODE END
382 :
383 :
384 :
385 : // cfWtBuf = sqrt(cfWtBuf);
386 : // psTerm.applySky(cfWtBufMat,true);
387 :
388 : //tim.mark();
389 0 : twoDPB_l.putSlice(cfBuf, PolnPlane);
390 0 : twoDPBSq_l.putSlice(cfWtBuf, PolnPlane);
391 : //tim.show("putSlice:");
392 : // WBAWP CODE BEGIN
393 : // twoDPB_l *= ftATerm_l;
394 : // WBAWP CODE END
395 :
396 : // twoDPBSq_l *= ftATermSq_l;//*conj(ftATerm_l);
397 :
398 : // To accumulate avgPB2, call this function.
399 : // PBSQWeight
400 0 : Bool PBSQ = false;
401 0 : if(PBSQ) makePBSq(twoDPBSq_l);
402 :
403 :
404 : //
405 : // Set the ref. freq. of the co-ordinate system to
406 : // that set by ATerm::applySky().
407 : //
408 : //tim.mark();
409 0 : CoordinateSystem cs=twoDPB_l.coordinates();
410 0 : Int index= twoDPB_l.coordinates().findCoordinate(Coordinate::SPECTRAL);
411 0 : SpectralCoordinate SpCS = twoDPB_l.coordinates().spectralCoordinate(index);
412 :
413 0 : Double cfRefFreq=SpCS.referenceValue()(0);
414 0 : Vector<Double> refValue; refValue.resize(1); refValue(0)=cfRefFreq;
415 0 : SpCS.setReferenceValue(refValue);
416 0 : cs.replaceCoordinate(SpCS,index);
417 : //tim.show("CSStuff:");
418 : //
419 : // Now FT the function and copy the data from
420 : // TempImages back to the CFBuffer buffers
421 : //
422 : //tim.mark();
423 0 : if (!isDryRun)
424 : {
425 0 : LatticeFFT::cfft2d(twoDPB_l);
426 0 : LatticeFFT::cfft2d(twoDPBSq_l);
427 : }
428 : //tim.show("FFT*2:");
429 : // Array<Complex> t0;
430 : // twoDPBSq_l.get(t0); t0 = abs(t0);
431 : // twoDPBSq_l.put(t0);
432 :
433 : // {
434 : // ostringstream name;
435 : // name << "twoDPB.before" << iw << "_" << inu << "_" << muellerElements(imx)(imy) <<".im";
436 : // storeImg(name,twoDPB_l);
437 : // }
438 : // {
439 : // ostringstream name;
440 : // name << "twoDPBSq.before" << iw << "_" << inu << "_" << muellerElements(imx)(imy) <<".im";
441 : // storeImg(name,twoDPBSq_l);
442 : // }
443 : // exit(0);
444 :
445 : //tim.mark();
446 :
447 0 : IPosition shp(twoDPB_l.shape());
448 0 : IPosition start(4, 0, 0, 0, 0), pbSlice(4, shp[0]-1, shp[1]-1,1/*polInUse*/, 1),
449 0 : sliceLength(4,cfBuf.shape()[0]-1,cfBuf.shape()[1]-1,1,1);
450 :
451 0 : cfBuf(Slicer(start,sliceLength)).nonDegenerate()
452 0 : =(twoDPB_l.getSlice(start, pbSlice, true));
453 :
454 0 : shp = twoDPBSq_l.shape();
455 0 : IPosition pbSqSlice(4, shp[0]-1, shp[1]-1, 1, 1),
456 0 : sqSliceLength(4,cfWtBuf.shape()(0)-1,cfWtBuf.shape()[1]-1,1,1);
457 :
458 0 : cfWtBuf(Slicer(start,sqSliceLength)).nonDegenerate()
459 0 : =(twoDPBSq_l.getSlice(start, pbSqSlice, true));
460 : //tim.show("Slicer*2:");
461 : //
462 : // Finally, resize the buffers, limited to the
463 : // support size determined by the threshold
464 : // suppled by the ATerm (done internally in
465 : // resizeCF()). Transform the co-ord. system to
466 : // the FT domain set the co-ord. sys. and modified
467 : // support sizes.
468 : //
469 : //tim.mark();
470 0 : Int supportBuffer = (Int)(getOversampling(psTerm, wTerm, aTerm)*2.0);
471 0 : if (!isDryRun)
472 : {
473 0 : if (iw==0) wtcpeak = max(cfWtBuf);
474 0 : cfWtBuf /= wtcpeak;
475 : }
476 : //tim.show("Norm");
477 :
478 : //tim.mark();
479 0 : if (!isDryRun)
480 0 : AWConvFunc::resizeCF(cfWtBuf, xSupportWt, ySupportWt, supportBuffer, samplingWt,0.0);
481 : //log_l << "CF WT Support: " << xSupport << " (" << xSupportWt << ") " << "pixels" << LogIO::POST;
482 : //tim.show("Resize:");
483 :
484 : //tim.mark();
485 0 : Vector<Double> ftRef(2);
486 0 : ftRef(0)=cfWtBuf.shape()(0)/2.0;
487 0 : ftRef(1)=cfWtBuf.shape()(1)/2.0;
488 0 : CoordinateSystem ftCoords=cs_l;
489 0 : SynthesisUtils::makeFTCoordSys(cs_l, cfWtBuf.shape()(0), ftRef, ftCoords);
490 0 : CountedPtr<CFCell> cfCellPtr;
491 0 : cfWtb.setParams(inu,iw,imx,imy,//muellerElements(imx)(imy),
492 0 : freqValues(inu), String(""), wValues(iw), muellerElements(imx)(imy),
493 : ftCoords, samplingWt, xSupportWt, ySupportWt,
494 0 : String(""), // Default ==> don't set it in the CFCell
495 0 : conjFreq, conjPol[0]);
496 0 : cfCellPtr = cfWtb.getCFCellPtr(freqValues(inu), wValues(iw),
497 0 : muellerElements(imx)(imy));
498 0 : cfCellPtr->pa_p=Quantity(vbPA,"rad");
499 0 : cfCellPtr->telescopeName_p = aTerm.getTelescopeName();
500 0 : cfCellPtr->isRotationallySymmetric_p = aTerm.isNoOp();
501 :
502 : //cerr << "AWConvFunc: Telescope name = " << cfCellPtr->telescopeName_p << " " << aTerm.getTelescopeName() << endl;
503 : //tim.show("CSStuff:");
504 : // setUpCFSupport(cfBuf, xSupport, ySupport, sampling);
505 : // if (iw==0)
506 : //tim.mark();
507 : //Int supportBuffer = (Int)(aTerm->getOversampling()*1.5);
508 :
509 0 : if (!isDryRun)
510 : {
511 0 : cpeak = max(cfBuf);
512 0 : cfBuf /= cpeak;
513 : }
514 : //tim.show("Peaknorm:");
515 : // {
516 : // ostringstream name;
517 : // name << "twoDPB.after" << iw << "_" << inu << "_" << muellerElements(imx)(imy) << ".im";
518 : // storeImg(name,twoDPB_l);
519 : // // name << "twoDPBSq.after" << iw << "_" << inu << "_" << muellerElements(imx)(imy) << ".im";
520 : // // storeImg(name,twoDPBSq_l);
521 : // }
522 :
523 0 : if (!isDryRun)
524 0 : AWConvFunc::resizeCF(cfBuf, xSupport, ySupport, supportBuffer, sampling,0.0);
525 :
526 0 : if (!isDryRun)
527 0 : log_l << "CF Support: " << xSupport << " (" << xSupportWt << ") " << "pixels" << LogIO::POST;
528 :
529 : // cfb.getCFCellPtr(freqValues(inu), wValues(iw), muellerElement)->storage_p->assign(cfBuf);
530 : // ftRef(0)=cfBuf.shape()(0)/2-1;
531 : // ftRef(1)=cfBuf.shape()(1)/2-1;
532 0 : ftRef(0)=cfBuf.shape()(0)/2.0;
533 0 : ftRef(1)=cfBuf.shape()(1)/2.0;
534 :
535 : //tim.mark();
536 0 : cfNorm=cfWtNorm=1.0;
537 : //if ((iw == 0) && (!isDryRun))
538 0 : if (!isDryRun)
539 : {
540 0 : cfNorm=0; cfWtNorm=0;
541 0 : cfNorm = AWConvFunc::cfArea(cfBufMat, xSupport, ySupport, sampling);
542 0 : cfWtNorm = AWConvFunc::cfArea(cfWtBufMat, xSupportWt, ySupportWt, sampling);
543 : }
544 : //tim.show("Area*2:");
545 :
546 : //tim.mark();
547 0 : cfBuf /= cfNorm;
548 0 : cfWtBuf /= cfWtNorm;
549 : //tim.show("cfNorm*2:");
550 :
551 : //tim.mark();
552 0 : ftCoords=cs_l;
553 0 : SynthesisUtils::makeFTCoordSys(cs_l, cfBuf.shape()(0), ftRef, ftCoords);
554 :
555 0 : cfb.setParams(inu,iw,imx,imy,//muellerElements(imx)(imy),
556 0 : freqValues(inu), String(""), wValues(iw), muellerElements(imx)(imy),
557 : ftCoords, sampling, xSupport, ySupport,
558 0 : String(""), // Default ==> Don't set in the CFCell
559 0 : conjFreq, conjPol[0]);
560 0 : cfCellPtr=cfb.getCFCellPtr(freqValues(inu), wValues(iw),
561 0 : muellerElements(imx)(imy));
562 0 : cfCellPtr->pa_p=Quantity(vbPA,"rad");
563 0 : cfCellPtr->telescopeName_p = aTerm.getTelescopeName();
564 0 : cfCellPtr->isRotationallySymmetric_p = aTerm.isNoOp();
565 : //
566 : // Now tha the CFs have been computed, cache its
567 : // paramters in CFCell for quick access in tight
568 : // loops (in the re-sampler, e.g.).
569 : //
570 :
571 0 : (cfWtb.getCFCellPtr(freqValues(inu), wValues(iw),
572 0 : muellerElements(imx)(imy)))->initCache(isDryRun);
573 0 : (cfb.getCFCellPtr(freqValues(inu), wValues(iw),
574 0 : muellerElements(imx)(imy)))->initCache(isDryRun);
575 :
576 : //tim.show("End*2:");
577 : }
578 : }
579 : }
580 : }
581 0 : }
582 : //
583 : //----------------------------------------------------------------------
584 : //
585 0 : Complex AWConvFunc::cfArea(Matrix<Complex>& cf,
586 : const Int& xSupport, const Int& ySupport,
587 : const Float& sampling)
588 : {
589 0 : LogIO log_l(LogOrigin("AWConvFunc","cfArea"));
590 0 : Complex cfNorm=0;
591 0 : Int origin=cf.shape()(0)/2;
592 0 : Float peak=0;
593 0 : IPosition ndx(4,0,0,0,0);
594 0 : IPosition peakPix(ndx);
595 0 : peakPix = 0;
596 0 : for(ndx(1)=0;ndx(1)<cf.shape()(1);ndx(1)++)
597 0 : for(ndx(0)=0;ndx(0)<cf.shape()(0);ndx(0)++)
598 0 : if (abs(cf(ndx)) > peak) {peakPix = ndx;peak=abs(cf(ndx));}
599 : // origin = peakPix(0);
600 :
601 : // int peakNIC=0;
602 :
603 0 : if (origin != peakPix(0))
604 : {
605 0 : log_l << "Peak not at the center " << origin << " " << cf(IPosition(4,origin,origin,0,0)) << " " << peakPix << " " << peak << LogIO::NORMAL1;
606 : // peakNIC=1e7;
607 : }
608 0 : for (Int ix=-xSupport;ix<xSupport;ix++)
609 0 : for (int iy=-ySupport;iy<ySupport;iy++)
610 : {
611 : //cfNorm += Complex(real(cf(ix*(Int)sampling+origin, iy*(Int)sampling+origin)),0.0);
612 0 : cfNorm += (cf(ix*(Int)sampling+origin, iy*(Int)sampling+origin));
613 : // cerr << cfNorm << " " << ix << " " << iy << " " << ix*(Int)sampling+origin << " " << iy*(Int)sampling+origin
614 : // << real(cf(ix*(Int)sampling+origin, iy*(Int)sampling+origin)) << endl;
615 : }
616 : // cf /= cfNorm;
617 :
618 0 : return cfNorm;//+Complex(peakNIC,0.0);
619 : }
620 : //
621 : //----------------------------------------------------------------------
622 : //
623 0 : Vector<Double> AWConvFunc::makeWValList(const Double &dW, const Int &nW)
624 : {
625 0 : Vector<Double> wValues(nW);
626 : // for (Int iw=0;iw<nW;iw++) wValues[iw]=iw*dW;
627 0 : wValues = 0.0;
628 0 : if (dW > 0.0)
629 0 : for (Int iw=0;iw<nW;iw++) wValues[iw]=iw*iw/dW;
630 0 : return wValues;
631 : }
632 :
633 : // This methods is depcricated. Keeping it here since it *might*
634 : // have use sometime later and therefore want to push it on to SVN
635 : // before deleting it form the active version of this file.
636 0 : Matrix<Double> AWConvFunc::getFreqRangePerSpw(const VisBuffer& vb)
637 : {
638 : //
639 : // Find the total effective bandwidth
640 : //
641 0 : Cube<Double> fminmax;
642 0 : Double fMax=0, fMin=MAX_FREQ;
643 0 : ArrayColumn<Double> spwCol=vb.msColumns().spectralWindow().chanFreq();
644 0 : fminmax.resize(spwChanSelFlag_p.shape()(0),spwChanSelFlag_p.shape()(1),2);
645 0 : fminmax=0;
646 0 : for (uInt ims=0; ims<spwChanSelFlag_p.shape()(0); ims++)
647 0 : for(uInt ispw=0; ispw<spwChanSelFlag_p.shape()(1); ispw++)
648 : {
649 0 : fMax=0, fMin=MAX_FREQ;
650 0 : for(uInt ichan=0; ichan<spwChanSelFlag_p.shape()(2); ichan++)
651 : {
652 0 : if (spwChanSelFlag_p(ims,ispw,ichan)==1)
653 : {
654 0 : Slicer slicer(IPosition(1,ichan), IPosition(1,1));
655 0 : Vector<Double> freq = spwCol(ispw)(slicer);
656 0 : if (freq(0) < fMin) fMin = freq(0);
657 0 : if (freq(0) > fMax) fMax = freq(0);
658 : }
659 : }
660 0 : fminmax(ims,ispw,0)=fMin;
661 0 : fminmax(ims,ispw,1)=fMax;
662 : }
663 :
664 0 : Matrix<Double> freqRangePerSpw(fminmax.shape()(1),2);
665 0 : for (uInt j=0;j<fminmax.shape()(1);j++) // SPW
666 : {
667 0 : freqRangePerSpw(j,0)=0;
668 0 : freqRangePerSpw(j,1)=MAX_FREQ;
669 0 : for (uInt i=0;i<fminmax.shape()(0);i++) //MSes
670 : {
671 0 : if (freqRangePerSpw(j,0) < fminmax(i,j,0)) freqRangePerSpw(j,0)=fminmax(i,j,0);
672 0 : if (freqRangePerSpw(j,1) > fminmax(i,j,1)) freqRangePerSpw(j,1)=fminmax(i,j,1);
673 : }
674 : }
675 0 : for(uInt i=0;i<freqRangePerSpw.shape()(0);i++)
676 : {
677 0 : if (freqRangePerSpw(i,0) == MAX_FREQ) freqRangePerSpw(i,0)=-1;
678 0 : if (freqRangePerSpw(i,1) == 0) freqRangePerSpw(i,1)=-1;
679 : }
680 :
681 0 : return freqRangePerSpw;
682 : }
683 : //
684 : //----------------------------------------------------------------------
685 : // Given the VB and the uv-grid, make a list of frequency values to
686 : // sample the frequency axis of the CFBuffer. Typically, this will
687 : // be determined by the bandwidth-smearning limit.
688 : //
689 : // This limit is (deltaNu/Nu) * sqrt(l^2 + m^2) < ResolutionElement.
690 : // Translating max. distance from the phase center to field-of-view
691 : // of the supplied image, and converting Resolution Element to
692 : // 1/Cellsize, this expression translates to deltaNU<FMin/Nx (!)
693 0 : Vector<Double> AWConvFunc::makeFreqValList(Double &dNU,
694 : const VisBuffer& vb,
695 : const ImageInterface<Complex>& uvGrid,
696 : Vector<String>& bandNames)
697 : {
698 : (void)uvGrid; (void)dNU; (void)vb;
699 0 : Vector<Double> fValues;
700 0 : if (wbAWP_p==false)
701 : {
702 : // Return the sky-image ref. freq.
703 0 : fValues.resize(1);
704 0 : fValues[0]=imRefFreq_p;
705 :
706 : // // Return the max. freq. from the list of selected SPWs
707 : // fValues.resize(1);
708 : // Double maxFreq=0.0;
709 : // for (Int i=0;i<spwFreqSelection_p.shape()(0);i++)
710 : // if (spwFreqSelection_p(i,2) > maxFreq) maxFreq=spwFreqSelection_p(i,2);
711 : // fValues[0]=maxFreq;
712 : }
713 : else
714 : {
715 : Int nSpw;
716 :
717 : // USEFUL DEBUG MESSAGE
718 : //cerr << "##### Min. Max. Freq. per Spw: " << spwFreqSelection_p << " " << spwFreqSelection_p.shape() <<endl;
719 :
720 0 : nSpw = spwFreqSelection_p.shape()(0);
721 0 : fValues.resize(nSpw);
722 0 : bandNames.resize(nSpw);
723 : // dNU = (spwFreqSelection_p(0,1) - spwFreqSelection_p(0,2));
724 0 : ScalarColumn<String> spwNames=vb.msColumns().spectralWindow().name();
725 0 : for(Int i=0;i<nSpw;i++)
726 : {
727 0 : int s=spwFreqSelection_p(i,0);
728 0 : cerr << "Spw"<<s<<": " << spwNames.getColumn()[s] << endl;
729 :
730 0 : bandNames(i)=spwNames.getColumn()[s];
731 0 : fValues(i)=spwFreqSelection_p(i,2);
732 : // Int j=0;
733 : // while (j*dNU+spwFreqSelection_p(i,1) <= spwFreqSelection_p(i,2))
734 : // {
735 : // fValues.resize(j+1,true);
736 : // // fValues(j)=spwFreqSelection_p(i,2); // Pick up the max. freq. for each selected SPW
737 : // fValues(j)=j*dNU+spwFreqSelection_p(i,1);
738 : // j=fValues.nelements();
739 : // }
740 : }
741 : // cerr << "Max. freq. per SPW = " << fValues << endl;
742 : }
743 0 : return fValues;
744 : }
745 : //
746 : //----------------------------------------------------------------------
747 : //
748 0 : void AWConvFunc::makeConvFunction(const ImageInterface<Complex>& image,
749 : const VisBuffer& vb,
750 : const Int wConvSize,
751 : const CountedPtr<PolOuterProduct>& pop,
752 : const Float pa,
753 : const Float dpa,
754 : const Vector<Double>& uvScale, const Vector<Double>& /*uvOffset*/,
755 : const Matrix<Double>& ,//vbFreqSelection,
756 : CFStore2& cfs2,
757 : CFStore2& cfwts2,
758 : Bool fillCF)
759 : {
760 0 : LogIO log_l(LogOrigin("AWConvFunc", "makeConvFunction[R&D]"));
761 : Int convSize, convSampling, polInUse;
762 0 : Double wScale=0.0; Int bandID_l=-1;
763 0 : Array<Complex> convFunc_l, convWeights_l;
764 0 : Double cfRefFreq=-1, freqScale=1e8;
765 0 : Quantity paQuant(pa,"rad");
766 :
767 :
768 0 : Int nx=image.shape()(0);//, ny=image.shape()(1);
769 0 : if (bandID_l == -1) bandID_l=getVisParams(vb,image.coordinates());
770 :
771 : log_l << "Making a new convolution function for PA="
772 0 : << pa*(180/C::pi) << "deg"
773 0 : << " for field ID " << vb.fieldId();
774 : // log_l << "TimeStamps(0-10) ";
775 : // for (Int i=0;i<10;i++)
776 : // //log_l << MVTime(vb.time()(i)).string(MVTime::TIME) << " ";
777 : // log_l << vb.time()(i)/1e8 << " ";
778 : // log_l << LogIO::NORMAL << LogIO::POST;
779 :
780 0 : if(wConvSize>0)
781 : {
782 0 : log_l << "Using " << wConvSize << " planes for W-projection" << LogIO::POST;
783 : Double maxUVW;
784 0 : maxUVW=0.25/abs(image.coordinates().increment()(0));
785 : log_l << "Estimating maximum possible W = " << maxUVW
786 0 : << " (wavelengths)" << LogIO::POST;
787 :
788 0 : Double invLambdaC=vb.frequency()(0)/C::c;
789 0 : Double invMinL = vb.frequency()((vb.frequency().nelements())-1)/C::c;
790 : log_l << "wavelength range = " << 1.0/invLambdaC << " (m) to "
791 0 : << 1.0/invMinL << " (m)" << LogIO::POST;
792 0 : if (wConvSize > 1)
793 : {
794 0 : wScale=Float((wConvSize-1)*(wConvSize-1))/maxUVW;
795 : log_l << "Scaling in W (at maximum W) = " << 1.0/wScale
796 0 : << " wavelengths per pixel" << LogIO::POST;
797 : }
798 : }
799 : //
800 : // Get the coordinate system
801 : //
802 0 : CoordinateSystem coords(image.coordinates());
803 : //
804 : // Set up the convolution function.
805 : //
806 : //convSampling=aTerm_p->getOversampling();
807 0 : convSampling=getOversampling(*psTerm_p, *wTerm_p, *aTerm_p);
808 0 : convSize=aTerm_p->getConvSize();
809 : // cout<<"Conv Sampling listed in aipsrc is : "<<convSampling<<endl;
810 : // cout<<"Conv Size is : "<<convSize<<endl;
811 : //
812 : // Make a two dimensional image to calculate auto-correlation of
813 : // the ideal illumination pattern. We want this on a fine grid in
814 : // the UV plane
815 : //
816 0 : Int index= coords.findCoordinate(Coordinate::SPECTRAL);
817 0 : SpectralCoordinate spCS = coords.spectralCoordinate(index);
818 0 : imRefFreq_p=spCS.referenceValue()(0);
819 :
820 0 : index=coords.findCoordinate(Coordinate::DIRECTION);
821 0 : AlwaysAssert(index>=0, AipsError);
822 0 : DirectionCoordinate dc=coords.directionCoordinate(index);
823 0 : Vector<Double> sampling;
824 0 : sampling = dc.increment();
825 : // cout<<"The image sampling is set to :"<<sampling<<endl;
826 0 : sampling*=Double(convSampling);
827 0 : sampling*=Double(nx)/Double(convSize);
828 : // cout<<"The resampled increment is :"<<sampling<<endl;
829 0 : dc.setIncrement(sampling);
830 :
831 0 : Vector<Double> unitVec(2);
832 0 : unitVec=convSize/2;
833 0 : dc.setReferencePixel(unitVec);
834 :
835 : // Set the reference value to that of the image
836 0 : coords.replaceCoordinate(dc, index);
837 : //
838 : // Make an image with circular polarization axis. Return the
839 : // no. of vis. poln. planes that will be used in making the user
840 : // defined Stokes image.
841 : //
842 0 : polInUse=aTerm_p->makePBPolnCoords(vb, convSize, convSampling,
843 : image.coordinates(),nx,nx,
844 0 : coords);//,feedStokes_l);
845 : //------------------------------------------------------------------
846 : // Make the sky Stokes PB. This will be used in the gridding
847 : // correction
848 : //------------------------------------------------------------------
849 0 : IPosition pbShape(4, convSize, convSize, polInUse, 1);
850 0 : TempImage<Complex> twoDPB(pbShape, coords);
851 0 : IPosition pbSqShp(pbShape);
852 :
853 0 : unitVec=pbSqShp[0]/2;
854 0 : dc.setReferencePixel(unitVec);
855 0 : coords.replaceCoordinate(dc, index);
856 :
857 0 : TempImage<Complex> twoDPBSq(pbSqShp,coords);
858 0 : twoDPB.set(Complex(1.0,0.0));
859 0 : twoDPBSq.set(Complex(1.0,0.0));
860 : //
861 : // Accumulate the various terms that constitute the gridding
862 : // convolution function.
863 : //
864 : //------------------------------------------------------------------
865 : // Int inner=convSize/convSampling;
866 : // CFStore2 cfs2_p, cfwts2_p;
867 0 : CountedPtr<CFBuffer> cfb_p, cfwtb_p;
868 : // cfs2.rememberATerm(aTerm_p);
869 : // cfwts2.rememberATerm(aTerm_p);
870 :
871 0 : Vector<Quantity> paList(1); paList[0]=paQuant;
872 : //
873 : // Determine the "Mueller Matrix" (called PolOuterProduct here for
874 : // a better name) elements to use based on the sky-Stokes planes
875 : // requested. PolOuterProduct::makePolMap() makes a
876 : // Matrix<Int>. The elements of this matrix has the index of the
877 : // convolution function for the pol. product. Unused elements are
878 : // set to -1. The physical definition of the PolOuterProduct
879 : // elements are as defined in Eq. 4 in A&A 487, 419-429 (2008)
880 : // (http://arxiv.org/abs/0805.0834).
881 : //
882 : // First detemine the list of Stokes requested. Then convert the
883 : // requested Stokes to the appropriate Pol cross-product. When
884 : // the off-diagonal elements of the outer-product are significant,
885 : // this will lead to more than one outer-product element per
886 : // Stokes.
887 : //
888 : // The code below still assume a diagonally dominant
889 : // outer-product. This probably OK for antena arrays. After the
890 : // debugging phase is over, the
891 : // Vector<PolOuterProduct::CrossCircular> should become
892 : // Matrix<PolOuterProduct> and PolOuterProduct should be
893 : // "templated" to be of type Circular or Linear.
894 : //
895 0 : StokesCoordinate skyStokesCo=coords.stokesCoordinate(coords.findCoordinate(Coordinate::STOKES));
896 0 : Vector<Int> skyStokes=skyStokesCo.stokes();
897 : //Vector<PolOuterProduct::CrossPolCircular> pp(skyStokes.nelements());
898 0 : PolMapType polMap, polIndexMap, conjPolMap, conjPolIndexMap;
899 0 : polMap = pop->getPolMat();
900 0 : polIndexMap = pop->getPol2CFMat();
901 0 : conjPolMap = pop->getConjPolMat();
902 0 : conjPolIndexMap = pop->getConjPol2CFMat();
903 :
904 : //cerr << "AWCF: " << polMap << endl << polIndexMap << endl << conjPolMap << endl << conjPolIndexMap << endl;
905 :
906 : // for(uInt ip=0;ip<pp.nelements();ip++)
907 : // pp(ip)=translateStokesToCrossPol(skyStokes(ip));
908 :
909 : // PolOuterProduct pOP; pOP.makePolMap(pp);
910 : // const Matrix<Int> muellerMatrix=pOP.getPolMap();
911 :
912 0 : Vector<Double> wValues = makeWValList(wScale, wConvSize);
913 0 : Vector<String> bandNames;
914 0 : Vector<Double> freqValues = makeFreqValList(freqScale,vb,image,bandNames);
915 0 : log_l << "Making " << wValues.nelements() << " w plane(s). " << LogIO::POST;
916 0 : log_l << "Making " << freqValues.nelements() << " frequency plane(s)." << LogIO::POST;
917 : //
918 : // If w-term is unity, we can scale the A-term with frequency. So
919 : // compute it only for the highest frequency involved.
920 : //
921 : //log_l << "Disabled scaling of CFs" << LogIO::WARN << LogIO::POST;
922 : // if (wConvSize <= 1)
923 : // {
924 : // Double rFreq = max(freqValues);
925 : // if (freqValues.nelements() > 1)
926 : // freqScale=2*(rFreq-min(freqValues));
927 : // freqValues.resize(1);freqValues(0)=rFreq;
928 : // }
929 : log_l << "CFB Freq. axis [N, Min, Max, Incr. (GHz)]: "
930 : << freqValues.nelements() << " "
931 0 : << min(freqValues)/1e9 << " "
932 0 : << max(freqValues)/1e9 << " "
933 : << freqScale/1e9
934 0 : << LogIO::POST;
935 : //
936 : // Re-size the CFStore object. It holds CFBuffers index by PA and
937 : // list of unique baselines (all possible pairs of unique antenna
938 : // types).
939 : //
940 0 : Matrix<Int> uniqueBaselineTypeList=makeBaselineList(aTerm_p->getAntTypeList());
941 : //Quantity dPA(360.0,"deg");
942 0 : Quantity dPA(dpa,"rad");
943 0 : Int totalCFs=uniqueBaselineTypeList.shape().product()*wConvSize*freqValues.nelements()*polMap.shape().product();
944 0 : ProgressMeter pm(1.0, Double(totalCFs), "makeCF", "","","",true);
945 0 : int cfDone=0;
946 0 : for(Int ib=0;ib<uniqueBaselineTypeList.shape()(0);ib++)
947 : {
948 0 : Vector<Int> pos;
949 0 : pos=cfs2.resize(paQuant, dPA, uniqueBaselineTypeList(ib,0), uniqueBaselineTypeList(ib,1));
950 0 : pos=cfwts2.resize(paQuant, dPA, uniqueBaselineTypeList(ib,0), uniqueBaselineTypeList(ib,1));
951 : //
952 : // Re-size the CFBuffer object. It holds the 2D convolution
953 : // functions index by (FreqValue, WValue, MuellerElement).
954 : //
955 0 : cfb_p=cfs2.getCFBuffer(paQuant, dPA, uniqueBaselineTypeList(ib,0),uniqueBaselineTypeList(ib,1));
956 0 : cfwtb_p=cfwts2.getCFBuffer(paQuant, dPA, uniqueBaselineTypeList(ib,0),uniqueBaselineTypeList(ib,1));
957 0 : cfb_p->setPointingOffset(pixFieldGrad_p);
958 : // cfb_p->resize(wValues,freqValues,muellerMatrix);
959 : // cfwtb_p->resize(wValues,freqValues,muellerMatrix);
960 :
961 0 : cfb_p->resize(wScale, freqScale, wValues,freqValues,polMap, polIndexMap,conjPolMap, conjPolIndexMap);
962 0 : cfwtb_p->resize(wScale, freqScale, wValues,freqValues,polMap, polIndexMap,conjPolMap, conjPolIndexMap);
963 :
964 0 : IPosition start(4, 0, 0, 0, 0);
965 0 : IPosition pbSlice(4, convSize, convSize, 1, 1);
966 :
967 0 : Matrix<Complex> screen(convSize, convSize);
968 : // WTerm wterm_l;
969 : // PSTerm psTerm_l;
970 :
971 : //Initiate construction of the "ConvolveGridder" object inside
972 : //PSTerm. This is, for historical reasons, used to access the
973 : //"standard" Prolate Spheroidal function implementaion. This
974 : //however should be replaced with a simpler access, direct
975 : //access the PS function implementation (in Utils.h
976 : //SynthesisUtils::libreSpheroidal() - but this needs more
977 : //testing).
978 0 : Int inner=convSize/(convSampling);
979 : // Float psScale= (image.coordinates().increment()(0)*nx) /
980 : // (coords.increment()(0)*screen.shape()(0));
981 :
982 0 : Float psScale = (2*coords.increment()(0))/(nx*image.coordinates().increment()(0)),
983 0 : innerQuaterFraction=1.0;
984 : // psScale when using SynthesisUtils::libreSpheroidal() is
985 : // 2.0/nSupport. nSupport is in pixels and the 2.0 is due to
986 : // the center being at Nx/2. Here the nSupport is determined
987 :
988 : // by the sky-image and is equal to convSize/convSampling.
989 0 : psScale = 2.0/(innerQuaterFraction*convSize/convSampling);// nx*image.coordinates().increment()(0)*convSampling/2;
990 0 : Vector<Double> uvOffset_cf(3,0); uvOffset_cf(0)=uvOffset_cf(2)=convSize/2;
991 0 : psTerm_p->init(IPosition(2,inner,inner), uvScale, uvOffset_cf,psScale);
992 :
993 0 : MuellerElementType muellerElement(0,0);
994 0 : CoordinateSystem cfb_cs=coords;
995 : //
996 : // Set up the Mueller matrix, the co-ordinate system, freq, and
997 : // wvalues in the CFBuffer for the currenct CFStore object.
998 : //
999 : //cerr<<"Mueller matrix of row length:"<<polMap.nelements()<<" at the start of the CFBuf Loop" <<endl;
1000 0 : for (Int iw=0;iw<wConvSize;iw++)
1001 : {
1002 0 : for(uInt inu=0;inu<freqValues.nelements(); inu++)
1003 : {
1004 0 : Int npol=0;
1005 0 : for (uInt ipolx=0;ipolx<polMap.nelements();ipolx++)
1006 : {
1007 0 : npol=0;
1008 0 : for (uInt ipoly=0;ipoly<polMap(ipolx).nelements();ipoly++)
1009 : {
1010 : // Now make a CS with a single appropriate
1011 : // polarization axis per Mueller element
1012 0 : Vector<Int> whichStokes(1,skyStokes(npol++));
1013 0 : Int sIndex=cfb_cs.findCoordinate(Coordinate::STOKES);
1014 0 : StokesCoordinate stokesCS=cfb_cs.stokesCoordinate(sIndex);
1015 0 : Int fIndex=coords.findCoordinate(Coordinate::SPECTRAL);
1016 0 : SpectralCoordinate spCS = coords.spectralCoordinate(fIndex);
1017 0 : Vector<Double> refValue, incr;
1018 0 : refValue = spCS.referenceValue();
1019 0 : incr = spCS.increment();
1020 0 : cfRefFreq=freqValues(inu);
1021 0 : refValue=cfRefFreq;
1022 0 : spCS.setReferenceValue(refValue);
1023 :
1024 0 : stokesCS.setStokes(whichStokes);
1025 0 : cfb_cs.replaceCoordinate(stokesCS,sIndex);
1026 0 : cfb_cs.replaceCoordinate(spCS,fIndex);
1027 : //
1028 : // Set the various axis-parameters for the CFBuffer.
1029 : //
1030 0 : Float s=convSampling;
1031 : // cfb_p->setParams(convSize,convSize,cfb_cs,s,
1032 : // convSize, convSize,
1033 : // freqValues(inu), wValues(iw), polMap(ipolx)(ipoly));
1034 : // cfwtb_p->setParams(convSize,convSize,cfb_cs,s,
1035 : // convSize, convSize,
1036 : // freqValues(inu), wValues(iw), polMap(ipolx)(ipoly));
1037 0 : cfb_p->setParams(inu, iw, ipolx,ipoly,//polMap(ipolx)(ipoly),
1038 0 : freqValues(inu), bandNames(inu), wValues(iw), polMap(ipolx)(ipoly),
1039 : cfb_cs, s, convSize, convSize);
1040 0 : cfwtb_p->setParams(inu, iw, ipolx,ipoly,//polMap(ipolx)(ipoly),
1041 0 : freqValues(inu), bandNames(inu), wValues(iw), polMap(ipolx)(ipoly),
1042 : cfb_cs, s, convSize, convSize);
1043 0 : pm.update((Double)cfDone++);
1044 : }
1045 : }
1046 : } // End of loop over Mueller elements.
1047 : } // End of loop over w
1048 : //
1049 : // By this point, the all the 4 axis (Time/PA, Freq, Pol,
1050 : // Baseline) of the CFBuffer objects have been setup. The CFs
1051 : // will now be filled using the supplied PS-, W- ad A-term objects.
1052 : //
1053 0 : if (fillCF) log_l << "Making CFs for baseline type " << ib << LogIO::POST;
1054 0 : else log_l << "Making empty CFs for baseline type " << ib << LogIO::POST;
1055 : {
1056 0 : Double vbPA = getPA(vb), freqHi;
1057 :
1058 :
1059 0 : Vector<Double> chanFreq = vb.frequency();
1060 0 : index = image.coordinates().findCoordinate(Coordinate::SPECTRAL);
1061 0 : SpectralCoordinate SpC = cfb_cs.spectralCoordinate(index);
1062 0 : Vector<Double> refVal = SpC.referenceValue();
1063 :
1064 0 : freqHi = refVal[0];
1065 0 : fillConvFuncBuffer(*cfb_p, *cfwtb_p, convSize, convSize, freqValues, wValues, wScale,
1066 : vbPA, freqHi,
1067 : polMap, polIndexMap, vb, psScale,
1068 0 : *psTerm_p, *wTerm_p, *aTerm_p, !fillCF);
1069 : }
1070 : // cfb_p->show(NULL,cerr);
1071 : //cfb_p->makePersistent("test.cf");
1072 : // cfwtb_p->makePersistent("test.wtcf");
1073 :
1074 : } // End of loop over baselines
1075 :
1076 0 : index=coords.findCoordinate(Coordinate::SPECTRAL);
1077 0 : spCS = coords.spectralCoordinate(index);
1078 0 : Vector<Double> refValue; refValue.resize(1);refValue(0)=cfRefFreq;
1079 0 : spCS.setReferenceValue(refValue);
1080 0 : coords.replaceCoordinate(spCS,index);
1081 :
1082 : // cfs.coordSys=coords; cfwts.coordSys=coords;
1083 : // cfs.pa=paQuant; cfwts.pa=paQuant;
1084 :
1085 : // aTerm_p->makeConvFunction(image,vb,wConvSize,pa,cfs,cfwts);
1086 0 : }
1087 : //
1088 : //----------------------------------------------------------------------
1089 : //
1090 0 : Bool AWConvFunc::setUpCFSupport(Array<Complex>& cfVals, Int& xSupport, Int& ySupport,
1091 : const Float& sampling, const Complex& peak)
1092 : {
1093 0 : LogIO log_l(LogOrigin("AWConvFunc", "setUpCFSupport[R&D]"));
1094 : //
1095 : // Find the convolution function support size. No assumption
1096 : // about the symmetry of the conv. func. can be made (except that
1097 : // they are same for all poln. planes).
1098 : //
1099 0 : xSupport = ySupport = -1;
1100 0 : Int convFuncOrigin=cfVals.shape()[0]/2, R;
1101 0 : Bool found=false;
1102 : Float threshold;
1103 : // Threshold as a fraction of the peak (presumed to be the center pixel).
1104 0 : if (abs(peak) != 0) threshold = real(abs(peak));
1105 : else
1106 0 : threshold = real(abs(cfVals(IPosition(4,convFuncOrigin,convFuncOrigin,0,0))));
1107 :
1108 : //threshold *= aTerm_p->getSupportThreshold();
1109 0 : threshold *= 1e-3;
1110 : // threshold *= 0.1;
1111 : // if (aTerm_p->isNoOp())
1112 : // threshold *= 1e-3; // This is the threshold used in "standard" FTMchines
1113 : // else
1114 :
1115 : //
1116 : // Find the support size of the conv. function in pixels
1117 : //
1118 : // Timer tim;
1119 : // tim.mark();
1120 0 : if ((found = AWConvFunc::awFindSupport(cfVals,threshold,convFuncOrigin,R)))
1121 0 : xSupport=ySupport=Int(0.5+Float(R)/sampling)+1;
1122 : // tim.show("findSupport:");
1123 :
1124 : // If the support size overflows, give a warning and set the
1125 : // support size to be convFuncSize/2 + the max. possible offset in
1126 : // the oversamplied grid. The max. possible offset would 0.5
1127 : // pixels on the sky, which would be sampling/2.0.
1128 : //
1129 : // If the extra buffer (max(offset)) is not included, the problem
1130 : // will show up when gridding the data or weights. It will not
1131 : // show up when making the avgPB since the gridding for that is
1132 : // always centered on the center of the image.
1133 0 : if ((xSupport*sampling + int(sampling/2.0+0.5)) > convFuncOrigin)
1134 : {
1135 : log_l << "Convolution function support size > N/2. Limiting it to N/2 "
1136 : << "(threshold = " << threshold << ")."
1137 0 : << LogIO::WARN;
1138 0 : xSupport = ySupport = (Int)(convFuncOrigin/sampling-1);
1139 : }
1140 :
1141 0 : if(xSupport<1)
1142 : log_l << "Convolution function is misbehaved - support seems to be zero"
1143 0 : << LogIO::EXCEPTION;
1144 0 : return found;
1145 : }
1146 : //
1147 : //----------------------------------------------------------------------
1148 : //
1149 0 : Bool AWConvFunc::resizeCF(Array<Complex>& cfVals, Int& xSupport, Int& ySupport,
1150 : const Int& supportBuffer, const Float& sampling, const Complex& peak)
1151 : {
1152 0 : LogIO log_l(LogOrigin("AWConvFunc", "resizeCF[R&D]"));
1153 0 : Int ConvFuncOrigin=cfVals.shape()[0]/2; // Conv. Func. is half that size of convSize
1154 :
1155 0 : Bool found = setUpCFSupport(cfVals, xSupport, ySupport, sampling,peak);
1156 :
1157 : //Int supportBuffer = (Int)(aTerm_p->getOversampling()*1.5);
1158 0 : Int bot=(Int)(ConvFuncOrigin-sampling*xSupport-supportBuffer),//-convSampling/2,
1159 0 : top=(Int)(ConvFuncOrigin+sampling*xSupport+supportBuffer);//+convSampling/2;
1160 : // bot *= 2; top *= 2;
1161 0 : bot = max(0,bot);
1162 0 : top = min(top, cfVals.shape()(0)-1);
1163 :
1164 0 : Array<Complex> tmp;
1165 0 : IPosition blc(4,bot,bot,0,0), trc(4,top,top,0,0);
1166 : //
1167 : // Cut out the conv. func., copy in a temp. array, resize the
1168 : // CFStore.data, and copy the cutout version to CFStore.data.
1169 : //
1170 0 : tmp = cfVals(blc,trc);
1171 0 : cfVals.resize(tmp.shape());
1172 0 : cfVals = tmp;
1173 0 : return found;
1174 : }
1175 : //
1176 : //----------------------------------------------------------------------
1177 : // A global method for use in OMP'ed findSupport() below
1178 : //
1179 0 : void archPeak(const Float& threshold, const Int& origin, const Block<Int>& cfShape, const Complex* cfValsPtr,
1180 : const Int& nCFS, const Int& PixInc,const Int& th, const Int& R, Block<Int>& maxR)
1181 : {
1182 0 : Block<Complex> vals;
1183 0 : Block<Int> ndx(nCFS); ndx=0;
1184 : Int NSteps;
1185 : //Check every PixInc pixel along a circle of radius R
1186 0 : NSteps = 90*R/PixInc;
1187 0 : vals.resize((Int)(NSteps+0.5));
1188 0 : uInt valsNelements=vals.nelements();
1189 0 : vals=0;
1190 :
1191 0 : for(Int pix=0;pix<NSteps;pix++)
1192 : {
1193 0 : ndx[0]=(int)(origin + R*sin(2.0*M_PI*pix*PixInc/R));
1194 0 : ndx[1]=(int)(origin + R*cos(2.0*M_PI*pix*PixInc/R));
1195 :
1196 0 : if ((ndx[0] < cfShape[0]) && (ndx[1] < cfShape[1]))
1197 : //vals[pix]=cfVals(ndx);
1198 0 : vals[pix]=cfValsPtr[ndx[0]+ndx[1]*cfShape[1]+ndx[2]*cfShape[2]+ndx[3]*cfShape[3]];
1199 : }
1200 :
1201 0 : maxR[th]=-R;
1202 0 : for (uInt i=0;i<valsNelements;i++)
1203 0 : if (fabs(vals[i]) > threshold)
1204 : {
1205 0 : maxR[th]=R;
1206 0 : break;
1207 : }
1208 : // th++;
1209 0 : }
1210 : //
1211 : //----------------------------------------------------------------------
1212 : //
1213 0 : Bool AWConvFunc::findSupport(Array<Complex>& cfVals, Float& threshold,
1214 : Int& origin, Int& radius)
1215 : {
1216 0 : return awFindSupport(cfVals, threshold, origin, radius);
1217 : }
1218 0 : Bool AWConvFunc::awFindSupport(Array<Complex>& cfVals, Float& threshold,
1219 : Int& origin, Int& radius)
1220 : {
1221 0 : LogIO log_l(LogOrigin("AWConvFunc", "findSupport[R&D]"));
1222 :
1223 0 : Int nCFS=cfVals.shape().nelements(),
1224 0 : PixInc=1, R0, R1, R, convSize;
1225 0 : Block<Int> cfShape(nCFS);
1226 0 : Bool found=false;
1227 : Complex *cfValsPtr;
1228 : Bool dummy;
1229 0 : uInt Nth=1, threadID=0;
1230 :
1231 0 : for (Int i=0;i<nCFS;i++)
1232 0 : cfShape[i]=cfVals.shape()[i];
1233 0 : convSize = cfShape[0];
1234 :
1235 : #ifdef _OPENMP
1236 0 : Nth = max(omp_get_max_threads()-2,1);
1237 : #endif
1238 :
1239 0 : Block<Int> maxR(Nth);
1240 :
1241 0 : cfValsPtr = cfVals.getStorage(dummy);
1242 :
1243 0 : R1 = convSize/2-2;
1244 :
1245 0 : while (R1 > 1)
1246 : {
1247 0 : R0 = R1; R1 -= Nth;
1248 :
1249 : //#pragma omp parallel default(none) firstprivate(R0,R1) private(R,threadID) shared(origin,threshold,PixInc,maxR,cfShape,nCFS,cfValsPtr) num_threads(Nth)
1250 0 : #pragma omp parallel firstprivate(R0,R1) private(R,threadID) shared(PixInc,maxR,cfShape,nCFS,cfValsPtr) num_threads(Nth)
1251 : {
1252 : #pragma omp for
1253 : for(R=R0;R>R1;R--)
1254 : {
1255 : #ifdef _OPENMP
1256 : threadID=omp_get_thread_num();
1257 : #endif
1258 : archPeak(threshold, origin, cfShape, cfValsPtr, nCFS, PixInc, threadID, R, maxR);
1259 : }
1260 : }///omp
1261 :
1262 0 : for (uInt th=0;th<Nth;th++)
1263 0 : if (maxR[th] > 0)
1264 0 : {found=true; radius=maxR[th]; return found;}
1265 : }
1266 0 : return found;
1267 : }
1268 : //
1269 : //----------------------------------------------------------------------
1270 : //
1271 : // Bool AWConvFunc::findSupport(Array<Complex>& func, Float& threshold,
1272 : // Int& origin, Int& R)
1273 : // {
1274 : // LogIO log_l(LogOrigin("AWConvFunc", "findSupport[R&D]"));
1275 : // Double NSteps;
1276 : // Int PixInc=1;
1277 : // Vector<Complex> vals;
1278 : // IPosition ndx(4,origin,0,0,0);
1279 : // Bool found=false;
1280 : // IPosition cfShape=func.shape();
1281 : // Int convSize = cfShape(0);
1282 :
1283 : // for(R=convSize/2-2;R>1;R--)
1284 : // {
1285 : // //Check every PixInc pixel along a circle of radius R
1286 : // NSteps = 90*R/PixInc;
1287 : // vals.resize((Int)(NSteps+0.5));
1288 : // vals=0;
1289 : // for(Int th=0;th<NSteps;th++)
1290 : // {
1291 : // ndx(0)=(int)(origin + R*sin(2.0*M_PI*th*PixInc/R));
1292 : // ndx(1)=(int)(origin + R*cos(2.0*M_PI*th*PixInc/R));
1293 :
1294 : // if ((ndx(0) < cfShape(0)) && (ndx(1) < cfShape(1)))
1295 : // vals(th)=func(ndx);
1296 : // }
1297 :
1298 : // if (max(abs(vals)) > threshold)
1299 : // {found=true;break;}
1300 : // }
1301 : // return found;
1302 : // }
1303 : //
1304 : //----------------------------------------------------------------------
1305 : //
1306 0 : Bool AWConvFunc::makeAverageResponse(const VisBuffer& vb,
1307 : const ImageInterface<Complex>& image,
1308 : ImageInterface<Float>& theavgPB,
1309 : Bool reset)
1310 : {
1311 0 : TempImage<Complex> complexPB;
1312 : Bool pbMade;
1313 0 : pbMade = makeAverageResponse(vb, image, complexPB,reset);
1314 0 : normalizeAvgPB(complexPB, theavgPB);
1315 0 : return pbMade;
1316 : }
1317 : //
1318 : //----------------------------------------------------------------------
1319 : //
1320 0 : Bool AWConvFunc::makeAverageResponse(const VisBuffer& vb,
1321 : const ImageInterface<Complex>& image,
1322 : ImageInterface<Complex>& theavgPB,
1323 : Bool reset)
1324 : {
1325 0 : LogIO log_l(LogOrigin("AWConvFunc","makeAverageResponse(Complex)[R&D]"));
1326 :
1327 0 : log_l << "Making the average response for " << aTerm_p->name()
1328 0 : << LogIO::NORMAL << LogIO::POST;
1329 :
1330 0 : if (reset)
1331 : {
1332 : log_l << "Initializing the average PBs"
1333 0 : << LogIO::NORMAL << LogIO::POST;
1334 0 : theavgPB.resize(image.shape());
1335 0 : theavgPB.setCoordinateInfo(image.coordinates());
1336 0 : theavgPB.set(1.0);
1337 : }
1338 :
1339 0 : aTerm_p->applySky(theavgPB, vb, true, 0);
1340 :
1341 0 : return true; // i.e., an average PB was made
1342 : }
1343 : //
1344 : //----------------------------------------------------------------------
1345 : //
1346 0 : void AWConvFunc::normalizeAvgPB(ImageInterface<Complex>& inImage,
1347 : ImageInterface<Float>& outImage)
1348 : {
1349 0 : LogIO log_l(LogOrigin("AWConvFunc", "normalizeAvgPB[R&D]"));
1350 :
1351 0 : String name("avgpb.im");
1352 0 : storeImg(name,inImage);
1353 0 : IPosition inShape(inImage.shape()),ndx(4,0,0,0,0);
1354 0 : Vector<Complex> peak(inShape(2));
1355 :
1356 0 : outImage.resize(inShape);
1357 0 : outImage.setCoordinateInfo(inImage.coordinates());
1358 :
1359 : Bool isRefIn;
1360 0 : Array<Complex> inBuf;
1361 0 : Array<Float> outBuf;
1362 :
1363 0 : isRefIn = inImage.get(inBuf);
1364 : //isRefOut = outImage.get(outBuf);
1365 : log_l << "Normalizing the average PBs to unity"
1366 0 : << LogIO::NORMAL << LogIO::POST;
1367 : //
1368 : // Normalize each plane of the inImage separately to unity.
1369 : //
1370 0 : Complex inMax = max(inBuf);
1371 0 : if (abs(inMax)-1.0 > 1E-3)
1372 : {
1373 0 : for(ndx(3)=0;ndx(3)<inShape(3);ndx(3)++)
1374 0 : for(ndx(2)=0;ndx(2)<inShape(2);ndx(2)++)
1375 : {
1376 0 : peak(ndx(2)) = 0;
1377 0 : for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
1378 0 : for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
1379 0 : if (abs(inBuf(ndx)) > peak(ndx(2)))
1380 0 : peak(ndx(2)) = inBuf(ndx);
1381 :
1382 0 : for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
1383 0 : for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
1384 : // avgPBBuf(ndx) *= (pbPeaks(ndx(2))/peak(ndx(2)));
1385 0 : inBuf(ndx) /= peak(ndx(2));
1386 : }
1387 0 : if (isRefIn) inImage.put(inBuf);
1388 : }
1389 :
1390 0 : ndx=0;
1391 0 : for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
1392 0 : for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
1393 : {
1394 0 : IPosition plane1(ndx);
1395 0 : plane1=ndx;
1396 0 : plane1(2)=1; // The other poln. plane
1397 : // avgPBBuf(ndx) = (avgPBBuf(ndx) + avgPBBuf(plane1))/2.0;
1398 0 : outBuf(ndx) = sqrt(real(inBuf(ndx) * inBuf(plane1)));
1399 : }
1400 : //
1401 : // Rather convoluted way of copying Pol. plane-0 to Pol. plane-1!!!
1402 : //
1403 0 : for(ndx(1)=0;ndx(1)<inShape(1);ndx(1)++)
1404 0 : for(ndx(0)=0;ndx(0)<inShape(0);ndx(0)++)
1405 : {
1406 0 : IPosition plane1(ndx);
1407 0 : plane1=ndx;
1408 0 : plane1(2)=1; // The other poln. plane
1409 0 : outBuf(plane1) = real(outBuf(ndx));
1410 : }
1411 0 : }
1412 : //
1413 : //-------------------------------------------------------------------------
1414 : // Legacy code. Should ultimately be deleteted after re-facatoring
1415 : // is finished.
1416 : //
1417 0 : Bool AWConvFunc::makeAverageResponse_org(const VisBuffer& vb,
1418 : const ImageInterface<Complex>& image,
1419 : ImageInterface<Float>& theavgPB,
1420 : Bool reset)
1421 : {
1422 0 : LogIO log_l(LogOrigin("AWConvFunc", "makeAverageResponse_org[R&D]"));
1423 0 : TempImage<Float> localPB;
1424 :
1425 : log_l << "Making the average response for "
1426 0 : << aTerm_p->name()
1427 0 : << LogIO::NORMAL << LogIO::POST;
1428 :
1429 0 : localPB.resize(image.shape()); localPB.setCoordinateInfo(image.coordinates());
1430 0 : if (reset)
1431 : {
1432 0 : log_l << "Initializing the average PBs" << LogIO::NORMAL << LogIO::POST;
1433 0 : theavgPB.resize(localPB.shape());
1434 0 : theavgPB.setCoordinateInfo(localPB.coordinates());
1435 0 : theavgPB.set(0.0);
1436 : }
1437 : //
1438 : // Make the Stokes PB
1439 : //
1440 0 : localPB.set(1.0);
1441 :
1442 : // Block<CountedPtr<ImageInterface<Float > > > tmpBlock(1);
1443 : // tmpBlock[0]=CountedPtr<ImageInterface<Float> >(&localPB, false);
1444 : // aTerm_p->applySky(tmpBlock, vb, 0, false);
1445 0 : aTerm_p->applySky(localPB, vb, false, 0);
1446 :
1447 0 : IPosition twoDPBShape(localPB.shape());
1448 0 : TempImage<Complex> localTwoDPB(twoDPBShape,localPB.coordinates());
1449 : // localTwoDPB.setMaximumCacheSize(cachesize);
1450 : Int NAnt;
1451 0 : NAnt=1;
1452 :
1453 0 : for(Int ant=0;ant<NAnt;ant++)
1454 : { //Ant loop
1455 : {
1456 0 : IPosition ndx(4,0,0,0,0);
1457 0 : for(ndx(0)=0; ndx(0)<twoDPBShape(0); ndx(0)++)
1458 0 : for(ndx(1)=0; ndx(1)<twoDPBShape(1); ndx(1)++)
1459 0 : for(ndx(2)=0; ndx(2)<twoDPBShape(2); ndx(2)++)
1460 0 : for(ndx(3)=0; ndx(3)<twoDPBShape(3); ndx(3)++)
1461 0 : localTwoDPB.putAt(Complex((localPB(ndx)),0.0),ndx);
1462 : }
1463 : //
1464 : // Accumulate the shifted PBs
1465 : //
1466 : {
1467 : Bool isRefF;
1468 0 : Array<Float> fbuf;
1469 0 : Array<Complex> cbuf;
1470 0 : isRefF=theavgPB.get(fbuf);
1471 : //isRefC=localTwoDPB.get(cbuf);
1472 :
1473 0 : IPosition fs(fbuf.shape());
1474 0 : IPosition ndx(4,0,0,0,0),avgNDX(4,0,0,0,0);
1475 0 : for(ndx(3)=0,avgNDX(3)=0;ndx(3)<fs(3);ndx(3)++,avgNDX(3)++)
1476 0 : for(ndx(2)=0,avgNDX(2)=0;ndx(2)<twoDPBShape(2);ndx(2)++,avgNDX(2)++)
1477 0 : for(ndx(0)=0,avgNDX(0)=0;ndx(0)<fs(0);ndx(0)++,avgNDX(0)++)
1478 0 : for(ndx(1)=0,avgNDX(1)=0;ndx(1)<fs(1);ndx(1)++,avgNDX(1)++)
1479 : {
1480 : Float val;
1481 0 : val = real(cbuf(ndx));
1482 0 : fbuf(avgNDX) += val;
1483 : }
1484 0 : if (!isRefF) theavgPB.put(fbuf);
1485 : }
1486 : }
1487 0 : theavgPB.setCoordinateInfo(localPB.coordinates());
1488 0 : return true; // i.e., an average PB was made
1489 : }
1490 : //
1491 : //----------------------------------------------------------------------
1492 : //
1493 0 : void AWConvFunc::prepareConvFunction(const VisBuffer& vb, VBRow2CFBMapType& theMap)
1494 : {
1495 0 : if (aTerm_p->rotationallySymmetric() == false) return;
1496 0 : Int nRow=theMap.nelements();
1497 : // CountedPtr<CFBuffer> cfb, cbPtr;
1498 : // CountedPtr<CFCell> cfc;
1499 : // CountedPtr<ATerm> aTerm_l=aTerm_p;
1500 0 : CFBuffer *cfb, *cbPtr=0;
1501 0 : CFCell *cfc, *baseCFC=NULL;
1502 0 : ATerm *aTerm_l=&*aTerm_p;
1503 :
1504 0 : cfb=&*(theMap(0));
1505 0 : cfc = &*(cfb->getCFCellPtr(0,0,0));
1506 0 : Double actualPA = getPA(vb), currentCFPA = cfc->pa_p.getValue("rad");
1507 0 : Double dPA = currentCFPA-actualPA;
1508 :
1509 0 : if (fabs(dPA) <= fabs(rotateCFOTFAngleRad_p)) return;
1510 :
1511 0 : LogIO log_l(LogOrigin("AWConvFunc", "prepareConvFunction"));
1512 :
1513 : // Int Nth=1;
1514 : // #ifdef _OPENMP
1515 : // Nth=max(omp_get_max_threads()-2,1);
1516 : // #endif
1517 0 : for (Int irow=0;irow<nRow;irow++)
1518 : {
1519 0 : cfb=&*(theMap(irow));
1520 : // if ((!cfb.null()) && (cfb != cbPtr))
1521 0 : if ((cfb!=NULL) && (cfb != cbPtr))
1522 : {
1523 : // baseCFB_p = cfb->clone();
1524 : // cerr << "NRef = " << baseCFB_p.nrefs() << endl;
1525 : //
1526 : // If the following messsage is emitted more than once, we
1527 : // are in a heterogeneous-array case
1528 : //
1529 0 : log_l << "Rotating the base CFB from PA=" << cfb->getCFCellPtr(0,0,0)->pa_p.getValue("deg")
1530 : << " to " << actualPA*57.2957795131
1531 0 : << " " << cfb->getCFCellPtr(0,0,0)->shape_p
1532 0 : << LogIO::DEBUG1 << LogIO::POST;
1533 :
1534 0 : IPosition shp(cfb->shape());
1535 0 : cbPtr = cfb;
1536 0 : for(Int k=0;k<shp(2);k++) // Mueller-loop
1537 0 : for(Int j=0;j<shp(1);j++) // W-loop
1538 : // #pragma omp parallel default(none) firstprivate(j,k) shared(shp,cfb,aTerm_l) num_threads(Nth)
1539 : {
1540 : // #pragma omp for
1541 0 : for (Int i=0;i<shp(0);i++) // Chan-loop
1542 : {
1543 0 : cfc = &*(cfb->getCFCellPtr(i,j,k));
1544 :
1545 : //baseCFC = &*(baseCFB_p->getCFCellPtr(i,j,k));
1546 : // Call this for every VB. Any optimization
1547 : // (e.g. rotating at some increment only) is
1548 : // implemented in the ATerm::rotate().
1549 : // if (rotateCF_p)
1550 :
1551 : // Rotate the cell only if it has been loaded.
1552 0 : if (cfc->getShape().product() > 0)
1553 0 : aTerm_l->rotate2(vb,*baseCFC, *cfc,rotateCFOTFAngleRad_p);
1554 : }
1555 : }
1556 : }
1557 : }
1558 : };
1559 : //
1560 : //----------------------------------------------------------------------
1561 : //
1562 0 : void AWConvFunc::setMiscInfo(const RecordInterface& params)
1563 : {
1564 : (void)params;
1565 0 : }
1566 : //
1567 : // REFACTORED CODE
1568 : //
1569 :
1570 : //
1571 : //----------------------------------------------------------------------
1572 : //
1573 0 : void AWConvFunc::fillConvFuncBuffer2(CFBuffer& cfb, CFBuffer& cfWtb,
1574 : const Int& nx, const Int& ny,
1575 : const ImageInterface<Complex>& skyImage,
1576 : //const CoordinateSystem& skyCoords,
1577 : const CFCStruct& miscInfo,
1578 : PSTerm& psTerm, WTerm& wTerm, ATerm& aTerm,
1579 : Bool conjPB)
1580 :
1581 : {
1582 0 : LogIO log_l(LogOrigin("AWConvFunc", "fillConvFuncBuffer2[R&D]"));
1583 0 : Complex cfNorm, cfWtNorm;
1584 0 : Complex cpeak;
1585 : {
1586 : Float sampling, samplingWt;
1587 : Int xSupport, ySupport, xSupportWt, ySupportWt;
1588 0 : CoordinateSystem cs_l;
1589 : // Extract the parameters index by (MuellerElement, Freq, W)
1590 0 : cfWtb.getParams(cs_l, samplingWt, xSupportWt, ySupportWt,
1591 0 : miscInfo.freqValue,
1592 : // wValues(iw),
1593 0 : miscInfo.wValue,
1594 0 : miscInfo.muellerElement);
1595 0 : cfb.getParams(cs_l, sampling, xSupport, ySupport,
1596 0 : miscInfo.freqValue,
1597 0 : miscInfo.wValue,
1598 0 : miscInfo.muellerElement);
1599 : //
1600 : // Cache the A-Term for this polarization and frequency
1601 : //
1602 : Double conjFreq, vbPA;
1603 0 : CountedPtr<CFCell> thisCell=cfb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement);
1604 0 : vbPA = thisCell->pa_p.getValue("rad");
1605 0 : conjFreq = thisCell->conjFreq_p;
1606 0 : CoordinateSystem conjPolCS_l=cs_l; AWConvFunc::makeConjPolAxis(conjPolCS_l, thisCell->conjPoln_p);
1607 0 : IPosition pbshp(4,nx,ny,1,1);
1608 0 : TempImage<Complex> ftATerm_l(pbshp, cs_l), ftATermSq_l(pbshp,conjPolCS_l);
1609 0 : Bool doSquint=true;
1610 0 : ftATerm_l.set(Complex(1.0,0.0)); ftATermSq_l.set(Complex(1.0,0.0));
1611 0 : Double freq_l=miscInfo.freqValue;
1612 :
1613 : {
1614 0 : aTerm.applySky(ftATerm_l, vbPA, doSquint, 0, miscInfo.muellerElement,freq_l);//freqHi);
1615 :
1616 0 : if (conjPB) aTerm.applySky(ftATermSq_l, vbPA, doSquint, 0,miscInfo.muellerElement,conjFreq);
1617 0 : else aTerm.applySky(ftATermSq_l, vbPA, doSquint, 0,miscInfo.muellerElement,freq_l);
1618 : }
1619 :
1620 0 : Vector<Double> cellSize;
1621 : {
1622 0 : CoordinateSystem skyCoords(skyImage.coordinates());
1623 0 : Int directionIndex=skyCoords.findCoordinate(Coordinate::DIRECTION);
1624 0 : DirectionCoordinate dc=skyCoords.directionCoordinate(directionIndex);
1625 0 : cellSize = dc.increment()*(Double)(miscInfo.sampling*skyImage.shape()(0)/nx); // nx is the size of the CF buffer
1626 : }
1627 :
1628 : //
1629 : // Now compute the PS x W-Term and apply the cached
1630 : // A-Term to build the full CF.
1631 : //
1632 : {
1633 : log_l << " CF("
1634 0 : << "M:"<< miscInfo.muellerElement
1635 0 : << ",C:" << miscInfo.freqValue/1e9
1636 0 : << ",W:" << miscInfo.wValue << "): ";
1637 0 : Array<Complex> &cfWtBuf=(*(cfWtb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement))->storage_p);
1638 0 : Array<Complex> &cfBuf=(*(cfb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement))->storage_p);
1639 :
1640 0 : cfWtBuf.resize(pbshp);
1641 0 : cfBuf.resize(pbshp);
1642 :
1643 0 : const Vector<Double> sampling_l(2,sampling);
1644 0 : Matrix<Complex> cfBufMat(cfBuf.nonDegenerate()),
1645 0 : cfWtBufMat(cfWtBuf.nonDegenerate());
1646 : //
1647 : // Apply the Prolate Spheroidal and W-Term kernels
1648 : //
1649 0 : Vector<Double> s(2); s=sampling;
1650 : //Timer tim;
1651 : //tim.mark();
1652 0 : if (psTerm.isNoOp())
1653 0 : cfBufMat = cfWtBufMat = 1.0;
1654 : else
1655 : {
1656 : // psTerm.applySky(cfBufMat, False); // Assign (psScale set in psTerm.init()
1657 : // psTerm.applySky(cfWtBufMat, False); // Assign
1658 0 : psTerm.applySky(cfBufMat, s, cfBufMat.shape()(0)/s(0)); // Assign (psScale set in psTerm.init()
1659 0 : psTerm.applySky(cfWtBufMat, s, cfWtBufMat.shape()(0)/s(0)); // Assign
1660 0 : cfWtBuf *= cfWtBuf;
1661 : }
1662 :
1663 : //tim.mark();
1664 0 : if (miscInfo.wValue > 0)
1665 0 : wTerm.applySky(cfBufMat, cellSize, miscInfo.wValue, cfBuf.shape()(0));///4);
1666 0 : IPosition PolnPlane(4,0,0,0,0),
1667 0 : pbShape(4, cfBuf.shape()(0), cfBuf.shape()(1), 1, 1);
1668 : //
1669 : // Make TempImages and copy the buffers with PS *
1670 : // WKernel applied (too bad that TempImages can't be
1671 : // made with existing buffers)
1672 : //
1673 : //-------------------------------------------------------------
1674 0 : TempImage<Complex> twoDPB_l(pbShape, cs_l);
1675 0 : TempImage<Complex> twoDPBSq_l(pbShape,cs_l);
1676 : //-------------------------------------------------------------
1677 : // WBAWP CODE BEGIN -- ftATermSq_l has conj. PolCS
1678 0 : cfWtBuf *= ftATerm_l.get()*conj(ftATermSq_l.get());
1679 :
1680 : //tim.mark();
1681 0 : cfBuf *= ftATerm_l.get();
1682 : //tim.show("W*A*2: ");
1683 : // WBAWP CODE END
1684 : //tim.mark();
1685 0 : twoDPB_l.putSlice(cfBuf, PolnPlane);
1686 0 : twoDPBSq_l.putSlice(cfWtBuf, PolnPlane);
1687 : //tim.show("putSlice:");
1688 :
1689 : // To accumulate avgPB2, call this function.
1690 : // PBSQWeight
1691 : // Bool PBSQ = false;
1692 : // if(PBSQ) makePBSq(twoDPBSq_l);
1693 :
1694 : //
1695 : // Set the ref. freq. of the co-ordinate system to
1696 : // that set by ATerm::applySky().
1697 : //
1698 : //tim.mark();
1699 0 : CoordinateSystem cs=twoDPB_l.coordinates();
1700 0 : Int index= twoDPB_l.coordinates().findCoordinate(Coordinate::SPECTRAL);
1701 0 : SpectralCoordinate SpCS = twoDPB_l.coordinates().spectralCoordinate(index);
1702 :
1703 0 : Double cfRefFreq=SpCS.referenceValue()(0);
1704 0 : Vector<Double> refValue; refValue.resize(1); refValue(0)=cfRefFreq;
1705 0 : SpCS.setReferenceValue(refValue);
1706 0 : cs.replaceCoordinate(SpCS,index);
1707 :
1708 : //tim.mark();
1709 : {
1710 0 : LatticeFFT::cfft2d(twoDPB_l);
1711 0 : LatticeFFT::cfft2d(twoDPBSq_l);
1712 : }
1713 : //tim.show("FFT*2:");
1714 :
1715 : //tim.mark();
1716 0 : IPosition shp(twoDPB_l.shape());
1717 0 : IPosition start(4, 0, 0, 0, 0), pbSlice(4, shp[0]-1, shp[1]-1,1/*polInUse*/, 1),
1718 0 : sliceLength(4,cfBuf.shape()[0]-1,cfBuf.shape()[1]-1,1,1);
1719 :
1720 0 : cfBuf(Slicer(start,sliceLength)).nonDegenerate()
1721 0 : =(twoDPB_l.getSlice(start, pbSlice, true));
1722 :
1723 0 : shp = twoDPBSq_l.shape();
1724 0 : IPosition pbSqSlice(4, shp[0]-1, shp[1]-1, 1, 1),
1725 0 : sqSliceLength(4,cfWtBuf.shape()(0)-1,cfWtBuf.shape()[1]-1,1,1);
1726 :
1727 0 : cfWtBuf(Slicer(start,sqSliceLength)).nonDegenerate()
1728 0 : =(twoDPBSq_l.getSlice(start, pbSqSlice, true));
1729 : //tim.show("Slicer*2:");
1730 :
1731 : //tim.mark();
1732 0 : Int supportBuffer = (Int)(AWConvFunc::getOversampling(psTerm, wTerm, aTerm)*2.0);
1733 :
1734 0 : AWConvFunc::resizeCF(cfWtBuf, xSupportWt, ySupportWt, supportBuffer, samplingWt,0.0);
1735 : //tim.show("Resize:");
1736 :
1737 : //tim.mark();
1738 0 : Vector<Double> ftRef(2);
1739 0 : ftRef(0)=cfWtBuf.shape()(0)/2.0;
1740 0 : ftRef(1)=cfWtBuf.shape()(1)/2.0;
1741 0 : CoordinateSystem ftCoords=cs_l;
1742 0 : SynthesisUtils::makeFTCoordSys(cs_l, cfWtBuf.shape()(0), ftRef, ftCoords);
1743 :
1744 0 : thisCell=cfWtb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement);
1745 0 : thisCell->pa_p=Quantity(vbPA,"rad");
1746 0 : thisCell->coordSys_p = ftCoords;
1747 0 : thisCell->xSupport_p = xSupportWt;
1748 0 : thisCell->ySupport_p = ySupportWt;
1749 0 : thisCell->isRotationallySymmetric_p = aTerm.isNoOp();
1750 : //tim.show("CSStuff:");
1751 :
1752 : //tim.mark();
1753 : {
1754 0 : cpeak = max(cfBuf);
1755 0 : cfBuf /= cpeak;
1756 : }
1757 : //tim.show("Peaknorm:");
1758 :
1759 0 : AWConvFunc::resizeCF(cfBuf, xSupport, ySupport, supportBuffer, sampling,0.0);
1760 :
1761 0 : log_l << "CF Support: " << xSupport << " (" << xSupportWt << ") " << "pixels" << LogIO::POST;
1762 :
1763 0 : ftRef(0)=cfBuf.shape()(0)/2.0;
1764 0 : ftRef(1)=cfBuf.shape()(1)/2.0;
1765 :
1766 : //tim.mark();
1767 : // if (miscInfo.wValue == 0)
1768 : {
1769 0 : cfNorm=0; cfWtNorm=0;
1770 0 : cfNorm = AWConvFunc::cfArea(cfBufMat, xSupport, ySupport, sampling);
1771 0 : cfWtNorm = AWConvFunc::cfArea(cfWtBufMat, xSupportWt, ySupportWt, sampling);
1772 : }
1773 : //tim.show("Area*2:");
1774 :
1775 : //==============================================================
1776 : // thisCell=cfb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement);
1777 : // if (real(cfNorm) > 1e7)
1778 : // {
1779 : // cfNorm -= Complex(1e7,0.0);
1780 : // ostringstream name;
1781 : // name << "WT_" << miscInfo.wValue;
1782 : // thisCell->makePersistent("./",name.str().c_str());
1783 : // }
1784 : // if (real(cfWtNorm) > 1e7)
1785 : // {
1786 : // cfWtNorm -= Complex(1e7,0.0);
1787 : // // ostringstream name;
1788 : // // name << "CFWT_" << miscInfo.wValue;
1789 : // // storeArrayAsImage(name,ftCoords, cfWtBufMat);
1790 : // }
1791 : //==============================================================
1792 :
1793 :
1794 : //tim.mark();
1795 0 : cfBuf /= cfNorm;
1796 0 : cfWtBuf /= cfWtNorm;
1797 : //tim.show("cfNorm*2:");
1798 :
1799 : //tim.mark();
1800 0 : ftCoords=cs_l;
1801 0 : SynthesisUtils::makeFTCoordSys(cs_l, cfBuf.shape()(0), ftRef, ftCoords);
1802 : //CountedPtr<CFCell>
1803 :
1804 0 : thisCell=cfb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement);
1805 0 : thisCell->pa_p=Quantity(vbPA,"rad");
1806 0 : thisCell->coordSys_p = ftCoords;
1807 0 : thisCell->xSupport_p = xSupport;
1808 0 : thisCell->ySupport_p = ySupport;
1809 0 : thisCell->isRotationallySymmetric_p = aTerm.isNoOp();
1810 :
1811 0 : (cfWtb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement))->initCache();
1812 0 : (cfb.getCFCellPtr(miscInfo.freqValue, miscInfo.wValue, miscInfo.muellerElement))->initCache();
1813 : //tim.show("End*2:");
1814 : }
1815 : }
1816 0 : }
1817 :
1818 :
1819 : //
1820 : //----------------------------------------------------------------------
1821 : //
1822 0 : void AWConvFunc::makeConvFunction2(const String& cfCachePath,
1823 : const Vector<Double>& uvScale, const Vector<Double>& uvOffset,
1824 : const Matrix<Double>& ,//vbFreqSelection,
1825 : CFStore2& cfs2,
1826 : CFStore2& cfwts2,
1827 : const Bool psTermOn,
1828 : const Bool aTermOn,
1829 : const Bool conjBeams)
1830 : {
1831 0 : LogIO log_l(LogOrigin("AWConvFunc", "makeConvFunction2[R&D]"));
1832 : Int convSize, convSampling;//, polInUse;
1833 0 : Array<Complex> convFunc_l, convWeights_l;
1834 : //
1835 : // Get the coordinate system
1836 : //
1837 0 : const String uvGridDiskImage=cfCachePath+"/"+"uvgrid.im";
1838 0 : PagedImage<Complex> image_l(uvGridDiskImage);//cfs2.getCacheDir()+"/uvgrid.im");
1839 0 : CoordinateSystem coords(image_l.coordinates());
1840 :
1841 : //Int nx=image_l.shape()(0);//, ny=image.shape()(1);
1842 0 : CountedPtr<CFBuffer> cfb_p, cfwtb_p;
1843 :
1844 0 : IPosition cfsShape = cfs2.getShape();
1845 0 : IPosition wCFStShape = cfwts2.getShape();
1846 :
1847 : //Matrix<Int> uniqueBaselineTypeList=makeBaselineList(aTerm_p->getAntTypeList());
1848 : Bool wbAWP, wTermOn;
1849 :
1850 0 : for (int iPA=0; iPA<cfsShape[0]; iPA++)
1851 0 : for (int iB=0; iB<cfsShape[1]; iB++)
1852 : {
1853 0 : log_l << "Filling CFs for baseline type " << iB << ", PA slot " << iPA << LogIO::WARN << LogIO::POST;
1854 0 : cfb_p=cfs2.getCFBuffer(iPA,iB);
1855 0 : cfwtb_p=cfwts2.getCFBuffer(iPA,iB);
1856 :
1857 0 : IPosition cfbShape = cfb_p->shape();
1858 :
1859 0 : for (int iNu=0; iNu<cfbShape(0); iNu++) // Frequency axis
1860 0 : for (int iPol=0; iPol<cfbShape(2); iPol++) // Polarization axis
1861 0 : for (int iW=0; iW<cfbShape(1); iW++) // W axis
1862 : {
1863 0 : CFCStruct miscInfo;
1864 0 : CoordinateSystem cs_l;
1865 : Int xSupport, ySupport;
1866 : Float sampling;
1867 :
1868 0 : CountedPtr<CFCell>& tt=(*cfb_p).getCFCellPtr(iNu, iW, iPol);
1869 : //cerr << "####@#$#@$@ " << iNu << " " << iW << " " << iPol << endl;
1870 : //tt->show("test",cout);
1871 0 : if (tt->cfShape_p.nelements() != 0)
1872 : {
1873 0 : (*cfb_p)(iNu,iW,iPol).getAsStruct(miscInfo); // Get misc. info. for this CFCell
1874 :
1875 0 : wbAWP=True; // Always true since the Freq. value is got from the coord. sys.
1876 0 : wTermOn=(miscInfo.wValue > 0.0);
1877 :
1878 : CountedPtr<ConvolutionFunction> awCF = AWProjectFT::makeCFObject(miscInfo.telescopeName,
1879 0 : aTermOn, psTermOn, wTermOn, True, wbAWP, conjBeams);
1880 0 : (static_cast<AWConvFunc &>(*awCF)).aTerm_p->cacheVBInfo(miscInfo.telescopeName, miscInfo.diameter);
1881 : //aTerm_p->cacheVBInfo(miscInfo.telescopeName, miscInfo.diameter);
1882 :
1883 0 : cfb_p->getParams(cs_l, sampling, xSupport, ySupport,iNu,iW,iPol);
1884 0 : convSampling=miscInfo.sampling;
1885 :
1886 : //convSize=miscInfo.shape[0];
1887 : // This method loads "empty CFs". Those have
1888 : // support size equal to the CONVBUF size
1889 : // required. So use that, instead of the
1890 : // "shape" information from CFs, since the
1891 : // latter for empty CFs can be small (to save
1892 : // disk space and i/o -- the CFs are supposed
1893 : // to be empty anyway at this stage!)
1894 0 : convSize=xSupport;
1895 :
1896 0 : IPosition start(4, 0, 0, 0, 0);
1897 0 : IPosition pbSlice(4, convSize, convSize, 1, 1);
1898 :
1899 0 : Matrix<Complex> screen(convSize, convSize);
1900 :
1901 0 : Int inner=convSize/(convSampling);
1902 : //Float psScale = (2*coords.increment()(0))/(nx*image.coordinates().increment()(0));
1903 0 : Float innerQuaterFraction=1.0;
1904 :
1905 0 : Float psScale = 2.0/(innerQuaterFraction*convSize/convSampling);// nx*image.coordinates().increment()(0)*convSampling/2;
1906 0 : ((static_cast<AWConvFunc &>(*awCF)).psTerm_p)->init(IPosition(2,inner,inner), uvScale, uvOffset,psScale);
1907 :
1908 : //
1909 : // By this point, all the 4 axis (Time/PA, Freq, Pol, Baseline)
1910 : // of the CFBuffer objects have been setup. The CFs will now
1911 : // be filled using the supplied PS-, W- and the A-term objects.
1912 : //
1913 :
1914 0 : AWConvFunc::fillConvFuncBuffer2(*cfb_p, *cfwtb_p, convSize, convSize,
1915 : image_l,//coords,
1916 : miscInfo,
1917 0 : *((static_cast<AWConvFunc &>(*awCF)).psTerm_p),
1918 0 : *((static_cast<AWConvFunc &>(*awCF)).wTerm_p),
1919 0 : *((static_cast<AWConvFunc &>(*awCF)).aTerm_p),
1920 : conjBeams);
1921 :
1922 : // *psTerm_p, *wTerm_p, *aTerm_p);
1923 : //cfb_p->show(NULL,cerr);
1924 : //
1925 : // Make the CFStores persistent.
1926 : //
1927 : // cfs2.makePersistent(cfCachePath.c_str());
1928 : // cfwts2.makePersistent(cfCachePath.c_str(),"WT");
1929 : }
1930 : }
1931 : } // End of loop over baselines
1932 :
1933 0 : cfs2.makePersistent(cfCachePath.c_str());
1934 0 : cfwts2.makePersistent(cfCachePath.c_str(),"","WT");
1935 : // Directory dir(uvGridDiskImage);
1936 : // dir.removeRecursive(false);
1937 : // dir.remove();
1938 0 : }
1939 0 : Int AWConvFunc::getOversampling(PSTerm& psTerm, WTerm& wTerm, ATerm& aTerm)
1940 : {
1941 : Int os;
1942 0 : if (!aTerm.isNoOp()) os=aTerm.getOversampling();
1943 0 : else if (!wTerm.isNoOp()) os=wTerm.getOversampling();
1944 0 : else os=psTerm.getOversampling();
1945 0 : return os;
1946 : }
1947 : };
|