source: trunk/src/PKSFiller.cpp@ 1913

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

pass down record for filler options

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