source: trunk/src/Scantable.cpp @ 999

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

added "redundant" fields from reader. The aren't used in asap but should be passed on for consistency.

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