Skip to content

ifu

Deprecated utilities for spectrally dispersed IFU NRM data.

clean_data(list_file, isz=256, r1=100, dr=10, edge=0, bad_map=None, add_bad=None, offx=0, offy=0, clip_fact=0.5, apod=True, sky=True, window=None, f_kernel=3, verbose=False, ihdu=0, display=False)

Clean IFU files and reshape their frames into a four-dimensional cube.

Parameters:

Name Type Description Default
list_file list of str or path-like

IFU FITS files.

required
isz int

Crop size.

256
r1 int

Sky-ring parameters.

100, 10
dr int

Sky-ring parameters.

100, 10
edge int

Detector-edge width to remove.

0
bad_map ndarray or None

Bad-pixel map.

None
add_bad list or None

Additional bad-pixel coordinates.

None
offx int

Crop-center offsets.

0
offy int

Crop-center offsets.

0
clip_fact float

Relative sigma threshold for frame selection.

0.5
apod bool

Whether to apodize and sky-subtract frames.

True
sky bool

Whether to apodize and sky-subtract frames.

True
window float or None

Apodization width.

None
f_kernel int or None

Median-filter kernel size for centering.

3
verbose bool

Whether to print progress.

False
ihdu int

FITS HDU containing the data.

0
display bool

Whether to display cleaning parameters.

False

Returns:

Type Description
ndarray

Cube with shape (ndit, nlambda, isz, isz).

Source code in src/amical/ifu.py
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
def clean_data(
    list_file,
    isz=256,
    r1=100,
    dr=10,
    edge=0,
    bad_map=None,
    add_bad=None,
    offx=0,
    offy=0,
    clip_fact=0.5,
    apod=True,
    sky=True,
    window=None,
    f_kernel=3,
    verbose=False,
    ihdu=0,
    display=False,
):
    """Clean IFU files and reshape their frames into a four-dimensional cube.

    Parameters
    ----------
    list_file : list of str or path-like
        IFU FITS files.
    isz : int, default=256
        Crop size.
    r1, dr : int, default=100, 10
        Sky-ring parameters.
    edge : int, default=0
        Detector-edge width to remove.
    bad_map : numpy.ndarray or None, default=None
        Bad-pixel map.
    add_bad : list or None, default=None
        Additional bad-pixel coordinates.
    offx, offy : int, default=0
        Crop-center offsets.
    clip_fact : float, default=0.5
        Relative sigma threshold for frame selection.
    apod, sky : bool, default=True
        Whether to apodize and sky-subtract frames.
    window : float or None, default=None
        Apodization width.
    f_kernel : int or None, default=3
        Median-filter kernel size for centering.
    verbose : bool, default=False
        Whether to print progress.
    ihdu : int, default=0
        FITS HDU containing the data.
    display : bool, default=False
        Whether to display cleaning parameters.

    Returns
    -------
    numpy.ndarray
        Cube with shape (ndit, nlambda, isz, isz).
    """

    clean_param = {
        "isz": isz,
        "r1": r1,
        "dr": dr,
        "edge": edge,
        "clip": False,
        "bad_map": bad_map,
        "add_bad": add_bad,
        "offx": offx,
        "offy": offy,
        "clip_fact": clip_fact,
        "apod": apod,
        "sky": sky,
        "window": window,
        "f_kernel": f_kernel,
        "verbose": verbose,
        "ihdu": ihdu,
        "display": display,
    }

    # Add check to create default add_bad list (not use mutable data)
    if add_bad is None:
        add_bad = []

    with fits.open(list_file[0]) as fd:
        hdr = fd[0].header

    nlambda = hdr["NAXIS3"]
    nframe = len(list_file)

    cube_lambda = np.zeros([nframe, nlambda, isz, isz])

    for i in track(
        range(len(list_file)),
        description="Format/clean IFU ({})".format(hdr["OBJECT"]),
    ):
        cube_cleaned = select_clean_data(list_file[i], **clean_param)
        cube_lambda[i] = cube_cleaned

    return cube_lambda

get_lambda(i_wl=None, filtname='YH', instrument='SPHERE-IFS')

Display and return wavelengths for the selected IFU channels.

Parameters:

Name Type Description Default
i_wl int or list of int or None

One channel, a two-index channel range, or all channels.

None
filtname str

IFU filter name.

"YH"
instrument str

Instrument name.

"SPHERE-IFS"

Returns:

Type Description
float, numpy.ndarray, or None

Selected wavelength values in micrometres, or None when unavailable.

Source code in src/amical/ifu.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def get_lambda(i_wl=None, filtname="YH", instrument="SPHERE-IFS"):
    """Display and return wavelengths for the selected IFU channels.

    Parameters
    ----------
    i_wl : int or list of int or None, default=None
        One channel, a two-index channel range, or all channels.
    filtname : str, default="YH"
        IFU filter name.
    instrument : str, default="SPHERE-IFS"
        Instrument name.

    Returns
    -------
    float, numpy.ndarray, or None
        Selected wavelength values in micrometres, or None when unavailable.
    """
    wl = get_wavelength(instrument, filtname) * 1e6

    if np.isnan(wl).any():
        return None

    print(f"\nInstrument: {instrument}, spectral range: {filtname}")
    print("-----------------------------")
    print(
        f"spectral coverage: {wl[0]:2.2f} - {wl[-1]:2.2f} µm (step = {np.diff(wl)[0]:2.2f})"
    )

    one_wl = True
    if isinstance(i_wl, list):
        one_wl = False
        wl_range = wl[i_wl[0] : i_wl[1]]
        sp_range = np.arange(i_wl[0], i_wl[1], 1)
    elif i_wl is None:
        one_wl = False
        sp_range = np.arange(len(wl))
        wl_range = wl

    plt.figure(figsize=(4, 3))
    plt.title("--- SPECTRAL INFORMATION (IFU)---")
    plt.plot(wl, label="All spectral channels")
    if one_wl:
        plt.plot(
            np.arange(len(wl))[i_wl],
            wl[i_wl],
            "ro",
            label=f"Selected ({wl[i_wl]:2.2f} µm)",
        )
    else:
        plt.plot(
            sp_range,
            wl_range,
            lw=5,
            alpha=0.5,
            label=f"Selected ({wl_range[0]:2.2f}-{wl_range[-1]:2.2f} µm)",
        )
    plt.legend()
    plt.xlabel("Spectral channel")
    plt.ylabel("Wavelength [µm]")
    plt.tight_layout()

    if one_wl:
        output = np.round(wl[i_wl], 2)
    else:
        output = np.round(wl_range, 2)
    return output