LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
Public Member Functions | Public Attributes | Static Public 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

def __init__ (self, config, version=1)
 
def getRingIndices (self, index)
 
def generateTract (self, index)
 
def findTract (self, coord)
 
def findTractIdArray (self, ra, dec, degrees=False)
 
def findAllTracts (self, coord)
 
def findTractPatchList (self, coordList)
 
def updateSha1 (self, sha1)
 
def __reduce__ (self)
 
def __iter__ (self)
 
def __len__ (self)
 
def __getitem__ (self, index)
 
def findClosestTractPatchList (self, coordList)
 
def __hash__ (self)
 
def __eq__ (self, other)
 
def __ne__ (self, other)
 
def logSkyMapInfo (self, log)
 
def getSha1 (self)
 
def register (self, name, butler)
 

Public Attributes

 config
 

Static Public Attributes

 ConfigClass = RingsSkyMapConfig
 
string SKYMAP_RUN_COLLECTION_NAME = "skymaps"
 
string SKYMAP_DATASET_TYPE_NAME = "skyMap"
 

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__()

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

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 calculating the ring size
82  self._ringSize = math.pi / (config.numRings + 1) # Size of a ring in Declination (radians)
83  self._ringNums = [] # Number of tracts for each ring
84  for i in range(config.numRings):
85  startDec = self._ringSize*(i + 0.5) - 0.5*math.pi
86  stopDec = startDec + self._ringSize
87  dec = min(math.fabs(startDec), math.fabs(stopDec)) # Declination for determining division in RA
88  self._ringNums.append(int(2*math.pi*math.cos(dec)/self._ringSize) + 1)
89  numTracts = sum(self._ringNums) + 2
90  super(RingsSkyMap, self).__init__(numTracts, config, version)
91  self._raStart = self.config.raStart*geom.degrees
92 
int min
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Definition: functional.cc:33

Member Function Documentation

◆ __eq__()

def lsst.skymap.baseSkyMap.BaseSkyMap.__eq__ (   self,
  other 
)
inherited

Definition at line 252 of file baseSkyMap.py.

252  def __eq__(self, other):
253  try:
254  return self.getSha1() == other.getSha1()
255  except AttributeError:
256  return NotImplemented
257 

◆ __getitem__()

def lsst.skymap.cachingSkyMap.CachingSkyMap.__getitem__ (   self,
  index 
)
inherited
Get the TractInfo for a particular index.

The tract is returned from a cache, if available, otherwise generated
on the fly.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 80 of file cachingSkyMap.py.

80  def __getitem__(self, index):
81  """Get the TractInfo for a particular index.
82 
83  The tract is returned from a cache, if available, otherwise generated
84  on the fly.
85  """
86  if index < 0 or index > self._numTracts:
87  raise IndexError("Index out of range: %d vs %d" % (index, self._numTracts))
88  if self._tractCache[index] is not None:
89  return self._tractCache[index]
90  tract = self.generateTract(index)
91  self._tractCache[index] = tract
92  return tract
93 

◆ __hash__()

def lsst.skymap.baseSkyMap.BaseSkyMap.__hash__ (   self)
inherited

Definition at line 249 of file baseSkyMap.py.

249  def __hash__(self):
250  return hash(self.getSha1())
251 

◆ __iter__()

def lsst.skymap.cachingSkyMap.CachingSkyMap.__iter__ (   self)
inherited
Iterator over tracts.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 71 of file cachingSkyMap.py.

71  def __iter__(self):
72  """Iterator over tracts."""
73  for i in range(self._numTracts):
74  yield self[i]
75 

◆ __len__()

def lsst.skymap.cachingSkyMap.CachingSkyMap.__len__ (   self)
inherited
Length is number of tracts.

Reimplemented from lsst.skymap.baseSkyMap.BaseSkyMap.

Definition at line 76 of file cachingSkyMap.py.

76  def __len__(self):
77  """Length is number of tracts."""
78  return self._numTracts
79 

◆ __ne__()

def lsst.skymap.baseSkyMap.BaseSkyMap.__ne__ (   self,
  other 
)
inherited

Definition at line 258 of file baseSkyMap.py.

258  def __ne__(self, other):
259  return not (self == other)
260 

◆ __reduce__()

def lsst.skymap.cachingSkyMap.CachingSkyMap.__reduce__ (   self)
inherited
To support pickling.

Notes
-----
**Warning:** This method assumes that the constructor is be defined:
    __init__(self, config, version=defaultVersion)
The use of 'config' is effectively set by the registry mechanism.
If additional optional arguments are added, this method should be
overridden to correspond.

Definition at line 58 of file cachingSkyMap.py.

58  def __reduce__(self):
59  """To support pickling.
60 
61  Notes
62  -----
63  **Warning:** This method assumes that the constructor is be defined:
64  __init__(self, config, version=defaultVersion)
65  The use of 'config' is effectively set by the registry mechanism.
66  If additional optional arguments are added, this method should be
67  overridden to correspond.
68  """
69  return (self.__class__, (self.config, self._version))
70 

◆ findAllTracts()

def 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 252 of file ringsSkyMap.py.

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

◆ findClosestTractPatchList()

def lsst.skymap.baseSkyMap.BaseSkyMap.findClosestTractPatchList (   self,
  coordList 
)
inherited
Find closest tract and patches that overlap coordinates.

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

Returns
-------
retList : `list`
    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.

Definition at line 217 of file baseSkyMap.py.

217  def findClosestTractPatchList(self, coordList):
218  """Find closest tract and patches that overlap coordinates.
219 
220  Parameters
221  ----------
222  coordList : `lsst.geom.SpherePoint`
223  List of ICRS sky coordinates to search for.
224 
225  Returns
226  -------
227  retList : `list`
228  list of (TractInfo, list of PatchInfo) for tracts and patches
229  that contain, or may contain, the specified region.
230  The list will be empty if there is no overlap.
231  """
232  retList = []
233  for coord in coordList:
234  tractInfo = self.findTract(coord)
235  patchList = tractInfo.findPatchList(coordList)
236  if patchList and not (tractInfo, patchList) in retList:
237  retList.append((tractInfo, patchList))
238  return retList
239 

◆ findTract()

def 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 187 of file ringsSkyMap.py.

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

◆ findTractIdArray()

def 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 : `np.ndarray`
    Array of Right Ascension.  Units are radians unless
    degrees=True.
dec : `np.ndarray`
    Array of Declination.  Units are radians unless
    degrees=True.
degrees : `bool`, optional
    Input ra, dec arrays are degrees if True.

Returns
-------
tractId : `np.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 205 of file ringsSkyMap.py.

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

◆ findTractPatchList()

def 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 303 of file ringsSkyMap.py.

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

◆ generateTract()

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

Reimplemented from lsst.skymap.cachingSkyMap.CachingSkyMap.

Definition at line 124 of file ringsSkyMap.py.

124  def generateTract(self, index):
125  """Generate TractInfo for the specified tract index."""
126  ringNum, tractNum = self.getRingIndices(index)
127  if ringNum == -1: # South polar cap
128  ra, dec = 0, -0.5*math.pi
129  elif ringNum == self.config.numRings: # North polar cap
130  ra, dec = 0, 0.5*math.pi
131  else:
132  dec = self._ringSize*(ringNum + 1) - 0.5*math.pi
133  ra = ((2*math.pi*tractNum/self._ringNums[ringNum])*geom.radians
134  + self._raStart).wrap().asRadians()
135 
136  center = geom.SpherePoint(ra, dec, geom.radians)
137  wcs = self._wcsFactory.makeWcs(crPixPos=geom.Point2D(0, 0), crValCoord=center)
138  return ExplicitTractInfo(index, self.config.patchInnerDimensions, self.config.patchBorder, center,
139  0.5*self._ringSize*geom.radians, self.config.tractOverlap*geom.degrees,
140  wcs)
141 
Point in an unspecified spherical coordinate system.
Definition: SpherePoint.h:57
std::shared_ptr< afw::geom::SkyWcs > makeWcs(SipForwardTransform const &sipForward, SipReverseTransform const &sipReverse, geom::SpherePoint const &skyOrigin)
Create a new TAN SIP Wcs from a pair of SIP transforms and the sky origin.
def wrap(ctrl)
Definition: wrap.py:302

◆ getRingIndices()

def 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 93 of file ringsSkyMap.py.

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

◆ getSha1()

def lsst.skymap.baseSkyMap.BaseSkyMap.getSha1 (   self)
inherited
Return a SHA1 hash that uniquely identifies this SkyMap instance.

Returns
-------
sha1 : `bytes`
    A 20-byte hash that uniquely identifies this SkyMap instance.

Notes
-----
Subclasses should almost always override ``updateSha1`` instead of
this function to add subclass-specific state to the hash.

Definition at line 285 of file baseSkyMap.py.

285  def getSha1(self):
286  """Return a SHA1 hash that uniquely identifies this SkyMap instance.
287 
288  Returns
289  -------
290  sha1 : `bytes`
291  A 20-byte hash that uniquely identifies this SkyMap instance.
292 
293  Notes
294  -----
295  Subclasses should almost always override ``updateSha1`` instead of
296  this function to add subclass-specific state to the hash.
297  """
298  if self._sha1 is None:
299  sha1 = hashlib.sha1()
300  sha1.update(type(self).__name__.encode('utf-8'))
301  configPacked = struct.pack(
302  "<iiidd3sd",
303  self.config.patchInnerDimensions[0],
304  self.config.patchInnerDimensions[1],
305  self.config.patchBorder,
306  self.config.tractOverlap,
307  self.config.pixelScale,
308  self.config.projection.encode('ascii'),
309  self.config.rotation
310  )
311  sha1.update(configPacked)
312  self.updateSha1(sha1)
313  self._sha1 = sha1.digest()
314  return self._sha1
315 
table::Key< int > type
Definition: Detector.cc:163

◆ logSkyMapInfo()

def lsst.skymap.baseSkyMap.BaseSkyMap.logSkyMapInfo (   self,
  log 
)
inherited
Write information about a sky map to supplied log

Parameters
----------
log : `lsst.log.Log`
    Log object that information about skymap will be written

Definition at line 261 of file baseSkyMap.py.

261  def logSkyMapInfo(self, log):
262  """Write information about a sky map to supplied log
263 
264  Parameters
265  ----------
266  log : `lsst.log.Log`
267  Log object that information about skymap will be written
268  """
269  log.info("sky map has %s tracts" % (len(self),))
270  for tractInfo in self:
271  wcs = tractInfo.getWcs()
272  posBox = geom.Box2D(tractInfo.getBBox())
273  pixelPosList = (
274  posBox.getMin(),
275  geom.Point2D(posBox.getMaxX(), posBox.getMinY()),
276  posBox.getMax(),
277  geom.Point2D(posBox.getMinX(), posBox.getMaxY()),
278  )
279  skyPosList = [wcs.pixelToSky(pos).getPosition(geom.degrees) for pos in pixelPosList]
280  posStrList = ["(%0.3f, %0.3f)" % tuple(skyPos) for skyPos in skyPosList]
281  log.info("tract %s has corners %s (RA, Dec deg) and %s x %s patches" %
282  (tractInfo.getId(), ", ".join(posStrList),
283  tractInfo.getNumPatches()[0], tractInfo.getNumPatches()[1]))
284 
A floating-point coordinate rectangle geometry.
Definition: Box.h:413

◆ register()

def lsst.skymap.baseSkyMap.BaseSkyMap.register (   self,
  name,
  butler 
)
inherited
Add skymap, tract, and patch Dimension entries to the given Gen3
Butler.

Parameters
----------
name : `str`
    The name of the skymap.
butler : `lsst.daf.butler.Butler`
    The butler to add to.

Raises
------
lsst.daf.butler.registry.ConflictingDefinitionError
    Raised if a different skymap exists with the same name.

Notes
-----
Registering the same skymap multiple times (with the exact same
definition) is safe, but inefficient; most of the work of computing
the rows to be inserted must be done first in order to check for
consistency between the new skymap and any existing one.

Re-registering a skymap with different tract and/or patch definitions
but the same summary information may not be detected as a conflict but
will never result in updating the skymap; there is intentionally no
way to modify a registered skymap (aside from manual administrative
operations on the database), as it is hard to guarantee that this can
be done without affecting reproducibility.

Definition at line 337 of file baseSkyMap.py.

337  def register(self, name, butler):
338  """Add skymap, tract, and patch Dimension entries to the given Gen3
339  Butler.
340 
341  Parameters
342  ----------
343  name : `str`
344  The name of the skymap.
345  butler : `lsst.daf.butler.Butler`
346  The butler to add to.
347 
348  Raises
349  ------
350  lsst.daf.butler.registry.ConflictingDefinitionError
351  Raised if a different skymap exists with the same name.
352 
353  Notes
354  -----
355  Registering the same skymap multiple times (with the exact same
356  definition) is safe, but inefficient; most of the work of computing
357  the rows to be inserted must be done first in order to check for
358  consistency between the new skymap and any existing one.
359 
360  Re-registering a skymap with different tract and/or patch definitions
361  but the same summary information may not be detected as a conflict but
362  will never result in updating the skymap; there is intentionally no
363  way to modify a registered skymap (aside from manual administrative
364  operations on the database), as it is hard to guarantee that this can
365  be done without affecting reproducibility.
366  """
367  nxMax = 0
368  nyMax = 0
369  tractRecords = []
370  patchRecords = []
371  for tractInfo in self:
372  nx, ny = tractInfo.getNumPatches()
373  nxMax = max(nxMax, nx)
374  nyMax = max(nyMax, ny)
375  region = tractInfo.getOuterSkyPolygon()
376  centroid = SpherePoint(region.getCentroid())
377  tractRecords.append({
378  "skymap": name,
379  "tract": tractInfo.getId(),
380  "region": region,
381  "ra": centroid.getRa().asDegrees(),
382  "dec": centroid.getDec().asDegrees(),
383  })
384  for patchInfo in tractInfo:
385  cellX, cellY = patchInfo.getIndex()
386  patchRecords.append({
387  "skymap": name,
388  "tract": tractInfo.getId(),
389  "patch": tractInfo.getSequentialPatchIndex(patchInfo),
390  "cell_x": cellX,
391  "cell_y": cellY,
392  "region": patchInfo.getOuterSkyPolygon(tractInfo.getWcs()),
393  })
394  skyMapRecord = {
395  "skymap": name,
396  "hash": self.getSha1(),
397  "tract_max": len(self),
398  "patch_nx_max": nxMax,
399  "patch_ny_max": nyMax,
400  }
401  butler.registry.registerRun(self.SKYMAP_RUN_COLLECTION_NAME)
402  # Kind of crazy that we've got three different capitalizations of
403  # "skymap" here, but that's what the various conventions (or at least
404  # precedents) dictate.
405  from lsst.daf.butler import DatasetType
406  from lsst.daf.butler.registry import ConflictingDefinitionError
407  datasetType = DatasetType(
408  name=self.SKYMAP_DATASET_TYPE_NAME,
409  dimensions=["skymap"],
410  storageClass="SkyMap",
411  universe=butler.registry.dimensions
412  )
413  butler.registry.registerDatasetType(datasetType)
414  with butler.transaction():
415  try:
416  inserted = butler.registry.syncDimensionData("skymap", skyMapRecord)
417  except ConflictingDefinitionError as err:
418  raise ConflictingDefinitionError(
419  f"SkyMap with hash {self.getSha1().hex()} is already registered with a different name."
420  ) from err
421  if inserted:
422  butler.registry.insertDimensionData("tract", *tractRecords)
423  butler.registry.insertDimensionData("patch", *patchRecords)
424  butler.put(self, datasetType, {"skymap": name}, run=self.SKYMAP_RUN_COLLECTION_NAME)
int max
lsst::geom::SpherePoint SpherePoint
Definition: misc.h:34

◆ updateSha1()

def 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 312 of file ringsSkyMap.py.

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

Member Data Documentation

◆ config

lsst.skymap.baseSkyMap.BaseSkyMap.config
inherited

Definition at line 108 of file baseSkyMap.py.

◆ ConfigClass

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

Definition at line 75 of file ringsSkyMap.py.

◆ SKYMAP_DATASET_TYPE_NAME

string lsst.skymap.baseSkyMap.BaseSkyMap.SKYMAP_DATASET_TYPE_NAME = "skyMap"
staticinherited

Definition at line 335 of file baseSkyMap.py.

◆ SKYMAP_RUN_COLLECTION_NAME

string lsst.skymap.baseSkyMap.BaseSkyMap.SKYMAP_RUN_COLLECTION_NAME = "skymaps"
staticinherited

Definition at line 333 of file baseSkyMap.py.


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