source: branches/newfiller/src/Scantable.cpp@ 1787

Last change on this file since 1787 was 1778, checked in by Malte Marquarding, 14 years ago

Initial untested Filler rewrite

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 53.2 KB
Line 
1//
2// C++ Implementation: Scantable
3//
4// Description:
5//
6//
7// Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2005
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12#include <map>
13#include <fstream>
14
15#include <casa/aips.h>
16#include <casa/iostream.h>
17#include <casa/iomanip.h>
18#include <casa/OS/Path.h>
19#include <casa/OS/File.h>
20#include <casa/Arrays/Array.h>
21#include <casa/Arrays/ArrayMath.h>
22#include <casa/Arrays/MaskArrMath.h>
23#include <casa/Arrays/ArrayLogical.h>
24#include <casa/Arrays/ArrayAccessor.h>
25#include <casa/Arrays/Vector.h>
26#include <casa/Arrays/VectorSTLIterator.h>
27#include <casa/Arrays/Slice.h>
28#include <casa/BasicMath/Math.h>
29#include <casa/BasicSL/Constants.h>
30#include <casa/Quanta/MVAngle.h>
31#include <casa/Containers/RecordField.h>
32#include <casa/Utilities/GenSort.h>
33#include <casa/Logging/LogIO.h>
34
35#include <tables/Tables/TableParse.h>
36#include <tables/Tables/TableDesc.h>
37#include <tables/Tables/TableCopy.h>
38#include <tables/Tables/SetupNewTab.h>
39#include <tables/Tables/ScaColDesc.h>
40#include <tables/Tables/ArrColDesc.h>
41#include <tables/Tables/TableRow.h>
42#include <tables/Tables/TableVector.h>
43#include <tables/Tables/TableIter.h>
44
45#include <tables/Tables/ExprNode.h>
46#include <tables/Tables/TableRecord.h>
47#include <casa/Quanta/MVTime.h>
48#include <casa/Quanta/MVAngle.h>
49#include <measures/Measures/MeasRef.h>
50#include <measures/Measures/MeasTable.h>
51// needed to avoid error in .tcc
52#include <measures/Measures/MCDirection.h>
53//
54#include <measures/Measures/MDirection.h>
55#include <measures/Measures/MFrequency.h>
56#include <measures/Measures/MEpoch.h>
57#include <measures/TableMeasures/TableMeasRefDesc.h>
58#include <measures/TableMeasures/TableMeasValueDesc.h>
59#include <measures/TableMeasures/TableMeasDesc.h>
60#include <measures/TableMeasures/ScalarMeasColumn.h>
61#include <coordinates/Coordinates/CoordinateUtil.h>
62
63#include "Scantable.h"
64#include "STPolLinear.h"
65#include "STPolCircular.h"
66#include "STPolStokes.h"
67#include "STAttr.h"
68#include "MathUtils.h"
69
70using namespace casa;
71
72namespace asap {
73
74std::map<std::string, STPol::STPolFactory *> Scantable::factories_;
75
76void Scantable::initFactories() {
77 if ( factories_.empty() ) {
78 Scantable::factories_["linear"] = &STPolLinear::myFactory;
79 Scantable::factories_["circular"] = &STPolCircular::myFactory;
80 Scantable::factories_["stokes"] = &STPolStokes::myFactory;
81 }
82}
83
84Scantable::Scantable(Table::TableType ttype) :
85 type_(ttype)
86{
87 initFactories();
88 setupMainTable();
89 freqTable_ = STFrequencies(*this);
90 table_.rwKeywordSet().defineTable("FREQUENCIES", freqTable_.table());
91 weatherTable_ = STWeather(*this);
92 table_.rwKeywordSet().defineTable("WEATHER", weatherTable_.table());
93 focusTable_ = STFocus(*this);
94 table_.rwKeywordSet().defineTable("FOCUS", focusTable_.table());
95 tcalTable_ = STTcal(*this);
96 table_.rwKeywordSet().defineTable("TCAL", tcalTable_.table());
97 moleculeTable_ = STMolecules(*this);
98 table_.rwKeywordSet().defineTable("MOLECULES", moleculeTable_.table());
99 historyTable_ = STHistory(*this);
100 table_.rwKeywordSet().defineTable("HISTORY", historyTable_.table());
101 fitTable_ = STFit(*this);
102 table_.rwKeywordSet().defineTable("FIT", fitTable_.table());
103 originalTable_ = table_;
104 attach();
105}
106
107Scantable::Scantable(const std::string& name, Table::TableType ttype) :
108 type_(ttype)
109{
110 initFactories();
111
112 Table tab(name, Table::Update);
113 uInt version = tab.keywordSet().asuInt("VERSION");
114 if (version != version_) {
115 throw(AipsError("Unsupported version of ASAP file."));
116 }
117 if ( type_ == Table::Memory ) {
118 table_ = tab.copyToMemoryTable(generateName());
119 } else {
120 table_ = tab;
121 }
122
123 attachSubtables();
124 originalTable_ = table_;
125 attach();
126}
127/*
128Scantable::Scantable(const std::string& name, Table::TableType ttype) :
129 type_(ttype)
130{
131 initFactories();
132 Table tab(name, Table::Update);
133 uInt version = tab.keywordSet().asuInt("VERSION");
134 if (version != version_) {
135 throw(AipsError("Unsupported version of ASAP file."));
136 }
137 if ( type_ == Table::Memory ) {
138 table_ = tab.copyToMemoryTable(generateName());
139 } else {
140 table_ = tab;
141 }
142
143 attachSubtables();
144 originalTable_ = table_;
145 attach();
146}
147*/
148
149Scantable::Scantable( const Scantable& other, bool clear )
150{
151 // with or without data
152 String newname = String(generateName());
153 type_ = other.table_.tableType();
154 if ( other.table_.tableType() == Table::Memory ) {
155 if ( clear ) {
156 table_ = TableCopy::makeEmptyMemoryTable(newname,
157 other.table_, True);
158 } else
159 table_ = other.table_.copyToMemoryTable(newname);
160 } else {
161 other.table_.deepCopy(newname, Table::New, False,
162 other.table_.endianFormat(),
163 Bool(clear));
164 table_ = Table(newname, Table::Update);
165 table_.markForDelete();
166 }
167 /// @todo reindex SCANNO, recompute nbeam, nif, npol
168 if ( clear ) copySubtables(other);
169 attachSubtables();
170 originalTable_ = table_;
171 attach();
172}
173
174void Scantable::copySubtables(const Scantable& other) {
175 Table t = table_.rwKeywordSet().asTable("FREQUENCIES");
176 TableCopy::copyRows(t, other.freqTable_.table());
177 t = table_.rwKeywordSet().asTable("FOCUS");
178 TableCopy::copyRows(t, other.focusTable_.table());
179 t = table_.rwKeywordSet().asTable("WEATHER");
180 TableCopy::copyRows(t, other.weatherTable_.table());
181 t = table_.rwKeywordSet().asTable("TCAL");
182 TableCopy::copyRows(t, other.tcalTable_.table());
183 t = table_.rwKeywordSet().asTable("MOLECULES");
184 TableCopy::copyRows(t, other.moleculeTable_.table());
185 t = table_.rwKeywordSet().asTable("HISTORY");
186 TableCopy::copyRows(t, other.historyTable_.table());
187 t = table_.rwKeywordSet().asTable("FIT");
188 TableCopy::copyRows(t, other.fitTable_.table());
189}
190
191void Scantable::attachSubtables()
192{
193 freqTable_ = STFrequencies(table_);
194 focusTable_ = STFocus(table_);
195 weatherTable_ = STWeather(table_);
196 tcalTable_ = STTcal(table_);
197 moleculeTable_ = STMolecules(table_);
198 historyTable_ = STHistory(table_);
199 fitTable_ = STFit(table_);
200}
201
202Scantable::~Scantable()
203{
204 //cout << "~Scantable() " << this << endl;
205}
206
207void Scantable::setupMainTable()
208{
209 TableDesc td("", "1", TableDesc::Scratch);
210 td.comment() = "An ASAP Scantable";
211 td.rwKeywordSet().define("VERSION", uInt(version_));
212
213 // n Cycles
214 td.addColumn(ScalarColumnDesc<uInt>("SCANNO"));
215 // new index every nBeam x nIF x nPol
216 td.addColumn(ScalarColumnDesc<uInt>("CYCLENO"));
217
218 td.addColumn(ScalarColumnDesc<uInt>("BEAMNO"));
219 td.addColumn(ScalarColumnDesc<uInt>("IFNO"));
220 // linear, circular, stokes
221 td.rwKeywordSet().define("POLTYPE", String("linear"));
222 td.addColumn(ScalarColumnDesc<uInt>("POLNO"));
223
224 td.addColumn(ScalarColumnDesc<uInt>("FREQ_ID"));
225 td.addColumn(ScalarColumnDesc<uInt>("MOLECULE_ID"));
226 ScalarColumnDesc<Int> refbeamnoColumn("REFBEAMNO");
227 refbeamnoColumn.setDefault(Int(-1));
228 td.addColumn(refbeamnoColumn);
229
230 td.addColumn(ScalarColumnDesc<uInt>("FLAGROW"));
231
232 td.addColumn(ScalarColumnDesc<Double>("TIME"));
233 TableMeasRefDesc measRef(MEpoch::UTC); // UTC as default
234 TableMeasValueDesc measVal(td, "TIME");
235 TableMeasDesc<MEpoch> mepochCol(measVal, measRef);
236 mepochCol.write(td);
237
238 td.addColumn(ScalarColumnDesc<Double>("INTERVAL"));
239
240 td.addColumn(ScalarColumnDesc<String>("SRCNAME"));
241 // Type of source (on=0, off=1, other=-1)
242 ScalarColumnDesc<Int> stypeColumn("SRCTYPE");
243 stypeColumn.setDefault(Int(-1));
244 td.addColumn(stypeColumn);
245 td.addColumn(ScalarColumnDesc<String>("FIELDNAME"));
246
247 //The actual Data Vectors
248 td.addColumn(ArrayColumnDesc<Float>("SPECTRA"));
249 td.addColumn(ArrayColumnDesc<uChar>("FLAGTRA"));
250 td.addColumn(ArrayColumnDesc<Float>("TSYS"));
251
252 td.addColumn(ArrayColumnDesc<Double>("DIRECTION",
253 IPosition(1,2),
254 ColumnDesc::Direct));
255 TableMeasRefDesc mdirRef(MDirection::J2000); // default
256 TableMeasValueDesc tmvdMDir(td, "DIRECTION");
257 // the TableMeasDesc gives the column a type
258 TableMeasDesc<MDirection> mdirCol(tmvdMDir, mdirRef);
259 // a uder set table type e.g. GALCTIC, B1950 ...
260 td.rwKeywordSet().define("DIRECTIONREF", String("J2000"));
261 // writing create the measure column
262 mdirCol.write(td);
263 td.addColumn(ScalarColumnDesc<Float>("AZIMUTH"));
264 td.addColumn(ScalarColumnDesc<Float>("ELEVATION"));
265 td.addColumn(ScalarColumnDesc<Float>("OPACITY"));
266
267 td.addColumn(ScalarColumnDesc<uInt>("TCAL_ID"));
268 ScalarColumnDesc<Int> fitColumn("FIT_ID");
269 fitColumn.setDefault(Int(-1));
270 td.addColumn(fitColumn);
271
272 td.addColumn(ScalarColumnDesc<uInt>("FOCUS_ID"));
273 td.addColumn(ScalarColumnDesc<uInt>("WEATHER_ID"));
274
275 // columns which just get dragged along, as they aren't used in asap
276 td.addColumn(ScalarColumnDesc<Double>("SRCVELOCITY"));
277 td.addColumn(ArrayColumnDesc<Double>("SRCPROPERMOTION"));
278 td.addColumn(ArrayColumnDesc<Double>("SRCDIRECTION"));
279 td.addColumn(ArrayColumnDesc<Double>("SCANRATE"));
280
281 td.rwKeywordSet().define("OBSMODE", String(""));
282
283 // Now create Table SetUp from the description.
284 SetupNewTable aNewTab(generateName(), td, Table::Scratch);
285 table_ = Table(aNewTab, type_, 0);
286 originalTable_ = table_;
287}
288
289void Scantable::attach()
290{
291 timeCol_.attach(table_, "TIME");
292 srcnCol_.attach(table_, "SRCNAME");
293 srctCol_.attach(table_, "SRCTYPE");
294 specCol_.attach(table_, "SPECTRA");
295 flagsCol_.attach(table_, "FLAGTRA");
296 tsysCol_.attach(table_, "TSYS");
297 cycleCol_.attach(table_,"CYCLENO");
298 scanCol_.attach(table_, "SCANNO");
299 beamCol_.attach(table_, "BEAMNO");
300 ifCol_.attach(table_, "IFNO");
301 polCol_.attach(table_, "POLNO");
302 integrCol_.attach(table_, "INTERVAL");
303 azCol_.attach(table_, "AZIMUTH");
304 elCol_.attach(table_, "ELEVATION");
305 dirCol_.attach(table_, "DIRECTION");
306 fldnCol_.attach(table_, "FIELDNAME");
307 rbeamCol_.attach(table_, "REFBEAMNO");
308
309 mweatheridCol_.attach(table_,"WEATHER_ID");
310 mfitidCol_.attach(table_,"FIT_ID");
311 mfreqidCol_.attach(table_, "FREQ_ID");
312 mtcalidCol_.attach(table_, "TCAL_ID");
313 mfocusidCol_.attach(table_, "FOCUS_ID");
314 mmolidCol_.attach(table_, "MOLECULE_ID");
315
316 //Add auxiliary column for row-based flagging (CAS-1433 Wataru Kawasaki)
317 attachAuxColumnDef(flagrowCol_, "FLAGROW", 0);
318
319}
320
321template<class T, class T2>
322void Scantable::attachAuxColumnDef(ScalarColumn<T>& col,
323 const String& colName,
324 const T2& defValue)
325{
326 try {
327 col.attach(table_, colName);
328 } catch (TableError& err) {
329 String errMesg = err.getMesg();
330 if (errMesg == "Table column " + colName + " is unknown") {
331 table_.addColumn(ScalarColumnDesc<T>(colName));
332 col.attach(table_, colName);
333 col.fillColumn(static_cast<T>(defValue));
334 } else {
335 throw;
336 }
337 } catch (...) {
338 throw;
339 }
340}
341
342template<class T, class T2>
343void Scantable::attachAuxColumnDef(ArrayColumn<T>& col,
344 const String& colName,
345 const Array<T2>& defValue)
346{
347 try {
348 col.attach(table_, colName);
349 } catch (TableError& err) {
350 String errMesg = err.getMesg();
351 if (errMesg == "Table column " + colName + " is unknown") {
352 table_.addColumn(ArrayColumnDesc<T>(colName));
353 col.attach(table_, colName);
354
355 int size = 0;
356 ArrayIterator<T2>& it = defValue.begin();
357 while (it != defValue.end()) {
358 ++size;
359 ++it;
360 }
361 IPosition ip(1, size);
362 Array<T>& arr(ip);
363 for (int i = 0; i < size; ++i)
364 arr[i] = static_cast<T>(defValue[i]);
365
366 col.fillColumn(arr);
367 } else {
368 throw;
369 }
370 } catch (...) {
371 throw;
372 }
373}
374
375void Scantable::setHeader(const STHeader& sdh)
376{
377 table_.rwKeywordSet().define("nIF", sdh.nif);
378 table_.rwKeywordSet().define("nBeam", sdh.nbeam);
379 table_.rwKeywordSet().define("nPol", sdh.npol);
380 table_.rwKeywordSet().define("nChan", sdh.nchan);
381 table_.rwKeywordSet().define("Observer", sdh.observer);
382 table_.rwKeywordSet().define("Project", sdh.project);
383 table_.rwKeywordSet().define("Obstype", sdh.obstype);
384 table_.rwKeywordSet().define("AntennaName", sdh.antennaname);
385 table_.rwKeywordSet().define("AntennaPosition", sdh.antennaposition);
386 table_.rwKeywordSet().define("Equinox", sdh.equinox);
387 table_.rwKeywordSet().define("FreqRefFrame", sdh.freqref);
388 table_.rwKeywordSet().define("FreqRefVal", sdh.reffreq);
389 table_.rwKeywordSet().define("Bandwidth", sdh.bandwidth);
390 table_.rwKeywordSet().define("UTC", sdh.utc);
391 table_.rwKeywordSet().define("FluxUnit", sdh.fluxunit);
392 table_.rwKeywordSet().define("Epoch", sdh.epoch);
393 table_.rwKeywordSet().define("POLTYPE", sdh.poltype);
394}
395
396STHeader Scantable::getHeader() const
397{
398 STHeader sdh;
399 table_.keywordSet().get("nBeam",sdh.nbeam);
400 table_.keywordSet().get("nIF",sdh.nif);
401 table_.keywordSet().get("nPol",sdh.npol);
402 table_.keywordSet().get("nChan",sdh.nchan);
403 table_.keywordSet().get("Observer", sdh.observer);
404 table_.keywordSet().get("Project", sdh.project);
405 table_.keywordSet().get("Obstype", sdh.obstype);
406 table_.keywordSet().get("AntennaName", sdh.antennaname);
407 table_.keywordSet().get("AntennaPosition", sdh.antennaposition);
408 table_.keywordSet().get("Equinox", sdh.equinox);
409 table_.keywordSet().get("FreqRefFrame", sdh.freqref);
410 table_.keywordSet().get("FreqRefVal", sdh.reffreq);
411 table_.keywordSet().get("Bandwidth", sdh.bandwidth);
412 table_.keywordSet().get("UTC", sdh.utc);
413 table_.keywordSet().get("FluxUnit", sdh.fluxunit);
414 table_.keywordSet().get("Epoch", sdh.epoch);
415 table_.keywordSet().get("POLTYPE", sdh.poltype);
416 return sdh;
417}
418
419void Scantable::setSourceType( int stype )
420{
421 if ( stype < 0 || stype > 1 )
422 throw(AipsError("Illegal sourcetype."));
423 TableVector<Int> tabvec(table_, "SRCTYPE");
424 tabvec = Int(stype);
425}
426
427bool Scantable::conformant( const Scantable& other )
428{
429 return this->getHeader().conformant(other.getHeader());
430}
431
432
433
434std::string Scantable::formatSec(Double x) const
435{
436 Double xcop = x;
437 MVTime mvt(xcop/24./3600.); // make days
438
439 if (x < 59.95)
440 return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_HM, 7)+"s";
441 else if (x < 3599.95)
442 return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_H,7)+" ";
443 else {
444 ostringstream oss;
445 oss << setw(2) << std::right << setprecision(1) << mvt.hour();
446 oss << ":" << mvt.string(MVTime::TIME_CLEAN_NO_H,7) << " ";
447 return String(oss);
448 }
449};
450
451std::string Scantable::formatDirection(const MDirection& md) const
452{
453 Vector<Double> t = md.getAngle(Unit(String("rad"))).getValue();
454 Int prec = 7;
455
456 MVAngle mvLon(t[0]);
457 String sLon = mvLon.string(MVAngle::TIME,prec);
458 uInt tp = md.getRef().getType();
459 if (tp == MDirection::GALACTIC ||
460 tp == MDirection::SUPERGAL ) {
461 sLon = mvLon(0.0).string(MVAngle::ANGLE_CLEAN,prec);
462 }
463 MVAngle mvLat(t[1]);
464 String sLat = mvLat.string(MVAngle::ANGLE+MVAngle::DIG2,prec);
465 return sLon + String(" ") + sLat;
466}
467
468
469std::string Scantable::getFluxUnit() const
470{
471 return table_.keywordSet().asString("FluxUnit");
472}
473
474void Scantable::setFluxUnit(const std::string& unit)
475{
476 String tmp(unit);
477 Unit tU(tmp);
478 if (tU==Unit("K") || tU==Unit("Jy")) {
479 table_.rwKeywordSet().define(String("FluxUnit"), tmp);
480 } else {
481 throw AipsError("Illegal unit - must be compatible with Jy or K");
482 }
483}
484
485void Scantable::setInstrument(const std::string& name)
486{
487 bool throwIt = true;
488 // create an Instrument to see if this is valid
489 STAttr::convertInstrument(name, throwIt);
490 String nameU(name);
491 nameU.upcase();
492 table_.rwKeywordSet().define(String("AntennaName"), nameU);
493}
494
495void Scantable::setFeedType(const std::string& feedtype)
496{
497 if ( Scantable::factories_.find(feedtype) == Scantable::factories_.end() ) {
498 std::string msg = "Illegal feed type "+ feedtype;
499 throw(casa::AipsError(msg));
500 }
501 table_.rwKeywordSet().define(String("POLTYPE"), feedtype);
502}
503
504MPosition Scantable::getAntennaPosition() const
505{
506 Vector<Double> antpos;
507 table_.keywordSet().get("AntennaPosition", antpos);
508 MVPosition mvpos(antpos(0),antpos(1),antpos(2));
509 return MPosition(mvpos);
510}
511
512void Scantable::makePersistent(const std::string& filename)
513{
514 String inname(filename);
515 Path path(inname);
516 /// @todo reindex SCANNO, recompute nbeam, nif, npol
517 inname = path.expandedName();
518 // WORKAROUND !!! for Table bug
519 // Remove when fixed in casacore
520 if ( table_.tableType() == Table::Memory && !selector_.empty() ) {
521 Table tab = table_.copyToMemoryTable(generateName());
522 tab.deepCopy(inname, Table::New);
523 tab.markForDelete();
524
525 } else {
526 table_.deepCopy(inname, Table::New);
527 }
528}
529
530int Scantable::nbeam( int scanno ) const
531{
532 if ( scanno < 0 ) {
533 Int n;
534 table_.keywordSet().get("nBeam",n);
535 return int(n);
536 } else {
537 // take the first POLNO,IFNO,CYCLENO as nbeam shouldn't vary with these
538 Table t = table_(table_.col("SCANNO") == scanno);
539 ROTableRow row(t);
540 const TableRecord& rec = row.get(0);
541 Table subt = t( t.col("IFNO") == Int(rec.asuInt("IFNO"))
542 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
543 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
544 ROTableVector<uInt> v(subt, "BEAMNO");
545 return int(v.nelements());
546 }
547 return 0;
548}
549
550int Scantable::nif( int scanno ) const
551{
552 if ( scanno < 0 ) {
553 Int n;
554 table_.keywordSet().get("nIF",n);
555 return int(n);
556 } else {
557 // take the first POLNO,BEAMNO,CYCLENO as nbeam shouldn't vary with these
558 Table t = table_(table_.col("SCANNO") == scanno);
559 ROTableRow row(t);
560 const TableRecord& rec = row.get(0);
561 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
562 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
563 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
564 if ( subt.nrow() == 0 ) return 0;
565 ROTableVector<uInt> v(subt, "IFNO");
566 return int(v.nelements());
567 }
568 return 0;
569}
570
571int Scantable::npol( int scanno ) const
572{
573 if ( scanno < 0 ) {
574 Int n;
575 table_.keywordSet().get("nPol",n);
576 return n;
577 } else {
578 // take the first POLNO,IFNO,CYCLENO as nbeam shouldn't vary with these
579 Table t = table_(table_.col("SCANNO") == scanno);
580 ROTableRow row(t);
581 const TableRecord& rec = row.get(0);
582 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
583 && t.col("IFNO") == Int(rec.asuInt("IFNO"))
584 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
585 if ( subt.nrow() == 0 ) return 0;
586 ROTableVector<uInt> v(subt, "POLNO");
587 return int(v.nelements());
588 }
589 return 0;
590}
591
592int Scantable::ncycle( int scanno ) const
593{
594 if ( scanno < 0 ) {
595 Block<String> cols(2);
596 cols[0] = "SCANNO";
597 cols[1] = "CYCLENO";
598 TableIterator it(table_, cols);
599 int n = 0;
600 while ( !it.pastEnd() ) {
601 ++n;
602 ++it;
603 }
604 return n;
605 } else {
606 Table t = table_(table_.col("SCANNO") == scanno);
607 ROTableRow row(t);
608 const TableRecord& rec = row.get(0);
609 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
610 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
611 && t.col("IFNO") == Int(rec.asuInt("IFNO")) );
612 if ( subt.nrow() == 0 ) return 0;
613 return int(subt.nrow());
614 }
615 return 0;
616}
617
618
619int Scantable::nrow( int scanno ) const
620{
621 return int(table_.nrow());
622}
623
624int Scantable::nchan( int ifno ) const
625{
626 if ( ifno < 0 ) {
627 Int n;
628 table_.keywordSet().get("nChan",n);
629 return int(n);
630 } else {
631 // take the first SCANNO,POLNO,BEAMNO,CYCLENO as nbeam shouldn't
632 // vary with these
633 Table t = table_(table_.col("IFNO") == ifno);
634 if ( t.nrow() == 0 ) return 0;
635 ROArrayColumn<Float> v(t, "SPECTRA");
636 return v.shape(0)(0);
637 }
638 return 0;
639}
640
641int Scantable::nscan() const {
642 Vector<uInt> scannos(scanCol_.getColumn());
643 uInt nout = genSort( scannos, Sort::Ascending,
644 Sort::QuickSort|Sort::NoDuplicates );
645 return int(nout);
646}
647
648int Scantable::getChannels(int whichrow) const
649{
650 return specCol_.shape(whichrow)(0);
651}
652
653int Scantable::getBeam(int whichrow) const
654{
655 return beamCol_(whichrow);
656}
657
658std::vector<uint> Scantable::getNumbers(const ScalarColumn<uInt>& col) const
659{
660 Vector<uInt> nos(col.getColumn());
661 uInt n = genSort( nos, Sort::Ascending, Sort::QuickSort|Sort::NoDuplicates );
662 nos.resize(n, True);
663 std::vector<uint> stlout;
664 nos.tovector(stlout);
665 return stlout;
666}
667
668int Scantable::getIF(int whichrow) const
669{
670 return ifCol_(whichrow);
671}
672
673int Scantable::getPol(int whichrow) const
674{
675 return polCol_(whichrow);
676}
677
678std::string Scantable::formatTime(const MEpoch& me, bool showdate) const
679{
680 MVTime mvt(me.getValue());
681 if (showdate)
682 mvt.setFormat(MVTime::YMD);
683 else
684 mvt.setFormat(MVTime::TIME);
685 ostringstream oss;
686 oss << mvt;
687 return String(oss);
688}
689
690void Scantable::calculateAZEL()
691{
692 MPosition mp = getAntennaPosition();
693 MEpoch::ROScalarColumn timeCol(table_, "TIME");
694 ostringstream oss;
695 oss << "Computed azimuth/elevation using " << endl
696 << mp << endl;
697 for (Int i=0; i<nrow(); ++i) {
698 MEpoch me = timeCol(i);
699 MDirection md = getDirection(i);
700 oss << " Time: " << formatTime(me,False) << " Direction: " << formatDirection(md)
701 << endl << " => ";
702 MeasFrame frame(mp, me);
703 Vector<Double> azel =
704 MDirection::Convert(md, MDirection::Ref(MDirection::AZEL,
705 frame)
706 )().getAngle("rad").getValue();
707 azCol_.put(i,Float(azel[0]));
708 elCol_.put(i,Float(azel[1]));
709 oss << "azel: " << azel[0]/C::pi*180.0 << " "
710 << azel[1]/C::pi*180.0 << " (deg)" << endl;
711 }
712 pushLog(String(oss));
713}
714
715void Scantable::clip(const Float uthres, const Float dthres, bool clipoutside, bool unflag)
716{
717 for (uInt i=0; i<table_.nrow(); ++i) {
718 Vector<uChar> flgs = flagsCol_(i);
719 srchChannelsToClip(i, uthres, dthres, clipoutside, unflag, flgs);
720 flagsCol_.put(i, flgs);
721 }
722}
723
724std::vector<bool> Scantable::getClipMask(int whichrow, const Float uthres, const Float dthres, bool clipoutside, bool unflag)
725{
726 Vector<uChar> flags;
727 flagsCol_.get(uInt(whichrow), flags);
728 srchChannelsToClip(uInt(whichrow), uthres, dthres, clipoutside, unflag, flags);
729 Vector<Bool> bflag(flags.shape());
730 convertArray(bflag, flags);
731 //bflag = !bflag;
732
733 std::vector<bool> mask;
734 bflag.tovector(mask);
735 return mask;
736}
737
738void Scantable::srchChannelsToClip(uInt whichrow, const Float uthres, const Float dthres, bool clipoutside, bool unflag,
739 Vector<uChar> flgs)
740{
741 Vector<Float> spcs = specCol_(whichrow);
742 uInt nchannel = nchan();
743 if (spcs.nelements() != nchannel) {
744 throw(AipsError("Data has incorrect number of channels"));
745 }
746 uChar userflag = 1 << 7;
747 if (unflag) {
748 userflag = 0 << 7;
749 }
750 if (clipoutside) {
751 for (uInt j = 0; j < nchannel; ++j) {
752 Float spc = spcs(j);
753 if ((spc >= uthres) || (spc <= dthres)) {
754 flgs(j) = userflag;
755 }
756 }
757 } else {
758 for (uInt j = 0; j < nchannel; ++j) {
759 Float spc = spcs(j);
760 if ((spc < uthres) && (spc > dthres)) {
761 flgs(j) = userflag;
762 }
763 }
764 }
765}
766
767void Scantable::flag(const std::vector<bool>& msk, bool unflag)
768{
769 std::vector<bool>::const_iterator it;
770 uInt ntrue = 0;
771 for (it = msk.begin(); it != msk.end(); ++it) {
772 if ( *it ) {
773 ntrue++;
774 }
775 }
776 if ( selector_.empty() && (msk.size() == 0 || msk.size() == ntrue) )
777 throw(AipsError("Trying to flag whole scantable."));
778 if ( msk.size() == 0 ) {
779 uChar userflag = 1 << 7;
780 if ( unflag ) {
781 userflag = 0 << 7;
782 }
783 for ( uInt i=0; i<table_.nrow(); ++i) {
784 Vector<uChar> flgs = flagsCol_(i);
785 flgs = userflag;
786 flagsCol_.put(i, flgs);
787 }
788 return;
789 }
790 if ( int(msk.size()) != nchan() ) {
791 throw(AipsError("Mask has incorrect number of channels."));
792 }
793 for ( uInt i=0; i<table_.nrow(); ++i) {
794 Vector<uChar> flgs = flagsCol_(i);
795 if ( flgs.nelements() != msk.size() ) {
796 throw(AipsError("Mask has incorrect number of channels."
797 " Probably varying with IF. Please flag per IF"));
798 }
799 std::vector<bool>::const_iterator it;
800 uInt j = 0;
801 uChar userflag = 1 << 7;
802 if ( unflag ) {
803 userflag = 0 << 7;
804 }
805 for (it = msk.begin(); it != msk.end(); ++it) {
806 if ( *it ) {
807 flgs(j) = userflag;
808 }
809 ++j;
810 }
811 flagsCol_.put(i, flgs);
812 }
813}
814
815void Scantable::flagRow(const std::vector<uInt>& rows, bool unflag)
816{
817 if ( selector_.empty() && (rows.size() == table_.nrow()) )
818 throw(AipsError("Trying to flag whole scantable."));
819
820 uInt rowflag = (unflag ? 0 : 1);
821 std::vector<uInt>::const_iterator it;
822 for (it = rows.begin(); it != rows.end(); ++it)
823 flagrowCol_.put(*it, rowflag);
824}
825
826std::vector<bool> Scantable::getMask(int whichrow) const
827{
828 Vector<uChar> flags;
829 flagsCol_.get(uInt(whichrow), flags);
830 Vector<Bool> bflag(flags.shape());
831 convertArray(bflag, flags);
832 bflag = !bflag;
833 std::vector<bool> mask;
834 bflag.tovector(mask);
835 return mask;
836}
837
838std::vector<float> Scantable::getSpectrum( int whichrow,
839 const std::string& poltype ) const
840{
841 String ptype = poltype;
842 if (poltype == "" ) ptype = getPolType();
843 if ( whichrow < 0 || whichrow >= nrow() )
844 throw(AipsError("Illegal row number."));
845 std::vector<float> out;
846 Vector<Float> arr;
847 uInt requestedpol = polCol_(whichrow);
848 String basetype = getPolType();
849 if ( ptype == basetype ) {
850 specCol_.get(whichrow, arr);
851 } else {
852 CountedPtr<STPol> stpol(STPol::getPolClass(Scantable::factories_,
853 basetype));
854 uInt row = uInt(whichrow);
855 stpol->setSpectra(getPolMatrix(row));
856 Float fang,fhand,parang;
857 fang = focusTable_.getTotalAngle(mfocusidCol_(row));
858 fhand = focusTable_.getFeedHand(mfocusidCol_(row));
859 stpol->setPhaseCorrections(fang, fhand);
860 arr = stpol->getSpectrum(requestedpol, ptype);
861 }
862 if ( arr.nelements() == 0 )
863 pushLog("Not enough polarisations present to do the conversion.");
864 arr.tovector(out);
865 return out;
866}
867
868void Scantable::setSpectrum( const std::vector<float>& spec,
869 int whichrow )
870{
871 Vector<Float> spectrum(spec);
872 Vector<Float> arr;
873 specCol_.get(whichrow, arr);
874 if ( spectrum.nelements() != arr.nelements() )
875 throw AipsError("The spectrum has incorrect number of channels.");
876 specCol_.put(whichrow, spectrum);
877}
878
879
880String Scantable::generateName()
881{
882 return (File::newUniqueName("./","temp")).baseName();
883}
884
885const casa::Table& Scantable::table( ) const
886{
887 return table_;
888}
889
890casa::Table& Scantable::table( )
891{
892 return table_;
893}
894
895std::string Scantable::getPolType() const
896{
897 return table_.keywordSet().asString("POLTYPE");
898}
899
900void Scantable::unsetSelection()
901{
902 table_ = originalTable_;
903 attach();
904 selector_.reset();
905}
906
907void Scantable::setSelection( const STSelector& selection )
908{
909 Table tab = const_cast<STSelector&>(selection).apply(originalTable_);
910 if ( tab.nrow() == 0 ) {
911 throw(AipsError("Selection contains no data. Not applying it."));
912 }
913 table_ = tab;
914 attach();
915 selector_ = selection;
916}
917
918std::string Scantable::summary( bool verbose )
919{
920 // Format header info
921 ostringstream oss;
922 oss << endl;
923 oss << asap::SEPERATOR << endl;
924 oss << " Scan Table Summary" << endl;
925 oss << asap::SEPERATOR << endl;
926 oss.flags(std::ios_base::left);
927 oss << setw(15) << "Beams:" << setw(4) << nbeam() << endl
928 << setw(15) << "IFs:" << setw(4) << nif() << endl
929 << setw(15) << "Polarisations:" << setw(4) << npol()
930 << "(" << getPolType() << ")" << endl
931 << setw(15) << "Channels:" << nchan() << endl;
932 String tmp;
933 oss << setw(15) << "Observer:"
934 << table_.keywordSet().asString("Observer") << endl;
935 oss << setw(15) << "Obs Date:" << getTime(-1,true) << endl;
936 table_.keywordSet().get("Project", tmp);
937 oss << setw(15) << "Project:" << tmp << endl;
938 table_.keywordSet().get("Obstype", tmp);
939 oss << setw(15) << "Obs. Type:" << tmp << endl;
940 table_.keywordSet().get("AntennaName", tmp);
941 oss << setw(15) << "Antenna Name:" << tmp << endl;
942 table_.keywordSet().get("FluxUnit", tmp);
943 oss << setw(15) << "Flux Unit:" << tmp << endl;
944 //Vector<Double> vec(moleculeTable_.getRestFrequencies());
945 int nid = moleculeTable_.nrow();
946 Bool firstline = True;
947 oss << setw(15) << "Rest Freqs:";
948 for (int i=0; i<nid; i++) {
949 Table t = table_(table_.col("MOLECULE_ID") == i);
950 if (t.nrow() > 0) {
951 Vector<Double> vec(moleculeTable_.getRestFrequency(i));
952 if (vec.nelements() > 0) {
953 if (firstline) {
954 oss << setprecision(10) << vec << " [Hz]" << endl;
955 firstline=False;
956 }
957 else{
958 oss << setw(15)<<" " << setprecision(10) << vec << " [Hz]" << endl;
959 }
960 } else {
961 oss << "none" << endl;
962 }
963 }
964 }
965
966 oss << setw(15) << "Abcissa:" << getAbcissaLabel(0) << endl;
967 oss << selector_.print() << endl;
968 oss << endl;
969 // main table
970 String dirtype = "Position ("
971 + getDirectionRefString()
972 + ")";
973 oss << setw(5) << "Scan" << setw(15) << "Source"
974 << setw(10) << "Time" << setw(18) << "Integration" << endl;
975 oss << setw(5) << "" << setw(5) << "Beam" << setw(3) << "" << dirtype << endl;
976 oss << setw(10) << "" << setw(3) << "IF" << setw(3) << ""
977 << setw(8) << "Frame" << setw(16)
978 << "RefVal" << setw(10) << "RefPix" << setw(12) << "Increment"
979 << setw(7) << "Channels"
980 << endl;
981 oss << asap::SEPERATOR << endl;
982 TableIterator iter(table_, "SCANNO");
983 while (!iter.pastEnd()) {
984 Table subt = iter.table();
985 ROTableRow row(subt);
986 MEpoch::ROScalarColumn timeCol(subt,"TIME");
987 const TableRecord& rec = row.get(0);
988 oss << setw(4) << std::right << rec.asuInt("SCANNO")
989 << std::left << setw(1) << ""
990 << setw(15) << rec.asString("SRCNAME")
991 << setw(10) << formatTime(timeCol(0), false);
992 // count the cycles in the scan
993 TableIterator cyciter(subt, "CYCLENO");
994 int nint = 0;
995 while (!cyciter.pastEnd()) {
996 ++nint;
997 ++cyciter;
998 }
999 oss << setw(3) << std::right << nint << setw(3) << " x " << std::left
1000 << setw(6) << formatSec(rec.asFloat("INTERVAL")) << endl;
1001
1002 TableIterator biter(subt, "BEAMNO");
1003 while (!biter.pastEnd()) {
1004 Table bsubt = biter.table();
1005 ROTableRow brow(bsubt);
1006 const TableRecord& brec = brow.get(0);
1007 uInt row0 = bsubt.rowNumbers(table_)[0];
1008 oss << setw(5) << "" << setw(4) << std::right << brec.asuInt("BEAMNO")<< std::left;
1009 oss << setw(4) << "" << formatDirection(getDirection(row0)) << endl;
1010 TableIterator iiter(bsubt, "IFNO");
1011 while (!iiter.pastEnd()) {
1012 Table isubt = iiter.table();
1013 ROTableRow irow(isubt);
1014 const TableRecord& irec = irow.get(0);
1015 oss << setw(9) << "";
1016 oss << setw(3) << std::right << irec.asuInt("IFNO") << std::left
1017 << setw(1) << "" << frequencies().print(irec.asuInt("FREQ_ID"))
1018 << setw(3) << "" << nchan(irec.asuInt("IFNO"))
1019 << endl;
1020
1021 ++iiter;
1022 }
1023 ++biter;
1024 }
1025 ++iter;
1026 }
1027 /// @todo implement verbose mode
1028 return String(oss);
1029}
1030
1031std::string Scantable::getTime(int whichrow, bool showdate) const
1032{
1033 MEpoch::ROScalarColumn timeCol(table_, "TIME");
1034 MEpoch me;
1035 if (whichrow > -1) {
1036 me = timeCol(uInt(whichrow));
1037 } else {
1038 Double tm;
1039 table_.keywordSet().get("UTC",tm);
1040 me = MEpoch(MVEpoch(tm));
1041 }
1042 return formatTime(me, showdate);
1043}
1044
1045MEpoch Scantable::getEpoch(int whichrow) const
1046{
1047 if (whichrow > -1) {
1048 return timeCol_(uInt(whichrow));
1049 } else {
1050 Double tm;
1051 table_.keywordSet().get("UTC",tm);
1052 return MEpoch(MVEpoch(tm));
1053 }
1054}
1055
1056std::string Scantable::getDirectionString(int whichrow) const
1057{
1058 return formatDirection(getDirection(uInt(whichrow)));
1059}
1060
1061
1062SpectralCoordinate Scantable::getSpectralCoordinate(int whichrow) const {
1063 const MPosition& mp = getAntennaPosition();
1064 const MDirection& md = getDirection(whichrow);
1065 const MEpoch& me = timeCol_(whichrow);
1066 //Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
1067 Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
1068 return freqTable_.getSpectralCoordinate(md, mp, me, rf,
1069 mfreqidCol_(whichrow));
1070}
1071
1072std::vector< double > Scantable::getAbcissa( int whichrow ) const
1073{
1074 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal row number"));
1075 std::vector<double> stlout;
1076 int nchan = specCol_(whichrow).nelements();
1077 String us = freqTable_.getUnitString();
1078 if ( us == "" || us == "pixel" || us == "channel" ) {
1079 for (int i=0; i<nchan; ++i) {
1080 stlout.push_back(double(i));
1081 }
1082 return stlout;
1083 }
1084 SpectralCoordinate spc = getSpectralCoordinate(whichrow);
1085 Vector<Double> pixel(nchan);
1086 Vector<Double> world;
1087 indgen(pixel);
1088 if ( Unit(us) == Unit("Hz") ) {
1089 for ( int i=0; i < nchan; ++i) {
1090 Double world;
1091 spc.toWorld(world, pixel[i]);
1092 stlout.push_back(double(world));
1093 }
1094 } else if ( Unit(us) == Unit("km/s") ) {
1095 Vector<Double> world;
1096 spc.pixelToVelocity(world, pixel);
1097 world.tovector(stlout);
1098 }
1099 return stlout;
1100}
1101void Scantable::setDirectionRefString( const std::string & refstr )
1102{
1103 MDirection::Types mdt;
1104 if (refstr != "" && !MDirection::getType(mdt, refstr)) {
1105 throw(AipsError("Illegal Direction frame."));
1106 }
1107 if ( refstr == "" ) {
1108 String defaultstr = MDirection::showType(dirCol_.getMeasRef().getType());
1109 table_.rwKeywordSet().define("DIRECTIONREF", defaultstr);
1110 } else {
1111 table_.rwKeywordSet().define("DIRECTIONREF", String(refstr));
1112 }
1113}
1114
1115std::string Scantable::getDirectionRefString( ) const
1116{
1117 return table_.keywordSet().asString("DIRECTIONREF");
1118}
1119
1120MDirection Scantable::getDirection(int whichrow ) const
1121{
1122 String usertype = table_.keywordSet().asString("DIRECTIONREF");
1123 String type = MDirection::showType(dirCol_.getMeasRef().getType());
1124 if ( usertype != type ) {
1125 MDirection::Types mdt;
1126 if (!MDirection::getType(mdt, usertype)) {
1127 throw(AipsError("Illegal Direction frame."));
1128 }
1129 return dirCol_.convert(uInt(whichrow), mdt);
1130 } else {
1131 return dirCol_(uInt(whichrow));
1132 }
1133}
1134
1135std::string Scantable::getAbcissaLabel( int whichrow ) const
1136{
1137 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal ro number"));
1138 const MPosition& mp = getAntennaPosition();
1139 const MDirection& md = getDirection(whichrow);
1140 const MEpoch& me = timeCol_(whichrow);
1141 //const Double& rf = mmolidCol_(whichrow);
1142 const Vector<Double> rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
1143 SpectralCoordinate spc =
1144 freqTable_.getSpectralCoordinate(md, mp, me, rf, mfreqidCol_(whichrow));
1145
1146 String s = "Channel";
1147 Unit u = Unit(freqTable_.getUnitString());
1148 if (u == Unit("km/s")) {
1149 s = CoordinateUtil::axisLabel(spc, 0, True,True, True);
1150 } else if (u == Unit("Hz")) {
1151 Vector<String> wau(1);wau = u.getName();
1152 spc.setWorldAxisUnits(wau);
1153 s = CoordinateUtil::axisLabel(spc, 0, True, True, False);
1154 }
1155 return s;
1156
1157}
1158
1159/**
1160void asap::Scantable::setRestFrequencies( double rf, const std::string& name,
1161 const std::string& unit )
1162**/
1163void Scantable::setRestFrequencies( vector<double> rf, const vector<std::string>& name,
1164 const std::string& unit )
1165
1166{
1167 ///@todo lookup in line table to fill in name and formattedname
1168 Unit u(unit);
1169 //Quantum<Double> urf(rf, u);
1170 Quantum<Vector<Double> >urf(rf, u);
1171 Vector<String> formattedname(0);
1172 //cerr<<"Scantable::setRestFrequnecies="<<urf<<endl;
1173
1174 //uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), name, "");
1175 uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), mathutil::toVectorString(name), formattedname);
1176 TableVector<uInt> tabvec(table_, "MOLECULE_ID");
1177 tabvec = id;
1178}
1179
1180/**
1181void asap::Scantable::setRestFrequencies( const std::string& name )
1182{
1183 throw(AipsError("setRestFrequencies( const std::string& name ) NYI"));
1184 ///@todo implement
1185}
1186**/
1187void Scantable::setRestFrequencies( const vector<std::string>& name )
1188{
1189 throw(AipsError("setRestFrequencies( const vector<std::string>& name ) NYI"));
1190 ///@todo implement
1191}
1192
1193std::vector< unsigned int > Scantable::rownumbers( ) const
1194{
1195 std::vector<unsigned int> stlout;
1196 Vector<uInt> vec = table_.rowNumbers();
1197 vec.tovector(stlout);
1198 return stlout;
1199}
1200
1201
1202Matrix<Float> Scantable::getPolMatrix( uInt whichrow ) const
1203{
1204 ROTableRow row(table_);
1205 const TableRecord& rec = row.get(whichrow);
1206 Table t =
1207 originalTable_( originalTable_.col("SCANNO") == Int(rec.asuInt("SCANNO"))
1208 && originalTable_.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
1209 && originalTable_.col("IFNO") == Int(rec.asuInt("IFNO"))
1210 && originalTable_.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
1211 ROArrayColumn<Float> speccol(t, "SPECTRA");
1212 return speccol.getColumn();
1213}
1214
1215std::vector< std::string > Scantable::columnNames( ) const
1216{
1217 Vector<String> vec = table_.tableDesc().columnNames();
1218 return mathutil::tovectorstring(vec);
1219}
1220
1221MEpoch::Types Scantable::getTimeReference( ) const
1222{
1223 return MEpoch::castType(timeCol_.getMeasRef().getType());
1224}
1225
1226void Scantable::addFit( const STFitEntry& fit, int row )
1227{
1228 //cout << mfitidCol_(uInt(row)) << endl;
1229 LogIO os( LogOrigin( "Scantable", "addFit()", WHERE ) ) ;
1230 os << mfitidCol_(uInt(row)) << LogIO::POST ;
1231 uInt id = fitTable_.addEntry(fit, mfitidCol_(uInt(row)));
1232 mfitidCol_.put(uInt(row), id);
1233}
1234
1235void Scantable::shift(int npix)
1236{
1237 Vector<uInt> fids(mfreqidCol_.getColumn());
1238 genSort( fids, Sort::Ascending,
1239 Sort::QuickSort|Sort::NoDuplicates );
1240 for (uInt i=0; i<fids.nelements(); ++i) {
1241 frequencies().shiftRefPix(npix, fids[i]);
1242 }
1243}
1244
1245std::string Scantable::getAntennaName() const
1246{
1247 String out;
1248 table_.keywordSet().get("AntennaName", out);
1249 return out;
1250}
1251
1252int Scantable::checkScanInfo(const std::vector<int>& scanlist) const
1253{
1254 String tbpath;
1255 int ret = 0;
1256 if ( table_.keywordSet().isDefined("GBT_GO") ) {
1257 table_.keywordSet().get("GBT_GO", tbpath);
1258 Table t(tbpath,Table::Old);
1259 // check each scan if other scan of the pair exist
1260 int nscan = scanlist.size();
1261 for (int i = 0; i < nscan; i++) {
1262 Table subt = t( t.col("SCAN") == scanlist[i]+1 );
1263 if (subt.nrow()==0) {
1264 //cerr <<"Scan "<<scanlist[i]<<" cannot be found in the scantable."<<endl;
1265 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1266 os <<LogIO::WARN<<"Scan "<<scanlist[i]<<" cannot be found in the scantable."<<LogIO::POST;
1267 ret = 1;
1268 break;
1269 }
1270 ROTableRow row(subt);
1271 const TableRecord& rec = row.get(0);
1272 int scan1seqn = rec.asuInt("PROCSEQN");
1273 int laston1 = rec.asuInt("LASTON");
1274 if ( rec.asuInt("PROCSIZE")==2 ) {
1275 if ( i < nscan-1 ) {
1276 Table subt2 = t( t.col("SCAN") == scanlist[i+1]+1 );
1277 if ( subt2.nrow() == 0) {
1278 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1279
1280 //cerr<<"Scan "<<scanlist[i+1]<<" cannot be found in the scantable."<<endl;
1281 os<<LogIO::WARN<<"Scan "<<scanlist[i+1]<<" cannot be found in the scantable."<<LogIO::POST;
1282 ret = 1;
1283 break;
1284 }
1285 ROTableRow row2(subt2);
1286 const TableRecord& rec2 = row2.get(0);
1287 int scan2seqn = rec2.asuInt("PROCSEQN");
1288 int laston2 = rec2.asuInt("LASTON");
1289 if (scan1seqn == 1 && scan2seqn == 2) {
1290 if (laston1 == laston2) {
1291 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1292 //cerr<<"A valid scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
1293 os<<"A valid scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<LogIO::POST;
1294 i +=1;
1295 }
1296 else {
1297 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1298 //cerr<<"Incorrect scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<endl;
1299 os<<LogIO::WARN<<"Incorrect scan pair ["<<scanlist[i]<<","<<scanlist[i+1]<<"]"<<LogIO::POST;
1300 }
1301 }
1302 else if (scan1seqn==2 && scan2seqn == 1) {
1303 if (laston1 == laston2) {
1304 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1305 //cerr<<"["<<scanlist[i]<<","<<scanlist[i+1]<<"] is a valid scan pair but in incorrect order."<<endl;
1306 os<<LogIO::WARN<<"["<<scanlist[i]<<","<<scanlist[i+1]<<"] is a valid scan pair but in incorrect order."<<LogIO::POST;
1307 ret = 1;
1308 break;
1309 }
1310 }
1311 else {
1312 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1313 //cerr<<"The other scan for "<<scanlist[i]<<" appears to be missing. Check the input scan numbers."<<endl;
1314 os<<LogIO::WARN<<"The other scan for "<<scanlist[i]<<" appears to be missing. Check the input scan numbers."<<LogIO::POST;
1315 ret = 1;
1316 break;
1317 }
1318 }
1319 }
1320 else {
1321 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1322 //cerr<<"The scan does not appear to be standard obsevation."<<endl;
1323 os<<LogIO::WARN<<"The scan does not appear to be standard obsevation."<<LogIO::POST;
1324 }
1325 //if ( i >= nscan ) break;
1326 }
1327 }
1328 else {
1329 LogIO os( LogOrigin( "Scantable", "checkScanInfo()", WHERE ) ) ;
1330 //cerr<<"No reference to GBT_GO table."<<endl;
1331 os<<LogIO::WARN<<"No reference to GBT_GO table."<<LogIO::POST;
1332 ret = 1;
1333 }
1334 return ret;
1335}
1336
1337std::vector<double> Scantable::getDirectionVector(int whichrow) const
1338{
1339 Vector<Double> Dir = dirCol_(whichrow).getAngle("rad").getValue();
1340 std::vector<double> dir;
1341 Dir.tovector(dir);
1342 return dir;
1343}
1344
1345void asap::Scantable::reshapeSpectrum( int nmin, int nmax )
1346 throw( casa::AipsError )
1347{
1348 // assumed that all rows have same nChan
1349 Vector<Float> arr = specCol_( 0 ) ;
1350 int nChan = arr.nelements() ;
1351
1352 // if nmin < 0 or nmax < 0, nothing to do
1353 if ( nmin < 0 ) {
1354 throw( casa::indexError<int>( nmin, "asap::Scantable::reshapeSpectrum: Invalid range. Negative index is specified." ) ) ;
1355 }
1356 if ( nmax < 0 ) {
1357 throw( casa::indexError<int>( nmax, "asap::Scantable::reshapeSpectrum: Invalid range. Negative index is specified." ) ) ;
1358 }
1359
1360 // if nmin > nmax, exchange values
1361 if ( nmin > nmax ) {
1362 int tmp = nmax ;
1363 nmax = nmin ;
1364 nmin = tmp ;
1365 LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
1366 os << "Swap values. Applied range is ["
1367 << nmin << ", " << nmax << "]" << LogIO::POST ;
1368 }
1369
1370 // if nmin exceeds nChan, nothing to do
1371 if ( nmin >= nChan ) {
1372 throw( casa::indexError<int>( nmin, "asap::Scantable::reshapeSpectrum: Invalid range. Specified minimum exceeds nChan." ) ) ;
1373 }
1374
1375 // if nmax exceeds nChan, reset nmax to nChan
1376 if ( nmax >= nChan ) {
1377 if ( nmin == 0 ) {
1378 // nothing to do
1379 LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
1380 os << "Whole range is selected. Nothing to do." << LogIO::POST ;
1381 return ;
1382 }
1383 else {
1384 LogIO os( LogOrigin( "Scantable", "reshapeSpectrum()", WHERE ) ) ;
1385 os << "Specified maximum exceeds nChan. Applied range is ["
1386 << nmin << ", " << nChan-1 << "]." << LogIO::POST ;
1387 nmax = nChan - 1 ;
1388 }
1389 }
1390
1391 // reshape specCol_ and flagCol_
1392 for ( int irow = 0 ; irow < nrow() ; irow++ ) {
1393 reshapeSpectrum( nmin, nmax, irow ) ;
1394 }
1395
1396 // update FREQUENCIES subtable
1397 Double refpix ;
1398 Double refval ;
1399 Double increment ;
1400 int freqnrow = freqTable_.table().nrow() ;
1401 Vector<uInt> oldId( freqnrow ) ;
1402 Vector<uInt> newId( freqnrow ) ;
1403 for ( int irow = 0 ; irow < freqnrow ; irow++ ) {
1404 freqTable_.getEntry( refpix, refval, increment, irow ) ;
1405 /***
1406 * need to shift refpix to nmin
1407 * note that channel nmin in old index will be channel 0 in new one
1408 ***/
1409 refval = refval - ( refpix - nmin ) * increment ;
1410 refpix = 0 ;
1411 freqTable_.setEntry( refpix, refval, increment, irow ) ;
1412 }
1413
1414 // update nchan
1415 int newsize = nmax - nmin + 1 ;
1416 table_.rwKeywordSet().define( "nChan", newsize ) ;
1417
1418 // update bandwidth
1419 // assumed all spectra in the scantable have same bandwidth
1420 table_.rwKeywordSet().define( "Bandwidth", increment * newsize ) ;
1421
1422 return ;
1423}
1424
1425void asap::Scantable::reshapeSpectrum( int nmin, int nmax, int irow )
1426{
1427 // reshape specCol_ and flagCol_
1428 Vector<Float> oldspec = specCol_( irow ) ;
1429 Vector<uChar> oldflag = flagsCol_( irow ) ;
1430 uInt newsize = nmax - nmin + 1 ;
1431 specCol_.put( irow, oldspec( Slice( nmin, newsize, 1 ) ) ) ;
1432 flagsCol_.put( irow, oldflag( Slice( nmin, newsize, 1 ) ) ) ;
1433
1434 return ;
1435}
1436
1437void asap::Scantable::regridChannel( int nChan, double dnu )
1438{
1439 LogIO os( LogOrigin( "Scantable", "regridChannel()", WHERE ) ) ;
1440 os << "Regrid abcissa with channel number " << nChan << " and spectral resoultion " << dnu << "Hz." << LogIO::POST ;
1441 // assumed that all rows have same nChan
1442 Vector<Float> arr = specCol_( 0 ) ;
1443 int oldsize = arr.nelements() ;
1444
1445 // if oldsize == nChan, nothing to do
1446 if ( oldsize == nChan ) {
1447 os << "Specified channel number is same as current one. Nothing to do." << LogIO::POST ;
1448 return ;
1449 }
1450
1451 // if oldChan < nChan, unphysical operation
1452 if ( oldsize < nChan ) {
1453 os << "Unphysical operation. Nothing to do." << LogIO::POST ;
1454 return ;
1455 }
1456
1457 // change channel number for specCol_ and flagCol_
1458 Vector<Float> newspec( nChan, 0 ) ;
1459 Vector<uChar> newflag( nChan, false ) ;
1460 vector<string> coordinfo = getCoordInfo() ;
1461 string oldinfo = coordinfo[0] ;
1462 coordinfo[0] = "Hz" ;
1463 setCoordInfo( coordinfo ) ;
1464 for ( int irow = 0 ; irow < nrow() ; irow++ ) {
1465 regridChannel( nChan, dnu, irow ) ;
1466 }
1467 coordinfo[0] = oldinfo ;
1468 setCoordInfo( coordinfo ) ;
1469
1470
1471 // NOTE: this method does not update metadata such as
1472 // FREQUENCIES subtable, nChan, Bandwidth, etc.
1473
1474 return ;
1475}
1476
1477void asap::Scantable::regridChannel( int nChan, double dnu, int irow )
1478{
1479 // logging
1480 //ofstream ofs( "average.log", std::ios::out | std::ios::app ) ;
1481 //ofs << "IFNO = " << getIF( irow ) << " irow = " << irow << endl ;
1482
1483 Vector<Float> oldspec = specCol_( irow ) ;
1484 Vector<uChar> oldflag = flagsCol_( irow ) ;
1485 Vector<Float> newspec( nChan, 0 ) ;
1486 Vector<uChar> newflag( nChan, false ) ;
1487
1488 // regrid
1489 vector<double> abcissa = getAbcissa( irow ) ;
1490 int oldsize = abcissa.size() ;
1491 double olddnu = abcissa[1] - abcissa[0] ;
1492 //int refChan = 0 ;
1493 //double frac = 0.0 ;
1494 //double wedge = 0.0 ;
1495 //double pile = 0.0 ;
1496 int ichan = 0 ;
1497 double wsum = 0.0 ;
1498 Vector<Float> z( nChan ) ;
1499 z[0] = abcissa[0] - 0.5 * olddnu + 0.5 * dnu ;
1500 for ( int ii = 1 ; ii < nChan ; ii++ )
1501 z[ii] = z[ii-1] + dnu ;
1502 Vector<Float> zi( nChan+1 ) ;
1503 Vector<Float> yi( oldsize + 1 ) ;
1504 zi[0] = z[0] - 0.5 * dnu ;
1505 zi[1] = z[0] + 0.5 * dnu ;
1506 for ( int ii = 2 ; ii < nChan ; ii++ )
1507 zi[ii] = zi[ii-1] + dnu ;
1508 zi[nChan] = z[nChan-1] + 0.5 * dnu ;
1509 yi[0] = abcissa[0] - 0.5 * olddnu ;
1510 yi[1] = abcissa[1] + 0.5 * olddnu ;
1511 for ( int ii = 2 ; ii < oldsize ; ii++ )
1512 yi[ii] = abcissa[ii-1] + olddnu ;
1513 yi[oldsize] = abcissa[oldsize-1] + 0.5 * olddnu ;
1514 if ( dnu > 0.0 ) {
1515 for ( int ii = 0 ; ii < nChan ; ii++ ) {
1516 double zl = zi[ii] ;
1517 double zr = zi[ii+1] ;
1518 for ( int j = ichan ; j < oldsize ; j++ ) {
1519 double yl = yi[j] ;
1520 double yr = yi[j+1] ;
1521 if ( yl <= zl ) {
1522 if ( yr <= zl ) {
1523 continue ;
1524 }
1525 else if ( yr <= zr ) {
1526 newspec[ii] += oldspec[j] * ( yr - zl ) ;
1527 newflag[ii] = newflag[ii] || oldflag[j] ;
1528 wsum += ( yr - zl ) ;
1529 }
1530 else {
1531 newspec[ii] += oldspec[j] * dnu ;
1532 newflag[ii] = newflag[ii] || oldflag[j] ;
1533 wsum += dnu ;
1534 ichan = j ;
1535 break ;
1536 }
1537 }
1538 else if ( yl < zr ) {
1539 if ( yr <= zr ) {
1540 newspec[ii] += oldspec[j] * ( yr - yl ) ;
1541 newflag[ii] = newflag[ii] || oldflag[j] ;
1542 wsum += ( yr - yl ) ;
1543 }
1544 else {
1545 newspec[ii] += oldspec[j] * ( zr - yl ) ;
1546 newflag[ii] = newflag[ii] || oldflag[j] ;
1547 wsum += ( zr - yl ) ;
1548 ichan = j ;
1549 break ;
1550 }
1551 }
1552 else {
1553 ichan = j - 1 ;
1554 break ;
1555 }
1556 }
1557 newspec[ii] /= wsum ;
1558 wsum = 0.0 ;
1559 }
1560 }
1561 else if ( dnu < 0.0 ) {
1562 for ( int ii = 0 ; ii < nChan ; ii++ ) {
1563 double zl = zi[ii] ;
1564 double zr = zi[ii+1] ;
1565 for ( int j = ichan ; j < oldsize ; j++ ) {
1566 double yl = yi[j] ;
1567 double yr = yi[j+1] ;
1568 if ( yl >= zl ) {
1569 if ( yr >= zl ) {
1570 continue ;
1571 }
1572 else if ( yr >= zr ) {
1573 newspec[ii] += oldspec[j] * abs( yr - zl ) ;
1574 newflag[ii] = newflag[ii] || oldflag[j] ;
1575 wsum += abs( yr - zl ) ;
1576 }
1577 else {
1578 newspec[ii] += oldspec[j] * abs( dnu ) ;
1579 newflag[ii] = newflag[ii] || oldflag[j] ;
1580 wsum += abs( dnu ) ;
1581 ichan = j ;
1582 break ;
1583 }
1584 }
1585 else if ( yl > zr ) {
1586 if ( yr >= zr ) {
1587 newspec[ii] += oldspec[j] * abs( yr - yl ) ;
1588 newflag[ii] = newflag[ii] || oldflag[j] ;
1589 wsum += abs( yr - yl ) ;
1590 }
1591 else {
1592 newspec[ii] += oldspec[j] * abs( zr - yl ) ;
1593 newflag[ii] = newflag[ii] || oldflag[j] ;
1594 wsum += abs( zr - yl ) ;
1595 ichan = j ;
1596 break ;
1597 }
1598 }
1599 else {
1600 ichan = j - 1 ;
1601 break ;
1602 }
1603 }
1604 newspec[ii] /= wsum ;
1605 wsum = 0.0 ;
1606 }
1607 }
1608// * ichan = 0
1609// ***/
1610// //ofs << "olddnu = " << olddnu << ", dnu = " << dnu << endl ;
1611// pile += dnu ;
1612// wedge = olddnu * ( refChan + 1 ) ;
1613// while ( wedge < pile ) {
1614// newspec[0] += olddnu * oldspec[refChan] ;
1615// newflag[0] = newflag[0] || oldflag[refChan] ;
1616// //ofs << "channel " << refChan << " is included in new channel 0" << endl ;
1617// refChan++ ;
1618// wedge += olddnu ;
1619// wsum += olddnu ;
1620// //ofs << "newspec[0] = " << newspec[0] << " wsum = " << wsum << endl ;
1621// }
1622// frac = ( wedge - pile ) / olddnu ;
1623// wsum += ( 1.0 - frac ) * olddnu ;
1624// newspec[0] += ( 1.0 - frac ) * olddnu * oldspec[refChan] ;
1625// newflag[0] = newflag[0] || oldflag[refChan] ;
1626// //ofs << "channel " << refChan << " is partly included in new channel 0" << " with fraction of " << ( 1.0 - frac ) << endl ;
1627// //ofs << "newspec[0] = " << newspec[0] << " wsum = " << wsum << endl ;
1628// newspec[0] /= wsum ;
1629// //ofs << "newspec[0] = " << newspec[0] << endl ;
1630// //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
1631
1632// /***
1633// * ichan = 1 - nChan-2
1634// ***/
1635// for ( int ichan = 1 ; ichan < nChan - 1 ; ichan++ ) {
1636// pile += dnu ;
1637// newspec[ichan] += frac * olddnu * oldspec[refChan] ;
1638// newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
1639// //ofs << "channel " << refChan << " is partly included in new channel " << ichan << " with fraction of " << frac << endl ;
1640// refChan++ ;
1641// wedge += olddnu ;
1642// wsum = frac * olddnu ;
1643// //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
1644// while ( wedge < pile ) {
1645// newspec[ichan] += olddnu * oldspec[refChan] ;
1646// newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
1647// //ofs << "channel " << refChan << " is included in new channel " << ichan << endl ;
1648// refChan++ ;
1649// wedge += olddnu ;
1650// wsum += olddnu ;
1651// //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
1652// }
1653// frac = ( wedge - pile ) / olddnu ;
1654// wsum += ( 1.0 - frac ) * olddnu ;
1655// newspec[ichan] += ( 1.0 - frac ) * olddnu * oldspec[refChan] ;
1656// newflag[ichan] = newflag[ichan] || oldflag[refChan] ;
1657// //ofs << "channel " << refChan << " is partly included in new channel " << ichan << " with fraction of " << ( 1.0 - frac ) << endl ;
1658// //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
1659// //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << " wsum = " << wsum << endl ;
1660// newspec[ichan] /= wsum ;
1661// //ofs << "newspec[" << ichan << "] = " << newspec[ichan] << endl ;
1662// }
1663
1664// /***
1665// * ichan = nChan-1
1666// ***/
1667// // NOTE: Assumed that all spectra have the same bandwidth
1668// pile += dnu ;
1669// newspec[nChan-1] += frac * olddnu * oldspec[refChan] ;
1670// newflag[nChan-1] = newflag[nChan-1] || oldflag[refChan] ;
1671// //ofs << "channel " << refChan << " is partly included in new channel " << nChan-1 << " with fraction of " << frac << endl ;
1672// refChan++ ;
1673// wedge += olddnu ;
1674// wsum = frac * olddnu ;
1675// //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
1676// for ( int jchan = refChan ; jchan < oldsize ; jchan++ ) {
1677// newspec[nChan-1] += olddnu * oldspec[jchan] ;
1678// newflag[nChan-1] = newflag[nChan-1] || oldflag[jchan] ;
1679// wsum += olddnu ;
1680// //ofs << "channel " << jchan << " is included in new channel " << nChan-1 << " with fraction of " << frac << endl ;
1681// //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
1682// }
1683// //ofs << "wedge = " << wedge << ", pile = " << pile << endl ;
1684// //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << " wsum = " << wsum << endl ;
1685// newspec[nChan-1] /= wsum ;
1686// //ofs << "newspec[" << nChan - 1 << "] = " << newspec[nChan-1] << endl ;
1687
1688// specCol_.put( irow, newspec ) ;
1689// flagsCol_.put( irow, newflag ) ;
1690
1691// // ofs.close() ;
1692
1693
1694 return ;
1695}
1696
1697std::vector<float> Scantable::getWeather(int whichrow) const
1698{
1699 std::vector<float> out(5);
1700 //Float temperature, pressure, humidity, windspeed, windaz;
1701 weatherTable_.getEntry(out[0], out[1], out[2], out[3], out[4],
1702 mweatheridCol_(uInt(whichrow)));
1703
1704
1705 return out;
1706}
1707
1708}
1709//namespace asap
Note: See TracBrowser for help on using the repository browser.