public void TestTwoAminoAcidLinkedPeptide() { const string modName = "crosslinker"; var srmSettings = SrmSettingsList.GetDefault(); srmSettings = srmSettings.ChangeTransitionSettings(srmSettings.TransitionSettings.ChangeFilter( srmSettings.TransitionSettings.Filter .ChangeFragmentRangeFirstName(TransitionFilter.StartFragmentFinder.ION_1.Name) .ChangeFragmentRangeLastName(@"last ion") .ChangePeptideIonTypes(new[] { IonType.precursor, IonType.y, IonType.b }) )); var mainPeptide = new Peptide("AD"); var staticMod = new StaticMod(modName, null, null, "-C2"); var linkedPeptide = new LinkedPeptide(new Peptide("EF"), 1, null); var mainTransitionGroup = new TransitionGroup(mainPeptide, Adduct.DOUBLY_PROTONATED, IsotopeLabelType.light); var mainTransitionGroupDocNode = new TransitionGroupDocNode(mainTransitionGroup, Annotations.EMPTY, srmSettings, null, null, ExplicitTransitionGroupValues.EMPTY, null, new TransitionDocNode[0], false); var modsWithLinkedPeptide = new ExplicitMods(mainPeptide, new[] { new ExplicitMod(0, staticMod).ChangeLinkedPeptide(linkedPeptide) }, new TypedExplicitModifications[0]); Assert.AreEqual(1, srmSettings.PeptideSettings.Modifications.MaxNeutralLosses); var oneNeutralLossChoices = mainTransitionGroupDocNode.GetTransitions( srmSettings, modsWithLinkedPeptide, mainTransitionGroupDocNode.PrecursorMz, mainTransitionGroupDocNode.IsotopeDist, null, null, true).Select(transition => transition.ComplexFragmentIon.GetName()).ToList(); var modSite = new ModificationSite(0, modName); var expectedFragmentIons = new[] { ComplexFragmentIonName.PRECURSOR.AddChild(modSite, ComplexFragmentIonName.PRECURSOR), ComplexFragmentIonName.PRECURSOR.AddChild(modSite, new ComplexFragmentIonName(IonType.y, 1)), new ComplexFragmentIonName(IonType.y, 1), new ComplexFragmentIonName(IonType.b, 1).AddChild(modSite, new ComplexFragmentIonName(IonType.precursor, 0)), ComplexFragmentIonName.ORPHAN.AddChild(modSite, new ComplexFragmentIonName(IonType.b, 1)), }; CollectionAssert.AreEquivalent(expectedFragmentIons, oneNeutralLossChoices); }
private void WriteLinkedIon(XmlWriter writer, ModificationSite modificationSite, ComplexFragmentIon complexFragmentIon) { writer.WriteStartElement(EL.linked_fragment_ion); if (!complexFragmentIon.IsOrphan) { // blank fragment type means orphaned fragment ion writer.WriteAttribute(ATTR.fragment_type, complexFragmentIon.Transition.IonType); } if (complexFragmentIon.Transition.IonType != IonType.precursor) { writer.WriteAttribute(ATTR.fragment_ordinal, complexFragmentIon.Transition.Ordinal); } writer.WriteAttribute(ATTR.index_aa, modificationSite.IndexAa); writer.WriteAttribute(ATTR.modification_name, modificationSite.ModName); WriteTransitionLosses(writer, complexFragmentIon.TransitionLosses); foreach (var child in complexFragmentIon.Children) { WriteLinkedIon(writer, child.Key, child.Value); } writer.WriteEndElement(); }
protected override void DoTest() { const string crosslinkerName = "Hydrolysis"; RunUI(() => SkylineWindow.OpenFile(TestFilesDir.GetTestPath("CrosslinkNeutralLossTest.sky"))); var peptideSettingsUi = ShowDialog <PeptideSettingsUI>(SkylineWindow.ShowPeptideSettingsUI); RunUI(() => { peptideSettingsUi.SelectedTab = PeptideSettingsUI.TABS.Modifications; }); var editModListDlg = ShowEditStaticModsDlg(peptideSettingsUi); // Define a crosslinker which is a water loss. In this way, two peptides can be joined end to end // and will have the same chemical formula as a single concatenated peptide RunDlg <EditStaticModDlg>(editModListDlg.AddItem, editStaticModDlg => { { editStaticModDlg.Modification = new StaticMod(crosslinkerName, null, null, "-H2O"); editStaticModDlg.IsCrosslinker = true; editStaticModDlg.OkDialog(); } }); RunDlg <EditStaticModDlg>(editModListDlg.AddItem, editStaticModDlg => { editStaticModDlg.Modification = ChangeLossesToIncludeAlways(UniMod.GetModification("Oxidation (M)", true)); editStaticModDlg.OkDialog(); }); RunDlg <EditStaticModDlg>(editModListDlg.AddItem, editStaticModDlg => { editStaticModDlg.Modification = ChangeLossesToIncludeAlways(UniMod.GetModification("Phospho (ST)", true)); editStaticModDlg.OkDialog(); }); OkDialog(editModListDlg, editModListDlg.OkDialog); OkDialog(peptideSettingsUi, peptideSettingsUi.OkDialog); RunDlg <PasteDlg>(SkylineWindow.ShowPastePeptidesDlg, pasteDlg => { // Insert two peptides which are equivalent to each other. // The first peptide is composed of two short peptides concatenated with the hydrolysis crosslinker. SetClipboardText(@"AMNFS[Phospho (ST)]GSPGAV-STSPT[Phospho (ST)]QSFM[Oxidation (M)]NTLPR-[Hydrolysis@11,1] AMNFS[Phospho (ST)]GSPGAVSTSPT[Phospho (ST)]QSFM[Oxidation (M)]NTLPR"); pasteDlg.PastePeptides(); pasteDlg.OkDialog(); }); AssertEx.Serializable(SkylineWindow.Document); var crosslinkedPeptide = SkylineWindow.Document.Peptides.First(); var flatPeptide = SkylineWindow.Document.Peptides.Skip(1).First(); Assert.IsNotNull(crosslinkedPeptide.ExplicitMods); Assert.IsNotNull(flatPeptide.ExplicitMods); Assert.IsTrue(crosslinkedPeptide.ExplicitMods.HasCrosslinks); Assert.IsFalse(flatPeptide.ExplicitMods.HasCrosslinks); Assert.AreEqual(1, crosslinkedPeptide.TransitionGroupCount); Assert.AreEqual(1, flatPeptide.TransitionGroupCount); var flatPrecursor = flatPeptide.TransitionGroups.First(); var crosslinkedPrecursor = crosslinkedPeptide.TransitionGroups.First(); Assert.AreEqual(flatPrecursor.PrecursorMz, crosslinkedPrecursor.PrecursorMz, DELTA); ModificationSite crosslinkSite = new ModificationSite(10, crosslinkerName); var flatTransitionNames = flatPrecursor.Transitions.Select(tran => tran.ComplexFragmentIon.GetTargetsTreeLabel() + Transition.GetChargeIndicator(tran.Transition.Adduct)) .ToList(); Assert.AreEqual(flatPrecursor.TransitionCount, flatTransitionNames.Count); var crosslinkedTransitionNames = crosslinkedPrecursor.Transitions.Select(tran => tran.ComplexFragmentIon.GetTargetsTreeLabel() + Transition.GetChargeIndicator(tran.Transition.Adduct)) .ToList(); Assert.AreEqual(crosslinkedPrecursor.TransitionCount, crosslinkedTransitionNames.Count); foreach (var transitionDocNode in flatPrecursor.Transitions) { // AMNFSGSPGAV(11)-STSPTQSFMNTLPR(14) ComplexFragmentIonName complexFragmentIonName = null; switch (transitionDocNode.Transition.IonType) { case IonType.precursor: complexFragmentIonName = ComplexFragmentIonName.PRECURSOR.AddChild(crosslinkSite, ComplexFragmentIonName.PRECURSOR); break; case IonType.b: if (transitionDocNode.Transition.Ordinal == 11) { continue; } if (transitionDocNode.Transition.Ordinal <= 11) { complexFragmentIonName = new ComplexFragmentIonName(IonType.b, transitionDocNode.Transition.Ordinal); } else { complexFragmentIonName = ComplexFragmentIonName.PRECURSOR.AddChild(crosslinkSite, new ComplexFragmentIonName(IonType.b, transitionDocNode.Transition.Ordinal - 11)); } break; case IonType.y: if (transitionDocNode.Transition.Ordinal == 14) { continue; } if (transitionDocNode.Transition.Ordinal < 14) { complexFragmentIonName = ComplexFragmentIonName.ORPHAN.AddChild(crosslinkSite, new ComplexFragmentIonName(IonType.y, transitionDocNode.Transition.Ordinal)); } else { complexFragmentIonName = new ComplexFragmentIonName(IonType.y, transitionDocNode.Transition.Ordinal - 14) .AddChild(crosslinkSite, ComplexFragmentIonName.PRECURSOR); } break; } Assert.IsNotNull(complexFragmentIonName); if (transitionDocNode.Transition.IonType != IonType.precursor && transitionDocNode.Losses != null && transitionDocNode.Losses.Losses.Count > 1) { continue; } var matchingTransitions = crosslinkedPrecursor.Transitions.Where(tran => complexFragmentIonName.Equals(tran.ComplexFragmentIon.GetName()) && Equals(transitionDocNode.Losses, tran.Losses) && Equals(transitionDocNode.Transition.Adduct, tran.Transition.Adduct)).ToList(); AssertEx.AreEqual(1, matchingTransitions.Count); AssertEx.AreEqual(transitionDocNode.Mz, matchingTransitions[0].Mz, DELTA); } }