---
title: "Introduction to markeR"
author: "Rita M. Silva"
date: "`r Sys.Date()`"
output:
  BiocStyle::html_document:
    toc: true
    toc_depth: 3
vignette: >
  %\VignetteIndexEntry{Introduction to markeR}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---


```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = TRUE,
message = FALSE,
warning = FALSE,
results = 'markup',
dev = 'png',     # raster images to reduce HTML size
dpi = 72,
fig.retina = 1
)
```
 
# Introduction

**`markeR`** is an R package that provides a modular and extensible framework for the systematic evaluation of gene sets as phenotypic markers using transcriptomic data. The package is designed to support both quantitative analyses and visual exploration of gene set behaviour across experimental and clinical phenotypes.

In this vignette, we demonstrate the core functionalities of `markeR` using a pre-processed gene expression dataset and associated metadata from Marthandan et al. (2016) (GSE63577). This dataset comprises human fibroblast samples cultured under two experimental conditions: replicative senescence and proliferative control.

## Primary Objectives

The primary objectives of **`markeR`** are to:

- Establish a reproducible and standardised framework for quantifying gene sets as phenotypic markers across transcriptomic datasets.
- Provide a unified interface for complementary analytical strategies, including score-based and enrichment-based methods.
- Enable systematic comparison of user-defined gene sets with curated reference collections (e.g., MSigDB) to enhance biological interpretability.
- Deliver modular tools for visualisation and evaluation, allowing exploration of both gene set behaviour and individual gene-level contributions. 

## Features and Capabilities

The package integrates multiple analytical strategies for quantifying phenotypes using gene sets, supporting both unidirectional and bidirectional (*i.e.*, respectively without and with information on the expected direction of change in expression of genes upon phenotype) gene set definitions:

- **Score-based methods**:  log2-median expression, ranking approaches, and single-sample gene set enrichment analysis (ssGSEA) to quantify coordinated expression within a gene set.
- **Enrichment-based methods**: GSEA using moderated t- or B-statistics.
- **Gene-level exploration**: expression heatmaps, violin plots, ROC curve analysis, area under the curve (AUC) calculations, effect size estimation, and principal component analysis (PCA) to characterise the contribution of individual genes.
- **Gene set similarity assessment**: Jaccard index and log odds ratio (logOR) calculations to compare user-defined gene sets with reference or user-defined collections.

The package is implemented with flexibility and extensibility as core design principles. Visualisation leverages `ggplot2`, `ComplexHeatmap`, `ggpubr`, `cowplot`, and `grid`, enabling a wide range of customisation options. The modular structure ensures compatibility with additional methods in future versions of the package.

# Installation

Install the latest release from Bioconductor:

```{r, eval=FALSE}
# Install from Bioconductor
if (!requireNamespace("BiocManager", quietly = TRUE))
  install.packages("BiocManager")
BiocManager::install("markeR")
```

Or install the latest development release of `markeR` from [GitHub](https://github.com/) with:

```r
devtools::install_github("DiseaseTranscriptomicsLab/markeR@*release")
```

```{r, echo=FALSE} 
library(markeR)
```
# Common Workflow

## Input Requirements
 
### Gene Sets

A named list where each element is a gene set.

- Use a **character vector** when putative direction of change in expression of genes upon phenotype is unknown (unidirectional).
- Use a **data frame** with columns `gene` and `direction` (values `+1` for up-, `-1` for down-regulation) when direction is known (bidirectional).

```{r example-gene-sets-vector, echo=FALSE}
# Gene set without direction
gene_set1 <- c("GeneA", "GeneB", "GeneC", "GeneD")

# Gene set with direction
gene_set2 <- data.frame(
  gene = c("GeneX", "GeneY", "GeneZ"),
  direction = c(1, -1, 1),
  stringsAsFactors = FALSE
)

# Combine both into a named list
gene_sets <- list(
  Set1 = gene_set1,
  Set2 = gene_set2
)
```

```{r show-gene-set, echo=TRUE}
# Example
gene_sets
```

For this vignette, we will use three senescence-related gene sets that ship with the package (see `?genesets_example` for more information):

* **LiteratureMarkers** (bidirectional; gene set of commonly reported senescence markers in the literature)
* **REACTOME_CELLULAR_SENESCENCE** (unidirectional; from the MSigDB database)
* **HernandezSegura** (bidirectional; from [Hernandez-Segura et al. (2017)](https://pubmed.ncbi.nlm.nih.gov/28844647/))

```{r loadsig}
# Load example gene sets
data(genesets_example)
```

### Expression Data Frame

A filtered and normalised, non log-transformed, gene expression matrix (genes × samples). Row names must be gene identifiers; column names must match sample IDs in the metadata.

**Warning:** If you are using microarray data or outputs from common RNA-seq pipelines (*e.g.*, edgeR), note that the expression values may already be log2-normalised. The input to `markeR` must necessarily be **non-log-transformed**. If your data are log2-transformed, you can revert them by applying `2^data`.


In this vignette, we use a pre‑processed RNA-seq dataset from Marthandan et al. (2016, GSE63577), with normalised read counts for human fibroblasts under **replicative senescence** and **proliferative control**. See `?counts_example` for structure.

```{r loaddata}
# Load example expression data
data(counts_example)
counts_example[1:5, 1:5]
```

### Sample Metadata

A data frame with samples as rows and annotations as columns. The first column should contain sample IDs matching the expression matrix column names.

We use the accompanying metadata from the Marthandan et al. (2016) study. See `?metadata_example`.

```{r load_metadata}
# Load example metadata
data(metadata_example)
head(metadata_example)
```

## Select Mode of Analysis

`markeR` provides two modes of operation:

* **Benchmarking**:
evaluates gene sets' performance in marking a metadata variable, *i.e.*, a phenotype, returning comparative visualisations across scoring and enrichment methods.

* **Discovery**:
examines the relationship between a gene set and one or more variables of interest, suitable for exploratory or hypothesis-generating analyses. 
 
## Choose a Quantification Approach

Two complementary strategies are implemented for quantifying associations between gene sets and phenotypes:

### Score-Based Approach

A score summarising the collective expression of a gene set therein is assigned **to each sample**. Scores can be visualised using built-in functions, or used directly in downstream analyses (*e.g.*, comparisons between phenotypic groups of samples, correlations with numerical phenotypes). 

Available methods:

* **Log2-median**: mean of the across-sample normalised log2 median-centred expression levels of the genes in the set; for bidirectional gene sets, the sample score is the partial score for the subset of putatively upregulated genes minus that of the downregulated subset.

* **Ranking**: mean expression rank of gene set members in each sample; for bidirectional gene sets, the sample score is the partial score for the subset of putatively upregulated genes minus that of the downregulated subset, and normalised by the number of genes in the set. 

* **ssGSEA**: single-sample gene set enrichment score using ssGSEA; for bidirectional gene sets, the sample score is the partial score for the subset of putatively upregulated genes minus that of the downregulated subset.

Gene sets that are robust phenotypic markers are expected to yield consistently high scores across methods.

### Enrichment-Based Approach

Enrichment-based methods implement **Gene Set Enrichment Analysis (GSEA)**. Genes are ranked according to differential expression statistics, and a Normalised Enrichment Score (NES) per variable of interest is computed, accompanied by a p-value adjusted for multiple hypothesis testing.

## Visualisation and Evaluation

### Benchmarking Mode

`markeR` offers a range of visual summaries for Benchmarking:

* Violin plots of score distributions by categorical phenotype;
* Scatter plots of association between scores and numerical phenotypes;
* Volcano plots and heatmaps of scores or differential gene set expression based on effect sizes (Cohen’s *d* or *f*);
* ROC curves and respective AUC values of gene sets' phenotypic classification performance;
* Violin plots of effect size distributions (Cohen’s *d*) for pairwise group differences in scores, for original and simulated gene sets;
* Plots summarising NES alongside adjusted p-values (*e.g.*, lollipop plots); 
* GSEA plots showing running enrichment scores across ranked gene lists.

Example of common workflows in Benchmarking Mode (full tutorial [here][tutorial-benchmarking]):

#### Score-based approaches

Score-based methods facilitate direct comparisons of gene set activity between phenotypic groups (*e.g.*, being senescent) and can be used in downstream analyses, including for example correlation with other metadata variables of interest (*e.g.*, day of sequencing) .
We first compute log2-median scores. In this dataset, the HernandezSegura and LiteratureMarkers gene sets yield large effect sizes (|Cohen’s d|), whereas REACTOME_CELLULAR_SENESCENCE shows more modest separation between senescent and proliferative fibroblasts. 

```{r fig.width=8, fig.height=4, warning=FALSE, message=FALSE}
# Quantification approach: scores
# Method: log2-median 
PlotScores(data = counts_example, 
           metadata = metadata_example, 
           gene_sets = genesets_example, 
           Variable="Condition",  
           method ="logmedian",    
           nrow = 1,    
           pointSize=4,  
           title="Marthandan et al. 2016", 
           widthTitle = 24,
           labsize=12, 
           titlesize = 12)  

```


Next, scores are calculated using multiple methods (log2-median, ranking, ssGSEA) to assess consistency across strategies. Outputs include heatmaps and volcano plots of effect sizes (|Cohen’s d|). HernandezSegura and LiteratureMarkers consistently discriminate Senescent from Proliferative samples, while REACTOME_CELLULAR_SENESCENCE shows weaker and less consistent separation.


```{r warning=FALSE, message=FALSE}
Overall_Scores <- PlotScores(data = counts_example, 
                             metadata = metadata_example,  
                             gene_sets=genesets_example, 
                             Variable="Condition",  
                             method ="all",   
                             ncol = NULL, 
                             nrow = 1, 
                             widthTitle=30, 
                             limits = c(0,3.5),   
                             title="Marthandan et al. 2016", 
                             titlesize = 10,
                             ColorValues = list(heatmap=c("#F9F4AE", "#B44141"),
                                                volcano=signature_colors <- c(
                                                  HernandezSegura = "#A07395",               
                                                  REACTOME_CELLULAR_SENESCENCE = "#6B8E9E",  
                                                  LiteratureMarkers = "#CA7E45"             
                                                )
                             ),
                             mode="simple",
                             widthlegend=30, 
                             sig_threshold=0.05, 
                             cohen_threshold=0.6,
                             pointSize=6,
                             colorPalette="Paired")  
```

```{r Overall_Scores_heatmap, fig.width=10, fig.height=2, warning=FALSE, message=FALSE}
Overall_Scores$heatmap
```

```{r Overall_Scores_volcano, fig.width=6, fig.height=3, warning=FALSE, message=FALSE}
Overall_Scores$volcano
```

The discriminatory capacity of gene set scores can also be assessed using ROC curves and corresponding AUC values. HernandezSegura and LiteratureMarkers exhibit consistently high AUCs across scoring methods, while REACTOME_CELLULAR_SENESCENCE shows more heterogeneous performance.

```{r roc_scores, fig.width=10, fig.height=3, warning=FALSE, message=FALSE}
ROC_Scores(data = counts_example, 
           metadata = metadata_example, 
           gene_sets=genesets_example, 
           method = "all", 
           variable ="Condition",
           colors = c(logmedian = "#3E5587", ssGSEA = "#B65285", ranking = "#B68C52"), 
           grid = TRUE, 
           spacing_annotation=0.3, 
           ncol=NULL, 
           nrow=1,
           mode = "simple",
           widthTitle = 28,
           titlesize = 10,  
           title="Marthandan et al. 2016") 

```

Finally, false positive rates for effect sizes are estimated by simulating random gene sets of equal size. This step provides a null distribution against which observed scores can be compared. In this example, the LiteratureMarkers signature demonstrates the strongest performance. Increasing the number of simulations would yield finer resolution at the cost of additional computational time.

```{r FDRSim, fig.width=12, fig.height=3,warning=FALSE, message=FALSE}
set.seed("123456")
FPR_Simulation(data = counts_example,
               metadata = metadata_example,
               original_signatures = genesets_example,
               gene_list = row.names(counts_example),
               number_of_sims = 100,
               title = "Marthandan et al. 2016",
               widthTitle = 30,
               Variable = "Condition",
               titlesize = 12,
               pointSize = 5,
               labsize = 10,
               mode = "simple",
               ColorValues=NULL,
               ncol=NULL, 
               nrow=1 ) 

```


#### Enrichment-based approaches
 
The first step is the quantification of differential expression. Here, a design matrix (as defined by the `limma` package) is automatically constructed from the `Condition` variable in the metadata, defining the contrast `Senescent - Proliferative`. Internally, this fits a linear model without an intercept, enabling quick comparison between levels of a categorical variable. 

```{r DEGs, fig.width=10, fig.height=3, warning=FALSE, message=FALSE}
# Build design matrix from variables (Condition) and apply a contrast.
# The design matrix is constructed automatically using the variable "Condition".
DEGs <- calculateDE(data = counts_example,
                    metadata = metadata_example,
                    variables = "Condition",
                    contrasts = c("Senescent - Proliferative"))
DEGs$`Senescent-Proliferative`[1:5,]
```

Differential expression results can be visualised with volcano plots. These highlight the magnitude of expression changes (log2 fold change) against statistical significance (adjusted p-value for the moderated t-statistic), with genes from predefined sets emphasised (up- in green and downregulated in red). In this example:

* Genes in the HernandezSegura set annotated as upregulated (green) display positive log2 fold changes, whereas those annotated as downregulated (red) show negative log2 fold changes. This pattern is consistent with the annotation of the set, although these genes are not necessarily those exhibiting the largest absolute fold changes.
* In the LiteratureMarkers set, *LMNB1* and *MKI67* exhibit strongly negative log2 fold change, consistent with their roles as proliferation markers absent in senescent cells.
* Genes from the REACTOME_CELLULAR_SENESCENCE set are undirected and appear across the full range of log2 fold change values, diluting discriminatory power.


```{r DEGsvolcano, fig.width=10, fig.height=3,warning=FALSE, message=FALSE} 
# Change order: gene sets in columns, contrast in rows
plotVolcano(DEGs, genes = genesets_example, 
            N = NULL,
            x = "logFC", y = "-log10(adj.P.Val)", pointSize = 2,
            color = "#6489B4", highlightcolor = "#05254A", highlightcolor_upreg = "#038C65", highlightcolor_downreg = "#8C0303",nointerestcolor = "#B7B7B7",
            threshold_y = NULL, threshold_x = NULL,
            xlab = NULL, ylab = NULL, ncol = NULL, nrow = NULL, title = "Marthandan et al. 2016",
            labsize = 10, widthlabs = 24, invert = TRUE)
```

We next apply GSEA to the differential expression results. This evaluates whether genes from each set are non-randomly concentrated at the top or bottom of the ranked list. Results are reported as NES with multiple-testing adjusted p-values. Gene ranking can be based on alternative statistics (*e.g.*, moderated t or B-statistic), which influence whether results are interpreted as enrichment/depletion or as altered directionality. For a full example and explanation, see the online tutorial [here][tutorial-benchmarking].


```{r GSEA, warning=FALSE, message=FALSE}
GSEAresults <- runGSEA(DEGList = DEGs, 
                       gene_sets = genesets_example,
                       stat = NULL,
                       ContrastCorrection = FALSE)

GSEAresults
```
 
Enrichment curves from `fgsea` show the running enrichment score across the ranked list, indicating the distribution of set members therein.


```{r GSEA_plotenrichment, fig.width=10, fig.height=3, warning=FALSE, message=FALSE}
plotGSEAenrichment(GSEA_results=GSEAresults, 
                   DEGList=DEGs, 
                   gene_sets=genesets_example, 
                   widthTitle=40, grid = TRUE, titlesize = 10, nrow=1, ncol=3) 
```

Enrichment results can also be summarised with a lollipop plot, which compactly shows the NES and highlights statistically significant gene sets. Here, we can see that the HernandezSegura gene set clearly exhibits the strongest enrichment signal. When many gene sets and contrasts are evaluated (which is not the case in this vignette), NES and adjusted p-values can be summarized in a scatter (volcano-style) plot for a simpler visualisation, using `plotCombinedGSEA`.
 
```{r GSEA_lollypop, fig.width=5, fig.height=4, out.width="60%", warning=FALSE, message=FALSE}
plotNESlollipop(GSEA_results=GSEAresults, 
                saturation_value=NULL, 
                nonsignif_color = "#F4F4F4", 
                signif_color = "red",
                sig_threshold = 0.05, 
                grid = FALSE, 
                nrow = NULL, ncol = NULL, 
                widthlabels=13, 
                title=NULL, titlesize=12) 
```
  

From this exercise in Benchmarking Mode, we can see that two gene sets clearly perform best at discriminating between Senescent and Proliferative conditions: HernandezSegura and LiteratureMarkers. The REACTOME_CELLULAR_SENESCENCE gene set does not show a strong signal; the absense of information on putative gene up- or downregulation upon phenotype potentially dilutes the signal, highlighting the importance of providing directionality when available.

Scoring and enrichment approaches provide complementary insights. Score-based methods offer sample-level resolution, capturing strong contributions from individual genes, while enrichment-based methods evaluate coordinated behaviour across the set. 


### Discovery Mode

In **Discovery** (full tutorial [here][tutorial-discovery]), analyses focus on a single gene set of interest, providing a targeted view of its behaviour across experimental variables (*i.e.*, phenotypes). The output includes:

* Score distributions stratified by variable;
* Effect sizes for pairwise and multiple-group differences (Cohen's *d* and *f*, respectively);
* Cross-variable summaries of NES and adjusted p-values (*e.g.*, lollipop plots).

We illustrate this using the HernandezSegura gene set from our example collection:

```{r}
HernandezSegura_GeneSet <- list(HernandezSegura=genesets_example$HernandezSegura) 
```

For illustration purposes, two synthetic variables were added to the data:

* `DaysToSequencing`, the number of days between sample preparation and sequencing;
* `Researcher`, identifying the person who processed each sample.

This enables exploration of associations between gene set activity and both categorical and continuous variables.

```{r load_metadata_discovery}
data(metadata_example)
set.seed("123456")
metadata_example$Researcher <- sample(c("John","Ana","Francisca"),39, replace = TRUE)
metadata_example$DaysToSequencing <- sample(c(1:20),39, replace = TRUE)
head(metadata_example)
```

We can then examine how the gene set associates with these variables using enrichment-based approaches in Discovery Mode. The resulting plot highlights significant associations across variables and visually summarises the direction and strength of the effects. The “simple” mode provides comparison of effect sizes across pairwise contrasts between only two levels of the variable, but can be changed to more levels of comparison (see `?VariableAssociation`). 

In this example, the HernandezSegura gene set shows significant enrichment in samples sequenced by Francisca relative to those processed by Ana or John, which would suggest a differentiated researcher-associated technical impact on the samples' biological phenotype. This gene set shows also a strong depletion in proliferative samples, which is expected given its annotation as senescence-associated and results from the Benchmarking Mode.  

```{r GSEA_varassoc, fig.width=6, fig.height=6,warning=FALSE, message=FALSE , out.width="70%"}
VariableAssociation(
  data = counts_example,
  metadata = metadata_example,
  method = "GSEA",
  cols = c("Condition","Researcher","DaysToSequencing"),
  mode = "simple",
  gene_set = HernandezSegura_GeneSet,
  saturation_value = NULL,
  nonsignif_color = "white",
  signif_color = "red",
  sig_threshold = 0.05,
  widthlabels = 30,
  labsize = 10,
  titlesize = 14,
  pointSize = 5
) $plot

```
 
Alternatively, **score-based methods** provide a per-sample metric of gene set activity, which can then be summarised across variables. Here, we compute log2-median scores. The `Condition` variable shows a large effect size (Cohen’s f), confirming strong discrimination between Senescent and Proliferative samples. In contrast, `Researcher` does not show a detectable association, in contrast to enrichment-based results. This divergence illustrates the value of applying both enrichment- and score-based approaches in a complementary manner.


```{r variableassoc_score_sen, fig.width=7, fig.height=7,warning=FALSE, message=FALSE , out.width="70%" } 
VariableAssociation(data = counts_example, 
                    metadata = metadata_example, 
                    method = "logmedian",
                    cols = c("Condition","Researcher","DaysToSequencing"),  
                    gene_set = HernandezSegura_GeneSet,
                    mode="simple",
                    nonsignif_color = "white", signif_color = "red", saturation_value=NULL,sig_threshold = 0.05,
                    widthlabels=30, labsize=10, titlesize=14, pointSize=5, discrete_colors=NULL,
                    continuous_color = "#8C6D03", color_palette = "Set2")$Overall 

```


The Benchmarking Mode offers the most comprehensive set of features. Users are allowed to seamlessly move from Discovery to Benchmarking once a variable of interest has been identified and further testing is required. Benchmarking is designed to evaluate multiple gene sets simultaneously, whereas Discovery focuses on the performance of a single gene set.
 

## Individual Gene Exploration  

To better understand the contribution of individual genes within a gene set, and identify whether specific genes drive the set's collective signal,  `markeR` provides `VisualiseIndividualGenes.` Available options include:

* Expression heatmaps of genes across samples or groups of samples;
* Violin plots showing cross-sample expression distributions of individual genes; 
* Heatmaps of pairwise cross-sample expression correlation between genes in the set;
* ROC curves and AUC values to evaluate single genes' performance as phenotypic markers;
* Effect size estimation (Cohen’s *d*) of expression differences between groups of samples;
* Principal Component Analysis (PCA) of expression of genes in the set, to evaluate which genes dominate collective variance and how samples separate according to the gene set's expression.

For a complete overview, see `?VisualiseIndividualGenes` and the extended online tutorial [here](https://diseasetranscriptomicslab.github.io/markeR/articles/Tutorial_BenchmarkingMode.html#visualise-individual-gene-behaviour).
 
## Compare with Reference Gene Sets  

`markeR` also supports comparison of user-defined gene sets against reference collections (e.g., MSigDB). Two complementary similarity metrics are implemented:

* **Jaccard Index**:
the ratio of the number of genes in common over the total number of genes in the two sets.

* **Log Odds Ratio (logOR)** from Fisher’s exact test of association between gene sets, given a specified gene universe.

Filters can be applied based on similarity thresholds (e.g., minimum Jaccard, OR, or Fisher's test p-value).

Example of Gene Set Similarity (full tutorial [here][tutorial-signaturesimilarity]): We compare two user-defined gene sets against other user gene set and the MSigDB C2:CP:KEGG_LEGACY collection. Similarity is summarised in a heatmap of log odds ratios, highlighting associations above a defined threshold (e.g., OR > 100 for at least one of the signatures being compared). The underlying data for the heatmap can be accessed via `$data` for further analysis.


```{r, fig.width=6, fig.height=8}

# Example data
signature1 <- c("TP53", "BRCA1", "MYC", "EGFR", "CDK2")
signature2 <- c("ATXN2", "FUS", "MTOR", "CASP3")

signature_list <- list(
  "User_Apoptosis" = c("TP53", "CASP3", "BAX"),
  "User_CellCycle" = c("CDK2", "CDK4", "CCNB1", "MYC"),
  "User_DNARepair" = c("BRCA1", "RAD51", "ATM"),
  "User_MTOR" = c("MTOR", "AKT1", "RPS6KB1")
)

geneset_similarity(
  signatures = list(Sig1 = signature1, Sig2 = signature2),
  other_user_signatures = signature_list,
  collection = "C2",
  subcollection = "CP:KEGG_LEGACY",
  metric = "odds_ratio",
  # Define gene universe (e.g., genes from HPA or your dataset)
  universe = unique(c(
    signature1, signature2,
    unlist(signature_list),
    msigdbr::msigdbr(species = "Homo sapiens", category = "C2")$gene_symbol
  )),
  or_threshold = 100, 
  width_text=50, 
  pval_threshold = 0.05
)$plot
```
 

# Further Reading

Full tutorials with extended examples:

- [Benchmarking Mode](https://diseasetranscriptomicslab.github.io/markeR/articles/Article_BenchmarkingMode.html)  
- [Discovery Mode](https://diseasetranscriptomicslab.github.io/markeR/articles/Article_DiscoveryMode.html)  
- [Signature Similarity](https://diseasetranscriptomicslab.github.io/markeR/articles/Article_GeneSetSimilarity.html)

# Contact

📩 For questions, contact:

**Rita Martins-Silva**  
Email: [rita.silva@medicina.ulisboa.pt](mailto:rita.silva@medicina.ulisboa.pt)



[tutorial-benchmarking]: https://diseasetranscriptomicslab.github.io/markeR/articles/Article_BenchmarkingMode.html
[tutorial-discovery]: https://diseasetranscriptomicslab.github.io/markeR/articles/Article_DiscoveryMode.html
[tutorial-signaturesimilarity]: https://diseasetranscriptomicslab.github.io/markeR/articles/Article_GeneSetSimilarity.html


# Session Information

```{r}
sessionInfo()
```