Line data Source code
1 : //# SimplePBConvFunc.cc: implementation of SimplePBConvFunc
2 : //# Copyright (C) 2007
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be adressed as follows:
20 : //# Internet email: aips2-request@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //#
27 : //# $Id$
28 : #include <casacore/casa/Arrays/ArrayMath.h>
29 : #include <casacore/casa/Arrays/Array.h>
30 : #include <casacore/casa/Arrays/MaskedArray.h>
31 : #include <casacore/casa/Arrays/Vector.h>
32 : #include <casacore/casa/Arrays/Slice.h>
33 : #include <casacore/casa/Arrays/Slicer.h>
34 : #include <casacore/casa/Arrays/Matrix.h>
35 : #include <casacore/casa/Arrays/Cube.h>
36 : #include <casacore/casa/OS/Timer.h>
37 : #include <casacore/casa/Utilities/Assert.h>
38 : #include <casacore/casa/Quanta/MVTime.h>
39 : #include <casacore/casa/Quanta/MVAngle.h>
40 : #include <casacore/measures/Measures/MeasTable.h>
41 : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
42 : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
43 :
44 : #include <casacore/images/Images/ImageInterface.h>
45 : #include <casacore/images/Images/PagedImage.h>
46 : #include <casacore/images/Images/TempImage.h>
47 : #include <casacore/images/Images/SubImage.h>
48 : #include <casacore/casa/Logging/LogIO.h>
49 : #include <casacore/casa/Logging/LogSink.h>
50 : #include <casacore/casa/Logging/LogMessage.h>
51 :
52 : #include <casacore/ms/MeasurementSets/MSColumns.h>
53 : #include <casacore/lattices/Lattices/ArrayLattice.h>
54 : #include <casacore/lattices/Lattices/SubLattice.h>
55 : #include <casacore/lattices/LRegions/LCBox.h>
56 : #include <casacore/lattices/LEL/LatticeExpr.h>
57 : #include <casacore/lattices/Lattices/LatticeCache.h>
58 : #include <casacore/lattices/LatticeMath/LatticeFFT.h>
59 :
60 : #include <casacore/scimath/Mathematics/ConvolveGridder.h>
61 : #include <casacore/scimath/Mathematics/MathFunc.h>
62 : #include <msvis/MSVis/VisBuffer.h>
63 : #include <msvis/MSVis/VisibilityIterator.h>
64 :
65 : #include <synthesis/TransformMachines/SimplePBConvFunc.h>
66 : #include <synthesis/TransformMachines/SkyJones.h>
67 : #include <synthesis/TransformMachines/PBMath1DNumeric.h>
68 : #include <casacore/scimath/Mathematics/FFTPack.h>
69 : #include <casacore/scimath/Mathematics/FFTW.h>
70 : #include <casacore/scimath/Mathematics/FFTServer.h>
71 : #include <casacore/casa/Utilities/CompositeNumber.h>
72 : #include <math.h>
73 : #ifdef _OPENMP
74 : #include <omp.h>
75 : #endif
76 : using namespace casacore;
77 : namespace casa { //# NAMESPACE CASA - BEGIN
78 :
79 0 : SimplePBConvFunc::SimplePBConvFunc(): nchan_p(-1),
80 : npol_p(-1), pointToPix_p(), directionIndex_p(-1), thePix_p(0),
81 : filledFluxScale_p(false),doneMainConv_p(0),
82 :
83 0 : calcFluxScale_p(true), actualConvIndex_p(-1), convSize_p(0), convSupport_p(0), pointingPix_p() {
84 : //
85 :
86 0 : pbClass_p=PBMathInterface::COMMONPB;
87 0 : ft_p=FFT2D(true);
88 0 : }
89 :
90 0 : SimplePBConvFunc::SimplePBConvFunc(const PBMathInterface::PBClass typeToUse):
91 : nchan_p(-1),npol_p(-1),pointToPix_p(),
92 : directionIndex_p(-1), thePix_p(0), filledFluxScale_p(false),doneMainConv_p(0),
93 0 : calcFluxScale_p(true), actualConvIndex_p(-1), convSize_p(0), convSupport_p(0), pointingPix_p() {
94 : //
95 0 : pbClass_p=typeToUse;
96 0 : ft_p=FFT2D(true);
97 0 : }
98 0 : SimplePBConvFunc::SimplePBConvFunc(const RecordInterface& rec, const Bool calcfluxneeded)
99 : : nchan_p(-1),npol_p(-1),pointToPix_p(), directionIndex_p(-1), thePix_p(0), filledFluxScale_p(false),
100 : doneMainConv_p(0),
101 0 : calcFluxScale_p(calcfluxneeded), actualConvIndex_p(-1), convSize_p(0), convSupport_p(0), pointingPix_p()
102 : {
103 0 : String err;
104 0 : fromRecord(err, rec, calcfluxneeded);
105 0 : ft_p=FFT2D(true);
106 0 : }
107 0 : SimplePBConvFunc::~SimplePBConvFunc(){
108 : //
109 :
110 :
111 0 : }
112 :
113 0 : void SimplePBConvFunc::storeImageParams(const ImageInterface<Complex>& iimage,
114 : const VisBuffer& vb){
115 : //image signature changed...rather simplistic for now
116 0 : if((iimage.shape().product() != nx_p*ny_p*nchan_p*npol_p) || nchan_p < 1){
117 0 : csys_p=iimage.coordinates();
118 0 : Int coordIndex=csys_p.findCoordinate(Coordinate::DIRECTION);
119 0 : AlwaysAssert(coordIndex>=0, AipsError);
120 0 : directionIndex_p=coordIndex;
121 0 : dc_p=csys_p.directionCoordinate(directionIndex_p);
122 0 : ObsInfo imInfo=csys_p.obsInfo();
123 0 : String tel= imInfo.telescope();
124 0 : MPosition pos;
125 0 : if (vb.msColumns().observation().nrow() > 0) {
126 0 : tel = vb.msColumns().observation().telescopeName()(vb.msColumns().observationId()(0));
127 : }
128 0 : if (tel.length() == 0 || !tel.contains("VLA") ||
129 0 : !MeasTable::Observatory(pos,tel)) {
130 : // unknown observatory, use first antenna
131 0 : Int ant1=vb.antenna1()(0);
132 0 : pos=vb.msColumns().antenna().positionMeas()(ant1);
133 : }
134 : //cout << "TELESCOPE " << tel << endl;
135 : //Store this to build epochs via the time access of visbuffer later
136 0 : timeMType_p=MEpoch::castType(vb.msColumns().timeMeas()(0).getRef().getType());
137 0 : timeUnit_p=Unit(vb.msColumns().timeMeas().measDesc().getUnits()(0).getName());
138 : // timeUnit_p=Unit("s");
139 : //cout << "UNIT " << timeUnit_p.getValue() << " name " << timeUnit_p.getName() << endl;
140 0 : pointFrame_p=MeasFrame(imInfo.obsDate(), pos);
141 0 : MDirection::Ref elRef(dc_p.directionType(), pointFrame_p);
142 : //For now we set the conversion from this direction
143 0 : pointToPix_p=MDirection::Convert( MDirection(), elRef);
144 0 : nx_p=iimage.shape()(coordIndex);
145 0 : ny_p=iimage.shape()(coordIndex+1);
146 0 : pointingPix_p.resize(nx_p, ny_p);
147 0 : pointingPix_p.set(false);
148 0 : coordIndex=csys_p.findCoordinate(Coordinate::SPECTRAL);
149 0 : Int pixAxis=csys_p.pixelAxes(coordIndex)[0];
150 0 : nchan_p=iimage.shape()(pixAxis);
151 0 : coordIndex=csys_p.findCoordinate(Coordinate::STOKES);
152 0 : pixAxis=csys_p.pixelAxes(coordIndex)[0];
153 0 : npol_p=iimage.shape()(pixAxis);
154 0 : if(calcFluxScale_p){
155 0 : if(fluxScale_p.shape().nelements()==0){
156 0 : fluxScale_p=TempImage<Float>(IPosition(4,nx_p,ny_p,npol_p,nchan_p), csys_p);
157 0 : fluxScale_p.set(0.0);
158 : }
159 0 : filledFluxScale_p=false;
160 : }
161 :
162 : }
163 :
164 0 : }
165 :
166 0 : void SimplePBConvFunc::toPix(const VisBuffer& vb){
167 0 : thePix_p.resize(2);
168 :
169 0 : const MDirection& p1=pointingDirAnt1(vb);
170 0 : if(dc_p.directionType() != MDirection::castType(p1.getRef().getType())){
171 : //pointToPix_p.setModel(theDir);
172 :
173 0 : String tel= csys_p.obsInfo().telescope();
174 0 : if(!tel.contains("VLA")) {
175 : //use first antenna as direction1_p is used to calculate pointing
176 : // as only VLA uses observatory pos for calculations
177 0 : Int ant1=vb.antenna1()(0);
178 0 : MPosition pos=vb.msColumns().antenna().positionMeas()(ant1);
179 0 : pointFrame_p.resetPosition(pos);
180 : }
181 0 : MEpoch timenow(Quantity(vb.time()(0), timeUnit_p), timeMType_p);
182 : //cerr << "Ref " << p1.toString() << " ep " << timenow.getRefString() << " time " << MVTime(timenow.getValue().getTime()).string(MVTime::YMD) << endl;
183 0 : pointFrame_p.resetEpoch(timenow);
184 : ///////////////////////////
185 : //MDirection some=pointToPix_p(vb.direction1()(0));
186 : //MVAngle mvRa=some.getAngle().getValue()(0);
187 : //MVAngle mvDec=some.getAngle().getValue()(1);
188 :
189 : //cout << mvRa(0.0).string(MVAngle::TIME,8) << " ";
190 : // cout << mvDec.string(MVAngle::DIG2,8) << " ";
191 : //cout << MDirection::showType(some.getRefPtr()->getType()) << endl;
192 :
193 : //////////////////////////
194 : //pointToPix holds pointFrame_p by reference...
195 : //thus good to go for conversion
196 0 : direction1_p=pointToPix_p(p1);
197 : //cerr << "converted " << direction1_p.toString() << endl;
198 : //direction2_p=pointToPix_p(vb.direction2()(0));
199 0 : direction2_p=direction1_p;
200 0 : dc_p.toPixel(thePix_p, direction1_p);
201 :
202 : }
203 : else{
204 0 : direction1_p=p1;
205 : //direction2_p=vb.direction2()(0);
206 : //For now
207 0 : direction2_p=direction1_p;
208 0 : dc_p.toPixel(thePix_p, direction1_p);
209 : }
210 0 : }
211 :
212 0 : void SimplePBConvFunc::setWeightImage(CountedPtr<TempImage<Float> >& wgtimage){
213 0 : convWeightImage_p=wgtimage;
214 0 : calcFluxScale_p=true;
215 :
216 0 : }
217 :
218 0 : void SimplePBConvFunc::reset(){
219 0 : doneMainConv_p.resize();
220 0 : convFunctions_p.resize(0, true);
221 0 : convWeights_p.resize(0, true);
222 0 : convSizes_p.resize(0, true);
223 0 : convSupportBlock_p.resize(0, true);
224 0 : convFunctionMap_p.clear();
225 0 : vbConvIndex_p.clear();
226 0 : }
227 :
228 :
229 :
230 0 : Int SimplePBConvFunc::convIndex(const VisBuffer& vb){
231 0 : String elkey=String::toString(vb.msId())+String("_")+String::toString(vb.spectralWindow());
232 0 : if(vbConvIndex_p.count(elkey) > 0){
233 0 : return vbConvIndex_p[elkey];
234 : }
235 0 : Int val=vbConvIndex_p.size();
236 0 : vbConvIndex_p[elkey]=val;
237 0 : return val;
238 : }
239 :
240 0 : const MDirection& SimplePBConvFunc::pointingDirAnt1(const VisBuffer& vb){
241 0 : std::ostringstream oss;
242 0 : oss << vb.msId() << "_" << vb.antenna1()(0) << "_";
243 0 : oss.precision(13);
244 0 : oss << vb.time()(0);
245 0 : String elkey=oss.str();
246 : // String elkey=String::toString(vb.msId())+String("_")+String::toString(vb.antenna1()(0))+String("_")
247 : // +String::toString(vb.time()(0));
248 :
249 : //cerr << "key " << elkey << " count " << ant1PointVal_p.count(elkey) << " size " << ant1PointVal_p.size() << " " << ant1PointingCache_p.nelements() << endl;
250 0 : if(ant1PointVal_p.count(elkey) > 0){
251 0 : return ant1PointingCache_p[ant1PointVal_p[elkey]];
252 :
253 : }
254 0 : Int val=ant1PointingCache_p.nelements();
255 0 : ant1PointingCache_p.resize(val+1, true);
256 0 : ant1PointingCache_p[val]=vb.firstDirection1();
257 : //cerr << "POINTINGDIRANT1 " << vb.firstDirection1() << " " << vb.direction1()(0) << endl;
258 : //ant1PointingCache_p[val]=vbUtil_p.getPointingDir(vb, vb.antenna1()(0), 0);
259 0 : ant1PointVal_p[elkey]=val;
260 0 : return ant1PointingCache_p[val];
261 :
262 : }
263 0 : void SimplePBConvFunc::findConvFunction(const ImageInterface<Complex>& iimage,
264 : const VisBuffer& vb,
265 : const Int& convSampling,
266 : const Vector<Double>& visFreq,
267 : Array<Complex>& convFunc,
268 : Array<Complex>& weightConvFunc,
269 : Vector<Int>& convsize,
270 : Vector<Int>& convSupport,
271 : Vector<Int>& convFuncPolMap,
272 : Vector<Int>& convFuncChanMap,
273 : Vector<Int>& convFuncRowMap,
274 : const Bool /*getConjFunc*/
275 : ){
276 :
277 :
278 :
279 0 : LogIO os;
280 0 : os << LogOrigin("SimplePBConv", "findConvFunction") << LogIO::NORMAL;
281 : /////////////////////////
282 : os<< LogIO::DEBUG1
283 0 : << "msID " << vb.msId() << " ANT1 id" << vb.antenna1()(0)
284 0 : << " direction " << vb.firstDirection1().toString() << " ANT2 id"
285 0 : << vb.antenna2()(0) << " direction " << vb.direction2()(0).toString()
286 0 : << LogIO::POST ;
287 : //////////////////////
288 0 : Int convSamp=2*convSampling;
289 0 : storeImageParams(iimage, vb);
290 0 : convFuncChanMap.resize(vb.nChannel());
291 0 : Vector<Double> beamFreqs;
292 0 : findUsefulChannels(convFuncChanMap, beamFreqs, vb, visFreq);
293 : //cerr << "CHANMAP " << convFuncChanMap << " beamFreqs " << beamFreqs << endl;
294 0 : Int nBeamChans=beamFreqs.nelements();
295 : //indgen(convFuncChanMap);
296 0 : convFuncPolMap.resize(vb.nCorr());
297 0 : convFuncPolMap.set(0);
298 : //Only one plane in this version
299 0 : convFuncRowMap.resize();
300 0 : convFuncRowMap=Vector<Int>(vb.nRow(),0);
301 : //break reference
302 0 : convFunc.resize();
303 0 : weightConvFunc.resize();
304 :
305 :
306 : // Get the coordinate system
307 0 : CoordinateSystem coords(iimage.coordinates());
308 :
309 :
310 0 : actualConvIndex_p=convIndex(vb);
311 : //cerr << "In findConv " << actualConvIndex_p << endl;
312 : // Make a two dimensional image to calculate the
313 : // primary beam. We want this on a fine grid in the
314 : // UV plane
315 0 : Int directionIndex=directionIndex_p;
316 0 : AlwaysAssert(directionIndex>=0, AipsError);
317 :
318 : // Set up the convolution function.
319 0 : Int nx=nx_p;
320 0 : Int ny=ny_p;
321 : // convSize_p=max(nx,ny)*convSampling;
322 : //cerr << "size " << nx << " " << ny << endl;
323 : //3 times the support size
324 0 : if(doneMainConv_p.shape()[0] < (actualConvIndex_p+1)){
325 : // cerr << "resizing DONEMAIN " << doneMainConv_p.shape()[0] << endl;
326 0 : doneMainConv_p.resize(actualConvIndex_p+1, true);
327 0 : doneMainConv_p[actualConvIndex_p]=false;
328 : }
329 :
330 0 : if(!(doneMainConv_p[actualConvIndex_p])){
331 :
332 : //convSize_p=4*(sj_p->support(vb, coords));
333 0 : convSize_p=Int(max(nx_p, ny_p)/2)*2*convSamp;
334 : //cerr << "convSize_p " << convSize_p << " support " << sj_p->support(vb, coords) << endl;
335 : // Make this a nice composite number, to speed up FFTs
336 : //cerr << "convSize_p 0 " << convSize_p << " convSamp " << convSamp<< endl;
337 0 : CompositeNumber cn(uInt(convSize_p*2.0));
338 :
339 0 : convSize_p = cn.nextLargerEven(Int(convSize_p));
340 : //cerr << "convSize : " << convSize_p << endl;
341 :
342 : }
343 :
344 :
345 0 : toPix(vb);
346 : //Timer tim;
347 : //tim.mark();
348 0 : addPBToFlux(vb);
349 : //tim.show("After addPBToFlux");
350 0 : DirectionCoordinate dc=dc_p;
351 :
352 : //where in the image in pixels is this pointing
353 0 : Vector<Double> pixFieldDir(2);
354 0 : pixFieldDir=thePix_p;
355 :
356 : //cerr << "pix of pointing " << pixFieldDir << endl;
357 0 : MDirection fieldDir=direction1_p;
358 : //shift from center
359 0 : pixFieldDir(0) = pixFieldDir(0) - Double(nx / 2);
360 0 : pixFieldDir(1) = pixFieldDir(1) - Double(ny / 2);
361 :
362 : //phase gradient per pixel to apply
363 0 : pixFieldDir(0) = -pixFieldDir(0)*2.0*C::pi/Double(nx)/Double(convSampling);
364 0 : pixFieldDir(1) = -pixFieldDir(1)*2.0*C::pi/Double(ny)/Double(convSampling);
365 :
366 : //cerr << "DonemainConv " << doneMainConv_p[actualConvIndex_p] << endl;
367 0 : if(!doneMainConv_p[actualConvIndex_p]){
368 0 : Vector<Double> sampling;
369 0 : sampling = dc.increment();
370 0 : sampling*=Double(convSamp);
371 0 : sampling(0)*=Double(nx)/Double(convSize_p);
372 0 : sampling(1)*=Double(ny)/Double(convSize_p);
373 0 : dc.setIncrement(sampling);
374 :
375 :
376 0 : Vector<Double> unitVec(2);
377 0 : unitVec=convSize_p/2;
378 0 : dc.setReferencePixel(unitVec);
379 :
380 :
381 : //make sure we are using the same units
382 0 : fieldDir.set(dc.worldAxisUnits()(0));
383 : //cerr << "SPB direction " << fieldDir << endl;
384 :
385 0 : dc.setReferenceValue(fieldDir.getAngle().getValue());
386 :
387 0 : coords.replaceCoordinate(dc, directionIndex);
388 0 : Int spind=coords.findCoordinate(Coordinate::SPECTRAL);
389 0 : SpectralCoordinate spCoord=coords.spectralCoordinate(spind);
390 0 : spCoord.setReferencePixel(Vector<Double>(1,0.0));
391 0 : spCoord.setReferenceValue(Vector<Double>(1, beamFreqs(0)));
392 0 : if(beamFreqs.nelements() >1)
393 0 : spCoord.setIncrement(Vector<Double>(1, beamFreqs(1)-beamFreqs(0)));
394 0 : coords.replaceCoordinate(spCoord, spind);
395 :
396 :
397 0 : CoordinateSystem coordLastPlane= coords;
398 0 : spCoord.setReferenceValue(Vector<Double>(1, beamFreqs(nBeamChans-1)));
399 0 : coordLastPlane.replaceCoordinate(spCoord, spind);
400 : //cerr << "BEAM freqs " << beamFreqs << endl;
401 :
402 : // coords.list(logIO(), MDoppler::RADIO, IPosition(), IPosition());
403 :
404 0 : Int tempConvSize=((convSize_p/4/(convSamp/convSampling))/2)*2;
405 0 : IPosition pbShape(4, tempConvSize, tempConvSize, 1, nBeamChans);
406 :
407 0 : Long memtot=HostInfo::memoryFree();
408 0 : Double memtobeused= Double(memtot)*1024.0;
409 : //cerr << "Mem to be used " << memtobeused << " arraysize " << Double(convSize_p*convSize_p)*8.0 << endl;;
410 : //check for 32 bit OS and limit it to 2Gbyte
411 : if( sizeof(void*) == 4){
412 : if(memtot > 2000000)
413 : memtot=2000000;
414 : }
415 0 : if(memtot <= 2000000)
416 0 : memtobeused=0.0;
417 : //cerr << "mem to be used " << memtobeused << endl;
418 : //tim.mark();
419 0 : IPosition start(4, 0, 0, 0, 0);
420 : //IPosition pbSlice(4, convSize_p, convSize_p, 1, 1);
421 : //cerr << "pbshape " << pbShape << endl;
422 0 : TempImage<Complex> twoDPB(TiledShape(pbShape, IPosition(4, pbShape(0), pbShape(1), 1, 1)), coords, memtobeused/10.0);
423 :
424 : //tim.show("after making one image");
425 0 : convFunc_p.resize(tempConvSize, tempConvSize);
426 0 : convFunc_p=0.0;
427 :
428 :
429 :
430 : // Accumulate terms
431 : //Matrix<Complex> screen(convSize_p, convSize_p);
432 : //screen=1.0;
433 : // Either the SkyJones
434 : //tim.mark();
435 : //twoDPB.set(Complex(1.0,0.0));
436 : //for (Int k=0; k < nBeamChans; ++k){
437 : //blcin[3]=k;
438 : //trcin[3]=k;
439 : //Slicer slin(blcin, trcin, Slicer::endIsLast);
440 : //SubImage<Complex> subim(twoDPB, slin, true);
441 0 : TempImage<Complex> subim(IPosition(4, convSize_p, convSize_p, 1, 1), coordLastPlane, memtobeused/2.2);
442 0 : subim.set(Complex(1.0,0.0));
443 :
444 :
445 : /////Let's make a spheroid taper...
446 : /* Vector<Float> valsph(300);
447 : valsph.set(1.0);
448 : Sph_Conv<Float> d(1.0, 1.0);
449 : for(Int k=200; k <300; ++k){
450 : valsph(k)=d.value((Float)(k-200)/100.0);
451 : }
452 : Quantity fulrad(27,"arcmin");
453 : Quantity lefreq(1.4, "GHz");
454 : PBMath1DNumeric taper(valsph,fulrad,lefreq);
455 : taper.applyPB(subim, subim, fieldDir);
456 : */
457 : ///////////////
458 : /*{
459 : PagedImage<Complex> thisScreen(subim.shape(), subim.coordinates(), "ELTAPER");
460 : //LatticeExpr<Float> le(abs(twoDPB2));
461 : thisScreen.copyData(subim);
462 : }*/
463 : //twoDPB.putSlice(screen, start);
464 : /////////////
465 : //Double wtime0=omp_get_wtime();
466 : //////////
467 0 : sj_p->apply(subim, subim, vb, 0);
468 : ///////////////
469 : //Double wtime1=omp_get_wtime();
470 : /////////////////
471 : /*{
472 : PagedImage<Complex> thisScreen(subim.shape(), subim.coordinates(), "BEAM-ELTAPER");
473 : //LatticeExpr<Float> le(abs(twoDPB2));
474 : thisScreen.copyData(subim);
475 : }*/
476 : //LatticeFFT::cfft2d(subim);
477 : //////
478 :
479 :
480 0 : ft_p.c2cFFT(subim);
481 :
482 : // cerr << "make pb " << wtime1-wtime0 << " fft " << omp_get_wtime()-wtime1 << endl;
483 : // }
484 : //tim.show("after an apply" );
485 : //tim.mark();
486 0 : TempImage<Float> screen2(TiledShape(IPosition(4, convSize_p, convSize_p, 1, 1)), coordLastPlane, memtobeused/2.2);
487 0 : screen2.set(1.0);
488 0 : TempImage<Complex> subout(TiledShape(IPosition(4, convSize_p, convSize_p, 1, 1)), coordLastPlane, memtobeused/2.2);
489 :
490 : //////Making a reference on half of the lattice as on the Mac rcfft is failing for some
491 : //////reason
492 0 : SubImage<Complex> halfsubout(subout, Slicer(IPosition(4, 0, 0, 0, 0),
493 0 : IPosition(4, convSize_p/2, convSize_p-1, 0, 0),
494 0 : Slicer::endIsLast), true);
495 : /////////////////////
496 : //wtime0=omp_get_wtime();
497 : ///////////////////
498 0 : sj_p->applySquare(screen2, screen2, vb, 0);
499 : ///////////////
500 : //wtime1=omp_get_wtime();
501 : /////////////////
502 : /////////
503 : /* arr.resize();
504 : Array<Float> arrf;
505 : screen2.get(arrf, false);
506 : isRef=halfsubout.get (arr,false);
507 : Bool delf;
508 : Float* scrf=arrf.getStorage(delf);
509 : scr= arr.getStorage(del);
510 :
511 : ft_p.r2cFFT(scr, scrf, Long(convSize_p), Long(convSize_p));
512 : cerr << "isRef " << isRef << " iscopy " << del << " delf " << delf << endl;
513 : if(del)
514 : arr.putStorage(scr, del);
515 : if(delf)
516 : arrf.putStorage(scrf, delf);
517 : if(!isRef)
518 : halfsubout.put(arr.reform(IPosition(4, convSize_p/2+1, convSize_p, 1, 1)));
519 : */
520 : ////////////////////
521 0 : ft_p.r2cFFT(halfsubout, screen2);
522 : //LatticeFFT::rcfft(halfsubout, screen2, true, false);
523 : //cerr << "make pb2 " << wtime1-wtime0 << " fft " << omp_get_wtime()-wtime1 << endl;
524 : //Real FFT fills only first half of the array
525 : //making it look like a Complex to Complex FFT
526 0 : IPosition iblc(4, 0, 3*subout.shape()(1)/8, 0, 0);
527 0 : IPosition itrc(4, 0, 5*subout.shape()(1)/8, 0, 0);
528 0 : for(Int x=subout.shape()(0)/2; x <(5*subout.shape()(0)/8); ++x){
529 :
530 0 : iblc[0]=x-subout.shape()(0)/2;
531 0 : itrc[0]=x-subout.shape()(0)/2;
532 0 : Slicer isl(iblc, itrc, Slicer::endIsLast);
533 0 : iblc[0]=x;
534 0 : subout.putSlice(subout.getSlice(isl), iblc);
535 : }
536 0 : for(Int x=subout.shape()(0)/2+1; x <(5*subout.shape()(0)/8); ++x){
537 :
538 0 : iblc[0]=x;
539 0 : itrc[0]=x;
540 0 : Slicer isl(iblc, itrc, Slicer::endIsLast);
541 0 : iblc[0]=subout.shape()(0)-x;
542 0 : subout.putSlice(subout.getSlice(isl), iblc);
543 0 : if(x==(subout.shape()(0)-1)){
544 0 : iblc[0]=0;
545 0 : subout.putSlice(subout.getSlice(isl), iblc);
546 : }
547 : }
548 : //End of FFT's
549 : //tim.show("After apply2 ");
550 : /////////////////////
551 : //wtime0=omp_get_wtime();
552 : ///////////////////
553 0 : TempImage<Complex> twoDPB2(TiledShape(pbShape, IPosition(4, pbShape(0), pbShape(1), 1, 1)), coords, memtobeused/10.0);
554 :
555 0 : IPosition blcout(4, 0, 0, 0, nBeamChans-1);
556 0 : IPosition trcout(4, pbShape(0)-1, pbShape(1)-1, 0,nBeamChans-1);
557 0 : Slicer outsl(blcout, trcout, Slicer::endIsLast);
558 :
559 0 : IPosition blcin(4, convSize_p/2-pbShape(0)/2, convSize_p/2-pbShape(1)/2, 0, 0);
560 0 : IPosition trcin(4, convSize_p/2+pbShape(0)/2-1, convSize_p/2+pbShape(1)/2-1, 0, 0);
561 0 : Slicer insl(blcin, trcin, Slicer::endIsLast);
562 : {
563 0 : SubImage<Complex> subtwoDPB(twoDPB, outsl, true);
564 0 : SubImage<Complex> intwoDPB(subim, insl, false);
565 0 : subtwoDPB.copyData(intwoDPB);
566 : }
567 : {
568 0 : SubImage<Complex> subtwoDPB2(twoDPB2, outsl, true);
569 0 : SubImage<Complex> intwoDPB2(subout, insl, false);
570 0 : subtwoDPB2.copyData(intwoDPB2);
571 : }
572 :
573 0 : if(nBeamChans > 0){
574 0 : blcin=IPosition(4,0,0,0, nBeamChans-1);
575 0 : trcin=IPosition(4, pbShape(0)-1, pbShape(1)-1, 0, nBeamChans-1);
576 0 : Slicer slin(blcin, trcin, Slicer::endIsLast);
577 0 : SubImage<Complex> origPB(twoDPB, slin, false);
578 0 : IPosition elshape= origPB.shape();
579 0 : Matrix<Complex> i1=origPB.get(true);
580 0 : SubImage<Complex> origPB2(twoDPB2, slin, false);
581 0 : Matrix<Complex> i2=origPB2.get(true);
582 0 : Int cenX=i1.shape()(0)/2;
583 0 : Int cenY=i1.shape()(1)/2;
584 :
585 :
586 0 : for (Int kk=0; kk < nBeamChans; ++kk){
587 0 : Double fratio=beamFreqs(kk)/beamFreqs(nBeamChans-1);
588 : //cerr << "fratio " << fratio << endl;
589 0 : Float convRatio=convSamp/convSampling;
590 0 : blcin[3]=kk;
591 0 : trcin[3]=kk;
592 : //Slicer slout(blcin, trcin, Slicer::endIsLast);
593 0 : Matrix<Complex> o1(i1.shape(), Complex(0.0));
594 0 : Matrix<Complex> o2(i2.shape(), Complex(0.0));
595 0 : for (Int yy=0; yy < i1.shape()(1); ++yy){
596 : //Int nyy= (Double(yy-cenY)*fratio) + cenY;
597 0 : Double nyy= (Double((yy-cenY)*convRatio)/fratio) + cenY;
598 0 : Double cyy=ceil(nyy);
599 0 : Double fyy= floor(nyy);
600 0 : Int iy=nyy > fyy+0.5 ? Int(cyy) : Int(fyy);
601 0 : if(cyy <2*cenY && fyy >=0.0)
602 0 : for(Int xx=0; xx < i1.shape()(0); ++ xx){
603 : //Int nxx= Int(Double(xx-cenX)*fratio) + cenX;
604 0 : Double nxx= Int(Double((xx-cenX)*convRatio)/fratio) + cenX;
605 0 : Double cxx=ceil(nxx);
606 0 : Double fxx= floor(nxx);
607 0 : Int ix=nxx > fxx+0.5 ? Int(cxx) : Int(fxx) ;
608 0 : if(cxx < 2*cenX && fxx >=0.0 ){
609 : //Double dist=sqrt((nxx-cxx)*(nxx-cxx)+(nyy-cyy)*(nyy-cyy))/sqrt(2.0);
610 : //o1(xx, yy)=float(1-dist)*i1(fxx, fyy)+ dist*i1(cxx,cyy);
611 0 : o1(xx, yy)=i1( ix, iy);
612 : //o2(xx, yy)=i2(nxx, nyy);
613 : //o2(xx, yy)=float(1-dist)*i2(fxx, fyy)+ dist*i2(cxx,cyy);
614 0 : o2(xx, yy)=i2(ix, iy);
615 : }
616 : }
617 : }
618 0 : twoDPB.putSlice(o1.reform(elshape), blcin);
619 0 : twoDPB2.putSlice(o2.reform(elshape), blcin);
620 : }
621 :
622 : }
623 : //cerr << "make multfreq beam " << omp_get_wtime()-wtime0 << endl;
624 : /*
625 : {
626 : TempImage<Float> screen2(TiledShape(pbShape, IPosition(4, pbShape(0), pbShape(1), 1, 1)), coords, memtobeused);
627 : // Matrix<Float> screenoo(convSize_p, convSize_p);
628 : //screenoo.set(1.0);
629 : //screen2.putSlice(screenoo,start);
630 : //screen2.set(1.0);
631 : for (Int k=0; k < nBeamChans; ++k){
632 : blcin[3]=k;
633 : trcin[3]=k;
634 : Slicer slin(blcin, trcin, Slicer::endIsLast);
635 : SubImage<Float> subim(screen2, slin, true);
636 : SubImage<Complex> subout(twoDPB2, slin, true);
637 : subim.set(1.0);
638 : //twoDPB.putSlice(screen, start);
639 : sj_p->applySquare(subim, subim, vb, 0);
640 : //// LatticeExpr<Complex> le(subim);
641 : //// subout.copyData(le);
642 : ///// LatticeFFT::cfft2d(subout);
643 :
644 : LatticeFFT::rcfft(subout, subim, true, false);
645 : IPosition iblc(4, 0, 3*subout.shape()(1)/8, 0, 0);
646 : IPosition itrc(4, 0, 5*subout.shape()(1)/8, 0, 0);
647 : for(Int x=subout.shape()(0)/2; x <(5*subout.shape()(0)/8); ++x){
648 :
649 : iblc[0]=x-subout.shape()(0)/2;
650 : itrc[0]=x-subout.shape()(0)/2;
651 : Slicer isl(iblc, itrc, Slicer::endIsLast);
652 : iblc[0]=x;
653 : subout.putSlice(subout.getSlice(isl), iblc);
654 : }
655 : for(Int x=subout.shape()(0)/2+1; x <(5*subout.shape()(0)/8); ++x){
656 :
657 : iblc[0]=x;
658 : itrc[0]=x;
659 : Slicer isl(iblc, itrc, Slicer::endIsLast);
660 : iblc[0]=subout.shape()(0)-x;
661 : subout.putSlice(subout.getSlice(isl), iblc);
662 : if(x==(subout.shape()(0)-1)){
663 : iblc[0]=0;
664 : subout.putSlice(subout.getSlice(isl), iblc);
665 : }
666 : }
667 :
668 : }
669 :
670 : //sj_p->applySquare(screen2, screen2, vb, 0);
671 : //LatticeExpr<Complex> le(screen2);
672 : //twoDPB2.copyData(le);
673 : }
674 :
675 : */
676 :
677 : /*
678 : if(0) {
679 : CoordinateSystem ftCoords(coords);
680 : //directionIndex=ftCoords.findCoordinate(Coordinate::DIRECTION);
681 : //AlwaysAssert(directionIndex>=0, AipsError);
682 : dc=coords.directionCoordinate(directionIndex);
683 : Vector<Bool> axes(2); axes(0)=true;axes(1)=true;
684 : Vector<Int> shape(2); shape(0)=convSize_p;shape(1)=convSize_p;
685 : Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape);
686 : //ftCoords.replaceCoordinate(*ftdc, directionIndex);
687 : delete ftdc; ftdc=0;
688 : ostringstream os1;
689 : os1 << "Screen_" << vb.fieldId() ;
690 : PagedImage<Complex> thisScreen(twoDPB2.shape(), ftCoords, String(os1));
691 : //LatticeExpr<Float> le(abs(twoDPB2));
692 : thisScreen.copyData(twoDPB2);
693 : LatticeFFT::cfft2d(thisScreen, false);
694 : PagedImage<Complex> thisScreen0(twoDPB.shape(), ftCoords, String("PB_")+String(os1));
695 : thisScreen0.copyData(twoDPB);
696 : LatticeFFT::cfft2d(thisScreen0, false);
697 : }
698 : */
699 : /*
700 : // Now FFT and get the result back
701 : //LatticeFFT::cfft2d(twoDPB);
702 : //LatticeFFT::cfft2d(twoDPB2);
703 :
704 : // Write out FT of screen as an image
705 : if(0) {
706 : CoordinateSystem ftCoords(coords);
707 : directionIndex=ftCoords.findCoordinate(Coordinate::DIRECTION);
708 : AlwaysAssert(directionIndex>=0, AipsError);
709 : dc=coords.directionCoordinate(directionIndex);
710 : Vector<Bool> axes(2); axes(0)=true;axes(1)=true;
711 : Vector<Int> shape(2); shape(0)=convSize_p;shape(1)=convSize_p;
712 : Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape);
713 : ftCoords.replaceCoordinate(*ftdc, directionIndex);
714 : delete ftdc; ftdc=0;
715 : ostringstream os1;
716 : os1 << "FTScreen_" << vb.fieldId() ;
717 : PagedImage<Float> thisScreen(pbShape, ftCoords, String(os1));
718 : LatticeExpr<Float> le(abs(twoDPB2));
719 : thisScreen.copyData(le);
720 : }
721 : */
722 : //cerr << "twoDPB shape " << twoDPB.shape() << " slice shape " << IPosition(4, tempConvSize, tempConvSize, 1, 1) << endl;
723 0 : convFunc_p=twoDPB.getSlice(IPosition(4,0,0,0,0), IPosition(4, tempConvSize, tempConvSize, 1, 1), true);
724 0 : weightConvFunc_p.resize();
725 0 : weightConvFunc_p=twoDPB2.getSlice(IPosition(4,0,0,0,nBeamChans-1), IPosition(4, tempConvSize, tempConvSize, 1, 1), true);
726 : //convFunc/=max(abs(convFunc));
727 0 : Float maxAbsConvFunc=max(amplitude(weightConvFunc_p));
728 :
729 0 : Float minAbsConvFunc=min(amplitude(weightConvFunc_p));
730 : //cerr << "min max " << minAbsConvFunc << " " << maxAbsConvFunc << endl;
731 0 : convSupport_p=-1;
732 0 : Bool found=false;
733 : //Bool found2=true;
734 : //Int trial2=0;
735 0 : Int trial=0;
736 0 : for (trial=tempConvSize/2-2;trial>0;trial--) {
737 : //Searching down a diagonal
738 0 : if(abs(weightConvFunc_p(tempConvSize/2-trial, tempConvSize/2-trial)) > (1.0e-3*maxAbsConvFunc)) {
739 0 : found=true;
740 0 : trial=Int(sqrt(2.0*Float(trial*trial)));
741 0 : break;
742 : }
743 : }
744 0 : if(!found){
745 0 : if((maxAbsConvFunc-minAbsConvFunc) > (1.0e-3*maxAbsConvFunc))
746 0 : found=true;
747 : // if it drops by more than 2 magnitudes per pixel
748 0 : trial=( tempConvSize > (10*convSampling)) ? 5*convSampling : (tempConvSize/2 - 4*convSampling);
749 : }
750 :
751 0 : if(trial < 5*convSampling)
752 0 : trial=( tempConvSize > (10*convSampling)) ? 5*convSampling : (tempConvSize/2 - 4*convSampling);
753 :
754 0 : if(found) {
755 0 : convSupport_p=Int(0.5+Float(trial)/Float(convSampling))+1;
756 : }
757 : else {
758 : os << "Convolution function is misbehaved - support seems to be zero\n"
759 : << "Reasons can be: \n(1)The image definition not covering one or more of the pointings selected\n"
760 : << "(2) No unflagged data in a given pointing\n"
761 : << "(3) The entries in the POINTING subtable do not match the field being imaged."
762 : << "Please check, and try again with an empty POINTING subtable.)\n"
763 0 : << LogIO::EXCEPTION;
764 : }
765 :
766 : // Normalize such that plane 0 sums to 1 (when jumping in
767 : // steps of convSampling)
768 :
769 0 : Double pbSum=0.0;
770 : //Double pbSum2=0.0;
771 :
772 :
773 0 : for (Int iy=-convSupport_p;iy<=convSupport_p;iy++) {
774 0 : for (Int ix=-convSupport_p;ix<=convSupport_p;ix++) {
775 0 : Complex val=convFunc_p(ix*convSampling+tempConvSize/2,
776 0 : iy*convSampling+tempConvSize/2);
777 0 : pbSum+=real(val);
778 :
779 : //pbSum+=sqrt(real(val)*real(val)+ imag(val)*imag(val));
780 : }
781 : }
782 :
783 :
784 : //pbSum=sum(amplitude(convFunc_p))/Double(convSampling)/Double(convSampling);
785 :
786 0 : if(pbSum>0.0) {
787 0 : convFunc_p*=Complex(1.0/pbSum,0.0);
788 : }
789 : else {
790 : os << "Convolution function integral is not positive"
791 0 : << LogIO::EXCEPTION;
792 : }
793 :
794 : //##########################################
795 : os << "Convolution support = " << convSupport_p
796 : << " pixels in Fourier plane"
797 0 : << LogIO::POST;
798 :
799 0 : convSupportBlock_p.resize(actualConvIndex_p+1);
800 0 : convSizes_p.resize(actualConvIndex_p+1);
801 : //Only one beam for now...but later this should be able to
802 : // take all the beams for the different antennas.
803 0 : convSupportBlock_p[actualConvIndex_p]=new Vector<Int>(1);
804 0 : convSizes_p[actualConvIndex_p]=new Vector<Int> (1);
805 0 : (*(convSupportBlock_p[actualConvIndex_p]))[0]=convSupport_p;
806 0 : convFunctions_p.resize(actualConvIndex_p+1);
807 0 : convWeights_p.resize(actualConvIndex_p+1);
808 0 : convFunctions_p[actualConvIndex_p]= new Array<Complex>();
809 0 : convWeights_p[actualConvIndex_p]= new Array<Complex>();
810 0 : Int newConvSize=2*(convSupport_p+2)*convSampling;
811 : //NEED to chop this right ...and in the centre
812 0 : if(newConvSize >=tempConvSize)
813 0 : newConvSize=tempConvSize;
814 :
815 0 : IPosition blc(4, (tempConvSize/2)-(newConvSize/2),
816 0 : (tempConvSize/2)-(newConvSize/2), 0, 0);
817 0 : IPosition trc(4, (tempConvSize/2)+(newConvSize/2-1),
818 0 : (tempConvSize/2)+(newConvSize/2-1), 0, nBeamChans-1);
819 0 : convFunctions_p[actualConvIndex_p]->resize(IPosition(5, newConvSize, newConvSize, 1, nBeamChans,1));
820 : //cerr << "convFunc shape " << (convFunctions_p[actualConvIndex_p])->shape() <<
821 : //" " << " twoDPB shape " <<twoDPB.get(false)(blc,trc).shape() << endl;
822 0 : convFunctions_p[actualConvIndex_p]->copyMatchingPart(twoDPB.get(false)(blc,trc));//*Complex(1.0/pbSum,0.0));
823 0 : convSize_p=newConvSize;
824 0 : convWeights_p[actualConvIndex_p]->resize(IPosition(5, newConvSize, newConvSize, 1, nBeamChans,1));
825 0 : convWeights_p[actualConvIndex_p]->copyMatchingPart(twoDPB2.get(false)(blc,trc));//*Complex(1.0/pbSum2,0.0));
826 0 : blc.resize(5, false);
827 0 : trc.resize(5,false);
828 0 : blc=IPosition(5, 0, 0, 0, 0,0);
829 0 : trc=IPosition(5, newConvSize-1, newConvSize-1, 0, 0,0);
830 0 : for (Int bc=0; bc< nBeamChans; ++bc){
831 0 : blc[3]=bc;
832 0 : trc[3]=bc;
833 0 : pbSum=real(sum((*convFunctions_p[actualConvIndex_p])(blc,trc)))/Double(convSampling)/Double(convSampling);
834 0 : (*convFunctions_p[actualConvIndex_p])(blc,trc)= (*convFunctions_p[actualConvIndex_p])(blc,trc)/pbSum;
835 0 : (*convWeights_p[actualConvIndex_p])(blc,trc)= (*convWeights_p[actualConvIndex_p])(blc,trc)/pbSum;
836 : }
837 :
838 :
839 :
840 0 : convFunc_p.resize();//break any reference
841 0 : (*convSizes_p[actualConvIndex_p])[0]=convSize_p;
842 0 : doneMainConv_p[actualConvIndex_p]=true;
843 :
844 : }
845 : else{
846 0 : convSize_p=(*convSizes_p[actualConvIndex_p])[0];
847 :
848 : }
849 :
850 : //Apply the shift phase gradient
851 0 : convFunc.resize();
852 0 : weightConvFunc.resize();
853 0 : convFunc.assign(*(convFunctions_p[actualConvIndex_p]));
854 0 : weightConvFunc.assign(*(convWeights_p[actualConvIndex_p]));
855 : Bool copyconv, copywgt;
856 0 : Complex *cv=convFunc.getStorage(copyconv);
857 0 : Complex *wcv=weightConvFunc.getStorage(copywgt);
858 : //cerr << "Field " << vb.fieldId() << " spw " << vb.spectralWindow() << " phase grad: " << pixFieldDir << endl;
859 :
860 0 : for (Int nc=0; nc < nBeamChans; ++nc){
861 0 : Int planeoffset=nc*convSize_p*convSize_p;
862 0 : for (Int iy=0;iy<convSize_p;iy++) {
863 : Double cy, sy;
864 : Int offset;
865 :
866 0 : SINCOS(Double(iy-convSize_p/2)*pixFieldDir(1), sy, cy);
867 0 : Complex phy(cy,sy) ;
868 0 : offset = iy*convSize_p+planeoffset;
869 0 : for (Int ix=0;ix<convSize_p;ix++) {
870 : Double cx, sx;
871 0 : SINCOS(Double(ix-convSize_p/2)*pixFieldDir(0), sx, cx);
872 0 : Complex phx(cx,sx) ;
873 0 : cv[ix+offset]= cv[ix+offset]*phx*phy;
874 0 : wcv[ix+offset]= wcv[ix+offset]*phx*phy;
875 :
876 : }
877 : }
878 : }
879 0 : convFunc.putStorage(cv, copyconv);
880 0 : weightConvFunc.putStorage(wcv, copywgt);
881 0 : convsize.resize();
882 0 : convsize=*(convSizes_p[actualConvIndex_p]);
883 0 : convSupport.resize();
884 0 : convSupport=(*(convSupportBlock_p[actualConvIndex_p]));
885 :
886 :
887 0 : }
888 :
889 0 : void SimplePBConvFunc::setSkyJones(SkyJones* sj){
890 0 : sj_p=sj;
891 0 : }
892 :
893 0 : void SimplePBConvFunc::findUsefulChannels(Vector<Int>& chanMap, Vector<Double>& chanFreqs, const VisBuffer& vb, const Vector<Double>& freq){
894 0 : chanMap.resize(freq.nelements());
895 0 : Vector<Double> localfreq=vb.frequency();
896 0 : Double minfreq=min(freq);
897 :
898 0 : Double origwidth=freq.nelements()==1 ? 1e12 : (max(freq)-min(freq))/(freq.nelements()-1);
899 : ///Fractional bandwidth which will trigger mutiple PB in one spw
900 0 : Double tol=(max(freq))*0.5/100;
901 0 : Int nchan=Int(lround((max(freq)-min(freq))/tol));
902 :
903 : //cerr << "TOLERA " << tol << " nchan " << nchan << " vb.nchan " << vb.nChannel() << endl;
904 : //Number of beams that matters are the ones in the data
905 0 : if(nchan > vb.nChannel())
906 0 : nchan=vb.nChannel();
907 :
908 0 : if(tol < origwidth) tol=origwidth;
909 0 : chanFreqs.resize();
910 0 : if(nchan >= (Int)(freq.nelements()-1)) { indgen(chanMap); chanFreqs=freq; return;}
911 0 : if((nchan==0) || (freq.nelements()==1)) { chanFreqs=Vector<Double>(1, freq[0]);chanMap.set(0); return;}
912 :
913 : //readjust the tolerance...
914 0 : tol=(max(freq)-min(freq)+origwidth)/Double(nchan);
915 0 : chanFreqs.resize(nchan);
916 0 : for (Int k=0; k < nchan; ++k)
917 0 : chanFreqs[k]=minfreq-origwidth+tol/2.0+tol*Double(k);
918 0 : Int activechan=0;
919 0 : chanMap.set(-1);
920 0 : for (uInt k=0; k < chanMap.nelements(); ++k){
921 :
922 0 : while((activechan< nchan) && Float(fabs(freq[k]-chanFreqs[activechan])) > Float(tol/2.0)){
923 : // cerr << "k " << k << " atcivechan " << activechan << " comparison "
924 : // << freq[k] << " " << chanFreqs[activechan] << endl;
925 0 : ++activechan;
926 : }
927 0 : if(activechan != nchan)
928 0 : chanMap[k]=activechan;
929 : //////////////////
930 : //if(chanMap[k] < 0)
931 : //cerr << "freq diffs " << freq[k]-chanFreqs << " TOL " << tol/2.0 << endl;
932 :
933 : ///////////////////////////
934 0 : activechan=0;
935 : }
936 :
937 0 : return;
938 : }
939 :
940 :
941 0 : Bool SimplePBConvFunc::checkPBOfField(const VisBuffer& vb){
942 : //Int fieldid=vb.fieldId();
943 0 : String msid=vb.msName(true);
944 : /*
945 : if(convFunctionMap_p.ndefined() > 0){
946 : if (((fluxScale_p.shape()[3] != nchan_p) || (fluxScale_p.shape()[2] != npol_p)) && calcFluxScale_p){
947 : convFunctionMap_p.clear();
948 : }
949 : }
950 : // if you rename the ms might be a problem
951 : String mapid=msid+String("_")+String::toString(fieldid);
952 : if(convFunctionMap_p.ndefined() == 0){
953 : convFunctionMap_p.define(mapid, 0);
954 : actualConvIndex_p=0;
955 : if(calcFluxScale_p){
956 : // 0ne channel only is needed to keep track of pb coverage
957 : if(fluxScale_p.shape().nelements()==0){
958 : fluxScale_p=TempImage<Float>(IPosition(4,nx_p,ny_p,npol_p,1), csys_p);
959 : fluxScale_p.set(0.0);
960 : }
961 : filledFluxScale_p=false;
962 : }
963 : return false;
964 : }
965 :
966 : if(!convFunctionMap_p.isDefined(mapid)){
967 : actualConvIndex_p=convFunctionMap_p.ndefined();
968 : convFunctionMap_p.define(mapid, actualConvIndex_p);
969 : return false;
970 : }
971 : else{
972 : actualConvIndex_p=convFunctionMap_p(mapid);
973 : convFunc_p.resize(); // break any reference
974 : weightConvFunc_p.resize();
975 : //Here we will need to use the right xyPlane for different PA range.
976 : //convFunc_p.reference(convFunctions_p[actualConvIndex_p]->xyPlane(0));
977 : //weightConvFunc_p.reference(convWeights_p[actualConvIndex_p]->xyPlane(0));
978 : //Again this for one time of antenna only later should be fixed for all
979 : // antennas independently
980 : convSupport_p=(*convSupportBlock_p[actualConvIndex_p])[0];
981 : convSize_p=(*convSizes_p[actualConvIndex_p])[0];
982 :
983 : }
984 : */
985 :
986 0 : return true;
987 :
988 :
989 :
990 : }
991 0 : ImageInterface<Float>& SimplePBConvFunc::getFluxScaleImage(){
992 :
993 0 : if(!calcFluxScale_p)
994 0 : throw(AipsError("Programmer error: Cannot get flux scale"));
995 0 : if(!filledFluxScale_p){
996 0 : IPosition blc=fluxScale_p.shape();
997 0 : IPosition trc=fluxScale_p.shape();
998 0 : blc(0)=0; blc(1)=0; trc(0)=nx_p-1; trc(1)=ny_p-1;
999 :
1000 0 : for (Int j=0; j < fluxScale_p.shape()(2); ++j){
1001 0 : for (Int k=0; k < fluxScale_p.shape()(3) ; ++k){
1002 :
1003 0 : blc(2)=j; trc(2)=j;
1004 0 : blc(3)=k; trc(3)=k;
1005 0 : Slicer sl(blc, trc, Slicer::endIsLast);
1006 0 : SubImage<Float> fscalesub(fluxScale_p, sl, true);
1007 : Float planeMax;
1008 0 : LatticeExprNode LEN = max( fscalesub );
1009 0 : planeMax = LEN.getFloat();
1010 0 : if(planeMax !=0){
1011 0 : fscalesub.copyData( (LatticeExpr<Float>) (fscalesub/planeMax));
1012 :
1013 : }
1014 : }
1015 : }
1016 :
1017 0 : filledFluxScale_p=true;
1018 : }
1019 :
1020 :
1021 0 : return fluxScale_p;
1022 :
1023 : }
1024 :
1025 :
1026 0 : Bool SimplePBConvFunc::toRecord(RecordInterface& rec){
1027 0 : Int numConv=convFunctions_p.nelements();
1028 : // not saving the protected variables as they are generated by
1029 : // the first call to storeImageParams
1030 : try{
1031 0 : rec.define("name", "SimplePBConvFunc");
1032 0 : rec.define("numconv", numConv);
1033 : //cerr << "num of conv " << numConv << " " << convFunctionMap_p.ndefined() << " " <<convFunctions_p.nelements() << endl;
1034 0 : std::map<String, Int>::iterator it=vbConvIndex_p.begin();
1035 0 : for (Int k=0; k < numConv; ++k){
1036 0 : rec.define("convfunctions"+String::toString(k), *(convFunctions_p[k]));
1037 0 : rec.define("convweights"+String::toString(k), *(convWeights_p[k]));
1038 0 : rec.define("convsizes"+String::toString(k), *(convSizes_p[k]));
1039 0 : rec.define("convsupportblock"+String::toString(k), *(convSupportBlock_p[k]));
1040 : //cerr << "k " << k << " key " << convFunctionMap_p.getKey(k) << " val " << convFunctionMap_p.getVal(k) << endl;
1041 0 : rec.define(String("key")+String::toString(k), it->first);
1042 0 : rec.define(String("val")+String::toString(k), it->second);
1043 0 : it++;
1044 : }
1045 0 : rec.define("pbclass", Int(pbClass_p));
1046 0 : rec.define("actualconvindex", actualConvIndex_p);
1047 0 : rec.define("donemainconv", doneMainConv_p);
1048 : //The following is not needed ..can be regenerated
1049 : //rec.define("pointingpix", pointingPix_p);
1050 : }
1051 0 : catch(AipsError &x) {
1052 0 : return false;
1053 : }
1054 0 : return true;
1055 : }
1056 :
1057 0 : Bool SimplePBConvFunc::fromRecord(String& err, const RecordInterface& rec, Bool calcFluxneeded){
1058 0 : Int numConv=0;
1059 : //make sure storeImageParams is triggered
1060 0 : nchan_p=0;
1061 :
1062 : try{
1063 0 : if(!rec.isDefined("name") || rec.asString("name") != "SimplePBConvFunc"){
1064 0 : throw(AipsError("Wrong record to recover SimplePBConvFunc from"));
1065 : }
1066 0 : rec.get("numconv", numConv);
1067 0 : convFunctions_p.resize(numConv, true, false);
1068 0 : convSupportBlock_p.resize(numConv, true, false);
1069 0 : convWeights_p.resize(numConv, true, false);
1070 0 : convSizes_p.resize(numConv, true, false);
1071 0 : convFunctionMap_p.clear( );
1072 0 : vbConvIndex_p.erase(vbConvIndex_p.begin(), vbConvIndex_p.end());
1073 0 : for (Int k=0; k < numConv; ++k){
1074 0 : convFunctions_p[k]=new Array<Complex>();
1075 0 : convWeights_p[k]=new Array<Complex>();
1076 0 : convSizes_p[k]=new Vector<Int>();
1077 0 : convSupportBlock_p[k]=new Vector<Int>();
1078 0 : rec.get("convfunctions"+String::toString(k), *(convFunctions_p[k]));
1079 0 : rec.get("convsupportblock"+String::toString(k), *(convSupportBlock_p[k]));
1080 0 : rec.get("convweights"+String::toString(k), *(convWeights_p[k]));
1081 0 : rec.get("convsizes"+String::toString(k), *(convSizes_p[k]));
1082 0 : String key;
1083 : Int val;
1084 0 : rec.get(String("key")+String::toString(k), key);
1085 0 : rec.get(String("val")+String::toString(k), val);
1086 0 : vbConvIndex_p[key]=val;
1087 0 : ant1PointVal_p.clear();
1088 0 : ant1PointingCache_p.resize();
1089 : //convFunctionMap_p.define(key,val);
1090 : }
1091 0 : pbClass_p=static_cast<PBMathInterface::PBClass>(rec.asInt("pbclass"));
1092 0 : rec.get("actualconvindex", actualConvIndex_p);
1093 0 : pointingPix_p.resize();
1094 : //rec.get("pointingpix", pointingPix_p);
1095 0 : calcFluxScale_p=calcFluxneeded;
1096 :
1097 : }
1098 0 : catch(AipsError & x) {
1099 0 : err=x.getMesg();
1100 0 : return false;
1101 : }
1102 0 : return true;
1103 :
1104 : }
1105 0 : void SimplePBConvFunc::addPBToFlux(const VisBuffer& vb){
1106 :
1107 0 : if(calcFluxScale_p){
1108 0 : if(fluxScale_p.shape().nelements()==0)
1109 : { //cerr << "nx_p " << nx_p << endl;
1110 0 : calcFluxScale_p=False;
1111 0 : return;
1112 : }
1113 0 : Vector<Int> pixdepoint(2, -100000);
1114 0 : convertArray(pixdepoint, thePix_p);
1115 0 : if((pixdepoint(0) >=0) && (pixdepoint(0) < pointingPix_p.shape()[0]) && (pixdepoint(1) >=0) && (pixdepoint(1) < pointingPix_p.shape()[1]) && !pointingPix_p(pixdepoint(0), pixdepoint(1))){
1116 0 : TempImage<Float> thispb(fluxScale_p.shape(), fluxScale_p.coordinates());
1117 0 : thispb.set(1.0);
1118 0 : sj_p->applySquare(thispb, thispb, vb, 0);
1119 0 : LatticeExpr<Float> le(fluxScale_p+thispb);
1120 0 : fluxScale_p.copyData(le);
1121 0 : pointingPix_p(pixdepoint(0), pixdepoint(1))=true;
1122 : //LatticeExprNode LEN = max(fluxScale_p);
1123 : //Float maxsca=LEN.getFloat();
1124 : //Tempporary fix when cubesky is chunking...do not add on
1125 : //already defined position
1126 : //if(maxsca > 1.98){
1127 : // cerr << "avoiding subtract " << endl;
1128 : //fluxScale_p.copyData(LatticeExpr<Float>(fluxScale_p-thispb));
1129 :
1130 : //}
1131 : /*
1132 : if(0) {
1133 : ostringstream os1;
1134 : os1 << "SINGLE_" << vb.fieldId() ;
1135 : PagedImage<Float> thisScreen(fluxScale_p.shape(), fluxScale_p.coordinates(), String(os1));
1136 : thisScreen.copyData(thispb);
1137 : ostringstream os2;
1138 : os2 << "ALL_" << vb.fieldId() ;
1139 : PagedImage<Float> thisScreen2(fluxScale_p.shape(), fluxScale_p.coordinates(), String(os2));
1140 : thisScreen2.copyData(fluxScale_p);
1141 : }
1142 : */
1143 : }
1144 : }
1145 :
1146 : }
1147 :
1148 0 : void SimplePBConvFunc::sliceFluxScale(Int npol) {
1149 0 : IPosition fshp=fluxScale_p.shape();
1150 0 : if (fshp(2)>npol){
1151 0 : npol_p=npol;
1152 : // use first npol planes...
1153 0 : IPosition blc(4,0,0,0,0);
1154 0 : IPosition trc(4,fluxScale_p.shape()(0)-1, fluxScale_p.shape()(1)-1,npol-1,fluxScale_p.shape()(3)-1);
1155 0 : Slicer sl=Slicer(blc, trc, Slicer::endIsLast);
1156 : //writeable if possible
1157 0 : SubImage<Float> fluxScaleSub = SubImage<Float> (fluxScale_p, sl, true);
1158 0 : fluxScale_p = TempImage<Float>(fluxScaleSub.shape(),fluxScaleSub.coordinates());
1159 0 : LatticeExpr<Float> le(fluxScaleSub);
1160 0 : fluxScale_p.copyData(le);
1161 : }
1162 0 : }
1163 :
1164 : } //# NAMESPACE CASA - END
1165 :
1166 :
1167 :
1168 :
1169 :
1170 :
1171 :
|