source: trunk/src/STWriter.cpp @ 1390

Last change on this file since 1390 was 1390, checked in by Malte Marquarding, 17 years ago

fix for scanning data, where direction can change per cycle not only per beam

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1//#---------------------------------------------------------------------------
2//# STWriter.cc: ASAP class to write out single dish spectra.
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2004
5//# ATNF
6//#
7//# This program is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU General Public License as published by the Free
9//# Software Foundation; either version 2 of the License, or (at your option)
10//# any later version.
11//#
12//# This program is distributed in the hope that it will be useful, but
13//# WITHOUT ANY WARRANTY; without even the implied warranty of
14//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
15//# Public License for more details.
16//#
17//# You should have received a copy of the GNU General Public License along
18//# with this program; if not, write to the Free Software Foundation, Inc.,
19//# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning this software should be addressed as follows:
22//#        Internet email: Malte.Marquarding@csiro.au
23//#        Postal address: Malte Marquarding,
24//#                        Australia Telescope National Facility,
25//#                        P.O. Box 76,
26//#                        Epping, NSW, 2121,
27//#                        AUSTRALIA
28//#
29//# $Id: STWriter.cpp 1390 2007-07-27 01:29:54Z MalteMarquarding $
30//#---------------------------------------------------------------------------
31
32#include <string>
33
34#include <casa/aips.h>
35#include <casa/Arrays/Array.h>
36#include <casa/Arrays/Vector.h>
37#include <casa/BasicSL/Complex.h>
38#include <casa/Utilities/CountedPtr.h>
39#include <casa/Utilities/Assert.h>
40
41#include <atnf/PKSIO/PKSMS2writer.h>
42#include <atnf/PKSIO/PKSSDwriter.h>
43
44#include <tables/Tables/Table.h>
45#include <tables/Tables/TableIter.h>
46#include <tables/Tables/TableRow.h>
47#include <tables/Tables/ArrayColumn.h>
48
49//#include "SDFITSImageWriter.h"
50#include "STAsciiWriter.h"
51#include "STHeader.h"
52
53#include "STWriter.h"
54
55using namespace casa;
56namespace asap {
57
58STWriter::STWriter(const std::string &format)
59{
60  format_ = format;
61  String t(format_);
62  t.upcase();
63  if (t== "MS2") {
64    writer_ = new PKSMS2writer();
65  } else if (t== "SDFITS") {
66    writer_ = new PKSSDwriter();
67  } else if (t== "ASCII") {
68    writer_ = 0;
69  } else {
70    throw (AipsError("Unrecognized export format"));
71  }
72}
73
74STWriter::~STWriter()
75{
76   if (writer_) {
77     delete writer_;
78   }
79}
80
81Int STWriter::setFormat(const std::string &format)
82{
83  if (format != format_) {
84    if (writer_) delete writer_;
85  }
86
87  format_ = format;
88  String t(format_);
89  t.upcase();
90  if (t== "MS2") {
91    writer_ = new PKSMS2writer();
92  } else if (t== "SDFITS") {
93    writer_ = new PKSSDwriter();
94  } else if (t== "ASCII") {
95    writer_ = 0;
96  } else {
97    throw (AipsError("Unrecognized Format"));
98  }
99  return 0;
100}
101
102Int STWriter::write(const CountedPtr<Scantable> in,
103                    const std::string &filename)
104{
105
106  if (format_=="ASCII") {
107    STAsciiWriter iw;
108    if (iw.write(*in, filename)) {
109      return 0;
110    } else {
111      return 1;
112    }
113  }
114
115  // MS or SDFITS
116
117  // Extract the header from the table.
118  STHeader hdr = in->getHeader();
119  //const Int nPol  = hdr.npol;
120  //const Int nChan = hdr.nchan;
121  std::vector<uint> ifs = in->getIFNos();
122  int nIF = in->nif();//ifs.size();
123  Vector<uInt> nPol(nIF),nChan(nIF);
124  Vector<Bool> havexpol(nIF);
125  nPol = 0;nChan = 0; havexpol = False;
126  for (uint i=0;i<ifs.size();++i) {
127    nPol(ifs[i]) = in->npol();
128    nChan(ifs[i]) = in->nchan(ifs[i]);
129    havexpol(ifs[i]) = nPol(ifs[i]) > 2;
130  }
131
132  const Table table = in->table();
133
134  // Create the output file and write static data.
135  Int status;
136  status = writer_->create(String(filename), hdr.observer, hdr.project,
137                               hdr.antennaname, hdr.antennaposition,
138                               hdr.obstype, hdr.equinox, hdr.freqref,
139                               nChan, nPol, havexpol, False);
140  if ( status ) {
141    throw(AipsError("Failed to create output file"));
142  }
143
144  Double          srcVel;
145
146  String          fieldName, srcName, tcalTime;
147  Vector<Float>   calFctr, sigma, tcal, tsys;
148  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2);
149  Matrix<Float>   spectra;
150  Matrix<uChar>   flagtra;
151  Complex         xCalFctr;
152  Int count = 0;
153  Int scanno = 1;
154  // use spearate iterators to ensure renumbering of all numbers
155  TableIterator scanit(table, "SCANNO");
156  while (!scanit.pastEnd() ) {
157    Table stable = scanit.table();
158    TableIterator beamit(stable, "BEAMNO");
159    Int beamno = 1;
160    while (!beamit.pastEnd() ) {
161      Table btable = beamit.table();
162      TableIterator cycit(btable, "CYCLENO");
163      ROArrayColumn<Double> srateCol(btable, "SCANRATE");
164      srateCol.get(0, scanRate);
165      ROArrayColumn<Double> spmCol(btable, "SRCPROPERMOTION");
166      spmCol.get(0, srcPM);
167      ROArrayColumn <Double> sdirCol(btable, "SRCDIRECTION");
168      sdirCol.get(0, srcDir);
169      ROScalarColumn<Double> svelCol(btable, "SRCVELOCITY");
170      svelCol.get(0, srcVel);
171      ROScalarColumn<uInt> bCol(btable, "BEAMNO");
172      beamno = bCol(0)+1;
173      Int cycno = 1;
174      while (!cycit.pastEnd() ) {
175        Table ctable = cycit.table();
176        TableIterator ifit(ctable, "IFNO");
177        MDirection::ScalarColumn dirCol(ctable, "DIRECTION");
178        Vector<Double> direction = dirCol(0).getAngle("rad").getValue();
179        Int ifno = 1;
180        while (!ifit.pastEnd() ) {
181          Table itable = ifit.table();
182          TableRow row(itable);
183          // use the first row to fill in all the "metadata"
184          const TableRecord& rec = row.get(0);
185          ROArrayColumn<Float> specCol(itable, "SPECTRA");
186          ifno = rec.asuInt("IFNO")+1;
187          uInt nchan = specCol(0).nelements();
188          Double cdelt,crval,crpix, restfreq;
189          Float focusAxi, focusTan, focusRot,
190                temperature, pressure, humidity, windSpeed, windAz;
191          Float tmp0,tmp1,tmp2,tmp3,tmp4;
192          Vector<Float> tcalval;
193          String stmp0,stmp1, tcalt;
194          in->frequencies().getEntry(crpix,crval,cdelt, rec.asuInt("FREQ_ID"));
195          in->focus().getEntry(focusAxi, focusTan, focusRot,
196                               tmp0,tmp1,tmp2,tmp3,tmp4,
197                               rec.asuInt("FOCUS_ID"));
198          in->molecules().getEntry(restfreq,stmp0,stmp1,rec.asuInt("MOLECULE_ID"));
199          in->tcal().getEntry(tcalt,tcalval,rec.asuInt("TCAL_ID"));
200          in->weather().getEntry(temperature, pressure, humidity,
201                                 windSpeed, windAz,
202                                 rec.asuInt("WEATHER_ID"));
203          Double pixel = Double(nchan/2);
204          Double refFreqNew = (pixel-crpix)*cdelt + crval;
205          // ok, now we have nrows for the n polarizations in this table
206          Matrix<Float> specs;
207          Matrix<uChar> flags;
208          Vector<Complex> xpol;
209          polConversion(specs, flags, xpol, itable);
210          Vector<Float> tsys = tsysFromTable(itable);
211          // dummy data
212          uInt npol = specs.ncolumn();
213
214          Matrix<Float>   baseLin(npol,2, 0.0f);
215          Matrix<Float>   baseSub(npol,9, 0.0f);
216          Complex         xCalFctr;
217          Vector<Double>  scanRate(2, 0.0);
218          Vector<Float>   sigma(npol, 0.0f);
219          Vector<Float>   calFctr(npol, 0.0f);
220          status = writer_->write(scanno, cycno, rec.asDouble("TIME"),
221                                      rec.asDouble("INTERVAL"),
222                                      rec.asString("FIELDNAME"),
223                                      rec.asString("SRCNAME"),
224                                      srcDir, srcPM, srcVel,hdr.obstype,
225                                      ifno,
226                                      refFreqNew, nchan*abs(cdelt), cdelt,
227                                      restfreq,
228                                      tcal,
229                                      tcalt,
230                                      rec.asFloat("AZIMUTH"),
231                                      rec.asFloat("ELEVATION"),
232                                      rec.asFloat("PARANGLE"),
233                                      focusAxi, focusTan, focusRot,
234                                      temperature,
235                                      pressure, humidity, windSpeed, windAz,
236                                      rec.asInt("REFBEAMNO")+1, beamno,
237                                      direction,
238                                      scanRate,
239                                      tsys,
240                                      sigma, calFctr,// not in scantable
241                                      baseLin, baseSub,// not in scantable
242                                      specs, flags,
243                                      xCalFctr,//
244                                      xpol);
245          if ( status ) {
246            writer_->close();
247            throw(AipsError("STWriter: Failed to export Scantable."));
248          }
249          ++count;
250          //++ifno;
251          ++ifit;
252        }
253        ++cycno;
254        ++cycit;
255      }
256      //++beamno;
257      ++beamit;
258    }
259    ++scanno;
260    ++scanit;
261  }
262  ostringstream oss;
263  oss << "STWriter: wrote " << count << " rows to " << filename;
264  pushLog(String(oss));
265  writer_->close();
266
267  return 0;
268}
269
270Vector<Float> STWriter::tsysFromTable(const Table& tab)
271{
272  ROArrayColumn<Float> tsysCol(tab, "TSYS");
273  Vector<Float> out(tab.nrow());
274  Vector<Float> tmp;
275  for (uInt i=0; i<tab.nrow(); ++i) {
276    tmp.resize();
277    tmp = tsysCol(i);
278    out[i] = tmp[0];
279  }
280  return out;
281}
282
283void STWriter::polConversion( Matrix< Float >& specs, Matrix< uChar >& flags,
284                              Vector< Complex > & xpol, const Table & tab )
285{
286  String poltype = tab.keywordSet().asString("POLTYPE");
287  if ( poltype == "stokes") {
288    String msg = "poltype = " + poltype + " not yet supported in output.";
289    throw(AipsError(msg));
290  }
291  ROArrayColumn<Float> specCol(tab, "SPECTRA");
292  ROArrayColumn<uChar> flagCol(tab, "FLAGTRA");
293  uInt nchan = specCol(0).nelements();
294  uInt ncol = (tab.nrow()==1 ? 1: 2 );
295  specs.resize(nchan, ncol);
296  flags.resize(nchan, ncol);
297  // the linears
298  for (uInt i=0; i<ncol; ++i) {
299    specs.column(i) = specCol(i);
300    flags.column(i) = flagCol(i);
301  }
302  // now the complex if exists
303  Bool hasxpol = False;
304  xpol.resize();
305  if ( tab.nrow() == 4 ) {
306    hasxpol = True;
307    xpol.resize(nchan);
308    Vector<Float> reals, imags;
309    reals = specCol(2); imags = specCol(3);
310    for (uInt k=0; k < nchan; ++k) {
311      xpol[k] = Complex(reals[k], imags[k]);
312    }
313  }
314}
315
316
317}
Note: See TracBrowser for help on using the repository browser.