source: branches/alma/src/STFiller.cpp@ 1420

Last change on this file since 1420 was 1387, checked in by TakTsutsumi, 17 years ago

merged from NRAO version of ASAP 2.1 with ALMA specific modifications

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.2 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 header_->fluxunit);
123
124 if (status) {
125 delete reader_;
126 reader_ = 0;
127 delete header_;
128 header_ = 0;
129 throw(AipsError("Failed to get header."));
130 }
131 if ((header_->obstype).matches("*SW*")) {
132 // need robust way here - probably read ahead of next timestamp
133 pushLog("Header indicates frequency switched observation.\n"
134 "setting # of IFs = 1 ");
135 nIF_ = 1;
136 header_->obstype = String("fswitch");
137 }
138 // Determine Telescope and set brightness unit
139
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 STAttr stattr;
148 header_->poltype = stattr.feedPolType(inst);
149 header_->nif = nIF_;
150 header_->epoch = "UTC";
151 // *** header_->frequnit = "Hz"
152 // Apply selection criteria.
153 Vector<Int> ref;
154 ifOffset_ = 0;
155 if (whichIF>=0) {
156 if (whichIF>=0 && whichIF<nIF_) {
157 ifs = False;
158 ifs(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 beamOffset_ = 0;
171 if (whichBeam>=0) {
172 if (whichBeam>=0 && whichBeam<nBeam_) {
173 beams = False;
174 beams(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(beams, ifs, start, end, ref, True, haveXPol_[0], False);
189 table_->setHeader(*header_);
190 //For MS, add the location of POINTING of the input MS so one get
191 //pointing data from there, if necessary.
192 //Also find nrow in MS
193 nInDataRow = 0;
194 if (format == "MS2") {
195 Path datapath(inName);
196 String ptTabPath = datapath.absoluteName();
197 Table inMS(ptTabPath);
198 nInDataRow = inMS.nrow();
199 ptTabPath.append("/POINTING");
200 table_->table().rwKeywordSet().define("POINTING", ptTabPath);
201 if ((header_->antennaname).matches("GBT")) {
202 String GOTabPath = datapath.absoluteName();
203 GOTabPath.append("/GBT_GO");
204 table_->table().rwKeywordSet().define("GBT_GO", GOTabPath);
205 }
206 }
207
208}
209
210void STFiller::close( )
211{
212 delete reader_;reader_=0;
213 delete header_;header_=0;
214 table_ = 0;
215}
216
217int asap::STFiller::read( )
218{
219 int status = 0;
220
221 Int beamNo, IFno, refBeam, scanNo, cycleNo;
222 Float azimuth, elevation, focusAxi, focusRot, focusTan,
223 humidity, parAngle, pressure, temperature, windAz, windSpeed;
224 Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
225 String fieldName, srcName, tcalTime, obsType;
226 Vector<Float> calFctr, sigma, tcal, tsys;
227 Matrix<Float> baseLin, baseSub;
228 Vector<Double> direction(2), scanRate(2), srcDir(2), srcPM(2);
229 Matrix<Float> spectra;
230 Matrix<uChar> flagtra;
231 Complex xCalFctr;
232 Vector<Complex> xPol;
233 Double min = 0.0;
234 Double max = nInDataRow;
235 ProgressMeter fillpm(min, max, "Data importing progress");
236 int n = 0;
237 while ( status == 0 ) {
238 status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
239 srcName, srcDir, srcPM, srcVel, obsType, IFno,
240 refFreq, bandwidth, freqInc, restFreq, tcal, tcalTime,
241 azimuth, elevation, parAngle, focusAxi,
242 focusTan, focusRot, temperature, pressure,
243 humidity, windSpeed, windAz, refBeam,
244 beamNo, direction, scanRate,
245 tsys, sigma, calFctr, baseLin, baseSub,
246 spectra, flagtra, xCalFctr, xPol);
247 if ( status != 0 ) break;
248 n += 1;
249
250 Regex filterrx(".*[SL|PA]$");
251 Regex obsrx("^AT.+");
252 if ( header_->antennaname.matches(obsrx) && obsType.matches(filterrx)) {
253 //cerr << "ignoring paddle scan" << endl;
254 continue;
255 }
256 TableRow row(table_->table());
257 TableRecord& rec = row.record();
258 // fields that don't get used and are just passed through asap
259 RecordFieldPtr<Array<Double> > srateCol(rec, "SCANRATE");
260 *srateCol = scanRate;
261 RecordFieldPtr<Array<Double> > spmCol(rec, "SRCPROPERMOTION");
262 *spmCol = srcPM;
263 RecordFieldPtr<Array<Double> > sdirCol(rec, "SRCDIRECTION");
264 *sdirCol = srcDir;
265 RecordFieldPtr<Double> svelCol(rec, "SRCVELOCITY");
266 *svelCol = srcVel;
267 // the real stuff
268 RecordFieldPtr<Int> fitCol(rec, "FIT_ID");
269 *fitCol = -1;
270 RecordFieldPtr<uInt> scanoCol(rec, "SCANNO");
271 *scanoCol = scanNo-1;
272 RecordFieldPtr<uInt> cyclenoCol(rec, "CYCLENO");
273 *cyclenoCol = cycleNo-1;
274 RecordFieldPtr<Double> mjdCol(rec, "TIME");
275 *mjdCol = mjd;
276 RecordFieldPtr<Double> intCol(rec, "INTERVAL");
277 *intCol = interval;
278 RecordFieldPtr<String> srcnCol(rec, "SRCNAME");
279 RecordFieldPtr<Int> srctCol(rec, "SRCTYPE");
280 RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME");
281 *fieldnCol = fieldName;
282 // try to auto-identify if it is on or off.
283 Regex rx(".*[e|w|_R]$");
284 Regex rx2("_S$");
285 Int match = srcName.matches(rx);
286 if (match) {
287 *srcnCol = srcName;
288 } else {
289 *srcnCol = srcName.before(rx2);
290 }
291 //*srcnCol = srcName;//.before(rx2);
292 *srctCol = match;
293 RecordFieldPtr<uInt> beamCol(rec, "BEAMNO");
294 *beamCol = beamNo-beamOffset_-1;
295 RecordFieldPtr<Int> rbCol(rec, "REFBEAMNO");
296 Int rb = -1;
297 if (nBeam_ > 1 ) rb = refBeam-1;
298 *rbCol = rb;
299 RecordFieldPtr<uInt> ifCol(rec, "IFNO");
300 *ifCol = IFno-ifOffset_- 1;
301 uInt id;
302 /// @todo this has to change when nchan isn't global anymore
303 id = table_->frequencies().addEntry(Double(header_->nchan/2),
304 refFreq, freqInc);
305 RecordFieldPtr<uInt> mfreqidCol(rec, "FREQ_ID");
306 *mfreqidCol = id;
307
308 id = table_->molecules().addEntry(restFreq);
309 RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
310 *molidCol = id;
311
312 id = table_->tcal().addEntry(tcalTime, tcal);
313 RecordFieldPtr<uInt> mcalidCol(rec, "TCAL_ID");
314 *mcalidCol = id;
315 id = table_->weather().addEntry(temperature, pressure, humidity,
316 windSpeed, windAz);
317 RecordFieldPtr<uInt> mweatheridCol(rec, "WEATHER_ID");
318 *mweatheridCol = id;
319 RecordFieldPtr<uInt> mfocusidCol(rec, "FOCUS_ID");
320 id = table_->focus().addEntry(focusAxi, focusTan, focusRot);
321 *mfocusidCol = id;
322 RecordFieldPtr<Array<Double> > dirCol(rec, "DIRECTION");
323 *dirCol = direction;
324 RecordFieldPtr<Float> azCol(rec, "AZIMUTH");
325 *azCol = azimuth;
326 RecordFieldPtr<Float> elCol(rec, "ELEVATION");
327 *elCol = elevation;
328
329 RecordFieldPtr<Float> parCol(rec, "PARANGLE");
330 *parCol = parAngle;
331
332 RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
333 RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
334 RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
335
336 RecordFieldPtr< Array<Float> > tsysCol(rec, "TSYS");
337 // Turn the (nchan,npol) matrix and possible complex xPol vector
338 // into 2-4 rows in the scantable
339 Vector<Float> tsysvec(1);
340 // Why is spectra.ncolumn() == 3 for haveXPol_ == True
341 uInt npol = (spectra.ncolumn()==1 ? 1: 2);
342 for ( uInt i=0; i< npol; ++i ) {
343 tsysvec = tsys(i);
344 *tsysCol = tsysvec;
345 *polnoCol = i;
346
347 *specCol = spectra.column(i);
348 *flagCol = flagtra.column(i);
349 table_->table().addRow();
350 row.put(table_->table().nrow()-1, rec);
351 }
352 if ( haveXPol_[0] ) {
353 // no tsys given for xpol, so emulate it
354 tsysvec = sqrt(tsys[0]*tsys[1]);
355 *tsysCol = tsysvec;
356 // add real part of cross pol
357 *polnoCol = 2;
358 Vector<Float> r(real(xPol));
359 *specCol = r;
360 // make up flags from linears
361 /// @fixme this has to be a bitwise or of both pols
362 *flagCol = flagtra.column(0);// | flagtra.column(1);
363 table_->table().addRow();
364 row.put(table_->table().nrow()-1, rec);
365 // ad imaginary part of cross pol
366 *polnoCol = 3;
367 Vector<Float> im(imag(xPol));
368 *specCol = im;
369 table_->table().addRow();
370 row.put(table_->table().nrow()-1, rec);
371 }
372 fillpm._update(n);
373 }
374 if (status > 0) {
375 close();
376 throw(AipsError("Reading error occured, data possibly corrupted."));
377 }
378 fillpm.done();
379 return status;
380}
381
382}//namespace asap
Note: See TracBrowser for help on using the repository browser.