|
@@ -20,9 +20,22 @@ use std::{
|
|
|
path::{Path, PathBuf},
|
|
path::{Path, PathBuf},
|
|
|
};
|
|
};
|
|
|
use tracing::info;
|
|
use tracing::info;
|
|
|
|
|
+use uuid::Uuid;
|
|
|
|
|
|
|
|
use super::modkit::ModkitSummary;
|
|
use super::modkit::ModkitSummary;
|
|
|
|
|
|
|
|
|
|
+pub fn run_phasing_somatic(id: &str, config: &Config) -> anyhow::Result<()> {
|
|
|
|
|
+ LongphaseModcallSolo::initialize(id, &config.normal_name, config)?.run()?;
|
|
|
|
|
+ LongphaseModcallSolo::initialize(id, &config.tumoral_name, config)?.run()?;
|
|
|
|
|
+
|
|
|
|
|
+ LongphasePhase::initialize(id, config)?.run()?;
|
|
|
|
|
+
|
|
|
|
|
+ LongphaseHap::initialize(id, &config.normal_name, config)?.run()?;
|
|
|
|
|
+ LongphaseHap::initialize(id, &config.tumoral_name, config)?.run()?;
|
|
|
|
|
+
|
|
|
|
|
+ Ok(())
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
#[derive(Debug, Clone)]
|
|
#[derive(Debug, Clone)]
|
|
|
pub struct LongphaseHap {
|
|
pub struct LongphaseHap {
|
|
|
pub id: String,
|
|
pub id: String,
|
|
@@ -34,12 +47,32 @@ pub struct LongphaseHap {
|
|
|
job_args: Vec<String>,
|
|
job_args: Vec<String>,
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+impl InitializeSolo for LongphaseHap {
|
|
|
|
|
+ fn initialize(id: &str, time: &str, config: &Config) -> anyhow::Result<Self> {
|
|
|
|
|
+ let log_dir = format!("{}/{}/log/longphase", config.result_dir, id);
|
|
|
|
|
+
|
|
|
|
|
+ let bam = config.solo_bam(id, time);
|
|
|
|
|
+ let bam_hp = config.solo_haplotagged_bam(id, time);
|
|
|
|
|
+
|
|
|
|
|
+ let phased_vcf = config.germline_phased_vcf(id);
|
|
|
|
|
+
|
|
|
|
|
+ Ok(Self {
|
|
|
|
|
+ id: id.to_string(),
|
|
|
|
|
+ vcf: phased_vcf,
|
|
|
|
|
+ bam: PathBuf::from(bam),
|
|
|
|
|
+ bam_hp: PathBuf::from(bam_hp),
|
|
|
|
|
+ config: config.clone(),
|
|
|
|
|
+ log_dir,
|
|
|
|
|
+ job_args: Vec::new(),
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
impl LongphaseHap {
|
|
impl LongphaseHap {
|
|
|
pub fn new(id: &str, bam: &str, phased_vcf: &str, config: Config) -> Self {
|
|
pub fn new(id: &str, bam: &str, phased_vcf: &str, config: Config) -> Self {
|
|
|
let log_dir = format!("{}/{}/log/longphase", config.result_dir, id);
|
|
let log_dir = format!("{}/{}/log/longphase", config.result_dir, id);
|
|
|
|
|
|
|
|
let bam = Path::new(bam);
|
|
let bam = Path::new(bam);
|
|
|
- // TODO change that use config.haplotagged_bam_tag_name
|
|
|
|
|
let new_fn = format!("{}_HP", bam.file_stem().unwrap().to_str().unwrap());
|
|
let new_fn = format!("{}_HP", bam.file_stem().unwrap().to_str().unwrap());
|
|
|
let bam_hp = bam.with_file_name(new_fn);
|
|
let bam_hp = bam.with_file_name(new_fn);
|
|
|
|
|
|
|
@@ -97,7 +130,8 @@ impl LongphaseHap {
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
// Temporary directory for per-chromosome BAMs
|
|
// Temporary directory for per-chromosome BAMs
|
|
|
- let tmp_dir = Path::new(&self.config.tmp_dir).join("longphase_hap");
|
|
|
|
|
|
|
+ let tmp_dir =
|
|
|
|
|
+ Path::new(&self.config.tmp_dir).join(format!("longphase_hap_{}", Uuid::new_v4()));
|
|
|
fs::create_dir_all(&tmp_dir)
|
|
fs::create_dir_all(&tmp_dir)
|
|
|
.with_context(|| format!("Failed to create tmp dir {}", tmp_dir.display()))?;
|
|
.with_context(|| format!("Failed to create tmp dir {}", tmp_dir.display()))?;
|
|
|
|
|
|
|
@@ -153,7 +187,8 @@ impl LongphaseHap {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Index final BAM
|
|
// Index final BAM
|
|
|
- let mut sam_index = SamtoolsIndex::from_config(&self.config, &final_bam.to_string_lossy().to_string()) ;
|
|
|
|
|
|
|
+ let mut sam_index =
|
|
|
|
|
+ SamtoolsIndex::from_config(&self.config, final_bam.to_string_lossy().as_ref());
|
|
|
run!(&self.config, &mut sam_index)
|
|
run!(&self.config, &mut sam_index)
|
|
|
.with_context(|| format!("samtools index failed for {}", final_bam.display()))?;
|
|
.with_context(|| format!("samtools index failed for {}", final_bam.display()))?;
|
|
|
|
|
|
|
@@ -201,6 +236,18 @@ impl Run for LongphaseHap {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+impl ShouldRun for LongphaseHap {
|
|
|
|
|
+ fn should_run(&self) -> bool {
|
|
|
|
|
+ let final_bam = PathBuf::from(format!("{}.bam", self.bam_hp.to_string_lossy()));
|
|
|
|
|
+ is_file_older(
|
|
|
|
|
+ final_bam.to_string_lossy().as_ref(),
|
|
|
|
|
+ self.bam.to_string_lossy().as_ref(),
|
|
|
|
|
+ true,
|
|
|
|
|
+ )
|
|
|
|
|
+ .unwrap_or(true)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
impl crate::commands::Command for LongphaseHap {
|
|
impl crate::commands::Command for LongphaseHap {
|
|
|
fn cmd(&self) -> String {
|
|
fn cmd(&self) -> String {
|
|
|
format!("{} {}", self.config.longphase_bin, self.job_args.join(" "))
|
|
format!("{} {}", self.config.longphase_bin, self.job_args.join(" "))
|
|
@@ -258,7 +305,7 @@ impl Initialize for LongphasePhase {
|
|
|
}
|
|
}
|
|
|
let vcf = config.constit_vcf(id);
|
|
let vcf = config.constit_vcf(id);
|
|
|
let bam = config.normal_bam(id);
|
|
let bam = config.normal_bam(id);
|
|
|
- let out_prefix = path_prefix(&config.constit_phased_vcf(id))?;
|
|
|
|
|
|
|
+ let out_prefix = path_prefix(&config.germline_phased_vcf(id))?;
|
|
|
let modcall_vcf = config.longphase_modcall_vcf(id, &config.normal_name);
|
|
let modcall_vcf = config.longphase_modcall_vcf(id, &config.normal_name);
|
|
|
|
|
|
|
|
Ok(LongphasePhase {
|
|
Ok(LongphasePhase {
|
|
@@ -274,6 +321,12 @@ impl Initialize for LongphasePhase {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+impl ShouldRun for LongphasePhase {
|
|
|
|
|
+ fn should_run(&self) -> bool {
|
|
|
|
|
+ is_file_older(&self.config.germline_phased_vcf(&self.id), &self.bam, true).unwrap_or(true)
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
impl crate::commands::Command for LongphasePhase {
|
|
impl crate::commands::Command for LongphasePhase {
|
|
|
fn cmd(&self) -> String {
|
|
fn cmd(&self) -> String {
|
|
|
format!("{} {}", self.config.longphase_bin, self.job_args.join(" "))
|
|
format!("{} {}", self.config.longphase_bin, self.job_args.join(" "))
|
|
@@ -309,6 +362,9 @@ impl crate::commands::SbatchRunner for LongphasePhase {
|
|
|
|
|
|
|
|
impl Run for LongphasePhase {
|
|
impl Run for LongphasePhase {
|
|
|
fn run(&mut self) -> anyhow::Result<()> {
|
|
fn run(&mut self) -> anyhow::Result<()> {
|
|
|
|
|
+ if !self.should_run() {
|
|
|
|
|
+ info!("Germline phased vcf is up-to-date for {}.", self.id)
|
|
|
|
|
+ }
|
|
|
info!("Running longphase phase for: {}", self.vcf);
|
|
info!("Running longphase phase for: {}", self.vcf);
|
|
|
info!("Saving longphase phase results in: {}", self.out_prefix);
|
|
info!("Saving longphase phase results in: {}", self.out_prefix);
|
|
|
|
|
|
|
@@ -318,7 +374,7 @@ impl Run for LongphasePhase {
|
|
|
modcall.run()?;
|
|
modcall.run()?;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- let final_vcf = self.config.constit_phased_vcf(&self.id);
|
|
|
|
|
|
|
+ let final_vcf = self.config.germline_phased_vcf(&self.id);
|
|
|
if !Path::new(&final_vcf).exists() {
|
|
if !Path::new(&final_vcf).exists() {
|
|
|
self.job_args = vec![
|
|
self.job_args = vec![
|
|
|
"phase".to_string(),
|
|
"phase".to_string(),
|
|
@@ -467,6 +523,11 @@ impl crate::commands::SbatchRunner for LongphaseModcallSolo {
|
|
|
|
|
|
|
|
impl Run for LongphaseModcallSolo {
|
|
impl Run for LongphaseModcallSolo {
|
|
|
fn run(&mut self) -> anyhow::Result<()> {
|
|
fn run(&mut self) -> anyhow::Result<()> {
|
|
|
|
|
+ if !self.should_run() {
|
|
|
|
|
+ info!("ModCall is up-to-date for {}, {}", self.id, self.time);
|
|
|
|
|
+ return Ok(());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
self.job_args = vec![
|
|
self.job_args = vec![
|
|
|
"modcall".to_string(),
|
|
"modcall".to_string(),
|
|
|
"-b".to_string(),
|
|
"-b".to_string(),
|