LSSTApplications  19.0.0-10-g920eed2,19.0.0-11-g48a0200+2,19.0.0-18-gfc4e62b+17,19.0.0-2-g3b2f90d+2,19.0.0-2-gd671419+5,19.0.0-20-g5a5a17ab+15,19.0.0-21-g2644856+18,19.0.0-23-g84eeccb+6,19.0.0-24-g878c510+5,19.0.0-25-g6c8df7140,19.0.0-25-gb330496+5,19.0.0-3-g2b32d65+5,19.0.0-3-g8227491+16,19.0.0-3-g9c54d0d+16,19.0.0-3-gca68e65+12,19.0.0-3-gcfc5f51+5,19.0.0-3-ge110943+15,19.0.0-3-ge74d124,19.0.0-3-gfe04aa6+16,19.0.0-30-g9c3fd16+6,19.0.0-4-g06f5963+5,19.0.0-4-g3d16501+18,19.0.0-4-g4a9c019+5,19.0.0-4-g5a8b323,19.0.0-4-g66397f0+1,19.0.0-4-g8278b9b+1,19.0.0-4-g8557e14,19.0.0-4-g8964aba+17,19.0.0-4-ge404a01+16,19.0.0-5-g40f3a5a,19.0.0-5-g4db63b3,19.0.0-5-gfb03ce7+17,19.0.0-6-gbaebbfb+16,19.0.0-61-gec4c6e08+6,19.0.0-7-g039c0b5+16,19.0.0-7-gbea9075+4,19.0.0-7-gc567de5+17,19.0.0-70-g334bf3e+1,19.0.0-9-g463f923+16,b.20.0.x-g5487ab2134,v20.0.0.rc1
LSSTDataManagementBasePackage
testUtils.py
Go to the documentation of this file.
1 # This file is part of afw.
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 
22 __all__ = ["DetectorWrapper", "CameraWrapper"]
23 
24 import os
25 
26 import numpy as np
27 
28 import lsst.utils
29 import lsst.geom
30 import lsst.afw.geom as afwGeom
31 from lsst.utils.tests import inTestCase
32 from .cameraSys import CameraSys, PIXELS, TAN_PIXELS, FIELD_ANGLE, FOCAL_PLANE, ACTUAL_PIXELS
33 from .orientation import Orientation
34 from .amplifier import Amplifier, ReadoutCorner
35 from .camera import Camera
36 from .detector import DetectorType
37 from .cameraConfig import DetectorConfig, CameraConfig
38 from .cameraFactory import makeCameraFromAmpLists
39 from .makePixelToTanPixel import makePixelToTanPixel
40 from .transformConfig import TransformMapConfig
41 
42 
44  """A Detector and the data used to construct it
45 
46  Intended for use with unit tests, thus saves a copy of all input parameters.
47  Does not support setting details of amplifiers.
48 
49  Parameters
50  ----------
51  name : `str` (optional)
52  Detector name.
53  id : `int` (optional)
54  Detector ID.
55  detType : `lsst.afw.cameraGeom.DetectorType` (optional)
56  Detector type.
57  serial : `str` (optional)
58  Serial "number".
59  bbox : `lsst.geom.Box2I` (optional)
60  Bounding box; defaults to (0, 0), (1024x1024).
61  numAmps : `int` (optional)
62  Number of amplifiers.
63  pixelSize : `lsst.geom.Point2D` (optional)
64  Pixel size (mm).
65  ampExtent : `lsst.geom.Extent2I` (optional)
66  Dimensions of amplifier image bbox.
67  orientation : `lsst.afw.cameraGeom.Orientation` (optional)
68  Orientation of CCC in focal plane.
69  plateScale : `float` (optional)
70  Plate scale in arcsec/mm; 20.0 is for LSST.
71  radialDistortion : `float` (optional)
72  Radial distortion, in mm/rad^2.
73  The r^3 coefficient of the radial distortion polynomial
74  that converts FIELD_ANGLE in radians to FOCAL_PLANE in mm;
75  0.925 is the value Dave Monet measured for lsstSim data
76  crosstalk : `iterable` (optional)
77  Crosstalk coefficient matrix. If None, then no crosstalk correction
78  can be performed.
79  modFunc : `callable` (optional)
80  A function that can modify attributes just before constructing the
81  detector; modFunc receives one argument: a DetectorWrapper with all
82  attributes except detector set.
83  physicalType : `str` (optional)
84  The physical type of the device, e.g. CCD, E2V, HgCdTe
85  """
86 
87  def __init__(self,
88  name="detector 1",
89  id=1,
90  detType=DetectorType.SCIENCE,
91  serial="xkcd722",
92  bbox=None, # do not use mutable objects as defaults
93  numAmps=3,
94  pixelSize=(0.02, 0.02),
95  ampExtent=(5, 6),
96  orientation=Orientation(),
97  plateScale=20.0,
98  radialDistortion=0.925,
99  crosstalk=None,
100  modFunc=None,
101  physicalType="CCD",
102  cameraBuilder=None
103  ):
104  # note that (0., 0.) for the reference position is the center of the
105  # first pixel
106  self.name = name
107  self.id = int(id)
108  self.type = detType
109  self.serial = serial
110  if bbox is None:
111  bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(1024, 1048))
112  self.bbox = bbox
113  self.pixelSize = lsst.geom.Extent2D(*pixelSize)
114  self.ampExtent = lsst.geom.Extent2I(*ampExtent)
115  self.plateScale = float(plateScale)
116  self.orientation = orientation
117  self.radialDistortion = float(radialDistortion)
118 
119  # compute TAN_PIXELS transform
120  pScaleRad = lsst.geom.arcsecToRad(self.plateScale)
121  radialDistortCoeffs = [0.0, 1.0/pScaleRad,
122  0.0, self.radialDistortion/pScaleRad]
123  focalPlaneToField = afwGeom.makeRadialTransform(radialDistortCoeffs)
124  pixelToTanPixel = makePixelToTanPixel(
125  bbox=self.bbox,
126  orientation=self.orientation,
127  focalPlaneToField=focalPlaneToField,
128  pixelSizeMm=self.pixelSize,
129  )
130  tanPixelSys = CameraSys(TAN_PIXELS, self.name)
131  actualPixelSys = CameraSys(ACTUAL_PIXELS, self.name)
132  self.transMap = {
133  FOCAL_PLANE: self.orientation.makePixelFpTransform(self.pixelSize),
134  tanPixelSys: pixelToTanPixel,
135  actualPixelSys: afwGeom.makeRadialTransform([0, 0.95, 0.01]),
136  }
137  if crosstalk is None:
138  crosstalk = [[0.0 for _ in range(numAmps)] for _ in range(numAmps)]
139  self.crosstalk = crosstalk
140  self.physicalType = physicalType
141  if cameraBuilder is None:
142  cameraBuilder = Camera.Builder("CameraForDetectorWrapper")
143  self.ampList = []
144  for i in range(numAmps):
145  ampBuilder = Amplifier.Builder()
146  ampName = f"amp {i + 1}"
147  ampBuilder.setName(ampName)
148  ampBuilder.setBBox(lsst.geom.Box2I(lsst.geom.Point2I(-1, 1), self.ampExtent))
149  ampBuilder.setGain(1.71234e3)
150  ampBuilder.setReadNoise(0.521237e2)
151  ampBuilder.setReadoutCorner(ReadoutCorner.LL)
152  self.ampList.append(ampBuilder)
153  if modFunc:
154  modFunc(self)
155  detectorBuilder = cameraBuilder.add(self.name, self.id)
156  detectorBuilder.setType(self.type)
157  detectorBuilder.setSerial(self.serial)
158  detectorBuilder.setPhysicalType(self.physicalType)
159  detectorBuilder.setBBox(self.bbox)
160  detectorBuilder.setOrientation(self.orientation)
161  detectorBuilder.setPixelSize(self.pixelSize)
162  detectorBuilder.setTransformFromPixelsTo(tanPixelSys, self.transMap[tanPixelSys])
163  detectorBuilder.setTransformFromPixelsTo(actualPixelSys, self.transMap[actualPixelSys])
164  detectorBuilder.setCrosstalk(np.array(self.crosstalk, dtype=np.float32))
165  for ampBuilder in self.ampList:
166  detectorBuilder.append(ampBuilder)
167  camera = cameraBuilder.finish()
168  self.detector = camera[self.name]
169 
170 
172  """A simple Camera and the data used to construct it
173 
174  Intended for use with unit tests, thus saves some interesting information.
175 
176  Parameters
177  ----------
178  plateScale : `float`
179  Plate scale in arcsec/mm; 20.0 is for LSST.
180  radialDistortion : `float`
181  Radial distortion, in mm/rad^2.
182  The r^3 coefficient of the radial distortion polynomial
183  that converts FIELD_ANGLE in radians to FOCAL_PLANE in mm;
184  0.925 is the value Dave Monet measured for lsstSim data.
185  isLsstLike : `bool`.
186  Make repository products with one raw image per amplifier (True)
187  or with one raw image per detector (False).
188  """
189 
190  def __init__(self, plateScale=20.0, radialDistortion=0.925, isLsstLike=False):
191  afwDir = lsst.utils.getPackageDir("afw")
192  self._afwTestDataDir = os.path.join(afwDir, "python", "lsst", "afw",
193  "cameraGeom", "testData")
194 
195  # Info to store for unit tests
196  self.plateScale = float(plateScale)
197  self.radialDistortion = float(radialDistortion)
199  self.detectorIdList = []
200  self.ampDataDict = {} # ampData[Dict]: raw dictionaries of test data fields
201 
202  # ampList[Dict]: actual cameraGeom.Amplifier objects
203  self.camConfig, self.ampListDict = self.makeTestRepositoryItems(
204  isLsstLike)
206  self.camConfig, self.ampListDict)
207 
208  @property
209  def nDetectors(self):
210  """Return the number of detectors"""
211  return len(self.detectorNameList)
212 
213  def makeDetectorConfigs(self, detFile):
214  """Construct a list of DetectorConfig, one per detector
215  """
216  detectors = []
217  self.detectorNameList = []
218  self.detectorIdList = []
219  with open(detFile) as fh:
220  names = fh.readline().rstrip().lstrip("#").split("|")
221  for l in fh:
222  els = l.rstrip().split("|")
223  detectorProps = dict([(name, el)
224  for name, el in zip(names, els)])
225  detectors.append(detectorProps)
226  detectorConfigs = []
227  for i, detector in enumerate(detectors):
228  detectorId = (i + 1) * 10 # to avoid simple 0, 1, 2...
229  detectorName = detector['name']
230  detConfig = DetectorConfig()
231  detConfig.name = detectorName
232  detConfig.id = detectorId
233  detConfig.bbox_x0 = 0
234  detConfig.bbox_y0 = 0
235  detConfig.bbox_x1 = int(detector['npix_x']) - 1
236  detConfig.bbox_y1 = int(detector['npix_y']) - 1
237  detConfig.serial = str(detector['serial'])
238  detConfig.detectorType = int(detector['detectorType'])
239  detConfig.offset_x = float(detector['x'])
240  detConfig.offset_y = float(detector['y'])
241  detConfig.refpos_x = float(detector['refPixPos_x'])
242  detConfig.refpos_y = float(detector['refPixPos_y'])
243  detConfig.yawDeg = float(detector['yaw'])
244  detConfig.pitchDeg = float(detector['pitch'])
245  detConfig.rollDeg = float(detector['roll'])
246  detConfig.pixelSize_x = float(detector['pixelSize'])
247  detConfig.pixelSize_y = float(detector['pixelSize'])
248  detConfig.transposeDetector = False
249  detConfig.transformDict.nativeSys = PIXELS.getSysName()
250  detectorConfigs.append(detConfig)
251  self.detectorNameList.append(detectorName)
252  self.detectorIdList.append(detectorId)
253  return detectorConfigs
254 
255  def makeAmpLists(self, ampFile, isLsstLike=False):
256  """Construct a dict of list of Amplifer, one list per detector.
257 
258  Parameters
259  ----------
260  ampFile : `str`
261  Path to amplifier data file.
262  isLsstLike : `bool`
263  If True then there is one raw image per amplifier;
264  if False then there is one raw image per detector.
265  """
266  readoutMap = {
267  'LL': ReadoutCorner.LL,
268  'LR': ReadoutCorner.LR,
269  'UR': ReadoutCorner.UR,
270  'UL': ReadoutCorner.UL,
271  }
272  ampDataList = []
273  with open(ampFile) as fh:
274  names = fh.readline().rstrip().lstrip("#").split("|")
275  for l in fh:
276  els = l.rstrip().split("|")
277  ampProps = dict([(name, el) for name, el in zip(names, els)])
278  ampDataList.append(ampProps)
279  ampListDict = {}
280  self.ampDataDict = {}
281  for ampData in ampDataList:
282  if ampData['ccd_name'] in ampListDict:
283  ampList = ampListDict[ampData['ccd_name']]
284  self.ampDataDict[ampData['ccd_name']]['namps'] += 1
285  else:
286  ampList = []
287  ampListDict[ampData['ccd_name']] = ampList
288  self.ampDataDict[ampData['ccd_name']] = {'namps': 1, 'linInfo': {}}
289  builder = Amplifier.Builder()
290  bbox = lsst.geom.Box2I(lsst.geom.Point2I(int(ampData['trimmed_xmin']),
291  int(ampData['trimmed_ymin'])),
292  lsst.geom.Point2I(int(ampData['trimmed_xmax']),
293  int(ampData['trimmed_ymax'])))
294  rawBbox = lsst.geom.Box2I(lsst.geom.Point2I(int(ampData['raw_xmin']),
295  int(ampData['raw_ymin'])),
296  lsst.geom.Point2I(int(ampData['raw_xmax']),
297  int(ampData['raw_ymax'])))
298  rawDataBbox = lsst.geom.Box2I(
299  lsst.geom.Point2I(int(ampData['raw_data_xmin']),
300  int(ampData['raw_data_ymin'])),
301  lsst.geom.Point2I(int(ampData['raw_data_xmax']),
302  int(ampData['raw_data_ymax'])))
303  rawHOverscanBbox = lsst.geom.Box2I(
304  lsst.geom.Point2I(int(ampData['hoscan_xmin']),
305  int(ampData['hoscan_ymin'])),
306  lsst.geom.Point2I(int(ampData['hoscan_xmax']),
307  int(ampData['hoscan_ymax'])))
308  rawVOverscanBbox = lsst.geom.Box2I(
309  lsst.geom.Point2I(int(ampData['voscan_xmin']),
310  int(ampData['voscan_ymin'])),
311  lsst.geom.Point2I(int(ampData['voscan_xmax']),
312  int(ampData['voscan_ymax'])))
313  rawPrescanBbox = lsst.geom.Box2I(
314  lsst.geom.Point2I(int(ampData['pscan_xmin']),
315  int(ampData['pscan_ymin'])),
316  lsst.geom.Point2I(int(ampData['pscan_xmax']),
317  int(ampData['pscan_ymax'])))
318  xoffset = int(ampData['x_offset'])
319  yoffset = int(ampData['y_offset'])
320  flipx = bool(int(ampData['flipx']))
321  flipy = bool(int(ampData['flipy']))
322  readcorner = 'LL'
323  if not isLsstLike:
324  offext = lsst.geom.Extent2I(xoffset, yoffset)
325  if flipx:
326  xExt = rawBbox.getDimensions().getX()
327  rawBbox.flipLR(xExt)
328  rawDataBbox.flipLR(xExt)
329  rawHOverscanBbox.flipLR(xExt)
330  rawVOverscanBbox.flipLR(xExt)
331  rawPrescanBbox.flipLR(xExt)
332  if flipy:
333  yExt = rawBbox.getDimensions().getY()
334  rawBbox.flipTB(yExt)
335  rawDataBbox.flipTB(yExt)
336  rawHOverscanBbox.flipTB(yExt)
337  rawVOverscanBbox.flipTB(yExt)
338  rawPrescanBbox.flipTB(yExt)
339  if not flipx and not flipy:
340  readcorner = 'LL'
341  elif flipx and not flipy:
342  readcorner = 'LR'
343  elif flipx and flipy:
344  readcorner = 'UR'
345  elif not flipx and flipy:
346  readcorner = 'UL'
347  else:
348  raise RuntimeError("Couldn't find read corner")
349 
350  flipx = False
351  flipy = False
352  rawBbox.shift(offext)
353  rawDataBbox.shift(offext)
354  rawHOverscanBbox.shift(offext)
355  rawVOverscanBbox.shift(offext)
356  rawPrescanBbox.shift(offext)
357  xoffset = 0
358  yoffset = 0
359  offset = lsst.geom.Extent2I(xoffset, yoffset)
360  builder.setBBox(bbox)
361  builder.setRawXYOffset(offset)
362  builder.setName(str(ampData['name']))
363  builder.setReadoutCorner(readoutMap[readcorner])
364  builder.setGain(float(ampData['gain']))
365  builder.setReadNoise(float(ampData['readnoise']))
366  linCoeffs = np.array([float(ampData['lin_coeffs']), ], dtype=float)
367  builder.setLinearityCoeffs(linCoeffs)
368  builder.setLinearityType(str(ampData['lin_type']))
369  builder.setRawFlipX(flipx)
370  builder.setRawFlipY(flipy)
371  builder.setRawBBox(rawBbox)
372  builder.setRawDataBBox(rawDataBbox)
373  builder.setRawHorizontalOverscanBBox(rawHOverscanBbox)
374  builder.setRawVerticalOverscanBBox(rawVOverscanBbox)
375  builder.setRawPrescanBBox(rawPrescanBbox)
376  builder.setLinearityThreshold(float(ampData['lin_thresh']))
377  builder.setLinearityMaximum(float(ampData['lin_max']))
378  builder.setLinearityUnits(str(ampData['lin_units']))
379  self.ampDataDict[ampData['ccd_name']]['linInfo'][ampData['name']] = \
380  {'lincoeffs': linCoeffs, 'lintype': str(ampData['lin_type']),
381  'linthresh': float(ampData['lin_thresh']), 'linmax': float(ampData['lin_max']),
382  'linunits': str(ampData['lin_units'])}
383  ampList.append(builder)
384  return ampListDict
385 
386  def makeTestRepositoryItems(self, isLsstLike=False):
387  """Make camera config and amp catalog dictionary, using default
388  detector and amp files.
389 
390  Parameters
391  ----------
392  isLsstLike : `bool`
393  If True then there is one raw image per amplifier;
394  if False then there is one raw image per detector.
395  """
396  detFile = os.path.join(self._afwTestDataDir, "testCameraDetectors.dat")
397  detectorConfigs = self.makeDetectorConfigs(detFile)
398  ampFile = os.path.join(self._afwTestDataDir, "testCameraAmps.dat")
399  ampListDict = self.makeAmpLists(ampFile, isLsstLike=isLsstLike)
400  camConfig = CameraConfig()
401  camConfig.name = "testCamera%s"%('LSST' if isLsstLike else 'SC')
402  camConfig.detectorList = dict((i, detConfig)
403  for i, detConfig in enumerate(detectorConfigs))
404  camConfig.plateScale = self.plateScale
405  pScaleRad = lsst.geom.arcsecToRad(self.plateScale)
406  radialDistortCoeffs = [0.0, 1.0/pScaleRad,
407  0.0, self.radialDistortion/pScaleRad]
408  tConfig = afwGeom.TransformConfig()
409  tConfig.transform.name = 'inverted'
410  radialClass = afwGeom.transformRegistry['radial']
411  tConfig.transform.active.transform.retarget(radialClass)
412  tConfig.transform.active.transform.coeffs = radialDistortCoeffs
413  tmc = TransformMapConfig()
414  tmc.nativeSys = FOCAL_PLANE.getSysName()
415  tmc.transforms = {FIELD_ANGLE.getSysName(): tConfig}
416  camConfig.transformDict = tmc
417  return camConfig, ampListDict
418 
419 
420 @inTestCase
421 def compare2DFunctions(self, func1, func2, minVal=-10, maxVal=None, nVal=5):
422  """Compare two Point2D(Point2D) functions by evaluating them over a
423  range of values.
424  """
425  if maxVal is None:
426  maxVal = -minVal
427  dVal = (maxVal - minVal) / (nVal - 1)
428  for xInd in range(nVal):
429  x = minVal + (xInd * dVal)
430  for yInd in range(nVal):
431  y = minVal + (yInd * dVal)
432  fromPoint = lsst.geom.Point2D(x, y)
433  res1 = func1(fromPoint)
434  res2 = func2(fromPoint)
435  self.assertPairsAlmostEqual(res1, res2)
436 
437 
438 @inTestCase
439 def assertTransformMapsEqual(self, map1, map2, **kwds):
440  """Compare two TransformMaps.
441  """
442  self.assertEqual(list(map1), list(map2)) # compares the sets of CameraSys
443  for sysFrom in map1:
444  for sysTo in map1:
445  with self.subTest(sysFrom=sysFrom, sysTo=sysTo):
446  transform1 = map1.getTransform(sysFrom, sysTo)
447  transform2 = map2.getTransform(sysFrom, sysTo)
448  self.compare2DFunctions(transform1.applyForward, transform2.applyForward, **kwds)
449  self.compare2DFunctions(transform1.applyInverse, transform2.applyInverse, **kwds)
450 
451 
452 @inTestCase
453 def assertAmplifiersEqual(self, amp1, amp2):
454  self.assertEqual(amp1.getName(), amp2.getName())
455  self.assertEqual(amp1.getBBox(), amp2.getBBox())
456  self.assertEqual(amp1.getGain(), amp2.getGain())
457  self.assertEqual(amp1.getReadNoise(), amp2.getReadNoise())
458  self.assertEqual(amp1.getSaturation(), amp2.getSaturation())
459  self.assertEqual(amp1.getReadoutCorner(), amp2.getReadoutCorner())
460  self.assertEqual(amp1.getSuspectLevel(), amp2.getSuspectLevel())
461  self.assertEqual(amp1.getLinearityCoeffs().shape, amp2.getLinearityCoeffs().shape)
462  self.assertFloatsEqual(amp1.getLinearityCoeffs(), amp2.getLinearityCoeffs())
463  self.assertEqual(amp1.getLinearityType(), amp2.getLinearityType())
464  self.assertEqual(amp1.getLinearityThreshold(), amp2.getLinearityThreshold())
465  self.assertEqual(amp1.getLinearityMaximum(), amp2.getLinearityMaximum())
466  self.assertEqual(amp1.getLinearityUnits(), amp2.getLinearityUnits())
467  self.assertEqual(amp1.getRawBBox(), amp2.getRawBBox())
468  self.assertEqual(amp1.getRawDataBBox(), amp2.getRawDataBBox())
469  self.assertEqual(amp1.getRawFlipX(), amp2.getRawFlipX())
470  self.assertEqual(amp1.getRawFlipY(), amp2.getRawFlipY())
471  self.assertEqual(amp1.getRawHorizontalOverscanBBox(), amp2.getRawHorizontalOverscanBBox())
472  self.assertEqual(amp1.getRawVerticalOverscanBBox(), amp2.getRawVerticalOverscanBBox())
473  self.assertEqual(amp1.getRawPrescanBBox(), amp2.getRawPrescanBBox())
474 
475 
476 @inTestCase
477 def assertDetectorsEqual(self, detector1, detector2, **kwds):
478  """Compare two Detectors.
479  """
480  self.assertEqual(detector1.getName(), detector2.getName())
481  self.assertEqual(detector1.getId(), detector2.getId())
482  self.assertEqual(detector1.getSerial(), detector2.getSerial())
483  self.assertEqual(detector1.getPhysicalType(), detector2.getPhysicalType())
484  self.assertEqual(detector1.getBBox(), detector2.getBBox())
485  self.assertEqual(detector1.getPixelSize(), detector2.getPixelSize())
486  orientationIn = detector1.getOrientation()
487  orientationOut = detector2.getOrientation()
488  self.assertEqual(orientationIn.getFpPosition(), orientationOut.getFpPosition())
489  self.assertEqual(orientationIn.getReferencePoint(), orientationOut.getReferencePoint())
490  self.assertEqual(orientationIn.getYaw(), orientationOut.getYaw())
491  self.assertEqual(orientationIn.getPitch(), orientationOut.getPitch())
492  self.assertEqual(orientationIn.getRoll(), orientationOut.getRoll())
493  self.assertFloatsEqual(detector1.getCrosstalk(), detector2.getCrosstalk())
494  self.assertTransformMapsEqual(detector1.getTransformMap(), detector2.getTransformMap(), **kwds)
495  self.assertEqual(len(detector1.getAmplifiers()), len(detector2.getAmplifiers()))
496  for amp1, amp2 in zip(detector1.getAmplifiers(), detector2.getAmplifiers()):
497  self.assertAmplifiersEqual(amp1, amp2)
498 
499 
500 @inTestCase
501 def assertDetectorCollectionsEqual(self, collection1, collection2, **kwds):
502  """Compare two DetectorCollections.
503  """
504  self.assertCountEqual(list(collection1.getNameIter()), list(collection2.getNameIter()))
505  for k in collection1.getNameIter():
506  self.assertDetectorsEqual(collection1[k], collection2[k], **kwds)
507 
508 
509 @inTestCase
510 def assertCamerasEqual(self, camera1, camera2, **kwds):
511  """Compare two Camers.
512  """
513  self.assertDetectorCollectionsEqual(camera1, camera2, **kwds)
514  self.assertTransformMapsEqual(camera1.getTransformMap(), camera2.getTransformMap())
515  self.assertEqual(camera1.getName(), camera2.getName())
516  self.assertEqual(camera1.getPupilFactoryName(), camera2.getPupilFactoryName())
lsst::afw::cameraGeom.testUtils.CameraWrapper.plateScale
plateScale
Definition: testUtils.py:196
lsst::afw::cameraGeom.testUtils.DetectorWrapper
Definition: testUtils.py:43
lsst::afw::cameraGeom.testUtils.CameraWrapper
Definition: testUtils.py:171
lsst::afw::cameraGeom.testUtils.DetectorWrapper.physicalType
physicalType
Definition: testUtils.py:124
lsst::afw::cameraGeom.testUtils.DetectorWrapper.ampExtent
ampExtent
Definition: testUtils.py:98
lsst::afw::cameraGeom.testUtils.CameraWrapper.detectorNameList
detectorNameList
Definition: testUtils.py:198
lsst::afw::cameraGeom.testUtils.DetectorWrapper.transMap
transMap
Definition: testUtils.py:116
lsst::afw::cameraGeom.transformConfig.TransformMapConfig
Definition: transformConfig.py:28
lsst::afw::cameraGeom.cameraConfig.CameraConfig
Definition: cameraConfig.py:132
lsst::afw::cameraGeom.testUtils.CameraWrapper.makeAmpLists
def makeAmpLists(self, ampFile, isLsstLike=False)
Definition: testUtils.py:255
ast::append
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33
lsst::afw::cameraGeom.testUtils.DetectorWrapper.crosstalk
crosstalk
Definition: testUtils.py:123
lsst::afw::cameraGeom.testUtils.CameraWrapper.ampListDict
ampListDict
Definition: testUtils.py:203
lsst::afw::cameraGeom.testUtils.DetectorWrapper.id
id
Definition: testUtils.py:91
lsst::afw::cameraGeom.testUtils.CameraWrapper.__init__
def __init__(self, plateScale=20.0, radialDistortion=0.925, isLsstLike=False)
Definition: testUtils.py:190
lsst::afw::cameraGeom.testUtils.CameraWrapper.radialDistortion
radialDistortion
Definition: testUtils.py:197
lsst::afw::cameraGeom.makePixelToTanPixel.makePixelToTanPixel
def makePixelToTanPixel(bbox, orientation, focalPlaneToField, pixelSizeMm)
Definition: makePixelToTanPixel.py:28
lsst::afw::cameraGeom.testUtils.assertDetectorCollectionsEqual
def assertDetectorCollectionsEqual(self, collection1, collection2, **kwds)
Definition: testUtils.py:501
lsst::afw::cameraGeom::Amplifier::Builder
A mutable Amplifier subclass class that can be used to incrementally construct or modify Amplifiers.
Definition: Amplifier.h:276
lsst::utils::getPackageDir
std::string getPackageDir(std::string const &packageName)
return the root directory of a setup package
Definition: packaging.cc:33
lsst::afw::cameraGeom.testUtils.DetectorWrapper.radialDistortion
radialDistortion
Definition: testUtils.py:101
lsst::afw::cameraGeom.testUtils.DetectorWrapper.__init__
def __init__(self, name="detector 1", id=1, detType=DetectorType.SCIENCE, serial="xkcd722", bbox=None, numAmps=3, pixelSize=(0.02, 0.02), ampExtent=(5, 6), orientation=Orientation(), plateScale=20.0, radialDistortion=0.925, crosstalk=None, modFunc=None, physicalType="CCD", cameraBuilder=None)
Definition: testUtils.py:87
lsst::afw::geom::makeRadialTransform
std::shared_ptr< TransformPoint2ToPoint2 > makeRadialTransform(std::vector< double > const &forwardCoeffs, std::vector< double > const &inverseCoeffs)
A purely radial polynomial distortion.
Definition: transformFactory.cc:183
lsst::afw::cameraGeom.testUtils.assertCamerasEqual
def assertCamerasEqual(self, camera1, camera2, **kwds)
Definition: testUtils.py:510
lsst::afw::cameraGeom.testUtils.CameraWrapper.camera
camera
Definition: testUtils.py:205
lsst::afw::cameraGeom.testUtils.compare2DFunctions
def compare2DFunctions(self, func1, func2, minVal=-10, maxVal=None, nVal=5)
Definition: testUtils.py:421
lsst::afw::cameraGeom.testUtils.CameraWrapper.ampDataDict
ampDataDict
Definition: testUtils.py:200
lsst::afw::cameraGeom.testUtils.CameraWrapper._afwTestDataDir
_afwTestDataDir
Definition: testUtils.py:192
lsst::afw::cameraGeom.testUtils.assertAmplifiersEqual
def assertAmplifiersEqual(self, amp1, amp2)
Definition: testUtils.py:453
lsst::afw::cameraGeom.testUtils.DetectorWrapper.bbox
bbox
Definition: testUtils.py:96
lsst::afw::cameraGeom.cameraConfig.DetectorConfig
Definition: cameraConfig.py:31
lsst::afw::cameraGeom.testUtils.assertTransformMapsEqual
def assertTransformMapsEqual(self, map1, map2, **kwds)
Definition: testUtils.py:439
lsst::utils
Definition: Backtrace.h:29
lsst::afw::cameraGeom.testUtils.DetectorWrapper.detector
detector
Definition: testUtils.py:152
lsst::afw::cameraGeom.testUtils.assertDetectorsEqual
def assertDetectorsEqual(self, detector1, detector2, **kwds)
Definition: testUtils.py:477
lsst::afw::cameraGeom.testUtils.CameraWrapper.makeTestRepositoryItems
def makeTestRepositoryItems(self, isLsstLike=False)
Definition: testUtils.py:386
lsst::utils.tests
Definition: tests.py:1
lsst::afw::geom.transformConfig.TransformConfig
Definition: transformConfig.py:189
lsst::afw::cameraGeom.testUtils.DetectorWrapper.serial
serial
Definition: testUtils.py:93
lsst::geom
Definition: geomOperators.dox:4
lsst::afw::cameraGeom.testUtils.DetectorWrapper.plateScale
plateScale
Definition: testUtils.py:99
lsst::afw::cameraGeom.testUtils.DetectorWrapper.orientation
orientation
Definition: testUtils.py:100
lsst::afw::cameraGeom.testUtils.CameraWrapper.makeDetectorConfigs
def makeDetectorConfigs(self, detFile)
Definition: testUtils.py:213
list
daf::base::PropertyList * list
Definition: fits.cc:913
lsst::geom::Point< int, 2 >
lsst::afw::cameraGeom::Camera::Builder
A helper class for creating and modifying cameras.
Definition: Camera.h:208
lsst::geom::Box2I
An integer coordinate rectangle.
Definition: Box.h:55
lsst::afw::cameraGeom.testUtils.DetectorWrapper.name
name
Definition: testUtils.py:90
lsst::afw::cameraGeom.cameraFactory.makeCameraFromAmpLists
def makeCameraFromAmpLists(cameraConfig, ampListDict, pupilFactoryClass=PupilFactory)
Definition: cameraFactory.py:156
lsst::afw::cameraGeom.testUtils.DetectorWrapper.type
type
Definition: testUtils.py:92
lsst::afw::cameraGeom.testUtils.CameraWrapper.detectorIdList
detectorIdList
Definition: testUtils.py:199
lsst::geom::Extent< int, 2 >
lsst::afw::cameraGeom.testUtils.CameraWrapper.nDetectors
def nDetectors(self)
Definition: testUtils.py:209
lsst::geom::arcsecToRad
constexpr double arcsecToRad(double x) noexcept
Definition: Angle.h:55
lsst::afw::cameraGeom.testUtils.DetectorWrapper.ampList
ampList
Definition: testUtils.py:127
lsst::afw::cameraGeom.testUtils.DetectorWrapper.pixelSize
pixelSize
Definition: testUtils.py:97
lsst::afw::geom
Definition: frameSetUtils.h:40