Coverage for soxspipe/recipes/soxs_disp_solution.py: 21%

# Coverage for soxspipe/recipes/soxs_disp_solution.py : 21%

## 85 statements 18 run 67 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*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 ####################

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 import unicodecsv as csv

26

27

28 class 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