|
@@ -722,7 +722,8 @@ pub fn par_whole_scan(id: &str, time_point: &str, config: &Config) -> anyhow::Re
|
|
|
bin_size,
|
|
bin_size,
|
|
|
chunk_n_bin,
|
|
chunk_n_bin,
|
|
|
config.bam_min_mapq,
|
|
config.bam_min_mapq,
|
|
|
- )?;
|
|
|
|
|
|
|
+ )
|
|
|
|
|
+ .with_context(|| format!("failed scanning contig {contig}"))?;
|
|
|
|
|
|
|
|
debug!("Scan {contig}, sorting bins");
|
|
debug!("Scan {contig}, sorting bins");
|
|
|
bins.par_sort_unstable_by(|a, b| a.start.cmp(&b.start));
|
|
bins.par_sort_unstable_by(|a, b| a.start.cmp(&b.start));
|
|
@@ -732,40 +733,47 @@ pub fn par_whole_scan(id: &str, time_point: &str, config: &Config) -> anyhow::Re
|
|
|
|
|
|
|
|
debug!("Scan {contig}, writing file");
|
|
debug!("Scan {contig}, writing file");
|
|
|
|
|
|
|
|
- {
|
|
|
|
|
- let temp_file = tempfile::NamedTempFile::new_in(&config.tmp_dir)
|
|
|
|
|
- .with_context(|| format!("failed to create temp file in {out_dir:?}"))?;
|
|
|
|
|
-
|
|
|
|
|
- let temp_path = temp_file.into_temp_path();
|
|
|
|
|
|
|
+ let out_path = std::path::Path::new(&out_file);
|
|
|
|
|
+ let out_parent = out_path
|
|
|
|
|
+ .parent()
|
|
|
|
|
+ .with_context(|| format!("output file has no parent: {out_file}"))?;
|
|
|
|
|
|
|
|
- {
|
|
|
|
|
- let temp_path_str = temp_path
|
|
|
|
|
- .to_str()
|
|
|
|
|
- .with_context(|| format!("temp path not valid UTF-8: {temp_path:?}"))?;
|
|
|
|
|
|
|
+ std::fs::create_dir_all(out_parent)
|
|
|
|
|
+ .with_context(|| format!("failed to create output dir: {out_parent:?}"))?;
|
|
|
|
|
|
|
|
- let mut writer = get_gz_writer(temp_path_str, true)
|
|
|
|
|
- .with_context(|| format!("failed to open BGZF file: {temp_path_str}"))?;
|
|
|
|
|
|
|
+ let tmp_path = out_parent.join(format!(
|
|
|
|
|
+ ".{}.{}.{}.tmp",
|
|
|
|
|
+ contig,
|
|
|
|
|
+ std::process::id(),
|
|
|
|
|
+ std::thread::current().name().unwrap_or("rayon")
|
|
|
|
|
+ ));
|
|
|
|
|
|
|
|
- for bin in &bins {
|
|
|
|
|
- writeln!(writer, "{}", bin.to_tsv_row()).with_context(|| {
|
|
|
|
|
- format!("failed writing {contig} row to {temp_path_str}")
|
|
|
|
|
- })?;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ let tmp_path_str = tmp_path
|
|
|
|
|
+ .to_str()
|
|
|
|
|
+ .with_context(|| format!("temp path is not valid UTF-8: {tmp_path:?}"))?;
|
|
|
|
|
|
|
|
- writer
|
|
|
|
|
- .flush()
|
|
|
|
|
- .with_context(|| format!("failed flushing BGZF writer: {temp_path_str}"))?;
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ let mut writer = get_gz_writer(tmp_path_str, true)
|
|
|
|
|
+ .with_context(|| format!("failed to open BGZF temp file: {tmp_path_str}"))?;
|
|
|
|
|
|
|
|
- writer
|
|
|
|
|
- .close()
|
|
|
|
|
- .with_context(|| format!("failed closing BGZF writer: {temp_path_str}"))?;
|
|
|
|
|
|
|
+ for bin in &bins {
|
|
|
|
|
+ writeln!(writer, "{}", bin.to_tsv_row()).with_context(|| {
|
|
|
|
|
+ format!("failed writing {contig} row to {tmp_path_str}")
|
|
|
|
|
+ })?;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- temp_path
|
|
|
|
|
- .persist(&out_file)
|
|
|
|
|
- .with_context(|| format!("failed atomic rename to {out_file}"))?;
|
|
|
|
|
|
|
+ writer
|
|
|
|
|
+ .flush()
|
|
|
|
|
+ .with_context(|| format!("failed flushing BGZF writer: {tmp_path_str}"))?;
|
|
|
|
|
+
|
|
|
|
|
+ writer.close().with_context(|| {
|
|
|
|
|
+ format!("failed closing/finalizing BGZF writer: {tmp_path_str}")
|
|
|
|
|
+ })?;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ std::fs::rename(&tmp_path, &out_file)
|
|
|
|
|
+ .with_context(|| format!("failed atomic rename {tmp_path_str} -> {out_file}"))?;
|
|
|
|
|
+
|
|
|
Ok(())
|
|
Ok(())
|
|
|
})?;
|
|
})?;
|
|
|
|
|
|