G4X-data import
The multi-modal output of the G4X spatial sequencer comprises images, tables and annotated data matrices, which allow deep exploration of your sample. The single_cell_data folder contains both per-cell counts aggregated from the segmentation and processed analysis outputs. Choose an input based on whether you want to start a new analysis or continue the provided analysis.
| Goal | Input | Contents |
|---|---|---|
| Start a new analysis with your own filtering and normalization | cell_by_gene.csv.gz and cell_metadata.csv.gz |
Raw transcript counts for the segmented cells, including control probes when present, and associated cell metadata. |
| Continue the provided analysis | sc_processed.h5ad |
Cells and genes retained after filtering, processed RNA values, and analysis results such as PCA, UMAP, and clustering when processing succeeds. |
The processed AnnData can contain fewer cells and genes than the CSV tables. Its .obs metadata describe only the retained cells and can include additional analysis annotations.
Below we illustrate data import strategies for Python and R users:
if you are working in Python
Some excellent tools are:
scanpy: full-featured single-cell analysis suiterapids-singlecell: expands scanpy with GPU-supportsquidpy: functionality for the analysis of spatial dataspatial-data: analysis and management of spatial data (requires data conversion)
All of these tools accept, or incorporate anndata objects as the basic representation of your single-cell data. The first two methods below load the provided processed AnnData; the third builds a new object from raw counts. These workflows differ in their cell/gene selection, RNA values, and available annotations.
Understanding the processed AnnData
Processing filters cells using quality measures such as cell area, transcript counts, detected genes, control-probe percentage, and available nuclear stain measurements. Gene filtering retains targeting genes with sufficient cell coverage. The retained counts are then normalized by total counts per cell and transformed with log1p.
When preprocessing completes, adata.X contains these normalized, log-transformed RNA values. adata.layers["counts"] preserves the raw counts for the same retained cells and genes. This layer does not restore cells, genes, or control probes removed during filtering; use the CSV count matrix when you need those values. Avoid treating adata.X as raw counts or repeating normalization on it unintentionally.
If processing stops before normalization, the saved object may lack the counts layer and some analysis results. Check the available layers and annotations before continuing an analysis.
For multiomics data, adata.obsm["protein"] contains the per-cell mean protein intensities, with rows aligned to adata.obs_names. The corresponding column names, in order, are stored in adata.uns["protein_names"]. Protein intensities are separate from the RNA matrix in adata.X:
# After loading the processed AnnData using either method below:
protein_values = adata.obsm["protein"]
protein_names = adata.uns["protein_names"]
The CSV import example below loads RNA and cell metadata only. To include protein measurements in a new analysis, also load cell_by_protein.csv.gz and align its rows by cell_id.
1. G4X-helpers
If you have G4X-helpers v4 installed, you can use the G4Xsample() class to access the anndata of your sample via the load_adata() method.
import g4x_helpers as g4x
run_base = '/path/to/g4x_data/sample_x1'
sample = g4x.G4Xsample(run_base)
adata = sample.load_adata(remove_nontargeting=False, load_clustering=False)
Note: load_adata() options
load_adata() provides options that control which data are returned.
processed: bool (default=True)
remove_nontargeting: bool (default=False)
load_clustering: bool (default=False)
2. scanpy
You can load the saved processed object directly by pointing scanpy's read_h5ad() function to sc_processed.h5ad in your G4X-data directory. This preserves the annotations stored in the file; the Helpers example above uses load_clustering=False and omits Leiden columns from .obs.
from pathlib import Path
import scanpy as sc
run_base = Path('/path/to/g4x_data/sample_x1')
ad_file = run_base / 'single_cell_data' / 'sc_processed.h5ad'
adata = sc.read_h5ad(ad_file)
Note
If you have G4X-helpers installed, then scanpy will be available as one of its dependencies. If not, please refer to the scanpy documentation for installation guides.
3. building from raw data
With G4X-helpers, use G4Xsample.load_adata(processed=False) to build a new, unfiltered AnnData from the per-cell count and metadata tables and transcript manifest, rather than loading sc_processed.h5ad:
import g4x_helpers as g4x
sample = g4x.G4Xsample('/path/to/g4x_data/sample_x1')
adata = sample.load_adata(processed=False)
This keeps raw RNA counts in .X, including control probes when present, and adds gene annotations and calculated QC metrics. It also includes protein intensities when available. It does not filter cells or genes, normalize or log-transform counts, or compute PCA, UMAP, or clustering. By default, remove_nontargeting=False and load_clustering=False.
Alternatively, to start a new RNA analysis without G4X-helpers, read the raw counts and cell metadata directly into an anndata object. Its .X contains raw counts, including control probes when present. The manual example below does not apply filtering or normalization, or load the provided clustering, embeddings, gene metadata, or protein matrix.
from pathlib import Path
import anndata as ad
import pandas as pd
from scipy import sparse
run_base = Path('/path/to/g4x_data/sample_x1')
txcounts_path = run_base / 'single_cell_data' / 'cell_by_gene.csv.gz'
metadata_path = run_base / 'single_cell_data' / 'cell_metadata.csv.gz'
counts = pd.read_csv(txcounts_path, index_col='cell_id')
X = sparse.csr_matrix(counts.values)
metadata = pd.read_csv(metadata_path, index_col='cell_id')
adata = ad.AnnData(X=X, obs=metadata)
adata.var_names = counts.columns
Note
If you have G4X-helpers installed, then anndata, pandas and scipy will be available as dependencies.
if you are working in R
The most feature rich package for single-cell analysis in R is:
Seurat: full-featured single-cell analysis suite with spatial analysis capabilities
To work with your data in Seurat, it needs to be loaded into a SeuratObject, which is an annotated data structure. This example starts from the raw RNA count matrix and cell metadata, so you can apply your own filtering and normalization in Seurat. It does not reproduce the provided processed AnnData analysis or load protein measurements.
library('Seurat')
run_base = c('/path/to/g4x_data/sample_x1')
txcounts_path = file.path(run_base, "single_cell_data/cell_by_gene.csv.gz")
metadata_path = file.path(run_base, "single_cell_data/cell_metadata.csv.gz")
counts <- read.csv(txcounts_path, row.names = 1)
counts <- t(counts) # transpose to match Seurat input
metadata <- read.csv(metadata_path, row.names = 1)
sobj <- CreateSeuratObject(counts = counts, meta.data = metadata)
βΈ»