Line data Source code
1 : #include <synthesis/Utilities/FixVis.h>
2 : #include <msvis/MSVis/MSUVWGenerator.h>
3 : #include <msvis/MSVis/SubMS.h>
4 : #include <casacore/measures/Measures/MeasTable.h>
5 : #include <casacore/measures/Measures/UVWMachine.h>
6 : #include <casacore/casa/Logging/LogIO.h>
7 : #include <casacore/casa/Exceptions/Error.h>
8 : #include <casacore/casa/Quanta/MVAngle.h>
9 : #include <casacore/coordinates/Coordinates/Projection.h>
10 : #include <casacore/coordinates/Coordinates/DirectionCoordinate.h>
11 : #include <casacore/coordinates/Coordinates/ObsInfo.h>
12 : #include <casacore/images/Images/PagedImage.h> // Used to pass coords
13 : #include <casacore/images/Images/ImageInfo.h> // to FTMachine.
14 : #include <casacore/ms/MeasurementSets/MSColumns.h>
15 : #include <casacore/ms/MeasurementSets/MSDopplerUtil.h>
16 : #include <casacore/ms/MSSel/MSSelection.h>
17 : #include <casacore/ms/MSSel/MSSelectionTools.h>
18 : #include <msvis/MSVis/VisibilityIterator.h>
19 : #include <msvis/MSVis/VisBuffer.h>
20 : #include <casacore/casa/BasicSL/String.h> // for parseColumnNames()
21 :
22 : #include <iostream>
23 :
24 : using namespace casacore;
25 : namespace casa {
26 :
27 0 : FixVis::FixVis(MeasurementSet& ms, const String& dataColName) :
28 : FTMachine(),
29 : ms_p(ms),
30 : msc_p(NULL),
31 : nsel_p(0),
32 : nAllFields_p(1),
33 : npix_p(2),
34 0 : cimageShape_p(4, npix_p, npix_p, 1, 1), // Can we get away with
35 0 : tileShape_p(4, npix_p, npix_p, 1, 1), // (1, 1, 1, 1)? Does it matter?
36 0 : tiledShape_p(cimageShape_p, tileShape_p),
37 : antennaSel_p(false),
38 0 : freqFrameValid_p(false)
39 : // obsString_p("")
40 : {
41 0 : logSink() << LogOrigin("FixVis", "") << LogIO::NORMAL3;
42 :
43 0 : antennaId_p.resize();
44 0 : antennaSelStr_p.resize();
45 0 : distances_p.resize();
46 0 : dataCols_p = SubMS::parseColumnNames(dataColName, ms);
47 0 : nDataCols_p = dataCols_p.nelements();
48 :
49 0 : nchan_p = 1; // imageNchan_p;
50 :
51 0 : spectralwindowids_p.resize(ms_p.spectralWindow().nrow());
52 0 : indgen(spectralwindowids_p);
53 :
54 0 : lockCounter_p = 0;
55 0 : }
56 :
57 : // Destructor
58 0 : FixVis::~FixVis()
59 : {
60 0 : if(!ms_p.isNull())
61 0 : ms_p.flush();
62 :
63 0 : delete msc_p;
64 0 : }
65 :
66 : // Interpret field indices (MSSelection)
67 0 : Vector<Int> FixVis::getFieldIdx(const String& fields)
68 : {
69 0 : MSSelection mssel;
70 :
71 0 : mssel.setFieldExpr(fields);
72 0 : return mssel.getFieldList(&ms_p);
73 : }
74 :
75 0 : uInt FixVis::setFields(const Vector<Int>& fieldIds)
76 : {
77 0 : logSink() << LogOrigin("FixVis", "setFields");
78 0 : logSink() << LogIO::NORMAL << "Selecting fields ";
79 :
80 0 : nsel_p = fieldIds.nelements();
81 0 : nAllFields_p = ms_p.field().nrow();
82 0 : FieldIds_p.resize(nAllFields_p);
83 :
84 0 : for(Int i = 0; i < static_cast<Int>(nAllFields_p); ++i){
85 0 : FieldIds_p(i) = -1;
86 0 : for(uInt j = 0; j < nsel_p; ++j){
87 0 : if(fieldIds[j] == i){
88 0 : FieldIds_p(i) = i;
89 0 : logSink() << i << " " << LogIO::NORMAL;
90 0 : break;
91 : }
92 : }
93 : }
94 0 : logSink() << LogIO::POST;
95 :
96 0 : return nsel_p;
97 : }
98 :
99 0 : void FixVis::setPhaseDirs(const Vector<MDirection>& phaseDirs)
100 : {
101 0 : phaseDirs_p = phaseDirs;
102 :
103 : // Do a consistency check between fieldIds and FieldIds_p.
104 0 : logSink() << LogOrigin("FixVis", "setPhaseDirs");
105 0 : uInt n2change = phaseDirs.nelements();
106 0 : if(n2change != nsel_p){
107 : logSink() << LogIO::SEVERE
108 : << "Mismatch between the number of new directions and the fields to change"
109 0 : << LogIO::POST;
110 : }
111 0 : }
112 :
113 :
114 0 : void FixVis::convertFieldDirs(const MDirection::Types outType)
115 : {
116 0 : logSink() << LogOrigin("FixVis", "convertFieldDirs");
117 :
118 : // Note that the each direction column in the FIELD table only allows one
119 : // reference frame for the entire column, but polynomials can be assigned on
120 : // a row-wise basis for objects moving in that frame.
121 :
122 : Muvw::Types uvwtype;
123 0 : Muvw::getType(uvwtype, MDirection::showType(outType));
124 :
125 0 : ready_msc_p();
126 :
127 0 : msc_p->uvw().rwKeywordSet().asrwRecord("MEASINFO").define("Ref", MDirection::showType(outType));
128 :
129 0 : MSFieldColumns& msfcs = msc_p->field();
130 :
131 0 : MDirection pd0(msfcs.phaseDirMeas(0));
132 : logSink() << LogIO::DEBUG1
133 0 : << "PHASE_DIR[0] before = " << pd0.tellMe() << " ";
134 : {
135 0 : ostringstream os;
136 0 : os << *(pd0.getData()) << endl;
137 0 : logSink() << os.str() << LogIO::POST;
138 : }
139 :
140 : // There is no physical or known programming need to change the delay and
141 : // reference direction frames as well, but for aesthetic reasons we keep them
142 : // all in the same frame if they start in the same frame.
143 : //ArrayMeasColumn<MDirection> msDelayDirCol;
144 : //msDelayDirCol.reference(msfcs.delayDirMeasCol());
145 : //ArrayMeasColumn<MDirection> msReferenceDirCol;
146 : //msReferenceDirCol.reference(msfcs.referenceDirMeasCol());
147 0 : Bool doAll3 = (msfcs.phaseDirMeasCol().getMeasRef().getType() ==
148 0 : msfcs.delayDirMeasCol().getMeasRef().getType() &&
149 0 : msfcs.phaseDirMeasCol().getMeasRef().getType() ==
150 0 : msfcs.referenceDirMeasCol().getMeasRef().getType());
151 :
152 : // Setup conversion machines.
153 : // Set the frame - choose the first antenna. For e.g. VLBI, we
154 : // will need to reset the frame per antenna
155 0 : mLocation_p = msc_p->antenna().positionMeas()(0);
156 :
157 : // Expect problems if a moving object is involved!
158 0 : mFrame_p = MeasFrame(msfcs.timeMeas()(0), mLocation_p);
159 :
160 : //MDirection::Ref startref(msfcs.phaseDirMeasCol().getMeasRef());
161 : // If the either of the start or destination frames refers to a finite
162 : // distance, then the conversion has to be done in two steps:
163 : // MDirection::Convert start2app(msfcs.phaseDirMeasCol()(0), MDirection::APP);
164 : //
165 : // Otherwise the conversion can be done directly.
166 0 : Bool haveMovingFrame = (MDirection::castType(msfcs.phaseDirMeasCol().getMeasRef().getType()) > MDirection::N_Types ||
167 0 : outType > MDirection::N_Types);
168 :
169 : const MDirection::Ref newFrame(haveMovingFrame ? MDirection::APP : outType,
170 0 : mFrame_p);
171 :
172 0 : convertFieldCols(msfcs, newFrame, doAll3);
173 :
174 0 : if(haveMovingFrame){
175 : // Since ArrayMeasCol most likely uses one frame for the whole column, do
176 : // the second half of the conversion with a second pass through the column
177 : // instead of on a row-by-row basis.
178 : logSink() << LogIO::WARN
179 : << "Switching to or from accelerating frames is not well tested."
180 0 : << LogIO::POST;
181 :
182 : // Using msfcs.phaseDirMeasCol()(0)[0] to initialize converter will only
183 : // work if msfcs.phaseDirMeasCol()'s type has been set to APP.
184 0 : const MDirection::Ref newerFrame(outType, mFrame_p);
185 :
186 0 : convertFieldCols(msfcs, newerFrame, doAll3);
187 : }
188 :
189 0 : pd0 = msfcs.phaseDirMeas(0);
190 : logSink() << LogIO::DEBUG1
191 0 : << "PHASE_DIR[0] after = " << pd0.tellMe() << " ";
192 : {
193 0 : ostringstream os;
194 0 : os << *(pd0.getData()) << endl;
195 0 : logSink() << os.str() << LogIO::POST;
196 : }
197 0 : }
198 :
199 :
200 0 : void FixVis::convertFieldCols(MSFieldColumns& msfcs,
201 : const MDirection::Ref& newFrame,
202 : const Bool doAll3)
203 : {
204 0 : logSink() << LogOrigin("FixVis", "convertFieldCols");
205 : // Unfortunately ArrayMeasColumn::doConvert() is private, which moots the
206 : // point of making a conversion machine here.
207 : // Vector<MDirection> dummyV;
208 : // dummyV.assign(pdc(0));
209 : // MDirection::Convert *converter = new MDirection::Convert(dummyV[0],
210 : // newFrame);
211 : // if(!converter)
212 : // logSink() << "Cannot make direction conversion machine"
213 : // << LogIO::SEVERE;
214 :
215 0 : uInt nrows = msfcs.nrow();
216 :
217 : // Convert each phase tracking center. This will make them numerically
218 : // correct in the new frame, but the column will still be labelled with the
219 : // old frame.
220 :
221 : uInt nOrders;
222 0 : Vector<MDirection> mdarr; // direction for each order
223 0 : Array<Double> darr; // longitude and latitude for each order
224 0 : Vector<Double> dirV;
225 0 : for(uInt i = 0; i < nrows; ++i){
226 0 : nOrders = msfcs.numPoly()(i) + 1;
227 : logSink() << LogIO::DEBUG1 << "numPoly(" << i << ") = " << nOrders - 1
228 0 : << LogIO::POST;
229 :
230 : //pdc.put(i, pdc.doConvert(i, *converter));
231 0 : mdarr = msfcs.phaseDirMeasCol().convert(i, newFrame);
232 0 : darr.resize(IPosition(2, 2, nOrders));
233 0 : for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
234 0 : dirV = mdarr[orderNumber].getAngle().getValue();
235 0 : darr(IPosition(2, 0, orderNumber)) = dirV[0];
236 0 : darr(IPosition(2, 1, orderNumber)) = dirV[1];
237 : }
238 0 : msfcs.phaseDir().put(i, darr);
239 :
240 : //msfcs.phaseDirMeasCol().put(i, mdarr);
241 :
242 0 : if(doAll3){
243 : //ddc.put(i, ddc.doConvert(i, *converter));
244 0 : mdarr = msfcs.delayDirMeasCol().convert(i, newFrame);
245 0 : for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
246 0 : dirV = mdarr[orderNumber].getAngle().getValue();
247 0 : darr(IPosition(2, 0, orderNumber)) = dirV[0];
248 0 : darr(IPosition(2, 1, orderNumber)) = dirV[1];
249 : }
250 0 : msfcs.delayDir().put(i, darr);
251 : //rdc.put(i, rdc.doConvert(i, *converter));
252 : //msfcs.referenceDirMeasCol().put(i,
253 : // msfcs.referenceDirMeasCol().convert(i, newFrame));
254 0 : mdarr = msfcs.referenceDirMeasCol().convert(i, newFrame);
255 0 : for(uInt orderNumber = 0; orderNumber < nOrders; ++orderNumber){
256 0 : dirV = mdarr(IPosition(1, orderNumber)).getAngle().getValue();
257 0 : darr(IPosition(2, 0, orderNumber)) = dirV[0];
258 0 : darr(IPosition(2, 1, orderNumber)) = dirV[1];
259 : }
260 0 : msfcs.referenceDir().put(i, darr);
261 : }
262 : }
263 :
264 : // Update the reference frame label(s).
265 0 : msfcs.phaseDirMeasCol().setDescRefCode(newFrame.getType(), false);
266 0 : if(doAll3){
267 0 : msfcs.delayDirMeasCol().setDescRefCode(newFrame.getType(), false);
268 0 : msfcs.referenceDirMeasCol().setDescRefCode(newFrame.getType(), false);
269 : }
270 :
271 : //delete converter;
272 0 : }
273 :
274 :
275 0 : void FixVis::setDistances(const Vector<Double>& distances)
276 : {
277 0 : logSink() << LogOrigin("FixVis", "setDistances");
278 0 : if(distances.nelements() != nsel_p)
279 : logSink() << LogIO::SEVERE
280 : << "Mismatch between the # of specified distances and selected fields."
281 0 : << LogIO::POST;
282 0 : distances_p = distances;
283 0 : }
284 :
285 : // Calculate the (u, v, w)s and store them in ms_p.
286 0 : Bool FixVis::calc_uvw(const String& refcode, const Bool reuse)
287 : {
288 0 : Bool retval = false;
289 :
290 0 : logSink() << LogOrigin("FixVis", "calc_uvw");
291 :
292 0 : if(!ready_msc_p())
293 0 : return false;
294 :
295 0 : if(nsel_p > 0){
296 :
297 : // Get the PHASE_DIR reference frame type for the input ms.
298 0 : MSFieldColumns& msfcs(msc_p->field());
299 0 : MDirection startDir = msfcs.phaseDirMeas(0);
300 0 : MDirection::Types startDirType = MDirection::castType(msfcs.phaseDirMeasCol().getMeasRef().getType());
301 : MDirection::Types wantedDirType;
302 0 : MDirection::getType(wantedDirType, refcode);
303 :
304 0 : if(startDirType != wantedDirType){
305 0 : if(nsel_p < nAllFields_p){
306 : logSink() << LogIO::SEVERE
307 : << "The reference frame must either be changed for all fields or not at all."
308 0 : << LogIO::POST;
309 0 : return false;
310 : }
311 : else
312 0 : convertFieldDirs(wantedDirType);
313 : }
314 0 : else if(reuse){
315 : logSink() << LogIO::NORMAL
316 : << "The UVWs are already in the desired frame - leaving them as is."
317 0 : << LogIO::POST;
318 0 : return true;
319 : }
320 :
321 : try{
322 0 : if(reuse){
323 0 : const MDirection::Ref outref(wantedDirType);
324 :
325 0 : rotateUVW(startDir, outref);
326 : }
327 : else{
328 : Muvw::Types uvwtype;
329 : MBaseline::Types bltype;
330 :
331 : try{
332 0 : MBaseline::getType(bltype, refcode);
333 0 : Muvw::getType(uvwtype, refcode);
334 : }
335 0 : catch(AipsError x){
336 : logSink() << LogIO::SEVERE
337 : << "refcode \"" << refcode << "\" is not valid for baselines."
338 0 : << LogIO::POST;
339 0 : return false;
340 : }
341 :
342 0 : MSUVWGenerator uvwgen(*msc_p, bltype, uvwtype);
343 0 : retval = uvwgen.make_uvws(FieldIds_p);
344 : }
345 :
346 : }
347 0 : catch(AipsError x){
348 0 : logSink() << LogIO::SEVERE << "Error " << x.getMesg() << LogIO::POST;
349 : }
350 :
351 : }
352 : else{
353 : logSink() << LogIO::SEVERE
354 : << "There is a problem with the selected field IDs and phase tracking centers."
355 0 : << LogIO::POST;
356 : }
357 0 : return retval;
358 : }
359 :
360 : // Convert the UVW column to a new reference frame by rotating the old
361 : // baselines instead of calculating fresh ones.
362 : //
363 : // oldref must be supplied instead of extracted from msc_p->uvw(), because
364 : // the latter might be wrong (use the field direction).
365 0 : void FixVis::rotateUVW(const MDirection &indir, const MDirection::Ref& newref)
366 : {
367 0 : ArrayColumn<Double>& UVWcol = msc_p->uvw();
368 :
369 : // Setup a machine for converting a UVW vector from the old frame to
370 : // uvwtype's frame
371 0 : UVWMachine uvm(newref, indir);
372 0 : RotMatrix rm(uvm.rotationUVW());
373 :
374 0 : uInt nRows = UVWcol.nrow();
375 0 : for(uInt row = 0; row < nRows; ++row){
376 0 : UVWcol.put(row, (rm * MVuvw(UVWcol(row))).getVector());
377 : }
378 0 : return;
379 : }
380 :
381 : // Don't just calculate the (u, v, w)s, do everything and store them in ms_p.
382 0 : Bool FixVis::fixvis(const String& refcode)
383 : {
384 0 : logSink() << LogOrigin("FixVis", "fixvis");
385 :
386 0 : Bool retval = false;
387 :
388 0 : if(!ready_msc_p())
389 0 : return false;
390 :
391 0 : if(nsel_p > 0){
392 0 : if(phaseDirs_p.nelements() == static_cast<uInt>(nsel_p)){
393 :
394 0 : String telescop = msc_p->observation().telescopeName()(0);
395 0 : MPosition obsPosition;
396 0 : if(!(MeasTable::Observatory(obsPosition, telescop))){
397 : logSink() << LogIO::WARN << "Did not get the position of " << telescop
398 0 : << " from data repository" << LogIO::POST;
399 : logSink() << LogIO::WARN << "Please contact CASA to add it to the repository."
400 0 : << LogIO::POST;
401 0 : logSink() << LogIO::WARN << "Frequency conversion will not work " << LogIO::POST;
402 0 : freqFrameValid_p = false;
403 : }
404 : else{
405 0 : mLocation_p = obsPosition;
406 0 : freqFrameValid_p = true;
407 : }
408 :
409 0 : MSFieldColumns& msfcs = msc_p->field();
410 :
411 0 : mFrame_p = MeasFrame(msfcs.timeMeas()(0), mLocation_p);
412 :
413 0 : msc_p->uvw().rwKeywordSet().asrwRecord("MEASINFO").define("Ref", refcode);
414 :
415 : //**** Adjust the phase tracking centers and distances. ****
416 : // Loop through each selected field.
417 : Int selectedField;
418 0 : Int selFldCounter=0;
419 0 : for(uInt fldCounter = 0; fldCounter < nAllFields_p; ++fldCounter){
420 0 : selectedField = FieldIds_p[fldCounter];
421 0 : if(selectedField<0){
422 0 : continue;
423 : }
424 0 : setImageField(selectedField);
425 0 : if(makeSelection(selectedField)){
426 0 : logSink() << LogIO::NORMAL << "Processing field " << selectedField << LogIO::POST;
427 0 : processSelected(selFldCounter);
428 0 : selFldCounter++;
429 :
430 : // Update FIELD (and/or optional tables SOURCE, OBSERVATION, but not
431 : // POINTING?) to new PTC.
432 :
433 0 : retval = true;
434 : }
435 : else{
436 : logSink() << LogIO::SEVERE
437 : << "Field " << selectedField << " could not be selected for phase tracking center or"
438 : << " distance adjustment."
439 0 : << LogIO::POST;
440 : }
441 : }
442 : }
443 0 : else if(phaseDirs_p.nelements() > 0){
444 : logSink() << LogIO::SEVERE
445 : << "There is a problem with the selected field IDs and phase tracking centers.\n"
446 : << "No adjustments of phase tracking centers or distances will be done."
447 0 : << LogIO::POST;
448 : }
449 : }
450 : else{
451 0 : logSink() << LogIO::SEVERE << "No fields are selected." << LogIO::POST;
452 : }
453 0 : return retval;
454 : }
455 :
456 :
457 0 : Bool FixVis::setImageField(const Int fieldid,
458 : const Bool dotrackDir //, const MDirection& trackDir
459 : )
460 : {
461 0 : logSink() << LogOrigin("FixVis", "setImageField()");
462 :
463 : try{
464 :
465 0 : doTrackSource_p = dotrackDir;
466 :
467 0 : fieldid_p = fieldid;
468 :
469 0 : return true;
470 : }
471 : catch(AipsError x){
472 : this->unlock();
473 : logSink() << LogIO::SEVERE << "Caught exception: " << x.getMesg()
474 : << LogIO::POST;
475 : return false;
476 : }
477 : return true;
478 : }
479 :
480 0 : Bool FixVis::lock()
481 : {
482 0 : Bool ok = true;
483 :
484 0 : if(lockCounter_p == 0)
485 0 : ok = ms_p.lock();
486 0 : ++lockCounter_p;
487 :
488 0 : return ok;
489 : }
490 :
491 0 : void FixVis::unlock()
492 : {
493 0 : if(lockCounter_p == 1)
494 0 : ms_p.unlock();
495 :
496 0 : if(lockCounter_p > 0)
497 0 : --lockCounter_p;
498 0 : }
499 :
500 :
501 0 : Bool FixVis::makeSelection(const Int selectedField)
502 : {
503 0 : logSink() << LogOrigin("FixVis", "makeSelection()");
504 :
505 : //Vis/MSIter will check if SORTED_TABLE exists and resort if necessary.
506 0 : MSSelection thisSelection;
507 0 : if(selectedField >= 0 && nAllFields_p > 1){
508 0 : Vector<Int> wrapper;
509 0 : wrapper.resize(1);
510 0 : wrapper[0] = selectedField;
511 0 : thisSelection.setFieldExpr(MSSelection::indexExprStr(wrapper));
512 : }
513 0 : else if(antennaSel_p){
514 0 : if(antennaId_p.nelements() > 0)
515 0 : thisSelection.setAntennaExpr(MSSelection::indexExprStr(antennaId_p));
516 0 : if(antennaSelStr_p[0] != "")
517 0 : thisSelection.setAntennaExpr(MSSelection::nameExprStr(antennaSelStr_p));
518 : }
519 : // if(obsString_p != "")
520 : // thisSelection.setObservationExpr(obsString_p);
521 :
522 0 : TableExprNode exprNode = thisSelection.toTableExprNode(&ms_p);
523 :
524 : // Now remake the selected ms
525 0 : if(!(exprNode.isNull())){
526 0 : mssel_p = MeasurementSet(ms_p(exprNode));
527 : }
528 0 : else if(selectedField < 0 || nsel_p == nAllFields_p){
529 : // Null take all the ms ...setdata() blank means that
530 0 : mssel_p = MeasurementSet(ms_p);
531 : }
532 : else{
533 : logSink() << LogIO::SEVERE
534 : << "Error selecting field " << selectedField << ". "
535 : << "Are you trying to adjust antenna positions at the same time?"
536 0 : << LogIO::POST;
537 0 : return false;
538 : }
539 :
540 : //mssel_p.rename(ms_p.tableName()+"/SELECTED_TABLE", Table::Scratch);
541 0 : if(mssel_p.nrow() == 0)
542 0 : return false;
543 :
544 0 : if(mssel_p.nrow() < ms_p.nrow())
545 : logSink() << LogIO::NORMAL
546 : << mssel_p.nrow() << " rows selected out of " << ms_p.nrow() << "."
547 0 : << LogIO::POST;
548 :
549 0 : delete msc_p;
550 0 : msc_p = NULL;
551 0 : return ready_msc_p();
552 : }
553 :
554 0 : Bool FixVis::ready_msc_p()
555 : {
556 0 : Bool retval = false;
557 :
558 0 : if(!msc_p){
559 : try{
560 0 : msc_p = new MSColumns(mssel_p.isNull() ? ms_p : mssel_p);
561 0 : retval = true; // Assume msc_p is OK.
562 : }
563 0 : catch(AipsError& e){
564 : logSink() << LogIO::SEVERE
565 : << "Error getting the columns from the MS."
566 0 : << LogIO::POST;
567 : }
568 0 : catch(std::bad_alloc& e){
569 : logSink() << LogIO::SEVERE
570 : << "Error allocating memory for the MS columns."
571 0 : << LogIO::POST;
572 : }
573 : // Just let any other exceptions, of the unexpected kind,
574 : // propagate up where they can be seen.
575 : }
576 : else
577 0 : retval = true; // Assume msc_p is OK.
578 :
579 0 : return retval;
580 : }
581 :
582 :
583 0 : void FixVis::processSelected(uInt numInSel)
584 : {
585 0 : logSink() << LogOrigin("FixVis", "processSelected()");
586 :
587 0 : mImage_p = phaseDirs_p[numInSel];
588 :
589 0 : ArrayColumn<Double>& UVWcol = msc_p->uvw();
590 :
591 0 : Block<Int> sort(0);
592 0 : sort.resize(4);
593 0 : sort[0] = MS::ARRAY_ID; // use default sort order
594 0 : sort[1] = MS::FIELD_ID;
595 0 : sort[2] = MS::DATA_DESC_ID;
596 0 : sort[3] = MS::TIME;
597 :
598 0 : VisibilityIterator vi(mssel_p, sort);
599 :
600 : // Loop over all visibilities in the selected field.
601 0 : VisBuffer vb(vi);
602 :
603 0 : vi.origin();
604 :
605 0 : for(vi.originChunks(); vi.moreChunks(); vi.nextChunk()){
606 0 : for(vi.origin(); vi.more(); ++vi){
607 :
608 0 : uInt numRows = vb.nRow();
609 :
610 0 : Matrix<Double> uvw(3, numRows);
611 0 : uvw=0.0;
612 0 : Vector<Double> dphase(numRows);
613 0 : dphase=0.0;
614 :
615 0 : for(uInt i = 0; i < numRows; ++i){
616 0 : for (Int idim=0;idim<3;idim++){
617 0 : uvw(idim,i)=vb.uvw()(i)(idim);
618 : }
619 : }
620 :
621 : // the following call requires the member variables
622 : // lastFieldId_p
623 : // lastMSId_p
624 : // tangentSpecified_p
625 : // MeasFrame mFrame_p == output ref frame for the UVW coordinates
626 : // MDirection mImage_p == output phase center
627 : // (input phase center is taken from the visbuffer, i.e. from the FIELD table)
628 :
629 0 : FTMachine::rotateUVW(uvw, dphase, vb);
630 :
631 : // Immediately returns if not needed.
632 0 : refocus(uvw, vb.antenna1(), vb.antenna2(), dphase, vb);
633 :
634 : // update vis buffer cache
635 0 : for(uInt datacol = 0; datacol < nDataCols_p; datacol++){
636 0 : if(dataCols_p[datacol] == MS::DATA){
637 0 : vb.visCube(); // return value not needed
638 : }
639 0 : else if(dataCols_p[datacol] == MS::CORRECTED_DATA){
640 0 : vb.correctedVisCube();
641 : }
642 0 : else if(dataCols_p[datacol] == MS::MODEL_DATA){
643 0 : vb.modelVisCube();
644 : }
645 : }
646 :
647 : // apply phase center shift to vis buffer
648 0 : vb.phaseCenterShift(dphase);
649 :
650 : // write changed UVWs
651 0 : auto origRows = vb.rowIds();
652 0 : for(uInt row = 0; row < numRows; row++){
653 0 : UVWcol.put(origRows(row), uvw.column(row));
654 : }
655 :
656 : // write changed visibilities
657 0 : for(uInt datacol = 0; datacol < nDataCols_p; datacol++){
658 0 : if(dataCols_p[datacol] == MS::DATA){
659 0 : vi.setVis(vb.visCube(),VisibilityIterator::Observed);
660 : }
661 0 : else if(dataCols_p[datacol] == MS::CORRECTED_DATA){
662 0 : vi.setVis(vb.correctedVisCube(),VisibilityIterator::Corrected);
663 : }
664 0 : else if(dataCols_p[datacol] == MS::MODEL_DATA){
665 0 : vi.setVis(vb.modelVisCube(),VisibilityIterator::Model);
666 : }
667 : }
668 :
669 :
670 : }
671 :
672 : }
673 :
674 0 : }
675 :
676 :
677 0 : void FixVis::ok() {
678 : // AlwaysAssert(image, AipsError);
679 0 : }
680 :
681 0 : void FixVis::init()
682 : {
683 0 : logSink() << LogOrigin("FixVis", "init") << LogIO::NORMAL;
684 :
685 : //ok();
686 :
687 : //npol = image->shape()(2);
688 : //nchan = image->shape()(3);
689 0 : }
690 :
691 : // Initialize FTMachine.
692 0 : void FixVis::initializeToVis(ImageInterface<Complex>& iimage,
693 : const VisBuffer&)
694 : {
695 0 : image = &iimage;
696 :
697 0 : ok();
698 0 : init();
699 :
700 : // Initialize the maps for polarization and channel. These maps
701 : // translate visibility indices into image indices
702 : //RR initMaps(vb);
703 0 : }
704 :
705 0 : void FixVis::finalizeToVis()
706 : {
707 0 : }
708 :
709 : // Initialize the FFT to the Sky. Here we have to setup and initialize the
710 : // grid.
711 0 : void FixVis::initializeToSky(ImageInterface<Complex>& iimage,
712 : Matrix<Float>&, //weight,
713 : const VisBuffer&)
714 : {
715 : // image always points to the image
716 0 : image = &iimage;
717 :
718 0 : init();
719 :
720 : // Initialize the maps for polarization and channel. These maps
721 : // translate visibility indices into image indices
722 : //RR initMaps(vb);
723 0 : }
724 :
725 : } // End of casa namespace.
726 :
|