Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding flexibility to choose the time string suffix for output file names #660

Merged
merged 6 commits into from
Jan 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions diag_manager/diag_data.F90
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ MODULE diag_data_mod
!Support for fms2_io time
real :: rtime_current
integer :: time_index
CHARACTER(len=10) :: filename_time_bounds
END TYPE file_type
! </TYPE>

Expand Down
14 changes: 12 additions & 2 deletions diag_manager/diag_manager.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3414,6 +3414,7 @@ INTEGER FUNCTION writing_field(out_num, at_diag_end, error_string, time)
TYPE(time_type), INTENT(in) :: time

TYPE(time_type) :: middle_time
TYPE(time_type) :: filename_time
LOGICAL :: time_max, time_min, reduced_k_range, missvalue_present
LOGICAL :: average, time_rms, need_compute, phys_window
INTEGER :: in_num, file_num, freq, units
Expand Down Expand Up @@ -3533,11 +3534,20 @@ INTEGER FUNCTION writing_field(out_num, at_diag_end, error_string, time)
endif
IF ( (output_fields(out_num)%time_ops) .AND. (.NOT. mix_snapshot_average_fields) ) THEN
middle_time = (output_fields(out_num)%last_output+output_fields(out_num)%next_output)/2
if (trim(files(file_num)%filename_time_bounds) == "begin") then
filename_time = output_fields(out_num)%last_output
elseif (trim(files(file_num)%filename_time_bounds) == "middle") then
filename_time = middle_time
elseif (trim(files(file_num)%filename_time_bounds) == "end") then
filename_time = output_fields(out_num)%next_output
endif

if (output_fields(out_num)%n_diurnal_samples > 1) then
CALL diag_data_out(file_num, out_num, diurnal_buffer, middle_time, use_mpp_io_arg=use_mpp_io)
CALL diag_data_out(file_num, out_num, diurnal_buffer, middle_time, &
& use_mpp_io_arg=use_mpp_io, filename_time=filename_time)
else
CALL diag_data_out(file_num, out_num, output_fields(out_num)%buffer, middle_time, &
& use_mpp_io_arg=use_mpp_io)
& use_mpp_io_arg=use_mpp_io, filename_time=filename_time)
endif
ELSE
if (output_fields(out_num)%n_diurnal_samples > 1) then
Expand Down
19 changes: 17 additions & 2 deletions diag_manager/diag_table.F90
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ MODULE diag_table_mod
CHARACTER(len=10) :: new_file_freq_units
CHARACTER(len=25) :: start_time_s
CHARACTER(len=10) :: file_duration_units
CHARACTER(len=10) :: filename_time_bounds
TYPE(time_type) :: start_time
END TYPE file_description_type

Expand Down Expand Up @@ -482,7 +483,7 @@ SUBROUTINE parse_diag_table(diag_subset, istat, err_msg)
ELSE IF ( temp_file%new_file_freq > 0 ) THEN ! Call the init_file subroutine. The '1' is for the tile_count
CALL init_file(temp_file%file_name, temp_file%output_freq, temp_file%iOutput_freq_units, temp_file%file_format,&
& temp_file%iTime_units, temp_file%long_name, 1, temp_file%new_file_freq, temp_file%iNew_file_freq_units,&
& temp_file%start_time, temp_file%file_duration, temp_file%iFile_duration_units)
& temp_file%start_time, temp_file%file_duration, temp_file%iFile_duration_units, temp_file%filename_time_bounds)
ELSE
CALL init_file(temp_file%file_name, temp_file%output_freq, temp_file%iOutput_freq_units, temp_file%file_format,&
& temp_file%iTime_units, temp_file%long_name, 1)
Expand Down Expand Up @@ -646,12 +647,13 @@ TYPE(file_description_type) FUNCTION parse_file_line(line, istat, err_msg)
parse_file_line%start_time_s = ''
parse_file_line%file_duration = 0
parse_file_line%file_duration_units = ''
parse_file_line%filename_time_bounds = ''

! Read in the file description line..
READ (line, FMT=*, IOSTAT=mystat) parse_file_line%file_name, parse_file_line%output_freq, parse_file_line%output_freq_units,&
& parse_file_line%file_format, parse_file_line%time_units, parse_file_line%long_name,&
& parse_file_line%new_file_freq, parse_file_line%new_file_freq_units, parse_file_line%start_time_s,&
& parse_file_line%file_duration, parse_file_line%file_duration_units
& parse_file_line%file_duration, parse_file_line%file_duration_units, parse_file_line%filename_time_bounds
IF ( mystat > 0 ) THEN
pstat = mystat
IF ( fms_error_handler('diag_table_mod::parse_file_line', 'Incorrect file description format in diag_table.', err_msg) )&
Expand Down Expand Up @@ -763,6 +765,19 @@ TYPE(file_description_type) FUNCTION parse_file_line(line, istat, err_msg)
END IF
END IF new_file_freq_present

!< If filename_time_bounds is empty using defaults
IF (trim(parse_file_line%filename_time_bounds) == "") THEN
parse_file_line%filename_time_bounds = "middle"
ELSE
!< Check if the filename_time_bounds is one of the accepted values
IF (trim(parse_file_line%filename_time_bounds) /= "begin" .or. &
& trim(parse_file_line%filename_time_bounds) /= "middle" .or. &
& trim(parse_file_line%filename_time_bounds) /= "end") THEN
IF ( fms_error_handler('diag_table_mod::parse_file_line',&
& 'filename_time_bounds must be "begin", "middle", "end".', err_msg) ) RETURN
ENDIF
ENDIF

END FUNCTION parse_file_line
! </FUNCTION>
! </PRIVATE>
Expand Down
29 changes: 20 additions & 9 deletions diag_manager/diag_util.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1063,13 +1063,14 @@ END SUBROUTINE check_bounds_are_exact_static
! <IN NAME="file_duration" TYPE="INTEGER, OPTIONAL">How long file is to be used.</IN>
! <IN NAME="file_duration_units" TYPE="INTEGER, OPTIONAL">File duration unit. (MIN, HOURS, DAYS, etc.)</IN>
SUBROUTINE init_file(name, output_freq, output_units, format, time_units, long_name, tile_count,&
& new_file_freq, new_file_freq_units, start_time, file_duration, file_duration_units)
& new_file_freq, new_file_freq_units, start_time, file_duration, file_duration_units, filename_time_bounds)
CHARACTER(len=*), INTENT(in) :: name, long_name
INTEGER, INTENT(in) :: output_freq, output_units, format, time_units
INTEGER, INTENT(in) :: tile_count
INTEGER, INTENT(in), OPTIONAL :: new_file_freq, new_file_freq_units
INTEGER, INTENT(in), OPTIONAL :: file_duration, file_duration_units
TYPE(time_type), INTENT(in), OPTIONAL :: start_time
CHARACTER(len=*), INTENT(in), OPTIONAL :: filename_time_bounds

INTEGER :: new_file_freq1, new_file_freq_units1
INTEGER :: file_duration1, file_duration_units1
Expand Down Expand Up @@ -1201,6 +1202,7 @@ SUBROUTINE init_file(name, output_freq, output_units, format, time_units, long_n
!> Initialize the times to 0
files(num_files)%rtime_current = -1.0
files(num_files)%time_index = 0
files(num_files)%filename_time_bounds = filename_time_bounds

IF ( PRESENT(start_time) ) THEN
files(num_files)%start_time = start_time
Expand Down Expand Up @@ -1772,13 +1774,14 @@ SUBROUTINE init_output_field(module_name, field_name, output_name, output_file,&
END SUBROUTINE init_output_field
! </SUBROUTINE>

!> \brief Open file for output.
SUBROUTINE opening_file(file, time, use_mpp_io)
SUBROUTINE opening_file(file, time, use_mpp_io, filename_time)
! WARNING: Assumes that all data structures are fully initialized
INTEGER, INTENT(in) :: file !< File ID.
TYPE(time_type), INTENT(in) :: time !< Time for the file time stamp
logical :: use_mpp_io !< controls which IO is used for output
TYPE(time_type), INTENT(in), optional :: filename_time !< Time used in setting the filename when writting periodic files

TYPE(time_type) :: fname_time !< Time used in setting the filename when writting periodic files
REAL, DIMENSION(2) :: DATA
INTEGER :: j, field_num, input_field_num, num_axes, k
INTEGER :: field_num1
Expand Down Expand Up @@ -1830,7 +1833,12 @@ SUBROUTINE opening_file(file, time, use_mpp_io)
CALL error_mesg('diag_util_mod::opening_file',&
& 'file name '//TRIM(files(file)%name)//' does not contain % for time stamp string', FATAL)
END IF
suffix = get_time_string(files(file)%name, time)
if (present(filename_time)) then
fname_time = filename_time
else
fname_time = time
endif
suffix = get_time_string(files(file)%name, fname_time)
ELSE
suffix = ' '
END IF
Expand Down Expand Up @@ -2593,12 +2601,13 @@ END FUNCTION get_date_dif
! <IN NAME="time" TYPE="TYPE(time_type)">Current model time.</IN>
! <IN NAME="final_call_in" TYPE="LOGICAL, OPTIONAL"><TT>.TRUE.</TT> if this is the last write for file.</IN>
! <IN NAME="static_write_in" TYPE="LOGICAL, OPTIONAL"><TT>.TRUE.</TT> if static fields are to be written to file.</IN>
SUBROUTINE diag_data_out(file, field, dat, time, final_call_in, static_write_in, use_mpp_io_arg)
SUBROUTINE diag_data_out(file, field, dat, time, final_call_in, static_write_in, use_mpp_io_arg, filename_time)
INTEGER, INTENT(in) :: file, field
REAL, DIMENSION(:,:,:,:), INTENT(inout) :: dat
TYPE(time_type), INTENT(in) :: time
LOGICAL, OPTIONAL, INTENT(in):: final_call_in, static_write_in
logical,optional,intent(in) :: use_mpp_io_arg !< Switch for which IO to use for outputting data
type(time_type), intent(in), optional :: filename_time !< Time used in setting the filename when writting periodic files

LOGICAL :: final_call, do_write, static_write
INTEGER :: i, num
Expand All @@ -2620,7 +2629,8 @@ SUBROUTINE diag_data_out(file, field, dat, time, final_call_in, static_write_in,
dif = get_date_dif(time, base_time, files(file)%time_units)

! get file_unit, open new file and close curent file if necessary
IF ( .NOT.static_write .OR. files(file)%file_unit < 0 ) CALL check_and_open(file, time, do_write, use_mpp_io)
IF ( .NOT.static_write .OR. files(file)%file_unit < 0 ) &
CALL check_and_open(file, time, do_write, use_mpp_io, filename_time=filename_time)
IF ( .NOT.do_write ) RETURN ! no need to write data
if( .not. use_mpp_io) then
!> Set up the time index and write the correct time value to the time array
Expand Down Expand Up @@ -2759,23 +2769,24 @@ END SUBROUTINE diag_data_out
! <IN NAME="file" TYPE="INTEGER">File ID.</IN>
! <IN NAME="time" TYPE="TYPE(time_type)">Current model time.</IN>
! <OUT NAME="do_write" TYPE="LOGICAL"><TT>.TRUE.</TT> if file is expecting more data to write, <TT>.FALSE.</TT> otherwise.</OUT>
SUBROUTINE check_and_open(file, time, do_write, use_mpp_io)
SUBROUTINE check_and_open(file, time, do_write, use_mpp_io, filename_time)
INTEGER, INTENT(in) :: file !<File ID.
TYPE(time_type), INTENT(in) :: time !< Current model time.
LOGICAL, INTENT(out) :: do_write !< .TRUE. if file is expecting more data to write, .FALSE. otherwise.
LOGICAL, INTENT(in) :: use_mpp_io !< true=mpp_io, false=fms2_io
TYPE(time_type), INTENT(in), optional :: filename_time !< Time used in setting the filename when writting periodic files

IF ( time >= files(file)%start_time ) THEN
IF ( files(file)%file_unit < 0 ) THEN ! need to open a new file
CALL opening_file(file, time, use_mpp_io)
CALL opening_file(file, time, use_mpp_io, filename_time=filename_time)
do_write = .TRUE.
ELSE
do_write = .TRUE.
IF ( time > files(file)%close_time .AND. time < files(file)%next_open ) THEN
do_write = .FALSE. ! file still open but receives NO MORE data
ELSE IF ( time > files(file)%next_open ) THEN ! need to close current file and open a new one
CALL write_static(file, use_mpp_io) ! write all static fields and close this file
CALL opening_file(file, time, use_mpp_io)
CALL opening_file(file, time, use_mpp_io, filename_time=filename_time)
files(file)%time_index = 0 !< Reset the number of times in the files back to 0
files(file)%start_time = files(file)%next_open
files(file)%close_time =&
Expand Down
10 changes: 8 additions & 2 deletions test_fms/diag_manager/diagTables/diag_table_24
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ test_diag_manager
2 1 1 0 0 0

#output files
"ocn%4yr%2mo%2dy%2hr", 1, "days", 1, "days", "time", 1, "days", "2 1 1 0 0 0"
"ocn_default%4yr%2mo%2dy%2hr", 6, "hours", 1, "hours", "time", 6, "hours", "2 1 1 0 0 0"
"ocn_middle%4yr%2mo%2dy%2hr", 6, "hours", 1, "hours", "time", 6, "hours", "2 1 1 0 0 0", 0, "", "middle"
"ocn_begin%4yr%2mo%2dy%2hr", 6, "hours", 1, "hours", "time", 6, "hours", "2 1 1 0 0 0" 0, "", "begin"
"ocn_end%4yr%2mo%2dy%2hr", 6, "hours", 1, "hours", "time", 6, "hours", "2 1 1 0 0 0" 0, "", "end"

#output variables
"test_diag_manager_mod", "sst", "sst", "ocn%4yr%2mo%2dy%2hr", "all", .true., "none", 2
"test_diag_manager_mod", "sst", "sst", "ocn_default%4yr%2mo%2dy%2hr", "all", .true., "none", 2
"test_diag_manager_mod", "sst", "sst", "ocn_middle%4yr%2mo%2dy%2hr", "all", .true., "none", 2
"test_diag_manager_mod", "sst", "sst", "ocn_begin%4yr%2mo%2dy%2hr", "all", .true., "none", 2
"test_diag_manager_mod", "sst", "sst", "ocn_end%4yr%2mo%2dy%2hr", "all", .true., "none", 2
4 changes: 2 additions & 2 deletions test_fms/diag_manager/test_diag_manager_time.F90
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ program test_diag_manager_time
used = send_data(id_z, z, Time)

! Increase the time and send data
do i=1,20
Time = set_date(2,1,i,0,0,0)
do i=1,23
Time = set_date(2,1,1,i,0,0)
if(id_sst > 0) used = send_data(id_sst, sst, Time)
enddo

Expand Down