ai4er-cdt / geograph

GeoGraph provides a tool for analysing habitat fragmentation and related problems in landscape ecology. GeoGraph builds a geospatially referenced graph from land cover or field survey data and enables graph-based landscape ecology analysis as well as interactive visualizations.
https://geograph.readthedocs.io
MIT License
39 stars 10 forks source link

Reliability: Binder Notebooks Currently Don't Run #83

Closed sdat2 closed 1 year ago

sdat2 commented 2 years ago

Hey, I just tried running the first notebook from binder. It broke on the first input with the output below.

As a general point, it would probably be good if there was an automatic test to see if the notebooks run without issue before merges. This would add a general smoke test to the project.

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import rioxarray as rxr
import geopandas as gpd
import pylandstats as pls
from geograph import GeoGraph
from geograph.constants import UTM35N
from geograph.demo.binder_constants import DATA_DIR, ROIS

# Parse geotif landcover data
chernobyl_path = (
    lambda year: DATA_DIR / "chernobyl" / "esa_cci" / f"esa_cci_{year}_chernobyl.tif"
)

# Parse ROIS
rois = gpd.read_file(ROIS)
cez = rois[rois["name"] == "Chernobyl Exclusion Zone"]
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import rioxarray as rxr
import geopandas as gpd
import pylandstats as pls
from geograph import GeoGraph
from geograph.constants import UTM35N
from geograph.demo.binder_constants import DATA_DIR, ROIS
​
# Parse geotif landcover data
chernobyl_path = (
    lambda year: DATA_DIR / "chernobyl" / "esa_cci" / f"esa_cci_{year}_chernobyl.tif"
)
​
# Parse ROIS
rois = gpd.read_file(ROIS)
cez = rois[rois["name"] == "Chernobyl Exclusion Zone"]
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
RuntimeError: module compiled against API version 0x10 but this version of numpy is 0xe
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
Input In [2], in <cell line: 6>()
      4 import rioxarray as rxr
      5 import geopandas as gpd
----> 6 import pylandstats as pls
      7 from geograph import GeoGraph
      8 from geograph.constants import UTM35N

File /srv/conda/envs/notebook/lib/python3.8/site-packages/pylandstats/__init__.py:1, in <module>
----> 1 from .landscape import *
      2 from .spatiotemporal import *
      3 from .zonal import *

File /srv/conda/envs/notebook/lib/python3.8/site-packages/pylandstats/landscape.py:32, in <module>
     27 CELLLENGTH_RTOL = 0.001
     28 KERNEL_MOORE = ndimage.generate_binary_structure(2, 2)
     31 @transonic.boost
---> 32 def compute_adjacency_arr(padded_arr: 'uint32[:,:]', num_classes: 'int'):
     33     # flat-array approach to pixel adjacency from link below:
     34     # https://ilovesymposia.com/2016/12/20/numba-in-the-real-world/
     35     # the first axis of `adjacency_arr` is of fixed size of 2 and serves to
     36     # distinguish between vertical and horizontal adjacencies (we could also
     37     # use a tuple of two 2-D arrays)
     38     # adjacency_arr = np.zeros((2, num_classes + 1, num_classes + 1),
     39     #                          dtype=np.uint32)
     40     num_cols_adjacency = num_classes + 1
     41     horizontal_adjacency_arr = np.zeros(
     42         num_cols_adjacency * num_cols_adjacency, dtype=np.uint32)

File /srv/conda/envs/notebook/lib/python3.8/site-packages/transonic/aheadoftime.py:116, in boost(obj, backend, inline, boundscheck, wraparound, cdivision, nonecheck, nogil)
    113 if backend is not None and not isinstance(backend, str):
    114     raise TypeError
--> 116 ts = _get_transonic_calling_module(backend_name=backend)
    118 decor = ts.boost(
    119     inline=inline,
    120     nogil=nogil,
   (...)
    124     nonecheck=nonecheck,
    125 )
    126 if callable(obj) or isinstance(obj, type):

File /srv/conda/envs/notebook/lib/python3.8/site-packages/transonic/aheadoftime.py:90, in _get_transonic_calling_module(backend_name)
     88         ts = Transonic(frame=frame, reuse=False, backend=backend_name)
     89 else:
---> 90     ts = Transonic(frame=frame, reuse=False, backend=backend_name)
     92 return ts

File /srv/conda/envs/notebook/lib/python3.8/site-packages/transonic/aheadoftime.py:316, in Transonic.__init__(self, use_transonified, frame, reuse, backend)
    313     if path_ext_alt.exists():
    314         self.path_extension = path_ext = path_ext_alt
--> 316 self.reload_module_backend(module_backend_name)
    318 if not self.is_transpiled:
    319     logger.warning(
    320         f"Module {path_mod} has not been compiled for "
    321         f"Transonic-{backend.name_capitalized}"
    322     )

File /srv/conda/envs/notebook/lib/python3.8/site-packages/transonic/aheadoftime.py:344, in Transonic.reload_module_backend(self, module_backend_name)
    342     module_backend_name = self.module_backend.__name__
    343 if self.path_extension.exists() and not self.is_compiling:
--> 344     self.module_backend = import_from_path(
    345         self.path_extension, module_backend_name
    346     )
    347 elif self.path_backend.exists():
    348     self.module_backend = import_from_path(
    349         self.path_backend, module_backend_name
    350     )

File /srv/conda/envs/notebook/lib/python3.8/site-packages/transonic/util.py:360, in import_from_path(path, module_name)
    358 # for potential "local imports" in the module
    359 sys.path.insert(0, str(path.parent))
--> 360 module = importlib.util.module_from_spec(spec)
    361 spec.loader.exec_module(module)
    362 # clean sys.path

ImportError: numpy.core.multiarray failed to import
Croydon-Brixton commented 1 year ago

Adressed in #80