LCOV - code coverage report
Current view: top level - alma/ASDM - ArrayTime.cc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 133 265 50.2 %
Date: 2023-10-25 08:47:59 Functions: 19 40 47.5 %

          Line data    Source code
       1             : /*
       2             :  * ALMA - Atacama Large Millimeter Array
       3             :  * (c) European Southern Observatory, 2002
       4             :  * (c) Associated Universities Inc., 2002
       5             :  * Copyright by ESO (in the framework of the ALMA collaboration),
       6             :  * Copyright by AUI (in the framework of the ALMA collaboration),
       7             :  * All rights reserved.
       8             :  * 
       9             :  * This library is free software; you can redistribute it and/or
      10             :  * modify it under the terms of the GNU Lesser General Public
      11             :  * License as published by the Free software Foundation; either
      12             :  * version 2.1 of the License, or (at your option) any later version.
      13             :  * 
      14             :  * This library is distributed in the hope that it will be useful,
      15             :  * but WITHOUT ANY WARRANTY, without even the implied warranty of
      16             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17             :  * Lesser General Public License for more details.
      18             :  * 
      19             :  * You should have received a copy of the GNU Lesser General Public
      20             :  * License along with this library; if not, write to the Free Software
      21             :  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
      22             :  * MA 02111-1307  USA
      23             :  *
      24             :  * File ArrayTime.cpp
      25             :  */
      26             : 
      27             : #include <cmath>
      28             : using std::fmod;
      29             : 
      30             : #include <alma/ASDM/ArrayTime.h>
      31             : 
      32             : #include <alma/ASDM/DoubleWrapper.h>
      33             : #include <alma/ASDM/LongWrapper.h>
      34             : #include <alma/ASDM/IntegerWrapper.h>
      35             : #include <alma/ASDM/InvalidArgumentException.h>
      36             : #include <alma/ASDM/NumberFormatException.h>
      37             : 
      38             : using namespace std;
      39             : 
      40             : namespace asdm {
      41             : 
      42             : #define UTCCorrectionLength 32
      43             :   static const UTCCorrection xUTCCorrectionTable [UTCCorrectionLength] = {
      44             :     //                                  JD                 TAI-UTC
      45             :     UTCCorrection(2438395.5,   3.2401300),      
      46             :     UTCCorrection(2438486.5,   3.3401300),
      47             :     UTCCorrection(2438639.5,   3.4401300),
      48             :     UTCCorrection(2438761.5,   3.5401300),
      49             :     UTCCorrection(2438820.5,   3.6401300),
      50             :     UTCCorrection(2438942.5,   3.7401300),
      51             :     UTCCorrection(2439004.5,   3.8401300),
      52             :     UTCCorrection(2439126.5,   4.3131700),
      53             :     UTCCorrection(2439887.5,   4.2131700),
      54             :     UTCCorrection(2441317.5,  10.0),
      55             :     UTCCorrection(2441499.5,  11.0),
      56             :     UTCCorrection(2441683.5,  12.0),
      57             :     UTCCorrection(2442048.5,  13.0),
      58             :     UTCCorrection(2442413.5,  14.0),
      59             :     UTCCorrection(2442778.5,  15.0),
      60             :     UTCCorrection(2443144.5,  16.0),
      61             :     UTCCorrection(2443509.5,  17.0),
      62             :     UTCCorrection(2443874.5,  18.0),
      63             :     UTCCorrection(2444239.5,  19.0),
      64             :     UTCCorrection(2444786.5,  20.0),
      65             :     UTCCorrection(2445151.5,  21.0),
      66             :     UTCCorrection(2445516.5,  22.0),
      67             :     UTCCorrection(2446247.5,  23.0),
      68             :     UTCCorrection(2447161.5,  24.0),
      69             :     UTCCorrection(2447892.5,  25.0),
      70             :     UTCCorrection(2448257.5,  26.0),
      71             :     UTCCorrection(2448804.5,  27.0),
      72             :     UTCCorrection(2449169.5,  28.0),
      73             :     UTCCorrection(2449534.5,  29.0),
      74             :     UTCCorrection(2450083.5,  30.0),
      75             :     UTCCorrection(2450630.5,  31.0),
      76             :     UTCCorrection(2451179.5,  32.0)
      77             :   };
      78             : 
      79             :   const UTCCorrection *ArrayTime::UTCCorrectionTable = &xUTCCorrectionTable[0];
      80             :   const UTCCorrection ArrayTime::UTCLast = UTCCorrectionTable [UTCCorrectionLength - 1];
      81             : 
      82             :   const double ArrayTime::unitsInADay                                                   = 86400000000000.0;
      83             :   const double ArrayTime::unitsInADayDiv100                             = 864000000000.0;
      84             :   const double ArrayTime::julianDayOfBase                                       = 2400000.5;
      85             : 
      86             :   /**
      87             :    * Return true if the specified year is a leap year.
      88             :    * @param year the year in the Gregorian calendar.
      89             :    * @return true if the specified year is a leap year.
      90             :    */
      91          21 :   bool ArrayTime::isLeapYear(int year) {
      92          21 :     if (year % 4 != 0)
      93           8 :       return false;
      94          13 :     if (year % 100 == 0 && year % 400 != 0)
      95           0 :       return false;
      96          13 :     return true;
      97             :   }
      98             : 
      99             :   /**
     100             :    * Return the Modified Julian day, given the Julian day.
     101             :    * @param jd The Julian day
     102             :    * @return The Modified Julian day
     103             :    */
     104           0 :   double ArrayTime::getMJD(double jd) {
     105           0 :     return jd - 2400000.5;
     106             :   }
     107             : 
     108             :   /**
     109             :    * Return the Julian day, given the Modified Julian day.
     110             :    * @param mjd The modified Julian day
     111             :    * @return the Julian day
     112             :    */
     113           0 :   double ArrayTime::getJD(double mjd) {
     114           0 :     return mjd + 2400000.5;
     115             :   }
     116             : 
     117             :   /**
     118             :    * Generate a new Time by adding an Interval
     119             :    * to the specified Time.
     120             :    * @param time The base Time 
     121             :    * @param interval The interval to be added to the base time.
     122             :    * @return A new Time formed by adding an Interval
     123             :    * to the specified Time. 
     124             :    */
     125           0 :   ArrayTime ArrayTime::add(const ArrayTime &time, const Interval & /* interval */) {
     126           0 :     ArrayTime t(time);
     127             :     //t.add(interval);
     128           0 :     return t;
     129             :   }
     130             : 
     131             :   /**
     132             :    * Generate a new Time by subtracting an Interval
     133             :    * from the specified Time.
     134             :    * @param time The base Time 
     135             :    * @param interval The interval to be subtracted from the base time.
     136             :    * @return A new Time formed by subtracting an Interval
     137             :    * from the specified Time. 
     138             :    */
     139           0 :   ArrayTime ArrayTime::sub(const ArrayTime &time, const Interval & /* interval */) {
     140           0 :     ArrayTime t(time);
     141             :     //t.sub(interval);
     142           0 :     return t;
     143             :   }
     144             : 
     145           0 :   ArrayTime ArrayTime::getArrayTime(StringTokenizer &t) {
     146           0 :     int64_t value = Long::parseLong(t.nextToken());
     147           0 :     return ArrayTime (value);
     148             :   }
     149             : 
     150             :   /**
     151             :    * Create a default Time, initialized to a value of zero.
     152             :    *
     153             :    */
     154     5029095 :   ArrayTime::ArrayTime() : Interval(0LL) {
     155     5029095 :   }
     156             : 
     157             :   /**
     158             :    * Create a Time from a string, which can be in one of three
     159             :    * formats:
     160             :    * <ul>
     161             :    * <li>A FITS formatted string,
     162             :    * <li>A modified Julian day, or, 
     163             :    * <li>An integer representing the number of  
     164             :    * nanoseconds since 15 October 1582 00:00:00 UTC.
     165             :    * </ul>
     166             :    * <p>
     167             :    * If the format is a FITS formatted string, its format must be 
     168             :    * of the following form:     
     169             :    *                    "YYYY-MM-DDThh:mm:ss.ssss"
     170             :    * Leading zeros are required if months, days, hours, minutes, or seconds 
     171             :    * are single digits.  The value for months ranges from "01" to "12".  
     172             :    * The "T" separting the data and time values is optional (which is a 
     173             :    * relaxation of the strict FITS standard).  If the "T" is 
     174             :    * not present, then a space MUST be present.
     175             :    * <p>
     176             :    * If the format is a modified Julian day, then the string value 
     177             :    * must be in the form of a double which MUST include a decimal point.
     178             :    * <p>
     179             :    * If the format is an interger, then it MUST represent the number of 
     180             :    * nanoseconds since 17 November 1858 00:00:00 UTC, the beginning of the 
     181             :    * modified Julian Day. 
     182             :    * 
     183             :    * @param s The string containing the initial value.
     184             :    */
     185       28108 :   ArrayTime::ArrayTime (const string &s) {
     186       28108 :     int64_t u = 0L;
     187       28108 :     if (s.find(':') != string::npos)
     188          83 :       u = FITSString(s);
     189             :     else {
     190       28025 :       if (s.find('.') != string::npos) {
     191           0 :         u = mjdToUnit(Double::parseDouble(s));
     192             :       } else {
     193       28025 :         u = Long::parseLong(s);
     194             :       }
     195             :     }
     196       28108 :     *this = u;
     197       28108 :   }
     198             : 
     199             :   /**
     200             :    * Create a Time that is initialized to a specified Time.
     201             :    * @param t
     202             :    */
     203    30355639 :   ArrayTime::ArrayTime(const ArrayTime &t) : Interval(t.get()) {
     204    30355639 :   }
     205             : 
     206             : #ifndef WITHOUT_ACS
     207             :   /**
     208             :    * Create a Time from an IDL time object.
     209             :    * @param t The IDL time object.
     210             :    */
     211             :   ArrayTime::ArrayTime (const asdmIDLTypes::IDLArrayTime &t) {
     212             :     *this = t.value;
     213             :   }
     214             : #endif
     215             : 
     216             :   /**
     217             :    * Create a Time by specifying the year, month, and day plus the fraction of a day.
     218             :    * @param year The yeay
     219             :    * @param month The month 
     220             :    * @param day the day (and time)
     221             :    */
     222           0 :   ArrayTime::ArrayTime(int year, int month, double day) :
     223           0 :     Interval(init(year,month,day)) {
     224           0 :   }
     225             : 
     226             :   /**
     227             :    * Create a Time by specifying the calendar date and the time.
     228             :    * @param year
     229             :    * @param month
     230             :    * @param day
     231             :    * @param hour
     232             :    * @param minute
     233             :    * @param second
     234             :    */
     235         110 :   ArrayTime::ArrayTime(int year, int month, int day, int hour, int minute, double second) : Interval(0L) {
     236         110 :     if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0.0 || second >= 60.0) {
     237           0 :       throw InvalidArgumentException("Invalid time");
     238             :     }
     239         110 :     *this = init(year,month,(double)(day + (((((second / 60.0) + minute) / 60.0) + hour) / 24.0)));
     240         110 :   }
     241             : 
     242             :   /**
     243             :    * Create a Time by specifying the modified Julian day.
     244             :    * @param modifiedJulianDay the modified Julian day, including fractions thereof.
     245             :    */
     246           9 :   ArrayTime::ArrayTime(double modifiedJulianDay) : 
     247           9 :     Interval(mjdToUnit(modifiedJulianDay)) {
     248           9 :   }
     249             : 
     250             :   /**
     251             :    * Create a Time by specifying the modified Julian day plus an additional factor
     252             :    * that designates the number of seconds and fractions in a day. 
     253             :    * @param modifiedJulianDay the Modified Julian day expressed as an interger
     254             :    * @param secondsInADay The number of seconds (with fractions) in this day.
     255             :    */
     256           0 :   ArrayTime::ArrayTime(int modifiedJulianDay, double secondsInADay) : 
     257           0 :     Interval(modifiedJulianDay * 8640000000000LL + (long)(secondsInADay * 100000000.0)) {
     258           0 :   }
     259             : 
     260             :   /**
     261             :    * Create a Time by specifying the number of  
     262             :    * nanoseconds since 17 November 1858 00:00:00 UTC, the beginning of the 
     263             :    * modified Julian Day.
     264             :    * @param tensOfNanoseconds  The number of  
     265             :    * nanoseconds since 17 November 1858 00:00:00 UTC, the beginning of the 
     266             :    * modified Julian Day.
     267             :    */
     268     9850356 :   ArrayTime::ArrayTime(int64_t nanoseconds) : Interval (nanoseconds) {
     269     9850356 :   }
     270             : 
     271             :   /**
     272             :    * Return the Julian day.
     273             :    * @return The Julian day as a double.
     274             :    */
     275           0 :   double ArrayTime::getJD() const {
     276           0 :     return unitToJD(get());
     277             :   }
     278             : 
     279             :   /**
     280             :    * Return the Modified Julian day.
     281             :    * @return The Modified Julian day as a double.
     282             :    */
     283      909179 :   double ArrayTime::getMJD() const {
     284      909179 :     return unitToMJD(get());
     285             :   }
     286             : 
     287             : #ifndef WITHOUT_ACS
     288             :   /**
     289             :    * Return an IDL Time object.
     290             :    * @return An IDL Time object.
     291             :    */
     292             :   asdmIDLTypes::IDLArrayTime ArrayTime::toIDLArrayTime() const {
     293             :     asdmIDLTypes::IDLArrayTime x;
     294             :     x.value = get();
     295             :     return x;
     296             :   }
     297             : #endif
     298             : 
     299             :   /**
     300             :    * Return this Time as a FITS formatted string, which is of the
     301             :    * form "YYYY-MM-DDThh:mm:ss.ssss".
     302             :    * @return This Time as a FITS formatted string.
     303             :    */
     304       14741 :   string ArrayTime::toFITS() const {
     305       14741 :     int *unit = getDateTime();
     306       14741 :     int yy = unit[0];
     307       14741 :     int mm = unit[1];
     308       14741 :     int dd = unit[2];
     309       14741 :     int hh = unit[3];
     310       14741 :     int min = unit[4];
     311       14741 :     int sec = unit[5];
     312       14741 :     string s = Integer::toString(yy); s += '-';
     313       14741 :     if (mm < 10) s += '0';
     314       14741 :     s += Integer::toString(mm); s += '-';
     315       14741 :     if (dd < 10) s += '0';
     316       14741 :     s += Integer::toString(dd); s += 'T';
     317       14741 :     if (hh < 10) s += '0';
     318       14741 :     s += Integer::toString(hh); s += ':';
     319       14741 :     if (min < 10) s += '0';
     320       14741 :     s += Integer::toString(min); s += ':';
     321       14741 :     if (sec < 10) s += '0';
     322       14741 :     s += Integer::toString(sec);
     323             :     // apply fractions of a second
     324       29482 :     string frac = Integer::toString(unit[6]);
     325       14741 :     s += '.';
     326             :     // The statement below is sensitive to the number of significant
     327             :     // digits in a fraction.  If units are nanoseconds,
     328             :     // then we need we will have 9 significant digits in a fraction 
     329             :     // string.
     330       29482 :     string tmp = "0000000000000000";
     331       14741 :     s += tmp.substr(0,numberSigDigitsInASecond - frac.length());
     332       14741 :     s += frac;
     333       14741 :     delete[] unit;
     334       29482 :     return s;
     335             :   }
     336             : 
     337         191 :   void ArrayTime::toBin(EndianOSStream& eoss) {
     338         191 :     eoss.writeLongLong( get());
     339         191 :   }
     340             : 
     341           0 :   void ArrayTime::toBin(const vector<ArrayTime>& arrayTime,  EndianOSStream& eoss) {
     342           0 :     eoss.writeInt((int) arrayTime.size());
     343           0 :     for (unsigned int i = 0; i < arrayTime.size(); i++)
     344           0 :       eoss.writeLongLong(arrayTime.at(i).get());
     345           0 :   }
     346             : 
     347           0 :   void ArrayTime::toBin(const vector<vector<ArrayTime> >& arrayTime,  EndianOSStream& eoss) {
     348           0 :     eoss.writeInt((int) arrayTime.size());
     349           0 :     eoss.writeInt((int) arrayTime.at(0).size());
     350           0 :     for (unsigned int i = 0; i < arrayTime.size(); i++)
     351           0 :       for (unsigned int j = 0; j < arrayTime.at(0).size(); j++)
     352           0 :         eoss.writeLongLong(arrayTime.at(i).at(j).get());
     353           0 :   }
     354             : 
     355           0 :   void ArrayTime::toBin(const vector< vector<vector<ArrayTime> > >& arrayTime,  EndianOSStream& eoss) {
     356           0 :     eoss.writeInt((int) arrayTime.size());
     357           0 :     eoss.writeInt((int) arrayTime.at(0).size());
     358           0 :     eoss.writeInt((int) arrayTime.at(0).at(0).size());  
     359           0 :     for (unsigned int i = 0; i < arrayTime.size(); i++)
     360           0 :       for (unsigned int j = 0; j < arrayTime.at(0).size(); j++)
     361           0 :         for (unsigned int k = 0; k < arrayTime.at(0).at(0).size(); j++)
     362           0 :           eoss.writeLongLong(arrayTime.at(i).at(j).at(k).get());
     363           0 :   }
     364             : 
     365       76508 :   ArrayTime ArrayTime::fromBin(EndianIStream & eis) {
     366       76508 :     return ArrayTime(eis.readLongLong());
     367             :   }
     368             : 
     369           0 :   vector<ArrayTime> ArrayTime::from1DBin(EndianIStream & eis) {
     370           0 :     int dim1 = eis.readInt();
     371           0 :     vector<ArrayTime> result;
     372           0 :     for (int i = 0; i < dim1; i++)
     373           0 :       result.push_back(ArrayTime(eis.readLongLong()));
     374           0 :     return result;      
     375             :   }
     376             : 
     377           0 :   vector<vector<ArrayTime > > ArrayTime::from2DBin(EndianIStream & eis) {
     378           0 :     int dim1 = eis.readInt();
     379           0 :     int dim2 = eis.readInt();
     380           0 :     vector< vector<ArrayTime> >result;
     381           0 :     vector <ArrayTime> aux;
     382           0 :     for (int i = 0; i < dim1; i++) {
     383           0 :       aux.clear();
     384           0 :       for (int j = 0; j < dim2; j++)
     385           0 :         aux.push_back(ArrayTime(eis.readLongLong()));
     386           0 :       result.push_back(aux);
     387             :     }
     388           0 :     return result;      
     389             :   }
     390             : 
     391           0 :   vector<vector<vector<ArrayTime > > > ArrayTime::from3DBin(EndianIStream & eis) {
     392           0 :     int dim1 = eis.readInt();
     393           0 :     int dim2 = eis.readInt();
     394           0 :     int dim3 = eis.readInt();
     395           0 :     vector<vector< vector<ArrayTime> > >result;
     396           0 :     vector < vector<ArrayTime> >aux1;
     397           0 :     vector <ArrayTime> aux2;
     398           0 :     for (int i = 0; i < dim1; i++) {
     399           0 :       aux1.clear();
     400           0 :       for (int j = 0; j < dim2; j++) {
     401           0 :         aux2.clear();
     402           0 :         for (int k = 0; k < dim3; k++)
     403           0 :           aux2.push_back(ArrayTime(eis.readLongLong()));
     404           0 :         aux1.push_back(aux2);
     405             :       }
     406           0 :       result.push_back(aux1);
     407             :     }
     408           0 :     return result;      
     409             :   }
     410             : 
     411             :   /**
     412             :    * Return this time as an array of integers denoting the following:
     413             :    * <ul>
     414             :    * <li>year,
     415             :    * <li>month (varies from 1 to 12),
     416             :    * <li>day (varies from 1 to 28, 29, 30, or 31),
     417             :    * <li>hour (varies from 0 to 23),
     418             :    * <li>minute (varies from 0 to 59),
     419             :    * <li>second (varies from 0 to 59), and
     420             :    * <li>the number of nanoseconds that remain in this fraction of a second.
     421             :    * </ul>
     422             :    * @return This time as an array of integers denoting year, month, day, hour, minute
     423             :    * second, and fraction of a second.
     424             :    */
     425       14741 :   int *ArrayTime::getDateTime() const {
     426       14741 :     int *n = new int [7];
     427       14741 :     int64_t fractionOfADay = get() % unitsInADayL;
     428       14741 :     if (fractionOfADay < 0)
     429           0 :       fractionOfADay = unitsInADayL - fractionOfADay;
     430       14741 :     int64_t nsec = fractionOfADay / unitsInASecond;
     431       14741 :     n[6] = (int)(fractionOfADay - (nsec * 1000000000LL));
     432       14741 :     int64_t nmin = nsec / 60L;
     433       14741 :     n[5] = (int)(nsec - nmin * 60L);
     434       14741 :     int64_t nhr = nmin / 60L;
     435       14741 :     n[4] = (int)(nmin - nhr * 60L);
     436       14741 :     n[3] = (int)nhr;
     437             : 
     438       14741 :     double jd = unitToJD(get());
     439             : 
     440             :     // For this algorithm see Meeus, chapter 7, p. 63.
     441       14741 :     double x = jd + 0.5; // Make the 12h UT adjustment.
     442       14741 :     int Z = (int)x;
     443       14741 :     double F = x - Z;
     444       14741 :     int A = Z;
     445       14741 :     int alpha = 0;
     446       14741 :     if (Z >= 2299161) {
     447       14741 :       alpha = (int)((Z - 1867216.25) / 36524.25);
     448       14741 :       A = Z + 1 + alpha - (int)(alpha / 4);
     449             :     }
     450       14741 :     int B = A + 1524;
     451       14741 :     int C = (int)((B - 122.1) / 365.25);
     452       14741 :     int D = (int)(365.25 * C);
     453       14741 :     int E = (int)((B - D) / 30.6001);
     454       14741 :     double day = B - D - (int)(30.6001 * E) + F;
     455       14741 :     int month = (E < 14) ? E - 1 : E - 13;
     456       14741 :     int year = (month > 2) ? C - 4716 : C - 4715;
     457             : 
     458       14741 :     n[2] = (int)day;
     459       14741 :     n[1] = month;
     460       14741 :     n[0] = year;
     461             : 
     462       14741 :     return n;
     463             :   }
     464             : 
     465             :   /**
     466             :    * Return the time of day in hours and fractions thereof. 
     467             :    * @return The time of day in hours.
     468             :    */
     469           0 :   double ArrayTime::getTimeOfDay() const {
     470           0 :     double x = unitToJD(get()) + 0.5;
     471           0 :     return (x - (int)x) * 24.0;
     472             :   }
     473             : 
     474             :   /**
     475             :    * Return the day number of the week of this Time.
     476             :    * The day numbers are 0-Sunday, 1-Monday, 2-Tuesday,
     477             :    * 3-Wednesday, 4-Thursday, 5-Friday, and 6-Saturday.
     478             :    * @return The day number of the week of this Time.
     479             :    */
     480           0 :   int ArrayTime::getDayOfWeek() const {
     481           0 :     return ((int)(unitToJD(get()) + 1.5)) % 7;
     482             :   }
     483             : 
     484             :   /**
     485             :    * Return the day number of the year of this Time.
     486             :    * @return The day number of the year of this Time.
     487             :    */
     488           0 :   int ArrayTime::getDayOfYear() const {
     489           0 :     int *n = getDateTime();
     490           0 :     int year = n[0];
     491           0 :     int month = n[1];
     492           0 :     int day = n[2];
     493           0 :     delete n;
     494           0 :     return ((275 * month) / 9) - 
     495           0 :       ((isLeapYear(year) ? 1 : 2) * ((month + 9) / 12)) + 
     496           0 :       day - 30;
     497             :   }
     498             : 
     499             :   /**
     500             :    * Return the time of day as a string, in the form
     501             :    * "hh:mm:ss".
     502             :    * @return The time of day as a string.
     503             :    */
     504           0 :   string ArrayTime::timeOfDayToString() const {
     505           0 :     int *n = getDateTime();
     506           0 :     int hh = n[3];
     507           0 :     int min = n[4];
     508           0 :     int sec = n[5];
     509           0 :     string s = "";
     510           0 :     if (hh < 10) s += '0'; else s += Integer::toString(hh); s += ':';
     511           0 :     if (min < 10) s += '0'; else s += Integer::toString(min); s += ':';
     512           0 :     if (sec < 10) s += '0'; else s += Integer::toString(sec);
     513           0 :     delete n;
     514           0 :     return s;
     515             :   }
     516             : 
     517             :   /**
     518             :    * Return the local sidereal time for this Time
     519             :    * in hours and fractions of an hour at the specified longitude.
     520             :    * @param longitudeInHours The desired longitude in hours.
     521             :    * @return The local sidereal time in hours.
     522             :    */
     523           0 :   double ArrayTime::getLocalSiderealTime(double longitudeInHours) const {
     524           0 :     return getGreenwichMeanSiderealTime() - longitudeInHours;
     525             :   }
     526             : 
     527             :   /**
     528             :    * Return the Greenwich mean sidereal time for this Time
     529             :    * in hours and fractions of an hour.
     530             :    * @return The Greenwich mean sidereal time in hours.
     531             :    */
     532           0 :   double ArrayTime::getGreenwichMeanSiderealTime() const {
     533           0 :     double jd = unitToJD(get());
     534           0 :     double t0 = jd - 2451545.0;
     535           0 :     double t = t0 / 36525.0;
     536           0 :     double tt = t * t;
     537           0 :     double x = (280.46061837 + 
     538           0 :                 360.98564736629 * t0 + 
     539           0 :                 tt * (0.000387933 - (t / 38710000.0))) / 15.0 ;
     540           0 :     double y = fmod(x,24.0);
     541           0 :     if (y < 0)
     542           0 :       y = 24.0 + y;        
     543           0 :     return y;
     544             :   }
     545             : 
     546         193 :   int64_t ArrayTime::init(int year, int month, double day) {
     547             :     // For this algorithm see Meeus, chapter 7, p. 61.
     548         193 :     int iday = (int)day;
     549         193 :     if (month < 1 || month > 12)
     550           0 :       throw InvalidArgumentException ("Illegal value of month");
     551         193 :     if ( (iday < 1 || iday > 31) ||
     552         407 :          ((month == 4 || month == 6 || month == 9 || month == 11) && iday > 30) ||
     553          21 :          (month == 2 && (iday > ((isLeapYear(year) ? 29 : 28)))) )
     554           0 :       throw InvalidArgumentException ("Illegal value of day");
     555         193 :     if (month <= 2) {
     556          25 :       --year;
     557          25 :       month += 12;
     558             :     }
     559         193 :     int A = year / 100;
     560         193 :     int B = 2 - A + (A / 4);
     561         193 :     double jd = (int)(365.25 * (year + 4716)) + (int)(30.6001 * (month + 1)) + iday + B - 1524.5;
     562         193 :     int64_t u = jdToUnit(jd);
     563             :     // Now add the fraction of a day.
     564         193 :     u += (int64_t)((day - iday) * unitsInADay + 0.5);
     565         193 :     return u;
     566             :   }
     567             : 
     568          83 :   int64_t ArrayTime::init(int year, int month, int day, int hour, int minute, double second) {
     569          83 :     if (hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0.0 || second >= 60.0) {
     570           0 :       throw InvalidArgumentException("Invalid time");
     571             :     }
     572          83 :     return init(year,month,(double)(day + (((((second / 60.0) + minute) / 60.0) + hour) / 24.0)));
     573             :   }
     574             : 
     575             :   /**
     576             :    * Return a unit of time, as a long, from a FITS-formatted string that 
     577             :    * specifies the time.  The format must be of the form:       
     578             :    *                    YYYY-MM-DDThh:mm:ss.ssss
     579             :    * Leading zeros are required if months, days, hours, minutes, or seconds 
     580             :    * are single digits.  The value for months ranges from "01" to "12".  
     581             :    * The "T" separting the data and time values is optional.  If the "T" is 
     582             :    * not present, then a space MUST be present.
     583             :    * 
     584             :    * An IllegalArgumentException is thrown is the string is not a valid 
     585             :    * time.
     586             :    */
     587          83 :   int64_t ArrayTime::FITSString(string t) const {
     588         166 :     if (t.length() < 19 || t.at(4) != '-' || t.at(7) != '-' || 
     589          83 :         (t.at(10) != 'T' && t.at(10) != ' ') || 
     590         166 :         t.at(13) != ':' || t.at(16) != ':')
     591           0 :       throw InvalidArgumentException("Invalid time format: " + t);
     592          83 :     int yyyy = 0;
     593          83 :     int mm = 0;
     594          83 :     int dd = 0;
     595          83 :     int hh = 0;
     596          83 :     int min = 0;
     597          83 :     double sec = 0.0;
     598             :     try {
     599          83 :       yyyy = Integer::parseInt(t.substr(0,4));
     600          83 :       mm   = Integer::parseInt(t.substr(5,2));
     601          83 :       dd   = Integer::parseInt(t.substr(8,2));
     602          83 :       hh   = Integer::parseInt(t.substr(11,2));
     603          83 :       min  = Integer::parseInt(t.substr(14,2));
     604          83 :       sec  = Double::parseDouble(t.substr(17,(t.length() - 17)));
     605           0 :     } catch (const NumberFormatException &err) {
     606           0 :       throw InvalidArgumentException("Invalid time format: " + t);
     607             :     }
     608          83 :     return init(yyyy,mm,dd,hh,min,sec);
     609             :   }
     610             : 
     611             :   /**
     612             :    * Convert a unit of time in units since the base time to a Julian day.
     613             :    * @param unit The unit to be converted.
     614             :    * @return The Julian day corresponding to the specified unit of time.
     615             :    */
     616       14741 :   double ArrayTime::unitToJD(int64_t unit) {
     617       14741 :     return (double)(unit) / unitsInADay + julianDayOfBase;
     618             :   }
     619             : 
     620             :   /**
     621             :    * Convert a unit of time in units since the base time to a Modified Julian day.
     622             :    * @param unit The unit to be converted.
     623             :    * @return The Modified Julian day corresponding to the specified unit of time.
     624             :    */
     625      909179 :   double ArrayTime::unitToMJD(int64_t unit) {
     626      909179 :     return (double)(unit) / unitsInADay;
     627             :   }
     628             : 
     629             :   /**
     630             :    * Convert a Julian day to a unit of time in tens of nanoseconds 
     631             :    * since 15 October 1582 00:00:00 UTC.
     632             :    * @param jd The Julian day to be converted.
     633             :    * @return The unit corresponding to the specified Julian day.
     634             :    */
     635         193 :   int64_t ArrayTime::jdToUnit(double jd) {
     636         193 :     return ((int64_t)(jd * unitsInADayDiv100) - julianDayOfBaseInUnitsInADayDiv100) * 100L;
     637             :   }
     638             : 
     639             :   /**
     640             :    * Convert a Modified Julian day to units since the base time.
     641             :    * @param mjd The Modified Julian day to be converted.
     642             :    * @return The unit corresponding to the specified Modified Julian day.
     643             :    */
     644           9 :   int64_t ArrayTime::mjdToUnit(double mjd) {
     645           9 :     return (int64_t)(mjd * unitsInADay);
     646             :   }
     647             : 
     648             :   /**
     649             :    * Return the TAI to UTC correction in units of seconds that must be applied
     650             :    * to a specified Julian Day, in other words return TAI time minus UCT time.
     651             :    * @param jd The Julian day for the TAI time.
     652             :    * @return The number of seconds that must be subtracted from the TAI time to get the 
     653             :    * correct UTC time.
     654             :    */
     655           0 :   double ArrayTime::utcCorrection(double jd) {
     656           0 :     if (jd > UTCLast.getJD())
     657           0 :       return UTCLast.getTAIMinusUTC();
     658           0 :     int i = UTCCorrectionLength - 1;
     659           0 :     for (; i >= 0; --i) {
     660           0 :       if (jd <= UTCCorrectionTable[i].getJD())
     661           0 :         break;
     662             :     }
     663           0 :     return UTCCorrectionTable[i].getTAIMinusUTC();
     664             :   }
     665             :   /*
     666             :   istream & operator >> ( istream &is, ArrayTime& x) {
     667             :     Interval::operator >> (is, x);
     668             :   }  
     669             :   */
     670             : } // End namespace asdm

Generated by: LCOV version 1.16