public static void Figure_EffectOfTemperature_Simple() { var ionTable = new IonTable(); double[] temps = ScottPlot.DataGen.Consecutive(50); double[] ljps = new double[temps.Length]; for (int i = 0; i < temps.Length; i++) { Console.WriteLine($"Calculating for {temps[i]}C..."); var ionSet = new List <Ion> { new Ion("Zn", 9, 0.0284), new Ion("K", 0, 3), new Ion("Cl", 18, 3.0568) }; ljps[i] = Calculate.Ljp(ionTable.Lookup(ionSet), temps[i]).mV; } var plt = new ScottPlot.Plot(800, 600); plt.PlotScatter(temps, ljps); plt.Title("JLJP Screenshot Ion Set"); plt.YLabel("LJP (mV)"); plt.XLabel("Temperature (C)"); string filePath = System.IO.Path.GetFullPath("Figure_EffectOfTemperatureSimple.png"); plt.SaveFig(filePath); Console.WriteLine($"Saved: {filePath}"); }
public IonLookup() { var mdTableBytes = Properties.Resources.IonTable; string mdTableString = System.Text.Encoding.Default.GetString(mdTableBytes); string[] mdTableLines = mdTableString.Split("\n"); Table = new IonTable(mdTableLines); }
public void Test_KnownIonSets_LjpWithinExpectedRange() { var ionTable = new IonTable(); var knownSets = new KnownIonSets(ionTable); foreach (var ionSet in knownSets.ionSets) { Console.WriteLine($"Testing known ion set: {ionSet.name}"); var ljp = Calculate.Ljp(ionSet.ions, ionSet.temperatureC); Assert.AreEqual(ionSet.expectedLjp_mV, ljp.mV, ionSet.expectedAccuracy_mV); } }
public void Test_LjpCalculationMatches_ExampleFromSourceCode() { /* From JLJP: https://github.com/swharden/JLJP/blob/2.0.0/src/Example.java */ Ion Zn = new Ion("Zn", MolsPerCubicMeter(9), MolsPerCubicMeter(0.0284)); Ion K = new Ion("K", MolsPerCubicMeter(0), MolsPerCubicMeter(3)); Ion Cl = new Ion("Cl", MolsPerCubicMeter(18), MolsPerCubicMeter(3.0568)); var ionSet = new List <Ion> { Zn, K, Cl }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-20.79558643, ljp.mV, 1e-6); }
public void Test_LjpCalculationMatches_Harper003() { // ion set from Harper (1985) Table I // https://pubs.acs.org/doi/pdf/10.1021/j100255a022 var ionSet = new List <Ion> { new Ion("Ca", .29, .00545), new Ion("Cl", .29 * 2, .00545 * 2) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-35, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_Harper004() { // ion set from Harper (1985) Table I // https://pubs.acs.org/doi/pdf/10.1021/j100255a022 var ionSet = new List <Ion> { new Ion("Zn", .4, .0186), new Ion("SO4", .4, .0186), }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-8.1, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_ExampleFromScreenshot() { /* Test came from screenshot on original JLJP website */ var ionSet = new List <Ion> { new Ion("Zn", 9, 0.0284), new Ion("K", 0, 3), new Ion("Cl", 18, 3.0568) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-20.79558643, ljp.mV, 1e-6); }
public void Test_LjpCalculationMatches_NgAndBarry001() { /* LJP for this test came from Ng and Barry (1994) Table 2 */ // 50 mM NaCl : 50 mM KCl var ionSet = new List <Ion> { new Ion("Na", 50, 0), new Ion("K", 0, 50), new Ion("Cl", 50, 50) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-4.3, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_NgAndBarry005() { /* LJP for this test came from Ng and Barry (1994) Table 2 */ // 100 CaCl2 : 100 MgCl2 // Ca (100), Cl (200) : Mg (100) Cl (200) var ionSet = new List <Ion> { new Ion("Ca", 100, 0), new Ion("Mg", 0, 100), new Ion("Cl", 200, 200) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(+0.6, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_JPWin002() { // ion set shown in JPCalcWin manual (page 10) // https://tinyurl.com/wk7otn7 var ionSet = new List <Ion> { new Ion("Cs", 145, 0), new Ion("Na", 0, 145), new Ion("F", 125, 0), new Ion("Cl", 20, 145) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(+8.71, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_NgAndBarry007() { /* LJP for this test came from Ng and Barry (1994) Table 2 */ // 50 CaCl2 + 50 MgCl2 : 100 LiCl // Ca (50), Cl (200), Mg (50) : Li (100), Cl (100) var ionSet = new List <Ion> { new Ion("Ca", 50, 0), new Ion("Cl", 200, 100), new Ion("Mg", 50, 0), new Ion("Li", 0, 100) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(-8.2, ljp.mV, 0.5); }
public void Test_LjpCalculationMatches_NgAndBarry006() { /* LJP for this test came from Ng and Barry (1994) Table 2 */ // 100 KCl + 2 CaCl2 : 100 LiCl + 2 CaCl2 // K (100), Cl (104), Ca (2) : Li (100), Cl (104), Ca (2) var ionSet = new List <Ion> { new Ion("Ca", 2, 2), new Ion("K", 100, 0), new Ion("Li", 0, 100), new Ion("Cl", 104, 104) }; var ionTable = new IonTable(); ionSet = ionTable.Lookup(ionSet); var ljp = Calculate.Ljp(ionSet); Assert.AreEqual(+6.4, ljp.mV, 0.5); }
private void LoadIonTable() { IonTableListbox.Items.Clear(); try { ionTable = new IonTable(); foreach (var ion in ionTable.ions) { IonTableListbox.Items.Add(ion.nameWithCharge); } } catch { IonTableListbox.Items.Add("ERROR"); IonTableListbox.IsEnabled = false; MessageBox.Show( "The ion table failed to load. Calculations will work, but ion values cannot be looked up and example ion sets will not be available.", "Ion Table Error", MessageBoxButton.OK, MessageBoxImage.Warning); } }
public IonMasses(TypedMass precursorMass, IonTable <TypedMass> fragmentMasses) { PrecursorMass = precursorMass; FragmentMasses = fragmentMasses; }
public static void Figure_EffectOfTemperature_SeveralSets() { /* this study calculates one of several known ionSets at every temperature between 0C and 50C */ var ionTable = new IonTable(); double[] temps = ScottPlot.DataGen.Consecutive(50); double[] jljpResults = new double[temps.Length]; double[] ngAndBarryResults = new double[temps.Length]; double[] HarperResults = new double[temps.Length]; double[] jpWinResults = new double[temps.Length]; List <Ion> ionSet; for (int i = 0; i < temps.Length; i++) { Console.WriteLine($"Calculating for {temps[i]}C..."); // see LjpCalculationTests.cs for ion set citations // create a new ion set for each iteration to prevent modifications due to solving from carrying to the next solve ionSet = new List <Ion> { new Ion("Zn", 9, 0.0284), new Ion("K", 0, 3), new Ion("Cl", 18, 3.0568) }; jljpResults[i] = Calculate.Ljp(ionTable.Lookup(ionSet), temps[i]).mV; ionSet = new List <Ion> { new Ion("Ca", 2, 2), new Ion("K", 100, 0), new Ion("Li", 0, 100), new Ion("Cl", 104, 104) }; ngAndBarryResults[i] = Calculate.Ljp(ionTable.Lookup(ionSet), temps[i]).mV; ionSet = new List <Ion> { new Ion("Ca", .29, .00545), new Ion("Cl", .29 * 2, .00545 * 2) }; HarperResults[i] = Calculate.Ljp(ionTable.Lookup(ionSet), temps[i]).mV; ionSet = new List <Ion> { new Ion("Na", 10, 145), new Ion("Cl", 10, 145), new Ion("Cs", 135, 0), new Ion("F", 135, 0) }; jpWinResults[i] = Calculate.Ljp(ionTable.Lookup(ionSet), temps[i]).mV; } var mplt = new ScottPlot.MultiPlot(800, 600, 2, 2); mplt.subplots[0].PlotScatter(temps, jljpResults); mplt.subplots[0].Title("JLJP screenshot"); mplt.subplots[1].PlotScatter(temps, ngAndBarryResults); mplt.subplots[1].Title("Ng and Barry (1994)"); mplt.subplots[2].PlotScatter(temps, HarperResults); mplt.subplots[2].Title("Harper (1985)"); mplt.subplots[3].PlotScatter(temps, jpWinResults); mplt.subplots[3].Title("JPWin screenshot"); for (int i = 0; i < 4; i++) { mplt.subplots[i].YLabel("LJP (mV)"); mplt.subplots[i].XLabel("Temperature (C)"); } string filePath = System.IO.Path.GetFullPath("Figure_EffectOfTemperature.png"); mplt.SaveFig(filePath); Console.WriteLine($"Saved: {filePath}"); }
public static Adduct CalcProductCharge(TypedMass productPrecursorMass, Adduct precursorCharge, IList <IonType> acceptedIonTypes, IonTable <TypedMass> productMasses, IList <IList <ExplicitLoss> > potentialLosses, double productMz, double tolerance, MassType massType, MassShiftType massShiftType, out IonType?ionType, out int?ordinal, out TransitionLosses losses, out int massShift) { // Get length of fragment ion mass array int len = productMasses.GetLength(1); // Check all possible ion types and offsets double? minDelta = null; var bestCharge = Adduct.EMPTY; IonType? bestIonType = null; int? bestOrdinal = null; TransitionLosses bestLosses = null; int bestMassShift = 0; // Check to see if it is the precursor foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses)) { var productMass = productPrecursorMass - (lossesTrial != null ? lossesTrial.Mass : 0); int potentialMassShift; int nearestCharge; var charge = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge, massShiftType, out potentialMassShift, out nearestCharge); if (Equals(charge, precursorCharge)) { double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift; double delta = Math.Abs(productMz - potentialMz); if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0) { bestCharge = charge; bestIonType = IonType.precursor; bestOrdinal = len + 1; bestLosses = lossesTrial; bestMassShift = potentialMassShift; minDelta = delta; } } } var categoryLast = -1; foreach (var typeAccepted in GetIonTypes(acceptedIonTypes)) { var type = typeAccepted.IonType; var category = typeAccepted.IonCategory; // Types have priorities. If changing type category, and there is already a // suitable answer stop looking. if (category != categoryLast && minDelta.HasValue && MatchMz(minDelta.Value, tolerance)) { break; } categoryLast = category; for (int offset = 0; offset < len; offset++) { foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(type, offset, massType, potentialLosses)) { // Look for the closest match. var productMass = productMasses[type, offset]; if (lossesTrial != null) { productMass -= lossesTrial.Mass; } int potentialMassShift; int nearestCharge; var chargeFound = CalcProductCharge(productMass, productMz, tolerance, false, precursorCharge, massShiftType, out potentialMassShift, out nearestCharge); if (!chargeFound.IsEmpty) { var charge = chargeFound; double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift; double delta = Math.Abs(productMz - potentialMz); if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0) { bestCharge = charge; bestIonType = type; // The peptide length is 1 longer than the mass array bestOrdinal = Transition.OffsetToOrdinal(type, offset, len + 1); bestLosses = lossesTrial; bestMassShift = potentialMassShift; minDelta = delta; } } } } } ionType = bestIonType; ordinal = bestOrdinal; losses = bestLosses; massShift = bestMassShift; return(bestCharge); }
public static Adduct CalcProductCharge(TypedMass productPrecursorMass, int?productZ, Adduct precursorCharge, IList <IonType> acceptedIonTypes, IonTable <TypedMass> productMasses, IList <IList <ExplicitLoss> > potentialLosses, double productMz, double tolerance, MassType massType, MassShiftType massShiftType, out IonType?ionType, out int?ordinal, out TransitionLosses losses, out int massShift) { // Get length of fragment ion mass array int len = productMasses.GetLength(1); // Check all possible ion types and offsets double?minDelta = null; double?minFragmentMass = null, maxFragmentMass = null, maxLoss = null; if (massShiftType == MassShiftType.none) { if (!productZ.HasValue) { minFragmentMass = productMz - tolerance; } else { minFragmentMass = SequenceMassCalc.GetMH(productMz - tolerance, productZ.Value); maxFragmentMass = SequenceMassCalc.GetMH(productMz + tolerance, productZ.Value); } } var bestCharge = Adduct.EMPTY; IonType? bestIonType = null; int? bestOrdinal = null; TransitionLosses bestLosses = null; int bestMassShift = 0; // Check to see if it is the precursor foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(IonType.precursor, 0, massType, potentialLosses)) { var productMass = productPrecursorMass; if (lossesTrial != null) { productMass -= lossesTrial.Mass; maxLoss = Math.Max(maxLoss ?? 0, lossesTrial.Mass); } int potentialMassShift; int nearestCharge; var charge = CalcProductCharge(productMass, productZ, productMz, tolerance, false, precursorCharge, massShiftType, out potentialMassShift, out nearestCharge); if (Equals(charge, precursorCharge)) { double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift; double delta = Math.Abs(productMz - potentialMz); if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0) { bestCharge = charge; bestIonType = IonType.precursor; bestOrdinal = len + 1; bestLosses = lossesTrial; bestMassShift = potentialMassShift; minDelta = delta; } } } if (maxLoss.HasValue) { maxFragmentMass += maxLoss.Value; } var categoryLast = -1; foreach (var typeAccepted in GetIonTypes(acceptedIonTypes)) { var type = typeAccepted.IonType; var category = typeAccepted.IonCategory; // Types have priorities. If changing type category, and there is already a // suitable answer stop looking. if (category != categoryLast && minDelta.HasValue && MatchMz(minDelta.Value, tolerance)) { break; } categoryLast = category; // The peptide length is 1 longer than the mass array for (int ord = len; ord > 0; ord--) { int offset = Transition.OrdinalToOffset(type, ord, len + 1); var productMassBase = productMasses[type, offset]; // Until below the maximum fragment mass no possible matches if (maxFragmentMass.HasValue && productMassBase > maxFragmentMass.Value) { continue; } // Once below the minimum fragment mass no more possible matches, so stop if (minFragmentMass.HasValue && productMassBase < minFragmentMass.Value) { break; } foreach (var lossesTrial in TransitionGroup.CalcTransitionLosses(type, offset, massType, potentialLosses)) { // Look for the closest match. var productMass = productMassBase; if (lossesTrial != null) { productMass -= lossesTrial.Mass; } int potentialMassShift; int nearestCharge; var chargeFound = CalcProductCharge(productMass, productZ, productMz, tolerance, false, precursorCharge, massShiftType, out potentialMassShift, out nearestCharge); if (!chargeFound.IsEmpty) { var charge = chargeFound; double potentialMz = SequenceMassCalc.GetMZ(productMass, charge) + potentialMassShift; double delta = Math.Abs(productMz - potentialMz); if (CompareIonMatch(delta, lossesTrial, potentialMassShift, minDelta, bestLosses, bestMassShift) < 0) { bestCharge = charge; bestIonType = type; bestOrdinal = ord; bestLosses = lossesTrial; bestMassShift = potentialMassShift; minDelta = delta; } } } } } ionType = bestIonType; ordinal = bestOrdinal; losses = bestLosses; massShift = bestMassShift; return(bestCharge); }
public IonMasses ChangeFragmentMasses(IonTable <TypedMass> fragmentMasses) { return(ChangeProp(ImClone(this), im => im.FragmentMasses = fragmentMasses)); }