sciforge-lib 0.0.4

Scientific computing library — mathematics, physics, chemistry, biology, astronomy, geology, meteorology.
Documentation
pub fn alpha_helix_propensity(residue_propensities: &[f64]) -> f64 {
    if residue_propensities.is_empty() {
        return 0.0;
    }
    residue_propensities.iter().sum::<f64>() / residue_propensities.len() as f64
}

pub fn beta_sheet_propensity(residue_propensities: &[f64]) -> f64 {
    if residue_propensities.is_empty() {
        return 0.0;
    }
    residue_propensities.iter().sum::<f64>() / residue_propensities.len() as f64
}

pub fn chou_fasman_nucleation(propensities: &[f64], window: usize, threshold: f64) -> Vec<bool> {
    let n = propensities.len();
    if n < window {
        return vec![false; n];
    }
    let mut result = vec![false; n];
    for i in 0..=n - window {
        let avg: f64 = propensities[i..i + window].iter().sum::<f64>() / window as f64;
        if avg > threshold {
            for item in &mut result[i..i + window] {
                *item = true;
            }
        }
    }
    result
}

pub fn gor_information_value(residue_freq_in_structure: f64, residue_freq_overall: f64) -> f64 {
    (residue_freq_in_structure / residue_freq_overall.max(1e-30)).ln()
}

pub fn coiled_coil_probability(heptad_score: f64, hydrophobic_moment: f64) -> f64 {
    let combined = heptad_score * hydrophobic_moment;
    combined / (1.0 + combined)
}

pub fn disorder_prediction(hydrophobicity: f64, charge: f64, complexity: f64) -> f64 {
    let disorder_score = charge.abs() / hydrophobicity.max(1e-30) + (1.0 - complexity);
    disorder_score / (1.0 + disorder_score)
}

pub fn solvent_accessibility(residue_asa: f64, max_asa: f64) -> f64 {
    residue_asa / max_asa.max(1e-30)
}

pub fn ramachandran_energy(phi: f64, psi: f64) -> f64 {
    let alpha_phi = -57.0_f64.to_radians();
    let alpha_psi = -47.0_f64.to_radians();
    let beta_phi = -120.0_f64.to_radians();
    let beta_psi = 120.0_f64.to_radians();

    let phi_rad = phi.to_radians();
    let psi_rad = psi.to_radians();

    let d_alpha = (phi_rad - alpha_phi).powi(2) + (psi_rad - alpha_psi).powi(2);
    let d_beta = (phi_rad - beta_phi).powi(2) + (psi_rad - beta_psi).powi(2);

    -(-d_alpha / 0.5).exp() - 0.8 * (-d_beta / 0.5).exp()
}

pub fn relative_contact_order(contacts: &[(usize, usize)], chain_length: usize) -> f64 {
    if contacts.is_empty() || chain_length == 0 {
        return 0.0;
    }
    let sum_sep: f64 = contacts
        .iter()
        .map(|(i, j)| (*j as f64 - *i as f64).abs())
        .sum();
    sum_sep / (contacts.len() as f64 * chain_length as f64)
}

pub fn hydrophobic_moment(hydrophobicities: &[f64], angle_deg: f64) -> f64 {
    let angle = angle_deg.to_radians();
    let mut hx = 0.0;
    let mut hy = 0.0;
    for (i, &h) in hydrophobicities.iter().enumerate() {
        hx += h * (i as f64 * angle).cos();
        hy += h * (i as f64 * angle).sin();
    }
    (hx * hx + hy * hy).sqrt() / hydrophobicities.len().max(1) as f64
}