LCOV - code coverage report
Current view: top level - nrao/VLA - VLAADA.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 218 292 74.7 %
Date: 2024-12-11 20:54:31 Functions: 18 23 78.3 %

          Line data    Source code
       1             : //# VLAADA.cc:
       2             : //# Copyright (C) 1999,2000,2001
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: casa-feedback@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : //#
      26             : //# $Id$
      27             : 
      28             : #include <iomanip>
      29             : #include <nrao/VLA/VLAADA.h>
      30             : #include <casacore/casa/Utilities/Assert.h>
      31             : #include <casacore/casa/Exceptions/Error.h>
      32             : #include <casacore/casa/BasicSL/String.h>
      33             : #include <casacore/casa/Quanta/QC.h>
      34             : #include <casacore/casa/Quanta/Unit.h>
      35             : #include <casacore/casa/Arrays/Vector.h>
      36             : #include <casacore/casa/Arrays/ArrayLogical.h>
      37             : #include <casacore/casa/Logging/LogIO.h>
      38             : #include <casacore/casa/Logging/LogOrigin.h>
      39             : #include <casacore/casa/BasicMath/Math.h>
      40             : 
      41             : Double ns2m;
      42             : 
      43         430 : VLAADA::VLAADA()
      44         430 :   :itsRecord(),
      45         430 :    itsOffset(0)
      46             : {
      47         430 :   ns2m = QC::c( ).getValue("m/ns");
      48             :   // cerr << QC::c( ) << endl;
      49             :   // cerr << C::c << endl;
      50         430 :   DebugAssert(ok(), AipsError);
      51         430 : }
      52             : 
      53           0 : VLAADA::VLAADA(ByteSource& record, uInt offset)
      54           0 :   :itsRecord(record),
      55           0 :    itsOffset(offset)
      56             : {
      57           0 :   DebugAssert(ok(), AipsError);
      58           0 : }
      59             : 
      60           0 : VLAADA::VLAADA(const VLAADA& other)
      61           0 :   :itsRecord(other.itsRecord),
      62           0 :    itsOffset(other.itsOffset)
      63             : {
      64           0 :   DebugAssert(ok(), AipsError);
      65           0 : }
      66             : 
      67         430 : VLAADA::~VLAADA()
      68             : {
      69         430 :   DebugAssert(ok(), AipsError);
      70         430 : }
      71             : 
      72           0 : VLAADA& VLAADA::operator=(const VLAADA& other) {
      73           0 :   if (this != &other) {
      74           0 :     itsRecord = other.itsRecord;
      75           0 :     itsOffset = other.itsOffset;
      76             :   }
      77           0 :   DebugAssert(ok(), AipsError);
      78           0 :   return *this;
      79             : }
      80             : 
      81      553931 : void VLAADA::attach(ByteSource& record, uInt offset) {
      82      553931 :   itsRecord = record;
      83      553931 :   itsOffset = offset;
      84      553931 :   DebugAssert(ok(), AipsError);
      85      553931 : }
      86             : 
      87      366726 : uInt VLAADA::antId() const {
      88      366726 :   DebugAssert(ok(), AipsError);
      89      366726 :   const Int64 where = itsOffset + 2*(0);
      90      366726 :   itsRecord.seek(where);
      91             :   uChar id;
      92      366726 :   itsRecord >> id;
      93      366726 :   return id;
      94             : }
      95             : 
      96      122329 : String VLAADA::antName(Bool newStyle) const {
      97      122329 :   DebugAssert(ok(), AipsError);
      98      122329 :   String antid=String::toString(antId());
      99      122329 :   if(antId() < 10)
     100       38976 :     antid=String("0")+antid;
     101      122329 :   if(newStyle){
     102           0 :     Int64 where = itsOffset + 2*(1);
     103           0 :     itsRecord.seek(where);
     104             : 
     105             :     Short bits;
     106           0 :     itsRecord >> bits;
     107             :     // Bit 9 == fiber == evla or pie town  (0x0040 = 0000.0000.0100.0000)
     108           0 :     Bool fiber = (bits & 0x0040);
     109             : 
     110           0 :     if (fiber)
     111           0 :       if (antId()==29)
     112             :         // pie town is just an old VLA antenna in this context
     113           0 :         antid=String("VA")+antid;
     114             :       else
     115             :         // evla
     116           0 :         antid=String("EA")+antid;
     117             :         
     118             :     else
     119           0 :       antid=String("VA")+antid;
     120             :   
     121             :   }
     122      122329 :   return antid;
     123           0 : }
     124             : 
     125           0 : Float VLAADA::frontEndTemp(VLAEnum::IF which) const {
     126           0 :   DebugAssert(ok(), AipsError);
     127           0 :   Int64 where = itsOffset+2*(48);
     128           0 :   switch (which) {
     129           0 :   case VLAEnum::IFA:
     130           0 :     break;
     131           0 :   case VLAEnum::IFB:
     132           0 :     where += 4;
     133           0 :     break;
     134           0 :   case VLAEnum::IFC:
     135           0 :     where += 8;
     136           0 :     break;
     137           0 :   case VLAEnum::IFD:
     138           0 :     where += 12;
     139           0 :     break;
     140           0 :   default:
     141           0 :     throw(AipsError("VLAADA::Unknown IF"));
     142             :   }
     143           0 :   itsRecord.seek(where);
     144             :   Float temp;
     145           0 :   itsRecord >> temp;
     146           0 :   return temp;
     147             : }
     148             : 
     149      122068 : Double VLAADA::u() const {
     150      122068 :   DebugAssert(ok(), AipsError);
     151      122068 :   const Int64 where = itsOffset+2*(28);
     152      122068 :   itsRecord.seek(where);
     153             :   Double u;
     154      122068 :   itsRecord >> u;
     155             :   // cerr << u << " " << ns2m << " ";
     156      122068 :   return u*ns2m;
     157             : }
     158             : 
     159      122068 : Double VLAADA::v() const {
     160      122068 :   DebugAssert(ok(), AipsError);
     161      122068 :   const Int64 where = itsOffset+2*(30);
     162      122068 :   itsRecord.seek(where);
     163             :   Double v;
     164      122068 :   itsRecord >> v;
     165      122068 :   return v*ns2m;
     166             : }
     167      122068 : Double VLAADA::w() const {
     168      122068 :   DebugAssert(ok(), AipsError);
     169      122068 :   const Int64 where = itsOffset+2*(32);
     170      122068 :   itsRecord.seek(where);
     171             :   Double w;
     172      122068 :   itsRecord >> w;
     173      122068 :   return w*ns2m;
     174             : }
     175             : 
     176      122329 : Double VLAADA::bx() const {
     177      122329 :   DebugAssert(ok(), AipsError);
     178      122329 :   const Int64 where = itsOffset+2*(34);
     179      122329 :   itsRecord.seek(where);
     180             :   Double bx;
     181      122329 :   itsRecord >> bx;
     182      122329 :   return bx*ns2m;
     183             : }
     184             : 
     185      122068 : Double VLAADA::by() const {
     186      122068 :   DebugAssert(ok(), AipsError);
     187      122068 :   const Int64 where = itsOffset+2*(38);
     188      122068 :   itsRecord.seek(where);
     189             :   Double by;
     190      122068 :   itsRecord >> by;
     191      122068 :   return by*ns2m;
     192             : }
     193             : 
     194      122068 : Double VLAADA::bz() const {
     195      122068 :   DebugAssert(ok(), AipsError);
     196      122068 :   const Int64 where = itsOffset+2*(42);
     197      122068 :   itsRecord.seek(where);
     198             :   Double bz;
     199      122068 :   itsRecord >> bz;
     200      122068 :   return bz*ns2m;
     201             : }
     202             : 
     203           0 : Vector<Double> VLAADA::pos() const {
     204           0 :   DebugAssert(ok(), AipsError);
     205           0 :   Vector<Double> pos(3);
     206           0 :   pos(0) = bx();
     207           0 :   pos(1) = by();
     208           0 :   pos(2) = bz();
     209           0 :   return pos;
     210           0 : }
     211             : 
     212         261 : String VLAADA::padName() const {
     213         261 :   DebugAssert(ok(), AipsError);
     214         261 :   const Double x = bx();
     215         261 :   const uInt nPad = 74;
     216         261 :   static Block<Double> padX(nPad);
     217         261 :   static Block<String> padName(nPad);
     218             :   static Bool init = false;
     219         261 :   if (!init) { // These are the nominal bx positions of the pads. This table
     220             :     // was extracted from the AIPS task FILLM
     221           1 :     padName[0] = "W1";    padX[0] = 77.   ;
     222           1 :     padName[1] = "W2";    padX[1] = 49.   ;
     223           1 :     padName[2] = "W3";    padX[2] = 96.   ;
     224           1 :     padName[3] = "W4";    padX[3] = 156.  ;
     225           1 :     padName[4] = "W5";    padX[4] = 229.  ;
     226           1 :     padName[5] = "W6";    padX[5] = 312.  ;
     227           1 :     padName[6] = "W7";    padX[6] = 406.  ;
     228           1 :     padName[7] = "W8";    padX[7] = 510.  ;
     229           1 :     padName[8] = "W9";    padX[8] = 623.  ;
     230           1 :     padName[9] = "W10";   padX[9] = 747.  ;
     231           1 :     padName[10] = "W12"; padX[10] = 1021. ;
     232           1 :     padName[11] = "W14"; padX[11] = 1328. ;
     233           1 :     padName[12] = "W16"; padX[12] = 1667. ;
     234           1 :     padName[13] = "W18"; padX[13] = 2041. ;
     235           1 :     padName[14] = "W20"; padX[14] = 2446. ;
     236           1 :     padName[15] = "W24"; padX[15] = 3354. ;
     237           1 :     padName[16] = "W28"; padX[16] = 4391. ;
     238           1 :     padName[17] = "W32"; padX[17] = 5470. ;
     239           1 :     padName[18] = "W36"; padX[18] = 6671. ;
     240           1 :     padName[19] = "W40"; padX[19] = 7988. ;
     241           1 :     padName[20] = "W48"; padX[20] = 10926.;
     242           1 :     padName[21] = "W56"; padX[21] = 14206.;
     243           1 :     padName[22] = "W64"; padX[22] = 17843.;
     244           1 :     padName[23] = "W72"; padX[23] = 21803.;
     245           1 :     padName[24] = "E1";        padX[24] = 151.  ;
     246           1 :     padName[25] = "E2";        padX[25] = 38.   ;
     247           1 :     padName[26] = "E3";        padX[26] = 73.   ;
     248           1 :     padName[27] = "E4";        padX[27] = 119.  ;
     249           1 :     padName[28] = "E5";  padX[28] = 173.  ;
     250           1 :     padName[29] = "E6";        padX[29] = 236.  ;
     251           1 :     padName[30] = "E7";        padX[30] = 305.  ;
     252           1 :     padName[31] = "E8";        padX[31] = 382.  ;
     253           1 :     padName[32] = "E9";        padX[32] = 466.  ;
     254           1 :     padName[33] = "E10"; padX[33] = 558.  ;
     255           1 :     padName[34] = "E12"; padX[34] = 765.  ;
     256           1 :     padName[35] = "E14"; padX[35] = 1000. ;
     257           1 :     padName[36] = "E16"; padX[36] = 1257. ;
     258           1 :     padName[37] = "E18"; padX[37] = 1548. ;
     259           1 :     padName[38] = "E20"; padX[38] = 1868. ;
     260           1 :     padName[39] = "E24"; padX[39] = 2552. ;
     261           1 :     padName[40] = "E28"; padX[40] = 3331. ;
     262           1 :     padName[41] = "E32"; padX[41] = 4180. ;
     263           1 :     padName[42] = "E36"; padX[42] = 5119. ;
     264           1 :     padName[43] = "E40"; padX[43] = 6127. ;
     265           1 :     padName[44] = "E48"; padX[44] = 8325. ;
     266           1 :     padName[45] = "E56"; padX[45] = 10814.;
     267           1 :     padName[46] = "E64"; padX[46] = 13620.;
     268           1 :     padName[47] = "E72"; padX[47] = 16204.;
     269           1 :     padName[48] = "N1";        padX[48] = 2.5    ;
     270           1 :     padName[49] = "N2";        padX[49] = -100.  ;
     271           1 :     padName[50] = "N3";        padX[50] = -175.  ;
     272           1 :     padName[51] = "N4";        padX[51] = -250.  ;
     273           1 :     padName[52] = "N5";  padX[52] = -362.  ;
     274           1 :     padName[53] = "N6";  padX[53] = -495.  ;
     275           1 :     padName[54] = "N7";  padX[54] = -646.  ;
     276           1 :     padName[55] = "N8";  padX[55] = -813.  ;
     277           1 :     padName[56] = "N9";  padX[56] = -995.  ;
     278           1 :     padName[57] = "N10"; padX[57] = -1193. ;
     279           1 :     padName[58] = "N12"; padX[58] = -1632. ;
     280           1 :     padName[59] = "N14"; padX[59] = -2126. ;
     281           1 :     padName[60] = "N16"; padX[60] = -2673. ;
     282           1 :     padName[61] = "N18"; padX[61] = -3271. ;
     283           1 :     padName[62] = "N20"; padX[62] = -3917. ;
     284           1 :     padName[63] = "N24"; padX[63] = -5539. ;
     285           1 :     padName[64] = "N28"; padX[64] = -6976. ;
     286           1 :     padName[65] = "N32"; padX[65] = -8770. ;
     287           1 :     padName[66] = "N36"; padX[66] = -10733.;
     288           1 :     padName[67] = "N40"; padX[67] = -12858.;
     289           1 :     padName[68] = "N48"; padX[68] = -17583.;
     290           1 :     padName[69] = "N56"; padX[69] = -22919.;
     291           1 :     padName[70] = "N64"; padX[70] = -28827.;
     292           1 :     padName[71] = "N72"; padX[71] = -35283.;
     293           1 :     padName[72] = "MPD"; padX[72] = 1148.;
     294           1 :     padName[73] = "VPT"; padX[73] = -46201.; // Pie Town
     295          75 :     for (uInt i = 0; i < nPad; i++) {
     296          74 :       padX[i] *= ns2m;
     297             :     }
     298           1 :     init = true;
     299             :   }
     300         261 :   String name;
     301         261 :   uInt i = 0;
     302         261 :   String arrname=arrayName();
     303        9122 :   while (name.length() == 0 && i < nPad) {
     304        8861 :     if (nearAbs(x, padX[i], 0.5)) { // This is nearly the largest slop
     305             :       // allowable as W1 is at 77*(0.3m/ns) and E3 is at 73.*(0.3m/ns)
     306             : 
     307         261 :       name = arrayName();
     308         261 :       name += padName[i];
     309             :     }
     310        8861 :     i++;
     311             :   }
     312         261 :   if (name.length() == 0) {
     313           0 :     name = "UNKNOWN";
     314             :   }
     315         522 :   return name;
     316         261 : }
     317             : 
     318      364420 : uInt VLAADA::ifStatus(VLAEnum::IF which) const {
     319      364420 :   DebugAssert(ok(), AipsError);
     320      364420 :   Int64 where = itsOffset+2*(3);
     321      364420 :   if (which == VLAEnum::IFC || which == VLAEnum::IFD) {
     322      161568 :     where++;
     323             :   }
     324      364420 :   itsRecord.seek(where);
     325             :   uChar status;
     326      364420 :   itsRecord >> status;
     327      364420 :   if (which == VLAEnum::IFA || which == VLAEnum::IFC) {
     328      202852 :     status >>= 4;
     329             :   }
     330      364420 :   status &= 0x0f;
     331      364420 :   return status;
     332             : }
     333             : 
     334      364420 : Float VLAADA::nominalSensitivity(VLAEnum::IF which) const {
     335      364420 :   DebugAssert(ok(), AipsError);
     336      364420 :   Int64 where = itsOffset+2*(4);
     337      364420 :   switch (which) {
     338      122068 :   case VLAEnum::IFA:
     339      122068 :     break;
     340       80784 :   case VLAEnum::IFB:
     341       80784 :     where += 4;
     342       80784 :     break;
     343       80784 :   case VLAEnum::IFC:
     344       80784 :     where += 8;
     345       80784 :     break;
     346       80784 :   case VLAEnum::IFD:
     347       80784 :     where += 12;
     348       80784 :     break;
     349           0 :   default:
     350           0 :     throw(AipsError("VLAADA::Unknown IF"));
     351             :   }
     352      364420 :   itsRecord.seek(where);
     353             :   Float sensitivity;
     354      364420 :   itsRecord >> sensitivity;
     355      364420 :   return sensitivity;
     356             : }
     357             :   
     358      224124 : Stokes::StokesTypes VLAADA::ifPol(VLAEnum::IF which) const {
     359      224124 :   DebugAssert(ok(), AipsError);
     360      224124 :   Int64 where = itsOffset+2*(1);
     361      224124 :   itsRecord.seek(where);
     362             :   uChar bits;
     363      224124 :   itsRecord >> bits;
     364      224124 :   Bool swap = bits & 0x80;
     365      224124 :   if (which == VLAEnum::IFA || which == VLAEnum::IFB) {
     366      176252 :     if (swap) {
     367           0 :       return Stokes::LCircular;
     368             :     } else {
     369      176252 :       return Stokes::RCircular;
     370             :     }
     371             :   } else {
     372       47872 :     if (swap) {
     373           0 :       return Stokes::RCircular;
     374             :     } else {
     375       47872 :       return Stokes::LCircular;
     376             :     }
     377             :   }
     378             : }
     379             : 
     380             : // Has nominal sensitivity been applied to amplitudes?
     381      364420 : Bool VLAADA::nomSensApplied(VLAEnum::IF which,const uInt rev) const {
     382      364420 :   DebugAssert(ok(), AipsError);
     383             : 
     384             :   // Prior (exclusive) to rev 25, nominal sensitivity ALWAYS applied
     385      364420 :   if (rev < 25) return true;
     386             : 
     387             :   // Note that VLA Archive Data Format (May 1, 1996) doc has typo 
     388             :   // in section 2.3.  The ADA's IF control bits are in words 64-67
     389             :   //  (not 65-68).
     390             : 
     391       41284 :   Int64 where = itsOffset + 2*(64+which);
     392       41284 :   itsRecord.seek(where);
     393             :     
     394             :   Short bits;
     395       41284 :   itsRecord >> bits;
     396             :   // Bit 2 == Tsys Corr On  (0x2000 = 0010.0000.0000.0000)
     397       41284 :   return (bits & 0x2000);  
     398             : 
     399             : }
     400             : 
     401         522 : String VLAADA::arrayName() const {
     402             :   
     403             :   // For prepending to padName
     404             : 
     405         522 :   Int64 where = itsOffset + 2*(1);
     406         522 :   itsRecord.seek(where);
     407             :   
     408             :   Short bits;
     409         522 :   itsRecord >> bits;
     410             :   // Bit 9 == fiber (0x0040 = 0100.0000.0100.0000)
     411         522 :   Bool fiber = (bits & 0x0040);
     412             : 
     413             :   // VLBA and EVLA are connected by fiber
     414         522 :   if (fiber) {
     415             :     // It is a VLBA antenna (e.g. PT)
     416           0 :     if (antId()>28)
     417             :       //      return String("VLBA:");
     418           0 :       return String("VLA:_");
     419             :     else
     420             :       // evla
     421           0 :       return String("EVLA:");
     422             :   }
     423             :   // Otherwise this is just the old VLA
     424             :   //  (the underscore is so string length same as above, for AIPS)
     425         522 :   return String("VLA:_");
     426             :   
     427             : }
     428             : 
     429             : 
     430     3094160 : Bool VLAADA::ok() const {
     431             :   // The LogIO class is only constructed if an Error is detected for
     432             :   // performance reasons. Both function static and file static variables
     433             :   // where considered and rejected for this purpose.
     434             : 
     435             :   // This function fails (dumps core) if the itsRecord data member was
     436             :   // constructed using the default constructor. I need to add a isNull
     437             :   // function to the BaseSinkSource class to overcome this
     438     3094160 :   if (!itsRecord.isNull()) {
     439     3093730 :     if (!itsRecord.isReadable()) {
     440           0 :       LogIO logErr(LogOrigin("VLAADA", "ok()"));
     441             :       logErr << LogIO::SEVERE 
     442             :              << "The VLA logical record is not readable"
     443           0 :              << LogIO::POST;
     444           0 :       return false;
     445           0 :     }
     446     3093730 :     if (!itsRecord.isSeekable()) {
     447           0 :       LogIO logErr(LogOrigin("VLAADA", "ok()"));
     448             :       logErr << LogIO::SEVERE 
     449             :              << "The VLA logical record is not seekable"
     450           0 :              << LogIO::POST;
     451           0 :       return false;
     452           0 :     }
     453     3093730 :     if (itsOffset == 0) {
     454           0 :       LogIO logErr(LogOrigin("VLAADA", "ok()"));
     455             :       logErr << LogIO::SEVERE 
     456             :              << "The antenna data area cannot have a zero offset"
     457           0 :              << LogIO::POST;
     458           0 :       return false;
     459           0 :     }
     460             :   }
     461     3094160 :   return true;
     462             : }
     463             : 
     464             : // Local Variables: 
     465             : // compile-command: "gmake VLAADA"
     466             : // End: 

Generated by: LCOV version 1.16