Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
return false;

IndexedPeaks = new List<T>[(int)Math.Ceiling(scanArray.Where(p => p != null
&& p.MassSpectrum.LastX != null).Max(p => p.MassSpectrum.LastX.Value) * BinsPerDalton) + 1];

Check warning on line 33 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Nullable value type may be null.

Check warning on line 33 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Nullable value type may be null.

Check warning on line 33 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Nullable value type may be null.
ScanInfoArray = new ScanInfo[scanArray.Length];

for (int scanIndex = 0; scanIndex < scanArray.Length; scanIndex++)
Expand Down Expand Up @@ -85,7 +85,7 @@
/// <param name="matchedPeaks"> the dictionary that stores all the peaks already matched to an xic </param>
/// <returns> A list of IIndexedPeak objects, ordered by retention time </returns>
public List<IIndexedPeak> GetXic(double m, double retentionTime, Tolerance ppmTolerance,
int missedScansAllowed, double maxPeakHalfWidth = double.MaxValue, int? charge = null, Dictionary<IIndexedPeak, ExtractedIonChromatogram> matchedPeaks = null)

Check warning on line 88 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 88 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 88 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Cannot convert null literal to non-nullable reference type.
{
// get precursor scan to start at
int scanIndex = -1;
Expand Down Expand Up @@ -120,7 +120,7 @@
/// <param name="charge"> an optional parameter used only for IIndexedMass and massIndexingEngine; must be null for mz peak indexing </param>
/// <param name="matchedPeaks"> the dictionary that stores all the peaks already matched to an xic </param>
/// <returns> A list of IIndexedPeak objects, ordered by retention time </returns>
public List<IIndexedPeak> GetXicByScanIndex(double m, int zeroBasedStartIndex, Tolerance ppmTolerance, int missedScansAllowed, double maxPeakHalfWidth = double.MaxValue, int? charge = null, Dictionary<IIndexedPeak, ExtractedIonChromatogram> matchedPeaks = null)

Check warning on line 123 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 123 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Cannot convert null literal to non-nullable reference type.

Check warning on line 123 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Cannot convert null literal to non-nullable reference type.
{
if (IndexedPeaks == null || ScanInfoArray == null) throw new MzLibException("Error: Attempt to retrieve XIC before peak indexing was performed");

Expand All @@ -134,7 +134,7 @@
var initialPeak = GetBestPeakFromBins(allBins, m, zeroBasedStartIndex, peakPointerArray, ppmTolerance, charge);

if (initialPeak.IsNotDefaultOrNull())
xic.Add(initialPeak);

Check warning on line 137 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'item' in 'void List<IIndexedPeak>.Add(IIndexedPeak item)'.

Check warning on line 137 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'item' in 'void List<IIndexedPeak>.Add(IIndexedPeak item)'.

Check warning on line 137 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Possible null reference argument for parameter 'item' in 'void List<IIndexedPeak>.Add(IIndexedPeak item)'.

foreach (int direction in new List<int> { -1, 1 })
{
Expand All @@ -148,7 +148,7 @@
{
// increment the scan index we're searching for
currentZeroBasedScanIndex += direction;
if(currentZeroBasedScanIndex < 0 || currentZeroBasedScanIndex > ScanInfoArray.Length - 1 || (initialPeak.IsNotDefaultOrNull() && ScanInfoArray[currentZeroBasedScanIndex] != null && Math.Abs(ScanInfoArray[currentZeroBasedScanIndex].RetentionTime - initialPeak.RetentionTime) > maxPeakHalfWidth))

Check warning on line 151 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 151 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Dereference of a possibly null reference.

Check warning on line 151 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Dereference of a possibly null reference.
break;

for (int i = 0; i < pointerArrayCopy.Length; i++)
Expand Down Expand Up @@ -195,11 +195,11 @@
/// A generic method performing peak tracing for all the peaks in an indexingEngine and trying to find all XICs.
/// <param name="cutPeakDiscriminationFactor"> The discrimination factor to determine if a peak should be cut if we are doing peak cutting </param>
/// <returns> A list of ExtractedIonChromatogram objects representing all XICs that can be found in an indexingEngine </returns>
public virtual List<ExtractedIonChromatogram> GetAllXics(Tolerance peakFindingTolerance, int maxMissedScanAllowed, double maxRTRange, int numPeakThreshold, double? cutPeakDiscriminationFactor = null)
public virtual List<ExtractedIonChromatogram> GetAllXics(Tolerance peakFindingTolerance, int maxMissedScanAllowed, double maxRTRange, int numPeakThreshold, out Dictionary<IIndexedPeak, ExtractedIonChromatogram> matchedPeaks, double? cutPeakDiscriminationFactor = null)

Copilot AI Oct 21, 2025

Copy link

Choose a reason for hiding this comment

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

The optional parameter cutPeakDiscriminationFactor should appear before the out parameter matchedPeaks. In C#, optional parameters must come after all required parameters, but out parameters are considered required. The current ordering violates this convention and could cause API confusion.

Copilot uses AI. Check for mistakes.
{
var xics = new List<ExtractedIonChromatogram>();
var matchedPeaks = new Dictionary<IIndexedPeak, ExtractedIonChromatogram>();
matchedPeaks = new Dictionary<IIndexedPeak, ExtractedIonChromatogram>();
var sortedPeaks = IndexedPeaks.Where(v => v != null).SelectMany(peaks => peaks).OrderByDescending(p => p.Intensity).ToList();

Check warning on line 202 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'source' in 'IEnumerable<List<T>> Enumerable.Where<List<T>>(IEnumerable<List<T>> source, Func<List<T>, bool> predicate)'.

Check warning on line 202 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference argument for parameter 'source' in 'IEnumerable<List<T>> Enumerable.Where<List<T>>(IEnumerable<List<T>> source, Func<List<T>, bool> predicate)'.

Check warning on line 202 in mzLib/MassSpectrometry/PeakIndexing/IndexingEngine.cs

View workflow job for this annotation

GitHub Actions / integration

Possible null reference argument for parameter 'source' in 'IEnumerable<List<T>> Enumerable.Where<List<T>>(IEnumerable<List<T>> source, Func<List<T>, bool> predicate)'.
foreach (var peak in sortedPeaks)
{
if (!matchedPeaks.ContainsKey(peak))
Expand Down
17 changes: 9 additions & 8 deletions mzLib/Test/TestXic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -147,18 +147,19 @@ public static void TestGetAllXics()
{
//Test case using FakeScans
var indexingEngine = PeakIndexingEngine.InitializeIndexingEngine(testScans);
var xics = indexingEngine.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var xics = indexingEngine.GetAllXics(new PpmTolerance(20), 2, 2, 3, out var matchedPeaks);
Assert.That(xics.Count, Is.EqualTo(20));
foreach(var xic in xics)
{
Assert.That(xic.Peaks.Count, Is.EqualTo(10));
}
Assert.That(matchedPeaks.Count, Is.EqualTo(xics.Sum(xic => xic.Peaks.Count)));

//Test with massIndexingEngine
var deconParameters = new ClassicDeconvolutionParameters(1, 20, 4, 3);
var allMasses = Deconvoluter.Deconvolute(testScans[0].MassSpectrum, deconParameters);
var massIndexingEngine = MassIndexingEngine.InitializeMassIndexingEngine(testScans, deconParameters);
var massXics = massIndexingEngine.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var massXics = massIndexingEngine.GetAllXics(new PpmTolerance(20), 2, 2, 3, out matchedPeaks);
Assert.That(massXics.Count, Is.EqualTo(2));
foreach (var mass in allMasses)
{
Expand All @@ -179,12 +180,12 @@ public static void TestGetAllXics()
mzAnalyzer: MZAnalyzerType.Orbitrap, totalIonCurrent: 1, injectionTime: 1.0, noiseData: null, nativeId: "scan=" + (s + 1));
}
var indexingEngine2 = PeakIndexingEngine.InitializeIndexingEngine(fakeScans2);
var xics2 = indexingEngine2.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var xics2 = indexingEngine2.GetAllXics(new PpmTolerance(20), 2, 2, 3, out matchedPeaks);
Assert.That(xics2.Count, Is.EqualTo(40)); //the first three scans and the last four scans will each contain two XICs
Assert.That(xics2.SequenceEqual(xics2.OrderByDescending(x => x.ApexPeak.Intensity)));//make sure the XICs are ordered by descending apex intensity
//Test with massIndexingEngine
var massIndexingEngine2 = MassIndexingEngine.InitializeMassIndexingEngine(fakeScans2, deconParameters);
var massXics2 = massIndexingEngine2.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var massXics2 = massIndexingEngine2.GetAllXics(new PpmTolerance(20), 2, 2, 3, out matchedPeaks);
Assert.That(massXics2.Count, Is.EqualTo(4));

var fakeScans3 = (MsDataScan[])testScans.Clone();
Expand All @@ -195,15 +196,15 @@ public static void TestGetAllXics()
mzAnalyzer: MZAnalyzerType.Orbitrap, totalIonCurrent: 1, injectionTime: 1.0, noiseData: null, nativeId: "scan=" + (s + 1));
}
var indexingEngine3 = PeakIndexingEngine.InitializeIndexingEngine(fakeScans3);
var xics3 = indexingEngine3.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var xics3 = indexingEngine3.GetAllXics(new PpmTolerance(20), 2, 2, 3, out matchedPeaks);
Assert.That(xics3.Count, Is.EqualTo(20)); // Because the minumum number of peaks required is set to 3, the first two scans do not contain any XICs with only two consecutive peaks.
foreach (var xic in xics3)
{
Assert.That(xic.Peaks.Count, Is.EqualTo(5));
}
//Test with massIndexingEngine
var massIndexingEngine3 = MassIndexingEngine.InitializeMassIndexingEngine(fakeScans3, deconParameters);
var massXics3 = massIndexingEngine3.GetAllXics(new PpmTolerance(20), 2, 2, 3);
var massXics3 = massIndexingEngine3.GetAllXics(new PpmTolerance(20), 2, 2, 3, out matchedPeaks);
Assert.That(massXics3.Count, Is.EqualTo(2));
foreach (var xic in massXics3)
{
Expand Down Expand Up @@ -275,14 +276,14 @@ public static void TestGetAllXicsWithCutPeak()
testScans[s] = new MsDataScan(massSpectrum: new MzSpectrum(mz, intensities, false), oneBasedScanNumber: s + 1, msnOrder: 1, isCentroid: true,polarity: Polarity.Positive, retentionTime: 1.0 + s / 10.0, scanWindowRange: new MzRange(400, 1600), scanFilter: "f",mzAnalyzer: MZAnalyzerType.Orbitrap, totalIonCurrent: intensities.Sum(), injectionTime: 1.0, noiseData: null, nativeId: "scan=" + (s + 1));
}
var indexingEngine = PeakIndexingEngine.InitializeIndexingEngine(testScans);
var xics = indexingEngine.GetAllXics(new PpmTolerance(5), 2, 3, 3);
var xics = indexingEngine.GetAllXics(new PpmTolerance(5), 2, 3, 3, out var matchedPeaks);
// 10 XICs should be found without peak cutting, each containing 10 peaks
Assert.That(xics.Count(), Is.EqualTo(10));
Assert.That(xics.All(x => x.Peaks.Count == 10), Is.True);
//The XICs should have an apex at the eighth scan
Assert.That(xics.All(x => x.ApexScanIndex == 7), Is.True);

var xicsWithCutPeak = indexingEngine.GetAllXics(new PpmTolerance(5), 2, 3, 3, 0.6);
var xicsWithCutPeak = indexingEngine.GetAllXics(new PpmTolerance(5), 2, 3, 3, out matchedPeaks, 0.6);
// since each original XIC contain two apex, cutting peaks should double the number of XICs found and each XIC should contain 5 peaks now
Assert.That(xicsWithCutPeak.Count(), Is.EqualTo(20));
Assert.That(xicsWithCutPeak.All(x => x.Peaks.Count == 5), Is.True);
Expand Down
Loading