diff --git a/diag_manager/fms_diag_object.F90 b/diag_manager/fms_diag_object.F90 index 7c8f279a9..12c33e082 100644 --- a/diag_manager/fms_diag_object.F90 +++ b/diag_manager/fms_diag_object.F90 @@ -888,7 +888,7 @@ function fms_diag_do_reduction(this, field_data, diag_field_id, oor_mask, weight !! in blocks type(time_type), intent(in), optional :: time !< Current time - character(len=50) :: error_msg !< Error message to check + character(len=150) :: error_msg !< Error message to check !TODO Mostly everything #ifdef use_yaml type(fmsDiagField_type), pointer :: field_ptr !< Pointer to the field's object @@ -1032,26 +1032,27 @@ function fms_diag_do_reduction(this, field_data, diag_field_id, oor_mask, weight endif case (time_sum) error_msg = buffer_ptr%do_time_sum_wrapper(field_data, oor_mask, field_ptr%get_var_is_masked(), & - field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value) + field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, field_ptr%has_missing_value()) if (trim(error_msg) .ne. "") then return endif case (time_average) error_msg = buffer_ptr%do_time_sum_wrapper(field_data, oor_mask, field_ptr%get_var_is_masked(), & - field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value) + field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, field_ptr%has_missing_value()) if (trim(error_msg) .ne. "") then return endif case (time_power) error_msg = buffer_ptr%do_time_sum_wrapper(field_data, oor_mask, field_ptr%get_var_is_masked(), & - field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, & + field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, field_ptr%has_missing_value(), & pow_value=field_yaml_ptr%get_pow_value()) if (trim(error_msg) .ne. "") then return endif case (time_rms) error_msg = buffer_ptr%do_time_sum_wrapper(field_data, oor_mask, field_ptr%get_var_is_masked(), & - field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, pow_value = 2) + field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, field_ptr%has_missing_value(), & + pow_value = 2) if (trim(error_msg) .ne. "") then return endif @@ -1061,7 +1062,7 @@ function fms_diag_do_reduction(this, field_data, diag_field_id, oor_mask, weight ! sets the diurnal index for reduction within the buffer object call buffer_ptr%set_diurnal_section_index(time) error_msg = buffer_ptr%do_time_sum_wrapper(field_data, oor_mask, field_ptr%get_var_is_masked(), & - field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value) + field_ptr%get_mask_variant(), bounds_in, bounds_out, missing_value, field_ptr%has_missing_value()) if (trim(error_msg) .ne. "") then return endif diff --git a/diag_manager/fms_diag_output_buffer.F90 b/diag_manager/fms_diag_output_buffer.F90 index 1837dae81..7c8b5a4ae 100644 --- a/diag_manager/fms_diag_output_buffer.F90 +++ b/diag_manager/fms_diag_output_buffer.F90 @@ -650,7 +650,7 @@ end function do_time_max_wrapper !> @brief Does the time_sum reduction method on the buffer object !! @return Error message if the math was not successful function do_time_sum_wrapper(this, field_data, mask, is_masked, mask_variant, bounds_in, bounds_out, missing_value, & - pow_value) & + has_missing_value, pow_value) & result(err_msg) class(fmsDiagOutputBuffer_type), intent(inout) :: this !< buffer object to write class(*), intent(in) :: field_data(:,:,:,:) !< Buffer data for current time @@ -660,10 +660,12 @@ function do_time_sum_wrapper(this, field_data, mask, is_masked, mask_variant, bo logical, intent(in) :: is_masked !< .True. if the field has a mask logical, intent(in) :: mask_variant !< .True. if the mask changes over time real(kind=r8_kind), intent(in) :: missing_value !< Missing_value for data points that are masked + logical, intent(in) :: has_missing_value !< .True. if the field was registered with + !! a missing value integer, optional, intent(in) :: pow_value !< power value, will calculate field_data^pow !! before adding to buffer should only be !! present if using pow reduction method - character(len=50) :: err_msg + character(len=150) :: err_msg !TODO This will be expanded for integers err_msg = "" @@ -671,6 +673,10 @@ function do_time_sum_wrapper(this, field_data, mask, is_masked, mask_variant, bo type is (real(kind=r8_kind)) select type (field_data) type is (real(kind=r8_kind)) + if (.not. is_masked) then + if (any(field_data .eq. missing_value)) & + err_msg = "You cannot pass data with missing values without masking them!" + endif call do_time_sum_update(output_buffer, this%weight_sum, field_data, mask, is_masked, mask_variant, & bounds_in, bounds_out, missing_value, this%diurnal_section, & pow=pow_value) @@ -680,6 +686,10 @@ function do_time_sum_wrapper(this, field_data, mask, is_masked, mask_variant, bo type is (real(kind=r4_kind)) select type (field_data) type is (real(kind=r4_kind)) + if (.not. is_masked) then + if (any(field_data .eq. missing_value)) & + err_msg = "You cannot pass data with missing values without masking them!" + endif call do_time_sum_update(output_buffer, this%weight_sum, field_data, mask, is_masked, mask_variant, & bounds_in, bounds_out, real(missing_value, kind=r4_kind), & this%diurnal_section, pow=pow_value) diff --git a/test_fms/diag_manager/test_reduction_methods.F90 b/test_fms/diag_manager/test_reduction_methods.F90 index 8327121ae..0b09fc69c 100644 --- a/test_fms/diag_manager/test_reduction_methods.F90 +++ b/test_fms/diag_manager/test_reduction_methods.F90 @@ -64,6 +64,8 @@ program test_reduction_methods integer :: id_var0 !< diag_field id for 0d var integer :: id_var1 !< diag_field id for 1d var integer :: id_var2 !< diag_field id for 2d var + integer :: id_var2missing !< diag_field id for a var that is not masked but has missing + !! values passed into send_data integer :: id_var2c !< diag_field id for 2d var_corner integer :: id_var3 !< diag_field id for 3d var integer :: id_var4 !< diag_field id for 4d var @@ -177,6 +179,8 @@ program test_reduction_methods 'mullions', missing_value = missing_value) id_var2 = register_diag_field ('ocn_mod', 'var2', (/id_x, id_y/), Time, 'Var2d', & 'mullions', missing_value = missing_value) + id_var2missing = register_diag_field ('ocn_mod', 'var2missing', (/id_x, id_y/), Time, 'Var2d', & + 'mullions', missing_value = missing_value) id_var2c = register_diag_field ('ocn_mod', 'var2c', (/id_xc, id_yc/), Time, 'Var2d corner', & 'mullions', missing_value = missing_value) id_var3 = register_diag_field ('ocn_mod', 'var3', (/id_x, id_y, id_z/), Time, 'Var3d', & @@ -198,6 +202,10 @@ program test_reduction_methods call set_buffer(cdata, i) call set_buffer(cdata_corner, i) + ! This is passing in the data with missing values, but the variable is not masked. + ! An error is expected in this case. + used = send_data(id_var2missing, cdata(:,:,1,1)*0_r8_kind + missing_value, Time) + used = send_data(id_var2c, cdata_corner(:,:,1,1), Time) used = send_data(id_var0, cdata(1,1,1,1), Time) diff --git a/test_fms/diag_manager/test_time_avg.sh b/test_fms/diag_manager/test_time_avg.sh index 3e80fcdc2..d40abf637 100755 --- a/test_fms/diag_manager/test_time_avg.sh +++ b/test_fms/diag_manager/test_time_avg.sh @@ -191,5 +191,25 @@ test_expect_success "Running diag_manager with "avg" reduction method with halo test_expect_success "Checking answers for the "avg" reduction method with halo output with real mask (test $my_test_count)" ' mpirun -n 1 ../check_time_avg ' + +cat <<_EOF > diag_table.yaml +title: test_avg +base_date: 2 1 1 0 0 0 +diag_files: +- file_name: test_failure + time_units: hours + unlimdim: time + freq: 6 hours + varlist: + - module: ocn_mod + var_name: var2missing + reduction: average + kind: r4 +_EOF + + my_test_count=`expr $my_test_count + 1` + test_expect_failure "Fail if passing in missing_values without masking them (test $my_test_count)" ' + mpirun -n 6 ../test_reduction_methods + ' fi test_done