subhaloscript 1.0.4__tar.gz → 1.0.6__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.
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/PKG-INFO +3 -2
- subhaloscript-1.0.6/README.md +11 -0
- subhaloscript-1.0.6/example-notebooks/basic-usage.ipynb +339 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/meta.yaml +1 -1
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/pyproject.toml +1 -1
- subhaloscript-1.0.6/subscript/external.py +87 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/scripts/nfilters.py +1 -1
- subhaloscript-1.0.6/tests/test_symphony.py +167 -0
- subhaloscript-1.0.4/README.md +0 -10
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/.github/workflows/main.yml +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/.gitignore +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/LICENSE +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/defaults.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/macros.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/scripts/histograms.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/scripts/nodes.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/scripts/spatial.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/tabulatehdf5.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/util.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/subscript/wrappers.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_histograms.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_macros.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_nfilters.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_nfilters_legacy.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_nodes.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_spatial.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_tabulatehdf5.py +0 -0
- {subhaloscript-1.0.4 → subhaloscript-1.0.6}/tests/test_wrappers.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: subhaloscript
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
4
4
|
Summary: Utility functions for analyzing subhalo distributions.
|
|
5
5
|
Author-email: Charles Gannon <cgannon@ucmerced.edu>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -15,7 +15,7 @@ Requires-Dist: scipy
|
|
|
15
15
|
Description-Content-Type: text/markdown
|
|
16
16
|
|
|
17
17
|
# SubScript
|
|
18
|
-
|
|
18
|
+
The ```subscript``` python package provides a library of ergonomic utility functions for analyzing Galacticus (https://github.com/galacticusorg/galacticus) subhalo data.
|
|
19
19
|
|
|
20
20
|
## Installation
|
|
21
21
|
|
|
@@ -24,3 +24,4 @@ Utility functions for analyzing subhalo distributions, focusing on the Galacticu
|
|
|
24
24
|
|
|
25
25
|
### Install via conda
|
|
26
26
|
```conda install cgannonucm::subhaloscript```
|
|
27
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# SubScript
|
|
2
|
+
The ```subscript``` python package provides a library of ergonomic utility functions for analyzing Galacticus (https://github.com/galacticusorg/galacticus) subhalo data.
|
|
3
|
+
|
|
4
|
+
## Installation
|
|
5
|
+
|
|
6
|
+
### Install via pip
|
|
7
|
+
```pip install subhaloscript```
|
|
8
|
+
|
|
9
|
+
### Install via conda
|
|
10
|
+
```conda install cgannonucm::subhaloscript```
|
|
11
|
+
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"id": "410260d7",
|
|
6
|
+
"metadata": {},
|
|
7
|
+
"source": [
|
|
8
|
+
"# Example Notebook\n",
|
|
9
|
+
"Author: Charles Gannon\n",
|
|
10
|
+
"\n",
|
|
11
|
+
"Contact: cgannon@ucmerced.edu\n",
|
|
12
|
+
"\n",
|
|
13
|
+
"## Introduction\n",
|
|
14
|
+
"The ```subscript``` python package provides a library of ergonomic utility functions for analyzing Galacticus (https://github.com/galacticusorg/galacticus) subhalo data. This notebook provides an introduction to the functionality provided in this package. More examples are provided in the test folder. \n",
|
|
15
|
+
"\n",
|
|
16
|
+
"# Installation \n",
|
|
17
|
+
"\n",
|
|
18
|
+
"### Install via pip\n",
|
|
19
|
+
"```pip install subhaloscript```\n",
|
|
20
|
+
"\n",
|
|
21
|
+
"### Install via conda\n",
|
|
22
|
+
"```conda install cgannonucm::subhaloscript```"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"cell_type": "markdown",
|
|
27
|
+
"id": "cd324615",
|
|
28
|
+
"metadata": {},
|
|
29
|
+
"source": [
|
|
30
|
+
"## Data From File\n",
|
|
31
|
+
"```subscript``` integrates with h5py"
|
|
32
|
+
]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"cell_type": "code",
|
|
36
|
+
"execution_count": 1,
|
|
37
|
+
"id": "2caf02a4",
|
|
38
|
+
"metadata": {},
|
|
39
|
+
"outputs": [],
|
|
40
|
+
"source": [
|
|
41
|
+
"import h5py\n",
|
|
42
|
+
"gout = h5py.File('data/test.hdf5')"
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"cell_type": "markdown",
|
|
47
|
+
"id": "57c0468a",
|
|
48
|
+
"metadata": {},
|
|
49
|
+
"source": [
|
|
50
|
+
"## Node Data\n",
|
|
51
|
+
"In Galacticus each subhalo is represented as a node on the primary halo's merger tree. To access properties of each node, use the ```nodedata``` function. Galacticus can contain multiple trees in a single output file, subscript automatically seperates the output nodes into their respective trees."
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"cell_type": "code",
|
|
56
|
+
"execution_count": 2,
|
|
57
|
+
"id": "fd9fdbe4",
|
|
58
|
+
"metadata": {},
|
|
59
|
+
"outputs": [
|
|
60
|
+
{
|
|
61
|
+
"name": "stdout",
|
|
62
|
+
"output_type": "stream",
|
|
63
|
+
"text": [
|
|
64
|
+
"[7.21810428e+09 1.49945391e+09 3.45035586e+09 3.10940712e+09\n",
|
|
65
|
+
" 2.28942716e+10]\n",
|
|
66
|
+
"[2.51769675e+09 6.33693813e+09 1.88133845e+09 1.02403051e+09\n",
|
|
67
|
+
" 1.48554503e+09]\n"
|
|
68
|
+
]
|
|
69
|
+
}
|
|
70
|
+
],
|
|
71
|
+
"source": [
|
|
72
|
+
"from subscript.scripts.nodes import nodedata\n",
|
|
73
|
+
"\n",
|
|
74
|
+
"mass = nodedata(gout, key='basicMass')\n",
|
|
75
|
+
"\n",
|
|
76
|
+
"# The infall mass of the first 5 subhalos in the 1st galacticus output tree\n",
|
|
77
|
+
"print(mass[0][:5])\n",
|
|
78
|
+
"\n",
|
|
79
|
+
"# The infall mass of the first 5 subhalos in the 2nd galacticus output tree\n",
|
|
80
|
+
"print(mass[1][:5])"
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"cell_type": "markdown",
|
|
85
|
+
"id": "018f16ee",
|
|
86
|
+
"metadata": {},
|
|
87
|
+
"source": [
|
|
88
|
+
"Multiple keys can be passed at once"
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"cell_type": "code",
|
|
93
|
+
"execution_count": 3,
|
|
94
|
+
"id": "e53ac8e2",
|
|
95
|
+
"metadata": {},
|
|
96
|
+
"outputs": [
|
|
97
|
+
{
|
|
98
|
+
"name": "stdout",
|
|
99
|
+
"output_type": "stream",
|
|
100
|
+
"text": [
|
|
101
|
+
"0.5666598142807098\n"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
"source": [
|
|
106
|
+
"import numpy as np\n",
|
|
107
|
+
"mass_basic, mass_bound = nodedata(gout, key=['basicMass', 'massBound'])[0]\n",
|
|
108
|
+
"mass_ratio = np.mean(mass_bound/mass_basic)\n",
|
|
109
|
+
"\n",
|
|
110
|
+
"# The average mass at infall to bound masss for the first tree\n",
|
|
111
|
+
"print(mass_ratio)"
|
|
112
|
+
]
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"cell_type": "markdown",
|
|
116
|
+
"id": "06d4750c",
|
|
117
|
+
"metadata": {},
|
|
118
|
+
"source": [
|
|
119
|
+
"Count number of nodes"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"cell_type": "code",
|
|
124
|
+
"execution_count": 4,
|
|
125
|
+
"id": "5812266f",
|
|
126
|
+
"metadata": {},
|
|
127
|
+
"outputs": [
|
|
128
|
+
{
|
|
129
|
+
"name": "stdout",
|
|
130
|
+
"output_type": "stream",
|
|
131
|
+
"text": [
|
|
132
|
+
"246.05357142857142\n"
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"source": [
|
|
137
|
+
"from subscript.scripts.nodes import nodecount\n",
|
|
138
|
+
"\n",
|
|
139
|
+
"# Average number of nodes per tree\n",
|
|
140
|
+
"print(np.mean(nodecount(gout)))"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"cell_type": "markdown",
|
|
145
|
+
"id": "7279057e",
|
|
146
|
+
"metadata": {},
|
|
147
|
+
"source": [
|
|
148
|
+
"## Filters\n",
|
|
149
|
+
"```subscript``` supports filtering nodes by passing a ```nfilter``` function or numpy array of booleans."
|
|
150
|
+
]
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
"cell_type": "code",
|
|
154
|
+
"execution_count": 5,
|
|
155
|
+
"id": "f88029f9",
|
|
156
|
+
"metadata": {},
|
|
157
|
+
"outputs": [
|
|
158
|
+
{
|
|
159
|
+
"name": "stdout",
|
|
160
|
+
"output_type": "stream",
|
|
161
|
+
"text": [
|
|
162
|
+
"13.0\n"
|
|
163
|
+
]
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
"source": [
|
|
167
|
+
"# Get the average host halo mass\n",
|
|
168
|
+
"import subscript.scripts.nfilters as nf\n",
|
|
169
|
+
"# Only include host halo nodes\n",
|
|
170
|
+
"host_halo_mass = nodedata(gout, key='basicMass', nfilter=nf.hosthalos)\n",
|
|
171
|
+
"\n",
|
|
172
|
+
"# Log 10 of average host halo mass\n",
|
|
173
|
+
"print(np.log10(np.mean(host_halo_mass)))"
|
|
174
|
+
]
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"cell_type": "markdown",
|
|
178
|
+
"id": "44f816e1",
|
|
179
|
+
"metadata": {},
|
|
180
|
+
"source": [
|
|
181
|
+
"### Combining filters"
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"cell_type": "markdown",
|
|
186
|
+
"id": "caa435ed",
|
|
187
|
+
"metadata": {},
|
|
188
|
+
"source": [
|
|
189
|
+
"Filters can be combined or modified using boolean logic. We can use the ```logical_and``` or ```logical_not``` function to combine two filters or the ```logical_not``` function to invert the filter."
|
|
190
|
+
]
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
"cell_type": "code",
|
|
194
|
+
"execution_count": 6,
|
|
195
|
+
"id": "1368ab7d",
|
|
196
|
+
"metadata": {},
|
|
197
|
+
"outputs": [
|
|
198
|
+
{
|
|
199
|
+
"name": "stdout",
|
|
200
|
+
"output_type": "stream",
|
|
201
|
+
"text": [
|
|
202
|
+
"0.04988945595354875\n"
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
],
|
|
206
|
+
"source": [
|
|
207
|
+
"from subscript.scripts.spatial import project3d\n",
|
|
208
|
+
"# Only get subhalos within 50 kpc of the host \n",
|
|
209
|
+
"# Note ```subscript``` uses default units of galacticus which is MPC\n",
|
|
210
|
+
"filter_combined = nf.logical_and(\n",
|
|
211
|
+
" nf.subhalos,\n",
|
|
212
|
+
" nf.r3d(None, 0, 5E-2) # Passing 'None' as a first argument 'freezes' the filter, saving the key word arguments\n",
|
|
213
|
+
" )\n",
|
|
214
|
+
"\n",
|
|
215
|
+
"# Now we have no subhalos outside of 0.05 MPC from the center of the host\n",
|
|
216
|
+
"print(np.max(project3d(gout, nfilter=filter_combined)[0])) "
|
|
217
|
+
]
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
"cell_type": "markdown",
|
|
221
|
+
"id": "00dce686",
|
|
222
|
+
"metadata": {},
|
|
223
|
+
"source": [
|
|
224
|
+
"## Statistical Analysis\n",
|
|
225
|
+
"\n",
|
|
226
|
+
"Perform statistical analysis over multiple trees by passing the argument ```summarize=true``` and optionally pass a list of functions, for statistical analysis passing the ```statfuncs``` argument. The default option is ```statfuncs=[np.mean]```, but if the standard deviation is required, you can pass ```statfuncts=[np.mean, np.std]```"
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
"cell_type": "code",
|
|
231
|
+
"execution_count": 7,
|
|
232
|
+
"id": "72a2eb62",
|
|
233
|
+
"metadata": {},
|
|
234
|
+
"outputs": [
|
|
235
|
+
{
|
|
236
|
+
"data": {
|
|
237
|
+
"text/plain": [
|
|
238
|
+
"[]"
|
|
239
|
+
]
|
|
240
|
+
},
|
|
241
|
+
"execution_count": 7,
|
|
242
|
+
"metadata": {},
|
|
243
|
+
"output_type": "execute_result"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"data": {
|
|
247
|
+
"image/png": "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",
|
|
248
|
+
"text/plain": [
|
|
249
|
+
"<Figure size 640x480 with 1 Axes>"
|
|
250
|
+
]
|
|
251
|
+
},
|
|
252
|
+
"metadata": {},
|
|
253
|
+
"output_type": "display_data"
|
|
254
|
+
}
|
|
255
|
+
],
|
|
256
|
+
"source": [
|
|
257
|
+
"# Subhalo massfunction\n",
|
|
258
|
+
"from subscript.scripts.histograms import massfunction\n",
|
|
259
|
+
"# Provides galacticus default parameter keys\n",
|
|
260
|
+
"from subscript.defaults import ParamKeys\n",
|
|
261
|
+
"import matplotlib.pyplot as plt\n",
|
|
262
|
+
"\n",
|
|
263
|
+
"\n",
|
|
264
|
+
"out = massfunction(\n",
|
|
265
|
+
" gout,\n",
|
|
266
|
+
" bins=np.logspace(9, 13, 30), \n",
|
|
267
|
+
" key_mass = ParamKeys.mass_bound, # The default key for bound mass of the subhalo\n",
|
|
268
|
+
" nfilter=nf.subhalos, # Only consider subhalos \n",
|
|
269
|
+
" summarize=True, # Take statistics over multiple trees\n",
|
|
270
|
+
" statfuncs=[np.mean, np.std] # Get the mean and std\n",
|
|
271
|
+
" )\n",
|
|
272
|
+
"\n",
|
|
273
|
+
"dndm_mean, mbine = out[0]\n",
|
|
274
|
+
"dndm_std , _ = out[1]\n",
|
|
275
|
+
"\n",
|
|
276
|
+
"# Plot the mean mass function over all trees, show the standard deviation at each point\n",
|
|
277
|
+
"plt.errorbar(mbine[:-1], dndm_mean, dndm_std)\n",
|
|
278
|
+
"plt.loglog()"
|
|
279
|
+
]
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
"cell_type": "markdown",
|
|
283
|
+
"id": "a5a8888c",
|
|
284
|
+
"metadata": {},
|
|
285
|
+
"source": [
|
|
286
|
+
"### Custom Analysis Functions\n",
|
|
287
|
+
"\n",
|
|
288
|
+
"Use the ```gscript``` decerator to create analysis functions"
|
|
289
|
+
]
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
"cell_type": "code",
|
|
293
|
+
"execution_count": 8,
|
|
294
|
+
"id": "ba018c49",
|
|
295
|
+
"metadata": {},
|
|
296
|
+
"outputs": [
|
|
297
|
+
{
|
|
298
|
+
"name": "stdout",
|
|
299
|
+
"output_type": "stream",
|
|
300
|
+
"text": [
|
|
301
|
+
"0.5539299558467177\n"
|
|
302
|
+
]
|
|
303
|
+
}
|
|
304
|
+
],
|
|
305
|
+
"source": [
|
|
306
|
+
"from subscript.wrappers import gscript\n",
|
|
307
|
+
"\n",
|
|
308
|
+
"# Custom analysis function to take the ratio between bound and infall mass\n",
|
|
309
|
+
"@gscript\n",
|
|
310
|
+
"def massratio_avg(gout, **kwargs):\n",
|
|
311
|
+
" return np.mean(gout[ParamKeys.mass_bound] / gout[ParamKeys.mass_basic])\n",
|
|
312
|
+
"\n",
|
|
313
|
+
"# Average bound to infall mass ratio\n",
|
|
314
|
+
"print(massratio_avg(gout, nfilter=nf.subhalos, summarize=True))"
|
|
315
|
+
]
|
|
316
|
+
}
|
|
317
|
+
],
|
|
318
|
+
"metadata": {
|
|
319
|
+
"kernelspec": {
|
|
320
|
+
"display_name": ".venv",
|
|
321
|
+
"language": "python",
|
|
322
|
+
"name": "python3"
|
|
323
|
+
},
|
|
324
|
+
"language_info": {
|
|
325
|
+
"codemirror_mode": {
|
|
326
|
+
"name": "ipython",
|
|
327
|
+
"version": 3
|
|
328
|
+
},
|
|
329
|
+
"file_extension": ".py",
|
|
330
|
+
"mimetype": "text/x-python",
|
|
331
|
+
"name": "python",
|
|
332
|
+
"nbconvert_exporter": "python",
|
|
333
|
+
"pygments_lexer": "ipython3",
|
|
334
|
+
"version": "3.13.3"
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
"nbformat": 4,
|
|
338
|
+
"nbformat_minor": 5
|
|
339
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
from subscript.defaults import ParamKeys
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
KEY_MAP_SYMPHONY_DEFAULT = {
|
|
6
|
+
ParamKeys.mass_basic : {
|
|
7
|
+
'SymphonyName' : 'mpeak',
|
|
8
|
+
'PerSnap' : False,
|
|
9
|
+
'conversion' : 1.0,
|
|
10
|
+
},
|
|
11
|
+
ParamKeys.mass_bound : {
|
|
12
|
+
'SymphonyName' : 'mvir',
|
|
13
|
+
'PerSnap' : True,
|
|
14
|
+
'conversion' : 1.0,
|
|
15
|
+
},
|
|
16
|
+
ParamKeys.rvir : {
|
|
17
|
+
'SymphonyName' : 'rvir',
|
|
18
|
+
'PerSnap' : True,
|
|
19
|
+
'conversion' : 1E-3,
|
|
20
|
+
},
|
|
21
|
+
ParamKeys.x : {
|
|
22
|
+
'SymphonyName' : 'x',
|
|
23
|
+
'PerSnap' : True,
|
|
24
|
+
'conversion' : 1E-3,
|
|
25
|
+
},
|
|
26
|
+
ParamKeys.y : {
|
|
27
|
+
'SymphonyName' : 'x',
|
|
28
|
+
'PerSnap' : True,
|
|
29
|
+
'conversion' : 1E-3,
|
|
30
|
+
},
|
|
31
|
+
ParamKeys.z : {
|
|
32
|
+
'SymphonyName' : 'x',
|
|
33
|
+
'PerSnap' : True,
|
|
34
|
+
'conversion' : 1E-3,
|
|
35
|
+
},
|
|
36
|
+
ParamKeys.z_lastisolated: {
|
|
37
|
+
'SymphonyName' : 'merger_snap',
|
|
38
|
+
'PerSnap' : False,
|
|
39
|
+
'conversion' : 1.0,
|
|
40
|
+
},
|
|
41
|
+
'custom_id' : {
|
|
42
|
+
'SymphonyName' : 'id',
|
|
43
|
+
'PerSnap' : True,
|
|
44
|
+
'conversion' : 1.0,
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
def symphony_to_galacticus_like_dict(sim_data, z_snap, key_map=KEY_MAP_SYMPHONY_DEFAULT, isnap=-1, tree_index=1):
|
|
49
|
+
ok = sim_data[0]['ok'][:, isnap]
|
|
50
|
+
h, hist = sim_data[0][ok], sim_data[1][ok]
|
|
51
|
+
out = {}
|
|
52
|
+
|
|
53
|
+
for gparamkey, symmap in key_map.items():
|
|
54
|
+
if symmap['PerSnap']:
|
|
55
|
+
val = np.astype(h[symmap['SymphonyName']][:, isnap], float)
|
|
56
|
+
else:
|
|
57
|
+
val = np.astype(hist[symmap['SymphonyName']], float)
|
|
58
|
+
|
|
59
|
+
val *= symmap['conversion']
|
|
60
|
+
|
|
61
|
+
# Hard code special cases
|
|
62
|
+
coord_indexes = {
|
|
63
|
+
ParamKeys.x: 0,
|
|
64
|
+
ParamKeys.y: 1,
|
|
65
|
+
ParamKeys.z: 2
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# Split coordinates from 3 vector into individual entries
|
|
69
|
+
if gparamkey in coord_indexes.keys():
|
|
70
|
+
n = coord_indexes[gparamkey]
|
|
71
|
+
val = val[:, n]
|
|
72
|
+
|
|
73
|
+
# Only the snapshot indexes are stored, get the redshift for the given snapshot index
|
|
74
|
+
if gparamkey == ParamKeys.z_lastisolated:
|
|
75
|
+
val = z_snap[np.astype(val, int)]
|
|
76
|
+
|
|
77
|
+
out[gparamkey] = val
|
|
78
|
+
|
|
79
|
+
# Assign tree index to all subhalos
|
|
80
|
+
nodecount = out.values().__iter__().__next__().shape[0]
|
|
81
|
+
out['custom_node_tree'] = tree_index * np.ones(nodecount, dtype=int)
|
|
82
|
+
|
|
83
|
+
# The first halo is the host
|
|
84
|
+
out[ParamKeys.is_isolated] = np.ones(nodecount, dtype=int)
|
|
85
|
+
out[ParamKeys.is_isolated][0] = 1
|
|
86
|
+
|
|
87
|
+
return out
|
|
@@ -278,7 +278,7 @@ def nfilter_virialized(*args, **kwargs):
|
|
|
278
278
|
return withinrv(*args, **kwargs)
|
|
279
279
|
|
|
280
280
|
@gscript
|
|
281
|
-
def subhalos_valid(gout, mass_min, mass_max, key_mass=ParamKeys.mass,
|
|
281
|
+
def subhalos_valid(gout, mass_min=-np.inf, mass_max=np.inf, key_mass=ParamKeys.mass,
|
|
282
282
|
kwargs_nfilter_subhalos=None, kwargs_nfilter_virialized=None, kwargs_nfilter_range=None, **kwargs):
|
|
283
283
|
"""
|
|
284
284
|
Select subhalos within the virial radius and a given mass range.
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
import numpy as np
|
|
3
|
+
from subscript.defaults import ParamKeys
|
|
4
|
+
from numpy import testing as npt
|
|
5
|
+
from subscript.external import symphony_to_galacticus_like_dict, KEY_MAP_SYMPHONY_DEFAULT
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_symphony_conversion():
|
|
9
|
+
h_mock = np.array([[( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
10
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
11
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
12
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
13
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
14
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
15
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
16
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
17
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
18
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),
|
|
19
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),],
|
|
20
|
+
[(161191255, 1.1802858e+08, 10.73, 1.4001675, [-352.33643 , -466.7435 , 399.61328 ], [ 230.34 , 86.240005, -149.66 ], True, 11.92505 , 31.378775),
|
|
21
|
+
(161763033, 1.1762858e+08, 10.58, 2.1060712, [-314.90338 , -456.68347 , 377.55533 ], [ 239.53 , 99.67 , -161.12 ], True, 12.00846 , 30.496603),
|
|
22
|
+
(162334212, 1.1682858e+08, 10.83, 1.5075221, [-274.99142 , -444.41937 , 353.44006 ], [ 244.91 , 112.77 , -170.87 ], True, 12.077489 , 33.516068),
|
|
23
|
+
(162905122, 1.1601429e+08, 10.75, 1.677781 , [-235.31105 , -429.24124 , 326.8972 ], [ 249.5 , 126.96 , -182.73001 ], True, 12.145057 , 33.39693 ),
|
|
24
|
+
(163473737, 1.1601429e+08, 11.17, 1.9568021, [-192.91576 , -411.1923 , 297.21194 ], [ 255.76001 , 143.56999 , -195.86 ], True, 12.240316 , 38.10785 ),
|
|
25
|
+
(164041230, 1.1641429e+08, 10.75, 1.6198878, [-149.09872 , -389.31595 , 264.40155 ], [ 263.41 , 166.73001 , -210.83 ], True, 12.349269 , 34.10137 ),
|
|
26
|
+
(164614912, 1.1641429e+08, 10.82, 1.5401733, [-103.52247 , -361.36618 , 227.9414 ], [ 272.7 , 195.22 , -228.29 ], True, 12.4436655, 35.222027),
|
|
27
|
+
(165176558, 1.1601429e+08, 10.94, 1.2020737, [ -55.2754 , -326.9403 , 187.49542 ], [ 283.72 , 230.87999 , -247.72 ], True, 12.523146 , 37.016132),
|
|
28
|
+
(165729990, 1.1521429e+08, 10.46, 1.8375131, [ -4.342098, -285.045 , 142.50906 ], [ 291.55 , 276.11002 , -272.67 ], True, 12.587252 , 32.767822),
|
|
29
|
+
(166275341, 1.1360000e+08, 9.95, 1.1902572, [ 48.24502 , -232.74557 , 91.75982 ], [ 291.81 , 339.43 , -304.88998 ], True, 12.620098 , 28.667397),
|
|
30
|
+
( -1, -1.0000000e+00, -1. , -1. , [ -1. , -1. , -1. ], [ -1. , -1. , -1. ], False, -1. , -1. ),]],
|
|
31
|
+
dtype=[('id', '<i4'), ('mvir', '<f4'), ('vmax', '<f4'), ('rvmax', '<f4'), ('x', '<f4', (3,)), ('v', '<f4', (3,)), ('ok', '?'), ('rvir', '<f4'), ('cvir', '<f4')]).T
|
|
32
|
+
|
|
33
|
+
hist_mock = np.array([(1.49857152e+08, 22.2 , 81, 6.6185818e-04, 13600455, 13600542, True, False, True, -1, 81, 232141, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
34
|
+
(1.24471432e+08, 13.12, 134, 6.8571426e-05, 30015901, 30016099, True, False, True, -1, 134, 569486, False, 1.22057144e+08, 0, 0, 0, 0, 0, 0),
|
|
35
|
+
(1.21257144e+08, 12.83, 157, 2.1584741e-05, 29358255, 29358454, True, False, True, -1, 157, 561426, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
36
|
+
(1.21257144e+08, 12.02, 225, 9.6484882e-06, 27526539, 27526714, True, False, True, -1, 225, 536412, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
37
|
+
(1.21257144e+08, 13.89, 168, 4.8911315e-06, 31447571, 31447779, True, False, True, 307964, 127, 585027, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
38
|
+
(1.24071432e+08, 13.45, 154, 2.6225385e-05, 29468890, 29469053, True, False, True, 272054, 153, 562801, False, 1.23671432e+08, 0, 0, 0, 0, 0, 0),
|
|
39
|
+
(1.21257144e+08, 12.65, 206, 8.1003436e-06, 105872378, 105872578, True, False, True, 1769091, 169, 1877999, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
40
|
+
(1.21257144e+08, 16.5 , 140, 1.9619740e-05, 14126887, 14127033, True, False, True, 562239, 123, 247818, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
41
|
+
(1.21257144e+08, 15.84, 165, 1.7540825e-06, 16509517, 16509676, True, False, True, 303394, 108, 307590, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
42
|
+
(1.21257144e+08, 11.88, 230, 9.2452192e-06, 27391623, 27391782, True, False, True, -1, 230, 534378, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),
|
|
43
|
+
(1.21257144e+08, 15.84, 165, 1.7540825e-06, 16509517, 16509676, True, False, True, 303394, 108, 307590, False, 1.21257144e+08, 0, 0, 0, 0, 0, 0),],
|
|
44
|
+
|
|
45
|
+
dtype=[('mpeak', '<f4'), ('vpeak', '<f4'), ('merger_snap', '<i4'), ('merger_ratio', '<f4'), ('start', '<i4'), ('end', '<i4'), ('is_real', '?'), ('is_disappear', '?'), ('is_main_sub', '?'), ('preprocess', '<i4'), ('first_infall_snap', '<i4'), ('branch_idx', '<i4'), ('false_selection', '?'), ('mpeak_pre', '<f4'), ('conv_snap_discrete', '<i4'), ('conv_snap_eps', '<i4'), ('conv_snap_relax', '<i4'), ('conv_snap_relax_hydro', '<i4'), ('disrupt_snap', '<i4'), ('disrupt_snap_rs', '<i4')])
|
|
46
|
+
|
|
47
|
+
z_snap = np.array([1.90000003e+01, 1.87466623e+01, 1.84965337e+01, 1.82495730e+01,
|
|
48
|
+
1.80057406e+01, 1.77649972e+01, 1.75273028e+01, 1.72926197e+01,
|
|
49
|
+
1.70609089e+01, 1.68321335e+01, 1.66062556e+01, 1.63832393e+01,
|
|
50
|
+
1.61630475e+01, 1.59456452e+01, 1.57309964e+01, 1.55190669e+01,
|
|
51
|
+
1.53098215e+01, 1.51032269e+01, 1.48992489e+01, 1.46978550e+01,
|
|
52
|
+
1.44990119e+01, 1.43026877e+01, 1.41088501e+01, 1.39174681e+01,
|
|
53
|
+
1.37285100e+01, 1.35419455e+01, 1.33577443e+01, 1.31758762e+01,
|
|
54
|
+
1.29963121e+01, 1.28190222e+01, 1.26439783e+01, 1.24711514e+01,
|
|
55
|
+
1.23005139e+01, 1.21320376e+01, 1.19656956e+01, 1.18014605e+01,
|
|
56
|
+
1.16393059e+01, 1.14792051e+01, 1.13211324e+01, 1.11650619e+01,
|
|
57
|
+
1.10109685e+01, 1.08588267e+01, 1.07086124e+01, 1.05603006e+01,
|
|
58
|
+
1.04138676e+01, 1.02692893e+01, 1.01265423e+01, 9.98560373e+00,
|
|
59
|
+
9.84645019e+00, 9.70905948e+00, 9.57340890e+00, 9.43947677e+00,
|
|
60
|
+
9.30724097e+00, 9.17668036e+00, 9.04777337e+00, 8.92049941e+00,
|
|
61
|
+
8.79483744e+00, 8.67076738e+00, 8.54826874e+00, 8.42732195e+00,
|
|
62
|
+
8.30790701e+00, 8.19000484e+00, 8.07359598e+00, 7.95866180e+00,
|
|
63
|
+
7.84518333e+00, 7.73314229e+00, 7.62252060e+00, 7.51330000e+00,
|
|
64
|
+
7.40546303e+00, 7.29899187e+00, 7.19386952e+00, 7.09007859e+00,
|
|
65
|
+
6.98760252e+00, 6.88642436e+00, 6.78652795e+00, 6.68789678e+00,
|
|
66
|
+
6.59051510e+00, 6.49436681e+00, 6.39943654e+00, 6.30570863e+00,
|
|
67
|
+
6.21316807e+00, 6.12179960e+00, 6.03158860e+00, 5.94252017e+00,
|
|
68
|
+
5.85458009e+00, 5.76775381e+00, 5.68202735e+00, 5.59738690e+00,
|
|
69
|
+
5.51381846e+00, 5.43130869e+00, 5.34984395e+00, 5.26941122e+00,
|
|
70
|
+
5.18999722e+00, 5.11158925e+00, 5.03417436e+00, 4.95774019e+00,
|
|
71
|
+
4.88227409e+00, 4.80776402e+00, 4.73419765e+00, 4.66156325e+00,
|
|
72
|
+
4.58984879e+00, 4.51904284e+00, 4.44913368e+00, 4.38011014e+00,
|
|
73
|
+
4.31196082e+00, 4.24467484e+00, 4.17824107e+00, 4.11264881e+00,
|
|
74
|
+
4.04788749e+00, 3.98394641e+00, 3.92081534e+00, 3.85848387e+00,
|
|
75
|
+
3.79694203e+00, 3.73617965e+00, 3.67618701e+00, 3.61695422e+00,
|
|
76
|
+
3.55847181e+00, 3.50073010e+00, 3.44371988e+00, 3.38743173e+00,
|
|
77
|
+
3.33185665e+00, 3.27698546e+00, 3.22280938e+00, 3.16931948e+00,
|
|
78
|
+
3.11650720e+00, 3.06436382e+00, 3.01288100e+00, 2.96205024e+00,
|
|
79
|
+
2.91186335e+00, 2.86231223e+00, 2.81338871e+00, 2.76508497e+00,
|
|
80
|
+
2.71739301e+00, 2.67030523e+00, 2.62381385e+00, 2.57791142e+00,
|
|
81
|
+
2.53259038e+00, 2.48784347e+00, 2.44366331e+00, 2.40004283e+00,
|
|
82
|
+
2.35697483e+00, 2.31445242e+00, 2.27246859e+00, 2.23101661e+00,
|
|
83
|
+
2.19008965e+00, 2.14968116e+00, 2.10978446e+00, 2.07039319e+00,
|
|
84
|
+
2.03150083e+00, 1.99310111e+00, 1.95518785e+00, 1.91775479e+00,
|
|
85
|
+
1.88079593e+00, 1.84430518e+00, 1.80827670e+00, 1.77270454e+00,
|
|
86
|
+
1.73758302e+00, 1.70290633e+00, 1.66866893e+00, 1.63486517e+00,
|
|
87
|
+
1.60148964e+00, 1.56853683e+00, 1.53600148e+00, 1.50387820e+00,
|
|
88
|
+
1.47216187e+00, 1.44084725e+00, 1.40992932e+00, 1.37940299e+00,
|
|
89
|
+
1.34926333e+00, 1.31950549e+00, 1.29012455e+00, 1.26111581e+00,
|
|
90
|
+
1.23247448e+00, 1.20419599e+00, 1.17627566e+00, 1.14870903e+00,
|
|
91
|
+
1.12149155e+00, 1.09461887e+00, 1.06808654e+00, 1.04189033e+00,
|
|
92
|
+
1.01602591e+00, 9.90489147e-01, 9.65275821e-01, 9.40381903e-01,
|
|
93
|
+
9.15803281e-01, 8.91536026e-01, 8.67576129e-01, 8.43919762e-01,
|
|
94
|
+
8.20563016e-01, 7.97502127e-01, 7.74733379e-01, 7.52253010e-01,
|
|
95
|
+
7.30057427e-01, 7.08142963e-01, 6.86506117e-01, 6.65143314e-01,
|
|
96
|
+
6.44051139e-01, 6.23226108e-01, 6.02664894e-01, 5.82364099e-01,
|
|
97
|
+
5.62320479e-01, 5.42530722e-01, 5.22991667e-01, 5.03700085e-01,
|
|
98
|
+
4.84652892e-01, 4.65846944e-01, 4.47279233e-01, 4.28946692e-01,
|
|
99
|
+
4.10846392e-01, 3.92975343e-01, 3.75330664e-01, 3.57909512e-01,
|
|
100
|
+
3.40709009e-01, 3.23726406e-01, 3.06958896e-01, 2.90403801e-01,
|
|
101
|
+
2.74058386e-01, 2.57920038e-01, 2.41986092e-01, 2.26254000e-01,
|
|
102
|
+
2.10721164e-01, 1.95385101e-01, 1.80243278e-01, 1.65293275e-01,
|
|
103
|
+
1.50532623e-01, 1.35958961e-01, 1.21569883e-01, 1.07363089e-01,
|
|
104
|
+
9.33362322e-02, 7.94870706e-02, 6.58133165e-02, 5.23127664e-02,
|
|
105
|
+
3.89832442e-02, 2.58225479e-02, 1.28285742e-02, 4.44089210e-16])
|
|
106
|
+
|
|
107
|
+
out = symphony_to_galacticus_like_dict(
|
|
108
|
+
sim_data=(h_mock, hist_mock),
|
|
109
|
+
z_snap=z_snap,
|
|
110
|
+
key_map=KEY_MAP_SYMPHONY_DEFAULT,
|
|
111
|
+
isnap=-1,
|
|
112
|
+
tree_index=2
|
|
113
|
+
)
|
|
114
|
+
# Ensure output size is correct
|
|
115
|
+
npt.assert_equal(out[ParamKeys.mass_basic].shape, (10,))
|
|
116
|
+
|
|
117
|
+
# Ensure outputs are expected
|
|
118
|
+
mass_basic_expect = np.asarray((1.49857152e+08, 1.24471432e+08, 1.21257144e+08, 1.21257144e+08, 1.21257144e+08, 1.24071432e+08, 1.21257144e+08, 1.21257144e+08, 1.21257144e+08, 1.21257144e+08))
|
|
119
|
+
npt.assert_allclose(out[ParamKeys.mass_basic], mass_basic_expect)
|
|
120
|
+
|
|
121
|
+
mass_bound_expect = np.asarray((1.1802858e+08, 1.1762858e+08, 1.1682858e+08, 1.1601429e+08, 1.1601429e+08,1.1641429e+08, 1.1641429e+08, 1.1601429e+08, 1.1521429e+08, 1.1360000e+08))
|
|
122
|
+
npt.assert_allclose(out[ParamKeys.mass_bound], mass_bound_expect)
|
|
123
|
+
|
|
124
|
+
rvir_expect = 1E-3 * np.asarray((11.92505, 12.00846, 12.077489, 12.145057,12.240316,12.349269,12.4436655,12.523146,12.587252,12.620098))
|
|
125
|
+
npt.assert_allclose(out[ParamKeys.rvir], rvir_expect)
|
|
126
|
+
|
|
127
|
+
r_expect = 1E-3 * np.asarray(([-352.33643 , -466.7435 , 399.61328 ],
|
|
128
|
+
[-314.90338 , -456.68347 , 377.55533 ],
|
|
129
|
+
[-274.99142 , -444.41937 , 353.44006 ],
|
|
130
|
+
[-235.31105 , -429.24124 , 326.8972 ],
|
|
131
|
+
[-192.91576 , -411.1923 , 297.21194 ],
|
|
132
|
+
[-149.09872 , -389.31595 , 264.40155 ],
|
|
133
|
+
[-103.52247 , -361.36618 , 227.9414 ],
|
|
134
|
+
[ -55.2754 , -326.9403 , 187.49542 ],
|
|
135
|
+
[ -4.342098, -285.045 , 142.50906 ],
|
|
136
|
+
[ 48.24502 , -232.74557 , 91.75982 ]))
|
|
137
|
+
|
|
138
|
+
x_expect = r_expect[:, 0]
|
|
139
|
+
npt.assert_allclose(out[ParamKeys.x], x_expect)
|
|
140
|
+
|
|
141
|
+
y_expect = r_expect[:, 1]
|
|
142
|
+
npt.assert_allclose(out[ParamKeys.y], y_expect)
|
|
143
|
+
|
|
144
|
+
z_expect = r_expect[:, 2]
|
|
145
|
+
npt.assert_allclose(out[ParamKeys.z], z_expect)
|
|
146
|
+
|
|
147
|
+
z_lastisolated_expect = np.array([6.1217996 , 2.62381385, 1.70290633, 0.13595896, 1.34926333,
|
|
148
|
+
1.8082767 , 0.44727923, 2.35697483, 1.44084725, 0.06581332])
|
|
149
|
+
npt.assert_allclose(out[ParamKeys.z_lastisolated], z_lastisolated_expect)
|
|
150
|
+
|
|
151
|
+
iso_expect = np.ones(10, dtype=int)
|
|
152
|
+
iso_expect[0] = 1
|
|
153
|
+
npt.assert_allclose(out[ParamKeys.is_isolated], iso_expect)
|
|
154
|
+
|
|
155
|
+
id_expect = np.asarray((161191255, 161763033, 162334212, 162905122, 163473737, 164041230, 164614912, 165176558, 165729990, 166275341))
|
|
156
|
+
npt.assert_allclose(out['custom_id'], id_expect)
|
|
157
|
+
|
|
158
|
+
tree_expect = 2 * np.ones(10, dtype=int)
|
|
159
|
+
npt.assert_allclose(out['custom_node_tree'], tree_expect)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
if __name__ == '__main__':
|
|
167
|
+
test_symphony_conversion()
|
subhaloscript-1.0.4/README.md
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
# SubScript
|
|
2
|
-
Utility functions for analyzing subhalo distributions, focusing on the Galacticus (https://github.com/galacticusorg/galacticus) output format. The goal of this package is to facilitate quick statistical analysis of subhalo distributions across multiple trees.
|
|
3
|
-
|
|
4
|
-
## Installation
|
|
5
|
-
|
|
6
|
-
### Install via pip
|
|
7
|
-
```pip install subhaloscript```
|
|
8
|
-
|
|
9
|
-
### Install via conda
|
|
10
|
-
```conda install cgannonucm::subhaloscript```
|
|
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
|