Skip to content

Commit 3fd6dd6

Browse files
Jammy2211Jammy2211
authored andcommitted
feat: support Kaplinghat halos in substructure arrays
1 parent 8e8d240 commit 3fd6dd6

3 files changed

Lines changed: 278 additions & 27 deletions

File tree

autolens/lens/substructure_util.py

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,60 @@
33
import autogalaxy as ag
44

55

6+
def _halo_parameter_extractor_from(profile_cls):
7+
kaplinghat_profile_classes = tuple(
8+
cls
9+
for cls in (
10+
getattr(ag.mp, "KaplinghatCoredNFWSph", None),
11+
getattr(ag.mp, "KaplinghatCoredNFWMCRLudlowSph", None),
12+
)
13+
if cls is not None
14+
)
15+
16+
if profile_cls is ag.mp.cNFWSph:
17+
18+
def extract(prof):
19+
return [
20+
prof.centre[0],
21+
prof.centre[1],
22+
prof.kappa_s,
23+
prof.scale_radius,
24+
prof.core_radius,
25+
]
26+
27+
return 5, extract
28+
29+
if profile_cls in kaplinghat_profile_classes:
30+
31+
def extract(prof):
32+
return [
33+
prof.centre[0],
34+
prof.centre[1],
35+
prof.kappa_s,
36+
prof.scale_radius,
37+
prof.interaction_radius,
38+
prof.central_density,
39+
prof.isothermal_radius,
40+
]
41+
42+
return 7, extract
43+
44+
if profile_cls is ag.mp.NFWTruncatedSph:
45+
46+
def extract(prof):
47+
return [
48+
prof.centre[0],
49+
prof.centre[1],
50+
prof.kappa_s,
51+
prof.scale_radius,
52+
prof.truncation_radius,
53+
]
54+
55+
return 5, extract
56+
57+
raise ValueError(f"Unsupported halo profile class: {profile_cls}")
58+
59+
660
def precompute_scaling_matrix(plane_redshifts, cosmology=None):
761
import jax.numpy as jnp
862

@@ -28,21 +82,7 @@ def galaxies_to_halo_arrays(galaxies, plane_redshifts, max_n, profile_cls):
2882
import jax.numpy as jnp
2983

3084
n_planes = len(plane_redshifts)
31-
32-
if profile_cls is ag.mp.cNFWSph:
33-
n_params = 5
34-
def extract(prof):
35-
return [
36-
prof.centre[0], prof.centre[1],
37-
prof.kappa_s, prof.scale_radius, prof.core_radius,
38-
]
39-
else:
40-
n_params = 5
41-
def extract(prof):
42-
return [
43-
prof.centre[0], prof.centre[1],
44-
prof.kappa_s, prof.scale_radius, prof.truncation_radius,
45-
]
85+
n_params, extract = _halo_parameter_extractor_from(profile_cls=profile_cls)
4686

4787
params = np.zeros((n_planes, max_n, n_params))
4888
mask = np.zeros((n_planes, max_n), dtype=bool)

test_autolens/config/priors/dark_mass_profiles.yaml

Lines changed: 154 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -261,8 +261,8 @@ gNFW:
261261
width_modifier:
262262
type: Relative
263263
value: 0.2
264-
gNFWSph:
265-
centre_0:
264+
gNFWSph:
265+
centre_0:
266266
limits:
267267
lower: -inf
268268
upper: inf
@@ -302,13 +302,155 @@ gNFWSph:
302302
width_modifier:
303303
type: Relative
304304
value: 0.2
305-
scale_radius:
306-
limits:
307-
lower: 0.0
308-
upper: inf
309-
lower_limit: 0.0
310-
type: Uniform
311-
upper_limit: 30.0
312-
width_modifier:
313-
type: Relative
314-
value: 0.2
305+
scale_radius:
306+
limits:
307+
lower: 0.0
308+
upper: inf
309+
lower_limit: 0.0
310+
type: Uniform
311+
upper_limit: 30.0
312+
width_modifier:
313+
type: Relative
314+
value: 0.2
315+
KaplinghatCoredNFWSph:
316+
centre_0:
317+
limits:
318+
lower: -inf
319+
upper: inf
320+
mean: 0.0
321+
sigma: 0.1
322+
type: Gaussian
323+
width_modifier:
324+
type: Absolute
325+
value: 0.05
326+
centre_1:
327+
limits:
328+
lower: -inf
329+
upper: inf
330+
mean: 0.0
331+
sigma: 0.1
332+
type: Gaussian
333+
width_modifier:
334+
type: Absolute
335+
value: 0.05
336+
kappa_s:
337+
limits:
338+
lower: 0.0
339+
upper: inf
340+
lower_limit: 0.0
341+
type: Uniform
342+
upper_limit: 1.0
343+
width_modifier:
344+
type: Relative
345+
value: 0.2
346+
scale_radius:
347+
limits:
348+
lower: 0.0
349+
upper: inf
350+
lower_limit: 0.0
351+
type: Uniform
352+
upper_limit: 30.0
353+
width_modifier:
354+
type: Relative
355+
value: 0.2
356+
sigma_over_m:
357+
limits:
358+
lower: 0.0
359+
upper: inf
360+
lower_limit: 0.0
361+
type: Uniform
362+
upper_limit: 10.0
363+
width_modifier:
364+
type: Relative
365+
value: 0.5
366+
t_age:
367+
limits:
368+
lower: 0.0
369+
upper: inf
370+
lower_limit: 0.0
371+
type: Uniform
372+
upper_limit: 13.8
373+
width_modifier:
374+
type: Relative
375+
value: 0.2
376+
interaction_radius:
377+
limits:
378+
lower: 0.0
379+
upper: inf
380+
lower_limit: 0.0
381+
type: Uniform
382+
upper_limit: 30.0
383+
width_modifier:
384+
type: Relative
385+
value: 0.2
386+
KaplinghatCoredNFWMCRLudlowSph:
387+
centre_0:
388+
limits:
389+
lower: -inf
390+
upper: inf
391+
mean: 0.0
392+
sigma: 0.1
393+
type: Gaussian
394+
width_modifier:
395+
type: Absolute
396+
value: 0.05
397+
centre_1:
398+
limits:
399+
lower: -inf
400+
upper: inf
401+
mean: 0.0
402+
sigma: 0.1
403+
type: Gaussian
404+
width_modifier:
405+
type: Absolute
406+
value: 0.05
407+
mass_at_200:
408+
limits:
409+
lower: 0.0
410+
upper: inf
411+
lower_limit: 100000000.0
412+
type: LogUniform
413+
upper_limit: 1000000000000000.0
414+
width_modifier:
415+
type: Relative
416+
value: 0.5
417+
sigma_over_m:
418+
limits:
419+
lower: 0.0
420+
upper: inf
421+
lower_limit: 0.0
422+
type: Uniform
423+
upper_limit: 10.0
424+
width_modifier:
425+
type: Relative
426+
value: 0.5
427+
t_age:
428+
limits:
429+
lower: 0.0
430+
upper: inf
431+
lower_limit: 0.0
432+
type: Uniform
433+
upper_limit: 13.8
434+
width_modifier:
435+
type: Relative
436+
value: 0.2
437+
redshift_object:
438+
limits:
439+
lower: 0.0
440+
upper: inf
441+
lower_limit: 0.0
442+
type: Uniform
443+
upper_limit: 1.0
444+
width_modifier:
445+
type: Relative
446+
value: 0.5
447+
redshift_source:
448+
limits:
449+
lower: 0.0
450+
upper: inf
451+
lower_limit: 0.0
452+
type: Uniform
453+
upper_limit: 1.0
454+
width_modifier:
455+
type: Relative
456+
value: 0.5
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import numpy as np
2+
import pytest
3+
4+
import autolens as al
5+
from autolens.lens import substructure_util
6+
7+
8+
requires_kaplinghat = pytest.mark.skipif(
9+
not hasattr(al.mp, "KaplinghatCoredNFWSph"),
10+
reason="Kaplinghat SIDM profiles are provided by the pending PyAutoGalaxy release.",
11+
)
12+
13+
14+
@requires_kaplinghat
15+
def test__autolens_exposes_kaplinghat_profiles_from_autogalaxy():
16+
assert hasattr(al.mp, "KaplinghatCoredNFWSph")
17+
assert hasattr(al.mp, "KaplinghatCoredNFWMCRLudlowSph")
18+
19+
20+
@requires_kaplinghat
21+
def test__galaxies_to_halo_arrays__packs_kaplinghat_profile_parameters():
22+
profile = al.mp.KaplinghatCoredNFWSph(
23+
centre=(0.1, -0.2),
24+
kappa_s=0.03,
25+
scale_radius=1.7,
26+
sigma_over_m=2.0,
27+
t_age=8.0,
28+
interaction_radius=0.25,
29+
)
30+
galaxies = [
31+
al.Galaxy(redshift=0.5, mass=profile),
32+
al.Galaxy(redshift=1.0, mass_sheet=al.mp.MassSheet(kappa=-0.01)),
33+
]
34+
35+
params, mask, sheet_kappas = substructure_util.galaxies_to_halo_arrays(
36+
galaxies=galaxies,
37+
plane_redshifts=[0.5, 1.0],
38+
max_n=2,
39+
profile_cls=al.mp.KaplinghatCoredNFWSph,
40+
)
41+
42+
assert params.shape == (2, 2, 7)
43+
assert mask.tolist() == [[True, False], [False, False]]
44+
assert sheet_kappas.tolist() == [0.0, -0.01]
45+
46+
np.testing.assert_allclose(
47+
np.asarray(params[0, 0]),
48+
np.array(
49+
[
50+
0.1,
51+
-0.2,
52+
profile.kappa_s,
53+
profile.scale_radius,
54+
profile.interaction_radius,
55+
profile.central_density,
56+
profile.isothermal_radius,
57+
]
58+
),
59+
)
60+
61+
62+
def test__galaxies_to_halo_arrays__raises_for_unsupported_profile_class():
63+
with pytest.raises(ValueError):
64+
substructure_util.galaxies_to_halo_arrays(
65+
galaxies=[],
66+
plane_redshifts=[0.5],
67+
max_n=1,
68+
profile_cls=al.mp.IsothermalSph,
69+
)

0 commit comments

Comments
 (0)