def _write_mag_file( # pylint:disable=too-many-arguments openscmdf, metadata, header, outfile_dir, symlink_dir, fnames, force): out_file = os.path.join(outfile_dir, fnames[0]) out_file = "{}.MAG".format(os.path.splitext(out_file)[0]) if _skip_file(out_file, force, symlink_dir): return writer = MAGICCData(openscmdf) writer["todo"] = "SET" time_steps = writer.timeseries().columns[1:] - writer.timeseries( ).columns[:-1] step_upper = np.timedelta64(32, "D") # pylint:disable=too-many-function-args step_lower = np.timedelta64(28, "D") # pylint:disable=too-many-function-args if any((time_steps > step_upper) | (time_steps < step_lower)): raise ValueError("Please raise an issue at " "github.com/znicholls/netcdf-scm/issues " "to discuss how to handle non-monthly data wrangling") writer.metadata = metadata writer.metadata["timeseriestype"] = "MONTHLY" writer.metadata["header"] = header logger.info("Writing file to %s", out_file) writer.write(out_file, magicc_version=7) symlink_file = os.path.join(symlink_dir, os.path.basename(out_file)) logger.info("Making symlink to %s", symlink_file) os.symlink(out_file, symlink_file)
def _write_magicc_input_files( # pylint:disable=too-many-arguments,too-many-locals openscmdf, time_id, outfile_dir, symlink_dir, force, metadata, header, timeseriestype, ): try: var_to_write = openscmdf["variable"].unique()[0] variable_abbreviations = { "filename": var_to_write, "magicc_name": _MAGICC_VARIABLE_MAP[var_to_write][0], "magicc_internal_name": _MAGICC_VARIABLE_MAP[var_to_write][1], } except KeyError: raise KeyError( "I don't know which MAGICC variable to use for input `{}`".format( var_to_write)) region_filters = { "FOURBOX": [ "World|Northern Hemisphere|Land", "World|Southern Hemisphere|Land", "World|Northern Hemisphere|Ocean", "World|Southern Hemisphere|Ocean", ], "GLOBAL": ["World"], } for region_key, regions_to_keep in region_filters.items(): out_file = os.path.join( outfile_dir, (("{}_{}_{}_{}_{}_{}_{}.IN").format( variable_abbreviations["filename"], openscmdf["scenario"].unique()[0], openscmdf["climate_model"].unique()[0], openscmdf["member_id"].unique()[0], time_id, region_key, variable_abbreviations["magicc_internal_name"], ).upper()), ) symlink_file = os.path.join(symlink_dir, os.path.basename(out_file)) if _skip_file(out_file, force, symlink_dir): return writer = MAGICCData(openscmdf).filter(region=regions_to_keep) writer["todo"] = "SET" writer["variable"] = variable_abbreviations["magicc_name"] writer.metadata = metadata writer.metadata["header"] = header writer.metadata["timeseriestype"] = timeseriestype logger.info("Writing file to %s", out_file) writer.write(out_file, magicc_version=7) logger.info("Making symlink to %s", symlink_file) os.symlink(out_file, symlink_file)
def writing_base_mag(): tregions = ( ["World"] + ["World|{}".format(r) for r in ["Northern Hemisphere", "Southern Hemisphere"]] + ["World|{}".format(r) for r in ["Land", "Ocean"]] ) writing_base_mag = MAGICCData( data=np.arange(27 * len(tregions)).reshape(27, len(tregions)), index=[ dt.datetime(2099, 1, 16, 12, 0), dt.datetime(2099, 2, 15, 0, 0), dt.datetime(2099, 3, 16, 12, 0), dt.datetime(2099, 4, 16, 0, 0), dt.datetime(2099, 5, 16, 12, 0), dt.datetime(2099, 6, 16, 0, 0), dt.datetime(2099, 7, 16, 12, 0), dt.datetime(2099, 8, 16, 12, 0), dt.datetime(2099, 9, 16, 0, 0), dt.datetime(2099, 10, 16, 12, 0), dt.datetime(2099, 11, 16, 0, 0), dt.datetime(2099, 12, 16, 12, 0), dt.datetime(2100, 1, 16, 12, 0), dt.datetime(2100, 2, 15, 0, 0), dt.datetime(2100, 3, 16, 12, 0), dt.datetime(2100, 4, 16, 0, 0), dt.datetime(2100, 5, 16, 12, 0), dt.datetime(2100, 6, 16, 0, 0), dt.datetime(2100, 7, 16, 12, 0), dt.datetime(2100, 8, 16, 12, 0), dt.datetime(2100, 9, 16, 0, 0), dt.datetime(2100, 10, 16, 12, 0), dt.datetime(2100, 11, 16, 0, 0), dt.datetime(2100, 12, 16, 12, 0), dt.datetime(2101, 1, 16, 12, 0), dt.datetime(2101, 2, 15, 0, 0), dt.datetime(2101, 3, 16, 12, 0), ], columns={ "region": tregions, "variable": "NPP", "model": "unspecified", "scenario": "mag test", "unit": "gC/yr", "todo": "SET", }, ) writing_base_mag.metadata = { "header": "Test mag file", "timeseriestype": "MONTHLY", "other info": "checking time point handling", } yield writing_base_mag
def test_external_forcing_only_run(package): time = zero_emissions["time"] forcing_external = 2.0 * np.arange(0, len(time)) / len(time) forcing_ext = MAGICCData( forcing_external, columns={ "index": time, "scenario": ["idealised"], "model": ["unspecified"], "climate_model": ["unspecified"], "variable": ["Radiative Forcing|Extra"], "unit": ["W / m^2"], "todo": ["SET"], "region": ["World"], }, ) forcing_ext_filename = "EXTERNAL_RF.IN" forcing_ext.metadata = { "header": "External radiative forcing file for testing" } forcing_ext.write(join(package.run_dir, forcing_ext_filename), package.version) results = package.run( rf_extra_read=1, file_extra_rf=forcing_ext_filename, rf_total_runmodus="QEXTRA", endyear=max(time).year, rf_initialization_method= "ZEROSTARTSHIFT", # this is default but just in case rf_total_constantafteryr=5000, ) # MAGICC's weird last year business means that last result is just constant from previous # year and is not treated properly # TODO: add this in docs validation_output = (results.filter( variable="Radiative Forcing", region="World").timeseries().values.squeeze()[:-1]) validation_input = forcing_external[:-1] np.testing.assert_allclose(validation_input, validation_output, rtol=1e-5) temperature_global = (results.filter( variable="Surface Temperature", region="World").timeseries().values.squeeze()) assert (temperature_global[1:] - temperature_global[:-1] >= 0).all()
def _write_mag_file_with_operation( # pylint:disable=too-many-arguments openscmdf, metadata, header, outfile_dir, symlink_dir, fnames, force, out_format): # pylint:disable=too-many-locals if len(fnames) > 1: raise AssertionError("more than one file to wrangle?" ) # pragma: no cover # emergency valve ts = openscmdf.timeseries() src_time_points = ts.columns original_years = ts.columns.map(lambda x: x.year).unique() time_id = "{}-{}".format(src_time_points[0].year, src_time_points[-1].year) regex_search = r"{:04d}\d*-{:04d}\d*".format(src_time_points[0].year, src_time_points[-1].year) old_time_id = re.search(regex_search, fnames[0]).group(0) out_file = os.path.join(outfile_dir, fnames[0].replace(old_time_id, time_id)) out_file = "{}.MAG".format(os.path.splitext(out_file)[0]) if _skip_file(out_file, force, symlink_dir): return writer = MAGICCData(_do_timeseriestype_operation( openscmdf, out_format)).filter(year=original_years) writer["todo"] = "SET" writer.metadata = metadata writer.metadata["timeseriestype"] = (out_format.replace( "mag-files-", "").replace("-", "_").upper()) writer.metadata["header"] = header logger.info("Writing file to %s", out_file) writer.write(out_file, magicc_version=7) symlink_file = os.path.join(symlink_dir, os.path.basename(out_file)) logger.info("Making symlink to %s", symlink_file) os.symlink(out_file, symlink_file)
def test_co2_emms_other_rf_run(package, emms_co2_level): package.set_zero_config() df = zero_emissions.timeseries() time = zero_emissions["time"] emms_fossil_co2 = np.zeros(len(time)) emms_fossil_co2[20:] = emms_co2_level df.loc[( df.index.get_level_values("variable") == "Emissions|CO2|MAGICC Fossil and Industrial"), :, ] = emms_fossil_co2 scen = MAGICCData(df) forcing_external = 2.0 * np.arange(0, len(time)) / len(time) forcing_ext = MAGICCData( forcing_external, columns={ "index": time, "scenario": ["idealised"], "model": ["unspecified"], "climate_model": ["unspecified"], "variable": ["Radiative Forcing|Extra"], "unit": ["W / m^2"], "todo": ["SET"], "region": ["World"], }, ) forcing_ext.metadata = { "header": "External radiative forcing file for testing" } forcing_ext_filename = "EXTERNAL_RF.IN" forcing_ext.write(join(package.run_dir, forcing_ext_filename), package.version) # TODO: fix endyear so it takes from scenario input by default results = package.run( scen, endyear=max(time).year, rf_extra_read=1, # fix writing of 'True' file_extra_rf=forcing_ext_filename, rf_total_runmodus="all", rf_initialization_method="ZEROSTARTSHIFT", rf_total_constantafteryr=5000, ) np.testing.assert_allclose( results.filter(variable="Em*CO2*Fossil*", region="World").timeseries().values.squeeze(), emms_fossil_co2, ) # CO2 temperature feedbacks mean that you get a CO2 outgassing, hence CO2 forcing. As a # result radiative forcing values don't match exactly. Numerical precision adds to this. ext_rf_output_vals = (results.filter( variable="Radiative Forcing", region="World").timeseries().values.squeeze()) zero_rows = (forcing_external == 0) & (ext_rf_output_vals == 0) greater_equal_rows = ext_rf_output_vals >= forcing_external close_rows_denominator = forcing_external close_rows_denominator[zero_rows] = 10**-10 # avoid divide by zero close_rows = (np.abs(ext_rf_output_vals - forcing_external) / close_rows_denominator <= 10**-3) matching_rows = greater_equal_rows | close_rows assert matching_rows.all()