source: trunk/src/STApplyCal.cpp @ 2725

Last change on this file since 2725 was 2722, checked in by Takeshi Nakazato, 11 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: 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...

Include assert.h to fix build error.


File size: 12.8 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 <tables/Tables/Table.h>
25
26#include "Scantable.h"
27#include "STApplyCal.h"
28#include "STApplyTable.h"
29#include "STCalTsysTable.h"
30#include "STCalSkyTable.h"
31#include "STCalEnum.h"
32#include "STIdxIter.h"
33#include "Calibrator.h"
34#include "PSAlmaCalibrator.h"
35#include "NearestInterpolator1D.h"
36#include <atnf/PKSIO/SrcType.h>
37
38
39using namespace casa;
40using namespace std;
41
42namespace asap {
43
44STApplyCal::STApplyCal()
45{
46  init();
47}
48
49STApplyCal::STApplyCal(CountedPtr<Scantable> target)
50  : target_(target)
51{
52  init();
53}
54
55STApplyCal::~STApplyCal()
56{
57}
58
59void STApplyCal::init()
60{
61  caltype_ = STCalEnum::NoType;
62  doTsys_ = False;
63  interp_.resize((int)STCalEnum::NumAxis);
64}
65
66void STApplyCal::setTarget(CountedPtr<Scantable> target)
67{
68  target_ = target;
69}
70
71void STApplyCal::setTarget(const String &name)
72{
73  // always create PlainTable
74  target_ = new Scantable(name, Table::Plain);
75}
76
77void STApplyCal::push(STCalSkyTable *table)
78{
79  skytable_.push_back(table);
80  STCalEnum::CalType caltype = STApplyTable::getCalType(table);
81  os_ << "caltype=" <<  caltype << LogIO::POST;
82  if (caltype_ == STCalEnum::NoType ||
83      caltype_ == STCalEnum::DefaultType ||
84      caltype_ == STCalEnum::CalTsys) {
85    caltype_ = caltype;
86  }
87  os_ << "caltype_=" << caltype_ << LogIO::POST;
88}
89
90void STApplyCal::push(STCalTsysTable *table)
91{
92  tsystable_.push_back(table);
93  doTsys_ = True;
94}
95
96void STApplyCal::setInterpolation(STCalEnum::InterpolationAxis axis, STCalEnum::InterpolationType itype, Int order)
97{
98  interp_[(int)axis] = itype;
99  order_ = order;
100}
101
102void STApplyCal::setTsysTransfer(uInt from, Vector<uInt> to)
103{
104  os_ << "from=" << from << ", to=" << to << LogIO::POST;
105  map<uInt, Vector<uInt> >::iterator i = spwmap_.find(from);
106  if (i == spwmap_.end()) {
107    spwmap_.insert(pair<uInt, Vector<uInt> >(from, to));
108  }
109  else {
110    Vector<uInt> toNew = i->second;
111    spwmap_.erase(i);
112    uInt k = toNew.nelements();
113    toNew.resize(k+to.nelements(), True);
114    for (uInt i = 0; i < to.nelements(); i++)
115      toNew[i+k] = to[i];
116    spwmap_.insert(pair<uInt, Vector<uInt> >(from, toNew));
117  }
118}
119
120void STApplyCal::apply(Bool insitu)
121{
122  // calibrator
123  if (caltype_ == STCalEnum::CalPSAlma)
124    calibrator_ = new PSAlmaCalibrator();
125
126  // interpolator
127  interpolatorS_ = new NearestInterpolator1D();
128  interpolatorT_ = new NearestInterpolator1D();
129  interpolatorF_ = new NearestInterpolator1D();
130
131  // select data
132  sel_.reset();
133  if (caltype_ == STCalEnum::CalPSAlma ||
134      caltype_ == STCalEnum::CalPS) {
135    sel_.setTypes(vector<int>(1,(int)SrcType::PSON));
136  }
137  target_->setSelection(sel_);
138
139  os_ << "sel_.print()=" << sel_.print() << LogIO::POST;
140
141  // working data
142  if (insitu)
143    work_ = target_;
144  else
145    work_ = new Scantable(*target_, false);
146
147  os_ << "work_->nrow()=" << work_->nrow() << LogIO::POST;
148
149  // list of apply tables for sky calibration
150  Vector<uInt> skycalList;
151  uInt numSkyCal = 0;
152  uInt nrowSky = 0;
153  // list of apply tables for Tsys calibration
154//   Vector<uInt> tsyscalList;
155
156  for (uInt i = 0 ; i < skytable_.size(); i++) {
157    STCalEnum::CalType caltype = STApplyTable::getCalType(skytable_[i]);
158    if (caltype == caltype_) {
159      skycalList.resize(numSkyCal+1, True);
160      skycalList[numSkyCal] = i;
161      numSkyCal++;
162      nrowSky += skytable_[i]->nrow();
163    }
164  }
165
166
167  vector<string> cols( 3 ) ;
168  cols[0] = "BEAMNO" ;
169  cols[1] = "POLNO" ;
170  cols[2] = "IFNO" ;
171  CountedPtr<STIdxIter> iter = new STIdxIterAcc(work_, cols) ;
172  while (!iter->pastEnd()) {
173    Vector<uInt> ids = iter->current();
174    Vector<uInt> rows = iter->getRows(SHARE);
175    os_ << "ids=" << ids << LogIO::POST;
176    if (rows.nelements() > 0)
177      doapply(ids[0], ids[2], ids[1], rows, skycalList);
178    iter->next();
179  }
180
181  target_->unsetSelection();
182}
183
184void STApplyCal::doapply(uInt beamno, uInt ifno, uInt polno,
185                         Vector<uInt> &rows,
186                         Vector<uInt> &skylist)
187{
188  os_ << "skylist=" << skylist << LogIO::POST;
189  os_ << "rows=" << rows << LogIO::POST;
190  Bool doTsys = doTsys_;
191
192  //STSelector sel = sel_;
193  STSelector sel;
194  vector<int> id(1);
195  id[0] = beamno;
196  sel.setBeams(id);
197  id[0] = ifno;
198  sel.setIFs(id);
199  id[0] = polno;
200  sel.setPolarizations(id); 
201  os_ << "sel=" << sel.print() << LogIO::POST;
202
203  // apply selection to apply tables
204  uInt nrowSky = 0;
205  uInt nrowTsys = 0;
206  for (uInt i = 0; i < skylist.nelements(); i++) {
207    skytable_[skylist[i]]->setSelection(sel);
208    nrowSky += skytable_[skylist[i]]->nrow();
209    os_ << "nrowSky=" << nrowSky << LogIO::POST;
210  }
211  uInt nchanTsys = 0;
212  Vector<Double> ftsys;
213  uInt tsysifno = getIFForTsys(ifno);
214  os_ << "tsysifno=" << tsysifno << LogIO::POST;
215  if (tsystable_.size() == 0) {
216    os_.origin(LogOrigin("STApplyTable", "doapply", WHERE));
217    os_ << "No Tsys tables are given. Skip Tsys calibratoin." << LogIO::POST;
218    doTsys = False;
219  }
220  else if (tsysifno == (uInt)-1) {
221    os_.origin(LogOrigin("STApplyTable", "doapply", WHERE));
222    os_ << "No corresponding Tsys for IFNO " << ifno << ". Skip Tsys calibration" << LogIO::POST;
223    doTsys = False;
224  }
225  else {
226    nchanTsys = tsystable_[0]->nchan(tsysifno);
227    ftsys = tsystable_[0]->getBaseFrequency(0);
228    interpolatorF_->setX(ftsys.data(), nchanTsys);
229    os_ << "nchanTsys=" << nchanTsys << LogIO::POST;
230    id[0] = (int)tsysifno;
231    sel.setIFs(id);
232    for (uInt i = 0; i < tsystable_.size() ; i++) {
233      tsystable_[i]->setSelection(sel);
234      nrowTsys += tsystable_[i]->nrow();
235      os_ << "nrowTsys=" << nrowTsys << LogIO::POST;
236    }
237  }
238
239  uInt nchanSp = skytable_[skylist[0]]->nchan(ifno);
240  os_ << "nchanSp = " << nchanSp << LogIO::POST;
241  Vector<Double> timeSky(nrowSky);
242  Matrix<Float> spoff(nchanSp, nrowSky);
243  Vector<Float> iOff(nchanSp);
244  nrowSky = 0;
245  os_ << "spoff.shape()=" << spoff.shape() << LogIO::POST;
246  for (uInt i = 0 ; i < skylist.nelements(); i++) {
247    STCalSkyTable *p = skytable_[skylist[i]];
248    os_ << "table " << i << ": nrow=" << p->nrow() << LogIO::POST;
249    Vector<Double> t = p->getTime();
250    Matrix<Float> sp = p->getSpectra();
251    os_ << "sp.shape()=" << sp.shape() << LogIO::POST;
252    os_ << "t.nelements()=" << t.nelements() << LogIO::POST;
253    for (uInt j = 0; j < t.nelements(); j++) {
254      timeSky[nrowSky] = t[j];
255      os_ << "timeSky[" << nrowSky << "]-timeSky[0]=" << timeSky[nrowSky] - timeSky[0] << LogIO::POST;
256      spoff.column(nrowSky) = sp.column(j);
257      nrowSky++;
258    }
259  }
260  os_ << "timeSky-timeSky[0]=" << timeSky-timeSky[0] << LogIO::POST;
261
262  Vector<uInt> skyIdx = timeSort(timeSky);
263  os_ << "skyIdx = " << skyIdx << LogIO::POST;
264
265  double *xa = new double[skyIdx.nelements()];
266  float *ya = new float[skyIdx.nelements()];
267  IPosition ipos(1, skyIdx.nelements());
268  Vector<double> timeSkySorted(ipos, xa, TAKE_OVER);
269  Vector<Float> tmpOff(ipos, ya, TAKE_OVER);
270  for (uInt i = 0 ; i < skyIdx.nelements(); i++) {
271    timeSkySorted[i] = (double)timeSky[skyIdx[i]];
272    os_ << "timeSkySorted[" << i << "]-timeSkySorted[0]=" << timeSkySorted[i] - timeSkySorted[0] << LogIO::POST;
273  }
274  os_ << "timeSkySorted-timeSkySorted[0]=" << timeSkySorted-timeSkySorted[0] << LogIO::POST;
275
276  interpolatorS_->setX(xa, skyIdx.nelements());
277
278  os_ << "doTsys = " << doTsys << LogIO::POST;
279  Vector<uInt> tsysIdx;
280  Vector<Double> timeTsys(nrowTsys);
281  Matrix<Float> tsys;
282  Vector<double> timeTsysSorted;
283  Vector<Float> tmpTsys;
284  if (doTsys) {
285    os_ << "doTsys" << LogIO::POST;
286    timeTsys.resize(nrowTsys);
287    tsys.resize(nchanTsys, nrowTsys);
288    nrowTsys = 0;
289    for (uInt i = 0 ; i < tsystable_.size(); i++) {
290      STCalTsysTable *p = tsystable_[i];
291      os_ << "p->nrow()=" << p->nrow() << LogIO::POST;
292      Vector<Double> t = p->getTime();
293      os_ << "t=" << t << LogIO::POST;
294      Matrix<Float> ts = p->getTsys();
295      for (uInt j = 0; j < t.nelements(); j++) {
296        timeTsys[nrowTsys] = t[j];
297        tsys.column(nrowTsys) = ts.column(j);
298        nrowTsys++;
299      }
300    }
301    tsysIdx = timeSort(timeTsys);
302    os_ << "tsysIdx = " << tsysIdx << LogIO::POST;
303
304    double *xb = new double[tsysIdx.nelements()];
305    float *yb = new float[tsysIdx.nelements()];
306    IPosition ipos(1, tsysIdx.nelements());
307    timeTsysSorted.takeStorage(ipos, xb, TAKE_OVER);
308    tmpTsys.takeStorage(ipos, yb, TAKE_OVER);
309    for (uInt i = 0 ; i < tsysIdx.nelements(); i++) {
310      timeTsysSorted[i] = (double)timeTsys[tsysIdx[i]];
311      os_ << "timeTsysSorted[" << i << "]-timeTsysSorted[0]=" << timeTsysSorted[i] - timeTsysSorted[0] << LogIO::POST;
312    }
313    os_ << "timeTsysSorted=" << timeTsysSorted << LogIO::POST;
314    interpolatorT_->setX(xb, tsysIdx.nelements());
315  }
316
317  Table tab = work_->table();
318  ArrayColumn<Float> spCol(tab, "SPECTRA");
319  ScalarColumn<Double> timeCol(tab, "TIME");
320  Vector<Float> on;
321  for (uInt i = 0; i < rows.nelements(); i++) {
322    os_ << "start row " << i << LogIO::POST;
323    uInt irow = rows[i];
324
325    // target spectral data
326    on = spCol(irow);
327    calibrator_->setSource(on);
328
329    // interpolation
330    double t0 = (double)timeCol(irow);
331    for (uInt ichan = 0; ichan < nchanSp; ichan++) {
332      Vector<Float> spOffSlice = spoff.row(ichan);
333      //os_ << "spOffSlice = " << spOffSlice << LogIO::POST;
334      for (uInt j = 0; j < skyIdx.nelements(); j++) {
335        tmpOff[j] = (float)spOffSlice[skyIdx[j]];
336      }
337      interpolatorS_->setY(ya, skyIdx.nelements());
338      iOff[ichan] = interpolatorS_->interpolate(t0);
339    }
340    //os_ << "iOff=" << iOff << LogIO::POST;
341    calibrator_->setReference(iOff);
342   
343    Float *Y = new Float[nchanSp];
344    Vector<Float> iTsys(IPosition(1,nchanSp), Y, TAKE_OVER);
345    if (doTsys) {
346      // Tsys correction
347      float *yt = new float[nchanTsys];
348      Vector<Float> iTsysT(IPosition(1,nchanTsys), yt, TAKE_OVER);
349      float *yb = tmpTsys.data();
350      for (uInt ichan = 0; ichan < nchanTsys; ichan++) {
351        Vector<Float> tsysSlice = tsys.row(ichan);
352        for (uInt j = 0; j < tsysIdx.nelements(); j++) {
353          tmpTsys[j] = (float)tsysSlice[tsysIdx[j]];
354        }
355        interpolatorT_->setY(yb, tsysIdx.nelements());
356        iTsysT[ichan] = interpolatorT_->interpolate(t0);
357      }
358      os_ << "iTsysT=" << iTsysT << LogIO::POST;
359      if (nchanSp == 1) {
360        // take average
361        iTsys[0] = mean(iTsysT);
362      }
363      else {
364        // interpolation on frequency axis
365        os_ << "getBaseFrequency for target" << LogIO::POST;
366        Vector<Double> fsp = getBaseFrequency(rows[i]);
367        os_ << "fsp = " << fsp << LogIO::POST;
368        interpolatorF_->setY(yt, nchanTsys);
369        for (uInt ichan = 0; ichan < nchanSp; ichan++) {
370          iTsys[ichan] = (Float)interpolatorF_->interpolate(fsp[ichan]);
371        }
372      }
373    }
374    else {
375      iTsys = 1.0;
376    }
377    os_ << "iTsys=" << iTsys << LogIO::POST;
378    calibrator_->setScaler(iTsys);
379 
380    // do calibration
381    calibrator_->calibrate();
382
383    // update table
384    os_ << "calibrated=" << calibrator_->getCalibrated() << LogIO::POST;
385    spCol.put(irow, calibrator_->getCalibrated());
386   
387  }
388 
389
390  // reset selection on apply tables
391  for (uInt i = 0; i < skylist.nelements(); i++)
392    skytable_[i]->unsetSelection();
393  for (uInt i = 0; i < tsystable_.size(); i++)
394    tsystable_[i]->unsetSelection();
395
396
397  // reset interpolator
398  interpolatorS_->reset();
399  interpolatorF_->reset();
400  interpolatorT_->reset();
401}
402
403Vector<uInt> STApplyCal::timeSort(Vector<Double> &t)
404{
405  Sort sort;
406  sort.sortKey(&t[0], TpDouble, 0, Sort::Ascending);
407  Vector<uInt> idx;
408  sort.sort(idx, t.nelements(), Sort::QuickSort|Sort::NoDuplicates);
409  return idx;
410}
411
412uInt STApplyCal::getIFForTsys(uInt to)
413{
414  for (map<casa::uInt, Vector<uInt> >::iterator i = spwmap_.begin();
415       i != spwmap_.end(); i++) {
416    Vector<uInt> tolist = i->second;
417    os_ << i->first << ": tolist=" << tolist << LogIO::POST;
418    for (uInt j = 0; j < tolist.nelements(); j++) {
419      if (tolist[j] == to)
420        return i->first;
421    }
422  }
423  return (uInt)-1;
424}
425
426void STApplyCal::save(const String &name)
427{
428  if (work_.null())
429    return;
430
431  work_->setSelection(sel_);
432  work_->makePersistent(name);
433  work_->unsetSelection();
434}
435
436Vector<Double> STApplyCal::getBaseFrequency(uInt whichrow)
437{
438  assert(whichrow <= (uInt)work_->nrow());
439  ROTableColumn col(work_->table(), "IFNO");
440  uInt ifno = col.asuInt(whichrow);
441  col.attach(work_->table(), "FREQ_ID");
442  uInt freqid = col.asuInt(whichrow);
443  uInt nc = work_->nchan(ifno);
444  STFrequencies ftab = work_->frequencies();
445  Double rp, rf, inc;
446  ftab.getEntry(rp, rf, inc, freqid);
447  Vector<Double> r(nc);
448  indgen(r, rf-rp*inc, inc);
449  return r;
450}
451
452}
Note: See TracBrowser for help on using the repository browser.