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

Last change on this file since 1815 was 1815, checked in by Malte Marquarding, 15 years ago

Eradicte raw pointer use.

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