Skip to content

Commit

Permalink
Merge pull request #2302 from desihub/frames2spectra_headers
Browse files Browse the repository at this point in the history
desi_group_spectra  header propagation cleanup
  • Loading branch information
sbailey authored Jul 24, 2024
2 parents 71dfe82 + 77edc4b commit d3bff04
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 3 deletions.
47 changes: 45 additions & 2 deletions py/desispec/pixgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -552,23 +552,38 @@ def add_missing_frames(frames):
wave[band], flux, ivar, mask, resolution_data,
frame.fibermap, header, scores)

def frames2spectra(frames, pix=None, nside=64):
def frames2spectra(frames, pix=None, nside=64, onetile=False):
'''
Combine a dict of FrameLite into a SpectraLite for healpix `pix`
Args:
frames: dict of FrameLight, keyed by (night, expid, camera)
frames: list or dict of FrameLight, keyed by (night, expid, camera)
Options:
pix: only include targets in this NESTED healpix pixel number
nside: Healpix nside, must be power of 2
onetile: All frames come from the same tile (impacts keyword propagation)
Returns:
SpectraLite object with subset of spectra from frames that are in
the requested healpix pixel `pix`
If `onetile` is True, propagate fibermap header keywords that apply
to a single tile, e.g. TILEID and fiberassign keywords
'''
log = get_logger()

#- support list or tuple instead of dict as input
if isinstance(frames, (list, tuple)):
framedict = dict()
for fr in frames:
night = fr.meta['NIGHT']
expid = fr.meta['EXPID']
camera = fr.meta['CAMERA']
framedict[(night, expid, camera)] = fr

frames = framedict

#- shallow copy of frames dict in case we augment with blank frames
frames = frames.copy()

Expand Down Expand Up @@ -704,6 +719,34 @@ def frames2spectra(frames, pix=None, nside=64):
outmap['FIBERSTATUS'] |= banddict[band]['FIBERSTATUS']
merged_over_cams_fmaps.append(outmap)

#- Only keep fibermap keywords that apply to combined spectra, not individual exp
general_keywords = [
'SURVEY', 'PROGRAM', 'EXTNAME', 'LONGSTRN',
'INSTRUME', 'OBSERVAT', 'OBS-LAT', 'OBS-LONG', 'OBS-ELEV', 'TELESCOP'
]

tile_keywords = [
'TILEID', 'TILERA', 'TILEDEC', 'FIELDROT',
'FILEDROT', 'FA_PLAN', 'FA_HA', 'FA_RUN', 'FA_M_GFA',
'FA_M_PET', 'FA_M_POS', 'REQRA', 'REQDEC', 'FIELDNUM',
'FA_VER', 'FA_SURV', 'FAFLAVOR', 'FAPRGRM', 'DESIROOT',
'GFA', 'MTL', 'SCND', 'SCND2', 'SCND3', 'SCNDMTL', 'SKY',
'SKYSUPP', 'TARG', 'TOO', 'FAARGS', 'FAOUTDIR',
'NOWTIME', 'RUNDATE', 'PMCORR', 'PMTIME', 'MTLTIME',
'OBSCON', 'GOALTIME', 'GOALTYPE', 'EBVFAC', 'SBPROF',
'MINTFRAC', 'FASCRIPT', 'SVNDM', 'SVNMTL',
]

if onetile:
keep_keywords = general_keywords + tile_keywords
else:
keep_keywords = general_keywords

for fm in merged_over_cams_fmaps:
for key in list(fm.meta.keys()):
if key not in keep_keywords:
del fm.meta[key]

#- Convert to Tables to facilitate column add/drop/reorder
for i, fm in enumerate(merged_over_cams_fmaps):
if not isinstance(fm, Table):
Expand Down
3 changes: 2 additions & 1 deletion py/desispec/scripts/group_spectra.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,8 @@ def main(args=None, comm=None):
framesdict[(night, expid, camera)] = frame

log0.info(f'Combining into spectra at {time.asctime()}')
spectra = frames2spectra(framesdict, pix=args.healpix, nside=args.nside)
spectra = frames2spectra(framesdict, pix=args.healpix, nside=args.nside,
onetile=args.onetile)

#- Record input files
if spectra.meta is None:
Expand Down
61 changes: 61 additions & 0 deletions py/desispec/test/test_pixgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,4 +372,65 @@ def test_exp2healpix_map(self):
self.assertGreater(n1, 0)
self.assertEqual(n6, 0)

def test_frames2spectra(self):
"""Test frames2spectra"""
from ..pixgroup import FrameLite, frames2spectra

#- Read input frames
frames = list()
for filename in self.framefiles:
frames.append( FrameLite.read(filename) )

#- Set some header keywords for testing
for i, fr in enumerate(frames):
fr.fibermap.meta['BLAT'] = i #- conflicting, never merged
fr.fibermap.meta['FOO'] = 'biz' #- consistent, but still not merged
fr.fibermap.meta['TILEID'] = 1234 #- only merged if onetile=True
fr.fibermap.meta['SURVEY'] = 'main' #- always merged
fr.fibermap.meta['PROGRAM'] = 'dark' #- always merged

#- converting list of frames
spectra = frames2spectra(frames)

#- converting dict of frames
framedict = dict()
for fr in frames:
night = fr.meta['NIGHT']
expid = fr.meta['EXPID']
camera = fr.meta['CAMERA']
framedict[(night, expid, camera)] = fr

spectra = frames2spectra(framedict)

#- Check header keyword propagation
self.assertNotIn('BLAT', spectra.fibermap.meta)
self.assertNotIn('FOO', spectra.fibermap.meta)
self.assertNotIn('TILEID', spectra.fibermap.meta)
self.assertIn('SURVEY', spectra.fibermap.meta)
self.assertIn('PROGRAM', spectra.fibermap.meta)

#- but originals were not changed
for i, fr in enumerate(frames):
self.assertEqual(fr.fibermap.meta['BLAT'], i)
self.assertEqual(fr.fibermap.meta['FOO'], 'biz')
self.assertEqual(fr.fibermap.meta['TILEID'], 1234)
self.assertEqual(fr.fibermap.meta['SURVEY'], 'main')
self.assertEqual(fr.fibermap.meta['PROGRAM'], 'dark')

#- frames2spectra(..., onetile=True) should propagate TILEID
spectra = frames2spectra(framedict, onetile=True)
self.assertNotIn('BLAT', spectra.fibermap.meta)
self.assertNotIn('FOO', spectra.fibermap.meta)
self.assertIn('TILEID', spectra.fibermap.meta) #- different from before
self.assertIn('SURVEY', spectra.fibermap.meta)
self.assertIn('PROGRAM', spectra.fibermap.meta)

#- originals are still not changed
for i, fr in enumerate(frames):
self.assertEqual(fr.fibermap.meta['BLAT'], i)
self.assertEqual(fr.fibermap.meta['FOO'], 'biz')
self.assertEqual(fr.fibermap.meta['TILEID'], 1234)
self.assertEqual(fr.fibermap.meta['SURVEY'], 'main')
self.assertEqual(fr.fibermap.meta['PROGRAM'], 'dark')


0 comments on commit d3bff04

Please sign in to comment.