IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 23625


Ignore:
Timestamp:
Mar 30, 2009, 10:24:58 PM (17 years ago)
Author:
Paul Price
Message:

Reworking to make time format consistent.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/concepts/pmConceptsStandard.c

    r23432 r23625  
    3333break;
    3434
     35
     36// Format type for time
     37typedef enum {
     38    TIME_FORMAT_ISO,                    // Date stored ISO (YYYY-MM-DD)
     39    TIME_FORMAT_BACKWARDS,              // Date stored backwards (DD-MM-YYYY)
     40    TIME_FORMAT_USA,                    // Date stored in USA order (MM-DD-YYYY)
     41    TIME_FORMAT_JD,                     // Date stored as JD
     42    TIME_FORMAT_MJD,                    // Date stored as MJD
     43} conceptTimeFormatType;
     44
     45// Format for time
     46typedef struct {
     47    conceptTimeFormatType format;       // Format type for time
     48    bool separate;                      // Date and time stored separately?
     49    bool pre2000;                       // Year is pre-2000 (two digits only)?
     50} conceptTimeFormat;
    3551
    3652
     
    630646}
    631647
     648static conceptTimeFormat conceptGetTimeFormat(const char *name, // Concept name ("CELL.TIME" or "FPA.TIME")
     649                                              const psMetadata *cameraFormat // Camera format
     650    )
     651{
     652    conceptTimeFormat time;               // Time format, to return
     653    time.format = TIME_FORMAT_ISO;
     654    time.separate = false;
     655    time.pre2000 = false;
     656
     657    bool mdok = true;                   // Status of MD lookup
     658    psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS"); // The formats
     659    if (mdok && formats) {
     660        psString format = psMetadataLookupStr(&mdok, formats, name); // The formats for eg, CELL.TIME
     661        if (mdok && format && strlen(format) > 0) {
     662            psList *formatList = psStringSplit(format, " ,;", false); // List of formats specified
     663            psListIterator *formatListIter = psListIteratorAlloc(formatList, PS_LIST_HEAD, false); // Iterator
     664            while ((format = psListGetAndIncrement(formatListIter))) {
     665                if (strcasecmp(format, "SEPARATE") == 0) {
     666                    time.separate = true;
     667                } else if (strcasecmp(format, "USA") == 0) {
     668                    time.format = TIME_FORMAT_USA;
     669                } else if (strcasecmp(format, "BACKWARDS") == 0) {
     670                    time.format = TIME_FORMAT_BACKWARDS;
     671                } else if (strcasecmp(format, "PRE2000") == 0) {
     672                    time.pre2000 = true;
     673                } else if (strcasecmp(format, "MJD") == 0) {
     674                    time.format = TIME_FORMAT_MJD;
     675                } else if (strcasecmp(format, "JD") == 0) {
     676                    time.format = TIME_FORMAT_JD;
     677                } else {
     678                    psWarning("Unrecognised FORMATS option for %s: %s --- ignored.", name, format);
     679                }
     680            }
     681            psFree(formatListIter);
     682            psFree(formatList);
     683        }
     684    }
     685
     686    return time;
     687}
     688
    632689// Determine the corresponding TIMESYS for one of the TIME concepts
    633690static psTimeType conceptGetTimesysForTime(const char *name, // Concept name ("CELL.TIME" or "FPA.TIME")
     
    734791    psTimeType timeSys = conceptGetTimesysForTime(pattern->name, fpa, chip, cell); // Time system
    735792
    736     // Work out how the time is represented
    737     bool separateTime = false;
    738     bool usaTime = false;               // Is the time specified in USA (MM-DD-YYYY) order?
    739     bool backwardsTime = false;         // Is the time specified in backwards (DD-MM-YYYY) order?
    740     bool yearFirst = false;            // Is the time specified in yearFirst (YYYY-MM-DD) order?
    741     bool pre2000Time = false;           // Is the time specified pre-2000 (where the year only has two digits)
    742     bool mjdTime = false;               // Is the time specified a MJD?
    743     bool jdTime = false;                // Is the time specified a JD?
    744 
    745     // Get format
    746     bool mdok;                          // Status of MD lookup
    747     psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS");
    748     if (!mdok || !formats) {
    749         psError(PS_ERR_UNKNOWN, true, "Unable to find FORMATS in camera configuration.\n");
    750         return NULL;
    751     }
    752 
    753     psString timeFormat = psMetadataLookupStr(&mdok, formats, pattern->name);
    754     if (!mdok || strlen(timeFormat) == 0) {
    755         psError(PS_ERR_UNKNOWN, true, "Unable to find %s in FORMATS.\n", pattern->name);
    756         return NULL;
    757     }
    758 
    759     // Parse the time format
    760     // why should more than one be allowed??
    761     psList *timeFormats = psStringSplit(timeFormat, " ,;", false); // List of the format options
    762     psListIterator *timeFormatsIter = psListIteratorAlloc(timeFormats, PS_LIST_HEAD, false); // Iter
    763     while ((timeFormat = psListGetAndIncrement(timeFormatsIter))) {
    764         if (strcasecmp(timeFormat, "SEPARATE") == 0) {
    765             separateTime = true;
    766         } else if (strcasecmp(timeFormat, "USA") == 0) {
    767             usaTime = true;
    768             backwardsTime = false;
    769             yearFirst = false;
    770             jdTime = false;
    771             mjdTime = false;
    772         } else if (strcasecmp(timeFormat, "BACKWARDS") == 0) {
    773             backwardsTime = true;
    774             usaTime = false;
    775             yearFirst = false;
    776             jdTime = false;
    777             mjdTime = false;
    778         } else if (strcasecmp(timeFormat, "YEAR.FIRST") == 0) {
    779             yearFirst = true;
    780             usaTime = false;
    781             backwardsTime = false;
    782             jdTime = false;
    783             mjdTime = false;
    784         } else if (strcasecmp(timeFormat, "PRE2000") == 0) {
    785             pre2000Time = true;
    786         } else if (strcasecmp(timeFormat, "MJD") == 0) {
    787             mjdTime = true;
    788             jdTime = false;
    789             yearFirst = false;
    790             backwardsTime = false;
    791             usaTime = false;
    792         } else if (strcasecmp(timeFormat, "JD") == 0) {
    793             jdTime = true;
    794             mjdTime = false;
    795             yearFirst = false;
    796             backwardsTime = false;
    797             usaTime = false;
    798         } else {
    799             psError(PS_ERR_UNKNOWN, true, "Unrecognised FORMATS option for %s: %s --- "
    800                     "ignored.\n", pattern->name, timeFormat);
    801             psFree(timeFormatsIter);
    802             psFree(timeFormats);
    803             return NULL;
    804         }
    805     }
    806     psFree(timeFormatsIter);
    807     psFree(timeFormats);
     793    conceptTimeFormat timeFormat = conceptGetTimeFormat(pattern->name, cameraFormat); // Format for time
    808794
    809795    psTime *time = NULL;                // The time
    810796    switch (concept->type) {
    811797      case PS_DATA_LIST: {
    812           if (!separateTime) {
     798          if (!timeFormat.separate) {
    813799              psWarning ("DATE and TIME stored separately, but not specified in format\n");
    814800          }
     
    837823              return NULL;
    838824          }
    839           if (backwardsTime) {
    840               // Need to switch days and years
    841               int temp = day;
    842               day = year;
    843               year = temp;
    844           }
    845           if (usaTime) {
    846               // Need to switch everything around.... Yanks!
    847               int temp = day;
    848               day = month;
    849               month = year;
    850               year = temp;
     825          switch (timeFormat.format) {
     826            case TIME_FORMAT_BACKWARDS: {
     827                // Need to switch days and years
     828                int temp = day;
     829                day = year;
     830                year = temp;
     831                break;
     832            }
     833            case TIME_FORMAT_USA: {
     834                // Need to switch everything around.... Yanks!
     835                int temp = day;
     836                day = month;
     837                month = year;
     838                year = temp;
     839                break;
     840            }
     841            default:
     842              break;
    851843          }
    852844          if (year < 100) {
    853               if (pre2000Time) {
     845              if (timeFormat.pre2000) {
    854846                  year += 1900;
    855847              } else {
     
    898890      case PS_DATA_STRING: {
    899891          psString timeString = concept->data.V;   // String with the time
    900           if (jdTime) {
    901               double timeValue = strtod (timeString, NULL);
    902               time = psTimeFromJD(timeValue);
    903           } else if (mjdTime) {
    904               double timeValue = strtod (timeString, NULL);
    905               time = psTimeFromMJD(timeValue);
    906           } else {
    907               // It's ISO
    908               time = psTimeFromISO(timeString, timeSys);
    909           } // Interpreting the time string
     892          switch (timeFormat.format) {
     893            case TIME_FORMAT_JD: {
     894                double timeValue = strtod (timeString, NULL);
     895                time = psTimeFromJD(timeValue);
     896                break;
     897            }
     898            case TIME_FORMAT_MJD: {
     899                double timeValue = strtod (timeString, NULL);
     900                time = psTimeFromMJD(timeValue);
     901                break;
     902            }
     903            case TIME_FORMAT_ISO: {
     904                // It's ISO
     905                time = psTimeFromISO(timeString, timeSys);
     906                break;
     907            }
     908            default:
     909              psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to interpret time string: %s", timeString);
     910              return NULL;
     911          }
    910912          break;
    911913      }
    912914      case PS_TYPE_F32: {
    913915          double timeValue = (double)concept->data.F32;
    914           if (jdTime) {
     916          switch (timeFormat.format) {
     917            case TIME_FORMAT_JD:
    915918              time = psTimeFromJD(timeValue);
    916           } else if (mjdTime) {
     919              break;
     920            case TIME_FORMAT_MJD:
    917921              time = psTimeFromMJD(timeValue);
    918           } else {
    919               psError(PS_ERR_UNKNOWN, true, "Not sure how to parse %s (%f) --- trying JD\n",
    920                       pattern->name, timeValue);
    921               time = psTimeFromJD(timeValue);
     922              break;
     923            default:
     924              psError(PS_ERR_UNKNOWN, true, "Unable to interpret time %s (%f)", pattern->name, timeValue);
     925              return NULL;
    922926          }
    923927          break;
     
    925929      case PS_TYPE_F64: {
    926930          double timeValue = (double)concept->data.F64;
    927           if (jdTime) {
     931          switch (timeFormat.format) {
     932            case TIME_FORMAT_JD:
    928933              time = psTimeFromJD(timeValue);
    929           } else if (mjdTime) {
     934              break;
     935            case TIME_FORMAT_MJD:
    930936              time = psTimeFromMJD(timeValue);
    931           } else {
    932               psError(PS_ERR_UNKNOWN, true, "Not sure how to parse %s (%f) --- trying JD\n",
    933                       pattern->name, timeValue);
    934               time = psTimeFromJD(timeValue);
     937              break;
     938            default:
     939              psError(PS_ERR_UNKNOWN, true, "Unable to interpret time %s (%f)", pattern->name, timeValue);
     940              return NULL;
    935941          }
    936942          break;
     
    946952    }
    947953
    948     if (jdTime || mjdTime) {
     954    // Set the time system appropriately
     955    switch (timeFormat.format) {
     956      case TIME_FORMAT_JD:
     957      case TIME_FORMAT_MJD:
    949958        conceptSetTimesysForTime(pattern->name, fpa, chip, cell, PS_TIME_TAI);
    950     } else {
     959        break;
     960      default:
    951961        time->type = timeSys;
     962        break;
    952963    }
    953964
     
    12111222    psTimeConvert(time, timeSys);
    12121223
    1213     // Work out the format
    1214     bool separateTime = false;          // Are the date and time stored separately?
    1215     bool pre2000Time = false;           // Is the year in pre-2000 format (two digits only)?
    1216     bool backwardsTime = false;         // Is the date stored backwards (DD-MM-YYYY)?
    1217     bool usaTime = false;               // Is the date stored in USA order (MM-DD-YYYY)?
    1218     bool jdTime = false;                // Is the date stored as a JD?
    1219     bool mjdTime = false;               // Is the date stored as a MJD?
    1220     bool yearFirst = false;
    1221 
    1222     bool mdok = true;                   // Status of MD lookup
    1223     psMetadata *formats = psMetadataLookupMetadata(&mdok, cameraFormat, "FORMATS"); // The formats
    1224     if (mdok && formats) {
    1225         psString format = psMetadataLookupStr(&mdok, formats, concept->name); // The formats for eg, CELL.TIME
    1226         if (mdok && format && strlen(format) > 0) {
    1227             psList *formatList = psStringSplit(format, " ,;", false); // List of formats specified
    1228             psListIterator *formatListIter = psListIteratorAlloc(formatList, PS_LIST_HEAD, false); // Iterator
    1229             while ((format = psListGetAndIncrement(formatListIter))) {
    1230                 if (strcasecmp(format, "SEPARATE") == 0) {
    1231                     separateTime = true;
    1232                 } else if (strcasecmp(format, "USA") == 0) {
    1233                     usaTime = true;
    1234                     backwardsTime = false;
    1235                     jdTime = false;
    1236                     mjdTime = false;
    1237                 } else if (strcasecmp(format, "BACKWARDS") == 0) {
    1238                     backwardsTime = true;
    1239                     usaTime = false;
    1240                     mjdTime = false;
    1241                     jdTime = false;
    1242                 } else if (strcasecmp(format, "YEAR.FIRST") == 0) {
    1243                     yearFirst = true;
    1244                     usaTime = false;
    1245                     backwardsTime = false;
    1246                     jdTime = false;
    1247                     mjdTime = false;
    1248                 } else if (strcasecmp(format, "PRE2000") == 0) {
    1249                     pre2000Time = true;
    1250                 } else if (strcasecmp(format, "MJD") == 0) {
    1251                     mjdTime = true;
    1252                     usaTime = false;
    1253                     backwardsTime = false;
    1254                     jdTime = false;
    1255                     separateTime = false;
    1256                 } else if (strcasecmp(format, "JD") == 0) {
    1257                     jdTime = true;
    1258                     usaTime = false;
    1259                     backwardsTime = false;
    1260                     mjdTime = false;
    1261                     separateTime = false;
    1262                 } else {
    1263                     psWarning("Unrecognised FORMATS option for %s: %s --- "
    1264                               "ignored.\n", concept->name, format);
    1265                 }
    1266             }
    1267             psFree(formatListIter);
    1268             psFree(formatList);
    1269         }
    1270     }
    1271 
    1272     if (separateTime) {
     1224    conceptTimeFormat timeFormat = conceptGetTimeFormat(concept->name, cameraFormat); // Format for time
     1225
     1226    if (timeFormat.separate) {
    12731227        // We're working with two separate headers --- construct a list with the date and time separately
    12741228        psString dateTimeString = psTimeToISO(time); // String representation
     
    12801234        // Need to format the strings....
    12811235        // XXX: Couldn't be bothered doing these right now
    1282         if (pre2000Time) {
     1236        if (timeFormat.pre2000) {
    12831237            psError(PS_ERR_UNKNOWN, true, "Don't you realise it's the twenty-first century?\n");
    12841238            return NULL;
    12851239        }
    1286         if (backwardsTime) {
    1287             int day, month, year;
    1288             psTrace ("psModules.concepts", 5, "ISO time has year first, convert to DD-MM-YYYY");
    1289             sscanf (dateString, "%d-%d-%d", &year, &month, &day);
    1290             sprintf (dateString, "%02d-%02d-%04d", day, month, year);
    1291             // XXX fix this for str length
    1292         }
    1293         if (usaTime) {
    1294             int day, month, year;
    1295             psTrace ("psModules.concepts", 5, "ISO time has year first, convert to MM-DD-YYYY");
    1296             sscanf (dateString, "%d-%d-%d", &year, &month, &day);
    1297             sprintf (dateString, "%02d-%02d-%04d", month, day, year);
    1298             // XXX fix this for str length
    1299         }
    1300         if (yearFirst) {
    1301             psTrace ("psModules.concepts", 5, "ISO time has year first, no adjustment needed");
     1240
     1241        switch (timeFormat.format) {
     1242          case TIME_FORMAT_BACKWARDS: {
     1243              int day, month, year;
     1244              psTrace ("psModules.concepts", 5, "ISO time has year first, convert to DD-MM-YYYY");
     1245              sscanf (dateString, "%d-%d-%d", &year, &month, &day);
     1246              sprintf (dateString, "%02d-%02d-%04d", day, month, year);
     1247              // XXX fix this for str length
     1248              break;
     1249          }
     1250          case TIME_FORMAT_USA: {
     1251              int day, month, year;
     1252              psTrace ("psModules.concepts", 5, "ISO time has year first, convert to MM-DD-YYYY");
     1253              sscanf (dateString, "%d-%d-%d", &year, &month, &day);
     1254              sprintf (dateString, "%02d-%02d-%04d", month, day, year);
     1255              // XXX fix this for str length
     1256              break;
     1257          }
     1258          default:
     1259            break;
    13021260        }
    13031261
     
    13131271        psListAdd(dateTime, PS_LIST_TAIL, timeItem);
    13141272
    1315         psMetadataItem *item = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST, concept->comment,
    1316                                                       dateTime);
    1317         psFree (dateItem);
    1318         psFree (timeItem);
    1319         psFree (dateTime);
     1273        psMetadataItem *item = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST,
     1274                                                      concept->comment, dateTime);
     1275        psFree(dateItem);
     1276        psFree(timeItem);
     1277        psFree(dateTime);
    13201278        return item;
    13211279    }
    1322     if (jdTime) {
    1323         double jd = psTimeToMJD(time);
    1324         return psMetadataItemAllocF64(concept->name, concept->comment, jd);
    1325     }
    1326     if (mjdTime) {
    1327         double mjd = psTimeToMJD(time);
    1328         return psMetadataItemAllocF64(concept->name, concept->comment, mjd);
    1329     }
    1330 
    1331     // If we've gotten this far, so it's straight ISO.
    1332     psString dateTimeString = psTimeToISO(time); // String representation
    1333     psMetadataItem *item = psMetadataItemAllocStr(concept->name, concept->comment, dateTimeString);
    1334     psFree(dateTimeString);
    1335     return item;
     1280
     1281    switch (timeFormat.format) {
     1282      case TIME_FORMAT_JD: {
     1283          double jd = psTimeToMJD(time);
     1284          return psMetadataItemAllocF64(concept->name, concept->comment, jd);
     1285      }
     1286      case TIME_FORMAT_MJD: {
     1287          double mjd = psTimeToMJD(time);
     1288          return psMetadataItemAllocF64(concept->name, concept->comment, mjd);
     1289      }
     1290      default: {
     1291          // If we've gotten this far, it's straight ISO.
     1292          psString dateTimeString = psTimeToISO(time); // String representation
     1293          psMetadataItem *item = psMetadataItemAllocStr(concept->name, concept->comment, dateTimeString);
     1294          psFree(dateTimeString);
     1295          return item;
     1296      }
     1297    }
     1298
     1299    return NULL;
    13361300}
    13371301
Note: See TracChangeset for help on using the changeset viewer.