// Unit test of annotations handler class private static void TestSpectrumPeakAnnotations() { var noNote = SpectrumPeakAnnotation.Create(new CustomIon(null, Adduct.FromChargeNoMass(-2), 100, 101, "noNote"), null); var noName = SpectrumPeakAnnotation.Create(new CustomIon(null, Adduct.FromChargeNoMass(-2), 100, 101, null), "noted"); var fullIon = new CustomIon("C12H5O3", Adduct.FromStringAssumeChargeOnly("M-H2O+"), null, null, "full"); var full = SpectrumPeakAnnotation.Create(fullIon, "noted"); var fullToo = SpectrumPeakAnnotation.Create(fullIon, "noted"); var nameOnlyTab = SpectrumPeakAnnotation.Create(new CustomIon(null, Adduct.FromChargeNoMass(-2), 100, 101, "test\ttabs"), "noted"); // Check tab escape var fullIonTabs = new CustomIon("C12H5", Adduct.FromChargeNoMass(-2), null, null, "full\ttabs"); var tabbedFull = SpectrumPeakAnnotation.Create(fullIonTabs, "noted\ttabs"); // Check tab escape Assume.AreEqual(full, fullToo); Assume.AreNotEqual(full, tabbedFull); var tests = new List <List <SpectrumPeakAnnotation> > { new List <SpectrumPeakAnnotation> { noNote, noName, full }, new List <SpectrumPeakAnnotation> { fullToo, nameOnlyTab, tabbedFull } }; var cached = SpectrumPeakAnnotation.ToCacheFormat(tests); var roundtrip = SpectrumPeakAnnotation.FromCacheFormat(cached); int i = 0; foreach (var annotsPerPeak in tests) { Assume.IsTrue(CollectionUtil.EqualsDeep(annotsPerPeak, roundtrip[i++])); } }
public void DoFullScanSettingsTest(RefinementSettings.ConvertToSmallMoleculesMode asSmallMolecules, out List <SrmDocument> docCheckPoints) { docCheckPoints = new List <SrmDocument>(); var doc0 = ResultsUtil.DeserializeDocument("MultiLabel.sky", GetType()); var refine = new RefinementSettings(); var docSM = refine.ConvertToSmallMolecules(doc0, ".", asSmallMolecules); docCheckPoints.Add(docSM); Assert.IsFalse(docSM.MoleculeTransitionGroups.Any(nodeGroup => nodeGroup.IsotopeDist != null)); AssertEx.Serializable(docSM, AssertEx.Cloned); double c13Delta = BioMassCalc.MONOISOTOPIC.GetMass(BioMassCalc.C13) - BioMassCalc.MONOISOTOPIC.GetMass(BioMassCalc.C); double n15Delta = BioMassCalc.MONOISOTOPIC.GetMass(BioMassCalc.N15) - BioMassCalc.MONOISOTOPIC.GetMass(BioMassCalc.N); // Verify isotope distributions calculated when MS1 filtering enabled var enrichments = IsotopeEnrichmentsList.DEFAULT; var docIsotopes = docSM.ChangeSettings(docSM.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorIsotopes(FullScanPrecursorIsotopes.Count, 3, enrichments))); docCheckPoints.Add(docIsotopes); Assert.AreEqual(FullScanMassAnalyzerType.tof, docIsotopes.Settings.TransitionSettings.FullScan.PrecursorMassAnalyzer); Assert.IsFalse(docIsotopes.MoleculeTransitionGroups.Any(nodeGroup => nodeGroup.IsotopeDist == null)); foreach (var nodeGroup in docIsotopes.MoleculeTransitionGroups) { Assert.AreEqual(3, nodeGroup.Children.Count); var isotopePeaks = nodeGroup.IsotopeDist; Assert.IsNotNull(isotopePeaks); Assert.IsTrue(nodeGroup.HasIsotopeDist); // The peaks should always includ at least M-1 Assume.IsTrue(isotopePeaks.MassIndexToPeakIndex(0) > 0); // Within 2.5% of 100% of the entire isotope distribution Assert.AreEqual(1.0, isotopePeaks.ExpectedProportions.Sum(), 0.025); // Precursor mass and m/z values are expected to match exactly (well, within XML roundtrip accuracy anyway) Assert.AreEqual(nodeGroup.PrecursorMz, nodeGroup.IsotopeDist.GetMZI(0), SequenceMassCalc.MassTolerance); Assert.AreEqual(nodeGroup.PrecursorMz, nodeGroup.TransitionGroup.IsCustomIon ? BioMassCalc.CalculateIonMz(nodeGroup.IsotopeDist.GetMassI(0), nodeGroup.TransitionGroup.PrecursorAdduct.Unlabeled) : SequenceMassCalc.GetMZ(nodeGroup.IsotopeDist.GetMassI(0), nodeGroup.TransitionGroup.PrecursorAdduct), SequenceMassCalc.MassTolerance); // Check isotope distribution masses for (int i = 1; i < isotopePeaks.CountPeaks; i++) { int massIndex = isotopePeaks.PeakIndexToMassIndex(i); Assert.IsTrue(isotopePeaks.GetMZI(massIndex - 1) < isotopePeaks.GetMZI(massIndex)); double massDelta = GetMassDelta(isotopePeaks, massIndex); if (nodeGroup.TransitionGroup.LabelType.IsLight) { // All positive should be close to 13C - C, and 0 should be the same as the next delta double expectedDelta = (massIndex > 0 ? c13Delta : GetMassDelta(isotopePeaks, massIndex + 1)); Assert.AreEqual(expectedDelta, massDelta, 0.001); } else if (nodeGroup.TransitionGroup.LabelType.Name.Contains("15N")) { // All positive should be close to 13C, and all negative 15N double expectedDelta = (massIndex > 0 ? c13Delta : n15Delta); Assert.AreEqual(expectedDelta, massDelta, 0.0015); } else if (massIndex == 0) { double expectedDelta = (isotopePeaks.GetProportionI(massIndex - 1) == 0 ? GetMassDelta(isotopePeaks, massIndex + 1) : 1.0017); Assert.AreEqual(expectedDelta, massDelta, 0.001); } else { Assert.AreEqual(c13Delta, massDelta, 0.001); } } } AssertEx.Serializable(docIsotopes, AssertEx.Cloned); // Narrow the resolution, and verify that predicted proportion of the isotope // distribution captured is reduced for all precursors var docIsotopesFt = docIsotopes.ChangeSettings(docIsotopes.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorResolution(FullScanMassAnalyzerType.ft_icr, 500 * 1000, 400))); docCheckPoints.Add(docIsotopesFt); var tranGroupsOld = docIsotopes.MoleculeTransitionGroups.ToArray(); var tranGroupsNew = docIsotopesFt.MoleculeTransitionGroups.ToArray(); Assume.AreEqual(tranGroupsOld.Length, tranGroupsNew.Length); for (int i = 0; i < tranGroupsOld.Length; i++) { Assert.AreNotSame(tranGroupsOld[i], tranGroupsNew[i]); Assert.AreNotSame(tranGroupsOld[i].IsotopeDist, tranGroupsNew[i].IsotopeDist); Assert.IsTrue(tranGroupsOld[i].IsotopeDist.ExpectedProportions.Sum() > tranGroupsNew[i].IsotopeDist.ExpectedProportions.Sum()); } // Use Min % of base peak and verify variation in transitions used const float minPercent1 = 10; var docIsotopesP1 = docIsotopes.ChangeSettings(docIsotopes.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorIsotopes(FullScanPrecursorIsotopes.Percent, minPercent1, enrichments))); docCheckPoints.Add(docIsotopesP1); tranGroupsNew = docIsotopesP1.MoleculeTransitionGroups.ToArray(); int maxTran = 0; for (int i = 0; i < tranGroupsOld.Length; i++) { // Isotope distributions should not have changed var isotopePeaks = tranGroupsNew[i].IsotopeDist; Assert.AreSame(tranGroupsOld[i].IsotopeDist, isotopePeaks); // Expected transitions should be present maxTran = Math.Max(maxTran, tranGroupsNew[i].Children.Count); foreach (TransitionDocNode nodeTran in tranGroupsNew[i].Children) { int massIndex = nodeTran.Transition.MassIndex; Assume.IsTrue(minPercent1 <= isotopePeaks.GetProportionI(massIndex) * 100.0 / isotopePeaks.BaseMassPercent); } } Assume.AreEqual(5, maxTran); AssertEx.Serializable(docIsotopesP1, AssertEx.Cloned); // Express any failure in terms of XML diffs // Use 10%, and check that 15N modifications all have M-1 const float minPercent2 = 5; var docIsotopesP2 = docIsotopesP1.ChangeSettings(docIsotopesP1.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorIsotopes(FullScanPrecursorIsotopes.Percent, minPercent2, enrichments))); docCheckPoints.Add(docIsotopesP2); foreach (var nodeGroup in docIsotopesP2.MoleculeTransitionGroups) { var firstChild = (TransitionDocNode)nodeGroup.Children[0]; if (nodeGroup.TransitionGroup.LabelType.Name.EndsWith("15N")) { Assume.AreEqual(-1, firstChild.Transition.MassIndex); } else { Assume.AreNotEqual(-1, firstChild.Transition.MassIndex); } } AssertEx.Serializable(docIsotopesP2, AssertEx.Cloned); // Use lower enrichment of 13C, and verify that this add M-1 for 13C labeled precursors var enrichmentsLow13C = enrichments.ChangeEnrichment(new IsotopeEnrichmentItem(BioMassCalc.C13, 0.9)); var docIsotopesLow13C = docIsotopesP1.ChangeSettings(docIsotopesP1.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorIsotopes(FullScanPrecursorIsotopes.Percent, minPercent2, enrichmentsLow13C))); tranGroupsNew = docIsotopesLow13C.MoleculeTransitionGroups.ToArray(); for (int i = 0; i < tranGroupsOld.Length; i++) { var nodeGroup = tranGroupsNew[i]; if (!Equals(nodeGroup.TransitionGroup.LabelType.Name, "heavy")) { Assert.AreSame(tranGroupsOld[i].IsotopeDist, nodeGroup.IsotopeDist); } else { var firstChild = (TransitionDocNode)nodeGroup.Children[0]; Assert.IsTrue(firstChild.Transition.MassIndex < 0); } } AssertEx.Serializable(docIsotopesLow13C, AssertEx.Cloned); // Express any failure as XML diffs // Use 0%, and check that everything has M-1 and lower var enrichmentsLow = enrichmentsLow13C.ChangeEnrichment(new IsotopeEnrichmentItem(BioMassCalc.N15, 0.97)); var docIsotopesLowP0 = docIsotopesP1.ChangeSettings(docIsotopesP1.Settings.ChangeTransitionFullScan(fs => fs.ChangePrecursorIsotopes(FullScanPrecursorIsotopes.Percent, 0, enrichmentsLow))); docCheckPoints.Add(docIsotopesLowP0); foreach (var nodeGroup in docIsotopesLowP0.MoleculeTransitionGroups) { Assume.AreEqual(nodeGroup.IsotopeDist.CountPeaks, nodeGroup.Children.Count); var firstChild = (TransitionDocNode)nodeGroup.Children[0]; if (nodeGroup.TransitionGroup.LabelType.IsLight) { Assert.AreEqual(-1, firstChild.Transition.MassIndex); } else { Assert.IsTrue(-1 > firstChild.Transition.MassIndex); } } AssertEx.Serializable(docIsotopesLowP0, AssertEx.Cloned); // Test a document with variable and heavy modifications, which caused problems for // the original implementation var docVariable = ResultsUtil.DeserializeDocument("HeavyVariable.sky", GetType()); Assert.IsFalse(docVariable.MoleculeTransitionGroups.Any(nodeGroup => nodeGroup.IsotopeDist == null)); foreach (var nodeGroup in docVariable.MoleculeTransitionGroups) { var isotopePeaks = nodeGroup.IsotopeDist; Assert.IsNotNull(isotopePeaks); // The peaks should always includ at least M-1 Assert.IsTrue(isotopePeaks.MassIndexToPeakIndex(0) > 0); // Precursor mass and m/z values are expected to match exactly (well, within XML roundtrip tolerance anyway) var mzI = nodeGroup.IsotopeDist.GetMZI(0); Assert.AreEqual(nodeGroup.PrecursorMz, mzI, SequenceMassCalc.MassTolerance); // Check isotope distribution masses for (int i = 1; i < isotopePeaks.CountPeaks; i++) { int massIndex = isotopePeaks.PeakIndexToMassIndex(i); Assert.IsTrue(isotopePeaks.GetMZI(massIndex - 1) < isotopePeaks.GetMZI(massIndex)); double massDelta = GetMassDelta(isotopePeaks, massIndex); bool containsSulfur = nodeGroup.TransitionGroup.Peptide.IsCustomMolecule ? (nodeGroup.CustomMolecule.Formula.IndexOfAny("S".ToCharArray()) != -1) : (nodeGroup.TransitionGroup.Peptide.Sequence.IndexOfAny("CM".ToCharArray()) != -1); if (massIndex == 0) { double expectedDelta = (isotopePeaks.GetProportionI(massIndex - 1) == 0 ? GetMassDelta(isotopePeaks, massIndex + 1) : 1.0017); Assert.AreEqual(expectedDelta, massDelta, 0.001); } else if (!containsSulfur || massIndex == 1) { Assert.AreEqual(c13Delta, massDelta, 0.001); } else { Assert.AreEqual(1.00075, massDelta, 0.001); } } } docCheckPoints.Add(docVariable); }