pro uly_solut_splot, solution, $
WAVERANGE=waverange, RESI_YR=resi_yr, FLUX_YR=flux_yr, $
SMOOTH_RESID=smooth_resid, $
SMOOTH_FLUX=smooth_flux, $
SCAN=scan, $
XLOG=xlog, YLOG=ylog, $
TITLE=title, $
PLOT_VAR=plot_var, _EXTRA=extra
if size(solution,/TYPE) eq size('str',/TYPE) then $
solut = uly_solut_sread(solution) $
else $
solut = solution
if size(solut, /TYPE) ne 8 then begin
message, 'No input' ,/INFO
return
endif
if n_elements(solut) ne 1 then begin
message, /INFO, 'Cannot plot, because <solution> is an array'
return
endif
if not keyword_set(plot_var) or size(plot_var, /TYPE) ne 8 then begin
if not keyword_set(linecolor) then linecolor='Black'
plot_var = uly_plot_init(LINECOLOR=linecolor, _EXTRA=extra)
endif
if n_elements(title) eq 0 then title = solut.title
if n_elements(scan) ne 0 then nscan = scan $
else nscan = 0
if not ptr_valid(solut.data) then begin
message, /INFO, 'No data to plot (spectrum is empty)'
return
endif
if (size(solut.bestfit,/N_DIM)) eq 0 then begin
message, /INFO, 'No data to plot (spectrum is empty)'
return
endif
if size(solut.bestfit,/N_DIM) gt 1 then begin
if nscan ge (size(solut.bestfit,/DIM))[1] then begin
message, 'SCAN is out of range' ,/info
return
endif
endif else if nscan ne 0 then begin
message, 'SCAN is out of range' ,/info
return
endif
crv = solut.start
cdv = solut.step
npix = (size(solut.bestfit,/DIM))[0]
wave = findgen(npix)*cdv+crv
if solut.sampling eq 1 then wave = exp(wave)
range = [wave[0], wave[n_elements(wave)-1]]
if n_elements(waverange) gt 0 then begin
if n_elements(waverange) eq 1 then $
waverange = [waverange,wave[n_elements(wave)-1]]
if waverange[0] lt range[0] then waverange[0] = range[0]
if waverange[1] gt range[1] then waverange[1] = range[1]
range = waverange
p0 = min(where(wave ge range[0]))
p1 = max(where(wave le range[1]))
wave = wave[p0:p1]
endif else begin
p0 = 0l
p1 = npix-1
endelse
data = dblarr(5, p1-p0+1)
data[0,*] = solut.bestfit[p0:p1,nscan]
if (size(*solut.data,/DIM))[0] ge p1 then begin
data[1,*] = (*solut.data)[p0:p1,nscan]
factor = abs(1./median(data[1,*]))
endif else begin
factor = 1
message, 'No observed spectrum to plot', /INFO
endelse
if (size(solut.mulcont,/DIM))[0] ge p1 then $
data[2,*] = solut.mulcont[p0:p1,nscan]
data[3,*] = solut.addcont[p0:p1,nscan]
data[4,*] = (*solut.err)[p0:p1,nscan]
goodpix = where(solut.mask[p0:p1,nscan] eq 1)
badpix = where(solut.mask[p0:p1,nscan] eq 0)
spec = reform(factor*data[1,*]/data[2,*])
model = reform(factor*data[0,*]/data[2,*])
resid = spec - model
if n_elements(smooth_resid) eq 1 then begin
chi = resid / data[4,*]
velscale = cdv * 299792.458d
uly_slit, 0d, smooth_resid, 0d, 0d, velscale, kernel
status = check_math(MASK=32)
resid = convol(chi,kernel,/EDGE_TRUNCATE) * data[4,*]
data[4,*] = sqrt(convol(reform(data[4,*])^2,kernel^2,/EDGE_TRUNCATE))
if status eq 0 then status = check_math(MASK=32)
endif
if n_elements(smooth_flux) eq 1 then begin
uly_slit, 0d, smooth_flux, 0d, 0d, cdv * 299792.458d, kernel
spec = convol(spec, kernel, /EDGE_TRUNCATE)
model = convol(model, kernel, /EDGE_TRUNCATE)
status = check_math(MASK=32)
endif
if array_equal(data[2,*], 0.*data[2,*]+1.) then begin
if array_equal(data[3,*], 0.*data[3,*]) then $
polyn = !VALUES.F_NAN*lindgen(p1-p0+1) else polyn = reform(data[3,*])
endif else begin
polyn = reform(data[2,*])
endelse
badresid = resid*!VALUES.F_NAN
goodresid = resid*!VALUES.F_NAN
badspec = spec*!VALUES.F_NAN
goodspec = spec*!VALUES.F_NAN
goodspec[goodpix] = spec[goodpix]
if n_elements(badpix) gt 1 then begin
badpix = uly_plot_padpixelrange(badpix)
if n_elements(smooth_flux) eq 1 then $
badpix = uly_plot_padpixelrange(badpix)
badspec[badpix] = spec[badpix]
residbadpix = badpix
if n_elements(smooth_resid) eq 1 then $
residbadpix = uly_plot_padpixelrange(residbadpix)
badresid[residbadpix] = resid[residbadpix]
residgoodpix = uly_plot_padpixelrange(where(finite(badresid, /nan)))
goodresid[residgoodpix] = resid[residgoodpix]
endif else begin
goodresid = resid
residgoodpix = goodpix
endelse
if !d.name ne 'PS' then device, DECOMPOSED=0
if n_elements(flux_yr) ne 0 then begin
yr_flux = flux_yr
ys_flux = 1
endif else begin
sorted = sort(spec[goodpix])
n = n_elements(goodpix)
yr_flux = (spec[goodpix])[sorted[[ceil(0.002*n), floor(0.998*n)]]]
endelse
if n_elements(resi_yr) ne 0 then begin
yr_resi = resi_yr
if n_elements(resi_yr) eq 1 then yr_resi=[-abs(resi_yr), abs(resi_yr)]
ys_resi = 1
endif else begin
sorted = sort(goodresid[residgoodpix])
n = n_elements(residgoodpix)
yr_resi = (goodresid[residgoodpix])[sorted[[ceil(0.003*n), floor(0.997*n)]]]
endelse
!p.multi=[0,1,2]
plot, wave, spec, $
XRANGE=range, XLOG=xlog, XSTYLE=1, XTICKNAME=replicate(' ', 30), $
YRANGE=yr_flux, YLOG=ylog, YSTYLE=ys_flux, YMARGIN=[0., !Y.MARGIN[1]], $
TITLE=title, CHARSIZE=plot_var.charsize, $
BACK=plot_var.bgcolor, COLOR=plot_var.axiscolor, $
/NODATA
ytpos = float(!D.y_ch_size)/!D.x_size * 2
xyouts, ytpos, mean(!y.window), 'Relative flux', CHARSIZE=plot_var.charsize, /NORMAL, ALIGN=0.5, ORIENT=90, COLOR=plot_var.axiscolor
oplot, wave, goodspec, COLOR=plot_var.linecolor, $
PSYM=plot_var.psym, LINESTYLE=plot_var.linestyle, THICK=plot_var.linethick
oplot, wave, polyn, COLOR=FSC_Color(plot_var.polycolor), $
PSYM=plot_var.polypsym, LINESTYLE=plot_var.polystyle, THICK=plot_var.polythick
oplot, wave, model, COLOR=FSC_Color(plot_var.modelcolor), $
PSYM=plot_var.modelpsym, LINESTYLE=plot_var.modelstyle, THICK=plot_var.modelthick
if n_elements(badpix) gt 1 then $
oplot, wave, badspec, $
COLOR=FSC_Color(plot_var.badcolor), PSYM=plot_var.psym, $
LINESTYLE=plot_var.linestyle, THICK=plot_var.linethick
ymarg = [!Y.MARGIN[0],1.]
xtitle = 'Wavelength, '+'!3' + STRING(197B) + '!X'
plot, wave, resid, /NODATA, $
BACK=plot_var.bgcolor, COLOR=plot_var.axiscolor, $
XRANGE=range, XLOG=xlog, XSTYLE=1, XTITLE=xtitle, $
YRANGE=yr_resi, YLOG=ylog, YMARGIN=ymarg, $
YSTYLE=ys_resi, $
CHARSIZE=plot_var.charsize
xyouts, ytpos, mean(!y.window), 'Residual', CHARSIZE=plot_var.charsize, /NORMAL, ALIGN=0.5, ORIENT=90, COLOR=plot_var.axiscolor
oplot, wave, goodresid, COLOR=FSC_Color(plot_var.residcolor), $
PSYM=plot_var.residpsym, LINESTYLE=plot_var.residstyle, THICK=plot_var.residthick
oplot, wave, badresid, COLOR=FSC_Color(plot_var.badcolor), $
PSYM=plot_var.residpsym, LINESTYLE=plot_var.residstyle, THICK=plot_var.residthick
oplot, wave, reform(factor*data[4,*]/data[2,*]), COLOR=FSC_Color(plot_var.sigmacolor), $
PSYM=plot_var.sigmapsym, LINESTYLE=plot_var.sigmastyle, THICK=plot_var.sigmathick
oplot, wave,-reform(factor*data[4,*]/data[2,*]), COLOR=FSC_Color(plot_var.sigmacolor), $
PSYM=plot_var.sigmapsym, LINESTYLE=plot_var.sigmastyle, THICK=plot_var.sigmathick
oplot, wave, wave*0., LINESTYLE=2, COLOR=FSC_Color(plot_var.sigmacolor)
if !d.name ne 'PS' then if n_elements(smooth_resid) eq 1 then begin
x = mean(range)
y = yr_resi[1] - 0.1 * (yr_resi[1]-yr_resi[0])
xyouts, x, y, 'Smoothed: ' + strtrim(string(smooth_resid),2) + ' km/s', $
COLOR=FSC_Color(plot_var.residcolor)
endif
if !d.name ne 'PS' then if n_elements(smooth_flux) eq 1 then begin
x = mean(range)
y = yr_resi[1] + 0.3 * (yr_resi[1]-yr_resi[0])
xyouts, x, y, 'Smoothed: ' + strtrim(string(smooth_flux),2) + ' km/s', COLOR=fsc_color('black')
endif
!p.multi=0
if !d.name ne 'PS' then device, DECOMPOSED=1
if size(solution, /TYPE) ne 8 then heap_free, solut, /PTR
end
Part of