diff --git a/py/desispec/coaddition.py b/py/desispec/coaddition.py index 02d355aa5..260253c2e 100644 --- a/py/desispec/coaddition.py +++ b/py/desispec/coaddition.py @@ -395,6 +395,16 @@ def coadd_fibermap(fibermap, onetile=False): if k in fibermap.colnames : tfmap[k][i]=1./np.mean(1./fibermap[k][jj][compute_coadds]) + #- Targeting bits can evolve, so use bitwise OR of any input bits set + #- See Sec 5.1 of https://ui.adsabs.harvard.edu/abs/2023AJ....165...50M/abstract + for targetcol in ('CMX_TARGET', + 'SV1_DESI_TARGET', 'SV1_BGS_TARGET', 'SV1_MWS_TARGET', 'SV1_SCND_TARGET', + 'SV2_DESI_TARGET', 'SV2_BGS_TARGET', 'SV2_MWS_TARGET', 'SV2_SCND_TARGET', + 'SV3_DESI_TARGET', 'SV3_BGS_TARGET', 'SV3_MWS_TARGET', 'SV3_SCND_TARGET', + 'DESI_TARGET', 'BGS_TARGET', 'MWS_TARGET', 'SCND_TARGET'): + if targetcol in tfmap.colnames: + tfmap[targetcol][i] = np.bitwise_or.reduce(fibermap[targetcol][jj],axis=0) + #- Remove some columns that apply to individual exp but not coadds #- (even coadds of the same tile) for k in ['NIGHT', 'EXPID', 'MJD', 'EXPTIME', 'NUM_ITER', diff --git a/py/desispec/test/test_coadd.py b/py/desispec/test/test_coadd.py index 89d0041d9..f0dbce220 100644 --- a/py/desispec/test/test_coadd.py +++ b/py/desispec/test/test_coadd.py @@ -510,6 +510,55 @@ def test_coadd_fibermap_mjd_night(self): self.assertEqual(cofm['MEAN_MJD'][1], np.mean(fm['MJD'][2:])) + def test_coadd_targetmask(self): + """Test coadding SV1/SV3/DESI_TARGET with varying bits""" + nspec = 4 + fm = Table() + fm['TARGETID'] = [111, 111, 222, 222] + fm['TILEID'] = 100 * np.ones(nspec, dtype=int) + fm['FIBERSTATUS'] = np.zeros(nspec, dtype=int) + fm['DESI_TARGET'] = 4 * np.ones(nspec, dtype=int) + fm['DESI_TARGET'][1] |= 8 + fm['DESI_TARGET'][3] |= 16 + + fm['CMX_TARGET'] = fm['DESI_TARGET'].copy() + fm['SV1_DESI_TARGET'] = fm['DESI_TARGET'].copy() + fm['SV2_DESI_TARGET'] = fm['DESI_TARGET'].copy() + fm['SV3_DESI_TARGET'] = fm['DESI_TARGET'].copy() + fm['SV1_MWS_TARGET'] = fm['DESI_TARGET'].copy() + 32 + fm['SV2_MWS_TARGET'] = fm['DESI_TARGET'].copy() + 32 + fm['SV3_MWS_TARGET'] = fm['DESI_TARGET'].copy() + 32 + fm['SV1_BGS_TARGET'] = fm['DESI_TARGET'].copy() + 64 + fm['SV2_BGS_TARGET'] = fm['DESI_TARGET'].copy() + 64 + fm['SV3_BGS_TARGET'] = fm['DESI_TARGET'].copy() + 64 + + cofm, expfm = coadd_fibermap(fm, onetile=True) + # first target has bitmasks 4+8=12 + self.assertEqual(cofm['DESI_TARGET'][0], 12) + self.assertEqual(cofm['CMX_TARGET'][0], 12) + self.assertEqual(cofm['SV1_DESI_TARGET'][0], 12) + self.assertEqual(cofm['SV2_DESI_TARGET'][0], 12) + self.assertEqual(cofm['SV3_DESI_TARGET'][0], 12) + self.assertEqual(cofm['SV1_MWS_TARGET'][0], 12+32) + self.assertEqual(cofm['SV2_MWS_TARGET'][0], 12+32) + self.assertEqual(cofm['SV3_MWS_TARGET'][0], 12+32) + self.assertEqual(cofm['SV1_BGS_TARGET'][0], 12+64) + self.assertEqual(cofm['SV2_BGS_TARGET'][0], 12+64) + self.assertEqual(cofm['SV3_BGS_TARGET'][0], 12+64) + + # second target has bitmasks 4+16=20 + self.assertEqual(cofm['DESI_TARGET'][1], 20) + self.assertEqual(cofm['CMX_TARGET'][1], 20) + self.assertEqual(cofm['SV1_DESI_TARGET'][1], 20) + self.assertEqual(cofm['SV2_DESI_TARGET'][1], 20) + self.assertEqual(cofm['SV3_DESI_TARGET'][1], 20) + self.assertEqual(cofm['SV1_MWS_TARGET'][1], 20+32) + self.assertEqual(cofm['SV2_MWS_TARGET'][1], 20+32) + self.assertEqual(cofm['SV3_MWS_TARGET'][1], 20+32) + self.assertEqual(cofm['SV1_BGS_TARGET'][1], 20+64) + self.assertEqual(cofm['SV2_BGS_TARGET'][1], 20+64) + self.assertEqual(cofm['SV3_BGS_TARGET'][1], 20+64) + def test_fiberstatus(self): """Test that FIBERSTATUS != 0 isn't included in coadd""" def _makespec(nspec, nwave):