예제 #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>
 /// Add the parent ion, or associate the fragmentation scan with an existing parent ion
 /// </summary>
 /// <param name="scanList"></param>
 /// <param name="surveyScanIndex"></param>
 /// <param name="parentIonMZ"></param>
 /// <param name="fragScanIndex"></param>
 /// <param name="spectraCache"></param>
 /// <param name="sicOptions"></param>
 public void AddUpdateParentIons(
     clsScanList scanList,
     int surveyScanIndex,
     double parentIonMZ,
     int fragScanIndex,
     clsSpectraCache spectraCache,
     clsSICOptions sicOptions)
 {
     AddUpdateParentIons(scanList, surveyScanIndex, parentIonMZ, 0, 0, fragScanIndex, spectraCache, sicOptions);
 }
예제 #4
0
        /// <summary>
        /// Export MRM data to disk
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="spectraCache"></param>
        /// <param name="inputFileName"></param>
        /// <param name="outputDirectoryPath"></param>
        /// <returns></returns>
        public bool ExportMRMDataToDisk(
            clsScanList scanList,
            clsSpectraCache spectraCache,
            string inputFileName,
            string outputDirectoryPath)
        {
            if (!DetermineMRMSettings(scanList, out var mrmSettings, out var srmList))
            {
                return(false);
            }

            var success = ExportMRMDataToDisk(scanList, spectraCache, mrmSettings, srmList, inputFileName, outputDirectoryPath);

            return(success);
        }
예제 #5
0
        /// <summary>
        /// Add the parent ion, or associate the fragmentation scan with an existing parent ion
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="surveyScanIndex"></param>
        /// <param name="parentIonMZ"></param>
        /// <param name="mrmInfo"></param>
        /// <param name="spectraCache"></param>
        /// <param name="sicOptions"></param>
        public void AddUpdateParentIons(
            clsScanList scanList,
            int surveyScanIndex,
            double parentIonMZ,
            clsMRMScanInfo mrmInfo,
            clsSpectraCache spectraCache,
            clsSICOptions sicOptions)
        {
            for (var mrmIndex = 0; mrmIndex < mrmInfo.MRMMassCount; mrmIndex++)
            {
                var mrmDaughterMZ         = mrmInfo.MRMMassList[mrmIndex].CentralMass;
                var mrmToleranceHalfWidth = Math.Round((mrmInfo.MRMMassList[mrmIndex].EndMass - mrmInfo.MRMMassList[mrmIndex].StartMass) / 2, 6);
                if (mrmToleranceHalfWidth < 0.001)
                {
                    mrmToleranceHalfWidth = 0.001;
                }

                AddUpdateParentIons(scanList, surveyScanIndex, parentIonMZ, mrmDaughterMZ, mrmToleranceHalfWidth, scanList.FragScans.Count - 1, spectraCache, sicOptions);
            }
        }
예제 #6
0
 protected void UpdateCacheStats(clsSpectraCache spectraCache)
 {
     OnUpdateCacheStats(spectraCache.CacheEventCount, spectraCache.UnCacheEventCount, spectraCache.SpectraPoolHitEventCount);
 }
예제 #7
0
        /// <summary>
        /// Looks for the reporter ion peaks using FindReporterIonsWork
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="spectraCache"></param>
        /// <param name="inputFilePathFull">Full path to the input file</param>
        /// <param name="outputDirectoryPath"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        public bool FindReporterIons(
            clsScanList scanList,
            clsSpectraCache spectraCache,
            string inputFilePathFull,
            string outputDirectoryPath)
        {
            const char TAB_DELIMITER = '\t';

            var outputFilePath = "??";

            try
            {
                // Use Xraw to read the .Raw files
                var readerOptions = new ThermoReaderOptions()
                {
                    LoadMSMethodInfo = false,
                    LoadMSTuneInfo   = false
                };

                var rawFileReader = new XRawFileIO(readerOptions);
                RegisterEvents(rawFileReader);

                var includeFtmsColumns = false;

                if (inputFilePathFull.ToUpper().EndsWith(DataInput.clsDataImport.THERMO_RAW_FILE_EXTENSION.ToUpper()))
                {
                    // Processing a thermo .Raw file
                    // Check whether any of the frag scans has IsFTMS true
                    for (var masterOrderIndex = 0; masterOrderIndex < scanList.MasterScanOrderCount; masterOrderIndex++)
                    {
                        var scanPointer = scanList.MasterScanOrder[masterOrderIndex].ScanIndexPointer;
                        if (scanList.MasterScanOrder[masterOrderIndex].ScanType == clsScanList.eScanTypeConstants.SurveyScan)
                        {
                            // Skip survey scans
                            continue;
                        }

                        if (scanList.FragScans[scanPointer].IsFTMS)
                        {
                            includeFtmsColumns = true;
                            break;
                        }
                    }

                    if (includeFtmsColumns)
                    {
                        rawFileReader.OpenRawFile(inputFilePathFull);
                    }
                }

                if (mOptions.ReporterIons.ReporterIonList.Count == 0)
                {
                    // No reporter ions defined; default to ITraq
                    mOptions.ReporterIons.SetReporterIonMassMode(clsReporterIons.eReporterIonMassModeConstants.ITraqFourMZ);
                }

                // Populate array reporterIons, which we will sort by m/z
                var reporterIons = new clsReporterIonInfo[mOptions.ReporterIons.ReporterIonList.Count];

                var reporterIonIndex = 0;
                foreach (var reporterIon in mOptions.ReporterIons.ReporterIonList)
                {
                    reporterIons[reporterIonIndex] = reporterIon;
                    reporterIonIndex += 1;
                }

                Array.Sort(reporterIons, new clsReportIonInfoComparer());

                outputFilePath = clsDataOutput.ConstructOutputFilePath(
                    Path.GetFileName(inputFilePathFull),
                    outputDirectoryPath,
                    clsDataOutput.eOutputFileTypeConstants.ReporterIonsFile);

                using (var writer = new StreamWriter(outputFilePath))
                {
                    // Write the file headers
                    var reporterIonMZsUnique = new SortedSet <string>();
                    var headerColumns        = new List <string>(7 + reporterIons.Length + 1)
                    {
                        "Dataset",
                        "ScanNumber",
                        "Collision Mode",
                        "ParentIonMZ",
                        "BasePeakIntensity",
                        "BasePeakMZ",
                        "ReporterIonIntensityMax"
                    };

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

                    var saveUncorrectedIntensities =
                        mOptions.ReporterIons.ReporterIonApplyAbundanceCorrection && mOptions.ReporterIons.ReporterIonSaveUncorrectedIntensities;

                    var dataAggregation = new clsDataAggregation();
                    RegisterEvents(dataAggregation);

                    foreach (var reporterIon in reporterIons)
                    {
                        if (!reporterIon.ContaminantIon || saveUncorrectedIntensities)
                        {
                            // Construct the reporter ion intensity header
                            // We skip contaminant ions, unless saveUncorrectedIntensities is True, then we include them

                            string mzValue;
                            if (mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTTenMZ ||
                                mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTElevenMZ ||
                                mOptions.ReporterIons.ReporterIonMassMode == clsReporterIons.eReporterIonMassModeConstants.TMTSixteenMZ)
                            {
                                mzValue = reporterIon.MZ.ToString("#0.000");
                            }
                            else
                            {
                                mzValue = ((int)Math.Round(reporterIon.MZ, 0)).ToString();
                            }

                            if (reporterIonMZsUnique.Contains(mzValue))
                            {
                                // Uniquify the m/z value
                                mzValue += "_" + reporterIonIndex;
                            }

                            try
                            {
                                reporterIonMZsUnique.Add(mzValue);
                            }
                            catch (Exception ex)
                            {
                                // Error updating the SortedSet;
                                // this shouldn't happen based on the .ContainsKey test above
                            }

                            // Append the reporter ion intensity title to the headers
                            headerColumns.Add("Ion_" + mzValue);

                            // This string will only be included in the header line if mOptions.ReporterIons.ReporterIonSaveObservedMasses is true
                            obsMZHeaders.Add("Ion_" + mzValue + "_ObsMZ");

                            // This string will be included in the header line if saveUncorrectedIntensities is true
                            uncorrectedIntensityHeaders.Add("Ion_" + mzValue + "_OriginalIntensity");

                            // This string will be included in the header line if includeFtmsColumns is true
                            ftmsSignalToNoise.Add("Ion_" + mzValue + "_SignalToNoise");
                            ftmsResolution.Add("Ion_" + mzValue + "_Resolution");

                            // Uncomment to include the label data m/z value in the _ReporterIons.txt file
                            // This string will only be included in the header line if mOptions.ReporterIons.ReporterIonSaveObservedMasses is true
                            //ftmsLabelDataMz.Add("Ion_" + mzValue + "_LabelDataMZ");
                        }
                    }

                    headerColumns.Add("Weighted Avg Pct Intensity Correction");

                    if (mOptions.ReporterIons.ReporterIonSaveObservedMasses)
                    {
                        headerColumns.AddRange(obsMZHeaders);
                    }

                    if (saveUncorrectedIntensities)
                    {
                        headerColumns.AddRange(uncorrectedIntensityHeaders);
                    }

                    if (includeFtmsColumns)
                    {
                        headerColumns.AddRange(ftmsSignalToNoise);
                        headerColumns.AddRange(ftmsResolution);
                        // Uncomment to include the label data m/z value in the _ReporterIons.txt file
                        // If mOptions.ReporterIons.ReporterIonSaveObservedMasses Then
                        // headerColumns.AddRange(ftmsLabelDataMz)
                        // End If
                    }

                    // Write the headers to the output file, separated by tabs
                    writer.WriteLine(string.Join(TAB_DELIMITER.ToString(), headerColumns));

                    UpdateProgress(0, "Searching for reporter ions");

                    for (var masterOrderIndex = 0; masterOrderIndex < scanList.MasterScanOrderCount; masterOrderIndex++)
                    {
                        var scanPointer = scanList.MasterScanOrder[masterOrderIndex].ScanIndexPointer;
                        if (scanList.MasterScanOrder[masterOrderIndex].ScanType == clsScanList.eScanTypeConstants.SurveyScan)
                        {
                            // Skip Survey Scans
                            continue;
                        }

                        FindReporterIonsWork(
                            rawFileReader,
                            dataAggregation,
                            includeFtmsColumns,
                            mOptions.SICOptions,
                            scanList,
                            spectraCache,
                            scanList.FragScans[scanPointer],
                            writer,
                            reporterIons,
                            TAB_DELIMITER,
                            saveUncorrectedIntensities,
                            mOptions.ReporterIons.ReporterIonSaveObservedMasses);

                        if (scanList.MasterScanOrderCount > 1)
                        {
                            UpdateProgress((short)(masterOrderIndex / (double)(scanList.MasterScanOrderCount - 1) * 100));
                        }
                        else
                        {
                            UpdateProgress(0);
                        }

                        UpdateCacheStats(spectraCache);
                        if (mOptions.AbortProcessing)
                        {
                            break;
                        }
                    }
                }

                if (includeFtmsColumns)
                {
                    // Close the handle to the data file
                    rawFileReader.CloseRawFile();
                }

                return(true);
            }
            catch (Exception ex)
            {
                ReportError("Error writing the reporter ions to: " + outputFilePath, ex, clsMASIC.eMasicErrorCodes.OutputFileWriteError);
                return(false);
            }
        }
예제 #8
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));
        }
예제 #9
0
        /// <summary>
        /// Add the parent ion, or associate the fragmentation scan with an existing parent ion
        ///
        /// Checks to see if the parent ion specified by surveyScanIndex and parentIonMZ exists in .ParentIons()
        /// If mrmDaughterMZ is > 0, also considers that value when determining uniqueness
        ///
        /// If the parent ion entry already exists, adds an entry to .FragScanIndices()
        /// If it does not exist, adds a new entry to .ParentIons()
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="surveyScanIndex">
        /// If this is less than 0 the first MS2 scan(s) in the file occurred before we encountered a survey scan
        /// In this case, we cannot properly associate the fragmentation scan with a survey scan
        /// </param>
        /// <param name="parentIonMZ"></param>
        /// <param name="mrmDaughterMZ"></param>
        /// <param name="mrmToleranceHalfWidth"></param>
        /// <param name="fragScanIndex">This is typically equal to scanList.FragScans.Count - 1</param>
        /// <param name="spectraCache"></param>
        /// <param name="sicOptions"></param>
        private void AddUpdateParentIons(
            clsScanList scanList,
            int surveyScanIndex,
            double parentIonMZ,
            double mrmDaughterMZ,
            double mrmToleranceHalfWidth,
            int fragScanIndex,
            clsSpectraCache spectraCache,
            clsSICOptions sicOptions)
        {
            const double MINIMUM_TOLERANCE_PPM = 0.01;
            const double MINIMUM_TOLERANCE_DA  = 0.0001;

            var parentIonIndex = 0;

            double parentIonTolerance;

            if (sicOptions.SICToleranceIsPPM)
            {
                parentIonTolerance = sicOptions.SICTolerance / sicOptions.CompressToleranceDivisorForPPM;
                if (parentIonTolerance < MINIMUM_TOLERANCE_PPM)
                {
                    parentIonTolerance = MINIMUM_TOLERANCE_PPM;
                }
            }
            else
            {
                parentIonTolerance = sicOptions.SICTolerance / sicOptions.CompressToleranceDivisorForDa;
                if (parentIonTolerance < MINIMUM_TOLERANCE_DA)
                {
                    parentIonTolerance = MINIMUM_TOLERANCE_DA;
                }
            }

            // See if an entry exists yet in .ParentIons for the parent ion for this fragmentation scan
            var matchFound = false;

            if (mrmDaughterMZ > 0)
            {
                if (sicOptions.SICToleranceIsPPM)
                {
                    // Force the tolerances to 0.01 m/z units
                    parentIonTolerance = MINIMUM_TOLERANCE_PPM;
                }
                else
                {
                    // Force the tolerances to 0.01 m/z units
                    parentIonTolerance = MINIMUM_TOLERANCE_DA;
                }
            }

            if (parentIonMZ > 0)
            {
                var parentIonToleranceDa = GetParentIonToleranceDa(sicOptions, parentIonMZ, parentIonTolerance);

                for (parentIonIndex = scanList.ParentIons.Count - 1; parentIonIndex >= 0; parentIonIndex += -1)
                {
                    if (scanList.ParentIons[parentIonIndex].SurveyScanIndex >= surveyScanIndex)
                    {
                        if (Math.Abs(scanList.ParentIons[parentIonIndex].MZ - parentIonMZ) <= parentIonToleranceDa)
                        {
                            if (mrmDaughterMZ < double.Epsilon ||
                                Math.Abs(scanList.ParentIons[parentIonIndex].MRMDaughterMZ - mrmDaughterMZ) <= parentIonToleranceDa)
                            {
                                matchFound = true;
                                break;
                            }
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (!matchFound)
            {
                // Add a new parent ion entry to .ParentIons(), but only if surveyScanIndex is non-negative

                if (surveyScanIndex < 0)
                {
                    return;
                }

                var newParentIon = new clsParentIonInfo(parentIonMZ)
                {
                    SurveyScanIndex       = surveyScanIndex,
                    CustomSICPeak         = false,
                    MRMDaughterMZ         = mrmDaughterMZ,
                    MRMToleranceHalfWidth = mrmToleranceHalfWidth
                };

                newParentIon.FragScanIndices.Add(fragScanIndex);

                newParentIon.OptimalPeakApexScanNumber      = scanList.SurveyScans[surveyScanIndex].ScanNumber;   // Was: .FragScans(fragScanIndex).ScanNumber
                newParentIon.PeakApexOverrideParentIonIndex = -1;
                scanList.FragScans[fragScanIndex].FragScanInfo.ParentIonInfoIndex = scanList.ParentIons.Count;

                // Look for .MZ in the survey scan, using a tolerance of parentIonTolerance
                // If found, then update the mass to the matched ion
                // This is done to determine the parent ion mass more precisely
                if (sicOptions.RefineReportedParentIonMZ)
                {
                    if (FindClosestMZ(spectraCache, scanList.SurveyScans, surveyScanIndex, parentIonMZ, parentIonTolerance, out var parentIonMZMatch))
                    {
                        newParentIon.UpdateMz(parentIonMZMatch);
                    }
                }

                scanList.ParentIons.Add(newParentIon);
                return;
            }

            // Add a new entry to .FragScanIndices() for the matching parent ion
            // However, do not add a new entry if this is an MRM scan
            if (mrmDaughterMZ < double.Epsilon)
            {
                scanList.ParentIons[parentIonIndex].FragScanIndices.Add(fragScanIndex);
                scanList.FragScans[fragScanIndex].FragScanInfo.ParentIonInfoIndex = parentIonIndex;
            }
        }
예제 #10
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);
        }
예제 #11
0
        public bool ProcessMRMList(
            clsScanList scanList,
            clsSpectraCache spectraCache,
            clsSICProcessing sicProcessor,
            clsXMLResultsWriter xmlResultsWriter,
            clsMASICPeakFinder peakFinder,
            ref int parentIonsProcessed)
        {
            try
            {
                // Initialize sicDetails
                var sicDetails = new clsSICDetails();
                sicDetails.Reset();
                sicDetails.SICScanType = clsScanList.eScanTypeConstants.FragScan;

                for (var parentIonIndex = 0; parentIonIndex < scanList.ParentIons.Count; parentIonIndex++)
                {
                    if (scanList.ParentIons[parentIonIndex].MRMDaughterMZ <= 0)
                    {
                        continue;
                    }

                    // Step 1: Create the SIC for this MRM Parent/Daughter pair

                    var parentIonMZ              = scanList.ParentIons[parentIonIndex].MZ;
                    var mrmDaughterMZ            = scanList.ParentIons[parentIonIndex].MRMDaughterMZ;
                    var searchToleranceHalfWidth = scanList.ParentIons[parentIonIndex].MRMToleranceHalfWidth;

                    // Reset SICData
                    sicDetails.SICData.Clear();

                    // Step through the fragmentation spectra, finding those that have matching parent and daughter ion m/z values
                    for (var scanIndex = 0; scanIndex < scanList.FragScans.Count; scanIndex++)
                    {
                        if (scanList.FragScans[scanIndex].MRMScanType != MRMScanTypeConstants.SRM)
                        {
                            continue;
                        }

                        var fragScan = scanList.FragScans[scanIndex];

                        var useScan = false;
                        for (var mrmMassIndex = 0; mrmMassIndex < fragScan.MRMScanInfo.MRMMassCount; mrmMassIndex++)
                        {
                            if (MRMParentDaughterMatch(fragScan.MRMScanInfo.ParentIonMZ,
                                                       fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].CentralMass,
                                                       parentIonMZ, mrmDaughterMZ))
                            {
                                useScan = true;
                                break;
                            }
                        }

                        if (!useScan)
                        {
                            continue;
                        }

                        // Include this scan in the SIC for this parent ion

                        mDataAggregation.FindMaxValueInMZRange(spectraCache,
                                                               scanList.FragScans[scanIndex],
                                                               mrmDaughterMZ - searchToleranceHalfWidth,
                                                               mrmDaughterMZ + searchToleranceHalfWidth,
                                                               out var closestMZ, out var matchIntensity);

                        sicDetails.AddData(fragScan.ScanNumber, matchIntensity, closestMZ, scanIndex);
                    }

                    // Step 2: Find the largest peak in the SIC

                    // Compute the noise level; the noise level may change with increasing index number if the background is increasing for a given m/z
                    var success = peakFinder.ComputeDualTrimmedNoiseLevelTTest(sicDetails.SICIntensities, 0,
                                                                               sicDetails.SICDataCount - 1,
                                                                               mOptions.SICOptions.SICPeakFinderOptions.
                                                                               SICBaselineNoiseOptions,
                                                                               out var noiseStatsSegments);

                    if (!success)
                    {
                        SetLocalErrorCode(clsMASIC.eMasicErrorCodes.FindSICPeaksError, true);
                        return(false);
                    }

                    // Initialize the peak
                    scanList.ParentIons[parentIonIndex].SICStats.Peak = new clsSICStatsPeak();

                    // Find the data point with the maximum intensity
                    double maximumIntensity = 0;
                    scanList.ParentIons[parentIonIndex].SICStats.Peak.IndexObserved = 0;
                    for (var scanIndex = 0; scanIndex < sicDetails.SICDataCount; scanIndex++)
                    {
                        var intensity = sicDetails.SICIntensities[scanIndex];
                        if (intensity > maximumIntensity)
                        {
                            maximumIntensity = intensity;
                            scanList.ParentIons[parentIonIndex].SICStats.Peak.IndexObserved = scanIndex;
                        }
                    }

                    // Compute the minimum potential peak area in the entire SIC, populating udtSICPotentialAreaStatsInFullSIC
                    peakFinder.FindPotentialPeakArea(sicDetails.SICData,
                                                     out var potentialAreaStatsInFullSIC,
                                                     mOptions.SICOptions.SICPeakFinderOptions);

                    // Update .BaselineNoiseStats in scanList.ParentIons(parentIonIndex).SICStats.Peak
                    scanList.ParentIons[parentIonIndex].SICStats.Peak.BaselineNoiseStats = peakFinder.LookupNoiseStatsUsingSegments(
                        scanList.ParentIons[parentIonIndex].SICStats.Peak.IndexObserved,
                        noiseStatsSegments);

                    var parentIon = scanList.ParentIons[parentIonIndex];

                    // Clear udtSICPotentialAreaStatsForPeak
                    parentIon.SICStats.SICPotentialAreaStatsForPeak = new clsSICPotentialAreaStats();

                    var peakIsValid = peakFinder.FindSICPeakAndArea(sicDetails.SICData,
                                                                    out var potentialAreaStatsForPeakOut,
                                                                    parentIon.SICStats.Peak, out var smoothedYDataSubset,
                                                                    mOptions.SICOptions.SICPeakFinderOptions,
                                                                    potentialAreaStatsInFullSIC, false,
                                                                    scanList.SIMDataPresent, false);

                    parentIon.SICStats.SICPotentialAreaStatsForPeak = potentialAreaStatsForPeakOut;

                    sicProcessor.StorePeakInParentIon(scanList, parentIonIndex, sicDetails,
                                                      parentIon.SICStats.SICPotentialAreaStatsForPeak,
                                                      parentIon.SICStats.Peak, peakIsValid);

                    // Step 3: store the results

                    // Possibly save the stats for this SIC to the SICData file
                    mDataOutputHandler.SaveSICDataToText(mOptions.SICOptions, scanList, parentIonIndex, sicDetails);

                    // Save the stats for this SIC to the XML file
                    xmlResultsWriter.SaveDataToXML(scanList, parentIonIndex, sicDetails, smoothedYDataSubset,
                                                   mDataOutputHandler);

                    parentIonsProcessed += 1;

                    // ---------------------------------------------------------
                    // Update progress
                    // ---------------------------------------------------------
                    try
                    {
                        if (scanList.ParentIons.Count > 1)
                        {
                            UpdateProgress((short)(parentIonsProcessed / (double)(scanList.ParentIons.Count - 1) * 100));
                        }
                        else
                        {
                            UpdateProgress(0);
                        }

                        UpdateCacheStats(spectraCache);
                        if (mOptions.AbortProcessing)
                        {
                            scanList.ProcessingIncomplete = true;
                            break;
                        }

                        if (parentIonsProcessed % 100 == 0)
                        {
                            if (DateTime.UtcNow.Subtract(mOptions.LastParentIonProcessingLogTime).TotalSeconds >= 10 || parentIonsProcessed % 500 == 0)
                            {
                                ReportMessage("Parent Ions Processed: " + parentIonsProcessed.ToString());
                                Console.Write(".");
                                mOptions.LastParentIonProcessingLogTime = DateTime.UtcNow;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        ReportError("Error updating progress", ex, clsMASIC.eMasicErrorCodes.CreateSICsError);
                    }
                }

                return(true);
            }
            catch (Exception ex)
            {
                ReportError("Error creating SICs for MRM spectra", ex, clsMASIC.eMasicErrorCodes.CreateSICsError);
                return(false);
            }
        }
예제 #12
0
        /// <summary>
        /// Export MRM data to disk
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="spectraCache"></param>
        /// <param name="mrmSettings"></param>
        /// <param name="srmList"></param>
        /// <param name="inputFileName"></param>
        /// <param name="outputDirectoryPath"></param>
        /// <returns>True if the MRM data is successfully written to disk, or if the mrmSettings list is empty</returns>
        private bool ExportMRMDataToDisk(
            clsScanList scanList,
            clsSpectraCache spectraCache,
            IReadOnlyList <clsMRMScanInfo> mrmSettings,
            IReadOnlyList <udtSRMListType> srmList,
            string inputFileName,
            string outputDirectoryPath)
        {
            const char TAB_DELIMITER = '\t';

            StreamWriter dataWriter     = null;
            StreamWriter crosstabWriter = null;

            bool success;

            try
            {
                // Only write this data if 1 or more fragmentation spectra are of type SRM
                if (mrmSettings == null || mrmSettings.Count == 0)
                {
                    return(true);
                }

                UpdateProgress(0, "Exporting MRM data");

                // Write out the MRM Settings
                var mrmSettingsFilePath = clsDataOutput.ConstructOutputFilePath(
                    inputFileName, outputDirectoryPath, clsDataOutput.eOutputFileTypeConstants.MRMSettingsFile);
                using (var settingsWriter = new StreamWriter(mrmSettingsFilePath))
                {
                    settingsWriter.WriteLine(mDataOutputHandler.GetHeadersForOutputFile(scanList, clsDataOutput.eOutputFileTypeConstants.MRMSettingsFile));

                    var dataColumns = new List <string>(7);

                    for (var mrmInfoIndex = 0; mrmInfoIndex < mrmSettings.Count; mrmInfoIndex++)
                    {
                        var mrmSetting = mrmSettings[mrmInfoIndex];
                        for (var mrmMassIndex = 0; mrmMassIndex < mrmSetting.MRMMassCount; mrmMassIndex++)
                        {
                            dataColumns.Clear();

                            dataColumns.Add(mrmInfoIndex.ToString());
                            dataColumns.Add(mrmSetting.ParentIonMZ.ToString("0.000"));
                            dataColumns.Add(mrmSetting.MRMMassList[mrmMassIndex].CentralMass.ToString("0.000"));
                            dataColumns.Add(mrmSetting.MRMMassList[mrmMassIndex].StartMass.ToString("0.000"));
                            dataColumns.Add(mrmSetting.MRMMassList[mrmMassIndex].EndMass.ToString("0.000"));
                            dataColumns.Add(mrmSetting.ScanCount.ToString());

                            settingsWriter.WriteLine(string.Join(TAB_DELIMITER.ToString(), dataColumns));
                        }
                    }

                    if (mOptions.WriteMRMDataList || mOptions.WriteMRMIntensityCrosstab)
                    {
                        // Populate srmKeyToIndexMap
                        var srmKeyToIndexMap = new Dictionary <string, int>();
                        for (var srmIndex = 0; srmIndex < srmList.Count; srmIndex++)
                        {
                            srmKeyToIndexMap.Add(ConstructSRMMapKey(srmList[srmIndex]), srmIndex);
                        }

                        if (mOptions.WriteMRMDataList)
                        {
                            // Write out the raw MRM Data
                            var dataFilePath = clsDataOutput.ConstructOutputFilePath(inputFileName, outputDirectoryPath, clsDataOutput.eOutputFileTypeConstants.MRMDatafile);
                            dataWriter = new StreamWriter(dataFilePath);

                            // Write the file headers
                            dataWriter.WriteLine(mDataOutputHandler.GetHeadersForOutputFile(scanList, clsDataOutput.eOutputFileTypeConstants.MRMDatafile));
                        }

                        if (mOptions.WriteMRMIntensityCrosstab)
                        {
                            // Write out the raw MRM Data
                            var crosstabFilePath = clsDataOutput.ConstructOutputFilePath(inputFileName, outputDirectoryPath, clsDataOutput.eOutputFileTypeConstants.MRMCrosstabFile);
                            crosstabWriter = new StreamWriter(crosstabFilePath);

                            // Initialize the crosstab header variable using the data in udtSRMList()

                            var headerNames = new List <string>(srmList.Count + 2)
                            {
                                "Scan_First",
                                "ScanTime"
                            };

                            for (var srmIndex = 0; srmIndex < srmList.Count; srmIndex++)
                            {
                                headerNames.Add(ConstructSRMMapKey(srmList[srmIndex]));
                            }

                            crosstabWriter.WriteLine(string.Join(TAB_DELIMITER.ToString(), headerNames));
                        }

                        var   scanFirst     = int.MinValue;
                        float scanTimeFirst = 0;
                        var   srmIndexLast  = 0;

                        var crosstabColumnValue = new double[srmList.Count];
                        var crosstabColumnFlag  = new bool[srmList.Count];

                        // For scanIndex = 0 To scanList.FragScanCount - 1
                        foreach (var fragScan in scanList.FragScans)
                        {
                            if (fragScan.MRMScanType != MRMScanTypeConstants.SRM)
                            {
                                continue;
                            }

                            if (scanFirst == int.MinValue)
                            {
                                scanFirst     = fragScan.ScanNumber;
                                scanTimeFirst = fragScan.ScanTime;
                            }

                            // Look for each of the m/z values specified in fragScan.MRMScanInfo.MRMMassList
                            for (var mrmMassIndex = 0; mrmMassIndex < fragScan.MRMScanInfo.MRMMassCount; mrmMassIndex++)
                            {
                                // Find the maximum value between fragScan.StartMass and fragScan.EndMass
                                // Need to define a tolerance to account for numeric rounding artifacts in the variables

                                var mzStart = fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].StartMass;
                                var mzEnd   = fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].EndMass;
                                var mrmToleranceHalfWidth = Math.Round((mzEnd - mzStart) / 2, 6);
                                if (mrmToleranceHalfWidth < 0.001)
                                {
                                    mrmToleranceHalfWidth = 0.001;
                                }

                                var matchFound = mDataAggregation.FindMaxValueInMZRange(
                                    spectraCache, fragScan,
                                    mzStart - mrmToleranceHalfWidth,
                                    mzEnd + mrmToleranceHalfWidth,
                                    out _, out var matchIntensity);

                                if (mOptions.WriteMRMDataList)
                                {
                                    dataColumns.Clear();
                                    dataColumns.Add(fragScan.ScanNumber.ToString());
                                    dataColumns.Add(fragScan.MRMScanInfo.ParentIonMZ.ToString("0.000"));

                                    if (matchFound)
                                    {
                                        dataColumns.Add(fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].CentralMass.ToString("0.000"));
                                        dataColumns.Add(matchIntensity.ToString("0.000"));
                                    }
                                    else
                                    {
                                        dataColumns.Add(fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].CentralMass.ToString("0.000"));
                                        dataColumns.Add("0");
                                    }

                                    dataWriter?.WriteLine(string.Join(TAB_DELIMITER.ToString(), dataColumns));
                                }

                                if (!mOptions.WriteMRMIntensityCrosstab)
                                {
                                    continue;
                                }

                                var srmMapKey = ConstructSRMMapKey(fragScan.MRMScanInfo.ParentIonMZ, fragScan.MRMScanInfo.MRMMassList[mrmMassIndex].CentralMass);

                                // Use srmKeyToIndexMap to determine the appropriate column index for srmMapKey
                                if (srmKeyToIndexMap.TryGetValue(srmMapKey, out var srmIndex))
                                {
                                    if (crosstabColumnFlag[srmIndex] ||
                                        srmIndex == 0 && srmIndexLast == srmList.Count - 1)
                                    {
                                        // Either the column is already populated, or the SRMIndex has cycled back to zero
                                        // Write out the current crosstab line and reset the crosstab column arrays
                                        ExportMRMDataWriteLine(crosstabWriter, scanFirst, scanTimeFirst,
                                                               crosstabColumnValue,
                                                               crosstabColumnFlag,
                                                               TAB_DELIMITER, true);

                                        scanFirst     = fragScan.ScanNumber;
                                        scanTimeFirst = fragScan.ScanTime;
                                    }

                                    if (matchFound)
                                    {
                                        crosstabColumnValue[srmIndex] = matchIntensity;
                                    }

                                    crosstabColumnFlag[srmIndex] = true;
                                    srmIndexLast = srmIndex;
                                }
                                else
                                {
                                    // Unknown combination of parent ion m/z and daughter m/z; this is unexpected
                                    // We won't write this entry out
                                }
                            }

                            UpdateCacheStats(spectraCache);
                            if (mOptions.AbortProcessing)
                            {
                                break;
                            }
                        }

                        if (mOptions.WriteMRMIntensityCrosstab)
                        {
                            // Write out any remaining crosstab values
                            ExportMRMDataWriteLine(crosstabWriter, scanFirst, scanTimeFirst, crosstabColumnValue, crosstabColumnFlag, TAB_DELIMITER, false);
                        }
                    }
                }

                success = true;
            }
            catch (Exception ex)
            {
                ReportError("Error writing the SRM data to disk", ex, clsMASIC.eMasicErrorCodes.OutputFileWriteError);
                success = false;
            }
            finally
            {
                dataWriter?.Close();
                crosstabWriter?.Close();
            }

            return(success);
        }
예제 #13
0
        public bool ProcessAndStoreSpectrum(
            clsScanInfo scanInfo,
            DataInput.clsDataImport dataImportUtilities,
            clsSpectraCache spectraCache,
            clsMSSpectrum msSpectrum,
            clsBaselineNoiseOptions noiseThresholdOptions,
            bool discardLowIntensityData,
            bool compressData,
            double msDataResolution,
            bool keepRawSpectrum)
        {
            var lastKnownLocation = "Start";

            try
            {
                // Determine the noise threshold intensity for this spectrum
                // Stored in scanInfo.BaselineNoiseStats
                lastKnownLocation = "Call ComputeNoiseLevelForMassSpectrum";
                ComputeNoiseLevelForMassSpectrum(scanInfo, msSpectrum, noiseThresholdOptions);

                if (!keepRawSpectrum)
                {
                    return(true);
                }

                // Discard low intensity data, but not for MRM scans
                if (discardLowIntensityData && scanInfo.MRMScanType == ThermoRawFileReader.MRMScanTypeConstants.NotMRM)
                {
                    // Discard data below the noise level or below the minimum S/N level
                    // If we are searching for Reporter ions, then it is important to not discard any of the ions in the region of the reporter ion m/z values
                    lastKnownLocation = "Call DiscardDataBelowNoiseThreshold";
                    dataImportUtilities.DiscardDataBelowNoiseThreshold(msSpectrum,
                                                                       scanInfo.BaselineNoiseStats.NoiseLevel,
                                                                       mReporterIons.MZIntensityFilterIgnoreRangeStart,
                                                                       mReporterIons.MZIntensityFilterIgnoreRangeEnd,
                                                                       noiseThresholdOptions);

                    scanInfo.IonCount = msSpectrum.IonCount;
                }

                if (compressData)
                {
                    lastKnownLocation = "Call CompressSpectraData";
                    // Again, if we are searching for Reporter ions, then it is important to not discard any of the ions in the region of the reporter ion m/z values
                    CompressSpectraData(msSpectrum, msDataResolution,
                                        mReporterIons.MZIntensityFilterIgnoreRangeStart,
                                        mReporterIons.MZIntensityFilterIgnoreRangeEnd);
                }

                if (msSpectrum.IonCount > MAX_ALLOWABLE_ION_COUNT)
                {
                    // Do not keep more than 50,000 ions
                    lastKnownLocation = "Call DiscardDataToLimitIonCount";
                    mSpectraFoundExceedingMaxIonCount += 1;

                    // Display a message at the console the first 10 times we encounter spectra with over MAX_ALLOWABLE_ION_COUNT ions
                    // In addition, display a new message every time a new max value is encountered
                    if (mSpectraFoundExceedingMaxIonCount <= 10 || msSpectrum.IonCount > mMaxIonCountReported)
                    {
                        Console.WriteLine();
                        Console.WriteLine(
                            "Note: Scan " + scanInfo.ScanNumber + " has " + msSpectrum.IonCount + " ions; " +
                            "will only retain " + MAX_ALLOWABLE_ION_COUNT + " (trimmed " +
                            mSpectraFoundExceedingMaxIonCount.ToString() + " spectra)");

                        mMaxIonCountReported = msSpectrum.IonCount;
                    }

                    dataImportUtilities.DiscardDataToLimitIonCount(msSpectrum,
                                                                   mReporterIons.MZIntensityFilterIgnoreRangeStart,
                                                                   mReporterIons.MZIntensityFilterIgnoreRangeEnd,
                                                                   MAX_ALLOWABLE_ION_COUNT);

                    scanInfo.IonCount = msSpectrum.IonCount;
                }

                lastKnownLocation = "Call AddSpectrumToPool";
                var success = spectraCache.AddSpectrumToPool(msSpectrum, scanInfo.ScanNumber);

                return(success);
            }
            catch (Exception ex)
            {
                ReportError("Error in ProcessAndStoreSpectrum (LastKnownLocation: " + lastKnownLocation + ")", ex, clsMASIC.eMasicErrorCodes.InputFileDataReadError);
                return(false);
            }
        }