subhaloscript 1.0.4__tar.gz → 1.0.5__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.
Files changed (26) hide show
  1. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/PKG-INFO +3 -2
  2. subhaloscript-1.0.5/README.md +11 -0
  3. subhaloscript-1.0.5/example-notebooks/basic-usage.ipynb +339 -0
  4. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/meta.yaml +1 -1
  5. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/pyproject.toml +1 -1
  6. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/scripts/nfilters.py +1 -1
  7. subhaloscript-1.0.4/README.md +0 -10
  8. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/.github/workflows/main.yml +0 -0
  9. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/.gitignore +0 -0
  10. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/LICENSE +0 -0
  11. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/defaults.py +0 -0
  12. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/macros.py +0 -0
  13. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/scripts/histograms.py +0 -0
  14. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/scripts/nodes.py +0 -0
  15. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/scripts/spatial.py +0 -0
  16. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/tabulatehdf5.py +0 -0
  17. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/util.py +0 -0
  18. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/subscript/wrappers.py +0 -0
  19. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_histograms.py +0 -0
  20. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_macros.py +0 -0
  21. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_nfilters.py +0 -0
  22. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_nfilters_legacy.py +0 -0
  23. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_nodes.py +0 -0
  24. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_spatial.py +0 -0
  25. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_tabulatehdf5.py +0 -0
  26. {subhaloscript-1.0.4 → subhaloscript-1.0.5}/tests/test_wrappers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: subhaloscript
3
- Version: 1.0.4
3
+ Version: 1.0.5
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
- 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.
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
+ }
@@ -1,6 +1,6 @@
1
1
  package:
2
2
  name: subhaloscript
3
- version: "1.0.4"
3
+ version: "1.0.5"
4
4
 
5
5
  source:
6
6
  path: . # Or use `git_url`/`url` if not building from local files
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
5
5
  [project]
6
6
  dependencies = ["numpy","pandas","scipy","h5py", "scikit-learn"]
7
7
  name = "subhaloscript"
8
- version = "1.0.4"
8
+ version = "1.0.5"
9
9
  authors = [
10
10
  { name="Charles Gannon", email="cgannon@ucmerced.edu" },
11
11
  ]
@@ -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.
@@ -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