thuban 0.0.2__tar.gz → 0.0.3__tar.gz
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.
- {thuban-0.0.2 → thuban-0.0.3}/PKG-INFO +1 -1
- {thuban-0.0.2 → thuban-0.0.3}/pyproject.toml +1 -1
- {thuban-0.0.2 → thuban-0.0.3}/thuban/catalog.py +6 -1
- {thuban-0.0.2 → thuban-0.0.3}/thuban/pointing.py +28 -17
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/PKG-INFO +1 -1
- {thuban-0.0.2 → thuban-0.0.3}/LICENSE +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/MANIFEST.in +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/README.md +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/setup.cfg +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_catalog.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_cli.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_distortion.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_pointing.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_util.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/tests/test_visualize.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/__init__.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/cli.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/data/reduced_hip.csv +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/distortion.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/error.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/simulate.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/util.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban/visualize.py +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/SOURCES.txt +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/dependency_links.txt +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/entry_points.txt +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/requires.txt +0 -0
- {thuban-0.0.2 → thuban-0.0.3}/thuban.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: thuban
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.3
|
4
4
|
Summary: High precision and accuracy astrometric image solving from a guess
|
5
5
|
Author-email: "J. Marcus Hughes" <hughes.jmb@gmail.com>
|
6
6
|
Maintainer-email: "J. Marcus Hughes" <hughes.jmb@gmail.com>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import os
|
2
|
+
from typing import Callable
|
2
3
|
|
3
4
|
import astropy.units as u
|
4
5
|
import numpy as np
|
@@ -163,7 +164,7 @@ def filter_for_visible_stars(catalog: pd.DataFrame, dimmest_magnitude: float = 6
|
|
163
164
|
|
164
165
|
|
165
166
|
def find_catalog_in_image(
|
166
|
-
catalog: pd.DataFrame, wcs: WCS, image_shape: (int, int),
|
167
|
+
catalog: pd.DataFrame, wcs: WCS, image_shape: (int, int), mask: Callable = None,
|
167
168
|
mode: str = "all"
|
168
169
|
) -> np.ndarray:
|
169
170
|
"""Using the provided WCS converts the RA/DEC catalog into pixel coordinates
|
@@ -195,6 +196,10 @@ def find_catalog_in_image(
|
|
195
196
|
except NoConvergence as e:
|
196
197
|
xs, ys = e.best_solution[:, 0], e.best_solution[:, 1]
|
197
198
|
bounds_mask = (0 <= xs) * (xs < image_shape[0]) * (0 <= ys) * (ys < image_shape[1])
|
199
|
+
|
200
|
+
if mask is not None:
|
201
|
+
bounds_mask *= mask(xs, ys)
|
202
|
+
|
198
203
|
reduced_catalog = catalog[bounds_mask].copy()
|
199
204
|
reduced_catalog["x_pix"] = xs[bounds_mask]
|
200
205
|
reduced_catalog['y_pix'] = ys[bounds_mask]
|
@@ -1,9 +1,11 @@
|
|
1
1
|
import warnings
|
2
|
+
from typing import Callable
|
2
3
|
|
3
4
|
import numpy as np
|
4
5
|
import pandas as pd
|
5
6
|
import sep_pjw as sep
|
6
7
|
from astropy.wcs import WCS, utils
|
8
|
+
import astropy.units as u
|
7
9
|
from lmfit import Parameters, minimize
|
8
10
|
|
9
11
|
from thuban.catalog import (filter_for_visible_stars, find_catalog_in_image,
|
@@ -47,19 +49,21 @@ def calculate_pc_matrix(crota: float, cdelt: (float, float)) -> np.ndarray:
|
|
47
49
|
"""
|
48
50
|
return np.array(
|
49
51
|
[
|
50
|
-
[np.cos(crota), np.sin(crota) * (cdelt[0] / cdelt[1])],
|
51
|
-
[
|
52
|
+
[np.cos(crota), -np.sin(crota) * (cdelt[0] / cdelt[1])],
|
53
|
+
[np.sin(crota) * (cdelt[1] / cdelt[0]), np.cos(crota)],
|
52
54
|
],
|
53
55
|
)
|
54
56
|
|
55
57
|
|
56
|
-
|
57
58
|
def _residual(params: Parameters,
|
58
59
|
observed_coords: np.ndarray,
|
59
60
|
catalog: pd.DataFrame,
|
60
61
|
guess_wcs: WCS,
|
61
62
|
n: int,
|
62
|
-
image_shape: (int, int)
|
63
|
+
image_shape: (int, int),
|
64
|
+
edge: int = 100,
|
65
|
+
sigma: float = 3.0,
|
66
|
+
mask: Callable = None):
|
63
67
|
"""Residual used when optimizing the pointing
|
64
68
|
|
65
69
|
Parameters
|
@@ -86,13 +90,13 @@ def _residual(params: Parameters,
|
|
86
90
|
refined_wcs.wcs.crpix = guess_wcs.wcs.crpix
|
87
91
|
refined_wcs.wcs.crval = (params["crval1"].value, params["crval2"].value)
|
88
92
|
refined_wcs.wcs.pc = calculate_pc_matrix(params["crota"], refined_wcs.wcs.cdelt)
|
89
|
-
refined_wcs.cpdis1 = guess_wcs.cpdis1
|
93
|
+
refined_wcs.cpdis1 = guess_wcs.cpdis1
|
90
94
|
refined_wcs.cpdis2 = guess_wcs.cpdis2
|
95
|
+
refined_wcs.wcs.set_pv(guess_wcs.wcs.get_pv())
|
91
96
|
|
92
|
-
reduced_catalog = find_catalog_in_image(catalog, refined_wcs, image_shape=image_shape)
|
97
|
+
reduced_catalog = find_catalog_in_image(catalog, refined_wcs, image_shape=image_shape, mask=mask)
|
93
98
|
refined_coords = np.stack([reduced_catalog['x_pix'], reduced_catalog['y_pix']], axis=-1)
|
94
99
|
|
95
|
-
edge = 300
|
96
100
|
image_bounds = (image_shape[0] - edge, image_shape[1] - edge)
|
97
101
|
refined_coords = np.array([c for c in refined_coords
|
98
102
|
if (c[0] > edge) and (c[1] > edge) and (c[0] < image_bounds[0]) and (c[1] < image_bounds[1])])
|
@@ -104,10 +108,9 @@ def _residual(params: Parameters,
|
|
104
108
|
"Try decreasing `num_stars` or increasing `dimmest_magnitude`.",
|
105
109
|
RepeatedStarWarning)
|
106
110
|
|
107
|
-
sigma = 3
|
108
111
|
out = np.array([np.min(np.linalg.norm(observed_coords - coord, axis=-1)) for coord in refined_coords[:n]])
|
109
|
-
|
110
|
-
out[out >
|
112
|
+
median, stdev = np.median(out), np.std(out)
|
113
|
+
out[out > median + (sigma * stdev)] = 0.0 # TODO: should this be zero?
|
111
114
|
return out
|
112
115
|
|
113
116
|
|
@@ -125,10 +128,16 @@ def refine_pointing_wrapper(image, guess_wcs, file_num, observed_coords=None, ca
|
|
125
128
|
return new_wcs, observed_coords, solution, trial_num, file_num
|
126
129
|
|
127
130
|
|
131
|
+
def extract_crota_from_wcs(wcs: WCS) -> tuple[float, float]:
|
132
|
+
"""Extract CROTA from a WCS."""
|
133
|
+
delta_ratio = wcs.wcs.cdelt[1] / wcs.wcs.cdelt[0]
|
134
|
+
return np.arctan2(wcs.wcs.pc[1, 0]/delta_ratio, wcs.wcs.pc[0, 0]) * u.rad
|
135
|
+
|
136
|
+
|
128
137
|
def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
129
138
|
background_width=16, background_height=16,
|
130
139
|
detection_threshold=5, num_stars=30, max_trials=15, chisqr_threshold=0.1,
|
131
|
-
dimmest_magnitude=6.0, method='leastsq'):
|
140
|
+
dimmest_magnitude=6.0, method='leastsq', edge=100, sigma=3.0, mask=None):
|
132
141
|
""" Refine the pointing for an image
|
133
142
|
|
134
143
|
Parameters
|
@@ -159,14 +168,15 @@ def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
|
159
168
|
background = sep.Background(image, bw=background_width, bh=background_height)
|
160
169
|
data_sub = image - background
|
161
170
|
objects = sep.extract(data_sub, detection_threshold, err=background.globalrms)
|
162
|
-
objects = pd.DataFrame(objects).sort_values('flux')
|
171
|
+
objects = pd.DataFrame(objects).sort_values('flux')
|
163
172
|
observed_coords = np.stack([objects["x"], objects["y"]], axis=-1)
|
164
|
-
|
173
|
+
if mask is not None:
|
174
|
+
observed_coords = observed_coords[mask(objects['x'], objects['y'])]
|
175
|
+
observed_coords = observed_coords[-3*num_stars:]
|
165
176
|
# set up the optimization
|
166
177
|
params = Parameters()
|
167
|
-
|
168
|
-
|
169
|
-
params.add("crota", value=initial_crota, min=-np.pi, max=np.pi)
|
178
|
+
initial_crota = extract_crota_from_wcs(guess_wcs)
|
179
|
+
params.add("crota", value=initial_crota.to(u.rad).value, min=-np.pi, max=np.pi)
|
170
180
|
params.add("crval1", value=guess_wcs.wcs.crval[0], min=-180, max=180, vary=True)
|
171
181
|
params.add("crval2", value=guess_wcs.wcs.crval[1], min=-90, max=90, vary=True)
|
172
182
|
|
@@ -176,7 +186,7 @@ def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
|
176
186
|
while trial_num < max_trials:
|
177
187
|
try:
|
178
188
|
out = minimize(_residual, params, method=method,
|
179
|
-
args=(observed_coords, catalog, guess_wcs, num_stars, image.shape))
|
189
|
+
args=(observed_coords, catalog, guess_wcs, num_stars, image.shape, edge, sigma, mask))
|
180
190
|
chisqr = out.chisqr
|
181
191
|
result_minimizations.append(out)
|
182
192
|
except IndexError:
|
@@ -195,6 +205,7 @@ def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
|
195
205
|
result_wcs.wcs.pc = calculate_pc_matrix(out.params["crota"], result_wcs.wcs.cdelt)
|
196
206
|
result_wcs.cpdis1 = guess_wcs.cpdis1 # TODO: what if there is no known distortion
|
197
207
|
result_wcs.cpdis2 = guess_wcs.cpdis2
|
208
|
+
result_wcs.wcs.set_pv(guess_wcs.wcs.get_pv())
|
198
209
|
result_wcses.append(result_wcs)
|
199
210
|
trial_num += 1
|
200
211
|
if chisqr < chisqr_threshold:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: thuban
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.3
|
4
4
|
Summary: High precision and accuracy astrometric image solving from a guess
|
5
5
|
Author-email: "J. Marcus Hughes" <hughes.jmb@gmail.com>
|
6
6
|
Maintainer-email: "J. Marcus Hughes" <hughes.jmb@gmail.com>
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|