') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); GitHub - sunericd/SPRITE: Spatial Propagation and Reinforcement of Imputed Transcript Expression · GitHub
Skip to content

Latest commit

History

6 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

SPRITE

SPRITE (Spatial Propagation and Reinforcement of Imputed Transcript Expression) is a meta-algorithm for post-processing spatial gene expression predictions to improve the quality of predictions and their utility in downstream analysis. It involves two steps: Reinforce followed by Smooth.

plot

Installation and setup

To install SPRITE locally, first clone the repository using git (you can install git following the instructions here):

git clone https://github.com/sunericd/SPRITE.git

We recommend setting up a conda environment to install the requirements for the package (instructions for installing conda and what conda environment can do can be found here). Installation of requirements can then be done with the following commands:

conda create -n sprite python=3.8
conda activate sprite
cd SPRITE
pip install -r requirements.txt

To keep the requirements light, we have only included packages that are necessary for the core functionalities of SPRITE. For additional utilities such as gene prediction with Tangram, please install those packages separately (or uncomment those lines in requirements.txt).

To test the installation, you run through the Quick Start guide examples below.

Quick Start

Below we outline a mini-tutorial to explore the main functionalities of SPRITE. For larger-scale examples, please refer to the code repository corresponding the figures and analyses generated for the SPRITE manuscript: https://github.com/sunericd/sprite-figures-and-analyses.git

NOTE: The initial prediction and data loading schemes are highly similar to another tool that we developed for estimating prediction uncertainty (TISSUE).

We start by importing SPRITE and other packages:

# import packagesimportsprite.spriteasspriteimportnumpyasnpimportpandasaspdimportmatplotlib.pyplotaspltimportscanpyasscimportanndataasadimportos

We will use the osmFISH spatial transcriptomics data of mouse somatosensory cortex published by Codeluppi et al., 2018: https://doi.org/10.1038/s41592-018-0175-z, which is in test/data/.

Note that we are using the SPRITE methods for building an AnnData object from tab-delimited text files for the spatial counts, scRNAseq counts, spatial locations, and spatial metadata. If you already have an AnnData object for the spatial data and another object for the scRNAseq data, you can skip this step.

# load in spatial and scRNAseq datasetsadata, RNAseq_adata=sprite.load_paired_datasets("tests/data/Spatial_count.txt",
"tests/data/Locations.txt",
"tests/data/scRNA_count.txt")
/home/edsun/anaconda3/envs/tissue/lib/python3.8/site-packages/anndata/_core/anndata.py:117: ImplicitModificationWarning: Transforming to str index.
warnings.warn("Transforming to str index.", ImplicitModificationWarning)
/home/edsun/anaconda3/envs/tissue/lib/python3.8/site-packages/anndata/_core/anndata.py:856: UserWarning: AnnData expects .obs.index to contain strings, but got values like:
[0, 1, 2, 3, 4]
Inferred to be: integer
names = self._prep_dim_index(names, "obs")

Predicting spatial gene expression

Now we can impute any genes of interest that are found in the scRNAseq dataset but not in the spatial dataset. In this case, we will hold out a target gene from the spatial data and apply an imputation method to predict its expression using the scRNAseq dataset.

First, we preprocess the data and make sure that the gene names are matchable across the two datasets:

# make genes lowercaseadata.var_names= [x.lower() forxinadata.var_names]
RNAseq_adata.var_names= [x.lower() forxinRNAseq_adata.var_names]
# preprocess RNAseq datasprite.preprocess_data(RNAseq_adata, standardize=False, normalize=True)
# subset spatial data into shared genesgene_names=np.intersect1d(adata.var_names, RNAseq_adata.var_names)
adata=adata[:, gene_names].copy()
# hold out target genetarget_gene="plp1"target_expn=adata[:, target_gene].X.copy()
adata=adata[:, [geneforgeneingene_namesifgene!=target_gene]].copy()

Now, we can make predictions of the target gene expression. In SPRITE, we have the SpaGE prediction method natively implemented (other methods will need to be installed). We will be using SpaGE in this example:

# SpaGE spatial gene expression predictionsprite.predict_gene_expression (adata, RNAseq_adata, [target_gene],
method="spage", n_folds=10, n_pv=10)

The predicted spatial gene expression is stored in the input AnnData object under adata.obsm['spage_predicted_expression'].

SPRITE post-processing of predictions

The first step in SPRITE post-processing is the Reinforce step, which uses gene correlation information to correct prediction errors.

Note that this step is the most computationally expensive component of SPRITE so if the compute is a burden, we recommend only using the Smooth step and skipping Reinforce.

For Reinforce, we will set alpha=0.1 (you can input an array-like to perform a search for alpha values as well).

# Reinforcesprite.reinforce_gene(adata, predicted="spage_predicted_expression",
alpha=0.1, tol=1e-8, cv=5)
Using automatic Spearman gene correlation threshold: 0.254
Propagation converged after 13 iterations

The second step in SPRITE is the Smooth step, which builds a spatial neighborhood graph and propagates information.

# build spatial neighborhood graphsprite.build_spatial_graph(adata, method="fixed_radius", n_neighbors=50)
# calculate cosine-based weights for edgessprite.calc_adjacency_weights(adata, method="cosine")
# Smoothsprite.smooth(adata, predicted="reinforced_gene_joint_spage_predicted_expression",
alpha=0.1, tol=1e-8)
Propagation converged after 12 iterations

In cases where you want to run Smooth without Reinforce, just set predicted='spage_predicted_expression'.

The predicted spatial gene expression matrices can be found in adata.obsm under the following keys:

  • 'spage_predicted_expression' - baseline predicted spatial gene expression
  • 'reinforced_gene_joint_spage_predicted_expression' - reinforced (intermediate) predicted spatial gene expression
  • 'smoothed_reinforced_gene_joint_spage_predicted_expression' - SPRITE predicted spatial gene expression

About

Spatial Propagation and Reinforcement of Imputed Transcript Expression

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages