LSSTApplications  11.0-13-gbb96280,12.1.rc1,12.1.rc1+1,12.1.rc1+2,12.1.rc1+5,12.1.rc1+8,12.1.rc1-1-g06d7636+1,12.1.rc1-1-g253890b+5,12.1.rc1-1-g3d31b68+7,12.1.rc1-1-g3db6b75+1,12.1.rc1-1-g5c1385a+3,12.1.rc1-1-g83b2247,12.1.rc1-1-g90cb4cf+6,12.1.rc1-1-g91da24b+3,12.1.rc1-2-g3521f8a,12.1.rc1-2-g39433dd+4,12.1.rc1-2-g486411b+2,12.1.rc1-2-g4c2be76,12.1.rc1-2-gc9c0491,12.1.rc1-2-gda2cd4f+6,12.1.rc1-3-g3391c73+2,12.1.rc1-3-g8c1bd6c+1,12.1.rc1-3-gcf4b6cb+2,12.1.rc1-4-g057223e+1,12.1.rc1-4-g19ed13b+2,12.1.rc1-4-g30492a7
LSSTDataManagementBasePackage
testCamera.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2014 LSST Corporation.
4 #
5 # This product includes software developed by the
6 # LSST Project (http://www.lsst.org/).
7 #
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the LSST License Statement and
19 # the GNU General Public License along with this program. If not,
20 # see <http://www.lsstcorp.org/LegalNotices/>.
21 #
22 import numpy as np
23 
24 import lsst.afw.cameraGeom as cameraGeom
25 import lsst.afw.geom as afwGeom
26 from lsst.afw.table import AmpInfoCatalog, AmpInfoTable, LL
27 from lsst.afw.cameraGeom import NullLinearityType
28 from lsst.afw.cameraGeom.cameraFactory import makeDetector
29 
30 __all__ = ["TestCamera"]
31 
32 
33 class TestCamera(cameraGeom.Camera):
34  """A simple test Camera
35 
36  There is one ccd with name "0"
37  It has four amplifiers with names "00", "01", "10", and "11"
38 
39  The camera is modeled after a small portion of the LSST sim Summer 2012 camera:
40  a single detector with four amplifiers, consisting of
41  raft 2,2 sensor 0,0, half of channels 0,0 0,1 1,0 and 1,1 (the half closest to the Y centerline)
42 
43  Note that the Summer 2012 camera has one very weird feature: the bias region
44  (rawHOverscanBbox) is actually a prescan (appears before the data pixels).
45 
46  A raw image has the sky in the same orientation on all amplifier subregions,
47  so no amplifier subregions need their pixels to be flipped.
48 
49  Standard keys are:
50  amp: amplifier number: one of 00, 01, 10, 11
51  ccd: ccd number: always 0
52  visit: exposure number; test data includes one exposure with visit=1
53  """
54 
55  def __init__(self):
56  """Construct a TestCamera
57  """
58  plateScale = afwGeom.Angle(20, afwGeom.arcseconds) # plate scale, in angle on sky/mm
59  radialDistortion = 0.925 # radial distortion in mm/rad^2
60  radialCoeff = np.array((0.0, 1.0, 0.0, radialDistortion)) / plateScale.asRadians()
61  focalPlaneToPupil = afwGeom.RadialXYTransform(radialCoeff)
62  pupilToFocalPlane = afwGeom.InvertedXYTransform(focalPlaneToPupil)
63  cameraTransformMap = cameraGeom.CameraTransformMap(cameraGeom.FOCAL_PLANE,
64  {cameraGeom.PUPIL: pupilToFocalPlane})
65  detectorList = self._makeDetectorList(pupilToFocalPlane)
66  cameraGeom.Camera.__init__(self, "test", detectorList, cameraTransformMap)
67 
68  def _makeDetectorList(self, focalPlaneToPupil):
69  """Make a list of detectors
70 
71  @param[in] focalPlaneToPupil lsst.afw.geom.XYTransform from FOCAL_PLANE to PUPIL coordinates
72  @return a list of detectors (lsst.afw.cameraGeom.Detector)
73  """
74  detectorList = []
75  detectorConfigList = self._makeDetectorConfigList()
76  for detectorConfig in detectorConfigList:
77  ampInfoCatalog = self._makeAmpInfoCatalog()
78  detector = makeDetector(detectorConfig, ampInfoCatalog, focalPlaneToPupil)
79  detectorList.append(detector)
80  return detectorList
81 
83  """Make a list of detector configs
84 
85  @return a list of detector configs (lsst.afw.cameraGeom.DetectorConfig)
86  """
87  # this camera has one detector that corresponds to a subregion of lsstSim detector R:2,2 S:0,0
88  # with lower left corner 0, 1000 and dimensions 1018 x 2000
89  # i.e. half of each of the following channels: 0,0, 0,1, 1,0 and 1,1
90  detector0Config = cameraGeom.DetectorConfig()
91  detector0Config.name = '0'
92  detector0Config.id = 0
93  detector0Config.serial = '0000011'
94  detector0Config.detectorType = 0
95  detector0Config.bbox_x0 = 0
96  detector0Config.bbox_x1 = 1017
97  detector0Config.bbox_y0 = 0
98  detector0Config.bbox_y1 = 1999
99  detector0Config.pixelSize_x = 0.01
100  detector0Config.pixelSize_y = 0.01
101  detector0Config.transformDict.nativeSys = 'Pixels'
102  detector0Config.transformDict.transforms = None
103  detector0Config.refpos_x = 2035.5
104  detector0Config.refpos_y = 999.5
105  detector0Config.offset_x = -42.26073
106  detector0Config.offset_y = -42.21914
107  detector0Config.transposeDetector = False
108  detector0Config.pitchDeg = 0.0
109  detector0Config.yawDeg = 90.0
110  detector0Config.rollDeg = 0.0
111  return [detector0Config]
112 
114  """Construct an amplifier info catalog
115 
116  The LSSTSim S12 amplifiers are unusual in that they start with 4 pixels
117  of usable bias region (which is used to set rawHOverscanBbox, despite the name),
118  followed by the data. There is no other underscan or overscan.
119  """
120  xDataExtent = 509 # trimmed
121  yDataExtent = 1000
122  xBiasExtent = 4
123  xRawExtent = xDataExtent + xBiasExtent
124  yRawExtent = yDataExtent
125  readNoise = 3.975 # amplifier read noise, in e-
126  saturationLevel = 65535
127  linearityType = NullLinearityType
128  linearityCoeffs = [0, 0, 0, 0]
129 
130  schema = AmpInfoTable.makeMinimalSchema()
131 
132  self.ampInfoDict = {}
133  ampCatalog = AmpInfoCatalog(schema)
134  for ampX in (0, 1):
135  for ampY in (0, 1):
136  # amplifier gain (e-/ADU) and read noiuse (ADU/pixel) from lsstSim raw data
137  # note that obs_test amp <ampX><ampY> = lsstSim amp C<ampY>,<ampX> (axes are swapped)
138  gain = {
139  (0, 0): 1.7741, # C0,0
140  (0, 1): 1.65881, # C1,0
141  (1, 0): 1.74151, # C0,1
142  (1, 1): 1.67073, # C1,1
143  }[(ampX, ampY)]
144  readNoise = {
145  (0, 0): 3.97531706217237, # C0,0
146  (0, 1): 4.08263755342685, # C1,0
147  (1, 0): 4.02753931932633, # C0,1
148  (1, 1): 4.1890610691135, # C1,1
149  }[(ampX, ampY)]
150  record = ampCatalog.addNew()
151  record.setName("%d%d" % (ampX, ampY))
152  record.setBBox(afwGeom.Box2I(
153  afwGeom.Point2I(ampX * xDataExtent, ampY * yDataExtent),
154  afwGeom.Extent2I(xDataExtent, yDataExtent),
155  ))
156 
157  x0Raw = ampX * xRawExtent
158  y0Raw = ampY * yRawExtent
159 
160  # bias region (which is prescan, in this case) is before the data
161  readCorner = LL
162  x0Bias = x0Raw
163  x0Data = x0Bias + xBiasExtent
164 
165  record.setRawBBox(afwGeom.Box2I(
166  afwGeom.Point2I(x0Raw, y0Raw),
167  afwGeom.Extent2I(xRawExtent, yRawExtent),
168  ))
169  record.setRawDataBBox(afwGeom.Box2I(
170  afwGeom.Point2I(x0Data, y0Raw),
171  afwGeom.Extent2I(xDataExtent, yDataExtent),
172  ))
173  record.setRawHorizontalOverscanBBox(afwGeom.Box2I(
174  afwGeom.Point2I(x0Bias, y0Raw),
175  afwGeom.Extent2I(xBiasExtent, yRawExtent),
176  ))
177  record.setRawXYOffset(afwGeom.Extent2I(x0Raw, y0Raw))
178  record.setReadoutCorner(readCorner)
179  record.setGain(gain)
180  record.setReadNoise(readNoise)
181  record.setSaturation(saturationLevel)
182  record.setSuspectLevel(float("nan"))
183  record.setLinearityCoeffs([float(val) for val in linearityCoeffs])
184  record.setLinearityType(linearityType)
185  record.setHasRawInfo(True)
186  record.setRawFlipX(False)
187  record.setRawFlipY(False)
188  record.setRawVerticalOverscanBBox(afwGeom.Box2I()) # no vertical overscan
189  record.setRawPrescanBBox(afwGeom.Box2I()) # no horizontal prescan
190  return ampCatalog
An integer coordinate rectangle.
Definition: Box.h:53
Wrap an XYTransform, swapping forward and reverse transforms.
Definition: XYTransform.h:107
CatalogT< AmpInfoRecord > AmpInfoCatalog
Definition: fwd.h:87
def makeDetector
Make a Detector instance from a detector config and amp info catalog.
A purely radial polynomial distortion, up to 6th order.
Definition: XYTransform.h:186