Example #1
0
    def test_zonal_mean_2d(self):
        # Running zonal_mean_2d with the core param only.
        self.runner.sets_to_run = ['zonal_mean_2d']
        core_only_results = self.runner.get_final_parameters([self.core_param])

        # Running zonal_mean_2d with a set-specific param.
        # We pass in both the core and this parameter.
        zonal_mean_2d_param = ZonalMean2dParameter()
        zonal_mean_2d_param.plevs = [10.0, 20.0, 30.0]
        both_results = self.runner.get_final_parameters(
            [self.core_param, zonal_mean_2d_param])

        # Check that the plevs value is actually changed.
        for param in both_results:
            if param.plevs != zonal_mean_2d_param.plevs:
                msg = 'plevs are {} when they should be {}.'
                self.fail(msg.format(param.plevs, zonal_mean_2d_param.plevs))

        # Running zonal_mean_2d without a CoreParameter.
        # When doing so, we still must have valid values for
        # certain parameters.
        another_zonal_mean_2d_param = ZonalMean2dParameter()
        another_zonal_mean_2d_param.reference_data_path = '/something'
        another_zonal_mean_2d_param.test_data_path = '/something/else'
        another_zonal_mean_2d_param.results_dir = '/something/else/too'
        zm_2d_only_results = self.runner.get_final_parameters(
            [another_zonal_mean_2d_param])

        # Now checking that all three configs have the same output.
        len1, len2, len3 = len(core_only_results), len(both_results), len(
            zm_2d_only_results)
        if len1 == 0 or not (len1 == len2 == len3):
            msg = 'The lengths are either 0 or not equal: {} {} {}'
            self.fail(msg.format(len1, len2, len3))
Example #2
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])
Example #3
0
from acme_diags.parameter.core_parameter import CoreParameter
from acme_diags.parameter.zonal_mean_2d_parameter import ZonalMean2dParameter
from acme_diags.run import runner

param = CoreParameter()

param.reference_data_path = (
    "/global/cfs/cdirs/e3sm/acme_diags/obs_for_e3sm_diags/climatology/")
param.test_data_path = (
    "/global/cfs/cdirs/e3sm/acme_diags/test_model_data_for_acme_diags/climatology/"
)
param.test_name = "20161118.beta0.FC5COSP.ne30_ne30.edison"
param.seasons = ["ANN"]

# Name of the folder where the results are stored.
# Change `prefix` to use your directory.
prefix = "/global/cfs/cdirs/e3sm/www/<your directory>/examples"
param.results_dir = os.path.join(prefix, "ex6_zonal_mean_2d_and_lat_lon_demo")

# Uncomment the two lines below to just
# run the diags with T and PRECT.
# param.selectors += ['variables']
# param.variables = ['T', 'PRECT']

# The new changes are below.
zonal_mean_2d_param = ZonalMean2dParameter()
zonal_mean_2d_param.plevs = [10.0, 20.0, 30.0]

runner.sets_to_run = ["zonal_mean_2d", "lat_lon"]
runner.run_diags([param, zonal_mean_2d_param])
def run_diag(parameter):
    variables = parameter.variables
    seasons = parameter.seasons
    ref_name = getattr(parameter, "ref_name", "")

    test_data = utils.dataset.Dataset(parameter, test=True)
    ref_data = utils.dataset.Dataset(parameter, ref=True)

    for season in seasons:
        # Get the name of the data, appended with the years averaged.
        parameter.test_name_yrs = utils.general.get_name_and_yrs(
            parameter, test_data, season)
        parameter.ref_name_yrs = utils.general.get_name_and_yrs(
            parameter, ref_data, season)

        for var in variables:
            print("Variable: {}".format(var))
            parameter.var_id = var

            mv1 = test_data.get_climo_variable(var, season)
            mv2 = ref_data.get_climo_variable(var, season)

            parameter.viewer_descr[var] = (mv1.long_name if hasattr(
                mv1, "long_name") else "No long_name attr in test data.")

            # For variables with a z-axis.
            if mv1.getLevel() and mv2.getLevel():
                # Since the default is now stored in MeridionalMean2dParameter,
                # we must get it from there if the plevs param is blank.
                plevs = parameter.plevs
                if (isinstance(plevs, numpy.ndarray) and not plevs.all()) or (
                        not isinstance(plevs, numpy.ndarray) and not plevs):
                    plevs = ZonalMean2dParameter().plevs

                # print('Selected pressure level: {}'.format(plevs))

                mv1_p = utils.general.convert_to_pressure_levels(
                    mv1, plevs, test_data, var, season)
                mv2_p = utils.general.convert_to_pressure_levels(
                    mv2, plevs, ref_data, var, season)

                mv1_p = cdutil.averager(mv1_p, axis="y")
                mv2_p = cdutil.averager(mv2_p, axis="y")

                parameter.output_file = "-".join(
                    [ref_name, var, season, parameter.regions[0]])
                parameter.main_title = str(" ".join([var, season]))

                # Regrid towards the lower resolution of the two
                # variables for calculating the difference.
                if len(mv1_p.getLongitude()) < len(mv2_p.getLongitude()):
                    mv1_reg = mv1_p
                    lev_out = mv1_p.getLevel()
                    lon_out = mv1_p.getLongitude()
                    # in order to use regrid tool we need to have at least two latitude bands, so generate new grid first
                    lat = cdms2.createAxis([0])
                    lat.setBounds(numpy.array([-1, 1]))
                    lat.designateLatitude()
                    grid = cdms2.createRectGrid(lat, lon_out)

                    data_shape = list(mv2_p.shape)
                    data_shape.append(1)
                    mv2_reg = MV2.resize(mv2_p, data_shape)
                    mv2_reg.setAxis(-1, lat)
                    for i, ax in enumerate(mv2_p.getAxisList()):
                        mv2_reg.setAxis(i, ax)

                    mv2_reg = mv2_reg.regrid(grid, regridTool="regrid2")[...,
                                                                         0]
                    # Apply the mask back, since crossSectionRegrid
                    # doesn't preserve the mask.
                    mv2_reg = MV2.masked_where(mv2_reg == mv2_reg.fill_value,
                                               mv2_reg)
                elif len(mv1_p.getLongitude()) > len(mv2_p.getLongitude()):
                    mv2_reg = mv2_p
                    lev_out = mv2_p.getLevel()
                    lon_out = mv2_p.getLongitude()
                    mv1_reg = mv1_p.crossSectionRegrid(lev_out, lon_out)
                    # In order to use regrid tool we need to have at least two
                    # latitude bands, so generate new grid first.
                    lat = cdms2.createAxis([0])
                    lat.setBounds(numpy.array([-1, 1]))
                    lat.designateLatitude()
                    grid = cdms2.createRectGrid(lat, lon_out)

                    data_shape = list(mv1_p.shape)
                    data_shape.append(1)
                    mv1_reg = MV2.resize(mv1_p, data_shape)
                    mv1_reg.setAxis(-1, lat)
                    for i, ax in enumerate(mv1_p.getAxisList()):
                        mv1_reg.setAxis(i, ax)

                    mv1_reg = mv1_reg.regrid(grid, regridTool="regrid2")[...,
                                                                         0]
                    # Apply the mask back, since crossSectionRegrid
                    # doesn't preserve the mask.
                    mv1_reg = MV2.masked_where(mv1_reg == mv1_reg.fill_value,
                                               mv1_reg)
                else:
                    mv1_reg = mv1_p
                    mv2_reg = mv2_p

                diff = mv1_reg - mv2_reg
                metrics_dict = create_metrics(mv2_p, mv1_p, mv2_reg, mv1_reg,
                                              diff)

                parameter.var_region = "global"

                plot(
                    parameter.current_set,
                    mv2_p,
                    mv1_p,
                    diff,
                    metrics_dict,
                    parameter,
                )
                utils.general.save_ncfiles(parameter.current_set, mv1_p, mv2_p,
                                           diff, parameter)

            # For variables without a z-axis.
            elif mv1.getLevel() is None and mv2.getLevel() is None:
                raise RuntimeError(
                    "One of or both data doesn't have z dimention. Aborting.")

    return parameter
def run_diag(parameter):
    variables = parameter.variables
    seasons = parameter.seasons
    ref_name = getattr(parameter, 'ref_name', '')
    regions = parameter.regions

    test_data = utils.dataset.Dataset(parameter, test=True)
    ref_data = utils.dataset.Dataset(parameter, ref=True)

    for season in seasons:
        # Get the name of the data, appended with the years averaged.
        parameter.test_name_yrs = utils.general.get_name_and_yrs(
            parameter, test_data, season)
        parameter.ref_name_yrs = utils.general.get_name_and_yrs(
            parameter, ref_data, season)

        # Get land/ocean fraction for masking.
        try:
            land_frac = test_data.get_climo_variable('LANDFRAC', season)
            ocean_frac = test_data.get_climo_variable('OCNFRAC', season)
        except:
            mask_path = os.path.join(acme_diags.INSTALL_PATH,
                                     'acme_ne30_ocean_land_mask.nc')
            with cdms2.open(mask_path) as f:
                land_frac = f('LANDFRAC')
                ocean_frac = f('OCNFRAC')

        for var in variables:
            print('Variable: {}'.format(var))
            parameter.var_id = var

            mv1 = test_data.get_climo_variable(var, season)
            mv2 = ref_data.get_climo_variable(var, season)

            parameter.viewer_descr[var] = mv1.long_name if hasattr(
                mv1, 'long_name') else 'No long_name attr in test data.'

            # Special case, cdms didn't properly convert mask with fill value
            # -999.0, filed issue with Denis.
            if ref_name == 'WARREN':
                # This is cdms2 fix for bad mask, Denis' fix should fix this.
                mv2 = MV2.masked_where(mv2 == -0.9, mv2)
            # The following should be moved to a derived variable.
            if ref_name == 'AIRS':
                # This is cdms2 fix for bad mask, Denis' fix should fix this.
                mv2 = MV2.masked_where(mv2 > 1e+20, mv2)
            if ref_name == 'WILLMOTT' or ref_name == 'CLOUDSAT':
                # This is cdms2 fix for bad mask, Denis' fix should fix this.
                mv2 = MV2.masked_where(mv2 == -999., mv2)

                # The following should be moved to a derived variable.
                if var == 'PRECT_LAND':
                    days_season = {
                        'ANN': 365,
                        'DJF': 90,
                        'MAM': 92,
                        'JJA': 92,
                        'SON': 91
                    }
                    # mv1 = mv1 * days_season[season] * 0.1 # following AMWG
                    # Approximate way to convert to seasonal cumulative
                    # precipitation, need to have solution in derived variable,
                    # unit convert from mm/day to cm.
                    mv2 = mv2 / days_season[season] / \
                        0.1  # Convert cm to mm/day instead.
                    mv2.units = 'mm/day'

            # For variables with a z-axis.
            if mv1.getLevel() and mv2.getLevel():
                # Since the default is now stored in ZonalMean2dParameter,
                # we must get it from there if the plevs param is blank.
                plevs = parameter.plevs
                if (isinstance(plevs, numpy.ndarray) and not plevs.all()) or \
                    (not isinstance(plevs, numpy.ndarray) and not plevs):
                    plevs = ZonalMean2dParameter().plevs

                #print('Selected pressure level: {}'.format(plevs))

                mv1_p = utils.general.convert_to_pressure_levels(
                    mv1, plevs, test_data, var, season)
                mv2_p = utils.general.convert_to_pressure_levels(
                    mv2, plevs, ref_data, var, season)

                mv1_p = cdutil.averager(mv1_p, axis='x')
                mv2_p = cdutil.averager(mv2_p, axis='x')

                parameter.output_file = '-'.join(
                    [ref_name, var, season, parameter.regions[0]])
                parameter.main_title = str(' '.join([var, season]))

                # Regrid towards the lower resolution of the two
                # variables for calculating the difference.
                if len(mv1_p.getLatitude()) < len(mv2_p.getLatitude()):
                    mv1_reg = mv1_p
                    lev_out = mv1_p.getLevel()
                    lat_out = mv1_p.getLatitude()
                    mv2_reg = mv2_p.crossSectionRegrid(lev_out, lat_out)
                    # Apply the mask back, since crossSectionRegrid
                    # doesn't preserve the mask.
                    mv2_reg = MV2.masked_where(mv2_reg == mv2_reg.fill_value,
                                               mv2_reg)
                elif len(mv1_p.getLatitude()) > len(mv2_p.getLatitude()):
                    mv2_reg = mv2_p
                    lev_out = mv2_p.getLevel()
                    lat_out = mv2_p.getLatitude()
                    mv1_reg = mv1_p.crossSectionRegrid(lev_out, lat_out)
                    # Apply the mask back, since crossSectionRegrid
                    # doesn't preserve the mask.
                    mv1_reg = MV2.masked_where(mv1_reg == mv1_reg.fill_value,
                                               mv1_reg)
                else:
                    mv1_reg = mv1_p
                    mv2_reg = mv2_p

                diff = mv1_reg - mv2_reg
                metrics_dict = create_metrics(mv2_p, mv1_p, mv2_reg, mv1_reg,
                                              diff)

                parameter.var_region = 'global'

                plot(parameter.current_set, mv2_p, mv1_p, diff, metrics_dict,
                     parameter)
                utils.general.save_ncfiles(parameter.current_set, mv1_p, mv2_p,
                                           diff, parameter)

            # For variables without a z-axis.
            elif mv1.getLevel() is None and mv2.getLevel() is None:
                for region in regions:
                    #print("Selected region: {}".format(region))

                    mv1_domain = utils.general.select_region(
                        region, mv1, land_frac, ocean_frac, parameter)
                    mv2_domain = utils.general.select_region(
                        region, mv2, land_frac, ocean_frac, parameter)

                    parameter.output_file = '-'.join(
                        [ref_name, var, season, region])
                    parameter.main_title = str(' '.join([var, season, region]))

                    # Regrid towards the lower resolution of the two
                    # variables for calculating the difference.
                    mv1_reg, mv2_reg = utils.general.regrid_to_lower_res(
                        mv1_domain, mv2_domain, parameter.regrid_tool,
                        parameter.regrid_method)

                    # Special case.
                    if var == 'TREFHT_LAND' or var == 'SST':
                        if ref_name == 'WILLMOTT':
                            mv2_reg = MV2.masked_where(
                                mv2_reg == mv2_reg.fill_value, mv2_reg)
                        land_mask = MV2.logical_or(mv1_reg.mask, mv2_reg.mask)
                        mv1_reg = MV2.masked_where(land_mask, mv1_reg)
                        mv2_reg = MV2.masked_where(land_mask, mv2_reg)

                    diff = mv1_reg - mv2_reg
                    metrics_dict = create_metrics(mv2_domain, mv1_domain,
                                                  mv2_reg, mv1_reg, diff)
                    parameter.var_region = region

                    plot(parameter.current_set, mv2_domain, mv1_domain, diff,
                         metrics_dict, parameter)
                    utils.general.save_ncfiles(parameter.current_set,
                                               mv1_domain, mv2_domain, diff,
                                               parameter)

            else:
                raise RuntimeError(
                    "Dimensions of the two variables are different. Aborting.")

    return parameter