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

"""
Module defining selection configurations where the decision space is subset 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.SelectionConfiguration import SelectionConfiguration
from pybrops.breed.prot.sel.cfg.SampledSelectionConfigurationMixin import SampledSelectionConfigurationMixin
from pybrops.core.error.error_type_numpy import check_is_ndarray
from pybrops.core.error.error_type_numpy import check_ndarray_dtype_is_integer
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 tiled_choice
from pybrops.popgen.gmat.PhasedGenotypeMatrix import PhasedGenotypeMatrix


[docs] class SubsetSelectionConfiguration( SampledSelectionConfigurationMixin, SelectionConfiguration, ): """ docstring for SubsetSelectionConfiguration. """ ########################## 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_integer(value, "xconfig_decn") self._xconfig_decn = value ############################## Object Methods ##############################
[docs] def sample_xconfig( self, return_xconfig: bool = False ) -> 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 out = tiled_choice( self.xconfig_decn, size = (self.ncross, self.nparent), replace = False, 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 ##############################