source: trunk/src/STFiller.cpp@ 969

Last change on this file since 969 was 942, checked in by mar637, 19 years ago

fixed _S stripping in sourcename; reverted auto-detection of npol==1 == stokes

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