source: trunk/src/STApplyCal.cpp@ 2726

Last change on this file since 2726 was 2722, checked in by Takeshi Nakazato, 12 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.