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

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*
6:Author:
7 David Young & Marco Landoni
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
28class soxs_disp_solution(_base_recipe_):
29 """
30 *generate a first approximation of the dispersion solution from single pinhole frames*
32 **Key Arguments**
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 - ``verbose`` -- verbose. True or False. Default *False*
39 **Usage**
41 ```python
42 from soxspipe.recipes import soxs_disp_solution
43 disp_map_path = soxs_disp_solution(
44 log=log,
45 settings=settings,
46 inputFrames=sofPath
47 ).produce_product()
48 ```
50 ---
52 ```eval_rst
53 .. todo::
55 - add a tutorial about ``soxs_disp_solution`` to documentation
56 ```
57 """
59 def __init__(
60 self,
61 log,
62 settings=False,
63 inputFrames=[],
64 verbose=False
66 ):
67 # INHERIT INITIALISATION FROM _base_recipe_
68 super(soxs_disp_solution, self).__init__(
69 log=log, settings=settings)
70 self.log = log
71 log.debug("instansiating a new 'soxs_disp_solution' object")
72 self.settings = settings
73 self.inputFrames = inputFrames
74 self.verbose = verbose
75 self.recipeName = "soxs-disp-solution"
76 self.recipeSettings = settings[self.recipeName]
78 # CONVERT INPUT FILES TO A CCDPROC IMAGE COLLECTION (inputFrames >
79 # imagefilecollection)
80 sof = set_of_files(
81 log=self.log,
82 settings=self.settings,
83 inputFrames=self.inputFrames
84 )
85 self.inputFrames, self.supplementaryInput = sof.get()
87 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY SOXS_disp_solution - NO MORE, NO LESS.
88 # PRINT SUMMARY OF FILES.
89 print("# VERIFYING INPUT FRAMES")
90 self.verify_input_frames()
91 sys.stdout.write("\x1b[1A\x1b[2K")
92 print("# VERIFYING INPUT FRAMES - ALL GOOD")
94 # SORT IMAGE COLLECTION
95 self.inputFrames.sort(['mjd-obs'])
96 if self.verbose:
97 print("# RAW INPUT FRAMES - SUMMARY")
98 print(self.inputFrames.summary, "\n")
100 # PREPARE THE FRAMES - CONVERT TO ELECTRONS, ADD UNCERTAINTY AND MASK
101 # EXTENSIONS
102 self.inputFrames = self.prepare_frames(
103 save=self.settings["save-intermediate-products"])
105 return None
107 def verify_input_frames(
108 self):
109 """*verify input frames match those required by the `soxs_disp_solution` recipe*
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')
115 kw = self.kw
117 # BASIC VERIFICATION COMMON TO ALL RECIPES
118 self._verify_input_frames_basics()
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)
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())
136 if imageTypes[0] != "LAMP,FMTCHK":
137 raise TypeError(
138 "Input frames for soxspipe disp_solution need to be single pinhole lamp on and lamp off frames for NIR" % locals())
140 for i in imageTech:
141 if i not in ['ECHELLE,PINHOLE', 'IMAGE']:
142 raise TypeError(
143 "Input frames for soxspipe disp_solution need to be single pinhole lamp on and lamp off frames for NIR" % locals())
145 else:
146 for i in imageTypes:
147 if i not in ["LAMP,FMTCHK", "BIAS", "DARK"]:
148 raise TypeError(
149 "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())
151 self.imageType = imageTypes[0]
152 self.log.debug('completed the ``verify_input_frames`` method')
153 return None
155 def produce_product(
156 self):
157 """*generate a fisrt guess of the dispersion solution*
159 **Return:**
160 - ``productPath`` -- the path to the first guess dispersion map
161 """
162 self.log.debug('starting the ``produce_product`` method')
164 arm = self.arm
165 kw = self.kw
166 dp = self.detectorParams
168 # self.inputFrames.summary.pprint_all()
170 master_bias = False
171 dark = False
172 pinhole_image = False
174 add_filters = {kw("DPR_CATG"): 'MASTER_BIAS_' + arm}
175 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
176 master_bias = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
177 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
179 # UVB/VIS DARK
180 add_filters = {kw("DPR_CATG"): 'MASTER_DARK_' + arm}
181 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
182 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
183 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
185 # NIR DARK
186 add_filters = {kw("DPR_TYPE"): 'LAMP,FMTCHK', kw("DPR_TECH"): 'IMAGE'}
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')
191 add_filters = {kw("DPR_TYPE"): 'LAMP,FMTCHK',
192 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
193 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
194 pinhole_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
195 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
197 self.pinholeFrame = self.subtract_calibrations(
198 inputFrame=pinhole_image, master_bias=master_bias, dark=dark)
200 if self.settings["save-intermediate-products"]:
201 outDir = self.intermediateRootPath
202 filePath = self._write(
203 frame=self.pinholeFrame,
204 filedir=outDir,
205 filename=False,
206 overwrite=True
207 )
208 print(f"\nCalibrated single pinhole frame: {filePath}\n")
210 from soxspipe.commonutils import create_dispersion_map
211 productPath = create_dispersion_map(
212 log=self.log,
213 settings=self.settings,
214 pinholeFrame=self.pinholeFrame
215 ).get()
217 self.clean_up()
219 self.log.debug('completed the ``produce_product`` method')
220 return productPath
222 # use the tab-trigger below for new method
223 # xt-class-method