## ----setup, echo = FALSE, eval = TRUE, include = FALSE------------------------
# Set global options
knitr::opts_chunk$set(eval = TRUE, include = TRUE, echo = TRUE, message = FALSE, warning = FALSE, error = FALSE, dpi = 72)
# Define custom hooks for handling errors, warnings, and messages during knitting
knitr::knit_hooks$set(
   error = function(x, options){
     paste('\n\n<div class="alert alert-danger">',
           gsub('##', '\n', gsub('^##\ Error', '**Error**', x)),
           '</div>', sep = '\n')},
   warning = function(x, options){
     paste('\n\n<div class="alert alert-warning">',
           gsub('##', '\n', gsub('^##\ Warning:', '**Warning**', x)),
           '</div>', sep = '\n')},
   message = function(x, options){
     paste('\n\n<div class="alert alert-info">',
           gsub('##', '\n', x),
           '</div>', sep = '\n')})

#Load AntibodyForests functions
devtools::load_all(".")

## ----eval = FALSE-------------------------------------------------------------
# #Install from CRAN
# install.packages("Platypus")
# install.packages("AntibodyForests")

## ----eval = FALSE-------------------------------------------------------------
# #Load the libraries
# library(Platypus)
# library(AntibodyForests)

## ----installation, echo = FALSE, eval = FALSE---------------------------------
# # List of CRAN packages required to run all functions
# CRAN_packages <- c("Platypus", "alakazam", "ape", "base",
#                    "base64enc", "BiocManager", "dplyr",
#                    "grDevices", "gtools", "igraph",
#                    "jsonlite", "knitr", "parallel",
#                    "phangorn", "scales", "stats",
#                    "stringdist", "stringr", "utils")
# 
# # List of Bioconductor packages required to run all functions
# Bioconductor_packages <- c("Biostrings", "msa")
# 
# # Iterate through packages
# for(package in c(CRAN_packages, Bioconductor_packages)){
#   # Check if the current packages is already installed
#   if(!requireNamespace(package, quietly = TRUE)){
#     # Install CRAN packages if not installed
#     if(package %in% CRAN_packages){install.packages(package)}
#     # Install Bioconductor packages if not installed
#     if(package %in% Bioconductor_packages){BiocManager::install(package)}
#   }
# }
# 

## ----quick-start1, eval = FALSE-----------------------------------------------
# # Import 10x Genomics output files into VDJ dataframe and only keep cells with one VDJ and one VJ transcript
# # For each clone, trim germline sequence
# VDJ_OVA <- Platypus::VDJ_build(VDJ.directory = "10x_output/VDJ/",
#                      remove.divergent.cells = TRUE,
#                      complete.cells.only = TRUE,
#                      trim.germlines = TRUE)
# 
# # Build lineage trees for all clones present in the VDJ dataframe with the default algorithm
# AntibodyForests_OVA_default <- Af_build(VDJ = VDJ_OVA,
#                                           construction.method = "phylo.network.default")

## ----quick-start2, eval = F---------------------------------------------------
# # Plot one of the lineage trees, constructed with the `phylo.network.default' method
# Af_plot_tree(AntibodyForests_object = AntibodyForests_OVA_default,
#                      sample = "S1",
#                      clonotype = "clonotype3")

## ----quick-start3, eval = F---------------------------------------------------
# # Cluster the trees in the repertoire based on the euclidean distance between various metrics of each tree
# out <- Af_compare_within_repertoires(input = AntibodyForests_OVA_default,
#                                      min.nodes = 5,
#                                      distance.method = "euclidean",
#                                      distance.metrics = c("mean.depth", "sackin.index", "spectral.density"),
#                                      clustering.method = "mediods",
#                                      visualization.methods = "PCA",
#                                      plot.label = T)
# 
# # Analyze the difference between the clusters based on the calculated sackin.index
# plots <- Af_cluster_metrics(input = AntibodyForests_OVA_default,
#                    clusters = out$clustering,
#                    metrics = c("spectral.density"),
#                    min.nodes = 5,
#                    significance = T)
# 

## ----quick-start4, eval=FALSE-------------------------------------------------
# # Plot the PCA colored on the assigned clusters
# out$plots$PCA_clusters

## ----quick-start5, eval=FALSE-------------------------------------------------
# # Plot the different number of modalities between the clusters
# plots$modalities

## ----vdj_build-example-3-code, eval = FALSE-----------------------------------
# # Read in data, keep only complete, non-divergent cells and trim germline sequences
# VDJ_OVA <- Platypus::VDJ_build(VDJ.directory = "10x_output/VDJ/",
#                      remove.divergent.cells = TRUE,
#                      complete.cells.only = TRUE,
#                      trim.germlines = TRUE,
#                      fill.germline.CDR3 = TRUE)

## ----vdj_build-example-3-message, echo = FALSE, results = "asis"--------------
# Print number of filtered cells/barcodes 
warning("Please be aware of the number of cells excluded, when 'remove.divergent.cells' or 'complete.cells.only' is set to TRUE:\n")
print(knitr::kable(data.frame(divergent.cells = c(360, 295, 79, 183 ,526), 
                              incomplete.cells = c(708, 503, 387, 380, 1113),
                              row.names = c("S1", "S2", "S3", "S4", "S5"))))

## ----vdj_build-example-3-df, echo = FALSE-------------------------------------
# Load the example VDJdataframe
load("objects/VDJ_OVA_dummy_3.RData")
knitr::kable(head(VDJ_OVA_dummy_3[,c("sample_id", "barcode", "isotype", "clonotype_id", "clonotype_frequency", "VDJ_vgene", "VDJ_jgene")], 10))

## ----AntibodyForests-example-default, eval = FALSE----------------------------
# # Infer lineage trees for all clones using the 'phylo.network.default' construction method and using all default parameter settings
# AntibodyForests_OVA_default <- Af_build(VDJ = VDJ_OVA,
#                                                sequence.columns = c("VDJ_sequence_nt_trimmed", "VJ_sequence_nt_trimmed"),
#                                                germline.columns = c("VDJ_germline_nt_trimmed", "VJ_germline_nt_trimmed"),
#                                                concatenate.sequences = FALSE,
#                                                node.features = "isotype",
#                                                construction.method = "phylo.network.default",
#                                                string.dist.metric = "lv",
#                                                resolve.ties = c("max.expansion", "close.germline.dist", "close.germline.edges", "random"),
#                                                parallel = TRUE)

## ----AntibodyForests-example-ML, eval = FALSE---------------------------------
# # Infer lineage trees for all clones using the 'phylo.tree.ml' construction method and using all default parameter settings
# AntibodyForests_OVA_ml <- Af_build(VDJ = VDJ_OVA,
#                                           sequence.columns = c("VDJ_sequence_nt_trimmed", "VJ_sequence_nt_trimmed"),
#                                           germline.columns = c("VDJ_germline_nt_trimmed", "VJ_germline_nt_trimmed"),
#                                           concatenate.sequences = FALSE,
#                                           construction.method = "phylo.tree.ml",
#                                           dna.model = "all",
#                                           remove.internal.nodes = "connect.to.parent",
#                                           parallel = TRUE)

## ----AntibodyForests-example-IgPhyML, eval = FALSE----------------------------
# # Infer lineage trees for all clones using the 'phylo.tree.IgPhyML' construction method and using all default parameter settings
# AntibodyForests_OVA_IgPhyML <- Af_build(VDJ = VDJ_OVA,
#                                                sequence.columns = "VDJ_sequence_nt_trimmed",
#                                                germline.columns = "VDJ_germline_nt_trimmed",
#                                                construction.method = "phylo.tree.IgPhyML",
#                                                IgPhyML.output.file = "data/OVA_scRNA-seq_data/VDJ/airr_rearrangement_igphyml-pass.tab",
#                                                remove.internal.nodes = "connect.to.parent",
#                                                parallel = TRUE)

## ----AntibodyForests_plot_ML_with_IN_example, eval = FALSE--------------------
# # Plot lineage tree, constructed with the `phylo.tree.ml' method, without internal nodes
# Af_plot_tree(AntibodyForests_object = AntibodyForests_OVA_ml,
#                      sample = "S1",
#                      clonotype = "clonotype8",
#                      show.inner.nodes = TRUE,
#                      label.by = "name",
#                      color.by = "isotype",
#                      node.size = "expansion",
#                      main.title = "Lineage tree - ML",
#                      sub.title = "OVA - S1 - clonotype8")

## ----AntibodyForests_plot_ML_without_IN_example, eval = FALSE-----------------
# # Plot lineage tree, constructed with the `phylo.tree.ml' method, without internal nodes
# Af_plot_tree(AntibodyForests_object = AntibodyForests_OVA_ml,
#                      sample = "S1",
#                      clonotype = "clonotype8",
#                      show.inner.nodes = FALSE,
#                      label.by = "name",
#                      color.by = "isotype",
#                      node.size = "expansion",
#                      main.title = "Lineage tree - ML",
#                      sub.title = "OVA - S1 - clonotype8")

## ----Af_sync_nodes, eval= FALSE-----------------------------------------------
# # Synchronize the nodes of the different AntibodyForests objects
# AntibodyForests_OVA_IgPhyML <- Af_sync_nodes(reference = AntibodyForests_OVA_default,
#                                                     subject = AntibodyForests_OVA_IgPhyML)
# AntibodyForests_OVA_mst <- Af_sync_nodes(reference = AntibodyForests_OVA_default,
#                                 subject = AntibodyForests_OVA_mst)
# AntibodyForests_OVA_nj <- Af_sync_nodes(reference = AntibodyForests_OVA_default,
#                                 subject = AntibodyForests_OVA_nj)
# AntibodyForests_OVA_mp <- Af_sync_nodes(reference = AntibodyForests_OVA_default,
#                                 subject = AntibodyForests_OVA_mp)
# AntibodyForests_OVA_ml <- Af_sync_nodes(reference = AntibodyForests_OVA_default,
#                                 subject = AntibodyForests_OVA_ml)

## ----compare_methods_example2, eval = FALSE-----------------------------------
# # Calculate the euclidean distance between different trees based on the GBLD
# out <- Af_compare_methods(input = list("Default" = AntibodyForests_OVA_default,
#                                        "MST" = AntibodyForests_OVA_mst,
#                                        "NJ" = AntibodyForests_OVA_nj,
#                                        "MP" = AntibodyForests_OVA_mp,
#                                        "ML" = AntibodyForests_OVA_ml,
#                                        "IgPhyML" = AntibodyForests_OVA_IgPhyML),
#                           min.nodes = 10,
#                           distance.method = "GBLD",
#                           visualization.methods = "heatmap",
#                           include.average = T)
# # Plot the average heatmap
# out$average$Heatmap

## ----metric_dataframe1, eval = FALSE------------------------------------------
# # Calculate the metric dataframe for the AntibodyForests object
# metric_df <- Af_metrics(input = AntibodyForests_OVA_default,
#                         min.nodes = 10,
#                         metrics = c("mean.depth", "sackin.index", "spectral.density"))
# 

## ----metric_dataframe2--------------------------------------------------------
load("objects/metric_df.RData")

## ----metric_dataframe3, echo=FALSE--------------------------------------------
# Print the dataframe
DT::datatable(data = metric_df,
              rownames = TRUE,
              options = list(scrollX = TRUE))

## ----compare_distance_isotype, eval=FALSE-------------------------------------
# # Cluster the trees in the repertoire based on the euclidean distance between various metrics of each tree
# Af_distance_boxplot(AntibodyForests_object = AntibodyForests_OVA_default,
#                     node.feature = "isotype",
#                     distance = "node.depth",
#                     min.nodes = 8,
#                     groups = c("IgG1", "IgA"),
#                     text.size = 16,
#                     unconnected = T,
#                     significance = T)

## ----compare_within_repertoire_example1, eval = FALSE-------------------------
# # Cluster the trees in the repertoire based on the euclidean distance between various metrics of each tree
# out <- Af_compare_within_repertoires(input = AntibodyForests_OVA_default,
#                                      min.nodes = 8,
#                                      distance.method = "euclidean",
#                                      distance.metrics = c("mean.depth", "sackin.index", "spectral.density"),
#                                      clustering.method = "mediods",
#                                      visualization.methods = "PCA")
# # Plot the PCA colored on the assigned clusters
# out$plots$PCA_clusters

## ----cluster_metrics_example1, eval = FALSE-----------------------------------
# # Analyze the difference between the clusters based on the calculated sackin.index
# plots <- Af_cluster_metrics(input = AntibodyForests_OVA_default,
#                    clusters = out$clustering,
#                    metrics = c("sackin.index", "spectral.density"),
#                    min.nodes = 8,
#                    significance = T)
# 
# plots$sackin.index
# plots$modalities

## ----cluster_node_features_example1, eval = FALSE-----------------------------
# # Analyze the difference between the clusters based on the calculated sackin.index
# plots <- Af_cluster_node_features(input = AntibodyForests_OVA_default,
#                    clusters = out$clustering,
#                    features = "isotype",
#                    fill = "max",
#                    significance = T)
# 
# plots$isotype

## ----compare_within_repertoire_example2, eval = FALSE-------------------------
# # Cluster the trees in the repertoire based on the Jensen-Shannon divergence between the Spectral Density profiles
# out <- Af_compare_within_repertoires(input = AntibodyForests_OVA_default,
#                                      min.nodes = 8,
#                                      distance.method = "jensen-shannon",
#                                      clustering.method = "mediods",
#                                      visualization.methods = "heatmap")
# # Plot the heatmap
# out$plots$heatmap_clusters

## ----cluster_metrics_example2, eval=FALSE-------------------------------------
# # Analyze the difference between the clusters
# plots <- Af_cluster_metrics(input = AntibodyForests_OVA_default,
#                    clusters = out$clustering,
#                    metrics = "spectral.density",
#                    min.nodes = 8,
#                    significance = T)
# 
# plots$spectral.asymmetry
# plots$modalities

## ----compare_across_repertoire_example1, eval=FALSE---------------------------
# #Calculate the difference between the two groups of repertoires
# boxplots <- Af_compare_across_repertoires(list("Blood" = AntibodyForests_example_blood,
#                                                "Lymph Nodes" = AntibodyForests_example_LN),
#                                           metrics = c("betweenness", "mean.depth"), significance = T)
# 
# #Plot the boxplots
# boxplots$betweenness
# boxplots$mean.depth

## ----add_pseudolikelihood_example, eval=FALSE---------------------------------
# # Add pseudolikelihood as node feature to the AntibodyForests object
# AntibodyForests_OVA_default <- Af_add_node_feature(AntibodyForests_object = AntibodyForests_OVA_default,
#                                                                 feature.df = VDJ_OVA,
#                                                                 feature.names = "pseudolikelihood")

## ----plot_pseudolikelihood_example1, eval=FALSE-------------------------------
# # Plot pseudolikelihood against distance to the germline
# Af_distance_scatterplot(AntibodyForests_object = AntibodyForests_OVA_default,
#                                      node.features = "pseudolikelihood",
#                                      distance = "edge.length",
#                                      min.nodes = 5,
#                                      correlation = "pearson",
#                                      color.by = "sample")

## ----get_sequences_probability_example, eval=FALSE----------------------------
# #Create a dataframe of the sequences with a sequence ID containing the sample, clonotype, and node number
# df <- Af_get_sequences(AntibodyForests_object = AntibodyForests_OVA_default,
#                                                sequence.name = "VDJ_sequence_aa_trimmed",
#                                                min.edges = 1)
# #Save the data frame as CSV to serve as input for the PLM-pipeline
# write.csv(df, file = "/directory/PLM_input.csv", row.names = FALSE)

## ----probability_matrix_example, eval=FALSE-----------------------------------
# #Create a PLM dataframe
# PLM_dataframe <- Af_PLM_dataframe(AntibodyForests_object = AntibodyForests_OVA_default,
#                                                sequence.name = "VDJ_sequence_aa_trimmed",
#                                                path_to_probabilities = "/directory/ProbabilityMatrix")

## ----load_plm_dataframe, echo=FALSE-------------------------------------------
load("objects/PLM_dataframe.RData")

## ----vdj_plm-df, echo = FALSE-------------------------------------------------
knitr::kable(PLM_dataframe)

## ----plot_likelihood_example1, eval = FALSE-----------------------------------
# # Plot the substitution rank
# Af_plot_PLM(PLM_dataframe = PLM_dataframe,
#                          values = "substitution_rank",
#                          group_by = "sample_id")

## ----load_structure_data, echo=FALSE------------------------------------------
load("objects/VDJ_ova_structure.RData") #vdj
load("objects/VDJ_structure_AbAg.RData") #vdj_structure_AbAg
load("objects/AntibodyForests_OVA_structure_AbAg.RData") #af_structure_AbAg

## ----structure_example2, eval = F---------------------------------------------
# #Biophysical properties of the heavy and light chain sequence of the antibodies are calculated
# vdj_structure_AbAg <- VDJ_3d_properties(VDJ = vdj,
#                                    pdb.dir = "~/path/PDBS_superimposed/",
#                                    file.df = files,
#                                    properties = c("charge",
#                                                   "3di_germline",
#                                                   "hydrophobicity",
#                                                   "RMSD_germline",
#                                                   "pKa_shift",
#                                                   "free_energy",
#                                                   "pLDDT"),
#                                    chain = "whole.complex",
#                                    sequence.region = "binding.residues",
#                                    propka.dir = "~/path/Propka_output/",
#                                    germline.pdb = "~/path/PDBS_superimposed/germline_5_model_0.pdb",
#                                    foldseek.dir = "~/path/3di_sequences/")
# 
# #Add the biophysical properties to the AntibodyForests object
# af_structure_AbAg <- Af_add_node_feature(AntibodyForests_object = af,
#                                                  feature.df = vdj_structure_AbAg,
#                                                  feature.names = c("average_charge",
#                                                                    "3di_germline",
#                                                                    "average_hydrophobicity",
#                                                                    "RMSD_germline",
#                                                                    "average_pKa_shift",
#                                                                    "free_energy",
#                                                                    "average_pLDDT"))

## ----structure_example4_plot, eval = T, fig.width=5, fig.height=5-------------
Af_distance_scatterplot(af_structure_AbAg,
                        node.features = "free_energy",
                        correlation = "pearson",
                        color.by = "average_pLDDT",
                        color.by.numeric = T,
                        geom_smooth.method = "lm")

## ----plot_structure_example1, eval = F----------------------------------------
# rmsd <- Af_edge_RMSD(af,
#              VDJ = vdj,
#              pdb.dir = "~/path/PDBS_superimposed/",
#              file.df = files,
#              sequence.region = "full.sequence",
#              chain = "HC+LC")
# rmsd$plot

## ----write-AIRR-rearrangement, eval = FALSE-----------------------------------
# # Append the IgBLAST annotations and alignment to the VDJ dataframe
# VDJ_OVA <- VDJ_import_IgBLAST_annotations(VDJ = VDJ_OVA,
#                                           VDJ.directory = "../data/OVA_scRNA-seq_data/VDJ/",
#                                           method = "append")
# 
# # Write the VDJ dataframe into an AIRR-formatted TSV file
# VDJ_to_AIRR(VDJ = VDJ_OVA,
#             output.file = "../data/OVA_scRNA-seq_data/VDJ/airr_rearrangement.tsv")

## ----bulk_example, eval = FALSE-----------------------------------------------
# # Integrate bulk RNA-seq data into the VDJ dataframe, if multiple clonotypes match the bulk sequence, the bulk transcript is added to all clonotypes (tie.resolvement = "all)
# VDJ_OVA <- VDJ_integrate_bulk(sc.VDJ = VDJ_OVA,
#                    bulk.tsv = "path/to/bulk/OVA_bulkRNA.tsv",
#                    bulk.tsv.sequence.column="VDJ_sequence_nt_raw",
#                    bulk.tsv.sample.column="sample_id",
#                    bulk.tsv.barcode.column="barcode",
#                    bulk.tsv.isotype.column="isotype",
#                    organism="mouse",
#                    igblast.dir="/path/to/anaconda3/envs/igphyml/share/igblast",
#                    tie.resolvement = "all")
# 
# #Create the lineage tree of the integrated VDJ dataframe
# af <- Af_build(VDJ = VDJ_OVA,
#                sequence.columns = "VDJ_sequence_aa_trimmed",
#                germline.columns = "VDJ_germline_aa_trimmed",
#                construction.method = "phylo.network.default",
#                node.features = c("dataset"))
# 
# #Plot lineage tree
# Af_plot_tree(af,
#              sample = "S1",
#              clonotype = "clonotype3",
#              color.by = "dataset",
#              label.by = "none",
#              main.title = "OVA S1",
#              sub.title = "clonotype3")

