Noticed originally by @abrodze, the output of fba_launch generates fiberassign output files from the raw fba files using
|
def merge_results(targetfiles, skyfiles, tiles, result_dir=".", |
which calls the per tile version
|
def merge_results_tile(out_dtype, copy_fba, params): |
The merging code only sets values for "fiberassign valid" TARGETIDs, defined as positive TARGETIDS:
|
# Rows containing assigned fibers |
|
fassign_valid = np.where(fiber_data["TARGETID"] >= 0)[0] |
Then it only sets the OBJTYPE for these TARGETIDs:
|
objtype = np.zeros(len(fassign_valid), dtype="S3") |
|
# AR relaxing the condition on the presence of any |
|
# AR *_TARGET, excluding FA_TARGET |
|
# AR hence accepting CMX_.., SV1_..., SV2_... |
|
#if "DESI_TARGET" in out_dtype.names: # AR commented out |
|
if "_TARGET" in [name[-7:] for name in out_dtype.names if name!="FA_TARGET"]: |
|
# This is a main survey file. |
|
objtype[:] = "TGT" |
|
is_sky = (tile_targets["DESI_TARGET"][target_rows] |
|
& desi_mask.SKY) != 0 |
|
is_sky |= (tile_targets["DESI_TARGET"][target_rows] |
|
& desi_mask.SUPP_SKY) != 0 |
|
objtype[is_sky] = "SKY" |
|
badmask = \ |
|
desi_mask.mask("BAD_SKY|NO_TARGET|IN_BRIGHT_OBJECT") |
|
is_bad = (tile_targets["DESI_TARGET"][target_rows] |
|
& badmask) != 0 |
|
objtype[is_bad] = "BAD" |
Which means that negative TARGETIDs have the default fill value (an empty string) for OBJTYPE.
Nominally I think the negative TARGETIDs are supposed to be handled by this line:
|
# Special handling for STUCK positioners that land on good SKY positions. |
|
# In the FA files these get FA_TYPE & 4 (SKY) and a negative TARGETID. |
|
stucksky_rows = np.where((fiber_data['TARGETID'] < 0) * |
|
((fiber_data['FA_TYPE'] & TARGET_TYPE_SKY) != 0))[0] |
|
if len(stucksky_rows): |
|
outdata['OBJTYPE'][stucksky_rows] = 'SKY' |
but evidently something in the boolean condition here is not flagging for the entire set of negative targetids (is fiberassign not propogating the TARGET_TYPE_SKY bit for some of these targets?). That is, only a subset of the negative targetids are captured by these two lines.
Picking a pseudorandom fiberassign file (fiberassign-101689.fits.gz) and reading the "FIBERASSIGN" header:
643 TARGETIDs are negative
400 of those are OBJTYPE == "SKY" set correctly
243 of these have no OBJTYPE == "".
This seems like an oversight but I don't know what the correct value should be set for these targets, but I certainly don't think it should be an empty string.
It's also not clear if the issue is actually in assign.py or if something upstream isn't propagating a bit correctly which is then mangling the results in this file.
Noticed originally by @abrodze, the output of fba_launch generates fiberassign output files from the raw fba files using
fiberassign/py/fiberassign/assign.py
Line 1474 in d93c2e3
fiberassign/py/fiberassign/assign.py
Line 1102 in d93c2e3
The merging code only sets values for "fiberassign valid" TARGETIDs, defined as positive TARGETIDS:
fiberassign/py/fiberassign/assign.py
Lines 1265 to 1266 in d93c2e3
Then it only sets the OBJTYPE for these TARGETIDs:
fiberassign/py/fiberassign/assign.py
Lines 1325 to 1342 in d93c2e3
Which means that negative TARGETIDs have the default fill value (an empty string) for OBJTYPE.
Nominally I think the negative TARGETIDs are supposed to be handled by this line:
fiberassign/py/fiberassign/assign.py
Lines 1297 to 1302 in d93c2e3
but evidently something in the boolean condition here is not flagging for the entire set of negative targetids (is fiberassign not propogating the TARGET_TYPE_SKY bit for some of these targets?). That is, only a subset of the negative targetids are captured by these two lines.
Picking a pseudorandom fiberassign file (fiberassign-101689.fits.gz) and reading the "FIBERASSIGN" header:
643 TARGETIDs are negative
400 of those are OBJTYPE == "SKY" set correctly
243 of these have no OBJTYPE == "".
This seems like an oversight but I don't know what the correct value should be set for these targets, but I certainly don't think it should be an empty string.
It's also not clear if the issue is actually in assign.py or if something upstream isn't propagating a bit correctly which is then mangling the results in this file.