source: trunk/src/STApplyCal.cpp@ 3059

Last change on this file since 3059 was 3021, checked in by Takeshi Nakazato, 10 years ago

New Development: No

JIRA Issue: Yes CAS-7193

Ready for Test: Yes

Interface Changes: Yes/No

What Interface Changed: Please list interface changes

Test Programs: test_sdcal2

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Fix for proper flag handling when input applytables are invalid/empty.

File size: 23.8 KB
RevLine 
[2720]1//
2// C++ Implementation: STApplyCal
3//
4// Description:
5//
6//
7// Author: Takeshi Nakazato <takeshi.nakazato@nao.ac.jp> (C) 2012
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
[2722]12#include <assert.h>
[2720]13
14#include <casa/Arrays/Array.h>
15#include <casa/Arrays/Vector.h>
16#include <casa/Arrays/Matrix.h>
17#include <casa/Arrays/ArrayIO.h>
18#include <casa/Arrays/ArrayMath.h>
19#include <casa/BasicSL/String.h>
20#include <casa/Logging/LogIO.h>
21#include <casa/Exceptions/Error.h>
22#include <casa/Utilities/CountedPtr.h>
23#include <casa/Utilities/Sort.h>
[2756]24#include <casa/Utilities/Assert.h>
[2720]25#include <tables/Tables/Table.h>
26
27#include "Scantable.h"
28#include "STApplyCal.h"
29#include "STApplyTable.h"
30#include "STCalTsysTable.h"
31#include "STCalSkyTable.h"
32#include "STCalEnum.h"
33#include "STIdxIter.h"
34#include "Calibrator.h"
35#include "PSAlmaCalibrator.h"
[2733]36#include "Interpolator1D.h"
[2720]37#include "NearestInterpolator1D.h"
[2727]38#include "BufferedLinearInterpolator1D.h"
39#include "PolynomialInterpolator1D.h"
40#include "CubicSplineInterpolator1D.h"
[2720]41#include <atnf/PKSIO/SrcType.h>
42
43
44using namespace casa;
45using namespace std;
46
[2963]47namespace {
[2964]48template<class Accessor, class Type>
49class AccessorInterface
[2963]50{
[2964]51public:
52 typedef Type TableType;
53 static void GetSortedData(const vector<TableType *> &tablelist,
54 const Vector<uInt> &tableIndex,
55 const uInt nrow,
56 const uInt nchan,
57 Vector<Double> &time,
58 Matrix<Float> &data,
59 Matrix<uChar> &flag)
60 {
61 Vector<Double> timeUnsorted;
62 Matrix<Float> dataUnsorted;
63 Matrix<uChar> flagUnsorted;
64 GetFromTable(tablelist, tableIndex, nrow, nchan,
65 timeUnsorted, dataUnsorted, flagUnsorted);
66 SortData(timeUnsorted, dataUnsorted, flagUnsorted,
67 time, data, flag);
68 }
69private:
70 static void GetFromTable(const vector<TableType *> &tableList,
71 const Vector<uInt> &tableIndex,
72 const uInt nrow,
73 const uInt nchan,
74 Vector<Double> &time,
75 Matrix<Float> &data,
76 Matrix<uChar> &flag)
77 {
78 time.resize(nrow, False);
79 const IPosition shape(2, nrow, nchan);
80 data.resize(shape, False);
81 flag.resize(shape, False);
82 uInt rowIndex = 0;
83 for (uInt i = 0 ; i < tableIndex.nelements(); i++) {
84 TableType *p = tableList[tableIndex[i]];
85 Vector<Double> t = Accessor::GetTime(p);
86 Matrix<Float> dt = Accessor::GetData(p);
87 Matrix<uChar> fl = Accessor::GetFlag(p);
88 for (uInt j = 0; j < t.nelements(); j++) {
89 time[rowIndex] = t[j];
90 data.row(rowIndex) = dt.column(j);
91 flag.row(rowIndex) = fl.column(j);
92 rowIndex++;
93 }
94 }
95 }
[2963]96
[2964]97 static Vector<uInt> IndexSort(const Vector<Double> &t)
98 {
99 Sort sort;
100 sort.sortKey(&t[0], TpDouble, 0, Sort::Ascending);
101 Vector<uInt> idx;
102 sort.sort(idx, t.nelements(), Sort::QuickSort|Sort::NoDuplicates);
103 return idx;
104 }
105
106 static void SortData(const Vector<Double> &key, const Matrix<Float> &data,
107 const Matrix<uChar> &flag,
108 Vector<Double> &sortedKey, Matrix<Float> &sortedData,
109 Matrix<uChar> &sortedFlag)
110 {
111 Vector<uInt> sortIndex = IndexSort(key);
112 uInt len = sortIndex.nelements();
113 IPosition shape = data.shape();
114 shape[0] = len;
115 Int64 nelements = shape.product();
116 sortedKey.takeStorage(IPosition(1, len), new Double[len], TAKE_OVER);
117 sortedData.takeStorage(shape, new Float[nelements], TAKE_OVER);
118 sortedFlag.takeStorage(shape, new uChar[nelements], TAKE_OVER);
119 for (uInt i = 0 ; i < len; i++) {
120 sortedKey[i] = key[sortIndex[i]];
121 }
122 for (uInt i = 0; i < len; ++i) {
123 sortedData.row(i) = data.row(sortIndex[i]);
124 sortedFlag.row(i) = flag.row(sortIndex[i]);
125 }
126 }
127
128};
129
130class SkyTableAccessor : public AccessorInterface<SkyTableAccessor, asap::STCalSkyTable>
[2963]131{
[2964]132public:
133 static Vector<Double> GetTime(const TableType *t) {return t->getTime();}
134 static Matrix<Float> GetData(const TableType *t) {return t->getSpectra();}
135 static Matrix<uChar> GetFlag(const TableType *t) {return t->getFlagtra();}
136};
137
138class TsysTableAccessor : public AccessorInterface<TsysTableAccessor, asap::STCalTsysTable>
139{
140public:
141 static Vector<Double> GetTime(const TableType *t) {return t->getTime();}
142 static Matrix<Float> GetData(const TableType *t) {return t->getTsys();}
143 static Matrix<uChar> GetFlag(const TableType *t) {return t->getFlagtra();}
144};
[2965]145
146inline uInt setupWorkingData(const uInt n, const Double *xin, const Float *yin,
147 const uChar *f, Double *xout, Float *yout)
148{
149 uInt nValid = 0;
150 for (uInt i = 0; i < n; ++i) {
151 if (f[i] == 0) {
152 xout[nValid] = xin[i];
153 yout[nValid] = yin[i];
154 nValid++;
155 }
156 }
157 return nValid;
[2963]158}
159
[2965]160template<class InterpolationHelperImpl>
161class InterpolationHelperInterface
162{
163public:
164 static void Interpolate(const Double xref, const uInt nx, const uInt ny,
165 Double *xin, Float *yin, uChar *fin,
166 asap::Interpolator1D<Double, Float> *interpolator,
167 Double *xwork, Float *ywork,
168 Float *yout, uChar *fout)
169 {
170 for (uInt i = 0; i < ny; i++) {
171 Float *tmpY = &(yin[i * nx]);
172 uInt wnrow = setupWorkingData(nx, xin, tmpY, &(fin[i * nx]), xwork, ywork);
173 if (wnrow > 0) {
174 // any valid reference data
175 InterpolationHelperImpl::ProcessValid(xref, i, interpolator,
176 xwork, ywork, wnrow,
177 yout, fout);
178 }
179 else {
180 // no valid reference data
181 InterpolationHelperImpl::ProcessInvalid(xref, i, interpolator,
182 xin, tmpY, nx,
183 yout, fout);
184 }
185 }
186 }
187};
188
189class SkyInterpolationHelper : public InterpolationHelperInterface<SkyInterpolationHelper>
190{
191public:
192 static void ProcessValid(const Double xref, const uInt index,
193 asap::Interpolator1D<Double, Float> *interpolator,
194 Double *xwork, Float *ywork,
195 const uInt wnrow, Float *yout, uChar *fout)
196 {
197 interpolator->setData(xwork, ywork, wnrow);
198 yout[index] = interpolator->interpolate(xref);
199 }
200 static void ProcessInvalid(const Double xref, const uInt index,
201 asap::Interpolator1D<Double, Float> *interpolator,
202 Double *xwork, Float *ywork,
203 const uInt wnrow, Float *yout, uChar *fout)
204 {
205 // interpolate data regardless of flag
206 ProcessValid(xref, index, interpolator, xwork, ywork, wnrow, yout, fout);
207 // flag this channel for calibrated data
208 fout[index] = 1 << 7; // user flag
209 }
210};
211
212class TsysInterpolationHelper : public InterpolationHelperInterface<TsysInterpolationHelper>
213{
214public:
215 static void ProcessValid(const Double xref, const uInt index,
216 asap::Interpolator1D<Double, Float> *interpolator,
217 Double *xwork, Float *ywork,
218 const uInt wnrow, Float *yout, uChar *fout)
219 {
220 interpolator->setData(xwork, ywork, wnrow);
221 yout[index] = interpolator->interpolate(xref);
222 fout[index] = 0;
223 }
224 static void ProcessInvalid(const Double xref, const uInt index,
225 asap::Interpolator1D<Double, Float> *interpolator,
226 Double *xwork, Float *ywork,
227 const uInt wnrow, Float *yout, uChar *fout)
228 {
229 fout[index] = 1 << 7; // user flag
230 }
231};
[3021]232
233inline void flagSpectrum(uInt &flagrow, Vector<uChar> &flagchan) {
234 flagrow = 1;
235 flagchan = (uChar)(1 << 7);
[2965]236}
237
[3021]238inline void flagSpectra(Table &tab, const Vector<uInt> &rows) {
239 //os_ << LogIO::WARN << "No valid sky data in sky caltable. Completely flag Beam " << beamno << " Spw " << ifno << " Pol " << polno << LogIO::POST;
240 // Given sky tables are all empty
241 // So, flag all data
242 //Table tab = work_->table();
243 ArrayColumn<uChar> flCol(tab, "FLAGTRA");
244 ScalarColumn<uInt> frCol(tab, "FLAGROW");
245 Vector<uChar> flag;
246 uInt flagrow;
247 for (uInt i = 0; i < rows.nelements(); i++) {
248 uInt irow = rows[i];
249 flCol.get(irow, flag);
250 frCol.get(irow, flagrow);
251 flagSpectrum(flagrow, flag);
252 //flag = (uChar)(1 << 7);
253 flCol.put(irow, flag);
254 frCol.put(irow, flagrow);
255 }
256}
257
258}
259
[2720]260namespace asap {
261STApplyCal::STApplyCal()
262{
263 init();
264}
265
266STApplyCal::STApplyCal(CountedPtr<Scantable> target)
267 : target_(target)
268{
269 init();
270}
271
272STApplyCal::~STApplyCal()
273{
274}
275
276void STApplyCal::init()
277{
278 caltype_ = STCalEnum::NoType;
279 doTsys_ = False;
[2742]280 iTime_ = STCalEnum::DefaultInterpolation;
281 iFreq_ = STCalEnum::DefaultInterpolation;
[2720]282}
283
[2735]284void STApplyCal::reset()
285{
[2742]286 // call init
287 init();
288
289 // clear apply tables
290 // do not delete object here
291 skytable_.resize(0);
292 tsystable_.resize(0);
293
294 // clear mapping for Tsys transfer
295 spwmap_.clear();
296
297 // reset selector
298 sel_.reset();
299
300 // delete interpolators
301 interpolatorT_ = 0;
302 interpolatorS_ = 0;
303 interpolatorF_ = 0;
304
305 // clear working scantable
306 work_ = 0;
307
308 // clear calibrator
309 calibrator_ = 0;
[2735]310}
311
312void STApplyCal::completeReset()
313{
314 reset();
315 target_ = 0;
316}
317
[2720]318void STApplyCal::setTarget(CountedPtr<Scantable> target)
319{
320 target_ = target;
321}
322
323void STApplyCal::setTarget(const String &name)
324{
325 // always create PlainTable
326 target_ = new Scantable(name, Table::Plain);
327}
328
329void STApplyCal::push(STCalSkyTable *table)
330{
[2735]331 os_.origin(LogOrigin("STApplyCal","push",WHERE));
[2720]332 skytable_.push_back(table);
333 STCalEnum::CalType caltype = STApplyTable::getCalType(table);
334 os_ << "caltype=" << caltype << LogIO::POST;
335 if (caltype_ == STCalEnum::NoType ||
336 caltype_ == STCalEnum::DefaultType ||
337 caltype_ == STCalEnum::CalTsys) {
338 caltype_ = caltype;
339 }
340 os_ << "caltype_=" << caltype_ << LogIO::POST;
341}
342
343void STApplyCal::push(STCalTsysTable *table)
344{
345 tsystable_.push_back(table);
346 doTsys_ = True;
347}
348
[2735]349void STApplyCal::setTimeInterpolation(STCalEnum::InterpolationType itype, Int order)
[2720]350{
[2735]351 iTime_ = itype;
[2720]352 order_ = order;
353}
354
[2735]355void STApplyCal::setFrequencyInterpolation(STCalEnum::InterpolationType itype, Int order)
356{
357 iFreq_ = itype;
358 order_ = order;
359}
360
[2720]361void STApplyCal::setTsysTransfer(uInt from, Vector<uInt> to)
362{
[2735]363 os_.origin(LogOrigin("STApplyCal","setTsysTransfer",WHERE));
[2720]364 os_ << "from=" << from << ", to=" << to << LogIO::POST;
365 map<uInt, Vector<uInt> >::iterator i = spwmap_.find(from);
366 if (i == spwmap_.end()) {
367 spwmap_.insert(pair<uInt, Vector<uInt> >(from, to));
368 }
369 else {
370 Vector<uInt> toNew = i->second;
371 spwmap_.erase(i);
372 uInt k = toNew.nelements();
373 toNew.resize(k+to.nelements(), True);
374 for (uInt i = 0; i < to.nelements(); i++)
375 toNew[i+k] = to[i];
376 spwmap_.insert(pair<uInt, Vector<uInt> >(from, toNew));
377 }
378}
379
[2742]380void STApplyCal::apply(Bool insitu, Bool filltsys)
[2720]381{
[2735]382 os_.origin(LogOrigin("STApplyCal","apply",WHERE));
[2750]383
[2756]384 //assert(!target_.null());
385 assert_<AipsError>(!target_.null(),"You have to set target scantable first.");
[2750]386
[2720]387 // calibrator
388 if (caltype_ == STCalEnum::CalPSAlma)
389 calibrator_ = new PSAlmaCalibrator();
390
391 // interpolator
[2727]392 initInterpolator();
[2720]393
394 // select data
395 sel_.reset();
[2806]396 sel_ = target_->getSelection();
[2720]397 if (caltype_ == STCalEnum::CalPSAlma ||
398 caltype_ == STCalEnum::CalPS) {
399 sel_.setTypes(vector<int>(1,(int)SrcType::PSON));
400 }
401 target_->setSelection(sel_);
402
[2735]403 //os_ << "sel_.print()=" << sel_.print() << LogIO::POST;
[2720]404
405 // working data
[2750]406 if (insitu) {
407 os_.origin(LogOrigin("STApplyCal","apply",WHERE));
408 os_ << "Overwrite input scantable" << LogIO::POST;
[2720]409 work_ = target_;
[2750]410 }
411 else {
412 os_.origin(LogOrigin("STApplyCal","apply",WHERE));
413 os_ << "Create output scantable from input" << LogIO::POST;
[2720]414 work_ = new Scantable(*target_, false);
[2750]415 }
[2720]416
[2735]417 //os_ << "work_->nrow()=" << work_->nrow() << LogIO::POST;
[2720]418
419 // list of apply tables for sky calibration
[2928]420 Vector<uInt> skycalList(skytable_.size());
[2720]421 uInt numSkyCal = 0;
[2735]422
[2720]423 // list of apply tables for Tsys calibration
424 for (uInt i = 0 ; i < skytable_.size(); i++) {
425 STCalEnum::CalType caltype = STApplyTable::getCalType(skytable_[i]);
426 if (caltype == caltype_) {
427 skycalList[numSkyCal] = i;
428 numSkyCal++;
429 }
430 }
[2928]431 skycalList.resize(numSkyCal, True);
[2720]432
433
434 vector<string> cols( 3 ) ;
435 cols[0] = "BEAMNO" ;
436 cols[1] = "POLNO" ;
437 cols[2] = "IFNO" ;
[2916]438 CountedPtr<STIdxIter2> iter = new STIdxIter2(work_, cols) ;
[2925]439 double start = mathutil::gettimeofday_sec();
440 os_ << LogIO::DEBUGGING << "start iterative doapply: " << start << LogIO::POST;
[2720]441 while (!iter->pastEnd()) {
[2916]442 Record ids = iter->currentValue();
[2720]443 Vector<uInt> rows = iter->getRows(SHARE);
444 if (rows.nelements() > 0)
[2916]445 doapply(ids.asuInt("BEAMNO"), ids.asuInt("IFNO"), ids.asuInt("POLNO"), rows, skycalList, filltsys);
[2720]446 iter->next();
447 }
[2925]448 double end = mathutil::gettimeofday_sec();
449 os_ << LogIO::DEBUGGING << "end iterative doapply: " << end << LogIO::POST;
450 os_ << LogIO::DEBUGGING << "elapsed time for doapply: " << end - start << " sec" << LogIO::POST;
[2720]451
452 target_->unsetSelection();
453}
454
455void STApplyCal::doapply(uInt beamno, uInt ifno, uInt polno,
456 Vector<uInt> &rows,
[2742]457 Vector<uInt> &skylist,
458 Bool filltsys)
[2720]459{
[2735]460 os_.origin(LogOrigin("STApplyCal","doapply",WHERE));
[2720]461 Bool doTsys = doTsys_;
462
463 STSelector sel;
464 vector<int> id(1);
465 id[0] = beamno;
466 sel.setBeams(id);
467 id[0] = ifno;
468 sel.setIFs(id);
469 id[0] = polno;
470 sel.setPolarizations(id);
471
472 // apply selection to apply tables
[2964]473 uInt nrowSkyTotal = 0;
474 uInt nrowTsysTotal = 0;
[2720]475 for (uInt i = 0; i < skylist.nelements(); i++) {
476 skytable_[skylist[i]]->setSelection(sel);
[2964]477 nrowSkyTotal += skytable_[skylist[i]]->nrow();
478 os_ << "nrowSkyTotal=" << nrowSkyTotal << LogIO::POST;
[2720]479 }
[2806]480
481 // Skip IFNO without sky data
[3021]482 if (nrowSkyTotal == 0) {
483 if (skytable_.size() > 0) {
484 os_ << LogIO::WARN << "No data in sky caltable. Completely flag Beam " << beamno << " Spw " << ifno << " Pol " << polno << LogIO::POST;
485 // Given sky tables are all empty
486 // So, flag all data
487 flagSpectra(work_->table(), rows);
488 }
[2806]489 return;
[3021]490 }
[2806]491
[2720]492 uInt nchanTsys = 0;
493 Vector<Double> ftsys;
494 uInt tsysifno = getIFForTsys(ifno);
[3021]495 Bool onlyInvalidTsys = False;
[2758]496 os_ << "tsysifno=" << (Int)tsysifno << LogIO::POST;
[2720]497 if (tsystable_.size() == 0) {
498 os_.origin(LogOrigin("STApplyTable", "doapply", WHERE));
499 os_ << "No Tsys tables are given. Skip Tsys calibratoin." << LogIO::POST;
500 doTsys = False;
501 }
502 else if (tsysifno == (uInt)-1) {
503 os_.origin(LogOrigin("STApplyTable", "doapply", WHERE));
504 os_ << "No corresponding Tsys for IFNO " << ifno << ". Skip Tsys calibration" << LogIO::POST;
505 doTsys = False;
506 }
507 else {
508 id[0] = (int)tsysifno;
509 sel.setIFs(id);
510 for (uInt i = 0; i < tsystable_.size() ; i++) {
511 tsystable_[i]->setSelection(sel);
[2848]512 uInt nrowThisTsys = tsystable_[i]->nrow();
[2964]513 nrowTsysTotal += nrowThisTsys;
[2963]514 if (nrowThisTsys > 0 && nchanTsys == 0) {
[2848]515 nchanTsys = tsystable_[i]->nchan(tsysifno);
516 ftsys = tsystable_[i]->getBaseFrequency(0);
517 }
[2720]518 }
[3021]519 if (nrowTsysTotal == 0) {
520 os_ << "No valid Tsys measurement. for Beam " << beamno << " Spw " << ifno << " Pol " << polno << ". Skip Tsys calibration." << LogIO::POST;
521 doTsys = False;
522 onlyInvalidTsys = True;
523 }
[2720]524 }
525
526 uInt nchanSp = skytable_[skylist[0]]->nchan(ifno);
[2964]527 uInt nrowSky = nrowSkyTotal;
528 Vector<Double> timeSky;
529 Matrix<Float> spoff;
530 Matrix<uChar> flagoff;
531 SkyTableAccessor::GetSortedData(skytable_, skylist,
532 nrowSkyTotal, nchanSp,
533 timeSky, spoff, flagoff);
[3021]534 if (allNE(flagoff, (uChar)0)) {
535 os_ << LogIO::WARN << "No valid sky data in sky caltable. Completely flag Beam " << beamno << " Spw " << ifno << " Pol " << polno << LogIO::POST;
536 // Given sky tables are all invalid
537 // So, flag all data
538 flagSpectra(work_->table(), rows);
539 }
[2964]540 nrowSky = timeSky.nelements();
[2720]541
[2964]542 uInt nrowTsys = nrowTsysTotal;
543 Vector<Double> timeTsys;
544 Matrix<Float> tsys;
545 Matrix<uChar> flagtsys;
[2720]546 if (doTsys) {
[2758]547 //os_ << "doTsys" << LogIO::POST;
[2964]548 Vector<uInt> tsyslist(tsystable_.size());
549 indgen(tsyslist);
550 TsysTableAccessor::GetSortedData(tsystable_, tsyslist,
551 nrowTsysTotal, nchanTsys,
552 timeTsys, tsys, flagtsys);
553 nrowTsys = timeTsys.nelements();
[3020]554
555 if (allNE(flagtsys, (uChar)0)) {
[3021]556 os_ << LogIO::WARN << "No valid Tsys measurement for Beam " << beamno << " Spw " << ifno << " Pol " << polno << ". Skip Tsys calibration." << LogIO::POST;
[3020]557 doTsys = False;
[3021]558 onlyInvalidTsys = True;
[3020]559 }
[2720]560 }
561
562 Table tab = work_->table();
563 ArrayColumn<Float> spCol(tab, "SPECTRA");
[2960]564 ArrayColumn<uChar> flCol(tab, "FLAGTRA");
[2735]565 ArrayColumn<Float> tsysCol(tab, "TSYS");
[2720]566 ScalarColumn<Double> timeCol(tab, "TIME");
[3021]567 ScalarColumn<uInt> frCol(tab, "FLAGROW");
[2925]568
569 // Array for scaling factor (aka Tsys)
[2928]570 Vector<Float> iTsys(IPosition(1, nchanSp), new Float[nchanSp], TAKE_OVER);
571 // Array for Tsys interpolation
572 // This is empty array and is never referenced if doTsys == false
573 // (i.e. nchanTsys == 0)
574 Vector<Float> iTsysT(IPosition(1, nchanTsys), new Float[nchanTsys], TAKE_OVER);
575
576 // Array for interpolated off spectrum
577 Vector<Float> iOff(IPosition(1, nchanSp), new Float[nchanSp], TAKE_OVER);
[2963]578
579 // working array for interpolation with flags
[2964]580 uInt arraySize = max(max(nrowTsys, nchanTsys), nrowSky);
[2963]581 Vector<Double> xwork(IPosition(1, arraySize), new Double[arraySize], TAKE_OVER);
582 Vector<Float> ywork(IPosition(1, arraySize), new Float[arraySize], TAKE_OVER);
583 Vector<uChar> fwork(IPosition(1, nchanTsys), new uChar[nchanTsys], TAKE_OVER);
[2965]584
585 // data array
586 Vector<Float> on(IPosition(1, nchanSp), new Float[nchanSp], TAKE_OVER);
587 Vector<uChar> flag(on.shape(), new uChar[on.shape().product()], TAKE_OVER);
[2925]588
[2720]589 for (uInt i = 0; i < rows.nelements(); i++) {
[2758]590 //os_ << "start i = " << i << " (row = " << rows[i] << ")" << LogIO::POST;
[2720]591 uInt irow = rows[i];
592
593 // target spectral data
[2965]594 spCol.get(irow, on);
595 flCol.get(irow, flag);
[3021]596 uInt flagrow = frCol(irow);
[2862]597 //os_ << "on=" << on[0] << LogIO::POST;
[2720]598 calibrator_->setSource(on);
599
600 // interpolation
[2733]601 Double t0 = timeCol(irow);
[2963]602 Double *xwork_p = xwork.data();
603 Float *ywork_p = ywork.data();
[2965]604 SkyInterpolationHelper::Interpolate(t0, nrowSky, nchanSp,
605 timeSky.data(), spoff.data(),
606 flagoff.data(), &(*interpolatorS_),
607 xwork_p, ywork_p,
608 iOff.data(), flag.data());
[2720]609 calibrator_->setReference(iOff);
610
611 if (doTsys) {
612 // Tsys correction
[2963]613 // interpolation on time axis
[2965]614 TsysInterpolationHelper::Interpolate(t0, nrowTsys, nchanTsys,
615 timeTsys.data(), tsys.data(),
616 flagtsys.data(), &(*interpolatorT_),
617 xwork_p, ywork_p,
618 iTsysT.data(), fwork.data());
[2963]619 uChar *fwork_p = fwork.data();
[2720]620 if (nchanSp == 1) {
621 // take average
622 iTsys[0] = mean(iTsysT);
623 }
624 else {
625 // interpolation on frequency axis
626 Vector<Double> fsp = getBaseFrequency(rows[i]);
[2965]627 uInt wnchan = setupWorkingData(nchanTsys, ftsys.data(), iTsysT.data(),
628 fwork_p, xwork_p, ywork_p);
[3020]629 assert(wnchan > 0);
630 if (wnchan == 0) {
631 throw AipsError("No valid Tsys measurements.");
632 }
[2963]633 interpolatorF_->setData(xwork_p, ywork_p, wnchan);
[3020]634 for (uInt ichan = 0; ichan < nchanSp; ichan++) {
[2733]635 iTsys[ichan] = interpolatorF_->interpolate(fsp[ichan]);
[2720]636 }
637 }
638 }
639 else {
[2759]640 Vector<Float> tsysInRow = tsysCol(irow);
641 if (tsysInRow.nelements() == 1) {
642 iTsys = tsysInRow[0];
643 }
644 else {
[2862]645 for (uInt ichan = 0; ichan < tsysInRow.nelements(); ++ichan)
[2759]646 iTsys[ichan] = tsysInRow[ichan];
647 }
[2720]648 }
[2862]649 //os_ << "iTsys=" << iTsys[0] << LogIO::POST;
[2720]650 calibrator_->setScaler(iTsys);
651
652 // do calibration
653 calibrator_->calibrate();
654
[3021]655 // flag spectrum if no valid Tsys measurement available
656 if (onlyInvalidTsys) {
657 flagSpectrum(flagrow, flag);
658 }
659
[2720]660 // update table
[2862]661 //os_ << "calibrated=" << calibrator_->getCalibrated()[0] << LogIO::POST;
[2720]662 spCol.put(irow, calibrator_->getCalibrated());
[2960]663 flCol.put(irow, flag);
[3021]664 frCol.put(irow, flagrow);
665 if (filltsys && !onlyInvalidTsys)
[2742]666 tsysCol.put(irow, iTsys);
[2720]667 }
668
669
670 // reset selection on apply tables
671 for (uInt i = 0; i < skylist.nelements(); i++)
672 skytable_[i]->unsetSelection();
673 for (uInt i = 0; i < tsystable_.size(); i++)
674 tsystable_[i]->unsetSelection();
675
676
677 // reset interpolator
678 interpolatorS_->reset();
679 interpolatorF_->reset();
680 interpolatorT_->reset();
681}
682
683uInt STApplyCal::getIFForTsys(uInt to)
684{
685 for (map<casa::uInt, Vector<uInt> >::iterator i = spwmap_.begin();
686 i != spwmap_.end(); i++) {
687 Vector<uInt> tolist = i->second;
[2735]688 os_ << "from=" << i->first << ": tolist=" << tolist << LogIO::POST;
[2720]689 for (uInt j = 0; j < tolist.nelements(); j++) {
690 if (tolist[j] == to)
691 return i->first;
692 }
693 }
694 return (uInt)-1;
695}
696
697void STApplyCal::save(const String &name)
698{
[2756]699 //assert(!work_.null());
700 assert_<AipsError>(!work_.null(),"You have to execute apply method first.");
[2720]701
702 work_->setSelection(sel_);
703 work_->makePersistent(name);
704 work_->unsetSelection();
705}
706
707Vector<Double> STApplyCal::getBaseFrequency(uInt whichrow)
708{
[2756]709 //assert(whichrow <= (uInt)work_->nrow());
710 assert_<AipsError>(whichrow <= (uInt)work_->nrow(),"row index out of range.");
[2720]711 ROTableColumn col(work_->table(), "IFNO");
712 uInt ifno = col.asuInt(whichrow);
713 col.attach(work_->table(), "FREQ_ID");
714 uInt freqid = col.asuInt(whichrow);
715 uInt nc = work_->nchan(ifno);
716 STFrequencies ftab = work_->frequencies();
717 Double rp, rf, inc;
718 ftab.getEntry(rp, rf, inc, freqid);
719 Vector<Double> r(nc);
720 indgen(r, rf-rp*inc, inc);
721 return r;
722}
723
[2727]724void STApplyCal::initInterpolator()
725{
[2735]726 os_.origin(LogOrigin("STApplyCal","initInterpolator",WHERE));
[2727]727 int order = (order_ > 0) ? order_ : 1;
[2735]728 switch (iTime_) {
[2727]729 case STCalEnum::NearestInterpolation:
730 {
731 os_ << "use NearestInterpolator in time axis" << LogIO::POST;
[2733]732 interpolatorS_ = new NearestInterpolator1D<Double, Float>();
733 interpolatorT_ = new NearestInterpolator1D<Double, Float>();
[2727]734 break;
735 }
736 case STCalEnum::LinearInterpolation:
737 {
738 os_ << "use BufferedLinearInterpolator in time axis" << LogIO::POST;
[2733]739 interpolatorS_ = new BufferedLinearInterpolator1D<Double, Float>();
740 interpolatorT_ = new BufferedLinearInterpolator1D<Double, Float>();
[2727]741 break;
742 }
743 case STCalEnum::CubicSplineInterpolation:
744 {
745 os_ << "use CubicSplineInterpolator in time axis" << LogIO::POST;
[2733]746 interpolatorS_ = new CubicSplineInterpolator1D<Double, Float>();
747 interpolatorT_ = new CubicSplineInterpolator1D<Double, Float>();
[2727]748 break;
749 }
750 case STCalEnum::PolynomialInterpolation:
751 {
752 os_ << "use PolynomialInterpolator in time axis" << LogIO::POST;
753 if (order == 0) {
[2733]754 interpolatorS_ = new NearestInterpolator1D<Double, Float>();
755 interpolatorT_ = new NearestInterpolator1D<Double, Float>();
[2727]756 }
757 else {
[2733]758 interpolatorS_ = new PolynomialInterpolator1D<Double, Float>();
759 interpolatorT_ = new PolynomialInterpolator1D<Double, Float>();
[2727]760 interpolatorS_->setOrder(order);
761 interpolatorT_->setOrder(order);
762 }
763 break;
764 }
765 default:
766 {
767 os_ << "use BufferedLinearInterpolator in time axis" << LogIO::POST;
[2733]768 interpolatorS_ = new BufferedLinearInterpolator1D<Double, Float>();
769 interpolatorT_ = new BufferedLinearInterpolator1D<Double, Float>();
[2727]770 break;
771 }
772 }
773
[2735]774 switch (iFreq_) {
[2727]775 case STCalEnum::NearestInterpolation:
776 {
777 os_ << "use NearestInterpolator in frequency axis" << LogIO::POST;
[2733]778 interpolatorF_ = new NearestInterpolator1D<Double, Float>();
[2727]779 break;
780 }
781 case STCalEnum::LinearInterpolation:
782 {
783 os_ << "use BufferedLinearInterpolator in frequency axis" << LogIO::POST;
[2733]784 interpolatorF_ = new BufferedLinearInterpolator1D<Double, Float>();
[2727]785 break;
786 }
787 case STCalEnum::CubicSplineInterpolation:
788 {
789 os_ << "use CubicSplineInterpolator in frequency axis" << LogIO::POST;
[2733]790 interpolatorF_ = new CubicSplineInterpolator1D<Double, Float>();
[2727]791 break;
792 }
793 case STCalEnum::PolynomialInterpolation:
794 {
795 os_ << "use PolynomialInterpolator in frequency axis" << LogIO::POST;
796 if (order == 0) {
[2733]797 interpolatorF_ = new NearestInterpolator1D<Double, Float>();
[2727]798 }
799 else {
[2733]800 interpolatorF_ = new PolynomialInterpolator1D<Double, Float>();
[2727]801 interpolatorF_->setOrder(order);
802 }
803 break;
804 }
805 default:
806 {
807 os_ << "use LinearInterpolator in frequency axis" << LogIO::POST;
[2733]808 interpolatorF_ = new BufferedLinearInterpolator1D<Double, Float>();
[2727]809 break;
810 }
811 }
[2720]812}
[2963]813
[2727]814}
Note: See TracBrowser for help on using the repository browser.