dkist-processing-common 11.7.0rc2__py3-none-any.whl → 11.7.1rc1__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.
Files changed (29) hide show
  1. changelog/271.misc.rst +1 -0
  2. dkist_processing_common/models/constants.py +21 -357
  3. dkist_processing_common/models/fits_access.py +25 -16
  4. dkist_processing_common/parsers/experiment_id_bud.py +4 -8
  5. dkist_processing_common/parsers/id_bud.py +19 -35
  6. dkist_processing_common/parsers/l0_fits_access.py +3 -3
  7. dkist_processing_common/parsers/l1_fits_access.py +21 -47
  8. dkist_processing_common/parsers/near_bud.py +4 -4
  9. dkist_processing_common/parsers/proposal_id_bud.py +5 -11
  10. dkist_processing_common/parsers/single_value_single_key_flower.py +1 -0
  11. dkist_processing_common/parsers/time.py +27 -141
  12. dkist_processing_common/tasks/mixin/quality/_metrics.py +4 -6
  13. dkist_processing_common/tasks/parse_l0_input_data.py +1 -249
  14. dkist_processing_common/tests/test_fits_access.py +44 -19
  15. dkist_processing_common/tests/test_parse_l0_input_data.py +5 -39
  16. dkist_processing_common/tests/test_quality_mixin.py +11 -3
  17. dkist_processing_common/tests/test_stems.py +10 -127
  18. dkist_processing_common/tests/test_task_parsing.py +6 -6
  19. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/METADATA +2 -2
  20. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/RECORD +22 -28
  21. changelog/267.feature.1.rst +0 -1
  22. changelog/267.feature.2.rst +0 -1
  23. changelog/267.feature.rst +0 -1
  24. changelog/267.misc.rst +0 -1
  25. changelog/267.removal.1.rst +0 -2
  26. changelog/267.removal.rst +0 -1
  27. dkist_processing_common/parsers/average_bud.py +0 -48
  28. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/WHEEL +0 -0
  29. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/top_level.txt +0 -0
changelog/271.misc.rst ADDED
@@ -0,0 +1 @@
1
+ Move `solar-wavelength-calibration` dep to 2.0.0 and make use of new helper properties in that release.
@@ -6,7 +6,6 @@ accessing the database (tab completion, etc.)
6
6
  """
7
7
 
8
8
  from enum import StrEnum
9
- from enum import unique
10
9
  from string import ascii_uppercase
11
10
 
12
11
  from sqids import Sqids
@@ -14,7 +13,6 @@ from sqids import Sqids
14
13
  from dkist_processing_common._util.constants import ConstantsDb
15
14
 
16
15
 
17
- @unique
18
16
  class BudName(StrEnum):
19
17
  """Controlled list of names for constant stems (buds)."""
20
18
 
@@ -35,62 +33,6 @@ class BudName(StrEnum):
35
33
  dark_exposure_times = "DARK_EXPOSURE_TIMES"
36
34
  dark_readout_exp_times = "DARK_READOUT_EXP_TIMES"
37
35
  wavelength = "WAVELENGTH"
38
- camera_id = "CAMERA_ID"
39
- camera_name = "CAMERA_NAME"
40
- camera_bit_depth = "CAMERA_BIT_DEPTH"
41
- hardware_binning_x = "HARDWARE_BINNING_X"
42
- hardware_binning_y = "HARDWARE_BINNING_Y"
43
- software_binning_x = "SOFTWARE_BINNING_X"
44
- software_binning_y = "SOFTWARE_BINNING_Y"
45
- hls_version = "HLS_VERSION"
46
- # Multi-task buds start here:
47
- dark_observing_program_execution_id = "DARK_OBSERVING_PROGRAM_EXECUTION_ID"
48
- solar_gain_observing_program_execution_id = "SOLAR_GAIN_OBSERVING_PROGRAM_EXECUTION_ID"
49
- polcal_observing_program_execution_id = "POLCAL_OBSERVING_PROGRAM_EXECUTION_ID"
50
- dark_date_begin = "DARK_DATE_BEGIN"
51
- solar_gain_date_begin = "SOLAR_GAIN_DATE_BEGIN"
52
- polcal_date_begin = "POLCAL_DATE_BEGIN"
53
- dark_date_end = "DARK_DATE_END"
54
- solar_gain_date_end = "SOLAR_GAIN_DATE_END"
55
- polcal_date_end = "POLCAL_DATE_END"
56
- dark_num_raw_frames_per_fpa = "DARK_NUM_RAW_FRAMES_PER_FPA"
57
- solar_gain_num_raw_frames_per_fpa = "SOLAR_GAIN_NUM_RAW_FRAMES_PER_FPA"
58
- polcal_num_raw_frames_per_fpa = "POLCAL_NUM_RAW_FRAMES_PER_FPA"
59
- dark_telescope_tracking_mode = "DARK_TELESCOPE_TRACKING_MODE"
60
- solar_gain_telescope_tracking_mode = "SOLAR_GAIN_TELESCOPE_TRACKING_MODE"
61
- polcal_telescope_tracking_mode = "POLCAL_TELESCOPE_TRACKING_MODE"
62
- dark_coude_table_tracking_mode = "DARK_COUDE_TABLE_TRACKING_MODE"
63
- solar_gain_coude_table_tracking_mode = "SOLAR_GAIN_COUDE_TABLE_TRACKING_MODE"
64
- polcal_coude_table_tracking_mode = "POLCAL_COUDE_TABLE_TRACKING_MODE"
65
- dark_telescope_scanning_mode = "DARK_TELESCOPE_SCANNING_MODE"
66
- solar_gain_telescope_scanning_mode = "SOLAR_GAIN_TELESCOPE_SCANNING_MODE"
67
- polcal_telescope_scanning_mode = "POLCAL_TELESCOPE_SCANNING_MODE"
68
- dark_average_light_level = "DARK_AVERAGE_LIGHT_LEVEL"
69
- solar_gain_average_light_level = "SOLAR_GAIN_AVERAGE_LIGHT_LEVEL"
70
- polcal_average_light_level = "POLCAL_AVERAGE_LIGHT_LEVEL"
71
- dark_average_telescope_elevation = "DARK_AVERAGE_TELESCOPE_ELEVATION"
72
- solar_gain_average_telescope_elevation = "SOLAR_GAIN_AVERAGE_TELESCOPE_ELEVATION"
73
- polcal_average_telescope_elevation = "POLCAL_AVERAGE_TELESCOPE_ELEVATION"
74
- dark_average_coude_table_angle = "DARK_AVERAGE_COUDE_TABLE_ANGLE"
75
- solar_gain_average_coude_table_angle = "SOLAR_GAIN_AVERAGE_COUDE_TABLE_ANGLE"
76
- polcal_average_coude_table_angle = "POLCAL_AVERAGE_COUDE_TABLE_ANGLE"
77
- dark_average_telescope_azimuth = "DARK_AVERAGE_TELESCOPE_AZIMUTH"
78
- solar_gain_average_telescope_azimuth = "SOLAR_GAIN_AVERAGE_TELESCOPE_AZIMUTH"
79
- polcal_average_telescope_azimuth = "POLCAL_AVERAGE_TELESCOPE_AZIMUTH"
80
- dark_gos_level3_status = "DARK_GOS_LEVEL3_STATUS"
81
- solar_gain_gos_level3_status = "SOLAR_GAIN_GOS_LEVEL3_STATUS"
82
- dark_gos_level3_lamp_status = "DARK_GOS_LEVEL3_LAMP_STATUS"
83
- solar_gain_gos_level3_lamp_status = "SOLAR_GAIN_GOS_LEVEL3_LAMP_STATUS"
84
- dark_gos_polarizer_status = "DARK_GOS_POLARIZER_STATUS"
85
- solar_gain_gos_polarizer_status = "SOLAR_GAIN_GOS_POLARIZER_STATUS"
86
- dark_gos_polarizer_angle = "DARK_GOS_POLARIZER_ANGLE"
87
- solar_gain_gos_polarizer_angle = "SOLAR_GAIN_GOS_POLARIZER_ANGLE"
88
- dark_gos_retarder_status = "DARK_GOS_RETARDER_STATUS"
89
- solar_gain_gos_retarder_status = "SOLAR_GAIN_GOS_RETARDER_STATUS"
90
- dark_gos_retarder_angle = "DARK_GOS_RETARDER_ANGLE"
91
- solar_gain_gos_retarder_angle = "SOLAR_GAIN_GOS_RETARDER_ANGLE"
92
- dark_gos_level0_status = "DARK_GOS_LEVEL0_STATUS"
93
- solar_gain_gos_level0_status = "SOLAR_GAIN_GOS_LEVEL0_STATUS"
94
36
 
95
37
 
96
38
  class ConstantsBase:
@@ -145,11 +87,11 @@ class ConstantsBase:
145
87
 
146
88
  @property
147
89
  def dataset_id(self) -> str:
148
- """Define the dataset id constant."""
90
+ """Define the dataset_id constant."""
149
91
  return Sqids(min_length=6, alphabet=ascii_uppercase).encode([self._recipe_run_id])
150
92
 
151
93
  @property
152
- def stokes_params(self) -> list[str]:
94
+ def stokes_params(self) -> [str]:
153
95
  """Return the list of stokes parameter names."""
154
96
  return ["I", "Q", "U", "V"]
155
97
 
@@ -159,41 +101,45 @@ class ConstantsBase:
159
101
  return self._db_dict[BudName.instrument]
160
102
 
161
103
  @property
162
- def num_cs_steps(self) -> int:
104
+ def num_cs_steps(self):
163
105
  """Get the number of calibration sequence steps."""
164
106
  return self._db_dict[BudName.num_cs_steps]
165
107
 
166
108
  @property
167
- def num_modstates(self) -> int:
109
+ def num_modstates(self):
168
110
  """Get the number of modulation states."""
169
111
  return self._db_dict[BudName.num_modstates]
170
112
 
171
113
  @property
172
- def retarder_name(self) -> str:
114
+ def retarder_name(self):
173
115
  """Get the retarder name."""
174
116
  return self._db_dict[BudName.retarder_name]
175
117
 
176
118
  @property
177
119
  def proposal_id(self) -> str:
178
- """Get the proposal ID constant."""
120
+ """Get the proposal_id constant."""
179
121
  return self._db_dict[BudName.proposal_id]
180
122
 
181
123
  @property
182
- def contributing_proposal_ids(self) -> list[str]:
124
+ def contributing_proposal_ids(self) -> [str]:
183
125
  """Return the list of contributing proposal IDs."""
184
126
  proposal_ids = self._db_dict[BudName.contributing_proposal_ids]
185
- return list(proposal_ids)
127
+ if isinstance(proposal_ids, str):
128
+ return [proposal_ids]
129
+ return proposal_ids
186
130
 
187
131
  @property
188
132
  def experiment_id(self) -> str:
189
- """Get the experiment ID constant."""
133
+ """Get the experiment_id constant."""
190
134
  return self._db_dict[BudName.experiment_id]
191
135
 
192
136
  @property
193
- def contributing_experiment_ids(self) -> list[str]:
137
+ def contributing_experiment_ids(self) -> [str]:
194
138
  """Return the list of contributing experiment IDs."""
195
139
  experiment_ids = self._db_dict[BudName.contributing_experiment_ids]
196
- return list(experiment_ids)
140
+ if isinstance(experiment_ids, str):
141
+ return [experiment_ids]
142
+ return experiment_ids
197
143
 
198
144
  @property
199
145
  def obs_ip_start_time(self) -> str:
@@ -202,7 +148,7 @@ class ConstantsBase:
202
148
 
203
149
  @property
204
150
  def average_cadence(self) -> float:
205
- """Get the average cadence constant."""
151
+ """Get the average_cadence constant."""
206
152
  return self._db_dict[BudName.average_cadence]
207
153
 
208
154
  @property
@@ -226,298 +172,16 @@ class ConstantsBase:
226
172
  return self._db_dict[BudName.num_dsps_repeats]
227
173
 
228
174
  @property
229
- def dark_exposure_times(self) -> list[float]:
175
+ def dark_exposure_times(self) -> [float]:
230
176
  """Get a list of exposure times used in the dark calibration."""
231
- exposure_times = self._db_dict[BudName.dark_exposure_times]
232
- return list(exposure_times)
177
+ return self._db_dict[BudName.dark_exposure_times]
233
178
 
234
179
  @property
235
- def dark_readout_exp_times(self) -> list[float]:
236
- """Get a list of readout exp times for all dark frames."""
237
- readout_times = self._db_dict[BudName.dark_readout_exp_times]
238
- return list(readout_times)
180
+ def dark_readout_exp_times(self) -> [float]:
181
+ """Get a list of readout exp times for all DARK frames."""
182
+ return self._db_dict[BudName.dark_readout_exp_times]
239
183
 
240
184
  @property
241
185
  def wavelength(self) -> float:
242
186
  """Wavelength."""
243
187
  return self._db_dict[BudName.wavelength]
244
-
245
- @property
246
- def camera_id(self) -> str:
247
- """Return the camera ID constant."""
248
- return self._db_dict[BudName.camera_id]
249
-
250
- @property
251
- def camera_name(self) -> str:
252
- """Return the camera name for humans constant."""
253
- return self._db_dict[BudName.camera_name]
254
-
255
- @property
256
- def camera_bit_depth(self) -> int:
257
- """Return the camera bit depth constant."""
258
- return self._db_dict[BudName.camera_bit_depth]
259
-
260
- @property
261
- def hardware_binning_x(self) -> int:
262
- """Return the x-direction hardware binning constant."""
263
- return self._db_dict[BudName.hardware_binning_x]
264
-
265
- @property
266
- def hardware_binning_y(self) -> int:
267
- """Return the y-direction hardware binning constant."""
268
- return self._db_dict[BudName.hardware_binning_y]
269
-
270
- @property
271
- def software_binning_x(self) -> int:
272
- """Return the x-direction software binning constant."""
273
- return self._db_dict[BudName.software_binning_x]
274
-
275
- @property
276
- def software_binning_y(self) -> int:
277
- """Return the y-direction software binning constant."""
278
- return self._db_dict[BudName.software_binning_y]
279
-
280
- @property
281
- def hls_version(self) -> str:
282
- """Return the High-Level Software version."""
283
- return self._db_dict[BudName.hls_version]
284
-
285
- # Multi-task constants start here:
286
-
287
- @property
288
- def dark_observing_program_execution_id(self) -> list[str]:
289
- """Return the observing program execution id constant for the dark task."""
290
- observing_programs = self._db_dict[BudName.dark_observing_program_execution_id]
291
- return list(observing_programs)
292
-
293
- @property
294
- def solar_gain_observing_program_execution_id(self) -> list[str]:
295
- """Return the observing program execution id constant for the solar_gain task."""
296
- observing_programs = self._db_dict[BudName.solar_gain_observing_program_execution_id]
297
- return list(observing_programs)
298
-
299
- @property
300
- def polcal_observing_program_execution_id(self) -> list[str]:
301
- """Return the observing program execution id constant."""
302
- observing_programs = self._db_dict[BudName.polcal_observing_program_execution_id]
303
- return list(observing_programs)
304
-
305
- @property
306
- def dark_date_begin(self) -> str:
307
- """Return the date begin header constant for the dark task."""
308
- return self._db_dict[BudName.dark_date_begin]
309
-
310
- @property
311
- def solar_gain_date_begin(self) -> str:
312
- """Return the date begin header constant for the solar gain task."""
313
- return self._db_dict[BudName.solar_gain_date_begin]
314
-
315
- @property
316
- def polcal_date_begin(self) -> str:
317
- """Return the time obs header constant for the polcal task."""
318
- return self._db_dict[BudName.polcal_date_begin]
319
-
320
- @property
321
- def dark_date_end(self) -> str:
322
- """Return the date end constant for the dark task."""
323
- return self._db_dict[BudName.dark_date_end]
324
-
325
- @property
326
- def solar_gain_date_end(self) -> str:
327
- """Return the date end constant for the solar gain task."""
328
- return self._db_dict[BudName.solar_gain_date_end]
329
-
330
- @property
331
- def polcal_date_end(self) -> str:
332
- """Return the date end constant for the polcal task."""
333
- return self._db_dict[BudName.polcal_date_end]
334
-
335
- @property
336
- def dark_num_raw_frames_per_fpa(self) -> int:
337
- """Return the number of raw frames per fpa constant for the dark task."""
338
- return self._db_dict[BudName.dark_num_raw_frames_per_fpa]
339
-
340
- @property
341
- def solar_gain_num_raw_frames_per_fpa(self) -> int:
342
- """Return the number of raw frames per fpa constant for the solar gain task."""
343
- return self._db_dict[BudName.solar_gain_num_raw_frames_per_fpa]
344
-
345
- @property
346
- def polcal_num_raw_frames_per_fpa(self) -> int:
347
- """Return the num raw frames per fpa constant for the polcal task."""
348
- return self._db_dict[BudName.polcal_num_raw_frames_per_fpa]
349
-
350
- @property
351
- def dark_telescope_tracking_mode(self) -> str:
352
- """Return the telescope tracking mode constant for the dark task."""
353
- return self._db_dict[BudName.dark_telescope_tracking_mode]
354
-
355
- @property
356
- def solar_gain_telescope_tracking_mode(self) -> str:
357
- """Return the telescope tracking mode constant for the solar gain task."""
358
- return self._db_dict[BudName.solar_gain_telescope_tracking_mode]
359
-
360
- @property
361
- def polcal_telescope_tracking_mode(self) -> str:
362
- """Return the telescope tracking mode constant for the polcal task."""
363
- return self._db_dict[BudName.polcal_telescope_tracking_mode]
364
-
365
- @property
366
- def dark_coude_table_tracking_mode(self) -> str:
367
- """Return the coude table tracking mode constant for the dark task."""
368
- return self._db_dict[BudName.dark_coude_table_tracking_mode]
369
-
370
- @property
371
- def solar_gain_coude_table_tracking_mode(self) -> str:
372
- """Return the coude table tracking mode constant for the solar gain task."""
373
- return self._db_dict[BudName.solar_gain_coude_table_tracking_mode]
374
-
375
- @property
376
- def polcal_coude_table_tracking_mode(self) -> str:
377
- """Return the coude table tracking mode constant for the polcal task."""
378
- return self._db_dict[BudName.polcal_coude_table_tracking_mode]
379
-
380
- @property
381
- def dark_telescope_scanning_mode(self) -> str:
382
- """Return the telescope scanning mode constant for the dark task."""
383
- return self._db_dict[BudName.dark_telescope_scanning_mode]
384
-
385
- @property
386
- def solar_gain_telescope_scanning_mode(self) -> str:
387
- """Return the telescope scanning mode constant for the solar gain task."""
388
- return self._db_dict[BudName.solar_gain_telescope_scanning_mode]
389
-
390
- @property
391
- def polcal_telescope_scanning_mode(self) -> str:
392
- """Return the telescope scanning mode constant for the polcal task."""
393
- return self._db_dict[BudName.polcal_telescope_scanning_mode]
394
-
395
- @property
396
- def dark_average_light_level(self) -> float:
397
- """Return the average light level constant for the dark task."""
398
- return self._db_dict[BudName.dark_average_light_level]
399
-
400
- @property
401
- def solar_gain_average_light_level(self) -> float:
402
- """Return the average light level constant for the solar gain task."""
403
- return self._db_dict[BudName.solar_gain_average_light_level]
404
-
405
- @property
406
- def polcal_average_light_level(self) -> float:
407
- """Return the average light level constant for the polcal task."""
408
- return self._db_dict[BudName.polcal_average_light_level]
409
-
410
- @property
411
- def dark_average_telescope_elevation(self) -> float:
412
- """Return the average telescope elevation constant for the dark task."""
413
- return self._db_dict[BudName.dark_average_telescope_elevation]
414
-
415
- @property
416
- def solar_gain_average_telescope_elevation(self) -> float:
417
- """Return the average telescope elevation constant for the solar gain task."""
418
- return self._db_dict[BudName.solar_gain_average_telescope_elevation]
419
-
420
- @property
421
- def polcal_average_telescope_elevation(self) -> float:
422
- """Return the average telescope elevation constant for the polcal task."""
423
- return self._db_dict[BudName.polcal_average_telescope_elevation]
424
-
425
- @property
426
- def dark_average_coude_table_angle(self) -> float:
427
- """Return the average coude table angle constant for the dark task."""
428
- return self._db_dict[BudName.dark_average_coude_table_angle]
429
-
430
- @property
431
- def solar_gain_average_coude_table_angle(self) -> float:
432
- """Return the average coude table angle constant for the solar gain task."""
433
- return self._db_dict[BudName.solar_gain_average_coude_table_angle]
434
-
435
- @property
436
- def polcal_average_coude_table_angle(self) -> float:
437
- """Return the average coude table angle constant for the polcal task."""
438
- return self._db_dict[BudName.polcal_average_coude_table_angle]
439
-
440
- @property
441
- def dark_average_telescope_azimuth(self) -> float:
442
- """Return the average telescope azimuth constant for the dark task."""
443
- return self._db_dict[BudName.dark_average_telescope_azimuth]
444
-
445
- @property
446
- def solar_gain_average_telescope_azimuth(self) -> float:
447
- """Return the average telescope azimuth constant for the solar gain task."""
448
- return self._db_dict[BudName.solar_gain_average_telescope_azimuth]
449
-
450
- @property
451
- def polcal_average_telescope_azimuth(self) -> float:
452
- """Return the average telescope azimuth constant for the polcal task."""
453
- return self._db_dict[BudName.polcal_average_telescope_azimuth]
454
-
455
- @property
456
- def dark_gos_level3_status(self) -> str:
457
- """Return the gos level3 status constant for the dark task."""
458
- return self._db_dict[BudName.dark_gos_level3_status]
459
-
460
- @property
461
- def solar_gain_gos_level3_status(self) -> str:
462
- """Return the gos level3 status constant for the solar gain task."""
463
- return self._db_dict[BudName.solar_gain_gos_level3_status]
464
-
465
- @property
466
- def dark_gos_level3_lamp_status(self) -> str:
467
- """Return the gos level3 lamp status constant for the dark task."""
468
- return self._db_dict[BudName.dark_gos_level3_lamp_status]
469
-
470
- @property
471
- def solar_gain_gos_level3_lamp_status(self) -> str:
472
- """Return the gos level3 lamp status constant for the solar gain task."""
473
- return self._db_dict[BudName.solar_gain_gos_level3_lamp_status]
474
-
475
- @property
476
- def dark_gos_polarizer_status(self) -> str:
477
- """Return the gos polarizer status constant for the dark task."""
478
- return self._db_dict[BudName.dark_gos_polarizer_status]
479
-
480
- @property
481
- def solar_gain_gos_polarizer_status(self) -> str:
482
- """Return the gos polarizer status constant for the solar gain task."""
483
- return self._db_dict[BudName.solar_gain_gos_polarizer_status]
484
-
485
- @property
486
- def dark_gos_polarizer_angle(self) -> float:
487
- """Return the gos polarizer angle constant for the dark task."""
488
- return self._db_dict[BudName.dark_gos_polarizer_angle]
489
-
490
- @property
491
- def solar_gain_gos_polarizer_angle(self) -> float:
492
- """Return the gos polarizer angle constant for the solar gain task."""
493
- return self._db_dict[BudName.solar_gain_gos_polarizer_angle]
494
-
495
- @property
496
- def dark_gos_retarder_status(self) -> str:
497
- """Return the gos retarder status constant for the dark task."""
498
- return self._db_dict[BudName.dark_gos_retarder_status]
499
-
500
- @property
501
- def solar_gain_gos_retarder_status(self) -> str:
502
- """Return the gos retarder status constant for the solar gain task."""
503
- return self._db_dict[BudName.solar_gain_gos_retarder_status]
504
-
505
- @property
506
- def dark_gos_retarder_angle(self) -> float:
507
- """Return the gos retarder angle constant for the dark task."""
508
- return self._db_dict[BudName.dark_gos_retarder_angle]
509
-
510
- @property
511
- def solar_gain_gos_retarder_angle(self) -> float:
512
- """Return the gos retarder angle constant for the solar gain task."""
513
- return self._db_dict[BudName.solar_gain_gos_retarder_angle]
514
-
515
- @property
516
- def dark_gos_level0_status(self) -> str:
517
- """Return the gos level0 status constant for the dark task."""
518
- return self._db_dict[BudName.dark_gos_level0_status]
519
-
520
- @property
521
- def solar_gain_gos_level0_status(self) -> str:
522
- """Return the gos level0 status constant for the solar gain task."""
523
- return self._db_dict[BudName.solar_gain_gos_level0_status]
@@ -3,16 +3,15 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from enum import StrEnum
6
- from enum import unique
7
6
  from pathlib import Path
7
+ from typing import Any
8
8
 
9
9
  import numpy as np
10
10
  from astropy.io import fits
11
11
 
12
- HEADER_KEY_NOT_FOUND = "HEADER_KEY_NOT_FOUND"
12
+ NOT_FOUND_MESSAGE = "_HEADER_KEYWORD_NOT_FOUND"
13
13
 
14
14
 
15
- @unique
16
15
  class MetadataKey(StrEnum):
17
16
  """Controlled list of names for FITS metadata header keys."""
18
17
 
@@ -40,19 +39,6 @@ class MetadataKey(StrEnum):
40
39
  fpa_exposure_time_ms = "XPOSURE"
41
40
  sensor_readout_exposure_time_ms = "TEXPOSUR"
42
41
  num_raw_frames_per_fpa = "NSUMEXP"
43
- camera_id = "CAM_ID"
44
- camera_name = "CAMERA"
45
- camera_bit_depth = "BITDEPTH"
46
- hardware_binning_x = "HWBIN1"
47
- hardware_binning_y = "HWBIN2"
48
- software_binning_x = "SWBIN1"
49
- software_binning_y = "SWBIN2"
50
- observing_program_execution_id = "OBSPR_ID"
51
- telescope_tracking_mode = "TELTRACK"
52
- coude_table_tracking_mode = "TTBLTRCK"
53
- telescope_scanning_mode = "TELSCAN"
54
- light_level = "LIGHTLVL"
55
- hls_version = "HLSVERS"
56
42
 
57
43
 
58
44
  class FitsAccessBase:
@@ -82,6 +68,29 @@ class FitsAccessBase:
82
68
  def __repr__(self):
83
69
  return f"{self.__class__.__name__}(hdu={self._hdu!r}, name={self.name!r}, auto_squeeze={self.auto_squeeze})"
84
70
 
71
+ def _set_metadata_key_value(
72
+ self, key: StrEnum, optional: bool = False, default: Any = NOT_FOUND_MESSAGE
73
+ ) -> None:
74
+ """
75
+ Get the header value and assign it as a metadata key name attribute.
76
+
77
+ Parameters
78
+ ----------
79
+ key
80
+ The StrEnum member in attribute_name = fits_keyword structure
81
+ optional
82
+ If the keyword is optional
83
+ default
84
+ Value for the attribute if the key is not found
85
+ """
86
+ if optional:
87
+ if default != NOT_FOUND_MESSAGE:
88
+ setattr(self, key.name, self.header.get(key, default))
89
+ else:
90
+ setattr(self, key.name, self.header.get(key, key + NOT_FOUND_MESSAGE))
91
+ else:
92
+ setattr(self, key.name, self.header[key])
93
+
85
94
  @property
86
95
  def data(self) -> np.ndarray:
87
96
  """
@@ -2,19 +2,16 @@
2
2
 
3
3
  from dkist_processing_common.models.constants import BudName
4
4
  from dkist_processing_common.models.fits_access import MetadataKey
5
- from dkist_processing_common.models.task_name import TaskName
6
5
  from dkist_processing_common.parsers.id_bud import ContributingIdsBud
7
- from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
6
+ from dkist_processing_common.parsers.id_bud import IdBud
8
7
 
9
8
 
10
- class ExperimentIdBud(TaskUniqueBud):
9
+ class ExperimentIdBud(IdBud):
11
10
  """Class to create a Bud for the experiment_id."""
12
11
 
13
12
  def __init__(self):
14
13
  super().__init__(
15
- constant_name=BudName.experiment_id,
16
- metadata_key=MetadataKey.experiment_id,
17
- ip_task_types=TaskName.observe,
14
+ constant_name=BudName.experiment_id, metadata_key=MetadataKey.experiment_id
18
15
  )
19
16
 
20
17
 
@@ -23,6 +20,5 @@ class ContributingExperimentIdsBud(ContributingIdsBud):
23
20
 
24
21
  def __init__(self):
25
22
  super().__init__(
26
- constant_name=BudName.contributing_experiment_ids,
27
- metadata_key=MetadataKey.experiment_id,
23
+ stem_name=BudName.contributing_experiment_ids, metadata_key=MetadataKey.experiment_id
28
24
  )
@@ -1,25 +1,36 @@
1
1
  """Base classes for ID bud parsing."""
2
2
 
3
3
  from enum import StrEnum
4
- from typing import Callable
5
4
  from typing import Type
6
5
 
7
6
  from dkist_processing_common.models.flower_pot import SpilledDirt
8
7
  from dkist_processing_common.models.flower_pot import Stem
8
+ from dkist_processing_common.models.task_name import TaskName
9
9
  from dkist_processing_common.parsers.l0_fits_access import L0FitsAccess
10
- from dkist_processing_common.parsers.task import passthrough_header_ip_task
10
+ from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
11
+
12
+
13
+ class IdBud(TaskUniqueBud):
14
+ """Base class for ID buds."""
15
+
16
+ def __init__(self, constant_name: str, metadata_key: str | StrEnum):
17
+ super().__init__(
18
+ constant_name=constant_name,
19
+ metadata_key=metadata_key,
20
+ ip_task_types=TaskName.observe,
21
+ )
11
22
 
12
23
 
13
24
  class ContributingIdsBud(Stem):
14
25
  """Base class for contributing ID buds."""
15
26
 
16
- def __init__(self, constant_name: str, metadata_key: str | StrEnum):
17
- super().__init__(stem_name=constant_name)
27
+ def __init__(self, stem_name: str, metadata_key: str | StrEnum):
28
+ super().__init__(stem_name=stem_name)
18
29
  if isinstance(metadata_key, StrEnum):
19
30
  metadata_key = metadata_key.name
20
31
  self.metadata_key = metadata_key
21
32
 
22
- def setter(self, fits_obj: L0FitsAccess) -> str:
33
+ def setter(self, fits_obj: L0FitsAccess) -> str | Type[SpilledDirt]:
23
34
  """
24
35
  Set the id for any type of frame.
25
36
 
@@ -33,9 +44,9 @@ class ContributingIdsBud(Stem):
33
44
  """
34
45
  return getattr(fits_obj, self.metadata_key)
35
46
 
36
- def getter(self, key) -> tuple[str, ...]:
47
+ def getter(self, key) -> tuple:
37
48
  """
38
- Get all ids seen for any type of frame.
49
+ Get all ids seen in non observe frames.
39
50
 
40
51
  Parameters
41
52
  ----------
@@ -44,33 +55,6 @@ class ContributingIdsBud(Stem):
44
55
 
45
56
  Returns
46
57
  -------
47
- IDs from all types of frames
58
+ IDs from non observe frames
48
59
  """
49
60
  return tuple(set(self.key_to_petal_dict.values()))
50
-
51
-
52
- class TaskContributingIdsBud(ContributingIdsBud):
53
- """Base class for contributing ID buds for a particular task type."""
54
-
55
- def __init__(
56
- self,
57
- constant_name: str,
58
- metadata_key: str | StrEnum,
59
- ip_task_types: str | list[str],
60
- task_type_parsing_function: Callable = passthrough_header_ip_task,
61
- ):
62
- super().__init__(constant_name=constant_name, metadata_key=metadata_key)
63
-
64
- if isinstance(ip_task_types, str):
65
- ip_task_types = [ip_task_types]
66
- self.ip_task_types = [task.casefold() for task in ip_task_types]
67
- self.parsing_function = task_type_parsing_function
68
-
69
- def setter(self, fits_obj: L0FitsAccess) -> str | Type[SpilledDirt]:
70
- """Ingest an object only if its parsed IP task type matches what's desired."""
71
- task = self.parsing_function(fits_obj)
72
-
73
- if task.casefold() in self.ip_task_types:
74
- return super().setter(fits_obj)
75
-
76
- return SpilledDirt
@@ -27,6 +27,6 @@ class L0FitsAccess(L1FitsAccess):
27
27
  auto_squeeze: bool = True,
28
28
  ):
29
29
  super().__init__(hdu=hdu, name=name, auto_squeeze=auto_squeeze)
30
- self.ip_task_type: str = self.header[MetadataKey.ip_task_type]
31
- self.ip_start_time: str = self.header[MetadataKey.ip_start_time]
32
- self.ip_end_time: str = self.header[MetadataKey.ip_end_time]
30
+ self._set_metadata_key_value(MetadataKey.ip_task_type)
31
+ self._set_metadata_key_value(MetadataKey.ip_start_time)
32
+ self._set_metadata_key_value(MetadataKey.ip_end_time)