Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions MetaMorpheus/EngineLayer/EngineLayer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@
<None Update="Digestion\rnases.tsv">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Glycan_Mods\General_Mods\ModBox Database.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Glycan_Mods\NGlycan\NGlycan.gdb">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
HexNAc(1) N1H0F0S0 203.0794
HexNAc(1)Hex(1) N1H1F0S0 365.1322
HexNAc(2) N2H0F0S0 406.1588
HexNAc(1)NeuAc(1) N1H0F0S1 494.1748
HexNAc(1)Hex(1)Fuc(1) N1H1F1S0 511.1901
HexNAc(1)Hex(2) N1H2F0S0 527.185
HexNAc(2)Hex(1) N2H1F0S0 568.2116
HexNAc(1)Hex(1)NeuAc(1) N1H1F0S1 656.2276
HexNAc(1)Hex(2)Fuc(1) N1H2F1S0 673.2429
HexNAc(2)Hex(1)Fuc(1) N2H1F1S0 714.2695
Oxidation on M O1 15.9994
Oxidation on Q O1 15.9994
2 changes: 1 addition & 1 deletion MetaMorpheus/EngineLayer/GlycoSearch/AdjNode.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Text;

using EngineLayer.ModSearch;
namespace EngineLayer.GlycoSearch
{
//the class is for localization graph matrix. Each node in the matrix is represented by AdjNode.
Expand Down
38 changes: 36 additions & 2 deletions MetaMorpheus/EngineLayer/GlycoSearch/Glycan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using Proteomics;
using MassSpectrometry;
using Omics.Modifications;
using System.Text.RegularExpressions;

namespace EngineLayer
{
Expand Down Expand Up @@ -60,7 +61,7 @@ public string Composition // Glycan composition string. Ex. H2N2
public HashSet<int> DiagnosticIons // B ions (the sugar fragment dropped from the glycopeptide), used for the N-glycan. There are more ions to set...
{
get
{
{
HashSet<int> diagnosticIons = new HashSet<int>();
if (Kind[0] >= 1) //if we have Hexose(the number more than one), then we have the corresponding diagonsitic ions as below.
{
Expand Down Expand Up @@ -508,6 +509,39 @@ public static string GetKindString(byte[] Kind)
return kindString;
}

/// <summary>
/// Convert the glycan name to the glycan kind array.
/// </summary>
/// <param name="glycanName"></param>
/// <returns></returns>
public static byte[] StringToKind(string glycanName)
{
// Initialize the kind array with zeros
byte[] kind = new byte[NameCharDic.Count];

// Regular expression to match the sugar type and count
Regex regex = new Regex(@"([A-Z][a-z]*)(\d+)");

// Match the input string
var matches = regex.Matches(glycanName);

// Update the kind array based on the matches
foreach (Match match in matches)
{
string sugarType = match.Groups[1].Value;
int count = int.Parse(match.Groups[2].Value);

// Find the corresponding index for the sugar type
var sugarInfo = NameCharDic.FirstOrDefault(x => x.Value.Item1.ToString() == sugarType);
if (sugarInfo.Value != null)
{
kind[sugarInfo.Value.Item2] = (byte)count;
}
}

return kind;
}

#endregion

//TO THINK: Is it reasonable to transfer Glycan to Modification the first time Glycan is read in? Which could save time.
Expand Down Expand Up @@ -557,7 +591,7 @@ public static Modification OGlycanToModification(Glycan glycan) //try to transfe
//TO THINK: what the neutralLoss for O-Glyco?
Dictionary<DissociationType, List<double>> neutralLosses = new Dictionary<DissociationType, List<double>>();

if (glycan.Ions!=null)
if (glycan.Ions != null)
{
List<double> lossMasses = glycan.Ions.Select(p => (double)p.LossIonMass / 1E5).OrderBy(p => p).ToList();
neutralLosses.Add(DissociationType.HCD, lossMasses);
Expand Down
11 changes: 4 additions & 7 deletions MetaMorpheus/EngineLayer/GlycoSearch/GlycanBox.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Chemistry;
using System;
using Proteomics;
using MassSpectrometry;
using Omics.Modifications;
using EngineLayer.ModSearch;

namespace EngineLayer
{
Expand Down Expand Up @@ -128,9 +125,9 @@ public static IEnumerable<GlycanBox> BuildChildOGlycanBoxes(int maxNum, int[] gl
public GlycanBox(int[] ids, bool Istarget = true):base(ids)
{
byte[] kind = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
foreach (var id in ModIds) //ModIds is the same as ids.
foreach (var id in ids) //ModIds is the same as ids.
{
for (int i = 0; i < kind.Length; i++)
for (int i = 0; i < kind.Length; i++)
{
kind[i] += GlobalOGlycans[id].Kind[i]; //kind is the sum of all glycan Kind in the Box.
}
Expand All @@ -139,7 +136,7 @@ public GlycanBox(int[] ids, bool Istarget = true):base(ids)

if (Istarget)
{
Mass = (double)Glycan.GetMass(Kind) / 1E5;
Mass = (double)(Glycan.GetMass(Kind)) / 1E5;
}
else
{
Expand Down
8 changes: 4 additions & 4 deletions MetaMorpheus/EngineLayer/GlycoSearch/GlycoPeptides.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using MassSpectrometry;
using Proteomics;
using Omics.Fragmentation;
using Proteomics.ProteolyticDigestion;
using System;
using System.Collections.Generic;
using System.Linq;
using Chemistry;
using Omics.Modifications;
using EngineLayer.ModSearch;

namespace EngineLayer.GlycoSearch
{
Expand Down Expand Up @@ -438,15 +438,15 @@ public static List<double> GetLocalFragment(List<Product> products, int[] modPos

foreach (var c in local_c_fragments)
{
var newMass = c.NeutralMass + localOGlycanBox.Mass;
var newMass = c.NeutralMass + localOGlycanBox.Mass.Value; // use the value to get the double value of the mass.
newFragments.Add(newMass);
}

var local_z_fragments = products.Where(p => p.ProductType == ProductType.zDot && p.AminoAcidPosition >= modPoses[modInd] && p.AminoAcidPosition < modPoses[modInd + 1]).ToList();

foreach (var z in local_z_fragments)
{
var newMass = z.NeutralMass + (OGlycanBox.Mass - localOGlycanBox.Mass);
var newMass = z.NeutralMass + (OGlycanBox.Mass.Value - localOGlycanBox.Mass.Value);
newFragments.Add(newMass);
}

Expand All @@ -456,7 +456,7 @@ public static List<double> GetLocalFragment(List<Product> products, int[] modPos
//Find FragmentMass for the fragments that doesn't contain localization Information. For example, "A|TAABBS|B", c1 and c7, z1 and z7, z8 ion don't contain localization information.
public static List<double> GetUnlocalFragment(List<Product> products, int[] modPoses, ModBox OGlycanBox)
{
var mass = OGlycanBox.Mass;
var mass = OGlycanBox.Mass.Value;

List<double> newFragments = new List<double>();
var c_fragments = products.Where(p => p.ProductType == ProductType.c && p.AminoAcidPosition < modPoses.First() - 1).Select(p => p.NeutralMass);
Expand Down
24 changes: 12 additions & 12 deletions MetaMorpheus/EngineLayer/GlycoSearch/GlycoSearchEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class GlycoSearchEngine : ModernSearchEngine
{
public static readonly double ToleranceForMassDifferentiation = 1e-9;
private readonly int OxoniumIon204Index = 9; // Check Glycan.AllOxoniumIons
protected readonly List<GlycoSpectralMatch>[] GlobalGsms; // Why don't we call it GlobalGsms?
protected readonly List<GlycoSpectralMatch>[] GlobalGsms;

private GlycoSearchType GlycoSearchType;
private readonly int TopN; // DDA top Peak number.
Expand Down Expand Up @@ -204,7 +204,7 @@ protected override MetaMorpheusEngineResults RunSpecific()

if (GlobalGsms[scanIndex] == null)
{
GlobalGsms[scanIndex] = new List<GlycoSpectralMatch>(); //the first one finished task, create teh new gsms list.
GlobalGsms[scanIndex] = new List<GlycoSpectralMatch>(); //the first one finished task, create the new gsms list.
}
else
{
Expand Down Expand Up @@ -392,23 +392,23 @@ private void FindSingle(Ms2ScanWithSpecificMass theScan, int scanIndex, int scor
/// <summary>
/// Match the mass of the peptide candidate with the precursor mass. Try to generate the Gsms for the Scan. Gsms will be stored in the possibleMatches.
/// </summary>
/// <param name="theScan"></param>
/// <param name="scanIndex"></param>
/// <param name="scoreCutOff"></param>
/// <param name="theScan"> The experimental data</param>
/// <param name="scanIndex"> The index for the scan</param>
/// <param name="scoreCutOff"> the cutoff for the indexing score</param>
/// <param name="theScanBestPeptide"> peptide candidate </param>
/// <param name="ind"></param>
/// <param name="possibleGlycanMassLow"> The precursor mass </param>
/// <param name="oxoniumIonIntensities"></param>
/// <param name="possibleGlycanMassLow"> The mass shift between the exact mass and the experimental mass </param>
/// <param name="oxoniumIonIntensities"> The oxonium for the filtering</param>
/// <param name="possibleMatches"> The space to store the gsms </param>
private void FindOGlycan(Ms2ScanWithSpecificMass theScan, int scanIndex, int scoreCutOff, PeptideWithSetModifications theScanBestPeptide, int ind, double possibleGlycanMassLow, double[] oxoniumIonIntensities, ref List<GlycoSpectralMatch> possibleMatches)
{
// The glycanBoxes will be filtered by the oxonium ions. If the oxonium ions don't make sense, we will remove the glycanBox.


int iDLow = GlycoPeptides.BinarySearchGetIndex(GlycanBox.OGlycanBoxes.Select(p => p.Mass).ToArray(), possibleGlycanMassLow); // try to find the index that closet match to the "possibleGlycanMassLow" within the glycanBox
// Using "possibleGlycanMassLow" to find index for the best matached glycanBox
int iDLow = GlycoPeptides.BinarySearchGetIndex(GlycanBox.OGlycanBoxes.Select(p => p.Mass.Value).ToArray(), possibleGlycanMassLow);

int[] modPos = GlycoSpectralMatch.GetPossibleModSites(theScanBestPeptide, new string[] { "S", "T" }).OrderBy(p => p).ToArray(); //list all of the possible glycoslation site/postition

var localizationScan = theScan;
List<Product> products = new List<Product>(); // product list for the theoretical fragment ions

Expand Down Expand Up @@ -438,7 +438,7 @@ private void FindOGlycan(Ms2ScanWithSpecificMass theScan, int scanIndex, int sco

List<LocalizationGraph> localizationGraphs = new List<LocalizationGraph>(); // if we also have ETD, then we will search the localization

while (iDLow < GlycanBox.OGlycanBoxes.Count() && (PrecusorSearchMode.Within(theScan.PrecursorMass, theScanBestPeptide.MonoisotopicMass + GlycanBox.OGlycanBoxes[iDLow].Mass))) // verify the glycan mass is invaild (within the range and match with mass shift)
while (iDLow < GlycanBox.OGlycanBoxes.Count() && (PrecusorSearchMode.Within(theScan.PrecursorMass, theScanBestPeptide.MonoisotopicMass + GlycanBox.OGlycanBoxes[iDLow].Mass.Value))) // verify the glycan mass is invaild (within the range and match with mass shift)
{
if (OxoniumIonFilter && !GlycoPeptides.DiagonsticFilter(oxoniumIonIntensities, GlycanBox.OGlycanBoxes[iDLow])) // if the filter is turned on, we need to check does the oxoiums make sense.
{
Expand All @@ -447,6 +447,7 @@ private void FindOGlycan(Ms2ScanWithSpecificMass theScan, int scanIndex, int sco
}
if (modPos.Length >= GlycanBox.OGlycanBoxes[iDLow].NumberOfMods) // the glycosite number should be larger than the possible glycan number.
{

LocalizationGraph localizationGraph = new LocalizationGraph(modPos, GlycanBox.OGlycanBoxes[iDLow], GlycanBox.OGlycanBoxes[iDLow].ChildGlycanBoxes, iDLow);
LocalizationGraph.LocalizeOGlycan(localizationGraph, localizationScan, CommonParameters.ProductMassTolerance, products); //create the localization graph with the glycan mass and the possible glycosite.

Expand Down Expand Up @@ -646,7 +647,6 @@ private List<GlycoSpectralMatch> FindOGlycopeptideHashLocal(Ms2ScanWithSpecificM
{
continue;
}

//Find O-Glycan
FindOGlycan(theScan, scanIndex, scoreCutOff, theScanBestPeptide, ind, possibleGlycanMassLow, oxoniumIonIntensities, ref possibleMatches);
}
Expand Down
6 changes: 3 additions & 3 deletions MetaMorpheus/EngineLayer/GlycoSearch/GlycoSpectralMatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ public string GlycoToString()
sb.Append(string.Join(",", glycans.Select(p => p.Struc.ToString()).ToArray())); //ex. (N(H)),(N(H(A))(N(H))),(N(H)(N(H(A))(F))
}
sb.Append("\t");

sb.Append(CorrectLocalizationLevel(SiteSpeciLocalProb, LocalizationGraphs.First(), Routes.First(), LocalizedGlycan, LocalizationLevel)); sb.Append("\t");

string local_peptide = "";
Expand Down Expand Up @@ -357,7 +357,7 @@ public string GlycoToString()
sb.Append("\t");
sb.Append("\t");

sb.Append("\t");
sb.Append("\t");

sb.Append(SiteSpeciLocalInfo(SiteSpeciLocalProb));
}
Expand Down Expand Up @@ -420,7 +420,7 @@ public static List<Tuple<int, int, bool>> GetLocalizedGlycan(List<Route> OGlycan

foreach (var seenMod in modSiteSeenCount)
{
if (seenMod.Value == OGlycanBoxLocalization.Count) // Try to fine the glycan-site pair that always localized in all the cases.
if (seenMod.Value == OGlycanBoxLocalization.Count) // Try to find the glycan-site pair that always localized in all the cases.
{
localizedGlycan.Add(new Tuple<int, int, bool>(int.Parse(seenMod.Key.Split('-')[0]), int.Parse(seenMod.Key.Split('-')[1]), true));
}
Expand Down
6 changes: 2 additions & 4 deletions MetaMorpheus/EngineLayer/GlycoSearch/LocalizationGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using Omics.Fragmentation;
using Proteomics.ProteolyticDigestion;
using Proteomics;
using MzLibUtil;
using EngineLayer.ModSearch;

namespace EngineLayer.GlycoSearch
{
Expand Down Expand Up @@ -46,7 +45,6 @@ public LocalizationGraph(int[] modPos, ModBox modBox, ModBox[] childModBoxes, in
public static void LocalizeOGlycan(LocalizationGraph localizationGraph, Ms2ScanWithSpecificMass theScan, Tolerance productTolerance, List<Product> products)
{
var boxSatisfyBox = BoxSatisfyBox(localizationGraph.ChildModBoxes);

for (int i = 0; i < localizationGraph.ModPos.Length; i++)
{
//maxLength: the most mods we can have up to current mod pos; minlengtt: the least mods we can have up to current mod pos.
Expand All @@ -57,7 +55,7 @@ public static void LocalizeOGlycan(LocalizationGraph localizationGraph, Ms2ScanW
{
if (localizationGraph.ChildModBoxes[j].NumberOfMods <= maxLength && localizationGraph.ChildModBoxes[j].NumberOfMods >= minlength)
{
AdjNode adjNode = new AdjNode(i, j, localizationGraph.ModPos[i], localizationGraph.ChildModBoxes[j]); //chekc the num of glycan in this node is make sense.
AdjNode adjNode = new AdjNode(i, j, localizationGraph.ModPos[i], localizationGraph.ChildModBoxes[j]); //check the num of glycan in this node is make sense.

double cost = 0;
if (i != localizationGraph.ModPos.Length - 1) // check the node is not the last one.
Expand Down
25 changes: 0 additions & 25 deletions MetaMorpheus/EngineLayer/GlycoSearch/ModBox.cs

This file was deleted.

2 changes: 1 addition & 1 deletion MetaMorpheus/EngineLayer/GlycoSearch/Route.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public class Route

public int ModBoxId { get; set; }

//Tuple<int, int, double> mod pos, glycan id, local peak exist
//Tuple<int, int, double> mod pos, Mod id, local peak exist
//For the local peak exist, the idea is that, in the localization graph matrix, if the node is detected as a mod, then the node score and the previous node has a current score >0.
public List<Tuple<int, int, bool>> Mods { get; private set; } = new List<Tuple<int, int, bool>>();

Expand Down
Loading
Loading