XMM-LSS master catalogue - IRAC merging¶

This notebook presents the merge of the IRAC pristine catalogues to produce the HELP master catalogue on XMM-LSS.

In [1]:
from herschelhelp_internal import git_version
print("This notebook was run with herschelhelp_internal version: \n{}".format(git_version()))
This notebook was run with herschelhelp_internal version: 
33f5ec7 (Wed Dec 6 16:56:17 2017 +0000)
In [2]:
%matplotlib inline
#%config InlineBackend.figure_format = 'svg'

import matplotlib.pyplot as plt
plt.rc('figure', figsize=(10, 6))

import os
import time

from astropy import units as u
from astropy.coordinates import SkyCoord
from astropy.table import Column, Table
import numpy as np
from pymoc import MOC

from herschelhelp_internal.masterlist import merge_catalogues, nb_merge_dist_plot, specz_merge
from herschelhelp_internal.utils import coords_to_hpidx, ebv, gen_help_id, inMoc
In [3]:
TMP_DIR = os.environ.get('TMP_DIR', "./data_tmp")
OUT_DIR = os.environ.get('OUT_DIR', "./data")
SUFFIX = os.environ.get('SUFFIX', time.strftime("_%Y%m%d"))

try:
    os.makedirs(OUT_DIR)
except FileExistsError:
    pass

I - Reading the prepared pristine catalogues¶

In [4]:
#candels = Table.read("{}/CANDELS.fits".format(TMP_DIR))           # 1.1
#cfht_wirds = Table.read("{}/CFHT-WIRDS.fits".format(TMP_DIR))     # 1.3
#cfhtls_wide = Table.read("{}/CFHTLS-WIDE.fits".format(TMP_DIR))   # 1.4a
#cfhtls_deep = Table.read("{}/CFHTLS-DEEP.fits".format(TMP_DIR))   # 1.4b
#We no longer use CFHTLenS as it is the same raw data set as CFHTLS-WIDE
# cfhtlens = Table.read("{}/CFHTLENS.fits".format(TMP_DIR))         # 1.5
#decals = Table.read("{}/DECaLS.fits".format(TMP_DIR))             # 1.6

servs = Table.read("{}/SERVS.fits".format(TMP_DIR))               # 1.8
swire = Table.read("{}/SWIRE.fits".format(TMP_DIR))               # 1.7

#hsc_wide = Table.read("{}/HSC-WIDE.fits".format(TMP_DIR))         # 1.9a
#hsc_deep = Table.read("{}/HSC-DEEP.fits".format(TMP_DIR))         # 1.9b
#hsc_udeep = Table.read("{}/HSC-UDEEP.fits".format(TMP_DIR))       # 1.9c
#ps1 = Table.read("{}/PS1.fits".format(TMP_DIR))                   # 1.10
#sxds = Table.read("{}/SXDS.fits".format(TMP_DIR))                 # 1.11
#sparcs = Table.read("{}/SpARCS.fits".format(TMP_DIR))             # 1.12
#dxs = Table.read("{}/UKIDSS-DXS.fits".format(TMP_DIR))            # 1.13
#uds = Table.read("{}/UKIDSS-UDS.fits".format(TMP_DIR))            # 1.14
#vipers = Table.read("{}/VIPERS.fits".format(TMP_DIR))             # 1.15
#vhs = Table.read("{}/VISTA-VHS.fits".format(TMP_DIR))             # 1.16
#video = Table.read("{}/VISTA-VIDEO.fits".format(TMP_DIR))         # 1.17
#viking = Table.read("{}/VISTA-VIKING.fits".format(TMP_DIR))       # 1.18

II - Merging tables¶

We first merge the optical catalogues and then add the infrared ones. We start with PanSTARRS because it coevrs the whole field.

At every step, we look at the distribution of the distances separating the sources from one catalogue to the other (within a maximum radius) to determine the best cross-matching radius.

Start with SERVS¶

In [5]:
master_catalogue = servs
master_catalogue['servs_ra'].name = 'ra'
master_catalogue['servs_dec'].name = 'dec'

Add SWIRE¶

In [6]:
nb_merge_dist_plot(
    SkyCoord(master_catalogue['ra'], master_catalogue['dec']),
    SkyCoord(swire['swire_ra'], swire['swire_dec'])
)
In [7]:
# Given the graph above, we use 1 arc-second radius
master_catalogue = merge_catalogues(master_catalogue, swire, "swire_ra", "swire_dec", radius=1.*u.arcsec)

Cleaning¶

When we merge the catalogues, astropy masks the non-existent values (e.g. when a row comes only from a catalogue and has no counterparts in the other, the columns from the latest are masked for that row). We indicate to use NaN for masked values for floats columns, False for flag columns and -1 for ID columns.

In [8]:
for col in master_catalogue.colnames:
    if "m_" in col or "merr_" in col or "f_" in col or "ferr_" in col or "stellarity" in col:
        master_catalogue[col] = master_catalogue[col].astype(float)
        master_catalogue[col].fill_value = np.nan
    elif "flag" in col:
        master_catalogue[col].fill_value = 0
    elif "id" in col:
        master_catalogue[col].fill_value = -1
        
master_catalogue = master_catalogue.filled()
In [9]:
#Since this is not the final merged catalogue. We rename column names to make them unique
master_catalogue['ra'].name = 'irac_ra'
master_catalogue['dec'].name = 'irac_dec'
master_catalogue['flag_merged'].name = 'irac_flag_merged'
In [10]:
master_catalogue[:10].show_in_notebook()
Out[10]:
<Table length=10>
idxservs_intidirac_rairac_decf_ap_servs_irac_i1ferr_ap_servs_irac_i1f_servs_irac_i1ferr_servs_irac_i1servs_stellarity_irac_i1f_ap_servs_irac_i2ferr_ap_servs_irac_i2f_servs_irac_i2ferr_servs_irac_i2servs_stellarity_irac_i2m_ap_servs_irac_i1merr_ap_servs_irac_i1m_servs_irac_i1merr_servs_irac_i1flag_servs_irac_i1m_ap_servs_irac_i2merr_ap_servs_irac_i2m_servs_irac_i2merr_servs_irac_i2flag_servs_irac_i2servs_flag_cleanedservs_flag_gaiairac_flag_mergedswire_intidf_ap_swire_irac_i1ferr_ap_swire_irac_i1f_swire_irac_i1ferr_swire_irac_i1swire_stellarity_irac_i1f_ap_swire_irac_i2ferr_ap_swire_irac_i2f_swire_irac_i2ferr_swire_irac_i2swire_stellarity_irac_i2f_ap_irac_i3ferr_ap_irac_i3f_irac_i3ferr_irac_i3swire_stellarity_irac_i3f_ap_irac_i4ferr_ap_irac_i4f_irac_i4ferr_irac_i4swire_stellarity_irac_i4m_ap_swire_irac_i1merr_ap_swire_irac_i1m_swire_irac_i1merr_swire_irac_i1flag_swire_irac_i1m_ap_swire_irac_i2merr_ap_swire_irac_i2m_swire_irac_i2merr_swire_irac_i2flag_swire_irac_i2m_ap_irac_i3merr_ap_irac_i3m_irac_i3merr_irac_i3flag_irac_i3m_ap_irac_i4merr_ap_irac_i4m_irac_i4merr_irac_i4flag_irac_i4swire_flag_cleanedswire_flag_gaia
degdeg
0344571834.5078548113-4.181411784451.859284167220.1993451078331.459110607730.1575237257690.34nannannannannan23.22663557230.11640834931623.4897794630.117214700016FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
1294469634.6249735113-5.453145384452.296290220880.2014741180122.039206797880.2189439069910.59nannannannannan22.99743305920.095261366467623.12634682440.116572447129FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
2296502034.8008917113-5.358858134453.002611021150.2062950301122.366995656380.1885883622240.845.516872152170.5728385872364.858585845680.7386509160280.2622.70625231410.074595737335522.96450634760.0865051070588False22.04576770060.11273627093222.18372529840.16506449977FalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
3285967835.7017118113-5.450521084453.529119964260.2074494611062.718913281220.1696214395060.87nannannannannan22.53083394640.063821970593622.81401160970.067734465548FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
4311203134.8082012113-4.985115784450.5286059216580.2158864215450.4172321197720.13693969140.35nannannannannan24.59216994010.44342239536824.84905566420.356349316785FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
5309858636.7314761113-4.574648684453.083538459810.2161967029292.33991262960.1910595284240.81nannannannannan22.6773765760.076124423540922.97700089620.0886529884278FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
6311174534.8088588113-4.981006634450.7223174588850.2186711047220.5422628034140.1526280423170.220.5672020624150.4023910609630.5173418193310.2100920396340.3524.25317971960.32869084418624.56447546260.305596825675False24.51565549670.7702555620124.61555603490.440916479662FalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
7291746734.6321277113-5.524311084450.8627327691660.2189601883620.8929701846890.2931735054270.06nannannannannan24.06030926460.27555810142124.02290760370.356461049401FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
8311217934.8115695613-4.980488484453.83579632140.2195607049263.229167503170.2272161821140.893.018003350190.437294616552.581076002750.3968373192210.5822.44036115420.06214746209322.62727356680.0763964195062False22.70070070620.15731811474122.87049801740.166930630643FalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
9311330534.8097592113-4.978086084451.456294381740.2209534342782.325051385120.4136829425590.12nannannannannan23.49187706490.16473121517822.98391861120.193178761941FalsenannannannanFalseFalse0False-1nannannannannannannannannannannannannannannannannannannannannannannannanFalsenannannannanFalsenannannannanFalsenannannannanFalseFalse0
In [11]:
master_catalogue.add_column(Column(data=(np.char.array(master_catalogue['servs_intid'].astype(str)) 
                                    +  np.char.array(master_catalogue['swire_intid'].astype(str) )), 
                              name="irac_intid"))
In [12]:
id_names = []
for col in master_catalogue.colnames:
    if '_id' in col:
        id_names += [col]
    if '_intid' in col:
        id_names += [col]
        
print(id_names)
['servs_intid', 'swire_intid', 'irac_intid']

VII - Choosing between multiple values for the same filter¶

VII.a SERVS and SWIRE IRAC fluxes¶

Both SERVS and SWIRE provide IRAC1 and IRAC2 fluxes. SERVS is deeper but tends to under-estimate flux of bright sources (Mattia said over 2000 µJy) as illustrated by this comparison of SWIRE, SERVS, and Spitzer-EIP fluxes.

In [13]:
seip = Table.read("../../dmu0/dmu0_SEIP/data/SEIP_XMM-LSS.fits")
seip_coords = SkyCoord(seip['ra'], seip['dec'])
idx, d2d, _ = seip_coords.match_to_catalog_sky(SkyCoord(master_catalogue['irac_ra'], master_catalogue['irac_dec']))
mask = d2d <= 2 * u.arcsec
WARNING: UnitsWarning: 'e/count' did not parse as fits unit: At col 0, Unit 'e' not supported by the FITS standard.  [astropy.units.core]
WARNING: UnitsWarning: 'image' did not parse as fits unit: At col 0, Unit 'image' not supported by the FITS standard.  [astropy.units.core]
In [14]:
fig, ax = plt.subplots()
ax.scatter(seip['i1_f_ap1'][mask], master_catalogue[idx[mask]]['f_ap_servs_irac_i1'], label="SERVS", s=2.)
ax.scatter(seip['i1_f_ap1'][mask], master_catalogue[idx[mask]]['f_ap_swire_irac_i1'], label="SWIRE", s=2.)
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel("SEIP flux [μJy]")
ax.set_ylabel("SERVS/SWIRE flux [μJy]")
ax.set_title("IRAC 1")
ax.legend()
ax.axvline(2000, color="black", linestyle="--", linewidth=1.)
ax.plot(seip['i1_f_ap1'][mask], seip['i1_f_ap1'][mask], linewidth=.1, color="black", alpha=.5);
In [15]:
fig, ax = plt.subplots()
ax.scatter(seip['i2_f_ap1'][mask], master_catalogue[idx[mask]]['f_ap_servs_irac_i2'], label="SERVS", s=2.)
ax.scatter(seip['i2_f_ap1'][mask], master_catalogue[idx[mask]]['f_ap_swire_irac_i2'], label="SWIRE", s=2.)
ax.set_xscale('log')
ax.set_yscale('log')
ax.set_xlabel("SEIP flux [μJy]")
ax.set_ylabel("SERVS/SWIRE flux [μJy]")
ax.set_title("IRAC 2")
ax.legend()
ax.axvline(2000, color="black", linestyle="--", linewidth=1.)

ax.plot(seip['i1_f_ap2'][mask], seip['i1_f_ap2'][mask], linewidth=.1, color="black", alpha=.5);

When both SWIRE and SERVS fluxes are provided, we use the SERVS flux below 2000 μJy and the SWIRE flux over.

We create a table indicating for each source the origin on the IRAC1 and IRAC2 fluxes that will be saved separately.

In [16]:
irac_origin = Table()
irac_origin.add_column(master_catalogue['irac_intid'])
In [17]:
# IRAC1 aperture flux and magnitudes
has_servs = ~np.isnan(master_catalogue['f_ap_servs_irac_i1'])
has_swire = ~np.isnan(master_catalogue['f_ap_swire_irac_i1'])
has_both = has_servs & has_swire

print("{} sources with SERVS flux".format(np.sum(has_servs)))
print("{} sources with SWIRE flux".format(np.sum(has_swire)))
print("{} sources with SERVS and SWIRE flux".format(np.sum(has_both)))

has_servs_above_limit = has_servs.copy()
has_servs_above_limit[has_servs] = master_catalogue['f_ap_servs_irac_i1'][has_servs] > 2000

use_swire = (has_swire & ~has_servs) | (has_both & has_servs_above_limit)
use_servs = (has_servs & ~(has_both & has_servs_above_limit))

print("{} sources for which we use SERVS".format(np.sum(use_servs)))
print("{} sources for which we use SWIRE".format(np.sum(use_swire)))

f_ap_irac_i = np.full(len(master_catalogue), np.nan)
f_ap_irac_i[use_servs] = master_catalogue['f_ap_servs_irac_i1'][use_servs]
f_ap_irac_i[use_swire] = master_catalogue['f_ap_swire_irac_i1'][use_swire]

ferr_ap_irac_i = np.full(len(master_catalogue), np.nan)
ferr_ap_irac_i[use_servs] = master_catalogue['ferr_ap_servs_irac_i1'][use_servs]
ferr_ap_irac_i[use_swire] = master_catalogue['ferr_ap_swire_irac_i1'][use_swire]

m_ap_irac_i = np.full(len(master_catalogue), np.nan)
m_ap_irac_i[use_servs] = master_catalogue['m_ap_servs_irac_i1'][use_servs]
m_ap_irac_i[use_swire] = master_catalogue['m_ap_swire_irac_i1'][use_swire]

merr_ap_irac_i = np.full(len(master_catalogue), np.nan)
merr_ap_irac_i[use_servs] = master_catalogue['merr_ap_servs_irac_i1'][use_servs]
merr_ap_irac_i[use_swire] = master_catalogue['merr_ap_swire_irac_i1'][use_swire]

master_catalogue.add_column(Column(data=f_ap_irac_i, name="f_ap_irac_i1"))
master_catalogue.add_column(Column(data=ferr_ap_irac_i, name="ferr_ap_irac_i1"))
master_catalogue.add_column(Column(data=m_ap_irac_i, name="m_ap_irac_i1"))
master_catalogue.add_column(Column(data=merr_ap_irac_i, name="merr_ap_irac_i1"))

master_catalogue.remove_columns(['f_ap_servs_irac_i1', 'f_ap_swire_irac_i1', 'ferr_ap_servs_irac_i1',
                                     'ferr_ap_swire_irac_i1', 'm_ap_servs_irac_i1', 'm_ap_swire_irac_i1',
                                     'merr_ap_servs_irac_i1', 'merr_ap_swire_irac_i1'])

origin = np.full(len(master_catalogue), '     ', dtype='<U5')
origin[use_servs] = "SERVS"
origin[use_swire] = "SWIRE"
irac_origin.add_column(Column(data=origin, name="IRAC1_app"))
710828 sources with SERVS flux
466544 sources with SWIRE flux
239549 sources with SERVS and SWIRE flux
709839 sources for which we use SERVS
227984 sources for which we use SWIRE
In [18]:
# IRAC1 total flux and magnitudes
has_servs = ~np.isnan(master_catalogue['f_servs_irac_i1'])
has_swire = ~np.isnan(master_catalogue['f_swire_irac_i1'])
has_both = has_servs & has_swire

print("{} sources with SERVS flux".format(np.sum(has_servs)))
print("{} sources with SWIRE flux".format(np.sum(has_swire)))
print("{} sources with SERVS and SWIRE flux".format(np.sum(has_both)))

has_servs_above_limit = has_servs.copy()
has_servs_above_limit[has_servs] = master_catalogue['f_servs_irac_i1'][has_servs] > 2000

use_swire = (has_swire & ~has_servs) | (has_both & has_servs_above_limit)
use_servs = (has_servs & ~(has_both & has_servs_above_limit))

print("{} sources for which we use SERVS".format(np.sum(use_servs)))
print("{} sources for which we use SWIRE".format(np.sum(use_swire)))

f_ap_irac_i = np.full(len(master_catalogue), np.nan)
f_ap_irac_i[use_servs] = master_catalogue['f_servs_irac_i1'][use_servs]
f_ap_irac_i[use_swire] = master_catalogue['f_swire_irac_i1'][use_swire]

ferr_ap_irac_i = np.full(len(master_catalogue), np.nan)
ferr_ap_irac_i[use_servs] = master_catalogue['ferr_servs_irac_i1'][use_servs]
ferr_ap_irac_i[use_swire] = master_catalogue['ferr_swire_irac_i1'][use_swire]

flag_irac_i = np.full(len(master_catalogue), False, dtype=bool)
flag_irac_i[use_servs] = master_catalogue['flag_servs_irac_i1'][use_servs]
flag_irac_i[use_swire] = master_catalogue['flag_swire_irac_i1'][use_swire]

m_ap_irac_i = np.full(len(master_catalogue), np.nan)
m_ap_irac_i[use_servs] = master_catalogue['m_servs_irac_i1'][use_servs]
m_ap_irac_i[use_swire] = master_catalogue['m_swire_irac_i1'][use_swire]

merr_ap_irac_i = np.full(len(master_catalogue), np.nan)
merr_ap_irac_i[use_servs] = master_catalogue['merr_servs_irac_i1'][use_servs]
merr_ap_irac_i[use_swire] = master_catalogue['merr_swire_irac_i1'][use_swire]

master_catalogue.add_column(Column(data=f_ap_irac_i, name="f_irac_i1"))
master_catalogue.add_column(Column(data=ferr_ap_irac_i, name="ferr_irac_i1"))
master_catalogue.add_column(Column(data=m_ap_irac_i, name="m_irac_i1"))
master_catalogue.add_column(Column(data=merr_ap_irac_i, name="merr_irac_i1"))
master_catalogue.add_column(Column(data=flag_irac_i, name="flag_irac_i1"))

master_catalogue.remove_columns(['f_servs_irac_i1', 'f_swire_irac_i1', 'ferr_servs_irac_i1',
                                 'ferr_swire_irac_i1', 'm_servs_irac_i1', 'flag_servs_irac_i1', 'm_swire_irac_i1',
                                 'merr_servs_irac_i1', 'merr_swire_irac_i1', 'flag_swire_irac_i1'])

origin = np.full(len(master_catalogue), '     ', dtype='<U5')
origin[use_servs] = "SERVS"
origin[use_swire] = "SWIRE"
irac_origin.add_column(Column(data=origin, name="IRAC1_total"))
710828 sources with SERVS flux
465906 sources with SWIRE flux
239547 sources with SERVS and SWIRE flux
709760 sources for which we use SERVS
227427 sources for which we use SWIRE
In [19]:
# IRAC2 aperture flux and magnitudes
has_servs = ~np.isnan(master_catalogue['f_ap_servs_irac_i2'])
has_swire = ~np.isnan(master_catalogue['f_ap_swire_irac_i2'])
has_both = has_servs & has_swire

print("{} sources with SERVS flux".format(np.sum(has_servs)))
print("{} sources with SWIRE flux".format(np.sum(has_swire)))
print("{} sources with SERVS and SWIRE flux".format(np.sum(has_both)))

has_servs_above_limit = has_servs.copy()
has_servs_above_limit[has_servs] = master_catalogue['f_ap_servs_irac_i2'][has_servs] > 2000

use_swire = (has_swire & ~has_servs) | (has_both & has_servs_above_limit)
use_servs = (has_servs & ~(has_both & has_servs_above_limit))

print("{} sources for which we use SERVS".format(np.sum(use_servs)))
print("{} sources for which we use SWIRE".format(np.sum(use_swire)))

f_ap_irac_i = np.full(len(master_catalogue), np.nan)
f_ap_irac_i[use_servs] = master_catalogue['f_ap_servs_irac_i2'][use_servs]
f_ap_irac_i[use_swire] = master_catalogue['f_ap_swire_irac_i2'][use_swire]

ferr_ap_irac_i = np.full(len(master_catalogue), np.nan)
ferr_ap_irac_i[use_servs] = master_catalogue['ferr_ap_servs_irac_i2'][use_servs]
ferr_ap_irac_i[use_swire] = master_catalogue['ferr_ap_swire_irac_i2'][use_swire]

m_ap_irac_i = np.full(len(master_catalogue), np.nan)
m_ap_irac_i[use_servs] = master_catalogue['m_ap_servs_irac_i2'][use_servs]
m_ap_irac_i[use_swire] = master_catalogue['m_ap_swire_irac_i2'][use_swire]

merr_ap_irac_i = np.full(len(master_catalogue), np.nan)
merr_ap_irac_i[use_servs] = master_catalogue['merr_ap_servs_irac_i2'][use_servs]
merr_ap_irac_i[use_swire] = master_catalogue['merr_ap_swire_irac_i2'][use_swire]

master_catalogue.add_column(Column(data=f_ap_irac_i, name="f_ap_irac_i2"))
master_catalogue.add_column(Column(data=ferr_ap_irac_i, name="ferr_ap_irac_i2"))
master_catalogue.add_column(Column(data=m_ap_irac_i, name="m_ap_irac_i2"))
master_catalogue.add_column(Column(data=merr_ap_irac_i, name="merr_ap_irac_i2"))

master_catalogue.remove_columns(['f_ap_servs_irac_i2', 'f_ap_swire_irac_i2', 'ferr_ap_servs_irac_i2',
                                 'ferr_ap_swire_irac_i2', 'm_ap_servs_irac_i2', 'm_ap_swire_irac_i2',
                                 'merr_ap_servs_irac_i2', 'merr_ap_swire_irac_i2'])

origin = np.full(len(master_catalogue), '     ', dtype='<U5')
origin[use_servs] = "SERVS"
origin[use_swire] = "SWIRE"
irac_origin.add_column(Column(data=origin, name="IRAC2_app"))
731919 sources with SERVS flux
324491 sources with SWIRE flux
175800 sources with SERVS and SWIRE flux
731206 sources for which we use SERVS
149404 sources for which we use SWIRE
In [20]:
# IRAC2 total flux and magnitudes
has_servs = ~np.isnan(master_catalogue['f_servs_irac_i2'])
has_swire = ~np.isnan(master_catalogue['f_swire_irac_i2'])
has_both = has_servs & has_swire

print("{} sources with SERVS flux".format(np.sum(has_servs)))
print("{} sources with SWIRE flux".format(np.sum(has_swire)))
print("{} sources with SERVS and SWIRE flux".format(np.sum(has_both)))

has_servs_above_limit = has_servs.copy()
has_servs_above_limit[has_servs] = master_catalogue['f_servs_irac_i2'][has_servs] > 2000

use_swire = (has_swire & ~has_servs) | (has_both & has_servs_above_limit)
use_servs = (has_servs & ~(has_both & has_servs_above_limit))

print("{} sources for which we use SERVS".format(np.sum(use_servs)))
print("{} sources for which we use SWIRE".format(np.sum(use_swire)))

f_ap_irac_i = np.full(len(master_catalogue), np.nan)
f_ap_irac_i[use_servs] = master_catalogue['f_servs_irac_i2'][use_servs]
f_ap_irac_i[use_swire] = master_catalogue['f_swire_irac_i2'][use_swire]

ferr_ap_irac_i = np.full(len(master_catalogue), np.nan)
ferr_ap_irac_i[use_servs] = master_catalogue['ferr_servs_irac_i2'][use_servs]
ferr_ap_irac_i[use_swire] = master_catalogue['ferr_swire_irac_i2'][use_swire]

flag_irac_i = np.full(len(master_catalogue), False, dtype=bool)
flag_irac_i[use_servs] = master_catalogue['flag_servs_irac_i2'][use_servs]
flag_irac_i[use_swire] = master_catalogue['flag_swire_irac_i2'][use_swire]

m_ap_irac_i = np.full(len(master_catalogue), np.nan)
m_ap_irac_i[use_servs] = master_catalogue['m_servs_irac_i2'][use_servs]
m_ap_irac_i[use_swire] = master_catalogue['m_swire_irac_i2'][use_swire]

merr_ap_irac_i = np.full(len(master_catalogue), np.nan)
merr_ap_irac_i[use_servs] = master_catalogue['merr_servs_irac_i2'][use_servs]
merr_ap_irac_i[use_swire] = master_catalogue['merr_swire_irac_i2'][use_swire]

master_catalogue.add_column(Column(data=f_ap_irac_i, name="f_irac_i2"))
master_catalogue.add_column(Column(data=ferr_ap_irac_i, name="ferr_irac_i2"))
master_catalogue.add_column(Column(data=m_ap_irac_i, name="m_irac_i2"))
master_catalogue.add_column(Column(data=merr_ap_irac_i, name="merr_irac_i2"))
master_catalogue.add_column(Column(data=flag_irac_i, name="flag_irac_i2"))

master_catalogue.remove_columns(['f_servs_irac_i2', 'f_swire_irac_i2', 'ferr_servs_irac_i2',
                                 'ferr_swire_irac_i2', 'm_servs_irac_i2', 'flag_servs_irac_i2', 'm_swire_irac_i2',
                                 'merr_servs_irac_i2', 'merr_swire_irac_i2', 'flag_swire_irac_i2'])

origin = np.full(len(master_catalogue), '     ', dtype='<U5')
origin[use_servs] = "SERVS"
origin[use_swire] = "SWIRE"
irac_origin.add_column(Column(data=origin, name="IRAC2_total"))
731919 sources with SERVS flux
324478 sources with SWIRE flux
175800 sources with SERVS and SWIRE flux
731159 sources for which we use SERVS
149438 sources for which we use SWIRE
In [21]:
irac_origin.write("{}/xmm-lss_irac_fluxes_origins{}.fits".format(OUT_DIR, SUFFIX), overwrite=True)

XI - Saving the catalogue¶

In [22]:
columns = ["help_id", "field", "ra", "dec", "hp_idx"]

bands = [column[5:] for column in master_catalogue.colnames if 'f_ap' in column]
for band in bands:
    columns += ["f_ap_{}".format(band), "ferr_ap_{}".format(band),
                "m_ap_{}".format(band), "merr_ap_{}".format(band),
                "f_{}".format(band), "ferr_{}".format(band),
                "m_{}".format(band), "merr_{}".format(band),
                "flag_{}".format(band)]    
    
columns += ["stellarity", "stellarity_origin", "flag_cleaned", "flag_merged", 
            "flag_gaia", "flag_optnir_obs", "flag_optnir_det" 
            ]
In [23]:
# We check for columns in the master catalogue that we will not save to disk.
print("Missing columns: {}".format(set(master_catalogue.colnames) - set(columns)))
Missing columns: {'irac_flag_merged', 'servs_stellarity_irac_i2', 'swire_stellarity_irac_i1', 'irac_dec', 'servs_flag_cleaned', 'swire_flag_cleaned', 'irac_intid', 'swire_intid', 'swire_stellarity_irac_i4', 'swire_stellarity_irac_i2', 'servs_stellarity_irac_i1', 'servs_intid', 'servs_flag_gaia', 'swire_stellarity_irac_i3', 'irac_ra', 'swire_flag_gaia'}
In [24]:
master_catalogue.write("{}/irac_merged_catalogue_xmm-lss.fits".format(TMP_DIR), overwrite=True)