Skip to content

Can't save Impacts when CRS is a pyproj CRS object #706

@ChrisFairless

Description

@ChrisFairless

The Impact.write_hdf5 method fails when the Impact's crs attribute is a pyproj.crs.crs.CRS class.

This is the case when the Impact is created using LitPop exposures from the Data API.

Here is a reproducible example:

from climada.util.api_client import Client
from climada.entity import ImpfTropCyclone, ImpactFuncSet
from climada.engine.impact_calc import ImpactCalc

client = Client()
country = 'KNA'
haz = client.get_hazard('tropical_cyclone', properties={'country_iso3alpha': country, 'climate_scenario': 'rcp45', 'ref_year': '2080'})
exp = client.get_litpop(country)
impf_set = ImpactFuncSet([ImpfTropCyclone.from_emanuel_usa()])
imp = ImpactCalc(exp, impf_set, haz).impact(save_mat=False)
imp.write_hdf5('./deleteme.hdf5')

Giving the error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/chrisfairless/opt/anaconda3/envs/nccs/lib/python3.9/site-packages/climada/engine/impact.py", line 987, in write_hdf5
    write(file, name, value)
  File "/Users/chrisfairless/opt/anaconda3/envs/nccs/lib/python3.9/site-packages/climada/engine/impact.py", line 922, in write
    return writer(group, name, value)
  File "/Users/chrisfairless/opt/anaconda3/envs/nccs/lib/python3.9/site-packages/climada/engine/impact.py", line 934, in write_attribute
    group.attrs[name] = value
  File "h5py/_objects.pyx", line 54, in h5py._objects.with_phil.wrapper
  File "h5py/_objects.pyx", line 55, in h5py._objects.with_phil.wrapper
  File "/Users/chrisfairless/opt/anaconda3/envs/nccs/lib/python3.9/site-packages/h5py/_hl/attrs.py", line 103, in __setitem__
    self.create(name, data=value)
  File "/Users/chrisfairless/opt/anaconda3/envs/nccs/lib/python3.9/site-packages/h5py/_hl/attrs.py", line 180, in create
    htype = h5t.py_create(original_dtype, logical=True)
  File "h5py/h5t.pyx", line 1663, in h5py.h5t.py_create
  File "h5py/h5t.pyx", line 1687, in h5py.h5t.py_create
  File "h5py/h5t.pyx", line 1747, in h5py.h5t.py_create
TypeError: Object dtype dtype('O') has no native HDF5 equivalent

The issue appears to be that there's no specific method for reading and writing the CRS to file. The method falls back on the generic method to write any object write_attribute which fails. It looks like we need a dedicated write_crs method.

In the meantime, users running into the issue can try converting the CRS object into a string before saving, or (in 99% of cases) change it to CLIMADA default:

from climada.util.constants import DEF_CRS
imp.crs = DEF_CRS

Note: Exposures.write_hdf5 doesn't have this issue because it uses a different method to convert.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions