Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#771 closed upgrade (Done)

VERY IMPORTANT Update: Reference Time

Reported by: arango Owned by:
Priority: major Milestone: Release ROMS/TOMS 3.7
Component: Nonlinear Version: 3.7
Keywords: Cc:

Description (last modified by arango)

ROMS support several date calendars according to the value of the input parameter TIME_REF in ocean.in:

time_ref = -2            Truncated Julian day number (Julian/Gregorian)
                           'time-units since 1968-05-23 00:00:00'
                         origin: Jan 01, 4713 BC (Proleptic Julian Calendar)
                                 Nov 24, 4713 BC (Proleptic Gregorian Calendar)

time_ref = -1            360 day per year calendar
                           'time-units since 0000-12-30 00:00:00'
                         origin: Jan 1, 0000 (360_day Calendar)

time_ref = 0             Proleptic Gregorian calendar
                           'time-units since 0001-01-01 00:00:00'
                         origin: Jan 1, 0000 (Proletic gregorian Calendar)

time_ref = YYYYMMDD.dd   Gregorian or Proleptic Gregorian calendar
                           'time-units since YYYY-MM-DD hh:mm:ss'
                         origin: Jan 1, 0000 (Proletic gregorian Calendar)

Notice that a calendar obtained by extending backward in time from its invention or implementation is called the Proleptic version of the calendar. For example, the Proleptic Gregorian Calendar extends backward the date preceding 15 October 1582 (Gregorian Calendar start) with a year length of 365.2425 days.

Until now, the reference date has been used loosely in ROMS, and it is only crucial when using the 360_day calendar. However, from this update on, it will be used strictly to measure the elapsed time since the reference date. It will not affect your current application configuration if the all the datasets have the same reference time coordinates. For example, input NetCDF files usually have the units attribute of the form:

       double ocean_time(ocean_time) ;
                ocean_time:long_name = "time since initialization" ;
                ocean_time:units = "seconds since 1900-01-01 00:00:00" ;
                ocean_time:calendar = "gregorian" ;
or

        double TIME(TIME) ;
                TIME:long_name = "time of atmosphere forcing" ;    
                TIME:units = "days since 1900-01-01 00:00:00" ;
                TIME:time_origin = "01-JAN-1900 00:00:00" ;
                TIME:standard_name = "time" ;
                TIME:calendar = "gregorian" ;

ROMS only process the units attribute for the time coordinate.

So why this change?

Because it allows input datasets to have different reference dates than the one specified in ocean.in, provided that:

  • All the datasets use the same calendar and have the same origin. Notice that time_ref = 0 or time_ref > 0 (YYYYMMDD.dd) correspond to the Proleptic Gregorian Calendar and have the same origin (see above). We cannot use datasets with both time_ref = -2 and time_ref >= 0 definitions because it have different origin and consequently non unique date numbers. Although they have the same calendar (Proleptic Gregorian) in the ROMS implementation.
  • It covers the time range needed by the ROMS application.
  • Users need to be strict about the units attribute when creating dataset NetCDF files.

So, there is no longer a need to modify the input dataset by recomputing the time coordinate to a particular time reference or epoch. ROMS will adjust the data time variable internally to the desired epoch specified by time_ref, hurrah! I know, we all had to manipulate the time in the input dataset NetCDF files. It was very annoying.

Two new routines were added to mod_netcdf.F to read time for a dataset:

      INTERFACE netcdf_get_time
        MODULE PROCEDURE netcdf_get_time_0d
        MODULE PROCEDURE netcdf_get_time_1d
      END INTERFACE netcdf_get_time

For example, in get_3dfld.F we now have:

            CALL netcdf_get_time (ng, model, ncfile, Tname(ifield),     &
     &                            Rclock%DateNumber, Tval,              &
     &                            ncid = ncid,                          &
     &                            start = (/Trec/),                     &
     &                            total = (/1/))

instead of

            CALL netcdf_get_fvar (ng, model, ncfile, Tname(ifield),     &
     &                            Tval,                                 &
     &                            ncid = ncid,                          &
     &                            start = (/Trec/),                     &
     &                            total = (/1/))

Notice that netcdf_get_time has an additional argument (Rclock%DateNumber) when compared with the older call to netcdf_get_fvar.

As a consequence, several routines were modified to use netcdf_get_time for reading the dataset time.

The dateclock.F module was modified to absorb the new changes. The datenum and its inverse datevec routines now compute the serial date number and date vector, respectively, for all the calendars supported in ROMS. Also, a new routine datestr was added to compute the date string from the serial date number.


Warningx:

  • ROMS now supports several Julian Day Numbers (JDN) with the time_ref = -2 option, but I will discourage Users to use them because it can be confusing. Since JDN can be large, there are several variants according to the epoch:
    Reduced:     days since 1858-11-16 12:00:00   (offset = 2400000)
    Modified:    days since 1858-11-17 00:00:00   (offset = 2400000.5)
    Truncated:   days since 1968-05-23 12:00:00   (offset = 2440000.5)
    
    Check the following wikipedia link for more information.

The JDN is primarily used by astronomers. Although in the formal definition Julian days start and end at noon, in ROMS Julian days starts and end at midnight. So, it is 12 hours faster. The Julian Calendar was adjusted on Oct 15, 1582 (Gregorian Calendar start date) with a year length of 365.2425 days. ROMS have the equations for both the Proleptic Julian Calendar which starts on Jan 1, 4713 BC or the corrected Proleptic Gregorian Calendar (default) which starts on Nov 24, 4713 BC.

As you can see, it is confusing and ambiguous, and we should stay away from it.

  • Also, it has been broad to my attention that several datasets out there have time clocks shifted by one or two days. It is wise to check the time coordinates always before using a dataset. I will also release an update the Matlab scripts with the implementation of ROMS clocks.

We provide new Perl script dates in the ROMS/Bin directory that can be used for date manipulation containing the following functions:

  • datenum: Converts Proleptic Gregorian Calendar date to serial date number. It is similar to Matlab's datenum function. If the date argument is omitted, today's date is used.
  • daysdiff: Calculates the number of days between two dates.

  • numdate: Converts serial date number to a date string. It is the inverse of datenum and similar to Matlab's datestr function.
  • yday: Computes day-of-the-year given a date. If the date argument is omitted, today's date is used.

Many thanks to Dave Robertson for coding this Perl function.

Several dates_test scripts (.bash, .ksh, .sh) are provided as examples for usage. In dates_test.bash, we have:

today=`date +"%d-%m-%Y %r"`

dn1=`dates datenum`
ds1=`dates numdate $dn1`
yd1=`dates yday $ds1`

dn2=`dates datenum 1900-01-01`
ds2=`dates numdate $dn2`
yd2=`dates yday $ds2`
d21=`dates daysdiff $ds2 $ds1`

dn2=`dates datenum 19000101`
ds2=`dates numdate $dn2`
yd2=`dates yday $ds2`
d21=`dates daysdiff $ds2 $ds1`

dn3=`dates datenum 1968-05-23`
ds3=`dates numdate $dn3`
yd3=`dates yday $ds3`
d31=`dates daysdiff $ds3 $ds1`

echo
echo "Testing 'dates' Perl Script on $today"
echo
echo "Today's Date:               $ds1"
echo "Today's Date Number:        $dn1"
echo "Today's Day-of-the-year:    $yd1"
echo
echo "Reference Date:             $ds2"
echo "Reference Date Number:      $dn2"
echo "Reference Day-of-the-year:  $yd2"
echo "Days since Reference date:  $d21"
echo
echo "Truncated Date:             $ds3"
echo "Truncated Date Number:      $dn3"
echo "Truncated Day-of-the-year:  $yd3"
echo "Days since TRuncated date:  $d31"
echo

which yields:

Testing 'dates' Perl Script on 20-06-2018 05:18:12 PM

Today's Date:               2018-06-20
Today's Date Number:        737231
Today's Day-of-the-year:    171

Reference Date:             1900-01-01
Reference Date Number:      693962
Reference Day-of-the-year:  1
Days since Reference date:  43269

Truncated Date:             1968-05-23
Truncated Date Number:      718941
Truncated Day-of-the-year:  144
Days since TRuncated date:  18290

Change History (2)

comment:1 by arango, 6 years ago

Resolution: Done
Status: newclosed

comment:2 by arango, 6 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.