Exemplo n.º 1
0
        protected override void IterateOverScans()
        {
            DeconMSnResults.Clear();
            _scanCounter = 0;

            var resultCounter = 0;

            foreach (var scanSet in Run.ScanSetCollection.ScanSetList)
            {
                _scanCounter++;

                if (BackgroundWorker != null)
                {
                    if (BackgroundWorker.CancellationPending)
                    {
                        return;
                    }
                }

                //check ms level
                var currentMSLevel = Run.GetMSLevel(scanSet.PrimaryScanNumber);

                if (currentMSLevel == 1)
                {
                    Run.ResultCollection.IsosResultBin.Clear();

                    Run.CurrentScanSet = scanSet;

                    MSGenerator.Execute(Run.ResultCollection);

                    _currentMS1XYValues = new XYData
                    {
                        Xvalues = Run.XYData.Xvalues,
                        Yvalues = Run.XYData.Yvalues
                    };

                    _currentMS1TICIntensity = Run.GetTICFromInstrumentInfo(scanSet.PrimaryScanNumber);

                    PeakDetector.Execute(Run.ResultCollection);
                    _currentMS1Peaks = new List <Peak>(Run.PeakList);
                }
                else if (currentMSLevel == 2)
                {
                    if (_currentMS1Peaks == null || _currentMS1Peaks.Count == 0)
                    {
                        continue;
                    }

                    var precursorInfo = Run.GetPrecursorInfo(scanSet.PrimaryScanNumber);
                    Run.CurrentScanSet = scanSet;
                    var inaccurateParentMZ = precursorInfo.PrecursorMZ;

                    resultCounter++;
                    var deconMSnResult = new DeconMSnResult {
                        ParentScan = Run.GetParentScan(scanSet.PrimaryScanNumber)
                    };
                    deconMSnResult.IonInjectionTime       = Run.GetIonInjectionTimeInMilliseconds(deconMSnResult.ParentScan);
                    deconMSnResult.ScanNum                = scanSet.PrimaryScanNumber;
                    deconMSnResult.OriginalMZTarget       = inaccurateParentMZ;
                    deconMSnResult.ParentScanTICIntensity = _currentMS1TICIntensity;

                    MSGenerator.Execute(Run.ResultCollection);

                    var lowerMZ = inaccurateParentMZ - 1.1;
                    var upperMZ = inaccurateParentMZ + 1.1;

                    var dataIsCentroided = Run.IsDataCentroided(scanSet.PrimaryScanNumber);
                    if (dataIsCentroided)
                    {
                        _ms2PeakDetectorForCentroidData.Execute(Run.ResultCollection);
                    }
                    else
                    {
                        _ms2PeakDetectorForProfileData.Execute(Run.ResultCollection);
                    }
                    var ms2Peaks = new List <Peak>(Run.PeakList);

                    var filteredMS1Peaks = _currentMS1Peaks.Where(p => p.XValue > lowerMZ && p.XValue < upperMZ).ToList();

                    IsotopicProfile selectedMS1Feature = null;
                    for (var attemptNum = 0; attemptNum < NumMaxAttemptsAtLowIntensitySpecies; attemptNum++)
                    {
                        var candidateMS1Features = GetCandidateMS1Features(inaccurateParentMZ, filteredMS1Peaks);

                        //if none were found, will regenerate MS1 spectrum and find peaks again
                        if (candidateMS1Features.Count == 0)
                        {
                            var numSummed = attemptNum * 2 + 3;
                            var ms1Scan   = precursorInfo.PrecursorScan;

                            var ms1ScanSet = new ScanSetFactory().CreateScanSet(Run, ms1Scan, numSummed);

                            //get MS1 mass spectrum again. This time sum spectra
                            Run.CurrentScanSet = ms1ScanSet;
                            MSGenerator.Execute(Run.ResultCollection);

                            //run MS1 peak detector, with greater sensitivity
                            var isLastAttempt = attemptNum >= NumMaxAttemptsAtLowIntensitySpecies - 2;    //need to do -2 because of the way the loop advances the counter.

                            if (isLastAttempt)
                            {
                                _superSensitiveMS1PeakDetector.MinX = lowerMZ;
                                _superSensitiveMS1PeakDetector.MaxX = upperMZ;
                                _superSensitiveMS1PeakDetector.Execute(Run.ResultCollection);
                                filteredMS1Peaks = new List <Peak>(Run.PeakList);
                            }
                            else
                            {
                                _moreSensitiveMS1PeakDetector.Execute(Run.ResultCollection);
                                var moreSensitiveMS1Peaks = new List <Peak>(Run.PeakList);
                                filteredMS1Peaks = moreSensitiveMS1Peaks.Where(p => p.XValue > lowerMZ && p.XValue < upperMZ).ToList();
                            }
                        }
                        else if (candidateMS1Features.Count == 1)
                        {
                            selectedMS1Feature = candidateMS1Features.First();
                            break;   //we found something, so no need for any further attempts
                        }
                        else
                        {
                            var highQualityCandidates = candidateMS1Features.Where(p => p.Score < 0.15).ToList();
                            if (highQualityCandidates.Count == 0)
                            {
                                selectedMS1Feature = candidateMS1Features.OrderByDescending(p => p.IntensityMostAbundantTheor).First();
                            }
                            else if (highQualityCandidates.Count == 1)
                            {
                                selectedMS1Feature = highQualityCandidates.First();
                            }
                            else
                            {
                                selectedMS1Feature = highQualityCandidates.OrderByDescending(p => p.IntensityMostAbundantTheor).First();
                            }

                            deconMSnResult.ExtraInfo = "Warning - multiple MSFeatures found for target parent MZ";
                            break;   //we found something, so no need for any further attempts
                        }
                    }

                    if (selectedMS1Feature != null)
                    {
                        deconMSnResult.ParentMZ           = selectedMS1Feature.MonoPeakMZ;
                        deconMSnResult.ParentChargeState  = selectedMS1Feature.ChargeState;
                        deconMSnResult.ParentIntensity    = selectedMS1Feature.IntensityMostAbundantTheor;
                        deconMSnResult.IntensityAggregate = selectedMS1Feature.IntensityMostAbundantTheor;
                        deconMSnResult.IsotopicProfile    = selectedMS1Feature;
                    }
                    else
                    {
                        var candidatePeaks = new List <Peak>();

                        foreach (var peak in filteredMS1Peaks)
                        {
                            var currentDiff = Math.Abs(peak.XValue - inaccurateParentMZ);

                            var toleranceInMZ = ToleranceInPPM * peak.XValue / 1e6;

                            if (currentDiff < toleranceInMZ)
                            {
                                candidatePeaks.Add(peak);
                            }
                        }

                        Peak selectedPeak = null;

                        if (candidatePeaks.Count == 0)
                        {
                            //cannot even find a suitable MS1 peak. So can't do anything
                        }
                        else if (candidatePeaks.Count == 1)
                        {
                            selectedPeak = candidatePeaks.First();
                        }
                        else
                        {
                            selectedPeak = candidatePeaks.OrderByDescending(p => p.Height).First();
                        }

                        if (selectedPeak != null)
                        {
                            deconMSnResult.ParentMZ          = selectedPeak.XValue;
                            deconMSnResult.ParentChargeState = 1;   //not sure what charge I should assign... Ask SangTae
                            deconMSnResult.ParentIntensity   = selectedPeak.Height;
                            deconMSnResult.IsotopicProfile   = null;
                            deconMSnResult.ExtraInfo         = "Failure code 1: No MSFeature, but peak found";
                        }
                        else
                        {
                            deconMSnResult.ParentMZ          = precursorInfo.PrecursorMZ; //could not find the accurate parentMZ, so just report what the instrument found.
                            deconMSnResult.ParentChargeState = 1;                         //not sure what charge I should assign... Ask SangTae
                            deconMSnResult.ParentIntensity   = 0;
                            deconMSnResult.IsotopicProfile   = null;
                            deconMSnResult.ExtraInfo         = "Failure code 2: No MSFeature or peak found";
                        }
                    }

                    //Build export data.
                    var outputString = GetMGFOutputString(Run, scanSet.PrimaryScanNumber, deconMSnResult, ms2Peaks);

                    var includeHeader = resultCounter == 1;
                    var summaryString = GetSummaryString(deconMSnResult, includeHeader);

                    var parentProfileString = GetParentProfileString(deconMSnResult, includeHeader);

                    if (ExportData)
                    {
                        WriteOutMainData(outputString);

                        WriteOutDeconMSnSummary(summaryString);

                        if (IsParentProfileDataExported)
                        {
                            WriteOutParentProfileInfoString(parentProfileString);
                        }
                    }

                    if (deconMSnResult.ParentIntensity > 0)
                    {
                        DeconMSnResults.Add(deconMSnResult);
                    }
                }
                else
                {
                    throw new ApplicationException(
                              "DeconMSn only works on MS1 and MS2 data; You are attempting MS3");
                }

                ReportProgress();
            }
        }