From ec76406307ec5f9691482095fea4adf504569501 Mon Sep 17 00:00:00 2001 From: David O'Connor Date: Thu, 29 Aug 2024 20:57:06 -0400 Subject: [PATCH] Work regarding salt con --- README.md | 7 +- screenshots/primers_aug_24.png | Bin 0 -> 95057 bytes src/gui/circle.rs | 13 +- src/gui/feature_table.rs | 13 +- src/gui/sequence.rs | 3 +- src/melting_temp_calcs.rs | 49 +++-- src/melting_temp_calcs.rs~ | 343 +++++++++++++++++++++++++++++++++ src/sequence.rs | 24 +++ 8 files changed, 419 insertions(+), 33 deletions(-) create mode 100644 screenshots/primers_aug_24.png create mode 100644 src/melting_temp_calcs.rs~ diff --git a/README.md b/README.md index 14b8200..e792f46 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ sequence on this end. The end point can then be adjusted to optimize primer qual When both ends are marked as tunable, PlasCAD assumes this primer is for attaching two DNA fragments together, as in SLIC and FC cloning. +![Primer view screenshot](screenshots/primers_aug_24.png) + ### Primer generation for SLIC and FastCloning Given the sequences for an insert, a vector, and insertion point, it will generate primers suitable for SLIC and FastCloning. @@ -150,6 +152,9 @@ a fast, lightweight program that's as easy to use as possible, without sacrifici Also of note, the native file format this program uses is more compact, including for DNA sequences, where each nucleotide only takes up 2 bits, as opposed to 8 in common formats. +Performance is a top priority; compared to other tools, this has a small program size, small memory footprint, and low CPU use. +It starts fast, and responds instantly. + ## Near-term plans - QCing plasmids for toxic proteins, hydrophobic regions, and aggregation-prone regions @@ -167,7 +172,7 @@ primer Molar concentration: $$ (1000 * ΔH) / (ΔS + R \times ln(\frac{C_T}{4})) - 273.15 $$ -The calculation also includes salt correction, derived from BioPython, using concentrations of $K^+$, $Na^+$, $Mg^{2+}$, and dntp concentration. These are provided by the user, or initiated with defaults. +The calculation also includes salt correction, derived from BioPython, using concentrations of $K^+$, $Na^+$, $Mg^{2+}$, and dntp concentration. (SantaLucia, 1998) These ion concentrations are provided by the user, or initiated with defaults. We score primer length compared to an ideal of 18-24 nucleotides. Note that for cloning primers that join sequences (eg SLIC insert primers), length is scored between each end and the anchor (The point the two sequences are joined at, towards the middle of the primer.) We expect these primers to be about twice the length of normal primers. diff --git a/screenshots/primers_aug_24.png b/screenshots/primers_aug_24.png new file mode 100644 index 0000000000000000000000000000000000000000..dab7553a3afc78bc7fcb6056975751ed01e413d3 GIT binary patch literal 95057 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 ^aLCe*Cq-4fuk)xDEO+aIOeIB&mh_K+n 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 literal 0 HcmV?d00001 diff --git a/src/gui/circle.rs b/src/gui/circle.rs index 333613d..13f0da9 100644 --- a/src/gui/circle.rs +++ b/src/gui/circle.rs @@ -4,8 +4,8 @@ use core::f32::consts::TAU; use eframe::{ egui::{ - pos2, vec2, Align2, Color32, FontFamily, FontId, Frame, Pos2, Rect, RichText, ScrollArea, - Sense, Shape, Slider, Stroke, Ui, + pos2, vec2, Align2, Color32, CursorIcon, FontFamily, FontId, Frame, Pos2, Rect, RichText, + ScrollArea, Sense, Shape, Slider, Stroke, Ui, }, emath::RectTransform, epaint::{CircleShape, PathShape}, @@ -63,7 +63,7 @@ const CIRCLE_SIZE_RATIO: f32 = 0.42; // The maximum distance the cursor can be from the circle for various tasks like selection, finding // the cursor position etc. -const SELECTION_MAX_DIST: f32 = 100.; +const SELECTION_MAX_DIST: f32 = 80.; const CENTER_TEXT_ROW_SPACING: f32 = 20.; @@ -1000,6 +1000,13 @@ pub fn circle_page(state: &mut State, ui: &mut Ui) { }); } + ui.ctx() + .set_cursor_icon(if state.ui.feature_hover.is_some() { + CursorIcon::PointingHand + } else { + CursorIcon::Default + }); + Frame::canvas(ui.style()) .fill(BACKGROUND_COLOR) .show(ui, |ui| { diff --git a/src/gui/feature_table.rs b/src/gui/feature_table.rs index 552d99a..274dd53 100644 --- a/src/gui/feature_table.rs +++ b/src/gui/feature_table.rs @@ -1,6 +1,8 @@ //! GUI code for the features editor and related. -use eframe::egui::{Color32, ComboBox, Frame, RichText, ScrollArea, Stroke, TextEdit, Ui}; +use eframe::egui::{ + Color32, ComboBox, CursorIcon, Frame, RichText, ScrollArea, Sense, Stroke, TextEdit, Ui, +}; use crate::{ gui::{int_field, COL_SPACING, ROW_SPACING}, @@ -94,7 +96,14 @@ pub fn feature_table(state: &mut State, ui: &mut Ui) { .stroke(Stroke::new(border_width, Color32::LIGHT_RED)) .inner_margin(border_width) .show(ui, |ui| { - ui.heading(RichText::new(&feature.label).color(Color32::GOLD)); + if ui + .heading(RichText::new(&feature.label).color(Color32::GOLD)) + .on_hover_cursor(CursorIcon::PointingHand) + .clicked() + { + state.ui.selected_item = Selection::Feature(i); + } + ui.horizontal(|ui| { int_field(&mut feature.range.start, "Start:", ui); int_field(&mut feature.range.end, "End:", ui); diff --git a/src/gui/sequence.rs b/src/gui/sequence.rs index 2836690..97263e2 100644 --- a/src/gui/sequence.rs +++ b/src/gui/sequence.rs @@ -71,9 +71,10 @@ fn primer_text(i: usize, primers: &[Primer], seq_len: usize, ui: &mut Ui) { ui.label(&primer.name); ui.label(&primer.location_descrip()); - ui.label(&primer.description.clone().unwrap_or_default()); // todo: Rev color A/R ui.label(RichText::new(seq_to_str(&primer.sequence)).color(PRIMER_FWD_COLOR)); + + ui.label(&primer.description.clone().unwrap_or_default()); } /// Add a toolbar to create a feature from selection, if appropriate. diff --git a/src/melting_temp_calcs.rs b/src/melting_temp_calcs.rs index 0ed316b..2ff71ec 100644 --- a/src/melting_temp_calcs.rs +++ b/src/melting_temp_calcs.rs @@ -14,6 +14,8 @@ use crate::{ sequence::Nucleotide::{self, A, C, G, T}, }; +const R: f32 = 1.987; // Universal gas constant (Cal/C * Mol) + /// Enthalpy (dH) and entropy (dS) tables based on terminal missmatch fn _dH_dS_tmm(nts: (Nucleotide, Nucleotide)) -> Option<(f32, f32)> { match nts { @@ -160,18 +162,23 @@ fn _dH_dS_de(nts: (Nucleotide, Nucleotide)) -> Option<(f32, f32)> { /// SantaLucia & Hicks, 2004, Table 1. Value are in kcal/Mol. /// /// `neighbors` refers to the values between adjacent pairs of NTs. +/// To interpret this table, and come up with this result, search it in these +/// two manners: +/// A: Left to right, left of the slash +/// B: Right to left, right of the slash +/// You will find exactly one match using this approach. fn dH_dS_neighbors(neighbors: (Nucleotide, Nucleotide)) -> (f32, f32) { match neighbors { (A, A) | (T, T) => (-7.6, -21.3), (A, T) => (-7.2, -20.4), (T, A) => (-7.2, -21.3), - (T, G) | (C, A) => (-8.5, -22.7), - (A, C) | (G, T) => (-8.4, -22.4), - (A, G) | (C, T) => (-7.8, -21.0), - (T, C) | (G, A) => (-8.2, -22.2), + (C, A) | (T, G) => (-8.5, -22.7), + (G, T) | (A, C) => (-8.4, -22.4), + (C, T) | (A, G) => (-7.8, -21.0), + (G, A) | (T, C) => (-8.2, -22.2), (C, G) => (-10.6, -27.2), (G, C) => (-9.8, -24.4), - (C, C) | (G, G) => (-8.0, -19.9), + (G, G) | (C, C) => (-8.0, -19.9), } } @@ -180,7 +187,7 @@ fn dH_dS_neighbors(neighbors: (Nucleotide, Nucleotide)) -> (f32, f32) { fn salt_correction(seq: &[Nucleotide], ion: &IonConcentrations) -> Option { // todo: Using Some casual defaults for now. // These are millimolar concentration of respective ions. - let method = 4; // todo? + let method = 5; // todo? let tris = 0.; // todo: Do we want this? @@ -271,7 +278,7 @@ pub fn calc_tm(seq: &[Nucleotide], ion_concentrations: &IonConcentrations) -> Op return None; } - // Inititial values. (Table 1) + // Inititial values. (S&H, Table 1) let mut dH = 0.2; let mut dS = -5.7; @@ -285,7 +292,7 @@ pub fn calc_tm(seq: &[Nucleotide], ion_concentrations: &IonConcentrations) -> Op { let term_pair = vec![seq[0], seq[seq.len() - 1]]; let mut at_term_count = 0; - //C onstants for the CG term are 0, so we don't need it. + // Constants for the CG term are 0, so we don't need it. for nt in term_pair { if nt == A || nt == T { at_term_count += 1; @@ -307,33 +314,23 @@ pub fn calc_tm(seq: &[Nucleotide], ion_concentrations: &IonConcentrations) -> Op dS += dS_nn; } - const R: f32 = 1.987; // Universal gas constant (Cal/C * Mol) - - // We are multiplying by two, as it's one per strand. - let C_T = (ion_concentrations.primer * 2.) * 1.0e-9; + let C_T = ion_concentrations.primer * 1.0e-9; - // SantaLucia and Hicks, Equation 3. - let mut result = (1_000. * dH) / (dS + R * ((C_T / 4.).ln())) - 273.15; + // println!("\n\ndH: {dH} dS: {dS}"); - // if saltcorr == 5: - // delta_s += corr - // melting_temp = (1000 * delta_h) / (delta_s + (R * (math.log(k)))) - 273.15 - // if saltcorr in (1, 2, 3, 4): - // melting_temp += corr - // if saltcorr in (6, 7): - // # Tm = 1/(1/Tm + corr) - // melting_temp = 1 / (1 / (melting_temp + 273.15) + corr) - 273.15 - - // We will assume saltcorr method 1-4 for now. if let Some(sc) = salt_correction(seq, ion_concentrations) { - // todo: Put back! Evaluating our method. + // Hard-coded for salt-correction method 5. + dS += sc; // result += sc; // for saltcorr 6/7: // result = 1. / (1. / (result + 273.15) + sc) - 273.15 } else { - println!("Error on SC") + eprintln!("Error calculating salt correction."); } + // SantaLucia and Hicks, Equation 3. Note the C_T / 2 vice / 4, due to double-stranded concentration. + let result = (1_000. * dH) / (dS + R * (C_T / 2.).ln()) - 273.15; + Some(result) } diff --git a/src/melting_temp_calcs.rs~ b/src/melting_temp_calcs.rs~ new file mode 100644 index 0000000..2a821d6 --- /dev/null +++ b/src/melting_temp_calcs.rs~ @@ -0,0 +1,343 @@ +#![allow(non_snake_case)] + +//! Primer melting temperature calculations. Modified from [BioPython's module here](https://github.com/biopython/biopython/blob/master/Bio/SeqUtils/MeltingTemp.py) +//! We use an approach that calculates enthalpy and entropy of neighbors basd on empirical data, +//! and apply salt corrections based on user input concentrations of ions and primers. +//! +//! The calculations are based primarily on [SantaLucia & Hicks (2004)](https://pubmed.ncbi.nlm.nih.gov/15139820/) +//! +//! [This calculator from NorthWestern](http://biotools.nubic.northwestern.edu/OligoCalc.html) may be used +//! for QC TM, weight, and other properties. It includes detailed sources and methods. + +use crate::{ + primer::{calc_gc, IonConcentrations, MIN_PRIMER_LEN}, + sequence::Nucleotide::{self, A, C, G, T}, +}; + +const R: f32 = 1.987; // Universal gas constant (Cal/C * Mol) + +/// Enthalpy (dH) and entropy (dS) tables based on terminal missmatch +fn _dH_dS_tmm(nts: (Nucleotide, Nucleotide)) -> Option<(f32, f32)> { + match nts { + (A, A) => Some((-7.6, -21.3)), + (A, T) => Some((-7.2, -20.4)), + (T, A) => Some((-7.2, -21.3)), + (C, A) => Some((-8.5, -22.7)), + (C, G) => Some((-10.6, -27.2)), + (G, A) => Some((-8.2, -22.2)), + (G, C) => Some((-9.8, -24.4)), + (G, T) => Some((-8.4, -22.4)), + (G, G) => Some((-8.0, -19.9)), + _ => None, + } + + // # Terminal mismatch table (DNA) + // # SantaLucia & Peyret (2001) Patent Application WO 01/94611 + // DNA_TMM1 = { + // "AA/TA": (-3.1, -7.8), + // "TA/AA": (-2.5, -6.3), + // "CA/GA": (-4.3, -10.7), + // "GA/CA": (-8.0, -22.5), + // "AC/TC": (-0.1, 0.5), + // "TC/AC": (-0.7, -1.3), + // "CC/GC": (-2.1, -5.1), + // "GC/CC": (-3.9, -10.6), + // "AG/TG": (-1.1, -2.1), + // "TG/AG": (-1.1, -2.7), + // "CG/GG": (-3.8, -9.5), + // "GG/CG": (-0.7, -19.2), + // "AT/TT": (-2.4, -6.5), + // "TT/AT": (-3.2, -8.9), + // "CT/GT": (-6.1, -16.9), + // "GT/CT": (-7.4, -21.2), + // "AA/TC": (-1.6, -4.0), + // "AC/TA": (-1.8, -3.8), + // "CA/GC": (-2.6, -5.9), + // "CC/GA": (-2.7, -6.0), + // "GA/CC": (-5.0, -13.8), + // "GC/CA": (-3.2, -7.1), + // "TA/AC": (-2.3, -5.9), "TC/AA": (-2.7, -7.0), + // "AC/TT": (-0.9, -1.7), "AT/TC": (-2.3, -6.3), "CC/GT": (-3.2, -8.0), + // "CT/GC": (-3.9, -10.6), "GC/CT": (-4.9, -13.5), "GT/CC": (-3.0, -7.8), + // "TC/AT": (-2.5, -6.3), "TT/AC": (-0.7, -1.2), + // "AA/TG": (-1.9, -4.4), "AG/TA": (-2.5, -5.9), "CA/GG": (-3.9, -9.6), + // "CG/GA": (-6.0, -15.5), "GA/CG": (-4.3, -11.1), "GG/CA": (-4.6, -11.4), + // "TA/AG": (-2.0, -4.7), "TG/AA": (-2.4, -5.8), + // "AG/TT": (-3.2, -8.7), "AT/TG": (-3.5, -9.4), "CG/GT": (-3.8, -9.0), + // "CT/GG": (-6.6, -18.7), "GG/CT": (-5.7, -15.9), "GT/CG": (-5.9, -16.1), + // "TG/AT": (-3.9, -10.5), "TT/AG": (-3.6, -9.8)} +} + +/// Enthalpy (dH) and entropy (dS) tables based on internal missmatch +fn _dH_dS_imm(nts: (Nucleotide, Nucleotide)) -> Option<(f32, f32)> { + match nts { + (A, A) => Some((-7.6, -21.3)), + (A, T) => Some((-7.2, -20.4)), + (T, A) => Some((-7.2, -21.3)), + (C, A) => Some((-8.5, -22.7)), + (C, G) => Some((-10.6, -27.2)), + (G, A) => Some((-8.2, -22.2)), + (G, C) => Some((-9.8, -24.4)), + (G, T) => Some((-8.4, -22.4)), + (G, G) => Some((-8.0, -19.9)), + _ => None, + } + + // # Internal mismatch and inosine table (DNA) + // # Allawi & SantaLucia (1997), Biochemistry 36: 10581-10594 + // # Allawi & SantaLucia (1998), Biochemistry 37: 9435-9444 + // # Allawi & SantaLucia (1998), Biochemistry 37: 2170-2179 + // # Allawi & SantaLucia (1998), Nucl Acids Res 26: 2694-2701 + // # Peyret et al. (1999), Biochemistry 38: 3468-3477 + // # Watkins & SantaLucia (2005), Nucl Acids Res 33: 6258-6267 + // DNA_IMM1 = { + // "AG/TT": (1.0, 0.9), "AT/TG": (-2.5, -8.3), "CG/GT": (-4.1, -11.7), + // "CT/GG": (-2.8, -8.0), "GG/CT": (3.3, 10.4), "GG/TT": (5.8, 16.3), + // "GT/CG": (-4.4, -12.3), "GT/TG": (4.1, 9.5), "TG/AT": (-0.1, -1.7), + // "TG/GT": (-1.4, -6.2), "TT/AG": (-1.3, -5.3), "AA/TG": (-0.6, -2.3), + // "AG/TA": (-0.7, -2.3), "CA/GG": (-0.7, -2.3), "CG/GA": (-4.0, -13.2), + // "GA/CG": (-0.6, -1.0), "GG/CA": (0.5, 3.2), "TA/AG": (0.7, 0.7), + // "TG/AA": (3.0, 7.4), + // "AC/TT": (0.7, 0.2), "AT/TC": (-1.2, -6.2), "CC/GT": (-0.8, -4.5), + // "CT/GC": (-1.5, -6.1), "GC/CT": (2.3, 5.4), "GT/CC": (5.2, 13.5), + // "TC/AT": (1.2, 0.7), "TT/AC": (1.0, 0.7), + // "AA/TC": (2.3, 4.6), "AC/TA": (5.3, 14.6), "CA/GC": (1.9, 3.7), + // "CC/GA": (0.6, -0.6), "GA/CC": (5.2, 14.2), "GC/CA": (-0.7, -3.8), + // "TA/AC": (3.4, 8.0), "TC/AA": (7.6, 20.2), + // "AA/TA": (1.2, 1.7), "CA/GA": (-0.9, -4.2), "GA/CA": (-2.9, -9.8), + // "TA/AA": (4.7, 12.9), "AC/TC": (0.0, -4.4), "CC/GC": (-1.5, -7.2), + // "GC/CC": (3.6, 8.9), "TC/AC": (6.1, 16.4), "AG/TG": (-3.1, -9.5), + // "CG/GG": (-4.9, -15.3), "GG/CG": (-6.0, -15.8), "TG/AG": (1.6, 3.6), + // "AT/TT": (-2.7, -10.8), "CT/GT": (-5.0, -15.8), "GT/CT": (-2.2, -8.4), + // "TT/AT": (0.2, -1.5), + // "AI/TC": (-8.9, -25.5), "TI/AC": (-5.9, -17.4), "AC/TI": (-8.8, -25.4), + // "TC/AI": (-4.9, -13.9), "CI/GC": (-5.4, -13.7), "GI/CC": (-6.8, -19.1), + // "CC/GI": (-8.3, -23.8), "GC/CI": (-5.0, -12.6), + // "AI/TA": (-8.3, -25.0), "TI/AA": (-3.4, -11.2), "AA/TI": (-0.7, -2.6), + // "TA/AI": (-1.3, -4.6), "CI/GA": (2.6, 8.9), "GI/CA": (-7.8, -21.1), + // "CA/GI": (-7.0, -20.0), "GA/CI": (-7.6, -20.2), + // "AI/TT": (0.49, -0.7), "TI/AT": (-6.5, -22.0), "AT/TI": (-5.6, -18.7), + // "TT/AI": (-0.8, -4.3), "CI/GT": (-1.0, -2.4), "GI/CT": (-3.5, -10.6), + // "CT/GI": (0.1, -1.0), "GT/CI": (-4.3, -12.1), + // "AI/TG": (-4.9, -15.8), "TI/AG": (-1.9, -8.5), "AG/TI": (0.1, -1.8), + // "TG/AI": (1.0, 1.0), "CI/GG": (7.1, 21.3), "GI/CG": (-1.1, -3.2), + // "CG/GI": (5.8, 16.9), "GG/CI": (-7.6, -22.0), + // "AI/TI": (-3.3, -11.9), "TI/AI": (0.1, -2.3), "CI/GI": (1.3, 3.0), + // "GI/CI": (-0.5, -1.3)} +} + +/// Enthalpy (dH) and entropy (dS) tables based on dangling ends. +fn _dH_dS_de(nts: (Nucleotide, Nucleotide)) -> Option<(f32, f32)> { + match nts { + (A, A) => Some((0.2, 2.3)), + (A, T) => Some((-7.2, -20.4)), + (T, A) => Some((-7.2, -21.3)), + (C, A) => Some((-8.5, -22.7)), + (C, G) => Some((-10.6, -27.2)), + (G, A) => Some((-8.2, -22.2)), + (G, C) => Some((-9.8, -24.4)), + (G, T) => Some((-8.4, -22.4)), + (G, G) => Some((-8.0, -19.9)), + _ => None, + } + + // # Dangling ends table (DNA) + // # Bommarito et al. (2000), Nucl Acids Res 28: 1929-1934 + // DNA_DE1 = { + // "AA/.T": (0.2, 2.3), "AC/.G": (-6.3, -17.1), "AG/.C": (-3.7, -10.0), + // "AT/.A": (-2.9, -7.6), "CA/.T": (0.6, 3.3), "CC/.G": (-4.4, -12.6), + // "CG/.C": (-4.0, -11.9), "CT/.A": (-4.1, -13.0), "GA/.T": (-1.1, -1.6), + // "GC/.G": (-5.1, -14.0), "GG/.C": (-3.9, -10.9), "GT/.A": (-4.2, -15.0), + // "TA/.T": (-6.9, -20.0), "TC/.G": (-4.0, -10.9), "TG/.C": (-4.9, -13.8), + // "TT/.A": (-0.2, -0.5), + // ".A/AT": (-0.7, -0.8), ".C/AG": (-2.1, -3.9), ".G/AC": (-5.9, -16.5), + // ".T/AA": (-0.5, -1.1), ".A/CT": (4.4, 14.9), ".C/CG": (-0.2, -0.1), + // ".G/CC": (-2.6, -7.4), ".T/CA": (4.7, 14.2), ".A/GT": (-1.6, -3.6), + // ".C/GG": (-3.9, -11.2), ".G/GC": (-3.2, -10.4), ".T/GA": (-4.1, -13.1), + // ".A/TT": (2.9, 10.4), ".C/TG": (-4.4, -13.1), ".G/TC": (-5.2, -15.0), + // ".T/TA": (-3.8, -12.6)} +} + +/// Enthalpy (dH) and entropy (dS) based on nearest neighbors. +/// SantaLucia & Hicks, 2004, Table 1. Value are in kcal/Mol. +/// +/// `neighbors` refers to the values between adjacent pairs of NTs. +/// To interpret this table, and come up with this result, search it in these +/// two manners: +/// A: Left to right, left of the slash +/// B: Right to left, right of the slash +/// You will find exactly one match using this approach. +fn dH_dS_neighbors(neighbors: (Nucleotide, Nucleotide)) -> (f32, f32) { + match neighbors { + (A, A) | (T, T) => (-7.6, -21.3), + (A, T) => (-7.2, -20.4), + (T, A) => (-7.2, -21.3), + (C, A) | (T, G) => (-8.5, -22.7), + (G, T) | (A, C) => (-8.4, -22.4), + (C, T) | (A, G) => (-7.8, -21.0), + (G, A) | (T, C) => (-8.2, -22.2), + (C, G) => (-10.6, -27.2), + (G, C) => (-9.8, -24.4), + (G, G) | (C, C) => (-8.0, -19.9), + } +} + +/// Calculate a Tm correction term due to salt ions. +/// https://github.com/biopython/biopython/blob/master/Bio/SeqUtils/MeltingTemp.py#L475 +fn salt_correction(seq: &[Nucleotide], ion: &IonConcentrations) -> Option { + // todo: Using Some casual defaults for now. + // These are millimolar concentration of respective ions. + let method = 5; // todo? + + let tris = 0.; // todo: Do we want this? + + if (5..=7).contains(&method) && seq.is_empty() { + // return Err("sequence is missing (is needed to calculate GC content or sequence length).".into()); + return None; + } + + let mut corr = 0.0; + if method == 0 { + return Some(corr); + } + + // It appears that this section modifies the monovalent concentration with divalent values. + let mut mon = ion.monovalent + tris / 2.0; + let mon_molar = mon * 1e-3; + let mg_molar = ion.divalent * 1e-3; + + if (ion.monovalent > 0.0 || ion.divalent > 0.0 || tris > 0.0 || ion.dntp > 0.0) + && method != 7 + && ion.dntp < ion.divalent + { + mon += 120.0 * (ion.divalent - ion.dntp).sqrt(); + } + + if (1..=6).contains(&method) && mon_molar == 0.0 { + // return Err("Total ion concentration of zero is not allowed in this method.".into()); + return None; + } + + match method { + 1 => corr = 16.6 * mon_molar.log10(), + 2 => corr = 16.6 * (mon_molar / (1.0 + 0.7 * mon_molar)).log10(), + 3 => corr = 12.5 * mon_molar.log10(), + 4 => corr = 11.7 * mon_molar.log10(), + 5 => { + corr = 0.368 * (seq.len() as f32 - 1.0) * mon_molar.ln(); + } + 6 => { + let gc_fraction = calc_gc(seq); + corr = ((4.29 * gc_fraction - 3.95) * 1e-5 * mon_molar.ln()) + + 9.40e-6 * mon_molar.ln().powi(2); + } + 7 => { + let (mut a, b, c, mut d, e, f, mut g) = (3.92, -0.911, 6.26, 1.42, -48.2, 52.5, 8.31); + let mut mg_free = mg_molar; + if ion.dntp > 0.0 { + let dntps_molar = ion.dntp * 1e-3; + let ka = 3e4; + // Free Mg2+ calculation + mg_free = (-(ka * dntps_molar - ka * mg_free + 1.0) + + ((ka * dntps_molar - ka * mg_free + 1.0).powi(2) + 4.0 * ka * mg_free) + .sqrt()) + / (2.0 * ka); + } + + if mon > 0.0 { + let r = (mg_free).sqrt() / mon_molar; + if r < 0.22 { + let gc_fraction = calc_gc(seq); + corr = (4.29 * gc_fraction - 3.95) * 1e-5 * mon_molar.ln() + + 9.40e-6 * mon_molar.ln().powi(2); + return Some(corr); + } else if r < 6.0 { + a = 3.92 * (0.843 - 0.352 * mon_molar.sqrt() * mon_molar.ln()); + d = 1.42 + * (1.279 - 4.03e-3 * mon_molar.ln() - 8.03e-3 * mon_molar.ln().powi(2)); + g = 8.31 * (0.486 - 0.258 * mon_molar.ln() + 5.25e-3 * mon_molar.ln().powi(3)); + } + + let gc_fraction = calc_gc(seq); + corr = (a + + b * mg_free.ln() + + gc_fraction * (c + d * mg_free.ln()) + + (1.0 / (2.0 * (seq.len() as f32 - 1.0))) + * (e + f * mg_free.ln() + g * mg_free.ln().powi(2))) + * 1e-5; + } + } + _ => return None, + } + + Some(corr) +} + +pub fn calc_tm(seq: &[Nucleotide], ion_concentrations: &IonConcentrations) -> Option { + if seq.len() < MIN_PRIMER_LEN { + return None; + } + + // Inititial values. (S&H, Table 1) + let mut dH = 0.2; + let mut dS = -5.7; + + // If no GC content, apply additional values. (Table 1) + if calc_gc(seq) < 0.001 { + dH += 2.2; + dS += 6.9; + } + + // Add to dH and dS based on the terminal pair. + { + let term_pair = vec![seq[0], seq[seq.len() - 1]]; + let mut at_term_count = 0; + // Constants for the CG term are 0, so we don't need it. + for nt in term_pair { + if nt == A || nt == T { + at_term_count += 1; + } + } + dH += 2.2 * at_term_count as f32; + dS += 6.9 * at_term_count as f32; + } + + for (i, nt) in seq.iter().enumerate() { + if i + 1 >= seq.len() { + break; + } + + let neighbors = (*nt, seq[i + 1]); + + let (dH_nn, dS_nn) = dH_dS_neighbors(neighbors); + dH += dH_nn; + dS += dS_nn; + } + + let C_T = ion_concentrations.primer * 1.0e-9; + + println!("\n\ndH: {dH} dS: {dS}"); + + if let Some(sc) = salt_correction(seq, ion_concentrations) { + // Hard-coded for salt-correction method 5. + dS += sc; + // result += sc; + + // for saltcorr 6/7: + // result = 1. / (1. / (result + 273.15) + sc) - 273.15 + } else { + eprintln!("Error calculating salt correction."); + } + + // SantaLucia and Hicks, Equation 3. Note the C_T / 2 vice / 4, due to double-stranded concentration. + let result = (1_000. * dH) / (dS + R * (C_T / 2.).ln()) - 273.15; + + // melting_temp = (1000 * delta_h) / (delta_s + (R * (math.log(k)))) - 273.15 + // if saltcorr in (1, 2, 3, 4): + // melting_temp += corr + // if saltcorr in (6, 7): + // # Tm = 1/(1/Tm + corr) + // melting_temp = 1 / (1 / (melting_temp + 273.15) + corr) - 273.15 + + Some(result) +} diff --git a/src/sequence.rs b/src/sequence.rs index 9d9fcd8..b19a788 100644 --- a/src/sequence.rs +++ b/src/sequence.rs @@ -73,6 +73,30 @@ impl Nucleotide { C => 289.18, } } + + /// Optical density of a 1mL solution, in a cuvette with 1cm pathlength. + /// Result is in nm. + /// http://biotools.nubic.northwestern.edu/OligoCalc.html + pub fn a_max(&self) -> f32 { + match self { + A => 259., + T => 267., + G => 253., + C => 271., + } + } + + /// Optical density of a 1mL solution, in a cuvette with 1cm pathlength. + /// Result is in 1/(Moles x cm) + /// http://biotools.nubic.northwestern.edu/OligoCalc.html + pub fn molar_density(&self) -> f32 { + match self { + A => 15_200., + T => 8_400., + G => 12_010., + C => 7_050., + } + } } /// Of the 6 possible reading frames.