28 from .cachingSkyMap
import CachingSkyMap
29 from .tractInfo
import ExplicitTractInfo
31 __all__ = [
"RingsSkyMapConfig",
"RingsSkyMap"]
35 """Configuration for the RingsSkyMap""" 36 numRings = Field(dtype=int, doc=
"Number of rings", check=
lambda x: x > 0)
37 raStart = Field(dtype=float, default=0.0, doc=
"Starting center RA for each ring (degrees)",
38 check=
lambda x: x >= 0.0
and x < 360.0)
42 """Rings sky map pixelization. 44 We divide the sphere into N rings of Declination, plus the two polar 45 caps, which sets the size of the individual tracts. The rings are 46 divided in RA into an integral number of tracts of this size; this 47 division is made at the Declination closest to zero so as to ensure 50 ConfigClass = RingsSkyMapConfig
56 @param[in] config: an instance of self.ConfigClass; if None the default config is used 57 @param[in] version: software version of this class, to retain compatibility with old instances 61 self.
_ringSize = math.pi / (config.numRings + 1)
63 for i
in range(config.numRings):
64 startDec = self.
_ringSize*(i + 0.5) - 0.5*math.pi
66 dec = min(math.fabs(startDec), math.fabs(stopDec))
69 super(RingsSkyMap, self).
__init__(numTracts, config, version)
72 """Calculate ring indices given a numerical index of a tract 74 The ring indices are the ring number and the tract number within 77 The ring number is -1 for the south polar cap and increases to the 78 north. The north polar cap has ring number = numRings. The tract 79 number is zero for either of the polar caps. 84 return self.
config.numRings, 0
93 """Generate the TractInfo for this index""" 96 ra, dec = 0, -0.5*math.pi
97 elif ringNum == self.
config.numRings:
98 ra, dec = 0, 0.5*math.pi
100 dec = self.
_ringSize*(ringNum + 1) - 0.5*math.pi
101 ra = math.fmod(self.
config.raStart + 2*math.pi*tractNum/self.
_ringNums[ringNum], 2*math.pi)
103 center = afwGeom.SpherePoint(ra, dec, afwGeom.radians)
104 wcs = self.
_wcsFactory.makeWcs(crPixPos=afwGeom.Point2D(0, 0), crValCoord=center)
106 0.5*self.
_ringSize*afwGeom.radians, self.
config.tractOverlap*afwGeom.degrees,
110 """Find the tract whose center is nearest the specified coord. 112 @param[in] coord: sky coordinate (afwCoord.Coord) 113 @return TractInfo of tract whose center is nearest the specified coord 116 - if tracts do not cover the whole sky then the returned tract may not include the coord 119 - This routine will be more efficient if coord is ICRS. 120 - If coord is equidistant between multiple sky tract centers then one is arbitrarily chosen. 121 - The default implementation is not very efficient; subclasses may wish to override. 123 ra = coord.getLongitude().asRadians()
124 dec = coord.getLatitude().asRadians()
126 firstRingStart = self.
_ringSize*0.5 - 0.5*math.pi
127 if dec < firstRingStart:
130 elif dec > firstRingStart*-1:
134 ringNum = int((dec - firstRingStart)/self.
_ringSize)
135 tractNum = int(math.fmod(ra - self.
config.raStart, 2*math.pi) /
136 (2*math.pi/self.
_ringNums[ringNum]) + 0.5)
139 for i
in range(ringNum):
145 """Find all tracts which include the specified coord. 147 @param[in] coord: sky coordinate (afwCoord.Coord) 148 @return List of TractInfo of tracts which include the specified coord 151 - This routine will be more efficient if coord is ICRS. 153 ra = coord.getLongitude().asRadians()
154 dec = coord.getLatitude().asRadians()
156 firstRingStart = self.
_ringSize*0.5 - 0.5*math.pi
158 ringNum = int((dec - firstRingStart)/self.
_ringSize)
163 for r
in [ringNum - 1, ringNum, ringNum + 1]:
164 if r < 0
or r > self.
config.numRings - 1:
166 tractNum = int(math.fmod(ra - self.
config.raStart, 2*math.pi) /
169 for t
in [tractNum - 1, tractNum, tractNum + 1]:
181 if tract.contains(coord):
182 tractList.append(tract)
186 for entry
in [0, len(self)-1]:
188 if tract.contains(coord):
189 tractList.append(tract)
194 """Find tracts and patches that overlap a region 196 @param[in] coordList: list of sky coordinates (afwCoord.Coord) 197 @return list of (TractInfo, list of PatchInfo) for tracts and patches that contain, 198 or may contain, the specified region. The list will be empty if there is no overlap. 200 @warning this uses a naive algorithm that may find some tracts and patches that do not overlap 201 the region (especially if the region is not a rectangle aligned along patch x,y). 204 for coord
in coordList:
206 patchList = tractInfo.findPatchList(coordList)
207 if patchList
and not (tractInfo, patchList)
in retList:
208 retList.append((tractInfo, patchList))
212 """Add subclass-specific state or configuration options to the SHA1.""" 213 sha1.update(struct.pack(
"<id", self.
config.numRings, self.
config.raStart))
def generateTract(self, index)
def findTractPatchList(self, coordList)
def updateSha1(self, sha1)
def findTract(self, coord)
def getRingIndices(self, index)
def findAllTracts(self, coord)
def __init__(self, config, version=0)