| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009 |
- use log::{info, warn};
- use serde::{Deserialize, Serialize};
- use std::fs;
- use std::path::{Path, PathBuf};
- const CONFIG_TEMPLATE: &str = include_str!("../pandora-config.example.toml");
- #[derive(Debug, Clone, Serialize, Deserialize)]
- /// Global configuration for the Pandora somatic pipeline.
- ///
- /// Loaded from `~/.local/share/pandora/pandora-config.toml` (see [`Config::config_path`]).
- /// Most fields are path templates that can contain placeholders such as:
- /// `{result_dir}`, `{id}`, `{time}`, `{reference_name}`, `{haplotagged_bam_tag_name}`, `{output_dir}`.
- pub struct Config {
- // === General filesystem layout / I/O ===
- /// Root directory where all results will be written.
- pub result_dir: String,
- /// Temporary directory.
- pub tmp_dir: String,
- /// Run cache directory.
- pub run_cache_dir: String,
- /// Runner can slurm
- pub slurm_runner: bool,
- /// Software threads
- pub threads: u8,
- /// Singularity/Apptainer bin
- pub singularity_bin: String,
- /// Path to the `conda.sh` activation script (used to activate envs before running tools).
- pub conda_sh: String,
- // === Alignment / BAM handling ===
- /// Configuration for Dorado + samtools alignment pipeline.
- pub align: AlignConfig,
- /// Minimum MAPQ for reads to be kept during BAM filtering.
- pub bam_min_mapq: u8,
- /// Number of threads for hts BAM reader
- pub bam_n_threads: u8,
- /// Number of reads sampled when estimating BAM composition (e.g. tumor contamination).
- pub bam_composition_sample_size: u32,
- // === Reference genome and annotations ===
- /// Path to the reference FASTA used throughout the pipeline.
- pub reference: String,
- /// Short name for the reference (e.g. "hs1"), used in filenames.
- pub reference_name: String,
- /// Pseudoautosomal regions (PARs) BED file.
- pub pseudoautosomal_regions_bed: String,
- /// Path to the sequence dictionary (`.dict`) for the reference.
- pub dict_file: String,
- /// Path to the RefSeq GFF3 annotation, sorted and indexed.
- pub refseq_gff: String,
- /// dbSNP vcf.gz file (should be indexed)
- pub db_snp: String,
- /// BED with genes on the 4th column
- pub genes_bed: String,
- /// Cytobands BED file
- pub cytobands_bed: String,
- /// Chromosome alias file
- pub chromosomes_alias: String,
- /// BED template used to mask low-quality or filtered regions.
- ///
- /// Placeholders:
- /// - `{result_dir}`: global result directory
- /// - `{id}`: case identifier
- pub mask_bed: String,
- /// Panels of interest (name, BED path).
- pub panels: Vec<(String, String)>,
- /// Repeats bed file
- pub repeats_bed: String,
- // === Sample naming conventions ===
- /// Label used for the tumor sample in directory and file names (e.g. "diag").
- pub tumoral_name: String,
- /// Label used for the normal sample (e.g. "mrd").
- pub normal_name: String,
- /// BAM tag name used for haplotagged reads (e.g. "HP").
- pub haplotagged_bam_tag_name: String,
- // === Coverage counting (somatic-scan) ===
- /// Name of the subdirectory (under each sample dir) where count files are stored.
- pub count_dir_name: String,
- /// Bin size (bp) for count files.
- pub count_bin_size: u32,
- /// Number of chunks used to split chromosomes for counting.
- pub count_n_chunks: u32,
- /// Whether to force recomputation of coverage / counting even if outputs already exist.
- pub somatic_scan_force: bool,
- // === Somatic pipeline global options ===
- /// Whether to force recomputation of the whole somatic pipeline.
- pub somatic_pipe_force: bool,
- /// Default number of threads for most heavy tools (DeepVariant, Savana, etc.).
- pub somatic_pipe_threads: u8,
- /// Path template to the per-case somatic pipeline statistics directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`.
- pub somatic_pipe_stats: String,
- // === Basic somatic filtering / QC thresholds ===
- /// Minimum depth in the constitutional sample to consider a site evaluable.
- pub somatic_min_constit_depth: u16,
- /// Maximum allowed ALT count in the constitutional sample for a somatic call.
- pub somatic_max_alt_constit: u16,
- /// Window size (bp) used when computing sequence entropy around variants.
- pub entropy_seq_len: usize,
- /// Minimum Shannon entropy threshold for keeping a variant.
- pub min_shannon_entropy: f64,
- /// Maximum depth considered "low quality" for certain filters.
- pub max_depth_low_quality: u32,
- /// Minimum depth considered "high quality" for certain filters.
- pub min_high_quality_depth: u32,
- /// Minimum number of callers supporting a variant for it to be kept.
- pub min_n_callers: u8,
- // === DeepVariant configuration ===
- /// Template for the DeepVariant output directory (solo and normal/tumor runs).
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub deepvariant_output_dir: String,
- /// Number of threads to use for DeepVariant.
- pub deepvariant_threads: u8,
- /// DeepVariant singularity image path
- pub deepvariant_image: String,
- /// DeepVariant model type (e.g. "ONT_R104").
- pub deepvariant_model_type: String,
- /// Force DeepVariant recomputation even if outputs already exist.
- pub deepvariant_force: bool,
- // === DeepSomatic configuration ===
- /// Template for the DeepSomatic output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub deepsomatic_output_dir: String,
- /// Number of threads for DeepSomatic.
- pub deepsomatic_threads: u8,
- /// DeepSomatic singularity image path
- pub deepsomatic_image: String,
- /// DeepSomatic model type (e.g. "ONT").
- pub deepsomatic_model_type: String,
- /// Force DeepSomatic recomputation.
- pub deepsomatic_force: bool,
- // === ClairS configuration ===
- /// Number of threads for ClairS.
- pub clairs_threads: u8,
- /// Path to ClairS singularity image.
- pub clairs_image: String,
- /// Force ClairS recomputation.
- pub clairs_force: bool,
- /// Platform preset for ClairS (e.g. "ont_r10_dorado_sup_5khz_ssrs").
- pub clairs_platform: String,
- /// Template for ClairS output directory (`{result_dir}`, `{id}`).
- pub clairs_output_dir: String,
- // === Savana configuration ===
- /// Savana binary name or full path.
- pub savana_bin: String,
- /// Number of threads for Savana.
- pub savana_threads: u8,
- /// Template for Savana output directory (`{result_dir}`, `{id}`).
- pub savana_output_dir: String,
- /// Template for Savana copy number file.
- ///
- /// Placeholders: `{output_dir}`, `{id}`, `{reference_name}`, `{haplotagged_bam_tag_name}`.
- pub savana_copy_number: String,
- /// Template for Savana raw read counts file.
- ///
- /// Same placeholders as [`Config::savana_copy_number`].
- pub savana_read_counts: String,
- /// Template for Savana passed VCF output (`{output_dir}`, `{id}`).
- pub savana_passed_vcf: String,
- /// Force Savana recomputation.
- pub savana_force: bool,
- /// Template for constitutional phased VCF (`{result_dir}`, `{id}`).
- pub germline_phased_vcf: String,
- // === Severus configuration ===
- /// Path to Severus main script (`severus.py`).
- pub severus_bin: String,
- /// Force Severus recomputation.
- pub severus_force: bool,
- /// Number of threads for Severus.
- pub severus_threads: u8,
- /// VNTRs BED file for Severus.
- pub vntrs_bed: String,
- /// Path to Severus PoN file (TSV or VCF).
- pub severus_pon: String,
- /// Template for Severus tumor/normal (paired) output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`.
- pub severus_output_dir: String,
- /// Template for Severus solo output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub severus_solo_output_dir: String,
- // === MARLIN ===
- pub marlin_bed: String,
- // === Echtvar ===
- pub echtvar_bin: String,
- pub echtvar_sources: Vec<String>,
- // === Bcftools configuration ===
- /// Path to Bcftools binary.
- pub bcftools_bin: String,
- /// Number of threads for Bcftools.
- pub bcftools_threads: u8,
- // === Longphase configuration ===
- /// Path to longphase binary.
- pub longphase_bin: String,
- /// Number of threads for longphase.
- pub longphase_threads: u8,
- /// Number of threads for longphase modcall step.
- pub longphase_modcall_threads: u8,
- /// Force longphase recomputation (haplotagging/phasing).
- pub longphase_force: bool,
- /// Template for longphase modcall VCF.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub longphase_modcall_vcf: String,
- // === Modkit configuration ===
- /// Path to modkit binary.
- pub modkit_bin: String,
- /// Number of threads for `modkit summary`.
- pub modkit_summary_threads: u8,
- /// Template for modkit summary output file.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub modkit_summary_file: String,
- // === Nanomonsv configuration ===
- /// Path to nanomonsv binary.
- pub nanomonsv_bin: String,
- /// Template for paired nanomonsv output directory (`{result_dir}`, `{id}`, `{time}`).
- pub nanomonsv_output_dir: String,
- /// Force nanomonsv recomputation.
- pub nanomonsv_force: bool,
- /// Number of threads for nanomonsv.
- pub nanomonsv_threads: u8,
- /// Template for paired nanomonsv passed VCF (`{output_dir}`, `{id}`).
- pub nanomonsv_passed_vcf: String,
- /// Template for solo nanomonsv output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub nanomonsv_solo_output_dir: String,
- /// Template for solo nanomonsv passed VCF (`{output_dir}`, `{id}`, `{time}`).
- pub nanomonsv_solo_passed_vcf: String,
- pub nanomonsv_simple_repeat_bed: String,
- // === Straglr configuration ===
- /// Path to Straglr executable.
- pub straglr_bin: String,
- /// Path to STR loci BED file for Straglr.
- pub straglr_loci_bed: String,
- /// Size of reported difference between normal and tumoral
- pub straglr_min_size_diff: u32,
- /// Minimum CN of reported difference between normal and tumoral
- pub straglr_min_support_diff: u32,
- /// Minimum read support for STR genotyping.
- pub straglr_min_support: u32,
- /// Minimum cluster size for STR detection.
- pub straglr_min_cluster_size: u32,
- /// Whether to genotype in size mode.
- pub straglr_genotype_in_size: bool,
- /// Template for paired Straglr output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`.
- pub straglr_output_dir: String,
- /// Template for solo Straglr output directory.
- ///
- /// Placeholders: `{result_dir}`, `{id}`, `{time}`.
- pub straglr_solo_output_dir: String,
- /// Force Straglr recomputation.
- pub straglr_force: bool,
- // === PromethION runs / metadata ===
- /// Directory containing metadata about PromethION runs.
- pub promethion_runs_metadata_dir: String,
- /// JSON file describing PromethION runs and flowcell IDs.
- pub promethion_runs_input: String,
- // === VEP ===
- /// Path to VEP singularity image
- pub vep_image: String,
- /// Path to the VEP cache directory
- pub vep_cache_dir: String,
- /// Path to VEP sorted GFF
- pub vep_gff: String,
- }
- #[derive(Debug, Clone, Serialize, Deserialize)]
- /// Configuration for basecalling and alignment using Dorado and samtools.
- pub struct AlignConfig {
- /// Path to Dorado binary.
- pub dorado_bin: String,
- /// Arguments passed to `dorado basecaller` (e.g. devices and model name).
- pub dorado_basecall_arg: String,
- /// Should dorado re-align after demux ?
- pub dorado_should_realign: bool,
- /// Dorado aligner threads number
- pub dorado_aligner_threads: u8,
- /// Reference FASTA used for alignment.
- pub ref_fa: String,
- /// Minimap2 index (`.mmi`) used by Dorado or downstream tools.
- pub ref_mmi: String,
- /// Path to Samtools binary.
- pub samtools_bin: String,
- /// Number of threads given to `samtools view`.
- pub samtools_view_threads: u8,
- /// Number of threads given to `samtools sort`.
- pub samtools_sort_threads: u8,
- /// Number of threads given to `samtools merge`.
- pub samtools_merge_threads: u8,
- /// Number of threads given to `samtools split`.
- pub samtools_split_threads: u8,
- }
- // Here comes names that can't be changed from output of tools
- lazy_static! {
- /// Template name for DeepVariant VCF outputs.
- static ref DEEPVARIANT_OUTPUT_NAME: &'static str = "{id}_{time}_DeepVariant.vcf.gz";
- /// ClairS main SNP/indel VCF name.
- static ref CLAIRS_OUTPUT_NAME: &'static str = "output.vcf.gz";
- /// ClairS indel-only VCF name.
- static ref CLAIRS_OUTPUT_INDELS_NAME: &'static str = "indel.vcf.gz";
- /// ClairS germline normal VCF name.
- static ref CLAIRS_GERMLINE_NORMAL: &'static str = "clair3_normal_germline_output.vcf.gz";
- /// ClairS germline tumor VCF name.
- static ref CLAIRS_GERMLINE_TUMOR: &'static str = "clair3_tumor_germline_output.vcf.gz";
- }
- // impl Default for AlignConfig {
- // fn default() -> Self {
- // Self {
- // dorado_bin: "/data/tools/dorado-1.1.1-linux-x64/bin/dorado".to_string(),
- // dorado_basecall_arg: "-x 'cuda:0,1,2,3' sup,5mC_5hmC".to_string(),
- // ref_fa: "/data/ref/hs1/chm13v2.0.fa".to_string(),
- // ref_mmi: "/data/ref/chm13v2.0.mmi".to_string(),
- // samtools_view_threads: 20,
- // samtools_sort_threads: 50,
- // }
- // }
- // }
- //
- impl Config {
- /// Returns the config file path, e.g.:
- /// `~/.local/share/pandora/pandora-config.toml`.
- pub fn config_path() -> PathBuf {
- let mut path = directories::ProjectDirs::from("", "", "pandora")
- .expect("Could not determine project directory")
- .config_dir()
- .to_path_buf();
- path.push("pandora-config.toml");
- path
- }
- /// Install the commented template config on disk **if it does not exist yet**.
- ///
- /// This writes `CONFIG_TEMPLATE` verbatim so comments are preserved.
- fn write_template_if_missing() -> Result<(), Box<dyn std::error::Error>> {
- let path = Self::config_path();
- if path.exists() {
- // Do not touch an existing user config.
- return Ok(());
- }
- if let Some(parent) = path.parent() {
- fs::create_dir_all(parent)?;
- }
- fs::write(&path, CONFIG_TEMPLATE)?;
- info!("Config template written to: {}", path.display());
- Ok(())
- }
- /// “Save” configuration.
- ///
- /// In this model, we do **not** overwrite the user config (to preserve comments).
- /// `save()` only ensures the template exists on disk on first run.
- pub fn save(&self) -> Result<(), Box<dyn std::error::Error>> {
- Self::write_template_if_missing()
- }
- pub fn from_path(path: impl AsRef<Path>) -> Self {
- let path = path.as_ref().to_path_buf();
- // First, ensure there is at least a file on disk (template on first run).
- if let Err(e) = Self::write_template_if_missing() {
- warn!(
- "Warning: failed to ensure config template at {}: {}",
- path.display(),
- e
- );
- }
- // Try to load and parse the user config file.
- match fs::read_to_string(&path) {
- Ok(content) => match toml::from_str::<Config>(&content) {
- Ok(cfg) => cfg,
- Err(e) => {
- warn!(
- "Warning: failed to parse user config {}: {}. Falling back to embedded template.",
- path.display(),
- e
- );
- // Fallback: parse the embedded template.
- toml::from_str::<Config>(CONFIG_TEMPLATE)
- .expect("embedded config template is invalid")
- }
- },
- Err(e) => {
- warn!(
- "Warning: failed to read user config {}: {}. Falling back to embedded template.",
- path.display(),
- e
- );
- toml::from_str::<Config>(CONFIG_TEMPLATE)
- .expect("embedded config template is invalid")
- }
- }
- }
- /// Returns `<result_dir>/<id>/<tumoral_name>`.
- #[inline]
- pub fn tumoral_dir(&self, id: &str) -> String {
- format!("{}/{}/{}", self.result_dir, id, self.tumoral_name)
- }
- /// Returns `<result_dir>/<id>/<normal_name>`.
- #[inline]
- pub fn normal_dir(&self, id: &str) -> String {
- format!("{}/{}/{}", self.result_dir, id, self.normal_name)
- }
- /// Returns the directory for a "solo" run (timepoint or tag), i.e. `<result_dir>/<id>/<time>`.
- #[inline]
- pub fn solo_dir(&self, id: &str, time: &str) -> String {
- format!("{}/{}/{}", self.result_dir, id, time)
- }
- /// BAM for a solo run: `<solo_dir>/<id>_<time>_<reference_name>.bam`.
- pub fn solo_bam(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_{}.bam",
- self.solo_dir(id, time),
- id,
- time,
- self.reference_name,
- )
- }
- /// JSON sidecar for the solo BAM.
- pub fn solo_bam_info_json(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_{}_info.json",
- self.solo_dir(id, time),
- id,
- time,
- self.reference_name,
- )
- }
- /// Tumor BAM path: `<tumoral_dir>/<id>_<tumoral_name>_<reference_name>.bam`.
- pub fn tumoral_bam(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_{}.bam",
- self.tumoral_dir(id),
- id,
- self.tumoral_name,
- self.reference_name,
- )
- }
- /// Normal BAM path: `<normal_dir>/<id>_<normal_name>_<reference_name>.bam`.
- pub fn normal_bam(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_{}.bam",
- self.normal_dir(id),
- id,
- self.normal_name,
- self.reference_name,
- )
- }
- /// Tumor haplotagged BAM.
- pub fn solo_haplotagged_bam(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_{}_{}.bam",
- self.solo_dir(id, time),
- id,
- time,
- self.reference_name,
- self.haplotagged_bam_tag_name
- )
- }
- /// Tumor haplotagged BAM.
- pub fn tumoral_haplotagged_bam(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_{}_{}.bam",
- self.tumoral_dir(id),
- id,
- self.tumoral_name,
- self.reference_name,
- self.haplotagged_bam_tag_name
- )
- }
- /// Normal haplotagged BAM.
- pub fn normal_haplotagged_bam(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_{}_{}.bam",
- self.normal_dir(id),
- id,
- self.normal_name,
- self.reference_name,
- self.haplotagged_bam_tag_name
- )
- }
- /// Normal count directory: `<normal_dir>/counts`.
- pub fn normal_dir_count(&self, id: &str) -> String {
- format!("{}/{}", self.normal_dir(id), self.count_dir_name)
- }
- /// Tumor count directory: `<tumoral_dir>/counts`.
- pub fn tumoral_dir_count(&self, id: &str) -> String {
- format!("{}/{}", self.tumoral_dir(id), self.count_dir_name)
- }
- /// Mask BED path with `{result_dir}` and `{id}` expanded.
- pub fn mask_bed(&self, id: &str) -> String {
- self.mask_bed
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// Germline phased VCF with `{result_dir}` and `{id}` expanded.
- pub fn germline_phased_vcf(&self, id: &str) -> String {
- self.germline_phased_vcf
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// Somatic pipeline stats directory with `{result_dir}` and `{id}` expanded.
- pub fn somatic_pipe_stats(&self, id: &str) -> String {
- self.somatic_pipe_stats
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// DeepVariant output directory for a given run (`{result_dir}`, `{id}`, `{time}`).
- pub fn deepvariant_output_dir(&self, id: &str, time: &str) -> String {
- self.deepvariant_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// DeepVariant solo VCF (raw) for `<id>, <time>`.
- pub fn deepvariant_solo_output_vcf(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}",
- self.deepvariant_output_dir(id, time),
- *DEEPVARIANT_OUTPUT_NAME
- )
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// DeepVariant output directory for the normal sample.
- pub fn deepvariant_normal_output_dir(&self, id: &str) -> String {
- self.deepvariant_output_dir(id, &self.normal_name)
- }
- /// DeepVariant "tumoral output dir" (as in your original code – note: this actually returns the *PASSED VCF* path).
- pub fn deepvariant_tumoral_output_dir(&self, id: &str) -> String {
- self.deepvariant_solo_passed_vcf(id, &self.tumoral_name)
- }
- /// DeepVariant solo *PASSED* VCF for `<id>, <time>`.
- pub fn deepvariant_solo_passed_vcf(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_DeepVariant_PASSED.vcf.gz",
- self.deepvariant_output_dir(id, time),
- id,
- time
- )
- }
- /// DeepVariant *PASSED* VCF for the normal sample.
- pub fn deepvariant_normal_passed_vcf(&self, id: &str) -> String {
- self.deepvariant_solo_passed_vcf(id, &self.normal_name)
- }
- /// DeepVariant *PASSED* VCF for the tumor sample.
- pub fn deepvariant_tumoral_passed_vcf(&self, id: &str) -> String {
- self.deepvariant_solo_passed_vcf(id, &self.tumoral_name)
- }
- /// DeepSomatic output directory (uses `{time} = tumoral_name`).
- pub fn deepsomatic_output_dir(&self, id: &str) -> String {
- self.deepsomatic_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", &self.tumoral_name)
- }
- /// DeepSomatic raw VCF.
- pub fn deepsomatic_output_vcf(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_DeepSomatic.vcf.gz",
- self.deepsomatic_output_dir(id),
- id,
- self.tumoral_name
- )
- }
- /// DeepSomatic *PASSED* VCF.
- pub fn deepsomatic_passed_vcf(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_DeepSomatic_PASSED.vcf.gz",
- self.deepsomatic_output_dir(id),
- id,
- self.tumoral_name
- )
- }
- /// ClairS output directory (`{result_dir}`, `{id}`).
- pub fn clairs_output_dir(&self, id: &str) -> String {
- self.clairs_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// ClairS main SNP/indel VCFs (standard + indel-only).
- pub fn clairs_output_vcfs(&self, id: &str) -> (String, String) {
- let dir = self.clairs_output_dir(id);
- (
- format!("{dir}/{}", *CLAIRS_OUTPUT_NAME),
- format!("{dir}/{}", *CLAIRS_OUTPUT_INDELS_NAME),
- )
- }
- /// ClairS somatic *PASSED* VCF.
- pub fn clairs_passed_vcf(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_clairs_PASSED.vcf.gz",
- self.clairs_output_dir(id),
- id,
- self.tumoral_name
- )
- }
- /// ClairS germline normal VCF.
- pub fn clairs_germline_normal_vcf(&self, id: &str) -> String {
- let dir = self.clairs_output_dir(id);
- format!("{dir}/{}", *CLAIRS_GERMLINE_NORMAL)
- }
- /// ClairS germline tumor VCF.
- pub fn clairs_germline_tumor_vcf(&self, id: &str) -> String {
- let dir = self.clairs_output_dir(id);
- format!("{dir}/{}", *CLAIRS_GERMLINE_TUMOR)
- }
- /// Consolidated germline *PASSED* VCF from ClairS.
- pub fn clairs_germline_passed_vcf(&self, id: &str) -> String {
- let dir = self.clairs_output_dir(id);
- format!("{dir}/{id}_diag_clair3-germline_PASSED.vcf.gz")
- }
- /// Paired nanomonsv output directory.
- pub fn nanomonsv_output_dir(&self, id: &str, time: &str) -> String {
- self.nanomonsv_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Paired nanomonsv *PASSED* VCF.
- pub fn nanomonsv_passed_vcf(&self, id: &str) -> String {
- self.nanomonsv_passed_vcf
- .replace("{output_dir}", &self.nanomonsv_output_dir(id, "diag"))
- .replace("{id}", id)
- }
- /// Solo nanomonsv output directory.
- pub fn nanomonsv_solo_output_dir(&self, id: &str, time: &str) -> String {
- self.nanomonsv_solo_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Solo nanomonsv *PASSED* VCF.
- pub fn nanomonsv_solo_passed_vcf(&self, id: &str, time: &str) -> String {
- self.nanomonsv_solo_passed_vcf
- .replace("{output_dir}", &self.nanomonsv_solo_output_dir(id, time))
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Savana output directory (`{result_dir}`, `{id}`).
- pub fn savana_output_dir(&self, id: &str) -> String {
- self.savana_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// Savana main somatic VCF (classified).
- pub fn savana_output_vcf(&self, id: &str) -> String {
- let output_dir = self.savana_output_dir(id);
- format!(
- "{output_dir}/{id}_{}_{}_{}.classified.somatic.vcf",
- self.tumoral_name, self.reference_name, self.haplotagged_bam_tag_name
- )
- }
- /// Savana *PASSED* VCF.
- pub fn savana_passed_vcf(&self, id: &str) -> String {
- self.savana_passed_vcf
- .replace("{output_dir}", &self.savana_output_dir(id))
- .replace("{id}", id)
- }
- /// Savana read counts file.
- pub fn savana_read_counts(&self, id: &str) -> String {
- self.savana_read_counts
- .replace("{output_dir}", &self.savana_output_dir(id))
- .replace("{id}", id)
- .replace("{reference_name}", &self.reference_name)
- .replace("{haplotagged_bam_tag_name}", &self.haplotagged_bam_tag_name)
- }
- /// Savana copy-number file.
- pub fn savana_copy_number(&self, id: &str) -> String {
- self.savana_copy_number
- .replace("{output_dir}", &self.savana_output_dir(id))
- .replace("{id}", id)
- .replace("{reference_name}", &self.reference_name)
- .replace("{haplotagged_bam_tag_name}", &self.haplotagged_bam_tag_name)
- }
- /// Severus paired output directory.
- pub fn severus_output_dir(&self, id: &str) -> String {
- self.severus_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// Severus somatic SV VCF (paired).
- pub fn severus_output_vcf(&self, id: &str) -> String {
- let output_dir = self.severus_output_dir(id);
- format!("{output_dir}/somatic_SVs/severus_somatic.vcf")
- }
- /// Severus *PASSED* VCF (paired).
- pub fn severus_passed_vcf(&self, id: &str) -> String {
- format!(
- "{}/{}_diag_severus_PASSED.vcf.gz",
- &self.severus_output_dir(id),
- id
- )
- }
- /// Severus solo output directory.
- pub fn severus_solo_output_dir(&self, id: &str, time: &str) -> String {
- self.severus_solo_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Severus solo SV VCF.
- pub fn severus_solo_output_vcf(&self, id: &str, time: &str) -> String {
- let output_dir = self.severus_solo_output_dir(id, time);
- format!("{output_dir}/all_SVs/severus_all.vcf")
- }
- /// Severus solo *PASSED* VCF.
- pub fn severus_solo_passed_vcf(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_severus-solo_PASSED.vcf.gz",
- &self.severus_solo_output_dir(id, time),
- id,
- time
- )
- }
- /// Straglr paired output directory.
- pub fn straglr_output_dir(&self, id: &str) -> String {
- self.straglr_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- }
- /// Straglr normal sample TSV output.
- pub fn straglr_normal_tsv(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_straglr.tsv",
- self.straglr_solo_output_dir(id, &self.normal_name),
- id,
- self.normal_name
- )
- }
- /// Straglr tumor sample TSV output.
- pub fn straglr_tumor_tsv(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_straglr.tsv",
- self.straglr_output_dir(id),
- id,
- self.tumoral_name
- )
- }
- /// Straglr tumor sample TSV output.
- pub fn straglr_tumor_normal_diff_tsv(&self, id: &str) -> String {
- format!(
- "{}/{}_{}_straglr_diff.tsv",
- self.straglr_output_dir(id),
- id,
- self.tumoral_name
- )
- }
- /// Straglr solo output directory.
- pub fn straglr_solo_output_dir(&self, id: &str, time: &str) -> String {
- self.straglr_solo_output_dir
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Straglr solo TSV output.
- pub fn straglr_solo_tsv(&self, id: &str, time: &str) -> String {
- format!(
- "{}/{}_{}_straglr.tsv",
- self.straglr_solo_output_dir(id, time),
- id,
- time
- )
- }
- /// Alias for the constitutional germline VCF.
- pub fn constit_vcf(&self, id: &str) -> String {
- self.clairs_germline_passed_vcf(id)
- }
- /// Somatic-scan output directory for a solo run (counts subdir).
- pub fn somatic_scan_solo_output_dir(&self, id: &str, time: &str) -> String {
- format!("{}/counts", self.solo_dir(id, time))
- }
- /// Somatic-scan output dir for the normal sample.
- pub fn somatic_scan_normal_output_dir(&self, id: &str) -> String {
- self.somatic_scan_solo_output_dir(id, &self.normal_name)
- }
- /// Somatic-scan output dir for the tumor sample.
- pub fn somatic_scan_tumoral_output_dir(&self, id: &str) -> String {
- self.somatic_scan_solo_output_dir(id, &self.tumoral_name)
- }
- /// Somatic-scan count file for a given contig in a solo run.
- pub fn somatic_scan_solo_count_file(&self, id: &str, time: &str, contig: &str) -> String {
- format!(
- "{}/{}_count.tsv.gz",
- self.somatic_scan_solo_output_dir(id, time),
- contig
- )
- }
- /// Somatic-scan count file (normal) for a given contig.
- pub fn somatic_scan_normal_count_file(&self, id: &str, contig: &str) -> String {
- self.somatic_scan_solo_count_file(id, &self.normal_name, contig)
- }
- /// Somatic-scan count file (tumor) for a given contig.
- pub fn somatic_scan_tumoral_count_file(&self, id: &str, contig: &str) -> String {
- self.somatic_scan_solo_count_file(id, &self.tumoral_name, contig)
- }
- /// Modkit summary file (`{result_dir}`, `{id}`, `{time}`).
- pub fn modkit_summary_file(&self, id: &str, time: &str) -> String {
- self.modkit_summary_file
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- /// Longphase modcall VCF (`{result_dir}`, `{id}`, `{time}`).
- pub fn longphase_modcall_vcf(&self, id: &str, time: &str) -> String {
- self.longphase_modcall_vcf
- .replace("{result_dir}", &self.result_dir)
- .replace("{id}", id)
- .replace("{time}", time)
- }
- }
- impl Default for Config {
- fn default() -> Self {
- let path = Self::config_path();
- Self::from_path(path)
- }
- }
|