import numpy as np
from lsst.sims.maf.plots.spatialPlotters import BaseSkyMap, BaseHistogram
from .baseSpatialSlicer import BaseSpatialSlicer
__all__ = ['UserPointsSlicer']
[docs]class UserPointsSlicer(BaseSpatialSlicer):
"""A spatial slicer that evaluates pointings overlapping user-provided list of points.
Parameters
----------
ra : list or numpy.ndarray
User-selected RA points, in degrees. Stored internally in radians.
dec : list or numpy.ndarray
User-selected Dec points, in degrees. Stored internally in radians.
lonCol : str, optional
Name of the longitude (RA equivalent) column to use from the input data.
Default fieldRA
latCol : str, optional
Name of the latitude (Dec equivalent) column to use from the input data.
Default fieldDec
latLonDeg : bool, optional
Flag indicating whether the lon and lat values will be in degrees (True) or radians (False).
Default True (appropriate for opsim v4).
verbose : boolean, optional
Flag to indicate whether or not to write additional information to stdout during runtime.
Default True.
badval : float, optional
Bad value flag, relevant for plotting. Default -666.
leafsize : int, optional
Leafsize value for kdtree. Default 100.
radius : float, optional
Radius for matching in the kdtree. Equivalent to the radius of the FOV. Degrees.
Default 1.75.
useCamera : boolean, optional
Flag to indicate whether to use the LSST camera footprint or not.
Default False.
rotSkyPosColName : str, optional
Name of the rotSkyPos column in the input data. Only used if useCamera is True.
Describes the orientation of the camera orientation compared to the sky.
Default rotSkyPos.
mjdColName : str, optional
Name of the exposure time column. Only used if useCamera is True.
Default observationStartMJD.
chipNames : array-like, optional
List of chips to accept, if useCamera is True. This lets users turn 'on' only a subset of chips.
Default 'all' - this uses all chips in the camera.
"""
def __init__(self, ra, dec, lonCol='fieldRA', latCol='fieldDec', latLonDeg=True, verbose=True,
badval=-666, leafsize=100, radius=1.75,
useCamera=False, rotSkyPosColName='rotSkyPos', mjdColName='observationStartMJD',
chipNames='all'):
super(UserPointsSlicer, self).__init__(lonCol=lonCol, latCol=latCol, latLonDeg=latLonDeg,
verbose=verbose,
badval=badval, radius=radius, leafsize=leafsize,
useCamera=useCamera, rotSkyPosColName=rotSkyPosColName,
mjdColName=mjdColName, chipNames=chipNames)
# check that ra and dec are iterable, if not, they are probably naked numbers, wrap in list
if not hasattr(ra, '__iter__'):
ra = [ra]
if not hasattr(dec, '__iter__'):
dec = [dec]
if len(ra) != len(dec):
raise ValueError('RA and Dec must be the same length')
ra = np.radians(ra)
dec = np.radians(dec)
self.slicePoints['sid'] = np.arange(np.size(ra))
self.slicePoints['ra'] = np.array(ra)
self.slicePoints['dec'] = np.array(dec)
self.nslice = np.size(ra)
self.shape = self.nslice
self.spatialExtent = [0, self.nslice - 1]
self.slicer_init = {'ra': ra,
'dec': dec,
'lonCol': lonCol,
'latCol': latCol,
'radius': radius}
self.plotFuncs = [BaseSkyMap, BaseHistogram]
[docs] def __eq__(self, otherSlicer):
"""Evaluate if two slicers are equivalent."""
result = False
# check the slicePoints
for key in otherSlicer.slicePoints:
if key in self.slicePoints.keys():
if not np.all(otherSlicer.slicePoints[key] == self.slicePoints[key]):
return False
else:
return False
if isinstance(otherSlicer, UserPointsSlicer):
if otherSlicer.nslice == self.nslice:
if np.all(otherSlicer.slicePoints['ra'] == self.slicePoints['ra']) \
and np.all(otherSlicer.slicePoints['dec'] == self.slicePoints['dec']):
if (otherSlicer.lonCol == self.lonCol and otherSlicer.latCol == self.latCol):
if otherSlicer.radius == self.radius:
if otherSlicer.useCamera == self.useCamera:
if otherSlicer.chipsToUse == self.chipsToUse:
if otherSlicer.rotSkyPosColName == self.rotSkyPosColName:
if np.all(otherSlicer.shape == self.shape):
result = True
return result