def saveCalibration(dim, basedir, dtype, dateid, ccdid, ampid, filterid): # CFHTLS/%(dtype)/v%(dateid)/c%(ccdid)-a%(ampid).fits # -- or -- # CFHTLS/%(dtype)/v%(dateid)-f%(filterid)/c%(ccdid)-a%(ampid).fits if filterid == None: outdir = '%s/calib/%s/v%s' % (basedir, dtype, dateid) if dtype == 'dark': outdir = '%s/calib/%s/v%s-e%d' % ( basedir, dtype, dateid, int(dim.getMetadata().get('DARKTIME'))) else: outdir = '%s/calib/%s/v%s-f%s' % (basedir, dtype, dateid, filterid) if not os.path.isdir(outdir): os.makedirs(outdir) outfile = '%s/c%s-a%s.fits' % (outdir, ccdid, ampid) print '# writing', outfile # convert to exposure exp = afwImage.ExposureF(afwImage.MaskedImageF(dim.getImage()), afwImage.Wcs()) exp.setMetadata(dim.getMetadata()) if filterid == None: # For biases exp.setFilter(afwImage.Filter("u")) else: exp.setFilter(afwImage.Filter(filterid)) exp.getMetadata().set('DC3BPATH', outfile) exp.writeFits(outfile)
def test1(self): # This fails due to #1386 #wcsfn = os.path.join(self.datadir, 'imsim-v85518312-fu-R43-S12.wcs') wcsfn = os.path.join(self.datadir, 'imsim-v85518312-fu-R43-S12.wcs2') hdr = afwImage.readMetadata(wcsfn) wcs1 = afwImage.makeWcs(hdr) crval = wcs1.getSkyOrigin() cd = wcs1.getCDMatrix() print cd crval_p = afwGeom.Point2D(crval.getLongitude().asDegrees(), crval.getLatitude().asDegrees()) origin = wcs1.getPixelOrigin() print crval_p print origin wcs2 = afwImage.Wcs(crval_p, origin, cd) for wcs in [wcs1,wcs2]: print wcs print 'x, y, RA, Dec, pixscale("/pix), pixscale2' for x,y in [(0,0),(300,0),(350,0),(360,0),(370,0),(380,0),(400,0)]: radec = wcs.pixelToSky(x,y) ra = radec.getLongitude().asDegrees() dec = radec.getLatitude ().asDegrees() pixscale = 3600. * sqrt(wcs.pixArea(afwGeom.Point2D(x,y))) ps2 = wcs.pixelScale().asArcseconds() print x,y,ra,dec,pixscale,ps2 self.assertTrue(abs(pixscale - 0.2) < 1e-3) self.assertTrue(abs(ps2 - 0.2) < 1e-3)
def testMeasure(self): """Test that we can instantiate and play with RotationAngle""" scale = 5.0e-5 # Pixel scale: 0.18 arcsec/pixel for angle in (0, 45, 90, 120, 180, 275): angle = angle * afwGeom.degrees for expFactory in (afwImage.ExposureF, afwImage.ExposureD): cdMatrix = numpy.array([[scale * math.cos(angle.asRadians()), scale * math.sin(angle.asRadians())], [scale * -math.sin(angle.asRadians()), scale * math.cos(angle.asRadians())]]) wcs = afwImage.Wcs(afwGeom.Point2D(0, 0), afwGeom.Point2D(50, 50), cdMatrix) exp = expFactory(afwGeom.ExtentI(100, 100), wcs) x, y = 10, 20 exp.getMaskedImage().getImage().set(x, y, 1.0) east, north = self.measureRotAngle(exp, x, y) eastTrue = angle northTrue = angle + 90 * afwGeom.degrees while east < 0 * afwGeom.degrees: east = east + 360 * afwGeom.degrees while north < 0 * afwGeom.degrees: north = north + 360 * afwGeom.degrees while northTrue > 360 * afwGeom.degrees: northTrue = northTrue - 360 * afwGeom.degrees self.assertAlmostEqual(east.asRadians(), eastTrue.asRadians()) self.assertAlmostEqual(north.asRadians(), northTrue.asRadians())
def setUp(self): crval = afwGeom.Point2D(1.23, 5.67) crpix = afwGeom.Point2D(102., 201.) cd = numpy.array([[5.399452e-5, -1.30770e-5], [1.30770e-5, 5.399452e-5]], dtype=float) self.plainWcs = afwImage.Wcs(crval, crpix, cd) self.sipWcs = afwImage.TanWcs(crval, crpix, cd) self.distortedWcs = afwImage.TanWcs(crval, crpix, cd, cd, cd, cd, cd)
def getSipWcsFromWcs(self, wcs, bbox, ngrid=20, linearizeAtCenter=True): """!Get a TAN-SIP WCS, starting from an existing WCS. It uses your WCS to compute a fake grid of corresponding "stars" in pixel and sky coords, and feeds that to the regular SIP code. @param[in] wcs initial WCS @param[in] bbox bounding box of image @param[in] ngrid number of grid points along x and y for fitting (fit at ngrid^2 points) @param[in] linearizeAtCenter if True, get a linear approximation of the input WCS at the image center and use that as the TAN initialization for the TAN-SIP solution. You probably want this if your WCS has its CRPIX outside the image bounding box. """ # Ugh, build src and ref tables srcSchema = afwTable.SourceTable.makeMinimalSchema() key = srcSchema.addField("centroid", type="PointD") srcTable = afwTable.SourceTable.make(srcSchema) srcTable.defineCentroid("centroid") srcs = srcTable refs = afwTable.SimpleTable.make( afwTable.SimpleTable.makeMinimalSchema()) cref = [] csrc = [] (W, H) = bbox.getDimensions() x0, y0 = bbox.getMin() for xx in np.linspace(0., W, ngrid): for yy in np.linspace(0, H, ngrid): src = srcs.makeRecord() src.set(key.getX(), x0 + xx) src.set(key.getY(), y0 + yy) csrc.append(src) rd = wcs.pixelToSky(xx + x0, yy + y0) ref = refs.makeRecord() ref.setCoord(rd) cref.append(ref) if linearizeAtCenter: # Linearize the original WCS around the image center to create a # TAN WCS. # Reference pixel in LSST coords crpix = afwGeom.Box2D(bbox).getCenter() crval = wcs.pixelToSky(crpix) crval = crval.getPosition(afwGeom.degrees) # Linearize *AT* crval to get effective CD at crval. # (we use the default skyUnit of degrees as per WCS standard) aff = wcs.linearizePixelToSky(crval) cd = aff.getLinear().getMatrix() wcs = afwImage.Wcs(crval, crpix, cd) return self.getSipWcsFromCorrespondences(wcs, cref, csrc, (W, H), x0=x0, y0=y0)
def acsEventCallback(key, source, im, frame): """Callback for event handlers to find COSMOS ACS cutout. \param key Key struck \param source The Source under the cursor \param im The (HSC) image cutout displayed in frame \param frame The frame that the HSC data's displayed in (we'll use the next one) We also use the following static members of utils.EventHandler (if set): sizeCutout The size of the HSC cutout (arcsec; default: 4.0) scale Make the COSMOS image with pixel size scale*HSC's pixel size (default 0.25 => 0.42mas) Use as e.g. utils.eventCallbacks['c'] = cosmos.acsEventCallback """ sizeCutout = utils.EventHandler.sizeCutout if hasattr( utils.EventHandler, "sizeCutout") else 4.0 # arcsec scale = utils.EventHandler.scale if hasattr( utils.EventHandler, "scale") else 0.25 # Pixel size scaling pos = source.get("coord") exp = getCosmosCutout(*pos.getPosition(), sizeX=sizeCutout) if im and exp and exp.getWcs(): # # Resample and rotate to the HSC orientation # warpingControl = afwMath.WarpingControl("lanczos3") rat = im.getWcs().pixelScale().asArcseconds() / exp.getWcs( ).pixelScale().asArcseconds() hsize = int(0.5 * exp.getWidth() / (scale * rat)) rexp = afwImage.ExposureF(2 * hsize + 1, 2 * hsize + 1) rexp.setWcs( afwImage.Wcs(pos.getPosition(), afwGeom.Point2D(hsize, hsize), im.getWcs().getCDMatrix() * scale)) afwMath.warpExposure(rexp, exp, warpingControl) else: print "\nI'm unable to remap the cosmos image to your coordinates, sorry" rexp = exp.getMaskedImage().getImage() frame += 1 rim = rexp if hasattr(rim, "getMaskedImage"): rim = rim.getMaskedImage().getImage() if hasattr(rim, "getImage"): rim = rim.getImage() disp = afwDisplay.Display(frame=frame) disp.mtv(rim) if hasattr(rexp, "getWcs"): cen = rexp.getWcs().skyToPixel(pos) - afwGeom.PointD(rexp.getXY0()) disp.pan(*cen) disp.dot('+', *cen)
def process(self): clipboard = self.inputQueue.getNextDataset() metadataPolicy = self._policy.getPolicy("metadata") datatypePolicy = self._policy.getPolicy("datatype") imageKey = self._policy.get("imageKey") metadataKey = self._policy.get("metadataKey") wcsKey = self._policy.get("wcsKey") decoratedImage = clipboard.get(imageKey) metadata = decoratedImage.getMetadata() if self._policy.exists("suffix"): suffix = self._policy.get("suffix") else: suffix = "Keyword" if self._policy.exists("computeWcsGuess"): if self._policy.getBool("computeWcsGuess"): wcs = afwImage.Wcs(metadata) ampBBoxKey = self._policy.getString("ampBBoxKey") ampBBox = clipboard.get(ampBBoxKey) wcs.shiftReferencePixel(ampBBox.getX0(), ampBBox.getY0()) clipboard.put(wcsKey, wcs) # set various exposure id's needed by downstream stages ccdId = clipboard.get("ccdId") ampId = clipboard.get("ampId") eventName = self._policy.get("eventName") event = clipboard.get(eventName) exposureId = event.get("exposureId") fpaExposureId = exposureId ccdExposureId = (fpaExposureId << 8) + ccdId ampExposureId = (ccdExposureId << 6) + ampId metadata.setLongLong('ampExposureId', ampExposureId) metadata.setLongLong('ccdExposureId', ccdExposureId) metadata.setLongLong('fpaExposureId', fpaExposureId) metadata.set('ampId', ampId) metadata.set('ccdId', ampId) # metadata.set('url', metadata.get('filename')) # who uses this?? transformMetadata(metadata, datatypePolicy, metadataPolicy, suffix) clipboard.put(metadataKey, metadata) clipboard.put(imageKey, decoratedImage.getImage()) self.outputQueue.addDataset(clipboard)
def initialWcs(self, matches, wcs): """Generate a guess Wcs from the astrometric matches We create a Wcs anchored at the center of the matches, with the scale of the input Wcs. This is necessary because matching returns only matches with no estimated Wcs, and the input Wcs is a wild guess. We're using the best of each: positions from the matches, and scale from the input Wcs. """ crpix = afwGeom.Extent2D(0, 0) crval = afwGeom.Extent3D(0, 0, 0) for mm in matches: crpix += afwGeom.Extent2D(mm.second.getCentroid()) crval += afwGeom.Extent3D(mm.first.getCoord().toIcrs().getVector()) crpix /= len(matches) crval /= len(matches) newWcs = afwImage.Wcs( afwCoord.IcrsCoord(afwGeom.Point3D(crval)).getPosition(), afwGeom.Point2D(crpix), wcs.getCDMatrix()) return newWcs
def std_raw_md(self, md, dataId): if False: # no std_raw_md in baseclass md = super(HscMapper, self).std_raw_md(md, dataId) # not present in baseclass # # We need to flip the WCS defined by the metadata in case anyone ever constructs a Wcs from it # wcs = afwImage.makeWcs(md) self._flipChipsLR(None, wcs, dataId, dims=afwImage.bboxFromMetadata(md).getDimensions()) wcsR = afwImage.Wcs(wcs.getSkyOrigin().getPosition(), wcs.getPixelOrigin(), wcs.getCDMatrix() * 0.992) wcsMd = wcsR.getFitsMetadata() for k in wcsMd.names(): md.set(k, wcsMd.get(k)) return md
def process(self): clipboard = self.inputQueue.getNextDataset() metadataPolicy = self._policy.getPolicy("metadata") datatypePolicy = self._policy.getPolicy("datatype") imageKey = self._policy.get("imageKey") metadataKey = self._policy.get("metadataKey") exposureMetadataKey = self._policy.get("exposureMetadataKey") wcsKey = self._policy.get("wcsKey") decoratedImage = clipboard.get(imageKey) exposureMetadata = clipboard.get(exposureMetadataKey) metadata = decoratedImage.getMetadata() if self._policy.exists("suffix"): suffix = self._policy.get("suffix") else: suffix = "Keyword" if self._policy.exists("computeWcsGuess"): if self._policy.getBool("computeWcsGuess"): wcs = afwImage.Wcs(metadata) ampBBoxKey = self._policy.getString("ampBBoxKey") ampBBox = clipboard.get(ampBBoxKey) wcs.shiftReferencePixel(ampBBox.getX0(), ampBBox.getY0()) clipboard.put(wcsKey, wcs) transformMetadata(metadata, datatypePolicy, metadataPolicy, suffix) metadata.setLongLong('ampExposureId', exposureMetadata.get('ampExposureId')) metadata.setLongLong('ccdExposureId', exposureMetadata.get('ccdExposureId')) metadata.setLongLong('fpaExposureId', exposureMetadata.get('fpaExposureId')) metadata.set('url', metadata.get('filename')) metadata.set('ampId', clipboard.get('ampId')) clipboard.put(metadataKey, metadata) clipboard.put(imageKey, decoratedImage.getImage()) self.outputQueue.addDataset(clipboard)
def std_raw(self, item, dataId): exposure = super(LsstSimMapper, self).std_raw(item, dataId) md = exposure.getMetadata() if md.exists("VERSION") and md.getInt("VERSION") < 16952: # Precess crval of WCS from date of observation to J2000 epoch = exposure.getInfo().getVisitInfo().getDate().get( dafBase.DateTime.EPOCH) if math.isnan(epoch): raise RuntimeError("Date not found in raw exposure %s" % (dataId, )) wcs = exposure.getWcs() origin = wcs.getSkyOrigin() refCoord = afwCoord.Fk5Coord(origin.getLongitude(), origin.getLatitude(), epoch) newRefCoord = refCoord.precess(2000.) crval = afwGeom.PointD() crval.setX(newRefCoord.getRa().asDegrees()) crval.setY(newRefCoord.getDec().asDegrees()) wcs = afwImage.Wcs(crval, wcs.getPixelOrigin(), wcs.getCDMatrix()) exposure.setWcs(wcs) return exposure
def run(self, sensorRefList, calibType): """Process a calibration frame. @param sensorRef: sensor-level butler data reference @return pipe_base Struct containing these fields: - masterExpList: amp exposures of master calibration products """ referenceAmps = sensorRefList[0].subItems(level="channel") masterExpList = [] dataIdList = [] expmeta = None for amp in referenceAmps: if amp.dataId['snap'] == 1: continue self.log.info("Amp: Processing %s", amp.dataId) print "dataid %s" % (amp.dataId) butler = amp.butlerSubset.butler ampMIList = afwImage.vectorMaskedImageF() for sRef in sensorRefList: self.log.info("Sensor: Processing %s", sRef.dataId) ampSnapMIList = afwImage.vectorMaskedImageF() dataId = eval(amp.dataId.__repr__()) dataId['visit'] = sRef.dataId['visit'] for snap in (0, 1): dataId['snap'] = snap ampExposure = sRef.butlerSubset.butler.get('raw', dataId) if expmeta is None: expmeta = ampExposure.getMetadata() expfilter = ampExposure.getFilter() expcalib = ampExposure.getCalib() ampDetector = cameraGeom.cast_Amp( ampExposure.getDetector()) ampExposure = self.convertIntToFloat(ampExposure) ampExpDataView = ampExposure.Factory( ampExposure, ampDetector.getDiskDataSec()) self.saturationDetection(ampExposure, ampDetector) self.overscanCorrection(ampExposure, ampDetector) if calibType in ('flat', 'dark'): self.biasCorrection(ampExpDataView, amp) if False: self.darkCorrection(ampExpDataView, amp) self.updateVariance(ampExpDataView, ampDetector) ampSnapMIList.append(ampExpDataView.getMaskedImage()) ampMIList.append(self.combineMIList(ampSnapMIList)) masterFrame = self.combineMIList(ampMIList) # Fix saturation too??? self.fixDefectsAndSat(masterFrame, ampDetector) exp = afwImage.ExposureF(masterFrame) self.copyMetadata(exp, expmeta, calibType) exp.setDetector(ampDetector) exp.setWcs(afwImage.Wcs()) exp.setCalib(expcalib) if calibType is 'flat': exp.setFilter(expfilter) if self.config.doWrite and calibType is not 'flat': print "writing file %s" % dataId butler.put(exp, calibType, dataId=amp.dataId) masterExpList.append(exp) dataIdList.append(amp.dataId) if self.config.doWrite and calibType is 'flat': self.normChipAmps(masterExpList) for exp, dataId in zip(masterExpList, dataIdList): print "writing flat file %s" % dataId butler.put(exp, calibType, dataId) return pipeBase.Struct(masterFrameList=masterExpList, )
def testConstructor(self): copy = afwImage.Wcs(self.wcs.getSkyOrigin(), self.wcs.getPixelOrigin(), self.wcs.getCDMatrix())
def makeCcdMosaic(dir, basename, e, c, aList, imageFactory=afwImage.MaskedImageF, verbose=0): """Return an image of all the specified amplifiers, aList, for the given CCD E.g. sl = makeCcdMosaic("/lsst/DC3root/rlp1173", "v704897", 0, 3, range(8)) """ try: aList[0] except TypeError: aList = [aList] for what in ("header", "data"): if what == "header": bbox = afwGeom.Box2I() ampBBox = {} wcs = {} else: ccdImage = imageFactory(bbox.getWidth(), bbox.getHeight()) ccdImage.set(0) ccdImage.setXY0(bbox.getLLC()) for a in aList: filename = os.path.join( dir, "IPSD", "output", "sci", "%s-e%d" % (basename, e), "%s-e%d-c%03d-a%02d.sci" % (basename, e, c, a)) if verbose and what == "header": print(filename) if what == "header": md = afwImage.readMetadata(filename + "_img.fits") xy0 = afwGeom.Point2I(md.get("CRVAL1A"), md.get("CRVAL2A")) xy1 = xy0 + afwGeom.Extent2I( md.get("NAXIS1") - 1, md.get("NAXIS2") - 1) bbox.grow(xy0) bbox.grow(xy1) ampBBox[a] = afwGeom.Box2I(xy0, xy1) wcs[a] = afwImage.Wcs(md) else: try: data = imageFactory(filename + "_img.fits") except: data = imageFactory(filename) ampImage = ccdImage.Factory(ccdImage, ampBBox[a]) ampImage[:] = data del ampImage try: ccdImage.getMask() if 0 in wcs: ccdImage = afwImage.ExposureF(ccdImage, wcs[0]) except AttributeError: pass return ccdImage
def testConstructor(self): copy = afwImage.Wcs( self.wcs.getSkyOrigin().getPosition(afwGeom.degrees), self.wcs.getPixelOrigin(), self.wcs.getCDMatrix())
imageSigma = %0.1f variance = %0.1f """ % (coaddPath, numImages, config.imageShape, config.imageSigma, config.variance)) np.random.seed(0) coadd = None for imInd in range(numImages): print("Create exposure %d" % (imInd, ), file=sys.stderr) maskedImage = afwTestUtils.makeGaussianNoiseMaskedImage( dimensions=config.imageShape, sigma=config.imageSigma, variance=config.variance) # the WCS doesn't matter; the default will do wcs = afwImage.Wcs() exposure = afwImage.ExposureF(maskedImage, wcs) if not coadd: print("Create coadd", file=sys.stderr) coadd = coaddChiSq.Coadd.fromConfig(bbox=exposure.getBBox(), wcs=exposure.getWcs(), config=config.coadd) print("badPixelMask=", coadd.getBadPixelMask(), file=sys.stderr) coadd.addExposure(exposure) print("Save weight map as %s" % (weightPath, ), file=sys.stderr) weightMap = coadd.getWeightMap() weightMap.writeFits(weightPath) coaddExposure = coadd.getCoadd()