diff --git a/.gitignore b/.gitignore index 7ead58b674d77f1e0a8365223a6782df4aa527e4..2af88e4f7f93d36d627c391f55ad9e4c64c4657c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /build/ /temp/ +/dist/ __pycache__ *.egg-info *temp.* \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..f387824b29f237d0e986b7cde4590c3a359a41dd --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,42 @@ +image: ubuntu:latest + +stages: + - code_embed + +variables: + GIT_STRATEGY: clone + +code_embedder: + stage: code_embed + script: + - echo "Personal a" + - cd code-embedder/ + - poetry install --only main + - README_PATHS=$(find .. -maxdepth 1 -name "*.md" -print) + - poetry run python ./src/main.py --readme-paths $README_PATHS + - cd .. + - README_PATHS=$(find . -maxdepth 1 -name "*.md" -print) + - git add $README_PATHS + - git diff --staged + - export BRANCH_NAME="${CI_MERGE_REQUEST_SOURCE_BRANCH_NAME:-$CI_COMMIT_REF_NAME}" + - echo "branch name $BRANCH_NAME" + - git remote set-url origin "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" + - echo "https://oauth2:${PERSONAL_ACCESS_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" + - if ! git diff --cached --exit-code; then + git commit -m "Apply Code Embedder"; + git push origin HEAD:$BRANCH_NAME; + else + echo "No changes to commit"; + fi + + before_script: + - apt-get update && apt-get install -y curl git python3 python3-pip + - curl -sSL https://install.python-poetry.org | python3 - + - export PATH="$HOME/.local/bin:$PATH" + - git clone https://github.com/kvankova/code-embedder.git + - git config --global user.email $GITLAB_USER_EMAIL + - git config --global user.name $GITLAB_USER_NAME + only: + - merge_requests + + diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000000000000000000000000000000000..c8cfe3959183f8e9a50f83f54cd723f2dc9c252d --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.10 diff --git a/CyXTraX/common/__init__.py b/CyXTraX/common/__init__.py deleted file mode 100644 index 0bcec689802c3b6b143aec6f110b5b8d3c8ee4ee..0000000000000000000000000000000000000000 --- a/CyXTraX/common/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .mesh_object import MeshObject \ No newline at end of file diff --git a/CyXTraX/common/mesh_object.py b/CyXTraX/common/mesh_object.py deleted file mode 100644 index df02eeb99f59da1facbb0c7e62702a88c93c9ac7..0000000000000000000000000000000000000000 --- a/CyXTraX/common/mesh_object.py +++ /dev/null @@ -1,23 +0,0 @@ -from dataclasses import dataclass -from pathlib import Path -import numpy as np - - -@dataclass -class MeshObject: - object_path: Path - position_mm: np.ndarray - orientation_quat: np.ndarray - - def as_dict(self): - return dict(object_path=str(self.object_path), - object_position=self.position_mm.astype(np.float64).tolist(), - object_orientation=self.orientation_quat.astype(np.float64).tolist()) - - @classmethod - def from_dict(cls: 'MeshObject', data_dict): - item = cls( - Path(data_dict['object_path']), - np.array(data_dict['object_position']), - np.array(data_dict['object_orientation'])) - return item \ No newline at end of file diff --git a/CyXTraX/data/__init__.py b/CyXTraX/data/__init__.py deleted file mode 100644 index b1d77652b80039a747b78e562d39d0e61c56a704..0000000000000000000000000000000000000000 --- a/CyXTraX/data/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import importlib.resources -import numpy as np -from ..common import MeshObject - - -with importlib.resources.path('CyXTraX.data', 'olaf_6.stl') as file_path: - olaf_stl = file_path - olaf_mesh = MeshObject(olaf_stl, - position_mm=np.array([1, 2, 3]), - orientation_quat=np.array([0., 0., 0., 1.])) - -with importlib.resources.path('CyXTraX.data', 'scones.stl') as file_path: - scones_stl = file_path - scones_mesh = MeshObject(scones_stl, - position_mm=np.array([0, 0, 0]), - orientation_quat=np.array([0., 0., 0., 1.])) \ No newline at end of file diff --git a/CyXTraX/io/__init__.py b/CyXTraX/io/__init__.py deleted file mode 100644 index 7ba211c6e3a0ef115cdd387bd8d8b4d82e7766b8..0000000000000000000000000000000000000000 --- a/CyXTraX/io/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .generate_atlas import record_atlas -from .load_maps import load_atlas \ No newline at end of file diff --git a/CyXTraX/io/generate_atlas.py b/CyXTraX/io/generate_atlas.py deleted file mode 100644 index 1df4b4fa98a68112e744c51af86a08ab2dae6808..0000000000000000000000000000000000000000 --- a/CyXTraX/io/generate_atlas.py +++ /dev/null @@ -1,58 +0,0 @@ -import numpy as np -import h5py -from CyXTraX.simulation.artist_bridge import CylindricalProjection -from CyXTraX.common.mesh_object import MeshObject -from pathlib import Path -import json - - - -def to_dict(mesh_object = MeshObject) -> dict: - return mesh_object.as_dict() - - -def record_atlas(cylindrical_projection: CylindricalProjection, mesh_list: list[MeshObject], - atlas_name: str, save_folder: Path, - map_bounding_box: tuple[float]=(-50., 50.), number_of_maps: int = 4) -> Path: - - grid = np.linspace(map_bounding_box[0], map_bounding_box[1], number_of_maps) - file_index = len(list(save_folder.glob('*.h5')))+1 - save_path = save_folder / f'{file_index:05}_{atlas_name}.h5' - file = h5py.File(save_path, 'a') - projection = file.require_dataset( - 'maps', - shape=(cylindrical_projection.x_px, cylindrical_projection.y_px, number_of_maps**3), # Initial shape with third dimension as 0 - maxshape=(cylindrical_projection.x_px, cylindrical_projection.y_px, number_of_maps**3), - dtype=np.float32) - - projection_points = file.require_dataset( - 'positions', - shape=(3, number_of_maps**3), # Initial shape with third dimension as 0 - maxshape=(3, number_of_maps**3), - dtype=np.float32) - - - mesh_list_dict = list(map(to_dict, mesh_list)) - print(mesh_list_dict) - - file.attrs['mesh_list'] = json.dumps(mesh_list_dict) - - - counter = 0 - for x in grid: - for y in grid: - for z in grid: - # x, y, z = 0, y, 0 - print(x, y, z) - position = np.array([x, y, z]) - - image = cylindrical_projection.compute_projection(position, output_full_ray_projection=True) - current_size = projection.shape[2] - new_size = current_size + 1 - #projection.resize((cylindrical_projection.x_px, cylindrical_projection.y_px, new_size)) - projection[:, :, counter:counter+1] = image[:, :, np.newaxis].astype(np.float32) - - #projection_points.resize((3, new_size)) - projection_points[:, counter:counter+1] = position.reshape((3, 1)) - counter += 1 - return save_path diff --git a/CyXTraX/mapping/__init__.py b/CyXTraX/mapping/__init__.py deleted file mode 100644 index 05cdb726d7dbc2a5899169dddc14c2db8c1b25e8..0000000000000000000000000000000000000000 --- a/CyXTraX/mapping/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .mapping import map_geometry_2_projection, map_source_2_cylinder \ No newline at end of file diff --git a/CyXTraX/mapping/mapping.py b/CyXTraX/mapping/mapping.py deleted file mode 100644 index 8a153a69e65c86030a7c36520d408e8940f761d6..0000000000000000000000000000000000000000 --- a/CyXTraX/mapping/mapping.py +++ /dev/null @@ -1,119 +0,0 @@ -from jax import numpy as jnp -import dm_pix as pix -from jax import jit, vmap -from jax.scipy.spatial.transform import Rotation - - - -@jit -def map_source_2_cylinder(source: jnp.ndarray, maps: jnp.ndarray, map_positions: jnp.ndarray, radius: float = 1000., - angle_discretisation: int = 2000, pitch: float = jnp.pi) -> tuple[jnp.ndarray, jnp.ndarray]: - """ - source: 1 x 3 - maps: u x v x m - map_positions: 3 x m - - --- - - cylinder_value: m x 1 - """ - - #map_positions = map_positions.T # m x 3 - - angles = cylindrical_angles(source, map_positions, radius, angle_discretisation, pitch) - - u = jnp.expand_dims(angles[0], 0) # 1 x m - v = jnp.expand_dims(angles[1], 0) # 1 x m - w = jnp.arange(0, maps.shape[2])[jnp.newaxis, ...] #+0.0001 # 1 x m - - uvw = jnp.concatenate([v, u , w], 0) # 3 x m - values = pix.flat_nd_linear_interpolate(maps, uvw) - - - return values, uvw # m, - -@jit -def cylindrical_angles(source: jnp.ndarray, map_positions: jnp.ndarray, radius: float = 1000., - angle_discretisation: int = 2000, pitch: float = jnp.pi) -> tuple[jnp.ndarray, jnp.ndarray]: - source = source.reshape((-1, 1)) # 1 x 3 - directions = map_positions - source # m x 3 - direction_norm_factor = jnp.linalg.norm(directions[:2], axis=0, keepdims=True) - directions = directions / direction_norm_factor # m x 3 - intersection = directions * radius - # sign = jnp.where(intersection[2]>=0, 1, -1) - # intersection = intersection * sign - - - z_value = intersection[2] / pitch - z = z_value + (angle_discretisation) / 2. - beta_value = (jnp.arctan2(intersection[0], intersection[1]) / jnp.pi) * angle_discretisation / 2 - beta = beta_value - ((angle_discretisation - 1.) / 4.) - angles = jnp.concatenate( - (jnp.expand_dims(z, 0) % 2000, - jnp.expand_dims(beta, 0) % 2000), - axis=0) - return angles - - -@jit -def map_geometry_2_projection(source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray, - map_positions: jnp.ndarray, - projections: jnp.ndarray, pixel_pitch_mm: float = 0.139): - """ - source: 1 x 3 - detector: 1 x 3 - detector_orientation: 1 x 4 - map_positions: 3 x m - projections: u x v - pixel_pitch_mm: 1, - - --- - - projection_value: m - """ - source = source.reshape((1, 3)) - detector = detector.reshape((1, 3)) - detector_orientation = detector_orientation.reshape((1, 4)) - - - projection_geometry = projection_matrix(source, detector, detector_orientation) # 3 x 4 - map_positions_homogen = jnp.ones((1, map_positions.shape[1])) # 1 x m - map_positions_homogen = jnp.concatenate((map_positions, map_positions_homogen), 0) # 4 x m - uv_px = projection_geometry @ map_positions_homogen # 3 x m - uv_px = uv_px / uv_px[2] - uv_px = uv_px / pixel_pitch_mm - uv_px = uv_px.at[0,:].multiply(-1) - uv_px = uv_px.at[0,:].add((projections.shape[-2])/ 2.) - # uv_px = uv_px.at[0,:].multiply(-1) - uv_px = uv_px.at[1,:].add((projections.shape[-2])/ 2.) - uv_px = uv_px[:2] - - uv_px_flip = jnp.flip(uv_px, 0) - # uv_px_flip = uv_px - - return pix.flat_nd_linear_interpolate(projections, uv_px_flip), uv_px - - -@jit -def projection_matrix(source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray - ) -> jnp.ndarray: - """ - source: 1 x 3 - detector: 1 x 3 - detector_orientation: 1 x 4 - - --- - - projection_matrix = 3 x 4 - """ - detector_orientation = detector_orientation / detector_orientation[1, 3] - rotation_matrix = Rotation.from_quat(detector_orientation).as_matrix() - detector_horizontal_vector = -rotation_matrix[0, :, 0] - detector_vertical_vector = -rotation_matrix[0, :, 1] - p3x3 = jnp.vstack([detector_horizontal_vector, - detector_vertical_vector, - (detector - source).reshape((-1, 3))]).T - p3x3_inv = jnp.linalg.inv(p3x3) - p4 = p3x3_inv @ (-source).reshape((3, 1)) - matrix = jnp.concatenate([p3x3_inv, p4], 1) # 3 x 4 - return matrix \ No newline at end of file diff --git a/CyXTraX/simulation/__init__.py b/CyXTraX/simulation/__init__.py deleted file mode 100644 index 320873fc56954f7ef06fb39d6212e32369f54dc5..0000000000000000000000000000000000000000 --- a/CyXTraX/simulation/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .artist_bridge import CylindricalProjection, load_mesh, SAVEMODES, utility \ No newline at end of file diff --git a/CyXTraX/simulation/model/__init__.py b/CyXTraX/simulation/model/__init__.py deleted file mode 100644 index ab04eac9c5d8225922a1310bae4c74e804e57956..0000000000000000000000000000000000000000 --- a/CyXTraX/simulation/model/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ - -from .augemtation_parameters import AugemntationParameter -from .noise import add_white_noise, add_gaussian_blur -from .xray import add_material \ No newline at end of file diff --git a/CyXTraX/util/datasets/__init__.py b/CyXTraX/util/datasets/__init__.py deleted file mode 100644 index 4a6739ff541d5191c1180f930897dff03e6b0b18..0000000000000000000000000000000000000000 --- a/CyXTraX/util/datasets/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .merge import merge_atlas_and_dict, merge_atlases, merge_lists -from .pipeline import generate_atlas_from_folder \ No newline at end of file diff --git a/CyXTraX/util/datasets/merge.py b/CyXTraX/util/datasets/merge.py deleted file mode 100644 index d1aae3f372d05fe00d83f006bdf9508e8a40eecb..0000000000000000000000000000000000000000 --- a/CyXTraX/util/datasets/merge.py +++ /dev/null @@ -1,14 +0,0 @@ -from jax import numpy as jnp -from CyXTraX.common.mesh_object import MeshObject - - -def merge_atlases(carry_atlas: jnp.ndarray, atlas: jnp.ndarray) -> jnp.ndarray: - return carry_atlas.at[:].add(atlas) / 2. - - -def merge_lists(carry_list: list, x: list) -> list: - return carry_list.extend(x) - - -def merge_atlas_and_dict(atlas_one, mesh_list_one, atlas_two, mesh_list_two) -> tuple[jnp.ndarray, list]: - return merge_atlases(atlas_one, atlas_two), merge_lists(mesh_list_one, mesh_list_two) diff --git a/CyXTraX/util/visualisation/__init__.py b/CyXTraX/util/visualisation/__init__.py deleted file mode 100644 index 589931f1beaaf10328afcd4cafd2efc5dbbd40c0..0000000000000000000000000000000000000000 --- a/CyXTraX/util/visualisation/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .plt import save_map_plot_with_index, voxel_cone_maps -from .gif import make_gif \ No newline at end of file diff --git a/README.md b/README.md index ceb674e2a9791581f475d5e06bccdf9b22a860c1..f102b30f9aa5766ae046b8fb5b0b53bba269e4fa 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,58 @@ The local cylindrical xray transform maps are stored as `.h5` file. +## Examples +Example files are from the `scripts` folder and directly included and updated via [CODE-EMBEDDER](https://github.com/kvankova/code-embedder). + +### Generate a Cylindrical Projection + +```python:../scripts/01_aRTist_bridge.py:s:A + # Create the cylindrical projection interface + cyl_proj = CylindricalProjection() + + + # Load the test object 'olaf'. It is automatically installed to your site-packages + print(f'STL Path: {scones_mesh.object_path}') + + # Obect are loaded in a dataclass: MeshObject. + print(f'Mesh is a MeshObject: {isinstance(scones_mesh, MeshObject)}') + scones_mesh.position_mm = np.array([0, 0, 0]) + scones_mesh.orientation_quat = np.array([0., -0., 0., 0.1]) + + + # The `load_mesh` function load a list of MeshObject + load_mesh(cyl_proj, [scones_mesh]) + + # Set local position of cylindrical projection + map_position = np.array([0, 0, 0]) + + # Generate local cylindrical projection + half_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=False) + full_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=True) +``` + + + +### Generate a Cylindrical Projection Atlas + +```python:../scripts/02_generate_atlas.py:s:A + # Create the cylindrical projection interface + cyl_proj = CylindricalProjection() + load_mesh(cyl_proj, [olaf_mesh]) + # make an atlas + + save_path = record_atlas(cyl_proj, [olaf_mesh], 'test', TEMP_FOLDER, + map_bounding_box=[-10, 20], number_of_maps=2) +``` + +### Load Atlas + +```python:../scripts/03_load_atlas.py:s:A + files = list(TEMP_FOLDER.glob('*.h5')) + if not files: + raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!') + + maps, points, mesh_object_list = load_atlas(files[-1]) +``` + + \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000000000000000000000000000000000..91b03059a663904a9640f16aaa0063e2b555978e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,35 @@ +[project] +name = "cyxtrax" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +authors = [ + { name = "swittl", email = "simon.wittl@th-deg.de" } +] +requires-python = ">=3.10" +dependencies = [ + "artistlib", + "dm-pix>=0.4.3", + "h5py>=3.12.1", + "jax>=0.4.35 ; sys_platform == 'windows'", + "jax[cuda12]>=0.4.35 ; sys_platform == 'linux'", + "matplotlib>=3.9.2", + "numpy>=2.1.3", + "ruff>=0.7.3", + "scipy>=1.14.1", + "xraylib>=4.1.5", +] + + +[tool.uv.sources] +artistlib = { git = "https://github.com/wittlsn/aRTist-PythonLib" } +cyxtrax = { workspace = true } + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.ruff] +exclude = [ + ".venv", +] diff --git a/scripts/01_aRTist_bridge.py b/scripts/01_aRTist_bridge.py index ff40e914eec7ff53c8f8ba007931fe6f3c0f6789..2d93de9ed2a942eca9d6c6b1a6d6d00e61f118b4 100644 --- a/scripts/01_aRTist_bridge.py +++ b/scripts/01_aRTist_bridge.py @@ -1,6 +1,6 @@ -from CyXTraX.simulation import CylindricalProjection, load_mesh -from CyXTraX.data import scones_mesh -from CyXTraX.common import MeshObject +from cyxtrax.simulation import CylindricalProjection, load_mesh +from cyxtrax.data import scones_mesh +from cyxtrax.common import MeshObject import numpy as np from matplotlib import pyplot as plt @@ -12,6 +12,7 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp' def main(): + # code_embedder:A start # Create the cylindrical projection interface cyl_proj = CylindricalProjection() @@ -33,11 +34,8 @@ def main(): # Generate local cylindrical projection half_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=False) - # output_full_ray_projection=True is the same As - # half_rays = cyl_proj.compute_projection(position, output_full_ray_projection=False) - # full_rays = cyl_proj.convert_rays(half_rays) full_rays = cyl_proj.compute_projection(map_position, output_full_ray_projection=True) - + # code_embedder:A end # Make some nice plots! fig = plt.figure(figsize=(12, 6)) diff --git a/scripts/02_generate_atlas.py b/scripts/02_generate_atlas.py index 39eff9da2c39deaa088f45e2cdc4dd1d30c18fe9..c6394023741d8f3527bc10f1c65885ac64e2fc09 100644 --- a/scripts/02_generate_atlas.py +++ b/scripts/02_generate_atlas.py @@ -10,6 +10,7 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp' def main(): + # code_embedder:A start # Create the cylindrical projection interface cyl_proj = CylindricalProjection() load_mesh(cyl_proj, [olaf_mesh]) @@ -17,8 +18,9 @@ def main(): save_path = record_atlas(cyl_proj, [olaf_mesh], 'test', TEMP_FOLDER, map_bounding_box=[-10, 20], number_of_maps=2) + # code_embedder:A end print(f'Atlas saved to the path: {save_path}') - + if __name__ == '__main__': diff --git a/scripts/03_load_atlas.py b/scripts/03_load_atlas.py index b574781233ee98e68074bcf5ddfaff408e38753c..f20a8afcc7ce574865d2a7e765e171a003bdb044 100644 --- a/scripts/03_load_atlas.py +++ b/scripts/03_load_atlas.py @@ -1,4 +1,5 @@ -from CyXTraX.io import load_atlas +from cyxtrax.io import load_atlas +from cyxtrax.util.visualisation import voxel_maps from pathlib import Path @@ -8,16 +9,18 @@ TEMP_FOLDER = FOLDER.parent.parent / 'temp' def main(): + # code_embedder:A start files = list(TEMP_FOLDER.glob('*.h5')) if not files: raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!') maps, points, mesh_object_list = load_atlas(files[-1]) - + # code_embedder:A end print(f'Loaded Map Shape: {maps.shape}') print(f'Loaded Map Centre Shape: {points.shape}') print(f'First Object: {mesh_object_list[0]}') - + + voxel_maps(maps, TEMP_FOLDER / 'scones_maps.png', title='Scones Atlas') if __name__ == '__main__': main() \ No newline at end of file diff --git a/scripts/04_mapping.py b/scripts/04_mapping.py index 45f729becf805b33ba531a58e094c20bab3e620b..175ca9d2c5bd368bd5edcf00870d35c70bf21f97 100644 --- a/scripts/04_mapping.py +++ b/scripts/04_mapping.py @@ -8,100 +8,107 @@ from matplotlib import pyplot as plt, figure # Just get the temp folder to store the atlas -FOLDER = Path(__file__) -TEMP_FOLDER = FOLDER.parent.parent / 'temp' +FOLDER = Path("/mnt/data/xray_studies_data/") +TEMP_FOLDER = FOLDER / "dataset_64" def main(): - files = list(TEMP_FOLDER.glob('*.h5')) + files = list(TEMP_FOLDER.glob("*.h5")) if not files: - raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!') + raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!") maps, points, mesh_object_list = load_atlas(files[-1]) cyl_proj = CylindricalProjection() - + load_mesh(cyl_proj, mesh_object_list, False) - print(f'Cone Beam Mode set: {cyl_proj.cone_mode}') + print(f"Cone Beam Mode set: {cyl_proj.cone_mode}") rot = 30 x, y = 2000 * jnp.cos(rot * jnp.pi / 180), 500 * jnp.sin(rot * jnp.pi / 180) - source_position = jnp.array([x, y, 0.]).reshape((1, 3)) - detector_position = jnp.array([-x, -y, -10.]).reshape((1, 3)) - detctor_orientation_scipy = Rotation.from_euler('xyz', [0, -90, rot], degrees=True) + source_position = jnp.array([x, y, 0.0]).reshape((1, 3)) + detector_position = jnp.array([-x, -y, -10.0]).reshape((1, 3)) + detctor_orientation_scipy = Rotation.from_euler("xyz", [0, -90, rot], degrees=True) - temp_projection = Path('temp.tif') + temp_projection = Path("temp.tif") detctor_orientation = detctor_orientation_scipy.as_quat().reshape((1, -1)) - cyl_proj.api.translate('S', source_position[0, 0], source_position[0, 1], source_position[0, 2]) - cyl_proj.api.translate('D', detector_position[0, 0], detector_position[0, 1], detector_position[0, 2]) - cyl_proj.api.rotate_from_quat('D', detctor_orientation[0]) + cyl_proj.api.translate( + "S", source_position[0, 0], source_position[0, 1], source_position[0, 2] + ) + cyl_proj.api.translate( + "D", detector_position[0, 0], detector_position[0, 1], detector_position[0, 2] + ) + cyl_proj.api.rotate_from_quat("D", detctor_orientation[0]) cyl_proj.api.save_image(temp_projection, save_mode=SAVEMODES.FLOAT_TIFF) projection, geometry = utility.load_projection(temp_projection) mapped_values, uv_px = map_geometry_2_projection( - source_position, - detector_position, - detctor_orientation, - points, - projection, - cyl_proj.pixel_pitch_mm) - + source_position, + detector_position, + detctor_orientation, + points, + projection, + cyl_proj.pixel_pitch_mm, + ) + values_calc, angles_calc = map_source_2_cylinder( - source_position, - maps, - points, - cyl_proj.detector_radius_mm, + source_position, + maps, + points, + cyl_proj.detector_radius_mm, cyl_proj.x_px, - cyl_proj.x_resolution_mm) - - for i in range(values_calc.shape[0]): - print(f'Step {i}: Value Cylinder {values_calc[i]:2.2f} \t/\t Value Projection {mapped_values[i]:2.2f}') + cyl_proj.x_resolution_mm, + ) + for i in range(values_calc.shape[0]): + print( + f"Step {i}: Value Cylinder {values_calc[i]:2.2f} \t/\t Value Projection {mapped_values[i]:2.2f}" + ) fig = plt.figure(figsize=(24, 10)) subfig1: figure.Figure subfig2: figure.Figure subfig1, subfig2 = fig.subfigures(1, 2) ax1 = subfig1.add_subplot(111) - ax1.set_title('Projection Mapping') + ax1.set_title("Projection Mapping") im = ax1.imshow(projection, vmin=maps.min(), vmax=maps.max()) counter = 0 number_of_maps = maps.shape[2] color = jnp.linspace(0, 1, 9)[:number_of_maps] - cmap = plt.get_cmap('hsv') + cmap = plt.get_cmap("hsv") colors = cmap(color) ax1.scatter(uv_px[0, :9], uv_px[1, :9], c=colors) - ax1.set_xlabel(r'$u$ / px') - ax1.set_ylabel(r'$v$ / px') - subfig1.colorbar(im, ax=ax1, orientation='vertical', label='Ray Length / mm') + ax1.set_xlabel(r"$u$ / px") + ax1.set_ylabel(r"$v$ / px") + subfig1.colorbar(im, ax=ax1, orientation="vertical", label="Ray Length / mm") - ax2 = subfig2.add_subplot(111) - ax2.set_title('Cylindrical Mapping') + ax2.set_title("Cylindrical Mapping") ax2.axis(False) for _ in range(3): for _ in range(3): if counter >= number_of_maps: continue - ax = subfig2.add_subplot(3, 3, counter+1) + ax = subfig2.add_subplot(3, 3, counter + 1) ax.imshow(maps[:, :, counter], vmin=maps.min(), vmax=maps.max()) - ax.scatter(angles_calc[0, counter], angles_calc[1, counter], c=colors[counter]) - ax.set_xlabel(r'$z$ / mm') - ax.set_ylabel(r'$\alpha$ / rad') - ax.set_xticks([0, 1000, 2000]) - ax.set_xticklabels([r'$-3141.5$', r'$0.$', r'$3141.5$']) - ax.set_yticks([0, 1000, 2000]) - ax.set_yticklabels([r'$-\pi$', r'$0.$', r'$\pi$']) + ax.scatter( + angles_calc[0, counter], angles_calc[1, counter], c=colors[counter] + ) + ax.set_xlabel(r"$z$ / mm") + ax.set_ylabel(r"$\alpha$ / rad") + ax.set_xticks([0, 1000, 2000]) + ax.set_xticklabels([r"$-3141.5$", r"$0.$", r"$3141.5$"]) + ax.set_yticks([0, 1000, 2000]) + ax.set_yticklabels([r"$-\pi$", r"$0.$", r"$\pi$"]) counter += 1 plt.tight_layout() - plt.savefig(TEMP_FOLDER / 'mapping.png') + plt.savefig(TEMP_FOLDER / "mapping.png") - -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/scripts/05_data_augmentation.py b/scripts/05_data_augmentation.py index 2ab1212390e0e98ebb6704dd8e455c87f8e8b928..81741745d9b7b6968dd38abead5756d52a34ef53 100644 --- a/scripts/05_data_augmentation.py +++ b/scripts/05_data_augmentation.py @@ -8,42 +8,61 @@ from jax import random # Just get the temp folder to store the atlas -FOLDER = Path(__file__) -TEMP_FOLDER = FOLDER.parent.parent / 'temp' +FOLDER = Path("/mnt/data/xray_studies_data/") +TEMP_FOLDER = FOLDER / "dataset_64" def main(): - files = list(TEMP_FOLDER.glob('*.h5')) + files = list(TEMP_FOLDER.glob("*.h5")) if not files: - raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!') + raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!") map_index = 3 maps, points, mesh_object_list = load_atlas(files[-1]) random_key = random.PRNGKey(42) - save_map_plot_with_index(maps, map_index, TEMP_FOLDER / 'blank_map.png') + save_map_plot_with_index(maps, map_index, TEMP_FOLDER / "blank_map.png") - map_with_white_noise, white_noise_parameter, random_key = add_white_noise(maps, 5.3, 10.1, random_key) + map_with_white_noise, white_noise_parameter, random_key = add_white_noise( + maps, 5.3, 10.1, random_key + ) print(white_noise_parameter) save_map_plot_with_index( - map_with_white_noise, map_index, TEMP_FOLDER / 'noise_map.png', - title='White Noise') + map_with_white_noise, + map_index, + TEMP_FOLDER / "noise_map.png", + title="White Noise", + ) - map_with_gaussian_blur, gaussian_blur_parameter, random_key = add_gaussian_blur(maps, 1.1, 3, random_key) + map_with_gaussian_blur, gaussian_blur_parameter, random_key = add_gaussian_blur( + maps, 1.1, 3, random_key + ) print(gaussian_blur_parameter) save_map_plot_with_index( - map_with_gaussian_blur, map_index, TEMP_FOLDER / 'gaussian_map.png', - title='Gaussian Blur') - - map_with_attenuation, attenuation_parameter, random_key = add_material(maps, 'c', 225, 30, random_key) + map_with_gaussian_blur, + map_index, + TEMP_FOLDER / "gaussian_map.png", + title="Gaussian Blur", + ) + + map_with_attenuation, attenuation_parameter, random_key = add_material( + maps, "c", 225, 30, random_key + ) print(attenuation_parameter) save_map_plot_with_index( - map_with_attenuation, map_index, TEMP_FOLDER / 'attenuation_c_map.png', - title='Attenuation C') - + map_with_attenuation, + map_index, + TEMP_FOLDER / "attenuation_c_map.png", + title="Attenuation C", + ) + merged_map = merge_atlases(map_with_gaussian_blur, map_with_white_noise) save_map_plot_with_index( - merged_map, map_index, TEMP_FOLDER / 'merged_map.png', - title='Merged Map: Gaussian + Noise') + merged_map, + map_index, + TEMP_FOLDER / "merged_map.png", + title="Merged Map: Gaussian + Noise", + ) + -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/scripts/06_generate_dataset.py b/scripts/06_generate_dataset.py index 79f8dc400b01d975a510c06a29ad65664650d2b3..224df5e0680195688360a51acd1f3810b59a5036 100644 --- a/scripts/06_generate_dataset.py +++ b/scripts/06_generate_dataset.py @@ -9,23 +9,29 @@ It takes about 300 minutes of time and needs 100gb of space. """ + def main(): # Dataset save folder - save_folder = Path(r'\\192.168.43.8\data\Wittl\06_datasets\XrayTransform') + save_folder = Path(r"\\192.168.43.8\data\Wittl\06_datasets\XrayTransform") number_of_maps = 4 map_bounding_box = 25 # Dataset of multiple random stl files from: https://ten-thousand-models.appspot.com/ - load_folder = Path(r'C:\Users\swittl\Downloads\Thingi10K\Thingi10K\raw_meshes') - - number_of_samples = len(list(save_folder.glob('*.h5'))) + 1 - + load_folder = Path(r"C:\Users\swittl\Downloads\Thingi10K\Thingi10K\raw_meshes") + + number_of_samples = len(list(save_folder.glob("*.h5"))) + 1 + for i in range(number_of_samples, number_of_samples + 100): # start from number of samples to generate diffrent rng keys!!! print(i) - key = random.PRNGKey(i) + key = random.PRNGKey(i) generate_atlas_from_folder( - load_folder, key, save_folder, map_bounding_box=(-map_bounding_box, map_bounding_box), number_of_maps=number_of_maps) - + load_folder, + key, + save_folder, + map_bounding_box=(-map_bounding_box, map_bounding_box), + number_of_maps=number_of_maps, + ) + -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/scripts/07_presentation.py b/scripts/07_presentation.py index 8540a44f317729c9f73b17f65db0551ab28eb8cc..bc834f6cc50649169ad2c0c8946eeb5fbfd2d384 100644 --- a/scripts/07_presentation.py +++ b/scripts/07_presentation.py @@ -1,71 +1,105 @@ -from CyXTraX.simulation import CylindricalProjection, load_mesh, SAVEMODES, utility +from CyXTraX.simulation import CylindricalProjection, load_mesh, utility from CyXTraX.io import load_atlas from CyXTraX.mapping import map_geometry_2_projection, map_source_2_cylinder from CyXTraX.util.visualisation import voxel_cone_maps from pathlib import Path from jax import numpy as jnp -from jax.scipy.spatial.transform import Rotation - -from cyxtrax_object import set_geometry_at_index, circular_trajectory, add_world_orign, zero_quat, x_90_quat, z_90_quat, add_offset +from cyxtrax_object import ( + set_geometry_at_index, + circular_trajectory, + add_world_orign, + zero_quat, + add_offset, +) # Just get the temp folder to store the atlas FOLDER = Path(__file__) -TEMP_FOLDER = FOLDER.parent.parent / 'temp' -MAP_FOLDER = Path(r'C:\data\XrayTransformLow') +TEMP_FOLDER = FOLDER.parent.parent / "temp" +MAP_FOLDER = Path(r"C:\data\XrayTransformLow") def main(): - files = list(MAP_FOLDER.glob('*.h5')) + files = list(MAP_FOLDER.glob("*.h5")) if not files: - raise FileNotFoundError('No .h5 files in temp folder. Run Example 02!') + raise FileNotFoundError("No .h5 files in temp folder. Run Example 02!") maps, points, mesh_object_list = load_atlas(files[3]) cyl_proj = CylindricalProjection() - - load_mesh(cyl_proj, mesh_object_list, False) - print(f'Cone Beam Mode set: {cyl_proj.cone_mode}') + load_mesh(cyl_proj, mesh_object_list, False) + print(f"Cone Beam Mode set: {cyl_proj.cone_mode}") number_of_projections = 30 - fod_mm = jnp.array([1000,]) - fdd_mm = jnp.array([2000,]) + fod_mm = jnp.array( + [ + 1000, + ] + ) + fdd_mm = jnp.array( + [ + 2000, + ] + ) alpha_rad = jnp.linspace(0, jnp.pi, number_of_projections).reshape((-1, 1)) - source, orientation_source, detector, orientation_detector = circular_trajectory(fod_mm, fdd_mm, alpha_rad) + source, orientation_source, detector, orientation_detector = circular_trajectory( + fod_mm, fdd_mm, alpha_rad + ) source, orientation_source, detector, orientation_detector = add_world_orign( - source, orientation_source, detector, orientation_detector, jnp.array([1, 2., -1.]), jnp.array([0.8, 0.1, -0.1, 0.9])) - detector, orientation_detector = add_offset(detector, orientation_detector, jnp.array([1, 20., -1.]), zero_quat) - - temp_projection = Path('temp.tif') - + source, + orientation_source, + detector, + orientation_detector, + jnp.array([1, 2.0, -1.0]), + jnp.array([0.8, 0.1, -0.1, 0.9]), + ) + detector, orientation_detector = add_offset( + detector, orientation_detector, jnp.array([1, 20.0, -1.0]), zero_quat + ) + + temp_projection = Path("temp.tif") - for i in range(number_of_projections): - set_geometry_at_index(source, orientation_source, detector, orientation_detector, i, temp_projection) + set_geometry_at_index( + source, + orientation_source, + detector, + orientation_detector, + i, + temp_projection, + ) projection, geometry = utility.load_projection(temp_projection) mapped_values, uv_px = map_geometry_2_projection( - source[i], - detector[i], - orientation_detector[i], - points, - projection, - cyl_proj.pixel_pitch_mm) - + source[i], + detector[i], + orientation_detector[i], + points, + projection, + cyl_proj.pixel_pitch_mm, + ) + values_calc, angles_calc = map_source_2_cylinder( - source[i], - maps, - points, - cyl_proj.detector_radius_mm, + source[i], + maps, + points, + cyl_proj.detector_radius_mm, cyl_proj.x_px, - cyl_proj.x_resolution_mm) - - voxel_cone_maps(maps, projection, uv_px, angles_calc, TEMP_FOLDER / f'{i:03}_presentation.png') - + cyl_proj.x_resolution_mm, + ) + + voxel_cone_maps( + maps, + projection, + uv_px, + angles_calc, + TEMP_FOLDER / f"{i:03}_presentation.png", + ) + -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/scripts/08_make_gif.py b/scripts/08_make_gif.py index 2498d0c90a3219b37f04f22ad18a0286babbc283..e1eac1da5bae14d1994b347742086138eb76d0be 100644 --- a/scripts/08_make_gif.py +++ b/scripts/08_make_gif.py @@ -3,11 +3,12 @@ from pathlib import Path # Just get the temp folder to store the atlas FOLDER = Path(__file__) -TEMP_FOLDER = FOLDER.parent.parent / 'temp' +TEMP_FOLDER = FOLDER.parent.parent / "temp" + def main(): - make_gif(TEMP_FOLDER, '*_presentation.png', 'cyxtrax.gif', 333) + make_gif(TEMP_FOLDER, "*_presentation.png", "cyxtrax.gif", 333) -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/CyXTraX/__init__.py b/scripts/09_data_aug_pipeline.py similarity index 100% rename from CyXTraX/__init__.py rename to scripts/09_data_aug_pipeline.py diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 35504c4d4e5228ec6b13944887cd726eca713dc8..0000000000000000000000000000000000000000 --- a/setup.cfg +++ /dev/null @@ -1,28 +0,0 @@ -[metadata] -name = CyXTraX -version = 0.1.0 -description = A Python module to play with local cylindrical xray transform maps or atlases. -author = Simon Wittl -author_email = simon.wittl@th-deg.de / simonwittl@gmail.com -url = https://mygit.th-deg.de/roboct/xraytrafo - -[options] -packages = find: -include_package_data = True # Ensures data files are included -zip_safe = False - -[options.package_data] -CyXTraX = - data/cone.aRTist - data/cylinder.aRTist - data/olaf_6.stl - data/scones.stl - -install_requires = - numpy>=2.0.0 - jaxlib - jax - git+https://github.com/wittlsn/aRTist-PythonLib - scipy - dm_pix - xraylib \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index fc1f76c84d17b458f7090667d495592c9abda034..0000000000000000000000000000000000000000 --- a/setup.py +++ /dev/null @@ -1,3 +0,0 @@ -from setuptools import setup - -setup() \ No newline at end of file diff --git a/CyXTraX/util/__init__.py b/src/cyxtrax/__init__.py similarity index 100% rename from CyXTraX/util/__init__.py rename to src/cyxtrax/__init__.py diff --git a/src/cyxtrax/common/__init__.py b/src/cyxtrax/common/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..7c315e4bdfc523b5f0b0ecc157a3dcc366044e11 --- /dev/null +++ b/src/cyxtrax/common/__init__.py @@ -0,0 +1,6 @@ +from .mesh_object import MeshObject + + +__all__ = [ + 'MeshObject' +] \ No newline at end of file diff --git a/src/cyxtrax/common/mesh_object.py b/src/cyxtrax/common/mesh_object.py new file mode 100644 index 0000000000000000000000000000000000000000..ee43ca348d1daad1fc3953f03fb80922ea43a413 --- /dev/null +++ b/src/cyxtrax/common/mesh_object.py @@ -0,0 +1,26 @@ +from dataclasses import dataclass +from pathlib import Path +import numpy as np + + +@dataclass +class MeshObject: + object_path: Path + position_mm: np.ndarray + orientation_quat: np.ndarray + + def as_dict(self): + return dict( + object_path=str(self.object_path), + object_position=self.position_mm.astype(np.float64).tolist(), + object_orientation=self.orientation_quat.astype(np.float64).tolist(), + ) + + @classmethod + def from_dict(cls: "MeshObject", data_dict): + item = cls( + Path(data_dict["object_path"]), + np.array(data_dict["object_position"]), + np.array(data_dict["object_orientation"]), + ) + return item diff --git a/src/cyxtrax/data/__init__.py b/src/cyxtrax/data/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8921d24d347c3d8351cd769c4ee42e5c2212550e --- /dev/null +++ b/src/cyxtrax/data/__init__.py @@ -0,0 +1,20 @@ +import importlib.resources +import numpy as np +from ..common import MeshObject + + +with importlib.resources.path("cyxtrax.data", "olaf_6.stl") as file_path: + olaf_stl = file_path + olaf_mesh = MeshObject( + olaf_stl, + position_mm=np.array([1, 2, 3]), + orientation_quat=np.array([0.0, 0.0, 0.0, 1.0]), + ) + +with importlib.resources.path("cyxtrax.data", "scones.stl") as file_path: + scones_stl = file_path + scones_mesh = MeshObject( + scones_stl, + position_mm=np.array([0, 0, 0]), + orientation_quat=np.array([0.0, 0.0, 0.0, 1.0]), + ) diff --git a/CyXTraX/data/cone.aRTist b/src/cyxtrax/data/cone.aRTist similarity index 100% rename from CyXTraX/data/cone.aRTist rename to src/cyxtrax/data/cone.aRTist diff --git a/CyXTraX/data/cylinder.aRTist b/src/cyxtrax/data/cylinder.aRTist similarity index 100% rename from CyXTraX/data/cylinder.aRTist rename to src/cyxtrax/data/cylinder.aRTist diff --git a/CyXTraX/data/olaf_6.stl b/src/cyxtrax/data/olaf_6.stl similarity index 100% rename from CyXTraX/data/olaf_6.stl rename to src/cyxtrax/data/olaf_6.stl diff --git a/CyXTraX/data/scones.stl b/src/cyxtrax/data/scones.stl similarity index 100% rename from CyXTraX/data/scones.stl rename to src/cyxtrax/data/scones.stl diff --git a/src/cyxtrax/io/__init__.py b/src/cyxtrax/io/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..2fff89e6e43e6ba570c599b610827e48cf68a198 --- /dev/null +++ b/src/cyxtrax/io/__init__.py @@ -0,0 +1,8 @@ +from .generate_atlas import record_atlas +from .load_maps import load_atlas + + +__all__ = [ + 'record_atlas', + 'load_atlas' +] \ No newline at end of file diff --git a/src/cyxtrax/io/generate_atlas.py b/src/cyxtrax/io/generate_atlas.py new file mode 100644 index 0000000000000000000000000000000000000000..6b15410b4a49e0228debb122d6224b5343ce7ee8 --- /dev/null +++ b/src/cyxtrax/io/generate_atlas.py @@ -0,0 +1,73 @@ +import numpy as np +import h5py +from CyXTraX.simulation.artist_bridge import CylindricalProjection +from CyXTraX.common.mesh_object import MeshObject +from pathlib import Path +import json + + +def to_dict(mesh_object=MeshObject) -> dict: + return mesh_object.as_dict() + + +def record_atlas( + cylindrical_projection: CylindricalProjection, + mesh_list: list[MeshObject], + atlas_name: str, + save_folder: Path, + map_bounding_box: tuple[float] = (-50.0, 50.0), + number_of_maps: int = 4, +) -> Path: + grid = np.linspace(map_bounding_box[0], map_bounding_box[1], number_of_maps) + file_index = len(list(save_folder.glob("*.h5"))) + 1 + save_path = save_folder / f"{file_index:05}_{atlas_name}.h5" + file = h5py.File(save_path, "a") + projection = file.require_dataset( + "maps", + shape=( + cylindrical_projection.x_px, + cylindrical_projection.y_px, + number_of_maps**3, + ), # Initial shape with third dimension as 0 + maxshape=( + cylindrical_projection.x_px, + cylindrical_projection.y_px, + number_of_maps**3, + ), + dtype=np.float32, + ) + + projection_points = file.require_dataset( + "positions", + shape=(3, number_of_maps**3), # Initial shape with third dimension as 0 + maxshape=(3, number_of_maps**3), + dtype=np.float32, + ) + + mesh_list_dict = list(map(to_dict, mesh_list)) + print(mesh_list_dict) + + file.attrs["mesh_list"] = json.dumps(mesh_list_dict) + + counter = 0 + for x in grid: + for y in grid: + for z in grid: + # x, y, z = 0, y, 0 + print(x, y, z) + position = np.array([x, y, z]) + + image = cylindrical_projection.compute_projection( + position, output_full_ray_projection=True + ) + # current_size = projection.shape[2] + # new_size = current_size + 1 + # projection.resize((cylindrical_projection.x_px, cylindrical_projection.y_px, new_size)) + projection[:, :, counter : counter + 1] = image[ + :, :, np.newaxis + ].astype(np.float32) + + # projection_points.resize((3, new_size)) + projection_points[:, counter : counter + 1] = position.reshape((3, 1)) + counter += 1 + return save_path diff --git a/CyXTraX/io/load_maps.py b/src/cyxtrax/io/load_maps.py similarity index 56% rename from CyXTraX/io/load_maps.py rename to src/cyxtrax/io/load_maps.py index eb42e5087f452b4f7733e081e2ea1972438b60d1..f0053a9244aeb585c69cbb7af81546a96c3e5f04 100644 --- a/CyXTraX/io/load_maps.py +++ b/src/cyxtrax/io/load_maps.py @@ -9,16 +9,13 @@ def from_dict(mesh_dict) -> MeshObject: return MeshObject.from_dict(mesh_dict) -def load_atlas(load_path: Path - ) -> tuple[jnp.ndarray, jnp.ndarray, list[MeshObject]]: - - with h5py.File(load_path, 'r') as f: - maps = jnp.array(f['/maps'][:]) - points = jnp.array(f['/positions'][:]) - - mesh_object_str = f.attrs['mesh_list'] +def load_atlas(load_path: Path) -> tuple[jnp.ndarray, jnp.ndarray, list[MeshObject]]: + with h5py.File(load_path, "r") as f: + maps = jnp.array(f["/maps"][:]) + points = jnp.array(f["/positions"][:]) + + mesh_object_str = f.attrs["mesh_list"] mesh_object_dict = json.loads(mesh_object_str) mesh_object_list = list(map(from_dict, mesh_object_dict)) return maps, points, mesh_object_list - diff --git a/src/cyxtrax/mapping/__init__.py b/src/cyxtrax/mapping/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..122cf03b2fe8d11b76711526d46360f17f553186 --- /dev/null +++ b/src/cyxtrax/mapping/__init__.py @@ -0,0 +1,6 @@ +from .mapping import map_geometry_2_projection, map_source_2_cylinder + +__all__ = [ + 'map_geometry_2_projection', + 'map_source_2_cylinder' +] diff --git a/src/cyxtrax/mapping/mapping.py b/src/cyxtrax/mapping/mapping.py new file mode 100644 index 0000000000000000000000000000000000000000..e41f5df7fe8a53fa1111bfce07b802c64d74826e --- /dev/null +++ b/src/cyxtrax/mapping/mapping.py @@ -0,0 +1,146 @@ +from jax import numpy as jnp +import dm_pix as pix +from jax import jit +from jax.scipy.spatial.transform import Rotation + + +@jit +def map_source_2_cylinder( + source: jnp.ndarray, + maps: jnp.ndarray, + map_positions: jnp.ndarray, + radius: float = 1000.0, + angle_discretisation: int = 2000, + pitch: float = jnp.pi, +) -> tuple[jnp.ndarray, jnp.ndarray]: + """ + source: 1 x 3 + maps: u x v x m + map_positions: 3 x m + + --- + + cylinder_value: m x 1 + """ + + # map_positions = map_positions.T # m x 3 + + angles = cylindrical_angles( + source, map_positions, radius, angle_discretisation, pitch + ) + + u = jnp.expand_dims(angles[0], 0) # 1 x m + v = jnp.expand_dims(angles[1], 0) # 1 x m + w = jnp.arange(0, maps.shape[2])[jnp.newaxis, ...] # +0.0001 # 1 x m + + uvw = jnp.concatenate([v, u, w], 0) # 3 x m + values = pix.flat_nd_linear_interpolate(maps, uvw) + + return values, uvw # m, + + +@jit +def cylindrical_angles( + source: jnp.ndarray, + map_positions: jnp.ndarray, + radius: float = 1000.0, + angle_discretisation: int = 2000, + pitch: float = jnp.pi, +) -> tuple[jnp.ndarray, jnp.ndarray]: + source = source.reshape((-1, 1)) # 1 x 3 + directions = map_positions - source # m x 3 + direction_norm_factor = jnp.linalg.norm(directions[:2], axis=0, keepdims=True) + directions = directions / direction_norm_factor # m x 3 + intersection = directions * radius + # sign = jnp.where(intersection[2]>=0, 1, -1) + # intersection = intersection * sign + + z_value = intersection[2] / pitch + z = z_value + (angle_discretisation) / 2.0 + beta_value = ( + (jnp.arctan2(intersection[0], intersection[1]) / jnp.pi) + * angle_discretisation + / 2 + ) + beta = beta_value - ((angle_discretisation - 1.0) / 4.0) + angles = jnp.concatenate( + (jnp.expand_dims(z, 0) % 2000, jnp.expand_dims(beta, 0) % 2000), axis=0 + ) + return angles + + +@jit +def map_geometry_2_projection( + source: jnp.ndarray, + detector: jnp.ndarray, + detector_orientation: jnp.ndarray, + map_positions: jnp.ndarray, + projections: jnp.ndarray, + pixel_pitch_mm: float = 0.139, +): + """ + source: 1 x 3 + detector: 1 x 3 + detector_orientation: 1 x 4 + map_positions: 3 x m + projections: u x v + pixel_pitch_mm: 1, + + --- + + projection_value: m + """ + source = source.reshape((1, 3)) + detector = detector.reshape((1, 3)) + detector_orientation = detector_orientation.reshape((1, 4)) + + projection_geometry = projection_matrix( + source, detector, detector_orientation + ) # 3 x 4 + map_positions_homogen = jnp.ones((1, map_positions.shape[1])) # 1 x m + map_positions_homogen = jnp.concatenate( + (map_positions, map_positions_homogen), 0 + ) # 4 x m + uv_px = projection_geometry @ map_positions_homogen # 3 x m + uv_px = uv_px / uv_px[2] + uv_px = uv_px / pixel_pitch_mm + uv_px = uv_px.at[0, :].multiply(-1) + uv_px = uv_px.at[0, :].add((projections.shape[-2]) / 2.0) + # uv_px = uv_px.at[0,:].multiply(-1) + uv_px = uv_px.at[1, :].add((projections.shape[-2]) / 2.0) + uv_px = uv_px[:2] + + uv_px_flip = jnp.flip(uv_px, 0) + # uv_px_flip = uv_px + + return pix.flat_nd_linear_interpolate(projections, uv_px_flip), uv_px + + +@jit +def projection_matrix( + source: jnp.ndarray, detector: jnp.ndarray, detector_orientation: jnp.ndarray +) -> jnp.ndarray: + """ + source: 1 x 3 + detector: 1 x 3 + detector_orientation: 1 x 4 + + --- + + projection_matrix = 3 x 4 + """ + detector_orientation = detector_orientation / detector_orientation[1, 3] + rotation_matrix = Rotation.from_quat(detector_orientation).as_matrix() + detector_horizontal_vector = -rotation_matrix[0, :, 0] + detector_vertical_vector = -rotation_matrix[0, :, 1] + p3x3 = jnp.vstack( + [ + detector_horizontal_vector, + detector_vertical_vector, + (detector - source).reshape((-1, 3)), + ] + ).T + p3x3_inv = jnp.linalg.inv(p3x3) + p4 = p3x3_inv @ (-source).reshape((3, 1)) + matrix = jnp.concatenate([p3x3_inv, p4], 1) # 3 x 4 + return matrix diff --git a/src/cyxtrax/simulation/__init__.py b/src/cyxtrax/simulation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ceddce2bc31b45b48999c027cb574f4fba0a2b2c --- /dev/null +++ b/src/cyxtrax/simulation/__init__.py @@ -0,0 +1,8 @@ +from .artist_bridge import CylindricalProjection, load_mesh, SAVEMODES, utility + +__all__ = [ + 'CylindricalProjection', + 'load_mesh', + 'SAVEMODES', + 'utility' +] \ No newline at end of file diff --git a/CyXTraX/simulation/artist_bridge.py b/src/cyxtrax/simulation/artist_bridge.py similarity index 52% rename from CyXTraX/simulation/artist_bridge.py rename to src/cyxtrax/simulation/artist_bridge.py index 0f7ff94bba2f3ac9a4ffcdefe275f2429a1190c9..93d32f2fc703c50a38eaa4e251554effb13c3856 100644 --- a/CyXTraX/simulation/artist_bridge.py +++ b/src/cyxtrax/simulation/artist_bridge.py @@ -2,24 +2,27 @@ try: from artistlib import API, utility, SAVEMODES # type: ignore except ModuleNotFoundError: from warnings import warn - warn('The module `artistlib`is not installed. The simulation module is not 100\% usable! \nInstall: https://github.com/wittlsn/aRTist-PythonLib') - API = lambda: None + + warn( + "The module `artistlib`is not installed. The simulation module is not 100\% usable! \nInstall: https://github.com/wittlsn/aRTist-PythonLib" + ) + def API(): + return None utility = None SAVEMODES = None from pathlib import Path import numpy as np import os -from scipy.spatial.transform import Rotation import importlib.resources from time import sleep -from CyXTraX.common.mesh_object import MeshObject +from cyxtrax.common.mesh_object import MeshObject # !!!!!!!!!!!!!!!!!!! # Read carefully #!!!!!!!!!!!!!!!!?!!! -# This Script assumes that the detector has a size of 6283.19 mm / 2 pi +# This Script assumes that the detector has a size of 6283.19 mm / 2 pi # and the curvature is set to the y axis with center on the source. # The source Position has to be on [0, 0, 0] @@ -30,6 +33,7 @@ from CyXTraX.common.mesh_object import MeshObject GLOBAL_COUNTER = 0 + class CylindricalProjection: def __init__(self, api: API = API()) -> None: self.api = api @@ -38,16 +42,16 @@ class CylindricalProjection: self.pixel_pitch_mm = 0.139 self.x_px = 2000 self.y_px = 2000 - self.detector_radius_mm = 1000. + self.detector_radius_mm = 1000.0 self.objects = list() self._cylindrical = True @property - def cylindrical_mode(self) -> bool: + def cylindrical_mode(self) -> bool: return self._cylindrical - @property - def cone_mode(self) -> bool: + @property + def cone_mode(self) -> bool: return not self._cylindrical def translate(self, position: np.ndarray): @@ -56,31 +60,45 @@ class CylindricalProjection: x_s, y_s, z_s = 0, 0, 0 x_p, y_p, z_p = position[0], position[1], position[2] - self.api.rc.send(f'::PartList::Invoke {str("S")} SetPosition {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};') - self.api.rc.send(f'::PartList::Invoke {str("S")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};') - - self.api.rc.send(f'::PartList::Invoke {str("D")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};') - self.api.rc.send(f'::PartList::Invoke {str("D")} SetPosition {str(x_d + x_p)} {str(y_d + y_p)} {str(z_d + z_p)};') - self.api.rc.send(f'::XDetector::SetDownCurvedView;') - - - def compute_projection(self, position: np.ndarray, temp_file_path: Path = Path(r'C:\data'), output_full_ray_projection: bool = True) -> np.ndarray: + self.api.rc.send( + f'::PartList::Invoke {str("S")} SetPosition {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};' + ) + self.api.rc.send( + f'::PartList::Invoke {str("S")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};' + ) + + self.api.rc.send( + f'::PartList::Invoke {str("D")} SetRefPos {str(x_s + x_p)} {str(y_s + y_p)} {str(z_s + z_p)};' + ) + self.api.rc.send( + f'::PartList::Invoke {str("D")} SetPosition {str(x_d + x_p)} {str(y_d + y_p)} {str(z_d + z_p)};' + ) + self.api.rc.send("::XDetector::SetDownCurvedView;") + + def compute_projection( + self, + position: np.ndarray, + temp_file_path: Path = Path(r"C:\data"), + output_full_ray_projection: bool = True, + ) -> np.ndarray: global GLOBAL_COUNTER self.translate(position) - temp_file = temp_file_path / f'temp_{GLOBAL_COUNTER:01}.tiff' + temp_file = temp_file_path / f"temp_{GLOBAL_COUNTER:01}.tiff" GLOBAL_COUNTER += 1 GLOBAL_COUNTER = GLOBAL_COUNTER % 10 - self.api.save_image(temp_file, save_projection_geometry=False, save_mode=SAVEMODES.FLOAT_TIFF) - + self.api.save_image( + temp_file, save_projection_geometry=False, save_mode=SAVEMODES.FLOAT_TIFF + ) + while not temp_file.exists(): - print('sleepy sleep sleep ...') + print("sleepy sleep sleep ...") # The computation of the cylindrical xray tansforms takes time ... aRTist is not programmed for it. # This catches problems with the computation and the remote control interfaces # It is ugly ... but works ... # Also if the mesh is not waterprof the triangle filter of artist seems to have problems. - sleep(2.) + sleep(2.0) image = utility.load_projection(temp_file, load_projection_geometry=False)[0] os.remove(temp_file) @@ -89,44 +107,57 @@ class CylindricalProjection: return self.convert_rays(image) else: return image - + def convert_rays(self, image): inter_image = np.roll(image, 1000, 0) image += np.flip(inter_image, 1) - return image - + return image + def set_cylindrical_mode(self): - with importlib.resources.path('CyXTraX.data', 'cylinder.aRTist') as file_path: - print(f'Load: {file_path}') + with importlib.resources.path("cyxtrax.data", "cylinder.aRTist") as file_path: + print(f"Load: {file_path}") self.api.load_project(file_path) - self.x_px = 2000. - self.y_px = 2000. + self.x_px = 2000.0 + self.y_px = 2000.0 self.x_resolution_mm = np.pi self.y_resolution_mm = np.pi - self.detector_radius_mm = 1000. + self.detector_radius_mm = 1000.0 self._cylindrical = True - print('Care! The default pixel pitch etc is set. If changes are made change the state of this class ...') - + print( + "Care! The default pixel pitch etc is set. If changes are made change the state of this class ..." + ) + def set_cone_mode(self): - with importlib.resources.path('CyXTraX.data', 'cone.aRTist') as file_path: - print(f'Load: {file_path}') + with importlib.resources.path("cyxtrax.data", "cone.aRTist") as file_path: + print(f"Load: {file_path}") self.api.load_project(file_path) self.pixel_pitch_mm = 0.139 self._cylindrical = False - print('Care! The default pixel pitch etc is set. If changes are made change the state of this class ...') - + print( + "Care! The default pixel pitch etc is set. If changes are made change the state of this class ..." + ) -def load_mesh(cylindrical_projection: CylindricalProjection, object_list: list[MeshObject], cylindrical_mode: bool = True) -> bool: + +def load_mesh( + cylindrical_projection: CylindricalProjection, + object_list: list[MeshObject], + cylindrical_mode: bool = True, +) -> bool: if cylindrical_mode: cylindrical_projection.set_cylindrical_mode() else: cylindrical_projection.set_cone_mode() for mesh_object in object_list: - object_id = cylindrical_projection.api.load_part(mesh_object.object_path) - cylindrical_projection.api.translate(object_id, mesh_object.position_mm[0], mesh_object.position_mm[1], mesh_object.position_mm[2]) - cylindrical_projection.api.rotate_from_quat(object_id, mesh_object.orientation_quat) - - return True + cylindrical_projection.api.translate( + object_id, + mesh_object.position_mm[0], + mesh_object.position_mm[1], + mesh_object.position_mm[2], + ) + cylindrical_projection.api.rotate_from_quat( + object_id, mesh_object.orientation_quat + ) + return True diff --git a/src/cyxtrax/simulation/model/__init__.py b/src/cyxtrax/simulation/model/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..ddd257a4ea7a8a6ad86558ce53971d1a321947ee --- /dev/null +++ b/src/cyxtrax/simulation/model/__init__.py @@ -0,0 +1,10 @@ +from .augemtation_parameters import AugemntationParameter +from .noise import add_white_noise, add_gaussian_blur +from .xray import add_material + +__all__ = [ + 'AugemntationParameter', + 'add_white_noise', + 'add_gaussian_blur', + 'add_material' +] \ No newline at end of file diff --git a/CyXTraX/simulation/model/augemtation_parameters.py b/src/cyxtrax/simulation/model/augemtation_parameters.py similarity index 77% rename from CyXTraX/simulation/model/augemtation_parameters.py rename to src/cyxtrax/simulation/model/augemtation_parameters.py index 51f5e1b9857a91141ec0e1a6936ce1f20c944a9b..e478c5b23df199a9ed491e4adaec7cd11410a8ba 100644 --- a/CyXTraX/simulation/model/augemtation_parameters.py +++ b/src/cyxtrax/simulation/model/augemtation_parameters.py @@ -1,5 +1,4 @@ from dataclasses import dataclass -from jax import random @dataclass @@ -7,4 +6,4 @@ class AugemntationParameter: augmentation_module: str augmentation_function: str function_parameter: dict - input_parameter: dict \ No newline at end of file + input_parameter: dict diff --git a/CyXTraX/simulation/model/noise.py b/src/cyxtrax/simulation/model/noise.py similarity index 60% rename from CyXTraX/simulation/model/noise.py rename to src/cyxtrax/simulation/model/noise.py index 76e1a4761714771d60526223527b65a21082c9e6..3ee76dd47feedff75efc596d7314f7005633538a 100644 --- a/CyXTraX/simulation/model/noise.py +++ b/src/cyxtrax/simulation/model/noise.py @@ -3,34 +3,37 @@ import dm_pix as pix from jax import numpy as jnp, random - -def add_white_noise(maps: jnp.ndarray, mu: jnp.ndarray, sigma: jnp.ndarray, key: random.PRNGKey - ) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]: +def add_white_noise( + maps: jnp.ndarray, mu: jnp.ndarray, sigma: jnp.ndarray, key: random.PRNGKey +) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]: key2use, key4next = random.split(key) function_kwargs = dict(key=key2use, shape=maps.shape, dtype=maps.dtype) input_kwargs = dict(mu=mu, sigma=sigma) maps = maps.at[:].add(random.normal(**function_kwargs) * sigma + mu) - + parameters = AugemntationParameter( - add_gaussian_blur.__globals__['__name__'], + add_gaussian_blur.__globals__["__name__"], add_gaussian_blur.__name__, function_kwargs, - input_kwargs) - + input_kwargs, + ) + return maps, parameters, key4next -def add_gaussian_blur(maps: jnp.ndarray, sigma: jnp.ndarray, kernel_size: jnp.ndarray, key: random.PRNGKey - ) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]: +def add_gaussian_blur( + maps: jnp.ndarray, sigma: jnp.ndarray, kernel_size: jnp.ndarray, key: random.PRNGKey +) -> tuple[jnp.ndarray, AugemntationParameter, random.PRNGKey]: key4next = key function_kwargs = dict(sigma=sigma, kernel_size=kernel_size) input_kwargs = dict(kernel_size=kernel_size, sigma=sigma) maps = pix.gaussian_blur(maps, **function_kwargs) parameters = AugemntationParameter( - add_gaussian_blur.__globals__['__name__'], + add_gaussian_blur.__globals__["__name__"], add_gaussian_blur.__name__, function_kwargs, - input_kwargs) - + input_kwargs, + ) + return maps, parameters, key4next diff --git a/src/cyxtrax/simulation/model/pipeline.py b/src/cyxtrax/simulation/model/pipeline.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/CyXTraX/simulation/model/xray.py b/src/cyxtrax/simulation/model/xray.py similarity index 61% rename from CyXTraX/simulation/model/xray.py rename to src/cyxtrax/simulation/model/xray.py index 978af9c12a760d498022dbf1bb4f7b56635a4f60..57376662543d2994b3491a603f6040e676afd4c1 100644 --- a/CyXTraX/simulation/model/xray.py +++ b/src/cyxtrax/simulation/model/xray.py @@ -1,7 +1,6 @@ from .augemtation_parameters import AugemntationParameter import xraylib -import numpy as np from jax import numpy as jnp, random @@ -10,29 +9,36 @@ def get_attenuation_coefficient_monochrom(element: str, energy_keV: float) -> fl return xraylib.CS_Total(element, energy_keV) -def get_attenuation_coefficient_polychrom(element: str, energy_keV: float, bins: int) -> float: +def get_attenuation_coefficient_polychrom( + element: str, energy_keV: float, bins: int +) -> float: energies = jnp.linspace(0, energy_keV, bins, endpoint=True) for i in range(1, bins): - energies = energies.at[i].set(get_attenuation_coefficient_monochrom(element, float(energies[i]))) + energies = energies.at[i].set( + get_attenuation_coefficient_monochrom(element, float(energies[i])) + ) return energies.sum() -def add_material(maps: jnp.ndarray, materilal: str, energy_keV: float, bins: int, key: random.PRNGKey): +def add_material( + maps: jnp.ndarray, materilal: str, energy_keV: float, bins: int, key: random.PRNGKey +): key4next = key function_kwargs = dict() input_kwargs = dict(element=materilal, energy_keV=energy_keV, bins=bins) attenuation_coefficient = get_attenuation_coefficient_polychrom(**input_kwargs) parameters = AugemntationParameter( - add_material.__globals__['__name__'], + add_material.__globals__["__name__"], add_material.__name__, function_kwargs, - input_kwargs) + input_kwargs, + ) maps = maps.at[:].multiply(attenuation_coefficient) - + return maps, parameters, key4next -if __name__ == '__main__': - mu = get_attenuation_coefficient_polychrom('c', 100, 10) - print(mu) \ No newline at end of file +if __name__ == "__main__": + mu = get_attenuation_coefficient_polychrom("c", 100, 10) + print(mu) diff --git a/src/cyxtrax/util/__init__.py b/src/cyxtrax/util/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/cyxtrax/util/datasets/__init__.py b/src/cyxtrax/util/datasets/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..8388c33666b5dd9fd516da6dab5af5ce7b9f3d64 --- /dev/null +++ b/src/cyxtrax/util/datasets/__init__.py @@ -0,0 +1,9 @@ +from .merge import merge_atlas_and_dict, merge_atlases, merge_lists +from .pipeline import generate_atlas_from_folder + +__all__ = [ + 'merge_atlas_and_dict', + 'merge_atlases', + 'merge_lists', + 'generate_atlas_from_folder' +] \ No newline at end of file diff --git a/CyXTraX/util/datasets/augmentation_pipeline.py b/src/cyxtrax/util/datasets/augmentation_pipeline.py similarity index 87% rename from CyXTraX/util/datasets/augmentation_pipeline.py rename to src/cyxtrax/util/datasets/augmentation_pipeline.py index 2e82b48a42e8fff91c68c9333e134d5bb4e58094..4e7345dc60679d1ca1f7a520252e1ac57b8acd41 100644 --- a/CyXTraX/util/datasets/augmentation_pipeline.py +++ b/src/cyxtrax/util/datasets/augmentation_pipeline.py @@ -1,4 +1,5 @@ -from jax import random, numpy as jnp +from jax import random + class DataAugmentation: def __init__(self, key: random.PRNGKey) -> None: @@ -10,7 +11,6 @@ class DataAugmentation: key2save, key2use = random.split(self._key) self._key = key2save return key2use - + def register(self): pass - diff --git a/src/cyxtrax/util/datasets/merge.py b/src/cyxtrax/util/datasets/merge.py new file mode 100644 index 0000000000000000000000000000000000000000..097f39f3356b01219d688a76ea2ca703cfc00b96 --- /dev/null +++ b/src/cyxtrax/util/datasets/merge.py @@ -0,0 +1,17 @@ +from jax import numpy as jnp + + +def merge_atlases(carry_atlas: jnp.ndarray, atlas: jnp.ndarray) -> jnp.ndarray: + return carry_atlas.at[:].add(atlas) / 2.0 + + +def merge_lists(carry_list: list, x: list) -> list: + return carry_list.extend(x) + + +def merge_atlas_and_dict( + atlas_one, mesh_list_one, atlas_two, mesh_list_two +) -> tuple[jnp.ndarray, list]: + return merge_atlases(atlas_one, atlas_two), merge_lists( + mesh_list_one, mesh_list_two + ) diff --git a/CyXTraX/util/datasets/pipeline.py b/src/cyxtrax/util/datasets/pipeline.py similarity index 52% rename from CyXTraX/util/datasets/pipeline.py rename to src/cyxtrax/util/datasets/pipeline.py index cfb4aab76371be841f7dc13c548b8214fa448a2f..fa9f0ef68ec768d5f093136a6b1808f3c0adc027 100644 --- a/CyXTraX/util/datasets/pipeline.py +++ b/src/cyxtrax/util/datasets/pipeline.py @@ -7,31 +7,38 @@ from jax.scipy.spatial.transform import Rotation def generate_atlas_from_folder( - folder: Path, key: random.PRNGKey, - save_folder: Path, - map_bounding_box: tuple[float]=(-50., 50.), number_of_maps: int = 4): + folder: Path, + key: random.PRNGKey, + save_folder: Path, + map_bounding_box: tuple[float] = (-50.0, 50.0), + number_of_maps: int = 4, +): randint_key, postion_key, orientation_key = random.split(key, 3) - stl_files = list(folder.glob('*.stl')) + stl_files = list(folder.glob("*.stl")) number_of_files = len(stl_files) item_id = random.randint(randint_key, (1,), 0, number_of_files, dtype=jnp.int32) random_euler = random.uniform(orientation_key, (3,), minval=-180, maxval=180) - rot: Rotation = Rotation.from_euler('xyz', random_euler) + rot: Rotation = Rotation.from_euler("xyz", random_euler) stl_path: Path = stl_files[item_id[0]] mesh_item = MeshObject( stl_path, - random.truncated_normal(postion_key, -50, 50, (3,)) + random.uniform(postion_key, (3,), minval=-25, maxval=25), - rot.as_quat()) + random.truncated_normal(postion_key, -50, 50, (3,)) + + random.uniform(postion_key, (3,), minval=-25, maxval=25), + rot.as_quat(), + ) mesh_list = [mesh_item] cycl_proj = CylindricalProjection() load_mesh(cycl_proj, mesh_list) - record_atlas(cycl_proj, mesh_list, - stl_path.stem, save_folder, - map_bounding_box, number_of_maps) - - - -def merge_atlas_with_data_augmentation(folder: Path, - data_augmentation_pipeline): - - pass \ No newline at end of file + record_atlas( + cycl_proj, + mesh_list, + stl_path.stem, + save_folder, + map_bounding_box, + number_of_maps, + ) + + +def merge_atlas_with_data_augmentation(folder: Path, data_augmentation_pipeline): + pass diff --git a/src/cyxtrax/util/visualisation/__init__.py b/src/cyxtrax/util/visualisation/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..995194029d4ad90bb3a622024fdb845cc1096783 --- /dev/null +++ b/src/cyxtrax/util/visualisation/__init__.py @@ -0,0 +1,9 @@ +from .plt import save_map_plot_with_index, voxel_cone_maps, voxel_maps +from .gif import make_gif + +__all__ = [ + 'save_map_plot_with_index', + 'voxel_cone_maps', + 'make_gif', + 'voxel_maps' +] \ No newline at end of file diff --git a/CyXTraX/util/visualisation/gif.py b/src/cyxtrax/util/visualisation/gif.py similarity index 90% rename from CyXTraX/util/visualisation/gif.py rename to src/cyxtrax/util/visualisation/gif.py index 68e0a043a05348a4c736100c3904db02462cdb2b..77c59c706fd0953ca0bc556f0d3f4e0bd3e2d66b 100644 --- a/CyXTraX/util/visualisation/gif.py +++ b/src/cyxtrax/util/visualisation/gif.py @@ -9,7 +9,7 @@ def atlas_gif(load_path: Path): def load_pil(path: Path) -> Image.Image: return Image.open(path) - + def make_gif(load_path: Path, pattern: str, name: str, duration_ms: float = 100): frames = sorted(list(load_path.glob(pattern))) @@ -17,7 +17,7 @@ def make_gif(load_path: Path, pattern: str, name: str, duration_ms: float = 100) frames[0].save( load_path / name, save_all=True, - append_images=frames[1:], + append_images=frames[1:], duration=duration_ms, - loop=0) - + loop=0, + ) diff --git a/CyXTraX/util/visualisation/plt.py b/src/cyxtrax/util/visualisation/plt.py similarity index 79% rename from CyXTraX/util/visualisation/plt.py rename to src/cyxtrax/util/visualisation/plt.py index 799e528e3702ca60e4d17e5ff24417f698c4b6b2..29704f68e05e151f2855e1ab6c9be46b4f02e1f8 100644 --- a/CyXTraX/util/visualisation/plt.py +++ b/src/cyxtrax/util/visualisation/plt.py @@ -135,5 +135,42 @@ def voxel_cone_maps_values(maps: jnp.ndarray, projection: jnp.ndarray, if title is not None: plt.title(title) + plt.tight_layout() + plt.savefig(save_path) + + +def voxel_maps(maps: jnp.ndarray, save_path: Path, figsize=(24, 10), title: str = None, vmin: bool = False): + fig = plt.figure(figsize=figsize) + + ax2 = fig.add_subplot(111) + ax2.set_title('Cylindrical Mapping') + ax2.axis(False) + + number_of_maps = maps.shape[2] + side_length = int(jnp.round(number_of_maps ** (1. / 3.))) + counter = 0 + for z in [0, side_length - 1]: + for y in [0, side_length - 1]: + for x in [0, side_length - 1]: + position = x + y * side_length + z * side_length ** 2 + if counter >= number_of_maps: + continue + ax = fig.add_subplot(3, 3, counter+1) + if vmin: + ax.imshow(maps[:, :, position].T, vmin=maps.min(), vmax=maps.max()) + else: + ax.imshow(maps[:, :, position].T, vmin=maps.min()) + ax.set_ylabel(r'$z$ / mm') + ax.set_xlabel(r'$\alpha$ / rad') + ax.set_yticks([0, 1000, 2000]) + ax.set_yticklabels([r'$-3141.5$', r'$0.$', r'$3141.5$']) + ax.set_xticks([0, 1000, 2000]) + ax.set_xticklabels([r'$-\pi$', r'$0.$', r'$\pi$']) + + counter += 1 + + if title is not None: + plt.title(title) + plt.tight_layout() plt.savefig(save_path) \ No newline at end of file diff --git a/temp/scones.png b/temp/scones.png new file mode 100644 index 0000000000000000000000000000000000000000..b00343ab54e02835bcefa53b8471d7b909fa38ef Binary files /dev/null and b/temp/scones.png differ diff --git a/temp/scones_maps.png b/temp/scones_maps.png new file mode 100644 index 0000000000000000000000000000000000000000..402700766767ee7fc2aaffb36bb0fab823dcb89d Binary files /dev/null and b/temp/scones_maps.png differ diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000000000000000000000000000000000000..7c477bf8a8b814d9274d5ed12f26652a6292caf6 --- /dev/null +++ b/uv.lock @@ -0,0 +1,883 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.11' and sys_platform == 'linux'", + "python_full_version < '3.11' and sys_platform == 'windows'", + "python_full_version < '3.11' and sys_platform != 'linux' and sys_platform != 'windows'", + "python_full_version == '3.11.*' and sys_platform == 'linux'", + "python_full_version == '3.11.*' and sys_platform == 'windows'", + "python_full_version == '3.11.*' and sys_platform != 'linux' and sys_platform != 'windows'", + "python_full_version == '3.12.*' and sys_platform == 'linux'", + "python_full_version == '3.12.*' and sys_platform == 'windows'", + "python_full_version == '3.12.*' and sys_platform != 'linux' and sys_platform != 'windows'", + "python_full_version >= '3.13' and sys_platform == 'linux'", + "python_full_version >= '3.13' and sys_platform == 'windows'", + "python_full_version >= '3.13' and sys_platform != 'linux' and sys_platform != 'windows'", +] + +[[package]] +name = "absl-py" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7a/8f/fc001b92ecc467cc32ab38398bd0bfb45df46e7523bf33c2ad22a505f06e/absl-py-2.1.0.tar.gz", hash = "sha256:7820790efbb316739cde8b4e19357243fc3608a152024288513dd968d7d959ff", size = 118055 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/ad/e0d3c824784ff121c03cc031f944bc7e139a8f1870ffd2845cc2dd76f6c4/absl_py-2.1.0-py3-none-any.whl", hash = "sha256:526a04eadab8b4ee719ce68f204172ead1027549089702d99b9059f129ff1308", size = 133706 }, +] + +[[package]] +name = "artistlib" +version = "0.1" +source = { git = "https://github.com/wittlsn/aRTist-PythonLib#14d657783e51f9c94dcafa47bf71a523b85e6d5a" } + +[[package]] +name = "chex" +version = "0.1.87" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "absl-py" }, + { name = "jax" }, + { name = "jaxlib" }, + { name = "numpy" }, + { name = "setuptools", marker = "python_full_version >= '3.12'" }, + { name = "toolz" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/8a/857474810b64ab135a0c3e594b0453c7f39f140757c4cd26a32bccadcbc4/chex-0.1.87.tar.gz", hash = "sha256:0096d89cc8d898bb521ef4bfbf5c24549022b0e5b301f529ab57238896fe6c5d", size = 90063 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/dd/c1ff2eb8fbf95a8ca804abb1cc3ce70b283ee7b4bc653c3abac245670400/chex-0.1.87-py3-none-any.whl", hash = "sha256:ce536475661fd96d21be0c1728ecdbedd03f8ff950c662dfc338c92ea782cb16", size = 99369 }, +] + +[[package]] +name = "contourpy" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/f6/31a8f28b4a2a4fa0e01085e542f3081ab0588eff8e589d39d775172c9792/contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4", size = 13464370 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/e0/be8dcc796cfdd96708933e0e2da99ba4bb8f9b2caa9d560a50f3f09a65f3/contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7", size = 265366 }, + { url = "https://files.pythonhosted.org/packages/50/d6/c953b400219443535d412fcbbc42e7a5e823291236bc0bb88936e3cc9317/contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42", size = 249226 }, + { url = "https://files.pythonhosted.org/packages/6f/b4/6fffdf213ffccc28483c524b9dad46bb78332851133b36ad354b856ddc7c/contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7", size = 308460 }, + { url = "https://files.pythonhosted.org/packages/cf/6c/118fc917b4050f0afe07179a6dcbe4f3f4ec69b94f36c9e128c4af480fb8/contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab", size = 347623 }, + { url = "https://files.pythonhosted.org/packages/f9/a4/30ff110a81bfe3abf7b9673284d21ddce8cc1278f6f77393c91199da4c90/contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589", size = 317761 }, + { url = "https://files.pythonhosted.org/packages/99/e6/d11966962b1aa515f5586d3907ad019f4b812c04e4546cc19ebf62b5178e/contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41", size = 322015 }, + { url = "https://files.pythonhosted.org/packages/4d/e3/182383743751d22b7b59c3c753277b6aee3637049197624f333dac5b4c80/contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d", size = 1262672 }, + { url = "https://files.pythonhosted.org/packages/78/53/974400c815b2e605f252c8fb9297e2204347d1755a5374354ee77b1ea259/contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223", size = 1321688 }, + { url = "https://files.pythonhosted.org/packages/52/29/99f849faed5593b2926a68a31882af98afbeac39c7fdf7de491d9c85ec6a/contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f", size = 171145 }, + { url = "https://files.pythonhosted.org/packages/a9/97/3f89bba79ff6ff2b07a3cbc40aa693c360d5efa90d66e914f0ff03b95ec7/contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b", size = 216019 }, + { url = "https://files.pythonhosted.org/packages/b3/1f/9375917786cb39270b0ee6634536c0e22abf225825602688990d8f5c6c19/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad", size = 266356 }, + { url = "https://files.pythonhosted.org/packages/05/46/9256dd162ea52790c127cb58cfc3b9e3413a6e3478917d1f811d420772ec/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49", size = 250915 }, + { url = "https://files.pythonhosted.org/packages/e1/5d/3056c167fa4486900dfbd7e26a2fdc2338dc58eee36d490a0ed3ddda5ded/contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66", size = 310443 }, + { url = "https://files.pythonhosted.org/packages/ca/c2/1a612e475492e07f11c8e267ea5ec1ce0d89971be496c195e27afa97e14a/contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081", size = 348548 }, + { url = "https://files.pythonhosted.org/packages/45/cf/2c2fc6bb5874158277b4faf136847f0689e1b1a1f640a36d76d52e78907c/contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1", size = 319118 }, + { url = "https://files.pythonhosted.org/packages/03/33/003065374f38894cdf1040cef474ad0546368eea7e3a51d48b8a423961f8/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d", size = 323162 }, + { url = "https://files.pythonhosted.org/packages/42/80/e637326e85e4105a802e42959f56cff2cd39a6b5ef68d5d9aee3ea5f0e4c/contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c", size = 1265396 }, + { url = "https://files.pythonhosted.org/packages/7c/3b/8cbd6416ca1bbc0202b50f9c13b2e0b922b64be888f9d9ee88e6cfabfb51/contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb", size = 1324297 }, + { url = "https://files.pythonhosted.org/packages/4d/2c/021a7afaa52fe891f25535506cc861c30c3c4e5a1c1ce94215e04b293e72/contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c", size = 171808 }, + { url = "https://files.pythonhosted.org/packages/8d/2f/804f02ff30a7fae21f98198828d0857439ec4c91a96e20cf2d6c49372966/contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67", size = 217181 }, + { url = "https://files.pythonhosted.org/packages/c9/92/8e0bbfe6b70c0e2d3d81272b58c98ac69ff1a4329f18c73bd64824d8b12e/contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f", size = 267838 }, + { url = "https://files.pythonhosted.org/packages/e3/04/33351c5d5108460a8ce6d512307690b023f0cfcad5899499f5c83b9d63b1/contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6", size = 251549 }, + { url = "https://files.pythonhosted.org/packages/51/3d/aa0fe6ae67e3ef9f178389e4caaaa68daf2f9024092aa3c6032e3d174670/contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639", size = 303177 }, + { url = "https://files.pythonhosted.org/packages/56/c3/c85a7e3e0cab635575d3b657f9535443a6f5d20fac1a1911eaa4bbe1aceb/contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c", size = 341735 }, + { url = "https://files.pythonhosted.org/packages/dd/8d/20f7a211a7be966a53f474bc90b1a8202e9844b3f1ef85f3ae45a77151ee/contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06", size = 314679 }, + { url = "https://files.pythonhosted.org/packages/6e/be/524e377567defac0e21a46e2a529652d165fed130a0d8a863219303cee18/contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09", size = 320549 }, + { url = "https://files.pythonhosted.org/packages/0f/96/fdb2552a172942d888915f3a6663812e9bc3d359d53dafd4289a0fb462f0/contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd", size = 1263068 }, + { url = "https://files.pythonhosted.org/packages/2a/25/632eab595e3140adfa92f1322bf8915f68c932bac468e89eae9974cf1c00/contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35", size = 1322833 }, + { url = "https://files.pythonhosted.org/packages/73/e3/69738782e315a1d26d29d71a550dbbe3eb6c653b028b150f70c1a5f4f229/contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb", size = 172681 }, + { url = "https://files.pythonhosted.org/packages/0c/89/9830ba00d88e43d15e53d64931e66b8792b46eb25e2050a88fec4a0df3d5/contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b", size = 218283 }, + { url = "https://files.pythonhosted.org/packages/53/a1/d20415febfb2267af2d7f06338e82171824d08614084714fb2c1dac9901f/contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3", size = 267879 }, + { url = "https://files.pythonhosted.org/packages/aa/45/5a28a3570ff6218d8bdfc291a272a20d2648104815f01f0177d103d985e1/contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7", size = 251573 }, + { url = "https://files.pythonhosted.org/packages/39/1c/d3f51540108e3affa84f095c8b04f0aa833bb797bc8baa218a952a98117d/contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84", size = 303184 }, + { url = "https://files.pythonhosted.org/packages/00/56/1348a44fb6c3a558c1a3a0cd23d329d604c99d81bf5a4b58c6b71aab328f/contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0", size = 340262 }, + { url = "https://files.pythonhosted.org/packages/2b/23/00d665ba67e1bb666152131da07e0f24c95c3632d7722caa97fb61470eca/contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b", size = 313806 }, + { url = "https://files.pythonhosted.org/packages/5a/42/3cf40f7040bb8362aea19af9a5fb7b32ce420f645dd1590edcee2c657cd5/contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da", size = 319710 }, + { url = "https://files.pythonhosted.org/packages/05/32/f3bfa3fc083b25e1a7ae09197f897476ee68e7386e10404bdf9aac7391f0/contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14", size = 1264107 }, + { url = "https://files.pythonhosted.org/packages/1c/1e/1019d34473a736664f2439542b890b2dc4c6245f5c0d8cdfc0ccc2cab80c/contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8", size = 1322458 }, + { url = "https://files.pythonhosted.org/packages/22/85/4f8bfd83972cf8909a4d36d16b177f7b8bdd942178ea4bf877d4a380a91c/contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294", size = 172643 }, + { url = "https://files.pythonhosted.org/packages/cc/4a/fb3c83c1baba64ba90443626c228ca14f19a87c51975d3b1de308dd2cf08/contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087", size = 218301 }, + { url = "https://files.pythonhosted.org/packages/76/65/702f4064f397821fea0cb493f7d3bc95a5d703e20954dce7d6d39bacf378/contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8", size = 278972 }, + { url = "https://files.pythonhosted.org/packages/80/85/21f5bba56dba75c10a45ec00ad3b8190dbac7fd9a8a8c46c6116c933e9cf/contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b", size = 263375 }, + { url = "https://files.pythonhosted.org/packages/0a/64/084c86ab71d43149f91ab3a4054ccf18565f0a8af36abfa92b1467813ed6/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973", size = 307188 }, + { url = "https://files.pythonhosted.org/packages/3d/ff/d61a4c288dc42da0084b8d9dc2aa219a850767165d7d9a9c364ff530b509/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18", size = 345644 }, + { url = "https://files.pythonhosted.org/packages/ca/aa/00d2313d35ec03f188e8f0786c2fc61f589306e02fdc158233697546fd58/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8", size = 317141 }, + { url = "https://files.pythonhosted.org/packages/8d/6a/b5242c8cb32d87f6abf4f5e3044ca397cb1a76712e3fa2424772e3ff495f/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6", size = 323469 }, + { url = "https://files.pythonhosted.org/packages/6f/a6/73e929d43028a9079aca4bde107494864d54f0d72d9db508a51ff0878593/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2", size = 1260894 }, + { url = "https://files.pythonhosted.org/packages/2b/1e/1e726ba66eddf21c940821df8cf1a7d15cb165f0682d62161eaa5e93dae1/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927", size = 1314829 }, + { url = "https://files.pythonhosted.org/packages/d1/09/60e486dc2b64c94ed33e58dcfb6f808192c03dfc5574c016218b9b7680dc/contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c", size = 261886 }, + { url = "https://files.pythonhosted.org/packages/19/20/b57f9f7174fcd439a7789fb47d764974ab646fa34d1790551de386457a8e/contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779", size = 311008 }, + { url = "https://files.pythonhosted.org/packages/74/fc/5040d42623a1845d4f17a418e590fd7a79ae8cb2bad2b2f83de63c3bdca4/contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4", size = 215690 }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, +] + +[[package]] +name = "cyxtrax" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "artistlib" }, + { name = "dm-pix" }, + { name = "h5py" }, + { name = "jax", marker = "sys_platform == 'linux' or sys_platform == 'windows'" }, + { name = "jax", extra = ["cuda12"], marker = "sys_platform == 'linux'" }, + { name = "matplotlib" }, + { name = "numpy" }, + { name = "ruff" }, + { name = "scipy" }, + { name = "xraylib" }, +] + +[package.metadata] +requires-dist = [ + { name = "artistlib", git = "https://github.com/wittlsn/aRTist-PythonLib" }, + { name = "dm-pix", specifier = ">=0.4.3" }, + { name = "h5py", specifier = ">=3.12.1" }, + { name = "jax", marker = "sys_platform == 'windows'", specifier = ">=0.4.35" }, + { name = "jax", extras = ["cuda12"], marker = "sys_platform == 'linux'", specifier = ">=0.4.35" }, + { name = "matplotlib", specifier = ">=3.9.2" }, + { name = "numpy", specifier = ">=2.1.3" }, + { name = "ruff", specifier = ">=0.7.3" }, + { name = "scipy", specifier = ">=1.14.1" }, + { name = "xraylib", specifier = ">=4.1.5" }, +] + +[[package]] +name = "dm-pix" +version = "0.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "chex" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/c3/04acc8314dedc0eb59809d3da8b0a1cdf07c72f150463f81db7b0f4694a4/dm_pix-0.4.3.tar.gz", hash = "sha256:03031112c73b1877e2eaee42d7f066a70feb7538df17c4edc7025e5174725a1a", size = 48187 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/56/a4a1bee7dc5b0f8da5d34489e160ce1cad4cceaa24435434fa9724974fe6/dm_pix-0.4.3-py3-none-any.whl", hash = "sha256:462ed274dbd071400ed7ea6ff3242bf71433691fcc38d483fe6a849366c44647", size = 56492 }, +] + +[[package]] +name = "fonttools" +version = "4.54.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/1d/70b58e342e129f9c0ce030029fb4b2b0670084bbbfe1121d008f6a1e361c/fonttools-4.54.1.tar.gz", hash = "sha256:957f669d4922f92c171ba01bef7f29410668db09f6c02111e22b2bce446f3285", size = 3463867 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/f9/285c9a2d0e86b9bf2babfe19bec00502361fda56cea144d6a269ab9a32e6/fonttools-4.54.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7ed7ee041ff7b34cc62f07545e55e1468808691dddfd315d51dd82a6b37ddef2", size = 2766970 }, + { url = "https://files.pythonhosted.org/packages/2f/9a/9d899e7ae55b0dd30632e6ca36c0f5fa1205b1b096ec171c9be903673058/fonttools-4.54.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41bb0b250c8132b2fcac148e2e9198e62ff06f3cc472065dff839327945c5882", size = 2254639 }, + { url = "https://files.pythonhosted.org/packages/16/6f/b99e0c347732fb003077a2cff38c26f381969b74329aa5597e344d540fe1/fonttools-4.54.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7965af9b67dd546e52afcf2e38641b5be956d68c425bef2158e95af11d229f10", size = 4574346 }, + { url = "https://files.pythonhosted.org/packages/e5/12/9a45294a7c4520cc32936edd15df1d5c24af701d2f5f51070a9a43d7664b/fonttools-4.54.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278913a168f90d53378c20c23b80f4e599dca62fbffae4cc620c8eed476b723e", size = 4630045 }, + { url = "https://files.pythonhosted.org/packages/64/52/ba4f00eb6003e4089264cd9ce126cddec2b39c78f1ab01be9dc389a197ca/fonttools-4.54.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0e88e3018ac809b9662615072dcd6b84dca4c2d991c6d66e1970a112503bba7e", size = 4569527 }, + { url = "https://files.pythonhosted.org/packages/41/ff/85f93a14c8acf978f332508f980dcaff5ed5f0cf284371eb101a78f0b1f4/fonttools-4.54.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:4aa4817f0031206e637d1e685251ac61be64d1adef111060df84fdcbc6ab6c44", size = 4741677 }, + { url = "https://files.pythonhosted.org/packages/6f/f0/06ea7d9f8b7b6d4758a50271517db04039c4c6da8fa0475d417e005624d0/fonttools-4.54.1-cp310-cp310-win32.whl", hash = "sha256:7e3b7d44e18c085fd8c16dcc6f1ad6c61b71ff463636fcb13df7b1b818bd0c02", size = 2166797 }, + { url = "https://files.pythonhosted.org/packages/71/73/545c817e34b8c34585291951722e1a5ae579380deb009576d9d244b13ab0/fonttools-4.54.1-cp310-cp310-win_amd64.whl", hash = "sha256:dd9cc95b8d6e27d01e1e1f1fae8559ef3c02c76317da650a19047f249acd519d", size = 2210552 }, + { url = "https://files.pythonhosted.org/packages/aa/2c/8b5d82fe2d9c7f260fb73121418f5e07d4e38c329ea3886a5b0e55586113/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5419771b64248484299fa77689d4f3aeed643ea6630b2ea750eeab219588ba20", size = 2768112 }, + { url = "https://files.pythonhosted.org/packages/37/2e/f94118b92f7b6a9ec93840101b64bfdd09f295b266133857e8e852a5c35c/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:301540e89cf4ce89d462eb23a89464fef50915255ece765d10eee8b2bf9d75b2", size = 2254739 }, + { url = "https://files.pythonhosted.org/packages/45/4b/8a32f56a13e78256192f77d6b65583c43538c7955f5420887bb574b91ddf/fonttools-4.54.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76ae5091547e74e7efecc3cbf8e75200bc92daaeb88e5433c5e3e95ea8ce5aa7", size = 4879772 }, + { url = "https://files.pythonhosted.org/packages/96/13/748b7f7239893ff0796de11074b0ad8aa4c3da2d9f4d79a128b0b16147f3/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82834962b3d7c5ca98cb56001c33cf20eb110ecf442725dc5fdf36d16ed1ab07", size = 4927686 }, + { url = "https://files.pythonhosted.org/packages/7c/82/91bc5a378b4a0593fa90ea706f68ce7e9e871c6873e0d91e134d107758db/fonttools-4.54.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d26732ae002cc3d2ecab04897bb02ae3f11f06dd7575d1df46acd2f7c012a8d8", size = 4890789 }, + { url = "https://files.pythonhosted.org/packages/ea/ca/82be5d4f8b78405cdb3f7f3f1316af5e8db93216121f19da9f684a35beee/fonttools-4.54.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:58974b4987b2a71ee08ade1e7f47f410c367cdfc5a94fabd599c88165f56213a", size = 5061351 }, + { url = "https://files.pythonhosted.org/packages/da/2f/fd6e1b01c80c473c3ac52492dcf8d26cdf5f4a89b4f30875ecfbda55e7ff/fonttools-4.54.1-cp311-cp311-win32.whl", hash = "sha256:ab774fa225238986218a463f3fe151e04d8c25d7de09df7f0f5fce27b1243dbc", size = 2166210 }, + { url = "https://files.pythonhosted.org/packages/63/f1/3a081cd047d83b5966cb0d7ef3fea929ee6eddeb94d8fbfdb2a19bd60cc7/fonttools-4.54.1-cp311-cp311-win_amd64.whl", hash = "sha256:07e005dc454eee1cc60105d6a29593459a06321c21897f769a281ff2d08939f6", size = 2211946 }, + { url = "https://files.pythonhosted.org/packages/27/b6/f9d365932dcefefdcc794985f8846471e60932070c557e0f66ed195fccec/fonttools-4.54.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:54471032f7cb5fca694b5f1a0aaeba4af6e10ae989df408e0216f7fd6cdc405d", size = 2761873 }, + { url = "https://files.pythonhosted.org/packages/67/9d/cfbfe36e5061a8f68b154454ba2304eb01f40d4ba9b63e41d9058909baed/fonttools-4.54.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fa92cb248e573daab8d032919623cc309c005086d743afb014c836636166f08", size = 2251828 }, + { url = "https://files.pythonhosted.org/packages/90/41/5573e074739efd9227dd23647724f01f6f07ad062fe09d02e91c5549dcf7/fonttools-4.54.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a911591200114969befa7f2cb74ac148bce5a91df5645443371aba6d222e263", size = 4792544 }, + { url = "https://files.pythonhosted.org/packages/08/07/aa85cc62abcc940b25d14b542cf585eebf4830032a7f6a1395d696bb3231/fonttools-4.54.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93d458c8a6a354dc8b48fc78d66d2a8a90b941f7fec30e94c7ad9982b1fa6bab", size = 4875892 }, + { url = "https://files.pythonhosted.org/packages/47/23/c5726c2615446c498a976bed21c35a242a97eee39930a2655d616ca885cc/fonttools-4.54.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5eb2474a7c5be8a5331146758debb2669bf5635c021aee00fd7c353558fc659d", size = 4769822 }, + { url = "https://files.pythonhosted.org/packages/8f/7b/87f7f7d35e0732ac67422dfa6f05e2b568fb6ca2dcd7f3e4f500293cfd75/fonttools-4.54.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9c563351ddc230725c4bdf7d9e1e92cbe6ae8553942bd1fb2b2ff0884e8b714", size = 5029455 }, + { url = "https://files.pythonhosted.org/packages/e0/09/241aa498587889576838aa73c78d22b70ce06970807a5475d372baa7ccb7/fonttools-4.54.1-cp312-cp312-win32.whl", hash = "sha256:fdb062893fd6d47b527d39346e0c5578b7957dcea6d6a3b6794569370013d9ac", size = 2154411 }, + { url = "https://files.pythonhosted.org/packages/b9/0a/a57caaff3bc880779317cb157e5b49dc47fad54effe027016abd355b0651/fonttools-4.54.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4564cf40cebcb53f3dc825e85910bf54835e8a8b6880d59e5159f0f325e637e", size = 2200412 }, + { url = "https://files.pythonhosted.org/packages/05/3d/cc515cae84a11d696f2cb7c139a90997b15f02e2e97ec09a5d79302cbcd7/fonttools-4.54.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6e37561751b017cf5c40fce0d90fd9e8274716de327ec4ffb0df957160be3bff", size = 2749174 }, + { url = "https://files.pythonhosted.org/packages/03/03/05d4b22d1a674d066380657f60bbc0eda2d206446912e676d1a33a206878/fonttools-4.54.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:357cacb988a18aace66e5e55fe1247f2ee706e01debc4b1a20d77400354cddeb", size = 2246267 }, + { url = "https://files.pythonhosted.org/packages/52/c3/bb6086adb675e8b0963a7dbb7769e7118c95b687dd318cd660aefd4b4c8c/fonttools-4.54.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8e953cc0bddc2beaf3a3c3b5dd9ab7554677da72dfaf46951e193c9653e515a", size = 4855090 }, + { url = "https://files.pythonhosted.org/packages/80/a1/d7192b6a104e3f9ea8e5b1c3463a6240399f0fa826a782eff636cbe0495a/fonttools-4.54.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58d29b9a294573d8319f16f2f79e42428ba9b6480442fa1836e4eb89c4d9d61c", size = 5005449 }, + { url = "https://files.pythonhosted.org/packages/5a/6c/ecfd5c6cd8c9006e85b128d073af26bb263e8aa47506374cb14b25bcf65f/fonttools-4.54.1-cp313-cp313-win32.whl", hash = "sha256:9ef1b167e22709b46bf8168368b7b5d3efeaaa746c6d39661c1b4405b6352e58", size = 2152496 }, + { url = "https://files.pythonhosted.org/packages/63/da/f7a1d837de419e3d4cccbd0dbf53c7399f610f65ceb9bcbf2480f3ae7950/fonttools-4.54.1-cp313-cp313-win_amd64.whl", hash = "sha256:262705b1663f18c04250bd1242b0515d3bbae177bee7752be67c979b7d47f43d", size = 2197257 }, + { url = "https://files.pythonhosted.org/packages/57/5e/de2e6e51cb6894f2f2bc2641f6c845561361b622e96df3cca04df77222c9/fonttools-4.54.1-py3-none-any.whl", hash = "sha256:37cddd62d83dc4f72f7c3f3c2bcf2697e89a30efb152079896544a93907733bd", size = 1096920 }, +] + +[[package]] +name = "h5py" +version = "3.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/0c/5c2b0a88158682aeafb10c1c2b735df5bc31f165bfe192f2ee9f2a23b5f1/h5py-3.12.1.tar.gz", hash = "sha256:326d70b53d31baa61f00b8aa5f95c2fcb9621a3ee8365d770c551a13dbbcbfdf", size = 411457 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/7d/b21045fbb004ad8bb6fb3be4e6ca903841722706f7130b9bba31ef2f88e3/h5py-3.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f0f1a382cbf494679c07b4371f90c70391dedb027d517ac94fa2c05299dacda", size = 3402133 }, + { url = "https://files.pythonhosted.org/packages/29/a7/3c2a33fba1da64a0846744726fd067a92fb8abb887875a0dd8e3bac8b45d/h5py-3.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cb65f619dfbdd15e662423e8d257780f9a66677eae5b4b3fc9dca70b5fd2d2a3", size = 2866436 }, + { url = "https://files.pythonhosted.org/packages/1e/d0/4bf67c3937a2437c20844165766ddd1a1817ae6b9544c3743050d8e0f403/h5py-3.12.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b15d8dbd912c97541312c0e07438864d27dbca857c5ad634de68110c6beb1c2", size = 5168596 }, + { url = "https://files.pythonhosted.org/packages/85/bc/e76f4b2096e0859225f5441d1b7f5e2041fffa19fc2c16756c67078417aa/h5py-3.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59685fe40d8c1fbbee088c88cd4da415a2f8bee5c270337dc5a1c4aa634e3307", size = 5341537 }, + { url = "https://files.pythonhosted.org/packages/99/bd/fb8ed45308bb97e04c02bd7aed324ba11e6a4bf9ed73967ca2a168e9cf92/h5py-3.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:577d618d6b6dea3da07d13cc903ef9634cde5596b13e832476dd861aaf651f3e", size = 2990575 }, + { url = "https://files.pythonhosted.org/packages/33/61/c463dc5fc02fbe019566d067a9d18746cd3c664f29c9b8b3c3f9ed025365/h5py-3.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ccd9006d92232727d23f784795191bfd02294a4f2ba68708825cb1da39511a93", size = 3410828 }, + { url = "https://files.pythonhosted.org/packages/95/9d/eb91a9076aa998bb2179d6b1788055ea09cdf9d6619cd967f1d3321ed056/h5py-3.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ad8a76557880aed5234cfe7279805f4ab5ce16b17954606cca90d578d3e713ef", size = 2872586 }, + { url = "https://files.pythonhosted.org/packages/b0/62/e2b1f9723ff713e3bd3c16dfeceec7017eadc21ef063d8b7080c0fcdc58a/h5py-3.12.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1473348139b885393125126258ae2d70753ef7e9cec8e7848434f385ae72069e", size = 5273038 }, + { url = "https://files.pythonhosted.org/packages/e1/89/118c3255d6ff2db33b062ec996a762d99ae50c21f54a8a6047ae8eda1b9f/h5py-3.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:018a4597f35092ae3fb28ee851fdc756d2b88c96336b8480e124ce1ac6fb9166", size = 5452688 }, + { url = "https://files.pythonhosted.org/packages/1d/4d/cbd3014eb78d1e449b29beba1f3293a841aa8086c6f7968c383c2c7ff076/h5py-3.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fdf95092d60e8130ba6ae0ef7a9bd4ade8edbe3569c13ebbaf39baefffc5ba4", size = 3006095 }, + { url = "https://files.pythonhosted.org/packages/d4/e1/ea9bfe18a3075cdc873f0588ff26ce394726047653557876d7101bf0c74e/h5py-3.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:06a903a4e4e9e3ebbc8b548959c3c2552ca2d70dac14fcfa650d9261c66939ed", size = 3372538 }, + { url = "https://files.pythonhosted.org/packages/0d/74/1009b663387c025e8fa5f3ee3cf3cd0d99b1ad5c72eeb70e75366b1ce878/h5py-3.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7b3b8f3b48717e46c6a790e3128d39c61ab595ae0a7237f06dfad6a3b51d5351", size = 2868104 }, + { url = "https://files.pythonhosted.org/packages/af/52/c604adc06280c15a29037d4aa79a24fe54d8d0b51085e81ed24b2fa995f7/h5py-3.12.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:050a4f2c9126054515169c49cb900949814987f0c7ae74c341b0c9f9b5056834", size = 5194606 }, + { url = "https://files.pythonhosted.org/packages/fa/63/eeaacff417b393491beebabb8a3dc5342950409eb6d7b39d437289abdbae/h5py-3.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c4b41d1019322a5afc5082864dfd6359f8935ecd37c11ac0029be78c5d112c9", size = 5413256 }, + { url = "https://files.pythonhosted.org/packages/86/f7/bb465dcb92ca3521a15cbe1031f6d18234dbf1fb52a6796a00bfaa846ebf/h5py-3.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:e4d51919110a030913201422fb07987db4338eba5ec8c5a15d6fab8e03d443fc", size = 2993055 }, + { url = "https://files.pythonhosted.org/packages/23/1c/ecdd0efab52c24f2a9bf2324289828b860e8dd1e3c5ada3cf0889e14fdc1/h5py-3.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:513171e90ed92236fc2ca363ce7a2fc6f2827375efcbb0cc7fbdd7fe11fecafc", size = 3346239 }, + { url = "https://files.pythonhosted.org/packages/93/cd/5b6f574bf3e318bbe305bc93ba45181676550eb44ba35e006d2e98004eaa/h5py-3.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59400f88343b79655a242068a9c900001a34b63e3afb040bd7cdf717e440f653", size = 2843416 }, + { url = "https://files.pythonhosted.org/packages/8a/4f/b74332f313bfbe94ba03fff784219b9db385e6139708e55b11490149f90a/h5py-3.12.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e465aee0ec353949f0f46bf6c6f9790a2006af896cee7c178a8c3e5090aa32", size = 5154390 }, + { url = "https://files.pythonhosted.org/packages/1a/57/93ea9e10a6457ea8d3b867207deb29a527e966a08a84c57ffd954e32152a/h5py-3.12.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba51c0c5e029bb5420a343586ff79d56e7455d496d18a30309616fdbeed1068f", size = 5378244 }, + { url = "https://files.pythonhosted.org/packages/50/51/0bbf3663062b2eeee78aa51da71e065f8a0a6e3cb950cc7020b4444999e6/h5py-3.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:52ab036c6c97055b85b2a242cb540ff9590bacfda0c03dd0cf0661b311f522f8", size = 2979760 }, +] + +[[package]] +name = "jax" +version = "0.4.35" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaxlib" }, + { name = "ml-dtypes" }, + { name = "numpy" }, + { name = "opt-einsum" }, + { name = "scipy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e3/34/21da583b9596e72bb8e95b6197dee0a44b96b9ea2c147fccabd43ca5515b/jax-0.4.35.tar.gz", hash = "sha256:c0c986993026b10bf6f607fecb7417377460254640766ce40f1fef3fd139c12e", size = 1861189 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/20/6c57c50c0ccc645fea1895950f1e5cd02f961ee44b3ffe83617fa46b0c1d/jax-0.4.35-py3-none-any.whl", hash = "sha256:fa99e909a31424abfec750019a6dd36f6acc18a6e7d40e2c0086b932cc351325", size = 2158621 }, +] + +[package.optional-dependencies] +cuda12 = [ + { name = "jax-cuda12-plugin", extra = ["with-cuda"], marker = "sys_platform == 'linux'" }, + { name = "jaxlib", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "jax-cuda12-pjrt" +version = "0.4.35" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/ba/12d0f831331e0eb7dafc49eb1bd0a905098aca917456d6ccf57efd57b908/jax_cuda12_pjrt-0.4.35-py3-none-manylinux2014_aarch64.whl", hash = "sha256:81980f1696749351364d7999ee5cb21bedd9d14daa01b40eb60d20f2210da11c", size = 84301075 }, + { url = "https://files.pythonhosted.org/packages/d7/aa/f15ea857ad9bcff7a0c942dc570ca718b026cc0cc5c513525bb08cacf3c0/jax_cuda12_pjrt-0.4.35-py3-none-manylinux2014_x86_64.whl", hash = "sha256:0ffe7e1ba65659bd5738c2cc5addaf0a56205d2188eec5da194b63c068e1fdd2", size = 100760554 }, +] + +[[package]] +name = "jax-cuda12-plugin" +version = "0.4.35" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jax-cuda12-pjrt", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/eb/f317f426b8ea56a9e634d6eb06230d9d2d01cc34066defeb7d3fd6ab5708/jax_cuda12_plugin-0.4.35-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:30290570a8a0547e59c1fd927aefb693d4a4fe15aae23c0a1e5c34eed82bef49", size = 15545891 }, + { url = "https://files.pythonhosted.org/packages/f5/2b/c39f961139b655d3d8ea203615486eab5aceea47540a50f377ff98958f43/jax_cuda12_plugin-0.4.35-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:5fcc47ef49cb8ff5ceaa67d143a18b22c78456a0967d243963312901d978e96e", size = 15519460 }, + { url = "https://files.pythonhosted.org/packages/7e/58/8f7eba5d6199e7b99903f85bbd97c456523f4f910717c409e5d082289723/jax_cuda12_plugin-0.4.35-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:982c9b6fcc6f7a64cb4cb19aa2f9f98cfc29faac28ef04721b4617da76d81949", size = 15546115 }, + { url = "https://files.pythonhosted.org/packages/5a/45/d1f9595ee26c2457f71df5b4a786775d77a8d2e96a9697445fd777bab35a/jax_cuda12_plugin-0.4.35-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:1752de1060f4671be6da47b88c1e0bcb1d2fe9e99958e95aa375a9b17dfa1656", size = 15520457 }, + { url = "https://files.pythonhosted.org/packages/0f/6b/2b08b0a33dbbd410ed6746d2f12c67b4b7a1318590cf05fa3ca7dbff4c46/jax_cuda12_plugin-0.4.35-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:767e53cd0ab0f543f7ac64c74e326b4e7145ca6424d0e7128373e5777012e6d9", size = 15541645 }, + { url = "https://files.pythonhosted.org/packages/23/a1/781f98da41b9abf63a1468c5babbafa7b1bdb766c081386644a4034fbdef/jax_cuda12_plugin-0.4.35-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:80aa5e628e8e9dd4f89b767f73900152033c3bf6d5f49dc2081e93f9bac1c9dc", size = 15516745 }, + { url = "https://files.pythonhosted.org/packages/17/5d/4cb713a31a92e451739732a86b2dd18ed7ca89825c347c47717d89843108/jax_cuda12_plugin-0.4.35-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:c241bd2decf9eeaad6c35aeccf5ede56447dc4152fc82d9272d103cb51450abe", size = 15542531 }, + { url = "https://files.pythonhosted.org/packages/d2/d1/7517b43aa06dcfa39bb9ef9ee485c2a612c2aa822f113871b36d84340d52/jax_cuda12_plugin-0.4.35-cp313-cp313-manylinux2014_x86_64.whl", hash = "sha256:91326529c11f64c954f1421cdf60d2bdfaa51caf2152dc743a20557933bae8d9", size = 15516650 }, +] + +[package.optional-dependencies] +with-cuda = [ + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvcc-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "jaxlib" +version = "0.4.34" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ml-dtypes" }, + { name = "numpy" }, + { name = "scipy" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/31/2e254fe2fc23201775a7d0ccd1bcde892cfa349eb805744b81b15e0dcf74/jaxlib-0.4.34-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:b7a212a3cb5c6acc201c32ae4f4b5f5a9ac09457fbb77ba8db5ce7e7d4adc214", size = 87399257 }, + { url = "https://files.pythonhosted.org/packages/1e/67/6a344c357caad33e84b871925cd043b4218fc13a427266d1a1dedcb1c095/jaxlib-0.4.34-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:45d719a2ce0ebf21255a277b71d756f3609b7b5be70cddc5d88fd58c35219de0", size = 67617952 }, + { url = "https://files.pythonhosted.org/packages/dd/ea/12c836126419ca80248228f2236831617eedb1e3640c34c942606f33bb08/jaxlib-0.4.34-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:3e60bc826933082e99b19b87c21818a8d26fcdb01f418d47cedff554746fd6cc", size = 69391770 }, + { url = "https://files.pythonhosted.org/packages/e4/b0/a5bd34643c070e50829beec217189eab1acdfea334df1f9ddb4e5f8bec0f/jaxlib-0.4.34-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:d840e64b85f8865404d6d225b9bb340e158df1457152a361b05680e24792b232", size = 86094116 }, + { url = "https://files.pythonhosted.org/packages/d8/c9/35a4233fe74ddd5aabe89aac1b3992b0e463982564252d21fd263d4d9992/jaxlib-0.4.34-cp310-cp310-win_amd64.whl", hash = "sha256:b0001c8f0e2b1c7bc99e4f314b524a340d25653505c1a1484d4041a9d3617f6f", size = 55206389 }, + { url = "https://files.pythonhosted.org/packages/bf/14/00a3385532d72ab51bd8e9f8c3e19a2e257667955565e9fc10236771dd06/jaxlib-0.4.34-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:8ee3f93836e53c86556ccd9449a4ea43516ee05184d031a71dd692e81259f7d9", size = 87420889 }, + { url = "https://files.pythonhosted.org/packages/66/78/d1535ee73fe505dc6c8831c19c4846afdce7df5acefb9f8ee885aa73d700/jaxlib-0.4.34-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c9d3adcae43a33aad4332be9c2aedc5ef751d1e755f917a5afb30c7872eacaa8", size = 67635880 }, + { url = "https://files.pythonhosted.org/packages/aa/06/3e09e794acf308e170905d732eca0d041449503c47505cc22e8ef78a989d/jaxlib-0.4.34-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:571ef03259835458111596a71a2f4a6fabf4ec34595df4cea555035362ac5bf0", size = 69421901 }, + { url = "https://files.pythonhosted.org/packages/c7/d0/6bc81c0b1d507f403e6085ce76a429e6d7f94749d742199252e299dd1424/jaxlib-0.4.34-cp311-cp311-manylinux2014_x86_64.whl", hash = "sha256:3bcfa639ca3cfaf86c8ceebd5fc0d47300fd98a078014a1d0cc03133e1523d5f", size = 86114491 }, + { url = "https://files.pythonhosted.org/packages/9d/5d/7e71019af5f6fdebe6c10eab97d01f44b931d94609330da9e142cb155f8c/jaxlib-0.4.34-cp311-cp311-win_amd64.whl", hash = "sha256:133070d4fec5525ffea4dc72956398c1cf647a04dcb37f8a935ee82af78d9965", size = 55241262 }, + { url = "https://files.pythonhosted.org/packages/bc/42/5038983664494dfb50f8669a662d965d7ea62f9250e40d8cd36dcf9ac3dd/jaxlib-0.4.34-cp312-cp312-macosx_10_14_x86_64.whl", hash = "sha256:c7b3e724a30426a856070aba0192b5d199e95b4411070e7ad96ad8b196877b10", size = 87473956 }, + { url = "https://files.pythonhosted.org/packages/87/2e/8a75d3107c019c370c50c01acc205da33f9d6fba830950401a772a8e9f6d/jaxlib-0.4.34-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:096f0ca309d41fa692a9d1f2f9baab1c5c8ca0749876ebb3f748e738a27c7ff4", size = 67650276 }, + { url = "https://files.pythonhosted.org/packages/af/09/cceae2d251a506b4297679d10ee9f5e905a6b992b0687d553c9470ffd1db/jaxlib-0.4.34-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:1a30771d85fa77f9ab8f18e63240f455ab3a3f87660ed7b8d5eea6ceecbe5c1e", size = 69431284 }, + { url = "https://files.pythonhosted.org/packages/e7/0d/4faf839e3c8ce2a5b615df64427be3e870899c72c0ebfb5859348150aba1/jaxlib-0.4.34-cp312-cp312-manylinux2014_x86_64.whl", hash = "sha256:48272e9034ff868d4328cf0055a07882fd2be93f59dfb6283af7de491f9d1290", size = 86151183 }, + { url = "https://files.pythonhosted.org/packages/a4/bc/a38f99071fca6cc31ae949e508a23b0de5de559da594443bb625a1adb8f3/jaxlib-0.4.34-cp312-cp312-win_amd64.whl", hash = "sha256:901cb4040ed24eae40071d8114ea8d10dff436277fa74a1a5b9e7206f641151c", size = 55278745 }, + { url = "https://files.pythonhosted.org/packages/21/4e/fab0606683af7aa9284a32d2b188ff132cffb0ee3ea04d941a547eb776d1/jaxlib-0.4.34-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:72e22e99a5dc890a64443c3fc12f13f20091f578c405a76de077ba42b4c62cd7", size = 87474367 }, + { url = "https://files.pythonhosted.org/packages/3e/1b/709be16d543a3db5b471ee5e7d089c57484c386b08499923e43bd8da5d0b/jaxlib-0.4.34-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c303f5acaf6c56ce5ff133a923c9b6247bdebedde15bd2c893c24be4d8f71306", size = 67651281 }, + { url = "https://files.pythonhosted.org/packages/85/9e/f3801096cd4a2c764af7a1f6b683c769706602ea72b27ec35bacfcc4cd4f/jaxlib-0.4.34-cp313-cp313-manylinux2014_aarch64.whl", hash = "sha256:7be673a876ebd1aef440fb7e3ebaf99a91abeb550c9728c644b7d7c7b5d7c108", size = 69432987 }, + { url = "https://files.pythonhosted.org/packages/e6/79/61301f55b24c3a898ef9bc4e13600b66e3f838623fc6f87648ac1ccbca01/jaxlib-0.4.34-cp313-cp313-manylinux2014_x86_64.whl", hash = "sha256:87f25a477cd279840e53718403f97092eba0e8a945fcab47bcf435b6f9119dda", size = 86152550 }, + { url = "https://files.pythonhosted.org/packages/16/b0/e682d02126e0062b58dec0f0851048592396f74c24b4a4412dce4ddbbadb/jaxlib-0.4.34-cp313-cp313-win_amd64.whl", hash = "sha256:6b43a974c5d91a19912d138f2658dd8dbb7d30dcdff5c961d896c673e872b611", size = 55279410 }, +] + +[[package]] +name = "kiwisolver" +version = "1.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60", size = 97286 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/14/fc943dd65268a96347472b4fbe5dcc2f6f55034516f80576cd0dd3a8930f/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6", size = 122440 }, + { url = "https://files.pythonhosted.org/packages/1e/46/e68fed66236b69dd02fcdb506218c05ac0e39745d696d22709498896875d/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17", size = 65758 }, + { url = "https://files.pythonhosted.org/packages/ef/fa/65de49c85838681fc9cb05de2a68067a683717321e01ddafb5b8024286f0/kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9", size = 64311 }, + { url = "https://files.pythonhosted.org/packages/42/9c/cc8d90f6ef550f65443bad5872ffa68f3dee36de4974768628bea7c14979/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9", size = 1637109 }, + { url = "https://files.pythonhosted.org/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c", size = 1617814 }, + { url = "https://files.pythonhosted.org/packages/12/5d/c36140313f2510e20207708adf36ae4919416d697ee0236b0ddfb6fd1050/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599", size = 1400881 }, + { url = "https://files.pythonhosted.org/packages/56/d0/786e524f9ed648324a466ca8df86298780ef2b29c25313d9a4f16992d3cf/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05", size = 1512972 }, + { url = "https://files.pythonhosted.org/packages/67/5a/77851f2f201e6141d63c10a0708e996a1363efaf9e1609ad0441b343763b/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407", size = 1444787 }, + { url = "https://files.pythonhosted.org/packages/06/5f/1f5eaab84355885e224a6fc8d73089e8713dc7e91c121f00b9a1c58a2195/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278", size = 2199212 }, + { url = "https://files.pythonhosted.org/packages/b5/28/9152a3bfe976a0ae21d445415defc9d1cd8614b2910b7614b30b27a47270/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5", size = 2346399 }, + { url = "https://files.pythonhosted.org/packages/26/f6/453d1904c52ac3b400f4d5e240ac5fec25263716723e44be65f4d7149d13/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad", size = 2308688 }, + { url = "https://files.pythonhosted.org/packages/5a/9a/d4968499441b9ae187e81745e3277a8b4d7c60840a52dc9d535a7909fac3/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895", size = 2445493 }, + { url = "https://files.pythonhosted.org/packages/07/c9/032267192e7828520dacb64dfdb1d74f292765f179e467c1cba97687f17d/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3", size = 2262191 }, + { url = "https://files.pythonhosted.org/packages/6c/ad/db0aedb638a58b2951da46ddaeecf204be8b4f5454df020d850c7fa8dca8/kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc", size = 46644 }, + { url = "https://files.pythonhosted.org/packages/12/ca/d0f7b7ffbb0be1e7c2258b53554efec1fd652921f10d7d85045aff93ab61/kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c", size = 55877 }, + { url = "https://files.pythonhosted.org/packages/97/6c/cfcc128672f47a3e3c0d918ecb67830600078b025bfc32d858f2e2d5c6a4/kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a", size = 48347 }, + { url = "https://files.pythonhosted.org/packages/e9/44/77429fa0a58f941d6e1c58da9efe08597d2e86bf2b2cce6626834f49d07b/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54", size = 122442 }, + { url = "https://files.pythonhosted.org/packages/e5/20/8c75caed8f2462d63c7fd65e16c832b8f76cda331ac9e615e914ee80bac9/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95", size = 65762 }, + { url = "https://files.pythonhosted.org/packages/f4/98/fe010f15dc7230f45bc4cf367b012d651367fd203caaa992fd1f5963560e/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935", size = 64319 }, + { url = "https://files.pythonhosted.org/packages/8b/1b/b5d618f4e58c0675654c1e5051bcf42c776703edb21c02b8c74135541f60/kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb", size = 1334260 }, + { url = "https://files.pythonhosted.org/packages/b8/01/946852b13057a162a8c32c4c8d2e9ed79f0bb5d86569a40c0b5fb103e373/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02", size = 1426589 }, + { url = "https://files.pythonhosted.org/packages/70/d1/c9f96df26b459e15cf8a965304e6e6f4eb291e0f7a9460b4ad97b047561e/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51", size = 1541080 }, + { url = "https://files.pythonhosted.org/packages/d3/73/2686990eb8b02d05f3de759d6a23a4ee7d491e659007dd4c075fede4b5d0/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052", size = 1470049 }, + { url = "https://files.pythonhosted.org/packages/a7/4b/2db7af3ed3af7c35f388d5f53c28e155cd402a55432d800c543dc6deb731/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18", size = 1426376 }, + { url = "https://files.pythonhosted.org/packages/05/83/2857317d04ea46dc5d115f0df7e676997bbd968ced8e2bd6f7f19cfc8d7f/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545", size = 2222231 }, + { url = "https://files.pythonhosted.org/packages/0d/b5/866f86f5897cd4ab6d25d22e403404766a123f138bd6a02ecb2cdde52c18/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b", size = 2368634 }, + { url = "https://files.pythonhosted.org/packages/c1/ee/73de8385403faba55f782a41260210528fe3273d0cddcf6d51648202d6d0/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36", size = 2329024 }, + { url = "https://files.pythonhosted.org/packages/a1/e7/cd101d8cd2cdfaa42dc06c433df17c8303d31129c9fdd16c0ea37672af91/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3", size = 2468484 }, + { url = "https://files.pythonhosted.org/packages/e1/72/84f09d45a10bc57a40bb58b81b99d8f22b58b2040c912b7eb97ebf625bf2/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523", size = 2284078 }, + { url = "https://files.pythonhosted.org/packages/d2/d4/71828f32b956612dc36efd7be1788980cb1e66bfb3706e6dec9acad9b4f9/kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d", size = 46645 }, + { url = "https://files.pythonhosted.org/packages/a1/65/d43e9a20aabcf2e798ad1aff6c143ae3a42cf506754bcb6a7ed8259c8425/kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b", size = 56022 }, + { url = "https://files.pythonhosted.org/packages/35/b3/9f75a2e06f1b4ca00b2b192bc2b739334127d27f1d0625627ff8479302ba/kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376", size = 48536 }, + { url = "https://files.pythonhosted.org/packages/97/9c/0a11c714cf8b6ef91001c8212c4ef207f772dd84540104952c45c1f0a249/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2", size = 121808 }, + { url = "https://files.pythonhosted.org/packages/f2/d8/0fe8c5f5d35878ddd135f44f2af0e4e1d379e1c7b0716f97cdcb88d4fd27/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a", size = 65531 }, + { url = "https://files.pythonhosted.org/packages/80/c5/57fa58276dfdfa612241d640a64ca2f76adc6ffcebdbd135b4ef60095098/kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee", size = 63894 }, + { url = "https://files.pythonhosted.org/packages/8b/e9/26d3edd4c4ad1c5b891d8747a4f81b1b0aba9fb9721de6600a4adc09773b/kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640", size = 1369296 }, + { url = "https://files.pythonhosted.org/packages/b6/67/3f4850b5e6cffb75ec40577ddf54f7b82b15269cc5097ff2e968ee32ea7d/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f", size = 1461450 }, + { url = "https://files.pythonhosted.org/packages/52/be/86cbb9c9a315e98a8dc6b1d23c43cffd91d97d49318854f9c37b0e41cd68/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483", size = 1579168 }, + { url = "https://files.pythonhosted.org/packages/0f/00/65061acf64bd5fd34c1f4ae53f20b43b0a017a541f242a60b135b9d1e301/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258", size = 1507308 }, + { url = "https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e", size = 1464186 }, + { url = "https://files.pythonhosted.org/packages/0a/0f/529d0a9fffb4d514f2782c829b0b4b371f7f441d61aa55f1de1c614c4ef3/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107", size = 2247877 }, + { url = "https://files.pythonhosted.org/packages/d1/e1/66603ad779258843036d45adcbe1af0d1a889a07af4635f8b4ec7dccda35/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948", size = 2404204 }, + { url = "https://files.pythonhosted.org/packages/8d/61/de5fb1ca7ad1f9ab7970e340a5b833d735df24689047de6ae71ab9d8d0e7/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038", size = 2352461 }, + { url = "https://files.pythonhosted.org/packages/ba/d2/0edc00a852e369827f7e05fd008275f550353f1f9bcd55db9363d779fc63/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383", size = 2501358 }, + { url = "https://files.pythonhosted.org/packages/84/15/adc15a483506aec6986c01fb7f237c3aec4d9ed4ac10b756e98a76835933/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520", size = 2314119 }, + { url = "https://files.pythonhosted.org/packages/36/08/3a5bb2c53c89660863a5aa1ee236912269f2af8762af04a2e11df851d7b2/kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b", size = 46367 }, + { url = "https://files.pythonhosted.org/packages/19/93/c05f0a6d825c643779fc3c70876bff1ac221f0e31e6f701f0e9578690d70/kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb", size = 55884 }, + { url = "https://files.pythonhosted.org/packages/d2/f9/3828d8f21b6de4279f0667fb50a9f5215e6fe57d5ec0d61905914f5b6099/kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a", size = 48528 }, + { url = "https://files.pythonhosted.org/packages/c4/06/7da99b04259b0f18b557a4effd1b9c901a747f7fdd84cf834ccf520cb0b2/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e", size = 121913 }, + { url = "https://files.pythonhosted.org/packages/97/f5/b8a370d1aa593c17882af0a6f6755aaecd643640c0ed72dcfd2eafc388b9/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6", size = 65627 }, + { url = "https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750", size = 63888 }, + { url = "https://files.pythonhosted.org/packages/bf/3e/0b7172793d0f41cae5c923492da89a2ffcd1adf764c16159ca047463ebd3/kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d", size = 1369145 }, + { url = "https://files.pythonhosted.org/packages/77/92/47d050d6f6aced2d634258123f2688fbfef8ded3c5baf2c79d94d91f1f58/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379", size = 1461448 }, + { url = "https://files.pythonhosted.org/packages/9c/1b/8f80b18e20b3b294546a1adb41701e79ae21915f4175f311a90d042301cf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c", size = 1578750 }, + { url = "https://files.pythonhosted.org/packages/a4/fe/fe8e72f3be0a844f257cadd72689c0848c6d5c51bc1d60429e2d14ad776e/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34", size = 1507175 }, + { url = "https://files.pythonhosted.org/packages/39/fa/cdc0b6105d90eadc3bee525fecc9179e2b41e1ce0293caaf49cb631a6aaf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1", size = 1463963 }, + { url = "https://files.pythonhosted.org/packages/6e/5c/0c03c4e542720c6177d4f408e56d1c8315899db72d46261a4e15b8b33a41/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f", size = 2248220 }, + { url = "https://files.pythonhosted.org/packages/3d/ee/55ef86d5a574f4e767df7da3a3a7ff4954c996e12d4fbe9c408170cd7dcc/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b", size = 2404463 }, + { url = "https://files.pythonhosted.org/packages/0f/6d/73ad36170b4bff4825dc588acf4f3e6319cb97cd1fb3eb04d9faa6b6f212/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27", size = 2352842 }, + { url = "https://files.pythonhosted.org/packages/0b/16/fa531ff9199d3b6473bb4d0f47416cdb08d556c03b8bc1cccf04e756b56d/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a", size = 2501635 }, + { url = "https://files.pythonhosted.org/packages/78/7e/aa9422e78419db0cbe75fb86d8e72b433818f2e62e2e394992d23d23a583/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee", size = 2314556 }, + { url = "https://files.pythonhosted.org/packages/a8/b2/15f7f556df0a6e5b3772a1e076a9d9f6c538ce5f05bd590eca8106508e06/kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07", size = 46364 }, + { url = "https://files.pythonhosted.org/packages/0b/db/32e897e43a330eee8e4770bfd2737a9584b23e33587a0812b8e20aac38f7/kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76", size = 55887 }, + { url = "https://files.pythonhosted.org/packages/c8/a4/df2bdca5270ca85fd25253049eb6708d4127be2ed0e5c2650217450b59e9/kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650", size = 48530 }, + { url = "https://files.pythonhosted.org/packages/ac/59/741b79775d67ab67ced9bb38552da688c0305c16e7ee24bba7a2be253fb7/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643", size = 59491 }, + { url = "https://files.pythonhosted.org/packages/58/cc/fb239294c29a5656e99e3527f7369b174dd9cc7c3ef2dea7cb3c54a8737b/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706", size = 57648 }, + { url = "https://files.pythonhosted.org/packages/3b/ef/2f009ac1f7aab9f81efb2d837301d255279d618d27b6015780115ac64bdd/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6", size = 84257 }, + { url = "https://files.pythonhosted.org/packages/81/e1/c64f50987f85b68b1c52b464bb5bf73e71570c0f7782d626d1eb283ad620/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2", size = 80906 }, + { url = "https://files.pythonhosted.org/packages/fd/71/1687c5c0a0be2cee39a5c9c389e546f9c6e215e46b691d00d9f646892083/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4", size = 79951 }, + { url = "https://files.pythonhosted.org/packages/ea/8b/d7497df4a1cae9367adf21665dd1f896c2a7aeb8769ad77b662c5e2bcce7/kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a", size = 55715 }, +] + +[[package]] +name = "matplotlib" +version = "3.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "kiwisolver" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/d8/3d7f706c69e024d4287c1110d74f7dabac91d9843b99eadc90de9efc8869/matplotlib-3.9.2.tar.gz", hash = "sha256:96ab43906269ca64a6366934106fa01534454a69e471b7bf3d79083981aaab92", size = 36088381 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9d/84eeb82ecdd3ba71b12dd6ab5c820c5cc1e868003ecb3717d41b589ec02a/matplotlib-3.9.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:9d78bbc0cbc891ad55b4f39a48c22182e9bdaea7fc0e5dbd364f49f729ca1bbb", size = 7893310 }, + { url = "https://files.pythonhosted.org/packages/36/98/cbacbd30241369d099f9c13a2b6bc3b7068d85214f5b5795e583ac3d8aba/matplotlib-3.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c375cc72229614632c87355366bdf2570c2dac01ac66b8ad048d2dabadf2d0d4", size = 7764089 }, + { url = "https://files.pythonhosted.org/packages/a8/a0/917f3c6d3a8774a3a1502d9f3dfc1456e07c1fa0c211a23b75a69e154180/matplotlib-3.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d94ff717eb2bd0b58fe66380bd8b14ac35f48a98e7c6765117fe67fb7684e64", size = 8192377 }, + { url = "https://files.pythonhosted.org/packages/8d/9d/d06860390f9d154fa884f1740a5456378fb153ff57443c91a4a32bab7092/matplotlib-3.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab68d50c06938ef28681073327795c5db99bb4666214d2d5f880ed11aeaded66", size = 8303983 }, + { url = "https://files.pythonhosted.org/packages/9e/a7/c0e848ed7de0766c605af62d8097472a37f1a81d93e9afe94faa5890f24d/matplotlib-3.9.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:65aacf95b62272d568044531e41de26285d54aec8cb859031f511f84bd8b495a", size = 9083318 }, + { url = "https://files.pythonhosted.org/packages/09/6c/0fa50c001340a45cde44853c116d6551aea741e59a7261c38f473b53553b/matplotlib-3.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:3fd595f34aa8a55b7fc8bf9ebea8aa665a84c82d275190a61118d33fbc82ccae", size = 7819628 }, + { url = "https://files.pythonhosted.org/packages/77/c2/f9d7fe80a8fcce9bb128d1381c6fe41a8d286d7e18395e273002e8e0fa34/matplotlib-3.9.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8dd059447824eec055e829258ab092b56bb0579fc3164fa09c64f3acd478772", size = 7902925 }, + { url = "https://files.pythonhosted.org/packages/28/ba/8be09886eb56ac04a218a1dc3fa728a5c4cac60b019b4f1687885166da00/matplotlib-3.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c797dac8bb9c7a3fd3382b16fe8f215b4cf0f22adccea36f1545a6d7be310b41", size = 7773193 }, + { url = "https://files.pythonhosted.org/packages/e6/9a/5991972a560db3ab621312a7ca5efec339ae2122f25901c0846865c4b72f/matplotlib-3.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d719465db13267bcef19ea8954a971db03b9f48b4647e3860e4bc8e6ed86610f", size = 8202378 }, + { url = "https://files.pythonhosted.org/packages/01/75/6c7ce560e95714a10fcbb3367d1304975a1a3e620f72af28921b796403f3/matplotlib-3.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8912ef7c2362f7193b5819d17dae8629b34a95c58603d781329712ada83f9447", size = 8314361 }, + { url = "https://files.pythonhosted.org/packages/6e/49/dc7384c6c092958e0b75e754efbd9e52500154939c3d715789cee9fb8a53/matplotlib-3.9.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7741f26a58a240f43bee74965c4882b6c93df3e7eb3de160126d8c8f53a6ae6e", size = 9091428 }, + { url = "https://files.pythonhosted.org/packages/8b/ce/15b0bb2fb29b3d46211d8ca740b96b5232499fc49200b58b8d571292c9a6/matplotlib-3.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:ae82a14dab96fbfad7965403c643cafe6515e386de723e498cf3eeb1e0b70cc7", size = 7829377 }, + { url = "https://files.pythonhosted.org/packages/82/de/54f7f38ce6de79cb77d513bb3eaa4e0b1031e9fd6022214f47943fa53a88/matplotlib-3.9.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ac43031375a65c3196bee99f6001e7fa5bdfb00ddf43379d3c0609bdca042df9", size = 7892511 }, + { url = "https://files.pythonhosted.org/packages/35/3e/5713b84a02b24b2a4bd4d6673bfc03017e6654e1d8793ece783b7ed4d484/matplotlib-3.9.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be0fc24a5e4531ae4d8e858a1a548c1fe33b176bb13eff7f9d0d38ce5112a27d", size = 7769370 }, + { url = "https://files.pythonhosted.org/packages/5b/bd/c404502aa1824456d2862dd6b9b0c1917761a51a32f7f83ff8cf94b6d117/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf81de2926c2db243c9b2cbc3917619a0fc85796c6ba4e58f541df814bbf83c7", size = 8193260 }, + { url = "https://files.pythonhosted.org/packages/27/75/de5b9cd67648051cae40039da0c8cbc497a0d99acb1a1f3d087cd66d27b7/matplotlib-3.9.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ee45bc4245533111ced13f1f2cace1e7f89d1c793390392a80c139d6cf0e6c", size = 8306310 }, + { url = "https://files.pythonhosted.org/packages/de/e3/2976e4e54d7ee76eaf54b7639fdc10a223d05c2bdded7045233e9871e469/matplotlib-3.9.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:306c8dfc73239f0e72ac50e5a9cf19cc4e8e331dd0c54f5e69ca8758550f1e1e", size = 9086717 }, + { url = "https://files.pythonhosted.org/packages/d2/92/c2b9464a0562feb6ae780bdc152364810862e07ef5e6affa2b7686028db2/matplotlib-3.9.2-cp312-cp312-win_amd64.whl", hash = "sha256:5413401594cfaff0052f9d8b1aafc6d305b4bd7c4331dccd18f561ff7e1d3bd3", size = 7832805 }, + { url = "https://files.pythonhosted.org/packages/5c/7f/8932eac316b32f464b8f9069f151294dcd892c8fbde61fe8bcd7ba7f7f7e/matplotlib-3.9.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:18128cc08f0d3cfff10b76baa2f296fc28c4607368a8402de61bb3f2eb33c7d9", size = 7893012 }, + { url = "https://files.pythonhosted.org/packages/90/89/9db9db3dd0ff3e2c49e452236dfe29e60b5586a88f8928ca1d153d0da8b5/matplotlib-3.9.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4876d7d40219e8ae8bb70f9263bcbe5714415acfdf781086601211335e24f8aa", size = 7769810 }, + { url = "https://files.pythonhosted.org/packages/67/26/d2661cdc2e1410b8929c5f12dfd521e4528abfed1b3c3d5a28ac48258b43/matplotlib-3.9.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d9f07a80deab4bb0b82858a9e9ad53d1382fd122be8cde11080f4e7dfedb38b", size = 8193779 }, + { url = "https://files.pythonhosted.org/packages/95/70/4839eaa672bf4eacc98ebc8d23633e02b6daf39e294e7433c4ab11a689be/matplotlib-3.9.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7c0410f181a531ec4e93bbc27692f2c71a15c2da16766f5ba9761e7ae518413", size = 8306260 }, + { url = "https://files.pythonhosted.org/packages/88/62/7b263b2cb2724b45d3a4f9c8c6137696cc3ef037d44383fb01ac2a9555c2/matplotlib-3.9.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:909645cce2dc28b735674ce0931a4ac94e12f5b13f6bb0b5a5e65e7cea2c192b", size = 9086073 }, + { url = "https://files.pythonhosted.org/packages/b0/6d/3572fe243c74112fef120f0bc86f5edd21f49b60e8322fc7f6a01fe945dd/matplotlib-3.9.2-cp313-cp313-win_amd64.whl", hash = "sha256:f32c7410c7f246838a77d6d1eff0c0f87f3cb0e7c4247aebea71a6d5a68cab49", size = 7833041 }, + { url = "https://files.pythonhosted.org/packages/03/8f/9d505be3eb2f40ec731674fb6b47d10cc3147bbd6a9ea7a08c8da55415c6/matplotlib-3.9.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:37e51dd1c2db16ede9cfd7b5cabdfc818b2c6397c83f8b10e0e797501c963a03", size = 7933657 }, + { url = "https://files.pythonhosted.org/packages/5d/68/44b458b9794bcff2a66921f8c9a8110a50a0bb099bd5f7cabb428a1dc765/matplotlib-3.9.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b82c5045cebcecd8496a4d694d43f9cc84aeeb49fe2133e036b207abe73f4d30", size = 7799276 }, + { url = "https://files.pythonhosted.org/packages/47/79/8486d4ddcaaf676314b5fb58e8fe19d1a6210a443a7c31fa72d4215fcb87/matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f053c40f94bc51bc03832a41b4f153d83f2062d88c72b5e79997072594e97e51", size = 8221027 }, + { url = "https://files.pythonhosted.org/packages/56/62/72a472181578c3d035dcda0d0fa2e259ba2c4cb91132588a348bb705b70d/matplotlib-3.9.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dbe196377a8248972f5cede786d4c5508ed5f5ca4a1e09b44bda889958b33f8c", size = 8329097 }, + { url = "https://files.pythonhosted.org/packages/01/8a/760f7fce66b39f447ad160800619d0bd5d0936d2b4633587116534a4afe0/matplotlib-3.9.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5816b1e1fe8c192cbc013f8f3e3368ac56fbecf02fb41b8f8559303f24c5015e", size = 9093770 }, +] + +[[package]] +name = "ml-dtypes" +version = "0.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/79/717c5e22ad25d63ce3acdfe8ff8d64bdedec18914256c59b838218708b16/ml_dtypes-0.5.0.tar.gz", hash = "sha256:3e7d3a380fe73a63c884f06136f8baa7a5249cc8e9fdec677997dd78549f8128", size = 699367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/50/0a2048895a764b138638b5e7a62436545eb206948a5e6f77d9d5a4b02479/ml_dtypes-0.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8c32138975797e681eb175996d64356bcfa124bdbb6a70460b9768c2b35a6fa4", size = 736793 }, + { url = "https://files.pythonhosted.org/packages/0b/b1/95e7995f031bb3890884ddb22e331f24c49b0a4a8f6c448ff5984c86012e/ml_dtypes-0.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab046f2ff789b1f11b2491909682c5d089934835f9a760fafc180e47dcb676b8", size = 4387416 }, + { url = "https://files.pythonhosted.org/packages/9a/5b/d47361f882ff2ae27d764f314d18706c69859da60a6c78e6c9e81714c792/ml_dtypes-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7a9152f5876fef565516aa5dd1dccd6fc298a5891b2467973905103eb5c7856", size = 4496271 }, + { url = "https://files.pythonhosted.org/packages/e6/0c/a89f5c0fe9e48ed6e7e27d53e045711ee3d5b850bece5ee22fb0fb24b281/ml_dtypes-0.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:968fede07d1f9b926a63df97d25ac656cac1a57ebd33701734eaf704bc55d8d8", size = 211915 }, + { url = "https://files.pythonhosted.org/packages/fe/29/8968fd7ee026c0d04c553fb1ce1cd67f9da668cd567d62c0cdc995ce989e/ml_dtypes-0.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60275f2b51b56834e840c4809fca840565f9bf8e9a73f6d8c94f5b5935701215", size = 736792 }, + { url = "https://files.pythonhosted.org/packages/19/93/14896596644dad2e041ac5ca7237e6233c484f7defa186ff88b18ee6110b/ml_dtypes-0.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76942f6aeb5c40766d5ea62386daa4148e6a54322aaf5b53eae9e7553240222f", size = 4392038 }, + { url = "https://files.pythonhosted.org/packages/89/65/ffdbf3489b0ba2213674ea347fad3a11747be64d2d23d888f9e5abe80a18/ml_dtypes-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e7534392682c3098bc7341648c650864207169c654aed83143d7a19c67ae06f", size = 4499448 }, + { url = "https://files.pythonhosted.org/packages/bf/31/058b9bcf9a81abd51623985add78711a915e4b0f6045baa5f9a0b41eb039/ml_dtypes-0.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:dc74fd9995513d33eac63d64e436240f5494ec74d522a9f0920194942fc3d2d7", size = 211916 }, + { url = "https://files.pythonhosted.org/packages/1c/b7/a067839f6e435785f34b09d96938dccb3a5d9502037de243cb84a2eb3f23/ml_dtypes-0.5.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d4b1a70a3e5219790d6b55b9507606fc4e02911d1497d16c18dd721eb7efe7d0", size = 750226 }, + { url = "https://files.pythonhosted.org/packages/31/75/bf571247bb3dbea73aa33ccae57ce322b9688003cfee2f68d303ab7b987b/ml_dtypes-0.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a988bac6572630e1e9c2edd9b1277b4eefd1c86209e52b0d061b775ac33902ff", size = 4420139 }, + { url = "https://files.pythonhosted.org/packages/6f/d3/1321715a95e856d4ef4fba24e4351cf5e4c89d459ad132a8cba5fe257d72/ml_dtypes-0.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a38df8df61194aeaae1ab7579075779b4ad32cd1cffd012c28be227fa7f2a70a", size = 4471130 }, + { url = "https://files.pythonhosted.org/packages/00/3a/40c40b78a7eb456837817bfa2c5bc442db59aefdf21c5ecb94700037813d/ml_dtypes-0.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:afa08343069874a30812871d639f9c02b4158ace065601406a493a8511180c02", size = 213187 }, + { url = "https://files.pythonhosted.org/packages/b3/4a/18f670a2703e771a6775fbc354208e597ff062a88efb0cecc220a282210b/ml_dtypes-0.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d3b3db9990c3840986a0e70524e122cfa32b91139c3653df76121ba7776e015f", size = 753345 }, + { url = "https://files.pythonhosted.org/packages/ed/c6/358d85e274e22d53def0c85f3cbe0933475fa3cf6922e9dca66eb25cb22f/ml_dtypes-0.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e04fde367b2fe901b1d47234426fe8819909bd1dd862a5adb630f27789c20599", size = 4424962 }, + { url = "https://files.pythonhosted.org/packages/4c/b4/d766586e24e7a073333c8eb8bd9275f3c6fe0569b509ae7b1699d4f00c74/ml_dtypes-0.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54415257f00eb44fbcc807454efac3356f75644f1cbfc2d4e5522a72ae1dacab", size = 4475201 }, + { url = "https://files.pythonhosted.org/packages/14/87/30323ad2e52f56262019a4493fe5f5e71067c5561ce7e2f9c75de520f5e8/ml_dtypes-0.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:cb5cc7b25acabd384f75bbd78892d0c724943f3e2e1986254665a1aa10982e07", size = 213195 }, +] + +[[package]] +name = "numpy" +version = "2.1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/25/ca/1166b75c21abd1da445b97bf1fa2f14f423c6cfb4fc7c4ef31dccf9f6a94/numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761", size = 20166090 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/80/d572a4737626372915bca41c3afbfec9d173561a39a0a61bacbbfd1dafd4/numpy-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c894b4305373b9c5576d7a12b473702afdf48ce5369c074ba304cc5ad8730dff", size = 21152472 }, + { url = "https://files.pythonhosted.org/packages/6f/bb/7bfba10c791ae3bb6716da77ad85a82d5fac07fc96fb0023ef0571df9d20/numpy-2.1.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b47fbb433d3260adcd51eb54f92a2ffbc90a4595f8970ee00e064c644ac788f5", size = 13747967 }, + { url = "https://files.pythonhosted.org/packages/da/d6/2df7bde35f0478455f0be5934877b3e5a505f587b00230f54a519a6b55a5/numpy-2.1.3-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:825656d0743699c529c5943554d223c021ff0494ff1442152ce887ef4f7561a1", size = 5354921 }, + { url = "https://files.pythonhosted.org/packages/d1/bb/75b945874f931494891eac6ca06a1764d0e8208791f3addadb2963b83527/numpy-2.1.3-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:6a4825252fcc430a182ac4dee5a505053d262c807f8a924603d411f6718b88fd", size = 6888603 }, + { url = "https://files.pythonhosted.org/packages/68/a7/fde73636f6498dbfa6d82fc336164635fe592f1ad0d13285fcb6267fdc1c/numpy-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e711e02f49e176a01d0349d82cb5f05ba4db7d5e7e0defd026328e5cfb3226d3", size = 13889862 }, + { url = "https://files.pythonhosted.org/packages/05/db/5d9c91b2e1e2e72be1369278f696356d44975befcae830daf2e667dcb54f/numpy-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78574ac2d1a4a02421f25da9559850d59457bac82f2b8d7a44fe83a64f770098", size = 16328151 }, + { url = "https://files.pythonhosted.org/packages/3e/6a/7eb732109b53ae64a29e25d7e68eb9d6611037f6354875497008a49e74d3/numpy-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c7662f0e3673fe4e832fe07b65c50342ea27d989f92c80355658c7f888fcc83c", size = 16704107 }, + { url = "https://files.pythonhosted.org/packages/88/cc/278113b66a1141053cbda6f80e4200c6da06b3079c2d27bda1fde41f2c1f/numpy-2.1.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fa2d1337dc61c8dc417fbccf20f6d1e139896a30721b7f1e832b2bb6ef4eb6c4", size = 14385789 }, + { url = "https://files.pythonhosted.org/packages/f5/69/eb20f5e1bfa07449bc67574d2f0f7c1e6b335fb41672e43861a7727d85f2/numpy-2.1.3-cp310-cp310-win32.whl", hash = "sha256:72dcc4a35a8515d83e76b58fdf8113a5c969ccd505c8a946759b24e3182d1f23", size = 6536706 }, + { url = "https://files.pythonhosted.org/packages/8e/8b/1c131ab5a94c1086c289c6e1da1d843de9dbd95fe5f5ee6e61904c9518e2/numpy-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:ecc76a9ba2911d8d37ac01de72834d8849e55473457558e12995f4cd53e778e0", size = 12864165 }, + { url = "https://files.pythonhosted.org/packages/ad/81/c8167192eba5247593cd9d305ac236847c2912ff39e11402e72ae28a4985/numpy-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4d1167c53b93f1f5d8a139a742b3c6f4d429b54e74e6b57d0eff40045187b15d", size = 21156252 }, + { url = "https://files.pythonhosted.org/packages/da/74/5a60003fc3d8a718d830b08b654d0eea2d2db0806bab8f3c2aca7e18e010/numpy-2.1.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c80e4a09b3d95b4e1cac08643f1152fa71a0a821a2d4277334c88d54b2219a41", size = 13784119 }, + { url = "https://files.pythonhosted.org/packages/47/7c/864cb966b96fce5e63fcf25e1e4d957fe5725a635e5f11fe03f39dd9d6b5/numpy-2.1.3-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:576a1c1d25e9e02ed7fa5477f30a127fe56debd53b8d2c89d5578f9857d03ca9", size = 5352978 }, + { url = "https://files.pythonhosted.org/packages/09/ac/61d07930a4993dd9691a6432de16d93bbe6aa4b1c12a5e573d468eefc1ca/numpy-2.1.3-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:973faafebaae4c0aaa1a1ca1ce02434554d67e628b8d805e61f874b84e136b09", size = 6892570 }, + { url = "https://files.pythonhosted.org/packages/27/2f/21b94664f23af2bb52030653697c685022119e0dc93d6097c3cb45bce5f9/numpy-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:762479be47a4863e261a840e8e01608d124ee1361e48b96916f38b119cfda04a", size = 13896715 }, + { url = "https://files.pythonhosted.org/packages/7a/f0/80811e836484262b236c684a75dfc4ba0424bc670e765afaa911468d9f39/numpy-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc6f24b3d1ecc1eebfbf5d6051faa49af40b03be1aaa781ebdadcbc090b4539b", size = 16339644 }, + { url = "https://files.pythonhosted.org/packages/fa/81/ce213159a1ed8eb7d88a2a6ef4fbdb9e4ffd0c76b866c350eb4e3c37e640/numpy-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:17ee83a1f4fef3c94d16dc1802b998668b5419362c8a4f4e8a491de1b41cc3ee", size = 16712217 }, + { url = "https://files.pythonhosted.org/packages/7d/84/4de0b87d5a72f45556b2a8ee9fc8801e8518ec867fc68260c1f5dcb3903f/numpy-2.1.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:15cb89f39fa6d0bdfb600ea24b250e5f1a3df23f901f51c8debaa6a5d122b2f0", size = 14399053 }, + { url = "https://files.pythonhosted.org/packages/7e/1c/e5fabb9ad849f9d798b44458fd12a318d27592d4bc1448e269dec070ff04/numpy-2.1.3-cp311-cp311-win32.whl", hash = "sha256:d9beb777a78c331580705326d2367488d5bc473b49a9bc3036c154832520aca9", size = 6534741 }, + { url = "https://files.pythonhosted.org/packages/1e/48/a9a4b538e28f854bfb62e1dea3c8fea12e90216a276c7777ae5345ff29a7/numpy-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:d89dd2b6da69c4fff5e39c28a382199ddedc3a5be5390115608345dec660b9e2", size = 12869487 }, + { url = "https://files.pythonhosted.org/packages/8a/f0/385eb9970309643cbca4fc6eebc8bb16e560de129c91258dfaa18498da8b/numpy-2.1.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f55ba01150f52b1027829b50d70ef1dafd9821ea82905b63936668403c3b471e", size = 20849658 }, + { url = "https://files.pythonhosted.org/packages/54/4a/765b4607f0fecbb239638d610d04ec0a0ded9b4951c56dc68cef79026abf/numpy-2.1.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:13138eadd4f4da03074851a698ffa7e405f41a0845a6b1ad135b81596e4e9958", size = 13492258 }, + { url = "https://files.pythonhosted.org/packages/bd/a7/2332679479c70b68dccbf4a8eb9c9b5ee383164b161bee9284ac141fbd33/numpy-2.1.3-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a6b46587b14b888e95e4a24d7b13ae91fa22386c199ee7b418f449032b2fa3b8", size = 5090249 }, + { url = "https://files.pythonhosted.org/packages/c1/67/4aa00316b3b981a822c7a239d3a8135be2a6945d1fd11d0efb25d361711a/numpy-2.1.3-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:0fa14563cc46422e99daef53d725d0c326e99e468a9320a240affffe87852564", size = 6621704 }, + { url = "https://files.pythonhosted.org/packages/5e/da/1a429ae58b3b6c364eeec93bf044c532f2ff7b48a52e41050896cf15d5b1/numpy-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8637dcd2caa676e475503d1f8fdb327bc495554e10838019651b76d17b98e512", size = 13606089 }, + { url = "https://files.pythonhosted.org/packages/9e/3e/3757f304c704f2f0294a6b8340fcf2be244038be07da4cccf390fa678a9f/numpy-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2312b2aa89e1f43ecea6da6ea9a810d06aae08321609d8dc0d0eda6d946a541b", size = 16043185 }, + { url = "https://files.pythonhosted.org/packages/43/97/75329c28fea3113d00c8d2daf9bc5828d58d78ed661d8e05e234f86f0f6d/numpy-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a38c19106902bb19351b83802531fea19dee18e5b37b36454f27f11ff956f7fc", size = 16410751 }, + { url = "https://files.pythonhosted.org/packages/ad/7a/442965e98b34e0ae9da319f075b387bcb9a1e0658276cc63adb8c9686f7b/numpy-2.1.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02135ade8b8a84011cbb67dc44e07c58f28575cf9ecf8ab304e51c05528c19f0", size = 14082705 }, + { url = "https://files.pythonhosted.org/packages/ac/b6/26108cf2cfa5c7e03fb969b595c93131eab4a399762b51ce9ebec2332e80/numpy-2.1.3-cp312-cp312-win32.whl", hash = "sha256:e6988e90fcf617da2b5c78902fe8e668361b43b4fe26dbf2d7b0f8034d4cafb9", size = 6239077 }, + { url = "https://files.pythonhosted.org/packages/a6/84/fa11dad3404b7634aaab50733581ce11e5350383311ea7a7010f464c0170/numpy-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:0d30c543f02e84e92c4b1f415b7c6b5326cbe45ee7882b6b77db7195fb971e3a", size = 12566858 }, + { url = "https://files.pythonhosted.org/packages/4d/0b/620591441457e25f3404c8057eb924d04f161244cb8a3680d529419aa86e/numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f", size = 20836263 }, + { url = "https://files.pythonhosted.org/packages/45/e1/210b2d8b31ce9119145433e6ea78046e30771de3fe353f313b2778142f34/numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598", size = 13507771 }, + { url = "https://files.pythonhosted.org/packages/55/44/aa9ee3caee02fa5a45f2c3b95cafe59c44e4b278fbbf895a93e88b308555/numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57", size = 5075805 }, + { url = "https://files.pythonhosted.org/packages/78/d6/61de6e7e31915ba4d87bbe1ae859e83e6582ea14c6add07c8f7eefd8488f/numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe", size = 6608380 }, + { url = "https://files.pythonhosted.org/packages/3e/46/48bdf9b7241e317e6cf94276fe11ba673c06d1fdf115d8b4ebf616affd1a/numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43", size = 13602451 }, + { url = "https://files.pythonhosted.org/packages/70/50/73f9a5aa0810cdccda9c1d20be3cbe4a4d6ea6bfd6931464a44c95eef731/numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56", size = 16039822 }, + { url = "https://files.pythonhosted.org/packages/ad/cd/098bc1d5a5bc5307cfc65ee9369d0ca658ed88fbd7307b0d49fab6ca5fa5/numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a", size = 16411822 }, + { url = "https://files.pythonhosted.org/packages/83/a2/7d4467a2a6d984549053b37945620209e702cf96a8bc658bc04bba13c9e2/numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef", size = 14079598 }, + { url = "https://files.pythonhosted.org/packages/e9/6a/d64514dcecb2ee70bfdfad10c42b76cab657e7ee31944ff7a600f141d9e9/numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f", size = 6236021 }, + { url = "https://files.pythonhosted.org/packages/bb/f9/12297ed8d8301a401e7d8eb6b418d32547f1d700ed3c038d325a605421a4/numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed", size = 12560405 }, + { url = "https://files.pythonhosted.org/packages/a7/45/7f9244cd792e163b334e3a7f02dff1239d2890b6f37ebf9e82cbe17debc0/numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f", size = 20859062 }, + { url = "https://files.pythonhosted.org/packages/b1/b4/a084218e7e92b506d634105b13e27a3a6645312b93e1c699cc9025adb0e1/numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4", size = 13515839 }, + { url = "https://files.pythonhosted.org/packages/27/45/58ed3f88028dcf80e6ea580311dc3edefdd94248f5770deb980500ef85dd/numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e", size = 5116031 }, + { url = "https://files.pythonhosted.org/packages/37/a8/eb689432eb977d83229094b58b0f53249d2209742f7de529c49d61a124a0/numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0", size = 6629977 }, + { url = "https://files.pythonhosted.org/packages/42/a3/5355ad51ac73c23334c7caaed01adadfda49544f646fcbfbb4331deb267b/numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408", size = 13575951 }, + { url = "https://files.pythonhosted.org/packages/c4/70/ea9646d203104e647988cb7d7279f135257a6b7e3354ea6c56f8bafdb095/numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6", size = 16022655 }, + { url = "https://files.pythonhosted.org/packages/14/ce/7fc0612903e91ff9d0b3f2eda4e18ef9904814afcae5b0f08edb7f637883/numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f", size = 16399902 }, + { url = "https://files.pythonhosted.org/packages/ef/62/1d3204313357591c913c32132a28f09a26357e33ea3c4e2fe81269e0dca1/numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17", size = 14067180 }, + { url = "https://files.pythonhosted.org/packages/24/d7/78a40ed1d80e23a774cb8a34ae8a9493ba1b4271dde96e56ccdbab1620ef/numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48", size = 6291907 }, + { url = "https://files.pythonhosted.org/packages/86/09/a5ab407bd7f5f5599e6a9261f964ace03a73e7c6928de906981c31c38082/numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4", size = 12644098 }, + { url = "https://files.pythonhosted.org/packages/00/e7/8d8bb791b62586cc432ecbb70632b4f23b7b7c88df41878de7528264f6d7/numpy-2.1.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:4f2015dfe437dfebbfce7c85c7b53d81ba49e71ba7eadbf1df40c915af75979f", size = 20983893 }, + { url = "https://files.pythonhosted.org/packages/5e/f3/cb8118a044b5007586245a650360c9f5915b2f4232dd7658bb7a63dd1d02/numpy-2.1.3-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:3522b0dfe983a575e6a9ab3a4a4dfe156c3e428468ff08ce582b9bb6bd1d71d4", size = 6752501 }, + { url = "https://files.pythonhosted.org/packages/53/f5/365b46439b518d2ec6ebb880cc0edf90f225145dfd4db7958334f7164530/numpy-2.1.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c006b607a865b07cd981ccb218a04fc86b600411d83d6fc261357f1c0966755d", size = 16142601 }, + { url = "https://files.pythonhosted.org/packages/03/c2/d1fee6ba999aa7cd41ca6856937f2baaf604c3eec1565eae63451ec31e5e/numpy-2.1.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e14e26956e6f1696070788252dcdff11b4aca4c3e8bd166e0df1bb8f315a67cb", size = 12771397 }, +] + +[[package]] +name = "nvidia-cublas-cu12" +version = "12.6.3.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/02/9fe3ca905d4838d716669de65006e0fb34fef7b849868f403416526f0e05/nvidia_cublas_cu12-12.6.3.3-py3-none-manylinux2014_aarch64.whl", hash = "sha256:e531199ca4f1f764fb45bc1dde49a006f6765033f9c89c737e4553b9502ca1f5", size = 390792508 }, + { url = "https://files.pythonhosted.org/packages/f3/e7/c186a31c234fce776436753bfef4807df7f9b4cb3eeff358fcfcbf64b547/nvidia_cublas_cu12-12.6.3.3-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f33fb68e101d99470c82d17f92a0dd9f74de2a21685c217f4716cdd63b1316eb", size = 393135292 }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.6.80" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/0f/acb326ac8fd26e13c799e0b4f3b2751543e1834f04d62e729485872198d4/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_aarch64.whl", hash = "sha256:358b4a1d35370353d52e12f0a7d1769fc01ff74a191689d3870b2123156184c4", size = 8236756 }, + { url = "https://files.pythonhosted.org/packages/a5/24/120ee57b218d9952c379d1e026c4479c9ece9997a4fb46303611ee48f038/nvidia_cuda_cupti_cu12-12.6.80-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a3eff6cdfcc6a4c35db968a06fcadb061cbc7d6dde548609a941ff8701b98b73", size = 8917972 }, +] + +[[package]] +name = "nvidia-cuda-nvcc-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/4a/d153d4ec0bfb42889584de351dd168ebb06d293fd43b96f0d0c763b8b029/nvidia_cuda_nvcc_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:9a2aad43b8f4e4be9c237ece04f64450df77871eeebffad5a5a872714a97ca77", size = 19261369 }, + { url = "https://files.pythonhosted.org/packages/62/8f/cd3032281ba7bb531fe3159337af00c5c805fd6a31dc700f0715c8748c8c/nvidia_cuda_nvcc_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b66bb5dd6b8ae62262586691977d3b4a425e91db61b4b9bc2f6b42bcd4154b96", size = 21169073 }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/3d/159023799677126e20c8fd580cca09eeb28d5c5a624adc7f793b9aa8bbfa/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:d461264ecb429c84c8879a7153499ddc7b19b5f8d84c204307491989a365588e", size = 908040 }, + { url = "https://files.pythonhosted.org/packages/f0/62/65c05e161eeddbafeca24dc461f47de550d9fa8a7e04eb213e32b55cfd99/nvidia_cuda_runtime_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:a84d15d5e1da416dd4774cb42edf5e954a3e60cc945698dc1d5be02321c44dc8", size = 897678 }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.5.1.17" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/93/a201a12d3ec1caa8c6ac34c1c2f9eeb696b886f0c36ff23c638b46603bd0/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:9fd4584468533c61873e5fda8ca41bac3a38bcb2d12350830c69b0a96a7e4def", size = 570523509 }, + { url = "https://files.pythonhosted.org/packages/2a/78/4535c9c7f859a64781e43c969a3a7e84c54634e319a996d43ef32ce46f83/nvidia_cudnn_cu12-9.5.1.17-py3-none-manylinux_2_28_x86_64.whl", hash = "sha256:30ac3869f6db17d170e0e556dd6cc5eee02647abc31ca856634d5a40f82c15b2", size = 570988386 }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/f5/188566814b7339e893f8d210d3a5332352b1409815908dad6a363dcceac1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8510990de9f96c803a051822618d42bf6cb8f069ff3f48d93a8486efdacb48fb", size = 200164135 }, + { url = "https://files.pythonhosted.org/packages/60/de/99ec247a07ea40c969d904fc14f3a356b3e2a704121675b75c366b694ee1/nvidia_cufft_cu12-11.3.0.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:768160ac89f6f7b459bee747e8d175dbf53619cfe74b2a5636264163138013ca", size = 200221622 }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/17/dbe1aa865e4fdc7b6d4d0dd308fdd5aaab60f939abfc0ea1954eac4fb113/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0ce237ef60acde1efc457335a2ddadfd7610b892d94efee7b776c64bb1cac9e0", size = 157833628 }, + { url = "https://files.pythonhosted.org/packages/9f/81/baba53585da791d043c10084cf9553e074548408e04ae884cfe9193bd484/nvidia_cusolver_cu12-11.7.1.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6cf28f17f64107a0c4d7802be5ff5537b2130bfc112f25d5a30df227058ca0e6", size = 158229780 }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "sys_platform == 'linux'" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/56/3af21e43014eb40134dea004e8d0f1ef19d9596a39e4d497d5a7de01669f/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7aa32fa5470cf754f72d1116c7cbc300b4e638d3ae5304cfa4a638a5b87161b1", size = 216451135 }, + { url = "https://files.pythonhosted.org/packages/43/ac/64c4316ba163e8217a99680c7605f779accffc6a4bcd0c778c12948d3707/nvidia_cusparse_cu12-12.5.4.2-py3-none-manylinux2014_x86_64.whl", hash = "sha256:23749a6571191a215cb74d1cdbff4a86e7b19f1200c071b3fcf844a5bea23a2f", size = 216561357 }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.23.4" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/3a/0112397396dec37ffc8edd7836d48261b4d14ca60ec8ed7bc857cce1d916/nvidia_nccl_cu12-2.23.4-py3-none-manylinux2014_aarch64.whl", hash = "sha256:aa946c8327e22ced28e7cef508a334673abc42064ec85f02d005ba1785ea4cec", size = 198953892 }, + { url = "https://files.pythonhosted.org/packages/ed/1f/6482380ec8dcec4894e7503490fc536d846b0d59694acad9cf99f27d0e7d/nvidia_nccl_cu12-2.23.4-py3-none-manylinux2014_x86_64.whl", hash = "sha256:b097258d9aab2fa9f686e33c6fe40ae57b27df60cedbd15d139701bb5509e0c1", size = 198954603 }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.6.77" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/8c/386018fdffdce2ff8d43fedf192ef7d14cab7501cbf78a106dd2e9f1fc1f/nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_aarch64.whl", hash = "sha256:3bf10d85bb1801e9c894c6e197e44dd137d2a0a9e43f8450e9ad13f2df0dd52d", size = 19270432 }, + { url = "https://files.pythonhosted.org/packages/fe/e4/486de766851d58699bcfeb3ba6a3beb4d89c3809f75b9d423b9508a8760f/nvidia_nvjitlink_cu12-12.6.77-py3-none-manylinux2014_x86_64.whl", hash = "sha256:9ae346d16203ae4ea513be416495167a0101d33d2d14935aa9c1829a3fb45142", size = 19745114 }, +] + +[[package]] +name = "opt-einsum" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/b9/2ac072041e899a52f20cf9510850ff58295003aa75525e58343591b0cbfb/opt_einsum-3.4.0.tar.gz", hash = "sha256:96ca72f1b886d148241348783498194c577fa30a8faac108586b14f1ba4473ac", size = 63004 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/cd/066e86230ae37ed0be70aae89aabf03ca8d9f39c8aea0dec8029455b5540/opt_einsum-3.4.0-py3-none-any.whl", hash = "sha256:69bb92469f86a1565195ece4ac0323943e83477171b91d24c35afe028a90d7cd", size = 71932 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pillow" +version = "11.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a5/26/0d95c04c868f6bdb0c447e3ee2de5564411845e36a858cfd63766bc7b563/pillow-11.0.0.tar.gz", hash = "sha256:72bacbaf24ac003fea9bff9837d1eedb6088758d41e100c1552930151f677739", size = 46737780 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/fb/a6ce6836bd7fd93fbf9144bf54789e02babc27403b50a9e1583ee877d6da/pillow-11.0.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:6619654954dc4936fcff82db8eb6401d3159ec6be81e33c6000dfd76ae189947", size = 3154708 }, + { url = "https://files.pythonhosted.org/packages/6a/1d/1f51e6e912d8ff316bb3935a8cda617c801783e0b998bf7a894e91d3bd4c/pillow-11.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3c5ac4bed7519088103d9450a1107f76308ecf91d6dabc8a33a2fcfb18d0fba", size = 2979223 }, + { url = "https://files.pythonhosted.org/packages/90/83/e2077b0192ca8a9ef794dbb74700c7e48384706467067976c2a95a0f40a1/pillow-11.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a65149d8ada1055029fcb665452b2814fe7d7082fcb0c5bed6db851cb69b2086", size = 4183167 }, + { url = "https://files.pythonhosted.org/packages/0e/74/467af0146970a98349cdf39e9b79a6cc8a2e7558f2c01c28a7b6b85c5bda/pillow-11.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a58d8ac0cc0e7f3a014509f0455248a76629ca9b604eca7dc5927cc593c5e9", size = 4283912 }, + { url = "https://files.pythonhosted.org/packages/85/b1/d95d4f7ca3a6c1ae120959605875a31a3c209c4e50f0029dc1a87566cf46/pillow-11.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:c26845094b1af3c91852745ae78e3ea47abf3dbcd1cf962f16b9a5fbe3ee8488", size = 4195815 }, + { url = "https://files.pythonhosted.org/packages/41/c3/94f33af0762ed76b5a237c5797e088aa57f2b7fa8ee7932d399087be66a8/pillow-11.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:1a61b54f87ab5786b8479f81c4b11f4d61702830354520837f8cc791ebba0f5f", size = 4366117 }, + { url = "https://files.pythonhosted.org/packages/ba/3c/443e7ef01f597497268899e1cca95c0de947c9bbf77a8f18b3c126681e5d/pillow-11.0.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:674629ff60030d144b7bca2b8330225a9b11c482ed408813924619c6f302fdbb", size = 4278607 }, + { url = "https://files.pythonhosted.org/packages/26/95/1495304448b0081e60c0c5d63f928ef48bb290acee7385804426fa395a21/pillow-11.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:598b4e238f13276e0008299bd2482003f48158e2b11826862b1eb2ad7c768b97", size = 4410685 }, + { url = "https://files.pythonhosted.org/packages/45/da/861e1df971ef0de9870720cb309ca4d553b26a9483ec9be3a7bf1de4a095/pillow-11.0.0-cp310-cp310-win32.whl", hash = "sha256:9a0f748eaa434a41fccf8e1ee7a3eed68af1b690e75328fd7a60af123c193b50", size = 2249185 }, + { url = "https://files.pythonhosted.org/packages/d5/4e/78f7c5202ea2a772a5ab05069c1b82503e6353cd79c7e474d4945f4b82c3/pillow-11.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:a5629742881bcbc1f42e840af185fd4d83a5edeb96475a575f4da50d6ede337c", size = 2566726 }, + { url = "https://files.pythonhosted.org/packages/77/e4/6e84eada35cbcc646fc1870f72ccfd4afacb0fae0c37ffbffe7f5dc24bf1/pillow-11.0.0-cp310-cp310-win_arm64.whl", hash = "sha256:ee217c198f2e41f184f3869f3e485557296d505b5195c513b2bfe0062dc537f1", size = 2254585 }, + { url = "https://files.pythonhosted.org/packages/f0/eb/f7e21b113dd48a9c97d364e0915b3988c6a0b6207652f5a92372871b7aa4/pillow-11.0.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:1c1d72714f429a521d8d2d018badc42414c3077eb187a59579f28e4270b4b0fc", size = 3154705 }, + { url = "https://files.pythonhosted.org/packages/25/b3/2b54a1d541accebe6bd8b1358b34ceb2c509f51cb7dcda8687362490da5b/pillow-11.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:499c3a1b0d6fc8213519e193796eb1a86a1be4b1877d678b30f83fd979811d1a", size = 2979222 }, + { url = "https://files.pythonhosted.org/packages/20/12/1a41eddad8265c5c19dda8fb6c269ce15ee25e0b9f8f26286e6202df6693/pillow-11.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8b2351c85d855293a299038e1f89db92a2f35e8d2f783489c6f0b2b5f3fe8a3", size = 4190220 }, + { url = "https://files.pythonhosted.org/packages/a9/9b/8a8c4d07d77447b7457164b861d18f5a31ae6418ef5c07f6f878fa09039a/pillow-11.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f4dba50cfa56f910241eb7f883c20f1e7b1d8f7d91c750cd0b318bad443f4d5", size = 4291399 }, + { url = "https://files.pythonhosted.org/packages/fc/e4/130c5fab4a54d3991129800dd2801feeb4b118d7630148cd67f0e6269d4c/pillow-11.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:5ddbfd761ee00c12ee1be86c9c0683ecf5bb14c9772ddbd782085779a63dd55b", size = 4202709 }, + { url = "https://files.pythonhosted.org/packages/39/63/b3fc299528d7df1f678b0666002b37affe6b8751225c3d9c12cf530e73ed/pillow-11.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:45c566eb10b8967d71bf1ab8e4a525e5a93519e29ea071459ce517f6b903d7fa", size = 4372556 }, + { url = "https://files.pythonhosted.org/packages/c6/a6/694122c55b855b586c26c694937d36bb8d3b09c735ff41b2f315c6e66a10/pillow-11.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b4fd7bd29610a83a8c9b564d457cf5bd92b4e11e79a4ee4716a63c959699b306", size = 4287187 }, + { url = "https://files.pythonhosted.org/packages/ba/a9/f9d763e2671a8acd53d29b1e284ca298bc10a595527f6be30233cdb9659d/pillow-11.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:cb929ca942d0ec4fac404cbf520ee6cac37bf35be479b970c4ffadf2b6a1cad9", size = 4418468 }, + { url = "https://files.pythonhosted.org/packages/6e/0e/b5cbad2621377f11313a94aeb44ca55a9639adabcaaa073597a1925f8c26/pillow-11.0.0-cp311-cp311-win32.whl", hash = "sha256:006bcdd307cc47ba43e924099a038cbf9591062e6c50e570819743f5607404f5", size = 2249249 }, + { url = "https://files.pythonhosted.org/packages/dc/83/1470c220a4ff06cd75fc609068f6605e567ea51df70557555c2ab6516b2c/pillow-11.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:52a2d8323a465f84faaba5236567d212c3668f2ab53e1c74c15583cf507a0291", size = 2566769 }, + { url = "https://files.pythonhosted.org/packages/52/98/def78c3a23acee2bcdb2e52005fb2810ed54305602ec1bfcfab2bda6f49f/pillow-11.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:16095692a253047fe3ec028e951fa4221a1f3ed3d80c397e83541a3037ff67c9", size = 2254611 }, + { url = "https://files.pythonhosted.org/packages/1c/a3/26e606ff0b2daaf120543e537311fa3ae2eb6bf061490e4fea51771540be/pillow-11.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2c0a187a92a1cb5ef2c8ed5412dd8d4334272617f532d4ad4de31e0495bd923", size = 3147642 }, + { url = "https://files.pythonhosted.org/packages/4f/d5/1caabedd8863526a6cfa44ee7a833bd97f945dc1d56824d6d76e11731939/pillow-11.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:084a07ef0821cfe4858fe86652fffac8e187b6ae677e9906e192aafcc1b69903", size = 2978999 }, + { url = "https://files.pythonhosted.org/packages/d9/ff/5a45000826a1aa1ac6874b3ec5a856474821a1b59d838c4f6ce2ee518fe9/pillow-11.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8069c5179902dcdce0be9bfc8235347fdbac249d23bd90514b7a47a72d9fecf4", size = 4196794 }, + { url = "https://files.pythonhosted.org/packages/9d/21/84c9f287d17180f26263b5f5c8fb201de0f88b1afddf8a2597a5c9fe787f/pillow-11.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f02541ef64077f22bf4924f225c0fd1248c168f86e4b7abdedd87d6ebaceab0f", size = 4300762 }, + { url = "https://files.pythonhosted.org/packages/84/39/63fb87cd07cc541438b448b1fed467c4d687ad18aa786a7f8e67b255d1aa/pillow-11.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fcb4621042ac4b7865c179bb972ed0da0218a076dc1820ffc48b1d74c1e37fe9", size = 4210468 }, + { url = "https://files.pythonhosted.org/packages/7f/42/6e0f2c2d5c60f499aa29be14f860dd4539de322cd8fb84ee01553493fb4d/pillow-11.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:00177a63030d612148e659b55ba99527803288cea7c75fb05766ab7981a8c1b7", size = 4381824 }, + { url = "https://files.pythonhosted.org/packages/31/69/1ef0fb9d2f8d2d114db982b78ca4eeb9db9a29f7477821e160b8c1253f67/pillow-11.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8853a3bf12afddfdf15f57c4b02d7ded92c7a75a5d7331d19f4f9572a89c17e6", size = 4296436 }, + { url = "https://files.pythonhosted.org/packages/44/ea/dad2818c675c44f6012289a7c4f46068c548768bc6c7f4e8c4ae5bbbc811/pillow-11.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3107c66e43bda25359d5ef446f59c497de2b5ed4c7fdba0894f8d6cf3822dafc", size = 4429714 }, + { url = "https://files.pythonhosted.org/packages/af/3a/da80224a6eb15bba7a0dcb2346e2b686bb9bf98378c0b4353cd88e62b171/pillow-11.0.0-cp312-cp312-win32.whl", hash = "sha256:86510e3f5eca0ab87429dd77fafc04693195eec7fd6a137c389c3eeb4cfb77c6", size = 2249631 }, + { url = "https://files.pythonhosted.org/packages/57/97/73f756c338c1d86bb802ee88c3cab015ad7ce4b838f8a24f16b676b1ac7c/pillow-11.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:8ec4a89295cd6cd4d1058a5e6aec6bf51e0eaaf9714774e1bfac7cfc9051db47", size = 2567533 }, + { url = "https://files.pythonhosted.org/packages/0b/30/2b61876e2722374558b871dfbfcbe4e406626d63f4f6ed92e9c8e24cac37/pillow-11.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:27a7860107500d813fcd203b4ea19b04babe79448268403172782754870dac25", size = 2254890 }, + { url = "https://files.pythonhosted.org/packages/63/24/e2e15e392d00fcf4215907465d8ec2a2f23bcec1481a8ebe4ae760459995/pillow-11.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bcd1fb5bb7b07f64c15618c89efcc2cfa3e95f0e3bcdbaf4642509de1942a699", size = 3147300 }, + { url = "https://files.pythonhosted.org/packages/43/72/92ad4afaa2afc233dc44184adff289c2e77e8cd916b3ddb72ac69495bda3/pillow-11.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0e038b0745997c7dcaae350d35859c9715c71e92ffb7e0f4a8e8a16732150f38", size = 2978742 }, + { url = "https://files.pythonhosted.org/packages/9e/da/c8d69c5bc85d72a8523fe862f05ababdc52c0a755cfe3d362656bb86552b/pillow-11.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ae08bd8ffc41aebf578c2af2f9d8749d91f448b3bfd41d7d9ff573d74f2a6b2", size = 4194349 }, + { url = "https://files.pythonhosted.org/packages/cd/e8/686d0caeed6b998351d57796496a70185376ed9c8ec7d99e1d19ad591fc6/pillow-11.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d69bfd8ec3219ae71bcde1f942b728903cad25fafe3100ba2258b973bd2bc1b2", size = 4298714 }, + { url = "https://files.pythonhosted.org/packages/ec/da/430015cec620d622f06854be67fd2f6721f52fc17fca8ac34b32e2d60739/pillow-11.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:61b887f9ddba63ddf62fd02a3ba7add935d053b6dd7d58998c630e6dbade8527", size = 4208514 }, + { url = "https://files.pythonhosted.org/packages/44/ae/7e4f6662a9b1cb5f92b9cc9cab8321c381ffbee309210940e57432a4063a/pillow-11.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:c6a660307ca9d4867caa8d9ca2c2658ab685de83792d1876274991adec7b93fa", size = 4380055 }, + { url = "https://files.pythonhosted.org/packages/74/d5/1a807779ac8a0eeed57f2b92a3c32ea1b696e6140c15bd42eaf908a261cd/pillow-11.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:73e3a0200cdda995c7e43dd47436c1548f87a30bb27fb871f352a22ab8dcf45f", size = 4296751 }, + { url = "https://files.pythonhosted.org/packages/38/8c/5fa3385163ee7080bc13026d59656267daaaaf3c728c233d530e2c2757c8/pillow-11.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fba162b8872d30fea8c52b258a542c5dfd7b235fb5cb352240c8d63b414013eb", size = 4430378 }, + { url = "https://files.pythonhosted.org/packages/ca/1d/ad9c14811133977ff87035bf426875b93097fb50af747793f013979facdb/pillow-11.0.0-cp313-cp313-win32.whl", hash = "sha256:f1b82c27e89fffc6da125d5eb0ca6e68017faf5efc078128cfaa42cf5cb38798", size = 2249588 }, + { url = "https://files.pythonhosted.org/packages/fb/01/3755ba287dac715e6afdb333cb1f6d69740a7475220b4637b5ce3d78cec2/pillow-11.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ba470552b48e5835f1d23ecb936bb7f71d206f9dfeee64245f30c3270b994de", size = 2567509 }, + { url = "https://files.pythonhosted.org/packages/c0/98/2c7d727079b6be1aba82d195767d35fcc2d32204c7a5820f822df5330152/pillow-11.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:846e193e103b41e984ac921b335df59195356ce3f71dcfd155aa79c603873b84", size = 2254791 }, + { url = "https://files.pythonhosted.org/packages/eb/38/998b04cc6f474e78b563716b20eecf42a2fa16a84589d23c8898e64b0ffd/pillow-11.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4ad70c4214f67d7466bea6a08061eba35c01b1b89eaa098040a35272a8efb22b", size = 3150854 }, + { url = "https://files.pythonhosted.org/packages/13/8e/be23a96292113c6cb26b2aa3c8b3681ec62b44ed5c2bd0b258bd59503d3c/pillow-11.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6ec0d5af64f2e3d64a165f490d96368bb5dea8b8f9ad04487f9ab60dc4bb6003", size = 2982369 }, + { url = "https://files.pythonhosted.org/packages/97/8a/3db4eaabb7a2ae8203cd3a332a005e4aba00067fc514aaaf3e9721be31f1/pillow-11.0.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c809a70e43c7977c4a42aefd62f0131823ebf7dd73556fa5d5950f5b354087e2", size = 4333703 }, + { url = "https://files.pythonhosted.org/packages/28/ac/629ffc84ff67b9228fe87a97272ab125bbd4dc462745f35f192d37b822f1/pillow-11.0.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:4b60c9520f7207aaf2e1d94de026682fc227806c6e1f55bba7606d1c94dd623a", size = 4412550 }, + { url = "https://files.pythonhosted.org/packages/d6/07/a505921d36bb2df6868806eaf56ef58699c16c388e378b0dcdb6e5b2fb36/pillow-11.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:1e2688958a840c822279fda0086fec1fdab2f95bf2b717b66871c4ad9859d7e8", size = 4461038 }, + { url = "https://files.pythonhosted.org/packages/d6/b9/fb620dd47fc7cc9678af8f8bd8c772034ca4977237049287e99dda360b66/pillow-11.0.0-cp313-cp313t-win32.whl", hash = "sha256:607bbe123c74e272e381a8d1957083a9463401f7bd01287f50521ecb05a313f8", size = 2253197 }, + { url = "https://files.pythonhosted.org/packages/df/86/25dde85c06c89d7fc5db17940f07aae0a56ac69aa9ccb5eb0f09798862a8/pillow-11.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5c39ed17edea3bc69c743a8dd3e9853b7509625c2462532e62baa0732163a904", size = 2572169 }, + { url = "https://files.pythonhosted.org/packages/51/85/9c33f2517add612e17f3381aee7c4072779130c634921a756c97bc29fb49/pillow-11.0.0-cp313-cp313t-win_arm64.whl", hash = "sha256:75acbbeb05b86bc53cbe7b7e6fe00fbcf82ad7c684b3ad82e3d711da9ba287d3", size = 2256828 }, + { url = "https://files.pythonhosted.org/packages/36/57/42a4dd825eab762ba9e690d696d894ba366e06791936056e26e099398cda/pillow-11.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1187739620f2b365de756ce086fdb3604573337cc28a0d3ac4a01ab6b2d2a6d2", size = 3119239 }, + { url = "https://files.pythonhosted.org/packages/98/f7/25f9f9e368226a1d6cf3507081a1a7944eddd3ca7821023377043f5a83c8/pillow-11.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:fbbcb7b57dc9c794843e3d1258c0fbf0f48656d46ffe9e09b63bbd6e8cd5d0a2", size = 2950803 }, + { url = "https://files.pythonhosted.org/packages/59/01/98ead48a6c2e31e6185d4c16c978a67fe3ccb5da5c2ff2ba8475379bb693/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d203af30149ae339ad1b4f710d9844ed8796e97fda23ffbc4cc472968a47d0b", size = 3281098 }, + { url = "https://files.pythonhosted.org/packages/51/c0/570255b2866a0e4d500a14f950803a2ec273bac7badc43320120b9262450/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a0d3b115009ebb8ac3d2ebec5c2982cc693da935f4ab7bb5c8ebe2f47d36f2", size = 3323665 }, + { url = "https://files.pythonhosted.org/packages/0e/75/689b4ec0483c42bfc7d1aacd32ade7a226db4f4fac57c6fdcdf90c0731e3/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:73853108f56df97baf2bb8b522f3578221e56f646ba345a372c78326710d3830", size = 3310533 }, + { url = "https://files.pythonhosted.org/packages/3d/30/38bd6149cf53da1db4bad304c543ade775d225961c4310f30425995cb9ec/pillow-11.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e58876c91f97b0952eb766123bfef372792ab3f4e3e1f1a2267834c2ab131734", size = 3414886 }, + { url = "https://files.pythonhosted.org/packages/ec/3d/c32a51d848401bd94cabb8767a39621496491ee7cd5199856b77da9b18ad/pillow-11.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:224aaa38177597bb179f3ec87eeefcce8e4f85e608025e9cfac60de237ba6316", size = 2567508 }, +] + +[[package]] +name = "pyparsing" +version = "3.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/d5/e5aeee5387091148a19e1145f63606619cb5f20b83fccb63efae6474e7b2/pyparsing-3.2.0.tar.gz", hash = "sha256:cbf74e27246d595d9a74b186b810f6fbb86726dbf3b9532efb343f6d7294fe9c", size = 920984 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/ec/2eb3cd785efd67806c46c13a17339708ddc346cbb684eade7a6e6f79536a/pyparsing-3.2.0-py3-none-any.whl", hash = "sha256:93d9577b88da0bbea8cc8334ee8b918ed014968fd2ec383e868fb8afb1ccef84", size = 106921 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "ruff" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/06/09d1276df977eece383d0ed66052fc24ec4550a61f8fbc0a11200e690496/ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313", size = 3243664 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/56/933d433c2489e4642487b835f53dd9ff015fb3d8fa459b09bb2ce42d7c4b/ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344", size = 10372090 }, + { url = "https://files.pythonhosted.org/packages/20/ea/1f0a22a6bcdd3fc26c73f63a025d05bd565901b729d56bcb093c722a6c4c/ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0", size = 10190037 }, + { url = "https://files.pythonhosted.org/packages/16/74/aca75666e0d481fe394e76a8647c44ea919087748024924baa1a17371e3e/ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9", size = 9811998 }, + { url = "https://files.pythonhosted.org/packages/20/a1/cf446a0d7f78ea1f0bd2b9171c11dfe746585c0c4a734b25966121eb4f5d/ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5", size = 10620626 }, + { url = "https://files.pythonhosted.org/packages/cd/c1/82b27d09286ae855f5d03b1ad37cf243f21eb0081732d4d7b0d658d439cb/ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299", size = 10177598 }, + { url = "https://files.pythonhosted.org/packages/b9/42/c0acac22753bf74013d035a5ef6c5c4c40ad4d6686bfb3fda7c6f37d9b37/ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e", size = 11171963 }, + { url = "https://files.pythonhosted.org/packages/43/18/bb0befb7fb9121dd9009e6a72eb98e24f1bacb07c6f3ecb55f032ba98aed/ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29", size = 11856157 }, + { url = "https://files.pythonhosted.org/packages/5e/91/04e98d7d6e32eca9d1372be595f9abc7b7f048795e32eb2edbd8794d50bd/ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5", size = 11440331 }, + { url = "https://files.pythonhosted.org/packages/f5/dc/3fe99f2ce10b76d389041a1b9f99e7066332e479435d4bebcceea16caff5/ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67", size = 12725354 }, + { url = "https://files.pythonhosted.org/packages/43/7b/1daa712de1c5bc6cbbf9fa60e9c41cc48cda962dc6d2c4f2a224d2c3007e/ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2", size = 11010091 }, + { url = "https://files.pythonhosted.org/packages/b6/db/1227a903587432eb569e57a95b15a4f191a71fe315cde4c0312df7bc85da/ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d", size = 10610687 }, + { url = "https://files.pythonhosted.org/packages/db/e2/dc41ee90c3085aadad4da614d310d834f641aaafddf3dfbba08210c616ce/ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2", size = 10254843 }, + { url = "https://files.pythonhosted.org/packages/6f/09/5f6cac1c91542bc5bd33d40b4c13b637bf64d7bb29e091dadb01b62527fe/ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2", size = 10730962 }, + { url = "https://files.pythonhosted.org/packages/d3/42/89a4b9a24ef7d00269e24086c417a006f9a3ffeac2c80f2629eb5ce140ee/ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16", size = 11101907 }, + { url = "https://files.pythonhosted.org/packages/b0/5c/efdb4777686683a8edce94ffd812783bddcd3d2454d38c5ac193fef7c500/ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc", size = 8611095 }, + { url = "https://files.pythonhosted.org/packages/bb/b8/28fbc6a4efa50178f973972d1c84b2d0a33cdc731588522ab751ac3da2f5/ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088", size = 9418283 }, + { url = "https://files.pythonhosted.org/packages/3f/77/b587cba6febd5e2003374f37eb89633f79f161e71084f94057c8653b7fb3/ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c", size = 8725228 }, +] + +[[package]] +name = "scipy" +version = "1.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/62/11/4d44a1f274e002784e4dbdb81e0ea96d2de2d1045b2132d5af62cc31fd28/scipy-1.14.1.tar.gz", hash = "sha256:5a275584e726026a5699459aa72f828a610821006228e841b94275c4a7c08417", size = 58620554 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/68/3bc0cfaf64ff507d82b1e5d5b64521df4c8bf7e22bc0b897827cbee9872c/scipy-1.14.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:b28d2ca4add7ac16ae8bb6632a3c86e4b9e4d52d3e34267f6e1b0c1f8d87e389", size = 39069598 }, + { url = "https://files.pythonhosted.org/packages/43/a5/8d02f9c372790326ad405d94f04d4339482ec082455b9e6e288f7100513b/scipy-1.14.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d0d2821003174de06b69e58cef2316a6622b60ee613121199cb2852a873f8cf3", size = 29879676 }, + { url = "https://files.pythonhosted.org/packages/07/42/0e0bea9666fcbf2cb6ea0205db42c81b1f34d7b729ba251010edf9c80ebd/scipy-1.14.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8bddf15838ba768bb5f5083c1ea012d64c9a444e16192762bd858f1e126196d0", size = 23088696 }, + { url = "https://files.pythonhosted.org/packages/15/47/298ab6fef5ebf31b426560e978b8b8548421d4ed0bf99263e1eb44532306/scipy-1.14.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:97c5dddd5932bd2a1a31c927ba5e1463a53b87ca96b5c9bdf5dfd6096e27efc3", size = 25470699 }, + { url = "https://files.pythonhosted.org/packages/d8/df/cdb6be5274bc694c4c22862ac3438cb04f360ed9df0aecee02ce0b798380/scipy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ff0a7e01e422c15739ecd64432743cf7aae2b03f3084288f399affcefe5222d", size = 35606631 }, + { url = "https://files.pythonhosted.org/packages/47/78/b0c2c23880dd1e99e938ad49ccfb011ae353758a2dc5ed7ee59baff684c3/scipy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e32dced201274bf96899e6491d9ba3e9a5f6b336708656466ad0522d8528f69", size = 41178528 }, + { url = "https://files.pythonhosted.org/packages/5d/aa/994b45c34b897637b853ec04334afa55a85650a0d11dacfa67232260fb0a/scipy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8426251ad1e4ad903a4514712d2fa8fdd5382c978010d1c6f5f37ef286a713ad", size = 42784535 }, + { url = "https://files.pythonhosted.org/packages/e7/1c/8daa6df17a945cb1a2a1e3bae3c49643f7b3b94017ff01a4787064f03f84/scipy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:a49f6ed96f83966f576b33a44257d869756df6cf1ef4934f59dd58b25e0327e5", size = 44772117 }, + { url = "https://files.pythonhosted.org/packages/b2/ab/070ccfabe870d9f105b04aee1e2860520460ef7ca0213172abfe871463b9/scipy-1.14.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:2da0469a4ef0ecd3693761acbdc20f2fdeafb69e6819cc081308cc978153c675", size = 39076999 }, + { url = "https://files.pythonhosted.org/packages/a7/c5/02ac82f9bb8f70818099df7e86c3ad28dae64e1347b421d8e3adf26acab6/scipy-1.14.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:c0ee987efa6737242745f347835da2cc5bb9f1b42996a4d97d5c7ff7928cb6f2", size = 29894570 }, + { url = "https://files.pythonhosted.org/packages/ed/05/7f03e680cc5249c4f96c9e4e845acde08eb1aee5bc216eff8a089baa4ddb/scipy-1.14.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:3a1b111fac6baec1c1d92f27e76511c9e7218f1695d61b59e05e0fe04dc59617", size = 23103567 }, + { url = "https://files.pythonhosted.org/packages/5e/fc/9f1413bef53171f379d786aabc104d4abeea48ee84c553a3e3d8c9f96a9c/scipy-1.14.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8475230e55549ab3f207bff11ebfc91c805dc3463ef62eda3ccf593254524ce8", size = 25499102 }, + { url = "https://files.pythonhosted.org/packages/c2/4b/b44bee3c2ddc316b0159b3d87a3d467ef8d7edfd525e6f7364a62cd87d90/scipy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:278266012eb69f4a720827bdd2dc54b2271c97d84255b2faaa8f161a158c3b37", size = 35586346 }, + { url = "https://files.pythonhosted.org/packages/93/6b/701776d4bd6bdd9b629c387b5140f006185bd8ddea16788a44434376b98f/scipy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fef8c87f8abfb884dac04e97824b61299880c43f4ce675dd2cbeadd3c9b466d2", size = 41165244 }, + { url = "https://files.pythonhosted.org/packages/06/57/e6aa6f55729a8f245d8a6984f2855696c5992113a5dc789065020f8be753/scipy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b05d43735bb2f07d689f56f7b474788a13ed8adc484a85aa65c0fd931cf9ccd2", size = 42817917 }, + { url = "https://files.pythonhosted.org/packages/ea/c2/5ecadc5fcccefaece775feadcd795060adf5c3b29a883bff0e678cfe89af/scipy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:716e389b694c4bb564b4fc0c51bc84d381735e0d39d3f26ec1af2556ec6aad94", size = 44781033 }, + { url = "https://files.pythonhosted.org/packages/c0/04/2bdacc8ac6387b15db6faa40295f8bd25eccf33f1f13e68a72dc3c60a99e/scipy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:631f07b3734d34aced009aaf6fedfd0eb3498a97e581c3b1e5f14a04164a456d", size = 39128781 }, + { url = "https://files.pythonhosted.org/packages/c8/53/35b4d41f5fd42f5781dbd0dd6c05d35ba8aa75c84ecddc7d44756cd8da2e/scipy-1.14.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:af29a935803cc707ab2ed7791c44288a682f9c8107bc00f0eccc4f92c08d6e07", size = 29939542 }, + { url = "https://files.pythonhosted.org/packages/66/67/6ef192e0e4d77b20cc33a01e743b00bc9e68fb83b88e06e636d2619a8767/scipy-1.14.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2843f2d527d9eebec9a43e6b406fb7266f3af25a751aa91d62ff416f54170bc5", size = 23148375 }, + { url = "https://files.pythonhosted.org/packages/f6/32/3a6dedd51d68eb7b8e7dc7947d5d841bcb699f1bf4463639554986f4d782/scipy-1.14.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:eb58ca0abd96911932f688528977858681a59d61a7ce908ffd355957f7025cfc", size = 25578573 }, + { url = "https://files.pythonhosted.org/packages/f0/5a/efa92a58dc3a2898705f1dc9dbaf390ca7d4fba26d6ab8cfffb0c72f656f/scipy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30ac8812c1d2aab7131a79ba62933a2a76f582d5dbbc695192453dae67ad6310", size = 35319299 }, + { url = "https://files.pythonhosted.org/packages/8e/ee/8a26858ca517e9c64f84b4c7734b89bda8e63bec85c3d2f432d225bb1886/scipy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f9ea80f2e65bdaa0b7627fb00cbeb2daf163caa015e59b7516395fe3bd1e066", size = 40849331 }, + { url = "https://files.pythonhosted.org/packages/a5/cd/06f72bc9187840f1c99e1a8750aad4216fc7dfdd7df46e6280add14b4822/scipy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:edaf02b82cd7639db00dbff629995ef185c8df4c3ffa71a5562a595765a06ce1", size = 42544049 }, + { url = "https://files.pythonhosted.org/packages/aa/7d/43ab67228ef98c6b5dd42ab386eae2d7877036970a0d7e3dd3eb47a0d530/scipy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:2ff38e22128e6c03ff73b6bb0f85f897d2362f8c052e3b8ad00532198fbdae3f", size = 44521212 }, + { url = "https://files.pythonhosted.org/packages/50/ef/ac98346db016ff18a6ad7626a35808f37074d25796fd0234c2bb0ed1e054/scipy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1729560c906963fc8389f6aac023739ff3983e727b1a4d87696b7bf108316a79", size = 39091068 }, + { url = "https://files.pythonhosted.org/packages/b9/cc/70948fe9f393b911b4251e96b55bbdeaa8cca41f37c26fd1df0232933b9e/scipy-1.14.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:4079b90df244709e675cdc8b93bfd8a395d59af40b72e339c2287c91860deb8e", size = 29875417 }, + { url = "https://files.pythonhosted.org/packages/3b/2e/35f549b7d231c1c9f9639f9ef49b815d816bf54dd050da5da1c11517a218/scipy-1.14.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e0cf28db0f24a38b2a0ca33a85a54852586e43cf6fd876365c86e0657cfe7d73", size = 23084508 }, + { url = "https://files.pythonhosted.org/packages/3f/d6/b028e3f3e59fae61fb8c0f450db732c43dd1d836223a589a8be9f6377203/scipy-1.14.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:0c2f95de3b04e26f5f3ad5bb05e74ba7f68b837133a4492414b3afd79dfe540e", size = 25503364 }, + { url = "https://files.pythonhosted.org/packages/a7/2f/6c142b352ac15967744d62b165537a965e95d557085db4beab2a11f7943b/scipy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b99722ea48b7ea25e8e015e8341ae74624f72e5f21fc2abd45f3a93266de4c5d", size = 35292639 }, + { url = "https://files.pythonhosted.org/packages/56/46/2449e6e51e0d7c3575f289f6acb7f828938eaab8874dbccfeb0cd2b71a27/scipy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5149e3fd2d686e42144a093b206aef01932a0059c2a33ddfa67f5f035bdfe13e", size = 40798288 }, + { url = "https://files.pythonhosted.org/packages/32/cd/9d86f7ed7f4497c9fd3e39f8918dd93d9f647ba80d7e34e4946c0c2d1a7c/scipy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4f5a7c49323533f9103d4dacf4e4f07078f360743dec7f7596949149efeec06", size = 42524647 }, + { url = "https://files.pythonhosted.org/packages/f5/1b/6ee032251bf4cdb0cc50059374e86a9f076308c1512b61c4e003e241efb7/scipy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:baff393942b550823bfce952bb62270ee17504d02a1801d7fd0719534dfb9c84", size = 44469524 }, +] + +[[package]] +name = "setuptools" +version = "75.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ed/22/a438e0caa4576f8c383fa4d35f1cc01655a46c75be358960d815bfbb12bd/setuptools-75.3.0.tar.gz", hash = "sha256:fba5dd4d766e97be1b1681d98712680ae8f2f26d7881245f2ce9e40714f1a686", size = 1351577 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/12/282ee9bce8b58130cb762fbc9beabd531549952cac11fc56add11dcb7ea0/setuptools-75.3.0-py3-none-any.whl", hash = "sha256:f2504966861356aa38616760c0f66568e535562374995367b4e69c7143cf6bcd", size = 1251070 }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, +] + +[[package]] +name = "toolz" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8a/0b/d80dfa675bf592f636d1ea0b835eab4ec8df6e9415d8cfd766df54456123/toolz-1.0.0.tar.gz", hash = "sha256:2c86e3d9a04798ac556793bced838816296a2f085017664e4995cb40a1047a02", size = 66790 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/98/eb27cc78ad3af8e302c9d8ff4977f5026676e130d28dd7578132a457170c/toolz-1.0.0-py3-none-any.whl", hash = "sha256:292c8f1c4e7516bf9086f8850935c799a874039c8bcf959d47b600e4c44a6236", size = 56383 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "xraylib" +version = "4.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/cc/f4d2c3231a256f62938fafbf42e487554fb4a83ab50a55e16be26cec468f/xraylib-4.1.5.tar.gz", hash = "sha256:0806b009a25288711cf7cc96fad61dbedd5668819562837d12ea8fe01343bfc1", size = 13204048 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/a5/ae97d11e2b73bf249e94a235464cb60f6939546fec1d0196f6c380d94d85/xraylib-4.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:325598da5ca8c1c33f6aa311c97d4a2bf4eaa0573f8a72486fe5b0c6a9ee5e5d", size = 16007436 }, + { url = "https://files.pythonhosted.org/packages/1a/a3/98cbd66c0cc866798687fa7cf71bc2b66ce97d88197ec0030047e4e2f0fc/xraylib-4.1.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e10a3c04effb88b0ac99a0504f868645c5fc6ac5303c9d3541085456d233079", size = 16221877 }, + { url = "https://files.pythonhosted.org/packages/40/77/a008bbf39a3398cb96c635efd8d3dd6b7ac42ad1ef94432c7b37b1ee7fe0/xraylib-4.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8824ec9d880fbd37d6f166114853bca82b6f5282c1df3163e3834b581366004d", size = 16356892 }, + { url = "https://files.pythonhosted.org/packages/f2/62/1e9148d2470beb1b3652c0775255f25f1c0afce02cf97d4a30b31db11a78/xraylib-4.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:508d263eeccf2a05a73cb7b4bf5d6568aa36f0982b9457b33a05df29d2590380", size = 14941025 }, + { url = "https://files.pythonhosted.org/packages/7a/33/69d6c1c11a61ed147959e71dddcc3cb0f351773bcd2497de197483626052/xraylib-4.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e514d7063dd0483aa675f2895db90522aa54ef88744bdc47b05ccaffa3df16cb", size = 16009809 }, + { url = "https://files.pythonhosted.org/packages/97/62/e14a4bc10af803f33052dd1d9bc65cd6bdcf28509e41ac938def376e3b9f/xraylib-4.1.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4d35c48bdc7aa851895e4f9dafb3cf2fdae9d0343504cf386f985c531f17348", size = 16222959 }, + { url = "https://files.pythonhosted.org/packages/7d/af/42d63aebf5130f9e60aeb2d5a4a3ad50f6b5c5fc7a0ba414948dd24e8961/xraylib-4.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e1e95564ef63f2948884cdc4a7a836667c2d1bc0c9f5a38961d5776a02c3387", size = 16360052 }, + { url = "https://files.pythonhosted.org/packages/56/bc/ec7a2a8bde475322b21fd953cac0bdb74404f13bbd8beb69c57fad475336/xraylib-4.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:b62de1b7e4a20f523cdc4a274a9b5f7dc196fbe4e206d93d9d8915682beec365", size = 14941442 }, + { url = "https://files.pythonhosted.org/packages/17/c1/471708d615351b1e6639e4237cc86290c4c09a475cb823c8d8cd675491fc/xraylib-4.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b3829a98de42cfe31b073ea57c0ac7a8eff36fda9597437ffca27bc10fa476b", size = 16009191 }, + { url = "https://files.pythonhosted.org/packages/05/5c/f5cdea6f822116868183e7004bacc297e4fa3f89324dee53c80b055808ce/xraylib-4.1.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a6ce16bffeebd42cfe83f43694b51174c69b3f01430e235109293903a7f97090", size = 16227522 }, + { url = "https://files.pythonhosted.org/packages/f8/76/1cc6ba2bb9d0e16eefcd04e188f08e8b1c4ddf4e43ba1e36807c58d2bc3e/xraylib-4.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c368962fe38126c445e2c1c0f2899c38f0593ba5d66657c2b01437759a0739aa", size = 16348727 }, + { url = "https://files.pythonhosted.org/packages/b2/cd/2e4e63e50ad81400d40df19f41992bb8ab9b374307ad4e1eaaa59481b9f3/xraylib-4.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:1102b6dfa6e761de3cb36b717559a55c76995000bd0b66d26d05d122978f4e5e", size = 14945070 }, + { url = "https://files.pythonhosted.org/packages/fb/0f/3b0cf048a1f11142f45c9f675c8d6fbac710b577cc21477d7087e8639d5c/xraylib-4.1.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25b4291679fa9b83b99c4aed3afcda966456fb686bfa49a75652f087ffc3a2cc", size = 16008267 }, + { url = "https://files.pythonhosted.org/packages/f1/5a/d18483ff841ebe38e711444c99d83965401f42c00d16b6375e6a6c84caf0/xraylib-4.1.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:41d760879012628051968bcfe1fc2b1373d69356b5d134f78cf5171b7f1c7971", size = 16226937 }, + { url = "https://files.pythonhosted.org/packages/52/c8/1b2ad0f1033ab0da1d8d616ea8f753b1de895834f8cbf4c66aef9e7913fc/xraylib-4.1.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f9b30a65368df889ff29929993d05abe16ed3e12ff1828e3d8cb5cd1661e84", size = 16350395 }, + { url = "https://files.pythonhosted.org/packages/8c/f9/a73c6b403e463ea8c648ffb01e764e913e300e47769ca528a0fd11bc91c3/xraylib-4.1.5-cp313-cp313-win_amd64.whl", hash = "sha256:0adcf21c5f94fc2456f115e74d59f8fe97394a1e762296a6616483a52c896388", size = 14945316 }, +]