primer3 0.1.0

Safe Rust bindings to the primer3 primer design library
Documentation
//! Penalty weight configuration for primer scoring.
//!
//! Controls how primer3 balances different quality metrics when scoring
//! and ranking primers and primer pairs.

/// Weights for scoring individual primers or oligos.
///
/// Each weight controls how much a given metric contributes to the
/// overall penalty score. Higher weight = more influence on primer selection.
/// Defaults are the primer3 v2 defaults.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct OligoWeights {
    /// Weight for Tm above optimal.
    pub temp_gt: f64,
    /// Weight for Tm below optimal.
    pub temp_lt: f64,
    /// Weight for bound fraction above optimal.
    pub bound_gt: f64,
    /// Weight for bound fraction below optimal.
    pub bound_lt: f64,
    /// Weight for GC% above optimal.
    pub gc_content_gt: f64,
    /// Weight for GC% below optimal.
    pub gc_content_lt: f64,
    /// Weight for size above optimal.
    pub size_gt: f64,
    /// Weight for size below optimal.
    pub size_lt: f64,
    /// Weight for self-complementarity (any).
    pub compl_any: f64,
    /// Weight for self-complementarity (any, thermodynamic).
    pub compl_any_th: f64,
    /// Weight for 3' self-complementarity.
    pub compl_end: f64,
    /// Weight for 3' self-complementarity (thermodynamic).
    pub compl_end_th: f64,
    /// Weight for hairpin stability.
    pub hairpin_th: f64,
    /// Weight for number of Ns.
    pub num_ns: f64,
    /// Weight for repeat library similarity.
    pub repeat_sim: f64,
    /// Weight for sequence quality.
    pub seq_quality: f64,
    /// Weight for end sequence quality.
    pub end_quality: f64,
    /// Weight for position penalty.
    pub pos_penalty: f64,
    /// Weight for end stability.
    pub end_stability: f64,
    /// Weight for template mispriming.
    pub template_mispriming: f64,
    /// Weight for template mispriming (thermodynamic).
    pub template_mispriming_th: f64,
    /// Weight for primer failure rate.
    pub failure_rate: f64,
}

impl Default for OligoWeights {
    fn default() -> Self {
        Self {
            temp_gt: 1.0,
            temp_lt: 1.0,
            bound_gt: 0.0,
            bound_lt: 0.0,
            gc_content_gt: 0.0,
            gc_content_lt: 0.0,
            size_gt: 1.0,
            size_lt: 1.0,
            compl_any: 0.0,
            compl_any_th: 0.0,
            compl_end: 0.0,
            compl_end_th: 0.0,
            hairpin_th: 0.0,
            num_ns: 0.0,
            repeat_sim: 0.0,
            seq_quality: 0.0,
            end_quality: 0.0,
            pos_penalty: 1.0,
            end_stability: 0.0,
            template_mispriming: 0.0,
            template_mispriming_th: 0.0,
            failure_rate: 0.0,
        }
    }
}

/// Weights for scoring primer pairs.
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct PairWeights {
    /// Weight for left/right primer individual quality.
    pub primer_quality: f64,
    /// Weight for internal oligo quality.
    pub io_quality: f64,
    /// Weight for Tm difference between primers.
    pub diff_tm: f64,
    /// Weight for pair complementarity (any).
    pub compl_any: f64,
    /// Weight for pair complementarity (any, thermodynamic).
    pub compl_any_th: f64,
    /// Weight for pair 3' complementarity.
    pub compl_end: f64,
    /// Weight for pair 3' complementarity (thermodynamic).
    pub compl_end_th: f64,
    /// Weight for product Tm below optimal.
    pub product_tm_lt: f64,
    /// Weight for product Tm above optimal.
    pub product_tm_gt: f64,
    /// Weight for product size below optimal.
    pub product_size_lt: f64,
    /// Weight for product size above optimal.
    pub product_size_gt: f64,
    /// Weight for repeat library similarity.
    pub repeat_sim: f64,
    /// Weight for template mispriming.
    pub template_mispriming: f64,
    /// Weight for template mispriming (thermodynamic).
    pub template_mispriming_th: f64,
}

impl Default for PairWeights {
    fn default() -> Self {
        Self {
            primer_quality: 1.0,
            io_quality: 0.0,
            diff_tm: 0.0,
            compl_any: 0.0,
            compl_any_th: 0.0,
            compl_end: 0.0,
            compl_end_th: 0.0,
            product_tm_lt: 0.0,
            product_tm_gt: 0.0,
            product_size_lt: 0.0,
            product_size_gt: 0.0,
            repeat_sim: 0.0,
            template_mispriming: 0.0,
            template_mispriming_th: 0.0,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_oligo_weights_default() {
        let w = OligoWeights::default();
        assert!((w.temp_gt - 1.0).abs() < f64::EPSILON);
        assert!((w.temp_lt - 1.0).abs() < f64::EPSILON);
        assert!((w.size_gt - 1.0).abs() < f64::EPSILON);
        assert!((w.size_lt - 1.0).abs() < f64::EPSILON);
        assert!((w.gc_content_gt - 0.0).abs() < f64::EPSILON);
        assert!((w.num_ns - 0.0).abs() < f64::EPSILON);
    }

    #[test]
    fn test_pair_weights_default() {
        let w = PairWeights::default();
        assert!((w.primer_quality - 1.0).abs() < f64::EPSILON);
        assert!((w.io_quality - 0.0).abs() < f64::EPSILON);
        assert!((w.diff_tm - 0.0).abs() < f64::EPSILON);
        assert!((w.compl_any - 0.0).abs() < f64::EPSILON);
    }
}