panoptes.utils.images package

Submodules

panoptes.utils.images.bayer module

panoptes.utils.images.bayer.get_pixel_color(x, y)[source]

Given a zero-indexed x,y position, return the corresponding color.

Note

See get_rgb_data() for a description of the RGGB pattern.

Returns:one of ‘R’, ‘G1’, ‘G2’, ‘B’
Return type:str
panoptes.utils.images.bayer.get_rgb_background(fits_fn, box_size=(84, 84), filter_size=(3, 3), camera_bias=0, estimator='mean', interpolator='zoom', sigma=5, iters=5, exclude_percentile=100, return_separate=False, *args, **kwargs)[source]

Get the background for each color channel.

Most of the options are described in the photutils.Background2D page: https://photutils.readthedocs.io/en/stable/background.html#d-background-and-noise-estimation

>>> from panoptes.utils.images import fits as fits_utils
>>> fits_fn = getfixture('solved_fits_file')
>>> data = fits_utils.getdata(fits_fn)
>>> data.mean()
2236.816...
>>> rgb_back = get_rgb_background(fits_fn)
>>> rgb_back.mean()
2202.392...
>>> rgb_backs = get_rgb_background(fits_fn, return_separate=True)
>>> rgb_backs[0]
<photutils.background.background_2d.Background2D...>
>>> {color:data.background_rms_median for color, data in zip('rgb', rgb_backs)}
{'r': 20.566..., 'g': 32.787..., 'b': 23.820...}
Parameters:
  • fits_fn (str) – The filename of the FITS image.
  • box_size (tuple, optional) – The box size over which to compute the 2D-Background, default (84, 84).
  • filter_size (tuple, optional) – The filter size for determining the median, default (3, 3).
  • camera_bias (int, optional) – The built-in camera bias, default 0. A zero camera bias means the bias will be considered as part of the background.
  • estimator (str, optional) – The estimator object to use, default ‘median’.
  • interpolator (str, optional) – The interpolater object to user, default ‘zoom’.
  • sigma (int, optional) – The sigma on which to filter values, default 5.
  • iters (int, optional) – The number of iterations to sigma filter, default 5.
  • exclude_percentile (int, optional) – The percentage of the data (per channel) that can be masked, default 100 (i.e. all).
  • return_separate (bool, optional) – If the function should return a separate array for color channel, default False.
  • *args – Description
  • **kwargs – Description
Returns:

Either a single numpy array representing the entire

background, or a list of masked numpy arrays in RGB order. The background for each channel has full interploation across all pixels, but the mask covers them.

Return type:

`numpy.array`|list

panoptes.utils.images.bayer.get_rgb_data(data, separate_green=False)[source]

Get the data split into separate channels for RGB.

data can be a 2D (W x H) or 3D (N x W x H) array where W=width and H=height of the data, with N=number of frames.

The return array will be a 3 x W x H or 3 x N x W x H array.

The Bayer array defines a superpixel as a collection of 4 pixels set in a square grid:

R G
G B

ds9 and other image viewers define the coordinate axis from the lower left corner of the image, which is how a traditional x-y plane is defined and how most images would expect to look when viewed. This means that the (0, 0) coordinate position will be in the lower left corner of the image.

When the data is loaded into a numpy array the data is flipped on the vertical axis in order to maintain the same indexing/slicing features. This means the the (0, 0) coordinate position is in the upper-left corner of the array when output. When plotting this array one can use the origin='lower' option to view the array as would be expected in a normal image although this does not change the actual index.

Image dimensions:

----------------------------
x | width  | i | columns |  5208
y | height | j | rows    |  3476

Bayer pattern as seen in ds9:

                             x / j

             0     1    2     3 ... 5204 5205 5206 5207
           --------------------------------------------
      3475 |  R   G1    R    G1        R   G1    R   G1
      3474 | G2    B   G2     B       G2    B   G2    B
      3473 |  R   G1    R    G1        R   G1    R   G1
      3472 | G2    B   G2     B       G2    B   G2    B
         . |
y / i    . |
         . |
         3 |  R   G1    R    G1        R   G1    R   G1
         2 | G2    B   G2     B       G2    B   G2    B
         1 |  R   G1    R    G1        R   G1    R   G1
         0 | G2    B   G2     B       G2    B   G2    B

The RGGB super-pixels thus start in the upper-left.

Bayer pattern as seen in a numpy array:

                             x / j

             0     1    2     3 ... 5204 5205 5206 5207
           --------------------------------------------
         0 | G2    B   G2     B       G2    B   G2    B
         1 |  R   G1    R    G1        R   G1    R   G1
         2 | G2    B   G2     B       G2    B   G2    B
         3 |  R   G1    R    G1        R   G1    R   G1
         . |
y / i    . |
         . |
      3472 | G2    B   G2     B       G2    B   G2    B
      3473 |  R   G1    R    G1        R   G1    R   G1
      3474 | G2    B   G2     B       G2    B   G2    B
      3475 |  R   G1    R    G1        R   G1    R   G1

Here the RGGB super-pixels are flipped upside down.

In both cases the data is in the following format:

    | row (y) |  col (x)
--------------| ------
 R  |  odd i, |  even j
 G1 |  odd i, |   odd j
 G2 | even i, |  even j
 B  | even i, |   odd j

And a mask can therefore be generated as:

bayer[1::2, 0::2] = 1 # Red
bayer[1::2, 1::2] = 1 # Green
bayer[0::2, 0::2] = 1 # Green
bayer[0::2, 1::2] = 1 # Blue
panoptes.utils.images.bayer.get_rgb_masks(data, separate_green=False)[source]

Get the RGGB Bayer pattern for the given data.

Note

See get_rgb_data() for a description of the RGGB pattern.

Parameters:
  • data (np.array) – An array of data representing an image.
  • separate_green (bool, optional) – If the two green channels should be separated, default False.
Returns:

A 3-tuple of numpy arrays of bool type.

Return type:

tuple(np.array, np.array, np.array)

panoptes.utils.images.bayer.get_stamp_slice(x, y, stamp_size=(14, 14), ignore_superpixel=False)[source]

Get the slice around a given position with fixed Bayer pattern.

Given an x,y pixel position, get the slice object for a stamp of a given size but make sure the first position corresponds to a red-pixel. This means that x,y will not necessarily be at the center of the resulting stamp.

>>> from panoptes.utils.images import bayer
>>> # Make a super-pixel as represented in numpy (see full stamp below).
>>> superpixel = np.array(['G2', 'B', 'R', 'G1']).reshape(2, 2)
>>> superpixel
array([['G2', 'B'],
       ['R', 'G1']], dtype='<U2')
>>> # Tile it into a 5x5 grid of super-pixels, i.e. a 10x10 stamp.
>>> stamp0 = np.tile(superpixel, (5, 5))
>>> stamp0
array([['G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1', 'R', 'G1']],
      dtype='<U2')
>>> stamp1 = np.arange(100).reshape(10, 10)
>>> stamp1
array([[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
       [20, 21, 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, 88, 89],
       [90, 91, 92, 93, 94, 95, 96, 97, 98, 99]])
>>> x = 7
>>> y = 5
>>> pixel_index = (y, x)  # y=rows, x=columns
>>> stamp0[pixel_index]
'G1'
>>> stamp1[pixel_index]
57
>>> slice0 = bayer.get_stamp_slice(x, y, stamp_size=(6, 6))
>>> slice0
(slice(2, 8, None), slice(4, 10, None))
>>> stamp0[slice0]
array([['G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1'],
       ['G2', 'B', 'G2', 'B', 'G2', 'B'],
       ['R', 'G1', 'R', 'G1', 'R', 'G1']], dtype='<U2')
>>> stamp1[slice0]
array([[24, 25, 26, 27, 28, 29],
       [34, 35, 36, 37, 38, 39],
       [44, 45, 46, 47, 48, 49],
       [54, 55, 56, 57, 58, 59],
       [64, 65, 66, 67, 68, 69],
       [74, 75, 76, 77, 78, 79]])

The original index had a value of 57, which is within the center superpixel.

Notice that the resulting stamp has a super-pixel in the center and is bordered on all sides by a complete superpixel. This is required by default and an invalid size

We can use ignore_superpixel=True to get an odd-sized stamp.

>>> slice1 = bayer.get_stamp_slice(x, y, stamp_size=(5, 5), ignore_superpixel=True)
>>> slice1
(slice(3, 8, None), slice(5, 10, None))
>>> stamp0[slice1]
array([['G1', 'R', 'G1', 'R', 'G1'],
       ['B', 'G2', 'B', 'G2', 'B'],
       ['G1', 'R', 'G1', 'R', 'G1'],
       ['B', 'G2', 'B', 'G2', 'B'],
       ['G1', 'R', 'G1', 'R', 'G1']], dtype='<U2')
>>> stamp1[slice1]
array([[35, 36, 37, 38, 39],
       [45, 46, 47, 48, 49],
       [55, 56, 57, 58, 59],
       [65, 66, 67, 68, 69],
       [75, 76, 77, 78, 79]])

This puts the requested pixel in the center but does not offer any guarantees about the RGGB pattern.

Parameters:
  • x (float) – X pixel position.
  • y (float) – Y pixel position.
  • stamp_size (tuple, optional) – The size of the cutout, default (14, 14).
  • ignore_superpixel (bool) – If superpixels should be ignored, default False.
Returns:

A slice object for the data.

Return type:

slice

panoptes.utils.images.cr2 module

panoptes.utils.images.cr2.cr2_to_fits(cr2_fname, fits_fname=None, overwrite=False, headers={}, fits_headers={}, remove_cr2=False, **kwargs)[source]

Convert a CR2 file to FITS

This is a convenience function that first converts the CR2 to PGM via ~cr2_to_pgm. Also adds keyword headers to the FITS file.

Note

The intermediate PGM file is automatically removed

Parameters:
  • cr2_fname (str) – Name of the CR2 file to be converted.
  • fits_fname (str, optional) – Name of the FITS file to output. Default is None, in which case the cr2_fname is used as the base.
  • overwrite (bool, optional) – Overwrite existing FITS, default False.
  • headers (dict, optional) – Header data added to the FITS file.
  • fits_headers (dict, optional) – Header data added to the FITS file without filtering.
  • remove_cr2 (bool, optional) – If CR2 should be removed after processing, default False.
  • **kwargs – Description
Returns:

The full path to the generated FITS file.

Return type:

str

panoptes.utils.images.cr2.cr2_to_pgm(cr2_fname, pgm_fname=None, overwrite=True, *args, **kwargs)[source]

Convert CR2 file to PGM

Converts a raw Canon CR2 file to a netpbm PGM file via dcraw. Assumes dcraw is installed on the system

Note

This is a blocking call

Parameters:
  • {str} -- Name of CR2 file to convert (cr2_fname) –
  • {dict} -- Additional keywords to pass to script (**kwargs) –
Keyword Arguments:
 
  • {str} -- Name of PGM file to output, if None (pgm_fname) – use same name as CR2 (default: {None})
  • {str} -- Path to installed dcraw (default (dcraw) – {‘dcraw’})
  • {bool} -- A bool indicating if existing PGM should be overwritten (overwrite) – (default: {True})
Returns:

str – Filename of PGM that was created

panoptes.utils.images.cr2.read_exif(fname, exiftool='exiftool')[source]

Read the EXIF information

Gets the EXIF information using exiftool

Note

Assumes the exiftool is installed

Parameters:{str} -- Name of file (fname) –
Keyword Arguments:
 {str} -- Location of exiftool (default (exiftool) – {‘/usr/bin/exiftool’})
Returns:dict – Dictonary of EXIF information
panoptes.utils.images.cr2.read_pgm(fname, byteorder='>', remove_after=False)[source]

Return image data from a raw PGM file as numpy array.

Note

This is correctly processed as a Big endian even though the CR2 itself marks it as a Little endian. See the notes in Source page above as well as the comment about significant bit in the Format Spec

Parameters:
  • fname (str) – Filename of PGM to be converted
  • byteorder (str) – Big endian
  • remove_after (bool) – Delete fname file after reading, defaults to False.
  • overwrite (bool) – overwrite existing PGM or not, defaults to True
Returns:

The raw data from the PGMx

Return type:

numpy.array

panoptes.utils.images.fits module

panoptes.utils.images.fits.fpack(fits_fname, unpack=False, overwrite=True)[source]

Compress/Decompress a FITS file

Uses fpack (or funpack if unpack=True) to compress a FITS file

Parameters:
  • fits_fname ({str}) – Name of a FITS file that contains a WCS.
  • unpack ({bool}, optional) – file should decompressed instead of compressed, default False.
Returns:

Filename of compressed/decompressed file.

Return type:

str

panoptes.utils.images.fits.funpack(*args, **kwargs)[source]

Unpack a FITS file.

Note

This is a thin-wrapper around the ~fpack function with the unpack=True option specified. See ~fpack documentation for details.

Parameters:
  • *args – Arguments passed to ~fpack.
  • **kwargs – Keyword arguments passed to ~fpack.
Returns:

Path to uncompressed FITS file.

Return type:

str

panoptes.utils.images.fits.get_solve_field(fname, replace=True, overwrite=True, timeout=30, **kwargs)[source]

Convenience function to wait for solve_field to finish.

This function merely passes the fname of the image to be solved along to solve_field, which returns a subprocess.Popen object. This function then waits for that command to complete, populates a dictonary with the EXIF informaiton and returns. This is often more useful than the raw solve_field function.

Example:

>>> from panoptes.utils.images import fits as fits_utils
>>> # Get our fits filename.
>>> fits_fn = getfixture('unsolved_fits_file')
>>> # Perform the solve.
>>> solve_info = fits_utils.get_solve_field(fits_fn)
>>> # Show solved filename.
>>> solve_info['solved_fits_file']
'.../unsolved.fits'
>>> # Pass a suggested location.
>>> ra = 15.23
>>> dec = 90
>>> radius = 5 # deg
>>> solve_info = fits_utils.solve_field(fits_fn, ra=ra, dec=dec, radius=radius)
>>> # Pass kwargs to `solve-field` program.
>>> solve_kwargs = {'--pnm': '/tmp/awesome.bmp', '--overwrite': True}
>>> solve_info = fits_utils.get_solve_field(fits_fn, **solve_kwargs, skip_solved=False)
>>> assert os.path.exists('/tmp/awesome.bmp')
Parameters:
  • fname ({str}) – Name of FITS file to be solved.
  • replace (bool, optional) – Saves the WCS back to the original file, otherwise output base filename with .new extension. Default True.
  • overwrite (bool, optional) – Clobber file, default True. Required if replace=True.
  • timeout (int, optional) – The timeout for solving, default 30 seconds.
  • **kwargs ({dict}) – Options to pass to solve_field should start with .
Returns:

Keyword information from the solved field.

Return type:

dict

panoptes.utils.images.fits.get_wcsinfo(fits_fname, **kwargs)[source]

Returns the WCS information for a FITS file.

Uses the wcsinfo astrometry.net utility script to get the WCS information from a plate-solved file.

Parameters:
  • fits_fname ({str}) – Name of a FITS file that contains a WCS.
  • **kwargs – Args that can be passed to wcsinfo.
Returns:

Output as returned from wcsinfo.

Return type:

dict

Raises:

error.InvalidCommand – Raised if wcsinfo is not found (part of astrometry.net)

panoptes.utils.images.fits.getdata(fn, *args, **kwargs)[source]

Get the FITS data.

Small wrapper around astropy.io.fits.getdata to auto-determine the FITS extension. This will return the data associated with the image.

>>> fits_fn = getfixture('solved_fits_file')
>>> d0 = getdata(fits_fn)
>>> d0
array([[2215, 2169, 2200, ..., 2169, 2235, 2168],
       [2123, 2191, 2133, ..., 2212, 2127, 2217],
       [2208, 2154, 2209, ..., 2159, 2233, 2187],
       ...,
       [2120, 2201, 2120, ..., 2209, 2126, 2195],
       [2219, 2151, 2199, ..., 2173, 2214, 2166],
       [2114, 2194, 2122, ..., 2202, 2125, 2204]], dtype=uint16)
>>> d1, h1 = getdata(fits_fn, header=True)
>>> (d0 == d1).all()
True
>>> h1['FIELD']
'KIC 8462852'
Parameters:
  • fn (str) – Path to FITS file.
  • *args – Passed to astropy.io.fits.getdata.
  • **kwargs – Passed to astropy.io.fits.getdata.
Returns:

The FITS data.

Return type:

np.ndarray

panoptes.utils.images.fits.getheader(fn, *args, **kwargs)[source]

Get the FITS header.

Small wrapper around astropy.io.fits.getheader to auto-determine the FITS extension. This will return the header associated with the image. If you need the compression header information use the astropy module directly.

>>> fits_fn = getfixture('tiny_fits_file')
>>> os.path.basename(fits_fn)
'tiny.fits'
>>> header = getheader(fits_fn)
>>> header['IMAGEID']
'PAN001_XXXXXX_20160909T081152'
>>> # Works with fpacked files
>>> fits_fn = getfixture('solved_fits_file')
>>> os.path.basename(fits_fn)
'solved.fits.fz'
>>> header = getheader(fits_fn)
>>> header['IMAGEID']
'PAN001_XXXXXX_20160909T081152'
Parameters:
  • fn (str) – Path to FITS file.
  • *args – Passed to astropy.io.fits.getheader.
  • **kwargs – Passed to astropy.io.fits.getheader.
Returns:

The FITS header for the data.

Return type:

astropy.io.fits.header.Header

panoptes.utils.images.fits.getval(fn, *args, **kwargs)[source]

Get a value from the FITS header.

Small wrapper around astropy.io.fits.getval to auto-determine the FITS extension. This will return the value from the header associated with the image (not the compression header). If you need the compression header information use the astropy module directly.

>>> fits_fn = getfixture('tiny_fits_file')
>>> getval(fits_fn, 'IMAGEID')
'PAN001_XXXXXX_20160909T081152'
Parameters:fn (str) – Path to FITS file.
Returns:Value from header (with no type conversion).
Return type:str or float
panoptes.utils.images.fits.getwcs(fn, *args, **kwargs)[source]

Get the WCS for the FITS file.

Small wrapper around astropy.wcs.WCS.

>>> from panoptes.utils.images import fits as fits_utils
>>> fits_fn = getfixture('solved_fits_file')
>>> wcs = fits_utils.getwcs(fits_fn)
>>> wcs.is_celestial
True
>>> fits_fn = getfixture('unsolved_fits_file')
>>> wcs = fits_utils.getwcs(fits_fn)
>>> wcs.is_celestial
False
Parameters:
  • fn (str) – Path to FITS file.
  • *args – Passed to astropy.io.fits.getheader.
  • **kwargs – Passed to astropy.io.fits.getheader.
Returns:

The World Coordinate System information.

Return type:

astropy.wcs.WCS

panoptes.utils.images.fits.solve_field(fname, timeout=15, solve_opts=None, *args, **kwargs)[source]

Plate solves an image.

Note: This is a low-level wrapper around the underlying solve-field
program. See get_solve_field for more typical usage and examples.
Parameters:
  • fname (str, required) – Filename to solve in .fits extension.
  • timeout (int, optional) – Timeout for the solve-field command, defaults to 60 seconds.
  • solve_opts (list, optional) – List of options for solve-field.
panoptes.utils.images.fits.update_observation_headers(file_path, info)[source]

Update FITS headers with items from the Observation status.

>>> # Check the headers
>>> from panoptes.utils.images import fits as fits_utils
>>> fits_fn = getfixture('unsolved_fits_file')
>>> # Show original value
>>> fits_utils.getval(fits_fn, 'FIELD')
'KIC 8462852'
>>> info = {'field_name': 'Tabbys Star'}
>>> update_observation_headers(fits_fn, info)
>>> # Show new value
>>> fits_utils.getval(fits_fn, 'FIELD')
'Tabbys Star'
Parameters:
  • file_path (str) – Path to a FITS file.
  • info (dict) – The return dict from pocs.observatory.Observation.status, which includes basic information about the observation.
panoptes.utils.images.fits.write_fits(data, header, filename, exposure_event=None, **kwargs)[source]

Write FITS file to requested location.

>>> from panoptes.utils.images import fits as fits_utils
>>> data = np.random.normal(size=100)
>>> header = { 'FILE': 'delete_me', 'TEST': True }
>>> filename = str(getfixture('tmpdir').join('temp.fits'))
>>> fits_utils.write_fits(data, header, filename)
>>> assert os.path.exists(filename)
>>> fits_utils.getval(filename, 'FILE')
'delete_me'
>>> data2 = fits_utils.getdata(filename)
>>> assert np.array_equal(data, data2)
Parameters:
  • data (array_like) – The data to be written.
  • header (dict) – Dictionary of items to be saved in header.
  • filename (str) – Path to filename for output.
  • exposure_event (None|`threading.Event`, optional) – A threading.Event that can be triggered when the image is written.
  • kwargs (dict) – Options that are passed to the astropy.io.fits.PrimaryHDU.writeto method.

panoptes.utils.images.focus module

panoptes.utils.images.focus.focus_metric(data, merit_function='vollath_F4', **kwargs)[source]

Compute the focus metric.

Computes a focus metric on the given data using a supplied merit function. The merit function can be passed either as the name of the function (must be defined in this module) or as a callable object. Additional keyword arguments for the merit function can be passed as keyword arguments to this function.

Parameters:
  • data (numpy array) –
  • merit_function (str/callable) – panoptes.utils.images) or a callable object.
Returns:

result of calling merit function on data

Return type:

scalar

panoptes.utils.images.focus.vollath_F4(data, axis=None)[source]

Compute F4 focus metric

Computes the F_4 focus metric as defined by Vollath (1998) for the given 2D numpy array. The metric can be computed in the y axis, x axis, or the mean of the two (default).

Parameters:
  • data (numpy array) –
  • axis (str, optional, default None) – be ‘Y’/’y’, ‘X’/’x’ or None, which will calculate the F4 value for both axes and return the mean.
Returns:

Calculated F4 value for y, x axis or both

Return type:

float64

panoptes.utils.images.plot module

panoptes.utils.images.plot.add_colorbar(axes_image, size='5%', pad=0.05, orientation='vertical')[source]

Add a colorbar to the image.

This is a simple convenience function to add a colorbar to a plot generated by matplotlib.pyplot.imshow.

(Source code, png, hires.png, pdf)

../_images/panoptes-utils-images-1.png
Parameters:axes_image (matplotlib.image.AxesImage) – A matplotlib AxesImage.
panoptes.utils.images.plot.add_pixel_grid(ax1, grid_height, grid_width, show_axis_labels=True, show_superpixel=False, major_alpha=0.5, minor_alpha=0.25)[source]
panoptes.utils.images.plot.animate_stamp(d0)[source]
panoptes.utils.images.plot.get_palette(cmap='inferno')[source]

Get a palette for drawing.

Returns a copy of the colormap palette with bad pixels marked.

Parameters:cmap (str, optional) – Colormap to use, default ‘inferno’.
Returns:The colormap.
Return type:matplotlib.cm
panoptes.utils.images.plot.show_stamps(pscs, frame_idx=None, stamp_size=11, aperture_position=None, show_residual=False, stretch=None, save_name=None, show_max=False, show_pixel_grid=False, **kwargs)[source]

Module contents

panoptes.utils.images.crop_data(data, box_width=200, center=None, data_only=True, wcs=None, **kwargs)[source]

Return a cropped portion of the image

Shape is a box centered around the middle of the data

Parameters:
  • data (numpy.array) – Array of data.
  • box_width (int, optional) – Size of box width in pixels, defaults to 200px.
  • center (tuple(int, int), optional) – Crop around set of coords, default to image center.
  • data_only (bool, optional) – If True (default), return only data. If False return the Cutout2D object.
  • wcs (None|`astropy.wcs.WCS`, optional) – A valid World Coordinate System (WCS) that will be cropped along with the data if provided.
Returns:

A clipped (thumbnailed) version of the data if data_only=True, otherwise

a astropy.nddata.Cutout2D object.

Return type:

np.array

panoptes.utils.images.make_pretty_image(fname, title=None, timeout=15, img_type=None, link_path=None, **kwargs)[source]

Make a pretty image.

This will create a jpg file from either a CR2 (Canon) or FITS file.

Notes

See scripts/cr2_to_jpg.sh for CR2 process.

Parameters:
  • fname (str) – The path to the raw image.
  • title (None|str, optional) – Title to be placed on image, default None.
  • timeout (int, optional) – Timeout for conversion, default 15 seconds.
  • img_type (None|str, optional) – Image type of fname, one of ‘.cr2’ or ‘.fits’. The default is None, in which case the file extension of fname is used.
  • link_path (None|str, optional) – Path to location that image should be symlinked. The directory must exist.
  • {dict} -- Additional arguments to be passed to external script. (**kwargs) –
Returns:

str – Filename of image that was created.

Deleted Parameters:
link_latest (bool, optional): If the pretty picture should be linked to
link_path, default False.
panoptes.utils.images.make_timelapse(directory, fn_out=None, glob_pattern='20[1-9][0-9]*T[0-9]*.jpg', overwrite=False, timeout=60, **kwargs)[source]

Create a timelapse.

A timelapse is created from all the images in given directory

Parameters:
  • directory (str) – Directory containing image files.
  • fn_out (str, optional) – Full path to output file name, if not provided, defaults to directory basename.
  • glob_pattern (str, optional) – A glob file pattern of images to include, default ‘20[1-9][0-9]*T[0-9]*.jpg’, which corresponds to the observation images but excludes any pointing images. The pattern should be relative to the local directory.
  • overwrite (bool, optional) – Overwrite timelapse if exists, default False.
  • timeout (int) – Timeout for making movie, default 60 seconds.
  • **kwargs (dict) –
Returns:

Name of output file

Return type:

str

Raises:
  • error.InvalidSystemCommand – Raised if ffmpeg command is not found.
  • FileExistsError – Raised if fn_out already exists and overwrite=False.
panoptes.utils.images.mask_saturated(data, saturation_level=None, threshold=0.9, bit_depth=None, dtype=None)[source]

Convert data to a masked array with saturated values masked.

Parameters:
  • data (array_like) – The numpy data array.
  • saturation_level (scalar, optional) – The saturation level. If not given then the saturation level will be set to threshold times the maximum pixel value.
  • threshold (float, optional) – The fraction of the maximum pixel value to use as the saturation level, default 0.9.
  • bit_depth (astropy.units.Quantity or int, optional) – The effective bit depth of the data. If given the maximum pixel value will be assumed to be 2**bit_depth, otherwise an attempt will be made to infer the maximum pixel value from the data type of the data. If data is not an integer type the maximum pixel value cannot be inferred and an IllegalValue exception will be raised.
  • dtype (numpy.dtype, optional) – The requested dtype for the masked array. If not given the dtype of the masked array will be same as data.
Returns:

The masked numpy array.

Return type:

numpy.ma.array

Raises:
  • error.IllegalValue – Raised if bit_depth is an astropy.units.Quantity object but the units are not compatible with either bits or bits/pixel.
  • error.IllegalValue – Raised if neither saturation level or bit_depth are given, and data has a non integer data type.