source: trunk/src/STFrequencies.cpp @ 856

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

added name()
reworked copy constructor for (Table tab) to also pass name to base class

File size: 9.6 KB
Line 
1//
2// C++ Implementation: STFrequencies
3//
4// Description:
5//
6//
7// Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2006
8//
9// Copyright: See COPYING file that comes with this distribution
10//
11//
12#include <casa/iostream.h>
13#include <casa/iomanip.h>
14#include <casa/Exceptions/Error.h>
15#include <casa/Containers/RecordField.h>
16#include <casa/Arrays/IPosition.h>
17
18#include <tables/Tables/TableDesc.h>
19#include <tables/Tables/SetupNewTab.h>
20#include <tables/Tables/ScaColDesc.h>
21#include <tables/Tables/TableRecord.h>
22#include <tables/Tables/TableParse.h>
23#include <tables/Tables/TableRow.h>
24
25#include <coordinates/Coordinates/CoordinateSystem.h>
26#include <coordinates/Coordinates/CoordinateUtil.h>
27
28#include "STFrequencies.h"
29
30
31using namespace casa;
32
33namespace asap {
34
35const String STFrequencies::name_ = "FREQUENCIES";
36
37STFrequencies::STFrequencies(const Scantable& parent) :
38  STSubTable(parent, name_)
39{
40  setup();
41}
42
43asap::STFrequencies::STFrequencies( casa::Table tab ) :
44  STSubTable(tab, name_)
45{
46  refpixCol_.attach(table_,"REFPIX");
47  refvalCol_.attach(table_,"REFVAL");
48  incrCol_.attach(table_,"INCREMENT");
49
50}
51
52STFrequencies::~STFrequencies()
53{
54}
55
56STFrequencies & asap::STFrequencies::operator =( const STFrequencies & other )
57{
58  if ( this != &other ) {
59    static_cast<STSubTable&>(*this) = other;
60    refpixCol_.attach(table_,"REFPIX");
61    refvalCol_.attach(table_,"REFVAL");
62    incrCol_.attach(table_,"INCREMENT");
63  }
64  return *this;
65}
66
67void STFrequencies::setup( )
68{
69  // add to base class table
70  table_.addColumn(ScalarColumnDesc<Double>("REFPIX"));
71  table_.addColumn(ScalarColumnDesc<Double>("REFVAL"));
72  table_.addColumn(ScalarColumnDesc<Double>("INCREMENT"));
73
74  table_.rwKeywordSet().define("FRAME", String("TOPO"));
75  table_.rwKeywordSet().define("BASEFRAME", String("TOPO"));
76  table_.rwKeywordSet().define("EQUINOX",String( "J2000"));
77  table_.rwKeywordSet().define("UNIT", String("Hz"));
78  table_.rwKeywordSet().define("DOPPLER", String("RADIO"));
79
80  // new cached columns
81  refpixCol_.attach(table_,"REFPIX");
82  refvalCol_.attach(table_,"REFVAL");
83  incrCol_.attach(table_,"INCREMENT");
84}
85
86uInt STFrequencies::addEntry( Double refpix, Double refval, Double inc )
87{
88  // test if this already exists
89  Table result = table_( near(table_.col("REFVAL"), refval)
90                    && near(table_.col("REFPIX"), refpix)
91                    && near(table_.col("INCREMENT"), inc) );
92  uInt resultid = 0;
93  if ( result.nrow() > 0) {
94    ROScalarColumn<uInt> c(result, "ID");
95    c.get(0, resultid);
96
97  } else {
98    uInt rno = table_.nrow();
99    table_.addRow();
100    // get last assigned freq_id and increment
101    if ( rno > 0 ) {
102      idCol_.get(rno-1, resultid);
103      resultid++;
104    }
105    refpixCol_.put(rno, refpix);
106    refvalCol_.put(rno, refval);
107    incrCol_.put(rno, inc);
108    idCol_.put(rno, resultid);
109  }
110  return resultid;
111}
112
113
114
115void STFrequencies::getEntry( Double& refpix, Double& refval, Double& inc,
116                              uInt id )
117{
118  Table t = table_(table_.col("ID") == Int(id) );
119  if (t.nrow() == 0 ) {
120    throw(AipsError("STFrequencies::getEntry - freqID out of range"));
121  }
122  ROTableRow row(t);
123  // get first row - there should only be one matching id
124  const TableRecord& rec = row.get(0);
125  refpix = rec.asDouble("REFPIX");
126  refval = rec.asDouble("REFVAL");
127  inc = rec.asDouble("INCREMENT");
128}
129
130SpectralCoordinate STFrequencies::getSpectralCoordinate( uInt id ) const
131{
132  Table t = table_(table_.col("ID") == Int(id) );
133
134  if (t.nrow() == 0 ) {
135    throw(AipsError("STFrequencies::getSpectralCoordinate - ID out of range"));
136  }
137
138  // get the data
139  ROTableRow row(t);
140  // get first row - there should only be one matching id
141  const TableRecord& rec = row.get(0);
142
143  return SpectralCoordinate( getFrame(true), rec.asDouble("REFVAL"),
144                             rec.asDouble("INCREMENT"),
145                             rec.asDouble("REFPIX"));
146}
147
148SpectralCoordinate
149  asap::STFrequencies::getSpectralCoordinate( const MDirection& md,
150                                              const MPosition& mp,
151                                              const MEpoch& me,
152                                              Double restfreq, uInt id ) const
153{
154  SpectralCoordinate spc = getSpectralCoordinate(id);
155  spc.setRestFrequency(restfreq, True);
156  if ( !spc.setReferenceConversion(getFrame(), me, mp, md) ) {
157    throw(AipsError("Couldn't convert frequency frame."));
158  }
159  String unitstr = getUnitString();
160  if ( !unitstr.empty() ) {
161    Unit unitu(unitstr);
162    if ( unitu == Unit("Hz") ) {
163    } else {
164      spc.setVelocity(unitstr, getDoppler());
165    }
166  }
167  return spc;
168}
169
170
171void STFrequencies::rescale( Float factor, const std::string& mode )
172{
173  TableRow row(table_);
174  TableRecord& outrec = row.record();
175  RecordFieldPtr<Double> rv(outrec, "REFVAL");
176  RecordFieldPtr<Double> rp(outrec, "REFPIX");
177  RecordFieldPtr<Double> inc(outrec, "INCREMENT");
178  for (uInt i=0; i<table_.nrow(); ++i) {
179
180    const TableRecord& rec = row.get(i);
181
182    SpectralCoordinate sc ( getFrame(true), rec.asDouble("REFVAL"),
183                            rec.asDouble("INCREMENT"), rec.asDouble("REFPIX") );
184
185    SpectralCoordinate scout;
186    if (mode == "BIN") {
187      scout = binCsys(sc, Int(factor));
188    } else if (mode == "RESAMPLE") {
189      scout = resampleCsys(sc, factor);
190    }
191    *rv = scout.referenceValue()[0];
192    *rp = scout.referencePixel()[0];
193    *inc = scout.increment()[0];
194    row.put(i);
195  }
196}
197
198SpectralCoordinate STFrequencies::binCsys(const SpectralCoordinate& sc,
199                                          Int factor)
200{
201  CoordinateSystem csys;
202  csys.addCoordinate(sc);
203  IPosition factors(1, factor);
204  CoordinateSystem binnedcs =
205    CoordinateUtil::makeBinnedCoordinateSystem(factors, csys, False);
206  return binnedcs.spectralCoordinate(0);
207}
208
209SpectralCoordinate STFrequencies::resampleCsys(const SpectralCoordinate& sc,
210                                               Float width)
211{
212  Vector<Float> offset(1,0.0);
213  Vector<Float> factors(1,1.0/width);
214  Vector<Int> newshape;
215  CoordinateSystem csys;
216  csys.addCoordinate(sc);
217  CoordinateSystem csys2 = csys.subImage(offset, factors, newshape);
218  return csys2.spectralCoordinate(0);
219}
220
221
222MFrequency::Types STFrequencies::getFrame(bool base) const
223{
224  // get the ref frame
225  String rf = table_.keywordSet().asString("BASEFRAME");
226
227  // Create SpectralCoordinate (units Hz)
228  MFrequency::Types mft;
229  if (!MFrequency::getType(mft, rf)) {
230    ostringstream oss;
231    pushLog("WARNING: Frequency type unknown assuming TOPO");
232    mft = MFrequency::TOPO;
233  }
234
235  return mft;
236}
237
238std::string asap::STFrequencies::getFrameString( bool base ) const
239{
240  if ( base ) return table_.keywordSet().asString("BASEFRAME");
241  else return table_.keywordSet().asString("FRAME");
242}
243
244std::string asap::STFrequencies::getUnitString( ) const
245{
246  return table_.keywordSet().asString("UNIT");
247}
248
249Unit asap::STFrequencies::getUnit( ) const
250{
251  return Unit(table_.keywordSet().asString("UNIT"));
252}
253
254std::string asap::STFrequencies::getDopplerString( ) const
255{
256  return table_.keywordSet().asString("DOPPLER");
257}
258
259MDoppler::Types asap::STFrequencies::getDoppler( ) const
260{
261  String dpl = table_.keywordSet().asString("DOPPLER");
262
263  // Create SpectralCoordinate (units Hz)
264  MDoppler::Types mdt;
265  if (!MDoppler::getType(mdt, dpl)) {
266    throw(AipsError("Doppler type unknown"));
267  }
268  return mdt;
269}
270
271std::string asap::STFrequencies::print( int id )
272{
273  Table t;
274  ostringstream oss;
275  if ( id < 0 ) t = table_;
276  else  t = table_(table_.col("ID") == Int(id) );
277  ROTableRow row(t);
278  for (uInt i=0; i<t.nrow(); ++i) {
279    const TableRecord& rec = row.get(i);
280    oss <<  setw(8)
281    << "frame" << setw(16) << setprecision(8)
282    << rec.asDouble("REFVAL") << setw(10)
283    << rec.asDouble("REFPIX") << setw(12)
284    << rec.asDouble("INCREMENT") << endl;
285  }
286  return String(oss);
287}
288
289float STFrequencies::getRefFreq( uInt id, uInt channel )
290{
291  Table t = table_(table_.col("ID") == Int(id) );
292  if ( t.nrow() == 0 ) throw(AipsError("Selected Illegal frequency id"));
293  ROTableRow row(t);
294  const TableRecord& rec = row.get(0);
295  return (Double(channel/2) - rec.asDouble("REFPIX"))
296          * rec.asDouble("INCREMENT") + rec.asDouble("REFVAL");
297}
298
299bool asap::STFrequencies::conformant( const STFrequencies& other ) const
300{
301  const Record& r = table_.keywordSet();
302  const Record& ro = other.table_.keywordSet();
303  return ( r.asString("FRAME") == ro.asString("FRAME") &&
304           r.asString("EQUINOX") == ro.asString("EQUINOX") &&
305           r.asString("UNIT") == ro.asString("UNIT") &&
306           r.asString("DOPPLER") == ro.asString("DOPPLER")
307          );
308}
309
310std::vector< std::string > asap::STFrequencies::getInfo( ) const
311{
312  const Record& r = table_.keywordSet();
313  std::vector<std::string> out;
314  out.push_back(r.asString("UNIT"));
315  out.push_back(r.asString("FRAME"));
316  out.push_back(r.asString("DOPPLER"));
317}
318
319void asap::STFrequencies::setInfo( const std::vector< std::string >& theinfo )
320{
321  if ( theinfo.size() != 3 ) throw(AipsError("setInfo needs three parameters"));
322  String un,rfrm,dpl;
323  un = theinfo[0];rfrm = theinfo[1];dpl = theinfo[2];
324  TableRecord& r = table_.rwKeywordSet();
325  setFrame(rfrm);
326  MDoppler::Types dtype;
327  dpl.upcase();
328  if (!MDoppler::getType(dtype, dpl)) {
329    throw(AipsError("Doppler type unknown"));
330  } else {
331    r.define("DOPPLER",dpl);
332  }
333}
334void asap::STFrequencies::setFrame( const std::string & frame )
335{
336  MFrequency::Types mdr;
337  if (!MFrequency::getType(mdr, frame)) {
338    Int a,b;const uInt* c;
339    const String* valid = MFrequency::allMyTypes(a, b, c);
340    String pfix = "Please specify a legal frame type. Types are\n";
341    throw(AipsError(pfix+(*valid)));
342  } else {
343    table_.rwKeywordSet().define("FRAME", frame);
344  }
345}
346
347
348} // namespace
Note: See TracBrowser for help on using the repository browser.