예제 #1
0
    def test_all_sets_and_all_seasons(self):
        ts_param = AreaMeanTimeSeriesParameter()
        ts_param.start_yr = "2000"
        ts_param.end_yr = "2004"

        enso_param = EnsoDiagsParameter()
        enso_param.start_yr = "2000"
        enso_param.end_yr = "2004"

        streamflow_param = StreamflowParameter()
        streamflow_param.test_data_path = "unit_test_data/3yr_nc"
        streamflow_param.reference_data_path = "unit_test_data"

        self.runner.sets_to_run = [
            "lat_lon",
            "area_mean_time_series",
            "enso_diags",
            "streamflow",
        ]

        parameters = self.runner.get_final_parameters(
            [self.core_param, ts_param, enso_param, streamflow_param])
        # Counts the number of each set and each seasons to run the diags on.
        set_counter, season_counter = (
            collections.Counter(),  # type: ignore
            collections.Counter(),  # type: ignore
        )
        for param in parameters:
            for set_name in param.sets:
                set_counter[set_name] += 1
            for season in param.seasons:
                season_counter[season] += 1

        for set_name in set_counter:
            count = set_counter[set_name]
            if count <= 0:
                msg = "Count for {} is invalid: {}"
                self.fail(msg.format(set_name, count))

        all_season_counts = list(season_counter.values())
        # enso_diags and streamflow only run ANN, no seasons
        # So, reduce the ANN count by the number of times these appear
        all_season_counts[0] -= set_counter["enso_diags"]
        all_season_counts[0] -= set_counter["streamflow"]
        if not all(all_season_counts[0] == count
                   for count in all_season_counts):
            self.fail("Counts for the seasons don't match: {}".format(
                all_season_counts))
예제 #2
0
    def test_all_sets_and_all_seasons(self):
        ts_param = AreaMeanTimeSeriesParameter()
        ts_param.start_yr = '2000'
        ts_param.end_yr = '2004'

        enso_param = EnsoDiagsParameter()
        enso_param.start_yr = '2000'
        enso_param.end_yr = '2004'

        streamflow_param = StreamflowParameter()
        streamflow_param.test_data_path = 'unit_test_data/3yr_nc'
        streamflow_param.reference_data_path = 'unit_test_data'

        parameters = self.runner.get_final_parameters(
            [self.core_param, ts_param, enso_param, streamflow_param])
        # Counts the number of each set and each seasons to run the diags on.
        set_counter, season_counter = collections.Counter(
        ), collections.Counter()
        for param in parameters:
            for set_name in param.sets:
                set_counter[set_name] += 1
            for season in param.seasons:
                season_counter[season] += 1

        for set_name in set_counter:
            count = set_counter[set_name]
            if count <= 0:
                msg = 'Count for {} is invalid: {}'
                self.fail(msg.format(set_name, count))

        all_season_counts = list(season_counter.values())
        # enso_diags and streamflow only run ANN, no seasons
        # So, reduce the ANN count by the number of times these appear
        all_season_counts[0] -= set_counter['enso_diags']
        all_season_counts[0] -= set_counter['streamflow']
        if not all(all_season_counts[0] == count
                   for count in all_season_counts):
            self.fail('Counts for the seasons don\'t match: {}'.format(
                all_season_counts))
예제 #3
0
# Running the software with the API:
#    python all_sets.py -d all_sets.py
import numpy
from acme_diags.parameter.area_mean_time_series_parameter import AreaMeanTimeSeriesParameter
from acme_diags.parameter.core_parameter import CoreParameter
from acme_diags.parameter.enso_diags_parameter import EnsoDiagsParameter
from acme_diags.parameter.meridional_mean_2d_parameter import MeridionalMean2dParameter
from acme_diags.parameter.zonal_mean_2d_parameter import ZonalMean2dParameter
from acme_diags.run import Run

run_object = Run()
param = CoreParameter()
ts_param = AreaMeanTimeSeriesParameter()

m2d_param = MeridionalMean2dParameter()
m2d_param.plevs = [
    200.,
    500.,
]
z2d_param = ZonalMean2dParameter()
z2d_param.plevs = [
    200.,
    300.,
]

enso_param = EnsoDiagsParameter()
enso_param.test_name = 'e3sm_v1'

run_object.run_diags([param, ts_param, m2d_param, z2d_param, enso_param])
예제 #4
0
    def test_complete_run(self):
        # Anvil
        # Run `source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified.sh`
        test_data_prefix = '/lcrc/group/e3sm/public_html/e3sm_diags_test_data'
        ref_data_prefix = '/lcrc/group/e3sm/public_html/diagnostics/observations/Atm'
        html_prefix = '.'

        param = CoreParameter()

        param.reference_data_path = os.path.join(ref_data_prefix,
                                                 'climatology')
        param.test_data_path = os.path.join(test_data_prefix, 'climatology/')
        param.test_name = '20161118.beta0.FC5COSP.ne30_ne30.edison'
        param.seasons = [
            "ANN", "JJA"
        ]  # Default setting: seasons = ["ANN", "DJF", "MAM", "JJA", "SON"]

        param.results_dir = os.path.join(html_prefix, 'tutorial_2020_all_sets')
        param.multiprocessing = True
        param.num_workers = 30

        # Additional parameters:
        #param.short_test_name = 'beta0.FC5COSP.ne30'
        #param.run_type = 'model_vs_model'
        #param.diff_title = 'Difference'
        #param.output_format = ['png']
        #param.output_format_subplot = ['pdf']
        #param.save_netcdf = True

        # Set specific parameters for new sets
        enso_param = EnsoDiagsParameter()
        enso_param.reference_data_path = os.path.join(ref_data_prefix,
                                                      'time-series/')
        enso_param.test_data_path = os.path.join(test_data_prefix,
                                                 'time-series/E3SM_v1/')
        enso_param.test_name = 'e3sm_v1'
        enso_param.start_yr = '1990'
        enso_param.end_yr = '1999'

        qbo_param = QboParameter()
        qbo_param.reference_data_path = os.path.join(ref_data_prefix,
                                                     'time-series/')
        qbo_param.test_data_path = os.path.join(test_data_prefix,
                                                'time-series/E3SM_v1/')
        qbo_param.test_name = 'e3sm_v1'
        qbo_param.start_yr = '1990'
        qbo_param.end_yr = '1999'

        ts_param = AreaMeanTimeSeriesParameter()
        ts_param.reference_data_path = os.path.join(ref_data_prefix,
                                                    'time-series/')
        ts_param.test_data_path = os.path.join(test_data_prefix,
                                               'time-series/E3SM_v1/')
        ts_param.test_name = 'e3sm_v1'
        ts_param.start_yr = '1990'
        ts_param.end_yr = '1999'

        runner.sets_to_run = [
            'lat_lon', 'zonal_mean_xy', 'zonal_mean_2d', 'polar',
            'cosp_histogram', 'meridional_mean_2d', 'enso_diags', 'qbo',
            'area_mean_time_series'
        ]
        runner.run_diags([param, enso_param, qbo_param, ts_param])

        actual_images_dir = param.results_dir
        # The expected_images_file lists all 475 images we expect to compare.
        # It was generated with the following steps:
        # cd /lcrc/group/e3sm/public_html/e3sm_diags_test_data/unit_test_complete_run/tutorial_2020_all_sets
        # find . -type f -name '*.png' > ../expected_images_complete_run.txt
        expected_images_file = '/lcrc/group/e3sm/public_html/e3sm_diags_test_data/unit_test_complete_run/expected_images_complete_run.txt'
        expected_images_dir = '/lcrc/group/e3sm/public_html/e3sm_diags_test_data/unit_test_complete_run/tutorial_2020_all_sets'

        mismatched_images = []

        with open(expected_images_file) as f:
            for line in f:
                image = line.strip('./').strip('\n')
                path_to_actual_png = os.path.join(actual_images_dir, image)
                path_to_expected_png = os.path.join(expected_images_dir, image)

                actual_png = Image.open(path_to_actual_png).convert('RGB')
                expected_png = Image.open(path_to_expected_png).convert('RGB')
                diff = ImageChops.difference(actual_png, expected_png)

                bbox = diff.getbbox()
                if not bbox:
                    # If `diff.getbbox()` is None, then the images are in theory equal
                    self.assertIsNone(diff.getbbox())
                else:
                    # Sometimes, a few pixels will differ, but the two images appear identical.
                    # https://codereview.stackexchange.com/questions/55902/fastest-way-to-count-non-zero-pixels-using-python-and-pillow
                    nonzero_pixels = diff.crop(bbox).point(
                        lambda x: 255
                        if x else 0).convert("L").point(bool).getdata()
                    num_nonzero_pixels = sum(nonzero_pixels)
                    print('\npath_to_actual_png={}'.format(path_to_actual_png))
                    print(
                        'path_to_expected_png={}'.format(path_to_expected_png))
                    print('diff has {} nonzero pixels.'.format(
                        num_nonzero_pixels))
                    width, height = expected_png.size
                    num_pixels = width * height
                    print('total number of pixels={}'.format(num_pixels))
                    fraction = num_nonzero_pixels / num_pixels
                    print('num_nonzero_pixels/num_pixels fraction={}'.format(
                        fraction))
                    # Fraction of mismatched pixels should be less than 0.02%
                    if fraction >= 0.0002:
                        mismatched_images.append(image)

        self.assertEqual(mismatched_images, [])
]  # Default setting: seasons = ["ANN", "DJF", "MAM", "JJA", "SON"]

param.results_dir = os.path.join(html_prefix, 'tutorial_2020_all_sets')
param.multiprocessing = True
param.num_workers = 30

# Additional parameters:
#param.short_test_name = 'beta0.FC5COSP.ne30'
#param.run_type = 'model_vs_model'
#param.diff_title = 'Difference'
#param.output_format = ['png']
#param.output_format_subplot = ['pdf']
#param.save_netcdf = True

# Set specific parameters for new sets
enso_param = EnsoDiagsParameter()
enso_param.reference_data_path = os.path.join(
    data_prefix, 'obs_for_e3sm_diags/time-series/')
enso_param.test_data_path = os.path.join(
    data_prefix, 'test_model_data_for_acme_diags/time-series/E3SM_v1/')
enso_param.test_name = 'e3sm_v1'
enso_param.start_yr = '1990'
enso_param.end_yr = '1999'

qbo_param = QboParameter()
qbo_param.reference_data_path = os.path.join(
    data_prefix, 'obs_for_e3sm_diags/time-series/')
qbo_param.test_data_path = os.path.join(
    data_prefix, 'test_model_data_for_acme_diags/time-series/E3SM_v1/')
qbo_param.test_name = 'e3sm_v1'
qbo_param.start_yr = '1990'
예제 #6
0
]  # Default setting: seasons = ["ANN", "DJF", "MAM", "JJA", "SON"]

param.results_dir = os.path.join(html_prefix, "tutorial_2020_all_sets")
param.multiprocessing = True
param.num_workers = 30

# Additional parameters:
# param.short_test_name = 'beta0.FC5COSP.ne30'
# param.run_type = 'model_vs_model'
# param.diff_title = 'Difference'
# param.output_format = ['png']
# param.output_format_subplot = ['pdf']
# param.save_netcdf = True

# Set specific parameters for new sets
enso_param = EnsoDiagsParameter()
enso_param.reference_data_path = os.path.join(
    data_prefix, "obs_for_e3sm_diags/time-series/")
enso_param.test_data_path = os.path.join(
    data_prefix, "test_model_data_for_acme_diags/time-series/E3SM_v1/")
enso_param.test_name = "e3sm_v1"
enso_param.start_yr = "1990"
enso_param.end_yr = "1999"

qbo_param = QboParameter()
qbo_param.reference_data_path = os.path.join(
    data_prefix, "obs_for_e3sm_diags/time-series/")
qbo_param.test_data_path = os.path.join(
    data_prefix, "test_model_data_for_acme_diags/time-series/E3SM_v1/")
qbo_param.test_name = "e3sm_v1"
qbo_param.start_yr = "1990"
예제 #7
0
qbo_param.reference_data_path = obs_ts
qbo_param.test_data_path = ts_path
qbo_param.test_name = casename
qbo_param.start_yr = "1980"
qbo_param.end_yr = "2014"


dc_param = DiurnalCycleParameter()
dc_param.reference_data_path = obs_climo
dc_param.test_data_path = dc_climo_path
dc_param.test_name = case
dc_param.short_test_name = casename
# Plotting diurnal cycle amplitude on different scales. Default is True
dc_param.normalize_test_amp = False

enso_param = EnsoDiagsParameter()
enso_param.reference_data_path = obs_ts
enso_param.test_data_path = ts_path
enso_param.test_name = casename
enso_param.start_yr = "1980"
enso_param.end_yr = "2014"

ts_param = AreaMeanTimeSeriesParameter()
ts_param.reference_data_path = obs_ts
ts_param.test_data_path = ts_path
ts_param.test_name = casename
ts_param.start_yr = "1980"
ts_param.end_yr = "2014"

streamflow_param = StreamflowParameter()
streamflow_param.reference_data_path = obs_ts
def run_all_sets(html_prefix, d):
    param = CoreParameter()

    param.reference_data_path = d["obs_climo"]
    param.test_data_path = d["test_climo"]
    param.test_name = "20161118.beta0.FC5COSP.ne30_ne30.edison"
    param.seasons = [
        "ANN",
        "JJA",
    ]  # Default setting: seasons = ["ANN", "DJF", "MAM", "JJA", "SON"]

    param.results_dir = os.path.join(html_prefix, "v2_4_0_all_sets")
    param.multiprocessing = True
    param.num_workers = 30

    # Set specific parameters for new sets
    enso_param = EnsoDiagsParameter()
    enso_param.reference_data_path = d["obs_ts"]
    enso_param.test_data_path = d["test_ts"]
    enso_param.test_name = "e3sm_v1"
    enso_param.start_yr = "1990"
    enso_param.end_yr = "1999"

    qbo_param = QboParameter()
    qbo_param.reference_data_path = d["obs_ts"]
    qbo_param.test_data_path = d["test_ts"]
    qbo_param.test_name = "e3sm_v1"
    qbo_param.start_yr = "1990"
    qbo_param.end_yr = "1999"

    ts_param = AreaMeanTimeSeriesParameter()
    ts_param.reference_data_path = d["obs_ts"]
    ts_param.test_data_path = d["test_ts"]
    ts_param.test_name = "e3sm_v1"
    ts_param.start_yr = "1990"
    ts_param.end_yr = "1999"

    dc_param = DiurnalCycleParameter()
    dc_param.reference_data_path = d["dc_obs_climo"]
    dc_param.test_data_path = d["dc_test_climo"]
    dc_param.test_name = "20180215.DECKv1b_H1.ne30_oEC.edison"
    dc_param.short_test_name = "DECKv1b_H1.ne30_oEC"
    # Plotting diurnal cycle amplitude on different scales. Default is True
    dc_param.normalize_test_amp = False

    streamflow_param = StreamflowParameter()
    streamflow_param.reference_data_path = d["streamflow_obs_ts"]
    streamflow_param.test_data_path = d["streamflow_test_ts"]
    streamflow_param.test_name = "20180215.DECKv1b_H1.ne30_oEC.edison"
    streamflow_param.test_start_yr = "1980"
    streamflow_param.test_end_yr = "2014"
    # Streamflow gauge station data range from year 1986 to 1995
    streamflow_param.ref_start_yr = "1986"
    streamflow_param.ref_end_yr = "1995"

    arm_param = ARMDiagsParameter()
    arm_param.reference_data_path = d["arm_obs"]
    arm_param.ref_name = "armdiags"
    arm_param.test_data_path = d["arm_test"]
    arm_param.test_name = "20210122.F2010.armsites"
    arm_param.run_type = "model_vs_obs"
    arm_param.test_start_yr = "0001"
    arm_param.test_end_yr = "0001"
    arm_param.ref_start_yr = "0001"
    arm_param.ref_end_yr = "0001"

    runner.sets_to_run = [
        "lat_lon",
        "zonal_mean_xy",
        "zonal_mean_2d",
        "polar",
        "cosp_histogram",
        "meridional_mean_2d",
        "enso_diags",
        "qbo",
        "area_mean_time_series",
        "diurnal_cycle",
        "streamflow",
        "arm_diags",
    ]
    runner.run_diags([
        param, enso_param, qbo_param, ts_param, dc_param, streamflow_param,
        arm_param
    ])

    return param.results_dir