fits.py 4.33 KB
Newer Older
Wei Shoulin's avatar
Wei Shoulin committed
1
2
3
from astropy_healpix import HEALPix
from astropy.coordinates import ICRS
from astropy import units as u
Wei Shoulin's avatar
C9    
Wei Shoulin committed
4
from astropy.coordinates import SkyCoord
Wei Shoulin's avatar
Wei Shoulin committed
5
from astropy.io import fits
Wei Shoulin's avatar
C9    
Wei Shoulin committed
6

Wei Shoulin's avatar
Wei Shoulin committed
7
from csst_dfs_commons.models.constants import PI, DEFAULT_NSIDE
Wei Shoulin's avatar
add hp    
Wei Shoulin committed
8

Wei Shoulin's avatar
Wei Shoulin committed
9
def get_header_value(key: str, headers, default_value = None):
Wei Shoulin's avatar
Wei Shoulin committed
10
    try:
Wei Shoulin's avatar
Wei Shoulin committed
11
12
13
14
15
16
17
18
        ret_value = None
        if not isinstance(headers, list):
            headers = [headers]
        for header in headers:
            if key in header:
                ret_value = header[key]
                if type(ret_value) == str:
                    return ret_value.strip()
Wei Shoulin's avatar
Wei Shoulin committed
19
                return ret_value
Wei Shoulin's avatar
Wei Shoulin committed
20
21
        if ret_value is None:
            return default_value
Wei Shoulin's avatar
Wei Shoulin committed
22
    except Exception as e:
Wei Shoulin's avatar
Wei Shoulin committed
23
24
        return default_value

Wei Shoulin's avatar
Wei Shoulin committed
25
def get_healpix_id(ra, dec, nside=256):
Wei Shoulin's avatar
Wei Shoulin committed
26
27
28
29
30
31
    try:
        hp = HEALPix(nside=nside, order='nested', frame=ICRS())
        coord = SkyCoord(ra = ra * u.deg, dec = dec * u.deg, frame='icrs')
        return hp.skycoord_to_healpix(coord)
    except:
        return -1
Wei Shoulin's avatar
h    
Wei Shoulin committed
32

Wei Shoulin's avatar
Wei Shoulin committed
33
def get_healpix_ids(ra, dec, radius, nside=256):
Wei Shoulin's avatar
h    
Wei Shoulin committed
34
35
    hp = HEALPix(nside=nside, order='nested', frame=ICRS())
    coord = SkyCoord(ra = ra * u.deg, dec = dec * u.deg, frame='icrs')
Wei Shoulin's avatar
Wei Shoulin committed
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    return hp.cone_search_skycoord(coord, radius = radius * u.deg)

def get_raw_header(filepath, **keys):
    union = {}
    with fits.open(filepath, **keys) as hdulist:
        for hdu in hdulist:
            for card in hdu.header.cards:
                card.verify('fix')
                key, value = card.keyword, card.value
                if not key:
                    continue
                union[key]= value
    return union

Wei Shoulin's avatar
Wei Shoulin committed
50
def heapix_sql_condition(ra, dec, radius, ra_col = 'ra', dec_col = 'dec', nside = DEFAULT_NSIDE):
Wei Shoulin's avatar
C9    
Wei Shoulin committed
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
    """
    生成用于筛选特定天区范围内数据的SQL条件语句(大圆公式)。
    
    Args:
        ra (float): 天区中心的赤经值,单位为度。
        dec (float): 天区中心的赤纬值,单位为度。
        radius (float): 天区的半径,单位为度。
        ra_col (str, optional): 数据表中赤经值的列名,默认为'ra'。
        dec_col (str, optional): 数据表中赤纬值的列名,默认为'dec'。
        nside (int, optional): Healpix像素化的nside参数,默认为DEFAULT_NSIDE。
    
    Returns:
        str: 用于筛选特定天区范围内数据的SQL条件语句。
    
    """
Wei Shoulin's avatar
Wei Shoulin committed
66
    arcDec = (PI / 180) * dec
Wei Shoulin's avatar
C9    
Wei Shoulin committed
67
    whereSql = f"abs((180./pi()) * ACOS(SIN(pi() * {dec_col}/180) * SIN({arcDec}) + COS(pi() * {dec_col}/180) * COS({arcDec}) * COS(pi()* ({ra_col} - {ra})/180))) < {radius}"
Wei Shoulin's avatar
Wei Shoulin committed
68
69
70
71
72
73

    heapix_ids = get_healpix_ids(ra, dec, radius, nside)
    nside_column = "NS%dHIdx" % (nside,)
    whereZoneSql = "%s in (%s)" % \
                (nside_column, ','.join([str(i) for i in heapix_ids]))
    
Wei Shoulin's avatar
C9    
Wei Shoulin committed
74
    return f"{whereSql} and {whereZoneSql}"
Wei Shoulin's avatar
C9    
Wei Shoulin committed
75
76

def catalog_heapix_sql_condition(ra, dec, radius, ra_col = 'ra', dec_col = 'dec', nside = DEFAULT_NSIDE):
Wei Shoulin's avatar
C9    
Wei Shoulin committed
77
78
79
    x2 = f"cos(pi()*{dec_col}/180.0)*cos(pi()*{ra_col}/180.0)"
    y2 = f"cos(pi()*{dec_col}/180.0)*sin(pi()*{ra_col}/180.0)"
    z2 = f"sin(pi()*{dec_col}/180.0)"
Wei Shoulin's avatar
C9    
Wei Shoulin committed
80

Wei Shoulin's avatar
C9    
Wei Shoulin committed
81
82
83
    x1 = f"cos(pi()*{dec}/180.0)*cos(pi()*{ra}/180.0)"
    y1 = f"cos(pi()*{dec}/180.0)*sin(pi()*{ra}/180.0)"
    z1 = f"sin(pi()*{dec}/180.0)"
Wei Shoulin's avatar
C9    
Wei Shoulin committed
84
85
86
87
88
89
90

    distance = f"pow(({x2}-{x1}),2)+pow(({y2}-{y1}),2)+pow(({z2}-{z1}),2)"

    heapix_ids = get_healpix_ids(ra, dec, radius, nside)
    nside_column = "NS%dHIdx" % (nside,)
    whereZoneSql = "%s in (%s)" % \
                (nside_column, ','.join([str(i) for i in heapix_ids]))
Wei Shoulin's avatar
C9    
Wei Shoulin committed
91
    whereSql = f"{distance} <= 4*pow(pi()*{radius}/180.0/2, 2) and {whereZoneSql}"
Wei Shoulin's avatar
Wei Shoulin committed
92
    
Wei Shoulin's avatar
C9    
Wei Shoulin committed
93
94
    return whereSql

Wei Shoulin's avatar
Wei Shoulin committed
95
def dfs_heapix_sql_condition(ra, dec, radius, ra_col = 'ra', dec_col = 'dec', brick_col = "brick_id", nside = DEFAULT_NSIDE):
Wei Shoulin's avatar
C9    
Wei Shoulin committed
96
97
98
    x2 = f"cos(pi()*{dec_col}/180.0)*cos(pi()*{ra_col}/180.0)"
    y2 = f"cos(pi()*{dec_col}/180.0)*sin(pi()*{ra_col}/180.0)"
    z2 = f"sin(pi()*{dec_col}/180.0)"
Wei Shoulin's avatar
Wei Shoulin committed
99

Wei Shoulin's avatar
C9    
Wei Shoulin committed
100
101
102
    x1 = f"cos(pi()*{dec}/180.0)*cos(pi()*{ra}/180.0)"
    y1 = f"cos(pi()*{dec}/180.0)*sin(pi()*{ra}/180.0)"
    z1 = f"sin(pi()*{dec}/180.0)"
Wei Shoulin's avatar
Wei Shoulin committed
103
104
105
106
107

    distance = f"pow(({x2}-{x1}),2)+pow(({y2}-{y1}),2)+pow(({z2}-{z1}),2)"

    heapix_ids = get_healpix_ids(ra, dec, radius, nside)
    whereZoneSql = "%s in (%s)" % \
Wei Shoulin's avatar
Wei Shoulin committed
108
                (brick_col, ','.join([str(i) for i in heapix_ids]))
Wei Shoulin's avatar
Wei Shoulin committed
109
    
Wei Shoulin's avatar
C9    
Wei Shoulin committed
110
    whereSql = f"{distance} <= 4*pow(pi()*{radius}/180.0/2, 2) and {whereZoneSql}"
Wei Shoulin's avatar
Wei Shoulin committed
111

Wei Shoulin's avatar
Wei Shoulin committed
112
    return whereSql