Пример #1
0
        /// <summary>
        /// The main Thrash algorithm.
        /// </summary>
        /// <param name="originalXYData">Mass spec XY data</param>
        /// <param name="msPeakList">Mass spec peak data</param>
        /// <param name="backgroundIntensity"></param>
        /// <param name="minPeptideIntensity"></param>
        /// <param name="minMSFeatureToBackgroundRatio"></param>
        /// <returns>List of isotopic profiles</returns>
        public List <IsotopicProfile> PerformThrash(XYData originalXYData,
                                                    List <Peak> msPeakList,
                                                    double backgroundIntensity    = 0,
                                                    double minPeptideIntensity    = 0, double
                                                    minMSFeatureToBackgroundRatio = 3)
        {
            var isotopicProfiles = new List <IsotopicProfile>();

            if (Parameters.AreAllTheoreticalProfilesCachedBeforeStarting)
            {
                CreateAllTheoreticalProfilesForMassRange();
            }

            var minMSFeatureIntensity = backgroundIntensity * minMSFeatureToBackgroundRatio;

            var xyData = new XYData
            {
                Xvalues = originalXYData.Xvalues,
                Yvalues = originalXYData.Yvalues
            };

            var sortedPeakList        = new List <Peak>(msPeakList).OrderByDescending(p => p.Height).ToList();
            var peaksAlreadyProcessed = new HashSet <Peak>();

            var sb = new StringBuilder();

            var listOfMonoMZs = new SortedDictionary <int, double>();
            var currentUniqueMSFeatureIDNum = 0;

            var peakCounter = -1;

            foreach (var msPeak in sortedPeakList)
            {
                //if (msPeak.XValue > 579.53 && msPeak.XValue < 579.54)
                //{
                //    int x = 90;
                //}
                var indexOfCurrentPeak = msPeakList.IndexOf(msPeak);

                if (peaksAlreadyProcessed.Contains(msPeak))
                {
                    continue;
                }

                var peakIsBelowIntensityThreshold = (msPeak.Height < minMSFeatureIntensity);
                if (peakIsBelowIntensityThreshold)
                {
                    break;
                }

                peakCounter++;

                if (peakCounter == 465)
                {
                    // Console.WriteLine(peakCounter);
                }

                //get potential charge states
                var ppmTolerance = (msPeak.Width / 2.35) / msPeak.XValue * 1e6;    //   peak's sigma value / mz * 1e6

                HashSet <int> potentialChargeStates;
                if (UseAutoCorrelationChargeDetermination)
                {
                    var chargeState = PattersonChargeStateCalculator.GetChargeState(xyData, msPeakList, msPeak as MSPeak);
                    potentialChargeStates = new HashSet <int> {
                        chargeState
                    };
                }
                else
                {   //Paul subtraction
                    IqLogger.LogTrace("MZ value: " + msPeak.XValue + "\n");
                    potentialChargeStates = GetPotentialChargeStates(indexOfCurrentPeak, msPeakList, ppmTolerance);
                    #region Paul Addition
                    var chargeDecider = new ChromCorrelatingChargeDecider(_run);
                    chargeDecider.GetPotentialChargeState(indexOfCurrentPeak, msPeakList, ppmTolerance);

                    #endregion
                }
                var reportString201 = "potentialChargeStates: ";
                foreach (var charge in potentialChargeStates)
                {
                    reportString201 += charge + "\t";
                }
                IqLogger.LogTrace(reportString201 + "\n");

                var potentialMSFeaturesForGivenChargeState = new List <IsotopicProfile>();
                foreach (var potentialChargeState in potentialChargeStates)
                {
                    var bestFitVal = 1.0;   // 1.0 is worst fit value. Start with 1.0 and see if we can find better fit value

                    //TODO: there could be a problem here
                    var msFeature = GetMSFeature(msPeakList, xyData, potentialChargeState, msPeak, ref bestFitVal, out var theorIso);

                    if (msFeature != null)
                    {
                        msFeature.Score = bestFitVal;
                        msFeature.IntensityMostAbundant = msFeature.getMostIntensePeak().Height;

                        var indexMostAbundantPeakTheor = theorIso.GetIndexOfMostIntensePeak();

                        //Paul edit. "&& indexMostAbundantPeakTheor>=0"
                        if (msFeature.Peaklist.Count > indexMostAbundantPeakTheor && indexMostAbundantPeakTheor >= 0)
                        {
                            msFeature.IntensityMostAbundantTheor = msFeature.Peaklist[indexMostAbundantPeakTheor].Height;
                        }
                        else
                        {
                            msFeature.IntensityMostAbundantTheor = msFeature.IntensityMostAbundant;
                        }

                        var msFeatureAlreadyPresentInAnotherChargeState = listOfMonoMZs.ContainsValue(msFeature.MonoPeakMZ);

                        if (!msFeatureAlreadyPresentInAnotherChargeState)
                        {
                            potentialMSFeaturesForGivenChargeState.Add(msFeature);
                        }
                        else
                        {
                            //Console.WriteLine( "Nope... not using this charge state... MSFeature already found with same MonoMZ. \tcurrent peak= \t" +msPeak.XValue.ToString("0.0000") + "\tmsfeature= " + msFeature);
                        }
                    }
                }

                IsotopicProfile isoProfile;
                if (potentialMSFeaturesForGivenChargeState.Count == 0)
                {
                    sb.Append(msPeak.XValue.ToString("0.00000") + "\tNo profile found.\n");
                    isoProfile = null;
                }
                else if (potentialMSFeaturesForGivenChargeState.Count == 1)
                {
                    isoProfile = potentialMSFeaturesForGivenChargeState[0];

                    sb.Append(msPeak.XValue.ToString("0.00000") + "\t" +
                              isoProfile.MonoPeakMZ.ToString("0.0000") + "\t" +
                              isoProfile.ChargeState + "\t" + isoProfile.Score + "\t" + ppmTolerance + "\n");
                }
                else
                {
                    sb.Append("Multiple candidates found...." + "\n");

                    foreach (var isotopicProfile in potentialMSFeaturesForGivenChargeState)
                    {
                        sb.Append(msPeak.XValue.ToString("0.00000") + "\t" +
                                  isotopicProfile.MonoPeakMZ.ToString("0.0000") + "\t" +
                                  isotopicProfile.ChargeState + "\t" + isotopicProfile.Score + "\t" + ppmTolerance + "\n");
                    }
                    sb.Append(Environment.NewLine);

                    if (Parameters.CheckAllPatternsAgainstChargeState1)
                    {
                        isoProfile = potentialMSFeaturesForGivenChargeState.FirstOrDefault(n => n.ChargeState == 1);
                    }
                    else
                    {
                        #region Paul addition
                        //TODO: [Paul]  This is the major means of deciding between charge states and where we need to do better.
                        //We need some test cases to capture this problem.
                        var stopwatch = new Stopwatch();

                        if (doPaulMethod)
                        {
                            var peaksNotLoaded = _run.ResultCollection.MSPeakResultList == null ||
                                                 _run.ResultCollection.MSPeakResultList.Count == 0;
                            if (peaksNotLoaded)
                            {
                                stopwatch.Start();
                                LoadPeaks(_run);
                                stopwatch.Stop();
                                IqLogger.LogDebug("stopwatch: " + stopwatch.Elapsed);
                            }
                            var brain = new ChromCorrelatingChargeDecider(_run);
                            isoProfile = brain.DetermineCorrectIsotopicProfile(potentialMSFeaturesForGivenChargeState.Where(n => n.Score < .50).ToList()) ??
                                         brain.DetermineCorrectIsotopicProfile(potentialMSFeaturesForGivenChargeState);
                            //hitcounter2++;
                        }
                        else//do it the regular way.
                        {
                            #endregion
                            isoProfile = (from n in potentialMSFeaturesForGivenChargeState
                                          where n.Score < 0.15
                                          orderby n.ChargeState descending
                                          select n).FirstOrDefault() ?? (from n in potentialMSFeaturesForGivenChargeState
                                                                         orderby n.Score
                                                                         select n).First();

                            #region Paul Addition
                        }
                        //line outputs.
                        var reportString309 = "\nM/Z = " + isoProfile.MonoPeakMZ +
                                              "\nCHOSEN CHARGE: " + isoProfile.ChargeState + "\n\n";
                        IqLogger.LogTrace(reportString309);

                        //tabular output
                        //string reportString309 = "\tM/Z = \t" + msfeature.MonoPeakMZ +
                        //        "\tCHOSEN CHARGE: \t" + msfeature.ChargeState+ "\n";
                        //IqLogger.Log.Debug(reportString309);
                        #endregion
                    }
                }

                if (isoProfile != null)
                {
                    listOfMonoMZs.Add(currentUniqueMSFeatureIDNum, isoProfile.MonoPeakMZ);
                    currentUniqueMSFeatureIDNum++;

                    isotopicProfiles.Add(isoProfile);
                    //hitcounter++;//Paul Addition

                    foreach (var peak in isoProfile.Peaklist)
                    {
                        //For debugging
                        //if (peak.XValue > 534.76515 && peak.XValue < 534.78515) //(peak.XValue>579.62 && peak.XValue<579.65) || (peak.XValue>579.75 && peak.XValue<579.8))
                        //{
                        //    int x = 39843;
                        //}
                        peaksAlreadyProcessed.Add(peak);
                    }
                }
            }//end of foreach peak loop

            //Console.WriteLine(sb.ToString());

            var uniqueIsotopicProfiles = removeDuplicatesFromFoundMSFeatures(isotopicProfiles);
            #region Paul Addition
            //IqLogger.Log.Debug("Hit counter: " + hitcounter);
            //IqLogger.Log.Debug("Hit counter2: " + hitcounter2);
            //var uniqueOtherIsotopicProfiles = removeDuplicatesFromFoundMSFeatures(isotopicProfiles);

            //IqLogger.Log.Debug("old non unique count: " + otherIsotopicProfiles.Count + "\n" +
            //    "new non unique count: " + myIsotopicProfiles.Count + "\n");
            //var uniqueMyIsotopicProfiles = removeDuplicatesFromFoundMSFeatures(myIsotopicProfiles);

            //IqLogger.Log.Debug("\nOld unique profile count: " + uniqueOtherIsotopicProfiles.Count + "\n" +
            //    "New unique profile count: " + uniqueMyIsotopicProfiles.Count);
            //IqLogger.Log.Debug("\nunique profile count: " + uniqueIsotopicProfiles.Count + "\n");

            #endregion
            //NOTE: we don't need to do the reordering, but I do this so I can compare to the old THRASH
            uniqueIsotopicProfiles = uniqueIsotopicProfiles.OrderByDescending(p => p.IntensityMostAbundantTheor).ToList();
            return(uniqueIsotopicProfiles);
        }