SVGram reconstructs clone-resolved complex structural-variant (CSV) paths from structural-variant junction calls and clone copy-number profiles. It builds a multi-clone SV graph, can add read support for reference adjacencies from a BAM file, balances junction copy numbers with an ILP model, and reconstructs derivative chromosome paths for each clone.
- Requirements
- Installation
- Quick Start
- Input Files
- Output Files
- Run Individual Stages
- References And License
SVGram needs both Python packages and C/C++ libraries. The recommended setup is
a conda or mamba environment built from environment.yml.
Required runtime and build components:
- Linux or another Unix-like shell environment.
- Python 3.9 or later.
- pandas.
- PuLP and the CBC ILP solver.
- pysam and htslib.
- CMake.
- A C++ compiler.
- zlib.
- Coin-OR/Cbc development libraries.
All of these are provided by environment.yml through the conda-forge and
bioconda channels.
Clone the repository and enter the project directory:
git clone https://github.com/deepomicslab/SVGram.git
cd SVGramCreate the conda environment:
mamba env create -n svgram -f environment.ymlIf mamba is not installed, use conda:
conda env create -n svgram -f environment.ymlActivate the environment:
conda activate svgramBuild the C++ component:
bash util/build_utils.shBy default, the build helper reads dependency paths from the active conda
environment through CONDA_PREFIX and writes the executable to:
build/Ambigram/Ambigram
Run the bundled example from the repository root after activating the SVGram environment. The example contains three tumor clones with distinct connected balanced rearrangements:
conda activate svgram
bash run_svgram_pipeline.sh \
--sv examples/sv_resolved.tsv \
--cn examples/cn_profile.tsv \
--fractions examples/fractions.tsv \
--mean-depth 30 \
--out-dir results/exampleThe example should finish with:
SVGram pipeline completed: results/example
For the tumor clones, each reconstructed output contains one selected linear
path. The same expected paths are saved in examples/expected_paths.tsv.
clone1: 1+5-2+8+4-7-11+5-9+3-6+10-4+12+
clone2: 1+6-3+9+4-8-11+6-10+2-5+7-4+12+
clone3: 12-5-9-11+7-4+10+5-2+6-3+8-7+1-
To add BAM-supported reference adjacencies, supply a coordinate-sorted and indexed BAM:
bash run_svgram_pipeline.sh \
--sv examples/sv_resolved.tsv \
--cn examples/cn_profile.tsv \
--fractions examples/fractions.tsv \
--mean-depth 30 \
--bam sample.sorted.bam \
--out-dir results/example_with_refSVGram expects tab-delimited text files.
The SV file must contain at least:
chrom1 pos1 strand1 chrom2 pos2 strand2 avg_dp
Example:
chrom1 pos1 strand1 chrom2 pos2 strand2 avg_dp
chr1 10000 + chr1 20000 - 24,22
chr1 15000 - chr1 25000 + 18,16
Field meanings:
chrom1,pos1,strand1: first breakpoint.chrom2,pos2,strand2: second breakpoint.avg_dp: junction read depth. It may be a single value such as24or a comma-separated pair such as24,22. If junction read depth is not available and a BAM is provided with--bam, this field can be left as0,0.
Strand values should be + or -.
The CN table contains genomic intervals followed by one column per clone:
chr start end clone0 clone1 clone2
Example:
chr start end clone0 clone1 clone2
chr1 8000 13000 2 3 2
chr1 13000 18000 2 4 3
chr1 18000 23000 2 3 5
chr1 23000 28000 2 2 4
Rules:
clone0is the normal clone forsolve_graph.py.- Additional clone columns are tumor clones.
- Values may be total copy numbers, for example
3. - Values may also be major/minor copy numbers, for example
2|1.
The fraction file is tab-delimited and contains one row per clone:
subclone fraction
clone0 0.20
clone1 0.55
clone2 0.25
Rules:
- Clone names should match the CN table clone columns.
- Fractions should usually sum to 1.
clone0is interpreted as the normal fraction.- Tumor purity is derived as
1 - fraction(clone0).
The BAM file is used when --bam is supplied to run_svgram_pipeline.sh or
when scripts/extract_ref_junc.py is run directly.
Requirements:
- Coordinate-sorted BAM.
- BAM index next to the BAM file, usually
sample.sorted.bam.bai. - Chromosome names compatible with the SV/CN tables. Simple
chrprefix differences are handled automatically.
The pipeline writes all outputs below --out-dir.
The initial multi-clone graph generated from the SV and CN tables. It includes
metadata lines, SEG rows, and observed JUNC rows.
Created when --bam is provided. It contains the original graph plus
BAM-supported REF rows for adjacent reference segments.
One clone-specific balanced graph per clone. These files are produced by
scripts/solve_graph.py and are used as inputs for path reconstruction.
The reconstructed paths for each clone. Each file contains the selected linear/circular derivative paths for that clone.
Path reconstruction also writes diagnostic ranking tables:
*.selection.tsv: candidate decomposition ranking.*.posterior.tsv: posterior-style candidate scoring details.*.joint_posterior.tsv: fraction-weighted joint posterior report when clone fractions are available.
The wrapper is convenient for routine runs, but each stage can also be run directly.
python scripts/generate_graph.py \
--sv-resolved-file examples/sv_resolved.tsv \
--cn-file examples/cn_profile.tsv \
--output-file results/example/graph.lhOptions:
--sv-resolved-file: input SV junction table.--cn-file: input clone copy-number table.--output-file: output.lhgraph.
python scripts/extract_ref_junc.py \
--graph results/example/graph.lh \
--bam sample.sorted.bam \
--output results/example/graph.with_ref.lhUseful options:
--min-mapq: minimum mapping quality. Default:20.--min-anchor: minimum aligned bases on both sides of an adjacency. Default:5.--no-exclude-clipped: keep reads with clipping near the boundary. By default, clipped reads near the boundary are excluded.--clip-margin: distance threshold for clipping near the boundary. Default:10.
python scripts/solve_graph.py \
--file results/example/graph.lh \
--fraction_file examples/fractions.tsv \
--mean_depth 30 \
--output_prefix results/example/balancedThe command above writes:
results/example/balanced_clone0.txt
results/example/balanced_clone1.txt
results/example/balanced_clone2.txt
results/example/balanced_clone3.txt
Main options:
--file: input multi-clone.lhgraph.--fraction_file: clone-fraction table.--mean_depth: mean whole-genome sequencing depth.--output_prefix: prefix forbalanced_cloneN.txtoutputs.--ploidy: baseline tumor ploidy. Default:2.0.
Advanced ILP options:
--base_individual_scale: clone-specific CN fitting weight scale.--sharing_discount: prior cost discount for SVs shared across tumor clones.--max_cn_change_free: CN change allowed without excess penalty.--excess_penalty_mult: multiplier for excess CN penalty.--weight_virtual: penalty for virtual imbalance edges.--weight_drop_junc: penalty for dropping an observed junction.--max_jcn: junction-copy-number upper bound.--junc_read_weight_base: lower bound for junction read-fit weight.--junc_read_weight_mult: junction read-fit multiplier.--sv_cn_prior_scale: SV junction CN prior scale.--weight_sv_presence: per-clone SV activation penalty.
Most users should start with the defaults.
python scripts/reconstruct_graph.py \
--file results/example/balanced_clone1.txt \
--out results/example/paths/balanced_clone1.paths.csv \
--clone balanced_clone1Common options:
--file: one balanced graph file.--out: output path CSV.--sample: sample identifier written to output. Default:sample_1.--clone: clone identifier written to output.--selection-mode:evolutionaryorlegacy. Default:evolutionary.--csv-type: lesion class. Usebfbfor BFB-like structures, or a non-BFB class such aschromothripsis,ecDNA,linear, orother.--fractions: clone-fraction file for joint posterior reporting.--clone-tree: clone-tree file for joint clone-posterior selection.
For a clone graph that was already split by solve_graph.py, the simple form
above is normally enough.
- Code: https://github.com/deepomicslab/SVGram
- Data and processed analysis artifacts: https://doi.org/10.5281/zenodo.20391483
- License: MIT. See LICENSE.