def testDataAuxTelZWO(self): inst = Instrument(self.instDir) inst.config(CamType.AuxTelZWO, 160, announcedDefocalDisInMm=0.5) self.assertEqual(inst.getObscuration(), 0.3525) self.assertEqual(inst.getFocalLength(), 21.6) self.assertEqual(inst.getApertureDiameter(), 1.2) self.assertEqual(inst.getDefocalDisOffset(), 0.0205) self.assertEqual(inst.getCamPixelSize(), 15.2e-6) self.assertAlmostEqual(inst.calcSizeOfDonutExpected(), 74.92690058, places=7)
class TestInstrument(unittest.TestCase): """Test the Instrument class.""" def setUp(self): self.instDir = os.path.join(getConfigDir(), "cwfs", "instData") self.inst = Instrument(self.instDir) self.dimOfDonutOnSensor = 120 self.inst.config(CamType.LsstCam, self.dimOfDonutOnSensor, announcedDefocalDisInMm=1.5) def testConfigWithUnsupportedCamType(self): self.assertRaises(ValueError, self.inst.config, "NoThisCamType", 120) def testGetInstFileDir(self): instFileDir = self.inst.getInstFileDir() ansInstFileDir = os.path.join(self.instDir, "lsst") self.assertEqual(instFileDir, ansInstFileDir) def testGetAnnDefocalDisInMm(self): annDefocalDisInMm = self.inst.getAnnDefocalDisInMm() self.assertEqual(annDefocalDisInMm, 1.5) def testSetAnnDefocalDisInMm(self): annDefocalDisInMm = 2.0 self.inst.setAnnDefocalDisInMm(annDefocalDisInMm) self.assertEqual(self.inst.getAnnDefocalDisInMm(), annDefocalDisInMm) def testGetInstFilePath(self): instFilePath = self.inst.getInstFilePath() self.assertTrue(os.path.exists(instFilePath)) self.assertEqual(os.path.basename(instFilePath), "instParam.yaml") def testGetMaskOffAxisCorr(self): maskOffAxisCorr = self.inst.getMaskOffAxisCorr() self.assertEqual(maskOffAxisCorr.shape, (9, 5)) self.assertEqual(maskOffAxisCorr[0, 0], 1.07) self.assertEqual(maskOffAxisCorr[2, 3], -0.090100858) def testGetDimOfDonutOnSensor(self): dimOfDonutOnSensor = self.inst.getDimOfDonutOnSensor() self.assertEqual(dimOfDonutOnSensor, self.dimOfDonutOnSensor) def testGetObscuration(self): obscuration = self.inst.getObscuration() self.assertEqual(obscuration, 0.61) def testGetFocalLength(self): focalLength = self.inst.getFocalLength() self.assertEqual(focalLength, 10.312) def testGetApertureDiameter(self): apertureDiameter = self.inst.getApertureDiameter() self.assertEqual(apertureDiameter, 8.36) def testGetDefocalDisOffset(self): defocalDisInM = self.inst.getDefocalDisOffset() # The answer is 1.5 mm self.assertEqual(defocalDisInM * 1e3, 1.5) def testGetCamPixelSize(self): camPixelSizeInM = self.inst.getCamPixelSize() # The answer is 10 um self.assertEqual(camPixelSizeInM * 1e6, 10) def testGetMarginalFocalLength(self): marginalFL = self.inst.getMarginalFocalLength() self.assertAlmostEqual(marginalFL, 9.4268, places=4) def testGetSensorFactor(self): sensorFactor = self.inst.getSensorFactor() self.assertAlmostEqual(sensorFactor, 0.98679, places=5) def testGetSensorCoor(self): xSensor, ySensor = self.inst.getSensorCoor() self.assertEqual(xSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertAlmostEqual(xSensor[0, 0], -0.97857, places=5) self.assertAlmostEqual(xSensor[0, 1], -0.96212, places=5) self.assertEqual(ySensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertAlmostEqual(ySensor[0, 0], -0.97857, places=5) self.assertAlmostEqual(ySensor[1, 0], -0.96212, places=5) def testGetSensorCoorAnnular(self): xoSensor, yoSensor = self.inst.getSensorCoorAnnular() self.assertEqual(xoSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertTrue(np.isnan(xoSensor[0, 0])) self.assertTrue(np.isnan(xoSensor[60, 60])) self.assertEqual(yoSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertTrue(np.isnan(yoSensor[0, 0])) self.assertTrue(np.isnan(yoSensor[60, 60])) def testCalcSizeOfDonutExpected(self): self.assertAlmostEqual(self.inst.calcSizeOfDonutExpected(), 121.60589604, places=7) def testDataAuxTel(self): inst = Instrument(self.instDir) inst.config(CamType.AuxTel, 160, announcedDefocalDisInMm=0.8) self.assertEqual(inst.getObscuration(), 0.3525) self.assertEqual(inst.getFocalLength(), 21.6) self.assertEqual(inst.getApertureDiameter(), 1.2) self.assertEqual(inst.getDefocalDisOffset(), 0.041 * 0.8) self.assertEqual(inst.getCamPixelSize(), 10.0e-6) self.assertAlmostEqual(inst.calcSizeOfDonutExpected(), 182.2222222, places=7) def testDataAuxTelZWO(self): inst = Instrument(self.instDir) inst.config(CamType.AuxTelZWO, 160, announcedDefocalDisInMm=0.5) self.assertEqual(inst.getObscuration(), 0.3525) self.assertEqual(inst.getFocalLength(), 21.6) self.assertEqual(inst.getApertureDiameter(), 1.2) self.assertEqual(inst.getDefocalDisOffset(), 0.0205) self.assertEqual(inst.getCamPixelSize(), 15.2e-6) self.assertAlmostEqual(inst.calcSizeOfDonutExpected(), 74.92690058, places=7)
def makeTemplate( self, sensorName, defocalType, imageSize, camType=CamType.LsstCam, opticalModel="offAxis", pixelScale=0.2, ): """Make the donut template image. Parameters ---------- sensorName : str The camera detector for which we want to make a template. Should be in "Rxx_Sxx" format. defocalType : enum 'DefocalType' The defocal state of the sensor. imageSize : int Size of template in pixels. The template will be a square. camType : enum 'CamType', optional Camera type. (The default is CamType.LsstCam) opticalModel : str, optional Optical model. It can be "paraxial", "onAxis", or "offAxis". (The default is "offAxis") pixelScale : float, optional The pixels to arcseconds conversion factor. (The default is 0.2) Returns ------- numpy.ndarray [int] The donut template as a binary image. Raises ------ ValueError Camera type is not supported. """ configDir = getConfigDir() # Load Instrument parameters instDir = os.path.join(configDir, "cwfs", "instData") inst = Instrument(instDir) if camType in (CamType.LsstCam, CamType.LsstFamCam, CamType.ComCam): inst.config(camType, imageSize) focalPlaneLayout = readPhoSimSettingData(configDir, "focalplanelayout.txt", "fieldCenter") pixelSizeInUm = float(focalPlaneLayout[sensorName][2]) sensorXMicron, sensorYMicron = np.array( focalPlaneLayout[sensorName][:2], dtype=float) elif camType == CamType.AuxTel: # AuxTel only works with onAxis sources if opticalModel != "onAxis": raise ValueError( str(f"Optical Model {opticalModel} not supported with AuxTel. " + "Must use 'onAxis'.")) # Defocal distance for Latiss in mm # for LsstCam can use the default # hence only need to set here announcedDefocalDisInMm = getDefocalDisInMm("auxTel") inst.config(camType, imageSize, announcedDefocalDisInMm) # load the info for auxTel pixelSizeInMeters = inst.getCamPixelSize() # pixel size in meters. pixelSizeInUm = pixelSizeInMeters * 1e6 camera = obs_lsst.Latiss.getCamera() sensorName = list( camera.getNameIter())[0] # only one detector in latiss detector = camera.get(sensorName) xp, yp = detector.getCenter( cameraGeom.FOCAL_PLANE) # center of CCD in mm # multiply by 1000 to for mm --> microns conversion sensorXMicron = yp * 1000 sensorYMicron = xp * 1000 else: raise ValueError("Camera type (%s) is not supported." % camType) # Create image for mask img = CompensableImage() # Convert pixel locations to degrees sensorXPixel = float(sensorXMicron) / pixelSizeInUm sensorYPixel = float(sensorYMicron) / pixelSizeInUm # Multiply by pixelScale then divide by 3600 for arcsec->deg conversion sensorXDeg = sensorXPixel * pixelScale / 3600 sensorYDeg = sensorYPixel * pixelScale / 3600 fieldXY = [sensorXDeg, sensorYDeg] # Define position of donut at center of current sensor in degrees boundaryT = 0 maskScalingFactorLocal = 1 img.setImg(fieldXY, defocalType, image=np.zeros((imageSize, imageSize))) img.makeMask(inst, opticalModel, boundaryT, maskScalingFactorLocal) return img.getNonPaddedMask()
class TestInstrument(unittest.TestCase): """Test the Instrument class.""" def setUp(self): self.instDir = os.path.join(getConfigDir(), "cwfs", "instData") self.inst = Instrument(self.instDir) self.dimOfDonutOnSensor = 120 self.inst.config(CamType.LsstCam, self.dimOfDonutOnSensor, announcedDefocalDisInMm=1.5) def testConfigWithUnsupportedCamType(self): self.assertRaises(ValueError, self.inst.config, CamType.LsstFamCam, 120) def testGetInstFileDir(self): instFileDir = self.inst.getInstFileDir() ansInstFileDir = os.path.join(self.instDir, "lsst") self.assertEqual(instFileDir, ansInstFileDir) def testGetAnnDefocalDisInMm(self): annDefocalDisInMm = self.inst.getAnnDefocalDisInMm() self.assertEqual(annDefocalDisInMm, 1.5) def testSetAnnDefocalDisInMm(self): annDefocalDisInMm = 2.0 self.inst.setAnnDefocalDisInMm(annDefocalDisInMm) self.assertEqual(self.inst.getAnnDefocalDisInMm(), annDefocalDisInMm) def testGetInstFilePath(self): instFilePath = self.inst.getInstFilePath() self.assertTrue(os.path.exists(instFilePath)) self.assertEqual(os.path.basename(instFilePath), "instParam.yaml") def testGetMaskOffAxisCorr(self): maskOffAxisCorr = self.inst.getMaskOffAxisCorr() self.assertEqual(maskOffAxisCorr.shape, (9, 5)) self.assertEqual(maskOffAxisCorr[0, 0], 1.07) self.assertEqual(maskOffAxisCorr[2, 3], -0.090100858) def testGetDimOfDonutOnSensor(self): dimOfDonutOnSensor = self.inst.getDimOfDonutOnSensor() self.assertEqual(dimOfDonutOnSensor, self.dimOfDonutOnSensor) def testGetObscuration(self): obscuration = self.inst.getObscuration() self.assertEqual(obscuration, 0.61) def testGetFocalLength(self): focalLength = self.inst.getFocalLength() self.assertEqual(focalLength, 10.312) def testGetApertureDiameter(self): apertureDiameter = self.inst.getApertureDiameter() self.assertEqual(apertureDiameter, 8.36) def testGetDefocalDisOffset(self): defocalDisInM = self.inst.getDefocalDisOffset() # The answer is 1.5 mm self.assertEqual(defocalDisInM * 1e3, 1.5) def testGetCamPixelSize(self): camPixelSizeInM = self.inst.getCamPixelSize() # The answer is 10 um self.assertEqual(camPixelSizeInM * 1e6, 10) def testGetMarginalFocalLength(self): marginalFL = self.inst.getMarginalFocalLength() self.assertAlmostEqual(marginalFL, 9.4268, places=4) def testGetSensorFactor(self): sensorFactor = self.inst.getSensorFactor() self.assertAlmostEqual(sensorFactor, 0.98679, places=5) def testGetSensorCoor(self): xSensor, ySensor = self.inst.getSensorCoor() self.assertEqual(xSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertAlmostEqual(xSensor[0, 0], -0.97857, places=5) self.assertAlmostEqual(xSensor[0, 1], -0.96212, places=5) self.assertEqual(ySensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertAlmostEqual(ySensor[0, 0], -0.97857, places=5) self.assertAlmostEqual(ySensor[1, 0], -0.96212, places=5) def testGetSensorCoorAnnular(self): xoSensor, yoSensor = self.inst.getSensorCoorAnnular() self.assertEqual(xoSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertTrue(np.isnan(xoSensor[0, 0])) self.assertTrue(np.isnan(xoSensor[60, 60])) self.assertEqual(yoSensor.shape, (self.dimOfDonutOnSensor, self.dimOfDonutOnSensor)) self.assertTrue(np.isnan(yoSensor[0, 0])) self.assertTrue(np.isnan(yoSensor[60, 60]))