From 70749c99046151c3554ff8715dce2ed2895d72e9 Mon Sep 17 00:00:00 2001 From: John Sharples Date: Wed, 27 Nov 2024 15:05:15 +1100 Subject: [PATCH 1/2] 401: initial commit --- metcalcpy/util/mode_3d_volrat_statistics.py | 58 +++++++++++---------- metcalcpy/util/utils.py | 2 +- test/test_mode_3d_volrat_statistics.py | 54 +++++++++++++++++++ 3 files changed, 85 insertions(+), 29 deletions(-) create mode 100644 test/test_mode_3d_volrat_statistics.py diff --git a/metcalcpy/util/mode_3d_volrat_statistics.py b/metcalcpy/util/mode_3d_volrat_statistics.py index 0ca9fb79..956cb13c 100644 --- a/metcalcpy/util/mode_3d_volrat_statistics.py +++ b/metcalcpy/util/mode_3d_volrat_statistics.py @@ -11,6 +11,8 @@ """ Program Name: mode_3d_volrat_statistics.py """ +import numpy as np + from metcalcpy.util.mode_arearat_statistics import * from metcalcpy.util.utils import column_data_by_name_value, THREE_D_DATA_FILTER from metcalcpy.util.safe_log import safe_log @@ -214,7 +216,7 @@ def calculate_3d_volrat_osm_osa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSM/OSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -244,7 +246,7 @@ def calculate_3d_volrat_osu_osa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSU/OSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -273,7 +275,7 @@ def calculate_3d_volrat_fsm_asm(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FSM/ASM calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -303,7 +305,7 @@ def calculate_3d_volrat_osm_asm(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSM/ASM calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -333,7 +335,7 @@ def calculate_3d_volrat_osu_asu(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSU/ASU calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -363,7 +365,7 @@ def calculate_3d_volrat_fsa_aaa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FSA/AAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -393,7 +395,7 @@ def calculate_3d_volrat_osa_aaa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSA/AAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -424,7 +426,7 @@ def calculate_3d_volrat_fsa_faa(input_data, columns_names, logger=None): try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FSA/FAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -454,7 +456,7 @@ def calculate_3d_volrat_fca_faa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FCA/FAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -484,7 +486,7 @@ def calculate_3d_volrat_osa_oaa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSA/OAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -514,7 +516,7 @@ def calculate_3d_volrat_oca_oaa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OCA/OAA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -544,7 +546,7 @@ def calculate_3d_volrat_fca_aca(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FCA/ACA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -574,7 +576,7 @@ def calculate_3d_volrat_oca_aca(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OCA/ACA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -605,7 +607,7 @@ def calculate_3d_volrat_fsa_osa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FSA/OSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -636,7 +638,7 @@ def calculate_3d_volrat_osa_fsa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSA/FSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -666,7 +668,7 @@ def calculate_3d_volrat_aca_asa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio ACA/ASA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -696,7 +698,7 @@ def calculate_3d_volrat_asa_aca(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio ASA/ACA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -727,7 +729,7 @@ def calculate_3d_volrat_fca_fsa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FCA/FSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -758,7 +760,7 @@ def calculate_3d_volrat_fsa_fca(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio FSA/FCA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -789,7 +791,7 @@ def calculate_3d_volrat_oca_osa(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OCA/OSA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -820,7 +822,7 @@ def calculate_3d_volrat_osa_oca(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Ratio OSA/OCA calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -850,7 +852,7 @@ def calculate_3d_objvhits(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Hits calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -880,7 +882,7 @@ def calculate_3d_objvmisses(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Renaming columns for 3D Volume Misses calculation.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", "Filtering data based on THREE_D_DATA_FILTER.") filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) @@ -909,7 +911,7 @@ def calculate_3d_objvfas(input_data, columns_names, logger=None): or None if some of the data values are missing or invalid """ try: - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) filtered_data = column_data_by_name_value(input_data, columns_names_new, THREE_D_DATA_FILTER) result = calculate_objafas(filtered_data, columns_names_new) except Exception as e: @@ -933,7 +935,7 @@ def calculate_3d_objvcsi(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Starting the renaming of columns.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", f"Renamed columns: {columns_names_new}") safe_log(logger, "debug", "Filtering data based on the new column names.") @@ -964,7 +966,7 @@ def calculate_3d_objvpody(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Starting the renaming of columns.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", f"Renamed columns: {columns_names_new}") safe_log(logger, "debug", "Filtering data based on the new column names.") @@ -995,7 +997,7 @@ def calculate_3d_objvfar(input_data, columns_names, logger=None): """ try: safe_log(logger, "debug", "Starting the renaming of columns.") - columns_names_new = rename_column(column_names, logger=logger) + columns_names_new = rename_column(columns_names, logger=logger) safe_log(logger, "debug", f"Renamed columns: {columns_names_new}") safe_log(logger, "debug", "Filtering data based on the new column names.") @@ -1027,4 +1029,4 @@ def rename_column(columns_names, logger=None): columns_names_new.insert(index, 'area') else: columns_names_new.insert(index, name) - return columns_names_new + return np.array(columns_names_new) diff --git a/metcalcpy/util/utils.py b/metcalcpy/util/utils.py index 9a0ff8ff..38f7c2f5 100644 --- a/metcalcpy/util/utils.py +++ b/metcalcpy/util/utils.py @@ -347,7 +347,7 @@ def column_data_by_name_value(input_data, columns, filters): try: # for each filter for key, value in filters.items(): - # get an index og the column + # get an index of the column index_array = np.where(columns == key)[0] if index_array.size == 0: return 0 diff --git a/test/test_mode_3d_volrat_statistics.py b/test/test_mode_3d_volrat_statistics.py new file mode 100644 index 00000000..0c5856ca --- /dev/null +++ b/test/test_mode_3d_volrat_statistics.py @@ -0,0 +1,54 @@ +import pytest +import numpy as np +import pandas as pd + +import metcalcpy.util.mode_3d_volrat_statistics as m3vs + +column_names = np.array(["object_type", "volume", "fcst_flag", "simple_flag", "matched_flag"]) + +data_values = np.array([ + ['3d', 100, 1, 1, 1], + ['3d', 30, 0, 1, 1], + ]) + +funcs = ["volrat_fsa_asa", +"volrat_osa_asa", +"volrat_asm_asa", +"volrat_asu_asa", +"volrat_fsm_fsa", +"volrat_fsu_fsa", +"volrat_osm_osa", +"volrat_osu_osa", +"volrat_fsm_asm", +"volrat_osm_asm", +"volrat_osu_asu", +"volrat_fsa_aaa", +"volrat_osa_aaa", +"volrat_fsa_faa", +"volrat_fca_faa", +"volrat_osa_oaa", +"volrat_oca_oaa", +"volrat_fca_aca", +"volrat_oca_aca", +"volrat_fsa_osa", +"volrat_osa_fsa", +"volrat_aca_asa", +"volrat_asa_aca", +"volrat_fca_fsa", +"volrat_fsa_fca", +"volrat_oca_osa", +"volrat_osa_oca", +"objvhits", +"objvmisses", +"objvfas", +"objvcsi", +"objvpody", +"objvfar"] + + +def test_calculate_3d_volrat_fsa_asa(): + for f in funcs: + func_str = f"calculate_3d_{f}" + func = getattr(m3vs, func_str) + actual = func(data_values, column_names) + print(f'"{f}", {actual}') \ No newline at end of file From 8a45c6e08a3bafc8bad77083bfbbb52be9f5e5cc Mon Sep 17 00:00:00 2001 From: John Sharples Date: Thu, 5 Dec 2024 16:31:40 +1100 Subject: [PATCH 2/2] 401: improve 3d volrat test --- test/test_mode_3d_volrat_statistics.py | 157 +++++++++++++++++-------- 1 file changed, 108 insertions(+), 49 deletions(-) diff --git a/test/test_mode_3d_volrat_statistics.py b/test/test_mode_3d_volrat_statistics.py index 0c5856ca..a8a7ae03 100644 --- a/test/test_mode_3d_volrat_statistics.py +++ b/test/test_mode_3d_volrat_statistics.py @@ -1,54 +1,113 @@ import pytest +from unittest.mock import patch import numpy as np -import pandas as pd - import metcalcpy.util.mode_3d_volrat_statistics as m3vs -column_names = np.array(["object_type", "volume", "fcst_flag", "simple_flag", "matched_flag"]) - -data_values = np.array([ - ['3d', 100, 1, 1, 1], - ['3d', 30, 0, 1, 1], - ]) - -funcs = ["volrat_fsa_asa", -"volrat_osa_asa", -"volrat_asm_asa", -"volrat_asu_asa", -"volrat_fsm_fsa", -"volrat_fsu_fsa", -"volrat_osm_osa", -"volrat_osu_osa", -"volrat_fsm_asm", -"volrat_osm_asm", -"volrat_osu_asu", -"volrat_fsa_aaa", -"volrat_osa_aaa", -"volrat_fsa_faa", -"volrat_fca_faa", -"volrat_osa_oaa", -"volrat_oca_oaa", -"volrat_fca_aca", -"volrat_oca_aca", -"volrat_fsa_osa", -"volrat_osa_fsa", -"volrat_aca_asa", -"volrat_asa_aca", -"volrat_fca_fsa", -"volrat_fsa_fca", -"volrat_oca_osa", -"volrat_osa_oca", -"objvhits", -"objvmisses", -"objvfas", -"objvcsi", -"objvpody", -"objvfar"] - - -def test_calculate_3d_volrat_fsa_asa(): - for f in funcs: - func_str = f"calculate_3d_{f}" - func = getattr(m3vs, func_str) +column_names = np.array( + ["object_type", "volume", "fcst_flag", "simple_flag", "matched_flag"] +) + + +data_simple = np.array( + [ + ["3d", 100, 1, 1, 1], + ["3d", 30, 0, 1, 1], + ] +) + + +data_complex = np.array( + [ + ["3d", 100, 1, 1, 1], + ["3d", 30, 0, 1, 1], + ["3d", 120, 1, 1, 0], + ["3d", 12, 0, 1, 1], + ["3d", 1, 1, 0, 1], + ["3d", 17, 0, 1, 1], + ["2d", 200, 1, 1, 1], + ["3d", 66, 0, 1, 0], + ] +) + + +@pytest.mark.parametrize( + "func_name,data_values,expected", + [ + ("volrat_fsa_asa", data_simple, 0.7692308), + ("volrat_osa_asa", data_simple, 0.2307692), + ("volrat_asm_asa", data_simple, 1.0), + ("volrat_asu_asa", data_simple, None), + ("volrat_fsm_fsa", data_simple, 1.0), + ("volrat_fsu_fsa", data_simple, None), + ("volrat_osm_osa", data_simple, 1.0), + ("volrat_osu_osa", data_simple, None), + ("volrat_fsm_asm", data_simple, None), + ("volrat_osm_asm", data_simple, 0.2307692), + ("volrat_osu_asu", data_simple, None), + ("volrat_fsa_aaa", data_simple, 0.7692308), + ("volrat_osa_aaa", data_simple, 0.2307692), + ("volrat_fsa_faa", data_simple, 1.0), + ("volrat_fca_faa", data_simple, None), + ("volrat_osa_oaa", data_simple, 1.0), + ("volrat_oca_oaa", data_simple, None), + ("volrat_fca_aca", data_simple, None), + ("volrat_oca_aca", data_simple, None), + ("volrat_fsa_osa", data_simple, 3.3333333), + ("volrat_osa_fsa", data_simple, 1.0), + ("volrat_aca_asa", data_simple, None), + ("volrat_asa_aca", data_simple, None), + ("volrat_fca_fsa", data_simple, None), + ("volrat_fsa_fca", data_simple, None), + ("volrat_oca_osa", data_simple, None), + ("volrat_osa_oca", data_simple, None), + ("objvhits", data_simple, 65.0), + ("objvmisses", data_simple, None), + ("objvfas", data_simple, None), + ("objvcsi", data_simple, None), + ("objvpody", data_simple, None), + ("objvfar", data_simple, None), + ("volrat_fsa_asa", data_complex, 0.6376812), + ("volrat_osa_asa", data_complex, 0.3623188), + ("volrat_asm_asa", data_complex, 0.4608696), + ("volrat_asu_asa", data_complex, 0.5391304), + ("volrat_fsm_fsa", data_complex, 0.4545455), + ("volrat_fsu_fsa", data_complex, 0.5454545), + ("volrat_osm_osa", data_complex, 0.472), + ("volrat_osu_osa", data_complex, 0.528), + ("volrat_fsm_asm", data_complex, 0.5454545), + ("volrat_osm_asm", data_complex, 0.3710692), + ("volrat_osu_asu", data_complex, 0.3548387), + ("volrat_fsa_aaa", data_complex, 0.6358382), + ("volrat_osa_aaa", data_complex, 0.3612717), + ("volrat_fsa_faa", data_complex, 0.9954751), + ("volrat_fca_faa", data_complex, 0.0045249), + ("volrat_osa_oaa", data_complex, 1.0), + ("volrat_oca_oaa", data_complex, None), + ("volrat_fca_aca", data_complex, 1.0), + ("volrat_oca_aca", data_complex, None), + ("volrat_fsa_osa", data_complex, 1.76), + ("volrat_osa_fsa", data_complex, 1.0), + ("volrat_aca_asa", data_complex, 0.0028986), + ("volrat_asa_aca", data_complex, 345.0), + ("volrat_fca_fsa", data_complex, 0.0045455), + ("volrat_fsa_fca", data_complex, 220.0), + ("volrat_oca_osa", data_complex, None), + ("volrat_osa_oca", data_complex, None), + ("objvhits", data_complex, 79.5), + ("objvmisses", data_complex, 66.0), + ("objvfas", data_complex, 120.0), + ("objvcsi", data_complex, 0.299435), + ("objvpody", data_complex, 0.5463918), + ("objvfar", data_complex, 0.2739726), + ], +) +def test_calculate_3d_volrat(func_name, data_values, expected): + func_str = f"calculate_3d_{func_name}" + func = getattr(m3vs, func_str) + actual = func(data_values, column_names) + assert actual == expected + + # Check None is returned on Exception + with patch.object(m3vs, "rename_column", side_effect=TypeError): actual = func(data_values, column_names) - print(f'"{f}", {actual}') \ No newline at end of file + assert actual == None