slim.simulation.lice_population module

This module provides two important classes:

The first is a numba-optimised Dictionary-style container for gene frequency. Because of that, the API has been geared towards efficiency over “pythonicity”.

For convenience, use the following snippet to create empty distribution with a default per-allele distribution

>>> cfg = Config(...)
>>> empty_geno = empty_geno_from_cfg(cfg)
>>> nonempty_geno = empty_geno.normalise_to(100)

The second class is a wrapper to manage multiple GenoDistrib arranged by life stage.


alias of str

class slim.simulation.lice_population.GenoDistrib(default_probs: numpy.ndarray, _no_init: bool = False)

Bases: object

An enriched Dictionary-style container of a statistical population of sea lice arranged by gene.

The interpretation is the following: a genotype is made of distinct genes, each of them appearing in at most 3 different modes: recessive (e.g. a), homozygous dominant (e.g. A), heterozygous dominant (e.g. Aa).

The value of this distribution at a specific allele is the number of lice that possess that trait. Note that a magnitude change in one allele will result in a change in others.

Assuming all genes are i.i.d. we allocate O(k) space.

Creates an empty GenoDistrib. An “empty” genotype distribution is a distribution with zero lice but preallocated data structures, therefore both k and the default ratios are required in advance.

  • num_alleles – the number of alleles to generate. Please keep this value below 5

  • default_probs – if the number of lice for a bucket is 0, use this array as a “normalised” probability

  • _no_init – (ADVANCED) if provided do not initialise the store matrix with 0.


Add operation between GenoDistrib and GenoDistrib

add_to_scalar(other: float)

Add to scalar.

static batch_sum(batches: List[GenoDistrib]) GenoDistrib

Calculate the sum of multiple GenoDistrib instances. This function is a bit faster than manually invoking a folding operation due to reduced overhead.

The caller must ensure the list of batches is non-empty and homogeneous. The default rates used for the generation are the same of the first element.


batches – either a list of distribution or a list of dictionaries (useful for pandas)


a GenoDistrib


Creates a deep copy of this distribution. As a result, modifications in the original distribution will not affect the new copy.


a deep copy of the distribution.

equals(other: GenoDistrib)

Overloaded eq operator

equals_dict(other: Dict[str, float])

Overloaded eq operator for dicts. Note: this is mainly meant for testing. Be sure to test without the JIT on, otherwise you may have to manually allocate a numba dict.

property gross: float

the gross population, i.e. the total number of lice irrespectively of the genotype


Inplace add operation between GenoDistrib and GenoDistrib


other – the GenoDistrib addend

iadd_scalar(other: float)

Inplace add operation between GenoDstrib and a scalar.


other: the scalar addend.

is_positive() bool

True if all the bins are positive.


:returns the list of keys

mul(other: GenoDistrib) GenoDistrib

Multiply a distribution by another distribution.


other – a similar distribution


the new genotype distribution

mul_by_scalar(other: float) GenoDistrib

Multiply a distribution by a scalar.

The multiplication by a scalar will multiply each bin by the scalar. If the new sum is expected to be an integer a rounding step is applied.


other – a scalar


the new genotype distribution

mutate(mutations: int)

Mutate the genotype distribution in-place.

There are only three directions: R->ID, ID->D, ID->R, D->ID. Note that R->D or D->R are impossible via a single mutation, and the probability of a double mutation is low enough to be ignored. Self-mutations are ignored.

The function uses a best-effort algorithm to derive mutations.


mutations – the number of mutations to perform

normalise_to(population: float)

Transform the distribution so that the overall sum changes to the given number but the ratios are preserved. Note: this operation yields undefined behaviour if the genotype distribution is 0


population – the new population


the new distribution

property num_genes: int

the number of genes in the distribution

set(population: float)

This is the inplace version of normalise_to().


population – the new population

setcounts(counts: numpy.ndarray)
sub(other: GenoDistrib) GenoDistrib

Overload sub operation

to_json_dict() Dict[str, float]

a JSON-friendly python representation of the different genotypes


a reference of the store


These are used when GenoDistrib is not available

alias of Dict[str, float]


The type of a serialised (JSON-style) representation of a GenoDistrib

alias of Dict[str, float]

class slim.simulation.lice_population.GenoTreatmentValue(mortality_rate, susceptible_stages)

Bases: tuple

Create new instance of GenoTreatmentValue(mortality_rate, susceptible_stages)

mortality_rate: float

Alias for field number 0

susceptible_stages: List[str]

Alias for field number 1


The type of a dictionary

alias of Dict[str, int]

class slim.simulation.lice_population.LicePopulation(geno_data: Dict[str, GenoDistrib], generic_ratios: Dict[str, float], busy_dam_waiting_time: float)

Bases: object

Wrapper to keep the global population and genotype information updated.

This class provides both a gross-based and a geno-based view of a lice population. It also manages busy dam distributions when mating is involved.

The stages population can be accessed via either dictionary access (gross) or via the geno_by_lifestage attribute (detailed).

Additionally we provide two “virtual” stages (“L5f_busy” and “L5f_free”) as read-only convenience accessors in place of the verbose busy_dams and available_dams attributes.

Note: this class is meant to describe the lice population per cage, but it is well known that the mobile stages are not technically confined to a single cage.

  • geno_data – the default genetic ratios

  • generic_ratios – a config to use

  • busy_dam_waiting_time – the average pregnancy period for dams (in days)

add_busy_dams_batch(num_dams: int)
as_dict() Dict[str, int]
property available_dams: GenoDistrib
property busy_dams: GenoDistrib

Returns the proportion of working busy dams.


a deep copy of the distribution.

static get_empty_geno_distrib(cfg: Config) GenoLifeStageDistrib
infectious_stages = ['L3', 'L4', 'L5f', 'L5m']
lice_stages = ['L1', 'L2', 'L3', 'L4', 'L5f', 'L5m']
lice_stages_bio_labels = {'L1': 'R', 'L2': 'CO', 'L3': 'CH', 'L4': 'PA', 'L5f': 'AF', 'L5m': 'AM'}
lice_stages_bio_long_names = {'L1': 'Recruitment', 'L2': 'Copepopid', 'L3': 'Chalimus', 'L4': 'Preadult', 'L5f': 'Adult Female', 'L5m': 'Adult Male'}
pathogenic_stages = ['L4', 'L5f', 'L5m']
to_json_dict() Dict[str, float]

a list of GenoDistrib sorted by stage


alias of str

slim.simulation.lice_population.from_dict(p: Dict[str, float]) GenoDistrib

Generate a GenoDistrib from a dictionary.

The default rates will be assumed to be the same as the current population arranged by gene.

Useful for testing and quick prototyping.

slim.simulation.lice_population.from_ratios(p: Union[Dict[str, float], numpy.ndarray], n: int = - 1) GenoDistrib

Create a GenoDistrib with a given number of lice and fixed ratios. Note that this function uses a deterministic approach based on the largest remainder method. If you prefer a noisier approach consider from_ratios_rng() .

  • p – the probability of each genotype

  • n – if not -1, set the distribution so that the gross value is equal to n


the new GenoDistrib

slim.simulation.lice_population.from_ratios_rng(n: int, pvals: numpy.ndarray, rng: numpy.random._generator.Generator) GenoDistrib

Create a GenoDistrib with a given number of lice and a probability distribution Note that this function uses a statistical approach to building such distribution. If you prefer a faster but deterministic alternative consider from_ratios() .

  • n – the number of lice

  • pvals – the probability of each genotype

  • rng – the random number generator to use for sampling.


the new GenoDistrib

slim.simulation.lice_population.genorates_to_dict(store: numpy.ndarray) Dict[str, float]

Get a JSON representation of the geno rates.


store – an array of genotype rates as plain matrix


a JSON representation