thuban 0.0.5__tar.gz → 0.0.7__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.7/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
- thuban-0.0.7/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- {thuban-0.0.5 → thuban-0.0.7}/.github/workflows/ci_fixed.yaml +1 -1
- {thuban-0.0.5 → thuban-0.0.7}/.pre-commit-config.yaml +5 -2
- thuban-0.0.7/CHANGELOG.md +36 -0
- {thuban-0.0.5 → thuban-0.0.7}/PKG-INFO +5 -4
- {thuban-0.0.5 → thuban-0.0.7}/README.md +1 -1
- {thuban-0.0.5 → thuban-0.0.7}/pyproject.toml +1 -1
- {thuban-0.0.5 → thuban-0.0.7}/thuban/cli.py +37 -23
- {thuban-0.0.5 → thuban-0.0.7}/thuban/distortion.py +1 -1
- {thuban-0.0.5 → thuban-0.0.7}/thuban/pointing.py +35 -47
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/PKG-INFO +5 -4
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/SOURCES.txt +3 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/requires.txt +1 -1
- {thuban-0.0.5 → thuban-0.0.7}/.github/workflows/ci.yaml +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/.github/workflows/publish.yaml +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/.gitignore +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/.readthedocs.yaml +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/CITATION.cff +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/LICENSE +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/MANIFEST.in +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/codecov.yaml +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/Makefile +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/_static/favicon.ico +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/_static/logo.png +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/conf.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/index.rst +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/docs/make.bat +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/scripts/prepare_reduced_hip.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/setup.cfg +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/__init__.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_catalog.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_cli.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_distortion.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_pointing.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_util.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/tests/test_visualize.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/__init__.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/catalog.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/data/reduced_hip.csv +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/error.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/simulate.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/util.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban/visualize.py +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/dependency_links.txt +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/entry_points.txt +0 -0
- {thuban-0.0.5 → thuban-0.0.7}/thuban.egg-info/top_level.txt +0 -0
@@ -0,0 +1,38 @@
|
|
1
|
+
---
|
2
|
+
name: Bug report
|
3
|
+
about: Create a report to help us improve
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Describe the bug**
|
11
|
+
A clear and concise description of what the bug is.
|
12
|
+
|
13
|
+
**To Reproduce**
|
14
|
+
Steps to reproduce the behavior:
|
15
|
+
1. Go to '...'
|
16
|
+
2. Click on '....'
|
17
|
+
3. Scroll down to '....'
|
18
|
+
4. See error
|
19
|
+
|
20
|
+
**Expected behavior**
|
21
|
+
A clear and concise description of what you expected to happen.
|
22
|
+
|
23
|
+
**Screenshots**
|
24
|
+
If applicable, add screenshots to help explain your problem.
|
25
|
+
|
26
|
+
**Desktop (please complete the following information):**
|
27
|
+
- OS: [e.g. iOS]
|
28
|
+
- Browser [e.g. chrome, safari]
|
29
|
+
- Version [e.g. 22]
|
30
|
+
|
31
|
+
**Smartphone (please complete the following information):**
|
32
|
+
- Device: [e.g. iPhone6]
|
33
|
+
- OS: [e.g. iOS8.1]
|
34
|
+
- Browser [e.g. stock browser, safari]
|
35
|
+
- Version [e.g. 22]
|
36
|
+
|
37
|
+
**Additional context**
|
38
|
+
Add any other context about the problem here.
|
@@ -0,0 +1,20 @@
|
|
1
|
+
---
|
2
|
+
name: Feature request
|
3
|
+
about: Suggest an idea for this project
|
4
|
+
title: ''
|
5
|
+
labels: ''
|
6
|
+
assignees: ''
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
**Is your feature request related to a problem? Please describe.**
|
11
|
+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
12
|
+
|
13
|
+
**Describe the solution you'd like**
|
14
|
+
A clear and concise description of what you want to happen.
|
15
|
+
|
16
|
+
**Describe alternatives you've considered**
|
17
|
+
A clear and concise description of any alternative solutions or features you've considered.
|
18
|
+
|
19
|
+
**Additional context**
|
20
|
+
Add any other context or screenshots about the feature request here.
|
@@ -3,14 +3,14 @@ repos:
|
|
3
3
|
# This should be before any formatting hooks like isort
|
4
4
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
5
5
|
# Ruff version.
|
6
|
-
rev: v0.
|
6
|
+
rev: v0.11.4
|
7
7
|
hooks:
|
8
8
|
# Run the linter.
|
9
9
|
- id: ruff
|
10
10
|
types_or: [ python, pyi ]
|
11
11
|
args: [ --fix ]
|
12
12
|
- repo: https://github.com/PyCQA/isort
|
13
|
-
rev:
|
13
|
+
rev: 6.0.1
|
14
14
|
hooks:
|
15
15
|
- id: isort
|
16
16
|
exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|extern.*|sunpy/extern)$"
|
@@ -29,3 +29,6 @@ repos:
|
|
29
29
|
exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*|.json)$|^CITATION.rst$"
|
30
30
|
- id: mixed-line-ending
|
31
31
|
exclude: ".*(.fits|.fts|.fit|.header|.txt|tca.*)$"
|
32
|
+
ci:
|
33
|
+
autofix_prs: false
|
34
|
+
autoupdate_schedule: "quarterly"
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
[Also available through GitHub interface](https://github.com/punch-mission/thuban/releases)
|
4
|
+
|
5
|
+
## Version 0.0.7: May 22, 2025
|
6
|
+
|
7
|
+
- allow PV to vary in fitting
|
8
|
+
|
9
|
+
## Version 0.0.6: May 22, 2025
|
10
|
+
|
11
|
+
* specify codecov path by @jmbhughes in https://github.com/punch-mission/thuban/pull/18
|
12
|
+
* Update issue templates by @jmbhughes in https://github.com/punch-mission/thuban/pull/19
|
13
|
+
* Support more PUNCH features in https://github.com/punch-mission/thuban/pull/25
|
14
|
+
|
15
|
+
## Version 0.0.5: Nov 13, 2024
|
16
|
+
|
17
|
+
- Fix version names in docs by @jmbhughes in #12
|
18
|
+
- add tolerances by @jmbhughes in #13
|
19
|
+
- [pre-commit.ci] pre-commit autoupdate by @pre-commit-ci in #14
|
20
|
+
|
21
|
+
## Version 0.0.4: Nov 1, 2024
|
22
|
+
|
23
|
+
- Add pinned environment ci by @jmbhughes in #10
|
24
|
+
- Create .readthedocs.yaml by @jmbhughes in #11
|
25
|
+
|
26
|
+
## Version 0.0.3: Aug 24, 2024
|
27
|
+
|
28
|
+
- incorporates masking and pv by @jmbhughes in #8
|
29
|
+
|
30
|
+
## Version 0.0.2: Aug 18, 2024
|
31
|
+
|
32
|
+
- add file manifest by @jmbhughes in #7
|
33
|
+
|
34
|
+
## Version 0.0.1: Aug 18, 2024
|
35
|
+
|
36
|
+
Initial release
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: thuban
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.7
|
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>
|
@@ -19,7 +19,7 @@ Requires-Dist: numpy
|
|
19
19
|
Requires-Dist: astropy
|
20
20
|
Requires-Dist: matplotlib
|
21
21
|
Requires-Dist: pandas
|
22
|
-
Requires-Dist: sep
|
22
|
+
Requires-Dist: sep
|
23
23
|
Requires-Dist: scipy
|
24
24
|
Requires-Dist: scikit-learn
|
25
25
|
Requires-Dist: lmfit
|
@@ -39,13 +39,14 @@ Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
39
39
|
Requires-Dist: sphinx-favicon; extra == "docs"
|
40
40
|
Requires-Dist: ipython; extra == "docs"
|
41
41
|
Requires-Dist: packaging; extra == "docs"
|
42
|
+
Dynamic: license-file
|
42
43
|
|
43
44
|
# thuban
|
44
45
|
|
45
46
|
High precision astrometric image solving from a guess.
|
46
47
|
|
47
48
|
> [!WARNING]
|
48
|
-
> This package
|
49
|
+
> This package may still have significant changes until v1.
|
49
50
|
|
50
51
|
|
51
52
|
## To-do
|
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
5
5
|
|
6
6
|
import click
|
7
7
|
import numpy as np
|
8
|
-
import
|
8
|
+
import sep
|
9
9
|
from astropy.io import fits
|
10
10
|
from astropy.wcs import WCS
|
11
11
|
from tqdm import tqdm
|
@@ -38,9 +38,8 @@ def open_files(paths: [Path], byte_swap=True) -> (np.ndarray, [fits.Header]):
|
|
38
38
|
for filename in tqdm(paths):
|
39
39
|
with fits.open(filename) as hdul:
|
40
40
|
if byte_swap:
|
41
|
-
|
42
|
-
|
43
|
-
data = hdul[data_hdu_num].data.astype(float)
|
41
|
+
raise NotImplementedError()
|
42
|
+
data = hdul[data_hdu_num].data.astype(float)
|
44
43
|
head = hdul[data_hdu_num].header
|
45
44
|
all_wcses.append(WCS(head, hdul, key=celestial_wcs_key))
|
46
45
|
all_data.append(data)
|
@@ -79,8 +78,6 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
79
78
|
# data[:, :edge, :] = 0.0
|
80
79
|
# data[:, -edge:, :] = 0.0
|
81
80
|
# data[:, :, -edge:] = 0.0
|
82
|
-
|
83
|
-
print(headers)
|
84
81
|
current_wcses = [convert_cd_matrix_to_pc_matrix(w) for w in all_wcses]
|
85
82
|
|
86
83
|
# remove any SIP distortion model and make an empty table
|
@@ -91,7 +88,6 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
91
88
|
wcs.sip = None
|
92
89
|
wcs.cpdis1 = cpdis1
|
93
90
|
wcs.cpdis2 = cpdis2
|
94
|
-
print(current_wcses[0].wcs.cunit)
|
95
91
|
|
96
92
|
counts = []
|
97
93
|
for iteration in range(iterations):
|
@@ -110,13 +106,18 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
110
106
|
current_wcses[file_index],
|
111
107
|
file_index,
|
112
108
|
detection_threshold=threshold,
|
113
|
-
max_trials=
|
109
|
+
max_trials=10,
|
114
110
|
dimmest_magnitude=magnitude,
|
115
111
|
num_stars=num_stars,
|
116
112
|
background_width=background,
|
117
113
|
background_height=background,
|
118
|
-
chisqr_threshold=0.
|
119
|
-
|
114
|
+
chisqr_threshold=0.1,
|
115
|
+
max_error=150,
|
116
|
+
method='least_squares',
|
117
|
+
fix_crota=False,
|
118
|
+
fix_crval=False,
|
119
|
+
fix_pv=iteration == 0 or iteration == iterations - 1,
|
120
|
+
fix_cdelt=True or iteration == iterations - 1 or iteration % 2 == 1))
|
120
121
|
|
121
122
|
print("\tprocessing")
|
122
123
|
with tqdm(total=len(futures)) as pbar:
|
@@ -124,21 +125,28 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
124
125
|
|
125
126
|
updated_wcs, _, solution, num_trials, file_index = future.result()
|
126
127
|
current_wcses[file_index] = updated_wcs
|
128
|
+
pbar.update(1)
|
127
129
|
|
130
|
+
global_pv = np.mean([w.wcs.get_pv()[0][-1] for w in current_wcses])
|
131
|
+
global_cdelt1 = np.mean([w.wcs.cdelt[0] for w in current_wcses])
|
132
|
+
global_cdelt2 = np.mean([w.wcs.cdelt[1] for w in current_wcses])
|
128
133
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
134
|
+
for file_index in range(len(current_wcses)):
|
135
|
+
updated_wcs = current_wcses[file_index]
|
136
|
+
updated_wcs.wcs.cdelt = (global_cdelt1, global_cdelt2)
|
137
|
+
updated_wcs.wcs.set_pv([(2, 1, global_pv)])
|
133
138
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
139
|
+
bg = sep.Background(data[file_index], bw=background, bh=background)
|
140
|
+
data_sub = data[file_index] - bg
|
141
|
+
objects = sep.extract(data_sub, threshold, err=bg.globalrms)
|
142
|
+
observed_coords = np.stack([objects["x"], objects["y"]], axis=-1)
|
138
143
|
|
139
|
-
|
140
|
-
|
141
|
-
|
144
|
+
new_stars = find_catalog_in_image(
|
145
|
+
filter_for_visible_stars(load_hipparcos_catalog(), dimmest_magnitude=8.0),
|
146
|
+
updated_wcs, data.shape[1:], mode='wcs')
|
147
|
+
all_no_distortion.append(np.stack([new_stars['x_pix'], new_stars['y_pix']], axis=-1))
|
148
|
+
|
149
|
+
all_found_positions.append(observed_coords)
|
142
150
|
|
143
151
|
# log.append((all_corrected_positions, all_found_positions))
|
144
152
|
# TODO: move lower to fix counting of stars
|
@@ -149,7 +157,7 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
149
157
|
for i in range(len(all_no_distortion)):
|
150
158
|
observed_filtered, refined_filtered = remove_pairless_points(all_found_positions[i],
|
151
159
|
all_no_distortion[i],
|
152
|
-
max_distance=
|
160
|
+
max_distance=150)
|
153
161
|
if (observed_filtered.ndim == 2 and refined_filtered.ndim == 2
|
154
162
|
and len(observed_filtered) > 0 and len(refined_filtered) > 0):
|
155
163
|
final_observations.append(observed_filtered)
|
@@ -164,6 +172,12 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
164
172
|
final_observations,
|
165
173
|
final_refined,
|
166
174
|
num_bins=num_bins)
|
175
|
+
if iteration != iterations - 1:
|
176
|
+
center_x_val = cpdis1.data[num_bins//2, num_bins//2]
|
177
|
+
center_y_val = cpdis2.data[num_bins//2, num_bins//2]
|
178
|
+
|
179
|
+
cpdis1.data -= center_x_val
|
180
|
+
cpdis2.data -= center_y_val
|
167
181
|
|
168
182
|
for wcs in current_wcses:
|
169
183
|
wcs.cpdis1 = cpdis1
|
@@ -177,4 +191,4 @@ def determine_pointing_and_distortion(directory, byte_swap=True, num_stars=20,
|
|
177
191
|
_, extension = os.path.splitext(fn)
|
178
192
|
hdul = updated_wcs.to_fits() # improve the writing mechanism
|
179
193
|
hdul[0].data = img
|
180
|
-
hdul.writeto(str(fn).replace(extension, "_repoint.fits"), overwrite=True) # todo make postfix
|
194
|
+
hdul.writeto(str(fn).replace(extension, "_repoint.fits"), overwrite=True) # todo make postfix an option
|
@@ -131,7 +131,7 @@ def compute_distortion(
|
|
131
131
|
img_shape: (int, int),
|
132
132
|
catalog_positions: np.ndarray,
|
133
133
|
found_positions: np.ndarray,
|
134
|
-
distortion_limit: float =20, num_bins: int =75, blur_sigma: float =
|
134
|
+
distortion_limit: float =20, num_bins: int =75, blur_sigma: float = 1, med_filter_size: int = 1
|
135
135
|
) -> (DistortionLookupTable, DistortionLookupTable):
|
136
136
|
""" Given the derived catalog and actual star positions, determines the distortion
|
137
137
|
|
@@ -4,7 +4,7 @@ from typing import Callable
|
|
4
4
|
import astropy.units as u
|
5
5
|
import numpy as np
|
6
6
|
import pandas as pd
|
7
|
-
import
|
7
|
+
import sep
|
8
8
|
from astropy.wcs import WCS, utils
|
9
9
|
from lmfit import Parameters, minimize
|
10
10
|
|
@@ -84,18 +84,15 @@ def _residual(params: Parameters,
|
|
84
84
|
np.ndarray
|
85
85
|
residual
|
86
86
|
"""
|
87
|
-
refined_wcs =
|
88
|
-
refined_wcs.wcs.
|
89
|
-
refined_wcs.wcs.cunit = guess_wcs.wcs.cunit
|
90
|
-
refined_wcs.wcs.cdelt = guess_wcs.wcs.cdelt
|
91
|
-
refined_wcs.wcs.crpix = guess_wcs.wcs.crpix
|
87
|
+
refined_wcs = guess_wcs.deepcopy()
|
88
|
+
refined_wcs.wcs.cdelt = (params['cdelt1'].value, params['cdelt2'].value)
|
92
89
|
refined_wcs.wcs.crval = (params["crval1"].value, params["crval2"].value)
|
93
|
-
refined_wcs.wcs.pc = calculate_pc_matrix(params["crota"],
|
90
|
+
refined_wcs.wcs.pc = calculate_pc_matrix(params["crota"], (params['cdelt1'], params['cdelt2']))
|
94
91
|
refined_wcs.cpdis1 = guess_wcs.cpdis1
|
95
92
|
refined_wcs.cpdis2 = guess_wcs.cpdis2
|
96
|
-
refined_wcs.wcs.set_pv(
|
93
|
+
refined_wcs.wcs.set_pv([(2, 1, params['pv'].value)])
|
97
94
|
|
98
|
-
reduced_catalog = find_catalog_in_image(catalog, refined_wcs, image_shape=image_shape, mask=mask)
|
95
|
+
reduced_catalog = find_catalog_in_image(catalog, refined_wcs, image_shape=image_shape, mask=mask, mode='wcs')
|
99
96
|
refined_coords = np.stack([reduced_catalog['x_pix'], reduced_catalog['y_pix']], axis=-1)
|
100
97
|
|
101
98
|
image_bounds = (image_shape[0] - edge, image_shape[1] - edge)
|
@@ -119,7 +116,8 @@ def _residual(params: Parameters,
|
|
119
116
|
def refine_pointing_wrapper(image, guess_wcs, file_num, observed_coords=None, catalog=None,
|
120
117
|
background_width=16, background_height=16,
|
121
118
|
detection_threshold=5, num_stars=30, max_trials=15, chisqr_threshold=0.1,
|
122
|
-
dimmest_magnitude=6.0, method='
|
119
|
+
dimmest_magnitude=6.0, method='least_squares', ra_tolerance=10, dec_tolerance=5, max_error=15,
|
120
|
+
fix_crval=False, fix_cdelt=True, fix_crota=False, fix_pv=True):
|
123
121
|
new_wcs, observed_coords, solution, trial_num = refine_pointing(image,
|
124
122
|
guess_wcs,
|
125
123
|
observed_coords=observed_coords, catalog=catalog,
|
@@ -128,7 +126,9 @@ def refine_pointing_wrapper(image, guess_wcs, file_num, observed_coords=None, ca
|
|
128
126
|
chisqr_threshold=chisqr_threshold,
|
129
127
|
dimmest_magnitude=dimmest_magnitude, method=method,
|
130
128
|
ra_tolerance=ra_tolerance,
|
131
|
-
dec_tolerance=dec_tolerance, max_error=max_error
|
129
|
+
dec_tolerance=dec_tolerance, max_error=max_error,
|
130
|
+
fix_crval=fix_crval, fix_cdelt=fix_cdelt,
|
131
|
+
fix_crota=fix_crota, fix_pv=fix_pv)
|
132
132
|
return new_wcs, observed_coords, solution, trial_num, file_num
|
133
133
|
|
134
134
|
|
@@ -141,30 +141,9 @@ def extract_crota_from_wcs(wcs: WCS) -> tuple[float, float]:
|
|
141
141
|
def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
142
142
|
background_width=16, background_height=16,
|
143
143
|
detection_threshold=5, num_stars=30, max_trials=15, chisqr_threshold=0.1,
|
144
|
-
dimmest_magnitude=6.0, method='
|
145
|
-
ra_tolerance=10, dec_tolerance=5, max_error=15
|
146
|
-
|
147
|
-
|
148
|
-
Parameters
|
149
|
-
----------
|
150
|
-
image : np.ndarray
|
151
|
-
the brightnesses of the image, no preprocessing necessary
|
152
|
-
guess_wcs : WCS
|
153
|
-
initial guess for th world coordinate system, must overlap with the true WCS
|
154
|
-
file_index
|
155
|
-
observed_coords
|
156
|
-
catalog
|
157
|
-
background_width
|
158
|
-
background_height
|
159
|
-
detection_threshold
|
160
|
-
x_lim
|
161
|
-
y_lim
|
162
|
-
n
|
163
|
-
|
164
|
-
Returns
|
165
|
-
-------
|
166
|
-
|
167
|
-
"""
|
144
|
+
dimmest_magnitude=6.0, method='least_squares', edge=100, sigma=3.0, mask=None,
|
145
|
+
ra_tolerance=10, dec_tolerance=5, max_error=15,
|
146
|
+
fix_crval=False, fix_cdelt=True, fix_crota=False, fix_pv=True):
|
168
147
|
if catalog is None:
|
169
148
|
catalog = filter_for_visible_stars(load_hipparcos_catalog(), dimmest_magnitude=dimmest_magnitude)
|
170
149
|
|
@@ -194,23 +173,35 @@ def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
|
194
173
|
# set up the optimization
|
195
174
|
params = Parameters()
|
196
175
|
initial_crota = extract_crota_from_wcs(guess_wcs)
|
197
|
-
params.add("crota", value=initial_crota.to(u.rad).value,
|
176
|
+
params.add("crota", value=initial_crota.to(u.rad).value,
|
177
|
+
min=-np.pi, max=np.pi, vary=not fix_crota)
|
198
178
|
params.add("crval1", value=guess_wcs.wcs.crval[0],
|
199
179
|
min=guess_wcs.wcs.crval[0]-ra_tolerance,
|
200
|
-
max=guess_wcs.wcs.crval[0]+ra_tolerance, vary=
|
180
|
+
max=guess_wcs.wcs.crval[0]+ra_tolerance, vary=not fix_crval)
|
201
181
|
params.add("crval2", value=guess_wcs.wcs.crval[1],
|
202
182
|
min=guess_wcs.wcs.crval[1]-dec_tolerance,
|
203
|
-
max=guess_wcs.wcs.crval[1]+dec_tolerance, vary=
|
183
|
+
max=guess_wcs.wcs.crval[1]+dec_tolerance, vary=not fix_crval)
|
184
|
+
params.add("cdelt1", value=guess_wcs.wcs.cdelt[0],
|
185
|
+
min=guess_wcs.wcs.cdelt[0]-1,
|
186
|
+
max=guess_wcs.wcs.cdelt[0]+1, vary=not fix_cdelt)
|
187
|
+
params.add("cdelt2", value=guess_wcs.wcs.cdelt[1],
|
188
|
+
min=max(guess_wcs.wcs.cdelt[1]-0.1, 0),
|
189
|
+
max=guess_wcs.wcs.cdelt[1]+0.1, vary=not fix_cdelt)
|
190
|
+
if guess_wcs.wcs.get_pv():
|
191
|
+
pv = guess_wcs.wcs.get_pv()[0][-1]
|
192
|
+
print(pv)
|
193
|
+
else:
|
194
|
+
pv = 0.0
|
195
|
+
params.add("pv", value=pv, min=0.0, max=1.0, vary=not fix_pv)
|
204
196
|
|
205
|
-
# return guess_wcs, observed_coords, None, None
|
206
|
-
# optimize
|
207
197
|
trial_num = 0
|
208
198
|
result_wcses, result_minimizations = [], []
|
209
199
|
while trial_num < max_trials:
|
210
200
|
try:
|
211
201
|
out = minimize(_residual, params, method=method,
|
212
202
|
args=(observed_coords, catalog, guess_wcs,
|
213
|
-
num_stars, image.shape, edge, sigma, max_error, mask)
|
203
|
+
num_stars, image.shape, edge, sigma, max_error, mask),
|
204
|
+
max_nfev=500, calc_covar=False)
|
214
205
|
chisqr = out.chisqr
|
215
206
|
result_minimizations.append(out)
|
216
207
|
except IndexError:
|
@@ -220,16 +211,13 @@ def refine_pointing(image, guess_wcs, observed_coords=None, catalog=None,
|
|
220
211
|
ConvergenceWarning)
|
221
212
|
else:
|
222
213
|
# construct the result
|
223
|
-
result_wcs =
|
224
|
-
result_wcs.wcs.
|
225
|
-
result_wcs.wcs.cunit = guess_wcs.wcs.cunit
|
226
|
-
result_wcs.wcs.cdelt = guess_wcs.wcs.cdelt
|
227
|
-
result_wcs.wcs.crpix = guess_wcs.wcs.crpix
|
214
|
+
result_wcs = guess_wcs.deepcopy()
|
215
|
+
result_wcs.wcs.cdelt = (out.params["cdelt1"].value, out.params["cdelt2"].value)
|
228
216
|
result_wcs.wcs.crval = (out.params["crval1"].value, out.params["crval2"].value)
|
229
217
|
result_wcs.wcs.pc = calculate_pc_matrix(out.params["crota"], result_wcs.wcs.cdelt)
|
230
218
|
result_wcs.cpdis1 = guess_wcs.cpdis1 # TODO: what if there is no known distortion
|
231
219
|
result_wcs.cpdis2 = guess_wcs.cpdis2
|
232
|
-
result_wcs.wcs.set_pv(
|
220
|
+
result_wcs.wcs.set_pv([(2, 1, out.params['pv'].value)])
|
233
221
|
result_wcses.append(result_wcs)
|
234
222
|
trial_num += 1
|
235
223
|
if chisqr < chisqr_threshold:
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: thuban
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.7
|
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>
|
@@ -19,7 +19,7 @@ Requires-Dist: numpy
|
|
19
19
|
Requires-Dist: astropy
|
20
20
|
Requires-Dist: matplotlib
|
21
21
|
Requires-Dist: pandas
|
22
|
-
Requires-Dist: sep
|
22
|
+
Requires-Dist: sep
|
23
23
|
Requires-Dist: scipy
|
24
24
|
Requires-Dist: scikit-learn
|
25
25
|
Requires-Dist: lmfit
|
@@ -39,13 +39,14 @@ Requires-Dist: pydata-sphinx-theme; extra == "docs"
|
|
39
39
|
Requires-Dist: sphinx-favicon; extra == "docs"
|
40
40
|
Requires-Dist: ipython; extra == "docs"
|
41
41
|
Requires-Dist: packaging; extra == "docs"
|
42
|
+
Dynamic: license-file
|
42
43
|
|
43
44
|
# thuban
|
44
45
|
|
45
46
|
High precision astrometric image solving from a guess.
|
46
47
|
|
47
48
|
> [!WARNING]
|
48
|
-
> This package
|
49
|
+
> This package may still have significant changes until v1.
|
49
50
|
|
50
51
|
|
51
52
|
## To-do
|
@@ -1,12 +1,15 @@
|
|
1
1
|
.gitignore
|
2
2
|
.pre-commit-config.yaml
|
3
3
|
.readthedocs.yaml
|
4
|
+
CHANGELOG.md
|
4
5
|
CITATION.cff
|
5
6
|
LICENSE
|
6
7
|
MANIFEST.in
|
7
8
|
README.md
|
8
9
|
codecov.yaml
|
9
10
|
pyproject.toml
|
11
|
+
.github/ISSUE_TEMPLATE/bug_report.md
|
12
|
+
.github/ISSUE_TEMPLATE/feature_request.md
|
10
13
|
.github/workflows/ci.yaml
|
11
14
|
.github/workflows/ci_fixed.yaml
|
12
15
|
.github/workflows/publish.yaml
|
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
|
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
|