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,140 @@
1
+ # HARPN 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__: HARPN
6
+ id_instrument: HARPN
7
+ instrument: INSTRUME
8
+ telescope: TELESCOP
9
+
10
+ date: DATE-OBS
11
+ date_format: fits
12
+
13
+ arms: [HARPN]
14
+ arms_id: [harpn]
15
+ extension: [1]
16
+ id: [[1, 2]]
17
+ orientation: 2
18
+ transpose: true
19
+
20
+ prescan_x: "HIERARCH TNG DET OUT{id[0]} PRSCX"
21
+ overscan_x: "HIERARCH TNG DET OUT{id[0]} OVSCX"
22
+ prescan_y: 0
23
+ overscan_y: 0
24
+ naxis_x: NAXIS1
25
+ naxis_y: NAXIS2
26
+
27
+ gain: "HIERARCH TNG DET OUT{id[0]} GAIN"
28
+ readnoise: "HIERARCH TNG DET OUT{id[0]} RON"
29
+ dark: "HIERARCH TNG INS DET{id[1]} OFFDRK"
30
+ sky: "HIERARCH TNG INS DET{id[1]} OFFSKY"
31
+ exposure_time: EXPTIME
32
+
33
+ image_type: "HIERARCH TNG OBS TARG NAME"
34
+ category: "HIERARCH TNG DPR CATG"
35
+ ra: RA
36
+ dec: DEC
37
+ longitude: GEOLON
38
+ latitude: GEOLAT
39
+ altitude: GEOELEV
40
+ target: OBJECT
41
+ instrument_mode: "HIERARCH TNG INS MODE"
42
+ instrument_mode_alternative: "TNG TPL NAME"
43
+ observation_type: "TNG DPR TYPE"
44
+
45
+ id_fiber_a: "LAMP,DARK,TUN"
46
+ id_fiber_b: "DARK,LAMP,TUN"
47
+
48
+ # File classification keywords and patterns
49
+ kw_bias: "HIERARCH TNG DPR TYPE"
50
+ kw_flat: "HIERARCH TNG DPR TYPE"
51
+ kw_curvature: "HIERARCH TNG DPR TYPE"
52
+ kw_scatter: "HIERARCH TNG DPR TYPE"
53
+ kw_orders: "HIERARCH TNG DPR TYPE"
54
+ kw_wave: "HIERARCH TNG DPR TYPE"
55
+ kw_comb: "HIERARCH TNG DPR TYPE"
56
+ kw_spec: "HIERARCH TNG DPR TYPE"
57
+
58
+ id_bias: "BIAS,BIAS"
59
+ id_flat: "LAMP,LAMP,TUN"
60
+ id_orders: "LAMP,LAMP,TUN"
61
+ id_curvature: "WAVE,WAVE,THAR2"
62
+ id_scatter: "LAMP,LAMP,TUN"
63
+ id_wave: "WAVE,WAVE,THAR2"
64
+ id_comb: "WAVE,WAVE,COMB"
65
+ id_spec: "STAR,*"
66
+
67
+ wavelength_range:
68
+ # HARPN mode
69
+ - - [5245.4, 5304.3]
70
+ - [5200.5, 5259.0]
71
+ - [5156.5, 5214.4]
72
+ - [5113.2, 5170.6]
73
+ - [5070.6, 5127.6]
74
+ - [5028.7, 5085.2]
75
+ - [4987.5, 5043.5]
76
+ - [4946.9, 5002.5]
77
+ - [4907.0, 4962.2]
78
+ - [4867.8, 4922.5]
79
+ - [4829.2, 4883.4]
80
+ - [4791.1, 4845.0]
81
+ - [4753.7, 4807.1]
82
+ - [4716.9, 4769.9]
83
+ - [4680.6, 4733.2]
84
+ - [4644.9, 4697.1]
85
+ - [4609.7, 4661.5]
86
+ - [4575.1, 4626.5]
87
+ - [4540.9, 4591.9]
88
+ - [4507.3, 4557.9]
89
+ - [4474.2, 4524.4]
90
+ - [4441.5, 4491.4]
91
+ - [4409.3, 4458.9]
92
+ - [4377.6, 4426.8]
93
+ - [4346.4, 4395.2]
94
+ - [4315.5, 4364.0]
95
+ - [4285.2, 4333.3]
96
+ - [4255.2, 4303.0]
97
+ - [4225.7, 4273.1]
98
+ - [4196.5, 4243.6]
99
+ - [4167.8, 4214.6]
100
+ - [4139.4, 4185.9]
101
+ - [4111.5, 4157.6]
102
+ - [4083.9, 4129.7]
103
+ - [4056.7, 4102.2]
104
+ - [4029.8, 4075.0]
105
+ - [4003.3, 4048.2]
106
+ - [3977.1, 4021.8]
107
+ - [3951.3, 3995.7]
108
+ - [3925.8, 3969.9]
109
+ - [3900.7, 3944.5]
110
+ - [3875.8, 3919.3]
111
+ - [3851.3, 3894.5]
112
+ - [3827.1, 3870.0]
113
+ - [3803.2, 3845.9]
114
+ - [3779.6, 3822.0]
115
+ - - [6835.9, 6913.0]
116
+ - [6760.0, 6836.2]
117
+ - [6685.7, 6761.1]
118
+ - [6613.1, 6687.6]
119
+ - [6542.0, 6615.7]
120
+ - [6472.4, 6545.4]
121
+ - [6404.3, 6476.5]
122
+ - [6337.7, 6409.1]
123
+ - [6272.3, 6343.0]
124
+ - [6208.4, 6278.3]
125
+ - [6145.7, 6214.9]
126
+ - [6084.2, 6152.8]
127
+ - [6024.0, 6091.9]
128
+ - [5965.0, 6032.1]
129
+ - [5907.1, 5973.6]
130
+ - [5850.3, 5916.2]
131
+ - [5794.6, 5859.8]
132
+ - [5739.9, 5804.6]
133
+ - [5686.3, 5750.3]
134
+ - [5633.7, 5697.1]
135
+ - [5582.0, 5644.8]
136
+ - [5531.3, 5593.5]
137
+ - [5481.5, 5543.2]
138
+ - [5432.5, 5493.7]
139
+ - [5384.5, 5445.1]
140
+ - [5337.3, 5397.3]
@@ -0,0 +1,312 @@
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 re
9
+ from os.path import dirname, join
10
+
11
+ import numpy as np
12
+
13
+ from .common import Instrument
14
+ from .filters import Filter, InstrumentFilter, NightFilter, ObjectFilter
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ class TypeFilter(Filter):
20
+ def __init__(self, keyword="ESO DPR TYPE"):
21
+ super().__init__(keyword, regex=True)
22
+
23
+ def classify(self, value):
24
+ if value is not None:
25
+ match = self.match(value)
26
+ data = np.asarray(self.data)
27
+ data = np.unique(data[match])
28
+ try:
29
+ regex = re.compile(value)
30
+ keys = [regex.match(f) for f in data]
31
+ keys = [[g for g in d.groups() if g is not None][0] for d in keys]
32
+ unique = np.unique(keys)
33
+ assign = {
34
+ u: [d for k, d in zip(keys, data, strict=False) if k == u]
35
+ for u in unique
36
+ }
37
+ data = [(u, self.match("|".join(a))) for u, a in assign.items()]
38
+ except IndexError:
39
+ data = np.asarray(self.data)
40
+ data = np.unique(data[match])
41
+ data = [(d, self.match(d)) for d in data]
42
+ else:
43
+ data = np.unique(self.data)
44
+ data = [(d, self.match(d)) for d in data]
45
+ return data
46
+
47
+
48
+ class FiberFilter(Filter):
49
+ def __init__(self, keyword="ESO DPR TYPE"):
50
+ super().__init__(keyword, regex=True)
51
+ self.lamp_values = ["LAMP", "STAR", "CIRPOL", "LINPOL"]
52
+
53
+ def collect(self, header):
54
+ value = header.get(self.keyword)
55
+ if value is None:
56
+ value = ""
57
+ else:
58
+ value = value.split(",")
59
+ if value[0] in self.lamp_values and value[1] in self.lamp_values:
60
+ value = "AB"
61
+ elif value[1] in self.lamp_values:
62
+ value = "B"
63
+ elif value[0] in self.lamp_values:
64
+ value = "A"
65
+ else:
66
+ value = ""
67
+
68
+ self.data.append(value)
69
+ return value
70
+
71
+
72
+ class PolarizationFilter(Filter):
73
+ def __init__(self, keyword="ESO INS RET?? POS"):
74
+ super().__init__(keyword, regex=True)
75
+
76
+ def collect(self, header):
77
+ dpr_type = header.get("ESO DPR TYPE", "")
78
+ match = re.match(r"^.*,(CIR|LIN)POL,.*$", dpr_type)
79
+ if match is None:
80
+ value = "none"
81
+ elif match.group(1) == "CIR":
82
+ value = "circular"
83
+ elif match.group(1) == "LIN":
84
+ value = "linear"
85
+ else:
86
+ raise ValueError("Polarization not recognised")
87
+ self.data.append(value)
88
+ return value
89
+
90
+
91
+ class HARPS(Instrument):
92
+ def __init__(self):
93
+ super().__init__()
94
+ self.filters = {
95
+ "instrument": InstrumentFilter(self.config.instrument),
96
+ "night": NightFilter(self.config.date),
97
+ # "branch": Filter(, regex=True),
98
+ "mode": Filter(
99
+ self.config.instrument_mode, regex=True, flags=re.IGNORECASE
100
+ ),
101
+ "type": TypeFilter(self.config.observation_type),
102
+ "polarization": PolarizationFilter(),
103
+ "target": ObjectFilter(self.config.target, regex=True),
104
+ "fiber": FiberFilter(),
105
+ }
106
+ self.night = "night"
107
+ self.science = "science"
108
+ self.shared = ["instrument", "night", "mode", "polarization", "fiber"]
109
+ self.find_closest = [
110
+ "bias",
111
+ "flat",
112
+ "wavecal_master",
113
+ "freq_comb_master",
114
+ "orders",
115
+ "scatter",
116
+ "curvature",
117
+ ]
118
+
119
+ def get_expected_values(
120
+ self, target, night, arm=None, mode=None, fiber=None, polarimetry=None, **kwargs
121
+ ):
122
+ """Determine the default expected values in the headers for a given observation configuration
123
+
124
+ Any parameter may be None, to indicate that all values are allowed
125
+
126
+ Parameters
127
+ ----------
128
+ target : str
129
+ Name of the star / observation target
130
+ night : str
131
+ Observation night/nights
132
+ fiber : "A", "B", "AB"
133
+ Which of the fibers should carry observation signal
134
+ polarimetry : "none", "linear", "circular", bool
135
+ Whether the instrument is used in HARPS or HARPSpol mode
136
+ and which polarization is observed. Set to true for both kinds
137
+ of polarisation.
138
+
139
+ Returns
140
+ -------
141
+ expectations: dict
142
+ Dictionary of expected header values, with one entry per step.
143
+ The entries for each step refer to the filters defined in self.filters
144
+
145
+ Raises
146
+ ------
147
+ ValueError
148
+ Invalid combination of parameters
149
+ """
150
+ if target is not None:
151
+ target = target.replace(" ", r"(?:\s*|-)")
152
+ else:
153
+ target = ".*"
154
+
155
+ if fiber == "AB":
156
+ template = r"({a},{a}),{c}"
157
+ elif fiber == "A":
158
+ template = r"({a},{b}),{c}"
159
+ elif fiber == "B":
160
+ template = r"({b},{a}),{c}"
161
+ elif fiber is None:
162
+ template = None
163
+ fiber = "(AB)|(A)|(B)"
164
+ else:
165
+ raise ValueError(
166
+ "fiber keyword not understood, possible values are 'AB', 'A', 'B'"
167
+ )
168
+
169
+ if polarimetry == "none" or not polarimetry:
170
+ mode = "HARPS"
171
+ if template is not None:
172
+ id_orddef = template.format(a="LAMP", b="DARK", c=".*?")
173
+ id_spec = template.format(a="STAR", b="(?!STAR).*?", c=".*?")
174
+ else:
175
+ id_spec = (
176
+ r"^(STAR,(?!STAR).*),.*$|^((?!STAR).*?,STAR),.*$|^(STAR,STAR),.*$"
177
+ )
178
+ id_orddef = r"^(LAMP,DARK),.*$|^(DARK,LAMP),.*$|^(LAMP,LAMP),.*$"
179
+ polarimetry = "none"
180
+ else:
181
+ mode = "HARPSpol"
182
+ id_orddef = r"(LAMP,LAMP),.*"
183
+ if polarimetry == r"linear":
184
+ id_spec = r"(STAR,LINPOL),.*"
185
+ elif polarimetry == "circular":
186
+ id_spec = r"(STAR,CIRPOL),.*"
187
+ elif polarimetry:
188
+ id_spec = r"(STAR,(?:LIN|CIR)POL),.*"
189
+ polarimetry = r"(circular|linear)"
190
+ else:
191
+ raise ValueError(
192
+ f"polarization parameter not recognized. Expected one of 'none', 'linear', 'circular', but got {polarimetry}"
193
+ )
194
+
195
+ expectations = {
196
+ "bias": {"instrument": "HARPS", "night": night, "type": r"BIAS,BIAS"},
197
+ "flat": {"instrument": "HARPS", "night": night, "type": r"(LAMP,LAMP),.*"},
198
+ "orders": {
199
+ "instrument": "HARPS",
200
+ "night": night,
201
+ "fiber": fiber,
202
+ "type": id_orddef,
203
+ },
204
+ "scatter": {
205
+ "instrument": "HARPS",
206
+ "night": night,
207
+ "type": id_orddef, # Same as orders or same as flat?
208
+ },
209
+ "curvature": {
210
+ "instrument": "HARPS",
211
+ "night": night,
212
+ "type": [r"(WAVE,WAVE,COMB)", r"(WAVE,WAVE,THAR)\d?"],
213
+ },
214
+ "wavecal_master": {
215
+ "instrument": "HARPS",
216
+ "night": night,
217
+ "type": r"(WAVE,WAVE,THAR)\d?",
218
+ },
219
+ "freq_comb_master": {
220
+ "instrument": "HARPS",
221
+ "night": night,
222
+ "type": r"(WAVE,WAVE,COMB)",
223
+ },
224
+ "science": {
225
+ "instrument": "HARPS",
226
+ "night": night,
227
+ "mode": mode,
228
+ "type": id_spec,
229
+ "fiber": fiber,
230
+ "polarization": polarimetry,
231
+ "target": target,
232
+ },
233
+ }
234
+ return expectations
235
+
236
+ def get_extension(self, header, arm):
237
+ extension = super().get_extension(header, arm)
238
+
239
+ try:
240
+ if (
241
+ header["NAXIS"] == 2
242
+ and header["NAXIS1"] == 4296
243
+ and header["NAXIS2"] == 4096
244
+ ):
245
+ extension = 0
246
+ except KeyError:
247
+ pass
248
+
249
+ return extension
250
+
251
+ def add_header_info(self, header, arm, **kwargs):
252
+ """read data from header and add it as REDUCE keyword back to the header"""
253
+ # "Normal" stuff is handled by the general version, specific changes to values happen here
254
+ # alternatively you can implement all of it here, whatever works
255
+ header = super().add_header_info(header, arm)
256
+
257
+ try:
258
+ header["e_ra"] /= 15
259
+ header["e_jd"] += header["e_exptim"] / (7200 * 24) + 0.5
260
+
261
+ pol_angle = header.get("eso ins ret25 pos")
262
+ if pol_angle is None:
263
+ pol_angle = header.get("eso ins ret50 pos")
264
+ if pol_angle is None:
265
+ pol_angle = "no polarimeter"
266
+ else:
267
+ pol_angle = "lin %i" % pol_angle
268
+ else:
269
+ pol_angle = "cir %i" % pol_angle
270
+
271
+ header["e_pol"] = (pol_angle, "polarization angle")
272
+ except:
273
+ pass
274
+
275
+ try:
276
+ if (
277
+ header["NAXIS"] == 2
278
+ and header["NAXIS1"] == 4296
279
+ and header["NAXIS2"] == 4096
280
+ ):
281
+ # both arms are in the same image
282
+ prescan_x = 50
283
+ overscan_x = 50
284
+ naxis_x = 2148
285
+ if arm == "BLUE":
286
+ header["e_xlo"] = prescan_x
287
+ header["e_xhi"] = naxis_x - overscan_x
288
+ elif arm == "RED":
289
+ header["e_xlo"] = naxis_x + prescan_x
290
+ header["e_xhi"] = 2 * naxis_x - overscan_x
291
+ except KeyError:
292
+ pass
293
+
294
+ return header
295
+
296
+ def get_wavecal_filename(self, header, arm, polarimetry, **kwargs):
297
+ """Get the filename of the wavelength calibration config file"""
298
+ cwd = dirname(__file__)
299
+ if polarimetry:
300
+ pol = "_pol"
301
+ else:
302
+ pol = ""
303
+ fname = f"harps_{arm.lower()}{pol}_2D.npz"
304
+ fname = join(cwd, "..", "wavecal", fname)
305
+ return fname
306
+
307
+ def get_wavelength_range(self, header, arm, **kwargs):
308
+ wave_range = super().get_wavelength_range(header, arm, **kwargs)
309
+ # The wavelength orders are in inverse order in the .json file
310
+ # because I was to lazy to invert them in the file
311
+ wave_range = wave_range[::-1]
312
+ return wave_range
@@ -0,0 +1,144 @@
1
+ # HARPS 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__: HARPS
6
+ id_instrument: "HARPS(pol)?"
7
+ instrument: INSTRUME
8
+ telescope: TELESCOP
9
+
10
+ date: DATE-OBS
11
+ date_format: fits
12
+
13
+ arms: [BLUE, RED]
14
+ arms_id: [HARPS, HARPS]
15
+ modes_id_polarimetry: [HARPSpol, HARPSpol]
16
+ extension: [1, 2]
17
+ id: [[1, 1], [1, 2]]
18
+ orientation: 1
19
+ transpose: false
20
+
21
+ prescan_x: "HIERARCH ESO DET OUT{id[0]} PRSCX"
22
+ overscan_x: "HIERARCH ESO DET OUT{id[0]} OVSCX"
23
+ prescan_y: 0
24
+ overscan_y: 0
25
+ naxis_x: NAXIS1
26
+ naxis_y: NAXIS2
27
+
28
+ polarization_linear: "eso ins ret50 pos"
29
+ polarization_circular: "eso ins ret25 pos"
30
+ gain: "HIERARCH ESO DET OUT{id[0]} CONAD"
31
+ readnoise: "HIERARCH ESO DET OUT{id[0]} RON"
32
+ dark: "HIERARCH ESO INS DET{id[1]} OFFDRK"
33
+ sky: "HIERARCH ESO INS DET{id[1]} OFFSKY"
34
+ exposure_time: EXPTIME
35
+
36
+ image_type: OBJECT
37
+ category: "HIERARCH ESO DPR CATG"
38
+ ra: RA
39
+ dec: DEC
40
+ longitude: "HIERARCH ESO TEL GEOLON"
41
+ latitude: "HIERARCH ESO TEL GEOLAT"
42
+ altitude: "HIERARCH ESO TEL GEOELEV"
43
+ target: OBJECT
44
+ instrument_mode: "ESO INS MODE"
45
+ instrument_mode_alternative: "ESO TPL NAME"
46
+ observation_type: "ESO DPR TYPE"
47
+
48
+ id_fiber_a: "LAMP,DARK,TUN"
49
+ id_fiber_b: "DARK,LAMP,TUN"
50
+
51
+ # File classification keywords and patterns
52
+ kw_bias: "ESO DPR TYPE"
53
+ kw_flat: "ESO DPR TYPE"
54
+ kw_curvature: "ESO DPR TYPE"
55
+ kw_scatter: "ESO DPR TYPE"
56
+ kw_orders: "ESO DPR TYPE"
57
+ kw_wave: "ESO DPR TYPE"
58
+ kw_comb: "ESO DPR TYPE"
59
+ kw_spec: "ESO DPR TYPE"
60
+
61
+ id_bias: "BIAS,BIAS"
62
+ id_flat: "LAMP,LAMP,TUN"
63
+ id_orders: "LAMP,LAMP,TUN"
64
+ id_curvature: "WAVE,WAVE,THAR2"
65
+ id_scatter: "LAMP,LAMP,TUN"
66
+ id_wave: "WAVE,WAVE,THAR2"
67
+ id_comb: "WAVE,WAVE,COMB"
68
+ id_spec: "STAR,*,*"
69
+
70
+ wavelength_range:
71
+ # BLUE mode
72
+ - - [5245.4, 5304.3]
73
+ - [5200.5, 5259.0]
74
+ - [5156.5, 5214.4]
75
+ - [5113.2, 5170.6]
76
+ - [5070.6, 5127.6]
77
+ - [5028.7, 5085.2]
78
+ - [4987.5, 5043.5]
79
+ - [4946.9, 5002.5]
80
+ - [4907.0, 4962.2]
81
+ - [4867.8, 4922.5]
82
+ - [4829.2, 4883.4]
83
+ - [4791.1, 4845.0]
84
+ - [4753.7, 4807.1]
85
+ - [4716.9, 4769.9]
86
+ - [4680.6, 4733.2]
87
+ - [4644.9, 4697.1]
88
+ - [4609.7, 4661.5]
89
+ - [4575.1, 4626.5]
90
+ - [4540.9, 4591.9]
91
+ - [4507.3, 4557.9]
92
+ - [4474.2, 4524.4]
93
+ - [4441.5, 4491.4]
94
+ - [4409.3, 4458.9]
95
+ - [4377.6, 4426.8]
96
+ - [4346.4, 4395.2]
97
+ - [4315.5, 4364.0]
98
+ - [4285.2, 4333.3]
99
+ - [4255.2, 4303.0]
100
+ - [4225.7, 4273.1]
101
+ - [4196.5, 4243.6]
102
+ - [4167.8, 4214.6]
103
+ - [4139.4, 4185.9]
104
+ - [4111.5, 4157.6]
105
+ - [4083.9, 4129.7]
106
+ - [4056.7, 4102.2]
107
+ - [4029.8, 4075.0]
108
+ - [4003.3, 4048.2]
109
+ - [3977.1, 4021.8]
110
+ - [3951.3, 3995.7]
111
+ - [3925.8, 3969.9]
112
+ - [3900.7, 3944.5]
113
+ - [3875.8, 3919.3]
114
+ - [3851.3, 3894.5]
115
+ - [3827.1, 3870.0]
116
+ - [3803.2, 3845.9]
117
+ - [3779.6, 3822.0]
118
+ # RED mode
119
+ - - [6835.9, 6913.0]
120
+ - [6760.0, 6836.2]
121
+ - [6685.7, 6761.1]
122
+ - [6613.1, 6687.6]
123
+ - [6542.0, 6615.7]
124
+ - [6472.4, 6545.4]
125
+ - [6404.3, 6476.5]
126
+ - [6337.7, 6409.1]
127
+ - [6272.3, 6343.0]
128
+ - [6208.4, 6278.3]
129
+ - [6145.7, 6214.9]
130
+ - [6084.2, 6152.8]
131
+ - [6024.0, 6091.9]
132
+ - [5965.0, 6032.1]
133
+ - [5907.1, 5973.6]
134
+ - [5850.3, 5916.2]
135
+ - [5794.6, 5859.8]
136
+ - [5739.9, 5804.6]
137
+ - [5686.3, 5750.3]
138
+ - [5633.7, 5697.1]
139
+ - [5582.0, 5644.8]
140
+ - [5531.3, 5593.5]
141
+ - [5481.5, 5543.2]
142
+ - [5432.5, 5493.7]
143
+ - [5384.5, 5445.1]
144
+ - [5337.3, 5397.3]