22 __all__ = [
'getByKey',
'setByKey',
'HeaderMap',
'HeaderAmpMap',
23 'HeaderDetectorMap',
'DetectorBuilder']
37 """Wrapper for getting a value from a metadata object by key. 41 metadata : `lsst.daf.base.PropertySet` 42 Metadata object to query for value. 44 Key to use for value lookup. 49 Value associated with key, None if key does not exist. 51 mdKeys = metadata.paramNames()
53 return metadata.getScalar(key)
59 """Wrapper for setting a value in a metadata object. Deals with case 60 where the key already exists. 64 metadata : `lsst.daf.base.PropertySet` 65 Metadata object ot modify in place. 67 Key to associate with value. 69 Value to assign in the metadata object. 71 Clobber the value if the key already exists? 73 mdKeys = metadata.paramNames()
74 if key
not in mdKeys
or (key
in mdKeys
and clobber):
75 metadata.set(key, value)
79 """ Class to hold mapping of header cards to attributes""" 81 def addEntry(self, keyname, attribute_name, default=None, transform=lambda x: x):
82 """Adds an entry to the registry. 87 Key used to retrieve the header record. 88 attribute_name : `str` 89 Name of the attribute to store the value in. 91 Default value to store if the header card is not available. 92 transform : `callable` 93 Transform to apply to the header value before assigning it to the 96 self.__setitem__(attribute_name, {
'keyName': keyname,
98 'transform': transform})
101 """Sets the attributes on the given object given a metadata object. 106 Object on which to operate in place. 107 metadata : `lsst.daf.base.PropertySet` 108 Metadata object used for applying the mapping. 110 Raise exceptions on calling methods on the input object that 113 for key, attrDict
in self.items():
115 value =
getByKey(metadata, attrDict[
'keyName'])
118 if value
is not None:
119 self.
_applyVal(obj, value, key, attrDict[
'transform'])
123 value = attrDict[
'default']
124 if value
is not None:
125 self.
_applyVal(obj, value, key,
lambda x: x)
126 except Exception
as e:
130 warnings.warn(
'WARNING: Failed to set %s attribute with %s value: %s' %
131 (key, value,
str(e)))
133 def _applyVal(self, obj, value, attrName, transform):
134 raise NotImplementedError(
'Must be implemented in sub-class')
138 """ Class to hold mapping of header cards to AmpInfoTable attributes 139 The amp info is stored using setters, thus calling the attribute as a function. 142 def _applyVal(self, obj, value, attrName, transform):
147 """ Class to hold mapping of header cards to Detector attributes 148 Detector information is stored as attributes on a Config object. 151 def _applyVal(self, obj, value, attrName, transform):
152 obj.__setattr__(attrName,
transform(value))
159 detectorFileName : `str` 160 FITS file containing the detector description. 161 May use [] notation to specify an extension in an MEF. 162 ampFileNameList : `list` of `str` 163 List of FITS file names to use in building the amps. 164 May contain duplicate entries if the raw data are assembled. 166 True if raw data are in amp coordinates, False if raw data 167 are assembled into pseudo detector pixel arrays. 169 Nominal platescale (arcsec/mm). 170 radialCoeffs : `iterable` of `float` 171 Radial distortion coefficients for a radial polynomial in 173 clobberMetadata : `bool` 174 Clobber metadata from input files if overridden in 177 Raise exception if not all non-defaulted keywords are defined? 179 def __init__(self, detectorFileName, ampFileNameList, inAmpCoords=True, plateScale=1.,
180 radialCoeffs=(0., 1.), clobberMetadata=
False, doRaise=
True):
190 for fileName
in ampFileNameList:
197 def _sanitizeHeaderMetadata(self, metadata, clobber):
198 """This method is called for all metadata and gives an opportunity to 199 add/modify header information for use downstream. 201 Override this method if more than the default is needed. 205 metadata : `lsst.daf.base.PropertySet` 206 Metadata to read/modify 208 Clobber keys that exist with default keys? 212 def _defaultSanitization(self, metadata, clobber):
213 """Does the default sanitization of the header metadata. 217 metadata : `lsst.daf.base.PropertySet` 218 Header metadata to extend/modify. 220 Override values in existing header cards? 231 if dtm1
is not None and dtm2
is not None:
232 setByKey(metadata,
'FLIPX', dtm1 < 0, clobber)
233 setByKey(metadata,
'FLIPY', dtm2 < 0, clobber)
235 afwTable.ReadoutCorner.LL), clobber)
237 setByKey(metadata,
'FLIPX',
False, clobber)
238 setByKey(metadata,
'FLIPY',
True, clobber)
241 setByKey(metadata,
'RDCRNR',
None, clobber)
246 if xext
is not None and yext
is not None:
247 setByKey(metadata,
'RAWBBOX',
'[%i:%i,%i:%i]'%(
248 1, xext, 1, yext), clobber)
252 if dtv1
is not None and dtv2
is not None:
253 setByKey(metadata,
'XYOFF', [dtv1, dtv2], clobber)
257 if metadata.isArray(
'BIASSEC'):
258 keylist = [
'HOSCAN',
'PRESCAN',
'VOSCAN']
259 biassecs =
getByKey(metadata,
'BIASSEC')
260 for i, biassec
in enumerate(biassecs):
261 setByKey(metadata, keylist[i], biassec, clobber)
263 biassec =
getByKey(metadata,
'BIASSEC')
264 if biassec
is not None:
265 setByKey(metadata,
'HOSCAN', biassec, clobber)
267 def _makeDefaultAmpMap(self):
268 """Make the default map from header information to amplifier 273 headerAmMap : `HeaderAmpMap` 274 The HeaderAmpMap object containing the mapping 278 mapList = [(
'EXTNAME',
'setName'),
279 (
'DETSEC',
'setBBox',
None, self.
_makeBbox),
280 (
'GAIN',
'setGain', 1.),
281 (
'RDNOISE',
'setReadNoise', 0.),
282 (
'SATURATE',
'setSaturation', 2 << 15),
283 (
'RDCRNR',
'setReadoutCorner',
int(
284 afwTable.ReadoutCorner.LL), afwTable.ReadoutCorner),
285 (
'LINCOEFF',
'setLinearityCoeffs', [0., 1.]),
286 (
'LINTYPE',
'setLinearityType',
'POLY'),
287 (
'RAWBBOX',
'setRawBBox',
None, self.
_makeBbox),
288 (
'DATASEC',
'setRawDataBBox',
None, self.
_makeBbox),
289 (
'FLIPX',
'setRawFlipX',
False),
290 (
'FLIPY',
'setRawFlipY',
False),
292 (
'HOSCAN',
'setRawHorizontalOverscanBBox',
294 (
'VOSCAN',
'setRawVerticalOverscanBBox',
296 (
'PRESCAN',
'setRawPrescanBBox', emptyBBox, self.
_makeBbox),
302 def _makeDefaultDetectorMap(self):
303 """Make the default map from header information to detector information. 307 headerDetectorMap : `HeaderDetectorMap` 308 The HeaderDetectorMap object containing the mapping. 311 mapList = [(
'CCDNAME',
'name',
'ccdName'),
319 (
'OBSTYPE',
'detectorType',
int(
320 afwCameraGeom.DetectorType.SCIENCE)),
321 (
'SERSTR',
'serial',
'none'),
322 (
'XPOS',
'offset_x', 0.),
323 (
'YPOS',
'offset_y', 0.),
324 (
'XPIX',
'refpos_x', 0.),
325 (
'YPIX',
'refpos_y', 0.),
326 (
'YAWDEG',
'yawDeg', 0.),
327 (
'PITCHDEG',
'pitchDeg', 0.),
328 (
'ROLLDEG',
'rollDeg', 0.),
329 (
'XPIXSIZE',
'pixelSize_x', 1.),
330 (
'YPIXSIZE',
'pixelSize_y', 1.),
331 (
'TRNSPOSE',
'transposeDetector',
False),
337 def _makeExt(self, extArr):
338 """Helper function to make an extent from an array 342 extArr : `array` of `int` 343 Length 2 array to use in creating the Extent object. 347 extent : `lsst.geom.Extent2I` 348 Extent constructed from the input list. 352 def _makeBbox(self, boxString):
353 """Helper funtion to make a bounding box from a string representing a 354 FITS style bounding box. 359 String describing the bounding box. 363 bbox : `lsst.geom.Box2I` 367 x1, x2, y1, y2 = [
int(el)
for el
in re.split(
368 '[:,]', boxString.strip()[1:-1])]
375 def _getBboxX0(self, boxString):
376 return self.
_makeBbox(boxString).getMinX()
378 def _getBboxX1(self, boxString):
379 return self.
_makeBbox(boxString).getMaxX()
381 def _getBboxY0(self, boxString):
382 return self.
_makeBbox(boxString).getMinY()
384 def _getBboxY1(self, boxString):
385 return self.
_makeBbox(boxString).getMaxY()
387 def _makeRadialTransform(self, radialCoeffs):
388 """Helper function to get the radial transform given the radial 389 polynomial coefficients given in the constructor. 393 radialCoeffs : `iterable` of `float` 394 List of coefficients describing a polynomial radial distortion in 395 normalized units. The first value must be 0. 399 transform : `lsst.afw.geom.TransformPoint2ToPoint2` 400 Transform object describing the radial distortion 406 """Take all the information and build a Detector object. 407 The Detector object is necessary for doing things like assembly. 411 detector : `lsst.afw.cameraGeom.Detector` 417 schema = afwTable.AmpInfoTable.makeMinimalSchema()
420 record = ampInfo.addNew()
422 record.setHasRawInfo(
True)
424 detConfig = afwCameraGeom.DetectorConfig()
427 self.
detector = afwCameraGeom.makeDetector(
432 """Method for constructing an exposure object from an image and the 433 information contained in this class to construct the Detector. 437 im : `lsst.afw.image.Image` 438 Image used to construct the exposure. 439 mask : `lsst.afw.image.MaskU` 441 variance : `lsst.afw.image.Image` 442 Optional variance plance as an image of the same type as im. 446 exposure : `lsst.afw.image.Exposure` 447 Constructed exposure (specific type will match that of ``im``). 457 exp.setDetector(detector)
def makeExposure(self, im, mask=None, variance=None)
def _makeRadialTransform(self, radialCoeffs)
def _getBboxY1(self, boxString)
def _makeDefaultAmpMap(self)
def _makeDefaultDetectorMap(self)
def _makeBbox(self, boxString)
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename std::shared_ptr< Image< ImagePixelT >> image, typename std::shared_ptr< Mask< MaskPixelT >> mask=Mask< MaskPixelT >(), typename std::shared_ptr< Image< VariancePixelT >> variance=Image< VariancePixelT >())
A function to return a MaskedImage of the correct type (cf.
def _defaultSanitization(self, metadata, clobber)
def _getBboxY0(self, boxString)
std::shared_ptr< Exposure< ImagePixelT, MaskPixelT, VariancePixelT > > makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, std::shared_ptr< geom::SkyWcs const > wcs=std::shared_ptr< geom::SkyWcs const >())
A function to return an Exposure of the correct type (cf.
def _sanitizeHeaderMetadata(self, metadata, clobber)
Represent a 2-dimensional array of bitmask pixels.
def getByKey(metadata, key)
std::shared_ptr< TransformPoint2ToPoint2 > makeRadialTransform(std::vector< double > const &forwardCoeffs, std::vector< double > const &inverseCoeffs)
A purely radial polynomial distortion.
def _getBboxX0(self, boxString)
def _makeExt(self, extArr)
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects...
def _getBboxX1(self, boxString)
constexpr double arcsecToRad(double x) noexcept
An integer coordinate rectangle.
def __init__(self, detectorFileName, ampFileNameList, inAmpCoords=True, plateScale=1., radialCoeffs=(0., 1.), clobberMetadata=False, doRaise=True)
def setByKey(metadata, key, value, clobber)