// // C++ Implementation: STFrequencies // // Description: // // // Author: Malte Marquarding , (C) 2006 // // Copyright: See COPYING file that comes with this distribution // // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "STFrequencies.h" using namespace casacore; namespace asap { const String STFrequencies::name_ = "FREQUENCIES"; STFrequencies::STFrequencies(const Scantable& parent) : STSubTable(parent, name_) { setup(); } STFrequencies::STFrequencies( casacore::Table tab ) : STSubTable(tab, name_) { refpixCol_.attach(table_,"REFPIX"); refvalCol_.attach(table_,"REFVAL"); incrCol_.attach(table_,"INCREMENT"); } STFrequencies::~STFrequencies() { } STFrequencies & STFrequencies::operator=( const STFrequencies & other ) { if ( this != &other ) { static_cast(*this) = other; refpixCol_.attach(table_,"REFPIX"); refvalCol_.attach(table_,"REFVAL"); incrCol_.attach(table_,"INCREMENT"); } return *this; } void STFrequencies::setup( ) { // add to base class table table_.addColumn(ScalarColumnDesc("REFPIX")); table_.addColumn(ScalarColumnDesc("REFVAL")); table_.addColumn(ScalarColumnDesc("INCREMENT")); table_.rwKeywordSet().define("FRAME", String("TOPO")); table_.rwKeywordSet().define("BASEFRAME", String("TOPO")); table_.rwKeywordSet().define("EQUINOX",String( "J2000")); table_.rwKeywordSet().define("UNIT", String("")); table_.rwKeywordSet().define("DOPPLER", String("RADIO")); // new cached columns refpixCol_.attach(table_,"REFPIX"); refvalCol_.attach(table_,"REFVAL"); incrCol_.attach(table_,"INCREMENT"); } uInt STFrequencies::addEntry( Double refpix, Double refval, Double inc ) { // test if this already exists Table result = table_( near(table_.col("REFVAL"), refval) && near(table_.col("REFPIX"), refpix) && near(table_.col("INCREMENT"), inc), 1 ); uInt resultid = 0; if ( result.nrow() > 0) { ROScalarColumn c(result, "ID"); c.get(0, resultid); } else { uInt rno = table_.nrow(); table_.addRow(); // get last assigned freq_id and increment if ( rno > 0 ) { idCol_.get(rno-1, resultid); resultid++; } refpixCol_.put(rno, refpix); refvalCol_.put(rno, refval); incrCol_.put(rno, inc); idCol_.put(rno, resultid); } return resultid; } void STFrequencies::getEntry( Double& refpix, Double& refval, Double& inc, uInt id ) { Table t = table_(table_.col("ID") == Int(id), 1 ); if (t.nrow() == 0 ) { throw(AipsError("STFrequencies::getEntry - freqID out of range")); } ROTableRow row(t); // get first row - there should only be one matching id const TableRecord& rec = row.get(0); refpix = rec.asDouble("REFPIX"); refval = rec.asDouble("REFVAL"); inc = rec.asDouble("INCREMENT"); } void STFrequencies::setEntry( Double refpix, Double refval, Double inc, uInt id ) { Table t = table_(table_.col("ID") == Int(id), 1 ); if (t.nrow() == 0 ) { throw(AipsError("STFrequencies::getEntry - freqID out of range")); } for ( uInt i = 0 ; i < table_.nrow() ; i++ ) { uInt fid ; idCol_.get( i, fid ) ; if ( fid == id ) { refpixCol_.put( i, refpix ) ; refvalCol_.put( i, refval ) ; incrCol_.put( i, inc ) ; } } } SpectralCoordinate STFrequencies::getSpectralCoordinate( uInt id ) const { Table t = table_(table_.col("ID") == Int(id), 1 ); if (t.nrow() == 0 ) { throw(AipsError("STFrequencies::getSpectralCoordinate - ID out of range")); } // get the data ROTableRow row(t); // get first row - there should only be one matching id const TableRecord& rec = row.get(0); return SpectralCoordinate( getFrame(true), rec.asDouble("REFVAL"), rec.asDouble("INCREMENT"), rec.asDouble("REFPIX")); } /** SpectralCoordinate STFrequencies::getSpectralCoordinate( const MDirection& md, const MPosition& mp, const MEpoch& me, Double restfreq, uInt id ) const **/ SpectralCoordinate STFrequencies::getSpectralCoordinate( const MDirection& md, const MPosition& mp, const MEpoch& me, Vector restfreq, uInt id ) const { SpectralCoordinate spc = getSpectralCoordinate(id); //spc.setRestFrequency(restfreq, True); // for now just use the first rest frequency if (restfreq.nelements()==0 ) { restfreq.resize(1); restfreq[0] = 0; } spc.setRestFrequency(restfreq[0], True); if ( !spc.setReferenceConversion(getFrame(), me, mp, md) ) { throw(AipsError("Couldn't convert frequency frame.")); } String unitstr = getUnitString(); if ( !unitstr.empty() ) { Unit unitu(unitstr); if ( unitu == Unit("Hz") ) { Vector wau(1); wau = unitu.getName(); spc.setWorldAxisUnits(wau); } else { spc.setVelocity(unitstr, getDoppler()); } } return spc; } void STFrequencies::rescale( Float factor, const std::string& mode ) { TableRow row(table_); TableRecord& outrec = row.record(); RecordFieldPtr rv(outrec, "REFVAL"); RecordFieldPtr rp(outrec, "REFPIX"); RecordFieldPtr inc(outrec, "INCREMENT"); for (uInt i=0; i offset(1,0.0); Vector factors(1,width); Vector newshape; CoordinateSystem csys; csys.addCoordinate(sc); CoordinateSystem csys2 = csys.subImage(offset, factors, newshape); return csys2.spectralCoordinate(0); } MFrequency::Types STFrequencies::getFrame(bool base) const { // get the ref frame String rf; if ( base ) rf = table_.keywordSet().asString("BASEFRAME"); else rf = table_.keywordSet().asString("FRAME"); // Create SpectralCoordinate (units Hz) MFrequency::Types mft; if (!MFrequency::getType(mft, rf)) { ostringstream oss; LogIO os( casacore::LogOrigin( "STFrequencies", "getFrame") ); os << LogIO::WARN << "WARNING: Frequency type unknown assuming TOPO" << LogIO::POST; mft = MFrequency::TOPO; } return mft; } std::string STFrequencies::getFrameString( bool base ) const { if ( base ) return table_.keywordSet().asString("BASEFRAME"); else return table_.keywordSet().asString("FRAME"); } std::string STFrequencies::getUnitString( ) const { return table_.keywordSet().asString("UNIT"); } Unit STFrequencies::getUnit( ) const { return Unit(table_.keywordSet().asString("UNIT")); } std::string STFrequencies::getDopplerString( ) const { return table_.keywordSet().asString("DOPPLER"); } MDoppler::Types STFrequencies::getDoppler( ) const { String dpl = table_.keywordSet().asString("DOPPLER"); // Create SpectralCoordinate (units Hz) MDoppler::Types mdt; if (!MDoppler::getType(mdt, dpl)) { throw(AipsError("Doppler type unknown")); } return mdt; } std::string STFrequencies::print( int id, Bool strip ) const { Table t; ostringstream oss; if ( id < 0 ) t = table_; else t = table_(table_.col("ID") == Int(id), 1 ); ROTableRow row(t); for (uInt i=0; i STFrequencies::getInfo( ) const { const Record& r = table_.keywordSet(); std::vector out; out.push_back(r.asString("UNIT")); out.push_back(r.asString("FRAME")); out.push_back(r.asString("DOPPLER")); return out; } void STFrequencies::setInfo( const std::vector< std::string >& theinfo ) { if ( theinfo.size() != 3 ) throw(AipsError("setInfo needs three parameters")); try { setUnit(theinfo[0]); setFrame(theinfo[1]); setDoppler(theinfo[2]); } catch (AipsError& e) { throw(e); } } void STFrequencies::setUnit( const std::string & unit ) { if (unit == "" || unit == "pixel" || unit == "channel" ) { table_.rwKeywordSet().define("UNIT", ""); } else { Unit u(unit); if ( u == Unit("km/s") || u == Unit("Hz") ) table_.rwKeywordSet().define("UNIT", unit); else { throw(AipsError("Illegal spectral unit.")); } } } void STFrequencies::setFrame(MFrequency::Types frame, bool base ) { String f = MFrequency::showType(frame); if (base) table_.rwKeywordSet().define("BASEFRAME", f); else table_.rwKeywordSet().define("FRAME", f); } void STFrequencies::setFrame( const std::string & frame, bool base ) { MFrequency::Types mdr; if (!MFrequency::getType(mdr, frame)) { Int a,b;const uInt* c; const String* valid = MFrequency::allMyTypes(a, b, c); Vector ftypes(IPosition(1,a), valid); ostringstream oss; oss << String("Please specify a legal frequency type. Types are\n"); oss << ftypes; String msg(oss); throw(AipsError(msg)); } else { if (base) table_.rwKeywordSet().define("BASEFRAME", frame); else table_.rwKeywordSet().define("FRAME", frame); } } void STFrequencies::setDoppler( const std::string & doppler ) { MDoppler::Types mdt; if (!MDoppler::getType(mdt, doppler)) { Int a,b;const uInt* c; const String* valid = MDoppler::allMyTypes(a, b, c); Vector ftypes(IPosition(1,a), valid); ostringstream oss; oss << String("Please specify a legal doppler type. Types are\n"); oss << ftypes; String msg(oss); throw(AipsError(msg)); } else { table_.rwKeywordSet().define("DOPPLER", doppler); } } void STFrequencies::shiftRefPix(int npix, uInt id) { Table t = table_(table_.col("ID") == Int(id), 1 ); if ( t.nrow() == 0 ) throw(AipsError("Selected Illegal frequency id")); ScalarColumn tcol(t, "REFPIX"); tcol.put(0, tcol(0)+Double(npix)); } bool STFrequencies::match( Double refpix, Double refval, Double inc, Double freqTolInHz, uInt &id) { ROScalarColumn idCol(table_, "ID"); ROScalarColumn refPixCol(table_, "REFPIX"); ROScalarColumn refValCol(table_, "REFVAL"); ROScalarColumn incCol(table_, "INCREMENT"); for (uInt irow = 0; irow < table_.nrow(); ++irow) { Double refInc = incCol(irow); Double refFreq = refValCol(irow) - refPixCol(irow) * refInc; Double freq0 = refval - refpix * inc; if (nearAbs(inc, refInc, freqTolInHz) && nearAbs(refFreq, freq0, freqTolInHz)) { id = irow; return true; } } return false; } } // namespace