def __init__(self, data_radius, model_radius, *args, **kwargs): """ A cone Region of Interest defined by a center and a radius. Examples: ROI centered on (R.A., Dec) = (1.23, 4.56) in J2000 ICRS coordinate system, with a radius of 5 degrees: > roi = HealpixConeROI(5.0, ra=1.23, dec=4.56) ROI centered on (L, B) = (1.23, 4.56) (Galactic coordiantes) with a radius of 30 arcmin: > roi = HealpixConeROI(30.0 * u.arcmin, l=1.23, dec=4.56) :param data_radius: radius of the cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param model_radius: radius of the model cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param args: arguments for the SkyDirection class of astromodels :param kwargs: keywords for the SkyDirection class of astromodels """ self._center = SkyDirection(*args, **kwargs) self._data_radius_radians = _get_radians(data_radius) self._model_radius_radians = _get_radians(model_radius)
def __init__(self, data_radius, model_radius, roimap=None, roifile=None, threshold=0.5, *args, **kwargs): """ A cone Region of Interest defined by a healpix map (can be read from a fits file). User needs to supply a cone region (center and radius) defining the plane projection for the model map. Examples: Model map centered on (R.A., Dec) = (1.23, 4.56) in J2000 ICRS coordinate system, with a radius of 5 degrees, ROI defined in healpix map in fitsfile: > roi = HealpixMapROI(model_radius=5.0, data_radius=4.0, ra=1.23, dec=4.56, file = "myROI.fits" ) Model map centered on (L, B) = (1.23, 4.56) (Galactic coordiantes) with a radius of 30 arcmin, ROI defined on-the-fly in healpix map: > roi = HealpixMapROI(model_radius=30.0 * u.arcmin, data_radius=20.0 * u.arcmin, l=1.23, dec=4.56, map = my_roi) :param model_radius: radius of the model cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param data_radius: radius used for displaying maps. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees. Note: THIS RADIUS IS JUST USED FOR PLOTTING, DOES NOT AFFECT THE FIT. :param map: healpix map containing the ROI. :param file: fits file containing a healpix map with the ROI. :param threshold: value below which pixels in the map will be set inactive (=not in ROI). :param args: arguments for the SkyDirection class of astromodels :param kwargs: keywords for the SkyDirection class of astromodels """ assert roifile is not None or roimap is not None, "Must supply either healpix map or fitsfile to create HealpixMapROI" self._center = SkyDirection(*args, **kwargs) self._model_radius_radians = _get_radians(model_radius) self._data_radius_radians = _get_radians(data_radius) self._threshold = threshold self.read_map(roimap=roimap, roifile=roifile)
def __init__(self, source_name: str, ra: Optional[float] = None, dec: Optional[float] = None, spectral_shape: Optional[Function1D] = None, l: Optional[float] = None, b: Optional[float] = None, components=None, sky_position: Optional[SkyDirection] = None): # Check that we have all the required information # (the '^' operator acts as XOR on booleans) # Check that we have one and only one specification of the position if not ((ra is not None and dec is not None) ^ (l is not None and b is not None) ^ (sky_position is not None)): log.error( "You have to provide one and only one specification for the position" ) raise AssertionError() # Gather the position if not isinstance(sky_position, SkyDirection): if (ra is not None) and (dec is not None): # Check that ra and dec are actually numbers try: ra = float(ra) dec = float(dec) except (TypeError, ValueError): log.error( "RA and Dec must be numbers. If you are confused by this message, you " "are likely using the constructor in the wrong way. Check the documentation." ) raise AssertionError() sky_position = SkyDirection(ra=ra, dec=dec) else: sky_position = SkyDirection(l=l, b=b) self._sky_position: SkyDirection = sky_position # Now gather the component(s) # We need either a single component, or a list of components, but not both # (that's the ^ symbol) if not (spectral_shape is not None) ^ (components is not None): log.error( "You have to provide either a single component, or a list of components (but not both)." ) raise AssertionError() # If the user specified only one component, make a list of one element with a default name ("main") if spectral_shape is not None: components = [SpectralComponent("main", spectral_shape)] Source.__init__(self, components, src_type=SourceType.POINT_SOURCE) # A source is also a Node in the tree Node.__init__(self, source_name) # Add the position as a child node, with an explicit name self._add_child(self._sky_position) # Add a node called 'spectrum' spectrum_node = Node('spectrum') spectrum_node._add_children(list(self._components.values())) self._add_child(spectrum_node) # Now set the units # Now sets the units of the parameters for the energy domain current_units = get_units() # Components in this case have energy as x and differential flux as y x_unit = current_units.energy y_unit = (current_units.energy * current_units.area * current_units.time)**(-1) # Now set the units of the components for component in list(self._components.values()): component.shape.set_units(x_unit, y_unit)
class HealpixConeROI(HealpixROIBase): def __init__(self, data_radius, model_radius, *args, **kwargs): """ A cone Region of Interest defined by a center and a radius. Examples: ROI centered on (R.A., Dec) = (1.23, 4.56) in J2000 ICRS coordinate system, with a radius of 5 degrees: > roi = HealpixConeROI(5.0, ra=1.23, dec=4.56) ROI centered on (L, B) = (1.23, 4.56) (Galactic coordiantes) with a radius of 30 arcmin: > roi = HealpixConeROI(30.0 * u.arcmin, l=1.23, dec=4.56) :param data_radius: radius of the cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param model_radius: radius of the model cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param args: arguments for the SkyDirection class of astromodels :param kwargs: keywords for the SkyDirection class of astromodels """ self._center = SkyDirection(*args, **kwargs) self._data_radius_radians = _get_radians(data_radius) self._model_radius_radians = _get_radians(model_radius) def to_dict(self): ra, dec = self.ra_dec_center s = { 'ROI type': type(self).__name__.split(".")[-1], 'ra': ra, 'dec': dec, 'data_radius_deg': np.rad2deg(self._data_radius_radians), 'model_radius_deg': np.rad2deg(self._model_radius_radians) } return s @classmethod def from_dict(cls, data): return cls(data['data_radius_deg'], data['model_radius_deg'], ra=data['ra'], dec=data['dec']) def __str__(self): s = ( "%s: Center (R.A., Dec) = (%.3f, %.3f), data radius = %.3f deg, model radius: %.3f deg" % (type(self).__name__, self.ra_dec_center[0], self.ra_dec_center[1], self.data_radius.to( u.deg).value, self.model_radius.to(u.deg).value)) return s def display(self): log.info(self) @property def ra_dec_center(self): return self._get_ra_dec() @property def data_radius(self): return self._data_radius_radians * u.rad @property def model_radius(self): return self._model_radius_radians * u.rad def _get_ra_dec(self): lon, lat = self._center.get_ra(), self._center.get_dec() return lon, lat def _get_healpix_vec(self): lon, lat = self._get_ra_dec() vec = radec_to_vec(lon, lat) return vec def _active_pixels(self, nside, ordering): vec = self._get_healpix_vec() nest = ordering is _NESTED pixels_inside_cone = hp.query_disc(nside, vec, self._data_radius_radians, inclusive=False, nest=nest) return pixels_inside_cone def get_flat_sky_projection(self, pixel_size_deg): # Decide side for image # Compute number of pixels, making sure it is going to be even (by approximating up) npix_per_side = 2 * int( np.ceil( old_div(np.rad2deg(self._model_radius_radians), pixel_size_deg))) # Get lon, lat of center ra, dec = self._get_ra_dec() # This gets a list of all RA, Decs for an AIT-projected image of npix_per_size x npix_per_side flat_sky_proj = FlatSkyProjection(ra, dec, pixel_size_deg, npix_per_side, npix_per_side) return flat_sky_proj
lm = load_model("hadronic/cocoon.yml") fluxUnit = 1. / (u.TeV * u.cm**2 * u.s) E = np.logspace(np.log10(1), np.log10(100), 100) * u.TeV spectrumPP_BPL = cutoff_pp() shapeD = Gaussian_on_sphere() hawcRA = 307.65 hawcDec = 40.93 from astromodels.core.sky_direction import SkyDirection position = SkyDirection(hawcRA, hawcDec) sourceCutP = ExtendedSource("cocoon_PP_BPL", spatial_shape=shapeD, spectral_shape=spectrumPP_BPL) # NOTE: if you use units, you have to set up the values for the parameters shapeD.lon0=hawcRA*u.degree shapeD.lat0=hawcDec*u.degree shapeD.lon0.fix=True shapeD.lat0.fix=True shapeD.sigma = 2*u.degree shapeD.sigma.fix = True shapeD.sigma.bounds = (0.2,2.0)*u.degree
class HealpixMapROI(HealpixROIBase): def __init__(self, model_radius, roimap=None, roifile=None, threshold=0.5, ceiling=1.0, *args, **kwargs): """ A cone Region of Interest defined by a healpix map (can be read from a fits file). User needs to supply a cone region (center and radius) defining the plane projection for the model map. Examples: Model map centered on (R.A., Dec) = (1.23, 4.56) in J2000 ICRS coordinate system, with a radius of 5 degrees, ROI defined in healpix map in fitsfile: > roi = HealpixMapROI(5.0, ra=1.23, dec=4.56, file = "myROI.fits" ) Model map centered on (L, B) = (1.23, 4.56) (Galactic coordiantes) with a radius of 30 arcmin, ROI defined on-the-fly in healpix map: > roi = HealpixMapROI(30.0 * u.arcmin, l=1.23, dec=4.56, map = my_roi) :param model_radius: radius of the model cone. Either an astropy.Quantity instance, or a float, in which case it is assumed to be the radius in degrees :param map: healpix map containing the ROI. :param file: fits file containing a healpix map with the ROI. :param threshold: value below which pixels in the map will be set inactive (=not in ROI). :param ceiling: value above which pixels in the map will be set inactive (=not in ROI). :param args: arguments for the SkyDirection class of astromodels :param kwargs: keywords for the SkyDirection class of astromodels """ assert roifile is not None or roimap is not None, "Must supply either healpix map or fitsfile to create HealpixMapROI" self._center = SkyDirection(*args, **kwargs) self._model_radius_radians = _get_radians(model_radius) self._threshold = threshold self._ceiling = ceiling self.read_map(roimap=roimap, roifile=roifile) def read_map(self, roimap=None, roifile=None): assert roifile is not None or roimap is not None, \ "Must supply either healpix map or fits file" if roimap is not None: roimap = roimap self._filename = None elif roifile is not None: self._filename = roifile roimap = hp.fitsfunc.read_map(self._filename) self._roimaps = {} self._original_nside = hp.npix2nside(roimap.shape[0]) self._roimaps[self._original_nside] = roimap self.check_roi_inside_model() def check_roi_inside_model(self): active_pixels = self.active_pixels(self._original_nside) radius = np.rad2deg(self._model_radius_radians) ra, dec = self.ra_dec_center temp_roi = HealpixConeROI(data_radius=radius, model_radius=radius, ra=ra, dec=dec) model_pixels = temp_roi.active_pixels(self._original_nside) if not all(p in model_pixels for p in active_pixels): custom_warnings.warn( "Some pixels inside your ROI are not contained in the model map." ) def to_dict(self): ra, dec = self.ra_dec_center s = { 'ROI type': type(self).__name__.split(".")[-1], 'ra': ra, 'dec': dec, 'model_radius_deg': np.rad2deg(self._model_radius_radians), 'roimap': self._roimaps[self._original_nside], 'threshold': self._threshold, 'ceiling': self._ceiling, 'roifile': self._filename } return s @classmethod def from_dict(cls, data): return cls(data['model_radius_deg'], threshold=data['threshold'], celing=data['ceiling'], roimap=data['roimap'], ra=data['ra'], dec=data['dec'], roifile=data['roifile']) def __str__(self): s = ( "%s: Center (R.A., Dec) = (%.3f, %.3f), model radius: %.3f deg, threshold = %.2f, ceiling = % .2f" % (type(self).__name__, self.ra_dec_center[0], self.ra_dec_center[1], self.model_radius.to( u.deg).value, self._threshold, self._ceiling)) if self._filename is not None: s = "%s, data ROI from %s" % (s, self._filename) return s def display(self): print(self) @property def ra_dec_center(self): return self._get_ra_dec() @property def model_radius(self): return self._model_radius_radians * u.rad @property def threshold(self): return self._threshold def ceiling(self): return self._ceiling def _get_ra_dec(self): lon, lat = self._center.get_ra(), self._center.get_dec() return lon, lat def _active_pixels(self, nside, ordering): if not nside in self._roimaps: self._roimaps[nside] = hp.ud_grade( self._roimaps[self._original_nside], nside_out=nside) pixels_inside_roi = np.where((self._roimaps[nside] >= self._threshold) & (self._roimaps[nside] < self._ceiling))[0] return pixels_inside_roi def get_flat_sky_projection(self, pixel_size_deg): # Decide side for image # Compute number of pixels, making sure it is going to be even (by approximating up) npix_per_side = 2 * int( np.ceil(np.rad2deg(self._model_radius_radians) / pixel_size_deg)) # Get lon, lat of center ra, dec = self._get_ra_dec() # This gets a list of all RA, Decs for an AIT-projected image of npix_per_size x npix_per_side flat_sky_proj = FlatSkyProjection(ra, dec, pixel_size_deg, npix_per_side, npix_per_side) return flat_sky_proj