def time_elliptical_small_subpixel_1(): elliptical_overlap_grid(-4., 4., -4., 4., 10, 10, 3., 2., 1., use_exact=0, subpixels=1)
def time_elliptical_big_subpixel_5(): elliptical_overlap_grid(-4., 4., -4., 4., 100, 100, 3., 2., 1., use_exact=1, subpixels=5)
def to_mask(self, x_size, y_size): """ This function ... :param x_size: :param y_size: :return: """ rel_center = self.center a = self.radius.x if isinstance(self.radius, Extent) else self.radius b = self.radius.y if isinstance(self.radius, Extent) else self.radius # theta in radians ! theta = self.angle.radian x_min = -rel_center.x x_max = x_size - rel_center.x y_min = -rel_center.y y_max = y_size - rel_center.y # Calculate the mask if a * b * x_size * y_size == 0: fraction = 0 else: fraction = elliptical_overlap_grid(x_min, x_max, y_min, y_max, x_size, y_size, a, b, theta, use_exact=0, subpixels=1) #xmin, xmax, ymin, ymax : float # Extent of the grid in the x and y direction. #nx, ny : int # Grid dimensions. #rx : float # The semimajor axis of the ellipse. #ry : float # The semiminor axis of the ellipse. #theta : float # The position angle of the semimajor axis in radians (counterclockwise). #use_exact : 0 or 1 # If set to 1, calculates the exact overlap, while if set to 0, uses a # subpixel sampling method with ``subpixel`` subpixels in each direction. #subpixels : int # If ``use_exact`` is 0, each pixel is resampled by this factor in each # dimension. Thus, each pixel is divided into ``subpixels ** 2`` # subpixels. return Mask(fraction)
def to_mask(self, x_size, y_size, invert=False): """ This function ... :param x_size: :param y_size: :param invert: :return: """ rel_center = self.center a = self.radius.x b = self.radius.y # theta in radians ! theta = self.angle.radian x_min = - rel_center.x x_max = x_size - rel_center.x y_min = - rel_center.y y_max = y_size - rel_center.y # Calculate the mask fraction = elliptical_overlap_grid(x_min, x_max, y_min, y_max, x_size, y_size, a, b, theta, use_exact=0, subpixels=1) # xmin, xmax, ymin, ymax : float # Extent of the grid in the x and y direction. # nx, ny : int # Grid dimensions. # rx : float # The semimajor axis of the ellipse. # ry : float # The semiminor axis of the ellipse. # theta : float # The position angle of the semimajor axis in radians (counterclockwise). # use_exact : 0 or 1 # If set to 1, calculates the exact overlap, while if set to 0, uses a # subpixel sampling method with ``subpixel`` subpixels in each direction. # subpixels : int # If ``use_exact`` is 0, each pixel is resampled by this factor in each # dimension. Thus, each pixel is divided into ``subpixels ** 2`` # subpixels. mask = Mask(fraction) # Return if invert: return mask.inverse() else: return mask
def calc_masked_aperture(ap, image, method='mmm', mask=None): positions = ap.positions extents = np.zeros((len(positions), 4), dtype=int) if isinstance(ap, EllipticalAnnulus): radius = ap.a_out elif isinstance(ap, CircularAnnulus): radius = ap.r_out elif isinstance(ap, CircularAperture): radius = ap.r elif isinstance(ap, EllipticalAperture): radius = ap.a extents[:, 0] = positions[:, 0] - radius + 0.5 extents[:, 1] = positions[:, 0] + radius + 1.5 extents[:, 2] = positions[:, 1] - radius + 0.5 extents[:, 3] = positions[:, 1] + radius + 1.5 ood_filter, extent, phot_extent = get_phot_extents(image, positions, extents) x_min, x_max, y_min, y_max = extent x_pmin, x_pmax, y_pmin, y_pmax = phot_extent bkg = np.zeros(len(positions)) area = np.zeros(len(positions)) for i in range(len(bkg)): if isinstance(ap, EllipticalAnnulus): fraction = elliptical_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.a_out, ap.b_out, ap.theta, 0, 1) b_in = ap.a_in * ap.b_out / ap.a_out fraction -= elliptical_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.a_in, b_in, ap.theta, 0, 1) elif isinstance(ap, CircularAnnulus): fraction = circular_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.r_out, 0, 1) fraction -= circular_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.r_in, 0, 1) elif isinstance(ap, CircularAperture): fraction = circular_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.r, 0, 1) elif isinstance(ap, EllipticalAperture): fraction = elliptical_overlap_grid(x_pmin[i], x_pmax[i], y_pmin[i], y_pmax[i], x_max[i] - x_min[i], y_max[i] - y_min[i], ap.a, ap.b, ap.theta, 0, 1) pixel_data = image[y_min[i]:y_max[i], x_min[i]:x_max[i]] * fraction if mask is not None: pixel_data[mask[y_min[i]:y_max[i], x_min[i]:x_max[i]]] = 0.0 good_pixels = pixel_data[pixel_data != 0.0].flatten() if method == 'mmm': skymod, skysigma, skew = mmm(good_pixels) bkg[i] = skymod elif method == 'sum': bkg[i] = np.sum(good_pixels) elif method == 'max': bkg[i] = np.nanmax(good_pixels) area[i] = len(good_pixels) return bkg, area
def elliptical_mask(self, major, minor, pa=0.0, xoff=0.0, yoff=0.0, use_exact=1, subsampling=1, transparency=1.0): """ Define an elliptical mask within the grid with specified major/minor axes, position angle, and offset from center by xoff/yoff. Use photutils.geometry to create masks that calculate the fraction of a pixel subtended by the mask. use_exact=1 performs the exact geometric calculation while use_exact=0 will sub-sample the pixels by the specfied subsampling parameter to estimate the subtended area. Parameters ---------- major: float Semi-major axis of the elliptical mask minor: float Semi-minor axis of the mask pa: float Position angle of the ellipse in degrees measured clockwise (positive in +X direction) xoff: float X position of the center of the mask yoff: float Y position of the center of the mask use_exact: int (default: 1) If 1, then use exact geometrical calculation to weight pixels partially covered by mask. This parameter is passed directly on to photutils.geometry.circular_overlap_grid() subsampling: int (default: 1) If use_exact=0, then subsample pixels by this factor to calculate area of each pixel subtended by the mask. The default value of 1 will force no partial pixels to be included in the mask. This parameter is passed directly on to photutils.geometry.circular_overlap_grid() transparency: float (default: 1.0) Transparency of the mask Returns ------- mask: 2D np.ndarray 2D mask image """ if transparency < 0.0 or transparency > 1.0: msg = "Mask transparency, %f, must be in the range of 0.0 (fully opaque) to 1.0 (fully clear)." % transparency raise EngineInputError(value=msg) theta = np.pi * pa / 180.0 # photutils uses angles in radians t = self.as_dict() # we need to use flipud because we use an origin in the UL corner of an image # while photutils uses the LL corner. mask = np.flipud( elliptical_overlap_grid( t['x_min'] - xoff, t['x_max'] - xoff, t['y_min'] - yoff, t['y_max'] - yoff, t['x_size'], t['y_size'], major, minor, theta, use_exact, subsampling ) ) mask *= transparency return mask