Opened 7 years ago
Closed 7 years ago
#782 closed upgrade (Done)
VERY IMPORTANT: Time units attribute in NetCDF files — at Version 1
Reported by: | arango | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | Release ROMS/TOMS 3.7 |
Component: | Nonlinear | Version: | 3.7 |
Keywords: | Cc: |
Description (last modified by )
This change is a significant improvement, and I recommend users to update their code if have a version newer than Jun 21, 2018.
In update src:ticket:771, I made changes on how the reference time is processed in ROMS. The time attribute in input NetCDF is essential in the processing of external data. It usually has the form of:
'time-units since YYYY-MM-DD hh:mm:ss' 'time-units since YYYY-MM-DD hh:mm:ss.s' 'time-units since YYYY-MM-DD hh:mm:ss.ss'
But the several variants that are still CF compliant. For example, one can have:
'days since 1900-01-01 00:00:00' 'seconds since 1968-05-23 12:00:00 -6' 'years since -4713-11-24 00:00:00' (Nov 24, 4713 BC) 'hours since 1990-1-1 0:0:0' 'days since 1582-10-15 00:00:0.000Z' 'days since 1-1-1 0:0:0' 'hours since 2010-12-1 12:5:30.5' 'days since 1900/01/01 00:00:00' 'seconds since 1960-1-1' 'days since 1-07-15 0:0:0' 'days since 0000-01-01 0:0:0'
As you can see, people creating NetCDF files are not consistent in the format for YYYY-MM-DD hh:mm:ss. Therefore, I added a generic routine time_units to the module dateclock.F.
I am using the ASCII character set to decode the time units attribute string and replace unneeded characters with a blank space, CHAR(32). Only the following characters are retained:
! Char Dec Control Action ! ------------------------------ ! SP 32 Space ! + 43 Plus ! - 45 Hyphen, dash, minus ! . 46 Period ! 0 48 Zero ! 1 49 One ! 2 50 Two ! 3 51 Three ! 4 52 Four ! 5 53 Five ! 6 54 Six ! 7 55 Seven ! 8 56 Eight ! 9 57 Nine ! DO i=1,lstr Schar=ICHAR(Tstring(i:i)) IF (.not.(((48.le.Schar).and.(Schar.le.57)).or. & & (Schar.eq.32).or.(Schar.eq.46))) THEN Tstring(i:i)=CHAR(32) ! blank space END IF END DO Tstring=ADJUSTL(TRIM(Tstring)) lstr=LEN_TRIM(Tstring)
Then, every numerical value in the string is converted to a real variable to allow floating-point values for seconds. The year, month, day, hour, and minutes are output as integers.
Many thanks to John Wilkin for bringing this issue to my attention. If the time attribute in your input file is not in the form of time-units since YYYY-MM-DD hh:mm:ss, you will get an error when calling function netcdf_get_time.
I also updated function decode_line in inp_par.F to remove control-keys introduced when generating or editing input script ocean.in. It now checks and replaces ASCII characters CHAR(0) to CHAR(31) with a blank space:
! Char Dec Key Control Action ! ---------------------------------------------------------------------- ! NUL 0 ^@ Null character ! SOH 1 ^A Start of heading, = console interrupt ! STX 2 ^B Start of text, maintenance mode on HP console ! ETX 3 ^C End of text ! EOT 4 ^D End of transmission, not the same as ETB ! ENQ 5 ^E Enquiry, goes with ACK; old HP flow control ! ACK 6 ^F Acknowledge, clears ENQ logon hand ! BEL 7 ^G Bell, rings the bell... ! BS 8 ^H Backspace, works on HP terminals/computers ! HT 9 ^I Horizontal tab, move to next tab stop ! LF 10 ^J Line Feed ! VT 11 ^K Vertical tab ! FF 12 ^L Form Feed, page eject ! CR 13 ^M Carriage Return ! SO 14 ^N Shift Out, alternate character set ! SI 15 ^O Shift In, resume default character set ! DLE 16 ^P Data link escape ! DC1 17 ^Q XON, with XOFF to pause listings; ":okay to send". ! DC2 18 ^R Device control 2, block-mode flow control ! DC3 19 ^S XOFF, with XON is TERM=18 flow control ! DC4 20 ^T Device control 4 ! NAK 21 ^U Negative acknowledge ! SYN 22 ^V Synchronous idle ! ETB 23 ^W End transmission block, not the same as EOT ! CAN 24 ^X Cancel line, MPE echoes !!! ! EM 25 ^Y End of medium, Control-Y interrupt ! SUB 26 ^Z Substitute ! ESC 27 ^[ Escape, next character is not echoed ! FS 28 ^\ File separator ! GS 29 ^] Group separator ! RS 30 ^^ Record separator, block-mode terminator ! US 31 ^_ Unit separator ! ! SP 32 Space ! inpline=TRIM(ADJUSTL(line_text)) Linp=LEN_TRIM(inpline) DO i=1,LEN_TRIM(inpline) j=ICHAR(inpline(i:i)) IF (j.lt.32) THEN inpline(i:i)=char(32) ! blank space END IF END DO inpline=TRIM(inpline)
Change History (1)
comment:1 by , 7 years ago
Description: | modified (diff) |
---|---|
Resolution: | → Done |
Status: | new → closed |
'