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