Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aggregated read functionality #87

Merged
merged 18 commits into from Feb 13, 2019
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Expand Up @@ -4,7 +4,7 @@ Changelog
master
------


- (`#87 <https://github.com/openclimatedata/openscm/pull/87>`_) Added aggregated read of parameter
- (`#86 <https://github.com/openclimatedata/openscm/pull/86>`_) Made top level of region explicit, rather than allowing access via ``()`` and made requests robust to string inputs
- (`#92 <https://github.com/openclimatedata/openscm/pull/92>`_) Updated installation to remove notebook dependencies from minimum requirements as discussed in `#90 <https://github.com/openclimatedata/openscm/issues/90>`_
- (`#85 <https://github.com/openclimatedata/openscm/pull/85>`_) Split out submodule for ScmDataFrameBase ``openscm.scmdataframebase`` to avoid circular imports
Expand Down
5 changes: 5 additions & 0 deletions openscm/errors.py
Expand Up @@ -13,6 +13,11 @@ class ParameterReadonlyError(ParameterError):
"""


class ParameterEmptyError(ParameterError):
"""
Exception raised when trying to read when a parameter's value hasn't been set
"""

class ParameterTypeError(ParameterError):
"""
Exception raised when a parameter is of a different type than
Expand Down
24 changes: 24 additions & 0 deletions openscm/parameter_views.py
Expand Up @@ -2,6 +2,7 @@
from .parameters import _Parameter
from .timeframes import Timeframe, TimeframeConverter
from .units import UnitConverter
from .errors import ParameterEmptyError


class ParameterView:
Expand Down Expand Up @@ -111,6 +112,29 @@ def get_series(self) -> Sequence[float]:
"""
Get values of the full timeseries.
"""
if self.is_empty:
if not self._parameter._children:
raise ParameterEmptyError

def get_child_data(para):
# where should this go?
znicholls marked this conversation as resolved.
Show resolved Hide resolved
for name, cp in para._children.items():
znicholls marked this conversation as resolved.
Show resolved Hide resolved
if not cp._children:
data_to_add = cp._data
else:
data_to_add = get_child_data(cp)
data_to_add = self._timeframe_converter.convert_from(
self._unit_converter.convert_from(data_to_add)
)
try:
data += data_to_add
except NameError:
data = data_to_add

return data

self._parameter._data = get_child_data(self._parameter)

return self._timeframe_converter.convert_from(
self._unit_converter.convert_from(self._parameter._data)
)
Expand Down
58 changes: 58 additions & 0 deletions tests/unit/test_core.py
Expand Up @@ -9,6 +9,7 @@
ParameterReadError,
ParameterReadonlyError,
ParameterTypeError,
ParameterEmptyError,
ParameterWrittenError,
RegionAggregatedError,
)
Expand Down Expand Up @@ -194,6 +195,10 @@ def test_timeseries_parameter_view(core, start_time, series):
carbon = parameterset.get_timeseries_view(
("Emissions", "CO2"), ("World"), "GtCO2/a", start_time, 365 * 24 * 3600
)
assert carbon.is_empty
with pytest.raises(ParameterEmptyError):
carbon.get_series()

carbon_writable = parameterset.get_writable_timeseries_view(
("Emissions", "CO2"), ("World"), "ktC/d", start_time, 24 * 3600
)
Expand All @@ -208,3 +213,56 @@ def test_timeseries_parameter_view(core, start_time, series):
parameterset.get_scalar_view(("Emissions", "CO2"), ("World",), "GtCO2/a")
with pytest.raises(DimensionalityError):
parameterset.get_timeseries_view(("Emissions", "CO2"), ("World",), "kg", 0, 1)


def test_timeseries_parameter_view_aggregation(core, start_time):
fossil_industry_emms = np.array([0, 1, 2])
fossil_energy_emms = np.array([2, 1, 4])
land_emms = np.array([0.05, 0.1, 0.2])

parameterset = core.parameters

fossil_industry_writable = parameterset.get_writable_timeseries_view(
("Emissions", "CO2", "Fossil", "Industry"), ("World"), "GtC/yr", start_time, 24 * 3600
)
fossil_industry_writable.set_series(fossil_industry_emms)

fossil_energy_writable = parameterset.get_writable_timeseries_view(
("Emissions", "CO2", "Fossil", "Energy"), ("World"), "GtC/yr", start_time, 24 * 3600
)
fossil_energy_writable.set_series(fossil_energy_emms)

land_writable = parameterset.get_writable_timeseries_view(
("Emissions", "CO2", "Land"), ("World"), "GtC/yr", start_time, 24 * 3600
)
land_writable.set_series(land_emms)

fossil_industry = parameterset.get_timeseries_view(
("Emissions", "CO2", "Fossil", "Industry"), ("World"), "GtC/yr", start_time, 24 * 3600
)
np.testing.assert_allclose(fossil_industry.get_series(), fossil_industry_emms)

fossil_energy = parameterset.get_timeseries_view(
("Emissions", "CO2", "Fossil", "Energy"), ("World"), "GtC/yr", start_time, 24 * 3600
)
np.testing.assert_allclose(fossil_energy.get_series(), fossil_energy_emms)

fossil = parameterset.get_timeseries_view(
("Emissions", "CO2", "Fossil"), ("World"), "GtC/yr", start_time, 24 * 3600
)
np.testing.assert_allclose(fossil.get_series(), fossil_industry_emms + fossil_energy_emms)

land = parameterset.get_timeseries_view(
("Emissions", "CO2", "Land"), ("World"), "GtC/yr", start_time, 24 * 3600
)
np.testing.assert_allclose(land.get_series(), land_emms)

with pytest.raises(ParameterReadonlyError):
parameterset.get_writable_timeseries_view(
("Emissions", "CO2"), ("World"), "GtC/yr", start_time, 24 * 3600
)

total = parameterset.get_timeseries_view(
("Emissions", "CO2"), ("World"), "GtC/yr", start_time, 24 * 3600
)
np.testing.assert_allclose(total.get_series(), land_emms + fossil_energy_emms + fossil_industry_emms)