Commit 93da7e73 authored by Wu You's avatar Wu You
Browse files

Upload New File

parent 57991da9
import healpy as hp
import numpy as np
from .brick_core import generate_bricks
from .brick_utils import angular_distance
def bricks_in_disc(nside, ra_center, dec_center, radius_deg, overlap):
"""
Find all bricks whose centers are within a circular region.
Parameters
----------
nside : int
HEALPix resolution parameter.
ra_center : float
Right Ascension of the circular region center (deg).
dec_center : float
Declination of the circular region center (deg).
radius_deg : float
Search radius of the circular region (deg).
overlap : float
Overlap factor to enlarge brick radius
(1.0 = no overlap, >1.0 = enlarged).
Returns
-------
list of Brick
A list of Brick objects whose centers fall within the given region.
"""
theta = np.radians(90 - dec_center)
phi = np.radians(ra_center)
radius_rad = np.radians(radius_deg)
vec = hp.ang2vec(theta, phi)
pix_ids = hp.query_disc(nside, vec, radius_rad)
return [generate_bricks(nside, pid, overlap=overlap) for pid in pix_ids]
def neighbor_bricks(nside, brick_id, overlap):
"""
Get all neighboring bricks of a given brick.
Parameters
----------
nside : int
HEALPix resolution parameter.
brick_id : int
The HEALPix pixel (brick) ID for which neighbors are to be found.
overlap : float
Overlap factor to enlarge brick radius
(1.0 = no overlap, >1.0 = enlarged).
Returns
-------
list of Brick
A list of Brick objects corresponding to the neighboring pixels.
"""
neighbors = hp.get_all_neighbours(nside, brick_id)
neighbors = [n for n in neighbors if n >= 0]
return [generate_bricks(nside, n, overlap=overlap) for n in neighbors]
def nearest_brick_with_distance(nside, ra, dec, overlap):
"""
Find the nearest brick to a given (RA, Dec) position and its angular distance.
Parameters
----------
nside : int
HEALPix resolution parameter.
ra : float
Right Ascension of the target position (deg).
dec : float
Declination of the target position (deg).
overlap : float
Overlap factor to enlarge brick radius
(1.0 = no overlap, >1.0 = enlarged).
Returns
-------
tuple
brick : Brick
The nearest Brick object to the given (RA, Dec) position.
dist_deg : float
The angular distance between the point and the brick center (deg).
"""
theta = np.radians(90 - dec)
phi = np.radians(ra)
pix_id = hp.ang2pix(nside, theta, phi)
brick = generate_bricks(nside, pix_id, overlap=overlap)
ra1, dec1 = np.radians(ra), np.radians(dec)
ra2, dec2 = np.radians(brick.ra), np.radians(brick.dec)
dist_deg = np.degrees(angular_distance(ra1, dec1, ra2, dec2))
return brick, dist_deg
def point_in_brick_with_distance(nside, ra, dec, brick_id, overlap):
"""
Check if a given point (RA, Dec) lies within a specific brick and
return its angular distance to the brick center.
Parameters
----------
nside : int
HEALPix resolution parameter.
ra : float
Right Ascension of the target point (deg).
dec : float
Declination of the target point (deg).
brick_id : int
The HEALPix pixel (brick) ID to check.
overlap : float
Overlap factor to enlarge brick radius
(1.0 = no overlap, >1.0 = enlarged).
Returns
-------
tuple
inside : bool
True if the point lies within the brick (distance <= brick.radius).
dist : float
Angular distance between the point and the brick center (deg).
"""
brick = generate_bricks(nside, brick_id, overlap=overlap)
ra1, dec1 = np.radians(ra), np.radians(dec)
ra2, dec2 = np.radians(brick.ra), np.radians(brick.dec)
dist = np.degrees(angular_distance(ra1, dec1, ra2, dec2))
return dist <= brick.radius, dist
def bricks_containing_point(nside, ra, dec, overlap, search_margin=5):
"""
Find all bricks that contain a given point (RA, Dec).
Parameters
----------
nside : int
HEALPix resolution parameter.
ra : float
Right Ascension of the target point (deg).
dec : float
Declination of the target point (deg).
overlap : float
Overlap factor to enlarge brick radius
(1.0 = no overlap, >1.0 = enlarged).
search_margin : float, optional
Search margin to expand the maximum search radius. Default is 5.
Returns
-------
list of Brick
A list of Brick objects whose radius contains the given point.
"""
max_radius = (180 / (np.pi * np.sqrt(3) * nside)) * search_margin * overlap
theta = np.radians(90 - dec)
phi = np.radians(ra)
vec = hp.ang2vec(theta, phi)
pix_ids = hp.query_disc(nside, vec, np.radians(max_radius), inclusive=True)
result = []
for pid in pix_ids:
brick = generate_bricks(nside, pid, overlap=overlap)
ra1, dec1 = np.radians(ra), np.radians(dec)
ra2, dec2 = np.radians(brick.ra), np.radians(brick.dec)
dist = np.degrees(angular_distance(ra1, dec1, ra2, dec2))
if dist <= brick.radius:
result.append(brick)
return result
class BrickQueries:
def __init__(self, nside, overlap=1.0):
self.nside = nside
self.overlap = overlap
self.methods = {
"disc_bricks": self.get_bricks_in_disc,
"neighbors": self.get_neighbor_bricks,
"nearest": self.get_nearest_brick_with_distance,
"contains_point": self.point_in_brick,
"find_bricks": self.get_bricks_containing_point
}
def __getattr__(self, name):
if name in self.methods:
return self.methods[name]
else:
raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{name}'")
def get_bricks_in_disc(self, ra_center, dec_center, radius_deg):
return bricks_in_disc(self.nside, ra_center, dec_center, radius_deg, self.overlap)
def get_neighbor_bricks(self, brick_id):
return neighbor_bricks(self.nside, brick_id, self.overlap)
def get_nearest_brick_with_distance(self, ra, dec):
return nearest_brick_with_distance(self.nside, ra, dec, self.overlap)
def point_in_brick(self, ra, dec, brick_id):
return point_in_brick_with_distance(self.nside, ra, dec, brick_id, self.overlap)
def get_bricks_containing_point(self, ra, dec, search_margin=5):
return bricks_containing_point(self.nside, ra, dec, self.overlap, search_margin)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment