Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ methods:
inferelator:
modular: False
ext: 500000
linger:
modular: False
version: 'LINGER'
mode: 'parallel'
pando:
modular: True
exclude_exons: 'TRUE'
Expand Down Expand Up @@ -108,6 +112,7 @@ colors:
granie: '#97de8a'
hummus: '#d52727'
inferelator: '#ff9796'
linger: '#17a589'
pando: '#9467bc'
scdori: '#c4afd4'
scenicplus: '#8c554a'
Expand Down Expand Up @@ -194,6 +199,7 @@ method_names:
grnboost: GRNBoost2
hummus: HuMMuS
inferelator: Inferelator3.0
linger: LINGER
pando: Pando
pearson: Pearson
random: Random
Expand Down
2 changes: 2 additions & 0 deletions workflow/Snakefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ include: 'rules/dbs/gst.smk'
include: 'rules/dbs/c2g.smk'
include: 'rules/dbs/prt.smk'
include: 'rules/dbs/sim.smk'
include: 'rules/dbs/linger_prior.smk'

# Datasets
include: 'rules/dts/pbmc10k.smk'
Expand Down Expand Up @@ -133,6 +134,7 @@ include: 'rules/mth/scdori.smk'
include: 'rules/mth/scenic.smk'
include: 'rules/mth/scgpt.smk'
include: 'rules/mth/scmtni.smk'
include: 'rules/mth/linger.smk'

# Analyses
include: 'rules/anl/metrics/prior.smk'
Expand Down
90 changes: 90 additions & 0 deletions workflow/envs/linger.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
Bootstrap: docker
From: ubuntu:20.04


%environment
export PATH=/opt/:$PATH
. "/opt/conda/etc/profile.d/conda.sh"
. "/opt/conda/etc/profile.d/mamba.sh"
conda activate env

%post

export DEBIAN_FRONTEND=noninteractive
apt update -y

# basic packages
apt-get install -y --no-install-recommends tzdata
apt install -y build-essential \
gcc \
g++ \
libstdc++6 \
cmake \
wget \
curl \
git \
zlib1g-dev \
libbz2-dev \
liblzma-dev \
libcurl4-openssl-dev \
libssl-dev \
libxml2-dev \
libcairo2-dev \
libxt-dev \
libopenblas-dev \
ca-certificates \
bedtools

# conda
wget -O Miniforge3.sh "https://github.com/conda-forge/miniforge/releases/latest/download/Miniforge3-$(uname)-$(uname -m).sh"
bash Miniforge3.sh -b -p "/opt/conda"
rm Miniforge3.sh
. "/opt/conda/etc/profile.d/conda.sh"
. "/opt/conda/etc/profile.d/mamba.sh"
conda activate

# Create env
mamba create -y -n env -c pytorch -c bioconda -c conda-forge \
python=3.10 \
pip \
setuptools \
wheel \
cython \
pytorch=2.5.1 \
torchvision \
torchaudio \
cpuonly \
pybedtools==0.10.0 \
bedtools \
homer \
r-base==4.3 \
r-ggplot2 \
r-tidyr \
r-tidyverse \
rpy2 \
jupyterlab \
notebook

# Install LingerGRN and dependencies
conda activate env
pip install \
scipy==1.11.3 \
numpy==1.24.3 \
pandas==2.0.3 \
shap==0.42.0 \
scikit-learn==1.3.0 \
joblib==1.3.2 \
matplotlib==3.8.0 \
seaborn==0.13.0 \
statsmodels==0.14.1 \
umap-learn \
scanpy==1.9.5 \
anndata==0.9.2 \
"mudata<0.2.4" \
LingerGRN==1.106

# Remove cache for lighter containers
pip cache purge
conda clean -a -y
apt-get clean
rm -rf /var/lib/apt/lists/*
20 changes: 20 additions & 0 deletions workflow/rules/dbs/linger_prior.smk
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import os

rule linger_prior:
threads: 1
singularity: 'workflow/envs/linger.sif'
input: 'workflow/envs/linger.sif'
output:
archive='dbs/lingerGRN/data_bulk.tar.gz',
dir=directory('dbs/lingerGRN/data_bulk')
params:
dir_name=lambda wildcards, output: os.path.dirname(output.archive)
shell:
"""
mkdir -p {params.dir_name}
wget -nv --load-cookies /tmp/cookies.txt \
"https://drive.usercontent.google.com/download?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://drive.usercontent.google.com/download?id=1jwRgRHPJrKABOk7wImKONTtUupV7yJ9b' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1/p')&id=1jwRgRHPJrKABOk7wImKONTtUupV7yJ9b" \
-O '{output.archive}'
rm -f /tmp/cookies.txt
tar -xzf '{output.archive}' -C '{params.dir_name}'
"""
17 changes: 16 additions & 1 deletion workflow/rules/dbs/tss.smk
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
localrules: gen_tss_celloracle, gen_tss_crema, gen_tss_dictys, gen_tss_figr, gen_tss_granie, gen_tss_pando, gen_tss_scenicplus, gen_tss_scdori, gen_tss_scmtni, gen_tss_promoters
localrules: gen_tss_celloracle, gen_tss_crema, gen_tss_dictys, gen_tss_figr, gen_tss_granie, gen_tss_linger, gen_tss_pando, gen_tss_scenicplus, gen_tss_scdori, gen_tss_scmtni, gen_tss_promoters


rule gen_tss_celloracle:
Expand Down Expand Up @@ -83,6 +83,21 @@ rule gen_tss_inferelator:
cp {input} {output}
"""

rule gen_tss_linger:
threads: 1
singularity: 'workflow/envs/gretabench.sif'
input:
gtf=rules.gen_genome_inferelator.output.gtf,
genes='dbs/lingerGRN/data_bulk/bulk_gene_all.txt'
output: 'dbs/hg38/gen/tss/linger.bed.gz'
shell:
"""
python workflow/scripts/dbs/gen/tss/linger.py \
-i {input.gtf} \
-g {input.genes} \
-o {output}
"""

rule gen_tss_pando:
threads: 1
singularity: 'workflow/envs/pando.sif'
Expand Down
39 changes: 39 additions & 0 deletions workflow/rules/mth/linger.smk
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
rule mdl_o_linger:
threads: 24
singularity: 'workflow/envs/linger.sif'
input:
img='workflow/envs/linger.sif',
linger_GRN=rules.linger_prior.output.dir,
mdata=rules.extract_case.output.mdata
output:
dir=directory('dts/{org}/{dat}/cases/{case}/runs/linger/'),
out='dts/{org}/{dat}/cases/{case}/runs/o_linger.o_linger.o_linger.o_linger.mdl.csv'
params:
version=config['methods']['linger']['version'],
mode=config['methods']['linger']['mode'],
organism=lambda w: config['dts'][w.dat]['organism'],
script='workflow/scripts/mth/linger/linger.sh'
resources:
mem_mb=lambda wildcards, attempt: restart_mem(wildcards, attempt) * 2,
runtime=(
30 if config['methods']['linger']['version'] == 'baseline'
else 140 if config['methods']['linger']['mode'] == 'parallel'
else 360
)
shell:
"""
mkdir -p {output.dir}
set -e
timeout $(({resources.runtime}-20))m \
bash {params.script} \
--linger_GRN {input.linger_GRN} \
--out_dir {output.dir} \
--path_mdata {input.mdata} \
--version {params.version} \
--genome {params.organism} \
--mode {params.mode} \
--path_out {output.out}
if [ $? -eq 124 ]; then
awk 'BEGIN {{ print "source,target,score,pval" }}' > {output.out}
fi
"""
42 changes: 42 additions & 0 deletions workflow/scripts/dbs/gen/tss/linger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import argparse
import gzip
import re
import pandas as pd

parser = argparse.ArgumentParser()
parser.add_argument('-g', '--path_genes', required=True)
parser.add_argument('-i', '--path_gtf', required=True)
parser.add_argument('-o', '--path_out', required=True)
args = parser.parse_args()

gene_set = set(pd.read_csv(args.path_genes, header=None)[0].tolist())
print(f"LINGER gene universe: {len(gene_set)} genes")

records = []
with gzip.open(args.path_gtf, 'rt') as f:
for line in f:
fields = line.rstrip('\n').split('\t')
if fields[2] != 'transcript':
continue
gene_name = re.search(r'gene_name "([^"]+)"', fields[8]).group(1)
records.append([fields[0], int(fields[3]), gene_name])

# mirror `get_TSS_ensembl` in LINGER_tr_fast.py
df = pd.DataFrame(records, columns=['chr', 'start', 'symbol'])
df = df.groupby(['chr', 'symbol'], as_index=False)['start'].min()
df = df[df['symbol'] != '']
df['start'] -= 1

std_chroms = [f'chr{i}' for i in range(1, 23)] + ['chrX']
df = df[df['symbol'].isin(gene_set) & df['chr'].isin(std_chroms)]
print(f"Matched {df['symbol'].nunique()}/{len(gene_set)} genes")

bed = pd.DataFrame({
'chr': df['chr'],
'start': df['start'],
'end': df['start'],
'name': df['symbol']
})
bed = bed.sort_values(['chr', 'start'])
bed.to_csv(args.path_out, sep='\t', index=False, header=False, compression='gzip')
print(f"Written {len(bed)} records to {args.path_out}")
Loading