subhaloscript 1.0.2__tar.gz → 1.0.3__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 (24) hide show
  1. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/PKG-INFO +1 -1
  2. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/meta.yaml +1 -1
  3. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/pyproject.toml +1 -1
  4. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/macros.py +1 -1
  5. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/wrappers.py +53 -39
  6. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_wrappers.py +46 -3
  7. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/.github/workflows/main.yml +0 -0
  8. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/.gitignore +0 -0
  9. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/LICENSE +0 -0
  10. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/README.md +0 -0
  11. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/defaults.py +0 -0
  12. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/scripts/histograms.py +0 -0
  13. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/scripts/nfilters.py +0 -0
  14. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/scripts/nodes.py +0 -0
  15. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/scripts/spatial.py +0 -0
  16. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/tabulatehdf5.py +0 -0
  17. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/subscript/util.py +0 -0
  18. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_histograms.py +0 -0
  19. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_macros.py +0 -0
  20. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_nfilters.py +0 -0
  21. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_nfilters_legacy.py +0 -0
  22. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_nodes.py +0 -0
  23. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_spatial.py +0 -0
  24. {subhaloscript-1.0.2 → subhaloscript-1.0.3}/tests/test_tabulatehdf5.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: subhaloscript
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: Utility functions for analyzing subhalo distributions.
5
5
  Author-email: Charles Gannon <cgannon@ucmerced.edu>
6
6
  License-File: LICENSE
@@ -1,6 +1,6 @@
1
1
  package:
2
2
  name: subhaloscript
3
- version: "1.0.2"
3
+ version: "1.0.3"
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.2"
8
+ version = "1.0.3"
9
9
  authors = [
10
10
  { name="Charles Gannon", email="cgannon@ucmerced.edu" },
11
11
  ]
@@ -10,7 +10,7 @@ from numpy.dtypes import StringDType
10
10
 
11
11
  def macro_add(macros:dict[str, Callable], macro, label=None, **kwargs):
12
12
  """
13
- Add a new macro function to an existing macros dictionary.
13
+ Add a new "script" to an existing macros dictionary.
14
14
 
15
15
  Parameters
16
16
  ----------
@@ -6,6 +6,7 @@ from functools import reduce
6
6
  import numpy as np
7
7
  from numpy.typing import ArrayLike
8
8
  import h5py
9
+ from copy import copy
9
10
 
10
11
  from subscript.util import is_arraylike
11
12
  from subscript.tabulatehdf5 import NodeProperties, tabulate_trees
@@ -27,6 +28,7 @@ def reduce_input(l, out=None):
27
28
  -------
28
29
  list of dict or UserDict
29
30
  Flattened list containing all dictionaries/UserDicts found in `l`.
31
+
30
32
  """
31
33
  if out is None:
32
34
  out = []
@@ -70,6 +72,32 @@ def format_nodedata(gout, out_index=-1)->Iterable[NodeProperties]:
70
72
  raise RuntimeError(f"Unrecognized data type for gout {type(gout)}")
71
73
  return _gout
72
74
 
75
+ def _summarize(outs, summarize, statfuncs):
76
+ if summarize is None or not summarize:
77
+ return outs
78
+
79
+ _statfuncs = [np.mean, ] if statfuncs is None else statfuncs
80
+
81
+ if isinstance(outs[0], Iterable):
82
+ eval_stats = lambda f,m: f(np.asarray([treeo[m] for treeo in outs]), axis=0)
83
+ summary = [[eval_stats(f,m) for m, _ in enumerate(outs[0])] for f in _statfuncs]
84
+ else:
85
+ eval_stats = lambda f: f(np.asarray([treeo for treeo in outs]), axis=0)
86
+ summary = [eval_stats(f) for f in _statfuncs]
87
+ return summary
88
+
89
+
90
+ # Eliminate lists of 1 item recursively
91
+ def _format_out(o):
92
+ if (not isinstance(o, Iterable)) or (isinstance(o, str)):
93
+ return o
94
+ if len(o) == 1:
95
+ return _format_out(o[0])
96
+ out = [_format_out(i) for i in o]
97
+ if isinstance(o, np.ndarray):
98
+ return np.asarray(out)
99
+ return out
100
+
73
101
  def gscript(func):
74
102
  """
75
103
  Decorator to wrap a function that processes Galacticus-like node data.
@@ -150,30 +178,9 @@ def gscript(func):
150
178
  _o = [o,] if single_out else o
151
179
  outs.append(_o)
152
180
 
153
- # Eliminate lists of 1 item recursively
154
- def format_out(o):
155
- if (not isinstance(o, Iterable)) or (isinstance(o, str)):
156
- return o
157
- if len(o) == 1:
158
- return format_out(o[0])
159
- out = [format_out(i) for i in o]
160
- if isinstance(o, np.ndarray):
161
- return np.asarray(out)
162
- return out
163
-
164
- if not summarize:
165
- return format_out(outs)
166
-
167
- _statfuncs = [np.mean, ] if statfuncs is None else statfuncs
168
-
169
- if isinstance(outs[0], Iterable):
170
- eval_stats = lambda f,m: f(np.asarray([treeo[m] for treeo in outs]), axis=0)
171
- summary = [[eval_stats(f,m) for m, _ in enumerate(outs[0])] for f in _statfuncs]
172
- else:
173
- eval_stats = lambda f: f(np.asarray([treeo for treeo in outs]), axis=0)
174
- summary = [eval_stats(f) for f in _statfuncs]
181
+ summary = _summarize(outs, summarize=summarize, statfuncs=statfuncs)
175
182
 
176
- return format_out(summary)
183
+ return _format_out(summary)
177
184
  return wrap
178
185
 
179
186
  def gscript_proj(func):
@@ -208,27 +215,36 @@ def gscript_proj(func):
208
215
  """
209
216
  def wrap(gout, normvector, *args, **kwargs):
210
217
  normvector = np.asarray(normvector)
211
- n = None
218
+
219
+ if normvector.ndim == 1:
220
+ #raise NotImplementedError()
221
+ return gscript(func)(gout, *args, normvector=normvector, **kwargs)
222
+ if normvector.ndim > 2 or normvector.ndim <= 0:
223
+ raise RuntimeError(f'"normvector" must be either 1 or 2 dimensional')
212
224
 
213
225
  @gscript
214
- def wrap_inner(gout, *args, normvector, **kwargs):
215
- nonlocal n
216
- v = normvector
217
- if n is not None:
218
- v = normvector[n]
219
- n += 1
220
- if n >= len(normvector):
221
- n = 0
226
+ def wrap_inner_main(gout, **kwargs):
227
+ n = gout.unfilter()['__custom_proj_iter__'][0]
228
+ return func(gout, *args, normvector=normvector[n], **kwargs)
222
229
 
223
230
 
224
- return func(gout, *args, normvector=v, **kwargs)
231
+ ## This wrapped as well so we can call with None
232
+ def wrap_inner(gout, **kwargs2):
233
+ _gout = format_nodedata(gout)[0].unfilter()
225
234
 
235
+ _input = []
236
+ for n, _ in enumerate(normvector):
237
+ _in = copy(_gout)
238
+ _in.data = copy(_in.data)
239
+ _in.data['__custom_proj_iter__'] = n * np.ones(_in.data[next(_in.data.__iter__())].shape[0], dtype=int)
240
+ _input.append(_in)
226
241
 
227
- if normvector.ndim == 1:
228
- return wrap_inner(gout, *args, normvector=normvector, **kwargs)
242
+ return wrap_inner_main(_input, **(kwargs | kwargs2))
229
243
 
230
- n = 0
231
- return wrap_inner([gout for _ in normvector], *args, normvector=normvector, **kwargs)
244
+ if gout is None:
245
+ return wrap_inner
246
+
247
+ return wrap_inner(gout)
232
248
 
233
249
  return wrap
234
250
 
@@ -267,5 +283,3 @@ def multiproj(func, nfilter):
267
283
  Function wrapped with `gscript_proj` and the node filter applied.
268
284
  """
269
285
  return gscript_proj(freeze(func, nfilter=nfilter))
270
-
271
-
@@ -53,8 +53,12 @@ def test_multi_proj():
53
53
  out_expected_yz = np.asarray((4, 3, 0), dtype=int)
54
54
 
55
55
  out_expected = np.mean(np.asarray((out_expected_xy, out_expected_xz, out_expected_yz)), axis=0)
56
-
57
- out_actual, dn_r = spatial2d_dn(mockdata, bins=bins, normvector=norm, summarize=True)
56
+ print(out_expected)
57
+
58
+ out = spatial2d_dn(mockdata, bins=bins, normvector=norm, summarize=True)
59
+ print(out)
60
+ out_actual, dn_r = out
61
+
58
62
 
59
63
  testing.assert_allclose(dn_r, bins)
60
64
  testing.assert_allclose(out_actual, out_expected)
@@ -96,6 +100,44 @@ def test_gscript_proj_wrap():
96
100
 
97
101
  testing.assert_allclose(n_actual, n_expected)
98
102
 
103
+
104
+ def test_gscript_proj_wrap_none():
105
+ test_x = np.asarray((0.0, 0.25, 0.5 , 0.7 , 0.8 , 1.3, 1.4))
106
+ test_y = np.asarray((0.0, 0.00, 0.5 , 0.3 , 0.9 , 0.0, 0.0))
107
+ test_z = np.asarray((0.0, 0.00, 0.5 , 0.4 , 0.1 , 0.0, 0.0))
108
+
109
+ mockdata = {
110
+ ParamKeys.x: test_x,
111
+ ParamKeys.y: test_y,
112
+ ParamKeys.z: test_z
113
+ }
114
+
115
+ r_xy_expected = np.asarray((0.0, 0.25, 0.70710678, 0.76157731, 1.20415946, 1.3, 1.4))
116
+ r_xz_expected = np.asarray((0.0, 0.25, 0.70710678, 0.80622577, 0.80622577, 1.3, 1.4))
117
+ r_yz_expected = np.asarray((0.0, 0.00, 0.70710678, 0.5 , 0.90553851, 0.0, 0.0))
118
+
119
+ rmin, rmax = 0.2, 0.71
120
+ normvectors = np.identity(3)
121
+
122
+ n_expected = (
123
+ np.sum((r_xy_expected >= rmin) & (r_xy_expected <= rmax))
124
+ +np.sum((r_xz_expected >= rmin) & (r_xz_expected <= rmax))
125
+ +np.sum((r_yz_expected >= rmin) & (r_yz_expected <= rmax))
126
+ ) / 3
127
+
128
+ nfproj = freeze(r2d, rmin=rmin, rmax=rmax)
129
+
130
+ frozentest = gscript_proj(freeze(nodecount, nfilter=nfproj))(None, summarize=True, normvector=normvectors)
131
+ n_actual = frozentest(mockdata)
132
+
133
+ testing.assert_allclose(n_actual, n_expected)
134
+
135
+ normvectors2 = ((1,0,0), (0,1,0), (0,0,1))
136
+
137
+ n_actual = gscript_proj(freeze(nodecount, nfilter=nfproj))(mockdata, summarize=True, normvector=normvectors2)
138
+
139
+ testing.assert_allclose(n_actual, n_expected)
140
+
99
141
  def test_multiproj():
100
142
  test_x = np.asarray((0.0, 0.25, 0.5 , 0.7 , 0.8 , 1.3, 1.4))
101
143
  test_y = np.asarray((0.0, 0.00, 0.5 , 0.3 , 0.9 , 0.0, 0.0))
@@ -208,4 +250,5 @@ def test_autofreeze():
208
250
  testing.assert_allclose(f[key][_key][:], _val)
209
251
 
210
252
 
211
-
253
+ if __name__ == "__main__":
254
+ test_multi_proj()
File without changes
File without changes
File without changes