src/sct_io.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 
00022 #include "scitime.h"
00023 
00024 int sct_set_jd (sct_time_ptr pElement, const double jd)
00025 {
00026     SCT_ACCURACY accuracy;
00027     double mjd2000;
00028     //Correct value from JD to MJD2000
00029     mjd2000 = jd - SCT_JD_TO_J2000;
00030     //Get accuracy automatically
00031     accuracy = sct_get_accuracy_from_jd(jd);
00032     //Set MJD2000 value
00033     return sct_set_mjd2000_acc(pElement, mjd2000, accuracy);
00034 }
00035 
00036 int sct_set_jd_acc (sct_time_ptr pElement, \
00037     const double jd, const SCT_ACCURACY accuracy)
00038 {
00039     double mjd2000;
00040     //Correct value from JD to MJD2000
00041     mjd2000 = jd - SCT_JD_TO_J2000;
00042     //Set MJD2000 value
00043     return sct_set_mjd2000_acc(pElement, mjd2000, accuracy);
00044 }
00045 
00046 int sct_set_mjd (sct_time_ptr pElement, const double mjd)
00047 {
00048     double mjd2000;
00049     SCT_ACCURACY accuracy;
00050     //Correct value from MJD to MJD2000
00051     mjd2000 = mjd - SCT_MJD_TO_J2000;
00052     //Get accuracy automatically
00053     accuracy = sct_get_accuracy_from_jd(mjd);
00054     //Set MJD2000 value
00055     return sct_set_mjd2000_acc(pElement, mjd2000, accuracy);
00056 }
00057 
00058 int sct_set_mjd_acc (sct_time_ptr pElement, \
00059     const double mjd, const SCT_ACCURACY accuracy)
00060 {
00061     double mjd2000;
00062     //Correct value from MJD to MJD2000
00063     mjd2000 = mjd - SCT_MJD_TO_J2000;
00064     //Set MJD2000 value
00065     return sct_set_mjd2000_acc(pElement, mjd2000, accuracy);
00066 }
00067 
00068 int sct_set_mjd2000 (sct_time_ptr pElement, const double mjd2000)
00069 {
00070     SCT_ACCURACY accuracy;
00071     //Get accuracy automatically
00072     accuracy = sct_get_accuracy_from_jd(mjd2000);
00073     return sct_set_mjd2000_acc(pElement, mjd2000, accuracy);
00074 }
00075 
00076 int sct_set_mjd2000_acc (sct_time_ptr pElement, \
00077     const double mjd2000, const SCT_ACCURACY accuracy)
00078 {
00079     double aux;
00080 
00081     //Check input pointer...
00082     if(pElement == NULL)
00083     {
00084         #ifdef SCT_DEBUG
00085             if(pElement == NULL)
00086             {
00087                 fprintf(stderr, \
00088                     "[scitime:%s] >> Unable to get element!\n", __FUNCTION__);
00089             }
00090         #endif
00091         //Ko, invalid pointer!
00092         return SCT_RET_INVALID_PTR;
00093     }
00094     //Set integer days
00095     pElement->days = (long)mjd2000;
00096     if(mjd2000 < 0)
00097     {
00098         pElement->days--;
00099     }
00100     //Get aux double with seconds
00101     aux = (mjd2000-pElement->days)*86400.0;
00102 
00103     //Set integer seconds
00104     pElement->secs = (long)aux;
00105 
00106     //Set integer femtoseconds
00107     pElement->fsecs = (int64_t)((aux-pElement->secs)*SCT_FSECS_IN_SEC);
00108 
00109     //Set accuracy
00110     pElement->accuracy = accuracy;
00111 
00112     //Set status
00113     pElement->status = SCT_STATUS_OK;
00114 
00115     //Ok, no problem
00116     return SCT_RET_OK;
00117 }
00118 
00119 
00120 int sct_set_YMDHMSF( \
00121     sct_time_ptr pElement, \
00122     const unsigned int year, \
00123     const unsigned int month, \
00124     const unsigned int day, \
00125     const unsigned int hour, \
00126     const unsigned int minute, \
00127     const unsigned int second, \
00128     const u_int64_t femtosecond)
00129 {
00130     double y;
00131     double m;
00132     double d;
00133     long jd;
00134     SCT_RET ret;
00135 
00136     //Check input values...
00137     //TODO!!!
00138 
00139     y = (double)year;
00140     m = (double)month,
00141     d = (double)day;
00142 
00143     // In the conversion from the Julian Calendar to the Gregorian 
00144     // Calendar the day after October 4, 1582 was October 15, 1582.
00145 
00146     // if the date is before October 15, 1582
00147     if(year < 1582 || \
00148         (year == 1582 && (month < 10 || (month == 10 && day < 15))))
00149     {
00150         jd = 1729777 + day + 367 * year \
00151             - ((long)(7 * ( y + 5001 + ((long)((m - 9) / 7))) / 4)) \
00152             + ((long)(275 * m / 9));
00153     }
00154     else   // after Oct 4, 1582 
00155     {
00156         jd = 1721029 + day + 367 * year \
00157             - ((long)(7 * (y + ((long)((m + 9) / 12))) / 4)) \
00158             - ((long)(3 * (((long)((y + (m - 9) / 7) / 100)) + 1) / 4)) \
00159             + ((long)(275 * m / 9));
00160 
00161         // catch century/non-400 non-leap years 
00162         if( (! (year % 100) && (year % 400) && month > 2 && month < 9) || 
00163             (!((year - 1) % 100) && ((year - 1) % 400) && month == 1) )
00164         {
00165             --jd;
00166         }
00167     }
00168     //Final adjustment
00169     jd--;
00170 
00171     //Set Y/M/D as a julian date epoch
00172     ret = sct_set_jd(pElement, ((double)(jd)+0.5)); //0.5 due to the JD offset
00173     if(ret != SCT_RET_OK)
00174     {
00175         return ret;
00176     }
00177 
00178     //Now, set H/M/S...
00179     pElement->secs = (hour * 3600) + (minute *60) + second;
00180 
00181     //Now, set F...
00182     pElement->fsecs = femtosecond;
00183 
00184     //Set accuracy
00185     pElement->accuracy = SCT_ACCURACY_FEMTOSECS;
00186 
00187     //Ok, no problem
00188     return SCT_RET_OK;
00189 }
00190 
00191 int sct_copy(sct_time_ptr pDest, const sct_time_ptr pSource)
00192 {
00193     //Check element
00194     if(pDest == NULL || pSource == NULL)
00195     {
00196         //Ko, invalid pointer!
00197         #ifdef SCT_DEBUG
00198             if(pDest == NULL)
00199             {
00200                 fprintf(stderr, \
00201                     "[scitime:%s] >>Unable to get destination element!\n",
00202                     __FUNCTION__);
00203             }
00204             if(pSource == NULL)
00205             {
00206                 fprintf(stderr, \
00207                     "[scitime:%s] >> Unable to get source element!\n",
00208                 __FUNCTION__);
00209             }
00210         #endif
00211         return SCT_RET_INVALID_PTR;
00212     }
00213     if(pSource->status == SCT_STATUS_NOT_INITIALISED)
00214     {
00215         #ifdef SCT_DEBUG
00216             fprintf(stderr, \
00217                 "[scitime:%s] >> Source element not initialised!\n",
00218                 __FUNCTION__);
00219         #endif
00220     }
00221 
00222     //Copy from source to dest...
00223     memcpy(pDest,pSource,sizeof(*pSource));
00224 
00225     //Ok, no problem
00226     return SCT_RET_OK;
00227 }
00228 
00229 int sct_set_delta_secs (sct_time_ptr pDelta, const double secs)
00230 {
00231     double aux;
00232 
00233     //Check element
00234     if(pDelta == NULL)
00235     {
00236         //Ko, invalid pointer!
00237         #ifdef SCT_DEBUG
00238             if(pDelta == NULL)
00239             {
00240                 fprintf(stderr, \
00241                     "[scitime:%s] >>Unable to get input delta element!\n",
00242                     __FUNCTION__);
00243             }
00244         #endif
00245         return SCT_RET_INVALID_PTR;
00246     }
00247 
00248     //Initialise delta element
00249     pDelta->status = SCT_STATUS_DELTA;
00250     pDelta->days = 0;
00251     pDelta->secs = 0;
00252     pDelta->fsecs = 0;
00253 
00254     //Find number of days...
00255     aux = secs;
00256     while(aux > SCT_SECS_IN_DAY)
00257     {
00258         pDelta->days++;
00259         aux -= SCT_SECS_IN_DAY;
00260     }
00261 
00262     //Find number of seconds...
00263     pDelta->secs = (int)aux;
00264 
00265     //Set number of femtoseconds...
00266     pDelta->fsecs = SCT_FSECS_IN_SEC*(int64_t)(aux-pDelta->secs);
00267 
00268     //Set accuracy
00269     pDelta->accuracy = sct_get_accuracy_from_secs(secs);
00270 
00271     //Ok, no problem
00272     return SCT_RET_OK;
00273 }
00274 
00275 int sct_clear(sct_time_ptr pElement)
00276 {
00277    //Check element
00278     if(pElement == NULL)
00279     {
00280         //Ko, invalid pointer!
00281         #ifdef SCT_DEBUG
00282            fprintf(stderr, "[scitime:%s] >>Unable to get input element!\n",
00283                 __FUNCTION__);
00284         #endif
00285         return SCT_RET_INVALID_PTR;
00286     }
00287 
00288     //Clear contents...
00289     pElement->days = 0;
00290     pElement->secs = 0;
00291     pElement->fsecs = 0;
00292     pElement->accuracy = SCT_ACCURACY_DAYS;
00293     pElement->status = SCT_STATUS_NOT_INITIALISED;
00294 
00295     //Ok, no problem
00296     return SCT_RET_OK;
00297 }
00298 
00299 
00300 int sct_get_jd(const sct_time_ptr pElement, double *pJd)
00301 {
00302     SCT_STATUS ret;
00303     double mjd2000;
00304 
00305     //Get MJD2000
00306     ret = sct_get_mjd2000(pElement, &mjd2000);
00307     if(ret != SCT_RET_OK)
00308     {
00309         return ret;
00310     }
00311     //Convert to MJD
00312     *pJd = mjd2000 + SCT_JD_TO_J2000;
00313 
00314     //Ok, no problem
00315     return SCT_RET_OK;
00316 }
00317 
00318 
00319 int sct_get_mjd(const sct_time_ptr pElement, double *pMjd)
00320 {
00321     SCT_STATUS ret;
00322     double mjd2000;
00323 
00324     //Get MJD2000
00325     ret = sct_get_mjd2000(pElement, &mjd2000);
00326     if(ret != SCT_RET_OK)
00327     {
00328         return ret;
00329     }
00330     //Convert to MJD
00331     *pMjd = mjd2000 + SCT_MJD_TO_J2000;
00332 
00333     //Ok, no problem
00334     return SCT_RET_OK;
00335 }
00336 
00337 
00338 int sct_get_mjd2000(const sct_time_ptr pElement, double *pMjd2000)
00339 {
00340     double aux;
00341 
00342     //Check element
00343     if(pElement->status != SCT_STATUS_OK)
00344     {
00345         #ifdef SCT_DEBUG
00346             fprintf(stderr,"[scitime:%s] >> Element not initialised!\n",
00347                 __FUNCTION__);
00348         #endif
00349         return SCT_RET_NOT_INITIALISED;
00350     }
00351 
00352     //Set seconds
00353     aux = pElement->secs + ((double)pElement->fsecs)*1E-15;
00354 
00355     //Set days + seconds
00356     *pMjd2000 = ((double)pElement->days)+(aux/SCT_SECS_IN_DAY);
00357 
00358     //Ok, no problem
00359     return SCT_RET_OK;
00360 }
00361 
00362 int sct_get_YMDHMSF ( \
00363     const sct_time_ptr pElement, \
00364     unsigned int *pYear, \
00365     unsigned int *pMonth, \
00366     unsigned int *pDay, \
00367     unsigned int *pHour, \
00368     unsigned int *pMinute, \
00369     unsigned int *pSecond, \
00370     u_int64_t    *pFemtosecond)
00371 {
00372     long L;
00373     long M;
00374     long N;
00375     long P;
00376     long Q;
00377     long JDl;
00378     int64_t aux;
00379 
00380 
00381     //Check input pointer...
00382     if(pElement == NULL)
00383     {
00384         #ifdef SCT_DEBUG
00385             if(pElement == NULL)
00386             {
00387                 fprintf(stderr, \
00388                     "[scitime:%s] >> Unable to get element!\n", __FUNCTION__);
00389             }
00390         #endif
00391         //Ko, invalid pointer!
00392         return SCT_RET_INVALID_PTR;
00393     }
00394 
00395     //Convert from MJD2000 to JD...
00396     JDl = pElement->days + SCT_JD_TO_J2000 +1;
00397 
00398     // In the conversion from the Julian Calendar to the Gregorian 
00399     // Calendar the day after October 4, 1582 was October 15, 1582.
00400 
00401     if(JDl > 2299160)    // after Oct 4, 1582
00402     {
00403         L = JDl + 68569;
00404         M = (4 * L) / 146097;
00405         L = L - ((146097 * M + 3) / 4);
00406         N = (4000 * (L + 1)) / 1461001;
00407         L = L - ((1461 * N) / 4) + 31;
00408         P = (80 * L) / 2447;
00409         *pDay = (int)(L - (2447 * P) / 80);
00410         L = P / 11;
00411         *pMonth = (int)(P + 2 - 12 * L);
00412         *pYear = (int)(100 * (M - 49) + N + L);
00413     }
00414     else 
00415     {
00416         P = JDl + 1402;
00417         Q = (P - 1) / 1461;
00418         L = P - 1461 * Q;
00419         M = (L - 1) / 365 - L / 1461;
00420         N = L - 365 * M + 30;
00421         P = (80 * N) / 2447;
00422         *pDay = (int)(N - (2447 * P) / 80);
00423         N = P / 11;
00424         *pMonth = (int)(P + 2 - 12 * N);
00425         *pYear = (int)(4 * Q + M + N - 4716);
00426         if(*pYear <= 0) 
00427         {
00428             --*pYear;
00429         }
00430     }
00431     //catch century/non-400 non-leap years
00432     if(*pYear > 1599 && 
00433        !(*pYear % 100) && 
00434        (*pYear % 400) && 
00435        *pMonth == 2 && 
00436        *pDay == 29)
00437     {
00438         *pMonth = 3;
00439         *pDay = 1;
00440     }
00441 
00442     //Get femtosecs
00443     *pFemtosecond = pElement->fsecs;
00444 
00445     //Get hours...
00446     *pHour = (int)(pElement->secs / 3600);
00447 
00448     //Get minutes...
00449     aux = pElement->secs % 3600;
00450     *pMinute = (int)(aux /60);
00451 
00452     //Get seconds...
00453     aux = aux % 60;
00454     *pSecond = (int)aux;
00455 
00456     //Ok, no problem
00457     return SCT_RET_OK;
00458 }
00459 
00460 int sct_get_delta_secs (const sct_time_ptr pDelta, double *pSecs)
00461 {
00462     //Check element
00463     if(pDelta == NULL || pSecs == NULL)
00464     {
00465         //Ko, invalid pointer!
00466         #ifdef SCT_DEBUG
00467             if(pDelta == NULL)
00468             {
00469                 fprintf(stderr, \
00470                     "[scitime:%s] >>Unable to get input delta element!\n",
00471                     __FUNCTION__);
00472             }
00473             if(pSecs == NULL)
00474             {
00475                 fprintf(stderr, "[scitime:%s] >> Unable to get output element!"
00476                     "\n", __FUNCTION__);
00477             }
00478         #endif
00479         return SCT_RET_INVALID_PTR;
00480     }
00481     if(pDelta->status != SCT_STATUS_DELTA)
00482     {
00483         #ifdef SCT_DEBUG
00484             if(pDelta->status != SCT_STATUS_DELTA)
00485             {
00486                 fprintf(stderr, "[scitime:%s] >> Delta element not "
00487                     "initialised as delta element!\n", __FUNCTION__);
00488             }
00489         #endif
00490         return SCT_RET_NOT_INITIALISED;
00491     }
00492 
00493     *pSecs = (SCT_SECS_IN_DAY * (double)pDelta->days)+ pDelta->secs + \
00494         (1E-15 * (double)pDelta->fsecs);
00495 
00496     //Ok, no problem
00497     return SCT_RET_OK;
00498 }
00499 
00500 int sct_print(const sct_time_ptr pElement)
00501 {
00502     switch(pElement->status)
00503     {
00504         case SCT_STATUS_NOT_INITIALISED:
00505             printf(">>>>>>>  Not Initialised  <<<<<<<\n");
00506             break;
00507         case SCT_STATUS_OK:
00508             printf(">>>>>>>  Epoch: %lld/%d/%lld, Acc: %d <<<<<<<\n",
00509                 pElement->days,
00510                 pElement->secs,
00511                 pElement->fsecs,
00512                 pElement->accuracy);
00513             break;
00514         case SCT_STATUS_DELTA:
00515             printf(">>>>>>>  Delta: %lld/%d/%lld, Acc: %d <<<<<<<\n",
00516                 pElement->days,
00517                 pElement->secs,
00518                 pElement->fsecs,
00519                 pElement->accuracy);
00520             break;
00521     }
00522     return SCT_RET_OK;
00523 }

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