예제 #1
0
        private bool FindClosestMZ(
            clsSpectraCache spectraCache,
            IList <clsScanInfo> scanList,
            int spectrumIndex,
            double searchMZ,
            double toleranceMZ,
            out double bestMatchMZ)
        {
            bool success;

            bestMatchMZ = 0;
            try
            {
                if (scanList[spectrumIndex].IonCount == 0 && scanList[spectrumIndex].IonCountRaw == 0)
                {
                    // No data in this spectrum
                    success = false;
                }
                else if (!spectraCache.GetSpectrum(scanList[spectrumIndex].ScanNumber, out var spectrum, canSkipPool: true))
                {
                    SetLocalErrorCode(clsMASIC.eMasicErrorCodes.ErrorUncachingSpectrum);
                    success = false;
                }
                else
                {
                    success = FindClosestMZ(spectrum.IonsMZ, spectrum.IonCount, searchMZ, toleranceMZ, out bestMatchMZ);
                }
            }
예제 #2
0
        /// <summary>
        /// Searches currentScan.IonsMZ for the maximum intensity value between mzStart and mzEnd
        /// If a match is found, updates bestMatchMZ to the m/z of the match,
        /// updates matchIntensity to its intensity, and returns True
        /// </summary>
        /// <param name="spectraCache"></param>
        /// <param name="currentScan"></param>
        /// <param name="mzStart"></param>
        /// <param name="mzEnd"></param>
        /// <param name="bestMatchMZ">Output: m/z of the most intense ion in the given range</param>
        /// <param name="matchIntensity">Output: intensity of the most intense ion in the given range</param>
        /// <returns>True if a match is found, false if no data exists within the m/z range (or if the spectrum could not be obtained)</returns>
        /// <remarks>
        /// Note that this function performs a linear search of .IonsMZ
        /// It is therefore good for spectra with less than 10 data points and bad for spectra with more than 10 data points
        /// As an alternative to this function, use AggregateIonsInRange
        /// </remarks>
        public bool FindMaxValueInMZRange(
            clsSpectraCache spectraCache,
            clsScanInfo currentScan,
            double mzStart,
            double mzEnd,
            out double bestMatchMZ,
            out double matchIntensity)
        {
            bestMatchMZ    = 0;
            matchIntensity = 0;
            try
            {
                if (!spectraCache.GetSpectrum(currentScan.ScanNumber, out var spectrum, true))
                {
                    OnErrorEvent("Error uncaching scan " + currentScan.ScanNumber);
                    return(false);
                }

                var success = FindMaxValueInMZRange(
                    spectrum.IonsMZ,
                    spectrum.IonsIntensity,
                    spectrum.IonCount,
                    mzStart, mzEnd,
                    out bestMatchMZ, out matchIntensity);

                return(success);
            }
            catch (Exception ex)
            {
                OnErrorEvent("Error in FindMaxValueInMZRange (A): " + ex.Message, ex);
                return(false);
            }
        }
예제 #3
0
        /// <summary>
        /// Looks for the reporter ion m/z values, +/- a tolerance
        /// Calls AggregateIonsInRange with returnMax = True, meaning we're reporting the maximum ion abundance for each reporter ion m/z
        /// </summary>
        /// <param name="rawFileReader"></param>
        /// <param name="dataAggregation"></param>
        /// <param name="includeFtmsColumns"></param>
        /// <param name="sicOptions"></param>
        /// <param name="scanList"></param>
        /// <param name="spectraCache"></param>
        /// <param name="currentScan"></param>
        /// <param name="writer"></param>
        /// <param name="reporterIons"></param>
        /// <param name="delimiter"></param>
        /// <param name="saveUncorrectedIntensities"></param>
        /// <param name="saveObservedMasses"></param>
        /// <remarks></remarks>
        private void FindReporterIonsWork(
            XRawFileIO rawFileReader,
            clsDataAggregation dataAggregation,
            bool includeFtmsColumns,
            clsSICOptions sicOptions,
            clsScanList scanList,
            clsSpectraCache spectraCache,
            clsScanInfo currentScan,
            TextWriter writer,
            IList <clsReporterIonInfo> reporterIons,
            char delimiter,
            bool saveUncorrectedIntensities,
            bool saveObservedMasses)
        {
            const bool USE_MAX_ABUNDANCE_IN_WINDOW = true;

            // The following will be a value between 0 and 100
            // Using Absolute Value of percent change to avoid averaging both negative and positive values
            double parentIonMZ;

            if (currentScan.FragScanInfo.ParentIonInfoIndex >= 0 && currentScan.FragScanInfo.ParentIonInfoIndex < scanList.ParentIons.Count)
            {
                parentIonMZ = scanList.ParentIons[currentScan.FragScanInfo.ParentIonInfoIndex].MZ;
            }
            else
            {
                parentIonMZ = 0;
            }

            if (!spectraCache.GetSpectrum(currentScan.ScanNumber, out var spectrum, true))
            {
                SetLocalErrorCode(clsMASIC.eMasicErrorCodes.ErrorUncachingSpectrum);
                return;
            }

            // Initialize the arrays used to track the observed reporter ion values
            var reporterIntensities          = new double[reporterIons.Count];
            var reporterIntensitiesCorrected = new double[reporterIons.Count];
            var closestMZ = new double[reporterIons.Count];

            // Initialize the output variables
            var dataColumns = new List <string>()
            {
                sicOptions.DatasetID.ToString(),
                currentScan.ScanNumber.ToString(),
                currentScan.FragScanInfo.CollisionMode,
                StringUtilities.DblToString(parentIonMZ, 2),
                StringUtilities.DblToString(currentScan.BasePeakIonIntensity, 2),
                StringUtilities.DblToString(currentScan.BasePeakIonMZ, 4)
            };

            var reporterIntensityList    = new List <string>(reporterIons.Count);
            var obsMZList                = new List <string>(reporterIons.Count);
            var uncorrectedIntensityList = new List <string>(reporterIons.Count);

            var ftmsSignalToNoise = new List <string>(reporterIons.Count);
            var ftmsResolution    = new List <string>(reporterIons.Count);
            //var ftmsLabelDataMz = new List<string>(reporterIons.Count);

            double reporterIntensityMax = 0;

            // Find the reporter ion intensities
            // Also keep track of the closest m/z for each reporter ion
            // Note that we're using the maximum intensity in the range (not the sum)
            for (var reporterIonIndex = 0; reporterIonIndex < reporterIons.Count; reporterIonIndex++)
            {
                var ion = reporterIons[reporterIonIndex];
                // Search for the reporter ion MZ in this mass spectrum
                reporterIntensities[reporterIonIndex] = dataAggregation.AggregateIonsInRange(
                    spectrum,
                    ion.MZ,
                    ion.MZToleranceDa,
                    out _,
                    out closestMZ[reporterIonIndex],
                    USE_MAX_ABUNDANCE_IN_WINDOW);

                ion.SignalToNoise = 0;
                ion.Resolution    = 0;
                ion.LabelDataMZ   = 0;
            }

            if (includeFtmsColumns && currentScan.IsFTMS)
            {
                // Retrieve the label data for this spectrum

                rawFileReader.GetScanLabelData(currentScan.ScanNumber, out var ftLabelData);

                // Find each reporter ion in ftLabelData

                for (var reporterIonIndex = 0; reporterIonIndex < reporterIons.Count; reporterIonIndex++)
                {
                    var mzToFind         = reporterIons[reporterIonIndex].MZ;
                    var mzToleranceDa    = reporterIons[reporterIonIndex].MZToleranceDa;
                    var highestIntensity = 0.0;
                    var udtBestMatch     = new udtFTLabelInfoType();
                    var matchFound       = false;

                    foreach (var labelItem in ftLabelData)
                    {
                        // Compare labelItem.Mass (which is m/z of the ion in labelItem) to the m/z of the current reporter ion
                        if (Math.Abs(mzToFind - labelItem.Mass) > mzToleranceDa)
                        {
                            continue;
                        }

                        // m/z is within range
                        if (labelItem.Intensity > highestIntensity)
                        {
                            udtBestMatch     = labelItem;
                            highestIntensity = labelItem.Intensity;
                            matchFound       = true;
                        }
                    }

                    if (matchFound)
                    {
                        reporterIons[reporterIonIndex].SignalToNoise = udtBestMatch.SignalToNoise;
                        reporterIons[reporterIonIndex].Resolution    = udtBestMatch.Resolution;
                        reporterIons[reporterIonIndex].LabelDataMZ   = udtBestMatch.Mass;
                    }
                }
            }

            // Populate reporterIntensitiesCorrected with the data in reporterIntensities
            Array.Copy(reporterIntensities, reporterIntensitiesCorrected, reporterIntensities.Length);
            if (mOptions.ReporterIons.ReporterIonApplyAbundanceCorrection)
            {
                if (mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.ITraqFourMZ ||
                    mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.ITraqEightMZHighRes ||
                    mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.ITraqEightMZLowRes ||
                    mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTTenMZ ||
                    mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTElevenMZ ||
                    mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTSixteenMZ)
                {
                    // Correct the reporter ion intensities using the Reporter Ion Intensity Corrector class

                    if (intensityCorrector.ReporterIonMode != mOptions.ReporterIons.ReporterIonMassMode ||
                        intensityCorrector.ITraq4PlexCorrectionFactorType != mOptions.ReporterIons.ReporterIonITraq4PlexCorrectionFactorType)
                    {
                        intensityCorrector.UpdateReporterIonMode(
                            mOptions.ReporterIons.ReporterIonMassMode,
                            mOptions.ReporterIons.ReporterIonITraq4PlexCorrectionFactorType);
                    }

                    // Count the number of non-zero data points in reporterIntensitiesCorrected()
                    var positiveCount = 0;
                    for (var reporterIonIndex = 0; reporterIonIndex < reporterIons.Count; reporterIonIndex++)
                    {
                        if (reporterIntensitiesCorrected[reporterIonIndex] > 0)
                        {
                            positiveCount += 1;
                        }
                    }

                    // Apply the correction if 2 or more points are non-zero
                    if (positiveCount >= 2)
                    {
                        intensityCorrector.ApplyCorrection(reporterIntensitiesCorrected);
                    }
                }
            }

            // Now construct the string of intensity values, delimited by delimiter
            // Will also compute the percent change in intensities

            // Initialize the variables used to compute the weighted average percent change
            double pctChangeSum         = 0;
            double originalIntensitySum = 0;

            for (var reporterIonIndex = 0; reporterIonIndex < reporterIons.Count; reporterIonIndex++)
            {
                if (!reporterIons[reporterIonIndex].ContaminantIon)
                {
                    // Update the PctChange variables and the IntensityMax variable only if this is not a Contaminant Ion

                    originalIntensitySum += reporterIntensities[reporterIonIndex];

                    if (reporterIntensities[reporterIonIndex] > 0)
                    {
                        // Compute the percent change, then update pctChangeSum
                        var pctChange =
                            (reporterIntensitiesCorrected[reporterIonIndex] - reporterIntensities[reporterIonIndex]) /
                            reporterIntensities[reporterIonIndex];

                        // Using Absolute Value here to prevent negative changes from cancelling out positive changes
                        pctChangeSum += Math.Abs(pctChange * reporterIntensities[reporterIonIndex]);
                    }

                    if (reporterIntensitiesCorrected[reporterIonIndex] > reporterIntensityMax)
                    {
                        reporterIntensityMax = reporterIntensitiesCorrected[reporterIonIndex];
                    }
                }

                if (!reporterIons[reporterIonIndex].ContaminantIon || saveUncorrectedIntensities)
                {
                    // Append the reporter ion intensity to reporterIntensityList
                    // We skip contaminant ions, unless saveUncorrectedIntensities is True, then we include them

                    reporterIntensityList.Add(StringUtilities.DblToString(reporterIntensitiesCorrected[reporterIonIndex], 2));

                    if (saveObservedMasses)
                    {
                        // Append the observed reporter mass value to obsMZList
                        obsMZList.Add(StringUtilities.DblToString(closestMZ[reporterIonIndex], 3));
                    }

                    if (saveUncorrectedIntensities)
                    {
                        // Append the original, uncorrected intensity value
                        uncorrectedIntensityList.Add(StringUtilities.DblToString(reporterIntensities[reporterIonIndex], 2));
                    }

                    if (includeFtmsColumns)
                    {
                        if (Math.Abs(reporterIons[reporterIonIndex].SignalToNoise) < float.Epsilon &&
                            Math.Abs(reporterIons[reporterIonIndex].Resolution) < float.Epsilon &&
                            Math.Abs(reporterIons[reporterIonIndex].LabelDataMZ) < float.Epsilon)
                        {
                            // A match was not found in the label data; display blanks (not zeroes)
                            ftmsSignalToNoise.Add(string.Empty);
                            ftmsResolution.Add(string.Empty);
                            //ftmsLabelDataMz.Add(string.Empty);
                        }
                        else
                        {
                            ftmsSignalToNoise.Add(StringUtilities.DblToString(reporterIons[reporterIonIndex].SignalToNoise, 2));
                            ftmsResolution.Add(StringUtilities.DblToString(reporterIons[reporterIonIndex].Resolution, 2));
                            //ftmsLabelDataMz.Add(StringUtilities.DblToString(reporterIons(reporterIonIndex).LabelDataMZ, 4));
                        }
                    }
                }
            }

            // Compute the weighted average percent intensity correction value
            float weightedAvgPctIntensityCorrection;

            if (originalIntensitySum > 0)
            {
                weightedAvgPctIntensityCorrection = (float)(pctChangeSum / originalIntensitySum * 100);
            }
            else
            {
                weightedAvgPctIntensityCorrection = 0;
            }

            // Resize the target list capacity to large enough to hold all data.
            dataColumns.Capacity = reporterIntensityList.Count + 3 + obsMZList.Count + uncorrectedIntensityList.Count +
                                   ftmsSignalToNoise.Count + ftmsResolution.Count;
            // Append the maximum reporter ion intensity then the individual reporter ion intensities
            dataColumns.Add(StringUtilities.DblToString(reporterIntensityMax, 2));
            dataColumns.AddRange(reporterIntensityList);

            // Append the weighted average percent intensity correction
            if (weightedAvgPctIntensityCorrection < float.Epsilon)
            {
                dataColumns.Add("0");
            }
            else
            {
                dataColumns.Add(StringUtilities.DblToString(weightedAvgPctIntensityCorrection, 1));
            }

            if (saveObservedMasses)
            {
                dataColumns.AddRange(obsMZList);
            }

            if (saveUncorrectedIntensities)
            {
                dataColumns.AddRange(uncorrectedIntensityList);
            }

            if (includeFtmsColumns)
            {
                dataColumns.AddRange(ftmsSignalToNoise);
                dataColumns.AddRange(ftmsResolution);

                // Uncomment to include the label data m/z value in the _ReporterIons.txt file
                //if (saveObservedMasses)
                //    dataColumns.AddRange(ftmsLabelDataMz)
            }

            writer.WriteLine(string.Join(delimiter.ToString(), dataColumns));
        }
예제 #4
0
        private float CompareFragSpectraForParentIons(
            clsScanList scanList,
            clsSpectraCache spectraCache,
            int parentIonIndex1,
            int parentIonIndex2,
            clsBinningOptions binningOptions,
            MASICPeakFinder.clsBaselineNoiseOptions noiseThresholdOptions,
            DataInput.clsDataImport dataImportUtilities)
        {
            // Compare the fragmentation spectra for the two parent ions
            // Returns the highest similarity score (ranging from 0 to 1)
            // Returns 0 if no similarity or no spectra to compare
            // Returns -1 if an error

            float highestSimilarityScore;

            try
            {
                if (scanList.ParentIons[parentIonIndex1].CustomSICPeak || scanList.ParentIons[parentIonIndex2].CustomSICPeak)
                {
                    // Custom SIC values do not have fragmentation spectra; nothing to compare
                    highestSimilarityScore = 0;
                }
                else if (scanList.ParentIons[parentIonIndex1].MRMDaughterMZ > 0 || scanList.ParentIons[parentIonIndex2].MRMDaughterMZ > 0)
                {
                    // MRM Spectra should not be compared
                    highestSimilarityScore = 0;
                }
                else
                {
                    highestSimilarityScore = 0;
                    foreach (var fragSpectrumIndex1 in scanList.ParentIons[parentIonIndex1].FragScanIndices)
                    {
                        if (!spectraCache.GetSpectrum(scanList.FragScans[fragSpectrumIndex1].ScanNumber, out var spectrum1, false))
                        {
                            SetLocalErrorCode(clsMASIC.eMasicErrorCodes.ErrorUncachingSpectrum);
                            return(-1);
                        }

                        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                        if (!clsMASIC.DISCARD_LOW_INTENSITY_MSMS_DATA_ON_LOAD)
#pragma warning disable 162
                        // ReSharper disable HeuristicUnreachableCode
                        {
                            dataImportUtilities.DiscardDataBelowNoiseThreshold(spectrum1, scanList.FragScans[fragSpectrumIndex1].BaselineNoiseStats.NoiseLevel, 0, 0, noiseThresholdOptions);
                        }
                        // ReSharper restore HeuristicUnreachableCode
#pragma warning restore 162

                        foreach (var fragSpectrumIndex2 in scanList.ParentIons[parentIonIndex2].FragScanIndices)
                        {
                            if (!spectraCache.GetSpectrum(scanList.FragScans[fragSpectrumIndex2].ScanNumber, out var spectrum2, false))
                            {
                                SetLocalErrorCode(clsMASIC.eMasicErrorCodes.ErrorUncachingSpectrum);
                                return(-1);
                            }

                            // ReSharper disable once ConditionIsAlwaysTrueOrFalse
                            if (!clsMASIC.DISCARD_LOW_INTENSITY_MSMS_DATA_ON_LOAD)
#pragma warning disable 162
                            // ReSharper disable HeuristicUnreachableCode
                            {
                                dataImportUtilities.DiscardDataBelowNoiseThreshold(spectrum2, scanList.FragScans[fragSpectrumIndex2].BaselineNoiseStats.NoiseLevel, 0, 0, noiseThresholdOptions);
                            }
                            // ReSharper restore HeuristicUnreachableCode
#pragma warning restore 162

                            var similarityScore = CompareSpectra(spectrum1, spectrum2, binningOptions);

                            if (similarityScore > highestSimilarityScore)
                            {
                                highestSimilarityScore = similarityScore;
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ReportError("Error in CompareFragSpectraForParentIons", ex);
                return(-1);
            }

            return(highestSimilarityScore);
        }