Galaxy Cluster Catalogs
=======================
The main object for galaxy cluster catalogs is ``ClCatalog``, it has
same properties of ``astropy`` tables, with additional functionality.
.. raw:: html
Table of Contents
.. raw:: html
.. container:: toc
.. raw:: html
.. raw:: html
-
1 ClCatalog attributes
.. raw:: html
.. raw:: html
-
2 Creating a catalog
.. raw:: html
.. raw:: html
-
2.1 From columns
.. raw:: html
.. raw:: html
-
2.2 From data table
.. raw:: html
.. raw:: html
-
2.3 Create a catalog from fits files
.. raw:: html
.. raw:: html
.. raw:: html
.. raw:: html
-
3 ClCatalog necessary columns
.. raw:: html
.. raw:: html
-
3.1 Important inputs of ClCatalog
.. raw:: html
.. raw:: html
-
3.2 Reserved keyword arguments
.. raw:: html
.. raw:: html
-
3.3 Catalog lables
.. raw:: html
.. raw:: html
-
3.4 Catalog mt_input
.. raw:: html
.. raw:: html
.. raw:: html
.. raw:: html
-
4 Saving catalogs
.. raw:: html
.. raw:: html
-
5 Accessing catalog data
.. raw:: html
.. raw:: html
-
6 Inbuilt function of catalogs
.. raw:: html
.. raw:: html
-
7 Adding members to cluster catalogs
.. raw:: html
.. raw:: html
-
7.1 Read members from fits files
.. raw:: html
.. raw:: html
-
7.2 Important inputs of members catalog
.. raw:: html
.. raw:: html
-
7.3 Reserved keyword arguments
.. raw:: html
.. raw:: html
-
7.4 Saving members
.. raw:: html
.. raw:: html
-
7.5 Memory consuption
.. raw:: html
.. raw:: html
.. raw:: html
.. raw:: html
.. code:: ipython3
%load_ext autoreload
%autoreload 2
from IPython.display import HTML
ClCatalog attributes
--------------------
The ``ClCatalog`` has the following internal attributes: - ``name``:
ClCatalog name - ``data``: Table with main catalog data (ex: id, ra,
dec, z) and matching data (mt_self, mt_other, mt_cross, mt_multi_self,
mt_multi_other) - ``tags``: Dictionary that tells which are the default
columns to be used - ``mt_input``: Table containing the necessary inputs
for the match (added by Match objects) - ``size``: Number of objects in
the catalog - ``id_dict``: Dictionary of indicies given the object id -
``labels``: Labels of data columns for plots - ``members``: Members of
clusters (optional) - ``leftover_members``: Galaxies in the input
members not hosted by the cluster catalog (optional)
Creating a catalog
------------------
The catalog can be created by passing individual columns or a whole data
table. Below we show how each case can be used.
.. code:: ipython3
from clevar import ClCatalog
From columns
~~~~~~~~~~~~
To create a catalog fom columns, you have to pass the name as the
initial argument and the data columns for the table as keyword
arguments:
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
You can also pass a ``tags`` dictionary as input if you want your
catalog to have names that are not default for ``ClEvaR`` use:
.. code:: ipython3
cat = ClCatalog('cluster', ID_CLUSTER=['c1', 'c2'], M200=[1e13, 1e14],
tags={'id':'ID_CLUSTER', 'mass':'M200'})
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
Almost all keyword arguments will become columns of the catalog (see
exeptions in `Important inputs of ``ClCatalog`` <#clcat_input>`__):
.. code:: ipython3
cat = ClCatalog('test name', id=['c1', 'c2'], test_column=[1, 2],
other=[True, False], third=[None, []])
cat
.. raw:: html
test name
tags: id(id)
Radius unit: None
ClData length=2
| id | test_column | other | third | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | int64 | bool | object | object | object | object | object |
| c1 | 1 | True | None | None | None | [] | [] |
| c2 | 2 | False | [] | None | None | [] | [] |
From data table
~~~~~~~~~~~~~~~
You can also create a ``ClCatalog`` passing directly a full data table:
.. code:: ipython3
from astropy.table import Table
ap_table = Table([['c1', 'c2'],[1e13, 1e14]], names=['id', 'mass'])
cat = ClCatalog('cluster', data=ap_table)
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
You can also pass a tags dictionary as input if you want your catalog to
have names that are not default for ``ClEvaR`` use:
.. code:: ipython3
from astropy.table import Table
ap_table = Table([['c1', 'c2'],[1e13, 1e14]], names=['ID_CLUSTER', 'M200'])
cat = ClCatalog('cluster', data=ap_table, tags={'id':'ID_CLUSTER', 'mass':'M200'})
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
You can also pass a dictionary or a ``numpy`` array with names:
.. code:: ipython3
cat = ClCatalog('cluster', data={'id':['c1', 'c2'], 'mass':[1e13, 1e14]})
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
.. code:: ipython3
import numpy as np
np_table = np.array([('c1', 1e13),('c2', 1e14)],
dtype=[('id', 'U10'), ('mass', 'f4')])
cat = ClCatalog('cluster', data=np_table)
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str10 | float32 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
Create a catalog from ``fits`` files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The catalogs objects can also be read directly from file, by passing the
fits file as the first argument, the catalog name as the second, and the
``tag`` argument listing the main columns to be read:
.. code:: ipython3
cat = ClCatalog.read('../demo/cat1.fits', 'my cluster',
tags={'id':'ID', 'mass':'MASS'})
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
my cluster
tags: ID(id), MASS(mass)
Radius unit: None
ClData length=5
| ID (id) | MASS (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str3 | float64 | object | object | object | object |
| CL0 | 3.16e+13 | None | None | [] | [] |
| CL1 | 2.51e+13 | None | None | [] | [] |
| CL2 | 2.00e+13 | None | None | [] | [] |
| CL3 | 6.31e+13 | None | None | [] | [] |
| CL4 | 1.00e+14 | None | None | [] | [] |
If you want to read all columns in the ``.fits`` file, set the argument
``full=True``.
.. code:: ipython3
cat = ClCatalog.read('../demo/cat1.fits', 'my cluster', full=True,
tags={'id':'ID', 'mass':'MASS'})
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
my cluster
tags: ID(id), MASS(mass), RA(ra), DEC(dec), Z(z)
Radius unit: None
ClData length=5
| ID (id) | RA (ra) | DEC (dec) | Z (z) | MASS (mass) | RADIUS_ARCMIN | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str3 | float64 | float64 | float64 | float64 | float64 | object | object | object | object |
| CL0 | 0.0 | 0.0 | 0.2 | 3.16e+13 | 1.0 | None | None | [] | [] |
| CL1 | 0.0001 | 0.0 | 0.3 | 2.51e+13 | 1.0 | None | None | [] | [] |
| CL2 | 0.00011 | 0.0 | 0.25 | 2.00e+13 | 1.0 | None | None | [] | [] |
| CL3 | 25.0 | 0.0 | 0.4 | 6.31e+13 | 1.0 | None | None | [] | [] |
| CL4 | 20.0 | 0.0 | 0.35 | 1.00e+14 | 1.0 | None | None | [] | [] |
ClCatalog necessary columns
---------------------------
There are a few columns that will aways be present on ``ClCatalog``
objects, and are added when not provided. For instance, the matching
columns (with prefix ``mt_``):
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
All catalogs have an ``id`` column. If it is not included in the input,
one will be created:
.. code:: ipython3
cat = ClCatalog('cluster', mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
cat
.. parsed-literal::
/home/aguena/.local/lib/python3.9/site-packages/clevar-0.13.2-py3.9.egg/clevar/catalog.py:267: UserWarning: id column missing, additional one is being created.
warnings.warn(
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str1 | float64 | object | object | object | object |
| 0 | 1.00e+13 | None | None | [] | [] |
| 1 | 1.00e+14 | None | None | [] | [] |
Each cluster must have an unique ``id``. Repetitions will have an suffix
``_r#`` added:
.. code:: ipython3
cat = ClCatalog('cluster', id=['cluster', 'cluster'])
cat
.. parsed-literal::
/home/aguena/.local/lib/python3.9/site-packages/clevar-0.13.2-py3.9.egg/clevar/catalog.py:501: UserWarning: Repeated ID's in id column, adding suffix _r# to them.
warnings.warn(
.. raw:: html
cluster
tags: id(id)
Radius unit: None
ClData length=2
| id | mt_self | mt_other | mt_multi_self | mt_multi_other |
| object | object | object | object | object |
| cluster_r1 | None | None | [] | [] |
| cluster_r2 | None | None | [] | [] |
Important inputs of ``ClCatalog``\
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As shown above, ``ClCatalog`` can have any column in its main data
table. There are a few key columns that must exist (or be tagged) to be
used for matching:
- ``id`` - necessary in membership matching (must correspond to
``id_cluster`` in the cluster member catalog).
- ``ra`` (in degrees) - necessary for proxity matching.
- ``dec`` (in degrees) - necessary for proxity matching.
- ``z`` - necessary for proxity matching if used as matching criteria
(or for angular to physical convertion).
- ``mass`` (or mass proxy) - necessary for proxity matching if
``shared_member_fraction`` used as preference criteria for unique
matches (default use in membership matching).
- ``radius`` - necessary for proxity matching if used as a criteria of
matching (also requires ``radius_unit`` to be passed)
Reserved keyword arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~
There is some keyword arguments that have a fixed meaning and do not
become columns in the cluster data table:
- ``radius_unit``: can be in angular units (``radians``, ``degrees``,
``arcmin``, ``arcsec``) or physical units (``Mpc``, ``kpc``, ``pc``)
or can enven be given by mass overdensity units (``m200b``,
``m500c``) and are case insensitive. In the proximity matching the
radius is converted to angular distances (degrees).
- ``data``: Data table to be added to the catalog.
- ``tags``: Dictionary that tags the important columns in the catalog.
- ``labels``: Dictionary with labels of data columns to be used in
plots.
- ``members``: Members of clusters, see `cluster members <#memcat>`__
section for details.
- ``members_warning``: Warn if the members catalog contains galaxies
not hosted by the cluster catalog.
- ``mt_input``: Table containing the necessary inputs for the match.
This attribute is usually added during the matching process, but it
can be passed in the ``ClCatalog`` construction.
Catalog lables
~~~~~~~~~~~~~~
The catalogs have a ``label`` attribute that is used for plots. If it is
not provided as argument, a default value is assigned:
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat.labels
.. parsed-literal::
{'id': 'id_{cluster}', 'mass': 'mass_{cluster}'}
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14],
labels={'id':'cluster ID', 'mass':'cluster M_200'})
cat.labels
.. parsed-literal::
{'id': 'cluster ID', 'mass': 'cluster M_200'}
Catalog mt_input
~~~~~~~~~~~~~~~~
Here are some examples of information being added to ``mt_input`` after
the catalog creation. In the proximity matching, it will add an angular
distance and min/max redshift when ``delta_z`` is not ``None``:
.. code:: ipython3
from clevar.match import ProximityMatch
mt = ProximityMatch()
.. code:: ipython3
cat = ClCatalog('Cat',id=['c1', 'c2'], radius=[0.01, 0.02], radius_unit='radians')
mt.prep_cat_for_match(cat, delta_z=None, match_radius='cat')
cat.mt_input['ang']
.. parsed-literal::
## Prep mt_cols
* zmin|zmax set to -1|10
* ang radius from cat
.. raw:: html
<Column name='ang' dtype='float64' length=2>
| 0.5729577951308232 |
| 1.1459155902616465 |
This information is also show directly when displaing the catalog:
.. code:: ipython3
cat = ClCatalog('Cat',id=['c1', 'c2'], radius=[0.01, 0.02], radius_unit='degrees')
mt.prep_cat_for_match(cat, delta_z=None, match_radius='cat')
cat
.. parsed-literal::
## Prep mt_cols
* zmin|zmax set to -1|10
* ang radius from cat
.. raw:: html
Cat
tags: id(id), radius(radius)
Radius unit: degrees
ClData length=2
| mt_input |
|---|
| id | radius | mt_self | mt_other | mt_multi_self | mt_multi_other | zmin | zmax | ang |
| str2 | float64 | object | object | object | object | float64 | float64 | float64 |
| c1 | 0.01 | None | None | [] | [] | -1.0 | 10.0 | 0.01 |
| c2 | 0.02 | None | None | [] | [] | -1.0 | 10.0 | 0.02 |
Using physical units (requires a cosmology):
.. code:: ipython3
from clevar.cosmology import AstroPyCosmology
cosmo = AstroPyCosmology()
display(HTML('Radius in Mpc
'))
cat = ClCatalog('Cat',id=['c1', 'c2'], radius=[1, 1.5], z=[.4, .5], radius_unit='mpc')
mt.prep_cat_for_match(cat, delta_z=None, match_radius='cat', cosmo=cosmo)
display(cat)
display(HTML('Radius from M200c
'))
cat = ClCatalog('Cat', id=['c1', 'c2'], mass=[1e13, 1e14], z=[.4, .5],
tags={'radius':'mass'}, radius_unit='m200c')
mt.prep_cat_for_match(cat, delta_z=None, match_radius='cat', cosmo=cosmo)
cat['mass'].info.format = '.2e' # Format for nice display
display(cat)
.. raw:: html
Radius in Mpc
.. parsed-literal::
## Prep mt_cols
* zmin|zmax set to -1|10
* ang radius from cat
.. raw:: html
Cat
tags: id(id), radius(radius), z(z)
Radius unit: mpc
ClData length=2
| mt_input |
|---|
| id | radius | z | mt_self | mt_other | mt_multi_self | mt_multi_other | zmin | zmax | ang |
| str2 | float64 | float64 | object | object | object | object | float64 | float64 | float64 |
| c1 | 1.0 | 0.4 | None | None | [] | [] | -1.0 | 10.0 | 0.05169945411341919 |
| c2 | 1.5 | 0.5 | None | None | [] | [] | -1.0 | 10.0 | 0.06825890628285289 |
.. raw:: html
Radius from M200c
.. parsed-literal::
## Prep mt_cols
* zmin|zmax set to -1|10
* ang radius from cat
* Converting mass (m200c) ->radius
.. raw:: html
Cat
tags: id(id), mass(radius), mass(mass), z(z)
Radius unit: m200c
ClData length=2
| mt_input |
|---|
| id | mass (radius) | z | mt_self | mt_other | mt_multi_self | mt_multi_other | zmin | zmax | ang |
| str2 | float64 | float64 | object | object | object | object | float64 | float64 | float64 |
| c1 | 1.00e+13 | 0.4 | None | None | [] | [] | -1.0 | 10.0 | 0.01996895400735947 |
| c2 | 1.00e+14 | 0.5 | None | None | [] | [] | -1.0 | 10.0 | 0.036417730336072186 |
Saving catalogs
---------------
The ``ClCatalog`` object has a ``write`` inbuilt function to save them
to ``.fits`` files. This function also take the argument ``add_header``
that add the name and labels informations to those files. If the file
was saved with this argument, it can be read without the requirement of
a ``name`` argument:
.. code:: ipython3
cat = ClCatalog('cluster', ID_CLUSTER=['c1', 'c2'], M200=[1e13, 1e14],
tags={'id':'ID_CLUSTER', 'mass':'M200'},
labels={'id':'cluster ID', 'mass':'cluster M_200'},
)
cat.write('cat1_with_info.fits', overwrite=True)
.. code:: ipython3
cat_temp = cat.read_full('cat1_with_info.fits')
cat_temp['mass'].info.format = '.2e' # Format for nice display
cat_temp
.. parsed-literal::
<< ClEvar used in matching: 0.13.2 >>
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
Accessing catalog data
----------------------
The main data table of the catalog can be accessed with ``[]``
operations in the same way as ``astropy`` tables. The output is a new
``ClCatalog`` object, exept when only 1 row or column is required, then
the row/column is returned:
.. code:: ipython3
cat = ClCatalog('cluster', ID_CLUSTER=['c1', 'c2'], M200=[1e13, 1e14],
tags={'id':'ID_CLUSTER', 'mass':'M200'},
labels={'id':'cluster ID', 'mass':'cluster M_200'},
)
cat['mass'].info.format = '.2e' # Format for nice display
.. code:: ipython3
cat['ID_CLUSTER']
.. raw:: html
<Column name='ID_CLUSTER' dtype='str2' length=2>
.. code:: ipython3
cat['ID_CLUSTER', 'M200']
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
.. code:: ipython3
cat[[1, 0]]
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c2 | 1.00e+14 | None | None | [] | [] |
| c1 | 1.00e+13 | None | None | [] | [] |
.. code:: ipython3
cat[[True, False]]
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=1
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
.. code:: ipython3
cat[:1]
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=1
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
.. code:: ipython3
cat[0]
.. raw:: html
Row index=0
| ID_CLUSTER | M200 | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
An important detail is that when the catalog has tags, passing a string
that is tagged will return the tagged column:
.. code:: ipython3
cat['id']
.. raw:: html
<Column name='ID_CLUSTER' dtype='str2' length=2>
.. code:: ipython3
cat['id_cluster', 'M200']
.. raw:: html
cluster
tags: ID_CLUSTER(id), M200(mass)
Radius unit: None
ClData length=2
| ID_CLUSTER (id) | M200 (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
Inbuilt function of catalogs
----------------------------
The ``ClCatalog`` object has some inbuilt functionality to facilitate
the matching. ``ids2inds`` returns the indicies of objects given an id
list. Other functions are related to footprint computations, see
footprint.ipynb for information on those.
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
display(HTML('Catalog
'))
display(cat)
display(HTML('Catalog sorted by id list
'))
inds = cat.ids2inds(['c2', 'c1'])
display(cat[inds])
.. raw:: html
Catalog
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
.. raw:: html
Catalog sorted by id list
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c2 | 1.00e+14 | None | None | [] | [] |
| c1 | 1.00e+13 | None | None | [] | [] |
Adding members to cluster catalogs
----------------------------------
The members are used as an internal table like object of ``ClCatalog``,
accessed by ``.members``. This object have the following attributes: -
``name``: ClCatalog name - ``data``: Table with main catalog data (ex:
id, id_cluster, ra, dec, z) - ``size``: Number of objects in the catalog
- ``id_dict``: Dictionary of indicies given the object id - ``labels``:
Labels of data columns for plots - ``id_dict_list``: Dictionary of
indicies given the object id, retiruning lists to account members with
repeated ``id``.
The members can be added to the cluster object using the ``add_members``
function. It has a similar instanciating format of a ``ClCatalog``
object, where the columns are added by keyword arguments (the key
``id_cluster`` is always necessary and must correspond to ``id`` in the
main cluster catalog):
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
cat.add_members(id=['m1', 'm2', 'm3'], id_cluster=['c1', 'c2', 'c1'])
display(cat)
display(cat.members)
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
.. raw:: html
members
tags: id(id), id_cluster(id_cluster)
ClData length=3
| id | id_cluster | ind_cl |
| str2 | str2 | int64 |
| m1 | c1 | 0 |
| m2 | c2 | 1 |
| m3 | c1 | 0 |
The same can be done using ``tags``:
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1', 'c2'], mass=[1e13, 1e14])
cat['mass'].info.format = '.2e' # Format for nice display
cat.add_members(
ID=['m1', 'm2', 'm3'], IDCL=['c1', 'c2', 'c1'],
tags={'id':'ID', 'id_cluster':'IDCL'})
display(cat)
display(cat.members)
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=2
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
| c2 | 1.00e+14 | None | None | [] | [] |
.. raw:: html
members
tags: ID(id), IDCL(id_cluster)
ClData length=3
| ID (id) | IDCL (id_cluster) | ind_cl |
| str2 | str2 | int64 |
| m1 | c1 | 0 |
| m2 | c2 | 1 |
| m3 | c1 | 0 |
Read members from ``fits`` files
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The catalogs objects can also be read directly from file, by passing the
fits file as the first argument, the catalog name as the second, and the
names of the columns in the fits files as keyword arguments:
.. code:: ipython3
cat = ClCatalog.read(
'../demo/cat1.fits', 'my cluster',
tags={'id':'ID', 'mass':'MASS'})
cat.read_members(
'../demo/cat1_mem.fits',
tags={'id':'ID', 'id_cluster':'ID_CLUSTER'})
cat['mass'].info.format = '.2e' # Format for nice display
display(cat)
display(cat.members)
.. raw:: html
my cluster
tags: ID(id), MASS(mass)
Radius unit: None
ClData length=5
| ID (id) | MASS (mass) | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str3 | float64 | object | object | object | object |
| CL0 | 3.16e+13 | None | None | [] | [] |
| CL1 | 2.51e+13 | None | None | [] | [] |
| CL2 | 2.00e+13 | None | None | [] | [] |
| CL3 | 6.31e+13 | None | None | [] | [] |
| CL4 | 1.00e+14 | None | None | [] | [] |
.. raw:: html
members
tags: ID(id), ID_CLUSTER(id_cluster)
ClData length=15
| ID (id) | ID_CLUSTER (id_cluster) | ind_cl |
| str5 | str3 | int64 |
| MEM0 | CL0 | 0 |
| MEM1 | CL0 | 0 |
| MEM2 | CL0 | 0 |
| MEM3 | CL0 | 0 |
| MEM4 | CL0 | 0 |
| MEM5 | CL1 | 1 |
| MEM6 | CL1 | 1 |
| MEM7 | CL1 | 1 |
| MEM8 | CL1 | 1 |
| MEM9 | CL2 | 2 |
| MEM10 | CL2 | 2 |
| MEM11 | CL2 | 2 |
| MEM12 | CL3 | 3 |
| MEM13 | CL3 | 3 |
| MEM14 | CL4 | 4 |
Again, passing ``full=True`` will read all columns in the file:
.. code:: ipython3
cat = ClCatalog.read(
'../demo/cat1.fits', 'my cluster',
tags={'id':'ID', 'mass':'MASS'}, full=True)
cat.read_members(
'../demo/cat1_mem.fits',
tags={'id':'ID', 'id_cluster':'ID_CLUSTER'}, full=True)
cat['mass'].info.format = '.2e' # Format for nice display
display(cat)
display(cat.members)
.. raw:: html
my cluster
tags: ID(id), MASS(mass), RA(ra), DEC(dec), Z(z)
Radius unit: None
ClData length=5
| ID (id) | RA (ra) | DEC (dec) | Z (z) | MASS (mass) | RADIUS_ARCMIN | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str3 | float64 | float64 | float64 | float64 | float64 | object | object | object | object |
| CL0 | 0.0 | 0.0 | 0.2 | 3.16e+13 | 1.0 | None | None | [] | [] |
| CL1 | 0.0001 | 0.0 | 0.3 | 2.51e+13 | 1.0 | None | None | [] | [] |
| CL2 | 0.00011 | 0.0 | 0.25 | 2.00e+13 | 1.0 | None | None | [] | [] |
| CL3 | 25.0 | 0.0 | 0.4 | 6.31e+13 | 1.0 | None | None | [] | [] |
| CL4 | 20.0 | 0.0 | 0.35 | 1.00e+14 | 1.0 | None | None | [] | [] |
.. raw:: html
members
tags: ID(id), ID_CLUSTER(id_cluster), RA(ra), DEC(dec), Z(z)
ClData length=15
| ID (id) | ID_CLUSTER (id_cluster) | RA (ra) | DEC (dec) | Z (z) | ind_cl |
| str5 | str3 | float64 | float64 | float64 | int64 |
| MEM0 | CL0 | 0.0 | 0.0 | 0.2 | 0 |
| MEM1 | CL0 | 1e-05 | 1e-05 | 0.2 | 0 |
| MEM2 | CL0 | 2e-05 | 2e-05 | 0.2 | 0 |
| MEM3 | CL0 | 3.0000000000000004e-05 | 3.0000000000000004e-05 | 0.2 | 0 |
| MEM4 | CL0 | 4e-05 | 4e-05 | 0.2 | 0 |
| MEM5 | CL1 | 0.0001 | 0.0 | 0.3 | 1 |
| MEM6 | CL1 | 0.00011 | 1e-05 | 0.3 | 1 |
| MEM7 | CL1 | 0.00012 | 2e-05 | 0.3 | 1 |
| MEM8 | CL1 | 0.00013000000000000002 | 3.0000000000000004e-05 | 0.3 | 1 |
| MEM9 | CL2 | 0.00011 | 0.0 | 0.25 | 2 |
| MEM10 | CL2 | 0.00012 | 1e-05 | 0.25 | 2 |
| MEM11 | CL2 | 0.00013000000000000002 | 2e-05 | 0.25 | 2 |
| MEM12 | CL3 | 25.0 | 0.0 | 0.4 | 3 |
| MEM13 | CL3 | 25.00001 | 1e-05 | 0.4 | 3 |
| MEM14 | CL4 | 20.0 | 0.0 | 0.35 | 4 |
Important inputs of members catalog
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
There are a few key columns these catalogs must have to be used for
matching:
- ``id`` - necessary in membership matching of members.
- ``id_cluster`` - always necessary and must correspond to ``id`` in
the main cluster catalog.
- ``ra`` (in degrees) - necessary for proxity matching of members.
- ``dec`` (in degrees) - necessary for proxity matching of members.
- ``pmem`` - Probability of the galaxy being a member, must be [0, 1].
If not provided, it will assing 1 for all members.
Reserved keyword arguments
~~~~~~~~~~~~~~~~~~~~~~~~~~
There are three keyword arguments with specific uses:
- ``data``: Data table to be added to the catalog.
- ``tags``: Dictionary that tags the important columns in the catalog.
- ``labels``: Dictionary with labels of data columns to be used in
plots.
- ``members_consistency``: Require that all input members belong to
this cluster catalog.
- ``members_warning``: Raise warning if members are do not belong to
this cluster catalog, and save them in leftover_members attribute.
- ``members_catalog``: Members catalog if avaliable, mostly for
internal use.
When ``members_consistency=True``, only galaxies hosted by the cluster
catalog is kept. If ``members_warning=True``, a warning is raised and
the clusters not hosted are stored in ``leftover_members``:
.. code:: ipython3
cat = ClCatalog('cluster', id=['c1'], mass=[1e13])
cat['mass'].info.format = '.2e' # Format for nice display
cat.add_members(id=['m1', 'm2', 'm3'], id_cluster=['c1', 'c2', 'c1'])
display(cat)
display(cat.members)
display(cat.leftover_members)
.. parsed-literal::
/home/aguena/.local/lib/python3.9/site-packages/clevar-0.13.2-py3.9.egg/clevar/catalog.py:1032: UserWarning: Some galaxies were not members of the cluster catalog. They are stored in leftover_members attribute.
warnings.warn(
.. raw:: html
cluster
tags: id(id), mass(mass)
Radius unit: None
ClData length=1
| id | mass | mt_self | mt_other | mt_multi_self | mt_multi_other |
| str2 | float64 | object | object | object | object |
| c1 | 1.00e+13 | None | None | [] | [] |
.. raw:: html
members
tags: id(id), id_cluster(id_cluster)
ClData length=2
| id | id_cluster | ind_cl |
| str2 | str2 | int64 |
| m1 | c1 | 0 |
| m3 | c1 | 0 |
.. raw:: html
leftover members
tags: id(id), id_cluster(id_cluster)
ClData length=1
| id | id_cluster | ind_cl |
| str2 | str2 | int64 |
| m2 | c2 | -1 |
Saving members
~~~~~~~~~~~~~~
The ``member`` object has a ``write`` inbuilt function to save them to
``.fits`` files. This function also take the argument ``add_header``
that add the name and labels informations to those files. If the file
was saved with this argument, it can be read without the requirement of
a ``name`` argument:
.. code:: ipython3
cat.members.write('mem1_with_info.fits', overwrite=True)
Memory consuption
~~~~~~~~~~~~~~~~~
IMPORTANT! The member catalogs are usually hundreds of times larger than
the cluster catalogs. Therefore it is advised not to add it unless you
are using it for a specific goal (ex: membership matching). This catalog
also can lead to memory overload and makes the other functions slower.
There are two options to handle this, you can either pass a member free
version of the catalog or remove the members altogether. To use the
member free version of the catalog, use the ``raw`` function:
.. code:: ipython3
cat_raw = cat.raw()
print("Original:")
display(cat.members)
print("Raw:")
display(cat.raw().members)
.. parsed-literal::
Original:
.. raw:: html
members
tags: id(id), id_cluster(id_cluster)
ClData length=2
| id | id_cluster | ind_cl |
| str2 | str2 | int64 |
| m1 | c1 | 0 |
| m3 | c1 | 0 |
.. parsed-literal::
Raw:
.. parsed-literal::
None
To remove the members from the cluster catalog, use the
``remove_members`` function:
.. code:: ipython3
cat.remove_members()
print(cat.members, cat.leftover_members)
.. parsed-literal::
None None