Coverage for soxspipe/recipes/soxs_order_centres.py : 90%

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*further constrain the first guess locations of the order centres derived in `soxs_disp_solution`*
6:Author:
7 David Young & Marco Landoni
9:Date Created:
10 September 8, 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
25from soxspipe.commonutils import detect_continuum
28class soxs_order_centres(_base_recipe_):
29 """
30 *The soxs_order_centres recipe*
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_order_centres
43 order_table = soxs_order_centres(
44 log=log,
45 settings=settings,
46 inputFrames=a["inputFrames"]
47 ).produce_product()
48 ```
50 ---
52 ```eval_rst
53 .. todo::
55 - add a tutorial about ``soxs_order_centres`` to documentation
56 ```
57 """
58 # Initialisation
60 def __init__(
61 self,
62 log,
63 settings=False,
64 inputFrames=[],
65 verbose=False
67 ):
68 # INHERIT INITIALISATION FROM _base_recipe_
69 super(soxs_order_centres, self).__init__(
70 log=log, settings=settings)
71 self.log = log
72 log.debug("instansiating a new 'soxs_order_centres' object")
73 self.settings = settings
74 self.inputFrames = inputFrames
75 self.verbose = verbose
76 self.recipeName = "soxs-order-centre"
77 self.recipeSettings = settings[self.recipeName]
78 # xt-self-arg-tmpx
80 # INITIAL ACTIONS
81 # CONVERT INPUT FILES TO A CCDPROC IMAGE COLLECTION (inputFrames >
82 # imagefilecollection)
83 sof = set_of_files(
84 log=self.log,
85 settings=self.settings,
86 inputFrames=self.inputFrames
87 )
88 self.inputFrames, self.supplementaryInput = sof.get()
90 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY SOXS_order_centres - NO MORE, NO LESS.
91 # PRINT SUMMARY OF FILES.
92 print("# VERIFYING INPUT FRAMES")
93 self.verify_input_frames()
94 sys.stdout.write("\x1b[1A\x1b[2K")
95 print("# VERIFYING INPUT FRAMES - ALL GOOD")
97 # SORT IMAGE COLLECTION
98 self.inputFrames.sort(['mjd-obs'])
99 if self.verbose:
100 print("# RAW INPUT FRAMES - SUMMARY")
101 print(self.inputFrames.summary, "\n")
103 # PREPARE THE FRAMES - CONVERT TO ELECTRONS, ADD UNCERTAINTY AND MASK
104 # EXTENSIONS
105 self.inputFrames = self.prepare_frames(
106 save=self.settings["save-intermediate-products"])
108 return None
110 def verify_input_frames(
111 self):
112 """*verify input frames match those required by the soxs_order_centres recipe*
114 **Return:**
115 - ``None``
117 If the fits files conform to required input for the recipe everything will pass silently, otherwise an exception shall be raised.
118 """
119 self.log.debug('starting the ``verify_input_frames`` method')
121 kw = self.kw
123 # BASIC VERIFICATION COMMON TO ALL RECIPES
124 self._verify_input_frames_basics()
126 imageTypes = self.inputFrames.values(
127 keyword=kw("DPR_TYPE").lower(), unique=True)
128 imageTech = self.inputFrames.values(
129 keyword=kw("DPR_TECH").lower(), unique=True)
130 imageCat = self.inputFrames.values(
131 keyword=kw("DPR_CATG").lower(), unique=True)
133 if self.arm == "NIR":
134 # WANT ON AND OFF PINHOLE FRAMES
135 # MIXED INPUT IMAGE TYPES ARE BAD
136 if len(imageTypes) > 1:
137 imageTypes = " and ".join(imageTypes)
138 print(self.inputFrames.summary)
139 raise TypeError(
140 "Input frames are a mix of %(imageTypes)s" % locals())
142 if imageTypes[0] != "LAMP,ORDERDEF":
143 raise TypeError(
144 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and lamp off frames for NIR" % locals())
146 for i in imageTech:
147 if i not in ['ECHELLE,PINHOLE', 'IMAGE']:
148 raise TypeError(
149 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and lamp off frames for NIR" % locals())
151 else:
152 for i in imageTypes:
153 if i not in ["LAMP,ORDERDEF", "BIAS", "DARK", 'LAMP,DORDERDEF', 'LAMP,QORDERDEF']:
154 raise TypeError(
155 "Input frames for soxspipe order_centres need to be single pinhole flat-lamp on and a master-bias and possibly a master dark for UVB/VIS" % locals())
157 # LOOK FOR DISP MAP
158 arm = self.arm
159 if arm not in self.supplementaryInput or "DISP_MAP" not in self.supplementaryInput[arm]:
160 raise TypeError(
161 "Need a first guess dispersion map for %(arm)s - none found with the input files" % locals())
163 self.imageType = imageTypes[0]
164 self.log.debug('completed the ``verify_input_frames`` method')
165 return None
167 def produce_product(
168 self):
169 """*generate the order-table with polynomal fits of order-centres*
171 **Return:**
172 - ``productPath`` -- the path to the order-table
173 """
174 self.log.debug('starting the ``produce_product`` method')
176 arm = self.arm
177 kw = self.kw
178 dp = self.detectorParams
180 productPath = None
182 master_bias = False
183 dark = False
184 orderDef_image = False
186 add_filters = {kw("DPR_CATG"): 'MASTER_BIAS_' + arm}
187 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
188 master_bias = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
189 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
191 # UVB/VIS DARK
192 add_filters = {kw("DPR_CATG"): 'MASTER_DARK_' + arm}
193 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
194 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
195 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
197 # NIR DARK
198 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',
199 kw("DPR_TECH"): 'IMAGE'}
200 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
201 print(i)
202 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
203 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
205 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',
206 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
207 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
208 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
209 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
211 # UVB - CHECK FOR D2 LAMP FIRST AND IF NOT FOUND USE THE QTH LAMP
212 add_filters = {kw("DPR_TYPE"): 'LAMP,QORDERDEF',
213 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
214 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
215 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
216 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
218 add_filters = {kw("DPR_TYPE"): 'LAMP,DORDERDEF',
219 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
220 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
221 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
222 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
224 self.orderFrame = self.subtract_calibrations(
225 inputFrame=orderDef_image, master_bias=master_bias, dark=dark)
227 if self.settings["save-intermediate-products"]:
228 fileDir = self.intermediateRootPath
229 filepath = self._write(
230 self.orderFrame, fileDir, filename=False, overwrite=True)
231 print(f"\nCalibrated single pinhole frame frame saved to {filepath}\n")
233 # DETECT THE CONTINUUM OF ORDERE CENTRES - RETURN ORDER TABLE FILE PATH
234 detector = detect_continuum(
235 log=self.log,
236 pinholeFlat=self.orderFrame,
237 dispersion_map=self.supplementaryInput[arm]["DISP_MAP"],
238 settings=self.settings,
239 recipeName="soxs-order-centre"
240 )
241 productPath = detector.get()
243 self.clean_up()
245 self.log.debug('completed the ``produce_product`` method')
246 return productPath
248 # use the tab-trigger below for new method
249 # xt-class-method
251 # Override Method Attributes
252 # method-override-tmpx