---
title: "VisiumIO: Import 10X Genomics Visium Experiment Data"
author: "Marcel Ramos"
date: "`r format(Sys.time(), '%B %d, %Y')`"
vignette: >
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteIndexEntry{VisiumIO Quick Start Guide}
  %\VignetteEncoding{UTF-8}
output:
  BiocStyle::html_document:
    number_sections: no
    toc: yes
    toc_depth: 4
package: VisiumIO
---

```{r, setup, include=FALSE}
knitr::opts_chunk$set(cache = TRUE)
```

# Introduction

The `VisiumIO` package provides a set of functions to import 10X Genomics Visium
experiment data into a `SpatialExperiment` object. The package makes use of the
`SpatialExperiment` data structure, which provides a set of classes and
methods to handle spatially resolved transcriptomics data.

# TENxIO Supported Formats

| **Extension**       | **Class**     | **Imported as**      |
|---------------------|---------------|----------------------|
| .h5                 | TENxH5        | SingleCellExperiment w/ TENxMatrix |
| .mtx / .mtx.gz      | TENxMTX       | SummarizedExperiment w/ dgCMatrix |
| .tar.gz             | TENxFileList  | SingleCellExperiment w/ dgCMatrix |
| peak_annotation.tsv | TENxPeaks     | GRanges              |
| fragments.tsv.gz    | TENxFragments | RaggedExperiment     |
| .tsv / .tsv.gz      | TENxTSV       | tibble               |

# VisiumIO Supported Formats

| **Extension**       | **Class**     | **Imported as**      |
|---------------------|---------------|----------------------|
| spatial.tar.gz      | TENxSpatialList | DataFrame list *   |
| .parquet            | TENxSpatialParquet | tibble *        |
| .geojson            | TENxGeoJSON   | sf object *          |

__Note__. (*) Intermediate format 

# Installation

```{r,eval=FALSE}
if (!require("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("VisiumIO")
```

# Loading package

```{r,include=TRUE,results="hide",message=FALSE,warning=FALSE}
library(VisiumIO)
```

# TENxVisium

The `TENxVisium` class is used to import a **single** sample of 10X Visium data.
The `TENxVisium` constructor function takes the following arguments:

```{r,eval=FALSE}
TENxVisium(
    resources = "path/to/10x/visium/file.tar.gz",
    spatialResource = "path/to/10x/visium/spatial/file.spatial.tar.gz",
    spacerangerOut = "path/to/10x/visium/sample/folder",
    sample_id = "sample01",
    images = c("lowres", "hires", "detected", "aligned"),
    jsonFile = "scalefactors_json.json",
    tissuePattern = "tissue_positions.*\\.csv",
    spatialCoordsNames = c("pxl_col_in_fullres", "pxl_row_in_fullres")
)
```

The `resource` argument is the path to the 10X Visium file. The
`spatialResource` argument is the path to the 10X Visium spatial file. It
usually ends in `spatial.tar.gz`.

## Example from SpatialExperiment

Note that we use the `images = "lowres"` and `processing = "raw"` arguments based
on the name of the `tissue_*_image.png` file and `*_feature_bc_matrix` folder in
the `spaceranger` output. The directory structure for a **single** sample is
shown below:

```
    section1
    └── outs
        ├── spatial
        │   ├── tissue_lowres_image.png
        │   └── tissue_positions_list.csv
        └── raw_feature_bc_matrix
            ├── barcodes.tsv
            ├── features.tsv
            └── matrix.mtx
```

### Creating a TENxVisium instance

Using the example data from `SpatialExperiment`, we can load the `section1`
sample using `TENxVisium`.

```{r}
outs_folder <- system.file(
    file.path("extdata", "10xVisium", "section1", "outs"),
    package = "VisiumIO"
)

vis <- TENxVisium(
    spacerangerOut = outs_folder, processing = "raw", images = "lowres"
)
vis
```

Note that the `spacerangerOut` input corresponds directly to the `outs` folder
from the `spaceranger` output. 

The show method of the `TENxVisium` class displays the object's metadata.

### Importing into SpatialExperiment

The `TEnxVisium` object can be imported into a `SpatialExperiment` object using
the `import` function.

```{r}
import(vis)
```

# TENxVisiumList

The `TENxVisiumList` class is used to import multiple samples of 10X Visium.
The interface is a bit more simple in that you only need to provide the
`space ranger` output folder as input to the function.

```{r,eval=FALSE}
TENxVisiumList(
    sampleFolders = "path/to/10x/visium/sample/folder",
    sample_ids = c("sample01", "sample02"),
    ...
)
```

The `sampleFolders` argument is a character vector of paths to the `spaceranger`
output folder. Note that each folder must contain an `outs` directory. The
`sample_ids` argument is a character vector of sample ids.

## Example from SpatialExperiment

The directory structure for **multiple** samples (`section1` and `section2`) is
shown below:

```
    section1
    └── outs
    |   ├── spatial
    |   └── raw_feature_bc_matrix
    section2
    └── outs
        ├── spatial
        └── raw_feature_bc_matrix
```

### Creating a TENxVisiumList

The main inputs to `TENxVisiumList` are the `sampleFolders` and `sample_ids`.
These correspond to the `spaceranger` output sample folders and a vector
of sample identifiers, respectively.

```{r}
sample_dirs <- list.dirs(
    system.file(
        file.path("extdata", "10xVisium"), package = "VisiumIO"
    ),
    recursive = FALSE, full.names = TRUE
)
    
vlist <- TENxVisiumList(
    sampleFolders = sample_dirs,
    sample_ids = basename(sample_dirs),
    processing = "raw",
    images = "lowres"
)
vlist
```

### Importing into SpatialExperiment

The `import` method combines both `SingleCellExperiment` objects along with the
spatial information into a single `SpatialExperiment` object. The number of
columns in the SpatialExperiment object is equal to the number of cells across
both samples (`section1` and `section2`).

```{r}
import(vlist)
```

### Visium HD folder structure

The directory structure for a single bin size is shown below.

```
    Visium_HD
    └── binned_outputs
        └─── square_002um
        │   └── filtered_feature_bc_matrix
        │   │   └── barcodes.tsv.gz
        │   │   └── features.tsv.gz
        │   │   └── matrix.mtx.gz
        │   └── filtered_feature_bc_matrix.h5
        │   └── raw_feature_bc_matrix/
        │   └── raw_feature_bc_matrix.h5
        │   └── spatial
        │       └── [ ... ]
        │       └── tissue_positions.parquet
        └── square_*
```

### Import Visium HD into SpatialExperiment

```{r, eval=FALSE}
TENxVisiumHD(
    spacerangerOut = "./Visium_HD/",
    sample_id = "sample01",
    processing = c("filtered", "raw"),
    images = c("lowres", "hires", "detected", "aligned_fiducials"),
    bin_size = c("002", "008", "016"),
    jsonFile = .SCALE_JSON_FILE,
    tissuePattern = "tissue_positions\\.parquet",
    spatialCoordsNames = c("pxl_col_in_fullres", "pxl_row_in_fullres"),
    ...
)
```

### In-package example

By default, the MatrixMarket format is read in (`format = "mtx"`).

```{r}
visfold <- system.file(
    package = "VisiumIO", "extdata", mustWork = TRUE
)
TENxVisiumHD(
    spacerangerOut = visfold, images = "lowres", bin_size = "002"
) |> import()
```

H5 files are supported via the `format = "h5"` argument input.

```{r}
TENxVisiumHD(
    spacerangerOut = visfold, images = "lowres", bin_size = "002",
    format = "h5"
) |> import()
```

# Session Info

```{r session-info, echo=FALSE, results='asis'}
html_output <- paste0(
    "<details><summary>",
    "Click to expand <code>sessionInfo()</code>",
    "</summary>\n\n",
    "<pre><code>",
    paste(capture.output(sessionInfo()), collapse = "\n"),
    "</code></pre>\n</details>"
)
cat(html_output)
```
