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

desi_group_spectra header propagation cleanup #2302

Merged
merged 3 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 39 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,28 @@ 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
keep_keywords = ['SURVEY', 'PROGRAM', 'EXTNAME', 'LONGSTRN',
'INSTRUME', 'OBSERVAT', 'OBS-LAT', 'OBS-LONG', 'OBS-ELEV', 'TELESCOP']

if onetile:
keep_keywords.extend([
sbailey marked this conversation as resolved.
Show resolved Hide resolved
'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',
])

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')


Loading