function Hermite3, x
h = (2*x^3 - 3*x)/sqrt(3.)
return, h
end
function Hermite4, x
h = (4*x^4 - 12*x^2 + 3)/sqrt(24.)
return, h
end
pro uly_slit, cz, sigma, h3, h4, velscale, slitout
c = 299792.458d
logl_shift = alog(1d + cz/c) / velscale * c
logl_sigma = alog(1d + sigma/c) / velscale * c
N = ceil((abs(logl_shift) + 5d*logl_sigma))
x = N - dindgen(2*n+1)
y = (x-logl_shift)/logl_sigma
large = where(abs(y) gt 30, c)
if c gt 0 then y[large] = 30d
slitout = EXP(-y*y/2d) / logl_sigma / sqrt(2d*!pi)
slitout = slitout*( 1d + h3*Hermite3(y) + h4*Hermite4(y))
slitout /= total(slitout)
end
function uly_spect_losvdconvol, SignalIn, cz, sigma, h3, h4, OVERWRITE=overwrite
compile_opt idl2
on_error, 2
input_sampling = SignalIn.sampling
if input_sampling ne 1 then SignalTmp = uly_spect_logrebin(SignalIn) $
else SignalTmp = SignalIn
if n_elements(cz) eq 0 then $
message, 'ULY_SPECT_LOSVDCONVOL: Velocity (cz) must be given'
if n_elements(sigma) eq 0 then sigma = 0
if n_elements(h3) eq 0 then h3 = 0
if n_elements(h4) eq 0 then h4 = 0
s = size(*SignalTmp.data)
if s[0] ne 1 then $
message, 'This function process only 1D arrays (yet)'
c = 299792.458d
velscale = SignalTmp.step * c
if keyword_set(overwrite) then SignalOut=SignalTmp else $
SignalOut = uly_spect_alloc(SPECTRUM=SignalTmp)
uly_slit, cz, sigma, h3, h4, velscale, losvd
status = check_math(MASK=32, /NOCLEAR)
*SignalOut.data = convol((*SignalTmp.data),losvd,/EDGE_TRUNCATE)
if status eq 0 then status = check_math(MASK=32)
if n_elements(*SignalTmp.err) ne 0 then begin
if n_elements(*SignalTmp.err) ne n_elements(*SignalTmp.data) then $
message, 'spectrum structure unconsistent (err)'
status = check_math(MASK=32, /NOCLEAR)
err = convol((*SignalTmp.err)^2, losvd, /EDGE_TRUNCATE)
if status eq 0 then status = check_math(MASK=32)
*SignalOut.err = sqrt(err * total(losvd^2))
endif
if n_elements(*SignalTmp.goodpix) ne 0 then begin
maskI = replicate(0E, n_elements(*SignalTmp.data))
maskI[*SignalTmp.goodpix] = 1
maskI = reform(maskI, size(*SignalIn.data, /DIM), /OVER)
status = check_math(MASK=32, /NOCLEAR)
maskO = convol(maskI, losvd, /EDGE_TRUNCATE)
if status eq 0 then status = check_math(MASK=32)
*SignalOut.goodpix = where(maskO gt 0.5, cnt)
if cnt eq 0 then message, $
/INFO, 'No good pixels were left after the convolution '+ $
'(it will probably be interpreted as "all pixels are good")'
endif
dof_factor = 1./max(losvd)
SignalOut.dof_factor = SignalTmp.dof_factor * dof_factor
sxaddpar, *SignalOut.hdr, 'HISTORY', 'uly_spect_losvdconvol'
input_sampling = SignalIn.sampling
if input_sampling ne 1 then SignalTmp = uly_spect_logrebin(SignalIn) $
else SignalTmp = SignalIn
if input_sampling ne 1 then begin
if keyword_set(overwrite) then uly_spect_free, SignalIn $
else uly_spect_free, SignalTmp
endif
return, SignalOut
end
Part of