Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize for MWS-specific tiles in minisv3 #601

Merged
merged 17 commits into from Apr 21, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 9 additions & 3 deletions doc/changes.rst
Expand Up @@ -5,9 +5,15 @@ desitarget Change Log
0.37.1 (unreleased)
-------------------

* Fixes a typo in the priority of MWS_WD_SV targets [`PR #600`_].

.. _`PR #600`: https://github.com/desihub/desitarget/pull/600
* Fixes a typo in the priority of MWS_WD_SV targets [`PR #601`_].
* Fixes calc_priority logic for MWS CMX targets [`PR #601`_].
* Separates special case in calc_priority for CMX into a separate function [`PR #601`_].
* Alter cmx targetmask such taht obsconditionsc can be used to work around MWS/BGS
conflicts on MWS CMX tiles [`PR #601`_].
* Updates test_priorities to deal with new scheme for MWS CMX targets [`PR #601`_].
* Adds SV0_MWS_FAINT bit [`PR #601`_].

.. _`PR #601`: https://github.com/desihub/desitarget/pull/601

0.37.0 (2020-03-12)
-------------------
Expand Down
18 changes: 15 additions & 3 deletions py/desitarget/cmx/cmx_cuts.py
Expand Up @@ -378,6 +378,9 @@ def isSV0_MWS(rflux=None, obs_rflux=None, objtype=None, paramssolved=None,
:class:`array_like`
``True`` if and only if the object is an early-SV/main survey
MWS_WD target.
:class:`array_like`
``True`` if and only if the object is an early-SV/main survey
SV0_MWS_FAINT target.

Notes
-----
Expand All @@ -394,6 +397,7 @@ def isSV0_MWS(rflux=None, obs_rflux=None, objtype=None, paramssolved=None,
if primary is None:
primary = np.ones_like(rflux, dtype='?')
ismws = primary.copy()
ismws_faint = primary.copy()
isnear = primary.copy()
iswd = primary.copy()

Expand All @@ -402,6 +406,13 @@ def isSV0_MWS(rflux=None, obs_rflux=None, objtype=None, paramssolved=None,
ismws &= gaia
# ADM main targets are point-like.
ismws &= _psflike(objtype)

# APC faint MWS filler for minsv3+ tiles
# APC no constraint on obs_rflux
ismws_faint &= ismws
ismws_faint &= rflux > 10**((22.5-21.0)/2.5)
ismws_faint &= rflux <= 10**((22.5-19.0)/2.5)

# ADM main targets are 16 <= r < 19.
ismws &= rflux > 10**((22.5-19.0)/2.5)
ismws &= rflux <= 10**((22.5-16.0)/2.5)
Expand Down Expand Up @@ -483,7 +494,7 @@ def isSV0_MWS(rflux=None, obs_rflux=None, objtype=None, paramssolved=None,
((gaiaaen < 1.) & (parallaxovererror > 4.) & (pm > 10.)))

# ADM return any object that passes the MWS cuts.
return ismws | isnear, iswd
return ismws | isnear, iswd, ismws_faint


def isSV0_LRG(gflux=None, rflux=None, zflux=None, w1flux=None,
Expand Down Expand Up @@ -2095,8 +2106,8 @@ def apply_cuts(objects, cmxdir=None, noqso=False):
objtype=objtype, primary=primary
)

# ADM determine if an object is SV0_MWS or WD.
sv0_mws, sv0_wd = isSV0_MWS(
# ADM determine if an object is SV0_MWS, WD or SV0_MWS_FAINT.
sv0_mws, sv0_wd, sv0_mws_faint = isSV0_MWS(
rflux=rflux, obs_rflux=obs_rflux, objtype=objtype,
gaiagmag=gaiagmag, gaiabmag=gaiabmag, gaiarmag=gaiarmag,
pmra=pmra, pmdec=pmdec, parallax=parallax,
Expand Down Expand Up @@ -2263,6 +2274,7 @@ def apply_cuts(objects, cmxdir=None, noqso=False):
cmx_target |= mini_sv_elg * cmx_mask.MINI_SV_ELG
cmx_target |= mini_sv_qso * cmx_mask.MINI_SV_QSO
cmx_target |= mini_sv_bgs_bright * cmx_mask.MINI_SV_BGS_BRIGHT
cmx_target |= sv0_mws_faint * cmx_mask.SV0_MWS_FAINT

# ADM update the priority with any shifts.
# ADM we may need to update this logic if there are other shifts.
Expand Down
46 changes: 25 additions & 21 deletions py/desitarget/cmx/data/cmx_targetmask.yaml
Expand Up @@ -3,24 +3,24 @@ cmx_mask:

- [STD_GAIA, 0, "Gaia stars used for dithering (and other) tests", {obsconditions: DARK|GRAY|BRIGHT}]
- [SV0_STD_FAINT, 1, "SV-like STD_FAINT class is set (very early SV selection)", {obsconditions: DARK|GRAY}]
- [SV0_STD_BRIGHT, 2, "SV-like STD_BRIGHT class is set (very early SV selection)", {obsconditions: BRIGHT}]
- [SV0_STD_BRIGHT, 2, "SV-like STD_BRIGHT class is set (very early SV selection)", {obsconditions: BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [STD_TEST, 3, "Very bright stars for early tests", {obsconditions: DARK|GRAY|BRIGHT}]
- [STD_CALSPEC, 4, "Matches to CALSPEC stars", {obsconditions: DARK|GRAY|BRIGHT}]
- [STD_CALSPEC, 4, "Matches to CALSPEC stars", {obsconditions: DARK|GRAY|BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [STD_DITHER, 5, "Gaia stars specifically for dithering tests", {obsconditions: DARK|GRAY|BRIGHT}]
- [SV0_MWS_CLUSTER, 6, "SV-like Open and Globular clusters for the MWS", {obsconditions: DARK|GRAY}]
- [SV0_MWS_CLUSTER_VERYBRIGHT, 7, "Bright SV-like Open and Globular clusters for the MWS", {obsconditions: BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [SV0_MWS_CLUSTER, 6, "SV-like Open and Globular clusters for the MWS", {obsconditions: POOR|TWILIGHT12|TWILIGHT18}]
- [SV0_MWS_CLUSTER_VERYBRIGHT, 7, "Bright SV-like Open and Globular clusters for the MWS", {obsconditions: TWILIGHT12|TWILIGHT18}]

# ADM targeting bits that should resemble at least the initial SV selections ("SV0").
- [SV0_BGS, 8, "SV-like BGS bit is set (very early SV selection)", {obsconditions: BRIGHT}]
- [SV0_MWS, 9, "SV-like MWS bit is set (very early SV selection)", {obsconditions: BRIGHT}]
- [SV0_MWS, 9, "SV-like MWS bit is set (very early SV selection)", {obsconditions: BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [SV0_LRG, 10, "SV-like LRG bit is set (very early SV selection)", {obsconditions: DARK}]
- [SV0_ELG, 11, "SV-like ELG bit is set (very early SV selection)", {obsconditions: DARK|GRAY}]
- [SV0_QSO, 12, "SV-like QSO bit is set (very early SV/RF selection)", {obsconditions: DARK}]
- [SV0_WD, 13, "SV-like WD bit is set (very early MWS_WD selection)", {obsconditions: BRIGHT}]
- [SV0_WD, 13, "SV-like WD bit is set (very early MWS_WD selection)", {obsconditions: BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [SV0_QSO_Z5, 14, "SV-like QSO bit is set (specifically for the QSO_Z5 selection from SV", {obsconditions: DARK}]

# ADM back-up targets for poor conditions.
- [BACKUP_BRIGHT, 16, "Bright Gaia targets for poor conditions", {obsconditions: POOR|TWILIGHT12|TWILIGHT18}]
- [BACKUP_BRIGHT, 16, "Bright Gaia targets for poor conditions", {obsconditions: TWILIGHT12|TWILIGHT18}]
- [BACKUP_FAINT, 17, "Fainter Gaia targets for poor conditions", {obsconditions: POOR|TWILIGHT12|TWILIGHT18}]

# ADM first light targets.
Expand Down Expand Up @@ -54,10 +54,12 @@ cmx_mask:

#- ADM retain bits 49-52 for masking/convenience (to mirror the main survey)

- [MINI_SV_LRG, 53, "LRGs for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [MINI_SV_ELG, 54, "ELGs for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [MINI_SV_QSO, 55, "QSOs (RF) for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [MINI_SV_BGS_BRIGHT, 56, "BGS (bright) for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT|POOR|TWILIGHT12|TWILIGHT18}]
- [MINI_SV_LRG, 53, "LRGs for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT}]
- [MINI_SV_ELG, 54, "ELGs for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT}]
- [MINI_SV_QSO, 55, "QSOs (RF) for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT}]
- [MINI_SV_BGS_BRIGHT, 56, "BGS (bright) for Mini SV tests (NORTH+SOUTH with noresolve)", {obsconditions: DARK|GRAY|BRIGHT}]

- [SV0_MWS_FAINT, 57, "Faint stars for Mini SV tests", {obsconditions: POOR|TWILIGHT12|TWILIGHT18}]

#- Calibration targets. Shared between main/cmx/sv programs.
- [SKY, 32, "Blank sky locations",
Expand Down Expand Up @@ -104,8 +106,8 @@ priorities:
STD_TEST: {UNOBS: 2800, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
STD_CALSPEC: {UNOBS: 3000, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
STD_DITHER: {UNOBS: 2400, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS_CLUSTER: {UNOBS: 1601, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS_CLUSTER_VERYBRIGHT: {UNOBS: 1600, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS_CLUSTER: {UNOBS: 1600, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS_CLUSTER_VERYBRIGHT: {UNOBS: 1601, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_BGS: {UNOBS: 2100, MORE_ZWARN: 2100, MORE_ZGOOD: 1000, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS: {UNOBS: 1500, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_ELG: {UNOBS: 3000, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
Expand Down Expand Up @@ -143,6 +145,7 @@ priorities:
MINI_SV_ELG: {UNOBS: 3001, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
MINI_SV_QSO: {UNOBS: 3420, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
MINI_SV_BGS_BRIGHT: {UNOBS: 2101, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
SV0_MWS_FAINT: {UNOBS: 5, DONE: 2, OBS: 1, DONOTOBSERVE: 0}
BAD_SKY: {UNOBS: 0, OBS: 0, DONE: 0, MORE_ZWARN: 0, MORE_ZGOOD: 0}
#- Standards and sky are treated specially; priorities don't apply
STD_FAINT: -1
Expand All @@ -155,20 +158,20 @@ priorities:
# ADM -1 means that the concept of NUMOBS doesn't apply to this bit
numobs:
cmx_mask:
STD_GAIA: 1
SV0_STD_FAINT: 1
SV0_STD_BRIGHT: 1
STD_GAIA: 100
SV0_STD_FAINT: 100
SV0_STD_BRIGHT: 100
STD_TEST: 1
STD_CALSPEC: 1
STD_CALSPEC: 100
STD_DITHER: 1
SV0_MWS_CLUSTER: 1
SV0_MWS_CLUSTER_VERYBRIGHT: 1
SV0_MWS_CLUSTER: 100
SV0_MWS_CLUSTER_VERYBRIGHT: 100
SV0_BGS: 1
SV0_MWS: 1
SV0_MWS: 100
SV0_ELG: 1
SV0_LRG: 2
SV0_QSO: 4
SV0_WD: 1
SV0_WD: 100
SV0_QSO_Z5: 4
BACKUP_BRIGHT: 1
BACKUP_FAINT: 1
Expand Down Expand Up @@ -200,6 +203,7 @@ numobs:
MINI_SV_LRG: 2
MINI_SV_QSO: 4
MINI_SV_BGS_BRIGHT: 1
SV0_MWS_FAINT: 1
BAD_SKY: 0
#- Standards and sky are treated specially; NUMOBS doesn't apply
STD_FAINT: -1
Expand Down
51 changes: 50 additions & 1 deletion py/desitarget/targets.py
Expand Up @@ -548,7 +548,56 @@ def calc_priority(targets, zcat, obscon):

# ADM Special case: SV-like commissioning targets.
if 'CMX_TARGET' in targets.dtype.names:
apcooper marked this conversation as resolved.
Show resolved Hide resolved
for name in ['SV0_' + label for label in ('BGS', 'MWS')]:
priority = _cmx_calc_priority(targets, priority,
unobs, done, zgood, zwarn, cmx_mask, obsconditions)

return priority


def _cmx_calc_priority(targets, priority, unobs, done, zgood, zwarn, cmx_mask, obsconditions):
"""Special-case logic for target priorities in CMX.

Parameters
----------
targets : :class:`~numpy.ndarray`
numpy structured array or astropy Table of targets. Must include
the column `CMX_TARGET`.
priority : :class:`~numpy.ndarray`
Initial priority values set, in calc_priorities().
unobs : :class:`~numpy.ndarray`
Boolean flag on targets indicating state UNOBS.
done : :class:`~numpy.ndarray`
Boolean flag on targets indicating state DONE.
zgood : :class:`~numpy.ndarray`
Boolean flag on targets indicating state ZGOOD.
zwarn : :class:`~numpy.ndarray`
Boolean flag on targets indicating state ZWARN.
cmx_mask : :class:`~desiutil.bitmask.BitMask`
The CMX target bitmask.
obscondtions : :class:`~desiutil.bitmask.BitMask`
The CMX obsconditions bitmask.

Returns
-------
:class:`~numpy.ndarray`
The updated priority values.

Notes
-----
- Intended to be called only from within calc_priority(), where any
pre-processing of the target state flags (uobs, done, zgood, zwarn) is
handled.

"""
# Build a whitelist of targets to update
names_to_update = ['SV0_' + label for label in ('STD_FAINT', 'STD_BRIGHT',
'BGS', 'MWS', 'WD', 'MWS_FAINT',
'MWS_CLUSTER', 'MWS_CLUSTER_VERYBRIGHT')]
names_to_update.extend(['BACKUP_BRIGHT', 'BACKUP_FAINT'])

for name in names_to_update:
pricon = obsconditions.mask(cmx_mask[name].obsconditions)
if (obsconditions.mask(obscon) & pricon) != 0:
ii = (targets['CMX_TARGET'] & cmx_mask[name]) != 0
priority[ii & unobs] = np.maximum(priority[ii & unobs], cmx_mask[name].priorities['UNOBS'])
priority[ii & done] = np.maximum(priority[ii & done], cmx_mask[name].priorities['DONE'])
Expand Down
15 changes: 9 additions & 6 deletions py/desitarget/test/test_priorities.py
Expand Up @@ -195,19 +195,22 @@ def test_cmx_priorities(self):
colnames, masks, _ = main_cmx_or_sv(t)
cmx_mask = masks[0]

# ADM test handling of unobserved SV0_BGS and SV0_MWS.
for name in ["SV0_BGS", "SV0_MWS"]:
# ADM test handling of unobserved SV0_BGS and SV0_MWS
for name, obscon in [("SV0_BGS", "BRIGHT"), ("SV0_MWS", "POOR")]:
t['CMX_TARGET'] = cmx_mask[name]
self.assertTrue(np.all(calc_priority(
t, z, "GRAY|DARK") == cmx_mask[name].priorities['UNOBS']))
t, z, obscon) == cmx_mask[name].priorities['UNOBS']))

# ADM done is Done, regardless of ZWARN.
for name in ["SV0_BGS", "SV0_MWS"]:
for name, obscon in [("SV0_BGS", "BRIGHT"), ("SV0_MWS", "POOR")]:
t['CMX_TARGET'] = cmx_mask[name]
t["PRIORITY_INIT"], t["NUMOBS_INIT"] = initial_priority_numobs(t)
z['NUMOBS'] = [0, 1, 1]

# APC: Use NUMOBS_INIT here to avoid hardcoding NOBS corresponding to "done".
numobs_done = t['NUMOBS_INIT'][0]
z['NUMOBS'] = [0, numobs_done, numobs_done]
z['ZWARN'] = [1, 1, 0]
p = make_mtl(t, "GRAY|DARK", zcat=z)["PRIORITY"]
p = make_mtl(t, obscon, zcat=z)["PRIORITY"]

self.assertEqual(p[0], cmx_mask[name].priorities['UNOBS'])
self.assertEqual(p[1], cmx_mask[name].priorities['DONE'])
Expand Down