stdpipe 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stdpipe/__init__.py +9 -0
- stdpipe/artefacts.py +370 -0
- stdpipe/astrometry.py +2001 -0
- stdpipe/astrometry_quad.py +1643 -0
- stdpipe/astrometry_wcs.py +1141 -0
- stdpipe/catalogs.py +942 -0
- stdpipe/cutouts.py +570 -0
- stdpipe/data/legacysurvey_bricks.fits.gz +0 -0
- stdpipe/data/ps1skycells.txt +199708 -0
- stdpipe/db.py +130 -0
- stdpipe/fringe_removal.py +1086 -0
- stdpipe/lcs.py +440 -0
- stdpipe/photometry.py +2340 -0
- stdpipe/photometry_background.py +998 -0
- stdpipe/photometry_iraf.py +913 -0
- stdpipe/photometry_measure.py +2268 -0
- stdpipe/photometry_model.py +931 -0
- stdpipe/photometry_psf.py +1124 -0
- stdpipe/photometry_quality.py +185 -0
- stdpipe/pipeline.py +1303 -0
- stdpipe/plots.py +1582 -0
- stdpipe/psf.py +1542 -0
- stdpipe/realbogus.py +971 -0
- stdpipe/realbogus_features.py +1657 -0
- stdpipe/reproject.py +943 -0
- stdpipe/resolve.py +267 -0
- stdpipe/sfft.py +1077 -0
- stdpipe/simulation.py +2131 -0
- stdpipe/smoothing.py +488 -0
- stdpipe/subtraction.py +1324 -0
- stdpipe/templates.py +929 -0
- stdpipe/utils.py +365 -0
- stdpipe-0.4.0.dist-info/METADATA +171 -0
- stdpipe-0.4.0.dist-info/RECORD +37 -0
- stdpipe-0.4.0.dist-info/WHEEL +5 -0
- stdpipe-0.4.0.dist-info/licenses/LICENSE.md +21 -0
- stdpipe-0.4.0.dist-info/top_level.txt +1 -0
stdpipe/resolve.py
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import xml.dom.minidom as minidom
|
|
2
|
+
import requests
|
|
3
|
+
import json
|
|
4
|
+
import re
|
|
5
|
+
import io
|
|
6
|
+
|
|
7
|
+
from astropy.coordinates import SkyCoord
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def simbadResolve(name='m31'):
|
|
11
|
+
url = 'http://cdsweb.u-strasbg.fr/viz-bin/nph-sesame/-oxpi/SNVA'
|
|
12
|
+
res = requests.get(url, params=requests.utils.quote(name))
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
xml = minidom.parseString(res.content)
|
|
16
|
+
|
|
17
|
+
r = xml.getElementsByTagName('Resolver')[0]
|
|
18
|
+
|
|
19
|
+
name = r.getElementsByTagName('oname')[0].childNodes[0].nodeValue
|
|
20
|
+
ra = float(r.getElementsByTagName('jradeg')[0].childNodes[0].nodeValue)
|
|
21
|
+
dec = float(r.getElementsByTagName('jdedeg')[0].childNodes[0].nodeValue)
|
|
22
|
+
|
|
23
|
+
return name, ra, dec
|
|
24
|
+
except:
|
|
25
|
+
return None, None, None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def parseSexadecimal(string):
|
|
29
|
+
value = 0
|
|
30
|
+
|
|
31
|
+
m = re.search("^\s*([+-])?\s*(\d{1,3})\s+(\d{1,2})\s+(\d{1,2}\.?\d*)\s*$", string) or re.search(
|
|
32
|
+
"^\s*([+-])?\s*(\d{1,3})\:(\d{1,2})\:(\d{1,2}\.?\d*)\s*$", string
|
|
33
|
+
)
|
|
34
|
+
if m:
|
|
35
|
+
value = float(m.group(2)) + float(m.group(3)) / 60 + float(m.group(4)) / 3600
|
|
36
|
+
|
|
37
|
+
if m.group(1) == '-':
|
|
38
|
+
value = -value
|
|
39
|
+
|
|
40
|
+
return value
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def tnsResolve(name='AT2023lxx'):
|
|
44
|
+
# Normalize AT name to have whitespace before year
|
|
45
|
+
m = re.match('^(AT)\s*(2\w+)$', name)
|
|
46
|
+
if m:
|
|
47
|
+
name = m[1] + ' ' + m[2]
|
|
48
|
+
|
|
49
|
+
for reverse in [False, True]:
|
|
50
|
+
params = {'resolver': 'tns', 'name': name}
|
|
51
|
+
if reverse:
|
|
52
|
+
params.update({'reverse': True})
|
|
53
|
+
|
|
54
|
+
r = requests.post("https://api.ztf.fink-portal.org/api/v1/resolver", json=params)
|
|
55
|
+
|
|
56
|
+
res = json.loads(r.content)
|
|
57
|
+
if res:
|
|
58
|
+
break
|
|
59
|
+
|
|
60
|
+
if res:
|
|
61
|
+
return res[0]['d:fullname'], res[0]['d:ra'], res[0]['d:declination']
|
|
62
|
+
|
|
63
|
+
return None, None, None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def resolve(string='M33', verbose=False):
|
|
67
|
+
"""
|
|
68
|
+
Resolve the object name (or coordinates string) into proper coordinates on the sky.
|
|
69
|
+
|
|
70
|
+
This function attempts multiple resolution methods in order:
|
|
71
|
+
1. Decimal degrees (RA Dec in degrees)
|
|
72
|
+
2. Sexagesimal coordinates (hours/degrees with minutes and seconds)
|
|
73
|
+
3. Simbad name resolution (astronomical objects)
|
|
74
|
+
4. TNS name resolution (transients)
|
|
75
|
+
5. Astropy SkyCoord.from_name() (fallback)
|
|
76
|
+
|
|
77
|
+
Parameters
|
|
78
|
+
----------
|
|
79
|
+
string : str, optional
|
|
80
|
+
Input string to resolve (object name or coordinates).
|
|
81
|
+
verbose : bool or callable, optional
|
|
82
|
+
Enable verbose output. Can be True/False or a print-like function.
|
|
83
|
+
|
|
84
|
+
Returns
|
|
85
|
+
-------
|
|
86
|
+
astropy.coordinates.SkyCoord or None
|
|
87
|
+
Resolved sky coordinates, or None if resolution fails.
|
|
88
|
+
|
|
89
|
+
**Supported Coordinate Formats:**
|
|
90
|
+
|
|
91
|
+
1. **Decimal degrees** (RA and Dec in degrees, space or comma separated):
|
|
92
|
+
- ``"123.456 45.678"`` → RA=123.456°, Dec=+45.678°
|
|
93
|
+
- ``"123.456, 45.678"`` → RA=123.456°, Dec=+45.678° (comma-separated)
|
|
94
|
+
- ``"123.456 -45.678"`` → RA=123.456°, Dec=-45.678°
|
|
95
|
+
- ``"10.68, 41.27"`` → RA=10.68°, Dec=+41.27° (M31)
|
|
96
|
+
|
|
97
|
+
2. **Sexagesimal coordinates** (space-separated or colon-separated):
|
|
98
|
+
- Space format: ``"HH MM SS.ss ±DD MM SS.ss"``
|
|
99
|
+
- Colon format: ``"HH:MM:SS.ss ±DD:MM:SS.ss"``
|
|
100
|
+
- Comma can separate RA from Dec: ``"HH MM SS.ss, ±DD MM SS.ss"``
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
- ``"12 34 56.7 +45 12 34.5"`` → RA=12h 34m 56.7s, Dec=+45° 12' 34.5"
|
|
104
|
+
- ``"12 34 56.7, +45 12 34.5"`` → Same (comma between RA and Dec)
|
|
105
|
+
- ``"12:34:56.7 +45:12:34.5"`` → RA=12h 34m 56.7s, Dec=+45° 12' 34.5"
|
|
106
|
+
- ``"12:34:56.7, +45:12:34.5"`` → Same (comma between RA and Dec)
|
|
107
|
+
- ``"12 34 56 45 12 34"`` → Dec assumed positive if no sign
|
|
108
|
+
- ``"00 42 44.3, +41 16 09"`` → M31 coordinates (comma-separated)
|
|
109
|
+
|
|
110
|
+
**Note:** RA is interpreted as **hours** (multiplied by 15 to convert to degrees),
|
|
111
|
+
Dec is interpreted as **degrees**. This is the standard astronomical convention.
|
|
112
|
+
|
|
113
|
+
3. **Object names** (resolved via Simbad, TNS, or Astropy):
|
|
114
|
+
- Messier objects: ``"M31"``, ``"M 31"``, ``"m31"``
|
|
115
|
+
- NGC/IC objects: ``"NGC1234"``, ``"IC 5146"``
|
|
116
|
+
- Named stars: ``"Betelgeuse"``, ``"Vega"``
|
|
117
|
+
- Transients: ``"AT2023lxx"``, ``"AT 2023lxx"``, ``"SN2023ixf"``
|
|
118
|
+
- Coordinates as names: ``"12h34m56s +45d12m34s"`` (via Astropy)
|
|
119
|
+
|
|
120
|
+
**Resolution Priority:**
|
|
121
|
+
|
|
122
|
+
The function tries methods in order and returns the first successful match:
|
|
123
|
+
1. Decimal degrees parsing (fastest, no network)
|
|
124
|
+
2. Sexagesimal parsing (fast, no network)
|
|
125
|
+
3. Simbad query (network required)
|
|
126
|
+
4. TNS query via Fink API (network required, for transients)
|
|
127
|
+
5. Astropy SkyCoord.from_name() (network required, CDS Sesame)
|
|
128
|
+
|
|
129
|
+
**Examples:**
|
|
130
|
+
|
|
131
|
+
>>> from stdpipe.resolve import resolve
|
|
132
|
+
>>>
|
|
133
|
+
>>> # Decimal degrees
|
|
134
|
+
>>> target = resolve("10.68 41.27")
|
|
135
|
+
>>> print(target.ra.deg, target.dec.deg)
|
|
136
|
+
10.68 41.27
|
|
137
|
+
>>>
|
|
138
|
+
>>> # Decimal degrees (comma-separated)
|
|
139
|
+
>>> target = resolve("10.68, 41.27")
|
|
140
|
+
>>> print(target.ra.deg, target.dec.deg)
|
|
141
|
+
10.68 41.27
|
|
142
|
+
>>>
|
|
143
|
+
>>> # Sexagesimal (space-separated)
|
|
144
|
+
>>> target = resolve("12 34 56 +45 12 34")
|
|
145
|
+
>>> print(f"{target.ra.deg:.2f} {target.dec.deg:.2f}")
|
|
146
|
+
188.73 45.21
|
|
147
|
+
>>>
|
|
148
|
+
>>> # Sexagesimal (comma between RA and Dec)
|
|
149
|
+
>>> target = resolve("12 34 56, +45 12 34")
|
|
150
|
+
>>> print(f"{target.ra.deg:.2f} {target.dec.deg:.2f}")
|
|
151
|
+
188.73 45.21
|
|
152
|
+
>>>
|
|
153
|
+
>>> # Sexagesimal (colon-separated)
|
|
154
|
+
>>> target = resolve("00:42:44.3 +41:16:09")
|
|
155
|
+
>>> print(f"{target.ra.deg:.2f} {target.dec.deg:.2f}")
|
|
156
|
+
10.68 41.27
|
|
157
|
+
>>>
|
|
158
|
+
>>> # Sexagesimal (colon-separated with comma)
|
|
159
|
+
>>> target = resolve("00:42:44.3, +41:16:09")
|
|
160
|
+
>>> print(f"{target.ra.deg:.2f} {target.dec.deg:.2f}")
|
|
161
|
+
10.68 41.27
|
|
162
|
+
>>>
|
|
163
|
+
>>> # Object name (requires network)
|
|
164
|
+
>>> target = resolve("M31", verbose=True)
|
|
165
|
+
Resolved by Simbad as M 31
|
|
166
|
+
RA = 10.6847 deg, Dec = 41.2688 deg
|
|
167
|
+
>>>
|
|
168
|
+
>>> # Transient name (requires network)
|
|
169
|
+
>>> target = resolve("AT2023lxx", verbose=True)
|
|
170
|
+
Resolved by TNS as AT 2023lxx
|
|
171
|
+
RA = 123.4560 deg, Dec = -45.6780 deg
|
|
172
|
+
>>>
|
|
173
|
+
>>> # Failed resolution returns None
|
|
174
|
+
>>> target = resolve("InvalidObject123")
|
|
175
|
+
>>> print(target)
|
|
176
|
+
None
|
|
177
|
+
|
|
178
|
+
**Verbose Mode:**
|
|
179
|
+
|
|
180
|
+
When ``verbose=True``, prints resolution method and result:
|
|
181
|
+
|
|
182
|
+
>>> target = resolve("123.456 45.678", verbose=True)
|
|
183
|
+
Resolved as two values in degrees
|
|
184
|
+
RA = 123.4560 deg, Dec = 45.6780 deg
|
|
185
|
+
|
|
186
|
+
You can also provide a custom logging function:
|
|
187
|
+
|
|
188
|
+
>>> def my_log(*args):
|
|
189
|
+
... print("[RESOLVER]", *args)
|
|
190
|
+
>>> target = resolve("M31", verbose=my_log)
|
|
191
|
+
[RESOLVER] Resolved by Simbad as M 31
|
|
192
|
+
[RESOLVER] RA = 10.6847 deg, Dec = 41.2688 deg
|
|
193
|
+
|
|
194
|
+
**Network Requirements:**
|
|
195
|
+
|
|
196
|
+
- Decimal/sexagesimal parsing: No network required
|
|
197
|
+
- Simbad resolution: Queries http://cdsweb.u-strasbg.fr
|
|
198
|
+
- TNS resolution: Queries https://api.ztf.fink-portal.org
|
|
199
|
+
- Astropy fallback: Queries CDS Sesame service
|
|
200
|
+
|
|
201
|
+
If network is unavailable, only coordinate parsing will work. Object name
|
|
202
|
+
resolution will fail silently and return None.
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
# Simple wrapper around print for logging in verbose mode only
|
|
206
|
+
log = (verbose if callable(verbose) else print) if verbose else lambda *args, **kwargs: None
|
|
207
|
+
|
|
208
|
+
target = None
|
|
209
|
+
|
|
210
|
+
if target is None:
|
|
211
|
+
m = re.search(r"^\s*(\d+\.?\d*)\s*[,\s]+\s*([+-]?\d+\.?\d*)\s*$", string)
|
|
212
|
+
if m:
|
|
213
|
+
log("Resolved as two values in degrees")
|
|
214
|
+
|
|
215
|
+
ra = float(m.group(1))
|
|
216
|
+
dec = float(m.group(2))
|
|
217
|
+
|
|
218
|
+
target = SkyCoord(ra, dec, unit='deg')
|
|
219
|
+
|
|
220
|
+
if target is None:
|
|
221
|
+
m = re.search(
|
|
222
|
+
r"^\s*(\d{1,2})\s+(\d{1,2})\s+(\d{1,2}\.?\d*)\s*[,\s]+\s*([+-])?\s*(\d{1,3})\s+(\d{1,2})\s+(\d{1,2}\.?\d*)\s*$",
|
|
223
|
+
string,
|
|
224
|
+
) or re.search(
|
|
225
|
+
r"^\s*(\d{1,2})\:(\d{1,2})\:(\d{1,2}\.?\d*)\s*[,\s]+\s*([+-])?\s*(\d{1,3})\:(\d{1,2})\:(\d{1,2}\.?\d*)\s*$",
|
|
226
|
+
string,
|
|
227
|
+
)
|
|
228
|
+
if m:
|
|
229
|
+
log("Resolved as two sexadecimal values, interpreted as hours and degrees")
|
|
230
|
+
|
|
231
|
+
ra = (float(m.group(1)) + float(m.group(2)) / 60 + float(m.group(3)) / 3600) * 15
|
|
232
|
+
dec = float(m.group(5)) + float(m.group(6)) / 60 + float(m.group(7)) / 3600
|
|
233
|
+
|
|
234
|
+
if m.group(4) == '-':
|
|
235
|
+
dec = -dec
|
|
236
|
+
|
|
237
|
+
target = SkyCoord(ra, dec, unit='deg')
|
|
238
|
+
|
|
239
|
+
if target is None:
|
|
240
|
+
name, ra, dec = simbadResolve(string)
|
|
241
|
+
|
|
242
|
+
if name:
|
|
243
|
+
log("Resolved by Simbad as", name)
|
|
244
|
+
|
|
245
|
+
target = SkyCoord(ra, dec, unit='deg')
|
|
246
|
+
|
|
247
|
+
if target is None:
|
|
248
|
+
name, ra, dec = tnsResolve(string)
|
|
249
|
+
|
|
250
|
+
if name:
|
|
251
|
+
log("Resolved by TNS as", name)
|
|
252
|
+
|
|
253
|
+
target = SkyCoord(ra, dec, unit='deg')
|
|
254
|
+
|
|
255
|
+
if target is None:
|
|
256
|
+
try:
|
|
257
|
+
target = SkyCoord.from_name(string, parse=True)
|
|
258
|
+
log("Resolved by Astropy SkyCoord.from_name()")
|
|
259
|
+
except:
|
|
260
|
+
pass
|
|
261
|
+
|
|
262
|
+
if target is not None:
|
|
263
|
+
log(f"RA = {target.ra.deg:.4f} deg, Dec = {target.dec.deg:.4f} deg")
|
|
264
|
+
else:
|
|
265
|
+
log(f"Failed to resolve", string)
|
|
266
|
+
|
|
267
|
+
return target
|