spectral_rings_fitter

This module’s scope is to find rings within tridimensional Fabry-Pérot spectrographs.

Example:

>>> import tuna
>>> raw = tuna.io.read ( "tuna/test/unit/unit_io/adhoc.ad3" )
>>> rings = tuna.plugins.run ( "Ring center finder" ) ( data = raw )
>>> sorted ( list ( rings.keys ( ) ) )
['concentric_rings', 'construction', 'gradient', 'gradients', 'lower_percentile_regions', 'ridge', 'ring_fit', 'ring_fit_parameters', 'ring_pixel_sets', 'rings', 'upper_percentile_regions']
>>> rings [ 'rings' ]
[(218.56306556317449, 256.97877557329144, 231.82699113784105, [0]), (219.14654183804043, 254.87497666726719, 110.1292761603854, [1]), (190.48575616356123, 248.81898301262672, 338.64377512691351, [2, 3])]
tuna.tools.spectral_rings_fitter.circle(center, radius, thickness, shape)[source]

This function’s goal is to generate an array with the value 1 for every pixel that is “thickness” distant to a circle with the input radius and center.

Parameters:

  • center : tuple of two floats

    Containing the coordinates for the circle center.

  • radius : float

  • thickness : float

    Each pixel’s distance to the center is calculated; if this distance minus the radius is less than or equal to the thickness, then the pixel receives the value 1.

  • shape : tuple of integers

    The dimensions for the resulting array.

tuna.tools.spectral_rings_fitter.find_rings(data: numpy.ndarray, min_rings: int=1, plane: int=None, ipython: object=None, plot_log: bool=False) → dict[source]

Attempts to find rings contained in a 3D numpy ndarray input.

Parameters:

  • data : numpy.ndarray

    A tridimensional spectrogram. This parameter can also be a Tuna can.

  • min_rings : integer

    This is the minimal number of rings expected to be found.

  • plane : integer : None

    This is the index in the cube for the spectrograph whose rings the user wants. If no plane is specified, all planes will be search (from 0 onwards) until at least two rings are found in a plane.

  • ipython : object : None

    Contains a reference to the ipython object, in case it exists.

  • plot_log : boolean : False

    Flags whether to output plots of the intermediary products. Even when not plotting, all numpy arrays are accessible in the result structure.

Returns:

  • dict

    With the following keys:

    • ‘array’ : 2D numpy.ndarray where pixels in the ring have value 1 and other pixels have value 0.
    • ‘center’ : a tuple of 2 floats, where the first is the column and the second is the row of the most probable locations for the center of that ring.
    • ‘radius’ : a float with the average value of the distance of the ring pixels to its center.
    • ‘construction’ : a list of numpy arrays containing the geometric construction that led to the estimated center and radius used in the fit.
    • ‘pixel_set’ : a list of numpy arrays containing the segmented pixel sets corresponding to each identified ring.
tuna.tools.spectral_rings_fitter.fit_circle(center_col, center_row, radius, data, function, ridge_thickness=1)[source]

This function’s goal is to fit a circle to the input data.

Parameters:

  • center_col : float

    The column coordinate of the center.

  • center_row : float

    The row coordinate of the center.

  • radius : float

  • data : numpy.ndarray

  • function : object

    A reference to the function to be used for fitting.

  • ridge_thickness : float : 1

    The thickness of the ring to be fitted to the data.

tuna.tools.spectral_rings_fitter.least_circle(p, args)[source]

This function’s goal is to wrap around a call to the function circle, so that it is called according to mpyfit’s API.

Parameters:

  • p : tuple

    Contains parameters used to call the function.

  • args : tuple

    Contains parameters used to call the function.

Returns:

  • residue.flatten ( ) : numpy.ndarray

    With the fitted circle.

class tuna.tools.spectral_rings_fitter.rings_finder(array, plane, ipython, plot_log)[source]

This class’ responsibility is to find all rings contained in a data cube.

Its constructor expects the following parameters:

  • array : numpy.ndarray

    Containing the data where ring structures are to be found.

  • plane : integer

    The index for the plane where to search for the ring.

  • ipython : object

    A reference to a ipython object, so plots produced by this module won’t suppress previous plots.

  • plot_log : boolean

    If set to True, will spawn plots of intermediary products, as they are produced.

aggregate_concentric_rings()[source]

This method’s goal is to construct the geometric description of the concentric ring structure.

The most abstract and relevant information is the following structure: ( center, radii ), where center is a tuple of floats and radii is a list of floats.

Each spectrograph should have a single result of this kind, which is generated here and stored in self.concentric_rings.

aggregate_fits()[source]

This method’s goal is to coalesce all circles fitted in the minimum number of geometric entities.

After fitting circles to pixel sets, some fits will correspond to the same ring. These must be aggregated into single results.

construct_ring_center(pixel_set)[source]

This method’s goal is to estimate the center and radius of a circle that is osculatory to the curve contained in the pixel_set.

Parameters:

  • pixel_set : numpy.ndarray

    Bidimensional array, where each pixel has either a 0 or a 1 as value.

Returns:

  • center : tuple of 2 floats

    Containing the column and row “coordinates” for the center.

  • radius : float

    The radius of this center.

execute()[source]

This method’s goal is to run the main algorithm:

  1. segment the image in ring and non-ring regions.
  2. Create a separate array for each individual ring.
  3. Calculate the center and the average radius.
find_max_pair(pixel_set)[source]

This method’s goal is to find the two pixels in the input set that are maximally distant to each other.

Parameters:

  • pixel_set : numpy.ndarray

    An array where zeros indicate lack of points, and ones indicate presence of points.

Returns:

  • max_pair : tuple of 2 tuples, of 2 integers each

    Contains the coordinates of the two points maximally distant.

find_min_pixel(pixel_set, line)[source]

This method’s goal is to find the pixel that has the minimal distance to the input line.

Parameters:

  • line : sympy.Line

    The line regarding which we want to find the closest pixel in a set.

  • pixel_set : numpy.ndarray

    The set of pixels of which we want the one closest to the input line.

Returns:

  • min_pixel : tuple of 2 integers

    Containing the column and row coordinates for the pixel in the input set that is closest to the input line.

  • concurrent_extreme_min : sympy.Point

    The point on the input line where is the projection of the pixel in the input pixel_set that is closest to the input line.

find_upper_percentile(gradient)[source]

Tries to find the maximum percentile that contains at least 10 % of the pixels.

fit_circles()[source]

This method’s goal is to fit circles to the data.

plot_sympy_line(array, sympy_line, color)[source]

This method’s goal is to add a line to an array. It expects to receive an array where pixels that have points have non-null value. From a line specified as a Sympy object, it will color pixels in the array using the value for color.

Parameters:

  • array : numpy.ndarray

    Containing the data where the line will be drawn in-place.

  • sympy_line : sympy.Line

    An object describing the geometry of the line to be drawn.

  • color : integer

    The value to attribute to each pixel in the input array that is crossed by the geometric input line.

remove_lumped_pixel_sets(pixel_sets)[source]

For some cubes, in some planes, the central region has many pixels that do not belong to a ring, but are identified as part of the ridge. This is possibly due to a “nascent” ring in that plane. This function identifies such regions and removes them from the returned set.

Parameters:

  • pixel_sets : list of numpy.ndarrays

    Containing disjoint pixel sets.

ridgeness(upper, lower, col, row, threshold=1)[source]

Returns 1 if point at col, row has threshold neighbours that is 1 in both upper and lower arrays.

Parameters:

  • upper : numpy.ndarray

    Should contain the array with a higher percentile gradient region.

  • lower : numpy.ndarray

    Should contain the array with a lower percentile gradient region.

  • col : integer

    The column where the pixel’s ridgeness is to be assessed.

  • row : integer

    The row where the pixel’s ridgeness is to be assessed.

  • threshold : integer : 1

    The minimum number of neighbours in each region that a pixel must possess to be considered a “ridge” pixel.

Returns:

  • unnamed variable : integer

    Will be 0 for pixels in the “ridge” and 0 otherwise.

segment()[source]

This method’s goal is to segment the image in ring and non-ring regions.

This is accomplished applying the numpy.gradient method on the input array; and then obtaining the lower percentile region (the regions in the data where the gradient is minimal) and the higher percentile region.

The very “middle” of each ring will consist of the pixels where the gradient is in the process of changing sign; and therefore, finding these pixels (the “ridge”), is equivalent to finding the “middle” of the rings.

separate_rings()[source]

This method’s goal is to create distinct array objects for each disjoint pixel set in the current self.result [ ‘ridge’ ] array.