Introduction

The idea behind the use of Multiparental Advanced Generation Inter-Cross (MAGIC) population in crops was introduced in Mackay and Powell (2007). Subsequently, Cavanagh et al (2008) further refined the idea and provided an example for an 8-founder MAGIC population. Over the years, many MAGIC populations have been developed for various numbers of founders in different crops. Recent reviews from Scott et al (2020) and Arrones et al (2020) provide good details on the history of MAGIC population development.

A major advantage of using a MAGIC population in crops is that the recombinant inbred lines (RILs) have highly recombined genomes with diverse mosaics of the founders. As such, MAGIC population is great for QTL mapping and breeding owing to its high mapping resolution and presence of various novel haplotypes. While MAGIC population is a great genetic resource, the design of crossing schemes can be daunting especially in a population with large number of founders. Many of the MAGIC populations to date have been centered around 8 founders. Based on the information in Table 1 of Scott et al (2020), 8-founder MAGIC populations constitute 15 of 28 total MAGIC populations. Of these 15 MAGIC populations, only one was created from a full design and the remaining were created from either partial or basic designs. Further information on the design types can be found in the Details Section.

A MAGIC population is usually represented by one or more funnels. A funnel is a pedigree subset where it has all the steps in getting all the n founders going into a RIL. In the example shown below, there are four founders and three funnels. Each funnel has a unique crossing scheme. The first round of crossing involves 1 x 2, 3 x 4, 1 x 3, and so on. These are known as two-way crosses because the genomes of the crosses progeny are made of two founders. The next round of crossing involves (1 x 2) x (3 x 4), (1 x 3) x (2 x 4) and (1 x 4) x (2 x 3). These are known as four-way crosses because the genomes of the crosses progeny are made of four founders. Same concept applies for n-founders in which the last step involves n-way crosses. For example, n=16 would have two-way, four-way, eight-way and sixteen-way crosses. In general, because the number of individuals in each funnel halves at each generation, it is convenient to have n as a power of 2 (e.g. 4, 8, 16, 32, …). It is also possible to accommodate other n, and these will all be discussed in the Details section.

With many designs available, it is best to plan ahead since the population creation process can be highly laborious. Prior to this, there was not any available tool for researchers to create and test various MAGIC population designs, which motivates us to create this magicdesign package.

 

Package Implementation

This magicdesign package is available in three options:
1. R package
2. R Shiny app (web)
3. R Shiny app (local)

The first option is targeted for R users. The second option is provided for non-R users with its web-based Shiny interface. The third option is somewhere in between the other two options, where it requires the users to run the Shiny interface locally. Instructions for each option are provided in the following section.

 

Installation

R package

Unlike many common CRAN R packages, magicdesign is provided directly from GitHub. To install an R package from GitHub, we first need to install the devtools package if we do not already have it installed.

install.packages("devtools")

Next, we will need to use devtools to install magicdesign. Note that this step may ask for various updates. The easiest way is to just ignore the updates. Updating other packages is usually not a problem when installing a CRAN R package, but it can be problematic with devtools. In rare occasions, some of these updates might actually be needed for the dependencies (R packages that magicdesign requires). If such issue arises, please update those packages prior to installing magicdesign.

devtools::install_github("cjyang-sruc/magicdesign")

Additional notes: The dependencies for magicdesign are: gtools, stringr, blocksdesign, AlphaSimR, ggplot2, reshape2, ggrepel, plotly and htmlwidgets. These packages should be installed automatically with magicdesign. Installing a package using devtools may result in a warning message about Rtools. Please ignore it since we do not need Rtools here. That should be fine, I think.

 

R Shiny app (web)

The Shiny app is available at https://www.shinyapps.io/. It provides the latest version of magicdesign in a web-based interface for users without needing to work with R directly. It is especially useful for users who are not familiar with R and also users whom currently do not have access to a working computer. Unfortunately, we do not have any funding to maintain a Shiny app server, so our web-based interface is limited to 24 free hours per month courtesy of Rstudio. Please consider using the other two options if possible.

 

R Shiny app (local)

Work under progress…

 

Workflow

A rough approximation of what a user can do with magicdesign is shown in the figure below.

Create a MAGIC population crossing scheme. This step begins with users providing input arguments to the function magic.eval, which will determine the type of MAGIC population to create. All supported population types are described in the Supported Designs. In addition, a flexible option is also provided in the magic.eval function where users can supply a complete pedigree. The pedigree must include all individuals used in generating a MAGIC population. Further information on how to use a pedigree input for magic.eval is described in Pedigree. Regardless of the options chosen, this step will generate a crossing scheme from the founders to the final RILs.

Simulate the population. This step takes the previously generated crossing scheme and simulate a population of RILs. To keep track of founder alleles, we code them (internally) as shown in the following example with n=4 inbred founders. Since a biallelic marker in an inbred individual can only be 0 or 2, we need three “markers” at the same genetic position to code for four founder alleles at a single marker. By keeping the genetic positions the same, we can prevent recombination between these “markers” in the simulation so the founder alleles information is preserved in the RILs.

##           marker_1a marker_1b marker_1c
## founder 1         0         0         0
## founder 2         2         0         0
## founder 3         0         2         0
## founder 4         0         0         2

At the end of the simulation, we convert the RIL marker data (internally) into another format based on n founder alleles.

##       marker_1 marker_2 marker_3 marker_4 marker_5
## RIL 1        2        2        3        3        3
## RIL 2        1        1        1        1        1
## RIL 3        4        4        4        4        2

Evaluate recombinants within an interval. By default, we count the number of all \(n^2 - n\) recombinant haplotypes between two markers at 5 centiMorgans apart in the RILs. This interval can be modified by specifying the hap.int in magic.eval. A good MAGIC population would ideally have high mean counts of recombinant haplotypes and low variance among all recombinant haplotypes. Further information is provided in Plot - Interval.

Evaluate genome-wide founder distributions. Here, we calculate the proportions of each founder genome in the RILs as well as the number of unique founder alleles in each chromosome. Note that the founder genome proportions are determined from genetic positions. Ideally, a good MAGIC population would have equal proportions of each founder genome in the RILs and high number of unique founder alleles in each chromosome. Further information is provided in Plot - Whole.

Repeat for n.sim-times. The previous three steps are repeated by specifying n.sim in magic.eval. Typically, n.sim=100 should be sufficient, I think. Note that the same initial crossing scheme is used in all iterations of the simulations. If only the output pedigree is desired, n.sim can be simply set to 1 to speed the process up.

Test another crossing schemes. This is simply a new simulation with different arguments in magic.eval for users to try a different MAGIC population design.

Display the results (up to 6 schemes). Once the simulations are done, we can plot the results and compare for up to 6 designs. Too many designs can clutter up the plots, so it is best to keep a low number of designs compared at any time. Besides, we can also plot the pedigree for each design. MAGIC pedigree can be complicated, and so we provide the pedigree as an interactive html plot where users can highlight any funnel to identify the paths starting from the founders to RILs. Further information is provided in Results Visualization.

Decide on your choice(s) of crossing scheme. After we have gone through all the results from different designs, it is now time to make a decision on which to move forward. This is entirely subjective as different users may have different ranks of importance in the genetic characteristics, required labor, available funding, and other factors towards creating a MAGIC population.

 

Details

This section contains all the information on how to use magicdesign split over four sub-sections. We will cover the three required functions and how to specify the arguments in each of them. All the supported designs and modifications are specified in the magic.eval function. All the results are displayed using the magic.ped2plot and magic.plot functions.

 

Supported Designs

Currently, there are four supported MAGIC population designs, namely Full, Partial, Basic and Deficient. The first three are restricted to n number of founders that is of a power of 2 and the last is for n that is not a power of 2. Additionally, magicdesign also allows custom design via user-input Pedigree. For each design, there are several Available Modifications. Specifically in the Partial and Deficient designs, the balanced argument is of important consideration as outlined in Mod - balanced.

 

Full Design

As its name suggests, the full design is the most comprehensive design of all. The full design encompasses all possible founder combinations (funnels), and thus it is always a balanced design (see Mod - balanced for more information on balanced design). In our simulation, the directions of crosses have no meaning and so 1 x 2 is equivalent to 2 x 1. But, if both directions are required, please refer to Mod - reps.

To obtain all possible founder combinations (funnels), we simply need to determine all permutations of \(n\) founders in the RILs, and that is \(n!\). Since we regard the reciprocal directions of crosses as equivalent, each permutation is equivalent to \(2^{n-1}-1\) other permutations. Therefore, we can eliminate those redundant permutations, which leads us to \(n!/2^{n-1}\) for a full design. For example, \(n=4\) would have \(3\) funnels and \(n=8\) would have \(315\) funnels. Unfortunately, it is impossible in practice to have a full design for \(n=16\) or larger as \(n=16\) would have \(638,512,875\) funnels.

A full design is only available for n=4 and n=8. To explicitly specify for a full design, we also need to specify the m and balanced arguments as shown in the table below. Details on m can be found in the Partial section and details on balanced can be found in the Mod - balanced section.

n m balanced
4 1 not relevant
8 45 TRUE
Note: if n=4, balanced argument is ignored

Partial Design

Unlike the full design, the partial design has a lot more choices to offer. A partial design is simply a subset of a full design, in which the subset can be either balanced or unbalanced. The subset is specified by the argument m in magic.eval, and the meaning of m depends on balanced=T or balanced=F.

In the case of balanced=T, m is the number of partial balanced funnel sets. Each funnel set has \(n-1\) funnels. As a corollary, a full design is made of \(n!/(2^{n-1}*(n-1))\) unique partial balanced funnel sets. In n=8, there are a total of \(45\) partial balanced funnel sets. Within a partial balanced funnel set, the founders meet once at two-way crosses, twice at four-way crosses, four times at eight-way crosses, and so on. For example, the following is a partial balanced funnel set for n=8.

Funnel 1: ((1 x 2) x (3 x 8)) x ((4 x 6) x (5 x 7))
Funnel 2: ((1 x 3) x (4 x 7)) x ((2 x 8) x (5 x 6))
Funnel 3: ((1 x 4) x (2 x 6)) x ((3 x 7) x (5 x 8))
Funnel 4: ((1 x 5) x (4 x 8)) x ((2 x 7) x (3 x 6))
Funnel 5: ((1 x 6) x (3 x 5)) x ((2 x 4) x (7 x 8))
Funnel 6: ((1 x 7) x (2 x 5)) x ((3 x 4) x (6 x 8))
Funnel 7: ((1 x 8) x (6 x 7)) x ((2 x 3) x (4 x 5))

founder_pair two_way four_way eight_way
1-2 1 2 4
1-3 1 2 4
1-4 1 2 4
1-5 1 2 4
1-6 1 2 4
1-7 1 2 4
1-8 1 2 4
2-3 1 2 4
2-4 1 2 4
2-5 1 2 4
2-6 1 2 4
2-7 1 2 4
2-8 1 2 4
3-4 1 2 4
3-5 1 2 4
3-6 1 2 4
3-7 1 2 4
3-8 1 2 4
4-5 1 2 4
4-6 1 2 4
4-7 1 2 4
4-8 1 2 4
5-6 1 2 4
5-7 1 2 4
5-8 1 2 4
6-7 1 2 4
6-8 1 2 4
7-8 1 2 4

 

In the case of balanced=F, m is the number of funnels. Since we do not need to keep the design balanced in this setting, we are not restricted by the need to have \(n-1\) funnels.

Note that n=4 has only one partial balanced set and that is the same as its full design. Although n=4 can have two partial unbalanced funnels, it has little purpose. To keep things simple, partial design for n=4 is not provided.

The arguments required for a partial design are shown in the table below.

m
balanced=T
balanced=F
n min max min max
8 1 44 1 315
16 1 100 1 10000
32 NA NA 1 10000
64 NA NA 1 10000
128 NA NA 1 10000
Note: Partial design is not available for n = 32, 64 or 128 when balanced=T

Basic Design

The basic design is equivalent to a partial unbalanced design with m=1 funnel. For example, with 8 founders, the basic design is simply ((1 x 2) x (3 x 4)) x ((5 x 6) x (7 x 8)). Since there is one funnel, high replications of the crosses are usually needed to get the haplotype variations and increase the number of RILs. There is also an option to add an extra generation of crossing among the n-way crosses to further increase haplotype variation. These additional settings are described further in the Examples.

This design is available for n = 4, 8, 16, 32, 64, 128, and it can be used by setting m=0 for any n.

NP2 Design

The Non-Power of 2 (NP2) design is similar to the partial design except that it is meant for n that is not a power of 2. The crossing scheme for an NP2 design is based on a n=2^ceiling(log(n,2)) partial design. For example, ((1 x 2) x (1 x 3)) x ((3 x 5) x (4 x 6)) is a funnel for n=6 and it has same number of crosses as n=8 except that founder 1 and 3 are duplicated to fill in the empty slots.

The NP2 design is available as either balanced or unbalanced, where m is the number of funnel sets if balanced=T and m is the number of funnels if balanced=F. Strictly speaking, the balanced NP2 design should only be considered as semi-balanced, as we are only keeping the number of founders in a set balanced but not the crosses. Due to the nature of NP2 design, it requires more than just \(n-1\) funnels to keep the crosses balanced. For example, n=6 requires 3 and 15 funnels to be semi-balanced and fully balanced respectively.

In addition to partial design, full NP2 design is also available for n = 3, 5, 6, 7 by setting balanced=T and m = 1, 48, 285, 135 respectively.

The arguments required for an NP2 design is shown in the table below. Note that the number of funnel (nf) is just provided as a reference and not to be used as an input argument.

m
balanced=T
balanced=F
n nf min max min max
3 3 1 1 1 1
5 5 1 48 1 240
6 3 1 285 1 855
7 7 1 135 1 945
9 9 1 100 1 10000
10 5 1 100 1 10000
11 11 1 100 1 10000
12 3 1 100 1 10000
13 13 1 100 1 10000
14 7 1 100 1 10000
15 15 1 100 1 10000
17 17 NA NA 1 10000
18 9 NA NA 1 10000
19 19 NA NA 1 10000
20 5 NA NA 1 10000
21 21 NA NA 1 10000
22 11 NA NA 1 10000
23 23 NA NA 1 10000
24 3 NA NA 1 10000
25 25 NA NA 1 10000
26 13 NA NA 1 10000
27 27 NA NA 1 10000
28 7 NA NA 1 10000
29 29 NA NA 1 10000
30 15 NA NA 1 10000
31 31 NA NA 1 10000
33 33 NA NA 1 10000
34 17 NA NA 1 10000
35 35 NA NA 1 10000
36 9 NA NA 1 10000
37 37 NA NA 1 10000
38 19 NA NA 1 10000
39 39 NA NA 1 10000
40 5 NA NA 1 10000
41 41 NA NA 1 10000
42 21 NA NA 1 10000
43 43 NA NA 1 10000
44 11 NA NA 1 10000
45 45 NA NA 1 10000
46 23 NA NA 1 10000
47 47 NA NA 1 10000
48 3 NA NA 1 10000
49 49 NA NA 1 10000
50 25 NA NA 1 10000
51 51 NA NA 1 10000
52 13 NA NA 1 10000
53 53 NA NA 1 10000
54 27 NA NA 1 10000
55 55 NA NA 1 10000
56 7 NA NA 1 10000
57 57 NA NA 1 10000
58 29 NA NA 1 10000
59 59 NA NA 1 10000
60 15 NA NA 1 10000
61 61 NA NA 1 10000
62 31 NA NA 1 10000
63 63 NA NA 1 10000
65 65 NA NA 1 10000
66 33 NA NA 1 10000
67 67 NA NA 1 10000
68 17 NA NA 1 10000
69 69 NA NA 1 10000
70 35 NA NA 1 10000
71 71 NA NA 1 10000
72 9 NA NA 1 10000
73 73 NA NA 1 10000
74 37 NA NA 1 10000
75 75 NA NA 1 10000
76 19 NA NA 1 10000
77 77 NA NA 1 10000
78 39 NA NA 1 10000
79 79 NA NA 1 10000
80 5 NA NA 1 10000
81 81 NA NA 1 10000
82 41 NA NA 1 10000
83 83 NA NA 1 10000
84 21 NA NA 1 10000
85 85 NA NA 1 10000
86 43 NA NA 1 10000
87 87 NA NA 1 10000
88 11 NA NA 1 10000
89 89 NA NA 1 10000
90 45 NA NA 1 10000
91 91 NA NA 1 10000
92 23 NA NA 1 10000
93 93 NA NA 1 10000
94 47 NA NA 1 10000
95 95 NA NA 1 10000
96 3 NA NA 1 10000
97 97 NA NA 1 10000
98 49 NA NA 1 10000
99 99 NA NA 1 10000
100 25 NA NA 1 10000
101 101 NA NA 1 10000
102 51 NA NA 1 10000
103 103 NA NA 1 10000
104 13 NA NA 1 10000
105 105 NA NA 1 10000
106 53 NA NA 1 10000
107 107 NA NA 1 10000
108 27 NA NA 1 10000
109 109 NA NA 1 10000
110 55 NA NA 1 10000
111 111 NA NA 1 10000
112 7 NA NA 1 10000
113 113 NA NA 1 10000
114 57 NA NA 1 10000
115 115 NA NA 1 10000
116 29 NA NA 1 10000
117 117 NA NA 1 10000
118 59 NA NA 1 10000
119 119 NA NA 1 10000
120 15 NA NA 1 10000
121 121 NA NA 1 10000
122 61 NA NA 1 10000
123 123 NA NA 1 10000
124 31 NA NA 1 10000
125 125 NA NA 1 10000
126 63 NA NA 1 10000
127 127 NA NA 1 10000
Note: NP2 design is not available for n > 16.

Pedigree

Instead of using designs from magicdesign, we also provide an option for users to input a complete pedigree of their design of choice. Theoretically, this option should work with any design as long as it can represented in a pedigree. The pedigree must be supplied as either a data.frame or matrix with four columns: individual ID, parent 1 ID, parent 2 ID, and generation number. The founders must be included in the pedigree, in which their individual IDs must be continuous from 1 to n founders, parent IDs as 0 or blank, and generation number as 0. All crosses going from the founders to final RILs including any selfing must be documented in the pedigree, and so the generation number must also be continuous (0 to final generations). The names of the individual IDs do not need to conform to any format as long as they are all unique, and the parent IDs must be present in the individual IDs from previous generations except for the founder parent IDs.

To use this option, the only input argument that is required is the ped argument in magic.eval.

 

Available Modifications

In addition to the few input arguments for magic.eval described previously, there are 15 additional arguments that can be used to modify the design.

 

Mod - reps

reps is an important argument in magic.eval as it determines the number of replicates (seeds) to keep from each biological cross. If reps is not supplied, magic.eval will automatically assume no replications at any generation. reps has to be provided as a vector of length \(log_2n\), with each element of the vector represent the number of replicates to keep at 2-way, 4-way, …, n-way crosses. For example, if n=8, reps=c(1,1,2) means that 2 replicates per 8-way cross are kept. In the same example, reps=c(2,1,1) is meaningless in practice because the replicates of each 2-way cross are the same.

Here are three pedigrees showing the effects of different reps in a single funnel for n=8.

In addition, if there is a need to include both directions of crosses (i.e. 1 x 2 and 2 x 1), elements of reps can be supplied as even number. For example, reps=c(2,2,2) would ensure both cross directions are included in each crossing generation. As mentioned previously, the directions of crosses do not matter in our simulation and the only consequence is that the RIL population size increases.

 

Mod - self

self is another important argument in magic.eval as it determines the number of selfing generations after every cross. If self is not supplied, magic.eval will assume no selfing at all. Similar to reps, self is a vector of length \(log_2n\). In the common practice, self is only used in the single-seed descent (SSD) process after n-way crosses have been done. Using n=8 as an example again, self=c(0,0,3) represents no selfing after two-way crosses, no selfing after four-way crosses, and three generations of selfing after eight-way crosses.

Below are three pedigrees with different self for n=8.

 

Mod - inbred

The default in magic.eval is inbred=T since we assume that the founders are inbred. Although the use of non-inbred founders in MAGIC population has not been very common, we do provide an option for non-inbred founders by setting inbred=F.
The major consequence in inbred=F is how the 2-way crosses are handled. If the founders are inbred, then the 2-way crosses between the same founder pairs are all equivalent and so only one is needed for the subsequent 4-way crosses. But, if the founders are not inbred, then the 2-way crosses between the same founder pairs are no longer the same and so each unique individual (seed) is needed for the subsequent 4-way crosses. For example, we have two 4-way crosses here: (1 x 2) x (3 x 4) and (1 x 2) x (5 x 8). If the founders are inbred, we can just use the same (1 x 2) plant for both 4-way crosses. But if the founders are non-inbred, then we need to use two different (1 x 2) plants for each of the 4-way crosses because the (1 x 2) plants are all segregating differently.

Another consequence of inbred=F is how the founder alleles are tracked during simulation. With inbred founders, we have only n founder alleles but with non-inbred founders, we maintain 2*n founder alleles with two distinct alleles for each founder.

Just a note for caution, inbred=F has not been tested extensively so there may still be bugs in the codes. Please let us know if there is any issue with this setting.

 

Mod - balanced

The balanced argument in magic.eval is a logical indicator of whether to use a balanced or unbalanced MAGIC design. A balanced design is defined as a design where all the funnels have equal representation of founders and founder crosses. An example of how a balanced design should look is shown in Partial Design. A full design is always balanced, partial and NP2 designs can be either balanced or unbalanced, and a basic design is always unbalanced. Below is a figure and table to illustrate why a basic design is always unbalanced.

founder_pair two_way four_way
1-2 1 0
1-3 0 1
1-4 0 1
2-3 0 1
2-4 0 1
3-4 1 0
Note: Founder pairs at 2-way and 4-way crosses are not equally represented.

 

Mod - minimize

minimize is an argument for minimizing number of crosses and plants. Conventionally, under minimize=F, in making multiple same eight-way crosses, different four-way individuals are needed to maximize haplotype diversity. However, under minimize=T, the same eight-way crosses are made using the same four-way individuals. This is relevant in n equal to 16 or larger for balanced design with multiple funnel sets, as some eight-way individuals may repeat.

In terms of minimizing plants, here is an example with n=8 where we have two funnels: ((1 x 2) x (3 x 4)) x ((5 x 6) x (7 x 8)) and ((1 x 2) x (3 x 4)) x ((5 x 7) x (6 x 8)). Normally, we require two different ((1 x 2) x (3 x 4)) individuals to maximize haplotype diversity. If minimize=T, then the same ((1 x 2) x (3 x 4)) individual would be used to make the eight-way crosses.

Generally, there is little incentive to use minimize=T, but it is provided as an option in case there is a need for it.

 

Mod - n.try

n.try is an argument in magic.eval that is only used for finding partial balanced design. By default, n.try is set to 1000 and that should suffice unless there is a rare issue in finding partial balanced design.

 

Mod - addx

addx is an argument in magic.eval that adds an extra crossing generation after the final n-way crosses. addx is NULL by default, and it is available as either 1 or 2. For addx=1, this only works with a basic design as it splits the n-way crosses into two pools and make all possible crosses between these two pools. Since this requires two pools of n-way crosses, the reps must be provided such that even number of n-way crosses are produced. For addx=2, this works with any design although it is only recommended for basic or small partial design as this option makes all possible crosses among the n-way individuals (random mating). For k available n-way crosses, this would lead to \(k!/(2!*(k-2)!)\) extra crosses.

 

Mod - repx

repx is an argument in magic.eval that follows if addx is set to either 1 or 2. Like its counterpart reps, repx is simply an integer indicating how many replicates (seeds) per extra cross to keep.

 

Mod - selfx

selfx is an argument in magic.eval that follows if addx is set to either 1 or 2. Like its counterpart self, selfx is simply an integer indicating how many selfing generations to include after the extra cross.

 

Mod - marker.dist

marker.dist, as its name suggests, determines the marker distance in the simulated population. By default, this is set to 0.01 Morgan (1 centiMorgan).

 

Mod - chr.len

chr.len is an important argument as it provides the number of chromosomes and genetic lengths of each chromosome to the simulation. So, chr.len should be supplied as a vector of genetic lengths in the unit of Morgans. For example, chr.len=c(2.45, 2.89, 1.53) would mean that this simulated species has three chromosomes of 2.45, 2.89 and 1.53 Morgans respectively.

 

Mod - n.sim

n.sim determines the number of simulations to run. It is best to start off with n.sim=1, which is also the default, to ensure that the design is working fine before committing into a longer run time with higher n.sim. Once everything is working fine, users may choose n.sim=100 or some other values. The design (crossing scheme) is generated once regardless of n.sim, while the population is simulated over n.sim times.

 

Mod - hap.int

hap.int refers to haplotype interval, which is the interval in Morgans to look for recombinant haplotypes generated from the MAGIC design. By default, hap.int is set to 0.05 Morgan and that tells magic.eval to compute the count of all possible recombinant haplotypes among the founder pairs within that said interval.

 

Mod - n.hap

n.hap indicates the number of haploid marker data to extract from the MAGIC RILs for results. By default, n.hap is set to 1. If the RILs fully inbred, then there is no difference between n.hap=1 and n.hap=2. That said, n.hap=1 should be sufficient as long as there are a few generations of single-seed descent (SSD).

 

Mod - keep

keep decides if the simulated marker data is exported or not. By default, this is not exported because the data can be large and rarely useful. If keep=T, magic.eval will export the marker data from all simulations into a “csv” file. If users choose to use this option, please keep n.sim=1 or small to prevent unneccessary slow down in processing.

 

Results Visualization

One or more results from magic.eval can be visualized in several plots and tables. The relevant functions are magic.ped2plot, magic.plot and magic.summary. The first function, magic.ped2plot converts a pedigree matrix into an interactive plot (exported as an external HTML file). Two other functions, magic.plot and magic.summary perform the same results comparisons except former displays the output as plots and the latter displays the output as tables. Note that magic.plot and magic.summary require a list of one or more designs that were created and tested in magic.eval, and these designs must have the same marker.dist, chr.len, n.sim, hap.int and n.hap otherwise the comparison is meaningless.

 

Plot - Pedigree

The magic.ped2plot function has two required arguments, ped and filename, as well as four optional arguments, basic, show.partial, w2h.ratio and force.option. The ped argument can take pedigree generated from magic.eval, which is the first object in the list of outputs from magic.eval. Similarly, the ped argument can also take any custom pedigree, as long as it conforms to the same standard as the pedigree required for ped input in magic.eval (see Pedigree). The filename argument is simply a character string that users wish to save the pedigree plot as. Please refrain from putting a full directory in the filename argument, and instead, it is better to use setwd() to set the working directory. This ensures that the HTML file is saved in a self-contained format.

As the name suggests, the optional argument basic should be set to TRUE only for pedigree created from basic design. show.partial=T should only be used for pedigree created from either full or partial balanced designs, as it displays the pedigree for only a single partial balanced funnel set. This is just a nicer way to show the subset of a complicated pedigree. w2h.ratio is 2 by default, and it is simply the width-to-height ratio of the pedigree plot. force.option is FALSE by default, and if it set to TRUE, it will create a simpler and less decorated pedigree plot.

 

Plot - Interval

The magic.plot function has four arguments, input, display, fpair, chr.names and annotate. The input argument is a list of one or more outputs from magic.eval. The display argument is a character string of either "interval" or "whole". The fpair argument is a matrix of two columns and is only required when display="interval" as it specifies which recombinant haplotypes to display. For example, with n=8, setting fpair=cbind(c(1,1,3,5), c(2,4,6,4)) would show only “1-2”, “1-4”, “3-6” and “5-4” recombinant haplotypes in the output. The chr.names argument is a vector of chromosome names, for example, chr.names=c("1A","1B","1D"). The annotate argument is a logical indicator of whether to annotate Plot C when display="whole".

For display="interval", a plot with 3 panels (labelled as A, B, C) will be created.

  1. Plot A shows the proportions of total recombinant haplotypes within the specified hap.int.
  2. Plot B shows the counts of unique recombinant haplotypes within hap.int. Note that this maxes out at \(n^2-n\).
  3. Plot C shows the proportions of each recombinant haplotype within hap.int.

High mean and low variance are better for all of these plots, and “evenness” across each recombinant haplotype in Plot C is also important.

 

Plot - Whole

For display="whole", a plot with 3 panels (labeled as A, B, C) will be created.

  1. Plot A shows the mean proportions of each founder genome.
  2. Plot B shows the mean counts of unique founder genome in each chromosome.
  3. Plot C shows the LOESS regression of the mean counts of non-recombinant segments of various lengths in each chromosome.

For Plot A, “evenness” across all founders is better. For Plot B, higher counts (right-biased) is better. For Plot C, higher counts of short segments (left-biased) is better.

 

Summary Tables

The magic.summary function presents a summary information for all the designs compared, as well as the same comparisons as magic.plot. The latter output is provided as an alternative to magic.plot. In the case with many designs being compared, the designs shown in plots can be challenging to distinguish especially for users with color-blindness.

The only argument needed for magic.summary is input, which is a list of one or more outputs from magic.eval.

 

Miscellaneous Notes

To be added.

Examples

For all the examples here, we will use a fictitious species with 5 chromosomes. Genetic lengths of these chromosomes are 3.37, 2.89, 2.50, 2.11, 1.94 Morgans.

 

4 founders + full design + reps + self (120 RILs, 3 funnels)
mpop.1 <- magicdesign::magic.eval(n=4,
                                  m=1,
                                  reps=c(1,40),
                                  self=c(0,4),
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

4 founders + full design + reps + self + addx (108 RILs, 3 funnels)
mpop.2 <- magicdesign::magic.eval(n=4,
                                  m=1,
                                  reps=c(1,3),
                                  self=c(0,0),
                                  addx=2,
                                  repx=3,
                                  selfx=4,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

4 founders + basic design + reps + self + addx (100 RILs, 1 funnel)
mpop.3 <- magicdesign::magic.eval(n=4,
                                  m=0,
                                  reps=c(1,10),
                                  self=c(0,0),
                                  addx=1,
                                  repx=4,
                                  selfx=4,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

4 founders + custom pedigree (120 RILs, 3 funnels, different reps for each funnel)
custom.ped <- cbind(c(1:610),
                    c(0,0,0,0,1,1,1,2,2,3,rep(5,50),rep(6,40),rep(7,30),11:490),
                    c(0,0,0,0,2,3,4,3,4,4,rep(10,50),rep(9,40),rep(8,30),11:490),
                    c(0,0,0,0,1,1,1,1,1,1,rep(2,120),rep(3,120),rep(4,120),rep(5,120),rep(6,120)))
mpop.4 <- magicdesign::magic.eval(ped=custom.ped,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

8 founders + full design + reps + self (630 RILs, 315 funnels)
mpop.5 <- magicdesign::magic.eval(n=8,
                                  m=45,
                                  reps=c(1,1,2),
                                  self=c(0,0,4),
                                  balanced=T,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

8 founders + partial design + balanced + reps + self (588 RILs, 49 funnels)
mpop.6 <- magicdesign::magic.eval(n=8,
                                  m=7,
                                  reps=c(1,3,4),
                                  self=c(0,0,4),
                                  balanced=T,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

8 founders + partial design + unbalanced + reps + self (588 RILs, 49 funnels)
mpop.7 <- magicdesign::magic.eval(n=8,
                                  m=49,
                                  reps=c(1,3,4),
                                  self=c(0,0,4),
                                  balanced=F,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

8 founders + basic design + reps + self + addx (576 RILs, 1 funnel)
mpop.8 <- magicdesign::magic.eval(n=8,
                                  m=0,
                                  reps=c(1,6,4),
                                  self=c(0,0,0),
                                  addx=1,
                                  repx=4,
                                  selfx=4,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

16 founders + partial design + balanced + reps + self (600 RILs, 75 funnels)
mpop.9 <- magicdesign::magic.eval(n=16,
                                  m=5,
                                  reps=c(1,2,2,2),
                                  self=c(0,0,0,4),
                                  balanced=T,
                                  chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                  n.sim=100)

 

16 founders + partial design + unbalanced + reps + self (600 RILs, 75 funnels)
mpop.10 <- magicdesign::magic.eval(n=16,
                                   m=75,
                                   reps=c(1,2,2,2),
                                   self=c(0,0,0,4),
                                   balanced=F,
                                   chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                   n.sim=100)

 

16 founders + basic design + reps + self + addx (600 RILs, 1 funnel)
mpop.11 <- magicdesign::magic.eval(n=16,
                                   m=0,
                                   reps=c(1,4,2,2),
                                   self=c(0,0,0,0),
                                   addx=2,
                                   repx=5,
                                   selfx=4,
                                   chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                   n.sim=100)

 

6 founders + NP2 design + balanced + reps + self (480 RILs, 60 funnels)
mpop.12 <- magicdesign::magic.eval(n=6,
                                   m=20,
                                   reps=c(1,2,4),
                                   self=c(0,0,4),
                                   balanced=T,
                                   chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                   n.sim=100)

 

6 founders + NP2 design + balanced + reps + self (480 RILs, 60 funnels)
mpop.13 <- magicdesign::magic.eval(n=6,
                                   m=60,
                                   reps=c(1,2,4),
                                   self=c(0,0,4),
                                   balanced=F,
                                   chr.len=c(3.37, 2.89, 2.50, 2.11, 1.94),
                                   n.sim=100)

 

Displaying results for some of the examples.

We will display the results for all the 4-founder examples.

Here are the R scripts required for plotting the pedigrees. Note that the pedigree plots are saved as external HTML files.

magicdesign::magic.ped2plot(ped=mpop.1$ped, filename="mpop1")
magicdesign::magic.ped2plot(ped=mpop.2$ped, filename="mpop2")
magicdesign::magic.ped2plot(ped=mpop.3$ped, filename="mpop3", basic=T)
magicdesign::magic.ped2plot(ped=mpop.4$ped, filename="mpop4")

Now, we can compare the results for these four different designs. We will start by plotting using the display="interval" option.

load("C:/Users/cjyan/Box Sync/MAGIC16/v20210204/github/misc/example_mpop1_4.RData")
magicdesign::magic.plot(input=list(mpop.1, mpop.2, mpop.3, mpop.4),
                        display="interval")
## Note: the plot can be exported using the ggsave function in ggplot2.
## For example,
## ggplot2::ggsave(filename="plot.png", width=7, height=7, units="in", dpi=600)

Next, we will plot using the display="whole" option.

magicdesign::magic.plot(input=list(mpop.1, mpop.2, mpop.3, mpop.4),
                        display="whole")
## Note: the plot can be exported using the ggsave function in ggplot2.
## For example,
## ggplot2::ggsave(filename="plot.png", width=7, height=7, units="in", dpi=600)

Lastly, we can look at some summary information of each design.

out.mpop <- magicdesign::magic.summary(input=list(mpop.1, mpop.2, mpop.3, mpop.4))
##              design 1 design 2 design 3 design 4
## 1    founder        4        4        4        4
## 2       type     full     full    basic   custom
## 3        rep   1,40,0    1,3,0   1,10,4     <NA>
## 4       self    0,4,0    0,0,0    0,0,4     <NA>
## 5      cross      6,3   6,3,36   2,1,25      6,3
## 6 generation        6        7        7        6
## 7        RIL      120      108      100      120
## 8     funnel        3        3        1     <NA>

Final remarks

Please feel free to email CJ () if you have any issue or question on how to use magicdesign.