diff --git a/CMD/CMD.csproj b/CMD/CMD.csproj
index fe7829cec..eb818e068 100644
--- a/CMD/CMD.csproj
+++ b/CMD/CMD.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/Dockerfile b/Dockerfile
index 408506c37..3b1eda923 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -11,4 +11,4 @@ RUN apk add --no-cache bash
RUN apk add --no-cache procps
## Set the entrypoint of the Docker image to CMD.dll
-ENTRYPOINT ["dotnet", "/metamorpheus/CMD.dll"]
+ENTRYPOINT ["dotnet", "/metamorpheus/CMD.dll"]
\ No newline at end of file
diff --git a/Dockerfile_WindowsInstaller b/Dockerfile_WindowsInstaller
index 893a68480..dcb4688d8 100644
--- a/Dockerfile_WindowsInstaller
+++ b/Dockerfile_WindowsInstaller
@@ -5,4 +5,4 @@ FROM mcr.microsoft.com/dotnet/runtime:5.0-nanoserver-1809
ADD /InstalledFiles/ /metamorpheus/
## Set the entrypoint of the Docker image to CMD.exe
-ENTRYPOINT ["/metamorpheus/CMD.exe"]
+ENTRYPOINT ["/metamorpheus/CMD.exe"]
\ No newline at end of file
diff --git a/EngineLayer/ClassicSearch/ClassicSearchEngine.cs b/EngineLayer/ClassicSearch/ClassicSearchEngine.cs
index 2eee0740e..2bdd0cf29 100644
--- a/EngineLayer/ClassicSearch/ClassicSearchEngine.cs
+++ b/EngineLayer/ClassicSearch/ClassicSearchEngine.cs
@@ -22,11 +22,12 @@ public class ClassicSearchEngine : MetaMorpheusEngine
private readonly PeptideSpectralMatch[] PeptideSpectralMatches;
private readonly Ms2ScanWithSpecificMass[] ArrayOfSortedMS2Scans;
private readonly double[] MyScanPrecursorMasses;
+ private readonly bool WriteSpectralLibrary;
public ClassicSearchEngine(PeptideSpectralMatch[] globalPsms, Ms2ScanWithSpecificMass[] arrayOfSortedMS2Scans,
List variableModifications, List fixedModifications, List silacLabels, SilacLabel startLabel, SilacLabel endLabel,
List proteinList, MassDiffAcceptor searchMode, CommonParameters commonParameters, List<(string FileName, CommonParameters Parameters)> fileSpecificParameters,
- SpectralLibrary spectralLibrary, List nestedIds)
+ SpectralLibrary spectralLibrary, List nestedIds, bool writeSpectralLibrary)
: base(commonParameters, fileSpecificParameters, nestedIds)
{
PeptideSpectralMatches = globalPsms;
@@ -39,9 +40,16 @@ public ClassicSearchEngine(PeptideSpectralMatch[] globalPsms, Ms2ScanWithSpecifi
{
TurnoverLabels = (startLabel, endLabel);
}
- Proteins = proteinList;
+
SearchMode = searchMode;
SpectralLibrary = spectralLibrary;
+ WriteSpectralLibrary = writeSpectralLibrary;
+
+ // if we're doing a spectral library search, we can skip the reverse protein decoys generated by metamorpheus.
+ // we will generate reverse peptide decoys w/ in the code just below this (and calculate spectral angles for them later).
+ // we have to generate the reverse peptides instead of the usual reverse proteins because we generate decoy spectral
+ // library spectra from their corresponding paired target peptides
+ Proteins = spectralLibrary == null ? proteinList : proteinList.Where(p => !p.IsDecoy).ToList();
}
protected override MetaMorpheusEngineResults RunSpecific()
@@ -66,19 +74,22 @@ protected override MetaMorpheusEngineResults RunSpecific()
int[] threads = Enumerable.Range(0, maxThreadsPerFile).ToArray();
Parallel.ForEach(threads, (i) =>
{
- var fragmentsForDissociationTypes = new Dictionary>();
+ var targetFragmentsForEachDissociationType = new Dictionary>();
+ var decoyFragmentsForEachDissociationType = new Dictionary>();
// check if we're supposed to autodetect dissociation type from the scan header or not
if (CommonParameters.DissociationType == DissociationType.Autodetect)
{
foreach (var item in GlobalVariables.AllSupportedDissociationTypes.Where(p => p.Value != DissociationType.Autodetect))
{
- fragmentsForDissociationTypes.Add(item.Value, new List());
+ targetFragmentsForEachDissociationType.Add(item.Value, new List());
+ decoyFragmentsForEachDissociationType.Add(item.Value, new List());
}
}
else
{
- fragmentsForDissociationTypes.Add(CommonParameters.DissociationType, new List());
+ targetFragmentsForEachDissociationType.Add(CommonParameters.DissociationType, new List());
+ decoyFragmentsForEachDissociationType.Add(CommonParameters.DissociationType, new List());
}
for (; i < Proteins.Count; i += maxThreadsPerFile)
@@ -89,22 +100,28 @@ protected override MetaMorpheusEngineResults RunSpecific()
// digest each protein into peptides and search for each peptide in all spectra within precursor mass tolerance
foreach (PeptideWithSetModifications peptide in Proteins[i].Digest(CommonParameters.DigestionParams, FixedModifications, VariableModifications, SilacLabels, TurnoverLabels))
{
- foreach (var fragmentSet in fragmentsForDissociationTypes)
+ PeptideWithSetModifications reversedOnTheFlyDecoy = null;
+
+ if (SpectralLibrary != null)
+ {
+ int[] newAAlocations = new int[peptide.BaseSequence.Length];
+ reversedOnTheFlyDecoy = peptide.GetReverseDecoyFromTarget(newAAlocations);
+ }
+
+ // clear fragments from the last peptide
+ foreach (var fragmentSet in targetFragmentsForEachDissociationType)
{
fragmentSet.Value.Clear();
+ decoyFragmentsForEachDissociationType[fragmentSet.Key].Clear();
}
+ // score each scan that has an acceptable precursor mass
foreach (ScanWithIndexAndNotchInfo scan in GetAcceptableScans(peptide.MonoisotopicMass, SearchMode))
{
- if (SpectralLibrary != null && !SpectralLibrary.ContainsSpectrum(peptide.FullSequence, scan.TheScan.PrecursorCharge))
- {
- continue;
- }
-
var dissociationType = CommonParameters.DissociationType == DissociationType.Autodetect ?
scan.TheScan.TheScan.DissociationType.Value : CommonParameters.DissociationType;
- if (!fragmentsForDissociationTypes.TryGetValue(dissociationType, out var peptideTheorProducts))
+ if (!targetFragmentsForEachDissociationType.TryGetValue(dissociationType, out var peptideTheorProducts))
{
//TODO: print some kind of warning here. the scan header dissociation type was unknown
continue;
@@ -116,32 +133,19 @@ protected override MetaMorpheusEngineResults RunSpecific()
peptide.Fragment(dissociationType, CommonParameters.DigestionParams.FragmentationTerminus, peptideTheorProducts);
}
- List matchedIons = MatchFragmentIons(scan.TheScan, peptideTheorProducts, CommonParameters);
+ // match theoretical target ions to spectrum
+ List matchedIons = MatchFragmentIons(scan.TheScan, peptideTheorProducts, CommonParameters,
+ matchAllCharges: WriteSpectralLibrary);
- double thisScore = CalculatePeptideScore(scan.TheScan.TheScan, matchedIons);
- bool meetsScoreCutoff = thisScore >= CommonParameters.ScoreCutoff;
+ // calculate the peptide's score
+ double thisScore = CalculatePeptideScore(scan.TheScan.TheScan, matchedIons, fragmentsCanHaveDifferentCharges: WriteSpectralLibrary);
- // this is thread-safe because even if the score improves from another thread writing to this PSM,
- // the lock combined with AddOrReplace method will ensure thread safety
- if (meetsScoreCutoff)
+ AddPeptideCandidateToPsm(scan, myLocks, thisScore, peptide, matchedIons);
+
+
+ if (SpectralLibrary != null)
{
- // valid hit (met the cutoff score); lock the scan to prevent other threads from accessing it
- lock (myLocks[scan.ScanIndex])
- {
- bool scoreImprovement = PeptideSpectralMatches[scan.ScanIndex] == null || (thisScore - PeptideSpectralMatches[scan.ScanIndex].RunnerUpScore) > -PeptideSpectralMatch.ToleranceForScoreDifferentiation;
-
- if (scoreImprovement)
- {
- if (PeptideSpectralMatches[scan.ScanIndex] == null)
- {
- PeptideSpectralMatches[scan.ScanIndex] = new PeptideSpectralMatch(peptide, scan.Notch, thisScore, scan.ScanIndex, scan.TheScan, CommonParameters, matchedIons, 0);
- }
- else
- {
- PeptideSpectralMatches[scan.ScanIndex].AddOrReplace(peptide, thisScore, scan.Notch, CommonParameters.ReportAllAmbiguity, matchedIons, 0);
- }
- }
- }
+ DecoyScoreForSpectralLibrarySearch(scan, reversedOnTheFlyDecoy, decoyFragmentsForEachDissociationType,dissociationType, myLocks);
}
}
}
@@ -167,6 +171,54 @@ protected override MetaMorpheusEngineResults RunSpecific()
return new MetaMorpheusEngineResults(this);
}
+ private void DecoyScoreForSpectralLibrarySearch(ScanWithIndexAndNotchInfo scan,PeptideWithSetModifications reversedOnTheFlyDecoy, Dictionary> decoyFragmentsForEachDissociationType, DissociationType dissociationType,object[] myLocks)
+ {
+ // match decoy ions for decoy-on-the-fly
+ var decoyTheoreticalFragments = decoyFragmentsForEachDissociationType[dissociationType];
+
+ if (decoyTheoreticalFragments.Count == 0)
+ {
+ reversedOnTheFlyDecoy.Fragment(dissociationType, CommonParameters.DigestionParams.FragmentationTerminus, decoyTheoreticalFragments);
+ }
+
+ var decoyMatchedIons = MatchFragmentIons(scan.TheScan, decoyTheoreticalFragments, CommonParameters,
+ matchAllCharges: WriteSpectralLibrary);
+
+ // calculate decoy's score
+ var decoyScore = CalculatePeptideScore(scan.TheScan.TheScan, decoyMatchedIons, fragmentsCanHaveDifferentCharges: WriteSpectralLibrary);
+
+ AddPeptideCandidateToPsm(scan, myLocks, decoyScore, reversedOnTheFlyDecoy, decoyMatchedIons);
+ }
+
+
+ private void AddPeptideCandidateToPsm(ScanWithIndexAndNotchInfo scan, object[] myLocks, double thisScore, PeptideWithSetModifications peptide, List matchedIons)
+ {
+ bool meetsScoreCutoff = thisScore >= CommonParameters.ScoreCutoff;
+
+ // this is thread-safe because even if the score improves from another thread writing to this PSM,
+ // the lock combined with AddOrReplace method will ensure thread safety
+ if (meetsScoreCutoff)
+ {
+ // valid hit (met the cutoff score); lock the scan to prevent other threads from accessing it
+ lock (myLocks[scan.ScanIndex])
+ {
+ bool scoreImprovement = PeptideSpectralMatches[scan.ScanIndex] == null || (thisScore - PeptideSpectralMatches[scan.ScanIndex].RunnerUpScore) > -PeptideSpectralMatch.ToleranceForScoreDifferentiation;
+
+ if (scoreImprovement)
+ {
+ if (PeptideSpectralMatches[scan.ScanIndex] == null)
+ {
+ PeptideSpectralMatches[scan.ScanIndex] = new PeptideSpectralMatch(peptide, scan.Notch, thisScore, scan.ScanIndex, scan.TheScan, CommonParameters, matchedIons, 0);
+ }
+ else
+ {
+ PeptideSpectralMatches[scan.ScanIndex].AddOrReplace(peptide, thisScore, scan.Notch, CommonParameters.ReportAllAmbiguity, matchedIons, 0);
+ }
+ }
+ }
+ }
+ }
+
private IEnumerable GetAcceptableScans(double peptideMonoisotopicMass, MassDiffAcceptor searchMode)
{
foreach (AllowedIntervalWithNotch allowedIntervalWithNotch in searchMode.GetAllowedPrecursorMassIntervalsFromTheoreticalMass(peptideMonoisotopicMass).ToList())
diff --git a/EngineLayer/EngineLayer.csproj b/EngineLayer/EngineLayer.csproj
index 763aad022..b1cc962e3 100644
--- a/EngineLayer/EngineLayer.csproj
+++ b/EngineLayer/EngineLayer.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/EngineLayer/MetaMorpheusEngine.cs b/EngineLayer/MetaMorpheusEngine.cs
index 13b0e0c88..5c41141ce 100644
--- a/EngineLayer/MetaMorpheusEngine.cs
+++ b/EngineLayer/MetaMorpheusEngine.cs
@@ -2,10 +2,13 @@
using MassSpectrometry;
using MzLibUtil;
using Proteomics.Fragmentation;
+using Proteomics.ProteolyticDigestion;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
+using System.Threading.Tasks;
namespace EngineLayer
{
@@ -42,8 +45,13 @@ protected MetaMorpheusEngine(CommonParameters commonParameters, List<(string Fil
public static event EventHandler OutProgressHandler;
- public static double CalculatePeptideScore(MsDataScan thisScan, List matchedFragmentIons)
+ public static double CalculatePeptideScore(MsDataScan thisScan, List matchedFragmentIons, bool fragmentsCanHaveDifferentCharges = false)
{
+ if(fragmentsCanHaveDifferentCharges)
+ {
+ return CalculateAllChargesPeptideScore(thisScan, matchedFragmentIons);
+ }
+
double score = 0;
if (thisScan.MassSpectrum.XcorrProcessed)
@@ -80,8 +88,44 @@ public static double CalculatePeptideScore(MsDataScan thisScan, List MatchFragmentIons(Ms2ScanWithSpecificMass scan, List theoreticalProducts, CommonParameters commonParameters)
+ //Used only when user wants to generate spectral library.
+ //Normal search only looks for one match ion for one fragment, and if it accepts it then it doesn't try to look for different charge states of that same fragment.
+ //The score will be the number of matched ions and plus some fraction calculated by intensity(matchedFragmentIons[i].Intensity / thisScan.TotalIonCurrent).
+ //Like b1, b2, b3 will have score 3.xxx;But when generating library, we need look for match ions with all charges.So we will have b1,b2,b3, b1^2, b2^3. If using
+ //the normal scoring function, the score will be 5.xxxx, which is not proper. The score for b1 and b1^2 should also be 1 plus some some fraction calculated by intensity,
+ //because they are matching the same fragment ion just with different charges. So b1, b2, b3, b1^2, b2^3 should be also 3.xxx(but a little higher than b1, b2, b3 as
+ //the fraction part) rather than 5.xxx.
+ private static double CalculateAllChargesPeptideScore(MsDataScan thisScan, List matchedFragmentIons)
+ {
+ double score = 0;
+
+ // Morpheus score
+ List ions = new List();
+ for (int i = 0; i < matchedFragmentIons.Count; i++)
+ {
+ String ion = $"{ matchedFragmentIons[i].NeutralTheoreticalProduct.ProductType.ToString()}{ matchedFragmentIons[i].NeutralTheoreticalProduct.FragmentNumber}";
+ if (ions.Contains(ion))
+ {
+ score += matchedFragmentIons[i].Intensity / thisScan.TotalIonCurrent;
+ }
+ else
+ {
+ score += 1 + matchedFragmentIons[i].Intensity / thisScan.TotalIonCurrent;
+ ions.Add(ion);
+ }
+ }
+
+ return score;
+
+ }
+
+ public static List MatchFragmentIons(Ms2ScanWithSpecificMass scan, List theoreticalProducts, CommonParameters commonParameters, bool matchAllCharges = false)
{
+ if (matchAllCharges)
+ {
+ return MatchFragmentIonsOfAllCharges(scan, theoreticalProducts, commonParameters);
+ }
+
var matchedFragmentIons = new List();
if (scan.TheScan.MassSpectrum.XcorrProcessed && scan.TheScan.MassSpectrum.XArray.Length != 0)
@@ -172,6 +216,53 @@ public static List MatchFragmentIons(Ms2ScanWithSpecificMass
return matchedFragmentIons;
}
+ //Used only when user wants to generate spectral library.
+ //Normal search only looks for one match ion for one fragment, and if it accepts it then it doesn't try to look for different charge states of that same fragment.
+ //But for library generation, we need find all the matched peaks with all the different charges.
+ private static List MatchFragmentIonsOfAllCharges(Ms2ScanWithSpecificMass scan, List theoreticalProducts, CommonParameters commonParameters)
+ {
+ var matchedFragmentIons = new List();
+ var ions = new List();
+
+ // if the spectrum has no peaks
+ if (scan.ExperimentalFragments != null && !scan.ExperimentalFragments.Any())
+ {
+ return matchedFragmentIons;
+ }
+
+ // search for ions in the spectrum
+ foreach (Product product in theoreticalProducts)
+ {
+ // unknown fragment mass; this only happens rarely for sequences with unknown amino acids
+ if (double.IsNaN(product.NeutralMass))
+ {
+ continue;
+ }
+
+ //get the range we can accept
+ var minMass = commonParameters.ProductMassTolerance.GetMinimumValue(product.NeutralMass);
+ var maxMass = commonParameters.ProductMassTolerance.GetMaximumValue(product.NeutralMass);
+ var closestExperimentalMassList = scan.GetClosestExperimentalIsotopicEnvelopeList(minMass, maxMass);
+ if (closestExperimentalMassList != null)
+ {
+ foreach (var x in closestExperimentalMassList)
+ {
+ String ion = $"{product.ProductType.ToString()}{ product.FragmentNumber}^{x.Charge}-{product.NeutralLoss}";
+ if (x != null && !ions.Contains(ion) && commonParameters.ProductMassTolerance.Within(x.MonoisotopicMass, product.NeutralMass) && x.Charge <= scan.PrecursorCharge)//TODO apply this filter before picking the envelope
+ {
+ Product temProduct = product;
+ matchedFragmentIons.Add(new MatchedFragmentIon(ref temProduct, x.MonoisotopicMass.ToMz(x.Charge),
+ x.Peaks.First().intensity, x.Charge));
+
+ ions.Add(ion);
+ }
+ }
+ }
+ }
+
+ return matchedFragmentIons;
+ }
+
public MetaMorpheusEngineResults Run()
{
StartingSingleEngine();
diff --git a/EngineLayer/Ms2ScanWithSpecificMass.cs b/EngineLayer/Ms2ScanWithSpecificMass.cs
index 87818fd8d..4e0d8f4c4 100644
--- a/EngineLayer/Ms2ScanWithSpecificMass.cs
+++ b/EngineLayer/Ms2ScanWithSpecificMass.cs
@@ -114,6 +114,45 @@ public int GetClosestFragmentMass(double mass)
return index - 1;
}
+ //look for IsotopicEnvelopes which are in the range of acceptable mass
+ public IsotopicEnvelope[] GetClosestExperimentalIsotopicEnvelopeList(double minimumMass, double maxMass)
+ {
+
+ if (DeconvolutedMonoisotopicMasses.Length == 0)
+ {
+ return null;
+ }
+
+ //if no mass is in this range, then return null
+ if (DeconvolutedMonoisotopicMasses[0] > maxMass || DeconvolutedMonoisotopicMasses.Last() < minimumMass)
+ {
+ return null;
+ }
+
+ int startIndex = GetClosestFragmentMass(minimumMass);
+ int endIndex = GetClosestFragmentMass(maxMass);
+
+ //the index we get from GetClosestFragmentMass is the closest mass, while the acceptable mass we need is between minimumMass and maxMass
+ //so the startIndex mass is supposed to be larger than minimumMass, if not , then startIndex increases by 1;
+ //the endIndex mass is supposed to be smaller than maxMass, if not , then endIndex decreases by 1;
+ if (DeconvolutedMonoisotopicMasses[startIndex] maxMass)
+ {
+ endIndex = endIndex - 1;
+ }
+ int length = endIndex - startIndex + 1;
+
+ if (length < 1)
+ {
+ return null;
+ }
+ IsotopicEnvelope[] isotopicEnvelopes = ExperimentalFragments.Skip(startIndex).Take(length).ToArray();
+ return isotopicEnvelopes;
+ }
+
public double? GetClosestExperimentalFragmentMz(double theoreticalMz, out double? intensity)
{
if (TheScan.MassSpectrum.XArray.Length == 0)
diff --git a/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs b/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs
index a3fd04cc3..cae87de43 100644
--- a/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs
+++ b/EngineLayer/SpectralLibrarySearch/SpectralLibrarySearchFunction.cs
@@ -73,7 +73,6 @@ public static double CalculateNormalizedSpectralAngle(List t
var test = new Product(libraryIon.NeutralTheoreticalProduct.ProductType, libraryIon.NeutralTheoreticalProduct.Terminus,
libraryIon.NeutralTheoreticalProduct.NeutralMass, libraryIon.NeutralTheoreticalProduct.FragmentNumber,
libraryIon.NeutralTheoreticalProduct.AminoAcidPosition, libraryIon.NeutralTheoreticalProduct.NeutralLoss);
-
matchedIons.Add(libraryIon, new MatchedFragmentIon(ref test, mz, experimentalIntensity, libraryIon.Charge));
}
}
diff --git a/GUI/GUI.csproj b/GUI/GUI.csproj
index 2ab3d4b22..b164dbbfb 100644
--- a/GUI/GUI.csproj
+++ b/GUI/GUI.csproj
@@ -55,7 +55,7 @@
-
+
diff --git a/GUI/TaskWindows/SearchTaskWindow.xaml b/GUI/TaskWindows/SearchTaskWindow.xaml
index abbf59cad..169429466 100644
--- a/GUI/TaskWindows/SearchTaskWindow.xaml
+++ b/GUI/TaskWindows/SearchTaskWindow.xaml
@@ -449,6 +449,7 @@
+
diff --git a/GUI/TaskWindows/SearchTaskWindow.xaml.cs b/GUI/TaskWindows/SearchTaskWindow.xaml.cs
index 0d038676e..563d27f8e 100644
--- a/GUI/TaskWindows/SearchTaskWindow.xaml.cs
+++ b/GUI/TaskWindows/SearchTaskWindow.xaml.cs
@@ -303,6 +303,7 @@ private void UpdateFieldsFromTask(SearchTask task)
WriteDecoyCheckBox.IsChecked = task.SearchParameters.WriteDecoys;
WriteContaminantCheckBox.IsChecked = task.SearchParameters.WriteContaminants;
WriteIndividualResultsCheckBox.IsChecked = task.SearchParameters.WriteIndividualFiles;
+ WriteSpectralLibraryCheckBox.IsChecked = task.SearchParameters.WriteSpectralLibrary;
CompressIndividualResultsCheckBox.IsChecked = task.SearchParameters.CompressIndividualFiles;
IncludeMotifInModNamesCheckBox.IsChecked = task.SearchParameters.IncludeModMotifInMzid;
@@ -577,6 +578,7 @@ private void SaveButton_Click(object sender, RoutedEventArgs e)
TheTask.SearchParameters.WriteDecoys = WriteDecoyCheckBox.IsChecked.Value;
TheTask.SearchParameters.WriteContaminants = WriteContaminantCheckBox.IsChecked.Value;
TheTask.SearchParameters.WriteIndividualFiles = WriteIndividualResultsCheckBox.IsChecked.Value;
+ TheTask.SearchParameters.WriteSpectralLibrary = WriteSpectralLibraryCheckBox.IsChecked.Value;
TheTask.SearchParameters.CompressIndividualFiles = CompressIndividualResultsCheckBox.IsChecked.Value;
TheTask.SearchParameters.IncludeModMotifInMzid = IncludeMotifInModNamesCheckBox.IsChecked.Value;
diff --git a/GuiFunctions/GuiFunctions.csproj b/GuiFunctions/GuiFunctions.csproj
index a6af21514..cc4c7c2ad 100644
--- a/GuiFunctions/GuiFunctions.csproj
+++ b/GuiFunctions/GuiFunctions.csproj
@@ -14,7 +14,7 @@
-
+
diff --git a/README.md b/README.md
index 976e0dea1..4e6e2a266 100644
--- a/README.md
+++ b/README.md
@@ -146,4 +146,4 @@ metamorpheus -t Task1-SearchTaskconfig.toml Task2-CalibrateTaskconfig.toml Task3
* [Global Identification of Protein Post-translational Modifications in a Single-Pass Database Search--J. Proteome Res., 2015, 14 (11), pp 4714–4720](http://pubs.acs.org/doi/abs/10.1021/acs.jproteome.5b00599)
-* [A Proteomics Search Algorithm Specifically Designed for High-Resolution Tandem Mass Spectra--J. Proteome Res., 2013, 12 (3), pp 1377–1386](http://pubs.acs.org/doi/abs/10.1021/pr301024c)
+* [A Proteomics Search Algorithm Specifically Designed for High-Resolution Tandem Mass Spectra--J. Proteome Res., 2013, 12 (3), pp 1377–1386](http://pubs.acs.org/doi/abs/10.1021/pr301024c)
\ No newline at end of file
diff --git a/TaskLayer/CalibrationTask/CalibrationTask.cs b/TaskLayer/CalibrationTask/CalibrationTask.cs
index f7f71c67f..3f5f281d6 100644
--- a/TaskLayer/CalibrationTask/CalibrationTask.cs
+++ b/TaskLayer/CalibrationTask/CalibrationTask.cs
@@ -266,8 +266,9 @@ private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsData
Log("Searching with searchMode: " + searchMode, new List { taskId, "Individual Spectra Files", fileNameWithoutExtension });
Log("Searching with productMassTolerance: " + initProdTol, new List { taskId, "Individual Spectra Files", fileNameWithoutExtension });
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null, proteinList, searchMode, combinedParameters,
- FileSpecificParameters, null, new List { taskId, "Individual Spectra Files", fileNameWithoutExtension }).Run();
+ FileSpecificParameters, null, new List { taskId, "Individual Spectra Files", fileNameWithoutExtension }, writeSpectralLibrary).Run();
List allPsms = allPsmsArray.Where(b => b != null).ToList();
allPsms = allPsms.OrderByDescending(b => b.Score)
diff --git a/TaskLayer/GPTMDTask/GPTMDTask.cs b/TaskLayer/GPTMDTask/GPTMDTask.cs
index 7e7c90898..046e55ef4 100644
--- a/TaskLayer/GPTMDTask/GPTMDTask.cs
+++ b/TaskLayer/GPTMDTask/GPTMDTask.cs
@@ -98,8 +98,11 @@ protected override MyTaskResults RunSpecific(string OutputFolder, List b.PrecursorMass).ToArray();
myFileManager.DoneWithFile(origDataFile);
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[arrayOfMs2ScansSortedByMass.Length];
+
+ //spectral Library search and library generation have't applied to GPTMD yet
+ bool writeSpctralLibrary = false;
new ClassicSearchEngine(allPsmsArray, arrayOfMs2ScansSortedByMass, variableModifications, fixedModifications, null, null, null,
- proteinList, searchMode, combinedParams, this.FileSpecificParameters, null, new List { taskId, "Individual Spectra Files", origDataFile }).Run();
+ proteinList, searchMode, combinedParams, this.FileSpecificParameters, null, new List { taskId, "Individual Spectra Files", origDataFile }, writeSpctralLibrary).Run();
allPsms.AddRange(allPsmsArray.Where(p => p != null));
FinishedDataFile(origDataFile, new List { taskId, "Individual Spectra Files", origDataFile });
ReportProgress(new ProgressEventArgs(100, "Done!", new List { taskId, "Individual Spectra Files", origDataFile }));
diff --git a/TaskLayer/SearchTask/MzIdentMLWriter.cs b/TaskLayer/SearchTask/MzIdentMLWriter.cs
index fc2655fb4..15aee66b4 100644
--- a/TaskLayer/SearchTask/MzIdentMLWriter.cs
+++ b/TaskLayer/SearchTask/MzIdentMLWriter.cs
@@ -227,7 +227,7 @@ public static void WriteMzIdentMl(IEnumerable psms, Listp!=null))
{
_mzid.DataCollection.Inputs.SearchDatabase[database_index] = new mzIdentML110.Generated.SearchDatabaseType()
{
@@ -252,7 +252,7 @@ public static void WriteMzIdentMl(IEnumerable psms, Listp.DatabaseFilePath!=null))
{
_mzid.SequenceCollection.DBSequence[protein_index] = new mzIdentML110.Generated.DBSequenceType
{
diff --git a/TaskLayer/SearchTask/SearchParameters.cs b/TaskLayer/SearchTask/SearchParameters.cs
index 057c6fc70..5e31183f3 100644
--- a/TaskLayer/SearchTask/SearchParameters.cs
+++ b/TaskLayer/SearchTask/SearchParameters.cs
@@ -84,6 +84,7 @@ public SearchParameters()
public bool WriteDecoys { get; set; }
public bool WriteContaminants { get; set; }
public bool WriteIndividualFiles { get; set; }
+ public bool WriteSpectralLibrary { get; set; }
public bool CompressIndividualFiles { get; set; }
public List SilacLabels { get; set; }
public SilacLabel StartTurnoverLabel { get; set; } //used for SILAC turnover experiments
diff --git a/TaskLayer/SearchTask/SearchTask.cs b/TaskLayer/SearchTask/SearchTask.cs
index aa1773ea4..7e90f6db6 100644
--- a/TaskLayer/SearchTask/SearchTask.cs
+++ b/TaskLayer/SearchTask/SearchTask.cs
@@ -333,7 +333,7 @@ protected override MyTaskResults RunSpecific(string OutputFolder, List
-
+
diff --git a/Test/AddCompIonsTest.cs b/Test/AddCompIonsTest.cs
index e6d0d076e..b59b51a42 100644
--- a/Test/AddCompIonsTest.cs
+++ b/Test/AddCompIonsTest.cs
@@ -47,8 +47,10 @@ public static void TestAddCompIonsClassic()
var fsp = new List<(string fileName, CommonParameters fileSpecificParameters)>();
fsp.Add(("", CommonParameters));
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), writeSpectralLibrary).Run();
CommonParameters CommonParameters2 = new CommonParameters(
digestionParams: new DigestionParams(protease: protease.Name, maxMissedCleavages: 0, minPeptideLength: 1),
@@ -57,8 +59,9 @@ public static void TestAddCompIonsClassic()
var fsp2 = new List<(string fileName, CommonParameters fileSpecificParameters)>();
fsp2.Add(("", CommonParameters2));
PeptideSpectralMatch[] allPsmsArray2 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+
new ClassicSearchEngine(allPsmsArray2, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters2, fsp2, null, new List()).Run();
+ proteinList, searchModes, CommonParameters2, fsp2, null, new List(), writeSpectralLibrary).Run();
double scoreT = allPsmsArray2[0].Score;
double scoreF = allPsmsArray[0].Score;
diff --git a/Test/AmbiguityTest.cs b/Test/AmbiguityTest.cs
index f889c5a7f..e9a4ecf29 100644
--- a/Test/AmbiguityTest.cs
+++ b/Test/AmbiguityTest.cs
@@ -57,10 +57,11 @@ public static void TestResolveAmbiguities()
PeptideSpectralMatch[] allPsmsArray_withOutAmbiguity = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray_withAmbiguity, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters_t, fsp_t, null, new List()).Run(); //report all ambiguity TRUE
+ proteinList, searchModes, CommonParameters_t, fsp_t, null, new List(), writeSpectralLibrary).Run(); //report all ambiguity TRUE
new ClassicSearchEngine(allPsmsArray_withOutAmbiguity, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters_f, fsp_f, null, new List()).Run(); //report all ambiguity FALSE
+ proteinList, searchModes, CommonParameters_f, fsp_f, null, new List(), writeSpectralLibrary).Run(); //report all ambiguity FALSE
Assert.AreEqual("QQQ", allPsmsArray_withAmbiguity[0].BaseSequence);
Assert.AreEqual("QQQ", allPsmsArray_withOutAmbiguity[0].BaseSequence);
diff --git a/Test/CoIsolationTests.cs b/Test/CoIsolationTests.cs
index d12bc4f07..caeade9bd 100644
--- a/Test/CoIsolationTests.cs
+++ b/Test/CoIsolationTests.cs
@@ -61,8 +61,10 @@ public static void TestCoIsolation()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters(deconvolutionIntensityRatio: 50)).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length]; ;
+
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), writeSpectralLibrary).Run();
// Two matches for this single scan! Corresponding to two co-isolated masses
Assert.AreEqual(2, allPsmsArray.Length);
diff --git a/Test/FdrTest.cs b/Test/FdrTest.cs
index 034d06e27..bc3b9e735 100644
--- a/Test/FdrTest.cs
+++ b/Test/FdrTest.cs
@@ -184,7 +184,7 @@ public static void TestDeltaValues()
//check better when using delta
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), SearchParameters.WriteSpectralLibrary).Run();
var indexEngine = new IndexingEngine(proteinList, variableModifications, fixedModifications, null, null, null, 1, DecoyType.None, CommonParameters,
fsp, 30000, false, new List(), TargetContaminantAmbiguity.RemoveContaminant, new List());
@@ -235,7 +235,7 @@ public static void TestDeltaValues()
//check no change when using delta
allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), SearchParameters.WriteSpectralLibrary).Run();
CommonParameters = new CommonParameters(useDeltaScore: true, digestionParams: new DigestionParams(minPeptideLength: 5));
@@ -268,6 +268,7 @@ public static void TestComputePEPValue()
var origDataFile = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\TaGe_SA_HeLa_04_subset_longestSeq.mzML");
MyFileManager myFileManager = new MyFileManager(true);
CommonParameters CommonParameters = new CommonParameters(digestionParams: new DigestionParams());
+ SearchParameters SearchParameters = new SearchParameters();
var fsp = new List<(string fileName, CommonParameters fileSpecificParameters)>();
fsp.Add(("TaGe_SA_HeLa_04_subset_longestSeq.mzML", CommonParameters));
@@ -278,7 +279,7 @@ public static void TestComputePEPValue()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, @"TestData\TaGe_SA_HeLa_04_subset_longestSeq.mzML", CommonParameters).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), SearchParameters.WriteSpectralLibrary).Run();
FdrAnalysisResults fdrResultsClassicDelta = (FdrAnalysisResults)(new FdrAnalysisEngine(allPsmsArray.Where(p => p != null).ToList(), 1,
CommonParameters, fsp, new List()).Run());
@@ -475,8 +476,10 @@ public static void TestComputePEPValueTopDown()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, origDataFile, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchMode, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchMode, CommonParameters, fsp, null, new List(), writeSpectralLibrary).Run();
var nonNullPsms = allPsmsArray.Where(p => p != null).ToList();
List moreNonNullPSMs = new List();
@@ -637,8 +640,9 @@ public static void ReplaceBadStdevOne()
extendedArray = extendedArray.OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[extendedArray.Length];
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, extendedArray, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), writeSpectralLibrary).Run();
List nonNullPsms = allPsmsArray.Where(p => p != null).ToList();
nonNullPsms = nonNullPsms.OrderByDescending(p => p.Score).ToList();
@@ -690,8 +694,9 @@ public static void ReplaceBadStdevTwo()
extendedArray = extendedArray.OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[extendedArray.Length];
+ bool writeSpectralLibrary = false;
new ClassicSearchEngine(allPsmsArray, extendedArray, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), writeSpectralLibrary).Run();
List nonNullPsms = allPsmsArray.Where(p => p != null).ToList();
nonNullPsms = nonNullPsms.OrderByDescending(p => p.Score).ToList();
diff --git a/Test/MatchIonsOfAllCharges.cs b/Test/MatchIonsOfAllCharges.cs
new file mode 100644
index 000000000..53c4bc1a6
--- /dev/null
+++ b/Test/MatchIonsOfAllCharges.cs
@@ -0,0 +1,343 @@
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using EngineLayer;
+using EngineLayer.ClassicSearch;
+using IO.MzML;
+using MzLibUtil;
+using NUnit.Framework;
+using Proteomics;
+using Proteomics.Fragmentation;
+using Proteomics.ProteolyticDigestion;
+using TaskLayer;
+using Chemistry;
+using System;
+using MassSpectrometry;
+
+namespace Test
+{
+ [TestFixture]
+ public class SearchEngineForWritingSpectralLibraryTest
+ {
+ [Test]
+ public static void TestMatchIonsOfAllChargesBottomUp()
+ {
+ CommonParameters CommonParameters = new CommonParameters();
+
+ MetaMorpheusTask.DetermineAnalyteType(CommonParameters);
+
+ var variableModifications = new List();
+ var fixedModifications = new List();
+
+ var proteinList = new List
+ {
+ new Protein("AAAHSSLK", ""),new Protein("RQPAQPR", ""),new Protein("EKAEAEAEK", "")
+ };
+ var myMsDataFile = Mzml.LoadAllStaticData(Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\SmallCalibratible_Yeast.mzML"));
+
+
+ var searchMode = new SinglePpmAroundZeroSearchMode(5);
+
+ Tolerance DeconvolutionMassTolerance = new PpmTolerance(5);
+
+ var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
+
+ //search by new method of looking for all charges
+ PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+
+ new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), true).Run();
+ var psm = allPsmsArray.Where(p => p != null).ToList();
+ Assert.That(psm[1].MatchedFragmentIons.Count == 14);
+ //there are ions with same product type and same fragment number but different charges
+ Assert.That(psm[1].MatchedFragmentIons[8].NeutralTheoreticalProduct.ProductType == psm[1].MatchedFragmentIons[9].NeutralTheoreticalProduct.ProductType &&
+ psm[1].MatchedFragmentIons[8].NeutralTheoreticalProduct.FragmentNumber == psm[1].MatchedFragmentIons[9].NeutralTheoreticalProduct.FragmentNumber &&
+ psm[1].MatchedFragmentIons[8].Charge != psm[1].MatchedFragmentIons[9].Charge);
+ Assert.That(psm[2].MatchedFragmentIons.Count == 14);
+ Assert.That(psm[4].MatchedFragmentIons.Count == 16);
+
+ //search by old method of looking for only one charge
+ PeptideSpectralMatch[] allPsmsArray_oneCharge = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray_oneCharge, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), false).Run();
+ var psm_oneCharge = allPsmsArray_oneCharge.Where(p => p != null).ToList();
+
+ //compare 2 scores , they should have same integer part but new search has a little higher score than old search
+ Assert.That(psm[1].Score > psm_oneCharge[1].Score);
+ Assert.AreEqual(Math.Truncate(psm[1].Score), 12);
+ Assert.AreEqual(Math.Truncate(psm_oneCharge[1].Score), 12);
+
+ //compare 2 results and evaluate the different matched ions
+ var peptideTheorProducts = new List();
+ Assert.That(psm_oneCharge[1].MatchedFragmentIons.Count == 12);
+ var differences = psm[1].MatchedFragmentIons.Except(psm_oneCharge[1].MatchedFragmentIons);
+ psm[1].BestMatchingPeptides.First().Peptide.Fragment(CommonParameters.DissociationType, CommonParameters.DigestionParams.FragmentationTerminus, peptideTheorProducts);
+ foreach (var ion in differences)
+ {
+ foreach (var product in peptideTheorProducts)
+ {
+ if (product.Annotation.ToString().Equals(ion.NeutralTheoreticalProduct.Annotation.ToString()))
+ {
+ //to see if the different matched ions are qualified
+ Assert.That(CommonParameters.ProductMassTolerance.Within(ion.Mz.ToMass(ion.Charge), product.NeutralMass));
+ }
+ }
+ }
+
+ //test specific condition: unknown fragment mass; this only happens rarely for sequences with unknown amino acids
+ var myMsDataFile1 = new TestDataFile();
+ var variableModifications1 = new List();
+ var fixedModifications1 = new List();
+ var proteinList1 = new List { new Protein("QXQ", null) };
+ var productMassTolerance = new AbsoluteTolerance(0.01);
+ var searchModes = new OpenSearchMode();
+
+ Tolerance DeconvolutionMassTolerance1 = new PpmTolerance(5);
+
+ var listOfSortedms2Scans1 = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
+
+ List motifs = new List { new DigestionMotif("K", null, 1, null) };
+ Protease protease = new Protease("Custom Protease3", CleavageSpecificity.Full, null, null, motifs);
+ ProteaseDictionary.Dictionary.Add(protease.Name, protease);
+
+ CommonParameters CommonParameters1 = new CommonParameters(
+ digestionParams: new DigestionParams(protease: protease.Name, maxMissedCleavages: 0, minPeptideLength: 1),
+ scoreCutoff: 1,
+ addCompIons: false);
+ var fsp = new List<(string fileName, CommonParameters fileSpecificParameters)>();
+ fsp.Add(("", CommonParameters));
+ PeptideSpectralMatch[] allPsmsArray1 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+
+ bool writeSpectralLibrary = true;
+ new ClassicSearchEngine(allPsmsArray1, listOfSortedms2Scans1, variableModifications1, fixedModifications1, null, null, null,
+ proteinList1, searchModes, CommonParameters1, fsp, null, new List(), writeSpectralLibrary).Run();
+
+ var psm1 = allPsmsArray1.Where(p => p != null).ToList();
+ Assert.AreEqual(psm1.Count, 222);
+ }
+
+ [Test]
+ public static void TestMatchIonsOfAllChargesTopDown()
+ {
+ CommonParameters CommonParameters = new CommonParameters(
+ digestionParams: new DigestionParams(protease: "top-down"),
+ scoreCutoff: 1,
+ assumeOrphanPeaksAreZ1Fragments: false);
+
+ MetaMorpheusTask.DetermineAnalyteType(CommonParameters);
+
+ // test output file name (should be proteoform and not peptide)
+ Assert.That(GlobalVariables.AnalyteType == "Proteoform");
+
+ var variableModifications = new List();
+ var fixedModifications = new List();
+ var proteinList = new List
+ {
+ new Protein("MPKVYSYQEVAEHNGPENFWIIIDDKVYDVSQFKDEHPGGDEIIMDLGGQDATESFVDIGHSDEALRLLKGLYIGDVDKTSERVSVEKVSTSENQSKGSGTLVVILAILMLGVAYYLLNE", "P40312")
+ };
+
+ var myMsDataFile = Mzml.LoadAllStaticData(Path.Combine(TestContext.CurrentContext.TestDirectory, @"TopDownTestData\slicedTDYeast.mzML"));
+
+ var searchMode = new SinglePpmAroundZeroSearchMode(5);
+
+ Tolerance DeconvolutionMassTolerance = new PpmTolerance(5);
+
+ var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
+
+ //search by new method of looking for all charges
+ PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), true).Run();
+
+ var psm = allPsmsArray.Where(p => p != null).FirstOrDefault();
+ Assert.That(psm.MatchedFragmentIons.Count == 62);
+
+
+ //search by old method of looking for only one charge
+ PeptideSpectralMatch[] allPsmsArray_oneCharge = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray_oneCharge, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), false).Run();
+
+ var psm_oneCharge = allPsmsArray_oneCharge.Where(p => p != null).FirstOrDefault();
+ Assert.That(psm_oneCharge.MatchedFragmentIons.Count == 47);
+
+ //compare 2 scores , they should have same integer but new search has a little higher score than old search
+ Assert.That(psm.Score > psm_oneCharge.Score);
+ Assert.AreEqual(Math.Truncate(psm.Score), 47);
+ Assert.AreEqual(Math.Truncate(psm_oneCharge.Score), 47);
+
+ //compare 2 results and evaluate the different matched ions
+ var peptideTheorProducts = new List();
+ var differences = psm.MatchedFragmentIons.Except(psm_oneCharge.MatchedFragmentIons);
+ psm.BestMatchingPeptides.First().Peptide.Fragment(CommonParameters.DissociationType, CommonParameters.DigestionParams.FragmentationTerminus, peptideTheorProducts);
+ foreach (var ion in differences)
+ {
+ foreach (var product in peptideTheorProducts)
+ {
+ if (product.Annotation.ToString().Equals(ion.NeutralTheoreticalProduct.Annotation.ToString()))
+ {
+ //to see if the different matched ions are qualified
+ Assert.That(CommonParameters.ProductMassTolerance.Within(ion.Mz.ToMass(ion.Charge), product.NeutralMass));
+ }
+ }
+ }
+ }
+
+ [Test]
+ public static void TestLookingForAcceptableIsotopicEnvelopes()
+ {
+ CommonParameters CommonParameters = new CommonParameters();
+
+ MetaMorpheusTask.DetermineAnalyteType(CommonParameters);
+
+ var variableModifications = new List();
+ var fixedModifications = new List();
+
+ var proteinList = new List
+ {
+ new Protein("AAAHSSLK", ""),new Protein("RQPAQPR", ""),new Protein("EKAEAEAEK", "")
+ };
+ var myMsDataFile = Mzml.LoadAllStaticData(Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\SmallCalibratible_Yeast.mzML"));
+
+
+ var searchMode = new SinglePpmAroundZeroSearchMode(5);
+
+ Tolerance DeconvolutionMassTolerance = new PpmTolerance(5);
+
+ var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
+
+ var ms2ScanTest = listOfSortedms2Scans[0];
+
+ //test when all the masses are not in the given range
+
+ //test1 when all the masses are too small
+ var test1 = ms2ScanTest.GetClosestExperimentalIsotopicEnvelopeList(50, 95);
+ Assert.AreEqual(test1, null);
+ //test2 when all the masses are too big
+ var test2 = ms2ScanTest.GetClosestExperimentalIsotopicEnvelopeList(582, 682);
+ Assert.AreEqual(test2, null);
+ //test3 when the mass which is bigger than given min mass is bigger than the mass which is smaller than the given max mass
+ //for example: the mass array is [1,2,3,4,5], the given min mass is 2.2, the given max mass is 2.8
+ var test3 = ms2ScanTest.GetClosestExperimentalIsotopicEnvelopeList(110, 111);
+ Assert.AreEqual(test3, null);
+
+
+ //test normal conditions:look for IsotopicEnvelopes which are in the range of acceptable mass
+ var test4 = ms2ScanTest.GetClosestExperimentalIsotopicEnvelopeList(120, 130);
+ IsotopicEnvelope[] expected4 = ms2ScanTest.ExperimentalFragments.Skip(15).Take(9).ToArray();
+ Assert.That(ms2ScanTest.ExperimentalFragments[15].MonoisotopicMass > 120 && ms2ScanTest.ExperimentalFragments[14].MonoisotopicMass < 120);
+ Assert.That(ms2ScanTest.ExperimentalFragments[23].MonoisotopicMass < 130 && ms2ScanTest.ExperimentalFragments[24].MonoisotopicMass > 130);
+ Assert.AreEqual(test4, expected4);
+
+ var test5 = ms2ScanTest.GetClosestExperimentalIsotopicEnvelopeList(400, 500);
+ IsotopicEnvelope[] expected5 = ms2ScanTest.ExperimentalFragments.Skip(150).Take(7).ToArray();
+ Assert.That(ms2ScanTest.ExperimentalFragments[150].MonoisotopicMass > 400 && ms2ScanTest.ExperimentalFragments[149].MonoisotopicMass < 400);
+ Assert.That(ms2ScanTest.ExperimentalFragments[156].MonoisotopicMass < 500 && ms2ScanTest.ExperimentalFragments[157].MonoisotopicMass > 500);
+ Assert.AreEqual(test5, expected5);
+ }
+
+ [Test]
+ public static void TestReverseDecoyGenerationDuringSearch()
+ {
+ CommonParameters CommonParameters = new CommonParameters();
+
+ MetaMorpheusTask.DetermineAnalyteType(CommonParameters);
+
+ var variableModifications = new List();
+ var fixedModifications = new List();
+
+ var proteinList = new List
+ {
+ new Protein ("KKAEDGINK",""),new Protein("AVNSISLK", ""),new Protein("EKAEAEAEK", ""), new Protein("DITANLR",""), new Protein("QNAIGTAK",""),
+ new Protein("FHKSQLNK",""),new Protein ("KQVAQWNK",""),new Protein ("NTRIEELK",""),new Protein("RQPAQPR", ""),
+ };
+ var myMsDataFile = Mzml.LoadAllStaticData(Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\SmallCalibratible_Yeast.mzML"));
+
+
+ var searchMode = new SinglePpmAroundZeroSearchMode(5);
+
+ Tolerance DeconvolutionMassTolerance = new PpmTolerance(5);
+
+ var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
+
+
+ var path = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\myPrositLib.msp");
+
+ var testLibrary = new SpectralLibrary(new List { path });
+
+
+
+ //test when doing spectral library search without generating library
+ PeptideSpectralMatch[] allPsmsArray1 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray1, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, testLibrary, new List(), false).Run();
+ var psm1 = allPsmsArray1.Where(p => p != null).ToList();
+ Assert.That(psm1[0].IsDecoy == false && psm1[0].FullSequence == "DITANLR");
+ Assert.That(psm1[1].IsDecoy == true && psm1[1].FullSequence == "LSISNVAK");
+ Assert.That(psm1[2].IsDecoy == true&& psm1[2].FullSequence == "LSISNVAK");
+ Assert.That(psm1[3].IsDecoy == false&& psm1[3].FullSequence == "RQPAQPR");
+ Assert.That(psm1[4].IsDecoy == false&& psm1[4].FullSequence == "KKAEDGINK");
+ Assert.That(psm1[5].IsDecoy == false&& psm1[5].FullSequence == "EKAEAEAEK");
+ Assert.That(psm1[6].IsDecoy == false&& psm1[6].FullSequence == "EKAEAEAEK");
+
+
+ proteinList.Add(new Protein("LSISNVAK", "", isDecoy: true));
+ //test when doing spectral library search with generating library; non spectral search won't generate decoy by "decoy on the fly" , so proteinlist used by non spectral library search would contain decoys
+ PeptideSpectralMatch[] allPsmsArray2 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray2, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, testLibrary, new List(), true).Run();
+ var psm2 = allPsmsArray2.Where(p => p != null).ToList();
+ Assert.That(psm2[0].IsDecoy == false && psm2[0].FullSequence == "DITANLR");
+ Assert.That(psm2[1].IsDecoy == true && psm2[1].FullSequence == "LSISNVAK");
+ Assert.That(psm2[2].IsDecoy == true && psm2[2].FullSequence == "LSISNVAK");
+ Assert.That(psm2[3].IsDecoy == false && psm2[3].FullSequence == "RQPAQPR");
+ Assert.That(psm2[4].IsDecoy == false && psm2[4].FullSequence == "KKAEDGINK");
+ Assert.That(psm2[5].IsDecoy == false && psm2[5].FullSequence == "EKAEAEAEK");
+ Assert.That(psm2[6].IsDecoy == false && psm2[6].FullSequence == "EKAEAEAEK");
+
+ //test when doing non spectral library search without generating library
+ PeptideSpectralMatch[] allPsmsArray3 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray3, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), false).Run();
+ var psm3 = allPsmsArray3.Where(p => p != null).ToList();
+ Assert.That(psm3[0].IsDecoy == false && psm3[0].FullSequence == "DITANLR");
+ Assert.That(psm3[1].IsDecoy == true && psm3[1].FullSequence == "LSISNVAK");
+ Assert.That(psm3[2].IsDecoy == true && psm3[2].FullSequence == "LSISNVAK");
+ Assert.That(psm3[3].IsDecoy == false && psm3[3].FullSequence == "RQPAQPR");
+ Assert.That(psm3[4].IsDecoy == false && psm3[4].FullSequence == "KKAEDGINK");
+ Assert.That(psm3[5].IsDecoy == false && psm3[5].FullSequence == "EKAEAEAEK");
+ Assert.That(psm3[6].IsDecoy == false && psm3[6].FullSequence == "EKAEAEAEK");
+
+
+ //test when doing non spectral library search with generating library
+ PeptideSpectralMatch[] allPsmsArray4 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ new ClassicSearchEngine(allPsmsArray4, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
+ proteinList, searchMode, CommonParameters, null, null, new List(), true).Run();
+ var psm4 = allPsmsArray4.Where(p => p != null).ToList();
+ Assert.That(psm4[0].IsDecoy == false && psm4[0].FullSequence == "DITANLR");
+ Assert.That(psm4[1].IsDecoy == true && psm4[1].FullSequence == "LSISNVAK");
+ Assert.That(psm4[2].IsDecoy == true && psm4[2].FullSequence == "LSISNVAK");
+ Assert.That(psm4[3].IsDecoy == false && psm4[3].FullSequence == "RQPAQPR");
+ Assert.That(psm4[4].IsDecoy == false && psm4[4].FullSequence == "KKAEDGINK");
+ Assert.That(psm4[5].IsDecoy == false && psm4[5].FullSequence == "EKAEAEAEK");
+ Assert.That(psm4[6].IsDecoy == false && psm4[6].FullSequence == "EKAEAEAEK");
+
+
+ //compare psm's target/decoy results in 4 conditions. they should be same as new decoy methods shouldn't change the t/d results
+ for (int i=0; i(), new List(), null, null, null,
- new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List());
+ new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List(), writeSpectralLibrary);
cse.Run();
Assert.AreEqual(3, globalPsms[0].MatchedFragmentIons.Count);
@@ -83,8 +84,9 @@ public static void TestLastPeaks()
minPeptideLength: 1,
maxModificationIsoforms: int.MaxValue,
initiatorMethionineBehavior: InitiatorMethionineBehavior.Retain));
+ bool writeSpectralLibrary = false;
ClassicSearchEngine cse = new ClassicSearchEngine(globalPsms, arrayOfSortedMS2Scans, new List(), new List(), null, null, null,
- new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List());
+ new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List(), writeSpectralLibrary);
cse.Run();
Assert.Less(globalPsms[0].Score, 2);
@@ -119,8 +121,9 @@ public static void TestVeryCloseExperimentalsClassic()
minPeptideLength: 1,
maxModificationIsoforms: int.MaxValue,
initiatorMethionineBehavior: InitiatorMethionineBehavior.Retain));
+ bool writeSpetralLibrary = false;
ClassicSearchEngine cse = new ClassicSearchEngine(globalPsms, arrayOfSortedMS2Scans, new List(), new List(), null, null, null,
- new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List());
+ new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List(), writeSpetralLibrary);
cse.Run();
Assert.Less(globalPsms[0].Score, 2);
@@ -179,9 +182,9 @@ public static void TestAllNaN()
PeptideSpectralMatch[] globalPsms = new PeptideSpectralMatch[1];
Ms2ScanWithSpecificMass[] arrayOfSortedMS2Scans = { new Ms2ScanWithSpecificMass(scan, 0, 0, null, new CommonParameters()) };
CommonParameters CommonParameters = new CommonParameters(productMassTolerance: new PpmTolerance(5), scoreCutoff: 1, digestionParams: new DigestionParams(maxMissedCleavages: 0, minPeptideLength: 1, maxModificationIsoforms: int.MaxValue, initiatorMethionineBehavior: InitiatorMethionineBehavior.Retain));
-
+ bool writeSpetralLibrary = false;
ClassicSearchEngine cse = new ClassicSearchEngine(globalPsms, arrayOfSortedMS2Scans, new List(), new List(), null, null, null,
- new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List());
+ new List { prot }, new OpenSearchMode(), CommonParameters, null, null, new List(), writeSpetralLibrary);
cse.Run();
Assert.IsNull(globalPsms[0]);
diff --git a/Test/SearchEngineTests.cs b/Test/SearchEngineTests.cs
index 7447f586b..17b732896 100644
--- a/Test/SearchEngineTests.cs
+++ b/Test/SearchEngineTests.cs
@@ -46,8 +46,9 @@ public static void TestClassicSearchEngine()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
// Single search mode
Assert.AreEqual(1, allPsmsArray.Length);
@@ -276,8 +277,9 @@ public static void TestClassicSearchEngineXcorr()
}
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedXcorrms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedXcorrms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
Assert.IsTrue(listOfSortedXcorrms2Scans[0].TheScan.MassSpectrum.XcorrProcessed);
@@ -327,8 +329,9 @@ public static void TestClassicSearchEngineWithWeirdPeptide()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
// Single search mode
Assert.AreEqual(1, allPsmsArray.Length);
@@ -632,8 +635,9 @@ public static void TestClassicSearchEngineLowResSimple()
var fsp = new List<(string, CommonParameters)>();
fsp.Add(("sliced_b6.mzML", CommonParameters));
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedXcorrms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, fsp, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, fsp, null, new List(), writeSpetralLibrary).Run();
var nonNullPsms = allPsmsArray.Where(p => p != null).ToList();
Assert.AreEqual(131, nonNullPsms.Count); //if you run the test separately, it will be 111 because mods won't have been read in a previous test...
@@ -824,8 +828,9 @@ public static void TestNonViablePSM()
PeptideSpectralMatch[] allPsmsArray = allPsmsArrays[0];
//Classic
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
//Modern
new ModernSearchEngine(allPsmsArray, listOfSortedms2Scans, indexResults.PeptideIndex, indexResults.FragmentIndex, 0, CommonParameters, null, massDiffAcceptor, SearchParameters.MaximumMassThatFragmentIonScoreIsDoubled, new List()).Run();
@@ -1556,8 +1561,9 @@ public static void TestClassicSemiProtease()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
//////////////////////////////
@@ -1575,7 +1581,7 @@ public static void TestClassicSemiProtease()
PeptideSpectralMatch[] allPsmsArray2 = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
new ClassicSearchEngine(allPsmsArray2, listOfSortedms2Scans2, variableModifications, fixedModifications, null, null, null,
- proteinList, searchModes, CommonParameters2, null, null, new List()).Run();
+ proteinList, searchModes, CommonParameters2, null, null, new List(), writeSpetralLibrary).Run();
// Single search mode
Assert.AreEqual(1, allPsmsArray2.Length);
Assert.AreEqual(allPsmsArray.Length, allPsmsArray2.Length);
@@ -1694,8 +1700,9 @@ public static void TestClassicSearchOneNterminalModifiedPeptideOneScan()
//Search the scan against the protein
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[1];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, scans, new List(), new List(), null, null, null,
- proteins, new SinglePpmAroundZeroSearchMode(20), new CommonParameters(dissociationType: DissociationType.CID), null, null, new List()).Run();
+ proteins, new SinglePpmAroundZeroSearchMode(20), new CommonParameters(dissociationType: DissociationType.CID), null, null, new List(), writeSpetralLibrary).Run();
//Process the results
List matchedFragmentIonList = allPsmsArray.SelectMany(p => p.MatchedFragmentIons).ToList();
diff --git a/Test/SpectralLibraryReaderTest.cs b/Test/SpectralLibraryReaderTest.cs
index 9af8f7d3a..b45aa5387 100644
--- a/Test/SpectralLibraryReaderTest.cs
+++ b/Test/SpectralLibraryReaderTest.cs
@@ -3,7 +3,6 @@
using System;
using System.Linq;
using EngineLayer;
-using MzLibUtil;
using TaskLayer;
using System.Collections.Generic;
using Proteomics.Fragmentation;
diff --git a/Test/Test.csproj b/Test/Test.csproj
index beb93c0ca..cdbe6674d 100644
--- a/Test/Test.csproj
+++ b/Test/Test.csproj
@@ -18,7 +18,7 @@
-
+
diff --git a/Test/TestPsm.cs b/Test/TestPsm.cs
index 8c1f9bb6e..8dcd9a6ad 100644
--- a/Test/TestPsm.cs
+++ b/Test/TestPsm.cs
@@ -115,8 +115,9 @@ public static void TestLongestFragmentIonSequence()
string myDatabase = Path.Combine(TestContext.CurrentContext.TestDirectory, @"TestData\DbForPrunedDb.fasta");
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null, proteinList, searchModes,
- new CommonParameters(), null, null, new List()).Run();
+ new CommonParameters(), null, null, new List(), writeSpetralLibrary).Run();
List longestSeriesObserved = new List();
diff --git a/Test/TestTopDown.cs b/Test/TestTopDown.cs
index a960d941e..5c768533b 100644
--- a/Test/TestTopDown.cs
+++ b/Test/TestTopDown.cs
@@ -47,8 +47,9 @@ public static void TestClassicSearchEngineTopDown()
var listOfSortedms2Scans = MetaMorpheusTask.GetMs2Scans(myMsDataFile, null, new CommonParameters()).OrderBy(b => b.PrecursorMass).ToArray();
PeptideSpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
+ bool writeSpetralLibrary = false;
new ClassicSearchEngine(allPsmsArray, listOfSortedms2Scans, variableModifications, fixedModifications, null, null, null,
- proteinList, searchMode, CommonParameters, null, null, new List()).Run();
+ proteinList, searchMode, CommonParameters, null, null, new List(), writeSpetralLibrary).Run();
var psm = allPsmsArray.Where(p => p != null).FirstOrDefault();
Assert.That(psm.MatchedFragmentIons.Count == 47);