def __init__(self, x=0, y=0, idx=None, value=None, as_int=False): """ Parameters ---------- x : number-like, Point, iterable x-coordinate or iterable type containing all coordinates. If iterable, values are assumed to be in order: (x,y,z). y : number-like, optional y-coordinate idx : int, optional Index of point. Useful for sequential coordinates; e.g. a point on a circle profile is sometimes easier to describe in terms of its index rather than x,y coords. value : number-like, optional value at point location (e.g. pixel value of an image) as_int : boolean If True, coordinates are converted to integers. """ if isinstance(x, Point): for attr in ['x', 'y', 'idx', 'value']: item = getattr(x, attr) setattr(self, attr, item) elif is_iterable(x): for attr, item in zip(['x', 'y', 'idx', 'value'], x): setattr(self, attr, item) else: self.x = x self.y = y self.idx = idx self.value = value if as_int: self.x = int(round(self.x)) self.y = int(round(self.y))
def __init__(self, x=0, y=0, z=0, idx=None, value=None, as_int=False): """ Parameters ---------- x : number-like, Point, iterable x-coordinate or iterable type containing all coordinates. If iterable, values are assumed to be in order: (x,y,z). y : number-like, optional y-coordinate idx : int, optional Index of point. Useful for sequential coordinates; e.g. a point on a circle profile is sometimes easier to describe in terms of its index rather than x,y coords. value : number-like, optional value at point location (e.g. pixel value of an image) as_int : boolean If True, coordinates are converted to integers. """ if isinstance(x, Point): for attr in self._attr_list: item = getattr(x, attr, None) setattr(self, attr, item) elif is_iterable(x): for attr, item in zip_longest(self._attr_list, x, fillvalue=0): setattr(self, attr, item) else: self.x = x self.y = y self.z = z self.idx = idx self.value = value if as_int: self.x = int(round(self.x)) self.y = int(round(self.y)) self.z = int(round(self.z))
def plot_flatness(self, plane='both', position='auto', method='varian', ax=None, show=True): """Plot the profile showing the min and max points. Parameters ---------- ax : None, matplotlib.Axes, list of matplotlib.Axes If None, the plot will be created on a new figure/axes, otherwise it will be plotted to the passed axes. show : bool If True (default), the plot will be drawn/shown at the end of the method call. Not showing the plot is useful when plotting multiple flat/sym plots. .. seealso:: :meth:`~pylinac.flatsym.BeamImage.plot_flatsym()` for ``plane``, ``position``, and ``method`` parameter info. """ position = self._convert_position(position, plane) if ax is None: ncols = 3 if _is_both_planes(plane) else 2 fig, (*axs, img_ax) = plt.subplots(ncols=ncols) self._plot_image(img_ax, plane, position) else: if not is_iterable(ax): axs = [ax,] else: axs = ax if _is_both_planes(plane): planes = ('x', 'in') else: planes = (plane, ) for ax, plane, pos in zip(axs, planes, position): profile = self._get_profile(plane, pos) flatness, dmax, dmin, lt_edge, rt_edge = self._get_flatness(profile, method) ax.plot(profile.values) ax.axhline(dmax, color='r') ax.axhline(dmin, color='r') ax.axvline(lt_edge, color='g', linestyle='-.') ax.axvline(rt_edge, color='g', linestyle='-.') self._plot_annotation(ax, flatness, method, profile, 'flat') self._plot_title(ax, plane, 'flat') self._polish_plot(ax) if show: plt.tight_layout() plt.show() return axs
def __init__(self, center_point=None, radius=None): """ Parameters ---------- center_point : Point, optional Center point of the wobble circle. radius : float, optional Radius of the wobble circle. """ if center_point is None: center_point = Point() elif isinstance(center_point, Point) or is_iterable(center_point): center_point = Point(center_point) else: raise TypeError("Circle center must be of type Point or iterable") self.center = center_point self.radius = radius
def plot_symmetry(self, plane='both', position='auto', method='varian', plot_mirror=True, show=True, ax=None): """Plot the profile, highlighting symmetry. Parameters ---------- show_mirror : bool If True (default), shows the "mirrored" profile, making visual comparison easier. ax : None, matplotlib.Axes, list containing matplotlib.Axes If None, the plot will be created on a new figure/axes, otherwise it will be plotted to the passed axes. show : bool If True (default), the plot will be drawn/shown at the end of the method call. Not showing the plot is useful when plotting multiple flat/sym plots. .. seealso:: :meth:`~pylinac.flatsym.BeamImage.plot_flatsym()` for ``plane``, ``position``, and ``method`` parameter info. """ position = self._convert_position(position, plane) if ax is None: ncols = 3 if _is_both_planes(plane) else 2 fig, (*axs, img_ax) = plt.subplots(ncols=ncols) self._plot_image(img_ax, plane, position) else: if not is_iterable(ax): axs = [ax, ] else: axs = ax if _is_both_planes(plane): planes = ('x', 'in') else: planes = (plane, ) for axis, plane, position in zip(axs, planes, position): profile = self._get_profile(plane, position) symmetry, lt_edge, rt_edge, max_idx = self._get_symmetry(profile, method) # plot axis.plot(profile.values) self._plot_annotation(axis, symmetry, method, profile, 'sym') self._plot_title(axis, plane, 'sym') # Add CAX and field edge lines cax_idx = profile.fwxm_center() axis.axvline(cax_idx, color='m', linestyle='-.') axis.axvline(lt_edge, color='g', linestyle='-.') axis.axvline(rt_edge, color='g', linestyle='-.') # Show max variation points axis.plot(profile._indices[max_idx], profile.values[max_idx], 'rx') axis.plot(profile._indices[rt_edge - (max_idx - lt_edge)], profile.values[rt_edge - (max_idx - lt_edge)], 'rx') if plot_mirror: central_idx = int(round(profile.values.size/2)) offset = cax_idx - central_idx mirror_vals = profile.values[::-1] axis.plot(profile._indices + 2*offset, mirror_vals) self._polish_plot(axis) if show: plt.tight_layout() plt.show() return axs