Skip to content

Commit 296ff1e

Browse files
authored
Merge pull request #29 from SWIFTSIM/adaptive_bin_cache_tweak
Adaptive Bin Caching
2 parents 7237888 + 5505b2c commit 296ff1e

File tree

5 files changed

+98
-28
lines changed

5 files changed

+98
-28
lines changed

examples/auto_plotter_example.yml

+27-24
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,29 @@
1+
stellar_mass_gas_metallicity:
2+
type: "2dhistogram"
3+
x:
4+
quantity: "apertures.mass_star_100_kpc"
5+
units: Solar_Mass
6+
start: 1e6
7+
end: 1e12
8+
y:
9+
quantity: "apertures.zmet_gas_100_kpc"
10+
units: ""
11+
start: 1e-6
12+
end: 1e-1
13+
median:
14+
plot: true
15+
log: true
16+
number_of_bins: 25
17+
adaptive: true
18+
start:
19+
value: 1e6
20+
units: Solar_Mass
21+
end:
22+
value: 1e12
23+
units: Solar_Mass
24+
metadata:
25+
title: Stellar Mass-Gas Metallicity relation (100 kpc aperture)
26+
127
stellar_mass_halo_mass_adaptive_100:
228
type: "2dhistogram"
329
x:
@@ -147,6 +173,7 @@ stellar_mass_stellar_metallicity:
147173
median:
148174
plot: true
149175
log: true
176+
adaptive: true
150177
number_of_bins: 25
151178
start:
152179
value: 1e6
@@ -157,27 +184,3 @@ stellar_mass_stellar_metallicity:
157184
metadata:
158185
title: Stellar Mass-Stellar Metallicity relation (100 kpc aperture)
159186

160-
stellar_mass_gas_metallicity:
161-
type: "2dhistogram"
162-
x:
163-
quantity: "apertures.mass_star_100_kpc"
164-
units: Solar_Mass
165-
start: 1e6
166-
end: 1e12
167-
y:
168-
quantity: "apertures.zmet_gas_100_kpc"
169-
units: ""
170-
start: 1e-6
171-
end: 1e-1
172-
median:
173-
plot: true
174-
log: true
175-
number_of_bins: 25
176-
start:
177-
value: 1e6
178-
units: Solar_Mass
179-
end:
180-
value: 1e12
181-
units: Solar_Mass
182-
metadata:
183-
title: Stellar Mass-Gas Metallicity relation (100 kpc aperture)

velociraptor/__version__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.10.3"
1+
__version__ = "0.10.4"

velociraptor/catalogue/catalogue.py

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ def getter(self):
117117
try:
118118
setattr(self, f"_{name}", unyt.unyt_array(handle[field][...], unit))
119119
getattr(self, f"_{name}").name = full_name
120+
getattr(self, f"_{name}").file = filename
120121
except KeyError:
121122
print(f"Could not read {field}")
122123
return None

velociraptor/tools/adaptive.py

+57
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,31 @@
66
import unyt
77

88

9+
adaptive_bin_cache = {}
10+
11+
12+
def adaptive_bin_hash(
13+
values,
14+
lowest_value,
15+
highest_value,
16+
base_n_bins,
17+
minimum_in_bin,
18+
logarithmic,
19+
stretch_final_bin,
20+
):
21+
"""
22+
Hash for adaptive binning. Note that this can raise AttributeError
23+
in the case where the array is unhashable.
24+
"""
25+
26+
this_hash = (
27+
f"{values.size}{values.name}{lowest_value}{highest_value}"
28+
f"{base_n_bins}{minimum_in_bin}{logarithmic}{stretch_final_bin}"
29+
)
30+
31+
return this_hash
32+
33+
934
def create_adaptive_bins(
1035
values: unyt.unyt_array,
1136
lowest_value: unyt.unyt_quantity,
@@ -58,7 +83,36 @@ def create_adaptive_bins(
5883
bin_edges: unyt.unyt_array, optional
5984
Bin edges that were used in the binning process.
6085
86+
Notes
87+
-----
88+
89+
Caches the output as this procedure can be very expensive, and will be
90+
repeated several times.
91+
6192
"""
93+
94+
# First we check in the cache to see if we have already performed
95+
# the binning procedure.
96+
try:
97+
this_hash = adaptive_bin_hash(
98+
values=values,
99+
lowest_value=lowest_value,
100+
highest_value=highest_value,
101+
base_n_bins=base_n_bins,
102+
minimum_in_bin=minimum_in_bin,
103+
logarithmic=logarithmic,
104+
stretch_final_bin=stretch_final_bin,
105+
)
106+
except AttributeError:
107+
this_hash = False
108+
109+
if this_hash:
110+
try:
111+
return adaptive_bin_cache[this_hash]
112+
except:
113+
# Not created yet!
114+
pass
115+
62116
assert (
63117
values.units == lowest_value.units and lowest_value.units == highest_value.units
64118
), "Please ensure that all value quantities have the same units."
@@ -162,5 +216,8 @@ def create_adaptive_bins(
162216
np.array([*bin_edges_left, bin_edges_right[-1]]), units=values.units
163217
)
164218

219+
if this_hash:
220+
adaptive_bin_cache[this_hash] = (bin_centers, bin_edges)
221+
165222
return bin_centers, bin_edges
166223

velociraptor/tools/mass_functions.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,21 @@ def create_adaptive_mass_function(
242242
bin_medians.append(
243243
np.median(sorted_masses[current_lower_index : index + 1])
244244
)
245-
bin_edges_right.append(mass)
246-
bin_edges_left.append(mass)
245+
246+
# The new bin edge lives half way in between our current value and the
247+
# next value, if it exists.
248+
try:
249+
new_edge = 0.5 * (sorted_masses[index + 1] + mass)
250+
except IndexError:
251+
# This case is where `value` is the last item in the array.
252+
new_edge = mass
253+
254+
bin_edges_right.append(new_edge)
255+
bin_edges_left.append(new_edge)
247256
number_in_bin.append(current_bin_count)
248257

249258
# Reset for the lads
250-
current_edge_left = mass
259+
current_edge_left = new_edge
251260
current_lower_index = index
252261
current_bin_count = 0
253262
else:

0 commit comments

Comments
 (0)