use std::path::PathBuf;
use anyhow::{Context, Result};
use clap::Parser;
use tracing::info;
use crate::core::profile_learner::{
read_quality_tsv, write_quality_tsv, LearnerConfig, ProfileLearner,
};
#[derive(Debug, Clone, PartialEq, clap::ValueEnum)]
pub enum ProfileFormat {
Json,
Tsv,
}
#[derive(Parser, Debug)]
pub struct LearnProfileOpts {
#[arg(long)]
pub bam: PathBuf,
#[arg(short, long)]
pub output: PathBuf,
#[arg(long, default_value_t = 1_000_000)]
pub sample_size: usize,
#[arg(long, default_value_t = 20)]
pub min_mapq: u8,
#[arg(long, value_enum, default_value_t = ProfileFormat::Json)]
pub format: ProfileFormat,
}
pub fn run(opts: LearnProfileOpts, _threads: Option<usize>) -> Result<()> {
info!(
bam = %opts.bam.display(),
output = %opts.output.display(),
sample_size = opts.sample_size,
"starting learn-profile"
);
let config = LearnerConfig {
sample_size: opts.sample_size,
min_mapq: opts.min_mapq,
};
let learner = ProfileLearner::new(config);
let profile = learner
.learn_from_bam(&opts.bam)
.with_context(|| format!("failed to learn profile from {}", opts.bam.display()))?;
match opts.format {
ProfileFormat::Json => {
let json = serde_json::to_string_pretty(&profile)
.context("failed to serialise profile to JSON")?;
std::fs::write(&opts.output, json.as_bytes())
.with_context(|| format!("failed to write profile to {}", opts.output.display()))?;
}
ProfileFormat::Tsv => {
write_quality_tsv(&profile, &opts.output).with_context(|| {
format!("failed to write TSV profile to {}", opts.output.display())
})?;
}
}
info!(
output = %opts.output.display(),
read_length = profile.read_length,
format = ?opts.format,
"profile written"
);
Ok(())
}
#[allow(dead_code)]
pub fn load_quality_tsv(path: &std::path::Path) -> Result<Vec<Vec<[f64; 2]>>> {
read_quality_tsv(path)
}