Exemplo n.º 1
0
        /// <summary>
        /// Looks through the result and finds ion mobility values.
        /// Note that this method only returns new values that were found in results.
        /// The returned dictionary should be merged with the existing values in
        /// order to preserve those existing values.
        /// </summary>
        public Dictionary <LibKey, IonMobilityAndCCS> FindIonMobilityPeaks()
        {
            // Overwrite any existing measurements with newly derived ones
            var measured = new Dictionary <LibKey, IonMobilityAndCCS>();

            if (_document.Settings.MeasuredResults == null)
            {
                return(measured);
            }

            var filepaths = _document.Settings.MeasuredResults.MSDataFilePaths.ToArray();

            _totalSteps = filepaths.Length * _document.MoleculeTransitionGroupCount;
            if (_totalSteps == 0)
            {
                return(measured);
            }

            using (_msDataFileScanHelper = new MsDataFileScanHelper(SetScans, HandleLoadScanException))
            {
                //
                // Avoid opening and re-opening raw files - make these the outer loop
                //

                _ms1IonMobilities = new Dictionary <LibKey, List <IonMobilityIntensityPair> >();
                _ms2IonMobilities = new Dictionary <LibKey, List <IonMobilityIntensityPair> >();
                var twopercent = (int)Math.Ceiling(_totalSteps * 0.02);
                _totalSteps += twopercent;
                _currentStep = twopercent;
                if (_progressMonitor != null)
                {
                    _progressStatus = new ProgressStatus(filepaths.First().GetFileName());
                    _progressStatus = _progressStatus.UpdatePercentCompleteProgress(_progressMonitor, _currentStep, _totalSteps); // Make that inital lag seem less dismal to the user
                }
                foreach (var fp in filepaths)
                {
                    if (!ProcessFile(fp))
                    {
                        return(null); // User cancelled
                    }
                }
                // Find ion mobilities based on MS1 data
                foreach (var dt in _ms1IonMobilities)
                {
                    // Choose the ion mobility which gave the largest signal
                    // CONSIDER: average IM and CCS values that fall "near" the IM of largest signal?
                    var ms1IonMobility = dt.Value.OrderByDescending(p => p.Intensity).First().IonMobility;
                    // Check for MS2 data to use for high energy offset
                    List <IonMobilityIntensityPair> listDt;
                    var ms2IonMobility = _ms2IonMobilities.TryGetValue(dt.Key, out listDt)
                        ? listDt.OrderByDescending(p => p.Intensity).First().IonMobility
                        : ms1IonMobility;
                    var value = IonMobilityAndCCS.GetIonMobilityAndCCS(ms1IonMobility.IonMobility, ms1IonMobility.CollisionalCrossSectionSqA, ms2IonMobility.IonMobility.Mobility.Value - ms1IonMobility.IonMobility.Mobility.Value);
                    if (!measured.ContainsKey(dt.Key))
                    {
                        measured.Add(dt.Key, value);
                    }
                    else
                    {
                        measured[dt.Key] = value;
                    }
                }
                // Check for data for which we have only MS2 to go on
                foreach (var im in _ms2IonMobilities)
                {
                    if (!_ms1IonMobilities.ContainsKey(im.Key))
                    {
                        // Only MS2 ion mobility values found, use that as a reasonable inference of MS1 ion mobility
                        var driftTimeIntensityPair = im.Value.OrderByDescending(p => p.Intensity).First();
                        var value = driftTimeIntensityPair.IonMobility;
                        // Note collisional cross section
                        if (_msDataFileScanHelper.ProvidesCollisionalCrossSectionConverter)
                        {
                            var mz  = im.Key.PrecursorMz ?? GetMzFromDocument(im.Key);
                            var ccs = _msDataFileScanHelper.CCSFromIonMobility(value.IonMobility,
                                                                               mz, im.Key.Charge);
                            if (ccs.HasValue)
                            {
                                value = IonMobilityAndCCS.GetIonMobilityAndCCS(value.IonMobility, ccs, value.HighEnergyIonMobilityValueOffset);
                            }
                        }

                        if (!measured.ContainsKey(im.Key))
                        {
                            measured.Add(im.Key, value);
                        }
                        else
                        {
                            measured[im.Key] = value;
                        }
                    }
                }
            }
            return(measured);
        }
Exemplo n.º 2
0
        private void EvaluateBestIonMobilityValue(int msLevel, LibKey libKey, float tolerance, List <TransitionFullScanInfo> transitions)
        {
            IonMobilityValue ionMobilityValue = IonMobilityValue.EMPTY;
            double           maxIntensity     = 0;

            // Avoid picking MS2 ion mobility values wildly different from MS1 valuess
            IonMobilityValue ms1IonMobilityBest;

            if ((msLevel == 2) && _ms1IonMobilities.ContainsKey(libKey))
            {
                ms1IonMobilityBest =
                    _ms1IonMobilities[libKey].OrderByDescending(p => p.Intensity)
                    .FirstOrDefault()
                    .IonMobility.IonMobility;
            }
            else
            {
                ms1IonMobilityBest = IonMobilityValue.EMPTY;
            }

            double maxHighEnergyDriftOffsetMsec = UseHighEnergyOffset ? 2 : 0; // CONSIDER(bspratt): user definable? or dynamically set by looking at scan to scan drift delta? Or resolving power?

            foreach (var scan in _msDataFileScanHelper.MsDataSpectra.Where(scan => scan != null))
            {
                if (!scan.IonMobility.HasValue || !scan.Mzs.Any())
                {
                    continue;
                }
                if (ms1IonMobilityBest.HasValue &&
                    (scan.IonMobility.Mobility <
                     ms1IonMobilityBest.Mobility - maxHighEnergyDriftOffsetMsec ||
                     scan.IonMobility.Mobility >
                     ms1IonMobilityBest.Mobility + maxHighEnergyDriftOffsetMsec))
                {
                    continue;
                }

                // Get the total intensity for all transitions of current msLevel
                double totalIntensity = 0;
                foreach (var t in transitions)
                {
                    Assume.IsTrue(t.ProductMz.IsNegative == scan.NegativeCharge);  // It would be strange if associated scan did not have same polarity
                    var mzPeak  = t.ProductMz;
                    var halfwin = (t.ExtractionWidth ?? tolerance) / 2;
                    var mzLow   = mzPeak - halfwin;
                    var mzHigh  = mzPeak + halfwin;
                    var first   = Array.BinarySearch(scan.Mzs, mzLow);
                    if (first < 0)
                    {
                        first = ~first;
                    }
                    for (var i = first; i < scan.Mzs.Length; i++)
                    {
                        if (scan.Mzs[i] > mzHigh)
                        {
                            break;
                        }
                        totalIntensity += scan.Intensities[i];
                    }
                }
                if (maxIntensity < totalIntensity)
                {
                    ionMobilityValue = scan.IonMobility;
                    maxIntensity     = totalIntensity;
                }
            }
            if (ionMobilityValue.HasValue)
            {
                var dict   = (msLevel == 1) ? _ms1IonMobilities : _ms2IonMobilities;
                var ccs    = msLevel == 1 && _msDataFileScanHelper.ProvidesCollisionalCrossSectionConverter ? _msDataFileScanHelper.CCSFromIonMobility(ionMobilityValue, transitions.First().PrecursorMz, libKey.Charge) : null;
                var result = new IonMobilityIntensityPair
                {
                    IonMobility = IonMobilityAndCCS.GetIonMobilityAndCCS(ionMobilityValue, ccs, 0),
                    Intensity   = maxIntensity
                };
                List <IonMobilityIntensityPair> listPairs;
                if (!dict.TryGetValue(libKey, out listPairs))
                {
                    listPairs = new List <IonMobilityIntensityPair>();
                    dict.Add(libKey, listPairs);
                }
                listPairs.Add(result);
            }
        }