source: trunk/src/STFiller.cpp@ 1406

Last change on this file since 1406 was 1391, checked in by Malte Marquarding, 17 years ago

merge from alma branch to get alma/GBT support. Commented out fluxUnit changes as they are using a chnaged interface to PKSreader/writer. Also commented out progress meter related code.

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