IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 26, 2009, 1:59:32 PM (17 years ago)
Author:
beaumont
Message:

merged with trunk

Location:
branches/cnb_branches/cnb_branch_20090301
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/cnb_branches/cnb_branch_20090301

  • branches/cnb_branches/cnb_branch_20090301/psModules

  • branches/cnb_branches/cnb_branch_20090301/psModules/src/concepts/pmConceptsStandard.c

    r23594 r24244  
    3333break;
    3434
     35
     36// Format type for time
     37typedef enum {
     38  TIME_FORMAT_YYYYMMDD,                 // Date stored in YYYY-MM-DD order (ISO-standard)
     39  TIME_FORMAT_DDMMYYYY,                 // Date stored in DD-MM-YYYY order
     40  TIME_FORMAT_MMDDYYYY,                 // Date stored in MM-DD-YYYY order
     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_YYYYMMDD;
     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, "YYYYMMDD") == 0) {
     668                    time.format = TIME_FORMAT_YYYYMMDD;
     669                } else if (strcasecmp(format, "MMDDYYYY") == 0) {
     670                    time.format = TIME_FORMAT_MMDDYYYY;
     671                } else if (strcasecmp(format, "DDMMYYYY") == 0) {
     672                    time.format = TIME_FORMAT_DDMMYYYY;
     673                } else if (strcasecmp(format, "ISO") == 0) {
     674                    time.format = TIME_FORMAT_YYYYMMDD;
     675                } else if (strcasecmp(format, "YEAR.FIRST") == 0) {
     676                    time.format = TIME_FORMAT_YYYYMMDD;
     677                } else if (strcasecmp(format, "USA") == 0) {
     678                    time.format = TIME_FORMAT_MMDDYYYY;
     679                } else if (strcasecmp(format, "BACKWARDS") == 0) {
     680                    time.format = TIME_FORMAT_DDMMYYYY;
     681                } else if (strcasecmp(format, "PRE2000") == 0) {
     682                    time.pre2000 = true;
     683                } else if (strcasecmp(format, "MJD") == 0) {
     684                    time.format = TIME_FORMAT_MJD;
     685                } else if (strcasecmp(format, "JD") == 0) {
     686                    time.format = TIME_FORMAT_JD;
     687                } else {
     688                    psWarning("Unrecognised FORMATS option for %s: %s --- ignored.", name, format);
     689                }
     690            }
     691            psFree(formatListIter);
     692            psFree(formatList);
     693        }
     694    }
     695
     696    return time;
     697}
     698
    632699// Determine the corresponding TIMESYS for one of the TIME concepts
    633700static psTimeType conceptGetTimesysForTime(const char *name, // Concept name ("CELL.TIME" or "FPA.TIME")
     
    734801    psTimeType timeSys = conceptGetTimesysForTime(pattern->name, fpa, chip, cell); // Time system
    735802
    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);
     803    conceptTimeFormat timeFormat = conceptGetTimeFormat(pattern->name, cameraFormat); // Format for time
    808804
    809805    psTime *time = NULL;                // The time
    810806    switch (concept->type) {
    811807      case PS_DATA_LIST: {
    812           if (!separateTime) {
     808          if (!timeFormat.separate) {
    813809              psWarning ("DATE and TIME stored separately, but not specified in format\n");
    814810          }
     
    837833              return NULL;
    838834          }
    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;
     835          switch (timeFormat.format) {
     836            case TIME_FORMAT_DDMMYYYY: {
     837                // Need to switch days and years
     838                int temp = day;
     839                day = year;
     840                year = temp;
     841                break;
     842            }
     843            case TIME_FORMAT_MMDDYYYY: {
     844                // Need to switch everything around.... Yanks!
     845                int temp = day;
     846                day = month;
     847                month = year;
     848                year = temp;
     849                break;
     850            }
     851            default:
     852              break;
    851853          }
    852854          if (year < 100) {
    853               if (pre2000Time) {
     855              if (timeFormat.pre2000) {
    854856                  year += 1900;
    855857              } else {
     
    898900      case PS_DATA_STRING: {
    899901          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
     902          switch (timeFormat.format) {
     903            case TIME_FORMAT_JD: {
     904                double timeValue = strtod (timeString, NULL);
     905                time = psTimeFromJD(timeValue);
     906                break;
     907            }
     908            case TIME_FORMAT_MJD: {
     909                double timeValue = strtod (timeString, NULL);
     910                time = psTimeFromMJD(timeValue);
     911                break;
     912            }
     913            case TIME_FORMAT_YYYYMMDD: {
     914                // this is ISO-standard
     915                time = psTimeFromISO(timeString, timeSys);
     916                break;
     917            }
     918            default:
     919              psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Unable to interpret time string: %s", timeString);
     920              return NULL;
     921          }
    910922          break;
    911923      }
    912924      case PS_TYPE_F32: {
    913925          double timeValue = (double)concept->data.F32;
    914           if (jdTime) {
     926          switch (timeFormat.format) {
     927            case TIME_FORMAT_JD:
    915928              time = psTimeFromJD(timeValue);
    916           } else if (mjdTime) {
     929              break;
     930            case TIME_FORMAT_MJD:
    917931              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);
     932              break;
     933            default:
     934              psError(PS_ERR_UNKNOWN, true, "Unable to interpret time %s (%f)", pattern->name, timeValue);
     935              return NULL;
    922936          }
    923937          break;
     
    925939      case PS_TYPE_F64: {
    926940          double timeValue = (double)concept->data.F64;
    927           if (jdTime) {
     941          switch (timeFormat.format) {
     942            case TIME_FORMAT_JD:
    928943              time = psTimeFromJD(timeValue);
    929           } else if (mjdTime) {
     944              break;
     945            case TIME_FORMAT_MJD:
    930946              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);
     947              break;
     948            default:
     949              psError(PS_ERR_UNKNOWN, true, "Unable to interpret time %s (%f)", pattern->name, timeValue);
     950              return NULL;
    935951          }
    936952          break;
     
    946962    }
    947963
    948     if (jdTime || mjdTime) {
     964    // Set the time system appropriately
     965    switch (timeFormat.format) {
     966      case TIME_FORMAT_JD:
     967      case TIME_FORMAT_MJD:
    949968        conceptSetTimesysForTime(pattern->name, fpa, chip, cell, PS_TIME_TAI);
    950     } else {
     969        break;
     970      default:
    951971        time->type = timeSys;
     972        break;
    952973    }
    953974
     
    11761197                                          const pmCell *cell)
    11771198{
     1199    psString timeName = psStringCopy(concept->name); // Name of corresponding TIME concept
     1200    psStringSubstitute(&timeName, "TIME", "TIMESYS");
     1201
     1202    conceptTimeFormat timeFormat = conceptGetTimeFormat(timeName, cameraFormat); // Format for time
     1203    psFree(timeName);
     1204
     1205    psTimeType timesys = concept->data.S32; // Time system
     1206
     1207    // JD and MJD are converted to TAI before writing
     1208    switch (timeFormat.format) {
     1209      case TIME_FORMAT_JD:
     1210      case TIME_FORMAT_MJD:
     1211        timesys = PS_TIME_TAI;
     1212        break;
     1213      default:
     1214        break;
     1215    }
     1216
    11781217    psString sys = NULL;            // String to store
    1179     switch (concept->data.S32) {
     1218    switch (timesys) {
    11801219      case PS_TIME_TAI:
    11811220        sys = psStringCopy("TAI");
     
    12111250    psTimeConvert(time, timeSys);
    12121251
    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) {
     1252    conceptTimeFormat timeFormat = conceptGetTimeFormat(concept->name, cameraFormat); // Format for time
     1253
     1254    if (timeFormat.separate) {
    12731255        // We're working with two separate headers --- construct a list with the date and time separately
    12741256        psString dateTimeString = psTimeToISO(time); // String representation
     
    12801262        // Need to format the strings....
    12811263        // XXX: Couldn't be bothered doing these right now
    1282         if (pre2000Time) {
     1264        if (timeFormat.pre2000) {
    12831265            psError(PS_ERR_UNKNOWN, true, "Don't you realise it's the twenty-first century?\n");
    12841266            return NULL;
    12851267        }
    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");
     1268
     1269        switch (timeFormat.format) {
     1270          case TIME_FORMAT_DDMMYYYY: {
     1271              int day, month, year;
     1272              psTrace ("psModules.concepts", 5, "ISO time has year first, convert to DD-MM-YYYY");
     1273              sscanf (dateString, "%d-%d-%d", &year, &month, &day);
     1274              sprintf (dateString, "%02d-%02d-%04d", day, month, year);
     1275              // XXX fix this for str length
     1276              break;
     1277          }
     1278          case TIME_FORMAT_MMDDYYYY: {
     1279              int day, month, year;
     1280              psTrace ("psModules.concepts", 5, "ISO time has year first, convert to MM-DD-YYYY");
     1281              sscanf (dateString, "%d-%d-%d", &year, &month, &day);
     1282              sprintf (dateString, "%02d-%02d-%04d", month, day, year);
     1283              // XXX fix this for str length
     1284              break;
     1285          }
     1286          default:
     1287            break;
    13021288        }
    13031289
     
    13131299        psListAdd(dateTime, PS_LIST_TAIL, timeItem);
    13141300
    1315         psMetadataItem *item = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST, concept->comment,
    1316                                                       dateTime);
    1317         psFree (dateItem);
    1318         psFree (timeItem);
    1319         psFree (dateTime);
     1301        psMetadataItem *item = psMetadataItemAllocPtr(concept->name, PS_DATA_LIST,
     1302                                                      concept->comment, dateTime);
     1303        psFree(dateItem);
     1304        psFree(timeItem);
     1305        psFree(dateTime);
    13201306        return item;
    13211307    }
    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;
     1308
     1309    switch (timeFormat.format) {
     1310      case TIME_FORMAT_JD: {
     1311          double jd = psTimeToMJD(time);
     1312          return psMetadataItemAllocF64(concept->name, concept->comment, jd);
     1313      }
     1314      case TIME_FORMAT_MJD: {
     1315          double mjd = psTimeToMJD(time);
     1316          return psMetadataItemAllocF64(concept->name, concept->comment, mjd);
     1317      }
     1318      default: {
     1319          // If we've gotten this far, it's straight ISO.
     1320          psString dateTimeString = psTimeToISO(time); // String representation
     1321          psMetadataItem *item = psMetadataItemAllocStr(concept->name, concept->comment, dateTimeString);
     1322          psFree(dateTimeString);
     1323          return item;
     1324      }
     1325    }
     1326
     1327    return NULL;
    13361328}
    13371329
Note: See TracChangeset for help on using the changeset viewer.