astropy:docs

Source code for halotools.hod_factory

# -*- coding: utf-8 -*-
"""

Module containing the primary class used to build 
composite HOD models from a set of components. 

"""

__all__ = ['HodModel']

import numpy as np

[docs]class HodModel(object): """ Composite HOD model object. The primary methods are for assigning the mean occupation of a galaxy population to a halo, the intra-halo radial profile of that population, and the accompanying methods to generate Monte Carlo realizations of those methods. All behavior is derived from external classes passed to the constructor via component_model_dict, which serves as a set of instructions for how the composite model is to be built from the components. """ def __init__(self, halo_prof_model, component_model_dict): """ The methods of this class derives their behavior from other, external classes, passed in the form of the component_model_dict, a dictionary whose keys are the galaxy types found in the halos, e.g., 'centrals', 'satellites', 'orphans', etc. The values of the component_model_dict are themselves dictionaries whose keys are strings specifying the type of model being passed, e.g., 'occupation_model', and values are instances of that type of model. The component_model_dict dictionary is built by the hod_designer interface. The input halo_prof_model is an instance of the class governing the assumed profile of the underlying halos. """ # Bind the model-making instructions to the composite model self.halo_prof_model = halo_prof_model self.component_model_dict = component_model_dict # Create attributes for galaxy types and their occupation bounds self.gal_types = self.component_model_dict.keys() self.occupation_bound = {} for gal_type in self.gal_types: self.occupation_bound[gal_type] = ( self.component_model_dict[gal_type]['occupation_model'].upper_bound) # Create strings used by the MC methods to access the appropriate columns of the # halo table passed by the mock factory # Currently, all behaviors of all galaxy types must use # the same primary (and, if applicable, secondary) halo property. # Also create a dictionary for which gal_types, and which behaviors, # are assembly biased. self._create_haloprop_keys() # The details of how parameters are passed back and forth still need to be worked out self.parameter_dict = ( self.retrieve_all_inherited_parameters( self.component_model_dict) ) self.publications = [] # dummy array for now self.additional_haloprops = []
[docs] def mean_occupation(self,gal_type,*args): """ Method supplying the mean abundance of gal_type galaxies. The behavior of this method is inherited from one of the component models. """ self.test_component_consistency(gal_type,'occupation_model') # For galaxies of type gal_type, the behavior of this method # will be set by the inherited occupation_model object occupation_model = self.component_model_dict[gal_type]['occupation_model'] inherited_method = occupation_model.mean_occupation output_occupation = self.retrieve_component_behavior(inherited_method,args) return output_occupation
[docs] def mc_occupation(self,gal_type,halo_table): """ Method providing a Monte Carlo realization of the mean occupation. The behavior of this method is inherited from one of the component models. """ # Retrieve the appropriate columns from halo_table input_haloprops = [halo_table[self.prim_haloprop_key]] assembias_occupation = ((gal_type in self.sec_haloprop_key_dict.keys()) & ('occupation_model' in self.sec_haloprop_key_dict[gal_type]) ) if assembias_occupation == True: input_haloprops.extend([halo_table[self.sec_haloprop_key]]) self.test_component_consistency(gal_type,'occupation_model') occupation_model = self.component_model_dict[gal_type]['occupation_model'] inherited_method = occupation_model.mc_occupation output_mc_realization = self.retrieve_component_behavior(inherited_method,input_haloprops) return output_mc_realization
[docs] def mean_profile_parameters(self,gal_type,*args): """ Method returning the mean value of the parameters governing the radial profile of gal_type galaxies. The behavior of this method is inherited from one of the component models. """ self.test_component_consistency(gal_type,'profile_model') profile_model = self.component_model_dict[gal_type]['profile_model'] inherited_method = profile_model.mean_profile_parameters output_profiles = self.retrieve_component_behavior(inherited_method,args) return output_profiles
[docs] def mc_coords(self,gal_type,*args): """ Method returning a Monte Carlo realization of the radial profile. The behavior of this method is inherited from one of the component models. """ self.test_component_consistency(gal_type,'profile_model') profile_model = self.component_model_dict[gal_type]['profile_model'] inherited_method = profile_model.mc_coords output_mc_realization = self.retrieve_component_behavior(inherited_method,args) return output_mc_realization
[docs] def test_component_consistency(self,gal_type,component_key): """ Simple tests to run to make sure that the desired behavior can be found in the component model. """ if gal_type not in self.gal_types: raise KeyError("Input gal_type is not supported " "by any of the components of this composite model") if component_key not in self.component_model_dict[gal_type]: raise KeyError("Could not find method to retrieve " " inherited behavior from the provided component model")
[docs] def retrieve_component_behavior(self,inherited_method,*args): """ Wrapper method whose purpose is solely to call the component model methods using the correct number of arguments. Purely for user convenience. """ if len(args)==1: prim_haloprop = args[0] output = inherited_method(prim_haloprop) elif len(args)==2: prim_haloprop, sec_haloprop = args[0], args[1] output = inherited_method(prim_haloprop,sec_haloprop) else: raise TypeError("Only one or two halo property inputs are supported by " "mean_occupation method") return output
[docs] def retrieve_all_inherited_parameters(self,component_model_dict): output_dict = {} # Loop over all galaxy types in the composite model for gal_type, model_list in component_model_dict.iteritems(): # For each galaxy type, loop over its features for model_feature in model_list: # Check to make sure we're not duplicating any dictionary keys self.test_model_redundancy( output_dict,model_feature.parameter_dict) output_dict = dict( model_feature.parameter_dict.items() + output_dict.items()) return output_dict
[docs] def test_model_redundancy(self,existing_composite_model,new_model_component): """ Check whether the new_model_component dictionary contains keys that duplicate the keys in the existing_composite_model dictionary. """ intersection = list(set(existing_composite_model) & set(new_model_component)) print(set(existing_composite_model),set(new_model_component)) if intersection != []: raise KeyError("New component model contains duplicate parameter keys")
def _create_haloprop_keys(self): # Create attribute for primary halo property used by all component models # Forced to be the same property defining the underlying halo profile # seen by all galaxy types self.prim_haloprop_key = self.halo_prof_model.prim_haloprop_key # If any of the galaxy types have any assembly-biased component behavior, # create a second attribute called sec_haloprop_key. # Force the secondary halo property to be the same for all behaviors # of all galaxy types. May wish to relax this requirement later. sec_haloprop_key_dict = {} for gal_type in self.gal_types: temp_dict = {} for behavior_key, behavior_model in self.component_model_dict[gal_type].iteritems(): if hasattr(behavior_model,'sec_haloprop_key'): temp_dict[behavior_key] = behavior_model.sec_haloprop_key if len(set(temp_dict.values())) > 1: raise KeyError("If implementing assembly bias for a particular gal_type, " "must use the same secondary halo property " " for all behaviors of this galaxy type") elif len(set(temp_dict.values())) == 1: sec_haloprop_key_dict[gal_type] = temp_dict if len(set(sec_haloprop_key_dict.values())) > 1: raise KeyError("If implementing assembly bias in a composite model, " " must use same secondary halo property for all galaxy types") elif len(set(sec_haloprop_key_dict.values())) == 1: self.sec_haloprop_key = sec_haloprop_key_dict.values()[0] self.sec_haloprop_key_dict = sec_haloprop_key_dict

Page Contents