LSST Applications  21.0.0-172-gfb10e10a+18fedfabac,22.0.0+297cba6710,22.0.0+80564b0ff1,22.0.0+8d77f4f51a,22.0.0+a28f4c53b1,22.0.0+dcf3732eb2,22.0.1-1-g7d6de66+2a20fdde0d,22.0.1-1-g8e32f31+297cba6710,22.0.1-1-geca5380+7fa3b7d9b6,22.0.1-12-g44dc1dc+2a20fdde0d,22.0.1-15-g6a90155+515f58c32b,22.0.1-16-g9282f48+790f5f2caa,22.0.1-2-g92698f7+dcf3732eb2,22.0.1-2-ga9b0f51+7fa3b7d9b6,22.0.1-2-gd1925c9+bf4f0e694f,22.0.1-24-g1ad7a390+a9625a72a8,22.0.1-25-g5bf6245+3ad8ecd50b,22.0.1-25-gb120d7b+8b5510f75f,22.0.1-27-g97737f7+2a20fdde0d,22.0.1-32-gf62ce7b1+aa4237961e,22.0.1-4-g0b3f228+2a20fdde0d,22.0.1-4-g243d05b+871c1b8305,22.0.1-4-g3a563be+32dcf1063f,22.0.1-4-g44f2e3d+9e4ab0f4fa,22.0.1-42-gca6935d93+ba5e5ca3eb,22.0.1-5-g15c806e+85460ae5f3,22.0.1-5-g58711c4+611d128589,22.0.1-5-g75bb458+99c117b92f,22.0.1-6-g1c63a23+7fa3b7d9b6,22.0.1-6-g50866e6+84ff5a128b,22.0.1-6-g8d3140d+720564cf76,22.0.1-6-gd805d02+cc5644f571,22.0.1-8-ge5750ce+85460ae5f3,master-g6e05de7fdc+babf819c66,master-g99da0e417a+8d77f4f51a,w.2021.48
LSST Data Management Base Package
Public Member Functions | Public Attributes | List of all members
lsst.afw.cameraGeom.testUtils.CameraWrapper Class Reference

Public Member Functions

def __init__ (self, plateScale=20.0, radialDistortion=0.925, isLsstLike=False)
 
def nDetectors (self)
 
def makeDetectorConfigs (self, detFile)
 
def makeAmpLists (self, ampFile, isLsstLike=False)
 
def makeTestRepositoryItems (self, isLsstLike=False)
 

Public Attributes

 plateScale
 
 radialDistortion
 
 detectorNameList
 
 detectorIdList
 
 ampDataDict
 
 ampListDict
 
 camera
 

Detailed Description

A simple Camera and the data used to construct it

Intended for use with unit tests, thus saves some interesting information.

Parameters
----------
plateScale : `float`
    Plate scale in arcsec/mm; 20.0 is for LSST.
radialDistortion : `float`
    Radial distortion, in mm/rad^2.
    The r^3 coefficient of the radial distortion polynomial
    that converts FIELD_ANGLE in radians to FOCAL_PLANE in mm;
    0.925 is the value Dave Monet measured for lsstSim data.
isLsstLike : `bool`.
    Make repository products with one raw image per amplifier (True)
    or with one raw image per detector (False).

Definition at line 170 of file testUtils.py.

Constructor & Destructor Documentation

◆ __init__()

def lsst.afw.cameraGeom.testUtils.CameraWrapper.__init__ (   self,
  plateScale = 20.0,
  radialDistortion = 0.925,
  isLsstLike = False 
)

Definition at line 189 of file testUtils.py.

189  def __init__(self, plateScale=20.0, radialDistortion=0.925, isLsstLike=False):
190  afwDir = lsst.utils.getPackageDir("afw")
191  self._afwTestDataDir = os.path.join(afwDir, "python", "lsst", "afw",
192  "cameraGeom", "testData")
193 
194  # Info to store for unit tests
195  self.plateScale = float(plateScale)
196  self.radialDistortion = float(radialDistortion)
197  self.detectorNameList = []
198  self.detectorIdList = []
199  self.ampDataDict = {} # ampData[Dict]: raw dictionaries of test data fields
200 
201  # ampList[Dict]: actual cameraGeom.Amplifier objects
202  self.camConfig, self.ampListDict = self.makeTestRepositoryItems(
203  isLsstLike)
204  self.camera = makeCameraFromAmpLists(
205  self.camConfig, self.ampListDict)
206 
def makeCameraFromAmpLists(cameraConfig, ampListDict, pupilFactoryClass=PupilFactory)

Member Function Documentation

◆ makeAmpLists()

def lsst.afw.cameraGeom.testUtils.CameraWrapper.makeAmpLists (   self,
  ampFile,
  isLsstLike = False 
)
Construct a dict of list of Amplifer, one list per detector.

Parameters
----------
ampFile : `str`
    Path to amplifier data file.
isLsstLike : `bool`
    If True then there is one raw image per amplifier;
    if False then there is one raw image per detector.

Definition at line 254 of file testUtils.py.

254  def makeAmpLists(self, ampFile, isLsstLike=False):
255  """Construct a dict of list of Amplifer, one list per detector.
256 
257  Parameters
258  ----------
259  ampFile : `str`
260  Path to amplifier data file.
261  isLsstLike : `bool`
262  If True then there is one raw image per amplifier;
263  if False then there is one raw image per detector.
264  """
265  readoutMap = {
266  'LL': ReadoutCorner.LL,
267  'LR': ReadoutCorner.LR,
268  'UR': ReadoutCorner.UR,
269  'UL': ReadoutCorner.UL,
270  }
271  ampDataList = []
272  with open(ampFile) as fh:
273  names = fh.readline().rstrip().lstrip("#").split("|")
274  for line in fh:
275  els = line.rstrip().split("|")
276  ampProps = dict([(name, el) for name, el in zip(names, els)])
277  ampDataList.append(ampProps)
278  ampListDict = {}
279  self.ampDataDict = {}
280  for ampData in ampDataList:
281  if ampData['ccd_name'] in ampListDict:
282  ampList = ampListDict[ampData['ccd_name']]
283  self.ampDataDict[ampData['ccd_name']]['namps'] += 1
284  else:
285  ampList = []
286  ampListDict[ampData['ccd_name']] = ampList
287  self.ampDataDict[ampData['ccd_name']] = {'namps': 1, 'linInfo': {}}
288  builder = Amplifier.Builder()
289  bbox = lsst.geom.Box2I(lsst.geom.Point2I(int(ampData['trimmed_xmin']),
290  int(ampData['trimmed_ymin'])),
291  lsst.geom.Point2I(int(ampData['trimmed_xmax']),
292  int(ampData['trimmed_ymax'])))
293  rawBbox = lsst.geom.Box2I(lsst.geom.Point2I(int(ampData['raw_xmin']),
294  int(ampData['raw_ymin'])),
295  lsst.geom.Point2I(int(ampData['raw_xmax']),
296  int(ampData['raw_ymax'])))
297  rawDataBbox = lsst.geom.Box2I(
298  lsst.geom.Point2I(int(ampData['raw_data_xmin']),
299  int(ampData['raw_data_ymin'])),
300  lsst.geom.Point2I(int(ampData['raw_data_xmax']),
301  int(ampData['raw_data_ymax'])))
302  rawHOverscanBbox = lsst.geom.Box2I(
303  lsst.geom.Point2I(int(ampData['hoscan_xmin']),
304  int(ampData['hoscan_ymin'])),
305  lsst.geom.Point2I(int(ampData['hoscan_xmax']),
306  int(ampData['hoscan_ymax'])))
307  rawVOverscanBbox = lsst.geom.Box2I(
308  lsst.geom.Point2I(int(ampData['voscan_xmin']),
309  int(ampData['voscan_ymin'])),
310  lsst.geom.Point2I(int(ampData['voscan_xmax']),
311  int(ampData['voscan_ymax'])))
312  rawPrescanBbox = lsst.geom.Box2I(
313  lsst.geom.Point2I(int(ampData['pscan_xmin']),
314  int(ampData['pscan_ymin'])),
315  lsst.geom.Point2I(int(ampData['pscan_xmax']),
316  int(ampData['pscan_ymax'])))
317  xoffset = int(ampData['x_offset'])
318  yoffset = int(ampData['y_offset'])
319  flipx = bool(int(ampData['flipx']))
320  flipy = bool(int(ampData['flipy']))
321  readcorner = 'LL'
322  if not isLsstLike:
323  offext = lsst.geom.Extent2I(xoffset, yoffset)
324  if flipx:
325  xExt = rawBbox.getDimensions().getX()
326  rawBbox.flipLR(xExt)
327  rawDataBbox.flipLR(xExt)
328  rawHOverscanBbox.flipLR(xExt)
329  rawVOverscanBbox.flipLR(xExt)
330  rawPrescanBbox.flipLR(xExt)
331  if flipy:
332  yExt = rawBbox.getDimensions().getY()
333  rawBbox.flipTB(yExt)
334  rawDataBbox.flipTB(yExt)
335  rawHOverscanBbox.flipTB(yExt)
336  rawVOverscanBbox.flipTB(yExt)
337  rawPrescanBbox.flipTB(yExt)
338  if not flipx and not flipy:
339  readcorner = 'LL'
340  elif flipx and not flipy:
341  readcorner = 'LR'
342  elif flipx and flipy:
343  readcorner = 'UR'
344  elif not flipx and flipy:
345  readcorner = 'UL'
346  else:
347  raise RuntimeError("Couldn't find read corner")
348 
349  flipx = False
350  flipy = False
351  rawBbox.shift(offext)
352  rawDataBbox.shift(offext)
353  rawHOverscanBbox.shift(offext)
354  rawVOverscanBbox.shift(offext)
355  rawPrescanBbox.shift(offext)
356  xoffset = 0
357  yoffset = 0
358  offset = lsst.geom.Extent2I(xoffset, yoffset)
359  builder.setBBox(bbox)
360  builder.setRawXYOffset(offset)
361  builder.setName(str(ampData['name']))
362  builder.setReadoutCorner(readoutMap[readcorner])
363  builder.setGain(float(ampData['gain']))
364  builder.setReadNoise(float(ampData['readnoise']))
365  linCoeffs = np.array([float(ampData['lin_coeffs']), ], dtype=float)
366  builder.setLinearityCoeffs(linCoeffs)
367  builder.setLinearityType(str(ampData['lin_type']))
368  builder.setRawFlipX(flipx)
369  builder.setRawFlipY(flipy)
370  builder.setRawBBox(rawBbox)
371  builder.setRawDataBBox(rawDataBbox)
372  builder.setRawHorizontalOverscanBBox(rawHOverscanBbox)
373  builder.setRawVerticalOverscanBBox(rawVOverscanBbox)
374  builder.setRawPrescanBBox(rawPrescanBbox)
375  builder.setLinearityThreshold(float(ampData['lin_thresh']))
376  builder.setLinearityMaximum(float(ampData['lin_max']))
377  builder.setLinearityUnits(str(ampData['lin_units']))
378  self.ampDataDict[ampData['ccd_name']]['linInfo'][ampData['name']] = \
379  {'lincoeffs': linCoeffs, 'lintype': str(ampData['lin_type']),
380  'linthresh': float(ampData['lin_thresh']), 'linmax': float(ampData['lin_max']),
381  'linunits': str(ampData['lin_units'])}
382  ampList.append(builder)
383  return ampListDict
384 
An integer coordinate rectangle.
Definition: Box.h:55

◆ makeDetectorConfigs()

def lsst.afw.cameraGeom.testUtils.CameraWrapper.makeDetectorConfigs (   self,
  detFile 
)
Construct a list of DetectorConfig, one per detector

Definition at line 212 of file testUtils.py.

212  def makeDetectorConfigs(self, detFile):
213  """Construct a list of DetectorConfig, one per detector
214  """
215  detectors = []
216  self.detectorNameList = []
217  self.detectorIdList = []
218  with open(detFile) as fh:
219  names = fh.readline().rstrip().lstrip("#").split("|")
220  for line in fh:
221  els = line.rstrip().split("|")
222  detectorProps = dict([(name, el)
223  for name, el in zip(names, els)])
224  detectors.append(detectorProps)
225  detectorConfigs = []
226  for i, detector in enumerate(detectors):
227  detectorId = (i + 1) * 10 # to avoid simple 0, 1, 2...
228  detectorName = detector['name']
229  detConfig = DetectorConfig()
230  detConfig.name = detectorName
231  detConfig.id = detectorId
232  detConfig.bbox_x0 = 0
233  detConfig.bbox_y0 = 0
234  detConfig.bbox_x1 = int(detector['npix_x']) - 1
235  detConfig.bbox_y1 = int(detector['npix_y']) - 1
236  detConfig.serial = str(detector['serial'])
237  detConfig.detectorType = int(detector['detectorType'])
238  detConfig.offset_x = float(detector['x'])
239  detConfig.offset_y = float(detector['y'])
240  detConfig.refpos_x = float(detector['refPixPos_x'])
241  detConfig.refpos_y = float(detector['refPixPos_y'])
242  detConfig.yawDeg = float(detector['yaw'])
243  detConfig.pitchDeg = float(detector['pitch'])
244  detConfig.rollDeg = float(detector['roll'])
245  detConfig.pixelSize_x = float(detector['pixelSize'])
246  detConfig.pixelSize_y = float(detector['pixelSize'])
247  detConfig.transposeDetector = False
248  detConfig.transformDict.nativeSys = PIXELS.getSysName()
249  detectorConfigs.append(detConfig)
250  self.detectorNameList.append(detectorName)
251  self.detectorIdList.append(detectorId)
252  return detectorConfigs
253 
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33

◆ makeTestRepositoryItems()

def lsst.afw.cameraGeom.testUtils.CameraWrapper.makeTestRepositoryItems (   self,
  isLsstLike = False 
)
Make camera config and amp catalog dictionary, using default
detector and amp files.

Parameters
----------
isLsstLike : `bool`
    If True then there is one raw image per amplifier;
    if False then there is one raw image per detector.

Definition at line 385 of file testUtils.py.

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  ampListDict = self.makeAmpLists(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, ampListDict
417 
418 
419 @inTestCase
constexpr double arcsecToRad(double x) noexcept
Definition: Angle.h:55

◆ nDetectors()

def lsst.afw.cameraGeom.testUtils.CameraWrapper.nDetectors (   self)
Return the number of detectors

Definition at line 208 of file testUtils.py.

208  def nDetectors(self):
209  """Return the number of detectors"""
210  return len(self.detectorNameList)
211 

Member Data Documentation

◆ ampDataDict

lsst.afw.cameraGeom.testUtils.CameraWrapper.ampDataDict

Definition at line 199 of file testUtils.py.

◆ ampListDict

lsst.afw.cameraGeom.testUtils.CameraWrapper.ampListDict

Definition at line 202 of file testUtils.py.

◆ camera

lsst.afw.cameraGeom.testUtils.CameraWrapper.camera

Definition at line 204 of file testUtils.py.

◆ detectorIdList

lsst.afw.cameraGeom.testUtils.CameraWrapper.detectorIdList

Definition at line 198 of file testUtils.py.

◆ detectorNameList

lsst.afw.cameraGeom.testUtils.CameraWrapper.detectorNameList

Definition at line 197 of file testUtils.py.

◆ plateScale

lsst.afw.cameraGeom.testUtils.CameraWrapper.plateScale

Definition at line 195 of file testUtils.py.

◆ radialDistortion

lsst.afw.cameraGeom.testUtils.CameraWrapper.radialDistortion

Definition at line 196 of file testUtils.py.


The documentation for this class was generated from the following file: