//#--------------------------------------------------------------------------- //# SDFITSImageWriter.cc: ASAP class to write out single dish spectra as FITS images //#--------------------------------------------------------------------------- //# 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: SDFITSImageWriter.cc 901 2006-03-10 02:29:22Z mar637 $ //#--------------------------------------------------------------------------- #include "SDFITSImageWriter.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "STDefs.h" #include "STHeader.h" #include "SDMemTable.h" #include "SDPol.h" using namespace casa; using namespace asap; SDFITSImageWriter::SDFITSImageWriter() {;} SDFITSImageWriter::~SDFITSImageWriter() {;} Bool SDFITSImageWriter::write(const SDMemTable& sdTable, const String& dirName, Bool toStokes, Bool verbose) { // Get global Header from Table STHeader header = sdTable.getSTHeader(); MEpoch::Ref timeRef(sdTable.getTimeReference()); MDirection::Types dirRef = sdTable.getDirectionReference(); // Prepare initial ObsInfo ObsInfo oi; oi.setTelescope(String(header.antennaname)); oi.setObserver(String(header.observer)); // Column keywords Table tab = sdTable.table(); ROArrayColumn dirCol(tab, String("DIRECTION")); ROScalarColumn timeCol(tab, "TIME"); ROArrayColumn freqidCol(tab, "FREQID"); ROArrayColumn restfreqidCol(tab, "RESTFREQID"); ROScalarColumn srcCol(tab, "SRCNAME"); // Output Image Shape; spectral axis to be updated IPosition shapeOut(4,1); // spectral, direction (2), stokes // Axes (should be in header) const uInt beamAxis = asap::BeamAxis; const uInt ifAxis = asap::IFAxis; const uInt stokesAxis = asap::PolAxis; const uInt chanAxis = asap::ChanAxis; const Unit RAD(String("rad")); // Output Directory String dirName2(dirName); if (dirName.length()==0) { dirName2 = String("asap_FITS"); } Directory dir(dirName2); dir.create(True); ostringstream oss; oss << "Created directory '" << dirName2 << "' for output files"; // Temps Vector whichStokes(1,1); Array whichDir; Vector lonLat(2); IPosition posDir(2,0); Projection proj(Projection::SIN); // What should we use ? Matrix xForm(2,2); xForm = 0.0; xForm.diagonal() = 1.0; Vector incLonLat(2,0.0); Vector refPixLonLat(2,0.0); // Do we have linear or circular ? No way to know yet... Bool linear = True; // Loop over rows uInt maxMem = 128; Bool preferVelocity = False; Bool opticalVelocity = False; Int bitPix = -32; // FLoating point Float minPix = 1.0; Float maxPix = -1.0; Bool overWrite = True; Bool degLast = False; Bool reallyVerbose = False; // String errMsg; const uInt nRows = sdTable.nRow(); for (uInt iRow=0; iRow& dataIn(sdTable.rowAsMaskedArray(iRow,toStokes)); const Array& values = dataIn.getArray(); const Array& mask = dataIn.getMask(); const IPosition& shapeIn = dataIn.shape(); shapeOut(0) = shapeIn(chanAxis); TiledShape tShapeOut(shapeOut); // Update ObsInfo (time changes per integration) Double dTmp; timeCol.get(iRow, dTmp); MVEpoch tmp2(Quantum(dTmp, Unit(String("d")))); MEpoch epoch(tmp2, timeRef); oi.setObsDate(epoch); // Iterate through data in this row by spectra ReadOnlyVectorIterator itData(values, chanAxis); ReadOnlyVectorIterator itMask(mask, chanAxis); while (!itData.pastEnd()) { const IPosition& pos = itData.pos(); // Form SpectralCoordinate Vector iTmp; freqidCol.get(iRow, iTmp); uInt freqID = iTmp(pos(ifAxis)); // restfreqidCol.get(iRow, iTmp); uInt restFreqID = iTmp(pos(ifAxis)); // SpectralCoordinate sC = sdTable.getSpectralCoordinate(freqID, restFreqID, iRow); // Form DirectionCoordinate dirCol.get(iRow, whichDir); posDir(0) = pos(beamAxis); posDir(1) = 0; lonLat[0] = whichDir(posDir); // posDir(0) = pos(beamAxis); posDir(1) = 1; lonLat[1] = whichDir(posDir); DirectionCoordinate dC(dirRef, proj, lonLat[0], lonLat[1], incLonLat[0], incLonLat[1], xForm, refPixLonLat[0], refPixLonLat[1]); // Form Stokes Coordinate (Stokes info still sketchy); Stokes::StokesTypes stokes = SDPolUtil::convertStokes(pos(stokesAxis), toStokes, linear); String stokesName = Stokes::name(stokes); whichStokes(0) = Int(stokes); StokesCoordinate stC(whichStokes); // Create CoordinateSystem CoordinateSystem cSys; cSys.addCoordinate(sC); cSys.addCoordinate(dC); cSys.addCoordinate(stC); cSys.setObsInfo(oi); // Reform data into correct shape for output Array t1(itData.array().reform(shapeOut)); Array m1(itMask.array().reform(shapeOut)); // Create aips++ Image TempImage tIm(tShapeOut, cSys); tIm.put(t1); // ArrayLattice latMask(m1); tIm.attachMask(latMask); // Write out as FITS Image file ostringstream oss2; oss2 << "row" << iRow << "_beam" << pos(0) << "_if" << pos(1) << "_" << stokesName << "_" << srcCol(iRow) << ".fits"; String tS(oss2); String fileName = dirName2 + String("/") + tS; if (verbose) oss << endl << "Writing row " << iRow << " into file '" << tS << "'"; // Bool ok = ImageFITSConverter::ImageToFITS(errMsg, tIm, fileName, maxMem, preferVelocity, opticalVelocity, bitPix, minPix, maxPix, overWrite, degLast, reallyVerbose); if (!ok) { oss << endl<< "Error writing fits - " << errMsg; } // Next spectrum itData.next(); itMask.next(); } } // if (!verbose) { oss << endl<< "Wrote " << nRows << " into individual FITS files"; } pushLog(String(oss)); return True; }