source: branches/newfiller/src/PKSFiller.cpp@ 1804

Last change on this file since 1804 was 1795, checked in by Malte Marquarding, 14 years ago

First Working version of the PKSFiller

File size: 10.0 KB
Line 
1//
2// C++ Implementation: PKSFiller
3//
4// Description:
5//
6//
7// Author: Malte Marquarding <asap@atnf.csiro.au>, (C) 2010
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
24#include <measures/Measures/MDirection.h>
25#include <measures/Measures/MeasConvert.h>
26
27#include <atnf/PKSIO/PKSrecord.h>
28#include <atnf/PKSIO/PKSreader.h>
29
30#ifdef HAS_ALMA
31 #include <casa/System/ProgressMeter.h>
32#endif
33#include <casa/Logging/LogIO.h>
34
35#include <time.h>
36
37#include "STDefs.h"
38#include "STAttr.h"
39
40#include "PKSFiller.h"
41#include "STHeader.h"
42
43using namespace casa;
44
45namespace asap {
46
47
48PKSFiller::PKSFiller( CountedPtr< Scantable > stbl ) :
49 FillerBase(stbl),
50 reader_(0),
51 header_(0)
52{
53 setReferenceRegex(".*(e|w|_R)$");
54}
55
56PKSFiller::~PKSFiller()
57{
58 close();
59}
60
61bool PKSFiller::open( const std::string& filename)
62{
63 /*
64 if (table_.null()) {
65 table_ = new Scantable();
66 }
67 */
68 if (reader_) { delete reader_; reader_ = 0; }
69 Bool haveBase, haveSpectra;
70
71 String inName(filename);
72 Path path(inName);
73 inName = path.expandedName();
74
75 File file(inName);
76 filename_ = inName;
77
78 // Create reader and fill in values for arguments
79 String format;
80 Vector<Bool> beams, ifs;
81 Vector<uInt> nchans,npols;
82
83 String antenna("");
84 if ( (reader_ = getPKSreader(inName, antenna, 0, 0, format, beams, ifs,
85 nchans, npols, haveXPol_,haveBase, haveSpectra
86 )) == 0 ) {
87 return False;
88 }
89
90 if (!haveSpectra) {
91 delete reader_;
92 reader_ = 0;
93 throw(AipsError("No spectral data in file."));
94 }
95 LogIO os;
96 nBeam_ = beams.nelements();
97 nIF_ = ifs.nelements();
98 // Get basic parameters.
99 if ( anyEQ(haveXPol_, True) ) {
100 os << "Cross polarization present" << LogIO::POST;
101 for (uInt i=0; i< npols.nelements();++i) {
102 if (npols[i] < 3) npols[i] += 2;// Convert Complex -> 2 Floats
103 }
104 }
105 if (header_) delete header_;
106 header_ = new STHeader();
107 header_->nchan = max(nchans);
108 header_->npol = max(npols);
109 header_->nbeam = nBeam_;
110
111 Int status = reader_->getHeader(header_->observer, header_->project,
112 header_->antennaname, header_->antennaposition,
113 header_->obstype,
114 header_->fluxunit,
115 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 os << "Header indicates frequency switched observation.\n"
130 << "setting # of IFs = 1 " << LogIO::POST;
131
132 nIF_ = 1;
133 header_->obstype = String("fswitch");
134 }
135 // Determine Telescope and set brightness unit
136
137 Bool throwIt = False;
138 Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
139
140 if (inst==ATMOPRA || inst==TIDBINBILLA) {
141 header_->fluxunit = "K";
142 } else {
143 // downcase for use with Quanta
144 if (header_->fluxunit == "JY") {
145 header_->fluxunit = "Jy";
146 }
147 }
148 STAttr stattr;
149 header_->poltype = stattr.feedPolType(inst);
150 header_->nif = nIF_;
151 header_->epoch = "UTC";
152 // *** header_->frequnit = "Hz"
153 // Apply selection criteria.
154 Vector<Int> ref;
155
156 Vector<Int> start(nIF_, 1);
157 Vector<Int> end(nIF_, 0);
158 Bool getPt = False;
159 reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False, getPt);
160 setHeader(*header_);
161 //For MS, add the location of POINTING of the input MS so one get
162 //pointing data from there, if necessary.
163 //Also find nrow in MS
164 nInDataRow = 0;
165 if (format == "MS2") {
166 Path datapath(inName);
167 String ptTabPath = datapath.absoluteName();
168 Table inMS(ptTabPath);
169 nInDataRow = inMS.nrow();
170 ptTabPath.append("/POINTING");
171 table_->table().rwKeywordSet().define("POINTING", ptTabPath);
172 if ((header_->antennaname).matches("GBT")) {
173 String GOTabPath = datapath.absoluteName();
174 GOTabPath.append("/GBT_GO");
175 table_->table().rwKeywordSet().define("GBT_GO", GOTabPath);
176 }
177 }
178 String freqFrame = header_->freqref;
179 //translate frequency reference frame back to
180 //MS style (as PKSMS2reader converts the original frame
181 //in FITS standard style)
182 if (freqFrame == "TOPOCENT") {
183 freqFrame = "TOPO";
184 } else if (freqFrame == "GEOCENER") {
185 freqFrame = "GEO";
186 } else if (freqFrame == "BARYCENT") {
187 freqFrame = "BARY";
188 } else if (freqFrame == "GALACTOC") {
189 freqFrame = "GALACTO";
190 } else if (freqFrame == "LOCALGRP") {
191 freqFrame = "LGROUP";
192 } else if (freqFrame == "CMBDIPOL") {
193 freqFrame = "CMB";
194 } else if (freqFrame == "SOURCE") {
195 freqFrame = "REST";
196 }
197 // set both "FRAME" and "BASEFRAME"
198 table_->frequencies().setFrame(freqFrame, false);
199 table_->frequencies().setFrame(freqFrame,true);
200 //table_->focus().setParallactify(true);
201
202 return true;
203}
204
205void PKSFiller::close( )
206{
207 if (reader_ != 0) {
208 delete reader_;
209 reader_=0;
210 }
211
212 if (header_ != 0) {
213 delete header_;
214 header_=0;
215 }
216 table_ = 0;
217}
218
219void PKSFiller::fill( )
220{
221 int status = 0;
222
223/**
224 Int beamNo, IFno, refBeam, scanNo, cycleNo;
225 Float azimuth, elevation, focusAxi, focusRot, focusTan,
226 humidity, parAngle, pressure, temperature, windAz, windSpeed;
227 Double bandwidth, freqInc, interval, mjd, refFreq, srcVel;
228 String fieldName, srcName, tcalTime, obsType;
229 Vector<Float> calFctr, sigma, tcal, tsys;
230 Matrix<Float> baseLin, baseSub;
231 Vector<Double> direction(2), scanRate(2), srcDir(2), srcPM(2), restFreq(1);
232 Matrix<Float> spectra;
233 Matrix<uChar> flagtra;
234 Complex xCalFctr;
235 Vector<Complex> xPol;
236**/
237
238 Double min = 0.0;
239 Double max = nInDataRow;
240#ifdef HAS_ALMA
241 ProgressMeter fillpm(min, max, "Data importing progress");
242#endif
243 PKSrecord pksrec;
244 pksrec.srcType=-1;
245 int n = 0;
246 bool isGBTFITS = false ;
247 if ((header_->antennaname.find( "GBT" ) != String::npos)
248 && File(filename_).isRegular()) {
249 FILE *fp = fopen( filename_.c_str(), "r" ) ;
250 fseek( fp, 640, SEEK_SET ) ;
251 char buf[81] ;
252 fread( buf, 80, 1, fp ) ;
253 buf[80] = '\0' ;
254 if ( strstr( buf, "NRAO_GBT" ) != NULL ) {
255 isGBTFITS = true ;
256 }
257 fclose( fp ) ;
258 }
259
260 while ( status == 0 ) {
261
262 status = reader_->read(pksrec);
263 if ( status != 0 ) break;
264 n += 1;
265 Regex filterrx(".*[SL|PA]$");
266 Regex obsrx("^AT.+");
267 if ( header_->antennaname.matches(obsrx) &&
268 pksrec.obsType.matches(filterrx)) {
269 //cerr << "ignoring paddle scan" << endl;
270 continue;
271 }
272
273 Vector<Double> sratedbl(pksrec.scanRate.nelements());
274 convertArray(sratedbl, pksrec.scanRate);
275 //setScanRate(sratedbl);
276
277 Regex rx(getReferenceRegex());
278 Regex rx2("_S$");
279 Int match = pksrec.srcName.matches(rx);
280 std::string srcname;
281 if (match) {
282 srcname = pksrec.srcName;
283 } else {
284 srcname = pksrec.srcName.before(rx2);
285 }
286 Int srctype = match;
287 if ( pksrec.srcType != -1 ) {
288 srctype = pksrec.srcType ;
289 }
290 setTime(pksrec.mjd, pksrec.interval);
291 setSource(srcname, srctype, pksrec.fieldName,
292 pksrec.srcDir, pksrec.srcPM, pksrec.srcVel);
293
294 if (nBeam_ > 1 ) {
295 setReferenceBeam(pksrec.refBeam-1);
296 }
297 setFrequency(Double(header_->nchan/2), pksrec.refFreq, pksrec.freqInc);
298 /*
299 if ( pksrec.nchan == 1 ) {
300 setFrequency(0.0, pksrec.refFreq, pksrec.freqInc)
301 }
302 else {
303 setFrequency(Double(pksrec.nchan/2), pksrec.refFreq, pksrec.freqInc);
304 }
305 */
306 setMolecule(pksrec.restFreq);
307 setTcal(pksrec.tcalTime, pksrec.tcal);
308 setWeather(pksrec.temperature, pksrec.pressure,
309 pksrec.humidity, pksrec.windSpeed,
310 pksrec.windAz);
311 setFocus(pksrec.parAngle, pksrec.focusAxi, pksrec.focusTan,
312 pksrec.focusRot);
313 setDirection(pksrec.direction, pksrec.azimuth, pksrec.elevation);
314
315 // Turn the (nchan,npol) matrix and possible complex xPol vector
316 // into 2-4 rows in the scantable
317 Vector<Float> tsysvec(1);
318 // Why is spectra.ncolumn() == 3 for haveXPol_ == True
319 uInt npol = (pksrec.spectra.ncolumn()==1 ? 1: 2);
320 uInt polno =0;
321 for ( uInt i=0; i< npol; ++i ) {
322 tsysvec = pksrec.tsys(i);
323 if (isGBTFITS) {
324 polno = pksrec.polNo ;
325 } else {
326 polno = i;
327 }
328 setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
329 pksrec.beamNo-1, polno);
330 setSpectrum(pksrec.spectra.column(i), pksrec.flagged.column(i), tsysvec);
331 commitRow();
332 }
333 /*
334 RecordFieldPtr< uInt > flagrowCol(rec, "FLAGROW");
335 *flagrowCol = pksrec.flagrow;
336 */
337 if ( haveXPol_[0] ) {
338 // no tsys given for xpol, so emulate it
339 tsysvec = sqrt(pksrec.tsys[0]*pksrec.tsys[1]);
340 // add real part of cross pol
341 polno = 2;
342 Vector<Float> r(real(pksrec.xPol));
343 // make up flags from linears
344 /// @fixme this has to be a bitwise or of both pols
345 /// pksrec.flagged.column(0) | pksrec.flagged.column(1);
346
347 setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
348 pksrec.beamNo-1, polno);
349 setSpectrum(r, pksrec.flagged.column(0), tsysvec);
350 commitRow();
351
352 // ad imaginary part of cross pol
353 polno = 3;
354 Vector<Float> im(imag(pksrec.xPol));
355 setIndex(pksrec.scanNo-1, pksrec.cycleNo-1, pksrec.IFno-1,
356 pksrec.beamNo-1, polno);
357 setSpectrum(im, pksrec.flagged.column(0), tsysvec);
358 commitRow();
359 }
360#ifdef HAS_ALMA
361 fillpm._update(n);
362#endif
363 }
364 if (status > 0) {
365 close();
366 throw(AipsError("Reading error occured, data possibly corrupted."));
367 }
368#ifdef HAS_ALMA
369 fillpm.done();
370#endif
371}
372
373}//namespace asap
Note: See TracBrowser for help on using the repository browser.