Convenience utilities

STDPipe also contains a number of convenience utilities that help solving some of maybe minor but still quite important problems you may encounter during data analysis and visualization.

Splitting the image into sub-images

Often you have quite large image, with significant variation of PSF, background etc over it. Such frames are not very well suited for image subtraction, as convolution kernel will become unstable and / or unable to properly match the resolutions of image and template.

So, for such images, it is better to split them into smaller pieces and do image subtraction on the latters. When splitting, however, you have to also split the mask, update WCS solution and FITS header, maybe select a subset of catalogue stars, etc etc. And we have a dedicated routine for doing just that!

# Crop the image (mask, header, WCS, object list and catalogue too) into 4 (2x2) pieces,
# adding 10 pixels wide overlap between them.
for i, x0, y0, image1, mask1, header1, wcs1, obj1, cat1 in pipeline.split_image(image, nx=2,
             mask=mask, header=header, wcs=wcs, obj=obj, cat=cat, overlap=10,
             get_index=True, get_origin=True, verbose=True):
    # We got a sub-image
    print('Subimage', i, 'has origin at', x0, y0, 'shape', image1.shape, 'and contains', len(obj1),
             'objects from original image')

    # Do something useful on the sub-images here!
    pass
stdpipe.pipeline.split_image(image, *args, nx=1, ny=None, overlap=0, xmin=None, xmax=None, ymin=None, ymax=None, get_index=False, get_origin=False, verbose=False, **kwargs)[source]

Generator that splits an image into nx × ny sub-image blocks.

Also optionally yields sub-setted copies of any additional images, FITS headers, WCS solutions, PSF models, catalogues, or object lists passed as positional or keyword arguments. FITS headers and WCS solutions are adjusted to reflect the sub-image astrometry. Tables are filtered to rows whose x/y, ra/dec, or RAJ2000/DEJ2000 coordinates fall inside the sub-image.

Sub-images may optionally overlap by overlap pixels in every direction, so that each part of the original image appears far from an edge in at least one block.

Parameters:
imagendarray

2D image to split.

*args

Additional images, headers, WCS objects, or tables to crop alongside image.

nxint, optional

Number of sub-images along the x axis.

nyint, optional

Number of sub-images along the y axis. Defaults to nx.

overlapint, optional

Number of pixels by which adjacent blocks overlap.

xmin, xmaxint, optional

Horizontal extent of the region to split (defaults to full image width).

ymin, ymaxint, optional

Vertical extent of the region to split (defaults to full image height).

get_indexbool, optional

If True, prepend the sub-image index (0-based) to each yielded list.

get_originbool, optional

If True, include the sub-image origin (x1, y1) in each yielded list.

verbosebool or callable, optional

Whether to show verbose messages. May be boolean or a print-like callable.

**kwargs

Additional images, headers, WCS objects, or tables to crop.

Yields:
list

Each element is a list built from (in order):

  • sub-image index, if get_index=True

  • origin x1, y1, if get_origin=True

  • cropped image

  • cropped versions of each *args and **kwargs entry

Extracting the time from FITS header

We have a routine that helps extracting the information on time of observations from FITS headers.

stdpipe.utils.get_obs_time(header=None, filename=None, string=None, get_datetime=False, verbose=False)[source]

Extract date and time of observations from a FITS header or string.

Tries the following FITS keywords in order: DATE-OBS, DATEOBS, DATE, TIME-OBS, TIMEOBS, UT, MJD, JD.

Parameters:
headerastropy.io.fits.Header, optional

FITS header containing observation time keywords.

filenamestr, optional

Path to a FITS file; its header is loaded if header is not provided.

stringstr, optional

Time string to parse directly instead of using a FITS header.

get_datetimebool, optional

If True, return a datetime.datetime instead of astropy.time.Time.

verbosebool or callable, optional

Whether to show verbose messages. May be boolean or a print-like callable.

Returns:
astropy.time.Time or datetime.datetime or None

Parsed observation time, or None if parsing fails.

Displaying the images

We have a convenience image plotting function stdpipe.plots.imshow() what may be used as a drop-in replacement for matplotlib.pyplot.imshow(), but also supports percentile-based intensity min/max levels, various intensity stretching options (linear, asinh, log, etc), built-in colorbar that plays nicely with sub-plots, and an option to hide the axes around the image.

# Plot the image with asinh intensity scaling between [0.5, 99.5] quantiles, and a color bar
plots.imshow(image, qq=[0.5, 99.5], stretch='asinh', show_colorbar=True)
stdpipe.plots.imshow(image, qq=None, mask=None, show_colorbar=True, show_axis=True, stretch='linear', r0=None, ax=None, max_plot_size=4096, fast=True, xlim=None, ylim=None, **kwargs)[source]

Display a 2D image with percentile-based intensity scaling.

Parameters:
imagendarray

2D array to display.

qqlist of float, optional

Two-element [low, high] percentile range for intensity normalization. Default is [0.5, 99.5]. Overridden by explicit vmin / vmax.

maskndarray of bool, optional

Boolean mask; masked pixels are excluded from intensity normalization.

show_colorbarbool, optional

If True, display a colorbar alongside the image.

show_axisbool, optional

If True, display axis ticks and labels.

stretchstr, optional

Intensity stretch: 'linear', 'log', 'asinh', 'histeq', or any stretch supported by Astropy visualization.

r0float, optional

Gaussian smoothing sigma in pixels applied before display.

axmatplotlib.axes.Axes, optional

Axes to draw on; defaults to the current axes.

max_plot_sizeint or None, optional

Images larger than this (in pixels) are downscaled for rendering. Set to None to disable. Default is 4096.

fastbool, optional

If True, use faster approximate methods for large images (subsampled percentiles, float32, FFT convolution).

xlimtuple of float, optional

(xmin, xmax) region selection in original image coordinates.

ylimtuple of float, optional

(ymin, ymax) region selection in original image coordinates.

**kwargs

Additional keyword arguments passed to matplotlib.pyplot.imshow().

Displaying 2d histograms of randomly distributed points

We also have a convenience function for plotting the images of 2d histograms of irregularly spaced data points. It may shows various statistics of the point values - means, medians, standard deviations etc, as well as display the color bar for the values, do percentile-based intensity scaling, and overlay the positions of the data points onto the histogram.

# Show the map of FWHM of detected objects using 8x8 bins and overlaying the positions
# of the objects. Also, force the image to have correct aspect ratio
plots.binned_map(obj['x'], obj['y'], obj['fwhm'], cmap='hot', bins=8, aspect='equal',
             show_colorbar=True, show_dots=True, color='blue')
stdpipe.plots.binned_map(x, y, value, bins=16, statistic='mean', qq=[0.5, 97.5], color=None, show_colorbar=True, show_axis=True, show_dots=False, ax=None, range=None, **kwargs)[source]

Plot statistical estimators binned onto a regular grid.

Parameters:
xarray_like

Abscissae of the data points.

yarray_like

Ordinates of the data points.

valuearray_like

Values to aggregate.

binsint, optional

Number of bins per axis.

statisticstr or callable, optional

Aggregation statistic: 'mean', 'median', or a callable.

qqlist of float, optional

[low, high] percentile range for color scaling. Default [0.5, 97.5]. Overridden by explicit vmin / vmax.

colorcolor, optional

Color used for the data-point overlay (requires show_dots=True).

show_colorbarbool, optional

If True, display a colorbar.

show_axisbool, optional

If True, display axis ticks and labels.

show_dotsbool, optional

If True, overlay the raw data point positions.

rangelist of list, optional

Data range [[xmin, xmax], [ymin, ymax]].

axmatplotlib.axes.Axes, optional

Axes to draw on; defaults to the current axes.

**kwargs

Additional keyword arguments passed to matplotlib.pyplot.imshow().

There is also an (a bit experimental) version of this function that adaptively bins the data to achieve more uniform distribution of points over bins, based on PowerBin package.

stdpipe.plots.adaptive_binned_map(x, y, value, target_count=50, target_sn=None, err=None, statistic='mean', method='auto', qq=[0.5, 97.5], color=None, show_colorbar=True, show_axis=True, show_dots=False, show_edges=True, ax=None, range=None, verbose=False, **kwargs)[source]

Plot statistical estimators with adaptive (density-based) binning.

Bins have variable sizes: sparse regions get larger bins, dense regions get finer resolution. Bins target approximately target_count points each, or a specified target_sn S/N ratio.

Parameters:
xarray_like

Abscissae of the data points.

yarray_like

Ordinates of the data points.

valuearray_like

Values to aggregate.

target_countint, optional

Target number of points per bin.

target_snfloat, optional

Target S/N per bin (alternative to target_count).

errarray_like, optional

Per-point value errors; required when target_sn is set.

statisticstr or callable, optional

Aggregation: 'mean', 'median', 'std', 'count', or callable.

methodstr, optional

Binning algorithm: 'auto', 'powerbin', or 'kdtree'.

qqlist of float, optional

[low, high] percentile range for color scaling. Default [0.5, 97.5].

colorcolor, optional

Color for the data-point overlay (requires show_dots=True).

show_colorbarbool, optional

If True, display a colorbar.

show_axisbool, optional

If True, display axis ticks and labels.

show_dotsbool, optional

If True, overlay the raw data point positions.

show_edgesbool, optional

If True, draw bin boundaries.

axmatplotlib.axes.Axes, optional

Axes to draw on; defaults to the current axes.

rangelist of list, optional

Data range [[xmin, xmax], [ymin, ymax]].

verbosebool, optional

If True, enable verbose output from the binning backend.

**kwargs

Additional keyword arguments passed to matplotlib.