pyreduce-astro 0.7a4__cp314-cp314-win_amd64.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 (182) hide show
  1. pyreduce/__init__.py +67 -0
  2. pyreduce/__main__.py +322 -0
  3. pyreduce/cli.py +342 -0
  4. pyreduce/clib/Release/_slitfunc_2d.cp311-win_amd64.exp +0 -0
  5. pyreduce/clib/Release/_slitfunc_2d.cp311-win_amd64.lib +0 -0
  6. pyreduce/clib/Release/_slitfunc_2d.cp312-win_amd64.exp +0 -0
  7. pyreduce/clib/Release/_slitfunc_2d.cp312-win_amd64.lib +0 -0
  8. pyreduce/clib/Release/_slitfunc_2d.cp313-win_amd64.exp +0 -0
  9. pyreduce/clib/Release/_slitfunc_2d.cp313-win_amd64.lib +0 -0
  10. pyreduce/clib/Release/_slitfunc_2d.cp314-win_amd64.exp +0 -0
  11. pyreduce/clib/Release/_slitfunc_2d.cp314-win_amd64.lib +0 -0
  12. pyreduce/clib/Release/_slitfunc_2d.obj +0 -0
  13. pyreduce/clib/Release/_slitfunc_bd.cp311-win_amd64.exp +0 -0
  14. pyreduce/clib/Release/_slitfunc_bd.cp311-win_amd64.lib +0 -0
  15. pyreduce/clib/Release/_slitfunc_bd.cp312-win_amd64.exp +0 -0
  16. pyreduce/clib/Release/_slitfunc_bd.cp312-win_amd64.lib +0 -0
  17. pyreduce/clib/Release/_slitfunc_bd.cp313-win_amd64.exp +0 -0
  18. pyreduce/clib/Release/_slitfunc_bd.cp313-win_amd64.lib +0 -0
  19. pyreduce/clib/Release/_slitfunc_bd.cp314-win_amd64.exp +0 -0
  20. pyreduce/clib/Release/_slitfunc_bd.cp314-win_amd64.lib +0 -0
  21. pyreduce/clib/Release/_slitfunc_bd.obj +0 -0
  22. pyreduce/clib/__init__.py +0 -0
  23. pyreduce/clib/_slitfunc_2d.cp311-win_amd64.pyd +0 -0
  24. pyreduce/clib/_slitfunc_2d.cp312-win_amd64.pyd +0 -0
  25. pyreduce/clib/_slitfunc_2d.cp313-win_amd64.pyd +0 -0
  26. pyreduce/clib/_slitfunc_2d.cp314-win_amd64.pyd +0 -0
  27. pyreduce/clib/_slitfunc_bd.cp311-win_amd64.pyd +0 -0
  28. pyreduce/clib/_slitfunc_bd.cp312-win_amd64.pyd +0 -0
  29. pyreduce/clib/_slitfunc_bd.cp313-win_amd64.pyd +0 -0
  30. pyreduce/clib/_slitfunc_bd.cp314-win_amd64.pyd +0 -0
  31. pyreduce/clib/build_extract.py +75 -0
  32. pyreduce/clib/slit_func_2d_xi_zeta_bd.c +1313 -0
  33. pyreduce/clib/slit_func_2d_xi_zeta_bd.h +55 -0
  34. pyreduce/clib/slit_func_bd.c +362 -0
  35. pyreduce/clib/slit_func_bd.h +17 -0
  36. pyreduce/clipnflip.py +147 -0
  37. pyreduce/combine_frames.py +861 -0
  38. pyreduce/configuration.py +191 -0
  39. pyreduce/continuum_normalization.py +329 -0
  40. pyreduce/cwrappers.py +404 -0
  41. pyreduce/datasets.py +238 -0
  42. pyreduce/echelle.py +413 -0
  43. pyreduce/estimate_background_scatter.py +130 -0
  44. pyreduce/extract.py +1362 -0
  45. pyreduce/extraction_width.py +77 -0
  46. pyreduce/instruments/__init__.py +0 -0
  47. pyreduce/instruments/aj.py +9 -0
  48. pyreduce/instruments/aj.yaml +51 -0
  49. pyreduce/instruments/andes.py +102 -0
  50. pyreduce/instruments/andes.yaml +72 -0
  51. pyreduce/instruments/common.py +711 -0
  52. pyreduce/instruments/common.yaml +57 -0
  53. pyreduce/instruments/crires_plus.py +103 -0
  54. pyreduce/instruments/crires_plus.yaml +101 -0
  55. pyreduce/instruments/filters.py +195 -0
  56. pyreduce/instruments/harpn.py +203 -0
  57. pyreduce/instruments/harpn.yaml +140 -0
  58. pyreduce/instruments/harps.py +312 -0
  59. pyreduce/instruments/harps.yaml +144 -0
  60. pyreduce/instruments/instrument_info.py +140 -0
  61. pyreduce/instruments/jwst_miri.py +29 -0
  62. pyreduce/instruments/jwst_miri.yaml +53 -0
  63. pyreduce/instruments/jwst_niriss.py +98 -0
  64. pyreduce/instruments/jwst_niriss.yaml +60 -0
  65. pyreduce/instruments/lick_apf.py +35 -0
  66. pyreduce/instruments/lick_apf.yaml +60 -0
  67. pyreduce/instruments/mcdonald.py +123 -0
  68. pyreduce/instruments/mcdonald.yaml +56 -0
  69. pyreduce/instruments/metis_ifu.py +45 -0
  70. pyreduce/instruments/metis_ifu.yaml +62 -0
  71. pyreduce/instruments/metis_lss.py +45 -0
  72. pyreduce/instruments/metis_lss.yaml +62 -0
  73. pyreduce/instruments/micado.py +45 -0
  74. pyreduce/instruments/micado.yaml +62 -0
  75. pyreduce/instruments/models.py +257 -0
  76. pyreduce/instruments/neid.py +156 -0
  77. pyreduce/instruments/neid.yaml +61 -0
  78. pyreduce/instruments/nirspec.py +215 -0
  79. pyreduce/instruments/nirspec.yaml +63 -0
  80. pyreduce/instruments/nte.py +42 -0
  81. pyreduce/instruments/nte.yaml +55 -0
  82. pyreduce/instruments/uves.py +46 -0
  83. pyreduce/instruments/uves.yaml +65 -0
  84. pyreduce/instruments/xshooter.py +39 -0
  85. pyreduce/instruments/xshooter.yaml +63 -0
  86. pyreduce/make_shear.py +607 -0
  87. pyreduce/masks/mask_crires_plus_det1.fits.gz +0 -0
  88. pyreduce/masks/mask_crires_plus_det2.fits.gz +0 -0
  89. pyreduce/masks/mask_crires_plus_det3.fits.gz +0 -0
  90. pyreduce/masks/mask_ctio_chiron.fits.gz +0 -0
  91. pyreduce/masks/mask_elodie.fits.gz +0 -0
  92. pyreduce/masks/mask_feros3.fits.gz +0 -0
  93. pyreduce/masks/mask_flames_giraffe.fits.gz +0 -0
  94. pyreduce/masks/mask_harps_blue.fits.gz +0 -0
  95. pyreduce/masks/mask_harps_red.fits.gz +0 -0
  96. pyreduce/masks/mask_hds_blue.fits.gz +0 -0
  97. pyreduce/masks/mask_hds_red.fits.gz +0 -0
  98. pyreduce/masks/mask_het_hrs_2x5.fits.gz +0 -0
  99. pyreduce/masks/mask_jwst_miri_lrs_slitless.fits.gz +0 -0
  100. pyreduce/masks/mask_jwst_niriss_gr700xd.fits.gz +0 -0
  101. pyreduce/masks/mask_lick_apf_.fits.gz +0 -0
  102. pyreduce/masks/mask_mcdonald.fits.gz +0 -0
  103. pyreduce/masks/mask_nes.fits.gz +0 -0
  104. pyreduce/masks/mask_nirspec_nirspec.fits.gz +0 -0
  105. pyreduce/masks/mask_sarg.fits.gz +0 -0
  106. pyreduce/masks/mask_sarg_2x2a.fits.gz +0 -0
  107. pyreduce/masks/mask_sarg_2x2b.fits.gz +0 -0
  108. pyreduce/masks/mask_subaru_hds_red.fits.gz +0 -0
  109. pyreduce/masks/mask_uves_blue.fits.gz +0 -0
  110. pyreduce/masks/mask_uves_blue_binned_2_2.fits.gz +0 -0
  111. pyreduce/masks/mask_uves_middle.fits.gz +0 -0
  112. pyreduce/masks/mask_uves_middle_2x2_split.fits.gz +0 -0
  113. pyreduce/masks/mask_uves_middle_binned_2_2.fits.gz +0 -0
  114. pyreduce/masks/mask_uves_red.fits.gz +0 -0
  115. pyreduce/masks/mask_uves_red_2x2.fits.gz +0 -0
  116. pyreduce/masks/mask_uves_red_2x2_split.fits.gz +0 -0
  117. pyreduce/masks/mask_uves_red_binned_2_2.fits.gz +0 -0
  118. pyreduce/masks/mask_xshooter_nir.fits.gz +0 -0
  119. pyreduce/pipeline.py +619 -0
  120. pyreduce/rectify.py +138 -0
  121. pyreduce/reduce.py +2065 -0
  122. pyreduce/settings/settings_AJ.json +19 -0
  123. pyreduce/settings/settings_ANDES.json +89 -0
  124. pyreduce/settings/settings_CRIRES_PLUS.json +89 -0
  125. pyreduce/settings/settings_HARPN.json +73 -0
  126. pyreduce/settings/settings_HARPS.json +69 -0
  127. pyreduce/settings/settings_JWST_MIRI.json +55 -0
  128. pyreduce/settings/settings_JWST_NIRISS.json +55 -0
  129. pyreduce/settings/settings_LICK_APF.json +62 -0
  130. pyreduce/settings/settings_MCDONALD.json +58 -0
  131. pyreduce/settings/settings_METIS_IFU.json +77 -0
  132. pyreduce/settings/settings_METIS_LSS.json +77 -0
  133. pyreduce/settings/settings_MICADO.json +78 -0
  134. pyreduce/settings/settings_NEID.json +73 -0
  135. pyreduce/settings/settings_NIRSPEC.json +58 -0
  136. pyreduce/settings/settings_NTE.json +60 -0
  137. pyreduce/settings/settings_UVES.json +54 -0
  138. pyreduce/settings/settings_XSHOOTER.json +78 -0
  139. pyreduce/settings/settings_pyreduce.json +184 -0
  140. pyreduce/settings/settings_schema.json +850 -0
  141. pyreduce/tools/__init__.py +0 -0
  142. pyreduce/tools/combine.py +117 -0
  143. pyreduce/trace.py +979 -0
  144. pyreduce/util.py +1366 -0
  145. pyreduce/wavecal/MICADO_HK_3arcsec_chip5.npz +0 -0
  146. pyreduce/wavecal/atlas/thar.fits +4946 -13
  147. pyreduce/wavecal/atlas/thar_list.txt +4172 -0
  148. pyreduce/wavecal/atlas/une.fits +0 -0
  149. pyreduce/wavecal/convert.py +38 -0
  150. pyreduce/wavecal/crires_plus_J1228_Open_det1.npz +0 -0
  151. pyreduce/wavecal/crires_plus_J1228_Open_det2.npz +0 -0
  152. pyreduce/wavecal/crires_plus_J1228_Open_det3.npz +0 -0
  153. pyreduce/wavecal/harpn_harpn_2D.npz +0 -0
  154. pyreduce/wavecal/harps_blue_2D.npz +0 -0
  155. pyreduce/wavecal/harps_blue_pol_2D.npz +0 -0
  156. pyreduce/wavecal/harps_red_2D.npz +0 -0
  157. pyreduce/wavecal/harps_red_pol_2D.npz +0 -0
  158. pyreduce/wavecal/mcdonald.npz +0 -0
  159. pyreduce/wavecal/metis_lss_l_2D.npz +0 -0
  160. pyreduce/wavecal/metis_lss_m_2D.npz +0 -0
  161. pyreduce/wavecal/nirspec_K2.npz +0 -0
  162. pyreduce/wavecal/uves_blue_360nm_2D.npz +0 -0
  163. pyreduce/wavecal/uves_blue_390nm_2D.npz +0 -0
  164. pyreduce/wavecal/uves_blue_437nm_2D.npz +0 -0
  165. pyreduce/wavecal/uves_middle_2x2_2D.npz +0 -0
  166. pyreduce/wavecal/uves_middle_565nm_2D.npz +0 -0
  167. pyreduce/wavecal/uves_middle_580nm_2D.npz +0 -0
  168. pyreduce/wavecal/uves_middle_600nm_2D.npz +0 -0
  169. pyreduce/wavecal/uves_middle_665nm_2D.npz +0 -0
  170. pyreduce/wavecal/uves_middle_860nm_2D.npz +0 -0
  171. pyreduce/wavecal/uves_red_580nm_2D.npz +0 -0
  172. pyreduce/wavecal/uves_red_600nm_2D.npz +0 -0
  173. pyreduce/wavecal/uves_red_665nm_2D.npz +0 -0
  174. pyreduce/wavecal/uves_red_760nm_2D.npz +0 -0
  175. pyreduce/wavecal/uves_red_860nm_2D.npz +0 -0
  176. pyreduce/wavecal/xshooter_nir.npz +0 -0
  177. pyreduce/wavelength_calibration.py +1871 -0
  178. pyreduce_astro-0.7a4.dist-info/METADATA +106 -0
  179. pyreduce_astro-0.7a4.dist-info/RECORD +182 -0
  180. pyreduce_astro-0.7a4.dist-info/WHEEL +4 -0
  181. pyreduce_astro-0.7a4.dist-info/entry_points.txt +2 -0
  182. pyreduce_astro-0.7a4.dist-info/licenses/LICENSE +674 -0
@@ -0,0 +1,77 @@
1
+ import logging
2
+
3
+ import numpy as np
4
+
5
+ from .util import make_index
6
+
7
+ logger = logging.getLogger(__name__)
8
+
9
+
10
+ def estimate_extraction_width(
11
+ img, orders, column_range, plot=False
12
+ ): # pragma: no cover
13
+ raise NotImplementedError
14
+ nrow, ncol = img.shape
15
+ nord, _ = orders.shape
16
+ extraction_width = np.zeros((nord, 2), dtype=int)
17
+
18
+ for i in range(nord):
19
+ # first guess, half way to the next order
20
+ # To order above
21
+ if i < nord - 1:
22
+ beg = max(column_range[[i, i + 1], 0])
23
+ end = min(column_range[[i, i + 1], 1])
24
+ x = np.arange(beg, end)
25
+ y = np.polyval(orders[i], x)
26
+ y_above = np.polyval(orders[i + 1], x)
27
+ width_above = int(np.mean(y_above - y) // 2)
28
+
29
+ # To order below
30
+ if i > 0:
31
+ beg = max(column_range[[i - 1, i], 0])
32
+ end = min(column_range[[i - 1, i], 1])
33
+ x = np.arange(beg, end)
34
+ y = np.polyval(orders[i], x)
35
+ y_below = np.polyval(orders[i - 1], x)
36
+ width_below = int(np.mean(y - y_below) // 2)
37
+ else:
38
+ width_below = width_above
39
+
40
+ if i == nord - 1:
41
+ width_above = width_below
42
+
43
+ beg, end = column_range[i]
44
+ x = np.arange(beg, end)
45
+ y = np.polyval(orders[i], x)
46
+
47
+ y_int = y.astype(int)
48
+ y_above = y_int + width_above
49
+ y_below = y_int - width_below
50
+
51
+ if np.ma.any(y_above >= nrow) or np.ma.any(y_below < 0):
52
+ beg, end = np.where((y_above < nrow) & (y_below >= 0))[0][[0, -1]]
53
+
54
+ index = make_index(y_int - width_below, y_int + width_above, beg, end, True)
55
+
56
+ np.ma.sum(img[index], axis=1)
57
+
58
+ # TODO fit rectangular profile
59
+
60
+ # width = int(4 * coef[2])
61
+
62
+ # plt.plot(p, slitf)
63
+ # plt.plot(p, gaussval(p, *coef))
64
+ # plt.vlines([coef[1] - width, coef[1] + width], slitf.min(), slitf.max())
65
+ # plt.show()
66
+
67
+ # width_below = min(width_below, width)
68
+ # width_above = min(width_above, width)
69
+
70
+ # index = make_index(y_int - width_below, y_int + width_above, beg, end, True)
71
+
72
+ # plt.imshow(np.log(img[index]), aspect="auto", origin="lower")
73
+ # plt.show()
74
+ width = 0.5
75
+ extraction_width[i] = [width, width]
76
+
77
+ return extraction_width
File without changes
@@ -0,0 +1,9 @@
1
+ """
2
+ AJ instrument - simulated echelle spectrograph with 75 fibers per order.
3
+ """
4
+
5
+ from .common import Instrument
6
+
7
+
8
+ class AJ(Instrument):
9
+ pass
@@ -0,0 +1,51 @@
1
+ # AJ instrument configuration
2
+ # Simulated echelle spectrograph with 75 fibers per order
3
+
4
+ __instrument__: AJ
5
+ instrument: PYE1
6
+ id_instrument: ".*ZEMAX.*"
7
+ telescope: Simulated
8
+
9
+ date: DATE-OBS
10
+ date_format: fits
11
+
12
+ arms: [ALL]
13
+ extension: 0
14
+ orientation: 0
15
+ transpose: false
16
+
17
+ prescan_x: 0
18
+ overscan_x: 0
19
+ prescan_y: 0
20
+ overscan_y: 0
21
+ naxis_x: NAXIS1
22
+ naxis_y: NAXIS2
23
+
24
+ gain: 1
25
+ readnoise: 0
26
+ dark: 0
27
+ sky: 0
28
+ exposure_time: EXPTIME
29
+
30
+ ra: null
31
+ dec: null
32
+ target: PYE1
33
+
34
+ # File classification
35
+ # For fiber bundle tracing, we need separate even/odd flat files
36
+ # These are matched by filename pattern since header values aren't reliable
37
+ kw_bias: PYE1
38
+ kw_flat: PYE1
39
+ kw_flat_even: FILENAME
40
+ kw_flat_odd: FILENAME
41
+ kw_orders: PYE1
42
+ kw_wave: PYE1
43
+ kw_spec: PYE1
44
+
45
+ id_bias: ".*bias.*"
46
+ id_flat: ".*"
47
+ id_flat_even: ".*even.*"
48
+ id_flat_odd: ".*odd.*"
49
+ id_orders: ".*"
50
+ id_wave: ".*"
51
+ id_spec: ".*"
@@ -0,0 +1,102 @@
1
+ """
2
+ Handles instrument specific info for the HARPS spectrograph
3
+
4
+ Mostly reading data from the header
5
+ """
6
+
7
+ import logging
8
+ import os.path
9
+ import re
10
+ from itertools import product
11
+
12
+ import numpy as np
13
+
14
+ from .common import Instrument
15
+ from .filters import Filter
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+
20
+ class ANDES(Instrument):
21
+ def __init__(self):
22
+ super().__init__()
23
+ self.filters["lamp"] = Filter(self.info["id_lamp"])
24
+ self.filters["band"] = Filter(self.info["id_band"])
25
+ self.filters["decker"] = Filter(self.info["id_decker"])
26
+ self.shared += ["band", "decker"]
27
+
28
+ def add_header_info(self, header, arm, **kwargs):
29
+ """read data from header and add it as REDUCE keyword back to the header"""
30
+ # "Normal" stuff is handled by the general version, specific changes to values happen here
31
+ # alternatively you can implement all of it here, whatever works
32
+ band, decker, detector = self.parse_arm(arm)
33
+ header = super().add_header_info(header, band)
34
+ self.load_info()
35
+
36
+ return header
37
+
38
+ def get_supported_arms(self):
39
+ settings = self.info["settings"]
40
+ deckers = self.info["deckers"]
41
+ detectors = self.info["chips"]
42
+ arms = [
43
+ "_".join([s, d, c]) for s, d, c in product(settings, deckers, detectors)
44
+ ]
45
+ return arms
46
+
47
+ def parse_arm(self, arm):
48
+ pattern = r"([A-Z]+)(_(Open|pos1|pos2))?_det(\d)"
49
+ match = re.match(pattern, arm, flags=re.IGNORECASE)
50
+ if not match:
51
+ raise ValueError(f"Invalid arm format: {arm}")
52
+ band = match.group(1).upper()
53
+ if match.group(3) is not None:
54
+ decker = match.group(3).lower().capitalize()
55
+ else:
56
+ decker = "Open"
57
+ detector = match.group(4)
58
+ return band, decker, detector
59
+
60
+ def get_expected_values(self, target, night, arm):
61
+ expectations = super().get_expected_values(target, night)
62
+ band, decker, detector = self.parse_arm(arm)
63
+
64
+ for key in expectations.keys():
65
+ if key == "bias":
66
+ continue
67
+ expectations[key]["band"] = band
68
+ expectations[key]["decker"] = decker
69
+
70
+ return expectations
71
+
72
+ def get_extension(self, header, arm):
73
+ band, decker, detector = self.parse_arm(arm)
74
+ extension = int(detector)
75
+ return extension
76
+
77
+ def get_wavecal_filename(self, header, arm, **kwargs):
78
+ """Get the filename of the wavelength calibration config file"""
79
+ cwd = os.path.dirname(__file__)
80
+ fname = f"{self.name}_{arm}.npz"
81
+ fname = os.path.join(cwd, "..", "wavecal", fname)
82
+ return fname
83
+
84
+ def get_mask_filename(self, arm, **kwargs):
85
+ i = self.name.lower()
86
+ band, decker, detector = self.parse_arm(arm)
87
+
88
+ fname = f"mask_{i}_det{detector}.fits.gz"
89
+ cwd = os.path.dirname(__file__)
90
+ fname = os.path.join(cwd, "..", "masks", fname)
91
+ return fname
92
+
93
+ def get_wavelength_range(self, header, arm, **kwargs):
94
+ wmin = [header["ESO INS WLEN MIN%i" % i] for i in range(1, 11)]
95
+ wmax = [header["ESO INS WLEN MAX%i" % i] for i in range(1, 11)]
96
+
97
+ wavelength_range = np.array([wmin, wmax]).T
98
+ # Invert the order numbering
99
+ wavelength_range = wavelength_range[::-1]
100
+ # Convert from nm to Angstrom
101
+ wavelength_range *= 10
102
+ return wavelength_range
@@ -0,0 +1,72 @@
1
+ # ANDES instrument configuration
2
+ # Note: red and middle are in the same fits file, with different extensions,
3
+ # i.e. share the same mode identifier, but have different extensions
4
+
5
+ __instrument__: ANDES
6
+ instrument: INSTRUME
7
+ id_instrument: ANDES
8
+ telescope: VLT
9
+
10
+ date: DATE-OBS
11
+ date_format: fits
12
+
13
+ id_mode: "ESO INS MODE"
14
+ id_band: "ESO INS WLEN ID"
15
+ id_decker: "ESO INS OPTI8 ID"
16
+ id_lamp: "ESO INS1 LAMP? ID"
17
+
18
+ arms: [SL, IFU]
19
+ deckers: [Open, pos1, pos2]
20
+ bands: [UBV, RIZ, YJH, K]
21
+ settings: [B, V, R, IZ, Y, J, H, K]
22
+ chips: [det1]
23
+
24
+ extension: CHIP1.INT1
25
+ orientation: 0
26
+ transpose: false
27
+
28
+ prescan_x: 5
29
+ overscan_x: 5
30
+ prescan_y: 5
31
+ overscan_y: 5
32
+ naxis_x: NAXIS1
33
+ naxis_y: NAXIS2
34
+
35
+ gain: "HIERARCH ESO DET CHIP GAIN"
36
+ readnoise: "HIERARCH ESO DET CHIP RON"
37
+ dark: "HIERARCH ESO DET DIT"
38
+ sky: 0
39
+ exposure_time: EXPTIME
40
+
41
+ image_type: OBJECT
42
+ category: "HIERARCH ESO DPR CATG"
43
+ ra: RA
44
+ dec: DEC
45
+ jd: MJD-OBS
46
+ longitude: "HIERARCH ESO TEL GEOLON"
47
+ latitude: "HIERARCH ESO TEL GEOLAT"
48
+ altitude: "HIERARCH ESO TEL GEOELEV"
49
+ target: OBJECT
50
+ observation_type: "ESO DPR TYPE"
51
+
52
+ id_lamp_wavecal: UNe_HCL
53
+ id_lamp_etalon: Etalon_Halogen
54
+
55
+ # File classification keywords and patterns
56
+ kw_bias: "ESO DPR TYPE"
57
+ kw_flat: "ESO DPR TYPE"
58
+ kw_curvature: "ESO DPR TYPE"
59
+ kw_scatter: "ESO DPR TYPE"
60
+ kw_orders: "ESO DPR TYPE"
61
+ kw_wave: "ESO DPR TYPE"
62
+ kw_comb: "ESO DPR TYPE"
63
+ kw_spec: "ESO DPR TYPE"
64
+
65
+ id_bias: DARK
66
+ id_flat: FLAT
67
+ id_orders: FLAT
68
+ id_curvature: "WAVE,FPET"
69
+ id_scatter: FLAT
70
+ id_wave: "WAVE,UNE"
71
+ id_comb: "WAVE,FPET"
72
+ id_spec: "STAR,*,*"