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

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.
38 **Usage**
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 ```
49 ```eval_rst
50 .. todo::
52 - add a tutorial about ``soxs_disp_solution`` to documentation
53 ```
54 """
56 def __init__(
57 self,
58 log,
59 settings=False,
60 inputFrames=[]
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
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()
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")
87 print("\n# RAW INPUT DARK FRAMES - SUMMARY")
88 # SORT IMAGE COLLECTION
89 self.inputFrames.sort(['mjd-obs'])
90 print(self.inputFrames.summary, "\n")
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"])
97 return None
99 def verify_input_frames(
100 self):
101 """*verify the input frame match those required by the soxs_disp_solution recipe*
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')
107 kw = self.kw
109 # BASIC VERIFICATION COMMON TO ALL RECIPES
110 self._verify_input_frames_basics()
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)
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())
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())
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())
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())
143 self.imageType = imageTypes[0]
144 self.log.debug('completed the ``verify_input_frames`` method')
145 return None
147 def produce_product(
148 self):
149 """*The code to generate the dispersion map*
151 **Return:**
152 - ``productPath`` -- the path to the dispersion map
153 """
154 self.log.debug('starting the ``produce_product`` method')
156 arm = self.arm
157 kw = self.kw
158 dp = self.detectorParams
160 # self.inputFrames.summary.pprint_all()
162 master_bias = False
163 dark = False
164 pinhole_image = False
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')
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')
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')
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')
189 self.pinholeFrame = self.subtract_calibrations(
190 inputFrame=pinhole_image, master_bias=master_bias, dark=dark)
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")
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()
209 self.clean_up()
211 self.log.debug('completed the ``produce_product`` method')
212 return productPath
214 # use the tab-trigger below for new method
215 # xt-class-method