# SynExtend
**Table of contents:**
- [Introduction](#introduction)
- [Installation](#installation)
- [Usage](#usage)
- [Reporting Bugs and Errors](#Reporting-Bugs-and-Errors)
## Introduction
SynExtend is a package of tools for working with synteny objects generated from the Bioconductor Package DECIPHER.
## Installation
SynExtend is present in the package repository Bioconductor and the current `release` version can be installed via:
```r
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install()
BiocManager::install("SynExtend")
library("SynExtend")
```
The `devel` version in Bioconductor can be installed via:
```r
BiocManager::install("SynExtend", version = "devel")
library("SynExtend")
```
The version in this repository (which should always be up to date with `devel` and frequently ahead of `release`) can be installed with devtools via:
```r
devtools::install_github(repo = "npcooley/synextend")
library("SynExtend")
```
Additionally, SynExtend is maintained in a Docker container on [Dockerhub](https://hub.docker.com/repository/docker/npcooley/synextend) that is [here](https://github.com/npcooley/SynContainer).
## Usage
### Prediction of Orthologous Gene Pairs
SynExtend facilitates the prediction of orthologous gene pairs from synteny maps. The functions herein rely on synteny maps built by the `FindSynteny()` function in the package `DECIPHER`. The process is relatively straightforward and only requires assemblies and genecalls, which can be conveniently pulled from the NCBI using [Entrez Direct](https://www.ncbi.nlm.nih.gov/books/NBK179288/). However, as long as given assemblies have associated gene calls, or can have gene calls generated, they will work just fine. `DECIPHER` now contains the function `FindGenes()` that produces high quality de novo gene calls.
Using Entrez Direct, this process would start like this:
```r
library(SynExtend)
EntrezQuery <- paste("esearch -db assembly ",
"-query '",
"kitasatospora[organism] ",
'AND "complete genome"[filter] ', # only complete genomes
'AND "refseq has annotation"[properties] ', # only genomes with annotations
'AND "latest refseq"[filter] ', # only latest
"NOT anomalous[filter]' ",
'| ',
'esummary ',
'| ',
'xtract -pattern DocumentSummary -element FtpPath_RefSeq',
sep = "")
FtPPaths <- system(command = EntrezQuery,
intern = TRUE,
timeout = 300L) # timeout argument is required for RStudio only
FNAs <- unname(sapply(FtPPaths,
function(x) paste(x,
"/",
strsplit(x,
split = "/",
fixed = TRUE)[[1]][10],
"_genomic.fna.gz",
sep = "")))
GFFs <- unname(sapply(FtPPaths,
function(x) paste(x,
"/",
strsplit(x,
split = "/",
fixed = TRUE)[[1]][10],
"_genomic.gff.gz",
sep = "")))
```
With these matched character vectors describing files on the NCBI FTP site, we can pull given assemblies, and their associated `GFF` files.
Assemblies are pulled using functions within the package `Biostrings` and placed in a sqlite database using the package `DECIPHER`. Note, `DBPATH` can be a specific local file location, though a tempfile works fine for this example. The tempfile in this example will be destroyed upon closure of the active R session, so specific file paths are preferable for most user activity. The code chunk below provides an example of pulling down assemblies from the NCBI and using `DECIPHER`'s built in gene finder to generate gene calls.
```r
DBPATH <- tempfile()
GC01 <- vector(mode = "list",
length = length(FNAs))
for (m1 in seq_along(FNAs)) {
X <- readDNAStringSet(FNAs[m1])
Seqs2DB(seqs = X,
type = "XStringSet",
dbFile = DBPATH,
identifier = as.character(m1),
verbose = TRUE)
GC01[[m1]] <- FindGenes(myDNAStringSet = X)
}
names(GC01) <- seq(length(FNAs))
```
A current quirk to this process is that genecalls must be present in a named list, where the names can be matched to integer identifiers in the `DECIPHER` database used to construct a synteny object. Users have the option of using the function `FindGenes` in `DECIPHER`, using the `rtracklayer` function `import` to import a valid `GFF` file, or importing a `GFF` with the `SynExtend` function `gffToDataFrame` which performs some data munging to convert the `GFF` into a `DataFrame` for user convenience.
```r
GC02 <- vector(mode = "list",
length = length(GFFs))
for (m1 in seq_along(GFFs)) {
GC02[[m1]] <- gffToDataFrame(GFF = GFFs[m1],
Verbose = TRUE)
}
names(GC02) <- seq(length(GC02))
```
With assemblies and genecalls now in a user's workspace, users can build a synteny map with `FindSynteny`. See `?FindSynteny` in R for further reading. Finding and tabulating where genes are connected by syntenic k-mers is then performed with `NucleotideOverlap`, and that raw data is converted into a convenient `data.frame` with the function `PairSummariers`.
```r
Syn <- FindSynteny(dbFile = DBPATH)
Links <- NucleotideOverlap(SyntenyObject = Syn,
GeneCalls = GC01,
Verbose = TRUE)
Pairs01 <- PairSummaries(SyntenyLinks = Links,
PIDs = TRUE,
Verbose = TRUE)
Clusters01 <- DisjointSet(Pairs = Pairs01,
Verbose = TRUE)
```
Pairs where predictions create conflicts can be removed by a simple subsetting function.
```r
Pairs02 <- SubSetPairs(CurrentPairs = Pairs01,
Verbose = TRUE)
Clusters02 <- DisjointSet(Pairs = Pairs02,
Verbose = TRUE)
```
A more self-contained example is maintained in this package's Bioconductor vignette, and can be found [here](https://www.bioconductor.org/packages/release/bioc/html/SynExtend.html)
### Creating Functional Association Networks
SynExtend also allows for prediction of functional association networks from evidence of correlated selective pressures between of pairs of clusters of orthologous genes (COGs). Given a list of gene trees or presence/absence data, the `EvoWeaver` class in SynExtend uses multiple algorithms to compute likelihood of pairwise functional association. This list can be generated with `DisjointSet(...)`, or can be created by the user.
An example of using `EvoWeaver` can be done using the built-in example *Streptomyces* dataset. This will predict functional association of 200 genes from 301 genomes.
```r
exData <- get(data("ExampleStreptomycesData"))
ew <- EvoWeaver(exData$Genes)
# For faster runtime, set subset as follows:
# predictions <- predict(ew, mySpeciesTree=exData$Tree, subset=1:20)
predictions <- predict(ew, mySpeciesTree=exData$Tree)
# View number of genes and number of predictions:
# Print out the adjacency matrix:
predictions
# Print out pairwise associations:
as.data.frame(predictions)
# Plot genes using force-directed embedding:
plot(predictions)
```
Current algorithms used for prediction are Jaccard distance, Hamming distance, Mutual Information, Direct Coupling Analysis, Phylogenetic Gain/Loss events, Co-localization, MirrorTree, and ContextTree. See `?EvoWeaver` for more details.
### Planned Updates
SynExtend currently has an extensive TODO list that includes:
1. Parsing communities of predicted pairs.
2. User friendly accessor functions to help with printing and plotting data.
If users have specific requests I would love to incorporate them.
## Reporting Bugs and Errors
Feel free to email me at npc19@pitt.edu or submit issues here on GitHub. Questions related to `EvoWeaver` can be sent to ahl27@pitt.edu or submitted similarly on GitHub.