PyCosmoMMF 0.6.0__tar.gz → 1.0.2__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.
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/PKG-INFO +2 -1
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/README.md +1 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/basic_usage.md +16 -19
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/pyproject.toml +1 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/_version.py +9 -4
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/filter.py +59 -74
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/hessian.py +11 -13
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/signatures.py +33 -34
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/tagging.py +94 -64
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/utils.py +40 -6
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/tests/test_integration.py +21 -7
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.copier-answers.yml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.git_archival.txt +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.gitattributes +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.github/CONTRIBUTING.md +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.github/dependabot.yml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.github/release.yml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.github/workflows/cd.yml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.github/workflows/ci.yml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.gitignore +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.pre-commit-config.yaml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/.readthedocs.yaml +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/LICENSE +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/CosmoMMF_Dark.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/CosmoMMF_light.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/basic.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/check-solid.svg +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/clipboard.min.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/copy-button.svg +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/copybutton.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/copybutton.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/copybutton_funcs.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/debug.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/doctools.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/documentation_options.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/file.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/language_data.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/minus.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/plus.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/pygments.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/scripts/furo-extensions.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/scripts/furo.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/scripts/furo.js.LICENSE.txt +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/scripts/furo.js.map +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/searchtools.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/skeleton.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/sphinx_highlight.js +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/styles/furo-extensions.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/styles/furo-extensions.css.map +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/styles/furo.css +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/_static/styles/furo.css.map +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/api/pycosmommf.rst +6 -6
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/api_tab.md +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/conf.py +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/CosmoMMF_Dark.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/CosmoMMF_light.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/final_NEXUSPLUS_Signatures_hydro.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/final_NEXUSPLUS_Signatures_hydro_dark.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/final_tagging_figure.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/images/final_tagging_figure_dark.png +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/docs/index.md +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/noxfile.py +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/__init__.py +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/_version.pyi +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/src/pycosmommf/py.typed +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/tests/__init__.py +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/tests/test_package.py +0 -0
- {pycosmommf-0.6.0 → pycosmommf-1.0.2}/tests/test_unit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pycosmommf
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.2
|
|
4
4
|
Summary: A package for identifying structures in the cosmic web.
|
|
5
5
|
Project-URL: Homepage, https://github.com/James11222/pycosmommf
|
|
6
6
|
Project-URL: Bug Tracker, https://github.com/James11222/pycosmommf/issues
|
|
@@ -64,6 +64,7 @@ Description-Content-Type: text/markdown
|
|
|
64
64
|
|
|
65
65
|
[![Actions Status][actions-badge]][actions-link]
|
|
66
66
|
[![Documentation Status][rtd-badge]][rtd-link]
|
|
67
|
+
[](https://doi.org/10.5281/zenodo.14876495)
|
|
67
68
|
|
|
68
69
|
[](https://codecov.io/gh/James11222/PyCosmoMMF)
|
|
69
70
|
[![PyPI version][pypi-version]][pypi-link]
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[![Actions Status][actions-badge]][actions-link]
|
|
4
4
|
[![Documentation Status][rtd-badge]][rtd-link]
|
|
5
|
+
[](https://doi.org/10.5281/zenodo.14876495)
|
|
5
6
|
|
|
6
7
|
[](https://codecov.io/gh/James11222/PyCosmoMMF)
|
|
7
8
|
[![PyPI version][pypi-version]][pypi-link]
|
|
@@ -46,7 +46,7 @@ density_field = np.load("path/to/density_field.npy")
|
|
|
46
46
|
Rs = [sqrt(2) ** n for n in range(10)] # smoothing scales
|
|
47
47
|
|
|
48
48
|
max_signatures = PyCosmoMMF.maximum_signature(
|
|
49
|
-
Rs, density_field,
|
|
49
|
+
Rs, density_field, algorithm="NEXUSPLUS"
|
|
50
50
|
) # compute maximum signatures
|
|
51
51
|
```
|
|
52
52
|
|
|
@@ -67,18 +67,13 @@ output of this can be seen below
|
|
|
67
67
|
|
|
68
68
|
We then have the option of running the tagging scheme a few different ways. The
|
|
69
69
|
first important argument in `calc_structure_bools()` besides the `density_field`
|
|
70
|
-
and the `max_signatures` arrays is the `verbose_flag`. When
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
function: `S_fil, dM2_fil, S_wall, dM2_wall` which can be used to make the mass
|
|
79
|
-
change curves for filaments and
|
|
80
|
-
|
|
81
|
-
walls.
|
|
70
|
+
and the `max_signatures` arrays is the `verbose_flag`. When set to `True` the
|
|
71
|
+
code gives a lot more information and provides a few plots. This is best turned
|
|
72
|
+
on when debugging the code. When `verbose_flag` is turned on there is an
|
|
73
|
+
additional output to the `calc_structure_bools()` function: `summary_data` which
|
|
74
|
+
is a dictionary containing all the relevant extra information one might need. It
|
|
75
|
+
can be used to make the mass change curves for filaments and walls. Consult the
|
|
76
|
+
API Docs tab for a detailed summary of what is inside `summary_data`.
|
|
82
77
|
|
|
83
78
|
**_Verbose Flag On:_**
|
|
84
79
|
|
|
@@ -86,8 +81,8 @@ walls.
|
|
|
86
81
|
verbose_flag = True # or False
|
|
87
82
|
|
|
88
83
|
|
|
89
|
-
clusbool, filbool, wallbool, voidbool,
|
|
90
|
-
|
|
84
|
+
clusbool, filbool, wallbool, voidbool, summary_data = PyCosmoMMF.calc_structure_bools(
|
|
85
|
+
density_field, max_signatures, verbose_flag
|
|
91
86
|
) # tag structures
|
|
92
87
|
```
|
|
93
88
|
|
|
@@ -125,11 +120,13 @@ clusbool, filbool, wallbool, voidbool = PyCosmoMMF.calc_structure_bools(
|
|
|
125
120
|
```
|
|
126
121
|
|
|
127
122
|
Another important optional argument in the `calc_structure_bools()` function is
|
|
128
|
-
|
|
123
|
+
`overdensity_threshold`. The default value is `overdensity_threshold = 370` as
|
|
124
|
+
used in
|
|
129
125
|
[Cautun et al. 2013](https://academic.oup.com/mnras/article/429/2/1286/1038906)
|
|
130
|
-
but other values can be 200 or 500 corresponding to `R_200` or `R_500`.
|
|
131
|
-
the overdensity parameter
|
|
132
|
-
value, they are thought to be
|
|
126
|
+
but other values can be 200 or 500 corresponding to `R_200` or `R_500`.
|
|
127
|
+
`overdensity_threshold` is the overdensity parameter Δ, when clusters achieve an
|
|
128
|
+
average overdensity greater than this value, they are thought to be
|
|
129
|
+
virialized/collapsed.
|
|
133
130
|
|
|
134
131
|
The boolean filters for each structure type produced by `calc_structure_bools()`
|
|
135
132
|
can be used to tag structures within a density field, the results of this can be
|
|
@@ -124,6 +124,7 @@ ignore = [
|
|
|
124
124
|
"PLR09", # Too many <...>
|
|
125
125
|
"PLR2004", # Magic value used in comparison
|
|
126
126
|
"ISC001", # Conflicts with formatter
|
|
127
|
+
"RUF001", # allow usage of `ρ` symbol in docstrings
|
|
127
128
|
]
|
|
128
129
|
isort.required-imports = ["from __future__ import annotations"]
|
|
129
130
|
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
-
# file generated by
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
2
|
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
+
|
|
3
6
|
TYPE_CHECKING = False
|
|
4
7
|
if TYPE_CHECKING:
|
|
5
|
-
from typing import Tuple
|
|
8
|
+
from typing import Tuple
|
|
9
|
+
from typing import Union
|
|
10
|
+
|
|
6
11
|
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
7
12
|
else:
|
|
8
13
|
VERSION_TUPLE = object
|
|
@@ -12,5 +17,5 @@ __version__: str
|
|
|
12
17
|
__version_tuple__: VERSION_TUPLE
|
|
13
18
|
version_tuple: VERSION_TUPLE
|
|
14
19
|
|
|
15
|
-
__version__ = version = '0.
|
|
16
|
-
__version_tuple__ = version_tuple = (
|
|
20
|
+
__version__ = version = '1.0.2'
|
|
21
|
+
__version_tuple__ = version_tuple = (1, 0, 2)
|
|
@@ -8,19 +8,19 @@ jit_compiler = nb.njit(parallel=True, fastmath=True)
|
|
|
8
8
|
|
|
9
9
|
def wavevectors3D(dims, box_size=(2 * np.pi, 2 * np.pi, 2 * np.pi)):
|
|
10
10
|
"""
|
|
11
|
-
Returns the wavevectors for a 3D grid of dimensions
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
Returns the wavevectors for a 3D grid of dimensions ``dims`` and box size ``box_size``.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
dims (:obj:`tuple`):
|
|
15
|
+
The dimensions of the grid ``(nx, ny, nz)``.
|
|
16
|
+
box_size (:obj:`tuple`, optional):
|
|
17
|
+
The size of the box in each dimension ``(Lx, Ly, Lz)``. Defaults to ``(2π, 2π, 2π)``.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
(tuple): a tuple containing:
|
|
21
|
+
- **kx** (:obj:`np.ndarray`): The wavevector in the x-direction.
|
|
22
|
+
- **ky** (:obj:`np.ndarray`): The wavevector in the y-direction.
|
|
23
|
+
- **kz** (:obj:`np.ndarray`): The wavevector in the z-direction.
|
|
24
24
|
"""
|
|
25
25
|
sample_rate = 2 * np.pi * (np.array(dims) / box_size)
|
|
26
26
|
kx = (np.fft.fftfreq(dims[0], 1 / sample_rate[0]) * (2 * np.pi / dims[0])).astype(
|
|
@@ -40,17 +40,14 @@ def kspace_gaussian_filter(R_S, kv): # pragma: no cover
|
|
|
40
40
|
"""
|
|
41
41
|
create a Gaussian filter in k-space.
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-------
|
|
52
|
-
filter_k : array
|
|
53
|
-
The filter in k-space.
|
|
43
|
+
Args:
|
|
44
|
+
R_S (:obj:`float`):
|
|
45
|
+
The smoothing scale.
|
|
46
|
+
kv (:obj:`tuple`):
|
|
47
|
+
The wavevectors in each dimension, each a ``1D float np.ndarray``.
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
(:obj:`3D float np.ndarray`): The filter in k-space.
|
|
54
51
|
"""
|
|
55
52
|
kx, ky, kz = kv
|
|
56
53
|
nx, ny, nz = len(kx), len(ky), len(kz)
|
|
@@ -69,17 +66,14 @@ def kspace_top_hat_filter(R_S, kv): # pragma: no cover
|
|
|
69
66
|
"""
|
|
70
67
|
create a top-hat filter in k-space.
|
|
71
68
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-------
|
|
81
|
-
filter_k : array
|
|
82
|
-
The filter in k-space.
|
|
69
|
+
Args:
|
|
70
|
+
R_S (:obj:`float`):
|
|
71
|
+
The smoothing scale.
|
|
72
|
+
kv (:obj:`tuple`):
|
|
73
|
+
The wavevectors in each dimension.
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
(:obj:`3D float np.ndarray`): The filter in k-space.
|
|
83
77
|
"""
|
|
84
78
|
|
|
85
79
|
kx, ky, kz = kv
|
|
@@ -106,19 +100,16 @@ def smooth_top_hat(f, R_S, kv):
|
|
|
106
100
|
"""
|
|
107
101
|
apply a top-hat filter to a field f.
|
|
108
102
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
-------
|
|
120
|
-
f_Rn : array
|
|
121
|
-
The smoothed field.
|
|
103
|
+
Args:
|
|
104
|
+
f (:obj:`3D float np.ndarray`):
|
|
105
|
+
The field to be smoothed.
|
|
106
|
+
R_S (:obj:`float`):
|
|
107
|
+
The smoothing scale in units of voxels.
|
|
108
|
+
kv (:obj:`tuple`):
|
|
109
|
+
The wavevectors in each dimension.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
(:obj:`3D float np.ndarray`): The smoothed field.
|
|
122
113
|
"""
|
|
123
114
|
GF = kspace_top_hat_filter(R_S, kv)
|
|
124
115
|
f_Rn = np.real(np.fft.ifftn(GF * np.fft.fftn(f)))
|
|
@@ -130,19 +121,16 @@ def smooth_gauss(f, R_S, kv):
|
|
|
130
121
|
"""
|
|
131
122
|
apply a Gaussian filter to a field f.
|
|
132
123
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
-------
|
|
144
|
-
f_Rn : array
|
|
145
|
-
The smoothed field.
|
|
124
|
+
Args:
|
|
125
|
+
f (:obj:`3D float np.ndarray`):
|
|
126
|
+
The field to be smoothed.
|
|
127
|
+
R_S (:obj:`float`):
|
|
128
|
+
The smoothing scale in units of voxels.
|
|
129
|
+
kv (:obj:`tuple`):
|
|
130
|
+
The wavevectors in each dimension.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
(:obj:`3D float np.ndarray`): The smoothed field.
|
|
146
134
|
"""
|
|
147
135
|
GF = kspace_gaussian_filter(R_S, kv)
|
|
148
136
|
f_Rn = np.real(np.fft.ifftn(GF * np.fft.fftn(f)))
|
|
@@ -154,19 +142,16 @@ def smooth_loggauss(f, R_S, kv):
|
|
|
154
142
|
"""
|
|
155
143
|
apply a Gaussian filter to the log of a field f.
|
|
156
144
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-------
|
|
168
|
-
f_Rn : array
|
|
169
|
-
The smoothed field.
|
|
145
|
+
Args:
|
|
146
|
+
f (:obj:`3D float np.ndarray`):
|
|
147
|
+
The field to be smoothed.
|
|
148
|
+
R_S (:obj:`float`):
|
|
149
|
+
The smoothing scale in units of voxels.
|
|
150
|
+
kv (:obj:`tuple`):
|
|
151
|
+
The wavevectors in each dimension.
|
|
152
|
+
|
|
153
|
+
Returns:
|
|
154
|
+
(:obj:`3D float np.ndarray`): The smoothed field.
|
|
170
155
|
"""
|
|
171
156
|
# Get filter in Fourier space
|
|
172
157
|
GF = kspace_gaussian_filter(R_S, kv)
|
|
@@ -10,19 +10,17 @@ def fast_hessian_from_smoothed(f_Rn, R_S, kv):
|
|
|
10
10
|
"""
|
|
11
11
|
Compute the hessian matrix of the smoothed field f_Rn.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
hessian : 3D array
|
|
25
|
-
The hessian matrix.
|
|
13
|
+
Args:
|
|
14
|
+
f_Rn (:obj:`3D float np.ndarray`):
|
|
15
|
+
The smoothed field in real space.
|
|
16
|
+
R_S (:obj:`float`):
|
|
17
|
+
The smoothing scale in units of voxels.
|
|
18
|
+
kv (:obj:`tuple`):
|
|
19
|
+
The wavevectors in each dimension.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
(:obj:`4D float np.ndarray`): The hessian matrix of the smoothed field.
|
|
23
|
+
The shape is ``(nx, ny, nz, 6)``, where ``nx, ny, nz`` are the dimensions of ``f_Rn``.
|
|
26
24
|
"""
|
|
27
25
|
|
|
28
26
|
f_Rn_hat = np.fft.fftn(f_Rn)
|
|
@@ -14,15 +14,15 @@ def signatures_from_hessian(hessian): # pragma: no cover
|
|
|
14
14
|
"""
|
|
15
15
|
Function to calculate the signatures from a given hessian.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
17
|
+
Args:
|
|
18
|
+
hessian (:obj:`4D float np.ndarray`):
|
|
19
|
+
The hessian matrix of the smoothed field, with shape ``(nx, ny, nz, 6)``.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
(:obj:`4D float np.ndarray`): The signatures array with shape ``(nx, ny, nz, 3)``. Each signature corresponds to a different type of structure:
|
|
23
|
+
- ``sigs[..., 0]``: Cluster signature
|
|
24
|
+
- ``sigs[..., 1]``: Filament signature
|
|
25
|
+
- ``sigs[..., 2]``: Wall signature
|
|
26
26
|
"""
|
|
27
27
|
|
|
28
28
|
hsize = hessian.shape[:3]
|
|
@@ -78,35 +78,34 @@ def signatures_from_hessian(hessian): # pragma: no cover
|
|
|
78
78
|
return sigs
|
|
79
79
|
|
|
80
80
|
|
|
81
|
-
def maximum_signature(Rs,
|
|
81
|
+
def maximum_signature(Rs, density_cube, algorithm="NEXUSPLUS", eps=1e-8):
|
|
82
82
|
"""
|
|
83
83
|
Compute the maximum signatures across all scales Rs.
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
sigmax : 4D array
|
|
100
|
-
The maximum signatures.
|
|
85
|
+
Args:
|
|
86
|
+
Rs (:obj:`list` of :obj:`float`):
|
|
87
|
+
List of smoothing scales in units of voxels.
|
|
88
|
+
density_cube (:obj:`3D float np.ndarray`):
|
|
89
|
+
The 3D density field to analyze.
|
|
90
|
+
algorithm (:obj:`str`, optional):
|
|
91
|
+
The algorithm to use for smoothing. Can be either "NEXUS" or "NEXUSPLUS". Defaults to "NEXUSPLUS".
|
|
92
|
+
eps (:obj:`float`, optional):
|
|
93
|
+
Small value to avoid division by zero. Defaults to ``1e-8``.
|
|
94
|
+
|
|
95
|
+
Returns:
|
|
96
|
+
(:obj:`4D float np.ndarray`):
|
|
97
|
+
An array of signatures with shape ``(nx, ny, nz, 3)``, where ``nx, ny, nz`` are the dimensions of the input ``density_cube``.
|
|
98
|
+
The last dimension contains the signatures for clusters, filaments, and walls respectively.
|
|
101
99
|
"""
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
|
|
101
|
+
if algorithm not in ["NEXUS", "NEXUSPLUS"]: # pragma: no cover
|
|
102
|
+
msg = "algorithm must be either 'NEXUS' or 'NEXUSPLUS'"
|
|
104
103
|
raise ValueError(msg)
|
|
105
104
|
|
|
106
|
-
nx, ny, nz =
|
|
105
|
+
nx, ny, nz = density_cube.shape
|
|
107
106
|
|
|
108
107
|
# Make sure the field has no 0 values
|
|
109
|
-
|
|
108
|
+
density_cube = density_cube + eps
|
|
110
109
|
|
|
111
110
|
# Calculate wave vectors for our field
|
|
112
111
|
wave_vecs = wavevectors3D((nx, ny, nz))
|
|
@@ -125,10 +124,10 @@ def maximum_signature(Rs, field, alg="NEXUSPLUS", eps=1e-8):
|
|
|
125
124
|
)
|
|
126
125
|
|
|
127
126
|
for R in Rs:
|
|
128
|
-
if
|
|
129
|
-
f_Rn = smooth_gauss(
|
|
130
|
-
elif
|
|
131
|
-
f_Rn = smooth_loggauss(
|
|
127
|
+
if algorithm == "NEXUS":
|
|
128
|
+
f_Rn = smooth_gauss(density_cube, R, wave_vecs)
|
|
129
|
+
elif algorithm == "NEXUSPLUS":
|
|
130
|
+
f_Rn = smooth_loggauss(density_cube, R, wave_vecs)
|
|
132
131
|
|
|
133
132
|
H_Rn = fast_hessian_from_smoothed(f_Rn, R, wave_vecs)
|
|
134
133
|
|
|
@@ -7,30 +7,30 @@ import skimage.measure
|
|
|
7
7
|
jit_compiler = nb.njit(parallel=True, fastmath=True)
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def make_the_clusbool(delta, max_sigs,
|
|
10
|
+
def make_the_clusbool(delta, max_sigs, overdensity_threshold): # pragma: no cover
|
|
11
11
|
"""
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
A function that creates a Boolean Filter which selects only
|
|
12
|
+
A function that creates a bool Filter which selects only
|
|
15
13
|
the clusters in a given cosmological δ field. This function accomplishes
|
|
16
14
|
this by finding a threshold value for 𝒮_cluster by looking at the
|
|
17
15
|
change in virialization fraction as a function of 𝒮_cluster.
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
17
|
+
Args:
|
|
18
|
+
delta (:obj:`3D float np.ndarray`):
|
|
19
|
+
delta refers to the (δ = ρ / <ρ> - 1) field, this is NOT the (δ + 1 = ρ / <ρ>) field.
|
|
20
|
+
max_sigs (:obj:`4D float np.ndarray`):
|
|
21
|
+
the maximum signatures array from the ``maximum_signature()`` function.
|
|
22
|
+
verbose_flag (:obj:`bool`):
|
|
23
|
+
a flag to allow the function to be more helpful and verbose.
|
|
24
|
+
overdensity_threshold (:obj:`float`):
|
|
25
|
+
The overdensity parameter threshold for determining virialization. Commonly used values
|
|
26
|
+
that are physically motivated can be 370, 200, or 500.
|
|
27
27
|
|
|
28
28
|
Returns:
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
(tuple): a tuple containing:
|
|
30
|
+
- **clusbool** (:obj:`3D bool np.ndarray`): a boolean filter that selects only the clusters in a given cosmological δ field.
|
|
31
|
+
- **S_th** (:obj:`float`): the threshold value for 𝒮_cluster.
|
|
32
|
+
- **signature_thresholds** (:obj:`1D float np.ndarray`): an array of threshold values for 𝒮_cluster.
|
|
33
|
+
- **virialized_fractions** (:obj:`1D float np.ndarray`): an array of virialized fractions as a function of 𝒮_cluster.
|
|
34
34
|
"""
|
|
35
35
|
|
|
36
36
|
signature_thresholds = np.geomspace(0.1, 30, 10) # hard coded for now
|
|
@@ -65,9 +65,9 @@ def make_the_clusbool(delta, max_sigs, Δ): # pragma: no cover
|
|
|
65
65
|
) # an array where 0 is background and 1, 2, 3, ... are the clumps
|
|
66
66
|
averaged_overdensity_per_clump = calc_virialized_fraction(clumps)
|
|
67
67
|
|
|
68
|
-
virialized_fractions[i] = np.sum(
|
|
69
|
-
|
|
70
|
-
)
|
|
68
|
+
virialized_fractions[i] = np.sum(
|
|
69
|
+
averaged_overdensity_per_clump > overdensity_threshold
|
|
70
|
+
) / np.max(clumps)
|
|
71
71
|
|
|
72
72
|
S_th = signature_thresholds[np.abs(virialized_fractions - 0.5).argmin()]
|
|
73
73
|
clusbool = max_sigs[:, :, :, 0] > S_th
|
|
@@ -79,17 +79,20 @@ def calc_mass_change(sig_vec, density_vec, Smin, Smax):
|
|
|
79
79
|
"""
|
|
80
80
|
Calculate the mass change curve for a given structure type.
|
|
81
81
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
density_vec
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
Args:
|
|
83
|
+
sig_vec (:obj:`1D float np.ndarray`):
|
|
84
|
+
the signature values for a given structure type
|
|
85
|
+
density_vec (:obj:`1D float np.ndarray`):
|
|
86
|
+
the density values for a given structure type
|
|
87
|
+
Smin (:obj:`float`):
|
|
88
|
+
the minimum signature value
|
|
89
|
+
Smax (:obj:`float`):
|
|
90
|
+
the maximum signature value
|
|
88
91
|
|
|
89
92
|
Returns:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
+
(tuple): a tuple containing:
|
|
94
|
+
- **S** (:obj:`1D float np.ndarray`): the signature values
|
|
95
|
+
- **ΔΜ_2** (:obj:`1D float np.ndarray`): the mass change curve
|
|
93
96
|
"""
|
|
94
97
|
# Initialize our arrays
|
|
95
98
|
log10S = np.arange(Smin, Smax + 0.1, 0.1)
|
|
@@ -111,48 +114,75 @@ def calc_mass_change(sig_vec, density_vec, Smin, Smax):
|
|
|
111
114
|
|
|
112
115
|
|
|
113
116
|
def calc_structure_bools(
|
|
114
|
-
density_cube,
|
|
117
|
+
density_cube,
|
|
118
|
+
max_sigs,
|
|
119
|
+
verbose_flag,
|
|
120
|
+
clusbool=None,
|
|
121
|
+
Smin=-3,
|
|
122
|
+
Smax=2,
|
|
123
|
+
overdensity_threshold=370,
|
|
115
124
|
):
|
|
116
125
|
"""
|
|
117
126
|
Calculate the boolean filters for clusters, filaments, walls, and voids.
|
|
118
127
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
max_sigs
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
Args:
|
|
129
|
+
density_cube (:obj:`3D float np.ndarray`):
|
|
130
|
+
the (δ+1 = ρ/<ρ>) ``density_cube``, this is NOT (δ = ρ/<ρ> - 1).
|
|
131
|
+
max_sigs (:obj:`4D float np.ndarray`):
|
|
132
|
+
the maximum signatures array from CosmoMMF.maximum_signature()
|
|
133
|
+
verbose_flag (:obj:`bool`) :
|
|
134
|
+
a flag to allow the function to be more helpful and verbose.
|
|
135
|
+
clusbool (:obj:`bool np.ndarray`, optional):
|
|
136
|
+
the cluster boolean filter
|
|
137
|
+
Smin (:obj:`float`, optional):
|
|
138
|
+
the minimum signature value
|
|
139
|
+
Smax (:obj:`float`, optional):
|
|
140
|
+
the maximum signature value
|
|
141
|
+
overdensity_threshold (:obj:`int`, optional):
|
|
142
|
+
the overdensity parameter threshold for determining virialization
|
|
128
143
|
|
|
129
144
|
Returns:
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
(tuple): a tuple containing:
|
|
146
|
+
- **clusbool** (:obj:`3D bool np.ndarray`): the cluster boolean filter
|
|
147
|
+
- **filbool** (:obj:`3D bool np.ndarray`): the filament boolean filter
|
|
148
|
+
- **wallbool** (:obj:`3D bool np.ndarray`): the wall boolean filter
|
|
149
|
+
- **voidbool** (:obj:`3D bool np.ndarray`): the void boolean filter
|
|
150
|
+
- **summary_data** (:obj:`dict`): a dictionary returned only when ``verbose_flag = True``, it contains the following keys:
|
|
151
|
+
- **S_clus** (:obj:`1D float np.ndarray`): the signature values for clusters
|
|
152
|
+
- **f_vir_clus** (:obj:`1D float np.ndarray`): the virialization fraction for clusters
|
|
153
|
+
- **S_fil** (:obj:`1D float np.ndarray`): the signature values for filaments
|
|
154
|
+
- **dM2_fil** (:obj:`1D float np.ndarray`): the mass change curve for filaments
|
|
155
|
+
- **S_fil_thresh** (:obj:`float`): the threshold value for filaments
|
|
156
|
+
- **S_wall** (:obj:`1D float np.ndarray`): the signature values for walls
|
|
157
|
+
- **dM2_wall** (:obj:`1D float np.ndarray`): the mass change curve for walls
|
|
158
|
+
- **S_wall_thresh** (:obj:`float`): the threshold value for walls
|
|
159
|
+
- **mass_fractions** (:obj:`1D float np.ndarray`): a list of mass fractions for clusters, filaments, walls, and voids
|
|
160
|
+
- **volume_fractions** (:obj:`1D float np.ndarray`): a list of volume fractions for clusters, filaments, walls, and voids
|
|
145
161
|
"""
|
|
146
162
|
|
|
147
163
|
N_cells = np.prod(density_cube.shape)
|
|
148
164
|
|
|
165
|
+
# Check if the input density_cube is actually δ
|
|
166
|
+
if np.isclose(np.abs(np.mean(density_cube)), 0, atol=1e-3):
|
|
167
|
+
msg = "make sure that you are not inputing the overdensity field δ = ρ/<ρ> - 1, but rather δ + 1 = ρ/<ρ>."
|
|
168
|
+
raise ValueError(msg)
|
|
169
|
+
|
|
170
|
+
# # Check if the input density_cube is actually δ + 1 = ρ/<ρ> or just ρ
|
|
171
|
+
# if np.mean(density_cube) != 1.0:
|
|
172
|
+
# # If the mean is greater than 1, we assume it is simply ρ, but we want to transform to δ + 1 = ρ/<ρ>
|
|
173
|
+
# if verbose_flag: # pragma: no cover
|
|
174
|
+
# print(
|
|
175
|
+
# "Input density_cube is in density units, transforming to δ + 1 = ρ/<ρ>."
|
|
176
|
+
# )
|
|
177
|
+
# density_cube /= np.mean(density_cube) # normalize to mean = 1
|
|
178
|
+
|
|
149
179
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
150
|
-
# Step 1. Create Cluster
|
|
180
|
+
# Step 1. Create Cluster bool Filter
|
|
151
181
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
152
182
|
|
|
153
183
|
if clusbool is None: # pragma: no cover
|
|
154
184
|
clusbool, cluster_thresh, S_clus, f_vir_clus = make_the_clusbool(
|
|
155
|
-
density_cube - 1.0, max_sigs,
|
|
185
|
+
density_cube - 1.0, max_sigs, overdensity_threshold
|
|
156
186
|
)
|
|
157
187
|
else:
|
|
158
188
|
cluster_thresh = None
|
|
@@ -160,7 +190,7 @@ def calc_structure_bools(
|
|
|
160
190
|
f_vir_clus = None
|
|
161
191
|
|
|
162
192
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
163
|
-
# Step 2. Create Filament
|
|
193
|
+
# Step 2. Create Filament bool Filter
|
|
164
194
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
165
195
|
|
|
166
196
|
# we create 3 N^3 arrays with the signature corresponding to each structure
|
|
@@ -181,7 +211,7 @@ def calc_structure_bools(
|
|
|
181
211
|
filbool = (max_sigs[:, :, :, 1] > filament_thresh) & (~clusbool)
|
|
182
212
|
|
|
183
213
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
184
|
-
# Step 3. Create Wall
|
|
214
|
+
# Step 3. Create Wall bool Filter
|
|
185
215
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
186
216
|
|
|
187
217
|
# Isolate Valid Walls (not clusters or filaments)
|
|
@@ -196,14 +226,14 @@ def calc_structure_bools(
|
|
|
196
226
|
wallbool = (max_sigs[:, :, :, 2] > wall_thresh) & ~(filbool | clusbool)
|
|
197
227
|
|
|
198
228
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
199
|
-
# Step 4. Create Void
|
|
229
|
+
# Step 4. Create Void bool Filter
|
|
200
230
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
201
231
|
|
|
202
232
|
voidbool = (clusbool + filbool + wallbool) == 0
|
|
203
233
|
|
|
204
|
-
if
|
|
234
|
+
if verbose_flag:
|
|
205
235
|
print("---------------------------------------")
|
|
206
|
-
print(" Cluster
|
|
236
|
+
print(" Cluster bool Filter Report ")
|
|
207
237
|
print("---------------------------------------\n")
|
|
208
238
|
|
|
209
239
|
volume_fraction_clus = np.sum(clusbool) / N_cells
|
|
@@ -215,7 +245,7 @@ def calc_structure_bools(
|
|
|
215
245
|
print("")
|
|
216
246
|
|
|
217
247
|
print("---------------------------------------")
|
|
218
|
-
print(" Filament
|
|
248
|
+
print(" Filament bool Filter Report ")
|
|
219
249
|
print("---------------------------------------\n")
|
|
220
250
|
|
|
221
251
|
volume_fraction_fil = np.sum(filbool) / N_cells
|
|
@@ -227,7 +257,7 @@ def calc_structure_bools(
|
|
|
227
257
|
print("")
|
|
228
258
|
|
|
229
259
|
print("---------------------------------------")
|
|
230
|
-
print(" Wall
|
|
260
|
+
print(" Wall bool Filter Report ")
|
|
231
261
|
print("---------------------------------------\n")
|
|
232
262
|
|
|
233
263
|
volume_fraction_wall = np.sum(wallbool) / N_cells
|
|
@@ -239,7 +269,7 @@ def calc_structure_bools(
|
|
|
239
269
|
print("")
|
|
240
270
|
|
|
241
271
|
print("---------------------------------------")
|
|
242
|
-
print(" Void
|
|
272
|
+
print(" Void bool Filter Report ")
|
|
243
273
|
print("---------------------------------------\n")
|
|
244
274
|
|
|
245
275
|
volume_fraction_void = np.sum(voidbool) / N_cells
|
|
@@ -6,6 +6,15 @@ import numpy as np
|
|
|
6
6
|
def shrink(data, new_size):
|
|
7
7
|
"""
|
|
8
8
|
A simple function to shrink a 3D array by summing over blocks of new_size.
|
|
9
|
+
|
|
10
|
+
Args:
|
|
11
|
+
data (:obj:`3D float np.ndarray`):
|
|
12
|
+
The input 3D array to be shrunk.
|
|
13
|
+
new_size (:obj:`int`):
|
|
14
|
+
The new size for each dimension after shrinking.
|
|
15
|
+
|
|
16
|
+
Returns:
|
|
17
|
+
(:obj:`3D float np.ndarray`): The shrunk 3D array.
|
|
9
18
|
"""
|
|
10
19
|
xs = new_size
|
|
11
20
|
ys = new_size
|
|
@@ -23,20 +32,36 @@ def shrink(data, new_size):
|
|
|
23
32
|
def wall(n):
|
|
24
33
|
"""
|
|
25
34
|
Builds a wall out of an nxnxn array. All values in the wall
|
|
26
|
-
are set to
|
|
35
|
+
are set to 10. Other points are set to 0.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
n (:obj:`int`):
|
|
39
|
+
The size of the 3D array to create.
|
|
40
|
+
|
|
41
|
+
Returns:
|
|
42
|
+
(:obj:`3D float np.ndarray`): An nxnxn array with a wall in the center.
|
|
27
43
|
"""
|
|
28
44
|
array = np.zeros((n, n, n))
|
|
29
45
|
array[:, :, :] = 0.1
|
|
30
46
|
index = n // 2
|
|
31
|
-
array[index, :, :] =
|
|
47
|
+
array[index, :, :] = 10.0
|
|
32
48
|
return array
|
|
33
49
|
|
|
34
50
|
|
|
35
51
|
def cylinder(n, r):
|
|
36
52
|
"""
|
|
37
53
|
Returns an nxnxn array with a cylinder in the center with
|
|
38
|
-
radius r. All points within the radius are set to
|
|
54
|
+
radius r. All points within the radius are set to 10, the rest
|
|
39
55
|
are set to 0.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
n (:obj:`int`):
|
|
59
|
+
The size of the 3D array to create.
|
|
60
|
+
r (:obj:`int`):
|
|
61
|
+
The radius of the cylinder.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
(:obj:`3D float np.ndarray`): An nxnxn array with a cylinder in the center.
|
|
40
65
|
"""
|
|
41
66
|
array = np.zeros((n, n, n), dtype=np.float64)
|
|
42
67
|
array[:, :, :] = 0.1
|
|
@@ -44,15 +69,24 @@ def cylinder(n, r):
|
|
|
44
69
|
for y in range(n):
|
|
45
70
|
for z in range(n):
|
|
46
71
|
if (x - (n // 2)) ** 2 + (y - (n // 2)) ** 2 < r**2:
|
|
47
|
-
array[x, y, z] =
|
|
72
|
+
array[x, y, z] = 10.0
|
|
48
73
|
return array
|
|
49
74
|
|
|
50
75
|
|
|
51
76
|
def sphere(n, r):
|
|
52
77
|
"""
|
|
53
78
|
Returns an nxnxn array with a sphere in the center with
|
|
54
|
-
radius r. All points within the radius are set to
|
|
79
|
+
radius r. All points within the radius are set to 10, the rest
|
|
55
80
|
are set to 0.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
n (:obj:`int`):
|
|
84
|
+
The size of the 3D array to create.
|
|
85
|
+
r (:obj:`int`):
|
|
86
|
+
The radius of the sphere.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
(:obj:`3D float np.ndarray`): An nxnxn array with a sphere in the center.
|
|
56
90
|
"""
|
|
57
91
|
array = np.zeros((n, n, n), dtype=np.float64)
|
|
58
92
|
array[:, :, :] = 0.1
|
|
@@ -62,5 +96,5 @@ def sphere(n, r):
|
|
|
62
96
|
if (x - (n // 2)) ** 2 + (y - (n // 2)) ** 2 + (
|
|
63
97
|
z - (n // 2)
|
|
64
98
|
) ** 2 < r**2:
|
|
65
|
-
array[x, y, z] =
|
|
99
|
+
array[x, y, z] = 10.0
|
|
66
100
|
return array
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
|
+
import pytest
|
|
4
5
|
|
|
5
6
|
import pycosmommf as m
|
|
6
7
|
|
|
@@ -15,28 +16,28 @@ test_field = (
|
|
|
15
16
|
def test_maximum_signature():
|
|
16
17
|
Rs = [np.sqrt(2) ** n for n in range(5)]
|
|
17
18
|
field = test_field
|
|
18
|
-
sigs = m.maximum_signature(Rs, field,
|
|
19
|
+
sigs = m.maximum_signature(Rs, field, algorithm="NEXUSPLUS")
|
|
19
20
|
assert sigs.shape == (32, 32, 32, 3)
|
|
20
21
|
|
|
21
|
-
sigs = m.maximum_signature(Rs, field,
|
|
22
|
+
sigs = m.maximum_signature(Rs, field, algorithm="NEXUS")
|
|
22
23
|
assert sigs.shape == (32, 32, 32, 3)
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def test_calc_structure_bools():
|
|
26
27
|
Rs = [np.sqrt(2) ** n for n in range(5)]
|
|
27
28
|
field = test_field
|
|
28
|
-
sigs = m.maximum_signature(Rs, field,
|
|
29
|
+
sigs = m.maximum_signature(Rs, field, algorithm="NEXUS")
|
|
29
30
|
clusbool = (
|
|
30
31
|
np.roll(m.sphere(32, 2), -10, axis=0) + np.roll(m.sphere(32, 2), 10, axis=0)
|
|
31
32
|
) >= 1
|
|
32
33
|
clusbool, filbool, wallbool, voidbool, summary_stats = m.calc_structure_bools(
|
|
33
34
|
field,
|
|
34
35
|
max_sigs=sigs,
|
|
35
|
-
|
|
36
|
+
verbose_flag=True,
|
|
36
37
|
clusbool=clusbool,
|
|
37
38
|
Smin=-3,
|
|
38
39
|
Smax=2,
|
|
39
|
-
|
|
40
|
+
overdensity_threshold=370,
|
|
40
41
|
)
|
|
41
42
|
assert clusbool.shape == (32, 32, 32)
|
|
42
43
|
assert filbool.shape == (32, 32, 32)
|
|
@@ -47,13 +48,26 @@ def test_calc_structure_bools():
|
|
|
47
48
|
clusbool, filbool, wallbool, voidbool = m.calc_structure_bools(
|
|
48
49
|
field,
|
|
49
50
|
max_sigs=sigs,
|
|
50
|
-
|
|
51
|
+
verbose_flag=False,
|
|
51
52
|
clusbool=clusbool,
|
|
52
53
|
Smin=-3,
|
|
53
54
|
Smax=2,
|
|
54
|
-
|
|
55
|
+
overdensity_threshold=370,
|
|
55
56
|
)
|
|
56
57
|
assert clusbool.shape == (32, 32, 32)
|
|
57
58
|
assert filbool.shape == (32, 32, 32)
|
|
58
59
|
assert wallbool.shape == (32, 32, 32)
|
|
59
60
|
assert voidbool.shape == (32, 32, 32)
|
|
61
|
+
|
|
62
|
+
delta = field / np.mean(field) - 1.0
|
|
63
|
+
|
|
64
|
+
with pytest.raises(ValueError): # noqa: PT011
|
|
65
|
+
clusbool, filbool, wallbool, voidbool = m.calc_structure_bools(
|
|
66
|
+
density_cube=delta,
|
|
67
|
+
max_sigs=sigs,
|
|
68
|
+
verbose_flag=False,
|
|
69
|
+
clusbool=clusbool,
|
|
70
|
+
Smin=-3,
|
|
71
|
+
Smax=2,
|
|
72
|
+
overdensity_threshold=370,
|
|
73
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -3,8 +3,8 @@ pycosmommf package
|
|
|
3
3
|
|
|
4
4
|
.. automodule:: pycosmommf
|
|
5
5
|
:members:
|
|
6
|
-
:undoc-members:
|
|
7
6
|
:show-inheritance:
|
|
7
|
+
:undoc-members:
|
|
8
8
|
|
|
9
9
|
Submodules
|
|
10
10
|
----------
|
|
@@ -14,37 +14,37 @@ pycosmommf.filter module
|
|
|
14
14
|
|
|
15
15
|
.. automodule:: pycosmommf.filter
|
|
16
16
|
:members:
|
|
17
|
-
:undoc-members:
|
|
18
17
|
:show-inheritance:
|
|
18
|
+
:undoc-members:
|
|
19
19
|
|
|
20
20
|
pycosmommf.hessian module
|
|
21
21
|
-------------------------
|
|
22
22
|
|
|
23
23
|
.. automodule:: pycosmommf.hessian
|
|
24
24
|
:members:
|
|
25
|
-
:undoc-members:
|
|
26
25
|
:show-inheritance:
|
|
26
|
+
:undoc-members:
|
|
27
27
|
|
|
28
28
|
pycosmommf.signatures module
|
|
29
29
|
----------------------------
|
|
30
30
|
|
|
31
31
|
.. automodule:: pycosmommf.signatures
|
|
32
32
|
:members:
|
|
33
|
-
:undoc-members:
|
|
34
33
|
:show-inheritance:
|
|
34
|
+
:undoc-members:
|
|
35
35
|
|
|
36
36
|
pycosmommf.tagging module
|
|
37
37
|
-------------------------
|
|
38
38
|
|
|
39
39
|
.. automodule:: pycosmommf.tagging
|
|
40
40
|
:members:
|
|
41
|
-
:undoc-members:
|
|
42
41
|
:show-inheritance:
|
|
42
|
+
:undoc-members:
|
|
43
43
|
|
|
44
44
|
pycosmommf.utils module
|
|
45
45
|
-----------------------
|
|
46
46
|
|
|
47
47
|
.. automodule:: pycosmommf.utils
|
|
48
48
|
:members:
|
|
49
|
-
:undoc-members:
|
|
50
49
|
:show-inheritance:
|
|
50
|
+
:undoc-members:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|