Coverage for soxspipe/recipes/soxs_order_centres.py: 19%

# Coverage for soxspipe/recipes/soxs_order_centres.py : 19%

## 96 statements 18 run 78 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1#!/usr/bin/env python

2# encoding: utf-8

3"""

4*further constrain the first guess locations of the order centres derived in `soxs_disp_solution`*

5

6:Author:

7 David Young & Marco Landoni

8

9:Date Created:

10 September 8, 2020

11"""

12################# GLOBAL IMPORTS ####################

13 from builtins import object

14 import sys

15 import os

16 os.environ['TERM'] = 'vt100'

17 from fundamentals import tools

18 from soxspipe.commonutils import set_of_files

19 from ._base_recipe_ import _base_recipe_

20 import numpy as np

21 from astropy.nddata import CCDData

22 from astropy import units as u

23 import ccdproc

24 from soxspipe.commonutils import keyword_lookup

25 from soxspipe.commonutils import detect_continuum

26

27

28 class soxs_order_centres(_base_recipe_):

29 """

30 *The soxs_order_centres recipe*

31

32 **Key Arguments**

33

34 - ``log`` -- logger

35 - ``settings`` -- the settings dictionary

36 - ``inputFrames`` -- input fits frames. Can be a directory, a set-of-files (SOF) file or a list of fits frame paths.

37

38 **Usage**

39

40 ```python

41 from soxspipe.recipes import soxs_order_centres

42 order_table = soxs_order_centres(

43 log=log,

44 settings=settings,

45 inputFrames=a["inputFrames"]

46 ).produce_product()

47 ```

48

49 ---

50

51 ```eval_rst

52 .. todo::

53

54 - add a tutorial about ``soxs_order_centres`` to documentation

55 ```

56 """

57 # Initialisation

58

59 def __init__(

60 self,

61 log,

62 settings=False,

63 inputFrames=[]

64

65 ):

66 # INHERIT INITIALISATION FROM _base_recipe_

67 super(soxs_order_centres, self).__init__(

68 log=log, settings=settings)

69 self.log = log

70 log.debug("instansiating a new 'soxs_order_centres' object")

71 self.settings = settings

72 self.inputFrames = inputFrames

73 # xt-self-arg-tmpx

74

75 # INITIAL ACTIONS

76 # CONVERT INPUT FILES TO A CCDPROC IMAGE COLLECTION (inputFrames >

77 # imagefilecollection)

78 sof = set_of_files(

79 log=self.log,

80 settings=self.settings,

81 inputFrames=self.inputFrames

82 )

83 self.inputFrames, self.supplementaryInput = sof.get()

84

85 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY SOXS_order_centres - NO MORE, NO LESS.

86 # PRINT SUMMARY OF FILES.

87 print("# VERIFYING INPUT FRAMES")

88 self.verify_input_frames()

89 sys.stdout.write("\x1b[1A\x1b[2K")

90 print("# VERIFYING INPUT FRAMES - ALL GOOD")

91

92 print("\n# RAW INPUT DARK FRAMES - SUMMARY")

93 # SORT IMAGE COLLECTION

94 self.inputFrames.sort(['mjd-obs'])

95 print(self.inputFrames.summary, "\n")

96

97 # PREPARE THE FRAMES - CONVERT TO ELECTRONS, ADD UNCERTAINTY AND MASK

98 # EXTENSIONS

99 self.inputFrames = self.prepare_frames(

100 save=self.settings["save-intermediate-products"])

101

102 return None

103

104 def verify_input_frames(

105 self):

106 """*verify the input frame match those required by the soxs_order_centres recipe*

107

108 **Return:**

109 - ``None``

110

111 If the fits files conform to required input for the recipe everything will pass silently, otherwise an exception shall be raised.

112 """

113 self.log.debug('starting the ``verify_input_frames`` method')

114

115 kw = self.kw

116

117 # BASIC VERIFICATION COMMON TO ALL RECIPES

118 self._verify_input_frames_basics()

119

120 imageTypes = self.inputFrames.values(

121 keyword=kw("DPR_TYPE").lower(), unique=True)

122 imageTech = self.inputFrames.values(

123 keyword=kw("DPR_TECH").lower(), unique=True)

124 imageCat = self.inputFrames.values(

125 keyword=kw("DPR_CATG").lower(), unique=True)

126

127 if self.arm == "NIR":

128 # WANT ON AND OFF PINHOLE FRAMES

129 # MIXED INPUT IMAGE TYPES ARE BAD

130 if len(imageTypes) > 1:

131 imageTypes = " and ".join(imageTypes)

132 print(self.inputFrames.summary)

133 raise TypeError(

134 "Input frames are a mix of %(imageTypes)s" % locals())

135

136 if imageTypes[0] != "LAMP,ORDERDEF":

137 raise TypeError(

138 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and lamp off frames for NIR" % locals())

139

140 for i in imageTech:

141 if i not in ['ECHELLE,PINHOLE', 'IMAGE']:

142 raise TypeError(

143 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and lamp off frames for NIR" % locals())

144

145 else:

146 for i in imageTypes:

147 if i not in ["LAMP,ORDERDEF", "BIAS", "DARK", 'LAMP,DORDERDEF', 'LAMP,QORDERDEF']:

148 raise TypeError(

149 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and a master-bias and possibly a master dark for UVB/VIS" % locals())

150

151 # LOOK FOR DISP MAP

152 arm = self.arm

153 if arm not in self.supplementaryInput or "DISP_MAP" not in self.supplementaryInput[arm]:

154 raise TypeError(

155 "Need a first guess dispersion map for %(arm)s - none found with the input files" % locals())

156

157 self.imageType = imageTypes[0]

158 self.log.debug('completed the ``verify_input_frames`` method')

159 return None

160

161 def produce_product(

162 self):

163 """*The code to generate the product of the soxs_order_centres recipe*

164

165 **Return:**

166 - ``productPath`` -- the path to the final product

167 """

168 self.log.debug('starting the ``produce_product`` method')

169

170 arm = self.arm

171 kw = self.kw

172 dp = self.detectorParams

173

174 productPath = None

175

176 master_bias = False

177 dark = False

178 orderDef_image = False

179

180 add_filters = {kw("DPR_CATG"): 'MASTER_BIAS_' + arm}

181 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

182 master_bias = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

183 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

184

185 # UVB/VIS DARK

186 add_filters = {kw("DPR_CATG"): 'MASTER_DARK_' + arm}

187 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

188 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

189 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

190

191 # NIR DARK

192 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',

193 kw("DPR_TECH"): 'IMAGE'}

194 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

195 print(i)

196 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

197 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

198

199 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',

200 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}

201 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

202 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

203 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

204

205 # UVB - CHECK FOR D2 LAMP FIRST AND IF NOT FOUND USE THE QTH LAMP

206 add_filters = {kw("DPR_TYPE"): 'LAMP,QORDERDEF',

207 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}

208 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

209 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

210 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

211

212 add_filters = {kw("DPR_TYPE"): 'LAMP,DORDERDEF',

213 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}

214 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):

215 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',

216 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')

217

218 self.orderFrame = self.subtract_calibrations(

219 inputFrame=orderDef_image, master_bias=master_bias, dark=dark)

220

221 if self.settings["save-intermediate-products"]:

222 fileDir = self.intermediateRootPath

223 filepath = self._write(

224 self.orderFrame, fileDir, filename=False, overwrite=True)

225 print(f"\nCalibrated single pinhole frame frame saved to {filepath}\n")

226

227 # DETECT THE CONTINUUM OF ORDERE CENTRES - RETURN ORDER TABLE FILE PATH

228 detector = detect_continuum(

229 log=self.log,

230 pinholeFlat=self.orderFrame,

231 dispersion_map=self.supplementaryInput[arm]["DISP_MAP"],

232 settings=self.settings

233 )

234 productPath = detector.get()

235

236 self.clean_up()

237

238 self.log.debug('completed the ``produce_product`` method')

239 return productPath

240

241 # use the tab-trigger below for new method

242 # xt-class-method

243

244 # Override Method Attributes

245 # method-override-tmpx