def _apply_convert_magicc6_to_magicc7_variables(variables, inverse): def hfc245ca_included(variables): variables = [variables] if isinstance(variables, str) else variables return any( [v.replace("-", "").lower() == "hfc245ca" for v in variables]) if hfc245ca_included(variables): error_msg = ( "HFC245ca wasn't meant to be included in MAGICC6. Renaming to HFC245fa." ) warnings.warn(error_msg) if inverse: return apply_string_substitutions( variables, MAGICC7_TO_MAGICC6_VARIABLES_MAPPING, unused_substitutions= "ignore", # TODO: make this warn and see what happens case_insensitive=True, # MAGICC variables are case insensitive ) else: return apply_string_substitutions( variables, MAGICC6_TO_MAGICC7_VARIABLES_MAPPING, unused_substitutions= "ignore", # TODO: make this warn and see what happens case_insensitive=True, # MAGICC variables are case insensitive )
def test_apply_string_substitutions_duplicate_substitutions_case_insensitive( inputs, substitutions, expected): res = apply_string_substitutions(inputs, substitutions) assert res == expected error_msg = re.escape( "Duplicate case insensitive substitutions: {}".format(substitutions)) with pytest.raises(ValueError, match=error_msg): apply_string_substitutions(inputs, substitutions, case_insensitive=True)
def _apply_convert_magicc7_to_openscm_variables(v, inverse): if inverse: return apply_string_substitutions( v, OPENSCM_TO_MAGICC7_VARIABLES_MAPPING, unused_substitutions="ignore", # TODO: make this warn and see what happens ) else: return apply_string_substitutions( v, MAGICC7_TO_OPENSCM_VARIABLES_MAPPING, unused_substitutions="ignore", # TODO: make this warn and see what happens case_insensitive=True, # MAGICC variables are case insensitive )
def _apply_convert_magicc_to_openscm_regions(regions, inverse): if inverse: return apply_string_substitutions( regions, OPENSCM_REGION_TO_MAGICC_REGION_MAPPING, unused_substitutions="ignore", # TODO: make this warn and see what happens ) else: return apply_string_substitutions( regions, MAGICC_REGION_TO_OPENSCM_REGION_MAPPING, unused_substitutions="ignore", # TODO: make this warn and see what happens case_insensitive=True, # MAGICC regions are case insensitive )
def test_apply_string_substitutions( mock_check_duplicate_substitutions, mock_check_unused_substitutions, mock_multiple_replace, mock_compile_replacement_regexp, ): treturn = "mocked return" mock_multiple_replace.return_value = treturn tcompiled_regexp = "mocked regexp" mock_compile_replacement_regexp.return_value = tcompiled_regexp tinput = "Hello JimBob" tsubstitutions = {"Jim": "Bob"} tcase_insensitive = "mocked case insensitivity" tunused_substitutions = "mocked unused substitutions" result = apply_string_substitutions( tinput, tsubstitutions, case_insensitive=tcase_insensitive, unused_substitutions=tunused_substitutions, ) assert result == treturn mock_check_duplicate_substitutions.assert_called_with(tsubstitutions) mock_check_unused_substitutions.assert_called_with(tsubstitutions, tinput, tunused_substitutions, tcase_insensitive) mock_compile_replacement_regexp.assert_called_with( tsubstitutions, case_insensitive=tcase_insensitive) mock_multiple_replace.assert_called_with(tinput, tsubstitutions, tcompiled_regexp)
def test_apply_string_substitutions_unused_substitutions( inputs, substitutions, unused_substitutions): if unused_substitutions == "ignore": result = apply_string_substitutions( inputs, substitutions, unused_substitutions=unused_substitutions) assert result == inputs return msg = "No substitution available for {'" + "{}".format(inputs) + "'}" if unused_substitutions == "warn": with warnings.catch_warnings(record=True) as warn_result: apply_string_substitutions( inputs, substitutions, unused_substitutions=unused_substitutions) assert len(warn_result) == 1 assert str(warn_result[0].message) == msg elif unused_substitutions == "raise": with pytest.raises(ValueError, match=re.escape(msg)): apply_string_substitutions( inputs, substitutions, unused_substitutions=unused_substitutions) else: msg = re.escape( "Invalid value for unused_substitutions, please see the docs") with pytest.raises(ValueError, match=msg): apply_string_substitutions( inputs, substitutions, unused_substitutions=unused_substitutions)
def convert_magicc6_to_magicc7_variables(variables, inverse=False): """ Convert MAGICC6 variables to MAGICC7 variables Parameters ---------- variables : list_like, str Variables to convert inverse : bool If True, convert the other way i.e. convert MAGICC7 variables to MAGICC6 variables Raises ------ ValueError If you try to convert HFC245ca, or some variant thereof, you will get a ValueError. The reason is that this variable was never meant to be included in MAGICC6, it was just an accident. See, for example, the text in the description section of ``pymagicc/MAGICC6/run/HISTRCP_HFC245fa_CONC.IN``: "...HFC245fa, rather than HFC245ca, is the actually used isomer.". Returns ------- ``type(variables)`` Set of converted variables """ def hfc245ca_included(variables): variables = [variables] if isinstance(variables, str) else variables return any( [v.replace("-", "").lower() == "hfc245ca" for v in variables]) if hfc245ca_included(variables): error_msg = ( "HFC245ca wasn't meant to be included in MAGICC6. Renaming to HFC245fa." ) warnings.warn(error_msg) if inverse: return apply_string_substitutions( variables, MAGICC7_TO_MAGICC6_VARIABLES_MAPPING) else: return apply_string_substitutions( variables, MAGICC6_TO_MAGICC7_VARIABLES_MAPPING)
def convert_pint_to_fortran_safe_units(units, inverse=False): """ Convert Pint units to Fortran safe units Parameters ---------- units : list_like, str Units to convert inverse : bool If True, convert the other way i.e. convert Fortran safe units to Pint units Returns ------- ``type(units)`` Set of converted units """ if inverse: return apply_string_substitutions(units, FORTRAN_SAFE_TO_PINT_UNITS_MAPPING) else: return apply_string_substitutions(units, PINT_TO_FORTRAN_SAFE_UNITS_MAPPING)
def get_openscm_replacement(in_var): if in_var.endswith("_EMIS"): prefix = "Emissions" elif in_var.endswith("_CONC"): prefix = "Atmospheric Concentrations" elif in_var.endswith("_RF"): prefix = "Radiative Forcing" elif in_var.endswith("_OT"): prefix = "Optical Thickness" else: raise ValueError("This shouldn't happen") variable = in_var.split("_")[0] # I hate edge cases edge_case_B = variable.upper() in ("HCFC141B", "HCFC142B") if variable.endswith("I"): variable = DATA_HIERARCHY_SEPARATOR.join( [variable[:-1], "MAGICC Fossil and Industrial"]) elif variable.endswith("B") and not edge_case_B: variable = DATA_HIERARCHY_SEPARATOR.join( [variable[:-1], "MAGICC AFOLU"]) case_adjustments = { "SOX": "SOx", "NOX": "NOx", "HFC134A": "HFC134a", "HFC143A": "HFC143a", "HFC152A": "HFC152a", "HFC227EA": "HFC227ea", "HFC236FA": "HFC236fa", "HFC245FA": "HFC245fa", "HFC365MFC": "HFC365mfc", "HCFC141B": "HCFC141b", "HCFC142B": "HCFC142b", "CH3CCL3": "CH3CCl3", "CCL4": "CCl4", "CH3CL": "CH3Cl", "CH2CL2": "CH2Cl2", "CHCL3": "CHCl3", "CH3BR": "CH3Br", "HALON1211": "Halon1211", "HALON1301": "Halon1301", "HALON2402": "Halon2402", "HALON1202": "Halon1202", "SOLAR": "Solar", "VOLCANIC": "Volcanic", } variable = apply_string_substitutions(variable, case_adjustments) return DATA_HIERARCHY_SEPARATOR.join([prefix, variable])
def convert_magicc7_to_openscm_variables(variables, inverse=False): """ Convert MAGICC7 variables to OpenSCM variables Parameters ---------- variables : list_like, str Variables to convert inverse : bool If True, convert the other way i.e. convert OpenSCM variables to MAGICC7 variables Returns ------- ``type(variables)`` Set of converted variables """ if inverse: return apply_string_substitutions( variables, OPENSCM_TO_MAGICC7_VARIABLES_MAPPING) else: return apply_string_substitutions( variables, MAGICC7_TO_OPENSCM_VARIABLES_MAPPING)
def convert_magicc_to_openscm_regions(regions, inverse=False): """ Convert MAGICC regions to OpenSCM regions Parameters ---------- regions : list_like, str Regions to convert inverse : bool If True, convert the other way i.e. convert OpenSCM regions to MAGICC7 regions Returns ------- ``type(regions)`` Set of converted regions """ if inverse: return apply_string_substitutions( regions, OPENSCM_REGION_TO_MAGICC_REGION_MAPPING) else: return apply_string_substitutions( regions, MAGICC_REGION_TO_OPENSCM_REGION_MAPPING)
def get_openscm_replacement(in_var): if in_var.endswith("_INVERSE_EMIS"): prefix = "Inverse Emissions" elif in_var.endswith("_EMIS"): prefix = "Emissions" elif in_var.endswith("_CONC"): prefix = "Atmospheric Concentrations" elif in_var.endswith("_ERF"): prefix = "Effective Radiative Forcing" elif in_var.endswith("_RF"): prefix = "Radiative Forcing" elif in_var.endswith("_OT"): prefix = "Optical Thickness" else: raise ValueError("This shouldn't happen") variable = in_var.split("_")[0] # I hate edge cases if variable.endswith("EQ"): variable = variable.replace("EQ", " Equivalent") if "GHG" in variable: variable = variable.replace("GHG", "Greenhouse Gases") if "BIOMASSAER" in variable: variable = variable.replace("BIOMASSAER", "Aerosols|Direct Effect|MAGICC AFOLU") if "CO2CH4N2O" in variable: variable = variable.replace("CO2CH4N2O", "CO2, CH4 and N2O") aggregate_indicators = { "KYOTO": "Kyoto Gases", "FGASSUM": "F Gases", "MHALOSUM": "Montreal Protocol Halogen Gases", } for agg_indicator, long_name in aggregate_indicators.items(): if variable.startswith(agg_indicator): stripped_var = variable.replace(agg_indicator, "") if stripped_var: variable = DATA_HIERARCHY_SEPARATOR.join( [stripped_var, long_name]) else: variable = long_name edge_case_B = variable.upper() in ("HCFC141B", "HCFC142B") if variable.endswith("I"): variable = DATA_HIERARCHY_SEPARATOR.join( [variable[:-1], "MAGICC Fossil and Industrial"]) elif variable.endswith("B") and not edge_case_B: variable = DATA_HIERARCHY_SEPARATOR.join( [variable[:-1], "MAGICC AFOLU"]) elif variable.endswith("T"): variable = variable[:-1] case_adjustments = { "SOX": "SOx", "NOX": "NOx", "CC4F8": "cC4F8", "HFC134A": "HFC134a", "HFC143A": "HFC143a", "HFC152A": "HFC152a", "HFC227EA": "HFC227ea", "HFC236FA": "HFC236fa", "HFC245FA": "HFC245fa", "HFC365MFC": "HFC365mfc", "HCFC141B": "HCFC141b", "HCFC142B": "HCFC142b", "CH3CCL3": "CH3CCl3", "CCL4": "CCl4", "CH3CL": "CH3Cl", "CH2CL2": "CH2Cl2", "CHCL3": "CHCl3", "CH3BR": "CH3Br", "HALON1211": "Halon1211", "HALON1301": "Halon1301", "HALON2402": "Halon2402", "HALON1202": "Halon1202", "SOLAR": "Solar", "VOLCANIC": "Volcanic", "EXTRA": "Extra", } variable = apply_string_substitutions(variable, case_adjustments) return DATA_HIERARCHY_SEPARATOR.join([prefix, variable])
def preprocess_edge_cases(lines, inverse=False): replacements = {"W/m": "Wperm", "^": "superscript"} return apply_string_substitutions(lines, replacements, inverse=inverse)
def test_apply_string_substitutions_inverse(inputs, substitutions, expected): result = apply_string_substitutions(inputs, substitutions, inverse=True) assert result == expected
def test_apply_string_substitutions_default(inputs, substitutions, expected): result = apply_string_substitutions(inputs, substitutions) assert result == expected
def test_apply_string_substitutions_case_insensitive(inputs, substitutions, expected): result = apply_string_substitutions(inputs, substitutions, case_insensitive=True) assert result == expected