1 from builtins
import range
29 from .cachingSkyMap
import CachingSkyMap
30 from .tractInfo
import ExplicitTractInfo
32 __all__ = [
"RingsSkyMapConfig",
"RingsSkyMap"]
36 """Configuration for the RingsSkyMap""" 37 numRings = Field(dtype=int, doc=
"Number of rings", check=
lambda x: x > 0)
38 raStart = Field(dtype=float, default=0.0, doc=
"Starting center RA for each ring (degrees)",
39 check=
lambda x: x >= 0.0
and x < 360.0)
43 """Rings sky map pixelization. 45 We divide the sphere into N rings of Declination, plus the two polar 46 caps, which sets the size of the individual tracts. The rings are 47 divided in RA into an integral number of tracts of this size; this 48 division is made at the Declination closest to zero so as to ensure 51 ConfigClass = RingsSkyMapConfig
57 @param[in] config: an instance of self.ConfigClass; if None the default config is used 58 @param[in] version: software version of this class, to retain compatibility with old instances 62 self.
_ringSize = math.pi / (config.numRings + 1)
64 for i
in range(config.numRings):
65 startDec = self.
_ringSize*(i + 0.5) - 0.5*math.pi
67 dec = min(math.fabs(startDec), math.fabs(stopDec))
70 super(RingsSkyMap, self).
__init__(numTracts, config, version)
73 """Calculate ring indices given a numerical index of a tract 75 The ring indices are the ring number and the tract number within 78 The ring number is -1 for the south polar cap and increases to the 79 north. The north polar cap has ring number = numRings. The tract 80 number is zero for either of the polar caps. 85 return self.
config.numRings, 0
94 """Generate the TractInfo for this index""" 97 ra, dec = 0, -0.5*math.pi
98 elif ringNum == self.
config.numRings:
99 ra, dec = 0, 0.5*math.pi
101 dec = self.
_ringSize*(ringNum + 1) - 0.5*math.pi
102 ra = math.fmod(self.
config.raStart + 2*math.pi*tractNum/self.
_ringNums[ringNum], 2*math.pi)
104 center = afwGeom.SpherePoint(ra, dec, afwGeom.radians)
105 wcs = self.
_wcsFactory.makeWcs(crPixPos=afwGeom.Point2D(0, 0), crValCoord=center)
107 0.5*self.
_ringSize*afwGeom.radians, self.
config.tractOverlap*afwGeom.degrees,
111 """Find the tract whose center is nearest the specified coord. 113 @param[in] coord: sky coordinate (afwCoord.Coord) 114 @return TractInfo of tract whose center is nearest the specified coord 117 - if tracts do not cover the whole sky then the returned tract may not include the coord 120 - This routine will be more efficient if coord is ICRS. 121 - If coord is equidistant between multiple sky tract centers then one is arbitrarily chosen. 122 - The default implementation is not very efficient; subclasses may wish to override. 124 ra = coord.getLongitude().asRadians()
125 dec = coord.getLatitude().asRadians()
127 firstRingStart = self.
_ringSize*0.5 - 0.5*math.pi
128 if dec < firstRingStart:
131 elif dec > firstRingStart*-1:
135 ringNum = int((dec - firstRingStart)/self.
_ringSize)
136 tractNum = int(math.fmod(ra - self.
config.raStart, 2*math.pi) /
137 (2*math.pi/self.
_ringNums[ringNum]) + 0.5)
140 for i
in range(ringNum):
146 """Find all tracts which include the specified coord. 148 @param[in] coord: sky coordinate (afwCoord.Coord) 149 @return List of TractInfo of tracts which include the specified coord 152 - This routine will be more efficient if coord is ICRS. 154 ra = coord.getLongitude().asRadians()
155 dec = coord.getLatitude().asRadians()
157 firstRingStart = self.
_ringSize*0.5 - 0.5*math.pi
159 ringNum = int((dec - firstRingStart)/self.
_ringSize)
164 for r
in [ringNum - 1, ringNum, ringNum + 1]:
165 if r < 0
or r > self.
config.numRings - 1:
167 tractNum = int(math.fmod(ra - self.
config.raStart, 2*math.pi) /
170 for t
in [tractNum - 1, tractNum, tractNum + 1]:
182 if tract.contains(coord):
183 tractList.append(tract)
187 for entry
in [0, len(self)-1]:
189 if tract.contains(coord):
190 tractList.append(tract)
195 """Find tracts and patches that overlap a region 197 @param[in] coordList: list of sky coordinates (afwCoord.Coord) 198 @return list of (TractInfo, list of PatchInfo) for tracts and patches that contain, 199 or may contain, the specified region. The list will be empty if there is no overlap. 201 @warning this uses a naive algorithm that may find some tracts and patches that do not overlap 202 the region (especially if the region is not a rectangle aligned along patch x,y). 205 for coord
in coordList:
207 patchList = tractInfo.findPatchList(coordList)
208 if patchList
and not (tractInfo, patchList)
in retList:
209 retList.append((tractInfo, patchList))
213 """Add subclass-specific state or configuration options to the SHA1.""" 214 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)