def cross_regions(cls, input_pointing_center, input_region_center, input_region_radius): """Return the three background regions starting from pointing and source one. Parameters ---------- input_pointing_center: SkyCoord or dict input_region_center: SkyCoord or dict input_region_radius: Angle or float Returns ------- array of regions """ # FIXME Wobble algorithm has no check about distance and region radius. pointing_center = utils.get_skycoord(input_pointing_center) region_center = utils.get_skycoord(input_region_center) region_radius = utils.get_angle(input_region_radius) radius = pointing_center.separation(region_center) starting_pos_angle = pointing_center.position_angle(region_center) regions = [] for i in range(1, 4): theta = starting_pos_angle + i * Angle(90, unit='deg') coord_pos = pointing_center.directional_offset_by(theta, radius) regions.append({ 'ra': coord_pos.ra.deg, 'dec': coord_pos.dec.deg, 'rad': region_radius.deg }) return regions
def region_counter(self, input_center, input_radius, emin=None, emax=None, tmin=None, tmax=None): """Counts photons in an input area""" region_center = utils.get_skycoord(input_center) region_radius = utils.get_angle(input_radius) # filtering... condlist = np.full(len(self.events_data.field('ENERGY')), True) # ... w/ energy boundaries if emin is not None: condlist &= self.events_data.field('ENERGY') >= emin if emax is not None: condlist &= self.events_data.field('ENERGY') <= emax # FIXME: TIME needs a better implementation # atm it consider users that knows the time format in the input fits if tmin is not None: condlist &= self.events_data.field('TIME') >= tmin if tmax is not None: condlist &= self.events_data.field('TIME') <= tmax events_list = np.extract(condlist, self.events_data) # events coordinates from the selected events list events_coords = SkyCoord(events_list.field('RA'), events_list.field('DEC'), unit='deg', frame='icrs') distances = region_center.separation(events_coords) return np.count_nonzero(distances < region_radius)
def reflected_regions(cls, input_pointing_center, input_region_center, input_region_radius): """Find regions with reflected algorithm. Parameters ---------- input_pointing_center: SkyCoord or dict input_region_center: SkyCoord or dict input_region_radius: Angle or float Returns ------- array of regions """ pointing_center = utils.get_skycoord(input_pointing_center) region_center = utils.get_skycoord(input_region_center) region_radius = utils.get_angle(input_region_radius) # Angular separation of reflected regions. 1.05 factor is to have a margin region_diameter = 1.05 * 2.0 * region_radius radius = pointing_center.separation(region_center) # the numbers_of_reflected regions is the number of center that can stay # on the circumference, NOT the really computated number of regions. # the number is floor down numbers_of_reflected_regions = int(2 * np.pi * radius / region_diameter) # Indeed, we skip the source region and the two near (see below), so we # need at least 4 centers to get one off region. if numbers_of_reflected_regions < 4: raise Exception( 'the combination of region radius and coordinates does not allow to compute reflected regions.' ) regions_offset_angle = Angle(360, unit='deg') / numbers_of_reflected_regions regions = [] # starting from the source region 0, we skip region 1 and region N, so 2..N-1 starting_pos_angle = pointing_center.position_angle(region_center) for i in range(2, numbers_of_reflected_regions - 1): theta = starting_pos_angle + i * regions_offset_angle coord_pos = pointing_center.directional_offset_by(theta, radius) regions.append({ 'ra': coord_pos.ra.deg, 'dec': coord_pos.dec.deg, 'rad': region_radius.deg }) return regions
def write_region(cls, coords, filename, **kwargs): try: iter(coords) except TypeError as te: raise Exception('Coords must be iterable') circles = [] for coord in coords: center = utils.get_skycoord(coord) rad = utils.get_angle(coord['rad']) circles.append( CircleSkyRegion(center=center, radius=rad, visual=kwargs)) write_ds9(circles, filename)
def get_thetas(pointing, midpoints): for k in ['ra', 'dec']: if k in pointing: continue raise Exception('pointing coord {} is missing.'.format(k)) if len(midpoints) < 1: raise Exception('need at least 1 point to check') pnt = utils.get_skycoord(pointing) midpoints_ra = [] midpoints_dec = [] for p in midpoints: midpoints_ra.append(p['ra']) midpoints_dec.append(p['dec']) midpoints_coords = SkyCoord(midpoints_ra, midpoints_dec, unit='deg', frame='icrs') return [ang.degree for ang in pnt.separation(midpoints_coords)]
def select_pixels_in_region(midpoints, region): for k in ['ra', 'dec', 'rad']: if k in region: continue raise Exception('region data missing {} mandatory key.'.format(k)) if region['rad'] <= 0: raise Exception('region radius must be > 0') if len(midpoints) < 1: raise Exception('need at least 1 point to check') region_center = utils.get_skycoord(region) region_radius = utils.get_angle(region['rad']) midpoints_ra = [] midpoints_dec = [] for p in midpoints: midpoints_ra.append(p['ra']) midpoints_dec.append(p['dec']) midpoints_coords = SkyCoord(midpoints_ra, midpoints_dec, unit='deg', frame='icrs') distances = region_center.separation(midpoints_coords) return np.extract(distances < region_radius, midpoints)