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

Modern diag_manager: Simplify the diag table yaml #1545

Merged
merged 4 commits into from
Aug 1, 2024
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
3 changes: 3 additions & 0 deletions diag_manager/diag_yaml_format.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ Below are some *optional* keys that may be added.
- **new_file_freq** is a string that defines the frequency and the frequency units (with a space between the frequency number and units) for closing the existing file
- **start_time** is an array of 6 integer indicating when to start the file for the first time. It is in the format [year month day hour minute second]. Requires “new_file_freq”
- **filename_time** is the time used to set the name of new files when using new_file_freq. The acceptable values are begin (which will use the begining of the file's time bounds), middle (which will use the middle of the file's time bounds), and end (which will use the end of the file's time bounds). The default is middle
- **reduction** is the reduction method that will be used for all the variables in the file. This is overriden if the reduction is specified at the variable level. The acceptable values are average, diurnalXX (where XX is the number of diurnal samples), powXX (whre XX is the power level), min, max, none, rms, and sum.
- **kind** is a string that defines the type of variable as it will be written out in the file. This is overriden if the kind is specified at the variable level. Acceptable values are r4, r8, i4, and i8.
- **module** is a string that defines the module where the variable is registered in the model code. This is overriden if the module is specified at the variable level.

**Example:** The following will create a new file every 6 hours starting at Jan 1 2020. Variable data will be written to the file every 6 hours.

Expand Down
56 changes: 50 additions & 6 deletions diag_manager/fms_diag_yaml.F90
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,15 @@ module fms_diag_yaml_mod
!! and values(dim=2) to be
!! added as global meta data to
!! the file
character (len=:), allocatable :: default_var_precision !< The precision for all of the variables in the file
!! This may be overriden if the precison was defined
!! at the variable level
character (len=:), allocatable :: default_var_reduction !< The reduction for all of the variables in the file
!! This may be overriden if the reduction was defined at
!! the variable level
character (len=:), allocatable :: default_var_module !< The module for all of the variables in the file
!! This may be overriden if the modules was defined at the
!! variable level
contains

!> All getter functions (functions named get_x(), for member field named x)
Expand Down Expand Up @@ -468,7 +477,8 @@ subroutine diag_yaml_object_init(diag_subset_output)
diag_yaml%diag_fields(var_count)%var_axes_names = ""
diag_yaml%diag_fields(var_count)%var_file_is_subregional = diag_yaml%diag_files(file_count)%has_file_sub_region()

call fill_in_diag_fields(diag_yaml_id, var_ids(j), diag_yaml%diag_fields(var_count), allow_averages)
call fill_in_diag_fields(diag_yaml_id, diag_yaml%diag_files(file_count), var_ids(j), &
diag_yaml%diag_fields(var_count), allow_averages)

!> Save the variable name in the diag_file type
diag_yaml%diag_files(file_count)%file_varlist(file_var_count) = diag_yaml%diag_fields(var_count)%var_varname
Expand Down Expand Up @@ -604,12 +614,19 @@ subroutine fill_in_diag_files(diag_yaml_id, diag_file_id, yaml_fileobj)
&" has multiple global_meta blocks")
endif

call diag_get_value_from_key(diag_yaml_id, diag_file_id, "reduction", yaml_fileobj%default_var_reduction, &
is_optional=.true.)
call diag_get_value_from_key(diag_yaml_id, diag_file_id, "kind", yaml_fileobj%default_var_precision, &
is_optional=.true.)
call diag_get_value_from_key(diag_yaml_id, diag_file_id, "module", yaml_fileobj%default_var_module, &
is_optional=.true.)
end subroutine

!> @brief Fills in a diagYamlFilesVar_type with the contents of a variable block in
!! diag_table.yaml
subroutine fill_in_diag_fields(diag_file_id, var_id, field, allow_averages)
subroutine fill_in_diag_fields(diag_file_id, yaml_fileobj, var_id, field, allow_averages)
integer, intent(in) :: diag_file_id !< Id of the file block in the yaml file
type(diagYamlFiles_type), intent(in) :: yaml_fileobj !< The yaml file obj for the variables
integer, intent(in) :: var_id !< Id of the variable block in the yaml file
type(diagYamlFilesVar_type), intent(inout) :: field !< diagYamlFilesVar_type obj to read the contents into
logical, intent(in) :: allow_averages !< .True. if averages are allowed for this file
Expand All @@ -623,8 +640,17 @@ subroutine fill_in_diag_fields(diag_file_id, var_id, field, allow_averages)
character(len=:), ALLOCATABLE :: buffer !< buffer to store the reduction method as it is read from the yaml

call diag_get_value_from_key(diag_file_id, var_id, "var_name", field%var_varname)
call diag_get_value_from_key(diag_file_id, var_id, "reduction", buffer)

if (yaml_fileobj%default_var_reduction .eq. "") then
!! If there is no default, the reduction method is required
call diag_get_value_from_key(diag_file_id, var_id, "reduction", buffer)
else
call diag_get_value_from_key(diag_file_id, var_id, "reduction", buffer, is_optional=.true.)
!! If the reduction was not set for the variable, override it with the default
if (trim(buffer) .eq. "") buffer = yaml_fileobj%default_var_reduction
endif
call set_field_reduction(field, buffer)
deallocate(buffer)

if (.not. allow_averages) then
if (field%var_reduction .ne. time_none) &
Expand All @@ -633,9 +659,27 @@ subroutine fill_in_diag_fields(diag_file_id, var_id, field, allow_averages)
"Check your diag_table.yaml for the field:"//trim(field%var_varname))
endif

call diag_get_value_from_key(diag_file_id, var_id, "module", field%var_module)
deallocate(buffer)
call diag_get_value_from_key(diag_file_id, var_id, "kind", buffer)
if (yaml_fileobj%default_var_module .eq. "") then
call diag_get_value_from_key(diag_file_id, var_id, "module", field%var_module)
else
call diag_get_value_from_key(diag_file_id, var_id, "module", buffer, is_optional=.true.)
!! If the module was set for the variable, override it with the default
if (trim(buffer) .eq. "") then
field%var_module = yaml_fileobj%default_var_module
else
field%var_module = trim(buffer)
endif
deallocate(buffer)
endif

if (yaml_fileobj%default_var_precision .eq. "") then
!! If there is no default, the kind is required
call diag_get_value_from_key(diag_file_id, var_id, "kind", buffer)
else
call diag_get_value_from_key(diag_file_id, var_id, "kind", buffer, is_optional=.true.)
!! If the kind was set for the variable, override it with the default
if (trim(buffer) .eq. "") buffer = yaml_fileobj%default_var_precision
endif
call set_field_kind(field, buffer)

call diag_get_value_from_key(diag_file_id, var_id, "output_name", field%var_outname, is_optional=.true.)
Expand Down
78 changes: 78 additions & 0 deletions test_fms/diag_manager/test_diag_manager2.sh
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,84 @@ if [ -z "${skipflag}" ]; then
title: test_diag_manager
base_date: 2 1 1 0 0 0
diag_files:
- file_name: wild_card_name%4yr%2mo%2dy%2hr
filename_time: end
freq: 6 hours
time_units: hours
unlimdim: time
new_file_freq: 6 hours
start_time: 2 1 1 0 0 0
file_duration: 12 hours
module: test_diag_manager_mod
reduction: average
kind: r4
varlist:
- var_name: sst
output_name: sst
global_meta:
- is_a_file: true
- file_name: normal
freq: 24 days
time_units: hours
unlimdim: records
# Here the module, kind and reduction are being overwritten with whats on the variable
module: potato_mod
kind: r8
reduction: min
varlist:
- module: test_diag_manager_mod
var_name: sst
output_name: sst
reduction: average
kind: r4
write_var: true
attributes:
- do_sst: .true.
sub_region:
- grid_type: latlon
corner1: -80, 0
corner2: -80, 75
corner3: -60, 0
corner4: -60, 75
- file_name: normal2
freq: -1
time_units: hours
unlimdim: records
write_file: true
module: test_diag_manager_mod
reduction: none
kind: r4
varlist:
- var_name: sstt
output_name: sstt
long_name: S S T
- var_name: sstt2
output_name: sstt2
long_name: S S T
write_var: false
sub_region:
- grid_type: index
tile: 1
corner1: 10, 15
corner2: 20, 15
corner3: 10, 25
corner4: 20, 25
- file_name: normal3
freq: -1
time_units: hours
unlimdim: records
write_file: false
_EOF

my_test_count=`expr $my_test_count + 1`
test_expect_success "diag_yaml test with the simple diag table.yaml (test $my_test_count)" '
mpirun -n 1 ../test_diag_yaml
'

cat <<_EOF > diag_table.yaml
title: test_diag_manager
base_date: 2 1 1 0 0 0
diag_files:
- file_name: wild_card_name%4yr%2mo%2dy%2hr
filename_time: end
freq: 6 hours
Expand Down
Loading