source: trunk/src/STFiller.cpp @ 805

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

Code replacemnts after the rename

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