private int GetScanData(XRawFileIO reader, clsScanInfo scanInfo, out double[] mzList, out double[] intensityList)
        {
            if (scanInfo.IsFTMS)
            {
                var labelDataCount = reader.GetScanLabelData(scanInfo.ScanNumber, out var labelData);

                if (labelDataCount > 0)
                {
                    mzList        = new double[labelDataCount];
                    intensityList = new double[labelDataCount];

                    for (var i = 0; i < labelDataCount; i++)
                    {
                        mzList[i]        = labelData[i].Mass;
                        intensityList[i] = labelData[i].Intensity;
                    }

                    return(labelDataCount);
                }
            }

            var dataPointCount = reader.GetScanData(scanInfo.ScanNumber, out mzList, out intensityList, 0, true);

            return(dataPointCount);
        }
예제 #2
0
        private List<XYData> LoadRawSpectra(XRawFileIO rawReader, int scan)
        {
            double[] mz;
            double[] intensities;
            rawReader.GetScanData(scan, out mz, out intensities);

            if (mz == null)
                return new List<XYData>();

            var data = new List<XYData>(mz.Length);
            for (var i = 0; i < mz.Length; i++)
            {
                var intensity = intensities[i];
                data.Add(new XYData(mz[i], intensity));
            }
            return data;
        }
예제 #3
0
        private static void TestReader(string rawFilePath, bool centroid = false, bool testSumming = false, int scanStart = 0, int scanEnd = 0)
        {
            try
            {
                var rawFile = ResolveDataFile(rawFilePath);
                if (rawFile == null)
                {
                    return;
                }

                var options = new ThermoReaderOptions {
                    LoadMSMethodInfo = mLoadMethods
                };

                using (var reader = new XRawFileIO(rawFile.FullName, options, mTraceMode))
                {
                    RegisterEvents(reader);

                    var numScans = reader.GetNumScans();

                    var collisionEnergyList = string.Empty;

                    ShowMethod(reader);

                    var scanStep = 1;

                    if (scanStart < 1)
                    {
                        scanStart = 1;
                    }

                    if (scanEnd < 1)
                    {
                        scanEnd  = numScans;
                        scanStep = 21;
                    }
                    else
                    {
                        if (scanEnd < scanStart)
                        {
                            scanEnd = scanStart;
                        }
                    }

                    if (scanEnd > numScans)
                    {
                        scanEnd = numScans;
                    }

                    var msLevelStats = new Dictionary <int, int>();

                    Console.WriteLine();
                    Console.WriteLine("Reading data for scans {0} to {1}, step {2}", scanStart, scanEnd, scanStep);

                    for (var scanNum = scanStart; scanNum <= scanEnd; scanNum += scanStep)
                    {
                        if (scanNum > reader.ScanEnd)
                        {
                            ConsoleMsgUtils.ShowWarning("Exiting for loop since scan number {0} is greater than the max scan number, {1}", scanNum, reader.ScanEnd);
                            break;
                        }

                        if (mOnlyLoadMSLevelInfo)
                        {
                            var msLevel = reader.GetMSLevel(scanNum);

                            if (msLevelStats.TryGetValue(msLevel, out var msLevelObsCount))
                            {
                                msLevelStats[msLevel] = msLevelObsCount + 1;
                            }
                            else
                            {
                                msLevelStats.Add(msLevel, 1);
                            }
                            if (mScanInfoInterval <= 0 || scanNum % mScanInfoInterval == 0)
                            {
                                Console.WriteLine("Scan " + scanNum);
                            }

                            continue;
                        }

                        var success = reader.GetScanInfo(scanNum, out clsScanInfo scanInfo);

                        if (!success)
                        {
                            continue;
                        }

                        if (mScanInfoInterval <= 0 || scanNum % mScanInfoInterval == 0)
                        {
                            Console.WriteLine("Scan " + scanNum + " at " + scanInfo.RetentionTime.ToString("0.00") + " minutes: " + scanInfo.FilterText);
                        }

                        if (mLoadCollisionEnergies)
                        {
                            var collisionEnergies = reader.GetCollisionEnergy(scanNum);

                            if (collisionEnergies.Count == 0)
                            {
                                collisionEnergyList = string.Empty;
                            }
                            else if (collisionEnergies.Count >= 1)
                            {
                                collisionEnergyList = collisionEnergies[0].ToString("0.0");

                                if (collisionEnergies.Count > 1)
                                {
                                    for (var index = 1; index <= collisionEnergies.Count - 1; index++)
                                    {
                                        collisionEnergyList += ", " + collisionEnergies[index].ToString("0.0");
                                    }
                                }
                            }

                            if (string.IsNullOrEmpty(collisionEnergyList))
                            {
                                Console.WriteLine();
                            }
                            else
                            {
                                Console.WriteLine("; CE " + collisionEnergyList);
                            }
                        }

                        if (mGetScanEvents)
                        {
                            if (scanInfo.TryGetScanEvent("Monoisotopic M/Z:", out var monoMZ))
                            {
                                Console.WriteLine("Monoisotopic M/Z: " + monoMZ);
                            }

                            if (scanInfo.TryGetScanEvent("Charge State", out var chargeState, true))
                            {
                                Console.WriteLine("Charge State: " + chargeState);
                            }

                            if (scanInfo.TryGetScanEvent("MS2 Isolation Width", out var isolationWidth, true))
                            {
                                Console.WriteLine("MS2 Isolation Width: " + isolationWidth);
                            }
                        }

                        if (!mLoadScanData || (scanNum % 50 != 0 && scanEnd - scanStart > 50))
                        {
                            continue;
                        }

                        // Get the data for scan scanNum
                        Console.WriteLine();
                        Console.WriteLine("Spectrum for scan " + scanNum);

                        reader.GetScanData(scanNum, out var mzList, out var intensityList, 0, centroid);

                        var mzDisplayStepSize = 50;
                        if (centroid)
                        {
                            mzDisplayStepSize = 1;
                        }

                        for (var i = 0; i <= mzList.Length - 1; i += mzDisplayStepSize)
                        {
                            Console.WriteLine("  " + mzList[i].ToString("0.000") + " mz   " + intensityList[i].ToString("0"));
                        }
                        Console.WriteLine();

                        const int scansToSum = 15;

                        if (scanNum + scansToSum < numScans && testSumming)
                        {
                            // Get the data for scan scanNum through scanNum + 15

#pragma warning disable 618
                            reader.GetScanDataSumScans(scanNum, scanNum + scansToSum, out var massIntensityPairs, 0, centroid);
#pragma warning restore 618

                            Console.WriteLine("Summed spectrum, scans " + scanNum + " through " + (scanNum + scansToSum));

                            for (var i = 0; i <= massIntensityPairs.GetLength(1) - 1; i += 50)
                            {
                                Console.WriteLine("  " + massIntensityPairs[0, i].ToString("0.000") + " mz   " +
                                                  massIntensityPairs[1, i].ToString("0"));
                            }

                            Console.WriteLine();
                        }

                        if (!scanInfo.IsFTMS)
                        {
                            continue;
                        }

                        var dataCount = reader.GetScanLabelData(scanNum, out var ftLabelData);

                        Console.WriteLine();
                        Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}{5,12}", "Mass", "Intensity", "Resolution", "Baseline", "Noise", "Charge");


                        for (var i = 0; i <= dataCount - 1; i += 50)
                        {
                            Console.WriteLine("{0,12:F3}{1,12:0}{2,12:0}{3,12:F1}{4,12:0}{5,12:0}",
                                              ftLabelData[i].Mass,
                                              ftLabelData[i].Intensity,
                                              ftLabelData[i].Resolution,
                                              ftLabelData[i].Baseline,
                                              ftLabelData[i].Noise,
                                              ftLabelData[i].Charge);
                        }

                        dataCount = reader.GetScanPrecisionData(scanNum, out var ftPrecisionData);

                        Console.WriteLine();
                        Console.WriteLine("{0,12}{1,12}{2,12}{3,12}{4,12}", "Mass", "Intensity", "AccuracyMMU", "AccuracyPPM", "Resolution");


                        for (var i = 0; i <= dataCount - 1; i += 50)
                        {
                            Console.WriteLine("{0,12:F3}{1,12:0}{2,12:F3}{3,12:F3}{4,12:0}",
                                              ftPrecisionData[i].Mass,
                                              ftPrecisionData[i].Intensity, ftPrecisionData[i].AccuracyMMU,
                                              ftPrecisionData[i].AccuracyPPM,
                                              ftPrecisionData[i].Resolution);
                        }
                    }

                    if (mOnlyLoadMSLevelInfo)
                    {
                        Console.WriteLine();
                        Console.WriteLine("{0,-10} {1}", "MSLevel", "Scans");
                        foreach (var item in msLevelStats)
                        {
                            Console.WriteLine("{0, -10} {1}", item.Key, item.Value);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError("Error in TestReader: " + ex.Message, ex);
            }
        }
예제 #4
0
        public void AddMs2ScanParameters(XRawFileIO reader)
        {
            // grab precursorMz from raw file
            var success = reader.GetScanInfo(ScanNumber, out var scanInfo);

            if (!success)
            {
                ConsoleMsgUtils.ShowWarning("Scan {0} not found by AddMs2ScanParameters", ScanNumber);
                return;
            }

            var precursorMzValue = Math.Round(scanInfo.ParentIonMZ, 8);

            var parentScanInfo = GetParentScan(reader, scanInfo);

            var parentScanDataCount = reader.GetScanData(parentScanInfo.ScanNumber, out var mzList, out var intensityList);

            double precursorIntensity = 0;

            if (parentScanDataCount > 0)
            {
                const double PRECURSOR_TOLERANCE = 0.1;

                var closestDifference = double.MaxValue;
                for (var i = 0; i < mzList.Length; i++)
                {
                    var mzDifference = Math.Abs(mzList[i] - precursorMzValue);
                    if (mzDifference > closestDifference)
                    {
                        continue;
                    }

                    closestDifference  = mzDifference;
                    precursorIntensity = Math.Round(intensityList[i], 2);
                }

                if (closestDifference > PRECURSOR_TOLERANCE)
                {
                    // couldn't find precursor mass in MS1. That's fine i guess.
                    precursorIntensity = 0;
                }
            }

            var filterLineParts = FilterLine.Split(' ');

            string activationType;

            switch (scanInfo.ActivationType)
            {
            case ActivationTypeConstants.CID:
            case ActivationTypeConstants.MPD:
            case ActivationTypeConstants.ECD:
            case ActivationTypeConstants.PQD:
            case ActivationTypeConstants.ETD:
            case ActivationTypeConstants.HCD:
            case ActivationTypeConstants.SA:
            case ActivationTypeConstants.PTR:
            case ActivationTypeConstants.NETD:
            case ActivationTypeConstants.NPTR:
            case ActivationTypeConstants.UVPD:
                activationType = scanInfo.ActivationType.ToString();
                break;

            default:
                // Includes ActivationTypeConstants.AnyType
                activationType = "CID";
                break;
            }

            foreach (var param in filterLineParts)
            {
                if (param.Contains("@"))
                {
                    // HCD25.00 -> [HCD, 25.00]
                    // RegEx alpha from numeric
                    var activationArray = Regex.Matches(param.Split('@')[1].Trim(), @"\D+|\d+").Cast <Match>().Select(m => m.Value).ToArray();

                    CollisionEnergy = Convert.ToInt32(double.Parse(activationArray[1]));
                }
            }

            PrecursorMz = new PrecursorMz(precursorIntensity, activationType, precursorMzValue);
        }
예제 #5
0
        private bool LoadSpectraForThermoRawFile(
            XRawFileIO xcaliburAccessor,
            clsSpectraCache spectraCache,
            clsScanInfo scanInfo,
            clsBaselineNoiseOptions noiseThresholdOptions,
            bool discardLowIntensityData,
            bool compressSpectraData,
            double msDataResolution,
            bool keepRawSpectrum)
        {
            var lastKnownLocation = "Start";

            try
            {
                // Load the ions for this scan

                lastKnownLocation = "xcaliburAccessor.GetScanData for scan " + scanInfo.ScanNumber;

                // Retrieve the m/z and intensity values for the given scan
                // We retrieve the profile-mode data, since that's required for determining spectrum noise
                scanInfo.IonCountRaw = xcaliburAccessor.GetScanData(scanInfo.ScanNumber, out var mzList, out var intensityList);

                if (scanInfo.IonCountRaw > 0)
                {
                    var ionCountVerified = VerifyDataSorted(scanInfo.ScanNumber, scanInfo.IonCountRaw, mzList, intensityList);
                    if (ionCountVerified != scanInfo.IonCountRaw)
                    {
                        scanInfo.IonCountRaw = ionCountVerified;
                    }
                }

                scanInfo.IonCount = scanInfo.IonCountRaw;

                lastKnownLocation = "Instantiate new clsMSSpectrum";

                var msSpectrum = new clsMSSpectrum(scanInfo.ScanNumber, mzList, intensityList, scanInfo.IonCountRaw);

                lastKnownLocation = "Manually determine the base peak m/z and base peak intensity";

                // ReSharper disable once CommentTypo

                // Regarding BPI, comparison of data read via the ThermoRawFileReader vs.
                // that read from the .mzML file for dataset QC_Shew_18_02-run1_02Mar19_Arwen_18-11-02
                // showed that 25% of the spectra had incorrect BPI values

                double totalIonIntensity = 0;
                double basePeakIntensity = 0;
                double basePeakMz        = 0;

                for (var ionIndex = 0; ionIndex < scanInfo.IonCountRaw; ionIndex++)
                {
                    totalIonIntensity += intensityList[ionIndex];
                    if (intensityList[ionIndex] > basePeakIntensity)
                    {
                        basePeakIntensity = intensityList[ionIndex];
                        basePeakMz        = mzList[ionIndex];
                    }
                }

                if (Math.Abs(scanInfo.BasePeakIonMZ - basePeakMz) > 0.1)
                {
                    mBpiUpdateCount += 1;

                    if (mBpiUpdateCount < 10)
                    {
                        ConsoleMsgUtils.ShowDebug("Updating BPI in scan {0} from {1:F3} m/z to {2:F3} m/z, and BPI Intensity from {3:F0} to {4:F0}",
                                                  scanInfo.ScanNumber, scanInfo.BasePeakIonMZ, basePeakMz, scanInfo.BasePeakIonIntensity, basePeakIntensity);
                    }

                    scanInfo.BasePeakIonMZ        = basePeakMz;
                    scanInfo.BasePeakIonIntensity = basePeakIntensity;
                }

                // Determine the minimum positive intensity in this scan
                lastKnownLocation = "Call mMASICPeakFinder.FindMinimumPositiveValue";
                scanInfo.MinimumPositiveIntensity = mPeakFinder.FindMinimumPositiveValue(msSpectrum.IonsIntensity, 0);

                if (msSpectrum.IonCount > 0)
                {
                    if (scanInfo.TotalIonIntensity < float.Epsilon)
                    {
                        scanInfo.TotalIonIntensity = totalIonIntensity;
                    }
                }
                else
                {
                    scanInfo.TotalIonIntensity = 0;
                }

                bool discardLowIntensityDataWork;
                bool compressSpectraDataWork;

                if (scanInfo.MRMScanType == MRMScanTypeConstants.NotMRM)
                {
                    discardLowIntensityDataWork = discardLowIntensityData;
                    compressSpectraDataWork     = compressSpectraData;
                }
                else
                {
                    discardLowIntensityDataWork = false;
                    compressSpectraDataWork     = false;
                }

                lastKnownLocation = "Call ProcessAndStoreSpectrum";
                mScanTracking.ProcessAndStoreSpectrum(
                    scanInfo, this,
                    spectraCache, msSpectrum,
                    noiseThresholdOptions,
                    discardLowIntensityDataWork,
                    compressSpectraDataWork,
                    msDataResolution,
                    keepRawSpectrum);
            }
            catch (Exception ex)
            {
                ReportError("Error in LoadSpectraForThermoRawFile (LastKnownLocation: " + lastKnownLocation + ")", ex, clsMASIC.eMasicErrorCodes.InputFileDataReadError);
                return(false);
            }

            return(true);
        }
예제 #6
0
        private double ComputeInterference(
            XRawFileIO xcaliburAccessor,
            ThermoRawFileReader.clsScanInfo scanInfo,
            int precursorScanNumber)
        {
            if (precursorScanNumber != mCachedPrecursorScan)
            {
                xcaliburAccessor.GetScanData(precursorScanNumber, out var centroidedIonsMz, out var centroidedIonsIntensity, 0, true);

                UpdateCachedPrecursorScan(precursorScanNumber, centroidedIonsMz, centroidedIonsIntensity);
            }

            var chargeState = 0;

            scanInfo.TryGetScanEvent(SCAN_EVENT_CHARGE_STATE, out var chargeStateText, true);
            if (!string.IsNullOrWhiteSpace(chargeStateText))
            {
                if (!int.TryParse(chargeStateText, out chargeState))
                {
                    chargeState = 0;
                }
            }

            if (!scanInfo.TryGetScanEvent(SCAN_EVENT_MS2_ISOLATION_WIDTH, out var isolationWidthText, true))
            {
                if (scanInfo.MRMScanType == MRMScanTypeConstants.SRM)
                {
                    // SRM data files don't have the MS2 Isolation Width event
                    return(0);
                }

                WarnIsolationWidthNotFound(
                    scanInfo.ScanNumber,
                    "Could not determine the MS2 isolation width (" + SCAN_EVENT_MS2_ISOLATION_WIDTH + ")");

                return(0);
            }

            if (!double.TryParse(isolationWidthText, out var isolationWidth))
            {
                ReportWarning("MS2 isolation width (" + SCAN_EVENT_MS2_ISOLATION_WIDTH + ") was non-numeric (" + isolationWidthText + "); " +
                              "cannot compute interference for scan " + scanInfo.ScanNumber);
                return(0);
            }

            double parentIonMz;

            if (Math.Abs(scanInfo.ParentIonMZ) > 0)
            {
                parentIonMz = scanInfo.ParentIonMZ;
            }
            else
            {
                // ThermoRawFileReader could not determine the parent ion m/z value (this is highly unlikely)
                // Use scan event "Monoisotopic M/Z" instead
                if (!scanInfo.TryGetScanEvent(SCAN_EVENT_MONOISOTOPIC_MZ, out var monoMzText, true))
                {
                    ReportWarning("Could not determine the parent ion m/z value (" + SCAN_EVENT_MONOISOTOPIC_MZ + "); " +
                                  "cannot compute interference for scan " + scanInfo.ScanNumber);
                    return(0);
                }

                if (!double.TryParse(monoMzText, out var mz))
                {
                    OnWarningEvent(string.Format("Skipping scan {0} since scan event {1} was not a number: {2}",
                                                 scanInfo.ScanNumber, SCAN_EVENT_MONOISOTOPIC_MZ, monoMzText));
                    return(0);
                }

                parentIonMz = mz;
            }

            if (Math.Abs(parentIonMz) < float.Epsilon)
            {
                ReportWarning("Parent ion m/z is 0; cannot compute interference for scan " + scanInfo.ScanNumber);
                return(0);
            }

            var precursorInterference = ComputePrecursorInterference(
                scanInfo.ScanNumber,
                precursorScanNumber, parentIonMz, isolationWidth, chargeState);

            return(precursorInterference);
        }
예제 #7
0
        public List <CompoundData> ReadSpectraData(List <CompoundData> combinedTransitions)
        {
            var scanTimes = new Dictionary <int, double>();

            using (var rawReader = new XRawFileIO(DatasetPath))
            {
                var numScans = rawReader.GetNumScans();
                if (numScans <= 0)
                {
                    // dataset has no MS data. Return.
                    return(null);
                }

                for (var i = 1; i <= numScans; i++)
                {
                    var err = rawReader.GetRetentionTime(i, out double time);
                    scanTimes.Add(i, time);
                    // Filter string parsing for speed: "+ c NSI SRM ms2 [precursor/parent m/z] [[list of product m/z ranges]]
                }

                // Map transition start/stop times to scans
                var scansAndTargets = new Dictionary <int, List <CompoundData> >();
                foreach (var scan in scanTimes)
                {
                    var matches = combinedTransitions
                                  .Where(x => x.StartTimeMinutes <= scan.Value && scan.Value <= x.StopTimeMinutes).ToList();
                    if (matches.Count > 0)
                    {
                        scansAndTargets.Add(scan.Key, matches);
                    }
                }

                rawReader.ScanInfoCacheMaxSize = 2;

                // read spectra data for each transition from the file, in an optimized fashion
                foreach (var scan in scansAndTargets)
                {
                    rawReader.GetScanInfo(scan.Key, out clsScanInfo scanInfo);
                    var preMz = scanInfo.ParentIonMZ;
                    rawReader.GetScanData(scan.Key, out var mzs, out var intensities);

                    foreach (var compound in scan.Value.Where(x => Math.Abs(x.PrecursorMz - preMz) < 0.01))
                    {
                        foreach (var massRange in scanInfo.MRMInfo.MRMMassList)
                        {
                            var match = compound.Transitions.FirstOrDefault(x => massRange.StartMass <= x.ProductMz && x.ProductMz <= massRange.EndMass);
                            if (match == null)
                            {
                                continue;
                            }

                            for (var j = 0; j < mzs.Length; j++)
                            {
                                var mz        = mzs[j];
                                var intensity = intensities[j];

                                if (massRange.StartMass <= mz && mz <= massRange.EndMass)
                                {
                                    match.IntensitySum += intensity;
                                    match.Intensities.Add(new TransitionData.DataPoint(scan.Key, scanTimes[scan.Key], intensity));
                                    if (intensity > match.MaxIntensity)
                                    {
                                        match.MaxIntensity     = intensity;
                                        match.MaxIntensityTime = scanTimes[scan.Key];
                                    }
                                }
                            }
                        }
                    }
                }
            }

            return(combinedTransitions.ToList());
        }