30 module fms_diag_yaml_mod
32 use diag_data_mod,
only: diag_null, diag_ocean, diag_all, diag_other,
set_base_time, latlon_gridtype, &
33 index_gridtype, null_gridtype, diag_seconds, diag_minutes, diag_hours, diag_days, &
42 use,
intrinsic :: iso_c_binding, only : c_ptr, c_null_char
45 use platform_mod,
only: r4_kind, i4_kind, r8_kind, i8_kind, fms_file_len
46 use fms_mod,
only: lowercase
49 use fms2_io_mod,
only: file_exists, get_instance_filename
66 integer,
parameter :: basedate_size = 6
67 integer,
parameter :: NUM_SUB_REGION_ARRAY = 8
68 integer,
parameter :: MAX_FREQ = 12
69 integer :: MAX_SUBAXES = 0
75 character(len=255),
allocatable :: var_name(:)
76 type(c_ptr),
allocatable :: var_pointer(:)
77 integer,
allocatable :: diag_field_indices(:)
82 character(len=FMS_FILE_LEN),
allocatable :: file_name(:)
83 type(c_ptr),
allocatable :: file_pointer(:)
84 integer,
allocatable :: diag_file_indices(:)
92 class(*),
allocatable :: corners(:,:)
101 character (len=:),
allocatable :: file_fname
102 integer :: file_frequnit(max_freq)
105 integer :: file_freq(max_freq)
106 integer :: file_timeunit
109 character (len=:),
allocatable :: file_unlimdim
111 integer :: file_new_file_freq(max_freq)
112 integer :: file_new_file_freq_units(max_freq)
118 logical :: file_start_time_set
119 integer :: filename_time
122 integer :: file_duration(max_freq)
131 integer :: file_duration_units(max_freq)
134 integer :: current_new_file_freq_index
136 character (len=MAX_STR_LEN),
allocatable :: file_varlist(:)
138 character (len=MAX_STR_LEN),
allocatable :: file_outlist(:)
141 character (len=MAX_STR_LEN),
allocatable :: file_global_meta(:,:)
145 character (len=:),
allocatable :: default_var_precision
148 character (len=:),
allocatable :: default_var_reduction
151 character (len=:),
allocatable :: default_var_module
154 logical :: use_collective_writes
155 integer,
dimension(MAX_DIMENSIONS):: default_chunksizes
197 character (len=:),
private,
allocatable :: var_fname
198 character (len=:),
private,
allocatable :: var_varname
199 integer ,
private,
allocatable :: var_reduction
202 character (len=:),
private,
allocatable :: var_module
203 integer ,
private,
allocatable :: var_kind
204 character (len=:),
private,
allocatable :: var_outname
205 character (len=:),
private,
allocatable :: var_longname
206 character (len=:),
private,
allocatable :: var_units
207 character (len=:),
private,
allocatable :: standard_name
208 real(kind=r4_kind),
private :: var_zbounds(2)
209 integer ,
private :: n_diurnal
211 integer ,
private :: pow_value
213 integer,
dimension(MAX_DIMENSIONS),
private :: chunksizes
214 logical ,
private :: var_file_is_subregional
218 character (len=MAX_STR_LEN),
dimension (:, :),
private,
allocatable :: var_attributes
220 character(len=:),
allocatable :: var_axes_names
253 procedure :: add_axis_name
254 procedure :: is_file_subregional
262 character(len=:),
allocatable,
private :: diag_title
263 integer,
private,
dimension (basedate_size) :: diag_basedate
286 logical,
private :: diag_yaml_module_initialized = .false.
305 result(diag_basedate)
307 integer,
dimension (basedate_size) :: diag_basedate
309 diag_basedate = this%diag_basedate
316 if (this%has_diag_files())
then
328 character(len=:),
allocatable :: diag_title
330 diag_title = this%diag_title
340 diag_files = this%diag_files
348 integer,
intent(in) :: yaml_id
352 if (yaml_id .eq. diag_not_registered)
call mpp_error(fatal, &
353 "Diag_manager: The yaml id for this field is not is not set")
355 diag_field => this%diag_fields(variable_list%diag_field_indices(yaml_id))
366 diag_fields = this%diag_fields
372 integer,
intent(in) :: diag_subset_output
377 integer :: diag_yaml_id
379 integer,
allocatable :: diag_file_ids(:)
381 integer :: total_nvars
383 integer :: file_var_count
385 integer,
allocatable :: var_ids(:)
387 logical,
allocatable :: ignore(:)
388 integer :: actual_num_files
389 integer :: file_count
390 logical :: write_file
392 logical :: allow_averages
394 character(len=:),
allocatable :: filename
395 logical :: is_instantaneous
396 character(len=FMS_FILE_LEN) :: yamlfilename
399 integer,
allocatable :: mod_ids(:)
400 integer,
allocatable :: nvars_per_file(:)
402 logical,
allocatable :: has_module_block(:)
403 character(len=FMS_FILE_LEN),
allocatable :: mod_name(:)
404 character(len=FMS_FILE_LEN) :: buffer
405 integer :: istart, iend
407 if (diag_yaml_module_initialized)
return
410 call get_instance_filename(
"diag_table.yaml", yamlfilename)
411 if (index(trim(yamlfilename),
"ens_") .ne. 0)
then
412 if (file_exists(yamlfilename) .and. file_exists(
"diag_table.yaml")) &
413 call mpp_error(fatal,
"Both diag_table.yaml and "//trim(yamlfilename)//
" exists, pick one!")
416 if (.not. file_exists(yamlfilename)) yamlfilename =
"diag_table.yaml"
419 if (diag_yaml_id .eq. missing_file_error_code) &
420 call mpp_error(fatal,
"The "//trim(yamlfilename)//
" is not present and it is required!")
427 allocate(diag_file_ids(nfiles))
428 allocate(ignore(nfiles))
430 call get_block_ids(diag_yaml_id,
"diag_files", diag_file_ids)
435 if(diag_subset_output .ne. diag_all)
then
438 call get_value_from_key(diag_yaml_id, diag_file_ids(i),
"is_ocean", is_ocean, is_optional=.true.)
440 if (diag_subset_output .eq. diag_ocean .and. .not. is_ocean) ignore(i) = .true.
443 if(diag_subset_output .eq. diag_other .and. is_ocean) ignore(i) = .true.
449 allocate(nvars_per_file(nfiles))
450 allocate(has_module_block(nfiles))
453 call get_value_from_key(diag_yaml_id, diag_file_ids(i),
"write_file", write_file, is_optional=.true.)
454 if(.not. write_file) ignore(i) = .true.
457 if (.not. ignore(i))
then
460 nmods =
get_num_blocks(diag_yaml_id,
"modules", parent_block_id=diag_file_ids(i))
462 nvars_per_file(i) =
get_num_blocks(diag_yaml_id,
"varlist", parent_block_id=diag_file_ids(i))
463 if (nmods .ne. 0)
then
464 has_module_block(i) = .true.
466 if (nvars_per_file(i) .ne. 0) &
467 call mpp_error(fatal,
"diag_manager_mod:: the file:"//trim(filename)//
" has a 'modules' block defined "//&
468 "and a 'module' key defined at the file level. This is not allowed!")
470 allocate(mod_ids(nmods))
471 call get_block_ids(diag_yaml_id,
"modules", mod_ids, parent_block_id=diag_file_ids(i))
475 nvars_per_file(i) = nvars_per_file(i) +
get_num_blocks(diag_yaml_id,
"varlist", parent_block_id=mod_ids(j))
481 has_module_block(i) = .false.
483 total_nvars = total_nvars + nvars
484 if (nvars .ne. 0)
then
485 actual_num_files = actual_num_files + 1
488 call mpp_error(note,
"diag_manager_mod:: the file:"//trim(filename)//
" has no variables defined. Ignoring!")
489 if (
allocated(filename))
deallocate(filename)
495 allocate(diag_yaml%diag_files(actual_num_files))
496 allocate(diag_yaml%diag_fields(total_nvars))
497 allocate(variable_list%var_name(total_nvars))
498 allocate(variable_list%diag_field_indices(total_nvars))
499 allocate(file_list%file_name(actual_num_files))
500 allocate(file_list%diag_file_indices(actual_num_files))
505 nfiles_loop:
do i = 1, nfiles
507 file_count = file_count + 1
509 call fill_in_diag_files(diag_yaml_id, diag_file_ids(i), diag_yaml%diag_files(file_count))
512 file_list%file_name(file_count) = trim(diag_yaml%diag_files(file_count)%file_fname)//c_null_char
513 file_list%diag_file_indices(file_count) = file_count
515 if (has_module_block(i))
then
516 allocate(var_ids(nvars_per_file(i)))
517 allocate(mod_name(nvars_per_file(i)))
518 nmods =
get_num_blocks(diag_yaml_id,
"modules", parent_block_id=diag_file_ids(i))
519 allocate(mod_ids(nmods))
520 call get_block_ids(diag_yaml_id,
"modules", mod_ids, parent_block_id=diag_file_ids(i))
523 nvars_per_file(i) = 0
525 iend = istart +
get_num_blocks(diag_yaml_id,
"varlist", parent_block_id=mod_ids(j)) - 1
526 call get_block_ids(diag_yaml_id,
"varlist", var_ids(istart:iend), parent_block_id=mod_ids(j))
532 mod_name(istart:iend) = trim(buffer)
539 allocate(var_ids(
get_num_blocks(diag_yaml_id,
"varlist", parent_block_id=diag_file_ids(i))))
540 allocate(mod_name(
size(var_ids)))
541 call get_block_ids(diag_yaml_id,
"varlist", var_ids, parent_block_id=diag_file_ids(i))
546 allocate(diag_yaml%diag_files(file_count)%file_varlist(nvars_per_file(i)))
547 allocate(diag_yaml%diag_files(file_count)%file_outlist(nvars_per_file(i)))
549 allow_averages = .not. diag_yaml%diag_files(file_count)%file_freq(1) < 1
550 is_instantaneous = .false.
551 nvars_loop:
do j = 1,
size(var_ids)
553 call get_value_from_key(diag_yaml_id, var_ids(j),
"write_var", write_var, is_optional=.true.)
554 if (.not. write_var) cycle
556 var_count = var_count + 1
557 file_var_count = file_var_count + 1
560 diag_yaml%diag_fields(var_count)%var_fname = diag_yaml%diag_files(file_count)%file_fname
563 diag_yaml%diag_fields(var_count)%var_axes_names =
""
564 diag_yaml%diag_fields(var_count)%var_file_is_subregional = diag_yaml%diag_files(file_count)%has_file_sub_region()
567 diag_yaml%diag_fields(var_count), allow_averages, has_module_block(i), mod_name(j))
570 diag_yaml%diag_files(file_count)%file_varlist(file_var_count) = diag_yaml%diag_fields(var_count)%var_varname
571 if(diag_yaml%diag_fields(var_count)%has_var_outname())
then
572 diag_yaml%diag_files(file_count)%file_outlist(file_var_count) = diag_yaml%diag_fields(var_count)%var_outname
574 diag_yaml%diag_files(file_count)%file_outlist(file_var_count) =
""
578 variable_list%var_name(var_count) = trim(diag_yaml%diag_fields(var_count)%var_varname)//&
579 ":"//trim(diag_yaml%diag_fields(var_count)%var_module)//c_null_char
581 variable_list%var_name(var_count) = lowercase(variable_list%var_name(var_count))
582 variable_list%diag_field_indices(var_count) = var_count
590 call fms_sort_this(file_list%file_pointer, actual_num_files, file_list%diag_file_indices)
593 call fms_sort_this(variable_list%var_pointer, total_nvars, variable_list%diag_field_indices)
595 deallocate(diag_file_ids)
596 diag_yaml_module_initialized = .true.
603 do i = 1,
size(diag_yaml%diag_files, 1)
604 if(
allocated(diag_yaml%diag_files(i)%file_varlist))
deallocate(diag_yaml%diag_files(i)%file_varlist)
605 if(
allocated(diag_yaml%diag_files(i)%file_outlist))
deallocate(diag_yaml%diag_files(i)%file_outlist)
606 if(
allocated(diag_yaml%diag_files(i)%file_global_meta))
deallocate(diag_yaml%diag_files(i)%file_global_meta)
607 if(
allocated(diag_yaml%diag_files(i)%file_sub_region%corners)) &
608 deallocate(diag_yaml%diag_files(i)%file_sub_region%corners)
610 if(
allocated(diag_yaml%diag_files))
deallocate(diag_yaml%diag_files)
612 do i = 1,
size(diag_yaml%diag_fields, 1)
613 if(
allocated(diag_yaml%diag_fields(i)%var_attributes))
deallocate(diag_yaml%diag_fields(i)%var_attributes)
615 if(
allocated(diag_yaml%diag_fields))
deallocate(diag_yaml%diag_fields)
617 if(
allocated(file_list%file_pointer))
deallocate(file_list%file_pointer)
618 if(
allocated(file_list%file_name))
deallocate(file_list%file_name)
619 if(
allocated(file_list%diag_file_indices))
deallocate(file_list%diag_file_indices)
621 if(
allocated(variable_list%var_pointer))
deallocate(variable_list%var_pointer)
622 if(
allocated(variable_list%var_name))
deallocate(variable_list%var_name)
623 if(
allocated(variable_list%diag_field_indices))
deallocate(variable_list%diag_field_indices)
629 integer,
intent(in) :: diag_yaml_id
630 integer,
intent(in) :: diag_file_id
633 integer :: nsubregion
634 integer :: sub_region_id(1)
636 integer :: global_att_id(1)
640 integer,
allocatable :: key_ids(:)
641 character(len=:),
ALLOCATABLE :: grid_type
642 character(len=:),
ALLOCATABLE :: buffer
643 integer :: start_time_int(6)
645 yaml_fileobj%file_frequnit = 0
649 call parse_key(yaml_fileobj%file_fname, buffer, yaml_fileobj%file_freq, yaml_fileobj%file_frequnit,
"freq")
658 call parse_key(yaml_fileobj%file_fname, buffer, yaml_fileobj%file_new_file_freq, &
659 yaml_fileobj%file_new_file_freq_units,
"new_file_freq")
666 start_time_int = diag_null
667 yaml_fileobj%file_start_time_set = .false.
669 start_time_int, is_optional=.true.)
670 if (any(start_time_int .ne. diag_null))
then
671 yaml_fileobj%file_start_time_set = .true.
672 call set_time_type(start_time_int, yaml_fileobj%file_start_time)
675 call parse_key(yaml_fileobj%file_fname, buffer, yaml_fileobj%file_duration, yaml_fileobj%file_duration_units, &
679 nsubregion =
get_num_blocks(diag_yaml_id,
"sub_region", parent_block_id=diag_file_id)
680 if (nsubregion .eq. 1)
then
681 max_subaxes = max_subaxes + 1
682 call get_block_ids(diag_yaml_id,
"sub_region", sub_region_id, parent_block_id=diag_file_id)
684 call get_sub_region(diag_yaml_id, sub_region_id(1), yaml_fileobj%file_sub_region, grid_type, &
685 yaml_fileobj%file_fname)
686 elseif (nsubregion .eq. 0)
then
687 yaml_fileobj%file_sub_region%grid_type = null_gridtype
689 call mpp_error(fatal,
"diag_yaml_object_init: file "//trim(yaml_fileobj%file_fname)//
" has multiple region blocks")
693 natt =
get_num_blocks(diag_yaml_id,
"global_meta", parent_block_id=diag_file_id)
694 if (natt .eq. 1)
then
695 call get_block_ids(diag_yaml_id,
"global_meta", global_att_id, parent_block_id=diag_file_id)
696 nkeys =
get_nkeys(diag_yaml_id, global_att_id(1))
697 allocate(key_ids(nkeys))
698 call get_key_ids(diag_yaml_id, global_att_id(1), key_ids)
700 allocate(yaml_fileobj%file_global_meta(nkeys, 2))
702 call get_key_name(diag_yaml_id, key_ids(j), yaml_fileobj%file_global_meta(j, 1))
703 call get_key_value(diag_yaml_id, key_ids(j), yaml_fileobj%file_global_meta(j, 2))
706 elseif (natt .ne. 0)
then
707 call mpp_error(fatal,
"diag_yaml_object_init: file "//trim(yaml_fileobj%file_fname)//&
708 &
" has multiple global_meta blocks")
718 yaml_fileobj%use_collective_writes = .false.
720 yaml_fileobj%use_collective_writes, is_optional=.true.)
722 yaml_fileobj%default_chunksizes = diag_null
724 yaml_fileobj%default_chunksizes, is_optional=.true.)
731 has_module_block, mod_name)
732 integer,
intent(in) :: diag_file_id
734 integer,
intent(in) :: var_id
736 logical,
intent(in) :: allow_averages
737 logical,
intent(in) :: has_module_block
738 character(len=*),
intent(in) :: mod_name
741 integer :: var_att_id(1)
745 integer,
allocatable :: key_ids(:)
746 character(len=:),
ALLOCATABLE :: buffer
750 if (yaml_fileobj%default_var_reduction .eq.
"")
then
756 if (trim(buffer) .eq.
"") buffer = yaml_fileobj%default_var_reduction
761 if (.not. allow_averages)
then
762 if (field%var_reduction .ne.
time_none) &
763 call mpp_error(fatal,
"The file "//field%var_fname//
" can only have variables that have none as "//&
764 "the reduction method because the frequency is either -1 or 0. "//&
765 "Check your diag_table.yaml for the field:"//trim(field%var_varname))
768 if (yaml_fileobj%default_var_module .eq.
"" .and. .not. has_module_block)
then
773 if (trim(buffer) .eq.
"")
then
774 if (has_module_block)
then
775 field%var_module = trim(mod_name)
777 field%var_module = yaml_fileobj%default_var_module
780 field%var_module = trim(buffer)
785 if (yaml_fileobj%default_var_precision .eq.
"")
then
791 if (trim(buffer) .eq.
"") buffer = yaml_fileobj%default_var_precision
800 natt =
get_num_blocks(diag_file_id,
"attributes", parent_block_id=var_id)
801 if (natt .eq. 1)
then
802 call get_block_ids(diag_file_id,
"attributes", var_att_id, parent_block_id=var_id)
803 nkeys =
get_nkeys(diag_file_id, var_att_id(1))
804 allocate(key_ids(nkeys))
805 call get_key_ids(diag_file_id, var_att_id(1), key_ids)
807 allocate(field%var_attributes(nkeys, 2))
809 call get_key_name(diag_file_id, key_ids(j), field%var_attributes(j, 1))
810 call get_key_value(diag_file_id, key_ids(j), field%var_attributes(j, 2))
813 elseif (natt .ne. 0)
then
814 call mpp_error(fatal,
"diag_yaml_object_init: variable "//trim(field%var_varname)//&
815 " has multiple attribute blocks")
819 field%var_zbounds = diag_null
820 call get_value_from_key(diag_file_id, var_id,
"zbounds", field%var_zbounds, is_optional=.true.)
821 if (field%has_var_zbounds()) max_subaxes = max_subaxes + 1
823 field%chunksizes = diag_null
824 call get_value_from_key(diag_file_id, var_id,
"chunksizes", field%chunksizes, is_optional=.true.)
825 if (.not. field%has_chunksizes())
then
826 field%chunksizes = yaml_fileobj%default_chunksizes
833 integer,
intent(in) :: diag_file_id
834 integer,
intent(in) :: par_id
835 character(len=*),
intent(in) :: key_name
836 character(len=:),
allocatable :: value_name
837 logical,
intent(in),
optional :: is_optional
839 character(len=255) :: buffer
842 call get_value_from_key(diag_file_id, par_id, trim(key_name), buffer, is_optional= is_optional)
843 allocate(
character(len=len_trim(buffer)) :: value_name)
844 value_name = trim(buffer)
849 subroutine get_sub_region(diag_yaml_id, sub_region_id, sub_region, grid_type, fname)
850 integer,
intent(in) :: diag_yaml_id
851 integer,
intent(in) :: sub_region_id
853 character(len=*),
intent(in) :: grid_type
854 character(len=*),
intent(in) :: fname
856 select case (trim(grid_type))
858 sub_region%grid_type = latlon_gridtype
859 allocate(real(kind=r4_kind) :: sub_region%corners(4,2))
861 sub_region%grid_type = index_gridtype
862 allocate(
integer(kind=i4_kind) :: sub_region%corners(4,2))
864 call get_value_from_key(diag_yaml_id, sub_region_id,
"tile", sub_region%tile, is_optional=.true.)
865 if (sub_region%tile .eq. diag_null)
call mpp_error(fatal, &
866 "The tile number is required when defining a "//&
867 "subregion. Check your subregion entry for "//trim(fname))
869 call mpp_error(fatal, trim(grid_type)//
" is not a valid region type. &
870 &The acceptable values are latlon and index. &
871 &Check your entry for file:"//trim(fname))
874 call get_value_from_key(diag_yaml_id, sub_region_id,
"corner1", sub_region%corners(1,:))
875 call get_value_from_key(diag_yaml_id, sub_region_id,
"corner2", sub_region%corners(2,:))
876 call get_value_from_key(diag_yaml_id, sub_region_id,
"corner3", sub_region%corners(3,:))
877 call get_value_from_key(diag_yaml_id, sub_region_id,
"corner4", sub_region%corners(4,:))
886 integer,
intent(in) :: diag_yaml_id
887 integer,
intent(in) :: diag_file_id
888 integer :: total_nvars
892 integer,
allocatable :: var_ids(:)
895 nvars =
get_num_blocks(diag_yaml_id,
"varlist", parent_block_id=diag_file_id)
896 allocate(var_ids(nvars))
897 call get_block_ids(diag_yaml_id,
"varlist", var_ids, parent_block_id=diag_file_id)
903 call get_value_from_key(diag_yaml_id, var_ids(i),
"write_var", var_write, is_optional=.true.)
904 if (var_write) total_nvars = total_nvars + 1
909 subroutine parse_key(filename, buffer, file_freq, file_frequnit, var)
910 character(len=*),
intent(in) :: filename
911 character(len=*),
intent(inout) :: buffer
912 integer,
intent(out) :: file_freq(:)
914 integer,
intent(out) :: file_frequnit(:)
916 character(len=*),
intent(in) :: var
922 character(len=255) :: str
923 character(len=10) :: units
926 if (buffer .eq.
"")
return
931 do while (.not. finished)
933 buffer = buffer(j+1:len_trim(buffer))
934 j = index(buffer,
",")
937 j = len_trim(buffer)+1
941 str = adjustl(buffer(1:j-1))
944 read(str(1:k-1), *, iostat=err_unit) file_freq(count)
945 units = str(k+1:len_trim(str))
947 if (err_unit .ne. 0) &
948 call mpp_error(fatal,
"Error parsing "//trim(var)//
". Check your entry for file"//&
951 if (file_freq(count) .lt. -1) &
952 call mpp_error(fatal, trim(var)//
" is not valid. &
953 &Check your entry for file:"//trim(filename))
955 if (file_freq(count) .eq. -1 .or. file_freq(count) .eq. 0)
then
957 file_frequnit(count) = diag_days
959 if (trim(units) .eq.
"") &
960 call mpp_error(fatal, trim(var)//
" units is required. &
961 &Check your entry for file:"//trim(filename))
964 trim(var)//
" for file:"//trim(filename))
972 character(len=*),
intent(in) :: file_timeunit
974 yaml_fileobj%file_timeunit =
set_valid_time_units(file_timeunit,
"timeunit for file:"//trim(yaml_fileobj%file_fname))
980 character(len=*),
intent(in) :: filename_time
982 select case (trim(filename_time))
990 yaml_fileobj%filename_time =
end_time
992 call mpp_error(fatal, trim(filename_time)//
" is an invalid filename_time &
993 &The acceptable values are begin, middle, and end. &
994 &Check your entry for file "//trim(yaml_fileobj%file_fname))
1001 character(len=*),
intent(in) :: skind
1003 select case (trim(skind))
1013 call mpp_error(fatal, trim(skind)//
" is an invalid kind! &
1014 &The acceptable values are r4, r8, i4, i8. &
1015 &Check your entry for file:"//trim(field%var_varname)//
" in file "//trim(field%var_fname))
1024 character(len=*) ,
intent(in) :: reduction_method
1026 integer :: n_diurnal
1027 integer :: pow_value
1033 if (index(reduction_method,
"diurnal") .ne. 0)
then
1034 READ (reduction_method(8:len_trim(reduction_method)), fmt=*, iostat=ioerror) n_diurnal
1035 if (ioerror .ne. 0) &
1036 call mpp_error(fatal,
"Error getting the number of diurnal samples from "//trim(reduction_method))
1037 if (n_diurnal .le. 0) &
1038 call mpp_error(fatal,
"Diurnal samples should be greater than 0. &
1039 & Check your entry for file:"//trim(field%var_varname)//
" in file "//trim(field%var_fname))
1041 elseif (index(reduction_method,
"pow") .ne. 0)
then
1042 READ (reduction_method(4:len_trim(reduction_method)), fmt=*, iostat=ioerror) pow_value
1043 if (ioerror .ne. 0) &
1044 call mpp_error(fatal,
"Error getting the power value from "//trim(reduction_method))
1045 if (pow_value .le. 0) &
1046 call mpp_error(fatal,
"The power value should be greater than 0. &
1047 & Check your entry for file:"//trim(field%var_varname)//
" in file "//trim(field%var_fname))
1050 select case (reduction_method)
1064 call mpp_error(fatal, trim(reduction_method)//
" is an invalid reduction method! &
1065 &The acceptable values are none, average, pow##, diurnal##, min, max, and rms. &
1066 &Check your entry for file:"//trim(field%var_varname)//
" in file "//trim(field%var_fname))
1070 field%n_diurnal = n_diurnal
1071 field%pow_value = pow_value
1077 result(time_units_int)
1079 character(len=*),
intent(in) :: time_units
1080 character(len=*),
intent(in) :: error_msg
1082 integer :: time_units_int
1084 select case (trim(time_units))
1086 time_units_int = diag_seconds
1088 time_units_int = diag_minutes
1090 time_units_int = diag_hours
1092 time_units_int = diag_days
1094 time_units_int = diag_months
1096 time_units_int = diag_years
1098 time_units_int =diag_null
1099 call mpp_error(fatal, trim(error_msg)//
" is not valid. Acceptable values are &
1100 &seconds, minutes, hours, days, months, years")
1117 character (len=:),
allocatable :: res
1118 res = this%file_fname
1126 res = this%file_frequnit(this%current_new_file_freq_index)
1134 res = this%file_freq(this%current_new_file_freq_index)
1142 res = this%file_timeunit
1149 character (len=:),
allocatable :: res
1150 res = this%file_unlimdim
1158 res => this%file_sub_region
1166 res = this%file_new_file_freq(this%current_new_file_freq_index)
1174 res = this%file_new_file_freq_units(this%current_new_file_freq_index)
1181 type(time_type) :: res
1182 res = this%file_start_time
1190 res = this%file_duration(this%current_new_file_freq_index)
1198 res = this%file_duration_units(this%current_new_file_freq_index)
1205 character (:),
allocatable :: res(:)
1206 res = this%file_varlist
1213 character (len=MAX_STR_LEN),
allocatable :: res(:,:)
1214 res = this%file_global_meta
1223 res = this%filename_time
1232 if (
allocated(this%file_global_meta)) &
1243 res = this%use_collective_writes
1249 this%current_new_file_freq_index = this%current_new_file_freq_index + 1
1263 character (len=:),
allocatable :: res
1264 res = this%var_fname
1271 character (len=:),
allocatable :: res
1272 res = this%var_varname
1279 integer,
allocatable :: res
1280 res = this%var_reduction
1287 character (len=:),
allocatable :: res
1288 res = this%var_module
1295 integer,
allocatable :: res
1303 character (len=:),
allocatable :: res
1305 if (this%has_var_outname())
then
1306 res = this%var_outname
1308 res = this%var_varname
1316 character (len=:),
allocatable :: res
1317 res = this%var_longname
1324 character (len=:),
allocatable :: res
1325 res = this%var_units
1332 real(kind=r4_kind) :: res(2)
1333 res = this%var_zbounds
1340 character (len=MAX_STR_LEN),
allocatable :: res (:,:)
1341 res = this%var_attributes
1349 res = this%n_diurnal
1357 res = this%pow_value
1365 integer :: res(max_dimensions)
1367 res = this%chunksizes
1377 if (
allocated(this%var_attributes)) &
1386 obj%file_freq = diag_null
1387 obj%file_sub_region%tile = diag_null
1388 obj%file_new_file_freq = diag_null
1389 obj%file_duration = diag_null
1390 obj%file_new_file_freq_units = diag_null
1391 obj%file_duration_units = diag_null
1392 obj%current_new_file_freq_index = 1
1405 has_file_frequnit = this%file_frequnit(this%current_new_file_freq_index) .NE. diag_null
1435 if ( this%file_sub_region%grid_type .eq. latlon_gridtype .or. this%file_sub_region%grid_type .eq. index_gridtype)
then
1463 has_file_duration = this%file_duration(this%current_new_file_freq_index) .ne. diag_null
1524 if (
allocated(this%var_outname))
then
1525 if (trim(this%var_outname) .ne.
"")
then
1614 nfields = fms_find_unique(variable_list%var_pointer,
size(variable_list%var_pointer))
1623 character(len=*),
intent(in) :: diag_field_name
1624 character(len=*),
intent(in) :: module_name
1626 integer,
allocatable :: indices(:)
1628 indices = fms_find_my_string(variable_list%var_pointer,
size(variable_list%var_pointer), &
1629 & lowercase(trim(diag_field_name))//
":"//lowercase(trim(module_name)//c_null_char))
1637 integer,
intent(in) :: indices(:)
1643 allocate(diag_field(
size(indices)))
1645 do i = 1,
size(indices)
1646 field_id = variable_list%diag_field_indices(indices(i))
1647 diag_field(i) = diag_yaml%diag_fields(field_id)
1656 integer,
intent(in) :: indices(:)
1657 integer,
allocatable :: field_ids(:)
1660 allocate(field_ids(
size(indices)))
1662 do i = 1,
size(indices)
1663 field_ids(i) = variable_list%diag_field_indices(indices(i))
1673 integer,
intent(in) :: indices(:)
1674 integer,
allocatable :: file_id(:)
1678 character(len=FMS_FILE_LEN) :: filename
1679 integer,
allocatable :: file_indices(:)
1681 allocate(file_id(
size(indices)))
1683 do i = 1,
size(indices)
1684 field_id = variable_list%diag_field_indices(indices(i))
1686 filename = diag_yaml%diag_fields(field_id)%var_fname
1689 file_indices = fms_find_my_string(file_list%file_pointer,
size(file_list%file_pointer), &
1690 & trim(filename)//c_null_char)
1692 if (
size(file_indices) .ne. 1) &
1693 &
call mpp_error(fatal,
"get_diag_files_id: Error getting the correct number of file indices!"//&
1694 " The diag file "//trim(filename)//
" was defined "//string(
size(file_indices))&
1697 if (file_indices(1) .eq. diag_null) &
1698 &
call mpp_error(fatal,
"get_diag_files_id: Error finding the file "//trim(filename)//
" in the diag_files yaml")
1701 file_id(i) = file_list%diag_file_indices(file_indices(1))
1709 character(len=*),
optional,
intent(in) :: filename
1713 integer :: i, unit_num
1714 if(
present(filename))
then
1715 open(newunit=unit_num, file=trim(filename), action=
'WRITE')
1720 if(
mpp_pe() .eq. mpp_root_pe())
then
1721 write(unit_num, *)
'**********Dumping diag_yaml object**********'
1722 if( diag_yaml%has_diag_title())
write(unit_num, *)
'Title:', diag_yaml%diag_title
1723 if( diag_yaml%has_diag_basedate())
write(unit_num, *)
'basedate array:', diag_yaml%diag_basedate
1724 write(unit_num, *)
'FILES'
1725 allocate(fields(
SIZE(diag_yaml%get_diag_fields())))
1726 files => diag_yaml%diag_files
1727 fields = diag_yaml%get_diag_fields()
1729 write(unit_num, *)
'File: ', files(i)%get_file_fname()
1730 if(files(i)%has_file_frequnit())
write(unit_num, *)
'file_frequnit:', files(i)%get_file_frequnit()
1731 if(files(i)%has_file_freq())
write(unit_num, *)
'freq:', files(i)%get_file_freq()
1732 if(files(i)%has_file_timeunit())
write(unit_num, *)
'timeunit:', files(i)%get_file_timeunit()
1733 if(files(i)%has_file_unlimdim())
write(unit_num, *)
'unlimdim:', files(i)%get_file_unlimdim()
1735 if(files(i)%has_file_new_file_freq())
write(unit_num, *)
'new_file_freq:', files(i)%get_file_new_file_freq()
1736 if(files(i)%has_file_new_file_freq_units())
write(unit_num, *)
'new_file_freq_units:', &
1737 & files(i)%get_file_new_file_freq_units()
1738 if(files(i)%has_file_start_time())
write(unit_num, *)
'start_time:', &
1739 & date_to_string(files(i)%get_file_start_time())
1740 if(files(i)%has_file_duration())
write(unit_num, *)
'duration:', files(i)%get_file_duration()
1741 if(files(i)%has_file_duration_units())
write(unit_num, *)
'duration_units:', files(i)%get_file_duration_units()
1742 if(files(i)%has_file_varlist())
write(unit_num, *)
'varlist:', files(i)%get_file_varlist()
1743 if(files(i)%has_file_global_meta())
write(unit_num, *)
'global_meta:', files(i)%get_file_global_meta()
1744 if(files(i)%is_global_meta())
write(unit_num, *)
'global_meta:', files(i)%is_global_meta()
1745 write(unit_num, *)
''
1747 write(unit_num, *)
'FIELDS'
1748 do i=1,
SIZE(fields)
1749 write(unit_num, *)
'Field: ', fields(i)%get_var_fname()
1750 if(fields(i)%has_var_fname())
write(unit_num, *)
'fname:', fields(i)%get_var_fname()
1751 if(fields(i)%has_var_varname())
write(unit_num, *)
'varname:', fields(i)%get_var_varname()
1752 if(fields(i)%has_var_reduction())
write(unit_num, *)
'reduction:', fields(i)%get_var_reduction()
1753 if(fields(i)%has_var_module())
write(unit_num, *)
'module:', fields(i)%get_var_module()
1754 if(fields(i)%has_var_kind())
write(unit_num, *)
'kind:', fields(i)%get_var_kind()
1755 if(fields(i)%has_var_outname())
write(unit_num, *)
'outname:', fields(i)%get_var_outname()
1756 if(fields(i)%has_var_longname())
write(unit_num, *)
'longname:', fields(i)%get_var_longname()
1757 if(fields(i)%has_var_units())
write(unit_num, *)
'units:', fields(i)%get_var_units()
1758 if(fields(i)%has_var_zbounds())
write(unit_num, *)
'zbounds:', fields(i)%get_var_zbounds()
1759 if(fields(i)%has_var_attributes())
write(unit_num, *)
'attributes:', fields(i)%get_var_attributes()
1760 if(fields(i)%has_n_diurnal())
write(unit_num, *)
'n_diurnal:', fields(i)%get_n_diurnal()
1761 if(fields(i)%has_pow_value())
write(unit_num, *)
'pow_value:', fields(i)%get_pow_value()
1762 if(fields(i)%has_var_attributes())
write(unit_num, *)
'is_var_attributes:', fields(i)%is_var_attributes()
1766 if(
present(filename))
then
1776 integer,
intent(in) :: ntimes(:)
1777 integer,
intent(in) :: ntiles(:)
1778 integer,
intent(in) :: ndistributedfiles(:)
1782 type (fmsyamloutkeys_type),
allocatable :: keys(:), keys2(:), keys3(:)
1783 type (fmsyamloutvalues_type),
allocatable :: vals(:), vals2(:), vals3(:)
1785 character(len=128) :: tmpstr1, tmpstr2
1786 integer,
parameter :: tier1size = 3
1787 integer :: tier2size, tier3size
1788 integer,
allocatable :: tier3each(:)
1789 integer,
dimension(basedate_size) :: basedate_loc
1790 integer :: varnum_i, key3_i, gm
1791 character(len=32),
allocatable :: st_vals(:)
1792 character(len=FMS_FILE_LEN) :: filename
1797 if(
mpp_pe() .ne. mpp_root_pe())
return
1799 allocate(tier3each(
SIZE(diag_yaml%diag_files) * 3))
1800 tier3size = 0; tier3each = 0
1805 allocate(keys2(
SIZE(diag_yaml%diag_files)))
1806 allocate(vals2(
SIZE(diag_yaml%diag_files)))
1807 allocate(st_vals(
SIZE(diag_yaml%diag_files)))
1808 do i=1,
SIZE(diag_yaml%diag_files)
1809 call initialize_key_struct(keys2(i))
1810 call initialize_val_struct(vals2(i))
1811 if (
allocated(diag_yaml%diag_files(i)%file_varlist) )
then
1812 do j=1,
SIZE(diag_yaml%diag_files(i)%file_varlist)
1813 tier3size = tier3size + 1
1816 tier3size = tier3size + 2
1818 allocate(keys3(tier3size))
1819 allocate(vals3(tier3size))
1822 call initialize_key_struct(keys(1))
1823 call initialize_val_struct(vals(1))
1824 call fms_f2c_string( keys(1)%key1,
'title')
1825 call fms_f2c_string( vals(1)%val1, diag_yaml%diag_title)
1826 call fms_f2c_string( keys(1)%key2,
'base_date')
1827 basedate_loc = diag_yaml%get_basedate()
1828 tmpstr1 =
''; tmpstr2 =
''
1829 tmpstr1 = string(basedate_loc(1))
1830 tmpstr2 = trim(tmpstr1)
1831 do i=2, basedate_size
1832 tmpstr1 = string(basedate_loc(i))
1833 tmpstr2 = trim(tmpstr2) //
' ' // trim(tmpstr1)
1835 call fms_f2c_string(vals(1)%val2, trim(tmpstr2))
1836 call yaml_out_add_level2key(
'diag_files', keys(1))
1839 do i=1,
SIZE(diag_yaml%diag_files)
1840 fileptr => diag_yaml%diag_files(i)
1842 call fms_f2c_string(keys2(i)%key1,
'file_name')
1843 call fms_f2c_string(keys2(i)%key2,
'freq')
1844 call fms_f2c_string(keys2(i)%key3,
'freq_units')
1845 call fms_f2c_string(keys2(i)%key4,
'time_units')
1846 call fms_f2c_string(keys2(i)%key5,
'unlimdim')
1847 call fms_f2c_string(keys2(i)%key6,
'new_file_freq')
1848 call fms_f2c_string(keys2(i)%key7,
'new_file_freq_units')
1849 call fms_f2c_string(keys2(i)%key8,
'start_time')
1850 call fms_f2c_string(keys2(i)%key9,
'file_duration')
1851 call fms_f2c_string(keys2(i)%key10,
'file_duration_units')
1854 call fms_f2c_string(keys2(i)%key11,
'number_of_timelevels')
1859 call fms_f2c_string(keys2(i)%key12,
'number_of_tiles')
1865 call fms_f2c_string(keys2(i)%key13,
'number_of_distributed_files')
1867 call fms_f2c_string(vals2(i)%val1, fileptr%file_fname)
1868 call fms_f2c_string(vals2(i)%val5, fileptr%file_unlimdim)
1871 do k=1,
SIZE(fileptr%file_freq)
1872 if(fileptr%file_freq(k) .eq. diag_null)
exit
1874 tmpstr2 = string(fileptr%file_freq(k))
1875 tmpstr1 = trim(tmpstr1)//
" "//trim(tmpstr2)
1877 call fms_f2c_string(vals2(i)%val2, adjustl(tmpstr1))
1880 do k=1,
SIZE(fileptr%file_new_file_freq)
1881 if(fileptr%file_new_file_freq(k) .eq. diag_null)
exit
1883 tmpstr2 = string(fileptr%file_new_file_freq(k))
1884 tmpstr1 = trim(tmpstr1)//
" "//trim(tmpstr2)
1886 call fms_f2c_string(vals2(i)%val6, adjustl(tmpstr1))
1888 if (fileptr%has_file_start_time())
then
1889 call fms_f2c_string(vals2(i)%val8, trim(date_to_string(fileptr%get_file_start_time())))
1891 call fms_f2c_string(vals2(i)%val8,
"")
1894 do k=1,
SIZE(fileptr%file_duration)
1895 if(fileptr%file_duration(k) .eq. diag_null)
exit
1897 tmpstr2 = string(fileptr%file_duration(k))
1898 tmpstr1 = trim(tmpstr1)//
" "//trim(tmpstr2)
1900 call fms_f2c_string(vals2(i)%val9, adjustl(tmpstr1))
1902 call fms_f2c_string(vals2(i)%val11, string(ntimes(i)))
1903 call fms_f2c_string(vals2(i)%val12, string(ntiles(i)))
1904 call fms_f2c_string(vals2(i)%val13, string(ndistributedfiles(i)))
1907 call yaml_out_add_level2key(
'varlist', keys2(i))
1909 if(
SIZE(fileptr%file_varlist) .gt. 0)
then
1910 do j=1,
SIZE(fileptr%file_varlist)
1912 call initialize_key_struct(keys3(key3_i))
1913 call initialize_val_struct(vals3(key3_i))
1916 do varnum_i=1,
SIZE(diag_yaml%diag_fields)
1917 if( trim(diag_yaml%diag_fields(varnum_i)%var_varname ) .eq. trim(fileptr%file_varlist(j)) .and. &
1918 trim(diag_yaml%diag_fields(varnum_i)%var_fname) .eq. trim(fileptr%file_fname))
then
1920 if(diag_yaml%diag_fields(varnum_i)%has_var_outname())
then
1921 if(trim(diag_yaml%diag_fields(varnum_i)%var_outname) .eq. trim(fileptr%file_outlist(j)))
then
1922 varptr => diag_yaml%diag_fields(varnum_i)
1926 varptr => diag_yaml%diag_fields(varnum_i)
1931 if( .not.
associated(varptr))
call mpp_error(fatal,
"diag_yaml_output: could not find variable in list."//&
1932 " var: "// trim(fileptr%file_varlist(j)))
1933 call fms_f2c_string(keys3(key3_i)%key1,
'module')
1934 call fms_f2c_string(keys3(key3_i)%key2,
'var_name')
1935 call fms_f2c_string(keys3(key3_i)%key3,
'reduction')
1936 call fms_f2c_string(keys3(key3_i)%key4,
'kind')
1937 call fms_f2c_string(keys3(key3_i)%key5,
'output_name')
1938 call fms_f2c_string(keys3(key3_i)%key6,
'long_name')
1939 call fms_f2c_string(keys3(key3_i)%key7,
'units')
1940 call fms_f2c_string(keys3(key3_i)%key8,
'zbounds')
1941 call fms_f2c_string(keys3(key3_i)%key9,
'n_diurnal')
1942 call fms_f2c_string(keys3(key3_i)%key10,
'pow_value')
1943 call fms_f2c_string(keys3(key3_i)%key11,
'dimensions')
1944 call fms_f2c_string(keys3(key3_i)%key12,
'standard_name')
1945 if (varptr%has_var_module())
call fms_f2c_string(vals3(key3_i)%val1, varptr%var_module)
1946 if (varptr%has_var_varname())
call fms_f2c_string(vals3(key3_i)%val2, varptr%var_varname)
1947 if (varptr%has_var_reduction())
then
1948 call fms_f2c_string(vals3(key3_i)%val3, &
1951 if (varptr%has_var_outname())
call fms_f2c_string(vals3(key3_i)%val5, varptr%var_outname)
1952 if (varptr%has_var_longname())
call fms_f2c_string(vals3(key3_i)%val6, varptr%var_longname)
1953 if (varptr%has_var_units())
call fms_f2c_string(vals3(key3_i)%val7, varptr%var_units)
1954 if (varptr%has_var_kind())
then
1955 select case(varptr%var_kind)
1957 call fms_f2c_string(vals3(key3_i)%val4,
'i4')
1959 call fms_f2c_string(vals3(key3_i)%val4,
'i8')
1961 call fms_f2c_string(vals3(key3_i)%val4,
'r4')
1963 call fms_f2c_string(vals3(key3_i)%val4,
'r8')
1967 if( abs(varptr%var_zbounds(1) - real(diag_null, r4_kind)) .gt. 1.0e-5 )
then
1968 tmpstr2 = string(varptr%var_zbounds(1),
"F8.2") //
' ' // string(varptr%var_zbounds(2),
"F8.2")
1969 call fms_f2c_string(vals3(key3_i)%val8, trim(tmpstr2))
1972 if( varptr%n_diurnal .gt. 0)
then
1973 tmpstr1 =
''; tmpstr1 = string(varptr%n_diurnal)
1974 call fms_f2c_string(vals3(key3_i)%val9, tmpstr1)
1977 if( varptr%pow_value .gt. 0)
then
1978 tmpstr1 =
''; tmpstr1 = string(varptr%pow_value)
1979 call fms_f2c_string(vals3(key3_i)%val10, tmpstr1)
1982 tmpstr1 =
''; tmpstr1 = varptr%var_axes_names
1983 call fms_f2c_string(vals3(key3_i)%val11, trim(adjustl(tmpstr1)))
1985 if(diag_yaml%diag_fields(varnum_i)%has_standname())&
1986 call fms_f2c_string(vals3(key3_i)%val12, diag_yaml%diag_fields(varnum_i)%standard_name)
1991 tier3each(i*3-2) = j-1
1992 tier3each(i*3-1) = 1
1994 call initialize_key_struct(keys3(key3_i))
1995 call initialize_val_struct(vals3(key3_i))
1997 call yaml_out_add_level2key(
'sub_region', keys2(i))
1998 call fms_f2c_string(keys3(key3_i)%key1,
'grid_type')
1999 call fms_f2c_string(keys3(key3_i)%key2,
'tile')
2000 call fms_f2c_string(keys3(key3_i)%key3,
'corner1')
2001 call fms_f2c_string(keys3(key3_i)%key4,
'corner2')
2002 call fms_f2c_string(keys3(key3_i)%key5,
'corner3')
2003 call fms_f2c_string(keys3(key3_i)%key6,
'corner4')
2005 select case (fileptr%file_sub_region%grid_type)
2006 case(latlon_gridtype)
2007 call fms_f2c_string(vals3(key3_i)%val1,
'latlon')
2008 case(index_gridtype)
2009 call fms_f2c_string(vals3(key3_i)%val1,
'index')
2011 if(fileptr%file_sub_region%tile .ne. diag_null)
then
2012 tmpstr1 =
''; tmpstr1 = string(fileptr%file_sub_region%tile)
2013 call fms_f2c_string(vals3(key3_i)%val2, tmpstr1)
2015 if(fileptr%has_file_sub_region())
then
2016 if(
allocated(fileptr%file_sub_region%corners))
then
2017 select type (corners => fileptr%file_sub_region%corners)
2018 type is (real(r8_kind))
2019 tmpstr1 =
''; tmpstr1 = string(corners(1,1))
2020 tmpstr2 =
''; tmpstr2 = string(corners(1,2))
2021 call fms_f2c_string(vals3(key3_i)%val3, trim(tmpstr1)//
' '//trim(tmpstr2))
2022 tmpstr1 =
''; tmpstr1 = string(corners(2,1))
2023 tmpstr2 =
''; tmpstr2 = string(corners(2,2))
2024 call fms_f2c_string(vals3(key3_i)%val4, trim(tmpstr1)//
' '//trim(tmpstr2))
2025 tmpstr1 =
''; tmpstr1 = string(corners(3,1))
2026 tmpstr2 =
''; tmpstr2 = string(corners(3,2))
2027 call fms_f2c_string(vals3(key3_i)%val5, trim(tmpstr1)//
' '//trim(tmpstr2))
2028 tmpstr1 =
''; tmpstr1 = string(corners(4,1))
2029 tmpstr2 =
''; tmpstr2 = string(corners(4,2))
2030 call fms_f2c_string(vals3(key3_i)%val6, trim(tmpstr1)//
' '//trim(tmpstr2))
2031 type is (real(r4_kind))
2032 tmpstr1 =
''; tmpstr1 = string(corners(1,1))
2033 tmpstr2 =
''; tmpstr2 = string(corners(1,2))
2034 call fms_f2c_string(vals3(key3_i)%val3, trim(tmpstr1)//
' '//trim(tmpstr2))
2035 tmpstr1 =
''; tmpstr1 = string(corners(2,1))
2036 tmpstr2 =
''; tmpstr2 = string(corners(2,2))
2037 call fms_f2c_string(vals3(key3_i)%val4, trim(tmpstr1)//
' '//trim(tmpstr2))
2038 tmpstr1 =
''; tmpstr1 = string(corners(3,1))
2039 tmpstr2 =
''; tmpstr2 = string(corners(3,2))
2040 call fms_f2c_string(vals3(key3_i)%val5, trim(tmpstr1)//
' '//trim(tmpstr2))
2041 tmpstr1 =
''; tmpstr1 = string(corners(4,1))
2042 tmpstr2 =
''; tmpstr2 = string(corners(4,2))
2043 call fms_f2c_string(vals3(key3_i)%val6, trim(tmpstr1)//
' '//trim(tmpstr2))
2044 type is (
integer(i4_kind))
2045 tmpstr1 =
''; tmpstr1 = string(corners(1,1))
2046 tmpstr2 =
''; tmpstr2 = string(corners(1,2))
2047 call fms_f2c_string(vals3(key3_i)%val3, trim(tmpstr1)//
' '//trim(tmpstr2))
2048 tmpstr1 =
''; tmpstr1 = string(corners(2,1))
2049 tmpstr2 =
''; tmpstr2 = string(corners(2,2))
2050 call fms_f2c_string(vals3(key3_i)%val4, trim(tmpstr1)//
' '//trim(tmpstr2))
2051 tmpstr1 =
''; tmpstr1 = string(corners(3,1))
2052 tmpstr2 =
''; tmpstr2 = string(corners(3,2))
2053 call fms_f2c_string(vals3(key3_i)%val5, trim(tmpstr1)//
' '//trim(tmpstr2))
2054 tmpstr1 =
''; tmpstr1 = string(corners(4,1))
2055 tmpstr2 =
''; tmpstr2 = string(corners(4,2))
2056 call fms_f2c_string(vals3(key3_i)%val6, trim(tmpstr1)//
' '//trim(tmpstr2))
2057 type is (
integer(i8_kind))
2058 tmpstr1 =
''; tmpstr1 = string(corners(1,1))
2059 tmpstr2 =
''; tmpstr2 = string(corners(1,2))
2060 call fms_f2c_string(vals3(key3_i)%val3, trim(tmpstr1)//
' '//trim(tmpstr2))
2061 tmpstr1 =
''; tmpstr1 = string(corners(2,1))
2062 tmpstr2 =
''; tmpstr2 = string(corners(2,2))
2063 call fms_f2c_string(vals3(key3_i)%val4, trim(tmpstr1)//
' '//trim(tmpstr2))
2064 tmpstr1 =
''; tmpstr1 = string(corners(3,1))
2065 tmpstr2 =
''; tmpstr2 = string(corners(3,2))
2066 call fms_f2c_string(vals3(key3_i)%val5, trim(tmpstr1)//
' '//trim(tmpstr2))
2067 tmpstr1 =
''; tmpstr1 = string(corners(4,1))
2068 tmpstr2 =
''; tmpstr2 = string(corners(4,2))
2069 call fms_f2c_string(vals3(key3_i)%val6, trim(tmpstr1)//
' '//trim(tmpstr2))
2075 call initialize_key_struct(keys3(key3_i))
2076 call initialize_val_struct(vals3(key3_i))
2077 call yaml_out_add_level2key(
'global_meta', keys2(i))
2078 if ( fileptr%has_file_global_meta())
then
2079 do gm=1,
SIZE(fileptr%file_global_meta, 1)
2082 call fms_f2c_string(keys3(key3_i)%key1, fileptr%file_global_meta(1,1))
2083 call fms_f2c_string(vals3(key3_i)%val1, fileptr%file_global_meta(1,2))
2085 call fms_f2c_string(keys3(key3_i)%key2, fileptr%file_global_meta(2,1))
2086 call fms_f2c_string(vals3(key3_i)%val2, fileptr%file_global_meta(2,2))
2088 call fms_f2c_string(keys3(key3_i)%key3, fileptr%file_global_meta(3,1))
2089 call fms_f2c_string(vals3(key3_i)%val3, fileptr%file_global_meta(3,2))
2091 call fms_f2c_string(keys3(key3_i)%key4, fileptr%file_global_meta(4,1))
2092 call fms_f2c_string(vals3(key3_i)%val4, fileptr%file_global_meta(4,2))
2094 call fms_f2c_string(keys3(key3_i)%key5, fileptr%file_global_meta(5,1))
2095 call fms_f2c_string(vals3(key3_i)%val5, fileptr%file_global_meta(5,2))
2097 call fms_f2c_string(keys3(key3_i)%key6, fileptr%file_global_meta(6,1))
2098 call fms_f2c_string(vals3(key3_i)%val6, fileptr%file_global_meta(6,2))
2100 call fms_f2c_string(keys3(key3_i)%key7, fileptr%file_global_meta(7,1))
2101 call fms_f2c_string(vals3(key3_i)%val7, fileptr%file_global_meta(7,2))
2103 call fms_f2c_string(keys3(key3_i)%key8, fileptr%file_global_meta(8,1))
2104 call fms_f2c_string(vals3(key3_i)%val8, fileptr%file_global_meta(8,2))
2106 call fms_f2c_string(keys3(key3_i)%key9, fileptr%file_global_meta(9,1))
2107 call fms_f2c_string(vals3(key3_i)%val9, fileptr%file_global_meta(9,2))
2109 call fms_f2c_string(keys3(key3_i)%key10, fileptr%file_global_meta(10,1))
2110 call fms_f2c_string(vals3(key3_i)%val10, fileptr%file_global_meta(10,2))
2112 call fms_f2c_string(keys3(key3_i)%key11, fileptr%file_global_meta(11,1))
2113 call fms_f2c_string(vals3(key3_i)%val11, fileptr%file_global_meta(11,2))
2115 call fms_f2c_string(keys3(key3_i)%key12, fileptr%file_global_meta(12,1))
2116 call fms_f2c_string(vals3(key3_i)%val12, fileptr%file_global_meta(12,2))
2118 call fms_f2c_string(keys3(key3_i)%key13, fileptr%file_global_meta(13,1))
2119 call fms_f2c_string(vals3(key3_i)%val13, fileptr%file_global_meta(13,2))
2121 call fms_f2c_string(keys3(key3_i)%key14, fileptr%file_global_meta(14,1))
2122 call fms_f2c_string(vals3(key3_i)%val14, fileptr%file_global_meta(14,2))
2124 call fms_f2c_string(keys3(key3_i)%key15, fileptr%file_global_meta(15,1))
2125 call fms_f2c_string(vals3(key3_i)%val15, fileptr%file_global_meta(15,2))
2127 call fms_f2c_string(keys3(key3_i)%key16, fileptr%file_global_meta(16,1))
2128 call fms_f2c_string(vals3(key3_i)%val16, fileptr%file_global_meta(16,2))
2135 call get_instance_filename(
'diag_manifest.yaml.'//string(
mpp_pe()), filename)
2136 call write_yaml_from_struct_3( trim(filename)//c_null_char, 1, keys, vals, &
2137 SIZE(diag_yaml%diag_files), keys2, vals2, &
2138 tier3size, tier3each, keys3, vals3, &
2139 (/
size(diag_yaml%diag_files), 0, 0, 0, 0, 0, 0, 0/))
2140 deallocate( keys, keys2, keys3, vals, vals2, vals3)
2146 integer,
intent(in) :: unit_param(:)
2149 character(len=7) :: tmp
2152 do i=1,
SIZE(unit_param)
2153 select case(unit_param(i))
2176 integer,
intent(in) :: reduction_val(:)
2179 character(len=7) :: tmp
2181 do i=1,
SIZE(reduction_val)
2182 select case (reduction_val(i))
2205 subroutine add_axis_name( this, axis_name )
2207 character(len=:),
allocatable,
intent(in) :: axis_name
2208 character(len=:),
allocatable :: tmp_str
2210 this%var_axes_names = trim(axis_name)//
" "//trim(this%var_axes_names)
2212 end subroutine add_axis_name
2217 character(len=*),
optional,
intent(in) :: standard_name
2219 if (
present(standard_name))
then
2220 this%standard_name = standard_name(1:len_trim(standard_name))
2222 this%standard_name =
""
2226 pure function is_file_subregional( this ) &
2231 res = this%var_file_is_subregional
2232 end function is_file_subregional
2235 end module fms_diag_yaml_mod
integer, parameter max_str_len
Max length for a string.
integer, parameter end_time
Use the end of the time average bounds.
integer, parameter time_min
The reduction method is min value.
subroutine set_base_time(base_time_int)
Set the module variable base_time.
integer, parameter time_diurnal
The reduction method is diurnal.
integer, parameter time_power
The reduction method is average with exponents.
integer, parameter max_dimensions
Max number of dimensions allowed (including unlimited dimension)
integer, parameter begin_time
Use the begining of the time average bounds.
integer, parameter time_average
The reduction method is average of values.
integer, parameter time_sum
The reduction method is sum of values.
integer, parameter time_rms
The reudction method is root mean square of values.
integer, parameter middle_time
Use the middle of the time average bounds.
integer, parameter time_none
There is no reduction method.
integer, parameter time_max
The reduction method is max value.
integer, parameter r8
Supported type/kind of the variable.
subroutine, public set_time_type(time_int, time)
Sets up a time_type based on 6 member array of integers defining the [year month day hour min sec].
pure logical function has_chunksizes(this)
Checks if chunksizes is set for the diag field.
integer pure function size_file_varlist(this)
Finds the number of variables in the file_varlist.
pure logical function has_diag_basedate(this)
diag_file_objdiag_basedate is on the stack, so this is always true
type(diagyamlobject_type) function, pointer, public get_diag_yaml_obj()
gets the diag_yaml module variable
type(diagyamlfilesvar_type) function, dimension(:), allocatable, public get_diag_fields_entries(indices)
Gets the diag_field entries corresponding to the indices of the sorted variable_list.
pure integer function get_filename_time(this)
Get the integer equivalent of the time to use to determine the filename, if using a wildcard file nam...
pure logical function has_file_duration_units(this)
diag_file_objfile_duration_units is on the stack, so this will retrun true
pure logical function has_var_reduction(this)
Checks if diag_file_objvar_reduction is allocated.
pure logical function has_var_attributes(this)
Checks if diag_file_objvar_attributes is allocated.
subroutine set_filename_time(yaml_fileobj, filename_time)
This checks if the filename_time in a diag file is correct and sets the integer equivalent.
pure logical function has_n_diurnal(this)
Checks if diag_file_objn_diurnal is set.
subroutine, public diag_yaml_object_end()
Destroys the diag_yaml object.
pure integer function get_pow_value(this)
Inquiry for diag_yaml_files_var_objpow_value.
pure integer function get_file_new_file_freq_units(this)
Inquiry for diag_files_objfile_new_file_freq_units.
subroutine add_standname(this, standard_name)
Adds the standname for the DiagYamlFilesVar_type.
pure logical function has_var_varname(this)
Checks if diag_file_objvar_varname is allocated.
subroutine set_file_time_units(yaml_fileobj, file_timeunit)
This checks if the time unit in a diag file is valid and sets the integer equivalent.
pure logical function has_file_timeunit(this)
Checks if diag_file_objfile_timeunit is allocated.
pure integer function size_diag_files(this)
Find the number of files listed in the diag yaml.
pure logical function has_file_start_time(this)
Checks if diag_file_objfile_start_time is allocated.
pure logical function has_file_sub_region(this)
Checks if diag_file_objfile_sub_region is being used and has the sub region variables allocated.
pure integer function, allocatable get_var_reduction(this)
Inquiry for diag_yaml_files_var_objvar_reduction.
pure integer function get_file_duration_units(this)
Inquiry for diag_files_objfile_duration_units.
type(diagyamlfiles_type) function, dimension(:), allocatable get_diag_files(this)
get the diag_files of a diag_yaml type
pure logical function has_file_global_meta(this)
Checks if diag_file_objfile_global_meta is allocated.
pure logical function has_var_longname(this)
Checks if diag_file_objvar_longname is allocated.
pure character(len=:) function, allocatable get_var_module(this)
Inquiry for diag_yaml_files_var_objvar_module.
pure logical function has_file_frequnit(this)
Checks if diag_file_objfile_frequnit is allocated.
logical function is_global_meta(this)
Inquiry for whether file_global_meta is allocated.
pure logical function is_using_collective_writes(this)
Determines whether or not the file is using netcdf collective writes.
pure real(kind=r4_kind) function, dimension(2) get_var_zbounds(this)
Inquiry for diag_yaml_files_var_objvar_zbounds.
pure integer function, dimension(basedate_size) get_basedate(this)
get the basedate of a diag_yaml type
subroutine, public fms_diag_yaml_out(ntimes, ntiles, ndistributedfiles)
Writes an output yaml with all available information on the written files. Will only write with root ...
integer function set_valid_time_units(time_units, error_msg)
This checks if a time unit is valid and if it is, it assigns the integer equivalent.
pure logical function has_diag_title(this)
Checks if diag_file_objdiag_title is allocated.
subroutine get_sub_region(diag_yaml_id, sub_region_id, sub_region, grid_type, fname)
gets the lat/lon of the sub region to use in a diag_table yaml
pure character(len=:) function, allocatable get_var_fname(this)
Inquiry for diag_yaml_files_var_objvar_fname.
pure logical function has_standname(this)
Checks if diag_file_objstandname is set.
pure integer function get_file_timeunit(this)
Inquiry for diag_files_objfile_timeunit.
subroutine increase_new_file_freq_index(this)
Increate the current_new_file_freq_index by 1.
subroutine diag_yaml_files_obj_init(obj)
Initializes the non string values of a diagYamlFiles_type to its default values.
integer function, dimension(:), allocatable, public get_diag_field_ids(indices)
Gets field indices corresponding to the indices (input argument) in the sorted variable_list.
pure character(len=8 *size(unit_param)) function get_diag_unit_string(unit_param)
private function for getting unit string from diag_data parameter values
subroutine, public diag_yaml_object_init(diag_subset_output)
Uses the yaml_parser_mod to read in the diag_table and fill in the diag_yaml object.
pure logical function has_var_write(this)
diag_file_objvar_write is on the stack, so this returns true
logical function is_var_attributes(this)
Inquiry for whether var_attributes is allocated.
pure character(len=:) function, allocatable get_var_units(this)
Inquiry for diag_yaml_files_var_objvar_units.
subroutine fill_in_diag_fields(diag_file_id, yaml_fileobj, var_id, field, allow_averages, has_module_block, mod_name)
Fills in a diagYamlFilesVar_type with the contents of a variable block in diag_table....
subroutine, public dump_diag_yaml_obj(filename)
Prints out values from diag_yaml object for debugging. Only writes on root.
pure integer function, allocatable get_var_kind(this)
Inquiry for diag_yaml_files_var_objvar_kind.
integer function, public get_num_unique_fields()
Determine the number of unique diag_fields in the diag_yaml_object.
pure character(:) function, dimension(:), allocatable get_file_varlist(this)
Inquiry for diag_files_objfile_varlist.
integer function get_total_num_vars(diag_yaml_id, diag_file_id)
gets the total number of variables in the diag_table yaml file
pure integer function get_file_frequnit(this)
Inquiry for diag_files_objfile_frequnit.
type(diagyamlfilesvar_type) function, pointer get_diag_field_from_id(this, yaml_id)
Get the diag_field yaml corresponding to a yaml_id.
pure character(len=:) function, allocatable get_file_fname(this)
Inquiry for diag_files_objfile_fname.
pure logical function has_var_outname(this)
Checks if diag_file_objvar_outname is allocated.
pure logical function has_file_new_file_freq_units(this)
Checks if diag_file_objfile_new_file_freq_units is allocated.
pure character(len=max_str_len) function, dimension(:,:), allocatable get_file_global_meta(this)
Inquiry for diag_files_objfile_global_meta.
pure character(len=:) function, allocatable get_var_varname(this)
Inquiry for diag_yaml_files_var_objvar_varname.
pure integer function get_file_new_file_freq(this)
Inquiry for diag_files_objfile_new_file_freq.
subroutine set_field_reduction(field, reduction_method)
This checks if the reduction of a diag field is valid and sets it If the reduction method is diurnalX...
pure logical function has_diag_fields(this)
Checks if diag_file_objdiag_fields is allocated.
pure integer function get_n_diurnal(this)
Inquiry for diag_yaml_files_var_objn_diurnal.
pure logical function has_file_freq(this)
diag_file_objfile_freq is on the stack, so the object always has it
subroutine set_field_kind(field, skind)
This checks if the kind of a diag field is valid and sets it.
pure type(time_type) function get_file_start_time(this)
Inquiry for diag_files_objfile_start_time.
pure logical function has_file_new_file_freq(this)
diag_file_objfile_new_file_freq is defined on the stack, so this will return true
pure type(diagyamlfilesvar_type) function, dimension(:), allocatable get_diag_fields(this)
get the diag_fields of a diag_yaml type
pure logical function has_var_module(this)
Checks if diag_file_objvar_module is allocated.
pure character(len=:) function, allocatable get_file_unlimdim(this)
Inquiry for diag_files_objfile_unlimdim.
pure logical function has_file_varlist(this)
Checks if diag_file_objfile_varlist is allocated.
pure character(len=:) function, allocatable get_var_outname(this)
Inquiry for diag_yaml_files_var_objvar_outname.
pure character(len=:) function, allocatable get_var_longname(this)
Inquiry for diag_yaml_files_var_objvar_longname.
pure character(len=8 *max_freq) function get_diag_reduction_string(reduction_val)
private function for getting reduction type string from parameter values
pure logical function has_diag_files(this)
Checks if diag_file_objdiag_files is allocated.
pure character(len=max_str_len) function, dimension(:,:), allocatable get_var_attributes(this)
Inquiry for diag_yaml_files_var_objvar_attributes.
pure logical function has_var_kind(this)
Checks if diag_file_objvar_kind is allocated.
pure integer function get_file_duration(this)
Inquiry for diag_files_objfile_duration.
subroutine fill_in_diag_files(diag_yaml_id, diag_file_id, yaml_fileobj)
Fills in a diagYamlFiles_type with the contents of a file block in diag_table.yaml.
integer function, dimension(:), allocatable, public find_diag_field(diag_field_name, module_name)
Determines if a diag_field is in the diag_yaml_object.
pure integer function, dimension(max_dimensions) get_chunksizes(this)
Inquiry for chunksizes.
pure logical function has_var_zbounds(this)
Checks if diag_file_objvar_zbounds is allocated.
pure character(len=:) function, allocatable get_title(this)
get the title of a diag_yaml type
type(subregion_type) function, pointer get_file_sub_region(this)
Inquiry for diag_files_objfile_subregion.
pure integer function get_file_freq(this)
Inquiry for diag_files_objfile_freq.
integer function, dimension(:), allocatable, public get_diag_files_id(indices)
Finds the indices of the diag_yamldiag_files(:) corresponding to fields in variable_list(indices)
subroutine parse_key(filename, buffer, file_freq, file_frequnit, var)
This parses the freq, new_file_freq, or file_duration keys which are read in as a comma list.
pure logical function has_file_write(this)
Checks if diag_file_objfile_write is on the stack, so this will always be true.
pure logical function has_pow_value(this)
Checks if diag_file_objpow_value is set.
pure logical function has_var_units(this)
Checks if diag_file_objvar_units is allocated.
pure logical function has_var_fname(this)
Checks if diag_file_objvar_fname is allocated.
pure logical function has_file_unlimdim(this)
Checks if diag_file_objfile_unlimdim is allocated.
subroutine diag_get_value_from_key(diag_file_id, par_id, key_name, value_name, is_optional)
diag_manager wrapper to get_value_from_key to use for allocatable string variables
pure logical function has_file_fname(this)
Checks if diag_file_objfile_fname is allocated.
pure logical function has_file_duration(this)
diag_file_objfile_duration is allocated on th stack, so this is always true
Object that holds the information of the diag_yaml.
character(:) function, allocatable, public string(v, fmt)
Converts a number or a Boolean value to a string.
type(c_ptr) function, dimension(:), allocatable, public fms_array_to_pointer(my_array)
Converts a character array to an array of c pointers!
integer function, dimension(:), allocatable, public fms_find_my_string(my_pointer, narray, string_to_find)
Searches through a SORTED array of pointers for a string.
subroutine, public fms_f2c_string(dest, str_in)
Copies a Fortran string into a C string and puts c_null_char in any trailing spaces.
subroutine, public initialize_val_struct(yv)
subroutine, public initialize_key_struct(yk)
Keys for the output yaml on a given level corresponding to the struct in yaml_output_functions....
Values for the output yaml on a given level corresponding to the struct in yaml_output_functions....
integer function stdout()
This function returns the current standard fortran unit numbers for output.
integer function mpp_pe()
Returns processor ID.
character(len=15) function, public date_to_string(time, err_msg)
Get the a character string that represents the time. The format will be yyyymmdd.hhmmss.
Type to represent amounts of time. Implemented as seconds and days to allow for larger intervals.
integer function, public get_nkeys(file_id, block_id)
Gets the number of key-value pairs in a block.
subroutine, public get_key_name(file_id, key_id, key_name)
Gets the key from a file id.
integer function, public open_and_parse_file(filename)
Opens and parses a yaml file.
subroutine, public get_key_ids(file_id, block_id, key_ids)
Gets the ids of the key-value pairs in a block.
subroutine, public get_block_ids(file_id, block_name, block_ids, parent_block_id)
Gets the ids of the blocks with block_name in the yaml file If parent_block_id is present,...
integer function, public get_num_blocks(file_id, block_name, parent_block_id)
Determines the number of blocks with block_name in the yaml file If parent_block_id is present,...
subroutine, public get_key_value(file_id, key_id, key_value)
Gets the value from a file id.
Dermine the value of a key from a keyname.
c function that finds the number of unique strings in an array of c pointers
Sorts an array of pointers (my pointer) of size (p_size) in alphabetical order.
type to hold the diag_file information
type to hold the info a diag_field
type to hold an array of sorted diag_files
type to hold the sub region information about a file
type to hold an array of sorted diag_fiels