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*The recipe for creating master-bias frames * 

5 

6:Author: 

7 David Young 

8 

9:Date Created: 

10 January 22, 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_ 

20from astropy.stats import mad_std 

21import numpy as np 

22from astropy.nddata import CCDData 

23import ccdproc 

24 

25 

26class mbias(_base_recipe_): 

27 """ 

28 *The mbias recipe* 

29 

30 **Key Arguments:** 

31 - ``log`` -- logger 

32 - ``settings`` -- the settings dictionary 

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

34 

35 **Usage:** 

36 

37 To setup your logger, settings and database connections, please use the ``fundamentals`` package (`see tutorial here <http://fundamentals.readthedocs.io/en/latest/#tutorial>`_).  

38 

39 See `produce_product` method for usage. 

40 

41 .. todo:: 

42 

43 - add a tutorial about ``mbias`` to documentation 

44 """ 

45 # Initialisation 

46 

47 def __init__( 

48 self, 

49 log, 

50 settings=False, 

51 inputFrames=[] 

52 

53 ): 

54 # INHERIT INITIALISATION FROM _base_recipe_ 

55 super().__init__(log=log, settings=settings) 

56 self.log = log 

57 log.debug("instansiating a new 'mbias' object") 

58 self.settings = settings 

59 self.inputFrames = inputFrames 

60 # xt-self-arg-tmpx 

61 

62 # INITIAL ACTIONS 

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

64 # imagefilecollection) 

65 sof = set_of_files( 

66 log=self.log, 

67 settings=self.settings, 

68 inputFrames=self.inputFrames 

69 ) 

70 self.inputFrames = sof.get() 

71 

72 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY MBIAS - NO MORE, NO LESS. 

73 # PRINT SUMMARY OF FILES. 

74 self.verify_input_frames() 

75 print(self.inputFrames.summary) 

76 

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

78 # EXTENSIONS 

79 self.inputFrames = self.prepare_frames( 

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

81 

82 return None 

83 

84 def verify_input_frames( 

85 self): 

86 """*verify the input frame match those required by the mbias recipe* 

87 

88 **Return:** 

89 - ``None`` 

90 

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

92 """ 

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

94 

95 imageTypes = self.inputFrames.values( 

96 keyword='eso dpr type', unique=True) 

97 

98 # MIXED INPUT IMAGE TYPES ARE BAD 

99 if len(imageTypes) > 1: 

100 imageTypes = " and ".join(imageTypes) 

101 print(self.inputFrames.summary) 

102 raise TypeError( 

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

104 # NON-BIAS INPUT IMAGE TYPES ARE BAD 

105 elif imageTypes[0] != 'BIAS': 

106 print(self.inputFrames.summary) 

107 raise TypeError( 

108 "Input frames not BIAS frames" % locals()) 

109 

110 arms = self.inputFrames.values( 

111 keyword='eso seq arm', unique=True) 

112 # MIXED INPUT ARMS ARE BAD 

113 if len(arms) > 1: 

114 arms = " and ".join(arms) 

115 print(self.inputFrames.summary) 

116 raise TypeError( 

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

118 

119 cdelt1 = self.inputFrames.values( 

120 keyword='cdelt1', unique=True) 

121 cdelt2 = self.inputFrames.values( 

122 keyword='cdelt2', unique=True) 

123 # MIXED BINNING IS BAD 

124 if len(cdelt1) > 1 or len(cdelt2) > 1: 

125 print(self.inputFrames.summary) 

126 raise TypeError( 

127 "Input frames are a mix of binnings" % locals()) 

128 

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

130 return None 

131 

132 def produce_product( 

133 self): 

134 """*The code to generate the product of the mbias recipe* 

135 

136 **Return:** 

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

138 

139 **Usage:** 

140 

141 ```python 

142 from soxspipe.recipes import mbias 

143 recipe = mbias( 

144 log=log, 

145 settings=settings, 

146 inputFrames=fileList 

147 ) 

148 mbiasFrame = recipe.produce_product() 

149 ``` 

150 """ 

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

152 

153 # IMAGECOLLECTION FILEPATHS 

154 filepaths = self.inputFrames.files_filtered(include_path=True) 

155 

156 ccds = [] 

157 for f in filepaths: 

158 ccd = CCDData.read(f, hdu=0, unit='electron', hdu_uncertainty='UNCERT', 

159 hdu_mask='MASK', hdu_flags='BITMAP', key_uncertainty_type='UTYPE') 

160 ccds.append(ccd) 

161 

162 # GENERATE THE COMBINED MEDIAN 

163 combined_bias_median = ccdproc.combine(ccds, method='median', sigma_clip=True, sigma_clip_low_thresh=5, 

164 sigma_clip_high_thresh=5, sigma_clip_func=np.ma.median, sigma_clip_dev_func=mad_std, mem_limit=700e6) 

165 

166 # PRODUCT PATH 

167 arm = combined_bias_median.header['eso seq arm'] 

168 x = combined_bias_median.header['eso det win1 binx'] 

169 y = combined_bias_median.header['eso det win1 biny'] 

170 productPath = self.intermediateRootPath + \ 

171 "/master_bias_%(arm)s_%(x)sx%(y)s.fits" % locals() 

172 

173 combined_bias_median.write( 

174 productPath, 

175 overwrite=True) 

176 

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

178 return productPath 

179 

180 # use the tab-trigger below for new method 

181 # xt-class-method 

182 

183 # Override Method Attributes 

184 # method-override-tmpx