source: trunk/src/Scantable.cpp@ 1122

Last change on this file since 1122 was 1111, checked in by mar637, 18 years ago

add getNumbers utility function, which is now called by all function which retrieve numbers from the Scantable

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 30.4 KB
RevLine 
[805]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//
[206]12#include <map>
13
[125]14#include <casa/aips.h>
[80]15#include <casa/iostream.h>
16#include <casa/iomanip.h>
[805]17#include <casa/OS/Path.h>
18#include <casa/OS/File.h>
[80]19#include <casa/Arrays/Array.h>
20#include <casa/Arrays/ArrayMath.h>
21#include <casa/Arrays/MaskArrMath.h>
22#include <casa/Arrays/ArrayLogical.h>
23#include <casa/Arrays/ArrayAccessor.h>
[455]24#include <casa/Arrays/VectorSTLIterator.h>
[206]25#include <casa/Arrays/Vector.h>
[418]26#include <casa/BasicMath/Math.h>
[504]27#include <casa/BasicSL/Constants.h>
[286]28#include <casa/Quanta/MVAngle.h>
[805]29#include <casa/Containers/RecordField.h>
[902]30#include <casa/Utilities/GenSort.h>
[2]31
[80]32#include <tables/Tables/TableParse.h>
33#include <tables/Tables/TableDesc.h>
[488]34#include <tables/Tables/TableCopy.h>
[80]35#include <tables/Tables/SetupNewTab.h>
36#include <tables/Tables/ScaColDesc.h>
37#include <tables/Tables/ArrColDesc.h>
[805]38#include <tables/Tables/TableRow.h>
39#include <tables/Tables/TableVector.h>
40#include <tables/Tables/TableIter.h>
[2]41
[80]42#include <tables/Tables/ExprNode.h>
43#include <tables/Tables/TableRecord.h>
44#include <measures/Measures/MFrequency.h>
[805]45#include <measures/Measures/MEpoch.h>
[80]46#include <measures/Measures/MeasTable.h>
[805]47#include <measures/Measures/MeasRef.h>
48#include <measures/TableMeasures/TableMeasRefDesc.h>
49#include <measures/TableMeasures/TableMeasValueDesc.h>
50#include <measures/TableMeasures/TableMeasDesc.h>
51#include <measures/TableMeasures/ScalarMeasColumn.h>
[105]52#include <coordinates/Coordinates/CoordinateUtil.h>
[80]53#include <casa/Quanta/MVTime.h>
[281]54#include <casa/Quanta/MVAngle.h>
[2]55
[805]56#include "Scantable.h"
[896]57#include "STPolLinear.h"
[913]58#include "STPolStokes.h"
[878]59#include "STAttr.h"
[902]60#include "MathUtils.h"
[2]61
[125]62using namespace casa;
[2]63
[805]64namespace asap {
65
[896]66std::map<std::string, STPol::STPolFactory *> Scantable::factories_;
67
68void Scantable::initFactories() {
69 if ( factories_.empty() ) {
70 Scantable::factories_["linear"] = &STPolLinear::myFactory;
[913]71 Scantable::factories_["stokes"] = &STPolStokes::myFactory;
[896]72 }
73}
74
[805]75Scantable::Scantable(Table::TableType ttype) :
[852]76 type_(ttype)
[206]77{
[896]78 initFactories();
[805]79 setupMainTable();
[852]80 freqTable_ = STFrequencies(*this);
[805]81 table_.rwKeywordSet().defineTable("FREQUENCIES", freqTable_.table());
[852]82 weatherTable_ = STWeather(*this);
[805]83 table_.rwKeywordSet().defineTable("WEATHER", weatherTable_.table());
[852]84 focusTable_ = STFocus(*this);
[805]85 table_.rwKeywordSet().defineTable("FOCUS", focusTable_.table());
[852]86 tcalTable_ = STTcal(*this);
[805]87 table_.rwKeywordSet().defineTable("TCAL", tcalTable_.table());
[852]88 moleculeTable_ = STMolecules(*this);
[805]89 table_.rwKeywordSet().defineTable("MOLECULES", moleculeTable_.table());
[860]90 historyTable_ = STHistory(*this);
91 table_.rwKeywordSet().defineTable("HISTORY", historyTable_.table());
[959]92 fitTable_ = STFit(*this);
93 table_.rwKeywordSet().defineTable("FIT", fitTable_.table());
[805]94 originalTable_ = table_;
[322]95 attach();
[18]96}
[206]97
[805]98Scantable::Scantable(const std::string& name, Table::TableType ttype) :
[852]99 type_(ttype)
[206]100{
[896]101 initFactories();
[865]102 Table tab(name, Table::Update);
[1009]103 uInt version = tab.keywordSet().asuInt("VERSION");
[483]104 if (version != version_) {
105 throw(AipsError("Unsupported version of ASAP file."));
106 }
[1009]107 if ( type_ == Table::Memory ) {
[852]108 table_ = tab.copyToMemoryTable(generateName());
[1009]109 } else {
[805]110 table_ = tab;
[1009]111 }
112
[859]113 attachSubtables();
[805]114 originalTable_ = table_;
[329]115 attach();
[2]116}
117
[805]118Scantable::Scantable( const Scantable& other, bool clear )
[206]119{
[805]120 // with or without data
[859]121 String newname = String(generateName());
[865]122 type_ = other.table_.tableType();
[859]123 if ( other.table_.tableType() == Table::Memory ) {
124 if ( clear ) {
125 table_ = TableCopy::makeEmptyMemoryTable(newname,
126 other.table_, True);
127 } else
128 table_ = other.table_.copyToMemoryTable(newname);
[16]129 } else {
[915]130 other.table_.deepCopy(newname, Table::New, False,
131 other.table_.endianFormat(),
[865]132 Bool(clear));
133 table_ = Table(newname, Table::Update);
134 table_.markForDelete();
135 }
[1111]136 /// @todo reindex SCANNO, recompute nbeam, nif, npol
[915]137 if ( clear ) copySubtables(other);
[859]138 attachSubtables();
[805]139 originalTable_ = table_;
[322]140 attach();
[2]141}
142
[865]143void Scantable::copySubtables(const Scantable& other) {
144 Table t = table_.rwKeywordSet().asTable("FREQUENCIES");
145 TableCopy::copyRows(t, other.freqTable_.table());
146 t = table_.rwKeywordSet().asTable("FOCUS");
147 TableCopy::copyRows(t, other.focusTable_.table());
148 t = table_.rwKeywordSet().asTable("WEATHER");
149 TableCopy::copyRows(t, other.weatherTable_.table());
150 t = table_.rwKeywordSet().asTable("TCAL");
151 TableCopy::copyRows(t, other.tcalTable_.table());
152 t = table_.rwKeywordSet().asTable("MOLECULES");
153 TableCopy::copyRows(t, other.moleculeTable_.table());
154 t = table_.rwKeywordSet().asTable("HISTORY");
155 TableCopy::copyRows(t, other.historyTable_.table());
[972]156 t = table_.rwKeywordSet().asTable("FIT");
157 TableCopy::copyRows(t, other.fitTable_.table());
[865]158}
159
[859]160void Scantable::attachSubtables()
161{
162 freqTable_ = STFrequencies(table_);
163 focusTable_ = STFocus(table_);
164 weatherTable_ = STWeather(table_);
165 tcalTable_ = STTcal(table_);
166 moleculeTable_ = STMolecules(table_);
[860]167 historyTable_ = STHistory(table_);
[972]168 fitTable_ = STFit(table_);
[859]169}
170
[805]171Scantable::~Scantable()
[206]172{
[941]173 //cout << "~Scantable() " << this << endl;
[2]174}
175
[805]176void Scantable::setupMainTable()
[206]177{
[805]178 TableDesc td("", "1", TableDesc::Scratch);
179 td.comment() = "An ASAP Scantable";
[1009]180 td.rwKeywordSet().define("VERSION", uInt(version_));
[2]181
[805]182 // n Cycles
183 td.addColumn(ScalarColumnDesc<uInt>("SCANNO"));
184 // new index every nBeam x nIF x nPol
185 td.addColumn(ScalarColumnDesc<uInt>("CYCLENO"));
[2]186
[805]187 td.addColumn(ScalarColumnDesc<uInt>("BEAMNO"));
188 td.addColumn(ScalarColumnDesc<uInt>("IFNO"));
[972]189 // linear, circular, stokes
[805]190 td.rwKeywordSet().define("POLTYPE", String("linear"));
191 td.addColumn(ScalarColumnDesc<uInt>("POLNO"));
[138]192
[805]193 td.addColumn(ScalarColumnDesc<uInt>("FREQ_ID"));
194 td.addColumn(ScalarColumnDesc<uInt>("MOLECULE_ID"));
195 td.addColumn(ScalarColumnDesc<Int>("REFBEAMNO"));
[80]196
[805]197 td.addColumn(ScalarColumnDesc<Double>("TIME"));
198 TableMeasRefDesc measRef(MEpoch::UTC); // UTC as default
199 TableMeasValueDesc measVal(td, "TIME");
200 TableMeasDesc<MEpoch> mepochCol(measVal, measRef);
201 mepochCol.write(td);
[483]202
[805]203 td.addColumn(ScalarColumnDesc<Double>("INTERVAL"));
204
[2]205 td.addColumn(ScalarColumnDesc<String>("SRCNAME"));
[805]206 // Type of source (on=0, off=1, other=-1)
207 td.addColumn(ScalarColumnDesc<Int>("SRCTYPE", Int(-1)));
208 td.addColumn(ScalarColumnDesc<String>("FIELDNAME"));
209
210 //The actual Data Vectors
[2]211 td.addColumn(ArrayColumnDesc<Float>("SPECTRA"));
212 td.addColumn(ArrayColumnDesc<uChar>("FLAGTRA"));
[89]213 td.addColumn(ArrayColumnDesc<Float>("TSYS"));
[805]214
215 td.addColumn(ArrayColumnDesc<Double>("DIRECTION",
216 IPosition(1,2),
217 ColumnDesc::Direct));
218 TableMeasRefDesc mdirRef(MDirection::J2000); // default
219 TableMeasValueDesc tmvdMDir(td, "DIRECTION");
220 // the TableMeasDesc gives the column a type
221 TableMeasDesc<MDirection> mdirCol(tmvdMDir, mdirRef);
[987]222 // a uder set table type e.g. GALCTIC, B1950 ...
223 td.rwKeywordSet().define("DIRECTIONREF", String("J2000"));
[805]224 // writing create the measure column
225 mdirCol.write(td);
[923]226 td.addColumn(ScalarColumnDesc<Float>("AZIMUTH"));
227 td.addColumn(ScalarColumnDesc<Float>("ELEVATION"));
[105]228 td.addColumn(ScalarColumnDesc<Float>("PARANGLE"));
[1047]229 td.addColumn(ScalarColumnDesc<Float>("OPACITY"));
[105]230
[805]231 td.addColumn(ScalarColumnDesc<uInt>("TCAL_ID"));
[972]232 ScalarColumnDesc<Int> fitColumn("FIT_ID");
[973]233 fitColumn.setDefault(Int(-1));
[972]234 td.addColumn(fitColumn);
[805]235
236 td.addColumn(ScalarColumnDesc<uInt>("FOCUS_ID"));
237 td.addColumn(ScalarColumnDesc<uInt>("WEATHER_ID"));
238
[999]239 // columns which just get dragged along, as they aren't used in asap
240 td.addColumn(ScalarColumnDesc<Double>("SRCVELOCITY"));
241 td.addColumn(ArrayColumnDesc<Double>("SRCPROPERMOTION"));
242 td.addColumn(ArrayColumnDesc<Double>("SRCDIRECTION"));
243 td.addColumn(ArrayColumnDesc<Double>("SCANRATE"));
244
[805]245 td.rwKeywordSet().define("OBSMODE", String(""));
246
[418]247 // Now create Table SetUp from the description.
[859]248 SetupNewTable aNewTab(generateName(), td, Table::Scratch);
[852]249 table_ = Table(aNewTab, type_, 0);
[805]250 originalTable_ = table_;
251}
[418]252
[455]253
[805]254void Scantable::attach()
[455]255{
[805]256 timeCol_.attach(table_, "TIME");
257 srcnCol_.attach(table_, "SRCNAME");
[1068]258 srctCol_.attach(table_, "SRCTYPE");
[805]259 specCol_.attach(table_, "SPECTRA");
260 flagsCol_.attach(table_, "FLAGTRA");
[865]261 tsysCol_.attach(table_, "TSYS");
[805]262 cycleCol_.attach(table_,"CYCLENO");
263 scanCol_.attach(table_, "SCANNO");
264 beamCol_.attach(table_, "BEAMNO");
[847]265 ifCol_.attach(table_, "IFNO");
266 polCol_.attach(table_, "POLNO");
[805]267 integrCol_.attach(table_, "INTERVAL");
268 azCol_.attach(table_, "AZIMUTH");
269 elCol_.attach(table_, "ELEVATION");
270 dirCol_.attach(table_, "DIRECTION");
271 paraCol_.attach(table_, "PARANGLE");
272 fldnCol_.attach(table_, "FIELDNAME");
273 rbeamCol_.attach(table_, "REFBEAMNO");
[455]274
[805]275 mfitidCol_.attach(table_,"FIT_ID");
276 mfreqidCol_.attach(table_, "FREQ_ID");
277 mtcalidCol_.attach(table_, "TCAL_ID");
278 mfocusidCol_.attach(table_, "FOCUS_ID");
279 mmolidCol_.attach(table_, "MOLECULE_ID");
[455]280}
281
[901]282void Scantable::setHeader(const STHeader& sdh)
[206]283{
[18]284 table_.rwKeywordSet().define("nIF", sdh.nif);
285 table_.rwKeywordSet().define("nBeam", sdh.nbeam);
286 table_.rwKeywordSet().define("nPol", sdh.npol);
287 table_.rwKeywordSet().define("nChan", sdh.nchan);
288 table_.rwKeywordSet().define("Observer", sdh.observer);
289 table_.rwKeywordSet().define("Project", sdh.project);
290 table_.rwKeywordSet().define("Obstype", sdh.obstype);
291 table_.rwKeywordSet().define("AntennaName", sdh.antennaname);
292 table_.rwKeywordSet().define("AntennaPosition", sdh.antennaposition);
293 table_.rwKeywordSet().define("Equinox", sdh.equinox);
294 table_.rwKeywordSet().define("FreqRefFrame", sdh.freqref);
295 table_.rwKeywordSet().define("FreqRefVal", sdh.reffreq);
296 table_.rwKeywordSet().define("Bandwidth", sdh.bandwidth);
297 table_.rwKeywordSet().define("UTC", sdh.utc);
[206]298 table_.rwKeywordSet().define("FluxUnit", sdh.fluxunit);
299 table_.rwKeywordSet().define("Epoch", sdh.epoch);
[905]300 table_.rwKeywordSet().define("POLTYPE", sdh.poltype);
[50]301}
[21]302
[901]303STHeader Scantable::getHeader() const
[206]304{
[901]305 STHeader sdh;
[21]306 table_.keywordSet().get("nBeam",sdh.nbeam);
307 table_.keywordSet().get("nIF",sdh.nif);
308 table_.keywordSet().get("nPol",sdh.npol);
309 table_.keywordSet().get("nChan",sdh.nchan);
310 table_.keywordSet().get("Observer", sdh.observer);
311 table_.keywordSet().get("Project", sdh.project);
312 table_.keywordSet().get("Obstype", sdh.obstype);
313 table_.keywordSet().get("AntennaName", sdh.antennaname);
314 table_.keywordSet().get("AntennaPosition", sdh.antennaposition);
315 table_.keywordSet().get("Equinox", sdh.equinox);
316 table_.keywordSet().get("FreqRefFrame", sdh.freqref);
317 table_.keywordSet().get("FreqRefVal", sdh.reffreq);
318 table_.keywordSet().get("Bandwidth", sdh.bandwidth);
319 table_.keywordSet().get("UTC", sdh.utc);
[206]320 table_.keywordSet().get("FluxUnit", sdh.fluxunit);
321 table_.keywordSet().get("Epoch", sdh.epoch);
[905]322 table_.keywordSet().get("POLTYPE", sdh.poltype);
[21]323 return sdh;
[18]324}
[805]325
[1068]326void asap::Scantable::setSourceType( int stype )
327{
328 if ( stype < 0 || stype > 1 )
329 throw(AipsError("Illegal sourcetype."));
330 TableVector<Int> tabvec(table_, "SRCTYPE");
331 tabvec = Int(stype);
332}
333
[845]334bool Scantable::conformant( const Scantable& other )
335{
336 return this->getHeader().conformant(other.getHeader());
337}
338
339
[50]340
[805]341std::string Scantable::formatSec(Double x) const
[206]342{
[105]343 Double xcop = x;
344 MVTime mvt(xcop/24./3600.); // make days
[365]345
[105]346 if (x < 59.95)
[281]347 return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_HM, 7)+"s";
[745]348 else if (x < 3599.95)
[281]349 return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_H,7)+" ";
350 else {
351 ostringstream oss;
352 oss << setw(2) << std::right << setprecision(1) << mvt.hour();
353 oss << ":" << mvt.string(MVTime::TIME_CLEAN_NO_H,7) << " ";
354 return String(oss);
[745]355 }
[105]356};
357
[805]358std::string Scantable::formatDirection(const MDirection& md) const
[281]359{
360 Vector<Double> t = md.getAngle(Unit(String("rad"))).getValue();
361 Int prec = 7;
362
363 MVAngle mvLon(t[0]);
364 String sLon = mvLon.string(MVAngle::TIME,prec);
[987]365 uInt tp = md.getRef().getType();
366 if (tp == MDirection::GALACTIC ||
367 tp == MDirection::SUPERGAL ) {
368 sLon = mvLon(0.0).string(MVAngle::ANGLE_CLEAN,prec);
369 }
[281]370 MVAngle mvLat(t[1]);
371 String sLat = mvLat.string(MVAngle::ANGLE+MVAngle::DIG2,prec);
[380]372 return sLon + String(" ") + sLat;
[281]373}
374
375
[805]376std::string Scantable::getFluxUnit() const
[206]377{
[847]378 return table_.keywordSet().asString("FluxUnit");
[206]379}
380
[805]381void Scantable::setFluxUnit(const std::string& unit)
[218]382{
383 String tmp(unit);
384 Unit tU(tmp);
385 if (tU==Unit("K") || tU==Unit("Jy")) {
386 table_.rwKeywordSet().define(String("FluxUnit"), tmp);
387 } else {
388 throw AipsError("Illegal unit - must be compatible with Jy or K");
389 }
390}
391
[805]392void Scantable::setInstrument(const std::string& name)
[236]393{
[805]394 bool throwIt = true;
[996]395 // create an Instrument to see if this is valid
396 STAttr::convertInstrument(name, throwIt);
[236]397 String nameU(name);
398 nameU.upcase();
399 table_.rwKeywordSet().define(String("AntennaName"), nameU);
400}
401
[805]402MPosition Scantable::getAntennaPosition () const
403{
404 Vector<Double> antpos;
405 table_.keywordSet().get("AntennaPosition", antpos);
406 MVPosition mvpos(antpos(0),antpos(1),antpos(2));
407 return MPosition(mvpos);
408}
[281]409
[805]410void Scantable::makePersistent(const std::string& filename)
411{
412 String inname(filename);
413 Path path(inname);
[1111]414 /// @todo reindex SCANNO, recompute nbeam, nif, npol
[805]415 inname = path.expandedName();
416 table_.deepCopy(inname, Table::New);
417}
418
[837]419int Scantable::nbeam( int scanno ) const
[805]420{
421 if ( scanno < 0 ) {
422 Int n;
423 table_.keywordSet().get("nBeam",n);
424 return int(n);
[105]425 } else {
[805]426 // take the first POLNO,IFNO,CYCLENO as nbeam shouldn't vary with these
[888]427 Table t = table_(table_.col("SCANNO") == scanno);
428 ROTableRow row(t);
429 const TableRecord& rec = row.get(0);
430 Table subt = t( t.col("IFNO") == Int(rec.asuInt("IFNO"))
431 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
432 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
433 ROTableVector<uInt> v(subt, "BEAMNO");
[805]434 return int(v.nelements());
[105]435 }
[805]436 return 0;
437}
[455]438
[837]439int Scantable::nif( int scanno ) const
[805]440{
441 if ( scanno < 0 ) {
442 Int n;
443 table_.keywordSet().get("nIF",n);
444 return int(n);
445 } else {
446 // take the first POLNO,BEAMNO,CYCLENO as nbeam shouldn't vary with these
[888]447 Table t = table_(table_.col("SCANNO") == scanno);
448 ROTableRow row(t);
449 const TableRecord& rec = row.get(0);
450 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
451 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
452 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
453 if ( subt.nrow() == 0 ) return 0;
454 ROTableVector<uInt> v(subt, "IFNO");
[805]455 return int(v.nelements());
[2]456 }
[805]457 return 0;
458}
[321]459
[837]460int Scantable::npol( int scanno ) const
[805]461{
462 if ( scanno < 0 ) {
463 Int n;
464 table_.keywordSet().get("nPol",n);
465 return n;
466 } else {
467 // take the first POLNO,IFNO,CYCLENO as nbeam shouldn't vary with these
[888]468 Table t = table_(table_.col("SCANNO") == scanno);
469 ROTableRow row(t);
470 const TableRecord& rec = row.get(0);
471 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
472 && t.col("IFNO") == Int(rec.asuInt("IFNO"))
473 && t.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
474 if ( subt.nrow() == 0 ) return 0;
475 ROTableVector<uInt> v(subt, "POLNO");
[805]476 return int(v.nelements());
[321]477 }
[805]478 return 0;
[2]479}
[805]480
[845]481int Scantable::ncycle( int scanno ) const
[206]482{
[805]483 if ( scanno < 0 ) {
[837]484 Block<String> cols(2);
485 cols[0] = "SCANNO";
486 cols[1] = "CYCLENO";
487 TableIterator it(table_, cols);
488 int n = 0;
489 while ( !it.pastEnd() ) {
490 ++n;
[902]491 ++it;
[837]492 }
493 return n;
[805]494 } else {
[888]495 Table t = table_(table_.col("SCANNO") == scanno);
496 ROTableRow row(t);
497 const TableRecord& rec = row.get(0);
498 Table subt = t( t.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
499 && t.col("POLNO") == Int(rec.asuInt("POLNO"))
500 && t.col("IFNO") == Int(rec.asuInt("IFNO")) );
501 if ( subt.nrow() == 0 ) return 0;
502 return int(subt.nrow());
[805]503 }
504 return 0;
[18]505}
[455]506
507
[845]508int Scantable::nrow( int scanno ) const
[805]509{
[845]510 return int(table_.nrow());
511}
512
513int Scantable::nchan( int ifno ) const
514{
515 if ( ifno < 0 ) {
[805]516 Int n;
517 table_.keywordSet().get("nChan",n);
518 return int(n);
519 } else {
[845]520 // take the first SCANNO,POLNO,BEAMNO,CYCLENO as nbeam shouldn't vary with these
[888]521 Table t = table_(table_.col("IFNO") == ifno);
522 if ( t.nrow() == 0 ) return 0;
523 ROArrayColumn<Float> v(t, "SPECTRA");
[923]524 return v.shape(0)(0);
[805]525 }
526 return 0;
[18]527}
[455]528
[1111]529int Scantable::nscan() const {
530 Vector<uInt> scannos(scanCol_.getColumn());
531 uInt nout = GenSort<uInt>::sort( scannos, Sort::Ascending,
532 Sort::QuickSort|Sort::NoDuplicates );
533 return int(nout);
534}
535
[923]536int Scantable::getChannels(int whichrow) const
537{
538 return specCol_.shape(whichrow)(0);
539}
[847]540
541int Scantable::getBeam(int whichrow) const
542{
543 return beamCol_(whichrow);
544}
545
[1111]546std::vector<uint> Scantable::getNumbers(ScalarColumn<uInt>& col)
547{
548 Vector<uInt> nos(col.getColumn());
549 GenSort<uInt>::sort( nos, Sort::Ascending,
550 Sort::QuickSort|Sort::NoDuplicates );
551 std::vector<uint> stlout;
552 nos.tovector(stlout);
553 return stlout;
554}
555
[847]556int Scantable::getIF(int whichrow) const
557{
558 return ifCol_(whichrow);
559}
560
561int Scantable::getPol(int whichrow) const
562{
563 return polCol_(whichrow);
564}
565
[805]566std::string Scantable::formatTime(const MEpoch& me, bool showdate) const
567{
568 MVTime mvt(me.getValue());
569 if (showdate)
570 mvt.setFormat(MVTime::YMD);
571 else
572 mvt.setFormat(MVTime::TIME);
573 ostringstream oss;
574 oss << mvt;
575 return String(oss);
576}
[488]577
[805]578void Scantable::calculateAZEL()
579{
580 MPosition mp = getAntennaPosition();
581 MEpoch::ROScalarColumn timeCol(table_, "TIME");
582 ostringstream oss;
583 oss << "Computed azimuth/elevation using " << endl
584 << mp << endl;
[996]585 for (Int i=0; i<nrow(); ++i) {
[805]586 MEpoch me = timeCol(i);
[987]587 MDirection md = getDirection(i);
[805]588 oss << " Time: " << formatTime(me,False) << " Direction: " << formatDirection(md)
589 << endl << " => ";
590 MeasFrame frame(mp, me);
591 Vector<Double> azel =
592 MDirection::Convert(md, MDirection::Ref(MDirection::AZEL,
593 frame)
594 )().getAngle("rad").getValue();
[923]595 azCol_.put(i,Float(azel[0]));
596 elCol_.put(i,Float(azel[1]));
[805]597 oss << "azel: " << azel[0]/C::pi*180.0 << " "
598 << azel[1]/C::pi*180.0 << " (deg)" << endl;
[16]599 }
[805]600 pushLog(String(oss));
601}
[89]602
[1000]603void Scantable::flag(const std::vector<bool>& msk)
[865]604{
[1026]605 if ( selector_.empty() && msk.size() == 0 )
[1000]606 throw(AipsError("Trying to flag whole scantable."));
607 if ( msk.size() == 0 ) {
608 uChar userflag = 1 << 7;
609 for ( uInt i=0; i<table_.nrow(); ++i) {
610 Vector<uChar> flgs = flagsCol_(i);
611 flgs = userflag;
612 flagsCol_.put(i, flgs);
613 }
614 return;
615 }
616 if ( int(msk.size()) != nchan() ) {
617 throw(AipsError("Mask has incorrect number of channels."));
618 }
619 for ( uInt i=0; i<table_.nrow(); ++i) {
620 Vector<uChar> flgs = flagsCol_(i);
621 if ( flgs.nelements() != msk.size() ) {
622 throw(AipsError("Mask has incorrect number of channels."
623 " Probably varying with IF. Please flag per IF"));
624 }
625 std::vector<bool>::const_iterator it;
626 uInt j = 0;
627 uChar userflag = 1 << 7;
628 for (it = msk.begin(); it != msk.end(); ++it) {
629 if ( *it ) {
630 flgs(j) = userflag;
631 }
632 ++j;
633 }
634 flagsCol_.put(i, flgs);
635 }
[865]636}
637
[805]638std::vector<bool> Scantable::getMask(int whichrow) const
639{
640 Vector<uChar> flags;
641 flagsCol_.get(uInt(whichrow), flags);
642 Vector<Bool> bflag(flags.shape());
643 convertArray(bflag, flags);
644 bflag = !bflag;
645 std::vector<bool> mask;
646 bflag.tovector(mask);
647 return mask;
648}
[89]649
[896]650std::vector<float> Scantable::getSpectrum( int whichrow,
[902]651 const std::string& poltype ) const
[805]652{
[905]653 String ptype = poltype;
654 if (poltype == "" ) ptype = getPolType();
[902]655 if ( whichrow < 0 || whichrow >= nrow() )
656 throw(AipsError("Illegal row number."));
[896]657 std::vector<float> out;
[805]658 Vector<Float> arr;
[896]659 uInt requestedpol = polCol_(whichrow);
660 String basetype = getPolType();
[905]661 if ( ptype == basetype ) {
[896]662 specCol_.get(whichrow, arr);
663 } else {
664 STPol* stpol = 0;
665 stpol =STPol::getPolClass(Scantable::factories_, basetype);
666 try {
667 uInt row = uInt(whichrow);
668 stpol->setSpectra(getPolMatrix(row));
[959]669 Float fang,fhand,parang;
670 fang = focusTable_.getTotalFeedAngle(mfocusidCol_(row));
671 fhand = focusTable_.getFeedHand(mfocusidCol_(row));
672 parang = paraCol_(row);
673 /// @todo re-enable this
674 // disable total feed angle to support paralactifying Caswell style
675 stpol->setPhaseCorrections(parang, -parang, fhand);
[905]676 arr = stpol->getSpectrum(requestedpol, ptype);
[896]677 delete stpol;
678 } catch (AipsError& e) {
679 delete stpol;
680 throw(e);
681 }
682 }
[902]683 if ( arr.nelements() == 0 )
684 pushLog("Not enough polarisations present to do the conversion.");
[805]685 arr.tovector(out);
686 return out;
[89]687}
[212]688
[884]689void asap::Scantable::setSpectrum( const std::vector<float>& spec,
690 int whichrow )
691{
692 Vector<Float> spectrum(spec);
693 Vector<Float> arr;
694 specCol_.get(whichrow, arr);
695 if ( spectrum.nelements() != arr.nelements() )
[896]696 throw AipsError("The spectrum has incorrect number of channels.");
[884]697 specCol_.put(whichrow, spectrum);
698}
699
700
[805]701String Scantable::generateName()
[745]702{
[805]703 return (File::newUniqueName("./","temp")).baseName();
[212]704}
705
[805]706const casa::Table& Scantable::table( ) const
[212]707{
[805]708 return table_;
[212]709}
710
[805]711casa::Table& Scantable::table( )
[386]712{
[805]713 return table_;
[386]714}
715
[896]716std::string Scantable::getPolType() const
717{
718 return table_.keywordSet().asString("POLTYPE");
719}
720
[805]721void Scantable::unsetSelection()
[380]722{
[805]723 table_ = originalTable_;
[847]724 attach();
[805]725 selector_.reset();
[380]726}
[386]727
[805]728void Scantable::setSelection( const STSelector& selection )
[430]729{
[805]730 Table tab = const_cast<STSelector&>(selection).apply(originalTable_);
731 if ( tab.nrow() == 0 ) {
732 throw(AipsError("Selection contains no data. Not applying it."));
733 }
734 table_ = tab;
[847]735 attach();
[805]736 selector_ = selection;
[430]737}
738
[837]739std::string Scantable::summary( bool verbose )
[447]740{
[805]741 // Format header info
742 ostringstream oss;
743 oss << endl;
744 oss << asap::SEPERATOR << endl;
745 oss << " Scan Table Summary" << endl;
746 oss << asap::SEPERATOR << endl;
747 oss.flags(std::ios_base::left);
748 oss << setw(15) << "Beams:" << setw(4) << nbeam() << endl
749 << setw(15) << "IFs:" << setw(4) << nif() << endl
[896]750 << setw(15) << "Polarisations:" << setw(4) << npol()
751 << "(" << getPolType() << ")" << endl
[805]752 << setw(15) << "Channels:" << setw(4) << nchan() << endl;
753 oss << endl;
754 String tmp;
[860]755 oss << setw(15) << "Observer:"
756 << table_.keywordSet().asString("Observer") << endl;
[805]757 oss << setw(15) << "Obs Date:" << getTime(-1,true) << endl;
758 table_.keywordSet().get("Project", tmp);
759 oss << setw(15) << "Project:" << tmp << endl;
760 table_.keywordSet().get("Obstype", tmp);
761 oss << setw(15) << "Obs. Type:" << tmp << endl;
762 table_.keywordSet().get("AntennaName", tmp);
763 oss << setw(15) << "Antenna Name:" << tmp << endl;
764 table_.keywordSet().get("FluxUnit", tmp);
765 oss << setw(15) << "Flux Unit:" << tmp << endl;
[941]766 Vector<Double> vec(moleculeTable_.getRestFrequencies());
[805]767 oss << setw(15) << "Rest Freqs:";
768 if (vec.nelements() > 0) {
769 oss << setprecision(10) << vec << " [Hz]" << endl;
770 } else {
771 oss << "none" << endl;
772 }
[941]773
774 oss << setw(15) << "Abcissa:" << getAbcissaLabel(0) << endl;
[805]775 oss << selector_.print() << endl;
776 oss << endl;
777 // main table
778 String dirtype = "Position ("
[987]779 + getDirectionRefString()
[805]780 + ")";
[941]781 oss << setw(5) << "Scan" << setw(15) << "Source"
782 << setw(10) << "Time" << setw(18) << "Integration" << endl;
783 oss << setw(5) << "" << setw(5) << "Beam" << setw(3) << "" << dirtype << endl;
784 oss << setw(10) << "" << setw(3) << "IF" << setw(6) << ""
[805]785 << setw(8) << "Frame" << setw(16)
786 << "RefVal" << setw(10) << "RefPix" << setw(12) << "Increment" <<endl;
787 oss << asap::SEPERATOR << endl;
788 TableIterator iter(table_, "SCANNO");
789 while (!iter.pastEnd()) {
790 Table subt = iter.table();
791 ROTableRow row(subt);
792 MEpoch::ROScalarColumn timeCol(subt,"TIME");
793 const TableRecord& rec = row.get(0);
794 oss << setw(4) << std::right << rec.asuInt("SCANNO")
795 << std::left << setw(1) << ""
796 << setw(15) << rec.asString("SRCNAME")
797 << setw(10) << formatTime(timeCol(0), false);
798 // count the cycles in the scan
799 TableIterator cyciter(subt, "CYCLENO");
800 int nint = 0;
801 while (!cyciter.pastEnd()) {
802 ++nint;
803 ++cyciter;
804 }
805 oss << setw(3) << std::right << nint << setw(3) << " x " << std::left
806 << setw(6) << formatSec(rec.asFloat("INTERVAL")) << endl;
[447]807
[805]808 TableIterator biter(subt, "BEAMNO");
809 while (!biter.pastEnd()) {
810 Table bsubt = biter.table();
811 ROTableRow brow(bsubt);
812 const TableRecord& brec = brow.get(0);
[1000]813 uInt row0 = bsubt.rowNumbers(table_)[0];
[941]814 oss << setw(5) << "" << setw(4) << std::right << brec.asuInt("BEAMNO")<< std::left;
[987]815 oss << setw(4) << "" << formatDirection(getDirection(row0)) << endl;
[805]816 TableIterator iiter(bsubt, "IFNO");
817 while (!iiter.pastEnd()) {
818 Table isubt = iiter.table();
819 ROTableRow irow(isubt);
820 const TableRecord& irec = irow.get(0);
[941]821 oss << setw(10) << "";
822 oss << setw(3) << std::right << irec.asuInt("IFNO") << std::left
823 << setw(2) << "" << frequencies().print(irec.asuInt("FREQ_ID"));
[447]824
[805]825 ++iiter;
826 }
827 ++biter;
828 }
829 ++iter;
[447]830 }
[805]831 /// @todo implement verbose mode
832 return String(oss);
[447]833}
834
[805]835std::string Scantable::getTime(int whichrow, bool showdate) const
[777]836{
[805]837 MEpoch::ROScalarColumn timeCol(table_, "TIME");
838 MEpoch me;
839 if (whichrow > -1) {
840 me = timeCol(uInt(whichrow));
841 } else {
842 Double tm;
843 table_.keywordSet().get("UTC",tm);
844 me = MEpoch(MVEpoch(tm));
[777]845 }
[805]846 return formatTime(me, showdate);
[777]847}
[805]848
[1068]849std::string Scantable::getDirectionString(int whichrow) const
850{
851 return formatDirection(getDirection(uInt(whichrow)));
852}
853
[865]854std::vector< double > asap::Scantable::getAbcissa( int whichrow ) const
855{
[996]856 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal ro number"));
[865]857 std::vector<double> stlout;
858 int nchan = specCol_(whichrow).nelements();
859 String us = freqTable_.getUnitString();
860 if ( us == "" || us == "pixel" || us == "channel" ) {
861 for (int i=0; i<nchan; ++i) {
862 stlout.push_back(double(i));
863 }
864 return stlout;
865 }
866
867 const MPosition& mp = getAntennaPosition();
[987]868 const MDirection& md = getDirection(whichrow);
[865]869 const MEpoch& me = timeCol_(whichrow);
870 Double rf = moleculeTable_.getRestFrequency(mmolidCol_(whichrow));
871 SpectralCoordinate spc =
872 freqTable_.getSpectralCoordinate(md, mp, me, rf, mfreqidCol_(whichrow));
873 Vector<Double> pixel(nchan);
874 Vector<Double> world;
875 indgen(pixel);
876 if ( Unit(us) == Unit("Hz") ) {
877 for ( int i=0; i < nchan; ++i) {
878 Double world;
879 spc.toWorld(world, pixel[i]);
880 stlout.push_back(double(world));
881 }
882 } else if ( Unit(us) == Unit("km/s") ) {
883 Vector<Double> world;
884 spc.pixelToVelocity(world, pixel);
885 world.tovector(stlout);
886 }
887 return stlout;
888}
[987]889void asap::Scantable::setDirectionRefString( const std::string & refstr )
890{
891 MDirection::Types mdt;
892 if (refstr != "" && !MDirection::getType(mdt, refstr)) {
893 throw(AipsError("Illegal Direction frame."));
894 }
895 if ( refstr == "" ) {
896 String defaultstr = MDirection::showType(dirCol_.getMeasRef().getType());
897 table_.rwKeywordSet().define("DIRECTIONREF", defaultstr);
898 } else {
899 table_.rwKeywordSet().define("DIRECTIONREF", String(refstr));
900 }
901}
[865]902
[987]903std::string asap::Scantable::getDirectionRefString( ) const
904{
905 return table_.keywordSet().asString("DIRECTIONREF");
906}
907
908MDirection Scantable::getDirection(int whichrow ) const
909{
910 String usertype = table_.keywordSet().asString("DIRECTIONREF");
911 String type = MDirection::showType(dirCol_.getMeasRef().getType());
912 if ( usertype != type ) {
913 MDirection::Types mdt;
914 if (!MDirection::getType(mdt, usertype)) {
915 throw(AipsError("Illegal Direction frame."));
916 }
917 return dirCol_.convert(uInt(whichrow), mdt);
918 } else {
919 return dirCol_(uInt(whichrow));
920 }
921}
922
[847]923std::string Scantable::getAbcissaLabel( int whichrow ) const
924{
[996]925 if ( whichrow > int(table_.nrow()) ) throw(AipsError("Illegal ro number"));
[847]926 const MPosition& mp = getAntennaPosition();
[987]927 const MDirection& md = getDirection(whichrow);
[847]928 const MEpoch& me = timeCol_(whichrow);
929 const Double& rf = mmolidCol_(whichrow);
930 SpectralCoordinate spc =
931 freqTable_.getSpectralCoordinate(md, mp, me, rf, mfreqidCol_(whichrow));
932
933 String s = "Channel";
934 Unit u = Unit(freqTable_.getUnitString());
935 if (u == Unit("km/s")) {
936 s = CoordinateUtil::axisLabel(spc,0,True,True,True);
937 } else if (u == Unit("Hz")) {
938 Vector<String> wau(1);wau = u.getName();
939 spc.setWorldAxisUnits(wau);
940 s = CoordinateUtil::axisLabel(spc,0,True,True,False);
941 }
942 return s;
943
944}
945
946void asap::Scantable::setRestFrequencies( double rf, const std::string& unit )
947{
[923]948 ///@todo lookup in line table to fill in name and formattedname
[847]949 Unit u(unit);
950 Quantum<Double> urf(rf, u);
951 uInt id = moleculeTable_.addEntry(urf.getValue("Hz"), "", "");
952 TableVector<uInt> tabvec(table_, "MOLECULE_ID");
953 tabvec = id;
954}
955
956void asap::Scantable::setRestFrequencies( const std::string& name )
957{
958 throw(AipsError("setRestFrequencies( const std::string& name ) NYI"));
959 ///@todo implement
960}
961
[852]962std::vector< unsigned int > asap::Scantable::rownumbers( ) const
963{
964 std::vector<unsigned int> stlout;
965 Vector<uInt> vec = table_.rowNumbers();
966 vec.tovector(stlout);
967 return stlout;
968}
969
[865]970
[896]971Matrix<Float> asap::Scantable::getPolMatrix( uInt whichrow ) const
972{
973 ROTableRow row(table_);
974 const TableRecord& rec = row.get(whichrow);
975 Table t =
976 originalTable_( originalTable_.col("SCANNO") == Int(rec.asuInt("SCANNO"))
977 && originalTable_.col("BEAMNO") == Int(rec.asuInt("BEAMNO"))
978 && originalTable_.col("IFNO") == Int(rec.asuInt("IFNO"))
979 && originalTable_.col("CYCLENO") == Int(rec.asuInt("CYCLENO")) );
980 ROArrayColumn<Float> speccol(t, "SPECTRA");
981 return speccol.getColumn();
982}
[865]983
[902]984std::vector< std::string > asap::Scantable::columnNames( ) const
985{
986 Vector<String> vec = table_.tableDesc().columnNames();
987 return mathutil::tovectorstring(vec);
988}
[896]989
[915]990casa::MEpoch::Types asap::Scantable::getTimeReference( ) const
991{
992 return MEpoch::castType(timeCol_.getMeasRef().getType());
[972]993}
[915]994
[1111]995void Scantable::addFit( const STFitEntry & fit, int row )
[972]996{
997 cout << mfitidCol_(uInt(row)) << endl;
998 uInt id = fitTable_.addEntry(fit, mfitidCol_(uInt(row)));
999 mfitidCol_.put(uInt(row), id);
1000}
[915]1001
[987]1002
1003}
1004 //namespace asap
Note: See TracBrowser for help on using the repository browser.