Skip to content

Commit cd9fb14

Browse files
author
stefanks
authored
Merge pull request #355 from smith-chem-wisc/StefanBranch
Performance
2 parents 58bd891 + e8dd19a commit cd9fb14

9 files changed

+244
-91
lines changed

EngineLayer/ClassicSearch/ClassicSearchEngine.cs

+5-4
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,9 @@ protected override MetaMorpheusEngineResults RunSpecific()
141141
}
142142
}
143143

144-
var sortedProductMasses = yyy.SortedProductMasses(lp);
145-
double[] matchedIonMassesListPositiveIsMatch = new double[sortedProductMasses.Length];
144+
var productMasses = yyy.ProductMassesMightHaveDuplicatesAndNaNs(lp);
145+
Array.Sort(productMasses);
146+
double[] matchedIonMassesListPositiveIsMatch = new double[productMasses.Length];
146147

147148
for (int aede = 0; aede < searchModes.Count; aede++)
148149
{
@@ -156,15 +157,15 @@ protected override MetaMorpheusEngineResults RunSpecific()
156157
//
157158
//}
158159

159-
var score = PsmWithMultiplePossiblePeptides.MatchIons(scan.TheScan, productMassTolerance, sortedProductMasses, matchedIonMassesListPositiveIsMatch);
160+
var score = PsmWithMultiplePossiblePeptides.MatchIons(scan.TheScan, productMassTolerance, productMasses, matchedIonMassesListPositiveIsMatch);
160161
var psm = new PsmClassic(yyy, fileName, scan.RetentionTime, scan.MonoisotopicPrecursorIntensity, scan.MonoisotopicPrecursorMass, scan.OneBasedScanNumber, scan.OneBasedPrecursorScanNumber, scan.PrecursorCharge, scan.NumPeaks, scan.TotalIonCurrent, scan.MonoisotopicPrecursorMZ, score, theTuple.Item2);
161162
if (psm.score > 1)
162163
{
163164
PsmClassic current_best_psm = psms[aede][scan.OneBasedScanNumber - 1];
164165
if (current_best_psm == null || PsmClassic.FirstIsPreferable(psm, current_best_psm, variableModifications))
165166
{
166167
psms[aede][scan.OneBasedScanNumber - 1] = psm;
167-
matchedIonMassesListPositiveIsMatch = new double[sortedProductMasses.Length];
168+
matchedIonMassesListPositiveIsMatch = new double[productMasses.Length];
168169
}
169170
}
170171
}

EngineLayer/Indexing/IndexingEngine.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -134,13 +134,13 @@ protected override MetaMorpheusEngineResults RunSpecific()
134134
myDictionary.Add(ps);
135135
}
136136

137-
foreach (var huhu in yyy.SortedProductMasses(lp))
137+
foreach (var huhu in yyy.ProductMassesMightHaveDuplicatesAndNaNs(lp))
138138
{
139139
if (!double.IsNaN(huhu))
140140
{
141141
var rounded = (float)Math.Round(huhu, decimalDigitsForFragmentMassRounding);
142142
List<int> value;
143-
if (myInnerDictionary.TryGetValue(rounded, out value))
143+
if (myInnerDictionary.TryGetValue(rounded, out value) && !value.Contains(index))
144144
value.Add(index);
145145
else
146146
myInnerDictionary.Add(rounded, new List<int> { index });

EngineLayer/Proteomics/PeptideWithSetModifications.cs

+51-19
Original file line numberDiff line numberDiff line change
@@ -195,30 +195,62 @@ public PeptideWithSetModifications Localize(int j, double massToLocalize)
195195
return hm;
196196
}
197197

198-
public double[] SortedProductMasses(List<ProductType> productTypes)
198+
public double[] ProductMassesMightHaveDuplicatesAndNaNs(List<ProductType> productTypes)
199199
{
200+
int massLen = 0;
201+
bool containsAdot = productTypes.Contains(ProductType.Adot);
202+
bool containsB = productTypes.Contains(ProductType.B);
203+
bool containsC = productTypes.Contains(ProductType.C);
204+
bool containsX = productTypes.Contains(ProductType.X);
205+
bool containsY = productTypes.Contains(ProductType.Y);
206+
bool containsZdot = productTypes.Contains(ProductType.Zdot);
207+
if (containsAdot)
208+
throw new NotImplementedException();
209+
if (containsB)
210+
massLen += Length - 2;
211+
if (containsC)
212+
massLen += Length - 1;
213+
if (containsX)
214+
throw new NotImplementedException();
215+
if (containsY)
216+
massLen += Length - 1;
217+
if (containsZdot)
218+
massLen += Length - 1;
219+
220+
double[] massesToReturn = new double[massLen];
221+
200222
if (p == null)
201223
ComputeFragmentMasses();
202224

203-
IEnumerable<double> allMasses = new List<double>();
204-
205-
// TODO: THIS
206-
//if (!(product_type == ProductType.C && r < Length && this[r] == 'P') &&
207-
//!(product_type == ProductType.Zdot && Length - r < Length && this[Length - r] == 'P')
208-
if (productTypes.Contains(ProductType.Adot))
209-
throw new NotImplementedException();
210-
if (productTypes.Contains(ProductType.B))
211-
allMasses = allMasses.Concat(p.nTerminalMasses.Where(b => b.index > 1).Select(b => b.mass));
212-
if (productTypes.Contains(ProductType.C))
213-
allMasses = allMasses.Concat(p.nTerminalMasses.Select(b => b.mass + nitrogenAtomMonoisotopicMass + 3 * hydrogenAtomMonoisotopicMass));
214-
if (productTypes.Contains(ProductType.X))
215-
throw new NotImplementedException();
216-
if (productTypes.Contains(ProductType.Y))
217-
allMasses = allMasses.Concat(p.cTerminalMasses.Select(b => b.mass + waterMonoisotopicMass));
218-
if (productTypes.Contains(ProductType.Zdot))
219-
allMasses = allMasses.Concat(p.cTerminalMasses.Select(b => b.mass + oxygenAtomMonoisotopicMass - nitrogenAtomMonoisotopicMass));
225+
int i = 0;
226+
foreach (var hm in p.nTerminalMasses)
227+
{
228+
if (hm.index > 1 && containsB)
229+
{
230+
massesToReturn[i] = hm.mass;
231+
i++;
232+
}
233+
if (containsC)
234+
{
235+
massesToReturn[i] = hm.mass + nitrogenAtomMonoisotopicMass + 3 * hydrogenAtomMonoisotopicMass;
236+
i++;
237+
}
238+
}
239+
foreach (var hm in p.cTerminalMasses)
240+
{
241+
if (containsY)
242+
{
243+
massesToReturn[i] = hm.mass + waterMonoisotopicMass;
244+
i++;
245+
}
246+
if (containsZdot)
247+
{
248+
massesToReturn[i] = hm.mass + oxygenAtomMonoisotopicMass - nitrogenAtomMonoisotopicMass;
249+
i++;
250+
}
251+
}
220252

221-
return allMasses.Where(f => !double.IsNaN(f)).GroupBy(b => Math.Round(b, 3)).Select(b => b.Key).OrderBy(b => b).ToArray();
253+
return massesToReturn;
222254
}
223255

224256
public override bool Equals(object obj)

EngineLayer/PsmWithMultiplePossiblePeptides.cs

+90-48
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Chemistry;
22
using MassSpectrometry;
33
using MzLibUtil;
4+
using System;
45
using System.Collections.Generic;
56
using System.Globalization;
67
using System.Linq;
@@ -36,8 +37,9 @@ public PsmWithMultiplePossiblePeptides(PsmParent newPsm, HashSet<PeptideWithSetM
3637
var MatchedIonDictPositiveIsMatch = new Dictionary<ProductType, double[]>();
3738
foreach (var huh in lp)
3839
{
39-
var df = representative.SortedProductMasses(new List<ProductType> { huh });
40+
var df = representative.ProductMassesMightHaveDuplicatesAndNaNs(new List<ProductType> { huh });
4041
double[] matchedIonMassesListPositiveIsMatch = new double[df.Length];
42+
Array.Sort(matchedIonMassesListPositiveIsMatch);
4143
MatchIons(theScan, fragmentTolerance, df, matchedIonMassesListPositiveIsMatch);
4244
MatchedIonDictPositiveIsMatch.Add(huh, matchedIonMassesListPositiveIsMatch);
4345
}
@@ -53,7 +55,8 @@ public PsmWithMultiplePossiblePeptides(PsmParent newPsm, HashSet<PeptideWithSetM
5355
{
5456
PeptideWithSetModifications localizedPeptide = representative.Localize(indexToLocalize, ScanPrecursorMass - representative.MonoisotopicMass);
5557

56-
var gg = localizedPeptide.SortedProductMasses(lp);
58+
var gg = localizedPeptide.ProductMassesMightHaveDuplicatesAndNaNs(lp);
59+
Array.Sort(gg);
5760
double[] matchedIonMassesListPositiveIsMatch = new double[gg.Length];
5861
var score = MatchIons(theScan, fragmentTolerance, gg, matchedIonMassesListPositiveIsMatch);
5962
localizedScores.Add(score);
@@ -161,6 +164,91 @@ internal static string TabSeparatedHeader
161164

162165
#region Public Methods
163166

167+
public static double MatchIons(IMsDataScan<IMzSpectrum<IMzPeak>> thisScan, Tolerance productMassTolerance, double[] sorted_theoretical_product_masses_for_this_peptide, double[] matchedIonMassesListPositiveIsMatch)
168+
{
169+
var TotalProductsHere = sorted_theoretical_product_masses_for_this_peptide.Length;
170+
if (TotalProductsHere == 0)
171+
return 0;
172+
int MatchingProductsHere = 0;
173+
double MatchingIntensityHere = 0;
174+
175+
// speed optimizations
176+
double[] experimental_mzs = thisScan.MassSpectrum.XArray;
177+
double[] experimental_intensities = thisScan.MassSpectrum.YArray;
178+
int num_experimental_peaks = experimental_mzs.Length;
179+
180+
int currentTheoreticalIndex = -1;
181+
double currentTheoreticalMass;
182+
do
183+
{
184+
currentTheoreticalIndex++;
185+
currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex];
186+
} while (double.IsNaN(currentTheoreticalMass));
187+
188+
double currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass;
189+
190+
int testTheoreticalIndex;
191+
double testTheoreticalMZ;
192+
double testTheoreticalMass;
193+
// Loop over all experimenal indices
194+
for (int experimentalIndex = 0; experimentalIndex < num_experimental_peaks; experimentalIndex++)
195+
{
196+
double currentExperimentalMZ = experimental_mzs[experimentalIndex];
197+
// If found match
198+
if (productMassTolerance.Within(currentExperimentalMZ, currentTheoreticalMz))
199+
{
200+
MatchingProductsHere++;
201+
MatchingIntensityHere += experimental_intensities[experimentalIndex];
202+
matchedIonMassesListPositiveIsMatch[currentTheoreticalIndex] = currentTheoreticalMass;
203+
currentTheoreticalIndex++;
204+
if (currentTheoreticalIndex == TotalProductsHere)
205+
break;
206+
currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex];
207+
currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass;
208+
}
209+
// Else if for sure did not reach the next theoretical yet, move to next experimental
210+
else if (currentExperimentalMZ < currentTheoreticalMz)
211+
continue;
212+
// Else if for sure passed a theoretical
213+
else
214+
{
215+
// Mark the theoretical as missed
216+
matchedIonMassesListPositiveIsMatch[currentTheoreticalIndex] = -currentTheoreticalMass;
217+
218+
// Move on to next index and never come back!
219+
currentTheoreticalIndex++;
220+
if (currentTheoreticalIndex == TotalProductsHere)
221+
break;
222+
currentTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[currentTheoreticalIndex];
223+
currentTheoreticalMz = currentTheoreticalMass + Constants.protonMass;
224+
225+
// Start with the current ones
226+
testTheoreticalIndex = currentTheoreticalIndex;
227+
testTheoreticalMZ = currentTheoreticalMz;
228+
testTheoreticalMass = currentTheoreticalMass;
229+
// Mark the skipped theoreticals as not found. The last one is not for sure, might be flipped!
230+
while (currentExperimentalMZ > testTheoreticalMZ)
231+
{
232+
matchedIonMassesListPositiveIsMatch[testTheoreticalIndex] = -currentTheoreticalMass;
233+
// Store old info for possible reuse
234+
currentTheoreticalMass = testTheoreticalMass;
235+
currentTheoreticalMz = testTheoreticalMZ;
236+
currentTheoreticalIndex = testTheoreticalIndex;
237+
238+
// Update test stuff!
239+
testTheoreticalIndex++;
240+
if (testTheoreticalIndex == TotalProductsHere)
241+
break;
242+
testTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[testTheoreticalIndex];
243+
testTheoreticalMZ = testTheoreticalMass + Constants.protonMass;
244+
}
245+
246+
experimentalIndex--;
247+
}
248+
}
249+
return MatchingProductsHere + MatchingIntensityHere / thisScan.TotalIonCurrent;
250+
}
251+
164252
public override string ToString()
165253
{
166254
var sb = new StringBuilder();
@@ -197,51 +285,5 @@ public override string ToString()
197285

198286
#endregion Public Methods
199287

200-
#region Internal Methods
201-
202-
internal static double MatchIons(IMsDataScan<IMzSpectrum<IMzPeak>> thisScan, Tolerance productMassTolerance, double[] sorted_theoretical_product_masses_for_this_peptide, double[] matchedIonMassesListPositiveIsMatch)
203-
{
204-
var TotalProductsHere = sorted_theoretical_product_masses_for_this_peptide.Length;
205-
if (TotalProductsHere == 0)
206-
return 0;
207-
int MatchingProductsHere = 0;
208-
double MatchingIntensityHere = 0;
209-
210-
// speed optimizations
211-
double[] experimental_mzs = thisScan.MassSpectrum.XArray;
212-
double[] experimental_intensities = thisScan.MassSpectrum.YArray;
213-
int num_experimental_peaks = experimental_mzs.Length;
214-
215-
int theoreticalIndex = 0;
216-
double nextTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[0];
217-
double nextTheoreticalMZ = nextTheoreticalMass + Constants.protonMass;
218-
219-
double currentExperimentalMZ;
220-
for (int i = 0; i < num_experimental_peaks; i++)
221-
{
222-
currentExperimentalMZ = experimental_mzs[i];
223-
if (productMassTolerance.Within(currentExperimentalMZ, nextTheoreticalMZ))
224-
{
225-
MatchingProductsHere++;
226-
MatchingIntensityHere += experimental_intensities[i];
227-
matchedIonMassesListPositiveIsMatch[theoreticalIndex] = nextTheoreticalMass;
228-
}
229-
else if (currentExperimentalMZ < nextTheoreticalMZ)
230-
continue;
231-
else
232-
matchedIonMassesListPositiveIsMatch[theoreticalIndex] = -nextTheoreticalMass;
233-
i--;
234-
// Passed a theoretical! Move counter forward
235-
theoreticalIndex++;
236-
if (theoreticalIndex == TotalProductsHere)
237-
break;
238-
nextTheoreticalMass = sorted_theoretical_product_masses_for_this_peptide[theoreticalIndex];
239-
nextTheoreticalMZ = nextTheoreticalMass + Constants.protonMass;
240-
}
241-
return MatchingProductsHere + MatchingIntensityHere / thisScan.TotalIonCurrent;
242-
}
243-
244-
#endregion Internal Methods
245-
246288
}
247289
}

MetaMorpheus.sln

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26228.9
4+
VisualStudioVersion = 15.0.26403.7
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GUI", "GUI\GUI.csproj", "{57B2A726-CCA9-432E-B74A-2EFA962D1A74}"
77
EndProject

0 commit comments

Comments
 (0)