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

Last change on this file since 1425 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
RevLine 
[805]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//
[404]12#include <casa/iostream.h>
13#include <casa/iomanip.h>
14
[125]15#include <casa/Exceptions.h>
[284]16#include <casa/OS/Path.h>
[290]17#include <casa/OS/File.h>
[338]18#include <casa/Quanta/Unit.h>
[805]19#include <casa/Arrays/ArrayMath.h>
[1060]20#include <casa/Arrays/ArrayLogical.h>
[805]21#include <casa/Utilities/Regex.h>
22
23#include <casa/Containers/RecordField.h>
24
25#include <tables/Tables/TableRow.h>
26
[2]27#include <atnf/PKSIO/PKSreader.h>
[1387]28#include <casa/System/ProgressMeter.h>
[125]29
[1387]30
[835]31#include "STDefs.h"
[878]32#include "STAttr.h"
[2]33
[805]34#include "STFiller.h"
[901]35#include "STHeader.h"
[805]36
[125]37using namespace casa;
[2]38
[805]39namespace asap {
40
41STFiller::STFiller() :
[2]42 reader_(0),
[405]43 header_(0),
[805]44 table_(0)
[420]45{
[2]46}
[805]47
48STFiller::STFiller( CountedPtr< Scantable > stbl ) :
[46]49 reader_(0),
[405]50 header_(0),
[805]51 table_(stbl)
[420]52{
[46]53}
[2]54
[855]55STFiller::STFiller(const std::string& filename, int whichIF, int whichBeam ) :
[2]56 reader_(0),
[405]57 header_(0),
[805]58 table_(0)
[420]59{
[805]60 open(filename, whichIF, whichBeam);
[2]61}
62
[805]63STFiller::~STFiller()
64{
65 close();
[2]66}
67
[855]68void STFiller::open( const std::string& filename, int whichIF, int whichBeam )
[805]69{
[846]70 if (table_.null()) {
71 table_ = new Scantable();
72 }
[805]73 if (reader_) { delete reader_; reader_ = 0; }
74 Bool haveBase, haveSpectra;
[2]75
76 String inName(filename);
[284]77 Path path(inName);
78 inName = path.expandedName();
[405]79
[290]80 File file(inName);
[805]81 if ( !file.exists() ) {
[290]82 throw(AipsError("File does not exist"));
83 }
[87]84 filename_ = inName;
[332]85
[405]86 // Create reader and fill in values for arguments
[2]87 String format;
[1060]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 ) {
[405]93 throw(AipsError("Creation of PKSreader failed"));
[2]94 }
95 if (!haveSpectra) {
96 delete reader_;
97 reader_ = 0;
[87]98 throw(AipsError("No spectral data in file."));
[2]99 return;
100 }
101 nBeam_ = beams.nelements();
[1060]102 nIF_ = ifs.nelements();
[2]103 // Get basic parameters.
[1060]104 if ( anyEQ(haveXPol_, True) ) {
[717]105 pushLog("Cross polarization present");
[1060]106 for (uInt i=0; i< npols.nelements();++i) {
107 if (npols[i] < 3) npols[i] += 2;// Convert Complex -> 2 Floats
108 }
[110]109 }
[405]110 if (header_) delete header_;
[901]111 header_ = new STHeader();
[1060]112 header_->nchan = max(nchans);
113 header_->npol = max(npols);
[405]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,
[1387]121 header_->bandwidth,
122 header_->fluxunit);
[405]123
[2]124 if (status) {
125 delete reader_;
126 reader_ = 0;
[805]127 delete header_;
128 header_ = 0;
[87]129 throw(AipsError("Failed to get header."));
[2]130 }
[405]131 if ((header_->obstype).matches("*SW*")) {
[2]132 // need robust way here - probably read ahead of next timestamp
[717]133 pushLog("Header indicates frequency switched observation.\n"
[754]134 "setting # of IFs = 1 ");
[2]135 nIF_ = 1;
[805]136 header_->obstype = String("fswitch");
[2]137 }
[405]138 // Determine Telescope and set brightness unit
[342]139
[1387]140
[342]141 Bool throwIt = False;
[878]142 Instrument inst = STAttr::convertInstrument(header_->antennaname, throwIt);
[1387]143 //header_->fluxunit = "Jy";
[342]144 if (inst==ATMOPRA || inst==TIDBINBILLA) {
[405]145 header_->fluxunit = "K";
[342]146 }
[1188]147 STAttr stattr;
148 header_->poltype = stattr.feedPolType(inst);
[405]149 header_->nif = nIF_;
150 header_->epoch = "UTC";
[805]151 // *** header_->frequnit = "Hz"
[2]152 // Apply selection criteria.
153 Vector<Int> ref;
[332]154 ifOffset_ = 0;
155 if (whichIF>=0) {
156 if (whichIF>=0 && whichIF<nIF_) {
[1060]157 ifs = False;
158 ifs(whichIF) = True;
[805]159 header_->nif = 1;
160 nIF_ = 1;
161 ifOffset_ = whichIF;
[332]162 } else {
[805]163 delete reader_;
164 reader_ = 0;
165 delete header_;
166 header_ = 0;
167 throw(AipsError("Illegal IF selection"));
[332]168 }
169 }
170 beamOffset_ = 0;
171 if (whichBeam>=0) {
[805]172 if (whichBeam>=0 && whichBeam<nBeam_) {
[1060]173 beams = False;
174 beams(whichBeam) = True;
[805]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 }
[332]185 }
186 Vector<Int> start(nIF_, 1);
187 Vector<Int> end(nIF_, 0);
[1060]188 reader_->select(beams, ifs, start, end, ref, True, haveXPol_[0], False);
[846]189 table_->setHeader(*header_);
[1387]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
[805]208}
[405]209
[805]210void STFiller::close( )
211{
212 delete reader_;reader_=0;
213 delete header_;header_=0;
214 table_ = 0;
[2]215}
216
[805]217int asap::STFiller::read( )
218{
[87]219 int status = 0;
220
[17]221 Int beamNo, IFno, refBeam, scanNo, cycleNo;
[87]222 Float azimuth, elevation, focusAxi, focusRot, focusTan,
[2]223 humidity, parAngle, pressure, temperature, windAz, windSpeed;
[73]224 Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
[1072]225 String fieldName, srcName, tcalTime, obsType;
[2]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;
[1387]233 Double min = 0.0;
234 Double max = nInDataRow;
235 ProgressMeter fillpm(min, max, "Data importing progress");
236 int n = 0;
[805]237 while ( status == 0 ) {
238 status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
[1072]239 srcName, srcDir, srcPM, srcVel, obsType, IFno,
240 refFreq, bandwidth, freqInc, restFreq, tcal, tcalTime,
[805]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;
[1387]248 n += 1;
249
[1081]250 Regex filterrx(".*[SL|PA]$");
[1110]251 Regex obsrx("^AT.+");
252 if ( header_->antennaname.matches(obsrx) && obsType.matches(filterrx)) {
253 //cerr << "ignoring paddle scan" << endl;
[1081]254 continue;
255 }
[805]256 TableRow row(table_->table());
257 TableRecord& rec = row.record();
[999]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
[972]268 RecordFieldPtr<Int> fitCol(rec, "FIT_ID");
269 *fitCol = -1;
[805]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");
[1387]280 RecordFieldPtr<String> fieldnCol(rec, "FIELDNAME");
281 *fieldnCol = fieldName;
[805]282 // try to auto-identify if it is on or off.
[922]283 Regex rx(".*[e|w|_R]$");
[942]284 Regex rx2("_S$");
[805]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;
[25]307
[805]308 id = table_->molecules().addEntry(restFreq);
309 RecordFieldPtr<uInt> molidCol(rec, "MOLECULE_ID");
310 *molidCol = id;
[414]311
[805]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;
[922]324 RecordFieldPtr<Float> azCol(rec, "AZIMUTH");
[805]325 *azCol = azimuth;
[922]326 RecordFieldPtr<Float> elCol(rec, "ELEVATION");
[805]327 *elCol = elevation;
[405]328
[805]329 RecordFieldPtr<Float> parCol(rec, "PARANGLE");
330 *parCol = parAngle;
[332]331
[805]332 RecordFieldPtr< Array<Float> > specCol(rec, "SPECTRA");
333 RecordFieldPtr< Array<uChar> > flagCol(rec, "FLAGTRA");
334 RecordFieldPtr< uInt > polnoCol(rec, "POLNO");
[405]335
[805]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;
[405]346
[805]347 *specCol = spectra.column(i);
348 *flagCol = flagtra.column(i);
349 table_->table().addRow();
350 row.put(table_->table().nrow()-1, rec);
[2]351 }
[1060]352 if ( haveXPol_[0] ) {
[805]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);
[2]371 }
[1387]372 fillpm._update(n);
[805]373 }
374 if (status > 0) {
375 close();
376 throw(AipsError("Reading error occured, data possibly corrupted."));
377 }
[1387]378 fillpm.done();
[2]379 return status;
380}
[805]381
382}//namespace asap
Note: See TracBrowser for help on using the repository browser.