Skip to main content

Simulate Breeding Crosses

Requires PopGenSims.jl

To perfom simulations, you will need add and import the package PopGenSims.jl (available here).

If you need to simulate offspring genotypes given mating between two individuals, the cross() functions are available to simulate crosses and backcrosses.

Currently, PopGenSims.jl can create crosses for:

  • haploids (ploidy = 1)
  • diploids (ploidy = 2)
  • tetraploids (ploidy = 4)
  • hexaploids (ploidy = 6)
  • octaploids (ploidy = 8)

Perform a crossโ€‹

cross(::PopData, parent1::String, parent2::String; n::Int, generation::String)

The cross function performs a simple parental cross from individuals parent1 and parent2 in the same PopData object. The parents are strings of the names of the parents in the PopData. The keyword argument n is the number of offspring to produce, and generation is a keyword argument for the population name to the assign the offspring (default: "F1").

Exampleโ€‹

julia> cats = @nancycats;

julia> f1 = cross(cats, "N111", "N107", n = 100000)
PopData{Diploid, 9 Microsatellite loci}
Samples: 100000
Populations: 1

Here is a look at the resulting PopData

There are two things that should jump out at you:

  1. The name of offspring are prepended with generation and the population is the generation.
  2. There is a never-before-seen parents column. This column exists for better record keeping of who has what parents if you are performing multiple crosses.
julia> f1.sampleinfo
100000ร—6 DataFrame
โ”‚ Row โ”‚ name โ”‚ ploidy โ”‚ population โ”‚ parents โ”‚
โ”‚ โ”‚ String โ”‚ Int8 โ”‚ String โ”‚ Tupleโ€ฆ โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1 โ”‚ F1_offspring_1 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 2 โ”‚ F1_offspring_2 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 3 โ”‚ F1_offspring_3 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 4 โ”‚ F1_offspring_4 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 5 โ”‚ F1_offspring_5 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ‹ฎ
โ”‚ 99995 โ”‚ F1_offspring_99995 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 99996 โ”‚ F1_offspring_99996 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 99997 โ”‚ F1_offspring_99997 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 99998 โ”‚ F1_offspring_99998 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 99999 โ”‚ F1_offspring_99999 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚
โ”‚ 100000 โ”‚ F1_offspring_100000 โ”‚ 2 โ”‚ F1 โ”‚ ("N111", "N107") โ”‚

Perform a cross/backcrossโ€‹

cross(PopData => "Parent1Name", PopData => "Parent2Name", n::Int, generation::String)

This syntax uses the Pair notation of PopData => "Parent" to specify inputs. This method can be used for performing a cross like above, with the flexibility of parents allowed from two different PopData objects, which makes backcrosses possible. The keyword argument n is the number of offspring to produce, and generation is a keyword argument for the population name to the assign the offspring (default: "F1").

Exampleโ€‹

julia> f2_backcross = cross(cats => "N111", f1 => "F1_offspring_99", n = 100000, generation = "F2_manycats")
PopData{Diploid, 9 Microsatellite loci}
Samples: 100000
Populations: 1

And here you can see that generation was again prepended to each offspring name, along with assigned to the population for each.

julia> f2_backcross.sampleinfo
100000ร—6 DataFrame
โ”‚ Row โ”‚ name โ”‚ ploidy โ”‚ population โ”‚ parents โ”‚
โ”‚ โ”‚ String โ”‚ Int8 โ”‚ String โ”‚ Tuple{String,String} โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1 โ”‚ F2_manycats_offspring_1 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 2 โ”‚ F2_manycats_offspring_2 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 3 โ”‚ F2_manycats_offspring_3 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 4 โ”‚ F2_manycats_offspring_4 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 5 โ”‚ F2_manycats_offspring_5 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ‹ฎ
โ”‚ 99995 โ”‚ F2_manycats_offspring_99995 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 99996 โ”‚ F2_manycats_offspring_99996 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 99997 โ”‚ F2_manycats_offspring_99997 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 99998 โ”‚ F2_manycats_offspring_99998 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 99999 โ”‚ F2_manycats_offspring_99999 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
โ”‚ 100000 โ”‚ F2_manycats_offspring_100000 โ”‚ 2 โ”‚ F2_manycats โ”‚ ("N111", "F1_offspring_99") โ”‚
caution

When crossing parents from different PopData, the parents must have the same loci. You will see error messages if they don't.

Merge resultsโ€‹

The PopData generated from breeding crosses can be combined used append or append!

append(::PopData, ::PopData)
append!(::PopData, ::PopData)

These methods use outer joins and the PopData you are combining must have the same loci.

Exampleโ€‹

# non mutating
crossed_sims = append(f1, f2_backcross)

# mutating
append!(f1, f2_backcross)