comparison pipeline_sources.py @ 0:a35056104c2c draft default tip

planemo upload for repository https://github.com/esg-epfl-apc/tools-astro/tree/main/tools commit da42ae0d18f550dec7f6d7e29d297e7cf1909df2
author astroteam
date Fri, 13 Jun 2025 13:26:36 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:a35056104c2c
1 import pandas as pd
2 import numpy as np
3 import re
4 import time
5 import io
6 import requests
7 from astroquery.simbad import Simbad
8 from astropy.coordinates import SkyCoord
9 from astropy import units as u
10
11 from query_tns_aux import parse_data, query_tns_main_name, query_tns_survey_name
12
13
14 def query_simbad(name):
15 Simbad.add_votable_fields("otypes")
16
17 table_ids = Simbad.query_objectids(name)
18 table_obj = Simbad.query_object(name)
19
20 dict_data = {}
21
22 list_ids = None
23 main_id = None
24 otype_ = None
25 ra = None
26 dec = None
27 if table_ids:
28 df_ids = table_ids.to_pandas()
29 df_ids.columns = df_ids.columns.str.upper()
30 list_ids = list(df_ids["ID"].str.decode("utf-8").values)
31 if table_obj:
32 df_obj = table_obj.to_pandas()
33 df_obj.columns = df_obj.columns.str.upper()
34 main_id = df_obj["MAIN_ID"].values[0]
35 otype_ = '|'.join(list(set(df_obj["OTYPES.OTYPE"].values)))
36 str_ra_dec = str(df_obj["RA"].values[0]) + " " + str(df_obj["DEC"].values[0])
37 ra_dec = SkyCoord(str_ra_dec, unit=(u.hourangle, u.deg))
38 ra = ra_dec.ra.value
39 dec = ra_dec.dec.value
40
41 dict_data[name] = {"IDs": list_ids, "MAIN_ID": main_id, "OTYPES": otype_, "RA": ra, "DEC": dec, "DISCOVERY_TIME": None}
42
43 return dict_data
44
45
46 def query_tns(name):
47 dict_data = {}
48
49 if ((name[0:3] == "at2") or (name[0:2] == "sn")):
50 my_text = query_tns_main_name(name[2:])
51 else:
52 my_text = query_tns_survey_name(name)
53
54 time.sleep(5)
55
56 main_id, list_ids, list_otypes, ra, dec, discovery_time = parse_data(my_text)
57 if ra and dec:
58 str_ra_dec = ra + ":" + dec
59 ra_dec = SkyCoord(str_ra_dec.replace(":", " "), unit=(u.hourangle, u.deg))
60 ra = ra_dec.ra.value
61 dec = ra_dec.dec.value
62
63 if list_otypes is None:
64 otype_ = None
65 elif len(list_otypes) == 1:
66 otype_ = list_otypes[0]
67 else:
68 otype_ = '|'.join(list_otypes)
69
70 dict_data[name] = {"IDs": list_ids, "MAIN_ID": main_id, "OTYPES": otype_, "RA": ra, "DEC": dec, "DISCOVERY_TIME": discovery_time}
71
72 return dict_data
73
74
75 def query_fink(name):
76 dict_data = {}
77 list_ids = None
78 main_id = None
79 otype_ = None
80 ra = None
81 dec = None
82 discovery_time = None
83
84 query_name = name.replace("ztf", "ZTF")
85 r = requests.post('https://api.fink-portal.org/api/v1/objects', json={'objectId': query_name, 'output-format': 'json', 'columns': 'i:ra,i:dec,i:objectId'})
86 # Format output in a DataFrame
87 df = pd.read_json(io.BytesIO(r.content))
88 if not df.empty:
89 object_id = df["i:objectId"].values[0]
90 main_id = object_id
91 ra_tmp = df["i:ra"][df["i:objectId"] == object_id].values
92 dec_tmp = df["i:dec"][df["i:objectId"] == object_id].values
93 ra = np.mean(np.float32(ra_tmp))
94 dec = np.mean(np.float32(dec_tmp))
95 list_ids = '|'.join(list(set(df["i:objectId"].values)))
96
97 dict_data[name] = {"IDs": list_ids, "MAIN_ID": main_id, "OTYPES": otype_, "RA": ra, "DEC": dec, "DISCOVERY_TIME": discovery_time}
98
99 return dict_data
100
101
102 def create_pattern_list():
103 pattern_list_low = []
104 pattern_list_low += ["\\b(ngc) *?([0-9]{1,4})\\b", "\\b(m) *?([0-9]{1,3})\\b"]
105 pattern_list_low += ["\\b(ugc) *?([0-9]{1,5})\\b"]
106
107 pattern_list_low += ["\\b(icecube|grb|frb|pks|mrk|hawc|maxi|gw)([ -]?)([0-9\\.\\-\\+]{2,}[a-z]?)\\b"]
108 pattern_list_low += ["\\b(ic)([ -]?)([0-9]{1,4})\\b"]
109 pattern_list_low += ["\\b(ztf) *?([0-9]{2}[a-z]{7})\\b"]
110
111 pattern_list_low += ["\\b(at|sn) *?([1-2]{1}[0-9]{3}[a-z]{1,4})\\b"]
112 pattern_list_low += ["\\b(asas)([ -]?)(sn)([ -]?)([0-9]{2}[a-z]{2,3})\\b"]
113
114 pattern_list_low += ["\\b(ps|gaia) *?([1-2]{1}[0-9]{1}[a-z]{1,4})\\b"]
115
116 pattern_list_low += ["\\b(m31n) *?([0-9]{4})-([0-9]{2}[a-z]{1})\\b"]
117 pattern_list_low += ["\\b(ptf|atlas) *?([0-9]{2}[a-z]{1,4})\\b"]
118
119 pattern_list_low += ["\\b(4c) *?((\\+|-)[0-9]{2}\\.[0-9]{2}\\.[0-9]{1})\\b"]
120 pattern_list_low += ["\\b(4c) *?((\\+|-)[0-9]{2}\\.[0-9]{2})\\b"]
121
122 # new from lm-astronomy
123 pattern_list_low += ["\\b(lsq12) *?([a-z]{3})\\b"]
124 pattern_list_low += ["\\b(des14) *?([a-z]{1}[0-9]{1})\\b"]
125
126 pattern_list = []
127
128 HH = "(2[0-4]|[0-1][0-9])"
129 MM = "(90|[0-8][0-9])"
130 MMm = "(90|[0-8][0-9])([0-9])"
131 SS = "(90|[0-8][0-9])"
132 DD = "(90|[0-8][0-9])"
133 pDDd = "(\\+|-)(90|[0-8][0-9])([0-9])"
134
135 LLL = "([0-9][0-9][0-9])"
136 BB = "([0-9][0-9])"
137 VVV = "([0-9][0-9][0-9])"
138
139 NAAA = "(([0-9][A-Z]{1,4})|([A-Z]{2,4}))"
140
141 pattern_list += [f"\\b{NAAA} *?([0-9]{{6}})(?!-)\\b"]
142
143 pattern_list += [f"\\b{NAAA} *?(J[0-9]{{6}}(\\+|-)[0-9]{{5}})(?!-)\\b"]
144 pattern_list += [f"\\b{NAAA} *?(J[0-9]{{6}}(\\.?)[0-9]{{1}}(\\+|-)[0-9]{{6}})(?!-)\\b"]
145
146 pattern_list += [f"\\b{NAAA} *?(J[0-9]{{4}}(\\.?)[0-9]{{1}}(\\+|-)[0-9]{{4}})[a-z]{{0,1}}(?!-)\\b"]
147 pattern_list += [f"\\b{NAAA} *?{HH}{MM}(\\+|-){DD}(?!-)\\b"]
148 pattern_list += [f"\\b{NAAA} *?(J?){HH}{MM}{pDDd}(?!-)\\b"]
149 pattern_list += [f"\\b{NAAA} *?B{HH}{MM}(\\+|-){DD}(?!-)\\b"]
150 pattern_list += [f"\\b{NAAA} *?B{HH}{MM}{pDDd}(?!-)\\b"]
151 pattern_list += [f"\\b{NAAA} *?J{HH}{MM}(\\+|-){DD}{MM}(?!-)\\b"]
152 pattern_list += [f"\\b{NAAA} *?J{HH}{MM}([0-9])(\\+|-){DD}{MM}(?!-)\\b"]
153
154 pattern_list += [f"\\b{NAAA} *?{HH}{MMm}(\\+|-){DD}{MM}(?!-)\\b"]
155 pattern_list += [f"\\b{NAAA} *?{HH}{MM}(\\.?)([0-9])(\\+|-){DD}{MM}(?!-)\\b"]
156 pattern_list += [f"\\b{NAAA} *?{HH}{MM}{SS}(\\+|-){DD}{MM}{SS}(?!-)\\b"]
157 pattern_list += [f"\\b{NAAA} *?{HH}{MM}{SS}(\\.?)([0-9])(\\+|-){DD}{MM}{SS}(?!-)\\b"]
158 pattern_list += [f"\\b{NAAA} *?B{HH}{MM}{SS}(\\.?)([0-9])(\\+|-){DD}{MM}{SS}(?!-)\\b"]
159 pattern_list += [f"\\b{NAAA} *?J{HH}{MM}{SS}(\\.?)([0-9][0-9])(\\+|-){DD}{MM}{SS}(\\.?)([0-9])(?!-)\\b"]
160
161 pattern_list += [f"\\b{NAAA} *?{LLL}(\\.?)([0-9])(\\+|-){BB}(\\.?)([0-9])(\\+|-){VVV}(?!-)\\b"]
162 pattern_list += [f"\\b{NAAA} *?G{LLL}(\\.?)([0-9])(\\+|-){BB}(\\.?)([0-9])(\\+|-){VVV}(?!-)\\b"]
163
164 FFF = "([0-9][0-9][0-9])"
165 FFFF = "([0-9][0-9][0-9][0-9])"
166 NNNN = FFFF
167 NNNNN = "([0-9][0-9][0-9][0-9][0-9])"
168
169 pattern_list += [f"\\b{NAAA} *?{FFF}-{NNNN}(?!-)\\b"]
170 pattern_list += [f"\\b{NAAA} *?{FFFF}-{NNNNN}(?!-)\\b"]
171
172 YY = "[0-9][0-9]"
173 MM = "[0-1][0-9]"
174 DD = "[0-3][0-9]"
175 pattern_list += [f"\\b{NAAA} *?{YY}{MM}{DD}A{{0,1}}(?!-)\\b"]
176
177 return pattern_list, pattern_list_low
178
179
180 def rule_based_source_detector(text_id, text_id_text):
181 pattern_list, pattern_list_low = create_pattern_list()
182
183 regex_sources = []
184
185 for pattern in pattern_list_low:
186 for m in re.finditer(pattern, text_id_text.lower()):
187 source_ = m.group(0).replace(" ", "")
188
189 if "asas" in source_:
190 source_ = source_.replace("-", "")
191 source_ = source_.replace("sn", "sn-")
192
193 regex_sources.append(source_)
194
195 for pattern in pattern_list:
196 for m in re.finditer(pattern, text_id_text):
197 source_ = m.group(0)
198 if source_.replace(" ", "").lower() not in regex_sources:
199 regex_sources.append(source_)
200
201 return list(set(regex_sources))
202
203
204 def query_info_sources(text_id, sources):
205 if len(sources) != 0:
206 source_list = []
207 otype_list = []
208 mainid_list = []
209 ra_list = []
210 dec_list = []
211 pattern_string = re.compile("[a-z]")
212 dict_unknown = {}
213 dict_unknown = {"Raw Source Name": []}
214
215 for source_name_0 in sources:
216 # TODO: remove all non a-z0-9 characters from the beginning and ending of the source name
217 # Now: remove "," from the beginning and ending of the source name
218 if source_name_0[0] == ",":
219 source_name = source_name_0[1:]
220 elif source_name_0[-1] == ",":
221 source_name = source_name_0[:-1]
222 else:
223 source_name = source_name_0
224
225 if pattern_string.findall(source_name.lower()):
226 dict_otype = query_simbad(source_name)
227 if dict_otype[source_name]["MAIN_ID"] is None:
228 dict_otype = query_tns(source_name)
229 if dict_otype[source_name]["MAIN_ID"] is None:
230 dict_otype = query_fink(source_name)
231
232 if dict_otype[source_name]["MAIN_ID"] is None:
233 dict_unknown["Raw Source Name"].append(source_name)
234 else:
235 mainid_list.append(dict_otype[source_name]["MAIN_ID"])
236 otype_list.append(dict_otype[source_name]["OTYPES"])
237 ra_list.append(dict_otype[source_name]["RA"])
238 dec_list.append(dict_otype[source_name]["DEC"])
239 source_list.append(source_name)
240 else:
241 dict_unknown["Raw Source Name"].append(source_name_0)
242
243 dict_data = {"TEXT_ID": [text_id] * len(source_list), "Raw Source Name": source_list, "Main ID Name": mainid_list, "OTYPE": otype_list, "RA": ra_list, "Dec": dec_list}
244 df_save = pd.DataFrame(dict_data)
245 df_save.replace({None: "NotKnown"}, inplace=True)
246 return df_save.drop_duplicates(subset=['Main ID Name']), pd.DataFrame(dict_unknown)
247
248 return pd.DataFrame(), pd.DataFrame()