lsst.ip.isr ge4dd2483da+a415d157d8
photodiodeCorrection.py
Go to the documentation of this file.
1# This file is part of ip_isr.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21"""
22PhotodiodeCorrection storage class.
23"""
24import numpy as np
25from astropy.table import Table
26from .calibType import IsrCalib
27
28__all__ = ["PhotodiodeCorrection"]
29
30
32 """Parameter set for photodiode correction.
33
34 These parameters are included in cameraGeom.Amplifier, but
35 should be accessible externally to allow for testing.
36
37 Parameters
38 ----------
39 table : `numpy.array`, optional
40 Lookup table; a 2-dimensional array of floats:
41 - one row for each row index (value of coef[0] in the amplifier)
42 - one column for each image value
43 To avoid copying the table the last index should vary fastest
44 (numpy default "C" order)
45 log : `logging.Logger`, optional
46 Logger to handle messages.
47 kwargs : `dict`, optional
48 Other keyword arguments to pass to the parent init.
49
50 Raises
51 ------
52 RuntimeError :
53 Raised if the supplied table is not 2D, or if the table has fewer
54 columns than rows (indicating that the indices are swapped).
55
56 Notes
57 -----
58 The photodiode correction attributes stored are:
59 abscissaCorrections : `dict` : [`str`, `float`]
60 Correction value indexed by exposure pair
61 """
62 _OBSTYPE = "PHOTODIODE_CORRECTION"
63 _SCHEMA = 'PhotodiodeCorrection'
64 _VERSION = 1.1
65
66 def __init__(self, table=None, **kwargs):
67 self.abscissaCorrections = dict()
68 self.tableData = None
69 if table is not None:
70 if len(table.shape) != 2:
71 raise RuntimeError("table shape = %s; must have two dimensions" % (table.shape,))
72 if table.shape[1] < table.shape[0]:
73 raise RuntimeError("table shape = %s; indices are switched" % (table.shape,))
74 self.tableData = np.array(table, order="C")
75
76 super().__init__(**kwargs)
77 self.requiredAttributesrequiredAttributesrequiredAttributes.update(['abscissaCorrections'])
78
79 def updateMetadata(self, setDate=False, **kwargs):
80 """Update metadata keywords with new values.
81
82 This calls the base class's method after ensuring the required
83 calibration keywords will be saved.
84
85 Parameters
86 ----------
87 setDate : `bool`, optional
88 Update the CALIBDATE fields in the metadata to the current
89 time. Defaults to False.
90 kwargs :
91 Other keyword parameters to set in the metadata.
92 """
93
94 super().updateMetadata(setDate=setDate, **kwargs)
95
96 @classmethod
97 def fromDict(cls, dictionary):
98 """Construct a PhotodiodeCorrection from a dictionary of properties.
99
100 Parameters
101 ----------
102 dictionary : `dict`
103 Dictionary of properties.
104
105 Returns
106 -------
108 Constructed photodiode data.
109
110 Raises
111 ------
112 RuntimeError :
113 Raised if the supplied dictionary is for a different
114 calibration type.
115 """
116 calib = cls()
117
118 if calib._OBSTYPE != dictionary['metadata']['OBSTYPE']:
119 raise RuntimeError(f"Incorrect photodiode correction supplied. Expected {calib._OBSTYPE}, "
120 f"found {dictionary['metadata']['OBSTYPE']}")
121
122 calib.setMetadata(dictionary['metadata'])
123 for pair in dictionary['pairs']:
124 correction = dictionary['pairs'][pair]
125 calib.abscissaCorrections[pair] = correction
126
127 calib.tableData = dictionary.get('tableData', None)
128 if calib.tableData:
129 calib.tableData = np.array(calib.tableData)
130
131 return calib
132
133 def toDict(self):
134 """Return a dictionary containing the photodiode correction properties.
135
136 The dictionary should be able to be round-tripped through.
137 `fromDict`.
138
139 Returns
140 -------
141 dictionary : `dict`
142 Dictionary of properties.
143 """
145
146 outDict = dict()
147 outDict['pairs'] = dict()
148 outDict['metadata'] = self.getMetadata()
149 for pair in self.abscissaCorrections.keys():
150 outDict['pairs'][pair] = self.abscissaCorrections[pair]
151
152 if self.tableData is not None:
153 outDict['tableData'] = self.tableData.tolist()
154
155 return outDict
156
157 @classmethod
158 def fromTable(cls, tableList):
159 """Construct calibration from a list of tables.
160
161 This method uses the `fromDict` method to create the
162 calibration after constructing an appropriate dictionary from
163 the input tables.
164
165 Parameters
166 ----------
167 tableList : `list` [`astropy.table.Table`]
168 List of tables to use to construct the crosstalk
169 calibration.
170
171 Returns
172 -------
174 The calibration defined in the tables.
175 """
176 dataTable = tableList[0]
177
178 metadata = dataTable.meta
179 inDict = dict()
180 inDict['metadata'] = metadata
181 inDict['pairs'] = dict()
182
183 for record in dataTable:
184 pair = record['PAIR']
185 inDict['pairs'][pair] = record['PD_CORR']
186
187 if len(tableList) > 1:
188 tableData = tableList[1]
189 inDict['tableData'] = [record['LOOKUP_VALUES'] for record in tableData]
190
191 return cls().fromDict(inDict)
192
193 def toTable(self):
194 """Construct a list of tables containing the information in this
195 calibration.
196
197 The list of tables should create an identical calibration
198 after being passed to this class's fromTable method.
199
200 Returns
201 -------
202 tableList : `list` [`astropy.table.Table`]
203 List of tables containing the photodiode correction
204 information.
205 """
206 tableList = []
208 catalog = Table([{'PAIR': key,
209 'PD_CORR': self.abscissaCorrections[key]}
210 for key in self.abscissaCorrections.keys()])
211 catalog.meta = self.getMetadata().toDict()
212 tableList.append(catalog)
213
214 if self.tableData is not None:
215 catalog = Table([{'LOOKUP_VALUES': value} for value in self.tableData])
216 tableList.append(catalog)
217
218 return(tableList)
219
220 def validate(self):
221 """Validate photodiode correction"""
222 return
def requiredAttributes(self, value)
Definition: calibType.py:150
def updateMetadata(self, camera=None, detector=None, filterName=None, setCalibId=False, setCalibInfo=False, setDate=False, **kwargs)
Definition: calibType.py:189