Skip to content

Commit e4b3586

Browse files
authored
Merge pull request #29 from siddharthlal25/p92
Added P92 model
2 parents f78e182 + 30d848a commit e4b3586

File tree

8 files changed

+258
-1
lines changed

8 files changed

+258
-1
lines changed

docs/src/assets/bibtex/P92.bib

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@ARTICLE{1992ApJ...395..130P,
2+
author = {{Pei}, Yichuan C.},
3+
title = "{Interstellar Dust from the Milky Way to the Magellanic Clouds}",
4+
journal = {\apj},
5+
keywords = {Cosmic Dust, Intergalactic Media, Interstellar Extinction, Interstellar Matter, Magellanic Clouds, Milky Way Galaxy, Chemical Evolution, Far Ultraviolet Radiation, Kramers-Kronig Formula, Astrophysics, GALAXIES: INTERGALACTIC MEDIUM, GALAXIES: INTERSTELLAR MATTER, GALAXIES: MAGELLANIC CLOUDS, ISM: DUST, EXTINCTION},
6+
year = 1992,
7+
month = aug,
8+
volume = {395},
9+
pages = {130},
10+
doi = {10.1086/171637},
11+
adsurl = {https://ui.adsabs.harvard.edu/abs/1992ApJ...395..130P},
12+
adsnote = {Provided by the SAO/NASA Astrophysics Data System}
13+
}

docs/src/color_laws.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,16 @@ lplot(FM90) # hide
243243
FM90
244244
```
245245

246+
### Pei (1992)
247+
248+
```@example plotting
249+
lplot(P92) # hide
250+
```
251+
252+
```@docs
253+
P92
254+
```
255+
246256
## Mixture Extinction Laws
247257

248258
### Gordon et al. (2003)

docs/src/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ There are various citations relevant to this work. Please be considerate when us
4848
| [`SFD98Map`](@ref) | [Schlegel, Finkbeiner and Davis (1998)](https://ui.adsabs.harvard.edu/abs/1998ApJ...500..525S) | [download](assets/bibtex/sfd98.bib) |
4949
| [`F99`](@ref) | [Fitzpatrick (1999)](https://ui.adsabs.harvard.edu/abs/1999PASP..111...63F) | [download](assets/bibtex/f99.bib) |
5050
| [`F04`](@ref) | [Fitzpatrick (2004)](https://ui.adsabs.harvard.edu/abs/2004ASPC..309...33F) | [download](assets/bibtex/f04.bib) |
51+
| [`P92`](@ref) | [Pei (1992)](https://ui.adsabs.harvard.edu/abs/1992ApJ...395..130P) | [download](assets/bibtex/P92.bib) |
5152
| [`F19`](@ref) | [Fitzpatrick (2019)](https://ui.adsabs.harvard.edu/abs/2019ApJ...886..108F) | [download](assets/bibtex/f19.bib) |
5253
| [`M14`](@ref) | [Maiz Apellaniz et al. (2014)](https://ui.adsabs.harvard.edu/abs/2014A%26A...564A..63M) | [download](assets/bibtex/m14.bib) |
5354

docs/src/plotting.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,36 @@ function lplot(law::Type{<:FM90}; args...)
7070
fig
7171
end
7272

73+
"""
74+
lplot(law::P92; args...)
75+
76+
Fittable law series plot with automatic axis labels.
77+
"""
78+
function lplot(law::Type{P92}; args...)
79+
# m1
80+
fig, ax, p = lplot(law(); label="total")
81+
82+
m2 = P92(FUV_amp=0, NUV_amp=0, SIL1_amp=0, SIL2_amp=0, FIR_amp=0)
83+
Makie.lines!(ax, m2; label="BKG only")
84+
85+
m3 = P92(NUV_amp=0, SIL1_amp=0, SIL2_amp=0, FIR_amp=0)
86+
Makie.lines!(ax, m3; label="BKG+FUV only")
87+
88+
m4 = P92(FUV_amp=0, SIL1_amp=0, SIL2_amp=0, FIR_amp=0)
89+
Makie.lines!(ax, m4; label="BKG+NUV only")
90+
91+
m5 = P92(FUV_amp=0, NUV_amp=0, SIL2_amp=0)
92+
Makie.lines!(ax, m5; label="BKG+FIR+SIL1 only")
93+
94+
m6 = P92(FUV_amp=0, NUV_amp=0, SIL1_amp=0)
95+
Makie.lines!(ax, m6; label="BKG+FIR+SIL2 only")
96+
97+
m7 = P92(FUV_amp=0, NUV_amp=0, SIL1_amp=0, SIL2_amp=0)
98+
Makie.lines!(ax, m7; label="BKG+FIR only")
99+
100+
fig
101+
end
102+
73103
"""
74104
mplot(law::Type{G16}, Rvs, f_A::Real; args...)
75105

src/DustExtinction.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export redden,
2020
M14,
2121
# Fittable laws
2222
FM90,
23+
P92,
2324
# Mixture laws
2425
G16,
2526
G03_SMCBar,

src/fittable_laws.jl

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,162 @@ function (law::FM90)(wave::T) where T <: Real
8080

8181
return exvebv
8282
end
83+
84+
85+
"""
86+
P92(; BKG_amp=218.57, BKG_lambda=0.047, BKG_b=90.0, BKG_n=2.0,
87+
FUV_amp=18.54, FUV_lambda=0.08, FUV_b=4.0, FUV_n=6.5,
88+
NUV_amp=0.0596, NUV_lambda=0.22, NUV_b=-1.95, NUV_n=2.0,
89+
SIL1_amp=0.0026, SIL1_lambda=9.7, SIL1_b=-1.95, SIL1_n=2.0,
90+
SIL2_amp=0.0026, SIL2_lambda=18.0, SIL2_b=-1.8, SIL2_n=2.0,
91+
FIR_amp=0.0159, FIR_lambda=25.0, FIR_b=0.0, FIR_n=2.0)
92+
93+
Pei (1992) generative extinction model applicable from the extreme UV to far-IR.
94+
95+
## Parameters
96+
97+
Background Terms
98+
* `BKG_amp` - amplitude
99+
* `BKG_lambda` - central wavelength
100+
* `BKG_b` - b coefficient
101+
* `BKG_n` - n coefficient
102+
103+
Far-Ultraviolet Terms
104+
* `FUV_amp` - amplitude
105+
* `FUV_lambda` - central wavelength
106+
* `FUV_b` - b coefficent
107+
* `FUV_n` - n coefficient
108+
109+
Near-Ultraviolet (2175 Å) Terms
110+
* `NUV_amp` - amplitude
111+
* `NUV_lambda` - central wavelength
112+
* `NUV_b` - b coefficent
113+
* `NUV_n` - n coefficient
114+
115+
1st Silicate Feature (~10 micron) Terms
116+
* `SIL1_amp` - amplitude
117+
* `SIL1_lambda` - central wavelength
118+
* `SIL1_b` - b coefficent
119+
* `SIL1_n` - n coefficient
120+
121+
2nd Silicate Feature (~18 micron) Terms
122+
* `SIL2_amp` - amplitude
123+
* `SIL2_lambda` - central wavelength
124+
* `SIL2_b` - b coefficient
125+
* `SIL2_n` - n coefficient
126+
127+
Far-Infrared Terms
128+
* `FIR_amp` - amplitude
129+
* `FIR_lambda` - central wavelength
130+
* `FIR_b` - b coefficent
131+
* `FIR_n` - n coefficient
132+
133+
If `λ` is a `Unitful.Quantity` it will be automatically converted to Å and the
134+
returned value will be `UnitfulAstro.mag`.
135+
136+
## Examples
137+
138+
```jldoctest
139+
julia> model = P92();
140+
141+
julia> model(1500)
142+
2.561019978746464
143+
144+
julia> P92(FUV_b = 2.0).([1000, 2000, 3000])
145+
3-element Vector{Float64}:
146+
5.17952309549434
147+
2.7581232249728607
148+
1.8081781540687367
149+
```
150+
151+
## Default Parameter Values
152+
153+
| Term | lambda (μm) | A | b | n |
154+
| :---: | :---------: | :-------------------: | :---: | :-: |
155+
| BKG | 0.047 | 218.57142857142858 | 90.0 | 2.0 |
156+
| FUV | 0.08 | 18.545454545454547 | 4.0 | 6.5 |
157+
| NUV | 0.22 | 0.05961038961038961 | -1.95 | 2.0 |
158+
| SIL1 | 9.7 | 0.0026493506493506496 | -1.95 | 2.0 |
159+
| SIL2 | 18.0 | 0.0026493506493506496 | -1.8 | 2.0 |
160+
| FIR | 25.0 | 0.015896103896103898 | 0.0 | 2.0 |
161+
162+
163+
## References
164+
[Pei (1992)](https://ui.adsabs.harvard.edu/abs/1992ApJ...395..130P)
165+
"""
166+
Base.@kwdef struct P92{T<:Number} <: ExtinctionLaw
167+
BKG_amp::T = 165.0 * (1 / 3.08 + 1)
168+
BKG_lambda::T = 0.047
169+
BKG_b::T = 90.0
170+
BKG_n::T = 2.0
171+
FUV_amp::T = 14.0 * (1 / 3.08 + 1)
172+
FUV_lambda::T = 0.08
173+
FUV_b::T = 4.0
174+
FUV_n::T = 6.5
175+
NUV_amp::T = 0.045 * (1 / 3.08 + 1)
176+
NUV_lambda::T = 0.22
177+
NUV_b::T = -1.95
178+
NUV_n::T = 2.0
179+
SIL1_amp::T = 0.002 * (1 / 3.08 + 1)
180+
SIL1_lambda::T = 9.7
181+
SIL1_b::T = -1.95
182+
SIL1_n::T = 2.0
183+
SIL2_amp::T = 0.002 * (1 / 3.08 + 1)
184+
SIL2_lambda::T = 18.0
185+
SIL2_b::T = -1.80
186+
SIL2_n::T = 2.0
187+
FIR_amp::T = 0.012 * (1 / 3.08 + 1)
188+
FIR_lambda::T = 25.0
189+
FIR_b::T = 0.00
190+
FIR_n::T = 2.0
191+
function P92(BKG_amp, BKG_lambda, BKG_b, BKG_n, FUV_amp, FUV_lambda, FUV_b, FUV_n,
192+
NUV_amp, NUV_lambda, NUV_b, NUV_n, SIL1_amp, SIL1_lambda, SIL1_b, SIL1_n,
193+
SIL2_amp, SIL2_lambda, SIL2_b, SIL2_n, FIR_amp, FIR_lambda, FIR_b, FIR_n)
194+
195+
BKG_amp 0 || error("`BKG_amp` must be ≥ 0, got ", BKG_amp)
196+
FUV_amp 0 || error("`FUV_amp` must be ≥ 0, got ", FUV_amp)
197+
0.06 FUV_lambda 0.08 || error("`FUV_lambda` must be in between [0.06, 0.08], got ", FUV_lambda)
198+
NUV_amp 0 || error("`NUV_amp` must be ≥ 0, got", NUV_amp)
199+
0.20 NUV_lambda 0.24 || error("`NUV_lambda` must be in between [0.20, 0.24], got ", NUV_lambda)
200+
SIL1_amp 0 || error("`SIL1_amp` must be ≥ 0, got ", SIL1_amp)
201+
7 SIL1_lambda 13 || error("`SIL1_lambda` must be in between [7, 13], got ", SIL1_lambda)
202+
SIL2_amp 0 || error("`SIL2_amp` must be ≥ 0, got ", SIL2_amp)
203+
15 SIL2_lambda 21 || error("`SIL2_lambda` must be in between [15, 21], got ", SIL2_lambda)
204+
FIR_amp 0 || error("`FIR_amp` must be ≥ 0, got ", FIR_amp)
205+
20 FIR_lambda 30 || error("`FIR_lambda` must be in between [20, 30], got ", FIR_lambda)
206+
207+
params = promote(BKG_amp, BKG_lambda, BKG_b, BKG_n,
208+
FUV_amp, FUV_lambda, FUV_b, FUV_n,
209+
NUV_amp, NUV_lambda, NUV_b, NUV_n,
210+
SIL1_amp, SIL1_lambda, SIL1_b, SIL1_n,
211+
SIL2_amp, SIL2_lambda, SIL2_b, SIL2_n,
212+
FIR_amp, FIR_lambda, FIR_b, FIR_n)
213+
214+
return new{eltype(params)}(params...)
215+
end
216+
end
217+
218+
bounds(::Type{<:P92}) = (10, 10_000_000)
219+
220+
function (law::P92)(wave::T) where T <: Real
221+
checkbounds(law, wave) || return zero(float(T))
222+
223+
x = aa_to_invum(wave)
224+
lam = 1 / x # wavelength is in microns
225+
226+
axav = _p92_single_term(lam, law.BKG_amp, law.BKG_lambda, law.BKG_b, law.BKG_n)
227+
axav += _p92_single_term(lam, law.FUV_amp, law.FUV_lambda, law.FUV_b, law.FUV_n)
228+
axav += _p92_single_term(lam, law.NUV_amp, law.NUV_lambda, law.NUV_b, law.NUV_n)
229+
axav += _p92_single_term(lam, law.SIL1_amp, law.SIL1_lambda, law.SIL1_b, law.SIL1_n)
230+
axav += _p92_single_term(lam, law.SIL2_amp, law.SIL2_lambda, law.SIL2_b, law.SIL2_n)
231+
axav += _p92_single_term(lam, law.FIR_amp, law.FIR_lambda, law.FIR_b, law.FIR_n)
232+
233+
return axav
234+
end
235+
236+
# function for calculating a single P92 term
237+
function _p92_single_term(x::Real, amplitude::Real, cen_wave::Real, b::Real, n::Real)
238+
l_norm = x / cen_wave
239+
l_norm_n = l_norm^n
240+
return amplitude / (l_norm_n + inv(l_norm_n) + b)
241+
end

test/fittable_laws.jl

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,46 @@
3434
@test ustrip.(reddening) ref_values rtol = 1e-4
3535
@test ustrip.(reddening1) ref_values rtol = 1e-4
3636
end
37+
38+
@testset "P92" begin
39+
40+
x_inv_microns = [0.21, 0.29, 0.45, 0.61, 0.80, 1.11, 1.43, 1.82, 2.27, 2.50, 2.91, 3.65, 4.00, 4.17, 4.35,
41+
4.57, 4.76, 5.00, 5.26, 5.56, 5.88, 6.25, 6.71, 7.18, 7.60, 8.00, 8.50, 9.00, 9.50, 10.00]
42+
43+
wave = 1e4 ./ x_inv_microns
44+
45+
MW_exvebv = [-3.02, -2.91, -2.76, -2.58, -2.23, -1.60, -0.78, 0.00, 1.00, 1.30, 1.80, 3.10, 4.19, 4.90, 5.77,
46+
6.57, 6.23, 5.52, 4.90, 4.65, 4.60, 4.73, 4.99, 5.36, 5.91, 6.55, 7.45, 8.45, 9.80, 11.30]
47+
48+
Rv = 3.08
49+
ref_values = MW_exvebv ./ Rv .+ 1
50+
51+
model = P92()
52+
model1 = P92(FUV_b = 4)
53+
54+
# Test out of bounds
55+
bad_waves = [9, 1e8]
56+
@test model.(bad_waves) == zeros(length(bad_waves))
57+
@test model1.(bad_waves) == zeros(length(bad_waves))
58+
59+
# testing main part
60+
@test model.(wave) ref_values rtol = 0.25 atol = 0.01
61+
@test model1.(wave) ref_values rtol = 0.25 atol = 0.01
62+
63+
# uncertainties
64+
noise = randn(length(wave)) .* 0.01
65+
wave_unc = wave noise
66+
reddening = @inferred broadcast(model, wave_unc)
67+
reddening1 = @inferred broadcast(model1, wave_unc)
68+
@test Measurements.value.(reddening) ref_values rtol = 0.25 atol = 0.01
69+
@test Measurements.value.(reddening1) ref_values rtol = 0.25 atol = 0.01
70+
71+
# Unitful
72+
wave_u = wave * u"angstrom"
73+
reddening = @inferred broadcast(model, wave_u)
74+
reddening1 = @inferred broadcast(model1, wave_u)
75+
@test eltype(reddening) <: Gain
76+
@test eltype(reddening1) <: Gain
77+
@test ustrip.(reddening) ref_values rtol = 0.25 atol = 0.01
78+
@test ustrip.(reddening1) ref_values rtol = 0.25 atol = 0.01
79+
end

test/runtests.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ using Test, Measurements, Unitful, UnitfulAstro, Random
1313
VERSION v"1.9" && include("makie_recipes.jl")
1414

1515
@testset "interfaces" begin
16-
for LAW in [CCM89, OD94, CAL00, GCC09, VCG04, FM90, G16, F99, F04, F19, M14]
16+
for LAW in [CCM89, OD94, CAL00, GCC09, VCG04, FM90, G16, F99, F04, F19, M14, P92]
1717
@test bounds(LAW) == bounds(LAW())
1818
@test checkbounds(LAW, 1000) == checkbounds(LAW(), 1000)
1919
low, high = bounds(LAW)

0 commit comments

Comments
 (0)