Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only quantify peptides that clear the q-value threshold #2375

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
4 changes: 4 additions & 0 deletions MetaMorpheus/EngineLayer/FdrAnalysis/FdrAnalysisEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ private void AddPsmAndPeptideFdrInfoIfNotPresent()
foreach (var psm in AllPsms.Where(p => p.PeptideFdrInfo == null))
{
psm.PeptideFdrInfo = new FdrInfo();
// If peptide level Q-values default to zero, it is hard to determine which PSMs have a legitimate peptide-level Q-value of zero and
// which just weren't included in peptide-level calculations. Hence, we set q values to one here.
psm.PeptideFdrInfo.QValue = 1;
psm.PeptideFdrInfo.PEP_QValue = 1;
}
Copy link
Contributor

@nbollis nbollis Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we instead default the value to -1 or 1 to make it more clear from instantiation instead of within this method?

}

Expand Down
18 changes: 18 additions & 0 deletions MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,24 @@
<ToolTip Content="Use peptide sequences shared between proteins for protein quantification" ToolTipService.ShowDuration="999999" ToolTipService.InitialShowDelay="500" />
</ToolTipService.ToolTip>
</CheckBox>
<CheckBox x:Name="CheckBoxOnlyQuantifyConfidentPeptides" Content="Only quantify confident peptides" ToolTipService.ShowDuration="999999" ToolTipService.InitialShowDelay="500">
<CheckBox.IsEnabled>
<MultiBinding Converter="{StaticResource boolOrConverter}">
<Binding ElementName="CheckBoxLFQ" Path ="IsChecked"/>
<Binding ElementName="CheckBoxLFQwSpectralRecovery" Path ="IsChecked"/>
</MultiBinding>
</CheckBox.IsEnabled>
<CheckBox.Visibility>
<MultiBinding Converter="{StaticResource boolOr2VisConverter}">
<Binding ElementName="CheckBoxLFQ" Path ="IsChecked"/>
<Binding ElementName="CheckBoxLFQwSpectralRecovery" Path ="IsChecked"/>
</MultiBinding>
</CheckBox.Visibility>
<ToolTipService.ToolTip>
<ToolTip Content="Only quantify peptides that meet the Q-Value or PEP Q-Value threshold.&#x0a;Unchecking this option results in low-confidence peptides being reported in the AllQuantifiedPeptides output" ToolTipService.ShowDuration="999999" ToolTipService.InitialShowDelay="500" />
</ToolTipService.ToolTip>
</CheckBox>


<!-- Multiplex Options -->
<StackPanel Orientation="Horizontal" Margin="5 5 5 0" Grid.Column="0" Grid.Row="0">
Expand Down
2 changes: 2 additions & 0 deletions MetaMorpheus/GUI/TaskWindows/SearchTaskWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ private void UpdateFieldsFromTask(SearchTask task)
CheckBoxNoQuant.IsChecked = !task.SearchParameters.DoLabelFreeQuantification;
CheckBoxLFQ.IsChecked = task.SearchParameters.DoLabelFreeQuantification;
CheckBoxUseSharedPeptidesForQuant.IsChecked = task.SearchParameters.UseSharedPeptidesForLFQ;
CheckBoxOnlyQuantifyConfidentPeptides.IsChecked = task.SearchParameters.OnlyQuantifyConfidentPeptides;
CheckBoxMultiplex.IsChecked = task.SearchParameters.DoMultiplexQuantification;
MultiplexComboBox.SelectedItem = task.SearchParameters.MultiplexModId ?? _defaultMultiplexType;
// If Spectral Recovery is enabled
Expand Down Expand Up @@ -628,6 +629,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
TheTask.SearchParameters.NoOneHitWonders = CheckBoxNoOneHitWonders.IsChecked.Value;
TheTask.SearchParameters.DoLabelFreeQuantification = !CheckBoxNoQuant.IsChecked.Value;
TheTask.SearchParameters.UseSharedPeptidesForLFQ = CheckBoxUseSharedPeptidesForQuant.IsChecked.Value;
TheTask.SearchParameters.OnlyQuantifyConfidentPeptides = CheckBoxOnlyQuantifyConfidentPeptides.IsChecked.Value;
TheTask.SearchParameters.DoSpectralRecovery = CheckBoxLFQwSpectralRecovery.IsChecked.Value;
TheTask.SearchParameters.DoMultiplexQuantification = CheckBoxMultiplex.IsChecked.Value;
TheTask.SearchParameters.MultiplexModId = (string)MultiplexComboBox.SelectedItem;
Expand Down
2 changes: 1 addition & 1 deletion MetaMorpheus/TaskLayer/FilteredPsms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static FilteredPsms Filter(IEnumerable<SpectralMatch> psms,
pepQValueThreshold ??= commonParams.PepQValueThreshold;
double filterThreshold = Math.Min((double)qValueThreshold, (double)pepQValueThreshold);
bool filteringNotPerformed = false;
List<SpectralMatch> filteredPsms = new List<SpectralMatch>();
List<SpectralMatch> filteredPsms = new();

// set the filter type
FilterType filterType = FilterType.QValue;
Expand Down
20 changes: 18 additions & 2 deletions MetaMorpheus/TaskLayer/SearchTask/PostSearchAnalysisTask.cs
Original file line number Diff line number Diff line change
Expand Up @@ -501,16 +501,32 @@ private void QuantificationAnalysis()
}
}

// Determine if only select, high confidence peptides will be used for quant
List<string> peptideSequencesForQuantification = null;
if (Parameters.SearchParameters.SilacLabels == null && Parameters.SearchParameters.OnlyQuantifyConfidentPeptides)
{
peptideSequencesForQuantification = FilteredPsms.Filter(Parameters.AllPsms,
CommonParameters,
includeDecoys: false,
includeContaminants: true,
includeAmbiguous: false,
includeAmbiguousMods: false,
includeHighQValuePsms: false,
filterAtPeptideLevel: true)
.Select(pep => pep.FullSequence).Distinct().ToList();
nbollis marked this conversation as resolved.
Show resolved Hide resolved
}

// run FlashLFQ
var flashLfqEngine = new FlashLfqEngine(
var flashLfqEngine = new FlashLfqEngine(
allIdentifications: flashLFQIdentifications,
normalize: Parameters.SearchParameters.Normalize,
ppmTolerance: Parameters.SearchParameters.QuantifyPpmTol,
matchBetweenRunsPpmTolerance: Parameters.SearchParameters.QuantifyPpmTol, // If these tolerances are not equivalent, then MBR will falsely classify peptides found in the initial search as MBR peaks
matchBetweenRuns: Parameters.SearchParameters.MatchBetweenRuns,
useSharedPeptidesForProteinQuant: Parameters.SearchParameters.UseSharedPeptidesForLFQ,
silent: true,
maxThreads: CommonParameters.MaxThreadsToUsePerFile);
maxThreads: CommonParameters.MaxThreadsToUsePerFile,
peptideSequencesToUse: peptideSequencesForQuantification);

if (flashLFQIdentifications.Any())
{
Expand Down
2 changes: 2 additions & 0 deletions MetaMorpheus/TaskLayer/SearchTask/SearchParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public SearchParameters()
ModPeptidesAreDifferent = false;
DoLabelFreeQuantification = true;
UseSharedPeptidesForLFQ = false;
OnlyQuantifyConfidentPeptides = true;
DoSpectralRecovery = false;
QuantifyPpmTol = 5;
SearchTarget = true;
Expand Down Expand Up @@ -69,6 +70,7 @@ public SearchParameters()
public bool MatchBetweenRuns { get; set; }
public bool Normalize { get; set; }
public double QuantifyPpmTol { get; set; }
public bool OnlyQuantifyConfidentPeptides { get; set; }
public bool DoHistogramAnalysis { get; set; }
public bool SearchTarget { get; set; }
public DecoyType DecoyType { get; set; }
Expand Down
1 change: 1 addition & 0 deletions MetaMorpheus/Test/EverythingRunnerEngineTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ static EverythingRunnerEngineTestCase()
@"TestData\TaGe_SA_A549_3_snip_2.mzML");
string myDatabase = Path.Combine(TestContext.CurrentContext.TestDirectory,
@"TestData\TaGe_SA_A549_3_snip.fasta");
searchTaskLoaded.SearchParameters.OnlyQuantifyConfidentPeptides = true;
_cases.Add(EverythingRunnerEngineTestCases.BottomUpQValue,
new EverythingRunnerEngineTestCase(EverythingRunnerEngineTestCases.BottomUpQValue,
new List<(string, MetaMorpheusTask)> { ("postSearchAnalysisTaskTestOutput", searchTaskLoaded) },
Expand Down
30 changes: 15 additions & 15 deletions MetaMorpheus/Test/FdrTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,19 +96,19 @@ public static void FdrTestMethod()
fdr.Run();

Assert.AreEqual(2, searchModes.NumNotches);
Assert.AreEqual(0, newPsms[0].FdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[0].FdrInfo.CumulativeTargetNotch);
Assert.AreEqual(0, newPsms[1].FdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[1].FdrInfo.CumulativeTargetNotch);
Assert.AreEqual(0, newPsms[2].FdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[2].FdrInfo.CumulativeTargetNotch);

Assert.AreEqual(0, newPsms[0].FdrInfo.CumulativeDecoy);
Assert.AreEqual(1, newPsms[0].FdrInfo.CumulativeTarget);
Assert.AreEqual(0, newPsms[1].FdrInfo.CumulativeDecoy);
Assert.AreEqual(2, newPsms[1].FdrInfo.CumulativeTarget);
Assert.AreEqual(0, newPsms[2].FdrInfo.CumulativeDecoy);
Assert.AreEqual(3, newPsms[2].FdrInfo.CumulativeTarget);
Assert.AreEqual(0, newPsms[0].PsmFdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[0].PsmFdrInfo.CumulativeTargetNotch);
Assert.AreEqual(0, newPsms[1].PsmFdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[1].PsmFdrInfo.CumulativeTargetNotch);
Assert.AreEqual(0, newPsms[2].PsmFdrInfo.CumulativeDecoyNotch);
Assert.AreEqual(1, newPsms[2].PsmFdrInfo.CumulativeTargetNotch);

Assert.AreEqual(0, newPsms[0].PsmFdrInfo.CumulativeDecoy);
Assert.AreEqual(1, newPsms[0].PsmFdrInfo.CumulativeTarget);
Assert.AreEqual(0, newPsms[1].PsmFdrInfo.CumulativeDecoy);
Assert.AreEqual(2, newPsms[1].PsmFdrInfo.CumulativeTarget);
Assert.AreEqual(0, newPsms[2].PsmFdrInfo.CumulativeDecoy);
Assert.AreEqual(3, newPsms[2].PsmFdrInfo.CumulativeTarget);
}

[Test]
Expand Down Expand Up @@ -266,7 +266,7 @@ public static void TestComputePEPValue()

foreach (var item in allPsmsArray.Where(p => p != null))
{
var b = item.FdrInfo.PEP;
var b = item.PsmFdrInfo.PEP;
if (b >= 0.5)
{
trueCount++;
Expand Down Expand Up @@ -349,7 +349,7 @@ public static void TestComputePEPValue()

foreach (var item in psmCopyForCZETest.Where(p => p != null))
{
var b = item.FdrInfo.PEP;
var b = item.PsmFdrInfo.PEP;
if (b >= 0.5)
{
trueCount++;
Expand Down
2 changes: 1 addition & 1 deletion MetaMorpheus/Test/MultiProteaseParsimonyTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ public static void TestPSMFdrFiltering_Simulated()
var fdrFilteredPsms = new List<SpectralMatch>();
foreach (SpectralMatch psm in psms)
{
if (psm != null && psm.FdrInfo.QValue <= 0.0100 && psm.FdrInfo.QValueNotch <= 0.0100)
if (psm != null && psm.PsmFdrInfo.QValue <= 0.0100 && psm.PsmFdrInfo.QValueNotch <= 0.0100)
{
fdrFilteredPsms.Add(psm);
}
Expand Down
10 changes: 10 additions & 0 deletions MetaMorpheus/Test/PostSearchAnalysisTaskTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,16 @@ public static void AllResultsAndResultsTxtContainsCorrectValues_PepQValue_Bottom
Assert.AreEqual("TaGe_SA_A549_3_snip_2 - Target protein groups within 1 % FDR: 140", results[15]);
}

[Test]
public static void TestPeptideQuantificationResults()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test seems subject to break in the future due to the hard coded number. Could you instead read in the peptides file, count the results at threshold, then use that in your assert?

{
EverythingRunnerEngineTestCase.TryGetTestCase(EverythingRunnerEngineTestCases.BottomUpQValue, out var testCase);

string peptideQuantFile = Path.Combine(testCase.OutputDirectory, @"postSearchAnalysisTaskTestOutput\AllQuantifiedPeptides.tsv");
string[] peptideQuant = File.ReadAllLines(peptideQuantFile);
Assert.AreEqual(175, peptideQuant.Length); // 174 peptides + header. Make sure that we're quantifying only those peptides with q-value <= 0.01
}

/// <summary>
/// Ensures that there is the proper ratio of summary and individual lines in the result.txt file and that peptides and proteoforms are distinct
/// </summary>
Expand Down
8 changes: 4 additions & 4 deletions MetaMorpheus/Test/SearchEngineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -553,13 +553,13 @@ public static void TestModernSearchEngineLowResOneRealSpectrum()
// Single search mode
Assert.AreEqual(12, allPsmsArray.Length);

var goodPsm = nonNullPsms.Where(p => p.FdrInfo.QValue <= 0.01).ToList();
var goodPsm = nonNullPsms.Where(p => p.PsmFdrInfo.QValue <= 0.01).ToList();

var myMatchedIons = goodPsm[0].MatchedFragmentIons;

Assert.AreEqual(47, myMatchedIons.Count());

var goodScore = nonNullPsms.Where(p => p.FdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();
var goodScore = nonNullPsms.Where(p => p.PsmFdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();
goodScore.Sort();
Assert.AreEqual(2, goodPsm.Count());
}
Expand Down Expand Up @@ -656,7 +656,7 @@ public static void TestClassicSearchEngineLowResSimple()
// Single search mode
Assert.AreEqual(535, allPsmsArray.Length);

var goodScore = nonNullPsms.Where(p => p.FdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();
var goodScore = nonNullPsms.Where(p => p.PsmFdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();

Assert.AreEqual(181, goodScore.Count());
Directory.Delete(outputFolder, true);
Expand Down Expand Up @@ -748,7 +748,7 @@ public static void TestModernSearchEngineLowResSimple()
// Single search mode
Assert.AreEqual(535, allPsmsArray.Length);

var goodScore = nonNullPsms.Where(p => p.FdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();
var goodScore = nonNullPsms.Where(p => p.PsmFdrInfo.QValue <= 0.01).Select(s => s.Score).ToList();

Assert.AreEqual(181, goodScore.Count());
}
Expand Down
6 changes: 2 additions & 4 deletions MetaMorpheus/Test/SpectralRecoveryTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,8 @@ public static void SpectralRecoveryPostSearchAnalysisTest()
List<PsmFromTsv> matches02ng = mbrPsms.Where(p => p.FileNameWithoutExtension == "K13_02ng_1min_frac1").ToList();
List<string> expectedMatches = mbrPsms.Select(p => p.BaseSeq).Intersect(expectedMbrPsms.Select(p => p.BaseSeq).ToList()).ToList();

// Changing Q-value calculation methods results in more PSMs being discovered, and so fewer spectra are available to be "recovered"
// (as they were identified in the orignal search)
Assert.That(matches2ng.Count >= 3);
Assert.That(matches02ng.Count >= 10);
Assert.That(matches2ng.Count >= 2);
Assert.That(matches02ng.Count >= 7); // AS: 6/17/24 - Fewer quantification events (8 -> 7) because one of the peptides doesn't clear peptide level FDR threshold
Assert.That(expectedMatches.Count >= 2); // FlashLFQ doesn't find all 6 expected peaks, only 3. MbrAnalysis finds these three peaks

//TODO: Add test for recovering fdrInfo from original. Currently, PsmTsvReader doesn't support the new columns, so it's hard to test
Expand Down
6 changes: 6 additions & 0 deletions MetaMorpheus/Test/Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,12 @@
<None Update="TestData\oneEmptyEntry.fa">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestData\PostSearchAnalysisTaskTestData\TaGe_SA_A549_3_snip.mzML">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestData\PostSearchAnalysisTaskTestData\TaGe_SA_A549_3_snip_2.mzML">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="TestData\PrunedDbSpectra.mzml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
2 changes: 1 addition & 1 deletion MetaMorpheus/Test/TestData/Task1-SearchTaskconfig.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ MassDiffAcceptorType = "Exact"
WritePrunedDatabase = false
KeepAllUniprotMods = true
DoLocalizationAnalysis = true
DoQuantification = false
DoQuantification = true
SearchType = "Classic"
LocalFdrCategories = ["FullySpecific"]
MaxFragmentSize = 30000.0
Expand Down
2 changes: 1 addition & 1 deletion MetaMorpheus/Test/TestPsm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ public static void TestPsmMatchingToTargetAndDecoyWithDifferentSequences()
List<(string fileName, CommonParameters fileSpecificParameters)> fsp = new List<(string fileName, CommonParameters fileSpecificParameters)> { ("filename", commonParameters) };

new FdrAnalysisEngine(new List<SpectralMatch> { psm }, 1, new CommonParameters(), fsp, new List<string>()).Run();
Assert.AreEqual(0.5, psm.FdrInfo.CumulativeDecoy);
Assert.AreEqual(0.5, psm.PsmFdrInfo.CumulativeDecoy);
}

[Test]
Expand Down
7 changes: 4 additions & 3 deletions MetaMorpheus/Test/XLTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,8 @@ public static void XlTest_MoreComprehensive()

var xlSearchParameters = new XlSearchParameters
{
CrosslinkAtCleavageSite = true
CrosslinkAtCleavageSite = true,
WritePepXml = true
};

//Create databases contain two protein.
Expand Down Expand Up @@ -579,7 +580,7 @@ public static void XlTest_MoreComprehensive()
deadendNH2 = 0;
deadendTris = 0;

foreach (CrosslinkSpectralMatch csm in firstCsmsFromListsOfCsms.Where(c => c.FdrInfo.QValue <= 0.01).ToList())
foreach (CrosslinkSpectralMatch csm in firstCsmsFromListsOfCsms.Where(c => c.PsmFdrInfo.QValue <= 0.01).ToList())
{
switch (csm.CrossType)
{
Expand Down Expand Up @@ -776,7 +777,7 @@ public static void XlTest_MoreComprehensive()
deadendNH2 = 0;
deadendTris = 0;

foreach (CrosslinkSpectralMatch csm in firstCsmsFromListsOfCsms.Where(c => c.FdrInfo.QValue <= 0.01).ToList())
foreach (CrosslinkSpectralMatch csm in firstCsmsFromListsOfCsms.Where(c => c.PsmFdrInfo.QValue <= 0.01).ToList())
{
switch (csm.CrossType)
{
Expand Down
Loading