source: trunk/external-alma/atnf/PKSIO/PKSMS2reader.cc@ 2965

Last change on this file since 2965 was 2343, checked in by Takeshi Nakazato, 13 years ago

New Development: No

JIRA Issue: No

Ready for Test: Yes

Interface Changes: 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...

Patch from Wes.
This is changes intend to compile with llvm c++ and Intel
and those might not affect actual behavior.


File size: 42.5 KB
Line 
1//#---------------------------------------------------------------------------
2//# PKSMS2reader.cc: Class to read Parkes Multibeam data from a v2 MS.
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: PKSMS2reader.cc,v 19.23 2009-09-29 07:33:38 cal103 Exp $
32//#---------------------------------------------------------------------------
33//# Original: 2000/08/03, Mark Calabretta, ATNF
34//#---------------------------------------------------------------------------
35
36// AIPS++ includes.
37#include <casa/stdio.h>
38#include <casa/Arrays/ArrayMath.h>
39#include <casa/Arrays/Slice.h>
40#include <ms/MeasurementSets/MSColumns.h>
41#include <tables/Tables.h>
42#include <casa/Quanta/MVTime.h>
43#include <casa/Quanta/MVAngle.h>
44#include <casa/BasicMath/Math.h>
45#include <casa/Logging/LogIO.h>
46#include <casa/Utilities/Sort.h>
47#include <measures/Measures/MeasConvert.h>
48#include <measures/Measures/MEpoch.h>
49#include <measures/Measures/MeasRef.h>
50
51
52// Parkes includes.
53#include <atnf/pks/pks_maths.h>
54#include <atnf/PKSIO/PKSrecord.h>
55#include <atnf/PKSIO/PKSMS2reader.h>
56
57
58//------------------------------------------------- PKSMS2reader::PKSMS2reader
59
60// Default constructor.
61
62PKSMS2reader::PKSMS2reader()
63{
64 cMSopen = False;
65}
66
67//------------------------------------------------ PKSMS2reader::~PKSMS2reader
68
69PKSMS2reader::~PKSMS2reader()
70{
71 close();
72}
73
74//--------------------------------------------------------- PKSMS2reader::open
75
76// Open the MS for reading.
77
78Int PKSMS2reader::open(
79 const String msName,
80 const String antenna,
81 Vector<Bool> &beams,
82 Vector<Bool> &IFs,
83 Vector<uInt> &nChan,
84 Vector<uInt> &nPol,
85 Vector<Bool> &haveXPol,
86 Bool &haveBase,
87 Bool &haveSpectra)
88{
89 // Check that MS is readable.
90 if (!MS::isReadable(msName)) {
91 return 1;
92 }
93
94 if (cMSopen) {
95 close();
96 }
97
98 cPKSMS = MeasurementSet(msName);
99
100 // data selection by antenna
101 if ( antenna.length() == 0 ) {
102 cAntId.resize( 1 ) ;
103 //cAntId[0] = 0 ;
104 ROScalarColumn<Int> ant1Col( cPKSMS, "ANTENNA1" ) ;
105 cAntId[0] = ant1Col(0) ;
106 }
107 else {
108 setupAntennaList( antenna ) ;
109 if ( cAntId.size() > 1 ) {
110 LogIO os( LogOrigin( "PKSMS2reader", "open()", WHERE ) ) ;
111 os << LogIO::WARN << "PKSMS2reader is not ready for multiple antenna selection. Use first antenna id " << cAntId[0] << "."<< LogIO::POST ;
112 Int tmp = cAntId[0] ;
113 cAntId.resize( 1 ) ;
114 cAntId[0] = tmp ;
115 }
116 stringstream ss ;
117 ss << "SELECT FROM $1 WHERE ANTENNA1 == ANTENNA2 && ANTENNA1 IN [" ;
118 for ( uInt i = 0 ; i < cAntId.size() ; i++ ) {
119 ss << cAntId[i] ;
120 if ( i == cAntId.size()-1 ) {
121 ss << "]" ;
122 }
123 else {
124 ss << "," ;
125 }
126 }
127 string taql = ss.str() ;
128 //cerr << "taql = " << taql << endl ;
129 cPKSMS = MeasurementSet( tableCommand( taql, cPKSMS ) ) ;
130 }
131
132 // taql access to the syscal table
133 cHaveSysCal = False;
134 if (cHaveSysCal=Table::isReadable(cPKSMS.sysCalTableName())) {
135 cSysCalTab = Table(cPKSMS.sysCalTableName());
136 }
137
138 // Lock the table for read access.
139 cPKSMS.lock(False);
140
141 cIdx = 0;
142 lastmjd = 0.0;
143 cNRow = cPKSMS.nrow();
144 cMSopen = True;
145
146 // Main MS table and subtable column access.
147 ROMSMainColumns msCols(cPKSMS);
148 ROMSDataDescColumns dataDescCols(cPKSMS.dataDescription());
149 ROMSFeedColumns feedCols(cPKSMS.feed());
150 ROMSFieldColumns fieldCols(cPKSMS.field());
151 ROMSPointingColumns pointingCols(cPKSMS.pointing());
152 ROMSPolarizationColumns polarizationCols(cPKSMS.polarization());
153 ROMSSourceColumns sourceCols(cPKSMS.source());
154 ROMSSpWindowColumns spWinCols(cPKSMS.spectralWindow());
155 ROMSStateColumns stateCols(cPKSMS.state());
156 ROMSSysCalColumns sysCalCols(cPKSMS.sysCal());
157 ROMSWeatherColumns weatherCols(cPKSMS.weather());
158 ROMSAntennaColumns antennaCols(cPKSMS.antenna());
159
160 // Column accessors for required columns.
161 cScanNoCol.reference(msCols.scanNumber());
162 cTimeCol.reference(msCols.time());
163 cIntervalCol.reference(msCols.interval());
164
165 cFieldIdCol.reference(msCols.fieldId());
166 cFieldNameCol.reference(fieldCols.name());
167 cFieldDelayDirCol.reference(fieldCols.delayDir());
168
169 cSrcIdCol.reference(fieldCols.sourceId());
170 cSrcId2Col.reference(sourceCols.sourceId());
171 cSrcNameCol.reference(sourceCols.name());
172 cSrcDirCol.reference(sourceCols.direction());
173 cSrcPMCol.reference(sourceCols.properMotion());
174 cSrcRestFrqCol.reference(sourceCols.restFrequency());
175
176 cStateIdCol.reference(msCols.stateId());
177 cObsModeCol.reference(stateCols.obsMode());
178 cCalCol.reference(stateCols.cal());
179 cSigStateCol.reference(stateCols.sig());
180 cRefStateCol.reference(stateCols.ref());
181
182 cDataDescIdCol.reference(msCols.dataDescId());
183 cSpWinIdCol.reference(dataDescCols.spectralWindowId());
184 cChanFreqCol.reference(spWinCols.chanFreq());
185 cTotBWCol.reference(spWinCols.totalBandwidth());
186
187 cWeatherTimeCol.reference(weatherCols.time());
188 cTemperatureCol.reference(weatherCols.temperature());
189 cPressureCol.reference(weatherCols.pressure());
190 cHumidityCol.reference(weatherCols.relHumidity());
191
192 cBeamNoCol.reference(msCols.feed1());
193 cPointingCol.reference(pointingCols.direction());
194 cPointingTimeCol.reference(pointingCols.time());
195 cSigmaCol.reference(msCols.sigma());
196 cNumReceptorCol.reference(feedCols.numReceptors());
197
198 // Optional columns.
199 cHaveTsys = False;
200 cHaveTcal = False;
201 if ((cHaveSrcVel = cPKSMS.source().tableDesc().isColumn("SYSVEL"))) {
202 cSrcVelCol.attach(cPKSMS.source(), "SYSVEL");
203 }
204
205 if (cHaveSysCal && (cHaveTsys = cPKSMS.sysCal().tableDesc().isColumn("TSYS"))) {
206 cTsysCol.attach(cPKSMS.sysCal(), "TSYS");
207 }
208
209 if (cHaveSysCal && (cHaveTcal = cPKSMS.sysCal().tableDesc().isColumn("TCAL"))) {
210 cTcalCol.attach(cPKSMS.sysCal(), "TCAL");
211 }
212
213 if ((cHaveCalFctr = cPKSMS.tableDesc().isColumn("CALFCTR"))) {
214 cCalFctrCol.attach(cPKSMS, "CALFCTR");
215 }
216
217 if ((cHaveBaseLin = cPKSMS.tableDesc().isColumn("BASELIN"))) {
218 cBaseLinCol.attach(cPKSMS, "BASELIN");
219 cBaseSubCol.attach(cPKSMS, "BASESUB");
220 }
221
222 // Spectral data should always be present.
223 haveSpectra = True;
224 cHaveDataCol = False;
225 cHaveCorrectedDataCol = False;
226 ROMSObservationColumns observationCols(cPKSMS.observation());
227 //String telName = observationCols.telescopeName()(0);
228 cTelName = observationCols.telescopeName()(0);
229 //cATF = cTelName.contains("ATF");
230 //cOSF = cTelName.contains("OSF");
231 //cALMA = cTelName.contains("ALMA");
232 cALMA = cTelName.contains("ATF")||cTelName.contains("OSF")||
233 cTelName.contains("ALMA");
234
235 if (cHaveDataCol = cPKSMS.isColumn(MSMainEnums::DATA)) {
236 if (cALMA) {
237 //try to read a single baseline interferometeric data
238 //and treat it as single dish data
239 //maybe extended for ALMA commissioning later
240 cDataCol.reference(msCols.data());
241 if (cHaveCorrectedDataCol = cPKSMS.isColumn(MSMainEnums::CORRECTED_DATA)) {
242 //cerr<<"Do have CORRECTED_DATA column"<<endl;
243 cCorrectedDataCol.reference(msCols.correctedData());
244 }
245 }
246 }
247 else {
248 cFloatDataCol.reference(msCols.floatData());
249 }
250 cFlagCol.reference(msCols.flag());
251 cFlagRowCol.reference(msCols.flagRow());
252
253 if (cGetXPol = (cPKSMS.isColumn(MSMainEnums::DATA) && (!cALMA))) {
254 if ((cHaveXCalFctr = cPKSMS.tableDesc().isColumn("XCALFCTR"))) {
255 cXCalFctrCol.attach(cPKSMS, "XCALFCTR");
256 }
257
258 cDataCol.reference(msCols.data());
259 }
260
261 // Find which beams are present in the data.
262 Vector<Int> beamNos = cBeamNoCol.getColumn();
263 Int maxBeamNo = max(beamNos) + 1;
264 beams.resize(maxBeamNo);
265
266 beams = False;
267 for (uInt irow = 0; irow < beamNos.nelements(); irow++) {
268 beams(beamNos(irow)) = True;
269 }
270
271
272 // Number of IFs.
273 //uInt nIF = dataDescCols.nrow();
274 uInt nIF =spWinCols.nrow();
275 Vector<Int> spWinIds = cSpWinIdCol.getColumn() ;
276 IFs.resize(nIF);
277 IFs = True;
278 for ( Int ispw = 0 ; ispw < nIF ; ispw++ ) {
279 if ( allNE( ispw, spWinIds ) ) {
280 IFs(ispw) = False ;
281 }
282 }
283
284 // Number of polarizations and channels in each IF.
285 ROScalarColumn<Int> numChanCol(spWinCols.numChan());
286
287 ROScalarColumn<Int> polIdCol(dataDescCols.polarizationId());
288 ROScalarColumn<Int> numPolCol(polarizationCols.numCorr());
289
290 nChan.resize(nIF);
291 nPol.resize(nIF);
292 for (uInt iIF = 0; iIF < nIF; iIF++) {
293 if ( IFs(iIF) ) {
294 nChan(iIF) = numChanCol(cSpWinIdCol(iIF)) ;
295 nPol(iIF) = numPolCol(polIdCol(iIF)) ;
296 }
297 else {
298 nChan(iIF) = 0 ;
299 nPol(iIF) = 0 ;
300 }
301 }
302
303 // Cross-polarization data present?
304 haveXPol.resize(nIF);
305 haveXPol = False;
306
307 if (cGetXPol && !(cALMA)) {
308 for (Int irow = 0; irow < cNRow; irow++) {
309 if (cDataCol.isDefined(irow)) {
310 Int iIF = cDataDescIdCol(irow);
311 haveXPol(iIF) = True;
312 }
313 }
314 }
315
316
317 // Initialize member data.
318 cBeams.assign(beams);
319 cIFs.assign(IFs);
320 cNChan.assign(nChan);
321 cNPol.assign(nPol);
322 cHaveXPol.assign(haveXPol);
323
324
325 // Default channel range selection.
326 cStartChan.resize(nIF);
327 cEndChan.resize(nIF);
328 cRefChan.resize(nIF);
329
330 for (uInt iIF = 0; iIF < nIF; iIF++) {
331 cStartChan(iIF) = 1;
332 cEndChan(iIF) = cNChan(iIF);
333 cRefChan(iIF) = cNChan(iIF)/2 + 1;
334 }
335
336 Slice all;
337 cDataSel.resize(nIF);
338 cDataSel = Slicer(all, all);
339
340 cScanNo = 0;
341 cCycleNo = 1;
342 cTime = cTimeCol(0);
343
344 return 0;
345}
346
347//---------------------------------------------------- PKSMS2reader::getHeader
348
349// Get parameters describing the data.
350
351Int PKSMS2reader::getHeader(
352 String &observer,
353 String &project,
354 String &antName,
355 Vector<Double> &antPosition,
356 // before merge...
357 //String &obsMode,
358 String &obsType,
359 String &bunit,
360 Float &equinox,
361 String &dopplerFrame,
362 Double &mjd,
363 Double &refFreq,
364 Double &bandwidth)
365{
366 if (!cMSopen) {
367 return 1;
368 }
369
370 // Observer and project.
371 ROMSObservationColumns observationCols(cPKSMS.observation());
372 observer = observationCols.observer()(0);
373 project = observationCols.project()(0);
374
375 // Antenna name and ITRF coordinates.
376 ROMSAntennaColumns antennaCols(cPKSMS.antenna());
377 //antName = antennaCols.name()(0);
378 antName = antennaCols.name()(cAntId[0]);
379 if (cALMA) {
380 antName = cTelName + "-" + antName;
381 }
382 //antPosition = antennaCols.position()(0);
383 antPosition = antennaCols.position()(cAntId[0]);
384
385 // Observation type.
386 if (cObsModeCol.nrow()) {
387 obsType = cObsModeCol(0);
388 if (obsType == "\0") obsType = "RF";
389 } else {
390 obsType = "RF";
391 }
392
393 bunit = "";
394 if (cHaveDataCol) {
395 const TableRecord& keywordSet2
396 = cDataCol.columnDesc().keywordSet();
397 if(keywordSet2.isDefined("UNIT")) {
398 bunit = keywordSet2.asString("UNIT");
399 }
400 } else {
401 const TableRecord& keywordSet
402 = cFloatDataCol.columnDesc().keywordSet();
403 if(keywordSet.isDefined("UNIT")) {
404 bunit = keywordSet.asString("UNIT");
405 }
406 }
407
408/***
409 const TableRecord& keywordSet
410 = cFloatDataCol.columnDesc().keywordSet();
411 if(keywordSet.isDefined("UNIT")) {
412 fluxunit = keywordSet.asString("UNIT");
413 }
414***/
415 // Coordinate equinox.
416 ROMSPointingColumns pointingCols(cPKSMS.pointing());
417 String dirref = pointingCols.direction().keywordSet().asRecord("MEASINFO").
418 asString("Ref");
419 cDirRef = dirref;
420 if (dirref =="AZELGEO" || dirref == "AZEL") {
421 dirref = "J2000";
422 }
423 sscanf(dirref.chars()+1, "%f", &equinox);
424
425 // Frequency/velocity reference frame.
426 ROMSSpWindowColumns spWinCols(cPKSMS.spectralWindow());
427 dopplerFrame = MFrequency::showType(spWinCols.measFreqRef()(0));
428
429 // Translate to FITS standard names.
430 if (dopplerFrame == "TOPO") {
431 dopplerFrame = "TOPOCENT";
432 } else if (dopplerFrame == "GEO") {
433 dopplerFrame = "GEOCENTR";
434 } else if (dopplerFrame == "BARY") {
435 dopplerFrame = "BARYCENT";
436 } else if (dopplerFrame == "GALACTO") {
437 dopplerFrame = "GALACTOC";
438 } else if (dopplerFrame == "LGROUP") {
439 dopplerFrame = "LOCALGRP";
440 } else if (dopplerFrame == "CMB") {
441 dopplerFrame = "CMBDIPOL";
442 } else if (dopplerFrame == "REST") {
443 dopplerFrame = "SOURCE";
444 }
445
446 // MJD at start of observation.
447 mjd = cTimeCol(0)/86400.0;
448
449 // Reference frequency and bandwidth.
450 refFreq = spWinCols.refFrequency()(0);
451 bandwidth = spWinCols.totalBandwidth()(0);
452
453 return 0;
454}
455
456//-------------------------------------------------- PKSMS2reader::getFreqInfo
457
458// Get frequency parameters for each IF.
459
460Int PKSMS2reader::getFreqInfo(
461 Vector<Double> &startFreq,
462 Vector<Double> &endFreq)
463{
464 uInt nIF = cIFs.nelements();
465 startFreq.resize(nIF);
466 endFreq.resize(nIF);
467
468 for (uInt iIF = 0; iIF < nIF; iIF++) {
469 Vector<Double> chanFreq = cChanFreqCol(iIF);
470
471 Int nChan = chanFreq.nelements();
472 startFreq(iIF) = chanFreq(0);
473 endFreq(iIF) = chanFreq(nChan-1);
474 }
475
476 return 0;
477}
478
479//------------------------------------------------------- PKSMS2reader::select
480
481// Set data selection by beam number and channel.
482
483uInt PKSMS2reader::select(
484 const Vector<Bool> beamSel,
485 const Vector<Bool> IFsel,
486 const Vector<Int> startChan,
487 const Vector<Int> endChan,
488 const Vector<Int> refChan,
489 const Bool getSpectra,
490 const Bool getXPol,
491 const Bool getFeedPos,
492 const Bool getPointing,
493 const Int coordSys)
494{
495 if (!cMSopen) {
496 return 1;
497 }
498
499 // Beam selection.
500 uInt nBeam = cBeams.nelements();
501 uInt nBeamSel = beamSel.nelements();
502 for (uInt ibeam = 0; ibeam < nBeam; ibeam++) {
503 if (ibeam < nBeamSel) {
504 cBeams(ibeam) = beamSel(ibeam);
505 } else {
506 cBeams(ibeam) = False;
507 }
508 }
509
510 uInt nIF = cIFs.nelements();
511 uInt maxNChan = 0;
512 for (uInt iIF = 0; iIF < nIF; iIF++) {
513 // IF selection.
514 if (iIF < IFsel.nelements()) {
515 cIFs(iIF) = IFsel(iIF);
516 } else {
517 cIFs(iIF) = False;
518 }
519
520 if (!cIFs(iIF)) continue;
521
522
523 // Channel selection.
524 if (iIF < startChan.nelements()) {
525 cStartChan(iIF) = startChan(iIF);
526
527 if (cStartChan(iIF) <= 0) {
528 cStartChan(iIF) += cNChan(iIF);
529 } else if (cStartChan(iIF) > Int(cNChan(iIF))) {
530 cStartChan(iIF) = cNChan(iIF);
531 }
532 }
533
534 if (iIF < endChan.nelements()) {
535 cEndChan(iIF) = endChan(iIF);
536
537 if (cEndChan(iIF) <= 0) {
538 cEndChan(iIF) += cNChan(iIF);
539 } else if (cEndChan(iIF) > Int(cNChan(iIF))) {
540 cEndChan(iIF) = cNChan(iIF);
541 }
542 }
543
544 if (iIF < refChan.nelements()) {
545 cRefChan(iIF) = refChan(iIF);
546 } else {
547 cRefChan(iIF) = cStartChan(iIF);
548 if (cStartChan(iIF) <= cEndChan(iIF)) {
549 cRefChan(iIF) += (cEndChan(iIF) - cStartChan(iIF) + 1)/2;
550 } else {
551 cRefChan(iIF) -= (cStartChan(iIF) - cEndChan(iIF) + 1)/2;
552 }
553 }
554
555 uInt nChan = abs(cEndChan(iIF) - cStartChan(iIF)) + 1;
556 if (maxNChan < nChan) {
557 maxNChan = nChan;
558 }
559
560 // Inverted Slices are not allowed.
561 Slice outPols;
562 Slice outChans(min(cStartChan(iIF),cEndChan(iIF))-1, nChan);
563 cDataSel(iIF) = Slicer(outPols, outChans);
564 }
565
566 // Get spectral data?
567 cGetSpectra = getSpectra;
568
569 // Get cross-polarization data?
570 cGetXPol = cGetXPol && getXPol;
571
572 // Get feed positions? (Not available.)
573 cGetFeedPos = False;
574
575 // Get Pointing data (for MS)
576 cGetPointing = getPointing;
577
578 // Coordinate system? (Only equatorial available.)
579 cCoordSys = 0;
580
581 return maxNChan;
582}
583
584//---------------------------------------------------- PKSMS2reader::findRange
585
586// Find the range of the data in time and position.
587
588Int PKSMS2reader::findRange(
589 Int &nRow,
590 Int &nSel,
591 Vector<Double> &timeSpan,
592 Matrix<Double> &positions)
593{
594 if (!cMSopen) {
595 return 1;
596 }
597
598 nRow = cNRow;
599
600 // Find the number of rows selected.
601 nSel = 0;
602 Vector<Bool> sel(nRow);
603 for (Int irow = 0; irow < nRow; irow++) {
604 if ((sel(irow) = cBeams(cBeamNoCol(irow)) &&
605 cIFs(cDataDescIdCol(irow)))) {
606 nSel++;
607 }
608 }
609
610 // Find the time range (s).
611 timeSpan.resize(2);
612 timeSpan(0) = cTimeCol(0);
613 timeSpan(1) = cTimeCol(nRow-1);
614
615 // Retrieve positions for selected data.
616 Int isel = 0;
617 positions.resize(2,nSel);
618 for (Int irow = 0; irow < nRow; irow++) {
619 if (sel(irow)) {
620 Matrix<Double> pointingDir = cPointingCol(cFieldIdCol(irow));
621 positions.column(isel++) = pointingDir.column(0);
622 }
623 }
624
625 return 0;
626}
627
628//--------------------------------------------------------- PKSMS2reader::read
629
630// Read the next data record.
631
632/**
633Int PKSMS2reader::read(
634 Int &scanNo,
635 Int &cycleNo,
636 Double &mjd,
637 Double &interval,
638 String &fieldName,
639 String &srcName,
640 Vector<Double> &srcDir,
641 Vector<Double> &srcPM,
642 Double &srcVel,
643 String &obsMode,
644 Int &IFno,
645 Double &refFreq,
646 Double &bandwidth,
647 Double &freqInc,
648 Vector<Double> &restFreq,
649 Vector<Float> &tcal,
650 String &tcalTime,
651 Float &azimuth,
652 Float &elevation,
653 Float &parAngle,
654 Float &focusAxi,
655 Float &focusTan,
656 Float &focusRot,
657 Float &temperature,
658 Float &pressure,
659 Float &humidity,
660 Float &windSpeed,
661 Float &windAz,
662 Int &refBeam,
663 Int &beamNo,
664 Vector<Double> &direction,
665 Vector<Double> &scanRate,
666 Vector<Float> &tsys,
667 Vector<Float> &sigma,
668 Vector<Float> &calFctr,
669 Matrix<Float> &baseLin,
670 Matrix<Float> &baseSub,
671 Matrix<Float> &spectra,
672 Matrix<uChar> &flagged,
673 uInt &flagrow,
674 Complex &xCalFctr,
675 Vector<Complex> &xPol)
676**/
677Int PKSMS2reader::read(PKSrecord &pksrec)
678{
679 LogIO os( LogOrigin( "PKSMS2reader", "read()", WHERE ) ) ;
680
681 if (!cMSopen) {
682 return 1;
683 }
684
685 // Check for EOF.
686 if (cIdx >= cNRow) {
687 return -1;
688 }
689
690 // Find the next selected beam and IF.
691 Int ibeam;
692 Int iIF;
693 Int iDataDesc;
694
695 while (True) {
696 ibeam = cBeamNoCol(cIdx);
697 iDataDesc = cDataDescIdCol(cIdx);
698 iIF =cSpWinIdCol(iDataDesc);
699 if (cBeams(ibeam) && cIFs(iIF)) {
700 break;
701 }
702
703 // Check for EOF.
704 if (++cIdx >= cNRow) {
705 return -1;
706 }
707 }
708 // Renumerate scan no. Here still is 1-based
709 //scanNo = cScanNoCol(cIdx) - cScanNoCol(0) + 1;
710 //scanNo = cScanNoCol(cIdx);
711 pksrec.scanNo = cScanNoCol(cIdx);
712
713 if (pksrec.scanNo != cScanNo) {
714 // Start of new scan.
715 cScanNo = pksrec.scanNo;
716 cCycleNo = 1;
717 cTime = cTimeCol(cIdx);
718 }
719
720 Double time = cTimeCol(cIdx);
721 pksrec.mjd = time/86400.0;
722 pksrec.interval = cIntervalCol(cIdx);
723
724 // Reconstruct the integration cycle number; due to small latencies the
725 // integration time is usually slightly less than the time between cycles,
726 // resetting cTime will prevent the difference from accumulating.
727 cCycleNo += nint((time - cTime)/pksrec.interval);
728 pksrec.cycleNo = cCycleNo;
729 cTime = time;
730
731 Int fieldId = cFieldIdCol(cIdx);
732 pksrec.fieldName = cFieldNameCol(fieldId);
733
734 Int srcId = cSrcIdCol(fieldId);
735 //For source with multiple spectral window setting, this is not
736 // correct. Source name of srcId may not be at 'srcId'th row of SrcNameCol
737 //srcName = cSrcNameCol(srcId);
738 for (uInt irow = 0; irow < cSrcId2Col.nrow(); irow++) {
739 if (cSrcId2Col(irow) == srcId) {
740 //srcName = cSrcNameCol(irow);
741 pksrec.srcName = cSrcNameCol(irow);
742 }
743 }
744
745 pksrec.srcDir = cSrcDirCol(srcId);
746 pksrec.srcPM = cSrcPMCol(srcId);
747
748 // Systemic velocity.
749 if (!cHaveSrcVel || cALMA) {
750 pksrec.srcVel = 0.0f;
751 } else {
752 pksrec.srcVel = cSrcVelCol(srcId)(IPosition(1,0));
753 }
754
755 ROMSAntennaColumns antennaCols(cPKSMS.antenna());
756 //String telescope = antennaCols.name()(0);
757 String telescope = antennaCols.name()(cAntId[0]);
758 Bool cGBT = telescope.contains("GBT");
759 //Bool cPM = telescope.contains("PM"); // ACA TP antenna
760 //Bool cDV = telescope.contains("DV"); // VERTEX
761 //Bool cCM = telescope.contains("CM"); // ACA 7m antenna
762 //Bool cALMA = cPM || cDV || cCM ;
763 // Observation type.
764 // check if State Table exist
765 //Bool cHaveStateTab=Table::isReadable(cPKSMS.stateTableName());
766 Int stateId = 0;
767 Int StateNRow = 0;
768 StateNRow=cObsModeCol.nrow();
769 if (Table::isReadable(cPKSMS.stateTableName())) {
770 pksrec.obsType = " ";
771 if (StateNRow > 0) {
772 stateId = cStateIdCol(cIdx);
773 if (stateId == -1) {
774 //pksrec.obsType = " ";
775 } else {
776 pksrec.obsType = cObsModeCol(stateId);
777 Bool sigState =cSigStateCol(stateId);
778 Bool refState =cRefStateCol(stateId);
779 //DEBUG
780 //cerr <<"stateid="<<stateId<<" obsmode="<<pksrec.obsType<<endl;
781 if (cGBT) {
782 // split the obsType string and append a proper label
783 // (these are GBT specific)
784 int epos = pksrec.obsType.find_first_of(':');
785 int nextpos = pksrec.obsType.find_first_of(':',epos+1);
786 string obsMode1 = pksrec.obsType.substr(0,epos);
787 string obsMode2 = pksrec.obsType.substr(epos+1,nextpos-epos-1);
788
789 //cerr <<"obsMode2= "<<obsMode2<<endl;
790 if (!pksrec.srcName.contains("_ps")
791 &&!pksrec.srcName.contains("_psr")
792 &&!pksrec.srcName.contains("_nod")
793 &&!pksrec.srcName.contains("_fs")
794 &&!pksrec.srcName.contains("_fsr")) {
795 // if Nod mode observation , append '_nod'
796 if (obsMode1 == "Nod") {
797 //pksrec.srcName.append("_nod");
798 pksrec.srcType = SrcType::NOD ;
799 } else if (obsMode1 == "OffOn") {
800 // for GBT position switch observations (OffOn or OnOff)
801 //if (obsMode2 == "PSWITCHON") pksrec.srcName.append("_ps");
802 //if (obsMode2 == "PSWITCHOFF") pksrec.srcName.append("_psr");
803 if (obsMode2 == "PSWITCHON") pksrec.srcType = SrcType::PSON ;
804 if (obsMode2 == "PSWITCHOFF") pksrec.srcType = SrcType::PSOFF ;
805 } else {
806 if (obsMode2 == "FSWITCH") {
807 // for GBT frequency switch mode
808 //if (sigState) pksrec.srcName.append("_fs");
809 //if (refState) pksrec.srcName.append("_fsr");
810 if (sigState) pksrec.srcType = SrcType::FSON ;
811 if (refState) pksrec.srcType = SrcType::FSOFF ;
812 }
813 }
814 }
815 }
816 else if (cALMA) {
817 // ALMA tag
818 // split the obsType string and append a proper label
819 string substr[1] ;
820 int numSubstr = split( pksrec.obsType, substr, 1, "," );
821 String obsType = String( substr[0] );
822 int epos = obsType.find_first_of('.');
823 int nextpos = obsType.find_first_of('.',epos+1);
824 string obsMode1 = obsType.substr(0,epos);
825 string obsMode2 = obsType.substr(epos+1,nextpos-epos-1);
826
827 //cerr <<"obsMode2= "<<obsMode2<<endl;
828 // Current OBS_MODE format:
829 //
830 // ON: OBSERVE_TARGET.ON_SOURCE
831 // OFF: OBSERVE_TARGET.OFF_SOURCE
832 //
833 if (obsMode1 == "OBSERVE_TARGET") {
834 //if (obsMode2 == "ON_SOURCE") pksrec.srcName.append("_pson");
835 //if (obsMode2 == "OFF_SOURCE") pksrec.srcName.append("_psoff");
836 if (obsMode2 == "ON_SOURCE") pksrec.srcType = SrcType::PSON ;
837 if (obsMode2 == "OFF_SOURCE") pksrec.srcType = SrcType::PSOFF ;
838 }
839 }
840 }
841 }
842 }
843 // CAL state
844 // this should be apply just for GBT data?
845 Double Cal;
846 if (stateId==-1 || StateNRow==0) {
847 Cal = 0;
848 } else {
849 Cal = cCalCol(stateId);
850 }
851 if (cGBT) {
852 if (Cal > 0 && !pksrec.srcName.contains("_calon")) {
853 //pksrec.srcName.append("_calon");
854 if ( pksrec.srcType == SrcType::NOD )
855 pksrec.srcType = SrcType::NODCAL ;
856 else if ( pksrec.srcType == SrcType::PSON )
857 pksrec.srcType = SrcType::PONCAL ;
858 else if ( pksrec.srcType == SrcType::PSOFF )
859 pksrec.srcType = SrcType::POFFCAL ;
860 else if ( pksrec.srcType == SrcType::FSON )
861 pksrec.srcType = SrcType::FONCAL ;
862 else if ( pksrec.srcType == SrcType::FSOFF )
863 pksrec.srcType = SrcType::FOFFCAL ;
864 else
865 pksrec.srcName.append("_calon");
866 }
867 }
868
869 pksrec.IFno = iIF + 1;
870 Int nChan = abs(cEndChan(iIF) - cStartChan(iIF)) + 1;
871
872 // Minimal handling on continuum data.
873 Vector<Double> chanFreq = cChanFreqCol(iIF);
874 if (nChan == 1) {
875 //pksrec.freqInc = chanFreq(0);
876 pksrec.freqInc = cTotBWCol(iIF);
877 pksrec.refFreq = chanFreq(0);
878 pksrec.restFreq.resize(1);
879 pksrec.restFreq[0] = 0.0f;
880 } else {
881
882 if (cStartChan(iIF) <= cEndChan(iIF)) {
883 pksrec.freqInc = chanFreq(1) - chanFreq(0);
884 } else {
885 pksrec.freqInc = chanFreq(0) - chanFreq(1);
886 }
887
888 pksrec.refFreq = chanFreq(cRefChan(iIF)-1);
889
890 Bool HaveSrcRestFreq= cSrcRestFrqCol.isDefined(srcId);
891 if (HaveSrcRestFreq) {
892 //restFreq = cSrcRestFrqCol(srcId)(IPosition(1,0));
893 //restFreq = cSrcRestFrqCol(srcId);
894 pksrec.restFreq = cSrcRestFrqCol(srcId);
895 } else {
896 pksrec.restFreq.resize(1);
897 pksrec.restFreq[0] = 0.0f;
898 }
899 }
900 //pksrec.bandwidth = abs(pksrec.freqInc * nChan);
901 pksrec.bandwidth = abs(cTotBWCol(0));
902
903 pksrec.tcal.resize(cNPol(iIF));
904 pksrec.tcal = 0.0f;
905 pksrec.tcalTime = "";
906// pksrec.azimuth = 0.0f;
907// pksrec.elevation = 0.0f;
908 pksrec.parAngle = 0.0f;
909
910 pksrec.focusAxi = 0.0f;
911 pksrec.focusTan = 0.0f;
912 pksrec.focusRot = 0.0f;
913
914 // Find the appropriate entry in the WEATHER subtable.
915 //Bool cHaveStateTab=Table::isReadable(cPKSMS.stateTableName());
916 Bool cHaveWeatherTab = Table::isReadable(cPKSMS.weatherTableName());
917 Int weatherIdx=-1;
918 if (cHaveWeatherTab) {
919 Vector<Double> wTimes = cWeatherTimeCol.getColumn();
920 for (weatherIdx = wTimes.nelements()-1; weatherIdx >= 0; weatherIdx--) {
921 if (cWeatherTimeCol(weatherIdx) <= time) {
922 break;
923 }
924 }
925 }
926
927 if (weatherIdx < 0 || !cHaveWeatherTab) {
928 // No appropriate WEATHER entry.
929 pksrec.temperature = 0.0f;
930 pksrec.pressure = 0.0f;
931 pksrec.humidity = 0.0f;
932 } else {
933 pksrec.temperature = cTemperatureCol(weatherIdx);
934 pksrec.pressure = cPressureCol(weatherIdx);
935 pksrec.humidity = cHumidityCol(weatherIdx);
936 }
937
938 pksrec.windSpeed = 0.0f;
939 pksrec.windAz = 0.0f;
940
941 pksrec.refBeam = 0;
942 pksrec.beamNo = ibeam + 1;
943
944 //pointing/azel
945 MVPosition mvpos(antennaCols.position()(cAntId[0]));
946 MPosition mp(mvpos);
947 Quantum<Double> qt(time,"s");
948 MVEpoch mvt(qt);
949 MEpoch me(mvt);
950 MeasFrame frame(mp, me);
951 MDirection md;
952 pksrec.pCode = 0;
953 pksrec.rateAge = 0.0f;
954 pksrec.paRate = 0.0f;
955 if (cGetPointing) {
956 //cerr << "get pointing data ...." << endl;
957 ROScalarColumn<Int> pAntIdCol ;
958 ROScalarColumn<Double> psTimeCol ;
959 Table ptTable = cPKSMS.pointing() ;
960 MSPointing selPtTab( ptTable( ptTable.col("ANTENNA_ID") == cAntId[0] ) ) ;
961 pAntIdCol.attach( selPtTab, "ANTENNA_ID" ) ;
962 Vector<Int> antIds = pAntIdCol.getColumn() ;
963 psTimeCol.attach( selPtTab, "TIME" ) ;
964 Vector<Double> pTimes = psTimeCol.getColumn();
965 Bool doInterp = False ;
966 Int PtIdx=-1;
967 for (PtIdx = pTimes.nelements()-1; PtIdx >= 0; PtIdx--) {
968 if ( pTimes[PtIdx] == time ) {
969 break ;
970 }
971 else if ( pTimes[PtIdx] < time ) {
972 if ( PtIdx != pTimes.nelements()-1 ) {
973 doInterp = True ;
974 }
975 break ;
976 }
977 }
978 if ( PtIdx == -1 ) {
979 PtIdx = 0 ;
980 }
981 //cerr << "got index=" << PtIdx << endl;
982 Matrix<Double> pointingDir = cPointingCol(PtIdx);
983 ROMSPointingColumns PtCols( selPtTab ) ;
984 Vector<Double> pointingDirVec ;
985 if ( doInterp ) {
986 Double dt1 = time - pTimes[PtIdx] ;
987 Double dt2 = pTimes[PtIdx+1] - time ;
988 Vector<Double> dirVec1 = pointingDir.column(0) ;
989 Matrix<Double> pointingDir2 = cPointingCol(PtIdx+1) ;
990 Vector<Double> dirVec2 = pointingDir2.column(0) ;
991 pointingDirVec = (dt1*dirVec2+dt2*dirVec1)/(dt1+dt2) ;
992 Vector<MDirection> vmd1(1) ;
993 Vector<MDirection> vmd2(1) ;
994 PtCols.directionMeasCol().get(PtIdx,vmd1) ;
995 Vector<Double> angle1 = vmd1(0).getAngle().getValue("rad") ;
996 PtCols.directionMeasCol().get(PtIdx+1,vmd2) ;
997 Vector<Double> angle2 = vmd2(0).getAngle().getValue("rad") ;
998 Vector<Double> angle = (dt1*angle2+dt2*angle1)/(dt1+dt2) ;
999 Quantum< Vector<Double> > qangle( angle, "rad" ) ;
1000 String typeStr = vmd1(0).getRefString() ;
1001 //cerr << "vmd1.getRefString()=" << typeStr << endl ;
1002 MDirection::Types mdType ;
1003 MDirection::getType( mdType, typeStr ) ;
1004 //cerr << "mdType=" << mdType << endl ;
1005 md = MDirection( qangle, mdType ) ;
1006 //cerr << "md=" << md.getAngle().getValue("rad") << endl ;
1007 }
1008 else {
1009 pointingDirVec = pointingDir.column(0) ;
1010 Vector<MDirection> vmd(1);
1011 PtCols.directionMeasCol().get(PtIdx,vmd);
1012 md = vmd[0];
1013 }
1014 // put J2000 coordinates in "direction"
1015 if (cDirRef =="J2000") {
1016 pksrec.direction = pointingDirVec ;
1017 }
1018 else {
1019 pksrec.direction =
1020 MDirection::Convert(md, MDirection::Ref(MDirection::J2000,
1021 frame)
1022 )().getAngle("rad").getValue();
1023
1024 }
1025 uInt ncols = pointingDir.ncolumn();
1026 pksrec.scanRate.resize(2);
1027 if (ncols == 1) {
1028 pksrec.scanRate = 0.0f;
1029 } else {
1030 pksrec.scanRate(0) = pointingDir.column(1)(0);
1031 pksrec.scanRate(1) = pointingDir.column(1)(1);
1032 }
1033 }
1034 else {
1035 // Get direction from FIELD table
1036 // here, assume direction to be the field direction not pointing
1037 Matrix<Double> delayDir = cFieldDelayDirCol(fieldId);
1038 pksrec.direction = delayDir.column(0);
1039 uInt ncols = delayDir.ncolumn();
1040 pksrec.scanRate.resize(2);
1041 if (ncols == 1) {
1042 pksrec.scanRate = 0.0f;
1043 } else {
1044 pksrec.scanRate(0) = delayDir.column(1)(0);
1045 pksrec.scanRate(1) = delayDir.column(1)(1);
1046 }
1047 }
1048 // caluculate azimuth and elevation
1049 // first, get the reference frame
1050 /**
1051 MVPosition mvpos(antennaCols.position()(0));
1052 MPosition mp(mvpos);
1053 Quantum<Double> qt(time,"s");
1054 MVEpoch mvt(qt);
1055 MEpoch me(mvt);
1056 MeasFrame frame(mp, me);
1057 **/
1058 //
1059 ROMSFieldColumns fldCols(cPKSMS.field());
1060 Vector<MDirection> vmd(1);
1061 //MDirection md;
1062 fldCols.delayDirMeasCol().get(fieldId,vmd);
1063 md = vmd[0];
1064 //Vector<Double> dircheck = md.getAngle("rad").getValue();
1065 //cerr<<"dircheck="<<dircheck<<endl;
1066
1067 Vector<Double> azel =
1068 MDirection::Convert(md, MDirection::Ref(MDirection::AZEL,
1069 frame)
1070 )().getAngle("rad").getValue();
1071 //cerr<<"azel="<<azel<<endl;
1072 pksrec.azimuth = azel[0];
1073 pksrec.elevation = azel[1];
1074
1075 // Get Tsys assuming that entries in the SYSCAL table match the main table.
1076 if (cHaveTsys) {
1077 Int nTsysColRow = cTsysCol.nrow();
1078 if (nTsysColRow != cNRow) {
1079 cHaveTsys=0;
1080 }
1081 }
1082 if (cHaveTsys) {
1083 cTsysCol.get(cIdx, pksrec.tsys, True);
1084 } else {
1085 Int numReceptor;
1086 cNumReceptorCol.get(0, numReceptor);
1087 pksrec.tsys.resize(numReceptor);
1088 pksrec.tsys = 1.0f;
1089 }
1090 cSigmaCol.get(cIdx, pksrec.sigma, True);
1091
1092 //get Tcal if available
1093 if (cHaveTcal) {
1094 Int nTcalColRow = cTcalCol.nrow();
1095 uInt nBeam = cBeams.nelements();
1096 uInt nIF = cIFs.nelements();
1097 uInt nrws = nBeam * nIF;
1098 if (nTcalColRow > 0) {
1099 // find tcal match with the data with the data time stamp
1100 Double mjds = pksrec.mjd*(24*3600);
1101 Double dtcalTime;
1102 if ( pksrec.mjd > lastmjd || cIdx==0 ) {
1103 //Table tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds));
1104 tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds), nrws);
1105 //DEBUG
1106 //if (cIdx == 0) {
1107 // cerr<<"inital table retrieved"<<endl;
1108 //}
1109
1110 }
1111
1112 if (nBeam == 1) {
1113 tmptab2 = tmptab( tmptab.col("SPECTRAL_WINDOW_ID") == iIF, 1);
1114 } else {
1115 tmptab2 = tmptab( tmptab.col("SPECTRAL_WINDOW_ID") == iIF &&
1116 tmptab.col("FEED_ID") == ibeam , 1);
1117 }
1118 //cerr<<"first subtab rows="<<tmptab.nrow()<<endl;
1119 int syscalrow = tmptab2.nrow();
1120 ROArrayColumn<Float> tcalCol(tmptab2, "TCAL");
1121 ROScalarColumn<Double> tcalTimeCol(tmptab2, "TIME");
1122 if (syscalrow==0) {
1123 os << LogIO::NORMAL
1124 <<"Cannot find any matching Tcal at/near the data timestamp."
1125 << " Set Tcal=0.0" << LogIO::POST ;
1126 } else {
1127 tcalCol.get(0, pksrec.tcal);
1128 tcalTimeCol.get(0,dtcalTime);
1129 pksrec.tcalTime = MVTime(dtcalTime/(24*3600)).string(MVTime::YMD);
1130 //DEBUG
1131 //cerr<<"cIdx:"<<cIdx<<" tcal="<<tcal<<" tcalTime="<<tcalTime<<endl;
1132 tmptab.markForDelete();
1133 tmptab2.markForDelete();
1134 }
1135 }
1136 lastmjd = pksrec.mjd;
1137 }
1138
1139 // Calibration factors (if available).
1140 pksrec.calFctr.resize(cNPol(iIF));
1141 if (cHaveCalFctr) {
1142 cCalFctrCol.get(cIdx, pksrec.calFctr);
1143 } else {
1144 pksrec.calFctr = 0.0f;
1145 }
1146
1147 // Baseline parameters (if available).
1148 if (cHaveBaseLin) {
1149 pksrec.baseLin.resize(2,cNPol(iIF));
1150 cBaseLinCol.get(cIdx, pksrec.baseLin);
1151
1152 pksrec.baseSub.resize(24,cNPol(iIF));
1153 cBaseSubCol.get(cIdx, pksrec.baseSub);
1154
1155 } else {
1156 pksrec.baseLin.resize(0,0);
1157 pksrec.baseSub.resize(0,0);
1158 }
1159
1160
1161 // Get spectral data.
1162 if (cGetSpectra) {
1163 Matrix<Float> tmpData;
1164 Matrix<Bool> tmpFlag;
1165 if (cHaveDataCol) {
1166 Matrix<Complex> tmpCmplxData;
1167 Matrix<Float> tmpReData;
1168 Matrix<Float> tmpImData;
1169 //cerr<<"reading spectra..."<<endl;
1170 //# TODO - should have a flag to user to select DATA or CORRECTED_DATA
1171 //# currently just automatically determined, --- read CORRECTED one
1172 //# if the column exist.
1173 if (cHaveCorrectedDataCol) {
1174 cCorrectedDataCol.getSlice(cIdx, cDataSel(iIF), tmpCmplxData, True);
1175 } else {
1176 cDataCol.getSlice(cIdx, cDataSel(iIF), tmpCmplxData, True);
1177 }
1178 tmpReData = real(tmpCmplxData);
1179 tmpImData = imag(tmpCmplxData);
1180 tmpData = sqrt(tmpReData*tmpReData + tmpImData*tmpImData);
1181 } else {
1182 cFloatDataCol.getSlice(cIdx, cDataSel(iIF), tmpData, True);
1183 }
1184 cFlagCol.getSlice(cIdx, cDataSel(iIF), tmpFlag, True);
1185
1186 // Transpose spectra.
1187 Int nPol = tmpData.nrow();
1188 pksrec.spectra.resize(nChan, nPol);
1189 pksrec.flagged.resize(nChan, nPol);
1190 if (cEndChan(iIF) >= cStartChan(iIF)) {
1191 // Simple transposition.
1192 for (Int ipol = 0; ipol < nPol; ipol++) {
1193 for (Int ichan = 0; ichan < nChan; ichan++) {
1194 pksrec.spectra(ichan,ipol) = tmpData(ipol,ichan);
1195 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,ichan);
1196 }
1197 }
1198
1199 } else {
1200 // Transpose with inversion.
1201 Int jchan = nChan - 1;
1202 for (Int ipol = 0; ipol < nPol; ipol++) {
1203 for (Int ichan = 0; ichan < nChan; ichan++, jchan--) {
1204 pksrec.spectra(ichan,ipol) = tmpData(ipol,jchan);
1205 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,jchan);
1206 }
1207 }
1208 }
1209
1210 // Row-based flagging info. (True:1, False:0)
1211 pksrec.flagrow = (cFlagRowCol(cIdx) ? 1 : 0);
1212 }
1213
1214 // Get cross-polarization data.
1215 if (cGetXPol) {
1216 //cerr<<"cGetXPol="<<cGetXPol<<endl;
1217 //cerr<<"cHaveXCalFctr="<<cHaveXCalFctr<<endl;
1218
1219 if (cHaveXCalFctr) {
1220 cXCalFctrCol.get(cIdx, pksrec.xCalFctr);
1221 } else {
1222 pksrec.xCalFctr = Complex(0.0f, 0.0f);
1223 }
1224
1225 if(!cALMA) {
1226 cDataCol.get(cIdx, pksrec.xPol, True);
1227
1228 if (cEndChan(iIF) < cStartChan(iIF)) {
1229 Complex ctmp;
1230 Int jchan = nChan - 1;
1231 for (Int ichan = 0; ichan < nChan/2; ichan++, jchan--) {
1232 ctmp = pksrec.xPol(ichan);
1233 pksrec.xPol(ichan) = pksrec.xPol(jchan);
1234 pksrec.xPol(jchan) = ctmp;
1235 }
1236 }
1237 }
1238 }
1239 /**
1240 cerr<<"scanNo="<<scanNo<<endl;
1241 cerr<<"cycleNo="<<cycleNo<<endl;
1242 cerr<<"mjd="<<mjd<<endl;
1243 cerr<<"interval="<<interval<<endl;
1244 cerr<<"fieldName="<<fieldName<<endl;
1245 cerr<<"srcNmae="<<srcName<<endl;
1246 cerr<<"srcDir="<<srcDir<<endl;
1247 cerr<<"srcPM="<<srcPM<<endl;
1248 cerr<<"srcVel="<<srcVel<<endl;
1249 cerr<<"obsMode="<<obsMode<<endl;
1250 cerr<<"IFno="<<IFno<<endl;
1251 cerr<<"refFreq="<<refFreq<<endl;
1252 cerr<<"tcal="<<tcal<<endl;
1253 cerr<<"direction="<<direction<<endl;
1254 cerr<<"scanRate="<<scanRate<<endl;
1255 cerr<<"tsys="<<tsys<<endl;
1256 cerr<<"sigma="<<sigma<<endl;
1257 cerr<<"calFctr="<<calFctr<<endl;
1258 cerr<<"baseLin="<<baseLin<<endl;
1259 cerr<<"baseSub="<<baseSub<<endl;
1260 cerr<<"spectra="<<spectra.shape()<<endl;
1261 cerr<<"flagged="<<flagged.shape()<<endl;
1262 cerr<<"xCalFctr="<<xCalFctr<<endl;
1263 cerr<<"xPol="<<xPol<<endl;
1264 **/
1265 cIdx++;
1266
1267 return 0;
1268}
1269
1270//--------------------------------------------------------- PKSMS2reader::read
1271
1272// Read the next data record, just the basics.
1273
1274Int PKSMS2reader::read(
1275 Int &IFno,
1276 Vector<Float> &tsys,
1277 Vector<Float> &calFctr,
1278 Matrix<Float> &baseLin,
1279 Matrix<Float> &baseSub,
1280 Matrix<Float> &spectra,
1281 Matrix<uChar> &flagged)
1282{
1283 if (!cMSopen) {
1284 return 1;
1285 }
1286
1287 // Check for EOF.
1288 if (cIdx >= cNRow) {
1289 return -1;
1290 }
1291
1292 // Find the next selected beam and IF.
1293 Int ibeam;
1294 Int iIF;
1295 Int iDataDesc;
1296 while (True) {
1297 ibeam = cBeamNoCol(cIdx);
1298 //iIF = cDataDescIdCol(cIdx);
1299 iDataDesc = cDataDescIdCol(cIdx);
1300 iIF = cSpWinIdCol(iDataDesc);
1301 if (cBeams(ibeam) && cIFs(iIF)) {
1302 break;
1303 }
1304
1305 // Check for EOF.
1306 if (++cIdx >= cNRow) {
1307 return -1;
1308 }
1309 }
1310
1311 IFno = iIF + 1;
1312 // Get Tsys assuming that entries in the SYSCAL table match the main table.
1313 cTsysCol.get(cIdx, tsys, True);
1314
1315 // Calibration factors (if available).
1316 if (cHaveCalFctr) {
1317 cCalFctrCol.get(cIdx, calFctr, True);
1318 } else {
1319 calFctr.resize(cNPol(iIF));
1320 calFctr = 0.0f;
1321 }
1322
1323 // Baseline parameters (if available).
1324 if (cHaveBaseLin) {
1325 baseLin.resize(2,cNPol(iIF));
1326 cBaseLinCol.get(cIdx, baseLin);
1327
1328 baseSub.resize(24,cNPol(iIF));
1329 cBaseSubCol.get(cIdx, baseSub);
1330
1331 } else {
1332 baseLin.resize(0,0);
1333 baseSub.resize(0,0);
1334 }
1335
1336 if (cGetSpectra) {
1337 // Get spectral data.
1338 Matrix<Float> tmpData;
1339 Matrix<Bool> tmpFlag;
1340 if (cHaveDataCol) {
1341 Matrix<Complex> tmpCmplxData;
1342 cDataCol.getSlice(cIdx, cDataSel(iIF), tmpCmplxData, True);
1343 tmpData = real(tmpCmplxData);
1344 } else {
1345 cFloatDataCol.getSlice(cIdx, cDataSel(iIF), tmpData, True);
1346 }
1347 cFlagCol.getSlice(cIdx, cDataSel(iIF), tmpFlag, True);
1348
1349 // Transpose spectra.
1350 Int nChan = tmpData.ncolumn();
1351 Int nPol = tmpData.nrow();
1352 spectra.resize(nChan, nPol);
1353 flagged.resize(nChan, nPol);
1354 if (cEndChan(iIF) >= cStartChan(iIF)) {
1355 // Simple transposition.
1356 for (Int ipol = 0; ipol < nPol; ipol++) {
1357 for (Int ichan = 0; ichan < nChan; ichan++) {
1358 spectra(ichan,ipol) = tmpData(ipol,ichan);
1359 flagged(ichan,ipol) = tmpFlag(ipol,ichan);
1360 }
1361 }
1362
1363 } else {
1364 // Transpose with inversion.
1365 Int jchan = nChan - 1;
1366 for (Int ipol = 0; ipol < nPol; ipol++) {
1367 for (Int ichan = 0; ichan < nChan; ichan++, jchan--) {
1368 spectra(ichan,ipol) = tmpData(ipol,jchan);
1369 flagged(ichan,ipol) = tmpFlag(ipol,jchan);
1370 }
1371 }
1372 }
1373 }
1374
1375 cIdx++;
1376
1377 return 0;
1378}
1379
1380//-------------------------------------------------------- PKSMS2reader::close
1381
1382// Close the MS.
1383
1384void PKSMS2reader::close()
1385{
1386 cPKSMS = MeasurementSet();
1387 cMSopen = False;
1388}
1389
1390//-------------------------------------------------------- PKSMS2reader::splitAntenanSelectionString
1391
1392// split antenna selection string
1393// delimiter is ','
1394
1395Vector<String> PKSMS2reader::splitAntennaSelectionString( const String s )
1396{
1397 Char delim = ',' ;
1398 Int n = s.freq( delim ) + 1 ;
1399 Vector<String> antlist ;
1400 string *sl = new string[n] ;
1401 Int numSubstr = split( s, sl, n, "," );
1402 antlist.resize( numSubstr ) ;
1403 for ( Int i = 0 ; i < numSubstr ; i++ ) {
1404 antlist[i] = String( sl[i] ) ;
1405 antlist[i].trim() ;
1406 }
1407 //cerr << "antlist = " << antlist << endl ;
1408 delete [] sl;
1409 return antlist ;
1410}
1411
1412//-------------------------------------------------------- PKSMS2reader::setupAntennaList
1413
1414// Fill cAntenna and cAntId
1415
1416void PKSMS2reader::setupAntennaList( const String s )
1417{
1418 LogIO os( LogOrigin( "PKSMS2reader", "setupAntennaList()", WHERE ) ) ;
1419 //cerr << "antenna specification: " << s << endl ;
1420 ROMSAntennaColumns antennaCols(cPKSMS.antenna());
1421 ROScalarColumn<String> antNames = antennaCols.name();
1422 Int nrow = antNames.nrow() ;
1423 Vector<String> antlist = splitAntennaSelectionString( s ) ;
1424 Int len = antlist.size() ;
1425 Vector<Int> AntId( len ) ;
1426 Regex re( "[0-9]+" ) ;
1427 for ( Int i = 0 ; i < len ; i++ ) {
1428 if ( antlist[i].matches( re ) ) {
1429 AntId[i] = atoi( antlist[i].c_str() ) ;
1430 if ( AntId[i] >= nrow ) {
1431 os << LogIO::SEVERE << "Antenna index out of range: " << AntId[i] << LogIO::EXCEPTION ;
1432 }
1433 }
1434 else {
1435 AntId[i] = -1 ;
1436 for ( uInt j = 0 ; j < antNames.nrow() ; j++ ) {
1437 if ( antlist[i] == antNames(j) ) {
1438 AntId[i] = j ;
1439 break ;
1440 }
1441 }
1442 if ( AntId[i] == -1 ) {
1443 os << LogIO::SEVERE << "Specified antenna name not found: " << antlist[i] << LogIO::EXCEPTION ;
1444 }
1445 }
1446 }
1447 //cerr << "AntId = " << AntId << endl ;
1448 vector<Int> uniqId ;
1449 uniqId.push_back( AntId(0) ) ;
1450 for ( uInt i = 1 ; i < AntId.size() ; i++ ) {
1451 if ( count(uniqId.begin(),uniqId.end(),AntId[i]) == 0 ) {
1452 uniqId.push_back( AntId[i] ) ;
1453 }
1454 }
1455 Vector<Int> newAntId( uniqId ) ;
1456 cAntId.assign( newAntId ) ;
1457 //cerr << "cAntId = " << cAntId << endl ;
1458}
Note: See TracBrowser for help on using the repository browser.