33
44from typing import ClassVar
55
6+ import numpy as np
7+ from astropy .convolution import convolve , Box1DKernel , Gaussian1DKernel
8+
69from ..effects import Effect
710from ...optics .fov import FieldOfView
811from ...utils import from_currsys , get_logger
912
1013logger = get_logger (__name__ )
1114
15+
1216class LineSpreadFunction (Effect ):
1317 """
1418 Compute and apply line spread function to IFU cube
@@ -26,13 +30,52 @@ def __init__(self, **kwargs):
2630 self .meta .update (kwargs )
2731 self .meta = from_currsys (self .meta , self .cmds )
2832
29- self .lsfwidth = None #self.get_width()
30- self .kernel = None #self.get_kernel()
33+ if "lsfwidth" not in self .meta :
34+ self .lsfwidth = self .get_lsf_width ()
35+ else :
36+ self .lsfwidth = self .meta ["lsfwidth" ]
37+ self .kernel = self .get_kernel ()
3138
32- def apply_to (self , obj , ** kwargs ):
39+ def apply_to (self , fov , ** kwargs ):
3340 """Apply the LSF"""
34- if not isinstance (obj , FieldOfView ):
35- return obj
41+ if not isinstance (fov , FieldOfView ):
42+ return fov
43+
44+ if fov .hdu is None or fov .hdu .header ["NAXIS" ] != 3 :
45+ logger .error ("Cannot apply LSF convolution" )
46+ return fov
47+
48+
49+ print ("Happily convolving with LSF" )
50+ fov .hdu .data = convolve (fov .hdu .data , self .kernel )
51+ fov .cube = fov .hdu
52+ return fov
53+
54+ def get_lsf_width (self ):
55+ """Determine width of the LSF kernel at central wavelength"""
56+
57+ slope = self .meta ['fit_slope' ]
58+ intercept = self .meta ['fit_intercept' ]
59+ lamc = self .meta ["wavelen" ]
60+ dlam_per_pix = slope * lamc + intercept
61+
62+ slice_width = self .meta ['slice_width' ]
63+ pixel_scale = self .meta ['pixel_scale' ]
64+
65+ dlam_per_slice = dlam_per_pix * slice_width / pixel_scale
66+
67+ spec_binwidth = self .meta ["spec_binwidth" ]
68+
69+ return dlam_per_slice / spec_binwidth
70+
71+
72+ def get_kernel (self ):
73+ """Build LSF kernel: box kernel smoothed with narrow Gauss"""
3674
37- lamc = from_currsys ("!OBS.wavelen" , self .cmds )
38- print (">>>>>>>>> Central wavelength:" , lamc )
75+ box = Box1DKernel (width = self .lsfwidth )
76+ gauss = Gaussian1DKernel (1 )
77+ if box .shape > gauss .shape :
78+ kernel = convolve (box .array , gauss )[np .newaxis , np .newaxis , :]
79+ else :
80+ kernel = convolve (gauss .array , box )[np .newaxis , np .newaxis , :]
81+ return kernel
0 commit comments