def prepare_sdss_catalog_for_merging(catalog, to_remove=None, to_recover=None): for b in get_sdss_bands(): catalog['{}_mag'.format(b)] = np.where( catalog['PHOTPTYPE'] == 6, catalog['PSFMAG_{}'.format(b.upper())], catalog[b]) - catalog['EXTINCTION_{}'.format(b.upper())] catalog['y_mag'] = 99.0 catalog['y_err'] = 99.0 catalog['is_galaxy'] = (catalog['PHOTPTYPE'] == 3) catalog['morphology_info'] = catalog['PHOTPTYPE'].astype(np.int32) catalog['radius'] = catalog['PETROR50_R'] catalog['radius_err'] = catalog['PETRORADERR_R'] * catalog[ 'PETROR50_R'] / catalog['PETRORAD_R'] fill_values_by_query( catalog, Query('radius_err < 0') | (~Query((np.isfinite, 'radius_err'))), {'radius_err': 9999.0}) remove_queries = [ 'BINNED1 == 0', 'SATURATED != 0', 'BAD_COUNTS_ERROR != 0', (lambda *x: np.abs(np.median(x, axis=0)) > 0.5, 'g_err', 'r_err', 'i_err'), 'abs(r_mag - i_mag) > 10', 'abs(g_mag - r_mag) > 10', ] catalog = set_remove_flag(catalog, remove_queries, to_remove, to_recover) return catalog[MERGED_CATALOG_COLUMNS]
def remove_bad_photometry(base): """ Remove objects that have bad SDSS photometry. Set REMOVE to 3, 4, or 5. This is step (4) of object removal. `base` is modified in-place. Parameters ---------- base : astropy.table.Table Returns ------- base : astropy.table.Table """ has_nsa = Query('OBJ_NSAID > -1') q = Query('BINNED1 == 0') q |= Query('SATURATED != 0') q |= Query('BAD_COUNTS_ERROR != 0') fill_values_by_query(base, q & (~has_nsa), {'REMOVE': 3}) q = Query((lambda *x: np.abs(np.median(x, axis=0)) > 0.5, 'g_err', 'r_err', 'i_err')) fill_values_by_query(base, q & (~has_nsa), {'REMOVE': 4}) return base
def test_simple_query(): """ test simple queries """ t = gen_test_table() check_query_on_table(t, Query(), None) check_query_on_table(t, Query('a > 3'), t['a'] > 3) check_query_on_table(t, Query('a == 100'), t['a'] == 100) check_query_on_table(t, Query('b > c'), t['b'] > t['c']) check_query_on_table(t, Query('a < 3', 'b > c'), (t['a'] < 3) & (t['b'] > t['c']))
def test_filter_column_slice(): t = gen_test_table() q = Query('a > 2') assert (q.filter(t, 'b') == t['b'][t['a'] > 2]).all() q = Query('a > 2', 'b < 2') assert (q.filter(t, 'c') == t['c'][(t['a'] > 2) & (t['b'] < 2)]).all() q = Query(None) assert (q.filter(t, 'a') == t['a']).all()
def remove_shreds_with_highz(base): """ Remove shereded objects that are within 1.25 R of each high-z (beyond NSA redshift cutoff) object in the base catalog. Set REMOVE to 4. Because this function uses objects with specs, it should be applied to base catalog after the specs are cleaned (i.e., after `clean_sdss_spectra`) `base` is modified in-place. Parameters ---------- base : astropy.table.Table Returns ------- base : astropy.table.Table """ highz_spec_cut = Query('SPEC_Z > 0.05', 'ZQUALITY >= 3', 'PETRORADERR_R > 0', 'PETRORAD_R > 2.0*PETRORADERR_R', 'REMOVE == -1') highz_spec_indices = np.flatnonzero(highz_spec_cut.mask(base)) for idx in highz_spec_indices: if base['REMOVE'][idx] != -1: continue nearby_obj_mask = (base['coord'].separation(base['coord'][idx]).arcsec < 1.25 * base['PETRORAD_R'][idx]) nearby_obj_mask &= (base['REMOVE'] == -1) assert nearby_obj_mask[idx] nearby_obj_mask[idx] = False nearby_obj_count = np.count_nonzero(nearby_obj_mask) if not nearby_obj_count: continue if nearby_obj_count > 25: logging.warning( 'In SAGA.objects.build.remove_shreds_with_highz()\n Too many (> 25) shreds around high-z object {} ({}, {})' .format(base['OBJID'][idx], base['RA'][idx], base['DEC'][idx])) base['REMOVE'][nearby_obj_mask] = 4 return base
def read_aat(dir_path, before_time=None): usecols = {2: 'RA', 3: 'DEC', 5: 'SPEC_Z', 7: 'ZQUALITY', 8: 'SPECOBJID'} cuts = Query('ZQUALITY >= 1') def midprocess(t): fits_filepath = os.path.join( dir_path, t['MASKNAME'][0].replace('.zlog', '.fits.gz')) try: corr, obstime = heliocentric_correction(fits_filepath, 'sso', 'MEANRA', 'MEANDEC', 'UTMJD') except IOError: t['HELIO_CORR'] = False else: if before_time is not None and obstime > before_time: return t['SPEC_Z'] += corr t['HELIO_CORR'] = True return t def postprocess(t): t['SPEC_Z_ERR'] = 10 / _SPEED_OF_LIGHT return t return read_generic_spectra(dir_path, '.zlog', 'AAT', usecols, 11, cuts, postprocess, midprocess)
def read_wiyn(dir_path): output = [] for f in os.listdir(dir_path): if not f.endswith('.fits.gz'): continue this = FitsTable(os.path.join(dir_path, f)).read()[[ 'RA', 'DEC', 'ZQUALITY', 'FID', 'Z', 'Z_ERR' ]] this = Query('ZQUALITY >= 1').filter(this) this['MASKNAME'] = f output.append(this) output = vstack(output, 'exact', 'error') output.rename_column('FID', 'SPECOBJID') output.rename_column('Z', 'SPEC_Z') output.rename_column('Z_ERR', 'SPEC_Z_ERR') output['TELNAME'] = 'WIYN' sc = SkyCoord(output['RA'], output['DEC'], unit=("hourangle", "deg")) output['RA'] = sc.ra.deg output['DEC'] = sc.dec.deg del sc return ensure_specs_dtype(output)
def add_more_photometric_data(base, wise, **kwargs): """ Add more photometric data to the base catalog (for a single host). `base` is modified in-place. Parameters ---------- base : astropy.table.Table wise : astropy.table.Table Returns ------- base : astropy.table.Table Notes ----- Currently this function only adds wise data, but in the future this function may add more photometric data """ if kwargs: raise NotImplementedError('Photometric data other than wise has not been implemented.') cols_rename = {'W1_MAG':'W1', 'W1_MAG_ERR':'W1ERR', 'W2_MAG':'W2', 'W2_MAG_ERR':'W2ERR'} join_table_by_coordinates(base, wise, list(cols_rename.keys()), cols_rename) # use -1.0 instead np.nan for missing values for col in cols_rename.values(): fill_values_by_query(base, Query((np.isnan, col)), {col:-1.0}) return base
def check_invalid_init(*queries): try: q = Query(*queries) # noqa: F841 except ValueError: pass else: raise AssertionError
def test_variable_names(): q1 = Query('log(a) > b**2.0') q2 = Query((lambda x, y: x + y < 1, 'c', 'd')) q3 = q1 & 'a + 2' q4 = ~q2 q5 = q1 ^ q2 q6 = Query('sin(5)') q7 = Query() assert set(q1.variable_names) == {'a', 'b'} assert set(q2.variable_names) == {'c', 'd'} assert set(q3.variable_names) == {'a', 'b'} assert set(q4.variable_names) == {'c', 'd'} assert set(q5.variable_names) == {'a', 'b', 'c', 'd'} assert set(q6.variable_names) == set() assert set(q7.variable_names) == set()
def read_mmt(dir_path, before_time=None): usecols = { 2: 'RA', 3: 'DEC', 4: 'mag', 5: 'SPEC_Z', 6: 'SPEC_Z_ERR', 7: 'ZQUALITY', 8: 'SPECOBJID' } cuts = Query('mag != 0', 'ZQUALITY >= 1') def midprocess(t): fits_filepath = os.path.join( dir_path, t['MASKNAME'][0].replace('.zlog', '.fits.gz')) try: corr, obstime = heliocentric_correction(fits_filepath, 'mmt', 'RA', 'DEC', 'MJD') except IOError: t['HELIO_CORR'] = False else: if before_time is not None and obstime > before_time: return t['SPEC_Z'] += corr t['HELIO_CORR'] = True return t def postprocess(t): del t['mag'] t['RA'] *= 15.0 return t return read_generic_spectra(dir_path, '.zlog', 'MMT', usecols, 11, cuts, postprocess, midprocess)
def set_remove_flag(base, objects_to_remove, objects_to_add): """ Set remove flag in the base catalog (for a single host), using the remove list and other info existing in the base catalog. `base` is modified in-place. Parameters ---------- base : astropy.table.Table objects_to_remove : astropy.table.Table objects_to_add : astropy.table.Table Returns ------- base : astropy.table.Table """ if 'REMOVE' not in base: base['REMOVE'] = -1 ids_to_remove = np.unique(objects_to_remove['SDSS ID'].data.compressed()) fill_values_by_query(base, Query((lambda x: np.in1d(x, ids_to_remove), 'OBJID')), {'REMOVE': 1}) del ids_to_remove fill_values_by_query(base, C.too_close_to_host, {'REMOVE': 1}) q = Query('BINNED1 == 0') q |= Query('SATURATED != 0') q |= Query('BAD_COUNTS_ERROR != 0') fill_values_by_query(base, q, {'REMOVE': 3}) q = Query('abs(PETRORAD_R - PETRORAD_G) > 40', 'r < 18') q |= Query('abs(PETRORAD_R - PETRORAD_I) > 40', 'r < 18') fill_values_by_query(base, q, {'REMOVE': 4}) q = Query('SB_EXP_R > 24', '(PETRORADERR_G + PETRORADERR_R + PETRORADERR_I)/3.0 == -1000.0') q |= Query('SB_EXP_R > 24', (lambda *x: np.median(x, axis=0) == -1000.0, 'PETRORADERR_G', 'PETRORADERR_R', 'PETRORADERR_I'), 'r < 18') fill_values_by_query(base, q, {'REMOVE': 5}) q = Query((lambda *x: np.abs(np.median(x, axis=0)) > 0.5, 'g_err', 'r_err', 'i_err')) fill_values_by_query(base, q, {'REMOVE': 3}) ids_to_add = np.unique(objects_to_add['SDSS ID'].data.compressed()) fill_values_by_query(base, Query((lambda x: np.in1d(x, ids_to_add), 'OBJID')), {'REMOVE': -1}) return base
def extract_sdss_spectra(sdss): specs = Query('SPEC_Z > -1.0').filter(sdss['RA', 'DEC', 'SPEC_Z', 'SPEC_Z_ERR', 'SPEC_Z_WARN']) specs['ZQUALITY'] = np.where(specs['SPEC_Z_WARN'] == 0, 4, 1) specs['TELNAME'] = 'SDSS' specs['MASKNAME'] = 'SDSS' specs['SPECOBJID'] = '' specs['HELIO_CORR'] = True del specs['SPEC_Z_WARN'] return ensure_specs_dtype(specs)
def test_valid_init(): """ test valid Query object creation """ q1 = Query() q2 = Query(None) q3 = Query('x > 2') q4 = Query(lambda t: t['x'] > 2) q5 = Query((lambda c: c > 2, 'x')) q6 = Query('x > 2', lambda t: t['x'] > 2, (lambda c: c > 2, 'x')) q7 = Query(q3) q8 = Query(q3, 'x > 2')
def initialize_base_catalog(base): """ Initialize the base catalog with empty columns. Also fill in some columns for objects that already have SDSS specs. `base` is modified in-place. Parameters ---------- base : astropy.table.Table Returns ------- base : astropy.table.Table """ base = add_skycoord(base) base['REMOVE'] = np.int16(-1) base['ZQUALITY'] = np.int16(-1) base['SATS'] = np.int16(-1) base['SPEC_HA_EW'] = np.float32(-9999.0) base['SPEC_HA_EWERR'] = np.float32(-9999.0) base['OBJ_NSAID'] = np.int32(-1) empty_str_arr = get_empty_str_array(len(base), 48) base['MASKNAME'] = empty_str_arr base['SPECOBJID'] = empty_str_arr base['SPEC_REPEAT'] = empty_str_arr base['TELNAME'] = get_empty_str_array(len(base), 6) fill_values_by_query( base, Query('SPEC_Z > -1.0'), { 'TELNAME': 'SDSS', 'MASKNAME': 'SDSS', 'SPEC_REPEAT': 'SDSS', 'ZQUALITY': 4 }) fill_values_by_query(base, Query('SPEC_Z > -1.0', 'SPEC_Z_WARN != 0'), {'ZQUALITY': 1}) return base
def test_valid_init(): """ test valid Query object creation """ q1 = Query() # noqa: F841 q2 = Query(None) # noqa: F841 q3 = Query('x > 2') q4 = Query(lambda t: t['x'] > 2) # noqa: F841 q5 = Query((lambda c: c > 2, 'x')) # noqa: F841 q6 = Query('x > 2', lambda t: t['x'] > 2, (lambda c: c > 2, 'x')) # noqa: F841 q7 = Query(q3) # noqa: F841 q8 = Query(q3, 'x > 2') # noqa: F841
def prepare_decals_catalog_for_merging(catalog, to_remove, to_recover): catalog['OBJID'] = np.array(catalog['BRICKID'], dtype=np.int64) * int(1e13) + np.array( catalog['OBJID'], dtype=np.int64) catalog['is_galaxy'] = (catalog['TYPE'] != 'PSF') catalog['morphology_info'] = catalog['TYPE'].getfield('<U1').view(np.int32) catalog['radius'] = catalog['FRACDEV'] * catalog['SHAPEDEV_R'] + ( 1.0 - catalog['FRACDEV']) * catalog['SHAPEEXP_R'] catalog['radius_err'] = np.hypot( catalog['FRACDEV']**2.0 / catalog['SHAPEDEV_R_IVAR'], (1.0 - catalog['FRACDEV'])**2.0 / catalog['SHAPEEXP_R_IVAR']) fill_values_by_query( catalog, Query('radius_err < 0') | (~Query((np.isfinite, 'radius_err'))), {'radius_err': 9999.0}) for band in 'uiy': catalog['{}_mag'.format(band)] = 99.0 catalog['{}_err'.format(band)] = 99.0 for band in 'grz': catalog['{}_mag'.format(band)] += 0.1 remove_queries = [ 'radius >= 20', 'FRACMASKED_G >= 0.35', 'FRACMASKED_R >= 0.35', 'RCHISQ_G >= 10', 'RCHISQ_R >= 10', 'RCHISQ_Z >= 10', 'ALLMASK_G > 0', 'ALLMASK_R > 0', 'g_err >= 0.2', 'r_err >= 0.2', Query('NOBS_G == 0', 'NOBS_R == 0'), 'r_mag >= 25', ] catalog = set_remove_flag(catalog, remove_queries, to_remove, to_recover) return catalog[MERGED_CATALOG_COLUMNS]
def _get_redshifts(filepath, night=None, target_ids=None): z1, z2 = load_fits(filepath, [1, 2]) if not any(col in z2.colnames for col in ["SV3_DESI_TARGET", "DESI_TARGET"]): return # z2.sort(["TARGETID", "NUM_ITER"]) z2 = unique(z2, "TARGETID", keep="last") q = Query() if target_ids is None else QueryMaker.isin( "TARGETID", target_ids) z1 = q.filter( z1, ["TARGETID", "Z", "ZERR", "ZWARN", "CHI2", "DELTACHI2", "SPECTYPE"]) z2_cols = [ "TARGETID", "TARGET_RA", "TARGET_DEC", "FLUX_R", "FLUX_G", "SHAPE_R", "FLUX_IVAR_R", "FLUX_IVAR_G", "EBV", "OBSCONDITIONS", "NIGHT", "TILEID", "FIBER", "SV3_SCND_TARGET", "SV3_BGS_TARGET", "SV3_DESI_TARGET", "SCND_TARGET", "BGS_TARGET" ] z2_cols_exist = [col for col in z2_cols if col in z2.colnames] z2_cols_not_exist = [col for col in z2_cols if col not in z2.colnames] z2 = q.filter(z2, z2_cols_exist) for col in z2_cols_not_exist: z2[col] = np.int32(-1) if night is not None: z2["NIGHT"] = night if len(z1) and len(z2): z = join(z1, z2, "TARGETID") if len(z): for BAND in ("G", "R"): z[f"SIGMA_{BAND}"] = z[f"FLUX_{BAND}"] * np.sqrt( np.abs(z[f"FLUX_IVAR_{BAND}"])) z[f"MW_TRANSMISSION_{BAND}"] = mw_xtinct(z["EBV"], BAND) const = 2.5 / np.log(10) for band in "gr": BAND = band.upper() with np.errstate(divide="ignore", invalid="ignore"): z[f"{band}_mag"] = _fill_not_finite(22.5 - const * np.log( z[f"FLUX_{BAND}"] / z[f"MW_TRANSMISSION_{BAND}"])) z[f"{band}_err"] = _fill_not_finite( const / np.abs(z[f"SIGMA_{BAND}"])) return z
def read_6df(file_path): if not hasattr(file_path, 'read'): file_path = FitsTable(file_path) specs = file_path.read()['RAJ2000', 'DEJ2000', '_6dFGS', 'cz', 'e_cz', 'q_cz'] # 3 = probably galaxy, 4 = definite galaxy, 6 = confirmed star specs = (Query('q_cz == 3') | Query('q_cz == 4') | Query('q_cz == 6')).filter(specs) specs['SPEC_Z'] = specs['cz'] / _SPEED_OF_LIGHT specs['SPEC_Z_ERR'] = specs['e_cz'] / _SPEED_OF_LIGHT del specs['cz'], specs['e_cz'] specs.rename_column('_6dFGS', 'SPECOBJID') specs.rename_column('RAJ2000', 'RA') specs.rename_column('DEJ2000', 'DEC') specs.rename_column('q_cz', 'ZQUALITY') specs['TELNAME'] = '6dF' specs['MASKNAME'] = '6dF' specs['HELIO_CORR'] = True return ensure_specs_dtype(specs)
def get_remove_flag(catalog, remove_queries): """ get remove flag by remove queries. remove_queries can be a list or dict. """ try: iter_queries = iter(remove_queries.items()) except AttributeError: iter_queries = enumerate(remove_queries) remove_flag = np.zeros(len(catalog), dtype=np.int) for i, remove_query in iter_queries: remove_flag[Query(remove_query).mask(catalog)] += (1 << i) return remove_flag
def load_nsa(self, version='0.1.2'): nsa = self._database['nsa_v{}'.format(version)].read() if version == '0.1.2': nsa = nsa[build.NSA_COLS_USED] for nsaid, fixes in fixes_to_nsa_v012.items(): fill_values_by_query(nsa, 'NSAID == {}'.format(nsaid), fixes) # NSA 64408 (127.324917502, 25.75292055) is wrong! For v0.1.2 ONLY!! nsa = Query('NSAID != 64408').filter(nsa) elif version == '1.0.1': nsa = nsa[build2.NSA_COLS_USED] for nsaid, fixes in fixes_to_nsa_v101.items(): fill_values_by_query(nsa, 'NSAID == {}'.format(nsaid), fixes) nsa = add_skycoord(nsa) return nsa
def replace_poor_sdss_sky_subtraction(base): mask = Query( 'abs(r_mag_sdss - r_mag_decals) > 2', (lambda s: s == 'sdss', 'survey'), 'OBJID_decals != -1', 'REMOVE_decals == 0', ).mask(base) base['survey'][mask] = 'decals' for col in base.colnames: if col.endswith('_decals'): base[col.rpartition('_')[0]][mask] = base[col][mask] return base
def fill_values_by_query(table, query, values_to_fill): """ Examples -------- fill_values_by_query(table, 'OBJID == 1237668367995568266', {'SPEC_Z': 0.21068, 'TELNAME':'SDSS', 'MASKNAME':'SDSS'}) """ mask = Query(query).mask(table) n_matched = np.count_nonzero(mask) if n_matched: for c, v in values_to_fill.items(): table[c][mask] = v return n_matched
def find_objid(table, objid): """ Parameters ---------- table : astropy.table.Table needs to have an integer column called `OBJID` objid : int Returns ------- table : astropy.table.Table """ t = Query('OBJID=={}'.format(objid)).filter(table) if len(t) == 0: raise KeyError('Cannot find OBJID {}'.format(objid)) return t[0]
def merge_spectra(specs): if 'coord' in specs.colnames: del specs['coord'] specs['group_id'] = get_fof_group_id(specs, 20.0) specs.sort(['group_id', 'SPEC_Z']) group_id_shift = specs['group_id'][-1] + 1 edge_mask = (np.ediff1d(specs['group_id']) > 0) | (np.ediff1d( specs['SPEC_Z']) > 150.0 / _SPEED_OF_LIGHT) group_id_edges = np.flatnonzero(np.hstack(([True], edge_mask, [True]))) regroup_mask = np.zeros(len(specs), np.bool) for i, j in zip(group_id_edges[:-1], group_id_edges[1:]): if j - i > 1 and ( np.median(specs['SPEC_Z'][i:j]) > 0.2 or np.count_nonzero(specs['TELNAME'][i:j] == 'NSA') > 1): regroup_mask[i:j] = True if regroup_mask.any(): specs['group_id'][regroup_mask] = get_fof_group_id( specs[regroup_mask], 10.0) + group_id_shift specs.sort(['group_id', 'SPEC_Z']) edge_mask = (np.ediff1d(specs['group_id']) > 0) | (np.ediff1d( specs['SPEC_Z']) > 150.0 / _SPEED_OF_LIGHT) group_id_edges = np.flatnonzero(np.hstack(([True], edge_mask, [True]))) del regroup_mask, edge_mask specs['SPEC_REPEAT'] = get_empty_str_array(len(specs), 48) specs['OBJ_NSAID'] = np.int32(-1) specs['chosen'] = False for i, j in zip(group_id_edges[:-1], group_id_edges[1:]): if j - i > 1: k, spec_repeat, nsa_id = find_best_spec(specs[i:j]) else: k = 0 spec_repeat = specs['TELNAME'][i] nsa_id = int(specs['SPECOBJID'][i]) if spec_repeat == 'NSA' else -1 k += i specs['chosen'][k] = True specs['SPEC_REPEAT'][k] = spec_repeat specs['OBJ_NSAID'][k] = nsa_id specs = Query('chosen').filter(specs) del specs['chosen'], specs['group_id'] return specs
def set_remove_flag(catalog, remove_queries=None, manual_remove=None, manual_recover=None): remove_queries = [] if remove_queries is None else list(remove_queries) if manual_remove is not None: remove_queries.append((lambda x: np.in1d(x, manual_remove), 'OBJID')) catalog['REMOVE'] = get_remove_flag(catalog, remove_queries) if manual_recover is not None: fill_values_by_query( catalog, Query((lambda x: np.in1d(x, manual_recover), 'OBJID')), {'REMOVE': 0}) return catalog
def read_generic_spectra(dir_path, extension, telname, usecols, n_cols_total, cuts=None, postprocess=None, midprocess=None, **kwargs): names = [usecols.get(i + 1, '_{}'.format(i)) for i in range(n_cols_total)] exclude_names = [n for n in names if n.startswith('_')] output = [] for f in os.listdir(dir_path): if not f.endswith(extension): continue try: this = Table.read(os.path.join(dir_path, f), format='ascii.fast_no_header', guess=False, names=names, exclude_names=exclude_names, **kwargs) except (IOError, CParserError) as e: logging.warning( 'SKIPPING spectra file {}/{} - could not read or parse\n{}'. format(dir_path, f, e)) continue this = Query(cuts).filter(this) if 'MASKNAME' not in this.colnames: this['MASKNAME'] = f if midprocess: this = midprocess(this) if this is not None: output.append(this) output = vstack(output, 'exact', 'error') output['TELNAME'] = telname if postprocess: output = postprocess(output) return ensure_specs_dtype(output)
def remove_too_close_to_host(base): """ Remove objects that are too close to the host. Set REMOVE to 1. This is step (2) of object removal. This will unfortunately also remove the host itself! But the host will be added back during `remove_shreds_with_nsa` `base` is modified in-place. Parameters ---------- base : astropy.table.Table Returns ------- base : astropy.table.Table """ fill_values_by_query(base, Query('RHOST_KPC < 10.0'), {'REMOVE': 1}) return base
def remove_human_inspected(base, objects_to_remove): """ Use the "remove list" to set REMOVE to 1 in the base catalog. This is step (1) of object removal. `base` is modified in-place. Parameters ---------- base : astropy.table.Table objects_to_remove : astropy.table.Table Returns ------- base : astropy.table.Table """ fill_values_by_query( base, Query((lambda x: np.in1d(x, objects_to_remove), 'OBJID')), {'REMOVE': 1}) return base
def recover_whitelisted_objects(base, objects_to_recover): """ Use the "add list" to set REMOVE back to -1 for whitelisted objects. This is mainly to deal with objects that are removed by `remove_bad_photometry` This is step (5) of object removal. `base` is modified in-place. Parameters ---------- base : astropy.table.Table objects_to_recover : astropy.table.Table Returns ------- base : astropy.table.Table """ fill_values_by_query( base, Query((lambda x: np.in1d(x, objects_to_recover), 'OBJID')), {'REMOVE': -1}) return base