Please see <https://pages.github.umn.edu/MSI-RIS/Tutorials/sc_intro/> for the latest version of this tutorial document.
Introduction to Single Cell Genomics
Last Updated: 2026-10-12
Last Delivered: 2026-10-13
Check out the recording of this tutorial and other MSI tutorials on our YouTube channel:
https://www.youtube.com/@UofMMSI/videos
Contact MSI
Our staff can help you access the MSI’s high performance computing resources, design and analyze your experiments!
- For general MSI help (using the systems, how to log in, etc.) email help@msi.umn.edu
- For bioinformatics questions (experimental design, analysis contracts, etc.) email ribhelp@msi.umn.edu
1. Introduction
1.1 Goals
In this tutorial we will cover the following topics:
- Discuss single cell measurement technologies, including some guidelines for planning a successful single cell or single nucleus experiment
- Provide an brief overview of single cell/nucleus gene expression analysis steps
- Demonstrate how to use MSI’s resources for performing single-cell analysis in R and Python
- Discuss important analysis considerations
- Showcase possible analysis avenues for scRNA-seq/snRNA-seq annotated data and discuss other data types
Single Cell or Single Nucleus There are many similarities between single cell RNA-seq analysis (scRNA-seq) and single nuclei RNA-seq analysis (snRNA-seq). We will use the term “single cell” throughout this tutorial for simplicity. The majority of the workflow for scRNA-seq is also applicable to snRNA-seq, with some small but important differences for sample preparation and quality control. Details are provided in our Single Cell Experimental Design template
1.2 Brief Introduction to Single Cell Methods
Here we discuss how single cell/nucleus transcriptomes are measured to create a count data matrix containing the expression of each gene for each cell/nucleus.
1.3 Single Cell Experimental Design
In practice, analyzing single cell experiments requires extensive fine tuning depending on the characteristics of the biological system and research questions. MSI Bioinformatics analysts developed this Single Cell Experimental Design template to help you consider important aspects of sample preparation and sequencing.
Some key points from that document include:
- What organism are you studying? Probe-based technologies (ie. 10X Flex) are available only for a subset of organisms.
- Can you get samples at the same time? How are you going to arrange the labwork to avoid confounding factors?
- Morphology of cells: can you actually capture the cells inside a droplet? If not, consider single nuclei or combinatorial labeling approaches.
- Ease of dissociation/stickyness: can you isolate “single” cells? You might need protocol optimizations.
- How abundant are the cell types of interest in your tissue? If rare, you might need enrichment approaches like cell sorting before library preparation.
- Are you planning to do statistical analysis? Then we strongly recommend biological replication!
We created this table to compare the 3 current types of single cell kits that are used by researchers at UMN. You may find it helpful when you are planning your experiments:
Another important consideration in experimental design is minimizing batch effects. Here we provide an example of how a batch effect can be introduced:
Remember, you can always reach out to MSI RI Bioinformatics for a free of charge consultation to help you with planning your sequencing experiments.
2. Single Cell RNA-seq Analysis on MSI
Accessing MSI systems requires that you are either on the UMN campus
network (eduroam or Ethernet in a UMN building) or connected to the UMN VPN. Please see https://it.umn.edu/services-technologies/virtual-private-network-vpn
for information on connecting to the UMN VPN.
You will also be required to have DUO multi-factor authentication set up. Please see https://it.umn.edu/services-technologies/self-help-guides/duo-set-use-duo-security for information about enrolling your device in DUO.
In this section we will briefly explore how to access MSI resources and get started with your single cell analysis. Our main goals are:
- Get familiar with the Open on Demand (OOD) interface
- Learn how to request resources from our HPC systems using available interactive apps (Jupyter and RStudio)
- Wrangle the large counts matrix resulting from a single cell experiment into a format compatible with the main analysis packages (Scanpy and Seurat)
- Generate some common plots for cell populations and gene expression
The software and data needed for this exercise is preinstalled in our systems. We also have created code templates with the commands you will need, please download them to your computer using the following links:
2.1 Open On Demand: files, terminal, interactive apps
Open on Demand (OOD) is web-browser based interface that allows access to MSI resources. We can see the files stored in the system and access computing nodes through a terminal or through graphical user interfaces and interactive apps.
A particularly useful option is the up/download button in the Files tab. This let’s you transfer files between your personal computer and the HPC cluster. Let’s try uploading the code templates into your Home Directory.
2.2 Seurat in RStudio
In this section we will connect to our HCP cluster and use RStudio through OOD to create our first Seurat object.
To connect to MSI -> OOD -> RStudio please follow these steps in your web browser:
- Go to https://ondemand.msi.umn.edu/ and log in with your UMN credentials
- In the
Interactive Appstab click onRStudio Server - Resources: Select the
Interactive - 2 cores, 32 GB, 64 GB local scratchoption. This resource combination works for the small dataset we will be using in this exercise, for a full experiment you will need more memory which you can request with theCustomoption. - R Version: Select
None (Custom Environment Providedfrom the drop-down menu. Click onCustomize Environment - Copy and paste these commands in the
Custom Environmentbox:
module purge
module load r-rich/4.6.0_msi1.2
- Time Limit: Select
1 Hours - Click on
Launch, this will submit a job with the resources we have asked for to our HPC scheduler SLURM. - You will be directed to a
My Interactive Sessionstab, where you should see a panel withRStudio Server (job ID)and theQueuedstatus. When the status changes toRunningclick onConnect to RStudio Server. A newRStudio Servertab opens up with the same look as if you were working on your laptop, but you are using the MSI compute capabilities. - Inside RStudio, look in the
Filespanel (bottom right) and click on the code template that we have just uploaded to open it. We will start our analysis with this file. - When you are done working with the template file, click on
Knitand download the resulting html documment so that you can revisit what you learnt using your web browser.
2.3 Installing Scanpy in Jupyter with the OOD Terminal
Installations can take a long time, so I have preinstalled the software needed for this tutorial in what is called a conda environment. In this section, I’ll show you how to do the last step of the installation (i.e. making the kernel available to Jupyter) using the OOD terminal.
Please follow these steps in your web browser:
- Go to https://ondemand.msi.umn.edu/ and log in with your UMN credentials
- In the
Clusterstab click onAgate Shell Access. A new window with a terminal will open. - Copy and paste these commands in the terminal:
module load miniforge/26.3
# activate the preinstalled environment:
source activate /common/tutorials/bioinformatics/single_cell/software/scanpy_051026/
# Make the kernel available to Jupyter:
python -m ipykernel install --user --name sc_tutorial_oct2026 --display-name sc_tutorial_2026
When successful, you should see a message like “Installed kernelspec sc_tutorial_1026 in …”, then you can exit the terminal.
For more information on how to make your own installations see the Installing Scanpy section below.
Installing Scanpy
Most certainly you’ll need to install software for your particular analysis. This is a little example with commands to create a conda environment that contains scanpy (with all its dependencies) and ipykernel.
# In Agate, ask for resources to SLURM, you might need to adjust them:
srun -N 1 --ntasks-per-node=4 --mem-per-cpu=3900MB -t 1:00:00 --pty bash
# Once your job starts:
# See what modules are available
module avail miniforge
# Choose and load a miniforge version
module load miniforge/26.3
# Install the packages:
today_date=$(date +%d%m%y) # good practice to date your installs
code_path='/appropriate_path/software' #use a path where you have writting permissions
conda create --copy -p $code_path/scanpy_${today_date} -c conda-forge -c bioconda scanpy ipykernel
For a more comprehensive guide on how to install and manage your own software check the Software Management tutorial on our YouTube channel and our User docs page about interactive HPC resources!
2.4 Scanpy in Jupyter
In this section we will connect to our HCP cluster and use Jupyter through OOD to create our first Anndata object. Please refer to the Scanpy tutorials and function websites for a more in depth walk through the analysis steps.
To connect to MSI -> OOD -> Jupyter please follow these steps in your web browser:
- Go to https://ondemand.msi.umn.edu/ and log in with your UMN credentials
- In the
Interactive Appstab click onJupyter - Resources: Select the
Interactive - 2 cores, 32 GB, 64 GB local scratchoption. This resource combination works for the small dataset we will be using in this exercise, for a full experiment you will need more memory which you can request with theCustomoption. - Jupyter Interface: Select
Lab - Jupyter Python: Select the default
MSI Python 3.8.3 / Jupyter 4.7.0 - Time Limit: Select
1 Hours - Click on
Launch, this will submit a job with the resources we have asked for to our HPC scheduler SLURM. - You will be directed to a
My Interactive Sessionstab, where you should see a panel withJupyter(job ID)and theQueuedstatus. When the status changes toRunningclick onConnect to Jupyter. - Inside Jupyter, in the
Filespanel (left) you’ll see the templates that we uploaded before. Double click onsc_tutorial_pre.ipynbto open it. - Click on the upper right corner of the file to select the appropriate kernel (in this case
sc_tutorial_2026). We are now ready to start. - When you are done working with the template remember to download the resulting documment so that you can revisit what you learnt later (tutorial accounts are temporary and all associated data will be lost when the account is ended).
3: Analysis Considerations
Single cell experiments can be as varied as tissue types and biological questions, so we can’t give you a roadmap of how the analysis should be performed. Instead, this section aims to walk you through the main steps to go from a count matrix to annotated data.
4. Resources
We hope this tutorial facilitates your introduction to the world of single cell analysis, but there is so much more to explore! The links here point to useful information along the experiment and analysis journey:
Experimental design
Using MSI Resources
- Getting access: https://msi.umn.edu/getting-started/getting-started-and-access
- Batch jobs: https://msi.umn.edu/computing/slurm-job-submission-and-scheduling
- Interactive computing: https://msi.umn.edu/computing/interactive-hpc/open-ondemand
- Tutorials page: https://msi.umn.edu/getting-started/help/tutorials
- Youtube channel: https://www.youtube.com/@UofMMSI/videos
- Biological databases: https://msi.umn.edu/consulting-and-research/bioinformatics-guides/bioref
- Running CellRanger on the MSI: https://userdocs.msi.umn.edu/software/package_docs/pages/cellranger.html
- Running Parse split-pipe on the MSI: https://userdocs.msi.umn.edu/software/package_docs/pages/parse-pipeline.html
Single cell analysis
- Seurat package: https://satijalab.org/seurat/
- Scanpy package: https://scanpy.readthedocs.io/en/stable/index.html
- CELLXGENE: https://cellxgene.cziscience.com/
- CellTypist reference atlas: https://www.celltypist.org/
FEEDBACK CONTACT
Thank you for reading this document, we hope it helps your research! This tutorial was prepared by Natalia Calixto Mancipe, Marissa Macchietto, and Sarah Munro, in the Core Bioinformatics group at MSI. We’d love to hear your feedback, please email us at ribhelp@msi.umn.edu.
5. Supplementary Materials
5.1: How to download single cell data from GEO
We will use the terminal in OOD to download some scRNA-seq data from GEO. I have selected a small dataset (GEO accession GSM8475184) of human peripheral blood mononuclear cells (PBMCs) from a graft rejection patient to demonstrate the commands. You can explore available datasets at https://www.ncbi.nlm.nih.gov/geo.
The following commands show how I create a folder in my /scratch.global/ space to store the data. When you try this, you’ll see your X500 in place of ‘calix015’.
calix015@ahl03 [~] % cd /scratch.global/$USER/
calix015@ahl03 [/scratch.global/calix015] % mkdir -p sc_tutorial/data/geo
calix015@ahl03 [/scratch.global/calix015] % cd sc_tutorial/data/geo
calix015@ahl03 [/scratch.global/calix015/sc_tutorial] % wget https://ftp.ncbi.nlm.nih.gov/geo/samples/GSM8475nnn/GSM8475184/suppl/GSM8475184_TS2_duringGF_raw_feature_bc_matrix.h5
# you'll see a progress bar, it should take just a few seconds
# Let's see the contents of the folder with the ls command:
calix015@ahl03 [/scratch.global/calix015/sc_tutorial] % ls
# you should see this file: GSM8475184_TS2_duringGF_raw_feature_bc_matrix.h5
Accessing single cell data from UMGC
If your laboratory works with the UMGC, your sequencing data will be delivered directly to your MSI storage space. You can find it in the appropriate folder /projects/standard/YOUR_GROUP/data_delivery/umgc/, where YOUR_GROUP is the MSI space name assigned to your lab. You can use the OOD file system to find it!
5.2: How to access single cell data from the UMGC
If your laboratory works with the UMGC, your sequencing data will be delivered directly to your MSI storage space. You can find it in the appropriate folder /projects/standard/YOUR_GROUP/data_delivery/umgc/, where YOUR_GROUP is the MSI space name assigned to your lab. You can use the OOD file system to find it!
5.3: How to find pre-built transcriptome references/indices for cellranger and split-pipe
Pre-built transcriptome indices for 10X Genomics cellranger and Parse Biosciences split-pipe softwares are available for select organisms within the (bioref) database on MSI and are also available for download through the vendor websites.
cellranger transcriptomes are available here:
/common/bioref/cellranger_10x/
split-pipe transcriptomes are available here:
/common/bioref/splitpipe_parse/1.5.0
If your organism is not available in the MSI bioref database, you can build your own transcriptome index for your organism using the cellranger mkref command (link) or the split-pipe --mode mkref command.
5.4: How to run CellRanger cell demultiplexing for 10X Genomics single-cell data
CellRanger is a software package from 10X Genomics that is used to demultiplex 10X Genomics sequencing FASTQ files to produce a cell-by-gene counts matrix containing the expression of each gene for each cell barcode, along with a quality report detailing the number of valid cell barcodes that were found, median numbers of genes and transcripts per cell, and read alignment statistics to the genome. If you have paid for full single-cell service through the UMGC, CellRanger will be run on your data. However, if you utilize the collab service and choose not to pay for the CellRanger service, you can run it yourself.
CellRanger is available as a system module on the MSI. You can view available versions of cellranger using the module avail cellranger command, and you can load the software by specifying the software version you would like to use. For example, we can use the command module load cellranger/10.0.0 to load version 10.0.0 which is the current version available on our system.
Below, we provide an example job script (.sbatch) that uses the cellranger count to perform this cell demultiplexing step on 3’ or 5’ GEX library data.
############cellranger_count.sbatch############
#!/bin/bash
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -c 24
#SBATCH --mem=128gb
#SBATCH -t 96:00:00
#SBATCH -p msismall
#SBATCH -A YOUR_GROUP
#SBATCH --mail-user=YOUR_EMAIL@umn.edu
#SBATCH --mail-type=ALL
#SBATCH -e cellranger_%j.err
#SBATCH -o cellranger_%j.out
# Load the cellranger module
module load cellranger/10.0.0
# The following cellranger command will align sequencing reads to the human GRCh38 transcriptome reference built by 10X Genomics (v2024) and demultiplex cells.
FASTQ_DIR="/path/to/your/FASTQ/folder/" # The path to your folder of FASTQ files
SAMPLE="sample1" # The unique sample name prefix on your FASTQ files
ID="cellranger_${SAMPLE}" # The name of the cellranger output folder
cellranger count \
--id=${ID} \
--sample=${SAMPLE} \
--transcriptome=/common/bioref/cellranger_10x/refdata-gex-GRCh38-2024-A/ \
--fastqs ${FASTQ_DIR} \
--chemistry auto \
--create-bam true \
--localcores=24 \
--localmem=128
5.5: How to run split-pipe cell demultiplexing for Parse Biosciences single-cell data
Split-pipe is the software developed by Parse Biosciences for demultiplexing sample and cell combinatorial barcodes and aligning transcript-derived reads to the genome. It is available on the MSI system through the parse-pipeline module. To view available versions, run the command module avail parse-pipeline, and a version can be loaded with the command module load parse-pipeline/1.5.0. Additionally, Parse Biosciences offers a cloud-based GUI platform called (Trailmaker) that can perform this demultiplexing step as well as downstream single-cell analyses.
For users who would like to process their parse data on the MSI system, we provide example job scripts for running split-pipe.
In the split-pipe_run.sbatch example script below, we run a single sublibrary FASTQ file through split-pipe to demultiplex the samples and cells given a text file called samplelist.txt that indicates which Parse plate wells correspond to each sample.
Example of a samplelist.txt file (column 1 = sample name, column 2 = plate well numbers, and columns are tab-delimited):
Sample1 A1-A6
Sample2 A7-A12
Sample3 B1-B6
Sample4 B7-B12
Sample5 C1-C6
Sample6 C7-C12
Sample7 D1-D6
Sample8 D7-D12
Example split-pipe_run.sbatch script:
############split-pipe_run.sbatch############
#!/bin/sh
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -c 32
#SBATCH --mem=200G
#SBATCH -t 96:00:00
#SBATCH -p msismall
#SBATCH -A YOUR_GROUP
#SBATCH --mail-type="ALL"
#SBATCH --mail-user=YOUR_EMAIL@umn.edu
# Load the parse-pipeline module
module load parse-pipeline/1.5.0
R1_FASTQ="Sub_Library1_L004_R1_001.fastq.gz" # Name of the R1 sublibrary FASTQ file
R2_FASTQ="Sub_Library1_L004_R2_001.fastq.gz" # Name of the R2 sublibrary FASTQ file
FASTQ_DIR="/path/to/your/FASTQ/folder/" # The path to your folder of FASTQ files
OUT="split_pipe_output/Sub_Library1" # The name of the split-pipe output folder
split-pipe --mode all \
--genome_dir "/common/bioref/splitpipe_parse/1.5.0/mm39/" \
--fq1 ${FASTQ_DIR}/${R1_FASTQ} \
--fq2 ${FASTQ_DIR}/${R2_FASTQ} \
--output_dir ${OUT} \
--samp_list samplelist.txt \
--chemistry v3 \
--kit WT \
--chem_score_skip \
--kit_score_skip \
--no_keep_going \
--nthreads 32
Once all of the sublibraries are processed using “split-pipe –mode all”, they can be combined together to produce the final output using the split-pipe --mode comb command:
############split-pipe_comb.sbatch############
#!/bin/sh
#SBATCH -N 1
#SBATCH -n 1
#SBATCH -c 32
#SBATCH --mem=100G
#SBATCH -t 96:00:00
#SBATCH -p msismall
#SBATCH -A YOUR_GROUP
#SBATCH --mail-type="ALL"
#SBATCH --mail-user=YOUR_EMAIL@umn.edu
module load parse-pipeline/1.5.0
# combine the split-pipe output directories from each sublibrary listed in "subsample.list"
split-pipe --mode comb \
--sublib_list subsample.list \
--output_dir split_pipe_output/combined \
--nthreads 32
The subsample.list file contains a list of all of the sublibrary output folder names produced from the split-pipe runs above. For example:
/path/to/your/split_pipe_output/Sub_Library1
/path/to/your/split_pipe_output/Sub_Library2
/path/to/your/split_pipe_output/Sub_Library3
5.6: Pseudobulking single-cell expression for DEG testing
For single-cell/nucleus data sets with multiple (>=2) biological replicates per group, aggregating the gene expression of single-cells of the same cell type for each sample (i.e. “pseudobulking”) is preferred for differential gene expression testing as it provided better control of the power to detect differentially expressed genes.
The basic workflow consists of: 1) Summing the raw gene counts by a chosen identity class.
AggregateExpression()from Seurat orSeurat2PBfrom edgeR can be used- Choose an identity that reflects the cell type and the biological replicate 2) Comparing the gene expression across identity classes with DEG testing method of choice.
- Appropriate normalization and covariate modeling should be done before Differential Expression Analysis
5.7: Cell type proportion analysis
For single-cell/nucleus data sets with multiple (>=2) biological replicates per group, it is possible to perform statistical analysis on cell type proportions across experimental conditions.
The Propeller() function in the (Speckle) R package is one package that can do this and it offers multiple statistical test options including linear regression modeling (can include covariates), ANOVA (for multiple groups), or T test.
5.8: Pseudotime
Pseudotime trajectory analysis is a single-cell/nucleus analysis approach that infers a progression of cell states (or temporal information) from a dataset collected at a single time point. Although cellular transcriptomes are captured as a “snapshot” in time, cells within that snapshot may occupy different stages of a continuous process, such as differentiation, development, activation, or response to treatment.
Pseudotime analyses order cells along an inferred trajectory according to similarities and gradual changes in gene-expression profiles, and the resulting values represents each cell’s relative position along that transcriptional continuum. Genes that vary statistically along that trajectory can then be determined.
How it works:
- Cells are clustered and embedded in a low-dimensional space (e.g PCA or UMAP).
- A trajectory inference method identifies continuous paths through transcriptional space that connect related cell states.
- The researcher selects a root or starting population (e.g, progenitor cells, untreated cells, resting cells, early activation state, etc).
- The method assigns pseudotime values to cells based on their distance or progression from the root population.
- The trajectory can be visualized over a UMAP, and genes that change along pseudotime can be identified.
Pseudotime softwares:
- PAGA (Python)
- Slingshot (R)
- Lamian (R, multi-sample)
5.9: RNA velocity
RNA velocity is an another approach to performing trajectory inference within a single-cell sample. Instead of using gene expression to construction that trajectory path, it looks at the expression relationship of unspliced pre-mRNAs (reads mapping into introns) and spliced mRNAs to infer whether each gene is in the process of being upregulated, downregulated, or in a steady expression state. It uses the combined information states of all genes to determine whether each cell is heading towards a particular cell fate. This program works well for samples where cells are developing or differentiating.
RNA velocity softwares:
- scVelo (Python)
- velociraptor (R)
- Velocyto (R and Python)
5.10: Single-nucleus ATAC-seq
snATAC-seq a single nucleus (sn) assay that measures open chromatin regions in single nuclei. It does so by utilizing transposase enzymes that cut at genomic regions that are open (e.g. promoters, enhancers, poised genomic elements). Sequencing reads will correspond the ends of the fragments that are generated from the transposase enzyme cuts.
-
No sample multiplexing options are available for nuclei assays because they do not have a cell membrane for antibody tagging.
-
There are different QC considerations.
-
Cell annotation can be preformed using an existing ATAC-seq reference or a RNA-seq reference.
5.11: Single-cell VDJ-seq
scVDJ-seq is a single-cell sequencing assay developed to specifically identify the unique VDJ sequence (variable sequence) within the T cell (TCR) and B cell (BCR) receptors that is generated during their development and maturation.
- Primers to conserved regions of the TCR or BCR receptors are used to amplify the cDNAs for sequencing
- Offered by 10X Genomics and Parse Biosciences
- Usually prepared along with scRNA-seq
- Other surface proteins can also be measured using oligo tags (e.g. Biolegend tags are used for 10X Genomics)
Glossary
This section describes the specialized terms that we use in this tutorial. Synonyms for some terms are also included.
Molecular Biology (Wet Bench) Terms
- (Sequencing) Adapter: Short nucleotide oligomers that are ligated to the 5′ and/or 3′ ends of a fragment in a sequencing library. These are non-biological, artificial sequences.
- Library: A collection of nucleic acid molecules that represents the sample organism that you wish to study. For RNAseq, it is usually a collection of cDNA (complementary DNA) sequences synthesized from RNA molecules.
- Library Preparation: The protocol that converts an extracted sample of nucleic acid into a sequencing library, read to run on the instrument. Various library preparation protocols exist, so it is important to know the details of the protocols your experiments are using. The details of the protocol do affect how your data should be handled.
- Sequencing Read: A string of nucleotide bases identified by the sequencing instrument. The nucleotide bases are derived from the sequence of the inserts of the sequencing library.
Bioinformatic Terms
- Depth: The number of times a particular nucleotide position has been seen in sequencing reads. Higher depth means the nucleotide has been read more times and thus typically has less uncertainty. Note that some people use “coverage” or “fold coverage” to refer to this definition of “depth.”
- Gene Annotation: (Noun) The assignment of regions of a reference genome to gene models. The assignments are stored in “annotation files” with formats such as GTF or GFF3. A gene annotation file must only be used with its accompanying reference genome file.
- Cell Annotation: process of identifying and labeling the biological classification of cells or clusters of cells.
- Mapping: A process by which short sequencing reads are compared to a reference genome to identify where they originated. This is the process that is used in inferring the relative abundance of transcripts in a RNA extraction. I distinguish mapping from alignment in that alignment is used to identify homologous sequences (rather than simply identifying a genomic position) and uses different algorithms from mapping. Some people use “mapping” and “alignment” interchangeably.
- Mapping Quality: A numerical value that describes the confidence with which the mapping position is known. Higher values indicate higher confidence. Each mapped read will have a mapping quality value associated with it.
- Normalization: A technique for adjusting the relative gene expression values across samples to account for variation in library size.
- (Raw) Counts Matrix: A matrix of integers describing the assignment of mapped reads to annotated gene models across multiple cells.
-
Reference Genome: A string of nucleotides that describes the genome of a given species. Sequencing reads are mapped against a reference genome, and gene expression is quantified using the accompanying gene annotation file.