---
title: "cgMLST report from chewieSnake pipeline"
date: "`r format(Sys.time(), '%d %B, %Y')`"
output:
  html_document:
    toc: true
    toc_depth: 2
editor_options: 
  chunk_output_type: console
---

<style type="text/css">
.main-container {
  max-width: 3600px;
  margin-left: auto;
  margin-right: auto;
}
</style>

<style>
  tbody tr:hover {
  background: yellow;
} 

</style>


```{r setup, include=FALSE}
knitr::opts_chunk$set(out.width = '80%',fig.asp= 0.5,fig.align='center',echo=FALSE, warning=FALSE, message=FALSE, fig.height = 20, fig.width = 20, fig.align = "center")
options(markdown.HTML.header = system.file("misc", "datatables.html", package = "knitr"))

```



```{r load_packages, echo=FALSE}

suppressPackageStartupMessages(library(magrittr))
suppressPackageStartupMessages(library(reshape2)) # for converting matrix
suppressPackageStartupMessages(library(ggplot2)) # for plotting (which?)
suppressPackageStartupMessages(library(ape)) # read/write data
suppressPackageStartupMessages(library(DT)) # datatable 
suppressPackageStartupMessages(library(plotly)) # interactive plots/trees
suppressPackageStartupMessages(library(dendextend)) ##  get_nodes_attr
suppressPackageStartupMessages(library(ggtree)) ## nice trees


```

```{r define_functions, echo=FALSE}

read_distance_matrix <- function(file, sep = " ", header = FALSE){
  if(!file.exists(file)) {stop(paste("File",file,"does Not exist")); return(NA)}
  distance_matrix <- read.delim(file, sep=sep, stringsAsFactors = F, header = header)
  rownames(distance_matrix) <- sub(".fasta","",distance_matrix[,1])
  distance_matrix <- distance_matrix[,-1]
  colnames(distance_matrix) <- rownames(distance_matrix)
  distance_matrix <- as.matrix(distance_matrix[order(colnames(distance_matrix)),order(colnames(distance_matrix))])
  return(distance_matrix)
}

reorder_cormat <- function(cormat){
  dd <- as.dist(cormat)
  hc <- hclust(dd)
  cormat <-cormat[hc$order, hc$order]
}

get_upper_tri <- function(cormat){
  cormat[lower.tri(cormat)]<- NA
  return(cormat)
}


plot_distance_matrix <- function(distance_matrix2, param_color_thr = c(0,1,5,10,20), param_size = 3, param_legendsize = 12, metadata = NA){
  
  # remove diagonal elements
  diag(distance_matrix2) <- NA
  
  # Reorder the correlation matrix
  distance_matrix2 <- reorder_cormat(distance_matrix2)
  
  # melt matrix
  distance_matrix.m <- reshape2::melt(distance_matrix2, na.rm = TRUE, value.name="Distance",varnames=c("Sample1","Sample2"), id.vars = "id")

  label_color <- "black"
  
  p1 <- ggplot(distance_matrix.m, aes(Sample1, Sample2)) +
    geom_tile(aes(fill = Distance), colour = "white", show.legend = F) + 
    geom_text(aes(label = round(Distance, 1)), size = param_size) +
    scale_fill_gradientn(colours = c("white", "yellow", "orange", "red"), values = scales::rescale(param_color_thr)) +
    theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = param_legendsize, hjust = 1, color = label_color),  axis.text.y = element_text(size = param_legendsize, color = label_color), axis.title.x = element_blank(),
          axis.title.y = element_blank()) + coord_fixed()
  
  
  return(p1)
  
}

```

```{r define_Data, echo=FALSE}

dev_mode <- F # T # receive parameters from snakemake, set to T for testing purposes

if(dev_mode){
  #source(file = "report_test_params.R") # TODO CHANGE
  source(file = "/home/carlus/BfR/Snakemake/chewieSnake/scripts/report_test_params.R")
} else {
workdir <- snakemake@params[["workdir"]]  

allele_stats_file <- file.path(workdir, snakemake@input[["allele_stats"]])
masked_loci_file <- file.path(workdir, snakemake@input[["masked_loci"]])
  

distance_matrix_file <- file.path(workdir, snakemake@input[["distance_matrix"]])

nwk_file  <- file.path(workdir, snakemake@input[["nwk"]])
sample_timestamps_file <- file.path(workdir, snakemake@input[["timestamps"]])

hashid_file <- file.path(workdir, snakemake@input[["hashids"]])

# params
exportpath <- file.path(workdir, snakemake@params[["exportpath"]])
export <- snakemake@params[["export"]]

parameters <- snakemake@params[["parameters"]]

distance_threshold <- snakemake@params[["distance_threshold"]]

clustering_method <- snakemake@params[["clustering_method"]]
clustering_threshold_range_raw <- snakemake@params[["threshold_range"]]

remove_frameshifts <- snakemake@params[["remove_frameshifts"]]

log <- file(snakemake@log[[1]], open="wt")

# redirect output to log file
sink(log)
sink(log, type="message")
}

```


```{r load_data, echo=FALSE}

allele_stats <- read.delim(allele_stats_file, stringsAsFactors = F, header = T, sep = "\t")


if (remove_frameshifts){
  warning("New Feature remove_frameshifts is active: ",remove_frameshifts) # TODO Remove
  
  masked_loci <- read.delim(masked_loci_file, stringsAsFactors = F, header = T, sep ="\t")
  # if (file.exists(masked_loci_file)){
  #      }

} else { # TODO Remove
  warning("New Feature remove_frameshifts is not active: ",remove_frameshifts)
}


distance_matrix <- read.delim(distance_matrix_file, stringsAsFactors = F, header = F, sep = " ")

sample_timestamps <- read.delim(sample_timestamps_file, stringsAsFactors = F, header = T, sep = "\t")

hashids <- read.delim(hashid_file, stringsAsFactors = F)

nwk <- ape::read.tree(nwk_file)

samples <- distance_matrix$V1

```


```{r preprocess_data, echo=FALSE}

# re-format cluster distance matrix
rownames(distance_matrix) <- distance_matrix[,1]
distance_matrix <- as.matrix(distance_matrix[,-1])
colnames(distance_matrix) <- rownames(distance_matrix)

# re-order matrix
distance_matrix_clustered <- hclust(as.dist(distance_matrix))
distance_matrix <- distance_matrix[distance_matrix_clustered$order, distance_matrix_clustered$order]

# round distances
distance_matrix <- round(distance_matrix,0)

# export distance matrix
distance_matrix_out <- file.path(workdir, "reports", "allele_distance_matrix.tsv") #exportpath
write.table(distance_matrix, file = distance_matrix_out, sep="\t", quote = F, row.names = T, col.names = NA)

# melt matrix
distance_matrix.m <- reshape2::melt(distance_matrix)
colnames(distance_matrix.m) <- c("Sample1","Sample2","Distance")

# further parameters
locus_count <- sum(allele_stats[1,-1])

max_sample_size_tables <- 200
max_table_size <- max_sample_size_tables^2

if(nrow(distance_matrix) > max_sample_size_tables){
  distance_table_reduced <- T
  distance_limit <- sort(distance_matrix.m$Distance, decreasing = F)[max_table_size]
  
} else {
  distance_table_reduced <- F
}

```


```{r clustering, echo=FALSE}
# TODO fix
# add clustering, cluster-address
clustering_threshold_range <- as.numeric(strsplit(clustering_threshold_range_raw,"[ ,;]+")[[1]])

clust <- distance_matrix %>% as.dist %>% hclust(., method = clustering_method)
dendro <- clust %>% as.dendrogram
phylo <- clust %>% as.phylo

# -------------

# subclusters

subcluster_counts <- sapply(clustering_threshold_range, function(cut_threshold) {
  length(unique(dendextend::cutree(dendro, h = cut_threshold)))  
})
names(subcluster_counts) <- clustering_threshold_range

# compute cluster memberships and addresses for all cutoffs
cluster_address_matrix <- do.call(rbind,lapply(sort(clustering_threshold_range,decreasing = T), function(x){
  dendextend::cutree(dendro, h = x)  
}))
rownames(cluster_address_matrix) <- as.character(sort(clustering_threshold_range, decreasing = T)) 
cluster_address_matrix <-t(cluster_address_matrix)


# re-order # TODO superflous with new version
# cluster_address_matrix <- cluster_address_matrix[,as.character(sort(as.numeric(colnames(cluster_address_matrix)),decreasing = T))]

# convert to single address
cluster_address <- apply(cluster_address_matrix,1,function(x) paste(x, collapse = "."))

# table of cluster membership
cluster_address_matrix_augmented <- as.data.frame(cluster_address_matrix)
colnames(cluster_address_matrix_augmented) <- paste("threshold",colnames(cluster_address_matrix_augmented),sep = "_")
cluster_address_matrix_augmented$Sample <- rownames(cluster_address_matrix)

cluster_address_matrix_augmented[] <- lapply( cluster_address_matrix_augmented, factor) 

cluster_address_matrix_augmented <- cluster_address_matrix_augmented[,c(ncol(cluster_address_matrix_augmented),1:(ncol(cluster_address_matrix_augmented)-1))]

# add hashid
#sample  hashID
cluster_address_matrix_augmented <- merge(cluster_address_matrix_augmented,hashids,by.x="Sample", by.y="sample")



executor <- Sys.info()["user"]

```


---
author: `r paste0(executor)`
---

# cgMLST report for analysis `r workdir` {.tabset}


User `r unname(Sys.info()["user"])` executed the pipeline.

## Overview


```{r overview_stats, echo=FALSE}

# recent samples
Today <- Sys.Date()
recent_days <- 30

sample_timestamps$dateformat <- as.Date(sample_timestamps$date)
sample_timestamps$age <- difftime(Today, sample_timestamps$dateformat, units = "day")
samples_recent <- sample_timestamps$sample[sample_timestamps$age < recent_days]
sample_timestamps_recent <- sample_timestamps[sample_timestamps$age < recent_days,]
# order by recency
sample_timestamps_recent <- sample_timestamps_recent[order(sample_timestamps_recent$age, decreasing = F),]


# Quality
bad_allele_threshold <- 0.05
bad_allele_fraction <- rowSums(allele_stats[,-c(1,2,3)])/rowSums(allele_stats[,-1])
good_allele_fraction <- 1 - bad_allele_fraction
bad_samples <- allele_stats[which(bad_allele_fraction > bad_allele_threshold),1]
bad_sample_count <- sum(bad_allele_fraction > bad_allele_threshold)

# add quality summary to allele_stats

allele_stats <- data.frame(allele_stats[,1],good_allele_fraction=round(good_allele_fraction,2),bad_allele_fraction=round(bad_allele_fraction,2),allele_stats[,-1])
colnames(allele_stats)[1:3] <- c("Sample","Fraction of\nloci found","Fraction of\nmissing loci")


if (remove_frameshifts){
  colnames(masked_loci)[2] <- "Loci removed\nby length"
  allele_stats <- merge(allele_stats,masked_loci,by.x="Sample",by.y="sample",all.x=T)
}



```


* Last update on `r strsplit(as.character(file.info(distance_matrix_file)$mtime[1]), split = " ")[[1]][1]`.

* Database contains `r length(samples)` samples.

* In the last `r recent_days` days `r length(samples_recent)` samples were added. The ten most recently added samples are `r head(sample_timestamps_recent$sample,10)`.

* `r bad_sample_count` samples were of bad quality (having more than `r bad_allele_threshold * 100` per cent missing or dubiously called alleles ), see __Allele statistics__ for details. Bad samples: `r bad_samples`

* Clustering the allele distance reveals the following number of clusters for different distance thresholds

```{r clustering_overview}

clustering_summary <- cbind("Distance threshold" = names(subcluster_counts), "Cluster count" = subcluster_counts)
knitr::kable(clustering_summary,row.names = F)
```

See section __Clustering__ for more details.


```{r overview, echo=FALSE}



# new files 
# need keep track of files added date


distance_matrix_recent.m <- distance_matrix.m[distance_matrix.m$Sample1 != distance_matrix.m$Sample2,]
distance_matrix_recent.m <- distance_matrix_recent.m[distance_matrix_recent.m$Sample1 %in% head(samples_recent),]

colnames(distance_matrix_recent.m) <- c("Recent samples","All samples","Distance")

DT::datatable(distance_matrix_recent.m, filter = 'top',rownames= FALSE, escape = FALSE , options = list(
  order = list(2, 'asc')
))


# new clusters
# need file cluster old, or cluster_db with cluster number and date
# link to cluster?

# new matches
# for each cluster, show distance of new files

```


## Allele statistics


```{r allele_stats, echo=FALSE}

# allele stats

DT::datatable(allele_stats, filter = 'top',rownames= FALSE, escape = FALSE, 
          extensions = list("ColReorder" = NULL, "Buttons" = NULL, "FixedColumns" = list(leftColumns=1)),
    options = list(
                dom = 'BRrltpi',
                autoWidth=FALSE,
                scrollX = TRUE,
                order = list(list(1, 'asc'),list(5, 'desc')),
                #fixedColumns = TRUE,
                lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
                ColReorder = TRUE,
                buttons =
                  list(
                    'copy',
                    'print',
                    list(
                      extend = 'collection',
                      buttons = c('csv', 'excel', 'pdf'),
                      text = 'Download'
                    ),
                    I('colvis')
                  )
              ))


# more stats, viz


ggplot(allele_stats, aes(x=EXC)) + geom_histogram(binwidth = 10) + xlab("Number of exact matches")
ggplot(allele_stats, aes(x=LNF)) + geom_histogram(binwidth = 1) + xlab("Number of loci not found")
ggplot(allele_stats, aes(x=PLOT)) + geom_histogram(binwidth = 1) + xlab("Number of contig-tip loci (PLOT)")
ggplot(allele_stats, aes(x=NIPH)) + geom_histogram(binwidth = 1) + xlab("Number of possible paralogs")


```

### Abbreviations

*  EXC - alleles which have exact matches (100% DNA identity) with previously identified alleles

*  INF - inferred new alleles using Prodigal CDS predictions

*  LNF - loci not found. No alleles were found for the number of loci in the schema shown. This means that, for those loci, there were no BLAST hits or they were not within the BSR threshold for allele assignment.

* PLOT - possible loci on the tip of the query genome contigs (see image below). A locus is classified as PLOT when the CDS of the query genome has a BLAST hit with a known larger allele that covers the CDS sequence entirely and the unaligned regions of the larger allele exceeds one of the query genome contigs ends. This could be an artifact caused by genome fragmentation resulting in a shorter CDS prediction by Prodigal. To avoid locus misclassification, loci in such situations are classified as PLOT.

*  NIPH - non-informative paralogous hit (see image below). When ≥ 2 CDSs in the query genome match one locus in the schema with a BSR > 0.6, that locus is classified as NIPH. This suggests that such locus can have paralogous (or orthologous) loci in the query genome and should be removed from the analysis due to the potential uncertainty in allele assignment (for example, due to the presence of multiple copies of the same mobile genetic element (MGE) or as a consequence of gene duplication followed by pseudogenization). A high number of NIPH may also indicate a poorly assembled genome due to a high number of smaller contigs which result in partial CDS predictions. These partial CDSs my contain conserved domains that match multiple loci. This classification takes precedence over PLOT classification.
* NIPHEM - similar to NIPH classification (NIPH with exact match), but specifically referring to exact matches. Whenever > 1 CDS matches different alleles of the same locus with 100% DNA similarity during the first DNA sequence comparison, the NIPHEM tag is attributed. The loci classified as NIPHEM are included in NIPH statistics file column, but represent a distinct classification in the MLST profile.

    
* ALM - alleles 20% larger than length mode of the distribution of the matched loci (CDS length > (locus length mode + locus length mode * 0.2)) (see image below). This determination is based on the currently identified set of alleles for a given locus.
* ASM - similar to ALM but for alleles 20% smaller than length mode distribution of the matched loci (CDS length < (locus length mode - locus length mode * 0.2)).


See [here](https://github.com/B-UMMI/chewBBACA/wiki/2.-Allele-Calling) for more details.

* Fraction of loci found - Sum of EXC and INF

* Fraction of loci missing - 1 _minus_ Sum of EXC and INF

* Loci removed by length -  Loci removed due to frameshiftering filter (if applied). Loci strongly deviate from median locus length - as specified in the parameters. This filter is stricter than ALM and ASM and does not appear in _Fraction of loci missing_


## Allele distance table

Table of all pairwise allele distances.

`r if(distance_table_reduced){paste("Distances above",distance_limit,"have been omitted for smooth usability. Hence, missing pairs have an allele distance larger than",distance_limit,".")} else {"All distances are displayed."}`

The number of loci in the scheme is `r locus_count`. Allele differences should be interpreted relative to the number of loci!


```{r distance_table, echo=FALSE}

distance_matrix_noself.m <- distance_matrix.m[distance_matrix.m$Sample1 != distance_matrix.m$Sample2,]

# omit large distances
distance_matrix_noself_unfiltered.m <- distance_matrix_noself.m

if(distance_table_reduced){
  #print(paste("distance_limit reduced to", distance_limit)  )    
  print(paste("Distances above",distance_limit,"have been omitted for smooth usability. Hence, missing pairs have an allele distance larger than",distance_limit,"."))
  
  distance_matrix_noself.m <- distance_matrix_noself.m[distance_matrix_noself.m$Distance < distance_limit,]  
} else {
  print("All distances are displayed.")
}


DT::datatable(distance_matrix_noself.m, filter = 'top',rownames= FALSE, escape = FALSE, 
    options = list(
                dom = 'BRrltpi',
                scrollX = TRUE,
                order = list(list(2, 'asc')),
                lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
                buttons =
                  list(
                    'copy',
                    'print',
                    list(
                      extend = 'collection',
                      buttons = c('csv', 'excel', 'pdf'),
                      text = 'Download'
                    ),
                    I('colvis')
                  )
              ))


```

```{r distance_histogram, echo=FALSE}
ggplot(distance_matrix_noself.m, aes(x=Distance)) + geom_histogram(binwidth = 1) + xlab("Allele distance") + ggtitle("Histogram of allele distances")
```

## Allele distance matrix

`r if (length(samples) > 100) {"Since more than 100 samples are present, the (static) allele distance matrix is not plotted."} else {"The pairwise distance matrix has been clustered and colored to visualize similarity of groups of closely related strains."}`


```{r distance_matrix, echo=FALSE}

if (length(samples) <= 100) {
  p1b <- plot_distance_matrix(distance_matrix)
  p1b
}


a <- list(
  title = "Sample",
  showticklabels = TRUE,
  tickangle = 45
)

# interactive allele distance matrix
 p2 <- plot_ly(x=distance_matrix_noself_unfiltered.m$Sample1,y=distance_matrix_noself_unfiltered.m$Sample2,z=distance_matrix_noself_unfiltered.m$Distance, type = "heatmap") %>%
 layout(xaxis = a, yaxis = a, showlegend = TRUE)
 p2


```

## Clustering

The clustering is based on the allele distance matrix.

The allele distance matrix was hierarchically clustered using `r paste0(clustering_method,"-linkage")` clustering and the subsequent clustering was divided into different sub-clusters at the chosen thresholds: `r paste(clustering_threshold_range,collape=",") `. At each threshold, samples are assigned to a cluster - resulting in a cluster member number. Searching the following table provides information which samples cluster together at a chosen allele threshold.

The combined cluster member numbers at all chosen threshold correspond to the cluster address.

Note that the cluster member numbers (cluster address) may be subject to change every time the clustering is run again!

The entire tree as well as the individual trees can be exported and visualized - together with relevant metadata - in interactive tools such as grapetree, phandango etc. The files were exported to the directory `r exportpath`


```{r visualize_clustering}

DT::datatable(cluster_address_matrix_augmented, caption = "Cluster membership", filter = 'top',rownames= FALSE, escape = FALSE, 
          extensions = list("ColReorder" = NULL, "Buttons" = NULL, "FixedColumns" = list(leftColumns=1)),
    options = list(
                dom = 'BRrltpi',
                #autoWidth=FALSE,
                scrollX = TRUE,
                #fixedColumns = TRUE,
                lengthMenu = list(c(10, 50, -1), c('10', '50', 'All')),
                #ColReorder = TRUE,
                buttons =
                  list(
                    'copy',
                    'print',
                    list(
                      extend = 'collection',
                      buttons = c('csv', 'excel', 'pdf'),
                      text = 'Download'
                    ),
                    I('colvis')
                  )
              ))

# print table of cluster sizes for all thresholds
knitr::kable(clustering_summary,row.names = F)

```




### Details of clustering analysis using a cluster threshold of `r distance_threshold`

In the following, the clustering analysis is visualized as a `r paste0(clustering_method,"-linkage tree")`. At a cluster threshold of `r distance_threshold`, the tree is divided int sub-clusters (cluster types), indicated by the coloring of the branches.

```{r cluster_viz_details}

#color_value <- subcluster_counts[as.character(distance_threshold)]
color_value <- 3

if (length(phylo$tip.label) > 500) {
    my_cex_tiplabel <- 0.1
    my_cex_edgelabel <- 0.1
  } else if (length(phylo$tip.label) > 150) {
    my_cex_tiplabel <- 0.3
    my_cex_edgelabel <- 0.3
      } else if (length(phylo$tip.label) > 50) {
    my_cex_tiplabel <- 0.5
    my_cex_edgelabel <- 0.5
    } else{
    my_cex_tiplabel <- 0.8
    my_cex_edgelabel <- 0.8
  }


dendro %>% set("labels_cex", my_cex_tiplabel) %>% set("labels_col", value = rainbow(color_value), h=distance_threshold) %>% set("branches_k_color", value = rainbow(color_value), h = distance_threshold) %>% 
  plot(main = paste("Tree resulting from clustering analysis"), sub = paste("Colored by using cluster threshold of",distance_threshold), horiz = T, xlab = "Clustering threshold", ylab = "Samples")
abline(v= distance_threshold, col = 8 , lwd = 3)

```




```{r cluster_viz_overview_2}
### `r paste0(clustering_method,"-linkage tree")`

# Shown here is the `r paste0(clustering_method,"-linkage tree")` with the branch length defined by the allele distance.


  # edge_color <- ifelse(phylo$edge.length<1,"white","red") 
  # tip_color <- "black"
  # plot(phylo, main = paste0(clustering_method,"-linkage tree"), cex=my_cex_tiplabel, tip.color = tip_color)
  # edgelabels(round(phylo$edge.length, 0), srt = 0, bg = "white", adj = c(0.5,1), col = edge_color, cex = my_cex_edgelabel, frame = "none")

```

### Cluster details

Shown here are the tree structures of the `r paste0(clustering_method,"-linkage tree")` for every sub-cluster defined by an allele distance of `r distance_threshold`. Clusters containing only a single sample are excluded.

Note that the cluster numbers can be looked up in the _cluster membership_ table above - in the field `r paste0("threshold_",distance_threshold)`. Furthermore, in the colored tree visualized above, every neighboring cluster is colored with a different color - starting with cluster 1 at the bottom.


```{r cluster_viz_details_3, results="asis"}

dendro_cut <- cut(dendro, h = distance_threshold)
clusters_notplotted <- c()

#par_default <- par()
par(mar=c(2,2,4.1,6.1))

for (subtree in 1:length(dendro_cut$lower)){  
  dend <- dendro_cut$lower[[subtree]]
  
  cluster_size <- dend %>% get_nodes_attr("label") %>% (function(x) x[!is.na(x)]) %>% length
  if(cluster_size > 1){
    
  cat("\n")
  cat(paste("###","Cluster",subtree))
  cat("\n")

    
    plot(dend, horiz = T, main = paste("Subtree for cluster",subtree))
  } else {
    clusters_notplotted <- c(clusters_notplotted,subtree)
  }
}

# unplotted clusters


```


The following clusters - only containing single samples - were not plotted: `r paste(clusters_notplotted, collapse = ",")`

```{r export_clustering}

if(export){

  dir.create(exportpath, showWarnings = F)

# export clustering
ape::write.tree(as.phylo(dendro), file = file.path(exportpath,"clustering_global.tre"))


# export cluster memberships
write.table(cluster_address_matrix_augmented, file = file.path(exportpath, "cluster_addresses.tsv"), sep = "\t", col.names = sub("Sample","ID",colnames(cluster_address_matrix_augmented)), row.names = F, quote = F)

# export subtrees

# for (subtree in 1:length(dendro_cut$lower)){  
#   dend <- dendro_cut$lower[[subtree]]
#   treefile_sub <- file.path(exportpath,paste0("clustering_subtree_",subtree,".tre"))
#   cluster_size <- dend %>% get_nodes_attr("label") %>% (function(x) x[!is.na(x)]) %>% length
# }


}

```


## Minimum-spanning tree
A minimum spanning tree was computed based on the allele profiles using _grapetree_.

Note that you can visualize the tree more interactively and combine it with metadata using tools such as _grapetree_ or _phandango_. Large plots may not be optimally plotted here.


```{r trees3, echo=FALSE, out.width = "100%"}  


  if (length(nwk$tip.label) > 200) {
    plot_label_size <- 1  
  } else if (length(nwk$tip.label) > 50) {
    plot_label_size <- 2  
  } else {
    plot_label_size <- 3
  }
  
  ggtree(nwk) + geom_tiplab(size=plot_label_size) + theme_tree2() + labs(caption="allele distance")

```

## Links to files

All data is available at `r workdir`.

The exported clustering files are in `r exportpath`

```{r file_info}



file_timestamps <- data.frame(
  name=c(
"distance matrix (as provided by grapetree)",
"distance matrix (with header and tab separated)",
"Minimum spanning tree"
  ),
  file=c(
distance_matrix_file,
distance_matrix_out,
nwk_file
)
)

file_timestamps$Link <- paste0("<a href=",file_timestamps$file,">",file_timestamps$name,"</a>")

knitr::kable(file_timestamps, caption = "Overview of files used for this report and their modification date")
  

#exportpath
 if(export){
   file_timestamps_2 <- data.frame(
  name=list.files(exportpath, full.names = F),
  file= list.files(exportpath, full.names = T))

   file_timestamps_2$Link <- paste0("<a href=",file_timestamps_2$file,">",file_timestamps_2$name,"</a>")

   
      knitr::kable(file_timestamps_2, caption = "Overview of files related to clustering")
 }
  


```

## Config and parameters
All  parameters are defined in the file config.yaml:


```{r }

print(parameters)


```

The individual tools and their versions are listed in the .yaml files in the directory `env`

## Help


### Grapetree instructions
* Download / copy minimum spanning tree
* Open grapetree
* Load tree file
* Load one or more metadata tsv files with the sample name in the first column (e.g. bakcharak summary data, geospatial/temporal metadata)
* E.g. subset data to particular clade and export data as json for sharing

### Other tools
* iTOL
* phandango
* phyloViz

