diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..db90f55 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,257 @@ +name: ci + +on: + pull_request: + push: + branches: + - master + tags-ignore: + - "v*" + - "test-v*" + +jobs: + tox_tests: + name: Tox tests (ubuntu, py${{ matrix.py }}) + runs-on: ubuntu-latest + env: + OCEANMESH_REQUIRE_INPOLY_ACCEL: "1" + OCEANMESH_INPOLY_ACCEL_DEBUG: "1" + OCEANMESH_INPOLY_ACCEL: "1" + OCEANMESH_INPOLY_METHOD: "" + strategy: + fail-fast: false + matrix: + include: + - py: "310" + python-version: "3.10" + toxenv: "py310" + - py: "311" + python-version: "3.11" + toxenv: "py311" + - py: "312" + python-version: "3.12" + toxenv: "py312" + - py: "313" + python-version: "3.13" + toxenv: "py313" + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install system build deps + run: | + sudo apt-get update + sudo apt-get install -y \ + libgmp-dev \ + libmpfr-dev \ + libcgal-dev \ + libopenmpi3 \ + libopenmpi-dev \ + openmpi-bin \ + libhdf5-dev + + - name: Install Python build dependencies + run: | + python -m pip install --upgrade pip + python -m pip install Cython numpy + + - name: Verify Cython inpoly kernel is available + env: + OCEANMESH_INPOLY_ACCEL: "1" + run: | + python -m pip install -e . + python - << 'PY' + import os, importlib + from oceanmesh.geometry import point_in_polygon as pip + + os.environ.pop("OCEANMESH_INPOLY_METHOD", None) + os.environ["OCEANMESH_INPOLY_ACCEL"] = "1" + pip = importlib.reload(pip) + + if not getattr(pip, "_COMPILED_KERNEL_AVAILABLE", False): + raise SystemExit("Cython inpoly2 kernel not available in CI environment") + + print("_COMPILED_KERNEL_AVAILABLE =", pip._COMPILED_KERNEL_AVAILABLE) + from oceanmesh.geometry.point_in_polygon_ import inpoly2_fast + print("inpoly2_fast:", inpoly2_fast) + PY + + - name: Install tox + run: | + python -m pip install tox + + - name: Run tests + run: | + tox -e "${{ matrix.toxenv }}" -- -q + + build_wheels: + name: Build wheels (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + python -m pip install cibuildwheel==2.* + + # Build dependencies (CGAL headers + GMP/MPFR libs) into a local prefix via micromamba. + # The wheel build will link against these, and repair tools will bundle the runtime libs. + - name: Install micromamba (Unix) + if: runner.os != 'Windows' + shell: bash + run: | + set -euxo pipefail + if [ "${RUNNER_OS}" = "macOS" ]; then + if [ "$(uname -m)" = "arm64" ]; then + MAMBA_PLATFORM="osx-arm64" + else + MAMBA_PLATFORM="osx-64" + fi + else + MAMBA_PLATFORM="linux-64" + fi + + curl -Ls "https://micro.mamba.pm/api/micromamba/${MAMBA_PLATFORM}/latest" -o micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 bin/micromamba + sudo mv bin/micromamba /usr/local/bin/micromamba + + - name: Install micromamba (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + Invoke-WebRequest -Uri "https://micro.mamba.pm/api/micromamba/win-64/latest" -OutFile micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 + echo "${PWD}\\Library\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Build wheels + env: + # Use a local prefix so setup.py can find include/lib without relying on system installs. + # cibuildwheel will run these on the build machine (and inside manylinux containers on Linux). + CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux_2_34_x86_64:2025.04.19-1 + CIBW_ENVIRONMENT: "OCEANMESH_PREFIX=/opt/om" + CIBW_ENVIRONMENT_MACOS: "OCEANMESH_PREFIX=$HOME/om" + CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel -v show {wheel} && auditwheel repair -w {dest_dir} {wheel}" + CIBW_BEFORE_ALL_LINUX: | + set -eux + curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest -o micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 bin/micromamba + mv bin/micromamba /usr/local/bin/micromamba + micromamba create -y -p /opt/om -c conda-forge \ + cgal boost-cpp gmp mpfr eigen + CIBW_BEFORE_ALL_MACOS: | + set -eux + micromamba create -y -p "$HOME/om" -c conda-forge \ + cgal boost-cpp gmp mpfr eigen + CIBW_BEFORE_ALL_WINDOWS: | + micromamba create -y -p C:\\om -c conda-forge cgal boost-cpp gmp mpfr eigen + CIBW_ENVIRONMENT_WINDOWS: "OCEANMESH_PREFIX=C:\\om" + # Repair wheels to bundle shared libs. + CIBW_REPAIR_WHEEL_COMMAND_MACOS: "python -m pip install delocate && delocate-wheel -w {dest_dir} -v {wheel}" + CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "python -m pip install delvewheel && delvewheel repair -w {dest_dir} {wheel}" + run: | + python -m cibuildwheel --output-dir dist + + - name: Upload wheel artifacts + uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: dist/*.whl + + build_sdist: + name: Build sdist + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Build sdist + run: | + python -m pip install --upgrade pip + python -m pip install build + python -m build --sdist + - name: Upload sdist artifact + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist/*.tar.gz + + smoke_test: + name: Smoke test install (${{ matrix.os }}) + needs: [build_wheels] + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Download wheel artifacts + uses: actions/download-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: dist + + - name: Install wheel into fresh venv and import + shell: bash + run: | + set -euxo pipefail + python -m venv .venv + if [ -f .venv/bin/activate ]; then + source .venv/bin/activate + else + source .venv/Scripts/activate + fi + + python -m pip install --upgrade pip packaging + + python - <<'PY' + import glob + import os + import sys + import subprocess + + from packaging import tags + from packaging.utils import parse_wheel_filename + + wheels = sorted(glob.glob(os.path.join("dist", "*.whl"))) + if not wheels: + raise SystemExit("No wheels found in dist/") + + supported = set(tags.sys_tags()) + + def is_compatible(wheel_path: str) -> bool: + _, _, _, wheel_tags = parse_wheel_filename(os.path.basename(wheel_path)) + return any(t in supported for t in wheel_tags) + + selected = next((w for w in wheels if is_compatible(w)), None) + if not selected: + raise SystemExit(f"No compatible wheel found. Found wheels: {wheels}") + + print(f"Selected wheel: {selected}") + subprocess.check_call([sys.executable, "-m", "pip", "install", selected]) + PY + + python -c "import oceanmesh; print(oceanmesh.__version__)" + python -c "import oceanmesh; oceanmesh.Region((0, 1, 0, 1), 'EPSG:4326'); print('ok')" diff --git a/.github/workflows/publish-testpypi.yml b/.github/workflows/publish-testpypi.yml new file mode 100644 index 0000000..6493b32 --- /dev/null +++ b/.github/workflows/publish-testpypi.yml @@ -0,0 +1,202 @@ +name: publish-testpypi + +on: + workflow_dispatch: + push: + tags: + - "test-v*" + +jobs: + build_wheels: + name: Build wheels (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + python -m pip install cibuildwheel==2.* + + # Build dependencies (CGAL headers + GMP/MPFR libs) into a local prefix via micromamba. + # The wheel build will link against these, and repair tools will bundle the runtime libs. + - name: Install micromamba (Unix) + if: runner.os != 'Windows' + shell: bash + run: | + set -euxo pipefail + if [ "${RUNNER_OS}" = "macOS" ]; then + if [ "$(uname -m)" = "arm64" ]; then + MAMBA_PLATFORM="osx-arm64" + else + MAMBA_PLATFORM="osx-64" + fi + else + MAMBA_PLATFORM="linux-64" + fi + + curl -Ls "https://micro.mamba.pm/api/micromamba/${MAMBA_PLATFORM}/latest" -o micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 bin/micromamba + sudo mv bin/micromamba /usr/local/bin/micromamba + + - name: Install micromamba (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + Invoke-WebRequest -Uri "https://micro.mamba.pm/api/micromamba/win-64/latest" -OutFile micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 + echo "${PWD}\\Library\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Build wheels + env: + # Use a local prefix so setup.py can find include/lib without relying on system installs. + # cibuildwheel will run these on the build machine (and inside manylinux containers on Linux). + CIBW_MANYLINUX_X86_64_IMAGE: quay.io/pypa/manylinux_2_34_x86_64:2025.04.19-1 + CIBW_ENVIRONMENT: "OCEANMESH_PREFIX=/opt/om" + CIBW_ENVIRONMENT_MACOS: "OCEANMESH_PREFIX=$HOME/om" + CIBW_REPAIR_WHEEL_COMMAND_LINUX: "auditwheel -v show {wheel} && auditwheel repair -w {dest_dir} {wheel}" + CIBW_BEFORE_ALL_LINUX: | + set -eux + curl -Ls https://micro.mamba.pm/api/micromamba/linux-64/latest -o micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 bin/micromamba + mv bin/micromamba /usr/local/bin/micromamba + micromamba create -y -p /opt/om -c conda-forge \ + cgal boost-cpp gmp mpfr eigen + CIBW_BEFORE_ALL_MACOS: | + set -eux + micromamba create -y -p "$HOME/om" -c conda-forge \ + cgal boost-cpp gmp mpfr eigen + CIBW_BEFORE_ALL_WINDOWS: | + micromamba create -y -p C:\\om -c conda-forge cgal boost-cpp gmp mpfr eigen + CIBW_ENVIRONMENT_WINDOWS: "OCEANMESH_PREFIX=C:\\om" + # Repair wheels to bundle shared libs. + CIBW_REPAIR_WHEEL_COMMAND_MACOS: "python -m pip install delocate && delocate-wheel -w {dest_dir} -v {wheel}" + CIBW_REPAIR_WHEEL_COMMAND_WINDOWS: "python -m pip install delvewheel && delvewheel repair -w {dest_dir} {wheel}" + run: | + python -m cibuildwheel --output-dir dist + + - name: Upload wheel artifacts + uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: dist/*.whl + + smoke_test: + name: Smoke test install (${{ matrix.os }}) + needs: [build_wheels] + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Download wheel artifacts + uses: actions/download-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: dist + + - name: Install wheel into fresh venv and import + shell: bash + run: | + set -euxo pipefail + python -m venv .venv + if [ -f .venv/bin/activate ]; then + source .venv/bin/activate + else + source .venv/Scripts/activate + fi + + python -m pip install --upgrade pip packaging + + python - <<'PY' + import glob + import os + import sys + import subprocess + + from packaging import tags + from packaging.utils import parse_wheel_filename + + wheels = sorted(glob.glob(os.path.join("dist", "*.whl"))) + if not wheels: + raise SystemExit("No wheels found in dist/") + + supported = set(tags.sys_tags()) + + def is_compatible(wheel_path: str) -> bool: + _, _, _, wheel_tags = parse_wheel_filename(os.path.basename(wheel_path)) + return any(t in supported for t in wheel_tags) + + selected = next((w for w in wheels if is_compatible(w)), None) + if not selected: + raise SystemExit(f"No compatible wheel found. Found wheels: {wheels}") + + print(f"Selected wheel: {selected}") + subprocess.check_call([sys.executable, "-m", "pip", "install", selected]) + PY + + python -c "import oceanmesh; print(oceanmesh.__version__)" + python -c "import oceanmesh; oceanmesh.Region((0, 1, 0, 1), 'EPSG:4326'); print('ok')" + + build_sdist: + name: Build sdist + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Build sdist + run: | + python -m pip install --upgrade pip + python -m pip install build + python -m build --sdist + - name: Upload sdist artifact + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist/*.tar.gz + + publish_testpypi: + name: Publish to TestPyPI + needs: [build_wheels, build_sdist, smoke_test] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: dist + + - name: Flatten dist directory + shell: bash + run: | + set -eux + mkdir -p upload + find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -maxdepth 3 -print -exec cp {} upload/ \; + + - name: Publish + uses: pypa/gh-action-pypi-publish@release/v1 + with: + repository-url: https://test.pypi.org/legacy/ + packages-dir: upload + skip-existing: true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..eb5f0ff --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,144 @@ +name: publish + +on: + push: + tags: + - "v*" + +jobs: + guard_tag_on_default_branch: + name: "Guard: tag commit on default branch" + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Verify tag commit is reachable from default branch + shell: bash + env: + DEFAULT_BRANCH: ${{ github.event.repository.default_branch }} + run: | + set -euxo pipefail + echo "Default branch: ${DEFAULT_BRANCH}" + git fetch origin "${DEFAULT_BRANCH}" --tags + git merge-base --is-ancestor "${GITHUB_SHA}" "origin/${DEFAULT_BRANCH}" + + build_wheels: + name: Build wheels (${{ matrix.os }}) + needs: [guard_tag_on_default_branch] + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest] + + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Install build tooling + run: | + python -m pip install --upgrade pip + python -m pip install cibuildwheel==2.* + + # Build dependencies (CGAL headers + GMP/MPFR libs) into a local prefix via micromamba. + # The wheel build will link against these, and repair tools will bundle the runtime libs. + - name: Install micromamba (Unix) + if: runner.os != 'Windows' + shell: bash + run: | + set -euxo pipefail + if [ "${RUNNER_OS}" = "macOS" ]; then + if [ "$(uname -m)" = "arm64" ]; then + MAMBA_PLATFORM="osx-arm64" + else + MAMBA_PLATFORM="osx-64" + fi + else + MAMBA_PLATFORM="linux-64" + fi + + curl -Ls "https://micro.mamba.pm/api/micromamba/${MAMBA_PLATFORM}/latest" -o micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 bin/micromamba + sudo mv bin/micromamba /usr/local/bin/micromamba + + - name: Install micromamba (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + Invoke-WebRequest -Uri "https://micro.mamba.pm/api/micromamba/win-64/latest" -OutFile micromamba.tar.bz2 + tar -xjf micromamba.tar.bz2 + echo "${PWD}\\Library\\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Build wheels + env: + # Use a local prefix so setup.py can find include/lib without relying on system installs. + # cibuildwheel will run these on the build machine (and inside manylinux containers on Linux). + CIBW_ENVIRONMENT_MACOS: "OCEANMESH_PREFIX=$HOME/om" + CIBW_BEFORE_ALL_MACOS: | + set -eux + micromamba create -y -p "$HOME/om" -c conda-forge \ + cgal boost-cpp gmp mpfr eigen + # Repair wheels to bundle shared libs. + CIBW_REPAIR_WHEEL_COMMAND_MACOS: "python -m pip install delocate && delocate-wheel -w {dest_dir} -v {wheel}" + run: | + python -m cibuildwheel --output-dir dist + + - name: Upload wheel artifacts + uses: actions/upload-artifact@v4 + with: + name: wheels-${{ matrix.os }} + path: dist/*.whl + + build_sdist: + name: Build sdist + needs: [guard_tag_on_default_branch] + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Build sdist + run: | + python -m pip install --upgrade pip + python -m pip install build + python -m build --sdist + - name: Upload sdist artifact + uses: actions/upload-artifact@v4 + with: + name: sdist + path: dist/*.tar.gz + + publish_pypi: + name: Publish to PyPI + needs: [guard_tag_on_default_branch, build_wheels, build_sdist] + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: dist + + - name: Flatten dist directory + shell: bash + run: | + set -eux + mkdir -p upload + find dist -type f \( -name "*.whl" -o -name "*.tar.gz" \) -maxdepth 3 -print -exec cp {} upload/ \; + + - name: Publish + uses: pypa/gh-action-pypi-publish@release/v1 + with: + packages-dir: upload + skip-existing: true diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml deleted file mode 100644 index 4eec5de..0000000 --- a/.github/workflows/testing.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: ci - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - lint: - runs-on: ubuntu-latest - steps: - - uses: actions/setup-python@v2 - with: - python-version: "3.12" - - uses: actions/checkout@v2 - - name: Lint with flake8 - run: | - pip install flake8 - flake8 . - - name: Lint with black - run: | - pip install black - black --check . - build: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - python-version: ['3.10','3.11','3.12','3.13'] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Update - run: | - sudo apt update - - name: Install CGAL 5 - run: | - sudo apt install -y libcgal-dev - - name: Install other dependencies - run: | - sudo apt install -y libopenmpi3 libopenmpi-dev openmpi-bin - sudo apt install -y libhdf5-dev - - name: Install Python build dependencies - run: | - python -m pip install --upgrade pip - python -m pip install Cython numpy - - name: Verify Cython inpoly kernel is available - env: - OCEANMESH_INPOLY_ACCEL: "1" - run: | - python -m pip install -e . - python - << 'PY' - import os, importlib - from oceanmesh.geometry import point_in_polygon as pip - - # Ensure we use the default acceleration behaviour - os.environ.pop("OCEANMESH_INPOLY_METHOD", None) - os.environ["OCEANMESH_INPOLY_ACCEL"] = "1" - pip = importlib.reload(pip) - - if not getattr(pip, "_COMPILED_KERNEL_AVAILABLE", False): - raise SystemExit("Cython inpoly2 kernel not available in CI environment") - - print("_COMPILED_KERNEL_AVAILABLE =", pip._COMPILED_KERNEL_AVAILABLE) - from oceanmesh.geometry.point_in_polygon_ import inpoly2_fast - print("inpoly2_fast:", inpoly2_fast) - PY - - name: Test with tox - env: - OCEANMESH_INPOLY_ACCEL: "1" - OCEANMESH_INPOLY_METHOD: "" - run: | - python -m pip install tox - tox - - uses: codecov/codecov-action@v1 diff --git a/.gitignore b/.gitignore index 084a398..4dda6ad 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ build/ tests/*.txt *.zip tests/gshhg-shp-2.3.7/ - +.gitignore diff --git a/README.md b/README.md index 2f08b78..19dc757 100644 --- a/README.md +++ b/README.md @@ -96,7 +96,7 @@ points, cells = om.delete_boundary_faces(points, cells, min_qual=0.15) ## 3. Installation -:warning: Active development. Installation is currently recommended for developers. A stable API will be published to PyPI later. +:warning: OceanMesh 1.0 provides a stable public API, but the project is still under active development. Check the release notes for details of any breaking changes between minor versions. The notes below refer to installation on platforms other than MS Windows. For Windows, see 3.2. @@ -115,12 +115,14 @@ CGAL can also be installed with conda: conda install -c conda-forge cgal ``` -After that, clone the repo and install/update with pip: +After that, install or update OceanMesh with pip (recommended for most users): ```bash -pip install -U -e . +pip install -U oceanmesh ``` +Prebuilt wheels are available for Apple Silicon (M1+) via `pip`. + On some clusters/HPC in order to install CGAL, you may need to load/install [gmp](https://gmplib.org/) and [mpfr](https://www.mpfr.org/). For example: ```bash @@ -407,26 +409,182 @@ Areas of finer refinement can be incorporated seamlessly by using `generate_mult ```python -import numpy as np -import matplotlib.tri as tri import matplotlib.gridspec as gridspec +import matplotlib.pyplot as plt +import matplotlib.tri as tri +import numpy as np + import oceanmesh as om fname = "gshhg-shp-2.3.7/GSHHS_shp/f/GSHHS_f_L1.shp" -extent1 = om.Region(extent=(-75.00, -70.001, 40.0001, 41.9000), crs=4326) -extent2 = om.Region(extent=np.array([[-73.95, 40.60], [-73.72, 40.65], [-73.95, 40.60]]), crs=4326) -s1 = om.Shoreline(fname, extent1.bbox, 0.01) -s2 = om.Shoreline(fname, extent2.bbox, 4.6e-4) -sdf1, sdf2 = om.signed_distance_function(s1), om.signed_distance_function(s2) -el1, el2 = om.distance_sizing_function(s1, max_edge_length=0.05), om.distance_sizing_function(s2) -points, cells = om.generate_multiscale_mesh([sdf1, sdf2], [el1, el2]) +EPSG = 4326 # EPSG:4326 or WGS84 +extent1 = om.Region(extent=(-75.00, -70.001, 40.0001, 41.9000), crs=EPSG) +min_edge_length1 = 0.01 # minimum mesh size in domain in projection +bbox2 = np.array( + [ + [-73.9481, 40.6028], + [-74.0186, 40.5688], + [-73.9366, 40.5362], + [-73.7269, 40.5626], + [-73.7231, 40.6459], + [-73.8242, 40.6758], + [-73.9481, 40.6028], + ], + dtype=float, +) +extent2 = om.Region(extent=bbox2, crs=EPSG) +min_edge_length2 = 4.6e-4 # minimum mesh size in domain in projection +s1 = om.Shoreline(fname, extent1.bbox, min_edge_length1) +sdf1 = om.signed_distance_function(s1) +el1 = om.distance_sizing_function(s1, max_edge_length=0.05) +s2 = om.Shoreline(fname, extent2.bbox, min_edge_length2) +sdf2 = om.signed_distance_function(s2) +el2 = om.distance_sizing_function(s2) +# Control the element size transition +# from coarse to fine with the kwargs prefixed with `blend` +points, cells = om.generate_multiscale_mesh( + [sdf1, sdf2], + [el1, el2], +) +# Remove degenerate mesh faces and other common problems in the mesh +points, cells = om.make_mesh_boundaries_traversable(points, cells) +# Remove singly connected elements (elements connected to only one other element) +points, cells = om.delete_faces_connected_to_one_face(points, cells) +# Remove poor boundary elements with quality < 15% +points, cells = om.delete_boundary_faces(points, cells, min_qual=0.15) +# Apply a Laplacian smoother that preservers the mesh size distribution +points, cells = om.laplacian2(points, cells) + +# Plot it showing the different levels of resolution +triang = tri.Triangulation(points[:, 0], points[:, 1], cells) +gs = gridspec.GridSpec(2, 2) +gs.update(wspace=0.5) +plt.figure() + +bbox3 = np.array( + [ + [-73.78, 40.60], + [-73.75, 40.60], + [-73.75, 40.64], + [-73.78, 40.64], + [-73.78, 40.60], + ], + dtype=float, +) + +ax = plt.subplot(gs[0, 0]) +ax.set_aspect("equal") +ax.triplot(triang, "-", lw=1) +ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") +ax.plot(bbox3[:, 0], bbox3[:, 1], "m--") + +ax = plt.subplot(gs[0, 1]) +ax.set_aspect("equal") +ax.triplot(triang, "-", lw=1) +ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") +ax.set_xlim(np.amin(bbox2[:, 0]), np.amax(bbox2[:, 0])) +ax.set_ylim(np.amin(bbox2[:, 1]), np.amax(bbox2[:, 1])) +ax.plot(bbox3[:, 0], bbox3[:, 1], "m--") + +ax = plt.subplot(gs[1, :]) +ax.set_aspect("equal") +ax.triplot(triang, "-", lw=1) +ax.set_xlim(-73.78, -73.75) +ax.set_ylim(40.60, 40.64) +plt.show() ``` ![Multiscale](docs/images/multiscale_trimmed.png) ### 6.2 Global and Multiscale Meshing -Global meshes are defined in WGS84 but meshed in a stereographic projection. Regional refinement can be added as additional domains. +Global meshes are defined in EPSG:4326 but meshed in a stereographic projection. Regional refinement can be added as additional domains. + +#### Global mesh generation (two-step: EPSG:4326 sizing → stereographic meshing) + +Global mesh generation is done in two steps: + +1. Define the shoreline and sizing functions in EPSG:4326. +2. Generate the mesh in a stereographic projection using a stereographic coastline. + +The repository includes example global shoreline shapefiles under `tests/global/`: + +- `tests/global/global_latlon.shp`: shoreline in EPSG:4326 (lon/lat) +- `tests/global/global_stereo.shp`: shoreline already transformed for stereographic meshing + +Note: `global_stereo.shp` can be produced using `global_tag()` in pyPoseidon: +https://github.com/ec-jrc/pyPoseidon/blob/9cfd3bbf5598c810004def83b1f43dc5149addd0/pyposeidon/boundary.py#L452 + + + +```python +import numpy as np +import oceanmesh as om +from oceanmesh.region import to_lat_lon +import matplotlib.pyplot as plt + + +def crosses_dateline(lon1, lon2): + return abs(lon1 - lon2) > 180 + + +def filter_triangles(points_lonlat, cells): + """Drop triangles that cross the dateline to avoid plot artifacts.""" + filtered = [] + for cell in cells: + p1, p2, p3 = ( + points_lonlat[cell[0]], + points_lonlat[cell[1]], + points_lonlat[cell[2]], + ) + if not ( + crosses_dateline(p1[0], p2[0]) + or crosses_dateline(p2[0], p3[0]) + or crosses_dateline(p3[0], p1[0]) + ): + filtered.append(cell) + return filtered + + +# WGS84 shoreline and stereographic shoreline +fname_wgs84 = "tests/global/global_latlon.shp" +fname_stereo = "tests/global/global_stereo.shp" + +extent = om.Region(extent=(-180.0, 180.0, -89.0, 90.0), crs=4326) + +# 1) Define sizing functions in WGS84 +min_edge_length = 0.5 +shoreline = om.Shoreline(fname_wgs84, extent.bbox, min_edge_length) +edge_length = om.distance_sizing_function(shoreline, rate=0.11) + +# 2) Mesh in stereographic projection using a stereographic shoreline +shoreline_stereo = om.Shoreline(fname_stereo, extent.bbox, min_edge_length, stereo=True) +domain = om.signed_distance_function(shoreline_stereo) + +points, cells = om.generate_mesh(domain, edge_length, stereo=True, max_iter=100) + +# Clean up and smooth +points, cells = om.make_mesh_boundaries_traversable(points, cells) +points, cells = om.delete_faces_connected_to_one_face(points, cells) +points, cells = om.laplacian2(points, cells, max_iter=100) + +# Convert back to lon/lat for plotting +lon, lat = to_lat_lon(points[:, 0], points[:, 1]) +tri_cells = filter_triangles(np.array([lon, lat]).T, cells) + +fig, ax, pc = edge_length.plot( + holding=True, + plot_colorbar=True, + cbarlabel="Resolution in °", + cmap="magma", +) +ax.triplot(lon, lat, tri_cells, color="w", linewidth=0.25) +plt.tight_layout() +plt.show() +``` + +![Global](docs/images/global_mesh_v1.png) + @@ -477,22 +635,9 @@ points, cells = om.generate_multiscale_mesh( ``` ![Global Regional Multiscale](docs/images/test_global_regional_multiscale.png) -*The image shows the global mesh with a refined Australia region.* - - +*The image shows the global mesh with a refined Australia region. -```python -# Global mesh generation only (stereographic meshing) -import oceanmesh as om -from oceanmesh.region import to_lat_lon -fname = "tests/global/global_latlon.shp" -fname2 = "tests/global/global_stereo.shp" -region = om.Region(extent=(-180.00, 180.00, -89.00, 90.00), crs=4326) -shore = om.Shoreline(fname, region.bbox, 0.5) -edge = om.distance_sizing_function(shore, rate=0.11) -domain = om.signed_distance_function(om.Shoreline(fname2, region.bbox, 0.5, stereo=True)) -points, cells = om.generate_mesh(domain, edge, stereo=True, max_iter=100) -``` +See the tests in the `tests/` folder for more inspiration; work is ongoing on this package. [Back to top](#table-of-contents) diff --git a/docs/images/global_mesh_v1.png b/docs/images/global_mesh_v1.png new file mode 100644 index 0000000..63fc288 Binary files /dev/null and b/docs/images/global_mesh_v1.png differ diff --git a/oceanmesh/geodata.py b/oceanmesh/geodata.py index c98cfc3..67b3da1 100644 --- a/oceanmesh/geodata.py +++ b/oceanmesh/geodata.py @@ -29,6 +29,350 @@ __all__ = ["Shoreline", "DEM", "get_polygon_coordinates", "create_circle_coords"] +def _bbox_overlaps_bounds(bbox_vals, bounds): + xmin, xmax, ymin, ymax = bbox_vals + ixmin = max(xmin, bounds.left) + ixmax = min(xmax, bounds.right) + iymin = max(ymin, bounds.bottom) + iymax = min(ymax, bounds.top) + return (ixmin < ixmax) and (iymin < iymax) + + +def _transform_bbox_to_src(bbox_vals, src_crs, dst_crs): + if src_crs is None or dst_crs is None or src_crs == dst_crs: + return bbox_vals + + from pyproj import Transformer + + xmin, xmax, ymin, ymax = bbox_vals + transformer = Transformer.from_crs(dst_crs, src_crs, always_xy=True) + xs, ys = transformer.transform([xmin, xmax], [ymin, ymax]) + return (min(xs), max(xs), min(ys), max(ys)) + + +def _prepare_region_bbox_and_crs(bbox, crs): + region = None + region_crs = None + region_bbox = None + + if bbox is not None: + assert isinstance(bbox, Region), "bbox must be a Region class object" + region = bbox + region_crs = region.crs + region_bbox = region.total_bounds + if crs != "EPSG:4326": + logger.warning( + "DEM: Both a Region object and an explicit 'crs' were provided; the Region's CRS will take precedence (crs=%s).", + region_crs, + ) + crs = CRS.from_user_input(region_crs).to_string() + bbox = region_bbox + + return bbox, crs, region, region_crs, region_bbox + + +def _pick_netcdf_open_target(dem_path, bbox_vals, crs_str): + """Choose a stable rasterio open target for NetCDF inputs. + + GDAL NetCDF subdataset ordering differs across builds/wheels. Prefer a + subdataset whose bounds overlap the requested bbox, otherwise choose the + largest-area subdataset. + """ + + if dem_path.suffix.lower() not in {".nc", ".nc4"}: + return dem_path + + try: + with rasterio.open(dem_path) as container: + subdatasets = list(getattr(container, "subdatasets", []) or []) + except Exception: + return dem_path + + if not subdatasets: + return dem_path + + desired_bbox = None + desired_crs = None + if bbox_vals is not None: + desired_bbox = tuple(map(float, bbox_vals)) + desired_crs = CRS.from_user_input(crs_str) + + best = None + best_area = -1.0 + + for sd in subdatasets: + try: + with rasterio.open(sd) as src: + if src.width <= 1 or src.height <= 1: + continue + b = src.bounds + if not np.isfinite([b.left, b.right, b.bottom, b.top]).all(): + continue + + area = float((b.right - b.left) * (b.top - b.bottom)) + + if desired_bbox is not None and desired_crs is not None: + bbox_in_sd = desired_bbox + if src.crs is not None and src.crs != desired_crs: + try: + bbox_in_sd = _transform_bbox_to_src( + desired_bbox, src.crs, desired_crs + ) + except Exception: + bbox_in_sd = None + + if bbox_in_sd is not None and _bbox_overlaps_bounds(bbox_in_sd, b): + if area > best_area: + best = sd + best_area = area + continue + + if area > best_area: + best = sd + best_area = area + except Exception: + continue + + return best or dem_path + + +def _xr_open_dataset(path): + try: + import xarray as xr + except Exception: + return None + + try: + return xr.open_dataset(path) + except Exception: + return None + + +def _xr_pick_first_raster_data_array(ds): + for name, var in ds.data_vars.items(): + if getattr(var, "ndim", 0) >= 2: + return ds[name] + return None + + +def _xr_reduce_to_2d(da): + while getattr(da, "ndim", 0) > 2: + da = da.isel({da.dims[0]: 0}) + return da + + +def _xr_pick_coord_name(ds, da, candidates): + for candidate in candidates: + if candidate in da.coords: + return candidate + if candidate in ds.coords: + return candidate + return None + + +def _xr_find_overlap_index_range(axis, lo, hi): + axis = np.asarray(axis) + if axis.size == 0: + return None + + if axis[0] <= axis[-1]: + idx = np.where((axis >= lo) & (axis <= hi))[0] + else: + idx = np.where((axis <= hi) & (axis >= lo))[0] + + if idx.size == 0: + return None + return int(idx.min()), int(idx.max()) + + +def _xr_median_spacing(axis): + axis = np.asarray(axis, dtype=float) + if axis.size <= 1: + return np.nan + return float(np.nanmedian(np.abs(np.diff(axis)))) + + +def _xr_subset_to_outputs(sub, xname, yname): + arr = np.asarray(sub.values, dtype=np.float64) + if tuple(sub.dims) == (xname, yname): + arr = np.transpose(arr, (1, 0)) + + topobathy_xy = np.transpose(arr, (1, 0)) + + x_sub = np.asarray(sub.coords[xname].values, dtype=float) + y_sub = np.asarray(sub.coords[yname].values, dtype=float) + dx = _xr_median_spacing(x_sub) + dy = _xr_median_spacing(y_sub) + if not (np.isfinite(dx) and np.isfinite(dy) and dx > 0 and dy > 0): + return None + + bbox_out = ( + float(np.nanmin(x_sub)), + float(np.nanmax(x_sub)), + float(np.nanmin(y_sub)), + float(np.nanmax(y_sub)), + ) + return bbox_out, dx, dy, topobathy_xy + + +def _try_subset_netcdf_with_xarray(dem_path, bbox_vals, crs_str): + """Fallback subsetting for NetCDF when rasterio bounds are unreliable. + + Returns (bbox, dx, dy, topobathy_xy) where topobathy_xy is shaped (nx, ny) + like the rasterio code path before the final np.fliplr() in DEM. + """ + + if dem_path.suffix.lower() not in {".nc", ".nc4"}: + return None + + ds = _xr_open_dataset(dem_path) + if ds is None: + return None + + da = _xr_pick_first_raster_data_array(ds) + if da is None: + return None + da = _xr_reduce_to_2d(da) + + coord_candidates_x = ["x", "lon", "longitude", "Long", "LONGITUDE"] + coord_candidates_y = ["y", "lat", "latitude", "Lat", "LATITUDE"] + + xname = _xr_pick_coord_name(ds, da, coord_candidates_x) + yname = _xr_pick_coord_name(ds, da, coord_candidates_y) + if xname is None or yname is None: + return None + + x = np.asarray(da.coords[xname].values) + y = np.asarray(da.coords[yname].values) + if x.ndim != 1 or y.ndim != 1: + return None + + xmin, xmax, ymin, ymax = map(float, bbox_vals) + + x_min, x_max = float(np.nanmin(x)), float(np.nanmax(x)) + y_min, y_max = float(np.nanmin(y)), float(np.nanmax(y)) + if not ( + max(xmin, x_min) < min(xmax, x_max) and max(ymin, y_min) < min(ymax, y_max) + ): + return None + + xrng = _xr_find_overlap_index_range(x, xmin, xmax) + yrng = _xr_find_overlap_index_range(y, ymin, ymax) + if xrng is None or yrng is None: + return None + + x0, x1 = xrng + y0, y1 = yrng + sub = da.isel({xname: slice(x0, x1 + 1), yname: slice(y0, y1 + 1)}) + return _xr_subset_to_outputs(sub, xname, yname) + + +def _read_dem_array_and_meta(dem_path, bbox, crs, region_bbox, region_crs): + open_target = _pick_netcdf_open_target(dem_path, bbox, crs) + + with rasterio.open(open_target) as src: + nodata_value = src.nodata + meta = src.meta + + src_crs = src.crs + desired_crs = CRS.from_user_input(crs) + + # Entire DEM is read in + if bbox is None: + bbox_ds = src.bounds # left, bottom, right, top + bbox_out = (bbox_ds.left, bbox_ds.right, bbox_ds.bottom, bbox_ds.top) + topobathy = src.read(1) + topobathy_xy = np.transpose(topobathy, (1, 0)) + else: + if region_bbox is None: + region_bbox = (bbox[0], bbox[1], bbox[2], bbox[3]) + + region_crs_for_transform = ( + region_crs if region_crs is not None else desired_crs + ) + region_bbox_src = _transform_bbox_to_src( + region_bbox, src_crs, region_crs_for_transform + ) + + ds_bounds = src.bounds # (left, bottom, right, top) + ds_bbox_conv = ( + ds_bounds.left, + ds_bounds.right, + ds_bounds.bottom, + ds_bounds.top, + ) + + xmin = max(region_bbox_src[0], ds_bbox_conv[0]) + xmax = min(region_bbox_src[1], ds_bbox_conv[1]) + ymin = max(region_bbox_src[2], ds_bbox_conv[2]) + ymax = min(region_bbox_src[3], ds_bbox_conv[3]) + + if not (xmin < xmax and ymin < ymax): + if (src_crs is None) or src.transform == Affine.identity: + logger.warning( + "DEM appears un-georeferenced; applying synthetic georeference using provided bbox extents %s.", + region_bbox, + ) + topobathy = src.read(1) + ny, nx = topobathy.shape # rasterio returns (rows, cols) + dx_syn = (region_bbox[1] - region_bbox[0]) / (nx - 1) + dy_syn = (region_bbox[3] - region_bbox[2]) / (ny - 1) + meta["transform"] = Affine( + dx_syn, 0, region_bbox[0], 0, -dy_syn, region_bbox[3] + ) + bbox_out = region_bbox + topobathy_xy = np.transpose(topobathy, (1, 0)) + else: + if dem_path.suffix.lower() in {".nc", ".nc4"}: + fb = _try_subset_netcdf_with_xarray( + dem_path, region_bbox_src, crs + ) + if fb is not None: + bbox_out, dx_fb, dy_fb, topobathy_xy = fb + meta["transform"] = Affine( + dx_fb, 0, bbox_out[0], 0, -dy_fb, bbox_out[3] + ) + else: + raise ValueError( + "Transformed DEM clipping bbox does not overlap raster bounds. " + f"Region bbox (in raster CRS)={region_bbox_src}, raster bounds={ds_bbox_conv}." + ) + else: + raise ValueError( + "Transformed DEM clipping bbox does not overlap raster bounds. " + f"Region bbox (in raster CRS)={region_bbox_src}, raster bounds={ds_bbox_conv}." + ) + else: + bounds_for_window = (xmin, ymin, xmax, ymax) + try: + window = from_bounds(*bounds_for_window, transform=src.transform) + except Exception as e: + raise RuntimeError( + "Failed to create window for DEM subset. " + f"Bounds={bounds_for_window}, transform={src.transform}." + ) from e + topobathy = src.read(1, window=window, masked=True) + topobathy_xy = np.transpose(topobathy, (1, 0)) + bbox_out = (xmin, xmax, ymin, ymax) + + # Warn if user requested output CRS different from raster CRS (no reprojection performed here) + if ( + (src_crs is not None) + and (desired_crs is not None) + and (src_crs != desired_crs) + and not ((src_crs is None) or src.transform == Affine.identity) + ): + logger.warning( + "DEM opened in its native CRS %s but requested CRS %s differs. " + "Values are NOT reprojected; proceeding in native CRS.", + src_crs, + desired_crs, + ) + crs = src_crs.to_string() + + return bbox_out, crs, meta, nodata_value, topobathy_xy + + def _infer_crs_from_coordinates(bbox): """ Heuristically infer whether a bbox looks like geographic (WGS84) or projected. @@ -733,7 +1077,7 @@ def _read(self): logger.debug("Entering: _read") - msg = f"Reading in ESRI Shapefile {self.shp}" + msg = f"Reading in vector file: {self.shp}" logger.info(msg) # Load once to get native CRS, then transform if necessary @@ -878,145 +1222,24 @@ def __init__(self, dem, crs="EPSG:4326", bbox=None, extrapolate=False): if isinstance(dem, str): dem = Path(dem) - region = None - region_crs = None - _region_bbox = None - if bbox is not None: - assert isinstance(bbox, Region), "bbox must be a Region class object" - region = bbox # Preserve original Region object - region_crs = region.crs - _region_bbox = region.total_bounds - if crs != "EPSG:4326": - logger.warning( - "DEM: Both a Region object and an explicit 'crs' were provided; the Region's CRS will take precedence (crs=%s).", - region_crs, - ) - crs = CRS.from_user_input(region_crs).to_string() - bbox = _region_bbox # Replace bbox with plain tuple bounds + bbox, crs, _region, region_crs, region_bbox = _prepare_region_bbox_and_crs( + bbox, crs + ) if dem.exists(): - msg = f"Reading in {dem}" - logger.info(msg) - # Open the raster file using rasterio - with rasterio.open(dem) as src: - nodata_value = src.nodata - self.meta = src.meta - - src_crs = src.crs - desired_crs = CRS.from_user_input(crs) - - # Helper: transform (xmin,xmax,ymin,ymax) bbox to src_crs if needed - def _transform_bbox_to_src(_bbox_vals, _src_crs, _dst_crs): - if _src_crs is None or _dst_crs is None or _src_crs == _dst_crs: - return _bbox_vals - from pyproj import Transformer - - xmin, xmax, ymin, ymax = _bbox_vals - transformer = Transformer.from_crs( - _dst_crs, _src_crs, always_xy=True - ) - # transform the two diagonal corners then rebuild axis-aligned bbox - xs, ys = transformer.transform([xmin, xmax], [ymin, ymax]) - xmin_t, xmax_t = min(xs), max(xs) - ymin_t, ymax_t = min(ys), max(ys) - return (xmin_t, xmax_t, ymin_t, ymax_t) - - # Entire DEM is read in - if bbox is None: - bbox_ds = src.bounds # left, bottom, right, top - bbox = (bbox_ds.left, bbox_ds.right, bbox_ds.bottom, bbox_ds.top) - topobathy = src.read(1) - # Align orientation with windowed-read branch: make array index order (x, y) - # Rasterio returns (rows, cols) = (ny, nx). Transpose to (nx, ny) then flip - # along y-axis later for bottom-left origin grids. - topobathy = np.transpose(topobathy, (1, 0)) - else: - # Region bbox currently (xmin,xmax,ymin,ymax) already in tuple form - if _region_bbox is None: - _region_bbox = (bbox[0], bbox[1], bbox[2], bbox[3]) - # Use previously captured region_crs if available, else fall back to desired_crs - _region_crs_for_transform = ( - region_crs if region_crs is not None else desired_crs - ) - # Transform to raster CRS if needed - _region_bbox_src = _transform_bbox_to_src( - _region_bbox, src_crs, _region_crs_for_transform - ) - # Intersect with raster bounds to avoid WindowError - ds_bounds = src.bounds # (left, bottom, right, top) - # Convert ds_bounds to (xmin,xmax,ymin,ymax) - ds_bbox_conv = ( - ds_bounds.left, - ds_bounds.right, - ds_bounds.bottom, - ds_bounds.top, - ) - xmin = max(_region_bbox_src[0], ds_bbox_conv[0]) - xmax = min(_region_bbox_src[1], ds_bbox_conv[1]) - ymin = max(_region_bbox_src[2], ds_bbox_conv[2]) - ymax = min(_region_bbox_src[3], ds_bbox_conv[3]) - if not (xmin < xmax and ymin < ymax): - # If raster is NOT georeferenced (identity transform / missing CRS), fallback: read full raster & stretch to requested bbox - if (src_crs is None) or src.transform == Affine.identity: - logger.warning( - "DEM appears un-georeferenced; applying synthetic georeference using provided bbox extents %s.", - _region_bbox, - ) - topobathy = src.read(1) - # derive dx, dy from desired bbox & raster shape - _ny, _nx = topobathy.shape # rasterio returns (rows, cols) - dx_syn = (_region_bbox[1] - _region_bbox[0]) / (_nx - 1) - dy_syn = (_region_bbox[3] - _region_bbox[2]) / (_ny - 1) - # build synthetic affine (note y origin is top in raster, so use ymax and negative dy) - self.meta["transform"] = Affine( - dx_syn, 0, _region_bbox[0], 0, -dy_syn, _region_bbox[3] - ) - bbox = _region_bbox # adopt requested bbox - # skip window clipping logic - # transpose to match later expectations - topobathy = np.transpose(topobathy, (1, 0)) - else: - raise ValueError( - "Transformed DEM clipping bbox does not overlap raster bounds. " - f"Region bbox (in raster CRS)={_region_bbox_src}, raster bounds={ds_bbox_conv}." - ) - else: - # Prepare bounds in rasterio (left,bottom,right,top) - _bounds_for_window = (xmin, ymin, xmax, ymax) - try: - window = from_bounds( - *_bounds_for_window, transform=src.transform - ) - except Exception as e: - raise RuntimeError( - "Failed to create window for DEM subset. " - f"Bounds={_bounds_for_window}, transform={src.transform}." - ) from e - topobathy = src.read(1, window=window, masked=True) - topobathy = np.transpose(topobathy, (1, 0)) - # Update bbox to (xmin,xmax,ymin,ymax) in raster CRS for Grid - bbox = (xmin, xmax, ymin, ymax) - - # Warn if user requested output CRS different from raster CRS (no reprojection performed here) - if ( - (src_crs is not None) - and (desired_crs is not None) - and (src_crs != desired_crs) - and not ((src_crs is None) or src.transform == Affine.identity) - ): - logger.warning( - "DEM opened in its native CRS %s but requested CRS %s differs. " - "Values are NOT reprojected; proceeding in native CRS.", - src_crs, - desired_crs, - ) - # overwrite desired_crs to keep internal consistency - crs = src_crs.to_string() - # Ensure its a floating point array + logger.info(f"Reading in {dem}") + + bbox, crs, meta, nodata_value, topobathy = _read_dem_array_and_meta( + dem, + bbox=bbox, + crs=crs, + region_bbox=region_bbox, + region_crs=region_crs, + ) + self.meta = meta + topobathy = topobathy.astype(np.float64) - topobathy[topobathy == nodata_value] = ( - np.nan - ) # set the no-data value to nan + topobathy[topobathy == nodata_value] = np.nan elif not dem.exists(): raise FileNotFoundError(f"File {dem} could not be located.") diff --git a/oceanmesh/geometry/point_in_polygon_.c b/oceanmesh/geometry/point_in_polygon_.c index aa767e9..6ed86b7 100644 --- a/oceanmesh/geometry/point_in_polygon_.c +++ b/oceanmesh/geometry/point_in_polygon_.c @@ -1,20 +1,20 @@ -/* Generated by Cython 3.2.2 */ +/* Generated by Cython 3.2.3 */ /* BEGIN: Cython Metadata { "distutils": { "depends": [ - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include/numpy/arrayobject.h", - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include/numpy/arrayscalars.h", - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include/numpy/ndarrayobject.h", - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include/numpy/ndarraytypes.h", - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include/numpy/ufuncobject.h" + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include/numpy/arrayobject.h", + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include/numpy/arrayscalars.h", + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include/numpy/ndarrayobject.h", + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include/numpy/ndarraytypes.h", + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include/numpy/ufuncobject.h" ], "extra_compile_args": [ "-O3" ], "include_dirs": [ - "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/_core/include" + "/private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/_core/include" ], "name": "oceanmesh.geometry.point_in_polygon_", "sources": [ @@ -47,8 +47,8 @@ END: Cython Metadata */ #elif PY_VERSION_HEX < 0x03080000 #error Cython requires Python 3.8+. #else -#define __PYX_ABI_VERSION "3_2_2" -#define CYTHON_HEX_VERSION 0x030202F0 +#define __PYX_ABI_VERSION "3_2_3" +#define CYTHON_HEX_VERSION 0x030203F0 #define CYTHON_FUTURE_DIVISION 1 /* CModulePreamble */ #include @@ -1163,6 +1163,15 @@ static int __Pyx_init_co_variables(void) { #define CYTHON_WITHOUT_ASSERTIONS #endif +#ifdef CYTHON_FREETHREADING_COMPATIBLE +#if CYTHON_FREETHREADING_COMPATIBLE +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_NOT_USED +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif #define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 #define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 #define __PYX_DEFAULT_STRING_ENCODING "" @@ -1386,7 +1395,7 @@ static const char *__pyx_filename; static const char* const __pyx_f[] = { "oceanmesh/geometry/point_in_polygon_.pyx", "", - "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd", + "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd", "cpython/type.pxd", }; /* #### Code section: utility_code_proto_before_types ### */ @@ -1639,7 +1648,7 @@ typedef struct { /* #### Code section: numeric_typedefs ### */ -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":743 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":744 * # in Cython to enable them only on the right systems. * * ctypedef npy_int8 int8_t # <<<<<<<<<<<<<< @@ -1648,7 +1657,7 @@ typedef struct { */ typedef npy_int8 __pyx_t_5numpy_int8_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":744 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":745 * * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t # <<<<<<<<<<<<<< @@ -1657,7 +1666,7 @@ typedef npy_int8 __pyx_t_5numpy_int8_t; */ typedef npy_int16 __pyx_t_5numpy_int16_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":745 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":746 * ctypedef npy_int8 int8_t * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t # <<<<<<<<<<<<<< @@ -1666,7 +1675,7 @@ typedef npy_int16 __pyx_t_5numpy_int16_t; */ typedef npy_int32 __pyx_t_5numpy_int32_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":746 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":747 * ctypedef npy_int16 int16_t * ctypedef npy_int32 int32_t * ctypedef npy_int64 int64_t # <<<<<<<<<<<<<< @@ -1675,7 +1684,7 @@ typedef npy_int32 __pyx_t_5numpy_int32_t; */ typedef npy_int64 __pyx_t_5numpy_int64_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":748 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":749 * ctypedef npy_int64 int64_t * * ctypedef npy_uint8 uint8_t # <<<<<<<<<<<<<< @@ -1684,7 +1693,7 @@ typedef npy_int64 __pyx_t_5numpy_int64_t; */ typedef npy_uint8 __pyx_t_5numpy_uint8_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":749 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":750 * * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t # <<<<<<<<<<<<<< @@ -1693,7 +1702,7 @@ typedef npy_uint8 __pyx_t_5numpy_uint8_t; */ typedef npy_uint16 __pyx_t_5numpy_uint16_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":750 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":751 * ctypedef npy_uint8 uint8_t * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t # <<<<<<<<<<<<<< @@ -1702,7 +1711,7 @@ typedef npy_uint16 __pyx_t_5numpy_uint16_t; */ typedef npy_uint32 __pyx_t_5numpy_uint32_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":751 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":752 * ctypedef npy_uint16 uint16_t * ctypedef npy_uint32 uint32_t * ctypedef npy_uint64 uint64_t # <<<<<<<<<<<<<< @@ -1711,7 +1720,7 @@ typedef npy_uint32 __pyx_t_5numpy_uint32_t; */ typedef npy_uint64 __pyx_t_5numpy_uint64_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":753 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":754 * ctypedef npy_uint64 uint64_t * * ctypedef npy_float32 float32_t # <<<<<<<<<<<<<< @@ -1720,7 +1729,7 @@ typedef npy_uint64 __pyx_t_5numpy_uint64_t; */ typedef npy_float32 __pyx_t_5numpy_float32_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":754 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":755 * * ctypedef npy_float32 float32_t * ctypedef npy_float64 float64_t # <<<<<<<<<<<<<< @@ -1729,7 +1738,7 @@ typedef npy_float32 __pyx_t_5numpy_float32_t; */ typedef npy_float64 __pyx_t_5numpy_float64_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":761 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":762 * ctypedef double complex complex128_t * * ctypedef npy_longlong longlong_t # <<<<<<<<<<<<<< @@ -1738,7 +1747,7 @@ typedef npy_float64 __pyx_t_5numpy_float64_t; */ typedef npy_longlong __pyx_t_5numpy_longlong_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":762 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":763 * * ctypedef npy_longlong longlong_t * ctypedef npy_ulonglong ulonglong_t # <<<<<<<<<<<<<< @@ -1747,7 +1756,7 @@ typedef npy_longlong __pyx_t_5numpy_longlong_t; */ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":764 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":765 * ctypedef npy_ulonglong ulonglong_t * * ctypedef npy_intp intp_t # <<<<<<<<<<<<<< @@ -1756,7 +1765,7 @@ typedef npy_ulonglong __pyx_t_5numpy_ulonglong_t; */ typedef npy_intp __pyx_t_5numpy_intp_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":765 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":766 * * ctypedef npy_intp intp_t * ctypedef npy_uintp uintp_t # <<<<<<<<<<<<<< @@ -1765,7 +1774,7 @@ typedef npy_intp __pyx_t_5numpy_intp_t; */ typedef npy_uintp __pyx_t_5numpy_uintp_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":767 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":768 * ctypedef npy_uintp uintp_t * * ctypedef npy_double float_t # <<<<<<<<<<<<<< @@ -1774,7 +1783,7 @@ typedef npy_uintp __pyx_t_5numpy_uintp_t; */ typedef npy_double __pyx_t_5numpy_float_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":768 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":769 * * ctypedef npy_double float_t * ctypedef npy_double double_t # <<<<<<<<<<<<<< @@ -1783,7 +1792,7 @@ typedef npy_double __pyx_t_5numpy_float_t; */ typedef npy_double __pyx_t_5numpy_double_t; -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":769 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":770 * ctypedef npy_double float_t * ctypedef npy_double double_t * ctypedef npy_longdouble longdouble_t # <<<<<<<<<<<<<< @@ -2780,22 +2789,22 @@ static int __Pyx__DelItemOnTypeDict(PyTypeObject *tp, PyObject *k); static int __Pyx_setup_reduce(PyObject* type_obj); /* TypeImport.proto */ -#ifndef __PYX_HAVE_RT_ImportType_proto_3_2_2 -#define __PYX_HAVE_RT_ImportType_proto_3_2_2 +#ifndef __PYX_HAVE_RT_ImportType_proto_3_2_3 +#define __PYX_HAVE_RT_ImportType_proto_3_2_3 #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #include #endif #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L) || __cplusplus >= 201103L -#define __PYX_GET_STRUCT_ALIGNMENT_3_2_2(s) alignof(s) +#define __PYX_GET_STRUCT_ALIGNMENT_3_2_3(s) alignof(s) #else -#define __PYX_GET_STRUCT_ALIGNMENT_3_2_2(s) sizeof(void*) +#define __PYX_GET_STRUCT_ALIGNMENT_3_2_3(s) sizeof(void*) #endif -enum __Pyx_ImportType_CheckSize_3_2_2 { - __Pyx_ImportType_CheckSize_Error_3_2_2 = 0, - __Pyx_ImportType_CheckSize_Warn_3_2_2 = 1, - __Pyx_ImportType_CheckSize_Ignore_3_2_2 = 2 +enum __Pyx_ImportType_CheckSize_3_2_3 { + __Pyx_ImportType_CheckSize_Error_3_2_3 = 0, + __Pyx_ImportType_CheckSize_Warn_3_2_3 = 1, + __Pyx_ImportType_CheckSize_Ignore_3_2_3 = 2 }; -static PyTypeObject *__Pyx_ImportType_3_2_2(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_2_2 check_size); +static PyTypeObject *__Pyx_ImportType_3_2_3(PyObject* module, const char *module_name, const char *class_name, size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_2_3 check_size); #endif /* dict_setdefault.proto (used by FetchCommonType) */ @@ -17065,7 +17074,7 @@ static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":242 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":243 * cdef int type_num * * @property # <<<<<<<<<<<<<< @@ -17076,7 +17085,7 @@ static PyObject *__pyx_unpickle_Enum__set_state(struct __pyx_MemviewEnum_obj *__ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_Descr *__pyx_v_self) { npy_intp __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":244 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":245 * @property * cdef inline npy_intp itemsize(self) noexcept nogil: * return PyDataType_ELSIZE(self) # <<<<<<<<<<<<<< @@ -17086,7 +17095,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_D __pyx_r = PyDataType_ELSIZE(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":242 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":243 * cdef int type_num * * @property # <<<<<<<<<<<<<< @@ -17099,7 +17108,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_D return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":246 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":247 * return PyDataType_ELSIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17110,7 +17119,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_8itemsize_itemsize(PyArray_D static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray_Descr *__pyx_v_self) { npy_intp __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":248 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":249 * @property * cdef inline npy_intp alignment(self) noexcept nogil: * return PyDataType_ALIGNMENT(self) # <<<<<<<<<<<<<< @@ -17120,7 +17129,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray __pyx_r = PyDataType_ALIGNMENT(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":246 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":247 * return PyDataType_ELSIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17133,7 +17142,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_5dtype_9alignment_alignment(PyArray return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":252 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":253 * # Use fields/names with care as they may be NULL. You must check * # for this using PyDataType_HASFIELDS. * @property # <<<<<<<<<<<<<< @@ -17147,7 +17156,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Desc PyObject *__pyx_t_1; __Pyx_RefNannySetupContext("fields", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":254 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":255 * @property * cdef inline object fields(self): * return PyDataType_FIELDS(self) # <<<<<<<<<<<<<< @@ -17160,7 +17169,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Desc __pyx_r = ((PyObject *)__pyx_t_1); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":252 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":253 * # Use fields/names with care as they may be NULL. You must check * # for this using PyDataType_HASFIELDS. * @property # <<<<<<<<<<<<<< @@ -17175,7 +17184,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_6fields_fields(PyArray_Desc return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":256 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":257 * return PyDataType_FIELDS(self) * * @property # <<<<<<<<<<<<<< @@ -17189,7 +17198,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr PyObject *__pyx_t_1; __Pyx_RefNannySetupContext("names", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":258 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":259 * @property * cdef inline tuple names(self): * return PyDataType_NAMES(self) # <<<<<<<<<<<<<< @@ -17202,7 +17211,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr __pyx_r = ((PyObject*)__pyx_t_1); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":256 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":257 * return PyDataType_FIELDS(self) * * @property # <<<<<<<<<<<<<< @@ -17217,7 +17226,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":263 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":264 * # valid (the pointer can be NULL). Most users should access * # this field via the inline helper method PyDataType_SHAPE. * @property # <<<<<<<<<<<<<< @@ -17228,7 +17237,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_5dtype_5names_names(PyArray_Descr static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarray(PyArray_Descr *__pyx_v_self) { PyArray_ArrayDescr *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":265 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":266 * @property * cdef inline PyArray_ArrayDescr* subarray(self) noexcept nogil: * return PyDataType_SUBARRAY(self) # <<<<<<<<<<<<<< @@ -17238,7 +17247,7 @@ static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarra __pyx_r = PyDataType_SUBARRAY(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":263 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":264 * # valid (the pointer can be NULL). Most users should access * # this field via the inline helper method PyDataType_SHAPE. * @property # <<<<<<<<<<<<<< @@ -17251,7 +17260,7 @@ static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarra return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":267 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":268 * return PyDataType_SUBARRAY(self) * * @property # <<<<<<<<<<<<<< @@ -17262,7 +17271,7 @@ static CYTHON_INLINE PyArray_ArrayDescr *__pyx_f_5numpy_5dtype_8subarray_subarra static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr *__pyx_v_self) { npy_uint64 __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":270 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":271 * cdef inline npy_uint64 flags(self) noexcept nogil: * """The data types flags.""" * return PyDataType_FLAGS(self) # <<<<<<<<<<<<<< @@ -17272,7 +17281,7 @@ static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr __pyx_r = PyDataType_FLAGS(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":267 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":268 * return PyDataType_SUBARRAY(self) * * @property # <<<<<<<<<<<<<< @@ -17285,7 +17294,7 @@ static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":279 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":280 * ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]: * * @property # <<<<<<<<<<<<<< @@ -17296,7 +17305,7 @@ static CYTHON_INLINE npy_uint64 __pyx_f_5numpy_5dtype_5flags_flags(PyArray_Descr static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMultiIterObject *__pyx_v_self) { int __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":282 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":283 * cdef inline int numiter(self) noexcept nogil: * """The number of arrays that need to be broadcast to the same shape.""" * return PyArray_MultiIter_NUMITER(self) # <<<<<<<<<<<<<< @@ -17306,7 +17315,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMulti __pyx_r = PyArray_MultiIter_NUMITER(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":279 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":280 * ctypedef class numpy.broadcast [object PyArrayMultiIterObject, check_size ignore]: * * @property # <<<<<<<<<<<<<< @@ -17319,7 +17328,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMulti return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":284 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":285 * return PyArray_MultiIter_NUMITER(self) * * @property # <<<<<<<<<<<<<< @@ -17330,7 +17339,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_7numiter_numiter(PyArrayMulti static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiIterObject *__pyx_v_self) { npy_intp __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":287 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":288 * cdef inline npy_intp size(self) noexcept nogil: * """The total broadcasted size.""" * return PyArray_MultiIter_SIZE(self) # <<<<<<<<<<<<<< @@ -17340,7 +17349,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiI __pyx_r = PyArray_MultiIter_SIZE(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":284 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":285 * return PyArray_MultiIter_NUMITER(self) * * @property # <<<<<<<<<<<<<< @@ -17353,7 +17362,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiI return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":289 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":290 * return PyArray_MultiIter_SIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17364,7 +17373,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_4size_size(PyArrayMultiI static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMultiIterObject *__pyx_v_self) { npy_intp __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":292 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":293 * cdef inline npy_intp index(self) noexcept nogil: * """The current (1-d) index into the broadcasted result.""" * return PyArray_MultiIter_INDEX(self) # <<<<<<<<<<<<<< @@ -17374,7 +17383,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMult __pyx_r = PyArray_MultiIter_INDEX(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":289 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":290 * return PyArray_MultiIter_SIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17387,7 +17396,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMult return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":294 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":295 * return PyArray_MultiIter_INDEX(self) * * @property # <<<<<<<<<<<<<< @@ -17398,7 +17407,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_9broadcast_5index_index(PyArrayMult static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject *__pyx_v_self) { int __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":297 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":298 * cdef inline int nd(self) noexcept nogil: * """The number of dimensions in the broadcasted result.""" * return PyArray_MultiIter_NDIM(self) # <<<<<<<<<<<<<< @@ -17408,7 +17417,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject __pyx_r = PyArray_MultiIter_NDIM(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":294 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":295 * return PyArray_MultiIter_INDEX(self) * * @property # <<<<<<<<<<<<<< @@ -17421,7 +17430,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":299 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":300 * return PyArray_MultiIter_NDIM(self) * * @property # <<<<<<<<<<<<<< @@ -17432,7 +17441,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_9broadcast_2nd_nd(PyArrayMultiIterObject static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions(PyArrayMultiIterObject *__pyx_v_self) { npy_intp *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":302 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":303 * cdef inline npy_intp* dimensions(self) noexcept nogil: * """The shape of the broadcasted result.""" * return PyArray_MultiIter_DIMS(self) # <<<<<<<<<<<<<< @@ -17442,7 +17451,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions __pyx_r = PyArray_MultiIter_DIMS(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":299 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":300 * return PyArray_MultiIter_NDIM(self) * * @property # <<<<<<<<<<<<<< @@ -17455,7 +17464,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":304 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":305 * return PyArray_MultiIter_DIMS(self) * * @property # <<<<<<<<<<<<<< @@ -17466,7 +17475,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_9broadcast_10dimensions_dimensions static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiIterObject *__pyx_v_self) { void **__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":308 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":309 * """An array of iterator objects that holds the iterators for the arrays to be broadcast together. * On return, the iterators are adjusted for broadcasting.""" * return PyArray_MultiIter_ITERS(self) # <<<<<<<<<<<<<< @@ -17476,7 +17485,7 @@ static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiI __pyx_r = PyArray_MultiIter_ITERS(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":304 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":305 * return PyArray_MultiIter_DIMS(self) * * @property # <<<<<<<<<<<<<< @@ -17489,7 +17498,7 @@ static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiI return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":322 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":323 * # Instead, we use properties that map to the corresponding C-API functions. * * @property # <<<<<<<<<<<<<< @@ -17500,7 +17509,7 @@ static CYTHON_INLINE void **__pyx_f_5numpy_9broadcast_5iters_iters(PyArrayMultiI static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject *__pyx_v_self) { PyObject *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":326 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":327 * """Returns a borrowed reference to the object owning the data/memory. * """ * return PyArray_BASE(self) # <<<<<<<<<<<<<< @@ -17510,7 +17519,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject __pyx_r = PyArray_BASE(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":322 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":323 * # Instead, we use properties that map to the corresponding C-API functions. * * @property # <<<<<<<<<<<<<< @@ -17523,7 +17532,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_7ndarray_4base_base(PyArrayObject return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":328 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":329 * return PyArray_BASE(self) * * @property # <<<<<<<<<<<<<< @@ -17537,7 +17546,7 @@ static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArray PyArray_Descr *__pyx_t_1; __Pyx_RefNannySetupContext("descr", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":332 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":333 * """Returns an owned reference to the dtype of the array. * """ * return PyArray_DESCR(self) # <<<<<<<<<<<<<< @@ -17550,7 +17559,7 @@ static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArray __pyx_r = ((PyArray_Descr *)__pyx_t_1); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":328 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":329 * return PyArray_BASE(self) * * @property # <<<<<<<<<<<<<< @@ -17565,7 +17574,7 @@ static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArray return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":334 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":335 * return PyArray_DESCR(self) * * @property # <<<<<<<<<<<<<< @@ -17576,7 +17585,7 @@ static CYTHON_INLINE PyArray_Descr *__pyx_f_5numpy_7ndarray_5descr_descr(PyArray static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx_v_self) { int __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":338 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":339 * """Returns the number of dimensions in the array. * """ * return PyArray_NDIM(self) # <<<<<<<<<<<<<< @@ -17586,7 +17595,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx __pyx_r = PyArray_NDIM(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":334 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":335 * return PyArray_DESCR(self) * * @property # <<<<<<<<<<<<<< @@ -17599,7 +17608,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":340 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":341 * return PyArray_NDIM(self) * * @property # <<<<<<<<<<<<<< @@ -17610,7 +17619,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_7ndarray_4ndim_ndim(PyArrayObject *__pyx static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObject *__pyx_v_self) { npy_intp *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":346 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":347 * Can return NULL for 0-dimensional arrays. * """ * return PyArray_DIMS(self) # <<<<<<<<<<<<<< @@ -17620,7 +17629,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObjec __pyx_r = PyArray_DIMS(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":340 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":341 * return PyArray_NDIM(self) * * @property # <<<<<<<<<<<<<< @@ -17633,7 +17642,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObjec return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":348 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":349 * return PyArray_DIMS(self) * * @property # <<<<<<<<<<<<<< @@ -17644,7 +17653,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_5shape_shape(PyArrayObjec static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayObject *__pyx_v_self) { npy_intp *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":353 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":354 * The number of elements matches the number of dimensions of the array (ndim). * """ * return PyArray_STRIDES(self) # <<<<<<<<<<<<<< @@ -17654,7 +17663,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayO __pyx_r = PyArray_STRIDES(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":348 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":349 * return PyArray_DIMS(self) * * @property # <<<<<<<<<<<<<< @@ -17667,7 +17676,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayO return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":355 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":356 * return PyArray_STRIDES(self) * * @property # <<<<<<<<<<<<<< @@ -17678,7 +17687,7 @@ static CYTHON_INLINE npy_intp *__pyx_f_5numpy_7ndarray_7strides_strides(PyArrayO static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject *__pyx_v_self) { npy_intp __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":359 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":360 * """Returns the total size (in number of elements) of the array. * """ * return PyArray_SIZE(self) # <<<<<<<<<<<<<< @@ -17688,7 +17697,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject * __pyx_r = PyArray_SIZE(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":355 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":356 * return PyArray_STRIDES(self) * * @property # <<<<<<<<<<<<<< @@ -17701,7 +17710,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject * return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":361 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":362 * return PyArray_SIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17712,7 +17721,7 @@ static CYTHON_INLINE npy_intp __pyx_f_5numpy_7ndarray_4size_size(PyArrayObject * static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__pyx_v_self) { char *__pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":368 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":369 * of `PyArray_DATA()` instead, which returns a 'void*'. * """ * return PyArray_BYTES(self) # <<<<<<<<<<<<<< @@ -17722,7 +17731,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__p __pyx_r = PyArray_BYTES(__pyx_v_self); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":361 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":362 * return PyArray_SIZE(self) * * @property # <<<<<<<<<<<<<< @@ -17735,7 +17744,7 @@ static CYTHON_INLINE char *__pyx_f_5numpy_7ndarray_4data_data(PyArrayObject *__p return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":776 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":777 * ctypedef long double complex clongdouble_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< @@ -17752,7 +17761,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew1", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":777 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":778 * * cdef inline object PyArray_MultiIterNew1(a): * return PyArray_MultiIterNew(1, a) # <<<<<<<<<<<<<< @@ -17760,13 +17769,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ * cdef inline object PyArray_MultiIterNew2(a, b): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 777, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(1, ((void *)__pyx_v_a)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 778, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":776 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":777 * ctypedef long double complex clongdouble_t * * cdef inline object PyArray_MultiIterNew1(a): # <<<<<<<<<<<<<< @@ -17785,7 +17794,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew1(PyObject *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":779 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":780 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< @@ -17802,7 +17811,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew2", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":780 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":781 * * cdef inline object PyArray_MultiIterNew2(a, b): * return PyArray_MultiIterNew(2, a, b) # <<<<<<<<<<<<<< @@ -17810,13 +17819,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ * cdef inline object PyArray_MultiIterNew3(a, b, c): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 780, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(2, ((void *)__pyx_v_a), ((void *)__pyx_v_b)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 781, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":779 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":780 * return PyArray_MultiIterNew(1, a) * * cdef inline object PyArray_MultiIterNew2(a, b): # <<<<<<<<<<<<<< @@ -17835,7 +17844,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew2(PyObject *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":782 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":783 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< @@ -17852,7 +17861,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew3", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":783 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":784 * * cdef inline object PyArray_MultiIterNew3(a, b, c): * return PyArray_MultiIterNew(3, a, b, c) # <<<<<<<<<<<<<< @@ -17860,13 +17869,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ * cdef inline object PyArray_MultiIterNew4(a, b, c, d): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 783, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(3, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 784, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":782 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":783 * return PyArray_MultiIterNew(2, a, b) * * cdef inline object PyArray_MultiIterNew3(a, b, c): # <<<<<<<<<<<<<< @@ -17885,7 +17894,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew3(PyObject *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":785 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":786 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -17902,7 +17911,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew4", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":786 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":787 * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): * return PyArray_MultiIterNew(4, a, b, c, d) # <<<<<<<<<<<<<< @@ -17910,13 +17919,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 786, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(4, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 787, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":785 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":786 * return PyArray_MultiIterNew(3, a, b, c) * * cdef inline object PyArray_MultiIterNew4(a, b, c, d): # <<<<<<<<<<<<<< @@ -17935,7 +17944,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew4(PyObject *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":788 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":789 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -17952,7 +17961,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ int __pyx_clineno = 0; __Pyx_RefNannySetupContext("PyArray_MultiIterNew5", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":789 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":790 * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): * return PyArray_MultiIterNew(5, a, b, c, d, e) # <<<<<<<<<<<<<< @@ -17960,13 +17969,13 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ * cdef inline tuple PyDataType_SHAPE(dtype d): */ __Pyx_XDECREF(__pyx_r); - __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 789, __pyx_L1_error) + __pyx_t_1 = PyArray_MultiIterNew(5, ((void *)__pyx_v_a), ((void *)__pyx_v_b), ((void *)__pyx_v_c), ((void *)__pyx_v_d), ((void *)__pyx_v_e)); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 790, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":788 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":789 * return PyArray_MultiIterNew(4, a, b, c, d) * * cdef inline object PyArray_MultiIterNew5(a, b, c, d, e): # <<<<<<<<<<<<<< @@ -17985,7 +17994,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyArray_MultiIterNew5(PyObject *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":791 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":792 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -18000,7 +18009,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ PyObject *__pyx_t_2; __Pyx_RefNannySetupContext("PyDataType_SHAPE", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":792 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":793 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -18010,7 +18019,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ __pyx_t_1 = PyDataType_HASSUBARRAY(__pyx_v_d); if (__pyx_t_1) { - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":793 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":794 * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): * return d.subarray.shape # <<<<<<<<<<<<<< @@ -18023,7 +18032,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ __pyx_r = ((PyObject*)__pyx_t_2); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":792 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":793 * * cdef inline tuple PyDataType_SHAPE(dtype d): * if PyDataType_HASSUBARRAY(d): # <<<<<<<<<<<<<< @@ -18032,7 +18041,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ */ } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":795 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":796 * return d.subarray.shape * else: * return () # <<<<<<<<<<<<<< @@ -18046,7 +18055,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ goto __pyx_L0; } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":791 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":792 * return PyArray_MultiIterNew(5, a, b, c, d, e) * * cdef inline tuple PyDataType_SHAPE(dtype d): # <<<<<<<<<<<<<< @@ -18061,7 +18070,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_PyDataType_SHAPE(PyArray_Descr *__ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":994 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":995 * int _import_umath() except -1 * * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< @@ -18075,7 +18084,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a const char *__pyx_filename = NULL; int __pyx_clineno = 0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":995 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":996 * * cdef inline void set_array_base(ndarray arr, object base) except *: * Py_INCREF(base) # important to do this before stealing the reference below! # <<<<<<<<<<<<<< @@ -18084,16 +18093,16 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a */ Py_INCREF(__pyx_v_base); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":996 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":997 * cdef inline void set_array_base(ndarray arr, object base) except *: * Py_INCREF(base) # important to do this before stealing the reference below! * PyArray_SetBaseObject(arr, base) # <<<<<<<<<<<<<< * * cdef inline object get_array_base(ndarray arr): */ - __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 996, __pyx_L1_error) + __pyx_t_1 = PyArray_SetBaseObject(__pyx_v_arr, __pyx_v_base); if (unlikely(__pyx_t_1 == ((int)-1))) __PYX_ERR(2, 997, __pyx_L1_error) - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":994 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":995 * int _import_umath() except -1 * * cdef inline void set_array_base(ndarray arr, object base) except *: # <<<<<<<<<<<<<< @@ -18108,7 +18117,7 @@ static CYTHON_INLINE void __pyx_f_5numpy_set_array_base(PyArrayObject *__pyx_v_a __pyx_L0:; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":998 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":999 * PyArray_SetBaseObject(arr, base) * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -18123,7 +18132,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py int __pyx_t_1; __Pyx_RefNannySetupContext("get_array_base", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":999 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1000 * * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) # <<<<<<<<<<<<<< @@ -18132,7 +18141,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py */ __pyx_v_base = PyArray_BASE(__pyx_v_arr); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1000 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1001 * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) * if base is NULL: # <<<<<<<<<<<<<< @@ -18142,7 +18151,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_t_1 = (__pyx_v_base == NULL); if (__pyx_t_1) { - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1001 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1002 * base = PyArray_BASE(arr) * if base is NULL: * return None # <<<<<<<<<<<<<< @@ -18153,7 +18162,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_r = Py_None; __Pyx_INCREF(Py_None); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1000 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1001 * cdef inline object get_array_base(ndarray arr): * base = PyArray_BASE(arr) * if base is NULL: # <<<<<<<<<<<<<< @@ -18162,7 +18171,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py */ } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1002 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1003 * if base is NULL: * return None * return base # <<<<<<<<<<<<<< @@ -18174,7 +18183,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py __pyx_r = ((PyObject *)__pyx_v_base); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":998 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":999 * PyArray_SetBaseObject(arr, base) * * cdef inline object get_array_base(ndarray arr): # <<<<<<<<<<<<<< @@ -18189,7 +18198,7 @@ static CYTHON_INLINE PyObject *__pyx_f_5numpy_get_array_base(PyArrayObject *__py return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1006 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1007 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -18215,7 +18224,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_array", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1007 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1008 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18231,16 +18240,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1008 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1009 * cdef inline int import_array() except -1: * try: * __pyx_import_array() # <<<<<<<<<<<<<< * except Exception: * raise ImportError("numpy._core.multiarray failed to import") */ - __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1008, __pyx_L3_error) + __pyx_t_4 = _import_array(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1009, __pyx_L3_error) - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1007 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1008 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18254,7 +18263,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1009 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1010 * try: * __pyx_import_array() * except Exception: # <<<<<<<<<<<<<< @@ -18264,12 +18273,12 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_Exception)))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_array", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1009, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1010, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1010 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1011 * __pyx_import_array() * except Exception: * raise ImportError("numpy._core.multiarray failed to import") # <<<<<<<<<<<<<< @@ -18282,16 +18291,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_mstate_global->__pyx_kp_u_numpy__core_multiarray_failed_to}; __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ImportError)), __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (__pyx_t_10*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1010, __pyx_L5_except_error) + if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1011, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); } __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1010, __pyx_L5_except_error) + __PYX_ERR(2, 1011, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1007 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1008 * # Cython code. * cdef inline int import_array() except -1: * try: # <<<<<<<<<<<<<< @@ -18307,7 +18316,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { __pyx_L8_try_end:; } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1006 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1007 * # Versions of the import_* functions which are more suitable for * # Cython code. * cdef inline int import_array() except -1: # <<<<<<<<<<<<<< @@ -18331,7 +18340,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_array(void) { return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1012 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1013 * raise ImportError("numpy._core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< @@ -18357,7 +18366,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_umath", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1013 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1014 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -18373,16 +18382,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1014 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1015 * cdef inline int import_umath() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< * except Exception: * raise ImportError("numpy._core.umath failed to import") */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1014, __pyx_L3_error) + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1015, __pyx_L3_error) - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1013 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1014 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -18396,7 +18405,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1015 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1016 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< @@ -18406,12 +18415,12 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_Exception)))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_umath", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1015, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1016, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1016 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1017 * _import_umath() * except Exception: * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< @@ -18424,16 +18433,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_mstate_global->__pyx_kp_u_numpy__core_umath_failed_to_impo}; __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ImportError)), __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (__pyx_t_10*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1016, __pyx_L5_except_error) + if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1017, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); } __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1016, __pyx_L5_except_error) + __PYX_ERR(2, 1017, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1013 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1014 * * cdef inline int import_umath() except -1: * try: # <<<<<<<<<<<<<< @@ -18449,7 +18458,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { __pyx_L8_try_end:; } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1012 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1013 * raise ImportError("numpy._core.multiarray failed to import") * * cdef inline int import_umath() except -1: # <<<<<<<<<<<<<< @@ -18473,7 +18482,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_umath(void) { return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1018 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1019 * raise ImportError("numpy._core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< @@ -18499,7 +18508,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { int __pyx_clineno = 0; __Pyx_RefNannySetupContext("import_ufunc", 0); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1019 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1020 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -18515,16 +18524,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __Pyx_XGOTREF(__pyx_t_3); /*try:*/ { - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1020 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1021 * cdef inline int import_ufunc() except -1: * try: * _import_umath() # <<<<<<<<<<<<<< * except Exception: * raise ImportError("numpy._core.umath failed to import") */ - __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1020, __pyx_L3_error) + __pyx_t_4 = _import_umath(); if (unlikely(__pyx_t_4 == ((int)-1))) __PYX_ERR(2, 1021, __pyx_L3_error) - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1019 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1020 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -18538,7 +18547,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { goto __pyx_L8_try_end; __pyx_L3_error:; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1021 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1022 * try: * _import_umath() * except Exception: # <<<<<<<<<<<<<< @@ -18548,12 +18557,12 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __pyx_t_4 = __Pyx_PyErr_ExceptionMatches(((PyObject *)(((PyTypeObject*)PyExc_Exception)))); if (__pyx_t_4) { __Pyx_AddTraceback("numpy.import_ufunc", __pyx_clineno, __pyx_lineno, __pyx_filename); - if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1021, __pyx_L5_except_error) + if (__Pyx_GetException(&__pyx_t_5, &__pyx_t_6, &__pyx_t_7) < 0) __PYX_ERR(2, 1022, __pyx_L5_except_error) __Pyx_XGOTREF(__pyx_t_5); __Pyx_XGOTREF(__pyx_t_6); __Pyx_XGOTREF(__pyx_t_7); - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1022 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1023 * _import_umath() * except Exception: * raise ImportError("numpy._core.umath failed to import") # <<<<<<<<<<<<<< @@ -18566,16 +18575,16 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { PyObject *__pyx_callargs[2] = {__pyx_t_9, __pyx_mstate_global->__pyx_kp_u_numpy__core_umath_failed_to_impo}; __pyx_t_8 = __Pyx_PyObject_FastCall((PyObject*)(((PyTypeObject*)PyExc_ImportError)), __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (__pyx_t_10*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0; - if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1022, __pyx_L5_except_error) + if (unlikely(!__pyx_t_8)) __PYX_ERR(2, 1023, __pyx_L5_except_error) __Pyx_GOTREF(__pyx_t_8); } __Pyx_Raise(__pyx_t_8, 0, 0, 0); __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __PYX_ERR(2, 1022, __pyx_L5_except_error) + __PYX_ERR(2, 1023, __pyx_L5_except_error) } goto __pyx_L5_except_error; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1019 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1020 * * cdef inline int import_ufunc() except -1: * try: # <<<<<<<<<<<<<< @@ -18591,7 +18600,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { __pyx_L8_try_end:; } - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1018 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1019 * raise ImportError("numpy._core.umath failed to import") * * cdef inline int import_ufunc() except -1: # <<<<<<<<<<<<<< @@ -18615,7 +18624,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1025 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1026 * * * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< @@ -18626,7 +18635,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_import_ufunc(void) { static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_obj) { int __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1037 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1038 * bool * """ * return PyObject_TypeCheck(obj, &PyTimedeltaArrType_Type) # <<<<<<<<<<<<<< @@ -18636,7 +18645,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyTimedeltaArrType_Type)); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1025 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1026 * * * cdef inline bint is_timedelta64_object(object obj) noexcept: # <<<<<<<<<<<<<< @@ -18649,7 +18658,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1040 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1041 * * * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< @@ -18660,7 +18669,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_timedelta64_object(PyObject *__pyx_v_ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_obj) { int __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1052 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1053 * bool * """ * return PyObject_TypeCheck(obj, &PyDatetimeArrType_Type) # <<<<<<<<<<<<<< @@ -18670,7 +18679,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o __pyx_r = PyObject_TypeCheck(__pyx_v_obj, (&PyDatetimeArrType_Type)); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1040 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1041 * * * cdef inline bint is_datetime64_object(object obj) noexcept: # <<<<<<<<<<<<<< @@ -18683,7 +18692,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1055 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1056 * * * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -18694,7 +18703,7 @@ static CYTHON_INLINE int __pyx_f_5numpy_is_datetime64_object(PyObject *__pyx_v_o static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject *__pyx_v_obj) { npy_datetime __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1062 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1063 * also needed. That can be found using `get_datetime64_unit`. * """ * return (obj).obval # <<<<<<<<<<<<<< @@ -18704,7 +18713,7 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * __pyx_r = ((PyDatetimeScalarObject *)__pyx_v_obj)->obval; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1055 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1056 * * * cdef inline npy_datetime get_datetime64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -18717,7 +18726,7 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1065 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1066 * * * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -18728,7 +18737,7 @@ static CYTHON_INLINE npy_datetime __pyx_f_5numpy_get_datetime64_value(PyObject * static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject *__pyx_v_obj) { npy_timedelta __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1069 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1070 * returns the int64 value underlying scalar numpy timedelta64 object * """ * return (obj).obval # <<<<<<<<<<<<<< @@ -18738,7 +18747,7 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject __pyx_r = ((PyTimedeltaScalarObject *)__pyx_v_obj)->obval; goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1065 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1066 * * * cdef inline npy_timedelta get_timedelta64_value(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -18751,7 +18760,7 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject return __pyx_r; } -/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1072 +/* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1073 * * * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -18762,7 +18771,7 @@ static CYTHON_INLINE npy_timedelta __pyx_f_5numpy_get_timedelta64_value(PyObject static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObject *__pyx_v_obj) { NPY_DATETIMEUNIT __pyx_r; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1076 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1077 * returns the unit part of the dtype for a numpy datetime64 object. * """ * return (obj).obmeta.base # <<<<<<<<<<<<<< @@ -18772,7 +18781,7 @@ static CYTHON_INLINE NPY_DATETIMEUNIT __pyx_f_5numpy_get_datetime64_unit(PyObjec __pyx_r = ((NPY_DATETIMEUNIT)((PyDatetimeScalarObject *)__pyx_v_obj)->obmeta.base); goto __pyx_L0; - /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/pip-build-env-a2fe1566/overlay/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1072 + /* "../../../../private/var/folders/r2/r_0zd0zn4ns8dc1_f421l03h0000gn/T/build-env-xpakl00k/lib/python3.12/site-packages/numpy/__init__.cython-30.pxd":1073 * * * cdef inline NPY_DATETIMEUNIT get_datetime64_unit(object obj) noexcept nogil: # <<<<<<<<<<<<<< @@ -21411,153 +21420,153 @@ static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { /*--- Type import code ---*/ __pyx_t_1 = PyImport_ImportModule(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_t_1)) __PYX_ERR(3, 9, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_mstate->__pyx_ptype_7cpython_4type_type = __Pyx_ImportType_3_2_2(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", + __pyx_mstate->__pyx_ptype_7cpython_4type_type = __Pyx_ImportType_3_2_3(__pyx_t_1, __Pyx_BUILTIN_MODULE_NAME, "type", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyTypeObject), + sizeof(PyTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyTypeObject), #elif CYTHON_COMPILING_IN_LIMITED_API 0, 0, #else - sizeof(PyHeapTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyHeapTypeObject), + sizeof(PyHeapTypeObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyHeapTypeObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_7cpython_4type_type) __PYX_ERR(3, 9, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 228, __pyx_L1_error) + __pyx_t_1 = PyImport_ImportModule("numpy"); if (unlikely(!__pyx_t_1)) __PYX_ERR(2, 229, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_mstate->__pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "dtype", + __pyx_mstate->__pyx_ptype_5numpy_dtype = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "dtype", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArray_Descr), + sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArray_Descr), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArray_Descr), + sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArray_Descr), #else - sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArray_Descr), + sizeof(PyArray_Descr), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArray_Descr), #endif - __Pyx_ImportType_CheckSize_Ignore_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 228, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "flatiter", + __Pyx_ImportType_CheckSize_Ignore_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_dtype) __PYX_ERR(2, 229, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_flatiter = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "flatiter", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayIterObject), + sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayIterObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayIterObject), + sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayIterObject), #else - sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayIterObject), + sizeof(PyArrayIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayIterObject), #endif - __Pyx_ImportType_CheckSize_Ignore_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 273, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "broadcast", + __Pyx_ImportType_CheckSize_Ignore_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_flatiter) __PYX_ERR(2, 274, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_broadcast = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "broadcast", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayMultiIterObject), + sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayMultiIterObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayMultiIterObject), + sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayMultiIterObject), #else - sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayMultiIterObject), + sizeof(PyArrayMultiIterObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayMultiIterObject), #endif - __Pyx_ImportType_CheckSize_Ignore_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 277, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "ndarray", + __Pyx_ImportType_CheckSize_Ignore_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_broadcast) __PYX_ERR(2, 278, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_ndarray = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "ndarray", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayObject), + sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayObject), + sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayObject), #else - sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyArrayObject), + sizeof(PyArrayObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyArrayObject), #endif - __Pyx_ImportType_CheckSize_Ignore_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 316, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_generic = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "generic", + __Pyx_ImportType_CheckSize_Ignore_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_ndarray) __PYX_ERR(2, 317, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_generic = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "generic", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_generic) __PYX_ERR(2, 825, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_number = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "number", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_generic) __PYX_ERR(2, 826, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_number = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "number", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_number) __PYX_ERR(2, 827, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_integer = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "integer", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_number) __PYX_ERR(2, 828, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_integer = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "integer", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_integer) __PYX_ERR(2, 829, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "signedinteger", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_integer) __PYX_ERR(2, 830, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_signedinteger = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "signedinteger", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 831, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "unsignedinteger", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_signedinteger) __PYX_ERR(2, 832, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_unsignedinteger = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "unsignedinteger", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 833, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "inexact", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_unsignedinteger) __PYX_ERR(2, 834, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_inexact = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "inexact", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 835, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_floating = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "floating", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_inexact) __PYX_ERR(2, 836, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_floating = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "floating", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_floating) __PYX_ERR(2, 837, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "complexfloating", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_floating) __PYX_ERR(2, 838, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_complexfloating = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "complexfloating", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 839, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "flexible", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_complexfloating) __PYX_ERR(2, 840, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_flexible = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "flexible", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 841, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_character = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "character", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_flexible) __PYX_ERR(2, 842, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_character = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "character", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #else - sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyObject), + sizeof(PyObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyObject), #endif - __Pyx_ImportType_CheckSize_Warn_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_character) __PYX_ERR(2, 843, __pyx_L1_error) - __pyx_mstate->__pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_2_2(__pyx_t_1, "numpy", "ufunc", + __Pyx_ImportType_CheckSize_Warn_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_character) __PYX_ERR(2, 844, __pyx_L1_error) + __pyx_mstate->__pyx_ptype_5numpy_ufunc = __Pyx_ImportType_3_2_3(__pyx_t_1, "numpy", "ufunc", #if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x050B0000 - sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyUFuncObject), + sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyUFuncObject), #elif CYTHON_COMPILING_IN_LIMITED_API - sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyUFuncObject), + sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyUFuncObject), #else - sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_2(PyUFuncObject), + sizeof(PyUFuncObject), __PYX_GET_STRUCT_ALIGNMENT_3_2_3(PyUFuncObject), #endif - __Pyx_ImportType_CheckSize_Ignore_3_2_2); if (!__pyx_mstate->__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 907, __pyx_L1_error) + __Pyx_ImportType_CheckSize_Ignore_3_2_3); if (!__pyx_mstate->__pyx_ptype_5numpy_ufunc) __PYX_ERR(2, 908, __pyx_L1_error) __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_RefNannyFinishContext(); return 0; @@ -21592,7 +21601,7 @@ static PyModuleDef_Slot __pyx_moduledef_slots[] = { {Py_mod_create, (void*)__pyx_pymod_create}, {Py_mod_exec, (void*)__pyx_pymod_exec_point_in_polygon_}, #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING - {Py_mod_gil, Py_MOD_GIL_USED}, + {Py_mod_gil, __Pyx_FREETHREADING_COMPATIBLE}, #endif #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, @@ -26807,10 +26816,10 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha } /* TypeImport */ - #ifndef __PYX_HAVE_RT_ImportType_3_2_2 - #define __PYX_HAVE_RT_ImportType_3_2_2 - static PyTypeObject *__Pyx_ImportType_3_2_2(PyObject *module, const char *module_name, const char *class_name, - size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_2_2 check_size) + #ifndef __PYX_HAVE_RT_ImportType_3_2_3 + #define __PYX_HAVE_RT_ImportType_3_2_3 + static PyTypeObject *__Pyx_ImportType_3_2_3(PyObject *module, const char *module_name, const char *class_name, + size_t size, size_t alignment, enum __Pyx_ImportType_CheckSize_3_2_3 check_size) { PyObject *result = 0; Py_ssize_t basicsize; @@ -26866,7 +26875,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha module_name, class_name, size, basicsize+itemsize); goto bad; } - if (check_size == __Pyx_ImportType_CheckSize_Error_3_2_2 && + if (check_size == __Pyx_ImportType_CheckSize_Error_3_2_3 && ((size_t)basicsize > size || (size_t)(basicsize + itemsize) < size)) { PyErr_Format(PyExc_ValueError, "%.200s.%.200s size changed, may indicate binary incompatibility. " @@ -26874,7 +26883,7 @@ static const char* __Pyx_BufFmt_CheckString(__Pyx_BufFmt_Context* ctx, const cha module_name, class_name, size, basicsize, basicsize+itemsize); goto bad; } - else if (check_size == __Pyx_ImportType_CheckSize_Warn_3_2_2 && (size_t)basicsize > size) { + else if (check_size == __Pyx_ImportType_CheckSize_Warn_3_2_3 && (size_t)basicsize > size) { if (PyErr_WarnFormat(NULL, 0, "%.200s.%.200s size changed, may indicate binary incompatibility. " "Expected %zd from C header, got %zd from PyObject", diff --git a/oceanmesh/mesh_generator.py b/oceanmesh/mesh_generator.py index d866b2f..deafa73 100644 --- a/oceanmesh/mesh_generator.py +++ b/oceanmesh/mesh_generator.py @@ -310,30 +310,17 @@ def _check_bbox(bbox): assert int(len(bbox) / 2), "`dim` must be 2" -def _validate_multiscale_domains(domains, edge_lengths): # noqa: C901 - """Validate domain & sizing function compatibility for multiscale meshing. - - Checks performed: - 1. Presence of CRS on all domains. - 2. Global domain (stereo=True) ordering: must be first if present. - 3. Bbox containment for regional domains within global domain when mixing. - 4. CRS compatibility (global EPSG:4326, regional geographic or projected). - 5. Edge length Grid CRS matches corresponding domain CRS. - 6. Stereo flag usage: only global domain should have stereo=True. +def _find_global_domain(domains, errors): + """Identify the global (stereo=True) domain if present. Returns ------- - (ok: bool, errors: list[str]) + global_domain: Domain | None """ - errors = [] - - if len(domains) != len(edge_lengths): - errors.append("Number of domains and edge_lengths differ.") - return False, errors - # Determine global domain (stereo=True) stereo_flags = [getattr(d, "stereo", False) for d in domains] global_indices = [i for i, s in enumerate(stereo_flags) if s] + global_domain = None if len(global_indices) > 1: errors.append("Only one global (stereo=True) domain permitted.") @@ -342,17 +329,12 @@ def _validate_multiscale_domains(domains, edge_lengths): # noqa: C901 errors.append("Global domain must be the first (coarsest) domain in list.") global_domain = domains[global_indices[0]] - # Helper flags for conditional CRS requirements - domain_crs_list = [getattr(d, "crs", None) for d in domains] - edge_crs_list = [ - getattr(el, "crs", None) if hasattr(el, "crs") else None for el in edge_lengths - ] - has_any_crs = any(c is not None for c in domain_crs_list) or any( - c is not None for c in edge_crs_list - ) + return global_domain + + +def _detect_implicit_global_domain(domains): + """Detect implicit global-like domain: EPSG:4326 + global bbox but stereo=False.""" - # Detect implicit global domain: EPSG:4326 + global-like bbox but stereo=False - implicit_global_idx = None for i, d in enumerate(domains): dcrs = getattr(d, "crs", None) try: @@ -361,135 +343,225 @@ def _validate_multiscale_domains(domains, edge_lengths): # noqa: C901 and CRS.from_user_input(dcrs).to_epsg() == 4326 and is_global_bbox(d.bbox) ): - implicit_global_idx = i - break + return i except Exception: # If CRS can't be parsed, skip implicit detection for this domain - pass + continue + return None - # If no CRS anywhere and no implicit global detected, allow bbox-only flows without error - if has_any_crs or implicit_global_idx is not None: - # Now missing CRS becomes an error because compatibility checks are required - for i, d in enumerate(domains): - if getattr(d, "crs", None) is None: + +def _has_any_crs_metadata(domains, edge_lengths): + domain_crs_list = [getattr(d, "crs", None) for d in domains] + edge_crs_list = [ + getattr(el, "crs", None) if hasattr(el, "crs") else None for el in edge_lengths + ] + return any(c is not None for c in domain_crs_list) or any( + c is not None for c in edge_crs_list + ) + + +def _validate_crs_presence(domains, errors): + for i, d in enumerate(domains): + if getattr(d, "crs", None) is None: + errors.append( + f"Domain #{i} missing CRS metadata. Provide CRS via Shoreline(crs=...) to enable compatibility checks." + ) + + +def _validate_global_domain_and_regions(global_domain, domains, errors): + """Validate CRS requirements, containment, and CRS mixing rules when a global domain is present.""" + + gcrs = getattr(global_domain, "crs", None) + if gcrs is not None: + try: + gcrs_str = get_crs_string(gcrs) + except Exception: + gcrs_str = str(gcrs) + + # Explicitly require global CRS be EPSG:4326 + try: + parsed = CRS.from_user_input(gcrs) + if parsed.to_epsg() != 4326: errors.append( - f"Domain #{i} missing CRS metadata. Provide CRS via Shoreline(crs=...) to enable compatibility checks." + f"Global domain CRS {gcrs_str} must be EPSG:4326 for global+regional multiscale meshing." ) + except Exception: + errors.append( + f"Global domain CRS '{gcrs_str}' could not be parsed; expected EPSG:4326." + ) - # If we have a global domain, validate CRS and containment - if global_domain is not None: - gcrs = getattr(global_domain, "crs", None) - if gcrs is not None: - try: - gcrs_str = get_crs_string(gcrs) - except Exception: - gcrs_str = str(gcrs) - # Explicitly require global CRS be EPSG:4326 - try: - parsed = CRS.from_user_input(gcrs) - if parsed.to_epsg() != 4326: - errors.append( - f"Global domain CRS {gcrs_str} must be EPSG:4326 for global+regional multiscale meshing." - ) - except Exception: - errors.append( - f"Global domain CRS '{gcrs_str}' could not be parsed; expected EPSG:4326." + # Containment checks + regional stereo checks + CRS compatibility + for i, d in enumerate(domains[1:], start=1): + g_bbox = global_domain.bbox + d_bbox = d.bbox + try: + if getattr(global_domain, "stereo", False): + lon_min, lon_max, lat_min, lat_max = d_bbox + reg_corners_lon = [lon_min, lon_max, lon_max, lon_min] + reg_corners_lat = [lat_min, lat_min, lat_max, lat_max] + sx, sy = to_stereo(np.array(reg_corners_lon), np.array(reg_corners_lat)) + stereo_reg_bbox = ( + float(np.min(sx)), + float(np.max(sx)), + float(np.min(sy)), + float(np.max(sy)), ) - # Containment checks for regional domains - for i, d in enumerate(domains[1:], start=1): - # Perform containment in lat/lon if global stereographic domain provided its bbox in stereo space - g_bbox = global_domain.bbox - d_bbox = d.bbox - try: - if getattr(global_domain, "stereo", False): - # Convert regional bbox corners to stereo then compare - lon_min, lon_max, lat_min, lat_max = d_bbox - reg_corners_lon = [lon_min, lon_max, lon_max, lon_min] - reg_corners_lat = [lat_min, lat_min, lat_max, lat_max] - sx, sy = to_stereo( - np.array(reg_corners_lon), np.array(reg_corners_lat) + if not bbox_contains(g_bbox, stereo_reg_bbox): + errors.append( + f"Regional domain #{i} bbox {d_bbox} (lat/lon) not contained within global stereo bbox {g_bbox}." ) - stereo_reg_bbox = ( - float(np.min(sx)), - float(np.max(sx)), - float(np.min(sy)), - float(np.max(sy)), + else: + if not bbox_contains(g_bbox, d_bbox): + errors.append( + f"Regional domain #{i} bbox {d_bbox} not contained within global bbox {g_bbox}." ) - if not bbox_contains(g_bbox, stereo_reg_bbox): - errors.append( - f"Regional domain #{i} bbox {d_bbox} (lat/lon) not contained within global stereo bbox {g_bbox}." - ) - else: - if not bbox_contains(g_bbox, d_bbox): - errors.append( - f"Regional domain #{i} bbox {d_bbox} not contained within global bbox {g_bbox}." - ) - except Exception: + except Exception: + errors.append( + f"Regional domain #{i} containment check failed due to transformation error; verify CRS and stereo settings." + ) + + if getattr(d, "stereo", False): + errors.append( + f"Regional domain #{i} has stereo=True; only the global domain may set stereo=True." + ) + + ok_crs, msg_crs = validate_crs_compatible( + getattr(global_domain, "crs", None), getattr(d, "crs", None) + ) + if not ok_crs: + errors.append(msg_crs) + + +def _validate_implicit_global_mixing(domains, implicit_global_idx, errors): + """Warn/error when a global-like EPSG:4326 domain is mixed with other CRSs without stereo=True.""" + + ig = domains[implicit_global_idx] + if getattr(ig, "stereo", False): + return + + try: + ig_crs = ( + CRS.from_user_input(ig.crs) + if getattr(ig, "crs", None) is not None + else None + ) + for j, d in enumerate(domains): + if j == implicit_global_idx: + continue + dcrs = getattr(d, "crs", None) + if dcrs is None or ig_crs is None: + continue + if not ig_crs.equals(CRS.from_user_input(dcrs)): errors.append( - f"Regional domain #{i} containment check failed due to transformation error; verify CRS and stereo settings." + "Detected global-like EPSG:4326 domain without stereo=True mixed with other CRS. " + "Set stereo=True on the global domain and place it first in the list." ) - # Stereo flag must be False for regional domains - if getattr(d, "stereo", False): + break + except Exception: + # If CRS parsing fails, skip this implicit enforcement + return + + +def _validate_edge_length_crs(domains, edge_lengths, errors): + for i, (d, el) in enumerate(zip(domains, edge_lengths)): + if not hasattr(el, "crs"): + continue + + el_crs = getattr(el, "crs", None) + d_crs = getattr(d, "crs", None) + if el_crs is None or d_crs is None: + continue + + try: + if not CRS.from_user_input(el_crs).equals(CRS.from_user_input(d_crs)): errors.append( - f"Regional domain #{i} has stereo=True; only the global domain may set stereo=True." + f"Edge length #{i} CRS {get_crs_string(el_crs)} does not match domain CRS {get_crs_string(d_crs)}." ) - # CRS compatibility between global and regional - ok_crs, msg_crs = validate_crs_compatible( - getattr(global_domain, "crs", None), getattr(d, "crs", None) + except Exception: + errors.append( + f"Edge length #{i} CRS could not be compared to domain CRS (el={get_crs_string(el_crs)}, domain={get_crs_string(d_crs)})." ) - if not ok_crs: - errors.append(msg_crs) + + +def _validate_multiscale_domains(domains, edge_lengths): # noqa: C901 + """Validate domain & sizing function compatibility for multiscale meshing. + + Checks performed: + 1. Presence of CRS on all domains. + 2. Global domain (stereo=True) ordering: must be first if present. + 3. Bbox containment for regional domains within global domain when mixing. + 4. CRS compatibility (global EPSG:4326, regional geographic or projected). + 5. Edge length Grid CRS matches corresponding domain CRS. + 6. Stereo flag usage: only global domain should have stereo=True. + + Returns + ------- + (ok: bool, errors: list[str]) + """ + errors = [] + + if len(domains) != len(edge_lengths): + errors.append("Number of domains and edge_lengths differ.") + return False, errors + + global_domain = _find_global_domain(domains, errors) + implicit_global_idx = _detect_implicit_global_domain(domains) + has_any_crs = _has_any_crs_metadata(domains, edge_lengths) + + # If no CRS anywhere and no implicit global detected, allow bbox-only flows without error + if has_any_crs or implicit_global_idx is not None: + _validate_crs_presence(domains, errors) + + # If we have a global domain, validate CRS and containment + if global_domain is not None: + _validate_global_domain_and_regions(global_domain, domains, errors) # Implicit global-like domain with EPSG:4326 but stereo=False mixing with different CRS if implicit_global_idx is not None: - ig = domains[implicit_global_idx] - if not getattr(ig, "stereo", False): - # If any other domain has a CRS that is not equal to EPSG:4326, require stereo=True and ordering - try: - ig_crs = ( - CRS.from_user_input(ig.crs) - if getattr(ig, "crs", None) is not None - else None - ) - for j, d in enumerate(domains): - if j == implicit_global_idx: - continue - dcrs = getattr(d, "crs", None) - if dcrs is None: - continue - if ig_crs is None: - continue - if not ig_crs.equals(CRS.from_user_input(dcrs)): - errors.append( - "Detected global-like EPSG:4326 domain without stereo=True mixed with other CRS. " - "Set stereo=True on the global domain and place it first in the list." - ) - break - except Exception: - # If CRS parsing fails, skip this implicit enforcement - pass + _validate_implicit_global_mixing(domains, implicit_global_idx, errors) # Edge length CRS matching - for i, (d, el) in enumerate(zip(domains, edge_lengths)): - if hasattr(el, "crs"): - el_crs = getattr(el, "crs", None) - d_crs = getattr(d, "crs", None) - if el_crs is not None and d_crs is not None: - try: - if not CRS.from_user_input(el_crs).equals( - CRS.from_user_input(d_crs) - ): - errors.append( - f"Edge length #{i} CRS {get_crs_string(el_crs)} does not match domain CRS {get_crs_string(d_crs)}." - ) - except Exception: - errors.append( - f"Edge length #{i} CRS could not be compared to domain CRS (el={get_crs_string(el_crs)}, domain={get_crs_string(d_crs)})." - ) + _validate_edge_length_crs(domains, edge_lengths, errors) return len(errors) == 0, errors +def _sanitize_smoothed_sizing_grids(edge_lengths_smoothed): + """Ensure each smoothed sizing Grid has a positive finite hmin. + + The multiscale sizing blender can produce Grid objects with missing/invalid + `hmin`. This helper recomputes `hmin` from the underlying grid values. + """ + + for i, el in enumerate(edge_lengths_smoothed): + _sanitize_smoothed_sizing_grid(i, el) + + +def _sanitize_smoothed_sizing_grid(i, el): + if not isinstance(el, Grid): + return + + hmin = getattr(el, "hmin", None) + if hmin is not None and np.isfinite(hmin) and hmin > 0: + return + + vals = el.values + if np.ma.isMaskedArray(vals): + vals = np.ma.filled(vals, np.nan) + vals = np.asarray(vals) + pos = vals[np.isfinite(vals) & (vals > 0)] + if pos.size > 0: + el.hmin = float(np.nanmin(pos)) + logger.warning( + f"Sizing grid #{i} had invalid hmin; recomputed fallback hmin={el.hmin:.3f}" + ) + return + + raise ValueError( + f"Sizing grid #{i} contains no positive values to determine a minimum edge length." + ) + + # NOTE: stereo-aware sizing wrapper removed per verification comment; sizing # functions are always evaluated on lat/lon points supplied by generate_mesh. @@ -561,7 +633,7 @@ def generate_multiscale_mesh(domains, edge_lengths, **kwargs): Notes ----- * Regional-only multiscale meshing (no global domain) requires all domains share a compatible CRS. - * Global+regional meshing follows a two-step workflow: sizing in WGS84, global meshing in stereographic space. + * Global+regional meshing follows a two-step workflow: sizing in EPSG:4326, global meshing in stereographic space. * Validation errors provide detailed guidance (CRS mismatches, bbox containment, stereo flag misuse). * Domain metadata (CRS, stereo flags) is collected internally to manage automatic coordinate transformations. @@ -593,7 +665,7 @@ def generate_multiscale_mesh(domains, edge_lengths, **kwargs): "blend_polynomial": 2, "blend_max_iter": 20, "blend_nnear": 256, - "lock_boundary": False, + "lock_boundary": True, } opts.update(kwargs) _parse_kwargs(kwargs) @@ -613,25 +685,8 @@ def generate_multiscale_mesh(domains, edge_lengths, **kwargs): p=opts["blend_polynomial"], domain_metadata=domain_metadata, ) - # Sanitize hmin on each smoothed sizing grid to ensure positivity - for i, el in enumerate(edge_lengths_smoothed): - if isinstance(el, Grid): - hmin = getattr(el, "hmin", None) - if hmin is None or not np.isfinite(hmin) or hmin <= 0: - vals = el.values - if np.ma.isMaskedArray(vals): - vals = np.ma.filled(vals, np.nan) - vals = np.asarray(vals) - pos = vals[np.isfinite(vals) & (vals > 0)] - if pos.size > 0: - el.hmin = float(np.nanmin(pos)) - logger.warning( - f"Sizing grid #{i} had invalid hmin; recomputed fallback hmin={el.hmin:.3f}" - ) - else: - raise ValueError( - f"Sizing grid #{i} contains no positive values to determine a minimum edge length." - ) + + _sanitize_smoothed_sizing_grids(edge_lengths_smoothed) union, nests = multiscale_signed_distance_function(domains) _p = [] global_minimum = 9999 @@ -744,7 +799,7 @@ def generate_mesh(domain, edge_length, **kwargs): geps = 1e-3 * np.amin(min_edge_length) deps = np.sqrt(np.finfo(np.double).eps) # * np.amin(min_edge_length) - pfix, nfix = _unpack_pfix(_DIM, opts) + pfix, _nfix = _unpack_pfix(_DIM, opts) lock_boundary = opts["lock_boundary"] if opts["points"] is None: @@ -777,18 +832,17 @@ def generate_mesh(domain, edge_length, **kwargs): # Get the current topology of the triangulation p, t = _get_topology(dt) - ifix = [] + fixed_indices = [] if lock_boundary: _, bpts = _external_topology(p, t) for fix in bpts: - ifix.append(_closest_node(fix, p)) - nfix = len(ifix) + fixed_indices.append(_closest_node(fix, p)) # Find where pfix went - if nfix > 0: + if len(pfix) > 0: for fix in pfix: ind = _closest_node(fix, p) - ifix.append(ind) + fixed_indices.append(ind) p[ind] = fix # Remove points outside the domain @@ -804,7 +858,9 @@ def generate_mesh(domain, edge_length, **kwargs): Ftot = _compute_forces(p, t, fh, min_edge_length, L0mult, opts) # Force = 0 at fixed points - Ftot[:nfix] = 0 + if fixed_indices: + fixed_indices = np.unique(np.asarray(fixed_indices, dtype=int)) + Ftot[fixed_indices] = 0 # Update positions p += delta_t * Ftot diff --git a/pyproject.toml b/pyproject.toml index e9a0876..e5cba9b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,3 +11,17 @@ build-backend = "setuptools.build_meta" [tool.black] target-version = ['py310'] + +[tool.cibuildwheel] +# Build wheels for CPython 3.10–3.12 (can expand once deps support newer Pythons) +build = "cp310-* cp311-* cp312-*" +skip = "pp* *-musllinux_*" + +[tool.cibuildwheel.linux] +archs = ["x86_64"] + +[tool.cibuildwheel.macos] +archs = ["arm64", "x86_64"] + +[tool.cibuildwheel.windows] +archs = ["AMD64"] diff --git a/setup.py b/setup.py index 4b1bfed..fde2489 100644 --- a/setup.py +++ b/setup.py @@ -2,12 +2,29 @@ import sys import configparser -import numpy as np -from pybind11.setup_helpers import Pybind11Extension, build_ext as pybind_build_ext +try: + import numpy as np + + _HAVE_NUMPY = True +except ModuleNotFoundError: # pragma: no cover + np = None + _HAVE_NUMPY = False from setuptools import Extension, setup # , find_packages import versioneer +try: + from pybind11.setup_helpers import ( # pyright: ignore[reportMissingImports] + Pybind11Extension, + build_ext as pybind_build_ext, + ) + + _HAVE_PYBIND11 = True +except ModuleNotFoundError: # pragma: no cover + Pybind11Extension = None + pybind_build_ext = None + _HAVE_PYBIND11 = False + sys.path.append(os.path.dirname(__file__)) # Build system: This package uses pybind11's setuptools integration to compile @@ -28,43 +45,92 @@ "oceanmesh/cpp/fast_geometry.cpp", ] -if os.name == "nt": - home = os.environ["USERPROFILE"].replace("\\", "/") - vcpkg = f"{home}/OceanMesh/vcpkg/installed/x64-windows" - ext_modules = [ - Pybind11Extension( - loc, - [fi], - include_dirs=[f"{vcpkg}/include"], - extra_link_args=[f"/LIBPATH:{vcpkg}/lib"], - libraries=["gmp", "mpfr"], - ) - for fi, loc in zip(files, is_called) - ] -else: - # no CGAL libraries necessary from CGAL 5.0 onwards - # Ensure linker can find conda-provided lib paths on macOS/Linux - conda_prefix = os.environ.get("CONDA_PREFIX", sys.prefix) - conda_lib = os.path.join(conda_prefix, "lib") - have_libdir = os.path.isdir(conda_lib) - - extra_link_args = [] - library_dirs = [] - if have_libdir: - library_dirs = [conda_lib] - # Help the linker locate shared libs at build and at runtime - extra_link_args = [f"-L{conda_lib}", f"-Wl,-rpath,{conda_lib}"] - - ext_modules = [ - Pybind11Extension( - loc, - [fi], - libraries=["gmp", "mpfr"], - library_dirs=library_dirs, - extra_link_args=extra_link_args, - ) - for fi, loc in zip(files, is_called) - ] + +ext_modules = [] + + +def _get_prefix_paths(prefix: str): + if not prefix: + return None, None + + include_dir = os.path.join(prefix, "include") + lib_dir = os.path.join(prefix, "lib") + + have_include = os.path.isdir(include_dir) + have_lib = os.path.isdir(lib_dir) + + return (include_dir if have_include else None), (lib_dir if have_lib else None) + + +if _HAVE_PYBIND11: + if os.name == "nt": + # Prefer an explicit prefix when building wheels (e.g., via micromamba/conda). + # This avoids hard-coding a developer-specific vcpkg location. + prefix = os.environ.get("OCEANMESH_PREFIX") or os.environ.get("CONDA_PREFIX") + include_dir, lib_dir = _get_prefix_paths(prefix) + + if include_dir and lib_dir: + ext_modules = [ + Pybind11Extension( + loc, + [fi], + include_dirs=[include_dir], + library_dirs=[lib_dir], + extra_link_args=[f"/LIBPATH:{lib_dir}"], + libraries=["gmp", "mpfr"], + ) + for fi, loc in zip(files, is_called) + ] + else: + home = os.environ.get("USERPROFILE", "").replace("\\", "/") + vcpkg_root = os.environ.get("VCPKG_ROOT") or os.environ.get( + "VCPKG_INSTALLATION_ROOT" + ) + if vcpkg_root: + vcpkg_root = vcpkg_root.replace("\\", "/") + vcpkg = f"{vcpkg_root}/installed/x64-windows" + else: + vcpkg = f"{home}/OceanMesh/vcpkg/installed/x64-windows" + + ext_modules = [ + Pybind11Extension( + loc, + [fi], + include_dirs=[f"{vcpkg}/include"], + extra_link_args=[f"/LIBPATH:{vcpkg}/lib"], + libraries=["gmp", "mpfr"], + ) + for fi, loc in zip(files, is_called) + ] + else: + # no CGAL libraries necessary from CGAL 5.0 onwards + # Ensure compiler/linker can find dependency headers and libs when building + # wheels (CI) without requiring system-wide installs. + prefix = os.environ.get("OCEANMESH_PREFIX") or os.environ.get("CONDA_PREFIX") + include_dir, lib_dir = _get_prefix_paths(prefix) + + include_dirs = [] + library_dirs = [] + extra_link_args = [] + + if include_dir: + include_dirs.append(include_dir) + + if lib_dir: + library_dirs.append(lib_dir) + extra_link_args.extend([f"-L{lib_dir}", f"-Wl,-rpath,{lib_dir}"]) + + ext_modules = [ + Pybind11Extension( + loc, + [fi], + include_dirs=include_dirs, + libraries=["gmp", "mpfr"], + library_dirs=library_dirs, + extra_link_args=extra_link_args, + ) + for fi, loc in zip(files, is_called) + ] def maybe_add_cython_extensions(): @@ -76,6 +142,9 @@ def maybe_add_cython_extensions(): the build proceeds without the accelerated kernel. """ + if not _HAVE_NUMPY: + return [] + from pathlib import Path src_dir = Path(__file__).parent / "oceanmesh" / "geometry" @@ -107,7 +176,21 @@ def maybe_add_cython_extensions(): cmdclass = versioneer.get_cmdclass() -cmdclass.update({"build_ext": pybind_build_ext}) + +if _HAVE_PYBIND11: + cmdclass.update({"build_ext": pybind_build_ext}) +else: + from setuptools.command.build_ext import build_ext as _setuptools_build_ext + + class build_ext(_setuptools_build_ext): + def run(self): + raise ModuleNotFoundError( + "pybind11 is required to build oceanmesh C++ extensions. " + "Install it (e.g. `python -m pip install pybind11`) or build via PEP 517 " + "so build dependencies are installed automatically." + ) + + cmdclass.update({"build_ext": build_ext}) def get_requirements(): diff --git a/tests/test_multiscale.py b/tests/test_multiscale.py index b3ff24f..f1363ff 100644 --- a/tests/test_multiscale.py +++ b/tests/test_multiscale.py @@ -1,8 +1,5 @@ import os -import matplotlib.gridspec as gridspec -import matplotlib.pyplot as plt -import matplotlib.tri as tri import numpy as np import oceanmesh as om @@ -59,46 +56,16 @@ def test_multiscale_overlap(): # Control the element size transition # from coarse to fine with the kwargs prefixed with `blend` points, cells = om.generate_multiscale_mesh( - [sdf1, sdf2, sdf3], [el1, el2, el3], blend_width=1000, blend_max_iter=100 + [sdf1, sdf2, sdf3], + [el1, el2, el3], + blend_width=1000, + max_iter=5, + blend_max_iter=5, ) - # remove degenerate mesh faces and other common problems in the mesh - points, cells = om.make_mesh_boundaries_traversable(points, cells) - # remove singly connected elements (elements - # connected to only one other element) - points, cells = om.delete_faces_connected_to_one_face(points, cells) - # remove poor boundary elements with quality < 15% - points, cells = om.delete_boundary_faces(points, cells, min_qual=0.15) - # apply a Laplacian smoother that preservers the mesh size distribution - points, cells = om.laplacian2(points, cells) - - triang = tri.Triangulation(points[:, 0], points[:, 1], cells) - gs = gridspec.GridSpec(3, 1) - gs.update(wspace=0.1) - plt.figure(figsize=[4.8, 6.4]) - - ax = plt.subplot(gs[0, 0]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") - ax.plot(bbox3[:, 0], bbox3[:, 1], "r--") - - ax = plt.subplot(gs[1, 0]) - buf = 0.07 - ax.set_xlim([min(bbox2[:, 0]) - buf, max(bbox2[:, 0]) + buf]) - ax.set_ylim([min(bbox2[:, 1]) - buf, max(bbox2[:, 1]) + buf]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") - - ax = plt.subplot(gs[2, 0]) - buf = 0.07 - ax.set_xlim([min(bbox3[:, 0]) - buf, max(bbox3[:, 0]) + buf]) - ax.set_ylim([min(bbox3[:, 1]) - buf, max(bbox3[:, 1]) + buf]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox3[:, 0], bbox3[:, 1], "r--") - - plt.show() + assert points.ndim == 2 and points.shape[1] == 2 + assert cells.ndim == 2 and cells.shape[1] == 3 + assert len(points) > 0 + assert len(cells) > 0 def test_multiscale_non_overlap(): @@ -150,43 +117,13 @@ def test_multiscale_non_overlap(): # coarse to fine with the kwargs prefixed with `blend`. # Function objects must appear in order of descending `min_edge_length`. points, cells = om.generate_multiscale_mesh( - [sdf1, sdf2, sdf3], [el1, el2, el3], blend_width=1000, blend_max_iter=100 + [sdf1, sdf2, sdf3], + [el1, el2, el3], + blend_width=1000, + max_iter=5, + blend_max_iter=5, ) - # remove degenerate mesh faces and other common problems in the mesh - points, cells = om.make_mesh_boundaries_traversable(points, cells) - # remove singly connected elements (elements - # connected to only one other element) - points, cells = om.delete_faces_connected_to_one_face(points, cells) - # remove poor boundary elements with quality < 15% - points, cells = om.delete_boundary_faces(points, cells, min_qual=0.15) - # apply a Laplacian smoother that preservers the mesh size distribution - points, cells = om.laplacian2(points, cells) - - triang = tri.Triangulation(points[:, 0], points[:, 1], cells) - gs = gridspec.GridSpec(3, 1) - gs.update(wspace=0.1) - plt.figure(figsize=[4.8, 6.4]) - - ax = plt.subplot(gs[0, 0]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") - ax.plot(bbox3[:, 0], bbox3[:, 1], "r--") - - ax = plt.subplot(gs[1, 0]) - buf = 0.07 - ax.set_xlim([min(bbox2[:, 0]) - buf, max(bbox2[:, 0]) + buf]) - ax.set_ylim([min(bbox2[:, 1]) - buf, max(bbox2[:, 1]) + buf]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox2[:, 0], bbox2[:, 1], "r--") - - ax = plt.subplot(gs[2, 0]) - buf = 0.07 - ax.set_xlim([min(bbox3[:, 0]) - buf, max(bbox3[:, 0]) + buf]) - ax.set_ylim([min(bbox3[:, 1]) - buf, max(bbox3[:, 1]) + buf]) - ax.set_aspect("equal") - ax.triplot(triang, "-", lw=0.5) - ax.plot(bbox3[:, 0], bbox3[:, 1], "r--") - - plt.show() + assert points.ndim == 2 and points.shape[1] == 2 + assert cells.ndim == 2 and cells.shape[1] == 3 + assert len(points) > 0 + assert len(cells) > 0 diff --git a/tools/build_deps_linux.sh b/tools/build_deps_linux.sh new file mode 100644 index 0000000..8436ca9 --- /dev/null +++ b/tools/build_deps_linux.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +set -euxo pipefail + +PREFIX="${1:-/opt/om}" + +GMP_VERSION="6.3.0" +MPFR_VERSION="4.2.1" + +GMP_URL="https://ftp.gnu.org/gnu/gmp/gmp-${GMP_VERSION}.tar.xz" +MPFR_URL="https://ftp.gnu.org/gnu/mpfr/mpfr-${MPFR_VERSION}.tar.xz" + +install_build_prereqs() { + if command -v yum >/dev/null 2>&1; then + yum -y install m4 + elif command -v dnf >/dev/null 2>&1; then + dnf -y install m4 + else + echo "Neither yum nor dnf found; cannot install build prerequisites" >&2 + exit 2 + fi +} + +build_one() { + local name="$1" + local version="$2" + local url="$3" + + local workdir + workdir="/tmp/build-${name}" + rm -rf "$workdir" + mkdir -p "$workdir" + pushd "$workdir" >/dev/null + + curl -fsSL "$url" -o "${name}-${version}.tar.xz" + tar -xf "${name}-${version}.tar.xz" + + pushd "${name}-${version}" >/dev/null + + if [ "$name" = "gmp" ]; then + ./configure \ + --prefix="$PREFIX" \ + --enable-shared \ + --disable-static \ + --enable-cxx \ + --with-pic + elif [ "$name" = "mpfr" ]; then + ./configure \ + --prefix="$PREFIX" \ + --with-gmp="$PREFIX" \ + --enable-shared \ + --disable-static \ + --with-pic + else + echo "Unknown dep: $name" >&2 + exit 2 + fi + + make -j"$(nproc)" + make install + + popd >/dev/null + popd >/dev/null +} + +mkdir -p "$PREFIX" +install_build_prereqs + +build_one gmp "$GMP_VERSION" "$GMP_URL" +build_one mpfr "$MPFR_VERSION" "$MPFR_URL" + +echo "Built deps installed into: $PREFIX" +ls -la "$PREFIX/lib" | head diff --git a/tools/verify_manylinux_wheels.py b/tools/verify_manylinux_wheels.py new file mode 100644 index 0000000..4996476 --- /dev/null +++ b/tools/verify_manylinux_wheels.py @@ -0,0 +1,111 @@ +from __future__ import annotations + +import argparse +import re +import subprocess +import sys +import zipfile +from pathlib import Path + + +def _parse_glibc_symbols(auditwheel_verbose_output: str) -> tuple[int, int] | None: + matches = re.findall(r"GLIBC_(\d+)\.(\d+)", auditwheel_verbose_output) + if not matches: + return None + versions = [(int(major), int(minor)) for major, minor in matches] + return max(versions) + + +def _run_auditwheel_show_verbose(wheel_path: Path) -> str: + return subprocess.check_output( + [sys.executable, "-m", "auditwheel", "show", "-v", str(wheel_path)], + text=True, + stderr=subprocess.STDOUT, + ) + + +def _wheel_contains_shared_lib(wheel_path: Path, needle: str) -> bool: + # auditwheel typically vendors libs under something like: + # .libs/libgmp-....so + # so we just search for the substring in zip members. + with zipfile.ZipFile(wheel_path, "r") as zf: + for name in zf.namelist(): + # Bundled libs are commonly version-suffixed (e.g. .so.10, .so.6). + if needle in name and ".so" in name: + return True + return False + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument( + "dist_dir", + type=Path, + help="Directory containing built wheels (e.g. dist/)", + ) + parser.add_argument( + "--max-glibc", + default="2.28", + help="Maximum allowed GLIBC symbol version (default: 2.28)", + ) + args = parser.parse_args() + + max_glibc_parts = args.max_glibc.split(".") + if len(max_glibc_parts) != 2: + raise SystemExit("--max-glibc must look like '2.28'") + + max_allowed = (int(max_glibc_parts[0]), int(max_glibc_parts[1])) + + wheels = sorted(args.dist_dir.glob("*.whl")) + linux_wheels = [ + w + for w in wheels + if "linux" in w.name and "x86_64" in w.name and "musllinux" not in w.name + ] + + if not linux_wheels: + raise SystemExit(f"No Linux x86_64 wheels found in {args.dist_dir}") + + failed = False + + for wheel in linux_wheels: + print(f"\n=== Checking wheel: {wheel.name} ===") + + if "manylinux" not in wheel.name: + print("ERROR: wheel filename does not include a manylinux tag") + failed = True + + if "linux_x86_64" in wheel.name and "manylinux" not in wheel.name: + print("ERROR: wheel appears to be plain linux_x86_64 (not manylinux)") + failed = True + + out = _run_auditwheel_show_verbose(wheel) + print(out) + + max_seen = _parse_glibc_symbols(out) + if max_seen is not None and max_seen > max_allowed: + print( + f"ERROR: wheel references too-new GLIBC symbols: " + f"max seen GLIBC_{max_seen[0]}.{max_seen[1]} > allowed GLIBC_{max_allowed[0]}.{max_allowed[1]}" + ) + failed = True + + # Ensure auditwheel actually bundled GMP/MPFR into the wheel + has_gmp = _wheel_contains_shared_lib(wheel, "libgmp") + has_mpfr = _wheel_contains_shared_lib(wheel, "libmpfr") + + if not has_gmp: + print("ERROR: bundled libgmp*.so not found inside wheel") + failed = True + if not has_mpfr: + print("ERROR: bundled libmpfr*.so not found inside wheel") + failed = True + + if has_gmp and has_mpfr: + print("OK: wheel contains bundled libgmp + libmpfr") + + return 1 if failed else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tox.ini b/tox.ini index 6397912..bf9bf9a 100644 --- a/tox.ini +++ b/tox.ini @@ -1,17 +1,30 @@ -# usage: -# tox --> default, runs pytest - [tox] -envlist = py3 +envlist = py{310,311,312,313} isolated_build = True [testenv] deps = pytest - pytest-codeblocks - requests extras = all +passenv = + CONDA_PREFIX + OCEANMESH_PREFIX + OCEANMESH_REQUIRE_INPOLY_ACCEL + OCEANMESH_INPOLY_ACCEL_DEBUG + OCEANMESH_INPOLY_ACCEL + OCEANMESH_INPOLY_METHOD setenv = MPLBACKEND = agg + OCEANMESH_PREFIX = {env:CONDA_PREFIX:} commands = - pytest {posargs} -v --codeblocks + python -c "import sys; print('tox python:', sys.version)" + python -c "import os; import oceanmesh.geometry.point_in_polygon as p; ok=bool(getattr(p,'_COMPILED_KERNEL_AVAILABLE', False)); print('inpoly compiled:', ok); req=os.environ.get('OCEANMESH_REQUIRE_INPOLY_ACCEL','0').strip().lower() not in {'0','false','no','off',''}; \ + (not req or ok) or (_ for _ in ()).throw(SystemExit('OCEANMESH_REQUIRE_INPOLY_ACCEL=1 but compiled inpoly kernel is unavailable'))" + pytest {posargs} -v + +[testenv:.pkg] +passenv = + CONDA_PREFIX + OCEANMESH_PREFIX +setenv = + OCEANMESH_PREFIX = {env:CONDA_PREFIX:} \ No newline at end of file