/// <summary> /// The score feature. /// </summary> /// <param name="peak"> /// The peak. /// </param> /// <param name="globalMaxIntensity"> /// The global max intensity. /// </param> /// <param name="uimfReader"> /// The uimf reader. /// </param> /// <param name="massToleranceInPpm"> /// The mass tolerance in ppm. /// </param> /// <param name="driftTimeToleranceInMs"> /// The drift time tolerance in ms. /// </param> /// <param name="voltageGroup"> /// The voltage group. /// </param> /// <param name="voltageGroupScans"> /// The voltage group scans. /// </param> /// <param name="target"> /// The target. /// </param> /// <param name="isotopicScoreMethod"> /// The isotopic score method. /// </param> /// <param name="theoreticalIsotopicProfile"> /// The theoretical isotopic profile. /// </param> /// <returns> /// The <see cref="PeakScores"/>. /// </returns> public static PeakScores ScoreFeature(this StandardImsPeak peak, double globalMaxIntensity, DataReader uimfReader, double massToleranceInPpm, double driftTimeToleranceInMs, VoltageGroup voltageGroup, int voltageGroupScans, IImsTarget target, IsotopicScoreMethod isotopicScoreMethod, List<Peak> theoreticalIsotopicProfile) { double intensityScore = IntensityScore(peak, globalMaxIntensity); double peakShapeScore = PeakShapeScore( peak, uimfReader, massToleranceInPpm, driftTimeToleranceInMs, voltageGroup, globalMaxIntensity, voltageGroupScans); double isotopicScore = 0; if (target.HasCompositionInfo) { isotopicScore = IsotopicProfileScore( peak, uimfReader, target, theoreticalIsotopicProfile, voltageGroup, IsotopicScoreMethod.Angle, globalMaxIntensity, voltageGroupScans); } return new PeakScores(intensityScore, isotopicScore, peakShapeScore); }
/// <summary> /// The score feature using isotopic profile. /// </summary> /// <param name="imsPeak"> /// The ims Peak. /// </param> /// <param name="reader"> /// The reader. /// </param> /// <param name="target"> /// The Target. /// </param> /// <param name="isotopicPeakList"> /// The isotopic peak list. /// </param> /// <param name="voltageGroup"> /// The voltage Group. /// </param> /// <param name="selectedMethod"> /// The selected Method. /// </param> /// <param name="globalMaxIntensities"> /// </param> /// <returns> /// The <see cref="double"/>. /// </returns> /// <exception cref="InvalidOperationException"> /// </exception> public static double IsotopicProfileScore(StandardImsPeak imsPeak, DataReader reader, IImsTarget target, List<Peak> isotopicPeakList, VoltageGroup voltageGroup, IsotopicScoreMethod selectedMethod, double globalMaxIntensities, double totalScans) { // No need to move on if the isotopic profile is not found // if (observedIsotopicProfile == null || observedIsotopicProfile.MonoIsotopicMass < 1) // { // result.AnalysisStatus = AnalysisStatus.IsotopicProfileNotFound; // continue; // } // Find Isotopic Profile // List<Peak> massSpectrumPeaks; // IsotopicProfile observedIsotopicProfile = _msFeatureFinder.IterativelyFindMSFeature(massSpectrum, theoreticalIsotopicProfile, out massSpectrumPeaks); if (target.CompositionWithoutAdduct == null) { throw new InvalidOperationException("Cannot score feature using isotopic profile for Ims Target without CompositionWithoutAdduct provided."); } // Bad Feature, so get out if (imsPeak == null) { return 0; } // Get the scanWindow size int scanNumberMax = imsPeak.PeakApex.DriftTimeFullWidthHalfMaxHigherBondInScanNumber; int scanNumberMin = imsPeak.PeakApex.DriftTimeFullWidthHalfMaxLowerBondInScanNumber; if ((scanNumberMin < 0) || (scanNumberMax > totalScans - 1)) { return 0; } // Get the mass error from the observed feature peak from the Target theoretical peak double mzOffset = imsPeak.PeakApex.MzCenterInDalton - target.MassWithAdduct; List<double> observedIsotopicPeakList = new List<double>(); int totalIsotopicIndex = isotopicPeakList.Count; int[] isotopicIndexMask = new int[totalIsotopicIndex]; // Find an unsaturated peak in the isotopic profile for (int i = 0; i < totalIsotopicIndex; i++) { // Isotopic centerMz double Mz = isotopicPeakList[i].XValue; var peakList = reader.GetXic(Mz + mzOffset, imsPeak.PeakApex.MzWindowToleranceInPpm, voltageGroup.FirstFrameNumber, voltageGroup.LastFrameNumber, scanNumberMin, scanNumberMax, DataReader.FrameType.MS1, DataReader.ToleranceType.PPM); // Sum the intensities double sumIntensities = 0; foreach (var point in peakList) { sumIntensities += point.Intensity; if (point.IsSaturated) { isotopicIndexMask[i] = 1; } } sumIntensities /= voltageGroup.FrameAccumulationCount; observedIsotopicPeakList.Add(sumIntensities); } // Return 0 if the intensity sum is really small if (observedIsotopicPeakList.Sum() < globalMaxIntensities * 0.0003) { return 0; } // If the unsaturated isotopes are below a certain threshold if (totalIsotopicIndex - isotopicIndexMask.Sum() <= 1) { return 0; } if (selectedMethod == IsotopicScoreMethod.Angle) { return IsotopicProfileScoreAngle(observedIsotopicPeakList, isotopicPeakList); } else if (selectedMethod == IsotopicScoreMethod.EuclideanDistance) { return IsotopicProfileScoreEuclidean(observedIsotopicPeakList, isotopicPeakList); } else if (selectedMethod == IsotopicScoreMethod.PearsonCorrelation) { return PearsonCorrelation(observedIsotopicPeakList, isotopicPeakList); } else if (selectedMethod == IsotopicScoreMethod.Bhattacharyya) { return BhattacharyyaDistance(observedIsotopicPeakList, isotopicPeakList); } else if (selectedMethod == IsotopicScoreMethod.EuclideanDistanceAlternative) { return EuclideanAlternative(observedIsotopicPeakList, isotopicPeakList); } else { throw new NotImplementedException(); } }