Skip to content

Commit 5a5cad0

Browse files
committed
Merge branch 'master' into precursorFragmentGroup
2 parents 3d08461 + 4b5271e commit 5a5cad0

28 files changed

+971
-172
lines changed

MetaMorpheus/CMD/CMD.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
<PackageReference Include="Microsoft.ML.CpuMath" Version="3.0.1" />
2525
<PackageReference Include="Microsoft.ML.FastTree" Version="3.0.1" />
2626
<PackageReference Include="Microsoft.NETCore.App" Version="2.2.8" />
27-
<PackageReference Include="mzLib" Version="1.0.566" />
27+
<PackageReference Include="mzLib" Version="1.0.569" />
2828
<PackageReference Include="Nett" Version="0.15.0" />
2929
<PackageReference Include="SQLite.Interop.dll" Version="1.0.103" />
3030
<PackageReference Include="System.Data.SQLite" Version="1.0.118" />

MetaMorpheus/EngineLayer/EngineLayer.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
<PackageReference Include="Microsoft.ML.CpuMath" Version="3.0.1" />
3030
<PackageReference Include="Microsoft.ML.FastTree" Version="3.0.1" />
3131
<PackageReference Include="Microsoft.NETCore.App" Version="2.2.8" />
32-
<PackageReference Include="mzLib" Version="1.0.566" />
32+
<PackageReference Include="mzLib" Version="1.0.569" />
3333
<PackageReference Include="NETStandard.Library" Version="2.0.3" />
3434
<PackageReference Include="Nett" Version="0.15.0" />
3535
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />

MetaMorpheus/EngineLayer/Gptmd/GptmdEngine.cs

Lines changed: 93 additions & 97 deletions
Large diffs are not rendered by default.
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
#nullable enable
2+
using System;
3+
using Omics.Fragmentation;
4+
using System.Collections.Generic;
5+
using Omics;
6+
using System.Linq;
7+
using Omics.Modifications;
8+
9+
namespace EngineLayer;
10+
11+
public interface IGptmdFilter
12+
{
13+
public static string GetFilterTypeName(IGptmdFilter filter) => filter.GetType().Name;
14+
15+
bool Passes(
16+
IBioPolymerWithSetMods candidatePeptide,
17+
SpectralMatch psm,
18+
double newScore,
19+
double originalScore,
20+
List<MatchedFragmentIon> matchedIons,
21+
int peptideOneBasedModSite,
22+
int peptideLength,
23+
Modification modAttemptingToAdd);
24+
}
25+
26+
/// <summary>
27+
/// Requires that the new score is greater than the original score.
28+
/// </summary>
29+
public sealed class ImprovedScoreFilter : IGptmdFilter
30+
{
31+
public bool Passes(
32+
IBioPolymerWithSetMods candidatePeptide,
33+
SpectralMatch psm,
34+
double newScore,
35+
double originalScore,
36+
List<MatchedFragmentIon> matchedIons,
37+
int peptideOneBasedModSite,
38+
int peptideLength,
39+
Modification modAttemptingToAdd)
40+
{
41+
return newScore > originalScore;
42+
}
43+
}
44+
45+
/// <summary>
46+
/// Requires the mod site to be covered by at least one N-terminal and one C-terminal ion.
47+
/// That is, ions from both directions must include the mod, even if not flanking it.
48+
/// </summary>
49+
public sealed class DualDirectionalIonCoverageFilter : IGptmdFilter
50+
{
51+
public bool Passes(
52+
IBioPolymerWithSetMods candidatePeptide,
53+
SpectralMatch psm,
54+
double newScore,
55+
double originalScore,
56+
List<MatchedFragmentIon> matchedIons,
57+
int peptideOneBasedModSite,
58+
int peptideLength,
59+
Modification modAttemptingToAdd)
60+
{
61+
if (matchedIons == null || matchedIons.Count == 0)
62+
return false;
63+
64+
int site = peptideOneBasedModSite;
65+
66+
bool coveredFromNTerm = matchedIons.Any(m =>
67+
m.NeutralTheoreticalProduct.ProductType == ProductType.M ||
68+
(m.NeutralTheoreticalProduct.Terminus is FragmentationTerminus.N or FragmentationTerminus.FivePrime &&
69+
m.NeutralTheoreticalProduct.ResiduePosition >= site)
70+
);
71+
72+
bool coveredFromCTerm = matchedIons.Any(m =>
73+
m.NeutralTheoreticalProduct.ProductType == ProductType.M ||
74+
(m.NeutralTheoreticalProduct.Terminus is FragmentationTerminus.C or FragmentationTerminus.ThreePrime &&
75+
m.NeutralTheoreticalProduct.ResiduePosition < site)
76+
);
77+
78+
if (modAttemptingToAdd.LocationRestriction.Contains("terminal", StringComparison.InvariantCultureIgnoreCase))
79+
return coveredFromCTerm || coveredFromNTerm;
80+
81+
return coveredFromNTerm && coveredFromCTerm;
82+
}
83+
}
84+
85+
/// <summary>
86+
/// Requires the mod site to be covered by at least one N-terminal or one C-terminal ion.
87+
/// That is, ions from one direction must include the mod, even if not flanking it.
88+
/// </summary>
89+
public sealed class UniDirectionalIonCoverageFilter : IGptmdFilter
90+
{
91+
public bool Passes(
92+
IBioPolymerWithSetMods candidatePeptide,
93+
SpectralMatch psm,
94+
double newScore,
95+
double originalScore,
96+
List<MatchedFragmentIon> matchedIons,
97+
int peptideOneBasedModSite,
98+
int peptideLength,
99+
Modification modAttemptingToAdd)
100+
{
101+
if (matchedIons == null || matchedIons.Count == 0)
102+
return false;
103+
104+
int site = peptideOneBasedModSite;
105+
106+
bool coveredFromNTerm = matchedIons.Any(m =>
107+
m.NeutralTheoreticalProduct.ProductType == ProductType.M ||
108+
(m.NeutralTheoreticalProduct.Terminus is FragmentationTerminus.N or FragmentationTerminus.FivePrime &&
109+
m.NeutralTheoreticalProduct.ResiduePosition >= site)
110+
);
111+
112+
bool coveredFromCTerm = matchedIons.Any(m =>
113+
m.NeutralTheoreticalProduct.ProductType == ProductType.M ||
114+
(m.NeutralTheoreticalProduct.Terminus is FragmentationTerminus.C or FragmentationTerminus.ThreePrime &&
115+
m.NeutralTheoreticalProduct.ResiduePosition < site)
116+
);
117+
118+
return coveredFromNTerm || coveredFromCTerm;
119+
}
120+
}
121+
122+
/// <summary>
123+
/// Requires flanking ions — a fragment from *before* and one from *after* the mod site,
124+
/// regardless of fragmentation direction.
125+
/// </summary>
126+
public sealed class FlankingIonCoverageFilter : IGptmdFilter
127+
{
128+
public bool Passes(
129+
IBioPolymerWithSetMods candidatePeptide,
130+
SpectralMatch psm,
131+
double newScore,
132+
double originalScore,
133+
List<MatchedFragmentIon> matchedIons,
134+
int peptideOneBasedModSite,
135+
int peptideLength,
136+
Modification modAttemptingToAdd)
137+
{
138+
if (matchedIons == null || matchedIons.Count == 0)
139+
return false;
140+
141+
int site = peptideOneBasedModSite;
142+
143+
bool leftFlank = matchedIons.Any(m =>
144+
m.NeutralTheoreticalProduct.ResiduePosition == site - 1);
145+
146+
bool rightFlank = matchedIons.Any(m =>
147+
m.NeutralTheoreticalProduct.ResiduePosition == site);
148+
149+
if (modAttemptingToAdd.LocationRestriction.Contains("terminal", StringComparison.InvariantCultureIgnoreCase))
150+
return leftFlank || rightFlank;
151+
152+
return leftFlank && rightFlank;
153+
}
154+
}
155+

MetaMorpheus/EngineLayer/NonSpecificEnzymeSearch/NonSpecificEnzymeSearchEngine.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ private Tuple<int, PeptideWithSetModifications> Accepts(List<Product> fragments,
421421
//add the terminal mod
422422
if (fragmentationTerminus == FragmentationTerminus.N)
423423
{
424-
updatedMods[peptide.OneBasedEndResidue] = terminalMod;
424+
updatedMods[peptide.OneBasedEndResidue + 1] = terminalMod;
425425
}
426426
else
427427
{

MetaMorpheus/GUI/GUI.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
<PackageReference Include="Microsoft.ML.CpuMath" Version="3.0.1" />
6363
<PackageReference Include="Microsoft.ML.FastTree" Version="3.0.1" />
6464
<PackageReference Include="Microsoft.NETCore.App" Version="2.2.8" />
65-
<PackageReference Include="mzLib" Version="1.0.566" />
65+
<PackageReference Include="mzLib" Version="1.0.569" />
6666
<PackageReference Include="Nett" Version="0.15.0" />
6767
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
6868
<PackageReference Include="OxyPlot.Core" Version="2.0.0" />

MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,21 @@
441441
</TextBox.Style>
442442
</TextBox>
443443
</StackPanel>
444-
<StackPanel Grid.Column="0" Grid.Row="2">
444+
<GroupBox Grid.Column="1" Grid.Row="1" Header="G-PTM-D Filter Stringency" Margin="0,-10,0,24">
445+
<ListBox x:Name="FilterOptionsListBox" ItemsSource="{Binding FilterOptions}" SelectionMode="Multiple"
446+
Margin="0,0,0,0" Padding="0" BorderThickness="0">
447+
<ListBox.ItemTemplate>
448+
<DataTemplate>
449+
<StackPanel Orientation="Horizontal" Margin="0,0,0,0" VerticalAlignment="Center"
450+
ToolTip="{Binding Summary}">
451+
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}" VerticalAlignment="Center"/>
452+
<TextBlock Text="{Binding Name}" Margin="8,0,0,0" VerticalAlignment="Center"/>
453+
</StackPanel>
454+
</DataTemplate>
455+
</ListBox.ItemTemplate>
456+
</ListBox>
457+
</GroupBox>
458+
<StackPanel Grid.Column="0" Grid.Row="1">
445459
<TreeView x:Name="gptmdModsTreeView" ItemsSource="{Binding}" DataContext="{x:Type guiFunctions:ModTypeForTreeViewModel}" Height="400">
446460
<TreeView.Resources>
447461
<HierarchicalDataTemplate DataType="{x:Type guiFunctions:ModTypeForTreeViewModel}" ItemsSource="{Binding Children}">

MetaMorpheus/GUI/TaskWindows/GPTMDTaskWindow.xaml.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
using System.Windows.Input;
1616
using TaskLayer;
1717
using GuiFunctions;
18+
using EngineLayer;
1819

1920
namespace MetaMorpheusGUI
2021
{
@@ -23,6 +24,7 @@ namespace MetaMorpheusGUI
2324
/// </summary>
2425
public partial class GptmdTaskWindow : Window
2526
{
27+
public ObservableCollection<GptmdFilterViewModel> FilterOptions { get; } = new();
2628
private readonly ObservableCollection<ModTypeForTreeViewModel> FixedModTypeForTreeViewObservableCollection = new ObservableCollection<ModTypeForTreeViewModel>();
2729
private readonly ObservableCollection<ModTypeForTreeViewModel> VariableModTypeForTreeViewObservableCollection = new ObservableCollection<ModTypeForTreeViewModel>();
2830
private readonly ObservableCollection<ModTypeForLoc> LocalizeModTypeForTreeViewObservableCollection = new ObservableCollection<ModTypeForLoc>();
@@ -38,6 +40,7 @@ public GptmdTaskWindow(GptmdTask myGPTMDtask)
3840

3941
AutomaticallyAskAndOrUpdateParametersBasedOnProtease = false;
4042
PopulateChoices();
43+
FilterOptionsListBox.ItemsSource = FilterOptions;
4144
UpdateFieldsFromTask(TheTask);
4245
AutomaticallyAskAndOrUpdateParametersBasedOnProtease = true;
4346
DeisotopingControl.DataContext = DeconHostViewModel;
@@ -183,6 +186,11 @@ private void UpdateFieldsFromTask(GptmdTask task)
183186
{
184187
ye.VerifyCheckState();
185188
}
189+
190+
foreach (var filter in FilterOptions)
191+
{
192+
filter.IsSelected = TheTask.GptmdParameters.GptmdFilters.Any(f => f.GetType() == filter.Filter.GetType());
193+
}
186194
}
187195

188196
private void PopulateChoices()
@@ -240,6 +248,28 @@ private void PopulateChoices()
240248
}
241249
}
242250
gptmdModsTreeView.DataContext = GptmdModTypeForTreeViewObservableCollection;
251+
252+
FilterOptions.Clear();
253+
FilterOptions.Add(new GptmdFilterViewModel(
254+
new ImprovedScoreFilter(),
255+
"Improved Score",
256+
"Requires that the new score is greater than the original score."
257+
));
258+
FilterOptions.Add(new GptmdFilterViewModel(
259+
new DualDirectionalIonCoverageFilter(),
260+
"Dual Directional Ion Coverage",
261+
"Requires the mod site to be covered by at least one N-terminal and one C-terminal ion. That is, ions from both directions must include the mod, even if not flanking it."
262+
));
263+
FilterOptions.Add(new GptmdFilterViewModel(
264+
new UniDirectionalIonCoverageFilter(),
265+
"Uni-Directional Ion Coverage",
266+
"Requires the mod site to be covered by at least one N-terminal or one C-terminal ion. That is, ions from one direction must include the mod, even if not flanking it."
267+
));
268+
FilterOptions.Add(new GptmdFilterViewModel(
269+
new FlankingIonCoverageFilter(),
270+
"Flanking Ion Coverage",
271+
"Requires flanking ions — a fragment from *before* and one from *after* the mod site, regardless of fragmentation direction."
272+
));
243273
}
244274

245275
private void CancelButton_Click(object sender, RoutedEventArgs e)
@@ -489,6 +519,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
489519
{
490520
TheTask.GptmdParameters.ListOfModsGptmd.AddRange(heh.Children.Where(b => b.Use).Select(b => (b.Parent.DisplayName, b.ModName)));
491521
}
522+
TheTask.GptmdParameters.GptmdFilters = FilterOptions.Where(f => f.IsSelected).Select(f => f.Filter).ToList();
492523

493524
TheTask.CommonParameters = commonParamsToSave;
494525

MetaMorpheus/GuiFunctions/GuiFunctions.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<ItemGroup>
1717
<PackageReference Include="itext7" Version="8.0.5" />
1818
<PackageReference Include="itext7.bouncy-castle-adapter" Version="8.0.5" />
19-
<PackageReference Include="mzLib" Version="1.0.566" />
19+
<PackageReference Include="mzLib" Version="1.0.569" />
2020
<PackageReference Include="OxyPlot.Wpf" Version="2.0.0" />
2121
<PackageReference Include="Svg" Version="3.4.7" />
2222
</ItemGroup>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using EngineLayer;
2+
3+
namespace GuiFunctions;
4+
5+
public class GptmdFilterViewModel : BaseViewModel
6+
{
7+
private bool _isSelected = false;
8+
public IGptmdFilter Filter { get; }
9+
public string Name { get; }
10+
public string Summary { get; }
11+
12+
public bool IsSelected
13+
{
14+
get => _isSelected;
15+
set { _isSelected = value; OnPropertyChanged(nameof(IsSelected)); }
16+
}
17+
18+
public GptmdFilterViewModel(IGptmdFilter filter, string name, string summary, bool isSelected = true)
19+
{
20+
Filter = filter;
21+
Name = name;
22+
Summary = summary;
23+
_isSelected = isSelected;
24+
}
25+
}

0 commit comments

Comments
 (0)