source: trunk/src/STApplyCal.cpp @ 3106

Last change on this file since 3106 was 3106, checked in by Takeshi Nakazato, 8 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes/No?

Interface Changes: Yes/No?

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No?

Module(s): Module Names change impacts.

Description: Describe your changes here...


Check-in asap modifications from Jim regarding casacore namespace conversion.

File size: 23.9 KB
Line 
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//
12#include <assert.h>
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>
24#include <casa/Utilities/Assert.h>
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"
36#include "Interpolator1D.h"
37#include "NearestInterpolator1D.h"
38#include "BufferedLinearInterpolator1D.h"
39#include "PolynomialInterpolator1D.h"
40#include "CubicSplineInterpolator1D.h"
41#include <atnf/PKSIO/SrcType.h>
42
43
44using namespace casacore;
45using namespace std;
46
47namespace {
48template<class Accessor, class Type>
49class AccessorInterface
50{
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  }
96
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>
131{
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};
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;
158}
159
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};
232
233inline void flagSpectrum(uInt &flagrow, Vector<uChar> &flagchan) {
234  flagrow = 1;
235  flagchan = (uChar)(1 << 7);
236}
237
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
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;
280  iTime_ = STCalEnum::DefaultInterpolation;
281  iFreq_ = STCalEnum::DefaultInterpolation;
282}
283
284void STApplyCal::reset()
285{
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;
310}
311
312void STApplyCal::completeReset()
313{
314  reset();
315  target_ = 0;
316}
317
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{
331  os_.origin(LogOrigin("STApplyCal","push",WHERE));
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
349void STApplyCal::setTimeInterpolation(STCalEnum::InterpolationType itype, Int order)
350{
351  iTime_ = itype;
352  order_ = order;
353}
354
355void STApplyCal::setFrequencyInterpolation(STCalEnum::InterpolationType itype, Int order)
356{
357  iFreq_ = itype;
358  order_ = order;
359}
360
361void STApplyCal::setTsysTransfer(uInt from, Vector<uInt> to)
362{
363  os_.origin(LogOrigin("STApplyCal","setTsysTransfer",WHERE));
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
380void STApplyCal::apply(Bool insitu, Bool filltsys)
381{
382  os_.origin(LogOrigin("STApplyCal","apply",WHERE));
383 
384  //assert(!target_.null());
385  assert_<AipsError>(!target_.null(),"You have to set target scantable first.");
386
387  // calibrator
388  if (caltype_ == STCalEnum::CalPSAlma)
389    calibrator_ = new PSAlmaCalibrator();
390
391  // interpolator
392  initInterpolator();
393
394  // select data
395  sel_.reset();
396  sel_ = target_->getSelection();
397  if (caltype_ == STCalEnum::CalPSAlma ||
398      caltype_ == STCalEnum::CalPS) {
399    sel_.setTypes(vector<int>(1,(int)SrcType::PSON));
400  }
401  target_->setSelection(sel_);
402
403  //os_ << "sel_.print()=" << sel_.print() << LogIO::POST;
404
405  // working data
406  if (insitu) {
407    os_.origin(LogOrigin("STApplyCal","apply",WHERE));
408    os_ << "Overwrite input scantable" << LogIO::POST;
409    work_ = target_;
410  }
411  else {
412    os_.origin(LogOrigin("STApplyCal","apply",WHERE));
413    os_ << "Create output scantable from input" << LogIO::POST;
414    work_ = new Scantable(*target_, false);
415  }
416
417  //os_ << "work_->nrow()=" << work_->nrow() << LogIO::POST;
418
419  // list of apply tables for sky calibration
420  Vector<uInt> skycalList(skytable_.size());
421  uInt numSkyCal = 0;
422
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  }
431  skycalList.resize(numSkyCal, True);
432
433
434  vector<string> cols( 3 ) ;
435  cols[0] = "BEAMNO" ;
436  cols[1] = "POLNO" ;
437  cols[2] = "IFNO" ;
438  CountedPtr<STIdxIter2> iter = new STIdxIter2(work_, cols) ;
439  double start = mathutil::gettimeofday_sec();
440  os_ << LogIO::DEBUGGING << "start iterative doapply: " << start << LogIO::POST;
441  while (!iter->pastEnd()) {
442    Record ids = iter->currentValue();
443    Vector<uInt> rows = iter->getRows(SHARE);
444    if (rows.nelements() > 0)
445      doapply(ids.asuInt("BEAMNO"), ids.asuInt("IFNO"), ids.asuInt("POLNO"), rows, skycalList, filltsys);
446    iter->next();
447  }
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;
451
452  target_->unsetSelection();
453}
454
455void STApplyCal::doapply(uInt beamno, uInt ifno, uInt polno,
456                         Vector<uInt> &rows,
457                         Vector<uInt> &skylist,
458                         Bool filltsys)
459{
460  os_.origin(LogOrigin("STApplyCal","doapply",WHERE));
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
473  uInt nrowSkyTotal = 0;
474  uInt nrowTsysTotal = 0;
475  for (uInt i = 0; i < skylist.nelements(); i++) {
476    skytable_[skylist[i]]->setSelection(sel);
477    nrowSkyTotal += skytable_[skylist[i]]->nrow();
478    os_ << "nrowSkyTotal=" << nrowSkyTotal << LogIO::POST;
479  }
480
481  // Skip IFNO without sky data
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    }
489    return;
490  }
491
492  uInt nchanTsys = 0;
493  Vector<Double> ftsys;
494  uInt tsysifno = getIFForTsys(ifno);
495  Bool onlyInvalidTsys = False;
496  os_ << "tsysifno=" << (Int)tsysifno << LogIO::POST;
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);
512      uInt nrowThisTsys = tsystable_[i]->nrow();
513      nrowTsysTotal += nrowThisTsys;
514      if (nrowThisTsys > 0 && nchanTsys == 0) {
515        nchanTsys = tsystable_[i]->nchan(tsysifno);
516        ftsys = tsystable_[i]->getBaseFrequency(0);
517      }
518    }
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    }
524  }
525
526  uInt nchanSp = skytable_[skylist[0]]->nchan(ifno);
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);
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  }
540  nrowSky = timeSky.nelements();
541
542  uInt nrowTsys = nrowTsysTotal;
543  Vector<Double> timeTsys;
544  Matrix<Float> tsys;
545  Matrix<uChar> flagtsys;
546  if (doTsys) {
547    //os_ << "doTsys" << LogIO::POST;
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();
554
555    if (allNE(flagtsys, (uChar)0)) {
556      os_ << LogIO::WARN << "No valid Tsys measurement for Beam " << beamno << " Spw " << ifno << " Pol " << polno << ". Skip Tsys calibration." << LogIO::POST;
557      doTsys = False;
558      onlyInvalidTsys = True;
559    }
560  }
561
562  Table tab = work_->table();
563  ArrayColumn<Float> spCol(tab, "SPECTRA");
564  ArrayColumn<uChar> flCol(tab, "FLAGTRA");
565  ArrayColumn<Float> tsysCol(tab, "TSYS");
566  ScalarColumn<Double> timeCol(tab, "TIME");
567  ScalarColumn<uInt> frCol(tab, "FLAGROW");
568
569  // Array for scaling factor (aka Tsys)
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);
578
579  // working array for interpolation with flags
580  uInt arraySize = max(max(nrowTsys, nchanTsys), nrowSky);
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);
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);
588 
589  for (uInt i = 0; i < rows.nelements(); i++) {
590    //os_ << "start i = " << i << " (row = " << rows[i] << ")" << LogIO::POST;
591    uInt irow = rows[i];
592
593    // target spectral data
594    spCol.get(irow, on);
595    flCol.get(irow, flag);
596    uInt flagrow = frCol(irow);
597    //os_ << "on=" << on[0] << LogIO::POST;
598    calibrator_->setSource(on);
599
600    // interpolation
601    Double t0 = timeCol(irow);
602    Double *xwork_p = xwork.data();
603    Float *ywork_p = ywork.data();
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());
609    calibrator_->setReference(iOff);
610   
611    if (doTsys) {
612      // Tsys correction
613      // interpolation on time axis
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());
619      uChar *fwork_p = fwork.data();
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]);
627        uInt wnchan = setupWorkingData(nchanTsys, ftsys.data(), iTsysT.data(),
628                                       fwork_p, xwork_p, ywork_p);
629        assert(wnchan > 0);
630        if (wnchan == 0) {
631          throw AipsError("No valid Tsys measurements.");
632        }
633        interpolatorF_->setData(xwork_p, ywork_p, wnchan);
634        for (uInt ichan = 0; ichan < nchanSp; ichan++) {
635          iTsys[ichan] = interpolatorF_->interpolate(fsp[ichan]);
636        }
637      }
638    }
639    else {
640      Vector<Float> tsysInRow = tsysCol(irow);
641      if (tsysInRow.nelements() == 1) {
642        iTsys = tsysInRow[0];
643      }
644      else {
645        for (uInt ichan = 0; ichan < tsysInRow.nelements(); ++ichan)
646          iTsys[ichan] = tsysInRow[ichan];
647      }
648    }
649    //os_ << "iTsys=" << iTsys[0] << LogIO::POST;
650    calibrator_->setScaler(iTsys);
651 
652    // do calibration
653    calibrator_->calibrate();
654
655    // flag spectrum if no valid Tsys measurement available
656    if (onlyInvalidTsys) {
657      flagSpectrum(flagrow, flag);
658    }
659
660    // update table
661    //os_ << "calibrated=" << calibrator_->getCalibrated()[0] << LogIO::POST;
662    spCol.put(irow, calibrator_->getCalibrated());
663    flCol.put(irow, flag);
664    frCol.put(irow, flagrow);
665    if (filltsys && !onlyInvalidTsys)
666      tsysCol.put(irow, iTsys);
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<casacore::uInt, Vector<uInt> >::iterator i = spwmap_.begin();
686       i != spwmap_.end(); i++) {
687    Vector<uInt> tolist = i->second;
688    os_ << "from=" << i->first << ": tolist=" << tolist << LogIO::POST;
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{
699  //assert(!work_.null());
700  assert_<AipsError>(!work_.null(),"You have to execute apply method first.");
701
702  work_->setSelection(sel_);
703  work_->makePersistent(name);
704  work_->unsetSelection();
705}
706
707Vector<Double> STApplyCal::getBaseFrequency(uInt whichrow)
708{
709  //assert(whichrow <= (uInt)work_->nrow());
710  assert_<AipsError>(whichrow <= (uInt)work_->nrow(),"row index out of range.");
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
724void STApplyCal::initInterpolator()
725{
726  os_.origin(LogOrigin("STApplyCal","initInterpolator",WHERE));
727  int order = (order_ > 0) ? order_ : 1;
728  switch (iTime_) {
729  case STCalEnum::NearestInterpolation:
730    {
731      os_ << "use NearestInterpolator in time axis" << LogIO::POST;
732      interpolatorS_ = new NearestInterpolator1D<Double, Float>();
733      interpolatorT_ = new NearestInterpolator1D<Double, Float>();
734      break;
735    }
736  case STCalEnum::LinearInterpolation:
737    {
738      os_ << "use BufferedLinearInterpolator in time axis" << LogIO::POST;
739      interpolatorS_ = new BufferedLinearInterpolator1D<Double, Float>();
740      interpolatorT_ = new BufferedLinearInterpolator1D<Double, Float>();
741      break;     
742    }
743  case STCalEnum::CubicSplineInterpolation:
744    {
745      os_ << "use CubicSplineInterpolator in time axis" << LogIO::POST;
746      interpolatorS_ = new CubicSplineInterpolator1D<Double, Float>();
747      interpolatorT_ = new CubicSplineInterpolator1D<Double, Float>();
748      break;
749    }
750  case STCalEnum::PolynomialInterpolation:
751    {
752      os_ << "use PolynomialInterpolator in time axis" << LogIO::POST;
753      if (order == 0) {
754        interpolatorS_ = new NearestInterpolator1D<Double, Float>();
755        interpolatorT_ = new NearestInterpolator1D<Double, Float>();
756      }
757      else {
758        interpolatorS_ = new PolynomialInterpolator1D<Double, Float>();
759        interpolatorT_ = new PolynomialInterpolator1D<Double, Float>();
760        interpolatorS_->setOrder(order);
761        interpolatorT_->setOrder(order);
762      }
763      break;
764    }
765  default:
766    {
767      os_ << "use BufferedLinearInterpolator in time axis" << LogIO::POST;
768      interpolatorS_ = new BufferedLinearInterpolator1D<Double, Float>();
769      interpolatorT_ = new BufferedLinearInterpolator1D<Double, Float>();
770      break;     
771    }
772  }
773   
774  switch (iFreq_) {
775  case STCalEnum::NearestInterpolation:
776    {
777      os_ << "use NearestInterpolator in frequency axis" << LogIO::POST;
778      interpolatorF_ = new NearestInterpolator1D<Double, Float>();
779      break;
780    }
781  case STCalEnum::LinearInterpolation:
782    {
783      os_ << "use BufferedLinearInterpolator in frequency axis" << LogIO::POST;
784      interpolatorF_ = new BufferedLinearInterpolator1D<Double, Float>();
785      break;     
786    }
787  case STCalEnum::CubicSplineInterpolation:
788    {
789      os_ << "use CubicSplineInterpolator in frequency axis" << LogIO::POST;
790      interpolatorF_ = new CubicSplineInterpolator1D<Double, Float>();
791      break;
792    }
793  case STCalEnum::PolynomialInterpolation:
794    {
795      os_ << "use PolynomialInterpolator in frequency axis" << LogIO::POST;
796      if (order == 0) {
797        interpolatorF_ = new NearestInterpolator1D<Double, Float>();
798      }
799      else {
800        interpolatorF_ = new PolynomialInterpolator1D<Double, Float>();
801        interpolatorF_->setOrder(order);
802      }
803      break;
804    }
805  default:
806    {
807      os_ << "use LinearInterpolator in frequency axis" << LogIO::POST;
808      interpolatorF_ = new BufferedLinearInterpolator1D<Double, Float>();
809      break;     
810    }
811  }
812}
813
814}
Note: See TracBrowser for help on using the repository browser.