source: branches/casa-release-4_3-test02/external-alma/atnf/PKSIO/PKSMS2writer.cc@ 3056

Last change on this file since 3056 was 1941, checked in by Takeshi Nakazato, 14 years ago

New Development: Yes/No

JIRA Issue: No/Yes List JIRA ticket.

Ready for Test: Yes/No

Interface Changes: Yes/No

What Interface Changed: Please list interface changes

Test Programs: List test programs

Put in Release Notes: Yes/No

Module(s): Module Names change impacts.

Description: Describe your changes here...

Merged bug fix on PKSMS2writer (external-alma@asap4casa3.1.0) to trunk.


File size: 38.9 KB
Line 
1//#---------------------------------------------------------------------------
2//# PKSMS2writer.cc: Class to write Parkes multibeam data to a measurementset.
3//#---------------------------------------------------------------------------
4//# livedata - processing pipeline for single-dish, multibeam spectral data.
5//# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO
6//#
7//# This file is part of livedata.
8//#
9//# livedata is free software: you can redistribute it and/or modify it under
10//# the terms of the GNU General Public License as published by the Free
11//# Software Foundation, either version 3 of the License, or (at your option)
12//# any later version.
13//#
14//# livedata is distributed in the hope that it will be useful, but WITHOUT
15//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16//# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17//# more details.
18//#
19//# You should have received a copy of the GNU General Public License along
20//# with livedata. If not, see <http://www.gnu.org/licenses/>.
21//#
22//# Correspondence concerning livedata may be directed to:
23//# Internet email: mcalabre@atnf.csiro.au
24//# Postal address: Dr. Mark Calabretta
25//# Australia Telescope National Facility, CSIRO
26//# PO Box 76
27//# Epping NSW 1710
28//# AUSTRALIA
29//#
30//# http://www.atnf.csiro.au/computing/software/livedata.html
31//# $Id: PKSMS2writer.cc,v 19.16 2009-09-29 07:33:38 cal103 Exp $
32//#---------------------------------------------------------------------------
33
34#include <atnf/PKSIO/PKSrecord.h>
35#include <atnf/PKSIO/PKSMS2writer.h>
36
37#include <casa/Arrays/ArrayUtil.h>
38#include <casa/Arrays/ArrayMath.h>
39#include <casa/Arrays/ArrayLogical.h>
40#include <casa/Arrays/Cube.h>
41#include <casa/BasicSL/Complex.h>
42#include <casa/BasicSL/Constants.h>
43#include <casa/Quanta/QC.h>
44#include <casa/Logging/LogIO.h>
45#include <measures/Measures/Stokes.h>
46#include <tables/Tables/ArrColDesc.h>
47#include <tables/Tables/IncrementalStMan.h>
48#include <tables/Tables/ScaColDesc.h>
49#include <tables/Tables/SetupNewTab.h>
50#include <tables/Tables/StandardStMan.h>
51#include <tables/Tables/Table.h>
52#include <tables/Tables/TableDesc.h>
53#include <tables/Tables/TiledShapeStMan.h>
54
55// Class name
56const string className = "PKSMS2writer" ;
57
58//------------------------------------------------- PKSMS2writer::PKSMS2writer
59
60// Default constructor.
61
62PKSMS2writer::PKSMS2writer()
63{
64 cPKSMS = 0x0;
65}
66
67//------------------------------------------------ PKSMS2writer::~PKSMS2writer
68
69// Destructor.
70
71PKSMS2writer::~PKSMS2writer()
72{
73 close();
74}
75
76//------------------------------------------------------- PKSMS2writer::create
77
78// Create the output MS and and write static data.
79
80Int PKSMS2writer::create(
81 const String msName,
82 const String observer,
83 const String project,
84 const String antName,
85 const Vector<Double> antPosition,
86 const String obsMode,
87 const String bunit,
88 const Float equinox,
89 const String dopplerFrame,
90 const Vector<uInt> nChan,
91 const Vector<uInt> nPol,
92 const Vector<Bool> haveXPol,
93 const Bool haveBase)
94{
95 const string methodName = "create()" ;
96 LogIO os( LogOrigin( className, methodName, WHERE ) ) ;
97
98 if (cPKSMS) {
99 os << LogIO::SEVERE << "Output MS already open, close it first." << LogIO::POST ;
100 return 1;
101 }
102
103 // Open a MS table.
104 TableDesc pksDesc = MS::requiredTableDesc();
105
106 cNChan.assign(nChan);
107 cNPol.assign(nPol);
108 cHaveXPol.assign(haveXPol);
109
110 Int maxNPol = max(cNPol);
111 cGBT = cAPEX = cSMT = cALMA = cATF = False;
112
113 String telName = antName;
114 // check if it is GBT data
115 if (antName.contains("GBT")) {
116 cGBT = True;
117 }
118 else if (antName.contains("APEX")) {
119 cAPEX = True;
120 }
121 else if (antName.contains("HHT") || antName.contains("SMT")) {
122 cSMT = True;
123 }
124 else if (antName.contains("ALMA")) {
125 cALMA = True;
126 }
127 else if (antName.contains("ATF")) {
128 cATF = True;
129 telName="ATF";
130 }
131
132 // Add the non-standard CALFCTR column.
133 pksDesc.addColumn(ArrayColumnDesc<Float>("CALFCTR", "Calibration factors",
134 IPosition(1,maxNPol), ColumnDesc::Direct));
135
136 // Add the optional FLOAT_DATA column.
137 MS::addColumnToDesc(pksDesc, MS::FLOAT_DATA, 2);
138 //pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet().
139 // define("UNIT", String("Jy"));
140 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet().
141 define("UNIT", bunit);
142 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet().
143 define("MEASURE_TYPE", "");
144
145 if ((cHaveBase = haveBase)) {
146 // Add the non-standard BASELIN and BASESUB columns.
147 pksDesc.addColumn(ArrayColumnDesc<Float>("BASELIN", "Linear baseline fit",
148 IPosition(2,2,maxNPol), ColumnDesc::Direct));
149 pksDesc.addColumn(ArrayColumnDesc<Float>("BASESUB", "Baseline subtracted",
150 IPosition(2,24,maxNPol), ColumnDesc::Direct));
151 }
152
153 // Add the optional DATA column if cross-polarizations are to be recorded.
154 if (ntrue(cHaveXPol)) {
155 // Add the non-standard XCALFCTR column.
156 pksDesc.addColumn(ScalarColumnDesc<Complex>("XCALFCTR",
157 "Cross-polarization calibration factor"));
158
159 MS::addColumnToDesc(pksDesc, MS::DATA, 2);
160 //pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet().
161 // define("UNIT", "Jy");
162 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet().
163 define("UNIT", bunit);
164 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet().
165 define("MEASURE_TYPE", "");
166 }
167
168 // Define hypercube for the float data (without coordinates).
169 pksDesc.defineHypercolumn("TiledData", 3,
170 stringToVector(MS::columnName(MS::FLOAT_DATA)));
171
172 SetupNewTable newtab(msName, pksDesc, Table::New);
173
174 // Set Incremental Storage Manager as the default.
175 IncrementalStMan incrStMan("ISMData");
176 newtab.bindAll(incrStMan, True);
177
178 // Use TiledShapeStMan for the FLOAT_DATA hypercube with tile size 1 MB.
179 TiledShapeStMan tiledStMan("TiledData", IPosition(3,1,128,2048));
180 newtab.bindColumn(MS::columnName(MS::FLOAT_DATA), tiledStMan);
181
182 // Use Standard Storage Manager to handle columns that change for each row.
183 StandardStMan stdStMan;
184 newtab.bindColumn(MS::columnName(MS::SCAN_NUMBER), stdStMan);
185 newtab.bindColumn(MS::columnName(MS::TIME), stdStMan);
186 newtab.bindColumn(MS::columnName(MS::SIGMA), stdStMan);
187 if (maxNPol > 2) {
188 newtab.bindColumn(MS::columnName(MS::DATA), stdStMan);
189 }
190
191 // Create the measurementset.
192 cPKSMS = new MeasurementSet(newtab, 0);
193
194 // Create subtables.
195 TableDesc antennaDesc = MSAntenna::requiredTableDesc();
196 SetupNewTable antennaSetup(cPKSMS->antennaTableName(), antennaDesc,
197 Table::New);
198 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::ANTENNA),
199 Table(antennaSetup));
200
201 TableDesc dataDescDesc = MSDataDescription::requiredTableDesc();
202 SetupNewTable dataDescSetup(cPKSMS->dataDescriptionTableName(), dataDescDesc,
203 Table::New);
204 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::DATA_DESCRIPTION),
205 Table(dataDescSetup));
206
207 TableDesc dopplerDesc = MSDoppler::requiredTableDesc();
208 SetupNewTable dopplerSetup(cPKSMS->dopplerTableName(), dopplerDesc,
209 Table::New);
210 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::DOPPLER),
211 Table(dopplerSetup));
212
213 TableDesc feedDesc = MSFeed::requiredTableDesc();
214 MSFeed::addColumnToDesc(feedDesc, MSFeedEnums::FOCUS_LENGTH);
215 SetupNewTable feedSetup(cPKSMS->feedTableName(), feedDesc, Table::New);
216 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::FEED),
217 Table(feedSetup));
218
219 TableDesc fieldDesc = MSField::requiredTableDesc();
220 SetupNewTable fieldSetup(cPKSMS->fieldTableName(), fieldDesc, Table::New);
221 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::FIELD),
222 Table(fieldSetup));
223
224 TableDesc flagCmdDesc = MSFlagCmd::requiredTableDesc();
225 SetupNewTable flagCmdSetup(cPKSMS->flagCmdTableName(), flagCmdDesc,
226 Table::New);
227 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::FLAG_CMD),
228 Table(flagCmdSetup));
229
230 TableDesc historyDesc = MSHistory::requiredTableDesc();
231 SetupNewTable historySetup(cPKSMS->historyTableName(), historyDesc,
232 Table::New);
233 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::HISTORY),
234 Table(historySetup));
235
236 TableDesc observationDesc = MSObservation::requiredTableDesc();
237 SetupNewTable observationSetup(cPKSMS->observationTableName(),
238 observationDesc, Table::New);
239 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::OBSERVATION),
240 Table(observationSetup));
241
242 TableDesc pointingDesc = MSPointing::requiredTableDesc();
243 SetupNewTable pointingSetup(cPKSMS->pointingTableName(), pointingDesc,
244 Table::New);
245 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::POINTING),
246 Table(pointingSetup));
247
248 TableDesc polarizationDesc = MSPolarization::requiredTableDesc();
249 SetupNewTable polarizationSetup(cPKSMS->polarizationTableName(),
250 polarizationDesc, Table::New);
251 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::POLARIZATION),
252 Table(polarizationSetup));
253
254 TableDesc processorDesc = MSProcessor::requiredTableDesc();
255 SetupNewTable processorSetup(cPKSMS->processorTableName(), processorDesc,
256 Table::New);
257 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::PROCESSOR),
258 Table(processorSetup));
259
260 TableDesc sourceDesc = MSSource::requiredTableDesc();
261 MSSource::addColumnToDesc(sourceDesc, MSSourceEnums::TRANSITION, 1);
262 MSSource::addColumnToDesc(sourceDesc, MSSourceEnums::REST_FREQUENCY,
263 1);
264 MSSource::addColumnToDesc(sourceDesc, MSSourceEnums::SYSVEL, 1);
265 SetupNewTable sourceSetup(cPKSMS->sourceTableName(), sourceDesc,
266 Table::New);
267 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::SOURCE),
268 Table(sourceSetup));
269
270 TableDesc spectralWindowDesc = MSSpectralWindow::requiredTableDesc();
271 MSSpectralWindow::addColumnToDesc(spectralWindowDesc,
272 MSSpectralWindowEnums::DOPPLER_ID);
273 SetupNewTable spectralWindowSetup(cPKSMS->spectralWindowTableName(),
274 spectralWindowDesc, Table::New);
275 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::SPECTRAL_WINDOW),
276 Table(spectralWindowSetup));
277
278 TableDesc stateDesc = MSState::requiredTableDesc();
279 SetupNewTable stateSetup(cPKSMS->stateTableName(), stateDesc, Table::New);
280 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::STATE),
281 Table(stateSetup));
282
283 TableDesc sysCalDesc = MSSysCal::requiredTableDesc();
284 MSSysCal::addColumnToDesc(sysCalDesc, MSSysCalEnums::TCAL, 1);
285 MSSysCal::addColumnToDesc(sysCalDesc, MSSysCalEnums::TSYS, 1);
286 SetupNewTable sysCalSetup(cPKSMS->sysCalTableName(), sysCalDesc,
287 Table::New);
288 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::SYSCAL),
289 Table(sysCalSetup));
290
291 TableDesc weatherDesc = MSWeather::requiredTableDesc();
292 MSWeather::addColumnToDesc(weatherDesc, MSWeatherEnums::PRESSURE);
293 MSWeather::addColumnToDesc(weatherDesc, MSWeatherEnums::REL_HUMIDITY);
294 MSWeather::addColumnToDesc(weatherDesc, MSWeatherEnums::TEMPERATURE);
295 SetupNewTable weatherSetup(cPKSMS->weatherTableName(), weatherDesc,
296 Table::New);
297 cPKSMS->rwKeywordSet().defineTable(MS::keywordName(MS::WEATHER),
298 Table(weatherSetup));
299
300 cPKSMS->initRefs();
301
302 // Measurementset subtables.
303 cAntenna = cPKSMS->antenna();
304 cDataDescription = cPKSMS->dataDescription();
305 cDoppler = cPKSMS->doppler();
306 cFeed = cPKSMS->feed();
307 cField = cPKSMS->field();
308 cFlagCmd = cPKSMS->flagCmd();
309 cHistory = cPKSMS->history();
310 cObservation = cPKSMS->observation();
311 cPointing = cPKSMS->pointing();
312 cPolarization = cPKSMS->polarization();
313 cProcessor = cPKSMS->processor();
314 cSource = cPKSMS->source();
315 cSpectralWindow = cPKSMS->spectralWindow();
316 cState = cPKSMS->state();
317 cSysCal = cPKSMS->sysCal();
318 cWeather = cPKSMS->weather();
319
320 // Measurementset table columns;
321 cMSCols = new MSColumns(*cPKSMS);
322 cAntennaCols = new MSAntennaColumns(cAntenna);
323 cDataDescCols = new MSDataDescColumns(cDataDescription);
324 cDopplerCols = new MSDopplerColumns(cDoppler);
325 cFeedCols = new MSFeedColumns(cFeed);
326 cFieldCols = new MSFieldColumns(cField);
327 cFlagCmdCols = new MSFlagCmdColumns(cFlagCmd);
328 cHistoryCols = new MSHistoryColumns(cHistory);
329 cObservationCols = new MSObservationColumns(cObservation);
330 cPointingCols = new MSPointingColumns(cPointing);
331 cPolarizationCols = new MSPolarizationColumns(cPolarization);
332 cProcessorCols = new MSProcessorColumns(cProcessor);
333 cSourceCols = new MSSourceColumns(cSource);
334 cSpWindowCols = new MSSpWindowColumns(cSpectralWindow);
335 cStateCols = new MSStateColumns(cState);
336 cSysCalCols = new MSSysCalColumns(cSysCal);
337 cWeatherCols = new MSWeatherColumns(cWeather);
338
339 cCalFctrCol = new ArrayColumn<Float>(*cPKSMS, "CALFCTR");
340 if (cHaveBase) {
341 cBaseLinCol = new ArrayColumn<Float>(*cPKSMS, "BASELIN");
342 cBaseSubCol = new ArrayColumn<Float>(*cPKSMS, "BASESUB");
343 }
344 if (ntrue(cHaveXPol)) {
345 cXCalFctrCol = new ScalarColumn<Complex>(*cPKSMS, "XCALFCTR");
346 }
347
348
349 // Define Measure references.
350 Vector<String> flagCat(1, "BAD");
351 cMSCols->sigma().rwKeywordSet().define("UNIT", "K");
352 cMSCols->flagCategory().rwKeywordSet().define("CATEGORY", flagCat);
353
354 String dirref;
355 if (equinox == 1950.0f) {
356 dirref = "B1950";
357 } else {
358 dirref = "J2000";
359 }
360
361 cFieldCols->delayDir().rwKeywordSet().asrwRecord("MEASINFO").
362 define("Ref", dirref);
363 cFieldCols->phaseDir().rwKeywordSet().asrwRecord("MEASINFO").
364 define("Ref", dirref);
365 cFieldCols->referenceDir().rwKeywordSet().asrwRecord("MEASINFO").
366 define("Ref", dirref);
367
368 cPointingCols->direction().rwKeywordSet().asrwRecord("MEASINFO").
369 define("Ref", dirref);
370 cPointingCols->target().rwKeywordSet().asrwRecord("MEASINFO").
371 define("Ref", dirref);
372
373 cSourceCols->direction().rwKeywordSet().asrwRecord("MEASINFO").
374 define("Ref", dirref);
375 cSourceCols->restFrequency().rwKeywordSet().asrwRecord("MEASINFO").
376 define("Ref", "REST");
377
378 // Translate Doppler frame name.
379 if (dopplerFrame == "TOPOCENT") {
380 MFrequency::getType(cDopplerFrame, "TOPO");
381 } else if (dopplerFrame == "GEOCENTR") {
382 MFrequency::getType(cDopplerFrame, "GEO");
383 } else if (dopplerFrame == "BARYCENT") {
384 MFrequency::getType(cDopplerFrame, "BARY");
385 } else if (dopplerFrame == "GALACTOC") {
386 MFrequency::getType(cDopplerFrame, "GALACTO");
387 } else if (dopplerFrame == "LOCALGRP") {
388 MFrequency::getType(cDopplerFrame, "LGROUP");
389 } else if (dopplerFrame == "CMBDIPOL") {
390 MFrequency::getType(cDopplerFrame, "CMB");
391 } else if (dopplerFrame == "SOURCE") {
392 MFrequency::getType(cDopplerFrame, "REST");
393 } else if (dopplerFrame == "LSRK") {
394 MFrequency::getType(cDopplerFrame, "LSRK");
395 }
396
397
398 // Store static data.
399 addAntennaEntry(antName, antPosition);
400 addDopplerEntry();
401 addFeedEntry();
402 //addObservationEntry(observer, project);
403 addObservationEntry(observer, project, telName);
404 addProcessorEntry();
405
406 return 0;
407}
408
409//-------------------------------------------------------- PKSMS2writer::write
410
411// Write the next data record.
412
413/**
414Int PKSMS2writer::write(
415 const Int scanNo,
416 const Int cycleNo,
417 const Double mjd,
418 const Double interval,
419 const String fieldName,
420 const String srcName,
421 const Vector<Double> srcDir,
422 const Vector<Double> srcPM,
423 const Double srcVel,
424 const String obsMode,
425 const Int IFno,
426 const Double refFreq,
427 const Double bandwidth,
428 const Double freqInc,
429 //const Double restFreq,
430 const Vector<Double> restFreq,
431 const Vector<Float> tcal,
432 const String tcalTime,
433 const Float azimuth,
434 const Float elevation,
435 const Float parAngle,
436 const Float focusAxi,
437 const Float focusTan,
438 const Float focusRot,
439 const Float temperature,
440 const Float pressure,
441 const Float humidity,
442 const Float windSpeed,
443 const Float windAz,
444 const Int refBeam,
445 const Int beamNo,
446 const Vector<Double> direction,
447 const Vector<Double> scanRate,
448 const Vector<Float> tsys,
449 const Vector<Float> sigma,
450 const Vector<Float> calFctr,
451 const Matrix<Float> baseLin,
452 const Matrix<Float> baseSub,
453 const Matrix<Float> &spectra,
454 const Matrix<uChar> &flagged,
455 const uInt flagrow,
456 const Complex xCalFctr,
457 const Vector<Complex> &xPol)
458**/
459Int PKSMS2writer::write(
460 const PKSrecord &pksrec)
461{
462 // Extend the time range in the OBSERVATION subtable.
463 Vector<Double> timerange(2);
464 cObservationCols->timeRange().get(0, timerange);
465 Double time = pksrec.mjd*86400.0;
466 if (timerange(0) == 0.0) {
467 timerange(0) = time;
468 }
469 timerange(1) = time;
470 cObservationCols->timeRange().put(0, timerange);
471
472 Int iIF = pksrec.IFno - 1;
473 Int nChan = cNChan(iIF);
474 Int nPol = cNPol(iIF);
475
476 // IFno is the 1-relative row number in the DATA_DESCRIPTION,
477 // SPECTRAL_WINDOW, and POLARIZATION subtables.
478 if (Int(cDataDescription.nrow()) < pksrec.IFno) {
479 // Add a new entry to each subtable.
480 addDataDescriptionEntry(pksrec.IFno);
481 addSpectralWindowEntry(pksrec.IFno, nChan, pksrec.refFreq,
482 pksrec.bandwidth, pksrec.freqInc);
483 addPolarizationEntry(pksrec.IFno, nPol);
484 }
485
486 // Find or add the source to the SOURCE subtable.
487 Int srcId = addSourceEntry(pksrec.srcName, pksrec.srcDir, pksrec.srcPM,
488 pksrec.restFreq, pksrec.srcVel);
489
490 // Find or add the obsMode to the STATE subtable.
491 Int stateId = addStateEntry(pksrec.obsType);
492
493 // FIELD subtable.
494 //Vector<Double> scanRate(2);
495 //scanRate(0) = pksrec.scanRate(0);
496 //scanRate(1) = pksrec.scanRate(1);
497 Int fieldId = addFieldEntry(pksrec.fieldName, time, pksrec.direction,
498 pksrec.scanRate, srcId);
499
500 // POINTING subtable.
501 addPointingEntry(time, pksrec.interval, pksrec.fieldName, pksrec.direction,
502 pksrec.scanRate);
503
504 // SYSCAL subtable.
505 addSysCalEntry(pksrec.beamNo, iIF, time, pksrec.interval, pksrec.tcal,
506 pksrec.tsys, nPol);
507
508 // Handle weather information.
509 ROScalarColumn<Double> wTime(cWeather, "TIME");
510 Int nWeather = wTime.nrow();
511 if (nWeather == 0 || time > wTime(nWeather-1)) {
512 addWeatherEntry(time, pksrec.interval, pksrec.pressure, pksrec.humidity,
513 pksrec.temperature);
514 }
515
516
517 // Extend the main table.
518 cPKSMS->addRow();
519 Int irow = cPKSMS->nrow() - 1;
520
521 // Keys.
522 cMSCols->time().put(irow, time);
523 cMSCols->antenna1().put(irow, 0);
524 cMSCols->antenna2().put(irow, 0);
525 cMSCols->feed1().put(irow, pksrec.beamNo-1);
526 cMSCols->feed2().put(irow, pksrec.beamNo-1);
527 cMSCols->dataDescId().put(irow, iIF);
528 cMSCols->processorId().put(irow, 0);
529 cMSCols->fieldId().put(irow, fieldId);
530
531 // Non-key attributes.
532 cMSCols->interval().put(irow, pksrec.interval);
533 cMSCols->exposure().put(irow, pksrec.interval);
534 cMSCols->timeCentroid().put(irow, time);
535 cMSCols->scanNumber().put(irow, pksrec.scanNo);
536 cMSCols->arrayId().put(irow, 0);
537 cMSCols->observationId().put(irow, 0);
538 cMSCols->stateId().put(irow, stateId);
539
540 Vector<Double> uvw(3, 0.0);
541 cMSCols->uvw().put(irow, uvw);
542
543 // Baseline fit parameters.
544 if (cHaveBase) {
545 cBaseLinCol->put(irow, pksrec.baseLin);
546
547 if (pksrec.baseSub.nrow() == 24) {
548 cBaseSubCol->put(irow, pksrec.baseSub);
549
550 } else {
551 Matrix<Float> tmp(24, 2, 0.0f);
552 for (Int ipol = 0; ipol < nPol; ipol++) {
553 for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) {
554 tmp(j,ipol) = pksrec.baseSub(j,ipol);
555 }
556 }
557 cBaseSubCol->put(irow, tmp);
558 }
559 }
560
561 // Transpose spectra.
562 Matrix<Float> tmpData(nPol, nChan);
563 Matrix<Bool> tmpFlag(nPol, nChan);
564 for (Int ipol = 0; ipol < nPol; ipol++) {
565 for (Int ichan = 0; ichan < nChan; ichan++) {
566 tmpData(ipol,ichan) = pksrec.spectra(ichan,ipol);
567 tmpFlag(ipol,ichan) = pksrec.flagged(ichan,ipol);
568 }
569 }
570
571 cCalFctrCol->put(irow, pksrec.calFctr);
572 cMSCols->floatData().put(irow, tmpData);
573 cMSCols->flag().put(irow, tmpFlag);
574
575 // Cross-polarization spectra.
576 if (cHaveXPol(iIF)) {
577 cXCalFctrCol->put(irow, pksrec.xCalFctr);
578 cMSCols->data().put(irow, pksrec.xPol);
579 }
580
581 cMSCols->sigma().put(irow, pksrec.sigma);
582
583 //Vector<Float> weight(1, 1.0f);
584 Vector<Float> weight(nPol, 1.0f);
585 cMSCols->weight().put(irow, weight);
586 //imaging weight
587 //Vector<Float> imagingWeight(nChan);
588 //cMSCols->imagingWeight().put(irow, imagingWeight);
589
590 // Flag information.
591 Cube<Bool> flags(nPol, nChan, 1, False);
592 //cMSCols->flag().put(irow, flags.xyPlane(0));
593 cMSCols->flagCategory().put(irow, flags);
594 // Row-based flagging info. (True:>0, False:0)
595 cMSCols->flagRow().put(irow, (pksrec.flagrow > 0));
596
597
598 return 0;
599}
600
601//-------------------------------------------------------- PKSMS2writer::close
602
603// Close the measurementset, flushing all associated tables.
604
605void PKSMS2writer::close()
606{
607 // Delete table column accessors.
608 delete cMSCols; cMSCols=0;
609 delete cAntennaCols; cAntennaCols=0;
610 delete cDataDescCols; cDataDescCols=0;
611 delete cDopplerCols; cDopplerCols=0;
612 delete cFeedCols; cFeedCols=0;
613 delete cFieldCols; cFieldCols=0;
614 delete cFlagCmdCols; cFlagCmdCols=0;
615 delete cHistoryCols; cHistoryCols=0;
616 delete cObservationCols; cObservationCols=0;
617 delete cPointingCols; cPointingCols=0;
618 delete cPolarizationCols; cPolarizationCols=0;
619 delete cProcessorCols; cProcessorCols=0;
620 delete cSourceCols; cSourceCols=0;
621 delete cSpWindowCols; cSpWindowCols=0;
622 delete cStateCols; cStateCols=0;
623 delete cSysCalCols; cSysCalCols=0;
624 delete cWeatherCols; cWeatherCols=0;
625
626 delete cCalFctrCol; cCalFctrCol=0;
627 if (cHaveBase) {
628 delete cBaseLinCol; cBaseLinCol=0;
629 delete cBaseSubCol; cBaseSubCol=0;
630 }
631 if (ntrue(cHaveXPol)) {
632 delete cXCalFctrCol; cXCalFctrCol=0;
633 }
634
635 // Release all subtables.
636 cAntenna = MSAntenna();
637 cDataDescription = MSDataDescription();
638 cDoppler = MSDoppler();
639 cFeed = MSFeed();
640 cField = MSField();
641 cFlagCmd = MSFlagCmd();
642 cHistory = MSHistory();
643 cObservation = MSObservation();
644 cPointing = MSPointing();
645 cPolarization = MSPolarization();
646 cProcessor = MSProcessor();
647 cSource = MSSource();
648 cSpectralWindow = MSSpectralWindow();
649 cState = MSState();
650 cSysCal = MSSysCal();
651 cWeather = MSWeather();
652 // Release the main table.
653 delete cPKSMS;
654 cPKSMS=0x0;
655}
656
657//---------------------------------------------- PKSMS2writer::addAntennaEntry
658
659// Add an entry to the ANTENNA subtable.
660
661Int PKSMS2writer::addAntennaEntry(
662 const String antName,
663 const Vector<Double> &antPosition)
664{
665 // Extend the ANTENNA subtable.
666 cAntenna.addRow();
667 Int n = cAntenna.nrow() - 1;
668
669 // do specific things for GBT
670 // Data.
671 // plus some more telescopes
672 cAntennaCols->name().put(n, antName);
673 //cAntennaCols->station().put(n, "ATNF_PARKES");
674 if (cGBT) {
675 cAntennaCols->station().put(n, "GREENBANK");
676 cAntennaCols->dishDiameter().put(n, 110.0);
677 }
678 else if (cAPEX) {
679 cAntennaCols->station().put(n, "CHAJNANTOR");
680 cAntennaCols->dishDiameter().put(n, 12.0);
681 }
682 else if (cALMA) {
683 // this needs to be changed in future...
684 cAntennaCols->station().put(n, "CHAJNANTOR");
685 cAntennaCols->dishDiameter().put(n, 12.0);
686 }
687 else if (cATF) {
688 //pad name for the antenna is static...
689 String stname="unknown";
690 if (antName.contains("DV")) {
691 stname="PAD001";
692 }
693 if (antName.contains("DA")) {
694 stname="PAD002";
695 }
696 cAntennaCols->station().put(n, stname);
697 cAntennaCols->dishDiameter().put(n, 12.0);
698 }
699 else if (cSMT) {
700 cAntennaCols->station().put(n, "MT_GRAHAM");
701 cAntennaCols->dishDiameter().put(n, 10.0);
702 }
703 else {
704 cAntennaCols->station().put(n, "ATNF_PARKES");
705 cAntennaCols->dishDiameter().put(n, 64.0);
706 }
707 cAntennaCols->type().put(n, "GROUND-BASED");
708 cAntennaCols->mount().put(n, "ALT-AZ");
709 cAntennaCols->position().put(n, antPosition);
710 Vector<Double> antOffset(3, 0.0);
711 cAntennaCols->offset().put(n, antOffset);
712 //cAntennaCols->dishDiameter().put(n, 64.0);
713 //if (cGBT) {
714 // cAntennaCols->dishDiameter().put(n, 110.0);
715 //}
716 //else {
717 // cAntennaCols->dishDiameter().put(n, 64.0);
718 //}
719 // Flags.
720 cAntennaCols->flagRow().put(n, False);
721
722 return n;
723}
724
725//-------------------------------------- PKSMS2writer::addDataDescriptionEntry
726
727// Add an entry to the DATA_DESCRIPTION subtable.
728
729Int PKSMS2writer::addDataDescriptionEntry(
730 const Int IFno)
731{
732 // Extend the DATA_DESCRIPTION subtable.
733 while (Int(cDataDescription.nrow()) < IFno) {
734 cDataDescription.addRow(1,True);
735 }
736 Int n = IFno - 1;
737
738 // Data.
739 cDataDescCols->spectralWindowId().put(n, n);
740 cDataDescCols->polarizationId().put(n, n);
741
742 // Flags.
743 cDataDescCols->flagRow().put(n, False);
744
745 return n;
746}
747
748//---------------------------------------------- PKSMS2writer::addDopplerEntry
749
750// Add an entry to the DOPPLER subtable.
751
752Int PKSMS2writer::addDopplerEntry()
753{
754 // Extend the DOPPLER subtable.
755 cDoppler.addRow();
756 Int n = cDoppler.nrow() - 1;
757
758 // Keys.
759 cDopplerCols->dopplerId().put(n, n);
760 cDopplerCols->sourceId().put(n, 0);
761
762 // Data.
763 cDopplerCols->transitionId().put(n, 0);
764
765 return n;
766}
767
768//------------------------------------------------- PKSMS2writer::addFeedEntry
769
770// Add an entry to the FEED subtable.
771
772Int PKSMS2writer::addFeedEntry()
773{
774 Int n = cFeed.nrow() - 1;
775 for (Int iBeam = 0; iBeam < 13; iBeam++) {
776 // Extend the FEED subtable.
777 cFeed.addRow();
778 n++;
779
780 // Keys.
781 cFeedCols->antennaId().put(n, cAntenna.nrow()-1);
782 cFeedCols->feedId().put(n, iBeam);
783 cFeedCols->spectralWindowId().put(n, -1);
784 cFeedCols->time().put(n, 0.0);
785 cFeedCols->interval().put(n, -1.0);
786
787 // Data description.
788 cFeedCols->numReceptors().put(n, 2);
789
790 // Data.
791 cFeedCols->beamId().put(n, -1);
792
793 Matrix<Double> beamOffset(2, 2, 0.0);
794 cFeedCols->beamOffset().put(n, beamOffset);
795
796 cFeedCols->focusLength().put(n, 26.0);
797
798 Vector<String> polarizationType(2);
799 polarizationType(0) = "X";
800 polarizationType(1) = "Y";
801 cFeedCols->polarizationType().put(n, polarizationType);
802
803 Matrix<Complex> polResponse(2, 2, Complex(0.0));
804 for (Int i = 0; i < 2; i++) {
805 polResponse(i,i) = Complex(1.0, 0.0);
806 }
807 cFeedCols->polResponse().put(n, polResponse);
808
809 Vector<Double> position(3, 0.0);
810 cFeedCols->position().put(n, position);
811
812 Vector<Double> receptorAngle(2, C::pi_4);
813 receptorAngle(1) += C::pi_2;
814 cFeedCols->receptorAngle().put(n, receptorAngle);
815 }
816
817 return n;
818}
819
820//------------------------------------------------ PKSMS2writer::addFieldEntry
821
822// Add an entry to the FIELD subtable.
823
824Int PKSMS2writer::addFieldEntry(
825 const String fieldName,
826 const Double time,
827 const Vector<Double> direction,
828 const Vector<Double> scanRate,
829 const Int srcId)
830{
831
832 ROScalarColumn<String> fldn(cField, "NAME");
833 ROScalarColumn<Int> sourceid(cField, "SOURCE_ID");
834 Int n;
835 Int nFld = cField.nrow();
836 for (n = 0; n < nFld; n++) {
837 if (fldn(n) == fieldName && sourceid(n) == srcId) {
838 break;
839 }
840 }
841
842 // Extend the FIELD subtable.
843 if (n == nFld) {
844 cField.addRow();
845 //Int n = cField.nrow() - 1;
846
847 // Data.
848 cFieldCols->name().put(n, fieldName);
849 if (cGBT) {
850 cFieldCols->code().put(n, " ");
851 }
852 else {
853 cFieldCols->code().put(n, "DRIFT");
854 }
855 cFieldCols->time().put(n, time);
856
857 //Matrix<Double> track(2, 2);
858 Matrix<Double> track(2, 1);
859 track.column(0) = direction;
860 //track.column(1) = scanRate;
861 cFieldCols->numPoly().put(n, 1);
862 cFieldCols->delayDir().put(n, track);
863 cFieldCols->phaseDir().put(n, track);
864 cFieldCols->referenceDir().put(n, track);
865 cFieldCols->sourceId().put(n, srcId);
866
867 // Flags.
868 cFieldCols->flagRow().put(n, False);
869 }
870
871 return n;
872}
873
874//------------------------------------------ PKSMS2writer::addObservationEntry
875
876// Add an entry to the OBSERVATION subtable.
877
878Int PKSMS2writer::addObservationEntry(
879 const String observer,
880 const String project,
881 const String antName)
882{
883 // Extend the OBSERVATION subtable.
884 cObservation.addRow();
885 Int n = cObservation.nrow() - 1;
886
887 // Data.
888 //cObservationCols->telescopeName().put(n, "Parkes");
889 cObservationCols->telescopeName().put(n, antName);
890 Vector<Double> timerange(2, 0.0);
891 cObservationCols->timeRange().put(n, timerange);
892 cObservationCols->observer().put(n, observer);
893 Vector<String> log(1, "none");
894 cObservationCols->log().put(n, log);
895 //cObservationCols->scheduleType().put(n, "ATNF");
896 cObservationCols->scheduleType().put(n, "");
897 Vector<String> schedule(1, "Not available");
898 cObservationCols->schedule().put(n, schedule);
899 cObservationCols->project().put(n, project);
900 cObservationCols->releaseDate().put(n, 0.0);
901
902 // Flags.
903 cObservationCols->flagRow().put(n, False);
904
905 return n;
906}
907
908//--------------------------------------------- PKSMS2writer::addPointingEntry
909
910// Modified to fill pointing data if the direction is the pointing direction.
911// So the following comment is no longer true.
912
913// Add an entry to the POINTING subtable. This compulsory subtable simply
914// duplicates information in the FIELD subtable.
915
916Int PKSMS2writer::addPointingEntry(
917 const Double time,
918 const Double interval,
919 const String fieldName,
920 const Vector<Double> direction,
921 const Vector<Double> scanRate)
922{
923
924 ROScalarColumn<Double> tms(cPointing, "TIME");
925 Int n;
926 Int ntm = cPointing.nrow();
927 for (n = 0; n < ntm; n++) {
928 if (tms(n) == time) {
929 break;
930 }
931 }
932
933 if (n == ntm) {
934 // Extend the POINTING subtable.
935 cPointing.addRow();
936 //Int n = cPointing.nrow() - 1;
937
938 // Keys.
939 cPointingCols->antennaId().put(n, 0);
940 cPointingCols->time().put(n, time);
941 cPointingCols->interval().put(n, interval);
942
943 // Data.
944 cPointingCols->name().put(n, fieldName);
945 cPointingCols->numPoly().put(n, 1);
946 cPointingCols->timeOrigin().put(n, time);
947
948 //Matrix<Double> track(2, 2);
949 Matrix<Double> track(2, 1);
950 track.column(0) = direction;
951 //track.column(1) = scanRate;
952 cPointingCols->direction().put(n, track);
953 cPointingCols->target().put(n, track);
954 cPointingCols->tracking().put(n, True);
955 }
956 return n;
957}
958
959//----------------------------------------- PKSMS2writer::addPolarizationEntry
960
961// Add an entry to the POLARIZATION subtable.
962
963Int PKSMS2writer::addPolarizationEntry(
964 const Int IFno,
965 const Int nPol)
966{
967 // Extend the POLARIZATION subtable.
968 Int nr = cPolarization.nrow() ;
969 while (Int(cPolarization.nrow()) < IFno) {
970 cPolarization.addRow(1,True);
971 }
972 Int n = IFno - 1;
973
974 // Data description.
975 cPolarizationCols->numCorr().put(n, nPol);
976
977 // Data.
978 Vector<Int> corrType(2);
979 if (nPol == 1) {
980 corrType.resize(1);
981 corrType(0) = Stokes::XX;
982 }
983 else {
984 //Vector<Int> corrType(2);
985 corrType(0) = Stokes::XX;
986 corrType(1) = Stokes::YY;
987 }
988 // initialization
989 for ( Int i = nr ; i < n ; i++ )
990 cPolarizationCols->corrType().put( i, corrType ) ;
991 cPolarizationCols->corrType().put(n, corrType);
992
993 Matrix<Int> corrProduct(2,2,1);
994 if (nPol == 1) {
995 corrProduct.resize(2,1,1);
996 corrProduct(1,0) = 0;
997 }
998 if (nPol == 2) {
999 corrProduct(1,0) = 0;
1000 corrProduct(0,1) = 0;
1001 }
1002 cPolarizationCols->corrProduct().put(n, corrProduct);
1003
1004 // Flags.
1005 cPolarizationCols->flagRow().put(n, False);
1006
1007 return n;
1008}
1009
1010
1011//-------------------------------------------- PKSMS2writer::addProcessorEntry
1012
1013// Add an entry to the PROCESSOR subtable.
1014
1015Int PKSMS2writer::addProcessorEntry()
1016{
1017 // Extend the PROCESSOR subtable.
1018 cProcessor.addRow();
1019 Int n = cProcessor.nrow() - 1;
1020
1021 // Data.
1022 cProcessorCols->type().put(n, "SPECTROMETER");
1023 cProcessorCols->subType().put(n, "MULTIBEAM");
1024 cProcessorCols->typeId().put(n, -1);
1025 cProcessorCols->modeId().put(n, -1);
1026
1027 // Flags.
1028 cProcessorCols->flagRow().put(n, False);
1029
1030 return n;
1031}
1032
1033//----------------------------------------------- PKSMS2writer::addSourceEntry
1034
1035// Add an entry to the SOURCE subtable.
1036
1037Int PKSMS2writer::addSourceEntry(
1038 const String name,
1039 const Vector<Double> direction,
1040 const Vector<Double> properMotion,
1041 //const Double restFreq,
1042 const Vector<Double> restFreq,
1043 const Double radialVelocity)
1044{
1045 // Look for an entry in the SOURCE subtable.
1046 ROScalarColumn<String> sources(cSource, "NAME");
1047 Int n;
1048 Int nSrc = sources.nrow();
1049 for (n = 0; n < nSrc; n++) {
1050 if (sources(n) == name) {
1051 break;
1052 }
1053 }
1054
1055 if (n == nSrc) {
1056 // Not found, add a new entry to the SOURCE subtable.
1057 cSource.addRow();
1058
1059 // Keys.
1060 cSourceCols->sourceId().put(n, n);
1061 cSourceCols->time().put(n, 0.0);
1062 cSourceCols->interval().put(n, -1.0);
1063 cSourceCols->spectralWindowId().put(n, -1);
1064
1065 // Data description.
1066 cSourceCols->numLines().put(n, 1);
1067
1068 // Data.
1069 cSourceCols->name().put(n, name);
1070 cSourceCols->calibrationGroup().put(n, 0);
1071 cSourceCols->code().put(n, "");
1072 cSourceCols->direction().put(n, direction);
1073// Vector<Double> position(3, 0.0);
1074// cSourceCols->position().put(n, position);
1075 cSourceCols->properMotion().put(n, properMotion);
1076// Vector<Double> restFrequency(1, restFreq);
1077// cSourceCols->restFrequency().put(n, restFrequency);
1078 cSourceCols->restFrequency().put(n, restFreq);
1079 Vector<Double> sysvel(1, radialVelocity);
1080 cSourceCols->sysvel().put(n, sysvel);
1081 }
1082
1083 return n;
1084}
1085
1086//--------------------------------------- PKSMS2writer::addSpectralWindowEntry
1087
1088// Add an entry to the SPECTRAL_WINDOW subtable.
1089
1090Int PKSMS2writer::addSpectralWindowEntry(
1091 const Int IFno,
1092 const Int nChan,
1093 const Double refFreq,
1094 const Double bandwidth,
1095 const Double freqInc)
1096{
1097 // Extend the SPECTRAL_WINDOW subtable.
1098 Int nr = cSpectralWindow.nrow() ;
1099 while (Int(cSpectralWindow.nrow()) < IFno) {
1100 cSpectralWindow.addRow(1,True);
1101 }
1102 Int n = IFno - 1;
1103
1104 // Data description.
1105 cSpWindowCols->numChan().put(n, nChan);
1106
1107 // Data.
1108 //cSpWindowCols->name().put(n, "L-band");
1109 cSpWindowCols->name().put(n, " ");
1110 cSpWindowCols->refFrequency().put(n, refFreq);
1111
1112 // 0-relative reference channel number.
1113 Double refChan = nChan / 2;
1114 Vector<Double> freqs(nChan);
1115 for (Int i = 0; i < nChan; i++) {
1116 freqs(i) = refFreq + (i - refChan)*freqInc;
1117 }
1118 // initialization
1119 for ( Int i = nr ; i < n ; i++ )
1120 cSpWindowCols->chanFreq().put( i, freqs ) ;
1121 cSpWindowCols->chanFreq().put(n, freqs);
1122
1123 Vector<Double> chanWidths(nChan, freqInc);
1124 // initialization
1125 for ( Int i = nr ; i < n ; i++ ) {
1126 cSpWindowCols->chanWidth().put( i, chanWidths ) ;
1127 cSpWindowCols->effectiveBW().put( i, chanWidths ) ;
1128 }
1129 cSpWindowCols->chanWidth().put(n, chanWidths);
1130
1131 cSpWindowCols->measFreqRef().put(n, cDopplerFrame);
1132 cSpWindowCols->effectiveBW().put(n, chanWidths);
1133
1134 Vector<Double> resolution(nChan, fabs(freqInc));
1135 // initialization
1136 for ( Int i = nr ; i < n ; i++ )
1137 cSpWindowCols->resolution().put( i, resolution ) ;
1138 cSpWindowCols->resolution().put(n, resolution);
1139
1140 cSpWindowCols->totalBandwidth().put(n, bandwidth);
1141 cSpWindowCols->netSideband().put(n, 0);
1142 cSpWindowCols->ifConvChain().put(n, -1);
1143 cSpWindowCols->freqGroup().put(n, 0);
1144 cSpWindowCols->freqGroupName().put(n, " ");
1145 cSpWindowCols->dopplerId().put(n, 0);
1146
1147 // Flags.
1148 cSpWindowCols->flagRow().put(n, False);
1149
1150 return n;
1151}
1152
1153//------------------------------------------------ PKSMS2writer::addStateEntry
1154
1155// Add an entry to the STATE subtable.
1156
1157Int PKSMS2writer::addStateEntry(
1158 const String obsType)
1159{
1160 // Look for an entry in the STATE subtable.
1161 for (uInt n = 0; n < cStateCols->nrow(); n++) {
1162 if (cStateCols->obsMode()(n) == obsType) {
1163 return n;
1164 }
1165 }
1166
1167 // Not found, extend the STATE subtable.
1168 cState.addRow();
1169 uInt n = cStateCols->nrow() - 1;
1170
1171 // Data.
1172 if (obsType.contains("RF")) {
1173 cStateCols->sig().put(n, False);
1174 cStateCols->ref().put(n, True);
1175 } else if (!obsType.contains("PA")) {
1176 // Signal and reference are both false for "paddle" data.
1177 cStateCols->sig().put(n, True);
1178 cStateCols->ref().put(n, False);
1179 }
1180
1181 cStateCols->load().put(n, 0.0);
1182 cStateCols->cal().put(n, 0.0);
1183 cStateCols->subScan().put(n, 0);
1184 cStateCols->obsMode().put(n, obsType);
1185
1186 // Flags.
1187 cStateCols->flagRow().put(n, False);
1188
1189 return n;
1190}
1191
1192//----------------------------------------------- PKSMS2writer::addSysCalEntry
1193
1194// Add an entry to the SYSCAL subtable.
1195
1196Int PKSMS2writer::addSysCalEntry(
1197 const Int beamNo,
1198 const Int spWinId,
1199 const Double time,
1200 const Double interval,
1201 const Vector<Float> tcal,
1202 const Vector<Float> tsys,
1203 const Int nPol)
1204{
1205 LogIO os(LogOrigin("PKSMS2writer", "addSysCalEntry()", WHERE));
1206
1207 // Extend the SYSCAL subtable.
1208 cSysCal.addRow();
1209 Int n = cSysCal.nrow() - 1;
1210
1211 //check fo consistency with n pol
1212 //here assume size of Tcal vector = npol
1213 Vector<Float> inTcal(nPol,0);
1214 Int ndim = tcal.shape()(0);
1215 Vector<Float> tmpTcal = tcal;
1216 if (nPol != ndim) {
1217 os << LogIO::WARN
1218 << "Found "<< ndim <<" Tcal value(s) for the data with "<<nPol<<" polarization(s)"
1219 << "(expecting one Tcal per pol)."<<endl
1220 << "First "<< nPol << " Tcal value(s) will be filled." << LogIO::POST;
1221 tmpTcal.resize(nPol, True);
1222 inTcal = tmpTcal;
1223 }
1224 // Keys.
1225 cSysCalCols->antennaId().put(n, 0);
1226 cSysCalCols->feedId().put(n, beamNo-1);
1227 cSysCalCols->spectralWindowId().put(n, spWinId);
1228 cSysCalCols->time().put(n, time);
1229 cSysCalCols->interval().put(n, interval);
1230
1231 // Data.
1232 //cSysCalCols->tcal().put(n, tcal);
1233 cSysCalCols->tcal().put(n, inTcal);
1234 cSysCalCols->tsys().put(n, tsys);
1235
1236 return n;
1237}
1238
1239//---------------------------------------------- PKSMS2writer::addWeatherEntry
1240
1241// Add an entry to the WEATHER subtable.
1242
1243Int PKSMS2writer::addWeatherEntry(
1244 const Double time,
1245 const Double interval,
1246 const Double pressure,
1247 const Double relHumidity,
1248 const Double temperature)
1249{
1250 // Extend the WEATHER subtable.
1251 cWeather.addRow();
1252 Int n = cWeather.nrow() - 1;
1253
1254 // Keys.
1255 cWeatherCols->antennaId().put(n, 0);
1256 cWeatherCols->time().put(n, time);
1257 cWeatherCols->interval().put(n, interval);
1258
1259 // Data.
1260 cWeatherCols->pressure().put(n, pressure);
1261 cWeatherCols->relHumidity().put(n, relHumidity);
1262 cWeatherCols->temperature().put(n, temperature);
1263
1264 return n;
1265}
Note: See TracBrowser for help on using the repository browser.