source: trunk/src/STFrequencies.cpp@ 861

Last change on this file since 861 was 856, checked in by mar637, 19 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.