Hide keyboard shortcuts

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*Recipe to generate a first approximation of the dispersion solution from single pinhole frames* 

5 

6:Author: 

7 David Young & Marco Landoni 

8 

9:Date Created: 

10 August 25, 2020 

11""" 

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

13from builtins import object 

14import sys 

15import os 

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

17from fundamentals import tools 

18from soxspipe.commonutils import set_of_files 

19from ._base_recipe_ import _base_recipe_ 

20import numpy as np 

21from astropy.nddata import CCDData 

22from astropy import units as u 

23import ccdproc 

24from soxspipe.commonutils import keyword_lookup 

25import unicodecsv as csv 

26 

27 

28class soxs_disp_solution(_base_recipe_): 

29 """ 

30 *generate a first approximation of the dispersion solution from single pinhole frames* 

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_disp_solution 

42 disp_map_path = soxs_disp_solution( 

43 log=log, 

44 settings=settings, 

45 inputFrames=sofPath 

46 ).produce_product() 

47 ``` 

48 

49 ```eval_rst 

50 .. todo:: 

51 

52 - add a tutorial about ``soxs_disp_solution`` to documentation 

53 ``` 

54 """ 

55 

56 def __init__( 

57 self, 

58 log, 

59 settings=False, 

60 inputFrames=[] 

61 

62 ): 

63 # INHERIT INITIALISATION FROM _base_recipe_ 

64 super(soxs_disp_solution, self).__init__( 

65 log=log, settings=settings) 

66 self.log = log 

67 log.debug("instansiating a new 'soxs_disp_solution' object") 

68 self.settings = settings 

69 self.inputFrames = inputFrames 

70 

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

72 # imagefilecollection) 

73 sof = set_of_files( 

74 log=self.log, 

75 settings=self.settings, 

76 inputFrames=self.inputFrames 

77 ) 

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

79 

80 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY SOXS_disp_solution - NO MORE, NO LESS. 

81 # PRINT SUMMARY OF FILES. 

82 print("# VERIFYING INPUT FRAMES") 

83 self.verify_input_frames() 

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

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

86 

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

88 # SORT IMAGE COLLECTION 

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

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

91 

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

93 # EXTENSIONS 

94 self.inputFrames = self.prepare_frames( 

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

96 

97 return None 

98 

99 def verify_input_frames( 

100 self): 

101 """*verify the input frame match those required by the soxs_disp_solution recipe* 

102 

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

104 """ 

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

106 

107 kw = self.kw 

108 

109 # BASIC VERIFICATION COMMON TO ALL RECIPES 

110 self._verify_input_frames_basics() 

111 

112 imageTypes = self.inputFrames.values( 

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

114 imageTech = self.inputFrames.values( 

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

116 imageCat = self.inputFrames.values( 

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

118 

119 if self.arm == "NIR": 

120 # WANT ON AND OFF PINHOLE FRAMES 

121 # MIXED INPUT IMAGE TYPES ARE BAD 

122 if len(imageTypes) > 1: 

123 imageTypes = " and ".join(imageTypes) 

124 print(self.inputFrames.summary) 

125 raise TypeError( 

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

127 

128 if imageTypes[0] != "LAMP,FMTCHK": 

129 raise TypeError( 

130 "Input frames for soxspipe disp_solution need to be single pinhole lamp on and lamp off frames for NIR" % locals()) 

131 

132 for i in imageTech: 

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

134 raise TypeError( 

135 "Input frames for soxspipe disp_solution need to be single pinhole lamp on and lamp off frames for NIR" % locals()) 

136 

137 else: 

138 for i in imageTypes: 

139 if i not in ["LAMP,FMTCHK", "BIAS", "DARK"]: 

140 raise TypeError( 

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

142 

143 self.imageType = imageTypes[0] 

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

145 return None 

146 

147 def produce_product( 

148 self): 

149 """*The code to generate the dispersion map* 

150 

151 **Return:** 

152 - ``productPath`` -- the path to the dispersion map 

153 """ 

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

155 

156 arm = self.arm 

157 kw = self.kw 

158 dp = self.detectorParams 

159 

160 # self.inputFrames.summary.pprint_all() 

161 

162 master_bias = False 

163 dark = False 

164 pinhole_image = False 

165 

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

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

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

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

170 

171 # UVB/VIS DARK 

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

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

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

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

176 

177 # NIR DARK 

178 add_filters = {kw("DPR_TYPE"): 'LAMP,FMTCHK', kw("DPR_TECH"): 'IMAGE'} 

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

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

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

182 

183 add_filters = {kw("DPR_TYPE"): 'LAMP,FMTCHK', 

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

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

186 pinhole_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS', 

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

188 

189 self.pinholeFrame = self.subtract_calibrations( 

190 inputFrame=pinhole_image, master_bias=master_bias, dark=dark) 

191 

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

193 outDir = self.intermediateRootPath 

194 filePath = self._write( 

195 frame=self.pinholeFrame, 

196 filedir=outDir, 

197 filename=False, 

198 overwrite=True 

199 ) 

200 print(f"\nCalibrated single pinhole frame: {filePath}\n") 

201 

202 from soxspipe.commonutils import create_dispersion_map 

203 productPath = create_dispersion_map( 

204 log=self.log, 

205 settings=self.settings, 

206 pinholeFrame=self.pinholeFrame 

207 ).get() 

208 

209 self.clean_up() 

210 

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

212 return productPath 

213 

214 # use the tab-trigger below for new method 

215 # xt-class-method