//#--------------------------------------------------------------------------- //# SDMemTable.cc: A MemoryTable container for single dish integrations //#--------------------------------------------------------------------------- //# Copyright (C) 2004 //# ATNF //# //# This program is free software; you can redistribute it and/or modify it //# under the terms of the GNU General Public License as published by the Free //# Software Foundation; either version 2 of the License, or (at your option) //# any later version. //# //# This program is distributed in the hope that it will be useful, but //# WITHOUT ANY WARRANTY; without even the implied warranty of //# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General //# Public License for more details. //# //# You should have received a copy of the GNU General Public License along //# with this program; if not, write to the Free Software Foundation, Inc., //# 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning this software should be addressed as follows: //# Internet email: Malte.Marquarding@csiro.au //# Postal address: Malte Marquarding, //# Australia Telescope National Facility, //# P.O. Box 76, //# Epping, NSW, 2121, //# AUSTRALIA //# //# $Id: //#--------------------------------------------------------------------------- #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SDDefs.h" #include "SDContainer.h" #include "MathUtils.h" #include "SDPol.h" #include "SDAttr.h" #include "SDMemTable.h" using namespace casa; using namespace asap; SDMemTable::SDMemTable() : IFSel_(0), beamSel_(0), polSel_(0) { setup(); attach(); } SDMemTable::SDMemTable(const std::string& name) : IFSel_(0), beamSel_(0), polSel_(0) { Table tab(name); Int version; tab.keywordSet().get("VERSION", version); if (version != version_) { throw(AipsError("Unsupported version of ASAP file.")); } table_ = tab.copyToMemoryTable("dummy"); attach(); } SDMemTable::SDMemTable(const SDMemTable& other, Bool clear) { table_ = other.table_.copyToMemoryTable(String("dummy")); // clear all rows() if (clear) { table_.removeRow(this->table_.rowNumbers()); IFSel_= 0; beamSel_= 0; polSel_= 0; chanMask_.resize(0); } else { IFSel_= other.IFSel_; beamSel_= other.beamSel_; polSel_= other.polSel_; chanMask_.resize(0); chanMask_ = other.chanMask_; } attach(); } SDMemTable::SDMemTable(const Table& tab, const std::string& exprs) : IFSel_(0), beamSel_(0), polSel_(0) { Table t = tableCommand(exprs,tab); if (t.nrow() == 0) throw(AipsError("Query unsuccessful.")); table_ = t.copyToMemoryTable("dummy"); attach(); renumber(); } SDMemTable::~SDMemTable() { //cerr << "goodbye from SDMemTable @ " << this << endl; } SDMemTable SDMemTable::getScan(Int scanID) const { String cond("SELECT * from $1 WHERE SCANID == "); cond += String::toString(scanID); return SDMemTable(table_, cond); } SDMemTable &SDMemTable::operator=(const SDMemTable& other) { if (this != &other) { IFSel_= other.IFSel_; beamSel_= other.beamSel_; polSel_= other.polSel_; chanMask_.resize(0); chanMask_ = other.chanMask_; table_ = other.table_.copyToMemoryTable(String("dummy")); attach(); } return *this; } SDMemTable SDMemTable::getSource(const std::string& source) const { String cond("SELECT * from $1 WHERE SRCNAME == "); cond += source; return SDMemTable(table_, cond); } void SDMemTable::setup() { TableDesc td("", "1", TableDesc::Scratch); td.comment() = "A SDMemTable"; td.rwKeywordSet().define("VERSION", Int(version_)); td.addColumn(ScalarColumnDesc("TIME")); td.addColumn(ScalarColumnDesc("SRCNAME")); td.addColumn(ArrayColumnDesc("SPECTRA")); td.addColumn(ArrayColumnDesc("FLAGTRA")); td.addColumn(ArrayColumnDesc("TSYS")); td.addColumn(ArrayColumnDesc("STOKES")); td.addColumn(ScalarColumnDesc("SCANID")); td.addColumn(ScalarColumnDesc("INTERVAL")); td.addColumn(ArrayColumnDesc("FREQID")); td.addColumn(ArrayColumnDesc("RESTFREQID")); td.addColumn(ArrayColumnDesc("DIRECTION")); td.addColumn(ScalarColumnDesc("FIELDNAME")); td.addColumn(ScalarColumnDesc("TCALTIME")); td.addColumn(ArrayColumnDesc("TCAL")); td.addColumn(ScalarColumnDesc("AZIMUTH")); td.addColumn(ScalarColumnDesc("ELEVATION")); td.addColumn(ScalarColumnDesc("PARANGLE")); td.addColumn(ScalarColumnDesc("REFBEAM")); td.addColumn(ArrayColumnDesc("FITID")); // Now create Table SetUp from the description. SetupNewTable aNewTab("dummy", td, Table::New); // Bind the Stokes Virtual machine to the STOKES column Because we // don't know how many polarizations will be in the data at this // point, we must bind the Virtual Engine regardless. The STOKES // column won't be accessed if not appropriate (nPol=4) SDStokesEngine::registerClass(); SDStokesEngine stokesEngine(String("STOKES"), String("SPECTRA")); aNewTab.bindColumn("STOKES", stokesEngine); // Create Table table_ = Table(aNewTab, Table::Memory, 0); // add subtable TableDesc tdf("", "1", TableDesc::Scratch); tdf.addColumn(ArrayColumnDesc("FUNCTIONS")); tdf.addColumn(ArrayColumnDesc("COMPONENTS")); tdf.addColumn(ArrayColumnDesc("PARAMETERS")); tdf.addColumn(ArrayColumnDesc("PARMASK")); tdf.addColumn(ArrayColumnDesc("FRAMEINFO")); SetupNewTable fittab("fits", tdf, Table::New); Table fitTable(fittab, Table::Memory); table_.rwKeywordSet().defineTable("FITS", fitTable); TableDesc tdh("", "1", TableDesc::Scratch); tdh.addColumn(ScalarColumnDesc("ITEM")); SetupNewTable histtab("hist", tdh, Table::New); Table histTable(histtab, Table::Memory); table_.rwKeywordSet().defineTable("HISTORY", histTable); } void SDMemTable::attach() { timeCol_.attach(table_, "TIME"); srcnCol_.attach(table_, "SRCNAME"); specCol_.attach(table_, "SPECTRA"); flagsCol_.attach(table_, "FLAGTRA"); tsCol_.attach(table_, "TSYS"); stokesCol_.attach(table_, "STOKES"); scanCol_.attach(table_, "SCANID"); integrCol_.attach(table_, "INTERVAL"); freqidCol_.attach(table_, "FREQID"); restfreqidCol_.attach(table_, "RESTFREQID"); dirCol_.attach(table_, "DIRECTION"); fldnCol_.attach(table_, "FIELDNAME"); tcaltCol_.attach(table_, "TCALTIME"); tcalCol_.attach(table_, "TCAL"); azCol_.attach(table_, "AZIMUTH"); elCol_.attach(table_, "ELEVATION"); paraCol_.attach(table_, "PARANGLE"); rbeamCol_.attach(table_, "REFBEAM"); fitCol_.attach(table_,"FITID"); } std::string SDMemTable::getSourceName(Int whichRow) const { String name; srcnCol_.get(whichRow, name); return name; } std::string SDMemTable::getTime(Int whichRow, Bool showDate) const { Double tm; if (whichRow > -1) { timeCol_.get(whichRow, tm); } else { table_.keywordSet().get("UTC",tm); } MVTime mvt(tm); if (showDate) mvt.setFormat(MVTime::YMD); else mvt.setFormat(MVTime::TIME); ostringstream oss; oss << mvt; return String(oss); } double SDMemTable::getInterval(Int whichRow) const { Double intval; integrCol_.get(whichRow, intval); return intval; } bool SDMemTable::setIF(Int whichIF) { if ( whichIF >= 0 && whichIF < nIF()) { IFSel_ = whichIF; return true; } return false; } bool SDMemTable::setBeam(Int whichBeam) { if ( whichBeam >= 0 && whichBeam < nBeam()) { beamSel_ = whichBeam; return true; } return false; } bool SDMemTable::setPol(Int whichPol) { if ( whichPol >= 0 && whichPol < nPol()) { polSel_ = whichPol; return true; } return false; } void SDMemTable::resetCursor() { polSel_ = 0; IFSel_ = 0; beamSel_ = 0; } bool SDMemTable::setMask(std::vector whichChans) { std::vector::iterator it; uInt n = flagsCol_.shape(0)(3); if (whichChans.empty()) { chanMask_ = std::vector(n,true); return true; } chanMask_.resize(n,true); for (it = whichChans.begin(); it != whichChans.end(); ++it) { if (*it < n) { chanMask_[*it] = false; } } return true; } std::vector SDMemTable::getMask(Int whichRow) const { std::vector mask; Array arr; flagsCol_.get(whichRow, arr); ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_)));//go to beam ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_)));// go to IF ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_)));// go to pol Bool useUserMask = ( chanMask_.size() == arr.shape()(3) ); std::vector tmp; tmp = chanMask_; // WHY the fxxx do I have to make a copy here std::vector::iterator miter; miter = tmp.begin(); for (ArrayAccessor > i(aa2); i != i.end(); ++i) { bool out =!static_cast(*i); if (useUserMask) { out = out && (*miter); miter++; } mask.push_back(out); } return mask; } std::vector SDMemTable::getSpectrum(Int whichRow) const { Array arr; specCol_.get(whichRow, arr); return getFloatSpectrum(arr); } int SDMemTable::nStokes() const { return stokesCol_.shape(0).nelements(); // All rows same shape } std::vector SDMemTable::getStokesSpectrum(Int whichRow, Bool doPol) const // // Gets one STokes parameter depending on cursor polSel location // doPol=False : I,Q,U,V // doPol=True : I,P,PA,V ; P = sqrt(Q**2+U**2), PA = 0.5*atan2(Q,U) // { AlwaysAssert(asap::nAxes==4,AipsError); if (nPol()!=1 && nPol()!=2 && nPol()!=4) { throw (AipsError("You must have 1,2 or 4 polarizations to get the Stokes parameters")); } // For full conversion we are only supporting linears at the moment if (nPol() > 2) { String antName; table_.keywordSet().get("AntennaName", antName); Instrument inst = SDAttr::convertInstrument (antName, True); SDAttr sdAtt; if (sdAtt.feedPolType(inst) != LINEAR) { throw(AipsError("Only linear polarizations are supported")); } } Array arr; stokesCol_.get(whichRow, arr); if (doPol && (polSel_==1 || polSel_==2)) { // Q,U --> P, P.A. // Set current cursor location const IPosition& shape = arr.shape(); IPosition start, end; getCursorSlice(start, end, shape); // Get Q and U slices Array Q = SDPolUtil::getStokesSlice(arr,start,end,"Q"); Array U = SDPolUtil::getStokesSlice(arr,start,end,"U"); // Compute output Array out; if (polSel_==1) { // P out = SDPolUtil::polarizedIntensity(Q,U); } else if (polSel_==2) { // P.A. out = SDPolUtil::positionAngle(Q,U); } // Copy to output IPosition vecShape(1,shape(asap::ChanAxis)); Vector outV = out.reform(vecShape); std::vector stlout; outV.tovector(stlout); return stlout; } else { // Selects at the cursor location return getFloatSpectrum(arr); } } std::string SDMemTable::getPolarizationLabel(Bool linear, Bool stokes, Bool linPol, Int polIdx) const { uInt idx = polSel_; if (polIdx >=0) idx = polIdx; return SDPolUtil::polarizationLabel(idx, linear, stokes, linPol); } std::vector SDMemTable::stokesToPolSpectrum(Int whichRow, Bool toLinear, Int polIdx) const // // polIdx // 0:3 -> RR,LL,Real(RL),Imag(RL) // XX,YY,Real(XY),Image(XY) // // Gets only // RR = I + V // LL = I - V // at the moment // { AlwaysAssert(asap::nAxes==4,AipsError); if (nStokes()!=4) { throw (AipsError("You must have 4 Stokes to convert to linear or circular")); } // Array arr, out; stokesCol_.get(whichRow, arr); // Set current cursor location const IPosition& shape = arr.shape(); IPosition start, end; getCursorSlice(start, end, shape); // Get the slice if (toLinear) { throw(AipsError("Conversion to linears not yet supported")); } else { uInt selection = polSel_; if (polIdx > -1) selection = polIdx; Bool doRR = (selection==0); if (selection>1) { throw(AipsError("Only conversion to RR & LL is currently supported")); } // Get I and V slices Array I = SDPolUtil::getStokesSlice(arr,start,end,"I"); Array V = SDPolUtil::getStokesSlice(arr,start,end,"V"); // Compute output out = SDPolUtil::circularPolarizationFromStokes(I, V, doRR); } // Copy to output IPosition vecShape(1,shape(asap::ChanAxis)); Vector outV = out.reform(vecShape); std::vector stlout; outV.tovector(stlout); // return stlout; } Array SDMemTable::getStokesSpectrum(Int whichRow, Int iBeam, Int iIF) const { // Get data Array arr; stokesCol_.get(whichRow, arr); // Set current cursor location and overwrite polarization axis const IPosition& shape = arr.shape(); IPosition start(shape.nelements(),0); IPosition end(shape-1); if (iBeam!=-1) { start(asap::BeamAxis) = iBeam; end(asap::BeamAxis) = iBeam; } if (iIF!=-1) { start(asap::IFAxis) = iIF; end(asap::IFAxis) = iIF; } // Get slice return arr(start,end); } std::vector SDMemTable::getCoordInfo() const { String un; Table t = table_.keywordSet().asTable("FREQUENCIES"); String sunit; t.keywordSet().get("UNIT",sunit); String dpl; t.keywordSet().get("DOPPLER",dpl); if (dpl == "") dpl = "RADIO"; String rfrm; t.keywordSet().get("REFFRAME",rfrm); std::vector inf; inf.push_back(sunit); inf.push_back(rfrm); inf.push_back(dpl); t.keywordSet().get("BASEREFFRAME",rfrm); inf.push_back(rfrm); return inf; } void SDMemTable::setCoordInfo(std::vector theinfo) { std::vector::iterator it; String un,rfrm, brfrm,dpl; un = theinfo[0]; // Abcissa unit rfrm = theinfo[1]; // Active (or conversion) frame dpl = theinfo[2]; // Doppler brfrm = theinfo[3]; // Base frame Table t = table_.rwKeywordSet().asTable("FREQUENCIES"); Vector rstf; t.keywordSet().get("RESTFREQS",rstf); Bool canDo = True; Unit u1("km/s");Unit u2("Hz"); if (Unit(un) == u1) { Vector rstf; t.keywordSet().get("RESTFREQS",rstf); if (rstf.nelements() == 0) { throw(AipsError("Can't set unit to km/s if no restfrequencies are specified")); } } else if (Unit(un) != u2 && un != "") { throw(AipsError("Unit not conformant with Spectral Coordinates")); } t.rwKeywordSet().define("UNIT", un); MFrequency::Types mdr; if (!MFrequency::getType(mdr, rfrm)) { Int a,b;const uInt* c; const String* valid = MFrequency::allMyTypes(a, b, c); String pfix = "Please specify a legal frame type. Types are\n"; throw(AipsError(pfix+(*valid))); } else { t.rwKeywordSet().define("REFFRAME",rfrm); } MDoppler::Types dtype; dpl.upcase(); if (!MDoppler::getType(dtype, dpl)) { throw(AipsError("Doppler type unknown")); } else { t.rwKeywordSet().define("DOPPLER",dpl); } if (!MFrequency::getType(mdr, brfrm)) { Int a,b;const uInt* c; const String* valid = MFrequency::allMyTypes(a, b, c); String pfix = "Please specify a legal frame type. Types are\n"; throw(AipsError(pfix+(*valid))); } else { t.rwKeywordSet().define("BASEREFFRAME",brfrm); } } std::vector SDMemTable::getAbcissa(Int whichRow) const { std::vector abc(nChan()); // Get header units keyword Table t = table_.keywordSet().asTable("FREQUENCIES"); String sunit; t.keywordSet().get("UNIT",sunit); if (sunit == "") sunit = "pixel"; Unit u(sunit); // Easy if just wanting pixels if (sunit==String("pixel")) { // assume channels/pixels std::vector::iterator it; uInt i=0; for (it = abc.begin(); it != abc.end(); ++it) { (*it) = Double(i++); } return abc; } // Continue with km/s or Hz. Get FreqIDs Vector freqIDs; freqidCol_.get(whichRow, freqIDs); uInt freqID = freqIDs(IFSel_); restfreqidCol_.get(whichRow, freqIDs); uInt restFreqID = freqIDs(IFSel_); // Get SpectralCoordinate, set reference frame conversion, // velocity conversion, and rest freq state SpectralCoordinate spc = getSpectralCoordinate(freqID, restFreqID, whichRow); Vector pixel(nChan()); indgen(pixel); if (u == Unit("km/s")) { Vector world; spc.pixelToVelocity(world,pixel); std::vector::iterator it; uInt i = 0; for (it = abc.begin(); it != abc.end(); ++it) { (*it) = world[i]; i++; } } else if (u == Unit("Hz")) { // Set world axis units Vector wau(1); wau = u.getName(); spc.setWorldAxisUnits(wau); std::vector::iterator it; Double tmp; uInt i = 0; for (it = abc.begin(); it != abc.end(); ++it) { spc.toWorld(tmp,pixel[i]); (*it) = tmp; i++; } } return abc; } std::string SDMemTable::getAbcissaString(Int whichRow) const { Table t = table_.keywordSet().asTable("FREQUENCIES"); String sunit; t.keywordSet().get("UNIT",sunit); if (sunit == "") sunit = "pixel"; Unit u(sunit); Vector freqIDs; freqidCol_.get(whichRow, freqIDs); uInt freqID = freqIDs(IFSel_); restfreqidCol_.get(whichRow, freqIDs); uInt restFreqID = freqIDs(IFSel_); // Get SpectralCoordinate, with frame, velocity, rest freq state set SpectralCoordinate spc = getSpectralCoordinate(freqID, restFreqID, whichRow); String s = "Channel"; if (u == Unit("km/s")) { s = CoordinateUtil::axisLabel(spc,0,True,True,True); } else if (u == Unit("Hz")) { Vector wau(1);wau = u.getName(); spc.setWorldAxisUnits(wau); s = CoordinateUtil::axisLabel(spc,0,True,True,False); } return s; } void SDMemTable::setSpectrum(std::vector spectrum, int whichRow) { Array arr; specCol_.get(whichRow, arr); if (spectrum.size() != arr.shape()(asap::ChanAxis)) { throw(AipsError("Attempting to set spectrum with incorrect length.")); } // Setup accessors ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_))); // Beam selection ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_))); // IF selection ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_))); // Pol selection // Iterate std::vector::iterator it = spectrum.begin(); for (ArrayAccessor > i(aa2); i != i.end(); ++i) { (*i) = Float(*it); it++; } specCol_.put(whichRow, arr); } void SDMemTable::getSpectrum(Vector& spectrum, Int whichRow) const { Array arr; specCol_.get(whichRow, arr); // Iterate and extract spectrum.resize(arr.shape()(3)); ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_)));//go to beam ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_)));// go to IF ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_)));// go to pol ArrayAccessor > va(spectrum); for (ArrayAccessor > i(aa2); i != i.end(); ++i) { (*va) = (*i); va++; } } /* void SDMemTable::getMask(Vector& mask, Int whichRow) const { Array arr; flagsCol_.get(whichRow, arr); mask.resize(arr.shape()(3)); ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_)));//go to beam ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_)));// go to IF ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_)));// go to pol Bool useUserMask = ( chanMask_.size() == arr.shape()(3) ); ArrayAccessor > va(mask); std::vector tmp; tmp = chanMask_; // WHY the fxxx do I have to make a copy here. The // iterator should work on chanMask_?? std::vector::iterator miter; miter = tmp.begin(); for (ArrayAccessor > i(aa2); i != i.end(); ++i) { bool out =!static_cast(*i); if (useUserMask) { out = out && (*miter); miter++; } (*va) = out; va++; } } */ MaskedArray SDMemTable::rowAsMaskedArray(uInt whichRow, Bool toStokes) const { // Get flags Array farr; flagsCol_.get(whichRow, farr); // Get data and convert mask to Bool Array arr; Array mask; if (toStokes) { stokesCol_.get(whichRow, arr); Array tMask(farr.shape()); convertArray(tMask, farr); mask = SDPolUtil::stokesData (tMask, True); } else { specCol_.get(whichRow, arr); mask.resize(farr.shape()); convertArray(mask, farr); } return MaskedArray(arr,!mask); } Float SDMemTable::getTsys(Int whichRow) const { Array arr; tsCol_.get(whichRow, arr); Float out; IPosition ip(arr.shape()); ip(asap::BeamAxis) = beamSel_; ip(asap::IFAxis) = IFSel_; ip(asap::PolAxis) = polSel_; ip(asap::ChanAxis)=0; // First channel only out = arr(ip); return out; } MDirection SDMemTable::getDirection(Int whichRow, Bool refBeam) const { MDirection::Types mdr = getDirectionReference(); Array posit; dirCol_.get(whichRow,posit); Vector wpos(2); Int rb; rbeamCol_.get(whichRow,rb); wpos[0] = posit(IPosition(2,beamSel_,0)); wpos[1] = posit(IPosition(2,beamSel_,1)); if (refBeam && rb > -1) { // use refBeam instead if it exists wpos[0] = posit(IPosition(2,rb,0)); wpos[1] = posit(IPosition(2,rb,1)); } Quantum lon(wpos[0],Unit(String("rad"))); Quantum lat(wpos[1],Unit(String("rad"))); return MDirection(lon, lat, mdr); } MEpoch SDMemTable::getEpoch(Int whichRow) const { MEpoch::Types met = getTimeReference(); Double obstime; timeCol_.get(whichRow,obstime); MVEpoch tm2(Quantum(obstime, Unit(String("d")))); return MEpoch(tm2, met); } MPosition SDMemTable::getAntennaPosition () const { Vector antpos; table_.keywordSet().get("AntennaPosition", antpos); MVPosition mvpos(antpos(0),antpos(1),antpos(2)); return MPosition(mvpos); } SpectralCoordinate SDMemTable::getSpectralCoordinate(uInt freqID) const { Table t = table_.keywordSet().asTable("FREQUENCIES"); if (freqID> t.nrow() ) { throw(AipsError("SDMemTable::getSpectralCoordinate - freqID out of range")); } Double rp,rv,inc; String rf; ROScalarColumn rpc(t, "REFPIX"); ROScalarColumn rvc(t, "REFVAL"); ROScalarColumn incc(t, "INCREMENT"); t.keywordSet().get("BASEREFFRAME",rf); // Create SpectralCoordinate (units Hz) MFrequency::Types mft; if (!MFrequency::getType(mft, rf)) { cerr << "Frequency type unknown assuming TOPO" << endl; mft = MFrequency::TOPO; } rpc.get(freqID, rp); rvc.get(freqID, rv); incc.get(freqID, inc); SpectralCoordinate spec(mft,rv,inc,rp); return spec; } SpectralCoordinate SDMemTable::getSpectralCoordinate(uInt freqID, uInt restFreqID, uInt whichRow) const { // Create basic SC SpectralCoordinate spec = getSpectralCoordinate (freqID); Table t = table_.keywordSet().asTable("FREQUENCIES"); // Set rest frequency Vector restFreqIDs; t.keywordSet().get("RESTFREQS",restFreqIDs); if (restFreqID < restFreqIDs.nelements()) { // Should always be true spec.setRestFrequency(restFreqIDs(restFreqID),True); } // Set up frame conversion layer String frm; t.keywordSet().get("REFFRAME",frm); if (frm == "") frm = "TOPO"; MFrequency::Types mtype; if (!MFrequency::getType(mtype, frm)) { // Should never happen cerr << "Frequency type unknown assuming TOPO" << endl; mtype = MFrequency::TOPO; } // Set reference frame conversion (requires row) MDirection dir = getDirection(whichRow); MEpoch epoch = getEpoch(whichRow); MPosition pos = getAntennaPosition(); if (!spec.setReferenceConversion(mtype,epoch,pos,dir)) { throw(AipsError("Couldn't convert frequency frame.")); } // Now velocity conversion if appropriate String unitStr; t.keywordSet().get("UNIT",unitStr); String dpl; t.keywordSet().get("DOPPLER",dpl); MDoppler::Types dtype; MDoppler::getType(dtype, dpl); // Only set velocity unit if non-blank and non-Hz if (!unitStr.empty()) { Unit unitU(unitStr); if (unitU==Unit("Hz")) { } else { spec.setVelocity(unitStr, dtype); } } return spec; } Bool SDMemTable::setCoordinate(const SpectralCoordinate& speccord, uInt freqID) { Table t = table_.rwKeywordSet().asTable("FREQUENCIES"); if (freqID > t.nrow() ) { throw(AipsError("SDMemTable::setCoordinate - coord no out of range")); } ScalarColumn rpc(t, "REFPIX"); ScalarColumn rvc(t, "REFVAL"); ScalarColumn incc(t, "INCREMENT"); rpc.put(freqID, speccord.referencePixel()[0]); rvc.put(freqID, speccord.referenceValue()[0]); incc.put(freqID, speccord.increment()[0]); return True; } Int SDMemTable::nCoordinates() const { return table_.keywordSet().asTable("FREQUENCIES").nrow(); } std::vector SDMemTable::getRestFreqs() const { Table t = table_.keywordSet().asTable("FREQUENCIES"); Vector tvec; t.keywordSet().get("RESTFREQS",tvec); std::vector stlout; tvec.tovector(stlout); return stlout; } bool SDMemTable::putSDFreqTable(const SDFrequencyTable& sdft) { TableDesc td("", "1", TableDesc::Scratch); td.addColumn(ScalarColumnDesc("REFPIX")); td.addColumn(ScalarColumnDesc("REFVAL")); td.addColumn(ScalarColumnDesc("INCREMENT")); SetupNewTable aNewTab("freqs", td, Table::New); Table aTable (aNewTab, Table::Memory, sdft.length()); ScalarColumn sc0(aTable, "REFPIX"); ScalarColumn sc1(aTable, "REFVAL"); ScalarColumn sc2(aTable, "INCREMENT"); for (uInt i=0; i < sdft.length(); ++i) { sc0.put(i,sdft.referencePixel(i)); sc1.put(i,sdft.referenceValue(i)); sc2.put(i,sdft.increment(i)); } String rf = sdft.refFrame(); if (rf.contains("TOPO")) rf = "TOPO"; aTable.rwKeywordSet().define("BASEREFFRAME", rf); aTable.rwKeywordSet().define("REFFRAME", rf); aTable.rwKeywordSet().define("EQUINOX", sdft.equinox()); aTable.rwKeywordSet().define("UNIT", String("")); aTable.rwKeywordSet().define("DOPPLER", String("RADIO")); Vector rfvec; String rfunit; sdft.restFrequencies(rfvec,rfunit); Quantum > q(rfvec, rfunit); rfvec.resize(); rfvec = q.getValue("Hz"); aTable.rwKeywordSet().define("RESTFREQS", rfvec); table_.rwKeywordSet().defineTable("FREQUENCIES", aTable); return true; } bool SDMemTable::putSDFitTable(const SDFitTable& sdft) { TableDesc td("", "1", TableDesc::Scratch); td.addColumn(ArrayColumnDesc("FUNCTIONS")); td.addColumn(ArrayColumnDesc("COMPONENTS")); td.addColumn(ArrayColumnDesc("PARAMETERS")); td.addColumn(ArrayColumnDesc("PARMASK")); td.addColumn(ArrayColumnDesc("FRAMEINFO")); SetupNewTable aNewTab("fits", td, Table::New); Table aTable(aNewTab, Table::Memory); ArrayColumn sc0(aTable, "FUNCTIONS"); ArrayColumn sc1(aTable, "COMPONENTS"); ArrayColumn sc2(aTable, "PARAMETERS"); ArrayColumn sc3(aTable, "PARMASK"); ArrayColumn sc4(aTable, "FRAMEINFO"); for (uInt i; i& parms = sdft.getParameters(i); const Vector& parmask = sdft.getParameterMask(i); const Vector& funcs = sdft.getFunctions(i); const Vector& comps = sdft.getComponents(i); const Vector& finfo = sdft.getFrameInfo(i); sc0.put(i,funcs); sc1.put(i,comps); sc3.put(i,parmask); sc2.put(i,parms); sc4.put(i,finfo); } table_.rwKeywordSet().defineTable("FITS", aTable); return true; } SDFitTable SDMemTable::getSDFitTable() const { const Table& t = table_.keywordSet().asTable("FITS"); Vector parms; Vector parmask; Vector funcs; Vector finfo; Vector comps; ROArrayColumn parmsCol(t, "PARAMETERS"); ROArrayColumn parmaskCol(t, "PARMASK"); ROArrayColumn compsCol(t, "COMPONENTS"); ROArrayColumn funcsCol(t, "FUNCTIONS"); ROArrayColumn finfoCol(t, "FRAMEINFO"); uInt n = t.nrow(); SDFitTable sdft; for (uInt i=0; i= t.nrow()) return SDFitTable(); Array fitid; fitCol_.get(whichRow, fitid); if (fitid.nelements() == 0) return SDFitTable(); IPosition shp = fitid.shape(); IPosition start(4, beamSel_, IFSel_, polSel_,0); IPosition end(4, beamSel_, IFSel_, polSel_, shp[3]-1); // reform the output array slice to be of dim=1 Vector tmp = (fitid(start, end)).reform(IPosition(1,shp[3])); Vector parms; Vector parmask; Vector funcs; Vector finfo; Vector comps; ROArrayColumn parmsCol(t, "PARAMETERS"); ROArrayColumn parmaskCol(t, "PARMASK"); ROArrayColumn compsCol(t, "COMPONENTS"); ROArrayColumn funcsCol(t, "FUNCTIONS"); ROArrayColumn finfoCol(t, "FRAMEINFO"); SDFitTable sdft; Int k=-1; for (uInt i=0; i< tmp.nelements(); ++i) { k = tmp[i]; if ( k > -1 && k < t.nrow() ) { parms.resize(); parmsCol.get(k, parms); parmask.resize(); parmaskCol.get(k, parmask); funcs.resize(); funcsCol.get(k, funcs); comps.resize(); compsCol.get(k, comps); finfo.resize(); finfoCol.get(k, finfo); sdft.addFit(parms, parmask, funcs, comps, finfo); } } return sdft; } void SDMemTable::addFit(uInt whichRow, const Vector& p, const Vector& m, const Vector& f, const Vector& c) { if (whichRow >= nRow()) { throw(AipsError("Specified row out of range")); } Table t = table_.keywordSet().asTable("FITS"); uInt nrow = t.nrow(); t.addRow(); ArrayColumn parmsCol(t, "PARAMETERS"); ArrayColumn parmaskCol(t, "PARMASK"); ArrayColumn compsCol(t, "COMPONENTS"); ArrayColumn funcsCol(t, "FUNCTIONS"); ArrayColumn finfoCol(t, "FRAMEINFO"); parmsCol.put(nrow, p); parmaskCol.put(nrow, m); compsCol.put(nrow, c); funcsCol.put(nrow, f); Vector fi = mathutil::toVectorString(getCoordInfo()); finfoCol.put(nrow, fi); Array fitarr; fitCol_.get(whichRow, fitarr); Array newarr; // The new Array containing the fitid Int pos =-1; // The fitid position in the array if ( fitarr.nelements() == 0 ) { // no fits at all in this row Array arr(IPosition(4,nBeam(),nIF(),nPol(),1)); arr = -1; newarr.reference(arr); pos = 0; } else { IPosition shp = fitarr.shape(); IPosition start(4, beamSel_, IFSel_, polSel_,0); IPosition end(4, beamSel_, IFSel_, polSel_, shp[3]-1); // reform the output array slice to be of dim=1 Array tmp = (fitarr(start, end)).reform(IPosition(1,shp[3])); const Vector& fits = tmp; VectorSTLIterator it(fits); Int i = 0; while (it != fits.end()) { if (*it == -1) { pos = i; break; } ++i; ++it; }; } if (pos == -1) { mathutil::extendLastArrayAxis(newarr,fitarr, -1); pos = fitarr.shape()[3]; // the new element position } else { if (fitarr.nelements() > 0) newarr = fitarr; } newarr(IPosition(4, beamSel_, IFSel_, polSel_, pos)) = Int(nrow); fitCol_.put(whichRow, newarr); } SDFrequencyTable SDMemTable::getSDFreqTable() const { const Table& t = table_.keywordSet().asTable("FREQUENCIES"); SDFrequencyTable sdft; // Add refpix/refval/incr. What are the units ? Hz I suppose // but it's nowhere described... Vector refPix, refVal, incr; ScalarColumn refPixCol(t, "REFPIX"); ScalarColumn refValCol(t, "REFVAL"); ScalarColumn incrCol(t, "INCREMENT"); refPix = refPixCol.getColumn(); refVal = refValCol.getColumn(); incr = incrCol.getColumn(); uInt n = refPix.nelements(); for (uInt i=0; i restFreqs; t.keywordSet().get("RESTFREQS", restFreqs); for (uInt i=0; i tc; tcalCol_.get(whichRow, tc); sdc.tcal[0] = tc[0];sdc.tcal[1] = tc[1]; tcaltCol_.get(whichRow, sdc.tcaltime); Array spectrum; Array tsys; Array flagtrum; Vector fmap; Array direction; Array fits; specCol_.get(whichRow, spectrum); sdc.putSpectrum(spectrum); flagsCol_.get(whichRow, flagtrum); sdc.putFlags(flagtrum); tsCol_.get(whichRow, tsys); sdc.putTsys(tsys); freqidCol_.get(whichRow, fmap); sdc.putFreqMap(fmap); restfreqidCol_.get(whichRow, fmap); sdc.putRestFreqMap(fmap); dirCol_.get(whichRow, direction); sdc.putDirection(direction); fitCol_.get(whichRow, fits); sdc.putFitMap(fits); return sdc; } bool SDMemTable::putSDHeader(const SDHeader& sdh) { table_.rwKeywordSet().define("nIF", sdh.nif); table_.rwKeywordSet().define("nBeam", sdh.nbeam); table_.rwKeywordSet().define("nPol", sdh.npol); table_.rwKeywordSet().define("nChan", sdh.nchan); table_.rwKeywordSet().define("Observer", sdh.observer); table_.rwKeywordSet().define("Project", sdh.project); table_.rwKeywordSet().define("Obstype", sdh.obstype); table_.rwKeywordSet().define("AntennaName", sdh.antennaname); table_.rwKeywordSet().define("AntennaPosition", sdh.antennaposition); table_.rwKeywordSet().define("Equinox", sdh.equinox); table_.rwKeywordSet().define("FreqRefFrame", sdh.freqref); table_.rwKeywordSet().define("FreqRefVal", sdh.reffreq); table_.rwKeywordSet().define("Bandwidth", sdh.bandwidth); table_.rwKeywordSet().define("UTC", sdh.utc); table_.rwKeywordSet().define("FluxUnit", sdh.fluxunit); table_.rwKeywordSet().define("Epoch", sdh.epoch); return true; } SDHeader SDMemTable::getSDHeader() const { SDHeader sdh; table_.keywordSet().get("nBeam",sdh.nbeam); table_.keywordSet().get("nIF",sdh.nif); table_.keywordSet().get("nPol",sdh.npol); table_.keywordSet().get("nChan",sdh.nchan); table_.keywordSet().get("Observer", sdh.observer); table_.keywordSet().get("Project", sdh.project); table_.keywordSet().get("Obstype", sdh.obstype); table_.keywordSet().get("AntennaName", sdh.antennaname); table_.keywordSet().get("AntennaPosition", sdh.antennaposition); table_.keywordSet().get("Equinox", sdh.equinox); table_.keywordSet().get("FreqRefFrame", sdh.freqref); table_.keywordSet().get("FreqRefVal", sdh.reffreq); table_.keywordSet().get("Bandwidth", sdh.bandwidth); table_.keywordSet().get("UTC", sdh.utc); table_.keywordSet().get("FluxUnit", sdh.fluxunit); table_.keywordSet().get("Epoch", sdh.epoch); return sdh; } void SDMemTable::makePersistent(const std::string& filename) { table_.deepCopy(filename,Table::New); } Int SDMemTable::nScan() const { Int n = 0; Int previous = -1;Int current=0; for (uInt i=0; i< scanCol_.nrow();i++) { scanCol_.getScalar(i,current); if (previous != current) { previous = current; n++; } } return n; } String SDMemTable::formatSec(Double x) const { Double xcop = x; MVTime mvt(xcop/24./3600.); // make days if (x < 59.95) return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_HM, 7)+"s"; else if (x < 3599.95) return String(" ") + mvt.string(MVTime::TIME_CLEAN_NO_H,7)+" "; else { ostringstream oss; oss << setw(2) << std::right << setprecision(1) << mvt.hour(); oss << ":" << mvt.string(MVTime::TIME_CLEAN_NO_H,7) << " "; return String(oss); } }; String SDMemTable::formatDirection(const MDirection& md) const { Vector t = md.getAngle(Unit(String("rad"))).getValue(); Int prec = 7; MVAngle mvLon(t[0]); String sLon = mvLon.string(MVAngle::TIME,prec); MVAngle mvLat(t[1]); String sLat = mvLat.string(MVAngle::ANGLE+MVAngle::DIG2,prec); return sLon + String(" ") + sLat; } std::string SDMemTable::getFluxUnit() const { String tmp; table_.keywordSet().get("FluxUnit", tmp); return tmp; } void SDMemTable::setFluxUnit(const std::string& unit) { String tmp(unit); Unit tU(tmp); if (tU==Unit("K") || tU==Unit("Jy")) { table_.rwKeywordSet().define(String("FluxUnit"), tmp); } else { throw AipsError("Illegal unit - must be compatible with Jy or K"); } } void SDMemTable::setInstrument(const std::string& name) { Bool throwIt = True; Instrument ins = SDAttr::convertInstrument(name, throwIt); String nameU(name); nameU.upcase(); table_.rwKeywordSet().define(String("AntennaName"), nameU); } std::string SDMemTable::summary(bool verbose) const { // Format header info ostringstream oss; oss << endl; oss << "--------------------------------------------------------------------------------" << endl; oss << " Scan Table Summary" << endl; oss << "--------------------------------------------------------------------------------" << endl; oss.flags(std::ios_base::left); oss << setw(15) << "Beams:" << setw(4) << nBeam() << endl << setw(15) << "IFs:" << setw(4) << nIF() << endl << setw(15) << "Polarisations:" << setw(4) << nPol() << endl << setw(15) << "Channels:" << setw(4) << nChan() << endl; oss << endl; String tmp; table_.keywordSet().get("Observer", tmp); oss << setw(15) << "Observer:" << tmp << endl; oss << setw(15) << "Obs Date:" << getTime(-1,True) << endl; table_.keywordSet().get("Project", tmp); oss << setw(15) << "Project:" << tmp << endl; table_.keywordSet().get("Obstype", tmp); oss << setw(15) << "Obs. Type:" << tmp << endl; table_.keywordSet().get("AntennaName", tmp); oss << setw(15) << "Antenna Name:" << tmp << endl; table_.keywordSet().get("FluxUnit", tmp); oss << setw(15) << "Flux Unit:" << tmp << endl; Table t = table_.keywordSet().asTable("FREQUENCIES"); Vector vec; t.keywordSet().get("RESTFREQS",vec); oss << setw(15) << "Rest Freqs:"; if (vec.nelements() > 0) { oss << setprecision(10) << vec << " [Hz]" << endl; } else { oss << "None set" << endl; } oss << setw(15) << "Abcissa:" << getAbcissaString() << endl; oss << setw(15) << "Cursor:" << "Beam[" << getBeam() << "] " << "IF[" << getIF() << "] " << "Pol[" << getPol() << "]" << endl; oss << endl; String dirtype ="Position ("+ MDirection::showType(getDirectionReference()) + ")"; oss << setw(5) << "Scan" << setw(15) << "Source" << setw(24) << dirtype << setw(10) << "Time" << setw(18) << "Integration" << setw(7) << "FreqIDs" << endl; oss << "--------------------------------------------------------------------------------" << endl; // Generate list of scan start and end integrations Vector scanIDs = scanCol_.getColumn(); Vector startInt, endInt; mathutil::scanBoundaries(startInt, endInt, scanIDs); const uInt nScans = startInt.nelements(); String name; Vector freqIDs, listFQ; Vector restFreqIDs, listRestFQ; uInt nInt; for (uInt i=0; i info = getCoordInfo(); SDFrequencyTable sdft = getSDFreqTable(); oss << endl << endl; oss << "FreqID Frame RefFreq(Hz) RefPix Increment(Hz)" << endl; oss << "--------------------------------------------------------------------------------" << endl; for (uInt i=0; i& whichScans) { ostringstream oss; Vector scanIDs = scanCol_.getColumn(); Vector startInt, endInt; mathutil::scanBoundaries(startInt, endInt, scanIDs); const uInt nScans = startInt.nelements(); std::vector::const_iterator it(whichScans); return String(oss); } */ Int SDMemTable::nBeam() const { Int n; table_.keywordSet().get("nBeam",n); return n; } Int SDMemTable::nIF() const { Int n; table_.keywordSet().get("nIF",n); return n; } Int SDMemTable::nPol() const { Int n; table_.keywordSet().get("nPol",n); return n; } Int SDMemTable::nChan() const { Int n; table_.keywordSet().get("nChan",n); return n; } Table SDMemTable::getHistoryTable() const { return table_.keywordSet().asTable("HISTORY"); } void SDMemTable::appendToHistoryTable(const Table& otherHist) { Table t = table_.rwKeywordSet().asTable("HISTORY"); const String sep = "--------------------------------------------------------------------------------"; addHistory(sep); TableCopy::copyRows(t, otherHist, t.nrow(), 0, otherHist.nrow()); addHistory(sep); } void SDMemTable::addHistory(const std::string& hist) { Table t = table_.rwKeywordSet().asTable("HISTORY"); uInt nrow = t.nrow(); t.addRow(); ScalarColumn itemCol(t, "ITEM"); itemCol.put(nrow, hist); } std::vector SDMemTable::getHistory() const { Vector history; const Table& t = table_.keywordSet().asTable("HISTORY"); uInt nrow = t.nrow(); ROScalarColumn itemCol(t, "ITEM"); std::vector stlout; String hist; for (uInt i=0; i& whichChans ) { std::vector::iterator it; ArrayAccessor > j(flags_); for (it = whichChans.begin(); it != whichChans.end(); it++) { j.reset(j.begin(uInt(*it))); for (ArrayAccessor > i(j); i != i.end(); ++i) { for (ArrayAccessor > ii(i); ii != ii.end(); ++ii) { for (ArrayAccessor > iii(ii); iii != iii.end(); ++iii) { (*iii) = } } } } } */ void SDMemTable::flag(int whichRow) { Array arr; flagsCol_.get(whichRow, arr); ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_)));//go to beam ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_)));// go to IF ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_)));// go to pol for (ArrayAccessor > i(aa2); i != i.end(); ++i) { (*i) = uChar(True); } flagsCol_.put(whichRow, arr); } MDirection::Types SDMemTable::getDirectionReference() const { Float eq; table_.keywordSet().get("Equinox",eq); std::map mp; mp[2000.0] = "J2000"; mp[1950.0] = "B1950"; MDirection::Types mdr; if (!MDirection::getType(mdr, mp[eq])) { mdr = MDirection::J2000; cerr << "Unknown equinox using J2000" << endl; } return mdr; } MEpoch::Types SDMemTable::getTimeReference() const { MEpoch::Types met; String ep; table_.keywordSet().get("Epoch",ep); if (!MEpoch::getType(met, ep)) { cerr << "Epoch type unknown - using UTC" << endl; met = MEpoch::UTC; } return met; } Bool SDMemTable::setRestFreqs(const Vector& restFreqsIn, const String& sUnit, const vector& lines, const String& source, Int whichIF) { const Int nIFs = nIF(); if (whichIF>=nIFs) { throw(AipsError("Illegal IF index")); } // Find vector of restfrequencies // Double takes precedence over String Unit unit; Vector restFreqs; if (restFreqsIn.nelements()>0) { restFreqs.resize(restFreqsIn.nelements()); restFreqs = restFreqsIn; unit = Unit(sUnit); } else if (lines.size()>0) { const uInt nLines = lines.size(); unit = Unit("Hz"); restFreqs.resize(nLines); MFrequency lineFreq; for (uInt i=0; i1) { // Replace restFreqs, one per IF if (nRestFreqs != nIFs) { throw (AipsError("Number of rest frequencies must be equal to the number of IFs")); } cout << "Replacing rest frequencies, one per IF, with given list : " << restFreqs << endl; sdft.deleteRestFrequencies(); for (uInt i=0; i rf(restFreqs[i], unit); sdft.addRestFrequency(rf.getValue("Hz")); } } else { // Add new rest freq Quantum rf(restFreqs[0], unit); idx = sdft.addRestFrequency(rf.getValue("Hz")); if (whichIF>=0) { cout << "Selecting given rest frequency (" << restFreqs[0] << ") for IF " << whichIF << endl; } else { cout << "Selecting given rest frequency (" << restFreqs[0] << ") for all IFs" << endl; } } // Replace Bool empty = source.empty(); Bool ok = False; if (putSDFreqTable(sdft)) { const uInt nRow = table_.nrow(); String srcName; Vector restFreqIDs; for (uInt i=0; i lines = MeasTable::Lines(); MFrequency lineFreq; Double freq; cout.flags(std::ios_base::left); cout << "Line Frequency (Hz)" << endl; cout << "-----------------------" << endl; for (uInt i=0; i SDMemTable::getFloatSpectrum(const Array& arr) const // Get spectrum at cursor location { // Setup accessors ArrayAccessor > aa0(arr); aa0.reset(aa0.begin(uInt(beamSel_))); // Beam selection ArrayAccessor > aa1(aa0); aa1.reset(aa1.begin(uInt(IFSel_))); // IF selection ArrayAccessor > aa2(aa1); aa2.reset(aa2.begin(uInt(polSel_))); // Pol selection std::vector spectrum; for (ArrayAccessor > i(aa2); i != i.end(); ++i) { spectrum.push_back(*i); } return spectrum; }