JAL-1705 use GET for single queries; set gene name as description on
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 27 Jan 2016 11:59:35 +0000 (11:59 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 27 Jan 2016 11:59:35 +0000 (11:59 +0000)
transcript

resources/lang/Messages.properties
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblGenome.java
src/jalview/ext/ensembl/EnsemblOverlap.java
src/jalview/ext/ensembl/EnsemblProtein.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
test/jalview/ext/ensembl/EnsemblRestClientTest.java
test/jalview/ext/ensembl/EnsemblSeqProxyTest.java

index 42dc0f7..6bbe798 100644 (file)
@@ -786,7 +786,7 @@ label.transformed_points_for_params = Transformed points for {0}
 label.graduated_color_for_params = Graduated Feature Colour for {0}
 label.select_backgroud_colour = Select Background Colour
 label.invalid_font = Invalid Font
-label.separate_multiple_accession_ids = Enter one or more PDB accession IDs separated by a semi-colon ";"
+label.separate_multiple_accession_ids = Enter one or more accession IDs separated by a semi-colon ";"
 label.separate_multiple_query_values = Enter one or more {0}s separated by a semi-colon ";"
 label.search_all = Enter one or more search values separated by a semi-colon ";" (Note: This Searches the entire PDB database)
 label.replace_commas_semicolons = Replace commas with semi-colons
index 5b57e5e..b5ea686 100644 (file)
@@ -154,6 +154,11 @@ public class EnsemblGene extends EnsemblSeqProxy
     }
 
     Sequence transcript = new Sequence(accId, seqChars, 1, transcriptLength);
+    String geneName = (String) transcriptFeature.getValue(NAME);
+    if (geneName != null)
+    {
+      transcript.setDescription(geneName);
+    }
     transcript.createDatasetSequence();
 
     al.addSequence(transcript);
@@ -178,9 +183,7 @@ public class EnsemblGene extends EnsemblSeqProxy
 
   /**
    * Returns a list of the transcript features on the sequence whose Parent is
-   * the gene for the accession id. Also removes all transcript features from
-   * the gene sequence, as we have no further need for them and they obscure
-   * more useful features on the display.
+   * the gene for the accession id.
    * 
    * @param accId
    * @param geneSequence
@@ -191,7 +194,6 @@ public class EnsemblGene extends EnsemblSeqProxy
   {
     List<SequenceFeature> transcriptFeatures = new ArrayList<SequenceFeature>();
 
-    List<SequenceFeature> keptFeatures = new ArrayList<SequenceFeature>();
     String parentIdentifier = "gene:" + accId;
     SequenceFeature[] sfs = geneSequence.getSequenceFeatures();
 
@@ -207,14 +209,8 @@ public class EnsemblGene extends EnsemblSeqProxy
             transcriptFeatures.add(sf);
           }
         }
-        else
-        {
-          keptFeatures.add(sf);
-        }
       }
     }
-    SequenceFeature[] featuresRetained = keptFeatures.toArray(new SequenceFeature[keptFeatures.size()]);
-    geneSequence.getDatasetSequence().setSequenceFeatures(featuresRetained);
 
     return transcriptFeatures;
   }
index 8238da0..b7db2bc 100644 (file)
@@ -10,7 +10,7 @@ public class EnsemblGenome extends EnsemblSeqProxy
    */
   private static final EnsemblFeatureType[] FEATURES_TO_FETCH = {
       EnsemblFeatureType.transcript, EnsemblFeatureType.exon,
-      EnsemblFeatureType.cds /*, EnsemblFeatureType.variation */};
+      EnsemblFeatureType.cds, EnsemblFeatureType.variation };
 
   public EnsemblGenome()
   {
index 1663d0d..b1514d8 100644 (file)
@@ -93,7 +93,7 @@ public class EnsemblOverlap extends EnsemblRestClient
    * describes the required encoding of the response.
    */
   @Override
-  protected String getRequestMimeType()
+  protected String getRequestMimeType(boolean multipleIds)
   {
     return "text/x-gff3";
   }
index 8a57a16..5238f98 100644 (file)
@@ -2,7 +2,6 @@ package jalview.ext.ensembl;
 
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceI;
 
 public class EnsemblProtein extends EnsemblSeqProxy
 {
@@ -47,8 +46,7 @@ public class EnsemblProtein extends EnsemblSeqProxy
    * applicable to the protein product sequence
    */
   @Override
-  protected void addFeaturesAndProduct(String accId, AlignmentI alignment,
-          SequenceI genomicSequence)
+  protected void addFeaturesAndProduct(String accId, AlignmentI alignment)
   {
   }
 
index 02b13ef..f81bce2 100644 (file)
@@ -69,10 +69,12 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
   /**
    * Return the desired value for the Content-Type request header
    * 
+   * @param multipleIds
+   * 
    * @return
    * @see https://github.com/Ensembl/ensembl-rest/wiki/HTTP-Headers
    */
-  protected abstract String getRequestMimeType();
+  protected abstract String getRequestMimeType(boolean multipleIds);
 
   /**
    * Return the desired value for the Accept request header
@@ -126,16 +128,18 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
      * POST method allows multiple queries in one request; it is supported for
      * sequence queries, but not for overlap
      */
-    connection.setRequestMethod(useGetRequest() ? HttpMethod.GET
-            : HttpMethod.POST);
-    connection.setRequestProperty("Content-Type", getRequestMimeType());
+    boolean multipleIds = ids.size() > 1;// useGetRequest();
+    connection.setRequestMethod(multipleIds ? HttpMethod.POST
+            : HttpMethod.GET);
+    connection.setRequestProperty("Content-Type",
+            getRequestMimeType(multipleIds));
     connection.setRequestProperty("Accept", getResponseMimeType());
 
     connection.setUseCaches(false);
     connection.setDoInput(true);
-    connection.setDoOutput(true);
+    connection.setDoOutput(multipleIds);
 
-    if (!useGetRequest())
+    if (multipleIds)
     {
       writePostBody(connection, ids);
     }
@@ -145,6 +149,10 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
   
     if (responseCode != 200)
     {
+      /*
+       * note: a GET request for an invalid id returns an error code e.g. 415
+       * but POST request returns 200 and an empty Fasta response 
+       */
       throw new RuntimeException(
               "Response code was not 200. Detected response was "
                       + responseCode);
index d7811b9..a6d838b 100644 (file)
@@ -42,6 +42,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
    */
   protected static final String NMD_VARIANT = "NMD_transcript_variant";
 
+  protected static final String NAME = "Name";
+
   public enum EnsemblSeqType
   {
     /**
@@ -111,12 +113,10 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
 
   /**
    * Makes the sequence queries to Ensembl's REST service and returns an
-   * alignment consisting of the returned sequences. This overloaded method
-   * allows the genomic sequence (with features) to be passed in if it has
-   * already been retrieved, to avoid repeat calls to fetch it.
+   * alignment consisting of the returned sequences.
    */
-  public AlignmentI getSequenceRecords(String query,
-          SequenceI genomicSequence) throws Exception
+  @Override
+  public AlignmentI getSequenceRecords(String query) throws Exception
   {
     long now = System.currentTimeMillis();
     // TODO use a String... query vararg instead?
@@ -159,11 +159,12 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     }
 
     /*
-     * fetch and transfer genomic sequence features
+     * fetch and transfer genomic sequence features,
+     * fetch protein product and add as cross-reference
      */
     for (String accId : allIds)
     {
-      addFeaturesAndProduct(accId, alignment, genomicSequence);
+      addFeaturesAndProduct(accId, alignment);
     }
 
     inProgress = false;
@@ -181,24 +182,26 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
    * @param accId
    * @param alignment
    */
-  protected void addFeaturesAndProduct(String accId, AlignmentI alignment,
-          SequenceI genomicSequence)
+  protected void addFeaturesAndProduct(String accId, AlignmentI alignment)
   {
+    if (alignment == null)
+    {
+      return;
+    }
+
     try
     {
       /*
        * get 'dummy' genomic sequence with exon, cds and variation features
        */
-      if (genomicSequence == null)
+      SequenceI genomicSequence = null;
+      EnsemblOverlap gffFetcher = new EnsemblOverlap();
+      EnsemblFeatureType[] features = getFeaturesToFetch();
+      AlignmentI geneFeatures = gffFetcher.getSequenceRecords(accId,
+              features);
+      if (geneFeatures.getHeight() > 0)
       {
-        EnsemblOverlap gffFetcher = new EnsemblOverlap();
-        EnsemblFeatureType[] features = getFeaturesToFetch();
-        AlignmentI geneFeatures = gffFetcher.getSequenceRecords(accId,
-                features);
-        if (geneFeatures.getHeight() > 0)
-        {
-          genomicSequence = geneFeatures.getSequenceAt(0);
-        }
+        genomicSequence = geneFeatures.getSequenceAt(0);
       }
       if (genomicSequence != null)
       {
@@ -386,6 +389,15 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
               "Only retrieved %d sequences for %d query strings", fr
                       .getSeqs().size(), ids.size()));
     }
+
+    if (fr.getSeqs().size() == 1 && fr.getSeqs().get(0).getLength() == 0)
+    {
+      /*
+       * POST request has returned an empty FASTA file e.g. for invalid id
+       */
+      throw new IOException("No data returned for " + ids);
+    }
+
     if (fr.getSeqs().size() > 0)
     {
       AlignmentI seqal = new Alignment(
@@ -424,10 +436,16 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   @Override
   protected URL getUrl(List<String> ids) throws MalformedURLException
   {
-    // ids are not used - they go in the POST body instead
+    /*
+     * a single id is included in the URL path
+     * multiple ids go in the POST body instead
+     */
     StringBuffer urlstring = new StringBuffer(128);
     urlstring.append(SEQUENCE_ID_URL);
-
+    if (ids.size() == 1)
+    {
+      urlstring.append("/").append(ids.get(0));
+    }
     // @see https://github.com/Ensembl/ensembl-rest/wiki/Output-formats
     urlstring.append("?type=").append(getSourceEnsemblType().getType());
     urlstring.append(("&Accept=text/x-fasta"));
@@ -454,9 +472,9 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   }
 
   @Override
-  protected String getRequestMimeType()
+  protected String getRequestMimeType(boolean multipleIds)
   {
-    return "application/json";
+    return multipleIds ? "application/json" : "text/x-fasta";
   }
 
   @Override
@@ -751,12 +769,6 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
             + " sequence with variant features";
   }
 
-  @Override
-  public AlignmentI getSequenceRecords(String identifier) throws Exception
-  {
-    return getSequenceRecords(identifier, null);
-  }
-
   /**
    * Returns a (possibly empty) list of features on the sequence which have the
    * specified sequence ontology type (or a sub-type of it), and the given
index c7b3397..6f7c1ad 100644 (file)
@@ -42,7 +42,7 @@ public class EnsemblRestClientTest
       }
   
       @Override
-      protected String getRequestMimeType()
+      protected String getRequestMimeType(boolean b)
       {
         return null;
       }
index a06465f..10ecfe0 100644 (file)
@@ -189,7 +189,7 @@ public class EnsemblSeqProxyTest
       }
 
       @Override
-      protected String getRequestMimeType()
+      protected String getRequestMimeType(boolean b)
       {
         // TODO Auto-generated method stub
         return null;