Skip to content

Commit

Permalink
Merge d5f833c into 9f9d2a7
Browse files Browse the repository at this point in the history
  • Loading branch information
sbailey committed May 25, 2021
2 parents 9f9d2a7 + d5f833c commit 0b57d09
Show file tree
Hide file tree
Showing 5 changed files with 234 additions and 3 deletions.
23 changes: 23 additions & 0 deletions bin/select_secondary
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ ap.add_argument("--nomasking", action='store_true',
ap.add_argument("--maskdir",
help="Name of the specific directory (or file) containing the bright star mask (defaults to the most recent directory in $MASK_DIR)",
default=None)
ap.add_argument("--dark-subpriorities", type=str,
help='Optional file with dark TARGETID:SUBPRIORITY overrides')
ap.add_argument("--bright-subpriorities", type=str,
help='Optional file with bright TARGETID:SUBPRIORITY overrides')

ns = ap.parse_args()
do_mask = not(ns.nomasking)
Expand Down Expand Up @@ -88,13 +92,32 @@ if do_mask:
hdr["masked"] = do_mask
hdr["maskdir"] = mdcomp

# SB subpriority override logic assumes that io.write_targets will set
# subpriorities; if they have already been set, crash early so that we
# can fix the logic
if np.any(scx['SUBPRIORITY'] > 0.0):
log.critical('SUBPRIORITY already set; fix override logic below')
sys.exit(1)

# ADM write out the secondary targets, with bright-time
# ADM and dark-time targets written separately.
obscons = ["BRIGHT", "DARK"]

if ns.writeall:
obscons.append(None)
for obscon in obscons:

# SB apply optional subpriority override; modifies targets in-place
scx['SUBPRIORITY'] = 0.0 # SB reset any previous overrides
if obscon == 'BRIGHT' and ns.bright_subpriorities:
subpriorities = fitsio.read(ns.bright_subpriorities, 'SUBPRIORITY')
overrideidx = override_subpriority(scx, subpriorities)
log.info(f'Overriding {len(overrideidx)} {obscon} subpriorities')
elif obscon == 'DARK' and ns.dark_subpriorities:
subpriorities = fitsio.read(ns.dark_subpriorities, 'SUBPRIORITY')
overrideidx = override_subpriority(scx, subpriorities)
log.info(f'Overriding {len(overrideidx)} {obscon} subpriorities')

# ADM the dict() here is to make hdr immutable.
if obscon is None:
ntargs, outfile = io.write_secondary(ns.dest, scx, primhdr=dict(hdr),
Expand Down
14 changes: 14 additions & 0 deletions bin/select_skies
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ from desitarget.io import check_both_set
from desitarget.geomask import bundle_bricks
from desitarget.targets import resolve
from desitarget.brightmask import mask_targets, get_recent_mask_dir
from desitarget.subpriority import override_subpriority

import numpy as np
import healpy as hp
import fitsio
from glob import glob

#import warnings
Expand Down Expand Up @@ -67,6 +69,8 @@ ap.add_argument("--nomasking", action='store_true',
ap.add_argument("--maskdir",
help="Name of the specific directory (or file) containing the bright star mask (defaults to the most recent directory in $MASK_DIR)",
default=None)
ap.add_argument("--sky-subpriorities", type=str,
help='Optional file with sky TARGETID:SUBPRIORITY override')

ns = ap.parse_args()
do_mask = not(ns.nomasking)
Expand Down Expand Up @@ -171,6 +175,16 @@ else:
extra = {k: v for k, v in zip(["masked", "maskdir"],
[do_mask, mdcomp])}

# SB apply optional subpriority override; modifies skies in-place
if ns.sky_subpriorities:
subpriorities = fitsio.read(ns.sky_subpriorities, 'SUBPRIORITY')
ii = override_subpriority(skies, subpriorities)
if len(ii) > 0:
log.info(f"Overriding {len(ii)} SUBPRIORITY from {ns.sky_subpriorities}")
else:
log.warning(f"No matching targets to override SUBPRIORITY from {ns.sky_subpriorities}")


# ADM this correctly records the apertures in the output file header
# ADM as well as adding HEALPixel information.
nskies, outfile = io.write_skies(ns.dest, skies, indir=ns.surveydir,
Expand Down
25 changes: 25 additions & 0 deletions bin/select_targets
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ from desitarget.cuts import select_targets, qso_selection_options
from desitarget.brightmask import mask_targets
from desitarget.QA import _parse_tcnames
from desitarget.targets import decode_targetid
from desitarget.subpriority import override_subpriority

from time import time
start = time()
Expand Down Expand Up @@ -79,6 +80,10 @@ ap.add_argument("-noc", "--nochecksum", action='store_true',
help='Do NOT add the list of input files and their checksums to the output target file as the second ("INFILES") extension')
ap.add_argument("-check", "--checkbright", action='store_true',
help='If passed, then log a warning about targets that could be too bright when writing output files')
ap.add_argument("--dark-subpriorities", type=str,
help='Optional file with dark TARGETID:SUBPRIORITY overrides')
ap.add_argument("--bright-subpriorities", type=str,
help='Optional file with bright TARGETID:SUBPRIORITY overrides')

ns = ap.parse_args()
# ADM build the list of command line arguments as
Expand Down Expand Up @@ -212,7 +217,27 @@ if ns.bundlefiles is None:
obscons.append(None)
iis.append(~isgaia)
supps.append(False)

# SB subpriority override logic assumes that io.write_targets will set
# subpriorities; if they have already been set, crash early so that we
# can fix the logic
if np.any(targets['SUBPRIORITY'] > 0.0):
log.critical('SUBPRIORITY already set; fix override logic below')
sys.exit(1)

for obscon, ii, supp in zip(obscons, iis, supps):

# SB apply optional subpriority override; modifies targets in-place
targets['SUBPRIORITY'] = 0.0 # SB reset any previous overrides
if obscon == 'BRIGHT' and ns.bright_subpriorities:
subpriorities = fitsio.read(ns.bright_subpriorities, 'SUBPRIORITY')
overrideidx = override_subpriority(targets, subpriorities)
log.info(f'Overriding {len(overrideidx)} {obscon} subpriorities')
elif obscon == 'DARK' and ns.dark_subpriorities:
subpriorities = fitsio.read(ns.dark_subpriorities, 'SUBPRIORITY')
overrideidx = override_subpriority(targets, subpriorities)
log.info(f'Overriding {len(overrideidx)} {obscon} subpriorities')

ntargs, outfile = io.write_targets(
ns.dest, targets[ii], resolve=not(ns.noresolve), nside=nside,
maskbits=not(ns.nomaskbits), indir=ns.sweepdir, indir2=ns.sweepdir2,
Expand Down
16 changes: 13 additions & 3 deletions py/desitarget/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,10 @@ def write_targets(targdir, data, indir=None, indir2=None, nchunks=None,
# ADM populate SUBPRIORITY with a reproducible random float.
if "SUBPRIORITY" in data.dtype.names and mockdata is None:
np.random.seed(616)
data["SUBPRIORITY"] = np.random.random(ntargs)
# SB only set subpriorities that aren't already set, but keep original
# full random sequence order
ii = data["SUBPRIORITY"] > 0.0
data["SUBPRIORITY"][ii] = np.random.random(ntargs)[ii]

# ADM add the type of survey (main, commissioning; or "cmx", sv) to the header.
hdr["SURVEY"] = survey
Expand Down Expand Up @@ -965,7 +968,10 @@ def write_secondary(targdir, data, primhdr=None, scxdir=None, obscon=None,
if "SUBPRIORITY" in data.dtype.names:
ntargs = len(data)
np.random.seed(616)
data["SUBPRIORITY"] = np.random.random(ntargs)
# SB only set subpriorities that aren't already set, but keep original
# full random sequence order
ii = data["SUBPRIORITY"] > 0.0
data["SUBPRIORITY"][ii] = np.random.random(ntargs)[ii]

# ADM remove the supplemental columns.
from desitarget.secondary import suppdatamodel
Expand Down Expand Up @@ -1155,7 +1161,11 @@ def write_skies(targdir, data, indir=None, indir2=None, supp=False,
np.random.seed(626)
else:
np.random.seed(616)
data["SUBPRIORITY"] = np.random.random(nskies)

# SB only set subpriorities that aren't already set, but keep original
# full random sequence order
ii = data["SUBPRIORITY"] > 0.0
data["SUBPRIORITY"][ii] = np.random.random(nskies)[ii]

# ADM add the extra dictionary to the header.
if extra is not None:
Expand Down
159 changes: 159 additions & 0 deletions py/desitarget/subpriority.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
#!/usr/bin/env python

"""
Get what subpriority was used by fiberassign
"""

import os.path
import numpy as np
import fitsio

from desiutil.log import get_logger

from desitarget.targetmask import desi_mask

def override_subpriority(targets, override):
"""
Override SUBPRIORITY column in targets for those in override table
Args:
targets: table with columns TARGETID and SUBPRIORITY
override: table with columns TARGETID and SUBPRIORITY
Returns:
indices of targets table rows that were changed
Modifies ``targets`` table in-place without copying memory.
Rows in ``targets`` that aren't in ``override`` are unchanged.
Rows in ``override`` that aren't in ``targets`` are ignored.
"""
log = get_logger()
ii = np.where(np.isin(targets['TARGETID'], override['TARGETID']))[0]
n = len(ii)
if n > 0:
subprio_dict = dict()
for tid, subprio in zip(override['TARGETID'], override['SUBPRIORITY']):
subprio_dict[tid] = subprio

for i in ii:
tid = targets['TARGETID'][i]
targets['SUBPRIORITY'][i] = subprio_dict[tid]

return ii


def get_fiberassign_subpriorities(fiberassignfiles):
"""
TODO: document
"""
log = get_logger()

#- allow duplicate inputs, but don't process multiple tiles
processed = set()

subprio_tables = dict(dark=list(), bright=list(), sky=list())

for filename in fiberassignfiles:
#- Have we already processed this file (e.g. from an earlier expid)?
basename = os.path.basename(filename)
if basename in processed:
continue
else:
processed.add(basename)

with fitsio.FITS(filename) as fx:
hdr = fx[0].read_header()

if 'SURVEY' not in hdr:
log.warning(f"Skipping {filename} missing SURVEY keyword")
continue

if 'FAPRGRM' not in hdr:
log.warning(f"Skipping {filename} missing FAPRGRM keyword")
continue

program = hdr['FAPRGRM'].lower()
if program not in ('dark', 'bright'):
log.warning(f"Skipping {filename} with FAPRGRM={program}")
continue

if hdr['SURVEY'].lower() != 'main':
log.info(f"Skipping {filename} with SURVEY {hdr['SURVEY']} != main")
continue

log.info(f'Reading {filename}')
sp = fx['TARGETS'].read(columns=['TARGETID', 'SUBPRIORITY', 'DESI_TARGET'])

#- Separate skies from non-skies
skymask = desi_mask.mask('SKY|SUPP_SKY|BAD_SKY')
iisky = (sp['DESI_TARGET'] & skymask) != 0

subprio_tables['sky'].append(sp[iisky])
subprio_tables[program].append(sp[~iisky])

log.info('Stacking individual fiberassign inputs')
for program in subprio_tables.keys():
subprio_tables[program] = np.hstack(subprio_tables[program])

#- QA checks on basic assumptions about uniqueness
log.info('Checking assumptions about TARGETID:SUBPRIORITY uniqueness')
for program in ['dark', 'bright', 'sky']:
subprio = subprio_tables[program]
tid, sortedidx = np.unique(subprio['TARGETID'], return_index=True)

#- sky can appear multiple times, but with same SUBPRIORITY
if program == 'sky':
subpriodict = dict()
for targetid, sp in zip(
subprio['TARGETID'], subprio['SUBPRIORITY']):
if targetid in subpriodict:
if sp != subpriodict[targetid]:
log.error(f'{program} TARGETID {targetid} has multiple subpriorities')
else:
subpriodict[targetid] = sp
#- but other programs should have each TARGETID exactly once
else:
if len(tid) != len(subprio):
log.error(f'Some {program} TARGETIDs appear multiple times')

log.info(f'Sorting {program} targets by TARGETID')
subprio_tables[program] = subprio[sortedidx]

return subprio_tables

if __name__ == "__main__":
import argparse

p = argparse.ArgumentParser()
p.add_argument('-i', '--infiles', nargs='+', required=True,
help='Input fiberassign files with TARGETS HDU')
p.add_argument('-o', '--outdir', required=True,
help='Output directory to keep dark/bright/sky TARGETID SUBPRIORITY tables')

args = p.parse_args()
log = get_logger()

nfiles = len(args.infiles)
log.info(f'Getting target subpriorities from {nfiles} fiberassign files')
subprio_tables = get_fiberassign_subpriorities(args.infiles)

if 'DESI_ROOT' in os.environ:
desiroot = os.path.normpath(os.getenv('DESI_ROOT'))
else:
desiroot = None

for program, subprio in subprio_tables.items():
hdr = fitsio.FITSHDR()
hdr['FAPRGRM'] = program
for i, filename in enumerate(args.infiles):
if desiroot and filename.startswith(desiroot):
filename = filename.replace(desiroot, '$DESI_ROOT')

hdr[f'INFIL{i:03d}'] = filename

outfile = os.path.join(args.outdir, f'subpriorities-{program}.fits')
fitsio.write(outfile, subprio, extname='SUBPRIORITY', header=hdr, clobber=True)
log.info(f'Wrote {outfile}')



0 comments on commit 0b57d09

Please sign in to comment.