Coverage for soxspipe/recipes/mbias.py: 95%

# Coverage for soxspipe/recipes/mbias.py : 95%

## 62 statements 59 run 3 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*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 ####################

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 from astropy.stats import mad_std

21 import numpy as np

22 from astropy.nddata import CCDData

23 import ccdproc

24

25

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