diff --git a/cipher_parse/cipher_input.py b/cipher_parse/cipher_input.py index ef79a61..9639dbc 100644 --- a/cipher_parse/cipher_input.py +++ b/cipher_parse/cipher_input.py @@ -333,6 +333,7 @@ def from_voronoi( num_phases=None, random_seed=None, is_periodic=False, + combine_phases=None, ): geometry = CIPHERGeometry.from_voronoi( num_phases=num_phases, @@ -343,6 +344,7 @@ def from_voronoi( size=size, random_seed=random_seed, is_periodic=is_periodic, + combine_phases=combine_phases, ) inp = cls( @@ -366,6 +368,7 @@ def from_seed_voronoi( solution_parameters, random_seed=None, is_periodic=False, + combine_phases=None, ): return cls.from_voronoi( seeds=seeds, @@ -378,6 +381,7 @@ def from_seed_voronoi( solution_parameters=solution_parameters, random_seed=random_seed, is_periodic=is_periodic, + combine_phases=combine_phases, ) @classmethod @@ -393,6 +397,7 @@ def from_random_voronoi( solution_parameters, random_seed=None, is_periodic=False, + combine_phases=None, ): return cls.from_voronoi( num_phases=num_phases, @@ -405,6 +410,7 @@ def from_random_voronoi( solution_parameters=solution_parameters, random_seed=random_seed, is_periodic=is_periodic, + combine_phases=combine_phases, ) @classmethod @@ -418,6 +424,7 @@ def from_voxel_phase_map( outputs, solution_parameters, random_seed=None, + combine_phases=None, ): geometry = CIPHERGeometry( voxel_phase=voxel_phase, @@ -425,6 +432,7 @@ def from_voxel_phase_map( interfaces=interfaces, size=size, random_seed=random_seed, + combine_phases=combine_phases, ) inp = cls( geometry=geometry, @@ -445,6 +453,7 @@ def from_dream3D( solution_parameters, container_labels=None, phase_type_map=None, + combine_phases=None, ): default_container_labels = { "SyntheticVolumeDataContainer": "SyntheticVolumeDataContainer", @@ -559,6 +568,7 @@ def from_dream3D( components=components, outputs=outputs, solution_parameters=solution_parameters, + combine_phases=combine_phases, ) @property @@ -604,14 +614,17 @@ def write_yaml(self, path, separate_mappings=False): self.geometry._validate_interface_map() - phase_mat_str = compress_1D_array_string(self.geometry.phase_material + 1) + "\n" - vox_phase_str = ( - compress_1D_array_string(self.geometry.voxel_phase.flatten(order="F") + 1) - + "\n" - ) - int_str = ( - compress_1D_array_string(self.geometry.interface_map_int.flatten() + 1) + "\n" + phase_mat_str = compress_1D_array_string(self.geometry.phase_material + 1) + vox_phase_str = compress_1D_array_string( + self.geometry.voxel_phase.flatten(order="F") + 1 ) + int_str = compress_1D_array_string(self.geometry.interface_map_int.flatten() + 1) + + if not separate_mappings: + # CIPHER does not like trailing new lines in the mapping text files: + phase_mat_str += "\n" + vox_phase_str += "\n" + int_str += "\n" if separate_mappings: phase_mat_map = "phase_material_mapping.txt" diff --git a/cipher_parse/cipher_output.py b/cipher_parse/cipher_output.py index 027b303..4374fcb 100644 --- a/cipher_parse/cipher_output.py +++ b/cipher_parse/cipher_output.py @@ -246,15 +246,28 @@ def get_incremental_data(self): incremental_data = [] for file_i_idx, file_i in enumerate(vtu_file_list): print(f"Reading VTU file {file_i.name}...", flush=True) - mesh = pv.get_reader(file_i).read() + try: + mesh = pv.get_reader(file_i).read() + except Exception: + print(f"Failed to read VTU file {file_i.name}.", flush=True) + continue vtu_file_name = file_i.name img_data = pv.ImageData(dimensions=grid_size) + print( f"Resampling VTU file {file_i.name} onto an image-data mesh...", flush=True, ) - img_mesh = img_data.sample(mesh) + try: + img_mesh = img_data.sample(mesh) + except Exception: + print( + f"Failed to re-sample VTU file {file_i.name} onto an image " + f"data grid.", + flush=True, + ) + continue inc_data_i = { "increment": int(re.search(r"\d+", vtu_file_name).group()), @@ -267,7 +280,15 @@ def get_incremental_data(self): standard_outputs = {} for name in output_lookup: - arr_flat = img_mesh.get_array(output_lookup[name]) + try: + arr_flat = img_mesh.get_array(output_lookup[name]) + except KeyError: + print( + f"Failed to get array {output_lookup[name]} from file " + f"{file_i.name}", + flush=True, + ) + continue arr = arr_flat.reshape(img_mesh.dimensions, order="F") if name in STANDARD_OUTPUTS_TYPES: arr = arr.astype(STANDARD_OUTPUTS_TYPES[name]) @@ -278,19 +299,33 @@ def get_incremental_data(self): name_i = derive_out_i["name"] func = DERIVED_OUTPUTS_FUNCS[name_i] func_args = {"input_data": inp_dat} - func_args.update( - {i: standard_outputs[i] for i in DERIVED_OUTPUTS_REQUIREMENTS[name_i]} - ) + try: + func_args.update( + { + i: standard_outputs[i] + for i in DERIVED_OUTPUTS_REQUIREMENTS[name_i] + } + ) + except KeyError: + print( + f"Failed to prepare arguments for derived output function " + f"{func.__name__!r}.", + flush=True, + ) + continue derived_outputs[name_i] = func(**func_args) for out_name, keep_idx in outputs_keep_idx.items(): if file_i_idx in keep_idx: - if out_name in DERIVED_OUTPUTS_REQUIREMENTS: - # a derived output: - inc_data_i[out_name] = derived_outputs[out_name] - else: - # a standard output: - inc_data_i[out_name] = standard_outputs[out_name] + try: + if out_name in DERIVED_OUTPUTS_REQUIREMENTS: + # a derived output: + inc_data_i[out_name] = derived_outputs[out_name] + else: + # a standard output: + inc_data_i[out_name] = standard_outputs[out_name] + except KeyError: + continue incremental_data.append(inc_data_i) @@ -434,7 +469,7 @@ def from_JSON_file(cls, path): data = json.load(fp) return cls.from_JSON(data) - def to_zarr(self, path): + def to_zarr(self, path, overwrite=False, close_store=None): """Save to a persistent zarr store. This does not yet save `geometries`. @@ -455,10 +490,12 @@ def to_zarr(self, path): out_group.create_dataset( name="stdout_file_str", data=self.stdout_file_str.splitlines(), + overwrite=overwrite, ) out_group.create_dataset( name="input_YAML_file_str", data=self.input_YAML_file_str.splitlines(), + overwrite=overwrite, ) inc_dat_group = out_group.create_group("incremental_data", overwrite=True) for idx, inc_dat_i in enumerate(self.incremental_data): @@ -466,7 +503,15 @@ def to_zarr(self, path): inc_dat_i_group.attrs.put({k: inc_dat_i[k] for k in INC_DATA_NON_ARRAYS}) for k in inc_dat_i: if k not in INC_DATA_NON_ARRAYS: - inc_dat_i_group.create_dataset(name=k, data=inc_dat_i[k]) + inc_dat_i_group.create_dataset( + name=k, data=inc_dat_i[k], overwrite=overwrite + ) + + if path.endswith(".zip") and close_store is None: + close_store = True + + if close_store: + out_group.store.close() return out_group @@ -477,7 +522,7 @@ def from_zarr(cls, path, cipher_input=None, quiet=True): This does not yet load `geometries`. """ - group = zarr.open_group(store=path) + group = zarr.open_group(store=path, mode="r") attrs = group.attrs.asdict() kwargs = { "directory": attrs["directory"], diff --git a/cipher_parse/geometry.py b/cipher_parse/geometry.py index 79df855..e260547 100644 --- a/cipher_parse/geometry.py +++ b/cipher_parse/geometry.py @@ -1,3 +1,5 @@ +import random + from damask import Orientation import pyvista as pv import numpy as np @@ -39,6 +41,7 @@ def __init__( time=None, increment=None, incremental_data_idx=None, + combine_phases=None, ): """ Parameters @@ -107,6 +110,22 @@ def __init__( self._ensure_phase_assignment(random_seed) + if combine_phases: + # combine multiple phases into the same phase to reduce the computational cost + self.voxel_phase = self.combine_phases_per_phase_type( + voxel_map, + materials, + combine_phases, + ) + self.voxel_map = VoxelMap( + region_ID=voxel_phase, + size=size, + is_periodic=is_periodic, + quiet=quiet, + ) + all_phases = self.present_phases + self._num_phases = all_phases.size + self._phase_material = self._get_phase_material() self._validate_interfaces() self._check_interface_phase_pairs() @@ -131,6 +150,93 @@ def __init__( self._misorientation_matrix = None self._misorientation_matrix_is_degrees = None + @staticmethod + def combine_phases_per_phase_type(voxel_map, materials, combine_phases): + + print(f"combining phases according to {combine_phases}") + + voxel_phase_new = voxel_map.region_ID + neighbours = voxel_map.neighbour_list + + for mat in materials: + for pt_i in mat.phase_types: + print(f"{pt_i.name=}") + max_phases_i = combine_phases.get(pt_i.name) + if max_phases_i: + + n_phases = pt_i.phases.size + group_size = int(np.ceil(n_phases / max_phases_i)) + + print(f" n_phases: {n_phases}") + print(f" max_phases_i: {max_phases_i}") + print(f" group_size: {group_size}") + + voxel_phase_new = np.copy(voxel_phase_new) + + reassignment = {} + reassignment_inv = {} + possible_IDs_idx = set(range(max_phases_i, n_phases)) + possible_IDs = set(pt_i.phases[list(possible_IDs_idx)]) + count = 0 + kept_IDs = [] + for root_ID_idx in range(int(np.ceil(n_phases / group_size))): + + root_ID = pt_i.phases[root_ID_idx] + kept_IDs.append(root_ID) + + neighbours_i = set(neighbours[:, neighbours[0] == root_ID][1]) + possible_IDs -= {root_ID} + possible_IDs_i = possible_IDs - neighbours_i + shared_IDs = [root_ID] + count += 1 + + for _ in range(1, group_size): + if count >= n_phases: + break + try: + sampled_ID = random.sample(possible_IDs_i, 1)[0] + except ValueError: + print( + f"No non-neighbouring samples left for root_ID: {root_ID}." + ) + # allow touching phase IDs within this group: + possible_IDs_i = possible_IDs - set(shared_IDs) + + if possible_IDs_i: + sampled_ID = random.sample(possible_IDs_i, 1)[0] + else: + raise ValueError( + f"Cannot find non-neighbouring root IDs" + ) from None + + neighbours_sampled = set( + neighbours[:, neighbours[0] == sampled_ID][1] + ) + possible_IDs_i -= neighbours_sampled + possible_IDs_i -= {sampled_ID} + possible_IDs -= {sampled_ID} + shared_IDs.append(sampled_ID) + count += 1 + + for i in shared_IDs: + reassignment[i] = root_ID + voxel_phase_new[voxel_phase_new == i] = root_ID + + reassignment_inv[root_ID] = shared_IDs + + pt_i.phases = kept_IDs # modify phase type phases + + # reindex phases across all materials to maintain consecutive phase IDs: + voxel_phase_new_flat = voxel_phase_new.reshape(-1) + uniq, inv = np.unique(voxel_phase_new_flat, return_inverse=True) + reindex = dict(zip(uniq, range(len(uniq)))) + voxel_phase_new = inv.reshape(voxel_phase_new.shape) + for mat_j in materials: + for pt_j in mat_j.phase_types: + pt_j.phases = np.array([reindex[i] for i in pt_j.phases]) + + return voxel_phase_new + def __eq__(self, other): # Note we don't check seeds (not stored in YAML file) if not isinstance(other, self.__class__): @@ -456,7 +562,7 @@ def _get_phase_material(self): "Not all phases are accounted for in the phase type definitions." ) # TODO: test raise - # check all phase indices form a consequtive range: + # check all phase indices form a consecutive range: num_phases_range = set(np.arange(self.num_phases)) known_phases = set(np.hstack(all_phase_idx)) miss_phase_idx = num_phases_range - known_phases @@ -740,6 +846,7 @@ def from_voronoi( num_phases=None, random_seed=None, is_periodic=False, + combine_phases=None, ): if sum(i is not None for i in (seeds, num_phases)) != 1: raise ValueError(f"Specify exactly one of `seeds` and `num_phases`") @@ -769,6 +876,7 @@ def from_voronoi( size=size, seeds=seeds, random_seed=random_seed, + combine_phases=combine_phases, ) @classmethod diff --git a/poetry.lock b/poetry.lock index 38ac7c4..5feb043 100644 --- a/poetry.lock +++ b/poetry.lock @@ -586,6 +586,25 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} +[[package]] +name = "cmocean" +version = "3.1.3" +description = "Colormaps for Oceanography" +optional = false +python-versions = ">=3.8" +files = [ + {file = "cmocean-3.1.3-py3-none-any.whl", hash = "sha256:b088f4409b0e40e3d9946ca165c62015806963dccfdb39b235301085157f999d"}, + {file = "cmocean-3.1.3.tar.gz", hash = "sha256:a4599a765e679477323292a8f62631439e16e92c3e5cb4f14c5264fc6d232a10"}, +] + +[package.dependencies] +matplotlib = "*" +numpy = "*" +packaging = "*" + +[package.extras] +plots = ["colorspacious", "viscm"] + [[package]] name = "colorama" version = "0.4.6" @@ -1881,6 +1900,31 @@ websocket-client = "*" docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] +[[package]] +name = "jupyter-server-proxy" +version = "4.1.2" +description = "A Jupyter server extension to run additional processes and proxy to them that comes bundled JupyterLab extension to launch pre-defined processes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server_proxy-4.1.2-py3-none-any.whl", hash = "sha256:f97bd0c6bbba4931d8ae22bef872703c9785fc1258c4bc196955e2bd034f3eaa"}, + {file = "jupyter_server_proxy-4.1.2.tar.gz", hash = "sha256:6fd8ce88a0100e637b48f1d3aa32f09672bcb2813dc057d70567f0a40b1237f5"}, +] + +[package.dependencies] +aiohttp = "*" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-server = ">=1.0" +simpervisor = ">=1.0" +tornado = ">=5.1" +traitlets = ">=4.2.1" + +[package.extras] +acceptance = ["jupyter-server-proxy[test]", "robotframework-jupyterlibrary (>=0.4.2)"] +classic = ["jupyter-server (<2)", "jupyterlab (>=3.0.0,<4.0.0a0)", "notebook (<7.0.0a0)"] +lab = ["jupyter-server (>=2)", "jupyterlab (>=4.0.5,<5.0.0a0)", "nbclassic", "notebook (>=7)"] +test = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-html"] + [[package]] name = "jupyter-server-terminals" version = "0.4.4" @@ -2044,6 +2088,30 @@ files = [ {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, ] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "2.1.2" @@ -2240,6 +2308,35 @@ files = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "meshio" +version = "5.3.5" +description = "I/O for many mesh formats" +optional = false +python-versions = ">=3.8" +files = [ + {file = "meshio-5.3.5-py3-none-any.whl", hash = "sha256:0736c6e34ecc768f62f2cde5d8233a3529512a9399b25c68ea2ca0d5900cdc10"}, + {file = "meshio-5.3.5.tar.gz", hash = "sha256:f21f01abd9f29ba06ea119304b3d39e610421cfe93b9dd23362834919f87586d"}, +] + +[package.dependencies] +numpy = ">=1.20.0" +rich = "*" + +[package.extras] +all = ["h5py", "netCDF4"] + [[package]] name = "mistune" version = "2.0.5" @@ -2930,13 +3027,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pooch" -version = "1.7.0" +version = "1.8.1" description = "\"Pooch manages your Python library's sample data files: it automatically downloads and stores them in a local directory, with support for versioning and corruption checks.\"" optional = false python-versions = ">=3.7" files = [ - {file = "pooch-1.7.0-py3-none-any.whl", hash = "sha256:74258224fc33d58f53113cf955e8d51bf01386b91492927d0d1b6b341a765ad7"}, - {file = "pooch-1.7.0.tar.gz", hash = "sha256:f174a1041b6447f0eef8860f76d17f60ed2f857dc0efa387a7f08228af05d998"}, + {file = "pooch-1.8.1-py3-none-any.whl", hash = "sha256:6b56611ac320c239faece1ac51a60b25796792599ce5c0b1bb87bf01df55e0a9"}, + {file = "pooch-1.8.1.tar.gz", hash = "sha256:27ef63097dd9a6e4f9d2694f5cfbf2f0a5defa44fccafec08d601e731d746270"}, ] [package.dependencies] @@ -3284,29 +3381,40 @@ files = [ [[package]] name = "pyvista" -version = "0.39.0" +version = "0.43.4" description = "Easier Pythonic interface to VTK" optional = false python-versions = ">=3.8" files = [ - {file = "pyvista-0.39.0-py3-none-any.whl", hash = "sha256:e7132aa2232c7e9c4096354e45938d9d59527c0ea79047b4f1ccadeaacc5ddce"}, - {file = "pyvista-0.39.0.tar.gz", hash = "sha256:55e1f668100cb803285053d4c4e0091225be2aef4875c614aa142478d20b4f60"}, + {file = "pyvista-0.43.4-py3-none-any.whl", hash = "sha256:f1fc56ac9ea1447660dec91e06b37f48736fd6983a2ed9fb2780252724b1caeb"}, + {file = "pyvista-0.43.4.tar.gz", hash = "sha256:e0b950d8283ba4e1333801d1d5fcdb2fa2f03a64e085b5b04ed8b7dcca6a7ac7"}, ] [package.dependencies] +cmocean = {version = "*", optional = true, markers = "extra == \"colormaps\""} +colorcet = {version = "*", optional = true, markers = "extra == \"colormaps\""} +imageio = {version = "*", optional = true, markers = "extra == \"io\""} +ipywidgets = {version = "*", optional = true, markers = "extra == \"jupyter\""} +jupyter-server-proxy = {version = "*", optional = true, markers = "extra == \"jupyter\""} matplotlib = ">=3.0.1" -numpy = "*" +meshio = {version = ">=5.2", optional = true, markers = "extra == \"io\""} +nest-asyncio = {version = "*", optional = true, markers = "extra == \"jupyter\""} +numpy = ">=1.21.0" pillow = "*" pooch = "*" scooby = ">=0.5.1" +trame = {version = ">=2.5.2", optional = true, markers = "extra == \"jupyter\""} +trame-client = {version = ">=2.12.7", optional = true, markers = "extra == \"jupyter\""} +trame-server = {version = ">=2.11.7", optional = true, markers = "extra == \"jupyter\""} +trame-vtk = {version = ">=2.5.8", optional = true, markers = "extra == \"jupyter\""} +trame-vuetify = {version = ">=2.3.1", optional = true, markers = "extra == \"jupyter\""} vtk = "*" [package.extras] -all = ["cmocean", "colorcet", "imageio", "ipyvtklink", "ipywidgets", "jupyter-server-proxy", "meshio (>=5.2)", "nest-asyncio", "panel", "pythreejs", "trame (>=2.2.6)", "trame-client (>=2.4.2)", "trame-server (>=2.8.0)", "trame-vtk (>=2.4.0)"] +all = ["pyvista[colormaps,io,jupyter]"] colormaps = ["cmocean", "colorcet"] io = ["imageio", "meshio (>=5.2)"] -jupyter = ["ipyvtklink", "ipywidgets", "jupyter-server-proxy", "nest-asyncio", "panel", "pythreejs", "trame (>=2.2.6)", "trame-client (>=2.4.2)", "trame-server (>=2.8.0)", "trame-vtk (>=2.4.0)"] -trame = ["trame (>=2.2.6)", "trame-client (>=2.4.2)", "trame-server (>=2.8.0)", "trame-vtk (>=2.4.0)"] +jupyter = ["ipywidgets", "jupyter-server-proxy", "nest-asyncio", "trame (>=2.5.2)", "trame-client (>=2.12.7)", "trame-server (>=2.11.7)", "trame-vtk (>=2.5.8)", "trame-vuetify (>=2.3.1)"] [[package]] name = "pywavelets" @@ -3584,6 +3692,25 @@ files = [ {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, ] +[[package]] +name = "rich" +version = "13.7.1" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, + {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "ruamel-yaml" version = "0.17.26" @@ -3738,13 +3865,13 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo [[package]] name = "scooby" -version = "0.7.2" +version = "0.9.2" description = "A Great Dane turned Python environment detective" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "scooby-0.7.2-py3-none-any.whl", hash = "sha256:75b77d22ecc22a5578fb0bb2957e8d024fa863fe905cd43447a86860afe37978"}, - {file = "scooby-0.7.2.tar.gz", hash = "sha256:6ba082ede5a82952b42538f913b3dfe3581ab79f5628e6c6efd3481f6cb5756e"}, + {file = "scooby-0.9.2-py3-none-any.whl", hash = "sha256:3cbc59de9febf8c8ba1e01bc7d08b4eca18ece3212d38b08a6f45188f88c8ea9"}, + {file = "scooby-0.9.2.tar.gz", hash = "sha256:28df643bb7c2087547b2e2220070e2f89e815ddbc515fbc28dd5df2b0a14293e"}, ] [package.extras] @@ -3782,6 +3909,20 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +[[package]] +name = "simpervisor" +version = "1.0.0" +description = "Simple async process supervisor" +optional = false +python-versions = ">=3.8" +files = [ + {file = "simpervisor-1.0.0-py3-none-any.whl", hash = "sha256:3e313318264559beea3f475ead202bc1cd58a2f1288363abb5657d306c5b8388"}, + {file = "simpervisor-1.0.0.tar.gz", hash = "sha256:7eb87ca86d5e276976f5bb0290975a05d452c6a7b7f58062daea7d8369c823c1"}, +] + +[package.extras] +test = ["aiohttp", "psutil", "pytest", "pytest-asyncio", "pytest-cov"] + [[package]] name = "six" version = "1.16.0" @@ -4247,41 +4388,44 @@ test = ["numpy", "pandas", "pytest", "xarray"] [[package]] name = "trame" -version = "2.4.2" +version = "2.5.2" description = "Trame, a framework to build applications in plain Python" optional = false python-versions = "*" files = [ - {file = "trame-2.4.2-py3-none-any.whl", hash = "sha256:d958783e4d7a99d1a0ba3c301ee3279c47c63944b71ced397637b86b5d2f5065"}, - {file = "trame-2.4.2.tar.gz", hash = "sha256:28a3f8e99da5b9eeb633a23f0921cd0610dc52d4e01ef6fac22ad848416f95b8"}, + {file = "trame-2.5.2-py3-none-any.whl", hash = "sha256:2948be7691cbcbbfa64144581acc825a669bb47a2d76b78d728db21be008daa5"}, + {file = "trame-2.5.2.tar.gz", hash = "sha256:875320353517c133312e46dc87c66050f721f045fd8817cd394fe06363e84ce2"}, ] [package.dependencies] -trame-client = ">=2.1.0" -trame-components = "2.1.0" -trame-deckgl = "2.0.1" -trame-markdown = "2.0.2" -trame-matplotlib = "2.0.1" -trame-plotly = "2.1.0" +trame-client = ">=2.7.7" +trame-components = "<3.0.0" +trame-deckgl = "<3.0.0" +trame-markdown = "<3.0.0" +trame-matplotlib = "<3.0.0" +trame-plotly = "<3.0.0" trame-rca = "<3.0.0" -trame-router = "2.0.1" -trame-server = ">=2.11.0" +trame-router = "<3.0.0" +trame-server = ">=2.11.7" trame-simput = "<3.0.0" -trame-vega = "2.0.2" +trame-vega = "<3.0.0" trame-vtk = "<3.0.0" trame-vuetify = "<3.0.0" [[package]] name = "trame-client" -version = "2.7.5" +version = "2.16.5" description = "Internal client of trame" optional = false python-versions = "*" files = [ - {file = "trame-client-2.7.5.tar.gz", hash = "sha256:54457d9cc9216c92e2c2ad855efaf41b951bd1d4d8010ad19df00dc9f1a16238"}, - {file = "trame_client-2.7.5-py3-none-any.whl", hash = "sha256:3743838c900ddc968f7b930bed269742371038a47e61d333156009c97d27a188"}, + {file = "trame-client-2.16.5.tar.gz", hash = "sha256:db4d5dc77760f30e9e6fc4d8e3f5b44a9177ad6ad567551824fa10bb165d9f72"}, + {file = "trame_client-2.16.5-py3-none-any.whl", hash = "sha256:055fb58be2003044700fd16615ba960842e7a4e832ca8d2a4d912ca5f4e60397"}, ] +[package.extras] +test = ["Pillow", "pixelmatch", "pytest", "pytest-xprocess", "seleniumbase"] + [[package]] name = "trame-components" version = "2.1.0" @@ -4383,13 +4527,13 @@ trame-client = "*" [[package]] name = "trame-server" -version = "2.11.0" +version = "2.11.7" description = "Internal server side implementation of trame" optional = false python-versions = "*" files = [ - {file = "trame-server-2.11.0.tar.gz", hash = "sha256:9838553a8f9f4b81bc746bc39e5380212890c660b437e8aebdff3ac372a8418d"}, - {file = "trame_server-2.11.0-py3-none-any.whl", hash = "sha256:93a9525bc3f72bee80ec35d37622259c585a34b76210c22c2d9ecd979fa956a8"}, + {file = "trame-server-2.11.7.tar.gz", hash = "sha256:6cca8f1f786bc7b121925524be85ce1ee9440a9911eaa16564e9af764dca6cd3"}, + {file = "trame_server-2.11.7-py3-none-any.whl", hash = "sha256:450e5b2ba450ebace4ed1cc37bda5d5a5a233963c7ea3f0965a6f6ea0319f26f"}, ] [package.dependencies] @@ -4426,13 +4570,13 @@ trame-client = "*" [[package]] name = "trame-vtk" -version = "2.4.4" +version = "2.8.5" description = "VTK widgets for trame" optional = false python-versions = "*" files = [ - {file = "trame-vtk-2.4.4.tar.gz", hash = "sha256:718663b3a8c95dd59f8f932ee2bda609b3b418790d4ff5e2a241aa743e65b29f"}, - {file = "trame_vtk-2.4.4-py3-none-any.whl", hash = "sha256:9c1ae2f68348f741aa9d9408d5f298613aa636adffd3d1fd35e6d17fd619e560"}, + {file = "trame-vtk-2.8.5.tar.gz", hash = "sha256:bd370840de78a73ed112948da6c8de66711e84003c76da0d1258a3ef5ba587d9"}, + {file = "trame_vtk-2.8.5-py3-none-any.whl", hash = "sha256:b89c6a164b6ec7e63b8a181547a7dda2a859f0fb16835e2686afc861d8c7b397"}, ] [package.dependencies] @@ -4440,13 +4584,13 @@ trame-client = "*" [[package]] name = "trame-vuetify" -version = "2.2.4" +version = "2.4.3" description = "Vuetify widgets for trame" optional = false python-versions = "*" files = [ - {file = "trame-vuetify-2.2.4.tar.gz", hash = "sha256:41316c16cf6af2446e980a0bbc32a549209bb27cc5fd4d18b87945e607ccc69a"}, - {file = "trame_vuetify-2.2.4-py3-none-any.whl", hash = "sha256:fede3b08db60f50e0f6ab36594c662c6cee010b7514376bfdfbece8a5c2ba9ee"}, + {file = "trame-vuetify-2.4.3.tar.gz", hash = "sha256:aa96059cb739244cf023f9af83f6b446e2207ebe3faff33a6f73f34efaf26eb7"}, + {file = "trame_vuetify-2.4.3-py3-none-any.whl", hash = "sha256:a3d05d714b78241d61fb5c76f65754e4b26afae67a3667a2daf47b399035f69c"}, ] [package.dependencies] @@ -4921,4 +5065,4 @@ notebook = ["notebook"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<3.11" -content-hash = "d251f7abd73aa3726138e2e7d9119e651d0b7fbcbcea8a2a761964ae2e650eff" +content-hash = "795f5ba111959e2e7960a43fbed69050e28c0527009739e9d5682e8f0d57c817" diff --git a/pyproject.toml b/pyproject.toml index f1725e0..39ce97f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,10 +27,10 @@ pandas = "^1.5.1" parse = "^1.19.0" ipywidgets = "<8.0.0" sqlalchemy = {version = "<2.0.0", optional = true} -pyvista = "^0.39.0" trame = "^2.4.2" defdap = "^0.93.5" zarr = "^2.16.0" +pyvista = {extras = ["all", "trame"], version = "^0.43.4"} [tool.poetry.dev-dependencies] pylint = "^2.12.2"