source: trunk/src/STFiller.cpp@ 1140

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

temporary hack for import of methanol multibeam data

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