teareduce 0.5.3__py3-none-any.whl → 0.5.5__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.
- teareduce/cleanest/__main__.py +57 -8
- teareduce/cleanest/centerchildparent.py +46 -0
- teareduce/cleanest/cleanest.py +16 -19
- teareduce/cleanest/cosmicraycleanerapp.py +264 -168
- teareduce/cleanest/definitions.py +30 -29
- teareduce/cleanest/imagedisplay.py +8 -9
- teareduce/cleanest/interpolation_a.py +5 -9
- teareduce/cleanest/interpolationeditor.py +156 -35
- teareduce/cleanest/modalprogressbar.py +182 -0
- teareduce/cleanest/parametereditor.py +98 -76
- teareduce/cleanest/reviewcosmicray.py +99 -66
- teareduce/version.py +1 -1
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/METADATA +1 -1
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/RECORD +18 -16
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/WHEEL +0 -0
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/entry_points.txt +0 -0
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/licenses/LICENSE.txt +0 -0
- {teareduce-0.5.3.dist-info → teareduce-0.5.5.dist-info}/top_level.txt +0 -0
teareduce/cleanest/__main__.py
CHANGED
|
@@ -12,26 +12,59 @@
|
|
|
12
12
|
import argparse
|
|
13
13
|
import tkinter as tk
|
|
14
14
|
import os
|
|
15
|
+
import platform
|
|
15
16
|
from rich import print
|
|
16
17
|
from rich_argparse import RichHelpFormatter
|
|
17
18
|
|
|
19
|
+
from .definitions import DEFAULT_FONT_FAMILY
|
|
20
|
+
from .definitions import DEFAULT_FONT_SIZE
|
|
21
|
+
from .definitions import DEFAULT_TK_WINDOW_SIZE_X
|
|
22
|
+
from .definitions import DEFAULT_TK_WINDOW_SIZE_Y
|
|
18
23
|
from .cosmicraycleanerapp import CosmicRayCleanerApp
|
|
19
24
|
|
|
20
25
|
import matplotlib
|
|
26
|
+
|
|
21
27
|
matplotlib.use("TkAgg")
|
|
22
28
|
|
|
23
29
|
|
|
24
30
|
def main():
|
|
25
31
|
parser = argparse.ArgumentParser(
|
|
26
32
|
description="Interactive cosmic ray cleaner for FITS images.",
|
|
27
|
-
formatter_class=RichHelpFormatter
|
|
33
|
+
formatter_class=RichHelpFormatter,
|
|
34
|
+
)
|
|
28
35
|
parser.add_argument("input_fits", help="Path to the FITS file to be cleaned.")
|
|
29
|
-
parser.add_argument("--extension", type=int, default=0,
|
|
30
|
-
|
|
31
|
-
parser.add_argument(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
parser.add_argument("--extension", type=int, default=0, help="FITS extension to use (default: 0).")
|
|
37
|
+
parser.add_argument("--auxfile", type=str, default=None, help="Auxiliary FITS file")
|
|
38
|
+
parser.add_argument(
|
|
39
|
+
"--extension_auxfile",
|
|
40
|
+
type=int,
|
|
41
|
+
default=0,
|
|
42
|
+
help="FITS extension for auxiliary file (default: 0).",
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--fontfamily",
|
|
46
|
+
type=str,
|
|
47
|
+
default=DEFAULT_FONT_FAMILY,
|
|
48
|
+
help=f"Font family for the GUI (default: {DEFAULT_FONT_FAMILY}).",
|
|
49
|
+
)
|
|
50
|
+
parser.add_argument(
|
|
51
|
+
"--fontsize",
|
|
52
|
+
type=int,
|
|
53
|
+
default=DEFAULT_FONT_SIZE,
|
|
54
|
+
help=f"Font size for the GUI (default: {DEFAULT_FONT_SIZE}).",
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--width",
|
|
58
|
+
type=int,
|
|
59
|
+
default=DEFAULT_TK_WINDOW_SIZE_X,
|
|
60
|
+
help=f"Width of the GUI window in pixels (default: {DEFAULT_TK_WINDOW_SIZE_X}).",
|
|
61
|
+
)
|
|
62
|
+
parser.add_argument(
|
|
63
|
+
"--height",
|
|
64
|
+
type=int,
|
|
65
|
+
default=DEFAULT_TK_WINDOW_SIZE_Y,
|
|
66
|
+
help=f"Height of the GUI window in pixels (default: {DEFAULT_TK_WINDOW_SIZE_Y}).",
|
|
67
|
+
)
|
|
35
68
|
args = parser.parse_args()
|
|
36
69
|
|
|
37
70
|
if not os.path.isfile(args.input_fits):
|
|
@@ -43,6 +76,18 @@ def main():
|
|
|
43
76
|
|
|
44
77
|
# Initialize Tkinter root
|
|
45
78
|
root = tk.Tk()
|
|
79
|
+
system = platform.system()
|
|
80
|
+
if system == "Darwin": # macOS
|
|
81
|
+
# Center the window on the screen
|
|
82
|
+
xoffset = root.winfo_screenwidth() // 2 - args.width // 2
|
|
83
|
+
yoffset = root.winfo_screenheight() // 2 - args.height // 2
|
|
84
|
+
else:
|
|
85
|
+
# Note that geometry("XxY+Xoffset+Yoffset") does not work properly on Fedora Linux
|
|
86
|
+
xoffset = 0
|
|
87
|
+
yoffset = 0
|
|
88
|
+
root.geometry(f"+{xoffset}+{yoffset}")
|
|
89
|
+
root.focus_force() # Request focus
|
|
90
|
+
root.lift() # Bring to front
|
|
46
91
|
|
|
47
92
|
# Create and run the application
|
|
48
93
|
CosmicRayCleanerApp(
|
|
@@ -50,7 +95,11 @@ def main():
|
|
|
50
95
|
input_fits=args.input_fits,
|
|
51
96
|
extension=args.extension,
|
|
52
97
|
auxfile=args.auxfile,
|
|
53
|
-
extension_auxfile=args.extension_auxfile
|
|
98
|
+
extension_auxfile=args.extension_auxfile,
|
|
99
|
+
fontfamily=args.fontfamily,
|
|
100
|
+
fontsize=args.fontsize,
|
|
101
|
+
width=args.width,
|
|
102
|
+
height=args.height,
|
|
54
103
|
)
|
|
55
104
|
|
|
56
105
|
# Execute
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright 2025 Universidad Complutense de Madrid
|
|
3
|
+
#
|
|
4
|
+
# This file is part of teareduce
|
|
5
|
+
#
|
|
6
|
+
# SPDX-License-Identifier: GPL-3.0+
|
|
7
|
+
# License-Filename: LICENSE.txt
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
"""Function to center a tk child window on its parent."""
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def center_on_parent(child, parent, offset_x=0, offset_y=0):
|
|
14
|
+
"""Center child window on parent window.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
child : tk.Toplevel or tk.Tk
|
|
19
|
+
The child window to be centered.
|
|
20
|
+
parent : tk.Toplevel or tk.Tk
|
|
21
|
+
The parent window.
|
|
22
|
+
offset_x : int, optional
|
|
23
|
+
Horizontal offset from center position (default is 0).
|
|
24
|
+
offset_y : int, optional
|
|
25
|
+
Vertical offset from center position (default is 0).
|
|
26
|
+
"""
|
|
27
|
+
# Update to get accurate dimensions
|
|
28
|
+
child.update_idletasks()
|
|
29
|
+
parent.update_idletasks()
|
|
30
|
+
|
|
31
|
+
# Get parent position and size
|
|
32
|
+
parent_x = parent.winfo_x()
|
|
33
|
+
parent_y = parent.winfo_y()
|
|
34
|
+
parent_width = parent.winfo_width()
|
|
35
|
+
parent_height = parent.winfo_height()
|
|
36
|
+
|
|
37
|
+
# Get child size
|
|
38
|
+
child_width = child.winfo_width()
|
|
39
|
+
child_height = child.winfo_height()
|
|
40
|
+
|
|
41
|
+
# Calculate center position
|
|
42
|
+
x = parent_x + (parent_width - child_width) // 2
|
|
43
|
+
y = parent_y + (parent_height - child_height) // 2
|
|
44
|
+
|
|
45
|
+
# Set child position
|
|
46
|
+
child.geometry(f"+{x + offset_x}+{y + offset_y}")
|
teareduce/cleanest/cleanest.py
CHANGED
|
@@ -18,9 +18,7 @@ from .interpolation_y import interpolation_y
|
|
|
18
18
|
from .interpolation_a import interpolation_a
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
def cleanest(data, mask_crfound, dilation=0,
|
|
22
|
-
interp_method=None, npoints=None, degree=None,
|
|
23
|
-
debug=False):
|
|
21
|
+
def cleanest(data, mask_crfound, dilation=0, interp_method=None, npoints=None, degree=None, debug=False):
|
|
24
22
|
"""Interpolate pixels identified in a mask.
|
|
25
23
|
|
|
26
24
|
The original data and mask are not modified. A copy of both
|
|
@@ -68,11 +66,11 @@ def cleanest(data, mask_crfound, dilation=0,
|
|
|
68
66
|
"""
|
|
69
67
|
if interp_method is None:
|
|
70
68
|
raise ValueError("interp_method must be specified.")
|
|
71
|
-
if interp_method not in [
|
|
69
|
+
if interp_method not in ["x", "y", "s", "d", "m"]:
|
|
72
70
|
raise ValueError(f"Unknown interp_method: {interp_method}")
|
|
73
71
|
if npoints is None:
|
|
74
72
|
raise ValueError("npoints must be specified.")
|
|
75
|
-
if degree is None and interp_method in [
|
|
73
|
+
if degree is None and interp_method in ["x", "y"]:
|
|
76
74
|
raise ValueError("degree must be specified for the chosen interp_method.")
|
|
77
75
|
|
|
78
76
|
# Apply dilation to the cosmic ray mask if needed
|
|
@@ -85,9 +83,7 @@ def cleanest(data, mask_crfound, dilation=0,
|
|
|
85
83
|
mask_fixed = np.zeros_like(mask_crfound, dtype=bool)
|
|
86
84
|
|
|
87
85
|
# Determine number of CR features
|
|
88
|
-
structure = [[1, 1, 1],
|
|
89
|
-
[1, 1, 1],
|
|
90
|
-
[1, 1, 1]]
|
|
86
|
+
structure = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
|
|
91
87
|
cr_labels, num_features = ndimage.label(updated_mask_crfound, structure=structure)
|
|
92
88
|
if debug:
|
|
93
89
|
print(f"Number of cosmic ray pixels to be cleaned: {np.sum(updated_mask_crfound)}")
|
|
@@ -97,10 +93,10 @@ def cleanest(data, mask_crfound, dilation=0,
|
|
|
97
93
|
cleaned_data = data.copy()
|
|
98
94
|
num_cr_cleaned = 0
|
|
99
95
|
for cr_index in range(1, num_features + 1):
|
|
100
|
-
if interp_method in [
|
|
96
|
+
if interp_method in ["x", "y"]:
|
|
101
97
|
if 2 * npoints <= degree:
|
|
102
98
|
raise ValueError("2*npoints must be greater than degree for polynomial interpolation.")
|
|
103
|
-
if interp_method ==
|
|
99
|
+
if interp_method == "x":
|
|
104
100
|
interp_func = interpolation_x
|
|
105
101
|
else:
|
|
106
102
|
interp_func = interpolation_y
|
|
@@ -110,23 +106,24 @@ def cleanest(data, mask_crfound, dilation=0,
|
|
|
110
106
|
cr_labels=cr_labels,
|
|
111
107
|
cr_index=cr_index,
|
|
112
108
|
npoints=npoints,
|
|
113
|
-
degree=degree
|
|
109
|
+
degree=degree,
|
|
110
|
+
)
|
|
114
111
|
if interpolation_performed:
|
|
115
112
|
num_cr_cleaned += 1
|
|
116
|
-
elif interp_method in [
|
|
117
|
-
if interp_method ==
|
|
118
|
-
method =
|
|
119
|
-
elif interp_method ==
|
|
120
|
-
method =
|
|
121
|
-
elif interp_method ==
|
|
122
|
-
method =
|
|
113
|
+
elif interp_method in ["s", "d", "m"]:
|
|
114
|
+
if interp_method == "s":
|
|
115
|
+
method = "surface"
|
|
116
|
+
elif interp_method == "d":
|
|
117
|
+
method = "median"
|
|
118
|
+
elif interp_method == "m":
|
|
119
|
+
method = "mean"
|
|
123
120
|
interpolation_performed, _, _ = interpolation_a(
|
|
124
121
|
data=cleaned_data,
|
|
125
122
|
mask_fixed=mask_fixed,
|
|
126
123
|
cr_labels=cr_labels,
|
|
127
124
|
cr_index=cr_index,
|
|
128
125
|
npoints=npoints,
|
|
129
|
-
method=method
|
|
126
|
+
method=method,
|
|
130
127
|
)
|
|
131
128
|
if interpolation_performed:
|
|
132
129
|
num_cr_cleaned += 1
|