teareduce 0.5.4__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.
@@ -13,11 +13,13 @@ import tkinter as tk
13
13
  from tkinter import ttk
14
14
  from tkinter import messagebox
15
15
 
16
+ from .centerchildparent import center_on_parent
16
17
  from .definitions import lacosmic_default_dict
17
18
 
18
19
 
19
20
  class ParameterEditor:
20
21
  """A dialog to edit L.A.Cosmic parameters."""
22
+
21
23
  def __init__(self, root, param_dict, window_title, xmin, xmax, ymin, ymax, imgshape):
22
24
  """Initialize the parameter editor dialog.
23
25
 
@@ -31,12 +33,16 @@ class ParameterEditor:
31
33
  Title of the dialog window.
32
34
  xmin : int
33
35
  Minimum x-coordinate of the region to be examined.
36
+ From 1 to NAXIS1.
34
37
  xmax : int
35
38
  Maximum x-coordinate of the region to be examined.
39
+ From 1 to NAXIS1.
36
40
  ymin : int
37
41
  Minimum y-coordinate of the region to be examined.
42
+ From 1 to NAXIS2.
38
43
  ymax : int
39
44
  Maximum y-coordinate of the region to be examined.
45
+ From 1 to NAXIS2.
40
46
  imgshape : tuple
41
47
  Shape of the image (height, width).
42
48
 
@@ -70,16 +76,17 @@ class ParameterEditor:
70
76
  self.root.title(window_title)
71
77
  self.param_dict = param_dict
72
78
  # Set default region values
73
- self.param_dict['xmin']['value'] = xmin
74
- self.param_dict['xmax']['value'] = xmax
75
- self.param_dict['ymin']['value'] = ymin
76
- self.param_dict['ymax']['value'] = ymax
79
+ self.param_dict["xmin"]["value"] = xmin
80
+ self.param_dict["xmax"]["value"] = xmax
81
+ self.param_dict["ymin"]["value"] = ymin
82
+ self.param_dict["ymax"]["value"] = ymax
77
83
  self.imgshape = imgshape
78
- self.entries = {'run1': {}, 'run2': {}} # dictionary to hold entry widgets
84
+ self.entries = {"run1": {}, "run2": {}} # dictionary to hold entry widgets
79
85
  self.result_dict = None
80
86
 
81
87
  # Create the form
82
88
  self.create_widgets()
89
+ center_on_parent(child=self.root, parent=self.root.master)
83
90
 
84
91
  def create_widgets(self):
85
92
  """Create the widgets for the dialog."""
@@ -90,7 +97,10 @@ class ParameterEditor:
90
97
  row = 0
91
98
 
92
99
  # Subtitle for L.A.Cosmic parameters
93
- subtitle_label = tk.Label(main_frame, text="L.A.Cosmic Parameters", font=("Arial", 14, "bold"))
100
+ default_font = tk.font.nametofont("TkDefaultFont")
101
+ bold_font = default_font.copy()
102
+ bold_font.configure(weight="bold", size=default_font.cget("size") + 2)
103
+ subtitle_label = tk.Label(main_frame, text="L.A.Cosmic Parameters", font=bold_font)
94
104
  subtitle_label.grid(row=row, column=0, columnspan=4, pady=(0, 15))
95
105
  row += 1
96
106
 
@@ -99,88 +109,101 @@ class ParameterEditor:
99
109
  # so that we can update the color of run2 entries if they differ from run1.
100
110
  self.entry_vars = {}
101
111
  for key, info in self.param_dict.items():
102
- if not key.startswith('run1_'):
112
+ if not key.startswith("run1_"):
103
113
  continue
104
114
  # Parameter name label
105
- label = tk.Label(main_frame, text=f"{key[5:]}:", anchor='e', width=15)
106
- label.grid(row=row, column=0, sticky='w', pady=5)
115
+ label = tk.Label(main_frame, text=f"{key[5:]}:", anchor="e", width=15)
116
+ label.grid(row=row, column=0, sticky="w", pady=5)
107
117
  # Entry field for run1
108
118
  self.entry_vars[key] = tk.StringVar()
109
- self.entry_vars[key].trace_add('write', lambda *args: self.update_colour_param_run1_run2())
119
+ self.entry_vars[key].trace_add("write", lambda *args: self.update_colour_param_run1_run2())
110
120
  entry = tk.Entry(main_frame, textvariable=self.entry_vars[key], width=10)
111
- entry.insert(0, str(info['value']))
121
+ entry.insert(0, str(info["value"]))
112
122
  entry.grid(row=row, column=1, padx=10, pady=5)
113
123
  self.entries[key] = entry # dictionary to hold entry widgets
114
124
  # Entry field for run2
115
- key2 = 'run2_' + key[5:]
125
+ key2 = "run2_" + key[5:]
116
126
  self.entry_vars[key2] = tk.StringVar()
117
- self.entry_vars[key2].trace_add('write', lambda *args: self.update_colour_param_run1_run2())
127
+ self.entry_vars[key2].trace_add("write", lambda *args: self.update_colour_param_run1_run2())
118
128
  entry = tk.Entry(main_frame, textvariable=self.entry_vars[key2], width=10)
119
- entry.insert(0, str(self.param_dict[key2]['value']))
129
+ entry.insert(0, str(self.param_dict[key2]["value"]))
120
130
  entry.grid(row=row, column=2, padx=10, pady=5)
121
- self.entries['run2_'+key[5:]] = entry # dictionary to hold entry widgets
131
+ self.entries["run2_" + key[5:]] = entry # dictionary to hold entry widgets
122
132
  # Type label
123
- type_label = tk.Label(main_frame, text=f"({info['type'].__name__})", fg='gray', anchor='w', width=10)
124
- type_label.grid(row=row, column=3, sticky='w', pady=5)
133
+ type_label = tk.Label(main_frame, text=f"({info['type'].__name__})", fg="gray", anchor="w", width=10)
134
+ type_label.grid(row=row, column=3, sticky="w", pady=5)
125
135
  row += 1
126
136
  # self.update_colour_param_run1_run2()
127
137
 
128
138
  # Separator
129
- separator1 = ttk.Separator(main_frame, orient='horizontal')
130
- separator1.grid(row=row, column=0, columnspan=4, sticky='ew', pady=(10, 10))
139
+ separator1 = ttk.Separator(main_frame, orient="horizontal")
140
+ separator1.grid(row=row, column=0, columnspan=4, sticky="ew", pady=(10, 10))
131
141
  row += 1
132
142
 
133
143
  # Subtitle for additional parameters
134
- subtitle_label = tk.Label(main_frame, text="Additional Parameters", font=("Arial", 14, "bold"))
144
+ subtitle_label = tk.Label(main_frame, text="Additional Parameters", font=bold_font)
135
145
  subtitle_label.grid(row=row, column=0, columnspan=4, pady=(0, 15))
136
146
  row += 1
137
147
 
138
148
  # Dilation label and entry
139
- label = tk.Label(main_frame, text="Dilation:", anchor='e', width=15)
140
- label.grid(row=row, column=0, sticky='w', pady=5)
149
+ label = tk.Label(main_frame, text="Dilation:", anchor="e", width=15)
150
+ label.grid(row=row, column=0, sticky="w", pady=5)
151
+ entry = tk.Entry(main_frame, width=10)
152
+ entry.insert(0, str(self.param_dict["dilation"]["value"]))
153
+ entry.grid(row=row, column=1, padx=10, pady=5)
154
+ self.entries["dilation"] = entry
155
+ type_label = tk.Label(
156
+ main_frame, text=f"({self.param_dict['dilation']['type'].__name__})", fg="gray", anchor="w", width=10
157
+ )
158
+ type_label.grid(row=row, column=2, sticky="w", pady=5)
159
+ row += 1
160
+
161
+ label = tk.Label(main_frame, text="Border Padding:", anchor="e", width=15)
162
+ label.grid(row=row, column=0, sticky="w", pady=5)
141
163
  entry = tk.Entry(main_frame, width=10)
142
- entry.insert(0, str(self.param_dict['dilation']['value']))
164
+ entry.insert(0, str(self.param_dict["borderpadd"]["value"]))
143
165
  entry.grid(row=row, column=1, padx=10, pady=5)
144
- self.entries['dilation'] = entry
145
- type_label = tk.Label(main_frame, text=f"({self.param_dict['dilation']['type'].__name__})",
146
- fg='gray', anchor='w', width=10)
147
- type_label.grid(row=row, column=2, sticky='w', pady=5)
166
+ self.entries["borderpadd"] = entry
167
+ type_label = tk.Label(
168
+ main_frame, text=f"({self.param_dict['borderpadd']['type'].__name__})", fg="gray", anchor="w", width=10
169
+ )
170
+ type_label.grid(row=row, column=2, sticky="w", pady=5)
148
171
  row += 1
149
172
 
150
173
  # Separator
151
- separator2 = ttk.Separator(main_frame, orient='horizontal')
152
- separator2.grid(row=row, column=0, columnspan=4, sticky='ew', pady=(10, 10))
174
+ separator2 = ttk.Separator(main_frame, orient="horizontal")
175
+ separator2.grid(row=row, column=0, columnspan=4, sticky="ew", pady=(10, 10))
153
176
  row += 1
154
177
 
155
178
  # Subtitle for region to be examined
156
- subtitle_label = tk.Label(main_frame, text="Region to be Examined", font=("Arial", 14, "bold"))
179
+ subtitle_label = tk.Label(main_frame, text="Region to be Examined", font=bold_font)
157
180
  subtitle_label.grid(row=row, column=0, columnspan=4, pady=(0, 15))
158
181
  row += 1
159
182
 
160
183
  # Region to be examined label and entries
161
184
  for key, info in self.param_dict.items():
162
- if key.lower() in ['xmin', 'xmax', 'ymin', 'ymax']:
185
+ if key.lower() in ["xmin", "xmax", "ymin", "ymax"]:
163
186
  # Parameter name label
164
- label = tk.Label(main_frame, text=f"{key}:", anchor='e', width=15)
165
- label.grid(row=row, column=0, sticky='w', pady=5)
187
+ label = tk.Label(main_frame, text=f"{key}:", anchor="e", width=15)
188
+ label.grid(row=row, column=0, sticky="w", pady=5)
166
189
  # Entry field
167
190
  entry = tk.Entry(main_frame, width=10)
168
- entry.insert(0, str(info['value']))
191
+ entry.insert(0, str(info["value"]))
169
192
  entry.grid(row=row, column=1, padx=10, pady=5)
170
193
  self.entries[key] = entry # dictionary to hold entry widgets
171
194
  # Type label
172
195
  dumtext = f"({info['type'].__name__})"
173
- if key.lower() in ['xmax', 'ymax']:
196
+ if key.lower() in ["xmin", "xmax"]:
174
197
  dumtext += f" --> [1, {self.imgshape[1]}]"
175
198
  else:
176
199
  dumtext += f" --> [1, {self.imgshape[0]}]"
177
- type_label = tk.Label(main_frame, text=dumtext, fg='gray', anchor='w', width=15)
178
- type_label.grid(row=row, column=2, sticky='w', pady=5)
200
+ type_label = tk.Label(main_frame, text=dumtext, fg="gray", anchor="w", width=15)
201
+ type_label.grid(row=row, column=2, sticky="w", pady=5)
179
202
  row += 1
180
203
 
181
204
  # Separator
182
- separator3 = ttk.Separator(main_frame, orient='horizontal')
183
- separator3.grid(row=row, column=0, columnspan=4, sticky='ew', pady=(10, 10))
205
+ separator3 = ttk.Separator(main_frame, orient="horizontal")
206
+ separator3.grid(row=row, column=0, columnspan=4, sticky="ew", pady=(10, 10))
184
207
  row += 1
185
208
 
186
209
  # Button frame
@@ -189,15 +212,15 @@ class ParameterEditor:
189
212
 
190
213
  # OK button
191
214
  ok_button = tk.Button(button_frame, text="OK", width=5, command=self.on_ok)
192
- ok_button.pack(side='left', padx=5)
215
+ ok_button.pack(side="left", padx=5)
193
216
 
194
217
  # Cancel button
195
218
  cancel_button = tk.Button(button_frame, text="Cancel", width=5, command=self.on_cancel)
196
- cancel_button.pack(side='left', padx=5)
219
+ cancel_button.pack(side="left", padx=5)
197
220
 
198
221
  # Reset button
199
222
  reset_button = tk.Button(button_frame, text="Reset", width=5, command=self.on_reset)
200
- reset_button.pack(side='left', padx=5)
223
+ reset_button.pack(side="left", padx=5)
201
224
 
202
225
  def on_ok(self):
203
226
  """Validate and save the updated values"""
@@ -205,61 +228,60 @@ class ParameterEditor:
205
228
  updated_dict = {}
206
229
 
207
230
  for key, info in self.param_dict.items():
208
- if key == 'nruns':
231
+ if key == "nruns":
209
232
  continue
210
233
  entry_value = self.entries[key].get()
211
- value_type = info['type']
234
+ value_type = info["type"]
212
235
 
213
236
  # Convert string to appropriate type
214
237
  if value_type == bool:
215
238
  # Handle boolean conversion
216
- if entry_value.lower() in ['true', '1', 'yes']:
239
+ if entry_value.lower() in ["true", "1", "yes"]:
217
240
  converted_value = True
218
- elif entry_value.lower() in ['false', '0', 'no']:
241
+ elif entry_value.lower() in ["false", "0", "no"]:
219
242
  converted_value = False
220
243
  else:
221
244
  raise ValueError(f"Invalid boolean value for {key}")
222
245
  else:
223
246
  converted_value = value_type(entry_value)
224
- if 'positive' in info and info['positive'] and converted_value < 0:
247
+ if "positive" in info and info["positive"] and converted_value < 0:
225
248
  raise ValueError(f"Value for {key} must be positive")
226
249
 
227
- updated_dict[key] = {
228
- 'value': converted_value,
229
- 'type': value_type
230
- }
250
+ updated_dict[key] = {"value": converted_value, "type": value_type}
231
251
 
232
252
  # Check whether any run1 and run2 parameters differ
233
253
  nruns = 1
234
254
  for key in self.param_dict.keys():
235
- if key.startswith('run1_'):
255
+ if key.startswith("run1_"):
236
256
  parname = key[5:]
237
- key2 = 'run2_' + parname
238
- if updated_dict[key]['value'] != updated_dict[key2]['value']:
257
+ key2 = "run2_" + parname
258
+ if updated_dict[key]["value"] != updated_dict[key2]["value"]:
239
259
  nruns = 2
240
- print(f"Parameter '{parname}' differs between run1 and run2: "
241
- f"{updated_dict[key]['value']} (run1) vs {updated_dict[key2]['value']} (run2)")
260
+ print(
261
+ f"Parameter '{parname}' differs between run1 and run2: "
262
+ f"{updated_dict[key]['value']} (run1) vs {updated_dict[key2]['value']} (run2)"
263
+ )
242
264
 
243
265
  # Additional validation for region limits
244
266
  try:
245
- if updated_dict['xmax']['value'] <= updated_dict['xmin']['value']:
267
+ if updated_dict["xmax"]["value"] <= updated_dict["xmin"]["value"]:
246
268
  raise ValueError("xmax must be greater than xmin")
247
- if updated_dict['ymax']['value'] <= updated_dict['ymin']['value']:
269
+ if updated_dict["ymax"]["value"] <= updated_dict["ymin"]["value"]:
248
270
  raise ValueError("ymax must be greater than ymin")
249
271
  self.result_dict = updated_dict
250
- self.result_dict['nruns'] = {'value': nruns, 'type': int, 'positive': True}
272
+ self.result_dict["nruns"] = {"value": nruns, "type": int, "positive": True}
251
273
  if nruns not in [1, 2]:
252
274
  raise ValueError("nruns must be 1 or 2")
253
275
  self.root.destroy()
254
276
  except ValueError as e:
255
- messagebox.showerror("Invalid Inputs",
256
- "Error in region limits:\n"
257
- f"{str(e)}\n\nPlease check your inputs.")
277
+ messagebox.showerror(
278
+ "Invalid Inputs", "Error in region limits:\n" f"{str(e)}\n\nPlease check your inputs."
279
+ )
258
280
 
259
281
  except ValueError as e:
260
- messagebox.showerror("Invalid Inputs",
261
- f"Error converting value for {key}:\n{str(e)}\n\n"
262
- "Please check your inputs.")
282
+ messagebox.showerror(
283
+ "Invalid Inputs", f"Error converting value for {key}:\n{str(e)}\n\n" "Please check your inputs."
284
+ )
263
285
 
264
286
  def on_cancel(self):
265
287
  """Close without saving"""
@@ -269,15 +291,15 @@ class ParameterEditor:
269
291
  def on_reset(self):
270
292
  """Reset all fields to original values"""
271
293
  self.param_dict = lacosmic_default_dict.copy()
272
- self.param_dict['xmin']['value'] = 1
273
- self.param_dict['xmax']['value'] = self.imgshape[1]
274
- self.param_dict['ymin']['value'] = 1
275
- self.param_dict['ymax']['value'] = self.imgshape[0]
294
+ self.param_dict["xmin"]["value"] = 1
295
+ self.param_dict["xmax"]["value"] = self.imgshape[1]
296
+ self.param_dict["ymin"]["value"] = 1
297
+ self.param_dict["ymax"]["value"] = self.imgshape[0]
276
298
  for key, info in self.param_dict.items():
277
- if key == 'nruns':
299
+ if key == "nruns":
278
300
  continue
279
301
  self.entries[key].delete(0, tk.END)
280
- self.entries[key].insert(0, str(info['value']))
302
+ self.entries[key].insert(0, str(info["value"]))
281
303
 
282
304
  def get_result(self):
283
305
  """Return the updated dictionary"""
@@ -287,10 +309,10 @@ class ParameterEditor:
287
309
  """Update the foreground color of run1 and run2 entries."""
288
310
  # Highlight run2 parameter if different from run1
289
311
  for key in self.param_dict.keys():
290
- if key.startswith('run1_'):
312
+ if key.startswith("run1_"):
291
313
  parname = key[5:]
292
- if key in self.entries and 'run2_'+parname in self.entries:
293
- if self.entries[key].get() != self.entries['run2_'+parname].get():
294
- self.entries['run2_'+parname].config(fg='red')
314
+ if key in self.entries and "run2_" + parname in self.entries:
315
+ if self.entries[key].get() != self.entries["run2_" + parname].get():
316
+ self.entries["run2_" + parname].config(fg="red")
295
317
  else:
296
- self.entries['run2_'+parname].config(fg='black')
318
+ self.entries["run2_" + parname].config(fg="black")