def makeTestRepositoryItems(self, isLsstLike=False): """!Make camera config and amp catalog dictionary, using default detector and amp files @param[in] isLsstLike if True then there is one raw image per amplifier; if False then there is one raw image per detector """ detFile = os.path.join(self._afwTestDir, "testCameraDetectors.dat") detectorConfigs = self.makeDetectorConfigs(detFile) ampFile = os.path.join(self._afwTestDir, "testCameraAmps.dat") ampCatalogDict = self.makeAmpCatalogs(ampFile, isLsstLike=isLsstLike) camConfig = CameraConfig() camConfig.name = "testCamera%s"%('LSST' if isLsstLike else 'SC') camConfig.detectorList = dict((i, detConfig) for i, detConfig in enumerate(detectorConfigs)) camConfig.plateScale = self.plateScale pScaleRad = afwGeom.arcsecToRad(self.plateScale) radialDistortCoeffs = [0.0, 1.0/pScaleRad, 0.0, self.radialDistortion/pScaleRad] tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'inverted' radialClass = afwGeom.xyTransformRegistry['radial'] tConfig.transform.active.transform.retarget(radialClass) tConfig.transform.active.transform.coeffs = radialDistortCoeffs tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName():tConfig} camConfig.transformDict = tmc return camConfig, ampCatalogDict
def testAngleAliases(self): with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.Angle(1), lsst.geom.Angle(1)) self.assertIs(afwGeom.radians, lsst.geom.radians) self.assertIs(afwGeom.degrees, lsst.geom.degrees) self.assertIs(afwGeom.hours, lsst.geom.hours) self.assertIs(afwGeom.arcminutes, lsst.geom.arcminutes) self.assertIs(afwGeom.arcseconds, lsst.geom.arcseconds) self.assertIs(afwGeom.PI, lsst.geom.PI) self.assertIs(afwGeom.TWOPI, lsst.geom.TWOPI) self.assertIs(afwGeom.HALFPI, lsst.geom.HALFPI) self.assertIs(afwGeom.ONE_OVER_PI, lsst.geom.ONE_OVER_PI) self.assertIs(afwGeom.SQRTPI, lsst.geom.SQRTPI) self.assertIs(afwGeom.INVSQRTPI, lsst.geom.INVSQRTPI) self.assertIs(afwGeom.ROOT2, lsst.geom.ROOT2) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.degToRad(1), lsst.geom.degToRad(1)) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.radToDeg(1), lsst.geom.radToDeg(1)) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.radToArcsec(1), lsst.geom.radToArcsec(1)) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.radToMas(1), lsst.geom.radToMas(1)) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.arcsecToRad(1), lsst.geom.arcsecToRad(1)) with self.assertWarns(FutureWarning): self.assertEqual(afwGeom.masToRad(1), lsst.geom.masToRad(1))
def ReturnCamera(baseDir): """ This method reads in the files baseDir/focalplanelayout.txt baseDir/segmentation.txt and returns an afw.cameraGeom object Below is the original documentation of the function this code was copied from: Create the configs for building a camera. This runs on the files distributed with PhoSim. Currently gain and saturation need to be supplied as well. The file should have three columns: on disk amp id (R22_S11_C00), gain, saturation. For example: DetectorLayoutFile -- https://dev.lsstcorp.org/cgit/LSST/sims/phosim.git/plain/data/lsst/focalplanelayout.txt?h=dev SegmentsFile -- https://dev.lsstcorp.org/cgit/LSST/sims/phosim.git/plain/data/lsst/segmentation.txt?h=dev """ defaultOutDir = 'scratch' DetectorLayoutFile = os.path.join(baseDir, 'focalplanelayout.txt') SegmentsFile = os.path.join(baseDir, 'segmentation.txt') GainFile = None phosimVersion='1.0' ampTableDict = makeAmpTables(SegmentsFile, GainFile) detectorConfigList = makeDetectorConfigs(DetectorLayoutFile, phosimVersion) #Build the camera config. camConfig = CameraConfig() camConfig.detectorList = dict([(i,detectorConfigList[i]) for i in range(len(detectorConfigList))]) camConfig.name = 'LSST' camConfig.plateScale = 2.0 #arcsec per mm pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) pincushion = 0.925 # Don't have this yet ticket/3155 #camConfig.boresiteOffset_x = 0. #camConfig.boresiteOffset_y = 0. tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'inverted' radialClass = afwGeom.xyTransformRegistry['radial'] tConfig.transform.active.transform.retarget(radialClass) # According to Dave M. the simulated LSST transform is well approximated (1/3 pix) # by a scale and a pincusion. #this is ultimately used to convert from focal plane coordinates to pupil coordinates #see the asgnment below to tmc.transforms tConfig.transform.active.transform.coeffs = [0., 1./pScaleRad, 0., pincushion/pScaleRad] #tConfig.transform.active.boresiteOffset_x = camConfig.boresiteOffset_x #tConfig.transform.active.boresiteOffset_y = camConfig.boresiteOffset_y tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName():tConfig} camConfig.transformDict = tmc myCamera = makeCameraFromCatalogs(camConfig, ampTableDict) return myCamera
def _makeRadialTransform(self, radialCoeffs): """Helper function to get the radial transform given the radial polynomial coefficients given in the constructor. @param[in] radialCoeffs List of coefficients describing a polynomial radial distortion in normalized units. @return RadialXYTransform object describing the radial distortion """ pScaleRad = afwGeom.arcsecToRad(self.plateScale) return afwGeom.RadialXYTransform([el/pScaleRad for el in radialCoeffs])
def ReturnCamera(baseDir): """ This method reads in the files baseDir/focalplanelayout.txt baseDir/segmentation.txt and returns an afw.cameraGeom object Below is the original documentation of the function this code was copied from: Create the configs for building a camera. This runs on the files distributed with PhoSim. Currently gain and saturation need to be supplied as well. The file should have three columns: on disk amp id (R22_S11_C00), gain, saturation. For example: DetectorLayoutFile -- https://dev.lsstcorp.org/cgit/LSST/sims/phosim.git/plain/data/lsst/focalplanelayout.txt?h=dev SegmentsFile -- https://dev.lsstcorp.org/cgit/LSST/sims/phosim.git/plain/data/lsst/segmentation.txt?h=dev """ defaultOutDir = 'scratch' DetectorLayoutFile = os.path.join(baseDir, 'focalplanelayout.txt') SegmentsFile = os.path.join(baseDir, 'segmentation.txt') GainFile = None phosimVersion='1.0' ampTableDict = makeAmpTables(SegmentsFile, GainFile) detectorConfigList = makeDetectorConfigs(DetectorLayoutFile, phosimVersion) #Build the camera config. camConfig = CameraConfig() camConfig.detectorList = dict([(i,detectorConfigList[i]) for i in xrange(len(detectorConfigList))]) camConfig.name = 'LSST' camConfig.plateScale = 2.0 #arcsec per mm pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) pincushion = 0.925 # Don't have this yet ticket/3155 #camConfig.boresiteOffset_x = 0. #camConfig.boresiteOffset_y = 0. tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'inverted' radialClass = afwGeom.xyTransformRegistry['radial'] tConfig.transform.active.transform.retarget(radialClass) # According to Dave M. the simulated LSST transform is well approximated (1/3 pix) # by a scale and a pincusion. #this is ultimately used to convert from focal plane coordinates to pupil coordinates #see the asgnment below to tmc.transforms tConfig.transform.active.transform.coeffs = [0., 1./pScaleRad, 0., pincushion/pScaleRad] #tConfig.transform.active.boresiteOffset_x = camConfig.boresiteOffset_x #tConfig.transform.active.boresiteOffset_y = camConfig.boresiteOffset_y tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName():tConfig} camConfig.transformDict = tmc myCamera = makeCameraFromCatalogs(camConfig, ampTableDict) return myCamera
def _makeRadialTransform(self, radialCoeffs): """Helper function to get the radial transform given the radial polynomial coefficients given in the constructor. @param[in] radialCoeffs List of coefficients describing a polynomial radial distortion in normalized units. @return Transform object describing the radial distortion """ pScaleRad = afwGeom.arcsecToRad(self.plateScale) return afwGeom.makeRadialTransform( [el / pScaleRad for el in radialCoeffs])
def __init__(self, size=None, n_step=3, filter_name='g', exposure_time=30., pixel_scale=Angle(afwGeom.arcsecToRad(0.25)), wavelength_step=None): """Initialize the lightweight version of GenerateTemplate for testing. Parameters ---------- size : int, optional Number of pixels on a side of the image and model. n_step : int, optional Number of sub-filter wavelength planes to model. Optional if `wavelength_step` supplied. filter_name : str, optional Name of the bandpass-defining filter of the data. Expected values are u,g,r,i,z,y. exposure_time : float, optional Length of the exposure, in seconds. Needed only for exporting to FITS. pixel_scale : lsst.afw.geom.Angle, optional Plate scale of the images, as an Angle wavelength_step : int, optional Overridden by `n_step`, if that is supplied. Sub-filter width, in nm. """ seed = 5 rand_gen = np.random rand_gen.seed(seed) self.butler = None self.default_repository = None self.debug = False bandpass_init = BasicBandpass(filter_name=filter_name, wavelength_step=wavelength_step) wavelength_step = (bandpass_init.wavelen_max - bandpass_init.wavelen_min) / n_step self.bandpass = BasicBandpass(filter_name=filter_name, wavelength_step=wavelength_step) self.bandpass_highres = BasicBandpass(filter_name=filter_name, wavelength_step=None) self.model = [rand_gen.random(size=(size, size)) for f in range(n_step)] # self.weights = np.ones((size, size)) self.mask = np.zeros((size, size), dtype=np.int32) self.n_step = n_step self.y_size = size self.x_size = size self.pixel_scale = pixel_scale self.psf_size = 5 self.exposure_time = exposure_time self.filter_name = filter_name self.observatory = lsst_observatory self.bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.ExtentI(size, size)) self.wcs = self._create_wcs(bbox=self.bbox, pixel_scale=pixel_scale, ra=Angle(0.), dec=Angle(0.), sky_rotation=Angle(0.)) psf_vals = np.zeros((self.psf_size, self.psf_size)) psf_vals[self.psf_size//2 - 1: self.psf_size//2 + 1, self.psf_size//2 - 1: self.psf_size//2 + 1] = 0.5 psf_vals[self.psf_size//2, self.psf_size//2] = 1. psf_image = afwImage.ImageD(self.psf_size, self.psf_size) psf_image.getArray()[:, :] = psf_vals psfK = afwMath.FixedKernel(psf_image) self.psf = measAlg.KernelPsf(psfK)
def makeCamera(name="SDSS", outputDir=None): """Make a camera @param name: name of the camera @param outputDir: If not None, write the objects used to make the camera to this location @return a camera object """ camConfig = CameraConfig() camConfig.name = name camConfig.detectorList = {} camConfig.plateScale = 16.5 # arcsec/mm pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) radialDistortCoeffs = [0.0, 1.0 / pScaleRad] tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'inverted' radialClass = afwGeom.xyTransformRegistry['radial'] tConfig.transform.active.transform.retarget(radialClass) tConfig.transform.active.transform.coeffs = radialDistortCoeffs tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName(): tConfig} camConfig.transformDict = tmc ccdId = 0 ampInfoCatDict = {} for i in range(6): dewarName = str(i + 1) filters = "riuzg" for j, c in enumerate(reversed(filters)): ccdName = "%s%s" % (c, dewarName) offsetPoint = afwGeom.Point2D(25.4 * 2.5 * (2.5 - i), 25.4 * 2.1 * (2.0 - j)) ccdInfo = makeCcd(ccdName, ccdId, offsetPoint) ampInfoCatDict[ccdName] = ccdInfo['ampInfo'] camConfig.detectorList[ccdId] = ccdInfo['ccdConfig'] ccdId += 1 if outputDir is not None: camConfig.save(os.path.join(outputDir, 'camera.py')) for k in ampInfoCatDict: ampInfoCatDict[k].writeFits( os.path.join(outputDir, "%s.fits" % (k))) return makeCameraFromCatalogs(camConfig, ampInfoCatDict)
def makeCamera(name="SDSS", outputDir=None): """Make a camera @param name: name of the camera @param outputDir: If not None, write the objects used to make the camera to this location @return a camera object """ camConfig = CameraConfig() camConfig.name = name camConfig.detectorList = {} camConfig.plateScale = 16.5 # arcsec/mm pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) radialDistortCoeffs = [0.0, 1.0/pScaleRad] tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'inverted' radialClass = afwGeom.transformRegistry['radial'] tConfig.transform.active.transform.retarget(radialClass) tConfig.transform.active.transform.coeffs = radialDistortCoeffs tmc = TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {FIELD_ANGLE.getSysName(): tConfig} camConfig.transformDict = tmc ccdId = 0 ampInfoCatDict = {} for i in range(6): dewarName = str(i+1) filters = "riuzg" for j, c in enumerate(reversed(filters)): ccdName = "%s%s" % (c, dewarName) offsetPoint = afwGeom.Point2D(25.4*2.5*(2.5-i), 25.4*2.1*(2.0 - j)) ccdInfo = makeCcd(ccdName, ccdId, offsetPoint) ampInfoCatDict[ccdName] = ccdInfo['ampInfo'] camConfig.detectorList[ccdId] = ccdInfo['ccdConfig'] ccdId += 1 if outputDir is not None: camConfig.save(os.path.join(outputDir, 'camera.py')) for k in ampInfoCatDict: ampInfoCatDict[k].writeFits(os.path.join(outputDir, "%s.fits"%(k))) return makeCameraFromCatalogs(camConfig, ampInfoCatDict)
def setUp(self): """Define parameters used by every test.""" filter_name = 'g' n_step = 3 pixel_scale = Angle(afwGeom.arcsecToRad(0.25)) size = 20 self.latitude = lsst_observatory.getLatitude() # NOTE that this array is randomly generated random_seed = 3 rand_gen = np.random rand_gen.seed(random_seed) self.array = np.float32(rand_gen.random(size=(size, size))) self.dcrTemplate = BasicGenerateTemplate(size=size, filter_name=filter_name, n_step=n_step, pixel_scale=pixel_scale) self.dcrTemplate.create_skyMap(doWrite=False) self.dec = self.dcrTemplate.wcs.getSkyOrigin().getLatitude() self.ra = self.dcrTemplate.wcs.getSkyOrigin().getLongitude() self.azimuth = Angle(np.radians(140.0)) self.elevation = Angle(np.radians(50.0)) ha_term1 = np.sin(self.elevation.asRadians()) ha_term2 = np.sin(self.dec.asRadians())*np.sin(self.latitude.asRadians()) ha_term3 = np.cos(self.dec.asRadians())*np.cos(self.latitude.asRadians()) self.hour_angle = Angle(np.arccos((ha_term1 - ha_term2) / ha_term3)) p_angle = parallactic_angle(self.hour_angle, self.dec, self.latitude) self.rotation_angle = Angle(p_angle) self.dcrTemplate.weights = np.zeros_like(self.array) nonzero_inds = self.array > 0 self.dcrTemplate.weights[nonzero_inds] = 1./np.abs(self.array[nonzero_inds]) self.dcr_gen = self.dcrTemplate._dcr_generator(self.dcrTemplate.bandpass, pixel_scale=self.dcrTemplate.pixel_scale, elevation=self.elevation, rotation_angle=self.rotation_angle, use_midpoint=False) self.exposure = self.dcrTemplate.create_exposure(self.array, self.elevation, self.azimuth, variance=None, boresightRotAngle=self.rotation_angle, dec=self.dec, ra=self.ra)
nargs = "?", default = defaultOutDir, ) parser.add_argument("--clobber", action="store_true", dest="clobber", default=False, help=("remove and re-create the output directory if it already exists?")) args = parser.parse_args() ampTableDict = makeAmpTables(args.SegmentsFile) detectorConfigList = makeDetectorConfigs(args.DetectorLayoutFile) #Build the camera config. camConfig = CameraConfig() camConfig.detectorList = dict([(i,detectorConfigList[i]) for i in xrange(len(detectorConfigList))]) camConfig.name = 'DECAM' #From DECam calibration doc camConfig.plateScale = 17.575 pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'radial' nomWavelen = 0.625 #nominal wavelen in microns coeff0 = 0 coeff1 = 1 - 2.178e-4 - 2.329e-4/nomWavelen + 4.255e-5/nomWavelen**2 coeff2 = 0 coeff3 = -6.174e-8 + 5.569e-9/nomWavelen tConfig.transform.active.coeffs = [pScaleRad*coeff0, pScaleRad*coeff1, pScaleRad*coeff2, pScaleRad*coeff3] tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName():tConfig} camConfig.transformDict = tmc def makeDir(dirPath, doClobber=False):
nargs="?", default=defaultOutDir, ) parser.add_argument("--clobber", action="store_true", dest="clobber", default=False, help=("remove and re-create the output directory if it already exists?")) args = parser.parse_args() ampTableDict = makeAmpTables(args.SegmentsFile) detectorConfigList = makeDetectorConfigs(args.DetectorLayoutFile) # Build the camera config. camConfig = CameraConfig() camConfig.detectorList = dict([(i, detectorConfigList[i]) for i in range(len(detectorConfigList))]) camConfig.name = 'DECAM' # From DECam calibration doc camConfig.plateScale = 17.575 pScaleRad = afwGeom.arcsecToRad(camConfig.plateScale) tConfig = afwGeom.TransformConfig() tConfig.transform.name = 'radial' nomWavelen = 0.625 # nominal wavelen in microns coeff0 = 0 coeff1 = 1 - 2.178e-4 - 2.329e-4/nomWavelen + 4.255e-5/nomWavelen**2 coeff2 = 0 coeff3 = -6.174e-8 + 5.569e-9/nomWavelen tConfig.transform.active.coeffs = [pScaleRad*coeff0, pScaleRad*coeff1, pScaleRad*coeff2, pScaleRad*coeff3] tmc = afwGeom.TransformMapConfig() tmc.nativeSys = FOCAL_PLANE.getSysName() tmc.transforms = {PUPIL.getSysName(): tConfig} camConfig.transformDict = tmc def makeDir(dirPath, doClobber=False):
def __init__(self, name="detector 1", id=1, detType=SCIENCE, serial="xkcd722", bbox=None, # do not use mutable objects as defaults numAmps=3, pixelSize=(0.02, 0.02), ampExtent=(5, 6), orientation=Orientation(), plateScale=20.0, radialDistortion=0.925, modFunc=None, ): """!Construct a DetectorWrapper @param[in] name detector name @param[in] id detector ID (int) @param[in] detType detector type (an lsst.afw.cameraGeom.DetectorType) @param[in] serial serial "number" (a string) @param[in] bbox bounding box; defaults to (0, 0), (1024x1024) (an lsst.afw.geom.Box2I) @param[in] numAmps number of amplifiers (int) @param[in] pixelSize pixel size (mm) (an lsst.afw.geom.Point2D) @param[in] ampExtent dimensions of amplifier image bbox (an lsst.afw.geom.Extent2I) @param[in] orientation orientation of CCC in focal plane (lsst.afw.cameraGeom.Orientation) @param[in] plateScale plate scale in arcsec/mm; 20.0 is for LSST @param[in] radialDistortion radial distortion, in mm/rad^2 (the r^3 coefficient of the radial distortion polynomial that converts PUPIL in radians to FOCAL_PLANE in mm); 0.925 is the value Dave Monet measured for lsstSim data @param[in] modFunc a function that can modify attributes just before constructing the detector; modFunc receives one argument: a DetectorWrapper with all attributes except detector set. """ # note that (0., 0.) for the reference position is the center of the first pixel self.name = name self.id = int(id) self.type = detType self.serial = serial if bbox is None: bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Extent2I(1024, 1048)) self.bbox = bbox self.pixelSize = afwGeom.Extent2D(*pixelSize) self.ampExtent = afwGeom.Extent2I(*ampExtent) self.plateScale = float(plateScale) self.radialDistortion = float(radialDistortion) schema = afwTable.AmpInfoTable.makeMinimalSchema() self.ampInfo = afwTable.AmpInfoCatalog(schema) for i in range(numAmps): record = self.ampInfo.addNew() ampName = "amp %d" % (i + 1,) record.setName(ampName) record.setBBox(afwGeom.Box2I(afwGeom.Point2I(-1, 1), self.ampExtent)) record.setGain(1.71234e3) record.setReadNoise(0.521237e2) record.setReadoutCorner(afwTable.LL) record.setHasRawInfo(False) self.orientation = orientation # compute TAN_PIXELS transform pScaleRad = afwGeom.arcsecToRad(self.plateScale) radialDistortCoeffs = [0.0, 1.0/pScaleRad, 0.0, self.radialDistortion/pScaleRad] focalPlaneToPupil = afwGeom.RadialXYTransform(radialDistortCoeffs) pixelToTanPixel = makePixelToTanPixel( bbox = self.bbox, orientation = self.orientation, focalPlaneToPupil = focalPlaneToPupil, pixelSizeMm = self.pixelSize, plateScale = self.plateScale, ) self.transMap = { FOCAL_PLANE: self.orientation.makePixelFpTransform(self.pixelSize), CameraSys(TAN_PIXELS, self.name): pixelToTanPixel, CameraSys(ACTUAL_PIXELS, self.name): afwGeom.RadialXYTransform([0, 0.95, 0.01]), } if modFunc: modFunc(self) self.detector = Detector( self.name, self.id, self.type, self.serial, self.bbox, self.ampInfo, self.orientation, self.pixelSize, self.transMap, )
def setUp(self): """Define parameters used by every test.""" filter_name = 'g' wavelength_step = 10.0 # nanometers self.pixel_scale = Angle(afwGeom.arcsecToRad(0.25)) # angle/pixel self.bandpass = BasicBandpass(filter_name=filter_name, wavelength_step=wavelength_step)