def contains(self, skycoord): """ Check whether the given (list of) sky coordinate(s) falls inside this sky patch (region). Parameters ---------- skycoord : `~astropy.coordinate.SkyCoord` or (lon, lat) tuple The (list of) sky coordinate(s) to check, or the (list of) longitudes and latitudes of sky coordinates [ deg ] Returns ------- inside : bool (list of) boolean values indicating whether the given sky coordinate(s) is inside this sky patch. """ if not isinstance(skycoord, SkyCoord): lon, lat = skycoord skycoord = SkyCoord(lon, lat, unit=au.deg) wcs = self.wcs pixcoord = PixCoord.from_sky(skycoord, wcs=wcs) center = PixCoord(x=self.xcenter, y=self.ycenter) region = RectanglePixelRegion(center=center, width=self.xsize, height=self.ysize) return region.contains(pixcoord)
def to_object(self, subset): data = subset.data if data.ndim != 2: raise NotImplementedError("Can only handle 2-d datasets at this time") subset_state = subset.subset_state if isinstance(subset_state, RoiSubsetState): if subset_state.xatt != data.pixel_component_ids[1]: raise ValueError('subset state xatt should be x pixel coordinate') if subset_state.yatt != data.pixel_component_ids[0]: raise ValueError('subset state yatt should be y pixel coordinate') roi = subset_state.roi if isinstance(roi, RectangularROI): xcen = 0.5 * (roi.xmin + roi.xmax) ycen = 0.5 * (roi.ymin + roi.ymax) width = roi.xmax - roi.xmin height = roi.ymax - roi.ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height) elif isinstance(roi, PolygonalROI): return PolygonPixelRegion(PixCoord(roi.vx, roi.vy)) else: raise NotImplementedError("ROIs of type {0} are not yet supported".format(roi.__class__.__name__)) else: raise NotImplementedError("Subset states of type {0} are not supported".format(subset_state.__class__.__name__))
def setup(self): """Compute parameters for reflected regions algorithm.""" geom = self.reference_map.geom self._pix_region = self.region.to_pixel(geom.wcs) self._pix_center = PixCoord.from_sky(self.center, geom.wcs) # Make the ON reference map mask = geom.region_mask([self.region], inside=True) # on_reference_map = WcsNDMap(geom=geom, data=mask) # Extract all pixcoords in the geom X, Y = geom.get_pix() ONpixels = PixCoord(X[mask], Y[mask]) # find excluded PixCoords mask = self.reference_map.data == 0 self.excluded_pixcoords = PixCoord(X[mask], Y[mask]) # Minimum angle a region has to be moved to not overlap with previous one min_ang = self._region_angular_size(ONpixels, self._pix_center) # Add required minimal distance between two off regions self._min_ang = min_ang + self.min_distance # Maximum possible angle before regions is reached again self._max_angle = Angle( "360deg") - self._min_ang - self.min_distance_input
def test_vert_multirange(self): subset_state = MultiRangeSubsetState([(30, 33.5), (21, 27)], self.data.pixel_component_ids[0]) self.dc.new_subset_group(subset_state=subset_state, label='horizmultirange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert reg.contains(PixCoord(145, 31.2)) assert reg.contains(PixCoord(32, 24.6)) assert not reg.contains(PixCoord(128, 29.2)) rect1 = reg.region1 assert isinstance(rect1, RectanglePixelRegion) assert_allclose(rect1.center.x, 128) assert_allclose(rect1.center.y, 31.75) assert_allclose(rect1.width, 256) assert_allclose(rect1.height, 3.5) rect2 = reg.region2 assert isinstance(rect2, RectanglePixelRegion) assert_allclose(rect2.center.x, 128) assert_allclose(rect2.center.y, 24) assert_allclose(rect2.width, 256) assert_allclose(rect2.height, 6)
def test_horiz_multirange(self): subset_state = MultiRangeSubsetState([(26, 27.5), (28, 29)], self.data.pixel_component_ids[1]) self.dc.new_subset_group(subset_state=subset_state, label='horizmultirange') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert reg.contains(PixCoord(26.4, 54.6)) assert reg.contains(PixCoord(28.26, 75.5)) assert not reg.contains(PixCoord(27.75, 34)) rect1 = reg.region1 assert isinstance(rect1, RectanglePixelRegion) assert_allclose(rect1.center.x, 26.75) assert_allclose(rect1.center.y, 64) assert_allclose(rect1.width, 1.5) assert_allclose(rect1.height, 128) rect2 = reg.region2 assert isinstance(rect2, RectanglePixelRegion) assert_allclose(rect2.center.x, 28.5) assert_allclose(rect2.center.y, 64) assert_allclose(rect2.width, 1) assert_allclose(rect2.height, 128)
def dagga(field): "function to tag sources for dd calibration, very smoky" key = 'calibrate_dd' #make a skymodel with only dE taggable sources. #de_only_model = 'de-only-model.txt' de_sources_mode = config[key]['de_sources_mode'] print("de_sources_mode:", de_sources_mode) # if usepb: # model_cube = prefix+"-DD-precal.cube.int.model.fits" # else: # model_cube = prefix+"-DD-precal.cube.app.model.fits" outdir = field+"_ddcal" if de_sources_mode == 'auto': print("Carrying out automatic source taggig for direction dependent calibration") caracal.log.info('Carrying out automatic dE tagging') catdagger_opts = { "ds9-reg-file": "de-{0:s}.reg:output".format(field), "ds9-tag-reg-file" : "de-clusterleads-{0:s}.reg:output".format(field), "noise-map" : prefix+"_"+field+"-DD-precal.app.residual.fits", "sigma" : config[key]['sigma'], "min-distance-from-tracking-centre" : config[key]['min_dist_from_phcentre'], } recipe.add('cab/catdagger', 'tag_sources-auto_mode', catdagger_opts,input=INPUT, output=OUTPUT+"/"+outdir,label='tag_sources-auto_mode::Tag dE sources with CatDagger',shared_memory=shared_mem) if de_sources_mode == 'manual': img = prefix+"_"+field+"-DD-precal.app.restored.fits" imagefile = os.path.join(pipeline.output,DD_DIR,outdir,img) #print("Imagefile",imagefile) #print("Pipeline output", pipeline.output) w = WCS(imagefile) #coords = config[key]['de_sources_manual'] print(de_dict) sources_to_tag = de_dict[field.replace("_","-")] reg = [] for j in range(len(sources_to_tag.split(";"))): coords = sources_to_tag.split(";")[j] size = coords.split(",")[2] coords_str = coords.split(",")[0]+" "+coords.split(",")[1] #print("Coordinate String", coords_str) centre = SkyCoord(coords_str, unit='deg') separation = int(size) * u.arcsec #print("Size",separation) xlist = [] ylist = [] for i in range(5): ang_sep = (306/5)*i*u.deg p = centre.directional_offset_by(ang_sep,separation) pix = PixCoord.from_sky(p,w) xlist.append(pix.x) ylist.append(pix.y) vertices = PixCoord(x=xlist, y=ylist) region_dd = PolygonPixelRegion(vertices=vertices) reg.append(region_dd) regfile = "de-{0:s}.reg".format(field) ds9_file = os.path.join(OUTPUT,outdir,regfile) write_ds9(reg,ds9_file,coordsys='physical')
def define_regions( hdu: iofits.hdu.image.PrimaryHDU, parameters: dict ) -> Dict[str, Union[CircleAnnulusPixelRegion, RectanglePixelRegion]]: regions = dict() pileup_region = read_pileup_region() rot_angle_deg = define_rotation_angle_deg(parameters) windel = parameters['win_start'] - 512 # source region regions['src'] = CircleAnnulusPixelRegion( center=pileup_region.center, inner_radius=pileup_region.inner_radius, outer_radius=RADII['3arcmin'], meta=SRC_REGION_META) # background region regions['bkg'] = CircleAnnulusPixelRegion(center=pileup_region.center, inner_radius=RADII['5arcmin'], outer_radius=RADII['7arcmin'], meta=BKG_REGION_META) # exclude region 1 ref = np.array([0, windel - 256.]) ref = convert_reference_coodinate(ref, parameters) regions['rct1'] = RectanglePixelRegion(center=PixCoord( float(ref[0][0]), float(ref[1][0])), width=1024., height=512., angle=Angle(rot_angle_deg, 'deg')) # exclude region 2 ref = np.array([0, windel + parameters['win_size'] + 256.]) ref = convert_reference_coodinate(ref, parameters) regions['rct2'] = RectanglePixelRegion(center=PixCoord( float(ref[0][0]), float(ref[1][0])), width=1024., height=512., angle=Angle(rot_angle_deg, 'deg')) # exclude region 3 ref = np.array([512. + 128., windel + parameters['win_size'] * 0.5]) ref = convert_reference_coodinate(ref, parameters) regions['rct3'] = RectanglePixelRegion( center=PixCoord(float(ref[0][0]), float(ref[1][0])), width=256., height=parameters['win_size'] + 1024., angle=Angle(rot_angle_deg, 'deg')) # exclude region 4 ref = np.array([-512 - 128, windel + parameters['win_size'] * 0.5]) ref = convert_reference_coodinate(ref, parameters) regions['rct4'] = RectanglePixelRegion( center=PixCoord(float(ref[0][0]), float(ref[1][0])), width=256., height=parameters['win_size'] + 1024., angle=Angle(rot_angle_deg, 'deg')) return regions
def mask_obj(image, apertures, if_plot=True): """ Automaticlly generate a list of masked based on the input apertures. """ from regions import PixCoord, EllipsePixelRegion from astropy.coordinates import Angle masks = [] # In the script, the objects are 1, emptys are 0. for i in range(len(apertures)): aperture = apertures[i] if isinstance(apertures[0].positions[0], np.ndarray): x, y = aperture.positions[0] elif isinstance(apertures[0].positions[0], float): x, y = aperture.positions center = PixCoord(x=x, y=y) theta = Angle(aperture.theta / np.pi * 180., 'deg') reg = EllipsePixelRegion(center=center, width=aperture.a * 2, height=aperture.b * 2, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) mask_set = reg.to_mask(mode='center') mask = mask_set.to_image((len(image), len(image))) mask = 1 - mask if if_plot: print("plot mask for object {0}:".format(i)) fig, axi = plt.subplots(1, 1, figsize=None) axi.add_patch(patch) axi.imshow(mask, origin='lower') plt.show() masks.append(mask) return masks
def test_regions_pixel(self): # A little out-of-bounds should still overlay the overlapped part. my_reg = CirclePixelRegion(center=PixCoord(x=6, y=2), radius=5) bad_regions = self.imviz.load_static_regions({'my_reg': my_reg}) assert len(bad_regions) == 0 self.verify_region_loaded('my_reg') # Unsupported shape but a valid region my_pt_reg = PointPixelRegion(center=PixCoord(x=1, y=1)) with pytest.warns(UserWarning, match='failed to load, skipping'): bad_regions = self.imviz.load_static_regions( {'my_pt_reg': my_pt_reg}) assert len(bad_regions) == 1 self.verify_region_loaded('my_pt_reg', count=0) assert self.imviz.get_interactive_regions() == {}
def mask_contains_region(self, region): """Check if input region is contained in a boolean mask map. Parameters ---------- region: `~regions.SkyRegion` or `~regions.PixRegion` Region or list of Regions (pixel or sky regions accepted). Returns ------- contained : bool Whether region is contained in the mask """ if not self.is_mask: raise ValueError( "mask_contains_region is only supported for boolean masks") if not self.geom.is_image: raise ValueError("Method only supported for 2D images") if isinstance(region, SkyRegion): region = region.to_pixel(self.geom.wcs) if isinstance(region, PointPixelRegion): lon, lat = region.center.x, region.center.y contains = self.get_by_pix((lon, lat)) else: idx = self.geom.get_idx() coords_pix = PixCoord(idx[0][self.data], idx[1][self.data]) contains = region.contains(coords_pix) return np.any(contains)
def find_sky_region(mask, wcs): '''create a region object from a mask and wcs Returns: reg_pix : PixelRegion reg_sky : SkyRegion ''' mask[:, [0, -1]] = 1 mask[[0, -1], :] = 1 # find the contours around the image to use as vertices for the PixelRegion contours = find_contours( mask, 0.5, ) # we use the region with the most vertices coords = max(contours, key=len) #coords = np.concatenate(contours) # the coordinates from find_counters are switched compared to astropy reg_pix = PolygonPixelRegion(vertices=PixCoord(*coords.T[::-1])) reg_sky = reg_pix.to_sky(wcs) return reg_pix, reg_sky
def range_to_rect(data, ori, low, high): """ Converts a 1D range on a 2D glue Data set into an astropy regions RectangularPixelRegion. The region covers the entirety of the data along the axis not specified by the `ori` parameter. Parameters ---------- data : `glue.core.data.Data` The 2D glue Data object on which the range subset is defined. ori: 'x' or 'y' Specifies if the range limits are for the x-axis or y-axis respectively. low: `float` The lower limit of the range. high: `float` The upper limit of the range. """ if data.ndim != 2: raise NotImplementedError("Can only handle 2-d datasets") if ori == 'x': ymin = 0 ymax = data.shape[0] xmin = low xmax = high else: xmin = 0 xmax = data.shape[1] ymin = low ymax = high xcen = 0.5 * (xmin + xmax) ycen = 0.5 * (ymin + ymax) width = xmax - xmin height = ymax - ymin return RectanglePixelRegion(PixCoord(xcen, ycen), width, height)
def get_region_mask_array(self, region): """Return mask of pixels inside region in the the form of boolean array Parameters ---------- region : `~regions.PixelRegion` or `~regions.SkyRegion` object A region on the sky could be defined in pixel or sky coordinates. Return ------ mask_array : `~numpy.ndarray` of booleans the array of booleans """ from regions import PixCoord # TODO : if Pixel Compound regions are taken into account, rather convert to PixelRegion if isinstance(region, SkyRegion): region = region.to_pixel(self.wcs) if not self.is_regular: raise NotImplementedError( "Region mask is not working yet with multiresolution maps") idx = self.get_idx() pixcoord = PixCoord(idx[0], idx[1]) return region.contains(pixcoord)
def ellipse_mask(a, b, x0, y0, theta, image): """Returns elliptical mask of radii (a,b) with rotation theta (in degrees) and offset (xo,yo) from the geometric center of 'I' (X0,Y0), which must be passed via **kws and must have an odd number of pixels in each dimension. The mask has the same shape as 'I' and is assigned 1 (0) for pixels outside (inside) the ellipse, and assigned fractional areas for pixels intercepted by the ellipse. To install astropy and regions, run the following commands from terminal: conda install astropy pip install regions """ from regions import EllipsePixelRegion, PixCoord from astropy.units import deg from numpy import array I = image height, width = I.shape # Calculate ellipse center (h,k) h = x0 k = y0 ellipse = EllipsePixelRegion(PixCoord(h, k), 2 * a, 2 * b, -theta * deg) mask = ellipse.to_mask(mode='exact') mask = mask.to_image(I.shape) return array(mask, dtype='bool')
def polygon_pix_pts2polygon_sky_reg(polygon_points, wcs): x_coord = polygon_points[:, 0] y_coord = polygon_points[:, 1] polygon_pix_reg = PolygonPixelRegion( vertices=PixCoord(x=x_coord, y=y_coord)) polygon_sky_reg = polygon_pix_reg.to_sky(wcs) return polygon_sky_reg
def setup(self): """Compute parameters for reflected regions algorithm.""" wcs = self.reference_map.geom.wcs self._pix_region = self.region.to_pixel(wcs) self._pix_center = PixCoord(*self.center.to_pixel(wcs)) dx = self._pix_region.center.x - self._pix_center.x dy = self._pix_region.center.y - self._pix_center.y # Offset of region in pix coordinates self._offset = np.hypot(dx, dy) # Starting angle of region self._angle = Angle(np.arctan2(dx, dy), "rad") # Minimum angle a circle has to be moved to not overlap with previous one min_ang = Angle(2 * np.arcsin(self._pix_region.radius / self._offset), "rad") # Add required minimal distance between two off regions self._min_ang = min_ang + self.min_distance # Maximum possible angle before regions is reached again self._max_angle = (self._angle + Angle("360deg") - self._min_ang - self.min_distance_input) # Distance image self._distance_image = _compute_distance_image(self.reference_map)
def test_regions_pixel(self): from regions import PixCoord, CirclePixelRegion # Out-of-bounds should still overlay the overlapped part. my_reg = CirclePixelRegion(center=PixCoord(x=6, y=2), radius=5) self.imviz.load_static_regions({'my_reg': my_reg}) self.verify_region_loaded('my_reg') assert self.imviz.get_interactive_regions() == {}
def cutout(filename, position, size, circ): """ Cut out a square of size size at center position position of the filename filename. Returns: the cut out filename, so it can be used in other scripts. """ # Load the image and the WCS hdu = fits.open(filename)[0] naxis = hdu.header['NAXIS'] wcs = WCS(hdu.header, naxis=naxis) # Make the cutout, including the WCS cutout = Cutout2D(hdu.data, position=position, size=size, wcs=wcs) # Put the cutout image in the FITS HDU hdu.data = cutout.data # Update the FITS header with the cutout WCS hdu.header.update(cutout.wcs.to_header()) # Choose whether you want a circle or a square if (circ): # Define a circle region and keep only data that is in that region circle_pix = CirclePixelRegion( PixCoord(len(cutout.data[:, 1]) // 2, len(cutout.data[1, :]) // 2), radius=np.min(size) / 2) # region object for i in range(len(cutout.data[:, 1])): for j in range(len(cutout.data[1, :])): if not PixCoord(i, j) in circle_pix: cutout.data[i, j] = 'nan' # Write the cutout to a new FITS file cutout_filename = filename.split( '.')[0] + '_cutout_circ.' + filename.split('.')[1] hdu.writeto(cutout_filename, overwrite=True) print("Made circle cutout, output: " + cutout_filename) else: # Write the cutout to a new FITS file cutout_filename = filename.split('.')[0] + '_cutout.' + filename.split( '.')[1] hdu.writeto(cutout_filename, overwrite=True) print("Made cutout, output: " + cutout_filename) # Return the output filename so we can use it in other scripts return cutout_filename
def _get_excluded_pixels(reference_geom, exclusion_mask): """Excluded pix coords""" # find excluded PixCoords exclusion_mask = ReflectedRegionsFinder._exclusion_mask_ref( reference_geom, exclusion_mask, ) pix_y, pix_x = np.nonzero(~exclusion_mask.data) return PixCoord(pix_x, pix_y)
def test_regions_fully_out_of_bounds(self): my_reg = CirclePixelRegion(center=PixCoord(x=100, y=100), radius=5) with pytest.warns(UserWarning, match='failed to load, skipping'): bad_regions = self.imviz.load_static_regions( {'my_oob_reg': my_reg}) assert len(bad_regions) == 1 # BUG: https://github.com/glue-viz/glue/issues/2275 self.verify_region_loaded('my_oob_reg', count=1) # Should be: count=0
def region_mask(self, regions, inside=True): """Create a mask from a given list of regions Parameters ---------- regions : list of `~regions.Region` Python list of regions (pixel or sky regions accepted) inside : bool For ``inside=True``, pixels in the region to True (the default). For ``inside=False``, pixels in the region are False. Returns ------- mask_map : `~gammapy.maps.WcsNDMap` of boolean type Boolean region mask Examples -------- Make an exclusion mask for a circular region:: from regions import CircleSkyRegion from astropy.coordinates import SkyCoord, Angle from gammapy.maps import WcsNDMap, WcsGeom pos = SkyCoord(0, 0, unit='deg') geom = WcsGeom.create(skydir=pos, npix=100, binsz=0.1) region = CircleSkyRegion( SkyCoord(3, 2, unit='deg'), Angle(1, 'deg'), ) mask = geom.region_mask([region], inside=False) Note how we made a list with a single region, since this method expects a list of regions. """ from regions import PixCoord from . import Map if not self.is_regular: raise ValueError("Multi-resolution maps not supported yet") idx = self.get_idx() pixcoord = PixCoord(idx[0], idx[1]) mask = np.zeros(self.data_shape, dtype=bool) for region in regions: if isinstance(region, SkyRegion): region = region.to_pixel(self.wcs) mask += region.contains(pixcoord) if inside is False: np.logical_not(mask, out=mask) return Map.from_geom(self, data=mask)
def _compute_xy(pix_center, offset, angle): """Compute x, y position for a given position angle and offset. # TODO: replace by calculation using `astropy.coordinates` """ dx = offset * np.sin(angle) dy = offset * np.cos(angle) x = pix_center.x + dx y = pix_center.y + dy return PixCoord(x=x, y=y)
def fitEllipse(cc,axesLength,angle): x0, y0 = cc[0],cc[1] a, b = axesLength[0],axesLength[1] theta = Angle(angle, 'deg') e = Ellipse2D(amplitude=100., x_0=x0, y_0=y0, a=a, b=b, theta=theta.radian) y, x = np.mgrid[0:1000, 0:1000] center = PixCoord(x=x0, y=y0) reg = EllipsePixelRegion(center=center, width=2*a, height=2*b, angle=theta) patch = reg.as_artist(facecolor='none', edgecolor='red', lw=2) return reg
def test_or_region(self): subset_state1 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(1, 5, 2, 6)) subset_state2 = RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], CircularROI(4.75, 5.75, 0.5)) or_subset_state = OrState(subset_state1, subset_state2) self.dc.new_subset_group(subset_state=or_subset_state, label='orstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, RectanglePixelRegion) assert isinstance(reg.region2, CirclePixelRegion) assert reg.contains(PixCoord(4.5, 5.5)) assert reg.contains(PixCoord(3, 4)) assert reg.contains(PixCoord(5.1, 6.1)) assert not reg.contains(PixCoord(11, 12))
def test_wcslink_affine_with_extras(self): from regions import PixCoord, CirclePixelRegion self.imviz.link_data(link_type='wcs', wcs_fallback_scheme=None, error_on_fail=True) links = self.imviz.app.data_collection.external_links assert len(links) == 1 assert isinstance(links[0], OffsetLink) # Customize display on second image (last loaded). self.imviz.set_colormap('viridis') self.imviz.stretch = 'sqrt' self.imviz.cuts = (0, 100) # Add subsets, both interactive and static. self.imviz._apply_interactive_region('bqplot:circle', (1.5, 2.5), (3.6, 4.6)) self.imviz.load_static_regions({ 'my_reg': CirclePixelRegion(center=PixCoord(x=6, y=2), radius=5)}) # Add markers. tbl = Table({'x': (0, 0), 'y': (0, 1)}) self.imviz.add_markers(tbl, marker_name='xy_markers') assert 'xy_markers' in self.imviz.app.data_collection.labels # Run linking again, does not matter what kind. self.imviz.link_data(link_type='wcs', wcs_fallback_scheme=None, error_on_fail=True) # Ensure display is still customized. assert self.viewer.state.layers[1].cmap.name == 'viridis' assert self.viewer.state.layers[1].stretch == 'sqrt' assert_allclose((self.viewer.state.layers[1].v_min, self.viewer.state.layers[1].v_max), (0, 100)) # Ensure subsets are still there. assert 'Subset 1' in self.imviz.get_interactive_regions() assert 'my_reg' in [layer.layer.label for layer in self.viewer.state.layers] # Ensure markers are deleted. # Zoom and pan will reset in this case, so we do not check those. assert 'xy_markers' not in self.imviz.app.data_collection.labels assert len(self.imviz._marktags) == 0 # Pan/zoom. self.imviz.center_on((5, 5)) self.imviz.zoom_level = 0.789 ans = (self.viewer.state.x_min, self.viewer.state.y_min, self.viewer.state.x_max, self.viewer.state.y_max) # Run linking again, does not matter what kind. self.imviz.link_data(link_type='wcs', wcs_fallback_scheme=None, error_on_fail=True) # Ensure pan/zoom does not change when markers are not present. assert_allclose((self.viewer.state.x_min, self.viewer.state.y_min, self.viewer.state.x_max, self.viewer.state.y_max), ans)
def test_multior_region(self): rects = [(1, 2, 3, 4), (1.5, 2.5, 3.5, 4.5), (2, 3, 4, 5)] states = [ RoiSubsetState(self.data.pixel_component_ids[1], self.data.pixel_component_ids[0], RectangularROI(*rect)) for rect in rects ] multior_subset_state = MultiOrState(states) self.dc.new_subset_group(subset_state=multior_subset_state, label='multiorstate') reg = self.data.get_selection_definition(format='astropy-regions') assert isinstance(reg, CompoundPixelRegion) assert isinstance(reg.region1, CompoundPixelRegion) assert isinstance(reg.region2, RectanglePixelRegion) assert isinstance(reg.region1.region1, RectanglePixelRegion) assert isinstance(reg.region1.region2, RectanglePixelRegion) assert reg.contains(PixCoord(1.25, 3.25)) assert reg.contains(PixCoord(1.75, 3.75)) assert reg.contains(PixCoord(2.25, 3.75)) assert reg.contains(PixCoord(2.25, 4.25)) assert reg.contains(PixCoord(2.75, 4.75)) assert not reg.contains(PixCoord(5, 7))
def angle_in_circle(image_filename, position_of_star, rht_data, radius): """ Gets a star, draws a circle around it and returns the average rht angle and standard deviation in this circle. """ ipoints, jpoints, hthets, naxis1, naxis2, wlen, smr, thresh, thets_deg = rht_data c = CirclePixelRegion(PixCoord( np.round(position_of_star)[0], np.round(position_of_star)[1]), radius=radius) # Check which RHT data is in this region, these are the indices: indices = c.contains(PixCoord(ipoints, jpoints)) # hthets[indices] are all the pixel angle distributions found in the circle # Loop through pixels: # We multiply by thets_deg to get angle distribution, then normalise by dividing by the sum of the distribution, and finally take the sum of all values to get the average angle. average_on_pixel = [] for i, v in enumerate(hthets[indices]): average_on_pixel.append( (hthets[indices][i] * thets_deg / hthets[indices][i].sum()).sum()) return np.mean(average_on_pixel), np.std(average_on_pixel)
def make_instrument_background(inst_spec, event_params, rmf, prng=None): from collections import defaultdict prng = parse_prng(prng) bkgnd_spec = inst_spec["bkgnd"] if isinstance(bkgnd_spec[0], str): nchips = len(event_params["chips"]) bkgnd_spec = [bkgnd_spec] * nchips bkg_events = defaultdict(list) pixel_area = (event_params["plate_scale"] * 60.0)**2 for i, chip in enumerate(event_params["chips"]): rtype = chip[0] args = chip[1:] r, bounds = create_region(rtype, args, 0.0, 0.0) sa = (bounds[1] - bounds[0]) * (bounds[3] - bounds[2]) * pixel_area bspec = InstrumentalBackground.from_filename(bkgnd_spec[i][0], bkgnd_spec[i][1], inst_spec['focal_length']) chan = bspec.generate_channels(event_params["exposure_time"], sa, prng=prng) n_events = chan.size detx = prng.uniform(low=bounds[0], high=bounds[1], size=n_events) dety = prng.uniform(low=bounds[2], high=bounds[3], size=n_events) if rtype in ["Box", "Rectangle"]: thisc = slice(None, None, None) n_det = n_events else: thisc = r.contains(PixCoord(detx, dety)) n_det = thisc.sum() ch = chan[thisc].astype('int') e = rmf.ch_to_eb(ch, prng=prng) bkg_events["energy"].append(e) bkg_events[rmf.chan_type].append(ch) bkg_events["detx"].append(detx[thisc]) bkg_events["dety"].append(dety[thisc]) bkg_events["chip_id"].append(i * np.ones(n_det)) for key in bkg_events: bkg_events[key] = np.concatenate(bkg_events[key]) if bkg_events["energy"].size == 0: raise RuntimeError( "No instrumental background events were detected!!!") else: mylog.info(f"Making {bkg_events['energy'].size} events " f"from the instrumental background.") return make_diffuse_background(bkg_events, event_params, rmf, prng=prng)
def __init__(self, x=None, y=None, width=None, length=None, *args, **kwargs): pixcoord = PixCoord(x, y) self._pix_region = RectanglePixelRegion(center=pixcoord, width=width, height=length) self._patch = self._pix_region.as_artist(edgecolor='red', facecolor='none') self._is_active = False
def makeMask(xs, ys, radius, cenx, ceny): shape = (xs, ys) fin_mask = np.zeros(shape) print(radius) for i in np.arange(len(cenx)): if radius[i] > 5: radius[i] = 6 center = PixCoord(cenx[i], ceny[i]) circle = CirclePixelRegion(center, radius[i] - 1) mask = circle.to_mask() newmask = mask.to_image(shape) fin_mask += newmask fin_mask[fin_mask > 1] = 1 return fin_mask