pyGCG 0.6.3__tar.gz → 0.7.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyGCG
3
- Version: 0.6.3
3
+ Version: 0.7.2
4
4
  Summary: A GUI to aid in viewing and classifying NIRISS data products from GLASS-JWST.
5
5
  Author-email: Peter Watson <peter.watson+pygcg@inaf.it>
6
6
  Project-URL: Homepage, https://github.com/PJ-Watson/pyGCG
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyGCG
3
- Version: 0.6.3
3
+ Version: 0.7.2
4
4
  Summary: A GUI to aid in viewing and classifying NIRISS data products from GLASS-JWST.
5
5
  Author-email: Peter Watson <peter.watson+pygcg@inaf.it>
6
6
  Project-URL: Homepage, https://github.com/PJ-Watson/pyGCG
@@ -14,6 +14,7 @@ from tqdm import tqdm
14
14
  from pygcg.tabs import BeamFrame, SpecFrame
15
15
  from pygcg.utils import ValidateFloatVar, flatten_dict, fpe
16
16
  from pygcg.windows import CommentsWindow, SearchWindow, SettingsWindow
17
+ from itertools import product
17
18
 
18
19
 
19
20
  class GCG(ctk.CTk):
@@ -115,6 +116,17 @@ class GCG(ctk.CTk):
115
116
  )
116
117
 
117
118
  self.current_gal_data = {}
119
+ self.poss_extvers = []
120
+ for g, p in product(
121
+ [
122
+ self.config["grisms"]["B"],
123
+ self.config["grisms"]["G"],
124
+ self.config["grisms"]["R"],
125
+ ],
126
+ [self.config["grisms"]["PA1"], self.config["grisms"]["PA2"]],
127
+ ):
128
+ self.poss_extvers.append(f"{g},{p}")
129
+ self.current_gal_data[f"{g},{p}"] = {}
118
130
 
119
131
  self.warning_flag = True
120
132
 
@@ -270,6 +282,8 @@ class GCG(ctk.CTk):
270
282
  self.temp_dir.mkdir(exist_ok=True)
271
283
 
272
284
  out_name = self.config["files"].get("out_cat_name", "pyGCG_output.fits")
285
+ if out_name == "":
286
+ out_name = "pyGCG_output.fits"
273
287
  self.out_cat_path = fpe(self.config["files"]["out_dir"]) / out_name
274
288
  self.read_write_button.configure(state="normal")
275
289
  except:
@@ -303,6 +317,7 @@ class GCG(ctk.CTk):
303
317
  "GRIZLI_REDSHIFT",
304
318
  "ESTIMATED_REDSHIFT",
305
319
  "UNRELIABLE_REDSHIFT",
320
+ "TENTATIVE_REDSHIFT",
306
321
  "BAD_SEG_MAP",
307
322
  "COMMENTS",
308
323
  ],
@@ -327,8 +342,33 @@ class GCG(ctk.CTk):
327
342
  float,
328
343
  bool,
329
344
  bool,
345
+ bool,
330
346
  str,
331
347
  ],
348
+ units=[
349
+ None,
350
+ None,
351
+ "deg",
352
+ "deg",
353
+ None,
354
+ None,
355
+ None,
356
+ None,
357
+ None,
358
+ None,
359
+ None,
360
+ None,
361
+ None,
362
+ None,
363
+ None,
364
+ None,
365
+ None,
366
+ None,
367
+ None,
368
+ None,
369
+ None,
370
+ None,
371
+ ],
332
372
  )
333
373
 
334
374
  for key, default in zip(
@@ -417,9 +457,13 @@ class GCG(ctk.CTk):
417
457
 
418
458
  pad = self.config.get("catalogue", {}).get("seg_id_length", 5)
419
459
 
420
- row_ids = [s.stem[-4 - pad : -4] for s in dir_to_chk.glob("*.row.fits")]
421
- stack_ids = [s.stem[-6 - pad : -6] for s in dir_to_chk.glob("*.stack.fits")]
422
- oned_ids = [s.stem[-3 - pad : -3] for s in dir_to_chk.glob("*.1D.fits")]
460
+ row_ids = [s.stem[-4 - pad : -4] for s in dir_to_chk.glob("**/*.row.fits")]
461
+ stack_ids = [
462
+ s.stem[-6 - pad : -6] for s in dir_to_chk.glob("**/*.stack.fits")
463
+ ] + [
464
+ s.stem[-3 - pad : -3] for s in dir_to_chk.glob("**/*.2D.fits")
465
+ ]
466
+ oned_ids = [s.stem[-3 - pad : -3] for s in dir_to_chk.glob("**/*.1D.fits")]
423
467
 
424
468
  for i, (n, s) in tqdm(
425
469
  enumerate(zip(self.id_col, self.seg_id_col)),
@@ -444,10 +488,17 @@ class GCG(ctk.CTk):
444
488
  self.id_col = self.id_col[id_idx_list]
445
489
  self.seg_id_col = self.seg_id_col[id_idx_list]
446
490
  self.cat = self.cat[id_idx_list]
447
- self.sky_coords = SkyCoord(
448
- self.cat[self.config.get("catalogue", {}).get("ra", "X_WORLD")],
449
- self.cat[self.config.get("catalogue", {}).get("dec", "Y_WORLD")],
450
- )
491
+ try:
492
+ self.sky_coords = SkyCoord(
493
+ self.cat[self.config.get("catalogue", {}).get("ra", "X_WORLD")],
494
+ self.cat[self.config.get("catalogue", {}).get("dec", "Y_WORLD")],
495
+ )
496
+ except:
497
+ self.sky_coords = SkyCoord(
498
+ self.cat[self.config.get("catalogue", {}).get("ra", "X_WORLD")],
499
+ self.cat[self.config.get("catalogue", {}).get("dec", "Y_WORLD")],
500
+ unit="deg"
501
+ )
451
502
 
452
503
  assert len(self.id_col) > 0
453
504
 
@@ -799,7 +850,10 @@ class GCG(ctk.CTk):
799
850
  mid_message = (
800
851
  "Classifications will not be saved."
801
852
  if self.read_write_button.get().lower() == "read-only"
802
- else "Classifications will be written to ??? in the output directory."
853
+ else (
854
+ f"Classifications will be written to "
855
+ f"{self.out_cat_path.name} in the output directory."
856
+ )
803
857
  )
804
858
  check_overwrite = CTkMessagebox(
805
859
  title="Read/Write Mode",
@@ -868,7 +922,7 @@ class GCG(ctk.CTk):
868
922
  flattened_data = flatten_dict(self.current_gal_data)
869
923
 
870
924
  if (
871
- len(flattened_data) == 21
925
+ len(flattened_data) == 22
872
926
  and self.read_write_button.get() == "Write output"
873
927
  and np.sum([*self.object_progress.values()]) == 3
874
928
  ):
@@ -943,7 +997,6 @@ class GCG(ctk.CTk):
943
997
  rad_val = f"{self.tab_row[rad_name]:.0f}"
944
998
  else:
945
999
  rad_val = float(plate_scale) * self.tab_row[rad_name].value * u.arcsec
946
- print(rad_val)
947
1000
  rad_val = f"{rad_val:.2f}"
948
1001
  rad_text = f"r\u2096\u1d63\u2092\u2099 = {rad_val}"
949
1002
  except Exception as e:
@@ -967,15 +1020,21 @@ class GCG(ctk.CTk):
967
1020
  self.current_gal_data["unreliable_redshift"] = out_row[
968
1021
  "UNRELIABLE_REDSHIFT"
969
1022
  ]
1023
+ self.current_gal_data["tentative_redshift"] = out_row[
1024
+ "TENTATIVE_REDSHIFT"
1025
+ ]
970
1026
  self.current_gal_data["bad_seg_map"] = out_row["BAD_SEG_MAP"]
971
1027
 
1028
+ for gp in self.poss_extvers:
1029
+ self.current_gal_data[gp] = {}
1030
+
972
1031
  def change_sky_coord(self, event=None):
973
1032
  new_coord = None
974
1033
  try:
975
1034
  new_coord = SkyCoord(self.current_gal_coords.get())
976
1035
  except ValueError:
977
1036
  try:
978
- parts = re.split("\s*[,|;|\s]\s*", self.current_gal_coords.get())
1037
+ parts = re.split(r"\s*[,|;|\s]\s*", self.current_gal_coords.get())
979
1038
  if len(parts) == 2:
980
1039
  new_coord = SkyCoord(
981
1040
  float(parts[0]) * u.deg, float(parts[1]) * u.deg
@@ -75,10 +75,6 @@ plate_scale = 0.03 # arcsec/pixel. If specified, radii are taken to be in pixels
75
75
  tex_name = 'NII'
76
76
  centre = 6585.27
77
77
 
78
- [lines.emission.PaE]
79
- tex_name = 'Pa-$\eta$'
80
- centre = 9548.6
81
-
82
78
  [lines.emission.PaD]
83
79
  tex_name = 'Pa-$\delta$'
84
80
  centre = 10052.1
@@ -105,7 +101,11 @@ plate_scale = 0.03 # arcsec/pixel. If specified, radii are taken to be in pixels
105
101
 
106
102
  [lines.emission.SIII_9069]
107
103
  tex_name = 'SIII'
108
- centre = 9068.6
104
+ centre = 9071.1
105
+
106
+ [lines.emission.SIII_9531]
107
+ tex_name = 'SIII'
108
+ centre = 9533.2
109
109
 
110
110
  [lines.emission.HeI_10830]
111
111
  tex_name = 'HeI'
@@ -93,14 +93,11 @@ class BeamFrame(ctk.CTkFrame):
93
93
  Path(self._root().config["files"]["extractions_dir"])
94
94
  .expanduser()
95
95
  .resolve()
96
- ).glob(f"*{self._root().seg_id:0>{pad}}.stack.fits")
96
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.stack.fits")
97
97
  ][0]
98
98
  except:
99
99
  self.file_path = None
100
100
 
101
- # print (self.master)
102
- # if self._root().main_tabs.get() in self._root().tab_names[0:2]:
103
- # print ("yes")
104
101
  self.generate_grid()
105
102
 
106
103
  def change_cmap(self, event=None):
@@ -119,7 +116,10 @@ class BeamFrame(ctk.CTkFrame):
119
116
  if self.gal_id == self._root().current_gal_id.get() and not force_update:
120
117
  self.beam_single_PA_frame.quality_frame.save_current()
121
118
  for k, v in self.beam_single_PA_frame.coverage.items():
122
- self._root().current_gal_data[k]["coverage"] = v
119
+ try:
120
+ self._root().current_gal_data[k]["coverage"] = v
121
+ except:
122
+ pass
123
123
  pass
124
124
  else:
125
125
  self.gal_id = self._root().current_gal_id.get()
@@ -129,22 +129,11 @@ class BeamFrame(ctk.CTkFrame):
129
129
  Path(self._root().config["files"]["extractions_dir"])
130
130
  .expanduser()
131
131
  .resolve()
132
- ).glob(f"*{self._root().seg_id:0>{pad}}.stack.fits")
132
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.stack.fits")
133
133
  ][0]
134
- with pf.open(self.file_path) as hdul:
135
- header = hdul[0].header
136
- n_grism = len(self._root().filter_names)
137
- n_pa = len(self._root().PAs)
138
- self.beam_frame_list = []
139
- extver_list = []
140
- for i in range(n_grism):
141
- try:
142
- grism_name = self._root().filter_names[::-1][i]
143
- extver = grism_name + f",{self.PA}"
144
- except:
145
- extver = "none"
146
- extver_list.append(extver)
147
- self.beam_single_PA_frame.update_plots(extvers=extver_list)
134
+
135
+ extver_list = [s for s in self._root().poss_extvers if self.PA in s]
136
+ self.beam_single_PA_frame.update_plots(extvers=extver_list)
148
137
 
149
138
  self.update()
150
139
 
@@ -155,18 +144,10 @@ class BeamFrame(ctk.CTkFrame):
155
144
  n_pa = np.nanmax(
156
145
  [header[f"N{header[f'GRISM{n:0>3}']}"] for n in range(1, n_grism + 1)]
157
146
  )
158
- self.beam_frame_list = []
159
- row = 0
160
- extver_list = []
161
- for i in range(n_grism):
162
- grism_name = header[f"GRISM{i+1:0>3}"]
163
- pa = "," + str(header[f"{grism_name}{row+1:0>2}"])
164
- extver = grism_name + pa
165
- extver = grism_name + f",{self.PA}"
166
- extver_list.append(extver)
167
- self.beam_single_PA_frame = SinglePABeamFrame(self, extvers=extver_list)
168
- self.beam_single_PA_frame.grid(row=1, column=0, sticky="news")
147
+ extver_list = [s for s in self._root().poss_extvers if self.PA in s]
169
148
 
149
+ self.beam_single_PA_frame = SinglePABeamFrame(self, extvers= extver_list)
150
+ self.beam_single_PA_frame.grid(row=1, column=0, sticky="news")
170
151
  self.grid_rowconfigure(1, weight=1)
171
152
  self.grid_columnconfigure(0, weight=1)
172
153
 
@@ -200,14 +181,12 @@ class SinglePABeamFrame(ctk.CTkFrame):
200
181
 
201
182
  self.check_axes_colours()
202
183
 
203
- # plt.style.use("dark_background")
204
-
205
184
  self.extvers = extvers
206
185
  self.coverage = {}
207
- widths = [1 / 3, 1] * len(self.extvers)
186
+ widths = [1 / 3, 1] * 3
208
187
  self.fig_axes = self.fig.subplots(
209
188
  4,
210
- 2 * len(self.extvers),
189
+ 6,
211
190
  sharey=True,
212
191
  width_ratios=widths,
213
192
  )
@@ -70,13 +70,37 @@ class SpecFrame(ctk.CTkFrame):
70
70
 
71
71
  self.redshift_frame = ctk.CTkFrame(self)
72
72
  self.redshift_frame.grid(row=2, column=2, sticky="news")
73
- self.redshift_frame.columnconfigure([0, 1], weight=1)
73
+ self.redshift_frame.columnconfigure([0, 1, 2, 3, 4, 5], weight=1)
74
74
  self.redshift_label = ctk.CTkLabel(
75
75
  self.redshift_frame, text="Estimated redshift:"
76
76
  )
77
77
  self.redshift_label.grid(
78
78
  row=0, column=0, columnspan=2, padx=(20, 10), pady=(10,), sticky="w"
79
79
  )
80
+ self.redshift_spec_info = ctk.CTkLabel(
81
+ self.redshift_frame,
82
+ text="test",
83
+ )
84
+ self.redshift_spec_info.grid(
85
+ row=0,
86
+ column=2,
87
+ columnspan=2,
88
+ padx=(20, 10),
89
+ pady=(10,),
90
+ sticky="we",
91
+ )
92
+ self.redshift_phot_info = ctk.CTkLabel(
93
+ self.redshift_frame,
94
+ text="test2",
95
+ )
96
+ self.redshift_phot_info.grid(
97
+ row=0,
98
+ column=4,
99
+ columnspan=2,
100
+ padx=(20, 10),
101
+ pady=(10,),
102
+ sticky="we",
103
+ )
80
104
  self.current_redshift = ValidateFloatVar(
81
105
  master=self,
82
106
  value=0,
@@ -88,6 +112,7 @@ class SpecFrame(ctk.CTkFrame):
88
112
  self.redshift_entry.grid(
89
113
  row=1,
90
114
  column=0,
115
+ columnspan=3,
91
116
  padx=(20, 10),
92
117
  pady=(10, 0),
93
118
  sticky="we",
@@ -103,7 +128,8 @@ class SpecFrame(ctk.CTkFrame):
103
128
  )
104
129
  self.reset_redshift_button.grid(
105
130
  row=1,
106
- column=1,
131
+ column=3,
132
+ columnspan=3,
107
133
  padx=(20, 10),
108
134
  pady=(10, 0),
109
135
  sticky="we",
@@ -118,32 +144,56 @@ class SpecFrame(ctk.CTkFrame):
118
144
  self.redshift_slider.grid(
119
145
  row=2,
120
146
  column=0,
121
- columnspan=2,
147
+ columnspan=6,
122
148
  padx=(20, 10),
123
149
  pady=10,
124
150
  sticky="we",
125
151
  )
126
152
 
127
- self.z_q_checkbox = ctk.CTkCheckBox(
153
+ self.z_q_checkbox_un = ctk.CTkCheckBox(
128
154
  self.redshift_frame,
129
- text="Unreliable redshift",
130
- command=self.z_q_update,
155
+ text="Unreliable z",
156
+ command=self.z_q_update_un,
157
+ )
158
+ self.z_q_checkbox_un.grid(
159
+ row=3, column=0, columnspan=2, padx=(20, 10), pady=10, sticky="w"
160
+ )
161
+
162
+ self.z_q_checkbox_te = ctk.CTkCheckBox(
163
+ self.redshift_frame,
164
+ text="Tentative z",
165
+ command=self.z_q_update_te,
166
+ )
167
+ self.z_q_checkbox_te.grid(
168
+ row=3, column=2, columnspan=2, padx=(20, 10), pady=10, sticky="w"
131
169
  )
132
- self.z_q_checkbox.grid(row=3, column=0, padx=(20, 10), pady=10, sticky="w")
133
170
 
134
171
  self.bad_seg_checkbox = ctk.CTkCheckBox(
135
172
  self.redshift_frame,
136
173
  text="Bad segmentation map",
137
174
  command=self.bad_seg_update,
138
175
  )
139
- self.bad_seg_checkbox.grid(row=3, column=1, padx=(20, 10), pady=10, sticky="w")
176
+ self.bad_seg_checkbox.grid(
177
+ row=3,
178
+ column=4,
179
+ columnspan=2,
180
+ padx=(20, 10),
181
+ pady=10,
182
+ sticky="w",
183
+ )
140
184
 
141
185
  self.muse_checkbox = ctk.CTkCheckBox(
142
186
  self.plot_options_frame,
143
187
  text="MUSE spectrum",
144
188
  command=self.change_components,
145
189
  )
146
- self.muse_checkbox.grid(row=0, column=2, padx=20, pady=(10, 10), sticky="w")
190
+ self.muse_checkbox.grid(
191
+ row=0,
192
+ column=2,
193
+ padx=20,
194
+ pady=(10, 10),
195
+ sticky="w",
196
+ )
147
197
  self.grizli_checkbox = ctk.CTkCheckBox(
148
198
  self.plot_options_frame,
149
199
  text="NIRISS spectrum",
@@ -166,8 +216,13 @@ class SpecFrame(ctk.CTkFrame):
166
216
  )
167
217
  self.images_frame.grid(row=2, column=0, columnspan=2, sticky="news")
168
218
 
169
- def z_q_update(self):
170
- self._root().current_gal_data["unreliable_redshift"] = self.z_q_checkbox.get()
219
+ def z_q_update_un(self):
220
+ self._root().current_gal_data[
221
+ "unreliable_redshift"
222
+ ] = self.z_q_checkbox_un.get()
223
+
224
+ def z_q_update_te(self):
225
+ self._root().current_gal_data["tentative_redshift"] = self.z_q_checkbox_te.get()
171
226
 
172
227
  def bad_seg_update(self):
173
228
  self._root().current_gal_data["bad_seg_map"] = self.bad_seg_checkbox.get()
@@ -239,7 +294,7 @@ class SpecFrame(ctk.CTkFrame):
239
294
  Path(self._root().config["files"]["extractions_dir"])
240
295
  .expanduser()
241
296
  .resolve()
242
- ).glob(f"*{self._root().seg_id:0>{pad}}.row.fits")
297
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.row.fits")
243
298
  ][0]
244
299
  with pf.open(_row_path) as hdul:
245
300
  grizli_redshift = Table(hdul[1].data)["redshift"].value[0]
@@ -252,6 +307,9 @@ class SpecFrame(ctk.CTkFrame):
252
307
  self.unreliable_redshift = self._root().current_gal_data.get(
253
308
  "unreliable_redshift", False
254
309
  )
310
+ self.tentative_redshift = self._root().current_gal_data.get(
311
+ "tentative_redshift", False
312
+ )
255
313
  self.bad_seg = self._root().current_gal_data.get("bad_seg_map", False)
256
314
 
257
315
  self._root().current_gal_data["grizli_redshift"] = self.grizli_redshift
@@ -261,11 +319,49 @@ class SpecFrame(ctk.CTkFrame):
261
319
  self._root().current_gal_data[
262
320
  "unreliable_redshift"
263
321
  ] = self.unreliable_redshift
322
+ self._root().current_gal_data[
323
+ "tentative_redshift"
324
+ ] = self.tentative_redshift
264
325
  self._root().current_gal_data["bad_seg_map"] = self.bad_seg
265
326
  self.current_redshift.set(self.estimated_redshift)
266
327
  self.redshift_slider.set(self.estimated_redshift)
267
- self.z_q_checkbox.select() if self.unreliable_redshift else self.z_q_checkbox.deselect()
268
- self.bad_seg_checkbox.select() if self.bad_seg else self.bad_seg_checkbox.deselect()
328
+ (
329
+ self.z_q_checkbox_un.select()
330
+ if self.unreliable_redshift
331
+ else self.z_q_checkbox_un.deselect()
332
+ )
333
+ (
334
+ self.z_q_checkbox_te.select()
335
+ if self.unreliable_redshift
336
+ else self.z_q_checkbox_te.deselect()
337
+ )
338
+ (
339
+ self.bad_seg_checkbox.select()
340
+ if self.bad_seg
341
+ else self.bad_seg_checkbox.deselect()
342
+ )
343
+
344
+ try:
345
+ phot_z_name = self._root().config.get("catalogue", {}).get("zphot", "zphot")
346
+ phot_z = self._root().tab_row[phot_z_name]
347
+ assert phot_z != "--"
348
+ phot_z_text = f"z\u209a\u2095\u2092\u209c = {phot_z:.3f} "
349
+ except Exception as e:
350
+ phot_z_text = "z\u209a\u2095\u2092\u209c = n/a "
351
+ self.redshift_phot_info.configure(
352
+ text=(f"{phot_z_text}"),
353
+ )
354
+
355
+ try:
356
+ spec_z_name = self._root().config.get("catalogue", {}).get("zspec", "zspec")
357
+ spec_z = self._root().tab_row[spec_z_name]
358
+ assert spec_z != "--"
359
+ spec_z_text = f"z\u209b\u209a\u2091\U0001E03F = {spec_z:.3f} "
360
+ except Exception as e:
361
+ spec_z_text = f"z\u209b\u209a\u2091\U0001E03F = n/a "
362
+ self.redshift_spec_info.configure(
363
+ text=(f"{spec_z_text}"),
364
+ )
269
365
 
270
366
  def _update_all(self):
271
367
  self.check_axes_colours()
@@ -299,7 +395,7 @@ class SpecFrame(ctk.CTkFrame):
299
395
  Path(self._root().config["files"]["extractions_dir"])
300
396
  .expanduser()
301
397
  .resolve()
302
- ).glob(f"*{self._root().seg_id:0>{pad}}.1D.fits")
398
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.1D.fits")
303
399
  ][0]
304
400
 
305
401
  if templates:
@@ -329,14 +425,16 @@ class SpecFrame(ctk.CTkFrame):
329
425
  data_table["line"][clip] / data_table["flat"][clip] / 1e-19,
330
426
  )
331
427
  except:
332
- (
333
- self.plotted_components[dict_key][hdu.name],
334
- ) = self.fig_axes.plot(
335
- data_table["wave"][clip],
336
- data_table["line"][clip] / data_table["flat"][clip] / 1e-19,
337
- c="red",
338
- alpha=0.7,
339
- zorder=10,
428
+ (self.plotted_components[dict_key][hdu.name],) = (
429
+ self.fig_axes.plot(
430
+ data_table["wave"][clip],
431
+ data_table["line"][clip]
432
+ / data_table["flat"][clip]
433
+ / 1e-19,
434
+ c="red",
435
+ alpha=0.7,
436
+ zorder=10,
437
+ )
340
438
  )
341
439
  else:
342
440
  try:
@@ -368,16 +466,16 @@ class SpecFrame(ctk.CTkFrame):
368
466
  yerr=y_err,
369
467
  )
370
468
  except:
371
- self.plotted_components[dict_key][
372
- hdu.name
373
- ] = self.fig_axes.errorbar(
374
- data_table["wave"][clip],
375
- y_vals,
376
- yerr=y_err,
377
- fmt="o",
378
- markersize=3,
379
- ecolor=colors.to_rgba(colours[hdu.name], 0.5),
380
- c=colours[hdu.name],
469
+ self.plotted_components[dict_key][hdu.name] = (
470
+ self.fig_axes.errorbar(
471
+ data_table["wave"][clip],
472
+ y_vals,
473
+ yerr=y_err,
474
+ fmt="o",
475
+ markersize=3,
476
+ ecolor=colors.to_rgba(colours[hdu.name], 0.5),
477
+ c=colours[hdu.name],
478
+ )
381
479
  )
382
480
  ymax = np.nanmax([ymax, np.nanmax(y_vals)])
383
481
 
@@ -774,7 +872,7 @@ class ImagesFrame(ctk.CTkFrame):
774
872
  Path(self._root().config["files"]["prep_dir"])
775
873
  .expanduser()
776
874
  .resolve()
777
- ).glob(f"*{p.lower()}_drz_sci.fits")
875
+ ).glob(f"*{p.lower()}*_dr[zc]_sci.fits")
778
876
  ]
779
877
  if len(rgb_path) == 0:
780
878
  print(f"{p} image not found.")
@@ -956,16 +1054,29 @@ class ImagesFrame(ctk.CTkFrame):
956
1054
 
957
1055
  for i, v in enumerate(self.rgb_paths):
958
1056
  with pf.open(v) as hdul:
1057
+ try:
1058
+ zp = hdul[0].header["ZP"]
1059
+ except:
1060
+ try:
1061
+ # PASSAGE
1062
+ zp = (
1063
+ -2.5 * np.log10(hdul[0].header["PHOTFLAM"])
1064
+ - 5 * np.log10(hdul[0].header["PHOTPLAM"])
1065
+ - 2.408
1066
+ )
1067
+ except:
1068
+ # Dawn JWST products
1069
+ zp = 28.9
959
1070
  self.rgb_data[i] = hdul[0].data[
960
1071
  self.cutout_dimensions[0] : self.cutout_dimensions[1],
961
1072
  self.cutout_dimensions[2] : self.cutout_dimensions[3],
962
- ] * 10 ** ((hdul[0].header["ZP"] - 25) / 2.5)
1073
+ ] * 10 ** ((zp - 25) / 2.5)
963
1074
 
964
1075
  self.rgb_stretched = make_lupton_rgb(
965
1076
  self.rgb_data[0],
966
1077
  self.rgb_data[1],
967
1078
  self.rgb_data[2],
968
- stretch=0.1, # Q=10
1079
+ stretch=0.2,
969
1080
  )
970
1081
  try:
971
1082
  self.plotted_components["rgb_img"].set_data(self.rgb_stretched)
@@ -1192,7 +1303,13 @@ class RedshiftPlotFrame(ctk.CTkFrame):
1192
1303
  Path(self._root().config["files"]["extractions_dir"])
1193
1304
  .expanduser()
1194
1305
  .resolve()
1195
- ).glob(f"*{self._root().seg_id:0>{pad}}.full.fits")
1306
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.full.fits")
1307
+ ] + [
1308
+ *(
1309
+ Path(self._root().config["files"]["extractions_dir"])
1310
+ .expanduser()
1311
+ .resolve()
1312
+ ).glob(f"**/*{self._root().seg_id:0>{pad}}.maps.fits")
1196
1313
  ]
1197
1314
  if len(self.fits_path) == 0:
1198
1315
  print("Full extraction data not found.")
@@ -4,7 +4,6 @@ import customtkinter as ctk
4
4
  import numpy as np
5
5
  from matplotlib import cbook
6
6
  from matplotlib.backend_bases import NavigationToolbar2
7
- from matplotlib.backends._backend_tk import ToolTip
8
7
  from matplotlib.backends.backend_tkagg import NavigationToolbar2Tk
9
8
  from PIL import Image
10
9
 
@@ -54,64 +54,77 @@ class SearchWindow(BaseWindow):
54
54
  lines = re.split("\n", text_input.strip())
55
55
 
56
56
  try:
57
- parts = re.split("\s*[,|;|\s]\s*", lines[0].strip())
57
+ parts = re.split(r"\s*[,|;|\s]\s*", lines[0].strip())
58
58
  except Exception as e:
59
59
  self.warn_input(f"Could not parse input: {e}")
60
60
  return
61
61
 
62
62
  ras = np.empty(len(lines), dtype=object)
63
63
  decs = np.empty_like(ras, dtype=object)
64
-
65
- try:
66
- if len(parts) == 3:
67
- self.ids_arr = np.empty_like(ras, dtype=object)
68
- for i, l in enumerate(lines):
69
- # print(re.split("\s*[,|;|\s]\s*", l.strip()))
70
- self.ids_arr[i], ras[i], decs[i] = re.split(
71
- "\s*[,|;|\s]\s*", l.strip()
72
- )
73
-
74
- elif len(parts) == 2:
75
- for i, l in enumerate(lines):
76
- # print(re.split("\s*[,|;|\s]\s*", l.strip()))
77
- ras[i], decs[i] = re.split("\s*[,|;|\s]\s*", l.strip())
78
- else:
79
- raise ValueError()
80
- except Exception as e:
81
- self.warn_input(
82
- "Could not parse input: input must be either "
83
- "two or three components per line."
64
+ self.ids_arr = np.empty_like(ras, dtype=object)
65
+
66
+ if len(parts) == 1:
67
+ for i, l in enumerate(lines):
68
+ self.ids_arr[i] = re.split(r"\s*[,|;|\s]\s*", l.strip())[0]
69
+ self.ids_arr = np.asarray(self.ids_arr)
70
+ _, _, match_idx = np.intersect1d(
71
+ np.asarray(self.ids_arr), self._root().id_col, return_indices=True
84
72
  )
85
- return
86
73
 
87
- try:
88
- new_coords = SkyCoord(ras.astype(float) * u.deg, decs.astype(float) * u.deg)
89
- except Exception as e:
74
+ else:
75
+ try:
76
+
77
+ if len(parts) == 3:
78
+ # self.ids_arr = np.empty_like(ras, dtype=object)
79
+ for i, l in enumerate(lines):
80
+ # print(re.split("\s*[,|;|\s]\s*", l.strip()))
81
+ self.ids_arr[i], ras[i], decs[i] = re.split(
82
+ r"\s*[,|;|\s]\s*", l.strip()
83
+ )
84
+
85
+ elif len(parts) == 2:
86
+ for i, l in enumerate(lines):
87
+ # print(re.split("\s*[,|;|\s]\s*", l.strip()))
88
+ ras[i], decs[i] = re.split(r"\s*[,|;|\s]\s*", l.strip())
89
+ else:
90
+ raise ValueError()
91
+ except Exception as e:
92
+ self.warn_input(
93
+ "Could not parse input: input must be either "
94
+ "two or three components per line."
95
+ )
96
+ return
97
+
90
98
  try:
91
- new_coords = SkyCoord(ras, decs)
99
+ new_coords = SkyCoord(
100
+ ras.astype(float) * u.deg, decs.astype(float) * u.deg
101
+ )
92
102
  except Exception as e:
93
103
  try:
94
- new_coords = SkyCoord(ras, decs, unit=(u.hourangle, u.deg))
104
+ new_coords = SkyCoord(ras, decs)
95
105
  except Exception as e:
96
- self.warn_input(f"Could not parse input coordinates: {e}")
97
- return
98
-
99
- sky_match_idx, dist, _ = new_coords.match_to_catalog_sky(
100
- self._root().sky_coords
101
- )
106
+ try:
107
+ new_coords = SkyCoord(ras, decs, unit=(u.hourangle, u.deg))
108
+ except Exception as e:
109
+ self.warn_input(f"Could not parse input coordinates: {e}")
110
+ return
111
+
112
+ sky_match_idx, dist, _ = new_coords.match_to_catalog_sky(
113
+ self._root().sky_coords
114
+ )
102
115
 
103
- sky_match_idx = sky_match_idx[
104
- dist <= float(self.search_radius.get()) * u.arcsec
105
- ]
106
- if hasattr(self, "ids_arr"):
107
- self.ids_arr = self.ids_arr[
116
+ sky_match_idx = sky_match_idx[
108
117
  dist <= float(self.search_radius.get()) * u.arcsec
109
118
  ]
110
-
111
- _, unique_idx = np.unique(sky_match_idx, return_index=True)
112
- match_idx = sky_match_idx[np.sort(unique_idx)]
113
- if hasattr(self, "ids_arr"):
114
- self.ids_arr = self.ids_arr[np.sort(unique_idx)]
119
+ if hasattr(self, "ids_arr"):
120
+ self.ids_arr = self.ids_arr[
121
+ dist <= float(self.search_radius.get()) * u.arcsec
122
+ ]
123
+
124
+ _, unique_idx = np.unique(sky_match_idx, return_index=True)
125
+ match_idx = sky_match_idx[np.sort(unique_idx)]
126
+ if hasattr(self, "ids_arr"):
127
+ self.ids_arr = self.ids_arr[np.sort(unique_idx)]
115
128
 
116
129
  if len(match_idx) == 0:
117
130
  self.warn_input("No matches found!")
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyGCG"
7
- version = "0.6.3"
7
+ version = "0.7.2"
8
8
  authors = [
9
9
  { name="Peter Watson", email="peter.watson+pygcg@inaf.it" },
10
10
  ]
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