pub mod consts;
pub mod io;
use std::sync::LazyLock;
use crate::utils::consts::PROTOR_RADII;
use fnv::{FnvHashMap, FnvHasher};
use pulp::Arch;
use rayon::ThreadPoolBuilder;
use std::hash::{Hash, Hasher};
pub(crate) static ARCH: LazyLock<Arch> = LazyLock::new(Arch::new);
pub(crate) fn simd_sum(values: &[f32]) -> f32 {
let mut total = 0f32;
ARCH.dispatch(|| {
for x in values {
total += x;
}
});
total
}
pub fn serialize_chain_id(s: &str) -> isize {
let mut result = 0;
for c in s.chars() {
if c.is_ascii_alphabetic() {
let position = c.to_ascii_uppercase() as isize - 64;
result = result * 10 + position;
}
}
result
}
pub fn get_protor_radius(residue: &str, atom: &str) -> Option<f32> {
PROTOR_RADII.get(residue)?.get(atom).copied()
}
pub fn get_radius(
residue_name: &str,
atom_name: &str,
radii_config: Option<&FnvHashMap<String, FnvHashMap<String, f32>>>,
) -> Option<f32> {
if let Some(config) = radii_config {
if let Some(radius) = config
.get(residue_name)
.and_then(|inner| inner.get(atom_name))
{
return Some(*radius);
}
}
get_protor_radius(residue_name, atom_name)
}
pub fn configure_thread_pool(threads: isize) -> Result<(), std::io::Error> {
if threads == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::InvalidInput,
"Thread count must be -1 (all cores) or a positive number",
));
}
if threads > 0 {
ThreadPoolBuilder::new()
.num_threads(threads as usize)
.build_global()
.map_err(|e| std::io::Error::other(format!("Failed to configure thread pool: {e}")))?;
}
Ok(())
}
pub(crate) fn combine_hash<N: Hash>(inputs: &N) -> isize {
let mut hasher = FnvHasher::default();
inputs.hash(&mut hasher);
hasher.finish() as isize
}