← Files Life Sciences NGS AnalysisARCHIVED FILE
workflows/scrnaseq_fastq_to_count/run_starsolo.py
3.91 KB · Oct 3, 2026 · 06:07 UTC
import gzip
import os
import shutil
import subprocess
from pathlib import Path
execution = snakemake.config.get("execution", {})
star_runner = execution.get("star_runner", "native")
star_image = execution.get(
"star_image",
"josousa/star@sha256:2683d370b9c91a2e497d776d9b0dff2ddcc01dfec5029103ffa66b2a8da7b0c2",
)
def materialize_fastq(source_path: str, output_dir: Path) -> str:
source = Path(source_path).resolve()
if not source.exists():
raise FileNotFoundError(source)
output_dir.mkdir(parents=True, exist_ok=True)
if source.suffix != ".gz":
return str(source)
destination = (output_dir / source.stem).resolve()
with gzip.open(source, "rb") as input_handle, destination.open("wb") as output_handle:
shutil.copyfileobj(input_handle, output_handle)
return str(destination)
sample_dir = Path(str(snakemake.output.log)).resolve().parent
sample_dir.mkdir(parents=True, exist_ok=True)
if star_runner == "docker":
run_root = sample_dir.parents[1]
cdna_fastq = Path(str(snakemake.input.cdna_fastq)).resolve()
barcode_fastq = Path(str(snakemake.input.barcode_fastq)).resolve()
whitelist = Path(str(snakemake.input.whitelist)).resolve()
read_files_command = "zcat" if cdna_fastq.suffix == ".gz" else "cat"
cmd = [
"docker",
"run",
"--rm",
"--platform",
"linux/amd64",
"-u",
f"{os.getuid()}:{os.getgid()}",
"-w",
"/work",
"-v",
f"{run_root}:/work",
"-v",
f"{cdna_fastq.parent}:/cdna_ro:ro",
"-v",
f"{barcode_fastq.parent}:/barcode_ro:ro",
"-v",
f"{whitelist.parent}:/wl_ro:ro",
star_image,
"STAR",
"--genomeDir",
f"/work/{Path(str(snakemake.input.index)).resolve().relative_to(run_root)}",
"--runThreadN",
str(snakemake.threads),
"--readFilesIn",
f"/cdna_ro/{cdna_fastq.name}",
f"/barcode_ro/{barcode_fastq.name}",
"--readFilesCommand",
read_files_command,
"--outFileNamePrefix",
f"/work/{sample_dir.relative_to(run_root)}/",
"--soloType",
str(snakemake.params.solo_type),
"--soloCBwhitelist",
f"/wl_ro/{whitelist.name}",
"--soloCBstart",
str(snakemake.params.cb_start),
"--soloCBlen",
str(snakemake.params.cb_len),
"--soloUMIstart",
str(snakemake.params.umi_start),
"--soloUMIlen",
str(snakemake.params.umi_len),
"--soloBarcodeReadLength",
"0",
"--soloFeatures",
str(snakemake.params.features_mode),
"--soloCellFilter",
*str(snakemake.params.solo_cell_filter).split(),
"--outSAMtype",
"None",
]
else:
scratch_dir = sample_dir / "_inputs"
cdna_input = materialize_fastq(str(snakemake.input.cdna_fastq), scratch_dir / "cdna")
barcode_input = materialize_fastq(str(snakemake.input.barcode_fastq), scratch_dir / "barcode")
cmd = [
"STAR",
"--genomeDir",
str(Path(str(snakemake.input.index)).resolve()),
"--runThreadN",
str(snakemake.threads),
"--readFilesIn",
cdna_input,
barcode_input,
"--outFileNamePrefix",
str(sample_dir) + "/",
"--soloType",
str(snakemake.params.solo_type),
"--soloCBwhitelist",
str(Path(str(snakemake.input.whitelist)).resolve()),
"--soloCBstart",
str(snakemake.params.cb_start),
"--soloCBlen",
str(snakemake.params.cb_len),
"--soloUMIstart",
str(snakemake.params.umi_start),
"--soloUMIlen",
str(snakemake.params.umi_len),
"--soloBarcodeReadLength",
"0",
"--soloFeatures",
str(snakemake.params.features_mode),
"--soloCellFilter",
*str(snakemake.params.solo_cell_filter).split(),
"--outSAMtype",
"None",
]
subprocess.run(cmd, check=True)
SHA-256: 042a1ed11291484efd0eac039bcbccb8e3e825fc626facb0026fd5c0d4deeb18