In [1]:
import os
import numpy as np
import pandas as pd

Note For this to work, you will need the lsst.sims stack to be installed.

  • opsimsummary uses healpy which is installed with the sims stack, but also available from pip/conda
  • snsims uses the lsst.sims stack.

In [2]:
import opsimsummary as oss
from opsimsummary import Tiling, HealpixTiles
# import snsims
import healpy as hp

In [3]:
%matplotlib inline
import matplotlib.pyplot as plt

This section pertains to how to write a new Tiling class

noTile = snsims.Tiling()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-9-5f6f8a94508e> in <module>()
----> 1 noTile = snsims.Tiling()

TypeError: Can't instantiate abstract class Tiling with abstract methods __init__, area, pointingSequenceForTile, tileIDSequence, tileIDsForSN

The class snsims.Tiling is an abstract Base class. Therefore, this cannot be instantiated. It must be subclassed, and the set of methods outlined have to be implemented for this to work.


In [4]:
class NoTile(Tiling):
    pass

In [5]:
noTile = NoTile()


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-8ddedac7fb97> in <module>()
----> 1 noTile = NoTile()

TypeError: Can't instantiate abstract class NoTile with abstract methods __init__, area, pointingSequenceForTile, positions, tileIDSequence, tileIDsForSN
"""noTile = NoTile()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-8ddedac7fb97> in <module>()
----> 1 noTile = NoTile()

TypeError: Can't instantiate abstract class NoTile with abstract methods __init__, area, pointingSequenceForTile, positions, tileIDSequence, tileIDsForSN
"""

The above fails because the methods are not implemented. Below is a stupid (ie. not useful) but minimalist class that would work:


In [6]:
class MyTile(Tiling):
    def __init__(self):
        pass
    @property
    def tileIDSequence(self):
        return np.arange(100)
    
    def tileIDsForSN(self, ra, dec):
        x = ra + dec
        y = np.remainder(x, 100.)
        return np.floor(y)
    def area(self, tileID):
        return 1.
    def pointingSequenceForTile(self, tileID, pointings):
        return None
    def positions(self):
        pass

In [7]:
myTile = MyTile()

Using the class HealpixTiles

Currently there is only concrete tiling class that has been implemented. This is the snsims.HealpixTiles class.

This shows how to use the HealpixTiles Class


In [8]:
issubclass(HealpixTiles, Tiling)


Out[8]:
True

In [9]:
help(HealpixTiles)


Help on class HealpixTiles in module opsimsummary.healpixTiles:

class HealpixTiles(opsimsummary.tessellations.Tiling)
 |  A concrete Tiling class based on Healpix Tiles. The user is
 |  allowed to choose the following parameters:
 |  
 |  Attributes
 |  ----------
 |  nside : int, power of 2, defaults to 256
 |      healpix nside parameter
 |  
 |  Method resolution order:
 |      HealpixTiles
 |      opsimsummary.tessellations.Tiling
 |      __builtin__.object
 |  
 |  Methods defined here:
 |  
 |  __init__(self, nside=256, healpixelizedOpSim=None, preComputedMap=None)
 |      nside : int, power of 2, defaults to 256
 |          nside parameter of healpix. determines the size of the tiles
 |          so that there are 12 * nside **2 equally sized tiles covering
 |          the sphere.
 |  
 |  area(self, tileID)
 |  
 |  pointingSequenceForTile(self, tileID, allPointings=None, columns=None, **kwargs)
 |      return a maximal sequence of pointings for a particular tileID.
 |  
 |  positions(self, tileID, numSamples, rng=None)
 |      Return a tuple of (res_phi, res_theta) where res_phi and res_theta are
 |      spatially uniform samples  of positions of size numSamples within the
 |      healpix Tile with ipix=tileID in the nested scheme. The return values
 |      should be in degrees, with the convention that theta is 0 on the equator and 
 |      90 degrees at the North Pole.
 |      
 |      Parameters
 |      ---------
 |      tileID : int, mandatory
 |      
 |      numSamples : number of positions required
 |      
 |      rng : instance of `np.random.RandomState`
 |      
 |      
 |      Returns
 |      -------
 |      
 |      .. notes : 1. The inelegant method is sampling a circle with a radius
 |          twice that required to have an area equal to the healpix tile. This
 |          operation can be done by self.samplePatchOnSphere and returns 
 |          numSamples, some of which are not on the healpixTiles.
 |          2. `self._angularSamples` returns only those of this sequence which
 |          lie on the original tile.
 |          3. by repeating the process till the number obtained matches the number
 |          requested, we obtain nsamples on the tile.
 |          4. The method works as long as the radius is large enough so that
 |          corners of the tile are not outside the circle sampled.
 |  
 |  tileIDsForSN(self, ra, dec)
 |      Parameters
 |      ----------
 |      ra : `numpyp.ndarray` or float, degrees, mandatory
 |      dec : `numpy.ndarray` or float, degrees, mandatory
 |  
 |  tilesForPointing(self, pointing, alltiles=None, **kwargs)
 |      return a maximal sequence of tile ID s for a particular OpSim pointing
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  preComputedEngine
 |  
 |  preComputedMap
 |  
 |  tileIDSequence
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __abstractmethods__ = frozenset([])
 |  
 |  ----------------------------------------------------------------------
 |  Static methods inherited from opsimsummary.tessellations.Tiling:
 |  
 |  samplePatchOnSphere(phi, theta, delta, size, rng, degrees=True)
 |      Uniformly distributes samples on a patch on a sphere between
 |      phi \pm delta, and theta \pm delta on a sphere. Uniform distribution
 |      implies that the number of points in a patch of sphere is proportional
 |      to the area of the patch. Here, the coordinate system is the usual
 |      spherical coordinate system with the azimuthal angle theta going from
 |      0 degrees at the North Pole, to 90 degrees at the South Pole, through
 |      0. at the equator.
 |      
 |      This function is not equipped to handle wrap-around the ranges of theta
 |      phi and therefore does not work at the poles.
 |      
 |      Parameters
 |      ----------
 |      phi: float, mandatory, degrees
 |          center of the spherical patch in ra with range 
 |      theta: float, mandatory, degrees
 |      delta: float, mandatory, degrees
 |      size: int, mandatory
 |          number of samples
 |      seed : int, optional, defaults to 1
 |          random Seed used for generating values
 |      degrees : bool, optional, defaults to True
 |          if True, returns angles in degrees, else in
 |          radians
 |      
 |      Returns
 |      -------
 |      tuple of (phivals, thetavals) where phivals and thetavals are arrays of 
 |          size size in degrees.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors inherited from opsimsummary.tessellations.Tiling:
 |  
 |  __dict__
 |      dictionary for instance variables (if defined)
 |  
 |  __weakref__
 |      list of weak references to the object (if defined)


In [10]:
datadir = os.path.join(oss.__path__[0], 'example_data')
opsimdb = os.path.join(datadir, 'enigma_1189_micro.db')

In [11]:
NSIDE = 4

In [12]:
hpOpSim = oss.HealPixelizedOpSim.fromOpSimDB(opsimdb, NSIDE=NSIDE)


 reading from database sqlite:////Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/example_data/enigma_1189_micro.db
SELECT * FROM Summary WHERE PROPID in (366, 364)

In [13]:
NSIDE


Out[13]:
4

In [14]:
hpTileshpOpSim = HealpixTiles(healpixelizedOpSim=hpOpSim, nside=NSIDE)

In [15]:
hpTileshpOpSim.pointingSequenceForTile(1, allPointings=None)


---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-15-0e6cfbda195a> in <module>()
----> 1 hpTileshpOpSim.pointingSequenceForTile(1, allPointings=None)

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpixTiles.pyc in pointingSequenceForTile(self, tileID, allPointings, columns, **kwargs)
    126             obsHistIDs = self._pointingFromPrecomputedDB(tileID, tableName='simlib')
    127         elif self.hpOpSim is not None:
--> 128             obsHistIDs = self._pointingFromHpOpSim(tileID)
    129         else:
    130             raise ValueError('both attributes preComputedMap and hpOpSim cannot'

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpixTiles.pyc in _pointingFromHpOpSim(self, tileID)
     94 
     95     def _pointingFromHpOpSim(self, tileID):
---> 96         return self.hpOpSim.obsHistIdsForTile(tileID)
     97 
     98 

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpix.pyc in obsHistIdsForTile(self, tileID)
    149         healpix tileID.
    150         """
--> 151         inds = self.sparseMat.getcol(tileID).nonzero()[0]
    152         return self.opsimdf.ix[inds, 'obsHistID'].values
    153 

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpix.pyc in sparseMat(self)
    161             shape=(len(self.opsimdf), hp.nside2npix(self.nside))
    162             # numpy ones like number of intersections
--> 163             ones_int = np.ones(len(self.rowdata))
    164             self._spmat = csr_matrix((ones_int, (self.rowdata, self.coldata)),
    165                                      shape=shape)

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpix.pyc in rowdata(self)
    169     def rowdata(self):
    170         if self._rowdata is None:
--> 171             self.doPreCalcs()
    172         return np.asarray(self._rowdata)
    173 

/Users/rbiswas/.local/lib/python2.7/site-packages/opsimsummary/healpix.pyc in doPreCalcs(self)
    227                                               factor=self.factor,
    228                                               nest=self.nest)
--> 229                                 for vec in self.opsimdf[self.vecColName]]
    230         lens = map(len, self.opsimdf.hids.values)
    231         rowdata = []

healpy/src/_query_disc.pyx in healpy._query_disc.query_disc (healpy/src/_query_disc.cpp:1622)()

TypeError: query_disc() got an unexpected keyword argument 'factor'

In [16]:
phi, theta = hpTileshpOpSim.positions(1, 10000)

In [17]:
mapvals = np.ones(hp.nside2npix(NSIDE)) * hp.UNSEEN

In [18]:
mapvals[1] = 100

In [ ]:


In [19]:
hp.ang2pix(NSIDE, np.radians(theta), np.radians(phi), nest=True)


Out[19]:
array([13, 13, 13, ..., 13, 15, 15])

In [20]:
theta_c, phi_c = hp.pix2ang(4, 1, nest=True)

In [21]:
hp.mollview(mapvals, nest=True)
hp.projscatter(np.radians(theta), np.radians(phi), **dict(s=0.0002))
hp.projscatter(theta_c, phi_c, **dict(s=8., c='r'))


Out[21]:
<matplotlib.collections.PathCollection at 0x109b11250>

In [30]:
%timeit hpTileshpOpSim.pointingSequenceForTile(33, allPointings=None)


100 loops, best of 3: 2.52 ms per loop

In [31]:
preCompMap = os.path.join(oss.__path__[0], 'example_data', 'healpixels_micro.db')

In [33]:
hpTilesMap = HealpixTiles(nside=1, preComputedMap=preCompMap)

In [34]:
hpTilesMap.pointingSequenceForTile(10, allPointings=None)


Out[34]:
array([171077, 171078, 171079, ..., 272594, 272626, 272656])

In [35]:
%timeit hpOpSim.obsHistIdsForTile(34)


100 loops, best of 3: 2.49 ms per loop

In [36]:
hpTiles = HealpixTiles(healpixelizedOpSim=hpOpSim)

In [37]:
hpTiles.pointingSequenceForTile(34, allPointings=None)


Out[37]:
array([], dtype=int64)

In [ ]:


In [ ]: