JAL-2738 use GeneLocus extends DBRefEntry to hold chromosomal mappings
[jalview.git] / src / jalview / ext / ensembl / EnsemblGene.java
index cdcfa96..9c7ce63 100644 (file)
@@ -23,7 +23,6 @@ package jalview.ext.ensembl;
 import jalview.api.FeatureColourI;
 import jalview.api.FeatureSettingsModelI;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.GeneLociI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
@@ -51,8 +50,6 @@ import com.stevesoft.pat.Regex;
  */
 public class EnsemblGene extends EnsemblSeqProxy
 {
-  private static final String GENE_PREFIX = "gene:";
-
   /*
    * accepts anything as we will attempt lookup of gene or 
    * transcript id or gene name
@@ -64,6 +61,8 @@ public class EnsemblGene extends EnsemblSeqProxy
       EnsemblFeatureType.exon, EnsemblFeatureType.cds,
       EnsemblFeatureType.variation };
 
+  private static final String CHROMOSOME = "chromosome";
+
   /**
    * Default constructor (to use rest.ensembl.org)
    */
@@ -100,6 +99,12 @@ public class EnsemblGene extends EnsemblSeqProxy
     return EnsemblSeqType.GENOMIC;
   }
 
+  @Override
+  protected String getObjectType()
+  {
+    return OBJECT_TYPE_GENE;
+  }
+
   /**
    * Returns an alignment containing the gene(s) for the given gene or
    * transcript identifier, or external identifier (e.g. Uniprot id). If given a
@@ -149,7 +154,11 @@ public class EnsemblGene extends EnsemblSeqProxy
       
       if (geneAlignment.getHeight() == 1)
       {
+        // ensure id has 'correct' case for the Ensembl identifier
+        geneId = geneAlignment.getSequenceAt(0).getName();
+
         findGeneLoci(geneAlignment.getSequenceAt(0), geneId);
+
         getTranscripts(geneAlignment, geneId);
       }
       if (al == null)
@@ -179,7 +188,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     if (geneLoci != null)
     {
       seq.setGeneLoci(geneLoci.getSpeciesId(), geneLoci.getAssemblyId(),
-              geneLoci.getChromosomeId(), geneLoci.getMap());
+              geneLoci.getChromosomeId(), geneLoci.getMapping());
     }
     else
     {
@@ -201,7 +210,7 @@ public class EnsemblGene extends EnsemblSeqProxy
       return false;
     }
     String[] tokens = description.split(":");
-    if (tokens.length == 6 && tokens[0].startsWith(DBRefEntry.CHROMOSOME))
+    if (tokens.length == 6 && tokens[0].startsWith(CHROMOSOME))
     {
       String ref = tokens[1];
       String chrom = tokens[2];
@@ -235,7 +244,7 @@ public class EnsemblGene extends EnsemblSeqProxy
    */
   List<String> getGeneIds(String accessions)
   {
-    List<String> geneIds = new ArrayList<String>();
+    List<String> geneIds = new ArrayList<>();
 
     for (String acc : accessions.split(getAccessionSeparator()))
     {
@@ -358,7 +367,7 @@ public class EnsemblGene extends EnsemblSeqProxy
      * look for exon features of the transcript, failing that for CDS
      * (for example ENSG00000124610 has 1 CDS but no exon features)
      */
-    String parentId = "transcript:" + accId;
+    String parentId = accId;
     List<SequenceFeature> splices = findFeatures(gene,
             SequenceOntologyI.EXON, parentId);
     if (splices.isEmpty())
@@ -370,7 +379,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     int transcriptLength = 0;
     final char[] geneChars = gene.getSequence();
     int offset = gene.getStart(); // to convert to 0-based positions
-    List<int[]> mappedFrom = new ArrayList<int[]>();
+    List<int[]> mappedFrom = new ArrayList<>();
 
     for (SequenceFeature sf : splices)
     {
@@ -389,7 +398,7 @@ public class EnsemblGene extends EnsemblSeqProxy
      * Ensembl has gene name as transcript Name
      * EnsemblGenomes doesn't, but has a url-encoded description field
      */
-    String description = (String) transcriptFeature.getValue(NAME);
+    String description = transcriptFeature.getDescription();
     if (description == null)
     {
       description = (String) transcriptFeature.getValue(DESCRIPTION);
@@ -412,7 +421,7 @@ public class EnsemblGene extends EnsemblSeqProxy
      * transfer features to the new sequence; we use EnsemblCdna to do this,
      * to filter out unwanted features types (see method retainFeature)
      */
-    List<int[]> mapTo = new ArrayList<int[]>();
+    List<int[]> mapTo = new ArrayList<>();
     mapTo.add(new int[] { 1, transcriptLength });
     MapList mapping = new MapList(mappedFrom, mapTo, 1, 1);
     EnsemblCdna cdna = new EnsemblCdna(getDomain());
@@ -452,7 +461,7 @@ public class EnsemblGene extends EnsemblSeqProxy
       return;
     }
 
-    MapList geneMapping = loci.getMap();
+    MapList geneMapping = loci.getMapping();
 
     List<int[]> exons = mapping.getFromRanges();
     List<int[]> transcriptLoci = new ArrayList<>();
@@ -478,7 +487,7 @@ public class EnsemblGene extends EnsemblSeqProxy
    */
   protected String getTranscriptId(SequenceFeature feature)
   {
-    return (String) feature.getValue("transcript_id");
+    return (String) feature.getValue(JSON_ID);
   }
 
   /**
@@ -498,9 +507,9 @@ public class EnsemblGene extends EnsemblSeqProxy
   protected List<SequenceFeature> getTranscriptFeatures(String accId,
           SequenceI geneSequence)
   {
-    List<SequenceFeature> transcriptFeatures = new ArrayList<SequenceFeature>();
+    List<SequenceFeature> transcriptFeatures = new ArrayList<>();
 
-    String parentIdentifier = GENE_PREFIX + accId;
+    String parentIdentifier = accId;
 
     List<SequenceFeature> sfs = geneSequence.getFeatures()
             .getFeaturesByOntology(SequenceOntologyI.TRANSCRIPT);
@@ -510,7 +519,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     for (SequenceFeature sf : sfs)
     {
       String parent = (String) sf.getValue(PARENT);
-      if (parentIdentifier.equals(parent))
+      if (parentIdentifier.equalsIgnoreCase(parent))
       {
         transcriptFeatures.add(sf);
       }
@@ -538,22 +547,26 @@ public class EnsemblGene extends EnsemblSeqProxy
   }
 
   /**
-   * Answers true for a feature of type 'gene' (or a sub-type of gene in the
-   * Sequence Ontology), whose ID is the accession we are retrieving
+   * Answers a list of sequence features (if any) whose type is 'gene' (or a
+   * subtype of gene in the Sequence Ontology), and whose ID is the accession we
+   * are retrieving
    */
   @Override
-  protected boolean identifiesSequence(SequenceFeature sf, String accId)
+  protected List<SequenceFeature> getIdentifyingFeatures(SequenceI seq,
+          String accId)
   {
-    if (SequenceOntologyFactory.getInstance().isA(sf.getType(),
-            SequenceOntologyI.GENE))
+    List<SequenceFeature> result = new ArrayList<>();
+    List<SequenceFeature> sfs = seq.getFeatures()
+            .getFeaturesByOntology(SequenceOntologyI.GENE);
+    for (SequenceFeature sf : sfs)
     {
-      String id = (String) sf.getValue(ID);
-      if ((GENE_PREFIX + accId).equals(id))
+      String id = (String) sf.getValue(JSON_ID);
+      if (accId.equalsIgnoreCase(id))
       {
-        return true;
+        result.add(sf);
       }
     }
-    return false;
+    return result;
   }
 
   /**
@@ -575,7 +588,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     if (isTranscript(type))
     {
       String parent = (String) sf.getValue(PARENT);
-      if (!(GENE_PREFIX + accessionId).equals(parent))
+      if (!accessionId.equalsIgnoreCase(parent))
       {
         return false;
       }
@@ -584,17 +597,6 @@ public class EnsemblGene extends EnsemblSeqProxy
   }
 
   /**
-   * Answers false. This allows an optimisation - a single 'gene' feature is all
-   * that is needed to identify the positions of the gene on the genomic
-   * sequence.
-   */
-  @Override
-  protected boolean isSpliceable()
-  {
-    return false;
-  }
-
-  /**
    * Override to do nothing as Ensembl doesn't return a protein sequence for a
    * gene identifier
    */