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

Last change on this file since 1427 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.