source: trunk/src/STFrequencies.cpp @ 840

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

added conformant() which checks if to objects are conformant

File size: 6.4 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 casa::String STFrequencies::name_ = "FREQUENCIES";
36
37STFrequencies::STFrequencies(casa::Table::TableType tt) :
38  STSubTable( name_, tt )
39{
40  setup();
41}
42
43
44STFrequencies::~STFrequencies()
45{
46}
47
48void STFrequencies::setup( )
49{
50  // add to base class table
51  table_.addColumn(ScalarColumnDesc<Double>("REFPIX"));
52  table_.addColumn(ScalarColumnDesc<Double>("REFVAL"));
53  table_.addColumn(ScalarColumnDesc<Double>("INCREMENT"));
54
55  table_.rwKeywordSet().define("REFFRAME", String("TOPO"));
56  table_.rwKeywordSet().define("EQUINOX",String( "J2000"));
57  table_.rwKeywordSet().define("UNIT", String("Hz"));
58  table_.rwKeywordSet().define("DOPPLER", String("RADIO"));
59
60  // new cached columns
61  refpixCol_.attach(table_,"REFPIX");
62  refvalCol_.attach(table_,"REFVAL");
63  incrCol_.attach(table_,"INCREMENT");
64}
65
66uInt STFrequencies::addEntry( Double refpix, Double refval, Double inc )
67{
68  // test if this already exists
69  Table result = table_( near(table_.col("REFVAL"), refval)
70                    && near(table_.col("REFPIX"), refpix)
71                    && near(table_.col("INCREMENT"), inc) );
72  uInt resultid = 0;
73  if ( result.nrow() > 0) {
74    ROScalarColumn<uInt> c(result, "ID");
75    c.get(0, resultid);
76
77  } else {
78    uInt rno = table_.nrow();
79    table_.addRow();
80    // get last assigned freq_id and increment
81    if ( rno > 0 ) {
82      idCol_.get(rno-1, resultid);
83      resultid++;
84    }
85    refpixCol_.put(rno, refpix);
86    refvalCol_.put(rno, refval);
87    incrCol_.put(rno, inc);
88    idCol_.put(rno, resultid);
89  }
90  return resultid;
91}
92
93
94
95void STFrequencies::getEntry( Double& refpix, Double& refval, Double& inc,
96                              uInt id )
97{
98  Table t = table_(table_.col("ID") == Int(id) );
99  if (t.nrow() == 0 ) {
100    throw(AipsError("STFrequencies::getEntry - freqID out of range"));
101  }
102  ROTableRow row(t);
103  // get first row - there should only be one matching id
104  const TableRecord& rec = row.get(0);
105  refpix = rec.asDouble("REFPIX");
106  refval = rec.asDouble("REFVAL");
107  inc = rec.asDouble("INCREMENT");
108}
109
110SpectralCoordinate STFrequencies::getSpectralCoordinate( uInt freqID )
111{
112  Table t = table_(table_.col("ID") == Int(freqID) );
113
114  if (t.nrow() == 0 ) {
115    throw(AipsError("STFrequencies::getSpectralCoordinate - freqID out of range"));
116  }
117
118  // get the data
119  ROTableRow row(t);
120  // get first row - there should only be one matching id
121  const TableRecord& rec = row.get(0);
122
123  return SpectralCoordinate( getFrame(), rec.asDouble("REFVAL"),
124                             rec.asDouble("INCREMENT"),
125                             rec.asDouble("REFPIX"));
126}
127
128void STFrequencies::rescale( casa::Float factor, const std::string& mode )
129{
130  TableRow row(table_);
131  TableRecord& outrec = row.record();
132  RecordFieldPtr<Double> rv(outrec, "REFVAL");
133  RecordFieldPtr<Double> rp(outrec, "REFPIX");
134  RecordFieldPtr<Double> inc(outrec, "INCREMENT");
135  for (uInt i=0; i<table_.nrow(); ++i) {
136
137    const TableRecord& rec = row.get(i);
138
139    SpectralCoordinate sc ( getFrame(), rec.asDouble("REFVAL"),
140                            rec.asDouble("INCREMENT"), rec.asDouble("REFPIX") );
141
142    SpectralCoordinate scout;
143    if (mode == "BIN") {
144      scout = binCsys(sc, Int(factor));
145    } else if (mode == "RESAMPLE") {
146      scout = resampleCsys(sc, factor);
147    }
148    *rv = scout.referenceValue()[0];
149    *rp = scout.referencePixel()[0];
150    *inc = scout.increment()[0];
151    row.put(i);
152  }
153}
154
155SpectralCoordinate STFrequencies::binCsys(const SpectralCoordinate& sc,
156                                          Int factor)
157{
158  CoordinateSystem csys;
159  csys.addCoordinate(sc);
160  IPosition factors(1, factor);
161  CoordinateSystem binnedcs =
162    CoordinateUtil::makeBinnedCoordinateSystem(factors, csys, False);
163  return binnedcs.spectralCoordinate(0);
164}
165
166SpectralCoordinate STFrequencies::resampleCsys(const SpectralCoordinate& sc,
167                                               Float width)
168{
169  Vector<Float> offset(1,0.0);
170  Vector<Float> factors(1,1.0/width);
171  Vector<Int> newshape;
172  CoordinateSystem csys;
173  csys.addCoordinate(sc);
174  CoordinateSystem csys2 = csys.subImage(offset, factors, newshape);
175  return csys2.spectralCoordinate(0);
176}
177
178
179casa::MFrequency::Types STFrequencies::getFrame( ) const
180{
181  // get the ref frame
182  String rf;
183  table_.keywordSet().get("REFFRAME", rf);
184
185  // Create SpectralCoordinate (units Hz)
186  MFrequency::Types mft;
187  if (!MFrequency::getType(mft, rf)) {
188    ostringstream oss;
189    pushLog("WARNING: Frequency type unknown assuming TOPO");
190    mft = MFrequency::TOPO;
191  }
192
193  return mft;
194}
195
196std::string asap::STFrequencies::print( int id )
197{
198  Table t;
199  ostringstream oss;
200  if ( id < 0 ) t = table_;
201  else  t = table_(table_.col("ID") == Int(id) );
202  ROTableRow row(t);
203  for (uInt i=0; i<t.nrow(); ++i) {
204    const TableRecord& rec = row.get(i);
205    oss <<  setw(8)
206    << "frame" << setw(16) << setprecision(8)
207    << rec.asDouble("REFVAL") << setw(10)
208    << rec.asDouble("REFPIX") << setw(12)
209    << rec.asDouble("INCREMENT") << endl;
210  }
211  return String(oss);
212}
213
214float STFrequencies::getRefFreq( uInt id, uInt channel )
215{
216  Table t = table_(table_.col("ID") == Int(id) );
217  if ( t.nrow() == 0 ) throw(AipsError("Selected Illegal frequency id"));
218  ROTableRow row(t);
219  const TableRecord& rec = row.get(0);
220  return (Double(channel/2) - rec.asDouble("REFPIX"))
221          * rec.asDouble("INCREMENT") + rec.asDouble("REFVAL");
222}
223
224bool asap::STFrequencies::conformant( const STFrequencies& other ) const
225{
226  const Record& r = table_.keywordSet();
227  const Record& ro = other.table_.keywordSet();
228  return ( r.asString("REFFRAME") == ro.asString("REFFRAME") &&
229           r.asString("EQUINOX") == ro.asString("EQUINOX") &&
230           r.asString("UNIT") == ro.asString("UNIT") &&
231           r.asString("DOPPLER") == ro.asString("DOPPLER")
232          );
233}
234
235} // namespace
Note: See TracBrowser for help on using the repository browser.