Skip to content

Commit f56be2a

Browse files
committed
Merge branch 'DockerFileUpdate' of https://github.com/Alexander-Sol/MetaMorpheus into DockerFileUpdate
2 parents fc78a16 + 84d98c1 commit f56be2a

File tree

10 files changed

+65505
-30
lines changed

10 files changed

+65505
-30
lines changed

MetaMorpheus/EngineLayer/Calibration/DataPointAcquisitionEngine.cs

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
using Chemistry;
22
using MassSpectrometry;
33
using MzLibUtil;
4-
using Proteomics.AminoAcidPolymer;
54
using System;
6-
using System.Collections.Concurrent;
75
using System.Collections.Generic;
86
using System.Linq;
97
using System.Threading.Tasks;
@@ -76,13 +74,6 @@ protected override MetaMorpheusEngineResults RunSpecific()
7674

7775
var representativeSinglePeptide = identification.BestMatchingBioPolymersWithSetMods.First().SpecificBioPolymer;
7876

79-
// Get the peptide, don't forget to add the modifications!!!!
80-
var SequenceWithChemicalFormulas = representativeSinglePeptide.SequenceWithChemicalFormulas;
81-
if (SequenceWithChemicalFormulas == null || representativeSinglePeptide.AllModsOneIsNterminus.Any(b => b.Value.NeutralLosses != null))
82-
continue;
83-
84-
Peptide coolPeptide = new Peptide(SequenceWithChemicalFormulas);
85-
8677
List<LabeledDataPoint> ms2tuple = SearchMS2Spectrum(GoodScans[matchIndex], identification, ProductMassTolerance);
8778

8879
lock (_ms2Lock)
@@ -91,7 +82,7 @@ protected override MetaMorpheusEngineResults RunSpecific()
9182
}
9283

9384
// Calculate theoretical isotopic distribution of the full peptide
94-
var dist = IsotopicDistribution.GetDistribution(coolPeptide.GetChemicalFormula(), FineResolutionForIsotopeDistCalculation, 0.001);
85+
var dist = IsotopicDistribution.GetDistribution(representativeSinglePeptide.ThisChemicalFormula, FineResolutionForIsotopeDistCalculation, 0.001);
9586

9687
double[] theoreticalMasses = dist.Masses.ToArray();
9788
double[] theoreticalIntensities = dist.Intensities.ToArray();
@@ -137,6 +128,7 @@ protected override MetaMorpheusEngineResults RunSpecific()
137128
theIndex = direction == 1 ? ms2spectrumIndex + 1 : identification.PrecursorScanNumber ?? ms2spectrumIndex;
138129

139130
bool addedAscan = true;
131+
bool positiveMode = identification.ScanPrecursorCharge > 0;
140132

141133
int highestKnownChargeForThisPeptide = peptideCharge;
142134
while (theIndex >= 1 && theIndex <= MyMsDataFile.NumSpectra && addedAscan) //as long as we're finding the peptide in ms1 scans
@@ -157,16 +149,26 @@ protected override MetaMorpheusEngineResults RunSpecific()
157149
break;
158150

159151
bool startingToAddCharges = false;
160-
int chargeToLookAt = 1;
152+
int chargeToLookAt = positiveMode ? 1 : -1;
153+
int chargeLimit = positiveMode ? highestKnownChargeForThisPeptide + 1 : highestKnownChargeForThisPeptide - 1;
154+
161155
do
162156
{
163-
if (theoreticalMasses[0].ToMz(chargeToLookAt) > scanWindowRange.Maximum)
157+
double mz = theoreticalMasses[0].ToMz(chargeToLookAt);
158+
159+
// If m/z is above the scan window, try next charge
160+
if (mz > scanWindowRange.Maximum)
164161
{
165-
chargeToLookAt++;
162+
chargeToLookAt += positiveMode ? 1 : -1;
166163
continue;
167164
}
168-
if (theoreticalMasses[0].ToMz(chargeToLookAt) < scanWindowRange.Minimum)
165+
166+
// If m/z is below the scan window, break early, more charge will only make the mz smaller.
167+
if (mz < scanWindowRange.Minimum)
168+
{
169169
break;
170+
}
171+
170172
var trainingPointsToAverage = new List<LabeledDataPoint>();
171173
foreach (double a in theoreticalMasses)
172174
{
@@ -187,15 +189,17 @@ protected override MetaMorpheusEngineResults RunSpecific()
187189
var closestPeakIndex = fullMS1spectrum.GetClosestPeakIndex(theMZ);
188190
var closestPeakMZ = fullMS1spectrum.XArray[closestPeakIndex];
189191

190-
highestKnownChargeForThisPeptide = Math.Max(highestKnownChargeForThisPeptide, chargeToLookAt);
192+
highestKnownChargeForThisPeptide = positiveMode
193+
? Math.Max(highestKnownChargeForThisPeptide, chargeToLookAt)
194+
: Math.Min(highestKnownChargeForThisPeptide, chargeToLookAt);
191195
trainingPointsToAverage.Add(new LabeledDataPoint(closestPeakMZ, -1, double.NaN, double.NaN, Math.Log(fullMS1spectrum.YArray[closestPeakIndex]), theMZ, null));
192196
}
193197
// If started adding and suddenly stopped, go to next one, no need to look at higher charges
194198
if (trainingPointsToAverage.Count == 0 && startingToAddCharges)
195199
{
196200
break;
197201
}
198-
if ((trainingPointsToAverage.Count == 0 || (trainingPointsToAverage.Count == 1 && theoreticalIntensities[0] < 0.65)) && (peptideCharge <= chargeToLookAt))
202+
if ((trainingPointsToAverage.Count == 0 || (trainingPointsToAverage.Count == 1 && theoreticalIntensities[0] < 0.65)) && (positiveMode ? peptideCharge <= chargeToLookAt : peptideCharge >= chargeToLookAt))
199203
{
200204
break;
201205
}
@@ -213,8 +217,8 @@ protected override MetaMorpheusEngineResults RunSpecific()
213217
trainingPointsToAverage.Select(b => b.TheoreticalMz).Average(),
214218
identification));
215219
}
216-
chargeToLookAt++;
217-
} while (chargeToLookAt <= highestKnownChargeForThisPeptide + 1);
220+
chargeToLookAt += positiveMode ? 1 : -1;
221+
} while (positiveMode ? chargeToLookAt <= chargeLimit : chargeToLookAt >= chargeLimit);
218222
theIndex += direction;
219223
}
220224
return (result, numMs1MassChargeCombinationsConsidered, numMs1MassChargeCombinationsThatAreIgnoredBecauseOfTooManyPeaks);
@@ -240,16 +244,17 @@ private static List<LabeledDataPoint> SearchMS2Spectrum(Ms2ScanWithSpecificMass
240244
if(envelopesThatMatch.Count == 0)
241245
continue;
242246
//only allow one envelope per charge state
243-
bool[] chargeStateFound = new bool[envelopesThatMatch.Max(x => x.Charge) + 1];
247+
bool[] chargeStateFound = new bool[envelopesThatMatch.Max(x => Math.Abs(x.Charge)) + 1];
244248

245249
foreach (var envelopeThatMatched in envelopesThatMatch)
246250
{
251+
int charge = Math.Abs(envelopeThatMatched.Charge);
247252
//if we haven't seen this charge state already
248-
if (!chargeStateFound[envelopeThatMatched.Charge])
253+
if (!chargeStateFound[charge])
249254
{
250-
chargeStateFound[envelopeThatMatched.Charge] = true;
255+
chargeStateFound[charge] = true;
251256

252-
double exptPeakMz = envelopeThatMatched.MonoisotopicMass.ToMz(envelopeThatMatched.Charge);
257+
double exptPeakMz = envelopeThatMatched.MonoisotopicMass.ToMz(charge);
253258
double exptPeakIntensity = envelopeThatMatched.TotalIntensity;
254259
double injTime = ms2DataScan.TheScan.InjectionTime ?? double.NaN;
255260

@@ -259,8 +264,8 @@ private static List<LabeledDataPoint> SearchMS2Spectrum(Ms2ScanWithSpecificMass
259264
ms2DataScan.OneBasedScanNumber,
260265
Math.Log(ms2DataScan.TotalIonCurrent),
261266
Math.Log(injTime),
262-
Math.Log(exptPeakIntensity),
263-
matchedIon.NeutralTheoreticalProduct.NeutralMass.ToMz(envelopeThatMatched.Charge),
267+
Math.Log(exptPeakIntensity),
268+
matchedIon.NeutralTheoreticalProduct.NeutralMass.ToMz(charge),
264269
identification));
265270
}
266271
}

MetaMorpheus/GUI/MainWindow.xaml.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
using TaskLayer;
2222
using System.Text.RegularExpressions;
2323
using Readers.InternalResults;
24+
using System.Diagnostics;
2425

2526
namespace MetaMorpheusGUI
2627
{
@@ -1263,8 +1264,35 @@ private void MenuItem_GuiSettings_Click(object sender, RoutedEventArgs e)
12631264

12641265
private void MenuItem_MetaDraw_Click(object sender, RoutedEventArgs e)
12651266
{
1266-
MetaDraw metaDrawGui = new MetaDraw();
1267-
metaDrawGui.Show();
1267+
string[]? filesToLoad = null;
1268+
try
1269+
{
1270+
// get completed search tasks from in progress tasks.
1271+
var completedSearchTasks = InProgressTasks.Where(p => p.Task is SearchTask && p.Progress >= 100).ToList();
1272+
1273+
// find last search task by the task ID
1274+
var finalSearchTask = completedSearchTasks.MaxBy(p => p.Id.Split('-')[0].Replace("Task", "").ToNullableInt());
1275+
1276+
// Get Spectra files
1277+
var prose = MetaMorpheusProseFile.LocateInDirectory(finalSearchTask.Task.OutputFolder);
1278+
var spectraFiles = prose!.SpectraFilePaths;
1279+
1280+
// Get search results
1281+
var searchResult = Directory.GetFiles(finalSearchTask.Task.OutputFolder)
1282+
.First(p => p.EndsWith(".psmtsv") || p.EndsWith(".osmtsv"));
1283+
1284+
filesToLoad = spectraFiles.Append(searchResult).ToArray();
1285+
}
1286+
catch (Exception ex)
1287+
{
1288+
// Something went wrong in trying to find a completed search task.
1289+
// This is expected when we do not have a completed search to parse.
1290+
}
1291+
finally
1292+
{
1293+
MetaDraw metaDrawGui = new MetaDraw(filesToLoad);
1294+
metaDrawGui.Show();
1295+
}
12681296
}
12691297

12701298
private void MenuItem_ResetDefaults_Click(object sender, RoutedEventArgs e)

MetaMorpheus/GUI/MetaDraw/MetaDraw.xaml.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public partial class MetaDraw : Window
4343
private FragmentationReanalysisViewModel FragmentationReanalysisViewModel;
4444
public ChimeraAnalysisTabViewModel ChimeraAnalysisTabViewModel { get; set; }
4545

46-
public MetaDraw()
46+
public MetaDraw(string[]? filesToLoad = null)
4747
{
4848
InitializeComponent();
4949

@@ -77,6 +77,12 @@ public MetaDraw()
7777
plotTypes = new ObservableCollection<string>();
7878
SetUpPlots();
7979
plotsListBox.ItemsSource = plotTypes;
80+
81+
// if files piped in from a MetaMorpheus search, load them immediately
82+
if (filesToLoad is not null)
83+
{
84+
filesToLoad.ForEach(AddFile);
85+
}
8086
}
8187

8288
private void Window_Drop(object sender, DragEventArgs e)

MetaMorpheus/GUI/Views/ProgressBarIndeterminate.xaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
77
xmlns:local="clr-namespace:MetaMorpheusGUI"
88
mc:Ignorable="d"
9-
Title="Progress" Height="115" Width="300">
9+
Title="Progress" Height="115" Width="300"
10+
Topmost="True">
1011
<StackPanel Margin="3">
1112
<Grid Height="20">
1213
<ProgressBar Minimum="0" Maximum="100" Name="pbStatus" IsIndeterminate="True"/>

MetaMorpheus/TaskLayer/CalibrationTask/CalibrationTask.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ private DataPointAquisitionResults GetDataAcquisitionResults(MsDataFile myMsData
268268
new SingleAbsoluteAroundZeroSearchMode(initPrecTol.Value);
269269

270270
Ms2ScanWithSpecificMass[] listOfSortedms2Scans = GetMs2Scans(myMsDataFile, currentDataFile, combinedParameters).OrderBy(b => b.PrecursorMass).ToArray();
271-
SpectralMatch[] allPsmsArray = new PeptideSpectralMatch[listOfSortedms2Scans.Length];
271+
SpectralMatch[] allPsmsArray = new SpectralMatch[listOfSortedms2Scans.Length];
272272

273273
Log("Searching with searchMode: " + searchMode, new List<string> { taskId, "Individual Spectra Files", fileNameWithoutExtension });
274274
Log("Searching with productMassTolerance: " + initProdTol, new List<string> { taskId, "Individual Spectra Files", fileNameWithoutExtension });

MetaMorpheus/TaskLayer/MetaMorpheusTask.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ public abstract class MetaMorpheusTask
139139

140140
protected readonly StringBuilder ProseCreatedWhileRunning = new StringBuilder();
141141

142-
protected string OutputFolder { get; private set; }
142+
[TomlIgnore]
143+
public string OutputFolder { get; private set; }
143144

144145
protected MyTaskResults MyTaskResults;
145146

MetaMorpheus/Test/Test.csproj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,9 @@
652652
<None Update="TopDownTestData\TopDownSearchToml.toml">
653653
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
654654
</None>
655+
<None Update="Transcriptomics\TestData\16mer2.fasta">
656+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
657+
</None>
655658
<None Update="Transcriptomics\TestData\22mer-Am.fasta">
656659
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
657660
</None>
@@ -676,6 +679,9 @@
676679
<None Update="Transcriptomics\TestData\GUACUG_NegativeMode_Sliced.mzML">
677680
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
678681
</None>
682+
<None Update="Transcriptomics\TestData\RnaStandard_Subset.mzML">
683+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
684+
</None>
679685
<None Update="Transcriptomics\TestData\TruncationAndVariantMods.xml">
680686
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
681687
</None>
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
using EngineLayer;
2+
using MassSpectrometry;
3+
using MzLibUtil;
4+
using NUnit.Framework;
5+
using System;
6+
using System.Collections.Generic;
7+
using System.IO;
8+
using System.Linq;
9+
using TaskLayer;
10+
using Transcriptomics.Digestion;
11+
using UsefulProteomicsDatabases;
12+
using Readers;
13+
14+
namespace Test.Transcriptomics;
15+
16+
[TestFixture]
17+
public class TestCalibration
18+
{
19+
public static RnaSearchParameters SearchParameters;
20+
public static CommonParameters CommonParameters;
21+
22+
[OneTimeSetUp]
23+
public static void Setup()
24+
{
25+
SearchParameters = new RnaSearchParameters
26+
{
27+
DecoyType = DecoyType.Reverse,
28+
MassDiffAcceptorType = MassDiffAcceptorType.Exact,
29+
DisposeOfFileWhenDone = true
30+
};
31+
CommonParameters = new CommonParameters
32+
(
33+
dissociationType: DissociationType.CID,
34+
deconvolutionMaxAssumedChargeState: -20,
35+
deconvolutionIntensityRatio: 3,
36+
deconvolutionMassTolerance: new PpmTolerance(20),
37+
precursorMassTolerance: new PpmTolerance(10),
38+
productMassTolerance: new PpmTolerance(5),
39+
scoreCutoff: 5,
40+
totalPartitions: 1,
41+
maxThreadsToUsePerFile: 1,
42+
doPrecursorDeconvolution: true,
43+
useProvidedPrecursorInfo: false,
44+
digestionParams: new RnaDigestionParams()
45+
);
46+
}
47+
48+
[Test]
49+
public void CalibrationTask_ReducesMassError()
50+
{
51+
// Arrange
52+
string testDir = TestContext.CurrentContext.TestDirectory;
53+
List<string> dbPaths =
54+
[Path.Combine(testDir, "Transcriptomics", "TestData", "16mer2.fasta")];
55+
List<string> spectraPaths =
56+
[Path.Combine(testDir, "Transcriptomics", "TestData", "RnaStandard_Subset.mzML")];
57+
string outputDir = Path.Combine(testDir, "CalibrationTest");
58+
59+
if (Directory.Exists(outputDir))
60+
Directory.Delete(outputDir, true); // Clean up previous test run
61+
Directory.CreateDirectory(outputDir);
62+
63+
// Set up search-cali-search task for RNA
64+
var dbs = dbPaths.Select(dbPath => new DbForTask(dbPath, false)).ToList();
65+
var searchTask = new SearchTask()
66+
{
67+
SearchParameters = SearchParameters,
68+
CommonParameters = CommonParameters
69+
};
70+
var cali = new CalibrationTask()
71+
{
72+
CommonParameters = CommonParameters
73+
};
74+
var searchTask2 = new SearchTask()
75+
{
76+
SearchParameters = SearchParameters,
77+
CommonParameters = CommonParameters
78+
};
79+
var runner = new EverythingRunnerEngine(new List<(string, MetaMorpheusTask)>()
80+
{
81+
("Search1", searchTask),
82+
("Calibration", cali),
83+
("Search2", searchTask2)
84+
}, spectraPaths, dbs, outputDir);
85+
runner.Run();
86+
87+
var firstSearchDir = Path.Combine(outputDir, "Search1");
88+
var firstOsmPath = Directory.GetFiles(firstSearchDir, "*OSMs.osmtsv", SearchOption.AllDirectories).First();
89+
var firstOsms = SpectrumMatchTsvReader.ReadTsv(firstOsmPath, out var warnings);
90+
Assert.That(warnings.Count, Is.EqualTo(0));
91+
92+
var secondSearchDir = Path.Combine(outputDir, "Search2");
93+
var secondOsmPath = Directory.GetFiles(secondSearchDir, "*OSMs.osmtsv", SearchOption.AllDirectories).First();
94+
var secondOsms = SpectrumMatchTsvReader.ReadTsv(secondOsmPath, out warnings);
95+
Assert.That(warnings.Count, Is.EqualTo(0));
96+
97+
// Assert that calibration increased search results
98+
Assert.That(secondOsms.Count, Is.GreaterThan(firstOsms.Count), "Expected more OligoSpectralMatches after calibration.");
99+
Assert.That(secondOsms.Count(p => p.QValue <= 0.01), Is.GreaterThan(firstOsms.Count(p => p.QValue <= 0.01)),
100+
"Expected more OligoSpectralMatches with QValue <= 0.01 after calibration.");
101+
102+
// Assert that the mass error is reduced after calibration
103+
var firstErrors = firstOsms.Select(p => p.MassDiffDa)
104+
.Select(double.Parse)
105+
.ToList();
106+
var secondErrors = secondOsms.Select(p => p.MassDiffDa)
107+
.Select(double.Parse)
108+
.ToList();
109+
110+
var firstAverage = firstErrors.Average();
111+
var secondAverage = secondErrors.Average();
112+
113+
Assert.That(secondAverage, Is.LessThan(firstAverage),
114+
"Expected average mass error to be reduced after calibration.");
115+
116+
Directory.Delete(outputDir, true); // Clean up after test
117+
}
118+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
>id:9|Name:16mer1|SOterm:16mer1|Type:tRNA|Subtype:Ala|Feature:VGC|Cellular_Localization:freezer|Species:standard
2+
AUCCAGUGCAGUACUG

0 commit comments

Comments
 (0)