source: trunk/src/STFiller.cpp @ 901

Last change on this file since 901 was 901, checked in by mar637, 18 years ago

SDContainer -> STHeader

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.4 KB
Line 
1//
2// C++ Implementation: STFiller
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
15#include <casa/Exceptions.h>
16#include <casa/OS/Path.h>
17#include <casa/OS/File.h>
18#include <casa/Quanta/Unit.h>
19#include <casa/Arrays/ArrayMath.h>
20#include <casa/Utilities/Regex.h>
21
22#include <casa/Containers/RecordField.h>
23
24#include <tables/Tables/TableRow.h>
25
26#include <atnf/PKSIO/PKSreader.h>
27
28#include "STDefs.h"
29#include "STAttr.h"
30
31#include "STFiller.h"
32#include "STHeader.h"
33
34using namespace casa;
35
36namespace asap {
37
38STFiller::STFiller() :
39  reader_(0),
40  header_(0),
41  table_(0)
42{
43}
44
45STFiller::STFiller( CountedPtr< Scantable > stbl ) :
46  reader_(0),
47  header_(0),
48  table_(stbl)
49{
50}
51
52STFiller::STFiller(const std::string& filename, int whichIF, int whichBeam ) :
53  reader_(0),
54  header_(0),
55  table_(0)
56{
57  open(filename, whichIF, whichBeam);
58}
59
60STFiller::~STFiller()
61{
62  close();
63}
64
65void STFiller::open( const std::string& filename, int whichIF, int whichBeam )
66{
67  if (table_.null())  {
68    table_ = new Scantable();
69  }
70  if (reader_)  { delete reader_; reader_ = 0; }
71  Bool haveBase, haveSpectra;
72
73  String inName(filename);
74  Path path(inName);
75  inName = path.expandedName();
76
77  File file(inName);
78  if ( !file.exists() ) {
79     throw(AipsError("File does not exist"));
80  }
81  filename_ = inName;
82
83  // Create reader and fill in values for arguments
84  String format;
85  Vector<Bool> beams;
86  if ( (reader_ = getPKSreader(inName, 0, 0, format, beams, nIF_,
87                              nChan_, nPol_, haveBase, haveSpectra,
88                              haveXPol_)) == 0 )  {
89    throw(AipsError("Creation of PKSreader failed"));
90  }
91  if (!haveSpectra) {
92    delete reader_;
93    reader_ = 0;
94    throw(AipsError("No spectral data in file."));
95    return;
96  }
97
98  nBeam_ = beams.nelements();
99  // Get basic parameters.
100  if ( haveXPol_ ) {
101    pushLog("Cross polarization present");
102    nPol_ += 2;                          // Convert Complex -> 2 Floats
103  }
104
105  if (header_) delete header_;
106  header_ = new STHeader();
107  header_->nchan = nChan_;
108  header_->npol = nPol_;
109  header_->nbeam = nBeam_;
110
111  Int status = reader_->getHeader(header_->observer, header_->project,
112                                  header_->antennaname, header_->antennaposition,
113                                  header_->obstype,header_->equinox,
114                                  header_->freqref,
115                                  header_->utc, header_->reffreq,
116                                  header_->bandwidth);
117
118  if (status) {
119    delete reader_;
120    reader_ = 0;
121    delete header_;
122    header_ = 0;
123    throw(AipsError("Failed to get header."));
124  }
125  if ((header_->obstype).matches("*SW*")) {
126    // need robust way here - probably read ahead of next timestamp
127    pushLog("Header indicates frequency switched observation.\n"
128               "setting # of IFs = 1 ");
129    nIF_ = 1;
130    header_->obstype = String("fswitch");
131  }
132
133  // Determine Telescope and set brightness unit
134
135  Bool throwIt = False;
136  Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
137  header_->fluxunit = "Jy";
138  if (inst==ATMOPRA || inst==TIDBINBILLA) {
139     header_->fluxunit = "K";
140  }
141
142  header_->nif = nIF_;
143  header_->epoch = "UTC";
144  // *** header_->frequnit = "Hz"
145  // Apply selection criteria.
146
147  Vector<Int> ref;
148  Vector<Bool> beamSel(nBeam_,True);
149  Vector<Bool> IFsel(nIF_,True);
150
151  ifOffset_ = 0;
152  if (whichIF>=0) {
153    if (whichIF>=0 && whichIF<nIF_) {
154      IFsel = False;
155      IFsel(whichIF) = True;
156      header_->nif = 1;
157      nIF_ = 1;
158      ifOffset_ = whichIF;
159    } else {
160      delete reader_;
161      reader_ = 0;
162      delete header_;
163      header_ = 0;
164      throw(AipsError("Illegal IF selection"));
165    }
166  }
167
168  beamOffset_ = 0;
169  if (whichBeam>=0) {
170    if (whichBeam>=0 && whichBeam<nBeam_) {
171      beamSel = False;
172      beamSel(whichBeam) = True;
173      header_->nbeam = 1;
174      nBeam_ = 1;
175      beamOffset_ = whichBeam;
176    } else {
177      delete reader_;
178      reader_ = 0;
179      delete header_;
180      header_ = 0;
181      throw(AipsError("Illegal Beam selection"));
182    }
183  }
184  Vector<Int> start(nIF_, 1);
185  Vector<Int> end(nIF_, 0);
186  reader_->select(beamSel, IFsel, start, end, ref, True, haveXPol_);
187  table_->setHeader(*header_);
188}
189
190void STFiller::close( )
191{
192  delete reader_;reader_=0;
193  delete header_;header_=0;
194  table_ = 0;
195}
196
197int asap::STFiller::read( )
198{
199  int status = 0;
200
201  Int    beamNo, IFno, refBeam, scanNo, cycleNo;
202  Float  azimuth, elevation, focusAxi, focusRot, focusTan,
203    humidity, parAngle, pressure, temperature, windAz, windSpeed;
204  Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
205  String          fieldName, srcName, tcalTime;
206  Vector<Float>   calFctr, sigma, tcal, tsys;
207  Matrix<Float>   baseLin, baseSub;
208  Vector<Double>  direction(2), scanRate(2), srcDir(2), srcPM(2);
209  Matrix<Float>   spectra;
210  Matrix<uChar>   flagtra;
211  Complex         xCalFctr;
212  Vector<Complex> xPol;
213  while ( status == 0 ) {
214    status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
215                          srcName, srcDir, srcPM, srcVel, IFno, refFreq,
216                          bandwidth, freqInc, restFreq, tcal, tcalTime,
217                          azimuth, elevation, parAngle, focusAxi,
218                          focusTan, focusRot, temperature, pressure,
219                          humidity, windSpeed, windAz, refBeam,
220                          beamNo, direction, scanRate,
221                          tsys, sigma, calFctr, baseLin, baseSub,
222                          spectra, flagtra, xCalFctr, xPol);
223    if ( status != 0 ) break;
224    TableRow row(table_->table());
225    TableRecord& rec = row.record();
226    RecordFieldPtr<uInt> scanoCol(rec, "SCANNO");
227    *scanoCol = scanNo-1;
228    RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO");
229    *cyclenoCol = cycleNo-1;
230    RecordFieldPtr<Double> mjdCol(rec, "TIME");
231    *mjdCol = mjd;
232    RecordFieldPtr<Double> intCol(rec, "INTERVAL");
233    *intCol = interval;
234    RecordFieldPtr<String> srcnCol(rec, "SRCNAME");
235    RecordFieldPtr<Int> srctCol(rec, "SRCTYPE");
236    // try to auto-identify if it is on or off.
237    Regex rx(".*_[e|w|R]$");
238    Regex rx2("_[e|w|R|S]$");
239    Int match = srcName.matches(rx);
240    if (match) {
241      *srcnCol = srcName;
242    } else {
243      *srcnCol = srcName.before(rx2);
244    }
245    //*srcnCol = srcName;//.before(rx2);
246    *srctCol = match;
247    RecordFieldPtr<uInt> beamCol(rec, "BEAMNO");
248    *beamCol = beamNo-beamOffset_-1;
249    RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO");
250    Int rb = -1;
251    if (nBeam_ > 1 ) rb = refBeam-1;
252    *rbCol = rb;
253    RecordFieldPtr<uInt> ifCol(rec, "IFNO");
254    *ifCol = IFno-ifOffset_- 1;
255    uInt id;
256    /// @todo this has to change when nchan isn't global anymore
257    id = table_->frequencies().addEntry(Double(header_->nchan/2),
258                                            refFreq, freqInc);
259    RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID");
260    *mfreqidCol = id;
261
262    id = table_->molecules().addEntry(restFreq);
263    RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
264    *molidCol = id;
265
266    id = table_->tcal().addEntry(tcalTime, tcal);
267    RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID");
268    *mcalidCol = id;
269    id = table_->weather().addEntry(temperature, pressure, humidity,
270                                    windSpeed, windAz);
271    RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID");
272    *mweatheridCol = id;
273    RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID");
274    id = table_->focus().addEntry(focusAxi, focusTan, focusRot);
275    *mfocusidCol = id;
276    RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION");
277    *dirCol = direction;
278    RecordFieldPtr<Double> azCol(rec, "AZIMUTH");
279    *azCol = azimuth;
280    RecordFieldPtr<Double> elCol(rec, "ELEVATION");
281    *elCol = elevation;
282
283    RecordFieldPtr<Float> parCol(rec, "PARANGLE");
284    *parCol = parAngle;
285
286    RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
287    RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
288    RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
289
290    RecordFieldPtr< Array<Float> > tsysCol(rec, "TSYS");
291    // Turn the (nchan,npol) matrix and possible complex xPol vector
292    // into 2-4 rows in the scantable
293    Vector<Float> tsysvec(1);
294    // Why is spectra.ncolumn() == 3 for haveXPol_ == True
295    uInt npol = (spectra.ncolumn()==1 ? 1: 2);
296    for ( uInt i=0; i< npol; ++i ) {
297      tsysvec = tsys(i);
298      *tsysCol = tsysvec;
299      *polnoCol = i;
300
301      *specCol = spectra.column(i);
302      *flagCol = flagtra.column(i);
303      table_->table().addRow();
304      row.put(table_->table().nrow()-1, rec);
305    }
306    if ( haveXPol_ ) {
307      // no tsys given for xpol, so emulate it
308      tsysvec = sqrt(tsys[0]*tsys[1]);
309      *tsysCol = tsysvec;
310      // add real part of cross pol
311      *polnoCol = 2;
312      Vector<Float> r(real(xPol));
313      *specCol = r;
314      // make up flags from linears
315      /// @fixme this has to be a bitwise or of both pols
316      *flagCol = flagtra.column(0);// | flagtra.column(1);
317      table_->table().addRow();
318      row.put(table_->table().nrow()-1, rec);
319      // ad imaginary part of cross pol
320      *polnoCol = 3;
321      Vector<Float> im(imag(xPol));
322      *specCol = im;
323      table_->table().addRow();
324      row.put(table_->table().nrow()-1, rec);
325    }
326  }
327  if (status > 0) {
328    close();
329    throw(AipsError("Reading error occured, data possibly corrupted."));
330  }
331  return status;
332}
333
334}//namespace asap
Note: See TracBrowser for help on using the repository browser.