source: trunk/src/STFiller.cpp@ 880

Last change on this file since 880 was 878, checked in by mar637, 19 years ago

SDAttr->STAttr name change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.3 KB
RevLine 
[805]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//
[404]12#include <casa/iostream.h>
13#include <casa/iomanip.h>
14
[125]15#include <casa/Exceptions.h>
[284]16#include <casa/OS/Path.h>
[290]17#include <casa/OS/File.h>
[338]18#include <casa/Quanta/Unit.h>
[805]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
[2]26#include <atnf/PKSIO/PKSreader.h>
[125]27
[835]28#include "STDefs.h"
[878]29#include "STAttr.h"
[2]30
[805]31#include "STFiller.h"
32
[125]33using namespace casa;
[2]34
[805]35namespace asap {
36
37STFiller::STFiller() :
[2]38 reader_(0),
[405]39 header_(0),
[805]40 table_(0)
[420]41{
[2]42}
[805]43
44STFiller::STFiller( CountedPtr< Scantable > stbl ) :
[46]45 reader_(0),
[405]46 header_(0),
[805]47 table_(stbl)
[420]48{
[46]49}
[2]50
[855]51STFiller::STFiller(const std::string& filename, int whichIF, int whichBeam ) :
[2]52 reader_(0),
[405]53 header_(0),
[805]54 table_(0)
[420]55{
[805]56 open(filename, whichIF, whichBeam);
[2]57}
58
[805]59STFiller::~STFiller()
60{
61 close();
[2]62}
63
[855]64void STFiller::open( const std::string& filename, int whichIF, int whichBeam )
[805]65{
[846]66 if (table_.null()) {
67 table_ = new Scantable();
68 }
[805]69 if (reader_) { delete reader_; reader_ = 0; }
70 Bool haveBase, haveSpectra;
[2]71
72 String inName(filename);
[284]73 Path path(inName);
74 inName = path.expandedName();
[405]75
[290]76 File file(inName);
[805]77 if ( !file.exists() ) {
[290]78 throw(AipsError("File does not exist"));
79 }
[87]80 filename_ = inName;
[332]81
[405]82 // Create reader and fill in values for arguments
[2]83 String format;
84 Vector<Bool> beams;
[805]85 if ( (reader_ = getPKSreader(inName, 0, 0, format, beams, nIF_,
[2]86 nChan_, nPol_, haveBase, haveSpectra,
[805]87 haveXPol_)) == 0 ) {
[405]88 throw(AipsError("Creation of PKSreader failed"));
[2]89 }
90 if (!haveSpectra) {
91 delete reader_;
92 reader_ = 0;
[87]93 throw(AipsError("No spectral data in file."));
[2]94 return;
95 }
[405]96
[2]97 nBeam_ = beams.nelements();
98 // Get basic parameters.
[805]99 if ( haveXPol_ ) {
[717]100 pushLog("Cross polarization present");
[420]101 nPol_ += 2; // Convert Complex -> 2 Floats
[110]102 }
[420]103
[405]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
[2]117 if (status) {
118 delete reader_;
119 reader_ = 0;
[805]120 delete header_;
121 header_ = 0;
[87]122 throw(AipsError("Failed to get header."));
[2]123 }
[405]124 if ((header_->obstype).matches("*SW*")) {
[2]125 // need robust way here - probably read ahead of next timestamp
[717]126 pushLog("Header indicates frequency switched observation.\n"
[754]127 "setting # of IFs = 1 ");
[2]128 nIF_ = 1;
[805]129 header_->obstype = String("fswitch");
[2]130 }
[337]131
[405]132 // Determine Telescope and set brightness unit
[342]133
134 Bool throwIt = False;
[878]135 Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
[405]136 header_->fluxunit = "Jy";
[342]137 if (inst==ATMOPRA || inst==TIDBINBILLA) {
[405]138 header_->fluxunit = "K";
[342]139 }
[332]140
[405]141 header_->nif = nIF_;
142 header_->epoch = "UTC";
[805]143 // *** header_->frequnit = "Hz"
[2]144 // Apply selection criteria.
[332]145
[2]146 Vector<Int> ref;
147 Vector<Bool> beamSel(nBeam_,True);
148 Vector<Bool> IFsel(nIF_,True);
[405]149
[332]150 ifOffset_ = 0;
151 if (whichIF>=0) {
152 if (whichIF>=0 && whichIF<nIF_) {
[805]153 IFsel = False;
154 IFsel(whichIF) = True;
155 header_->nif = 1;
156 nIF_ = 1;
157 ifOffset_ = whichIF;
[332]158 } else {
[805]159 delete reader_;
160 reader_ = 0;
161 delete header_;
162 header_ = 0;
163 throw(AipsError("Illegal IF selection"));
[332]164 }
165 }
[405]166
[332]167 beamOffset_ = 0;
168 if (whichBeam>=0) {
[805]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 }
[332]182 }
183 Vector<Int> start(nIF_, 1);
184 Vector<Int> end(nIF_, 0);
[420]185 reader_->select(beamSel, IFsel, start, end, ref, True, haveXPol_);
[846]186 table_->setHeader(*header_);
[805]187}
[405]188
[805]189void STFiller::close( )
190{
191 delete reader_;reader_=0;
192 delete header_;header_=0;
193 table_ = 0;
[2]194}
195
[805]196int asap::STFiller::read( )
197{
[87]198 int status = 0;
199
[17]200 Int beamNo, IFno, refBeam, scanNo, cycleNo;
[87]201 Float azimuth, elevation, focusAxi, focusRot, focusTan,
[2]202 humidity, parAngle, pressure, temperature, windAz, windSpeed;
[73]203 Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
[2]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;
[805]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;
[25]260
[805]261 id = table_->molecules().addEntry(restFreq);
262 RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
263 *molidCol = id;
[414]264
[805]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;
[405]281
[805]282 RecordFieldPtr<Float> parCol(rec, "PARANGLE");
283 *parCol = parAngle;
[332]284
[805]285 RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
286 RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
287 RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
[405]288
[805]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;
[405]299
[805]300 *specCol = spectra.column(i);
301 *flagCol = flagtra.column(i);
302 table_->table().addRow();
303 row.put(table_->table().nrow()-1, rec);
[2]304 }
[805]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);
[2]324 }
[805]325 }
326 if (status > 0) {
327 close();
328 throw(AipsError("Reading error occured, data possibly corrupted."));
329 }
[404]330
[2]331 return status;
332}
[805]333
334}//namespace asap
Note: See TracBrowser for help on using the repository browser.