Source code for pybrops.breed.prot.sel.cfg.RealSelectionConfiguration

"""
Module defining selection configurations where the decision space is real-valued in nature.
"""

from numbers import Integral
from typing import Optional
from typing import Union

import numpy
from numpy.random import Generator
from numpy.random import RandomState
from pybrops.breed.prot.sel.cfg.SampledSelectionConfigurationMixin import SampledSelectionConfigurationMixin
from pybrops.breed.prot.sel.cfg.SelectionConfiguration import SelectionConfiguration
from pybrops.core.error.error_type_numpy import check_is_ndarray
from pybrops.core.error.error_type_numpy import check_ndarray_dtype_is_floating
from pybrops.core.error.error_value_numpy import check_ndarray_ndim
from pybrops.core.random.sampling import axis_shuffle
from pybrops.core.random.sampling import outcross_shuffle
from pybrops.core.random.sampling import stochastic_universal_sampling
from pybrops.popgen.gmat.PhasedGenotypeMatrix import PhasedGenotypeMatrix


[docs] class RealSelectionConfiguration( SampledSelectionConfigurationMixin, SelectionConfiguration, ): """ docstring for RealSelectionConfiguration. """ ########################## Special Object Methods ########################## def __init__( self, ncross: Integral, nparent: Integral, nmating: Union[Integral,numpy.ndarray], nprogeny: Union[Integral,numpy.ndarray], pgmat: PhasedGenotypeMatrix, xconfig_decn: numpy.ndarray, rng: Optional[Union[Generator,RandomState]] = None, **kwargs: dict ) -> None: """ Constructor for DenseSelectionConfiguration. Parameters ---------- ncross : Integral Number of cross configurations to consider. Example: ``ncross = 10, nparent = 2`` specifies 10 two-way crosses. nparent : Integral The number of parents in a given cross configuration. Example: ``ncross = 10, nparent = 2`` specifies 10 two-way crosses. nmating : Integral, numpy.ndarray The number of times an individual cross configuration is executed. This becomes important in four-way crosses with heterozygous parents where initial F1 hybrids are unique and can affect the dihybrid composition. nprogeny : Integral, numpy.ndarray The number of progeny to derive from a mating event. pgmat : PhasedGenotypeMatrix A genome matrix containing parental candidates xconfig_decn : numpy.ndarray A decision vector of shape ``(ndecn,)`` containing indices corresponding to individuals in ``pgmat``. rng : numpy.random.Generator, numpy.random.RandomState, None Random number source. kwargs : dict Additional keyword arguments. """ # order dependent assignments! # set shape parameters first self.ncross = ncross self.nparent = nparent # mating parameters second self.nmating = nmating self.nprogeny = nprogeny # set genotypes and cross configuration third self.pgmat = pgmat self.xconfig_decn = xconfig_decn self.rng = rng # sample cross configuration self.sample_xconfig(return_xconfig=False) ############################ Object Properties ############################# @SampledSelectionConfigurationMixin.xconfig_decn.setter def xconfig_decn(self, value: numpy.ndarray) -> None: """Set decision vector for calculating the cross configuration matrix.""" check_is_ndarray(value, "xconfig_decn") check_ndarray_ndim(value, "xconfig_decn", 1) check_ndarray_dtype_is_floating(value, "xconfig_decn") self._xconfig_decn = value ############################## Object Methods ##############################
[docs] def sample_xconfig( self, return_xconfig: bool = True ) -> Union[numpy.ndarray,None]: """ Sample a cross configuration from the decision vector and set it as the ``xconfig`` value. Parameters ---------- return_xconfig : bool Whether to return the sampled ``xconfig`` matrix. Returns ------- out : numpy.ndarray, None The sampled ``xconfig`` matrix if ``return_xconfig`` is true, otherwise return nothing. """ # create sample using SUS out = stochastic_universal_sampling( numpy.arange(len(self.xconfig_decn)), self.xconfig_decn, size = (self.ncross, self.nparent), rng = self.rng ) # at least locally ensure outcrossing outcross_shuffle(out, rng = self.rng) # shuffle within mating configurations just for good measure axis_shuffle(out, 0, rng = self.rng) # set cross configuration self.xconfig = out # if we are returning xconfig, then return it, else do not return anything if return_xconfig: return out
############################## Class Methods ############################### ############################## Static Methods ##############################