source: trunk/src/STFrequencies.cpp @ 3106

Last change on this file since 3106 was 3106, checked in by Takeshi Nakazato, 8 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes/No?

Interface Changes: Yes/No?

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No?

Module(s): Module Names change impacts.

Description: Describe your changes here...


Check-in asap modifications from Jim regarding casacore namespace conversion.

File size: 13.0 KB
RevLine 
[806]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>
[2658]17#include <casa/Logging/LogIO.h>
[2900]18#include <casa/BasicMath/Math.h>
[806]19
20#include <tables/Tables/TableDesc.h>
21#include <tables/Tables/SetupNewTab.h>
22#include <tables/Tables/ScaColDesc.h>
23#include <tables/Tables/TableRecord.h>
[3084]24#include <tables/TaQL/TableParse.h>
[806]25#include <tables/Tables/TableRow.h>
26
27#include <coordinates/Coordinates/CoordinateSystem.h>
28#include <coordinates/Coordinates/CoordinateUtil.h>
29
30#include "STFrequencies.h"
31
32
[3106]33using namespace casacore;
[806]34
35namespace asap {
36
[847]37const String STFrequencies::name_ = "FREQUENCIES";
[806]38
[849]39STFrequencies::STFrequencies(const Scantable& parent) :
40  STSubTable(parent, name_)
[806]41{
42  setup();
43}
44
[3106]45STFrequencies::STFrequencies( casacore::Table tab ) :
[856]46  STSubTable(tab, name_)
[849]47{
48  refpixCol_.attach(table_,"REFPIX");
49  refvalCol_.attach(table_,"REFVAL");
50  incrCol_.attach(table_,"INCREMENT");
[806]51
[849]52}
53
[806]54STFrequencies::~STFrequencies()
55{
56}
57
[1360]58STFrequencies & STFrequencies::operator=( const STFrequencies & other )
[849]59{
60  if ( this != &other ) {
61    static_cast<STSubTable&>(*this) = other;
62    refpixCol_.attach(table_,"REFPIX");
63    refvalCol_.attach(table_,"REFVAL");
64    incrCol_.attach(table_,"INCREMENT");
65  }
66  return *this;
67}
68
[806]69void STFrequencies::setup( )
70{
71  // add to base class table
72  table_.addColumn(ScalarColumnDesc<Double>("REFPIX"));
73  table_.addColumn(ScalarColumnDesc<Double>("REFVAL"));
74  table_.addColumn(ScalarColumnDesc<Double>("INCREMENT"));
75
[847]76  table_.rwKeywordSet().define("FRAME", String("TOPO"));
77  table_.rwKeywordSet().define("BASEFRAME", String("TOPO"));
[806]78  table_.rwKeywordSet().define("EQUINOX",String( "J2000"));
[941]79  table_.rwKeywordSet().define("UNIT", String(""));
[806]80  table_.rwKeywordSet().define("DOPPLER", String("RADIO"));
81
82  // new cached columns
83  refpixCol_.attach(table_,"REFPIX");
84  refvalCol_.attach(table_,"REFVAL");
85  incrCol_.attach(table_,"INCREMENT");
86}
87
88uInt STFrequencies::addEntry( Double refpix, Double refval, Double inc )
89{
90  // test if this already exists
91  Table result = table_( near(table_.col("REFVAL"), refval)
[2242]92                         && near(table_.col("REFPIX"), refpix)
93                         && near(table_.col("INCREMENT"), inc), 1 );
[806]94  uInt resultid = 0;
95  if ( result.nrow() > 0) {
96    ROScalarColumn<uInt> c(result, "ID");
97    c.get(0, resultid);
98
99  } else {
100    uInt rno = table_.nrow();
101    table_.addRow();
102    // get last assigned freq_id and increment
103    if ( rno > 0 ) {
104      idCol_.get(rno-1, resultid);
105      resultid++;
106    }
107    refpixCol_.put(rno, refpix);
108    refvalCol_.put(rno, refval);
109    incrCol_.put(rno, inc);
110    idCol_.put(rno, resultid);
111  }
112  return resultid;
113}
114
115
[830]116
117void STFrequencies::getEntry( Double& refpix, Double& refval, Double& inc,
118                              uInt id )
119{
[2243]120  Table t = table_(table_.col("ID") == Int(id), 1 );
[830]121  if (t.nrow() == 0 ) {
122    throw(AipsError("STFrequencies::getEntry - freqID out of range"));
123  }
124  ROTableRow row(t);
125  // get first row - there should only be one matching id
126  const TableRecord& rec = row.get(0);
127  refpix = rec.asDouble("REFPIX");
128  refval = rec.asDouble("REFVAL");
129  inc = rec.asDouble("INCREMENT");
130}
131
[1819]132void STFrequencies::setEntry( Double refpix, Double refval, Double inc, uInt id )
133{
[2243]134  Table t = table_(table_.col("ID") == Int(id), 1 );
[1819]135  if (t.nrow() == 0 ) {
136    throw(AipsError("STFrequencies::getEntry - freqID out of range"));
137  }
138  for ( uInt i = 0 ; i < table_.nrow() ; i++ ) {
139    uInt fid ;
140    idCol_.get( i, fid ) ;
141    if ( fid == id ) {
142      refpixCol_.put( i, refpix ) ;
143      refvalCol_.put( i, refval ) ;
144      incrCol_.put( i, inc ) ;
145    }
146  }
147}
148
[847]149SpectralCoordinate STFrequencies::getSpectralCoordinate( uInt id ) const
[806]150{
[2243]151  Table t = table_(table_.col("ID") == Int(id), 1 );
[806]152
153  if (t.nrow() == 0 ) {
[847]154    throw(AipsError("STFrequencies::getSpectralCoordinate - ID out of range"));
[806]155  }
156
157  // get the data
158  ROTableRow row(t);
159  // get first row - there should only be one matching id
160  const TableRecord& rec = row.get(0);
[847]161  return SpectralCoordinate( getFrame(true), rec.asDouble("REFVAL"),
[806]162                             rec.asDouble("INCREMENT"),
163                             rec.asDouble("REFPIX"));
164}
165
[1819]166/**
[847]167SpectralCoordinate
[1360]168  STFrequencies::getSpectralCoordinate( const MDirection& md,
169                                        const MPosition& mp,
170                                        const MEpoch& me,
171                                        Double restfreq, uInt id ) const
[1819]172**/
173SpectralCoordinate
174  STFrequencies::getSpectralCoordinate( const MDirection& md,
175                                              const MPosition& mp,
176                                              const MEpoch& me,
177                                              Vector<Double> restfreq, uInt id ) const
[806]178{
[847]179  SpectralCoordinate spc = getSpectralCoordinate(id);
[1819]180  //spc.setRestFrequency(restfreq, True);
181  // for now just use the first rest frequency
182  if (restfreq.nelements()==0 ) {
183    restfreq.resize(1);
184    restfreq[0] = 0;
185  }
186  spc.setRestFrequency(restfreq[0], True);
[847]187  if ( !spc.setReferenceConversion(getFrame(), me, mp, md) ) {
188    throw(AipsError("Couldn't convert frequency frame."));
189  }
190  String unitstr = getUnitString();
191  if ( !unitstr.empty() ) {
192    Unit unitu(unitstr);
193    if ( unitu == Unit("Hz") ) {
[866]194      Vector<String> wau(1); wau = unitu.getName();
195      spc.setWorldAxisUnits(wau);
[847]196    } else {
197      spc.setVelocity(unitstr, getDoppler());
198    }
199  }
200  return spc;
201}
202
203
204void STFrequencies::rescale( Float factor, const std::string& mode )
205{
[806]206  TableRow row(table_);
207  TableRecord& outrec = row.record();
208  RecordFieldPtr<Double> rv(outrec, "REFVAL");
209  RecordFieldPtr<Double> rp(outrec, "REFPIX");
210  RecordFieldPtr<Double> inc(outrec, "INCREMENT");
211  for (uInt i=0; i<table_.nrow(); ++i) {
212
213    const TableRecord& rec = row.get(i);
214
[847]215    SpectralCoordinate sc ( getFrame(true), rec.asDouble("REFVAL"),
[806]216                            rec.asDouble("INCREMENT"), rec.asDouble("REFPIX") );
217
218    SpectralCoordinate scout;
219    if (mode == "BIN") {
220      scout = binCsys(sc, Int(factor));
221    } else if (mode == "RESAMPLE") {
222      scout = resampleCsys(sc, factor);
223    }
224    *rv = scout.referenceValue()[0];
225    *rp = scout.referencePixel()[0];
226    *inc = scout.increment()[0];
227    row.put(i);
228  }
229}
230
231SpectralCoordinate STFrequencies::binCsys(const SpectralCoordinate& sc,
232                                          Int factor)
233{
234  CoordinateSystem csys;
235  csys.addCoordinate(sc);
236  IPosition factors(1, factor);
237  CoordinateSystem binnedcs =
238    CoordinateUtil::makeBinnedCoordinateSystem(factors, csys, False);
239  return binnedcs.spectralCoordinate(0);
240}
241
242SpectralCoordinate STFrequencies::resampleCsys(const SpectralCoordinate& sc,
243                                               Float width)
244{
245  Vector<Float> offset(1,0.0);
[1694]246  Vector<Float> factors(1,width);
[806]247  Vector<Int> newshape;
248  CoordinateSystem csys;
249  csys.addCoordinate(sc);
250  CoordinateSystem csys2 = csys.subImage(offset, factors, newshape);
251  return csys2.spectralCoordinate(0);
252}
253
254
[847]255MFrequency::Types STFrequencies::getFrame(bool base) const
[806]256{
257  // get the ref frame
[921]258  String rf;
259  if ( base )
260    rf = table_.keywordSet().asString("BASEFRAME");
261  else
262    rf = table_.keywordSet().asString("FRAME");
[806]263
264  // Create SpectralCoordinate (units Hz)
265  MFrequency::Types mft;
266  if (!MFrequency::getType(mft, rf)) {
267    ostringstream oss;
[3106]268    LogIO os( casacore::LogOrigin( "STFrequencies", "getFrame") );
[2658]269    os << LogIO::WARN << "WARNING: Frequency type unknown assuming TOPO"
270       << LogIO::POST;
[806]271    mft = MFrequency::TOPO;
272  }
273
274  return mft;
275}
276
[1360]277std::string STFrequencies::getFrameString( bool base ) const
[847]278{
279  if ( base ) return table_.keywordSet().asString("BASEFRAME");
280  else return table_.keywordSet().asString("FRAME");
281}
282
[1360]283std::string STFrequencies::getUnitString( ) const
[847]284{
285  return table_.keywordSet().asString("UNIT");
286}
287
[1360]288Unit STFrequencies::getUnit( ) const
[847]289{
290  return Unit(table_.keywordSet().asString("UNIT"));
291}
292
[1360]293std::string STFrequencies::getDopplerString( ) const
[847]294{
295  return table_.keywordSet().asString("DOPPLER");
296}
297
[1360]298MDoppler::Types STFrequencies::getDoppler( ) const
[847]299{
300  String dpl = table_.keywordSet().asString("DOPPLER");
301
302  // Create SpectralCoordinate (units Hz)
303  MDoppler::Types mdt;
304  if (!MDoppler::getType(mdt, dpl)) {
305    throw(AipsError("Doppler type unknown"));
306  }
307  return mdt;
308}
309
[1375]310std::string STFrequencies::print( int id, Bool strip ) const
[806]311{
312  Table t;
313  ostringstream oss;
314  if ( id < 0 ) t = table_;
[2243]315  else  t = table_(table_.col("ID") == Int(id), 1 );
[806]316  ROTableRow row(t);
317  for (uInt i=0; i<t.nrow(); ++i) {
318    const TableRecord& rec = row.get(i);
319    oss <<  setw(8)
[2816]320        << t.keywordSet().asString("BASEFRAME") << setw(16) << setprecision(8)
[1375]321        << rec.asDouble("REFVAL") << setw(7)
322        << rec.asDouble("REFPIX")
[1694]323        << setw(15)
[1375]324        << rec.asDouble("INCREMENT");
[806]325  }
[1375]326  String outstr(oss);
327  if (strip) {
328    int f = outstr.find_first_not_of(' ');
329    int l = outstr.find_last_not_of(' ', outstr.size());
[1694]330    if (f < 0) {
331      f = 0;
[1375]332    }
[1694]333    if ( l < f  || l < f ) {
[1375]334      l = outstr.size();
335    }
336    return outstr.substr(f,l);
337  }
338  return outstr;
[806]339}
340
341float STFrequencies::getRefFreq( uInt id, uInt channel )
342{
[2243]343  Table t = table_(table_.col("ID") == Int(id), 1 );
[806]344  if ( t.nrow() == 0 ) throw(AipsError("Selected Illegal frequency id"));
345  ROTableRow row(t);
346  const TableRecord& rec = row.get(0);
347  return (Double(channel/2) - rec.asDouble("REFPIX"))
348          * rec.asDouble("INCREMENT") + rec.asDouble("REFVAL");
349}
350
[1360]351bool STFrequencies::conformant( const STFrequencies& other ) const
[840]352{
353  const Record& r = table_.keywordSet();
354  const Record& ro = other.table_.keywordSet();
[847]355  return ( r.asString("FRAME") == ro.asString("FRAME") &&
[840]356           r.asString("EQUINOX") == ro.asString("EQUINOX") &&
357           r.asString("UNIT") == ro.asString("UNIT") &&
358           r.asString("DOPPLER") == ro.asString("DOPPLER")
359          );
360}
361
[1360]362std::vector< std::string > STFrequencies::getInfo( ) const
[847]363{
364  const Record& r = table_.keywordSet();
365  std::vector<std::string> out;
366  out.push_back(r.asString("UNIT"));
367  out.push_back(r.asString("FRAME"));
368  out.push_back(r.asString("DOPPLER"));
[866]369  return out;
[847]370}
371
[1360]372void STFrequencies::setInfo( const std::vector< std::string >& theinfo )
[847]373{
374  if ( theinfo.size() != 3 ) throw(AipsError("setInfo needs three parameters"));
[866]375  try {
376    setUnit(theinfo[0]);
377    setFrame(theinfo[1]);
378    setDoppler(theinfo[2]);
379  } catch (AipsError& e) {
380    throw(e);
381  }
382}
383
[1360]384void STFrequencies::setUnit( const std::string & unit )
[866]385{
386  if (unit == "" || unit == "pixel" || unit == "channel" ) {
387    table_.rwKeywordSet().define("UNIT", "");
[847]388  } else {
[866]389    Unit u(unit);
390    if ( u == Unit("km/s") || u == Unit("Hz") )
391      table_.rwKeywordSet().define("UNIT", unit);
392    else {
393      throw(AipsError("Illegal spectral unit."));
394    }
[847]395  }
396}
[866]397
[1360]398void STFrequencies::setFrame(MFrequency::Types frame, bool base )
[847]399{
[921]400  String f = MFrequency::showType(frame);
401  if (base)
402    table_.rwKeywordSet().define("BASEFRAME", f);
403  else
404    table_.rwKeywordSet().define("FRAME", f);
405
406}
407
[1360]408void STFrequencies::setFrame( const std::string & frame, bool base )
[921]409{
[847]410  MFrequency::Types mdr;
411  if (!MFrequency::getType(mdr, frame)) {
412    Int a,b;const uInt* c;
413    const String* valid = MFrequency::allMyTypes(a, b, c);
[866]414    Vector<String> ftypes(IPosition(1,a), valid);
415    ostringstream oss;
416    oss <<  String("Please specify a legal frequency type. Types are\n");
417    oss << ftypes;
418    String msg(oss);
419    throw(AipsError(msg));
[847]420  } else {
[921]421    if (base)
422      table_.rwKeywordSet().define("BASEFRAME", frame);
423    else
424      table_.rwKeywordSet().define("FRAME", frame);
[847]425  }
426}
427
[1360]428void STFrequencies::setDoppler( const std::string & doppler )
[866]429{
430  MDoppler::Types mdt;
431  if (!MDoppler::getType(mdt, doppler)) {
432    Int a,b;const uInt* c;
433    const String* valid = MDoppler::allMyTypes(a, b, c);
434    Vector<String> ftypes(IPosition(1,a), valid);
435    ostringstream oss;
436    oss <<  String("Please specify a legal doppler type. Types are\n");
437    oss << ftypes;
438    String msg(oss);
439    throw(AipsError(msg));
440  } else {
441    table_.rwKeywordSet().define("DOPPLER", doppler);
442  }
443}
[849]444
[1694]445void STFrequencies::shiftRefPix(int npix, uInt id)
[1360]446{
[2243]447  Table t = table_(table_.col("ID") == Int(id), 1  );
[1360]448  if ( t.nrow() == 0 ) throw(AipsError("Selected Illegal frequency id"));
449  ScalarColumn<Double> tcol(t, "REFPIX");
450  tcol.put(0, tcol(0)+Double(npix));
451}
[866]452
[2900]453bool STFrequencies::match( Double refpix, Double refval,
454                           Double inc, Double freqTolInHz,
455                           uInt &id)
456{
457  ROScalarColumn<uInt> idCol(table_, "ID");
458  ROScalarColumn<Double> refPixCol(table_, "REFPIX");
459  ROScalarColumn<Double> refValCol(table_, "REFVAL");
460  ROScalarColumn<Double> incCol(table_, "INCREMENT");
461  for (uInt irow = 0; irow < table_.nrow(); ++irow) {
462    Double refInc = incCol(irow);
463    Double refFreq = refValCol(irow) - refPixCol(irow) * refInc;
464    Double freq0 = refval - refpix * inc;
465    if (nearAbs(inc, refInc, freqTolInHz) &&
466        nearAbs(refFreq, freq0, freqTolInHz)) {
467      id = irow;
468      return true;
469    }
470  }
471  return false;
472}
473 
[806]474} // namespace
Note: See TracBrowser for help on using the repository browser.