Пример #1
0
        public MsFeatureSpectraViewModel(MSFeatureLight feature, IEnumerable <XYData> spectrum, string name)
            : base(name)
        {
            MsmsDistanceLower = 1.5;
            MsmsDistanceUpper = 1.5;

            var mzAxis = new LinearAxis
            {
                Position        = AxisPosition.Bottom,
                IsZoomEnabled   = true,
                MinorStep       = 1,
                AbsoluteMinimum = 0
            };

            var intensityAxis = new LinearAxis
            {
                IsPanEnabled              = false,
                Position                  = AxisPosition.Left,
                IsZoomEnabled             = true,
                Minimum                   = 0,
                AbsoluteMinimum           = 0,
                UseSuperExponentialFormat = true
            };

            Model.Axes.Add(mzAxis);
            Model.Axes.Add(intensityAxis);

            m_mzAxis = mzAxis;
            PlotSpectra(feature, spectrum);
        }
Пример #2
0
        private MSFeatureLight FindFeature(double x)
        {
            MSFeatureLight best = null;

            if (SelectedCharge == null)
            {
                return(null);
            }

            if (!m_scanMaps.ContainsKey(SelectedCharge.ChargeState))
            {
                return(best);
            }

            var bestDist = double.MaxValue;

            foreach (var msFeature in m_scanMaps[SelectedCharge.ChargeState])
            {
                var dist = Math.Abs(msFeature.Scan - x);
                if (!(dist < bestDist))
                {
                    continue;
                }

                best     = msFeature;
                bestDist = dist;
            }
            return(best);
        }
Пример #3
0
        /// <summary>
        /// Weighted distance function that was used previously in the old feature finder.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public double WeightedNETDistanceFunction(MSFeatureLight a, MSFeatureLight b)
        {
            if ((a.MassMonoisotopic - b.MassMonoisotopic) * m_options.MonoMassWeight > m_options.ConstraintMonoMass ||
                (a.MassMonoisotopicAverage - b.MassMonoisotopicAverage) * m_options.AveMassWeight > m_options.ConstraintAveMass)
            {
                return(double.MaxValue);
            }

            double a_log_abundance = Math.Log10(a.Abundance);
            double b_log_abundance = Math.Log10(b.Abundance);
            double ppm             = ((a.MassMonoisotopic - b.MassMonoisotopic) / a.MassMonoisotopic) * 1000000;
            double ppmAvg          = ((a.MassMonoisotopicAverage - b.MassMonoisotopicAverage) / a.MassMonoisotopicAverage) * 1000000;

            if (!m_options.UseNET)
            {
                double sqrDist = ppm * ppm * m_options.MonoMassWeight * m_options.MonoMassWeight;
                sqrDist += ppmAvg * ppmAvg * m_options.AveMassWeight * m_options.AveMassWeight;
                sqrDist += (a_log_abundance - b_log_abundance) * (a_log_abundance - b_log_abundance) * m_options.LogAbundanceWeight * m_options.LogAbundanceWeight;
                sqrDist += (a.Scan - b.Scan) * (a.Scan - b.Scan) * m_options.ScanWeight * m_options.ScanWeight;
                sqrDist += (a.Score - b.Score) * (a.Score - b.Score) * m_options.FitWeight * m_options.FitWeight;
                return(Math.Sqrt(sqrDist));
            }
            else
            {
                double sqrDist      = ppm * ppm * m_options.MonoMassWeight * m_options.MonoMassWeight;
                double net_distance = Convert.ToDouble(a.Scan - b.Scan) / Convert.ToDouble(m_maxScan - m_minScan);
                sqrDist += (a_log_abundance - b_log_abundance) * (a_log_abundance - b_log_abundance) * m_options.LogAbundanceWeight * m_options.LogAbundanceWeight;
                // Convert scan difference to Generic NET
                sqrDist += net_distance * net_distance * m_options.NETWeight * m_options.NETWeight;
                sqrDist += (a.Score - b.Score) * (a.Score - b.Score) * m_options.FitWeight * m_options.FitWeight;
                return(Math.Sqrt(sqrDist));
            }
        }
Пример #4
0
        public MsFeatureSpectraViewModel(MSFeatureLight feature, IEnumerable<XYData> spectrum, string name)
            : base(name)
        {
            MsmsDistanceLower = 1.5;
            MsmsDistanceUpper = 1.5;

            var mzAxis = new LinearAxis
            {
                Position = AxisPosition.Bottom,
                IsZoomEnabled = true,
                MinorStep = 1,
                AbsoluteMinimum = 0
            };

            var intensityAxis = new LinearAxis
            {
                IsPanEnabled = false,
                Position = AxisPosition.Left,
                IsZoomEnabled = true,
                Minimum = 0,
                AbsoluteMinimum = 0,
                UseSuperExponentialFormat = true
            };
            Model.Axes.Add(mzAxis);
            Model.Axes.Add(intensityAxis);

            m_mzAxis = mzAxis;
            PlotSpectra(feature, spectrum);
        }
Пример #5
0
 public static UMCLight GetParentUmc(this MSFeatureLight feature)
 {
     if (feature == null)
     {
         return(null);
     }
     return(feature.ParentFeature);
 }
Пример #6
0
        /// <summary>
        /// Determines if two features are within proper range of each other.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        protected bool WithinRange(MSFeatureLight x, MSFeatureLight y)
        {
            double distance = WeightedNETDistanceFunction(x, y);

            if (Math.Abs(x.Scan - y.Scan) > 6000)
            {
                if (distance < m_maxDistance)
                {
                    int xx = 0;
                    xx++;
                }
            }
            return(distance < m_maxDistance);
        }
Пример #7
0
        /// <summary>
        /// Creates an XIC from the m/z values provided.
        /// </summary>
        /// <param name="mz"></param>
        /// <param name="massError"></param>
        /// <param name="minScan"></param>
        /// <param name="maxScan"></param>
        /// <param name="provider"></param>
        /// <returns></returns>
        public IEnumerable <MSFeatureLight> CreateXic(double mz,
                                                      double massError,
                                                      int minScan,
                                                      int maxScan,
                                                      ISpectraProvider provider)
        {
            var newFeatures = new List <MSFeatureLight>();
            var lower       = FeatureLight.ComputeDaDifferenceFromPPM(mz, massError);
            var higher      = FeatureLight.ComputeDaDifferenceFromPPM(mz, -massError);



            for (var i = minScan; i < maxScan; i++)
            {
                List <XYData> spectrum = null;

                try
                {
                    var summary = new ScanSummary();
                    spectrum = provider.GetRawSpectra(i, 0, 1, out summary);
                }
                catch
                {
                }

                if (spectrum == null)
                {
                    continue;
                }

                var data = (from x in spectrum
                            where x.X > lower && x.X < higher
                            select x).ToList();

                var summedIntensity = data.Sum(x => x.Y);


                var newFeature = new MSFeatureLight
                {
                    Scan      = i,
                    Net       = i,
                    Abundance = Convert.ToInt64(summedIntensity)
                };
                newFeatures.Add(newFeature);
            }
            return(newFeatures);
        }
Пример #8
0
        public List <MSFeatureLight> LoadMSFeaturesFromCache(string path)
        {
            var features = new List <MSFeatureLight>();
            var start    = System.DateTime.Now;

            using (var connection = new SQLiteConnection("Data Source=" + path))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    command.CommandType = System.Data.CommandType.Text;
                    command.CommandText = "SELECT * FROM T_MSFeatures where DATASET_ID = 0";
                    using (var reader = command.ExecuteReader())
                    {
                        var x      = 0;
                        var values = new object[100];
                        while (reader.Read())
                        {
                            var feature = new MSFeatureLight();
                            feature.DriftTime                    = Convert.ToDouble(reader["DriftTime"]);
                            feature.Score                        = Convert.ToDouble(reader["FIT"]);
                            feature.Scan                         = Convert.ToInt32(reader["SCAN_NUM"]);
                            feature.ChargeState                  = Convert.ToInt32(reader["CHARGE"]);
                            feature.Abundance                    = Convert.ToInt64(reader["ABUNDANCE"]);
                            feature.Mz                           = Convert.ToDouble(reader["MZ"]);
                            feature.MassMonoisotopicAverage      = Convert.ToDouble(reader["AVERAGE_MW"]);
                            feature.MassMonoisotopic             = Convert.ToDouble(reader["MONOISOTOPIC_MW"]);
                            feature.MassMonoisotopicMostAbundant = Convert.ToDouble(reader["MONOISOTOPIC_MW_ABUNDANT"]);
                            feature.UmcId                        = Convert.ToInt32(reader["LCMS_FEATURE_ID"]);
                            x++;
                            features.Add(feature);
                        }
                        System.Console.WriteLine("{0} features loaded", x);
                    }
                }
            }

            var end  = System.DateTime.Now;
            var span = end.Subtract(start);

            System.Console.WriteLine("{0} features loaded", span.TotalMilliseconds);

            return(features);
        }
Пример #9
0
        public List<MSFeatureLight> LoadMSFeaturesFromCache(string path)
        {
            var features = new List<MSFeatureLight>();
            var start = System.DateTime.Now;
            using (var connection = new SQLiteConnection("Data Source=" + path))
            {
                connection.Open();
                using (var command = connection.CreateCommand())
                {
                    command.CommandType = System.Data.CommandType.Text;
                    command.CommandText = "SELECT * FROM T_MSFeatures where DATASET_ID = 0";
                    using (var reader = command.ExecuteReader())
                    {
                        var x = 0;
                        var values = new object[100];
                        while (reader.Read())
                        {
                            var feature                  = new MSFeatureLight();
                            feature.DriftTime                       = Convert.ToDouble(reader["DriftTime"]);
                            feature.Score                           = Convert.ToDouble(reader["FIT"]);
                            feature.Scan                            = Convert.ToInt32(reader["SCAN_NUM"]);
                            feature.ChargeState                     = Convert.ToInt32(reader["CHARGE"]);
                            feature.Abundance                       = Convert.ToInt64(reader["ABUNDANCE"]);
                            feature.Mz                              = Convert.ToDouble(reader["MZ"]);
                            feature.MassMonoisotopicAverage         = Convert.ToDouble(reader["AVERAGE_MW"]);
                            feature.MassMonoisotopic                = Convert.ToDouble(reader["MONOISOTOPIC_MW"]);
                            feature.MassMonoisotopicMostAbundant    = Convert.ToDouble(reader["MONOISOTOPIC_MW_ABUNDANT"]);
                            feature.UmcId                           = Convert.ToInt32(reader["LCMS_FEATURE_ID"]);
                            x++;
                            features.Add(feature);
                        }
                        System.Console.WriteLine("{0} features loaded", x);
                    }
                }
            }

            var end = System.DateTime.Now;
            var span = end.Subtract(start);
            System.Console.WriteLine("{0} features loaded", span.TotalMilliseconds);

            return features;
        }
Пример #10
0
        public void TestChargeStateSplit(string path)
        {
            var data = File.ReadAllLines(path);
            var map  = new Dictionary <int, List <MSFeatureLight> >();

            for (var i = 1; i < data.Length; i++)
            {
                var feature       = new MSFeatureLight();
                var msFeatureData = data[i].Split(',');

                feature.ChargeState      = Convert.ToInt32(msFeatureData[0]);
                feature.MassMonoisotopic = Convert.ToDouble(msFeatureData[1]);
                feature.Scan             = Convert.ToInt32(msFeatureData[2]);
                feature.Abundance        = Convert.ToInt64(msFeatureData[3]);

                if (!map.ContainsKey(feature.ChargeState))
                {
                    map.Add(feature.ChargeState, new List <MSFeatureLight>());
                }
                map[feature.ChargeState].Add(feature);
            }


            var features = new List <UMCLight>();

            foreach (var charge in map.Keys)
            {
                var feature = new UMCLight();
                foreach (var msFeature in map[charge])
                {
                    feature.AddChildFeature(msFeature);
                }
                feature.CalculateStatistics(ClusterCentroidRepresentation.Median);
                features.Add(feature);
            }

            var finder     = new MsFeatureTreeClusterer <MSFeatureLight, UMCLight>();
            var comparison = finder.CompareMonoisotopic(features[0], features[1]);

            Assert.AreNotEqual(comparison, 0);
        }
Пример #11
0
        public void TestChargeStateSplit(string path)
        {
            var data = File.ReadAllLines(path);
            var map = new Dictionary<int, List<MSFeatureLight>>();

            for (var i = 1; i < data.Length; i++)
            {
                var feature = new MSFeatureLight();
                var msFeatureData = data[i].Split(',');

                feature.ChargeState = Convert.ToInt32(msFeatureData[0]);
                feature.MassMonoisotopic = Convert.ToDouble(msFeatureData[1]);
                feature.Scan = Convert.ToInt32(msFeatureData[2]);
                feature.Abundance = Convert.ToInt64(msFeatureData[3]);

                if (!map.ContainsKey(feature.ChargeState))
                {
                    map.Add(feature.ChargeState, new List<MSFeatureLight>());
                }
                map[feature.ChargeState].Add(feature);
            }

            var features = new List<UMCLight>();

            foreach (var charge in map.Keys)
            {
                var feature = new UMCLight();
                foreach (var msFeature in map[charge])
                {
                    feature.AddChildFeature(msFeature);
                }
                feature.CalculateStatistics(ClusterCentroidRepresentation.Median);
                features.Add(feature);
            }

            var finder = new MsFeatureTreeClusterer<MSFeatureLight, UMCLight>();
            var comparison = finder.CompareMonoisotopic(features[0], features[1]);

            Assert.AreNotEqual(comparison, 0);
        }
Пример #12
0
        private void LoadSpectrum(MSFeatureLight msFeature)
        {
            var info = SingletonDataProviders.GetDatasetInformation(msFeature.GroupId);

            if (info == null || info.RawFile.Path == null || info.RawFile.Path == null)
            {
                return;
            }


            var mz      = msFeature.Mz;
            var charge  = msFeature.ChargeState;
            var spacing = 1.0 / Convert.ToDouble(charge);
            var lowMz   = mz - spacing * 3;
            var highMz  = mz + spacing * (NumberOfIsotopes + 1);

            var spectrum = ParentSpectraFinder.GetParentSpectrum(info.RawFile.Path,
                                                                 msFeature.Scan,
                                                                 lowMz,
                                                                 highMz);

            if (spectrum == null)
            {
                return;
            }

            var name = string.Format("Scan {0} Charge {1} Dataset {2}",
                                     msFeature.Scan,
                                     msFeature.ChargeState,
                                     msFeature.GroupId
                                     );

            var msFeatureSpectra = new MsFeatureSpectraViewModel(msFeature, spectrum, name);

            msFeatureSpectra.SetXExtrema(lowMz, highMz);
            ParentSpectrumViewModel = msFeatureSpectra;
        }
Пример #13
0
        /// <summary>
        /// Builds XIC plot based on selected charge state chromatograms.
        /// </summary>
        private void BuildPlot()
        {
            this.XicPlotModel.Series.Clear();

            double minX = double.PositiveInfinity;
            double maxX = 0;
            double minY = double.PositiveInfinity;
            double maxY = 0;

            var chargeHash = new HashSet <int>();

            MSFeatureLight maxFeature = null;

            int i = 0;

            foreach (var feature in this.Features)
            {
                var xics = this.GetXic(feature.UMCLight);
                foreach (var xic in xics)
                {
                    if (xic.Count == 0)
                    {
                        continue;
                    }

                    if (!chargeHash.Contains(xic[0].ChargeState))
                    {
                        chargeHash.Add(xic[0].ChargeState);
                    }


                    // Get dataset info for mapping scan # -> retention time
                    var dsInfo = SingletonDataProviders.GetDatasetInformation(feature.UMCLight.GroupId);

                    foreach (var msfeature in xic)
                    {
                        minX = Math.Min(minX, msfeature.Net);
                        maxX = Math.Max(maxX, msfeature.Net);
                        minY = Math.Min(minY, msfeature.Abundance);
                        maxY = Math.Max(maxY, msfeature.Abundance);
                    }

                    var maxA = xic.Max(msf => msf.Abundance);
                    var maxL = xic.FirstOrDefault(msf => msf.Abundance.Equals(maxA));
                    if (maxFeature == null || (maxL != null && maxL.Abundance >= maxFeature.Abundance))
                    {
                        maxFeature = maxL;
                    }

                    var color  = this.Colors[i++ % this.Colors.Count];
                    var series = new LineSeries
                    {
                        ItemsSource           = xic,
                        Mapping               = dataPoint => new DataPoint(((MSFeatureLight)dataPoint).Net, ((MSFeatureLight)dataPoint).Abundance),
                        Title                 = string.Format("{0}({1}+) ID({2})", dsInfo.DatasetName, xic[0].ChargeState, feature.UMCLight.Id),
                        Color                 = color,
                        MarkerType            = MarkerType.Circle,
                        MarkerSize            = 3,
                        MarkerFill            = OxyColors.White,
                        MarkerStroke          = color,
                        MarkerStrokeThickness = 0.5,
                        TrackerFormatString   = "{0}" + Environment.NewLine +
                                                "{1}: {2:0.###} (Scan: {Scan:0})" + Environment.NewLine +
                                                "{3}: {4:0.###E0}" + Environment.NewLine
                    };

                    this.XicPlotModel.Series.Add(series);
                }
            }

            this.SelectedMsFeature = maxFeature;
            this.SetMsFeatureAnnotation();

            this.ChargeStates.Clear();
            foreach (var chargeState in chargeHash)
            {
                this.ChargeStates.Add(new ChargeStateViewModel(chargeState));
            }

            minX = Math.Max(0, minX - (0.01 * minX));
            maxX = maxX + (0.01 * maxX);
            maxY = maxY + (0.05 * maxY);

            this.xaxis.Minimum = minX;
            this.xaxis.Maximum = maxX;
            this.yaxis.Minimum = minY;
            this.yaxis.Maximum = maxY;

            this.xaxis.Zoom(minX, maxX);
            this.yaxis.Zoom(minY, maxY);

            this.XicPlotModel.InvalidatePlot(true);
        }
Пример #14
0
 public static bool HasMsMs(this MSFeatureLight msFeature)
 {
     return(msFeature.MSnSpectra.Count > 0);
 }
Пример #15
0
        /// <summary>
        ///     Reconstructs a MS Feature by loading the MS/MS data
        /// </summary>
        /// <param name="feature"></param>
        /// <param name="providers"></param>
        public static void ReconstructMSFeature(this MSFeatureLight msFeature, FeatureDataAccessProviders providers)
        {
            // We are reconstruction the objects here.  But
            // I want to reduce the number of transactions to make.
            // So I go back through the database and pull out all msms spectra first
            // then sort it out in memory.

            // Get the map
            var msmsFeatures = new List <MSFeatureToMSnFeatureMap>();

            // Maps the id's of the MS/MS spectra
            var ids = new List <int>();

            // Make a map, from the dataset, then the spectra to the ms feature Id.
            var map
                = new Dictionary <int, Dictionary <int, MSFeatureToMSnFeatureMap> >();


            msmsFeatures = providers.MSFeatureToMSnFeatureCache.FindByUMCFeatureId(msFeature.GroupId,
                                                                                   msFeature.Id);
            // Then grab the spectra id list
            ids = msmsFeatures.ConvertAll(x => x.MSMSFeatureID);


            // construct that map here.
            foreach (var subFeature in msmsFeatures)
            {
                // first map the dataset id
                if (!map.ContainsKey(subFeature.MSDatasetID))
                {
                    map.Add(subFeature.MSDatasetID, new Dictionary <int, MSFeatureToMSnFeatureMap>());
                }

                //TODO: There may be multiple MSMS spectra
                // Then map its msms spectra id
                if (map[subFeature.MSDatasetID].ContainsKey(subFeature.MSFeatureID))
                {
                    continue;
                }

                map[subFeature.MSDatasetID].Add(subFeature.MSFeatureID, subFeature);
            }

            // Now we get all the spectra, map to the UMC, then the ms/ms spectra.
            var spectra = providers.MSnFeatureCache.FindBySpectraId(ids);

            var spectraMap = new Dictionary <int, Dictionary <int, MSSpectra> >();

            foreach (var spectrum in spectra)
            {
                if (!spectraMap.ContainsKey(spectrum.GroupId))
                {
                    spectraMap.Add(spectrum.GroupId, new Dictionary <int, MSSpectra>());
                }
                spectraMap[spectrum.GroupId].Add(spectrum.Id, spectrum);
            }

            // Here we check the dataset.
            if (map.ContainsKey(msFeature.GroupId))
            {
                // then check the ms/ms spectra
                if (map[msFeature.GroupId].ContainsKey(msFeature.Id))
                {
                    // ok, we are sure that the spectra is present now!
                    var singleMap = map[msFeature.GroupId][msFeature.Id];
                    var spectrum  = spectraMap[singleMap.MSDatasetID][singleMap.MSMSFeatureID];
                    msFeature.MSnSpectra.Add(spectrum);
                }
            }
        }
Пример #16
0
        public IEnumerable <UMCLight> CreateXic(IList <UMCLight> features,
                                                double massError,
                                                ISpectraProvider provider)
        {
            // this algorithm works as follows
            //
            //  PART A - Build the XIC target list
            //  For each UMC Light , find the XIC representation
            //      for each charge in a feature
            //          from start scan to end scan
            //              1. Compute a lower / upper m/z bound
            //              2. build an XIC chomatogram object
            //              3. reference the original UMC Feature -- this allows us to easily add
            //                  chromatograms to the corresponding feature
            //              4. store the chomatogram (with unique ID across all features)
            //
            //  PART B - Read Data From File
            //  Sort the list of XIC's by scan
            //  for each scan s = start scan to end scan
            //      1. find all xic's that start before and end after s -
            //          a. cache these xics in a dictionary based on unique id
            //          b. NOTE: this is why we sort so we can do an O(N) search for
            //             all XIC's that need data from this scan s
            //      2.  Then for each XIC that needs data
            //          a. Pull intensity data from lower / upper m/z bound
            //          b. create an MS Feature
            //          c. store in original UMC Feature
            //          d. Test to see if the XIC is done building (Intensity < 1 or s > scan end)
            //      3. Remove features that are done building from cache
            //
            //  CONCLUSIONS
            //  Building UMC's then takes linear time  (well O(N Lg N) time if you consider sort)
            //      and theoretically is only bounded by the time it takes to read an entire raw file
            //
            if (features.Count <= 0)
            {
                throw new Exception("No features were available to create XIC's from");
            }

            var minScan = Math.Max(1, features.Min(x => x.Scan - ScanWindowSize));
            var maxScan = features.Max(x => x.Scan + ScanWindowSize);

            OnProgress("Sorting features for optimized scan partitioning");
            // PART A
            // Map the feature ID to the xic based features
            var xicFeatures = new SortedSet <XicFeature>();
            var allFeatures = CreateXicTargets(features, massError);

            // PART B
            // sort the features...
            var featureCount = allFeatures.Count;

            allFeatures = allFeatures.OrderBy(x => x.StartScan).ToList();

            // This map tracks all possible features to keep

            var msFeatureId = 0;

            // This list stores a temporary amount of parent MS features
            // so that we can link MS/MS spectra to MS Features
            var parentMsList = new List <MSFeatureLight>();

            // Creates a comparison function for building a BST from a spectrum.
            var msmsFeatureId = 0;

            var totalScans = provider.GetTotalScans(0);

            OnProgress(string.Format("Analyzing {0} scans", totalScans));


            // Iterate over all the scans...
            for (var currentScan = minScan; currentScan < maxScan && currentScan <= totalScans; currentScan++)
            {
                // Find any features that need data from this scan
                var featureIndex = 0;
                while (featureIndex < featureCount)
                {
                    var xicFeature = allFeatures[featureIndex];
                    // This means that no new features were eluting with this scan....
                    if (xicFeature.StartScan > currentScan)
                    {
                        break;
                    }

                    // This means that there is a new feature...
                    if (currentScan <= xicFeature.EndScan)
                    {
                        if (!xicFeatures.Contains(xicFeature))
                        {
                            xicFeatures.Add(xicFeature);
                        }
                    }
                    featureIndex++;
                }

                // Skip pulling the data from the file if there is nothing to pull from.
                if (xicFeatures.Count < 1)
                {
                    continue;
                }

                // Here We link the MSMS Spectra to the UMC Features
                ScanSummary summary;
                var         spectrum = provider.GetRawSpectra(currentScan, 0, 1, out summary);


                if (summary.MsLevel > 1)
                {
                    // If it is an MS 2 spectra... then let's link it to the parent MS
                    // Feature
                    var matching = parentMsList.Where(
                        x => Math.Abs(x.Mz - summary.PrecursorMz) <= FragmentationSizeWindow
                        );

                    foreach (var match in matching)
                    {
                        // We create multiple spectra because this guy is matched to multiple ms
                        // features
                        var spectraData = new MSSpectra
                        {
                            Id              = msmsFeatureId,
                            ScanMetaData    = summary,
                            CollisionType   = summary.CollisionType,
                            Scan            = currentScan,
                            MsLevel         = summary.MsLevel,
                            PrecursorMz     = summary.PrecursorMz,
                            TotalIonCurrent = summary.TotalIonCurrent
                        };

                        match.MSnSpectra.Add(spectraData);
                        spectraData.ParentFeature = match;
                    }

                    if (spectrum != null)
                    {
                        spectrum.Clear();
                    }
                    msmsFeatureId++;

                    continue;
                }


                var mzList        = new double[spectrum.Count];
                var intensityList = new double[spectrum.Count];
                XYData.XYDataListToArrays(spectrum, mzList, intensityList);
                Array.Sort(mzList, intensityList);

                // Tracks which spectra need to be removed from the cache
                var toRemove = new List <XicFeature>();

                // Tracks which features we need to link to MSMS spectra with
                parentMsList.Clear();

                // now we iterate through all features that need data from this scan

                foreach (var xic in xicFeatures)
                {
                    var lower  = xic.LowMz;
                    var higher = xic.HighMz;

                    var startIndex = Array.BinarySearch(mzList, lower);
                    // A bitwise complement of the index, so use the bitwise complement
                    if (startIndex < 0)
                    {
                        startIndex = ~startIndex;
                    }

                    double summedIntensity = 0;

                    if (startIndex < mzList.Count() && mzList[startIndex] < lower)
                    {
                        // All data in the list is lighter than lower; nothing to sum
                    }
                    else
                    {
                        while (startIndex < mzList.Count() && mzList[startIndex] <= higher)
                        {
                            summedIntensity += intensityList[startIndex];
                            startIndex++;
                        }
                    }

                    // See if we need to remove this feature
                    // We only do so if the intensity has dropped off and we are past the end of the feature.
                    if (summedIntensity < 1 && currentScan > xic.EndScan)
                    {
                        toRemove.Add(xic);
                        continue;
                    }

                    var umc = xic.Feature;

                    // otherwise create a new feature here...
                    var msFeature = new MSFeatureLight
                    {
                        ChargeState      = xic.ChargeState,
                        Mz               = xic.Mz,
                        MassMonoisotopic = umc.MassMonoisotopic,
                        Scan             = currentScan,
                        Abundance        = Convert.ToInt64(summedIntensity),
                        Id               = msFeatureId++,
                        DriftTime        = umc.DriftTime,
                        Net              = currentScan,
                        GroupId          = umc.GroupId
                    };
                    parentMsList.Add(msFeature);
                    xic.Feature.AddChildFeature(msFeature);
                }

                // Remove features that end their elution prior to the current scan
                toRemove.ForEach(x => xicFeatures.Remove(x));
            }

            OnProgress("Filtering bad features with no data.");
            features = features.Where(x => x.MsFeatures.Count > 0).ToList();

            OnProgress("Refining XIC features.");
            return(RefineFeatureXics(features));
        }
Пример #17
0
        /// <summary>
        /// Aligns features based on MSMS spectral similarity.
        /// </summary>
        /// <param name="featureMap"></param>
        /// <param name="msms"></param>
        public List <MsmsCluster> Cluster(List <UMCLight> features, ISpectraProvider provider)
        {
            UpdateStatus("Mapping UMC's to MS/MS spectra using intensity profile.");
            // Step 1: Cluster the spectra
            // Create the collection of samples.
            var msFeatures = new List <MSFeatureLight>();

            // Sort through the features
            foreach (var feature in features)
            {
                // Sort out charge states...?
                var chargeMap = new Dictionary <int, MSFeatureLight>();

                double         abundance  = int.MinValue;
                MSFeatureLight maxFeature = null;

                // Find the max abundance spectrum.  This the number of features we have to search.
                foreach (var msFeature in feature.MsFeatures)
                {
                    if (msFeature.Abundance > abundance && msFeature.MSnSpectra.Count > 0)
                    {
                        abundance  = msFeature.Abundance;
                        maxFeature = msFeature;
                    }
                }

                if (maxFeature != null)
                {
                    msFeatures.Add(maxFeature);
                }
            }

            UpdateStatus(string.Format("Found {0} total spectra for clustering.", msFeatures.Count));

            UpdateStatus("Sorting spectra.");
            // Sort based on mass using the max abundance of the feature.
            msFeatures.Sort(delegate(MSFeatureLight x, MSFeatureLight y)
                            { return(x.MassMonoisotopicMostAbundant.CompareTo(y.MassMonoisotopicMostAbundant)); });

            // Then cluster the spectra.
            var j = 1;
            var h = 0;
            var N = msFeatures.Count;

            var clusters  = new List <MsmsCluster>();
            var tol       = MassTolerance;
            var lastTotal = 0;

            UpdateStatus("Clustering spectra.");
            while (j < N)
            {
                var i        = j - 1;
                var featureJ = msFeatures[j];
                var featureI = msFeatures[i];
                var diff     = FeatureLight.ComputeMassPPMDifference(featureJ.MassMonoisotopicMostAbundant, featureI.MassMonoisotopicMostAbundant);

                if (Math.Abs(diff) > tol)
                {
                    // We only care to create clusters of size greater than one.
                    if ((j - h) > 1)
                    {
                        var data = Cluster(h,
                                           j,
                                           msFeatures,
                                           provider,
                                           SimilarityTolerance);
                        clusters.AddRange(data);
                    }

                    // Reset the count, we're done looking at those clusters.
                    h = j;
                }
                if (j - lastTotal > 500)
                {
                    lastTotal = j;
                    UpdateStatus(string.Format("Processed {0} / {1} total spectra.", lastTotal, N));
                }
                j++;
            }
            UpdateStatus("Finishing last cluster data.");

            // Cluster the rest
            if ((j - h) > 1)
            {
                var data = Cluster(h,
                                   j,
                                   msFeatures,
                                   provider,
                                   SimilarityTolerance);
                clusters.AddRange(data);
            }
            UpdateStatus("Finished clustering.");
            var passingClusters = clusters.Where(cluster => cluster.Features.Count >= MinimumClusterSize);

            return(passingClusters.ToList());
        }
Пример #18
0
        /// <summary>
        ///     Plots the UMC's
        /// </summary>
        /// <param name="features"></param>
        private void PlotFeatures(IEnumerable <UMCLight> features)
        {
            var markerIterator = new MarkerTypeIterator();

            m_colorIterator = new ColorTypeIterator();

            var i = 0;

            m_scanAnnotation = new LineAnnotation
            {
                X               = 0,
                TextColor       = OxyColors.Gray,
                Text            = "0",
                TextOrientation = AnnotationTextOrientation.Vertical,
                LineStyle       = LineStyle.Dash,
                Type            = LineAnnotationType.Vertical,
            };


            Model.Annotations.Add(m_scanAnnotation);

            foreach (var feature in features)
            {
                var chargeMap = feature.CreateChargeMap();

                foreach (var charge in chargeMap.Keys)
                {
                    var msFeatures = chargeMap[charge];
                    msFeatures = msFeatures.OrderBy(x => x.Scan).ToList();
                    var mz = msFeatures[0].Mz;

                    var newSeries = new LineSeries
                    {
                        Color                 = m_colorIterator.GetColor(charge),
                        MarkerFill            = m_colorIterator.GetColor(charge),
                        MarkerSize            = 3,
                        MarkerStroke          = OxyColors.White,
                        MarkerStrokeThickness = 1.5,
                        MarkerType            = markerIterator.GetMarker(i++),
                        Title                 = string.Format("{0} m/z  - Charge {1}",
                                                              mz.ToString("F3"),
                                                              charge)
                    };

                    double         abundance   = 0;
                    MSFeatureLight bestFeature = null;

                    foreach (var msFeature in msFeatures)
                    {
                        if (abundance < msFeature.Abundance)
                        {
                            bestFeature = msFeature;
                            abundance   = msFeature.Abundance;
                        }

                        foreach (var msms in msFeature.MSnSpectra)
                        {
                            var peptideSequence = "";
                            if (msms.Peptides.Count > 0)
                            {
                                peptideSequence = msms.Peptides[0].Sequence;
                            }

                            var msmsAnnotation = new LineAnnotation
                            {
                                Type            = LineAnnotationType.Vertical,
                                X               = msms.Scan,
                                Y               = msFeature.Abundance,
                                StrokeThickness = 2,
                                Color           = m_colorIterator.GetColor(msFeature.ChargeState),
                                TextColor       = m_colorIterator.GetColor(msFeature.ChargeState),
                                Text            = string.Format("{2} - {0} m/z {1}",
                                                                msms.PrecursorMz.ToString("F3"),
                                                                peptideSequence,
                                                                msms.CollisionType)
                            };
                            Model.Annotations.Add(msmsAnnotation);
                        }
                        newSeries.Points.Add(new DataPoint(msFeature.Scan, msFeature.Abundance));
                    }

                    newSeries.Tag = charge;

                    if (bestFeature != null)
                    {
                        ScanAnnotationX = bestFeature.Scan;
                        SelectedCharge  = charge;
                    }
                    Model.Series.Add(newSeries);
                }
            }
        }
Пример #19
0
        public void PlotSpectra(MSFeatureLight feature, IEnumerable <XYData> spectrum)
        {
            var series = new StemSeries
            {
                Color = OxyColors.Black
            };

            var minimumMz    = double.MaxValue;
            var maximumMz    = double.MinValue;
            var maxAbundance = double.MinValue;

            if (spectrum.Count() < 1)
            {
                return;
            }

            foreach (var peak in spectrum)
            {
                minimumMz    = Math.Min(peak.X, minimumMz);
                maximumMz    = Math.Max(peak.X, maximumMz);
                maxAbundance = Math.Max(maxAbundance, peak.Y);

                series.Points.Add(new DataPoint(peak.X, peak.Y));
            }

            var maxAbundanceTop = maxAbundance * .5;

            Model.Axes[0].AbsoluteMinimum = minimumMz;
            Model.Axes[0].AbsoluteMaximum = maximumMz;

            Model.Series.Add(series);

            // Add in the monoisotopic peak
            var colors      = new ColorTypeIterator();
            var chargeColor = colors.GetColor(feature.ChargeState);
            var msFeature   = new StemSeries
            {
                Color = chargeColor
            };

            msFeature.Points.Add(new DataPoint(feature.Mz, feature.Abundance));
            Model.Series.Add(msFeature);

            // Add in the rest of the isotopes
            var alphaColor         = OxyColor.FromAColor(100, OxyColors.Red);
            var charge             = feature.ChargeState;
            var mz                 = feature.Mz;
            var abundance          = Convert.ToDouble(feature.Abundance);
            var monoPeakAnnotation = new LineAnnotation
            {
                Type      = LineAnnotationType.Vertical,
                X         = mz,
                Color     = alphaColor,
                TextColor = alphaColor,
                Text      = string.Format("mono peak: {0} m/z",
                                          mz.ToString("F3"))
            };

            Model.Annotations.Add(monoPeakAnnotation);

            var lastMz  = mz;
            var spacing = 1.0 / charge;

            while (mz < maximumMz && abundance > 1)
            {
                mz         = mz + (1.0 / charge);
                abundance *= .75;
                var peakAnnotation = new LineAnnotation
                {
                    Type      = LineAnnotationType.Vertical,
                    X         = mz,
                    Color     = alphaColor,
                    TextColor = alphaColor,
                    Text      = string.Format("{0} m/z",
                                              mz.ToString("F3"))
                };

                var spaceAnnotation = new LineAnnotation
                {
                    Type      = LineAnnotationType.Horizontal,
                    Color     = alphaColor,
                    TextColor = alphaColor,
                    TextHorizontalAlignment = HorizontalAlignment.Center,
                    TextVerticalAlignment   = VerticalAlignment.Top,
                    TextPosition            = new DataPoint(.5, 0),
                    MinimumX = lastMz,
                    MaximumX = mz,
                    Text     = string.Format("d={0}", spacing.ToString("F2")),
                    Y        = maxAbundance * .75
                };
                maxAbundance *= .75;
                lastMz        = mz;
                Model.Annotations.Add(spaceAnnotation);
                Model.Annotations.Add(peakAnnotation);
            }

            if (feature.GetParentFeature() != null)
            {
                var features = feature.GetParentFeature().Features;
                foreach (var subFeature in features)
                {
                    var msms =
                        subFeature.MSnSpectra.Where(x => x.PrecursorMz > minimumMz && x.PrecursorMz < maximumMz);
                    foreach (var fragmentation  in msms)
                    {
                        var spaceAnnotation = new LineAnnotation
                        {
                            Type                  = LineAnnotationType.Vertical,
                            Color                 = OxyColors.Gray,
                            TextColor             = OxyColors.Gray,
                            FontWeight            = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition          = new DataPoint(1, 0),
                            StrokeThickness       = 2,
                            Text                  =
                                string.Format("msms {0} - scan {1}", fragmentation.PrecursorMz.ToString("F2"),
                                              fragmentation.Scan),
                            X = fragmentation.PrecursorMz
                        };
                        Model.Annotations.Add(spaceAnnotation);


                        var lowerMz = new LineAnnotation
                        {
                            Type                  = LineAnnotationType.Horizontal,
                            Color                 = OxyColors.LightGray,
                            TextColor             = OxyColors.LightGray,
                            FontWeight            = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition          = new DataPoint(1, 0),
                            StrokeThickness       = 2,
                            Y        = maxAbundanceTop,
                            Text     = string.Format("{0} m/z", MsmsDistanceLower.ToString("F2")),
                            MinimumX = fragmentation.PrecursorMz - MsmsDistanceLower,
                            MaximumX = fragmentation.PrecursorMz
                        };

                        var upperMz = new LineAnnotation
                        {
                            Type                  = LineAnnotationType.Horizontal,
                            Color                 = OxyColors.LightGray,
                            TextColor             = OxyColors.LightGray,
                            FontWeight            = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition          = new DataPoint(1, 0),
                            StrokeThickness       = 2,
                            Text                  = string.Format("{0} m/z", MsmsDistanceUpper.ToString("F2")),
                            Y        = maxAbundanceTop,
                            MinimumX = fragmentation.PrecursorMz,
                            MaximumX = fragmentation.PrecursorMz + MsmsDistanceUpper
                        };

                        Model.Annotations.Add(upperMz);
                        Model.Annotations.Add(lowerMz);
                    }
                }
            }
        }
Пример #20
0
        /// <summary>
        /// Determines if two features are within proper range of each other.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        protected bool WithinRange(MSFeatureLight x, MSFeatureLight  y)
        {
            double distance = WeightedNETDistanceFunction(x, y);

            if (Math.Abs(x.Scan - y.Scan) > 6000)
            {
                if (distance < m_maxDistance)
                {
                    int xx = 0;
                    xx++;
                }
            }
            return (distance < m_maxDistance);
        }
Пример #21
0
        /// <summary>
        /// Weighted distance function that was used previously in the old feature finder.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public double WeightedNETDistanceFunction(MSFeatureLight a, MSFeatureLight b)
        {
            if ((a.MassMonoisotopic - b.MassMonoisotopic) * m_options.MonoMassWeight > m_options.ConstraintMonoMass
                || (a.MassMonoisotopicAverage - b.MassMonoisotopicAverage) * m_options.AveMassWeight > m_options.ConstraintAveMass)
            {
                return double.MaxValue;
            }

            double a_log_abundance	= Math.Log10(a.Abundance);
            double b_log_abundance  = Math.Log10(b.Abundance);
            double ppm				= ((a.MassMonoisotopic - b.MassMonoisotopic) / a.MassMonoisotopic) * 1000000;
            double ppmAvg           = ((a.MassMonoisotopicAverage - b.MassMonoisotopicAverage) / a.MassMonoisotopicAverage) * 1000000;
            if (!m_options.UseNET)
            {
                double sqrDist = ppm * ppm * m_options.MonoMassWeight * m_options.MonoMassWeight;
                sqrDist += ppmAvg * ppmAvg * m_options.AveMassWeight  * m_options.AveMassWeight;
                sqrDist += (a_log_abundance - b_log_abundance) * (a_log_abundance - b_log_abundance) * m_options.LogAbundanceWeight * m_options.LogAbundanceWeight;
                sqrDist += (a.Scan  - b.Scan)  * (a.Scan  - b.Scan) * m_options.ScanWeight * m_options.ScanWeight;
                sqrDist += (a.Score - b.Score) * (a.Score - b.Score) * m_options.FitWeight * m_options.FitWeight;
                return Math.Sqrt(sqrDist);
            }
            else
            {
                double sqrDist      = ppm * ppm * m_options.MonoMassWeight * m_options.MonoMassWeight;
                double net_distance = Convert.ToDouble(a.Scan - b.Scan) / Convert.ToDouble(m_maxScan - m_minScan);
                sqrDist += (a_log_abundance - b_log_abundance) * (a_log_abundance - b_log_abundance) * m_options.LogAbundanceWeight * m_options.LogAbundanceWeight;
                // Convert scan difference to Generic NET
                sqrDist += net_distance * net_distance * m_options.NETWeight * m_options.NETWeight;
                sqrDist += (a.Score - b.Score) * (a.Score - b.Score) * m_options.FitWeight * m_options.FitWeight;
                return Math.Sqrt(sqrDist);
            }
        }
Пример #22
0
        public void PlotSpectra(MSFeatureLight feature, IEnumerable<XYData> spectrum)
        {
            var series = new StemSeries
            {
                Color = OxyColors.Black
            };

            var minimumMz = double.MaxValue;
            var maximumMz = double.MinValue;
            var maxAbundance = double.MinValue;

            if (spectrum.Count() < 1)
                return;

            foreach (var peak in spectrum)
            {
                minimumMz = Math.Min(peak.X, minimumMz);
                maximumMz = Math.Max(peak.X, maximumMz);
                maxAbundance = Math.Max(maxAbundance, peak.Y);

                series.Points.Add(new DataPoint(peak.X, peak.Y));
            }

            var maxAbundanceTop = maxAbundance*.5;

            Model.Axes[0].AbsoluteMinimum = minimumMz;
            Model.Axes[0].AbsoluteMaximum = maximumMz;

            Model.Series.Add(series);

            // Add in the monoisotopic peak
            var colors = new ColorTypeIterator();
            var chargeColor = colors.GetColor(feature.ChargeState);
            var msFeature = new StemSeries
            {
                Color = chargeColor
            };
            msFeature.Points.Add(new DataPoint(feature.Mz, feature.Abundance));
            Model.Series.Add(msFeature);

            // Add in the rest of the isotopes
            var alphaColor = OxyColor.FromAColor(100, OxyColors.Red);
            var charge = feature.ChargeState;
            var mz = feature.Mz;
            var abundance = Convert.ToDouble(feature.Abundance);
            var monoPeakAnnotation = new LineAnnotation
            {
                Type = LineAnnotationType.Vertical,
                X = mz,
                Color = alphaColor,
                TextColor = alphaColor,
                Text = string.Format("mono peak: {0} m/z",
                    mz.ToString("F3"))
            };
            Model.Annotations.Add(monoPeakAnnotation);

            var lastMz = mz;
            var spacing = 1.0/charge;
            while (mz < maximumMz && abundance > 1)
            {
                mz = mz + (1.0/charge);
                abundance *= .75;
                var peakAnnotation = new LineAnnotation
                {
                    Type = LineAnnotationType.Vertical,
                    X = mz,
                    Color = alphaColor,
                    TextColor = alphaColor,
                    Text = string.Format("{0} m/z",
                        mz.ToString("F3"))
                };

                var spaceAnnotation = new LineAnnotation
                {
                    Type = LineAnnotationType.Horizontal,
                    Color = alphaColor,
                    TextColor = alphaColor,
                    TextHorizontalAlignment = HorizontalAlignment.Center,
                    TextVerticalAlignment = VerticalAlignment.Top,
                    TextPosition = new DataPoint(.5, 0),
                    MinimumX = lastMz,
                    MaximumX = mz,
                    Text = string.Format("d={0}", spacing.ToString("F2")),
                    Y = maxAbundance*.75
                };
                maxAbundance *= .75;
                lastMz = mz;
                Model.Annotations.Add(spaceAnnotation);
                Model.Annotations.Add(peakAnnotation);
            }

            if (feature.ParentFeature != null)
            {
                var features = feature.ParentFeature.Features;
                foreach (var subFeature in features)
                {
                    var msms =
                        subFeature.MSnSpectra.Where(x => x.PrecursorMz > minimumMz && x.PrecursorMz < maximumMz);
                    foreach (var fragmentation  in msms)
                    {
                        var spaceAnnotation = new LineAnnotation
                        {
                            Type = LineAnnotationType.Vertical,
                            Color = OxyColors.Gray,
                            TextColor = OxyColors.Gray,
                            FontWeight = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition = new DataPoint(1, 0),
                            StrokeThickness = 2,
                            Text =
                                string.Format("msms {0} - scan {1}", fragmentation.PrecursorMz.ToString("F2"),
                                    fragmentation.Scan),
                            X = fragmentation.PrecursorMz
                        };
                        Model.Annotations.Add(spaceAnnotation);

                        var lowerMz = new LineAnnotation
                        {
                            Type = LineAnnotationType.Horizontal,
                            Color = OxyColors.LightGray,
                            TextColor = OxyColors.LightGray,
                            FontWeight = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition = new DataPoint(1, 0),
                            StrokeThickness = 2,
                            Y = maxAbundanceTop,
                            Text = string.Format("{0} m/z", MsmsDistanceLower.ToString("F2")),
                            MinimumX = fragmentation.PrecursorMz - MsmsDistanceLower,
                            MaximumX = fragmentation.PrecursorMz
                        };

                        var upperMz = new LineAnnotation
                        {
                            Type = LineAnnotationType.Horizontal,
                            Color = OxyColors.LightGray,
                            TextColor = OxyColors.LightGray,
                            FontWeight = 3,
                            TextVerticalAlignment = VerticalAlignment.Top,
                            TextPosition = new DataPoint(1, 0),
                            StrokeThickness = 2,
                            Text = string.Format("{0} m/z", MsmsDistanceUpper.ToString("F2")),
                            Y = maxAbundanceTop,
                            MinimumX = fragmentation.PrecursorMz,
                            MaximumX = fragmentation.PrecursorMz + MsmsDistanceUpper
                        };

                        Model.Annotations.Add(upperMz);
                        Model.Annotations.Add(lowerMz);
                    }
                }
            }
        }
Пример #23
0
        private void LoadSpectrum(MSFeatureLight msFeature)
        {
            var info = SingletonDataProviders.GetDatasetInformation(msFeature.GroupId);
            if (info == null || info.Raw == null || info.RawPath == null)
                return;

            var mz = msFeature.Mz;
            var charge = msFeature.ChargeState;
            var spacing = 1.0 / Convert.ToDouble(charge);
            var lowMz = mz - spacing * 3;
            var highMz = mz + spacing * (NumberOfIsotopes + 1);

            var spectrum = ParentSpectraFinder.GetParentSpectrum(info.RawPath,
                msFeature.Scan,
                lowMz,
                highMz);
            if (spectrum == null)
                return;

            var name = string.Format("Scan {0} Charge {1} Dataset {2}",
                msFeature.Scan,
                msFeature.ChargeState,
                msFeature.GroupId
                );

            var msFeatureSpectra = new MsFeatureSpectraViewModel(msFeature, spectrum, name);
            msFeatureSpectra.SetXExtrema(lowMz, highMz);
            ParentSpectrumViewModel = msFeatureSpectra;
        }