コード例 #1
0
ファイル: ProteinMatcher.cs プロジェクト: rfellers/pwiz
        public static String ProteinMatchTypeDbFieldName(ProteinMatchType type)
        {
            switch (type)
            {
            case ProteinMatchType.name:
                return(@"Name");

            case ProteinMatchType.description:
                return(@"Description");

            case ProteinMatchType.sequence:
                return(@"Sequence");

            case ProteinMatchType.accession:
                return(@"Accession");

            case ProteinMatchType.preferredName:
                return(@"PreferredName");

            case ProteinMatchType.gene:
                return(@"Gene");

            case ProteinMatchType.species:
                return(@"Species");

            default:
                return(String.Empty);
            }
        }
コード例 #2
0
 public ProteinMatchSettings(ProteomeDbPath proteomeDbPath, IProtease protease, ProteinMatchType proteinMatchTypes, String searchText)
 {
     ProteomeDbPath = proteomeDbPath;
     Protease       = protease;
     if (protease != null)
     {
         using (var proteomeDb = proteomeDbPath.OpenProteomeDb())
         {
             Digestion = proteomeDb.GetDigestion(protease.Name);
         }
     }
     MatchTypes = proteinMatchTypes;
     SearchText = searchText;
 }
コード例 #3
0
ファイル: ProteinMatcher.cs プロジェクト: lgatto/proteowizard
 public ProteinMatchSettings(ProteomeDbPath proteomeDbPath, IProtease protease, ProteinMatchType proteinMatchTypes, String searchText)
 {
     ProteomeDbPath = proteomeDbPath;
     Protease = protease;
     if (protease != null)
     {
         using (var proteomeDb = proteomeDbPath.OpenProteomeDb())
         {
             Digestion = proteomeDb.GetDigestion(protease.Name);
         }
     }
     MatchTypes = proteinMatchTypes;
     SearchText = searchText;
 }
コード例 #4
0
        public static string TextForMatchTypes(this ProteinMetadata p, ProteinMatchType type)
        {
            if (type == ProteinMatchType.sequence)
            {
                return(null);
            }

            var results = new List <string>();

            if (0 != (type & ProteinMatchType.name))
            {
                results.Add(p.Name ?? String.Empty);
            }
            if (0 != (type & ProteinMatchType.accession))
            {
                results.Add(p.Accession ?? String.Empty);
            }
            if (0 != (type & ProteinMatchType.preferredName))
            {
                results.Add(p.PreferredName ?? String.Empty);
            }
            if (0 != (type & ProteinMatchType.gene))
            {
                results.Add(p.Gene ?? String.Empty);
            }
            if (0 != (type & ProteinMatchType.species))
            {
                results.Add(p.Species ?? String.Empty);
            }
            if (0 != (type & ProteinMatchType.description)) // put this last, as it likely contains the others
            {
                results.Add(p.Description ?? String.Empty);
            }
            if (results.Count > 0)
            {
                return(String.Join(" ", results)); // Not L10N
            }
            return(null);
        }
コード例 #5
0
ファイル: ProteinMatcher.cs プロジェクト: lgatto/proteowizard
 static public String ProteinMatchTypeDbFieldName(ProteinMatchType type)
 {
     switch (type)
     {
         case ProteinMatchType.name:
             return "Name"; // Not L10N
         case ProteinMatchType.description:
             return "Description"; // Not L10N
         case ProteinMatchType.sequence:
             return "Sequence"; // Not L10N
         case ProteinMatchType.accession:
             return "Accession"; // Not L10N
         case ProteinMatchType.preferredName:
             return "PreferredName"; // Not L10N
         case ProteinMatchType.gene:
             return "Gene"; // Not L10N
         case ProteinMatchType.species:
             return "Species"; // Not L10N
         default:
             return String.Empty;
     }
 }
コード例 #6
0
ファイル: ProteinMatcher.cs プロジェクト: rfellers/pwiz
 private static bool Matches(ProteinMetadata proteinMetadata, ProteinMatchType matchType, string ltext)
 {
     return(ContainsLowerCase(proteinMetadata.TextForMatchTypes(ProteinMatchTypes.Singleton(matchType)), ltext));
 }
コード例 #7
0
        public ProteinMatch(ProteinMatchSettings proteinMatchSettings, Protein protein)
        {
            Settings = proteinMatchSettings;
            Protein  = protein;
            String ltext = proteinMatchSettings.SearchText.ToLower();

            for (int bit = 1; bit < (int)ProteinMatchType.all; bit <<= 1) // name, accession, gene, etc - case insenstive
            {
                ProteinMatchType matchType = (ProteinMatchType)bit;
                if ((0 != (proteinMatchSettings.MatchTypes & matchType)) &&
                    (0 == (matchType & (ProteinMatchType.sequence | ProteinMatchType.description)))) // handle sequence and description below
                {
                    if (Matches(protein.ProteinMetadata, matchType, ltext))
                    {
                        MatchType |= matchType;
                    }
                    else
                    {
                        foreach (ProteinMetadata alternative in Protein.AlternativeNames)
                        {
                            if (Matches(alternative, matchType, ltext))
                            {
                                MatchType      |= matchType;
                                AlternativeName = alternative;
                                break;
                            }
                        }
                    }
                }
            }
            if ((MatchType == 0) && // Don't bother declaring a description match if we already have a more specific one (name, accession etc)
                (0 != (proteinMatchSettings.MatchTypes & ProteinMatchType.description)))
            {
                if (ContainsLowerCase(protein.Description, ltext) ||
                    ContainsLowerCase(protein.Name, ltext))
                {
                    MatchType |= ProteinMatchType.description;
                }
                else
                {
                    foreach (ProteinMetadata alternative in Protein.AlternativeNames)
                    {
                        if (ContainsLowerCase(alternative.Name, ltext) ||
                            ContainsLowerCase(alternative.Description, ltext))
                        {
                            MatchType |= ProteinMatchType.description;
                            AlternativeDescription = alternative;
                        }
                    }
                }
            }
            List <DigestedPeptide> digestedPeptides = new List <DigestedPeptide>();

            if (0 != (proteinMatchSettings.MatchTypes & ProteinMatchType.sequence))
            {
                if (proteinMatchSettings.Protease != null)
                {
                    String lastPeptide = null;
                    foreach (var peptide in proteinMatchSettings.Protease.Digest(protein))
                    {
                        if (!peptide.Sequence.StartsWith(proteinMatchSettings.SearchText))
                        {
                            continue;
                        }
                        // If this peptide is just an extension of the previous peptide (i.e. with one
                        // more missed cleavage), then only include it if the user has typed the entire
                        // sequence of the previous peptide.
                        if (lastPeptide != null && peptide.Sequence.StartsWith(lastPeptide) &&
                            lastPeptide.Length > proteinMatchSettings.SearchText.Length)
                        {
                            continue;
                        }
                        lastPeptide = peptide.Sequence;
                        MatchType  |= ProteinMatchType.sequence;
                        digestedPeptides.Add(peptide);
                    }
                }
            }
            DigestedPeptides = digestedPeptides;
        }
コード例 #8
0
        private void ExecuteBackground()
        {
            try
            {
                using (var proteomeDb = Settings.ProteomeDbPath.OpenProteomeDb())
                    using (_session = proteomeDb.OpenSession())
                    {
                        if (0 != (Settings.MatchTypes & ProteinMatchType.sequence) && Settings.Digestion != null &&
                            IsAminoAcidSequence(Settings.SearchText))
                        {
                            String truncatedSearchText = Settings.SearchText.Substring(
                                0, Math.Min(Settings.SearchText.Length, Settings.Digestion.MaxSequenceLength));
                            String hql = "SELECT distinct dpp.Protein FROM " + typeof(DbDigestedPeptideProtein) + " dpp"                                 // Not L10N
                                         +
                                         "\nWHERE dpp.Peptide.Digestion = :digestion AND dpp.Peptide.Sequence >= :start AND dpp.Peptide.Sequence < :end" // Not L10N
                                         + "\nORDER BY dpp.Peptide.Sequence";                                                                            // Not L10N
                            IQuery query = _session.CreateQuery(hql)
                                           .SetParameter("digestion", Settings.Digestion.GetEntity(_session))                                            // Not L10N
                                           .SetParameter("start", truncatedSearchText)                                                                   // Not L10N
                                           .SetParameter("end", NextString(truncatedSearchText));                                                        // Not L10N
                            AddProteinMatches(query);
                        }

                        if ((_matches == null) || (_matches.Count < MaxResults))
                        {
                            string           pattern            = "%" + Settings.SearchText + "%"; // Not L10N
                            ProteinMatchType unwantedMatchTypes = ProteinMatchType.sequence;       // Don't search on sequence again
                            if (Settings.SearchText.Length < MIN_FREE_SEARCH_LENGTH)
                            {
                                // That could cast a pretty wide net - only match to beginning of keywords, and not to description or species
                                pattern             = Settings.SearchText + "%"; // Not L10N
                                unwantedMatchTypes |= (ProteinMatchType.description | ProteinMatchType.species);
                            }

                            var exprLike = new List <string>();
                            for (int bit = 1; bit < (int)ProteinMatchType.all; bit = bit << 1)
                            {
                                ProteinMatchType matchType = (ProteinMatchType)bit;
                                if ((0 == (matchType & unwantedMatchTypes)) &&
                                    (0 != (Settings.MatchTypes & matchType)))
                                {
                                    exprLike.Add(String.Format("pn.{0} LIKE :expr", ProteinMatchTypeDbFieldName(matchType))); // Not L10N
                                }
                            }

                            String hql = "SELECT distinct pn.Protein FROM " + typeof(DbProteinName) + " pn " // Not L10N
                                         + String.Format("\nWHERE {0}", String.Join(" OR ", exprLike))       // Not L10N
                                         + "\nORDER BY pn.IsPrimary DESC, pn.Name";                          // Not L10N
                            IQuery query = _session.CreateQuery(hql).SetParameter("expr", pattern);          // Not L10N
                            AddProteinMatches(query);
                        }
                    }
            }
            catch (Exception exception)
            {
                if (_cancelled)
                {
                    return;
                }
                Console.Out.WriteLine(exception);
            }
        }
コード例 #9
0
 private ProteinMatchSettings CreateProteinMatchSettings(SrmDocument srmDocument, ProteinMatchType matchTypes, String searchText)
 {
     var peptideSettings = srmDocument.Settings.PeptideSettings;
     var backgroundProteome = peptideSettings.BackgroundProteome;
     if (backgroundProteome.IsNone)
     {
         return null;
     }
     try
     {
         if (_proteomeDb != null && _proteomeDb.Path != backgroundProteome.DatabasePath)
         {
             _proteomeDb.Dispose();
             _proteomeDb = null;
         }
         if (_proteomeDb == null)
         {
             _proteomeDb = backgroundProteome.OpenProteomeDb();
         }
         return new ProteinMatchSettings(_proteomeDb.ProteomeDbPath,
                                     new ProteaseImpl(peptideSettings.Enzyme),
                                     matchTypes,
                                     searchText);
     }
     catch (SQLiteException)
     {
         // CONSIDER: Silent failure could be confusing.  Show a message box
         //           about failing to open the database.
         return null;
     }
 }
コード例 #10
0
        /// <summary>
        /// Create the ordered list of dropdown items, with a rational sort order:
        ///   First present any sequence matches, sorted by sequence
        ///   Then present any name, accession, gene, preferredname, or species metadata matches, sorted by the matched metadata field
        ///   Then present any matches against the description field, sorted by the description text starting at the match location
        /// </summary>
        public static IList<ListViewItem> CreateListViewItems(IList<ProteinMatch> matches, String searchText, ProteinMatchType matchTypes, int maxCount)
        {
            var listItems = new SortedList<string,ListViewItem>();
            var listUsedMatches = new List<string>();

            // First check for matching by sequence
            foreach (var match in matches)
            {
                if (0 != (matchTypes & match.MatchType & ProteinMatchType.sequence))
                {
                    foreach (DigestedPeptide digestedPeptide in match.DigestedPeptides)
                    {
                        var listItem = new ListViewItem
                                           {
                                               Text = digestedPeptide.Sequence,
                                               Tag = new StatementCompletionItem
                                                         {
                                                             Peptide = digestedPeptide.Sequence,
                                                             ProteinInfo = match.Protein.ProteinMetadata,
                                                             SearchText = searchText
                                                         },
                                           };
                        StatementCompletionForm.AddDescription(listItem,
                                                               match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes),
                                                               null);
                        listUsedMatches.Add(match.Protein.Name);
                        listItem.ImageIndex = (int) ImageId.peptide;
                        var tooltip = new StringBuilder();
                        tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions)
                               .Append(match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes));
                        foreach (var name in match.Protein.AlternativeNames)
                        {
                            tooltip.AppendLine().Append(name.TextForMatchTypes(matchTypes));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                        // Note the leading space in this sort key - we'd like to list sequence matches first
                        var key = TextUtil.SpaceSeparate(" ", listItem.Text, listItem.ToolTipText); // Not L10N
                        if (!listItems.ContainsKey(key))
                            listItems.Add(key, listItem);
                    }
                }
            }
            if (listItems.Count >= maxCount)
            {
                return new List<ListViewItem>(listItems.Values);  // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence
            }

            // Decide which field not to display on righthand side, based on what's already showing on the left due to View|Targets|By* menu
            ProteinMatchType displayMatchType = ProteinMatchType.all;
            switch (SequenceTree.ProteinsDisplayMode)
            {
                case ProteinDisplayMode.ByName:
                    displayMatchType &= ~ProteinMatchType.name;
                    break;
                case ProteinDisplayMode.ByAccession:
                    displayMatchType &= ~ProteinMatchType.accession;
                    break;
                case ProteinDisplayMode.ByGene:
                    displayMatchType &= ~ProteinMatchType.gene;
                    break;
                case ProteinDisplayMode.ByPreferredName:
                    displayMatchType &= ~ProteinMatchType.preferredName;
                    break;
            }

            foreach (var match in matches)
            {
                // Try matching on name, accession etc - cycle through name, accession, preferredName, gene
                for (int bit = 1; bit < (int) ProteinMatchType.all; bit = bit << 1)
                {
                    ProteinMatchType tryType = (ProteinMatchType) bit;
                    if ((tryType != ProteinMatchType.sequence) && // We already did sequence
                        (tryType != ProteinMatchType.description) &&  // And aren't ready for description
                        (0 != (matchTypes & match.MatchType & tryType) &&
                        !listUsedMatches.Contains(match.Protein.Name)))
                    {
                        var listItem = new ListViewItem();
                        // Show description, and any other fields we were searching on
                        if (match.AlternativeName != null)
                        {
                            listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.AlternativeName, Settings.Default.ShowPeptidesDisplayMode);
                            listItem.Tag = new StatementCompletionItem {ProteinInfo = match.AlternativeName, SearchText = searchText};
                            StatementCompletionForm.AddDescription(listItem,
                                match.AlternativeName.TextForMatchTypes(displayMatchType & ~ProteinMatchType.name), searchText);
                        }
                        else
                        {
                            listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.Protein.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode);
                            listItem.Tag = new StatementCompletionItem { ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText };
                            StatementCompletionForm.AddDescription(listItem,
                                match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType), searchText);
                        }
                        listUsedMatches.Add(match.Protein.Name);
                        listItem.ImageIndex = (int) ImageId.protein;
                        var tooltip = new StringBuilder();
                        tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions)
                            .Append(match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType));
                        foreach (var altName in match.Protein.AlternativeNames)
                        {
                            tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                        // We want the sort to be on the particular bit of metadata that we matched
                        var key = TextUtil.SpaceSeparate(match.Protein.ProteinMetadata.TextForMatchTypes(tryType), listItem.Text, listItem.ToolTipText);
                        if (!listItems.ContainsKey(key))
                            listItems.Add(key, listItem);
                        break;
                    }
                }
            }
            if (listItems.Count >= maxCount)
            {
                return new List<ListViewItem>(listItems.Values);  // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence
            }

            // Any matches by description?
            foreach (var match in matches)
            {
                if ((0 != (match.MatchType & ProteinMatchType.description)) &&
                    !listUsedMatches.Contains(match.Protein.Name))
                {
                    ProteinMetadata mainName = match.AlternativeDescription;
                    string matchName = match.Protein.Name;
                    var proteinInfo = match.Protein.ProteinMetadata;
                    if (matchName.Length > MAX_NAME_LENGTH)
                        proteinInfo = proteinInfo.ChangeName(matchName.Substring(0, MAX_NAME_LENGTH) + "..."); // Not L10N
                    var alternativeNames = new List<ProteinMetadata>();
                    if (mainName == null)
                    {
                        mainName = proteinInfo;
                    }
                    else
                    {
                        alternativeNames.Add(proteinInfo);
                    }
                    var listItem = new ListViewItem
                                       {
                                           Text = PeptideGroupTreeNode.ProteinModalDisplayText(mainName, Settings.Default.ShowPeptidesDisplayMode),
                                           ImageIndex = (int) ImageId.protein,
                                           Tag = new StatementCompletionItem { ProteinInfo = proteinInfo, SearchText = searchText }
                                       };

                    StatementCompletionForm.AddDescription(listItem, mainName.TextForMatchTypes(displayMatchType), searchText);
                    if (match.Protein.AlternativeNames.Count > 0)
                    {
                        alternativeNames.AddRange(match.Protein.AlternativeNames);
                        StringBuilder tooltip = new StringBuilder(Resources.StatementCompletionTextBox_CreateListViewItems_Alternative_Names);
                        foreach (var altName in alternativeNames)
                        {
                            if (altName.Name == mainName.Name)
                            {
                                continue;
                            }

                            tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType | ProteinMatchType.name));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                    }
                    // We want the sort to be on what we matched in the description, and what follows.
                    var remains = match.Protein.ProteinMetadata.Description;
                    int pos = remains.ToLower().IndexOf(searchText.ToLower(), StringComparison.Ordinal);
                    if (pos > 0)
                        remains = remains.Substring(pos);
                    var key = TextUtil.SpaceSeparate(remains, listItem.Text, listItem.ToolTipText);
                    if (!listItems.ContainsKey(key))
                        listItems.Add(key, listItem);
                }

            }
            return new List<ListViewItem>(listItems.Values);
        }
コード例 #11
0
ファイル: ProteinMatcher.cs プロジェクト: lgatto/proteowizard
        public static string TextForMatchTypes(this ProteinMetadata p, ProteinMatchType type)
        {
            if (type == ProteinMatchType.sequence)
                return null;

            var results = new List<string>();
            if (0 != (type & ProteinMatchType.name))
                results.Add(p.Name??String.Empty);
            if (0 != (type & ProteinMatchType.accession))
                results.Add(p.Accession ?? String.Empty);
            if (0 != (type & ProteinMatchType.preferredName))
                results.Add(p.PreferredName ?? String.Empty);
            if (0 != (type & ProteinMatchType.gene))
                results.Add(p.Gene ?? String.Empty);
            if (0 != (type & ProteinMatchType.species))
                results.Add(p.Species ?? String.Empty);
            if (0 != (type & ProteinMatchType.description)) // put this last, as it likely contains the others
                results.Add(p.Description ?? String.Empty);
            if (results.Count > 0)
                return String.Join(" ",results); // Not L10N

            return null;
        }
コード例 #12
0
ファイル: ProteinMatcher.cs プロジェクト: lgatto/proteowizard
 private static bool Matches(ProteinMetadata proteinMetadata, ProteinMatchType matchType, string ltext)
 {
     return ContainsLowerCase(proteinMetadata.TextForMatchTypes(matchType), ltext);
 }
コード例 #13
0
        private ProteinMatchSettings CreateProteinMatchSettings(SrmDocument srmDocument, ProteinMatchType matchTypes, String searchText)
        {
            var peptideSettings    = srmDocument.Settings.PeptideSettings;
            var backgroundProteome = peptideSettings.BackgroundProteome;

            if (backgroundProteome.IsNone)
            {
                return(null);
            }
            try
            {
                if (_proteomeDb != null && _proteomeDb.Path != backgroundProteome.DatabasePath)
                {
                    _proteomeDb.Dispose();
                    _proteomeDb = null;
                }
                if (_proteomeDb == null)
                {
                    _proteomeDb = backgroundProteome.OpenProteomeDb();
                }
                return(new ProteinMatchSettings(_proteomeDb.ProteomeDbPath,
                                                new ProteaseImpl(peptideSettings.Enzyme),
                                                matchTypes,
                                                searchText));
            }
            catch (SQLiteException)
            {
                // CONSIDER: Silent failure could be confusing.  Show a message box
                //           about failing to open the database.
                return(null);
            }
        }
コード例 #14
0
        /// <summary>
        /// Create the ordered list of dropdown items, with a rational sort order:
        ///   First present any sequence matches, sorted by sequence
        ///   Then present any name, accession, gene, preferredname, or species metadata matches, sorted by the matched metadata field
        ///   Then present any matches against the description field, sorted by the description text starting at the match location
        /// </summary>
        public static IList <ListViewItem> CreateListViewItems(IList <ProteinMatch> matches, String searchText, ProteinMatchType matchTypes, int maxCount)
        {
            var listItems       = new SortedList <string, ListViewItem>();
            var listUsedMatches = new List <string>();

            // First check for matching by sequence
            foreach (var match in matches)
            {
                if (0 != (matchTypes & match.MatchType & ProteinMatchType.sequence))
                {
                    foreach (DigestedPeptide digestedPeptide in match.DigestedPeptides)
                    {
                        var listItem = new ListViewItem
                        {
                            Text = digestedPeptide.Sequence,
                            Tag  = new StatementCompletionItem
                            {
                                Peptide     = digestedPeptide.Sequence,
                                ProteinInfo = match.Protein.ProteinMetadata,
                                SearchText  = searchText
                            },
                        };
                        StatementCompletionForm.AddDescription(listItem,
                                                               match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes),
                                                               null);
                        listUsedMatches.Add(match.Protein.Name);
                        listItem.ImageIndex = (int)ImageId.peptide;
                        var tooltip = new StringBuilder();
                        tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions)
                        .Append(match.Protein.ProteinMetadata.TextForMatchTypes(matchTypes));
                        foreach (var name in match.Protein.AlternativeNames)
                        {
                            tooltip.AppendLine().Append(name.TextForMatchTypes(matchTypes));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                        // Note the leading space in this sort key - we'd like to list sequence matches first
                        var key = TextUtil.SpaceSeparate(" ", listItem.Text, listItem.ToolTipText); // Not L10N
                        if (!listItems.ContainsKey(key))
                        {
                            listItems.Add(key, listItem);
                        }
                    }
                }
            }
            if (listItems.Count >= maxCount)
            {
                return(new List <ListViewItem>(listItems.Values));  // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence
            }

            // Decide which field not to display on righthand side, based on what's already showing on the left due to View|Targets|By* menu
            ProteinMatchType displayMatchType = ProteinMatchType.all;

            switch (SequenceTree.ProteinsDisplayMode)
            {
            case ProteinDisplayMode.ByName:
                displayMatchType &= ~ProteinMatchType.name;
                break;

            case ProteinDisplayMode.ByAccession:
                displayMatchType &= ~ProteinMatchType.accession;
                break;

            case ProteinDisplayMode.ByGene:
                displayMatchType &= ~ProteinMatchType.gene;
                break;

            case ProteinDisplayMode.ByPreferredName:
                displayMatchType &= ~ProteinMatchType.preferredName;
                break;
            }

            foreach (var match in matches)
            {
                // Try matching on name, accession etc - cycle through name, accession, preferredName, gene
                for (int bit = 1; bit < (int)ProteinMatchType.all; bit = bit << 1)
                {
                    ProteinMatchType tryType = (ProteinMatchType)bit;
                    if ((tryType != ProteinMatchType.sequence) &&    // We already did sequence
                        (tryType != ProteinMatchType.description) && // And aren't ready for description
                        (0 != (matchTypes & match.MatchType & tryType) &&
                         !listUsedMatches.Contains(match.Protein.Name)))
                    {
                        var listItem = new ListViewItem();
                        // Show description, and any other fields we were searching on
                        if (match.AlternativeName != null)
                        {
                            listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.AlternativeName, Settings.Default.ShowPeptidesDisplayMode);
                            listItem.Tag  = new StatementCompletionItem {
                                ProteinInfo = match.AlternativeName, SearchText = searchText
                            };
                            StatementCompletionForm.AddDescription(listItem,
                                                                   match.AlternativeName.TextForMatchTypes(displayMatchType & ~ProteinMatchType.name), searchText);
                        }
                        else
                        {
                            listItem.Text = PeptideGroupTreeNode.ProteinModalDisplayText(match.Protein.ProteinMetadata, Settings.Default.ShowPeptidesDisplayMode);
                            listItem.Tag  = new StatementCompletionItem {
                                ProteinInfo = match.Protein.ProteinMetadata, SearchText = searchText
                            };
                            StatementCompletionForm.AddDescription(listItem,
                                                                   match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType), searchText);
                        }
                        listUsedMatches.Add(match.Protein.Name);
                        listItem.ImageIndex = (int)ImageId.protein;
                        var tooltip = new StringBuilder();
                        tooltip.AppendLine(Resources.StatementCompletionTextBox_CreateListViewItems_Descriptions)
                        .Append(match.Protein.ProteinMetadata.TextForMatchTypes(displayMatchType));
                        foreach (var altName in match.Protein.AlternativeNames)
                        {
                            tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                        // We want the sort to be on the particular bit of metadata that we matched
                        var key = TextUtil.SpaceSeparate(match.Protein.ProteinMetadata.TextForMatchTypes(tryType), listItem.Text, listItem.ToolTipText);
                        if (!listItems.ContainsKey(key))
                        {
                            listItems.Add(key, listItem);
                        }
                        break;
                    }
                }
            }
            if (listItems.Count >= maxCount)
            {
                return(new List <ListViewItem>(listItems.Values));  // We used to exit here if we had any matches - but that's frustrating when you're not actually trying to match by sequence
            }

            // Any matches by description?
            foreach (var match in matches)
            {
                if ((0 != (match.MatchType & ProteinMatchType.description)) &&
                    !listUsedMatches.Contains(match.Protein.Name))
                {
                    ProteinMetadata mainName    = match.AlternativeDescription;
                    string          matchName   = match.Protein.Name;
                    var             proteinInfo = match.Protein.ProteinMetadata;
                    if (matchName.Length > MAX_NAME_LENGTH)
                    {
                        proteinInfo = proteinInfo.ChangeName(matchName.Substring(0, MAX_NAME_LENGTH) + "..."); // Not L10N
                    }
                    var alternativeNames = new List <ProteinMetadata>();
                    if (mainName == null)
                    {
                        mainName = proteinInfo;
                    }
                    else
                    {
                        alternativeNames.Add(proteinInfo);
                    }
                    var listItem = new ListViewItem
                    {
                        Text       = PeptideGroupTreeNode.ProteinModalDisplayText(mainName, Settings.Default.ShowPeptidesDisplayMode),
                        ImageIndex = (int)ImageId.protein,
                        Tag        = new StatementCompletionItem {
                            ProteinInfo = proteinInfo, SearchText = searchText
                        }
                    };

                    StatementCompletionForm.AddDescription(listItem, mainName.TextForMatchTypes(displayMatchType), searchText);
                    if (match.Protein.AlternativeNames.Count > 0)
                    {
                        alternativeNames.AddRange(match.Protein.AlternativeNames);
                        StringBuilder tooltip = new StringBuilder(Resources.StatementCompletionTextBox_CreateListViewItems_Alternative_Names);
                        foreach (var altName in alternativeNames)
                        {
                            if (altName.Name == mainName.Name)
                            {
                                continue;
                            }

                            tooltip.AppendLine().Append(altName.TextForMatchTypes(displayMatchType | ProteinMatchType.name));
                        }
                        listItem.ToolTipText = StripTabs(tooltip.ToString());
                    }
                    // We want the sort to be on what we matched in the description, and what follows.
                    var remains = match.Protein.ProteinMetadata.Description;
                    int pos     = remains.ToLower().IndexOf(searchText.ToLower(), StringComparison.Ordinal);
                    if (pos > 0)
                    {
                        remains = remains.Substring(pos);
                    }
                    var key = TextUtil.SpaceSeparate(remains, listItem.Text, listItem.ToolTipText);
                    if (!listItems.ContainsKey(key))
                    {
                        listItems.Add(key, listItem);
                    }
                }
            }
            return(new List <ListViewItem>(listItems.Values));
        }