Exemplo n.º 1
0
        public static void TestPsmHeader()
        {
            CommonParameters            commonParameters = new CommonParameters();
            PeptideWithSetModifications pepWithSetMods   = new Protein(
                "MQQQQQQQ",
                "accession1",
                "org",
                new List <Tuple <string, string> > {
                new Tuple <string, string>("geneNameType", "geneName")
            },
                new Dictionary <int, List <Modification> > {
                { 2, new List <Modification> {
                      new Modification("mod", "mod")
                  } }
            },
                name: "name",
                fullName: "fullName",
                sequenceVariations: new List <SequenceVariation> {
                new SequenceVariation(2, "P", "Q", "changed this sequence")
            })
                                                           .Digest(commonParameters.DigestionParams, new List <Modification>(), new List <Modification>()).First();
            MsDataFile myMsDataFile      = new TestDataFile(pepWithSetMods, "quadratic");
            MsDataScan scann             = myMsDataFile.GetOneBasedScan(2);
            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(scann, 4, 1, null, new CommonParameters());

            var theoreticalIons = new List <Product>();

            pepWithSetMods.Fragment(DissociationType.HCD, FragmentationTerminus.Both, theoreticalIons);
            var matchedIons          = MetaMorpheusEngine.MatchFragmentIons(scan, theoreticalIons, new CommonParameters());
            PeptideSpectralMatch psm = new PeptideSpectralMatch(pepWithSetMods, 1, 2, 3, scan, commonParameters, matchedIons);

            psm.ResolveAllAmbiguities();

            var t            = psm.ToString();
            var tabsepheader = PeptideSpectralMatch.GetTabSeparatedHeader();

            Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t'));

            Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t'));

            Tolerance fragmentTolerance = new PpmTolerance(10);

            new LocalizationEngine(new List <PeptideSpectralMatch> {
                psm
            }, myMsDataFile, new CommonParameters(productMassTolerance: fragmentTolerance), null, new List <string>()).Run();

            Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t'));

            psm.SetFdrValues(6, 6, 6, 6, 6, 0, 0, 0);

            Assert.AreEqual(psm.ToString().Count(f => f == '\t'), PeptideSpectralMatch.GetTabSeparatedHeader().Count(f => f == '\t'));
        }
Exemplo n.º 2
0
        public static void TestMzIdentMlWriterWithUniprotPsiMod()
        {
            Protein protein = new Protein("PEPTIDE", "", databaseFilePath: "temp");

            ModificationMotif.TryGetMotif("T", out var motif);

            Modification fakeMod = new Modification(_originalId: "FAKE", _accession: "FAKE_MOD_ACCESSION", _modificationType: "fake",
                                                    _target: motif, _locationRestriction: "Anywhere.", _monoisotopicMass: 0,
                                                    _databaseReference: new Dictionary <string, IList <string> > {
                { "PSI-MOD", new List <string> {
                      "FAKE_MOD_ACCESSION"
                  } }
            });

            string resIdAccession = fakeMod.DatabaseReference["PSI-MOD"].First();
            var    peptide        = protein.Digest(new DigestionParams(), new List <Modification> {
                fakeMod
            }, new List <Modification>()).First();

            MsDataScan dfb = new MsDataScan(new MzSpectrum(new double[] { 1 }, new double[] { 1 }, false), 0, 1, true, Polarity.Positive, double.NaN, null,
                                            null, MZAnalyzerType.Orbitrap, double.NaN, null, null, "scan=1", double.NaN, null, null, double.NaN, null, DissociationType.AnyActivationType, 0, null);
            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(dfb, 2, 0, "File", new CommonParameters());

            var psm = new PeptideSpectralMatch(peptide, 0, 1, 0, scan, new DigestionParams(), new List <MatchedFragmentIon>());

            psm.ResolveAllAmbiguities();
            psm.SetFdrValues(0, 0, 0, 0, 0, 0, 0, 0);

            string path = Path.Combine(TestContext.CurrentContext.TestDirectory, "ResIdOutput.mzID");

            MzIdentMLWriter.WriteMzIdentMl(new List <PeptideSpectralMatch> {
                psm
            }, new List <ProteinGroup>(), new List <Modification>(),
                                           new List <Modification>(), new List <SilacLabel>(), new List <Protease>(), 0, new PpmTolerance(20), new PpmTolerance(20),
                                           0, path);

            var  file  = File.ReadAllLines(path);
            bool found = false;

            foreach (var line in file)
            {
                if (line.Contains("FAKE on T") && line.Contains("PSI-MOD:" + resIdAccession))
                {
                    found = true;
                }
            }
            Assert.That(found);

            File.Delete(path);
        }
Exemplo n.º 3
0
        public static void RemoveAmbiguousPeptides()
        {
            var              variableModifications = new List <Modification>();
            var              fixedModifications    = new List <Modification>();
            var              origDataFile          = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\TaGe_SA_HeLa_04_subset_longestSeq.mzML");
            MyFileManager    myFileManager         = new MyFileManager(true);
            CommonParameters CommonParameters      = new CommonParameters(digestionParams: new DigestionParams());
            var              myMsDataFile          = myFileManager.LoadFile(origDataFile, CommonParameters);
            var              searchModes           = new SinglePpmAroundZeroSearchMode(5);
            List <Protein>   proteinList           = ProteinDbLoader.LoadProteinFasta(Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\hela_snip_for_unitTest.fasta"), true, DecoyType.Reverse, false, ProteinDbLoader.UniprotAccessionRegex, ProteinDbLoader.UniprotFullNameRegex, ProteinDbLoader.UniprotFullNameRegex, ProteinDbLoader.UniprotGeneNameRegex,
                                                                                      ProteinDbLoader.UniprotOrganismRegex, out var dbErrors, -1);
            var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, @"TestData\TaGe_SA_HeLa_04_subset_longestSeq.mzML", CommonParameters).OrderBy(b => b.PrecursorMass).ToArray();

            PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
            new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null, proteinList, searchModes, CommonParameters, new List <string>()).Run();

            var nonNullPsms = allPsmsArray.Where(p => p != null).ToList();

            nonNullPsms.OrderByDescending(p => p.Score);
            var maxScore = nonNullPsms.Select(n => n.Score).Max();
            PeptideSpectralMatch maxScorePsm = nonNullPsms.Where(n => n.Score == maxScore).First();

            Protein newProteinToRemove = new Protein("RREMVE", "BUBBA", isDecoy: false);
            PeptideWithSetModifications pwsmToRemove = new PeptideWithSetModifications(newProteinToRemove, new DigestionParams(), 1, 6, CleavageSpecificity.Full, "peptideDescription", 2, new Dictionary <int, Modification>(), 1, "RREMVE");

            maxScorePsm.AddOrReplace(pwsmToRemove, maxScore, 1, true, maxScorePsm.MatchedFragmentIons, maxScore);
            maxScorePsm.ResolveAllAmbiguities();

            List <PeptideSpectralMatch> psmBloated = new List <PeptideSpectralMatch>();

            psmBloated.AddRange(nonNullPsms);
            psmBloated.AddRange(nonNullPsms.GetRange(0, nonNullPsms.Count - 2));
            foreach (PeptideSpectralMatch psm in nonNullPsms.GetRange(0, nonNullPsms.Count - 2))
            {
                Protein newDecoyProtein = new Protein(psm.BestMatchingPeptides.First().Peptide.BaseSequence + "K", "DECOY_" + psm.BestMatchingPeptides.First().Peptide.Protein.Accession, isDecoy: true);
                PeptideWithSetModifications pwsmDecoy = new PeptideWithSetModifications(newDecoyProtein, new DigestionParams(), 1, psm.BestMatchingPeptides.First().Peptide.BaseSequence.Length + 1, CleavageSpecificity.Full, "peptideDescription", 2, new Dictionary <int, Modification>(), 1, psm.BestMatchingPeptides.First().Peptide.BaseSequence + "K");
                PeptideSpectralMatch        decoyPsm  = new PeptideSpectralMatch(pwsmDecoy, 1, psm.Score, psm.ScanIndex, listOfSortedms2Scans[psm.ScanIndex], new DigestionParams(), psm.MatchedFragmentIons);
                decoyPsm.ResolveAllAmbiguities();
                psmBloated.Add(decoyPsm);
            }

            PeptideSpectralMatch oldBloatedMaxScorePsm = psmBloated.Where(n => n.Score == maxScore).First();
            int countOfBestPeptidesBloatedMax          = oldBloatedMaxScorePsm.BestMatchingPeptides.Count();

            FdrAnalysisResults fdrResultsClassicDelta = (FdrAnalysisResults)(new FdrAnalysisEngine(psmBloated.Where(p => p != null).ToList(), 1, CommonParameters, new List <string>()).Run());

            PeptideSpectralMatch newMaxScorePsm = psmBloated.Where(n => n.Score == maxScore).First();

            Assert.AreEqual(countOfBestPeptidesBloatedMax - 1, newMaxScorePsm.BestMatchingPeptides.Count());
        }
Exemplo n.º 4
0
        public static void TestMzIdentMlWriterWithUniprotResId()
        {
            Protein protein = new Protein("PEPTIDE", "", databaseFilePath: "temp");

            Modification uniProtMod = GlobalVariables.AllModsKnown.First(p =>
                                                                         p.IdWithMotif == "FMN phosphoryl threonine on T" &&
                                                                         p.ModificationType == "UniProt" &&
                                                                         p.Target.ToString() == "T" &&
                                                                         p.DatabaseReference.ContainsKey("RESID") &&
                                                                         p.LocationRestriction == "Anywhere.");

            string resIdAccession = uniProtMod.DatabaseReference["RESID"].First();
            var    peptide        = protein.Digest(new DigestionParams(), new List <Modification> {
                uniProtMod
            }, new List <Modification>()).First();

            MsDataScan dfb = new MsDataScan(new MzSpectrum(new double[] { 1 }, new double[] { 1 }, false), 0, 1, true, Polarity.Positive, double.NaN, null,
                                            null, MZAnalyzerType.Orbitrap, double.NaN, null, null, "scan=1", double.NaN, null, null, double.NaN, null, DissociationType.AnyActivationType, 0, null);
            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(dfb, 2, 0, "File", new CommonParameters());

            var psm = new PeptideSpectralMatch(peptide, 0, 1, 0, scan, new DigestionParams(), new List <MatchedFragmentIon>());

            psm.ResolveAllAmbiguities();
            psm.SetFdrValues(0, 0, 0, 0, 0, 0, 0, 0);

            string path = Path.Combine(TestContext.CurrentContext.TestDirectory, "ResIdOutput.mzID");

            MzIdentMLWriter.WriteMzIdentMl(new List <PeptideSpectralMatch> {
                psm
            }, new List <ProteinGroup>(), new List <Modification>(),
                                           new List <Modification>(), new List <SilacLabel>(), new List <Protease>(), 0, new PpmTolerance(20), new PpmTolerance(20),
                                           0, path);

            var  file  = File.ReadAllLines(path);
            bool found = false;

            foreach (var line in file)
            {
                if (line.Contains("FMN phosphoryl threonine on T") && line.Contains("RESID:" + resIdAccession))
                {
                    found = true;
                }
            }
            Assert.That(found);

            File.Delete(path);
        }
Exemplo n.º 5
0
        public static void TestLocalization()
        {
            Protein          parentProteinForMatch = new Protein("MEK", null);
            CommonParameters commonParameters      = new CommonParameters(digestionParams: new DigestionParams(minPeptideLength: 1));
            var fsp = new List <(string fileName, CommonParameters fileSpecificParameters)>();

            fsp.Add(("", commonParameters));
            ModificationMotif.TryGetMotif("E", out ModificationMotif motif);
            List <Modification> variableModifications = new List <Modification> {
                new Modification(_originalId: "21", _target: motif, _locationRestriction: "Anywhere.", _monoisotopicMass: 21.981943)
            };

            List <PeptideWithSetModifications> allPeptidesWithSetModifications = parentProteinForMatch.Digest(commonParameters.DigestionParams, new List <Modification>(), variableModifications).ToList();

            Assert.AreEqual(4, allPeptidesWithSetModifications.Count());
            PeptideWithSetModifications ps = allPeptidesWithSetModifications.First();

            PeptideWithSetModifications pepWithSetModsForSpectrum = allPeptidesWithSetModifications[1];
            MsDataFile myMsDataFile = new TestDataFile(new List <PeptideWithSetModifications> {
                pepWithSetModsForSpectrum
            });
            Tolerance fragmentTolerance = new AbsoluteTolerance(0.01);

            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(myMsDataFile.GetAllScansList().Last(), pepWithSetModsForSpectrum.MonoisotopicMass.ToMz(1), 1, null, new CommonParameters());

            var theoreticalProducts = new List <Product>();

            ps.Fragment(DissociationType.HCD, FragmentationTerminus.Both, theoreticalProducts);
            var matchedIons             = MetaMorpheusEngine.MatchFragmentIons(scan, theoreticalProducts, new CommonParameters());
            PeptideSpectralMatch newPsm = new PeptideSpectralMatch(ps, 0, 0, 2, scan, commonParameters, matchedIons);

            newPsm.ResolveAllAmbiguities();

            LocalizationEngine f = new LocalizationEngine(new List <PeptideSpectralMatch> {
                newPsm
            }, myMsDataFile, commonParameters, fsp, new List <string>());

            f.Run();

            // single peak matches
            Assert.AreEqual(1, newPsm.MatchedFragmentIons.Where(p => p.NeutralTheoreticalProduct.ProductType == ProductType.b).Count());//including b1 now
            Assert.AreEqual(1, newPsm.MatchedFragmentIons.Where(p => p.NeutralTheoreticalProduct.ProductType == ProductType.y).Count());

            // when localizing, three peaks match
            Assert.IsTrue(newPsm.LocalizedScores[1] > 4 && newPsm.LocalizedScores[1] < 5);//we have another matched ion
        }
        public static void TestModificationAnalysisWithNonLocalizedPtms()
        {
            IScan scan = new ThisTestScan();

            ModificationMotif.TryGetMotif("N", out ModificationMotif motif1);
            Modification mod1 = new Modification(_originalId: "mod1", _modificationType: "mt", _target: motif1, _locationRestriction: "Anywhere.", _monoisotopicMass: 10, _neutralLosses: new Dictionary <DissociationType, List <double> > {
                { MassSpectrometry.DissociationType.AnyActivationType, new List <double> {
                      10
                  } }
            });

            IDictionary <int, List <Modification> > oneBasedModifications = new Dictionary <int, List <Modification> >
            {
                { 2, new List <Modification> {
                      mod1
                  } },
                { 7, new List <Modification> {
                      mod1
                  } },
            };
            Protein protein1 = new Protein("MNLDLDNDL", "prot1", oneBasedModifications: oneBasedModifications);

            Dictionary <int, Modification> allModsOneIsNterminus1 = new Dictionary <int, Modification>
            {
                { 2, mod1 },
            };
            PeptideWithSetModifications pwsm1 = new PeptideWithSetModifications(protein1, new DigestionParams(), 2, 9, CleavageSpecificity.Unknown, null, 0, allModsOneIsNterminus1, 0);

            Dictionary <int, Modification> allModsOneIsNterminus3 = new Dictionary <int, Modification>
            {
                { 7, mod1 },
            };
            PeptideWithSetModifications pwsm2 = new PeptideWithSetModifications(protein1, new DigestionParams(), 2, 9, CleavageSpecificity.Unknown, null, 0, allModsOneIsNterminus3, 0);

            CommonParameters CommonParameters = new CommonParameters(digestionParams: new DigestionParams(maxMissedCleavages: 0, minPeptideLength: 1), scoreCutoff: 1);

            PeptideSpectralMatch myPsm = new PeptideSpectralMatch(pwsm1, 0, 10, 0, scan, new DigestionParams(), new List <MatchedFragmentIon>());

            myPsm.AddOrReplace(pwsm2, 10, 0, true, new List <MatchedFragmentIon>(), 0);

            myPsm.ResolveAllAmbiguities();

            MassDiffAcceptor searchMode  = new SinglePpmAroundZeroSearchMode(5);
            List <Protein>   proteinList = new List <Protein> {
                protein1
            };

            FdrAnalysisEngine fdrAnalysisEngine = new FdrAnalysisEngine(new List <PeptideSpectralMatch> {
                myPsm
            }, searchMode.NumNotches, CommonParameters, new List <string>());

            fdrAnalysisEngine.Run();
            ModificationAnalysisEngine modificationAnalysisEngine = new ModificationAnalysisEngine(new List <PeptideSpectralMatch> {
                myPsm
            }, new CommonParameters(), new List <string>());
            var res = (ModificationAnalysisResults)modificationAnalysisEngine.Run();

            Assert.AreEqual(1, res.CountOfEachModSeenOnProteins.Count());
            Assert.AreEqual(2, res.CountOfEachModSeenOnProteins[mod1.IdWithMotif]);
            Assert.AreEqual(0, res.CountOfModsSeenAndLocalized.Count());
            Assert.AreEqual(0, res.CountOfAmbiguousButLocalizedModsSeen.Count);
            Assert.AreEqual(1, res.CountOfUnlocalizedMods[mod1.IdWithMotif]); // Saw it, but not sure where!
            Assert.AreEqual(0, res.CountOfUnlocalizedFormulas.Count());
        }
        public static void ParsimonyDontTreatModifiedFormsAsUnique()
        {
            bool modPeptidesAreUnique = false;

            // set up mods
            var modDictionary = new Dictionary <int, List <Modification> >();

            ModificationMotif.TryGetMotif("M", out ModificationMotif motif1);
            var mod = new Modification(_originalId: "Oxidation of M", _modificationType: "Common Variable", _target: motif1, _locationRestriction: "Anywhere.", _monoisotopicMass: 15.99491461957);

            // modified version of protein
            var protein1 = new Protein("PEPTIDEM", "accession1");

            // unmodified version of protein
            var protein2 = new Protein("YYYKPEPTIDEM", "accession2");

            List <PeptideWithSetModifications> pwsmsFromProtein1 = protein1.Digest(new DigestionParams(protease: "trypsin", minPeptideLength: 1), new List <Modification> {
                mod
            }, new List <Modification>()).ToList();                                                                                                                                                                   //this is a fixed mod
            List <PeptideWithSetModifications> pwsmsFromProtein2 = protein2.Digest(new DigestionParams(protease: "trypsin", minPeptideLength: 1), new List <Modification>(), new List <Modification>()).ToList();

            // check to make sure mod is present
            PeptideWithSetModifications modifiedPeptide   = pwsmsFromProtein1[0];
            PeptideWithSetModifications unmodifiedPeptide = pwsmsFromProtein2[1];

            Assert.That(!modifiedPeptide.FullSequence.Equals(unmodifiedPeptide.FullSequence)); // sequences should not be equal (one has a mod)
            Assert.That(modifiedPeptide.BaseSequence.Equals(unmodifiedPeptide.BaseSequence));  // base sequences should be equal
            Assert.That(modifiedPeptide.NumMods == 1);                                         // methionine was oxidized on this protein
            Assert.That(unmodifiedPeptide.NumMods == 0);                                       // there was no modification on this protein

            // build PSMs for parsimony
            List <PeptideSpectralMatch> psmsForParsimony = new List <PeptideSpectralMatch>();

            MsDataScan fakeScan = new MsDataScan(new MzSpectrum(new double[] { 1 }, new double[] { 1 }, false),
                                                 0, 1, true, Polarity.Positive, double.NaN, null, null, MZAnalyzerType.Orbitrap, double.NaN, null,
                                                 null, "scan=1", double.NaN, null, null, double.NaN, null, DissociationType.AnyActivationType, 0, null);

            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(fakeScan, 2, 0, "File", new CommonParameters());

            PeptideSpectralMatch psm1 = new PeptideSpectralMatch(modifiedPeptide, 0, 10, 1, scan, new DigestionParams(), new List <MatchedFragmentIon>());

            psm1.SetFdrValues(0, 0, 0, 0, 0, 0, 0, 0);
            psm1.ResolveAllAmbiguities();

            PeptideSpectralMatch psm2 = new PeptideSpectralMatch(unmodifiedPeptide, 0, 10, 2, scan, new DigestionParams(), new List <MatchedFragmentIon>());

            psm2.SetFdrValues(0, 0, 0, 0, 0, 0, 0, 0);
            psm2.ResolveAllAmbiguities();

            psmsForParsimony.Add(psm1);
            psmsForParsimony.Add(psm2);

            // apply parsimony
            ProteinParsimonyEngine pae = new ProteinParsimonyEngine(psmsForParsimony, modPeptidesAreUnique, new CommonParameters(), new List <string>());

            // because the two chosen peptides are the same, we should end up with both protein accessions still in the list
            var proteinParsimonyResult = (ProteinParsimonyResults)pae.Run();

            // score protein groups and merge indistinguishable ones
            ProteinScoringAndFdrEngine proteinScoringEngine = new ProteinScoringAndFdrEngine(proteinParsimonyResult.ProteinGroups, psmsForParsimony, false, true, true, new CommonParameters(), new List <string>());
            var results = (ProteinScoringAndFdrResults)proteinScoringEngine.Run();

            int countOfProteinGroups = results.SortedAndScoredProteinGroups.Count;

            // because modified peptides were NOT considered as unique,
            // then there should be one ambiguous protein group after parsimony,
            // and two protein accessions for each peptide
            Assert.AreEqual(1, countOfProteinGroups);
            Assert.AreEqual(2, results.SortedAndScoredProteinGroups.First().Proteins.Count);
            Assert.IsNull(psm1.ProteinAccession);
            Assert.IsNull(psm2.ProteinAccession);
        }
Exemplo n.º 8
0
        public static void ResolveModificationsTest()
        {
            double mass = 12.0 + new PeptideWithSetModifications(new Protein("LNLDLDND", "prot1"), new DigestionParams(), 1, 8, CleavageSpecificity.Full, "", 0, new Dictionary <int, Modification>(), 0, null).MonoisotopicMass.ToMz(1);
            Ms2ScanWithSpecificMass scan = new Ms2ScanWithSpecificMass(new MsDataScan(new MzSpectrum(new double[, ] {
            }), 0, 0, true, Polarity.Positive,
                                                                                      0, new MzLibUtil.MzRange(0, 0), "", MZAnalyzerType.FTICR, 0, null, null, ""), mass, 1, "", new CommonParameters());

            ModificationMotif.TryGetMotif("N", out ModificationMotif motif1);

            Dictionary <DissociationType, List <double> > NeutralLosses = new Dictionary <DissociationType, List <double> >();

            NeutralLosses.Add(DissociationType.HCD, new List <double> {
                0
            });

            Modification modFormula_C1 = new Modification(_originalId: "modC", _accession: "", _modificationType: "mt", _featureType: "", _target: motif1, _locationRestriction: "Anywhere.", _chemicalFormula: new ChemicalFormula(ChemicalFormula.ParseFormula("C1")), null, null, null, null, _neutralLosses: NeutralLosses, null, null);
            Modification modFormula_H1 = new Modification(_originalId: "modH", _accession: "", _modificationType: "mt", _featureType: "", _target: motif1, _locationRestriction: "Anywhere.", _chemicalFormula: new ChemicalFormula(ChemicalFormula.ParseFormula("H1")), null, null, null, null, _neutralLosses: NeutralLosses, null, null);

            IDictionary <int, List <Modification> > oneBasedModifications = new Dictionary <int, List <Modification> >
            {
                { 2, new List <Modification> {
                      modFormula_C1, modFormula_H1
                  } },
            };
            Protein protein1 = new Protein("MNLDLDNDL", "prot1", oneBasedModifications: oneBasedModifications);

            Dictionary <int, Modification> allModsOneIsNterminus1 = new Dictionary <int, Modification>
            {
                { 2, modFormula_C1 },
            };

            PeptideWithSetModifications pwsm1 = new PeptideWithSetModifications(protein1, new DigestionParams(), 2, 9, CleavageSpecificity.Unknown, null, 0, allModsOneIsNterminus1, 0);

            Dictionary <int, Modification> allModsOneIsNterminus2 = new Dictionary <int, Modification>
            {
                { 2, modFormula_H1 },
            };

            PeptideWithSetModifications pwsm2 = new PeptideWithSetModifications(protein1, new DigestionParams(), 2, 9, CleavageSpecificity.Unknown, null, 0, allModsOneIsNterminus2, 0);

            CommonParameters CommonParameters = new CommonParameters(digestionParams: new DigestionParams(maxMissedCleavages: 0, minPeptideLength: 1), scoreCutoff: 1);
            var fsp = new List <(string fileName, CommonParameters fileSpecificParameters)>();

            fsp.Add(("", CommonParameters));

            List <MatchedFragmentIon> mfi = new List <MatchedFragmentIon>();

            //we're adding a neutral loss of 5 to the product to make sure we hit the right spot in the unit test to add that loss to the product ion string
            Product p = new Product(ProductType.b, FragmentationTerminus.N, 1, 1, 1, 5);

            mfi.Add(new MatchedFragmentIon(ref p, 1, 1, 1));
            PeptideSpectralMatch myPsm = new PeptideSpectralMatch(pwsm1, 0, 10, 0, scan, new CommonParameters(), mfi);

            myPsm.AddOrReplace(pwsm2, 10, 0, true, mfi, 10);

            myPsm.ResolveAllAmbiguities();

            //Here we have a situation where there are two mods at the same position with different chemical formuala. They cannot be resolved and so the return value is null.
            Assert.IsNull(myPsm.ModsChemicalFormula);

            string myPsmString = myPsm.ToString();

            string[] myPsmStringSplit = myPsmString.Split('\t');
            string   ppmErrorString   = myPsmStringSplit[23];

            //The two different mods produce two separate mass errors, which are both then reported
            Assert.AreEqual("0.00|11801.30", ppmErrorString);

            //Make sure we see produt ion neutral losses in the output.
            string matchedIonSeries = myPsmStringSplit[38];

            Assert.AreEqual("[(b1-5.00)+1]", matchedIonSeries);


            //removing one of the peptides to reset for the next test
            myPsm.RemoveThisAmbiguousPeptide(0, pwsm2);

            PeptideWithSetModifications pwsm3 = new PeptideWithSetModifications(protein1, new DigestionParams(), 2, 9, CleavageSpecificity.Unknown, null, 0, allModsOneIsNterminus1, 0);

            myPsm.AddOrReplace(pwsm3, 10, 0, true, mfi, 10);

            myPsm.ResolveAllAmbiguities();

            //Now we have removed one of the peptides with a different chemical formual and replaced it with a mod that has the same chemical formula as the remaining original best peptide
            //Here we have a situation where there are two mods at the same position have the same chemical formuala and they can be resolved and so the return value the chemical formual of the mod.
            Assert.AreEqual("C", myPsm.ModsChemicalFormula.Formula.ToString());

            myPsmString      = myPsm.ToString();
            myPsmStringSplit = myPsmString.Split('\t');
            ppmErrorString   = myPsmStringSplit[23];

            Assert.AreEqual("0.00", ppmErrorString);
        }