use std::io::Write;
use std::path::Path;
#[derive(Debug, Clone, Default)]
pub struct BiasDump {
pub obs5_seq: Vec<f64>,
pub obs3_seq: Vec<f64>,
pub exp5_seq: Vec<f64>,
pub exp3_seq: Vec<f64>,
pub obs_gc: Vec<f64>,
pub exp_gc: Vec<f64>,
pub obs5_pos: Vec<Vec<f64>>,
pub obs3_pos: Vec<Vec<f64>>,
pub exp5_pos: Vec<Vec<f64>>,
pub exp3_pos: Vec<Vec<f64>>,
}
pub fn gz_write(path: &Path, bytes: &[u8]) -> std::io::Result<()> {
let f = std::fs::File::create(path)?;
let mut enc = flate2::write::GzEncoder::new(f, flate2::Compression::new(6));
enc.write_all(bytes)?;
enc.finish()?;
Ok(())
}
pub fn write_f64_gz(path: &Path, vals: &[f64]) -> std::io::Result<()> {
let mut b = Vec::with_capacity(vals.len() * 8);
for v in vals {
b.extend_from_slice(&v.to_le_bytes());
}
gz_write(path, &b)
}
pub fn write_i32_gz(path: &Path, vals: &[i32]) -> std::io::Result<()> {
let mut b = Vec::with_capacity(vals.len() * 4);
for v in vals {
b.extend_from_slice(&v.to_le_bytes());
}
gz_write(path, &b)
}
pub fn write_pos_gz(path: &Path, models: &[Vec<f64>]) -> std::io::Result<()> {
let bins = models.first().map(|m| m.len()).unwrap_or(0) as u32;
let mut b = Vec::new();
b.extend_from_slice(&(models.len() as u32).to_le_bytes());
b.extend_from_slice(&bins.to_le_bytes());
for m in models {
for v in m {
b.extend_from_slice(&v.to_le_bytes());
}
}
gz_write(path, &b)
}
pub fn write_fld_dump(path: &Path, pmf: &[f64]) -> std::io::Result<()> {
const N_SAMPLES: f64 = 10000.0;
let hist: Vec<i32> = pmf
.iter()
.map(|&p| (p * N_SAMPLES).round() as i32)
.collect();
write_i32_gz(path, &hist)
}
pub fn write_flen_dist(path: &Path, pmf: &[f64]) -> std::io::Result<()> {
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
let mut s = String::with_capacity(pmf.len() * 14);
for (i, p) in pmf.iter().enumerate() {
if i > 0 {
s.push('\t');
}
s.push_str(&format!("{p:e}"));
}
s.push('\n');
std::fs::write(path, s)
}
pub fn write_aux_bias_dumps(aux_dir: &Path, dump: &BiasDump) -> std::io::Result<()> {
write_i32_gz(&aux_dir.join("observed_bias.gz"), &[0])?;
write_i32_gz(&aux_dir.join("observed_bias_3p.gz"), &[0])?;
write_f64_gz(&aux_dir.join("expected_bias.gz"), &[1.0])?;
if !dump.obs5_seq.is_empty() {
write_f64_gz(&aux_dir.join("obs5_seq.gz"), &dump.obs5_seq)?;
write_f64_gz(&aux_dir.join("obs3_seq.gz"), &dump.obs3_seq)?;
write_f64_gz(&aux_dir.join("exp5_seq.gz"), &dump.exp5_seq)?;
write_f64_gz(&aux_dir.join("exp3_seq.gz"), &dump.exp3_seq)?;
}
if !dump.obs_gc.is_empty() {
write_f64_gz(&aux_dir.join("obs_gc.gz"), &dump.obs_gc)?;
write_f64_gz(&aux_dir.join("exp_gc.gz"), &dump.exp_gc)?;
}
if !dump.obs5_pos.is_empty() {
write_pos_gz(&aux_dir.join("obs5_pos.gz"), &dump.obs5_pos)?;
write_pos_gz(&aux_dir.join("obs3_pos.gz"), &dump.obs3_pos)?;
write_pos_gz(&aux_dir.join("exp5_pos.gz"), &dump.exp5_pos)?;
write_pos_gz(&aux_dir.join("exp3_pos.gz"), &dump.exp3_pos)?;
}
Ok(())
}