| [1325] | 1 | //#--------------------------------------------------------------------------- | 
|---|
|  | 2 | //# PKSMS2writer.cc: Class to write Parkes multibeam data to a measurementset. | 
|---|
|  | 3 | //#--------------------------------------------------------------------------- | 
|---|
| [1720] | 4 | //# livedata - processing pipeline for single-dish, multibeam spectral data. | 
|---|
|  | 5 | //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO | 
|---|
| [1325] | 6 | //# | 
|---|
| [1720] | 7 | //# This file is part of livedata. | 
|---|
| [1325] | 8 | //# | 
|---|
| [1720] | 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. | 
|---|
| [1325] | 13 | //# | 
|---|
| [1720] | 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. | 
|---|
| [1325] | 18 | //# | 
|---|
| [1720] | 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/>. | 
|---|
| [1325] | 21 | //# | 
|---|
| [1720] | 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 $ | 
|---|
| [1325] | 32 | //#--------------------------------------------------------------------------- | 
|---|
|  | 33 |  | 
|---|
| [1452] | 34 | #include <atnf/PKSIO/PKSrecord.h> | 
|---|
| [1325] | 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> | 
|---|
| [1779] | 44 | #include <casa/Logging/LogIO.h> | 
|---|
| [1325] | 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 |  | 
|---|
| [1779] | 55 | // Class name | 
|---|
|  | 56 | const string className = "PKSMS2writer" ; | 
|---|
|  | 57 |  | 
|---|
| [1325] | 58 | //------------------------------------------------- PKSMS2writer::PKSMS2writer | 
|---|
|  | 59 |  | 
|---|
|  | 60 | // Default constructor. | 
|---|
|  | 61 |  | 
|---|
|  | 62 | PKSMS2writer::PKSMS2writer() | 
|---|
|  | 63 | { | 
|---|
| [1452] | 64 | cPKSMS = 0x0; | 
|---|
| [1325] | 65 | } | 
|---|
|  | 66 |  | 
|---|
|  | 67 | //------------------------------------------------ PKSMS2writer::~PKSMS2writer | 
|---|
|  | 68 |  | 
|---|
|  | 69 | // Destructor. | 
|---|
|  | 70 |  | 
|---|
|  | 71 | PKSMS2writer::~PKSMS2writer() | 
|---|
|  | 72 | { | 
|---|
|  | 73 | close(); | 
|---|
|  | 74 | } | 
|---|
|  | 75 |  | 
|---|
|  | 76 | //------------------------------------------------------- PKSMS2writer::create | 
|---|
|  | 77 |  | 
|---|
|  | 78 | // Create the output MS and and write static data. | 
|---|
|  | 79 |  | 
|---|
|  | 80 | Int 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, | 
|---|
| [1399] | 87 | const String bunit, | 
|---|
| [1325] | 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 | { | 
|---|
| [1779] | 95 | const string methodName = "create()" ; | 
|---|
|  | 96 | LogIO os( LogOrigin( className, methodName, WHERE ) ) ; | 
|---|
|  | 97 |  | 
|---|
| [1452] | 98 | if (cPKSMS) { | 
|---|
| [1779] | 99 | os << LogIO::SEVERE << "Output MS already open, close it first." << LogIO::POST ; | 
|---|
| [1452] | 100 | return 1; | 
|---|
|  | 101 | } | 
|---|
|  | 102 |  | 
|---|
| [1325] | 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); | 
|---|
| [1779] | 111 | cGBT = cAPEX = cSMT = cALMA = cATF = False; | 
|---|
| [1325] | 112 |  | 
|---|
| [1779] | 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 |  | 
|---|
| [1325] | 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); | 
|---|
| [1779] | 138 | //pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). | 
|---|
|  | 139 | //              define("UNIT", String("Jy")); | 
|---|
| [1325] | 140 | pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). | 
|---|
| [1399] | 141 | define("UNIT", bunit); | 
|---|
| [1325] | 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", | 
|---|
| [1635] | 150 | IPosition(2,24,maxNPol), ColumnDesc::Direct)); | 
|---|
| [1325] | 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); | 
|---|
| [1779] | 160 | //pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). | 
|---|
|  | 161 | //            define("UNIT", "Jy"); | 
|---|
| [1325] | 162 | pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). | 
|---|
| [1399] | 163 | define("UNIT", bunit); | 
|---|
| [1325] | 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 |  | 
|---|
| [1779] | 178 | // Use TiledShapeStMan for the FLOAT_DATA hypercube with tile size 1 MB. | 
|---|
|  | 179 | TiledShapeStMan tiledStMan("TiledData", IPosition(3,1,128,2048)); | 
|---|
| [1325] | 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"); | 
|---|
| [1779] | 393 | } else if (dopplerFrame == "LSRK") { | 
|---|
|  | 394 | MFrequency::getType(cDopplerFrame, "LSRK"); | 
|---|
| [1325] | 395 | } | 
|---|
|  | 396 |  | 
|---|
|  | 397 |  | 
|---|
|  | 398 | // Store static data. | 
|---|
|  | 399 | addAntennaEntry(antName, antPosition); | 
|---|
|  | 400 | addDopplerEntry(); | 
|---|
|  | 401 | addFeedEntry(); | 
|---|
| [1779] | 402 | //addObservationEntry(observer, project); | 
|---|
|  | 403 | addObservationEntry(observer, project, telName); | 
|---|
| [1325] | 404 | addProcessorEntry(); | 
|---|
|  | 405 |  | 
|---|
|  | 406 | return 0; | 
|---|
|  | 407 | } | 
|---|
|  | 408 |  | 
|---|
|  | 409 | //-------------------------------------------------------- PKSMS2writer::write | 
|---|
|  | 410 |  | 
|---|
|  | 411 | // Write the next data record. | 
|---|
|  | 412 |  | 
|---|
| [1779] | 413 | /** | 
|---|
| [1325] | 414 | Int PKSMS2writer::write( | 
|---|
| [1779] | 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 | **/ | 
|---|
|  | 459 | Int PKSMS2writer::write( | 
|---|
| [1452] | 460 | const PKSrecord &pksrec) | 
|---|
| [1325] | 461 | { | 
|---|
|  | 462 | // Extend the time range in the OBSERVATION subtable. | 
|---|
|  | 463 | Vector<Double> timerange(2); | 
|---|
|  | 464 | cObservationCols->timeRange().get(0, timerange); | 
|---|
| [1452] | 465 | Double time = pksrec.mjd*86400.0; | 
|---|
| [1325] | 466 | if (timerange(0) == 0.0) { | 
|---|
|  | 467 | timerange(0) = time; | 
|---|
|  | 468 | } | 
|---|
|  | 469 | timerange(1) = time; | 
|---|
|  | 470 | cObservationCols->timeRange().put(0, timerange); | 
|---|
|  | 471 |  | 
|---|
| [1452] | 472 | Int iIF = pksrec.IFno - 1; | 
|---|
| [1325] | 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. | 
|---|
| [1452] | 478 | if (Int(cDataDescription.nrow()) < pksrec.IFno) { | 
|---|
| [1325] | 479 | // Add a new entry to each subtable. | 
|---|
| [1452] | 480 | addDataDescriptionEntry(pksrec.IFno); | 
|---|
|  | 481 | addSpectralWindowEntry(pksrec.IFno, nChan, pksrec.refFreq, | 
|---|
|  | 482 | pksrec.bandwidth, pksrec.freqInc); | 
|---|
|  | 483 | addPolarizationEntry(pksrec.IFno, nPol); | 
|---|
| [1325] | 484 | } | 
|---|
|  | 485 |  | 
|---|
|  | 486 | // Find or add the source to the SOURCE subtable. | 
|---|
| [1452] | 487 | Int srcId = addSourceEntry(pksrec.srcName, pksrec.srcDir, pksrec.srcPM, | 
|---|
|  | 488 | pksrec.restFreq, pksrec.srcVel); | 
|---|
| [1325] | 489 |  | 
|---|
| [1779] | 490 | // Find or add the obsMode to the STATE subtable. | 
|---|
| [1452] | 491 | Int stateId = addStateEntry(pksrec.obsType); | 
|---|
| [1325] | 492 |  | 
|---|
|  | 493 | // FIELD subtable. | 
|---|
| [1779] | 494 | //Vector<Double> scanRate(2); | 
|---|
|  | 495 | //scanRate(0) = pksrec.scanRate(0); | 
|---|
|  | 496 | //scanRate(1) = pksrec.scanRate(1); | 
|---|
| [1452] | 497 | Int fieldId = addFieldEntry(pksrec.fieldName, time, pksrec.direction, | 
|---|
| [1779] | 498 | pksrec.scanRate, srcId); | 
|---|
| [1325] | 499 |  | 
|---|
|  | 500 | // POINTING subtable. | 
|---|
| [1452] | 501 | addPointingEntry(time, pksrec.interval, pksrec.fieldName, pksrec.direction, | 
|---|
| [1779] | 502 | pksrec.scanRate); | 
|---|
| [1325] | 503 |  | 
|---|
|  | 504 | // SYSCAL subtable. | 
|---|
| [1452] | 505 | addSysCalEntry(pksrec.beamNo, iIF, time, pksrec.interval, pksrec.tcal, | 
|---|
| [1779] | 506 | pksrec.tsys, nPol); | 
|---|
| [1325] | 507 |  | 
|---|
|  | 508 | // Handle weather information. | 
|---|
|  | 509 | ROScalarColumn<Double> wTime(cWeather, "TIME"); | 
|---|
|  | 510 | Int nWeather = wTime.nrow(); | 
|---|
|  | 511 | if (nWeather == 0 || time > wTime(nWeather-1)) { | 
|---|
| [1452] | 512 | addWeatherEntry(time, pksrec.interval, pksrec.pressure, pksrec.humidity, | 
|---|
|  | 513 | pksrec.temperature); | 
|---|
| [1325] | 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); | 
|---|
| [1452] | 525 | cMSCols->feed1().put(irow, pksrec.beamNo-1); | 
|---|
|  | 526 | cMSCols->feed2().put(irow, pksrec.beamNo-1); | 
|---|
| [1325] | 527 | cMSCols->dataDescId().put(irow, iIF); | 
|---|
|  | 528 | cMSCols->processorId().put(irow, 0); | 
|---|
|  | 529 | cMSCols->fieldId().put(irow, fieldId); | 
|---|
|  | 530 |  | 
|---|
|  | 531 | // Non-key attributes. | 
|---|
| [1452] | 532 | cMSCols->interval().put(irow, pksrec.interval); | 
|---|
|  | 533 | cMSCols->exposure().put(irow, pksrec.interval); | 
|---|
| [1325] | 534 | cMSCols->timeCentroid().put(irow, time); | 
|---|
| [1452] | 535 | cMSCols->scanNumber().put(irow, pksrec.scanNo); | 
|---|
| [1325] | 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) { | 
|---|
| [1452] | 545 | cBaseLinCol->put(irow, pksrec.baseLin); | 
|---|
| [1325] | 546 |  | 
|---|
| [1635] | 547 | if (pksrec.baseSub.nrow() == 24) { | 
|---|
| [1452] | 548 | cBaseSubCol->put(irow, pksrec.baseSub); | 
|---|
| [1325] | 549 |  | 
|---|
|  | 550 | } else { | 
|---|
| [1635] | 551 | Matrix<Float> tmp(24, 2, 0.0f); | 
|---|
| [1325] | 552 | for (Int ipol = 0; ipol < nPol; ipol++) { | 
|---|
| [1452] | 553 | for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) { | 
|---|
|  | 554 | tmp(j,ipol) = pksrec.baseSub(j,ipol); | 
|---|
| [1325] | 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++) { | 
|---|
| [1452] | 566 | tmpData(ipol,ichan) = pksrec.spectra(ichan,ipol); | 
|---|
|  | 567 | tmpFlag(ipol,ichan) = pksrec.flagged(ichan,ipol); | 
|---|
| [1325] | 568 | } | 
|---|
|  | 569 | } | 
|---|
|  | 570 |  | 
|---|
| [1452] | 571 | cCalFctrCol->put(irow, pksrec.calFctr); | 
|---|
| [1325] | 572 | cMSCols->floatData().put(irow, tmpData); | 
|---|
|  | 573 | cMSCols->flag().put(irow, tmpFlag); | 
|---|
|  | 574 |  | 
|---|
|  | 575 | // Cross-polarization spectra. | 
|---|
|  | 576 | if (cHaveXPol(iIF)) { | 
|---|
| [1452] | 577 | cXCalFctrCol->put(irow, pksrec.xCalFctr); | 
|---|
|  | 578 | cMSCols->data().put(irow, pksrec.xPol); | 
|---|
| [1325] | 579 | } | 
|---|
|  | 580 |  | 
|---|
| [1452] | 581 | cMSCols->sigma().put(irow, pksrec.sigma); | 
|---|
| [1325] | 582 |  | 
|---|
| [1779] | 583 | //Vector<Float> weight(1, 1.0f); | 
|---|
|  | 584 | Vector<Float> weight(nPol, 1.0f); | 
|---|
| [1325] | 585 | cMSCols->weight().put(irow, weight); | 
|---|
| [1779] | 586 | //imaging weight | 
|---|
|  | 587 | //Vector<Float> imagingWeight(nChan); | 
|---|
|  | 588 | //cMSCols->imagingWeight().put(irow, imagingWeight); | 
|---|
| [1325] | 589 |  | 
|---|
|  | 590 | // Flag information. | 
|---|
|  | 591 | Cube<Bool> flags(nPol, nChan, 1, False); | 
|---|
| [1779] | 592 | //cMSCols->flag().put(irow, flags.xyPlane(0)); | 
|---|
| [1325] | 593 | cMSCols->flagCategory().put(irow, flags); | 
|---|
| [1779] | 594 | // Row-based flagging info. (True:>0, False:0) | 
|---|
|  | 595 | cMSCols->flagRow().put(irow, (pksrec.flagrow > 0)); | 
|---|
| [1325] | 596 |  | 
|---|
| [1779] | 597 |  | 
|---|
| [1325] | 598 | return 0; | 
|---|
|  | 599 | } | 
|---|
|  | 600 |  | 
|---|
|  | 601 | //-------------------------------------------------------- PKSMS2writer::close | 
|---|
|  | 602 |  | 
|---|
|  | 603 | // Close the measurementset, flushing all associated tables. | 
|---|
|  | 604 |  | 
|---|
|  | 605 | void 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 | } | 
|---|
| [1399] | 634 |  | 
|---|
| [1325] | 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. | 
|---|
| [1779] | 653 | delete cPKSMS; | 
|---|
|  | 654 | cPKSMS=0x0; | 
|---|
| [1325] | 655 | } | 
|---|
|  | 656 |  | 
|---|
|  | 657 | //---------------------------------------------- PKSMS2writer::addAntennaEntry | 
|---|
|  | 658 |  | 
|---|
|  | 659 | // Add an entry to the ANTENNA subtable. | 
|---|
|  | 660 |  | 
|---|
|  | 661 | Int 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 |  | 
|---|
| [1779] | 669 | // do specific things for GBT | 
|---|
| [1325] | 670 | // Data. | 
|---|
| [1779] | 671 | // plus some more telescopes | 
|---|
| [1325] | 672 | cAntennaCols->name().put(n, antName); | 
|---|
| [1779] | 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 | } | 
|---|
| [1325] | 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); | 
|---|
| [1779] | 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 | //} | 
|---|
| [1325] | 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 |  | 
|---|
|  | 729 | Int PKSMS2writer::addDataDescriptionEntry( | 
|---|
|  | 730 | const Int IFno) | 
|---|
|  | 731 | { | 
|---|
|  | 732 | // Extend the DATA_DESCRIPTION subtable. | 
|---|
|  | 733 | while (Int(cDataDescription.nrow()) < IFno) { | 
|---|
|  | 734 | cDataDescription.addRow(); | 
|---|
|  | 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 |  | 
|---|
|  | 752 | Int 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 |  | 
|---|
|  | 772 | Int 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 |  | 
|---|
|  | 824 | Int 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 | { | 
|---|
| [1779] | 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 |  | 
|---|
| [1325] | 842 | // Extend the FIELD subtable. | 
|---|
| [1779] | 843 | if (n == nFld) { | 
|---|
|  | 844 | cField.addRow(); | 
|---|
|  | 845 | //Int n = cField.nrow() - 1; | 
|---|
| [1325] | 846 |  | 
|---|
| [1779] | 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); | 
|---|
| [1325] | 856 |  | 
|---|
| [1779] | 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); | 
|---|
| [1325] | 866 |  | 
|---|
| [1779] | 867 | // Flags. | 
|---|
|  | 868 | cFieldCols->flagRow().put(n, False); | 
|---|
|  | 869 | } | 
|---|
| [1325] | 870 |  | 
|---|
|  | 871 | return n; | 
|---|
|  | 872 | } | 
|---|
|  | 873 |  | 
|---|
|  | 874 | //------------------------------------------ PKSMS2writer::addObservationEntry | 
|---|
|  | 875 |  | 
|---|
|  | 876 | // Add an entry to the OBSERVATION subtable. | 
|---|
|  | 877 |  | 
|---|
|  | 878 | Int PKSMS2writer::addObservationEntry( | 
|---|
|  | 879 | const String observer, | 
|---|
| [1779] | 880 | const String project, | 
|---|
|  | 881 | const String antName) | 
|---|
| [1325] | 882 | { | 
|---|
|  | 883 | // Extend the OBSERVATION subtable. | 
|---|
|  | 884 | cObservation.addRow(); | 
|---|
|  | 885 | Int n = cObservation.nrow() - 1; | 
|---|
|  | 886 |  | 
|---|
|  | 887 | // Data. | 
|---|
| [1779] | 888 | //cObservationCols->telescopeName().put(n, "Parkes"); | 
|---|
|  | 889 | cObservationCols->telescopeName().put(n, antName); | 
|---|
| [1325] | 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); | 
|---|
| [1779] | 895 | //cObservationCols->scheduleType().put(n, "ATNF"); | 
|---|
|  | 896 | cObservationCols->scheduleType().put(n, ""); | 
|---|
| [1325] | 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 |  | 
|---|
| [1779] | 910 | // Modified to fill pointing data if the direction is the pointing direction. | 
|---|
|  | 911 | // So the following comment is no longer true. | 
|---|
|  | 912 |  | 
|---|
| [1325] | 913 | // Add an entry to the POINTING subtable.  This compulsory subtable simply | 
|---|
|  | 914 | // duplicates information in the FIELD subtable. | 
|---|
|  | 915 |  | 
|---|
|  | 916 | Int 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 |  | 
|---|
| [1779] | 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 | } | 
|---|
| [1325] | 932 |  | 
|---|
| [1779] | 933 | if (n == ntm) { | 
|---|
|  | 934 | // Extend the POINTING subtable. | 
|---|
|  | 935 | cPointing.addRow(); | 
|---|
|  | 936 | //Int n = cPointing.nrow() - 1; | 
|---|
| [1325] | 937 |  | 
|---|
| [1779] | 938 | // Keys. | 
|---|
|  | 939 | cPointingCols->antennaId().put(n, 0); | 
|---|
|  | 940 | cPointingCols->time().put(n, time); | 
|---|
|  | 941 | cPointingCols->interval().put(n, interval); | 
|---|
| [1325] | 942 |  | 
|---|
| [1779] | 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 | } | 
|---|
| [1325] | 956 | return n; | 
|---|
|  | 957 | } | 
|---|
|  | 958 |  | 
|---|
|  | 959 | //----------------------------------------- PKSMS2writer::addPolarizationEntry | 
|---|
|  | 960 |  | 
|---|
|  | 961 | // Add an entry to the POLARIZATION subtable. | 
|---|
|  | 962 |  | 
|---|
|  | 963 | Int PKSMS2writer::addPolarizationEntry( | 
|---|
|  | 964 | const Int IFno, | 
|---|
|  | 965 | const Int nPol) | 
|---|
|  | 966 | { | 
|---|
|  | 967 | // Extend the POLARIZATION subtable. | 
|---|
|  | 968 | while (Int(cPolarization.nrow()) < IFno) { | 
|---|
|  | 969 | cPolarization.addRow(); | 
|---|
|  | 970 | } | 
|---|
|  | 971 | Int n = IFno - 1; | 
|---|
|  | 972 |  | 
|---|
|  | 973 | // Data description. | 
|---|
|  | 974 | cPolarizationCols->numCorr().put(n, nPol); | 
|---|
|  | 975 |  | 
|---|
|  | 976 | // Data. | 
|---|
|  | 977 | Vector<Int> corrType(2); | 
|---|
| [1779] | 978 | if (nPol == 1) { | 
|---|
|  | 979 | corrType.resize(1); | 
|---|
| [1325] | 980 | corrType(0) = Stokes::XX; | 
|---|
| [1779] | 981 | } | 
|---|
|  | 982 | else { | 
|---|
|  | 983 | //Vector<Int> corrType(2); | 
|---|
|  | 984 | corrType(0) = Stokes::XX; | 
|---|
| [1325] | 985 | corrType(1) = Stokes::YY; | 
|---|
| [1779] | 986 | } | 
|---|
| [1325] | 987 | cPolarizationCols->corrType().put(n, corrType); | 
|---|
|  | 988 |  | 
|---|
|  | 989 | Matrix<Int> corrProduct(2,2,1); | 
|---|
| [1779] | 990 | if (nPol == 1) { | 
|---|
|  | 991 | corrProduct.resize(2,1,1); | 
|---|
|  | 992 | corrProduct(1,0) = 0; | 
|---|
|  | 993 | } | 
|---|
| [1325] | 994 | if (nPol == 2) { | 
|---|
|  | 995 | corrProduct(1,0) = 0; | 
|---|
|  | 996 | corrProduct(0,1) = 0; | 
|---|
|  | 997 | } | 
|---|
|  | 998 | cPolarizationCols->corrProduct().put(n, corrProduct); | 
|---|
|  | 999 |  | 
|---|
|  | 1000 | // Flags. | 
|---|
|  | 1001 | cPolarizationCols->flagRow().put(n, False); | 
|---|
|  | 1002 |  | 
|---|
|  | 1003 | return n; | 
|---|
|  | 1004 | } | 
|---|
|  | 1005 |  | 
|---|
|  | 1006 |  | 
|---|
|  | 1007 | //-------------------------------------------- PKSMS2writer::addProcessorEntry | 
|---|
|  | 1008 |  | 
|---|
|  | 1009 | // Add an entry to the PROCESSOR subtable. | 
|---|
|  | 1010 |  | 
|---|
|  | 1011 | Int PKSMS2writer::addProcessorEntry() | 
|---|
|  | 1012 | { | 
|---|
|  | 1013 | // Extend the PROCESSOR subtable. | 
|---|
|  | 1014 | cProcessor.addRow(); | 
|---|
|  | 1015 | Int n = cProcessor.nrow() - 1; | 
|---|
|  | 1016 |  | 
|---|
|  | 1017 | // Data. | 
|---|
|  | 1018 | cProcessorCols->type().put(n, "SPECTROMETER"); | 
|---|
|  | 1019 | cProcessorCols->subType().put(n, "MULTIBEAM"); | 
|---|
|  | 1020 | cProcessorCols->typeId().put(n, -1); | 
|---|
|  | 1021 | cProcessorCols->modeId().put(n, -1); | 
|---|
|  | 1022 |  | 
|---|
|  | 1023 | // Flags. | 
|---|
|  | 1024 | cProcessorCols->flagRow().put(n, False); | 
|---|
|  | 1025 |  | 
|---|
|  | 1026 | return n; | 
|---|
|  | 1027 | } | 
|---|
|  | 1028 |  | 
|---|
|  | 1029 | //----------------------------------------------- PKSMS2writer::addSourceEntry | 
|---|
|  | 1030 |  | 
|---|
|  | 1031 | // Add an entry to the SOURCE subtable. | 
|---|
|  | 1032 |  | 
|---|
|  | 1033 | Int PKSMS2writer::addSourceEntry( | 
|---|
|  | 1034 | const String name, | 
|---|
|  | 1035 | const Vector<Double> direction, | 
|---|
|  | 1036 | const Vector<Double> properMotion, | 
|---|
| [1779] | 1037 | //const Double restFreq, | 
|---|
|  | 1038 | const Vector<Double> restFreq, | 
|---|
| [1325] | 1039 | const Double radialVelocity) | 
|---|
|  | 1040 | { | 
|---|
|  | 1041 | // Look for an entry in the SOURCE subtable. | 
|---|
|  | 1042 | ROScalarColumn<String> sources(cSource, "NAME"); | 
|---|
|  | 1043 | Int n; | 
|---|
|  | 1044 | Int nSrc = sources.nrow(); | 
|---|
|  | 1045 | for (n = 0; n < nSrc; n++) { | 
|---|
|  | 1046 | if (sources(n) == name) { | 
|---|
|  | 1047 | break; | 
|---|
|  | 1048 | } | 
|---|
|  | 1049 | } | 
|---|
|  | 1050 |  | 
|---|
|  | 1051 | if (n == nSrc) { | 
|---|
|  | 1052 | // Not found, add a new entry to the SOURCE subtable. | 
|---|
|  | 1053 | cSource.addRow(); | 
|---|
|  | 1054 |  | 
|---|
|  | 1055 | // Keys. | 
|---|
|  | 1056 | cSourceCols->sourceId().put(n, n); | 
|---|
|  | 1057 | cSourceCols->time().put(n, 0.0); | 
|---|
|  | 1058 | cSourceCols->interval().put(n, -1.0); | 
|---|
|  | 1059 | cSourceCols->spectralWindowId().put(n, -1); | 
|---|
|  | 1060 |  | 
|---|
|  | 1061 | // Data description. | 
|---|
|  | 1062 | cSourceCols->numLines().put(n, 1); | 
|---|
|  | 1063 |  | 
|---|
|  | 1064 | // Data. | 
|---|
|  | 1065 | cSourceCols->name().put(n, name); | 
|---|
|  | 1066 | cSourceCols->calibrationGroup().put(n, 0); | 
|---|
|  | 1067 | cSourceCols->code().put(n, ""); | 
|---|
|  | 1068 | cSourceCols->direction().put(n, direction); | 
|---|
|  | 1069 | //  Vector<Double> position(3, 0.0); | 
|---|
|  | 1070 | //  cSourceCols->position().put(n, position); | 
|---|
|  | 1071 | cSourceCols->properMotion().put(n, properMotion); | 
|---|
| [1779] | 1072 | //  Vector<Double> restFrequency(1, restFreq); | 
|---|
|  | 1073 | //  cSourceCols->restFrequency().put(n, restFrequency); | 
|---|
|  | 1074 | cSourceCols->restFrequency().put(n, restFreq); | 
|---|
| [1325] | 1075 | Vector<Double> sysvel(1, radialVelocity); | 
|---|
|  | 1076 | cSourceCols->sysvel().put(n, sysvel); | 
|---|
|  | 1077 | } | 
|---|
|  | 1078 |  | 
|---|
|  | 1079 | return n; | 
|---|
|  | 1080 | } | 
|---|
|  | 1081 |  | 
|---|
|  | 1082 | //--------------------------------------- PKSMS2writer::addSpectralWindowEntry | 
|---|
|  | 1083 |  | 
|---|
|  | 1084 | // Add an entry to the SPECTRAL_WINDOW subtable. | 
|---|
|  | 1085 |  | 
|---|
|  | 1086 | Int PKSMS2writer::addSpectralWindowEntry( | 
|---|
|  | 1087 | const Int IFno, | 
|---|
|  | 1088 | const Int nChan, | 
|---|
|  | 1089 | const Double refFreq, | 
|---|
|  | 1090 | const Double bandwidth, | 
|---|
|  | 1091 | const Double freqInc) | 
|---|
|  | 1092 | { | 
|---|
|  | 1093 | // Extend the SPECTRAL_WINDOW subtable. | 
|---|
|  | 1094 | while (Int(cSpectralWindow.nrow()) < IFno) { | 
|---|
|  | 1095 | cSpectralWindow.addRow(); | 
|---|
|  | 1096 | } | 
|---|
|  | 1097 | Int n = IFno - 1; | 
|---|
|  | 1098 |  | 
|---|
|  | 1099 | // Data description. | 
|---|
|  | 1100 | cSpWindowCols->numChan().put(n, nChan); | 
|---|
|  | 1101 |  | 
|---|
|  | 1102 | // Data. | 
|---|
| [1779] | 1103 | //cSpWindowCols->name().put(n, "L-band"); | 
|---|
|  | 1104 | cSpWindowCols->name().put(n, " "); | 
|---|
| [1325] | 1105 | cSpWindowCols->refFrequency().put(n, refFreq); | 
|---|
|  | 1106 |  | 
|---|
|  | 1107 | // 0-relative reference channel number. | 
|---|
|  | 1108 | Double refChan = nChan / 2; | 
|---|
|  | 1109 | Vector<Double> freqs(nChan); | 
|---|
|  | 1110 | for (Int i = 0; i < nChan; i++) { | 
|---|
|  | 1111 | freqs(i) = refFreq + (i - refChan)*freqInc; | 
|---|
|  | 1112 | } | 
|---|
|  | 1113 | cSpWindowCols->chanFreq().put(n, freqs); | 
|---|
|  | 1114 |  | 
|---|
|  | 1115 | Vector<Double> chanWidths(nChan, freqInc); | 
|---|
|  | 1116 | cSpWindowCols->chanWidth().put(n, chanWidths); | 
|---|
|  | 1117 |  | 
|---|
|  | 1118 | cSpWindowCols->measFreqRef().put(n, cDopplerFrame); | 
|---|
|  | 1119 | cSpWindowCols->effectiveBW().put(n, chanWidths); | 
|---|
|  | 1120 |  | 
|---|
|  | 1121 | Vector<Double> resolution(nChan, fabs(freqInc)); | 
|---|
|  | 1122 | cSpWindowCols->resolution().put(n, resolution); | 
|---|
|  | 1123 |  | 
|---|
|  | 1124 | cSpWindowCols->totalBandwidth().put(n, bandwidth); | 
|---|
|  | 1125 | cSpWindowCols->netSideband().put(n, 0); | 
|---|
|  | 1126 | cSpWindowCols->ifConvChain().put(n, -1); | 
|---|
|  | 1127 | cSpWindowCols->freqGroup().put(n, 0); | 
|---|
|  | 1128 | cSpWindowCols->freqGroupName().put(n, " "); | 
|---|
|  | 1129 | cSpWindowCols->dopplerId().put(n, 0); | 
|---|
|  | 1130 |  | 
|---|
|  | 1131 | // Flags. | 
|---|
|  | 1132 | cSpWindowCols->flagRow().put(n, False); | 
|---|
|  | 1133 |  | 
|---|
|  | 1134 | return n; | 
|---|
|  | 1135 | } | 
|---|
|  | 1136 |  | 
|---|
|  | 1137 | //------------------------------------------------ PKSMS2writer::addStateEntry | 
|---|
|  | 1138 |  | 
|---|
|  | 1139 | // Add an entry to the STATE subtable. | 
|---|
|  | 1140 |  | 
|---|
|  | 1141 | Int PKSMS2writer::addStateEntry( | 
|---|
| [1452] | 1142 | const String obsType) | 
|---|
| [1325] | 1143 | { | 
|---|
|  | 1144 | // Look for an entry in the STATE subtable. | 
|---|
|  | 1145 | for (uInt n = 0; n < cStateCols->nrow(); n++) { | 
|---|
| [1452] | 1146 | if (cStateCols->obsMode()(n) == obsType) { | 
|---|
| [1325] | 1147 | return n; | 
|---|
|  | 1148 | } | 
|---|
|  | 1149 | } | 
|---|
|  | 1150 |  | 
|---|
|  | 1151 | // Not found, extend the STATE subtable. | 
|---|
|  | 1152 | cState.addRow(); | 
|---|
|  | 1153 | uInt n = cStateCols->nrow() - 1; | 
|---|
|  | 1154 |  | 
|---|
|  | 1155 | // Data. | 
|---|
| [1452] | 1156 | if (obsType.contains("RF")) { | 
|---|
| [1325] | 1157 | cStateCols->sig().put(n, False); | 
|---|
|  | 1158 | cStateCols->ref().put(n, True); | 
|---|
| [1452] | 1159 | } else if (!obsType.contains("PA")) { | 
|---|
| [1325] | 1160 | // Signal and reference are both false for "paddle" data. | 
|---|
|  | 1161 | cStateCols->sig().put(n, True); | 
|---|
|  | 1162 | cStateCols->ref().put(n, False); | 
|---|
|  | 1163 | } | 
|---|
|  | 1164 |  | 
|---|
|  | 1165 | cStateCols->load().put(n, 0.0); | 
|---|
|  | 1166 | cStateCols->cal().put(n, 0.0); | 
|---|
|  | 1167 | cStateCols->subScan().put(n, 0); | 
|---|
| [1452] | 1168 | cStateCols->obsMode().put(n, obsType); | 
|---|
| [1325] | 1169 |  | 
|---|
|  | 1170 | // Flags. | 
|---|
|  | 1171 | cStateCols->flagRow().put(n, False); | 
|---|
|  | 1172 |  | 
|---|
|  | 1173 | return n; | 
|---|
|  | 1174 | } | 
|---|
|  | 1175 |  | 
|---|
|  | 1176 | //----------------------------------------------- PKSMS2writer::addSysCalEntry | 
|---|
|  | 1177 |  | 
|---|
|  | 1178 | // Add an entry to the SYSCAL subtable. | 
|---|
|  | 1179 |  | 
|---|
|  | 1180 | Int PKSMS2writer::addSysCalEntry( | 
|---|
|  | 1181 | const Int beamNo, | 
|---|
|  | 1182 | const Int spWinId, | 
|---|
|  | 1183 | const Double time, | 
|---|
|  | 1184 | const Double interval, | 
|---|
|  | 1185 | const Vector<Float> tcal, | 
|---|
| [1779] | 1186 | const Vector<Float> tsys, | 
|---|
|  | 1187 | const Int nPol) | 
|---|
| [1325] | 1188 | { | 
|---|
| [1779] | 1189 | LogIO os(LogOrigin("PKSMS2writer", "addSysCalEntry()", WHERE)); | 
|---|
|  | 1190 |  | 
|---|
| [1325] | 1191 | // Extend the SYSCAL subtable. | 
|---|
|  | 1192 | cSysCal.addRow(); | 
|---|
|  | 1193 | Int n = cSysCal.nrow() - 1; | 
|---|
|  | 1194 |  | 
|---|
| [1779] | 1195 | //check fo consistency with n pol | 
|---|
|  | 1196 | //here assume size of Tcal vector = npol | 
|---|
|  | 1197 | Vector<Float> inTcal(nPol,0); | 
|---|
|  | 1198 | Int ndim = tcal.shape()(0); | 
|---|
|  | 1199 | Vector<Float> tmpTcal = tcal; | 
|---|
|  | 1200 | if (nPol != ndim) { | 
|---|
|  | 1201 | os << LogIO::WARN | 
|---|
|  | 1202 | << "Found "<< ndim <<" Tcal value(s) for the data with "<<nPol<<" polarization(s)" | 
|---|
|  | 1203 | << "(expecting one Tcal per pol)."<<endl | 
|---|
|  | 1204 | << "First "<< nPol << " Tcal value(s) will be filled." << LogIO::POST; | 
|---|
|  | 1205 | tmpTcal.resize(nPol, True); | 
|---|
|  | 1206 | inTcal = tmpTcal; | 
|---|
|  | 1207 | } | 
|---|
| [1325] | 1208 | // Keys. | 
|---|
|  | 1209 | cSysCalCols->antennaId().put(n, 0); | 
|---|
|  | 1210 | cSysCalCols->feedId().put(n, beamNo-1); | 
|---|
|  | 1211 | cSysCalCols->spectralWindowId().put(n, spWinId); | 
|---|
|  | 1212 | cSysCalCols->time().put(n, time); | 
|---|
|  | 1213 | cSysCalCols->interval().put(n, interval); | 
|---|
|  | 1214 |  | 
|---|
|  | 1215 | // Data. | 
|---|
| [1779] | 1216 | //cSysCalCols->tcal().put(n, tcal); | 
|---|
|  | 1217 | cSysCalCols->tcal().put(n, inTcal); | 
|---|
| [1325] | 1218 | cSysCalCols->tsys().put(n, tsys); | 
|---|
|  | 1219 |  | 
|---|
|  | 1220 | return n; | 
|---|
|  | 1221 | } | 
|---|
|  | 1222 |  | 
|---|
|  | 1223 | //---------------------------------------------- PKSMS2writer::addWeatherEntry | 
|---|
|  | 1224 |  | 
|---|
|  | 1225 | // Add an entry to the WEATHER subtable. | 
|---|
|  | 1226 |  | 
|---|
|  | 1227 | Int PKSMS2writer::addWeatherEntry( | 
|---|
|  | 1228 | const Double time, | 
|---|
|  | 1229 | const Double interval, | 
|---|
|  | 1230 | const Double pressure, | 
|---|
|  | 1231 | const Double relHumidity, | 
|---|
|  | 1232 | const Double temperature) | 
|---|
|  | 1233 | { | 
|---|
|  | 1234 | // Extend the WEATHER subtable. | 
|---|
|  | 1235 | cWeather.addRow(); | 
|---|
|  | 1236 | Int n = cWeather.nrow() - 1; | 
|---|
|  | 1237 |  | 
|---|
|  | 1238 | // Keys. | 
|---|
|  | 1239 | cWeatherCols->antennaId().put(n, 0); | 
|---|
|  | 1240 | cWeatherCols->time().put(n, time); | 
|---|
|  | 1241 | cWeatherCols->interval().put(n, interval); | 
|---|
|  | 1242 |  | 
|---|
|  | 1243 | // Data. | 
|---|
|  | 1244 | cWeatherCols->pressure().put(n, pressure); | 
|---|
|  | 1245 | cWeatherCols->relHumidity().put(n, relHumidity); | 
|---|
|  | 1246 | cWeatherCols->temperature().put(n, temperature); | 
|---|
|  | 1247 |  | 
|---|
|  | 1248 | return n; | 
|---|
|  | 1249 | } | 
|---|