Skip to content

Commit

Permalink
Merge branch 'master' into pr/hailiangliu89/254
Browse files Browse the repository at this point in the history
  • Loading branch information
FabianHofmann committed Oct 11, 2022
2 parents 95399d5 + bfcecc8 commit c45763f
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 23 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ atlite/version.py
paper
.coverage*
!.coveragerc

# Ignore PyCharm / JetBrains IDE project files
.idea/
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repos:
hooks:
- id: check-yaml
- repo: https://github.com/psf/black
rev: 22.8.0
rev: 22.10.0
hooks:
- id: black
- repo: https://github.com/fsfe/reuse-tool
Expand Down
7 changes: 7 additions & 0 deletions RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ Release Notes
.. Upcoming Release
.. =================
Upcoming Release
================

* Bugfix: For certain time spans, the ERA5 influx data would be incorrectly shifted by 12 hours.
This is now fixed and influx data is **always** shifted by minus 30 minutes.
See `#256 <https://github.com/PyPSA/atlite/issues/256#issuecomment-1271446531>`_ for details.

Version 0.2.9
=============

Expand Down
12 changes: 1 addition & 11 deletions atlite/datasets/era5.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,7 @@ def get_data_influx(retrieval_params):
# Do not show DeprecationWarning from new SolarPosition calculation (#199)
with warnings.catch_warnings():
warnings.simplefilter("ignore", DeprecationWarning)
# Convert dt / time frequency to timedelta and shift solar position by half
# (freqs like ["H","30T"] do not work with pd.to_timedelta(...)
time_shift = (
-1
/ 2
* pd.to_timedelta(
pd.date_range(
"1970-01-01", periods=1, freq=pd.infer_freq(ds["time"])
).freq
)
)
time_shift = pd.to_timedelta("-30 minutes")
sp = SolarPosition(ds, time_shift=time_shift)
sp = sp.rename({v: f"solar_{v}" for v in sp.data_vars})

Expand Down
58 changes: 47 additions & 11 deletions test/test_preparation_and_conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@

# %% Predefine tests for cutout

TIME = "2013-01-01"
BOUNDS = (-4, 56, 1.5, 62)
SARAH_DIR = os.getenv("SARAH_DIR", "/home/vres/climate-data/sarah_v2")
GEBCO_PATH = os.getenv("GEBCO_PATH", "/home/vres/climate-data/GEBCO_2014_2D.nc")


def all_notnull_test(cutout):
"""Test if no nan's in the prepared data occur"""
Expand Down Expand Up @@ -59,7 +64,7 @@ def wrong_recreation(cutout):
Cutout(path=cutout.path, module="somethingelse")


def pv_test(cutout):
def pv_test(cutout, time=TIME):
"""
Test the atlite.Cutout.pv function with different settings. Compare
optimal orientation with flat orientation.
Expand All @@ -76,7 +81,7 @@ def pv_test(cutout):
)

assert production.notnull().all()
assert production.sel(time=TIME + " 00:00") == 0
assert production.sel(time=time + " 00:00") == 0

cells = cutout.grid
cells = cells.assign(regions=["lower"] * 200 + ["upper"] * (len(cells) - 200))
Expand Down Expand Up @@ -105,7 +110,7 @@ def pv_test(cutout):
atlite.resource.solarpanels.CdTe, "latitude_optimal", layout=cap_factor_opt
)

assert production_opt.sel(time=TIME + " 00:00") == 0
assert production_opt.sel(time=time + " 00:00") == 0

assert production_opt.sum() > production.sum()

Expand All @@ -117,7 +122,7 @@ def pv_test(cutout):
trigon_model="other",
)

assert production_other.sel(time=TIME + " 00:00") == 0
assert production_other.sel(time=time + " 00:00") == 0
# should be roughly the same
assert (production_other.sum() / production_opt.sum()).round(0) == 1

Expand All @@ -128,7 +133,7 @@ def pv_test(cutout):
layout=cap_factor_opt,
)

assert production_other.sel(time=TIME + " 00:00") == 0
assert production_other.sel(time=time + " 00:00") == 0
# should be roughly the same
assert (production_other.sum() / production_opt.sum()).round(0) == 1

Expand Down Expand Up @@ -293,12 +298,6 @@ def coefficient_of_performance_test(cutout):
# %% Prepare cutouts to test


TIME = "2013-01-01"
BOUNDS = (-4, 56, 1.5, 62)
SARAH_DIR = os.getenv("SARAH_DIR", "/home/vres/climate-data/sarah_v2")
GEBCO_PATH = os.getenv("GEBCO_PATH", "/home/vres/climate-data/GEBCO_2014_2D.nc")


@pytest.fixture(scope="session")
def cutout_era5(tmp_path_factory):
tmp_path = tmp_path_factory.mktemp("era5")
Expand All @@ -307,6 +306,33 @@ def cutout_era5(tmp_path_factory):
return cutout


@pytest.fixture(scope="session")
def cutout_era5_3h_sampling(tmp_path_factory):
tmp_path = tmp_path_factory.mktemp("era5")
time = [
f"{TIME} 00:00",
f"{TIME} 03:00",
f"{TIME} 06:00",
f"{TIME} 09:00",
f"{TIME} 12:00",
f"{TIME} 15:00",
f"{TIME} 18:00",
f"{TIME} 21:00",
]
cutout = Cutout(path=tmp_path / "era5", module="era5", bounds=BOUNDS, time=time)
cutout.prepare()
return cutout


@pytest.fixture(scope="session")
def cutout_era5_2days_crossing_months(tmp_path_factory):
tmp_path = tmp_path_factory.mktemp("era5")
time = slice("2013-02-28", "2013-03-01")
cutout = Cutout(path=tmp_path / "era5", module="era5", bounds=BOUNDS, time=time)
cutout.prepare()
return cutout


@pytest.fixture(scope="session")
def cutout_era5_coarse(tmp_path_factory):
tmp_path = tmp_path_factory.mktemp("era5_coarse")
Expand Down Expand Up @@ -490,6 +516,16 @@ def test_wrong_loading(cutout_era5):
def test_pv_era5(cutout_era5):
return pv_test(cutout_era5)

@staticmethod
def test_pv_era5_2days_crossing_months(cutout_era5_2days_crossing_months):
"""See https://github.com/PyPSA/atlite/issues/256"""
return pv_test(cutout_era5_2days_crossing_months, time="2013-03-01")

@staticmethod
def test_pv_era5_3h_sampling(cutout_era5_3h_sampling):
assert pd.infer_freq(cutout_era5_3h_sampling.data.time) == "3H"
return pv_test(cutout_era5_3h_sampling)

@staticmethod
def test_wind_era5(cutout_era5):
return wind_test(cutout_era5)
Expand Down

0 comments on commit c45763f

Please sign in to comment.