Introduction

Cette page correspond à l’analyse des résultats du SNP calling effectué avec mon petit programme phruscle (“phred + muscle”).

Pour rappel, ce programme utilisait phred sur les fichiers de séquençage pour déterminer les bases. Les séquences obtenues étaient ensuite alignées à un alignement de référence composé de la séquence sauvage et de la séquence du gène synthétique.

J’ai ensuite analysé les sorties de phred qui recense la qualité des bases appelées. J’ai pu ainsi attribuer un score de qualité à toutes les bases non chimériques, ie avec une correspondance dans l’alignement de référence et dans le fichier de séquençage.

library(dplyr)
library(ggplot2)
library(readr)
library(viridis)
library(ggthemes)
library(cowplot)
library(extrafont)
library(gcbiasr)
set_gcbiasr_theme()
snp <- read_phruscle("../../data/phruscle_snpcall.csv")

J’ai donc obtenu un tableau de donnée de la forme suivante, où :

head(snp)
## Source: local data frame [6 x 15]
## 
##    name   refb   snpb   expb  refp  expp  cons  qual mutant lastmp switchp
##   (chr) (fctr) (fctr) (fctr) (int) (int) (chr) (int) (fctr)  (int)   (int)
## 1   pS1      T      T      T   125     1     .    12      s    132     794
## 2   pS1      T      T      T   126     2     .    29      s    132     794
## 3   pS1      G      G      G   127     3     .    32      s    132     794
## 4   pS1      T      T      T   128     4     .    29      s    132     794
## 5   pS1      C      C      C   129     5     .    32      s    132     794
## 6   pS1      T      T      T   130     6     .    29      s    132     794
## Variables not shown: switchb (fctr), sens (chr), inconv (lgl), isrestor
##   (lgl)

Observations générales

Nombres de séquences ?

n_distinct(snp$name)
## [1] 382
snp %>%
    select(mutant, name) %>%
    group_by(mutant) %>%
    summarise(count = n_distinct(name)) %>%
    knitr::kable()
mutant count
s 92
w 99
sw 95
ws 96

On a donc bien toutes nos séquences.

snp %>%
    group_by(mutant) %>%
    summarise(count = n()) %>%
    knitr::kable(align = "c")
mutant count ——– ——- s 64904 w 69927 sw 72509 ws 74074

plot_grid(
    snp %>%
    group_by(mutant, name) %>%
    summarise(count = n()) %>%
    ggplot(aes(x = count, fill = mutant)) +
    geom_histogram(binwidth = 1) +
    scale_fill_brewer(palette = "Set1") +
    labs(x = "Nombre de positions", y = "",
         title = "Distribution de la longueur des séquences"),
    snp %>%
    keep_clean_only() %>%
    group_by(mutant, name) %>%
    summarise(count = n())  %>%
    ggplot(aes(x = count, fill = mutant)) +
    geom_histogram(binwidth = 1) +
    labs(x = "Nombre de positions", y = "",
         title = "Distribution de la longueur des séquences filtrées") +
    ## coord_cartesian(xlim = c(660, 800)) +
    scale_fill_brewer(palette = "Set1"),
    ncol = 1
)

J’ai voulu déterminer s’il existe des bases dans les sorties de phruscle qui ne correspondent pas aux sorties de phd. Autrement dit si la base base est bien toujours la même que la base expb. Plutôt bon signe ! Phruscle a fonctionné comme il faut, ie toutes les bases qu’on a sorties dans nos alignements ont une correspondance dans le fichier phred !.

Analyse de la qualité des séquences

J’ai regardé globalement la distribution de la qualité des bases :

snp %>%
    ggplot(data = ., aes(x = qual )) +
    geom_histogram(binwidth = 1)

J’ai regardé séquence par séquence les variation de qualité le long de la séquence :

quality_control(snp)

Comme attendu, la qualité est moindre en fin de run, et plutôt bonne au début1 On séquence de gauche à droite, la cassette de résistance est en 3’. Ce sont des séquences trimmées par phd. On n’est pas obligé de trimmer, mais ça permet de ne garder que les séquences qui vallent le coup. Peut-être refaire les analyses avec les séquences non trimmées. Certaines séquences ne sont pas des plus propres. On peut certainement les virer pour ne garder que les bonnes séquences. Comme pour le cas de la séquence psw21.

J’ai choisi pour statistique la qualité médiane, la qualité moyenne étant trop influencée par les baisses de qualité dans les positions terminales. De plus, la médiane a une distribution plus centrée que la moyenne.

snp %>%
    group_by(name) %>%
    summarise(median = median(qual)) %>%
    qplot(data = . , median, binwidth = 0.1) +
    geom_vline(xintercept = 40, color = "red")

snp %>%
    group_by(name) %>%
    summarise(mean = mean(qual)) %>%
    qplot(data = . , mean, binwidth = 0.1) +
    geom_vline(xintercept = 40, color = "red")

Après avoir appliqué tout ça, on a perdu 9 séquences

Distribution de la longueur des séquences.

Comme attendu, la longueur des séquences est plus élevée avec les constructions SW et WS, puisqu’on a placé l’amorce légérèment en amont de la construction.

snp %>%
    group_by(name, mutant) %>%
    summarise(len = max(refp) - min(refp)) %>%
    ggplot(data = ., aes(x = len )) +
    geom_histogram(binwidth = 1) +
    facet_grid(mutant ~ .) +
    labs(x = "longueur", y = "")

snp %>%
    filter(cons == "x" | cons == "X") %>%
    ## filter(refp < 750 & refp > 40) %>%
    ggplot(aes(x = refp)) +
    geom_histogram(binwidth = 1)

Analyses visuelles des traces de conversion

plot_align(snp, "ws")

plot_align(snp, "sw")

plot_align(snp, "s")

plot_align(snp, "w")

plot_grid(
    snp %>% plot_align("s") + theme(legend.position = "bottom")
   ,snp %>% plot_align("w") + theme(legend.position = "bottom")
   ,snp %>% plot_align("ws") + theme(legend.position = "bottom")
   ,snp %>% plot_align("sw") + theme(legend.position = "bottom")
   ,labels = c("A", "B", "C", "D")
   ,ncol = 4
)

Comparaison des longueurs de trace de conversion

On peut s’attendre sous l’hypothèse gBGC à ce que les traces de conversions soient plus longues lorsqu’on transforme par un plasmide porteur de S que lorsqu’on transforme par un plasmide porteur de W.

snp %>%
    filter(cons == "x") %>%
    group_by(name, mutant) %>%
    summarise(len = min(refp) ) %>%
    ggplot(aes(x = factor(mutant, levels = c("s", "w", "sw", "ws")), y = len)) +
    geom_point(alpha = 0.2) +
    stat_summary(fun.y = "mean", geom = "point", color = "red", shape = "|",
                 size = 7) +
    labs(x = "mutant", y = "Longueur\ndu tract") +
    coord_flip()
snp %>%
    filter(cons == "x") %>%
    group_by(name, mutant) %>%
    summarise(len = min(refp) ) %>%
    group_by(mutant) %>%
    summarise(mean_len = mean(len)) %>%
    knitr::kable(align = "c")
mutant mean_len
s 380.5165
w 403.4255
sw 464.1250
ws 405.8851
plot_conv_len(snp)

Pour l’instant on ne voit quand même pas grand chose de flagrant. Il semblerait même que les plasmides S introduisent des traces de conversion plus courtes, même si rien de quantifié pour l’instant.

Comptage des alternances SNP SS et WW

Comptage des doublets

En fin de trace de conversion, on s’attend à une alternance entre le génotype du donneur et le génotype du receveur. En fin de trace de conversion, on aura donc des doublets (GC)(GC) ou (AT)(AT), Sous l’hypothèse gBGC, les traces de conversions se terminent préférentiellement sur des SNPs GC. On aurait donc plus de doublets (GC)(GC).

On pourrait simplement compter les doublets en question par construction SW et WS, mais il existe des cas intermédiaires où le génotype parental est restauré. Il faut donc discrimer les doublets en fin de trace de conversion des doublets intermédiaires correspondant aux cas complexes. En fait, ces cas complexes se manifestent par des triplets (GC)(GC)(GC) ou (AT)(AT)(AT) dans la trace de conversion, où le SNP médian correspond au génotype parental.

knitr::kable(count_last_snp(snp))
mutant sens count
S AT 89
W CG 87
SW CG 45
SW AT 33
WS CG 37
WS AT 41

plot(count_last_snp(snp))
knitr::kable(count_restor(snp))
mutant sens count
w CG 4
sw CG 2
sw AT 3
ws CG 4
ws AT 1

plot(count_restor(snp))

Quantification du rapport en base

Franck se disait qu’il serait peut-être judicieux de comparer globalement le taux de GC global de nos séquences, sachant qu’on introduit des SNPs AT et GC dans toutes nos séquences, en tout cas pour la manip SW / WS. Au vu des graphiques suivants, on peut déjà se rendre compte d’une chose : le taux de GC ne se comporte pas comme attendu sous l’hypothèse d’une conversion biaisée dans les manips SW et WS.

get_gc_content(data = snp) %>% plot()

Enquête de néomutation

devtools::session_info()
##  setting  value                       
##  version  R version 3.2.4 (2016-03-16)
##  system   x86_64, darwin14.5.0        
##  ui       X11                         
##  language (EN)                        
##  collate  en_US.UTF-8                 
##  tz       Europe/Paris                
##  date     2016-04-28                  
## 
##  package      * version    date       source        
##  ade4           1.7-4      2016-03-01 CRAN (R 3.2.4)
##  assertthat     0.1        2013-12-06 CRAN (R 3.2.0)
##  colorspace     1.2-6      2015-03-11 CRAN (R 3.2.0)
##  cowplot      * 0.6.2      2016-04-20 CRAN (R 3.2.5)
##  DBI            0.3.1      2014-09-24 CRAN (R 3.2.0)
##  devtools       1.11.1     2016-04-21 CRAN (R 3.2.5)
##  digest         0.6.9      2016-01-08 CRAN (R 3.2.3)
##  dplyr        * 0.4.3      2015-09-01 CRAN (R 3.2.0)
##  evaluate       0.8        2015-09-18 CRAN (R 3.2.0)
##  extrafont    * 0.17       2014-12-08 CRAN (R 3.2.0)
##  extrafontdb    1.0        2012-06-11 CRAN (R 3.2.0)
##  formatR        1.2.1      2015-09-18 CRAN (R 3.2.0)
##  gcbiasr      * 0.0.0.9000 2016-04-28 local         
##  ggplot2      * 2.1.0      2016-03-01 CRAN (R 3.2.4)
##  ggthemes     * 3.0.3      2016-04-09 CRAN (R 3.2.4)
##  gridExtra      2.2.1      2016-02-29 CRAN (R 3.2.4)
##  gtable         0.2.0      2016-02-26 CRAN (R 3.2.3)
##  highr          0.5.1      2015-09-18 CRAN (R 3.2.0)
##  htmltools      0.3        2015-12-29 CRAN (R 3.2.3)
##  knitr        * 1.12.3     2016-01-22 CRAN (R 3.2.3)
##  labeling       0.3        2014-08-23 CRAN (R 3.2.0)
##  lazyeval       0.1.10     2015-01-02 CRAN (R 3.2.0)
##  magrittr       1.5        2014-11-22 CRAN (R 3.2.0)
##  memoise        1.0.0      2016-01-29 CRAN (R 3.2.3)
##  munsell        0.4.3      2016-02-13 CRAN (R 3.2.3)
##  plyr           1.8.3      2015-06-12 CRAN (R 3.2.0)
##  R6             2.1.2      2016-01-26 CRAN (R 3.2.3)
##  RColorBrewer   1.1-2      2014-12-07 CRAN (R 3.2.0)
##  Rcpp           0.12.4     2016-03-26 CRAN (R 3.2.4)
##  readr        * 0.2.2      2015-10-22 CRAN (R 3.2.0)
##  reshape2       1.4.1      2014-12-06 CRAN (R 3.2.0)
##  rmarkdown      0.9.5      2016-02-22 CRAN (R 3.2.3)
##  Rttf2pt1       1.3.3      2015-01-13 CRAN (R 3.2.0)
##  scales         0.4.0      2016-02-26 CRAN (R 3.2.3)
##  seqinr         3.1-3      2014-12-17 CRAN (R 3.2.0)
##  stringi        1.0-1      2015-10-22 CRAN (R 3.2.0)
##  stringr        1.0.0      2015-04-30 CRAN (R 3.2.0)
##  tidyr          0.4.1      2016-02-05 CRAN (R 3.2.3)
##  tufte        * 0.2        2016-02-07 CRAN (R 3.2.3)
##  viridis      * 0.3.4      2016-03-12 CRAN (R 3.2.4)
##  withr          1.0.1      2016-02-04 CRAN (R 3.2.3)
##  yaml           2.1.13     2014-06-12 CRAN (R 3.2.0)