Source code for cosmo_utils.mock_catalogues.abundance_matching

#! /usr/bin/env python
# -*- coding: utf-8 -*-

# Victor Calderon
# Created      : 2018-05-07
# Last Modified: 2018-05-07
from __future__ import absolute_import, division, print_function
__author__     = ['Victor Calderon']
__copyright__  = ["Copyright 2018 Victor Calderon"]
__email__      = ['victor.calderon@vanderbilt.edu']
__maintainer__ = ['Victor Calderon']
__all__        = [  "abundance_matching_f",
                    "reversed_arrays"]

# Importing modules
import numpy as np
from   scipy.interpolate import interp1d
from   cosmo_utils.utils import file_utils as fd
from   cosmo_utils.custom_exceptions import LSSUtils_Error

# Functions

# Reversed arrays
[docs]def reversed_arrays(x, y): """ Determines if arrays increase or decrease monotonically. Parameters ----------- x : `numpy.ndarray` Array containing the 1st set of values y : `numpy.ndarray` Array containing the 2nd set of values. Return ----------- mono_opt : `bool` If True, `x` increases monotonically with increasing `y`. If False, `x` decreases monotonically with increasing `y`. Raises ---------- LSSUtils_Error : Exception Program exception if input parameters are accepted """ file_msg = fd.Program_Msg(__file__) # Testing input arguments # x-array valid_types = (list, np.ndarray) if not (isinstance(x, valid_types)): msg = '{0} `x` is not a valid type!'.format(file_msg, type(x)) raise LSSUtils_Error(msg) # y-array valid_types = (list, np.ndarray) if not (isinstance(y, valid_types)): msg = '{0} `y` is not a valid type!'.format(file_msg, type(y)) raise LSSUtils_Error(msg) # x- and y-array shapes x = np.asarray(x) y = np.asarray(y) # # Checking if arrays increase or decrease monotonically x_diff = np.diff(x).sum() y_diff = np.diff(y).sum() # Monotonically increasing or decreasing if (x_diff > 0) and (y_diff > 0): mono_opt = True else: mono_opt = False return mono_opt
## Abundance Matching function
[docs]def abundance_matching_f(dict1, dict2, volume1=1., volume2=1., reverse=True, dens1_opt=False): """ Abundance matching based on 2 quantities. It assigns values from `dict2` to elements in `dict1` Parameters ----------- dict1 : python dictionary or `numpy.ndarray` Dictionary or array of 1st property. Keys : - `var` : 1st variable to be analysed - `dens` : Density array corresponding to `var` elements. Only if `dens` == True. dict2 : python dictionary dictionary or array of the 2nd property. Keys : - `var` : 2nd variable to be analyzed - `dens` : Density array corresponding to `var` elements. Given if `dens` == True. volume1 : float Corresponding volume to `dict1`. reverse : `bool`, optional Determines the relation between `var1` and `var2`. dens1_opt : `bool`, optional If True, `density` must be calculated. Options : - `True` : Density is already provided as key for `dict1`. - `False` : Density must be calculated. Returns ----------- var1_ab : `numpy.ndarray` Array of elements matching those of `dict1`, after matching with `dict2`. """ file_msg = fd.Program_Msg(__file__) # Check types of input paramenters valid_types = (list, dict, np.ndarray) # `dict1` if not (isinstance(dict1, valid_types)): msg = '{0} `dict1` ({1}) is not a valid type!'.format(file_msg, type(dict1)) # `dict2` if not (isinstance(dict2, dict)): msg = '{0} `dict2` must be a dictionary. Its type is `{1}`'.format( file_msg, type(dict2)) raise LSSUtils_Error(msg) # 2nd property var2 = np.asarray(dict2['var' ]) dens2 = np.asarray(dict2['dens']) # # `dens1_opt` if dens1_opt: # 1st Property var1 = np.asarray(dict1['var' ]) dens_1 = np.asarray(dict1['dens']) else: if (isinstance(dict1, dict)): var1 = dict1['var'] elif (isinstance(dict1, (list, np.ndarray))): var1 = dict1.copy() # # Determining relation between `var1` and `var2` mono_opt_1 = reversed_arrays(var1, var2) # Monotonically increasing if mono_opt_1: counts_1 = np.array([np.where(var1 > x)[0].size for x in var1]) + 1 else: counts_1 = np.array([np.where(var1 < x)[0].size for x in var1]) + 1 # # Determining density of 1st property dens_1 = counts_1.astype(float) / volume1 # # Interpolation for 2nd property var2_interp = interp1d(dens2, var2, bounds_error=True, assume_sorted=False) # Assigning values to property 1 var1_ab = np.asarray([var2_interp(xx) for xx in dens_1]) return var1_ab