Changeset 22678
- Timestamp:
- Feb 26, 2009, 8:37:23 AM (17 years ago)
- Location:
- trunk/psLib/src/astro
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astro/psTime.c
r20595 r22678 9 9 * 10 10 * @author Ross Harman, MHPCC 11 * @author Paul Price, IfA 11 12 * 12 * @version $Revision: 1.117 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2008-11-09 00:30:07 $ 14 * 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii 13 * Copyright 2004-2009 Institute for Astronomy, University of Hawaii 16 14 */ 17 15 18 16 #ifdef HAVE_CONFIG_H 19 # include "config.h"17 #include "config.h" 20 18 #endif 21 19 … … 39 37 #include "psAssert.h" 40 38 41 #define MAX_STRING_LENGTH 256 42 43 /** Sidereal angular conversion from seconds to radians for GMST in seconds (i.e. pi/(180*240)) */ 44 #define S2R (7.272205216643039903848711535369e-5) 45 46 /** Two times pi with double precision accuracy */ 47 #define TWOPI (2.0*M_PI) 48 49 /** Conversion from radians to degrees */ 50 #define R2DEG = (180.0/M_PI) 51 52 /** Maximum length of time string */ 53 #define MAX_TIME_STRING_LENGTH 256 54 55 /** Seconds per minute */ 56 #define SEC_PER_MINUTE 60.0 57 58 /** Seconds per hour */ 59 #define SEC_PER_HOUR (60.0*SEC_PER_MINUTE) 60 61 /** Seconds per day */ 62 #define SEC_PER_DAY (24.0*SEC_PER_HOUR) 63 64 /** Seconds per year */ 65 #define SEC_PER_YEAR (365.0*SEC_PER_DAY) 66 67 /** Microseconds per day */ 68 #define NSEC_PER_DAY 86400000000000.0 69 70 // Time config file path 71 static char *timeConfig = NULL; 72 73 /** Time metadata read from config file */ 74 static psMetadata *timeMetadata = NULL; 75 76 // Offset to convert terrestrial time(TT) to international atomic time(TAI) 77 #define TAI_TT_OFFSET_SECONDS 32 78 #define TAI_TT_OFFSET_NANOSECONDS 184000000 79 80 // Offset from converting to MJD 81 #define MJD_EPOCH_OFFSET 40587.0 82 83 // Offset for converting to JD 84 #define JD_EPOCH_OFFSET 2440587.5 85 86 // Offset of year 0000 from epoch 87 #define YEAR_0000_SEC -62125920000 88 89 // Offset of year 9999 from epoch 90 #define YEAR_9999_SEC 253202544000 39 40 #define S2R (M_PI / (180.0 * 240.0)) /// Sidereal conversion: GMST in seconds to radians 41 #define R2DEG = (180.0/M_PI) /// Conversion from radians to degrees 42 #define MAX_STRING_LENGTH 256 /// Maximum length of string 43 #define MAX_TIME_STRING_LENGTH 256 /// Maximum length of time string 44 #define SEC_PER_MINUTE 60.0 /// Seconds per minute 45 #define SEC_PER_HOUR (60.0*SEC_PER_MINUTE) /// Seconds per hour 46 #define SEC_PER_DAY (24.0*SEC_PER_HOUR) /// Seconds per day 47 #define SEC_PER_YEAR (365.0*SEC_PER_DAY) /// Seconds per year 48 #define NSEC_PER_DAY (SEC_PER_DAY * 1000000000.0) /// Nanoseconds per day 49 50 #define MJD_EPOCH_OFFSET 40587.0 // Offset from converting to MJD 51 #define JD_EPOCH_OFFSET 2440587.5 // Offset for converting to JD 52 #define YEAR_0000_SEC -62125920000 // Offset of year 0000 from epoch 53 #define YEAR_9999_SEC 253202544000 // Offset of year 9999 from epoch 54 55 // Offset to convert terrestrial time (TT) to international atomic time (TAI) 56 #define TAI_TT_OFFSET_SECONDS 32 57 #define TAI_TT_OFFSET_NANOSECONDS 184000000 58 59 60 // Static global variables 61 static char *timeConfig = NULL; // Time config file path 62 static psMetadata *timeMetadata = NULL; // Time metadata read from config file 63 91 64 92 65 /** Static function prototypes */ … … 99 72 static psTime* convertTimeUTCUT1(psTime* time); 100 73 101 static bool p_psTimeInit(const char *fileName);74 static bool timeInit(const char *fileName); 102 75 103 76 /** Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 104 77 * terminated copy of the original input string. */ 105 static char *cleanString(char *inString, 106 int sLen) 107 { 108 char *ptrB = NULL; 109 char *ptrE = NULL; 110 char *cleaned = NULL; 111 112 ptrB = inString; 78 static char *cleanString(char *inString,// Input string 79 int sLen // Length of string 80 ) 81 { 82 char *ptrB = inString; // Pointer to start 113 83 114 84 // Skip over leading # or whitespace 115 while (isspace(*ptrB) || *ptrB =='#') {85 while (isspace(*ptrB) || *ptrB == '#') { 116 86 ptrB++; 117 87 } 118 88 119 89 // Skip over trailing whitespace, null terminators, and # characters 120 ptrE = inString + sLen - 1;121 while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {90 char *ptrE = inString + sLen - 1; // Pointer to end 91 while (isspace(*ptrE) || *ptrE == '\0' || *ptrE == '#') { 122 92 ptrE--; 123 93 } … … 127 97 128 98 // Adds '\0' to end of string and +1 to sLen 129 cleaned = psStringNCopy(ptrB, sLen); 130 131 return cleaned; 99 return psStringNCopy(ptrB, sLen); 132 100 } 133 101 134 102 /** Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 135 103 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 136 static char* getToken(char **inString, 137 char *delimiter, 138 psParseErrorType *status) 139 { 140 char *cleanToken = NULL; 141 int sLen = 0; 142 104 static char* getToken(char **inString, // Input string 105 char *delimiter, // Delimiter 106 psParseErrorType *status // Parsing status, returned 107 ) 108 { 143 109 // Skip over leading whitespace 144 while (isspace(**inString)) {110 while (isspace(**inString)) { 145 111 (*inString)++; 146 112 } 147 113 148 // Length of token, not including delimiter 149 sLen = strcspn(*inString, delimiter); 150 151 if(sLen) { 152 114 int sLen = strcspn(*inString, delimiter); // Length of token, not including delimiter 115 char *cleanToken = NULL; // Token, cleaned of delimiters 116 if (sLen) { 153 117 // Create new, cleaned, and null terminated token 154 118 cleanToken = cleanString(*inString, sLen); 155 119 156 120 // Move to end of token 157 // (*inString) += (sLen+1);158 121 (*inString) += sLen; 159 122 if (**inString != '\0' ) { 160 123 (*inString)++; 161 124 } 162 163 } else if(**inString!='\0' && sLen==0) { 125 } else if (**inString != '\0' && sLen == 0) { 164 126 *status = PS_PARSE_ERROR_GENERAL; 165 127 } … … 210 172 211 173 // Check if psTime tables are already loaded 212 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {174 if (!timeInit(p_psTimeConfigFilename(NULL))) { 213 175 *status = PS_LOOKUP_ERROR; 214 176 return NAN; … … 225 187 226 188 // Check if table not a metadata item 227 if (tableMetadataItem == NULL) {189 if (tableMetadataItem == NULL) { 228 190 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 229 191 tableName); … … 239 201 240 202 // Check if index within to/from range 241 if (index >= table->validFrom ) {242 if (index <= table->validTo) {203 if (index >= table->validFrom ) { 204 if (index <= table->validTo) { 243 205 // Attempt to interpolate table 244 206 result = psLookupTableInterpolate(table, index, column); 245 207 *status = PS_LOOKUP_SUCCESS; 246 if (!isnan(result)) {208 if (!isnan(result)) { 247 209 break; 248 210 } … … 258 220 } 259 221 260 bool p_psTimeInit(const char *fileName)222 static bool timeInit(const char *fileName) 261 223 { 262 224 psS32 numLines = 0; … … 270 232 char *tableName = NULL; 271 233 char *tableFormat = NULL; 272 char *fullTableName = NULL;273 psS32 i = 0;274 psS32 j = 0;275 234 psS32 numTables = 0; 276 235 psU32 nFail = 0; … … 283 242 char metadataTableNames[4][MAX_STRING_LENGTH] = {"daily", "eopc", "finals", "tai"}; 284 243 285 // Check if the p_psTimeInit has already been ran286 if (timeMetadata != NULL) {244 // Check if the timeInit has already been run 245 if (timeMetadata) { 287 246 return true; 288 247 } 289 248 249 // All memory allocated below is "persistent" 290 250 // XXX this is not thread safe as the persistence setting is global 291 const bool initialPersistence = 292 p_psMemAllocatePersistent(true); // All memory allocated below is "persistent" 251 const bool initialPersistence = p_psMemAllocatePersistent(true); // Initial setting of persistence 293 252 294 253 // Read config file 295 254 timeMetadata = psMetadataConfigRead(timeMetadata, &nFail, fileName, true); 296 if(timeMetadata == NULL) { 255 if (!timeMetadata) { 256 psError(PS_ERR_IO, false, "Unable to read time configuration file %s", fileName); 297 257 return false; 298 } else if(nFail != 0) { 258 } else if (nFail != 0) { 259 psError(PS_ERR_IO, false, "Failed to parse %d lines reading time configuration file %s", 260 nFail, fileName); 299 261 return false; 300 262 } … … 302 264 // Get number of tables 303 265 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.n"); 304 if (metadataItem == NULL) {266 if (metadataItem == NULL) { 305 267 p_psMemAllocatePersistent(initialPersistence); 306 268 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 312 274 // Get lower range of tables 313 275 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.from"); 314 if (metadataItem == NULL) {276 if (metadataItem == NULL) { 315 277 p_psMemAllocatePersistent(initialPersistence); 316 278 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 319 281 } 320 282 tablesFrom = psVectorCopy(tablesFrom, metadataItem->data.V, PS_TYPE_F64); 321 if (tablesFrom->n != numTables) {283 if (tablesFrom->n != numTables) { 322 284 p_psMemAllocatePersistent(initialPersistence); 323 285 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Incorrect vector size. Size: %ld, Expected %d."), tablesFrom->n, numTables); … … 328 290 // Get upper range of tables 329 291 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.to"); 330 if (metadataItem == NULL) {292 if (metadataItem == NULL) { 331 293 p_psMemAllocatePersistent(initialPersistence); 332 294 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 336 298 } 337 299 tablesTo = psVectorCopy(tablesTo, metadataItem->data.V, PS_TYPE_F64); 338 if (tablesTo->n != numTables) {300 if (tablesTo->n != numTables) { 339 301 p_psMemAllocatePersistent(initialPersistence); 340 302 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Incorrect vector size. Size: %ld, Expected %d."), tablesTo->n, numTables); … … 346 308 // Get index columns for the tables 347 309 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.index"); 348 if (metadataItem == NULL) {310 if (metadataItem == NULL) { 349 311 p_psMemAllocatePersistent(initialPersistence); 350 312 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Failed find '%s' in time metadata."), … … 355 317 } 356 318 tablesIndex = psVectorCopy(tablesIndex, metadataItem->data.V, PS_TYPE_S32); 357 if (tablesIndex->n != numTables) {319 if (tablesIndex->n != numTables) { 358 320 p_psMemAllocatePersistent(initialPersistence); 359 321 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Incorrect vector size. Size: %ld, Expected %d."),tablesIndex->n,numTables); … … 366 328 // Get path to time data files 367 329 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.dir"); 368 if (metadataItem == NULL) {330 if (metadataItem == NULL) { 369 331 p_psMemAllocatePersistent(initialPersistence); 370 332 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 379 341 // Table file names 380 342 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.files"); 381 if (metadataItem == NULL) {343 if (metadataItem == NULL) { 382 344 p_psMemAllocatePersistent(initialPersistence); 383 345 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), … … 394 356 // Get table format strings 395 357 metadataItem = psMetadataLookup(timeMetadata, "psLib.time.tables.format"); 396 if (metadataItem == NULL) {358 if (metadataItem == NULL) { 397 359 p_psMemAllocatePersistent(initialPersistence); 398 360 psError(PS_ERR_BAD_PARAMETER_VALUE,true, _("Failed find '%s' in time metadata."), … … 411 373 bool no_problem = true; // True if we've detected no errors 412 374 namesPtr = tableNames; 413 while((tableName=getToken(&namesPtr, " ", &status)) != NULL) { 414 415 // Form path with table name, adding one to length for last '/' that may not occur 416 // in string in cong file 417 fullTableName = (char*)psAlloc(strlen(tableDir)+strlen(tableName)+1+1); 418 419 // Old strings may come back from psAlloc(), so set initial position to EOL 420 fullTableName[0]='\0'; 421 strcat(fullTableName, tableDir); 422 strcat(fullTableName, "/"); 423 strcat(fullTableName, tableName); 375 int i; // Iterator 376 for (i = 0; (tableName = getToken(&namesPtr, " ", &status)) != NULL; i++) { 377 psString fullTableName = NULL; // Full path for table 378 psStringAppend(&fullTableName, "%s/%s", tableDir, tableName); 424 379 425 380 // Get table format 426 tableFormat = getToken(&formatPtr, ",",&status);427 if (tableFormat == NULL) {428 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem,_("Failed find '%s' in time metadata."),381 tableFormat = getToken(&formatPtr, ",", &status); 382 if (!tableFormat) { 383 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, _("Failed find '%s' in time metadata."), 429 384 "psLib.time.tables.format"); 430 385 no_problem = false; … … 432 387 433 388 // Create and read table 434 if (i < numTables) {389 if (i < numTables) { 435 390 table = psLookupTableAlloc(fullTableName, (const char*)tableFormat, tablesIndex->data.S32[i]); 436 391 numLines = psLookupTableRead(table); 437 392 } else { 438 393 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 439 _("Incorrect number of table files entered. Found: %d. Expected: %d."), i +1, numTables);394 _("Incorrect number of table files entered. Found: %d. Expected: %d."), i + 1, numTables); 440 395 no_problem = false; 441 396 } … … 443 398 // Place tables into metadata slightly altered names as keys to create consistent naming conventions 444 399 foundTable = false; 445 for (j=0; j<numTables; j++) {400 for (int j = 0; j < numTables; j++) { 446 401 metadataNamesPtr = strstr(tableName, metadataTableNames[j]); 447 if (metadataNamesPtr != NULL) {402 if (metadataNamesPtr != NULL) { 448 403 psMetadataAdd(timeMetadata, PS_LIST_TAIL, strcat(metadataTableNames[j], "Table"), 449 404 PS_DATA_LOOKUPTABLE, NULL, table); 450 405 foundTable = true; 451 } else if (foundTable==false && j==numTables-1) {406 } else if (foundTable == false && j == numTables - 1) { 452 407 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 453 408 _("Incorrect number of table files entered. Found: %d. Expected: %d."), j, numTables); … … 460 415 psFree(tableFormat); 461 416 psFree(table); 462 i++;463 417 } 464 418 465 419 p_psMemAllocatePersistent(initialPersistence); 466 420 467 if(numTables != i) { 468 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, _("Incorrect number of table files entered. Found: %d. Expected: %d."), i, numTables); 421 if (numTables != i) { 422 psError(PS_ERR_BAD_PARAMETER_VALUE, no_problem, 423 _("Incorrect number of table files entered. Found: %d. Expected: %d."), 424 i, numTables); 469 425 } 470 426 … … 481 437 bool p_psTimeFinalize(void) 482 438 { 483 if (timeMetadata != NULL) {439 if (timeMetadata != NULL) { 484 440 psFree(timeMetadata); 485 441 timeMetadata = NULL; … … 496 452 psTime* psTimeAlloc(psTimeType type) 497 453 { 498 psTime *outTime = NULL;499 500 454 // Error checks 501 if(type!=PS_TIME_TAI && type!=PS_TIME_UTC && type!=PS_TIME_UT1 && 502 type!=PS_TIME_TT) { 503 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 504 _("Specified type, %d, is not supported."), 505 type); 506 return NULL; 455 switch (type) { 456 case PS_TIME_TAI: 457 case PS_TIME_UTC: 458 case PS_TIME_UT1: 459 case PS_TIME_TT: 460 // No action 461 break; 462 default: 463 // Since we can never return NULL from an allocator 464 psAbort("Specified type, %d, is not supported.", type); 507 465 } 508 466 509 467 // Allocate memory for structure 510 outTime = (psTime*)psAlloc(sizeof(psTime));468 psTime *outTime = psAlloc(sizeof(psTime)); 511 469 psMemSetDeallocator(outTime, (psFreeFunc)timeFree); 470 512 471 // Initialize members 513 472 outTime->sec = 0; … … 522 481 bool psMemCheckTime(psPtr ptr) 523 482 { 524 return ( psMemGetDeallocator(ptr) == (psFreeFunc)timeFree);483 return (psMemGetDeallocator(ptr) == (psFreeFunc)timeFree); 525 484 } 526 485 … … 528 487 psTime* psTimeGetNow(psTimeType type) 529 488 { 530 struct timeval now;531 psTime *time = NULL;532 533 // Allocate psTime struct534 time = psTimeAlloc(type);535 536 // Verify time structure allocated537 if(time == NULL) {538 return NULL;539 }540 541 489 // Get the system time 542 // if (gettimeofday(&now, (struct timezone *)0) == -1) {490 struct timeval now; // Current time 543 491 if (gettimeofday(&now, 0) == -1) { 544 492 psError(PS_ERR_OS_CALL_FAILED, true, … … 547 495 } 548 496 497 // Allocate psTime struct 498 psTime *time = psTimeAlloc(type); // Container for current time 499 549 500 // Convert timeval time to psTime 550 501 time->sec = now.tv_sec; 551 time->nsec = now.tv_usec *1000;502 time->nsec = now.tv_usec * 1000; 552 503 553 504 // Add most leapseconds to UTC time to get TAI time if necessary 554 if (type == PS_TIME_TAI) {505 if (type == PS_TIME_TAI) { 555 506 time->sec += p_psTimeGetTAIDelta(time); 556 507 } … … 575 526 576 527 // Check for underflow in nsec 577 if (deltaNsec > time->nsec) {528 if (deltaNsec > time->nsec) { 578 529 // Borrow second 579 530 time->nsec += 1e9; … … 585 536 586 537 // Check for overflow in nsec 587 if (time->nsec >= 1e9) {538 if (time->nsec >= 1e9) { 588 539 time->nsec -= 1e9; 589 540 time->sec++; … … 595 546 // Check if leapsecond present in delta 596 547 deltaUTC = p_psTimeGetTAIDelta(time); 597 if (fabs(deltaTAI-deltaUTC) >= 1.0) {548 if (fabs(deltaTAI-deltaUTC) >= 1.0) { 598 549 time->sec++; 599 550 } … … 621 572 622 573 // Check for overflow in nsec 623 if (time->nsec >= 1e9) {574 if (time->nsec >= 1e9) { 624 575 time->nsec -= 1e9; 625 576 time->sec++; … … 641 592 642 593 // Check for overflow in nsec 643 if (time->nsec >= 1e9) {594 if (time->nsec >= 1e9) { 644 595 time->nsec -= 1e9; 645 596 time->sec++; … … 658 609 659 610 // Check for nsec underflow 660 if (TAI_TT_OFFSET_NANOSECONDS > time->nsec) {611 if (TAI_TT_OFFSET_NANOSECONDS > time->nsec) { 661 612 // Borrow second 662 613 time->sec--; … … 666 617 667 618 // Check for overflow in nsec 668 if (time->nsec >= 1e9) {619 if (time->nsec >= 1e9) { 669 620 time->nsec -= 1e9; 670 621 time->sec++; … … 685 636 686 637 // Since UTC is within 0.9 sec of UT1 then nsec member is the member affected 687 if ((ut1utc < 0) && (abs(ut1utc) > time->nsec)) {638 if ((ut1utc < 0) && (abs(ut1utc) > time->nsec)) { 688 639 // Borrow from sec 689 640 time->sec--; 690 if (time->leapsecond) {641 if (time->leapsecond) { 691 642 time->leapsecond = false; 692 643 } else { … … 699 650 700 651 // Check for overflow in nsec 701 if (time->nsec >= 1e9) {652 if (time->nsec >= 1e9) { 702 653 time->nsec -= 1e9; 703 654 time->sec++; 704 if (time->leapsecond) {655 if (time->leapsecond) { 705 656 time->leapsecond = false; 706 657 time->sec--; … … 724 675 725 676 // If the input type is UT1 then return time and generate error message 726 if (time->type == PS_TIME_UT1) {677 if (time->type == PS_TIME_UT1) { 727 678 psError(PS_ERR_BAD_PARAMETER_VALUE,true,"Cannot convert from UT1 time type"); 728 679 return NULL; … … 735 686 736 687 // Convert from TAI to UTC, TT, UT1 737 if (time->type == PS_TIME_TAI) {688 if (time->type == PS_TIME_TAI) { 738 689 // Convert from TAI to UTC 739 if (type == PS_TIME_UTC) {690 if (type == PS_TIME_UTC) { 740 691 time = convertTimeTAIUTC(time); 741 692 // Convert from TAI to TT 742 } else if (type == PS_TIME_TT) {693 } else if (type == PS_TIME_TT) { 743 694 time = convertTimeTAITT(time); 744 695 // Convert from TAI to UT1 745 } else if (type == PS_TIME_UT1) {696 } else if (type == PS_TIME_UT1) { 746 697 // Convert to UTC first 747 698 time = convertTimeTAIUTC(time); … … 754 705 } 755 706 // Convert from TT to TAI, UTC, UT1 756 } else if (time->type == PS_TIME_TT) {707 } else if (time->type == PS_TIME_TT) { 757 708 // Convert from TT to UTC 758 if (type == PS_TIME_UTC) {709 if (type == PS_TIME_UTC) { 759 710 // Convert to TAI time first 760 711 time = convertTimeTTTAI(time); … … 762 713 time = convertTimeTAIUTC(time); 763 714 // Convert from TT to TAI 764 } else if (type == PS_TIME_TAI) {715 } else if (type == PS_TIME_TAI) { 765 716 time = convertTimeTTTAI(time); 766 717 // Convert from TT to UT1 767 } else if (type == PS_TIME_UT1) {718 } else if (type == PS_TIME_UT1) { 768 719 // Convert to UTC first 769 720 // Convert to TAI time first … … 779 730 } 780 731 // Convert from UTC to TAI, TT, UT1 781 } else if (time->type == PS_TIME_UTC) {732 } else if (time->type == PS_TIME_UTC) { 782 733 // Convert UTC to TAI 783 if (type == PS_TIME_TAI) {734 if (type == PS_TIME_TAI) { 784 735 time = convertTimeUTCTAI(time); 785 736 // Convert UTC to TT 786 } else if (type == PS_TIME_TT) {737 } else if (type == PS_TIME_TT) { 787 738 // Convert to TAI time first 788 739 time = convertTimeUTCTAI(time); … … 790 741 time = convertTimeTAITT(time); 791 742 // Convert UTC to UT1 792 } else if (type == PS_TIME_UT1) {743 } else if (type == PS_TIME_UT1) { 793 744 time = convertTimeUTCUT1(time); 794 745 // Convert UTC to unknown time type … … 831 782 832 783 // Verify input time is not in UT1 seconds 833 if (time->type == PS_TIME_UT1) {784 if (time->type == PS_TIME_UT1) { 834 785 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),time->type); 835 786 return NAN; … … 864 815 // Calculate Greenwich Mean Sidereal Time (GMST) in radians. 865 816 // Equation set up to minimize multiplications. 866 gmstRad = fracDays *TWOPI867 + (const1+const2*tu+t*(const3+t*(const4+t*(const5+const6*t))))*S2R;817 gmstRad = fracDays * 2 * M_PI + 818 (const1 + const2 * tu + t * (const3 + t * (const4 + t * (const5 + const6 * t)))) * S2R; 868 819 869 820 // Place GMST between 0 and 2*pi 870 gmstRad = fmod(gmstRad, TWOPI);821 gmstRad = fmod(gmstRad, 2 * M_PI); 871 822 872 823 // Calculate Local Mean Sidereal Time (LMST) in radians … … 899 850 900 851 // Check for invalid bulletin specified 901 if ((bulletin != PS_IERS_A) && (bulletin != PS_IERS_B)) {852 if ((bulletin != PS_IERS_A) && (bulletin != PS_IERS_B)) { 902 853 psError(PS_ERR_BAD_PARAMETER_VALUE,true,"Invalid bulletin specified %d",bulletin); 903 854 return NAN; … … 905 856 906 857 // Check if psTime tables are already loaded 907 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {858 if (!timeInit(p_psTimeConfigFilename(NULL))) { 908 859 psError(PS_ERR_UNKNOWN, true, "failed to init time tables."); 909 860 return NAN; … … 911 862 912 863 // Set lookup table column based on Bullentin 913 if (bulletin == PS_IERS_A) {864 if (bulletin == PS_IERS_A) { 914 865 tableColumn = 3; 915 866 } else { … … 922 873 923 874 // Value could not be found through table lookup and interpolation 924 if (status == PS_LOOKUP_PAST_TOP) {875 if (status == PS_LOOKUP_PAST_TOP) { 925 876 926 877 // Date too early for tables. Get default time delta value from metadata, and issue warning. … … 929 880 // Lookup value from time metadata loaded from pslib.config 930 881 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.dut"); 931 if (tableMetadataItem == NULL) {882 if (tableMetadataItem == NULL) { 932 883 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 933 884 "psLib.time.before.dut"); … … 936 887 result = tableMetadataItem->data.F64; 937 888 938 } else if (status == PS_LOOKUP_PAST_BOTTOM) {889 } else if (status == PS_LOOKUP_PAST_BOTTOM) { 939 890 /* Date too late for tables. Issue warning and use following formulae for predicting 940 891 ahead of the most recent available table entry. … … 949 900 // Lookup values to calculate prediction 950 901 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.dut"); 951 if (tableMetadataItem == NULL) {902 if (tableMetadataItem == NULL) { 952 903 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 953 904 "psLib.time.predict.dut"); … … 958 909 959 910 // Calculate predication of future UT1-UTC 960 t = 2000.0 + (mjd - 51544.03)/365.2422; 961 dut2ut1 = 0.022*sin(TWOPI*t) - 0.012*cos(TWOPI*t) - 0.006*sin(4.0*M_PI*t) + 0.007*cos(4.0*M_PI*t); 962 result = dut->data.F64[0] + dut->data.F64[1]*(mjd - dut->data.F64[2]) - dut2ut1; 963 964 } else if(status != PS_LOOKUP_SUCCESS) { 911 t = 2000.0 + (mjd - 51544.03) / 365.2422; 912 dut2ut1 = 0.022 * sin(2 * M_PI * t) - 0.012 * cos(2 * M_PI * t) - 913 0.006 * sin(4.0 * M_PI * t) + 0.007 * cos(4.0 * M_PI * t); 914 result = dut->data.F64[0] + dut->data.F64[1] * (mjd - dut->data.F64[2]) - dut2ut1; 915 916 } else if (status != PS_LOOKUP_SUCCESS) { 965 917 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 966 918 return NAN; … … 1086 1038 PS_ASSERT_INT_WITHIN_RANGE(time->nsec,0,(psU32)((1e9)-1),NULL); 1087 1039 1088 if (time->type != PS_TIME_TAI) {1040 if (time->type != PS_TIME_TAI) { 1089 1041 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Specified type, %d, is incorrect."), time->type); 1090 1042 return NULL; … … 1092 1044 1093 1045 // Check if psTime tables are already loaded 1094 if (!p_psTimeInit(p_psTimeConfigFilename(NULL))) {1046 if (!timeInit(p_psTimeConfigFilename(NULL))) { 1095 1047 psError(PS_ERR_UNKNOWN, true, "failed to init time tables."); 1096 1048 return NULL; … … 1105 1057 1106 1058 // Value could not be found through table lookup and interpolation 1107 if (xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP) {1059 if (xStatus==PS_LOOKUP_PAST_TOP && yStatus==PS_LOOKUP_PAST_TOP) { 1108 1060 1109 1061 // Date too earlier for tables. Get default polar coodinate values from metadata, and issue warning. … … 1117 1069 1118 1070 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.xp"); 1119 if (tableMetadataItem == NULL) {1071 if (tableMetadataItem == NULL) { 1120 1072 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 1121 1073 _("Failed find '%s' in time metadata."), "psLib.time.before.xp"); … … 1125 1077 1126 1078 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.before.yp"); 1127 if (tableMetadataItem == NULL) {1079 if (tableMetadataItem == NULL) { 1128 1080 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.before.yp"); 1129 1081 return NULL; … … 1131 1083 y = tableMetadataItem->data.F64; 1132 1084 1133 } else if (xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM) {1085 } else if (xStatus==PS_LOOKUP_PAST_BOTTOM && yStatus==PS_LOOKUP_PAST_BOTTOM) { 1134 1086 1135 1087 /* Date too late for tables. Issue warning and use following formulae for predicting … … 1154 1106 // Get predicted MJD 1155 1107 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.mjd"); 1156 if (tableMetadataItem == NULL) {1108 if (tableMetadataItem == NULL) { 1157 1109 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), 1158 1110 "psLib.time.predict.mjd"); … … 1163 1115 // Get xp 1164 1116 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.xp"); 1165 if (tableMetadataItem == NULL) {1117 if (tableMetadataItem == NULL) { 1166 1118 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.predict.xp"); 1167 1119 return NULL; … … 1172 1124 // Get yp 1173 1125 tableMetadataItem = psMetadataLookup(timeMetadata, "psLib.time.predict.yp"); 1174 if (tableMetadataItem == NULL) {1126 if (tableMetadataItem == NULL) { 1175 1127 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "psLib.time.predict.yp"); 1176 1128 return NULL; … … 1180 1132 1181 1133 // Calculate "a" and "c" constants 1182 a = TWOPI*(mjd - mjdPred)/365.25;1183 c = TWOPI*(mjd - mjdPred)/435.0;1134 a = 2 * M_PI * (mjd - mjdPred) / 365.25; 1135 c = 2 * M_PI * (mjd - mjdPred) / 435.0; 1184 1136 1185 1137 // Calculate x and y polar coordinates … … 1196 1148 yp->data.F64[4]*sin(c); 1197 1149 1198 } else if (xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS) {1150 } else if (xStatus!=PS_LOOKUP_SUCCESS || yStatus!=PS_LOOKUP_SUCCESS) { 1199 1151 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 1200 1152 return NULL; … … 1226 1178 1227 1179 // Check if psTime tables are loaded/loadable 1228 if (! p_psTimeInit(p_psTimeConfigFilename(NULL))) {1180 if (!timeInit(p_psTimeConfigFilename(NULL))) { 1229 1181 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."), 1230 1182 p_psTimeConfigFilename(NULL)); … … 1234 1186 // Get table from metadata 1235 1187 tableMetadataItem = psMetadataLookup(timeMetadata, "taiTable"); 1236 if (tableMetadataItem == NULL) {1188 if (tableMetadataItem == NULL) { 1237 1189 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed find '%s' in time metadata."), "taiTable"); 1238 1190 return NAN; … … 1242 1194 1243 1195 // Determine Julian and modified Julian dates used in table lookup and time delta calculation 1244 if (time->sec < 0) {1196 if (time->sec < 0) { 1245 1197 // psTime earlier than epoch 1246 1198 jd = time->sec / SEC_PER_DAY - time->nsec / NSEC_PER_DAY + JD_EPOCH_OFFSET; … … 1253 1205 1254 1206 // Set ceiling of the julian date to the last entry in the lookup table 1255 if (table->validTo < jd) {1207 if (table->validTo < jd) { 1256 1208 jd = table->validTo; 1257 1209 } … … 1261 1213 1262 1214 // Check for successful interpolation 1263 if (results == NULL) {1215 if (results == NULL) { 1264 1216 psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed time table interpolation.")); 1265 1217 return NAN; … … 1272 1224 1273 1225 // If const3 not equal to zero solve for difference else floor of const1 1274 if (fabs(const3-0.0) > FLT_EPSILON) {1226 if (fabs(const3-0.0) > FLT_EPSILON) { 1275 1227 out = const1 + (mjd - const2) * const3; 1276 1228 } else { … … 1306 1258 1307 1259 // Verify time is UTC type 1308 if (utc->type != PS_TIME_UTC) {1260 if (utc->type != PS_TIME_UTC) { 1309 1261 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),utc->type); 1310 1262 return false; … … 1316 1268 1317 1269 // Check the absolute difference between the two times for leapsecond 1318 if (psTimeLeapSecondDelta(utc,prevUtc) >= 1.0) {1270 if (psTimeLeapSecondDelta(utc,prevUtc) >= 1.0) { 1319 1271 returnValue = true; 1320 1272 } else { … … 1343 1295 1344 1296 // Julian date conversion 1345 if (time2->sec < 0) {1297 if (time2->sec < 0) { 1346 1298 // psTime earlier than epoch 1347 1299 jd = time2->sec / SEC_PER_DAY - time2->nsec / NSEC_PER_DAY + JD_EPOCH_OFFSET; … … 1369 1321 1370 1322 // Modified Julian date conversion 1371 if (time2->sec < 0) {1323 if (time2->sec < 0) { 1372 1324 // psTime earlier than epoch 1373 1325 mjd = time2->sec / SEC_PER_DAY - time2->nsec / NSEC_PER_DAY + MJD_EPOCH_OFFSET; … … 1416 1368 1417 1369 // Check if time is UTC and leapsecond 1418 if (((time->type==PS_TIME_UTC)||(time->type==PS_TIME_UT1)) && (time->leapsecond)) {1370 if (((time->type==PS_TIME_UTC)||(time->type==PS_TIME_UT1)) && (time->leapsecond)) { 1419 1371 // Modify second to be 60 1420 1372 tempString[17] = '6'; … … 1487 1439 days = jd - 2440587.5; 1488 1440 seconds = days * SEC_PER_DAY; 1489 if (seconds < 0.0) {1441 if (seconds < 0.0) { 1490 1442 outTime->nsec = (seconds - (psS64)seconds) * -1000000000.0; // psTime earlier than epoch 1491 1443 } else { … … 1513 1465 seconds = days * SEC_PER_DAY; 1514 1466 1515 if (seconds < 0.0) {1467 if (seconds < 0.0) { 1516 1468 outTime->nsec = (seconds - (psS64)seconds) * -1000000000.0; // psTime earlier than epoch 1517 1469 } else { … … 1701 1653 1702 1654 // Make month in range 3..14 (treat Jan & Feb as months 13..14 of prev year) 1703 if ( month <= 2 )1655 if ( month <= 2 ) 1704 1656 { 1705 1657 temp = (14 - month) / 12; … … 1707 1659 year -= temp; 1708 1660 month += 12 * temp; 1709 } else if (month > 14)1661 } else if (month > 14) 1710 1662 { 1711 1663 temp = (month - 3) / 12; … … 1812 1764 1813 1765 // Convert time to TAI if necessary, but without changing input arguments 1814 if (time->type == PS_TIME_UTC) {1766 if (time->type == PS_TIME_UTC) { 1815 1767 tempTime = psTimeAlloc(PS_TIME_UTC); 1816 1768 tempTime->sec = time->sec; … … 1833 1785 1834 1786 // Convert result to same time type as input 1835 if (time->type == PS_TIME_UTC) {1787 if (time->type == PS_TIME_UTC) { 1836 1788 outTime = psTimeConvert(outTime, PS_TIME_UTC); 1837 1789 } … … 1858 1810 1859 1811 // Verify both times of the same type 1860 if (time1->type != time2->type) {1812 if (time1->type != time2->type) { 1861 1813 psError(PS_ERR_BAD_PARAMETER_VALUE,true,_("Specified type, %d, is incorrect."),time1->type); 1862 1814 return NAN; … … 1864 1816 1865 1817 // Convert time to TAI if necessary, but without changing input arguments 1866 if (time1->type == PS_TIME_UTC) {1818 if (time1->type == PS_TIME_UTC) { 1867 1819 tempTime1 = psTimeAlloc(PS_TIME_UTC); 1868 1820 tempTime1->sec = time1->sec; … … 1872 1824 tempTime1 = psMemIncrRefCounter((psTime*)time1); 1873 1825 } 1874 if (time2->type == PS_TIME_UTC) {1826 if (time2->type == PS_TIME_UTC) { 1875 1827 tempTime2 = psTimeAlloc(PS_TIME_UTC); 1876 1828 tempTime2->sec = time2->sec; -
trunk/psLib/src/astro/psTime.h
r17023 r22678 474 474 ); 475 475 476 // used by p_psEOCInit() 477 const char *p_psTimeConfigFilename(const char *filename); 476 /// Return the name of the configuration file used for time 477 /// 478 /// The name is derived first from the environment variable PS_CONFIG_FILE if set; next from a previously used 479 /// configuration file if available; finally from the default which is set at install time. 480 const char *p_psTimeConfigFilename(const char *filename // Filename to use, or NULL 481 ); 478 482 479 483 /// @}
Note:
See TracChangeset
for help on using the changeset viewer.
