src/sct_timescales.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Aleksander Morgado Juez                         *
00003  *   scitime@aleksander_morgado.mm.st                                      *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Library General Public License as       *
00007  *   published by the Free Software Foundation; either version 2 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU Library General Public     *
00016  *   License along with this program; if not, write to the                 *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "scitime.h"
00022 
00023 typedef struct _TAItoUTC_data {
00024     double      epochJD;            //Cols [18,26]
00025     double      leapSeconds;        //Cols [37,48]
00026     double      fact1;              //Cols [60,65]
00027     double      fact2;              //Cols [70,79]
00028 } TAItoUTC_data;                    //TAI-UTC=leapSeconds+(MJD-fact1)*fact2
00029 
00030 
00031 static const TAItoUTC_data _tai_to_utc[] = {
00032     { 2453736.5 ,  33.0     ,   41317.0 ,   0.0         },
00033     { 2451179.5 ,  32.0     ,   41317.0 ,   0.0         },
00034     { 2450630.5 ,  31.0     ,   41317.0 ,   0.0         },
00035     { 2450083.5 ,  30.0     ,   41317.0 ,   0.0         },
00036     { 2449534.5 ,  29.0     ,   41317.0 ,   0.0         },
00037     { 2449169.5 ,  28.0     ,   41317.0 ,   0.0         },
00038     { 2448804.5 ,  27.0     ,   41317.0 ,   0.0         },
00039     { 2448257.5 ,  26.0     ,   41317.0 ,   0.0         },
00040     { 2447892.5 ,  25.0     ,   41317.0 ,   0.0         },
00041     { 2447161.5 ,  24.0     ,   41317.0 ,   0.0         },
00042     { 2446247.5 ,  23.0     ,   41317.0 ,   0.0         },
00043     { 2445516.5 ,  22.0     ,   41317.0 ,   0.0         },
00044     { 2445151.5 ,  21.0     ,   41317.0 ,   0.0         },
00045     { 2444786.5 ,  20.0     ,   41317.0 ,   0.0         },
00046     { 2444239.5 ,  19.0     ,   41317.0 ,   0.0         },
00047     { 2443874.5 ,  18.0     ,   41317.0 ,   0.0         },
00048     { 2443509.5 ,  17.0     ,   41317.0 ,   0.0         },
00049     { 2443144.5 ,  16.0     ,   41317.0 ,   0.0         },
00050     { 2442778.5 ,  15.0     ,   41317.0 ,   0.0         },
00051     { 2442413.5 ,  14.0     ,   41317.0 ,   0.0         },
00052     { 2442048.5 ,  13.0     ,   41317.0 ,   0.0         },
00053     { 2441683.5 ,  12.0     ,   41317.0 ,   0.0         },
00054     { 2441499.5 ,  11.0     ,   41317.0 ,   0.0         },
00055     { 2441317.5 ,  10.0     ,   41317.0 ,   0.0         },
00056     { 2439887.5 ,   4.21317 ,   39126.0 ,   0.002592    },
00057     { 2439126.5 ,   4.31317 ,   39126.0 ,   0.002592    },
00058     { 2439004.5 ,   3.84013 ,   38761.0 ,   0.001296    },
00059     { 2438942.5 ,   3.74013 ,   38761.0 ,   0.001296    },
00060     { 2438820.5 ,   3.64013 ,   38761.0 ,   0.001296    },
00061     { 2438761.5 ,   3.54013 ,   38761.0 ,   0.001296    },
00062     { 2438639.5 ,   3.44013 ,   38761.0 ,   0.001296    },
00063     { 2438486.5 ,   3.34013 ,   38761.0 ,   0.001296    },
00064     { 2438395.5 ,   3.24013 ,   38761.0 ,   0.001296    },
00065     { 2438334.5 ,   1.945858,   37665.0 ,   0.0011232   },
00066     { 2437665.5 ,   1.845858,   37665.0 ,   0.0011232   },
00067     { 2437512.5 ,   1.372818,   37300.0 ,   0.001296    },
00068     { 2437300.5 ,   1.422818,   37300.0 ,   0.001296    },
00069     { NAN       ,   0.0     ,       0.0,    0.0         }
00070 };
00071 
00072 static double _sct_get_leapseconds_from_epoch(sct_time_ptr pElem);
00073 
00074 
00075 SCT_TIMESCALE sct_get_timescale (sct_time_ptr pElem)
00076 {
00077     return pElem->timescale;
00078 }
00079 
00080 SCT_RET sct_set_timescale (sct_time_ptr pElem, SCT_TIMESCALE timescale)
00081 {
00082     pElem->timescale = timescale;
00083     return  SCT_RET_OK;
00084 }
00085 
00086 SCT_RET sct_from_TAI_to_UTC (sct_time_ptr pElem)
00087 {
00088     double leapseconds;
00089     sct_time delta;
00090     #ifdef SCT_DEBUG
00091     if(pElem->timescale != SCT_TIMESCALE_TAI)
00092     {
00093         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00094             "UTC a time element which is NOT TAI.\n", __FUNCTION__);
00095     }
00096     #endif
00097 
00098     //Get leapseconds for this epoch...
00099     leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00100     if(isnan(leapseconds))
00101     {
00102         return SCT_RET_INVALID_LEAPSECONDS;
00103     }
00104     leapseconds *= (-1.0);
00105 
00106     //Set seconds in delta element...
00107     sct_set_delta_secs(&delta,leapseconds);
00108 
00109     //Add delta to output element
00110     sct_add_delta(pElem,pElem,&delta);
00111 
00112     //Set final timescale
00113     pElem->timescale = SCT_TIMESCALE_UTC;
00114 
00115     return SCT_RET_OK;
00116 }
00117 
00118 
00119 SCT_RET sct_from_TAI_to_GPS (sct_time_ptr pElem)
00120 {
00121     #ifdef SCT_DEBUG
00122     if(pElem->timescale != SCT_TIMESCALE_TAI)
00123     {
00124         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00125             "GPS a time element which is NOT TAI.\n", __FUNCTION__);
00126     }
00127     #endif
00128 
00129     //The difference between TAI and GPS is always SCT_GPS_TAI_LEAPSECOND
00130     // (GPS is behind TAI)
00131     sct_add_deltaDSF(pElem,pElem,0,-SCT_GPS_TAI_LEAPSECOND,0);
00132 
00133     //Set final timescale
00134     pElem->timescale = SCT_TIMESCALE_GPS;
00135 
00136     return SCT_RET_OK;
00137 }
00138 
00139 
00140 SCT_RET sct_from_TAI_to_UT (sct_time_ptr pElem)
00141 {
00142     #ifdef SCT_DEBUG
00143     if(pElem->timescale != SCT_TIMESCALE_TAI)
00144     {
00145         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from TAI to"
00146             "UT a time element which is NOT TAI.\n", __FUNCTION__);
00147     }
00148     #endif
00149 
00150     //Set final timescale
00151     pElem->timescale = SCT_TIMESCALE_UT;
00152 
00153     return SCT_RET_OK;
00154 }
00155 
00156 
00157 SCT_RET sct_from_UTC_to_TAI (sct_time_ptr pElem)
00158 {
00159     double leapseconds;
00160     sct_time delta;
00161 
00162     #ifdef SCT_DEBUG
00163     if(pElem->timescale != SCT_TIMESCALE_UTC)
00164     {
00165         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00166             "TAI a time element which is NOT UTC.\n", __FUNCTION__);
00167     }
00168     #endif
00169 
00170     //Get leapseconds for this epoch...
00171     leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00172     if(isnan(leapseconds))
00173     {
00174         return SCT_RET_INVALID_LEAPSECONDS;
00175     }
00176 
00177     //Set seconds in delta element...
00178     sct_set_delta_secs(&delta,leapseconds);
00179 
00180     //Add delta to output element
00181     sct_add_delta(pElem,pElem,&delta);
00182 
00183     //Set final timescale
00184     pElem->timescale = SCT_TIMESCALE_TAI;
00185 
00186     return SCT_RET_OK;
00187 }
00188 
00189 
00190 SCT_RET sct_from_UTC_to_GPS (sct_time_ptr pElem)
00191 {
00192     double leapseconds;
00193     sct_time delta;
00194 
00195     #ifdef SCT_DEBUG
00196     if(pElem->timescale != SCT_TIMESCALE_UTC)
00197     {
00198         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00199             "GPS a time element which is NOT UTC.\n", __FUNCTION__);
00200     }
00201     #endif
00202 
00203     //Get leapseconds for this epoch...
00204     leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00205     if(isnan(leapseconds))
00206     {
00207         return SCT_RET_INVALID_LEAPSECONDS;
00208     }
00209 
00210     //Set seconds in delta element... 
00211     sct_set_delta_secs(&delta,leapseconds);
00212 
00213     //Add delta to output element (so converting to TAI)
00214     sct_add_delta(pElem,pElem,&delta);
00215 
00216     //The difference between TAI and GPS is always SCT_GPS_TAI_LEAPSECOND
00217     // (GPS is behind TAI)
00218     sct_add_deltaDSF(pElem,pElem,0,-SCT_GPS_TAI_LEAPSECOND,0);
00219 
00220     //Set final timescale
00221     pElem->timescale = SCT_TIMESCALE_GPS;
00222 
00223     return SCT_RET_OK;
00224 }
00225 
00226 
00227 SCT_RET sct_from_UTC_to_UT (sct_time_ptr pElem)
00228 {
00229     #ifdef SCT_DEBUG
00230     if(pElem->timescale != SCT_TIMESCALE_UTC)
00231     {
00232         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UTC to"
00233             "UT a time element which is NOT UTC.\n", __FUNCTION__);
00234     }
00235     #endif
00236 
00237     //Set final timescale
00238     pElem->timescale = SCT_TIMESCALE_UT;
00239 
00240     return SCT_RET_OK;
00241 }
00242 
00243 
00244 SCT_RET sct_from_GPS_to_TAI (sct_time_ptr pElem)
00245 {
00246     #ifdef SCT_DEBUG
00247     if(pElem->timescale != SCT_TIMESCALE_GPS)
00248     {
00249         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00250             "TAI a time element which is NOT GPS.\n", __FUNCTION__);
00251     }
00252     #endif
00253 
00254     //The difference between TAI and GPS is always SCT_GPS_TAI_LEAPSECOND
00255     // (GPS is behind TAI)
00256     sct_add_deltaDSF(pElem,pElem,0,SCT_GPS_TAI_LEAPSECOND,0);
00257 
00258     //Set final timescale
00259     pElem->timescale = SCT_TIMESCALE_TAI;
00260 
00261     return SCT_RET_OK;
00262 }
00263 
00264 
00265 SCT_RET sct_from_GPS_to_UTC (sct_time_ptr pElem)
00266 {
00267     double leapseconds;
00268     sct_time delta;
00269 
00270     #ifdef SCT_DEBUG
00271     if(pElem->timescale != SCT_TIMESCALE_GPS)
00272     {
00273         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00274             "UTC a time element which is NOT GPS.\n", __FUNCTION__);
00275     }
00276     #endif
00277 
00278     //The difference between TAI and GPS is always SCT_GPS_TAI_LEAPSECOND
00279     // (GPS is behind TAI)... so converting to TAI
00280     sct_add_deltaDSF(pElem,pElem,0,SCT_GPS_TAI_LEAPSECOND,0);
00281 
00282     //Get leapseconds for this epoch...
00283     leapseconds = _sct_get_leapseconds_from_epoch(pElem);
00284     if(isnan(leapseconds))
00285     {
00286         return SCT_RET_INVALID_LEAPSECONDS;
00287     }
00288     leapseconds *= (-1.0);
00289 
00290     //Set seconds in delta element...
00291     sct_set_delta_secs(&delta,leapseconds);
00292 
00293     //Add delta to output element (so converting to UTC)
00294     sct_add_delta(pElem,pElem,&delta);
00295 
00296     //Set final timescale
00297     pElem->timescale = SCT_TIMESCALE_UTC;
00298 
00299     return SCT_RET_OK;
00300 }
00301 
00302 
00303 SCT_RET sct_from_GPS_to_UT (sct_time_ptr pElem)
00304 {
00305     #ifdef SCT_DEBUG
00306     if(pElem->timescale != SCT_TIMESCALE_GPS)
00307     {
00308         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from GPS to"
00309             "UT a time element which is NOT GPS.\n", __FUNCTION__);
00310     }
00311     #endif
00312 
00313     //Set final timescale
00314     pElem->timescale = SCT_TIMESCALE_UT;
00315 
00316     return SCT_RET_OK;
00317 }
00318 
00319 
00320 SCT_RET sct_from_UT_to_TAI (sct_time_ptr pElem)
00321 {
00322     #ifdef SCT_DEBUG
00323     if(pElem->timescale != SCT_TIMESCALE_UT)
00324     {
00325         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00326             "TAI a time element which is NOT UT.\n", __FUNCTION__);
00327     }
00328     #endif
00329 
00330     //Set final timescale
00331     pElem->timescale = SCT_TIMESCALE_TAI;
00332 
00333     return SCT_RET_OK;
00334 }
00335 
00336 
00337 SCT_RET sct_from_UT_to_GPS (sct_time_ptr pElem)
00338 {
00339     #ifdef SCT_DEBUG
00340     if(pElem->timescale != SCT_TIMESCALE_UT)
00341     {
00342         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00343             "GPS a time element which is NOT UT.\n", __FUNCTION__);
00344     }
00345     #endif
00346 
00347     //Set final timescale
00348     pElem->timescale = SCT_TIMESCALE_GPS;
00349 
00350     return SCT_RET_OK;
00351 }
00352 
00353 
00354 SCT_RET sct_from_UT_to_UTC (sct_time_ptr pElem)
00355 {
00356     #ifdef SCT_DEBUG
00357     if(pElem->timescale != SCT_TIMESCALE_UT)
00358     {
00359         fprintf(stderr, "[scitime:%s] >> Warning! Trying to convert from UT to"
00360             "UTC a time element which is NOT UT.\n", __FUNCTION__);
00361     }
00362     #endif
00363 
00364     //Set final timescale
00365     pElem->timescale = SCT_TIMESCALE_UTC;
00366 
00367     return SCT_RET_OK;
00368 }
00369 
00370 
00371 static double _sct_get_leapseconds_from_epoch(sct_time_ptr pElem)
00372 {
00373     extern const TAItoUTC_data _tai_to_utc[];
00374     int ind = 0;
00375     double elementJD;
00376 
00377     //Get JD epoch...
00378     sct_get_jd(pElem,&elementJD);
00379 
00380     //Loop the TAI-UTC data...
00381     while(!isnan(_tai_to_utc[ind].epochJD))
00382     {
00383         //Compare epochs...
00384         if(elementJD > _tai_to_utc[ind].epochJD)
00385         {
00386             //Ok, get leapseconds for this epoch...
00387             if(_tai_to_utc[ind].fact2 == 0.0)
00388                 return _tai_to_utc[ind].leapSeconds;
00389             else
00390             {
00391                 double elementMJD;
00392                 sct_get_mjd(pElem,&elementMJD);
00393                 return ( _tai_to_utc[ind].leapSeconds + \
00394                          (elementMJD - _tai_to_utc[ind].fact1) * \
00395                          _tai_to_utc[ind].fact2);
00396             }
00397         }
00398         //Update index...
00399         ind++;
00400     }
00401 
00402     return NAN;
00403 }
00404 

Generated on Sun May 20 15:32:42 2007 for scitime by  doxygen 1.5.1