Exome-guided reannotation of nucleotide sequences
2.4K
Exome-guided reannotation of nucleotide sequences, and the CRISPR screen analysis toolchain that goes with it. One image, five commands.
Source and full documentation: https://github.com/SimonLammmm/exorcise. Runs on x86_64 and Apple silicon.
Exorcise is described in Lam, S., Thomas, J.C. & Jackson, S.P. Genome-aware annotation of CRISPR guides validates targets in variant cell lines and enhances discovery in screens. Genome Med 16, 139 (2024). https://doi.org/10.1186/s13073-024-01414-4. Please cite it if you use Exorcise in your work.
You can also try Exorcise on the web at https://sjlab.cruk.cam.ac.uk/app/ddrcs/ > Exorcise.
Sequences are usually annotated against one particular genome assembly, and it is not always right to carry those annotations over to another use. A library of sgRNAs for CRISPR-Cas9 might have been designed against GRCh37, with each guide described as targeting some gene or as non-targeting. Searching for those same guides in GRCh38 will turn up discrepancies, because the assembly has moved on; and a cell line that does not faithfully reflect GRCh37 will respond to the guides in ways its annotations do not predict.
Exorcise reannotates sequences according to whether they are present in a genome and exome that you supply. If that genome and exome reflect the material you are actually working with, you can be confident about which sequences are present in it and which annotations hold.
It works by aligning the sequences to the genome with BLAT, then using set operations between the alignment coordinates and the exon coordinates to transfer annotations onto the perfect alignments. Each sequence is considered independently, so a guide that turns out to cut two genes is reported against both.
Exorcise is written in R and developed by Dr Simon Lam.
Pick a tag from the Tags tab and pull it. Both architectures are published under one tag as a manifest list, so a plain pull fetches whichever matches your machine.
docker pull simonlammmm/exorcise:<tag>
Bind mount a working directory at /data and name the command you want:
docker run --rm -v .:/data/ simonlammmm/exorcise:<tag> exorcise [arguments]
Run the image with no command, or with --help, to list what it accepts.
With Singularity:
singularity pull docker://simonlammmm/exorcise:<tag>
singularity run -B .:/data/ exorcise_<tag>.sif exorcise [arguments]
Ask your cluster administrator which host directories are mounted by default and
whether you may bind others with -B.
Every example below shows the command on its own. Prefix each with
docker run --rm -v .:/data/ simonlammmm/exorcise:<tag>, and give paths relative
to the directory you mounted.
| Path | Contents |
|---|---|
/data/ | Working directory. Bind mount yours here. |
/exorcise/data/hsa.grch38.refseqall.tsv.gz | A bundled human exome annotation. |
/exorcise/env/ | The two conda environments, with pinned versions. |
/exorcise/VERSION, CHANGELOG.md, LICENSE | Version, release history, licence. |
The repository's example/ directory is not in the image. Clone the
repository if you want the example inputs, the analysis workbook template, or
example/examples.txt, which works through every step as a runnable script.
You supply the genome yourself, in 2bit format:
curl -L -o hg38.2bit "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/bigZips/hg38.2bit"
Exorcise itself reannotates sequences. Four other commands cover the rest of a screen analysis, and all five are in this image.
| Command | Does | Language |
|---|---|---|
exorcise | Reannotate sequences against a genome and exome | R |
exorcise-trace | Plot nucleotide frequency by sequencing cycle | R |
exorcise-count | Count reads and map them to a guide library | Python |
exorcise-analyse | Run MAGeCK, DrugZ or Chronos over a screen | Python |
exorcise-database | Build or update a screen results database | Python |
A typical run goes exorcise-trace to find the guide region in your reads,
exorcise to reannotate the library, exorcise-count to count against it,
exorcise-analyse to score the screen, then exorcise-database to collect the
results.
The Python commands were previously the separate crispr_tools and crispr_screen_viewer projects. They are now one package.
The commands were renamed in 3.0.0. Every old name still works and behaves identically; each prints a warning naming its replacement.
| Old name | Use instead |
|---|---|
ntByCycle | exorcise-trace |
count_reads | exorcise-count |
crispr_pipeline | exorcise-analyse |
crispr-screen-viewer database | exorcise-database |
crispr-screen-viewer remove DB_DIR ID... | exorcise-database --remove --out-dir DB_DIR ID... |
crispr-screen-viewer accepts database and remove here. Its launch,
genes and test subcommands went with the Dash web viewer, which is not part
of this project.
exorcise --infile library.tsv.gz --outdir exorcise-output/ \
--seq 7 --harm 2 --pam NGG --mode ko \
--genome hg38.2bit --exome /exorcise/data/hsa.grch38.refseqall.tsv.gz
| Long flag (short) | Required | Value | Description |
|---|---|---|---|
--infile (-i) | Yes | File | Input file containing the sequences to exorcise. |
--outdir (-o) | Yes | Directory | Output directory. Created if it does not exist. |
--seq (-g) | Yes | Number | 1-based column number in --infile holding the sequences. |
--genome (-v) | Yes | File | Genome assembly in 2bit format. |
--exome (-w) | Yes | File | Exome annotation in UCSC Table Browser format. |
--pam (-z) | No | Nucleotide | PAM appended to each sequence before alignment. [ACGTN]. |
--mode (-q) | No | String | CRISPR chemistry. See below. Default ko. |
--harm (-n) | No | Number | 1-based column number in --infile holding the existing annotations. |
--control (-c) | No | Patterns | Comma-separated regular expressions matching control guides in the --harm column. |
--control_type (-d) | No | Names | Comma-separated control names, one per --control pattern. |
--expression (-x) | No | File | Two-column file of gene symbol and expression value. Requires --harm. |
--exprcutoff (-k) | No | Number | Expression value below which a gene counts as not expressed. Default 10. |
--ref | No | Flag | Print the citation and exit. |
--version | No | Flag | Print the version and exit. |
--help (-h) | No | Flag | Print the syntax and exit. |
Files may be plain or gzipped.
Set the chemistry with --mode. It decides which features a guide is considered
to act on.
--mode | Behaviour |
|---|---|
ko | CRISPR knockout, the default. Annotates each guide with the features overlapping its cut site. |
a | CRISPR activation. Annotates each guide with features within 500 bases of its target site. |
i | CRISPR interference. Identical to a; the distinction is for your records. |
| an integer | As a and i, but with the distance you give instead of 500 bases. |
cbe | Cytosine base editor. C to T within the window [2, 8]. |
abe | Adenine base editor. A to G within the window [4, 9]. |
beXYnnmm | Custom base editor. See below. |
For a custom base editor, X is the original base and Y the edited base, both
in [ACGT]; nn and mm are the first and last positions of the editing
window, two digits each, counting from the PAM-distal end of the guide. So
beCT0208 is equivalent to cbe, and beAG0409 to abe.
Base editor modes need an exome that carries CDS coordinates and exon frames,
which means the name, cdsStart, cdsEnd and exonFrames columns as well as
the usual ones. The bundled exome has only five columns, so download a fuller
refGene table from the UCSC Table Browser for base editing.
Guides that fail to align inside any exon are named exo_Non-targeting_1,
exo_Non-targeting_2 and so on. If you know that some of them are declared
controls, pass --harm along with --control and --control_type and they will
be named after the control they belong to instead. For example:
--harm 2 --control "NO_CURRENT,^NonTargeting" --control_type "Unmapped,NonTargeting"
names every unannotated guide whose column 2 value matches /NO_CURRENT/ as
Unmapped_1, Unmapped_2 and so on. Patterns are tried in the order given, and
each guide takes the first that matches.
--expression takes a two-column file of gene symbol and expression value.
Guides whose --harm annotation names a gene scoring below --exprcutoff are
dropped before alignment, which is a fast way to restrict a screen to the genes
a particular cell line actually expresses. It requires --harm, since that is
the column the symbols are matched against.
Exorcise writes exorcise.tsv plus the intermediate files each stage produced.
The intermediates are safe to delete once you are happy with the result.
Each stage is checkpointed: if its output is already present and non-empty, the
stage is skipped. That makes it cheap to rerun with a different --mode against
the same genome, since the BLAT alignment is reused. It also means that if you
change --infile you must either use a fresh --outdir or delete the
intermediates, or the stale alignment will be picked up. Exorcise warns when it
notices alignments that are not in the current input.
| File | Description |
|---|---|
exorcise.1-seq.fa | Sequences plus PAM, as sent to BLAT. |
exorcise.2-<genome>_BLAT.psl | BLAT alignments against the genome. |
exorcise.3-<genome>_genomicRanges.tsv | Coordinates of the perfect alignments, and their cut sites. |
exorcise.3-<genome>_genomicSeqSpecs.tsv | Those coordinates, as sent for sequence verification. |
exorcise.3-<genome>_genomicSeqs.fa | Sequences read back out of the genome to verify each alignment. |
exorcise.4-<exome>_exonHits.tsv | Alignments with the annotations inherited from the exome. |
exorcise.5-<exome>_exonDist.tsv | Alignments with the distance to the nearest exon. |
exorcise.6-<exome>_baseEdited.tsv | Predicted base edits. Base editor modes only. |
exorcise.tsv | The exorcised library. |
logfile_exorcise_<timestamp>.log | Everything Exorcise reported during the run. |
In exorcise.tsv, Exorcise's own columns are prefixed exo_ and come first.
Every column from your input file follows, unchanged. Columns inherited from the
exome are prefixed inherit..
| Column | Description |
|---|---|
exo_id | Unique identifier for this reannotation. |
exo_seq | The sequence. |
exo_symbol | Reannotation from the exome, or a non-targeting or control name. |
exo_orig | The original annotation, if --harm was given. |
exo_target | Genome coordinates of the alignment, including the PAM. |
exo_cut | Genome coordinates of the cut site. |
exo_be | Symbol and predicted amino acid change. Base editor modes only. |
... | Your input columns, then the inherit. columns from the exome. |
One input sequence can produce several rows: a sequence aligning to two loci is two reannotations, and in base editor mode each predicted protein change is its own reannotation.
Base editor modes add these columns:
| Column | Description |
|---|---|
be_position_in_genome | Genome coordinates of the edit. |
be_nt_mutation | The edit in transcript coordinates, e.g. C123T. |
be_aa_mutation | The predicted protein change, e.g. Q41*. |
be_consequence | One of synonymous, missense, stopgain or stoploss. |
transcript | The transcript the prediction was made against. |
Plots the proportion of each nucleotide called at each sequencing cycle in a
FASTQ file, which is a quick way to find where the fixed region of an amplicon
ends and the variable guide region begins. Use the answer as --slice for
exorcise-count.
exorcise-trace --file reads.fastq.gz --nrows 10000 --out trace-output/
| Long flag (short) | Required | Value | Description |
|---|---|---|---|
--file (-f) | Yes | Paths | Comma-separated FASTQ files or directories to search recursively. |
--out (-o) | No | Directory | Output directory. Default the working directory. |
--nrows (-n) | No | Number | Read only the first N lines of each file. Four lines per read. |
--start (-s) | No | Number | First cycle to plot. Default 1. |
--end (-e) | No | Number | Last cycle to plot. Default the longest read. |
It writes a PDF, an interactive HTML plot and a TSV of the counts per file.
Counts the unique sequences in the sliced region of each read, then maps them
onto a guide library. Output is one dereplicated count file per sample, plus a
single counts table when --library is given.
exorcise-count --slice 0,20 --prefix counts/run \
--library exorcise-output/exorcise.tsv \
--seqhdr exo_seq --guidehdr exo_id --genehdr exo_symbol \
reads/*.fastq.gz
| Long flag (short) | Required | Description |
|---|---|---|
files | Yes | FASTQ/FASTA files, or directories of them. |
--slice (-s) | Yes | The guide region of each read, as M,N zero-based offsets, end exclusive. |
--prefix (-p) | Yes | Prefix for output files. May include a directory. |
--library | No | Guide library. Also writes <prefix>.counts.tsv. |
--seqhdr (-g) | No | Library column with guide sequences. Default seq. |
--guidehdr (-j) | No | Library column with guide names. Default guide. |
--genehdr (-n) | No | Library column with gene names. Default gene. |
--allow-mismatch | No | Also count reads one substitution from exactly one library guide. |
--merge-samples | No | Sum counts across files differing only by lane. |
--fn-split | No | Substring at which filenames are split to get the sample name. Default _R1_. |
--suffix | No | Suffix for per-sample count files. Default .rawcount. |
--file-type | No | a, q or infer. Default infer. |
--overwrite | No | Recount samples whose output already exists. |
An Exorcise output makes a good library here: pass --seqhdr exo_seq --guidehdr exo_id --genehdr exo_symbol and your counts arrive already carrying
genome-aware annotations.
Guides shorter than 16 bases are not counted, because below that a sequence stops being specific enough to identify one guide. If the library's guides vary in length, or are shorter than the slice, a window is slid along the sliced region.
Runs MAGeCK, DrugZ or Chronos over a screen. What runs is decided by the Analyses
sheet of an .xlsx workbook; start from
example/example-analysis-workbook-template.xlsx in the repository. A .json
configuration carrying sample_reps, analyses and control_groups also works.
exorcise-analyse --counts counts/ --output-dir results/ my-screen.xlsx
| Long flag | Required | Description |
|---|---|---|
config_file | Yes | An .xlsx workbook or .json configuration. |
--counts | Yes | Counts file, or the directory holding the counts files the workbook names. |
--output-dir | No | Where the results directory is created. Default the working directory. |
--file-prefix | No | Prefix for generated files. Default result. |
--skip-method | No | Comma-separated methods to skip. |
--run-groups | No | Comma-separated control groups to include. All by default. |
--run-analyses | No | Comma-separated analysis names to include. All by default. |
--analysis-version | No | Results are filed under this, if set. |
--overwrite | No | Rerun analyses whose output already exists. |
--dry-run | No | Validate the configuration without running anything. |
Every analysis is checkpointed on its output file, so a rerun only does what is
missing. --dry-run is worth using first: it reports every problem it can find
in the workbook at once.
Chronos only applies to comparisons that span more than one timepoint with the
control at the earliest one, so it needs Days grown and Trajectory columns in
Sample details. Comparisons that do not qualify are skipped with a reason.
Collects the tables exorcise-analyse wrote into a queryable database, alongside
two gzipped CSVs of experiment and comparison metadata.
exorcise-database --out-dir db/ --results-dir results/ --counts-dir counts/ \
--new-db my-screen.xlsx
| Long flag (short) | Required | Description |
|---|---|---|
details_xlsx | Yes | One or more analysis workbooks. With --remove, experiment IDs are also accepted. |
--out-dir (-o) | Yes | The database directory: where it is written, or the one to remove from. |
--results-dir (-r) | No | Directory holding the analysis results. Default results. |
--counts-dir (-c) | No | Directory holding the counts files. Default counts. |
--filename-prefix (-p) | No | Prefix the analysis files were written with. Default result. |
--new-db (-n) | No | Create a new database rather than adding to one. |
--remove | No | Remove the named experiments instead of adding them. |
--reindex | No | Add any missing index to an existing database and exit. |
--update-existing (-u) | No | Replace experiments already present instead of skipping them. |
--force-overwrite (-f) | No | Skip the confirmation prompt for a destructive action. |
--verbosity (-v) | No | 0 warnings, 1 info, 2 debug. Default 1. |
It writes database.db, experiments_metadata.csv.gz and
comparisons_metadata.csv.gz. Nothing here touches the network.
--new-db over a database that already exists asks before replacing it. Under
docker run there is no terminal to answer with unless you pass -it, so in a
script or a scheduled job add --force-overwrite. Without either, it refuses and
leaves the database alone rather than proceeding. Omit --new-db altogether to
add to the existing database instead of replacing it.
--remove takes an experiment out of a database. Name it either by the workbook
you added it with, or by its experiment ID:
exorcise-database --remove --out-dir db/ my-screen.xlsx
exorcise-database --remove --out-dir db/ my-experiment-id
Anything ending .xlsx is read as a workbook and its "Experiment name" is used;
anything else is taken as an ID literally. The IDs in a database are listed in
its experiments_metadata.csv.gz. Several may be given at once.
This removes the experiment's statistics and its rows from both metadata tables. Gene records stay, because they are shared between experiments. Experiments you name that are not in the database are reported and skipped, not treated as errors.
Like --new-db, removal asks first, needs -it under docker run to be
answerable, and takes --force-overwrite to proceed unattended.
A finished database is indexed for the queries downstream tools make. The stat
table's primary key is ordered (comparison_id, gene_id, analysis_type_id), so
it only helps queries that filter on comparison first; anything asking about one
gene across many comparisons would otherwise scan the whole table. Two indexes
are added once the rows are written:
| Index | Columns | Serves |
|---|---|---|
crave_idx_stat_gene | gene_id, analysis_type_id | one gene across comparisons |
crave_idx_stat_type | analysis_type_id, comparison_id | a whole analysis type |
This happens automatically whenever a database is created, added to or updated, so normally there is nothing to do. For a database built before this was added:
exorcise-database --reindex --out-dir db/
which creates whatever is missing, runs ANALYZE, and changes no data. It is
idempotent, so it is safe to run on a database that is already indexed.
The index names are CRAVE's. The output
directory of exorcise-database is a CRAVE dataset directory: point an instance
of CRAVE at it and you get within- and between-screen exploration over the
results, scored against genome-aware annotations all the way back to the library.
CRAVE creates these indexes itself if they are absent, looking for exactly these
names, so matching them means it finds them already there instead of spending
minutes rebuilding them at startup — and it cannot build them at all when the
dataset directory is mounted read-only, as it usually is in a deployment.
Conda environments and a source install are both supported, and the image builds
from a working tree if you want to test a change. See the
README on GitHub for both, and for the
worked examples in example/examples.txt.
git clone https://github.com/SimonLammmm/exorcise
cd exorcise
docker build -f docker/Dockerfile -t simonlammmm/exorcise .
The build context is the repository root, which is why -f is needed and why the
trailing . matters.
Exorcise is developed and maintained by Dr Simon Lam, University of Cambridge, [email protected].
exorcise-count, exorcise-analyse and exorcise-database derive from
crispr_tools and crispr_screen_viewer by John C. Thomas. exorcise-analyse
bundles DrugZ by Medina Colic and Traver
Hart, whose numerical routines are reproduced unchanged.
This code is licensed under the Creative Commons Zero v1.0 Universal licence.
Exorcise uses BLAT, which is free for
academic, personal and non-profit use. exorcise-analyse calls
MAGeCK and, optionally,
Chronos; both carry their own
licences.
Content type
Image
Digest
sha256:edc0275bf…
Size
1.8 GB
Last updated
5 days ago
docker pull simonlammmm/exorcise