LSST Applications g02d81e74bb+86cf3d8bc9,g180d380827+7a4e862ed4,g2079a07aa2+86d27d4dc4,g2305ad1205+e1ca1c66fa,g29320951ab+012e1474a1,g295015adf3+341ea1ce94,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+c429d67c83,g48712c4677+f88676dd22,g487adcacf7+27e1e21933,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+b41db86c35,g5a732f18d5+53520f316c,g64a986408d+86cf3d8bc9,g858d7b2824+86cf3d8bc9,g8a8a8dda67+585e252eca,g99cad8db69+84912a7fdc,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,ga8c6da7877+a2b54eae19,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+6681f309db,gc120e1dc64+f0fcc2f6d8,gc28159a63d+0e5473021a,gcf0d15dbbd+c429d67c83,gdaeeff99f8+f9a426f77a,ge6526c86ff+0433e6603d,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+86cf3d8bc9,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
lsst.skymap.ringsSkyMap.RingsSkyMap Class Reference
Inheritance diagram for lsst.skymap.ringsSkyMap.RingsSkyMap:
lsst.skymap.cachingSkyMap.CachingSkyMap lsst.skymap.baseSkyMap.BaseSkyMap

Public Member Functions

 __init__ (self, config, version=1)
 
 getRingIndices (self, index)
 
 generateTract (self, index)
 
 findTract (self, coord)
 
 findTractIdArray (self, ra, dec, degrees=False)
 
 findAllTracts (self, coord)
 
 findTractPatchList (self, coordList)
 
 updateSha1 (self, sha1)
 

Static Public Attributes

 ConfigClass = RingsSkyMapConfig
 

Protected Member Functions

 _decToRingNum (self, dec)
 
 _raToTractNum (self, ra, ringNum)
 

Protected Attributes

 _ringSize
 
 _ringNums
 
 _raStart
 
 _version
 
 _tractBuilder
 

Static Protected Attributes

tuple _version = (1, 0)
 

Detailed Description

Rings sky map pixelization.

We divide the sphere into N rings of Declination, plus the two polar
caps, which sets the size of the individual tracts.  The rings are
divided in RA into an integral number of tracts of this size; this
division is made at the Declination closest to zero so as to ensure
full overlap.

Rings are numbered in the rings from south to north. The south pole cap is
``tract=0``, then the tract at ``raStart`` in the southernmost ring is
``tract=1``. Numbering continues (in the positive RA direction) around that
ring and then continues in the same fashion with the next ring north, and
so on until all reaching the north pole cap, which is
``tract=len(skymap) - 1``.

However, ``version=0`` had a bug in the numbering of the tracts: the first
and last tracts in the first (southernmost) ring were identical, and the
first tract in the last (northernmost) ring was missing. When using
``version=0``, these tracts remain missing in order to preserve the
numbering scheme.

Parameters
----------
config : `lsst.skymap.RingsSkyMapConfig`
    The configuration for this SkyMap.
version : `int`, optional
    Software version of this class, to retain compatibility with old
    verisons. ``version=0`` covers the period from first implementation
    until DM-14809, at which point bugs were identified in the numbering
    of tracts (affecting only tracts at RA=0). ``version=1`` uses the
    post-DM-14809 tract numbering.

Definition at line 42 of file ringsSkyMap.py.

Constructor & Destructor Documentation

◆ __init__()

lsst.skymap.ringsSkyMap.RingsSkyMap.__init__ ( self,
config,
version = 1 )

Reimplemented from lsst.skymap.cachingSkyMap.CachingSkyMap.

Definition at line 78 of file ringsSkyMap.py.

78 def __init__(self, config, version=1):
79 assert version in (0, 1), "Unrecognised version: %s" % (version,)
80 # We count rings from south to north
81 # Note: pole caps together count for one additional ring when
82 # calculating the ring size.
83 self._ringSize = math.pi / (config.numRings + 1) # Size of a ring in Declination (radians)
84 self._ringNums = [] # Number of tracts for each ring
85 for i in range(config.numRings):
86 startDec = self._ringSize*(i + 0.5) - 0.5*math.pi
87 stopDec = startDec + self._ringSize
88 dec = min(math.fabs(startDec), math.fabs(stopDec)) # Declination for determining division in RA
89 self._ringNums.append(int(2*math.pi*math.cos(dec)/self._ringSize) + 1)
90 numTracts = sum(self._ringNums) + 2
91 super(RingsSkyMap, self).__init__(numTracts, config, version)
92 self._raStart = self.config.raStart*geom.degrees
93
int min

Member Function Documentation

◆ _decToRingNum()

lsst.skymap.ringsSkyMap.RingsSkyMap._decToRingNum ( self,
dec )
protected
Calculate ring number from Declination.

Parameters
----------
dec : `lsst.geom.Angle`
    Declination.

Returns
-------
ringNum : `int`
    Ring number: -1 for the south polar cap, and increasing to the
    north, ending with ``numRings`` for the north polar cap.

Definition at line 143 of file ringsSkyMap.py.

143 def _decToRingNum(self, dec):
144 """Calculate ring number from Declination.
145
146 Parameters
147 ----------
148 dec : `lsst.geom.Angle`
149 Declination.
150
151 Returns
152 -------
153 ringNum : `int`
154 Ring number: -1 for the south polar cap, and increasing to the
155 north, ending with ``numRings`` for the north polar cap.
156 """
157 firstRingStart = self._ringSize*0.5 - 0.5*math.pi
158 if dec < firstRingStart:
159 # Southern cap
160 return -1
161 elif dec > firstRingStart*-1:
162 # Northern cap
163 return self.config.numRings
164 return int((dec.asRadians() - firstRingStart)/self._ringSize)
165

◆ _raToTractNum()

lsst.skymap.ringsSkyMap.RingsSkyMap._raToTractNum ( self,
ra,
ringNum )
protected
Calculate tract number from the Right Ascension.

Parameters
----------
ra : `lsst.geom.Angle`
    Right Ascension.
ringNum : `int`
    Ring number (from ``_decToRingNum``).

Returns
-------
tractNum : `int`
    Tract number within the ring (starts at 0 for the tract at
    ``raStart``).

Definition at line 166 of file ringsSkyMap.py.

166 def _raToTractNum(self, ra, ringNum):
167 """Calculate tract number from the Right Ascension.
168
169 Parameters
170 ----------
171 ra : `lsst.geom.Angle`
172 Right Ascension.
173 ringNum : `int`
174 Ring number (from ``_decToRingNum``).
175
176 Returns
177 -------
178 tractNum : `int`
179 Tract number within the ring (starts at 0 for the tract at
180 ``raStart``).
181 """
182 if ringNum in (-1, self.config.numRings):
183 return 0
184 assert ringNum in range(self.config.numRings)
185 tractNum = int((ra - self._raStart).wrap().asRadians()
186 / (2*math.pi/self._ringNums[ringNum]) + 0.5)
187 return 0 if tractNum == self._ringNums[ringNum] else tractNum # Allow wraparound
188

◆ findAllTracts()

lsst.skymap.ringsSkyMap.RingsSkyMap.findAllTracts ( self,
coord )
Find all tracts which include the specified coord.

Parameters
----------
coord : `lsst.geom.SpherePoint`
    ICRS sky coordinate to search for.

Returns
-------
tractList : `list` of `TractInfo`
    The tracts which include the specified coord.

Definition at line 255 of file ringsSkyMap.py.

255 def findAllTracts(self, coord):
256 """Find all tracts which include the specified coord.
257
258 Parameters
259 ----------
260 coord : `lsst.geom.SpherePoint`
261 ICRS sky coordinate to search for.
262
263 Returns
264 -------
265 tractList : `list` of `TractInfo`
266 The tracts which include the specified coord.
267 """
268 ringNum = self._decToRingNum(coord.getLatitude())
269
270 tractList = list()
271 # ringNum denotes the closest ring to the specified coord
272 # I will check adjacent rings which may include the specified coord
273 for r in [ringNum - 1, ringNum, ringNum + 1]:
274 if r < 0 or r >= self.config.numRings:
275 # Poles will be checked explicitly outside this loop
276 continue
277 tractNum = self._raToTractNum(coord.getLongitude(), r)
278 # Adjacent tracts will also be checked.
279 for t in [tractNum - 1, tractNum, tractNum + 1]:
280 # Wrap over raStart
281 if t < 0:
282 t = t + self._ringNums[r]
283 elif t > self._ringNums[r] - 1:
284 t = t - self._ringNums[r]
285
286 extra = 0
287 if self._version == 0 and t == 0 and r != 0:
288 # Account for off-by-one error in getRingIndices
289 # Note that this means that tract 1 gets duplicated.
290 extra = 1
291
292 index = sum(self._ringNums[:r + extra], t + 1) # Allow 1 for south pole
293 tract = self[index]
294 if tract.contains(coord):
295 tractList.append(tract)
296
297 # Always check tracts at poles
298 # Southern cap is 0, Northern cap is the last entry in self
299 for entry in [0, len(self)-1]:
300 tract = self[entry]
301 if tract.contains(coord):
302 tractList.append(tract)
303
304 return tractList
305

◆ findTract()

lsst.skymap.ringsSkyMap.RingsSkyMap.findTract ( self,
coord )
Find the tract whose center is nearest the specified coord.

Parameters
----------
coord : `lsst.geom.SpherePoint`
    ICRS sky coordinate to search for.

Returns
-------
result : `TractInfo`
    TractInfo of tract whose center is nearest the specified coord.

Notes
-----
- If coord is equidistant between multiple sky tract centers then one
  is arbitrarily chosen.

- The default implementation is not very efficient; subclasses may wish
  to override.

.. warning::

   If tracts do not cover the whole sky then the returned tract may not
   include the coord.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 189 of file ringsSkyMap.py.

189 def findTract(self, coord):
190 ringNum = self._decToRingNum(coord.getLatitude())
191 if ringNum == -1:
192 # Southern cap
193 return self[0]
194 if ringNum == self.config.numRings:
195 # Northern cap
196 return self[self._numTracts - 1]
197 tractNum = self._raToTractNum(coord.getLongitude(), ringNum)
198
199 if self._version == 0 and tractNum == 0 and ringNum != 0:
200 # Account for off-by-one error in getRingIndices
201 # Note that this means that tract 1 gets duplicated.
202 ringNum += 1
203
204 index = sum(self._ringNums[:ringNum], tractNum + 1) # Allow 1 for south pole
205 return self[index]
206

◆ findTractIdArray()

lsst.skymap.ringsSkyMap.RingsSkyMap.findTractIdArray ( self,
ra,
dec,
degrees = False )
Find array of tract IDs with vectorized operations (where
supported).

If a given sky map does not support vectorized operations, then a loop
over findTract will be called.

Parameters
----------
ra : `numpy.ndarray`
    Array of Right Ascension.  Units are radians unless
    degrees=True.
dec : `numpy.ndarray`
    Array of Declination.  Units are radians unless
    degrees=True.
degrees : `bool`, optional
    Input ra, dec arrays are degrees if `True`.

Returns
-------
tractId : `numpy.ndarray`
    Array of tract IDs

Notes
-----
- If coord is equidistant between multiple sky tract centers then one
  is arbitrarily chosen.

.. warning::

   If tracts do not cover the whole sky then the returned tract may not
   include the given ra/dec.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 207 of file ringsSkyMap.py.

207 def findTractIdArray(self, ra, dec, degrees=False):
208 if degrees:
209 _ra = np.deg2rad(ra)
210 _dec = np.deg2rad(dec)
211 else:
212 _ra = np.atleast_1d(ra)
213 _dec = np.atleast_1d(dec)
214
215 # Set default to -1 to distinguish from polar tracts
216 indexes = np.full(_ra.size, -1, dtype=np.int32)
217
218 # Do the dec search
219 firstRingStart = self._ringSize*0.5 - 0.5*np.pi
220 ringNums = np.zeros(len(_dec), dtype=np.int32)
221
222 ringNums[_dec < firstRingStart] = -1
223 ringNums[_dec > -1*firstRingStart] = self.config.numRings
224
225 mid = (_dec >= firstRingStart) & (_dec <= -1*firstRingStart)
226 ringNums[mid] = ((_dec[mid] - firstRingStart)/self._ringSize).astype(np.int32)
227
228 indexes[ringNums == -1] = 0
229 indexes[ringNums == self.config.numRings] = self._numTracts - 1
230
231 # We now do the full lookup for all non-polar tracts that have not
232 # been set.
233 inRange, = np.where(indexes < 0)
234
235 # Do the ra search
236 _ringNumArray = np.array(self._ringNums)
237 _ringCumulative = np.cumsum(np.insert(_ringNumArray, 0, 0))
238
239 deltaWrap = (_ra[inRange] - self._raStart.asRadians()) % (2.*np.pi)
240 tractNum = (deltaWrap/(2.*np.pi/_ringNumArray[ringNums[inRange]]) + 0.5).astype(np.int32)
241 # Allow wraparound
242 tractNum[tractNum == _ringNumArray[ringNums[inRange]]] = 0
243
244 if self._version == 0:
245 # Account for off-by-one error in getRingIndices
246 # Note that this means tract 1 gets duplicated
247 offByOne, = np.where((tractNum == 0)
248 & (ringNums[inRange] != 0))
249 ringNums[inRange[offByOne]] += 1
250
251 indexes[inRange] = _ringCumulative[ringNums[inRange]] + tractNum + 1
252
253 return indexes
254

◆ findTractPatchList()

lsst.skymap.ringsSkyMap.RingsSkyMap.findTractPatchList ( self,
coordList )
Find tracts and patches that overlap a region.

Parameters
----------
coordList : `list` of `lsst.geom.SpherePoint`
    List of ICRS sky coordinates to search for.

Returns
-------
reList : `list` of (`TractInfo`, `list` of `PatchInfo`)
    For tracts and patches that contain, or may contain, the specified
    region. The list will be empty if there is no overlap.

Notes
-----
.. warning::

    This uses a naive algorithm that may find some tracts and patches
    that do not overlap the region (especially if the region is not a
    rectangle aligned along patch x, y).

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 306 of file ringsSkyMap.py.

306 def findTractPatchList(self, coordList):
307 retList = []
308 for coord in coordList:
309 for tractInfo in self.findAllTracts(coord):
310 patchList = tractInfo.findPatchList(coordList)
311 if patchList and not (tractInfo, patchList) in retList:
312 retList.append((tractInfo, patchList))
313 return retList
314

◆ generateTract()

lsst.skymap.ringsSkyMap.RingsSkyMap.generateTract ( self,
index )
Generate TractInfo for the specified tract index.

Reimplemented from lsst.skymap.cachingSkyMap.CachingSkyMap.

Definition at line 125 of file ringsSkyMap.py.

125 def generateTract(self, index):
126 """Generate TractInfo for the specified tract index."""
127 ringNum, tractNum = self.getRingIndices(index)
128 if ringNum == -1: # South polar cap
129 ra, dec = 0, -0.5*math.pi
130 elif ringNum == self.config.numRings: # North polar cap
131 ra, dec = 0, 0.5*math.pi
132 else:
133 dec = self._ringSize*(ringNum + 1) - 0.5*math.pi
134 ra = ((2*math.pi*tractNum/self._ringNums[ringNum])*geom.radians
135 + self._raStart).wrap().asRadians()
136
137 center = geom.SpherePoint(ra, dec, geom.radians)
138 wcs = self._wcsFactory.makeWcs(crPixPos=geom.Point2D(0, 0), crValCoord=center)
139 return ExplicitTractInfo(index, self._tractBuilder, center,
140 0.5*self._ringSize*geom.radians, self.config.tractOverlap*geom.degrees,
141 wcs)
142
Point in an unspecified spherical coordinate system.
Definition SpherePoint.h:57

◆ getRingIndices()

lsst.skymap.ringsSkyMap.RingsSkyMap.getRingIndices ( self,
index )
Calculate ring indices given a numerical index of a tract.

The ring indices are the ring number and the tract number within
the ring.

The ring number is -1 for the south polar cap and increases to the
north.  The north polar cap has ring number = numRings.  The tract
number is zero for either of the polar caps.

Definition at line 94 of file ringsSkyMap.py.

94 def getRingIndices(self, index):
95 """Calculate ring indices given a numerical index of a tract.
96
97 The ring indices are the ring number and the tract number within
98 the ring.
99
100 The ring number is -1 for the south polar cap and increases to the
101 north. The north polar cap has ring number = numRings. The tract
102 number is zero for either of the polar caps.
103 """
104 if index == 0: # South polar cap
105 return -1, 0
106 if index == self._numTracts - 1: # North polar cap
107 return self.config.numRings, 0
108 if index < 0 or index >= self._numTracts:
109 raise IndexError("Tract index %d is out of range [0, %d]" % (index, len(self) - 1))
110 ring = 0 # Ring number
111 tractNum = index - 1 # Tract number within ring
112 if self._version == 0:
113 # Maintain the off-by-one bug in version=0 (DM-14809).
114 # This means that the first tract in the first ring is duplicated
115 # and the first tract in the last ring is missing.
116 while ring < self.config.numRings and tractNum > self._ringNums[ring]:
117 tractNum -= self._ringNums[ring]
118 ring += 1
119 else:
120 while ring < self.config.numRings and tractNum >= self._ringNums[ring]:
121 tractNum -= self._ringNums[ring]
122 ring += 1
123 return ring, tractNum
124

◆ updateSha1()

lsst.skymap.ringsSkyMap.RingsSkyMap.updateSha1 ( self,
sha1 )
Add subclass-specific state or configuration options to the SHA1.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 315 of file ringsSkyMap.py.

315 def updateSha1(self, sha1):
316 """Add subclass-specific state or configuration options to the SHA1."""
317 sha1.update(struct.pack("<id", self.config.numRings, self.config.raStart))

Member Data Documentation

◆ _raStart

lsst.skymap.ringsSkyMap.RingsSkyMap._raStart
protected

Definition at line 92 of file ringsSkyMap.py.

◆ _ringNums

lsst.skymap.ringsSkyMap.RingsSkyMap._ringNums
protected

Definition at line 84 of file ringsSkyMap.py.

◆ _ringSize

lsst.skymap.ringsSkyMap.RingsSkyMap._ringSize
protected

Definition at line 83 of file ringsSkyMap.py.

◆ _tractBuilder

lsst.skymap.ringsSkyMap.RingsSkyMap._tractBuilder
protected

Definition at line 139 of file ringsSkyMap.py.

◆ _version [1/2]

tuple lsst.skymap.ringsSkyMap.RingsSkyMap._version = (1, 0)
staticprotected

Definition at line 76 of file ringsSkyMap.py.

◆ _version [2/2]

lsst.skymap.ringsSkyMap.RingsSkyMap._version
protected

Definition at line 112 of file ringsSkyMap.py.

◆ ConfigClass

lsst.skymap.ringsSkyMap.RingsSkyMap.ConfigClass = RingsSkyMapConfig
static

Definition at line 75 of file ringsSkyMap.py.


The documentation for this class was generated from the following file: