25 import lsst.afw.cameraGeom
as cameraGeom
26 import lsst.afw.geom
as afwGeom
27 from lsst.afw.table
import AmpInfoCatalog, AmpInfoTable
28 from lsst.afw.cameraGeom.cameraFactory
import makeDetector
32 """The Commissioning Camera (comCam) 36 cameraYamlFile : `str` 37 Camera description YAML file. 41 with open(cameraYamlFile)
as fd:
42 cameraParams = yaml.load(fd, Loader=yaml.Loader)
44 plateScale = afwGeom.Angle(cameraParams[
"plateScale"], afwGeom.arcseconds)
49 radialCoeffs = np.array(cameraParams[
"radialCoeffs"])/plateScale.asRadians()
50 fieldAngleToFocalPlane = afwGeom.makeRadialTransform(radialCoeffs)
51 focalPlaneToFieldAngle = fieldAngleToFocalPlane.inverted()
52 cameraTransformMap = cameraGeom.TransformMap(cameraGeom.FOCAL_PLANE,
53 {cameraGeom.FIELD_ANGLE: focalPlaneToFieldAngle})
54 detectorList = self.
_makeDetectorList(cameraParams[
"CCDs"], focalPlaneToFieldAngle)
55 cameraGeom.Camera.__init__(self, cameraParams[
"name"], detectorList, cameraTransformMap)
57 def _makeDetectorList(self, ccdParams, focalPlaneToFieldAngle):
58 """Make a list of detectors 63 Dict of YAML descriptions of CCDs. 64 focalPlaneToFieldAngle : `lsst.afw.geom.TransformPoint2ToPoint2` 65 Angle from FOCAL_PLANE to FIELD_ANGLE coordinates. 69 `list` of `lsst.afw.cameraGeom.Detector` 70 list of detectors in this camera. 74 for ccd, detectorConfig
in zip(ccdParams.values(), detectorConfigList):
76 detector = makeDetector(detectorConfig, ampInfoCatalog, focalPlaneToFieldAngle)
77 detectorList.append(detector)
80 def _makeDetectorConfigList(self, ccdParams):
81 """Make a list of detector configs 85 `list` of `lsst.afw.cameraGeom.DetectorConfig` 86 A list of detector configs. 89 for name, ccd
in ccdParams.items():
90 detectorConfig = cameraGeom.DetectorConfig()
91 detectorConfigs.append(detectorConfig)
93 detectorConfig.name = name
94 detectorConfig.id = ccd[
'id']
95 detectorConfig.serial = ccd[
'serial']
96 detectorConfig.detectorType = ccd[
'detectorType']
98 detectorConfig.bbox_x0, detectorConfig.bbox_y0 = ccd[
'bbox'][0]
99 detectorConfig.bbox_x1, detectorConfig.bbox_y1 = ccd[
'bbox'][1]
100 detectorConfig.pixelSize_x, detectorConfig.pixelSize_y = ccd[
'pixelSize']
101 detectorConfig.transformDict.nativeSys = ccd[
'transformDict'][
'nativeSys']
102 transforms = ccd[
'transformDict'][
'transforms']
103 detectorConfig.transformDict.transforms =
None if transforms ==
'None' else transforms
104 detectorConfig.refpos_x, detectorConfig.refpos_y = ccd[
'refpos']
105 detectorConfig.offset_x, detectorConfig.offset_y = ccd[
'offset']
106 detectorConfig.transposeDetector = ccd[
'transposeDetector']
107 detectorConfig.pitchDeg = ccd[
'pitch']
108 detectorConfig.yawDeg = ccd[
'yaw']
109 detectorConfig.rollDeg = ccd[
'roll']
110 if 'crosstalk' in ccd:
111 detectorConfig.crosstalk = ccd[
'crosstalk']
113 return detectorConfigs
116 def _makeBBoxFromList(ylist):
117 """Given a list [(x0, y0), (xsize, ysize)], probably from a yaml file, 120 (x0, y0), (xsize, ysize) = ylist
121 return afwGeom.BoxI(afwGeom.PointI(x0, y0), afwGeom.ExtentI(xsize, ysize))
123 def _makeAmpInfoCatalog(self, ccd):
124 """Construct an amplifier info catalog 127 assert len(ccd[
'amplifiers']) > 0
128 amp = list(ccd[
'amplifiers'].values())[0]
131 xRawExtent, yRawExtent = rawBBox.getDimensions()
133 from lsst.afw.table
import LL, LR, UL, UR
134 readCorners = dict(LL=LL, LR=LR, UL=UL, UR=UR)
136 schema = AmpInfoTable.makeMinimalSchema()
138 linThreshKey = schema.addField(
'linearityThreshold', type=float)
139 linMaxKey = schema.addField(
'linearityMaximum', type=float)
140 linUnitsKey = schema.addField(
'linearityUnits', type=str, size=9)
141 hduKey = schema.addField(
'hdu', type=np.int32)
144 ampCatalog = AmpInfoCatalog(schema)
145 for name, amp
in sorted(ccd[
'amplifiers'].items(), key=
lambda x: x[1][
'hdu']):
146 record = ampCatalog.addNew()
148 record.set(hduKey, amp[
'hdu'])
151 perAmpData = amp[
'perAmpData']
155 x0, y0 = ix*xRawExtent, iy*yRawExtent
158 xDataExtent, yDataExtent = rawDataBBox.getDimensions()
159 record.setBBox(afwGeom.BoxI(
160 afwGeom.PointI(ix*xDataExtent, iy*yDataExtent), rawDataBBox.getDimensions()))
163 rawBBox.shift(afwGeom.ExtentI(x0, y0))
164 record.setRawBBox(rawBBox)
167 rawDataBBox.shift(afwGeom.ExtentI(x0, y0))
168 record.setRawDataBBox(rawDataBBox)
171 rawSerialOverscanBBox.shift(afwGeom.ExtentI(x0, y0))
172 record.setRawHorizontalOverscanBBox(rawSerialOverscanBBox)
175 rawParallelOverscanBBox.shift(afwGeom.ExtentI(x0, y0))
176 record.setRawVerticalOverscanBBox(rawParallelOverscanBBox)
179 rawSerialPrescanBBox.shift(afwGeom.ExtentI(x0, y0))
180 record.setRawPrescanBBox(rawSerialPrescanBBox)
183 record.setRawXYOffset(afwGeom.Extent2I(ix*xRawExtent, iy*yRawExtent))
185 record.setRawXYOffset(afwGeom.Extent2I(0, 0))
187 record.setReadoutCorner(readCorners[amp[
'readCorner']])
188 record.setGain(amp[
'gain'])
189 record.setReadNoise(amp[
'readNoise'])
190 record.setSaturation(amp[
'saturation'])
191 record.setHasRawInfo(
True)
193 flipX, flipY = amp.get(
"flipXY")
195 record.setRawFlipX(flipX)
196 record.setRawFlipY(flipY)
198 record.setLinearityCoeffs([float(val)
for val
in amp[
'linearityCoeffs']])
199 record.setLinearityType(amp[
'linearityType'])
200 record.set(linThreshKey, float(amp[
'linearityThreshold']))
201 record.set(linMaxKey, float(amp[
'linearityMax']))
202 record.set(linUnitsKey,
"DN")
def _makeAmpInfoCatalog(self, ccd)
def _makeDetectorList(self, ccdParams, focalPlaneToFieldAngle)
def __init__(self, cameraYamlFile)
def _makeBBoxFromList(ylist)
def _makeDetectorConfigList(self, ccdParams)