source: trunk/external/atnf/PKSIO/PKSSDwriter.cc@ 1402

Last change on this file since 1402 was 1399, checked in by Malte Marquarding, 17 years ago

Mark C added brightness unit to getHeader()

File size: 10.0 KB
Line 
1//#---------------------------------------------------------------------------
2//# PKSSDwriter.cc: Class to write Parkes multibeam data to an SDFITS file.
3//#---------------------------------------------------------------------------
4//# Copyright (C) 2000-2007
5//# Associated Universities, Inc. Washington DC, USA.
6//#
7//# This library is free software; you can redistribute it and/or modify it
8//# under the terms of the GNU Library General Public License as published by
9//# the Free Software Foundation; either version 2 of the License, or (at your
10//# option) any later version.
11//#
12//# This library is distributed in the hope that it will be useful, but
13//# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14//# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
15//# License for more details.
16//#
17//# You should have received a copy of the GNU Library General Public License
18//# along with this library; if not, write to the Free Software Foundation,
19//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
20//#
21//# Correspondence concerning AIPS++ should be addressed as follows:
22//# Internet email: aips2-request@nrao.edu.
23//# Postal address: AIPS++ Project Office
24//# National Radio Astronomy Observatory
25//# 520 Edgemont Road
26//# Charlottesville, VA 22903-2475 USA
27//#
28//# $Id: PKSSDwriter.cc,v 19.13 2007/11/12 03:37:56 cal103 Exp $
29//#---------------------------------------------------------------------------
30
31#include <atnf/PKSIO/PKSMBrecord.h>
32#include <atnf/PKSIO/PKSSDwriter.h>
33
34#include <casa/Quanta/MVTime.h>
35
36
37//--------------------------------------------------- PKSSDwriter::PKSSDwriter
38
39// Default constructor.
40
41PKSSDwriter::PKSSDwriter()
42{
43}
44
45//-------------------------------------------------- PKSSDwriter::~PKSSDwriter
46
47// Destructor.
48
49PKSSDwriter::~PKSSDwriter()
50{
51 close();
52}
53
54//-------------------------------------------------------- PKSSDwriter::create
55
56// Create the SDFITS file and and write static data.
57
58Int PKSSDwriter::create(
59 const String sdName,
60 const String observer,
61 const String project,
62 const String antName,
63 const Vector<Double> antPosition,
64 const String obsMode,
65 const String bunit,
66 const Float equinox,
67 const String dopplerFrame,
68 const Vector<uInt> nChan,
69 const Vector<uInt> nPol,
70 const Vector<Bool> haveXPol,
71 const Bool haveBase)
72{
73 double antPos[3];
74 antPos[0] = antPosition(0);
75 antPos[1] = antPosition(1);
76 antPos[2] = antPosition(2);
77
78 cNIF = nChan.nelements();
79 if (nPol.nelements() != cNIF || haveXPol.nelements() != cNIF) {
80 cerr << "PKSSDwriter::create: "
81 << "Inconsistent number of IFs for nChan, nPol, and/or haveXPol."
82 << endl;
83 return 1;
84 }
85
86 cNChan.assign(nChan);
87 cNPol.assign(nPol);
88
89 cHaveXPol.resize(cNIF);
90 for (uInt iIF = 0; iIF < cNIF; iIF++) {
91 // Convert Bool -> uInt.
92 cHaveXPol(iIF) = haveXPol(iIF) ? 1 : 0;
93 }
94
95 cHaveBase = haveBase;
96
97 // Storage in the trivial cNChan, cNPol, and cHaveXPol arrays should always
98 // be contiguous so the pointer returned by getStorage() shouldn't need to
99 // be deleted via freeStorage() (i.e. deleteIt always returned False). This
100 // storage will, of course, be deleted when the PKSwriter object is deleted.
101 Bool deleteIt;
102 Int status = cSDwriter.create((char *)sdName.chars(),
103 (char *)observer.chars(), (char *)project.chars(),
104 (char *)antName.chars(), antPos, (char *)obsMode.chars(),
105 (char *)bunit.chars(), equinox, (char *)dopplerFrame.chars(), cNIF,
106 (int *)cNChan.getStorage(deleteIt),
107 (int *)cNPol.getStorage(deleteIt),
108 (int *)cHaveXPol.getStorage(deleteIt), (int)cHaveBase, 1);
109 if (status) {
110 cSDwriter.reportError();
111 cSDwriter.deleteFile();
112 close();
113 }
114
115 return status;
116}
117
118//--------------------------------------------------------- PKSSDwriter::write
119
120// Write the next data record.
121
122Int PKSSDwriter::write(
123 const Int scanNo,
124 const Int cycleNo,
125 const Double mjd,
126 const Double interval,
127 const String fieldName,
128 const String srcName,
129 const Vector<Double> srcDir,
130 const Vector<Double> srcPM,
131 const Double srcVel,
132 const String obsMode,
133 const Int IFno,
134 const Double refFreq,
135 const Double bandwidth,
136 const Double freqInc,
137 const Double restFreq,
138 const Vector<Float> tcal,
139 const String tcalTime,
140 const Float azimuth,
141 const Float elevation,
142 const Float parAngle,
143 const Float focusAxi,
144 const Float focusTan,
145 const Float focusRot,
146 const Float temperature,
147 const Float pressure,
148 const Float humidity,
149 const Float windSpeed,
150 const Float windAz,
151 const Int refBeam,
152 const Int beamNo,
153 const Vector<Double> direction,
154 const Vector<Double> scanRate,
155 const Vector<Float> tsys,
156 const Vector<Float> sigma,
157 const Vector<Float> calFctr,
158 const Matrix<Float> baseLin,
159 const Matrix<Float> baseSub,
160 const Matrix<Float> &spectra,
161 const Matrix<uChar> &flagged,
162 const Complex xCalFctr,
163 const Vector<Complex> &xPol)
164{
165 // Do basic checks.
166 uInt iIF = IFno - 1;
167 if (IFno < 1 || Int(cNIF) < IFno) {
168 cerr << "PKSDwriter::write: "
169 << "Invalid IF number " << IFno
170 << " (maximum " << cNIF << ")." << endl;
171 return 1;
172 }
173
174 uInt nChan = spectra.nrow();
175 if (nChan != cNChan(iIF)) {
176 cerr << "PKSDwriter::write: "
177 << "Wrong number of channels for IF " << IFno << "," << endl
178 << " "
179 << "got " << nChan << " should be " << cNChan(iIF) << "." << endl;
180 return 1;
181 }
182
183 uInt nPol = spectra.ncolumn();
184 if (nPol != cNPol(iIF)) {
185 cerr << "PKSDwriter::write: "
186 << "Wrong number of polarizations for IF " << IFno << "," << endl
187 << " "
188 << "got " << nPol << " should be " << cNPol(iIF) << "." << endl;
189 return 1;
190 }
191
192 // Extract calendar information from mjd.
193 MVTime time(mjd);
194 Int year = time.year();
195 Int month = time.month();
196 Int day = time.monthday();
197
198 // Transfer data to a single-IF PKSMBrecord.
199 PKSMBrecord mbrec(1);
200
201 // Start with basic beam- and IF-independent bookkeeping information.
202 mbrec.scanNo = scanNo;
203 mbrec.cycleNo = cycleNo;
204
205 sprintf(mbrec.datobs, "%4.4d-%2.2d-%2.2d", year, month, day);
206 mbrec.utc = fmod(mjd, 1.0) * 86400.0;
207 mbrec.exposure = float(interval);
208
209 strncpy(mbrec.srcName, (char *)srcName.chars(), 17);
210 mbrec.srcRA = srcDir(0);
211 mbrec.srcDec = srcDir(1);
212
213 mbrec.restFreq = restFreq;
214
215 strncpy(mbrec.obsType, (char *)obsMode.chars(), 16);
216
217 // Now beam-dependent parameters.
218 mbrec.beamNo = beamNo;
219 mbrec.ra = direction(0);
220 mbrec.dec = direction(1);
221 mbrec.raRate = scanRate(0);
222 mbrec.decRate = scanRate(1);
223
224 // Now IF-dependent parameters.
225 mbrec.nIF = 1;
226 mbrec.IFno[0] = IFno;
227 mbrec.nChan[0] = nChan;
228 mbrec.nPol[0] = nPol;
229
230 mbrec.fqRefPix[0] = (nChan/2) + 1;
231 mbrec.fqRefVal[0] = refFreq;
232 mbrec.fqDelt[0] = freqInc;
233
234 // Now the data itself.
235 for (uInt i = 0; i < tsys.nelements(); i++) {
236 mbrec.tsys[0][i] = tsys(i);
237 }
238
239 for (uInt ipol = 0; ipol < nPol; ipol++) {
240 mbrec.calfctr[0][ipol] = calFctr(ipol);
241 }
242
243 if (cHaveXPol(iIF)) {
244 mbrec.xcalfctr[0][0] = xCalFctr.real();
245 mbrec.xcalfctr[0][1] = xCalFctr.imag();
246 } else {
247 mbrec.xcalfctr[0][0] = 0.0f;
248 mbrec.xcalfctr[0][1] = 0.0f;
249 }
250
251 if (cHaveBase) {
252 mbrec.haveBase = 1;
253
254 for (uInt ipol = 0; ipol < nPol; ipol++) {
255 mbrec.baseLin[0][ipol][0] = baseLin(0,ipol);
256 mbrec.baseLin[0][ipol][1] = baseLin(1,ipol);
257
258 for (uInt j = 0; j < baseSub.nrow(); j++) {
259 mbrec.baseSub[0][ipol][j] = baseSub(j,ipol);
260 }
261 for (uInt j = baseSub.nrow(); j < 9; j++) {
262 mbrec.baseSub[0][ipol][j] = 0.0f;
263 }
264 }
265
266 } else {
267 mbrec.haveBase = 0;
268 }
269
270 Bool delSpectra = False;
271 const Float *specstor = spectra.getStorage(delSpectra);
272 mbrec.spectra[0] = (float *)specstor;
273
274 Bool delFlagged = False;
275 const uChar *flagstor = flagged.getStorage(delFlagged);
276 mbrec.flagged[0] = (unsigned char *)flagstor;
277
278 Bool delXPol = False;
279 const Complex *xpolstor;
280 if (cHaveXPol(iIF)) {
281 xpolstor = xPol.getStorage(delXPol);
282 } else {
283 xpolstor = 0;
284 }
285 mbrec.xpol[0] = (float *)xpolstor;
286
287 // Finish off with system calibration parameters.
288 mbrec.extraSysCal = 1;
289 mbrec.refBeam = refBeam;
290 for (uInt i = 0; i < tcal.nelements(); i++) {
291 mbrec.tcal[0][i] = tcal(i);
292 }
293 strncpy(mbrec.tcalTime, (char *)tcalTime.chars(), 16);
294 mbrec.azimuth = azimuth;
295 mbrec.elevation = elevation;
296 mbrec.parAngle = parAngle;
297 mbrec.focusAxi = focusAxi;
298 mbrec.focusTan = focusTan;
299 mbrec.focusRot = focusRot;
300 mbrec.temp = temperature;
301 mbrec.pressure = pressure;
302 mbrec.humidity = humidity;
303 mbrec.windSpeed = windSpeed;
304 mbrec.windAz = windAz;
305
306 Int status = cSDwriter.write(mbrec);
307 if (status) {
308 cSDwriter.reportError();
309 status = 1;
310 }
311
312 spectra.freeStorage(specstor, delSpectra);
313 flagged.freeStorage(flagstor, delFlagged);
314 xPol.freeStorage(xpolstor, delXPol);
315
316 return status;
317}
318
319//------------------------------------------------------- PKSSDwriter::history
320
321// Write a history record.
322
323Int PKSSDwriter::history(const String text)
324{
325 return cSDwriter.history((char *)text.chars());
326}
327
328Int PKSSDwriter::history(const char *text)
329{
330 return cSDwriter.history((char *)text);
331}
332
333//--------------------------------------------------------- PKSSDwriter::close
334
335// Close the SDFITS file.
336
337void PKSSDwriter::close()
338{
339 cSDwriter.close();
340}
Note: See TracBrowser for help on using the repository browser.