/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)\r
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
+ * \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE. See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.\r
*/\r
package jalview.ws;\r
\r
import jalview.bin.Cache;\r
import jalview.datamodel.*;\r
import jalview.gui.*;\r
+import jalview.util.UrlLink;\r
\r
/**\r
* DOCUMENT ME!\r
- *\r
+ * \r
* @author $author$\r
* @version $Revision$\r
*/\r
public class DasSequenceFeatureFetcher\r
{\r
SequenceI[] sequences;\r
+\r
AlignFrame af;\r
+\r
FeatureSettings fsettings;\r
+\r
StringBuffer sbuffer = new StringBuffer();\r
+\r
Vector selectedSources;\r
+\r
boolean cancelled = false;\r
\r
+ private void debug(String mesg)\r
+ {\r
+ debug(mesg, null);\r
+ }\r
+\r
+ private void debug(String mesg, Exception e)\r
+ {\r
+ if (Cache.log != null)\r
+ {\r
+ Cache.log.debug(mesg, e);\r
+ }\r
+ else\r
+ {\r
+ System.err.println(mesg);\r
+ if (e != null)\r
+ {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ }\r
+\r
long startTime;\r
\r
/**\r
- * Creates a new SequenceFeatureFetcher object.\r
- * Uses default\r
- *\r
- * @param align DOCUMENT ME!\r
- * @param ap DOCUMENT ME!\r
+ * Creates a new SequenceFeatureFetcher object. Uses default\r
+ * \r
+ * @param align\r
+ * DOCUMENT ME!\r
+ * @param ap\r
+ * DOCUMENT ME!\r
*/\r
public DasSequenceFeatureFetcher(SequenceI[] sequences,\r
- FeatureSettings fsettings,\r
- Vector selectedSources)\r
+ FeatureSettings fsettings, Vector selectedSources)\r
{\r
- this.selectedSources = selectedSources;\r
- this.sequences = sequences;\r
- this.af = fsettings.af;\r
- this.fsettings = fsettings;\r
+ this(sequences, fsettings, selectedSources, true, true);\r
+ }\r
\r
+ public DasSequenceFeatureFetcher(SequenceI[] oursequences,\r
+ FeatureSettings fsettings, Vector ourselectedSources,\r
+ boolean checkDbrefs, boolean promptFetchDbrefs)\r
+ {\r
+ this.selectedSources = new Vector();\r
+ Enumeration sources = ourselectedSources.elements();\r
+ // filter both sequences and sources to eliminate duplicates\r
+ while (sources.hasMoreElements())\r
+ {\r
+ Object src = sources.nextElement();\r
+ if (!selectedSources.contains(src))\r
+ {\r
+ selectedSources.addElement(src);\r
+ }\r
+ ;\r
+ }\r
+ Vector sqs = new Vector();\r
+ for (int i = 0; i < oursequences.length; i++)\r
+ {\r
+ if (!sqs.contains(oursequences[i]))\r
+ {\r
+ sqs.addElement(oursequences[i]);\r
+ }\r
+ }\r
+ sequences = new SequenceI[sqs.size()];\r
+ for (int i = 0; i < sequences.length; i++)\r
+ {\r
+ sequences[i] = (SequenceI) sqs.elementAt(i);\r
+ }\r
+ if (fsettings != null)\r
+ {\r
+ this.fsettings = fsettings;\r
+ this.af = fsettings.af;\r
+ af.setShowSeqFeatures(true);\r
+ }\r
int uniprotCount = 0;\r
for (int i = 0; i < selectedSources.size(); i++)\r
{\r
DasCoordinateSystem[] coords = source.getCoordinateSystem();\r
for (int c = 0; c < coords.length; c++)\r
{\r
+ // TODO: match UniProt coord system canonically (?) - does\r
+ // UniProt==uniprot==UNIPROT ?\r
if (coords[c].getName().indexOf("UniProt") > -1)\r
{\r
uniprotCount++;\r
{\r
for (int j = 0; j < dbref.length; j++)\r
{\r
- if (dbref[j].getSource()\r
- .equals(jalview.datamodel.DBRefSource.UNIPROT))\r
+ if (dbref[j].getSource().equals(\r
+ jalview.datamodel.DBRefSource.UNIPROT))\r
{\r
refCount++;\r
break;\r
}\r
}\r
\r
- if (refCount < sequences.length && uniprotCount > 0)\r
+ if (checkDbrefs && refCount < sequences.length && uniprotCount > 0)\r
{\r
\r
- int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
- "Do you want Jalview to find\n"\r
- + "Uniprot Accession ids for given sequence names?",\r
- "Find Uniprot Accession Ids",\r
- JOptionPane.YES_NO_OPTION,\r
- JOptionPane.QUESTION_MESSAGE);\r
+ int reply = JOptionPane.YES_OPTION;\r
+ if (promptFetchDbrefs)\r
+ {\r
+ reply = JOptionPane\r
+ .showInternalConfirmDialog(\r
+ Desktop.desktop,\r
+ "Do you want Jalview to find\n"\r
+ + "Uniprot Accession ids for given sequence names?",\r
+ "Find Uniprot Accession Ids",\r
+ JOptionPane.YES_NO_OPTION,\r
+ JOptionPane.QUESTION_MESSAGE);\r
+ }\r
\r
if (reply == JOptionPane.YES_OPTION)\r
{\r
else\r
{\r
startFetching();\r
- }\r
+ }\r
}\r
else\r
{\r
startFetching();\r
}\r
\r
- }\r
+ }\r
\r
- class FetchDBRefs\r
- implements Runnable\r
+ class FetchDBRefs implements Runnable\r
{\r
public void run()\r
{\r
}\r
}\r
\r
+ /**\r
+ * Spawns a number of dasobert Fetcher threads to add features to sequences in\r
+ * the dataset\r
+ */\r
+ void startFetching()\r
+ {\r
+ cancelled = false;\r
+ startTime = System.currentTimeMillis();\r
+ if (af != null)\r
+ {\r
+ af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
+ }\r
\r
- /**\r
- * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset\r
- */\r
- void startFetching()\r
- {\r
- cancelled = false;\r
- startTime = System.currentTimeMillis();\r
- af.setProgressBar("Fetching DAS Sequence Features", startTime);\r
-\r
- DasSource[] sources = new jalview.gui.DasSourceBrowser().getDASSource();\r
-\r
- if (selectedSources == null || selectedSources.size() == 0)\r
- {\r
- String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
- "uniprot");\r
- StringTokenizer st = new StringTokenizer(active, "\t");\r
- Vector selectedSources = new Vector();\r
- String token;\r
- while (st.hasMoreTokens())\r
- {\r
- token = st.nextToken();\r
- for (int i = 0; i < sources.length; i++)\r
- {\r
- if (sources[i].getNickname().equals(token))\r
- {\r
- selectedSources.addElement(sources[i]);\r
- break;\r
- }\r
- }\r
- }\r
- }\r
-\r
- if (selectedSources == null || selectedSources.size() == 0)\r
- {\r
- System.out.println("No DAS Sources active");\r
- af.setProgressBar("No DAS Sources Active", startTime);\r
- cancelled = true;\r
- fsettings.noDasSourceActive();\r
- return;\r
- }\r
-\r
- sourcesRemaining = selectedSources.size();\r
- //Now sending requests one at a time to each server\r
- for (int sourceIndex = 0;\r
- sourceIndex < selectedSources.size()\r
- && !cancelled;\r
- sourceIndex++)\r
- {\r
- DasSource dasSource = (DasSource) selectedSources.elementAt(\r
- sourceIndex);\r
-\r
- nextSequence(dasSource, sequences[0]);\r
- }\r
- }\r
-\r
- public void cancel()\r
- {\r
- af.setProgressBar("DAS Feature Fetching Cancelled", startTime);\r
- cancelled = true;\r
- }\r
-\r
- int sourcesRemaining=0;\r
- void responseComplete(DasSource dasSource, SequenceI seq)\r
- {\r
- if (seq != null)\r
- {\r
- for (int seqIndex = 0;\r
- seqIndex < sequences.length-1\r
- && !cancelled; seqIndex++)\r
- {\r
- if (sequences[seqIndex] == seq)\r
- {\r
- nextSequence(dasSource, sequences[++seqIndex]);\r
- return;\r
- }\r
- }\r
- }\r
-\r
- sourcesRemaining --;\r
-\r
- if(sourcesRemaining==0)\r
- {\r
- af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
-\r
- if(af.featureSettings!=null)\r
+ if (selectedSources == null || selectedSources.size() == 0)\r
+ {\r
+ try\r
+ {\r
+ DasSource[] sources = new jalview.gui.DasSourceBrowser()\r
+ .getDASSource();\r
+\r
+ String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE",\r
+ "uniprot");\r
+ StringTokenizer st = new StringTokenizer(active, "\t");\r
+ selectedSources = new Vector();\r
+ String token;\r
+ while (st.hasMoreTokens())\r
+ {\r
+ token = st.nextToken();\r
+ for (int i = 0; i < sources.length; i++)\r
+ {\r
+ if (sources[i].getNickname().equals(token))\r
+ {\r
+ selectedSources.addElement(sources[i]);\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ } catch (Exception ex)\r
{\r
- af.featureSettings.setTableData();\r
+ debug("Exception whilst setting default feature sources from registry and local preferences.",\r
+ ex);\r
}\r
+ }\r
+\r
+ if (selectedSources == null || selectedSources.size() == 0)\r
+ {\r
+ System.out.println("No DAS Sources active");\r
+ cancelled = true;\r
+ setGuiNoDassourceActive();\r
+ return;\r
+ }\r
\r
- fsettings.complete();\r
- }\r
+ sourcesRemaining = selectedSources.size();\r
+ // Now sending requests one at a time to each server\r
+ for (int sourceIndex = 0; sourceIndex < selectedSources.size()\r
+ && !cancelled; sourceIndex++)\r
+ {\r
+ DasSource dasSource = (DasSource) selectedSources\r
+ .elementAt(sourceIndex);\r
\r
- }\r
+ nextSequence(dasSource, sequences[0]);\r
+ }\r
+ }\r
\r
- void featuresAdded(SequenceI seq)\r
- {\r
- af.getFeatureRenderer().featuresAdded();\r
+ private void setGuiNoDassourceActive()\r
+ {\r
\r
- int start = af.getViewport().getStartSeq();\r
- int end = af.getViewport().getEndSeq();\r
- int index;\r
- for(index=start; index<end; index++)\r
- {\r
- if (seq ==\r
- af.getViewport().getAlignment().getSequenceAt(index).getDatasetSequence())\r
+ if (af != null)\r
+ {\r
+ af.setProgressBar("No DAS Sources Active", startTime);\r
+ }\r
+ if (getFeatSettings() != null)\r
+ {\r
+ fsettings.noDasSourceActive();\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Update our fsettings dialog reference if we didn't have one when we were\r
+ * first initialised.\r
+ * \r
+ * @return fsettings\r
+ */\r
+ private FeatureSettings getFeatSettings()\r
+ {\r
+ if (fsettings == null)\r
+ {\r
+ if (af != null)\r
{\r
- af.alignPanel.paintAlignment(true);\r
- break;\r
- }\r
- }\r
+ fsettings = af.featureSettings;\r
+ }\r
+ }\r
+ return fsettings;\r
+ }\r
+\r
+ public void cancel()\r
+ {\r
+ if (af != null)\r
+ {\r
+ af.setProgressBar("DAS Feature Fetching Cancelled", startTime);\r
+ }\r
+ cancelled = true;\r
+ }\r
+\r
+ int sourcesRemaining = 0;\r
+\r
+ void responseComplete(DasSource dasSource, SequenceI seq)\r
+ {\r
+ if (seq != null)\r
+ {\r
+ for (int seqIndex = 0; seqIndex < sequences.length - 1 && !cancelled; seqIndex++)\r
+ {\r
+ if (sequences[seqIndex] == seq)\r
+ {\r
+ nextSequence(dasSource, sequences[++seqIndex]);\r
+ return;\r
+ }\r
+ }\r
+ }\r
+\r
+ sourcesRemaining--;\r
+\r
+ if (sourcesRemaining == 0)\r
+ {\r
+ System.err.println("Fetching Complete.");\r
+ setGuiFetchComplete();\r
+ }\r
+\r
+ }\r
+\r
+ private void setGuiFetchComplete()\r
+ {\r
+\r
+ if (!cancelled && af != null)\r
+ {\r
+ // only update the progress bar if we've completed the fetch normally\r
+ af.setProgressBar("DAS Feature Fetching Complete", startTime);\r
+ }\r
+\r
+ if (af != null && af.featureSettings != null)\r
+ {\r
+ af.featureSettings.setTableData();\r
+ }\r
+\r
+ if (getFeatSettings() != null)\r
+ {\r
+ fsettings.complete();\r
+ }\r
}\r
\r
+ void featuresAdded(SequenceI seq)\r
+ {\r
+ if (af == null)\r
+ {\r
+ // no gui to update with features.\r
+ return;\r
+ }\r
+ af.getFeatureRenderer().featuresAdded();\r
+\r
+ int start = af.getViewport().getStartSeq();\r
+ int end = af.getViewport().getEndSeq();\r
+ int index;\r
+ for (index = start; index < end; index++)\r
+ {\r
+ if (seq == af.getViewport().getAlignment().getSequenceAt(index)\r
+ .getDatasetSequence())\r
+ {\r
+ af.alignPanel.paintAlignment(true);\r
+ break;\r
+ }\r
+ }\r
+ }\r
\r
void nextSequence(DasSource dasSource, SequenceI seq)\r
{\r
if (cancelled)\r
return;\r
- DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),\r
- new String[]\r
- {\r
- // jalview.datamodel.DBRefSource.PDB,\r
- jalview.datamodel.DBRefSource.UNIPROT,\r
- // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord sys sources\r
- });\r
-// TODO: minimal list of DAS queries to make by querying with untyped ID if distinct from any typed IDs\r
+ DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(\r
+ seq.getDBRef(), new String[]\r
+ {\r
+ // jalview.datamodel.DBRefSource.PDB,\r
+ jalview.datamodel.DBRefSource.UNIPROT,\r
+ // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord\r
+ // sys sources\r
+ });\r
+ // TODO: minimal list of DAS queries to make by querying with untyped ID if\r
+ // distinct from any typed IDs\r
+\r
+ boolean dasCoordSysFound = false;\r
\r
- boolean dasCoordSysFound = false;\r
+ if (uprefs != null)\r
+ {\r
+ // do any of these ids match the source's coordinate system ?\r
+ for (int j = 0; !dasCoordSysFound && j < uprefs.length; j++)\r
+ {\r
+ DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
\r
- if (uprefs != null)\r
+ for (int csIndex = 0; csIndex < cs.length && !dasCoordSysFound; csIndex++)\r
{\r
- // do any of these ids match the source's coordinate system ?\r
- for (int j = 0; !dasCoordSysFound && j < uprefs.length; j++)\r
+ if (cs.length > 0\r
+ && jalview.util.DBRefUtils.isDasCoordinateSystem(\r
+ cs[csIndex].getName(), uprefs[j]))\r
{\r
- DasCoordinateSystem cs[] = dasSource.getCoordinateSystem();\r
-\r
- for(int csIndex=0; csIndex<cs.length && !dasCoordSysFound; csIndex++)\r
- {\r
- if (cs.length > 0 && jalview.util.DBRefUtils\r
- .isDasCoordinateSystem(cs[csIndex].getName(), uprefs[j]))\r
- {\r
- Cache.log.debug("Launched fetcher for coordinate system " +\r
- cs[0].getName());\r
- // Will have to pass any mapping information to the fetcher\r
- //- the start/end for the DBRefEntry may not be the same as the sequence's start/end\r
-\r
- System.out.println(seq.getName() + " " + (seq.getDatasetSequence() == null)\r
- + " " + dasSource.getUrl());\r
-\r
- dasCoordSysFound = true; // break's out of the loop\r
- createFeatureFetcher(seq,\r
- dasSource,\r
- uprefs[j]);\r
- }\r
- else\r
- System.out.println("IGNORE " + cs[csIndex].getName());\r
- }\r
+ debug("Launched fetcher for coordinate system "\r
+ + cs[0].getName());\r
+ // Will have to pass any mapping information to the fetcher\r
+ // - the start/end for the DBRefEntry may not be the same as the\r
+ // sequence's start/end\r
+\r
+ System.out.println(seq.getName() + " "\r
+ + (seq.getDatasetSequence() == null) + " "\r
+ + dasSource.getUrl());\r
+\r
+ dasCoordSysFound = true; // break's out of the loop\r
+ createFeatureFetcher(seq, dasSource, uprefs[j]);\r
}\r
+ else\r
+ System.out.println("IGNORE " + cs[csIndex].getName());\r
}\r
+ }\r
+ }\r
\r
- if(!dasCoordSysFound)\r
+ if (!dasCoordSysFound)\r
+ {\r
+ String id = null;\r
+ // try and use the name as the sequence id\r
+ if (seq.getName().indexOf("|") > -1)\r
+ {\r
+ id = seq.getName().substring(seq.getName().lastIndexOf("|") + 1);\r
+ if (id.trim().length() < 4)\r
{\r
- String id = null;\r
- // try and use the name as the sequence id\r
- if (seq.getName().indexOf("|") > -1)\r
+ // hack - we regard a significant ID as being at least 4\r
+ // non-whitespace characters\r
+ id = seq.getName().substring(0, seq.getName().lastIndexOf("|"));\r
+ if (id.indexOf("|") > -1)\r
{\r
- id = seq.getName().substring(\r
- seq.getName().lastIndexOf("|") + 1);\r
- }\r
- else\r
- {\r
- id = seq.getName();\r
- }\r
- if (id != null)\r
- {\r
- // Should try to call a general feature fetcher that\r
- // queries many sources with name to discover applicable ID references\r
- createFeatureFetcher(seq,\r
- dasSource,\r
- id);\r
+ id = id.substring(id.lastIndexOf("|") + 1);\r
}\r
}\r
+ }\r
+ else\r
+ {\r
+ id = seq.getName();\r
+ }\r
+ if (id != null)\r
+ {\r
+ // Should try to call a general feature fetcher that\r
+ // queries many sources with name to discover applicable ID references\r
+ createFeatureFetcher(seq, dasSource, id);\r
+ }\r
+ }\r
\r
- }\r
-\r
+ }\r
\r
-/**\r
- * fetch and add das features to a sequence using the given source URL and compatible DbRef id.\r
- * new features are mapped using the DbRef mapping to the local coordinate system.\r
- * @param seq\r
- * @param SourceUrl\r
- * @param dbref\r
- */\r
- protected void createFeatureFetcher(final SequenceI seq, final DasSource dasSource,\r
- final DBRefEntry dbref) {\r
+ /**\r
+ * fetch and add das features to a sequence using the given source URL and\r
+ * compatible DbRef id. new features are mapped using the DbRef mapping to the\r
+ * local coordinate system.\r
+ * \r
+ * @param seq\r
+ * @param SourceUrl\r
+ * @param dbref\r
+ */\r
+ protected void createFeatureFetcher(final SequenceI seq,\r
+ final DasSource dasSource, final DBRefEntry dbref)\r
+ {\r
\r
- //////////////\r
- /// fetch DAS features\r
+ // ////////////\r
+ // / fetch DAS features\r
final Das1Source source = new Das1Source();\r
source.setUrl(dasSource.getUrl());\r
source.setNickname(dasSource.getNickname());\r
- if (dbref==null || dbref.getAccessionId()==null || dbref.getAccessionId().length()<1)\r
+ if (dbref == null || dbref.getAccessionId() == null\r
+ || dbref.getAccessionId().length() < 1)\r
{\r
+ responseComplete(dasSource, seq); // reduce thread count anyhow\r
return;\r
}\r
- Cache.log.debug("new Das Feature Fetcher for " + dbref.getSource()+":"+dbref.getAccessionId() + " querying " +\r
- dasSource.getUrl());\r
+ debug("new Das Feature Fetcher for " + dbref.getSource() + ":"\r
+ + dbref.getAccessionId() + " querying " + dasSource.getUrl());\r
FeatureThread fetcher = new FeatureThread(dbref.getAccessionId()\r
- // + ":" + start + "," + end,\r
- , source);\r
+ // + ":" + start + "," + end,\r
+ , source);\r
\r
- fetcher.addFeatureListener(new FeatureListener()\r
+ fetcher.addFeatureListener(new FeatureListener()\r
+ {\r
+ public void comeBackLater(FeatureEvent e)\r
{\r
- public void comeBackLater(FeatureEvent e)\r
- {\r
- responseComplete(dasSource, seq);\r
- Cache.log.debug("das source " + e.getDasSource().getNickname() +\r
- " asked us to come back in " + e.getComeBackLater() +\r
- " secs.");\r
- }\r
+ responseComplete(dasSource, seq);\r
+ debug("das source " + e.getSource().getNickname()\r
+ + " asked us to come back in " + e.getComeBackLater()\r
+ + " secs.");\r
+ }\r
\r
- public void newFeatures(FeatureEvent e)\r
- {\r
+ public void newFeatures(FeatureEvent e)\r
+ {\r
\r
- Das1Source ds = e.getDasSource();\r
+ Das1Source ds = e.getSource();\r
\r
- Map[] features = e.getFeatures();\r
- // add features to sequence\r
- Cache.log.debug("das source " + ds.getUrl() + " returned " +\r
- features.length + " features");\r
+ Map[] features = e.getFeatures();\r
+ // add features to sequence\r
+ debug("das source " + ds.getUrl() + " returned " + features.length\r
+ + " features");\r
\r
- if (features.length > 0)\r
+ if (features.length > 0)\r
+ {\r
+ for (int i = 0; i < features.length; i++)\r
{\r
- for (int i = 0; i < features.length; i++)\r
+ // standard DAS feature-> jalview sequence feature transformation\r
+ SequenceFeature f = newSequenceFeature(features[i],\r
+ source.getNickname());\r
+ if (!parseSeqFeature(seq, f, features[i], source))\r
{\r
- SequenceFeature f = newSequenceFeature(features[i],\r
- source.getNickname());\r
- if (dbref.getMap()!=null && f.getBegin()>0 && f.getEnd()>0) {\r
- Cache.log.debug("mapping from "+f.getBegin()+" - "+f.getEnd());\r
- SequenceFeature vf[]=null;\r
- \r
- try {\r
+ if (dbref.getMap() != null && f.getBegin() > 0\r
+ && f.getEnd() > 0)\r
+ {\r
+ debug("mapping from " + f.getBegin() + " - " + f.getEnd());\r
+ SequenceFeature vf[] = null;\r
+\r
+ try\r
+ {\r
vf = dbref.getMap().locateFeature(f);\r
- }\r
- catch (Exception ex)\r
+ } catch (Exception ex)\r
{\r
- Cache.log.info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to help@jalview.org.");\r
- Cache.log.info("Mapping feature from "+f.getBegin()+" to "+f.getEnd()+" in dbref "+dbref.getAccessionId()+" in "+dbref.getSource());\r
- Cache.log.info("using das Source "+ds.getUrl());\r
+ Cache.log\r
+ .info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to jalview-discuss@jalview.org.");\r
+ Cache.log.info("Mapping feature from " + f.getBegin()\r
+ + " to " + f.getEnd() + " in dbref "\r
+ + dbref.getAccessionId() + " in "\r
+ + dbref.getSource());\r
+ Cache.log.info("using das Source " + ds.getUrl());\r
Cache.log.info("Exception", ex);\r
}\r
- \r
- if (vf!=null) {\r
- for (int v=0;v<vf.length;v++)\r
+\r
+ if (vf != null)\r
+ {\r
+ for (int v = 0; v < vf.length; v++)\r
{\r
- Cache.log.debug("mapping to "+v+": "+vf[v].getBegin()+" - "+vf[v].getEnd());\r
+ debug("mapping to " + v + ": " + vf[v].getBegin()\r
+ + " - " + vf[v].getEnd());\r
seq.addSequenceFeature(vf[v]);\r
}\r
}\r
- } else {\r
+ }\r
+ else\r
+ {\r
seq.addSequenceFeature(f);\r
}\r
}\r
-\r
- featuresAdded(seq);\r
- }\r
- else\r
- {\r
- // System.out.println("No features found for " + seq.getName()\r
- // + " from: " + e.getDasSource().getNickname());\r
}\r
- responseComplete(dasSource, seq);\r
-\r
+ featuresAdded(seq);\r
}\r
+ else\r
+ {\r
+ // System.out.println("No features found for " + seq.getName()\r
+ // + " from: " + e.getDasSource().getNickname());\r
+ }\r
+ responseComplete(dasSource, seq);\r
+\r
}\r
+ }\r
\r
- );\r
+ );\r
+\r
+ fetcher.start();\r
+ }\r
\r
- fetcher.start();\r
- }\r
protected void createFeatureFetcher(final SequenceI seq,\r
- final DasSource dasSource,\r
- String id)\r
+ final DasSource dasSource, String id)\r
{\r
- //////////////\r
- /// fetch DAS features\r
+ // ////////////\r
+ // / fetch DAS features\r
final Das1Source source = new Das1Source();\r
source.setUrl(dasSource.getUrl());\r
source.setNickname(dasSource.getNickname());\r
\r
- Cache.log.debug("new Das Feature Fetcher for " + id + " querying " +\r
- dasSource.getUrl());\r
-\r
+ if (id != null)\r
+ {\r
+ id = id.trim();\r
+ }\r
if (id != null && id.length() > 0)\r
{\r
+ debug("new Das Feature Fetcher for " + id + " querying "\r
+ + dasSource.getUrl());\r
FeatureThread fetcher = new FeatureThread(id\r
- // + ":" + start + "," + end,\r
- , source);\r
+ // + ":" + start + "," + end,\r
+ , source);\r
\r
fetcher.addFeatureListener(new FeatureListener()\r
{\r
public void comeBackLater(FeatureEvent e)\r
{\r
responseComplete(dasSource, seq);\r
- Cache.log.debug("das source " + e.getDasSource().getNickname() +\r
- " asked us to come back in " + e.getComeBackLater() +\r
- " secs.");\r
+ debug("das source " + e.getSource().getNickname()\r
+ + " asked us to come back in " + e.getComeBackLater()\r
+ + " secs.");\r
}\r
\r
public void newFeatures(FeatureEvent e)\r
{\r
\r
- Das1Source ds = e.getDasSource();\r
+ Das1Source ds = e.getSource();\r
\r
Map[] features = e.getFeatures();\r
// add features to sequence\r
- Cache.log.debug("das source " + ds.getUrl() + " returned " +\r
- features.length + " features");\r
+ debug("das source " + ds.getUrl() + " returned "\r
+ + features.length + " features");\r
\r
if (features.length > 0)\r
{\r
for (int i = 0; i < features.length; i++)\r
{\r
+ // standard DAS feature-> jalview sequence feature transformation\r
SequenceFeature f = newSequenceFeature(features[i],\r
- source.getNickname());\r
-\r
- seq.addSequenceFeature(f);\r
+ source.getNickname());\r
+ if (!parseSeqFeature(seq, f, features[i], source))\r
+ {\r
+ // just add as a simple sequence feature\r
+ seq.addSequenceFeature(f);\r
+ }\r
}\r
\r
featuresAdded(seq);\r
}\r
else\r
{\r
- // System.out.println("No features found for " + seq.getName()\r
- // + " from: " + e.getDasSource().getNickname());\r
+ // System.out.println("No features found for " + seq.getName()\r
+ // + " from: " + e.getDasSource().getNickname());\r
}\r
responseComplete(dasSource, seq);\r
\r
\r
fetcher.start();\r
}\r
+ else\r
+ {\r
+ // invalid fetch - indicate it is finished.\r
+ debug("Skipping empty ID for querying " + dasSource.getUrl());\r
+ responseComplete(dasSource, seq);\r
+ }\r
+ }\r
+\r
+ /**\r
+ * examine the given sequence feature to determine if it should actually be\r
+ * turned into sequence annotation or database cross references rather than a\r
+ * simple sequence feature.\r
+ * \r
+ * @param seq\r
+ * the sequence to annotate\r
+ * @param f\r
+ * the jalview sequence feature generated from the DAS feature\r
+ * @param map\r
+ * the sequence feature attributes\r
+ * @param source\r
+ * the source that emitted the feature\r
+ * @return true if feature was consumed as another kind of annotation.\r
+ */\r
+ protected boolean parseSeqFeature(SequenceI seq, SequenceFeature f,\r
+ Map map, Das1Source source)\r
+ {\r
+ SequenceI mseq = seq;\r
+ while (seq.getDatasetSequence() != null)\r
+ {\r
+ seq = seq.getDatasetSequence();\r
+ }\r
+ if (f.getType() != null)\r
+ {\r
+ String type = f.getType();\r
+ if (type.equalsIgnoreCase("protein_name"))\r
+ {\r
+ // parse name onto the alignment sequence or the dataset sequence.\r
+ if (seq.getDescription() == null\r
+ || seq.getDescription().trim().length() == 0)\r
+ {\r
+ // could look at the note series to pick out the first long name, for\r
+ // the moment just use the whole description string\r
+ seq.setDescription(f.getDescription());\r
+ }\r
+ if (mseq.getDescription() == null\r
+ || mseq.getDescription().trim().length() == 0)\r
+ {\r
+ // could look at the note series to pick out the first long name, for\r
+ // the moment just use the whole description string\r
+ mseq.setDescription(f.getDescription());\r
+ }\r
+ return true;\r
+ }\r
+ // check if source has biosapiens or other sequence ontology label\r
+ if (type.equalsIgnoreCase("DBXREF") || type.equalsIgnoreCase("DBREF"))\r
+ {\r
+ // try to parse the accession out\r
+\r
+ DBRefEntry dbr = new DBRefEntry();\r
+ dbr.setVersion(source.getNickname());\r
+ StringTokenizer st = new StringTokenizer(f.getDescription(), ":");\r
+ if (st.hasMoreTokens())\r
+ {\r
+ dbr.setSource(st.nextToken());\r
+ }\r
+ if (st.hasMoreTokens())\r
+ {\r
+ dbr.setAccessionId(st.nextToken());\r
+ }\r
+ seq.addDBRef(dbr);\r
+\r
+ if (f.links != null && f.links.size() > 0)\r
+ {\r
+ // feature is also appended to enable links to be seen.\r
+ // TODO: consider extending dbrefs to have their own links ?\r
+ // TODO: new feature: extract dbref links from DAS servers and add the\r
+ // URL pattern to the list of DB name associated links in the user's\r
+ // preferences ?\r
+ // for the moment - just fix up the existing feature so it displays\r
+ // correctly.\r
+ // f.setType(dbr.getSource());\r
+ // f.setDescription();\r
+ f.setValue("linkonly", Boolean.TRUE);\r
+ // f.setDescription("");\r
+ Vector newlinks = new Vector();\r
+ Enumeration it = f.links.elements();\r
+ while (it.hasMoreElements())\r
+ {\r
+ String elm;\r
+ UrlLink urllink = new UrlLink(elm = (String) it.nextElement());\r
+ if (urllink.isValid())\r
+ {\r
+ urllink.setLabel(f.getDescription());\r
+ newlinks.addElement(urllink.toString());\r
+ }\r
+ else\r
+ {\r
+ // couldn't parse the link properly. Keep it anyway - just in\r
+ // case.\r
+ debug("couldn't parse link string - " + elm);\r
+ newlinks.addElement(elm);\r
+ }\r
+ }\r
+ f.links = newlinks;\r
+ seq.addSequenceFeature(f);\r
+ }\r
+ return true;\r
+ }\r
+ }\r
+ return false;\r
}\r
\r
/**\r
* creates a jalview sequence feature from a das feature document\r
+ * \r
* @param dasfeature\r
* @return sequence feature object created using dasfeature information\r
*/\r
SequenceFeature newSequenceFeature(Map dasfeature, String nickname)\r
{\r
- if (dasfeature==null)\r
+ if (dasfeature == null)\r
{\r
return null;\r
}\r
try\r
{\r
/**\r
- * Different qNames for a DAS Feature - are string keys to the HashMaps in features\r
- * "METHOD") ||\r
- qName.equals("TYPE") ||\r
- qName.equals("START") ||\r
- qName.equals("END") ||\r
- qName.equals("NOTE") ||\r
- qName.equals("LINK") ||\r
- qName.equals("SCORE")\r
+ * Different qNames for a DAS Feature - are string keys to the HashMaps in\r
+ * features "METHOD") || qName.equals("TYPE") || qName.equals("START") ||\r
+ * qName.equals("END") || qName.equals("NOTE") || qName.equals("LINK") ||\r
+ * qName.equals("SCORE")\r
*/\r
String desc = new String();\r
if (dasfeature.containsKey("NOTE"))\r
try\r
{\r
start = Integer.parseInt(dasfeature.get("START").toString());\r
+ } catch (Exception ex)\r
+ {\r
}\r
- catch (Exception ex)\r
- {}\r
try\r
{\r
end = Integer.parseInt(dasfeature.get("END").toString());\r
+ } catch (Exception ex)\r
+ {\r
}\r
- catch (Exception ex)\r
- {}\r
try\r
{\r
- score = Integer.parseInt(dasfeature.get("SCORE").toString());\r
+ Object scr = dasfeature.get("SCORE");\r
+ if (scr != null)\r
+ {\r
+ score = (float) Double.parseDouble(scr.toString());\r
+\r
+ }\r
+ } catch (Exception ex)\r
+ {\r
}\r
- catch (Exception ex)\r
- {}\r
\r
SequenceFeature f = new SequenceFeature(\r
- (String) dasfeature.get("TYPE"),\r
- desc,\r
- start,\r
- end,\r
- score,\r
- nickname);\r
+ (String) dasfeature.get("TYPE"), desc, start, end, score,\r
+ nickname);\r
\r
if (dasfeature.containsKey("LINK"))\r
{\r
- f.addLink(f.getType() + " " + f.begin + "_" + f.end\r
- + "|" + dasfeature.get("LINK"));\r
+ // Do not put feature extent in link text for non-positional features\r
+ if (f.begin == 0 && f.end == 0)\r
+ {\r
+ f.addLink(f.getType() + "|" + dasfeature.get("LINK"));\r
+ }\r
+ else\r
+ {\r
+ f.addLink(f.getType() + " " + f.begin + "_" + f.end + "|"\r
+ + dasfeature.get("LINK"));\r
+ }\r
}\r
\r
return f;\r
- }\r
- catch (Exception e)\r
+ } catch (Exception e)\r
{\r
System.out.println("ERRR " + e);\r
e.printStackTrace();\r
System.out.println("############");\r
- Cache.log.debug("Failed to parse " + dasfeature.toString(), e);\r
+ debug("Failed to parse " + dasfeature.toString(), e);\r
return null;\r
}\r
}\r
\r
+ /**\r
+ * query the default DAS Source Registry for sources. Uses value of jalview\r
+ * property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that\r
+ * doesn't exist.\r
+ * \r
+ * @return list of sources\r
+ */\r
public static DasSource[] getDASSources()\r
{\r
- DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
\r
String registryURL = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL",\r
- DasSourceBrowser.DEFAULT_REGISTRY\r
- );\r
+ DasSourceBrowser.DEFAULT_REGISTRY);\r
+ return getDASSources(registryURL);\r
+ }\r
+\r
+ /**\r
+ * query the given URL for DasSources.\r
+ * \r
+ * @param registryURL\r
+ * return sources from registryURL\r
+ */\r
+ public static DasSource[] getDASSources(String registryURL)\r
+ {\r
+ DasSourceReaderImpl reader = new DasSourceReaderImpl();\r
\r
try\r
{\r
}\r
else if (ds instanceof Das1Source)\r
{\r
- das1sources.add( (Das1Source) ds);\r
+ das1sources.add((Das1Source) ds);\r
}\r
}\r
\r
- return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources.size()]);\r
- }\r
- catch (Exception ex)\r
+ return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources\r
+ .size()]);\r
+ } catch (Exception ex)\r
{\r
+ System.err.println("Failed to contact DAS1 registry at "\r
+ + registryURL);\r
ex.printStackTrace();\r
return null;\r
}\r
}\r
\r
}\r
-\r