source: trunk/src/SDReader.cc@ 465

Last change on this file since 465 was 420, checked in by kil064, 20 years ago

handle cross polarization

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
RevLine 
[2]1//#---------------------------------------------------------------------------
2//# SDReader.cc: A class to read single dish spectra from SDFITS, RPFITS
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2004
[125]5//# ATNF
[2]6//#
7//# This program is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU General Public License as published by the Free
9//# Software Foundation; either version 2 of the License, or (at your option)
10//# any later version.
11//#
12//# This program is distributed in the hope that it will be useful, but
13//# WITHOUT ANY WARRANTY; without even the implied warranty of
14//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15//# Public License for more details.
16//#
17//# You should have received a copy of the GNU General Public License along
18//# with this program; if not, write to the Free Software Foundation, Inc.,
19//# 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning this software should be addressed as follows:
22//# Internet email: Malte.Marquarding@csiro.au
23//# Postal address: Malte Marquarding,
24//# Australia Telescope National Facility,
25//# P.O. Box 76,
26//# Epping, NSW, 2121,
27//# AUSTRALIA
28//#
29//# $Id:
30//#---------------------------------------------------------------------------
[404]31#include <casa/iostream.h>
32#include <casa/iomanip.h>
33
[125]34#include <casa/Exceptions.h>
[284]35#include <casa/OS/Path.h>
[290]36#include <casa/OS/File.h>
[338]37#include <casa/Quanta/Unit.h>
[2]38#include <atnf/PKSIO/PKSreader.h>
[125]39
[2]40#include "SDReader.h"
[337]41#include "SDDefs.h"
[2]42
[125]43using namespace casa;
[83]44using namespace asap;
[2]45
46SDReader::SDReader() :
47 reader_(0),
[405]48 header_(0),
49 frequencies_(0),
[420]50 table_(new SDMemTable()),
51 haveXPol_(False)
52{
[2]53 cursor_ = 0;
54}
[342]55SDReader::SDReader(const std::string& filename,
[338]56 int whichIF, int whichBeam) :
[46]57 reader_(0),
[405]58 header_(0),
59 frequencies_(0),
[420]60 table_(new SDMemTable()),
61 haveXPol_(False)
62{
[46]63 cursor_ = 0;
[342]64 open(filename, whichIF, whichBeam);
[46]65}
[2]66
67SDReader::SDReader(CountedPtr<SDMemTable> tbl) :
68 reader_(0),
[405]69 header_(0),
[420]70 table_(tbl),
71 haveXPol_(False)
72{
[2]73 cursor_ = 0;
74}
75
76SDReader::~SDReader() {
[405]77 if (reader_) delete reader_;
78 if (header_) delete header_;
79 if (frequencies_) delete frequencies_;
[2]80}
81
82void SDReader::reset() {
[46]83 cursor_ = 0;
[87]84 table_ = new SDMemTable();
[405]85 open(filename_,ifOffset_, beamOffset_);
[2]86}
87
[332]88
[46]89void SDReader::close() {
90 cerr << "disabled" << endl;
91}
92
[342]93void SDReader::open(const std::string& filename,
[338]94 int whichIF, int whichBeam) {
[2]95 if (reader_) delete reader_; reader_ = 0;
[420]96 Bool haveBase, haveSpectra;
[405]97
[2]98 String inName(filename);
[284]99 Path path(inName);
100 inName = path.expandedName();
[405]101
[290]102 File file(inName);
103 if (!file.exists()) {
104 throw(AipsError("File does not exist"));
105 }
[87]106 filename_ = inName;
[332]107
[405]108 // Create reader and fill in values for arguments
[2]109 String format;
110 Vector<Bool> beams;
111 if ((reader_ = getPKSreader(inName, 0, False, format, beams, nIF_,
112 nChan_, nPol_, haveBase, haveSpectra,
[420]113 haveXPol_)) == 0) {
[405]114 throw(AipsError("Creation of PKSreader failed"));
[2]115 }
116 if (!haveSpectra) {
117 delete reader_;
118 reader_ = 0;
[87]119 throw(AipsError("No spectral data in file."));
[2]120 return;
121 }
[405]122
[2]123 nBeam_ = beams.nelements();
124 // Get basic parameters.
[420]125 if (haveXPol_) {
126 cout << "Cross polarization present" << endl;
127 nPol_ += 2; // Convert Complex -> 2 Floats
[110]128 }
[420]129
[405]130 if (header_) delete header_;
131 header_ = new SDHeader();
132 header_->nchan = nChan_;
133 header_->npol = nPol_;
134 header_->nbeam = nBeam_;
135
136 Int status = reader_->getHeader(header_->observer, header_->project,
137 header_->antennaname, header_->antennaposition,
138 header_->obstype,header_->equinox,
139 header_->freqref,
140 header_->utc, header_->reffreq,
141 header_->bandwidth);
142
[2]143 if (status) {
144 delete reader_;
145 reader_ = 0;
[87]146 throw(AipsError("Failed to get header."));
[2]147 return;
148 }
[405]149 if ((header_->obstype).matches("*SW*")) {
[2]150 // need robust way here - probably read ahead of next timestamp
151 cout << "Header indicates frequency switched observation.\n"
152 "setting # of IFs = 1 " << endl;
153 nIF_ = 1;
154 }
[337]155
[405]156 // Determine Telescope and set brightness unit
[342]157
158 Bool throwIt = False;
[405]159 Instrument inst = SDMemTable::convertInstrument(header_->antennaname,
160 throwIt);
161 header_->fluxunit = "Jy";
[342]162 if (inst==ATMOPRA || inst==TIDBINBILLA) {
[405]163 header_->fluxunit = "K";
[342]164 }
[332]165
[405]166 header_->nif = nIF_;
167 header_->epoch = "UTC";
168
[2]169 // Apply selection criteria.
[332]170
[2]171 Vector<Int> ref;
172 Vector<Bool> beamSel(nBeam_,True);
173 Vector<Bool> IFsel(nIF_,True);
[405]174
[332]175 ifOffset_ = 0;
176 if (whichIF>=0) {
177 if (whichIF>=0 && whichIF<nIF_) {
178 IFsel = False;
179 IFsel(whichIF) = True;
[405]180 header_->nif = 1;
[332]181 nIF_ = 1;
182 ifOffset_ = whichIF;
183 } else {
184 throw(AipsError("Illegal IF selection"));
185 }
186 }
[405]187
[332]188 beamOffset_ = 0;
189 if (whichBeam>=0) {
190 if (whichBeam>=0 && whichBeam<nBeam_) {
191 beamSel = False;
192 beamSel(whichBeam) = True;
[405]193 header_->nbeam = 1;
[332]194 nBeam_ = 1;
195 beamOffset_ = whichBeam;
196 } else {
197 throw(AipsError("Illegal Beam selection"));
198 }
199 }
200 Vector<Int> start(nIF_, 1);
201 Vector<Int> end(nIF_, 0);
[420]202 reader_->select(beamSel, IFsel, start, end, ref, True, haveXPol_);
[405]203 table_->putSDHeader(*header_);
204
205 if (frequencies_) delete frequencies_;
206 frequencies_ = new SDFrequencyTable();
207 frequencies_->setRefFrame(header_->freqref);
208 frequencies_->setRestFrequencyUnit("Hz");
209 frequencies_->setEquinox(header_->equinox);
[2]210}
211
212int SDReader::read(const std::vector<int>& seq) {
[87]213 int status = 0;
214
[17]215 Int beamNo, IFno, refBeam, scanNo, cycleNo;
[87]216 Float azimuth, elevation, focusAxi, focusRot, focusTan,
[2]217 humidity, parAngle, pressure, temperature, windAz, windSpeed;
[73]218 Double bandwidth, freqInc, interval, mjd, refFreq, restFreq, srcVel;
[2]219 String fieldName, srcName, tcalTime;
220 Vector<Float> calFctr, sigma, tcal, tsys;
221 Matrix<Float> baseLin, baseSub;
222 Vector<Double> direction(2), scanRate(2), srcDir(2), srcPM(2);
223 Matrix<Float> spectra;
224 Matrix<uChar> flagtra;
225 Complex xCalFctr;
226 Vector<Complex> xPol;
227 uInt n = seq.size();
[25]228
[414]229
[405]230 uInt stepsize = header_->nif*header_->nbeam;
[2]231 uInt seqi = 0;
232 Bool getAll = False;
[405]233
[2]234 if (seq[n-1] == -1) getAll = True;
235 while ( (cursor_ <= seq[n-1]) || getAll) {
236 // only needs to be create if in seq
[405]237 SDContainer sc(header_->nbeam,header_->nif,header_->npol,header_->nchan);
[2]238 // iterate over one correlator integration cycle = nBeam*nIF
239 for (uInt row=0; row < stepsize; row++) {
240 // stepsize as well
241 // spectra(nChan,nPol)!!!
[87]242 status = reader_->read(scanNo, cycleNo, mjd, interval, fieldName,
243 srcName, srcDir, srcPM, srcVel, IFno, refFreq,
244 bandwidth, freqInc, restFreq, tcal, tcalTime,
245 azimuth, elevation, parAngle, focusAxi,
246 focusTan, focusRot, temperature, pressure,
247 humidity, windSpeed, windAz, refBeam,
248 beamNo, direction, scanRate,
249 tsys, sigma, calFctr, baseLin, baseSub,
250 spectra, flagtra, xCalFctr, xPol);
[332]251
[405]252 // Make sure beam/IF numbers are 0-relative - dealing with
253 // possible IF or Beam selection
[332]254 beamNo = beamNo - beamOffset_ - 1;
255 IFno = IFno - ifOffset_ - 1;
[405]256
[2]257 if (status) {
[87]258 if (status == -1) {
259 // EOF.
[205]260 if (row > 0 && row < stepsize-1)
261 cerr << "incomplete scan data.\n Probably means not all Beams/IFs/Pols within a scan are present." << endl;
[405]262
263 // flush frequency table
264 table_->putSDFreqTable(*frequencies_);
[87]265 return status;
266 }
267 }
[2]268 // if in the given list
[33]269 if (cursor_ == seq[seqi] || getAll) {
[87]270 // add integration cycle
271 if (row==0) {
272 //add invariant info: scanNo, mjd, interval, fieldName,
273 //srcName, azimuth, elevation, parAngle, focusAxi, focusTan,
274 //focusRot, temperature, pressure, humidity, windSpeed,
275 //windAz srcDir, srcPM, srcVel
276 sc.timestamp = mjd;
277 sc.interval = interval;
278 sc.sourcename = srcName;
[110]279 sc.fieldname = fieldName;
280 sc.azimuth = azimuth;
281 sc.elevation = elevation;
[87]282 }
283 // add specific info
[404]284 // refPix = nChan/2+1 in 1-rel Integer arith.!
[405]285 Int refPix = header_->nchan/2; // 0-rel
286 uInt freqID = frequencies_->addFrequency(refPix, refFreq, freqInc);
287 uInt restFreqID = frequencies_->addRestFrequency(restFreq);
288
[390]289 sc.setFrequencyMap(freqID, IFno);
290 sc.setRestFrequencyMap(restFreqID, IFno);
[405]291
[110]292 sc.tcal[0] = tcal[0];sc.tcal[1] = tcal[1];
293 sc.tcaltime = tcalTime;
294 sc.parangle = parAngle;
[374]295 sc.refbeam = refBeam-1;//make it 0-based; -1 if nbeams == 1
[87]296 sc.scanid = scanNo-1;//make it 0-based
[420]297 if (haveXPol_) {
298 sc.setSpectrum(spectra, xPol, beamNo, IFno);
299 sc.setFlags(flagtra, beamNo, IFno, True);
300 } else {
301 sc.setSpectrum(spectra, beamNo, IFno);
302 sc.setFlags(flagtra, beamNo, IFno, False);
303 }
304 sc.setTsys(tsys, beamNo, IFno, haveXPol_);
[332]305 sc.setDirection(direction, beamNo);
[2]306 }
307 }
[404]308
[33]309 if (cursor_ == seq[seqi] || getAll) {
[2]310 // insert container into table/list
311 table_->putSDContainer(sc);
312 seqi++;// next in list
313 }
[16]314 cursor_++;// increment position in file
[404]315
[2]316 }
[405]317 table_->putSDFreqTable(*frequencies_);
[2]318 return status;
319}
Note: See TracBrowser for help on using the repository browser.