} //Total score is the score of matched ions that are used for localization. For O-glycan, it is the score of all matched c/zDot ions. public LocalizationGraph(int[] modPos, ModBox modBox, ModBox[] childModBoxes, int id) { ModPos = modPos; ModBox = modBox; ModBoxId = id; ChildModBoxes = childModBoxes; //array is localization graph matrix. array is composed of 2d array of node. From left to right, node is build under a glycosite. From up to down, node is build for each child box. array = new AdjNode[modPos.Length][]; for (int i = 0; i < modPos.Length; i++) { array[i] = new AdjNode[ChildModBoxes.Length]; } }
//The modification problem is turned into a Directed Acyclic Graph. The Graph was build with matrix, and dynamic programming is used. //The function goes through the AdjNode[][] array from left to right, assign weight to each AdjNode, keep track of the heaviest previous AdjNode. 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. int maxLength = i + 1; int minlength = localizationGraph.ModBox.ModIds.Length - (localizationGraph.ModPos.Length - 1 - i); for (int j = 0; j < localizationGraph.ChildModBoxes.Length; j++) { if (localizationGraph.ChildModBoxes[j].NumberOfMods <= maxLength && localizationGraph.ChildModBoxes[j].NumberOfMods >= minlength) { AdjNode adjNode = new AdjNode(i, j, localizationGraph.ModPos[i], localizationGraph.ChildModBoxes[j]); double cost = 0; if (i != localizationGraph.ModPos.Length - 1) { var fragments = GlycoPeptides.GetLocalFragment(products, localizationGraph.ModPos, i, localizationGraph.ModBox, localizationGraph.ChildModBoxes[j]); cost = CalculateCost(theScan, productTolerance, fragments); } adjNode.CurrentCost = cost; //The first line of the graph didnot have Sources. if (i == 0) { //Get cost adjNode.maxCost = cost; } else { double maxCost = 0; for (int prej = 0; prej <= j; prej++) { //Check if a previous AdjNode exist and the current AdjNode could link to previous AdjNode. if (boxSatisfyBox[j][prej] && localizationGraph.array[i - 1][prej] != null) { adjNode.AllSources.Add(prej); var tempCost = cost + localizationGraph.array[i - 1][prej].maxCost; if (tempCost > maxCost) { adjNode.CummulativeSources.Clear(); adjNode.CummulativeSources.Add(prej); maxCost = tempCost; } else if (tempCost == maxCost) { adjNode.CummulativeSources.Add(prej); } } } adjNode.maxCost = maxCost; } localizationGraph.array[i][j] = adjNode; } } } var unlocalFragments = GlycoPeptides.GetUnlocalFragment(products, localizationGraph.ModPos, localizationGraph.ModBox); var noLocalScore = CalculateCost(theScan, productTolerance, unlocalFragments); localizationGraph.NoLocalCost = noLocalScore; localizationGraph.TotalScore = localizationGraph.array[localizationGraph.ModPos.Length - 1][localizationGraph.ChildModBoxes.Length - 1].maxCost + noLocalScore; }