gaynorr / AlphaSimR

R package for breeding program simulations
https://gaynorr.github.io/AlphaSimR/
Other
43 stars 18 forks source link

Write a function that simulates gametes so we can generate pollen, ova, sperm, ... #48

Closed gregorgorjanc closed 2 years ago

gregorgorjanc commented 2 years ago

While working on a beeCross() in SIMplyBee I came to the following problem, which I think shows that it might be nice to be able to simulate gametes - that is, simulate meiosis and return a population with ploidy/2 number of chromosomes (like reduceGenome() does). BUT, I am not fully clear on how to handle pedigree and recombination tracking though - one might argue we don't want to (there can be lots of gametes, ...), but then one could argue we want to for some cases, yada yada.

The bees situation:

We use reduceGenome() to simulate drones and all works as we want, including pedigree and recombination tracking - for example drones appear in the global pedigree.

Then we wrote the following function to simulate workers and we get a population that we want, BUT since we use reduceGenome() to generate the eggs (female gametes) the eggs appear as individuals in the pedigree - we don't want this .

beeCross <- function(queen, drones, nProgeny = 1, simParamBee = NULL) {
  if (is.null(simParamBee)) {
    simParamBee <- get(x = "SP", envir = .GlobalEnv)
  }
  if (nInd(queen) > 1) {
    stop("At the moment we only cater for crosses with a single queen!")
  }
  # Recombination of queen's genomes to generate gametes from the queen
  # (keepParents = FALSE means that the queen will be the parent of the
  #  gamete(s), not queen's parents; but we don't want reduceGenome() because it
  #  creates additional individuals in pedigree, we only want gametes here;
  #  see https://github.com/HighlanderLab/SIMplyBee/issues/126)
  gametesFromTheQueen <- reduceGenome(pop = queen, nProgeny = nProgeny,
                                      keepParents = FALSE, simRecomb = TRUE,
                                      simParam = simParamBee)
  # Drones are already haploid so we just merge both sets of gametes
  pairs <- cbind(gametesFromTheQueen@id,
                 sample(x = drones@id, size = nProgeny, replace = TRUE))
  ret <- mergeGenome(females = gametesFromTheQueen, males = drones,
                     crossPlan = pairs, simParam = simParamBee)
  return(ret)

We can get away by taking bits of the code from reduceGenome() and mergeGenome() for our beeCross(), but this made me think that this gamete generation could be a more general issue that we could cater for, BUT, I am not entirely clear how to address the pedigree and recombination tracking for the gametes - maybe we make it optional? There could be situations where we could generate gametes and say genotype them (at least in principle) so one might want to attach IDs to them, hence pedigree and recombination tracking would make sense in such a case, but not otherwise.

Thoughts?

gaynorr commented 2 years ago

Your best bet is to address this in a cross function that creates the pedigree when it creates an individual. Maybe you could have an intermediate object that stores the parents and creates new individuals from those parents on demand. The current pedigree and recombination tracking implementation just won't easily handle gametes that are separate from individuals.

Alternatively, you could rely on creating "DH" individuals to serve as a gametes. Then you'd want something to process to appropriately process the isDH column in the pedigree to construct the pedigree you want to actually see.