CLIMADA-project / climada_python

Python (3.8+) version of CLIMADA
GNU General Public License v3.0
291 stars 115 forks source link

Issues with CRS when using TropCyclone.from_tracks() #879

Closed manniepmkam closed 1 week ago

manniepmkam commented 1 month ago

Describe the bug Error message about cannot determine the common CRS when computing the TC windfield using TropCyclone.from_tracks().

Code example:

from climada.hazard.tc_tracks import TCTracks
from climada.hazard import TropCyclone, Centroids

sel_storm = TCTracks.from_ibtracs_netcdf(storm_id='2017043S19040')
sel_storm.equal_timestep(time_step_h=1)

centroids_sel = Centroids.from_hdf5('centroids_sel.hdf5')

tc_fcast = TropCyclone.from_tracks(sel_storm, centroids_sel)

centroids_sel.hdf5.zip

Error message:

File ~/opt/anaconda3/envs/climada_env/lib/python3.9/site-packages/geopandas/array.py:1493 in _get_common_crs
    raise ValueError(

ValueError: Cannot determine common CRS for concatenation inputs, got ['WGS 84', 'WGS 84']. Use `to_crs()` to transform geometries to the same CRS before merging.

Expected behavior Produce the TC wind field of storm '2017043S19040'

Screenshots If applicable, add screenshots to help explain your problem.

Climada Version: [Version or branch] v4.1.1 - develop

(I'm experiencing issues with exposure and hazards not having a common longitude in the main branch.)

System Information (please complete the following information):

Additional context The same problem also exists on macOS14.3.1

chahank commented 1 month ago

I tried to reproduce the error but was unable to.

Can you please tell me which version of geopandas you are using?

manniepmkam commented 1 month ago

I tried to reproduce the error but was unable to.

Can you please tell me which version of geopandas you are using?

geopandas 0.13.0

chahank commented 1 month ago

Can you please try to update to geopandas 0.14 or higher?

emanuel-schmid commented 1 month ago

That's probably not the issue. I can confirm above behavior on my computer and I'm using geopandas 0.14.2. Still debugging...

chahank commented 1 month ago

Ok, interesting. To be clear, I am using geopanadas 0.14.3.

manniepmkam commented 1 month ago

For me I just install the newest climada_env with geopandas 0.14.4 and it works

emanuel-schmid commented 1 month ago

Glad that this is already solved by an update. Nevertheless we have a minor problem in Hazard.concat when the list of hazards has a single item: even with gepandas 0.14.4 I get an error for the following:

from scipy import sparse
import numpy as np

intensity = sparse.csr_matrix([[0.2, 0.3, 0.4],
                            [0.1, 0.1, 0.01],
                            [4.3, 2.1, 1.0],
                            [5.3, 0.2, 0.0]])

haz = Hazard("TC",
    intensity=intensity,
    centroids=Centroids(
        lat=np.array([1, 3, 5]), lon=np.array([2, 4, 6]),
        crs="epsg:7777"
    ),
    event_id=np.array([1, 2, 3, 4]),
    frequency=np.array([1, 1, 1, 1]),
)
Hazard.concat([haz])

(Without the `crs="epsg:7777" line or with "epsg:4326" it works fine.)

emanuel-schmid commented 1 month ago

Even if we'll abandon support for non standard crs - the fix is very easy. 😃

peanutfun commented 1 month ago

Sorry, I don't understand. What's the issue with "epsg:7777" and what is the easy fix?

emanuel-schmid commented 1 month ago

The issue is that Hazard.concat() creates a blank hazard with an empty Centroids object to start with and then merges the list of hazards into it. The overall centroids is eventually the union of the individual hazards' centroids. That works fine as long as each centroids' CRS is compatible with the default CRS ("epsg:4326") from the empty Centroids object at the beginning. Otherwise it fails.

Now, "epsg:7777" is not compatible with the default CRS, no matter what geopandas version. The CRS from @manniepmkam 's centroids file above is compatible but only starting from geopandas > 0.14.2.

The easy fix is to create the empty Centroids object at the beginning of Hazard.concat() with the CRS from the first hazard of the list.

peanutfun commented 1 month ago

Thanks for the explanation! This sounds indeed like a simple contribution. @manniepmkam would you have the time to provide a pull request?

manniepmkam commented 1 month ago

Thanks for the explanation! This sounds indeed like a simple contribution. @manniepmkam would you have the time to provide a pull request?

Yes I have time this afternoon.

manniepmkam commented 1 month ago

Glad that this is already solved by an update. Nevertheless we have a minor problem in Hazard.concat when the list of hazards has a single item: even with gepandas 0.14.4 I get an error for the following:

from scipy import sparse
import numpy as np

intensity = sparse.csr_matrix([[0.2, 0.3, 0.4],
                            [0.1, 0.1, 0.01],
                            [4.3, 2.1, 1.0],
                            [5.3, 0.2, 0.0]])

haz = Hazard("TC",
    intensity=intensity,
    centroids=Centroids(
        lat=np.array([1, 3, 5]), lon=np.array([2, 4, 6]),
        crs="epsg:7777"
    ),
    event_id=np.array([1, 2, 3, 4]),
    frequency=np.array([1, 1, 1, 1]),
)
Hazard.concat([haz])

(Without the `crs="epsg:7777" line or with "epsg:4326" it works fine.)

I'm a bit confused right now. Just now I'm running this code and I get


  File ~/Documents/ETHZ/PhD/_side_project/climada_debug/debug_haz_crs.py:21
    centroids=Centroids(

TypeError: __init__() got an unexpected keyword argument 'crs'

Seems I cannot initiate a Centroids object with defined crs.

peanutfun commented 1 month ago

@manniepmkam Centroids takes crs as keyword argument, but you have to define the positional lon/lat arguments too: https://github.com/CLIMADA-project/climada_python/blob/ac03762a20f0e174b5548bbca58108761374c090/climada/hazard/centroids/centr.py#L80

The Hazard.__init__ creates a "stub" Centroids object with no coordinates, see https://github.com/CLIMADA-project/climada_python/blob/ac03762a20f0e174b5548bbca58108761374c090/climada/hazard/base.py#L228 for how to do that.

peanutfun commented 1 week ago

Fixed by #881