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

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.
38 **Usage**
40 ```python
41 from soxspipe.recipes import soxs_order_centres
42 order_table = soxs_order_centres(
43 log=log,
44 settings=settings,
45 inputFrames=a["inputFrames"]
46 ).produce_product()
47 ```
49 ---
51 ```eval_rst
52 .. todo::
54 - add a tutorial about ``soxs_order_centres`` to documentation
55 ```
56 """
57 # Initialisation
59 def __init__(
60 self,
61 log,
62 settings=False,
63 inputFrames=[]
65 ):
66 # INHERIT INITIALISATION FROM _base_recipe_
67 super(soxs_order_centres, self).__init__(
68 log=log, settings=settings)
69 self.log = log
70 log.debug("instansiating a new 'soxs_order_centres' object")
71 self.settings = settings
72 self.inputFrames = inputFrames
73 # xt-self-arg-tmpx
75 # INITIAL ACTIONS
76 # CONVERT INPUT FILES TO A CCDPROC IMAGE COLLECTION (inputFrames >
77 # imagefilecollection)
78 sof = set_of_files(
79 log=self.log,
80 settings=self.settings,
81 inputFrames=self.inputFrames
82 )
83 self.inputFrames, self.supplementaryInput = sof.get()
85 # VERIFY THE FRAMES ARE THE ONES EXPECTED BY SOXS_order_centres - NO MORE, NO LESS.
86 # PRINT SUMMARY OF FILES.
87 print("# VERIFYING INPUT FRAMES")
88 self.verify_input_frames()
89 sys.stdout.write("\x1b[1A\x1b[2K")
90 print("# VERIFYING INPUT FRAMES - ALL GOOD")
92 print("\n# RAW INPUT DARK FRAMES - SUMMARY")
93 # SORT IMAGE COLLECTION
94 self.inputFrames.sort(['mjd-obs'])
95 print(self.inputFrames.summary, "\n")
97 # PREPARE THE FRAMES - CONVERT TO ELECTRONS, ADD UNCERTAINTY AND MASK
98 # EXTENSIONS
99 self.inputFrames = self.prepare_frames(
100 save=self.settings["save-intermediate-products"])
102 return None
104 def verify_input_frames(
105 self):
106 """*verify the input frame match those required by the soxs_order_centres recipe*
108 **Return:**
109 - ``None``
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,ORDERDEF":
137 raise TypeError(
138 "Input frames for soxspipe order_centres need to be single pinhole flat-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 order_centres need to be single pinhole flat-lamp on and lamp off frames for NIR" % locals())
145 else:
146 for i in imageTypes:
147 if i not in ["LAMP,ORDERDEF", "BIAS", "DARK", 'LAMP,DORDERDEF', 'LAMP,QORDERDEF']:
148 raise TypeError(
149 "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())
151 # LOOK FOR DISP MAP
152 arm = self.arm
153 if arm not in self.supplementaryInput or "DISP_MAP" not in self.supplementaryInput[arm]:
154 raise TypeError(
155 "Need a first guess dispersion map for %(arm)s - none found with the input files" % locals())
157 self.imageType = imageTypes[0]
158 self.log.debug('completed the ``verify_input_frames`` method')
159 return None
161 def produce_product(
162 self):
163 """*The code to generate the product of the soxs_order_centres recipe*
165 **Return:**
166 - ``productPath`` -- the path to the final product
167 """
168 self.log.debug('starting the ``produce_product`` method')
170 arm = self.arm
171 kw = self.kw
172 dp = self.detectorParams
174 productPath = None
176 master_bias = False
177 dark = False
178 orderDef_image = False
180 add_filters = {kw("DPR_CATG"): 'MASTER_BIAS_' + arm}
181 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
182 master_bias = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
183 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
185 # UVB/VIS DARK
186 add_filters = {kw("DPR_CATG"): 'MASTER_DARK_' + arm}
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 # NIR DARK
192 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',
193 kw("DPR_TECH"): 'IMAGE'}
194 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
195 print(i)
196 dark = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
197 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
199 add_filters = {kw("DPR_TYPE"): 'LAMP,ORDERDEF',
200 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
201 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
202 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
203 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
205 # UVB - CHECK FOR D2 LAMP FIRST AND IF NOT FOUND USE THE QTH LAMP
206 add_filters = {kw("DPR_TYPE"): 'LAMP,QORDERDEF',
207 kw("DPR_TECH"): 'ECHELLE,PINHOLE'}
208 for i in self.inputFrames.files_filtered(include_path=True, **add_filters):
209 orderDef_image = CCDData.read(i, hdu=0, unit=u.adu, hdu_uncertainty='ERRS',
210 hdu_mask='QUAL', hdu_flags='FLAGS', key_uncertainty_type='UTYPE')
212 add_filters = {kw("DPR_TYPE"): 'LAMP,DORDERDEF',
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 self.orderFrame = self.subtract_calibrations(
219 inputFrame=orderDef_image, master_bias=master_bias, dark=dark)
221 if self.settings["save-intermediate-products"]:
222 fileDir = self.intermediateRootPath
223 filepath = self._write(
224 self.orderFrame, fileDir, filename=False, overwrite=True)
225 print(f"\nCalibrated single pinhole frame frame saved to {filepath}\n")
227 # DETECT THE CONTINUUM OF ORDERE CENTRES - RETURN ORDER TABLE FILE PATH
228 detector = detect_continuum(
229 log=self.log,
230 pinholeFlat=self.orderFrame,
231 dispersion_map=self.supplementaryInput[arm]["DISP_MAP"],
232 settings=self.settings
233 )
234 productPath = detector.get()
236 self.clean_up()
238 self.log.debug('completed the ``produce_product`` method')
239 return productPath
241 # use the tab-trigger below for new method
242 # xt-class-method
244 # Override Method Attributes
245 # method-override-tmpx