forked from ErikOsinga/POSSUMutils
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathquery_status.py
More file actions
197 lines (158 loc) · 6.69 KB
/
query_status.py
File metadata and controls
197 lines (158 loc) · 6.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
"""
Created on 2024-01-25
Query POSSUM status page maintained by Cameron van Eck for some target RA,DEC
Simply scrapes the data from the HTML source page:
view-source:https://www.mso.anu.edu.au/~cvaneck/possum/aladin_survey_band1.html
and checks whether coordinates fall inside one of the field with a certain status.
Assumes flat sky, so might not work for sources on boundary of observations?
Returns:
True or False
@author: Erik Osinga
"""
import re
import astropy.units as u
import requests
from astropy.coordinates import SkyCoord
from astroquery.simbad import Simbad
from bs4 import BeautifulSoup
from shapely.geometry import Point, Polygon
stages = {
"released": "validated_field_overlay",
"observed": "observed_field_overlay",
"processed": "processed_field_overlay",
"planned": "field_overlay",
}
def adjust_coordinates_for_wraparound(coordinate_pairs, adjust_positive=True):
"""When a polygon is defined near the 0 RA boundary, return adjusted RA coords
e.g. a polygon defined in RA by [(357, DEC), (2, DEC)] will be returned either as
adjust_positive=True -- [(357,DEC), (362,DEC)]
adjust_positive=False -- [(-3,DEC), (2,DEC)]
such that points laying near the RA=0 boundary will be correctly identified as laying in a polygon
"""
ra_values = [coord[0] for coord in coordinate_pairs]
if max(ra_values) - min(ra_values) > 180:
if adjust_positive:
adjusted_pairs = [
(ra + 360 if ra < 180 else ra, dec) for ra, dec in coordinate_pairs
]
else:
adjusted_pairs = [
(ra - 360 if ra > 180 else ra, dec) for ra, dec in coordinate_pairs
]
return adjusted_pairs
return coordinate_pairs
def get_overlay_polygons(stage, band=1):
"""
Find all polygons of a certain class, see above, e.g.
'validated_field_overlay' - fields that are released
'observed_field_overlay' - fields that are observed
'processed_field_overlay' - fields that are processed
'field_overlay' - fields that are planned
"""
overlay_name = stages[stage]
# URL of the webpage
if band == 1:
url = "https://www.mso.anu.edu.au/~cvaneck/possum/aladin_survey_band1.html"
elif band == 2:
url = "https://www.mso.anu.edu.au/~cvaneck/possum/aladin_survey_band2.html"
else:
raise ValueError(f"Band has to be 1 or 2, input is {band}")
# Send an HTTP GET request to the webpage
response = requests.get(url)
# Check if the request was successful (status code 200)
if response.status_code == 200:
# Parse the HTML content of the webpage
soup = BeautifulSoup(response.content, "html.parser")
# Extract all script tags
script_tags = soup.find_all("script")
# Search for the script tags containing the specified overlay
overlay_polygons = []
for line in script_tags[2].text.split("\n"):
if f"{overlay_name}.addFootprints" in line:
# Define a regular expression pattern to find all floating-point numbers
pattern = r"-?\d+\.\d+"
# Use re.findall to extract all matching numbers from the string
numbers = re.findall(pattern, line)
# Group the numbers into coordinate pairs
coordinate_pairs = [
(float(numbers[i]), float(numbers[i + 1]))
for i in range(0, len(numbers), 2)
]
if coordinate_pairs is not None:
adjusted_pairs = adjust_coordinates_for_wraparound(
coordinate_pairs, adjust_positive=True
)
if adjusted_pairs == coordinate_pairs:
# Simple case
overlay_polygons.append(Polygon(coordinate_pairs))
if adjusted_pairs != coordinate_pairs:
# Append two polygons, one with positive RA values only
# and one with negative RA values
overlay_polygons.append(Polygon(adjusted_pairs))
adjusted_pairs = adjust_coordinates_for_wraparound(
coordinate_pairs, adjust_positive=False
)
overlay_polygons.append(Polygon(adjusted_pairs))
return overlay_polygons
return None
def check_coordinates_in_overlay(ra, dec, overlay_name, band=1, overlay_polygons=None):
# Get the list of polygons corresponding to the specified overlay
# polygons can be given as input as well to speed up multiple code runs
if ra < 0:
print(f"WARNING: RA={ra:.2f} degrees, changing to lie within [0-360] degrees.")
ra += 360
if not overlay_polygons:
overlay_polygons = get_overlay_polygons(overlay_name, band)
if overlay_polygons:
# Check if the given RA, DEC falls inside any of the polygons
point = Point(ra, dec)
for polygon in overlay_polygons:
if polygon.contains(point):
return True
return False
def get_coordinates_from_simbad(target_name):
simbad = Simbad()
result_table = simbad.query_object(target_name)
if (
result_table is not None
and "ra" in result_table.colnames
and "dec" in result_table.colnames
):
# Convert coordinates from sexagesimal to degrees using astropy
coords = SkyCoord(
result_table["ra"][0], result_table["dec"][0], unit=(u.hourangle, u.deg)
)
return coords.ra.deg, coords.dec.deg
else:
print(f"Target {target_name} not found in Simbad")
return None
if __name__ == "__main__":
# Which observing band (1 = 800-1088 MHz, 2 = 1296-1440 MHz)
band = 1
# Which status to query
stage = "released"
# stage = 'planned'
# Example usage with coordinates
target = None
ra_input = 252.5
dec_input = -41.9
# Example usage with target name, query SIMBAD
target = "Abell 85"
target = "Abell 1651"
target = "Abell 3627"
target = "Dorado Group"
# target = 'Abell 3526'
# target = 'Abell S 636'
ra_input, dec_input = get_coordinates_from_simbad(target)
# Compute whether target is in the requested field type
result = check_coordinates_in_overlay(ra_input, dec_input, stage, band)
if target:
print(f"Results of searching for target {target}:")
if result:
print(
f"The coordinates (RA={ra_input:.3f}, DEC={dec_input:.3f}) fall inside band {band} {stage} fields."
)
else:
print(
f"The coordinates (RA={ra_input:.3f}, DEC={dec_input:.3f}) do not fall inside band {band} {stage} fields."
)