* SequenceIdMatcher\r
* <p>Description: </p>\r
* Routine which does approximate Sequence Id resolution by name using\r
- * string containment (on word boundaries) rather than equivalence\r
+ * string containment (on word boundaries) rather than equivalence. It also\r
+ * attempts to resolve ties where no exact match is available by picking the\r
+ * the id closest to the query.\r
* <p>Copyright: Copyright (c) 2004</p>\r
*\r
* <p>Company: Dundee University</p>\r
names.put(new SeqIdName(seqs[i].getName()), seqs[i]);\r
}\r
}\r
+ /**\r
+ * returns the closest SequenceI in matches to SeqIdName and returns all the matches\r
+ * to the names hash.\r
+ * @param candName SeqIdName\r
+ * @param matches Vector of SequenceI objects\r
+ * @return SequenceI closest SequenceI to SeqIdName\r
+ */\r
+ private SequenceI pickbestMatch(SeqIdName candName, Vector matches) {\r
+ SequenceI match=null;\r
+ if (candName==null || matches==null || matches.size()==0)\r
+ return null;\r
+ match=(SequenceI) matches.elementAt(0);\r
+ matches.removeElementAt(0);\r
+ names.put(new SeqIdName(match.getName()), match);\r
+ int matchlen=match.getName().length();\r
+ int namlen=candName.id.length();\r
+ while (matches.size()>0) {\r
+ // look through for a better one.\r
+ SequenceI cand=(SequenceI) matches.elementAt(0);\r
+ names.put(new SeqIdName(cand.getName()), cand);\r
+ int candlen = cand.getName().length();\r
+ // keep the one with an id 'closer' to the given seqnam string\r
+ if (Math.abs(matchlen-namlen)>Math.abs(candlen-namlen) && candlen>matchlen) {\r
+ match = cand;\r
+ matchlen = candlen;\r
+ }\r
+ }\r
+ return match;\r
+ }\r
\r
+ /**\r
+ * get SequenceI with closest SequenceI.getName() to seq.getName()\r
+ * @param seq SequenceI\r
+ * @return SequenceI\r
+ */\r
SequenceI findIdMatch(SequenceI seq)\r
{\r
SeqIdName nam = new SeqIdName(seq.getName());\r
-\r
- if (names.containsKey(nam))\r
- {\r
- return (SequenceI) names.get(nam);\r
- }\r
-\r
- return null;\r
+ return findIdMatch(nam);\r
}\r
\r
SequenceI findIdMatch(String seqnam)\r
- {\r
- SeqIdName nam = new SeqIdName(seqnam);\r
-\r
- if (names.containsKey(nam))\r
{\r
- return (SequenceI) names.get(nam);\r
- }\r
-\r
- return null;\r
+ SeqIdName nam = new SeqIdName(seqnam);\r
+ return findIdMatch(nam);\r
}\r
-\r
/**\r
* findIdMatch\r
*\r
\r
if (names.containsKey(nam))\r
{\r
- namedseqs[i] = (SequenceI) names.get(nam);\r
+ namedseqs[i] = findIdMatch(nam);\r
}\r
else\r
{\r
return namedseqs;\r
}\r
\r
+ /**\r
+ * core findIdMatch search method\r
+ * @param nam SeqIdName\r
+ * @return SequenceI\r
+ */\r
+ private SequenceI findIdMatch(jalview.analysis.SequenceIdMatcher.SeqIdName\r
+ nam)\r
+ {\r
+ Vector matches=new Vector();\r
+ while (names.containsKey(nam))\r
+ {\r
+ matches.addElement(names.remove(nam));\r
+ }\r
+ return pickbestMatch(nam, matches);\r
+ }\r
+\r
private class SeqIdName\r
{\r
String id;\r
* JBPNote: This is a heuristic that will fail for arbritrarily extended sequence id's\r
* (like portions of an aligned set of repeats from one sequence)\r
*/\r
- private String WORD_SEP="~. |#\\/<>!\"£$%^*)}[@',?";\r
+ private String WORD_SEP="~. |#\\/<>!\"£$%^*)}[@',?_";\r
\r
/**\r
* matches if one ID properly contains another at a whitespace boundary.\r