@@ -80,3 +80,162 @@ function (law::FM90)(wave::T) where T <: Real
8080
8181 return exvebv
8282end
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
0 commit comments