Index: branches/alma/external/atnf/PKSIO/PKSMS2writer.cc
===================================================================
--- branches/alma/external/atnf/PKSIO/PKSMS2writer.cc	(revision 1453)
+++ branches/alma/external/atnf/PKSIO/PKSMS2writer.cc	(revision 1757)
@@ -2,31 +2,35 @@
 //# PKSMS2writer.cc: Class to write Parkes multibeam data to a measurementset.
 //#---------------------------------------------------------------------------
-//# Copyright (C) 2000-2006
-//# Associated Universities, Inc. Washington DC, USA.
+//# livedata - processing pipeline for single-dish, multibeam spectral data.
+//# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO
 //#
-//# This library is free software; you can redistribute it and/or modify it
-//# under the terms of the GNU Library General Public License as published by
-//# the Free Software Foundation; either version 2 of the License, or (at your
-//# option) any later version.
+//# This file is part of livedata.
 //#
-//# This library is distributed in the hope that it will be useful, but
-//# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-//# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
-//# License for more details.
+//# livedata is free software: you can redistribute it and/or modify it under
+//# the terms of the GNU General Public License as published by the Free
+//# Software Foundation, either version 3 of the License, or (at your option)
+//# any later version.
 //#
-//# You should have received a copy of the GNU Library General Public License
-//# along with this library; if not, write to the Free Software Foundation,
-//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
+//# livedata is distributed in the hope that it will be useful, but WITHOUT
+//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+//# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+//# more details.
 //#
-//# Correspondence concerning AIPS++ should be addressed as follows:
-//#        Internet email: aips2-request@nrao.edu.
-//#        Postal address: AIPS++ Project Office
-//#                        National Radio Astronomy Observatory
-//#                        520 Edgemont Road
-//#                        Charlottesville, VA 22903-2475 USA
+//# You should have received a copy of the GNU General Public License along
+//# with livedata.  If not, see <http://www.gnu.org/licenses/>.
 //#
-//# $Id: PKSMS2writer.cc,v 19.11 2006/11/06 22:25:22 mmarquar Exp $
+//# Correspondence concerning livedata may be directed to:
+//#        Internet email: mcalabre@atnf.csiro.au
+//#        Postal address: Dr. Mark Calabretta
+//#                        Australia Telescope National Facility, CSIRO
+//#                        PO Box 76
+//#                        Epping NSW 1710
+//#                        AUSTRALIA
+//#
+//# http://www.atnf.csiro.au/computing/software/livedata.html
+//# $Id: PKSMS2writer.cc,v 19.16 2009-09-29 07:33:38 cal103 Exp $
 //#---------------------------------------------------------------------------
 
+#include <atnf/PKSIO/PKSrecord.h>
 #include <atnf/PKSIO/PKSMS2writer.h>
 
@@ -49,4 +53,7 @@
 #include <tables/Tables/TiledShapeStMan.h>
 
+// Class name
+const string className = "PKSMS2writer" ;
+
 //------------------------------------------------- PKSMS2writer::PKSMS2writer
 
@@ -55,4 +62,5 @@
 PKSMS2writer::PKSMS2writer()
 {
+  cPKSMS = 0x0;
 }
 
@@ -77,4 +85,5 @@
         const Vector<Double> antPosition,
         const String obsMode,
+        const String bunit,
         const Float  equinox,
         const String dopplerFrame,
@@ -82,7 +91,14 @@
         const Vector<uInt> nPol,
         const Vector<Bool> haveXPol,
-        const Bool   haveBase,
-        const String fluxUnit)
-{
+        const Bool   haveBase)
+{
+  const string methodName = "create()" ;
+  LogIO os( LogOrigin( className, methodName, WHERE ) ) ;
+
+  if (cPKSMS) {
+    os << LogIO::SEVERE << "Output MS already open, close it first." << LogIO::POST ;
+    return 1;
+  }
+
   // Open a MS table.
   TableDesc pksDesc = MS::requiredTableDesc();
@@ -93,6 +109,7 @@
 
   Int maxNPol = max(cNPol);
-  cGBT = cAPEX = cSMT = cALMA = False;
-
+  cGBT = cAPEX = cSMT = cALMA = cATF = False;
+
+  String telName = antName;
   // check if it is GBT data
   if (antName.contains("GBT")) {
@@ -108,12 +125,9 @@
     cALMA = True;
   }
+  else if (antName.contains("ATF")) {
+    cATF = True;
+    telName="ATF";
+  }
  
-
-   
-  //cGBT = antName.contains("GBT");
-  //cAPEX = antName.contains("APEX");
-  //cSMT = antName.contains("HHT");
-  //cALMA = antName.contains("ALMA");
-
   // Add the non-standard CALFCTR column.
   pksDesc.addColumn(ArrayColumnDesc<Float>("CALFCTR", "Calibration factors",
@@ -125,5 +139,5 @@
   //              define("UNIT", String("Jy"));
   pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet().
-                define("UNIT", fluxUnit);
+                define("UNIT", bunit);
   pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet().
                 define("MEASURE_TYPE", "");
@@ -134,5 +148,5 @@
                 IPosition(2,2,maxNPol), ColumnDesc::Direct));
     pksDesc.addColumn(ArrayColumnDesc<Float>("BASESUB", "Baseline subtracted",
-                IPosition(2,9,maxNPol), ColumnDesc::Direct));
+                IPosition(2,24,maxNPol), ColumnDesc::Direct));
   }
 
@@ -147,5 +161,5 @@
     //            define("UNIT", "Jy");
     pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet().
-                define("UNIT", fluxUnit);
+                define("UNIT", bunit);
     pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet().
                 define("MEASURE_TYPE", "");
@@ -387,5 +401,5 @@
   addFeedEntry();
   //addObservationEntry(observer, project);
-  addObservationEntry(observer, project, antName);
+  addObservationEntry(observer, project, telName);
   addProcessorEntry();
 
@@ -397,4 +411,5 @@
 // Write the next data record.
 
+/**
 Int PKSMS2writer::write(
         const Int             scanNo,
@@ -438,11 +453,15 @@
         const Matrix<Float>   &spectra,
         const Matrix<uChar>   &flagged,
+	const uInt            flagrow,
         const Complex         xCalFctr,
         const Vector<Complex> &xPol)
+**/
+Int PKSMS2writer::write(
+        const PKSrecord &pksrec)
 {
   // Extend the time range in the OBSERVATION subtable.
   Vector<Double> timerange(2);
   cObservationCols->timeRange().get(0, timerange);
-  Double time = mjd*86400.0;
+  Double time = pksrec.mjd*86400.0;
   if (timerange(0) == 0.0) {
     timerange(0) = time;
@@ -451,5 +470,5 @@
   cObservationCols->timeRange().put(0, timerange);
 
-  Int iIF = IFno - 1;
+  Int iIF = pksrec.IFno - 1;
   Int nChan = cNChan(iIF);
   Int nPol  = cNPol(iIF);
@@ -457,26 +476,33 @@
   // IFno is the 1-relative row number in the DATA_DESCRIPTION,
   // SPECTRAL_WINDOW, and POLARIZATION subtables.
-  if (Int(cDataDescription.nrow()) < IFno) {
+  if (Int(cDataDescription.nrow()) < pksrec.IFno) {
     // Add a new entry to each subtable.
-    addDataDescriptionEntry(IFno);
-    addSpectralWindowEntry(IFno, nChan, refFreq, bandwidth, freqInc);
-    addPolarizationEntry(IFno, nPol);
+    addDataDescriptionEntry(pksrec.IFno);
+    addSpectralWindowEntry(pksrec.IFno, nChan, pksrec.refFreq,
+      pksrec.bandwidth, pksrec.freqInc);
+    addPolarizationEntry(pksrec.IFno, nPol);
   }
 
   // Find or add the source to the SOURCE subtable.
-  Int srcId = addSourceEntry(srcName, srcDir, srcPM, restFreq, srcVel);
+  Int srcId = addSourceEntry(pksrec.srcName, pksrec.srcDir, pksrec.srcPM,
+    pksrec.restFreq, pksrec.srcVel);
 
   // Find or add the obsMode to the STATE subtable.
-  Int stateId = addStateEntry(obsMode);
+  Int stateId = addStateEntry(pksrec.obsType);
 
   // FIELD subtable.
-  Int fieldId = addFieldEntry(fieldName, time, direction, scanRate, srcId);
+  //Vector<Double> scanRate(2);
+  //scanRate(0) = pksrec.scanRate(0);
+  //scanRate(1) = pksrec.scanRate(1);
+  Int fieldId = addFieldEntry(pksrec.fieldName, time, pksrec.direction,
+    pksrec.scanRate, srcId);
 
   // POINTING subtable.
-  addPointingEntry(time, interval, fieldName, direction, scanRate);
+  addPointingEntry(time, pksrec.interval, pksrec.fieldName, pksrec.direction,
+    pksrec.scanRate);
 
   // SYSCAL subtable.
-  addSysCalEntry(beamNo, iIF, time, interval, tcal, tsys, nPol);
-
+  addSysCalEntry(pksrec.beamNo, iIF, time, pksrec.interval, pksrec.tcal,
+    pksrec.tsys, nPol);
 
   // Handle weather information.
@@ -484,5 +510,6 @@
   Int nWeather = wTime.nrow();
   if (nWeather == 0 || time > wTime(nWeather-1)) {
-    addWeatherEntry(time, interval, pressure, humidity, temperature);
+    addWeatherEntry(time, pksrec.interval, pksrec.pressure, pksrec.humidity,
+      pksrec.temperature);
   }
 
@@ -496,6 +523,6 @@
   cMSCols->antenna1().put(irow, 0);
   cMSCols->antenna2().put(irow, 0);
-  cMSCols->feed1().put(irow, beamNo-1);
-  cMSCols->feed2().put(irow, beamNo-1);
+  cMSCols->feed1().put(irow, pksrec.beamNo-1);
+  cMSCols->feed2().put(irow, pksrec.beamNo-1);
   cMSCols->dataDescId().put(irow, iIF);
   cMSCols->processorId().put(irow, 0);
@@ -503,8 +530,8 @@
 
   // Non-key attributes.
-  cMSCols->interval().put(irow, interval);
-  cMSCols->exposure().put(irow, interval);
+  cMSCols->interval().put(irow, pksrec.interval);
+  cMSCols->exposure().put(irow, pksrec.interval);
   cMSCols->timeCentroid().put(irow, time);
-  cMSCols->scanNumber().put(irow, scanNo);
+  cMSCols->scanNumber().put(irow, pksrec.scanNo);
   cMSCols->arrayId().put(irow, 0);
   cMSCols->observationId().put(irow, 0);
@@ -516,14 +543,14 @@
   // Baseline fit parameters.
   if (cHaveBase) {
-    cBaseLinCol->put(irow, baseLin);
-
-    if (baseSub.nrow() == 9) {
-      cBaseSubCol->put(irow, baseSub);
+    cBaseLinCol->put(irow, pksrec.baseLin);
+
+    if (pksrec.baseSub.nrow() == 24) {
+      cBaseSubCol->put(irow, pksrec.baseSub);
 
     } else {
-      Matrix<Float> tmp(9, 2, 0.0f);
+      Matrix<Float> tmp(24, 2, 0.0f);
       for (Int ipol = 0; ipol < nPol; ipol++) {
-        for (uInt j = 0; j < baseSub.nrow(); j++) {
-          tmp(j,ipol) = baseSub(j,ipol);
+        for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) {
+          tmp(j,ipol) = pksrec.baseSub(j,ipol);
         }
       }
@@ -531,4 +558,5 @@
     }
   }
+
   // Transpose spectra.
   Matrix<Float> tmpData(nPol, nChan);
@@ -536,9 +564,10 @@
   for (Int ipol = 0; ipol < nPol; ipol++) {
     for (Int ichan = 0; ichan < nChan; ichan++) {
-      tmpData(ipol,ichan) = spectra(ichan,ipol);
-      tmpFlag(ipol,ichan) = flagged(ichan,ipol);
+      tmpData(ipol,ichan) = pksrec.spectra(ichan,ipol);
+      tmpFlag(ipol,ichan) = pksrec.flagged(ichan,ipol);
     }
   }
-  cCalFctrCol->put(irow, calFctr);
+
+  cCalFctrCol->put(irow, pksrec.calFctr);
   cMSCols->floatData().put(irow, tmpData);
   cMSCols->flag().put(irow, tmpFlag);
@@ -546,9 +575,9 @@
   // Cross-polarization spectra.
   if (cHaveXPol(iIF)) {
-    cXCalFctrCol->put(irow, xCalFctr);
-    cMSCols->data().put(irow, xPol);
-  }
-
-  cMSCols->sigma().put(irow, sigma);
+    cXCalFctrCol->put(irow, pksrec.xCalFctr);
+    cMSCols->data().put(irow, pksrec.xPol);
+  }
+
+  cMSCols->sigma().put(irow, pksrec.sigma);
 
   //Vector<Float> weight(1, 1.0f);
@@ -563,5 +592,7 @@
   //cMSCols->flag().put(irow, flags.xyPlane(0));
   cMSCols->flagCategory().put(irow, flags);
-  cMSCols->flagRow().put(irow, False);
+  // Row-based flagging info. (True:>0, False:0)
+  cMSCols->flagRow().put(irow, (pksrec.flagrow > 0));
+
 
   return 0;
@@ -601,5 +632,5 @@
     delete cXCalFctrCol; cXCalFctrCol=0;
   }
- 
+
   // Release all subtables.
   cAntenna         = MSAntenna();
@@ -620,5 +651,6 @@
   cWeather         = MSWeather();
   // Release the main table.
-  delete cPKSMS; cPKSMS=0;
+  delete cPKSMS; 
+  cPKSMS=0x0;
 }
 
@@ -649,5 +681,18 @@
   }
   else if (cALMA) {
+    // this needs to be changed in future...
     cAntennaCols->station().put(n, "CHAJNANTOR");
+    cAntennaCols->dishDiameter().put(n, 12.0);
+  }
+  else if (cATF) {
+    //pad name for the antenna is static...
+    String stname="unknown";
+    if (antName.contains("DV")) {
+       stname="PAD001";
+    }
+    if (antName.contains("DA")) {
+       stname="PAD002";
+    }
+    cAntennaCols->station().put(n, stname);
     cAntennaCols->dishDiameter().put(n, 12.0);
   }
@@ -1095,9 +1140,9 @@
 
 Int PKSMS2writer::addStateEntry(
-        const String obsMode)
+        const String obsType)
 {
   // Look for an entry in the STATE subtable.
   for (uInt n = 0; n < cStateCols->nrow(); n++) {
-    if (cStateCols->obsMode()(n) == obsMode) {
+    if (cStateCols->obsMode()(n) == obsType) {
       return n;
     }
@@ -1109,8 +1154,8 @@
 
   // Data.
-  if (obsMode.contains("RF")) {
+  if (obsType.contains("RF")) {
     cStateCols->sig().put(n, False);
     cStateCols->ref().put(n, True);
-  } else if (!obsMode.contains("PA")) {
+  } else if (!obsType.contains("PA")) {
     // Signal and reference are both false for "paddle" data.
     cStateCols->sig().put(n, True);
@@ -1121,5 +1166,5 @@
   cStateCols->cal().put(n, 0.0);
   cStateCols->subScan().put(n, 0);
-  cStateCols->obsMode().put(n, obsMode);
+  cStateCols->obsMode().put(n, obsType);
 
   // Flags.
