Changeset 1757 for branches/alma/external
- Timestamp:
- 06/09/10 19:03:06 (15 years ago)
- Location:
- branches/alma
- Files:
-
- 22 added
- 4 deleted
- 24 edited
- 3 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/alma
-
Property svn:ignore
set to
.sconf_temp
.sconsign.dblite
-
Property svn:mergeinfo
set to
/branches/asap-3.x merged eligible
-
Property svn:ignore
set to
-
branches/alma/external/atnf/PKSIO/FITSreader.cc
r1453 r1757 2 2 //# FITSreader.cc: ATNF single-dish FITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: FITSreader.cc,v 19.4 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The FITSreader class is an abstract base class for the Parkes Multibeam … … 53 55 const int getSpectra, 54 56 const int getXPol, 55 const int getFeedPos) 57 const int getFeedPos, 58 const int getPointing, 59 const int coordSys) 56 60 { 57 61 int maxNChan = 0; … … 84 88 cGetXPol = getXPol && cGetXPol; 85 89 cGetFeedPos = getFeedPos; 90 cCoordSys = coordSys; 91 86 92 87 93 return maxNChan; -
branches/alma/external/atnf/PKSIO/FITSreader.h
r1453 r1757 2 2 //# FITSreader.h: ATNF single-dish FITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: FITSreader.h,v 19.11 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The FITSreader class is an abstract base class for the Parkes Multibeam … … 38 40 #define ATNF_FITSREADER_H 39 41 40 #include <atnf/PKSIO/PKSMBrecord.h> 42 #include <atnf/PKSIO/MBrecord.h> 43 44 using namespace std; 45 41 46 42 47 // <summary> … … 44 49 // </summary> 45 50 51 //class FITSreader 46 52 class FITSreader 47 53 { … … 74 80 double antPos[3], 75 81 char obsType[32], 82 char bunit[32], 76 83 float &equinox, 77 84 char radecsys[32], … … 90 97 // Set data selection criteria. Channel numbering is 1-relative, zero or 91 98 // negative channel numbers are taken to be offsets from the last channel. 99 // Coordinate systems are 100 // 0: equatorial (RA,Dec), 101 // 1: horizontal (Az,El), 102 // 2: feed-plane, 103 // 3: zenithal position angle of feed and elevation, (ZPA,El). 92 104 int select( 93 105 const int startChan[], … … 96 108 const int getSpectra = 1, 97 109 const int getXPol = 0, 98 const int getFeedPos = 0); 110 const int getFeedPos = 0, 111 const int getPointing = 0, 112 const int coordSys = 0); 113 99 114 100 115 // Find the range in time and position of the data selected. … … 108 123 // Read the next data record. 109 124 virtual int read( 110 PKSMBrecord &record) = 0; 125 // PKSMBrecord &record) = 0; 126 MBrecord &record) = 0; 111 127 112 128 // Close the RPFITS file. … … 114 130 115 131 protected: 116 int *cBeams, *cEndChan, cGetFeedPos, cGetSpectra, cGetXPol, cHaveBase, 117 cHaveSpectra, *cHaveXPol, *cIFs, cNBeam, *cNChan, cNIF, *cNPol, 118 *cRefChan, *cStartChan; 132 int *cBeams, *cEndChan, cGetFeedPos, cCoordSys, cGetSpectra, cGetXPol, 133 cHaveBase, cHaveSpectra, *cHaveXPol, *cIFs, cNBeam, *cNChan, cNIF, 134 *cNPol, *cRefChan, *cStartChan; 135 136 // For use in constructing messages. 137 char cMsg[256]; 138 119 139 }; 120 140 -
branches/alma/external/atnf/PKSIO/MBFITSreader.cc
r1453 r1757 2 2 //# MBFITSreader.cc: ATNF single-dish RPFITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: MBFITSreader.cc,v 19.57 2009-10-30 06:34:36 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The MBFITSreader class reads single dish RPFITS files (such as Parkes … … 35 37 //#--------------------------------------------------------------------------- 36 38 39 #include <atnf/pks/pks_maths.h> 37 40 #include <atnf/PKSIO/MBFITSreader.h> 38 #include <atnf/PKSIO/ PKSMBrecord.h>39 40 #include < RPFITS.h>41 #include <atnf/PKSIO/MBrecord.h> 42 43 #include <casa/Logging/LogIO.h> 41 44 42 45 #include <casa/math.h> … … 47 50 #include <unistd.h> 48 51 52 #include <RPFITS.h> 53 49 54 using namespace std; 50 55 … … 52 57 const double PI = 3.141592653589793238462643; 53 58 const double TWOPI = 2.0 * PI; 59 const double HALFPI = PI / 2.0; 60 const double R2D = 180.0 / PI; 61 62 // Class name 63 const string className = "MBFITSreader" ; 54 64 55 65 //------------------------------------------------- MBFITSreader::MBFITSreader … … 81 91 cRefChan = 0x0; 82 92 83 cVis = new float[2*4*8163]; 93 cVis = 0x0; 94 cWgt = 0x0; 84 95 85 96 cBeamSel = 0x0; … … 91 102 92 103 cMBopen = 0; 93 jstat = -3; 104 105 // Tell RPFITSIN not to report errors directly. 106 //iostat_.errlun = -1; 94 107 } 95 108 … … 120 133 int &extraSysCal) 121 134 { 135 const string methodName = "open()" ; 136 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 137 122 138 if (cMBopen) { 123 139 close(); … … 127 143 128 144 // Open the RPFITS file. 129 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 130 &if_no, &sourceno); 131 132 if (jstat) { 133 fprintf(stderr, "Failed to open MBFITS file: %s\n", rpname); 145 int jstat = -3; 146 if (rpfitsin(jstat)) { 147 sprintf(cMsg, "Failed to open MBFITS file\n%s", rpname); 148 os << LogIO::SEVERE << cMsg << LogIO::POST ; 134 149 return 1; 135 150 } … … 147 162 // Read the first header. 148 163 jstat = -1; 149 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 150 &if_no, &sourceno); 151 152 if (jstat) { 153 fprintf(stderr, "Failed to read MBFITS header: %s\n", rpname); 164 if (rpfitsin(jstat)) { 165 sprintf(cMsg, "Failed to read MBFITS header in file\n" 166 "%s", rpname); 167 os << LogIO::SEVERE << cMsg << LogIO::POST ; 154 168 close(); 155 169 return 1; … … 159 173 cMopra = strncmp(names_.instrument, "ATMOPRA", 7) == 0; 160 174 161 // Tidbinbilla data has some more. 162 cTid = strncmp(names_.sta, "tid", 3) == 0; 163 if (cTid) { 164 // Telescope position is stored in the source table. 175 // Non-ATNF data may not store the position in (u,v,w). 176 if (strncmp(names_.sta, "tid", 3) == 0) { 177 sprintf(cMsg, "Found Tidbinbilla data"); 178 cSUpos = 1; 179 } else if (strncmp(names_.sta, "HOB", 3) == 0) { 180 sprintf(cMsg, "Found Hobart data"); 181 cSUpos = 1; 182 } else if (strncmp(names_.sta, "CED", 3) == 0) { 183 sprintf(cMsg, "Found Ceduna data"); 184 cSUpos = 1; 185 } else { 186 cSUpos = 0; 187 } 188 189 if (cSUpos) { 190 strcat(cMsg, ", using telescope position\n from SU table."); 191 os << LogIO::WARN << cMsg << LogIO::POST ; 165 192 cInterp = 0; 166 193 } 194 195 // Mean scan rate (for timestamp repairs). 196 cNRate = 0; 197 cAvRate[0] = 0.0; 198 cAvRate[1] = 0.0; 199 cCode5 = 0; 167 200 168 201 … … 176 209 177 210 if (cNBeam <= 0) { 178 fprintf(stderr, "Couldn't determine number of beams.\n");211 os << LogIO::SEVERE << "Couldn't determine number of beams." << LogIO::POST ; 179 212 close(); 180 213 return 1; … … 189 222 // ...beams present in the data. 190 223 for (int iBeam = 0; iBeam < anten_.nant; iBeam++) { 191 cBeams[anten_.ant_num[iBeam] - 1] = 1; 224 // Guard against dubious beam numbers, e.g. zeroes in 225 // 1999-09-29_1632_024848p14_071b.hpf and the four scans following. 226 // Note that the actual beam number is decoded from the 'baseline' random 227 // parameter for each spectrum and is only used for beam selection. 228 int beamNo = anten_.ant_num[iBeam]; 229 if (beamNo != iBeam+1) { 230 char sta[8]; 231 strncpy(sta, names_.sta+(8*iBeam), 8); 232 char *cp = sta + 7; 233 while (*cp == ' ') *(cp--) = '\0'; 234 235 sprintf(cMsg, 236 "RPFITSIN returned beam number %2d for AN table\n" 237 "entry %2d with name '%.8s'", beamNo, iBeam+1, sta); 238 239 char text[8]; 240 sprintf(text, "MB%2.2d", iBeam+1); 241 cp = cMsg + strlen(cMsg); 242 if (strncmp(sta, text, 8) == 0) { 243 beamNo = iBeam + 1; 244 sprintf(cp, "; using beam number %2d.", beamNo); 245 } else { 246 sprintf(cp, "."); 247 } 248 249 os << LogIO::WARN << cMsg << LogIO::POST ; 250 } 251 252 if (0 < beamNo && beamNo <= cNBeam) { 253 cBeams[beamNo-1] = 1; 254 } 192 255 } 193 256 … … 237 300 } 238 301 239 // Is the vis array declared by RPFITS.h large enough?240 if ( 8*8193 < maxProd) {241 // Need to allocate more memory for RPFITSIN.242 243 }302 // Allocate memory for RPFITSIN subroutine arguments. 303 if (cVis) delete [] cVis; 304 if (cWgt) delete [] cWgt; 305 cVis = new float[2*maxProd]; 306 cWgt = new float[maxProd]; 244 307 245 308 nChan = cNChan; … … 278 341 // Read the first syscal record. 279 342 if (rpget(1, cEOS)) { 280 fprintf(stderr, "Error: Failed to read first syscal record.\n");343 os << LogIO::SEVERE << "Failed to read first syscal record." << LogIO::POST ; 281 344 close(); 282 345 return 1; … … 304 367 double antPos[3], 305 368 char obsType[32], 369 char bunit[32], 306 370 float &equinox, 307 371 char radecsys[32], … … 312 376 double &bandwidth) 313 377 { 378 const string methodName = "getHeader()" ; 379 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 380 314 381 if (!cMBopen) { 315 fprintf(stderr, "An MBFITS file has not been opened.\n");382 os << LogIO::SEVERE << "An MBFITS file has not been opened." << LogIO::POST ; 316 383 return 1; 317 384 } … … 333 400 antPos[1] = 2816759.046; 334 401 antPos[2] = -3454035.950; 402 335 403 } else if (strncmp(names_.sta, "HOH", 3) == 0) { 336 404 // Parkes HOH receiver. … … 339 407 antPos[1] = 2816759.046; 340 408 antPos[2] = -3454035.950; 409 341 410 } else if (strncmp(names_.sta, "CA0", 3) == 0) { 342 411 // An ATCA antenna, use the array centre position. … … 345 414 antPos[1] = 2792906.182; 346 415 antPos[2] = -3200483.747; 416 417 // ATCA-104. Updated position at epoch 2007/06/24 from Chris Phillips. 418 // antPos[0] = -4751640.182; // ± 0.008 419 // antPos[1] = 2791700.322; // ± 0.006 420 // antPos[2] = -3200490.668; // ± 0.007 421 // 347 422 } else if (strncmp(names_.sta, "MOP", 3) == 0) { 348 // Mopra. 423 // Mopra. Updated position at epoch 2007/06/24 from Chris Phillips. 349 424 sprintf(telescope, "%-16.16s", "ATMOPRA"); 350 antPos[0] = -4682768.630; 351 antPos[1] = 2802619.060; 352 antPos[2] = -3291759.900; 425 antPos[0] = -4682769.444; // ± 0.009 426 antPos[1] = 2802618.963; // ± 0.006 427 antPos[2] = -3291758.864; // ± 0.008 428 353 429 } else if (strncmp(names_.sta, "HOB", 3) == 0) { 354 430 // Hobart. … … 357 433 antPos[1] = 2522347.567; 358 434 antPos[2] = -4311562.569; 435 359 436 } else if (strncmp(names_.sta, "CED", 3) == 0) { 360 // Ceduna. 437 // Ceduna. Updated position at epoch 2007/06/24 from Chris Phillips. 361 438 sprintf(telescope, "%-16.16s", "CEDUNA"); 362 antPos[0] = -3749943.657; 363 antPos[1] = 3909017.709; 364 antPos[2] = -3367518.309; 439 antPos[0] = -3753443.168; // ± 0.017 440 antPos[1] = 3912709.794; // ± 0.017 441 antPos[2] = -3348067.060; // ± 0.016 442 365 443 } else if (strncmp(names_.sta, "tid", 3) == 0) { 366 444 // DSS. … … 379 457 obsType[j] = '\0'; 380 458 459 // Brightness unit. 460 sprintf(bunit, "%-16.16s", names_.bunit); 461 if (strcmp(bunit, "JY") == 0) { 462 bunit[1] = 'y'; 463 } else if (strcmp(bunit, "JY/BEAM") == 0) { 464 strcpy(bunit, "Jy/beam"); 465 } 466 381 467 // Coordinate frames. 382 468 equinox = 2000.0f; … … 386 472 // Time at start of observation. 387 473 sprintf(datobs, "%-10.10s", names_.datobs); 388 utc = ut;474 utc = cUTC; 389 475 390 476 // Spectral parameters. … … 425 511 //--------------------------------------------------------- MBFITSreader::read 426 512 427 // Read the next data record .513 // Read the next data record (if you're feeling lucky). 428 514 429 515 int MBFITSreader::read( 430 PKSMBrecord &MBrec)516 MBrecord &MBrec) 431 517 { 518 const string methodName = "read()" ; 519 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 520 432 521 int beamNo = -1; 433 int haveData, status; 434 PKSMBrecord *iMBuff = 0x0; 522 int haveData, pCode = 0, status; 523 double raRate = 0.0, decRate = 0.0, paRate = 0.0; 524 MBrecord *iMBuff = 0x0; 435 525 436 526 if (!cMBopen) { 437 fprintf(stderr, "An MBFITS file has not been opened.\n");527 os << LogIO::SEVERE << "An MBFITS file has not been opened." << LogIO::POST ; 438 528 return 1; 439 529 } 440 530 441 // Positions recorded in the input records do not coincide with the midpoint442 // of the integration and hence the input must be buffered so that true443 // positions may be interpolated.531 // Positions recorded in the input records usually do not coincide with the 532 // midpoint of the integration and hence the input must be buffered so that 533 // true positions may be interpolated. 444 534 // 445 535 // On the first call nBeamSel buffers of length nBin, are allocated and … … 471 561 472 562 // Read the next record. 563 pCode = 0; 473 564 if ((status = rpget(0, cEOS)) == -1) { 474 565 // EOF. … … 479 570 480 571 #ifdef PKSIO_DEBUG 481 printf("End-of-file detected, flushing last scan.\n");572 os << LogIO::DEBUGGING << "\nEnd-of-file detected, flushing last cycle.\n" << LogIO::POST ; 482 573 #endif 483 574 … … 507 598 cXpolOff = new int[cNIF]; 508 599 509 int simulIF = 0;510 600 int maxChan = 0; 511 601 int maxXpol = 0; 512 602 603 cSimulIF = 0; 513 604 for (int iIF = 0; iIF < cNIF; iIF++) { 514 605 if (cIFs[iIF]) { … … 536 627 537 628 // Maximum number of selected IFs in any simultaneous set. 538 simulIF = max(simulIF, cIFSel[iIF]+1);629 cSimulIF = max(cSimulIF, cIFSel[iIF]+1); 539 630 540 631 // Maximum memory required for any simultaneous set. … … 563 654 564 655 if (cNBin > 1 && cNBeamSel > 1) { 565 fprintf(stderr, "Cannot handle binning mode for multiple " 566 "beams.\n"); 656 os << LogIO::SEVERE << "Cannot handle binning mode for multiple beams.\nSelect a single beam for input." << LogIO::POST ; 567 657 close(); 568 658 return 1; 569 659 } 570 660 571 // Allocate buffer data storage. 661 // Allocate buffer data storage; the MBrecord constructor zeroes 662 // class members such as cycleNo that are tested in the first pass 663 // below. 572 664 int nBuff = cNBeamSel * cNBin; 573 cBuffer = new PKSMBrecord[nBuff];665 cBuffer = new MBrecord[nBuff]; 574 666 575 667 // Allocate memory for spectral arrays. 576 668 for (int ibuff = 0; ibuff < nBuff; ibuff++) { 577 cBuffer[ibuff].setNIFs( simulIF);669 cBuffer[ibuff].setNIFs(cSimulIF); 578 670 cBuffer[ibuff].allocate(0, maxChan, maxXpol); 671 672 // Signal that this IF in this buffer has been flushed. 673 for (int iIF = 0; iIF < cSimulIF; iIF++) { 674 cBuffer[ibuff].IFno[iIF] = 0; 675 } 579 676 } 580 677 … … 584 681 cScanNo = 1; 585 682 cCycleNo = 0; 586 cUTC = 0.0; 587 cStaleness = new int[cNBeamSel]; 588 for (int iBeamSel = 0; iBeamSel < cNBeamSel; iBeamSel++) { 589 cStaleness[iBeamSel] = 0; 590 } 683 cPrevUTC = -1.0; 591 684 } 592 685 … … 595 688 cScanNo++; 596 689 cCycleNo = 0; 597 cUTC = 0.0; 598 } 599 600 // Apply beam selection. 601 beamNo = int(baseline / 256.0); 690 cPrevUTC = -1.0; 691 } 692 693 // Apply beam and IF selection before the change-of-day test to allow 694 // a single selected beam and IF to be handled in binning-mode. 695 beamNo = int(cBaseline / 256.0); 696 if (beamNo == 1) { 697 // Store the position of beam 1 for grid convergence corrections. 698 cRA0 = cU; 699 cDec0 = cV; 700 } 602 701 iBeamSel = cBeamSel[beamNo-1]; 603 702 if (iBeamSel < 0) continue; 604 703 605 704 // Sanity check (mainly for MOPS). 606 if (if_no > cNIF) continue; 607 608 // Apply IF selection. 609 iIFSel = cIFSel[if_no - 1]; 705 if (cIFno > cNIF) continue; 706 707 // Apply IF selection; iIFSel == 0 for the first selected IF, == 1 708 // for the second, etc. 709 iIFSel = cIFSel[cIFno - 1]; 610 710 if (iIFSel < 0) continue; 611 711 612 sprintf(cDateObs, "%-10.10s", names_.datobs);613 614 // Change-of-day; note that the ut variable from RPFITS.h is global615 // and will be preserved between calls to this function.616 if (ut < cUTC - 85800.0) {617 ut += 86400.0;618 }619 620 // New integration cycle?621 if (ut > cUTC) {622 cCycleNo++;623 cUTC = ut + 0.0001;624 }625 712 626 713 if (cNBin > 1) { 627 714 // Binning mode: correct the time. 628 ut += param_.intbase * (bin - (cNBin + 1)/2.0); 629 } 715 cUTC += param_.intbase * (cBin - (cNBin + 1)/2.0); 716 } 717 718 // Check for change-of-day. 719 double cod = 0.0; 720 if ((cUTC + 86400.0) < (cPrevUTC + 600.0)) { 721 // cUTC should continue to increase past 86400 during a single scan. 722 // However, if the RPFITS file contains multiple scans that straddle 723 // midnight then cUTC can jump backwards from the end of one scan to 724 // the start of the next. 725 #ifdef PKSIO_DEBUG 726 char buf[256] ; 727 sprintf(buf, "Change-of-day on cUTC: %.1f -> %.1f\n", cPrevUTC, cUTC); 728 os << LogIO::DEBUGGING << buf << LogIO::POST ; 729 #endif 730 // Can't change the recorded value of cUTC directly (without also 731 // changing dateobs) so change-of-day must be recorded separately as 732 // an offset to be applied when comparing integration timestamps. 733 cod = 86400.0; 734 735 } 736 737 if ((cUTC+cod) < cPrevUTC - 1.0) { 738 if (cBin == 1 && iIFSel) { 739 // Multiple-IF, binning-mode data is only partially time ordered. 740 #ifdef PKSIO_DEBUG 741 fprintf(stderr, "New IF in multiple-IF, binning-mode data.\n"); 742 #endif 743 cCycleNo -= cNBin; 744 cPrevUTC = -1.0; 745 746 } else { 747 // All other data should be fully time ordered. 748 sprintf(cMsg, 749 "Cycle %d:%03d-%03d, UTC went backwards from\n" 750 "%.1f to %.1f! Incrementing day number,\n" 751 "positions may be unreliable.", cScanNo, cCycleNo, 752 cCycleNo+1, cPrevUTC, cUTC); 753 //logMsg(cMsg); 754 os << LogIO::WARN << cMsg << LogIO::POST ; 755 cUTC += 86400.0; 756 } 757 } 758 759 // New integration cycle? 760 if ((cUTC+cod) > cPrevUTC) { 761 cCycleNo++; 762 cPrevUTC = cUTC + 0.0001; 763 } 764 765 sprintf(cDateObs, "%-10.10s", names_.datobs); 766 cDateObs[10] = '\0'; 630 767 631 768 // Compute buffer number. 632 769 iMBuff = cBuffer + iBeamSel; 633 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);770 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 634 771 635 772 if (cCycleNo < iMBuff->cycleNo) { … … 640 777 641 778 // Begin flush cycle? 642 if (cEOS || (iMBuff->nIF && ut > iMBuff->utc + 0.0001)) {779 if (cEOS || (iMBuff->nIF && (cUTC+cod) > (iMBuff->utc+0.0001))) { 643 780 cFlushing = 1; 644 781 cFlushBin = 0; … … 647 784 648 785 #ifdef PKSIO_DEBUG 649 printf(" In:%4d%4d%3d%3d\n", cScanNo, cCycleNo, beamNo, if_no); 650 if (cEOS) printf("Start of new scan, flushing previous scan.\n"); 786 char rel = '='; 787 double dt = utcDiff(cUTC, cW); 788 if (dt < 0.0) { 789 rel = '<'; 790 } else if (dt > 0.0) { 791 rel = '>'; 792 } 793 794 sprintf(buf, "\n In:%4d%4d%3d%3d %.3f %c %.3f (%+.3fs) - " 795 "%sflushing\n", cScanNo, cCycleNo, beamNo, cIFno, cUTC, rel, cW, dt, 796 cFlushing ? "" : "not "); 797 os << LogIO::DEBUGGING << buf << LogIO::POST ; 798 if (cEOS) { 799 sprintf(buf, "Start of new scan, flushing previous scan.\n"); 800 os << LogIO::DEBUGGING << buf << LogIO::POST ; 801 } 651 802 #endif 652 803 } … … 663 814 iMBuff = cBuffer + iBeamSel + cNBeamSel*cFlushBin; 664 815 665 // iMBuff->nIF is set to zero (below) to signal that all IFs in666 // an integration have been flushed.816 // iMBuff->nIF is decremented (below) and if zero signals that all 817 // IFs in an integration have been flushed. 667 818 if (iMBuff->nIF) { 668 819 if (cycleNo == 0 || iMBuff->cycleNo < cycleNo) { … … 677 828 break; 678 829 } 830 831 // Start with the first IF in the next bin. 832 cFlushIF = 0; 679 833 } 680 834 … … 684 838 685 839 // Find the IF to flush. 686 for (; cFlushIF < iMBuff->nIF; cFlushIF++) {840 for (; cFlushIF < cSimulIF; cFlushIF++) { 687 841 if (iMBuff->IFno[cFlushIF]) break; 688 842 } … … 696 850 697 851 // The last record read must have been the first of a new cycle. 698 beamNo = int( baseline / 256.0);852 beamNo = int(cBaseline / 256.0); 699 853 iBeamSel = cBeamSel[beamNo-1]; 700 854 701 855 // Compute buffer number. 702 856 iMBuff = cBuffer + iBeamSel; 703 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);857 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 704 858 } 705 859 } 706 860 707 861 708 if (cFlushing && cFlushBin == 0 && cFlushIF == 0 && cInterp) { 709 // Interpolate the beam position at the start of the flush cycle. 862 if (cInterp && cFlushing == 1) { 863 // Start of flush cycle, interpolate the beam position. 864 // 865 // The position is measured by the control system at a time returned by 866 // RPFITSIN as the 'w' visibility coordinate. The ra and dec, returned 867 // as the 'u' and 'v' visibility coordinates, must be interpolated to 868 // the integration time which RPFITSIN returns as 'cUTC', this usually 869 // being a second or two later. The interpolation method used here is 870 // based on the scan rate. 871 // 872 // "This" RA, Dec, and UTC refers to the position currently stored in 873 // the buffer marked for output (iMBuff). This position is interpolated 874 // to the midpoint of that integration using either 875 // a) the rate currently sitting in iMBuff, which was computed from 876 // the previous integration, otherwise 877 // b) from the position recorded in the "next" integration which is 878 // currently sitting in the RPFITS commons, 879 // so that the position timestamps straddle the midpoint of the 880 // integration and is thereby interpolated rather than extrapolated. 881 // 882 // At the end of a scan, or if the next position has not been updated 883 // or its timestamp does not advance sufficiently, the most recent 884 // determination of the scan rate will be used for extrapolation which 885 // is quantified by the "rate age" measured in seconds beyond the 886 // interval defined by the position timestamps. 887 888 // At this point, iMBuff contains cU, cV, cW, parAngle and focusRot 889 // stored from the previous call to rpget() for this beam (i.e. "this"), 890 // and also raRate, decRate and paRate computed from that integration 891 // and the previous one. 892 double thisRA = iMBuff->ra; 893 double thisDec = iMBuff->dec; 894 double thisUTC = cPosUTC[iBeamSel]; 895 double thisPA = iMBuff->parAngle + iMBuff->focusRot; 896 710 897 #ifdef PKSIO_DEBUG 711 printf("Doing position interpolation for beam %d.\n", iMBuff->beamNo); 898 sprintf(buf, "This (%d) ra, dec, UTC: %9.4f %9.4f %10.3f %9.4f\n", 899 iMBuff->cycleNo, thisRA*R2D, thisDec*R2D, thisUTC, thisPA*R2D); 900 os << LogIO::DEBUGGING << buf << LogIO::POST ; 712 901 #endif 713 902 714 double prevRA = iMBuff->ra; 715 double prevDec = iMBuff->dec; 716 double prevUTC = cPosUTC[iBeamSel]; 717 718 if (!cEOF && !cEOS) { 719 // The position is measured by the control system at a time returned 720 // by RPFITSIN as the 'w' visibility coordinate. The ra and dec, 721 // returned as the 'u' and 'v' visibility coordinates, must be 722 // interpolated to the integration time which RPFITSIN returns as 723 // 'ut', this usually being a second or two later. 724 // 725 // Note that the time recorded as the 'w' visibility coordinate 726 // cycles through 86400 back to 0 at midnight, whereas that in 'ut' 727 // continues to increase past 86400. 728 729 double thisRA = u; 730 double thisDec = v; 731 double thisUTC = w; 732 733 if (thisUTC < prevUTC) { 734 // Must have cycled through midnight. 735 thisUTC += 86400.0; 736 } 737 738 // Guard against RA cycling through 24h in either direction. 739 if (fabs(thisRA - prevRA) > PI) { 740 if (thisRA < prevRA) { 741 thisRA += TWOPI; 903 if (cEOF || cEOS) { 904 // Use rates from the last cycle. 905 raRate = iMBuff->raRate; 906 decRate = iMBuff->decRate; 907 paRate = iMBuff->paRate; 908 909 } else { 910 if (cW == thisUTC) { 911 // The control system at Mopra typically does not update the 912 // positions between successive integration cycles at the end of a 913 // scan (nor are they flagged). In this case we use the previously 914 // computed rates, even if from the previous scan since these are 915 // likely to be a better guess than anything else. 916 raRate = iMBuff->raRate; 917 decRate = iMBuff->decRate; 918 paRate = iMBuff->paRate; 919 920 if (cU == thisRA && cV == thisDec) { 921 // Position and timestamp unchanged. 922 pCode = 1; 923 924 } else if (fabs(cU-thisRA) < 0.0001 && fabs(cV-thisDec) < 0.0001) { 925 // Allow small rounding errors (seen infrequently). 926 pCode = 1; 927 742 928 } else { 743 thisRA -= TWOPI; 929 // (cU,cV) are probably rubbish (not yet seen in practice). 930 pCode = 2; 931 cU = thisRA; 932 cV = thisDec; 744 933 } 745 } 746 747 // The control system at Mopra typically does not update the 748 // positions between successive integration cycles at the end of a 749 // scan (nor are they flagged). In this case we use the previously 750 // computed rates, even if from the previous scan since these are 751 // likely to be a better guess than anything else. 752 753 double dUTC = thisUTC - prevUTC; 754 755 // Scan rate for this beam. 756 if (dUTC > 0.0) { 757 iMBuff->raRate = (thisRA - prevRA) / dUTC; 758 iMBuff->decRate = (thisDec - prevDec) / dUTC; 759 760 if (cInterp == 2) { 761 // Use the same interpolation scheme as the original pksmbfits 762 // client. This incorrectly assumed that (thisUTC - prevUTC) is 763 // equal to the integration time and interpolated by computing a 764 // weighted sum of the positions before and after the required 765 // time. 766 767 double utc = iMBuff->utc; 768 if (utc - prevUTC > 100.0) { 769 // Must have cycled through midnight. 770 utc -= 86400.0; 934 935 #ifdef PKSIO_DEBUG 936 sprintf(buf, "Next (%d) ra, dec, UTC: %9.4f %9.4f %10.3f " 937 "(0.000s)\n", cCycleNo, cU*R2D, cV*R2D, cW); 938 os << LogIO::DEBUGGING << buf << LogIO::POST ; 939 #endif 940 941 } else { 942 double nextRA = cU; 943 double nextDec = cV; 944 945 // Check and, if necessary, repair the position timestamp, 946 // remembering that pCode refers to the NEXT cycle. 947 pCode = fixw(cDateObs, cCycleNo, beamNo, cAvRate, thisRA, thisDec, 948 thisUTC, nextRA, nextDec, cW); 949 if (pCode > 0) pCode += 3; 950 double nextUTC = cW; 951 952 #ifdef PKSIO_DEBUG 953 sprintf(buf, "Next (%d) ra, dec, UTC: %9.4f %9.4f %10.3f " 954 "(%+.3fs)\n", cCycleNo, nextRA*R2D, nextDec*R2D, nextUTC, 955 utcDiff(nextUTC, thisUTC)); 956 os << LogIO::DEBUGGING << buf << LogIO::POST ; 957 #endif 958 959 // Compute the scan rate for this beam. 960 double dUTC = utcDiff(nextUTC, thisUTC); 961 if ((0.0 < dUTC) && (dUTC < 600.0)) { 962 scanRate(cRA0, cDec0, thisRA, thisDec, nextRA, nextDec, dUTC, 963 raRate, decRate); 964 965 // Update the mean scan rate. 966 cAvRate[0] = (cAvRate[0]*cNRate + raRate) / (cNRate + 1); 967 cAvRate[1] = (cAvRate[1]*cNRate + decRate) / (cNRate + 1); 968 cNRate++; 969 970 // Rate of change of position angle. 971 if (sc_.sc_ant <= anten_.nant) { 972 paRate = 0.0; 973 } else { 974 int iOff = sc_.sc_q * (sc_.sc_ant - 1) - 1; 975 double nextPA = sc_.sc_cal[iOff + 4] + sc_.sc_cal[iOff + 7]; 976 double paDiff = nextPA - thisPA; 977 if (paDiff > PI) { 978 paDiff -= TWOPI; 979 } else if (paDiff < -PI) { 980 paDiff += TWOPI; 981 } 982 paRate = paDiff / dUTC; 771 983 } 772 984 773 double tw1 = 1.0 - (utc - prevUTC) / iMBuff->exposure; 774 double tw2 = 1.0 - (thisUTC - utc) / iMBuff->exposure; 775 double gamma = (tw2 / (tw1 + tw2)) * dUTC / (utc - prevUTC); 776 777 iMBuff->raRate *= gamma; 778 iMBuff->decRate *= gamma; 779 } 780 781 cStaleness[iBeamSel] = 0; 782 783 } else { 784 // Issue warnings. 785 int nch = 0; 786 fprintf(stderr, "WARNING, scan %d,%n cycle %d: Position ", 787 iMBuff->scanNo, &nch, iMBuff->cycleNo); 788 789 if (dUTC < 0.0) { 790 fprintf(stderr, "timestamp went backwards!\n"); 985 if (cInterp == 2) { 986 // Use the same interpolation scheme as the original pksmbfits 987 // client. This incorrectly assumed that (nextUTC - thisUTC) is 988 // equal to the integration time and interpolated by computing a 989 // weighted sum of the positions before and after the required 990 // time. 991 992 double utc = iMBuff->utc; 993 double tw1 = 1.0 - utcDiff(utc, thisUTC) / iMBuff->exposure; 994 double tw2 = 1.0 - utcDiff(nextUTC, utc) / iMBuff->exposure; 995 double gamma = (tw2 / (tw1 + tw2)) * dUTC / (utc - thisUTC); 996 997 // Guard against RA cycling through 24h in either direction. 998 if (fabs(nextRA - thisRA) > PI) { 999 if (nextRA < thisRA) { 1000 nextRA += TWOPI; 1001 } else { 1002 nextRA -= TWOPI; 1003 } 1004 } 1005 1006 raRate = gamma * (nextRA - thisRA) / dUTC; 1007 decRate = gamma * (nextDec - thisDec) / dUTC; 1008 } 1009 791 1010 } else { 792 if (thisRA != prevRA || thisDec != prevDec) { 793 fprintf(stderr, "changed but timestamp unchanged!\n"); 1011 if (cCycleNo == 2 && fabs(utcDiff(cUTC,cW)) < 600.0) { 1012 // thisUTC (i.e. cW for the first cycle) is rubbish, and 1013 // probably the position as well (extremely rare in practice, 1014 // e.g. 97-12-19_1029_235708-18_586e.hpf which actually has the 1015 // t/1000 scaling bug in the first cycle). 1016 iMBuff->pCode = 3; 1017 thisRA = cU; 1018 thisDec = cV; 1019 thisUTC = cW; 1020 raRate = 0.0; 1021 decRate = 0.0; 1022 paRate = 0.0; 1023 794 1024 } else { 795 fprintf(stderr, "and timestamp unchanged!\n"); 1025 // cW is rubbish and probably (cU,cV), and possibly the 1026 // parallactic angle and everything else as well (rarely seen 1027 // in practice, e.g. 97-12-09_0743_235707-58_327c.hpf and 1028 // 97-09-01_0034_123717-42_242b.hpf, the latter with bad 1029 // parallactic angle). 1030 pCode = 3; 1031 cU = thisRA; 1032 cV = thisDec; 1033 cW = thisUTC; 1034 raRate = iMBuff->raRate; 1035 decRate = iMBuff->decRate; 1036 paRate = iMBuff->paRate; 796 1037 } 797 1038 } 798 799 cStaleness[iBeamSel]++; 800 fprintf(stderr, "%-*s Using stale scan rate, staleness = %d " 801 "cycle%s.\n", nch, "WARNING,", cStaleness[iBeamSel], 802 (cStaleness[iBeamSel] == 1) ? "" : "s"); 803 804 if (thisRA != prevRA || thisDec != prevDec) { 805 if (iMBuff->raRate == 0.0 && iMBuff->decRate == 0.0) { 806 fprintf(stderr, "%-*s But the previous rate was zero! " 807 "Position will be inaccurate.\n", nch, "WARNING,"); 1039 } 1040 } 1041 1042 1043 // Choose the closest rate determination. 1044 if (cCycleNo == 1) { 1045 // Scan containing a single integration. 1046 iMBuff->raRate = 0.0; 1047 iMBuff->decRate = 0.0; 1048 iMBuff->paRate = 0.0; 1049 1050 } else { 1051 double dUTC = iMBuff->utc - cPosUTC[iBeamSel]; 1052 1053 if (dUTC >= 0.0) { 1054 // In HIPASS/ZOA, the position timestamp, which should always occur 1055 // on the whole second, normally precedes an integration midpoint 1056 // falling on the half-second. Consequently, positive ages are 1057 // always half-integral. 1058 dUTC = utcDiff(iMBuff->utc, cW); 1059 if (dUTC > 0.0) { 1060 iMBuff->rateAge = dUTC; 1061 } else { 1062 iMBuff->rateAge = 0.0f; 1063 } 1064 1065 iMBuff->raRate = raRate; 1066 iMBuff->decRate = decRate; 1067 iMBuff->paRate = paRate; 1068 1069 } else { 1070 // In HIPASS/ZOA, negative ages occur when the integration midpoint, 1071 // occurring on the whole second, precedes the position timestamp. 1072 // Thus negative ages are always an integral number of seconds. 1073 // They have only been seen to occur sporadically in the period 1074 // 1999/05/31 to 1999/11/01, e.g. 1999-07-26_1821_005410-74_007c.hpf 1075 // 1076 // In recent (2008/10/07) Mopra data, small negative ages (~10ms, 1077 // occasionally up to ~300ms) seem to be the norm, with both the 1078 // position timestamp and integration midpoint falling close to but 1079 // not on the integral second. 1080 if (cCycleNo == 2) { 1081 // We have to start with something! 1082 iMBuff->rateAge = dUTC; 1083 1084 } else { 1085 // Although we did not record the relevant position timestamp 1086 // explicitly, it can easily be deduced. 1087 double w = iMBuff->utc - utcDiff(cUTC, iMBuff->utc) - 1088 iMBuff->rateAge; 1089 dUTC = utcDiff(iMBuff->utc, w); 1090 1091 if (dUTC > 0.0) { 1092 iMBuff->rateAge = 0.0f; 1093 } else { 1094 iMBuff->rateAge = dUTC; 808 1095 } 809 1096 } 810 } 811 } 1097 1098 iMBuff->raRate = raRate; 1099 iMBuff->decRate = decRate; 1100 iMBuff->paRate = paRate; 1101 } 1102 } 1103 1104 #ifdef PKSIO_DEBUG 1105 double avRate = sqrt(cAvRate[0]*cAvRate[0] + cAvRate[1]*cAvRate[1]); 1106 sprintf(buf, "RA, Dec, Av & PA rates: %8.4f %8.4f %8.4f %8.4f " 1107 "pCode %d\n", raRate*R2D, decRate*R2D, avRate*R2D, paRate*R2D, pCode); 1108 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1109 #endif 1110 812 1111 813 1112 // Compute the position of this beam for all bins. … … 817 1116 cBuffer[jbuff].raRate = iMBuff->raRate; 818 1117 cBuffer[jbuff].decRate = iMBuff->decRate; 819 820 double dutc = cBuffer[jbuff].utc - prevUTC; 821 if (dutc > 100.0) { 1118 cBuffer[jbuff].paRate = iMBuff->paRate; 1119 1120 double dUTC = utcDiff(cBuffer[jbuff].utc, thisUTC); 1121 if (dUTC > 100.0) { 822 1122 // Must have cycled through midnight. 823 dutc -= 86400.0; 824 } 825 826 cBuffer[jbuff].ra = prevRA + cBuffer[jbuff].raRate * dutc; 827 cBuffer[jbuff].dec = prevDec + cBuffer[jbuff].decRate * dutc; 828 if (cBuffer[jbuff].ra < 0.0) { 829 cBuffer[jbuff].ra += TWOPI; 830 } else if (cBuffer[jbuff].ra > TWOPI) { 831 cBuffer[jbuff].ra -= TWOPI; 832 } 833 } 1123 dUTC -= 86400.0; 1124 } 1125 1126 applyRate(cRA0, cDec0, thisRA, thisDec, 1127 cBuffer[jbuff].raRate, cBuffer[jbuff].decRate, dUTC, 1128 cBuffer[jbuff].ra, cBuffer[jbuff].dec); 1129 1130 #ifdef PKSIO_DEBUG 1131 sprintf(buf, "Intp (%d) ra, dec, UTC: %9.4f %9.4f %10.3f (pCode, " 1132 "age: %d %.1fs)\n", iMBuff->cycleNo, cBuffer[jbuff].ra*R2D, 1133 cBuffer[jbuff].dec*R2D, cBuffer[jbuff].utc, iMBuff->pCode, 1134 iMBuff->rateAge); 1135 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1136 #endif 1137 } 1138 1139 cFlushing = 2; 834 1140 } 835 1141 … … 841 1147 842 1148 #ifdef PKSIO_DEBUG 843 printf("Out:%4d%4d%3d%3d\n", MBrec.scanNo, MBrec.cycleNo, MBrec.beamNo, 844 MBrec.IFno[0]); 1149 sprintf(buf, "Out:%4d%4d%3d%3d\n", MBrec.scanNo, MBrec.cycleNo, 1150 MBrec.beamNo, MBrec.IFno[0]); 1151 os << LogIO::DEBUGGING << buf << LogIO::POST ; 845 1152 #endif 846 1153 … … 848 1155 iMBuff->IFno[cFlushIF] = 0; 849 1156 850 if (cFlushIF == iMBuff->nIF - 1) { 851 // Signal that all IFs in this buffer location have been flushed. 852 iMBuff->nIF = 0; 1157 iMBuff->nIF--; 1158 if (iMBuff->nIF == 0) { 1159 // All IFs in this buffer location have been flushed. Stop cEOS 1160 // being set when the next integration is read. 1161 iMBuff->cycleNo = 0; 1162 853 1163 } else { 854 1164 // Carry on flushing the other IFs. … … 859 1169 if (cFlushBin == cNBin - 1) { 860 1170 if (cEOS || cEOF) { 861 // Stop cEOS being set when the next integration is read.862 iMBuff->cycleNo = 0;863 864 1171 // Carry on flushing other buffers. 865 1172 cFlushIF = 0; … … 869 1176 cFlushing = 0; 870 1177 871 beamNo = int( baseline / 256.0);1178 beamNo = int(cBaseline / 256.0); 872 1179 iBeamSel = cBeamSel[beamNo-1]; 873 1180 874 1181 // Compute buffer number. 875 1182 iMBuff = cBuffer + iBeamSel; 876 if (cNBin > 1) iMBuff += cNBeamSel*( bin-1);1183 if (cNBin > 1) iMBuff += cNBeamSel*(cBin-1); 877 1184 } 878 1185 } … … 880 1187 if (!cFlushing) { 881 1188 // Buffer this MBrec. 882 if ( cCycleNo == 1&& iMBuff->IFno[0]) {1189 if ((cScanNo > iMBuff->scanNo) && iMBuff->IFno[0]) { 883 1190 // Sanity check on the number of IFs in the new scan. 884 1191 if (if_.n_if != cNIF) { 885 fprintf(stderr, "WARNING, scan %d has %d IFs instead of %d, " 886 "continuing.\n", cScanNo, if_.n_if, cNIF); 887 } 888 } 889 890 iMBuff->scanNo = cScanNo; 891 iMBuff->cycleNo = cCycleNo; 892 893 // Times. 894 strncpy(iMBuff->datobs, cDateObs, 10); 895 iMBuff->utc = ut; 896 iMBuff->exposure = param_.intbase; 897 898 // Source identification. 899 sprintf(iMBuff->srcName, "%-16.16s", 900 names_.su_name + (sourceno-1)*16); 901 iMBuff->srcRA = doubles_.su_ra[sourceno-1]; 902 iMBuff->srcDec = doubles_.su_dec[sourceno-1]; 903 904 // Rest frequency of the line of interest. 905 iMBuff->restFreq = doubles_.rfreq; 906 if (strncmp(names_.instrument, "ATPKSMB", 7) == 0) { 907 // Fix the HI rest frequency recorded for Parkes multibeam data. 908 double reffreq = doubles_.freq; 909 double restfreq = doubles_.rfreq; 910 if ((restfreq == 0.0 || fabs(restfreq - reffreq) == 0.0) && 911 fabs(reffreq - 1420.40575e6) < 100.0) { 912 iMBuff->restFreq = 1420.40575e6; 913 } 914 } 915 916 // Observation type. 917 int j; 918 for (j = 0; j < 15; j++) { 919 iMBuff->obsType[j] = names_.card[11+j]; 920 if (iMBuff->obsType[j] == '\'') break; 921 } 922 iMBuff->obsType[j] = '\0'; 923 924 // Beam-dependent parameters. 925 iMBuff->beamNo = beamNo; 926 927 // Beam position at the specified time. 928 if (cTid) { 929 // Tidbinbilla data. 930 iMBuff->ra = doubles_.su_ra[sourceno-1]; 931 iMBuff->dec = doubles_.su_dec[sourceno-1]; 932 } else { 933 iMBuff->ra = u; 934 iMBuff->dec = v; 935 } 936 cPosUTC[iBeamSel] = w; 1192 sprintf(cMsg, "Scan %d has %d IFs instead of %d, " 1193 "continuing.", cScanNo, if_.n_if, cNIF); 1194 os << LogIO::WARN << cMsg << LogIO::POST ; 1195 } 1196 } 1197 1198 // Sanity check on incomplete integrations within a scan. 1199 if (iMBuff->nIF && (iMBuff->cycleNo != cCycleNo)) { 1200 // Force the incomplete integration to be flushed before proceeding. 1201 cFlushing = 1; 1202 continue; 1203 } 1204 1205 #ifdef PKSIO_DEBUG 1206 sprintf(buf, "Buf:%4d%4d%3d%3d\n", cScanNo, cCycleNo, beamNo, cIFno); 1207 os << LogIO::DEBUGGING << buf << LogIO::POST ; 1208 #endif 1209 1210 // Store IF-independent parameters only for the first IF of a new cycle, 1211 // particularly because this is the only one for which the scan rates 1212 // are computed above. 1213 int firstIF = (iMBuff->nIF == 0); 1214 if (firstIF) { 1215 iMBuff->scanNo = cScanNo; 1216 iMBuff->cycleNo = cCycleNo; 1217 1218 // Times. 1219 strcpy(iMBuff->datobs, cDateObs); 1220 iMBuff->utc = cUTC; 1221 iMBuff->exposure = param_.intbase; 1222 1223 // Source identification. 1224 sprintf(iMBuff->srcName, "%-16.16s", 1225 names_.su_name + (cSrcNo-1)*16); 1226 iMBuff->srcName[16] = '\0'; 1227 iMBuff->srcRA = doubles_.su_ra[cSrcNo-1]; 1228 iMBuff->srcDec = doubles_.su_dec[cSrcNo-1]; 1229 1230 // Rest frequency of the line of interest. 1231 iMBuff->restFreq = doubles_.rfreq; 1232 if (strncmp(names_.instrument, "ATPKSMB", 7) == 0) { 1233 // Fix the HI rest frequency recorded for Parkes multibeam data. 1234 double reffreq = doubles_.freq; 1235 double restfreq = doubles_.rfreq; 1236 if ((restfreq == 0.0 || fabs(restfreq - reffreq) == 0.0) && 1237 fabs(reffreq - 1420.405752e6) < 100.0) { 1238 iMBuff->restFreq = 1420.405752e6; 1239 } 1240 } 1241 1242 // Observation type. 1243 int j; 1244 for (j = 0; j < 15; j++) { 1245 iMBuff->obsType[j] = names_.card[11+j]; 1246 if (iMBuff->obsType[j] == '\'') break; 1247 } 1248 iMBuff->obsType[j] = '\0'; 1249 1250 // Beam-dependent parameters. 1251 iMBuff->beamNo = beamNo; 1252 1253 // Beam position at the specified time. 1254 if (cSUpos) { 1255 // Non-ATNF data that does not store the position in (u,v,w). 1256 iMBuff->ra = doubles_.su_ra[cSrcNo-1]; 1257 iMBuff->dec = doubles_.su_dec[cSrcNo-1]; 1258 } else { 1259 iMBuff->ra = cU; 1260 iMBuff->dec = cV; 1261 } 1262 cPosUTC[iBeamSel] = cW; 1263 iMBuff->pCode = pCode; 1264 1265 // Store rates for next time. 1266 iMBuff->raRate = raRate; 1267 iMBuff->decRate = decRate; 1268 iMBuff->paRate = paRate; 1269 } 937 1270 938 1271 // IF-dependent parameters. 939 int iIF = if_no - 1;1272 int iIF = cIFno - 1; 940 1273 int startChan = cStartChan[iIF]; 941 1274 int endChan = cEndChan[iIF]; … … 945 1278 946 1279 iIFSel = cIFSel[iIF]; 947 iMBuff->nIF++; 948 iMBuff->IFno[iIFSel] = if_no; 1280 if (iMBuff->IFno[iIFSel] == 0) { 1281 iMBuff->nIF++; 1282 iMBuff->IFno[iIFSel] = cIFno; 1283 } else { 1284 // Integration cycle written to the output file twice (the only known 1285 // example is 1999-05-22_1914_000-031805_03v.hpf). 1286 sprintf(cMsg, "Integration cycle %d:%d, beam %2d, \n" 1287 "IF %d was duplicated.", cScanNo, cCycleNo-1, 1288 beamNo, cIFno); 1289 os << LogIO::WARN << cMsg << LogIO::POST ; 1290 } 949 1291 iMBuff->nChan[iIFSel] = nChan; 950 1292 iMBuff->nPol[iIFSel] = cNPol[iIF]; … … 1005 1347 1006 1348 // The baseline flag may be set independently. 1007 if (rpflag == 0) rpflag = flag;1349 if (rpflag == 0) rpflag = cFlag; 1008 1350 1009 1351 // Copy and scale data. … … 1046 1388 1047 1389 1048 // Parallactic angle.1049 iMBuff->parAngle = sc_.sc_cal[scq*iBeam + 11];1050 1051 1390 // Calibration factor applied to the data by the correlator. 1052 1391 if (scq > 14) { … … 1059 1398 } 1060 1399 1061 if (sc_.sc_ant <= anten_.nant) { 1062 // No extra syscal information present. 1063 iMBuff->extraSysCal = 0; 1064 iMBuff->azimuth = 0.0f; 1065 iMBuff->elevation = 0.0f; 1066 iMBuff->parAngle = 0.0f; 1067 iMBuff->focusAxi = 0.0f; 1068 iMBuff->focusTan = 0.0f; 1069 iMBuff->focusRot = 0.0f; 1070 iMBuff->temp = 0.0f; 1071 iMBuff->pressure = 0.0f; 1072 iMBuff->humidity = 0.0f; 1073 iMBuff->windSpeed = 0.0f; 1074 iMBuff->windAz = 0.0f; 1075 strcpy(iMBuff->tcalTime, " "); 1076 iMBuff->refBeam = 0; 1077 1078 } else { 1079 // Additional information for Parkes Multibeam data. 1080 int iOff = scq*(sc_.sc_ant - 1) - 1; 1081 iMBuff->extraSysCal = 1; 1082 iMBuff->azimuth = sc_.sc_cal[iOff + 2]; 1083 iMBuff->elevation = sc_.sc_cal[iOff + 3]; 1084 iMBuff->parAngle = sc_.sc_cal[iOff + 4]; 1085 iMBuff->focusAxi = sc_.sc_cal[iOff + 5] * 1e-3; 1086 iMBuff->focusTan = sc_.sc_cal[iOff + 6] * 1e-3; 1087 iMBuff->focusRot = sc_.sc_cal[iOff + 7]; 1088 iMBuff->temp = sc_.sc_cal[iOff + 8]; 1089 iMBuff->pressure = sc_.sc_cal[iOff + 9]; 1090 iMBuff->humidity = sc_.sc_cal[iOff + 10]; 1091 iMBuff->windSpeed = sc_.sc_cal[iOff + 11]; 1092 iMBuff->windAz = sc_.sc_cal[iOff + 12]; 1093 1094 char *tcalTime = iMBuff->tcalTime; 1095 sprintf(tcalTime, "%-16.16s", (char *)(&sc_.sc_cal[iOff+13])); 1400 if (firstIF) { 1401 if (sc_.sc_ant <= anten_.nant) { 1402 // No extra syscal information present. 1403 iMBuff->extraSysCal = 0; 1404 iMBuff->azimuth = 0.0f; 1405 iMBuff->elevation = 0.0f; 1406 iMBuff->parAngle = 0.0f; 1407 iMBuff->focusAxi = 0.0f; 1408 iMBuff->focusTan = 0.0f; 1409 iMBuff->focusRot = 0.0f; 1410 iMBuff->temp = 0.0f; 1411 iMBuff->pressure = 0.0f; 1412 iMBuff->humidity = 0.0f; 1413 iMBuff->windSpeed = 0.0f; 1414 iMBuff->windAz = 0.0f; 1415 strcpy(iMBuff->tcalTime, " "); 1416 iMBuff->refBeam = 0; 1417 1418 } else { 1419 // Additional information for Parkes Multibeam data. 1420 int iOff = scq*(sc_.sc_ant - 1) - 1; 1421 iMBuff->extraSysCal = 1; 1422 1423 iMBuff->azimuth = sc_.sc_cal[iOff + 2]; 1424 iMBuff->elevation = sc_.sc_cal[iOff + 3]; 1425 iMBuff->parAngle = sc_.sc_cal[iOff + 4]; 1426 1427 iMBuff->focusAxi = sc_.sc_cal[iOff + 5] * 1e-3; 1428 iMBuff->focusTan = sc_.sc_cal[iOff + 6] * 1e-3; 1429 iMBuff->focusRot = sc_.sc_cal[iOff + 7]; 1430 1431 iMBuff->temp = sc_.sc_cal[iOff + 8]; 1432 iMBuff->pressure = sc_.sc_cal[iOff + 9]; 1433 iMBuff->humidity = sc_.sc_cal[iOff + 10]; 1434 iMBuff->windSpeed = sc_.sc_cal[iOff + 11]; 1435 iMBuff->windAz = sc_.sc_cal[iOff + 12]; 1436 1437 char *tcalTime = iMBuff->tcalTime; 1438 sprintf(tcalTime, "%-16.16s", (char *)(&sc_.sc_cal[iOff+13])); 1439 tcalTime[16] = '\0'; 1096 1440 1097 1441 #ifndef AIPS_LITTLE_ENDIAN 1098 // Do byte swapping on the ASCII date string.1099 for (int j = 0; j < 16; j += 4) {1100 char ctmp;1101 ctmp = tcalTime[j];1102 tcalTime[j] = tcalTime[j+3];1103 tcalTime[j+3] = ctmp;1104 ctmp = tcalTime[j+1];1105 tcalTime[j+1] = tcalTime[j+2];1106 tcalTime[j+2] = ctmp;1107 }1442 // Do byte swapping on the ASCII date string. 1443 for (int j = 0; j < 16; j += 4) { 1444 char ctmp; 1445 ctmp = tcalTime[j]; 1446 tcalTime[j] = tcalTime[j+3]; 1447 tcalTime[j+3] = ctmp; 1448 ctmp = tcalTime[j+1]; 1449 tcalTime[j+1] = tcalTime[j+2]; 1450 tcalTime[j+2] = ctmp; 1451 } 1108 1452 #endif 1109 1453 1110 // Reference beam number. 1111 float refbeam = sc_.sc_cal[iOff + 17]; 1112 if (refbeam > 0.0f || refbeam < 100.0f) { 1113 iMBuff->refBeam = int(refbeam); 1114 } else { 1115 iMBuff->refBeam = 0; 1454 // Reference beam number. 1455 float refbeam = sc_.sc_cal[iOff + 17]; 1456 if (refbeam > 0.0f || refbeam < 100.0f) { 1457 iMBuff->refBeam = int(refbeam); 1458 } else { 1459 iMBuff->refBeam = 0; 1460 } 1116 1461 } 1117 1462 } … … 1128 1473 int MBFITSreader::rpget(int syscalonly, int &EOS) 1129 1474 { 1475 const string methodName = "rpget()" ; 1476 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 1477 1130 1478 EOS = 0; 1131 1479 … … 1135 1483 int numErr = 0; 1136 1484 1137 jstat = 0;1485 int jstat = 0; 1138 1486 while (numErr < 10) { 1139 1487 int lastjstat = jstat; 1140 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin, 1141 &if_no, &sourceno); 1142 1143 switch(jstat) { 1488 1489 switch(rpfitsin(jstat)) { 1144 1490 case -1: 1145 1491 // Read failed; retry. 1146 1492 numErr++; 1147 fprintf(stderr, "RPFITS read failed - retrying.\n");1493 os << LogIO::WARN << "RPFITS read failed - retrying." << LogIO::POST ; 1148 1494 jstat = 0; 1149 1495 break; … … 1152 1498 // Successful read. 1153 1499 if (lastjstat == 0) { 1154 if ( baseline == -1) {1500 if (cBaseline == -1) { 1155 1501 // Syscal data. 1156 1502 if (syscalonly) { … … 1201 1547 default: 1202 1548 // Shouldn't reach here. 1203 fprintf(stderr, "Unrecognized RPFITSIN return code: %d (retrying)\n", 1204 jstat); 1549 sprintf(cMsg, "Unrecognized RPFITSIN return code: %d " 1550 "(retrying).", jstat); 1551 os << LogIO::WARN << cMsg << LogIO::POST ; 1205 1552 jstat = 0; 1206 1553 break; … … 1208 1555 } 1209 1556 1210 fprintf(stderr, "RPFITS read failed too many times.\n");1557 os << LogIO::SEVERE << "RPFITS read failed too many times." << LogIO::POST ; 1211 1558 return 2; 1559 } 1560 1561 //----------------------------------------------------- MBFITSreader::rpfitsin 1562 1563 // Wrapper around RPFITSIN that reports errors. Returned RPFITSIN subroutine 1564 // arguments are captured as MBFITSreader member variables. 1565 1566 int MBFITSreader::rpfitsin(int &jstat) 1567 1568 { 1569 rpfitsin_(&jstat, cVis, cWgt, &cBaseline, &cUTC, &cU, &cV, &cW, &cFlag, 1570 &cBin, &cIFno, &cSrcNo); 1571 1572 // Handle messages from RPFITSIN. 1573 /** 1574 if (names_.errmsg[0] != ' ') { 1575 int i; 1576 for (i = 80; i > 0; i--) { 1577 if (names_.errmsg[i-1] != ' ') break; 1578 } 1579 1580 sprintf(cMsg, "WARNING: Cycle %d:%03d, RPFITSIN reported -\n" 1581 " %.*s", cScanNo, cCycleNo, i, names_.errmsg); 1582 logMsg(cMsg); 1583 } 1584 **/ 1585 return jstat; 1586 } 1587 1588 //------------------------------------------------------- MBFITSreader::fixPos 1589 1590 // Check and, if necessary, repair a position timestamp. 1591 // 1592 // Problems with the position timestamp manifest themselves via the scan rate: 1593 // 1594 // 1) Zero scan rate pairs, 1997/02/28 to 1998/01/07 1595 // 1596 // These occur because the position timestamp for the first integration 1597 // of the pair is erroneous; the value recorded is t/1000, where t is the 1598 // true value. 1599 // Earliest known: 97-02-28_1725_132653-42_258a.hpf 1600 // Latest known: 98-01-02_1923_095644-50_165c.hpf 1601 // (time range chosen to encompass observing runs). 1602 // 1603 // 2) Slow-fast scan rate pairs (0.013 - 0.020 deg/s), 1604 // 1997/03/28 to 1998/01/07. 1605 // 1606 // The UTC position timestamp is 1.0s later than it should be (never 1607 // earlier), almost certainly arising from an error in the telescope 1608 // control system. 1609 // Earliest known: 97-03-28_0150_010420-74_008d.hpf 1610 // Latest known: 98-01-04_1502_065150-02_177c.hpf 1611 // (time range chosen to encompass observing runs). 1612 // 1613 // 3) Slow-fast scan rate pairs (0.015 - 0.018 deg/s), 1614 // 1999/05/20 to 2001/07/12 (HIPASS and ZOA), 1615 // 2001/09/02 to 2001/12/04 (HIPASS and ZOA), 1616 // 2002/03/28 to 2002/05/13 (ZOA only), 1617 // 2003/04/26 to 2003/06/09 (ZOA only). 1618 // Earliest known: 1999-05-20_1818_175720-50_297e.hpf 1619 // Latest known: 2001-12-04_1814_065531p14_173e.hpf (HIPASS) 1620 // 2003-06-09_1924_352-085940_-6c.hpf (ZOA) 1621 // 1622 // Caused by the Linux signalling NaN problem. IEEE "signalling" NaNs 1623 // are silently transformed to "quiet" NaNs during assignment by setting 1624 // bit 22. This affected RPFITS because of its use of VAX-format 1625 // floating-point numbers which, with their permuted bytes, may sometimes 1626 // appear as signalling NaNs. 1627 // 1628 // The problem arose when the linux correlator came online and was 1629 // fixed with a workaround to the RPFITS library (repeated episodes 1630 // are probably due to use of an older version of the library). It 1631 // should not have affected the data significantly because of the 1632 // low relative error, which ranges from 0.0000038 to 0.0000076, but 1633 // it is important for the computation of scan rates which requires 1634 // taking the difference of two large UTC timestamps, one or other 1635 // of which will have 0.5s added to it. 1636 // 1637 // The return value identifies which, if any, of these problems was repaired. 1638 1639 int MBFITSreader::fixw( 1640 const char *datobs, 1641 int cycleNo, 1642 int beamNo, 1643 double avRate[2], 1644 double thisRA, 1645 double thisDec, 1646 double thisUTC, 1647 double nextRA, 1648 double nextDec, 1649 float &nextUTC) 1650 { 1651 if (strcmp(datobs, "2003-06-09") > 0) { 1652 return 0; 1653 1654 } else if (strcmp(datobs, "1998-01-07") <= 0) { 1655 if (nextUTC < thisUTC && (nextUTC + 86400.0) > (thisUTC + 600.0)) { 1656 // Possible scaling problem. 1657 double diff = nextUTC*1000.0 - thisUTC; 1658 if (0.0 < diff && diff < 600.0) { 1659 nextUTC *= 1000.0; 1660 return 1; 1661 } else { 1662 // Irreparable. 1663 return -1; 1664 } 1665 } 1666 1667 if (cycleNo > 2) { 1668 if (beamNo == 1) { 1669 // This test is only reliable for beam 1. 1670 double dUTC = nextUTC - thisUTC; 1671 if (dUTC < 0.0) dUTC += 86400.0; 1672 1673 // Guard against RA cycling through 24h in either direction. 1674 if (fabs(nextRA - thisRA) > PI) { 1675 if (nextRA < thisRA) { 1676 nextRA += TWOPI; 1677 } else { 1678 nextRA -= TWOPI; 1679 } 1680 } 1681 1682 double dRA = (nextRA - thisRA) * cos(nextDec); 1683 double dDec = nextDec - thisDec; 1684 double arc = sqrt(dRA*dRA + dDec*dDec); 1685 1686 double averate = sqrt(avRate[0]*avRate[0] + avRate[1]*avRate[1]); 1687 double diff1 = fabs(averate - arc/(dUTC-1.0)); 1688 double diff2 = fabs(averate - arc/dUTC); 1689 if ((diff1 < diff2) && (diff1 < 0.05*averate)) { 1690 nextUTC -= 1.0; 1691 cCode5 = cycleNo; 1692 return 2; 1693 } else { 1694 cCode5 = 0; 1695 } 1696 1697 } else { 1698 if (cycleNo == cCode5) { 1699 nextUTC -= 1.0; 1700 return 2; 1701 } 1702 } 1703 } 1704 1705 } else if ((strcmp(datobs, "1999-05-20") >= 0 && 1706 strcmp(datobs, "2001-07-12") <= 0) || 1707 (strcmp(datobs, "2001-09-02") >= 0 && 1708 strcmp(datobs, "2001-12-04") <= 0) || 1709 (strcmp(datobs, "2002-03-28") >= 0 && 1710 strcmp(datobs, "2002-05-13") <= 0) || 1711 (strcmp(datobs, "2003-04-26") >= 0 && 1712 strcmp(datobs, "2003-06-09") <= 0)) { 1713 // Signalling NaN problem, e.g. 1999-07-26_1839_011106-74_009c.hpf. 1714 // Position timestamps should always be an integral number of seconds. 1715 double resid = nextUTC - int(nextUTC); 1716 if (resid == 0.5) { 1717 nextUTC -= 0.5; 1718 return 3; 1719 } 1720 } 1721 1722 return 0; 1212 1723 } 1213 1724 … … 1219 1730 { 1220 1731 if (cMBopen) { 1221 jstat = 1;1222 rpfitsin_(&jstat, cVis, weight, &baseline, &ut, &u, &v, &w, &flag, &bin,1223 & if_no, &sourceno);1732 int jstat = 1; 1733 rpfitsin_(&jstat, cVis, cWgt, &cBaseline, &cUTC, &cU, &cV, &cW, &cFlag, 1734 &cBin, &cIFno, &cSrcNo); 1224 1735 1225 1736 if (cBeams) delete [] cBeams; … … 1232 1743 if (cRefChan) delete [] cRefChan; 1233 1744 1234 if (cVis) delete [] cVis; 1745 if (cVis) delete [] cVis; 1746 if (cWgt) delete [] cWgt; 1235 1747 1236 1748 if (cBeamSel) delete [] cBeamSel; … … 1244 1756 } 1245 1757 } 1758 1759 //-------------------------------------------------------------------- utcDiff 1760 1761 // Subtract two UTCs (s) allowing for any plausible number of cycles through 1762 // 86400s, returning a result in the range [-43200, +43200]s. 1763 1764 double MBFITSreader::utcDiff(double utc1, double utc2) 1765 { 1766 double diff = utc1 - utc2; 1767 1768 if (diff > 43200.0) { 1769 diff -= 86400.0; 1770 while (diff > 43200.0) diff -= 86400.0; 1771 } else if (diff < -43200.0) { 1772 diff += 86400.0; 1773 while (diff < -43200.0) diff += 86400.0; 1774 } 1775 1776 return diff; 1777 } 1778 1779 //------------------------------------------------------- scanRate & applyRate 1780 1781 // Compute and apply the scan rate corrected for grid convergence. (ra0,dec0) 1782 // are the coordinates of the central beam, assumed to be the tracking centre. 1783 // The rate computed in RA will be a rate of change of angular distance in the 1784 // direction of increasing RA at the position of the central beam. Similarly 1785 // for declination. Angles in radian, time in s. 1786 1787 void MBFITSreader::scanRate( 1788 double ra0, 1789 double dec0, 1790 double ra1, 1791 double dec1, 1792 double ra2, 1793 double dec2, 1794 double dt, 1795 double &raRate, 1796 double &decRate) 1797 { 1798 // Transform to a system where the central beam lies on the equator at 12h. 1799 eulerx(ra1, dec1, ra0+HALFPI, -dec0, -HALFPI, ra1, dec1); 1800 eulerx(ra2, dec2, ra0+HALFPI, -dec0, -HALFPI, ra2, dec2); 1801 1802 raRate = (ra2 - ra1) / dt; 1803 decRate = (dec2 - dec1) / dt; 1804 } 1805 1806 1807 void MBFITSreader::applyRate( 1808 double ra0, 1809 double dec0, 1810 double ra1, 1811 double dec1, 1812 double raRate, 1813 double decRate, 1814 double dt, 1815 double &ra2, 1816 double &dec2) 1817 { 1818 // Transform to a system where the central beam lies on the equator at 12h. 1819 eulerx(ra1, dec1, ra0+HALFPI, -dec0, -HALFPI, ra1, dec1); 1820 1821 ra2 = ra1 + (raRate * dt); 1822 dec2 = dec1 + (decRate * dt); 1823 1824 // Transform back. 1825 eulerx(ra2, dec2, -HALFPI, dec0, ra0+HALFPI, ra2, dec2); 1826 } 1827 1828 //--------------------------------------------------------------------- eulerx 1829 1830 void MBFITSreader::eulerx( 1831 double lng0, 1832 double lat0, 1833 double phi0, 1834 double theta, 1835 double phi, 1836 double &lng1, 1837 double &lat1) 1838 1839 // Applies the Euler angle based transformation of spherical coordinates. 1840 // 1841 // phi0 Longitude of the ascending node in the old system, radians. The 1842 // ascending node is the point of intersection of the equators of 1843 // the two systems such that the equator of the new system crosses 1844 // from south to north as viewed in the old system. 1845 // 1846 // theta Angle between the poles of the two systems, radians. THETA is 1847 // positive for a positive rotation about the ascending node. 1848 // 1849 // phi Longitude of the ascending node in the new system, radians. 1850 1851 { 1852 // Compute intermediaries. 1853 double lng0p = lng0 - phi0; 1854 double slng0p = sin(lng0p); 1855 double clng0p = cos(lng0p); 1856 double slat0 = sin(lat0); 1857 double clat0 = cos(lat0); 1858 double ctheta = cos(theta); 1859 double stheta = sin(theta); 1860 1861 double x = clat0*clng0p; 1862 double y = clat0*slng0p*ctheta + slat0*stheta; 1863 1864 // Longitude in the new system. 1865 if (x != 0.0 || y != 0.0) { 1866 lng1 = phi + atan2(y, x); 1867 } else { 1868 // Longitude at the poles in the new system is consistent with that 1869 // specified in the old system. 1870 lng1 = phi + lng0p; 1871 } 1872 lng1 = fmod(lng1, TWOPI); 1873 if (lng1 < 0.0) lng1 += TWOPI; 1874 1875 lat1 = asin(slat0*ctheta - clat0*stheta*slng0p); 1876 } -
branches/alma/external/atnf/PKSIO/MBFITSreader.h
r1453 r1757 2 2 //# MBFITSreader.h: ATNF single-dish RPFITS reader. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: MBFITSreader.h,v 19.23 2009-09-29 07:33:38 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# The MBFITSreader class reads single dish RPFITS files (such as Parkes … … 39 41 40 42 #include <atnf/PKSIO/FITSreader.h> 41 #include <atnf/PKSIO/PKSMBrecord.h> 43 #include <atnf/PKSIO/MBrecord.h> 44 45 using namespace std; 42 46 43 47 // <summary> … … 78 82 double antPos[3], 79 83 char obsType[32], 84 char bunit[32], 80 85 float &equinox, 81 86 char radecsys[32], … … 101 106 102 107 // Read the next data record. 103 virtual int read( PKSMBrecord &record);108 virtual int read(MBrecord &record); 104 109 105 110 // Close the RPFITS file. … … 107 112 108 113 private: 109 char cDateObs[10]; 114 // RPFITSIN subroutine arguments. 115 int cBaseline, cFlag, cBin, cIFno, cSrcNo; 116 float cUTC, cU, cV, cW, *cVis, *cWgt; 117 118 char cDateObs[12]; 110 119 int *cBeamSel, *cChanOff, cFirst, *cIFSel, cInterp, cIntTime, cMBopen, 111 cMopra, cNBeamSel, cNBin, cRetry, *cStaleness, cTid, *cXpolOff; 112 float *cVis; 120 cMopra, cNBeamSel, cNBin, cRetry, cSimulIF, cSUpos, *cXpolOff; 113 121 114 122 // The data has to be bufferred to allow positions to be interpolated. 115 123 int cEOF, cEOS, cFlushBin, cFlushIF, cFlushing; 116 124 double *cPosUTC; 117 PKSMBrecord *cBuffer;125 MBrecord *cBuffer; 118 126 127 // Scan and cycle number bookkeeping. 119 128 int cCycleNo, cScanNo; 120 double c UTC;129 double cPrevUTC; 121 130 122 131 // Read the next data record from the RPFITS file. 123 132 int rpget(int syscalonly, int &EOS); 124 // These are no longer define in the RPFITS.h file so moved here 125 int jstat; 126 float *weight; 127 int baseline; 128 int flag; 129 int bin; 130 int if_no; 131 int sourceno; 132 float *vis; 133 float u; 134 float v; 135 float w; 136 float ut; 137 133 int rpfitsin(int &jstat); 134 135 // Check and, if necessary, repair a position timestamp. 136 int cCode5, cNRate; 137 double cAvRate[2]; 138 int fixw(const char *datobs, int cycleNo, int beamNo, double avRate[2], 139 double thisRA, double thisDec, double thisUTC, 140 double nextRA, double nextDec, float &nextUTC); 141 142 // Subtract two UTCs (s). 143 double utcDiff(double utc1, double utc2); 144 145 // Compute and apply the scan rate corrected for grid convergence. 146 double cRA0, cDec0; 147 void scanRate(double ra0, double dec0, 148 double ra1, double dec1, 149 double ra2, double dec2, double dt, 150 double &raRate, double &decRate); 151 void applyRate(double ra0, double dec0, 152 double ra1, double dec1, 153 double raRate, double decRate, double dt, 154 double &ra2, double &dec2); 155 void eulerx(double lng0, double lat0, double phi0, double theta, 156 double phi, double &lng1, double &lat1); 138 157 }; 139 158 -
branches/alma/external/atnf/PKSIO/MBrecord.cc
r1752 r1757 322 322 refBeam = other.refBeam; 323 323 324 polNo = other.polNo ; 325 srcVelocity = other.srcVelocity ; 326 324 327 return *this; 325 328 } … … 436 439 refBeam = other.refBeam; 437 440 441 polNo = other.polNo ; 442 srcVelocity = other.srcVelocity ; 443 438 444 return 0; 439 445 } -
branches/alma/external/atnf/PKSIO/MBrecord.h
r1752 r1757 166 166 short refBeam; // Reference beam, in beam-switching (MX) 167 167 // mode (added 1999/03/17). 168 int polNo ; // polarization ID 169 float srcVelocity ; // source velocity w.r.t. reference frame 168 170 169 171 private: -
branches/alma/external/atnf/PKSIO/PKSFITSreader.cc
r1453 r1757 2 2 //# PKSFITSreader.cc: Class to read Parkes multibeam data from a FITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.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. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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/>. 27 21 //# 28 //# $Id$ 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: PKSFITSreader.cc,v 19.23 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/02, Mark Calabretta, ATNF … … 34 37 #include <atnf/PKSIO/SDFITSreader.h> 35 38 #include <atnf/PKSIO/PKSFITSreader.h> 36 #include <atnf/PKSIO/PKSMBrecord.h> 37 39 #include <atnf/PKSIO/PKSrecord.h> 40 41 #include <casa/stdio.h> 38 42 #include <casa/Arrays/Array.h> 39 43 #include <casa/BasicMath/Math.h> 40 44 #include <casa/Quanta/MVTime.h> 41 42 #include <casa/stdio.h> 45 #include <casa/Logging/LogIO.h> 43 46 44 47 //----------------------------------------------- PKSFITSreader::PKSFITSreader … … 76 79 Int PKSFITSreader::open( 77 80 const String fitsName, 81 const String antenna, 78 82 Vector<Bool> &beams, 79 83 Vector<Bool> &IFs, … … 86 90 int extraSysCal, haveBase_, *haveXPol_, haveSpectra_, nBeam, *nChan_, 87 91 nIF, *nPol_, status; 88 if ((status = cReader->open((char *)fitsName.chars(), nBeam, cBeams, nIF, 89 cIFs, nChan_, nPol_, haveXPol_, haveBase_, 90 haveSpectra_, extraSysCal))) { 92 status = cReader->open((char *)fitsName.chars(), nBeam, cBeams, nIF, cIFs, 93 nChan_, nPol_, haveXPol_, haveBase_, haveSpectra_, 94 extraSysCal); 95 //logMsg(cReader->getMsg()); 96 //cReader->clearMsg(); 97 if (status) { 91 98 return status; 92 99 } … … 138 145 Vector<Double> &antPosition, 139 146 String &obsType, 147 String &bunit, 140 148 Float &equinox, 141 149 String &dopplerFrame, 142 150 Double &mjd, 143 151 Double &refFreq, 144 Double &bandwidth ,145 String &fluxunit) 146 { 147 char datobs[32], dopplerFrame_[32], observer_[32], obsType_[32],148 project_[32], radecsys[32], telescope[32];152 Double &bandwidth) 153 { 154 char bunit_[32], datobs[32], dopplerFrame_[32], observer_[32], 155 obsType_[32], project_[32], radecsys[32], telescope[32]; 156 int status; 149 157 float equinox_; 150 158 double antPos[3], utc; 151 159 152 if (cReader->getHeader(observer_, project_, telescope, antPos, obsType_, 153 equinox_, radecsys, dopplerFrame_, datobs, utc, 154 refFreq, bandwidth)) { 160 status = cReader->getHeader(observer_, project_, telescope, antPos, 161 obsType_, bunit_, equinox_, radecsys, 162 dopplerFrame_, datobs, utc, refFreq, bandwidth); 163 //logMsg(cReader->getMsg()); 164 //cReader->clearMsg(); 165 if (status) { 155 166 return 1; 156 167 } 157 168 158 fluxunit = "";159 169 observer = trim(observer_); 160 170 project = trim(project_); … … 165 175 antPosition(2) = antPos[2]; 166 176 obsType = trim(obsType_); 177 bunit = trim(bunit_); 167 178 equinox = equinox_; 168 179 dopplerFrame = trim(dopplerFrame_); … … 188 199 double *startfreq, *endfreq; 189 200 190 Int status; 191 if (!(status = cReader->getFreqInfo(nIF, startfreq, endfreq))) { 201 Int status = cReader->getFreqInfo(nIF, startfreq, endfreq); 202 203 //logMsg(cReader->getMsg()); 204 //cReader->clearMsg(); 205 if (!status) { 192 206 startFreq.takeStorage(IPosition(1,nIF), startfreq, TAKE_OVER); 193 207 endFreq.takeStorage(IPosition(1,nIF), endfreq, TAKE_OVER); … … 209 223 const Bool getSpectra, 210 224 const Bool getXPol, 211 const Bool getFeedPos) 225 const Bool getFeedPos, 226 const Bool getPointing, 227 const Int coordSys) 212 228 { 213 229 // Apply beam selection. … … 277 293 cGetXPol = getXPol; 278 294 cGetFeedPos = getFeedPos; 295 cGetPointing = getPointing; 296 cCoordSys = coordSys; 279 297 280 298 uInt maxNChan = cReader->select(start, end, ref, cGetSpectra, cGetXPol, 281 cGetFeedPos); 299 cGetFeedPos, cGetPointing, cCoordSys); 300 //logMsg(cReader->getMsg()); 301 //cReader->clearMsg(); 282 302 283 303 delete [] end; … … 302 322 double* posns; 303 323 304 Int status; 305 if (!(status = cReader->findRange(nRow, nSel, dateSpan, utcSpan, posns))) { 324 Int status = cReader->findRange(nRow, nSel, dateSpan, utcSpan, posns); 325 //logMsg(cReader->getMsg()); 326 //cReader->clearMsg(); 327 328 if (!status) { 306 329 timeSpan.resize(2); 307 330 … … 322 345 // Read the next data record. 323 346 324 Int PKSFITSreader::read( 325 Int &scanNo, 326 Int &cycleNo, 327 Double &mjd, 328 Double &interval, 329 String &fieldName, 330 String &srcName, 331 Vector<Double> &srcDir, 332 Vector<Double> &srcPM, 333 Double &srcVel, 334 String &obsType, 335 Int &IFno, 336 Double &refFreq, 337 Double &bandwidth, 338 Double &freqInc, 339 Vector<Double> &restFreq, 340 Vector<Float> &tcal, 341 String &tcalTime, 342 Float &azimuth, 343 Float &elevation, 344 Float &parAngle, 345 Float &focusAxi, 346 Float &focusTan, 347 Float &focusRot, 348 Float &temperature, 349 Float &pressure, 350 Float &humidity, 351 Float &windSpeed, 352 Float &windAz, 353 Int &refBeam, 354 Int &beamNo, 355 Vector<Double> &direction, 356 Vector<Double> &scanRate, 357 Vector<Float> &tsys, 358 Vector<Float> &sigma, 359 Vector<Float> &calFctr, 360 Matrix<Float> &baseLin, 361 Matrix<Float> &baseSub, 362 Matrix<Float> &spectra, 363 Matrix<uChar> &flagged, 364 Complex &xCalFctr, 365 Vector<Complex> &xPol) 366 { 367 Int status; 368 369 if ((status = cReader->read(cMBrec))) { 347 Int PKSFITSreader::read(PKSrecord &pksrec) 348 { 349 Int status = cReader->read(cMBrec); 350 //logMsg(cReader->getMsg()); 351 //cReader->clearMsg(); 352 353 if (status) { 370 354 if (status != -1) { 371 355 status = 1; … … 379 363 uInt nPol = cMBrec.nPol[0]; 380 364 381 scanNo = cMBrec.scanNo; 382 cycleNo = cMBrec.cycleNo; 365 pksrec.scanNo = cMBrec.scanNo; 366 pksrec.cycleNo = cMBrec.cycleNo; 367 pksrec.polNo = cMBrec.polNo ; 383 368 384 369 // Extract MJD. 385 370 Int day, month, year; 386 sscanf(cMBrec.datobs, "%4d-%2d-%2d", &year, &month, &day); 387 mjd = MVTime(year, month, Double(day)).day() + cMBrec.utc/86400.0; 388 389 interval = cMBrec.exposure; 390 391 fieldName = trim(cMBrec.srcName); 392 srcName = fieldName; 393 srcDir(0) = cMBrec.srcRA; 394 srcDir(1) = cMBrec.srcDec; 395 srcPM(0) = 0.0; 396 srcPM(1) = 0.0; 397 srcVel = 0.0; 398 obsType = trim(cMBrec.obsType); 399 400 IFno = cMBrec.IFno[0]; 371 if ( strstr( cMBrec.datobs, "T" ) == NULL ) { 372 sscanf(cMBrec.datobs, "%4d-%2d-%2d", &year, &month, &day); 373 pksrec.mjd = MVTime(year, month, Double(day)).day() + cMBrec.utc/86400.0; 374 } 375 else { 376 Double dd, hour, min, sec ; 377 sscanf( cMBrec.datobs, "%4d-%2d-%2lfT%lf:%lf:%lf", &year, &month, &dd, &hour, &min, &sec ) ; 378 dd = dd + ( hour * 3600.0 + min * 60.0 + sec ) / 86400.0 ; 379 pksrec.mjd = MVTime(year, month, dd).day() ; 380 } 381 382 pksrec.interval = cMBrec.exposure; 383 384 pksrec.fieldName = trim(cMBrec.srcName); 385 pksrec.srcName = pksrec.fieldName; 386 387 int namelen = pksrec.srcName.length() ; 388 if ( namelen > 4 ) { 389 String srcsub = pksrec.srcName.substr( namelen-4, 4 ) ; 390 if ( srcsub.find( "_psc" ) != string::npos ) { 391 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 392 pksrec.srcName = pksrec.fieldName + "_ps_calon" ; 393 } 394 else if ( srcsub.find( "_pso" ) != string::npos ) { 395 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 396 pksrec.srcName = pksrec.fieldName + "_ps" ; 397 } 398 else if ( srcsub.find( "_prc" ) != string::npos ) { 399 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 400 pksrec.srcName = pksrec.fieldName + "_psr_calon" ; 401 } 402 else if ( srcsub.find( "_pro" ) != string::npos ) { 403 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 404 pksrec.srcName = pksrec.fieldName + "_psr" ; 405 } 406 else if ( srcsub.find( "_fsc" ) != string::npos ) { 407 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 408 pksrec.srcName = pksrec.fieldName + "_fs_calon" ; 409 } 410 else if ( srcsub.find( "_fso" ) != string::npos ) { 411 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 412 pksrec.srcName = pksrec.fieldName + "_fs" ; 413 } 414 else if ( srcsub.find( "_frc" ) != string::npos ) { 415 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 416 pksrec.srcName = pksrec.fieldName + "_fsr_calon" ; 417 } 418 else if ( srcsub.find( "_fro" ) != string::npos ) { 419 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 420 pksrec.srcName = pksrec.fieldName + "_fsr" ; 421 } 422 else if ( srcsub.find( "_nsc" ) != string::npos || srcsub.find( "_nrc" ) != string::npos ) { 423 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 424 pksrec.srcName = pksrec.fieldName + "_nod_calon" ; 425 } 426 else if ( srcsub.find( "_nso" ) != string::npos || srcsub.find( "_nro" ) != string::npos ) { 427 pksrec.fieldName = pksrec.srcName.substr( 0, namelen-4 ) ; 428 pksrec.srcName = pksrec.fieldName + "_nod" ; 429 } 430 } 431 432 pksrec.srcDir.resize(2); 433 pksrec.srcDir(0) = cMBrec.srcRA; 434 pksrec.srcDir(1) = cMBrec.srcDec; 435 436 pksrec.srcPM.resize(2); 437 pksrec.srcPM(0) = 0.0; 438 pksrec.srcPM(1) = 0.0; 439 pksrec.srcVel = cMBrec.srcVelocity; 440 pksrec.obsType = trim(cMBrec.obsType); 441 442 pksrec.IFno = cMBrec.IFno[0]; 401 443 Double chanWidth = fabs(cMBrec.fqDelt[0]); 402 refFreq = cMBrec.fqRefVal[0]; 403 bandwidth = chanWidth * nChan; 404 freqInc = cMBrec.fqDelt[0]; 405 //restFreq = cMBrec.restFreq; 406 restFreq.resize(1); 407 restFreq(0) = cMBrec.restFreq; 408 409 tcal.resize(nPol); 444 pksrec.refFreq = cMBrec.fqRefVal[0]; 445 pksrec.bandwidth = chanWidth * nChan; 446 pksrec.freqInc = cMBrec.fqDelt[0]; 447 pksrec.restFreq.resize(1) ; 448 pksrec.restFreq(0) = cMBrec.restFreq; 449 450 pksrec.tcal.resize(nPol); 410 451 for (uInt ipol = 0; ipol < nPol; ipol++) { 411 tcal(ipol) = cMBrec.tcal[0][ipol]; 412 } 413 tcalTime = trim(cMBrec.tcalTime); 414 azimuth = cMBrec.azimuth; 415 elevation = cMBrec.elevation; 416 parAngle = cMBrec.parAngle; 417 focusAxi = cMBrec.focusAxi; 418 focusTan = cMBrec.focusTan; 419 focusRot = cMBrec.focusRot; 420 421 temperature = cMBrec.temp; 422 pressure = cMBrec.pressure; 423 humidity = cMBrec.humidity; 424 windSpeed = cMBrec.windSpeed; 425 windAz = cMBrec.windAz; 426 427 refBeam = cMBrec.refBeam; 428 beamNo = cMBrec.beamNo; 429 430 direction(0) = cMBrec.ra; 431 direction(1) = cMBrec.dec; 432 scanRate(0) = cMBrec.raRate; 433 scanRate(1) = cMBrec.decRate; 434 435 tsys.resize(nPol); 436 sigma.resize(nPol); 437 calFctr.resize(nPol); 452 pksrec.tcal(ipol) = cMBrec.tcal[0][ipol]; 453 } 454 pksrec.tcalTime = trim(cMBrec.tcalTime); 455 pksrec.azimuth = cMBrec.azimuth; 456 pksrec.elevation = cMBrec.elevation; 457 pksrec.parAngle = cMBrec.parAngle; 458 459 pksrec.focusAxi = cMBrec.focusAxi; 460 pksrec.focusTan = cMBrec.focusTan; 461 pksrec.focusRot = cMBrec.focusRot; 462 463 pksrec.temperature = cMBrec.temp; 464 pksrec.pressure = cMBrec.pressure; 465 pksrec.humidity = cMBrec.humidity; 466 pksrec.windSpeed = cMBrec.windSpeed; 467 pksrec.windAz = cMBrec.windAz; 468 469 pksrec.refBeam = cMBrec.refBeam; 470 pksrec.beamNo = cMBrec.beamNo; 471 472 pksrec.direction.resize(2); 473 pksrec.direction(0) = cMBrec.ra; 474 pksrec.direction(1) = cMBrec.dec; 475 pksrec.pCode = cMBrec.pCode; 476 pksrec.rateAge = cMBrec.rateAge; 477 pksrec.scanRate.resize(2); 478 pksrec.scanRate(0) = cMBrec.raRate; 479 pksrec.scanRate(1) = cMBrec.decRate; 480 pksrec.paRate = cMBrec.paRate; 481 482 pksrec.tsys.resize(nPol); 483 pksrec.sigma.resize(nPol); 484 pksrec.calFctr.resize(nPol); 438 485 for (uInt ipol = 0; ipol < nPol; ipol++) { 439 tsys(ipol) = cMBrec.tsys[0][ipol]; 440 sigma(ipol) = tsys(ipol) / 0.81 / sqrt(interval * chanWidth); 441 calFctr(ipol) = cMBrec.calfctr[0][ipol]; 486 pksrec.tsys(ipol) = cMBrec.tsys[0][ipol]; 487 pksrec.sigma(ipol) = (pksrec.tsys(ipol) / 0.81) / 488 sqrt(pksrec.interval * chanWidth); 489 pksrec.calFctr(ipol) = cMBrec.calfctr[0][ipol]; 442 490 } 443 491 444 492 if (cMBrec.haveBase) { 445 baseLin.resize(2,nPol);446 baseSub.resize(9,nPol);493 pksrec.baseLin.resize(2,nPol); 494 pksrec.baseSub.resize(24,nPol); 447 495 448 496 for (uInt ipol = 0; ipol < nPol; ipol++) { 449 baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0];450 baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1];451 452 for (uInt j = 0; j < 9; j++) {453 baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j];497 pksrec.baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0]; 498 pksrec.baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1]; 499 500 for (uInt j = 0; j < 24; j++) { 501 pksrec.baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j]; 454 502 } 455 503 } 456 504 457 505 } else { 458 baseLin.resize(0,0);459 baseSub.resize(0,0);506 pksrec.baseLin.resize(0,0); 507 pksrec.baseSub.resize(0,0); 460 508 } 461 509 462 510 if (cGetSpectra && cMBrec.haveSpectra) { 463 spectra.resize(nChan,nPol); 464 spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], SHARE); 465 466 flagged.resize(nChan,nPol); 467 flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], SHARE); 511 pksrec.spectra.resize(nChan,nPol); 512 pksrec.spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], 513 SHARE); 514 515 pksrec.flagged.resize(nChan,nPol); 516 pksrec.flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], 517 SHARE); 468 518 469 519 } else { 470 spectra.resize(0,0);471 flagged.resize(0,0);520 pksrec.spectra.resize(0,0); 521 pksrec.flagged.resize(0,0); 472 522 } 473 523 474 524 if (cGetXPol) { 475 xCalFctr = Complex(cMBrec.xcalfctr[0][0], cMBrec.xcalfctr[0][1]); 476 xPol.resize(nChan); 477 xPol.takeStorage(IPosition(1,nChan), (Complex *)cMBrec.xpol[0], SHARE); 525 pksrec.xCalFctr = Complex(cMBrec.xcalfctr[0][0], 526 cMBrec.xcalfctr[0][1]); 527 pksrec.xPol.resize(nChan); 528 pksrec.xPol.takeStorage(IPosition(1,nChan), (Complex *)cMBrec.xpol[0], 529 SHARE); 478 530 } 479 531 … … 481 533 } 482 534 483 //-------------------------------------------------------- PKSFITSreader::read484 485 // Read the next data record, just the basics.486 487 Int PKSFITSreader::read(488 Int &IFno,489 Vector<Float> &tsys,490 Vector<Float> &calFctr,491 Matrix<Float> &baseLin,492 Matrix<Float> &baseSub,493 Matrix<Float> &spectra,494 Matrix<uChar> &flagged)495 {496 Int status;497 498 if ((status = cReader->read(cMBrec))) {499 if (status != -1) {500 status = 1;501 }502 503 return status;504 }505 506 IFno = cMBrec.IFno[0];507 508 uInt nChan = cMBrec.nChan[0];509 uInt nPol = cMBrec.nPol[0];510 511 tsys.resize(nPol);512 calFctr.resize(nPol);513 for (uInt ipol = 0; ipol < nPol; ipol++) {514 tsys(ipol) = cMBrec.tsys[0][ipol];515 calFctr(ipol) = cMBrec.calfctr[0][ipol];516 }517 518 if (cMBrec.haveBase) {519 baseLin.resize(2,nPol);520 baseSub.resize(9,nPol);521 522 for (uInt ipol = 0; ipol < nPol; ipol++) {523 baseLin(0,ipol) = cMBrec.baseLin[0][ipol][0];524 baseLin(1,ipol) = cMBrec.baseLin[0][ipol][1];525 526 for (uInt j = 0; j < 9; j++) {527 baseSub(j,ipol) = cMBrec.baseSub[0][ipol][j];528 }529 }530 531 } else {532 baseLin.resize(0,0);533 baseSub.resize(0,0);534 }535 536 if (cGetSpectra && cMBrec.haveSpectra) {537 spectra.resize(nChan,nPol);538 spectra.takeStorage(IPosition(2,nChan,nPol), cMBrec.spectra[0], SHARE);539 540 flagged.resize(nChan,nPol);541 flagged.takeStorage(IPosition(2,nChan,nPol), cMBrec.flagged[0], SHARE);542 543 } else {544 spectra.resize(0,0);545 flagged.resize(0,0);546 }547 548 return 0;549 }550 551 535 //------------------------------------------------------- PKSFITSreader::close 552 536 … … 556 540 { 557 541 cReader->close(); 542 //logMsg(cReader->getMsg()); 543 //cReader->clearMsg(); 558 544 } 559 545 -
branches/alma/external/atnf/PKSIO/PKSFITSreader.h
r1453 r1757 2 2 //# PKSFITSreader.h: Class to read Parkes Multibeam data from a FITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSFITSreader.h,v 19.18 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# This class is basically a wrapper class for reading data from either an … … 39 42 40 43 #include <atnf/PKSIO/FITSreader.h> 44 #include <atnf/PKSIO/PKSrecord.h> 41 45 #include <atnf/PKSIO/PKSreader.h> 42 46 43 47 #include <casa/aips.h> 48 #include <casa/stdio.h> 44 49 #include <casa/Arrays/Vector.h> 45 50 #include <casa/Arrays/Matrix.h> … … 47 52 #include <casa/BasicSL/String.h> 48 53 54 #include <casa/namespace.h> 55 49 56 // <summary> 50 57 // Class to read Parkes Multibeam data from a FITS file. 51 58 // </summary> 52 59 53 #include <casa/namespace.h>54 60 class PKSFITSreader : public PKSreader 55 61 { … … 67 73 virtual Int open( 68 74 const String fitsName, 75 const String antenna, 69 76 Vector<Bool> &beams, 70 77 Vector<Bool> &IFs, … … 82 89 Vector<Double> &antPosition, 83 90 String &obsType, 91 String &bunit, 84 92 Float &equinox, 85 93 String &dopplerFrame, 86 94 Double &mjd, 87 95 Double &refFreq, 88 Double &bandwidth, 89 String &fluxunit); 96 Double &bandwidth); 90 97 91 98 // Get frequency parameters for each IF. … … 104 111 const Bool getSpectra = True, 105 112 const Bool getXPol = False, 106 const Bool getFeedPos = False); 113 const Bool getFeedPos = False, 114 const Bool getPointing = False, 115 const Int coordSys = 0); 107 116 108 117 // Find the range of the data selected in time and position. … … 114 123 115 124 // Read the next data record. 116 virtual Int read( 117 Int &scanNo, 118 Int &cycleNo, 119 Double &mjd, 120 Double &interval, 121 String &fieldName, 122 String &srcName, 123 Vector<Double> &srcDir, 124 Vector<Double> &srcPM, 125 Double &srcVel, 126 String &obsType, 127 Int &IFno, 128 Double &refFreq, 129 Double &bandwidth, 130 Double &freqInc, 131 Vector<Double> &restFreq, 132 Vector<Float> &tcal, 133 String &tcalTime, 134 Float &azimuth, 135 Float &elevation, 136 Float &parAngle, 137 Float &focusAxi, 138 Float &focusTan, 139 Float &focusRot, 140 Float &temperature, 141 Float &pressure, 142 Float &humidity, 143 Float &windSpeed, 144 Float &windAz, 145 Int &refBeam, 146 Int &beamNo, 147 Vector<Double> &direction, 148 Vector<Double> &scanRate, 149 Vector<Float> &tsys, 150 Vector<Float> &sigma, 151 Vector<Float> &calFctr, 152 Matrix<Float> &baseLin, 153 Matrix<Float> &baseSub, 154 Matrix<Float> &spectra, 155 Matrix<uChar> &flagged, 156 Complex &xCalFctr, 157 Vector<Complex> &xPol); 158 159 // Read the next data record, just the basics. 160 virtual Int read( 161 Int &IFno, 162 Vector<Float> &tsys, 163 Vector<Float> &calFctr, 164 Matrix<Float> &baseLin, 165 Matrix<Float> &baseSub, 166 Matrix<Float> &spectra, 167 Matrix<uChar> &flagged); 125 virtual Int read(PKSrecord &pksrec); 168 126 169 127 // Close the FITS file. … … 173 131 Int *cBeams, *cIFs; 174 132 uInt cNBeam, cNIF; 175 PKSMBrecord cMBrec;133 MBrecord cMBrec; 176 134 FITSreader *cReader; 177 135 -
branches/alma/external/atnf/PKSIO/PKSMS2reader.cc
r1453 r1757 2 2 //# PKSMS2reader.cc: Class to read Parkes Multibeam data from a v2 MS. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.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. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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/>. 27 21 //# 28 //# $Id$ 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 $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/03, Mark Calabretta, ATNF 31 34 //#--------------------------------------------------------------------------- 32 33 35 34 36 // AIPS++ includes. … … 41 43 #include <casa/Quanta/MVAngle.h> 42 44 #include <casa/BasicMath/Math.h> 45 #include <casa/Logging/LogIO.h> 46 #include <casa/Utilities/Sort.h> 43 47 #include <measures/Measures/MeasConvert.h> 44 48 #include <measures/Measures/MEpoch.h> … … 48 52 // Parkes includes. 49 53 #include <atnf/pks/pks_maths.h> 54 #include <atnf/PKSIO/PKSrecord.h> 50 55 #include <atnf/PKSIO/PKSMS2reader.h> 51 56 … … 73 78 Int PKSMS2reader::open( 74 79 const String msName, 80 const String antenna, 75 81 Vector<Bool> &beams, 76 82 Vector<Bool> &IFs, … … 91 97 92 98 cPKSMS = MeasurementSet(msName); 99 100 // data selection by antenna 101 if ( antenna.length() == 0 ) { 102 cAntId.resize( 1 ) ; 103 cAntId[0] = 0 ; 104 } 105 else { 106 setupAntennaList( antenna ) ; 107 if ( cAntId.size() > 1 ) { 108 LogIO os( LogOrigin( "PKSMS2reader", "open()", WHERE ) ) ; 109 os << LogIO::WARN << "PKSMS2reader is not ready for multiple antenna selection. Use first antenna id " << cAntId[0] << "."<< LogIO::POST ; 110 Int tmp = cAntId[0] ; 111 cAntId.resize( 1 ) ; 112 cAntId[0] = tmp ; 113 } 114 stringstream ss ; 115 ss << "SELECT FROM $1 WHERE ANTENNA1 == ANTENNA2 && ANTENNA1 IN [" ; 116 for ( uInt i = 0 ; i < cAntId.size() ; i++ ) { 117 ss << cAntId[i] ; 118 if ( i == cAntId.size()-1 ) { 119 ss << "]" ; 120 } 121 else { 122 ss << "," ; 123 } 124 } 125 string taql = ss.str() ; 126 //cerr << "taql = " << taql << endl ; 127 cPKSMS = MeasurementSet( tableCommand( taql, cPKSMS ) ) ; 128 } 129 93 130 // taql access to the syscal table 94 131 cHaveSysCal = False; … … 97 134 } 98 135 136 // Lock the table for read access. 137 cPKSMS.lock(False); 138 99 139 cIdx = 0; 100 140 lastmjd = 0.0; 101 141 cNRow = cPKSMS.nrow(); 102 142 cMSopen = True; 103 104 // Lock the table for read access.105 cPKSMS.lock(False);106 143 107 144 // Main MS table and subtable column access. … … 140 177 cSigStateCol.reference(stateCols.sig()); 141 178 cRefStateCol.reference(stateCols.ref()); 179 142 180 cDataDescIdCol.reference(msCols.dataDescId()); 143 181 cSpWinIdCol.reference(dataDescCols.spectralWindowId()); 144 182 cChanFreqCol.reference(spWinCols.chanFreq()); 183 cTotBWCol.reference(spWinCols.totalBandwidth()); 145 184 146 185 cWeatherTimeCol.reference(weatherCols.time()); … … 151 190 cBeamNoCol.reference(msCols.feed1()); 152 191 cPointingCol.reference(pointingCols.direction()); 192 cPointingTimeCol.reference(pointingCols.time()); 153 193 cSigmaCol.reference(msCols.sigma()); 154 194 cNumReceptorCol.reference(feedCols.numReceptors()); … … 182 222 cHaveDataCol = False; 183 223 cHaveCorrectedDataCol = False; 184 //String telName = antennaCols.name()(0);185 224 ROMSObservationColumns observationCols(cPKSMS.observation()); 186 String telName = observationCols.telescopeName()(0); 187 //cATF = (telName.contains("DA41") || telName.contains("DV01")); 188 cATF = telName.contains("ATF"); 225 //String telName = observationCols.telescopeName()(0); 226 cTelName = observationCols.telescopeName()(0); 227 //cATF = cTelName.contains("ATF"); 228 //cOSF = cTelName.contains("OSF"); 229 //cALMA = cTelName.contains("ALMA"); 230 cALMA = cTelName.contains("ATF")||cTelName.contains("OSF")|| 231 cTelName.contains("ALMA"); 189 232 190 233 if (cHaveDataCol = cPKSMS.isColumn(MSMainEnums::DATA)) { 191 if (cA TF) {234 if (cALMA) { 192 235 //try to read a single baseline interferometeric data 193 236 //and treat it as single dish data … … 204 247 } 205 248 cFlagCol.reference(msCols.flag()); 206 207 208 if (cGetXPol = (cPKSMS.isColumn(MSMainEnums::DATA) && (!cA TF))) {249 cFlagRowCol.reference(msCols.flagRow()); 250 251 if (cGetXPol = (cPKSMS.isColumn(MSMainEnums::DATA) && (!cALMA))) { 209 252 if ((cHaveXCalFctr = cPKSMS.tableDesc().isColumn("XCALFCTR"))) { 210 253 cXCalFctrCol.attach(cPKSMS, "XCALFCTR"); … … 228 271 //uInt nIF = dataDescCols.nrow(); 229 272 uInt nIF =spWinCols.nrow(); 273 Vector<Int> spWinIds = cSpWinIdCol.getColumn() ; 230 274 IFs.resize(nIF); 231 275 IFs = True; 276 for ( Int ispw = 0 ; ispw < nIF ; ispw++ ) { 277 if ( allNE( ispw, spWinIds ) ) { 278 IFs(ispw) = False ; 279 } 280 } 232 281 233 282 // Number of polarizations and channels in each IF. 234 ROScalarColumn<Int> spWinIdCol(dataDescCols.spectralWindowId());235 283 ROScalarColumn<Int> numChanCol(spWinCols.numChan()); 236 284 … … 241 289 nPol.resize(nIF); 242 290 for (uInt iIF = 0; iIF < nIF; iIF++) { 243 nChan(iIF) = numChanCol(spWinIdCol(iIF)); 244 nPol(iIF) = numPolCol(polIdCol(iIF)); 291 if ( IFs(iIF) ) { 292 nChan(iIF) = numChanCol(cSpWinIdCol(iIF)) ; 293 nPol(iIF) = numPolCol(polIdCol(iIF)) ; 294 } 295 else { 296 nChan(iIF) = 0 ; 297 nPol(iIF) = 0 ; 298 } 245 299 } 246 300 … … 249 303 haveXPol = False; 250 304 251 if (cGetXPol && !(cA TF)) {305 if (cGetXPol && !(cALMA)) { 252 306 for (Int irow = 0; irow < cNRow; irow++) { 253 307 if (cDataCol.isDefined(irow)) { … … 298 352 String &antName, 299 353 Vector<Double> &antPosition, 300 String &obsMode, 354 // before merge... 355 //String &obsMode, 356 String &obsType, 357 String &bunit, 301 358 Float &equinox, 302 359 String &dopplerFrame, 303 360 Double &mjd, 304 361 Double &refFreq, 305 Double &bandwidth, 306 String &fluxunit) 362 Double &bandwidth) 307 363 { 308 364 if (!cMSopen) { … … 317 373 // Antenna name and ITRF coordinates. 318 374 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 319 antName = antennaCols.name()(0); 320 antPosition = antennaCols.position()(0); 375 //antName = antennaCols.name()(0); 376 antName = antennaCols.name()(cAntId[0]); 377 if (cALMA) { 378 antName = cTelName + "-" + antName; 379 } 380 //antPosition = antennaCols.position()(0); 381 antPosition = antennaCols.position()(cAntId[0]); 321 382 322 383 // Observation type. 323 384 if (cObsModeCol.nrow()) { 324 obs Mode = cObsModeCol(0);325 if (obs Mode == "\0") obsMode = "RF";385 obsType = cObsModeCol(0); 386 if (obsType == "\0") obsType = "RF"; 326 387 } else { 327 obs Mode = "RF";328 } 329 330 fluxunit = "";388 obsType = "RF"; 389 } 390 391 bunit = ""; 331 392 if (cHaveDataCol) { 332 393 const TableRecord& keywordSet2 333 394 = cDataCol.columnDesc().keywordSet(); 334 395 if(keywordSet2.isDefined("UNIT")) { 335 fluxunit = keywordSet2.asString("UNIT");396 bunit = keywordSet2.asString("UNIT"); 336 397 } 337 398 } else { … … 339 400 = cFloatDataCol.columnDesc().keywordSet(); 340 401 if(keywordSet.isDefined("UNIT")) { 341 fluxunit = keywordSet.asString("UNIT");402 bunit = keywordSet.asString("UNIT"); 342 403 } 343 404 } … … 354 415 String dirref = pointingCols.direction().keywordSet().asRecord("MEASINFO"). 355 416 asString("Ref"); 417 cDirRef = dirref; 418 if (dirref =="AZELGEO" || dirref == "AZEL") { 419 dirref = "J2000"; 420 } 356 421 sscanf(dirref.chars()+1, "%f", &equinox); 357 422 … … 422 487 const Bool getSpectra, 423 488 const Bool getXPol, 424 const Bool getFeedPos) 489 const Bool getFeedPos, 490 const Bool getPointing, 491 const Int coordSys) 425 492 { 426 493 if (!cMSopen) { … … 504 571 cGetFeedPos = False; 505 572 573 // Get Pointing data (for MS) 574 cGetPointing = getPointing; 575 576 // Coordinate system? (Only equatorial available.) 577 cCoordSys = 0; 578 506 579 return maxNChan; 507 580 } … … 555 628 // Read the next data record. 556 629 630 /** 557 631 Int PKSMS2reader::read( 558 632 Int &scanNo, … … 595 669 Matrix<Float> &spectra, 596 670 Matrix<uChar> &flagged, 671 uInt &flagrow, 597 672 Complex &xCalFctr, 598 673 Vector<Complex> &xPol) 674 **/ 675 Int PKSMS2reader::read(PKSrecord &pksrec) 599 676 { 677 LogIO os( LogOrigin( "PKSMS2reader", "read()", WHERE ) ) ; 678 600 679 if (!cMSopen) { 601 680 return 1; … … 627 706 // Renumerate scan no. Here still is 1-based 628 707 //scanNo = cScanNoCol(cIdx) - cScanNoCol(0) + 1; 629 scanNo = cScanNoCol(cIdx); 630 631 if (scanNo != cScanNo) { 708 //scanNo = cScanNoCol(cIdx); 709 pksrec.scanNo = cScanNoCol(cIdx); 710 711 if (pksrec.scanNo != cScanNo) { 632 712 // Start of new scan. 633 cScanNo = scanNo;713 cScanNo = pksrec.scanNo; 634 714 cCycleNo = 1; 635 715 cTime = cTimeCol(cIdx); … … 637 717 638 718 Double time = cTimeCol(cIdx); 639 mjd = time/86400.0;640 interval = cIntervalCol(cIdx);719 pksrec.mjd = time/86400.0; 720 pksrec.interval = cIntervalCol(cIdx); 641 721 642 722 // Reconstruct the integration cycle number; due to small latencies the 643 723 // integration time is usually slightly less than the time between cycles, 644 724 // resetting cTime will prevent the difference from accumulating. 645 cCycleNo += nint((time - cTime)/ interval);646 cycleNo = cCycleNo;647 cTime 725 cCycleNo += nint((time - cTime)/pksrec.interval); 726 pksrec.cycleNo = cCycleNo; 727 cTime = time; 648 728 649 729 Int fieldId = cFieldIdCol(cIdx); 650 fieldName = cFieldNameCol(fieldId);730 pksrec.fieldName = cFieldNameCol(fieldId); 651 731 652 732 Int srcId = cSrcIdCol(fieldId); … … 656 736 for (uInt irow = 0; irow < cSrcId2Col.nrow(); irow++) { 657 737 if (cSrcId2Col(irow) == srcId) { 658 srcName = cSrcNameCol(irow); 659 } 660 } 661 662 srcDir = cSrcDirCol(srcId); 663 srcPM = cSrcPMCol(srcId); 738 //srcName = cSrcNameCol(irow); 739 pksrec.srcName = cSrcNameCol(irow); 740 } 741 } 742 743 pksrec.srcDir = cSrcDirCol(srcId); 744 pksrec.srcPM = cSrcPMCol(srcId); 664 745 665 746 // Systemic velocity. 666 if (!cHaveSrcVel || cA TF) {667 srcVel = 0.0f;747 if (!cHaveSrcVel || cALMA) { 748 pksrec.srcVel = 0.0f; 668 749 } else { 669 srcVel= cSrcVelCol(srcId)(IPosition(1,0));750 pksrec.srcVel = cSrcVelCol(srcId)(IPosition(1,0)); 670 751 } 671 752 672 753 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 673 String telescope = antennaCols.name()(0); 754 //String telescope = antennaCols.name()(0); 755 String telescope = antennaCols.name()(cAntId[0]); 674 756 Bool cGBT = telescope.contains("GBT"); 757 //Bool cPM = telescope.contains("PM"); // ACA TP antenna 758 //Bool cDV = telescope.contains("DV"); // VERTEX 759 //Bool cCM = telescope.contains("CM"); // ACA 7m antenna 760 //Bool cALMA = cPM || cDV || cCM ; 675 761 // Observation type. 676 762 // check if State Table exist … … 680 766 StateNRow=cObsModeCol.nrow(); 681 767 if (Table::isReadable(cPKSMS.stateTableName())) { 682 obsMode = " ";768 pksrec.obsType = " "; 683 769 if (StateNRow > 0) { 684 770 stateId = cStateIdCol(cIdx); 685 771 if (stateId == -1) { 686 // obsMode = " ";772 //pksrec.obsType = " "; 687 773 } else { 688 obsMode = cObsModeCol(stateId);774 pksrec.obsType = cObsModeCol(stateId); 689 775 Bool sigState =cSigStateCol(stateId); 690 776 Bool refState =cRefStateCol(stateId); 691 777 //DEBUG 692 //cerr <<"stateid="<<stateId<<" obsmode="<< obsMode<<endl;778 //cerr <<"stateid="<<stateId<<" obsmode="<<pksrec.obsType<<endl; 693 779 if (cGBT) { 694 // split the obs Mode string and append a proper label780 // split the obsType string and append a proper label 695 781 // (these are GBT specific) 696 int epos = obsMode.find_first_of(':');697 int nextpos = obsMode.find_first_of(':',epos+1);698 string obsMode1 = obsMode.substr(0,epos);699 string obsMode2 = obsMode.substr(epos+1,nextpos-epos-1);782 int epos = pksrec.obsType.find_first_of(':'); 783 int nextpos = pksrec.obsType.find_first_of(':',epos+1); 784 string obsMode1 = pksrec.obsType.substr(0,epos); 785 string obsMode2 = pksrec.obsType.substr(epos+1,nextpos-epos-1); 700 786 701 787 //cerr <<"obsMode2= "<<obsMode2<<endl; 702 if (! srcName.contains("_ps")703 &&! srcName.contains("_psr")704 &&! srcName.contains("_nod")705 &&! srcName.contains("_fs")706 &&! srcName.contains("_fsr")) {788 if (!pksrec.srcName.contains("_ps") 789 &&!pksrec.srcName.contains("_psr") 790 &&!pksrec.srcName.contains("_nod") 791 &&!pksrec.srcName.contains("_fs") 792 &&!pksrec.srcName.contains("_fsr")) { 707 793 // if Nod mode observation , append '_nod' 708 794 if (obsMode1 == "Nod") { 709 srcName.append("_nod"); 795 //pksrec.srcName.append("_nod"); 796 pksrec.srcType = SrcType::NOD ; 710 797 } else if (obsMode1 == "OffOn") { 711 798 // for GBT position switch observations (OffOn or OnOff) 712 if (obsMode2 == "PSWITCHON") srcName.append("_ps"); 713 if (obsMode2 == "PSWITCHOFF") srcName.append("_psr"); 799 //if (obsMode2 == "PSWITCHON") pksrec.srcName.append("_ps"); 800 //if (obsMode2 == "PSWITCHOFF") pksrec.srcName.append("_psr"); 801 if (obsMode2 == "PSWITCHON") pksrec.srcType = SrcType::PSON ; 802 if (obsMode2 == "PSWITCHOFF") pksrec.srcType = SrcType::PSOFF ; 714 803 } else { 715 804 if (obsMode2 == "FSWITCH") { 716 805 // for GBT frequency switch mode 717 if (sigState) srcName.append("_fs"); 718 if (refState) srcName.append("_fsr"); 806 //if (sigState) pksrec.srcName.append("_fs"); 807 //if (refState) pksrec.srcName.append("_fsr"); 808 if (sigState) pksrec.srcType = SrcType::FSON ; 809 if (refState) pksrec.srcType = SrcType::FSOFF ; 719 810 } 720 811 } 721 812 } 722 813 } 814 else if (cALMA) { 815 // ALMA tag 816 // split the obsType string and append a proper label 817 string substr[1] ; 818 int numSubstr = split( pksrec.obsType, substr, 1, "," ); 819 String obsType = String( substr[0] ); 820 int epos = obsType.find_first_of('.'); 821 int nextpos = obsType.find_first_of('.',epos+1); 822 string obsMode1 = obsType.substr(0,epos); 823 string obsMode2 = obsType.substr(epos+1,nextpos-epos-1); 824 825 //cerr <<"obsMode2= "<<obsMode2<<endl; 826 // Current OBS_MODE format: 827 // 828 // ON: OBSERVE_TARGET.ON_SOURCE 829 // OFF: OBSERVE_TARGET.OFF_SOURCE 830 // 831 if (obsMode1 == "OBSERVE_TARGET") { 832 //if (obsMode2 == "ON_SOURCE") pksrec.srcName.append("_pson"); 833 //if (obsMode2 == "OFF_SOURCE") pksrec.srcName.append("_psoff"); 834 if (obsMode2 == "ON_SOURCE") pksrec.srcType = SrcType::PSON ; 835 if (obsMode2 == "OFF_SOURCE") pksrec.srcType = SrcType::PSOFF ; 836 } 837 } 723 838 } 724 839 } … … 733 848 } 734 849 if (cGBT) { 735 if (Cal > 0 && !srcName.contains("_calon")) { 736 srcName.append("_calon"); 737 } 738 } 739 740 IFno = iIF + 1; 850 if (Cal > 0 && !pksrec.srcName.contains("_calon")) { 851 //pksrec.srcName.append("_calon"); 852 if ( pksrec.srcType == SrcType::NOD ) 853 pksrec.srcType = SrcType::NODCAL ; 854 else if ( pksrec.srcType == SrcType::PSON ) 855 pksrec.srcType = SrcType::PONCAL ; 856 else if ( pksrec.srcType == SrcType::PSOFF ) 857 pksrec.srcType = SrcType::POFFCAL ; 858 else if ( pksrec.srcType == SrcType::FSON ) 859 pksrec.srcType = SrcType::FONCAL ; 860 else if ( pksrec.srcType == SrcType::FSOFF ) 861 pksrec.srcType = SrcType::FOFFCAL ; 862 else 863 pksrec.srcName.append("_calon"); 864 } 865 } 866 867 pksrec.IFno = iIF + 1; 741 868 Int nChan = abs(cEndChan(iIF) - cStartChan(iIF)) + 1; 742 869 743 870 // Minimal handling on continuum data. 744 871 Vector<Double> chanFreq = cChanFreqCol(iIF); 872 pksrec.nchan = nChan; 745 873 if (nChan == 1) { 746 freqInc = chanFreq(0); 747 refFreq = chanFreq(0); 748 restFreq = 0.0f; 874 //pksrec.freqInc = chanFreq(0); 875 pksrec.freqInc = cTotBWCol(iIF); 876 pksrec.refFreq = chanFreq(0); 877 pksrec.restFreq.resize(1); 878 pksrec.restFreq[0] = 0.0f; 749 879 } else { 750 880 751 881 if (cStartChan(iIF) <= cEndChan(iIF)) { 752 freqInc = chanFreq(1) - chanFreq(0);882 pksrec.freqInc = chanFreq(1) - chanFreq(0); 753 883 } else { 754 freqInc = chanFreq(0) - chanFreq(1); 755 } 756 refFreq = chanFreq(cRefChan(iIF)-1); 884 pksrec.freqInc = chanFreq(0) - chanFreq(1); 885 } 886 887 pksrec.refFreq = chanFreq(cRefChan(iIF)-1); 888 757 889 Bool HaveSrcRestFreq= cSrcRestFrqCol.isDefined(srcId); 758 890 if (HaveSrcRestFreq) { 759 891 //restFreq = cSrcRestFrqCol(srcId)(IPosition(1,0)); 760 restFreq = cSrcRestFrqCol(srcId); 892 //restFreq = cSrcRestFrqCol(srcId); 893 pksrec.restFreq = cSrcRestFrqCol(srcId); 761 894 } else { 762 restFreq = 0.0f; 763 } 764 } 765 bandwidth = abs(freqInc * nChan); 766 767 tcal.resize(cNPol(iIF)); 768 tcal = 0.0f; 769 tcalTime = ""; 770 //azimuth = 0.0f; 771 //elevation = 0.0f; 772 parAngle = 0.0f; 773 focusAxi = 0.0f; 774 focusTan = 0.0f; 775 focusRot = 0.0f; 895 pksrec.restFreq.resize(1); 896 pksrec.restFreq[0] = 0.0f; 897 } 898 } 899 //pksrec.bandwidth = abs(pksrec.freqInc * nChan); 900 pksrec.bandwidth = abs(cTotBWCol(0)); 901 902 pksrec.tcal.resize(cNPol(iIF)); 903 pksrec.tcal = 0.0f; 904 pksrec.tcalTime = ""; 905 // pksrec.azimuth = 0.0f; 906 // pksrec.elevation = 0.0f; 907 pksrec.parAngle = 0.0f; 908 909 pksrec.focusAxi = 0.0f; 910 pksrec.focusTan = 0.0f; 911 pksrec.focusRot = 0.0f; 776 912 777 913 // Find the appropriate entry in the WEATHER subtable. … … 787 923 } 788 924 } 925 789 926 if (weatherIdx < 0 || !cHaveWeatherTab) { 790 927 // No appropriate WEATHER entry. 791 p ressure= 0.0f;792 humidity= 0.0f;793 temperature= 0.0f;928 pksrec.temperature = 0.0f; 929 pksrec.pressure = 0.0f; 930 pksrec.humidity = 0.0f; 794 931 } else { 795 pressure = cPressureCol(weatherIdx); 796 humidity = cHumidityCol(weatherIdx); 797 temperature = cTemperatureCol(weatherIdx); 798 } 799 800 windSpeed = 0.0f; 801 windAz = 0.0f; 802 803 refBeam = 0; 804 beamNo = ibeam + 1; 805 806 //Matrix<Double> pointingDir = cPointingCol(fieldId); 807 //pointingDir = cPointingCol(fieldId); 808 //direction = pointingDir.column(0); 809 //uInt ncols = pointingDir.ncolumn(); 810 //if (ncols == 1) { 811 // scanRate = 0.0f; 812 //} else { 813 // scanRate = pointingDir.column(1); 814 //} 815 932 pksrec.temperature = cTemperatureCol(weatherIdx); 933 pksrec.pressure = cPressureCol(weatherIdx); 934 pksrec.humidity = cHumidityCol(weatherIdx); 935 } 936 937 pksrec.windSpeed = 0.0f; 938 pksrec.windAz = 0.0f; 939 940 pksrec.refBeam = 0; 941 pksrec.beamNo = ibeam + 1; 942 943 //pointing/azel 944 MVPosition mvpos(antennaCols.position()(cAntId[0])); 945 MPosition mp(mvpos); 946 Quantum<Double> qt(time,"s"); 947 MVEpoch mvt(qt); 948 MEpoch me(mvt); 949 MeasFrame frame(mp, me); 950 MDirection md; 951 pksrec.pCode = 0; 952 pksrec.rateAge = 0.0f; 953 pksrec.paRate = 0.0f; 954 if (cGetPointing) { 955 //cerr << "get pointing data ...." << endl; 956 ROScalarColumn<Int> pAntIdCol ; 957 ROScalarColumn<Double> psTimeCol ; 958 Table ptTable = cPKSMS.pointing() ; 959 MSPointing selPtTab( ptTable( ptTable.col("ANTENNA_ID") == cAntId[0] ) ) ; 960 pAntIdCol.attach( selPtTab, "ANTENNA_ID" ) ; 961 Vector<Int> antIds = pAntIdCol.getColumn() ; 962 psTimeCol.attach( selPtTab, "TIME" ) ; 963 Vector<Double> pTimes = psTimeCol.getColumn(); 964 Bool doInterp = False ; 965 Int PtIdx=-1; 966 for (PtIdx = pTimes.nelements()-1; PtIdx >= 0; PtIdx--) { 967 if ( pTimes[PtIdx] == time ) { 968 break ; 969 } 970 else if ( pTimes[PtIdx] < time ) { 971 if ( PtIdx != pTimes.nelements()-1 ) { 972 doInterp = True ; 973 } 974 break ; 975 } 976 } 977 if ( PtIdx == -1 ) { 978 PtIdx = 0 ; 979 } 980 //cerr << "got index=" << PtIdx << endl; 981 Matrix<Double> pointingDir = cPointingCol(PtIdx); 982 ROMSPointingColumns PtCols( selPtTab ) ; 983 Vector<Double> pointingDirVec ; 984 if ( doInterp ) { 985 Double dt1 = time - pTimes[PtIdx] ; 986 Double dt2 = pTimes[PtIdx+1] - time ; 987 Vector<Double> dirVec1 = pointingDir.column(0) ; 988 Matrix<Double> pointingDir2 = cPointingCol(PtIdx+1) ; 989 Vector<Double> dirVec2 = pointingDir2.column(0) ; 990 pointingDirVec = (dt1*dirVec2+dt2*dirVec1)/(dt1+dt2) ; 991 Vector<MDirection> vmd1(1) ; 992 Vector<MDirection> vmd2(1) ; 993 PtCols.directionMeasCol().get(PtIdx,vmd1) ; 994 Vector<Double> angle1 = vmd1(0).getAngle().getValue("rad") ; 995 PtCols.directionMeasCol().get(PtIdx+1,vmd2) ; 996 Vector<Double> angle2 = vmd2(0).getAngle().getValue("rad") ; 997 Vector<Double> angle = (dt1*angle2+dt2*angle1)/(dt1+dt2) ; 998 Quantum< Vector<Double> > qangle( angle, "rad" ) ; 999 String typeStr = vmd1(0).getRefString() ; 1000 //cerr << "vmd1.getRefString()=" << typeStr << endl ; 1001 MDirection::Types mdType ; 1002 MDirection::getType( mdType, typeStr ) ; 1003 //cerr << "mdType=" << mdType << endl ; 1004 md = MDirection( qangle, mdType ) ; 1005 //cerr << "md=" << md.getAngle().getValue("rad") << endl ; 1006 } 1007 else { 1008 pointingDirVec = pointingDir.column(0) ; 1009 Vector<MDirection> vmd(1); 1010 PtCols.directionMeasCol().get(PtIdx,vmd); 1011 md = vmd[0]; 1012 } 1013 // put J2000 coordinates in "direction" 1014 if (cDirRef =="J2000") { 1015 pksrec.direction = pointingDirVec ; 1016 } 1017 else { 1018 pksrec.direction = 1019 MDirection::Convert(md, MDirection::Ref(MDirection::J2000, 1020 frame) 1021 )().getAngle("rad").getValue(); 1022 1023 } 1024 uInt ncols = pointingDir.ncolumn(); 1025 pksrec.scanRate.resize(2); 1026 if (ncols == 1) { 1027 pksrec.scanRate = 0.0f; 1028 } else { 1029 pksrec.scanRate(0) = pointingDir.column(1)(0); 1030 pksrec.scanRate(1) = pointingDir.column(1)(1); 1031 } 1032 } 1033 else { 816 1034 // Get direction from FIELD table 817 1035 // here, assume direction to be the field direction not pointing 818 Matrix<Double> delayDir = cFieldDelayDirCol(fieldId); 819 direction = delayDir.column(0); 820 uInt ncols = delayDir.ncolumn(); 821 if (ncols == 1) { 822 scanRate = 0.0f; 823 } else { 824 scanRate = delayDir.column(1); 825 } 826 1036 Matrix<Double> delayDir = cFieldDelayDirCol(fieldId); 1037 pksrec.direction = delayDir.column(0); 1038 uInt ncols = delayDir.ncolumn(); 1039 pksrec.scanRate.resize(2); 1040 if (ncols == 1) { 1041 pksrec.scanRate = 0.0f; 1042 } else { 1043 pksrec.scanRate(0) = delayDir.column(1)(0); 1044 pksrec.scanRate(1) = delayDir.column(1)(1); 1045 } 1046 } 827 1047 // caluculate azimuth and elevation 828 1048 // first, get the reference frame 1049 /** 829 1050 MVPosition mvpos(antennaCols.position()(0)); 830 1051 MPosition mp(mvpos); … … 833 1054 MEpoch me(mvt); 834 1055 MeasFrame frame(mp, me); 1056 **/ 835 1057 // 836 1058 ROMSFieldColumns fldCols(cPKSMS.field()); 837 1059 Vector<MDirection> vmd(1); 838 MDirection md;1060 //MDirection md; 839 1061 fldCols.delayDirMeasCol().get(fieldId,vmd); 840 1062 md = vmd[0]; … … 847 1069 )().getAngle("rad").getValue(); 848 1070 //cerr<<"azel="<<azel<<endl; 849 azimuth = azel[0];850 elevation = azel[1];1071 pksrec.azimuth = azel[0]; 1072 pksrec.elevation = azel[1]; 851 1073 852 1074 // Get Tsys assuming that entries in the SYSCAL table match the main table. … … 858 1080 } 859 1081 if (cHaveTsys) { 860 cTsysCol.get(cIdx, tsys, True);1082 cTsysCol.get(cIdx, pksrec.tsys, True); 861 1083 } else { 862 1084 Int numReceptor; 863 1085 cNumReceptorCol.get(0, numReceptor); 864 tsys.resize(numReceptor);865 tsys = 1.0f;866 } 867 cSigmaCol.get(cIdx, sigma, True);1086 pksrec.tsys.resize(numReceptor); 1087 pksrec.tsys = 1.0f; 1088 } 1089 cSigmaCol.get(cIdx, pksrec.sigma, True); 868 1090 869 1091 //get Tcal if available … … 875 1097 if (nTcalColRow > 0) { 876 1098 // find tcal match with the data with the data time stamp 877 Double mjds = mjd*(24*3600);1099 Double mjds = pksrec.mjd*(24*3600); 878 1100 Double dtcalTime; 879 if ( mjd > lastmjd || cIdx==0 ) {1101 if ( pksrec.mjd > lastmjd || cIdx==0 ) { 880 1102 //Table tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds)); 881 1103 tmptab = cSysCalTab(near(cSysCalTab.col("TIME"),mjds), nrws); … … 898 1120 ROScalarColumn<Double> tcalTimeCol(tmptab2, "TIME"); 899 1121 if (syscalrow==0) { 900 cerr<<"Cannot find any matching Tcal at/near the data timestamp." 901 << " Set Tcal=0.0"<<endl; 1122 os << LogIO::NORMAL 1123 <<"Cannot find any matching Tcal at/near the data timestamp." 1124 << " Set Tcal=0.0" << LogIO::POST ; 902 1125 } else { 903 tcalCol.get(0, tcal);1126 tcalCol.get(0, pksrec.tcal); 904 1127 tcalTimeCol.get(0,dtcalTime); 905 tcalTime = MVTime(dtcalTime/(24*3600)).string(MVTime::YMD);1128 pksrec.tcalTime = MVTime(dtcalTime/(24*3600)).string(MVTime::YMD); 906 1129 //DEBUG 907 1130 //cerr<<"cIdx:"<<cIdx<<" tcal="<<tcal<<" tcalTime="<<tcalTime<<endl; … … 910 1133 } 911 1134 } 912 lastmjd = mjd;1135 lastmjd = pksrec.mjd; 913 1136 } 914 1137 915 1138 // Calibration factors (if available). 916 calFctr.resize(cNPol(iIF));1139 pksrec.calFctr.resize(cNPol(iIF)); 917 1140 if (cHaveCalFctr) { 918 cCalFctrCol.get(cIdx, calFctr);1141 cCalFctrCol.get(cIdx, pksrec.calFctr); 919 1142 } else { 920 calFctr = 0.0f;1143 pksrec.calFctr = 0.0f; 921 1144 } 922 1145 923 1146 // Baseline parameters (if available). 924 1147 if (cHaveBaseLin) { 925 baseLin.resize(2,cNPol(iIF));926 cBaseLinCol.get(cIdx, baseLin);927 928 baseSub.resize(9,cNPol(iIF));929 cBaseSubCol.get(cIdx, baseSub);1148 pksrec.baseLin.resize(2,cNPol(iIF)); 1149 cBaseLinCol.get(cIdx, pksrec.baseLin); 1150 1151 pksrec.baseSub.resize(24,cNPol(iIF)); 1152 cBaseSubCol.get(cIdx, pksrec.baseSub); 930 1153 931 1154 } else { 932 baseLin.resize(0,0); 933 baseSub.resize(0,0); 934 } 1155 pksrec.baseLin.resize(0,0); 1156 pksrec.baseSub.resize(0,0); 1157 } 1158 1159 935 1160 // Get spectral data. 936 1161 if (cGetSpectra) { … … 960 1185 // Transpose spectra. 961 1186 Int nPol = tmpData.nrow(); 962 spectra.resize(nChan, nPol);963 flagged.resize(nChan, nPol);1187 pksrec.spectra.resize(nChan, nPol); 1188 pksrec.flagged.resize(nChan, nPol); 964 1189 if (cEndChan(iIF) >= cStartChan(iIF)) { 965 1190 // Simple transposition. 966 1191 for (Int ipol = 0; ipol < nPol; ipol++) { 967 1192 for (Int ichan = 0; ichan < nChan; ichan++) { 968 spectra(ichan,ipol) = tmpData(ipol,ichan);969 flagged(ichan,ipol) = tmpFlag(ipol,ichan);1193 pksrec.spectra(ichan,ipol) = tmpData(ipol,ichan); 1194 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,ichan); 970 1195 } 971 1196 } … … 976 1201 for (Int ipol = 0; ipol < nPol; ipol++) { 977 1202 for (Int ichan = 0; ichan < nChan; ichan++, jchan--) { 978 spectra(ichan,ipol) = tmpData(ipol,jchan);979 flagged(ichan,ipol) = tmpFlag(ipol,jchan);1203 pksrec.spectra(ichan,ipol) = tmpData(ipol,jchan); 1204 pksrec.flagged(ichan,ipol) = tmpFlag(ipol,jchan); 980 1205 } 981 1206 } 982 1207 } 1208 1209 // Row-based flagging info. (True:1, False:0) 1210 pksrec.flagrow = (cFlagRowCol(cIdx) ? 1 : 0); 983 1211 } 984 1212 … … 989 1217 990 1218 if (cHaveXCalFctr) { 991 cXCalFctrCol.get(cIdx, xCalFctr);1219 cXCalFctrCol.get(cIdx, pksrec.xCalFctr); 992 1220 } else { 993 xCalFctr = Complex(0.0f, 0.0f);994 } 995 996 if(!cA TF) {997 cDataCol.get(cIdx, xPol, True);1221 pksrec.xCalFctr = Complex(0.0f, 0.0f); 1222 } 1223 1224 if(!cALMA) { 1225 cDataCol.get(cIdx, pksrec.xPol, True); 998 1226 999 1227 if (cEndChan(iIF) < cStartChan(iIF)) { … … 1001 1229 Int jchan = nChan - 1; 1002 1230 for (Int ichan = 0; ichan < nChan/2; ichan++, jchan--) { 1003 ctmp = xPol(ichan);1004 xPol(ichan) =xPol(jchan);1005 xPol(jchan) = ctmp;1231 ctmp = pksrec.xPol(ichan); 1232 pksrec.xPol(ichan) = pksrec.xPol(jchan); 1233 pksrec.xPol(jchan) = ctmp; 1006 1234 } 1007 1235 } … … 1097 1325 cBaseLinCol.get(cIdx, baseLin); 1098 1326 1099 baseSub.resize( 9,cNPol(iIF));1327 baseSub.resize(24,cNPol(iIF)); 1100 1328 cBaseSubCol.get(cIdx, baseSub); 1101 1329 … … 1158 1386 cMSopen = False; 1159 1387 } 1388 1389 //-------------------------------------------------------- PKSMS2reader::splitAntenanSelectionString 1390 1391 // split antenna selection string 1392 // delimiter is ',' 1393 1394 Vector<String> PKSMS2reader::splitAntennaSelectionString( const String s ) 1395 { 1396 Char delim = ',' ; 1397 Int n = s.freq( delim ) + 1 ; 1398 Vector<String> antlist ; 1399 string sl[n] ; 1400 Int numSubstr = split( s, sl, n, "," ); 1401 antlist.resize( numSubstr ) ; 1402 for ( Int i = 0 ; i < numSubstr ; i++ ) { 1403 antlist[i] = String( sl[i] ) ; 1404 antlist[i].trim() ; 1405 } 1406 //cerr << "antlist = " << antlist << endl ; 1407 return antlist ; 1408 } 1409 1410 //-------------------------------------------------------- PKSMS2reader::setupAntennaList 1411 1412 // Fill cAntenna and cAntId 1413 1414 void PKSMS2reader::setupAntennaList( const String s ) 1415 { 1416 LogIO os( LogOrigin( "PKSMS2reader", "setupAntennaList()", WHERE ) ) ; 1417 //cerr << "antenna specification: " << s << endl ; 1418 ROMSAntennaColumns antennaCols(cPKSMS.antenna()); 1419 ROScalarColumn<String> antNames = antennaCols.name(); 1420 Int nrow = antNames.nrow() ; 1421 Vector<String> antlist = splitAntennaSelectionString( s ) ; 1422 Int len = antlist.size() ; 1423 Vector<Int> AntId( len ) ; 1424 Regex re( "[0-9]+" ) ; 1425 for ( Int i = 0 ; i < len ; i++ ) { 1426 if ( antlist[i].matches( re ) ) { 1427 AntId[i] = atoi( antlist[i].c_str() ) ; 1428 if ( AntId[i] >= nrow ) { 1429 os << LogIO::SEVERE << "Antenna index out of range: " << AntId[i] << LogIO::EXCEPTION ; 1430 } 1431 } 1432 else { 1433 AntId[i] = -1 ; 1434 for ( uInt j = 0 ; j < antNames.nrow() ; j++ ) { 1435 if ( antlist[i] == antNames(j) ) { 1436 AntId[i] = j ; 1437 break ; 1438 } 1439 } 1440 if ( AntId[i] == -1 ) { 1441 os << LogIO::SEVERE << "Specified antenna name not found: " << antlist[i] << LogIO::EXCEPTION ; 1442 } 1443 } 1444 } 1445 //cerr << "AntId = " << AntId << endl ; 1446 vector<Int> uniqId ; 1447 uniqId.push_back( AntId(0) ) ; 1448 for ( uInt i = 1 ; i < AntId.size() ; i++ ) { 1449 if ( count(uniqId.begin(),uniqId.end(),AntId[i]) == 0 ) { 1450 uniqId.push_back( AntId[i] ) ; 1451 } 1452 } 1453 Vector<Int> newAntId( uniqId ) ; 1454 cAntId.assign( newAntId ) ; 1455 //cerr << "cAntId = " << cAntId << endl ; 1456 } -
branches/alma/external/atnf/PKSIO/PKSMS2reader.h
r1453 r1757 2 2 //# PKSMS2reader.h: Class to read Parkes Multibeam data from a v2 MS. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 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.h,v 19.18 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/03, Mark Calabretta, ATNF … … 35 38 36 39 #include <atnf/PKSIO/PKSreader.h> 40 #include <atnf/PKSIO/PKSrecord.h> 37 41 38 42 #include <casa/aips.h> … … 46 50 #include <tables/Tables/ScalarColumn.h> 47 51 52 #include <casa/namespace.h> 53 48 54 // <summary> 49 55 // Class to read Parkes Multibeam data from a v2 MS. 50 56 // </summary> 51 52 #include <casa/namespace.h>53 57 54 58 class PKSMS2reader : public PKSreader … … 64 68 virtual Int open( 65 69 const String msName, 70 const String antenna, 66 71 Vector<Bool> &beams, 67 72 Vector<Bool> &IFs, … … 79 84 Vector<Double> &antPosition, 80 85 String &obsMode, 86 String &bunit, 81 87 Float &equinox, 82 String &freqRef, 88 //String &freqRef, 89 String &dopplerFrame, 83 90 Double &mjd, 84 91 Double &refFreq, 85 Double &bandwidth, 86 String &fluxunit); 92 Double &bandwidth); 87 93 88 94 // Get frequency parameters for each IF. … … 101 107 const Bool getSpectra = True, 102 108 const Bool getXPol = False, 103 const Bool getFeedPos = False); 109 const Bool getFeedPos = False, 110 const Bool getPointing = False, 111 const Int coordSys = 0); 112 104 113 105 114 // Find the range of the data selected in time and position. … … 111 120 112 121 // Read the next data record. 122 /** 113 123 virtual Int read( 114 124 Int &scanNo, … … 153 163 Complex &xCalFctr, 154 164 Vector<Complex> &xPol); 165 **/ 166 virtual Int read(PKSrecord &pksrec); 167 155 168 156 169 // Read the next data record, just the basics. … … 168 181 169 182 private: 183 Vector<String> splitAntennaSelectionString( const String s ); 184 void setupAntennaList( const String s ) ; 185 170 186 Bool cHaveBaseLin, cHaveCalFctr, cHaveSrcVel, cHaveTsys, cHaveXCalFctr, 171 cMSopen, cHaveTcal, cHaveDataCol, cA TF, cHaveSysCal, cHaveCorrectedDataCol;187 cMSopen, cHaveTcal, cHaveDataCol, cALMA, cHaveSysCal, cHaveCorrectedDataCol; 172 188 Int cCycleNo, cIdx, cNRow, cScanNo; 173 189 Double cTime, lastmjd; … … 175 191 Vector<Bool> cBeams, cIFs; 176 192 Vector<Slicer> cDataSel; 193 String cDirRef, cTelName; 177 194 MeasurementSet cPKSMS; 178 195 Table cSysCalTab, tmptab, tmptab2; 196 197 //Vector<String> cAntenna; 198 Vector<Int> cAntId; 179 199 180 200 ROScalarColumn<Int> cScanNoCol; … … 197 217 ROScalarColumn<Int> cSpWinIdCol; 198 218 ROArrayColumn<Double> cChanFreqCol; 219 ROScalarColumn<Double> cTotBWCol; 199 220 ROScalarColumn<Double> cWeatherTimeCol; 200 221 ROScalarColumn<Float> cTemperatureCol; … … 204 225 ROScalarColumn<Int> cBeamNoCol; 205 226 ROArrayColumn<Double> cPointingCol; 227 ROScalarColumn<Double> cPointingTimeCol; 206 228 ROArrayColumn<Float> cTsysCol; 207 229 ROArrayColumn<Float> cSigmaCol; … … 211 233 ROArrayColumn<Float> cFloatDataCol; 212 234 ROArrayColumn<Bool> cFlagCol; 235 ROScalarColumn<Bool> cFlagRowCol; 213 236 ROScalarColumn<Complex> cXCalFctrCol; 214 237 ROArrayColumn<Complex> cDataCol; -
branches/alma/external/atnf/PKSIO/PKSMS2writer.cc
r1453 r1757 2 2 //# PKSMS2writer.cc: Class to write Parkes multibeam data to a measurementset. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License for more details.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. 16 13 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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. 20 18 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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/>. 27 21 //# 28 //# $Id: PKSMS2writer.cc,v 19.11 2006/11/06 22:25:22 mmarquar Exp $ 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 $ 29 32 //#--------------------------------------------------------------------------- 30 33 34 #include <atnf/PKSIO/PKSrecord.h> 31 35 #include <atnf/PKSIO/PKSMS2writer.h> 32 36 … … 49 53 #include <tables/Tables/TiledShapeStMan.h> 50 54 55 // Class name 56 const string className = "PKSMS2writer" ; 57 51 58 //------------------------------------------------- PKSMS2writer::PKSMS2writer 52 59 … … 55 62 PKSMS2writer::PKSMS2writer() 56 63 { 64 cPKSMS = 0x0; 57 65 } 58 66 … … 77 85 const Vector<Double> antPosition, 78 86 const String obsMode, 87 const String bunit, 79 88 const Float equinox, 80 89 const String dopplerFrame, … … 82 91 const Vector<uInt> nPol, 83 92 const Vector<Bool> haveXPol, 84 const Bool haveBase, 85 const String fluxUnit) 86 { 93 const Bool haveBase) 94 { 95 const string methodName = "create()" ; 96 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 97 98 if (cPKSMS) { 99 os << LogIO::SEVERE << "Output MS already open, close it first." << LogIO::POST ; 100 return 1; 101 } 102 87 103 // Open a MS table. 88 104 TableDesc pksDesc = MS::requiredTableDesc(); … … 93 109 94 110 Int maxNPol = max(cNPol); 95 cGBT = cAPEX = cSMT = cALMA = False; 96 111 cGBT = cAPEX = cSMT = cALMA = cATF = False; 112 113 String telName = antName; 97 114 // check if it is GBT data 98 115 if (antName.contains("GBT")) { … … 108 125 cALMA = True; 109 126 } 127 else if (antName.contains("ATF")) { 128 cATF = True; 129 telName="ATF"; 130 } 110 131 111 112 113 //cGBT = antName.contains("GBT");114 //cAPEX = antName.contains("APEX");115 //cSMT = antName.contains("HHT");116 //cALMA = antName.contains("ALMA");117 118 132 // Add the non-standard CALFCTR column. 119 133 pksDesc.addColumn(ArrayColumnDesc<Float>("CALFCTR", "Calibration factors", … … 125 139 // define("UNIT", String("Jy")); 126 140 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). 127 define("UNIT", fluxUnit);141 define("UNIT", bunit); 128 142 pksDesc.rwColumnDesc(MS::columnName(MS::FLOAT_DATA)).rwKeywordSet(). 129 143 define("MEASURE_TYPE", ""); … … 134 148 IPosition(2,2,maxNPol), ColumnDesc::Direct)); 135 149 pksDesc.addColumn(ArrayColumnDesc<Float>("BASESUB", "Baseline subtracted", 136 IPosition(2, 9,maxNPol), ColumnDesc::Direct));150 IPosition(2,24,maxNPol), ColumnDesc::Direct)); 137 151 } 138 152 … … 147 161 // define("UNIT", "Jy"); 148 162 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). 149 define("UNIT", fluxUnit);163 define("UNIT", bunit); 150 164 pksDesc.rwColumnDesc(MS::columnName(MS::DATA)).rwKeywordSet(). 151 165 define("MEASURE_TYPE", ""); … … 387 401 addFeedEntry(); 388 402 //addObservationEntry(observer, project); 389 addObservationEntry(observer, project, antName);403 addObservationEntry(observer, project, telName); 390 404 addProcessorEntry(); 391 405 … … 397 411 // Write the next data record. 398 412 413 /** 399 414 Int PKSMS2writer::write( 400 415 const Int scanNo, … … 438 453 const Matrix<Float> &spectra, 439 454 const Matrix<uChar> &flagged, 455 const uInt flagrow, 440 456 const Complex xCalFctr, 441 457 const Vector<Complex> &xPol) 458 **/ 459 Int PKSMS2writer::write( 460 const PKSrecord &pksrec) 442 461 { 443 462 // Extend the time range in the OBSERVATION subtable. 444 463 Vector<Double> timerange(2); 445 464 cObservationCols->timeRange().get(0, timerange); 446 Double time = mjd*86400.0;465 Double time = pksrec.mjd*86400.0; 447 466 if (timerange(0) == 0.0) { 448 467 timerange(0) = time; … … 451 470 cObservationCols->timeRange().put(0, timerange); 452 471 453 Int iIF = IFno - 1;472 Int iIF = pksrec.IFno - 1; 454 473 Int nChan = cNChan(iIF); 455 474 Int nPol = cNPol(iIF); … … 457 476 // IFno is the 1-relative row number in the DATA_DESCRIPTION, 458 477 // SPECTRAL_WINDOW, and POLARIZATION subtables. 459 if (Int(cDataDescription.nrow()) < IFno) {478 if (Int(cDataDescription.nrow()) < pksrec.IFno) { 460 479 // Add a new entry to each subtable. 461 addDataDescriptionEntry(IFno); 462 addSpectralWindowEntry(IFno, nChan, refFreq, bandwidth, freqInc); 463 addPolarizationEntry(IFno, nPol); 480 addDataDescriptionEntry(pksrec.IFno); 481 addSpectralWindowEntry(pksrec.IFno, nChan, pksrec.refFreq, 482 pksrec.bandwidth, pksrec.freqInc); 483 addPolarizationEntry(pksrec.IFno, nPol); 464 484 } 465 485 466 486 // Find or add the source to the SOURCE subtable. 467 Int srcId = addSourceEntry(srcName, srcDir, srcPM, restFreq, srcVel); 487 Int srcId = addSourceEntry(pksrec.srcName, pksrec.srcDir, pksrec.srcPM, 488 pksrec.restFreq, pksrec.srcVel); 468 489 469 490 // Find or add the obsMode to the STATE subtable. 470 Int stateId = addStateEntry( obsMode);491 Int stateId = addStateEntry(pksrec.obsType); 471 492 472 493 // FIELD subtable. 473 Int fieldId = addFieldEntry(fieldName, time, direction, scanRate, srcId); 494 //Vector<Double> scanRate(2); 495 //scanRate(0) = pksrec.scanRate(0); 496 //scanRate(1) = pksrec.scanRate(1); 497 Int fieldId = addFieldEntry(pksrec.fieldName, time, pksrec.direction, 498 pksrec.scanRate, srcId); 474 499 475 500 // POINTING subtable. 476 addPointingEntry(time, interval, fieldName, direction, scanRate); 501 addPointingEntry(time, pksrec.interval, pksrec.fieldName, pksrec.direction, 502 pksrec.scanRate); 477 503 478 504 // SYSCAL subtable. 479 addSysCalEntry( beamNo, iIF, time, interval, tcal, tsys, nPol);480 505 addSysCalEntry(pksrec.beamNo, iIF, time, pksrec.interval, pksrec.tcal, 506 pksrec.tsys, nPol); 481 507 482 508 // Handle weather information. … … 484 510 Int nWeather = wTime.nrow(); 485 511 if (nWeather == 0 || time > wTime(nWeather-1)) { 486 addWeatherEntry(time, interval, pressure, humidity, temperature); 512 addWeatherEntry(time, pksrec.interval, pksrec.pressure, pksrec.humidity, 513 pksrec.temperature); 487 514 } 488 515 … … 496 523 cMSCols->antenna1().put(irow, 0); 497 524 cMSCols->antenna2().put(irow, 0); 498 cMSCols->feed1().put(irow, beamNo-1);499 cMSCols->feed2().put(irow, beamNo-1);525 cMSCols->feed1().put(irow, pksrec.beamNo-1); 526 cMSCols->feed2().put(irow, pksrec.beamNo-1); 500 527 cMSCols->dataDescId().put(irow, iIF); 501 528 cMSCols->processorId().put(irow, 0); … … 503 530 504 531 // Non-key attributes. 505 cMSCols->interval().put(irow, interval);506 cMSCols->exposure().put(irow, interval);532 cMSCols->interval().put(irow, pksrec.interval); 533 cMSCols->exposure().put(irow, pksrec.interval); 507 534 cMSCols->timeCentroid().put(irow, time); 508 cMSCols->scanNumber().put(irow, scanNo);535 cMSCols->scanNumber().put(irow, pksrec.scanNo); 509 536 cMSCols->arrayId().put(irow, 0); 510 537 cMSCols->observationId().put(irow, 0); … … 516 543 // Baseline fit parameters. 517 544 if (cHaveBase) { 518 cBaseLinCol->put(irow, baseLin);519 520 if ( baseSub.nrow() == 9) {521 cBaseSubCol->put(irow, baseSub);545 cBaseLinCol->put(irow, pksrec.baseLin); 546 547 if (pksrec.baseSub.nrow() == 24) { 548 cBaseSubCol->put(irow, pksrec.baseSub); 522 549 523 550 } else { 524 Matrix<Float> tmp( 9, 2, 0.0f);551 Matrix<Float> tmp(24, 2, 0.0f); 525 552 for (Int ipol = 0; ipol < nPol; ipol++) { 526 for (uInt j = 0; j < baseSub.nrow(); j++) {527 tmp(j,ipol) = baseSub(j,ipol);553 for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) { 554 tmp(j,ipol) = pksrec.baseSub(j,ipol); 528 555 } 529 556 } … … 531 558 } 532 559 } 560 533 561 // Transpose spectra. 534 562 Matrix<Float> tmpData(nPol, nChan); … … 536 564 for (Int ipol = 0; ipol < nPol; ipol++) { 537 565 for (Int ichan = 0; ichan < nChan; ichan++) { 538 tmpData(ipol,ichan) = spectra(ichan,ipol);539 tmpFlag(ipol,ichan) = flagged(ichan,ipol);566 tmpData(ipol,ichan) = pksrec.spectra(ichan,ipol); 567 tmpFlag(ipol,ichan) = pksrec.flagged(ichan,ipol); 540 568 } 541 569 } 542 cCalFctrCol->put(irow, calFctr); 570 571 cCalFctrCol->put(irow, pksrec.calFctr); 543 572 cMSCols->floatData().put(irow, tmpData); 544 573 cMSCols->flag().put(irow, tmpFlag); … … 546 575 // Cross-polarization spectra. 547 576 if (cHaveXPol(iIF)) { 548 cXCalFctrCol->put(irow, xCalFctr);549 cMSCols->data().put(irow, xPol);550 } 551 552 cMSCols->sigma().put(irow, sigma);577 cXCalFctrCol->put(irow, pksrec.xCalFctr); 578 cMSCols->data().put(irow, pksrec.xPol); 579 } 580 581 cMSCols->sigma().put(irow, pksrec.sigma); 553 582 554 583 //Vector<Float> weight(1, 1.0f); … … 563 592 //cMSCols->flag().put(irow, flags.xyPlane(0)); 564 593 cMSCols->flagCategory().put(irow, flags); 565 cMSCols->flagRow().put(irow, False); 594 // Row-based flagging info. (True:>0, False:0) 595 cMSCols->flagRow().put(irow, (pksrec.flagrow > 0)); 596 566 597 567 598 return 0; … … 601 632 delete cXCalFctrCol; cXCalFctrCol=0; 602 633 } 603 634 604 635 // Release all subtables. 605 636 cAntenna = MSAntenna(); … … 620 651 cWeather = MSWeather(); 621 652 // Release the main table. 622 delete cPKSMS; cPKSMS=0; 653 delete cPKSMS; 654 cPKSMS=0x0; 623 655 } 624 656 … … 649 681 } 650 682 else if (cALMA) { 683 // this needs to be changed in future... 651 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); 652 697 cAntennaCols->dishDiameter().put(n, 12.0); 653 698 } … … 1095 1140 1096 1141 Int PKSMS2writer::addStateEntry( 1097 const String obs Mode)1142 const String obsType) 1098 1143 { 1099 1144 // Look for an entry in the STATE subtable. 1100 1145 for (uInt n = 0; n < cStateCols->nrow(); n++) { 1101 if (cStateCols->obsMode()(n) == obs Mode) {1146 if (cStateCols->obsMode()(n) == obsType) { 1102 1147 return n; 1103 1148 } … … 1109 1154 1110 1155 // Data. 1111 if (obs Mode.contains("RF")) {1156 if (obsType.contains("RF")) { 1112 1157 cStateCols->sig().put(n, False); 1113 1158 cStateCols->ref().put(n, True); 1114 } else if (!obs Mode.contains("PA")) {1159 } else if (!obsType.contains("PA")) { 1115 1160 // Signal and reference are both false for "paddle" data. 1116 1161 cStateCols->sig().put(n, True); … … 1121 1166 cStateCols->cal().put(n, 0.0); 1122 1167 cStateCols->subScan().put(n, 0); 1123 cStateCols->obsMode().put(n, obs Mode);1168 cStateCols->obsMode().put(n, obsType); 1124 1169 1125 1170 // Flags. -
branches/alma/external/atnf/PKSIO/PKSMS2writer.h
r1453 r1757 2 2 //# PKSMS2writer.h: Class to write Parkes Multibeam data to a measurementset. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 18 //# 19 //# You should have received a copy of the GNU General Public License along 20 //# with livedata. If not, see <http://www.gnu.org/licenses/>. 21 //# 22 //# Correspondence concerning livedata may be directed to: 23 //# Internet email: mcalabre@atnf.csiro.au 24 //# Postal address: Dr. Mark Calabretta 25 //# Australia Telescope National Facility, CSIRO 26 //# PO Box 76 27 //# Epping NSW 1710 28 //# AUSTRALIA 29 //# 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSMS2writer.h,v 19.14 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 … … 32 35 #define ATNF_PKSMS2WRITER_H 33 36 37 #include <atnf/PKSIO/PKSrecord.h> 34 38 #include <atnf/PKSIO/PKSwriter.h> 35 39 … … 38 42 #include <casa/Arrays/Vector.h> 39 43 #include <casa/BasicSL/Complex.h> 44 #include <casa/BasicSL/String.h> 40 45 #include <ms/MeasurementSets/MeasurementSet.h> 41 46 #include <ms/MeasurementSets/MSColumns.h> 42 #include <casa/BasicSL/String.h> 47 48 #include <casa/namespace.h> 43 49 44 50 // <summary> … … 46 52 // </summary> 47 53 48 #include <casa/namespace.h>49 54 class PKSMS2writer : public PKSwriter 50 55 { … … 64 69 const Vector<Double> antPosition, 65 70 const String obsMode, 71 const String bunit, 66 72 const Float equinox, 67 73 const String dopplerFrame, … … 69 75 const Vector<uInt> nPol, 70 76 const Vector<Bool> haveXPol, 71 const Bool haveBase, 72 const String fluxUnit); 77 const Bool haveBase); 73 78 74 79 // Write the next data record. 80 /** 75 81 virtual Int write( 76 82 const Int scanNo, … … 114 120 const Matrix<Float> &spectra, 115 121 const Matrix<uChar> &flagged, 122 const uInt flagrow, 116 123 const Complex xCalFctr, 117 124 const Vector<Complex> &xPol); 125 **/ 126 virtual Int write( 127 const PKSrecord &pksrec); 118 128 119 129 // Close the MS, flushing all associated Tables. … … 168 178 169 179 // for handling parameters specific to GBT and other telescopes 170 Bool cGBT; 171 Bool cSMT; 172 Bool cAPEX; 173 Bool cALMA; 180 Bool cGBT, cSMT, cAPEX, cALMA, cATF; 174 181 175 182 // Add an entry to the ANTENNA subtable. -
branches/alma/external/atnf/PKSIO/PKSSDwriter.cc
r1453 r1757 2 2 //# PKSSDwriter.cc: Class to write Parkes multibeam data to an SDFITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but 13 //# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 //# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 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: PKSSDwriter.cc,v 19.17 2009-09-29 07:33:38 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 31 #include <atnf/PKSIO/ PKSMBrecord.h>34 #include <atnf/PKSIO/MBrecord.h> 32 35 #include <atnf/PKSIO/PKSSDwriter.h> 33 36 37 #include <casa/Logging/LogIO.h> 38 39 #include <casa/stdio.h> 34 40 #include <casa/Quanta/MVTime.h> 35 41 42 #include <string> 43 #include <cstring> 44 45 // Class name 46 const string className = "PKSSDwriter" ; 36 47 37 48 //--------------------------------------------------- PKSSDwriter::PKSSDwriter … … 63 74 const Vector<Double> antPosition, 64 75 const String obsMode, 76 const String bunit, 65 77 const Float equinox, 66 78 const String dopplerFrame, … … 68 80 const Vector<uInt> nPol, 69 81 const Vector<Bool> haveXPol, 70 const Bool haveBase, 71 const String fluxUnit) 72 { 82 const Bool haveBase) 83 { 84 const string methodName = "create()" ; 85 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 86 73 87 double antPos[3]; 74 88 antPos[0] = antPosition(0); … … 78 92 cNIF = nChan.nelements(); 79 93 if (nPol.nelements() != cNIF || haveXPol.nelements() != cNIF) { 80 cerr << "PKSSDwriter::create: " 81 << "Inconsistent number of IFs for nChan, nPol, and/or haveXPol." 82 << endl; 94 os << LogIO::SEVERE << "Inconsistent number of IFs for nChan, nPol, and/or haveXPol." << LogIO::POST ; 83 95 return 1; 84 96 } … … 102 114 Int status = cSDwriter.create((char *)sdName.chars(), 103 115 (char *)observer.chars(), (char *)project.chars(), 104 (char *)antName.chars(), antPos, (char *)obsMode.chars(), equinox,105 (char *) dopplerFrame.chars(), cNIF,116 (char *)antName.chars(), antPos, (char *)obsMode.chars(), 117 (char *)bunit.chars(), equinox, (char *)dopplerFrame.chars(), cNIF, 106 118 (int *)cNChan.getStorage(deleteIt), 107 119 (int *)cNPol.getStorage(deleteIt), 108 120 (int *)cHaveXPol.getStorage(deleteIt), (int)cHaveBase, 1); 121 //logMsg(cSDwriter.getMsg()); 122 //cSDwriter.clearMsg(); 109 123 if (status) { 110 cSDwriter.reportError();111 124 cSDwriter.deleteFile(); 112 125 close(); … … 121 134 122 135 Int PKSSDwriter::write( 123 const Int scanNo, 124 const Int cycleNo, 125 const Double mjd, 126 const Double interval, 127 const String fieldName, 128 const String srcName, 129 const Vector<Double> srcDir, 130 const Vector<Double> srcPM, 131 const Double srcVel, 132 const String obsMode, 133 const Int IFno, 134 const Double refFreq, 135 const Double bandwidth, 136 const Double freqInc, 137 //const Double restFreq, 138 const Vector<Double> restFreq, 139 const Vector<Float> tcal, 140 const String tcalTime, 141 const Float azimuth, 142 const Float elevation, 143 const Float parAngle, 144 const Float focusAxi, 145 const Float focusTan, 146 const Float focusRot, 147 const Float temperature, 148 const Float pressure, 149 const Float humidity, 150 const Float windSpeed, 151 const Float windAz, 152 const Int refBeam, 153 const Int beamNo, 154 const Vector<Double> direction, 155 const Vector<Double> scanRate, 156 const Vector<Float> tsys, 157 const Vector<Float> sigma, 158 const Vector<Float> calFctr, 159 const Matrix<Float> baseLin, 160 const Matrix<Float> baseSub, 161 const Matrix<Float> &spectra, 162 const Matrix<uChar> &flagged, 163 const Complex xCalFctr, 164 const Vector<Complex> &xPol) 165 { 136 const PKSrecord &pksrec) 137 { 138 const string methodName = "write()" ; 139 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 140 166 141 // Do basic checks. 142 Int IFno = pksrec.IFno; 167 143 uInt iIF = IFno - 1; 168 144 if (IFno < 1 || Int(cNIF) < IFno) { 169 cerr << "PKSDwriter::write: "170 171 << " (maximum " << cNIF << ")." << endl;145 os << LogIO::SEVERE 146 << "Invalid IF number " << IFno 147 << " (maximum " << cNIF << ")." << LogIO::POST ; 172 148 return 1; 173 149 } 174 150 175 uInt nChan = spectra.nrow();151 uInt nChan = pksrec.spectra.nrow(); 176 152 if (nChan != cNChan(iIF)) { 177 cerr << "PKSDwriter::write: " 178 << "Wrong number of channels for IF " << IFno << "," << endl 179 << " " 153 os << LogIO::SEVERE << "Wrong number of channels for IF " << IFno << "," << endl 180 154 << "got " << nChan << " should be " << cNChan(iIF) << "." << endl; 155 os << LogIO::POST ; 181 156 return 1; 182 157 } 183 158 184 uInt nPol = spectra.ncolumn();159 uInt nPol = pksrec.spectra.ncolumn(); 185 160 if (nPol != cNPol(iIF)) { 186 cerr << "PKSDwriter::write: " 187 << "Wrong number of polarizations for IF " << IFno << "," << endl 188 << " " 189 << "got " << nPol << " should be " << cNPol(iIF) << "." << endl; 161 os << LogIO::SEVERE << "Wrong number of polarizations for IF " << IFno << "," << endl 162 << "got " << nPol << " should be " << cNPol(iIF) << "." << endl; 163 os << LogIO::POST ; 190 164 return 1; 191 165 } 192 166 193 // Extract calendar information fr om mjd.194 MVTime time( mjd);167 // Extract calendar information frrom mjd. 168 MVTime time(pksrec.mjd); 195 169 Int year = time.year(); 196 170 Int month = time.month(); 197 171 Int day = time.monthday(); 198 172 199 // Transfer data to a single-IF PKSMBrecord.200 PKSMBrecord mbrec(1);173 // Transfer data to a single-IF MBrecord. 174 MBrecord mbrec(1); 201 175 202 176 // Start with basic beam- and IF-independent bookkeeping information. 203 mbrec.scanNo = scanNo;204 mbrec.cycleNo = cycleNo;177 mbrec.scanNo = pksrec.scanNo; 178 mbrec.cycleNo = pksrec.cycleNo; 205 179 206 180 sprintf(mbrec.datobs, "%4.4d-%2.2d-%2.2d", year, month, day); 207 mbrec.utc = fmod(mjd, 1.0) * 86400.0; 208 mbrec.exposure = float(interval); 209 210 strncpy(mbrec.srcName, (char *)srcName.chars(), 17); 211 mbrec.srcRA = srcDir(0); 212 mbrec.srcDec = srcDir(1); 213 214 //mbrec.restFreq = restFreq; 215 mbrec.restFreq = restFreq(0); 216 217 strncpy(mbrec.obsType, (char *)obsMode.chars(), 16); 181 mbrec.utc = fmod(pksrec.mjd, 1.0) * 86400.0; 182 mbrec.exposure = float(pksrec.interval); 183 184 strncpy(mbrec.srcName, (char *)pksrec.srcName.chars(), 17); 185 mbrec.srcRA = pksrec.srcDir(0); 186 mbrec.srcDec = pksrec.srcDir(1); 187 if (pksrec.restFreq.shape()==0) { 188 mbrec.restFreq = 0; 189 } 190 else { 191 mbrec.restFreq = pksrec.restFreq(0); 192 } 193 strncpy(mbrec.obsType, (char *)pksrec.obsType.chars(), 16); 218 194 219 195 // Now beam-dependent parameters. 220 mbrec.beamNo = beamNo;221 mbrec.ra = direction(0);222 mbrec.dec = direction(1);223 mbrec.raRate = scanRate(0);224 mbrec.decRate = scanRate(1);196 mbrec.beamNo = pksrec.beamNo; 197 mbrec.ra = pksrec.direction(0); 198 mbrec.dec = pksrec.direction(1); 199 mbrec.raRate = pksrec.scanRate(0); 200 mbrec.decRate = pksrec.scanRate(1); 225 201 226 202 // Now IF-dependent parameters. … … 231 207 232 208 mbrec.fqRefPix[0] = (nChan/2) + 1; 233 mbrec.fqRefVal[0] = refFreq;234 mbrec.fqDelt[0] = freqInc;209 mbrec.fqRefVal[0] = pksrec.refFreq; 210 mbrec.fqDelt[0] = pksrec.freqInc; 235 211 236 212 // Now the data itself. 237 for (uInt i = 0; i < tsys.nelements(); i++) {238 mbrec.tsys[0][i] = tsys(i);213 for (uInt i = 0; i < pksrec.tsys.nelements(); i++) { 214 mbrec.tsys[0][i] = pksrec.tsys(i); 239 215 } 240 216 241 217 for (uInt ipol = 0; ipol < nPol; ipol++) { 242 mbrec.calfctr[0][ipol] = calFctr(ipol);218 mbrec.calfctr[0][ipol] = pksrec.calFctr(ipol); 243 219 } 244 220 245 221 if (cHaveXPol(iIF)) { 246 mbrec.xcalfctr[0][0] = xCalFctr.real();247 mbrec.xcalfctr[0][1] = xCalFctr.imag();222 mbrec.xcalfctr[0][0] = pksrec.xCalFctr.real(); 223 mbrec.xcalfctr[0][1] = pksrec.xCalFctr.imag(); 248 224 } else { 249 225 mbrec.xcalfctr[0][0] = 0.0f; … … 255 231 256 232 for (uInt ipol = 0; ipol < nPol; ipol++) { 257 mbrec.baseLin[0][ipol][0] = baseLin(0,ipol);258 mbrec.baseLin[0][ipol][1] = baseLin(1,ipol);259 260 for (uInt j = 0; j < baseSub.nrow(); j++) {261 mbrec.baseSub[0][ipol][j] = baseSub(j,ipol);233 mbrec.baseLin[0][ipol][0] = pksrec.baseLin(0,ipol); 234 mbrec.baseLin[0][ipol][1] = pksrec.baseLin(1,ipol); 235 236 for (uInt j = 0; j < pksrec.baseSub.nrow(); j++) { 237 mbrec.baseSub[0][ipol][j] = pksrec.baseSub(j,ipol); 262 238 } 263 for (uInt j = baseSub.nrow(); j < 9; j++) {239 for (uInt j = pksrec.baseSub.nrow(); j < 24; j++) { 264 240 mbrec.baseSub[0][ipol][j] = 0.0f; 265 241 } … … 271 247 272 248 Bool delSpectra = False; 273 const Float *specstor = spectra.getStorage(delSpectra);249 const Float *specstor = pksrec.spectra.getStorage(delSpectra); 274 250 mbrec.spectra[0] = (float *)specstor; 275 251 276 252 Bool delFlagged = False; 277 const uChar *flagstor = flagged.getStorage(delFlagged);253 const uChar *flagstor = pksrec.flagged.getStorage(delFlagged); 278 254 mbrec.flagged[0] = (unsigned char *)flagstor; 279 255 … … 281 257 const Complex *xpolstor; 282 258 if (cHaveXPol(iIF)) { 283 xpolstor = xPol.getStorage(delXPol);259 xpolstor = pksrec.xPol.getStorage(delXPol); 284 260 } else { 285 261 xpolstor = 0; … … 289 265 // Finish off with system calibration parameters. 290 266 mbrec.extraSysCal = 1; 291 mbrec.refBeam = refBeam;292 for (uInt i = 0; i < tcal.nelements(); i++) {293 mbrec.tcal[0][i] = tcal(i);294 } 295 strncpy(mbrec.tcalTime, (char *) tcalTime.chars(), 16);296 mbrec.azimuth = azimuth;297 mbrec.elevation = elevation;298 mbrec.parAngle = p arAngle;299 mbrec.focusAxi = focusAxi;300 mbrec.focusTan = focusTan;301 mbrec.focusRot = focusRot;302 mbrec.temp = temperature;303 mbrec.pressure = p ressure;304 mbrec.humidity = humidity;305 mbrec.windSpeed = windSpeed;306 mbrec.windAz = windAz;267 mbrec.refBeam = pksrec.refBeam; 268 for (uInt i = 0; i < pksrec.tcal.nelements(); i++) { 269 mbrec.tcal[0][i] = pksrec.tcal(i); 270 } 271 strncpy(mbrec.tcalTime, (char *)pksrec.tcalTime.chars(), 16); 272 mbrec.azimuth = pksrec.azimuth; 273 mbrec.elevation = pksrec.elevation; 274 mbrec.parAngle = pksrec.parAngle; 275 mbrec.focusAxi = pksrec.focusAxi; 276 mbrec.focusTan = pksrec.focusTan; 277 mbrec.focusRot = pksrec.focusRot; 278 mbrec.temp = pksrec.temperature; 279 mbrec.pressure = pksrec.pressure; 280 mbrec.humidity = pksrec.humidity; 281 mbrec.windSpeed = pksrec.windSpeed; 282 mbrec.windAz = pksrec.windAz; 307 283 308 284 Int status = cSDwriter.write(mbrec); 285 //logMsg(cSDwriter.getMsg()); 286 //cSDwriter.clearMsg(); 309 287 if (status) { 310 cSDwriter.reportError();311 288 status = 1; 312 289 } 313 290 314 spectra.freeStorage(specstor, delSpectra);315 flagged.freeStorage(flagstor, delFlagged);316 xPol.freeStorage(xpolstor, delXPol);291 pksrec.spectra.freeStorage(specstor, delSpectra); 292 pksrec.flagged.freeStorage(flagstor, delFlagged); 293 pksrec.xPol.freeStorage(xpolstor, delXPol); 317 294 318 295 return status; 319 296 } 320 297 298 //------------------------------------------------------- PKSSDwriter::history 299 300 // Write a history record. 301 302 Int PKSSDwriter::history(const String text) 303 { 304 return cSDwriter.history((char *)text.chars()); 305 } 306 307 Int PKSSDwriter::history(const char *text) 308 { 309 return cSDwriter.history((char *)text); 310 } 311 321 312 //--------------------------------------------------------- PKSSDwriter::close 322 313 … … 326 317 { 327 318 cSDwriter.close(); 328 } 319 //logMsg(cSDwriter.getMsg()); 320 //cSDwriter.clearMsg(); 321 } -
branches/alma/external/atnf/PKSIO/PKSSDwriter.h
r1453 r1757 1 1 //#--------------------------------------------------------------------------- 2 //# PKSSD Writer.h: Class to write Parkes multibeam data to an SDFITS file.2 //# PKSSDwriter.h: Class to write Parkes multibeam data to an SDFITS file. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSSDwriter.h,v 19.17 2009-09-29 07:33:38 cal103 Exp $ 29 32 //# Original: 2000/07/21, Mark Calabretta, ATNF 30 33 //#--------------------------------------------------------------------------- … … 34 37 35 38 #include <atnf/PKSIO/PKSwriter.h> 39 #include <atnf/PKSIO/PKSrecord.h> 36 40 #include <atnf/PKSIO/SDFITSwriter.h> 37 41 38 42 #include <casa/aips.h> 43 #include <casa/stdio.h> 39 44 #include <casa/Arrays/Vector.h> 40 45 #include <casa/Arrays/Matrix.h> … … 42 47 #include <casa/BasicSL/String.h> 43 48 49 #include <casa/namespace.h> 50 44 51 // <summary> 45 52 // Class to write Parkes multibeam data to an SDFITS file. 46 53 // </summary> 47 54 48 #include <casa/namespace.h>49 55 class PKSSDwriter : public PKSwriter 50 56 { … … 64 70 const Vector<Double> antPosition, 65 71 const String obsMode, 72 const String bunit, 66 73 const Float equinox, 67 74 const String dopplerFrame, … … 69 76 const Vector<uInt> nPol, 70 77 const Vector<Bool> haveXPol, 71 const Bool haveBase, 72 const String fluxUnit); 78 const Bool haveBase); 73 79 74 80 // Write the next data record. 75 81 virtual Int write( 76 const Int scanNo, 77 const Int cycleNo, 78 const Double mjd, 79 const Double interval, 80 const String fieldName, 81 const String srcName, 82 const Vector<Double> srcDir, 83 const Vector<Double> srcPM, 84 const Double srcVel, 85 const String obsMode, 86 const Int IFno, 87 const Double refFreq, 88 const Double bandwidth, 89 const Double freqInc, 90 //const Double restFreq, 91 const Vector<Double> restFreq, 92 const Vector<Float> tcal, 93 const String tcalTime, 94 const Float azimuth, 95 const Float elevation, 96 const Float parAngle, 97 const Float focusAxi, 98 const Float focusTan, 99 const Float focusRot, 100 const Float temperature, 101 const Float pressure, 102 const Float humidity, 103 const Float windSpeed, 104 const Float windAz, 105 const Int refBeam, 106 const Int beamNo, 107 const Vector<Double> direction, 108 const Vector<Double> scanRate, 109 const Vector<Float> tsys, 110 const Vector<Float> sigma, 111 const Vector<Float> calFctr, 112 const Matrix<Float> baselin, 113 const Matrix<Float> basesub, 114 const Matrix<Float> &spectra, 115 const Matrix<uChar> &flagged, 116 const Complex xCalFctr, 117 const Vector<Complex> &xPol); 82 const PKSrecord &pksrec); 83 84 // Write a history record. 85 virtual Int history(const String text); 86 virtual Int history(const char *text); 118 87 119 88 // Close the SDFITS file. -
branches/alma/external/atnf/PKSIO/PKSreader.cc
r1453 r1757 2 2 //# PKSreader.cc: Class to read Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 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: PKSreader.cc,v 19.13 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/23, Mark Calabretta, ATNF … … 41 44 #include <casa/OS/File.h> 42 45 43 44 46 //--------------------------------------------------------------- getPKSreader 45 47 … … 50 52 const Int retry, 51 53 const Int interpolate, 52 String &format, 53 Vector<Bool> &beams, 54 Vector<Bool> &IFs, 55 Vector<uInt> &nChan, 56 Vector<uInt> &nPol, 57 Vector<Bool> &haveXPol, 58 Bool &haveBase, 59 Bool &haveSpectra) 54 String &format) 60 55 { 61 56 // Check accessibility of the input. … … 63 58 if (!inFile.exists()) { 64 59 format = "DATASET NOT FOUND"; 65 return 0 ;60 return 0x0; 66 61 } 67 62 68 63 if (!inFile.isReadable()) { 69 64 format = "DATASET UNREADABLE"; 70 return 0 ;65 return 0x0; 71 66 } 72 67 73 68 // Determine the type of input. 74 PKSreader *reader = 0 ;69 PKSreader *reader = 0x0; 75 70 if (inFile.isRegular()) { 76 71 // Is it MBFITS or SDFITS? 77 RegularFileIO file(name); 78 char buf[32]; 79 file.read(30, buf, False); 80 buf[30] = '\0'; 81 if (String(buf) == "SIMPLE = T") { 82 // Looks like SDFITS. 72 if (strstr(name.chars(), ".sdfits")) { 73 // Looks like SDFITS, possibly gzip'd. 83 74 format = "SDFITS"; 84 75 reader = new PKSFITSreader("SDFITS"); 85 76 86 77 } else { 87 // Assume it's MBFITS. 88 format = "MBFITS"; 89 reader = new PKSFITSreader("MBFITS", retry, interpolate); 78 RegularFileIO file(name); 79 char buf[32]; 80 file.read(30, buf, False); 81 buf[30] = '\0'; 82 if (String(buf) == "SIMPLE = T") { 83 // Looks like SDFITS. 84 format = "SDFITS"; 85 reader = new PKSFITSreader("SDFITS"); 86 87 } else { 88 // Assume it's MBFITS. 89 format = "MBFITS"; 90 reader = new PKSFITSreader("MBFITS", retry, interpolate); 91 } 90 92 } 91 93 … … 104 106 format = "UNRECOGNIZED INPUT FORMAT"; 105 107 } 106 108 return reader; 109 } 110 111 //--------------------------------------------------------------- getPKSreader 112 113 // Search a list of directories for a Parkes Multibeam dataset and return an 114 115 PKSreader* getPKSreader( 116 const String name, 117 const Vector<String> directories, 118 const Int retry, 119 const Int interpolate, 120 Int &iDir, 121 String &format) 122 { 123 PKSreader *reader = 0x0; 124 125 iDir = -1; 126 Int nDir = directories.nelements(); 127 for (Int i = 0; i < nDir; i++) { 128 String inName = directories(i) + "/" + name; 129 reader = getPKSreader(inName, retry, interpolate, format); 130 if (reader) { 131 iDir = i; 132 break; 133 } 134 } 135 136 return reader; 137 } 138 139 //--------------------------------------------------------------- getPKSreader 140 141 // Open an appropriate PKSreader for a Parkes Multibeam dataset. 142 143 PKSreader* getPKSreader( 144 const String name, 145 const String antenna, 146 const Int retry, 147 const Int interpolate, 148 String &format, 149 Vector<Bool> &beams, 150 Vector<Bool> &IFs, 151 Vector<uInt> &nChan, 152 Vector<uInt> &nPol, 153 Vector<Bool> &haveXPol, 154 Bool &haveBase, 155 Bool &haveSpectra) 156 { 157 PKSreader *reader = getPKSreader(name, retry, interpolate, format); 107 158 108 159 // Try to open it. 109 160 if (reader) { 110 if (reader->open(name, beams, IFs, nChan, nPol, haveXPol, haveBase,111 have Spectra)) {161 if (reader->open(name, antenna, beams, IFs, nChan, nPol, haveXPol, 162 haveBase, haveSpectra)) { 112 163 format += " OPEN ERROR"; 113 164 delete reader; 114 } else { 115 return reader; 116 } 117 } 118 119 return 0; 120 } 121 165 reader = 0x0; 166 } 167 } 168 169 return reader; 170 } 122 171 123 172 //--------------------------------------------------------------- getPKSreader … … 125 174 // Search a list of directories for a Parkes Multibeam dataset and return an 126 175 // appropriate PKSreader for it. 127 128 PKSreader* getPKSreader( 129 const String name,176 PKSreader* getPKSreader( 177 const String name, 178 const String antenna, 130 179 const Vector<String> directories, 131 180 const Int retry, … … 141 190 Bool &haveSpectra) 142 191 { 143 Int nDir = directories.nelements(); 144 for (iDir = 0; iDir < nDir; iDir++) { 145 String inName = directories(iDir) + "/" + name; 146 PKSreader *reader = getPKSreader(inName, retry, interpolate, format, 147 beams, IFs, nChan, nPol, haveXPol, 148 haveBase, haveSpectra); 149 if (reader != 0) { 150 return reader; 151 } 152 } 153 154 iDir = -1; 155 return 0; 156 } 192 PKSreader *reader = getPKSreader(name, directories, retry, interpolate, 193 iDir, format); 194 195 // Try to open it. 196 if (reader) { 197 if (reader->open(name, antenna, beams, IFs, nChan, nPol, haveXPol, 198 haveBase, haveSpectra)) { 199 format += " OPEN ERROR"; 200 delete reader; 201 reader = 0x0; 202 } 203 } 204 205 return reader; 206 } -
branches/alma/external/atnf/PKSIO/PKSreader.h
r1453 r1757 2 2 //# PKSreader.h: Class to read Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# $Id$ 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: PKSreader.h,v 19.24 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# Original: 2000/08/02, Mark Calabretta, ATNF … … 33 36 #ifndef ATNF_PKSREADER_H 34 37 #define ATNF_PKSREADER_H 38 39 #include <atnf/PKSIO/PKSrecord.h> 40 #include <atnf/PKSIO/SrcType.h> 35 41 36 42 #include <casa/aips.h> … … 40 46 #include <casa/BasicSL/String.h> 41 47 48 #include <casa/namespace.h> 49 42 50 // <summary> 43 51 // Class to read Parkes multibeam data. 44 52 // </summary> 45 53 46 #include <casa/namespace.h> 54 // Return an appropriate PKSreader for a Parkes Multibeam dataset. 55 class PKSreader* getPKSreader( 56 const String name, 57 const Int retry, 58 const Int interpolate, 59 String &format); 60 61 // As above, but search a list of directories for it. 62 class PKSreader* getPKSreader( 63 const String name, 64 const Vector<String> directories, 65 const Int retry, 66 const Int interpolate, 67 Int &iDir, 68 String &format); 47 69 48 70 // Open an appropriate PKSreader for a Parkes Multibeam dataset. 49 71 class PKSreader* getPKSreader( 50 72 const String name, 73 const String antenna, 51 74 const Int retry, 52 75 const Int interpolate, … … 63 86 class PKSreader* getPKSreader( 64 87 const String name, 88 const String antenna, 65 89 const Vector<String> directories, 66 90 const Int retry, … … 86 110 virtual Int open( 87 111 const String inName, 112 const String antenna, 88 113 Vector<Bool> &beams, 89 114 Vector<Bool> &IFs, … … 101 126 Vector<Double> &antPosition, 102 127 String &obsType, 128 String &bunit, 103 129 Float &equinox, 104 130 String &dopplerFrame, 105 131 Double &mjd, 106 132 Double &refFreq, 107 Double &bandwidth, 108 String &fluxunit) = 0; 133 Double &bandwidth) = 0; 109 134 110 135 // Get frequency parameters for each IF. … … 115 140 // Set data selection criteria. Channel numbering is 1-relative, zero or 116 141 // negative channel numbers are taken to be offsets from the last channel. 142 // Coordinate system selection (only supported for SDFITS input): 143 // 0: equatorial (RA,Dec), 144 // 1: horizontal (Az,El), 145 // 2: feed-plane, 146 // 3: zenithal position angle of feed and elevation, (ZPA,El). 117 147 virtual uInt select( 118 148 const Vector<Bool> beamSel, … … 123 153 const Bool getSpectra = True, 124 154 const Bool getXPol = False, 125 const Bool getFeedPos = False) = 0; 155 const Bool getFeedPos = False, 156 const Bool getPointing = False, 157 const Int coordSys = 0) = 0; 158 126 159 127 160 // Find the range of the data selected in time and position. … … 132 165 Matrix<Double> &positions) = 0; 133 166 134 // Read the next data record. 167 // Read the next data record. 168 /** 135 169 virtual Int read( 136 170 Int &scanNo, … … 175 209 Complex &xCalFctr, 176 210 Vector<Complex> &xPol) = 0; 177 211 **/ 212 /** 178 213 // Read the next data record, just the basics. 179 214 virtual Int read( … … 185 220 Matrix<Float> &spectra, 186 221 Matrix<uChar> &flagged) = 0; 222 **/ 223 virtual Int read(PKSrecord &pksrec) = 0; 187 224 188 225 // Close the input file. … … 190 227 191 228 protected: 192 Bool cGetFeedPos, cGetSpectra, cGetXPol; 229 Bool cGetFeedPos, cGetSpectra, cGetXPol, cGetPointing; 230 Int cCoordSys; 193 231 194 232 Vector<uInt> cNChan, cNPol; -
branches/alma/external/atnf/PKSIO/PKSrecord.h
r1752 r1757 67 67 Double bandwidth; 68 68 Double freqInc; 69 Double restFreq; 69 Int nchan; 70 Vector<Double> restFreq; 70 71 Vector<Float> tcal; 71 72 String tcalTime; … … 86 87 Int pCode; 87 88 Float rateAge; 88 Vector< Float>scanRate;89 Vector<Double> scanRate; 89 90 Float paRate; 90 91 Vector<Float> tsys; … … 95 96 Matrix<Float> spectra; 96 97 Matrix<uChar> flagged; 98 uInt flagrow; 97 99 Complex xCalFctr; 98 100 Vector<Complex> xPol; 101 Int polNo ; 102 Int srcType ; 99 103 }; 100 104 -
branches/alma/external/atnf/PKSIO/PKSwriter.h
r1453 r1757 2 2 //# PKSwriter.h: Class to write out Parkes multibeam data. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: PKSwriter.h,v 19.17 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 31 34 #ifndef ATNF_PKSWRITER_H 32 35 #define ATNF_PKSWRITER_H 36 37 #include <atnf/PKSIO/PKSrecord.h> 33 38 34 39 #include <casa/aips.h> … … 38 43 #include <casa/BasicSL/String.h> 39 44 45 #include <casa/namespace.h> 46 40 47 // <summary> 41 48 // Class to write out Parkes multibeam data. 42 49 // </summary> 43 50 44 #include <casa/namespace.h>45 51 class PKSwriter 46 52 { … … 57 63 const Vector<Double> antPosition, 58 64 const String obsMode, 65 const String bunit, 59 66 const Float equinox, 60 67 const String dopplerFrame, … … 62 69 const Vector<uInt> nPol, 63 70 const Vector<Bool> haveXPol, 64 const Bool havebase, 65 const String fluxUnit) = 0; 71 const Bool havebase) = 0; 66 72 67 73 // Write the next data record. 68 74 virtual Int write ( 69 const Int scanNo, 70 const Int cycleNo, 71 const Double mjd, 72 const Double interval, 73 const String fieldName, 74 const String srcName, 75 const Vector<Double> srcDir, 76 const Vector<Double> srcPM, 77 const Double srcVel, 78 const String obsMode, 79 const Int IFno, 80 const Double refFreq, 81 const Double bandwidth, 82 const Double freqInc, 83 //const Double restFreq, 84 const Vector<Double> restFreq, 85 const Vector<Float> tcal, 86 const String tcalTime, 87 const Float azimuth, 88 const Float elevation, 89 const Float parAngle, 90 const Float focusAxi, 91 const Float focusTan, 92 const Float focusRot, 93 const Float temperature, 94 const Float pressure, 95 const Float humidity, 96 const Float windSpeed, 97 const Float windAz, 98 const Int refBeam, 99 const Int beamNo, 100 const Vector<Double> direction, 101 const Vector<Double> scanRate, 102 const Vector<Float> tsys, 103 const Vector<Float> sigma, 104 const Vector<Float> calFctr, 105 const Matrix<Float> baseLin, 106 const Matrix<Float> baseSub, 107 const Matrix<Float> &spectra, 108 const Matrix<uChar> &flagged, 109 const Complex xCalFctr, 110 const Vector<Complex> &xPol) = 0; 75 const PKSrecord &pksrec) = 0; 76 77 // Write a history record. 78 virtual Int history(const String text) {return 0;}; 79 virtual Int history(const char *text) {return 0;}; 111 80 112 81 // Close the output file. -
branches/alma/external/atnf/PKSIO/SDFITSreader.cc
r1453 r1757 1 1 //#--------------------------------------------------------------------------- 2 //# SDFITSreader.cc: ATNF CFITSIO interface class for SDFITS input.2 //# SDFITSreader.cc: ATNF interface class for SDFITS input using CFITSIO. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSreader.cc,v 19.45 2009-09-30 07:23:48 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# The SDFITSreader class reads single dish FITS files such as those written … … 34 37 //#--------------------------------------------------------------------------- 35 38 39 #include <atnf/pks/pks_maths.h> 40 #include <atnf/PKSIO/MBrecord.h> 41 #include <atnf/PKSIO/SDFITSreader.h> 42 43 #include <casa/Logging/LogIO.h> 44 #include <casa/Quanta/MVTime.h> 45 #include <casa/math.h> 46 #include <casa/stdio.h> 47 36 48 #include <algorithm> 37 49 #include <strings.h> 38 39 // AIPS++ includes. 40 #include <casa/iostream.h> 41 #include <casa/math.h> 42 #include <casa/stdio.h> 43 44 // ATNF includes. 45 #include <atnf/pks/pks_maths.h> 46 #include <atnf/PKSIO/PKSMBrecord.h> 47 #include <atnf/PKSIO/SDFITSreader.h> 48 50 #include <cstring> 49 51 50 52 class FITSparm … … 57 59 long nelem; // Column data repeat count; < 0 for vardim. 58 60 int tdimcol; // TDIM column number; 0 for keyword; -1 absent. 61 char units[32]; // Units from TUNITn keyword. 59 62 }; 60 63 … … 64 67 // Factor to convert radians to degrees. 65 68 const double D2R = PI / 180.0; 69 70 // Class name 71 const string className = "SDFITSreader" ; 72 73 //---------------------------------------------------- SDFITSreader::(statics) 74 75 int SDFITSreader::sInit = 1; 76 int SDFITSreader::sReset = 0; 77 int (*SDFITSreader::sALFAcalNon)[2] = (int (*)[2])(new float[16]); 78 int (*SDFITSreader::sALFAcalNoff)[2] = (int (*)[2])(new float[16]); 79 float (*SDFITSreader::sALFAcalOn)[2] = (float (*)[2])(new float[16]); 80 float (*SDFITSreader::sALFAcalOff)[2] = (float (*)[2])(new float[16]); 81 float (*SDFITSreader::sALFAcal)[2] = (float (*)[2])(new float[16]); 66 82 67 83 //------------------------------------------------- SDFITSreader::SDFITSreader … … 70 86 { 71 87 // Default constructor. 72 cSDptr = 0 ;88 cSDptr = 0x0; 73 89 74 90 // Allocate space for data descriptors. … … 85 101 cEndChan = 0x0; 86 102 cRefChan = 0x0; 103 cPols = 0x0; 87 104 } 88 105 … … 113 130 int &extraSysCal) 114 131 { 132 const string methodName = "open()" ; 133 115 134 if (cSDptr) { 116 135 close(); … … 120 139 cStatus = 0; 121 140 if (fits_open_file(&cSDptr, sdName, READONLY, &cStatus)) { 122 cerr << "Failed to open SDFITS file: " << sdName << endl;123 reportError();141 sprintf(cMsg, "ERROR: Failed to open SDFITS file\n %s", sdName); 142 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, cMsg); 124 143 return 1; 125 144 } … … 138 157 cALFA_CIMA = 1; 139 158 159 // Check for later versions of CIMAFITS. 160 float version; 161 readParm("VERSION", TFLOAT, &version); 162 if (version >= 2.0f) cALFA_CIMA = int(version); 163 140 164 } else { 141 cerr << "Failed to locate SDFITS binary table." << endl; 142 reportError(); 165 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to locate SDFITS binary table."); 143 166 close(); 144 167 return 1; … … 148 171 // Arecibo ALFA data of some kind. 149 172 cALFA = 1; 150 for (int iBeam = 0; iBeam < 8; iBeam++) { 151 for (int iPol = 0; iPol < 2; iPol++) { 152 cALFAcalOn[iBeam][iPol] = 0.0f; 153 cALFAcalOff[iBeam][iPol] = 0.0f; 154 155 // Nominal factor to calibrate spectra in Jy. 156 cALFAcal[iBeam][iPol] = 3.0f; 157 } 173 if (sInit) { 174 for (int iBeam = 0; iBeam < 8; iBeam++) { 175 for (int iPol = 0; iPol < 2; iPol++) { 176 sALFAcalOn[iBeam][iPol] = 0.0f; 177 sALFAcalOff[iBeam][iPol] = 0.0f; 178 179 // Nominal factor to calibrate spectra in Jy. 180 sALFAcal[iBeam][iPol] = 3.0f; 181 } 182 } 183 184 sInit = 0; 158 185 } 159 186 } … … 165 192 strncmp(telescope, "NRAO_GBT", 8) == 0; 166 193 167 cRow = 0;168 169 194 170 195 // Check that the DATA array column is present. … … 172 197 haveSpectra = cHaveSpectra = cData[DATA].colnum > 0; 173 198 199 cNAxisTime = 0; 174 200 if (cHaveSpectra) { 175 201 // Find the number of data axes (must be the same for each IF). 176 cNAx is = 5;177 if (readDim(DATA, 1, &cNAx is, cNAxes)) {178 reportError();202 cNAxes = 5; 203 if (readDim(DATA, 1, &cNAxes, cNAxis)) { 204 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 179 205 close(); 180 206 return 1; … … 182 208 183 209 if (cALFA_BD) { 184 // ALFA BDFITS: variable length arrays don't actually vary and there is 210 // ALFA BDFITS: variable length arrays don't actually vary and there is 185 211 // no TDIM (or MAXISn) card; use the LAGS_IN value. 186 cNAx is = 5;187 readParm("LAGS_IN", TLONG, cNAx es);188 cNAx es[1] = 1;189 cNAx es[2] = 1;190 cNAx es[3] = 1;191 cNAx es[4] = 1;192 cData[DATA].nelem = cNAx es[0];193 } 194 195 if (cNAx is < 4) {212 cNAxes = 5; 213 readParm("LAGS_IN", TLONG, cNAxis); 214 cNAxis[1] = 1; 215 cNAxis[2] = 1; 216 cNAxis[3] = 1; 217 cNAxis[4] = 1; 218 cData[DATA].nelem = cNAxis[0]; 219 } 220 221 if (cNAxes < 4) { 196 222 // Need at least four axes (for now). 197 cerr << "DATA array contains fewer than four axes." << endl;223 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array contains fewer than four axes."); 198 224 close(); 199 225 return 1; 200 } else if (cNAx is > 5) {226 } else if (cNAxes > 5) { 201 227 // We support up to five axes. 202 cerr << "DATA array contains more than five axes." << endl;228 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array contains more than five axes."); 203 229 close(); 204 230 return 1; … … 211 237 findData(DATAXED, "DATAXED", TSTRING); 212 238 if (cData[DATAXED].colnum < 0) { 213 cerr << "DATA array column absent from binary table." << endl;239 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array column absent from binary table."); 214 240 close(); 215 241 return 1; … … 220 246 readParm("DATAXED", TSTRING, dataxed); 221 247 222 for (int iaxis = 0; iaxis < 5; iaxis++) cNAx es[iaxis] = 0;223 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAx es, cNAxes+1, cNAxes+2,224 cNAx es+3, cNAxes+4);248 for (int iaxis = 0; iaxis < 5; iaxis++) cNAxis[iaxis] = 0; 249 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAxis, cNAxis+1, cNAxis+2, 250 cNAxis+3, cNAxis+4); 225 251 for (int iaxis = 4; iaxis > -1; iaxis--) { 226 if (cNAx es[iaxis] == 0) cNAxis = iaxis;252 if (cNAxis[iaxis] == 0) cNAxes = iaxis; 227 253 } 228 254 } … … 235 261 // Find required DATA array axes. 236 262 char ctype[5][72]; 237 for (int iaxis = 0; iaxis < cNAx is; iaxis++) {263 for (int iaxis = 0; iaxis < cNAxes; iaxis++) { 238 264 strcpy(ctype[iaxis], ""); 239 265 readParm(CTYPE[iaxis], TSTRING, ctype[iaxis]); // Core. … … 241 267 242 268 if (cStatus) { 243 reportError();269 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 244 270 close(); 245 271 return 1; 246 272 } 247 273 248 char *fqCRPIX = 0;249 274 char *fqCRVAL = 0; 250 275 char *fqCDELT = 0; 276 char *fqCRPIX = 0; 251 277 char *raCRVAL = 0; 252 278 char *decCRVAL = 0; 253 279 char *timeCRVAL = 0; 280 char *timeCDELT = 0; 281 char *timeCRPIX = 0; 254 282 char *beamCRVAL = 0; 255 256 for (int iaxis = 0; iaxis < cNAxis; iaxis++) { 283 char *polCRVAL = 0; 284 285 cFreqAxis = -1; 286 cStokesAxis = -1; 287 cRaAxis = -1; 288 cDecAxis = -1; 289 cTimeAxis = -1; 290 cBeamAxis = -1; 291 292 for (int iaxis = 0; iaxis < cNAxes; iaxis++) { 257 293 if (strncmp(ctype[iaxis], "FREQ", 4) == 0) { 258 c Reqax[0]= iaxis;259 fqCR PIX = CRPIX[iaxis];260 fqC RVAL = CRVAL[iaxis];261 fqC DELT = CDELT[iaxis];294 cFreqAxis = iaxis; 295 fqCRVAL = CRVAL[iaxis]; 296 fqCDELT = CDELT[iaxis]; 297 fqCRPIX = CRPIX[iaxis]; 262 298 263 299 } else if (strncmp(ctype[iaxis], "STOKES", 6) == 0) { 264 cReqax[1] = iaxis; 300 cStokesAxis = iaxis; 301 polCRVAL = CRVAL[iaxis]; 265 302 266 303 } else if (strncmp(ctype[iaxis], "RA", 2) == 0) { 267 cR eqax[2]= iaxis;268 raCRVAL = CRVAL[iaxis];304 cRaAxis = iaxis; 305 raCRVAL = CRVAL[iaxis]; 269 306 270 307 } else if (strncmp(ctype[iaxis], "DEC", 3) == 0) { 271 c Reqax[3]= iaxis;272 decCRVAL = CRVAL[iaxis];308 cDecAxis = iaxis; 309 decCRVAL = CRVAL[iaxis]; 273 310 274 311 } else if (strcmp(ctype[iaxis], "TIME") == 0) { 275 // TIME (UTC seconds since midnight) can be a keyword or axis type. 312 // TIME (UTC seconds since midnight); axis type, if present, takes 313 // precedence over keyword. 314 cTimeAxis = iaxis; 276 315 timeCRVAL = CRVAL[iaxis]; 316 317 // Check for non-degeneracy. 318 if ((cNAxisTime = cNAxis[iaxis]) > 1) { 319 timeCDELT = CDELT[iaxis]; 320 timeCRPIX = CRPIX[iaxis]; 321 sprintf(cMsg, "DATA array contains a TIME axis of length %ld.", 322 cNAxisTime); 323 //logMsg(cMsg); 324 log(LogOrigin( className, methodName, WHERE ), LogIO::NORMAL, cMsg); 325 } 277 326 278 327 } else if (strcmp(ctype[iaxis], "BEAM") == 0) { 279 328 // BEAM can be a keyword or axis type. 329 cBeamAxis = iaxis; 280 330 beamCRVAL = CRVAL[iaxis]; 281 331 } … … 284 334 if (cALFA_BD) { 285 335 // Fixed in ALFA CIMAFITS. 286 cR eqax[2]= 2;336 cRaAxis = 2; 287 337 raCRVAL = "CRVAL2A"; 288 338 289 c Reqax[3]= 3;339 cDecAxis = 3; 290 340 decCRVAL = "CRVAL3A"; 291 341 } 292 342 293 // Check that all are present. 294 for (int iaxis = 0; iaxis < 4; iaxis++) { 295 if (cReqax[iaxis] < 0) { 296 cerr << "Could not find required DATA array axes." << endl; 297 close(); 298 return 1; 299 } 343 344 // Check that required axes are present. 345 if (cFreqAxis < 0 || cStokesAxis < 0 || cRaAxis < 0 || cDecAxis < 0) { 346 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Could not find required DATA array axes."); 347 close(); 348 return 1; 300 349 } 301 350 … … 304 353 findData(CYCLE, "CYCLE", TINT); // Additional. 305 354 findData(DATE_OBS, "DATE-OBS", TSTRING); // Core. 306 findData(TIME, "TIME", TDOUBLE); // Core. 355 356 if (cTimeAxis >= 0) { 357 // The DATA array has a TIME axis. 358 if (cNAxisTime > 1) { 359 // Non-degenerate. 360 findData(TimeRefVal, timeCRVAL, TDOUBLE); // Time reference value. 361 findData(TimeDelt, timeCDELT, TDOUBLE); // Time increment. 362 findData(TimeRefPix, timeCRPIX, TFLOAT); // Time reference pixel. 363 } else { 364 // Degenerate, treat its like a simple TIME keyword. 365 findData(TIME, timeCRVAL, TDOUBLE); 366 } 367 368 } else { 369 findData(TIME, "TIME", TDOUBLE); // Core. 370 } 371 307 372 findData(EXPOSURE, "EXPOSURE", TFLOAT); // Core. 308 373 findData(OBJECT, "OBJECT", TSTRING); // Core. … … 314 379 findData(BEAM, "BEAM", TSHORT); // Additional. 315 380 findData(IF, "IF", TSHORT); // Additional. 316 findData(FqRefPix, fqCRPIX, TFLOAT); // Frequency reference pixel.317 381 findData(FqRefVal, fqCRVAL, TDOUBLE); // Frequency reference value. 318 382 findData(FqDelt, fqCDELT, TDOUBLE); // Frequency increment. 383 findData(FqRefPix, fqCRPIX, TFLOAT); // Frequency reference pixel. 319 384 findData(RA, raCRVAL, TDOUBLE); // Right ascension. 320 385 findData(DEC, decCRVAL, TDOUBLE); // Declination. … … 343 408 findData(WINDDIRE, "WINDDIRE", TFLOAT); // Shared. 344 409 410 findData(STOKES, polCRVAL, TINT); 411 findData(SIG, "SIG", TSTRING); 412 findData(CAL, "CAL", TSTRING); 413 414 findData(RVSYS, "RVSYS", TDOUBLE); 415 findData(VFRAME, "VFRAME", TDOUBLE); 416 findData(VELDEF, "VELDEF", TSTRING); 417 345 418 if (cStatus) { 346 reportError();419 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 347 420 close(); 348 421 return 1; … … 355 428 cALFAscan = 0; 356 429 cScanNo = 0; 357 if (cALFA_BD) { 430 if (cALFA_CIMA) { 431 findData(SCAN, "SCAN_ID", TINT); 432 if (cALFA_CIMA > 1) { 433 // Note that RECNUM increases by cNAxisTime per row. 434 findData(CYCLE, "RECNUM", TINT); 435 } else { 436 findData(CYCLE, "SUBSCAN", TINT); 437 } 438 } else if (cALFA_BD) { 358 439 findData(SCAN, "SCAN_NUMBER", TINT); 359 440 findData(CYCLE, "PATTERN_NUMBER", TINT); 360 } else if (cALFA_CIMA) {361 findData(SCAN, "SCAN_ID", TINT);362 findData(CYCLE, "SUBSCAN", TINT);363 441 } 364 442 } else { … … 368 446 cCycleNo = 0; 369 447 cLastUTC = 0.0; 448 for ( int i = 0 ; i < 4 ; i++ ) { 449 cGLastUTC[i] = 0.0 ; 450 cGLastScan[i] = -1 ; 451 cGCycleNo[i] = 0 ; 452 } 370 453 371 454 // Beam number, 1-relative by default. 372 455 cBeam_1rel = 1; 373 if (cData[BEAM].colnum < 0) { 456 if (cALFA) { 457 // ALFA INPUT_ID, 0-relative (overrides BEAM column if present). 458 findData(BEAM, "INPUT_ID", TSHORT); 459 cBeam_1rel = 0; 460 461 } else if (cData[BEAM].colnum < 0) { 374 462 if (beamCRVAL) { 375 463 // There is a BEAM axis. 376 464 findData(BEAM, beamCRVAL, TDOUBLE); 377 378 465 } else { 379 if (cALFA) { 380 // ALFA data, 0-relative. 381 findData(BEAM, "INPUT_ID", TSHORT); 382 } else { 383 // ms2sdfits output, 0-relative "feed" number. 384 findData(BEAM, "MAIN_FEED1", TSHORT); 385 } 386 466 // ms2sdfits output, 0-relative "feed" number. 467 findData(BEAM, "MAIN_FEED1", TSHORT); 387 468 cBeam_1rel = 0; 388 469 } … … 393 474 if (cALFA && cData[IF].colnum < 0) { 394 475 // ALFA data, 0-relative. 395 findData(IF, "IFVAL", TSHORT); 476 if (cALFA_CIMA > 1) { 477 findData(IF, "IFN", TSHORT); 478 } else { 479 findData(IF, "IFVAL", TSHORT); 480 } 396 481 cIF_1rel = 0; 397 }398 399 if (cData[TIME].colnum < 0) {400 if (timeCRVAL) {401 // There is a TIME axis.402 findData(TIME, timeCRVAL, TDOUBLE);403 }404 482 } 405 483 … … 476 554 fits_get_num_rows(cSDptr, &cNRow, &cStatus); 477 555 if (!cNRow) { 478 cerr << "Table contains no entries." << endl;556 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Table contains no entries."); 479 557 close(); 480 558 return 1; … … 489 567 if (fits_read_col(cSDptr, TSHORT, cData[BEAM].colnum, 1, 1, cNRow, 490 568 &beamNul, beamCol, &anynul, &cStatus)) { 491 reportError();492 569 delete [] beamCol; 570 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 493 571 close(); 494 572 return 1; … … 504 582 // Check validity. 505 583 if (beamCol[irow] < cBeam_1rel) { 506 cerr << "SDFITS file contains invalid beam number." << endl;507 584 delete [] beamCol; 585 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "SDFITS file contains invalid beam number."); 508 586 close(); 509 587 return 1; … … 545 623 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 546 624 &IFNul, IFCol, &anynul, &cStatus)) { 547 reportError();548 625 delete [] IFCol; 626 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 549 627 close(); 550 628 return 1; … … 560 638 // Check validity. 561 639 if (IFCol[irow] < cIF_1rel) { 562 cerr << "SDFITS file contains invalid IF number." << endl;563 640 delete [] IFCol; 641 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "SDFITS file contains invalid IF number."); 564 642 close(); 565 643 return 1; … … 592 670 if (cData[DATA].nelem < 0) { 593 671 // Variable dimension array. 594 if (readDim(DATA, irow+1, &cNAx is, cNAxes)) {595 reportError();672 if (readDim(DATA, irow+1, &cNAxes, cNAxis)) { 673 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 596 674 close(); 597 675 return 1; … … 604 682 readParm("DATAXED", TSTRING, dataxed); 605 683 606 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAx es, cNAxes+1,607 cNAx es+2, cNAxes+3, cNAxes+4);684 sscanf(dataxed, "(%ld,%ld,%ld,%ld,%ld)", cNAxis, cNAxis+1, 685 cNAxis+2, cNAxis+3, cNAxis+4); 608 686 } 609 687 } 610 688 611 689 // Number of channels and polarizations. 612 cNChan[iIF] = cNAx es[cReqax[0]];613 cNPol[iIF] = cNAx es[cReqax[1]];690 cNChan[iIF] = cNAxis[cFreqAxis]; 691 cNPol[iIF] = cNAxis[cStokesAxis]; 614 692 cHaveXPol[iIF] = 0; 615 693 … … 621 699 622 700 if (readDim(XPOLDATA, irow+1, &nAxis, nAxes)) { 623 reportError();701 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE ); 624 702 close(); 625 703 return 1; … … 650 728 651 729 // Number of channels and polarizations. 652 cNChan[0] = cNAx es[cReqax[0]];653 cNPol[0] = cNAx es[cReqax[1]];730 cNChan[0] = cNAxis[cFreqAxis]; 731 cNPol[0] = cNAxis[cStokesAxis]; 654 732 cHaveXPol[0] = 0; 655 733 } 656 734 657 if (cALFA ) {658 // ALFAlabels each polarization as a separate IF.735 if (cALFA && cALFA_CIMA < 2) { 736 // Older ALFA data labels each polarization as a separate IF. 659 737 cNPol[0] = cNIF; 660 738 cNIF = 1; 739 } 740 741 // For GBT data that stores spectra for each polarization in separate rows 742 if ( cData[STOKES].colnum > 0 ) { 743 int *stokesCol = new int[cNRow]; 744 int stokesNul = 1; 745 int anynul; 746 if (fits_read_col(cSDptr, TINT, cData[STOKES].colnum, 1, 1, cNRow, 747 &stokesNul, stokesCol, &anynul, &cStatus)) { 748 delete [] stokesCol; 749 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 750 close(); 751 return 1; 752 } 753 754 vector<int> pols ; 755 pols.push_back( stokesCol[0] ) ; 756 for ( int i = 0 ; i < cNRow ; i++ ) { 757 bool pmatch = false ; 758 for ( uint j = 0 ; j < pols.size() ; j++ ) { 759 if ( stokesCol[i] == pols[j] ) { 760 pmatch = true ; 761 break ; 762 } 763 } 764 if ( !pmatch ) { 765 pols.push_back( stokesCol[i] ) ; 766 } 767 } 768 769 cPols = new int[pols.size()] ; 770 for ( uint i = 0 ; i < pols.size() ; i++ ) { 771 cPols[i] = pols[i] ; 772 } 773 774 for ( int i = 0 ; i < cNIF ; i++ ) { 775 cNPol[i] = pols.size() ; 776 } 777 778 delete [] stokesCol ; 661 779 } 662 780 … … 712 830 extraSysCal = cExtraSysCal; 713 831 832 833 // Extras for ALFA data. 834 cALFAacc = 0.0f; 835 if (cALFA_CIMA > 1) { 836 // FFTs per second when the Mock correlator operates in RFI blanking mode. 837 readData("PHFFTACC", TFLOAT, 0, &cALFAacc); 838 } 839 840 841 cRow = 0; 842 cTimeIdx = cNAxisTime; 843 714 844 return 0; 715 845 } … … 725 855 double antPos[3], 726 856 char obsMode[32], 857 char bunit[32], 727 858 float &equinox, 728 859 char radecsys[32], … … 733 864 double &bandwidth) 734 865 { 866 const string methodName = "getHeader()" ; 867 735 868 // Has the file been opened? 736 869 if (!cSDptr) { … … 773 906 readData(OBSMODE, 1, obsMode); // Shared. 774 907 908 // Brightness unit. 909 if (cData[DATAXED].colnum >= 0) { 910 strcpy(bunit, "Jy"); 911 } else { 912 strcpy(bunit, cData[DATA].units); 913 } 914 915 if (strcmp(bunit, "JY") == 0) { 916 bunit[1] = 'y'; 917 } else if (strcmp(bunit, "JY/BEAM") == 0) { 918 strcpy(bunit, "Jy/beam"); 919 } 920 775 921 readParm("EQUINOX", TFLOAT, &equinox); // Shared. 776 922 if (cStatus == 405) { … … 793 939 794 940 // Look for VELFRAME, written by earlier versions of Livedata. 941 // 942 // Added few more codes currently (as of 2009 Oct) used in the GBT 943 // SDFITS (based io_sdfits_define.pro of GBTIDL). - TT 795 944 if (readParm("VELFRAME", TSTRING, dopplerFrame)) { // Additional. 796 945 // No, try digging it out of the CTYPE card (AIPS convention). 797 946 char keyw[9], ctype[9]; 798 sprintf(keyw, "CTYPE%ld", c Reqax[0]+1);947 sprintf(keyw, "CTYPE%ld", cFreqAxis+1); 799 948 readParm(keyw, TSTRING, ctype); 800 949 … … 804 953 // LSR unqualified usually means LSR (kinematic). 805 954 strcpy(dopplerFrame, "LSRK"); 955 } else if (strcmp(dopplerFrame, "LSD") == 0) { 956 // LSR as a dynamical defintion 957 strcpy(dopplerFrame, "LSRD"); 806 958 } else if (strcmp(dopplerFrame, "HEL") == 0) { 807 959 // Almost certainly barycentric. 808 960 strcpy(dopplerFrame, "BARYCENT"); 961 } else if (strcmp(dopplerFrame, "BAR") == 0) { 962 // barycentric. 963 strcpy(dopplerFrame, "BARYCENT"); 964 } else if (strcmp(dopplerFrame, "OBS") == 0) { 965 // observed or topocentric. 966 strcpy(dopplerFrame, "TOPO"); 967 } else if (strcmp(dopplerFrame, "GEO") == 0) { 968 // geocentric 969 strcpy(dopplerFrame, "GEO"); 970 } else if (strcmp(dopplerFrame, "GAL") == 0) { 971 // galactic 972 strcpy(dopplerFrame, "GAL"); 973 } else if (strcmp(dopplerFrame, "LGR") == 0) { 974 // Local group 975 strcpy(dopplerFrame, "LGROUP"); 976 } else if (strcmp(dopplerFrame, "CMB") == 0) { 977 // Cosimic Microwave Backgroup 978 strcpy(dopplerFrame, "CMB"); 809 979 } 810 980 } else { … … 812 982 } 813 983 } 814 815 984 // Translate to FITS standard names. 816 985 if (strncmp(dopplerFrame, "TOP", 3) == 0) { … … 822 991 } else if (strncmp(dopplerFrame, "BARY", 4) == 0) { 823 992 strcpy(dopplerFrame, "BARYCENT"); 824 } 825 } 826 993 } else if (strncmp(dopplerFrame, "GAL", 3) == 0) { 994 strcpy(dopplerFrame, "GALACTOC"); 995 } else if (strncmp(dopplerFrame, "LGROUP", 6) == 0) { 996 strcpy(dopplerFrame, "LOCALGRP"); 997 } else if (strncmp(dopplerFrame, "CMB", 3) == 0) { 998 strcpy(dopplerFrame, "CMBDIPOL"); 999 } 1000 } 1001 827 1002 if (cStatus) { 828 reportError();1003 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 829 1004 return 1; 830 1005 } 831 1006 832 1007 // Get parameters from first row of table. 833 readData(DATE_OBS, 1, datobs); 834 readData(TIME, 1, &utc); 1008 readTime(1, 1, datobs, utc); 835 1009 readData(FqRefVal, 1, &refFreq); 836 1010 readParm("BANDWID", TDOUBLE, &bandwidth); // Core. 837 1011 838 if (cALFA_BD) utc *= 3600.0;839 840 1012 if (cStatus) { 841 reportError();1013 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 842 1014 return 1; 843 }844 845 // Check DATE-OBS format.846 if (datobs[2] == '/') {847 // Translate an old-format DATE-OBS.848 datobs[9] = datobs[1];849 datobs[8] = datobs[0];850 datobs[2] = datobs[6];851 datobs[5] = datobs[3];852 datobs[3] = datobs[7];853 datobs[6] = datobs[4];854 datobs[7] = '-';855 datobs[4] = '-';856 datobs[1] = '9';857 datobs[0] = '1';858 datobs[10] = '\0';859 860 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) {861 // Dig UTC out of a new-format DATE-OBS.862 int hh, mm;863 float ss;864 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss);865 utc = (hh*60 + mm)*60 + ss;866 datobs[10] = '\0';867 1015 } 868 1016 … … 879 1027 double* &endFreq) 880 1028 { 1029 const string methodName = "getFreqInfo()" ; 1030 881 1031 float fqRefPix; 882 1032 double fqDelt, fqRefVal; … … 892 1042 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 893 1043 &IFNul, IFCol, &anynul, &cStatus)) { 894 reportError();895 1044 delete [] IFCol; 1045 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 896 1046 close(); 897 1047 return 1; … … 956 1106 double* &positions) 957 1107 { 958 int anynul;1108 const string methodName = "findRange()" ; 959 1109 960 1110 // Has the file been opened? … … 966 1116 967 1117 // Find the number of rows selected. 968 short *sel = new short[ nRow];969 for (int irow = 0; irow < nRow; irow++) {1118 short *sel = new short[cNRow]; 1119 for (int irow = 0; irow < cNRow; irow++) { 970 1120 sel[irow] = 1; 971 1121 } 972 1122 1123 int anynul; 973 1124 if (cData[BEAM].colnum > 0) { 974 1125 short *beamCol = new short[cNRow]; … … 976 1127 if (fits_read_col(cSDptr, TSHORT, cData[BEAM].colnum, 1, 1, cNRow, 977 1128 &beamNul, beamCol, &anynul, &cStatus)) { 978 reportError();979 1129 delete [] beamCol; 980 1130 delete [] sel; 1131 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 981 1132 return 1; 982 1133 } 983 1134 984 for (int irow = 0; irow < nRow; irow++) {1135 for (int irow = 0; irow < cNRow; irow++) { 985 1136 if (!cBeams[beamCol[irow]-cBeam_1rel]) { 986 1137 sel[irow] = 0; … … 996 1147 if (fits_read_col(cSDptr, TSHORT, cData[IF].colnum, 1, 1, cNRow, 997 1148 &IFNul, IFCol, &anynul, &cStatus)) { 998 reportError();999 1149 delete [] IFCol; 1000 1150 delete [] sel; 1151 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1001 1152 return 1; 1002 1153 } 1003 1154 1004 for (int irow = 0; irow < nRow; irow++) {1155 for (int irow = 0; irow < cNRow; irow++) { 1005 1156 if (!cIFs[IFCol[irow]-cIF_1rel]) { 1006 1157 sel[irow] = 0; … … 1012 1163 1013 1164 nSel = 0; 1014 for (int irow = 0; irow < nRow; irow++) {1165 for (int irow = 0; irow < cNRow; irow++) { 1015 1166 nSel += sel[irow]; 1016 1167 } … … 1018 1169 1019 1170 // Find the time range assuming the data is in chronological order. 1020 readData(DATE_OBS, 1, dateSpan[0]); 1021 readData(DATE_OBS, nRow, dateSpan[1]); 1022 readData(TIME, 1, utcSpan); 1023 readData(TIME, nRow, utcSpan+1); 1024 1025 if (cALFA_BD) { 1026 utcSpan[0] *= 3600.0; 1027 utcSpan[1] *= 3600.0; 1028 } 1029 1030 // Check DATE-OBS format. 1031 for (int i = 0; i < 2; i++) { 1032 if (dateSpan[0][2] == '/') { 1033 // Translate an old-format DATE-OBS. 1034 dateSpan[i][9] = dateSpan[i][1]; 1035 dateSpan[i][8] = dateSpan[i][0]; 1036 dateSpan[i][2] = dateSpan[i][6]; 1037 dateSpan[i][5] = dateSpan[i][3]; 1038 dateSpan[i][3] = dateSpan[i][7]; 1039 dateSpan[i][6] = dateSpan[i][4]; 1040 dateSpan[i][7] = '-'; 1041 dateSpan[i][4] = '-'; 1042 dateSpan[i][1] = '9'; 1043 dateSpan[i][0] = '1'; 1044 dateSpan[i][10] = '\0'; 1045 } 1046 1047 if (dateSpan[i][10] == 'T' && cData[TIME].colnum < 0) { 1048 // Dig UTC out of a new-format DATE-OBS. 1049 int hh, mm; 1050 float ss; 1051 sscanf(dateSpan[i]+11, "%d:%d:%f", &hh, &mm, &ss); 1052 utcSpan[i] = (hh*60 + mm)*60 + ss; 1053 } 1054 } 1171 readTime(1, 1, dateSpan[0], utcSpan[0]); 1172 readTime(cNRow, cNAxisTime, dateSpan[1], utcSpan[1]); 1055 1173 1056 1174 1057 1175 // Retrieve positions for selected data. 1058 double *ra = new double[cNRow];1059 double *dec = new double[cNRow];1060 fits_read_col(cSDptr, TDOUBLE, cData[RA].colnum, 1, 1, nRow, 0, ra,1061 &anynul, &cStatus);1062 fits_read_col(cSDptr, TDOUBLE, cData[DEC].colnum, 1, 1, nRow, 0, dec,1063 &anynul, &cStatus);1064 1065 if (cALFA_BD) {1066 for (int irow = 0; irow < nRow; irow++) {1067 // Convert hours to degrees.1068 ra[irow] *= 15.0;1069 }1070 }1071 1072 1176 int isel = 0; 1073 1177 positions = new double[2*nSel]; 1074 1178 1075 // Parameters needed to compute feed-plane coordinates. 1076 double *srcRA, *srcDec; 1077 float *par, *rot; 1078 if (cGetFeedPos) { 1079 srcRA = new double[cNRow]; 1080 srcDec = new double[cNRow]; 1081 par = new float[cNRow]; 1082 rot = new float[cNRow]; 1083 fits_read_col(cSDptr, TDOUBLE, cData[OBJ_RA].colnum, 1, 1, nRow, 0, 1084 srcRA, &anynul, &cStatus); 1085 fits_read_col(cSDptr, TDOUBLE, cData[OBJ_DEC].colnum, 1, 1, nRow, 0, 1086 srcDec, &anynul, &cStatus); 1087 fits_read_col(cSDptr, TFLOAT, cData[PARANGLE].colnum, 1, 1, nRow, 0, 1088 par, &anynul, &cStatus); 1089 fits_read_col(cSDptr, TFLOAT, cData[FOCUSROT].colnum, 1, 1, nRow, 0, 1090 rot, &anynul, &cStatus); 1091 1092 for (int irow = 0; irow < nRow; irow++) { 1093 if (sel[irow]) { 1094 // Convert to feed-plane coordinates. 1095 Double dist, pa; 1096 distPA(ra[irow]*D2R, dec[irow]*D2R, srcRA[irow]*D2R, srcDec[irow]*D2R, 1097 dist, pa); 1098 1099 Double spin = (par[irow] + rot[irow])*D2R - pa + PI; 1100 if (spin > 2.0*PI) spin -= 2.0*PI; 1101 Double squint = PI/2.0 - dist; 1102 1103 positions[isel++] = spin; 1104 positions[isel++] = squint; 1105 } 1106 } 1107 1108 delete [] srcRA; 1109 delete [] srcDec; 1110 delete [] par; 1111 delete [] rot; 1179 if (cCoordSys == 1) { 1180 // Horizontal (Az,El). 1181 if (cData[AZIMUTH].colnum < 0 || 1182 cData[ELEVATIO].colnum < 0) { 1183 log(LogOrigin( className, methodName, WHERE ), LogIO::WARN, "Azimuth/elevation information absent."); 1184 cStatus = -1; 1185 1186 } else { 1187 float *az = new float[cNRow]; 1188 float *el = new float[cNRow]; 1189 readCol(AZIMUTH, az); 1190 readCol(ELEVATIO, el); 1191 1192 if (!cStatus) { 1193 for (int irow = 0; irow < cNRow; irow++) { 1194 if (sel[irow]) { 1195 positions[isel++] = az[irow] * D2R; 1196 positions[isel++] = el[irow] * D2R; 1197 } 1198 } 1199 } 1200 1201 delete [] az; 1202 delete [] el; 1203 } 1204 1205 } else if (cCoordSys == 3) { 1206 // ZPA-EL. 1207 if (cData[BEAM].colnum < 0 || 1208 cData[FOCUSROT].colnum < 0 || 1209 cData[ELEVATIO].colnum < 0) { 1210 log(LogOrigin( className, methodName, WHERE ), LogIO::WARN, "ZPA/elevation information absent."); 1211 cStatus = -1; 1212 1213 } else { 1214 short *beam = new short[cNRow]; 1215 float *rot = new float[cNRow]; 1216 float *el = new float[cNRow]; 1217 readCol(BEAM, beam); 1218 readCol(FOCUSROT, rot); 1219 readCol(ELEVATIO, el); 1220 1221 if (!cStatus) { 1222 for (int irow = 0; irow < cNRow; irow++) { 1223 if (sel[irow]) { 1224 Int beamNo = beam[irow]; 1225 Double zpa = rot[irow]; 1226 if (beamNo > 1) { 1227 // Beam geometry for the Parkes multibeam. 1228 if (beamNo < 8) { 1229 zpa += -60.0 + 60.0*(beamNo-2); 1230 } else { 1231 zpa += -90.0 + 60.0*(beamNo-8); 1232 } 1233 1234 if (zpa < -180.0) { 1235 zpa += 360.0; 1236 } else if (zpa > 180.0) { 1237 zpa -= 360.0; 1238 } 1239 } 1240 1241 positions[isel++] = zpa * D2R; 1242 positions[isel++] = el[irow] * D2R; 1243 } 1244 } 1245 } 1246 1247 delete [] beam; 1248 delete [] rot; 1249 delete [] el; 1250 } 1112 1251 1113 1252 } else { 1114 for (int irow = 0; irow < nRow; irow++) { 1115 if (sel[irow]) { 1116 positions[isel++] = ra[irow] * D2R; 1117 positions[isel++] = dec[irow] * D2R; 1118 } 1119 } 1120 } 1121 1253 double *ra = new double[cNRow]; 1254 double *dec = new double[cNRow]; 1255 readCol(RA, ra); 1256 readCol(DEC, dec); 1257 1258 if (cStatus) { 1259 delete [] ra; 1260 delete [] dec; 1261 goto cleanup; 1262 } 1263 1264 if (cALFA_BD) { 1265 for (int irow = 0; irow < cNRow; irow++) { 1266 // Convert hours to degrees. 1267 ra[irow] *= 15.0; 1268 } 1269 } 1270 1271 if (cCoordSys == 0) { 1272 // Equatorial (RA,Dec). 1273 for (int irow = 0; irow < cNRow; irow++) { 1274 if (sel[irow]) { 1275 positions[isel++] = ra[irow] * D2R; 1276 positions[isel++] = dec[irow] * D2R; 1277 } 1278 } 1279 1280 } else if (cCoordSys == 2) { 1281 // Feed-plane. 1282 if (cData[OBJ_RA].colnum < 0 || 1283 cData[OBJ_DEC].colnum < 0 || 1284 cData[PARANGLE].colnum < 0 || 1285 cData[FOCUSROT].colnum < 0) { 1286 log( LogOrigin( className, methodName, WHERE ), LogIO::WARN, 1287 "Insufficient information to compute feed-plane\n" 1288 " coordinates."); 1289 cStatus = -1; 1290 1291 } else { 1292 double *srcRA = new double[cNRow]; 1293 double *srcDec = new double[cNRow]; 1294 float *par = new float[cNRow]; 1295 float *rot = new float[cNRow]; 1296 1297 readCol(OBJ_RA, srcRA); 1298 readCol(OBJ_DEC, srcDec); 1299 readCol(PARANGLE, par); 1300 readCol(FOCUSROT, rot); 1301 1302 if (!cStatus) { 1303 for (int irow = 0; irow < cNRow; irow++) { 1304 if (sel[irow]) { 1305 // Convert to feed-plane coordinates. 1306 Double dist, pa; 1307 distPA(ra[irow]*D2R, dec[irow]*D2R, srcRA[irow]*D2R, 1308 srcDec[irow]*D2R, dist, pa); 1309 1310 Double spin = (par[irow] + rot[irow])*D2R - pa; 1311 if (spin > 2.0*PI) spin -= 2.0*PI; 1312 Double squint = PI/2.0 - dist; 1313 1314 positions[isel++] = spin; 1315 positions[isel++] = squint; 1316 } 1317 } 1318 } 1319 1320 delete [] srcRA; 1321 delete [] srcDec; 1322 delete [] par; 1323 delete [] rot; 1324 } 1325 } 1326 1327 delete [] ra; 1328 delete [] dec; 1329 } 1330 1331 cleanup: 1122 1332 delete [] sel; 1123 delete [] ra; 1124 delete [] dec; 1125 1126 return cStatus; 1333 1334 if (cStatus) { 1335 nSel = 0; 1336 delete [] positions; 1337 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1338 cStatus = 0; 1339 return 1; 1340 } 1341 1342 return 0; 1127 1343 } 1128 1344 … … 1133 1349 1134 1350 int SDFITSreader::read( 1135 PKSMBrecord &mbrec)1351 MBrecord &mbrec) 1136 1352 { 1353 const string methodName = "read()" ; 1354 1137 1355 // Has the file been opened? 1138 1356 if (!cSDptr) { 1139 1357 return 1; 1140 1358 } 1141 1142 1359 // Find the next selected beam and IF. 1143 1360 short iBeam = 0, iIF = 0; 1144 while (++cRow <= cNRow) { 1361 int iPol = -1 ; 1362 while (1) { 1363 if (++cTimeIdx > cNAxisTime) { 1364 if (++cRow > cNRow) break; 1365 cTimeIdx = 1; 1366 } 1367 1145 1368 if (cData[BEAM].colnum > 0) { 1146 1369 readData(BEAM, cRow, &iBeam); … … 1164 1387 char chars[32]; 1165 1388 readData(OBSMODE, cRow, chars); 1166 if (strcmp(chars, "CAL") == 0) { 1167 // iIF is really the polarization in ALFA data. 1168 alfaCal(iBeam, iIF); 1389 if (strcmp(chars, "DROP") == 0) { 1390 // Completely flagged integration. 1169 1391 continue; 1392 1393 } else if (strcmp(chars, "CAL") == 0) { 1394 sReset = 1; 1395 if (cALFA_CIMA > 1) { 1396 for (short iPol = 0; iPol < cNPol[iIF]; iPol++) { 1397 alfaCal(iBeam, iIF, iPol); 1398 } 1399 continue; 1400 } else { 1401 // iIF is really the polarization in older ALFA data. 1402 alfaCal(iBeam, 0, iIF); 1403 continue; 1404 } 1405 1406 } else { 1407 // Reset for the next CAL record. 1408 if (sReset) { 1409 for (short iPol = 0; iPol < cNPol[iIF]; iPol++) { 1410 sALFAcalNon[iBeam][iPol] = 0; 1411 sALFAcalNoff[iBeam][iPol] = 0; 1412 sALFAcalOn[iBeam][iPol] = 0.0f; 1413 sALFAcalOff[iBeam][iPol] = 0.0f; 1414 } 1415 sReset = 0; 1416 1417 sprintf(cMsg, "ALFA cal factors for beam %d: %.3e, %.3e", 1418 iBeam+1, sALFAcal[iBeam][0], sALFAcal[iBeam][1]); 1419 log(LogOrigin( className, methodName, WHERE ), LogIO::NORMAL, cMsg); 1420 //logMsg(cMsg); 1421 } 1170 1422 } 1171 1423 } 1172 1424 1425 // for GBT SDFITS 1426 if (cData[STOKES].colnum > 0 ) { 1427 readData(STOKES, cRow, &iPol ) ; 1428 for ( int i = 0 ; i < cNPol[iIF] ; i++ ) { 1429 if ( cPols[i] == iPol ) { 1430 iPol = i ; 1431 break ; 1432 } 1433 } 1434 } 1173 1435 break; 1174 1436 } … … 1200 1462 // Times. 1201 1463 char datobs[32]; 1202 readData(DATE_OBS, cRow, datobs); 1203 readData(TIME, cRow, &mbrec.utc); 1204 if (cALFA_BD) mbrec.utc *= 3600.0; 1205 1206 if (datobs[2] == '/') { 1207 // Translate an old-format DATE-OBS. 1208 datobs[9] = datobs[1]; 1209 datobs[8] = datobs[0]; 1210 datobs[2] = datobs[6]; 1211 datobs[5] = datobs[3]; 1212 datobs[3] = datobs[7]; 1213 datobs[6] = datobs[4]; 1214 datobs[7] = '-'; 1215 datobs[4] = '-'; 1216 datobs[1] = '9'; 1217 datobs[0] = '1'; 1218 1219 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) { 1220 // Dig UTC out of a new-format DATE-OBS. 1221 int hh, mm; 1222 float ss; 1223 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss); 1224 mbrec.utc = (hh*60 + mm)*60 + ss; 1225 } 1226 1227 datobs[10] = '\0'; 1464 readTime(cRow, cTimeIdx, datobs, mbrec.utc); 1228 1465 strcpy(mbrec.datobs, datobs); 1229 1466 1230 1467 if (cData[CYCLE].colnum > 0) { 1231 1468 readData(CYCLE, cRow, &mbrec.cycleNo); 1469 mbrec.cycleNo += cTimeIdx - 1; 1232 1470 if (cALFA_BD) mbrec.cycleNo++; 1233 1471 } else { … … 1239 1477 } 1240 1478 1479 if ( iPol != -1 ) { 1480 if ( mbrec.scanNo != cGLastScan[iPol] ) { 1481 cGLastScan[iPol] = mbrec.scanNo ; 1482 cGCycleNo[iPol] = 0 ; 1483 mbrec.cycleNo = ++cGCycleNo[iPol] ; 1484 } 1485 else { 1486 mbrec.cycleNo = ++cGCycleNo[iPol] ; 1487 } 1488 } 1489 1241 1490 readData(EXPOSURE, cRow, &mbrec.exposure); 1242 1491 1243 1492 // Source identification. 1244 readData(OBJECT, cRow, mbrec.srcName); 1493 readData(OBJECT, cRow, mbrec.srcName); 1494 1495 if ( iPol != -1 ) { 1496 char obsmode[32] ; 1497 readData( OBSMODE, cRow, obsmode ) ; 1498 char sig[1] ; 1499 char cal[1] ; 1500 readData( SIG, cRow, sig ) ; 1501 readData( CAL, cRow, cal ) ; 1502 if ( strstr( obsmode, "PSWITCH" ) != NULL ) { 1503 // position switch 1504 strcat( mbrec.srcName, "_p" ) ; 1505 if ( strstr( obsmode, "PSWITCHON" ) != NULL ) { 1506 strcat( mbrec.srcName, "s" ) ; 1507 } 1508 else if ( strstr( obsmode, "PSWITCHOFF" ) != NULL ) { 1509 strcat( mbrec.srcName, "r" ) ; 1510 } 1511 } 1512 else if ( strstr( obsmode, "Nod" ) != NULL ) { 1513 // nod 1514 strcat( mbrec.srcName, "_n" ) ; 1515 if ( sig[0] == 'T' ) { 1516 strcat( mbrec.srcName, "s" ) ; 1517 } 1518 else { 1519 strcat( mbrec.srcName, "r" ) ; 1520 } 1521 } 1522 else if ( strstr( obsmode, "FSWITCH" ) != NULL ) { 1523 // frequency switch 1524 strcat( mbrec.srcName, "_f" ) ; 1525 if ( sig[0] == 'T' ) { 1526 strcat( mbrec.srcName, "s" ) ; 1527 } 1528 else { 1529 strcat( mbrec.srcName, "r" ) ; 1530 } 1531 } 1532 if ( cal[0] == 'T' ) { 1533 strcat( mbrec.srcName, "c" ) ; 1534 } 1535 else { 1536 strcat( mbrec.srcName, "o" ) ; 1537 } 1538 } 1245 1539 1246 1540 readData(OBJ_RA, cRow, &mbrec.srcRA); … … 1279 1573 mbrec.decRate = scanrate[1] * D2R; 1280 1574 } 1575 mbrec.paRate = 0.0f; 1281 1576 1282 1577 // IF-dependent parameters. … … 1289 1584 int nPol = cNPol[iIF]; 1290 1585 1586 if ( cData[STOKES].colnum > 0 ) 1587 nPol = 1 ; 1588 1291 1589 if (cGetSpectra || cGetXPol) { 1292 1590 int nxpol = cGetXPol ? 2*nChan : 0; … … 1298 1596 mbrec.nChan[0] = nChan; 1299 1597 mbrec.nPol[0] = nPol; 1598 mbrec.polNo = iPol ; 1300 1599 1301 1600 readData(FqRefPix, cRow, mbrec.fqRefPix); … … 1316 1615 1317 1616 if (cStatus) { 1318 reportError();1617 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1319 1618 return 1; 1320 1619 } … … 1353 1652 1354 1653 if (cStatus) { 1355 reportError();1654 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1356 1655 return 1; 1357 1656 } 1358 1657 1359 1658 // Read data, sectioning and transposing it in the process. 1360 long *blc = new long[cNAx is+1];1361 long *trc = new long[cNAx is+1];1362 long *inc = new long[cNAx is+1];1363 for (int iaxis = 0; iaxis <= cNAx is; iaxis++) {1659 long *blc = new long[cNAxes+1]; 1660 long *trc = new long[cNAxes+1]; 1661 long *inc = new long[cNAxes+1]; 1662 for (int iaxis = 0; iaxis <= cNAxes; iaxis++) { 1364 1663 blc[iaxis] = 1; 1365 1664 trc[iaxis] = 1; … … 1367 1666 } 1368 1667 1369 blc[cReqax[0]] = std::min(startChan, endChan); 1370 trc[cReqax[0]] = std::max(startChan, endChan); 1371 blc[cNAxis] = cRow; 1372 trc[cNAxis] = cRow; 1668 blc[cFreqAxis] = std::min(startChan, endChan); 1669 trc[cFreqAxis] = std::max(startChan, endChan); 1670 if (cTimeAxis >= 0) { 1671 blc[cTimeAxis] = cTimeIdx; 1672 trc[cTimeAxis] = cTimeIdx; 1673 } 1674 blc[cNAxes] = cRow; 1675 trc[cNAxes] = cRow; 1373 1676 1374 1677 mbrec.haveSpectra = cGetSpectra; … … 1376 1679 int anynul; 1377 1680 1378 for (int i pol = 0; ipol < nPol; ipol++) {1379 blc[c Reqax[1]] = ipol+1;1380 trc[c Reqax[1]] = ipol+1;1381 1382 if (cALFA ) {1681 for (int iPol = 0; iPol < nPol; iPol++) { 1682 blc[cStokesAxis] = iPol+1; 1683 trc[cStokesAxis] = iPol+1; 1684 1685 if (cALFA && cALFA_CIMA < 2) { 1383 1686 // ALFA data: polarizations are stored in successive rows. 1384 blc[c Reqax[1]] = 1;1385 trc[c Reqax[1]] = 1;1386 1387 if (i pol) {1687 blc[cStokesAxis] = 1; 1688 trc[cStokesAxis] = 1; 1689 1690 if (iPol) { 1388 1691 if (++cRow > cNRow) { 1389 1692 return -1; 1390 1693 } 1391 1694 1392 blc[cNAx is] = cRow;1393 trc[cNAx is] = cRow;1695 blc[cNAxes] = cRow; 1696 trc[cNAxes] = cRow; 1394 1697 } 1395 1698 1396 1699 } else if (cData[DATA].nelem < 0) { 1397 1700 // Variable dimension array; get axis lengths. 1398 int naxis = 5, status;1399 1400 if ((status = readDim(DATA, cRow, &nax is, cNAxes))) {1401 reportError();1402 1403 } else if ((status = (nax is != cNAxis))) {1404 cerr << "DATA array dimensions changed." << endl;1701 int naxes = 5, status; 1702 1703 if ((status = readDim(DATA, cRow, &naxes, cNAxis))) { 1704 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1705 1706 } else if ((status = (naxes != cNAxes))) { 1707 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "DATA array dimensions changed."); 1405 1708 } 1406 1709 … … 1413 1716 } 1414 1717 1415 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAx is, cNAxes,1416 blc, trc, inc, 0, mbrec.spectra[0] + i pol*nChan, &anynul,1718 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxes, cNAxis, 1719 blc, trc, inc, 0, mbrec.spectra[0] + iPol*nChan, &anynul, 1417 1720 &cStatus)) { 1418 reportError();1721 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1419 1722 delete [] blc; 1420 1723 delete [] trc; … … 1425 1728 if (endChan < startChan) { 1426 1729 // Reverse the spectrum. 1427 float *iptr = mbrec.spectra[0] + i pol*nChan;1730 float *iptr = mbrec.spectra[0] + iPol*nChan; 1428 1731 float *jptr = iptr + nChan - 1; 1429 1732 float *mid = iptr + nChan/2; … … 1437 1740 if (cALFA) { 1438 1741 // ALFA data, rescale the spectrum. 1439 float *chan = mbrec.spectra[0] + ipol*nChan; 1742 float el, zd; 1743 readData(ELEVATIO, cRow, &el); 1744 zd = 90.0f - el; 1745 1746 float factor = sALFAcal[iBeam][iPol] / alfaGain(zd); 1747 1748 if (cALFA_CIMA > 1) { 1749 // Rescale according to the number of unblanked accumulations. 1750 int colnum, naccum; 1751 findCol("STAT", &colnum); 1752 fits_read_col(cSDptr, TINT, colnum, cRow, 10*(cTimeIdx-1)+2, 1, 0, 1753 &naccum, &anynul, &cStatus); 1754 factor *= cALFAacc / naccum; 1755 } 1756 1757 float *chan = mbrec.spectra[0] + iPol*nChan; 1440 1758 float *chanN = chan + nChan; 1441 1759 while (chan < chanN) { 1442 1760 // Approximate conversion to Jy. 1443 *(chan++) *= cALFAcal[iBeam][iIF];1761 *(chan++) *= factor; 1444 1762 } 1445 1763 } 1446 1764 1447 if (mbrec.tsys[0][i pol] == 0.0) {1765 if (mbrec.tsys[0][iPol] == 0.0) { 1448 1766 // Compute Tsys as the average across the spectrum. 1449 float *chan = mbrec.spectra[0] + i pol*nChan;1767 float *chan = mbrec.spectra[0] + iPol*nChan; 1450 1768 float *chanN = chan + nChan; 1451 float *tsys = mbrec.tsys[0] + i pol;1769 float *tsys = mbrec.tsys[0] + iPol; 1452 1770 while (chan < chanN) { 1453 1771 *tsys += *(chan++); … … 1459 1777 // Read data flags. 1460 1778 if (cData[FLAGGED].colnum > 0) { 1461 if (fits_read_subset_byt(cSDptr, cData[FLAGGED].colnum, cNAx is,1462 cNAx es, blc, trc, inc, 0, mbrec.flagged[0] + ipol*nChan, &anynul,1779 if (fits_read_subset_byt(cSDptr, cData[FLAGGED].colnum, cNAxes, 1780 cNAxis, blc, trc, inc, 0, mbrec.flagged[0] + iPol*nChan, &anynul, 1463 1781 &cStatus)) { 1464 reportError();1782 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1465 1783 delete [] blc; 1466 1784 delete [] trc; … … 1471 1789 if (endChan < startChan) { 1472 1790 // Reverse the flag vector. 1473 unsigned char *iptr = mbrec.flagged[0] + i pol*nChan;1791 unsigned char *iptr = mbrec.flagged[0] + iPol*nChan; 1474 1792 unsigned char *jptr = iptr + nChan - 1; 1475 1793 for (int ichan = 0; ichan < nChan/2; ichan++) { … … 1482 1800 } else { 1483 1801 // All channels are unflagged by default. 1484 unsigned char *iptr = mbrec.flagged[0] + i pol*nChan;1802 unsigned char *iptr = mbrec.flagged[0] + iPol*nChan; 1485 1803 for (int ichan = 0; ichan < nChan; ichan++) { 1486 1804 *(iptr++) = 0; … … 1513 1831 if (fits_read_subset_flt(cSDptr, cData[XPOLDATA].colnum, nAxis, nAxes, 1514 1832 blc, trc, inc, 0, mbrec.xpol[0], &anynul, &cStatus)) { 1515 reportError();1833 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1516 1834 delete [] blc; 1517 1835 delete [] trc; … … 1544 1862 1545 1863 if (cStatus) { 1546 reportError();1864 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1547 1865 return 1; 1548 1866 } … … 1552 1870 readData(TCAL, cRow, &mbrec.tcal[0]); 1553 1871 readData(TCALTIME, cRow, mbrec.tcalTime); 1872 1554 1873 readData(AZIMUTH, cRow, &mbrec.azimuth); 1555 1874 readData(ELEVATIO, cRow, &mbrec.elevation); 1556 1875 readData(PARANGLE, cRow, &mbrec.parAngle); 1876 1557 1877 readData(FOCUSAXI, cRow, &mbrec.focusAxi); 1558 1878 readData(FOCUSTAN, cRow, &mbrec.focusTan); 1559 1879 readData(FOCUSROT, cRow, &mbrec.focusRot); 1880 1560 1881 readData(TAMBIENT, cRow, &mbrec.temp); 1561 1882 readData(PRESSURE, cRow, &mbrec.pressure); … … 1575 1896 mbrec.windAz *= D2R; 1576 1897 1898 // For GBT data, source velocity can be evaluated 1899 if ( cData[RVSYS].colnum > 0 && cData[VFRAME].colnum > 0 ) { 1900 float vframe; 1901 readData(VFRAME, cRow, &vframe); 1902 float rvsys; 1903 readData(RVSYS, cRow, &rvsys); 1904 //mbrec.srcVelocity = rvsys - vframe ; 1905 mbrec.srcVelocity = rvsys ; 1906 } 1907 1577 1908 if (cStatus) { 1578 reportError();1909 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 1579 1910 return 1; 1580 1911 } 1581 1912 1582 1913 return 0; 1583 }1584 1585 1586 //------------------------------------------------------ SDFITSreader::alfaCal1587 1588 // Process ALFA calibration data.1589 1590 int SDFITSreader::alfaCal(1591 short iBeam,1592 short iPol)1593 {1594 int calOn;1595 char chars[32];1596 if (cALFA_BD) {1597 readData("OBS_NAME", TSTRING, cRow, chars);1598 } else {1599 readData("SCANTYPE", TSTRING, cRow, chars);1600 }1601 1602 if (strcmp(chars, "ON") == 0) {1603 calOn = 1;1604 } else if (strcmp(chars, "OFF") == 0) {1605 calOn = 0;1606 } else {1607 return 1;1608 }1609 1610 // Read cal data.1611 long *blc = new long[cNAxis+1];1612 long *trc = new long[cNAxis+1];1613 long *inc = new long[cNAxis+1];1614 for (int iaxis = 0; iaxis <= cNAxis; iaxis++) {1615 blc[iaxis] = 1;1616 trc[iaxis] = 1;1617 inc[iaxis] = 1;1618 }1619 1620 // User channel selection.1621 int startChan = cStartChan[0];1622 int endChan = cEndChan[0];1623 1624 blc[cNAxis] = cRow;1625 trc[cNAxis] = cRow;1626 blc[cReqax[0]] = std::min(startChan, endChan);1627 trc[cReqax[0]] = std::max(startChan, endChan);1628 blc[cReqax[1]] = 1;1629 trc[cReqax[1]] = 1;1630 1631 float spectrum[endChan];1632 int anynul;1633 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxis, cNAxes,1634 blc, trc, inc, 0, spectrum, &anynul, &cStatus)) {1635 reportError();1636 delete [] blc;1637 delete [] trc;1638 delete [] inc;1639 return 1;1640 }1641 1642 // Average the spectrum.1643 float mean = 1e9f;1644 for (int k = 0; k < 2; k++) {1645 float discrim = 2.0f * mean;1646 1647 int nChan = 0;1648 float sum = 0.0f;1649 1650 float *chanN = spectrum + abs(endChan - startChan) + 1;1651 for (float *chan = spectrum; chan < chanN; chan++) {1652 // Simple discriminant that eliminates strong radar interference.1653 if (*chan < discrim) {1654 nChan++;1655 sum += *chan;1656 }1657 }1658 1659 mean = sum / nChan;1660 }1661 1662 if (calOn) {1663 cALFAcalOn[iBeam][iPol] += mean;1664 } else {1665 cALFAcalOff[iBeam][iPol] += mean;1666 }1667 1668 if (cALFAcalOn[iBeam][iPol] != 0.0f &&1669 cALFAcalOff[iBeam][iPol] != 0.0f) {1670 // Tcal should come from the TCAL table, it varies weakly with beam,1671 // polarization, and frequency. However, TCAL is not written properly.1672 float Tcal = 12.0f;1673 cALFAcal[iBeam][iPol] = Tcal / (cALFAcalOn[iBeam][iPol] -1674 cALFAcalOff[iBeam][iPol]);1675 1676 // Scale from K to Jy; the gain also varies weakly with beam,1677 // polarization, frequency, and zenith angle.1678 float fluxCal = 10.0f;1679 cALFAcal[iBeam][iPol] /= fluxCal;1680 1681 cALFAcalOn[iBeam][iPol] = 0.0f;1682 cALFAcalOff[iBeam][iPol] = 0.0f;1683 }1684 1685 return 0;1686 }1687 1688 1689 //-------------------------------------------------- SDFITSreader::reportError1690 1691 // Print the error message corresponding to the input status value and all the1692 // messages on the CFITSIO error stack to stderr.1693 1694 void SDFITSreader::reportError()1695 {1696 fits_report_error(stderr, cStatus);1697 1914 } 1698 1915 … … 1706 1923 int status = 0; 1707 1924 fits_close_file(cSDptr, &status); 1708 cSDptr = 0 ;1925 cSDptr = 0x0; 1709 1926 1710 1927 if (cBeams) delete [] cBeams; … … 1714 1931 if (cRefChan) delete [] cRefChan; 1715 1932 } 1933 } 1934 1935 //------------------------------------------------------- SDFITSreader::log 1936 1937 // Log a message. If the current CFITSIO status value is non-zero, also log 1938 // the corresponding error message and the CFITSIO message stack. 1939 1940 void SDFITSreader::log(LogOrigin origin, LogIO::Command cmd, const char *msg) 1941 { 1942 LogIO os( origin ) ; 1943 1944 os << msg << endl ; 1945 1946 if (cStatus > 0) { 1947 fits_get_errstatus(cStatus, cMsg); 1948 os << cMsg << endl ; 1949 1950 while (fits_read_errmsg(cMsg)) { 1951 os << cMsg << endl ; 1952 } 1953 } 1954 os << LogIO::POST ; 1716 1955 } 1717 1956 … … 1737 1976 long nelem, width; 1738 1977 fits_get_coltype(cSDptr, colnum, &coltype, &nelem, &width, &cStatus); 1978 fits_get_bcolparms(cSDptr, colnum, 0x0, cData[iData].units, 0x0, 0x0, 0x0, 1979 0x0, 0x0, 0x0, &cStatus); 1739 1980 1740 1981 // Look for a TDIMnnn keyword or column. … … 1768 2009 } 1769 2010 2011 //------------------------------------------------------ SDFITSreader::findCol 2012 2013 // Locate a parameter in the SDFITS file. 2014 2015 void SDFITSreader::findCol( 2016 char *name, 2017 int *colnum) 2018 { 2019 *colnum = 0; 2020 int status = 0; 2021 fits_get_colnum(cSDptr, CASESEN, name, colnum, &status); 2022 2023 if (status) { 2024 // Not a real column - maybe it's virtual. 2025 char card[81]; 2026 2027 status = 0; 2028 fits_read_card(cSDptr, name, card, &status); 2029 if (status) { 2030 // Not virtual either. 2031 *colnum = -1; 2032 } 2033 2034 // Clear error messages. 2035 fits_clear_errmsg(); 2036 } 2037 } 2038 1770 2039 //------------------------------------------------------ SDFITSreader::readDim 1771 2040 … … 1775 2044 int iData, 1776 2045 long iRow, 1777 int *nax is,1778 long nax es[])2046 int *naxes, 2047 long naxis[]) 1779 2048 { 1780 2049 int colnum = cData[iData].colnum; … … 1783 2052 } 1784 2053 1785 int maxdim = *nax is;2054 int maxdim = *naxes; 1786 2055 if (cData[iData].tdimcol < 0) { 1787 2056 // No TDIMnnn column for this array. 1788 2057 if (cData[iData].nelem < 0) { 1789 2058 // Variable length array; read the array descriptor. 1790 *nax is = 1;2059 *naxes = 1; 1791 2060 long dummy; 1792 if (fits_read_descript(cSDptr, colnum, iRow, nax es, &dummy, &cStatus)) {2061 if (fits_read_descript(cSDptr, colnum, iRow, naxis, &dummy, &cStatus)) { 1793 2062 return 1; 1794 2063 } … … 1796 2065 } else { 1797 2066 // Read the repeat count from TFORMnnn. 1798 if (fits_read_tdim(cSDptr, colnum, maxdim, nax is, naxes, &cStatus)) {2067 if (fits_read_tdim(cSDptr, colnum, maxdim, naxes, naxis, &cStatus)) { 1799 2068 return 1; 1800 2069 } … … 1814 2083 1815 2084 tp++; 1816 *nax is = 0;2085 *naxes = 0; 1817 2086 for (size_t j = 1; j < strlen(tdimval); j++) { 1818 2087 if (tdimval[j] == ',' || tdimval[j] == ')') { 1819 sscanf(tp, "%ld", nax es + (*naxis)++);2088 sscanf(tp, "%ld", naxis + (*naxes)++); 1820 2089 if (tdimval[j] == ')') break; 1821 2090 tp = tdimval + j + 1; … … 1852 2121 findCol(name, &colnum); 1853 2122 1854 if (colnum > 0 ) {2123 if (colnum > 0 && iRow > 0) { 1855 2124 // Read the first value from the specified row of the table. 1856 2125 int coltype; … … 1915 2184 void *value) 1916 2185 { 1917 char *name = cData[iData].name;1918 2186 int type = cData[iData].type; 1919 2187 int colnum = cData[iData].colnum; 1920 long nelem = cData[iData].nelem; 1921 1922 if (colnum > 0) { 2188 2189 if (colnum > 0 && iRow > 0) { 1923 2190 // Read the required number of values from the specified row of the table. 2191 long nelem = cData[iData].nelem; 1924 2192 int anynul; 1925 2193 if (type == TSTRING) { … … 1950 2218 } else if (colnum == 0) { 1951 2219 // Read keyword value. 2220 char *name = cData[iData].name; 1952 2221 fits_read_key(cSDptr, type, name, value, 0, &cStatus); 1953 2222 … … 1970 2239 } 1971 2240 1972 //------------------------------------------------------ SDFITSreader:: findCol1973 1974 // Locate a parameter inthe SDFITS file.1975 1976 void SDFITSreader::findCol(1977 char *name,1978 int *colnum)2241 //------------------------------------------------------ SDFITSreader::readCol 2242 2243 // Read a scalar column from the SDFITS file. 2244 2245 int SDFITSreader::readCol( 2246 int iData, 2247 void *value) 1979 2248 { 1980 *colnum = 0; 1981 int status = 0; 1982 fits_get_colnum(cSDptr, CASESEN, name, colnum, &status); 1983 1984 if (status) { 1985 // Not a real column - maybe it's virtual. 1986 char card[81]; 1987 1988 status = 0; 1989 fits_read_card(cSDptr, name, card, &status); 1990 if (status) { 1991 // Not virtual either. 1992 *colnum = -1; 1993 } 1994 1995 // Clear error messages. 1996 fits_clear_errmsg(); 1997 } 2249 int type = cData[iData].type; 2250 2251 if (cData[iData].colnum > 0) { 2252 // Table column. 2253 int anynul; 2254 fits_read_col(cSDptr, type, cData[iData].colnum, 1, 1, cNRow, 0, 2255 value, &anynul, &cStatus); 2256 2257 } else { 2258 // Header keyword. 2259 readData(iData, 0, value); 2260 for (int irow = 1; irow < cNRow; irow++) { 2261 if (type == TSHORT) { 2262 ((short *)value)[irow] = *((short *)value); 2263 } else if (type == TINT) { 2264 ((int *)value)[irow] = *((int *)value); 2265 } else if (type == TFLOAT) { 2266 ((float *)value)[irow] = *((float *)value); 2267 } else if (type == TDOUBLE) { 2268 ((double *)value)[irow] = *((double *)value); 2269 } 2270 } 2271 } 2272 2273 return cData[iData].colnum < 0; 1998 2274 } 2275 2276 //----------------------------------------------------- SDFITSreader::readTime 2277 2278 // Read the time from the SDFITS file. 2279 2280 int SDFITSreader::readTime( 2281 long iRow, 2282 int iPix, 2283 char *datobs, 2284 double &utc) 2285 { 2286 readData(DATE_OBS, iRow, datobs); 2287 if (cData[TIME].colnum >= 0) { 2288 readData(TIME, iRow, &utc); 2289 } else if (cGBT) { 2290 Int yy, mm ; 2291 Double dd, hour, min, sec ; 2292 sscanf( datobs, "%d-%d-%lfT%lf:%lf:%lf", &yy, &mm, &dd, &hour, &min, &sec ) ; 2293 dd = dd + ( hour * 3600.0 + min * 60.0 + sec ) / 86400.0 ; 2294 MVTime mvt( yy, mm, dd ) ; 2295 dd = mvt.day() ; 2296 utc = fmod( dd, 1.0 ) * 86400.0 ; 2297 } else if (cNAxisTime > 1) { 2298 double timeDelt, timeRefPix, timeRefVal; 2299 readData(TimeRefVal, iRow, &timeRefVal); 2300 readData(TimeDelt, iRow, &timeDelt); 2301 readData(TimeRefPix, iRow, &timeRefPix); 2302 utc = timeRefVal + (iPix - timeRefPix) * timeDelt; 2303 } 2304 2305 if (cALFA_BD) utc *= 3600.0; 2306 2307 // Check DATE-OBS format. 2308 if (datobs[2] == '/') { 2309 // Translate an old-format DATE-OBS. 2310 datobs[9] = datobs[1]; 2311 datobs[8] = datobs[0]; 2312 datobs[2] = datobs[6]; 2313 datobs[5] = datobs[3]; 2314 datobs[3] = datobs[7]; 2315 datobs[6] = datobs[4]; 2316 datobs[7] = '-'; 2317 datobs[4] = '-'; 2318 datobs[1] = '9'; 2319 datobs[0] = '1'; 2320 2321 } else if (datobs[10] == 'T' && cData[TIME].colnum < 0) { 2322 // Dig UTC out of a new-format DATE-OBS. 2323 int hh, mm; 2324 float ss; 2325 sscanf(datobs+11, "%d:%d:%f", &hh, &mm, &ss); 2326 utc = (hh*60 + mm)*60 + ss; 2327 } 2328 2329 datobs[10] = '\0'; 2330 2331 return 0; 2332 } 2333 2334 //------------------------------------------------------ SDFITSreader::alfaCal 2335 2336 // Process ALFA calibration data. 2337 2338 int SDFITSreader::alfaCal( 2339 short iBeam, 2340 short iIF, 2341 short iPol) 2342 { 2343 const string methodName = "alfaCal()" ; 2344 2345 int calOn; 2346 char chars[32]; 2347 if (cALFA_BD) { 2348 readData("OBS_NAME", TSTRING, cRow, chars); 2349 } else { 2350 readData("SCANTYPE", TSTRING, cRow, chars); 2351 } 2352 2353 if (strcmp(chars, "ON") == 0) { 2354 calOn = 1; 2355 } else if (strcmp(chars, "OFF") == 0) { 2356 calOn = 0; 2357 } else { 2358 return 1; 2359 } 2360 2361 // Read cal data. 2362 long *blc = new long[cNAxes+1]; 2363 long *trc = new long[cNAxes+1]; 2364 long *inc = new long[cNAxes+1]; 2365 for (int iaxis = 0; iaxis <= cNAxes; iaxis++) { 2366 blc[iaxis] = 1; 2367 trc[iaxis] = 1; 2368 inc[iaxis] = 1; 2369 } 2370 2371 // User channel selection. 2372 int startChan = cStartChan[iIF]; 2373 int endChan = cEndChan[iIF]; 2374 2375 blc[cFreqAxis] = std::min(startChan, endChan); 2376 trc[cFreqAxis] = std::max(startChan, endChan); 2377 if (cALFA_CIMA > 1) { 2378 // CIMAFITS 2.x has a legitimate STOKES axis... 2379 blc[cStokesAxis] = iPol+1; 2380 trc[cStokesAxis] = iPol+1; 2381 } else { 2382 // ...older ALFA data does not. 2383 blc[cStokesAxis] = 1; 2384 trc[cStokesAxis] = 1; 2385 } 2386 if (cTimeAxis >= 0) { 2387 blc[cTimeAxis] = cTimeIdx; 2388 trc[cTimeAxis] = cTimeIdx; 2389 } 2390 blc[cNAxes] = cRow; 2391 trc[cNAxes] = cRow; 2392 2393 float spectrum[endChan]; 2394 int anynul; 2395 if (fits_read_subset_flt(cSDptr, cData[DATA].colnum, cNAxes, cNAxis, 2396 blc, trc, inc, 0, spectrum, &anynul, &cStatus)) { 2397 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE); 2398 delete [] blc; 2399 delete [] trc; 2400 delete [] inc; 2401 return 1; 2402 } 2403 2404 // Factor to rescale according to the number of unblanked accumulations. 2405 float factor = 1.0f; 2406 if (cALFA_CIMA > 1) { 2407 int colnum, naccum; 2408 findCol("STAT", &colnum); 2409 fits_read_col(cSDptr, TINT, colnum, cRow, 2, 1, 0, &naccum, &anynul, 2410 &cStatus); 2411 factor = cALFAacc / naccum; 2412 } 2413 2414 // Average the spectrum. 2415 float mean = 1e9f; 2416 for (int k = 0; k < 2; k++) { 2417 float discrim = 2.0f * mean; 2418 2419 int nChan = 0; 2420 float sum = 0.0f; 2421 2422 float *chanN = spectrum + abs(endChan - startChan) + 1; 2423 for (float *chan = spectrum; chan < chanN; chan++) { 2424 // Simple discriminant that eliminates strong radar interference. 2425 if (*chan < discrim) { 2426 nChan++; 2427 sum += *chan * factor; 2428 } 2429 } 2430 2431 mean = sum / nChan; 2432 } 2433 2434 if (calOn) { 2435 sALFAcalOn[iBeam][iPol] *= sALFAcalNon[iBeam][iPol]; 2436 sALFAcalOn[iBeam][iPol] += mean; 2437 sALFAcalOn[iBeam][iPol] /= ++sALFAcalNon[iBeam][iPol]; 2438 } else { 2439 sALFAcalOff[iBeam][iPol] *= sALFAcalNoff[iBeam][iPol]; 2440 sALFAcalOff[iBeam][iPol] += mean; 2441 sALFAcalOff[iBeam][iPol] /= ++sALFAcalNoff[iBeam][iPol]; 2442 } 2443 2444 if (sALFAcalNon[iBeam][iPol] && sALFAcalNoff[iBeam][iPol]) { 2445 // Tcal should come from the TCAL table, it varies weakly with beam, 2446 // polarization, and frequency. However, TCAL is not written properly. 2447 float Tcal = 12.0f; 2448 sALFAcal[iBeam][iPol] = Tcal / (sALFAcalOn[iBeam][iPol] - 2449 sALFAcalOff[iBeam][iPol]); 2450 2451 // Scale from K to Jy; the gain also varies weakly with beam, 2452 // polarization, frequency, and zenith angle. 2453 float fluxCal = 10.0f; 2454 sALFAcal[iBeam][iPol] /= fluxCal; 2455 } 2456 2457 return 0; 2458 } 2459 2460 //----------------------------------------------------- SDFITSreader::alfaGain 2461 2462 // ALFA gain factor. 2463 2464 float SDFITSreader::alfaGain( 2465 float zd) 2466 { 2467 // Gain vs zenith distance table from Robert Minchin, 2008/12/08. 2468 const int nZD = 37; 2469 const float zdLim[] = {1.5f, 19.5f}; 2470 const float zdInc = (nZD - 1) / (zdLim[1] - zdLim[0]); 2471 float zdGain[] = { 1.00723708, 2472 1.16644573, 1.15003645, 1.07117307, 1.02532673, 2473 1.01788402, 1.01369524, 1.00000000, 0.989855111, 2474 0.990888834, 0.993996620, 0.989964068, 0.982213855, 2475 0.978662670, 0.979349494, 0.978478372, 0.974631131, 2476 0.972126007, 0.972835243, 0.972742677, 0.968671739, 2477 0.963891327, 0.963452935, 0.966831207, 0.969585896, 2478 0.970700860, 0.972644389, 0.973754644, 0.967344403, 2479 0.952168941, 0.937160134, 0.927843094, 0.914048433, 2480 0.886700928, 0.864701211, 0.869126320, 0.854309499}; 2481 2482 float gain; 2483 // Do table lookup by linear interpolation. 2484 float lambda = zdInc * (zd - zdLim[0]); 2485 int j = int(lambda); 2486 if (j < 0) { 2487 gain = zdGain[0]; 2488 } else if (j >= nZD-1) { 2489 gain = zdGain[nZD-1]; 2490 } else { 2491 gain = zdGain[j] + (lambda - j) * (zdGain[j+1] - zdGain[j]); 2492 } 2493 2494 return gain; 2495 } 2496 -
branches/alma/external/atnf/PKSIO/SDFITSreader.h
r1453 r1757 2 2 //# SDFITSreader.h: ATNF CFITSIO interface class for SDFITS input. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Associated Universities, Inc. Washington DC, USA.4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSreader.h,v 19.22 2009-09-29 07:33:39 cal103 Exp $ 29 32 //#--------------------------------------------------------------------------- 30 33 //# The SDFITSreader class reads single dish FITS files such as those written … … 38 41 39 42 #include <atnf/PKSIO/FITSreader.h> 40 #include <atnf/PKSIO/PKSMBrecord.h> 43 #include <atnf/PKSIO/MBrecord.h> 44 45 #include <casa/Logging/LogIO.h> 41 46 42 47 #include <fitsio.h> 48 49 using namespace std; 50 using namespace casa; 43 51 44 52 // <summary> … … 76 84 double antPos[3], 77 85 char obsMode[32], 86 char bunit[32], 78 87 float &equinox, 79 88 char radecsys[32], … … 99 108 100 109 // Read the next data record. 101 virtual int read(PKSMBrecord &record); 102 103 // Print out CFITSIO error messages. 104 void reportError(void); 110 virtual int read(MBrecord &record); 105 111 106 112 // Close the SDFITS file. … … 108 114 109 115 private: 110 int cCycleNo, cExtraSysCal, cNAxis, cStatus; 111 long cNAxes[5], cNRow, cReqax[4], cRow; 116 int cCycleNo, cExtraSysCal, cNAxes, cStatus; 117 long cBeamAxis, cDecAxis, cFreqAxis, cNAxis[5], cNAxisTime, cNRow, 118 cRaAxis, cRow, cStokesAxis, cTimeAxis, cTimeIdx; 112 119 double cLastUTC; 113 120 fitsfile *cSDptr; … … 117 124 int cBeam_1rel, cIF_1rel; 118 125 126 // for GBT 127 int *cPols ; 128 119 129 enum {SCAN, CYCLE, DATE_OBS, TIME, EXPOSURE, OBJECT, OBJ_RA, OBJ_DEC, 120 RESTFRQ, OBSMODE, BEAM, IF, FqRefPix, FqRefVal, FqDelt, RA, DEC, 121 SCANRATE, TSYS, CALFCTR, XCALFCTR, BASELIN, BASESUB, DATA, FLAGGED, 122 DATAXED, XPOLDATA, REFBEAM, TCAL, TCALTIME, AZIMUTH, ELEVATIO, 123 PARANGLE, FOCUSAXI, FOCUSTAN, FOCUSROT, TAMBIENT, PRESSURE, 124 HUMIDITY, WINDSPEE, WINDDIRE, NDATA}; 130 RESTFRQ, OBSMODE, BEAM, IF, FqRefVal, FqDelt, FqRefPix, RA, DEC, 131 TimeRefVal, TimeDelt, TimeRefPix, SCANRATE, TSYS, CALFCTR, XCALFCTR, 132 BASELIN, BASESUB, DATA, FLAGGED, DATAXED, XPOLDATA, REFBEAM, TCAL, 133 TCALTIME, AZIMUTH, ELEVATIO, PARANGLE, FOCUSAXI, FOCUSTAN, FOCUSROT, 134 TAMBIENT, PRESSURE, HUMIDITY, WINDSPEE, WINDDIRE, STOKES, SIG, CAL, 135 VFRAME, RVSYS, VELDEF, NDATA}; 136 137 // Message handling. 138 void log(LogOrigin origin, LogIO::Command cmd, const char *msg = 0x0); 125 139 126 140 void findData(int iData, char *name, int type); 141 void findCol(char *name, int *colnum); 127 142 int readDim(int iData, long iRow, int *naxis, long naxes[]); 128 143 int readParm(char *name, int type, void *value); 129 144 int readData(char *name, int type, long iRow, void *value); 130 145 int readData(int iData, long iRow, void *value); 131 void findCol(char *name, int *colnum); 146 int readCol(int iData, void *value); 147 int readTime(long iRow, int iPix, char *datobs, double &utc); 132 148 133 // These are for ALFA data, "BDFITS" or "CIMAFITS". 149 // These are for ALFA data: "BDFITS" or "CIMAFITS". Statics are required 150 // for CIMAFITS v2.0 because CAL ON/OFF data is split into separate files. 151 static int sInit, sReset; 152 static int (*sALFAcalNon)[2], (*sALFAcalNoff)[2]; 153 static float (*sALFAcal)[2], (*sALFAcalOn)[2], (*sALFAcalOff)[2]; 154 134 155 int cALFA, cALFA_BD, cALFA_CIMA, cALFAscan, cScanNo; 135 float cALFAcal[8][2], cALFAcalOn[8][2], cALFAcalOff[8][2]; 136 int alfaCal(short iBeam, short iIF); 156 float cALFAacc; 157 int alfaCal(short iBeam, short iIF, short iPol); 158 float alfaGain(float zd); 137 159 138 160 // These are for GBT data. 139 161 int cGBT, cFirstScanNo; 162 double cGLastUTC[4] ; 163 int cGLastScan[4] ; 164 int cGCycleNo[4] ; 140 165 }; 141 166 -
branches/alma/external/atnf/PKSIO/SDFITSwriter.cc
r1453 r1757 2 2 //# SDFITSwriter.cc: ATNF CFITSIO interface class for SDFITS output. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSwriter.cc,v 19.18 2009-09-29 07:33:39 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# Original: 2000/07/24, Mark Calabretta, ATNF 32 34 //#--------------------------------------------------------------------------- 33 35 36 #include <atnf/PKSIO/MBrecord.h> 37 #include <atnf/PKSIO/SDFITSwriter.h> 38 39 #include <casa/Logging/LogIO.h> 40 41 #include <casa/iostream.h> 42 34 43 #include <algorithm> 35 44 #include <math.h> 36 37 // AIPS++ includes. 38 #include <casa/iostream.h> 39 40 // ATNF includes. 41 #include <atnf/PKSIO/PKSMBrecord.h> 42 #include <atnf/PKSIO/SDFITSwriter.h> 45 #include <cstring> 43 46 44 47 using namespace std; … … 49 52 // Factor to convert radians to degrees. 50 53 const double R2D = 180.0 / PI; 54 55 // Class name 56 const string className = "SDFITSwriter" ; 51 57 52 58 //------------------------------------------------- SDFITSwriter::SDFITSwriter … … 55 61 { 56 62 // Default constructor. 57 cSDptr = 0 ;63 cSDptr = 0x0; 58 64 } 59 65 … … 76 82 double antPos[3], 77 83 char* obsMode, 84 char* bunit, 78 85 float equinox, 79 86 char* dopplerFrame, … … 85 92 int extraSysCal) 86 93 { 94 const string methodName = "create()" ; 95 96 if (cSDptr) { 97 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Output file already open, close it first."); 98 return 1; 99 } 100 87 101 // Prepend an '!' to the output name to force it to be overwritten. 88 102 char sdname[80]; … … 93 107 cStatus = 0; 94 108 if (fits_create_file(&cSDptr, sdname, &cStatus)) { 109 sprintf(cMsg, "Failed to create SDFITS file\n %s", sdName); 110 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, cMsg); 95 111 return cStatus; 96 112 } … … 113 129 break; 114 130 } 115 131 116 132 if (cNChan[iIF] != cNChan[0] || cNPol[iIF] != cNPol[0]) { 117 133 // Varying channels and/or polarizations, need a TDIM column at least. … … 140 156 // Write required primary header keywords. 141 157 if (fits_write_imghdr(cSDptr, 8, 0, 0, &cStatus)) { 158 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to write required primary header keywords."); 142 159 return cStatus; 143 160 } … … 159 176 char version[7]; 160 177 char date[11]; 161 sscanf("$Revision: 19.1 0$", "%*s%s", version);162 sscanf("$Date: 200 6/07/05 05:44:52$", "%*s%s", date);178 sscanf("$Revision: 19.18 $", "%*s%s", version); 179 sscanf("$Date: 2009-09-29 07:33:39 $", "%*s%s", date); 163 180 sprintf(text, "SDFITSwriter (v%s, %s)", version, date); 164 181 fits_write_key_str(cSDptr, "ORIGIN", text, "output class", &cStatus); … … 170 187 fits_write_comment(cSDptr, text, &cStatus); 171 188 189 if (cStatus) { 190 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing primary header."); 191 return cStatus; 192 } 193 194 172 195 // Create an SDFITS extension. 173 196 long nrow = 0; … … 175 198 if (fits_create_tbl(cSDptr, BINARY_TBL, nrow, ncol, NULL, NULL, NULL, 176 199 "SINGLE DISH", &cStatus)) { 200 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to create a binary table extension."); 177 201 return 1; 178 202 } … … 209 233 210 234 // CYCLE (additional, real). 211 fits_insert_col(cSDptr, ++ncol, "CYCLE", "1 I", &cStatus);235 fits_insert_col(cSDptr, ++ncol, "CYCLE", "1J", &cStatus); 212 236 213 237 // DATE-OBS (core, real). … … 355 379 fits_insert_col(cSDptr, ++ncol, "TSYS", tform, &cStatus); 356 380 sprintf(tunit, "TUNIT%d", ncol); 357 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);381 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 358 382 359 383 // CALFCTR (additional, real). … … 369 393 370 394 // BASESUB (additional, real). 371 sprintf(tform, "%dE", 9*maxNPol);395 sprintf(tform, "%dE", 24*maxNPol); 372 396 fits_insert_col(cSDptr, ++ncol, "BASESUB", tform, &cStatus); 373 tdim[0] = 9;397 tdim[0] = 24; 374 398 fits_write_tdim(cSDptr, ncol, 2, tdim, &cStatus); 375 399 } … … 396 420 397 421 sprintf(tunit, "TUNIT%d", ncol); 398 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);422 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 399 423 400 424 // FLAGGED (additional, logical). … … 444 468 445 469 sprintf(tunit, "TUNIT%d", ncol); 446 fits_write_key_str(cSDptr, tunit, "Jy", "units of field", &cStatus);470 fits_write_key_str(cSDptr, tunit, bunit, "units of field", &cStatus); 447 471 } 448 472 … … 523 547 } 524 548 549 if (cStatus) { 550 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing binary table header."); 551 } 552 525 553 return cStatus; 526 554 } … … 530 558 // Write a record to the SDFITS file. 531 559 532 int SDFITSwriter::write( PKSMBrecord &mbrec)560 int SDFITSwriter::write(MBrecord &mbrec) 533 561 { 562 const string methodName = "write()" ; 563 LogIO os( LogOrigin( className, methodName, WHERE ) ) ; 564 534 565 char *cptr; 535 566 … … 537 568 int IFno = mbrec.IFno[0]; 538 569 if (IFno < 1 || cNIF < IFno) { 539 cerr << "SDFITSwriter::write: " 540 << "Invalid IF number " << IFno 541 << " (maximum " << cNIF << ")." << endl; 570 os << LogIO::WARN 571 << "SDFITSwriter::write: " 572 << "Invalid IF number " << IFno 573 << " (maximum " << cNIF << ")." << LogIO::POST ; 542 574 return 1; 543 575 } … … 546 578 int nChan = cNChan[iIF]; 547 579 if (mbrec.nChan[0] != nChan) { 548 cerr << "SDFITSriter::write: " 549 << "Wrong number of channels for IF " << IFno << "," << endl 550 << " " 551 << "got " << nChan << " should be " << mbrec.nChan[0] << "." << endl; 580 os << LogIO::WARN 581 << "SDFITSriter::write: " 582 << "Wrong number of channels for IF " << IFno << "," << endl 583 << " " 584 << "got " << nChan << " should be " << mbrec.nChan[0] << "." << endl; 585 os << LogIO::POST ; 552 586 return 1; 553 587 } … … 555 589 int nPol = cNPol[iIF]; 556 590 if (mbrec.nPol[0] != nPol) { 557 cerr << "SDFITSriter::write: " 558 << "Wrong number of polarizations for IF " << IFno << "," << endl 559 << " " 560 << "got " << nPol << " should be " << mbrec.nPol[0] << "." << endl; 591 os << LogIO::WARN 592 << "SDFITSriter::write: " 593 << "Wrong number of polarizations for IF " << IFno << "," << endl 594 << " " 595 << "got " << nPol << " should be " << mbrec.nPol[0] << "." << endl; 596 os << LogIO::POST ; 561 597 return 1; 562 598 } … … 655 691 656 692 // BASESUB. 657 fits_write_col_flt(cSDptr, ++icol, cRow, 1, 9*nPol, mbrec.baseSub[0][0],693 fits_write_col_flt(cSDptr, ++icol, cRow, 1, 24*nPol, mbrec.baseSub[0][0], 658 694 &cStatus); 659 695 } … … 739 775 } 740 776 777 if (cStatus) { 778 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing binary table entry."); 779 } 780 741 781 return cStatus; 742 782 } 743 783 744 784 745 //-------------------------------------------------- SDFITSwriter::reportError746 747 // Print the error message corresponding to the input status value and all the748 // messages on the CFITSIO error stack to stderr. 749 750 void SDFITSwriter::reportError() 785 //------------------------------------------------------ SDFITSwriter::history 786 787 // Write a history record. 788 789 int SDFITSwriter::history(char *text) 790 751 791 { 752 fits_report_error(stderr, cStatus); 792 const string methodName = "history()" ; 793 794 if (!cSDptr) { 795 return 1; 796 } 797 798 if (fits_write_history(cSDptr, text, &cStatus)) { 799 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed in writing HISTORY records."); 800 } 801 802 return cStatus; 753 803 } 754 804 … … 759 809 void SDFITSwriter::close() 760 810 { 811 const string methodName = "close()" ; 812 761 813 if (cSDptr) { 762 814 cStatus = 0; 763 fits_close_file(cSDptr, &cStatus); 815 if (fits_close_file(cSDptr, &cStatus)) { 816 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to close file."); 817 } 818 764 819 cSDptr = 0; 765 820 } … … 772 827 void SDFITSwriter::deleteFile() 773 828 { 829 const string methodName = "deleteFile()" ; 830 774 831 if (cSDptr) { 775 832 cStatus = 0; 776 fits_delete_file(cSDptr, &cStatus); 833 if (fits_delete_file(cSDptr, &cStatus)) { 834 log(LogOrigin( className, methodName, WHERE ), LogIO::SEVERE, "Failed to close and delete file."); 835 } 836 777 837 cSDptr = 0; 778 838 } 779 839 } 840 841 //------------------------------------------------------- SDFITSwriter::log 842 843 // Log a message. If the current CFITSIO status value is non-zero, also log 844 // the corresponding error message and dump the CFITSIO message stack. 845 846 void SDFITSwriter::log(LogOrigin origin, LogIO::Command cmd, const char *msg) 847 { 848 LogIO os( origin ) ; 849 850 os << cmd << msg << endl ; 851 852 if (cStatus) { 853 fits_get_errstatus(cStatus, cMsg); 854 os << cMsg << endl ; 855 856 while (fits_read_errmsg(cMsg)) { 857 os << cMsg << endl ; 858 } 859 } 860 861 os << LogIO::POST ; 862 } -
branches/alma/external/atnf/PKSIO/SDFITSwriter.h
r1453 r1757 2 2 //# SDFITSwriter.h: ATNF CFITSIO interface class for SDFITS output. 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 2000-20065 //# Mark Calabretta, ATNF4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning this software should be addressed as follows:22 //# Internet email: mcalabre@atnf.csiro.au .23 //# Postal address: Dr. Mark Calabretta ,24 //# Australia Telescope National Facility, 25 //# P .O. Box 76,26 //# Epping , NSW, 2121,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 27 28 //# AUSTRALIA 28 29 //# 29 //# $Id$ 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: SDFITSwriter.h,v 19.10 2009-09-29 07:33:39 cal103 Exp $ 30 32 //#--------------------------------------------------------------------------- 31 33 //# Original: 2000/07/24, Mark Calabretta, ATNF … … 35 37 #define ATNF_SDFITSWRITER_H 36 38 37 #include <atnf/PKSIO/PKSMBrecord.h> 39 #include <atnf/PKSIO/MBrecord.h> 40 #include <casa/Logging/LogIO.h> 38 41 39 42 #include <fitsio.h> 43 44 using namespace std; 45 using namespace casa; 40 46 41 47 // <summary> … … 50 56 51 57 // Destructor. 52 ~SDFITSwriter();58 virtual ~SDFITSwriter(); 53 59 54 60 // Create a new SDFITSwriter and store static data. … … 60 66 double antPos[3], 61 67 char* obsMode, 68 char* bunit, 62 69 float equinox, 63 70 char* dopplerFrame, … … 70 77 71 78 // Store time-variable data. 72 int write( PKSMBrecord &record);79 int write(MBrecord &record); 73 80 74 // Print out CFITSIO error messages.75 void reportError();81 // Write a history record. 82 int history(char* text); 76 83 77 84 // Close the SDFITS file. … … 86 93 *cNChan, cNIF, *cNPol, cStatus; 87 94 long cRow; 95 96 // Message handling. 97 char cMsg[256]; 98 void log(LogOrigin origin, LogIO::Command cmd, const char *msg = 0x0); 88 99 }; 89 100 -
branches/alma/external/atnf/PKSIO/makefile
r1325 r1757 1 # $Id : makefile,v 19.0 2003/07/16 03:34:05 aips2adm Exp$1 # $Id$ 2 2 3 3 XLIBLIST := CFITSIO RPFITS … … 5 5 # Use the generic AIPS++ class implementation makefile. 6 6 #------------------------------------------------------ 7 include $(word 1, $( AIPSPATH))/code/install/makefile.imp7 include $(word 1, $(CASAPATH))/code/install/makefile.imp -
branches/alma/external/atnf/pks/makefile
r1325 r1757 1 # $Id : makefile,v 19.0 2003/07/16 03:33:47 aips2adm Exp$1 # $Id$ 2 2 3 3 # Use the generic AIPS++ class implementation makefile. 4 4 #------------------------------------------------------ 5 include $(word 1, $( AIPSPATH))/code/install/makefile.imp5 include $(word 1, $(CASAPATH))/code/install/makefile.imp -
branches/alma/external/atnf/pks/pks_maths.cc
r1325 r1757 2 2 //# pks_maths.cc: Mathematical functions for Parkes single-dish data reduction 3 3 //#--------------------------------------------------------------------------- 4 //# Copyright (C) 1994-2006 5 //# Associated Universities, Inc. Washington DC, USA. 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 11 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2004-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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 15 //# License for more details. 16 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 20 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 27 //# 28 //# Original: Mark Calabretta 29 //# $Id: pks_maths.cc,v 1.5 2006/05/19 00:12:35 mcalabre Exp $ 30 //---------------------------------------------------------------------------- 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: pks_maths.cc,v 1.7 2009-09-29 07:45:02 cal103 Exp $ 32 //#--------------------------------------------------------------------------- 33 //# Original: 2004/07/16 Mark Calabretta 34 //#--------------------------------------------------------------------------- 31 35 32 36 // AIPS++ includes. … … 295 299 //----------------------------------------------------------------------- azel 296 300 297 // Convert (ra,dec) to (az,el), from 298 // http://aa.usno.navy.mil/faq/docs/Alt_Az.html. Position as a Cartesian 299 // triplet in m, UT1 in MJD form, and all angles in radian. 301 // Convert (ra,dec) to (az,el). Position as a Cartesian triplet in m, UT1 in 302 // MJD form, and all angles in radian. 300 303 301 304 void azel(const Vector<Double> position, Double ut1, Double ra, Double dec, 302 305 Double &az, Double &el) 303 306 { 304 // Get g ocentric longitude and latitude (rad).307 // Get geocentric longitude and latitude (rad). 305 308 Double x = position(0); 306 309 Double y = position(1); … … 318 321 319 322 // Azimuth and elevation (rad). 320 az = atan2(cos(dec)*sin(ha), cos(dec)*sin(lat)*cos(ha) - sin(dec)*cos(lat)); 323 az = atan2(cos(dec)*sin(ha), 324 cos(dec)*sin(lat)*cos(ha) - sin(dec)*cos(lat)); 321 325 if (az < 0.0) az += C::_2pi; 322 el = asin(cos(dec)*cos(lat)*cos(ha) + sin(dec)*sin(lat)); 326 el = asin(sin(dec)*sin(lat) + cos(dec)*cos(lat)*cos(ha)); 327 323 328 } 324 329 -
branches/alma/external/atnf/pks/pks_maths.h
r1325 r1757 1 // ----------------------------------------------------------------------------1 //#--------------------------------------------------------------------------- 2 2 //# pks_maths.h: Mathematical functions for Parkes single dish data reduction 3 // ----------------------------------------------------------------------------4 //# Copyright (C) 1994-20065 //# Associated Universities, Inc. Washington DC, USA.3 //#--------------------------------------------------------------------------- 4 //# livedata - processing pipeline for single-dish, multibeam spectral data. 5 //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO 6 6 //# 7 //# This library is free software; you can redistribute it and/or modify it 8 //# under the terms of the GNU Library General Public License as published by 9 //# the Free Software Foundation; either version 2 of the License, or (at your 10 //# option) any later version. 7 //# This file is part of livedata. 11 8 //# 12 //# This library is distributed in the hope that it will be useful, but WITHOUT 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 13 15 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public15 //# License formore details.16 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 17 //# more details. 16 18 //# 17 //# You should have received a copy of the GNU Library General Public License 18 //# along with this library; if not, write to the Free Software Foundation, 19 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 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/>. 20 21 //# 21 //# Correspondence concerning AIPS++ should be addressed as follows: 22 //# Internet email: aips2-request@nrao.edu. 23 //# Postal address: AIPS++ Project Office 24 //# National Radio Astronomy Observatory 25 //# 520 Edgemont Road 26 //# Charlottesville, VA 22903-2475 USA 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 27 29 //# 28 //# Original: Mark Calabretta 29 //# $Id: pks_maths.h,v 1.6 2006/05/19 00:12:06 mcalabre Exp $ 30 //---------------------------------------------------------------------------- 30 //# http://www.atnf.csiro.au/computing/software/livedata.html 31 //# $Id: pks_maths.h,v 1.7 2009-09-29 07:45:02 cal103 Exp $ 32 //#--------------------------------------------------------------------------- 33 //# Original: 2004/07/16 Mark Calabretta 34 //#--------------------------------------------------------------------------- 31 35 #ifndef ATNF_PKS_MATHS_H 32 36 #define ATNF_PKS_MATHS_H
Note:
See TracChangeset
for help on using the changeset viewer.