Skip to content

Commit 37c7a1a

Browse files
committed
Merge branch 'master' into twilight
2 parents 5e72b92 + dd62ce4 commit 37c7a1a

File tree

6 files changed

+83
-31
lines changed

6 files changed

+83
-31
lines changed

LICENSE.rst

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ are permitted provided that the following conditions are met:
99
* Redistributions in binary form must reproduce the above copyright notice, this
1010
list of conditions and the following disclaimer in the documentation and/or
1111
other materials provided with the distribution.
12-
* Neither the name of the Astropy Team nor the names of its contributors may be
13-
used to endorse or promote products derived from
12+
* Neither the name of the DESI Collaboration nor the names of its contributors
13+
may be used to endorse or promote products derived from
1414
this software without specific prior written permission.
1515

1616
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND

doc/changes.rst

+12-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,19 @@
22
desisurvey change log
33
=====================
44

5-
0.9.4 (unreleased)
6-
------------------
5+
0.10.1 (unreleased)
6+
-------------------
7+
8+
* Set the ``EXTNAME`` keyword on the Table returned by ``Progress.get_exposures()``.
9+
10+
0.10.0 (2017-11-09)
11+
-------------------
12+
13+
* Progress.get_exposures() updates:
714

8-
* No changes yet.
15+
* includes FLAVOR and PROGRAM columns.
16+
* uses desimodel.footprint.pass2program if available.
17+
* standardized on UPPERCASE column names and NIGHT=YEARMMDD not YEAR-MM-DD.
918

1019
0.9.3 (2017-10-09)
1120
------------------

py/desisurvey/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '0.9.3.dev614'
1+
__version__ = '0.10.0.dev632'

py/desisurvey/progress.py

+38-14
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,9 @@ def add_exposure(self, tile_id, start, exptime, snr2frac, airmass, seeing,
484484

485485
def get_exposures(self, start=None, stop=None,
486486
tile_fields='tileid,pass,ra,dec,ebmv',
487-
exp_fields='night,mjd,exptime,seeing,transparency,'
488-
+'airmass,moonfrac,moonalt,moonsep'):
487+
exp_fields=('night,mjd,exptime,seeing,transparency,' +
488+
'airmass,moonfrac,moonalt,moonsep,' +
489+
'program,flavor')):
489490
"""Create a table listing exposures in time order.
490491
491492
Parameters
@@ -505,7 +506,7 @@ def get_exposures(self, start=None, stop=None,
505506
Comma-separated list of per-exposure field names to include. The
506507
special name 'snr2cum' denotes the cummulative snr2frac on each
507508
tile, since the start of the survey. The special name 'night'
508-
denotes a string YYYY-MM-DD specifying the date on which each
509+
denotes a string YYYYMMDD specifying the date on which each
509510
night starts. The special name 'lst' denotes the apparent local
510511
sidereal time of the shutter open timestamp. The special name
511512
'expid' denotes the index of each exposure in the full progress
@@ -514,7 +515,7 @@ def get_exposures(self, start=None, stop=None,
514515
Returns
515516
-------
516517
astropy.table.Table
517-
Table with the specified columns and one row per exposure.
518+
Table with the specified columns as uppercase and one row per exposure.
518519
"""
519520
# Get MJD range to show.
520521
if start is None:
@@ -549,52 +550,75 @@ def get_exposures(self, start=None, stop=None,
549550
# Create the output table.
550551
tileinfo = None
551552
output = astropy.table.Table()
553+
output.meta['EXTNAME'] = 'EXPOSURES'
552554
for name in tile_fields.split(','):
555+
name = name.lower()
553556
if name == 'index':
554-
output[name] = tile_index
557+
output[name.upper()] = tile_index
555558
elif name == 'ebmv':
556559
if tileinfo is None:
557560
config = desisurvey.config.Configuration()
558561
tileinfo = astropy.table.Table(
559562
desimodel.io.load_tiles(onlydesi=True, extra=False,
560563
tilesfile=config.tiles_file()))
561564
assert np.all(tileinfo['TILEID'] == table['tileid'])
562-
output[name] = tileinfo['EBV_MED'][tile_index]
565+
output[name.upper()] = tileinfo['EBV_MED'][tile_index]
563566
else:
564567
if name not in table.colnames or len(table[name].shape) != 1:
565568
raise ValueError(
566569
'Invalid tile field name: {0}.'.format(name))
567-
output[name] = table[name][tile_index]
570+
output[name.upper()] = table[name][tile_index]
568571
for name in exp_fields.split(','):
572+
name = name.lower()
569573
if name == 'snr2cum':
570574
snr2cum = np.cumsum(
571575
table['snr2frac'], axis=1).flatten()[order]
572-
output[name] = astropy.table.Column(
576+
output[name.upper()] = astropy.table.Column(
573577
snr2cum, format='%.3f',
574578
description='Cummulative fraction of target S/N**2')
575579
elif name == 'night':
576580
mjd = table['mjd'].flatten()[order]
577-
night = np.empty(len(mjd), dtype='S10')
581+
night = np.empty(len(mjd), dtype=(str, 8))
578582
for i in range(len(mjd)):
579-
night[i] = str(desisurvey.utils.get_date(mjd[i]))
580-
output[name] = astropy.table.Column(
583+
night[i] = str(desisurvey.utils.get_date(mjd[i])).replace('-', '')
584+
output[name.upper()] = astropy.table.Column(
581585
night,
582586
description='Date at start of night when exposure taken')
583587
elif name == 'lst':
584588
mjd = table['mjd'].flatten()[order]
585589
times = astropy.time.Time(
586590
mjd, format='mjd', location=desisurvey.utils.get_location())
587591
lst = times.sidereal_time('apparent').to(u.deg).value
588-
output[name] = astropy.table.Column(
592+
output[name.upper()] = astropy.table.Column(
589593
lst, format='%.1f', unit='deg',
590594
description='Apparent local sidereal time in degrees')
595+
elif name == 'program':
596+
exppass = table['pass'][tile_index]
597+
try:
598+
from desimodel.footprint import pass2program
599+
program = pass2program(exppass)
600+
except ImportError:
601+
#- desimodel < 0.9.1 doesn't have pass2program, so
602+
#- hardcode the mapping that it did have
603+
program = np.empty(len(exppass), dtype=(str, 6))
604+
program[:] = 'BRIGHT'
605+
program[exppass < 4] = 'DARK'
606+
program[exppass == 4] = 'GRAY'
607+
608+
output[name.upper()] = astropy.table.Column(program,
609+
description='Program name')
610+
elif name == 'flavor':
611+
flavor = np.empty(len(exppass), dtype=(str, 7))
612+
flavor[:] = 'science'
613+
output[name.upper()] = astropy.table.Column(flavor,
614+
description='Exposure flavor')
591615
elif name == 'expid':
592-
output[name] = astropy.table.Column(
616+
output[name.upper()] = astropy.table.Column(
593617
expid[order], description='Exposure index')
594618
else:
595619
if name not in table.colnames or len(table[name].shape) != 2:
596620
raise ValueError(
597621
'Invalid exposure field name: {0}.'.format(name))
598-
output[name] = table[name].flatten()[order]
622+
output[name.upper()] = table[name].flatten()[order]
599623

600624
return output

py/desisurvey/test/test_progress.py

+23-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77

88
import astropy.units as u
9+
from astropy.table import Table
910

1011
import desisurvey.config
1112

@@ -97,24 +98,36 @@ def test_get_exposures(self):
9798
p.add_exposure(
9899
tile_id, t0 + i * u.hour, 1e3 * u.s, 0.5, 1.5, 1.1, 1, 0, 0, 0)
99100
explist = p.get_exposures()
100-
self.assertTrue(np.all(np.diff(explist['mjd']) > 0))
101+
self.assertEqual(explist.meta['EXTNAME'], 'EXPOSURES')
102+
self.assertTrue(np.all(np.diff(explist['MJD']) > 0))
101103
explist = p.get_exposures(tile_fields='index', exp_fields='lst')
102-
self.assertTrue(np.all(np.diff(explist['lst']) > 0))
103-
self.assertTrue(np.min(explist['lst'] >= 0))
104-
self.assertTrue(np.max(explist['lst'] < 360))
104+
self.assertTrue(np.all(np.diff(explist['LST']) > 0))
105+
self.assertTrue(np.min(explist['LST'] >= 0))
106+
self.assertTrue(np.max(explist['LST'] < 360))
105107
with self.assertRaises(ValueError):
106108
p.get_exposures(tile_fields='mjd')
107109
with self.assertRaises(ValueError):
108110
p.get_exposures(tile_fields='nonexistent')
109-
with self.assertRaises(ValueError):
110-
p.get_exposures(exp_fields='pass')
111-
explist = p.get_exposures(exp_fields='mjd,night')
111+
# with self.assertRaises(ValueError):
112+
# p.get_exposures(exp_fields='pass')
113+
explist = p.get_exposures(exp_fields='mjd,night,program')
112114
for row in explist:
113-
self.assertEqual(desisurvey.utils.get_date(row['mjd']),
114-
desisurvey.utils.get_date(row['night']))
115-
night = str(desisurvey.utils.get_date(row['mjd']))
115+
self.assertEqual(desisurvey.utils.get_date(row['MJD']),
116+
desisurvey.utils.get_date(row['NIGHT']))
117+
night = str(desisurvey.utils.get_date(row['MJD']))
116118
self.assertEqual(night, str(desisurvey.utils.get_date(night)))
117119

120+
#- Test roundtrip to disk
121+
expfile = os.path.join(self.tmpdir, 'test-exposures.fits')
122+
explist.write(expfile)
123+
newexp = Table.read(expfile)
124+
125+
self.assertEqual(newexp.meta['EXTNAME'], 'EXPOSURES')
126+
self.assertEqual(explist['PROGRAM'].dtype, newexp['PROGRAM'].dtype)
127+
self.assertEqual(explist['NIGHT'].dtype, newexp['NIGHT'].dtype)
128+
self.assertTrue(np.all(explist['PROGRAM'] == newexp['PROGRAM']))
129+
self.assertTrue(np.all(explist['NIGHT'] == newexp['NIGHT']))
130+
118131
def test_exposures_incrementing(self):
119132
"""Successive exposures of the same tile must be time ordered"""
120133
p = Progress()

py/desisurvey/utils.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,13 @@ def get_date(date):
508508
# Convert a string of the form YYYY-MM-DD into a date.
509509
# This will raise a ValueError for a badly formatted string
510510
# or invalid date such as 2019-13-01.
511-
date = datetime.datetime.strptime(date, '%Y-%m-%d').date()
511+
try:
512+
date = datetime.datetime.strptime(date, '%Y-%m-%d').date()
513+
except ValueError:
514+
try:
515+
date = datetime.datetime.strptime(date, '%Y%m%d').date()
516+
except ValueError:
517+
raise
512518
except TypeError:
513519
pass
514520
# valid types: number, Time, datetime, date

0 commit comments

Comments
 (0)