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)
38 with open(cameraYamlFile)
as fd:
39 cameraParams = yaml.load(fd, Loader=yaml.Loader)
41 plateScale = afwGeom.Angle(cameraParams[
"plateScale"], afwGeom.arcseconds)
42 radialCoeffs = np.array(cameraParams[
"radialCoeffs"])/plateScale.asRadians()
43 focalPlaneToPupil = afwGeom.makeRadialTransform(radialCoeffs)
44 pupilToFocalPlane = focalPlaneToPupil.getInverse()
45 cameraTransformMap = cameraGeom.CameraTransformMap(cameraGeom.FOCAL_PLANE,
46 {cameraGeom.PUPIL: pupilToFocalPlane})
47 detectorList = self.
_makeDetectorList(cameraParams[
"CCDs"], pupilToFocalPlane, plateScale)
48 cameraGeom.Camera.__init__(self, cameraParams[
"name"], detectorList, cameraTransformMap)
50 def _makeDetectorList(self, ccdParams, focalPlaneToPupil, plateScale):
51 """!Make a list of detectors
52 @param[in] ccdParams Dict of YAML descriptions of CCDs
53 @param[in] focalPlaneToPupil lsst.afw.geom.XYTransform from FOCAL_PLANE to PUPIL coordinates
54 @param[in] plateScale plate scale, in angle on sky/mm
55 @return a list of detectors (lsst.afw.cameraGeom.Detector)
59 for ccd, detectorConfig
in zip(ccdParams.values(), detectorConfigList):
61 detector = makeDetector(detectorConfig, ampInfoCatalog, focalPlaneToPupil)
62 detectorList.append(detector)
65 def _makeDetectorConfigList(self, ccdParams):
66 """!Make a list of detector configs
68 @return a list of detector configs (lsst.afw.cameraGeom.DetectorConfig)
71 for name, ccd
in ccdParams.items():
72 detectorConfig = cameraGeom.DetectorConfig()
73 detectorConfigs.append(detectorConfig)
75 detectorConfig.name = name
76 detectorConfig.id = ccd[
'id']
77 detectorConfig.serial = ccd[
'serial']
78 detectorConfig.detectorType = ccd[
'detectorType']
80 detectorConfig.bbox_x0, detectorConfig.bbox_y0 = ccd[
'bbox'][0]
81 detectorConfig.bbox_x1, detectorConfig.bbox_y1 = ccd[
'bbox'][1]
82 detectorConfig.pixelSize_x, detectorConfig.pixelSize_y = ccd[
'pixelSize']
83 detectorConfig.transformDict.nativeSys = ccd[
'transformDict'][
'nativeSys']
84 transforms = ccd[
'transformDict'][
'transforms']
85 detectorConfig.transformDict.transforms =
None if transforms ==
'None' else transforms
86 detectorConfig.refpos_x, detectorConfig.refpos_y = ccd[
'refpos']
87 detectorConfig.offset_x, detectorConfig.offset_y = ccd[
'offset']
88 detectorConfig.transposeDetector = ccd[
'transposeDetector']
89 detectorConfig.pitchDeg = ccd[
'pitch']
90 detectorConfig.yawDeg = ccd[
'yaw']
91 detectorConfig.rollDeg = ccd[
'roll']
92 if 'crosstalk' in ccd:
93 detectorConfig.crosstalk = ccd[
'crosstalk']
95 return detectorConfigs
98 def _makeBBoxFromList(ylist):
99 """Given a list [(x0, y0), (xsize, ysize)], probably from a yaml file, return a BoxI
101 (x0, y0), (xsize, ysize) = ylist
102 return afwGeom.BoxI(afwGeom.PointI(x0, y0), afwGeom.ExtentI(xsize, ysize))
104 def _makeAmpInfoCatalog(self, ccd):
105 """Construct an amplifier info catalog
108 assert len(ccd[
'amplifiers']) > 0
109 amp = ccd[
'amplifiers'].values()[0]
112 xRawExtent, yRawExtent = rawBBox.getDimensions()
114 from lsst.afw.table
import LL, LR, UL, UR
115 readCorners = dict(LL = LL, LR = LR, UL = UL, UR = UR)
117 schema = AmpInfoTable.makeMinimalSchema()
119 linThreshKey = schema.addField(
'linearityThreshold', type=float)
120 linMaxKey = schema.addField(
'linearityMaximum', type=float)
121 linUnitsKey = schema.addField(
'linearityUnits', type=str, size=9)
122 hduKey = schema.addField(
'hdu', type=np.int32)
125 ampCatalog = AmpInfoCatalog(schema)
126 for name, amp
in sorted(ccd[
'amplifiers'].items(), key=
lambda x: x[1][
'hdu']):
127 record = ampCatalog.addNew()
129 record.set(hduKey, amp[
'hdu'])
132 perAmpData = amp[
'perAmpData']
136 x0, y0 = ix*xRawExtent, iy*yRawExtent
139 xDataExtent, yDataExtent = rawDataBBox.getDimensions()
140 record.setBBox(afwGeom.BoxI(
141 afwGeom.PointI(ix*xDataExtent, iy*yDataExtent), rawDataBBox.getDimensions()))
144 rawBBox.shift(afwGeom.ExtentI(x0, y0))
145 record.setRawBBox(rawBBox)
148 rawDataBBox.shift(afwGeom.ExtentI(x0, y0))
149 record.setRawDataBBox(rawDataBBox)
152 rawSerialOverscanBBox.shift(afwGeom.ExtentI(x0, y0))
153 record.setRawHorizontalOverscanBBox(rawSerialOverscanBBox)
156 rawParallelOverscanBBox.shift(afwGeom.ExtentI(x0, y0))
157 record.setRawVerticalOverscanBBox(rawParallelOverscanBBox)
160 rawSerialPrescanBBox.shift(afwGeom.ExtentI(x0, y0))
161 record.setRawPrescanBBox(rawSerialPrescanBBox)
164 record.setRawXYOffset(afwGeom.Extent2I(ix*xRawExtent, iy*yRawExtent))
166 record.setRawXYOffset(afwGeom.Extent2I(0, 0))
168 record.setReadoutCorner(readCorners[amp[
'readCorner']])
169 record.setGain(amp[
'gain'])
170 record.setReadNoise(amp[
'readNoise'])
171 record.setSaturation(amp[
'saturation'])
172 record.setHasRawInfo(
True)
174 flipX, flipY = amp.get(
"flipXY")
176 record.setRawFlipX(flipX)
177 record.setRawFlipY(flipY)
179 record.setLinearityCoeffs([float(val)
for val
in amp[
'linearityCoeffs']])
180 record.setLinearityType(amp[
'linearityType'])
181 record.set(linThreshKey, float(amp[
'linearityThreshold']))
182 record.set(linMaxKey, float(amp[
'linearityMax']))
183 record.set(linUnitsKey,
"DN")
def _makeDetectorList
Make a list of detectors.
def _makeDetectorConfigList
Make a list of detector configs.