Line data Source code
1 : /*
2 : * MSUVBin.cc implementation of gridding MSs to a gridded MS
3 : //#
4 : //# CASA - Common Astronomy Software Applications (http://casa.nrao.edu/)
5 :
6 : //# Copyright (C) 2014-2015
7 : //# Associated Universities, Inc. Washington DC, USA.
8 : //#
9 : //# This library is free software; you can redistribute it and/or modify it
10 : //# under the terms of the GNU General Public License as published by
11 : //# the Free Software Foundation; either version 3 of the License, or (at your
12 : //# option) any later version.
13 : //#
14 : //# This library is distributed in the hope that it will be useful, but WITHOUT
15 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 : //# License for more details.
18 : //#
19 : //# You should have received a copy of the GNU General Public License
20 : //# along with this library; if not, write to the Free Software Foundation,
21 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
22 : //#
23 :
24 : //# Postal address:
25 : //# National Radio Astronomy Observatory
26 : //# 520 Edgemont Road
27 : //# Charlottesville, VA 22903-2475 USA
28 : //#
29 : *
30 : * Created on: Feb 4, 2014
31 : * Author: kgolap
32 : */
33 :
34 : #include <casacore/casa/Arrays/ArrayMath.h>
35 : #include <casacore/casa/Arrays/Array.h>
36 : #include <casacore/casa/Arrays/Matrix.h>
37 : #include <casacore/casa/Arrays/Cube.h>
38 : #include <casacore/casa/Arrays/Vector.h>
39 : #include <casacore/casa/OS/HostInfo.h>
40 :
41 : #include <casacore/casa/System/ProgressMeter.h>
42 : #include <casacore/casa/Quanta/QuantumHolder.h>
43 : #include <casacore/casa/Utilities/CompositeNumber.h>
44 : #include <casacore/measures/Measures/MeasTable.h>
45 : #include <casacore/ms/MeasurementSets/MSPolColumns.h>
46 : #include <casacore/ms/MeasurementSets/MSPolarization.h>
47 : #include <mstransform/MSTransform/MSUVBin.h>
48 : #include <mstransform/MSTransform/MSTransformDataHandler.h>
49 : #include <casacore/coordinates/Coordinates/CoordinateSystem.h>
50 : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
51 : #include <casacore/coordinates/Coordinates/SpectralCoordinate.h>
52 : #include <casacore/coordinates/Coordinates/StokesCoordinate.h>
53 : #include <casacore/images/Images/PagedImage.h>
54 : #include <casacore/images/Images/TempImage.h>
55 : #include <msvis/MSVis/MSUtil.h>
56 : #include <msvis/MSVis/VisBuffer.h>
57 : #include <msvis/MSVis/VisBuffer2Adapter.h>
58 : #include <imageanalysis/Utilities/SpectralImageUtil.h>
59 : #include <msvis/MSVis/VisibilityIterator2.h>
60 : #include <casacore/scimath/Mathematics/FFTPack.h>
61 : #include <casacore/scimath/Mathematics/ConvolveGridder.h>
62 : #include <wcslib/wcsconfig.h> /** HAVE_SINCOS **/
63 : #include <math.h>
64 : #ifdef _OPENMP
65 : #include <omp.h>
66 : #endif
67 : #if HAVE_SINCOS
68 : #define SINCOS(a,s,c) sincos(a,&s,&c)
69 : #else
70 : #define SINCOS(a,s,c) \
71 : s = sin(a); \
72 : c = cos(a)
73 : #endif
74 :
75 :
76 : typedef unsigned long long ooLong;
77 :
78 : using namespace casacore;
79 : namespace casa { //# NAMESPACE CASA - BEGIN
80 :
81 4 : MSUVBin::MSUVBin():nx_p(0), ny_p(0), nchan_p(0), npol_p(0),existOut_p(false),numVis_p(), sumWeight_p(){
82 4 : outMsPtr_p=NULL;
83 4 : outMSName_p="OutMS.ms";
84 4 : memFraction_p=0.5;
85 4 : }
86 4 : MSUVBin::MSUVBin(const MDirection& phaseCenter,
87 4 : const Int nx, const Int ny, const Int nchan, const Int npol, Quantity cellx, Quantity celly, Quantity freqStart, Quantity freqStep, Float memFraction, Bool dow, Bool doflag):
88 4 : existOut_p(false)
89 :
90 : {
91 4 : phaseCenter_p=phaseCenter;
92 4 : nx_p=nx;
93 4 : ny_p=ny;
94 4 : nchan_p=nchan;
95 4 : npol_p=npol;
96 4 : numVis_p.resize(npol, nchan);
97 4 : sumWeight_p.resize(npol, nchan);
98 4 : numVis_p.set(0);
99 4 : sumWeight_p.set(0);
100 4 : deltas_p.resize(2);
101 4 : deltas_p[0]=cellx.getValue("rad");
102 4 : deltas_p[1]=celly.getValue("rad");
103 4 : freqStart_p=freqStart.getValue("Hz");
104 4 : freqStep_p=freqStep.getValue("Hz");
105 4 : outMsPtr_p=NULL;
106 4 : outMSName_p="OutMS.ms";
107 4 : memFraction_p=memFraction;
108 4 : doW_p=dow;
109 4 : doFlag_p=doflag;
110 :
111 4 : }
112 :
113 8 : MSUVBin::~MSUVBin(){
114 : //close the measurementsets
115 12 : for (uInt k=0; k < mss_p.nelements(); ++k){
116 4 : (const_cast<MeasurementSet *>(mss_p[k]))->unlock();
117 4 : *(const_cast<MeasurementSet *>(mss_p[k]))=MeasurementSet();
118 : }
119 8 : }
120 4 : Bool MSUVBin::selectData(const String& msname, const String& spw, const String& field,
121 : const String& baseline, const String& scan,
122 : const String& uvrange, const String& taql,
123 : const String& subarray, const String& correlation,const String& intent, const String& obs){
124 :
125 4 : Vector<Int> fakestep = Vector<Int> (1, 1);
126 :
127 4 : MSTransformDataHandler mshandler(msname, doFlag_p ? Table::Update: Table::Old);
128 : //No very well documented what the step is supposed to do
129 : //using the default value here
130 4 : if(mshandler.setmsselect(spw, field, baseline, scan, uvrange,
131 : taql, fakestep, subarray, correlation, intent, obs)){
132 4 : mss_p.resize(mss_p.nelements()+1);
133 4 : mshandler.makeSelection();
134 : // have to make a copy here as the selected ms pointer of mshandler
135 : // dies with mshandler
136 4 : mss_p[mss_p.nelements()-1]=new MeasurementSet(*mshandler.getSelectedInputMS());
137 : }
138 : else
139 0 : return false;
140 :
141 : // cerr << "num of ms" << mss_p.nelements() << " ms0 " << (mss_p[0])->tableName() << " nrows " << (mss_p[0])->nrow() << endl;
142 4 : return true;
143 4 : }
144 :
145 4 : void MSUVBin::setOutputMS(const String& msname){
146 4 : outMSName_p=msname;
147 4 : checkOutputGridParams();
148 4 : }
149 :
150 :
151 4 : void MSUVBin::createOutputMS(const Int nrrow){
152 4 : if(Table::isReadable(outMSName_p)){
153 2 : Int oldnrows=recoverGridInfo(outMSName_p);
154 2 : if(oldnrows != nrrow)
155 0 : throw(AipsError("Number of grid points requested "+ String::toString(nrrow)+ " does not match "+String::toString(oldnrows)+ " in outputms"));
156 2 : existOut_p=true;
157 2 : return;
158 : }
159 2 : if(mss_p.nelements()==0)
160 0 : throw(AipsError("no ms selected for input yet"));
161 2 : Vector<Int> tileShape(3);
162 2 : tileShape[0]=4; tileShape[1]=200; tileShape[2]=500;
163 2 : auto wtSpec = MSColumns(*mss_p[0]).weightSpectrum();
164 : //auto createdWeightSpectrumCols = !wtSpec.isNull() && wtSpec.isDefined(0);
165 2 : outMsPtr_p = MSTransformDataHandler::setupMS(outMSName_p, nchan_p, npol_p,
166 4 : Vector<MS::PredefinedColumns>(1, MS::DATA),
167 2 : True, tileShape);
168 2 : outMsPtr_p->addRow(nrrow, true);
169 : //cerr << "mss Info " << mss_p[0]->tableName() << " " << mss_p[0]->nrow() <<endl;
170 2 : MSTransformDataHandler::addOptionalColumns(mss_p[0]->spectralWindow(),
171 2 : outMsPtr_p->spectralWindow());
172 : ///Setup pointing why this is not done in setupMS
173 : {
174 2 : SetupNewTable pointingSetup(outMsPtr_p->pointingTableName(),
175 4 : MSPointing::requiredTableDesc(), Table::New);
176 : // POINTING can be large, set some sensible defaults for storageMgrs
177 2 : IncrementalStMan ismPointing ("ISMPointing");
178 2 : StandardStMan ssmPointing("SSMPointing", 32768);
179 2 : pointingSetup.bindAll(ismPointing, true);
180 2 : pointingSetup.bindColumn(MSPointing::columnName(MSPointing::DIRECTION),
181 : ssmPointing);
182 2 : pointingSetup.bindColumn(MSPointing::columnName(MSPointing::TARGET),
183 : ssmPointing);
184 2 : pointingSetup.bindColumn(MSPointing::columnName(MSPointing::TIME),
185 : ssmPointing);
186 4 : outMsPtr_p->rwKeywordSet().defineTable(MS::keywordName(MS::POINTING),
187 4 : Table(pointingSetup));
188 2 : outMsPtr_p->initRefs();
189 2 : }
190 2 : TableCopy::copySubTables(outMsPtr_p->pointing(), (mss_p[0])->pointing());
191 2 : if(doW_p){
192 0 : TiledShapeStMan tiledStMan("TiledImagWgtSpectrum", tileShape);
193 0 : outMsPtr_p->addColumn(ArrayColumnDesc<Float>("IMAGINARY_WEIGHT_SPECTRUM",2), tiledStMan);
194 0 : ArrayColumn<Float> imagWgtSpecCol(*outMsPtr_p, "IMAGINARY_WEIGHT_SPECTRUM");
195 0 : imagWgtSpecCol.fillColumn(Matrix<Float>(npol_p, nchan_p, 0.0));
196 0 : }
197 2 : MSColumns msc(*outMsPtr_p);
198 2 : msc.data().fillColumn(Matrix<Complex>(npol_p, nchan_p, Complex(0.0)));
199 2 : msc.flagRow().fillColumn(true);
200 2 : msc.flag().fillColumn(Matrix<Bool>(npol_p, nchan_p, true));
201 2 : msc.weight().fillColumn(Vector<Float>(npol_p, 0.0));
202 2 : msc.sigma().fillColumn(Vector<Float>(npol_p, 0.0));
203 2 : msc.weightSpectrum().fillColumn(Matrix<Float>(npol_p, nchan_p, 0.0));
204 2 : msc.antenna1().fillColumn(0);
205 2 : msc.antenna2().fillColumn(0);
206 : //change array id for every 2000 rows
207 2 : Vector<Int> arrayID(nrrow,0);
208 2 : Int blk=2000;
209 2 : Int naid=nrrow/blk;
210 2 : IPosition blc(1,0);
211 2 : IPosition trc(1,0);
212 92 : for (Int k=0; k < naid; ++k){
213 90 : blc[0]=k*blk;
214 90 : trc[0]= (k < (naid-1)) ? (k+1)*blk-1 : (k+1)*blk+nrrow%blk-1;
215 90 : arrayID(blc, trc)=k;
216 : }
217 : //cerr << "MINMAX array ID " << min(arrayID) << " " << max(arrayID) << endl;
218 2 : msc.arrayId().putColumn(arrayID);
219 : // Note: we suspect this flush with sync=true (fsync!) can be removed (it is
220 : // commented out in other functions in this same file. See CAS-11946.
221 2 : outMsPtr_p->flush(true);
222 :
223 2 : existOut_p=false;
224 :
225 2 : }
226 4 : bool MSUVBin::checkOutputGridParams(){
227 : //Table does not exist nothing to check
228 4 : if(!Table::isReadable(outMSName_p))
229 2 : return true;
230 2 : MeasurementSet theGridMS(outMSName_p, Table::Old);
231 2 : if(!theGridMS.keywordSet().isDefined("MSUVBIN")){
232 0 : throw(AipsError("The ms "+outMSName_p+" was not made with the UV binner"));
233 : }
234 2 : Record rec=theGridMS.keywordSet().asRecord("MSUVBIN");
235 : Int nx, ny, nchan, npol;
236 2 : rec.get("nx", nx);
237 2 : rec.get("ny", ny);
238 2 : rec.get("nchan", nchan);
239 2 : rec.get("npol", npol);
240 2 : if(!doFlag_p){
241 2 : if(nx != nx_p || ny != ny_p || nchan != nchan_p || npol != npol_p){
242 0 : LogIO os(LogOrigin("MSUVBin", "checkGridParams", WHERE));
243 0 : os << LogIO::SEVERE << "Output is a binned ms of "<< nx << " by " << ny << " with "<< npol << " pol and "<< nchan << " channels where as user has given [" << nx_p << ", " << ny_p << ", " << npol_p << ", " << nchan_p << "]" << LogIO::POST;
244 0 : return false;
245 0 : }
246 : }
247 : CoordinateSystem *tempCoordsys;
248 2 : tempCoordsys=CoordinateSystem::restore(rec, "csys");
249 2 : if(tempCoordsys==NULL)
250 0 : throw(AipsError("could recover grid info from ms"));
251 :
252 2 : Vector<Double> pixelPhaseCenter(2);
253 2 : pixelPhaseCenter(0) = Double( nx / 2 );
254 2 : pixelPhaseCenter(1) = Double( ny / 2 );
255 2 : MDirection phcen;
256 2 : (tempCoordsys->directionCoordinate(0)).toWorld(phcen, pixelPhaseCenter);
257 2 : if(!doFlag_p && ((phaseCenter_p.getRefPtr()->getType()) != ((phcen.getRefPtr())->getType()))){
258 0 : throw(AipsError("Requested output frame is not the same as what was used with existant "+outMSName_p));
259 : }
260 2 : MVDirection mvphcen=phcen.getValue();
261 2 : Double sep=mvphcen.separation(phaseCenter_p.getValue());
262 2 : if(!doFlag_p && (sep > 2.0*(tempCoordsys->directionCoordinate(0)).increment()(0)))
263 : {
264 0 : std::ostringstream oss;
265 0 : oss << "stored is " << phcen.toString();
266 0 : oss << " user requested " <<phaseCenter_p.toString();
267 0 : throw(AipsError("phasecentre requested is not the same as stored in "+outMSName_p+ " " +String(oss.str())));
268 0 : }
269 2 : if(!doFlag_p){
270 : //check pixel size
271 2 : DirectionCoordinate dc=tempCoordsys->directionCoordinate(0);
272 2 : dc.setWorldAxisUnits(Vector<String>(2, "rad"));
273 2 : Vector<Double> incr=dc.increment();
274 2 : if(deltas_p[0] != incr[0] || deltas_p[1] != incr[1]){
275 0 : std::ostringstream oss;
276 0 : oss << "stored is [" << incr[0] << ", "<< incr[1]<< "] radians" ;
277 0 : oss << " user requested [" << deltas_p[0] << ", "<< deltas_p[1]<< "] radians" ;
278 0 : throw(AipsError("increment in image domain requested is not the same as stored in "+outMSName_p+ " " +String(oss.str())));
279 0 : }
280 :
281 2 : }
282 :
283 : // When transferring flags we don't care about the input params we take
284 : // what is stored
285 2 : if(doFlag_p){
286 0 : nx_p=nx;
287 0 : ny_p=ny;
288 0 : nchan_p=nchan;
289 0 : npol_p=npol;
290 0 : csys_p=*tempCoordsys;
291 0 : phaseCenter_p=phcen;
292 : }
293 :
294 2 : delete tempCoordsys;
295 2 : return true;
296 :
297 2 : }
298 2 : Int MSUVBin::recoverGridInfo(const String& msname){
299 2 : outMsPtr_p=new MeasurementSet(msname, Table::Update);
300 2 : if(!outMsPtr_p->keywordSet().isDefined("MSUVBIN")){
301 0 : throw(AipsError("The ms "+msname+" was not made with the UV binner"));
302 : }
303 2 : Record rec=outMsPtr_p->keywordSet().asRecord("MSUVBIN");
304 2 : rec.get("nx", nx_p);
305 2 : rec.get("ny", ny_p);
306 2 : rec.get("nchan", nchan_p);
307 2 : rec.get("npol", npol_p);
308 4 : LogIO os(LogOrigin("MSUVBin", "recoverInfo", WHERE));
309 2 : os << "Output is a binned ms of "<< nx_p << " by " << ny_p << " with "<< npol_p << " pol and "<< nchan_p << " channel " << endl;
310 : CoordinateSystem *tempCoordsys;
311 2 : tempCoordsys=CoordinateSystem::restore(rec, "csys");
312 2 : if(tempCoordsys==NULL)
313 0 : throw(AipsError("could recover grid info from ms"));
314 2 : csys_p=*tempCoordsys;
315 2 : delete tempCoordsys;
316 2 : numVis_p.resize();
317 2 : rec.get("numvis", numVis_p);
318 2 : sumWeight_p.resize();
319 2 : rec.get("sumweight", sumWeight_p);
320 4 : return outMsPtr_p->nrow();
321 :
322 :
323 2 : }
324 :
325 4 : void MSUVBin::storeGridInfo(){
326 : //cerr << "numVis " << numVis_p << endl;
327 : //cerr << "sumWgt " << sumWeight_p << endl;
328 4 : if(existOut_p){
329 2 : outMsPtr_p->rwKeywordSet().asrwRecord("MSUVBIN").define("numvis", numVis_p);
330 2 : outMsPtr_p->rwKeywordSet().asrwRecord("MSUVBIN").define("sumweight", sumWeight_p);
331 2 : return;
332 : }
333 2 : Record rec;
334 2 : rec.define("nx", nx_p);
335 2 : rec.define("ny", ny_p);
336 2 : rec.define("nchan", nchan_p);
337 2 : rec.define("npol", npol_p);
338 2 : rec.define("numvis", numVis_p);
339 2 : rec.define("sumweight", sumWeight_p);
340 2 : csys_p.save(rec, "csys");
341 2 : outMsPtr_p->rwKeywordSet().defineRecord("MSUVBIN", rec);
342 :
343 :
344 2 : }
345 4 : void MSUVBin::setTileCache()
346 : {
347 4 : if(outMsPtr_p->tableType() ==Table::Memory){
348 0 : return;
349 : }
350 4 : const ColumnDescSet & cds = outMsPtr_p->tableDesc ().columnDescSet ();
351 :
352 : //uInt startrow = 0;
353 :
354 4 : Vector<String> columns (6);
355 4 : columns (0) = MS::columnName (MS::DATA); // complex
356 4 : columns (1) = MS::columnName (MS::FLAG); // boolean
357 4 : columns (2) = MS::columnName (MS::WEIGHT_SPECTRUM); // float
358 4 : columns (3) = MS::columnName (MS::WEIGHT); // float
359 4 : columns (4) = MS::columnName (MS::SIGMA); // float
360 4 : columns (5) = MS::columnName (MS::UVW); // double
361 :
362 28 : for (uInt k = 0; k < columns.nelements (); ++k) {
363 :
364 24 : if (! cds.isDefined (columns (k)))
365 : {
366 0 : continue;
367 : }
368 :
369 : try {
370 : //////////////////
371 : //////Temporary fix for virtual ms of multiple real ms's ...miracle of statics
372 : //////setting the cache size of hypercube at row 0 of each ms.
373 : ///will not work if each subms of a virtual ms has multi hypecube being
374 : ///accessed.
375 :
376 : {
377 24 : Bool usesTiles=false;
378 24 : String dataManType = RODataManAccessor (*outMsPtr_p, columns[k], true).dataManagerType ();
379 : //cerr << "column " << columns[k] << " dataman "<< dataManType << endl;
380 24 : usesTiles = dataManType.contains ("Tiled");
381 24 : if(usesTiles){
382 24 : ROTiledStManAccessor tacc (*outMsPtr_p, columns[k], true);
383 24 : tacc.clearCaches (); //One tile only for now ...seems to work faster
384 :
385 :
386 :
387 :
388 :
389 : /// If some bucketSize is 0...there is trouble in setting cache
390 : /// but if slicer is used it gushes anyways if one does not set cache
391 : /// need to fix the 0 bucket size in the filler anyways...then this is not needed
392 :
393 :
394 24 : tacc.setCacheSize (0, 1);
395 :
396 :
397 24 : }
398 24 : }
399 : }
400 0 : catch (AipsError x) {
401 : // cerr << "Data man type " << dataManType << " " << dataManType.contains ("Tiled") << " && " << (!String (cdesc.dataManagerGroup ()).empty ()) << endl;
402 : // cerr << "Failed to set settilecache due to " << x.getMesg () << " column " << columns[k] <<endl;
403 : //It failed so leave the caching as is
404 0 : continue;
405 0 : }
406 : }
407 :
408 4 : }
409 :
410 4 : Bool MSUVBin::fillOutputMS(){
411 : // Double imagevol=Double(nx_p)*Double(ny_p)*Double(npol_p)*Double(nchan_p)*12.0/1e6; //in MB
412 : // Double memoryMB=Double(HostInfo::memoryFree())/1024.0 ;
413 : Bool retval;
414 4 : retval= fillNewBigOutputMS();
415 4 : return retval;
416 : }
417 :
418 4 : Bool MSUVBin::fillNewBigOutputMS(){
419 4 : if(mss_p.nelements()==0)
420 0 : throw(AipsError("No valid input MSs defined"));
421 4 : Vector<Double> incr;
422 4 : Vector<Int> cent;
423 4 : Matrix<Double> uvw;
424 4 : Double numOfFlagsBefore=0;
425 4 : Double numOfFlagsAfter=0;
426 : //need to build or recover csys at this stage
427 4 : makeCoordsys();
428 4 : Double reffreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
429 4 : Int nrrows=makeUVW(reffreq, incr, cent, uvw);
430 4 : Vector<Bool> rowFlag(nrrows);
431 4 : Vector<Int> ant1(nrrows);
432 4 : Vector<Int> ant2(nrrows);
433 4 : Vector<Double> timeCen(nrrows);
434 4 : Matrix<Float> wght(npol_p, nrrows);
435 4 : createOutputMS(nrrows);
436 4 : setTileCache();
437 4 : MSColumns msc(*outMsPtr_p);
438 8 : vi::VisibilityIterator2 iter(mss_p, vi::SortColumns(), doFlag_p);
439 4 : vi::VisBuffer2* vb=iter.getVisBuffer();
440 4 : iter.originChunks();
441 4 : iter.origin();
442 4 : if(existOut_p){
443 2 : msc.weight().getColumn(wght);
444 2 : msc.flagRow().getColumn(rowFlag);
445 2 : msc.antenna1().getColumn(ant1);
446 2 : msc.antenna2().getColumn(ant2);
447 2 : msc.time().getColumn(timeCen);
448 2 : msc.uvw().getColumn(uvw);
449 :
450 : }
451 : else{
452 2 : wght.set(0.0);
453 2 : rowFlag.set(true);
454 2 : timeCen.set(vb->time()(0));
455 : }
456 : ////////////////////////////////////////////////
457 4 : Cube<Complex> convFunc;
458 4 : Vector<Int> convSupport;
459 : Double wScale;
460 : Int convSampling, convSize;
461 4 : if(doW_p){
462 0 : makeWConv(iter, convFunc, convSupport, wScale, convSampling, convSize);
463 : //makeSFConv(convFunc, convSupport, wScale, convSampling, convSize);
464 : // cerr << "convSupport0 " << convFunc.shape() << " " << convSupport << endl;
465 : }
466 : /////////////////////////////////////////////////
467 4 : Int usableNchan=Int(Double(HostInfo::memoryFree())*memFraction_p*1024.0/Double(npol_p)/Double(nx_p*ny_p)/(doW_p ? 16.0: 12.0));
468 4 : if(usableNchan < nchan_p)
469 0 : cerr << "Maximum nchan per pass " << min(usableNchan, nchan_p) << endl;
470 4 : Int npass=nchan_p%usableNchan==0 ? nchan_p/usableNchan : nchan_p/usableNchan+1;
471 4 : if(npass >1)
472 0 : cerr << "Due to lack of memory will be doing " << npass << " passes through data"<< endl;
473 8 : for (Int pass=0; pass < npass; ++pass){
474 4 : Int startchan=pass*usableNchan;
475 4 : Int endchan=pass==nchan_p/usableNchan ? nchan_p%usableNchan+ startchan-1 : (pass+1)*usableNchan -1 ;
476 :
477 4 : Cube<Complex> grid(npol_p, endchan-startchan+1, nrrows);
478 : //cerr << "shape " << grid.shape() << endl;
479 4 : Cube<Complex> wghtSpec;
480 4 : Cube<Float> realWghtSpec(npol_p, endchan-startchan+1, nrrows);
481 4 : Cube<Float> imagWghtSpec;
482 4 : Cube<Bool> flag(npol_p, endchan-startchan+1, nrrows);
483 : //Matrix<Int> locuv;
484 :
485 :
486 4 : iter.originChunks();
487 4 : iter.origin();
488 4 : vbutil_p=VisBufferUtil(*vb);
489 4 : if(existOut_p){
490 : //recover the previous data for summing
491 4 : Slicer elslice(IPosition(2, 0, startchan), IPosition(2,npol_p, endchan-startchan+1));
492 2 : msc.data().getColumn(elslice, grid);
493 2 : msc.weightSpectrum().getColumn(elslice, realWghtSpec);
494 2 : msc.flag().getColumn(elslice, flag);
495 2 : wghtSpec.resize(realWghtSpec.shape());
496 2 : setReal(wghtSpec, realWghtSpec);
497 2 : if(outMsPtr_p->tableDesc().columnDescSet().isDefined("IMAGINARY_WEIGHT_SPECTRUM")){
498 0 : ArrayColumn<Float> imagWgtSpecCol(*outMsPtr_p, "IMAGINARY_WEIGHT_SPECTRUM");
499 0 : imagWghtSpec.resize(realWghtSpec.shape());
500 0 : imagWgtSpecCol.getColumn(elslice, imagWghtSpec);
501 0 : setImag(wghtSpec, imagWghtSpec);
502 0 : }
503 2 : if(doW_p){
504 0 : imagWghtSpec.resize();
505 0 : realWghtSpec.resize();
506 : }
507 : //multiply the data with weight here
508 : {
509 180002 : for (Int iz=0; iz< grid.shape()(2); ++iz){
510 540000 : for(Int iy=0; iy < grid.shape()(1); ++iy){
511 1080000 : for(Int ix=0; ix < grid.shape()(0); ++ix){
512 720000 : grid(ix,iy,iz)= grid(ix,iy,iz)*wghtSpec(ix,iy,iz);
513 : }
514 : }
515 : }
516 : }
517 2 : if(!doW_p)
518 2 : wghtSpec.resize();
519 :
520 :
521 2 : }
522 : else{
523 2 : grid.set(Complex(0));
524 2 : if(doW_p){
525 0 : wghtSpec.resize(realWghtSpec.shape());
526 0 : wghtSpec.set(0);
527 0 : realWghtSpec.resize();
528 : }
529 2 : realWghtSpec.set(0);
530 2 : flag.set(true);
531 :
532 : //cerr << "Zeroing grid " << grid.shape() << endl;
533 : //outMsPtr_p->addRow(nrrows, true);
534 : }
535 4 : if(npass > 1)
536 0 : cerr <<"Pass " << pass ;
537 : ProgressMeter pm(1.0, Double(nrrows),"Gridding data",
538 8 : "", "", "", true);
539 4 : Double rowsDone=0.0;
540 : //cerr << "Before: Num of flagged model " << ntrue(uvw.row(2) ==(-666.0)) << endl;
541 :
542 8 : for (iter.originChunks(); iter.moreChunks(); iter.nextChunk()){
543 1432 : for(iter.origin(); iter.more(); iter.next()){
544 1428 : if(doFlag_p){
545 0 : numOfFlagsBefore += ntrue(vb->flagCube());
546 : //cerr << " before " << ntrue(vb->flagCube()) << endl;
547 0 : Cube<Bool> datFlag=vb->flagCube();
548 0 : locateFlagFromGrid(*vb, datFlag,
549 : realWghtSpec,
550 : flag, rowFlag, uvw, ant1,
551 : ant2, timeCen, startchan, endchan);
552 : //cerr << " after " << ntrue(datFlag) << endl;
553 0 : numOfFlagsAfter += ntrue(datFlag);
554 0 : iter.writeFlag(datFlag);
555 :
556 0 : }
557 : else{
558 1428 : if(doW_p){
559 : //gridDataConv(*vb, grid, wght, wghtSpec,flag, rowFlag, uvw,
560 : // ant1,ant2,timeCen, startchan, endchan, convFunc, convSupport, wScale, convSampling);
561 0 : gridDataConvThr(*vb, grid, wghtSpec,flag, rowFlag, uvw,
562 : ant1,ant2,timeCen, startchan, endchan, convFunc, convSupport, wScale, convSampling);
563 :
564 : }
565 : else{
566 1428 : gridData(*vb, grid, wght, realWghtSpec,flag, rowFlag, uvw,
567 : ant1,ant2,timeCen, startchan, endchan);
568 : }
569 :
570 :
571 : }
572 1428 : rowsDone+=Double(vb->nRows());
573 :
574 :
575 :
576 1428 : pm.update(rowsDone);
577 :
578 :
579 : }
580 :
581 : }
582 :
583 4 : imagWghtSpec.resize();
584 4 : if(doW_p){
585 0 : realWghtSpec.resize(wghtSpec.shape());
586 0 : realWghtSpec=real(wghtSpec);
587 0 : imagWghtSpec.resize(wghtSpec.shape());
588 0 : imagWghtSpec=imag(wghtSpec);
589 : }
590 : else{
591 4 : wghtSpec.resize(realWghtSpec.shape());
592 4 : wghtSpec.set(0.0);
593 4 : setReal(wghtSpec, realWghtSpec);
594 : }
595 :
596 : //Weight Correct the data
597 : {
598 360004 : for (Int iz=0; iz< grid.shape()(2); ++iz){
599 : /* Float medweight= 0.0;
600 : if(max(abs(wghtSpec.xyPlane(iz))) > 0.0){
601 : medweight=median(wghtSpec.xyPlane(iz));
602 : medweight
603 : }
604 : */
605 : /* if(max(wghtSpec.xyPlane(iz)) > 0.0)
606 : cerr << iz << " median " << median(wghtSpec.xyPlane(iz)) << " min " << min(wghtSpec.xyPlane(iz)) << " max " << max(wghtSpec.xyPlane(iz)) << endl;
607 : */
608 :
609 1080000 : for(Int iy=0; iy < grid.shape()(1); ++iy){
610 2160000 : for(Int ix=0; ix < grid.shape()(0); ++ix){
611 1440000 : if(!flag(ix,iy,iz) && wghtSpec(ix,iy, iz) > 0.0){
612 17504 : grid(ix,iy, iz)=grid(ix,iy,iz)/wghtSpec(ix,iy,iz);
613 : }
614 : else{
615 1422496 : grid(ix,iy,iz)=0.0;
616 1422496 : wghtSpec(ix,iy,iz)=0.0;
617 : }
618 :
619 : //grid(ix,iy,iz)= (!flag(ix,iy,iz) && fabs(wghtSpec(ix,iy, iz)) > 1e-3*medweight) ? grid(ix,iy,iz)/wghtSpec(ix,iy,iz): Complex(0);
620 : }
621 : }
622 :
623 :
624 : } // iz
625 : }
626 :
627 : //cerr << "After: Num of flagged model " << ntrue(uvw.row(2) ==(-666.0)) << endl;
628 4 : saveData(grid, flag, rowFlag, realWghtSpec, uvw, ant1, ant2, timeCen, startchan, endchan, imagWghtSpec);
629 4 : }
630 4 : if(doFlag_p){
631 0 : LogIO os(LogOrigin("MSUVBin", "TransferFlags", WHERE));
632 0 : os << "Number of flags before transfer " << numOfFlagsBefore << "\n";
633 0 : os << "Number of flags after transfer " << numOfFlagsAfter << LogIO::POST;
634 0 : }
635 4 : storeGridInfo();
636 4 : return true;
637 4 : }
638 :
639 0 : Bool MSUVBin::fillSmallOutputMS(){
640 0 : if(mss_p.nelements()==0)
641 0 : throw(AipsError("No valid input MSs defined"));
642 0 : Vector<Double> incr;
643 0 : Vector<Int> cent;
644 0 : Matrix<Double> uvw;
645 : //need to build or recover csys at this stage
646 0 : makeCoordsys();
647 0 : Double reffreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
648 0 : Int nrrows=makeUVW(reffreq, incr, cent, uvw);
649 0 : Cube<Complex> grid(npol_p, nchan_p, nrrows);
650 0 : Matrix<Float> wght(npol_p, nrrows);
651 0 : Cube<Float> wghtSpec(npol_p, nchan_p, nrrows);
652 0 : Cube<Bool> flag(npol_p, nchan_p, nrrows);
653 0 : Vector<Bool> rowFlag(nrrows);
654 0 : Vector<Int> ant1(nrrows);
655 0 : Vector<Int> ant2(nrrows);
656 0 : Vector<Double> timeCen(nrrows);
657 0 : createOutputMS(nrrows);
658 0 : Matrix<Int> locuv;
659 0 : vi::VisibilityIterator2 iter(mss_p, vi::SortColumns(), false);
660 0 : vi::VisBuffer2* vb=iter.getVisBuffer();
661 :
662 0 : iter.originChunks();
663 0 : iter.origin();
664 0 : vbutil_p=VisBufferUtil(*vb);
665 0 : if(existOut_p){
666 : //recover the previous data for summing
667 :
668 0 : MSColumns msc(*outMsPtr_p);
669 0 : msc.data().getColumn(grid);
670 0 : msc.weightSpectrum().getColumn(wghtSpec);
671 0 : msc.weight().getColumn(wght);
672 0 : msc.flag().getColumn(flag);
673 0 : msc.flagRow().getColumn(rowFlag);
674 0 : msc.antenna1().getColumn(ant1);
675 0 : msc.antenna2().getColumn(ant2);
676 0 : msc.time().getColumn(timeCen);
677 0 : msc.uvw().getColumn(uvw);
678 0 : }
679 : else{
680 0 : grid.set(Complex(0));
681 0 : wght.set(0);
682 0 : wghtSpec.set(0);
683 0 : flag.set(true);
684 0 : rowFlag.set(true);
685 : //cerr << "SETTING time to val" << vb->time()(0) << endl;
686 0 : timeCen.set(vb->time()(0));
687 : //outMsPtr_p->addRow(nrrows, true);
688 : }
689 : ProgressMeter pm(1.0, Double(nrrows),"Gridding data",
690 0 : "", "", "", true);
691 0 : Double rowsDone=0.0;
692 0 : for (iter.originChunks(); iter.moreChunks(); iter.nextChunk()){
693 0 : for(iter.origin(); iter.more(); iter.next()){
694 0 : locateuvw(locuv, incr, cent, vb->uvw());
695 0 : gridData(*vb, grid, wght, wghtSpec,flag, rowFlag, uvw,
696 : ant1,ant2,timeCen, locuv);
697 0 : rowsDone+=Double(vb->nRows());
698 0 : pm.update(rowsDone);
699 : }
700 :
701 : }
702 :
703 0 : saveData(grid, flag, rowFlag, wghtSpec, wght, uvw, ant1, ant2, timeCen);
704 0 : storeGridInfo();
705 0 : return true;
706 0 : }
707 :
708 0 : Bool MSUVBin::fillBigOutputMS(){
709 :
710 0 : if(mss_p.nelements()==0)
711 0 : throw(AipsError("No valid input MSs defined"));
712 0 : Vector<Double> incr;
713 0 : Vector<Int> cent;
714 0 : Matrix<Double> uvw;
715 : //need to build or recover csys at this stage
716 0 : makeCoordsys();
717 0 : Double reffreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
718 0 : Int nrrows=makeUVW(reffreq, incr, cent, uvw);
719 0 : createOutputMS(nrrows);
720 0 : if(!existOut_p)
721 0 : MSColumns(*outMsPtr_p).uvw().putColumn(uvw);
722 0 : nrrows=0;
723 0 : for (uInt k=0; k < mss_p.nelements() ; ++k)
724 0 : nrrows+=(mss_p[k])->nrow();
725 :
726 0 : vi::VisibilityIterator2 iter(mss_p, vi::SortColumns(), false);
727 0 : vi::VisBuffer2* vb=iter.getVisBuffer();
728 0 : iter.originChunks();
729 0 : iter.origin();
730 0 : vbutil_p=VisBufferUtil(*vb);
731 0 : Matrix<Int> locuv;
732 :
733 : ProgressMeter pm(1.0, Double(nrrows),"Gridding data",
734 0 : "", "", "", true);
735 0 : Double rowsDone=0.0;
736 0 : for (iter.originChunks(); iter.moreChunks(); iter.nextChunk()){
737 0 : for(iter.origin(); iter.more(); iter.next()){
738 :
739 : //locateuvw(locuv, incr, cent, vb->uvw());
740 0 : inplaceGridData(*vb);
741 : //
742 : //gridData(*vb, grid, wght, wghtSpec,flag, rowFlag, uvw,
743 : // ant1,ant2,timeCen, locuv);
744 0 : rowsDone+=Double(vb->nRows());
745 0 : pm.update(rowsDone);
746 : }
747 : }
748 :
749 0 : if(!existOut_p){
750 0 : fillSubTables();
751 : }
752 : ////Need to do the weight calculation here from spectral weight.
753 0 : weightSync();
754 0 : storeGridInfo();
755 0 : return true;
756 0 : }
757 :
758 4 : Int MSUVBin::makeUVW(const Double reffreq, Vector<Double>& increment,
759 : Vector<Int>& center, Matrix<Double>& uvw){
760 4 : Vector<Int> shp(2);
761 4 : shp(0)=nx_p; shp(1)=ny_p;
762 4 : Int directionIndex=csys_p.findCoordinate(Coordinate::DIRECTION);
763 4 : DirectionCoordinate thedir=csys_p.directionCoordinate(directionIndex);
764 4 : Coordinate *ftcoord=thedir.makeFourierCoordinate(Vector<Bool>(2, true), shp);
765 4 : increment=ftcoord->increment();
766 4 : increment *= C::c/reffreq;
767 : //Vector<Float> scale(2);
768 : //scale(0)=1.0/(nx_p*thedir.increment()(0));
769 : //scale(1)=1.0/(ny_p*thedir.increment()(1));
770 4 : center.resize(2);
771 4 : center(0)=nx_p/2;
772 4 : center(1)=ny_p/2;
773 4 : Vector<Int> npix(2);
774 4 : npix(0)=nx_p;
775 4 : npix(1)=ny_p;
776 4 : uvw.resize(3, nx_p*ny_p);
777 4 : uvw.set(-666.0);
778 4 : Vector<Double> px(2);
779 4 : Vector<Double> wld(2);
780 4 : Double lambd=C::c/reffreq;
781 4 : Int counter=0;
782 1204 : for (Int k=0; k < ny_p;++k ){
783 1200 : px(1)=Double(k);
784 : //px(1)=Double(k-ny_p/2)*C::c/reffreq*scale(1);
785 361200 : for(Int j=0; j < nx_p; ++j){
786 : //px(0)=Double(j-nx_p/2)*C::c/reffreq*scale(0);
787 : //uvw(0, k*nx_p+j)=px(0);
788 : //uvw(1, k*nx_p+j)=px(1);
789 : //wld(0)=Double(j);
790 : //wld(1)=Double(k);
791 360000 : px(0)=Double(j);
792 360000 : if(ftcoord->toWorld(wld, px)){
793 : //cerr << "wld " << wld*C::c/reffreq << " px " << uvw(0,k*nx_p+j) << ", "<< uvw(1, k*nx_p+j) << endl;
794 360000 : uvw(0, k*nx_p+j)=wld(0)*lambd;
795 360000 : uvw(1, k*nx_p+j)=wld(1)*lambd;
796 360000 : ++counter;
797 : }
798 : }
799 : }
800 4 : return counter;
801 4 : }
802 4 : void MSUVBin::makeCoordsys(){
803 :
804 : //if outMS already has the coordsys..it is recovered
805 4 : if(existOut_p)
806 0 : return;
807 : //
808 4 : Matrix<Double> xform(2,2);
809 4 : xform=0.0;xform.diagonal()=1.0;
810 8 : MVAngle ra=phaseCenter_p.getAngle("rad").getValue()(0);
811 4 : ra(0.0);
812 8 : MVAngle dec=phaseCenter_p.getAngle("rad").getValue()(1);
813 :
814 4 : DirectionCoordinate myRaDec(MDirection::Types(phaseCenter_p.getRefPtr()->getType()),
815 : Projection::SIN,
816 : ra.radian(), dec.radian(),
817 12 : deltas_p(0), deltas_p(1),
818 : xform,
819 8 : Double(nx_p)/2.0, Double(ny_p)/2.0);
820 :
821 : //Now to the spectral part
822 : //LSRK frame unless REST
823 4 : MFrequency::Types outFreqFrame=MFrequency::LSRK;
824 4 : Vector<MFrequency::Types> typesInData;
825 4 : MSUtil::getSpectralFrames(typesInData, *(mss_p[0]));
826 4 : if(anyEQ(typesInData, MFrequency::REST))
827 0 : outFreqFrame=MFrequency::REST;
828 : //make freqstart the centre of channel
829 4 : freqStart_p=freqStart_p+freqStep_p/2.0;
830 4 : SpectralCoordinate mySpectral(outFreqFrame, freqStart_p, freqStep_p, 0.0);
831 4 : MSColumns msc(*mss_p[0]);
832 4 : Int ddId=msc.dataDescId()(0);
833 4 : Int firstPolId=msc.dataDescription().polarizationId()(ddId);
834 4 : Int polType = Vector<Int>(msc.polarization().corrType()(firstPolId))(0);
835 4 : Bool isCircular=true;
836 4 : if (polType>=Stokes::XX && polType<=Stokes::YY)
837 0 : isCircular=false;
838 :
839 4 : if(isCircular){
840 4 : if(npol_p==4){
841 0 : whichStokes_p.resize(4);
842 :
843 0 : whichStokes_p(0)=Stokes::RR; whichStokes_p(1)=Stokes::RL;
844 0 : whichStokes_p(2)=Stokes::LR; whichStokes_p(3)=Stokes::LL;
845 : }
846 4 : else if(npol_p==2){
847 4 : whichStokes_p.resize(2);
848 4 : whichStokes_p(0)=Stokes::RR; whichStokes_p(1)=Stokes::LL;
849 : }
850 0 : else if(npol_p==1){
851 0 : whichStokes_p.resize(1);
852 0 : whichStokes_p(0)=Stokes::RR;
853 : }
854 : }
855 : else{
856 0 : if(npol_p==4){
857 0 : whichStokes_p.resize(4);
858 0 : whichStokes_p(0)=Stokes::XX; whichStokes_p(1)=Stokes::XY;
859 0 : whichStokes_p(2)=Stokes::YX; whichStokes_p(3)=Stokes::YY;
860 : }
861 0 : else if(npol_p==2){
862 0 : whichStokes_p.resize(2);
863 0 : whichStokes_p(0)=Stokes::XX; whichStokes_p(1)=Stokes::YY;
864 : }
865 0 : else if(npol_p==1){
866 0 : whichStokes_p.resize(1);
867 0 : whichStokes_p(0)=Stokes::XX;
868 : }
869 : }
870 4 : StokesCoordinate myStokes(whichStokes_p);
871 4 : csys_p=CoordinateSystem();
872 4 : csys_p.addCoordinate(myRaDec);
873 4 : csys_p.addCoordinate(myStokes);
874 4 : csys_p.addCoordinate(mySpectral);
875 4 : ObsInfo obsinf;
876 4 : obsinf.setObsDate(msc.timeMeas()(0));
877 4 : obsinf.setTelescope(msc.observation().telescopeName()(0));
878 4 : obsinf.setPointingCenter(phaseCenter_p.getValue());
879 4 : csys_p.setObsInfo(obsinf);
880 4 : }
881 :
882 0 : void MSUVBin::locateuvw(Matrix<Int>& locuv, const Vector<Double>& increment,
883 : const Vector<Int>& center, const Matrix<Double>& uvw){
884 0 : locuv.resize(2, uvw.shape()(1));
885 0 : for (Int k=0; k <uvw.shape()(1); ++k){
886 0 : for(Int j=0; j < 2; ++j)
887 0 : locuv(j,k)=Int(Double(center(j))+uvw(j,k)/increment(j)+0.5);
888 : }
889 :
890 :
891 0 : }
892 1428 : Bool MSUVBin::datadescMap(const vi::VisBuffer2& vb, Double& fracbw){
893 1428 : polMap_p.resize(vb.nCorrelations());
894 1428 : polMap_p.set(-1);
895 : //Should ultimately find the real polarization in case it is a non common MS
896 1428 : if(npol_p==4){
897 0 : if( polMap_p.nelements()==4)
898 0 : indgen(polMap_p);
899 0 : if(polMap_p.nelements()==2){
900 0 : polMap_p(0)=0;
901 0 : polMap_p(1)=3;
902 : }
903 : //This case sounds bad
904 0 : if(polMap_p.nelements()==1)
905 0 : polMap_p(0)=0;
906 : }
907 1428 : if(npol_p==2){
908 1428 : if( polMap_p.nelements()==4){
909 1428 : polMap_p(0)=0;
910 1428 : polMap_p(3)=1;
911 : }
912 1428 : if(polMap_p.nelements()==2)
913 0 : indgen(polMap_p);
914 : //again a bad case ...not resolving this here
915 1428 : if(polMap_p.nelements()==1)
916 0 : polMap_p(0)=0;
917 : }
918 0 : else if(npol_p==1){
919 0 : polMap_p(0)=0;
920 0 : if(polMap_p.nelements()==2)
921 0 : polMap_p(1)=0;
922 0 : if(polMap_p.nelements()==4)
923 0 : polMap_p(3)=0;
924 : }
925 : ////Now to chanmap
926 1428 : fracbw=0.0;
927 1428 : Vector<Double> f(1);
928 1428 : Vector<Double> c(1,0.0);
929 1428 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
930 1428 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
931 : //Vector<Double> visFreq;
932 : //vbutil_p.convertFrequency(visFreq, vb, MFrequency::LSRK);
933 1428 : chanMap_p.resize(visFreq.nelements());
934 1428 : chanMapRev_p.resize(nchan_p);
935 4284 : for (Int chan=0; chan < nchan_p; ++chan){
936 2856 : chanMapRev_p[chan].resize();
937 : }
938 1428 : chanMap_p.set(-1);
939 92820 : for (Int chan=0; chan < vb.nChannels(); ++chan){
940 91392 : f[0]=visFreq[chan];
941 :
942 91392 : if(spec.toPixel(c,f)){
943 :
944 91392 : Int pixel=Int(floor(c(0)+0.5)); // round to chan freq at chan center
945 : //cout << " pixel " << pixel << " " << c << " f " << f << " chan " << chan << endl;
946 91392 : if(pixel > -1 && pixel< nchan_p){
947 91392 : chanMap_p(chan)=pixel;
948 91392 : chanMapRev_p[pixel].resize(chanMapRev_p[pixel].nelements()+1, true);
949 91392 : chanMapRev_p[pixel][chanMapRev_p[pixel].nelements()-1]=chan;
950 91392 : c[0]=pixel;
951 91392 : spec.toWorld(f, c);
952 : //cout << " pixel " << pixel << " chan " << chan << endl;
953 91392 : if((abs(visFreq[chan]-f[0])/f[0]) > fracbw)
954 1996 : fracbw=(abs(visFreq[chan]-f[0])/f[0]);
955 : }
956 : }
957 : }
958 :
959 : ///////////////////////
960 : //cout << "spw" << vb.spectralWindows()(0) << " rowid " << vb.rowIds()(0) << " max " << max(chanMap_p) << " sum "<< ntrue(chanMap_p > -1) << endl;
961 : /*if( ntrue(chanMap_p > -1) > 0){
962 : for (uInt k=0; k < visFreq.nelements() ; ++k){
963 : if(chanMap_p(k) > -1){
964 : cerr << " " <<k<< " "<< visFreq[k] << " = " << chanMap_p[k];
965 : }
966 : }
967 : cerr <<endl;
968 : cerr << "*************************************" << endl;
969 :
970 : }
971 : */
972 : ////////////////////////////////////
973 : //cerr << "spw " << vb.spectralWindows() << " fracbw " << fracbw << endl;
974 1428 : if(allLT(chanMap_p ,0) || allLT(polMap_p , 0))
975 0 : return false;
976 :
977 1428 : return true;
978 1428 : }
979 :
980 0 : void MSUVBin::weightSync(){
981 0 : MSColumns msc(*outMsPtr_p);
982 0 : Matrix<Float> wght(npol_p, outMsPtr_p->nrow());
983 0 : Matrix<Float> wghtSpec;
984 0 : for (uInt row=0; row < outMsPtr_p->nrow(); ++row){
985 0 : for (uInt pol=0; pol < wght.shape()(0); ++pol){
986 :
987 0 : wghtSpec=msc.weightSpectrum().get(row);
988 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
989 0 : wght(pol,row)=median(wghtSpec.row(pol));
990 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
991 : }
992 : }
993 0 : msc.weight().putColumn(wght);
994 0 : Matrix<Float> sigma(wght.shape());
995 0 : for (uInt k=0; k<wght.shape()[1]; ++k)
996 0 : for (uInt j=0; j<wght.shape()[0]; ++j)
997 0 : sigma(j,k)=wght(j,k)>0.0 ? 1/sqrt(wght(j,k)) :0.0;
998 0 : msc.sigma().putColumn(sigma);
999 :
1000 :
1001 0 : }
1002 :
1003 0 : void MSUVBin::inplaceGridData(const vi::VisBuffer2& vb){
1004 : //we need polmap and chanmap;
1005 : // no point of proceeding if nothing maps in this vb
1006 : Double fracbw;
1007 0 : if(!datadescMap(vb, fracbw)) return;
1008 : //cerr << "fracbw " << fracbw << endl;
1009 :
1010 0 : if(fracbw >0.05)
1011 0 : inplaceLargeBW(vb);
1012 : else
1013 0 : inplaceSmallBW(vb);
1014 :
1015 :
1016 :
1017 :
1018 : }
1019 :
1020 0 : void MSUVBin::inplaceLargeBW(const vi::VisBuffer2& vb){
1021 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1022 : //not there
1023 0 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1024 0 : Int nrows=vb.nRows();
1025 : // Cube<Complex> grid(npol_p, nchan_p, nrows);
1026 : // Matrix<Float> wght(npol_p,nrows);
1027 : // Cube<Float> wghtSpec(npol_p,nchan_p,nrows);
1028 : // Cube<Bool> flag(npol_p, nchan_p,nrows);
1029 : // Vector<Bool> rowFlag(nrows);
1030 : // Matrix<Double> uvw(3, nrows);
1031 : // Vector<Int> ant1(nrows);
1032 : // Vector<Int> ant2(nrows);
1033 : // Vector<Double> timeCen(nrows);
1034 : // Vector<uInt> rowids(nrows);
1035 : //cerr << outMsPtr_p.null() << endl;
1036 0 : MSColumns msc(*outMsPtr_p);
1037 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1038 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1039 0 : Vector<Float> scale(2);
1040 0 : scale(0)=fabs(nx_p*thedir.increment()(0))/C::c;
1041 0 : scale(1)=fabs(ny_p*thedir.increment()(1))/C::c;
1042 : ///Index
1043 0 : Vector<Int> rowToIndex(nx_p*ny_p, -1);
1044 0 : Matrix<Int> locu(vb.nChannels(), nrows, -1);
1045 0 : Matrix<Int> locv(vb.nChannels(), nrows, -1);
1046 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1047 0 : Vector<Double> phasor;
1048 0 : Matrix<Double> eluvw;
1049 0 : Bool needRot=vbutil_p.rotateUVW(vb, phaseCenter_p, eluvw, phasor);
1050 0 : Int numUniq=0;
1051 0 : for (Int k=0; k <nrows; ++k){
1052 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1053 0 : if(chanMap_p(chan) >=0){
1054 0 : locv(chan, k)=Int(Double(ny_p)/2.0+eluvw(1,k)*visFreq(chan)*scale(1)+0.5);
1055 0 : locu(chan, k)=Int(Double(nx_p)/2.0+eluvw(0,k)*visFreq(chan)*scale(0)+0.5);
1056 0 : Int newrow=locv(chan, k)*nx_p+locu(chan, k);
1057 0 : if(rowToIndex[newrow] <0){
1058 0 : rowToIndex[newrow]=numUniq;
1059 0 : ++numUniq;
1060 : }
1061 : }
1062 : }
1063 : }
1064 : //cerr << "numrows " << vb.nRows() << " nuniq " << numUniq << endl;
1065 0 : Cube<Complex> grid(npol_p, nchan_p, numUniq);
1066 0 : Matrix<Float> wght(npol_p,numUniq);
1067 0 : Cube<Float> wghtSpec(npol_p,nchan_p,numUniq);
1068 0 : Cube<Bool> flag(npol_p, nchan_p,numUniq);
1069 0 : Vector<Bool> rowFlag(numUniq);
1070 0 : Matrix<Double> uvw(3, numUniq);
1071 0 : Vector<Int> ant1(numUniq);
1072 0 : Vector<Int> ant2(numUniq);
1073 0 : Vector<Double> timeCen(numUniq);
1074 0 : Vector<uInt> rowids(numUniq);
1075 0 : Vector<Bool> rowvisited(numUniq, false);
1076 :
1077 0 : Vector<Double> invLambda=visFreq/C::c;
1078 0 : Vector<Double> phasmult(vb.nChannels(),0.0);
1079 0 : for (Int k=0; k < nrows; ++k){
1080 0 : if(needRot)
1081 0 : phasmult=phasor(k)*invLambda;
1082 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1083 0 : if(chanMap_p(chan) >=0){
1084 : //Have to reject uvws out of range.
1085 0 : if(locu(chan,k) > -1 && locu(chan, k) < nx_p && locv(chan,k)> -1 && locv(chan,k) < ny_p){
1086 0 : Int newrow=locv(chan,k)*nx_p+locu(chan,k);
1087 0 : Int actrow=rowToIndex[newrow];
1088 0 : rowids[actrow]=uInt(newrow);
1089 0 : if(!rowvisited[actrow]){
1090 0 : rowvisited[actrow]=true;
1091 0 : rowFlag[actrow]=msc.flagRow()(newrow);
1092 0 : wghtSpec[actrow]=msc.weightSpectrum().get(newrow);
1093 0 : flag[actrow]=msc.flag().get(newrow);
1094 0 : uvw[actrow]=msc.uvw().get(newrow);
1095 0 : ant1[actrow]=msc.antenna1()(newrow);
1096 0 : ant2[actrow]=msc.antenna2()(newrow);
1097 0 : timeCen[actrow]=msc.time()(newrow);
1098 0 : grid[actrow]=msc.data().get(newrow);
1099 : }
1100 0 : if(rowFlag[actrow] && !(vb.flagRow()(k))){
1101 : // cerr << newrow << " rowFlag " << rowFlag[actrow] <<" rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,actrow) << endl;
1102 0 : rowFlag[actrow]=false;
1103 0 : uvw(2,actrow)=eluvw(2,k);
1104 : // cerr << newrow << " rowFlag " << rowFlag[actrow] <<" rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,actrow) << endl;
1105 0 : ant1[actrow]=vb.antenna1()(k);
1106 0 : ant2[actrow]=vb.antenna2()(k);
1107 0 : timeCen[actrow]=vb.time()(k);
1108 : }
1109 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1110 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0)){
1111 0 : Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k):
1112 0 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k);
1113 0 : if(needRot){
1114 : Double s, c;
1115 0 : SINCOS(phasmult(chan), s, c);
1116 0 : Complex elphas(c, s);
1117 0 : toB *= elphas;
1118 : }
1119 0 : grid(polMap_p(pol),chanMap_p(chan),actrow)
1120 0 : = (grid(polMap_p(pol),chanMap_p(chan),actrow)*wghtSpec(polMap_p(pol),chanMap_p(chan),actrow)
1121 0 : + toB)/(vb.weight()(pol,k)+wghtSpec(polMap_p(pol),chanMap_p(chan),actrow));
1122 0 : flag(polMap_p(pol),chanMap_p(chan),actrow)=false;
1123 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1124 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1125 0 : wghtSpec(polMap_p(pol),chanMap_p(chan),actrow) += vb.weight()(pol,k);
1126 : }
1127 : }
1128 : }
1129 : }
1130 : //This should go for later
1131 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1132 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1133 : wght(pol,actrow)=median(wghtSpec.xyPlane(actrow).row(pol));
1134 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1135 : }*/
1136 : }
1137 : }
1138 : //now lets put back the stuff
1139 : //cerr << "rowids " << rowids << endl;
1140 0 : RefRows elrow(rowids);
1141 0 : msc.flagRow().putColumnCells(elrow, rowFlag);
1142 : //reference row
1143 : //Matrix<Complex>matdata(grid.xyPlane(k));
1144 0 : msc.data().putColumnCells(elrow, grid);
1145 : //Matrix<Float> matwgt(wghtSpec.xyPlane(k));
1146 0 : msc.weightSpectrum().putColumnCells(elrow, wghtSpec);
1147 : //Matrix<Bool> matflag(flag.xyPlane(k));
1148 0 : msc.flag().putColumnCells(elrow, flag);
1149 : //Vector<Double> vecuvw(uvw.column(k));
1150 0 : msc.uvw().putColumnCells(elrow, uvw);
1151 : //cerr << "ant1 " << ant1 << endl;
1152 0 : msc.antenna1().putColumnCells(elrow, ant1);
1153 0 : msc.antenna2().putColumnCells(elrow, ant2);
1154 0 : msc.time().putColumnCells(elrow, timeCen);
1155 : //outMsPtr_p->flush(true);
1156 : ///////
1157 :
1158 :
1159 0 : }
1160 :
1161 0 : void MSUVBin::inplaceSmallBW(const vi::VisBuffer2& vb){
1162 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1163 : //not there
1164 0 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1165 0 : Int nrows=vb.nRows();
1166 0 : MSColumns msc(*outMsPtr_p);
1167 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1168 : Double refFreq;
1169 0 : spec.toWorld(refFreq, Double(nchan_p)/2.0);
1170 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1171 0 : Vector<Float> scale(2);
1172 0 : scale(0)=(nx_p*thedir.increment()(0))/C::c;
1173 0 : scale(1)=(ny_p*thedir.increment()(1))/C::c;
1174 : ///Index
1175 0 : Vector<Int> rowToIndex(nx_p*ny_p, -1);
1176 0 : Vector<Int> locu(nrows, -1);
1177 0 : Vector<Int> locv(nrows, -1);
1178 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1179 0 : Int numUniq=0;
1180 0 : Vector<Double> phasor;
1181 0 : Matrix<Double> eluvw;
1182 0 : eluvw=vb.uvw();
1183 0 : Bool needRot=vbutil_p.rotateUVW(vb, phaseCenter_p, eluvw, phasor);
1184 : //cerr << "SHAPES " << eluvw.shape() << " " << vb.uvw().shape() << endl;
1185 0 : for (Int k=0; k <nrows; ++k){
1186 0 : locv(k)=Int(Double(ny_p)/2.0+eluvw(1,k)*refFreq*scale(1)+0.5);
1187 0 : locu(k)=Int(Double(nx_p)/2.0+eluvw(0,k)*refFreq*scale(0)+0.5);
1188 : //cerr << "locu " << locu(k) << " locv " << locv(k) << " eluvw " << eluvw(0,k) << " uvw " << vb.uvw()(0,k) << endl;
1189 0 : if(locu(k) > -1 && locu(k) < nx_p && locv(k)> -1 && locv(k) < ny_p){
1190 0 : Int newrow=locv(k)*nx_p+locu(k);
1191 0 : if(rowToIndex[newrow] <0){
1192 0 : rowToIndex[newrow]=numUniq;
1193 0 : ++numUniq;
1194 : }
1195 : }
1196 :
1197 : }
1198 :
1199 : //cerr << "numrows " << vb.nRows() << " nuniq " << numUniq << endl;
1200 0 : Cube<Complex> grid(npol_p, nchan_p, numUniq);
1201 0 : Matrix<Float> wght(npol_p,numUniq);
1202 0 : Cube<Float> wghtSpec(npol_p,nchan_p,numUniq);
1203 0 : Cube<Bool> flag(npol_p, nchan_p,numUniq);
1204 0 : Vector<Bool> rowFlag(numUniq);
1205 0 : Matrix<Double> uvw(3, numUniq);
1206 0 : Vector<Int> ant1(numUniq);
1207 0 : Vector<Int> ant2(numUniq);
1208 0 : Vector<Double> timeCen(numUniq);
1209 0 : Vector<uInt> rowids(numUniq);
1210 0 : Vector<Bool> rowvisited(numUniq, false);
1211 :
1212 0 : Vector<Double> invLambda=visFreq/C::c;
1213 0 : for (Int k=0; k < nrows; ++k){
1214 :
1215 0 : if(locu(k) > -1 && locu(k) < nx_p && locv(k)> -1 && locv(k) < ny_p){
1216 0 : Int newrow=locv(k)*nx_p+locu(k);
1217 0 : Int actrow=rowToIndex[newrow];
1218 0 : rowids[actrow]=uInt(newrow);
1219 0 : if(!rowvisited[actrow]){
1220 0 : rowvisited[actrow]=true;
1221 0 : rowFlag[actrow]=msc.flagRow()(newrow);
1222 0 : wghtSpec[actrow]=msc.weightSpectrum().get(newrow);
1223 0 : flag[actrow]=msc.flag().get(newrow);
1224 0 : uvw[actrow]=msc.uvw().get(newrow);
1225 0 : ant1[actrow]=msc.antenna1()(newrow);
1226 0 : ant2[actrow]=msc.antenna2()(newrow);
1227 0 : timeCen[actrow]=msc.time()(newrow);
1228 0 : grid[actrow]=msc.data().get(newrow);
1229 : }
1230 0 : if(rowFlag[actrow] && !(vb.flagRow()(k))){
1231 : // cerr << newrow << " rowFlag " << rowFlag[actrow] <<" rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,actrow) << endl;
1232 0 : rowFlag[actrow]=false;
1233 0 : uvw(2,actrow)=eluvw(2,k);
1234 : // cerr << newrow << " rowFlag " << rowFlag[actrow] <<" rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,actrow) << endl;
1235 0 : ant1[actrow]=vb.antenna1()(k);
1236 0 : ant2[actrow]=vb.antenna2()(k);
1237 0 : timeCen[actrow]=vb.time()(k);
1238 : }
1239 0 : Complex elphas(1.0, 0.0);
1240 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1241 :
1242 0 : if(chanMap_p(chan) >=0){
1243 0 : if(needRot){
1244 0 : Double phasmult=phasor(k)*invLambda(chan);
1245 : Double s, c;
1246 0 : SINCOS(phasmult, s, c);
1247 0 : elphas=Complex(c, s);
1248 : }
1249 :
1250 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1251 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0)){
1252 0 : Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k):
1253 0 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k);
1254 0 : if(needRot)
1255 0 : toB *= elphas;
1256 0 : grid(polMap_p(pol),chanMap_p(chan),actrow)
1257 0 : = (grid(polMap_p(pol),chanMap_p(chan),actrow)*wghtSpec(polMap_p(pol),chanMap_p(chan),actrow)
1258 0 : + toB)/(vb.weight()(pol,k)+wghtSpec(polMap_p(pol),chanMap_p(chan),actrow));
1259 0 : flag(polMap_p(pol),chanMap_p(chan),actrow)=false;
1260 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1261 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1262 0 : wghtSpec(polMap_p(pol),chanMap_p(chan),actrow) += vb.weight()(pol,k);
1263 : }
1264 : }
1265 : }
1266 : }
1267 : //This should go for later
1268 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1269 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1270 : wght(pol,actrow)=median(wghtSpec.xyPlane(actrow).row(pol));
1271 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1272 : }*/
1273 : }
1274 : }
1275 : //now lets put back the stuff
1276 0 : RefRows elrow(rowids);
1277 : //cerr << "ROWIDS " << rowids << endl;
1278 0 : msc.flagRow().putColumnCells(elrow, rowFlag);
1279 : //reference row
1280 : //Matrix<Complex>matdata(grid.xyPlane(k));
1281 0 : msc.data().putColumnCells(elrow, grid);
1282 : //Matrix<Float> matwgt(wghtSpec.xyPlane(k));
1283 0 : msc.weightSpectrum().putColumnCells(elrow, wghtSpec);
1284 : //Matrix<Bool> matflag(flag.xyPlane(k));
1285 0 : msc.flag().putColumnCells(elrow, flag);
1286 : //Vector<Double> vecuvw(uvw.column(k));
1287 0 : msc.uvw().putColumnCells(elrow, uvw);
1288 : //cerr << "ant1 " << ant1 << endl;
1289 0 : msc.antenna1().putColumnCells(elrow, ant1);
1290 0 : msc.antenna2().putColumnCells(elrow, ant2);
1291 0 : msc.time().putColumnCells(elrow, timeCen);
1292 : //outMsPtr_p->flush(true);
1293 : ///////
1294 :
1295 :
1296 0 : }
1297 :
1298 :
1299 :
1300 0 : void MSUVBin::gridData(const vi::VisBuffer2& vb, Cube<Complex>& grid,
1301 : Matrix<Float>& /*wght*/, Cube<Float>& wghtSpec,
1302 : Cube<Bool>& flag, Vector<Bool>& rowFlag, Matrix<Double>& uvw, Vector<Int>& ant1,
1303 : Vector<Int>& ant2, Vector<Double>& timeCen, const Matrix<Int>& /*locuv*/){
1304 : //all pixel that are touched the flag and flag Row shall be unset and the w be assigned
1305 : //later we'll deal with multiple w for the same uv
1306 : //we need polmap and chanmap;
1307 :
1308 : Double fracbw;
1309 0 : if(!datadescMap(vb, fracbw)) return;
1310 : //cerr << "fracbw " << fracbw << endl;
1311 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1312 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1313 0 : Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
1314 : //Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(0));
1315 0 : Vector<Float> scale(2);
1316 0 : scale(0)=fabs(nx_p*thedir.increment()(0))/C::c;
1317 0 : scale(1)=fabs(ny_p*thedir.increment()(1))/C::c;
1318 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1319 : //not there
1320 0 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1321 : //locateuvw(locuv, vb.uvw());
1322 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1323 0 : for (rownr_t k=0; k < vb.nRows(); ++k){
1324 0 : if(!vb.flagRow()[k]){
1325 : Int locu, locv;
1326 : {
1327 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
1328 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
1329 :
1330 : }
1331 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1332 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << endl;
1333 : //Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1334 : //Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1335 : //Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1336 : //Double phaseCorr=((newU-vb.uvw()(0,k))+(newV-vb.uvw()(1,k)))*2.0*M_PI*refFreq/C::c;
1337 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1338 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << " phase " << phaseCorr << endl;
1339 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1340 0 : if(chanMap_p(chan) >=0){
1341 : //Double outChanFreq;
1342 : //spec.toWorld(outChanFreq, Double(chanMap_p(chan)));
1343 0 : if(fracbw > 0.05)
1344 : {
1345 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
1346 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
1347 : }
1348 0 : if(locv < ny_p && locu < nx_p){
1349 0 : Int newrow=locv*nx_p+locu;
1350 0 : if(rowFlag(newrow) && !(vb.flagRow()(k))){
1351 0 : rowFlag(newrow)=false;
1352 : /////TEST
1353 : //uvw(0,newrow)=vb.uvw()(0,k);
1354 : //uvw(1,newrow)=vb.uvw()(1,k);
1355 : /////
1356 0 : uvw(2,newrow)=vb.uvw()(2,k);
1357 : //cerr << newrow << " rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,newrow) << endl;
1358 0 : ant1(newrow)=vb.antenna1()(k);
1359 0 : ant2(newrow)=vb.antenna2()(k);
1360 0 : timeCen(newrow)=vb.time()(k);
1361 :
1362 : }
1363 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1364 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0)){
1365 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1366 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1367 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1368 0 : Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k):
1369 0 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k);
1370 : // Double s, c;
1371 : //SINCOS(phaseCorr, s, c);
1372 : // toB=toB*Complex(c,s);
1373 0 : grid(polMap_p(pol),chanMap_p(chan), newrow)
1374 0 : = (grid(polMap_p(pol),chanMap_p(chan), newrow)*wghtSpec(polMap_p(pol),chanMap_p(chan),newrow)
1375 0 : + toB)/(vb.weight()(pol,k)+wghtSpec(polMap_p(pol),chanMap_p(chan),newrow));
1376 0 : flag(polMap_p(pol),chanMap_p(chan), newrow)=false;
1377 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1378 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1379 0 : wghtSpec(polMap_p(pol),chanMap_p(chan), newrow) += vb.weight()(pol,k);
1380 : }
1381 : ///We should do that at the end totally
1382 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1383 : }
1384 : }//locu && locv
1385 : }
1386 : }
1387 : //sum wgtspec along channels for weight
1388 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1389 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1390 : wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1391 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1392 : }
1393 : */
1394 : }
1395 : }
1396 :
1397 :
1398 :
1399 :
1400 0 : }
1401 :
1402 1428 : void MSUVBin::gridData(const vi::VisBuffer2& vb, Cube<Complex>& grid,
1403 : Matrix<Float>& /*wght*/, Cube<Float>& wghtSpec,
1404 : Cube<Bool>& flag, Vector<Bool>& rowFlag, Matrix<Double>& uvw, Vector<Int>& ant1,
1405 : Vector<Int>& ant2, Vector<Double>& timeCen, const Int startchan, const Int endchan){
1406 : //all pixel that are touched the flag and flag Row shall be unset and the w be assigned
1407 : //later we'll deal with multiple w for the same uv
1408 : //we need polmap and chanmap;
1409 :
1410 : Double fracbw;
1411 1428 : if(!datadescMap(vb, fracbw)) return;
1412 : //cerr << "fracbw " << fracbw << endl;
1413 1428 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1414 1428 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1415 1428 : Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
1416 : //Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(0));
1417 1428 : Vector<Float> scale(2);
1418 1428 : scale(0)=fabs(Double(nx_p)*thedir.increment()(0))/C::c;
1419 1428 : scale(1)=fabs(Double(ny_p)*thedir.increment()(1))/C::c;
1420 : //cerr << "dir incr "<< thedir.increment() << " nx ny " << nx_p << " " << ny_p << endl;
1421 : //cerr << "SCALE " << scale << " fracbw " << fracbw << endl;
1422 :
1423 : //cerr << "chanmap " << chanMap_p << " pol map " <<polMap_p << " weight " << wghtSpec.shape() << endl;
1424 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1425 : //not there
1426 1428 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1427 : //locateuvw(locuv, vb.uvw());
1428 1428 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1429 465528 : for (rownr_t k=0; k < vb.nRows(); ++k){
1430 464100 : if(!vb.flagRow()[k]){
1431 : Int locu, locv;
1432 : {
1433 464100 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
1434 464100 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
1435 :
1436 : }
1437 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1438 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << endl;
1439 : //Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1440 : //Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1441 : //Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1442 : //Double phaseCorr=((newU-vb.uvw()(0,k))+(newV-vb.uvw()(1,k)))*2.0*M_PI*refFreq/C::c;
1443 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1444 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << " phase " << phaseCorr << endl;
1445 30166500 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1446 29702400 : if(chanMap_p(chan) >=startchan && chanMap_p(chan) <=endchan){
1447 : //Double outChanFreq;
1448 : //spec.toWorld(outChanFreq, Double(chanMap_p(chan)));
1449 29702400 : if(fracbw > 0.05)
1450 : {
1451 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
1452 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
1453 : }
1454 29702400 : if(locv < ny_p && locu < nx_p && locv >=0 && locu >=0){
1455 29702400 : Int newrow=locv*nx_p+locu;
1456 29702400 : if(rowFlag(newrow) && !(vb.flagRow()(k))){
1457 2188 : rowFlag(newrow)=false;
1458 : /////TEST
1459 : //uvw(0,newrow)=vb.uvw()(0,k);
1460 : //uvw(1,newrow)=vb.uvw()(1,k);
1461 : /////
1462 2188 : uvw(2,newrow)=vb.uvw()(2,k);
1463 : //cerr << newrow << " rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,newrow) << endl;
1464 2188 : ant1(newrow)=vb.antenna1()(k);
1465 2188 : ant2(newrow)=vb.antenna2()(k);
1466 2188 : timeCen(newrow)=vb.time()(k);
1467 :
1468 : }
1469 148512000 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1470 118809600 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0)){
1471 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1472 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1473 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1474 0 : Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k):
1475 52597488 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k);
1476 : // Double s, c;
1477 : //SINCOS(phaseCorr, s, c);
1478 : // toB=toB*Complex(c,s);
1479 52597488 : grid(polMap_p(pol),chanMap_p(chan)-startchan, newrow)
1480 52597488 : = (grid(polMap_p(pol),chanMap_p(chan)-startchan, newrow)
1481 52597488 : + toB); ///(vb.weight()(pol,k)+wghtSpec(polMap_p(pol),chanMap_p(chan)-startchan,newrow));
1482 52597488 : flag(polMap_p(pol),chanMap_p(chan)-startchan, newrow)=false;
1483 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1484 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1485 52597488 : wghtSpec(polMap_p(pol),chanMap_p(chan)-startchan, newrow) += vb.weight()(pol,k);
1486 : }
1487 : ///We should do that at the end totally
1488 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1489 : }
1490 : }//locu && locv
1491 : }
1492 : }
1493 : //sum wgtspec along channels for weight
1494 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1495 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1496 : wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1497 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1498 : }
1499 : */
1500 : }
1501 : }
1502 :
1503 :
1504 :
1505 :
1506 1428 : }
1507 0 : void MSUVBin::gridDataConv(const vi::VisBuffer2& vb, Cube<Complex>& grid,
1508 : Matrix<Float>& /*wght*/, Cube<Complex>& wghtSpec,
1509 : Cube<Bool>& flag, Vector<Bool>& rowFlag, Matrix<Double>& uvw, Vector<Int>& ant1,
1510 : Vector<Int>& ant2, Vector<Double>& timeCen, const Int startchan, const Int endchan, const Cube<Complex>& convFunc, const Vector<Int>& convSupport, const Double wScale, const Int convSampling){
1511 : //all pixel that are touched the flag and flag Row shall be unset and the w be assigned
1512 : //later we'll deal with multiple w for the same uv
1513 : //we need polmap and chanmap;
1514 :
1515 : Double fracbw;
1516 0 : if(!datadescMap(vb, fracbw)) return;
1517 : //cerr << "fracbw " << fracbw << endl;
1518 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1519 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1520 0 : Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
1521 : //Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(0));
1522 0 : Vector<Float> scale(2);
1523 0 : scale(0)=fabs(Double(nx_p)*thedir.increment()(0))/C::c;
1524 0 : scale(1)=fabs(Double(ny_p)*thedir.increment()(1))/C::c;
1525 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1526 : //not there
1527 0 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1528 : //locateuvw(locu v, vb.uvw());
1529 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1530 : //cerr << "support " << convSupport << endl;
1531 0 : Vector<Double> phasor;
1532 0 : Matrix<Double> eluvw;
1533 0 : eluvw=vb.uvw();
1534 0 : Bool needRot=vbutil_p.rotateUVW(vb, phaseCenter_p, eluvw, phasor);
1535 0 : Vector<Double> invLambda=visFreq/C::c;
1536 0 : for (rownr_t k=0; k < vb.nRows(); ++k){
1537 0 : if(!vb.flagRow()[k]){
1538 : Int locu, locv, locw,supp, offu, offv;
1539 : {
1540 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
1541 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
1542 0 : offv=Int ((Double(locv)-(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)))*Double(convSampling)+0.5);
1543 0 : offu=Int ((Double(locu)-(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)))*Double(convSampling)+0.5);
1544 0 : locw=Int(sqrt(fabs(wScale*vb.uvw()(2,k)*refFreq/C::c))+0.5);
1545 : //cerr << "locw " << locw << " " << " offs " << offu << " " << offv << endl;
1546 0 : supp=locw < convSupport.shape()[0] ? convSupport(locw) :convSupport(convSupport.nelements()-1) ;
1547 : //////////////////
1548 : //supp=10;
1549 : /////////////////
1550 : }
1551 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1552 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << endl;
1553 : //Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1554 : //Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1555 : //Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1556 : //Double phaseCorr=((newU-vb.uvw()(0,k))+(newV-vb.uvw()(1,k)))*2.0*M_PI*refFreq/C::c;
1557 : //cerr << "fracbw " << fracbw << " pixel u " << Double(locu-nx_p/2)/refFreq/scale(0) << " data u" << vb.uvw()(0,k) <<
1558 : // " pixel v "<< Double(locv-ny_p/2)/refFreq/scale(1) << " data v "<< vb.uvw()(1,k) << " phase " << phaseCorr << endl;
1559 0 : Vector<Int> newrow((2*supp+1)*(2*supp+1), -1);
1560 0 : if(locv < ny_p && locu < nx_p){
1561 0 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1562 0 : Int newlocv=locv+ yy-supp;
1563 0 : if(newlocv >0 && newlocv < ny_p){
1564 0 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1565 0 : Int newlocu=locu+xx-supp;
1566 0 : if(newlocu < nx_p && newlocu >0){
1567 0 : newrow(yy*(2*supp+1)+xx)=newlocv*nx_p+newlocu;
1568 : }
1569 : }
1570 : }
1571 : }
1572 : }
1573 0 : Complex elphas(1.0, 0.0);
1574 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
1575 0 : if(chanMap_p(chan) >=startchan && chanMap_p(chan) <=endchan){
1576 : //Double outChanFreq;
1577 : //spec.toWorld(outChanFreq, Double(chanMap_p(chan)));
1578 0 : if(needRot){
1579 0 : Double phasmult=phasor(k)*invLambda(chan);
1580 : Double s, c;
1581 0 : SINCOS(phasmult, s, c);
1582 0 : elphas=Complex(c, s);
1583 : }
1584 0 : if(fracbw > 0.05)
1585 : {
1586 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
1587 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
1588 : }
1589 0 : if(locv < ny_p && locu < nx_p){
1590 0 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1591 0 : Int locy=abs((yy-supp)*convSampling+offv);
1592 : //cerr << "y " << yy << " locy " << locy ;
1593 0 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1594 0 : Int locx=abs((xx-supp)*convSampling+offu);
1595 : //cerr << " x " << xx << " locx " << locx << endl;
1596 0 : Int jj=yy*(2*supp+1)+xx;
1597 0 : if(newrow[jj] >-1){
1598 0 : Complex cwt=convFunc(locx, locy, locw);
1599 : ////////////////TEST
1600 : //cwt=Complex(1.0, 0.0);
1601 : ///////////////////////////////////
1602 0 : if(vb.uvw()(2,k) > 0.0)
1603 0 : cwt=conj(cwt);
1604 0 : if(rowFlag(newrow[jj]) && !(vb.flagRow()(k))){
1605 0 : rowFlag(newrow[jj])=false;
1606 : /////TEST
1607 : //uvw(0,newrow)=vb.uvw()(0,k);
1608 : //uvw(1,newrow)=vb.uvw()(1,k);
1609 : /////
1610 0 : uvw(2,newrow[jj])=0;
1611 : //cerr << newrow << " rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,newrow) << endl;
1612 0 : ant1(newrow[jj])=vb.antenna1()(k);
1613 0 : ant2(newrow[jj])=vb.antenna2()(k);
1614 0 : timeCen(newrow[jj])=vb.time()(k);
1615 :
1616 : }
1617 0 : Int lechan=chanMap_p(chan)-startchan;
1618 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1619 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0) && (fabs(cwt) > 0.0)){
1620 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1621 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1622 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1623 : Complex toB=hasCorrected ?
1624 0 : vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k)*cwt:
1625 0 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k)*cwt;
1626 : //Complex dat=hasCorrected ? vb.visCubeCorrected()(pol,chan,k) :
1627 : // vb.visCube()(pol,chan,k);
1628 0 : if(needRot)
1629 0 : toB *=elphas;
1630 : // Double s, c;
1631 : //SINCOS(phaseCorr, s, c);
1632 : // toB=toB*Complex(c,s);
1633 : //Float elwgt=vb.weight()(pol,k)* fabs(real(cwt));
1634 : //////////////TESTING
1635 0 : Complex elwgt=vb.weight()(pol,k)* cwt;
1636 : //Complex elwgt=real(dat) !=0.0 ? real(toB)/real(dat): 0.0;
1637 : ///////////////////////////
1638 0 : grid(polMap_p(pol),lechan, newrow[jj])
1639 0 : = (grid(polMap_p(pol),lechan, newrow[jj])/*wghtSpec(polMap_p(pol),lechan,newrow[jj])*/
1640 0 : + toB);///(elwgt+wghtSpec(polMap_p(pol),lechan,newrow[jj]));
1641 0 : flag(polMap_p(pol), lechan, newrow[jj])=false;
1642 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1643 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1644 : // if( wghtSpec(polMap_p(pol),lechan, newrow[jj]) > 10)
1645 : //if(newrow[jj]==2149026)
1646 : // cerr <<xx << " : " << yy << " : " <<jj <<" spec " << wghtSpec(polMap_p(pol),lechan, newrow[jj]) << " elwgt " << elwgt << " chan " <<chan << " : " << lechan << " pol " << pol << " newrow " << newrow[jj] << " vbrow " << vb.rowIds()(k) << " uv " << uvw(0, newrow[jj]) << " " << uvw(1, newrow[jj]) << " " << vb.uvw()(0,k) << " " << vb.uvw()(1,k) <<endl;
1647 0 : wghtSpec(polMap_p(pol),lechan, newrow[jj]) += elwgt;
1648 : }
1649 : ///We should do that at the end totally
1650 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1651 : }
1652 : }//if(newrow)
1653 : }
1654 : }
1655 : }//locu && locv
1656 : }
1657 : }
1658 : //sum wgtspec along channels for weight
1659 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1660 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1661 : wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1662 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1663 : }
1664 : */
1665 0 : }
1666 : }
1667 :
1668 :
1669 :
1670 :
1671 0 : }
1672 0 : void MSUVBin::gridDataConvThr(const vi::VisBuffer2& vb, Cube<Complex>& grid,
1673 : Cube<Complex>& wghtSpec,
1674 : Cube<Bool>& flag, Vector<Bool>& rowFlag, Matrix<Double>& uvw, Vector<Int>& ant1,
1675 : Vector<Int>& ant2, Vector<Double>& timeCen, const Int startchan, const Int endchan, const Cube<Complex>& convFunc, const Vector<Int>& convSupport, const Double wScale, const Int convSampling){
1676 : //all pixel that are touched the flag and flag Row shall be unset and the w be assigned
1677 : //later we'll deal with multiple w for the same uv
1678 : //we need polmap and chanmap;
1679 :
1680 : Double fracbw;
1681 0 : if(!datadescMap(vb, fracbw)) return;
1682 : //cerr << "fracbw " << fracbw << endl;
1683 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
1684 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
1685 0 : Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
1686 : //Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(0));
1687 0 : Vector<Float> scale(2);
1688 0 : scale(0)=fabs(Double(nx_p)*thedir.increment()(0))/C::c;
1689 0 : scale(1)=fabs(Double(ny_p)*thedir.increment()(1))/C::c;
1690 : //Dang i thought the new vb will return Data or FloatData if correctedData was
1691 : //not there
1692 0 : Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
1693 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
1694 : //cerr << "support " << convSupport << endl;
1695 0 : Vector<Double> phasor;
1696 0 : Matrix<Double> eluvw;
1697 0 : eluvw=vb.uvw();
1698 0 : Bool needRot=vbutil_p.rotateUVW(vb, phaseCenter_p, eluvw, phasor);
1699 : Bool gridCopy, weightCopy, flagCopy, rowFlagCopy, uvwCopy, ant1Copy, ant2Copy, timeCenCopy, sumWeightCopy, numVisCopy;
1700 0 : Complex * gridStor=grid.getStorage(gridCopy);
1701 0 : Complex * wghtSpecStor=wghtSpec.getStorage(weightCopy);
1702 0 : Bool * flagStor=flag.getStorage(flagCopy);
1703 0 : Bool * rowFlagStor=rowFlag.getStorage(rowFlagCopy);
1704 0 : Double * uvwStor=uvw.getStorage(uvwCopy);
1705 0 : Int* ant1Stor=ant1.getStorage(ant1Copy);
1706 0 : Int* ant2Stor=ant2.getStorage(ant2Copy);
1707 0 : Double* timeCenStor= timeCen.getStorage(timeCenCopy);
1708 0 : Double* sumweightStor=sumWeight_p.getStorage(sumWeightCopy);
1709 0 : Double* numvisStor=numVis_p.getStorage(numVisCopy);
1710 : // Vector<Double> invLambda=visFreq/C::c;
1711 :
1712 : //Fill the caches in the master thread
1713 : //// these are thread unsafe...unless already cached
1714 0 : vb.flagRow(); vb.uvw(); vb.antenna1(); vb.antenna2(); vb.time();
1715 0 : vb.nRows(); vb.nCorrelations();
1716 0 : if(hasCorrected)
1717 0 : vb.visCubeCorrected();
1718 : else
1719 0 : vb.visCube();
1720 0 : vb.flagCube();
1721 0 : vb.weight();
1722 : ///////////////////////////
1723 0 : Int nth=1;
1724 : #ifdef _OPENMP
1725 0 : nth=min(nchan_p, omp_get_max_threads());
1726 0 : omp_set_dynamic(0);
1727 : #endif
1728 0 : #pragma omp parallel for firstprivate(refFreq, scale, hasCorrected, needRot, fracbw, gridStor, wghtSpecStor, flagStor, rowFlagStor, uvwStor, ant1Stor, ant2Stor, timeCenStor, sumweightStor, numvisStor ) shared(phasor, visFreq) num_threads(nth) schedule(dynamic, 1)
1729 :
1730 : for(Int outchan=0; outchan < nchan_p; ++outchan){
1731 : //cerr << "outchan " << outchan << " " << chanMapRev_p[outchan] << endl;
1732 :
1733 : multiThrLoop(outchan, vb, refFreq, scale, hasCorrected, needRot, phasor, visFreq,
1734 : fracbw, gridStor, wghtSpecStor, flagStor, rowFlagStor, uvwStor, ant1Stor,
1735 : ant2Stor, timeCenStor, sumweightStor, numvisStor, startchan, endchan, convFunc, convSupport, wScale,
1736 : convSampling);
1737 :
1738 : /*for(uInt nel=0; nel < chanMapRev_p[outchan].nelements(); ++nel ){
1739 : Int chan=chanMapRev_p[outchan][nel];
1740 : for (Int k=0; k < vb.nRows(); ++k){
1741 : if(!vb.flagRow()[k]){
1742 : Int locu, locv, locw,supp, offu, offv;
1743 : {
1744 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
1745 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
1746 : offv=Int ((Double(locv)-(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)))*Double(convSampling)+0.5);
1747 : offu=Int ((Double(locu)-(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)))*Double(convSampling)+0.5);
1748 : locw=Int(sqrt(fabs(wScale*vb.uvw()(2,k)*refFreq/C::c))+0.5);
1749 : supp=locw < convSupport.shape()[0] ? convSupport(locw) :conSupport(convSupport.nelements()-1) ;
1750 : }
1751 :
1752 : Vector<Int> newrow((2*supp+1)*(2*supp+1), -1);
1753 : if(locv < ny_p && locu < nx_p){
1754 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1755 : Int newlocv=locv+ yy-supp;
1756 : if(newlocv >0 && newlocv < ny_p){
1757 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1758 : Int newlocu=locu+xx-supp;
1759 : if(newlocu < nx_p && newlocu >0){
1760 : newrow(yy*(2*supp+1)+xx)=newlocv*nx_p+newlocu;
1761 : }
1762 : }
1763 : }
1764 : }
1765 : }
1766 : Complex elphas(1.0, 0.0);
1767 :
1768 : if(chanMap_p(chan) >=startchan && chanMap_p(chan) <=endchan){
1769 : if(needRot){
1770 : Double phasmult=phasor(k)*invLambda(chan);
1771 : Double s, c;
1772 : SINCOS(phasmult, s, c);
1773 : elphas=Complex(c, s);
1774 : }
1775 : if(fracbw > 0.05)
1776 : {
1777 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
1778 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
1779 : }
1780 : if(locv < ny_p && locu < nx_p){
1781 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1782 : Int locy=abs((yy-supp)*convSampling+offv);
1783 :
1784 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1785 : Int locx=abs((xx-supp)*convSampling+offu);
1786 :
1787 : Int jj=yy*(2*supp+1)+xx;
1788 : if(newrow[jj] >-1){
1789 : Complex cwt=convFunc(locx, locy, locw);
1790 : if(vb.uvw()(2,k) > 0.0)
1791 : cwt=conj(cwt);
1792 : if(rowFlag(newrow[jj]) && !(vb.flagRow()(k))){
1793 : rowFlag(newrow[jj])=false;
1794 : uvw(2,newrow[jj])=0;
1795 : ant1(newrow[jj])=vb.antenna1()(k);
1796 : ant2(newrow[jj])=vb.antenna2()(k);
1797 : timeCen(newrow[jj])=vb.time()(k);
1798 :
1799 : }
1800 : Int lechan=chanMap_p(chan)-startchan;
1801 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1802 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0) && (fabs(cwt) > 0.0)){
1803 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1804 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1805 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1806 : Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k)*cwt:
1807 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k)*cwt;
1808 : if(needRot)
1809 : toB *=elphas;
1810 : // Double s, c;
1811 : //SINCOS(phaseCorr, s, c);
1812 : // toB=toB*Complex(c,s);
1813 : //Float elwgt=vb.weight()(pol,k)* fabs(real(cwt));
1814 : //////////////TESTING
1815 : Float elwgt=vb.weight()(pol,k)* real(cwt);
1816 : ///////////////////////////
1817 : grid(polMap_p(pol),lechan, newrow[jj])
1818 : = (grid(polMap_p(pol),lechan, newrow[jj])// *wghtSpec(polMap_p(pol),lechan,newrow[jj])
1819 : + toB); ///(elwgt+wghtSpec(polMap_p(pol),lechan,newrow[jj]));
1820 : flag(polMap_p(pol), lechan, newrow[jj])=false;
1821 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1822 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1823 : wghtSpec(polMap_p(pol),lechan, newrow[jj]) += elwgt;
1824 : }
1825 : ///We should do that at the end totally
1826 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1827 : }
1828 : }//if(newrow)
1829 : }
1830 : }
1831 : }//locu && locv
1832 : }
1833 : }
1834 : }
1835 : //sum wgtspec along channels for weight
1836 : }
1837 : */
1838 : }
1839 0 : grid.putStorage(gridStor, gridCopy);
1840 0 : wghtSpec.putStorage(wghtSpecStor, weightCopy);
1841 0 : flag.putStorage(flagStor, flagCopy);
1842 0 : rowFlag.putStorage(rowFlagStor, rowFlagCopy);
1843 0 : uvw.putStorage(uvwStor,uvwCopy);
1844 0 : ant1.putStorage(ant1Stor,ant1Copy);
1845 0 : ant2.putStorage(ant2Stor, ant2Copy);
1846 0 : timeCen.putStorage(timeCenStor, timeCenCopy);
1847 0 : sumWeight_p.putStorage(sumweightStor, sumWeightCopy);
1848 0 : numVis_p.putStorage(numvisStor, numVisCopy);
1849 :
1850 :
1851 0 : }
1852 :
1853 0 : void MSUVBin::multiThrLoop(const Int outchan, const vi::VisBuffer2& vb, Double refFreq, Vector<Float> scale, Bool hasCorrected, Bool needRot, const Vector<Double>& phasor, const Vector<Double>& visFreq, const Double& fracbw, Complex*& grid,
1854 : Complex*& wghtSpec,
1855 : Bool*& flag, Bool*& rowFlag, Double*& uvw,
1856 : Int*& ant1, Int*& ant2, Double*& timeCen, Double*& sumWeight, Double*& numVis,
1857 : const Int startchan, const Int endchan,
1858 : const Cube<Complex>& convFunc, const Vector<Int>& convSupport, const Double wScale, const Int convSampling ){
1859 :
1860 0 : for(uInt nel=0; nel < chanMapRev_p[outchan].nelements(); ++nel ){
1861 0 : Int chan=chanMapRev_p[outchan][nel];
1862 0 : Double invLambda=visFreq[chan]/C::c;
1863 0 : for (rownr_t k=0; k < vb.nRows(); ++k){
1864 0 : if(!vb.flagRow()[k]){
1865 : Int locu, locv, locw,supp, offu, offv;
1866 : {
1867 0 : Double centx=Double(nx_p)/2.0;
1868 0 : Double centy=Double(ny_p)/2.0;
1869 0 : locv=Int(centy+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
1870 0 : locu=Int(centx+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
1871 0 : offv=Int ((Double(locv)-(centy+vb.uvw()(1,k)*refFreq*scale(1)))*Double(convSampling)+0.5);
1872 0 : offu=Int ((Double(locu)-(centx+vb.uvw()(0,k)*refFreq*scale(0)))*Double(convSampling)+0.5);
1873 0 : locw=Int(sqrt(fabs(wScale*vb.uvw()(2,k)*refFreq/C::c))+0.5);
1874 0 : supp=locw < convSupport.shape()[0] ? convSupport(locw) :convSupport(convSupport.nelements()-1) ;
1875 : }
1876 :
1877 0 : Vector<Int> newrow((2*supp+1)*(2*supp+1), -1);
1878 0 : if(locv < ny_p && locu < nx_p){
1879 0 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1880 0 : Int newlocv=locv+ yy-supp;
1881 0 : if(newlocv >0 && newlocv < ny_p){
1882 0 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1883 0 : Int newlocu=locu+xx-supp;
1884 0 : if(newlocu < nx_p && newlocu >0){
1885 0 : newrow(yy*(2*supp+1)+xx)=newlocv*nx_p+newlocu;
1886 : }
1887 : }
1888 : }
1889 : }
1890 : }
1891 0 : Complex elphas(1.0, 0.0);
1892 :
1893 0 : if(chanMap_p(chan) >=startchan && chanMap_p(chan) <=endchan){
1894 0 : if(needRot){
1895 0 : Double phasmult=phasor(k)*invLambda;
1896 : Double s, c;
1897 0 : SINCOS(phasmult, s, c);
1898 0 : elphas=Complex(c, s);
1899 : }
1900 0 : if(fracbw > 0.05)
1901 : {
1902 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
1903 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
1904 : }
1905 0 : if(locv < ny_p && locu < nx_p){
1906 0 : for (Int yy=0; yy< Int(2*supp+1); ++yy){
1907 0 : Int locy=abs((yy-supp)*convSampling+offv);
1908 :
1909 0 : for (Int xx=0; xx< Int(2*supp+1); ++xx){
1910 0 : Int locx=abs((xx-supp)*convSampling+offu);
1911 :
1912 0 : Int jj=yy*(2*supp+1)+xx;
1913 : ////////TEST
1914 : //Int CENTER=2*supp*(supp+1);
1915 : //jj=CENTER;
1916 : /////////////////End TEST
1917 0 : if(newrow[jj] >-1){
1918 0 : Complex cwt=convFunc(locx, locy, locw);
1919 : //Float fracconv=fabs(cwt)/fabs(convFunc(0,0,locw));
1920 : /////TEST
1921 : //cwt=1.0;
1922 : //////
1923 0 : if(vb.uvw()(2,k) > 0.0)
1924 0 : cwt=conj(cwt);
1925 : //if(rowFlag[newrow[jj]] && !(vb.flagRow()(k))){
1926 0 : if(!(vb.flagRow()(k))){
1927 0 : rowFlag[newrow[jj]]=false;
1928 0 : if(yy==supp and xx==supp){
1929 0 : uvw[2+newrow[jj]*3]=0;
1930 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1931 0 : numVis[npol_p*chanMap_p(chan)+polMap_p(pol)] += 1.0;
1932 0 : sumWeight[npol_p*chanMap_p(chan)+polMap_p(pol)] += vb.weight()(pol,k) ;
1933 : }
1934 : }
1935 : /*else{
1936 : if(uvw[2+newrow[jj]*3] !=0)
1937 : uvw[2+newrow[jj]*3]=-666;
1938 : }*/
1939 0 : ant1[newrow[jj]]=vb.antenna1()(k);
1940 0 : ant2[newrow[jj]]=vb.antenna2()(k);
1941 0 : timeCen[newrow[jj]]=vb.time()(k);
1942 :
1943 : }
1944 0 : Int lechan=chanMap_p(chan)-startchan;
1945 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
1946 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) /*&& (vb.weight()(pol,k)>0.0) && fabs(cwt) > 0.0//// (fracconv > 5e-2)*/){
1947 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
1948 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
1949 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
1950 : Complex toB=hasCorrected ?
1951 0 : vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k)*cwt :
1952 0 : vb.visCube()(pol,chan,k)*vb.weight()(pol,k)*cwt;
1953 0 : if(needRot)
1954 0 : toB *=elphas;
1955 : // Double s, c;
1956 : //SINCOS(phaseCorr, s, c);
1957 : // toB=toB*Complex(c,s);
1958 : //Float elwgt=vb.weight()(pol,k)* fabs(real(cwt));
1959 : //////////////TESTING
1960 0 : Complex elwgt=vb.weight()(pol,k)* (cwt);
1961 : ///////////////////////////
1962 0 : ooLong cubindx=ooLong(newrow[jj])*ooLong(npol_p)*ooLong(endchan-startchan+1)+ooLong(lechan*npol_p)+ooLong(polMap_p(pol));
1963 : /* if(newrow[jj]==2023010 && outchan==0){
1964 : cerr << jj << " newrow[jj] " << newrow[jj] << " polMap_p(pol) " <<polMap_p(pol) << " cubindex " << cubindx << endl;
1965 : cerr << "uvw " << vb.uvw().column(k) << " weight " << vb.weight()(pol,k) << " elwgt " << elwgt << " cwt " << cwt << endl;
1966 : cerr << "revmap " << chanMapRev_p[outchan].nelements() << " support " << supp << " locu locv " << locu << " " <<locv << endl;
1967 : }*/
1968 0 : grid[cubindx]
1969 0 : = (grid[cubindx]// *wghtSpec(polMap_p(pol),lechan,newrow[jj])
1970 0 : + toB); ///(elwgt+wghtSpec(polMap_p(pol),lechan,newrow[jj]));
1971 0 : flag[cubindx]=false;
1972 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
1973 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
1974 0 : wghtSpec[cubindx] += elwgt;
1975 : //wghtSpec[cubindx] +=vb.weight()(pol,k)/(4*supp*supp);
1976 : }
1977 : ///We should do that at the end totally
1978 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1979 : }
1980 : }//if(newrow)
1981 : }
1982 : }
1983 : }//locu && locv
1984 : }
1985 0 : }
1986 : }
1987 : //sum wgtspec along channels for weight
1988 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
1989 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
1990 : wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
1991 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
1992 : }
1993 : */
1994 : }
1995 :
1996 0 : }
1997 :
1998 :
1999 0 : void MSUVBin::locateFlagFromGrid(vi::VisBuffer2& vb, Cube<Bool>& datFlag,
2000 : Cube<Float>& wghtSpec,
2001 : Cube<Bool>& flag, Vector<Bool>& rowFlag, Matrix<Double>& uvw, Vector<Int>& ant1,
2002 : Vector<Int>& ant2, Vector<Double>& timeCen, const Int startchan, const Int endchan){
2003 : //all pixel that are touched the flag and flag Row shall be unset and the w be assigned
2004 : //later we'll deal with multiple w for the same uv
2005 : //we need polmap and chanmap;
2006 :
2007 : Double fracbw;
2008 0 : if(!datadescMap(vb, fracbw)) return;
2009 : //cerr << "fracbw " << fracbw << endl;
2010 0 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
2011 0 : DirectionCoordinate thedir=csys_p.directionCoordinate(0);
2012 0 : Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(nchan_p/2));
2013 : //Double refFreq=SpectralImageUtil::worldFreq(csys_p, Double(0));
2014 0 : Vector<Float> scale(2);
2015 0 : scale(0)=fabs(nx_p*thedir.increment()(0))/C::c;
2016 0 : scale(1)=fabs(ny_p*thedir.increment()(1))/C::c;
2017 : //Dang i thought the new vb will return Data or FloatData if correctedData was
2018 : //not there
2019 : //Bool hasCorrected=!(MSMainColumns(vb.ms()).correctedData().isNull());
2020 : //locateuvw(locuv, vb.uvw());
2021 0 : Vector<Double> visFreq=vb.getFrequencies(0, MFrequency::LSRK);
2022 0 : for (rownr_t k=0; k < vb.nRows(); ++k){
2023 0 : if(!vb.flagRow()[k]){
2024 : Int locu, locv;
2025 : {
2026 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*refFreq*scale(1)+0.5);
2027 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*refFreq*scale(0)+0.5);
2028 :
2029 : }
2030 :
2031 0 : for(Int chan=0; chan < vb.nChannels(); ++chan ){
2032 0 : if(chanMap_p(chan) >=startchan && chanMap_p(chan) <=endchan){
2033 : //Double outChanFreq;
2034 : //spec.toWorld(outChanFreq, Double(chanMap_p(chan)));
2035 0 : if(fracbw > 0.05)
2036 : {
2037 0 : locv=Int(Double(ny_p)/2.0+vb.uvw()(1,k)*visFreq(chan)*scale(1)+0.5);
2038 0 : locu=Int(Double(nx_p)/2.0+vb.uvw()(0,k)*visFreq(chan)*scale(0)+0.5);
2039 : }
2040 0 : if(locv < ny_p && locu < nx_p && locv >=0 && locu >=0){
2041 0 : Int newrow=locv*nx_p+locu;
2042 0 : if(rowFlag(newrow) && !(vb.flagRow()(k))){
2043 0 : rowFlag(newrow)=false;
2044 : /////TEST
2045 : //uvw(0,newrow)=vb.uvw()(0,k);
2046 : //uvw(1,newrow)=vb.uvw()(1,k);
2047 : /////
2048 0 : uvw(2,newrow)=vb.uvw()(2,k);
2049 : //cerr << newrow << " rowids " << vb.rowIds()[k] << " uvw2 " << uvw(2 ,newrow) << endl;
2050 0 : ant1(newrow)=vb.antenna1()(k);
2051 0 : ant2(newrow)=vb.antenna2()(k);
2052 0 : timeCen(newrow)=vb.time()(k);
2053 :
2054 : }
2055 0 : for(Int pol=0; pol < vb.nCorrelations(); ++pol){
2056 0 : if((!vb.flagCube()(pol,chan, k)) && (polMap_p(pol)>=0) && (vb.weight()(pol,k)>0.0)){
2057 : // Double newU= Double(locu-nx_p/2)/refFreq/scale(0);
2058 : // Double newV= Double(locv-ny_p/2)/refFreq/scale(1);
2059 : // Double phaseCorr=((newU/vb.uvw()(0,k)-1)+(newV/vb.uvw()(1,k)-1))*vb.uvw()(2,k)*2.0*M_PI*refFreq/C::c;
2060 : // Complex toB=hasCorrected ? vb.visCubeCorrected()(pol,chan,k)*vb.weight()(pol,k):
2061 : // vb.visCube()(pol,chan,k)*vb.weight()(pol,k);
2062 : // Double s, c;
2063 : //SINCOS(phaseCorr, s, c);
2064 : // toB=toB*Complex(c,s);
2065 : // grid(polMap_p(pol),chanMap_p(chan)-startchan, newrow)
2066 : // = (grid(polMap_p(pol),chanMap_p(chan)-startchan, newrow)
2067 : // + toB); ///(vb.weight()(pol,k)+wghtSpec(polMap_p(pol),chanMap_p(chan)-startchan,newrow));
2068 0 : if(flag(polMap_p(pol),chanMap_p(chan)-startchan, newrow) || wghtSpec(polMap_p(pol),chanMap_p(chan)-startchan, newrow)==0.0) {
2069 0 : datFlag(pol,chan,k)=true;
2070 :
2071 : }
2072 : //cerr << "weights " << max(vb.weight()) << " spec " << max(vb.weightSpectrum()) << endl;
2073 : //wghtSpec(polMap_p(pol),chanMap_p(chan), newrow)+=vb.weightSpectrum()(pol, chan, k);
2074 : //wghtSpec(polMap_p(pol),chanMap_p(chan)-startchan, newrow) += vb.weight()(pol,k);
2075 : }
2076 : ///We should do that at the end totally
2077 : //wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
2078 : }
2079 : }//locu && locv
2080 : }
2081 : }
2082 : //sum wgtspec along channels for weight
2083 : /*for (Int pol=0; pol < wght.shape()(0); ++pol){
2084 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
2085 : wght(pol,newrow)=median(wghtSpec.xyPlane(newrow).row(pol));
2086 : //cerr << "pol " << pol << " newrow "<< newrow << " weight "<< wght(pol, newrow) << endl;
2087 : }
2088 : */
2089 : }
2090 : }
2091 :
2092 :
2093 :
2094 :
2095 0 : }
2096 4 : Bool MSUVBin::saveData(const Cube<Complex>& grid, const Cube<Bool>&flag, const Vector<Bool>& rowFlag,
2097 : const Cube<Float>&wghtSpec,
2098 : const Matrix<Double>& uvw, const Vector<Int>& ant1,
2099 : const Vector<Int>& ant2, const Vector<Double>& timeCen, const Int startchan, const Int endchan, const Cube<Float>& imagWghtSpec){
2100 4 : Bool retval=true;
2101 4 : MSColumns msc(*outMsPtr_p);
2102 4 : if(!existOut_p && startchan==0){
2103 2 : fillSubTables();
2104 : // msc.uvw().putColumn(uvw);
2105 :
2106 : }
2107 4 : msc.uvw().putColumn(uvw);
2108 8 : Slicer elslice(IPosition(2, 0, startchan), IPosition(2,npol_p, endchan-startchan+1));
2109 : //lets put ny_p slices
2110 4 : Int nchan=endchan-startchan+1;
2111 4 : Slice polslice(0,npol_p);
2112 4 : Slice chanslice(0,nchan);
2113 1204 : for (Int k=0; k <ny_p; ++k){
2114 : //Slicer rowslice(IPosition(1, k*nx_p), IPosition(1,nx_p));
2115 1200 : RefRows rowslice(k*nx_p, (k+1)*nx_p-1);
2116 1200 : msc.data().putColumnCells(rowslice, elslice, grid(polslice, chanslice, Slice(k*nx_p, nx_p)));
2117 : //msc.data().putColumnRange(rowslice, elslice, grid(polslice, chanslice, Slice(k*nx_p, nx_p)));
2118 1200 : msc.weightSpectrum().putColumnCells(rowslice, elslice, wghtSpec(polslice,chanslice, Slice(k*nx_p, nx_p)));
2119 : //msc.weightSpectrum().putColumnRange(rowslice, elslice, wghtSpec(polslice,chanslice, Slice(k*nx_p, nx_p)));
2120 : //////msc.weight().putColumn(wght);
2121 1200 : msc.flag().putColumnCells(rowslice, elslice,flag(polslice, chanslice, Slice(k*nx_p,nx_p)));
2122 : //msc.flag().putColumnRange(rowslice, elslice,flag(polslice, chanslice, Slice(k*nx_p,nx_p)));
2123 1200 : }
2124 4 : if(doW_p){
2125 0 : ArrayColumn<Float> imagWgtSpecCol(*outMsPtr_p, "IMAGINARY_WEIGHT_SPECTRUM");
2126 0 : for (Int k=0; k <ny_p; ++k){
2127 0 : RefRows rowslice(k*nx_p, (k+1)*nx_p-1);
2128 0 : imagWgtSpecCol.putColumnCells(rowslice, elslice, imagWghtSpec(polslice,chanslice, Slice(k*nx_p, nx_p)));
2129 0 : }
2130 0 : }
2131 4 : if(endchan==nchan_p-1){
2132 4 : msc.flagRow().putColumn(rowFlag);
2133 4 : msc.antenna1().putColumn(ant1);
2134 4 : msc.antenna2().putColumn(ant2);
2135 4 : Cube<Float> spectralweight;
2136 4 : msc.weightSpectrum().getColumn(spectralweight);
2137 4 : Matrix<Float> weight(npol_p, wghtSpec.shape()[2]);
2138 360004 : for (Int row=0; row < wghtSpec.shape()[2]; ++row){
2139 1080000 : for (Int pol=0; pol < npol_p; ++pol){
2140 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
2141 720000 : weight(pol,row)=min(spectralweight.xyPlane(row).row(pol));
2142 : //weight(pol,row)=1.0;
2143 : //if(!rowFlag(row))
2144 : // cerr << "pol " << pol << " row "<< row << " median "<< weight(pol, row) << " min-max " << (min(wghtSpec.xyPlane(row).row(pol))+max(wghtSpec.xyPlane(row).row(pol)))/2.0 << " mean " << mean(wghtSpec.xyPlane(row).row(pol)) << endl;
2145 : }
2146 : }
2147 :
2148 4 : msc.weight().putColumn(weight);
2149 4 : Matrix<Float> sigma(weight.shape());
2150 360004 : for (uInt k=0; k<weight.shape()[1]; ++k)
2151 1080000 : for (uInt j=0; j<weight.shape()[0]; ++j)
2152 720000 : sigma(j,k)=weight(j,k)>0.0 ? 1/sqrt(weight(j,k)) :0.0;
2153 4 : msc.sigma().putColumn(sigma);
2154 :
2155 4 : msc.time().putColumn(timeCen);
2156 4 : msc.timeCentroid().putColumn(timeCen);
2157 4 : }
2158 4 : return retval;
2159 :
2160 :
2161 4 : }
2162 0 : Bool MSUVBin::saveData(const Cube<Complex>& grid, const Cube<Bool>&flag, const Vector<Bool>& rowFlag,
2163 : const Cube<Float>&wghtSpec, const Matrix<Float>& /*wght*/,
2164 : const Matrix<Double>& uvw, const Vector<Int>& ant1,
2165 : const Vector<Int>& ant2, const Vector<Double>& timeCen){
2166 0 : Bool retval=true;
2167 0 : MSColumns msc(*outMsPtr_p);
2168 0 : if(!existOut_p){
2169 0 : fillSubTables();
2170 0 : msc.uvw().putColumn(uvw);
2171 :
2172 : }
2173 :
2174 :
2175 0 : msc.data().putColumn(grid);
2176 0 : msc.weightSpectrum().putColumn(wghtSpec);
2177 : //msc.weight().putColumn(wght);
2178 0 : msc.flag().putColumn(flag);
2179 0 : msc.flagRow().putColumn(rowFlag);
2180 0 : msc.antenna1().putColumn(ant1);
2181 0 : msc.antenna2().putColumn(ant2);
2182 0 : Matrix<Float> weight(npol_p, wghtSpec.shape()[2]);
2183 0 : for (Int row=0; row < wghtSpec.shape()[2]; ++row){
2184 0 : for (Int pol=0; pol < npol_p; ++pol){
2185 : //cerr << "shape min max "<< median(wghtSpec.xyPlane(newrow).row(pol)) << " " << min(wghtSpec.xyPlane(newrow).row(pol)) << " "<< max(wghtSpec.xyPlane(newrow).row(pol)) << endl;
2186 0 : weight(pol,row)=max(wghtSpec.xyPlane(row).row(pol));
2187 : //if(!rowFlag(row))
2188 : // cerr << "pol " << pol << " row "<< row << " median "<< weight(pol, row) << " min-max " << (min(wghtSpec.xyPlane(row).row(pol))+max(wghtSpec.xyPlane(row).row(pol)))/2.0 << " mean " << mean(wghtSpec.xyPlane(row).row(pol)) << endl;
2189 : }
2190 : }
2191 0 : msc.weight().putColumn(weight);
2192 0 : Matrix<Float> sigma(weight.shape());
2193 0 : for (uInt k=0; k<weight.shape()[1]; ++k)
2194 0 : for (uInt j=0; j<weight.shape()[0]; ++j)
2195 0 : sigma(j,k)=weight(j,k)>0.0 ? 1/sqrt(weight(j,k)) :0.0;
2196 0 : msc.sigma().putColumn(sigma);
2197 0 : msc.time().putColumn(timeCen);
2198 0 : msc.timeCentroid().putColumn(timeCen);
2199 :
2200 0 : return retval;
2201 :
2202 :
2203 0 : }
2204 2 : void MSUVBin::fillSubTables(){
2205 2 : fillFieldTable();
2206 2 : copySubtable("SPECTRAL_WINDOW", mss_p[0]->spectralWindow(), true);
2207 2 : copySubtable("POLARIZATION", mss_p[0]->polarization(), true);
2208 2 : copySubtable("DATA_DESCRIPTION", mss_p[0]->dataDescription(), true);
2209 2 : copySubtable("FEED", mss_p[0]->feed(), false);
2210 2 : copySubtable("OBSERVATION", mss_p[0]->observation(), false);
2211 2 : copySubtable("ANTENNA", mss_p[0]->antenna(), false);
2212 2 : fillDDTables();
2213 :
2214 2 : }
2215 2 : void MSUVBin::fillDDTables(){
2216 : {
2217 2 : MSPolarizationColumns mspol(outMsPtr_p->polarization());
2218 :
2219 2 : if(outMsPtr_p->polarization().nrow()==0)
2220 2 : outMsPtr_p->polarization().addRow();
2221 2 : mspol.numCorr().put(0, npol_p);
2222 2 : mspol.corrType().put(0,whichStokes_p);
2223 2 : Matrix<Int> corrProd(2,npol_p);
2224 2 : corrProd.set(0);
2225 2 : if(npol_p==2){
2226 2 : corrProd(0,1)=1;
2227 2 : corrProd(1,1)=1;
2228 : }
2229 2 : if(npol_p==4){
2230 0 : corrProd(0,1)=0;
2231 0 : corrProd(1,1)=1;
2232 0 : corrProd(0,2)=1;
2233 0 : corrProd(1,2)=0;
2234 0 : corrProd(0,3)=1;
2235 0 : corrProd(1,3)=1;
2236 : }
2237 2 : mspol.corrProduct().put(0,corrProd);
2238 2 : mspol.flagRow().put(0,false);
2239 2 : }
2240 : ///Now with Spectral window
2241 : {
2242 2 : MSSpWindowColumns msSpW(outMsPtr_p->spectralWindow());
2243 2 : if(outMsPtr_p->spectralWindow().nrow()==0){
2244 2 : MSTransformDataHandler::addOptionalColumns(mss_p[0]->spectralWindow(),
2245 2 : outMsPtr_p->spectralWindow());
2246 2 : outMsPtr_p->spectralWindow().addRow();
2247 : }
2248 2 : msSpW.name().put(0,"none");
2249 2 : msSpW.ifConvChain().put(0,0);
2250 2 : msSpW.numChan().put(0,nchan_p);
2251 2 : SpectralCoordinate spec=csys_p.spectralCoordinate(2);
2252 : Double refFreq;
2253 2 : spec.toWorld(refFreq,0.0);
2254 2 : Double chanBandWidth=spec.increment()[0];
2255 2 : Vector<Double> chanFreq(nchan_p),resolution(nchan_p);
2256 6 : for (Int i=0; i < nchan_p; ++i) {
2257 4 : spec.toWorld(chanFreq[i], Double(i));
2258 : }
2259 2 : resolution=chanBandWidth;
2260 2 : msSpW.chanFreq().put(0,chanFreq);
2261 2 : msSpW.chanWidth().put(0,resolution);
2262 2 : msSpW.effectiveBW().put(0,resolution);
2263 2 : msSpW.refFrequency().put(0,refFreq);
2264 2 : msSpW.resolution().put(0,resolution);
2265 2 : msSpW.totalBandwidth().put(0,abs(nchan_p*chanBandWidth));
2266 2 : msSpW.netSideband().put(0,1);
2267 2 : msSpW.freqGroup().put(0,0);
2268 2 : msSpW.freqGroupName().put(0,"none");
2269 2 : msSpW.flagRow().put(0,false);
2270 2 : msSpW.measFreqRef().put(0,MFrequency::LSRK);
2271 2 : }
2272 : //Now the DD
2273 : {
2274 2 : MSDataDescColumns msDD(outMsPtr_p->dataDescription());
2275 2 : if(outMsPtr_p->dataDescription().nrow()==0)
2276 2 : outMsPtr_p->dataDescription().addRow();
2277 2 : msDD.spectralWindowId().put(0,0);
2278 2 : msDD.polarizationId().put(0,0);
2279 2 : msDD.flagRow().put(0,false);
2280 2 : }
2281 2 : MSColumns(*outMsPtr_p).dataDescId().fillColumn(0);
2282 :
2283 :
2284 2 : }
2285 12 : void MSUVBin::copySubtable(const String& tabName, const Table& inTab,const Bool norows)
2286 : {
2287 : //outMsPtr_p->closeSubTables();
2288 12 : String outName(outMsPtr_p->tableName() + '/' + tabName);
2289 :
2290 12 : if (PlainTable::tableCache()(outName)){
2291 : //cerr << "cpy subtable "<< outName << endl;
2292 12 : Table outTab(outName, Table::Update);
2293 12 : if(norows){
2294 6 : Vector<rownr_t> rownums=outTab.rowNumbers();
2295 6 : outTab.removeRow(rownums);
2296 6 : }
2297 : else{
2298 6 : TableCopy::copySubTables(outTab, inTab);
2299 6 : TableCopy::copyInfo(outTab, inTab);
2300 : //cerr << "ROWS "<< inTab.nrow() << " " << outTab.nrow() << endl;
2301 6 : TableCopy::copyRows(outTab, inTab);
2302 : /*outTab=Table();
2303 : cerr << "copying " << tabName << endl;
2304 : inTab.copy(outName, Table::New);
2305 : */
2306 : }
2307 12 : }
2308 : else{
2309 0 : inTab.deepCopy(outName, Table::New, false, Table::AipsrcEndian, norows);
2310 : }
2311 12 : Table outTab(outName, Table::Update);
2312 12 : outMsPtr_p->rwKeywordSet().defineTable(tabName, outTab);
2313 12 : outMsPtr_p->initRefs();
2314 :
2315 24 : return;
2316 12 : }
2317 :
2318 2 : void MSUVBin::fillFieldTable() {
2319 2 : MSFieldColumns msField(outMsPtr_p->field());
2320 :
2321 2 : if(outMsPtr_p->field().nrow()==0)
2322 2 : outMsPtr_p->field().addRow();
2323 :
2324 2 : msField.sourceId().put(0, 0);
2325 2 : msField.code().put(0, "");
2326 2 : String sourceName="MSUVBIN";
2327 2 : Int fieldId=MSColumns(*mss_p[0]).fieldId()(0);
2328 :
2329 2 : sourceName=MSFieldColumns((mss_p[0])->field()).name()(fieldId);
2330 2 : msField.name().put(0, sourceName);
2331 2 : Int numPoly = 0;
2332 :
2333 : //
2334 2 : Vector<MDirection> radecMeas(1);
2335 2 : radecMeas(0)=phaseCenter_p;
2336 :
2337 2 : Double obsTime=MSColumns(*mss_p[0]).time()(0);
2338 2 : msField.time().put(0, obsTime);
2339 2 : msField.numPoly().put(0, numPoly);
2340 2 : msField.delayDirMeasCol().put(0, radecMeas);
2341 2 : msField.phaseDirMeasCol().put(0, radecMeas);
2342 2 : msField.referenceDirMeasCol().put(0, radecMeas);
2343 2 : msField.flagRow().put(0, false);
2344 2 : MSColumns(*outMsPtr_p).fieldId().fillColumn(0);
2345 2 : }
2346 :
2347 0 : Bool MSUVBin::String2MDirection(const String& theString,
2348 : MDirection& theMeas, const String msname){
2349 :
2350 0 : istringstream istr(theString);
2351 : Int fieldid;
2352 0 : istr >> fieldid;
2353 0 : if(!istr.fail() && msname != ""){
2354 : //We'll interprete string as a field id of ms
2355 0 : MeasurementSet thems(msname);
2356 0 : theMeas=MSFieldColumns(thems.field()).phaseDirMeas(fieldid);
2357 0 : return true;
2358 0 : }
2359 :
2360 :
2361 0 : QuantumHolder qh;
2362 0 : String error;
2363 :
2364 0 : Vector<String> str;
2365 : //In case of compound strings with commas or empty space
2366 0 : sepCommaEmptyToVectorStrings(str, theString);
2367 :
2368 0 : if(str.nelements()==3){
2369 0 : qh.fromString(error, str[1]);
2370 0 : casacore::Quantity val1=qh.asQuantity();
2371 0 : qh.fromString(error, str[2]);
2372 0 : casacore::Quantity val2=qh.asQuantity();
2373 : MDirection::Types tp;
2374 0 : if(!MDirection::getType(tp, str[0])){
2375 0 : ostringstream oss;
2376 0 : oss << "Could not understand Direction frame...defaulting to J2000 " ;
2377 0 : cerr << oss.str() << endl;
2378 0 : tp=MDirection::J2000;
2379 0 : }
2380 0 : theMeas=MDirection(val1,val2, tp);
2381 0 : return true;
2382 0 : }
2383 0 : else if(str.nelements()==2){
2384 0 : qh.fromString(error, str[0]);
2385 0 : casacore::Quantity val1=qh.asQuantity();
2386 0 : qh.fromString(error, str[1]);
2387 0 : casacore::Quantity val2=qh.asQuantity();
2388 0 : theMeas=MDirection(val1, val2);
2389 0 : return true;
2390 0 : }
2391 0 : else if(str.nelements()==1){
2392 : //Must be a string like sun, moon, jupiter
2393 0 : casacore::Quantity val1(0.0, "deg");
2394 0 : casacore::Quantity val2(90.0, "deg");
2395 0 : theMeas=MDirection(val1, val2);
2396 : MDirection::Types ref;
2397 : Int numAll;
2398 : Int numExtra;
2399 : const uInt *dum;
2400 0 : const String *allTypes=MDirection::allMyTypes(numAll, numExtra, dum);
2401 : //if it is SUN moon etc
2402 0 : if(MDirection::getType(ref,str[0])){
2403 :
2404 0 : theMeas=MDirection(val1, val2, ref);
2405 0 : return true;
2406 : }
2407 0 : if(MeasTable::Source(theMeas, str[0])){
2408 0 : return true;
2409 : }
2410 0 : if(!MDirection::getType(ref, str[0])){
2411 0 : Vector<String> all(numExtra);
2412 0 : for(Int k =0; k < numExtra; ++k){
2413 0 : all[k]=*(allTypes+numAll-k-1);
2414 : }
2415 0 : ostringstream oss;
2416 0 : oss << "Could not understand Direction string " <<str[0] << "\n" ;
2417 0 : oss << "Valid ones are " << all;
2418 0 : cerr << oss.str() << " or one of the valid known sources in the data repos" << endl;
2419 0 : theMeas=MDirection(val1, val2);
2420 0 : return false;
2421 0 : }
2422 :
2423 0 : }
2424 :
2425 :
2426 :
2427 :
2428 : ///If i am here i don't know how to interprete this
2429 :
2430 :
2431 0 : return false;
2432 0 : }
2433 :
2434 :
2435 0 : void MSUVBin::makeSFConv(Cube<Complex>& convFunc, Vector<Int>& convSupport, Double& wScale, Int& convSampling, Int& convSize){
2436 0 : Vector<Double> uvOffset(2);
2437 0 : uvOffset(0)=Double(nx_p)/2.0;
2438 0 : uvOffset(1)=Double(ny_p)/2.0;
2439 0 : Vector<Double> uvScale(2);
2440 : //cerr << "increments " << csys_p.increment() << endl;
2441 0 : uvScale(0)=fabs(nx_p*csys_p.increment()(0));
2442 0 : uvScale(1)=fabs(ny_p*csys_p.increment()(1));
2443 : /////no w
2444 0 : wScale=0.0;
2445 :
2446 : ConvolveGridder<Double, Complex>
2447 0 : gridder(IPosition(2, nx_p, ny_p), uvScale, uvOffset, "SF");
2448 0 : convSupport.resize(1);
2449 0 : convSupport=gridder.cSupport()(0);
2450 0 : convSize=convSupport(0);
2451 0 : convSampling=gridder.cSampling();
2452 : //cerr << " support " << gridder.cSupport() << " sampling " << convSampling << endl;
2453 :
2454 0 : Vector<Double> cfunc1D=gridder.cFunction();
2455 :
2456 : //cerr << "convFunc " << cfunc1D << endl;
2457 0 : convFunc.resize(convSampling*convSupport(0), convSampling*convSupport(0), 1);
2458 0 : convFunc.set(Complex(0.0));
2459 0 : for (Int k=0; k < convSampling*convSupport(0); ++k){
2460 0 : for (int j=0; j < convSampling*convSupport(0); ++j){
2461 0 : convFunc(j, k,0)=Complex(cfunc1D(k)*cfunc1D(j));
2462 : }
2463 : }
2464 :
2465 0 : }
2466 :
2467 0 : void MSUVBin::makeWConv(vi::VisibilityIterator2& iter, Cube<Complex>& convFunc, Vector<Int>& convSupport,
2468 : Double& wScale, Int& convSampling, Int& convSize){
2469 : ///////Let's find ... the maximum w
2470 0 : vi::VisBuffer2 *vb=iter.getVisBuffer();
2471 0 : Double maxW=0.0;
2472 0 : Double minW=1e99;
2473 0 : Double nval=0;
2474 0 : Double rmsW=0.0;
2475 0 : for (iter.originChunks(); iter.moreChunks(); iter.nextChunk()) {
2476 0 : for (iter.origin(); iter.more(); iter.next()) {
2477 0 : maxW=max(maxW, max(abs(vb->uvw().row(2)*max(vb->getFrequencies(0))))/C::c);
2478 0 : minW=min(minW, min(abs(vb->uvw().row(2)*min(vb->getFrequencies(0))))/C::c);
2479 : ///////////some shenanigans as some compilers is confusing * operator for vector
2480 0 : Vector<Double> elw;
2481 0 : elw=vb->uvw().row(2);
2482 0 : elw*=vb->uvw().row(2);
2483 : //////////////////////////////////////////////////
2484 0 : rmsW+=sum(elw);
2485 :
2486 0 : nval+=Double(vb->nRows());
2487 0 : }
2488 : }
2489 0 : rmsW=sqrt(rmsW/Double(nval))*max(vb->getFrequencies(0))/C::c;
2490 0 : Double maxUVW=rmsW < 0.5*(minW+maxW) ? 1.05*maxW: (rmsW /(0.5*((minW)+maxW))*1.05*maxW) ;
2491 : //Int wConvSize=Int(maxUVW*fabs(sin(fabs(csys_p.increment()(0))*max(nx_p, ny_p)/2.0)));
2492 : //////////TEST
2493 0 : Int wConvSize=2*Int(maxUVW*fabs(sin(fabs(csys_p.increment()(0))*max(nx_p, ny_p)/2.0)));
2494 : /////////////////
2495 0 : wScale=Double((wConvSize-1)*(wConvSize-1))/maxUVW;
2496 0 : if(wConvSize <2)
2497 0 : ThrowCc("Should not be using wprojection");
2498 0 : Int maxMemoryMB=HostInfo::memoryTotal(true)/1024;
2499 0 : Double maxConvSizeConsidered=sqrt(Double(maxMemoryMB)/8.0*1024.0*1024.0/Double(wConvSize));
2500 0 : CompositeNumber cn(Int(maxConvSizeConsidered/2.0)*2);
2501 : //cerr << "max ConvSize considered " << maxConvSizeConsidered << endl;
2502 0 : convSampling=10;
2503 0 : convSize=max(nx_p, ny_p);
2504 0 : convSize=min(convSize,(Int)cn.nearestEven(Int(maxConvSizeConsidered/2.0)*2));
2505 0 : Int maxConvSize=convSize;
2506 0 : CoordinateSystem coords=csys_p;
2507 0 : DirectionCoordinate dc=coords.directionCoordinate(0);
2508 0 : Vector<Double> sampling;
2509 0 : sampling = dc.increment();
2510 0 : sampling*=Double(convSampling);
2511 0 : sampling[0]*=Double(cn.nextLargerEven(Int(Float(nx_p)-0.5)))/Double(convSize);
2512 0 : sampling[1]*=Double(cn.nextLargerEven(Int(Float(ny_p)-0.5)))/Double(convSize);
2513 0 : dc.setIncrement(sampling);
2514 0 : Vector<Double> unitVec(2);
2515 0 : unitVec=convSize/2;
2516 0 : dc.setReferencePixel(unitVec);
2517 :
2518 : // Set the reference value to that of the image center for sure.
2519 : {
2520 : // dc.setReferenceValue(mTangent_p.getAngle().getValue());
2521 0 : MDirection wcenter;
2522 0 : Vector<Double> pcenter(2);
2523 0 : pcenter(0) = nx_p/2;
2524 0 : pcenter(1) = ny_p/2;
2525 0 : coords.directionCoordinate(0).toWorld( wcenter, pcenter );
2526 0 : dc.setReferenceValue(wcenter.getAngle().getValue());
2527 0 : }
2528 0 : coords.replaceCoordinate(dc, 0);
2529 0 : IPosition pbShape(4, convSize, convSize, 1, 1);
2530 0 : TempImage<Complex> twoDPB(pbShape, coords);
2531 0 : convFunc.resize(); // break any reference
2532 0 : convFunc.resize(convSize/2-1, convSize/2-1, wConvSize);
2533 0 : convFunc.set(0.0);
2534 0 : Bool convFuncStor=false;
2535 0 : Complex *convFuncPtr=convFunc.getStorage(convFuncStor);
2536 0 : IPosition start(4, 0, 0, 0, 0);
2537 0 : IPosition pbSlice(4, convSize, convSize, 1, 1);
2538 0 : Vector<Complex> maxes(wConvSize);
2539 : Bool maxdel;
2540 0 : Complex* maxptr=maxes.getStorage(maxdel);
2541 0 : Int inner=convSize/convSampling;
2542 : //cerr << "inner " << inner << endl;
2543 0 : Matrix<Complex> corr(inner, inner);
2544 :
2545 0 : Vector<Double> uvOffset(2);
2546 0 : uvOffset(0)=Double(nx_p)/2.0;
2547 0 : uvOffset(1)=Double(ny_p)/2.0;
2548 0 : Vector<Double> uvScale(2);
2549 0 : Vector<Complex> correction(inner);
2550 : //cerr << "increments " << csys_p.increment() << endl;
2551 0 : uvScale(0)=fabs(nx_p*csys_p.increment()(0));
2552 0 : uvScale(1)=fabs(ny_p*csys_p.increment()(1));
2553 :
2554 :
2555 : ConvolveGridder<Double, Complex>
2556 :
2557 0 : ggridder(IPosition(2, inner, inner), uvScale, uvOffset, "SF");
2558 : /////////////////////////////////////////////////////////
2559 : /////////////Testing
2560 : /*correction.resize(2*inner);
2561 : uvScale *=2.0;
2562 : uvOffset *=2.0;
2563 : ConvolveGridder<Double, Complex>
2564 : ggridder(IPosition(2, 2*inner, 2*inner), uvScale, uvOffset, "SF");
2565 : for (Int iy=-inner/2;iy<inner/2;iy++) {
2566 :
2567 : ggridder.correctX1D(correction, iy+inner);
2568 : corr.row(iy+inner/2)=correction(Slice(inner/2, inner));
2569 : }
2570 : */
2571 : /////////////////////////////////
2572 : //////////////////////////////////////////
2573 :
2574 0 : for (Int iy=-inner/2;iy<inner/2;iy++) {
2575 :
2576 0 : ggridder.correctX1D(correction, iy+inner/2);
2577 0 : corr.row(iy+inner/2)=correction;
2578 : }
2579 :
2580 :
2581 : Bool cpcor;
2582 0 : Complex *cor=corr.getStorage(cpcor);
2583 0 : Double s1=sampling(1);
2584 0 : Double s0=sampling(0);
2585 : ///////////Por FFTPack
2586 0 : Vector<Float> wsave(2*convSize*convSize+15);
2587 0 : Int lsav=2*convSize*convSize+15;
2588 : Bool wsavesave;
2589 0 : Float *wsaveptr=wsave.getStorage(wsavesave);
2590 : Int ier;
2591 0 : FFTPack::cfft2i(convSize, convSize, wsaveptr, lsav, ier);
2592 : //////////
2593 : #ifdef _OPENMP
2594 0 : omp_set_nested(0);
2595 : #endif
2596 : //////openmp like to share reference param ...making a copy to reduce shared objects
2597 0 : Int cpConvSize=convSize;
2598 0 : Int cpWConvSize=wConvSize;
2599 0 : Double cpWscale=wScale;
2600 0 : Int cpConvSamp=convSampling;
2601 :
2602 : ///////////////
2603 :
2604 0 : convSupport.resize(wConvSize);
2605 0 : convSupport=-1;
2606 0 : Vector<Int> pcsupp;
2607 0 : pcsupp=convSupport;
2608 : Bool delsupstor;
2609 0 : Int* suppstor=pcsupp.getStorage(delsupstor);
2610 : ////////////
2611 :
2612 : //Float max0=1.0;
2613 0 : #pragma omp parallel for default(none) firstprivate(cpWConvSize, cpConvSize, convFuncPtr, s0, s1, wsaveptr, ier, lsav, maxptr, cpWscale,inner, cor, maxConvSize, cpConvSamp, suppstor )
2614 :
2615 : for (Int iw=0; iw< cpWConvSize;iw++) {
2616 : // First the w term
2617 : Matrix<Complex> screen(cpConvSize, cpConvSize);
2618 : Matrix<Complex> screen2(cpConvSize, cpConvSize);
2619 : screen=0.0;
2620 : screen2=0.0;
2621 : Bool cpscr;
2622 : Bool cpscr2;
2623 : Complex *scr=screen.getStorage(cpscr);
2624 : Complex *scr2=screen2.getStorage(cpscr2);
2625 : Double twoPiW=2.0*M_PI*Double(iw*iw)/cpWscale;
2626 : for (Int iy=-inner/2;iy<inner/2;iy++) {
2627 : Double m=s1*Double(iy);
2628 : Double msq=m*m;
2629 : //////Int offset= (iy+convSize/2)*convSize;
2630 : ///fftpack likes it flipped
2631 : ooLong offset= (iy>-1 ? iy : ooLong(iy+cpConvSize))*ooLong(cpConvSize);
2632 : for (Int ix=-inner/2;ix<inner/2;ix++) {
2633 : ////// Int ind=offset+ix+convSize/2;
2634 : ///fftpack likes it flipped
2635 : ooLong ind=offset+(ix > -1 ? ooLong(ix) : ooLong(ix+cpConvSize));
2636 : Double l=s0*Double(ix);
2637 : Double rsq=l*l+msq;
2638 : if(rsq<1.0) {
2639 : Double phase=twoPiW*(sqrt(1.0-rsq)-1.0);
2640 : Double cval, sval;
2641 : SINCOS(phase, sval, cval);
2642 :
2643 : Complex comval(cval, sval);
2644 : scr2[ind]=(cor[ooLong(ix+inner/2)+ ooLong((iy+inner/2))*ooLong(inner)])*comval;
2645 : scr[ind]=comval;
2646 :
2647 : }
2648 : }
2649 :
2650 : }
2651 : // Now FFT and get the result back
2652 : /////////Por FFTPack
2653 : Vector<Float>work(2*cpConvSize*cpConvSize);
2654 : Int lenwrk=2*cpConvSize*cpConvSize;
2655 : Bool worksave;
2656 : Float *workptr=work.getStorage(worksave);
2657 : FFTPack::cfft2f(cpConvSize, cpConvSize, cpConvSize, scr, wsaveptr, lsav, workptr, lenwrk, ier);
2658 : FFTPack::cfft2f(cpConvSize, cpConvSize, cpConvSize, scr2, wsaveptr, lsav, workptr, lenwrk, ier);
2659 : screen.putStorage(scr, cpscr);
2660 : screen2.putStorage(scr2, cpscr2);
2661 : ooLong offset=uInt(iw*(cpConvSize/2-1)*(cpConvSize/2-1));
2662 : maxptr[iw]=screen(0,0);
2663 : for (uInt y=0; y< uInt(cpConvSize/2)-1; ++y){
2664 : for (uInt x=0; x< uInt(cpConvSize/2)-1; ++x){
2665 : convFuncPtr[offset+ooLong(y*(cpConvSize/2-1))+ooLong(x)] = screen(x,y);
2666 : }
2667 : }
2668 : /* Bool found=false;
2669 : Int trial=0;
2670 : for (trial=0; trial<cpConvSize/2-2;++trial) {
2671 : // if((abs(convFunc(trial,0,iw))>1e-3)||(abs(convFunc(0,trial,iw))>1e-3) ) {
2672 : if((abs(screen(trial,0))<1e-3)||(abs(screen(0,trial))<1e-3) ) {
2673 : //cout <<"iw " << iw << " x " << abs(convFunc(trial,0,iw)) << " y "
2674 : // <<abs(convFunc(0,trial,iw)) << endl;
2675 : found=true;
2676 : break;
2677 : }
2678 : }
2679 : if(found) {
2680 : suppstor[iw]=Int(0.5+Float(trial)/Float(cpConvSamp))+1;
2681 : if(suppstor[iw]*cpConvSamp*2 >= maxConvSize){
2682 : suppstor[iw]=cpConvSize/2/cpConvSamp-1;
2683 : }
2684 : }
2685 : */
2686 : }
2687 :
2688 :
2689 : #ifdef _OPENMP
2690 0 : omp_set_nested(0);
2691 : #endif
2692 :
2693 : /* convFunc.putStorage(convFuncPtr, convFuncStor);
2694 : maxes.putStorage(maxptr, maxdel);
2695 : Complex maxconv=max(abs(maxes));
2696 : convFunc=convFunc/real(maxconv);
2697 : convFuncPtr=convFunc.getStorage(convFuncStor);
2698 : */
2699 :
2700 0 : #pragma omp parallel for default(none) firstprivate(suppstor, cpConvSize, cpWConvSize, cpConvSamp, convFuncPtr, maxConvSize, maxes)
2701 : for (Int iw=0;iw<cpWConvSize;iw++) {
2702 : Bool found=false;
2703 : Int trial=0;
2704 : ooLong ploffset=ooLong(cpConvSize/2-1)*ooLong(cpConvSize/2-1)*ooLong(iw);
2705 : ////////////////
2706 : // for (trial=cpConvSize/2-2;trial>0;trial--) {
2707 : // // if((abs(convFunc(trial,0,iw))>1e-3)||(abs(convFunc(0,trial,iw))>1e-3) ) {
2708 : // if((abs(convFuncPtr[trial+ploffset])>1e-2)||(abs(convFuncPtr[trial*(cpConvSize/2-1)+ploffset])>1e-2) ) {
2709 : // //cout <<"iw " << iw << " x " << abs(convFunc(trial,0,iw)) << " y "
2710 : // // <<abs(convFunc(0,trial,iw)) << endl;
2711 : // found=true;
2712 : // break;
2713 : // }
2714 : // }
2715 : ///////////////////////
2716 :
2717 : for (trial=0; trial<cpConvSize/2-2;++trial) {
2718 : //for (trial=cpConvSize/2-2;trial>0;trial--) {
2719 : // if((abs(convFunc(trial,0,iw))>1e-3)||(abs(convFunc(0,trial,iw))>1e-3) ) {
2720 : if((abs(convFuncPtr[ooLong(trial)+ploffset])/abs(maxes[0])< 1e-3)||(abs(convFuncPtr[ooLong(trial*(cpConvSize/2-1))+ploffset])/abs(maxes[0]) < 1e-3) ) {
2721 : //if((abs(convFuncPtr[ooLong(trial)+ploffset]) < 1e-3)||(abs(convFuncPtr[ooLong(trial*(cpConvSize/2-1))+ploffset]) < 1e-3) ) {
2722 : //if(abs(convFuncPtr[ooLong(trial)+ploffset])*abs(convFuncPtr[ooLong(trial*(cpConvSize/2-1))+ploffset]) < 1e-3){
2723 : ///diagonal
2724 : //if(abs(convFuncPtr[ooLong((Double(trial)/sqrt(2.0))*(cpConvSize/2-1))+ploffset+ooLong((Double(trial)/sqrt(2.0)))]) < 1e-4){
2725 : //cout <<"iw " << iw << " x " << abs(convFunc(trial,0,iw)) << " y "
2726 : // <<abs(convFunc(0,trial,iw)) << endl;
2727 : found=true;
2728 : break;
2729 : }
2730 : }
2731 :
2732 : if(found) {
2733 : suppstor[iw]=Int(0.5+Float(trial)/Float(cpConvSamp))+1;
2734 : }
2735 : else{
2736 : suppstor[iw]=Int(0.5+Float(cpConvSize/2-2)/Float(cpConvSamp))+1;
2737 : }
2738 : if(suppstor[iw]*cpConvSamp*2 >= maxConvSize){
2739 : suppstor[iw]=cpConvSize/2/cpConvSamp-1;
2740 :
2741 : }
2742 : }
2743 :
2744 :
2745 :
2746 0 : convFunc.putStorage(convFuncPtr, convFuncStor);
2747 : /* maxes.putStorage(maxptr, maxdel);
2748 : Complex maxconv=max(abs(maxes));
2749 : convFunc=convFunc/real(maxconv);
2750 : */
2751 0 : pcsupp.putStorage(suppstor, delsupstor);
2752 0 : convSupport=pcsupp;
2753 : ////////////TESTING
2754 :
2755 : //cerr<< " convsupp " << convSupport << endl;
2756 :
2757 : //convSupport.set(0);
2758 : /////////////////
2759 :
2760 :
2761 : // Normalize such that plane 0 sums to 1 (when jumping in
2762 : // steps of convSampling)
2763 0 : Complex pbSum=0.0;
2764 0 : Int iz=0;
2765 : //for (Int iz=0; iz< convSupport.shape()[0]; ++iz){
2766 0 : pbSum=0.0;
2767 :
2768 0 : for (Int iy=-convSupport(iz);iy<=convSupport(iz);iy++) {
2769 0 : for (Int ix=-convSupport(iz);ix<=convSupport(iz);ix++) {
2770 0 : pbSum+=real(convFunc(abs(ix)*cpConvSamp,abs(iy)*cpConvSamp,iz));
2771 : }
2772 : }
2773 : //convFunc.xyPlane(iz) = convFunc.xyPlane(iz)/Complex(pbSum);
2774 : // }
2775 : //cerr << "pbSum " << pbSum << endl;
2776 0 : for (Int iz2=0; iz2< convSupport.shape()[0]; ++iz2){
2777 0 : convFunc.xyPlane(iz2)= convFunc.xyPlane(iz2)/pbSum;
2778 :
2779 : }
2780 0 : Int newConvSize=2*(max(convSupport)+2)*convSampling;
2781 :
2782 0 : if(newConvSize < convSize){
2783 0 : IPosition blc(3, 0,0,0);
2784 0 : IPosition trc(3, (newConvSize/2-2),
2785 0 : (newConvSize/2-2),
2786 0 : convSupport.shape()(0)-1);
2787 :
2788 0 : Cube<Complex> newConvFunc=convFunc(blc,trc);
2789 0 : convFunc.resize();
2790 0 : convFunc=newConvFunc;
2791 : // convFunctions_p[actualConvIndex_p]->assign(Cube<Complex>(convFunc(blc,trc)));
2792 0 : convSize=newConvSize;
2793 : //cerr << "new convsize " << convSize << endl;
2794 0 : }
2795 :
2796 :
2797 : //////////////////////TESTING
2798 : //convFunc*=Complex(1.0/5.4, 0.0);
2799 :
2800 : ////////////////////////////
2801 : //// if(pbSum>0.0) {
2802 : //// convFunc*=Complex(1.0/pbSum,0.0);
2803 : //// }
2804 : /// else {
2805 : /// cerr << "Convolution function integral is not positive"
2806 : /// << endl;
2807 : /// }
2808 : /////////////TEST
2809 :
2810 : /* Int maxConvSupp=max(convSupport)+1;
2811 : for (Int iw=1;iw<cpWConvSize; ++iw) {
2812 : Float maxplane=max(amplitude(convFunc.xyPlane(iw)));
2813 : for (Int iy=0; iy< maxConvSupp*cpConvSamp; ++iy){
2814 : for (Int ix=0; ix< maxConvSupp*cpConvSamp; ++ix){
2815 : convFunc(ix, iy, iw) /=maxplane;
2816 : }
2817 : }
2818 : }
2819 : */
2820 : /////////////////////////
2821 : /////Write out the SF correction image
2822 : /*String corrim=outMSName_p+String("/WprojCorrection.image");
2823 : Path elpath(corrim);
2824 : cerr << "Saving the correction image " << elpath.absoluteName() << "\nIt should be used to restore images to a flat noise state " << endl;
2825 : if(!Table::isReadable(corrim)){
2826 : ConvolveGridder<Double, Float>elgridder(IPosition(2, nx_p, ny_p),
2827 : uvScale, uvOffset,
2828 : "SF");
2829 : CoordinateSystem newcoord=csys_p;
2830 : StokesCoordinate st(Vector<Int>(1, Stokes::I));
2831 : newcoord.replaceCoordinate(st, 1);
2832 : PagedImage<Float> thisScreen(IPosition(4, nx_p, ny_p, 1, 1), newcoord, corrim);
2833 : thisScreen.set(0.0);
2834 : Vector<Float> correction(nx_p);
2835 : correction=1.0;
2836 :
2837 : Int npixCorr= max(nx_p,ny_p);
2838 : Vector<Float> sincConv(npixCorr);
2839 : for (Int ix=0;ix<npixCorr;ix++) {
2840 : Float x=M_PI*Float(ix-npixCorr/2)/(Float(npixCorr)*Float(convSampling));
2841 : if(ix==npixCorr/2) {
2842 : sincConv(ix)=1.0;
2843 : }
2844 : else {
2845 : sincConv(ix)=sin(x)/x;
2846 : }
2847 : }
2848 : IPosition cursorShape(4, nx_p, 1, 1, 1);
2849 : IPosition axisPath(4, 0, 1, 2, 3);
2850 : LatticeStepper lsx(thisScreen.shape(), cursorShape, axisPath);
2851 : LatticeIterator<Float> lix(thisScreen, lsx);
2852 : for(lix.reset();!lix.atEnd();lix++) {
2853 : Int iy=lix.position()(1);
2854 : elgridder.correctX1D(correction, iy);
2855 :
2856 : for (Int ix=0;ix<nx_p; ++ix) {
2857 : //correction(ix)=sincConv(ix)*sincConv(iy);
2858 : correction(ix)*=sincConv(ix)*sincConv(iy);
2859 : }
2860 : lix.rwVectorCursor()=correction;
2861 : }
2862 : }
2863 :
2864 : */
2865 : // Write out FT of screen as an image
2866 : /* if(1) {
2867 : CoordinateSystem ftCoords(coords);
2868 : Int directionIndex=ftCoords.findCoordinate(Coordinate::DIRECTION);
2869 : AlwaysAssert(directionIndex>=0, AipsError);
2870 : dc=coords.directionCoordinate(directionIndex);
2871 : Vector<Bool> axes(2); axes(0)=true;axes(1)=true;
2872 : Vector<Int> shape(2); shape(0)=convSize;shape(1)=convSize;
2873 : Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape);
2874 : ftCoords.replaceCoordinate(*ftdc, directionIndex);
2875 : delete ftdc; ftdc=0;
2876 : ostringstream name;
2877 : name << "FTScreen" ;
2878 : if(Table::canDeleteTable(name)) Table::deleteTable(name);
2879 : PagedImage<Complex> thisScreen(IPosition(4, convFunc.shape()(0), convFunc.shape()(1), 1, convFunc.shape()(2)), ftCoords, name);
2880 : thisScreen.put(convFunc.reform(IPosition(4, convFunc.shape()(0), convFunc.shape()(1), 1, convFunc.shape()(2))));
2881 : if(Table::canDeleteTable("CORR2")) Table::deleteTable("CORR2");
2882 : PagedImage<Complex> thisScreen2(IPosition(4, corr.shape()(0), corr.shape()(1), 1, 1), ftCoords, "CORR2");
2883 : thisScreen2.put(corr.reform(IPosition(4, corr.shape()(0), corr.shape()(1), 1, 1)));
2884 :
2885 : //LatticeExpr<Float> le(real(twoDPB));
2886 : //thisScreen.copyData(le);
2887 : //thisScreen.put(real(screen));
2888 : }
2889 : */
2890 :
2891 :
2892 0 : }
2893 :
2894 0 : Int MSUVBin::sepCommaEmptyToVectorStrings(Vector<String>& lesStrings,
2895 : const String& str){
2896 :
2897 0 : String oneStr=str;
2898 0 : Int nsep=0;
2899 : // decide if its comma seperated or empty space seperated
2900 0 : casacore::String sep;
2901 0 : if((nsep=oneStr.freq(",")) > 0){
2902 0 : sep=",";
2903 : }
2904 : else {
2905 0 : nsep=oneStr.freq(" ");
2906 0 : sep=" ";
2907 : }
2908 0 : if(nsep == 0){
2909 0 : lesStrings.resize(1);
2910 0 : lesStrings=oneStr;
2911 0 : nsep=1;
2912 : }
2913 : else{
2914 0 : String *splitstrings = new String[nsep+1];
2915 0 : nsep=split(oneStr, splitstrings, nsep+1, sep);
2916 0 : lesStrings.resize(nsep);
2917 0 : Int index=0;
2918 0 : for (Int k=0; k < nsep; ++k){
2919 0 : if((String(splitstrings[k]) == String(""))
2920 0 : || (String(splitstrings[k]) == String(" "))){
2921 0 : lesStrings.resize(lesStrings.nelements()-1, true);
2922 : }
2923 : else{
2924 0 : lesStrings[index]=splitstrings[k];
2925 0 : ++index;
2926 : }
2927 : }
2928 0 : delete [] splitstrings;
2929 : }
2930 :
2931 0 : return nsep;
2932 :
2933 0 : }
2934 :
2935 :
2936 :
2937 : } //# NAMESPACE CASA - END
2938 :
|