Exemplo n.º 1
0
 public SpectrumGraphItem(TransitionGroupDocNode transitionGroupNode, TransitionDocNode transition,
                          LibraryRankedSpectrumInfo spectrumInfo, string libName) : base(spectrumInfo)
 {
     TransitionGroupNode = transitionGroupNode;
     TransitionNode      = transition;
     LibraryName         = libName;
 }
Exemplo n.º 2
0
        public void GetLibraryInfo(SrmSettings settings, ExplicitMods mods, bool useFilter,
                                   ref SpectrumHeaderInfo libInfo,
                                   Dictionary <double, LibraryRankedSpectrumInfo.RankedMI> transitionRanks)
        {
            PeptideLibraries libraries = settings.PeptideSettings.Libraries;

            // No libraries means no library info
            if (!libraries.HasLibraries)
            {
                libInfo = null;
                return;
            }
            // If not loaded, leave everything alone, and let the update
            // when loading is complete fix things.
            if (!libraries.IsLoaded)
            {
                return;
            }

            IsotopeLabelType labelType;

            if (!settings.TryGetLibInfo(Peptide.Sequence, PrecursorCharge, mods, out labelType, out libInfo))
            {
                libInfo = null;
            }
            else if (transitionRanks != null)
            {
                try
                {
                    SpectrumPeaksInfo spectrumInfo;
                    string            sequenceMod = settings.GetModifiedSequence(Peptide.Sequence, labelType, mods);
                    if (libraries.TryLoadSpectrum(new LibKey(sequenceMod, PrecursorCharge), out spectrumInfo))
                    {
                        var spectrumInfoR = new LibraryRankedSpectrumInfo(spectrumInfo, labelType,
                                                                          this, settings, mods, useFilter, 50);
                        foreach (var rmi in spectrumInfoR.PeaksRanked)
                        {
                            if (!transitionRanks.ContainsKey(rmi.PredictedMz))
                            {
                                transitionRanks.Add(rmi.PredictedMz, rmi);
                            }
                            if (!useFilter && rmi.PredictedMz2 != 0 && !transitionRanks.ContainsKey(rmi.PredictedMz2))
                            {
                                transitionRanks.Add(rmi.PredictedMz2, rmi);
                            }
                        }
                    }
                }
                // Catch and ignore file access exceptions
                catch (IOException) {}
                catch (UnauthorizedAccessException) {}
                catch (ObjectDisposedException) {}
            }
        }
Exemplo n.º 3
0
        // ReSharper restore InconsistentNaming

        protected AbstractSpectrumGraphItem(LibraryRankedSpectrumInfo spectrumInfo)
        {
            SpectrumInfo = spectrumInfo;
            _ionMatches  = new Dictionary <double, LibraryRankedSpectrumInfo.RankedMI>();
            foreach (var rmi in spectrumInfo.PeaksMatched)
            {
                _ionMatches[rmi.ObservedMz] = rmi;
            }

            // Default values
            FontSize  = 10;
            LineWidth = 1;
        }
Exemplo n.º 4
0
        /// <summary>
        /// Calculates the normalized contrast angle of the square rooted
        /// intensities of the two given spectra.
        /// </summary>
        /// <param name="spectrum1">First spectrum</param>
        /// <param name="spectrum2">Second spectrum</param>
        /// <param name="mzTolerance">Tolerance for considering two mzs the same</param>
        public static double CalculateSpectrumDotpMzMatch(LibraryRankedSpectrumInfo spectrum1, LibraryRankedSpectrumInfo spectrum2, double mzTolerance)
        {
            var matched1        = spectrum1.PeaksMatched.ToArray();
            var matched2        = spectrum2.PeaksMatched.ToArray();
            var intensities1All = new List <double>(matched1.Length + matched2.Length);
            var intensities2All = new List <double>(matched1.Length + matched2.Length);
            var matchIndex1     = 0;
            var matchIndex2     = 0;

            while (matchIndex1 < matched1.Length && matchIndex2 < matched2.Length)
            {
                var mz1 = matched1[matchIndex1].ObservedMz;
                var mz2 = matched2[matchIndex2].ObservedMz;
                if (Math.Abs(mz1 - mz2) <
                    mzTolerance)
                {
                    intensities1All.Add(matched1[matchIndex1].Intensity);
                    intensities2All.Add(matched2[matchIndex2].Intensity);

                    ++matchIndex1;
                    ++matchIndex2;
                }
                else if (mz1 < mz2)
                {
                    intensities1All.Add(matched1[matchIndex1].Intensity);
                    intensities2All.Add(0.0);
                    ++matchIndex1;
                }
                else
                {
                    intensities1All.Add(0.0);
                    intensities2All.Add(matched2[matchIndex2].Intensity);
                    ++matchIndex2;
                }
            }

            return(new Statistics(intensities1All).NormalizedContrastAngleSqrt(
                       new Statistics(intensities2All)));
        }
Exemplo n.º 5
0
        public void UpdateUI(bool selectionChanged = true)
        {
            // Only worry about updates, if the graph is visible
            // And make sure it is not disposed, since rendering happens on a timer
            if (!Visible || IsDisposed)
            {
                return;
            }

            // Clear existing data from the graph pane
            var graphPane = (MSGraphPane)graphControl.MasterPane[0];

            graphPane.CurveList.Clear();
            graphPane.GraphObjList.Clear();
            GraphItem = null;

            GraphHelper.FormatGraphPane(graphControl.GraphPane);
            GraphHelper.FormatFontSize(graphControl.GraphPane, Settings.Default.SpectrumFontSize);
            // Try to find a tree node with spectral library info associated
            // with the current selection.
            var nodeTree      = _stateProvider.SelectedNode as SrmTreeNode;
            var nodeGroupTree = nodeTree as TransitionGroupTreeNode;
            var nodeTranTree  = nodeTree as TransitionTreeNode;

            if (nodeTranTree != null)
            {
                nodeGroupTree = nodeTranTree.Parent as TransitionGroupTreeNode;
            }

            var             nodeGroup = (nodeGroupTree != null ? nodeGroupTree.DocNode : null);
            PeptideTreeNode nodePepTree;

            if (nodeGroup == null)
            {
                nodePepTree = nodeTree as PeptideTreeNode;
                if (nodePepTree != null)
                {
                    var listInfoGroups = GetLibraryInfoChargeGroups(nodePepTree);
                    if (listInfoGroups.Length == 1)
                    {
                        nodeGroup = listInfoGroups[0];
                    }
                    else if (listInfoGroups.Length > 1)
                    {
                        _nodeGroup      = null;
                        toolBar.Visible = false;
                        _graphHelper.SetErrorGraphItem(new NoDataMSGraphItem(
                                                           Resources.GraphSpectrum_UpdateUI_Multiple_charge_states_with_library_spectra));
                        return;
                    }
                }
            }
            else
            {
                nodePepTree = nodeGroupTree.Parent as PeptideTreeNode;
            }

            // Check for appropriate spectrum to load
            SrmSettings      settings  = DocumentUI.Settings;
            PeptideLibraries libraries = settings.PeptideSettings.Libraries;
            bool             available = false;

            if (nodeGroup == null || (!nodeGroup.HasLibInfo && !libraries.HasMidasLibrary))
            {
                _spectra = null;
            }
            else
            {
                TransitionGroup   group      = nodeGroup.TransitionGroup;
                TransitionDocNode transition = (nodeTranTree == null ? null : nodeTranTree.DocNode);
                var          lookupSequence  = group.Peptide.Target;// Sequence or custom ion id
                ExplicitMods lookupMods      = null;
                if (nodePepTree != null)
                {
                    lookupSequence = nodePepTree.DocNode.SourceUnmodifiedTarget;
                    lookupMods     = nodePepTree.DocNode.SourceExplicitMods;
                }
                try
                {
                    // Try to load a list of spectra matching the criteria for
                    // the current node group.
                    if (libraries.HasLibraries && libraries.IsLoaded)
                    {
                        if (NodeGroupChanged(nodeGroup))
                        {
                            try
                            {
                                UpdateSpectra(nodeGroup, lookupSequence, lookupMods);
                                UpdateToolbar();
                            }
                            catch (Exception)
                            {
                                _spectra = null;
                                UpdateToolbar();
                                throw;
                            }

                            _nodeGroup = nodeGroup;
                            if (settings.TransitionSettings.Instrument.IsDynamicMin)
                            {
                                ZoomSpectrumToSettings();
                            }
                        }

                        var spectrum = SelectedSpectrum;
                        if (spectrum != null)
                        {
                            IsotopeLabelType typeInfo = spectrum.LabelType;
                            var types   = _stateProvider.ShowIonTypes(group.IsProteomic);
                            var adducts = (group.IsProteomic ?
                                           Transition.DEFAULT_PEPTIDE_LIBRARY_CHARGES :
                                           nodeGroup.InUseAdducts).ToArray();
                            var charges     = _stateProvider.ShowIonCharges(adducts);
                            var rankTypes   = group.IsProteomic ? settings.TransitionSettings.Filter.PeptideIonTypes : settings.TransitionSettings.Filter.SmallMoleculeIonTypes;
                            var rankAdducts = group.IsProteomic ? settings.TransitionSettings.Filter.PeptideProductCharges : settings.TransitionSettings.Filter.SmallMoleculeFragmentAdducts;
                            var rankCharges = Adduct.OrderedAbsoluteChargeValues(rankAdducts);
                            // Make sure the types and charges in the settings are at the head
                            // of these lists to give them top priority, and get rankings correct.
                            int i = 0;
                            foreach (IonType type in rankTypes)
                            {
                                if (types.Remove(type))
                                {
                                    types.Insert(i++, type);
                                }
                            }
                            i = 0;
                            var showAdducts = new List <Adduct>();
                            foreach (var charge in rankCharges)
                            {
                                if (charges.Remove(charge))
                                {
                                    charges.Insert(i++, charge);
                                }
                                // NB for all adducts we just look at abs value of charge
                                // CONSIDER(bspratt): we may want finer per-adduct control for small molecule use
                                showAdducts.AddRange(adducts.Where(a => charge == Math.Abs(a.AdductCharge)));
                            }
                            showAdducts.AddRange(adducts.Where(a => charges.Contains(Math.Abs(a.AdductCharge)) && !showAdducts.Contains(a)));
                            SpectrumPeaksInfo spectrumInfo = spectrum.SpectrumPeaksInfo;
                            var spectrumInfoR = new LibraryRankedSpectrumInfo(spectrumInfo,
                                                                              typeInfo,
                                                                              nodeGroup,
                                                                              settings,
                                                                              lookupSequence,
                                                                              lookupMods,
                                                                              showAdducts,
                                                                              types,
                                                                              rankAdducts,
                                                                              rankTypes);
                            GraphItem = new SpectrumGraphItem(nodeGroup, transition, spectrumInfoR, spectrum.LibName)
                            {
                                ShowTypes      = types,
                                ShowCharges    = charges,
                                ShowRanks      = Settings.Default.ShowRanks,
                                ShowMz         = Settings.Default.ShowIonMz,
                                ShowObservedMz = Settings.Default.ShowObservedMz,
                                ShowDuplicates = Settings.Default.ShowDuplicateIons,
                                FontSize       = Settings.Default.SpectrumFontSize,
                                LineWidth      = Settings.Default.SpectrumLineWidth
                            };
                            LibraryChromGroup chromatogramData = null;
                            if (Settings.Default.ShowLibraryChromatograms)
                            {
                                chromatogramData = spectrum.LoadChromatogramData();
                            }
                            if (null == chromatogramData)
                            {
                                _graphHelper.ResetForSpectrum(new[] { nodeGroup.TransitionGroup });
                                _graphHelper.AddSpectrum(GraphItem);
                                _graphHelper.ZoomSpectrumToSettings(DocumentUI, nodeGroup);
                            }
                            else
                            {
                                _graphHelper.ResetForChromatograms(new[] { nodeGroup.TransitionGroup });

                                var displayType = GraphChromatogram.GetDisplayType(DocumentUI, nodeGroup);
                                IList <TransitionDocNode> displayTransitions =
                                    GraphChromatogram.GetDisplayTransitions(nodeGroup, displayType).ToArray();
                                int numTrans      = displayTransitions.Count;
                                var allChromDatas =
                                    chromatogramData.ChromDatas.Where(
                                        chromData => DisplayTypeMatches(chromData, displayType)).ToList();
                                var chromDatas = new List <LibraryChromGroup.ChromData>();
                                for (int iTran = 0; iTran < numTrans; iTran++)
                                {
                                    var displayTransition = displayTransitions[iTran];
                                    var indexMatch        =
                                        allChromDatas.IndexOf(chromData => IonMatches(displayTransition.Transition, chromData));
                                    if (indexMatch >= 0)
                                    {
                                        chromDatas.Add(allChromDatas[indexMatch]);
                                        allChromDatas.RemoveAt(indexMatch);
                                    }
                                    else
                                    {
                                        chromDatas.Add(null);
                                    }
                                }
                                allChromDatas.Sort((chromData1, chromData2) => chromData1.Mz.CompareTo(chromData2.Mz));
                                chromDatas.AddRange(allChromDatas);
                                double maxHeight         = chromDatas.Max(chromData => null == chromData ? double.MinValue : chromData.Height);
                                int    iChromDataPrimary = chromDatas.IndexOf(chromData => null != chromData && maxHeight == chromData.Height);
                                int    colorOffset       = displayType == DisplayTypeChrom.products
                                                      ? GraphChromatogram.GetDisplayTransitions(nodeGroup,
                                                                                                DisplayTypeChrom.
                                                                                                precursors).Count()
                                                      : 0;
                                for (int iChromData = 0; iChromData < chromDatas.Count; iChromData++)
                                {
                                    var chromData = chromDatas[iChromData];
                                    if (chromData == null)
                                    {
                                        continue;
                                    }
                                    string label;
                                    var    pointAnnotation = GraphItem.AnnotatePoint(new PointPair(chromData.Mz, 1.0));
                                    if (null != pointAnnotation)
                                    {
                                        label = pointAnnotation.Label;
                                    }
                                    else
                                    {
                                        label = chromData.Mz.ToString(@"0.####");
                                    }
                                    TransitionDocNode matchingTransition;
                                    Color             color;
                                    if (iChromData < numTrans)
                                    {
                                        matchingTransition = displayTransitions[iChromData];
                                        color =
                                            GraphChromatogram.COLORS_LIBRARY[
                                                (iChromData + colorOffset) % GraphChromatogram.COLORS_LIBRARY.Count];
                                    }
                                    else
                                    {
                                        matchingTransition = null;
                                        color =
                                            GraphChromatogram.COLORS_GROUPS[
                                                iChromData % GraphChromatogram.COLORS_GROUPS.Count];
                                    }

                                    TransitionChromInfo tranPeakInfo;
                                    ChromatogramInfo    chromatogramInfo;
                                    MakeChromatogramInfo(nodeGroup.PrecursorMz, chromatogramData, chromData, out chromatogramInfo, out tranPeakInfo);
                                    var graphItem = new ChromGraphItem(nodeGroup, matchingTransition, chromatogramInfo, iChromData == iChromDataPrimary ? tranPeakInfo : null, null,
                                                                       new[] { iChromData == iChromDataPrimary }, null, 0, false, false, null, 0,
                                                                       color, Settings.Default.ChromatogramFontSize, 1);
                                    LineItem curve = (LineItem)_graphHelper.AddChromatogram(PaneKey.DEFAULT, graphItem);
                                    if (matchingTransition == null)
                                    {
                                        curve.Label.Text = label;
                                    }
                                    curve.Line.Width = Settings.Default.ChromatogramLineWidth;
                                    if (null != transition)
                                    {
                                        if (IonMatches(transition.Transition, chromData))
                                        {
                                            color = ChromGraphItem.ColorSelected;
                                        }
                                    }
                                    curve.Color = color;
                                }
                                graphPane.Title.IsVisible  = false;
                                graphPane.Legend.IsVisible = true;
                                _graphHelper.FinishedAddingChromatograms(chromatogramData.StartTime, chromatogramData.EndTime, false);
                                graphControl.Refresh();
                            }
                            graphControl.IsEnableVPan = graphControl.IsEnableVZoom =
                                !Settings.Default.LockYAxis;
                            available = true;
                        }
                    }
                }
                catch (Exception)
                {
                    _graphHelper.SetErrorGraphItem(new NoDataMSGraphItem(
                                                       Resources.GraphSpectrum_UpdateUI_Failure_loading_spectrum__Library_may_be_corrupted));
                    return;
                }
            }
            // Show unavailable message, if no spectrum loaded
            if (!available)
            {
                UpdateToolbar();
                _nodeGroup = null;
                _graphHelper.SetErrorGraphItem(new UnavailableMSGraphItem());
            }
        }
        public void TestLibraryRankedSpectrumInfoSpeed()
        {
            var         testFilesDir = new TestFilesDir(TestContext, @"Test\LibraryRankedSpectrumInfoSpeedTest.zip");
            SrmDocument srmDocument;

            using (var stream = File.OpenRead(testFilesDir.GetTestPath("LibraryRankedSpectrumInfoSpeedTest.sky")))
            {
                srmDocument = (SrmDocument) new XmlSerializer(typeof(SrmDocument)).Deserialize(stream);
            }

            var unloadedLibrary = srmDocument.Settings.PeptideSettings.Libraries.Libraries.FirstOrDefault();

            Assert.IsNotNull(unloadedLibrary);
            var streamManager = new MemoryStreamManager();
            var loader        = new LibraryLoadTest.TestLibraryLoader {
                StreamManager = streamManager
            };
            var librarySpec = unloadedLibrary.CreateSpec(testFilesDir.GetTestPath("LibraryRankedSpectrumInfoSpeedTest.blib"));
            var library     = librarySpec.LoadLibrary(loader);

            Assert.IsTrue(library.IsLoaded);
            var peptideLibraries = srmDocument.Settings.PeptideSettings.Libraries.ChangeLibraries(new[] { library });

            var settingsWithLibraries =
                srmDocument.Settings.ChangePeptideSettings(
                    srmDocument.Settings.PeptideSettings.ChangeLibraries(peptideLibraries));

            // List of peptides to test with: <peptide sequence, description, expected # of matched ions, expected ranked ions>
            Tuple <string, string, int, double[]>[] testPeptides = new[]
            {
                // ReSharper disable StringLiteralTypo
                Tuple.Create("MEIVK", "Short Peptide",
                             20, new[] { 131.1, 147.1, 187.1 }),
                Tuple.Create("EIYYTPDPSELAAKEEPAKEEAPAPTPAASAPAPAAAAPAPVAAAAPAAAAAEIADEPVK", "Long Peptide",
                             55, new[] { 587.4, 771.4, 900.5 }),
                Tuple.Create("LVGFT[+80]FR", "Short Peptide with 1 Neutral Loss",
                             24, new[] { 305.1334, 322.0948, 325.2004 }),
                Tuple.Create("DLKEILSGFHNAGPVAGAGAASGAAAAGGDAAAEEEKEEEAAEES[+80]DDDMGFGLFD",
                             "Long peptide with 1 Neutral Loss",
                             43, new[] { 790.1161, 825.5901, 889.6103 }),
                Tuple.Create("MLPTS[+80]VS[+80]R", "Short peptide with 2 neutral losses",
                             36, new[] { 305.6439, 340.5001, 343.2071 }),
                Tuple.Create("RNPDFEDDDFLGGDFDEDEIDEESS[+80]EEEEEEKT[+80]QKK", "Long peptide with 2 neutral losses",
                             65, new[] { 483.2214, 552.9168, 626.2743 })
                // ReSharper restore StringLiteralTypo
            };

            Console.Out.WriteLine();
            foreach (var tuple in testPeptides)
            {
                var peptideDocNode = srmDocument.Molecules.FirstOrDefault(pep => pep.ModifiedSequenceDisplay == tuple.Item1);
                Assert.IsNotNull(peptideDocNode, "Could not find peptide {0}", tuple.Item1);
                var transitionGroup = peptideDocNode.TransitionGroups.FirstOrDefault();
                Assert.IsNotNull(transitionGroup);
                var spectrum = library
                               .GetSpectra(new LibKey(peptideDocNode.ModifiedTarget, transitionGroup.PrecursorAdduct),
                                           transitionGroup.LabelType, LibraryRedundancy.all).FirstOrDefault();
                Assert.IsNotNull(spectrum);

                var startTime = DateTime.UtcNow;
                LibraryRankedSpectrumInfo libraryRankedSpectrum = null;
                int repeatCount = 50;
                for (int i = 0; i < repeatCount; i++)
                {
                    libraryRankedSpectrum = LibraryRankedSpectrumInfo.NewLibraryRankedSpectrumInfo(spectrum.SpectrumPeaksInfo,
                                                                                                   transitionGroup.LabelType, transitionGroup, settingsWithLibraries, peptideDocNode.ExplicitMods,
                                                                                                   false, TransitionGroup.MAX_MATCHED_MSMS_PEAKS);
                    Assert.IsNotNull(libraryRankedSpectrum);
                }
                var endTime = DateTime.UtcNow;

                Console.Out.WriteLine("Time to get LibraryRankedSpectrumInfo for {0} {1} times: {2}", tuple.Item2, repeatCount, endTime.Subtract(startTime));
                Assert.IsNotNull(libraryRankedSpectrum);
                var rankedMzs = libraryRankedSpectrum.PeaksRanked.Select(peak => Math.Round(peak.ObservedMz, 4)).Take(3).ToArray();
                Console.Out.WriteLine("{0} matched peaks. First {1}/{2} ranked peaks: {{ {3} }}",
                                      libraryRankedSpectrum.PeaksMatched.Count(), rankedMzs.Length,
                                      libraryRankedSpectrum.PeaksRanked.Count(), string.Join(",", rankedMzs));
                if (!IsRecording)
                {
                    CollectionAssert.AreEqual(tuple.Item4, rankedMzs);
                    Assert.AreEqual(tuple.Item3, libraryRankedSpectrum.PeaksMatched.Count());
                }
            }
        }
Exemplo n.º 7
0
 public SpectrumGraphItem(TransitionGroupDocNode transitionGroupNode, TransitionDocNode transition,
     LibraryRankedSpectrumInfo spectrumInfo, string libName)
     : base(spectrumInfo)
 {
     TransitionGroupNode = transitionGroupNode;
     TransitionNode = transition;
     LibraryName = libName;
 }
Exemplo n.º 8
0
 private bool IsVisibleIon(LibraryRankedSpectrumInfo.RankedMI rmi)
 {
     bool singleIon = (rmi.Ordinal2 == 0);
     if (ShowDuplicates && singleIon)
         return false;
     return IsVisibleIon(rmi.IonType, rmi.Ordinal, rmi.Charge) ||
            IsVisibleIon(rmi.IonType2, rmi.Ordinal2, rmi.Charge2);
 }
Exemplo n.º 9
0
        private string GetLabel(LibraryRankedSpectrumInfo.RankedMI rmi)
        {
            string[] parts = new string[2];
            int i = 0;
            bool visible1 = IsVisibleIon(rmi.IonType, rmi.Ordinal, rmi.Charge);
            bool visible2 = IsVisibleIon(rmi.IonType2, rmi.Ordinal2, rmi.Charge2);
            // Show the m/z values in the labels, if they should both be visible, and
            // they have different display values.
            bool showMzInLabel = ShowMz && visible1 && visible2 &&
                GetDisplayMz(rmi.PredictedMz) != GetDisplayMz(rmi.PredictedMz2);

            if (visible1)
            {
                parts[i++] = GetLabel(rmi.IonType, rmi.Ordinal, rmi.Losses,
                    rmi.Charge, rmi.PredictedMz, rmi.Rank, showMzInLabel);
            }
            if (visible2)
            {
                parts[i] = GetLabel(rmi.IonType2, rmi.Ordinal2, rmi.Losses2,
                    rmi.Charge2, rmi.PredictedMz2, 0, showMzInLabel);
            }
            StringBuilder sb = new StringBuilder();
            foreach (string part in parts)
            {
                if (part == null)
                    continue;
                if (sb.Length > 0)
                {
                    if (showMzInLabel)
                        sb.AppendLine();
                    else
                        sb.Append(", "); // Not L10N
                }
                sb.Append(part);
            }
            // If predicted m/z should be displayed, but hasn't been yet, then display now.
            if (ShowMz && !showMzInLabel)
            {
                sb.AppendLine().Append(GetDisplayMz(rmi.PredictedMz));
            }
            // If showing observed m/z, and it is different from the predicted m/z, then display it last.
            if (ShowObservedMz)
            {
                sb.AppendLine().Append(GetDisplayMz(rmi.ObservedMz));
            }
            return sb.ToString();
        }
Exemplo n.º 10
0
        // ReSharper restore InconsistentNaming
        protected AbstractSpectrumGraphItem(LibraryRankedSpectrumInfo spectrumInfo)
        {
            SpectrumInfo = spectrumInfo;
            _ionMatches = new Dictionary<double, LibraryRankedSpectrumInfo.RankedMI>();
            foreach (var rmi in spectrumInfo.PeaksMatched)
            {
                _ionMatches[rmi.ObservedMz] = rmi;
            }

            // Default values
            FontSize = 10;
            LineWidth = 1;
        }