Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions docs/src/content/docs/rna/preseq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,23 @@ all files directly to the output directory instead.
<FileTree>
- preseq/
- `sample.lc_extrap.txt` Library complexity extrapolation curve
- `sample.preseq_skipped.txt` Status when the estimator rejects the analysis
</FileTree>

When the estimator rejects an analysis (for example, too few distinct molecules
or a failed Good-Toulmin check), RustQC keeps the warning and writes only
`<sample>.preseq_skipped.txt`, with `STATUS` and `REASON` columns and one
`skipped` row. It does not write a complexity curve or substitute numeric
predictions. MultiQC 1.35 ignores this status file; header-only complexity
tables can instead fail in that version's Preseq module.

After a successful enabled rerun in the same output layout, only the current
artifact remains for that sample: a skipped estimate removes the previous curve,
and an estimated curve removes the previous skipped status. Files in another
previously used output layout are not removed. File write or removal errors fail
the command; old or partially updated files may remain after a failure.
Disabling preseq creates no preseq outputs and leaves existing files untouched.

### Complexity curve

**File:** `<sample>.lc_extrap.txt`
Expand Down
16 changes: 16 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1838,6 +1838,7 @@ fn write_rseqc_outputs(
};
std::fs::create_dir_all(&preseq_dir)?;
let output_path = preseq_dir.join(format!("{}.lc_extrap.txt", sample_name));
let skipped_path = preseq_dir.join(format!("{}.preseq_skipped.txt", sample_name));
accum.finalize();
let total_reads = accum.total_fragments;
let n_distinct = accum.n_distinct();
Expand All @@ -1860,13 +1861,19 @@ fn write_rseqc_outputs(
&output_path,
params.config.preseq.confidence_level,
)?;
remove_stale_preseq_output(&skipped_path)?;
let p = output_path.display().to_string();
ui.output_item("preseq", &p);
ui.output_detail(&format!("{} extrapolation points", result.curve.len(),));
written.push(("preseq".into(), p));
}
Err(e) => {
ui.warn(&format!("preseq: skipped — {}", e));
rna::preseq::write_skipped_output(&skipped_path, &e.to_string())?;
remove_stale_preseq_output(&output_path)?;
let p = skipped_path.display().to_string();
ui.output_item("preseq status", &p);
written.push(("preseq status".into(), p));
}
}
}
Expand All @@ -1876,3 +1883,12 @@ fn write_rseqc_outputs(
infer_experiment: infer_experiment_result,
})
}

fn remove_stale_preseq_output(path: &Path) -> Result<()> {
match std::fs::remove_file(path) {
Ok(()) => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e)
.with_context(|| format!("Failed to remove stale preseq output: {}", path.display())),
}
}
18 changes: 18 additions & 0 deletions src/rna/preseq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1239,6 +1239,24 @@ fn quantile(sorted: &[f64], q: f64) -> f64 {
// Output
// ============================================================================

/// Write a skipped-status TSV when the estimator rejects an analysis, without predictions.
pub fn write_skipped_output(output_path: &Path, reason: &str) -> Result<()> {
let mut f = std::fs::File::create(output_path).with_context(|| {
format!(
"Failed to create preseq skipped-status output: {}",
output_path.display()
)
})?;
let reason = reason.replace(['\t', '\r', '\n'], " ");
writeln!(f, "STATUS\tREASON\nskipped\t{reason}").with_context(|| {
format!(
"Failed to write preseq skipped-status output: {}",
output_path.display()
)
})?;
Ok(())
}

/// Write the preseq lc_extrap output in TSV format.
///
/// Output format matches preseq's lc_extrap output:
Expand Down
Loading
Loading