Skip to content

Commit 9fb5fec

Browse files
authored
Merge pull request #28 from asgr/copilot/refactor-sfhfunc-escape-handling
Refactor SFHfunc() escape fraction: compute esc_vec once, stop mutating Zspec
2 parents 25b75d0 + dd1e9da commit 9fb5fec

3 files changed

Lines changed: 27 additions & 40 deletions

File tree

.Rbuildignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
^.*\.Rproj$
2+
^\.Rproj\.user$
3+
.github
4+
.git
5+
.DS_Store
6+
.Rhistory

R/SFH.R

Lines changed: 20 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,21 @@ SFHfunc = function(massfunc = massfunc_b5,
247247
masstot = forcemass
248248
}
249249

250-
# Here we modify the speclib if we have an escape fraction less than 1.
251-
# This is because this will be the first process that occurs, before birth cloud dust or ISM screen dust
252-
# This means we also need to track the luminosity of the stars before any UV absorption (lum)
250+
# Compute wavelength-dependent escape multiplier once (length wave_lum).
251+
# Escape is the first process; Zspec is never mutated for escape fraction.
252+
esc_vec = rep(1, length(wave_lum))
253+
if (any(escape_frac < 1)) {
254+
if (length(Ly_limit) == 1) {
255+
esc_vec[wave_lum < Ly_limit] = escape_frac
256+
} else{
257+
for (i in 1:(length(Ly_limit) - 1)) {
258+
esc_vec[wave_lum < Ly_limit[i] & wave_lum > Ly_limit[i + 1]] = escape_frac[i]
259+
}
260+
esc_vec[wave_lum < Ly_limit[length(Ly_limit)]] = escape_frac[length(Ly_limit)]
261+
}
262+
}
253263

264+
# Accumulate intrinsic (no escape, no dust) luminosity from the spectral library.
254265
if (length(Zuse) > 1) {
255266
lum = rep(0, length(wave_lum))
256267
for (Zid in Zuse) {
@@ -259,49 +270,18 @@ SFHfunc = function(massfunc = massfunc_b5,
259270
#lum = lum + toadd
260271
#.vec_add_cpp(lum, .colSums_wt_cpp(Zspec[[Zid]], massvec * Zwmat[, Zid]))
261272
.vec_add_cpp(lum, crossprod(Zspec[[Zid]], massvec * Zwmat[, Zid])) #factor of about 2-3 faster
262-
if (any(escape_frac < 1)) {
263-
if (length(Ly_limit) == 1) {
264-
sel = which(wave_lum < Ly_limit)
265-
Zspec[[Zid]][, sel] = Zspec[[Zid]][, sel] * escape_frac
266-
} else{
267-
for (i in 1:(length(Ly_limit) - 1)) {
268-
sel = which(wave_lum < Ly_limit[i] & wave_lum > Ly_limit[i + 1])
269-
Zspec[[Zid]][, sel] = Zspec[[Zid]][, sel] *
270-
escape_frac[i]
271-
}
272-
sel = which(wave_lum < Ly_limit[length(Ly_limit)])
273-
Zspec[[Zid]][, sel] = Zspec[[Zid]][, sel] * escape_frac[length(Ly_limit)]
274-
}
275-
}
276273
}
277274
} else{
278275
#lum = colSums(Zspec[[Zuse]] * massvec)
279276
#lum = .colSums_wt_cpp(Zspec[[Zuse]], massvec)
280-
lum = crossprod(Zspec[[Zuse]], massvec) #factor of about 2-3 faster
281-
# if(any(escape_frac<1)){
282-
# Zspec[[Zuse]][,wave_lum<Ly_limit]=Zspec[[Zuse]][,wave_lum<Ly_limit]*escape_frac
283-
# }
284-
if (any(escape_frac < 1)) {
285-
if (length(Ly_limit) == 1) {
286-
wave_lum_sel = wave_lum < Ly_limit
287-
Zspec[[Zuse]][, wave_lum_sel] = Zspec[[Zuse]][, wave_lum_sel] * escape_frac
288-
#.vec_mult_cpp(Zspec[[Zuse]][, wave_lum_sel], escape_frac)
289-
} else{
290-
for (i in 1:(length(Ly_limit) - 1)) {
291-
wave_lum_sel = which(wave_lum < Ly_limit[i] & wave_lum > Ly_limit[i + 1])
292-
Zspec[[Zuse]][, wave_lum_sel] = Zspec[[Zuse]][, wave_lum_sel] * escape_frac[i]
293-
#.vec_mult_cpp(Zspec[[Zuse]][, wave_lum_sel], escape_frac[i])
294-
}
295-
wave_lum_sel = which(wave_lum < Ly_limit[length(Ly_limit)])
296-
Zspec[[Zuse]][, wave_lum_sel] = Zspec[[Zuse]][, wave_lum_sel] * escape_frac[length(Ly_limit)]
297-
#.vec_mult_cpp(Zspec[[Zuse]][, wave_lum_sel], escape_frac[length(Ly_limit)])
298-
}
299-
}
277+
lum = as.numeric(crossprod(Zspec[[Zuse]], massvec)) #factor of about 2-3 faster
300278
}
301279

302-
# This should be pre dispersion being added, and birthcloud or ISM attenuation.
303-
lumtot_unatten = sum(.qdiff(wave_lum) * lum)
280+
# lum_unatten: intrinsic spectrum (no escape, no dust); lumtot_unatten from intrinsic.
281+
# lum: working spectrum with escape applied (still no dust).
304282
lum_unatten = lum
283+
lumtot_unatten = sum(.qdiff(wave_lum) * lum_unatten)
284+
lum = lum_unatten * esc_vec
305285

306286
if (tau_birth != 0) {
307287
birth_sel = 1:birthcloud_len
@@ -319,6 +299,7 @@ SFHfunc = function(massfunc = massfunc_b5,
319299
.vec_add_cpp(lum, crossprod(Zspec[[Zid]][old_sel,,drop=FALSE], massvec[old_sel]))
320300
}
321301
}
302+
lum = lum * esc_vec
322303
lumtot_birth = lumtot_unatten - sum(.qdiff(wave_lum) * lum)
323304
}else{
324305
lumtot_birth = 0

tests/test_disp_stars_cpp.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ for (tc in test_cases) {
5252
z_disp <- rep(veldisp / (c_to_mps / 1000), n) # constant z_disp for simplicity
5353

5454
ref <- disp_stars_R(wave_log, lum_log, z_disp, grid, weights, res)
55-
got <- .disp_stars_cpp(wave_log, lum_log, z_disp, grid, weights, res)
55+
got <- ProSpect:::.disp_stars_cpp(wave_log, lum_log, z_disp, grid, weights, res)
5656

5757
rel_err <- max(abs(ref - got) / pmax(abs(ref), 1e-300))
5858

0 commit comments

Comments
 (0)