Line data Source code
1 : //# VisBufferUtil.cc: VisBuffer Utilities
2 : //# Copyright (C) 1996,1997,2001
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be adressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //#
27 : //# $Id$
28 :
29 : #include <casacore/casa/aips.h>
30 :
31 : #include <casacore/casa/Utilities/Assert.h>
32 : #include <casacore/casa/Exceptions/Error.h>
33 : #include <casacore/casa/Arrays/ArrayMath.h>
34 : #include <casacore/casa/Arrays/MatrixMath.h>
35 : #include <casacore/casa/Arrays/Array.h>
36 : #include <casacore/casa/Arrays/Vector.h>
37 : #include <casacore/casa/Arrays/Matrix.h>
38 : #include <casacore/casa/Arrays/Cube.h>
39 : #include <casacore/casa/Utilities/Sort.h>
40 : #include <casacore/casa/OS/Timer.h>
41 : #include <casacore/casa/OS/Path.h>
42 : #include <casacore/measures/Measures/UVWMachine.h>
43 : #include <casacore/measures/Measures/MeasTable.h>
44 : #include <casacore/ms/MSSel/MSSelectionTools.h>
45 : #include <casacore/ms/MeasurementSets/MSPointingColumns.h>
46 : #include <msvis/MSVis/VisBufferUtil.h>
47 : #include <msvis/MSVis/StokesVector.h>
48 : #include <msvis/MSVis/ViImplementation2.h>
49 : #include <msvis/MSVis/VisibilityIterator.h>
50 : #include <msvis/MSVis/VisibilityIterator2.h>
51 : #include <msvis/MSVis/VisBuffer.h>
52 : #include <casacore/ms/MeasurementSets/MSColumns.h>
53 : #include <iostream>
54 : #include <fstream>
55 : #include <iomanip>
56 :
57 : #ifdef _OPENMP
58 : #include <omp.h>
59 : #endif
60 : using namespace std;
61 :
62 : using namespace casacore;
63 : namespace casa { //# NAMESPACE CASA - BEGIN
64 :
65 : // <summary>
66 : // </summary>
67 :
68 : // <reviewed reviewer="" date="" tests="tMEGI" demos="">
69 :
70 : // <prerequisite>
71 : // </prerequisite>
72 : //
73 : // <etymology>
74 : // </etymology>
75 : //
76 : // <synopsis>
77 : // </synopsis>
78 : //
79 : // <example>
80 : // <srcblock>
81 : // </srcblock>
82 : // </example>
83 : //
84 : // <motivation>
85 : // </motivation>
86 : //
87 : // <todo asof="">
88 : // </todo>
89 :
90 :
91 0 : VisBufferUtil::VisBufferUtil(): oldMSId_p(-1), oldPCMSId_p(-1), timeAntIndex_p(0), cachedPointingDir_p(0), cachedPhaseCenter_p(0){};
92 :
93 :
94 : // Construct from a VisBuffer (sets frame info)
95 0 : VisBufferUtil::VisBufferUtil(const VisBuffer& vb): oldMSId_p(-1), oldPCMSId_p(-1), timeAntIndex_p(0), cachedPointingDir_p(0), cachedPhaseCenter_p(0) {
96 :
97 : // The nominal epoch
98 0 : MEpoch ep=vb.msColumns().timeMeas()(0);
99 :
100 : // The nominal position
101 0 : String observatory;
102 0 : MPosition pos;
103 0 : if (vb.msColumns().observation().nrow() > 0) {
104 0 : observatory = vb.msColumns().observation().telescopeName()
105 0 : (vb.msColumns().observationId()(0));
106 : }
107 0 : if (observatory.length() == 0 ||
108 0 : !MeasTable::Observatory(pos,observatory)) {
109 : // unknown observatory, use first antenna
110 0 : pos=vb.msColumns().antenna().positionMeas()(0);
111 : }
112 :
113 : // The nominal direction
114 0 : MDirection dir=vb.phaseCenter();
115 :
116 : // The nominal MeasFrame
117 0 : mframe_=MeasFrame(ep, pos, dir);
118 :
119 0 : }
120 :
121 : // Construct from a VisBuffer (sets frame info)
122 3 : VisBufferUtil::VisBufferUtil(const vi::VisBuffer2& vb): oldMSId_p(-1), oldPCMSId_p(-1), timeAntIndex_p(0), cachedPointingDir_p(0), cachedPhaseCenter_p(0) {
123 3 : if(!vb.isAttached())
124 0 : ThrowCc("Programmer Error: used a detached Visbuffer when it should not have been so");
125 3 : MSColumns msc(vb.ms());
126 : // The nominal epoch
127 3 : MEpoch ep=msc.timeMeas()(0);
128 :
129 : // The nominal position
130 3 : String observatory;
131 3 : MPosition pos;
132 3 : if (msc.observation().nrow() > 0) {
133 3 : observatory = msc.observation().telescopeName()
134 3 : (msc.observationId()(0));
135 : }
136 6 : if (observatory.length() == 0 ||
137 3 : !MeasTable::Observatory(pos,observatory)) {
138 : // unknown observatory, use first antenna
139 0 : pos=msc.antenna().positionMeas()(0);
140 : }
141 :
142 : // The nominal direction
143 3 : MDirection dir=vb.phaseCenter();
144 :
145 : // The nominal MeasFrame
146 3 : mframe_=MeasFrame(ep, pos, dir);
147 :
148 3 : }
149 0 : VisBufferUtil::VisBufferUtil(const vi::VisibilityIterator2& iter): oldMSId_p(-1) {
150 :
151 0 : MSColumns msc(iter.ms());
152 : // The nominal epoch
153 0 : MEpoch ep=msc.timeMeas()(0);
154 :
155 : // The nominal position
156 0 : String observatory;
157 0 : MPosition pos;
158 0 : if (msc.observation().nrow() > 0) {
159 0 : observatory = msc.observation().telescopeName()
160 0 : (msc.observationId()(0));
161 : }
162 0 : if (observatory.length() == 0 ||
163 0 : !MeasTable::Observatory(pos,observatory)) {
164 : // unknown observatory, use first antenna
165 0 : pos=msc.antenna().positionMeas()(0);
166 : }
167 :
168 : // The nominal direction
169 : //MDirection dir=iter.phaseCenter();
170 0 : MDirection dir=msc.field().phaseDirMeasCol()(0)(IPosition(1,0));
171 : // The nominal MeasFrame
172 0 : mframe_=MeasFrame(ep, pos, dir);
173 :
174 0 : }
175 0 : VisBufferUtil::VisBufferUtil(const MeasFrame& mframe): oldMSId_p(-1) {
176 0 : mframe_=mframe;
177 :
178 0 : }
179 0 : Bool VisBufferUtil::rotateUVW(const vi::VisBuffer2&vb, const MDirection& desiredDir,
180 : Matrix<Double>& uvw, Vector<Double>& dphase){
181 :
182 0 : Bool retval=true;
183 0 : mframe_.resetEpoch(vb.time()(0));
184 0 : UVWMachine uvwMachine(desiredDir, vb.phaseCenter(), mframe_,
185 0 : false, false);
186 0 : retval = !uvwMachine.isNOP();
187 0 : dphase.resize(vb.nRows());
188 0 : dphase.set(0.0);
189 0 : if(uvw.nelements() ==0)
190 0 : uvw=vb.uvw();
191 0 : for (rownr_t row=0; row< vb.nRows(); ++row){
192 0 : Vector<Double> eluvw(uvw.column(row));
193 0 : uvwMachine.convertUVW(dphase(row), eluvw);
194 0 : }
195 :
196 0 : return retval;
197 0 : }
198 :
199 : // Set the visibility buffer for a PSF
200 0 : void VisBufferUtil::makePSFVisBuffer(VisBuffer& vb) {
201 0 : CStokesVector coh(Complex(1.0), Complex(0.0), Complex(0.0), Complex(1.0));
202 0 : vb.correctedVisibility()=coh;
203 0 : }
204 :
205 :
206 0 : Bool VisBufferUtil::interpolateFrequency(Cube<Complex>& data,
207 : Cube<Bool>& flag,
208 : const VisBuffer& vb,
209 : const Vector<Float>& outFreqGrid,
210 : const MS::PredefinedColumns whichCol,
211 : const MFrequency::Types freqFrame,
212 : const InterpolateArray1D<Float,Complex>::InterpolationMethod interpMethod){
213 :
214 0 : Cube<Complex> origdata;
215 : // Convert the visibility frequency to the frame requested
216 0 : Vector<Double> visFreqD;
217 0 : convertFrequency(visFreqD, vb, freqFrame);
218 : //convert it to Float
219 0 : Vector<Float> visFreq(visFreqD.nelements());
220 0 : convertArray(visFreq, visFreqD);
221 :
222 : //Assign which column is to be regridded to origdata
223 0 : if(whichCol==MS::MODEL_DATA){
224 0 : origdata.reference(vb.modelVisCube());
225 : }
226 0 : else if(whichCol==MS::CORRECTED_DATA){
227 0 : origdata.reference(vb.correctedVisCube());
228 : }
229 0 : else if(whichCol==MS::DATA){
230 0 : origdata.reference(vb.visCube());
231 : }
232 : else{
233 0 : throw(AipsError("Don't know which column is being regridded"));
234 : }
235 0 : Cube<Complex> flipdata;
236 0 : Cube<Bool> flipflag;
237 : //The interpolator interpolates on the 3rd axis only...so need to flip the axes (y,z)
238 0 : swapyz(flipflag,vb.flagCube());
239 0 : swapyz(flipdata,origdata);
240 :
241 : //interpolate the data and the flag to the output frequency grid
242 : InterpolateArray1D<Float,Complex>::
243 0 : interpolate(data,flag, outFreqGrid,visFreq,flipdata,flipflag,interpMethod);
244 0 : flipdata.resize();
245 : //reflip the data and flag to be in the same order as in Visbuffer output
246 0 : swapyz(flipdata,data);
247 0 : data.resize();
248 0 : data.reference(flipdata);
249 0 : flipflag.resize();
250 0 : swapyz(flipflag,flag);
251 0 : flag.resize();
252 0 : flag.reference(flipflag);
253 :
254 0 : return true;
255 :
256 0 : }
257 0 : void VisBufferUtil::getFreqRange(Double& freqMin, Double& freqMax, vi::VisibilityIterator2& vi, MFrequency::Types freqFrame){
258 0 : vi.originChunks();
259 0 : vi.origin();
260 :
261 0 : Double freqEnd=0.0;
262 0 : Double freqStart=C::dbl_max;
263 0 : vi::VisBuffer2* vb=vi.getVisBuffer();
264 0 : for (vi.originChunks(); vi.moreChunks();vi.nextChunk())
265 : {
266 0 : for (vi.origin(); vi.more();vi.next())
267 : {
268 : Double localmax, localmin;
269 0 : IPosition localmaxpos(1,0);
270 0 : IPosition localminpos(1,0);
271 0 : Vector<Double> freqs=vb->getFrequencies(0, freqFrame);
272 0 : if(freqs.nelements() ==0){
273 0 : throw(AipsError("Frequency selection error" ));
274 : }
275 0 : minMax(localmin,localmax,localminpos, localmaxpos, freqs);
276 : //localmax=max(freqs);
277 : //localmin=min(freqs);
278 : //freqEnd=max(freqEnd, localmax);
279 : //freqStart=min(freqStart, localmin);
280 :
281 0 : Int nfreq = freqs.nelements();
282 0 : Vector<Int> curspws = vb->spectralWindows();
283 : // as the vb row 0 is used for getFrequencies, the same row 0 is used here
284 0 : Vector<Double> chanWidths = vi.subtableColumns().spectralWindow().chanWidth()(curspws[0]);
285 : // freqs are in channel center freq so add the half the width to the values to return the edge frequencies
286 0 : if (nfreq==1) {
287 0 : freqEnd=max(freqEnd, localmax+fabs(chanWidths[0]/2.0));
288 0 : freqStart=min(freqStart, localmin-fabs(chanWidths[0]/2.0));
289 : }
290 : else {
291 0 : freqEnd=max(freqEnd, localmax+fabs(chanWidths[localmaxpos[0]]/2.0));
292 0 : freqStart=min(freqStart, localmin-fabs(chanWidths[localminpos[0]]/2.0));
293 : }
294 :
295 0 : }
296 : }
297 0 : freqMin=freqStart;
298 0 : freqMax=freqEnd;
299 0 : }
300 :
301 0 : Bool VisBufferUtil::getFreqRangeFromRange(casacore::Double& outfreqMin, casacore::Double& outfreqMax, const casacore::MFrequency::Types inFreqFrame, const casacore::Double infreqMin, const casacore::Double infreqMax, vi::VisibilityIterator2& vi, casacore::MFrequency::Types outFreqFrame){
302 :
303 :
304 0 : if(inFreqFrame==outFreqFrame){
305 0 : outfreqMin=infreqMin;
306 0 : outfreqMax=infreqMax;
307 0 : return True;
308 : }
309 :
310 :
311 0 : vi.originChunks();
312 0 : vi.origin();
313 : try{
314 0 : outfreqMin=C::dbl_max;
315 0 : outfreqMax=0;
316 0 : vi::VisBuffer2* vb=vi.getVisBuffer();
317 0 : MSColumns msc(vi.ms());
318 : // The nominal epoch
319 0 : MEpoch ep=msc.timeMeas()(0);
320 :
321 : // The nominal position
322 0 : String observatory;
323 0 : MPosition pos;
324 0 : if (msc.observation().nrow() > 0) {
325 0 : observatory = msc.observation().telescopeName()
326 0 : (msc.observationId()(0));
327 : }
328 0 : if (observatory.length() == 0 ||
329 0 : !MeasTable::Observatory(pos,observatory)) {
330 : // unknown observatory, use first antenna
331 0 : pos=msc.antenna().positionMeas()(0);
332 : }
333 :
334 : // The nominal direction
335 0 : MDirection dir=vb->phaseCenter();
336 0 : MeasFrame mFrame(ep, pos, dir);
337 : // The conversion engine:
338 : MFrequency::Convert toNewFrame(inFreqFrame,
339 0 : MFrequency::Ref(outFreqFrame, mFrame));
340 :
341 0 : for (vi.originChunks(); vi.moreChunks();vi.nextChunk())
342 : {
343 0 : for (vi.origin(); vi.more();vi.next()){
344 : //assuming time is fixed in visbuffer
345 0 : mFrame.resetEpoch(vb->time()(0)/86400.0);
346 :
347 : // Reset the direction (ASSUMES phaseCenter is constant in the VisBuffer)
348 0 : mFrame.resetDirection(vb->phaseCenter());
349 0 : Double temp=toNewFrame(infreqMin).getValue().getValue();
350 0 : if(temp < outfreqMin)
351 0 : outfreqMin = temp;
352 :
353 0 : temp=toNewFrame(infreqMax).getValue().getValue();
354 0 : if(temp > outfreqMax)
355 0 : outfreqMax = temp;
356 : }
357 : }
358 0 : }
359 0 : catch(...){
360 : //Could not do a conversion
361 0 : return False;
362 :
363 0 : }
364 : //cerr << "min " << outfreqMin << " max " << outfreqMax << endl;
365 0 : return True;
366 :
367 : }
368 :
369 0 : void VisBufferUtil::convertFrequency(Vector<Double>& outFreq,
370 : const VisBuffer& vb,
371 : const MFrequency::Types freqFrame){
372 0 : Int spw=vb.spectralWindow();
373 0 : MFrequency::Types obsMFreqType=(MFrequency::Types)(vb.msColumns().spectralWindow().measFreqRef()(spw));
374 :
375 : // The input frequencies (a reference)
376 0 : Vector<Double> inFreq(vb.frequency());
377 :
378 : // The output frequencies
379 0 : outFreq.resize(inFreq.nelements());
380 :
381 0 : MFrequency::Types newMFreqType=freqFrame;
382 0 : if (freqFrame==MFrequency::N_Types)
383 : // Opt out of conversion
384 0 : newMFreqType=obsMFreqType;
385 :
386 :
387 : // Only convert if the requested frame differs from observed frame
388 0 : if(obsMFreqType != newMFreqType){
389 :
390 : // Setting epoch to the first in this iteration
391 : // MEpoch ep=vb.msColumns().timeMeas()(0);
392 : // MEpoch ep(MVEpoch(vb.time()(0)/86400.0),MEpoch::UTC);
393 : // cout << "Time = " << ep.getValue() << endl;
394 :
395 : // Reset the timestamp (ASSUMES TIME is constant in the VisBuffer)
396 0 : mframe_.resetEpoch(vb.time()(0)/86400.0);
397 :
398 : // Reset the direction (ASSUMES phaseCenter is constant in the VisBuffer)
399 0 : mframe_.resetDirection(vb.msColumns().field().phaseDirMeasCol()(vb.fieldId())(IPosition(1,0)));
400 :
401 : // cout << "Frame = " << mframe_ << endl;
402 :
403 : // The conversion engine:
404 : MFrequency::Convert toNewFrame(obsMFreqType,
405 0 : MFrequency::Ref(newMFreqType, mframe_));
406 :
407 : // Do the conversion
408 0 : for (uInt k=0; k< inFreq.nelements(); ++k)
409 0 : outFreq(k)=toNewFrame(inFreq(k)).getValue().getValue();
410 :
411 0 : }
412 : else{
413 : // The requested frame is the same as the observed frame
414 0 : outFreq=inFreq;
415 : }
416 :
417 0 : }
418 :
419 0 : void VisBufferUtil::convertFrequency(Vector<Double>& outFreq,
420 : const vi::VisBuffer2& vb,
421 : const MFrequency::Types freqFrame){
422 0 : Int spw=vb.spectralWindows()(0);
423 0 : MFrequency::Types obsMFreqType=(MFrequency::Types)(MSColumns(vb.ms()).spectralWindow().measFreqRef()(spw));
424 :
425 :
426 :
427 : // The input frequencies
428 0 : Vector<Int> chanNums=vb.getChannelNumbers(0);
429 :
430 0 : Vector<Double> inFreq(chanNums.nelements());
431 0 : Vector<Double> spwfreqs=MSColumns(vb.ms()).spectralWindow().chanFreq().get(spw);
432 0 : for (uInt k=0; k < chanNums.nelements(); ++k){
433 :
434 0 : inFreq[k]=spwfreqs[chanNums[k]];
435 : }
436 :
437 : // The output frequencies
438 0 : outFreq.resize(inFreq.nelements());
439 :
440 0 : MFrequency::Types newMFreqType=freqFrame;
441 0 : if (freqFrame==MFrequency::N_Types)
442 : // Opt out of conversion
443 0 : newMFreqType=obsMFreqType;
444 :
445 :
446 : // Only convert if the requested frame differs from observed frame
447 0 : if(obsMFreqType != newMFreqType){
448 :
449 : // Setting epoch to the first in this iteration
450 : // MEpoch ep=vb.msColumns().timeMeas()(0);
451 : // MEpoch ep(MVEpoch(vb.time()(0)/86400.0),MEpoch::UTC);
452 : // cout << "Time = " << ep.getValue() << endl;
453 :
454 : // Reset the timestamp (ASSUMES TIME is constant in the VisBuffer)
455 0 : mframe_.resetEpoch(vb.time()(0)/86400.0);
456 :
457 : // Reset the direction (ASSUMES phaseCenter is constant in the VisBuffer)
458 0 : mframe_.resetDirection(vb.phaseCenter());
459 :
460 : // cout << "Frame = " << mframe_ << endl;
461 :
462 : // The conversion engine:
463 : MFrequency::Convert toNewFrame(obsMFreqType,
464 0 : MFrequency::Ref(newMFreqType, mframe_));
465 :
466 : // Do the conversion
467 0 : for (uInt k=0; k< inFreq.nelements(); ++k)
468 0 : outFreq(k)=toNewFrame(inFreq(k)).getValue().getValue();
469 :
470 0 : }
471 : else{
472 : // The requested frame is the same as the observed frame
473 0 : outFreq=inFreq;
474 : }
475 :
476 : //cerr << std::setprecision(9) << " infreq " << inFreq[152] << " " << outFreq[152] << " vb freq " << vb.getFrequencies(0, freqFrame)[152] << endl;
477 :
478 0 : }
479 :
480 0 : void VisBufferUtil::toVelocity(Vector<Double>& outVel,
481 : const VisBuffer& vb,
482 : const MFrequency::Types freqFrame,
483 : const MVFrequency restFreq,
484 : const MDoppler::Types veldef){
485 :
486 : // The input frequencies (a reference)
487 0 : Vector<Double> inFreq(vb.frequency());
488 :
489 : // The output velocities
490 0 : outVel.resize(inFreq.nelements());
491 :
492 : // Reset the timestamp (ASSUMES TIME is constant in the VisBuffer)
493 0 : mframe_.resetEpoch(vb.time()(0)/86400.0);
494 :
495 : // Reset the direction (ASSUMES phaseCenter is constant in the VisBuffer)
496 : //mframe_.resetDirection(vb.phaseCenter());
497 0 : mframe_.resetDirection(vb.msColumns().field().phaseDirMeasCol()(vb.fieldId())(IPosition(1,0)));
498 :
499 : // The frequency conversion engine:
500 0 : Int spw=vb.spectralWindow();
501 0 : MFrequency::Types obsMFreqType=(MFrequency::Types)(vb.msColumns().spectralWindow().measFreqRef()(spw));
502 :
503 0 : MFrequency::Types newMFreqType=freqFrame;
504 0 : if (freqFrame==MFrequency::N_Types)
505 : // Don't convert frame
506 0 : newMFreqType=obsMFreqType;
507 :
508 : MFrequency::Convert toNewFrame(obsMFreqType,
509 0 : MFrequency::Ref(newMFreqType, mframe_));
510 :
511 : // The velocity conversion engine:
512 0 : MDoppler::Ref dum1(MDoppler::RELATIVISTIC);
513 0 : MDoppler::Ref dum2(veldef);
514 0 : MDoppler::Convert dopConv(dum1, dum2);
515 :
516 : // Cope with unspecified rest freq
517 0 : MVFrequency rf=restFreq;
518 0 : if (restFreq.getValue()<=0.0)
519 0 : rf=toNewFrame(inFreq(vb.nChannel()/2)).getValue();
520 :
521 : // Do the conversions
522 0 : for (uInt k=0; k< inFreq.nelements(); ++k){
523 : //cerr <<"old freq " << toNewFrame(inFreq(k)).getValue().get().getValue() << endl;
524 0 : MDoppler eh = toNewFrame(inFreq(k)).toDoppler(rf);
525 0 : MDoppler eh2 = dopConv(eh);
526 0 : outVel(k)=eh2.getValue().get().getValue();
527 0 : }
528 :
529 0 : }
530 :
531 0 : void VisBufferUtil::toVelocity(Vector<Double>& outVel,
532 : const vi::VisBuffer2& vb,
533 : const MFrequency::Types freqFrame,
534 : const MVFrequency restFreq,
535 : const MDoppler::Types veldef, const Int row){
536 :
537 0 : Vector<Double> inFreq;
538 0 : inFreq=vb.getFrequencies(row, freqFrame);
539 : // cerr << "Freqs " << inFreq << endl;
540 : // The output velocities
541 0 : outVel.resize(inFreq.nelements());
542 : // The velocity conversion engine:
543 0 : MDoppler::Ref dum1(MDoppler::RELATIVISTIC);
544 0 : MDoppler::Ref dum2(veldef);
545 0 : MDoppler::Convert dopConv(dum1, dum2);
546 :
547 : // Cope with unspecified rest freq
548 0 : MVFrequency rf=restFreq;
549 0 : if (restFreq.getValue()<=0.0)
550 0 : rf=inFreq(inFreq.nelements()/2);
551 :
552 : // Do the conversions
553 0 : for (uInt k=0; k< inFreq.nelements(); ++k){
554 0 : MDoppler eh = MFrequency(Quantity(inFreq(k), "Hz"), freqFrame).toDoppler(rf);
555 0 : MDoppler eh2 = dopConv(eh);
556 0 : outVel(k)=eh2.getValue().get().getValue();
557 0 : }
558 :
559 :
560 0 : }
561 0 : void VisBufferUtil::toVelocity(Vector<Double>& outVel,
562 : const vi::VisBuffer2& vb,
563 : const vi::VisibilityIterator2& iter,
564 : const MFrequency::Types freqFrame,
565 : const MVFrequency restFreq,
566 : const MDoppler::Types veldef, const Int row){
567 :
568 : // The input frequencies (a reference)
569 0 : Vector<Double> inFreq(vb.getFrequencies(row));
570 0 : MSColumns msc(iter.ms());
571 :
572 0 : MEpoch ep(Quantity(vb.time()(row)/86400.0, "d"), msc.timeMeas()(0).getRef());
573 0 : MDirection dir(msc.field().phaseDirMeasCol()(vb.fieldId()(row))(IPosition(1,0)));
574 0 : Int spw=vb.spectralWindows()(row);
575 0 : MFrequency::Types obsMFreqType=(MFrequency::Types)(msc.spectralWindow().measFreqRef()(spw));
576 0 : toVelocity(outVel, freqFrame, inFreq, obsMFreqType, ep, dir, restFreq, veldef);
577 0 : }
578 0 : void VisBufferUtil::toVelocity(Vector<Double>& outVel,
579 : const MFrequency::Types outFreqFrame,
580 : const Vector<Double>& inFreq,
581 : const MFrequency::Types inFreqFrame,
582 : const MEpoch& ep,
583 : const MDirection& dir,
584 : const MVFrequency restFreq,
585 : const MDoppler::Types veldef){
586 :
587 :
588 :
589 : // The output velocities
590 0 : outVel.resize(inFreq.nelements());
591 :
592 : // Reset the timestamp
593 0 : mframe_.resetEpoch(ep);
594 :
595 : // Reset the direction
596 0 : mframe_.resetDirection(dir);
597 :
598 : // The frequency conversion engine:
599 :
600 0 : MFrequency::Types newMFreqType=outFreqFrame;
601 0 : if (outFreqFrame==MFrequency::N_Types)
602 : // Don't convert frame
603 0 : newMFreqType=inFreqFrame;
604 :
605 : MFrequency::Convert toNewFrame(inFreqFrame,
606 0 : MFrequency::Ref(newMFreqType, mframe_));
607 :
608 : // The velocity conversion engine:
609 0 : MDoppler::Ref dum1(MDoppler::RELATIVISTIC);
610 0 : MDoppler::Ref dum2(veldef);
611 0 : MDoppler::Convert dopConv(dum1, dum2);
612 :
613 : // Cope with unspecified rest freq
614 0 : MVFrequency rf=restFreq;
615 0 : if (restFreq.getValue()<=0.0)
616 0 : rf=toNewFrame(inFreq(inFreq.nelements()/2)).getValue();
617 :
618 : // Do the conversions
619 0 : for (uInt k=0; k< inFreq.nelements(); ++k){
620 0 : MDoppler eh = toNewFrame(inFreq(k)).toDoppler(rf);
621 0 : MDoppler eh2 = dopConv(eh);
622 0 : outVel(k)=eh2.getValue().get().getValue();
623 0 : }
624 :
625 :
626 :
627 :
628 0 : }
629 :
630 0 : MDirection VisBufferUtil::getPointingDir(const VisBuffer& vb, const Int antid, const Int vbrow){
631 :
632 0 : Timer tim;
633 0 : tim.mark();
634 0 : const MSColumns& msc=vb.msColumns();
635 : //cerr << "oldMSId_p " << oldMSId_p << " vb " << vb.msId() << endl;
636 0 : if(vb.msId() < 0)
637 0 : throw(AipsError("VisBuffer is not attached to an ms so cannot get pointing "));
638 0 : if(oldMSId_p != vb.msId()){
639 0 : oldMSId_p=vb.msId();
640 0 : if(timeAntIndex_p.shape()(0) < (oldMSId_p+1)){
641 0 : timeAntIndex_p.resize(oldMSId_p+1, true);
642 0 : cachedPointingDir_p.resize(oldMSId_p+1, true);
643 : }
644 0 : if( timeAntIndex_p[oldMSId_p].empty()){
645 0 : Vector<Double> tOrig;
646 0 : msc.time().getColumn(tOrig);
647 0 : Vector<Double> t;
648 0 : rejectConsecutive(tOrig, t);
649 0 : Vector<uInt> uniqIndx;
650 0 : uInt nTimes=GenSortIndirect<Double>::sort (uniqIndx, t, Sort::Ascending, Sort::QuickSort|Sort::NoDuplicates);
651 0 : uInt nAnt=msc.antenna().nrow();
652 0 : const MSPointingColumns& mspc=msc.pointing();
653 0 : Vector<Double> tUniq(nTimes);
654 0 : for (uInt k=0; k <nTimes; ++k){
655 0 : tUniq[k]= t[uniqIndx[k]];
656 : }
657 : Bool tstor, timcolstor, intcolstor, antcolstor;
658 0 : Double * tuniqptr=tUniq.getStorage(tstor);
659 0 : Int cshape=cachedPointingDir_p[oldMSId_p].shape()[0];
660 0 : cachedPointingDir_p[oldMSId_p].resize(cshape+nTimes*nAnt, True);
661 0 : Vector<Double> timecol;
662 0 : Vector<Double> intervalcol;
663 0 : Vector<Int> antcol;
664 0 : mspc.time().getColumn(timecol, True);
665 0 : mspc.interval().getColumn(intervalcol, True);
666 0 : mspc.antennaId().getColumn(antcol, True);
667 0 : Double *tcolptr=timecol.getStorage(timcolstor);
668 0 : Double *intcolptr=intervalcol.getStorage(intcolstor);
669 0 : Int * antcolptr=antcol.getStorage(antcolstor);
670 0 : Int npointrow=msc.pointing().nrow();
671 0 : #pragma omp parallel for firstprivate(nTimes, tuniqptr, tcolptr, antcolptr, intcolptr, npointrow), shared(mspc)
672 : for (uInt a=0; a < nAnt; ++a){
673 :
674 : //Double wtime1=omp_get_wtime();
675 : Vector<ssize_t> indices;
676 : Vector<MDirection> theDirs(nTimes);
677 : pointingIndex(tcolptr, antcolptr, intcolptr, npointrow, a, nTimes, tuniqptr, indices);
678 :
679 : #pragma omp critical
680 : {
681 : for (uInt k=0; k <nTimes; ++k){
682 :
683 :
684 : // std::ostringstream oss;
685 : // oss.precision(13);
686 : // oss << tuniqptr[k] << "_" << a;
687 : // String key=oss.str();
688 : std::pair<double, int> key=make_pair(t[uniqIndx[k]],a);
689 : timeAntIndex_p[oldMSId_p][key]=indices[k] > -1 ? cshape : -1;
690 :
691 : if(indices[k] >-1){
692 :
693 : cachedPointingDir_p[oldMSId_p][cshape]=mspc.directionMeas(indices[k]);
694 : cshape+=1;
695 : }
696 :
697 :
698 : }
699 : }//end critical
700 :
701 :
702 : }
703 :
704 0 : cachedPointingDir_p[oldMSId_p].resize(cshape, True);
705 0 : }
706 :
707 : }
708 :
709 : /////
710 : // String index=String::toString(vb.time()(vbrow))+String("_")+String::toString(antid);
711 : // std::ostringstream oss;
712 : // oss.precision(13);
713 : // oss << vb.time()(vbrow) << "_" << antid ;
714 : // String index=oss.str();
715 : //cerr << "index "<< index << endl;
716 : ////////////
717 : /*
718 : for (auto it = timeAntIndex_p[oldMSId_p].begin(); it != timeAntIndex_p[oldMSId_p].end(); ++it)
719 : {
720 : cerr << (*it).first << " --> " << (*it).second << endl;
721 : }
722 : */
723 : /////////////
724 0 : std::pair<double, int> index=make_pair(vb.time()(vbrow), antid);
725 0 : Int rowincache=timeAntIndex_p[oldMSId_p][index];
726 : ///////TESTOO
727 : /* if(rowincache>=0){
728 : cerr << "msid " << oldMSId_p << " key "<< index << " index " << rowincache<< " " << cachedPointingDir_p[oldMSId_p][rowincache] << endl;
729 : }*/
730 : /////////////
731 : //tim.show("retrieved cache");
732 0 : if(rowincache <0)
733 0 : return vb.phaseCenter();
734 0 : return cachedPointingDir_p[oldMSId_p][rowincache];
735 :
736 : }
737 0 : MDirection VisBufferUtil::getPointingDir(const vi::VisBuffer2& vb, const Int antid, const Int vbrow, const MDirection::Types dirframe, const Bool usePointing){
738 :
739 : //Double wtime0=omp_get_wtime();
740 0 : Int rowincache=-1;
741 0 : if(usePointing){
742 0 : if(oldMSId_p != vb.msId()){
743 0 : MSColumns msc(vb.ms());
744 0 : oldMSId_p=vb.msId();
745 0 : if(timeAntIndex_p.shape()(0) < (oldMSId_p+1)){
746 0 : timeAntIndex_p.resize(oldMSId_p+1, true);
747 0 : cachedPointingDir_p.resize(oldMSId_p+1, true);
748 : }
749 0 : MEpoch::Types timeType=MEpoch::castType(msc.timeMeas()(0).getRef().getType());
750 0 : Unit timeUnit(msc.timeMeas().measDesc().getUnits()(0).getName());
751 0 : MPosition pos;
752 0 : String tel;
753 0 : if (vb.subtableColumns().observation().nrow() > 0) {
754 0 : tel =vb.subtableColumns().observation().telescopeName()(msc.observationId()(0));
755 : }
756 0 : if (tel.length() == 0 || !tel.contains("VLA") ||
757 0 : !MeasTable::Observatory(pos,tel)) {
758 : // unknown observatory, use first antenna
759 0 : Int ant1=vb.antenna1()(0);
760 0 : pos=vb.subtableColumns().antenna().positionMeas()(ant1);
761 : }
762 0 : if( timeAntIndex_p[oldMSId_p].empty()){
763 0 : Vector<Double> tOrig;
764 0 : msc.time().getColumn(tOrig);
765 0 : Vector<Double> t;
766 0 : rejectConsecutive(tOrig, t);
767 0 : Vector<uInt> uniqIndx;
768 0 : uInt nTimes=GenSortIndirect<Double>::sort (uniqIndx, t, Sort::Ascending, Sort::QuickSort|Sort::NoDuplicates);
769 0 : uInt nAnt=msc.antenna().nrow();
770 0 : const MSPointingColumns& mspc=msc.pointing();
771 0 : Vector<Double> tUniq(nTimes);
772 0 : for (uInt k=0; k <nTimes; ++k){
773 0 : tUniq[k]= t[uniqIndx[k]];
774 : }
775 : Bool tstor, timcolstor, intcolstor, antcolstor;
776 0 : Double * tuniqptr=tUniq.getStorage(tstor);
777 0 : Int cshape=cachedPointingDir_p[oldMSId_p].shape()[0];
778 0 : cachedPointingDir_p[oldMSId_p].resize(cshape+nTimes*nAnt, True);
779 0 : Vector<Double> timecol;
780 0 : Vector<Double> intervalcol;
781 0 : Vector<Int> antcol;
782 0 : mspc.time().getColumn(timecol, True);
783 0 : mspc.interval().getColumn(intervalcol, True);
784 0 : mspc.antennaId().getColumn(antcol, True);
785 0 : Double *tcolptr=timecol.getStorage(timcolstor);
786 0 : Double *intcolptr=intervalcol.getStorage(intcolstor);
787 0 : Int * antcolptr=antcol.getStorage(antcolstor);
788 0 : Int npointrow=vb.ms().pointing().nrow();
789 : //ofstream myfile;
790 : //myfile.open ("POINTING.txt", ios::trunc);
791 0 : #pragma omp parallel for firstprivate(nTimes, tuniqptr, tcolptr, antcolptr, intcolptr, npointrow, timeType, timeUnit, pos, dirframe), shared(mspc)
792 : for (uInt a=0; a < nAnt; ++a){
793 :
794 : //Double wtime1=omp_get_wtime();
795 : Vector<ssize_t> indices;
796 : //Vector<MDirection> theDirs(nTimes);
797 : pointingIndex(tcolptr, antcolptr, intcolptr, npointrow, a, nTimes, tuniqptr, indices);
798 :
799 : #pragma omp critical
800 : {
801 : MEpoch timenow(Quantity(tuniqptr[0], timeUnit),timeType);
802 : MeasFrame mframe(timenow, pos);
803 : MDirection::Convert cvt(MDirection(), MDirection::Ref(dirframe, mframe));
804 : for (uInt k=0; k <nTimes; ++k){
805 :
806 :
807 : /*std::ostringstream oss;
808 : oss.precision(13);
809 : oss << tuniqptr[k] << "_" << a;
810 : String key=oss.str();
811 : */
812 : // myfile <<std::setprecision(13) << tuniqptr[k] << "_" << a << " index "<< indices[k] << "\n";
813 : pair<double, int> key=make_pair(tuniqptr[k],a);
814 : timeAntIndex_p[oldMSId_p][key]=indices[k] > -1 ? cshape : -1;
815 :
816 : if(indices[k] >-1){
817 : timenow=MEpoch(Quantity(tuniqptr[k], timeUnit),timeType);
818 : mframe.resetEpoch(timenow);
819 : cachedPointingDir_p[oldMSId_p][cshape]=cvt(mspc.directionMeas(indices[k]));
820 :
821 : cshape+=1;
822 : }
823 :
824 :
825 : }
826 : }//end critical
827 :
828 :
829 : }
830 0 : cachedPointingDir_p[oldMSId_p].resize(cshape, True);
831 0 : }
832 :
833 0 : }
834 :
835 : /////
836 : // String index=String::toString(vb.time()(vbrow))+String("_")+String::toString(antid);
837 : /* std::ostringstream oss;
838 : oss.precision(13);
839 : oss << vb.time()(vbrow) << "_" << antid ;
840 : String index=oss.str();
841 : */
842 0 : pair<double, int> index=make_pair(vb.time()(vbrow),antid);
843 0 : rowincache=timeAntIndex_p[oldMSId_p].at(index);
844 :
845 : //tim.show("retrieved cache");
846 : }///if usepointing
847 0 : if(rowincache <0)
848 0 : return getPhaseCenter(vb);
849 0 : return cachedPointingDir_p[oldMSId_p][rowincache];
850 :
851 :
852 :
853 : }
854 :
855 0 : void VisBufferUtil::pointingIndex(Double*& timecol, Int*& antcol, Double*& intervalcol, const rownr_t nrow, const Int ant, const Int ntimes, Double*& ptime, Vector<ssize_t>& indices){
856 :
857 0 : indices.resize(ntimes);
858 :
859 0 : indices.set(-1);
860 :
861 0 : for(Int pt=0; pt < ntimes; ++pt){
862 : //cerr << " " << guessRow ;
863 :
864 : /*for (Int k=0; k< 2; ++k){
865 : Int start=guessRow;
866 : Int end=nrow;
867 : if(k==1){
868 : start=0;
869 : end=guessRow;
870 : }
871 : */
872 0 : Double nearval=1e99;
873 0 : ssize_t nearestIndx=-1;
874 0 : ssize_t start=0;
875 0 : ssize_t end=nrow;
876 0 : for (ssize_t i=start; i<end; i++) {
877 0 : if(intervalcol[i]<=0.0 && ant==antcol[i]){
878 0 : if(abs(timecol[i]-ptime[pt]) < nearval){
879 0 : nearestIndx=i;
880 0 : nearval=abs(timecol[i]-ptime[pt]);
881 : }
882 : }
883 : }
884 0 : indices[pt]=nearestIndx;
885 :
886 :
887 0 : for (ssize_t i=start; i<end; i++) {
888 0 : if(ant == antcol[i]){
889 0 : Double halfInt=0.0;
890 0 : Bool done=False;
891 0 : if(intervalcol[i]<=0.0){
892 : // if(abs(timecol[inx[i]]-ptime[pt]) < nearval){
893 : // nearestIndx=inx[i];
894 : // }
895 0 : ssize_t counter=0;
896 0 : ssize_t adder=1;
897 0 : done=False;
898 : // while(!( (timecol[i+counter]!=timecol[i]))){
899 0 : while(!done){
900 0 : counter=counter+adder;
901 0 : if((ssize_t)nrow <= i+counter){
902 0 : adder=-1;
903 0 : counter=0;
904 : }
905 : ////Could not find another point (interval is infinite) hence only 1 valid point
906 0 : if( (i+counter) < 0){
907 0 : cerr << "HIT BREAK " << endl;
908 0 : indices[pt]=i;
909 0 : break;
910 : }
911 0 : if( (antcol[i+counter]==ant && timecol[i+counter] != timecol[i]) ){
912 0 : done=True;
913 : }
914 : }
915 :
916 : //if(ant==12 && abs(timecol[i+counter]-timecol[i]) > 10.0){
917 : //cerr << "i " << i << " counter " << counter << " done " << done << " adder " << adder << "ant count "<< antcol[i+counter] << " diff " << abs(timecol[i+counter]-timecol[i]) << endl;
918 : // }
919 0 : halfInt = abs(timecol[i+counter]-timecol[i])/2.0;
920 : }
921 : else{
922 0 : halfInt = intervalcol[i]/2.0;
923 : }
924 0 : if (halfInt>0.0) {
925 :
926 0 : if ((timecol[i] >= (ptime[pt] - halfInt)) && (timecol[i] <= (ptime[pt] + halfInt))) {
927 : ////TESTOO
928 : //if(ant==12){
929 : // cerr << "timecol " << timecol[i] << " halfInt " << halfInt << " TEST " << timecol[nearestIndx] << " inx " << i << " " << nearestIndx << endl;
930 : //}
931 0 : indices[pt]=abs(timecol[i]-ptime[pt]) < nearval ? i : nearestIndx;
932 : ////////TESTOO
933 0 : if(indices[pt] > 4688000){
934 0 : cerr << indices[pt] << " timecol " << timecol[i] << " halfInt " << halfInt << " TEST " << timecol[nearestIndx] << " nearval " << nearval << " inx " << i << " " << nearestIndx << endl;
935 :
936 : }
937 : ///////////////////
938 0 : break;
939 : }
940 : } else {
941 : // valid for all times (we should also handle interval<0 -> timestamps)
942 0 : cerr << "JUMPY " << i << " ant " << ant << " halfint " << halfInt << " done "<< done << endl;
943 0 : indices[pt]=i;
944 0 : break;
945 : }
946 :
947 : }//if ant
948 : }//start end
949 :
950 : //}//k
951 :
952 : }//pt
953 :
954 : //cerr << "ant " << ant << " indices " << indices << endl;
955 0 : }
956 :
957 1212 : MDirection VisBufferUtil::getPhaseCenter(const vi::VisBuffer2& vb, const Double timeo){
958 : //Timer tim;
959 :
960 1212 : Double timeph = timeo > 0.0 ? timeo : vb.time()(0);
961 : //MDirection outdir;
962 1212 : if(oldPCMSId_p != vb.msId()){
963 3 : MSColumns msc(vb.ms());
964 : //tim.mark();
965 : //cerr << "MSID: "<< oldPCMSId_p << " " << vb.msId() << endl;
966 3 : oldPCMSId_p=vb.msId();
967 3 : if(cachedPhaseCenter_p.shape()(0) < (oldPCMSId_p+1)){
968 3 : cachedPhaseCenter_p.resize(oldPCMSId_p+1, true);
969 3 : cachedPhaseCenter_p[oldPCMSId_p]=map<Double, MDirection>();
970 : }
971 3 : if( cachedPhaseCenter_p[oldPCMSId_p].empty()){
972 3 : Vector<Double> tOrig;
973 3 : msc.time().getColumn(tOrig);
974 3 : Vector<Int> fieldId;
975 3 : msc.fieldId().getColumn(fieldId);
976 3 : Vector<Double> t;
977 3 : Vector<Int> origindx;
978 3 : rejectConsecutive(tOrig, t, origindx);
979 3 : Vector<uInt> uniqIndx;
980 :
981 3 : uInt nTimes=GenSortIndirect<Double>::sort (uniqIndx, t, Sort::Ascending, Sort::QuickSort|Sort::NoDuplicates);
982 : //cerr << "ntimes " << nTimes << " " << uniqIndx << "\n origInx " << origindx << endl;
983 3 : const MSFieldColumns& msfc=msc.field();
984 603 : for (uInt k=0; k <nTimes; ++k){
985 : //cerr << t[uniqIndx[k]] << " " << fieldId[origindx[uniqIndx[k]]] << endl;
986 : //cerr << msfc.phaseDirMeas(fieldId[origindx[uniqIndx[k]]], t[uniqIndx[k]]) << endl;
987 : //cerr << "size " << cachedPhaseCenter_p[oldPCMSId_p].size() << endl;
988 600 : String ephemIfAny=msfc.ephemPath(fieldId[origindx[uniqIndx[k]]]);
989 600 : if(ephemIfAny=="" || !Table::isReadable(ephemIfAny, False)){
990 600 : (cachedPhaseCenter_p[oldPCMSId_p])[t[uniqIndx[k]]]=msfc.phaseDirMeas(fieldId[origindx[uniqIndx[k]]], t[uniqIndx[k]]);
991 : }
992 : else{
993 0 : Vector<MDirection> refDir(msfc.referenceDirMeasCol()(fieldId[origindx[uniqIndx[k]]]));
994 0 : (cachedPhaseCenter_p[oldPCMSId_p])[t[uniqIndx[k]]]=getEphemBasedPhaseDir(vb, ephemIfAny, refDir(0), t[uniqIndx[k]]);
995 0 : }
996 :
997 600 : }
998 :
999 :
1000 3 : }
1001 : //tim.show("After caching all phasecenters");
1002 3 : }
1003 : //tim.mark();
1004 1212 : MDirection retval;
1005 1212 : auto it=cachedPhaseCenter_p[oldPCMSId_p].find(timeph);
1006 1212 : if(it != cachedPhaseCenter_p[oldPCMSId_p].end()){
1007 1212 : retval=it->second;
1008 : }
1009 : else{
1010 0 : auto upp= cachedPhaseCenter_p[oldPCMSId_p].upper_bound(timeph);
1011 0 : auto low= cachedPhaseCenter_p[oldPCMSId_p].lower_bound(timeph);
1012 0 : if (upp==cachedPhaseCenter_p[oldPCMSId_p].begin())
1013 0 : retval=(cachedPhaseCenter_p[oldPCMSId_p].begin())->second;
1014 0 : else if(low==cachedPhaseCenter_p[oldPCMSId_p].end()){
1015 0 : --low;
1016 0 : retval=low->second;
1017 : }
1018 : else{
1019 0 : if(fabs(timeph - (low->first)) < fabs(timeph - (upp->first))){
1020 0 : retval=low->second;
1021 : }
1022 : else{
1023 0 : retval=upp->second;
1024 : }
1025 :
1026 : }
1027 : }
1028 : //tim.show("retrieved cache");
1029 : //cerr << std::setprecision(12) <<"msid " << oldPCMSId_p << " time "<< timeph << " val " << retval.toString() << endl;
1030 :
1031 2424 : return retval;
1032 :
1033 :
1034 :
1035 0 : }
1036 :
1037 :
1038 6 : MDirection VisBufferUtil::getEphemBasedPhaseDir(const vi::VisBuffer2& vb, const String& ephemPath, const MDirection&refDir, const Double t){
1039 :
1040 :
1041 6 : if(!Table::isReadable(ephemPath, False))
1042 6 : return refDir;
1043 0 : if(!(vb.getVi()->getImpl())){
1044 0 : throw(AipsError("VisibilityIterator is not attached to an ms"));
1045 : }
1046 0 : MEpoch ep(Quantity(t, "s"), vb.getVi()->getImpl()->getEpoch().getRef());
1047 0 : mframe_.resetEpoch(ep);
1048 0 : MeasComet mcomet(Path(ephemPath).absoluteName());
1049 0 : mframe_.set(mcomet);
1050 0 : MDirection::Ref outref1(MDirection::AZEL, mframe_);
1051 0 : MDirection tmpazel=MDirection::Convert(MDirection(MDirection::COMET), outref1)();
1052 0 : MDirection::Types outtype=(MDirection::Types) refDir.getRef().getType();
1053 0 : MDirection::Ref outref(outtype, mframe_);
1054 0 : MDirection outdir=MDirection::Convert(tmpazel, outref)();
1055 0 : MVDirection mvoutdir(outdir.getAngle());
1056 0 : MVDirection mvrefdir(refDir.getAngle());
1057 : //copying what ROMSFieldColumns::extractDirMeas does
1058 0 : mvoutdir.shift(mvrefdir.getAngle(), True);
1059 0 : return MDirection(mvoutdir, outtype);
1060 0 : }
1061 :
1062 6 : MDirection VisBufferUtil::getEphemDir(const vi::VisBuffer2& vb,
1063 : const Double timeo){
1064 :
1065 6 : Double timeEphem = timeo > 0.0 ? timeo : vb.time()(0);
1066 6 : const MSFieldColumns &msfc = vb.subtableColumns().field();
1067 6 : Int fieldId=vb.fieldId()(0);
1068 12 : MDirection refDir(Quantity(0, "deg"), Quantity(0, "deg"),(MDirection::Types)msfc.ephemerisDirMeas(fieldId, timeEphem).getRef().getType());
1069 : //Now do the parallax correction
1070 18 : return getEphemBasedPhaseDir(vb, msfc.ephemPath(fieldId), refDir, timeEphem);
1071 :
1072 :
1073 6 : }
1074 :
1075 : //utility to reject consecutive similar value for sorting
1076 0 : void VisBufferUtil::rejectConsecutive(const Vector<Double>& t, Vector<Double>& retval){
1077 0 : uInt n=t.nelements();
1078 0 : if(n >0){
1079 0 : retval.resize(n);
1080 0 : retval[0]=t[0];
1081 : }
1082 : else
1083 0 : return;
1084 0 : Int prev=0;
1085 0 : for (uInt k=1; k < n; ++k){
1086 0 : if(t[k] != retval(prev)){
1087 0 : ++prev;
1088 :
1089 0 : retval[prev]=t[k];
1090 : }
1091 : }
1092 0 : retval.resize(prev+1, true);
1093 :
1094 : }
1095 3 : void VisBufferUtil::rejectConsecutive(const Vector<Double>& t, Vector<Double>& retval, Vector<Int>& indx){
1096 3 : uInt n=t.nelements();
1097 3 : if(n >0){
1098 3 : retval.resize(n);
1099 3 : indx.resize(n);
1100 3 : retval[0]=t[0];
1101 3 : indx[0]=0;
1102 : }
1103 : else
1104 0 : return;
1105 3 : Int prev=0;
1106 210600 : for (uInt k=1; k < n; ++k){
1107 210597 : if(t[k] != retval(prev)){
1108 597 : ++prev;
1109 : //retval.resize(prev+1, true);
1110 597 : retval[prev]=t[k];
1111 : //indx.resize(prev+1, true);
1112 597 : indx[prev]=k;
1113 : }
1114 : }
1115 3 : retval.resize(prev+1, true);
1116 3 : indx.resize(prev+1, true);
1117 :
1118 : }
1119 :
1120 : // helper function to swap the y and z axes of a Cube
1121 0 : void VisBufferUtil::swapyz(Cube<Complex>& out, const Cube<Complex>& in)
1122 : {
1123 0 : IPosition inShape=in.shape();
1124 0 : uInt nxx=inShape(0),nyy=inShape(2),nzz=inShape(1);
1125 : //resize breaks references...so out better have the right shape
1126 : //if references is not to be broken
1127 0 : if(out.nelements()==0)
1128 0 : out.resize(nxx,nyy,nzz);
1129 : Bool deleteIn,deleteOut;
1130 0 : const Complex* pin = in.getStorage(deleteIn);
1131 0 : Complex* pout = out.getStorage(deleteOut);
1132 0 : uInt i=0, zOffset=0;
1133 0 : for (uInt iz=0; iz<nzz; ++iz, zOffset+=nxx) {
1134 0 : Int yOffset=zOffset;
1135 0 : for (uInt iy=0; iy<nyy; ++iy, yOffset+=nxx*nzz) {
1136 0 : for (uInt ix=0; ix<nxx; ++ix){
1137 0 : pout[i++] = pin[ix+yOffset];
1138 : }
1139 : }
1140 : }
1141 0 : out.putStorage(pout,deleteOut);
1142 0 : in.freeStorage(pin,deleteIn);
1143 0 : }
1144 :
1145 : // helper function to swap the y and z axes of a Cube
1146 0 : void VisBufferUtil::swapyz(Cube<Bool>& out, const Cube<Bool>& in)
1147 : {
1148 0 : IPosition inShape=in.shape();
1149 0 : uInt nxx=inShape(0),nyy=inShape(2),nzz=inShape(1);
1150 0 : if(out.nelements()==0)
1151 0 : out.resize(nxx,nyy,nzz);
1152 : Bool deleteIn,deleteOut;
1153 0 : const Bool* pin = in.getStorage(deleteIn);
1154 0 : Bool* pout = out.getStorage(deleteOut);
1155 0 : uInt i=0, zOffset=0;
1156 0 : for (uInt iz=0; iz<nzz; iz++, zOffset+=nxx) {
1157 0 : Int yOffset=zOffset;
1158 0 : for (uInt iy=0; iy<nyy; iy++, yOffset+=nxx*nzz) {
1159 0 : for (uInt ix=0; ix<nxx; ix++) pout[i++] = pin[ix+yOffset];
1160 : }
1161 : }
1162 0 : out.putStorage(pout,deleteOut);
1163 0 : in.freeStorage(pin,deleteIn);
1164 0 : }
1165 :
1166 :
1167 :
1168 :
1169 : } //# NAMESPACE CASA - END
1170 :
|