Skip to content

Commit 3c8e0b8

Browse files
authored
Two New MetaDraw Plots: Histogram of Ambiguity Levels and Histogram of Notch (#2679)
* gitignore * Add Collision Energy column to PSM TSV output Parse collisional energy from MsDataScan.HcdEnergy into a new nullable CollisionalEnergy property on SpectralMatch. Write the column conditionally (only when at least one scan has data) using the same pattern as 1/K0. * Add unit tests for collisional energy TSV column Six tests covering parsed from scan, null when absent, null when invalid, column present with flag, column absent by default, N/A when missing. * Add Collision Energy as a grouping property in MetaDraw data visualization * ambiguity * Notch Plot * more tests
1 parent 5d10144 commit 3c8e0b8

2 files changed

Lines changed: 856 additions & 4 deletions

File tree

MetaMorpheus/GuiFunctions/MetaDraw/PlotModelStat.cs

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public class PlotModelStat
4343
"Histogram of Missed Cleavages",
4444
"Histogram of Fragment Ion Types by Count",
4545
"Histogram of Fragment Ion Types by Intensity",
46-
"Histogram of Ids by Retention Time"
46+
"Histogram of Ids by Retention Time",
47+
"Histogram of Spectral Match Ambiguity Levels",
48+
"Histogram of Notch (Ambiguous PSMs Split Across Notches)"
4749
};
4850

4951
public PlotModel Model => privateModel;
@@ -124,6 +126,12 @@ private void createPlot(string plotType)
124126
case "Histogram of Ids by Retention Time":
125127
histogramPlot(12);
126128
break;
129+
case "Histogram of Spectral Match Ambiguity Levels":
130+
histogramPlot(13);
131+
break;
132+
case "Histogram of Notch (Ambiguous PSMs Split Across Notches)":
133+
histogramPlot(14);
134+
break;
127135
}
128136
}
129137

@@ -153,7 +161,7 @@ private void histogramPlot(int plotType)
153161
int[] totalCounts;
154162
int categoriesPerGroup = 0;
155163
List<string> allGroupKeys = null;
156-
bool isCategoryHistogram = plotType == 5 || plotType == 10 || plotType == 11;
164+
bool isCategoryHistogram = plotType == 5 || plotType == 10 || plotType == 11 || plotType == 13;
157165

158166
if (isCategoryHistogram)
159167
{
@@ -336,6 +344,34 @@ private HistogramRawData GetHistogramData(int plotType)
336344
dictsBySourceFile.Add(fileName, result);
337345
}
338346
break;
347+
case 13: // Histogram of Spectral Match Ambiguity Levels
348+
xAxisTitle = "Ambiguity Level";
349+
labelAngle = 0;
350+
foreach (var fileName in psmsBySourceFile.Keys)
351+
{
352+
var result = psmsBySourceFile[fileName]
353+
.GroupBy(p => NormalizeAmbiguityLevel(p.AmbiguityLevel))
354+
.ToDictionary(p => p.Key, p => p.Count());
355+
dictsBySourceFile.Add(fileName, result);
356+
}
357+
break;
358+
case 14: // Histogram of Notch (ambiguous PSMs contribute to each of their pipe-delimited notches)
359+
xAxisTitle = "Notch";
360+
binSize = 1;
361+
labelAngle = 0;
362+
foreach (var fileName in psmsBySourceFile.Keys)
363+
{
364+
var values = new List<double>();
365+
foreach (var psm in psmsBySourceFile[fileName])
366+
{
367+
foreach (double notch in ParseAmbiguousNotchValues(psm.Notch))
368+
values.Add(notch);
369+
}
370+
numbersBySourceFile.Add(fileName, values);
371+
var results = values.GroupBy(p => roundToBin(p, binSize)).OrderBy(p => p.Key).Select(p => p);
372+
dictsBySourceFile.Add(fileName, results.ToDictionary(p => p.Key.ToString(CultureInfo.InvariantCulture), v => v.Count()));
373+
}
374+
break;
339375
}
340376

341377
return new HistogramRawData(xAxisTitle, yAxisTitle, binSize, labelAngle, numbersBySourceFile, dictsBySourceFile);
@@ -515,6 +551,13 @@ private Dictionary<string, int> GetCategoryDictForGroup(int plotType, Observable
515551
return mods.GroupBy(p => p.IdWithMotif).ToDictionary(p => p.Key, v => v.Count());
516552
}
517553

554+
if (plotType == 13)
555+
{
556+
return groupPsms
557+
.GroupBy(p => NormalizeAmbiguityLevel(p.AmbiguityLevel))
558+
.ToDictionary(p => p.Key, p => p.Count());
559+
}
560+
518561
var allMatchedIons = groupPsms.SelectMany(p => p.MatchedIons).ToList();
519562
if (plotType == 10)
520563
{
@@ -1013,6 +1056,7 @@ private IEnumerable<double> GetNumbersFromPsms(ObservableCollection<SpectrumMatc
10131056
8 => GetHydrophobicityScores(psms),
10141057
9 => psms.Where(p => !p.MissedCleavage.Contains("|")).Select(p => double.Parse(p.MissedCleavage)),
10151058
12 => psms.Select(p => (double)(int)Math.Round(p.RetentionTime, 0)),
1059+
14 => psms.SelectMany(p => ParseAmbiguousNotchValues(p.Notch)),
10161060
_ => Enumerable.Empty<double>()
10171061
};
10181062
}
@@ -1042,6 +1086,37 @@ public HistItem(double value, int categoryIndex, string bin, int total, string g
10421086
}
10431087
}
10441088

1089+
private static IEnumerable<string> SplitAmbiguousNotch(string notch)
1090+
{
1091+
if (string.IsNullOrWhiteSpace(notch))
1092+
return new[] { "0" };
1093+
1094+
return notch.Split('|')
1095+
.Select(p => p.Trim())
1096+
.Where(p => p.Length > 0)
1097+
.DefaultIfEmpty("0");
1098+
}
1099+
1100+
private static IEnumerable<double> ParseAmbiguousNotchValues(string notch)
1101+
{
1102+
foreach (var part in SplitAmbiguousNotch(notch))
1103+
{
1104+
if (double.TryParse(part, NumberStyles.Float, CultureInfo.InvariantCulture, out double value))
1105+
yield return value;
1106+
else
1107+
yield return 0.0;
1108+
}
1109+
}
1110+
1111+
private static string NormalizeAmbiguityLevel(string ambiguityLevel)
1112+
{
1113+
if (string.IsNullOrWhiteSpace(ambiguityLevel))
1114+
return "1";
1115+
1116+
var first = ambiguityLevel.Split('|')[0].Trim();
1117+
return string.IsNullOrEmpty(first) ? "1" : first;
1118+
}
1119+
10451120
/// <summary>
10461121
/// Orders strings numerically if all values are numeric, otherwise alphabetically.
10471122
/// </summary>

0 commit comments

Comments
 (0)