compgen 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- compgen-0.1.0/LICENSE +23 -0
- compgen-0.1.0/PKG-INFO +105 -0
- compgen-0.1.0/README.md +64 -0
- compgen-0.1.0/compgen/__init__.py +29 -0
- compgen-0.1.0/compgen/exoutil.py +43 -0
- compgen-0.1.0/compgen/filters.py +120 -0
- compgen-0.1.0/compgen/gen.py +612 -0
- compgen-0.1.0/compgen/hdfwriter.py +57 -0
- compgen-0.1.0/compgen/materials.py +78 -0
- compgen-0.1.0/compgen/mesh.py +507 -0
- compgen-0.1.0/compgen/moose.py +365 -0
- compgen-0.1.0/compgen/physics/2d/elastic/settings.json +56 -0
- compgen-0.1.0/compgen/physics/2d/elastic/template.i +209 -0
- compgen-0.1.0/compgen/physics/2d/plastic/settings.json +95 -0
- compgen-0.1.0/compgen/physics/2d/plastic/template.i +558 -0
- compgen-0.1.0/compgen/physics/2d/thermal_conductivity/settings.json +49 -0
- compgen-0.1.0/compgen/physics/2d/thermal_conductivity/template.i +215 -0
- compgen-0.1.0/compgen/physics/2d/thermal_conductivity_with_interface/settings.json +53 -0
- compgen-0.1.0/compgen/physics/2d/thermal_conductivity_with_interface/template.i +229 -0
- compgen-0.1.0/compgen/physics/2d/thermal_expansion/settings.json +55 -0
- compgen-0.1.0/compgen/physics/2d/thermal_expansion/template.i +233 -0
- compgen-0.1.0/compgen/physics/3d/elastic/settings.json +68 -0
- compgen-0.1.0/compgen/physics/3d/elastic/template.i +281 -0
- compgen-0.1.0/compgen/physics/3d/plastic/settings.json +245 -0
- compgen-0.1.0/compgen/physics/3d/plastic/template.i +658 -0
- compgen-0.1.0/compgen/physics/3d/thermal_conductivity/settings.json +53 -0
- compgen-0.1.0/compgen/physics/3d/thermal_conductivity/template.i +245 -0
- compgen-0.1.0/compgen/physics/3d/thermal_conductivity_with_interface/settings.json +57 -0
- compgen-0.1.0/compgen/physics/3d/thermal_conductivity_with_interface/template.i +259 -0
- compgen-0.1.0/compgen/physics/3d/thermal_expansion/settings.json +61 -0
- compgen-0.1.0/compgen/physics/3d/thermal_expansion/template.i +276 -0
- compgen-0.1.0/compgen/runner.py +407 -0
- compgen-0.1.0/compgen/temp.py +56 -0
- compgen-0.1.0/compgen/tensors.py +65 -0
- compgen-0.1.0/compgen/utils.py +180 -0
- compgen-0.1.0/compgen.egg-info/PKG-INFO +105 -0
- compgen-0.1.0/compgen.egg-info/SOURCES.txt +45 -0
- compgen-0.1.0/compgen.egg-info/dependency_links.txt +1 -0
- compgen-0.1.0/compgen.egg-info/requires.txt +20 -0
- compgen-0.1.0/compgen.egg-info/top_level.txt +1 -0
- compgen-0.1.0/pyproject.toml +67 -0
- compgen-0.1.0/setup.cfg +4 -0
- compgen-0.1.0/tests/test_filters.py +84 -0
- compgen-0.1.0/tests/test_gen.py +121 -0
- compgen-0.1.0/tests/test_materials.py +64 -0
- compgen-0.1.0/tests/test_mesh.py +133 -0
- compgen-0.1.0/tests/test_utils.py +152 -0
compgen-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Copyright 2026, UChicago Argonne, LLC
|
|
2
|
+
All Rights Reserved
|
|
3
|
+
Software Name: compgen
|
|
4
|
+
By: Argonne National Laboratory
|
|
5
|
+
OPEN SOURCE LICENSE (MIT)
|
|
6
|
+
|
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
in the Software without restriction, including without limitation the rights
|
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
furnished to do so, subject to the following conditions:
|
|
13
|
+
|
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
|
15
|
+
all copies or substantial portions of the Software.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
THE SOFTWARE.
|
compgen-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: compgen
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python toolkit for generating simulation data for two phase composite materials.
|
|
5
|
+
Author: Mark Messner, Tianchen Hu, Fabio Sozio
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/applied-material-modeling/compgen
|
|
8
|
+
Project-URL: Repository, https://github.com/applied-material-modeling/compgen
|
|
9
|
+
Project-URL: Issues, https://github.com/applied-material-modeling/compgen/issues
|
|
10
|
+
Keywords: composite materials,microstructure,finite element,homogenization,MOOSE,dataset generation
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Operating System :: POSIX
|
|
14
|
+
Classifier: Operating System :: MacOS
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
20
|
+
Requires-Python: >=3.13
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
License-File: LICENSE
|
|
23
|
+
Requires-Dist: numpy
|
|
24
|
+
Requires-Dist: scipy
|
|
25
|
+
Requires-Dist: h5py
|
|
26
|
+
Requires-Dist: scikit-image
|
|
27
|
+
Requires-Dist: gstools
|
|
28
|
+
Requires-Dist: multiprocess
|
|
29
|
+
Requires-Dist: pyvista
|
|
30
|
+
Requires-Dist: exodusii==26.10.29
|
|
31
|
+
Provides-Extra: mcrpy
|
|
32
|
+
Requires-Dist: mcrpy; extra == "mcrpy"
|
|
33
|
+
Provides-Extra: demos
|
|
34
|
+
Requires-Dist: matplotlib; extra == "demos"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: black==26.3.0; extra == "dev"
|
|
37
|
+
Requires-Dist: pytest==9.0.2; extra == "dev"
|
|
38
|
+
Requires-Dist: pylint==4.0.5; extra == "dev"
|
|
39
|
+
Requires-Dist: pre-commit==4.7.0; extra == "dev"
|
|
40
|
+
Dynamic: license-file
|
|
41
|
+
|
|
42
|
+
# compgen
|
|
43
|
+
|
|
44
|
+
## Summary
|
|
45
|
+
compgen is a Python toolkit for generating simulation data for two phase composite materials. It will generate structures, invoke physics codes to simulate the response for a variety of material properties, and write summaries of the results.
|
|
46
|
+
|
|
47
|
+
## Install
|
|
48
|
+
compgen requires Python 3.13 or newer.
|
|
49
|
+
|
|
50
|
+
1. (Optional) Create and activate a virtual environment.
|
|
51
|
+
2. Install the package:
|
|
52
|
+
- `pip install compgen`
|
|
53
|
+
- To use the reconstruction generator, `pip install compgen[mcrpy]`. mcrpy depends on TensorFlow, which currently supports Python up to 3.13, so use Python 3.13 for this option.
|
|
54
|
+
- To develop compgen, or to run the tests and demos, clone this repository and run `pip install -e .[dev,demos]` from its root.
|
|
55
|
+
3. Install the mesher and physics codes you want to use:
|
|
56
|
+
1. [MOOSE](https://mooseframework.inl.gov/)
|
|
57
|
+
2. [SCULPT](https://www.sandia.gov/files/cubit/documents/SculptSANDReport.pdf)
|
|
58
|
+
|
|
59
|
+
## Inputs
|
|
60
|
+
|
|
61
|
+
compgen pipes together several steps to generate results:
|
|
62
|
+
1. Generate a composite structure -- the distribution of two materials A and B over a periodic domain. We use pixelated fixed grids to define this distribution.
|
|
63
|
+
2. Make an unstructured finite element mesh of the fixed grid representation, smoothing interfaces. This might involve first filtering the fixed grid representation, then calling a mesh generator.
|
|
64
|
+
3. Setup input files for the physics codes describing the problem physics and boundary conditions.
|
|
65
|
+
4. Actually run the physics code. This might require multiple calls, for example if we're interested in properties in different loading directions.
|
|
66
|
+
5. Post process the output from the physics code into a common format. We use an [HDF5 format](https://github.com/applied-material-modeling/compgen/blob/main/doc/data.md).
|
|
67
|
+
|
|
68
|
+
compgen provides a simple API (`runner.run`) for doing all of this based on json input files. You need two input files to invoke the runner:
|
|
69
|
+
1. A problem file defining the steps outlined above -- which structure generator, mesh, physics, solver, etc.
|
|
70
|
+
2. A system file letting compgen know how to run external tools (meshers and physics codes).
|
|
71
|
+
|
|
72
|
+
There are examples of each file type to make up the 2D and 3D demos, described below.
|
|
73
|
+
|
|
74
|
+
## Tests and demos
|
|
75
|
+
|
|
76
|
+
First set environment variables:
|
|
77
|
+
1. `MOOSE_DIR` to the root directory of your moose installation
|
|
78
|
+
2. `CUBIT_DIR` to the root directory of your CUBIT directory, if you want to run the demos using sculpt. This is not necessary for the verification tests.
|
|
79
|
+
|
|
80
|
+
## Run the tests
|
|
81
|
+
|
|
82
|
+
Run the tests with `pytest`. The general tests in the `tests` directory do not require MOOSE and are quick and cheap to run. The verification tests in `tests/verification` are more expensive and require MOOSE.
|
|
83
|
+
|
|
84
|
+
## Run the demos
|
|
85
|
+
|
|
86
|
+
There are complete demos that generate random structures, call MOOSE to solve for some material properties, and store the results. These demos live in `demos/complete`. The subdirectories first split
|
|
87
|
+
the problems into different physics/types of material properties and then into 2D and 3D examples.
|
|
88
|
+
|
|
89
|
+
## License headers
|
|
90
|
+
|
|
91
|
+
Every source file (`*.py` and the MOOSE `*.i` templates) must start with the contents of `LICENSE` as a comment header. CI enforces this.
|
|
92
|
+
|
|
93
|
+
- `python scripts/add_license.py` adds the header to any tracked source file that is missing it (or pass specific files as arguments).
|
|
94
|
+
- `python scripts/check_license.py` reports files missing the header and exits non-zero if there are any.
|
|
95
|
+
|
|
96
|
+
## Pre-commit hooks
|
|
97
|
+
|
|
98
|
+
The license check, black, and pylint run as [pre-commit](https://pre-commit.com) hooks on the files staged for each commit. To enable them, install the dev dependencies and then install the hooks once per clone:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
pip install -e .[dev]
|
|
102
|
+
pre-commit install
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
To run the hooks by hand against every file, use `pre-commit run --all-files`.
|
compgen-0.1.0/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# compgen
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
compgen is a Python toolkit for generating simulation data for two phase composite materials. It will generate structures, invoke physics codes to simulate the response for a variety of material properties, and write summaries of the results.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
compgen requires Python 3.13 or newer.
|
|
8
|
+
|
|
9
|
+
1. (Optional) Create and activate a virtual environment.
|
|
10
|
+
2. Install the package:
|
|
11
|
+
- `pip install compgen`
|
|
12
|
+
- To use the reconstruction generator, `pip install compgen[mcrpy]`. mcrpy depends on TensorFlow, which currently supports Python up to 3.13, so use Python 3.13 for this option.
|
|
13
|
+
- To develop compgen, or to run the tests and demos, clone this repository and run `pip install -e .[dev,demos]` from its root.
|
|
14
|
+
3. Install the mesher and physics codes you want to use:
|
|
15
|
+
1. [MOOSE](https://mooseframework.inl.gov/)
|
|
16
|
+
2. [SCULPT](https://www.sandia.gov/files/cubit/documents/SculptSANDReport.pdf)
|
|
17
|
+
|
|
18
|
+
## Inputs
|
|
19
|
+
|
|
20
|
+
compgen pipes together several steps to generate results:
|
|
21
|
+
1. Generate a composite structure -- the distribution of two materials A and B over a periodic domain. We use pixelated fixed grids to define this distribution.
|
|
22
|
+
2. Make an unstructured finite element mesh of the fixed grid representation, smoothing interfaces. This might involve first filtering the fixed grid representation, then calling a mesh generator.
|
|
23
|
+
3. Setup input files for the physics codes describing the problem physics and boundary conditions.
|
|
24
|
+
4. Actually run the physics code. This might require multiple calls, for example if we're interested in properties in different loading directions.
|
|
25
|
+
5. Post process the output from the physics code into a common format. We use an [HDF5 format](https://github.com/applied-material-modeling/compgen/blob/main/doc/data.md).
|
|
26
|
+
|
|
27
|
+
compgen provides a simple API (`runner.run`) for doing all of this based on json input files. You need two input files to invoke the runner:
|
|
28
|
+
1. A problem file defining the steps outlined above -- which structure generator, mesh, physics, solver, etc.
|
|
29
|
+
2. A system file letting compgen know how to run external tools (meshers and physics codes).
|
|
30
|
+
|
|
31
|
+
There are examples of each file type to make up the 2D and 3D demos, described below.
|
|
32
|
+
|
|
33
|
+
## Tests and demos
|
|
34
|
+
|
|
35
|
+
First set environment variables:
|
|
36
|
+
1. `MOOSE_DIR` to the root directory of your moose installation
|
|
37
|
+
2. `CUBIT_DIR` to the root directory of your CUBIT directory, if you want to run the demos using sculpt. This is not necessary for the verification tests.
|
|
38
|
+
|
|
39
|
+
## Run the tests
|
|
40
|
+
|
|
41
|
+
Run the tests with `pytest`. The general tests in the `tests` directory do not require MOOSE and are quick and cheap to run. The verification tests in `tests/verification` are more expensive and require MOOSE.
|
|
42
|
+
|
|
43
|
+
## Run the demos
|
|
44
|
+
|
|
45
|
+
There are complete demos that generate random structures, call MOOSE to solve for some material properties, and store the results. These demos live in `demos/complete`. The subdirectories first split
|
|
46
|
+
the problems into different physics/types of material properties and then into 2D and 3D examples.
|
|
47
|
+
|
|
48
|
+
## License headers
|
|
49
|
+
|
|
50
|
+
Every source file (`*.py` and the MOOSE `*.i` templates) must start with the contents of `LICENSE` as a comment header. CI enforces this.
|
|
51
|
+
|
|
52
|
+
- `python scripts/add_license.py` adds the header to any tracked source file that is missing it (or pass specific files as arguments).
|
|
53
|
+
- `python scripts/check_license.py` reports files missing the header and exits non-zero if there are any.
|
|
54
|
+
|
|
55
|
+
## Pre-commit hooks
|
|
56
|
+
|
|
57
|
+
The license check, black, and pylint run as [pre-commit](https://pre-commit.com) hooks on the files staged for each commit. To enable them, install the dev dependencies and then install the hooks once per clone:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
pip install -e .[dev]
|
|
61
|
+
pre-commit install
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
To run the hooks by hand against every file, use `pre-commit run --all-files`.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Copyright 2026, UChicago Argonne, LLC
|
|
2
|
+
# All Rights Reserved
|
|
3
|
+
# Software Name: compgen
|
|
4
|
+
# By: Argonne National Laboratory
|
|
5
|
+
# OPEN SOURCE LICENSE (MIT)
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
|
15
|
+
# all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
# THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
"""Top-level package for composite structure generation and simulation workflows."""
|
|
26
|
+
|
|
27
|
+
from importlib.metadata import version
|
|
28
|
+
|
|
29
|
+
__version__ = version("compgen")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright 2026, UChicago Argonne, LLC
|
|
2
|
+
# All Rights Reserved
|
|
3
|
+
# Software Name: compgen
|
|
4
|
+
# By: Argonne National Laboratory
|
|
5
|
+
# OPEN SOURCE LICENSE (MIT)
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
|
15
|
+
# all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
# THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
"""Various helpers for reading Exodus II files."""
|
|
26
|
+
|
|
27
|
+
import numpy as np
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_element_field(exo, field):
|
|
31
|
+
"""Retrieve an element field from an Exodus mesh.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
exo (exodusii.File): Open Exodus file object.
|
|
35
|
+
field (str): Name of the element field to retrieve.
|
|
36
|
+
"""
|
|
37
|
+
var_names = list(exo.get_element_variable_names())
|
|
38
|
+
if field not in var_names:
|
|
39
|
+
raise ValueError(f"Field '{field}' not found in output Exodus file.")
|
|
40
|
+
|
|
41
|
+
return np.concatenate(
|
|
42
|
+
[exo.get_element_variable_values(blk, field) for blk in [1, 2]], axis=-1
|
|
43
|
+
)
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Copyright 2026, UChicago Argonne, LLC
|
|
2
|
+
# All Rights Reserved
|
|
3
|
+
# Software Name: compgen
|
|
4
|
+
# By: Argonne National Laboratory
|
|
5
|
+
# OPEN SOURCE LICENSE (MIT)
|
|
6
|
+
#
|
|
7
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
8
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
9
|
+
# in the Software without restriction, including without limitation the rights
|
|
10
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
12
|
+
# furnished to do so, subject to the following conditions:
|
|
13
|
+
#
|
|
14
|
+
# The above copyright notice and this permission notice shall be included in
|
|
15
|
+
# all copies or substantial portions of the Software.
|
|
16
|
+
#
|
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
18
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
20
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
21
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
22
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
23
|
+
# THE SOFTWARE.
|
|
24
|
+
|
|
25
|
+
"""Image filtering utilities for preprocessing generated microstructures."""
|
|
26
|
+
|
|
27
|
+
import numpy as np
|
|
28
|
+
import skimage
|
|
29
|
+
from compgen import utils
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def mean_filter(img, radius=3, periodic=True):
|
|
33
|
+
"""Apply a mean filter to an image.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
img (np.ndarray): 2D or 3D image.
|
|
37
|
+
radius (int): Radius of disk/ball footprint.
|
|
38
|
+
periodic (bool): If True, use periodic wrapping at the boundaries.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
np.ndarray: Smoothed binary image.
|
|
42
|
+
"""
|
|
43
|
+
ndim = img.ndim
|
|
44
|
+
|
|
45
|
+
if ndim == 3:
|
|
46
|
+
footprint = skimage.morphology.ball(radius)
|
|
47
|
+
elif ndim == 2:
|
|
48
|
+
footprint = skimage.morphology.disk(radius)
|
|
49
|
+
else:
|
|
50
|
+
raise ValueError("mean_filter only supports 2D and 3D images")
|
|
51
|
+
|
|
52
|
+
def smooth(i):
|
|
53
|
+
i_u8 = skimage.util.img_as_ubyte(i.astype(float))
|
|
54
|
+
|
|
55
|
+
if periodic:
|
|
56
|
+
pad_width = [(radius, radius)] * ndim
|
|
57
|
+
i_u8 = np.pad(i_u8, pad_width=pad_width, mode="wrap")
|
|
58
|
+
|
|
59
|
+
out = skimage.filters.rank.mean(i_u8, footprint=footprint)
|
|
60
|
+
out = skimage.util.img_as_float(out)
|
|
61
|
+
|
|
62
|
+
if periodic:
|
|
63
|
+
slices = tuple(slice(radius, -radius) for _ in range(ndim))
|
|
64
|
+
out = out[slices]
|
|
65
|
+
|
|
66
|
+
return out
|
|
67
|
+
|
|
68
|
+
return utils.binary_smoother(img, smooth)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def make_orthogonal(img):
|
|
72
|
+
"""Mirror and tile the input array to give it orthogonal periodicity.
|
|
73
|
+
|
|
74
|
+
This works for arrays of arbitrary dimensionality by concatenating the
|
|
75
|
+
array with its flipped version along each axis (processing axes from
|
|
76
|
+
last to first).
|
|
77
|
+
"""
|
|
78
|
+
arr = np.asarray(img)
|
|
79
|
+
for axis in reversed(range(arr.ndim)):
|
|
80
|
+
arr = np.concatenate([arr, np.flip(arr, axis=axis)], axis=axis)
|
|
81
|
+
return arr
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def make_periodic(img: np.ndarray, margin: int = 2) -> np.ndarray:
|
|
85
|
+
"""
|
|
86
|
+
Make periodic for Sculpt/MOOSE workflow.
|
|
87
|
+
|
|
88
|
+
Overwrite the first and last `margin` layers of each axis with the layer at
|
|
89
|
+
index `margin`, for 2D or 3D arrays.
|
|
90
|
+
|
|
91
|
+
A value `margin` = 2 seems to work consistently with Sculpt/MOOSE.
|
|
92
|
+
"""
|
|
93
|
+
arr = np.array(img, copy=True)
|
|
94
|
+
|
|
95
|
+
if arr.ndim not in (2, 3):
|
|
96
|
+
raise RuntimeError(f"Expected 2D or 3D array, got {arr.ndim}D")
|
|
97
|
+
|
|
98
|
+
if not isinstance(margin, int) or margin < 1:
|
|
99
|
+
raise ValueError(f"margin must be a positive integer, got {margin}")
|
|
100
|
+
|
|
101
|
+
if any(2 * margin >= s for s in arr.shape):
|
|
102
|
+
raise ValueError(f"margin={margin} is too large for shape {arr.shape}")
|
|
103
|
+
|
|
104
|
+
# Loop over each axis
|
|
105
|
+
for ax in range(arr.ndim):
|
|
106
|
+
# Slice selecting the master layer at index = margin
|
|
107
|
+
master = [slice(None)] * arr.ndim
|
|
108
|
+
master[ax] = slice(margin, margin + 1)
|
|
109
|
+
|
|
110
|
+
# Slice for lower and upper boundary block
|
|
111
|
+
lo = [slice(None)] * arr.ndim
|
|
112
|
+
lo[ax] = slice(0, margin)
|
|
113
|
+
hi = [slice(None)] * arr.ndim
|
|
114
|
+
hi[ax] = slice(-margin, None)
|
|
115
|
+
|
|
116
|
+
# Overwrite both boundary blocks using the master layer
|
|
117
|
+
arr[tuple(lo)] = arr[tuple(master)]
|
|
118
|
+
arr[tuple(hi)] = arr[tuple(master)]
|
|
119
|
+
|
|
120
|
+
return arr
|