Exemplo n.º 1
0
        /// <summary>
        /// Find the index of the scan closest to scanOrAcqTime (searching both Survey and Frag Scans using the MasterScanList)
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="scanOrAcqTime">can be absolute, relative, or AcquisitionTime</param>
        /// <param name="eScanType">Specifies what type of value scanOrAcqTime is; 0=absolute, 1=relative, 2=acquisition time (aka elution time)</param>
        /// <returns>The index of the scan closest to scanOrAcqTime, or 0 if an error</returns>
        /// <remarks></remarks>
        private int FindNearestScanNumIndex(
            clsScanList scanList,
            float scanOrAcqTime,
            clsCustomSICList.eCustomSICScanTypeConstants eScanType)
        {
            try
            {
                int scanIndexMatch;

                if (eScanType == clsCustomSICList.eCustomSICScanTypeConstants.Absolute || eScanType == clsCustomSICList.eCustomSICScanTypeConstants.Relative)
                {
                    var absoluteScanNumber = ScanOrAcqTimeToAbsolute(scanList, scanOrAcqTime, eScanType, false);
                    scanIndexMatch = clsBinarySearch.BinarySearchFindNearest(scanList.MasterScanNumList, absoluteScanNumber, clsBinarySearch.eMissingDataModeConstants.ReturnClosestPoint);
                }
                else
                {
                    // eScanType = eCustomSICScanTypeConstants.AcquisitionTime
                    // Find the closest match in scanList.MasterScanTimeList
                    scanIndexMatch = clsBinarySearch.BinarySearchFindNearest(
                        scanList.MasterScanTimeList,
                        scanOrAcqTime,
                        clsBinarySearch.eMissingDataModeConstants.ReturnClosestPoint);
                }

                return(scanIndexMatch);
            }
            catch (Exception ex)
            {
                OnErrorEvent("Error in FindNearestScanNumIndex", ex);
                return(0);
            }
        }
Exemplo n.º 2
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);
 }
Exemplo n.º 3
0
        public int FindNearestSurveyScanIndex(
            clsScanList scanList,
            float scanOrAcqTime,
            clsCustomSICList.eCustomSICScanTypeConstants eScanType)
        {
            // Finds the index of the survey scan closest to scanOrAcqTime
            // Note that scanOrAcqTime can be absolute, relative, or AcquisitionTime; eScanType specifies which it is

            try
            {
                var surveyScanIndexMatch = -1;
                var scanNumberToFind     = ScanOrAcqTimeToAbsolute(scanList, scanOrAcqTime, eScanType, false);

                for (var index = 0; index < scanList.SurveyScans.Count; index++)
                {
                    if (scanList.SurveyScans[index].ScanNumber >= scanNumberToFind)
                    {
                        surveyScanIndexMatch = index;
                        if (scanList.SurveyScans[index].ScanNumber != scanNumberToFind && index < scanList.SurveyScans.Count - 1)
                        {
                            // Didn't find an exact match; determine which survey scan is closer
                            if (Math.Abs(scanList.SurveyScans[index + 1].ScanNumber - scanNumberToFind) <
                                Math.Abs(scanList.SurveyScans[index].ScanNumber - scanNumberToFind))
                            {
                                surveyScanIndexMatch += 1;
                            }
                        }

                        break;
                    }
                }

                if (surveyScanIndexMatch < 0)
                {
                    // Match not found; return either the first or the last survey scan
                    if (scanList.SurveyScans.Count > 0)
                    {
                        surveyScanIndexMatch = scanList.SurveyScans.Count - 1;
                    }
                    else
                    {
                        surveyScanIndexMatch = 0;
                    }
                }

                return(surveyScanIndexMatch);
            }
            catch (Exception ex)
            {
                OnErrorEvent("Error in FindNearestSurveyScanIndex", ex);
                return(0);
            }
        }
Exemplo n.º 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);
        }
Exemplo n.º 5
0
        private void AppendParentIonToUniqueMZEntry(
            clsScanList scanList,
            int parentIonIndex,
            clsUniqueMZListItem mzListEntry,
            double searchMZOffset)
        {
            var parentIon = scanList.ParentIons[parentIonIndex];

            if (mzListEntry.MatchCount == 0)
            {
                mzListEntry.MZAvg = parentIon.MZ - searchMZOffset;
                mzListEntry.MatchIndices.Add(parentIonIndex);
            }
            else
            {
                // Update the average MZ: NewAvg = (OldAvg * OldCount + NewValue) / NewCount
                mzListEntry.MZAvg = (mzListEntry.MZAvg * mzListEntry.MatchCount + (parentIon.MZ - searchMZOffset)) / (mzListEntry.MatchCount + 1);
                mzListEntry.MatchIndices.Add(parentIonIndex);
            }

            var sicStats = parentIon.SICStats;

            if (sicStats.Peak.MaxIntensityValue > mzListEntry.MaxIntensity || mzListEntry.MatchCount == 1)
            {
                mzListEntry.MaxIntensity = sicStats.Peak.MaxIntensityValue;
                if (sicStats.ScanTypeForPeakIndices == clsScanList.eScanTypeConstants.FragScan)
                {
                    mzListEntry.ScanNumberMaxIntensity = scanList.FragScans[sicStats.PeakScanIndexMax].ScanNumber;
                    mzListEntry.ScanTimeMaxIntensity   = scanList.FragScans[sicStats.PeakScanIndexMax].ScanTime;
                }
                else
                {
                    mzListEntry.ScanNumberMaxIntensity = scanList.SurveyScans[sicStats.PeakScanIndexMax].ScanNumber;
                    mzListEntry.ScanTimeMaxIntensity   = scanList.SurveyScans[sicStats.PeakScanIndexMax].ScanTime;
                }

                mzListEntry.ParentIonIndexMaxIntensity = parentIonIndex;
            }

            if (sicStats.Peak.Area > mzListEntry.MaxPeakArea || mzListEntry.MatchCount == 1)
            {
                mzListEntry.MaxPeakArea = sicStats.Peak.Area;
                mzListEntry.ParentIonIndexMaxPeakArea = parentIonIndex;
            }
        }
Exemplo n.º 6
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);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Store custom SIC values defined in CustomMZSearchValues
        /// </summary>
        /// <param name="scanList"></param>
        /// <param name="defaultSICTolerance"></param>
        /// <param name="sicToleranceIsPPM"></param>
        /// <param name="defaultScanOrAcqTimeTolerance"></param>
        public void AddCustomSICValues(
            clsScanList scanList,
            double defaultSICTolerance,
            bool sicToleranceIsPPM,
            float defaultScanOrAcqTimeTolerance)
        {
            var   scanOrAcqTimeSumCount        = 0;
            float scanOrAcqTimeSumForAveraging = 0;

            try
            {
                if (CustomMZSearchValues.Count == 0)
                {
                    return;
                }

                var scanNumScanConverter = new clsScanNumScanTimeConversion();
                RegisterEvents(scanNumScanConverter);

                foreach (var customMzSearchValue in CustomMZSearchValues)
                {
                    // Add a new parent ion entry to .ParentIons() for this custom MZ value
                    var currentParentIon = new clsParentIonInfo(customMzSearchValue.MZ);

                    if (customMzSearchValue.ScanOrAcqTimeCenter < float.Epsilon)
                    {
                        // Set the SurveyScanIndex to the center of the analysis
                        currentParentIon.SurveyScanIndex = scanNumScanConverter.FindNearestSurveyScanIndex(
                            scanList, 0.5F, eCustomSICScanTypeConstants.Relative);
                    }
                    else
                    {
                        currentParentIon.SurveyScanIndex = scanNumScanConverter.FindNearestSurveyScanIndex(
                            scanList, customMzSearchValue.ScanOrAcqTimeCenter, ScanToleranceType);
                    }

                    // Find the next MS2 scan that occurs after the survey scan (parent scan)
                    var surveyScanNumberAbsolute = 0;
                    if (currentParentIon.SurveyScanIndex < scanList.SurveyScans.Count)
                    {
                        surveyScanNumberAbsolute = scanList.SurveyScans[currentParentIon.SurveyScanIndex].ScanNumber + 1;
                    }

                    if (scanList.MasterScanOrderCount == 0)
                    {
                        currentParentIon.FragScanIndices.Add(0);
                    }
                    else
                    {
                        var fragScanIndexMatch = clsBinarySearch.BinarySearchFindNearest(
                            scanList.MasterScanNumList,
                            surveyScanNumberAbsolute,
                            clsBinarySearch.eMissingDataModeConstants.ReturnClosestPoint);

                        while (fragScanIndexMatch < scanList.MasterScanOrderCount && scanList.MasterScanOrder[fragScanIndexMatch].ScanType == clsScanList.eScanTypeConstants.SurveyScan)
                        {
                            fragScanIndexMatch += 1;
                        }

                        if (fragScanIndexMatch == scanList.MasterScanOrderCount)
                        {
                            // Did not find the next frag scan; find the previous frag scan
                            fragScanIndexMatch -= 1;
                            while (fragScanIndexMatch > 0 && scanList.MasterScanOrder[fragScanIndexMatch].ScanType == clsScanList.eScanTypeConstants.SurveyScan)
                            {
                                fragScanIndexMatch -= 1;
                            }

                            if (fragScanIndexMatch < 0)
                            {
                                fragScanIndexMatch = 0;
                            }
                        }

                        // This is a custom SIC-based parent ion
                        // Prior to August 2014, we set .FragScanIndices(0) = 0, which made it appear that the fragmentation scan was the first MS2 spectrum in the dataset for all custom SICs
                        // This caused undesirable display results in MASIC browser, so we now set it to the next MS2 scan that occurs after the survey scan (parent scan)
                        if (scanList.MasterScanOrder[fragScanIndexMatch].ScanType == clsScanList.eScanTypeConstants.FragScan)
                        {
                            currentParentIon.FragScanIndices.Add(scanList.MasterScanOrder[fragScanIndexMatch].ScanIndexPointer);
                        }
                        else
                        {
                            currentParentIon.FragScanIndices.Add(0);
                        }
                    }

                    currentParentIon.CustomSICPeak                       = true;
                    currentParentIon.CustomSICPeakComment                = customMzSearchValue.Comment;
                    currentParentIon.CustomSICPeakMZToleranceDa          = customMzSearchValue.MZToleranceDa;
                    currentParentIon.CustomSICPeakScanOrAcqTimeTolerance = customMzSearchValue.ScanOrAcqTimeTolerance;

                    if (currentParentIon.CustomSICPeakMZToleranceDa < double.Epsilon)
                    {
                        if (sicToleranceIsPPM)
                        {
                            currentParentIon.CustomSICPeakMZToleranceDa = clsUtilities.PPMToMass(defaultSICTolerance, currentParentIon.MZ);
                        }
                        else
                        {
                            currentParentIon.CustomSICPeakMZToleranceDa = defaultSICTolerance;
                        }
                    }

                    if (currentParentIon.CustomSICPeakScanOrAcqTimeTolerance < float.Epsilon)
                    {
                        currentParentIon.CustomSICPeakScanOrAcqTimeTolerance = defaultScanOrAcqTimeTolerance;
                    }
                    else
                    {
                        scanOrAcqTimeSumForAveraging += currentParentIon.CustomSICPeakScanOrAcqTimeTolerance;
                        scanOrAcqTimeSumCount        += 1;
                    }

                    if (currentParentIon.SurveyScanIndex < scanList.SurveyScans.Count)
                    {
                        currentParentIon.OptimalPeakApexScanNumber =
                            scanList.SurveyScans[currentParentIon.SurveyScanIndex].ScanNumber;
                    }
                    else
                    {
                        currentParentIon.OptimalPeakApexScanNumber = 1;
                    }

                    currentParentIon.PeakApexOverrideParentIonIndex = -1;

                    scanList.ParentIons.Add(currentParentIon);
                }

                if (scanOrAcqTimeSumCount == CustomMZSearchValues.Count && scanOrAcqTimeSumForAveraging > 0)
                {
                    // All of the entries had a custom scan or acq time tolerance defined
                    // Update mScanOrAcqTimeTolerance to the average of the values
                    ScanOrAcqTimeTolerance = (float)(Math.Round(scanOrAcqTimeSumForAveraging / scanOrAcqTimeSumCount, 4));
                }
            }
            catch (Exception ex)
            {
                OnErrorEvent("Error in AddCustomSICValues", ex);
            }
        }
Exemplo n.º 8
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);
            }
        }
Exemplo n.º 9
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));
        }
Exemplo n.º 10
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;
            }
        }
Exemplo n.º 11
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);
        }
Exemplo n.º 12
0
        private bool DetermineMRMSettings(
            clsScanList scanList,
            out List <clsMRMScanInfo> mrmSettings,
            out List <udtSRMListType> srmList)
        {
            // Returns true if this dataset has MRM data and if it is parsed successfully
            // Returns false if the dataset does not have MRM data, or if an error occurs

            mrmSettings = new List <clsMRMScanInfo>(200);
            srmList     = new List <udtSRMListType>(600); // Assume there are 3 frag masses for each parent mass

            try
            {
                var mrmDataPresent = false;
                UpdateProgress(0, "Determining MRM settings");

                // Initialize the tracking arrays
                var mrmHashToIndexMap = new Dictionary <string, clsMRMScanInfo>();

                // Construct a list of the MRM search values used
                foreach (var fragScan in scanList.FragScans)
                {
                    if (fragScan.MRMScanType == MRMScanTypeConstants.SRM)
                    {
                        mrmDataPresent = true;

                        // See if this MRM spec is already in mrmSettings

                        var mrmInfoHash = GenerateMRMInfoHash(fragScan.MRMScanInfo);

                        if (!mrmHashToIndexMap.TryGetValue(mrmInfoHash, out var mrmInfoForHash))
                        {
                            mrmInfoForHash = DuplicateMRMInfo(fragScan.MRMScanInfo);

                            mrmInfoForHash.ScanCount          = 1;
                            mrmInfoForHash.ParentIonInfoIndex = fragScan.FragScanInfo.ParentIonInfoIndex;

                            mrmSettings.Add(mrmInfoForHash);
                            mrmHashToIndexMap.Add(mrmInfoHash, mrmInfoForHash);

                            // Append the new entries to srmList
                            for (var mrmMassIndex = 0; mrmMassIndex < mrmInfoForHash.MRMMassCount; mrmMassIndex++)
                            {
                                // Add this new transition to srmList() only if not already present
                                var matchFound = false;
                                foreach (var srmItem in srmList)
                                {
                                    if (MRMParentDaughterMatch(srmItem, mrmInfoForHash, mrmMassIndex))
                                    {
                                        matchFound = true;
                                        break;
                                    }
                                }

                                if (!matchFound)
                                {
                                    // Entry is not yet present; add it

                                    var newSRMItem = new udtSRMListType()
                                    {
                                        ParentIonMZ = mrmInfoForHash.ParentIonMZ,
                                        CentralMass = mrmInfoForHash.MRMMassList[mrmMassIndex].CentralMass
                                    };

                                    srmList.Add(newSRMItem);
                                }
                            }
                        }
                        else
                        {
                            mrmInfoForHash.ScanCount += 1;
                        }
                    }
                }

                // Resize the lists to their contents
                mrmSettings.Capacity = mrmSettings.Count;
                srmList.Capacity     = srmList.Count;

                return(mrmDataPresent);
            }
            catch (Exception ex)
            {
                ReportError("Error determining the MRM settings", ex, clsMASIC.eMasicErrorCodes.OutputFileWriteError);
                return(false);
            }
        }
Exemplo n.º 13
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);
            }
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
        public float ScanOrAcqTimeToScanTime(
            clsScanList scanList,
            float scanOrAcqTime,
            clsCustomSICList.eCustomSICScanTypeConstants eScanType,
            bool convertingRangeOrTolerance)
        {
            try
            {
                float computedScanTime = 0;

                switch (eScanType)
                {
                case clsCustomSICList.eCustomSICScanTypeConstants.Absolute:
                    // scanOrAcqTime is an absolute scan number (or range of scan numbers)

                    // If convertingRangeOrTolerance = False, then look for the scan that is nearest to scanOrAcqTime
                    // If convertingRangeOrTolerance = True, then Convert scanOrAcqTime to a relative scan range and then
                    // call this function again with that relative time

                    if (convertingRangeOrTolerance)
                    {
                        var totalScans = scanList.MasterScanNumList[scanList.MasterScanOrderCount - 1] - scanList.MasterScanNumList[0];
                        if (totalScans < 1)
                        {
                            totalScans = 1;
                        }

                        var relativeTime = scanOrAcqTime / totalScans;

                        computedScanTime = ScanOrAcqTimeToScanTime(scanList, relativeTime, clsCustomSICList.eCustomSICScanTypeConstants.Relative, true);
                    }
                    else
                    {
                        var masterScanIndex = FindNearestScanNumIndex(scanList, scanOrAcqTime, eScanType);
                        if (masterScanIndex >= 0 && scanList.MasterScanOrderCount > 0)
                        {
                            computedScanTime = scanList.MasterScanTimeList[masterScanIndex];
                        }
                    }

                    break;

                case clsCustomSICList.eCustomSICScanTypeConstants.Relative:
                    // scanOrAcqTime is a fraction of the total number of scans (for example, 0.5)

                    // Use the total range of scan times
                    if (scanList.MasterScanOrderCount > 0)
                    {
                        var totalRunTime = scanList.MasterScanTimeList[scanList.MasterScanOrderCount - 1] - scanList.MasterScanTimeList[0];

                        computedScanTime = scanOrAcqTime * totalRunTime + scanList.MasterScanTimeList[0];
                    }
                    else
                    {
                        computedScanTime = 0;
                    }

                    break;

                case clsCustomSICList.eCustomSICScanTypeConstants.AcquisitionTime:
                    // scanOrAcqTime is an elution time value (or elution time range)
                    // No conversion needed; simply return the value
                    computedScanTime = scanOrAcqTime;
                    break;

                default:
                    // Unknown type; assume already a scan time
                    computedScanTime = scanOrAcqTime;
                    break;
                }

                return(computedScanTime);
            }
            catch (Exception ex)
            {
                OnErrorEvent("Error in clsMasic->ScanOrAcqTimeToScanTime", ex);
                return(0);
            }
        }