source: trunk/src/STFiller.cpp @ 922

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

fixed type azimuth and elevation types to be float. fixed pattern match fro Tid reference scans.

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