diff --git a/docs/pydl/changes.rst b/docs/pydl/changes.rst index b8712b8d..300d6d59 100644 --- a/docs/pydl/changes.rst +++ b/docs/pydl/changes.rst @@ -5,9 +5,12 @@ PyDL Changelog 0.6.1 (unreleased) ------------------ +* Support the ``firstField`` bit in ObjIDs from DR7 and earlier (Issue `#37`_). * Change tests of Astropy development version from Python 2 to Python 3. * Update to `astropy_helpers`_/v2.0.2. +.. _`#37`: https://github.com/weaverba137/pydl/issues/37. + 0.6.0 (2017-09-19) ------------------ diff --git a/pydl/__init__.py b/pydl/__init__.py index 44126778..c806d1df 100644 --- a/pydl/__init__.py +++ b/pydl/__init__.py @@ -29,6 +29,14 @@ from .uniq import uniq +# Workaround: Numpy 1.14.x changes the way arrays are printed. +try: + from numpy import set_printoptions + set_printoptions(legacy='1.13') +except Exception: + pass + + class PydlException(Exception): """Base class for exceptions raised in PyDL functions. """ diff --git a/pydl/photoop/photoobj.py b/pydl/photoop/photoobj.py index 18a3c2b0..30da54d0 100644 --- a/pydl/photoop/photoobj.py +++ b/pydl/photoop/photoobj.py @@ -40,8 +40,8 @@ def unwrap_objid(objid): Returns ------- :class:`numpy.recarray` - A record array with the same length as objid, with the columns - 'run', 'camcol', 'frame', 'id', 'rerun', 'skyversion'. + A record array with the same length as `objid`, with the columns + 'skyversion', 'rerun', 'run', 'camcol', 'firstfield', 'frame', 'id'. Notes ----- @@ -57,8 +57,8 @@ def unwrap_objid(objid): >>> from numpy import array >>> from pydl.photoop.photoobj import unwrap_objid >>> unwrap_objid(array([1237661382772195474])) - rec.array([(2, 301, 3704, 3, 91, 146)], - dtype=[('skyversion', '> 59, 2**4 - 1) unwrap.rerun = np.bitwise_and(tempobjid >> 48, 2**11 - 1) unwrap.run = np.bitwise_and(tempobjid >> 32, 2**16 - 1) unwrap.camcol = np.bitwise_and(tempobjid >> 29, 2**3 - 1) - # unwrap.firstfield = np.bitwise_and(tempobjid >> 28, 2**1 - 1) + unwrap.firstfield = np.bitwise_and(tempobjid >> 28, 2**1 - 1) unwrap.frame = np.bitwise_and(tempobjid >> 16, 2**12 - 1) unwrap.id = np.bitwise_and(tempobjid, 2**16 - 1) return unwrap diff --git a/pydl/photoop/tests/test_photoop.py b/pydl/photoop/tests/test_photoop.py index 74771802..1e9899d0 100644 --- a/pydl/photoop/tests/test_photoop.py +++ b/pydl/photoop/tests/test_photoop.py @@ -24,6 +24,7 @@ def test_unwrap_objid(self): assert objid.rerun == 301 assert objid.run == 3704 assert objid.camcol == 3 + assert objid.firstfield == 0 assert objid.frame == 91 assert objid.id == 146 objid = unwrap_objid(np.array(['1237661382772195474'])) @@ -31,7 +32,16 @@ def test_unwrap_objid(self): assert objid.rerun == 301 assert objid.run == 3704 assert objid.camcol == 3 + assert objid.firstfield == 0 assert objid.frame == 91 assert objid.id == 146 + objid = unwrap_objid(np.array([587722984180548043])) + assert objid.skyversion == 1 + assert objid.rerun == 40 + assert objid.run == 752 + assert objid.camcol == 5 + assert objid.firstfield == 1 + assert objid.frame == 618 + assert objid.id == 459 with raises(ValueError): objid = unwrap_objid(np.array([3.14159])) diff --git a/pydl/pydlutils/cooling.py b/pydl/pydlutils/cooling.py index 87fe5095..b1e37225 100644 --- a/pydl/pydlutils/cooling.py +++ b/pydl/pydlutils/cooling.py @@ -35,9 +35,9 @@ def read_ds_cooling(fname, logT=None): -------- >>> from pydl.pydlutils.cooling import read_ds_cooling >>> logT, loglambda = read_ds_cooling('m-15.cie') - >>> logT[0:5] + >>> logT[0:5] # doctest: +NORMALIZE_WHITESPACE array([ 4. , 4.05, 4.1 , 4.15, 4.2 ]) - >>> loglambda[0:5] + >>> loglambda[0:5] # doctest: +NORMALIZE_WHITESPACE array([-26. , -24.66, -23.52, -22.62, -22.11]) """ from astropy.utils.data import get_pkg_data_contents diff --git a/pydl/pydlutils/sdss.py b/pydl/pydlutils/sdss.py index d5cdb78c..7a9fb292 100644 --- a/pydl/pydlutils/sdss.py +++ b/pydl/pydlutils/sdss.py @@ -287,10 +287,11 @@ def sdss_flagval(flagname, bitname): return flagvalue -def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): +def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None, + firstfield=None): """Convert SDSS photometric identifiers into CAS-style ObjID. - Bits are assigned in objid thus: + Bits are assigned in ObjID thus: ===== ========== =============================================== Bits Name Comment @@ -300,7 +301,7 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): 48-58 rerun number of pipeline rerun 32-47 run run number 29-31 camcol camera column (1-6) - 28 firstField [is this the first field in segment?] 0 for now + 28 firstField is this the first field in segment? Usually 0. 16-27 field field number within run 0-15 object object number within field ===== ========== =============================================== @@ -310,8 +311,9 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): run, camcol, field, objnum : :class:`int` or array of int Run, camcol, field and object number within field. If arrays are passed, all must have the same length. - rerun, skyversion : :class:`int` or array of int, optional - Rerun and skyversion usually don't change very much. If supplied, + rerun, skyversion, firstfield : :class:`int` or array of int, optional + `rerun`, `skyversion` and `firstfield` usually don't change at all, + especially for ObjIDs in DR8 and later. If supplied, make sure the size matches all the other values. Returns @@ -327,7 +329,7 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): Notes ----- - * ``firstField`` flag never set. + * The ``firstField`` flag is never set in ObjIDs from DR8 and later. * On 32-bit systems, makes sure to explicitly declare all inputs as 64-bit integers. @@ -339,6 +341,8 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): """ if skyversion is None: skyversion = default_skyversion() + if firstfield is None: + firstfield = 0 if isinstance(run, int): run = np.array([run], dtype=np.int64) if isinstance(camcol, int): @@ -357,11 +361,15 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): skyversion = np.zeros(run.shape, dtype=np.int64) + default_skyversion() else: skyversion = np.array([skyversion], dtype=np.int64) + if isinstance(firstfield, int): + if firstfield == 0: + firstfield = np.zeros(run.shape, dtype=np.int64) + else: + firstfield = np.array([firstfield], dtype=np.int64) # # Check that all inputs have the same shape. # - firstfield = np.zeros(run.shape, dtype=np.int64) if run.shape != camcol.shape: raise ValueError("camcol.shape does not match run.shape!") if run.shape != field.shape: @@ -372,9 +380,13 @@ def sdss_objid(run, camcol, field, objnum, rerun=301, skyversion=None): raise ValueError("rerun.shape does not match run.shape!") if run.shape != skyversion.shape: raise ValueError("skyversion.shape does not match run.shape!") + if run.shape != firstfield.shape: + raise ValueError("firstfield.shape does not match run.shape!") # # Check ranges of parameters # + if ((firstfield < 0) | (firstfield > 1)).any(): + raise ValueError("firstfield values are out-of-bounds!") if ((skyversion < 0) | (skyversion >= 16)).any(): raise ValueError("skyversion values are out-of-bounds!") if ((rerun < 0) | (rerun >= 2**11)).any(): diff --git a/pydl/pydlutils/tests/test_sdss.py b/pydl/pydlutils/tests/test_sdss.py index dfad1082..3628bccd 100644 --- a/pydl/pydlutils/tests/test_sdss.py +++ b/pydl/pydlutils/tests/test_sdss.py @@ -131,6 +131,8 @@ def test_sdss_objid(self): assert (np.array([1237661382772195474, 1237649770790322299], dtype=np.int64) == sdss_objid(run, camcol, field, obj)).all() + assert (sdss_objid(752, 5, 618, 459, rerun=40, + skyversion=1, firstfield=1) == 587722984180548043) # # Exceptions # @@ -146,10 +148,16 @@ def test_sdss_objid(self): objid = sdss_objid(3704, 3, 91, 146, rerun=np.array([137, 301])) with raises(ValueError): objid = sdss_objid(3704, 3, 91, 146, skyversion=np.array([2, 3])) + with raises(ValueError): + objid = sdss_objid(3704, 3, 91, 146, firstfield=np.array([0, 1])) with raises(ValueError): objid = sdss_objid(3704, 3, 91, 146, skyversion=-2) with raises(ValueError): objid = sdss_objid(3704, 3, 91, 146, skyversion=16) + with raises(ValueError): + objid = sdss_objid(3704, 3, 91, 146, firstfield=-2) + with raises(ValueError): + objid = sdss_objid(3704, 3, 91, 146, firstfield=2) with raises(ValueError): objid = sdss_objid(3704, 3, 91, 146, rerun=-2) with raises(ValueError): @@ -190,6 +198,21 @@ def test_sdss_specobjid(self): # # Exceptions # + with raises(ValueError): + s = sdss_specobjid(np.array([4055, 4056]), 408, 55359, 'v5_7_0') + with raises(ValueError): + s = sdss_specobjid(4055, np.array([408, 409]), 55359, 'v5_7_0') + with raises(ValueError): + s = sdss_specobjid(4055, 408, np.array([55359, 55360]), 'v5_7_0') + with raises(ValueError): + s = sdss_specobjid(4055, 408, 55359, + np.array(['v5_7_0', 'v5_7_2'])) + with raises(ValueError): + s = sdss_specobjid(4055, 408, 55359, 'v5_7_0', + line=np.array([137, 138])) + with raises(ValueError): + s = sdss_specobjid(4055, 408, 55359, 'v5_7_0', + index=np.array([137, 138])) with raises(ValueError): s = sdss_specobjid(4055, 408, 55359, 'v5_7_0', line=137, index=137) diff --git a/pydl/rebin.py b/pydl/rebin.py index 67c7e7c9..f356bc1c 100644 --- a/pydl/rebin.py +++ b/pydl/rebin.py @@ -44,9 +44,9 @@ def rebin(x, d, sample=False): -------- >>> from numpy import arange, float >>> from pydl import rebin - >>> rebin(arange(10, dtype=float), (5,)) + >>> rebin(arange(10, dtype=float), (5,)) # doctest: +NORMALIZE_WHITESPACE array([ 0.5, 2.5, 4.5, 6.5, 8.5]) - >>> rebin(arange(5, dtype=float), (10,)) + >>> rebin(arange(5, dtype=float), (10,)) # doctest: +NORMALIZE_WHITESPACE array([ 0. , 0.5, 1. , 1.5, 2. , 2.5, 3. , 3.5, 4. , 4. ]) """ from numpy import floor, zeros