24 - Consider tweaking pixel scale so the average scale is as specified, rather than the scale at the center
30 __all__ = [
"BaseSkyMap"]
33 patchInnerDimensions = pexConfig.ListField(
34 doc =
"dimensions of inner region of patches (x,y pixels)",
37 default = (4000, 4000),
39 patchBorder = pexConfig.Field(
40 doc =
"border between patch inner and outer bbox (pixels)",
44 tractOverlap = pexConfig.Field(
45 doc =
"minimum overlap between adjacent sky tracts, on the sky (deg)",
49 pixelScale = pexConfig.Field(
50 doc =
"nominal pixel scale (arcsec/pixel)",
54 projection = pexConfig.Field(
55 doc =
"""one of the FITS WCS projection codes, such as:
56 - STG: stereographic projection
57 - MOL: Molleweide's projection
58 - TAN: tangent-plane projection
63 rotation = pexConfig.Field(
64 doc =
"Rotation for WCS (deg)",
71 """A collection of overlapping Tracts that map part or all of the sky.
73 See TractInfo for more information.
75 BaseSkyMap is an abstract base class. Subclasses must do the following:
76 @li define __init__ and have it construct the TractInfo objects and put them in _tractInfoList
77 @li define __getstate__ and __setstate__ to allow pickling (the butler saves sky maps using pickle);
78 see DodecaSkyMap for an example of how to do this. (Most of that code could be moved
79 into this base class, but that would make it harder to handle older versions of pickle data.)
81 ConfigClass = BaseSkyMapConfig
83 """Construct a BaseSkyMap
85 @param[in] config: an instance of self.ConfigClass; if None the default config is used
93 pixelScale =
afwGeom.Angle(self.config.pixelScale, afwGeom.arcseconds),
94 projection = self.config.projection,
95 rotation =
afwGeom.Angle(self.config.rotation, afwGeom.degrees),
99 """Find the tract whose center is nearest the specified coord.
101 @param[in] coord: sky coordinate (afwCoord.Coord)
102 @return TractInfo of tract whose center is nearest the specified coord
105 - if tracts do not cover the whole sky then the returned tract may not include the coord
108 - This routine will be more efficient if coord is ICRS.
109 - If coord is equidistant between multiple sky tract centers then one is arbitrarily chosen.
110 - The default implementation is not very efficient; subclasses may wish to override.
112 icrsCoord = coord.toIcrs()
113 distTractInfoList = []
114 for tractInfo
in self:
115 angSep = icrsCoord.angularSeparation(tractInfo.getCtrCoord()).asDegrees()
116 distTractInfoList.append((angSep, tractInfo))
117 distTractInfoList.sort()
118 return distTractInfoList[0][1]
121 """Find tracts and patches that overlap a region
123 @param[in] coordList: list of sky coordinates (afwCoord.Coord)
124 @return list of (TractInfo, list of PatchInfo) for tracts and patches that contain,
125 or may contain, the specified region. The list will be empty if there is no overlap.
127 @warning this uses a naive algorithm that may find some tracts and patches that do not overlap
128 the region (especially if the region is not a rectangle aligned along patch x,y).
131 for tractInfo
in self:
132 patchList = tractInfo.findPatchList(coordList)
134 retList.append((tractInfo, patchList))