use anyhow::Context;
use indicatif::{MultiProgress, ProgressBar, ProgressIterator};
use log::error;
use std::sync::{mpsc, Arc};
use crate::data_types::compare_benchmark::CompareBenchmark;
use crate::data_types::compare_region::CompareRegion;
use crate::util::progress_bar::get_progress_style;
use crate::writers::region_sequence::RegionSequenceWriter;
use crate::writers::region_summary::RegionSummaryWriter;
use crate::writers::summary::SummaryWriter;
use crate::writers::variant_categorizer::{index_categorizer, VariantCategorizer};
pub fn write_compare_outputs(
all_results: Vec<(CompareRegion, Option<CompareBenchmark>)>,
summary_writer: &mut SummaryWriter,
mut truth_vcf_writer: VariantCategorizer,
mut query_vcf_writer: VariantCategorizer,
mut region_writer: Option<RegionSummaryWriter>,
mut region_seq_writer: Option<RegionSequenceWriter>
) -> anyhow::Result<()> {
let arc_all_results = Arc::new(all_results);
let multi_bar = MultiProgress::new();
let (arc_tx, rx) = mpsc::channel();
rayon::scope(|s| {
let all_results = arc_all_results.clone();
let pb = ProgressBar::new(all_results.len() as u64)
.with_style(get_progress_style())
.with_message("Gathering summary stats...");
let pb = multi_bar.add(pb);
pb.tick();
s.spawn(move|_| {
for (_region, opt_comparison) in all_results.iter() {
if let Some(comparison) = opt_comparison {
summary_writer.add_comparison_benchmark(comparison);
} else {
summary_writer.inc_error_blocks();
}
pb.inc(1);
}
pb.finish_with_message("Summary stats complete.");
});
let all_results = arc_all_results.clone();
let tx = arc_tx.clone();
let pb = ProgressBar::new(all_results.len() as u64)
.with_style(get_progress_style())
.with_message("Truth VCF writing...");
let pb = multi_bar.add(pb);
pb.tick();
s.spawn(move|_| {
let mut error = false;
for (region, opt_comparison) in all_results.iter() {
if let Some(comparison) = opt_comparison {
if let Err(e) = truth_vcf_writer.write_results(region, comparison)
.with_context(|| "Error while writing truth VCF results:") {
tx.send(e).unwrap();
pb.abandon_with_message("Truth VCF writing - ERROR");
error = true;
break;
}
}
pb.inc(1);
}
if !error {
pb.set_message("Truth VCF indexing...");
if let Err(e) = index_categorizer(truth_vcf_writer)
.with_context(|| "Error while indexing truth VCF file:") {
tx.send(e).unwrap();
pb.abandon_with_message("Truth VCF indexing - ERROR");
error = true;
}
}
if !error {
pb.finish_with_message("Truth VCF writing complete.");
}
});
let all_results = arc_all_results.clone();
let tx = arc_tx.clone();
let pb = ProgressBar::new(all_results.len() as u64)
.with_style(get_progress_style())
.with_message("Query VCF writing...");
let pb = multi_bar.add(pb);
pb.tick();
s.spawn(move|_| {
let mut error = false;
for (region, opt_comparison) in all_results.iter() {
if let Some(comparison) = opt_comparison {
if let Err(e) = query_vcf_writer.write_results(region, comparison)
.with_context(|| "Error while writing query VCF results:") {
tx.send(e).unwrap();
pb.abandon_with_message("Query VCF writing - ERROR");
error = true;
break;
}
}
pb.inc(1);
}
if !error {
pb.set_message("Query VCF indexing...");
if let Err(e) = index_categorizer(query_vcf_writer)
.with_context(|| "Error while indexing query VCF file:") {
tx.send(e).unwrap();
pb.abandon_with_message("Query VCF indexing - ERROR");
error = true;
}
}
if !error {
pb.finish_with_message("Query VCF writing complete.");
}
});
if let Some(rsw) = region_writer.as_mut() {
let all_results = arc_all_results.clone();
let tx = arc_tx.clone();
let pb = ProgressBar::new(all_results.len() as u64)
.with_style(get_progress_style())
.with_message("Region stats writing...");
let pb = multi_bar.add(pb);
pb.tick();
s.spawn(move|_| {
let mut error = false;
for (region, opt_comparison) in all_results.iter() {
if let Some(comparison) = opt_comparison {
if let Err(e) = rsw.write_region_summary(region, comparison)
.with_context(|| "Error while writing region summary results:") {
tx.send(e).unwrap();
pb.abandon_with_message("Region stats writing - ERROR");
error = true;
break;
}
}
pb.inc(1);
}
if !error {
pb.finish_with_message("Region stats writing complete.");
}
});
}
if let Some(rsw) = region_seq_writer.as_mut() {
let all_results = arc_all_results.clone();
let tx = arc_tx.clone();
let pb = ProgressBar::new(all_results.len() as u64)
.with_style(get_progress_style())
.with_message("Region sequence writing...");
let pb = multi_bar.add(pb);
pb.tick();
s.spawn(move|_| {
let mut error = false;
for (region, opt_comparison) in all_results.iter() {
if let Some(comparison) = opt_comparison {
if let Err(e) = rsw.write_region_sequences(region, comparison)
.with_context(|| "Error while writing region sequences results:") {
tx.send(e).unwrap();
pb.abandon_with_message("Region sequence writing - ERROR");
error = true;
break;
}
}
pb.inc(1);
}
if !error {
pb.finish_with_message("Region sequence writing complete.");
}
});
}
});
std::mem::drop(arc_tx);
let mut result = Ok(());
for e in rx {
error!("Error while writing files: {e:#}");
result = Err(e);
}
result
}
pub fn single_write_compare_outputs(
all_results: Vec<(CompareRegion, Option<CompareBenchmark>)>,
summary_writer: &mut SummaryWriter,
mut truth_vcf_writer: VariantCategorizer,
mut query_vcf_writer: VariantCategorizer,
mut region_writer: Option<RegionSummaryWriter>,
mut region_seq_writer: Option<RegionSequenceWriter>
) -> anyhow::Result<()> {
for (region, opt_comparison) in all_results.into_iter()
.progress_with_style(get_progress_style()) {
if let Some(comparison) = opt_comparison {
summary_writer.add_comparison_benchmark(&comparison);
truth_vcf_writer.write_results(®ion, &comparison)
.with_context(|| "Error while writing truth VCF results:")?;
query_vcf_writer.write_results(®ion, &comparison)
.with_context(|| "Error while writing query VCF results:")?;
if let Some(rsw) = region_writer.as_mut() {
rsw.write_region_summary(®ion, &comparison)
.with_context(|| "Error while writing region summary results:")?;
}
if let Some(rsw) = region_seq_writer.as_mut() {
rsw.write_region_sequences(®ion, &comparison)
.with_context(|| "Error while writing region sequences results:")?;
}
} else {
summary_writer.inc_error_blocks();
}
}
index_categorizer(truth_vcf_writer)?;
index_categorizer(query_vcf_writer)?;
Ok(())
}