astrolab.spectroscopy module

This package contains a list of functions specifically designed to analyse images with spectra in them. These functions are intended to be used in the Fraunhofer Lines and Grating Spectroscopy experiments.

Note

The idea behind the find_angle and rotate_spectrum functions of this module were conceived of by Ayush Gurule, an Ashoka undergraduate from the UG25 (2022-2026) batch. The code has changed significantly since his implementation, but the basic idea is essentially the same.

astrolab.spectroscopy.find_angle(image_array, threshold=0.1, star=None, search=500, print_log=False, fig=None, ax=None)[source]

Find angle by which to rotate an image with a spectrum so that the spectrum is horizontal.

The function works by fitting a straight line to the brightest points in the pixel, and finding its slope. The arctangent of this slope is used to find the angle by which the image must be rotated.

NOTE: The algorithm assumes the spectrum faces rightward. If this is not the case, first flip the image using the flip function.

Parameters

image_array: array_like

A 2D array which serves as the image data.

threshold: float < 1, default: 0.1

Threshold value (as a fraction of the maximum value in the image) below which all data-points are ignored.

star: [int, int] or None, default: None

x and y pixel coordinates of the star’s rough location to refine search for the brightest pixel. # TODO: Incorporate this. If None is provided, the brightest pixel is used.

search: float, default: 500

Search “radius” in pixels. The brightest pixel will be found in the range (star_pos[0] +/- search, star_pos[1]+/- search). # TODO: Incorporate this.

print_log: bool, default: False

Provides option to print a log to debug your code. In this case, it will plot the data-points above the threshold, and the trendline that is fit through it.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

angle: float

Value of angle by which the image is to be rotated.

Usage

>>> this_angle = find_angle(this_data, threshold=0.22)
astrolab.spectroscopy.rotate_spectrum(image_array, angle=None, origin=None, threshold=0.1, expand=False, fill=False, print_log=False)[source]

Rotate an image by an angle around an origin. If no origin is provided, it rotates about the centre of the image. If no angle is provided, the angle is computed using imaging.find_angle. The origin could be the location of a star, found as the output of the imaging.find_star function.

Parameters

image_array: array_like

A 2D array which serves as the image data.

angle: float or None, default: None

Angle by which to rotate the image.

origin: [int, int] or None, default: None

x and y pixel coordinates of the star’s exact location.

threshold: float < 1, default: 0.1

Threshold value (as a fraction of the maximum value in the image) below which all data-points are ignored.

expand: bool, default: False

Expands the output image to make it large enough to hold the entire rotated image. Note that this flag assumes rotation about the centre, and no translation.

fill: bool, default: False

Fill area outside the rotated image. If True, this area is filled with the median value of the image.

print_log: bool, default: False

Provides option to print a log to debug your code. In this case, it will display the rotated array.

Returns

rotated_array: array_like

A 2D array. The rotated array.

Warns

UserWarning

If expand=True and origin is provided.

Usage

>>> rotated_array = rotate_spectrum(this_data, angle=23.0, star=[1052,1002])
>>> rotated_array = rotate_spectrum(this_data, star=[1052,1002], threshold=0.22)
astrolab.spectroscopy.crop_spectrum(image_array, origin=None, offset=100, width=1500, height=200, print_log=False, cmap='Greys_r')[source]

Crop an image around a star, with offset pixels to the left, a total width of width and height height. The star location can be found using the imaging.find_star function. If no star location is provided, it simply finds the brightest pixel.

Parameters

image_array: array_like

A 2D array which serves as the image data.

origin: [int, int] or None, default: None

x and y pixel coordinates of the origin. The cropped image starts from offset pixels to the left of this point, with a total width of width, and a total height of height about this point. By default, the centre of the image is chosen.

offset: int, default: 100

Space to the left of star in cropped image.

width: int, default: 1500

Width of the cropped image.

height: int, default: 200

Height of the cropped image.

print_log: bool, default: False

Provides option to print a log to debug your code. In this case, it displays the cropped array.

cmap: str, default: “Greys_r”

A string containing the colormap title if print_log=True and a plot is produced. Should be one of the colormaps used by matplotlib: https://matplotlib.org/stable/users/explain/colors/colormaps.html.

Returns

cropped_array: array_like

A 2D array. The cropped array.

Raises

ValueError

If the offset is larger than half the image dimension in either direction.

Warns

UserWarning

If width is larger than the image’s width.

UserWarning

If height is larger than the image height.

UserWarning

If there isn’t enough space between the star and the left/bottom of the image.

Usage

>>> cropped_array = crop_spectrum(this_data, origin=[1052,1002], offset=100, width=2500, height=400)
astrolab.spectroscopy.get_spectrum(image_array, sub_bkg=False, lower_lim=None, upper_lim=None, n_rows=None, n_sigma=3, print_log=False, fig=None, ax=None)[source]

Produce a spectrum from a cropped image, with the option to compute and subtract the background.

Parameters

image_array: array_like

A 2D array which serves as the image data.

sub_bkg: bool, default: False

Compute and subtract background from spectrum.

lower_lim: int or None, default: None

Lower row limit of spectrum. All pixel rows below this are taken to be background.

upper_lim: int or None, default: None

Upper row limit of spectrum. All pixel rows above this are taken to be background.

n_rows: int or [int, int] or None, default: None

Number of rows to consider for the background. If None is provided, all rows below the lower limit and above the upper limit are considered as background. If a single integer is provided, n_rows below and above are considered respectively. If a two-element list is provided, the first element represents the number of rows below the lower limit and the second the number of rows above the upper limit.

n_sigma: float, default: 3.0

Width of the spectrum beyond which background can be taken.

print_log: bool, default: False

Provides option to print a log to debug your code. In this case, it plots the point-spread function of the star if n_sigma is not None, or the lower and upper limits if those are provided. It also plots the spectrum before and after background subtraction.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

spectrum: array_like

A 1D array with information of the intensity as a function of pixel.

Raises

ValueError

If n_rows is anything other than NoneType, a single number, or a 2-element list.

Usage

>>> this_spectrum = get_spectrum(cropped_array, n_sigma=4)
astrolab.spectroscopy.plot_ref(wvs=[6562.79, 4861.35, 4340.472, 4101.734], wvnames=['$\\alpha$', '$\\beta$', '$\\gamma$', '$\\delta$'], color='darkgoldenrod', lw=0.5, text_rotation=90, fig=None, ax=None)[source]

Plot vertical lines of a reference spectrum. By default, the Balmer lines are plotted in Angstroms.

Parameters

wvs: array_like, default: [6562.79, 4861.35, 4340.472, 4101.734] (Balmer series)

A list of wavelengths.

wvnames: array_like, default: [r”\(\alpha\)”,r”\(\beta\)”,r”\(\gamma\)”, r”\(\delta\)”] (Balmer series)

A list of wavelength names.

color: str, default: ‘darkgoldenrod’

Colour of this plot. Must be one of the matplotlib “named colors”: https://matplotlib.org/stable/gallery/color/named_colors.html.

lw: float, default: 0.5

Linewidth for the vertical reference lines.

text_rotation: float, default: 90

Angle in degrees by which to rotate text labels.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

matplotlib.image.AxesImage (A plot).

Usage

>>> plot_ref(this_spectrum, fig=fig, ax=ax)
astrolab.spectroscopy.plot_fraunhofer(wvs=[7594.0, 6867.0, 6563.0, 5895.0, 5270.0, 5184.0, 4861.0, 4308.0, 3968.0], wvnames=['A', 'B', 'C', 'D$_1$', 'E$_2$', 'b$_1$', 'F', 'G', 'H'], color='firebrick', lw=0.5, text_rotation=90, fig=None, ax=None)[source]

Plot vertical lines of a reference spectrum. By default, the Balmer lines are plotted in Angstroms.

NOTE: This is just a wrapper function around the plot_ref function.

Parameters

wvs: array_like, default: [7594.0, 6867.0, 6563.0, 5895.0, 5270.0, 5184.0, 4861.0, 4308.0, 3968.0] (Fraunhofer lines).

A list of wavelengths.

wvnames: array_like, default: [“A”, “B”, “C”, r”D\(_1\)”, r”E\(_2\)”, r”b\(_1\)”, “F”, “G”, “H”] (Fraunhofer lines)

A list of wavelength names.

color: str, default: ‘darkgoldenrod’

Colour of this plot. Must be one of the matplotlib “named colors”: https://matplotlib.org/stable/gallery/color/named_colors.html.

lw: float, default: 0.5

Linewidth for the vertical reference lines.

text_rotation: float, default: 90

Angle in degrees by which to rotate text labels.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

matplotlib.image.AxesImage (A plot).

Usage

>>> plot_fraunhofer(this_spectrum, fig=fig, ax=ax)
astrolab.spectroscopy.calibrate(spectrum, lineA, lineB=None, wvPerPix=None, print_log=False, lw=0.5, xlim=None, ylim=None, fig=None, ax=None)[source]

Calibrate a spectrum using either one-point or two-point calibration, assuming the relation between wavelength and pixel is linear.

If only the spectrum and details of one point are given, one-point calibration is done using the value of wvPerPix provided.

If the data for two points are given, wvPerPix is calculated using both points.

Parameters

spectrum: array_list

An array of spectrum values.

lineA: list [int, float]

First element (integer) is the pixel number, second element (float) is the wavelength.

lineB: list [int, float] or None, default: None

Required for two-point calibration. First element is the pixel number, second element is the wavelength.

wvPerPix: float or None, default: None

Required for one-point calibration. Number of wavelength units (angstroms or nanometres) per pixel. If two-point calibration is done, then this quantity is computed and returned. If both lineA and lineB is provided in addition to wvPerPix, wvPerPix is ignored and two-point calibration is done.

print_log: bool, default: False

Provides option to print a log to debug your code. In this case, it plots the calibrated spectrum along with vertical lines to mark lineA and (if provided) lineB.

lw: float, default 0.5

Linewidth for the vertical calibration lines.

xlim, ylim: [float, float] or None, default: None

Set the x or y limits of the plot. First element is the lower limit, and the second is the upper limit. If None is proved, default plot limits are used.

fig: matplotlib figure object, default: None

Figure on which to plot the result. By default, a new figure is created.

ax: matplotlib axes object, default: None

Axes on which to plot the result. By default, a new axis is created.

Returns

wavelengths: array_like

An array of wavelengths for every pixel value.

wvPerPix: float

Value of number of wavelength units per pixel. IMPORTANT: Only returned if 2-point calibration is being done.

Raises

ValueError

If lineA is not provided.

ValueError

If lineB is not provided and wvPerPix is not provided.

Warns

UserWarning

If both lineA and lineB are provided and wvPerPix is provided. In this case, wvPerPix is ignored.

Usage

>>> this_wvs, this_wvPerPix = calibrate(this_spectrum, lineA=[100,0], lineB=[767,486.135]) # For two-point calibration
>>> this_wvs = calibrate(this_spectrum, lineA=[100,0], wvPerPix=0.48) # For 1-point calibration