def single_cutout(ax,position,image,mask1=None,mask2=None,points=None,label=None,size=6*u.arcsec): cutout_image = Cutout2D(image.data,position,size=size,wcs=image.wcs) norm = simple_norm(cutout_image.data,clip=False,stretch='linear',percent=99.5) ax.imshow(cutout_image.data,origin='lower',norm=norm,cmap=plt.cm.gray_r) # plot the nebulae catalogue cutout_mask, _ = reproject_interp(mask1,output_projection=cutout_image.wcs,shape_out=cutout_image.shape,order='nearest-neighbor') region_ID = np.unique(cutout_mask[~np.isnan(cutout_mask)]) contours = [] for i in region_ID: blank_mask = np.zeros_like(cutout_mask) blank_mask[cutout_mask==i] = 1 contours += find_contours(blank_mask, 0.5) for coords in contours: ax.plot(coords[:,1],coords[:,0],color='tab:red',lw=1,label='HII-region') mask = np.zeros((*cutout_mask.shape,4)) mask[~np.isnan(cutout_mask.data),:] = (0.84, 0.15, 0.16,0.1) ax.imshow(mask,origin='lower') # plot the association catalogue if mask2: cutout_mask, _ = reproject_interp(mask2,output_projection=cutout_image.wcs,shape_out=cutout_image.shape,order='nearest-neighbor') region_ID = np.unique(cutout_mask[~np.isnan(cutout_mask)]) contours = [] for i in region_ID: blank_mask = np.zeros_like(cutout_mask) blank_mask[cutout_mask==i] = 1 contours += find_contours(blank_mask, 0.5) for coords in contours: ax.plot(coords[:,1],coords[:,0],color='tab:blue',lw=1,label='association') mask = np.zeros((*cutout_mask.shape,4)) mask[~np.isnan(cutout_mask.data),:] = (0.12,0.47,0.71,0.1) ax.imshow(mask,origin='lower') # mark the position of the clusters within the cutout if points: region = RectangleSkyRegion(position,0.9*size,0.9*size) in_frame = points[region.contains(points['SkyCoord'],cutout_image.wcs)] for row in in_frame: x,y = row['SkyCoord'].to_pixel(cutout_image.wcs) if 5<x<cutout_image.data.shape[0]-5 and 5<y<cutout_image.data.shape[1]-5: ax.scatter(x,y,marker='o',facecolors='none',s=20,lw=0.4,color='tab:blue',label='cluster') if label: t = ax.text(0.07,0.875,label, transform=ax.transAxes,color='black',fontsize=8) t.set_bbox(dict(facecolor='white', alpha=1, ec='white')) ax.set_xticks([]) ax.set_yticks([]) return ax
class RectangleSkySlit(_RectangleSlitBase): """ Slit constructed using WCS and coords information. Utilizes `regions` package. Parameters ---------- wcs : `astropy.wcs.WCS` ra, dec : float Center (ra, dec) of slit in deg. width, length : float Angular width and length of slit in arcsec. """ def __init__(self, wcs, ra, dec, width, length, *args, **kwargs): self.wcs = wcs skycoord = SkyCoord(ra, dec, unit=(u.Unit(u.deg), u.Unit(u.deg)), frame='fk5') length = Angle(length, u.arcsec) width = Angle(width, u.arcsec) self._sky_region = RectangleSkyRegion(center=skycoord, width=width, height=length) # N.B: The following step will not be needed when # regions.RectangleSkyRegion.as_artist is implemented self._pix_region = self._sky_region.to_pixel(wcs) self._patch = self._pix_region.as_artist(edgecolor='red', facecolor='none') self._is_active = False
def test_get_wcs_coord_and_weights(region): # test on circular region geom = RegionGeom(region) region_coord, weights = geom.get_wcs_coord_and_weights() wcs_geom = geom.to_wcs_geom() solid_angles = wcs_geom.solid_angle().T[wcs_geom.coord_to_idx( region_coord)] area = (weights * solid_angles).sum() assert_allclose(area.value, geom.solid_angle().value, rtol=1e-3) assert region_coord.shape == weights.shape # test on rectangular region (assymetric) center = SkyCoord("0 deg", "0 deg", frame="galactic") region = RectangleSkyRegion(center=center, width=1 * u.deg, height=2 * u.deg, angle=15 * u.deg) geom = RegionGeom(region) wcs_geom = geom.to_wcs_geom() region_coord, weights = geom.get_wcs_coord_and_weights() solid_angles = wcs_geom.solid_angle().T[wcs_geom.coord_to_idx( region_coord)] area = (weights * solid_angles).sum() assert_allclose(area.value, geom.solid_angle().value, rtol=1e-3) assert region_coord.shape == weights.shape
def jwst_header_to_skyregion(header): s_region = header['S_REGION'] footprint = s_region.split("POLYGON ICRS")[1].split() ra = np.array(footprint[::2], dtype=np.float) dec = np.array(footprint[1::2], dtype=np.float) # Find center of slit cra = (max(ra) + min(ra)) / 2 cdec = (max(dec) + min(dec)) / 2 # Find center as skycoord skycoord = SkyCoord(cra, cdec, unit=(u.Unit(u.deg), u.Unit(u.deg))) # Puts corners of slit into skycoord object corners = SkyCoord(ra, dec, unit="deg") # Compute length and width length = corners[0].separation(corners[1]) width = corners[1].separation(corners[2]) length = Angle(length, u.deg) width = Angle(width, u.deg) skyregion = RectangleSkyRegion(center=skycoord, width=width, height=length) return skyregion
def to_region(self, **kwargs): """Model outline from template map boundary (`~regions.RectangleSkyRegion`).""" return RectangleSkyRegion( center=self.map.geom.center_skydir, width=self.map.geom.width[0][0], height=self.map.geom.width[1][0], **kwargs, )
def to_region_nd_map(self, region=None, func=np.nansum, weights=None, method="nearest"): """Get region ND map in a given region. By default the whole map region is considered. Parameters ---------- region: `~regions.Region` or `~astropy.coordinates.SkyCoord` Region. func : numpy.func Function to reduce the data. Default is np.nansum. For boolean Map, use np.any or np.all. weights : `WcsNDMap` Array to be used as weights. The geometry must be equivalent. method : {"nearest", "linear"} How to interpolate if a position is given. Returns ------- spectrum : `~gammapy.maps.RegionNDMap` Spectrum in the given region. """ from gammapy.maps import RegionGeom, RegionNDMap if isinstance(region, SkyCoord): region = PointSkyRegion(region) elif region is None: width, height = self.geom.width region = RectangleSkyRegion( center=self.geom.center_skydir, width=width[0], height=height[0] ) if weights is not None: if not self.geom == weights.geom: raise ValueError("Incompatible spatial geoms between map and weights") geom = RegionGeom(region=region, axes=self.geom.axes, wcs=self.geom.wcs) if isinstance(region, PointSkyRegion): coords = geom.get_coord() data = self.interp_by_coord(coords=coords, method=method) if weights is not None: data *= weights.interp_by_coord(coords=coords, method=method) else: cutout = self.cutout(position=geom.center_skydir, width=geom.width) if weights is not None: weights_cutout = weights.cutout( position=geom.center_skydir, width=geom.width ) cutout.data *= weights_cutout.data mask = cutout.geom.to_image().region_mask([region]).data idx_y, idx_x = np.where(mask) data = func(cutout.data[..., idx_y, idx_x], axis=-1) return RegionNDMap(geom=geom, data=data, unit=self.unit, meta=self.meta.copy())
def __init__(self, wcs, ra, dec, width, length, *args, **kwargs): self.wcs = wcs skycoord = SkyCoord(ra, dec, unit=(u.Unit(u.deg), u.Unit(u.deg)), frame='fk5') length = Angle(length, u.arcsec) width = Angle(width, u.arcsec) self._sky_region = RectangleSkyRegion(center=skycoord, width=width, height=length) # N.B: The following step will not be needed when # regions.RectangleSkyRegion.as_artist is implemented self._pix_region = self._sky_region.to_pixel(wcs) self._patch = self._pix_region.as_artist(edgecolor='red', facecolor='none') self._is_active = False
def test_integrate_geom_energy_axis(): center = SkyCoord("0d", "0d", frame='icrs') model = GaussianSpatialModel(lon="0d", lat="0d", sigma=0.1*u.deg, frame='icrs') radius = 1 * u.deg square = RectangleSkyRegion(center, radius, radius) axis = MapAxis.from_energy_bounds("1 TeV", "10 TeV", nbin=10) geom = RegionGeom(region=square, axes=[axis]) integral = model.integrate_geom(geom).data assert_allclose(integral, 1, rtol=0.01)
def setup_class(self): table = Table() table["RA"] = [0.0, 0.0, 0.0, 10.0] * u.deg table["DEC"] = [0.0, 0.9, 10.0, 10.0] * u.deg table["ENERGY"] = [1.0, 1.5, 1.5, 10.0] * u.TeV table["OFFSET"] = [0.1, 0.5, 1.0, 1.5] * u.deg self.events = EventListBase(table) center1 = SkyCoord(0.0, 0.0, frame="icrs", unit="deg") on_region1 = CircleSkyRegion(center1, radius=1.0 * u.deg) center2 = SkyCoord(0.0, 10.0, frame="icrs", unit="deg") on_region2 = RectangleSkyRegion(center2, width=0.5 * u.deg, height=0.3 * u.deg) self.on_regions = [on_region1, on_region2]
def setup(self): ra = [0.0, 0.0, 0.0, 10.0] * u.deg dec = [0.0, 0.9, 10.0, 10.0] * u.deg energy = [1.0, 1.5, 1.5, 10.0] * u.TeV evt_table = Table([ra, dec, energy], names=["RA", "DEC", "ENERGY"]) self.evt_list = EventListBase(evt_table) center1 = SkyCoord(0.0, 0.0, frame="icrs", unit="deg") on_region1 = CircleSkyRegion(center1, radius=1.0 * u.deg) center2 = SkyCoord(0.0, 10.0, frame="icrs", unit="deg") on_region2 = RectangleSkyRegion(center2, width=0.5 * u.deg, height=0.3 * u.deg) self.on_regions = [on_region1, on_region2]
def test_get_wcs_coord(region): # test on circular region geom = RegionGeom(region) region_coords = geom.get_wcs_coord() sep = geom.region.center.separation(region_coords.skycoord).value assert max(sep) <= geom.region.radius.value # test on rectangular region (assymetric) center = SkyCoord("0 deg", "0 deg", frame="galactic") region = RectangleSkyRegion(center=center, width = 1 * u.deg, height=2 * u.deg) geom = RegionGeom(region) region_coords = geom.get_wcs_coord() coord = SkyCoord("100d", "30d") assert geom.contains(region_coords.skycoord[0]) assert geom.contains(coord) is not True
def make_orthogonal_rectangle_sky_regions(start_pos, end_pos, wcs, height, nbin=1): """Utility returning an array of regions to make orthogonal projections Parameters ---------- start_pos : `~astropy.regions.SkyCoord' First sky coordinate defining the line to which the orthogonal boxes made end_pos : `~astropy.regions.SkyCoord' Second sky coordinate defining the line to which the orthogonal boxes made height : `~astropy.quantity.Quantity` Height of the rectangle region. wcs : `~astropy.wcs.WCS` WCS projection object nbin : int Number of boxes along the line Returns -------- regions : list of `~regions.RectangleSkyRegion` Regions in which the profiles are made """ pix_start = start_pos.to_pixel(wcs) pix_stop = end_pos.to_pixel(wcs) points = np.linspace(start=pix_start, stop=pix_stop, num=nbin + 1).T centers = 0.5 * (points[:, :-1] + points[:, 1:]) coords = SkyCoord.from_pixel(centers[0], centers[1], wcs) width = start_pos.separation(end_pos).to("rad") / nbin angle = end_pos.position_angle(start_pos) - 90 * u.deg regions = [] for center in coords: reg = RectangleSkyRegion(center=center, width=width, height=u.Quantity(height), angle=angle) regions.append(reg) return regions
def get_regions_from_flim(shotid): date = str(shotid)[0:8] obs = str(shotid)[8:] datevobs = str(date) + "v" + str(obs).zfill(3) shotid = int(str(date) + str(obs).zfill(3)) hdf_filename, mask_fn = return_sensitivity_hdf_path(datevobs, release="hdr2.1", return_mask_fn=True) hdfcont = SensitivityCubeHDF5Container( filename=hdf_filename, aper_corr=1.0, flim_model="hdr2pt1", mask_filename=mask_fn, ) ifu_name_list = [] ifu_ra = [] ifu_dec = [] ifuregions = [] for ifu_name, tscube in hdfcont.itercubes(): shape = tscube.sigmas.shape ra, dec, lambda_ = tscube.wcs.all_pix2world(shape[2] / 2.0, shape[1] / 2.0, shape[0] / 2.0, 0) pa = -tscube.header["CROTA2"] ifu_name_list.append(ifu_name) coord = SkyCoord(ra, dec, unit="deg") ifu_ra.append(ra) ifu_dec.append(dec) ifuregions.append( RectangleSkyRegion( center=coord, width=1.0 * u.arcmin, height=1.0 * u.arcmin, angle=pa * u.deg, )) hdfcont.close() return ifuregions
def get_spectrum(self, region=None, func=np.nansum): """Extract spectrum in a given region. The spectrum can be computed by summing (or, more generally, applying ``func``) along the spatial axes in each energy bin. This occurs only inside the ``region``, which by default is assumed to be the whole spatial extension of the map. Parameters ---------- region: `~regions.Region` Region (pixel or sky regions accepted). func : numpy.ufunc Function to reduce the data. Returns ------- spectrum : `~gammapy.maps.RegionNDMap` Spectrum in the given region. """ energy_axis = self.geom.axes[0] geom = RegionGeom(region=region, axes=[energy_axis], wcs=self.geom.wcs) if region: cutout = self.cutout(position=geom.center_skydir, width=geom.width) mask = cutout.geom.region_mask([region]) data = cutout.data[mask].reshape(energy_axis.nbin, -1) data = func(data, axis=1) else: width, height = self.geom.width region = RectangleSkyRegion(center=self.geom.center_skydir, width=width[0], height=height[0]) geom = RegionGeom(region=region, axes=[energy_axis], wcs=self.geom.wcs) data = func(self.data, axis=(1, 2)) return RegionNDMap(geom=geom, data=data.reshape(geom.data_shape), unit=self.unit)
def to_region_nd_map(self, region=None, func=np.nansum): """Get region ND map in a given region. By default the whole map region is considered. Parameters ---------- region: `~regions.Region` or `~astropy.coordinates.SkyCoord` Region. func : numpy.ufunc Function to reduce the data. Returns ------- spectrum : `~gammapy.maps.RegionNDMap` Spectrum in the given region. """ if isinstance(region, SkyCoord): region = PointSkyRegion(region) elif region is None: width, height = self.geom.width region = RectangleSkyRegion( center=self.geom.center_skydir, width=width[0], height=height[0] ) geom = RegionGeom( region=region, axes=self.geom.axes, wcs=self.geom.wcs ) if isinstance(region, PointSkyRegion): coords = geom.get_coord() data = self.get_by_coord(coords=coords) else: cutout = self.cutout(position=geom.center_skydir, width=geom.width) mask = cutout.geom.to_image().region_mask([region]) idx_y, idx_x = np.where(mask) data = func(cutout.data[..., idx_y, idx_x], axis=-1) return RegionNDMap(geom=geom, data=data, unit=self.unit)
def post(self): # See bottom of this file for redoc docstring -- moved it there so that # it could be made an f-string. data = self.get_json() telescope_id = data.get('telescope_id') telescope = Telescope.get_if_accessible_by( telescope_id, self.current_user, raise_if_none=True, mode="read" ) sensitivity_data = data.get("sensitivity_data", None) if sensitivity_data: filters = data.get("filters", []) if not set(sensitivity_data.keys()).issubset(filters): return self.error( 'Sensitivity_data filters must be a subset of the instrument filters' ) field_data = data.pop("field_data", None) field_region = data.pop("field_region", None) field_fov_type = data.pop("field_fov_type", None) field_fov_attributes = data.pop("field_fov_attributes", None) if (field_region is not None) and (field_fov_type is not None): return self.error('must supply only one of field_region or field_fov_type') if field_region is not None: regions = Regions.parse(field_region, format='ds9') data['region'] = regions.serialize(format='ds9') if field_fov_type is not None: if field_fov_attributes is None: return self.error( 'field_fov_attributes required if field_fov_type supplied' ) if not field_fov_type.lower() in ["circle", "rectangle"]: return self.error('field_fov_type must be circle or rectangle') if isinstance(field_fov_attributes, list): field_fov_attributes = [float(x) for x in field_fov_attributes] else: field_fov_attributes = [float(field_fov_attributes)] center = SkyCoord(0.0, 0.0, unit='deg', frame='icrs') if field_fov_type.lower() == "circle": if not len(field_fov_attributes) == 1: return self.error( 'If field_fov_type is circle, then should supply only radius for field_fov_attributes' ) radius = field_fov_attributes[0] regions = CircleSkyRegion(center=center, radius=radius * u.deg) elif field_fov_type.lower() == "rectangle": if not len(field_fov_attributes) == 2: return self.error( 'If field_fov_type is rectangle, then should supply width and height for field_fov_attributes' ) width, height = field_fov_attributes regions = RectangleSkyRegion( center=center, width=width * u.deg, height=height * u.deg ) data['region'] = regions.serialize(format='ds9') schema = Instrument.__schema__() try: instrument = schema.load(data) except ValidationError as exc: return self.error( 'Invalid/missing parameters: ' f'{exc.normalized_messages()}' ) existing_instrument = ( Instrument.query_records_accessible_by( self.current_user, ) .filter( Instrument.name == data.get('name'), Instrument.telescope_id == telescope_id, ) .first() ) if existing_instrument is None: instrument.telescope = telescope DBSession().add(instrument) DBSession().commit() else: instrument = existing_instrument if field_data is not None: if (field_region is None) and (field_fov_type is None): return self.error( 'field_region or field_fov_type is required with field_data' ) if type(field_data) is str: field_data = pd.read_table(StringIO(field_data), sep=",").to_dict( orient='list' ) if not {'ID', 'RA', 'Dec'}.issubset(field_data): return self.error("ID, RA, and Dec required in field_data.") log(f"Started generating fields for instrument {instrument.id}") # run async IOLoop.current().run_in_executor( None, lambda: add_tiles(instrument.id, instrument.name, regions, field_data), ) self.push_all(action="skyportal/REFRESH_INSTRUMENTS") return self.success(data={"id": instrument.id})
inner_width=0.1 * u.deg, outer_width=0.2 * u.deg, inner_height=0.3 * u.deg, outer_height=0.6 * u.deg, angle=130 * u.deg, ) finder.region = on_ellipse_annulus finder.reference_map = None finder.run() regions = finder.reflected_regions assert len(regions) == 5 center = SkyCoord(0.5, 0.0, unit="deg") other_region_finder_param = [ (RectangleSkyRegion(center, 0.5 * u.deg, 0.5 * u.deg, angle=0 * u.deg), 3), (RectangleSkyRegion(center, 0.5 * u.deg, 1 * u.deg, angle=0 * u.deg), 1), (RectangleSkyRegion(center, 0.5 * u.deg, 1 * u.deg, angle=90 * u.deg), 0), (EllipseSkyRegion(center, 0.1 * u.deg, 1 * u.deg, angle=0 * u.deg), 2), (EllipseSkyRegion(center, 0.1 * u.deg, 1 * u.deg, angle=60 * u.deg), 3), (EllipseSkyRegion(center, 0.1 * u.deg, 1 * u.deg, angle=90 * u.deg), 0), ] @pytest.mark.parametrize("region, nreg", other_region_finder_param) def test_non_circular_regions(region, nreg): pointing = SkyCoord(0.0, 0.0, unit="deg") finder = ReflectedRegionsFinder(center=pointing, region=region, min_distance_input="0 deg")
from astropy.coordinates import SkyCoord from regions import RectangleSkyRegion import matplotlib.pyplot as plt from gammapy.data import DataStore from gammapy.spectrum import ReflectedRegionsBackgroundEstimator data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") mask = data_store.obs_table["TARGET_NAME"] == "Crab" obs_ids = data_store.obs_table["OBS_ID"][mask].data observations = data_store.get_observations(obs_ids) crab_position = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") # The ON region center is defined in the icrs frame. The angle is defined w.r.t. to its axis. on_region = RectangleSkyRegion( center=crab_position, width=0.5 * u.deg, height=0.4 * u.deg, angle=0 * u.deg ) background_estimator = ReflectedRegionsBackgroundEstimator( observations=observations, on_region=on_region, min_distance=0.1 * u.rad ) background_estimator.run() # Let's inspect the data extracted in the first observation print(background_estimator.result[0]) background_estimator.plot() # Now we change the ON region, and use a center defined in the galactic frame
position = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") on_circle = CircleSkyRegion(position, 0.3 * u.deg) on_ellipse_annulus = EllipseAnnulusSkyRegion( center=position, inner_width=1.5 * u.deg, outer_width=2.5 * u.deg, inner_height=3 * u.deg, outer_height=4 * u.deg, angle=130 * u.deg, ) another_position = SkyCoord(80.3, 22.0, unit="deg") on_rectangle = RectangleSkyRegion(center=another_position, width=2.0 * u.deg, height=4.0 * u.deg, angle=50 * u.deg) # Now we plot those regions. We first create an empty map empty_map = WcsNDMap.create(skydir=position, width=10 * u.deg, binsz=0.1 * u.deg, proj="TAN") empty_map.data += 1.0 empty_map.plot(cmap="gray", vmin=0, vmax=1) # To plot the regions, we convert them to PixelRegion with the map wcs on_circle.to_pixel(empty_map.geom.wcs).plot() on_rectangle.to_pixel(empty_map.geom.wcs).plot() on_ellipse_annulus.to_pixel(empty_map.geom.wcs).plot()
from astropy.coordinates import Angle, SkyCoord from astropy import units as u from ..slit_overlay import SlitOverlay header = { 'S_REGION': 'POLYGON ICRS 5.029236065 4.992154276 5.029513148 4.992154276 5.029513148 4.992468585 5.029236065 4.992468585' } skycoord = SkyCoord(5.02937461, 4.99231143, unit=(u.Unit(u.deg), u.Unit(u.deg))) sky_region = RectangleSkyRegion(center=skycoord, width=Angle(0.0003143089999999251, u.deg), height=Angle(0.00027603191980735836, u.deg)) def todo_fix_test_slit_overlay(spectral_cube_wcs): app = Application() dc = app.data_collection dc.append( Data(x=np.ones((3, 4, 5)), label='test', coords=spectral_cube_wcs)) #so = SlitOverlay(app=app) # # so_sky_region = so.jwst_header_to_skyregion(header) # # assert np.allclose(sky_region.width.value, so_sky_region.width.value)
from gammapy.data import DataStore from gammapy.datasets import SpectrumDataset from gammapy.makers import ReflectedRegionsBackgroundMaker, SpectrumDatasetMaker from gammapy.maps import Map, MapAxis from gammapy.visualization import plot_spectrum_datasets_off_regions data_store = DataStore.from_dir("$GAMMAPY_DATA/hess-dl3-dr1/") mask = data_store.obs_table["TARGET_NAME"] == "Crab" obs_ids = data_store.obs_table["OBS_ID"][mask].data observations = data_store.get_observations(obs_ids) crab_position = SkyCoord(83.63, 22.01, unit="deg", frame="icrs") # The ON region center is defined in the icrs frame. The angle is defined w.r.t. to its axis. rectangle = RectangleSkyRegion(center=crab_position, width=0.5 * u.deg, height=0.4 * u.deg, angle=0 * u.deg) bkg_maker = ReflectedRegionsBackgroundMaker(min_distance=0.1 * u.rad) dataset_maker = SpectrumDatasetMaker(selection=["counts"]) e_reco = MapAxis.from_energy_bounds(0.1, 100, 30, unit="TeV") dataset_empty = SpectrumDataset.create(e_reco=e_reco, region=rectangle) datasets = [] for obs in observations: dataset = dataset_maker.run(dataset_empty.copy(name=f"obs-{obs.obs_id}"), obs) dataset_on_off = bkg_maker.run(observation=obs, dataset=dataset)
# Default plotting settings #circle.plot_region() # Different line styles, widths and colors #box.plot_region(lw=2, linestyle='--', ec='k') #ellipse.plot_region(lw=2, linestyle=':', ec='white') # Filling the region with a color #annulus.plot_region(lw=2, ec='purple', fc='purple') #Galactic_Center = SkyCoord('17:45:40.04', '−29:00:28.1', frame="icrs", unit=(u.hourangle, u.deg)) Galactic_Center = SkyCoord(0.0, 0.0, frame="galactic", unit=(u.deg, u.deg)) m = Map.create(binsz=2.0, width=(180.0, 24.0*15.0), skydir=Galactic_Center, frame="galactic", proj="TAN") #m.data.fill(0.0) m.plot(add_cbar=True) plane_survey_region = RectangleSkyRegion(center=SkyCoord(0.0,0.0, frame='galactic', unit=(u.deg, u.deg)), width=(2.0*85.0) * u.deg, height=20 * u.deg, angle=0.0*u.deg) LMC_region = RectangleSkyRegion(center=SkyCoord(280.4652, -32.8884, frame='galactic', unit=(u.deg, u.deg)), width=(322.827/60) * u.deg, height=(274.770/60) * u.deg, angle=0.0*u.deg) SMC_region = plane_survey_box = RegionGeom.create(plane_survey_region) LMC_box = RegionGeom.create(LMC_region) plane_survey_box.plot_region(lw=2, ec='purple', fc='purple', alpha=0.2) LMC_box.plot_region(lw=2, ec='purple', fc='purple') plt.show()
def put(self, instrument_id): """ --- description: Update instrument tags: - instruments parameters: - in: path name: instrument_id required: true schema: type: integer requestBody: content: application/json: schema: InstrumentNoID responses: 200: content: application/json: schema: Success 400: content: application/json: schema: Error """ data = self.get_json() data['id'] = int(instrument_id) # permission check instrument = Instrument.get_if_accessible_by( int(instrument_id), self.current_user, mode='update' ) if instrument is None: return self.error(f'Missing instrument with ID {instrument_id}') filters = instrument.filters sensitivity_data = data.get('sensitivity_data', None) if sensitivity_data: if not set(sensitivity_data.keys()).issubset(filters): return self.error( 'Filter names must be present in both sensitivity_data property and filters property' ) field_data = data.pop("field_data", None) field_region = data.pop("field_region", None) field_fov_type = data.pop("field_fov_type", None) field_fov_attributes = data.pop("field_fov_attributes", None) if (field_region is not None) and (field_fov_type is not None): return self.error('must supply only one of field_region or field_fov_type') if field_region is not None: regions = Regions.parse(field_region, format='ds9') data['region'] = regions.serialize(format='ds9') if field_fov_type is not None: if field_fov_attributes is None: return self.error( 'field_fov_attributes required if field_fov_type supplied' ) if not field_fov_type.lower() in ["circle", "rectangle"]: return self.error('field_fov_type must be circle or rectangle') if isinstance(field_fov_attributes, list): field_fov_attributes = [float(x) for x in field_fov_attributes] else: field_fov_attributes = [float(field_fov_attributes)] center = SkyCoord(0.0, 0.0, unit='deg', frame='icrs') if field_fov_type.lower() == "circle": if not len(field_fov_attributes) == 1: return self.error( 'If field_fov_type is circle, then should supply only radius for field_fov_attributes' ) radius = field_fov_attributes[0] regions = CircleSkyRegion(center=center, radius=radius * u.deg) elif field_fov_type.lower() == "rectangle": if not len(field_fov_attributes) == 2: return self.error( 'If field_fov_type is rectangle, then should supply width and height for field_fov_attributes' ) width, height = field_fov_attributes regions = RectangleSkyRegion( center=center, width=width * u.deg, height=height * u.deg ) data['region'] = regions.serialize(format='ds9') schema = Instrument.__schema__() try: schema.load(data, partial=True) except ValidationError as exc: return self.error( 'Invalid/missing parameters: ' f'{exc.normalized_messages()}' ) self.verify_and_commit() if field_data is not None: if (field_region is None) and (field_fov_type is None): return self.error( 'field_region or field_fov_type is required with field_data' ) if type(field_data) is str: field_data = pd.read_table(StringIO(field_data), sep=",").to_dict( orient='list' ) if not {'ID', 'RA', 'Dec'}.issubset(field_data): return self.error("ID, RA, and Dec required in field_data.") log(f"Started generating fields for instrument {instrument.id}") # run async IOLoop.current().run_in_executor( None, lambda: add_tiles(instrument.id, instrument.name, regions, field_data), ) self.push_all(action="skyportal/REFRESH_INSTRUMENTS") return self.success()