teareduce 0.5.4__tar.gz → 0.5.5__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.
Files changed (57) hide show
  1. {teareduce-0.5.4/src/teareduce.egg-info → teareduce-0.5.5}/PKG-INFO +1 -1
  2. teareduce-0.5.5/src/teareduce/cleanest/__main__.py +110 -0
  3. teareduce-0.5.5/src/teareduce/cleanest/centerchildparent.py +46 -0
  4. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/cleanest.py +16 -19
  5. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/cosmicraycleanerapp.py +262 -170
  6. teareduce-0.5.5/src/teareduce/cleanest/definitions.py +63 -0
  7. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/imagedisplay.py +8 -9
  8. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/interpolation_a.py +5 -9
  9. teareduce-0.5.5/src/teareduce/cleanest/interpolationeditor.py +332 -0
  10. teareduce-0.5.5/src/teareduce/cleanest/modalprogressbar.py +182 -0
  11. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/parametereditor.py +98 -76
  12. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/reviewcosmicray.py +90 -62
  13. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/version.py +1 -1
  14. {teareduce-0.5.4 → teareduce-0.5.5/src/teareduce.egg-info}/PKG-INFO +1 -1
  15. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce.egg-info/SOURCES.txt +2 -0
  16. teareduce-0.5.4/src/teareduce/cleanest/__main__.py +0 -61
  17. teareduce-0.5.4/src/teareduce/cleanest/definitions.py +0 -62
  18. teareduce-0.5.4/src/teareduce/cleanest/interpolationeditor.py +0 -211
  19. {teareduce-0.5.4 → teareduce-0.5.5}/LICENSE.txt +0 -0
  20. {teareduce-0.5.4 → teareduce-0.5.5}/README.md +0 -0
  21. {teareduce-0.5.4 → teareduce-0.5.5}/pyproject.toml +0 -0
  22. {teareduce-0.5.4 → teareduce-0.5.5}/setup.cfg +0 -0
  23. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/__init__.py +0 -0
  24. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/avoid_astropy_warnings.py +0 -0
  25. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/__init__.py +0 -0
  26. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/dilatemask.py +0 -0
  27. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/find_closest_true.py +0 -0
  28. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/interpolation_x.py +0 -0
  29. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cleanest/interpolation_y.py +0 -0
  30. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cookbook/__init__.py +0 -0
  31. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cookbook/get_cookbook_file.py +0 -0
  32. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/correct_pincushion_distortion.py +0 -0
  33. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/cosmicrays.py +0 -0
  34. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/ctext.py +0 -0
  35. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/draw_rectangle.py +0 -0
  36. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/elapsed_time.py +0 -0
  37. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/histogram1d.py +0 -0
  38. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/imshow.py +0 -0
  39. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/numsplines.py +0 -0
  40. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/peaks_spectrum.py +0 -0
  41. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/polfit.py +0 -0
  42. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/robust_std.py +0 -0
  43. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/sdistortion.py +0 -0
  44. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/simulateccdexposure.py +0 -0
  45. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/sliceregion.py +0 -0
  46. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/statsummary.py +0 -0
  47. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/tests/__init__.py +0 -0
  48. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/tests/test_cleanest.py +0 -0
  49. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/tests/test_sliceregion.py +0 -0
  50. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/tests/test_version.py +0 -0
  51. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/wavecal.py +0 -0
  52. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/write_array_to_fits.py +0 -0
  53. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce/zscale.py +0 -0
  54. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce.egg-info/dependency_links.txt +0 -0
  55. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce.egg-info/entry_points.txt +0 -0
  56. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce.egg-info/requires.txt +0 -0
  57. {teareduce-0.5.4 → teareduce-0.5.5}/src/teareduce.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: teareduce
3
- Version: 0.5.4
3
+ Version: 0.5.5
4
4
  Summary: Utilities for astronomical data reduction
5
5
  Author-email: Nicolás Cardiel <cardiel@ucm.es>
6
6
  License: GPL-3.0-or-later
@@ -0,0 +1,110 @@
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
+ """Interactive Cosmic Ray cleaning tool."""
11
+
12
+ import argparse
13
+ import tkinter as tk
14
+ import os
15
+ import platform
16
+ from rich import print
17
+ from rich_argparse import RichHelpFormatter
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
23
+ from .cosmicraycleanerapp import CosmicRayCleanerApp
24
+
25
+ import matplotlib
26
+
27
+ matplotlib.use("TkAgg")
28
+
29
+
30
+ def main():
31
+ parser = argparse.ArgumentParser(
32
+ description="Interactive cosmic ray cleaner for FITS images.",
33
+ formatter_class=RichHelpFormatter,
34
+ )
35
+ parser.add_argument("input_fits", help="Path to the FITS file to be cleaned.")
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
+ )
68
+ args = parser.parse_args()
69
+
70
+ if not os.path.isfile(args.input_fits):
71
+ print(f"Error: File '{args.input_fits}' does not exist.")
72
+ return
73
+ if args.auxfile is not None and not os.path.isfile(args.auxfile):
74
+ print(f"Error: Auxiliary file '{args.auxfile}' does not exist.")
75
+ return
76
+
77
+ # Initialize Tkinter root
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
91
+
92
+ # Create and run the application
93
+ CosmicRayCleanerApp(
94
+ root=root,
95
+ input_fits=args.input_fits,
96
+ extension=args.extension,
97
+ auxfile=args.auxfile,
98
+ extension_auxfile=args.extension_auxfile,
99
+ fontfamily=args.fontfamily,
100
+ fontsize=args.fontsize,
101
+ width=args.width,
102
+ height=args.height,
103
+ )
104
+
105
+ # Execute
106
+ root.mainloop()
107
+
108
+
109
+ if __name__ == "__main__":
110
+ main()
@@ -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}")
@@ -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 ['x', 'y', 's', 'd', 'm']:
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 ['x', 'y']:
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 ['x', 'y']:
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 == 'x':
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 ['s', 'd', 'm']:
117
- if interp_method == 's':
118
- method = 'surface'
119
- elif interp_method == 'd':
120
- method = 'median'
121
- elif interp_method == 'm':
122
- method = 'mean'
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