From feaa53e0e6dea15a236b99097347df52c21db896 Mon Sep 17 00:00:00 2001 From: jprocter Date: Mon, 12 Nov 2007 16:33:58 +0000 Subject: [PATCH] added mechanism to initiate DAS feature fetching programmatically from jalview.bin.Jalview. Various thread safe gui update issues and javadoc. --- src/jalview/gui/FeatureSettings.java | 88 +++- src/jalview/ws/DasSequenceFeatureFetcher.java | 648 ++++++++++++++----------- 2 files changed, 444 insertions(+), 292 deletions(-) diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index de61be3..ea492e2 100755 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -752,23 +752,32 @@ public class FeatureSettings fetchDAS.setEnabled(false); cancelDAS.setEnabled(true); Vector selectedSources = dassourceBrowser.getSelectedSources(); - + doDasFeatureFetch(selectedSources, true, true); + } + /** + * get the features from selectedSources for all or the current selection + * @param selectedSources + * @param checkDbRefs + * @param promptFetchDbRefs + */ + private void doDasFeatureFetch(Vector selectedSources, boolean checkDbRefs, boolean promptFetchDbRefs) + { SequenceI[] dataset, seqs; int iSize; - - if (af.getViewport().getSelectionGroup() != null - && af.getViewport().getSelectionGroup().getSize() > 0) + AlignViewport vp = af.getViewport(); + if (vp.getSelectionGroup() != null + && vp.getSelectionGroup().getSize() > 0) { - iSize = af.getViewport().getSelectionGroup().getSize(); + iSize = vp.getSelectionGroup().getSize(); dataset = new SequenceI[iSize]; - seqs = af.getViewport().getSelectionGroup(). + seqs = vp.getSelectionGroup(). getSequencesInOrder( - af.getViewport().getAlignment()); + vp.getAlignment()); } else { - iSize = af.getViewport().getAlignment().getHeight(); - seqs = af.getViewport().getAlignment().getSequencesArray(); + iSize = vp.getAlignment().getHeight(); + seqs = vp.getAlignment().getSequencesArray(); } dataset = new SequenceI[iSize]; @@ -777,15 +786,64 @@ public class FeatureSettings dataset[i] = seqs[i].getDatasetSequence(); } + cancelDAS.setEnabled(true); dasFeatureFetcher = new jalview.ws.DasSequenceFeatureFetcher( dataset, this, - selectedSources); - cancelDAS.setEnabled(true); + selectedSources, checkDbRefs, promptFetchDbRefs); af.getViewport().setShowSequenceFeatures(true); af.showSeqFeatures.setSelected(true); } + /** + * properly initialise DAS fetcher and then initiate a new thread to fetch features from the named sources (rather than any turned on by default) + * @param sources + */ + public void fetchDasFeatures(Vector sources) + { + Thread thr = new Thread(new Runnable() { + public void run() { + // this actually initialises the das source list + dassourceBrowser.paintComponent(null); // yuk + } + }); + thr.start(); + while (dassourceBrowser.loadingDasSources || dassourceBrowser.dasSources==null) + { + try { Thread.sleep(10); } catch (Exception e) {}; + } + Vector resolved = new Vector(); + if (sources!=null) + { + for (int i=0;i0) + { + final Vector dassources = resolved; + SwingUtilities.invokeLater(new Runnable() { + + public void run() + { + fetchDAS.setEnabled(false); + cancelDAS.setEnabled(true); + doDasFeatureFetch(dassources, true, false); + + }}); + } + } public void saveDAS_actionPerformed(ActionEvent e) { @@ -800,12 +858,16 @@ public class FeatureSettings public void cancelDAS_actionPerformed(ActionEvent e) { - dasFeatureFetcher.cancel(); + if (dasFeatureFetcher!=null) + { + dasFeatureFetcher.cancel(); + } fetchDAS.setEnabled(true); cancelDAS.setEnabled(false); } public void noDasSourceActive() { + complete(); JOptionPane.showInternalConfirmDialog(Desktop.desktop, "No das sources were selected.\n" + "Please select some sources and\n" @@ -813,7 +875,6 @@ public class FeatureSettings "No Sources Selected", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE); - complete(); } ///////////////////////////////////////////////////////////////////////// @@ -929,7 +990,6 @@ public class FeatureSettings return this; } } - } class ColorEditor diff --git a/src/jalview/ws/DasSequenceFeatureFetcher.java b/src/jalview/ws/DasSequenceFeatureFetcher.java index 2d4e73f..1e7ea06 100644 --- a/src/jalview/ws/DasSequenceFeatureFetcher.java +++ b/src/jalview/ws/DasSequenceFeatureFetcher.java @@ -41,10 +41,15 @@ import jalview.gui.*; public class DasSequenceFeatureFetcher { SequenceI[] sequences; + AlignFrame af; + FeatureSettings fsettings; + StringBuffer sbuffer = new StringBuffer(); + Vector selectedSources; + boolean cancelled = false; long startTime; @@ -57,14 +62,21 @@ public class DasSequenceFeatureFetcher * @param ap DOCUMENT ME! */ public DasSequenceFeatureFetcher(SequenceI[] sequences, - FeatureSettings fsettings, - Vector selectedSources) + FeatureSettings fsettings, Vector selectedSources) + { + this(sequences, fsettings, selectedSources, true, true); + } + public DasSequenceFeatureFetcher(SequenceI[] sequences, + FeatureSettings fsettings, Vector selectedSources, boolean checkDbrefs, boolean promptFetchDbrefs) { this.selectedSources = selectedSources; this.sequences = sequences; - this.af = fsettings.af; - this.fsettings = fsettings; - + if (fsettings!=null) + { + this.fsettings = fsettings; + this.af = fsettings.af; + af.getViewport().setShowSequenceFeatures(true); + } int uniprotCount = 0; for (int i = 0; i < selectedSources.size(); i++) { @@ -88,8 +100,8 @@ public class DasSequenceFeatureFetcher { for (int j = 0; j < dbref.length; j++) { - if (dbref[j].getSource() - .equals(jalview.datamodel.DBRefSource.UNIPROT)) + if (dbref[j].getSource().equals( + jalview.datamodel.DBRefSource.UNIPROT)) { refCount++; break; @@ -98,15 +110,19 @@ public class DasSequenceFeatureFetcher } } - if (refCount < sequences.length && uniprotCount > 0) + if (checkDbrefs && refCount < sequences.length && uniprotCount > 0) { - int reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, - "Do you want Jalview to find\n" - + "Uniprot Accession ids for given sequence names?", - "Find Uniprot Accession Ids", - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE); + int reply = JOptionPane.YES_OPTION; + if (promptFetchDbrefs) + { + reply = JOptionPane.showInternalConfirmDialog(Desktop.desktop, + "Do you want Jalview to find\n" + + "Uniprot Accession ids for given sequence names?", + "Find Uniprot Accession Ids", JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + } + if (reply == JOptionPane.YES_OPTION) { @@ -116,17 +132,16 @@ public class DasSequenceFeatureFetcher else { startFetching(); - } + } } else { startFetching(); } - } + } - class FetchDBRefs - implements Runnable + class FetchDBRefs implements Runnable { public void run() { @@ -135,313 +150,380 @@ public class DasSequenceFeatureFetcher } } + /** + * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset + */ + void startFetching() + { + cancelled = false; + startTime = System.currentTimeMillis(); + af.setProgressBar("Fetching DAS Sequence Features", startTime); - /** - * Spawns a number of dasobert Fetcher threads to add features to sequences in the dataset - */ - void startFetching() - { - cancelled = false; - startTime = System.currentTimeMillis(); - af.setProgressBar("Fetching DAS Sequence Features", startTime); - - DasSource[] sources = new jalview.gui.DasSourceBrowser().getDASSource(); - - if (selectedSources == null || selectedSources.size() == 0) - { - String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", - "uniprot"); - StringTokenizer st = new StringTokenizer(active, "\t"); - Vector selectedSources = new Vector(); - String token; - while (st.hasMoreTokens()) - { - token = st.nextToken(); - for (int i = 0; i < sources.length; i++) - { - if (sources[i].getNickname().equals(token)) - { - selectedSources.addElement(sources[i]); - break; - } - } - } - } + DasSource[] sources = new jalview.gui.DasSourceBrowser().getDASSource(); - if (selectedSources == null || selectedSources.size() == 0) - { - System.out.println("No DAS Sources active"); - af.setProgressBar("No DAS Sources Active", startTime); - cancelled = true; - fsettings.noDasSourceActive(); - return; - } + if (selectedSources == null || selectedSources.size() == 0) + { + String active = jalview.bin.Cache.getDefault("DAS_ACTIVE_SOURCE", + "uniprot"); + StringTokenizer st = new StringTokenizer(active, "\t"); + Vector selectedSources = new Vector(); + String token; + while (st.hasMoreTokens()) + { + token = st.nextToken(); + for (int i = 0; i < sources.length; i++) + { + if (sources[i].getNickname().equals(token)) + { + selectedSources.addElement(sources[i]); + break; + } + } + } + } + + if (selectedSources == null || selectedSources.size() == 0) + { + System.out.println("No DAS Sources active"); + cancelled = true; + setGuiNoDassourceActive(); + return; + } + + sourcesRemaining = selectedSources.size(); + //Now sending requests one at a time to each server + for (int sourceIndex = 0; sourceIndex < selectedSources.size() + && !cancelled; sourceIndex++) + { + DasSource dasSource = (DasSource) selectedSources + .elementAt(sourceIndex); + + nextSequence(dasSource, sequences[0]); + } + } + + private void setGuiNoDassourceActive() + { - sourcesRemaining = selectedSources.size(); - //Now sending requests one at a time to each server - for (int sourceIndex = 0; - sourceIndex < selectedSources.size() - && !cancelled; - sourceIndex++) - { - DasSource dasSource = (DasSource) selectedSources.elementAt( - sourceIndex); - - nextSequence(dasSource, sequences[0]); - } - } - - public void cancel() - { - af.setProgressBar("DAS Feature Fetching Cancelled", startTime); - cancelled = true; - } - - int sourcesRemaining=0; - void responseComplete(DasSource dasSource, SequenceI seq) - { - if (seq != null) - { - for (int seqIndex = 0; - seqIndex < sequences.length-1 - && !cancelled; seqIndex++) - { - if (sequences[seqIndex] == seq) - { - nextSequence(dasSource, sequences[++seqIndex]); - return; - } - } + if (af!=null) + { + af.setProgressBar("No DAS Sources Active", startTime); + } + if (getFeatSettings()!=null) + { + fsettings.noDasSourceActive(); } + } - sourcesRemaining --; + /** + * Update our fsettings dialog reference if we didn't have one when we were first initialised. + * @return fsettings + */ + private FeatureSettings getFeatSettings() + { + if (fsettings == null) + { + if (af != null) + { + fsettings = af.featureSettings; + } + } + return fsettings; + } - if(sourcesRemaining==0) - { - af.setProgressBar("DAS Feature Fetching Complete", startTime); + public void cancel() + { + if (af!=null) + { + af.setProgressBar("DAS Feature Fetching Cancelled", startTime); + } + cancelled = true; + } + + int sourcesRemaining = 0; - if(af.featureSettings!=null) + void responseComplete(DasSource dasSource, SequenceI seq) + { + if (seq != null) + { + for (int seqIndex = 0; seqIndex < sequences.length - 1 && !cancelled; seqIndex++) { - af.featureSettings.setTableData(); + if (sequences[seqIndex] == seq) + { + nextSequence(dasSource, sequences[++seqIndex]); + return; + } } + } - fsettings.complete(); - } + sourcesRemaining--; + + if (sourcesRemaining == 0) + { + System.err.println("Fetching Complete."); + setGuiFetchComplete(); + } - } + } - void featuresAdded(SequenceI seq) - { - af.getFeatureRenderer().featuresAdded(); + private void setGuiFetchComplete() + { - int start = af.getViewport().getStartSeq(); - int end = af.getViewport().getEndSeq(); - int index; - for(index=start; index 0 + && jalview.util.DBRefUtils.isDasCoordinateSystem( + cs[csIndex].getName(), uprefs[j])) { - DasCoordinateSystem cs[] = dasSource.getCoordinateSystem(); + Cache.log.debug("Launched fetcher for coordinate system " + + cs[0].getName()); + // Will have to pass any mapping information to the fetcher + //- the start/end for the DBRefEntry may not be the same as the sequence's start/end - for(int csIndex=0; csIndex 0 && jalview.util.DBRefUtils - .isDasCoordinateSystem(cs[csIndex].getName(), uprefs[j])) - { - Cache.log.debug("Launched fetcher for coordinate system " + - cs[0].getName()); - // Will have to pass any mapping information to the fetcher - //- the start/end for the DBRefEntry may not be the same as the sequence's start/end - - System.out.println(seq.getName() + " " + (seq.getDatasetSequence() == null) - + " " + dasSource.getUrl()); - - dasCoordSysFound = true; // break's out of the loop - createFeatureFetcher(seq, - dasSource, - uprefs[j]); - } - else - System.out.println("IGNORE " + cs[csIndex].getName()); - } + System.out.println(seq.getName() + " " + + (seq.getDatasetSequence() == null) + " " + + dasSource.getUrl()); + + dasCoordSysFound = true; // break's out of the loop + createFeatureFetcher(seq, dasSource, uprefs[j]); } + else + System.out.println("IGNORE " + cs[csIndex].getName()); } + } + } - if(!dasCoordSysFound) + if (!dasCoordSysFound) + { + String id = null; + // try and use the name as the sequence id + if (seq.getName().indexOf("|") > -1) + { + id = seq.getName().substring(seq.getName().lastIndexOf("|") + 1); + if (id.trim().length()<4) { - String id = null; - // try and use the name as the sequence id - if (seq.getName().indexOf("|") > -1) - { - id = seq.getName().substring( - seq.getName().lastIndexOf("|") + 1); - } - else + // hack - we regard a significant ID as being at least 4 non-whitespace characters + id = seq.getName().substring(0, seq.getName().lastIndexOf("|")); + if (id.indexOf("|")>-1) { - id = seq.getName(); - } - if (id != null) - { - // Should try to call a general feature fetcher that - // queries many sources with name to discover applicable ID references - createFeatureFetcher(seq, - dasSource, - id); + id = id.substring(id.lastIndexOf("|")+1); } } + } + else + { + id = seq.getName(); + } + if (id != null) + { + // Should try to call a general feature fetcher that + // queries many sources with name to discover applicable ID references + createFeatureFetcher(seq, dasSource, id); + } + } - } - + } -/** - * fetch and add das features to a sequence using the given source URL and compatible DbRef id. - * new features are mapped using the DbRef mapping to the local coordinate system. - * @param seq - * @param SourceUrl - * @param dbref - */ - protected void createFeatureFetcher(final SequenceI seq, final DasSource dasSource, - final DBRefEntry dbref) { + /** + * fetch and add das features to a sequence using the given source URL and compatible DbRef id. + * new features are mapped using the DbRef mapping to the local coordinate system. + * @param seq + * @param SourceUrl + * @param dbref + */ + protected void createFeatureFetcher(final SequenceI seq, + final DasSource dasSource, final DBRefEntry dbref) + { ////////////// /// fetch DAS features final Das1Source source = new Das1Source(); source.setUrl(dasSource.getUrl()); source.setNickname(dasSource.getNickname()); - if (dbref==null || dbref.getAccessionId()==null || dbref.getAccessionId().length()<1) + if (dbref == null || dbref.getAccessionId() == null + || dbref.getAccessionId().length() < 1) { + responseComplete(dasSource, seq); // reduce thread count anyhow return; } - Cache.log.debug("new Das Feature Fetcher for " + dbref.getSource()+":"+dbref.getAccessionId() + " querying " + - dasSource.getUrl()); + Cache.log.debug("new Das Feature Fetcher for " + dbref.getSource() + + ":" + dbref.getAccessionId() + " querying " + + dasSource.getUrl()); FeatureThread fetcher = new FeatureThread(dbref.getAccessionId() - // + ":" + start + "," + end, - , source); + // + ":" + start + "," + end, + , source); - fetcher.addFeatureListener(new FeatureListener() + fetcher.addFeatureListener(new FeatureListener() + { + public void comeBackLater(FeatureEvent e) { - public void comeBackLater(FeatureEvent e) - { - responseComplete(dasSource, seq); - Cache.log.debug("das source " + e.getDasSource().getNickname() + - " asked us to come back in " + e.getComeBackLater() + - " secs."); - } + responseComplete(dasSource, seq); + Cache.log.debug("das source " + e.getDasSource().getNickname() + + " asked us to come back in " + e.getComeBackLater() + + " secs."); + } - public void newFeatures(FeatureEvent e) - { + public void newFeatures(FeatureEvent e) + { - Das1Source ds = e.getDasSource(); + Das1Source ds = e.getDasSource(); - Map[] features = e.getFeatures(); - // add features to sequence - Cache.log.debug("das source " + ds.getUrl() + " returned " + - features.length + " features"); + Map[] features = e.getFeatures(); + // add features to sequence + Cache.log.debug("das source " + ds.getUrl() + " returned " + + features.length + " features"); - if (features.length > 0) + if (features.length > 0) + { + for (int i = 0; i < features.length; i++) { - for (int i = 0; i < features.length; i++) + SequenceFeature f = newSequenceFeature(features[i], source + .getNickname()); + if (dbref.getMap() != null && f.getBegin() > 0 + && f.getEnd() > 0) { - SequenceFeature f = newSequenceFeature(features[i], - source.getNickname()); - if (dbref.getMap()!=null && f.getBegin()>0 && f.getEnd()>0) { - Cache.log.debug("mapping from "+f.getBegin()+" - "+f.getEnd()); - SequenceFeature vf[]=null; - - try { - vf = dbref.getMap().locateFeature(f); - } - catch (Exception ex) + Cache.log.debug("mapping from " + f.getBegin() + " - " + + f.getEnd()); + SequenceFeature vf[] = null; + + try + { + vf = dbref.getMap().locateFeature(f); + } catch (Exception ex) + { + Cache.log + .info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to help@jalview.org."); + Cache.log.info("Mapping feature from " + f.getBegin() + + " to " + f.getEnd() + " in dbref " + + dbref.getAccessionId() + " in " + + dbref.getSource()); + Cache.log.info("using das Source " + ds.getUrl()); + Cache.log.info("Exception", ex); + } + + if (vf != null) + { + for (int v = 0; v < vf.length; v++) { - Cache.log.info("Error in 'experimental' mapping of features. Please try to reproduce and then report info to help@jalview.org."); - Cache.log.info("Mapping feature from "+f.getBegin()+" to "+f.getEnd()+" in dbref "+dbref.getAccessionId()+" in "+dbref.getSource()); - Cache.log.info("using das Source "+ds.getUrl()); - Cache.log.info("Exception", ex); - } - - if (vf!=null) { - for (int v=0;v 0) { + Cache.log.debug("new Das Feature Fetcher for " + id + " querying " + + dasSource.getUrl()); FeatureThread fetcher = new FeatureThread(id - // + ":" + start + "," + end, - , source); + // + ":" + start + "," + end, + , source); fetcher.addFeatureListener(new FeatureListener() { public void comeBackLater(FeatureEvent e) { responseComplete(dasSource, seq); - Cache.log.debug("das source " + e.getDasSource().getNickname() + - " asked us to come back in " + e.getComeBackLater() + - " secs."); + Cache.log.debug("das source " + e.getDasSource().getNickname() + + " asked us to come back in " + e.getComeBackLater() + + " secs."); } public void newFeatures(FeatureEvent e) @@ -451,15 +533,15 @@ public class DasSequenceFeatureFetcher Map[] features = e.getFeatures(); // add features to sequence - Cache.log.debug("das source " + ds.getUrl() + " returned " + - features.length + " features"); + Cache.log.debug("das source " + ds.getUrl() + " returned " + + features.length + " features"); if (features.length > 0) { for (int i = 0; i < features.length; i++) { - SequenceFeature f = newSequenceFeature(features[i], - source.getNickname()); + SequenceFeature f = newSequenceFeature(features[i], source + .getNickname()); seq.addSequenceFeature(f); } @@ -468,8 +550,8 @@ public class DasSequenceFeatureFetcher } else { - // System.out.println("No features found for " + seq.getName() - // + " from: " + e.getDasSource().getNickname()); + // System.out.println("No features found for " + seq.getName() + // + " from: " + e.getDasSource().getNickname()); } responseComplete(dasSource, seq); @@ -479,6 +561,11 @@ public class DasSequenceFeatureFetcher ); fetcher.start(); + } else { + // invalid fetch - indicate it is finished. + Cache.log.debug("Skipping empty ID for querying " + + dasSource.getUrl()); + responseComplete(dasSource, seq); } } @@ -489,7 +576,7 @@ public class DasSequenceFeatureFetcher */ SequenceFeature newSequenceFeature(Map dasfeature, String nickname) { - if (dasfeature==null) + if (dasfeature == null) { return null; } @@ -517,39 +604,33 @@ public class DasSequenceFeatureFetcher try { start = Integer.parseInt(dasfeature.get("START").toString()); + } catch (Exception ex) + { } - catch (Exception ex) - {} try { end = Integer.parseInt(dasfeature.get("END").toString()); + } catch (Exception ex) + { } - catch (Exception ex) - {} try { score = Integer.parseInt(dasfeature.get("SCORE").toString()); + } catch (Exception ex) + { } - catch (Exception ex) - {} - SequenceFeature f = new SequenceFeature( - (String) dasfeature.get("TYPE"), - desc, - start, - end, - score, - nickname); + SequenceFeature f = new SequenceFeature((String) dasfeature + .get("TYPE"), desc, start, end, score, nickname); if (dasfeature.containsKey("LINK")) { - f.addLink(f.getType() + " " + f.begin + "_" + f.end - + "|" + dasfeature.get("LINK")); + f.addLink(f.getType() + " " + f.begin + "_" + f.end + "|" + + dasfeature.get("LINK")); } return f; - } - catch (Exception e) + } catch (Exception e) { System.out.println("ERRR " + e); e.printStackTrace(); @@ -558,14 +639,26 @@ public class DasSequenceFeatureFetcher return null; } } - + /** + * query the default DAS Source Registry for sources. + * Uses value of jalview property DAS_REGISTRY_URL and the DasSourceBrowser.DEFAULT_REGISTRY if that doesn't exist. + * @return list of sources + */ public static DasSource[] getDASSources() { - DasSourceReaderImpl reader = new DasSourceReaderImpl(); String registryURL = jalview.bin.Cache.getDefault("DAS_REGISTRY_URL", - DasSourceBrowser.DEFAULT_REGISTRY - ); + DasSourceBrowser.DEFAULT_REGISTRY); + return getDASSources(registryURL); + } + /** + * query the given URL for DasSources. + * @param registryURL + * return sources from registryURL + */ + public static DasSource[] getDASSources(String registryURL) + { + DasSourceReaderImpl reader = new DasSourceReaderImpl(); try { @@ -589,13 +682,13 @@ public class DasSequenceFeatureFetcher } else if (ds instanceof Das1Source) { - das1sources.add( (Das1Source) ds); + das1sources.add((Das1Source) ds); } } - return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources.size()]); - } - catch (Exception ex) + return (Das1Source[]) das1sources.toArray(new Das1Source[das1sources + .size()]); + } catch (Exception ex) { ex.printStackTrace(); return null; @@ -603,4 +696,3 @@ public class DasSequenceFeatureFetcher } } - -- 1.7.10.2