<commit_before>from copy import deepcopy
import numpy as np
import json
from bsfh import priors
from bsfh.datautils import logify_data, norm_spectrum

param_template = {'name':'', 'N':1, 'isfree': False,
                  'init':0.0, 'units':'',
                  'prior_function_name': None, 'prior_args': None}

class ProspectrParams(object):
    """
    :param config_list:
        A list of ``model parameters``.
    
    """
    # information about each parameter stored as a list
    #config_list = [] 
    # information about each parameter as a dictionary keyed by
    # parameter name for easy access
    #_config_dict = {}
    # Model parameter state, keyed by parameter name
    #params = {}
    # Mapping from parameter name to index in the theta vector
    #theta_index = {}
    # the initial theta vector
    #theta_init = np.array([])

    # Information about the fiting parameters, filenames, fitting and
    # configure options, runtime variables, etc.
    #run_params = {}
    #obs = {}
    
    def __init__(self, config_list, verbose=True):
        self.init_config_list = config_list
        self.config_list = config_list
        self.configure()
        self.verbose = verbose

    def configure(self, reset=False, **kwargs):
        """
        Use the parameter config_list to generate a theta_index
        mapping, and propogate the initial parameters into the params
        state dictionary, and store the intital theta vector implied
        by the config dictionary.

        :param kwargs:
            Keyword parameters can be used to override or add to the
            initial parameter values specified in  config_list
        """
        self._has_parameter_dependencies = False
        if (not hasattr(self, 'params')) or reset:
            self.params = {}
        self._config_dict = plist_to_pdict(self.config_list)
        self.map_theta()
        # propogate initial parameter values from the configure dictionary
        for par, info in self._config_dict.iteritems():
            self.params[par] = np.atleast_1d(info['init'])
            if info.get('depends_on', None) is not None:
                self._has_parameter_dependencies = True
        # propogate user supplied values, overriding the configure
        for k,v in kwargs.iteritems():
            self.params[k] = np.atleast_1d(v)
        # store these initial values
        self.initial_theta = self.theta.copy()#self.rectify_theta((self.theta.copy()))
        
    def map_theta(self):
        """
        Construct the mapping from parameter name to the index in the
        theta vector corresponding to the first element of that
        parameter.
        """
        self.theta_index = {}
        count = 0
        for par in self.free_params:
            self.theta_index[par] = (count,
                                     count + self._config_dict[par]['N'])
            count += self._config_dict[par]['N']
        self.ndim = count

    def set_parameters(self, theta):
        """
        Propagate theta into the model parameters dictionary.

        :param theta:
            A theta parameter vector containing the desired
            parameters.  ndarray of shape (ndim,)
        """
        assert len(theta) == self.ndim
        for k, v in self.theta_index.iteritems():
            start, end = v
            self.params[k] = np.atleast_1d(theta[start:end])
        self.propagate_parameter_dependencies()

    def prior_product(self, theta):
        return self.simple_prior_product(theta)
            
    def simple_prior_product(self, theta):
        """
        Return a scalar which is the ln of the product of the prior
        probabilities for each element of theta.  Requires that the
        prior functions are defined in the theta descriptor.

        :param theta:
            Iterable containing the free model parameter values.

        :returns lnp_prior:
            The log of the product of the prior probabilities for
            these parameter values.
        """
        lnp_prior = 0
        for k, v in self.theta_index.iteritems():
            start, end = v
            #print(k)
            lnp_prior += np.sum(self._config_dict[k]['prior_function']
                                (theta[start:end], **self._config_dict[k]['prior_args']))
        return lnp_prior
            
    def rescale_parameter(self, par, func):
        ind = [p['name'] for p in self.config_list].index(par)
        self.config_list[ind]['init'] = func(self.config_list[ind]['init'])
        for k,v in self.config_list[ind]['prior_args'].iteritems():
            self.config_list[ind]['prior_args'][k] = func(v)

    def propagate_parameter_dependencies(self):
        """ Propogate any parameter dependecies. That is, for
        parameters whose value depends on another parameter, calculate
        those values and store them.
        """
        if self._has_parameter_dependencies is False:
            return
        for p, info in self._config_dict.iteritems():
            if 'depends_on' in info:
                value = (info['depends_on'](**self.params)
                self.params[p] = np.atleast_1d(value)

    def rectify_theta(self, theta):
        tiny_number = 1e-10
        zero = (theta == 0)
        theta[zero] = tiny_number
        return theta
    
    @property
    def theta(self):
        """The current value of the theta vector, pulled from the
        params state dictionary.
        """
        theta = np.zeros(self.ndim)
        for k, v in self.theta_index.iteritems():
            start, end = v
            theta[start:end] = self.params[k]
        return theta

    @property
    def free_params(self):
        """A list of the free model parameters.
        """
        return [k['name'] for k in pdict_to_plist(self.config_list)
                if k['isfree']]

    @property
    def fixed_params(self):
        """A list of the fixed model parameters that are specified in<commit_msg>fix dumb typo<commit_after>from copy import deepcopy
import numpy as np
import json
from bsfh import priors
from bsfh.datautils import logify_data, norm_spectrum

param_template = {'name':'', 'N':1, 'isfree': False,
                  'init':0.0, 'units':'',
                  'prior_function_name': None, 'prior_args': None}

class ProspectrParams(object):
    """
    :param config_list:
        A list of ``model parameters``.
    
    """
    # information about each parameter stored as a list
    #config_list = [] 
    # information about each parameter as a dictionary keyed by
    # parameter name for easy access
    #_config_dict = {}
    # Model parameter state, keyed by parameter name
    #params = {}
    # Mapping from parameter name to index in the theta vector
    #theta_index = {}
    # the initial theta vector
    #theta_init = np.array([])

    # Information about the fiting parameters, filenames, fitting and
    # configure options, runtime variables, etc.
    #run_params = {}
    #obs = {}
    
    def __init__(self, config_list, verbose=True):
        self.init_config_list = config_list
        self.config_list = config_list
        self.configure()
        self.verbose = verbose

    def configure(self, reset=False, **kwargs):
        """
        Use the parameter config_list to generate a theta_index
        mapping, and propogate the initial parameters into the params
        state dictionary, and store the intital theta vector implied
        by the config dictionary.

        :param kwargs:
            Keyword parameters can be used to override or add to the
            initial parameter values specified in  config_list
        """
        self._has_parameter_dependencies = False
        if (not hasattr(self, 'params')) or reset:
            self.params = {}
        self._config_dict = plist_to_pdict(self.config_list)
        self.map_theta()
        # propogate initial parameter values from the configure dictionary
        for par, info in self._config_dict.iteritems():
            self.params[par] = np.atleast_1d(info['init'])
            if info.get('depends_on', None) is not None:
                self._has_parameter_dependencies = True
        # propogate user supplied values, overriding the configure
        for k,v in kwargs.iteritems():
            self.params[k] = np.atleast_1d(v)
        # store these initial values
        self.initial_theta = self.theta.copy()#self.rectify_theta((self.theta.copy()))
        
    def map_theta(self):
        """
        Construct the mapping from parameter name to the index in the
        theta vector corresponding to the first element of that
        parameter.
        """
        self.theta_index = {}
        count = 0
        for par in self.free_params:
            self.theta_index[par] = (count,
                                     count + self._config_dict[par]['N'])
            count += self._config_dict[par]['N']
        self.ndim = count

    def set_parameters(self, theta):
        """
        Propagate theta into the model parameters dictionary.

        :param theta:
            A theta parameter vector containing the desired
            parameters.  ndarray of shape (ndim,)
        """
        assert len(theta) == self.ndim
        for k, v in self.theta_index.iteritems():
            start, end = v
            self.params[k] = np.atleast_1d(theta[start:end])
        self.propagate_parameter_dependencies()

    def prior_product(self, theta):
        return self.simple_prior_product(theta)
            
    def simple_prior_product(self, theta):
        """
        Return a scalar which is the ln of the product of the prior
        probabilities for each element of theta.  Requires that the
        prior functions are defined in the theta descriptor.

        :param theta:
            Iterable containing the free model parameter values.

        :returns lnp_prior:
            The log of the product of the prior probabilities for
            these parameter values.
        """
        lnp_prior = 0
        for k, v in self.theta_index.iteritems():
            start, end = v
            #print(k)
            lnp_prior += np.sum(self._config_dict[k]['prior_function']
                                (theta[start:end], **self._config_dict[k]['prior_args']))
        return lnp_prior
            
    def rescale_parameter(self, par, func):
        ind = [p['name'] for p in self.config_list].index(par)
        self.config_list[ind]['init'] = func(self.config_list[ind]['init'])
        for k,v in self.config_list[ind]['prior_args'].iteritems():
            self.config_list[ind]['prior_args'][k] = func(v)

    def propagate_parameter_dependencies(self):
        """ Propogate any parameter dependecies. That is, for
        parameters whose value depends on another parameter, calculate
        those values and store them.
        """
        if self._has_parameter_dependencies is False:
            return
        for p, info in self._config_dict.iteritems():
            if 'depends_on' in info:
                value = info['depends_on'](**self.params)
                self.params[p] = np.atleast_1d(value)

    def rectify_theta(self, theta):
        tiny_number = 1e-10
        zero = (theta == 0)
        theta[zero] = tiny_number
        return theta
    
    @property
    def theta(self):
        """The current value of the theta vector, pulled from the
        params state dictionary.
        """
        theta = np.zeros(self.ndim)
        for k, v in self.theta_index.iteritems():
            start, end = v
            theta[start:end] = self.params[k]
        return theta

    @property
    def free_params(self):
        """A list of the free model parameters.
        """
        return [k['name'] for k in pdict_to_plist(self.config_list)
                if k['isfree']]

    @property
    def fixed_params(self):
        """A list of the fixed model parameters that are specified in
{'fraction_non_alphanumeric': 0.09074120708469739, 'fraction_numerical': 0.002182489717115756, 'mean_word_length': 2.1627289620387575, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6494162', 'n_tokens_mistral': 3341, 'n_tokens_neox': 3180, 'n_words': 1017}