source: trunk/src/STFiller.cpp@ 919

Last change on this file since 919 was 905, checked in by mar637, 19 years ago

change default polytype passed as argument to "", to then apply Scantable::poltype if empty.
added poltype to STHeader

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 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<Double> azCol(rec, "AZIMUTH");
281 *azCol = azimuth;
282 RecordFieldPtr<Double> 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.