teareduce 0.5.8__py3-none-any.whl → 0.6.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.
- teareduce/cleanest/__init__.py +8 -1
- teareduce/cleanest/__main__.py +11 -6
- teareduce/cleanest/askextension.py +85 -0
- teareduce/cleanest/cosmicraycleanerapp.py +297 -65
- teareduce/cleanest/definitions.py +55 -9
- teareduce/cleanest/gausskernel2d_elliptical.py +54 -0
- teareduce/cleanest/interpolate.py +65 -48
- teareduce/cleanest/interpolationeditor.py +196 -52
- teareduce/cleanest/lacosmicpad.py +100 -2
- teareduce/cleanest/parametereditor.py +279 -51
- teareduce/cleanest/reviewcosmicray.py +285 -83
- teareduce/cleanest/trackedbutton.py +73 -0
- teareduce/version.py +1 -1
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/METADATA +17 -5
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/RECORD +19 -16
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/WHEEL +0 -0
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/entry_points.txt +0 -0
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/licenses/LICENSE.txt +0 -0
- {teareduce-0.5.8.dist-info → teareduce-0.6.0.dist-info}/top_level.txt +0 -0
|
@@ -9,26 +9,56 @@
|
|
|
9
9
|
|
|
10
10
|
"""Definitions for the cleanest module."""
|
|
11
11
|
|
|
12
|
+
VALID_LACOSMIC_CLEANTYPE_VALUES = ["median", "medmask", "meanmask", "idw"]
|
|
13
|
+
VALID_LACOSMIC_FSMODE_VALUES = ["median", "convolve"]
|
|
14
|
+
VALID_LACOSMIC_PSFMODEL_VALUES = ["gauss", "moffat", "gaussx", "gaussy", "gaussxy"]
|
|
15
|
+
|
|
12
16
|
# Default parameters for L.A.Cosmic algorithm
|
|
13
17
|
# Note that 'type' is set to the expected data type for each parameter
|
|
14
18
|
# using the intrinsic Python types, so that they can be easily cast
|
|
15
19
|
# when reading user input.
|
|
16
20
|
lacosmic_default_dict = {
|
|
17
21
|
# L.A.Cosmic parameters for run 1
|
|
18
|
-
"run1_gain": {"value": 1.0, "type": float, "positive": True},
|
|
19
|
-
"run1_readnoise": {"value": 6.5, "type": float, "positive": True},
|
|
20
22
|
"run1_sigclip": {"value": 5.0, "type": float, "positive": True},
|
|
21
23
|
"run1_sigfrac": {"value": 0.3, "type": float, "positive": True},
|
|
22
24
|
"run1_objlim": {"value": 5.0, "type": float, "positive": True},
|
|
23
|
-
"
|
|
25
|
+
"run1_gain": {"value": 1.0, "type": float, "positive": True},
|
|
26
|
+
"run1_readnoise": {"value": 6.5, "type": float, "positive": True},
|
|
27
|
+
"run1_satlevel": {"value": 65535, "type": float, "positive": True},
|
|
28
|
+
"run1_niter": {"value": 4, "type": int, "positive": True, "intmode": "any"},
|
|
29
|
+
"run1_sepmed": {"value": True, "type": bool},
|
|
30
|
+
"run1_cleantype": {"value": "meanmask", "type": str, "valid_values": VALID_LACOSMIC_CLEANTYPE_VALUES},
|
|
31
|
+
"run1_fsmode": {"value": "median", "type": str, "valid_values": VALID_LACOSMIC_FSMODE_VALUES},
|
|
32
|
+
"run1_psfmodel": {
|
|
33
|
+
"value": "gaussxy",
|
|
34
|
+
"type": str,
|
|
35
|
+
"valid_values": VALID_LACOSMIC_PSFMODEL_VALUES,
|
|
36
|
+
},
|
|
37
|
+
"run1_psffwhm_x": {"value": 2.5, "type": float, "positive": True},
|
|
38
|
+
"run1_psffwhm_y": {"value": 2.5, "type": float, "positive": True},
|
|
39
|
+
"run1_psfsize": {"value": 7, "type": int, "positive": True, "intmode": "odd"},
|
|
40
|
+
"run1_psfbeta": {"value": 4.765, "type": float, "positive": True},
|
|
24
41
|
"run1_verbose": {"value": True, "type": bool},
|
|
25
42
|
# L.A.Cosmic parameters for run 2
|
|
26
|
-
"run2_gain": {"value": 1.0, "type": float, "positive": True},
|
|
27
|
-
"run2_readnoise": {"value": 6.5, "type": float, "positive": True},
|
|
28
43
|
"run2_sigclip": {"value": 3.0, "type": float, "positive": True},
|
|
29
44
|
"run2_sigfrac": {"value": 0.3, "type": float, "positive": True},
|
|
30
45
|
"run2_objlim": {"value": 5.0, "type": float, "positive": True},
|
|
31
|
-
"
|
|
46
|
+
"run2_gain": {"value": 1.0, "type": float, "positive": True},
|
|
47
|
+
"run2_readnoise": {"value": 6.5, "type": float, "positive": True},
|
|
48
|
+
"run2_satlevel": {"value": 65535, "type": float, "positive": True},
|
|
49
|
+
"run2_niter": {"value": 4, "type": int, "positive": True, "intmode": "any"},
|
|
50
|
+
"run2_sepmed": {"value": True, "type": bool},
|
|
51
|
+
"run2_cleantype": {"value": "meanmask", "type": str, "valid_values": VALID_LACOSMIC_CLEANTYPE_VALUES},
|
|
52
|
+
"run2_fsmode": {"value": "median", "type": str, "valid_values": VALID_LACOSMIC_FSMODE_VALUES},
|
|
53
|
+
"run2_psfmodel": {
|
|
54
|
+
"value": "gaussxy",
|
|
55
|
+
"type": str,
|
|
56
|
+
"valid_values": VALID_LACOSMIC_PSFMODEL_VALUES,
|
|
57
|
+
},
|
|
58
|
+
"run2_psffwhm_x": {"value": 2.5, "type": float, "positive": True},
|
|
59
|
+
"run2_psffwhm_y": {"value": 2.5, "type": float, "positive": True},
|
|
60
|
+
"run2_psfsize": {"value": 7, "type": int, "positive": True, "intmode": "odd"},
|
|
61
|
+
"run2_psfbeta": {"value": 4.765, "type": float, "positive": True},
|
|
32
62
|
"run2_verbose": {"value": True, "type": bool},
|
|
33
63
|
# Dilation of the mask
|
|
34
64
|
"dilation": {"value": 0, "type": int, "positive": True},
|
|
@@ -39,11 +69,20 @@ lacosmic_default_dict = {
|
|
|
39
69
|
"ymin": {"value": 1, "type": int, "positive": True},
|
|
40
70
|
"ymax": {"value": None, "type": int, "positive": True},
|
|
41
71
|
# Number of runs to execute L.A.Cosmic
|
|
42
|
-
"nruns": {"value": 1, "type": int, "positive": True},
|
|
72
|
+
"nruns": {"value": 1, "type": int, "positive": True, "intmode": "any"},
|
|
43
73
|
}
|
|
44
74
|
|
|
45
|
-
#
|
|
46
|
-
VALID_CLEANING_METHODS =
|
|
75
|
+
# Valid cleaning methods (as shown to the user and their internal codes)
|
|
76
|
+
VALID_CLEANING_METHODS = {
|
|
77
|
+
"x interp.": "x",
|
|
78
|
+
"y interp.": "y",
|
|
79
|
+
"surface interp.": "a-plane",
|
|
80
|
+
"median": "a-median",
|
|
81
|
+
"mean": "a-mean",
|
|
82
|
+
"lacosmic": "lacosmic",
|
|
83
|
+
"maskfill": "maskfill",
|
|
84
|
+
"auxdata": "auxdata",
|
|
85
|
+
}
|
|
47
86
|
|
|
48
87
|
# Maximum pixel distance to consider when finding closest CR pixel
|
|
49
88
|
MAX_PIXEL_DISTANCE_TO_CR = 15
|
|
@@ -54,6 +93,13 @@ DEFAULT_NPOINTS_INTERP = 2
|
|
|
54
93
|
# Default degree for interpolation
|
|
55
94
|
DEFAULT_DEGREE_INTERP = 1
|
|
56
95
|
|
|
96
|
+
# Default maskfill parameters
|
|
97
|
+
DEFAULT_MASKFILL_SIZE = 3
|
|
98
|
+
DEFAULT_MASKFILL_OPERATOR = "median"
|
|
99
|
+
MASKFILL_OPERATOR_VALUES = ["median", "mean"]
|
|
100
|
+
DEFAULT_MASKFILL_SMOOTH = True
|
|
101
|
+
DEFAULT_MASKFILL_VERBOSE = False
|
|
102
|
+
|
|
57
103
|
# Default Tk window size
|
|
58
104
|
DEFAULT_TK_WINDOW_SIZE_X = 800
|
|
59
105
|
DEFAULT_TK_WINDOW_SIZE_Y = 700
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
"""Calculate elliptical 2D Gaussian kernel."""
|
|
11
|
+
|
|
12
|
+
import math
|
|
13
|
+
import numpy as np
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def gausskernel2d_elliptical(fwhm_x, fwhm_y, kernsize):
|
|
17
|
+
"""Calculate elliptical 2D Gaussian kernel.
|
|
18
|
+
|
|
19
|
+
This kernel can be used as the psfk parameter of
|
|
20
|
+
ccdproc.cosmicray_lacosmic.
|
|
21
|
+
|
|
22
|
+
Parameters
|
|
23
|
+
----------
|
|
24
|
+
fwhm_x : float
|
|
25
|
+
Full width at half maximum in the x direction.
|
|
26
|
+
fwhm_y : float
|
|
27
|
+
Full width at half maximum in the y direction.
|
|
28
|
+
kernsize : int
|
|
29
|
+
Size of the kernel (must be odd).
|
|
30
|
+
|
|
31
|
+
Returns
|
|
32
|
+
-------
|
|
33
|
+
kernel : 2D numpy array
|
|
34
|
+
The elliptical Gaussian kernel. It is normalized
|
|
35
|
+
so that the sum of all its elements is 1. It
|
|
36
|
+
is returned as a float32 array (required by
|
|
37
|
+
ccdproc.cosmicray_lacosmic).
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
if kernsize % 2 == 0 or kernsize < 3:
|
|
41
|
+
raise ValueError("kernsize must be an odd integer >= 3.")
|
|
42
|
+
if fwhm_x <= 0 or fwhm_y <= 0:
|
|
43
|
+
raise ValueError("fwhm_x and fwhm_y must be positive numbers.")
|
|
44
|
+
|
|
45
|
+
sigma_x = fwhm_x / (2 * math.sqrt(2 * math.log(2)))
|
|
46
|
+
sigma_y = fwhm_y / (2 * math.sqrt(2 * math.log(2)))
|
|
47
|
+
halfsize = kernsize // 2
|
|
48
|
+
y, x = np.mgrid[-halfsize : halfsize + 1, -halfsize : halfsize + 1]
|
|
49
|
+
kernel = np.exp(-0.5 * ((x / sigma_x) ** 2 + (y / sigma_y) ** 2))
|
|
50
|
+
kernel /= np.sum(kernel)
|
|
51
|
+
|
|
52
|
+
# reverse the psf kernel as that is what it is used in the convolution
|
|
53
|
+
kernel = kernel[::-1, ::-1]
|
|
54
|
+
return kernel.astype(np.float32)
|
|
@@ -9,8 +9,16 @@
|
|
|
9
9
|
|
|
10
10
|
"""Interpolate pixels identified in a mask."""
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
try:
|
|
13
|
+
from maskfill import maskfill
|
|
14
|
+
except ModuleNotFoundError as e:
|
|
15
|
+
raise ModuleNotFoundError(
|
|
16
|
+
"The 'teareduce.cleanest' module requires the 'ccdproc' and 'maskfill' packages. "
|
|
17
|
+
"Please install teareduce with the 'cleanest' extra dependencies: "
|
|
18
|
+
"`pip install teareduce[cleanest]`."
|
|
19
|
+
) from e
|
|
13
20
|
import numpy as np
|
|
21
|
+
from scipy import ndimage
|
|
14
22
|
from tqdm import tqdm
|
|
15
23
|
|
|
16
24
|
from .dilatemask import dilatemask
|
|
@@ -37,11 +45,12 @@ def interpolate(data, mask_crfound, dilation=0, interp_method=None, npoints=None
|
|
|
37
45
|
interpolation.
|
|
38
46
|
interp_method : str, optional
|
|
39
47
|
The interpolation method to use. Options are:
|
|
40
|
-
'x' : Polynomial interpolation in the X direction
|
|
41
|
-
'y' : Polynomial interpolation in the Y direction
|
|
42
|
-
's' : Surface fit (degree 1) interpolation
|
|
43
|
-
'd' : Median of
|
|
44
|
-
'm' : Mean of
|
|
48
|
+
'x' : Polynomial interpolation in the X direction using neighbor pixels
|
|
49
|
+
'y' : Polynomial interpolation in the Y direction using neighbor pixels
|
|
50
|
+
's' : Surface fit (degree 1) interpolation using neighbor pixels
|
|
51
|
+
'd' : Median of neighbor pixels interpolation using neighbor pixels
|
|
52
|
+
'm' : Mean of neighbor pixels interpolation using neighbor pixels
|
|
53
|
+
'k' : Maskfill method, as described in van Dokkum & Pasha (2024)
|
|
45
54
|
npoints : int, optional
|
|
46
55
|
The number of points to use for interpolation. This
|
|
47
56
|
parameter is relevant for 'x', 'y', 's', 'd', and 'm' methods.
|
|
@@ -67,12 +76,14 @@ def interpolate(data, mask_crfound, dilation=0, interp_method=None, npoints=None
|
|
|
67
76
|
"""
|
|
68
77
|
if interp_method is None:
|
|
69
78
|
raise ValueError("interp_method must be specified.")
|
|
70
|
-
if interp_method not in ["x", "y", "s", "d", "m"]:
|
|
79
|
+
if interp_method not in ["x", "y", "s", "d", "m", "k"]:
|
|
71
80
|
raise ValueError(f"Unknown interp_method: {interp_method}")
|
|
72
|
-
if npoints is None:
|
|
73
|
-
raise ValueError("npoints must be specified.")
|
|
74
|
-
if
|
|
81
|
+
if interp_method in ["x", "y", "s", "d", "m"] and npoints is None:
|
|
82
|
+
raise ValueError("npoints must be specified for the chosen interp_method.")
|
|
83
|
+
if interp_method in ["x", "y"] and degree is None:
|
|
75
84
|
raise ValueError("degree must be specified for the chosen interp_method.")
|
|
85
|
+
if data.shape != mask_crfound.shape:
|
|
86
|
+
raise ValueError("data and mask_crfound must have the same shape.")
|
|
76
87
|
|
|
77
88
|
# Apply dilation to the cosmic ray mask if needed
|
|
78
89
|
if dilation > 0:
|
|
@@ -93,44 +104,50 @@ def interpolate(data, mask_crfound, dilation=0, interp_method=None, npoints=None
|
|
|
93
104
|
|
|
94
105
|
# Fix cosmic rays using the specified interpolation method
|
|
95
106
|
cleaned_data = data.copy()
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
107
|
+
if interp_method == "k":
|
|
108
|
+
smoothed_output, _ = maskfill(input_image=data, mask=mask_crfound, size=3, operator="median", smooth=True)
|
|
109
|
+
cleaned_data[mask_crfound] = smoothed_output[mask_crfound]
|
|
110
|
+
mask_fixed[mask_crfound] = True
|
|
111
|
+
num_cr_cleaned = num_features
|
|
112
|
+
elif interp_method in ["x", "y", "s", "d", "m"]:
|
|
113
|
+
num_cr_cleaned = 0
|
|
114
|
+
for cr_index in tqdm(range(1, num_features + 1), disable=not debug):
|
|
115
|
+
if interp_method in ["x", "y"]:
|
|
116
|
+
if 2 * npoints <= degree:
|
|
117
|
+
raise ValueError("2*npoints must be greater than degree for polynomial interpolation.")
|
|
118
|
+
if interp_method == "x":
|
|
119
|
+
interp_func = interpolation_x
|
|
120
|
+
else:
|
|
121
|
+
interp_func = interpolation_y
|
|
122
|
+
interpolation_performed, _, _ = interp_func(
|
|
123
|
+
data=cleaned_data,
|
|
124
|
+
mask_fixed=mask_fixed,
|
|
125
|
+
cr_labels=cr_labels,
|
|
126
|
+
cr_index=cr_index,
|
|
127
|
+
npoints=npoints,
|
|
128
|
+
degree=degree,
|
|
129
|
+
)
|
|
130
|
+
if interpolation_performed:
|
|
131
|
+
num_cr_cleaned += 1
|
|
132
|
+
elif interp_method in ["s", "d", "m"]:
|
|
133
|
+
if interp_method == "s":
|
|
134
|
+
method = "surface"
|
|
135
|
+
elif interp_method == "d":
|
|
136
|
+
method = "median"
|
|
137
|
+
elif interp_method == "m":
|
|
138
|
+
method = "mean"
|
|
139
|
+
interpolation_performed, _, _ = interpolation_a(
|
|
140
|
+
data=cleaned_data,
|
|
141
|
+
mask_fixed=mask_fixed,
|
|
142
|
+
cr_labels=cr_labels,
|
|
143
|
+
cr_index=cr_index,
|
|
144
|
+
npoints=npoints,
|
|
145
|
+
method=method,
|
|
146
|
+
)
|
|
147
|
+
if interpolation_performed:
|
|
148
|
+
num_cr_cleaned += 1
|
|
149
|
+
else:
|
|
150
|
+
raise ValueError(f"Unknown interpolation method: {interp_method}")
|
|
134
151
|
|
|
135
152
|
if debug:
|
|
136
153
|
print(f"Number of cosmic rays cleaned............: {num_cr_cleaned:>{len(sdum)}}")
|