|
|
@@ -778,9 +778,33 @@ pub fn par_whole_scan(id: &str, time_point: &str, config: &Config) -> anyhow::Re
|
|
|
})?;
|
|
|
|
|
|
for bin in &bins {
|
|
|
- writeln!(writer, "{}", bin.to_tsv_row()).with_context(|| {
|
|
|
- format!("failed writing {contig} row to {tmp_path_str}")
|
|
|
- })?;
|
|
|
+ let row = bin.to_tsv_row();
|
|
|
+
|
|
|
+ anyhow::ensure!(
|
|
|
+ !row.contains('\n') && !row.contains('\r'),
|
|
|
+ "BUG: to_tsv_row() contains newline for {contig}: {}:{}-{}",
|
|
|
+ bin.contig,
|
|
|
+ bin.start,
|
|
|
+ bin.end
|
|
|
+ );
|
|
|
+
|
|
|
+ let nf = row.split('\t').count();
|
|
|
+ anyhow::ensure!(
|
|
|
+ nf == 12,
|
|
|
+ "BUG: to_tsv_row() produced {nf} fields instead of 12 for {contig}: {}:{}-{}\nrow={row}",
|
|
|
+ bin.contig,
|
|
|
+ bin.start,
|
|
|
+ bin.end
|
|
|
+ );
|
|
|
+
|
|
|
+ anyhow::ensure!(
|
|
|
+ bin.contig == *contig,
|
|
|
+ "BUG: writing {contig} file but row contig is {}",
|
|
|
+ bin.contig
|
|
|
+ );
|
|
|
+
|
|
|
+ writeln!(writer, "{row}")
|
|
|
+ .with_context(|| format!("failed writing {contig} row to {tmp_path_str}"))?;
|
|
|
}
|
|
|
|
|
|
writer
|
|
|
@@ -792,9 +816,13 @@ pub fn par_whole_scan(id: &str, time_point: &str, config: &Config) -> anyhow::Re
|
|
|
})?;
|
|
|
}
|
|
|
|
|
|
- validate_count_file(tmp_path_str, contig, bins.len()).with_context(|| {
|
|
|
- format!("invalid temp count file before rename: {tmp_path_str}")
|
|
|
- })?;
|
|
|
+ validate_count_file(tmp_path_str, contig, bins.len())
|
|
|
+ .with_context(|| {
|
|
|
+ format!(
|
|
|
+ "invalid temp count file before rename: {tmp_path_str}; contig={contig}; expected_rows={}",
|
|
|
+ bins.len()
|
|
|
+ )
|
|
|
+ })?;
|
|
|
|
|
|
std::fs::rename(&tmp_path, &out_file)
|
|
|
.with_context(|| format!("failed atomic rename {tmp_path_str} -> {out_file}"))?;
|
|
|
@@ -805,15 +833,22 @@ pub fn par_whole_scan(id: &str, time_point: &str, config: &Config) -> anyhow::Re
|
|
|
Ok(())
|
|
|
}
|
|
|
|
|
|
-fn validate_count_file(path: &str, expected_contig: &str, expected_rows: usize) -> anyhow::Result<()> {
|
|
|
+fn validate_count_file(
|
|
|
+ path: &str,
|
|
|
+ expected_contig: &str,
|
|
|
+ expected_rows: usize,
|
|
|
+) -> anyhow::Result<()> {
|
|
|
let rdr = get_gz_reader(path)?;
|
|
|
let mut tsv = tsv_reader(rdr);
|
|
|
let mut rec = csv::ByteRecord::new();
|
|
|
|
|
|
let mut n = 0usize;
|
|
|
- while tsv.read_byte_record(&mut rec)
|
|
|
- .with_context(|| format!("failed reading validation record in {path} around line {}", n + 1))?
|
|
|
- {
|
|
|
+ while tsv.read_byte_record(&mut rec).with_context(|| {
|
|
|
+ format!(
|
|
|
+ "failed reading validation record in {path} around line {}",
|
|
|
+ n + 1
|
|
|
+ )
|
|
|
+ })? {
|
|
|
n += 1;
|
|
|
|
|
|
anyhow::ensure!(
|