Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# 

2# LSST Data Management System 

3# Copyright 2008, 2009, 2010 LSST Corporation. 

4# 

5# This product includes software developed by the 

6# LSST Project (http://www.lsst.org/). 

7# 

8# This program is free software: you can redistribute it and/or modify 

9# it under the terms of the GNU General Public License as published by 

10# the Free Software Foundation, either version 3 of the License, or 

11# (at your option) any later version. 

12# 

13# This program is distributed in the hope that it will be useful, 

14# but WITHOUT ANY WARRANTY; without even the implied warranty of 

15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

16# GNU General Public License for more details. 

17# 

18# You should have received a copy of the LSST License Statement and 

19# the GNU General Public License along with this program. If not, 

20# see <http://www.lsstcorp.org/LegalNotices/>. 

21# 

22 

23""" 

242015 December 10: 

25This is a modified version of the approximateWcs.py script from 

26meas_astrom 

27""" 

28 

29from builtins import range 

30import numpy as np 

31import lsst.afw.image as afwImage 

32import lsst.afw.table as afwTable 

33import lsst.geom as LsstGeom 

34from lsst.meas.base import SingleFrameMeasurementTask 

35from lsst.meas.astrom.sip import makeCreateWcsWithSip 

36from lsst.sims.coordUtils import raDecFromPixelCoords 

37 

38__all__ = ["approximateWcs"] 

39 

40def approximateWcs(wcs, camera_wrapper=None, detector_name=None, obs_metadata=None, 

41 order=3, nx=20, ny=20, iterations=3, 

42 skyTolerance=0.001*LsstGeom.arcseconds, pixelTolerance=0.02): 

43 """Approximate an existing WCS as a TAN-SIP WCS 

44 

45 The fit is performed by evaluating the WCS at a uniform grid of points within a bounding box. 

46 

47 @param[in] wcs wcs to approximate 

48 @param[in] camera_wrapper is an instantiation of GalSimCameraWrapper 

49 @param[in] detector_name is the name of the detector 

50 @param[in] obs_metadata is an ObservationMetaData characterizing the telescope pointing 

51 @param[in] order order of SIP fit 

52 @param[in] nx number of grid points along x 

53 @param[in] ny number of grid points along y 

54 @param[in] iterations number of times to iterate over fitting 

55 @param[in] skyTolerance maximum allowed difference in world coordinates between 

56 input wcs and approximate wcs (default is 0.001 arcsec) 

57 @param[in] pixelTolerance maximum allowed difference in pixel coordinates between 

58 input wcs and approximate wcs (default is 0.02 pixels) 

59 @return the fit TAN-SIP WCS 

60 """ 

61 tanWcs = wcs 

62 

63 # create a matchList consisting of a grid of points covering the bbox 

64 refSchema = afwTable.SimpleTable.makeMinimalSchema() 

65 refCoordKey = afwTable.CoordKey(refSchema["coord"]) 

66 refCat = afwTable.SimpleCatalog(refSchema) 

67 

68 sourceSchema = afwTable.SourceTable.makeMinimalSchema() 

69 SingleFrameMeasurementTask(schema=sourceSchema) # expand the schema 

70 sourceCentroidKey = afwTable.Point2DKey(sourceSchema["slot_Centroid"]) 

71 

72 sourceCat = afwTable.SourceCatalog(sourceSchema) 

73 

74 # 20 March 2017 

75 # the 'try' block is how it works in swig; 

76 # the 'except' block is how it works in pybind11 

77 try: 

78 matchList = afwTable.ReferenceMatchVector() 

79 except AttributeError: 

80 matchList = [] 

81 

82 bbox = camera_wrapper.getBBox(detector_name) 

83 bboxd = LsstGeom.Box2D(bbox) 

84 

85 for x in np.linspace(bboxd.getMinX(), bboxd.getMaxX(), nx): 

86 for y in np.linspace(bboxd.getMinY(), bboxd.getMaxY(), ny): 

87 pixelPos = LsstGeom.Point2D(x, y) 

88 

89 ra, dec = camera_wrapper.raDecFromPixelCoords(np.array([x]), np.array([y]), 

90 detector_name, 

91 obs_metadata=obs_metadata, 

92 epoch=2000.0, 

93 includeDistortion=True) 

94 

95 skyCoord = LsstGeom.SpherePoint(ra[0], dec[0], LsstGeom.degrees) 

96 

97 refObj = refCat.addNew() 

98 refObj.set(refCoordKey, skyCoord) 

99 

100 source = sourceCat.addNew() 

101 source.set(sourceCentroidKey, pixelPos) 

102 

103 matchList.append(afwTable.ReferenceMatch(refObj, source, 0.0)) 

104 

105 # The TAN-SIP fitter is fitting x and y separately, so we have to iterate to make it converge 

106 for indx in range(iterations) : 

107 sipObject = makeCreateWcsWithSip(matchList, tanWcs, order, bbox) 

108 tanWcs = sipObject.getNewWcs() 

109 fitWcs = sipObject.getNewWcs() 

110 

111 return fitWcs