def test_handles_not_too_many_nans_within_shapes(single_shape, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([0, np.nan, 2, 3]) area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data, gridcell_overlap_threshold=0.75 )
def test_fails_with_diverging_crs(single_shape, any_spatiotemporal_data, crs1, crs2): single_shape = single_shape.to_crs(crs1) any_spatiotemporal_data.attrs["crs"] = crs2 with pytest.raises(AssertionError): area_weighted_time_series(shapes=single_shape, spatiotemporal=any_spatiotemporal_data)
def test_fails_with_too_much_nodata_within_shapes(single_shape, spatiotemporal_data_with_nodata_within_single_shape): with pytest.raises(AssertionError): area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data_with_nodata_within_single_shape, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_fails_with_wrong_dimension_names(single_shape, any_spatiotemporal_data, correct_name, wrong_name): any_spatiotemporal_data = any_spatiotemporal_data.rename({correct_name: wrong_name}) with pytest.raises(AssertionError): area_weighted_time_series( shapes=single_shape, spatiotemporal=any_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_allows_all_crs(single_shape, any_spatiotemporal_data, crs): single_shape = single_shape.set_crs(crs, allow_override=True) any_spatiotemporal_data.attrs["crs"] = crs area_weighted_time_series( shapes=single_shape, spatiotemporal=any_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_fails_without_crs_in_spatiotemporal(single_shape, any_spatiotemporal_data): del any_spatiotemporal_data.attrs["crs"] with pytest.raises(AssertionError): area_weighted_time_series( shapes=single_shape, spatiotemporal=any_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_fails_with_too_many_nans_within_shapes(single_shape, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([0, np.nan, 2, 3]) with pytest.raises(AssertionError): area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_fails_with_wrong_dimension_names(single_shape, any_spatiotemporal_data, correct_name, wrong_name): any_spatiotemporal_data = any_spatiotemporal_data.rename( {correct_name: wrong_name}) with pytest.raises(AssertionError): area_weighted_time_series(shapes=single_shape, spatiotemporal=any_spatiotemporal_data)
def test_fails_with_diverging_crs(single_shape, any_spatiotemporal_data, crs1, crs2): single_shape = single_shape.to_crs(crs1) any_spatiotemporal_data.attrs["crs"] = crs2 with pytest.raises(AssertionError): area_weighted_time_series( shapes=single_shape, spatiotemporal=any_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_handles_non_rectangular_data(single_shape, non_rectangular_spatiotemporal_data): weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=non_rectangular_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD ) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_returns_normal_with_nodata_outside_shape(single_shape, spatiotemporal_data_with_nodata_outside_single_shape): weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data_with_nodata_outside_single_shape, gridcell_overlap_threshold=DEFAULT_THRESHOLD ) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_partial_match(single_shape_small, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([1, 1, 2, 2]) weighted_ts = area_weighted_time_series(shapes=single_shape_small, spatiotemporal=spatiotemporal_data) expected_mean = 1 * (8 / 12) + 2 * (4 / 12) assert pytest.approx(expected_mean, rel=0.001) == weighted_ts.iloc[:, 0].values.mean()
def test_equal_values(single_shape, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([8, 8, 8, 8]) weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD ) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_four_shapes(four_shapes, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([0, 1, 2, 3]) weighted_ts = area_weighted_time_series(shapes=four_shapes, spatiotemporal=spatiotemporal_data) assert (weighted_ts.iloc[:, 0].values == 0).all() assert (weighted_ts.iloc[:, 1].values == 1).all() assert (weighted_ts.iloc[:, 2].values == 2).all() assert (weighted_ts.iloc[:, 3].values == 3).all()
def test_four_shapes(four_shapes, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([0, 1, 2, 3]) weighted_ts = area_weighted_time_series( shapes=four_shapes, spatiotemporal=spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD ) assert (weighted_ts.iloc[:, 0].values == 0).all() assert (weighted_ts.iloc[:, 1].values == 1).all() assert (weighted_ts.iloc[:, 2].values == 2).all() assert (weighted_ts.iloc[:, 3].values == 3).all()
def capacityfactors(path_to_eez, path_to_shared_coast, path_to_timeseries, threshold, path_to_result, year=None): """Generate offshore capacityfactor time series for each location.""" eez = gpd.read_file(path_to_eez).set_index("id").to_crs(EPSG3035).geometry shared_coast = pd.read_csv(path_to_shared_coast, index_col=0) shared_coast.index = shared_coast.index.map(lambda x: x.replace(".", "-")) ts = xr.open_dataset(path_to_timeseries) if year: ts = ts.sel(time=str(year)) ts = convert_old_style_capacity_factor_time_series(ts) capacityfactors_per_eez = area_weighted_time_series(shapes=eez, spatiotemporal=ts) capacityfactors = _allocate_to_onshore_locations(capacityfactors_per_eez, shared_coast) capacityfactors.where(capacityfactors >= threshold, 0).to_csv(path_to_result)
def capacityfactors(path_to_locations, path_to_timeseries, path_to_timeseries_with_coordinates, cf_threshold, path_to_result, gridcell_overlap_threshold, first_year=None, final_year=None): """Generate capacityfactor time series for each location.""" locations = gpd.read_file(path_to_locations).set_index("id").to_crs( EPSG3035).geometry locations.index = locations.index.map(lambda x: x.replace(".", "-")) ts = xr.open_dataset(path_to_timeseries) ts = ts.sel(time=slice(first_year, final_year)) # xarray will silently miss the fact that data doesn't exist with slice if first_year is not None and first_year not in ts.time.to_index( ).year.astype(str).unique(): raise ValueError( f"Cannot access capacity factor data for timeseries {path_to_timeseries} " f"with a start year of {first_year}.") if final_year is not None and final_year not in ts.time.to_index( ).year.astype(str).unique(): raise ValueError( f"Cannot access capacity factor data for timeseries {path_to_timeseries} " f"with an end year of {final_year}.") if ("lat" not in ts.dims) or ( "lon" not in ts.dims): # rooftop pv comes without coordinates ts_with_latlon = xr.open_dataset(path_to_timeseries_with_coordinates) ts["lat"] = ts_with_latlon["lat"] ts["lon"] = ts_with_latlon["lon"] ts = convert_old_style_capacity_factor_time_series(ts) capacityfactors = area_weighted_time_series( shapes=locations, spatiotemporal=ts, gridcell_overlap_threshold=gridcell_overlap_threshold) capacityfactors.where(capacityfactors >= cf_threshold, 0).to_csv(path_to_result)
def capacityfactors(path_to_eez, path_to_shared_coast, path_to_timeseries, cf_threshold, path_to_result, gridcell_overlap_threshold, first_year=None, final_year=None): """Generate offshore capacityfactor time series for each location.""" eez = gpd.read_file(path_to_eez).set_index("mrgid").to_crs( EPSG3035).geometry shared_coast = pd.read_csv(path_to_shared_coast, index_col=0) shared_coast.index = shared_coast.index.map(lambda x: x.replace(".", "-")) shared_coast.columns = shared_coast.columns.astype(int) ts = xr.open_dataset(path_to_timeseries) ts = ts.sel(time=slice(first_year, final_year)) # xarray will silently miss the fact that data doesn't exist with slice if first_year is not None and first_year not in ts.time.to_index( ).year.astype(str).unique(): raise ValueError( f"Cannot access capacity factor data for timeseries {path_to_timeseries} " f"with a start year of {first_year}.") if final_year is not None and final_year not in ts.time.to_index( ).year.astype(str).unique(): raise ValueError( f"Cannot access capacity factor data for timeseries {path_to_timeseries} " f"with an end year of {final_year}.") ts = convert_old_style_capacity_factor_time_series(ts) capacityfactors_per_eez = area_weighted_time_series( shapes=eez, spatiotemporal=ts, gridcell_overlap_threshold=gridcell_overlap_threshold) capacityfactors = _allocate_to_onshore_locations(capacityfactors_per_eez, shared_coast) capacityfactors.where(capacityfactors >= cf_threshold, 0).to_csv(path_to_result)
def capacityfactors(path_to_locations, path_to_timeseries, path_to_timeseries_with_coordinates, threshold, path_to_result, year=None): """Generate capacityfactor time series for each location.""" locations = gpd.read_file(path_to_locations).set_index("id").to_crs( EPSG3035).geometry locations.index = locations.index.map(lambda x: x.replace(".", "-")) ts = xr.open_dataset(path_to_timeseries) if year: ts = ts.sel(time=str(year)) if ("lat" not in ts.dims) or ( "lon" not in ts.dims): # rooftop pv comes without coordinates ts_with_latlon = xr.open_dataset(path_to_timeseries_with_coordinates) ts["lat"] = ts_with_latlon["lat"] ts["lon"] = ts_with_latlon["lon"] ts = convert_old_style_capacity_factor_time_series(ts) capacityfactors = area_weighted_time_series(shapes=locations, spatiotemporal=ts) capacityfactors.where(capacityfactors >= threshold, 0).to_csv(path_to_result)
def test_handles_reverted_coordinates_gracefully(single_shape, reverted_spatiotemporal_data): area_weighted_time_series( shapes=single_shape, spatiotemporal=reverted_spatiotemporal_data, )
def test_handles_not_too_much_nodata_within_shapes(single_shape, spatiotemporal_data_with_nodata_within_single_shape): area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data_with_nodata_within_single_shape, gridcell_overlap_threshold=0.75 )
def test_returns_normal_with_nodata_outside_shape( single_shape, spatiotemporal_data_with_nodata_outside_single_shape): weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data_with_nodata_outside_single_shape) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_returns_nan_with_nodata_within_shapes( single_shape, spatiotemporal_data_with_nodata_within_single_shape): weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=spatiotemporal_data_with_nodata_within_single_shape) assert pd.isna(weighted_ts).all().all()
def test_not_equal_values(single_shape, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([8, 8, 8, 0]) weighted_ts = area_weighted_time_series(shapes=single_shape, spatiotemporal=spatiotemporal_data) expected_mean = (8 + 8 + 8 + 0) / 4 assert (weighted_ts.iloc[:, 0].values == expected_mean).all()
def test_handles_non_rectangular_data(single_shape, non_rectangular_spatiotemporal_data): weighted_ts = area_weighted_time_series( shapes=single_shape, spatiotemporal=non_rectangular_spatiotemporal_data) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_equal_values(single_shape, make_spatiotemporal_data): spatiotemporal_data = make_spatiotemporal_data([8, 8, 8, 8]) weighted_ts = area_weighted_time_series(shapes=single_shape, spatiotemporal=spatiotemporal_data) assert (weighted_ts.iloc[:, 0].values == 8).all()
def test_handles_reverted_coordinates_gracefully(single_shape, reverted_spatiotemporal_data): area_weighted_time_series( shapes=single_shape, spatiotemporal=reverted_spatiotemporal_data, gridcell_overlap_threshold=DEFAULT_THRESHOLD )
def test_allows_all_crs(single_shape, any_spatiotemporal_data, crs): single_shape = single_shape.set_crs(crs, allow_override=True) any_spatiotemporal_data.attrs["crs"] = crs area_weighted_time_series(shapes=single_shape, spatiotemporal=any_spatiotemporal_data)
def test_fails_without_crs_in_shapes(single_shape, any_spatiotemporal_data): single_shape.crs = None with pytest.raises(AssertionError): area_weighted_time_series(shapes=single_shape, spatiotemporal=any_spatiotemporal_data)
def test_fails_without_crs_in_spatiotemporal(single_shape, any_spatiotemporal_data): del any_spatiotemporal_data.attrs["crs"] with pytest.raises(AssertionError): area_weighted_time_series(shapes=single_shape, spatiotemporal=any_spatiotemporal_data)