Source code for mirar.processors.skyportal.thumbnail

"""
Function for converting a FITS image to a skyportal "thumbnail".
"""

import base64
import io

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from astropy.visualization import (
    AsymmetricPercentileInterval,
    ImageNormalize,
    LinearStretch,
    LogStretch,
)

matplotlib.use("agg")


[docs] def make_thumbnail( image_data: np.ndarray, linear_stretch: bool = False, ) -> str: """ Util function to convert a FITS image to a PNG image Skyportal requires, to quote the API: base64-encoded PNG image file contents. Image size must be between 16px and 500px on a side. :param image_data: Image data :param linear_stretch: boolean whether to use a linear stretch (default is log) :return: Skyportal-compliant PNG image string """ with io.BytesIO() as buff: fig = plt.figure() fig.set_size_inches(4, 4, forward=False) ax_1 = plt.Axes(fig, [0.0, 0.0, 1.0, 1.0]) ax_1.set_axis_off() fig.add_axes(ax_1) # replace nans with median: img = np.array(image_data) # replace dubiously large values xl_mask = np.greater(np.abs(img), 1e20, where=~np.isnan(img)) if img[xl_mask].any(): img[xl_mask] = np.nan if np.isnan(img).any(): median = float(np.nanmean(img.flatten())) img = np.nan_to_num(img, nan=median) norm = ImageNormalize( img, stretch=LinearStretch() if linear_stretch else LogStretch(), ) img_norm = norm(img) normalizer = AsymmetricPercentileInterval( lower_percentile=1, upper_percentile=100 ) vmin, vmax = normalizer.get_limits(img_norm) ax_1.imshow(img_norm, cmap="bone", origin="lower", vmin=vmin, vmax=vmax) plt.savefig(buff, dpi=42) buff.seek(0) plt.close() fritz_thumbnail = base64.b64encode(buff.read()).decode("utf-8") return fritz_thumbnail