Source code for sunpy.net.helio.chaincode

"""
This module implements a function to understand chaincodes from HELIO.
"""
import numpy as np

__all__ = ["Chaincode"]


[docs] class Chaincode(np.ndarray): """ A tool to infer some information from chaincodes produced by HELIO Feature Catalogue or Heliophysics Events Knowledgebase. Parameters ---------- origin : `numpy.ndarray`, `list` The 2 points of the origin of the chaincode. chaincode : `str` A list of the numbers (0-7) that indicate the path of the chaincode. 0 moves horizontally to the left and the rest follows anticlockwise. xdelta : `float`, optional The scale to convert between pixels and flat coordinates. Defaults to 1.0. ydelta : `float`, optional The scale to convert between pixels and flat coordinates. Defaults to 1.0 Returns ------- `numpy.ndarray` An array containing all the x and y coordinates of the chaincode e.g., ``[[x0, x1, x2, ..., xn], [y0 ,y1, y2, ..., yn]]``. Examples -------- >>> from sunpy.net.helio.chaincode import Chaincode >>> cc = Chaincode([-88, 812], "44464655567670006011212222324", ... xdelta=2.629, ydelta=2.629) >>> fig = plt.figure() # doctest: +SKIP >>> ax = fig.add_subplot(111) # doctest: +SKIP >>> x,y = zip(cc.coordinates) # doctest: +SKIP >>> ax.plot(x[0], y[0], 'go-') # doctest: +SKIP >>> fig.show() # doctest: +SKIP """ def __new__(cls, origin, chaincode, **kwargs): if isinstance(origin, list): obj = np.asarray(origin).view(cls) elif isinstance(origin, np.ndarray): obj = origin.view(cls) else: raise TypeError('Invalid input') return obj def __init__(self, origin, chaincode, xdelta=1, ydelta=1): x_steps = [-1, -1, 0, 1, 1, 1, 0, -1] y_steps = [0, -1, -1, -1, 0, 1, 1, 1] self.coordinates = np.ndarray((2, len(chaincode) + 1)) self.coordinates[:, 0] = origin if chaincode.isdigit(): for index, step in enumerate(chaincode): self.coordinates[:, index + 1] = self.coordinates[:, index] + \ [[x_steps[int(step)] * xdelta, y_steps[int(step)] * ydelta]]
[docs] def matchend(self, end): return np.all(np.equal(self.coordinates[:, -1], np.asarray(end)))
[docs] def matchany(self, coordinates, index): return np.all( np.allclose(self.coordinates[:, index], np.asarray(coordinates)) )
[docs] def boundingbox(self): """ Extract the coordinates of the chaincode. Returns in the form of ``[[x0, x1], [y0, y1]]``. """ bb = np.zeros((2, 2)) bb[:, 0] = self.coordinates.min(1) bb[:, 1] = self.coordinates.max(1) return bb
[docs] def area(self): raise NotImplementedError
[docs] def length(self): raise NotImplementedError
[docs] def sub_boundingbox(self, xedge=None, yedge=None): """ Extract the x or y boundaries of the chaincode from a defined limits ``xedge`` or ``yedge``. Parameters ---------- xedge : list, optional A list of two values to check. yedge : list, optional A list of two values to check. """ if xedge is not None: edge = xedge IndexMask = 0 IndexValue = 1 elif yedge is not None: edge = yedge IndexMask = 1 IndexValue = 0 else: raise ValueError("Please input either `xedge` or `yedge`") mask = (self.coordinates[IndexMask, :] >= edge[0]) & (self.coordinates[IndexMask, :] <= edge[1]) mx = np.ma.masked_array(self.coordinates[IndexValue, :], mask=(~mask)) return [mx.min(), mx.max()]