JAL-1793 update spike build to latest incl stop and synonymous variants on peptides
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 Jan 2018 16:07:17 +0000 (16:07 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 30 Jan 2018 16:07:17 +0000 (16:07 +0000)
29 files changed:
RELEASE
benchmarking/README
help/help.jhm
help/html/releases.html
help/html/whatsNew.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/Dna.java
src/jalview/ext/ensembl/EnsemblCdna.java
src/jalview/ext/ensembl/EnsemblFeatures.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblGenome.java
src/jalview/ext/ensembl/EnsemblLookup.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
src/jalview/ext/ensembl/EnsemblSequenceFetcher.java
src/jalview/ext/ensembl/EnsemblSymbol.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/gui/CrossRefAction.java
src/jalview/gui/StructureChooser.java
src/jalview/io/gff/SequenceOntologyI.java
src/jalview/jbgui/GStructureChooser.java
src/jalview/schemes/ResidueProperties.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/ext/ensembl/EnsemblCdnaTest.java
test/jalview/ext/ensembl/EnsemblGeneTest.java
test/jalview/ext/ensembl/EnsemblSeqProxyTest.java
test/jalview/gui/StructureChooserTest.java
test/jalview/io/vcf/VCFLoaderTest.java

diff --git a/RELEASE b/RELEASE
index f1faf34..eb9d7cd 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
 jalview.release=releases/Release_2_10_3_Branch
-jalview.version=2.10.3
+jalview.version=2.10.3b1
index fac0bf6..ccf53c1 100644 (file)
@@ -7,16 +7,19 @@ You will need to install Maven: https://maven.apache.org/install.html
 
 This builds a jalview.jar file and puts it into dist/
 
+
 2. Make a lib directory in benchmarking/ if not already present and cd into this directory.
 
+
 3. Purge any previous maven dependencies:
    mvn dependency:purge-local-repository -DactTransitively=false -DreResolve=false
 
+
 4. Run
   mvn install:install-file -Dfile=../dist/jalview.jar -DgroupId=jalview.org -DartifactId=jalview -Dversion=1.0 -Dpackaging=jar -DlocalRepositoryPath=lib
-
 to install the jalview.jar file in the local maven repository. The pom.xml in the benchmarking references this installation, so if you change the names the pom.xml file will also need to be updated.
 
+
 5. Build and run jmh benchmarking. In the benchmarking directory:
   mvn clean install
   java -jar target/benchmarks.jar
@@ -24,4 +27,14 @@ to install the jalview.jar file in the local maven repository. The pom.xml in th
   To get JSON output instead use:
   java -jar target/benchmarks.jar -rf json
   
-  JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
\ No newline at end of file
+  JSON output can be viewed quickly by drag-dropping on http://jmh.morethan.io/
+  
+  To get help use the standard -h option:
+       java -jar target/benchmarks.jar -h
+       
+  More information here:
+       http://openjdk.java.net/projects/code-tools/jmh/
+       http://java-performance.info/jmh/
+  
+  
+ 6. If you make changes to the Jalview code everything will need to be refreshed, by performing steps 3-5 again.
index 010bca8..732f01b 100755 (executable)
@@ -22,7 +22,7 @@
    <mapID target="home" url="html/index.html" />
    
    <mapID target="new" url="html/whatsNew.html"/>
-   <mapID target="release" url="html/releases.html#Jalview.2.10.3"/>
+   <mapID target="release" url="html/releases.html#Jalview.2.10.3b1"/>
    <mapID target="alannotation" url="html/features/annotation.html"/>
    <mapID target="keys" url="html/keys.html"/>
    <mapID target="newkeys" url="html/features/newkeystrokes.html"/>
index a36e31a..83d2ce4 100755 (executable)
@@ -68,22 +68,26 @@ li:before {
       </td>
     </tr>
     <tr>
-      <td width=="60" nowrap>
+      <td width="60" nowrap>
         <div align="center">
-          <strong><a name="Jalview.2.10.3b1">2.10.3b1</a><br /> <em>5/12/2017</em></strong>
+          <strong><a name="Jalview.2.10.3b1">2.10.3b1</a><br /> <em>24/1/2018</em></strong>
         </div>
       </td>
       <td><div align="left">
-          <em></em>
-      </td>
+          <ul><li>Updated Certum Codesigning Certificate
+              (Valid till 30th November 2018)</li></ul></div></td>
       <td><div align="left">
+          <em>Desktop</em><ul>
           <ul>
+            <li><!-- JAL-2859-->Only one structure is loaded when several sequences and structures are selected for viewing/superposing</li>
             <li><!-- JAL-2851-->Alignment doesn't appear to scroll vertically via trackpad and scrollwheel</li>
             <li><!-- JAL-2842-->Jalview hangs if up/down arrows pressed in cursor mode when cursor lies in hidden region at start of alignment</li>
             <li><!-- JAL-2827-->Helix annotation has 'notches' when scrolled into view if columns are hidden</li>
             <li><!-- JAL-2740-->Annotation column filter can be slow to reset (ie after hitting cancel) for large numbers of hidden columns</li>
-            <li><!-- JAL-2849-->User preference for disabling inclusion of sequence limits when exporting as flat file has no effect</li>
-          <ul>
+            <li><!-- JAL-2849-->User preference for disabling inclusion of sequence limits when exporting as flat file has no effect</li>             
+            <li><!-- JAL-2679-->Reproducible cross-reference relationships when retrieving sequences from EnsemblGenomes</li>  
+          </ul>
+          </div>
       </td>
     </tr>
     <tr>
index 4bf1cec..6d75f0f 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>What's new in Jalview 2.10.3 ?</strong>
+    <strong>What's new in Jalview 2.10.3b1 ?</strong>
   </p>
   <p>
-    Version 2.10.3 was released in November 2017. The major focus was to
-    improve Jalview's sequence features datamodel and the scalability of
-    the alignment rendering system. The full list of bug fixes and new
-    features can be found in the <a href="releases.html#Jalview.2.10.3">2.10.3
-      Release Notes</a>. Key improvements include:
+    This is the January 2018 patch release, which addresses critical bugs including trackpad function in OSX, and display of multiple 3D structures. 
+    The full list bugs fixed in this release can be found in the <a href="releases.html#Jalview.2.10.3b1">2.10.3b1
+      Release Notes</a>. In addition, Jalview 2.10.3 provides:
   </p>
   <ul>
     <li>Faster and more responsive UI when importing and working
index 1277a86..0f801eb 100644 (file)
@@ -678,7 +678,8 @@ label.2d_rna_structure_line = 2D RNA {0} (alignment)
 label.2d_rna_sequence_name = 2D RNA - {0}
 label.edit_name_and_description_current_group = Edit name and description of current group
 label.from_file = From File
-label.enter_pdb_id = Enter PDB Id (or pdbid:chaincode)
+label.enter_pdb_id = Enter PDB Id
+label.enter_pdb_id_tip = Enter PDB Id (or pdbid:chaincode)
 label.text_colour = Text Colour...
 label.structure = Structure
 label.show_pdbstruct_dialog = 3D Structure Data...
@@ -1345,7 +1346,7 @@ label.score = Score
 label.colour_by_label = Colour by label
 label.variable_colour = Variable colour
 label.select_colour = Select colour
-option.enable_disable_autosearch = When ticked, search is performed automatically.
+option.enable_disable_autosearch = When ticked, search is performed automatically
 option.autosearch = Autosearch
 label.retrieve_ids = Retrieve IDs
 label.display_settings_for = Display settings for {0} features
@@ -1359,3 +1360,10 @@ label.filters_tooltip = Click to set or amend filters
 label.or = Or
 label.and = And
 label.sequence_feature_colours = Sequence Feature Colours
+label.best_quality = Best Quality
+label.best_resolution = Best Resolution
+label.most_protein_chain = Most Protein Chain
+label.most_bound_molecules = Most Bound Molecules
+label.most_polymer_residues = Most Polymer Residues
+label.cached_structures = Cached Structures
+label.free_text_search = Free Text Search
index 616cb9d..d035e73 100644 (file)
@@ -337,6 +337,8 @@ label.optimise_order = Optimizar orden
 label.seq_sort_by_score = Ordenar las secuencias por puntuación
 label.load_colours = Cargar colores
 label.save_colours = Guardar colores
+label.load_colours_tooltip = Cargar colores y filtros desde fichero
+label.save_colours_tooltip = Guardar colores y filtros en fichero
 label.fetch_das_features = Recuperar funciones DAS
 label.selected_database_to_fetch_from = Seleccionada {0} Base de datos {1} para buscar de {2} 
 label.database_param = Base de datos: {0}
@@ -630,6 +632,7 @@ label.2d_rna_sequence_name = 2D RNA - {0}
 label.edit_name_and_description_current_group = Editar el nombre y la descripción del grupo actual
 label.from_file = desde fichero
 label.enter_pdb_id = Introducir PDB Id
+label.enter_pdb_id_tip = Introducir PDB Id (o pdbid:chaincode)
 label.text_colour = Color de texto...
 label.structure = Estructura
 label.create_sequence_details_report_annotation_for = Anotación para {0}
@@ -1344,8 +1347,8 @@ label.score = Puntuaci
 label.colour_by_label = Colorear por texto
 label.variable_colour = Color variable
 label.select_colour = Seleccionar color
-option.enable_disable_autosearch = Marque para buscar automáticamente
-option.autosearch = Búsqueda automática
+option.enable_disable_autosearch = Marcar para buscar automáticamente
+option.autosearch = Auto búsqueda
 label.retrieve_ids = Recuperar IDs
 label.display_settings_for = Visualización de características {0}
 label.simple = Simple
@@ -1356,4 +1359,12 @@ label.by_text_of = Por texto de
 label.by_range_of = Por rango de
 label.filters_tooltip = Haga clic para configurar o modificar los filtros
 label.or = O
-label.and = Y
\ No newline at end of file
+label.and = Y
+label.sequence_feature_colours = Colores de características de las secuencias
+label.best_quality = Mejor Calidad
+label.best_resolution = Mejor Resolución
+label.most_protein_chain = Más Cadena de Proteína
+label.most_bound_molecules = Más Moléculas Ligadas
+label.most_polymer_residues = Más Residuos de Polímeros
+label.cached_structures = Estructuras en Caché
+label.free_text_search = Búsqueda de texto libre
index bef667d..bdc5fc1 100644 (file)
@@ -128,7 +128,7 @@ public class AlignmentUtils
    */
   public static AlignmentI expandContext(AlignmentI core, int flankSize)
   {
-    List<SequenceI> sq = new ArrayList<SequenceI>();
+    List<SequenceI> sq = new ArrayList<>();
     int maxoffset = 0;
     for (SequenceI s : core.getSequences())
     {
@@ -258,7 +258,7 @@ public class AlignmentUtils
   public static Map<String, List<SequenceI>> getSequencesByName(
           AlignmentI al)
   {
-    Map<String, List<SequenceI>> theMap = new LinkedHashMap<String, List<SequenceI>>();
+    Map<String, List<SequenceI>> theMap = new LinkedHashMap<>();
     for (SequenceI seq : al.getSequences())
     {
       String name = seq.getName();
@@ -267,7 +267,7 @@ public class AlignmentUtils
         List<SequenceI> seqs = theMap.get(name);
         if (seqs == null)
         {
-          seqs = new ArrayList<SequenceI>();
+          seqs = new ArrayList<>();
           theMap.put(name, seqs);
         }
         seqs.add(seq);
@@ -294,8 +294,8 @@ public class AlignmentUtils
       return false;
     }
 
-    Set<SequenceI> mappedDna = new HashSet<SequenceI>();
-    Set<SequenceI> mappedProtein = new HashSet<SequenceI>();
+    Set<SequenceI> mappedDna = new HashSet<>();
+    Set<SequenceI> mappedProtein = new HashSet<>();
 
     /*
      * First pass - map sequences where cross-references exist. This include
@@ -465,7 +465,7 @@ public class AlignmentUtils
     {
       String lastCodon = String.valueOf(cdnaSeqChars,
               cdnaLength - CODON_LENGTH, CODON_LENGTH).toUpperCase();
-      for (String stop : ResidueProperties.STOP)
+      for (String stop : ResidueProperties.STOP_CODONS)
       {
         if (lastCodon.equals(stop))
         {
@@ -536,7 +536,8 @@ public class AlignmentUtils
        * allow * in protein to match untranslatable in dna
        */
       final char aaRes = aaSeqChars[aaPos];
-      if ((translated == null || "STOP".equals(translated)) && aaRes == '*')
+      if ((translated == null || ResidueProperties.STOP.equals(translated))
+              && aaRes == '*')
       {
         continue;
       }
@@ -568,7 +569,8 @@ public class AlignmentUtils
     if (dnaPos == cdnaSeqChars.length - CODON_LENGTH)
     {
       String codon = String.valueOf(cdnaSeqChars, dnaPos, CODON_LENGTH);
-      if ("STOP".equals(ResidueProperties.codonTranslate(codon)))
+      if (ResidueProperties.STOP
+              .equals(ResidueProperties.codonTranslate(codon)))
       {
         return true;
       }
@@ -881,7 +883,7 @@ public class AlignmentUtils
       System.err.println("Wrong alignment type in alignProteinAsDna");
       return 0;
     }
-    List<SequenceI> unmappedProtein = new ArrayList<SequenceI>();
+    List<SequenceI> unmappedProtein = new ArrayList<>();
     Map<AlignedCodon, Map<SequenceI, AlignedCodon>> alignedCodons = buildCodonColumnsMap(
             protein, dna, unmappedProtein);
     return alignProteinAs(protein, alignedCodons, unmappedProtein);
@@ -1092,7 +1094,7 @@ public class AlignmentUtils
      * {dnaSequence, {proteinSequence, codonProduct}} at that position. The
      * comparator keeps the codon positions ordered.
      */
-    Map<AlignedCodon, Map<SequenceI, AlignedCodon>> alignedCodons = new TreeMap<AlignedCodon, Map<SequenceI, AlignedCodon>>(
+    Map<AlignedCodon, Map<SequenceI, AlignedCodon>> alignedCodons = new TreeMap<>(
             new CodonComparator());
 
     for (SequenceI dnaSeq : dna.getSequences())
@@ -1138,9 +1140,9 @@ public class AlignmentUtils
     // TODO delete this ugly hack once JAL-2022 is resolved
     // i.e. we can model startPhase > 0 (incomplete start codon)
 
-    List<SequenceI> sequencesChecked = new ArrayList<SequenceI>();
+    List<SequenceI> sequencesChecked = new ArrayList<>();
     AlignedCodon lastCodon = null;
-    Map<SequenceI, AlignedCodon> toAdd = new HashMap<SequenceI, AlignedCodon>();
+    Map<SequenceI, AlignedCodon> toAdd = new HashMap<>();
 
     for (Entry<AlignedCodon, Map<SequenceI, AlignedCodon>> entry : alignedCodons
             .entrySet())
@@ -1319,7 +1321,7 @@ public class AlignmentUtils
     Map<SequenceI, AlignedCodon> seqProduct = alignedCodons.get(codon);
     if (seqProduct == null)
     {
-      seqProduct = new HashMap<SequenceI, AlignedCodon>();
+      seqProduct = new HashMap<>();
       alignedCodons.put(codon, seqProduct);
     }
     seqProduct.put(protein, codon);
@@ -1456,7 +1458,7 @@ public class AlignmentUtils
       {
         continue;
       }
-      final List<AlignmentAnnotation> result = new ArrayList<AlignmentAnnotation>();
+      final List<AlignmentAnnotation> result = new ArrayList<>();
       for (AlignmentAnnotation dsann : datasetAnnotations)
       {
         /*
@@ -1638,13 +1640,13 @@ public class AlignmentUtils
       throw new IllegalArgumentException(
               "IMPLEMENTATION ERROR: dataset.getDataset() must be null!");
     }
-    List<SequenceI> foundSeqs = new ArrayList<SequenceI>();
-    List<SequenceI> cdsSeqs = new ArrayList<SequenceI>();
+    List<SequenceI> foundSeqs = new ArrayList<>();
+    List<SequenceI> cdsSeqs = new ArrayList<>();
     List<AlignedCodonFrame> mappings = dataset.getCodonFrames();
     HashSet<SequenceI> productSeqs = null;
     if (products != null)
     {
-      productSeqs = new HashSet<SequenceI>();
+      productSeqs = new HashSet<>();
       for (SequenceI seq : products)
       {
         productSeqs.add(seq.getDatasetSequence() == null ? seq : seq
@@ -2055,8 +2057,8 @@ public class AlignmentUtils
           SequenceI contig, SequenceI proteinProduct, Mapping mapping)
   {
     // gather direct refs from contig congruent with mapping
-    List<DBRefEntry> direct = new ArrayList<DBRefEntry>();
-    HashSet<String> directSources = new HashSet<String>();
+    List<DBRefEntry> direct = new ArrayList<>();
+    HashSet<String> directSources = new HashSet<>();
     if (contig.getDBRefs() != null)
     {
       for (DBRefEntry dbr : contig.getDBRefs())
@@ -2076,7 +2078,7 @@ public class AlignmentUtils
     DBRefEntry[] onSource = DBRefUtils.selectRefs(
             proteinProduct.getDBRefs(),
             directSources.toArray(new String[0]));
-    List<DBRefEntry> propagated = new ArrayList<DBRefEntry>();
+    List<DBRefEntry> propagated = new ArrayList<>();
 
     // and generate appropriate mappings
     for (DBRefEntry cdsref : direct)
@@ -2255,7 +2257,7 @@ public class AlignmentUtils
       proteinStart++;
       proteinLength--;
     }
-    List<int[]> proteinRange = new ArrayList<int[]>();
+    List<int[]> proteinRange = new ArrayList<>();
 
     /*
      * dna length should map to protein (or protein plus stop codon)
@@ -2290,7 +2292,7 @@ public class AlignmentUtils
    */
   protected static List<int[]> findCdsPositions(SequenceI dnaSeq)
   {
-    List<int[]> result = new ArrayList<int[]>();
+    List<int[]> result = new ArrayList<>();
 
     List<SequenceFeature> sfs = dnaSeq.getFeatures().getFeaturesByOntology(
             SequenceOntologyI.CDS);
@@ -2428,10 +2430,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base + base2 + base3;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base1.equals(base))
             {
-              count++;
+              String codon = base + base2 + base3;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2450,10 +2456,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base1 + base + base3;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base2.equals(base))
             {
-              count++;
+              String codon = base1 + base + base3;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2472,10 +2482,14 @@ public class AlignmentUtils
         {
           for (String base : alleles.split(","))
           {
-            String codon = base1 + base2 + base;
-            if (addPeptideVariant(peptide, peptidePos, residue, var, codon))
+            if (!base3.equals(base))
             {
-              count++;
+              String codon = base1 + base2 + base;
+              if (addPeptideVariant(peptide, peptidePos, residue, var,
+                      codon))
+              {
+                count++;
+              }
             }
           }
         }
@@ -2507,57 +2521,71 @@ public class AlignmentUtils
      * e.g. multibase variants or HGMD_MUTATION etc
      * are currently ignored here
      */
-    String trans = codon.contains("-") ? "-"
+    String trans = codon.contains("-") ? null
             : (codon.length() > CODON_LENGTH ? null
                     : ResidueProperties.codonTranslate(codon));
-    if (trans != null && !trans.equals(residue))
+    if (trans == null)
+    {
+      return false;
+    }
+    String desc = codon;
+    String featureType = "";
+    if (trans.equals(residue))
+    {
+      featureType = SequenceOntologyI.SYNONYMOUS_VARIANT;
+    }
+    else if (ResidueProperties.STOP.equals(trans))
+    {
+      featureType = SequenceOntologyI.STOP_GAINED;
+    }
+    else
     {
       String residue3Char = StringUtils
               .toSentenceCase(ResidueProperties.aa2Triplet.get(residue));
       String trans3Char = StringUtils
               .toSentenceCase(ResidueProperties.aa2Triplet.get(trans));
-      String desc = "p." + residue3Char + peptidePos + trans3Char;
-      SequenceFeature sf = new SequenceFeature(
-              SequenceOntologyI.SEQUENCE_VARIANT, desc, peptidePos,
-              peptidePos, var.getSource());
-      StringBuilder attributes = new StringBuilder(32);
-      String id = (String) var.variant.getValue(ID);
-      if (id != null)
-      {
-        if (id.startsWith(SEQUENCE_VARIANT))
-        {
-          id = id.substring(SEQUENCE_VARIANT.length());
-        }
-        sf.setValue(ID, id);
-        attributes.append(ID).append("=").append(id);
-        // TODO handle other species variants JAL-2064
-        StringBuilder link = new StringBuilder(32);
-        try
-        {
-          link.append(desc).append(" ").append(id).append(
-                  "|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
-                  .append(URLEncoder.encode(id, "UTF-8"));
-          sf.addLink(link.toString());
-        } catch (UnsupportedEncodingException e)
-        {
-          // as if
-        }
-      }
-      String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
-      if (clinSig != null)
+      desc = "p." + residue3Char + peptidePos + trans3Char;
+      featureType = SequenceOntologyI.NONSYNONYMOUS_VARIANT;
+    }
+    SequenceFeature sf = new SequenceFeature(featureType, desc, peptidePos,
+            peptidePos, var.getSource());
+
+    StringBuilder attributes = new StringBuilder(32);
+    String id = (String) var.variant.getValue(ID);
+    if (id != null)
+    {
+      if (id.startsWith(SEQUENCE_VARIANT))
       {
-        sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
-        attributes.append(";").append(CLINICAL_SIGNIFICANCE).append("=")
-                .append(clinSig);
+        id = id.substring(SEQUENCE_VARIANT.length());
       }
-      peptide.addSequenceFeature(sf);
-      if (attributes.length() > 0)
+      sf.setValue(ID, id);
+      attributes.append(ID).append("=").append(id);
+      // TODO handle other species variants JAL-2064
+      StringBuilder link = new StringBuilder(32);
+      try
       {
-        sf.setAttributes(attributes.toString());
+        link.append(desc).append(" ").append(id).append(
+                "|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=")
+                .append(URLEncoder.encode(id, "UTF-8"));
+        sf.addLink(link.toString());
+      } catch (UnsupportedEncodingException e)
+      {
+        // as if
       }
-      return true;
     }
-    return false;
+    String clinSig = (String) var.variant.getValue(CLINICAL_SIGNIFICANCE);
+    if (clinSig != null)
+    {
+      sf.setValue(CLINICAL_SIGNIFICANCE, clinSig);
+      attributes.append(";").append(CLINICAL_SIGNIFICANCE).append("=")
+              .append(clinSig);
+    }
+    peptide.addSequenceFeature(sf);
+    if (attributes.length() > 0)
+    {
+      sf.setAttributes(attributes.toString());
+    }
+    return true;
   }
 
   /**
@@ -2579,7 +2607,7 @@ public class AlignmentUtils
      * map from peptide position to all variants of the codon which codes for it
      * LinkedHashMap ensures we keep the peptide features in sequence order
      */
-    LinkedHashMap<Integer, List<DnaVariant>[]> variants = new LinkedHashMap<Integer, List<DnaVariant>[]>();
+    LinkedHashMap<Integer, List<DnaVariant>[]> variants = new LinkedHashMap<>();
 
     List<SequenceFeature> dnaFeatures = dnaSeq.getFeatures()
             .getFeaturesByOntology(SequenceOntologyI.SEQUENCE_VARIANT);
@@ -2638,9 +2666,9 @@ public class AlignmentUtils
       if (codonVariants == null)
       {
         codonVariants = new ArrayList[CODON_LENGTH];
-        codonVariants[0] = new ArrayList<DnaVariant>();
-        codonVariants[1] = new ArrayList<DnaVariant>();
-        codonVariants[2] = new ArrayList<DnaVariant>();
+        codonVariants[0] = new ArrayList<>();
+        codonVariants[1] = new ArrayList<>();
+        codonVariants[2] = new ArrayList<>();
         variants.put(peptidePosition, codonVariants);
       }
 
@@ -2764,7 +2792,7 @@ public class AlignmentUtils
     /*
      * fancy case - aligning via mappings between sequences
      */
-    List<SequenceI> unmapped = new ArrayList<SequenceI>();
+    List<SequenceI> unmapped = new ArrayList<>();
     Map<Integer, Map<SequenceI, Character>> columnMap = buildMappedColumnsMap(
             unaligned, aligned, unmapped);
     int width = columnMap.size();
@@ -2839,7 +2867,7 @@ public class AlignmentUtils
     }
 
     // map from dataset sequence to alignment sequence(s)
-    Map<SequenceI, List<SequenceI>> alignedDatasets = new HashMap<SequenceI, List<SequenceI>>();
+    Map<SequenceI, List<SequenceI>> alignedDatasets = new HashMap<>();
     for (SequenceI seq : aligned.getSequences())
     {
       SequenceI ds = seq.getDatasetSequence();
@@ -2902,7 +2930,7 @@ public class AlignmentUtils
      * {unalignedSequence, characterPerSequence} at that position.
      * TreeMap keeps the entries in ascending column order. 
      */
-    SortedMap<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+    SortedMap<Integer, Map<SequenceI, Character>> map = new TreeMap<>();
 
     /*
      * record any sequences that have no mapping so can't be realigned
@@ -3007,7 +3035,7 @@ public class AlignmentUtils
             Map<SequenceI, Character> seqsMap = map.get(fromCol);
             if (seqsMap == null)
             {
-              seqsMap = new HashMap<SequenceI, Character>();
+              seqsMap = new HashMap<>();
               map.put(fromCol, seqsMap);
             }
             seqsMap.put(seq, seq.getCharAt(mappedCharPos - toStart));
index f3088ea..ef05a58 100644 (file)
@@ -161,7 +161,7 @@ public class Dna
 
     int s;
     int sSize = selection.size();
-    List<SequenceI> pepseqs = new ArrayList<SequenceI>();
+    List<SequenceI> pepseqs = new ArrayList<>();
     for (s = 0; s < sSize; s++)
     {
       SequenceI newseq = translateCodingRegion(selection.get(s),
@@ -213,7 +213,7 @@ public class Dna
       if (dnarefs != null)
       {
         // intersect with pep
-        List<DBRefEntry> mappedrefs = new ArrayList<DBRefEntry>();
+        List<DBRefEntry> mappedrefs = new ArrayList<>();
         DBRefEntry[] refs = dna.getDBRefs();
         for (int d = 0; d < refs.length; d++)
         {
@@ -391,7 +391,7 @@ public class Dna
           String seqstring, AlignedCodonFrame acf,
           List<SequenceI> proteinSeqs)
   {
-    List<int[]> skip = new ArrayList<int[]>();
+    List<int[]> skip = new ArrayList<>();
     int skipint[] = null;
     ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring
     // intervals
@@ -544,7 +544,7 @@ public class Dna
             skip.add(skipint);
             skipint = null;
           }
-          if (aa.equals("STOP"))
+          if (aa.equals(ResidueProperties.STOP))
           {
             aa = STOP_ASTERIX;
           }
@@ -800,7 +800,7 @@ public class Dna
   public AlignmentI reverseCdna(boolean complement)
   {
     int sSize = selection.size();
-    List<SequenceI> reversed = new ArrayList<SequenceI>();
+    List<SequenceI> reversed = new ArrayList<>();
     for (int s = 0; s < sSize; s++)
     {
       SequenceI newseq = reverseSequence(selection.get(s).getName(),
index 6d031b7..952f01e 100644 (file)
@@ -24,9 +24,6 @@ import jalview.datamodel.SequenceFeature;
 import jalview.io.gff.SequenceOntologyFactory;
 import jalview.io.gff.SequenceOntologyI;
 
-import java.util.HashMap;
-import java.util.Map;
-
 import com.stevesoft.pat.Regex;
 
 /**
@@ -47,13 +44,6 @@ public class EnsemblCdna extends EnsemblSeqProxy
   private static final Regex ACCESSION_REGEX = new Regex(
           "(ENS([A-Z]{3}|)[TG][0-9]{11}$)" + "|" + "(CCDS[0-9.]{3,}$)");
 
-  private static Map<String, String> params = new HashMap<String, String>();
-
-  static
-  {
-    params.put("object_type", "transcript");
-  }
-
   /*
    * fetch exon features on genomic sequence (to identify the cdna regions)
    * and cds and variation features (to retain)
@@ -139,13 +129,13 @@ public class EnsemblCdna extends EnsemblSeqProxy
   }
 
   /**
-   * Parameter object_type=cdna added to ensure cdna and not peptide is returned
-   * (JAL-2529)
+   * Parameter object_type=Transcaript added to ensure cdna and not peptide is
+   * returned (JAL-2529)
    */
   @Override
-  protected Map<String, String> getAdditionalParameters()
+  protected String getObjectType()
   {
-    return params;
+    return OBJECT_TYPE_TRANSCRIPT;
   }
 
 }
index 7570822..cb6f548 100644 (file)
@@ -82,7 +82,7 @@ class EnsemblFeatures extends EnsemblRestClient
   public AlignmentI getSequenceRecords(String query) throws IOException
   {
     // TODO: use a vararg String... for getSequenceRecords instead?
-    List<String> queries = new ArrayList<String>();
+    List<String> queries = new ArrayList<>();
     queries.add(query);
     FileParse fp = getSequenceReader(queries);
     if (fp == null || !fp.isValid())
@@ -109,9 +109,17 @@ class EnsemblFeatures extends EnsemblRestClient
     urlstring.append("?content-type=text/x-gff3");
 
     /*
+     * specify object_type=gene in case is shared by transcript and/or protein;
+     * currently only fetching features for gene sequences;
+     * refactor in future if needed to fetch for transcripts
+     */
+    urlstring.append("&").append(OBJECT_TYPE).append("=")
+            .append(OBJECT_TYPE_GENE);
+
+    /*
      * specify  features to retrieve
      * @see http://rest.ensembl.org/documentation/info/overlap_id
-     * could make the list a configurable entry in jalview.properties
+     * could make the list a configurable entry in .jalview_properties
      */
     for (EnsemblFeatureType feature : featuresWanted)
     {
index cdcfa96..7e6f653 100644 (file)
@@ -100,6 +100,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 +155,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)
@@ -235,7 +245,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()))
     {
@@ -370,7 +380,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)
     {
@@ -412,7 +422,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());
@@ -498,7 +508,7 @@ 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;
 
@@ -510,7 +520,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);
       }
@@ -547,8 +557,9 @@ public class EnsemblGene extends EnsemblSeqProxy
     if (SequenceOntologyFactory.getInstance().isA(sf.getType(),
             SequenceOntologyI.GENE))
     {
-      String id = (String) sf.getValue(ID);
-      if ((GENE_PREFIX + accId).equals(id))
+      // NB features as gff use 'ID'; rest services return as 'id'
+      String id = (String) sf.getValue("ID");
+      if ((GENE_PREFIX + accId).equalsIgnoreCase(id))
       {
         return true;
       }
@@ -575,7 +586,7 @@ public class EnsemblGene extends EnsemblSeqProxy
     if (isTranscript(type))
     {
       String parent = (String) sf.getValue(PARENT);
-      if (!(GENE_PREFIX + accessionId).equals(parent))
+      if (!(GENE_PREFIX + accessionId).equalsIgnoreCase(parent))
       {
         return false;
       }
index 458a233..bde3c0f 100644 (file)
@@ -103,7 +103,7 @@ public class EnsemblGenome extends EnsemblSeqProxy
   {
     if (isTranscript(sf.getType()))
     {
-      String id = (String) sf.getValue(ID);
+      String id = (String) sf.getValue("ID");
       if (("transcript:" + accId).equals(id))
       {
         return true;
index 0d1b554..f6b3a47 100644 (file)
@@ -32,14 +32,15 @@ import java.net.URL;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.function.Function;
 
 import org.json.simple.JSONObject;
 import org.json.simple.parser.JSONParser;
 import org.json.simple.parser.ParseException;
 
 /**
- * A client for the Ensembl lookup REST endpoint
+ * A client for the Ensembl /lookup REST endpoint, used to find the gene
+ * identifier given a gene, transcript or protein identifier, or to extract the
+ * species or chromosomal coordinates from the same service response
  * 
  * @author gmcarstairs
  */
@@ -47,14 +48,6 @@ public class EnsemblLookup extends EnsemblRestClient
 {
   private static final String SPECIES = "species";
 
-  private static final String PARENT = "Parent";
-
-  private static final String OBJECT_TYPE_TRANSLATION = "Translation";
-  private static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
-  private static final String ID = "id";
-  private static final String OBJECT_TYPE_GENE = "Gene";
-  private static final String OBJECT_TYPE = "object_type";
-
   /**
    * Default constructor (to use rest.ensembl.org)
    */
@@ -89,17 +82,26 @@ public class EnsemblLookup extends EnsemblRestClient
   protected URL getUrl(List<String> ids) throws MalformedURLException
   {
     String identifier = ids.get(0);
-    return getUrl(identifier);
+    return getUrl(identifier, null);
   }
 
   /**
+   * Gets the url for lookup of the given identifier, optionally with objectType
+   * also specified in the request
+   * 
    * @param identifier
+   * @param objectType
    * @return
    */
-  protected URL getUrl(String identifier)
+  protected URL getUrl(String identifier, String objectType)
   {
     String url = getDomain() + "/lookup/id/" + identifier
             + CONTENT_TYPE_JSON;
+    if (objectType != null)
+    {
+      url += "&" + OBJECT_TYPE + "=" + objectType;
+    }
+
     try
     {
       return new URL(url);
@@ -128,20 +130,15 @@ public class EnsemblLookup extends EnsemblRestClient
   }
 
   /**
-   * Calls the Ensembl lookup REST endpoint and returns
-   * <ul>
-   * <li>the 'id' for the identifier if its type is "Gene"</li>
-   * <li>the 'Parent' if its type is 'Transcript'</li>
-   * <ul>
-   * If the type is 'Translation', does a recursive call to this method, passing
-   * in the 'Parent' (transcript id).
+   * Returns the gene id related to the given identifier (which may be for a
+   * gene, transcript or protein)
    * 
    * @param identifier
    * @return
    */
   public String getGeneId(String identifier)
   {
-    return (String) getResult(identifier, br -> parseGeneId(br));
+    return parseGeneId(getResult(identifier, null));
   }
 
   /**
@@ -153,34 +150,45 @@ public class EnsemblLookup extends EnsemblRestClient
    */
   public String getSpecies(String identifier)
   {
-    return (String) getResult(identifier, br -> getAttribute(br, SPECIES));
+    String species = null;
+    JSONObject json = getResult(identifier, null);
+    if (json != null)
+    {
+      Object o = json.get(SPECIES);
+      if (o != null)
+      {
+        species = o.toString();
+      }
+    }
+    return species;
   }
 
   /**
-   * Calls the /lookup/id rest service and delegates parsing of the JSON
-   * response to the supplied parser
+   * Calls the /lookup/id rest service and returns the response as a JSONObject,
+   * or null if any error
    * 
    * @param identifier
-   * @param parser
+   * @param objectType
+   *          (optional)
    * @return
    */
-  protected Object getResult(String identifier,
-          Function<BufferedReader, Object> parser)
+  protected JSONObject getResult(String identifier, String objectType)
   {
     List<String> ids = Arrays.asList(new String[] { identifier });
 
     BufferedReader br = null;
     try
     {
-      URL url = getUrl(identifier);
+      URL url = getUrl(identifier, objectType);
       if (url != null)
       {
         br = getHttpResponse(url, ids);
       }
-      return br == null ? null : parser.apply(br);
-    } catch (IOException e)
+      return br == null ? null : (JSONObject) (new JSONParser().parse(br));
+    } catch (IOException | ParseException e)
     {
-      // ignore
+      System.err.println("Error parsing " + identifier + " lookup response "
+              + e.getMessage());
       return null;
     } finally
     {
@@ -198,74 +206,42 @@ public class EnsemblLookup extends EnsemblRestClient
   }
 
   /**
-   * Answers the value of 'attribute' from the JSON response, or null if not
-   * found
-   * 
-   * @param br
-   * @param attribute
-   * @return
-   */
-  protected String getAttribute(BufferedReader br, String attribute)
-  {
-    String value = null;
-    JSONParser jp = new JSONParser();
-    try
-    {
-      JSONObject val = (JSONObject) jp.parse(br);
-      value = val.get(attribute).toString();
-    } catch (ParseException | NullPointerException | IOException e)
-    {
-      // ignore
-    }
-    return value;
-  }
-
-  /**
    * Parses the JSON response and returns the gene identifier, or null if not
    * found. If the returned object_type is Gene, returns the id, if Transcript
    * returns the Parent. If it is Translation (peptide identifier), then the
-   * Parent is the transcript identifier, so we redo the search with this value.
+   * Parent is the transcript identifier, so we redo the search with this value,
+   * specifying that object_type should be Transcript.
    * 
-   * @param br
+   * @param jsonObject
    * @return
    */
-  protected String parseGeneId(BufferedReader br)
+  protected String parseGeneId(JSONObject json)
   {
+    if (json == null)
+    {
+      // e.g. lookup failed with 404 not found
+      return null;
+    }
+
     String geneId = null;
-    JSONParser jp = new JSONParser();
-    try
+    String type = json.get(OBJECT_TYPE).toString();
+    if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
     {
-      JSONObject val = (JSONObject) jp.parse(br);
-      String type = val.get(OBJECT_TYPE).toString();
-      if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
-      {
-        geneId = val.get(ID).toString();
-      }
-      else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
-      {
-        geneId = val.get(PARENT).toString();
-      }
-      else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
-      {
-        String transcriptId = val.get(PARENT).toString();
-        try
-        {
-          geneId = getGeneId(transcriptId);
-        } catch (StackOverflowError e)
-        {
-          /*
-           * unlikely data condition error!
-           */
-          System.err
-                  .println("** Ensembl lookup "
-                          + getUrl(transcriptId).toString()
-                          + " looping on Parent!");
-        }
-      }
-    } catch (ParseException | IOException e)
+      // got the gene - just returns its id
+      geneId = json.get(JSON_ID).toString();
+    }
+    else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
+    {
+      // got the transcript - return its (Gene) Parent
+      geneId = json.get(PARENT).toString();
+    }
+    else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
     {
-      // ignore
+      // got the protein - look up its Parent, restricted to type Transcript
+      String transcriptId = json.get(PARENT).toString();
+      geneId = parseGeneId(getResult(transcriptId, OBJECT_TYPE_TRANSCRIPT));
     }
+
     return geneId;
   }
 
@@ -278,7 +254,7 @@ public class EnsemblLookup extends EnsemblRestClient
    */
   public GeneLociI getGeneLoci(String geneId)
   {
-    return (GeneLociI) getResult(geneId, br -> parseGeneLoci(br));
+    return parseGeneLoci(getResult(geneId, OBJECT_TYPE_GENE));
   }
 
   /**
@@ -286,21 +262,24 @@ public class EnsemblLookup extends EnsemblRestClient
    * seq_region_name, start, end and returns an object that wraps them, or null
    * if unsuccessful
    * 
-   * @param br
+   * @param json
    * @return
    */
-  GeneLociI parseGeneLoci(BufferedReader br)
+  GeneLociI parseGeneLoci(JSONObject json)
   {
-    JSONParser jp = new JSONParser();
+    if (json == null)
+    {
+      return null;
+    }
+
     try
     {
-      JSONObject val = (JSONObject) jp.parse(br);
-      final String species = val.get("species").toString();
-      final String assembly = val.get("assembly_name").toString();
-      final String chromosome = val.get("seq_region_name").toString();
-      String strand = val.get("strand").toString();
-      int start = Integer.parseInt(val.get("start").toString());
-      int end = Integer.parseInt(val.get("end").toString());
+      final String species = json.get("species").toString();
+      final String assembly = json.get("assembly_name").toString();
+      final String chromosome = json.get("seq_region_name").toString();
+      String strand = json.get("strand").toString();
+      int start = Integer.parseInt(json.get("start").toString());
+      int end = Integer.parseInt(json.get("end").toString());
       int fromEnd = end - start + 1;
       boolean reverseStrand = "-1".equals(strand);
       int toStart = reverseStrand ? end : start;
@@ -337,10 +316,10 @@ public class EnsemblLookup extends EnsemblRestClient
           return map;
         }
       };
-    } catch (ParseException | NullPointerException | IOException
-            | NumberFormatException | ClassCastException e)
+    } catch (NullPointerException | NumberFormatException e)
     {
       Cache.log.error("Error looking up gene loci: " + e.getMessage());
+      e.printStackTrace();
     }
     return null;
   }
index 35ceea3..9229379 100644 (file)
@@ -49,8 +49,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
 
 /**
  * Base class for Ensembl sequence fetchers
@@ -60,10 +58,6 @@ import java.util.Map.Entry;
  */
 public abstract class EnsemblSeqProxy extends EnsemblRestClient
 {
-  protected static final String PARENT = "Parent";
-
-  protected static final String ID = "ID";
-
   protected static final String NAME = "Name";
 
   protected static final String DESCRIPTION = "description";
@@ -208,7 +202,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     try
     {
       /*
-       * get 'dummy' genomic sequence with exon, cds and variation features
+       * get 'dummy' genomic sequence with gene, transcript, 
+       * exon, cds and variation features
        */
       SequenceI genomicSequence = null;
       EnsemblFeatures gffFetcher = new EnsemblFeatures(getDomain());
@@ -224,7 +219,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
         /*
          * transfer features to the query sequence
          */
-        SequenceI querySeq = alignment.findName(accId);
+        SequenceI querySeq = alignment.findName(accId, true);
         if (transferFeatures(accId, genomicSequence, querySeq))
         {
 
@@ -471,14 +466,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
     urlstring.append("?type=").append(getSourceEnsemblType().getType());
     urlstring.append(("&Accept=text/x-fasta"));
 
-    Map<String, String> params = getAdditionalParameters();
-    if (params != null)
+    String objectType = getObjectType();
+    if (objectType != null)
     {
-      for (Entry<String, String> entry : params.entrySet())
-      {
-        urlstring.append("&").append(entry.getKey()).append("=")
-                .append(entry.getValue());
-      }
+      urlstring.append("&").append(OBJECT_TYPE).append("=")
+              .append(objectType);
     }
 
     URL url = new URL(urlstring.toString());
@@ -486,11 +478,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   }
 
   /**
-   * Override this method to add any additional x=y URL parameters needed
+   * Override this method to specify object_type request parameter
    * 
    * @return
    */
-  protected Map<String, String> getAdditionalParameters()
+  protected String getObjectType()
   {
     return null;
   }
@@ -559,7 +551,6 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   protected MapList getGenomicRangesFromFeatures(SequenceI sourceSequence,
           String accId, int start)
   {
-    // SequenceFeature[] sfs = sourceSequence.getSequenceFeatures();
     List<SequenceFeature> sfs = sourceSequence.getFeatures()
             .getPositionalFeatures();
     if (sfs.isEmpty())
@@ -571,7 +562,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
      * generously initial size for number of cds regions
      * (worst case titin Q8WZ42 has c. 313 exons)
      */
-    List<int[]> regions = new ArrayList<int[]>(100);
+    List<int[]> regions = new ArrayList<>(100);
     int mappedLength = 0;
     int direction = 1; // forward
     boolean directionSet = false;
@@ -871,7 +862,8 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   {
     String parent = (String) sf.getValue(PARENT);
     // using contains to allow for prefix "gene:", "transcript:" etc
-    if (parent != null && !parent.contains(identifier))
+    if (parent != null
+            && !parent.toUpperCase().contains(identifier.toUpperCase()))
     {
       // this genomic feature belongs to a different transcript
       return false;
@@ -899,14 +891,14 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
   protected List<SequenceFeature> findFeatures(SequenceI sequence,
           String term, String parentId)
   {
-    List<SequenceFeature> result = new ArrayList<SequenceFeature>();
+    List<SequenceFeature> result = new ArrayList<>();
 
     List<SequenceFeature> sfs = sequence.getFeatures()
             .getFeaturesByOntology(term);
     for (SequenceFeature sf : sfs)
     {
       String parent = (String) sf.getValue(PARENT);
-      if (parent != null && parent.equals(parentId))
+      if (parent != null && parent.equalsIgnoreCase(parentId))
       {
         result.add(sf);
       }
index 598dba1..cfb3c6d 100644 (file)
@@ -45,6 +45,18 @@ abstract class EnsemblSequenceFetcher extends DbSourceProxyImpl
 
   protected static final String ENSEMBL_REST = "http://rest.ensembl.org";
 
+  protected static final String OBJECT_TYPE_TRANSLATION = "Translation";
+
+  protected static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
+
+  protected static final String OBJECT_TYPE_GENE = "Gene";
+
+  protected static final String PARENT = "Parent";
+
+  protected static final String JSON_ID = "id";
+
+  protected static final String OBJECT_TYPE = "object_type";
+
   /*
    * possible values for the 'feature' parameter of the /overlap REST service
    * @see http://rest.ensembl.org/documentation/info/overlap_id
index 65be906..40d6cad 100644 (file)
@@ -44,8 +44,6 @@ public class EnsemblSymbol extends EnsemblXref
 {
   private static final String GENE = "gene";
   private static final String TYPE = "type";
-  private static final String ID = "id";
-
   /**
    * Constructor given the target domain to fetch data from
    * 
@@ -77,7 +75,7 @@ public class EnsemblSymbol extends EnsemblXref
       while (rvals.hasNext())
       {
         JSONObject val = (JSONObject) rvals.next();
-        String id = val.get(ID).toString();
+        String id = val.get(JSON_ID).toString();
         String type = val.get(TYPE).toString();
         if (id != null && GENE.equals(type))
         {
index 9802d4b..86710e1 100644 (file)
@@ -92,7 +92,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
   protected JTabbedPane tabs = new JTabbedPane();
   protected IProgressIndicator progressIndicator;
 
-  protected JComboBox<FTSDataColumnI> cmb_searchTarget = new JComboBox<FTSDataColumnI>();
+  protected JComboBox<FTSDataColumnI> cmb_searchTarget = new JComboBox<>();
 
   protected JButton btn_ok = new JButton();
 
@@ -151,7 +151,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
 
   protected int pageLimit;
 
-  protected HashSet<String> paginatorCart = new HashSet<String>();
+  protected HashSet<String> paginatorCart = new HashSet<>();
 
   private static final int MIN_WIDTH = 670;
 
@@ -293,7 +293,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
   private void jbInit() throws Exception
   {
 
-    txt_search = new JvCacheableInputBox<String>(getCacheKey());
+    txt_search = new JvCacheableInputBox<>(getCacheKey());
     populateCmbSearchTargetOptions();
     Integer width = getTempUserPrefs().get("FTSPanel.width") == null ? 800
             : getTempUserPrefs().get("FTSPanel.width");
@@ -681,7 +681,8 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     if (tabs != null)
     {
       tabs.setOpaque(true);
-      tabs.insertTab("Free Text Search", null, this, "", 0);
+      tabs.insertTab(MessageManager.getString("label.free_text_search"),
+              null, this, "", 0);
       mainFrame.setContentPane(tabs);
       tabs.setVisible(true);
     }
@@ -871,7 +872,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
    */
   public void populateCmbSearchTargetOptions()
   {
-    List<FTSDataColumnI> searchableTargets = new ArrayList<FTSDataColumnI>();
+    List<FTSDataColumnI> searchableTargets = new ArrayList<>();
     try
     {
       Collection<FTSDataColumnI> foundFTSTargets = getFTSRestClient()
index 285e574..85f2498 100644 (file)
@@ -176,10 +176,14 @@ public class CrossRefAction implements Runnable
       /*
        * copy feature rendering settings to split frame
        */
-      newFrame.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
-              .transferSettings(myFeatureStyling);
-      copyThis.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer()
-              .transferSettings(myFeatureStyling);
+      FeatureRenderer fr1 = newFrame.alignPanel.getSeqPanel().seqCanvas
+              .getFeatureRenderer();
+      fr1.transferSettings(myFeatureStyling);
+      fr1.findAllFeatures(true);
+      FeatureRenderer fr2 = copyThis.alignPanel.getSeqPanel().seqCanvas
+              .getFeatureRenderer();
+      fr2.transferSettings(myFeatureStyling);
+      fr2.findAllFeatures(true);
 
       /*
        * apply 'database source' feature configuration
index 7c386f1..217f653 100644 (file)
@@ -525,7 +525,7 @@ public class StructureChooser extends GStructureChooser
    * structures
    */
   protected void populateFilterComboBox(boolean haveData,
-          boolean cachedPDBExists)
+          boolean cachedPDBExist)
   {
     /*
      * temporarily suspend the change listener behaviour
@@ -535,25 +535,33 @@ public class StructureChooser extends GStructureChooser
     cmb_filterOption.removeAllItems();
     if (haveData)
     {
-      cmb_filterOption.addItem(new FilterOption("Best Quality",
+      cmb_filterOption.addItem(new FilterOption(
+              MessageManager.getString("label.best_quality"),
               "overall_quality", VIEWS_FILTER, false));
-      cmb_filterOption.addItem(new FilterOption("Best Resolution",
+      cmb_filterOption.addItem(new FilterOption(
+              MessageManager.getString("label.best_resolution"),
               "resolution", VIEWS_FILTER, false));
-      cmb_filterOption.addItem(new FilterOption("Most Protein Chain",
+      cmb_filterOption.addItem(new FilterOption(
+              MessageManager.getString("label.most_protein_chain"),
               "number_of_protein_chains", VIEWS_FILTER, false));
-      cmb_filterOption.addItem(new FilterOption("Most Bound Molecules",
+      cmb_filterOption.addItem(new FilterOption(
+              MessageManager.getString("label.most_bound_molecules"),
               "number_of_bound_molecules", VIEWS_FILTER, false));
-      cmb_filterOption.addItem(new FilterOption("Most Polymer Residues",
+      cmb_filterOption.addItem(new FilterOption(
+              MessageManager.getString("label.most_polymer_residues"),
               "number_of_polymer_residues", VIEWS_FILTER, true));
     }
     cmb_filterOption.addItem(
-            new FilterOption("Enter PDB Id", "-", VIEWS_ENTER_ID, false));
+            new FilterOption(MessageManager.getString("label.enter_pdb_id"),
+                    "-", VIEWS_ENTER_ID, false));
     cmb_filterOption.addItem(
-            new FilterOption("From File", "-", VIEWS_FROM_FILE, false));
+            new FilterOption(MessageManager.getString("label.from_file"),
+                    "-", VIEWS_FROM_FILE, false));
 
-    if (cachedPDBExists)
+    if (cachedPDBExist)
     {
-      FilterOption cachedOption = new FilterOption("Cached Structures",
+      FilterOption cachedOption = new FilterOption(
+              MessageManager.getString("label.cached_structures"),
               "-", VIEWS_LOCAL_PDB, false);
       cmb_filterOption.addItem(cachedOption);
       cmb_filterOption.setSelectedItem(cachedOption);
index c0570e0..307e1d1 100644 (file)
@@ -42,6 +42,15 @@ public interface SequenceOntologyI
   // SO:0001060
   public static final String SEQUENCE_VARIANT = "sequence_variant";
 
+  // SO:0001819
+  public static final String SYNONYMOUS_VARIANT = "synonymous_variant";
+
+  // SO:0001992
+  public static final String NONSYNONYMOUS_VARIANT = "nonsynonymous_variant";
+
+  // SO:0001587
+  public static final String STOP_GAINED = "stop_gained";
+
   // SO:0000147
   public static final String EXON = "exon";
 
index 7c4672a..9bcaa5a 100644 (file)
@@ -91,7 +91,7 @@ public abstract class GStructureChooser extends JPanel
 
   protected JInternalFrame mainFrame = new JInternalFrame(frameTitle);
 
-  protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<FilterOption>();
+  protected JComboBox<FilterOption> cmb_filterOption = new JComboBox<>();
 
   protected AlignmentPanel ap;
 
@@ -182,7 +182,7 @@ public abstract class GStructureChooser extends JPanel
 
   protected FTSDataColumnI[] previousWantedFields;
 
-  protected static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+  protected static Map<String, Integer> tempUserPrefs = new HashMap<>();
 
   private JTable tbl_summary = new JTable()
   {
@@ -474,7 +474,7 @@ public abstract class GStructureChooser extends JPanel
     chk_rememberSettings.setFont(new java.awt.Font("Verdana", 0, 12));
     chk_rememberSettings.setVisible(false);
     txt_search.setToolTipText(JvSwingUtils.wrapTooltip(true,
-            MessageManager.getString("label.enter_pdb_id")));
+            MessageManager.getString("label.enter_pdb_id_tip")));
     cmb_filterOption.setToolTipText(
             MessageManager.getString("info.select_filter_option"));
     txt_search.getDocument().addDocumentListener(new DocumentListener()
@@ -803,7 +803,7 @@ public abstract class GStructureChooser extends JPanel
    */
   public class AssciateSeqPanel extends JPanel implements ItemListener
   {
-    private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<AssociateSeqOptions>();
+    private JComboBox<AssociateSeqOptions> cmb_assSeq = new JComboBox<>();
 
     private JLabel lbl_associateSeq = new JLabel();
 
index 55df1d1..a4e6480 100755 (executable)
@@ -39,14 +39,14 @@ public class ResidueProperties
 
   public static final int[] purinepyrimidineIndex;
 
-  public static final Map<String, Integer> aa3Hash = new HashMap<String, Integer>();
+  public static final Map<String, Integer> aa3Hash = new HashMap<>();
 
-  public static final Map<String, String> aa2Triplet = new HashMap<String, String>();
+  public static final Map<String, String> aa2Triplet = new HashMap<>();
 
-  public static final Map<String, String> nucleotideName = new HashMap<String, String>();
+  public static final Map<String, String> nucleotideName = new HashMap<>();
 
   // lookup from modified amino acid (e.g. MSE) to canonical form (e.g. MET)
-  public static final Map<String, String> modifications = new HashMap<String, String>();
+  public static final Map<String, String> modifications = new HashMap<>();
 
   static
   {
@@ -496,25 +496,27 @@ public class ResidueProperties
    * Color.white, // R Color.white, // Y Color.white, // N Color.white, // Gap
    */
 
-  public static List<String> STOP = Arrays.asList("TGA", "TAA", "TAG");
+  public static String STOP = "STOP";
+
+  public static List<String> STOP_CODONS = Arrays.asList("TGA", "TAA", "TAG");
 
   public static String START = "ATG";
 
   /**
    * Nucleotide Ambiguity Codes
    */
-  public static final Map<String, String[]> ambiguityCodes = new Hashtable<String, String[]>();
+  public static final Map<String, String[]> ambiguityCodes = new Hashtable<>();
 
   /**
    * Codon triplets with additional symbols for unambiguous codons that include
    * ambiguity codes
    */
-  public static final Hashtable<String, String> codonHash2 = new Hashtable<String, String>();
+  public static final Hashtable<String, String> codonHash2 = new Hashtable<>();
 
   /**
    * all ambiguity codes for a given base
    */
-  public final static Hashtable<String, List<String>> _ambiguityCodes = new Hashtable<String, List<String>>();
+  public final static Hashtable<String, List<String>> _ambiguityCodes = new Hashtable<>();
 
   static
   {
@@ -638,7 +640,7 @@ public class ResidueProperties
         List<String> codesfor = _ambiguityCodes.get(r);
         if (codesfor == null)
         {
-          _ambiguityCodes.put(r, codesfor = new ArrayList<String>());
+          _ambiguityCodes.put(r, codesfor = new ArrayList<>());
         }
         if (!codesfor.contains(acode.getKey()))
         {
@@ -755,27 +757,27 @@ public class ResidueProperties
   }
 
   // Stores residue codes/names and colours and other things
-  public static Map<String, Map<String, Integer>> propHash = new Hashtable<String, Map<String, Integer>>();
+  public static Map<String, Map<String, Integer>> propHash = new Hashtable<>();
 
-  public static Map<String, Integer> hydrophobic = new Hashtable<String, Integer>();
+  public static Map<String, Integer> hydrophobic = new Hashtable<>();
 
-  public static Map<String, Integer> polar = new Hashtable<String, Integer>();
+  public static Map<String, Integer> polar = new Hashtable<>();
 
-  public static Map<String, Integer> small = new Hashtable<String, Integer>();
+  public static Map<String, Integer> small = new Hashtable<>();
 
-  public static Map<String, Integer> positive = new Hashtable<String, Integer>();
+  public static Map<String, Integer> positive = new Hashtable<>();
 
-  public static Map<String, Integer> negative = new Hashtable<String, Integer>();
+  public static Map<String, Integer> negative = new Hashtable<>();
 
-  public static Map<String, Integer> charged = new Hashtable<String, Integer>();
+  public static Map<String, Integer> charged = new Hashtable<>();
 
-  public static Map<String, Integer> aromatic = new Hashtable<String, Integer>();
+  public static Map<String, Integer> aromatic = new Hashtable<>();
 
-  public static Map<String, Integer> aliphatic = new Hashtable<String, Integer>();
+  public static Map<String, Integer> aliphatic = new Hashtable<>();
 
-  public static Map<String, Integer> tiny = new Hashtable<String, Integer>();
+  public static Map<String, Integer> tiny = new Hashtable<>();
 
-  public static Map<String, Integer> proline = new Hashtable<String, Integer>();
+  public static Map<String, Integer> proline = new Hashtable<>();
 
   static
   {
@@ -1149,7 +1151,7 @@ public class ResidueProperties
     String cdn = codonHash2.get(lccodon.toUpperCase());
     if ("*".equals(cdn))
     {
-      return "STOP";
+      return STOP;
     }
     return cdn;
   }
@@ -1157,7 +1159,7 @@ public class ResidueProperties
   public static Hashtable<String, String> toDssp3State;
   static
   {
-    toDssp3State = new Hashtable<String, String>();
+    toDssp3State = new Hashtable<>();
     toDssp3State.put("H", "H");
     toDssp3State.put("E", "E");
     toDssp3State.put("C", " ");
@@ -2525,7 +2527,7 @@ public class ResidueProperties
   // / cut here
   public static void main(String[] args)
   {
-    Hashtable<String, Vector<String>> aaProps = new Hashtable<String, Vector<String>>();
+    Hashtable<String, Vector<String>> aaProps = new Hashtable<>();
     System.out.println("my %aa = {");
     // invert property hashes
     for (String pname : propHash.keySet())
@@ -2536,7 +2538,7 @@ public class ResidueProperties
         Vector<String> aprops = aaProps.get(rname);
         if (aprops == null)
         {
-          aprops = new Vector<String>();
+          aprops = new Vector<>();
           aaProps.put(rname, aprops);
         }
         Integer hasprop = phash.get(rname);
@@ -2578,7 +2580,7 @@ public class ResidueProperties
   public static List<String> getResidues(boolean forNucleotide,
           boolean includeAmbiguous)
   {
-    List<String> result = new ArrayList<String>();
+    List<String> result = new ArrayList<>();
     if (forNucleotide)
     {
       for (String nuc : nucleotideName.keySet())
index 1bff8bf..be6ba60 100644 (file)
@@ -263,14 +263,14 @@ public class AlignmentUtilsTests
   @Test(groups = { "Functional" })
   public void testMapProteinAlignmentToCdna_noXrefs() throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR
     dnaseqs.add(new Sequence("EMBL|A22222", "GAGATACAA")); // = EIQ
     dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ
@@ -507,7 +507,7 @@ public class AlignmentUtilsTests
     acf.addMap(dna1.getDatasetSequence(), prot1.getDatasetSequence(), map);
     acf.addMap(dna2.getDatasetSequence(), prot2.getDatasetSequence(), map);
     acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map);
-    ArrayList<AlignedCodonFrame> acfs = new ArrayList<AlignedCodonFrame>();
+    ArrayList<AlignedCodonFrame> acfs = new ArrayList<>();
     acfs.add(acf);
     protein.setCodonFrames(acfs);
 
@@ -605,14 +605,14 @@ public class AlignmentUtilsTests
   public void testMapProteinAlignmentToCdna_withStartAndStopCodons()
           throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     // start + SAR:
     dnaseqs.add(new Sequence("EMBL|A11111", "ATGTCAGCACGC"));
     // = EIQ + stop
@@ -697,14 +697,14 @@ public class AlignmentUtilsTests
   @Test(groups = { "Functional" })
   public void testMapProteinAlignmentToCdna_withXrefs() throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12347", "SAR"));
     AlignmentI protein = new Alignment(protseqs.toArray(new SequenceI[3]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "TCAGCACGC")); // = SAR
     dnaseqs.add(new Sequence("EMBL|A22222", "ATGGAGATACAA")); // = start + EIQ
     dnaseqs.add(new Sequence("EMBL|A33333", "GAAATCCAG")); // = EIQ
@@ -774,14 +774,14 @@ public class AlignmentUtilsTests
   public void testMapProteinAlignmentToCdna_prioritiseXrefs()
           throws IOException
   {
-    List<SequenceI> protseqs = new ArrayList<SequenceI>();
+    List<SequenceI> protseqs = new ArrayList<>();
     protseqs.add(new Sequence("UNIPROT|V12345", "EIQ"));
     protseqs.add(new Sequence("UNIPROT|V12346", "EIQ"));
     AlignmentI protein = new Alignment(
             protseqs.toArray(new SequenceI[protseqs.size()]));
     protein.setDataset(null);
 
-    List<SequenceI> dnaseqs = new ArrayList<SequenceI>();
+    List<SequenceI> dnaseqs = new ArrayList<>();
     dnaseqs.add(new Sequence("EMBL|A11111", "GAAATCCAG")); // = EIQ
     dnaseqs.add(new Sequence("EMBL|A22222", "GAAATTCAG")); // = EIQ
     AlignmentI cdna = new Alignment(dnaseqs.toArray(new SequenceI[dnaseqs
@@ -848,8 +848,8 @@ public class AlignmentUtilsTests
     al.addAnnotation(ann4); // Temp for seq1
     al.addAnnotation(ann5); // Temp for seq2
     al.addAnnotation(ann6); // Temp for no sequence
-    List<String> types = new ArrayList<String>();
-    List<SequenceI> scope = new ArrayList<SequenceI>();
+    List<String> types = new ArrayList<>();
+    List<SequenceI> scope = new ArrayList<>();
 
     /*
      * Set all sequence related Structure to hidden (ann1, ann2)
@@ -1783,7 +1783,7 @@ public class AlignmentUtilsTests
     map = new MapList(new int[] { 9, 11 }, new int[] { 2, 2 }, 3, 1);
     acf.addMap(dna3.getDatasetSequence(), prot3.getDatasetSequence(), map);
 
-    ArrayList<AlignedCodonFrame> acfs = new ArrayList<AlignedCodonFrame>();
+    ArrayList<AlignedCodonFrame> acfs = new ArrayList<>();
     acfs.add(acf);
     protein.setCodonFrames(acfs);
 
@@ -1932,6 +1932,7 @@ public class AlignmentUtilsTests
     sf6.setValue("alleles", "g, a"); // should force to upper-case
     sf6.setValue("ID", "sequence_variant:rs758803216");
     dna.addSequenceFeature(sf6);
+
     SequenceFeature sf7 = new SequenceFeature("sequence_variant", "", 15,
             15, 0f, null);
     sf7.setValue("alleles", "A, T");
@@ -2021,6 +2022,7 @@ public class AlignmentUtilsTests
      * variants:
      *           GAA -> E             source: Ensembl
      *           CAA -> Q             source: dbSNP
+     *           TAA -> STOP          source: dnSNP
      *           AAG synonymous       source: COSMIC
      *           AAT -> N             source: Ensembl
      *           ...TTC synonymous    source: dbSNP
@@ -2036,39 +2038,50 @@ public class AlignmentUtilsTests
     String ensembl = "Ensembl";
     String dbSnp = "dbSNP";
     String cosmic = "COSMIC";
+
     SequenceFeature sf1 = new SequenceFeature("sequence_variant", "", 1, 1,
             0f, ensembl);
-    sf1.setValue("alleles", "A,G"); // GAA -> E
+    sf1.setValue("alleles", "A,G"); // AAA -> GAA -> K/E
     sf1.setValue("ID", "var1.125A>G");
+
     SequenceFeature sf2 = new SequenceFeature("sequence_variant", "", 1, 1,
             0f, dbSnp);
-    sf2.setValue("alleles", "A,C"); // CAA -> Q
+    sf2.setValue("alleles", "A,C"); // AAA -> CAA -> K/Q
     sf2.setValue("ID", "var2");
     sf2.setValue("clinical_significance", "Dodgy");
-    SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 3, 3,
-            0f, cosmic);
-    sf3.setValue("alleles", "A,G"); // synonymous
+
+    SequenceFeature sf3 = new SequenceFeature("sequence_variant", "", 1, 1,
+            0f, dbSnp);
+    sf3.setValue("alleles", "A,T"); // AAA -> TAA -> stop codon
     sf3.setValue("ID", "var3");
-    sf3.setValue("clinical_significance", "None");
+    sf3.setValue("clinical_significance", "Bad");
+
     SequenceFeature sf4 = new SequenceFeature("sequence_variant", "", 3, 3,
+            0f, cosmic);
+    sf4.setValue("alleles", "A,G"); // AAA -> AAG synonymous
+    sf4.setValue("ID", "var4");
+    sf4.setValue("clinical_significance", "None");
+
+    SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 3, 3,
             0f, ensembl);
-    sf4.setValue("alleles", "A,T"); // AAT -> N
-    sf4.setValue("ID", "sequence_variant:var4"); // prefix gets stripped off
-    sf4.setValue("clinical_significance", "Benign");
-    SequenceFeature sf5 = new SequenceFeature("sequence_variant", "", 6, 6,
+    sf5.setValue("alleles", "A,T"); // AAA -> AAT -> K/N
+    sf5.setValue("ID", "sequence_variant:var5"); // prefix gets stripped off
+    sf5.setValue("clinical_significance", "Benign");
+
+    SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 6, 6,
             0f, dbSnp);
-    sf5.setValue("alleles", "T,C"); // synonymous
-    sf5.setValue("ID", "var5");
-    sf5.setValue("clinical_significance", "Bad");
-    SequenceFeature sf6 = new SequenceFeature("sequence_variant", "", 8, 8,
-            0f, cosmic);
-    sf6.setValue("alleles", "C,A,G"); // CAC,CGC -> H,R
+    sf6.setValue("alleles", "T,C"); // TTT -> TTC synonymous
     sf6.setValue("ID", "var6");
-    sf6.setValue("clinical_significance", "Good");
 
-    List<DnaVariant> codon1Variants = new ArrayList<DnaVariant>();
-    List<DnaVariant> codon2Variants = new ArrayList<DnaVariant>();
-    List<DnaVariant> codon3Variants = new ArrayList<DnaVariant>();
+    SequenceFeature sf7 = new SequenceFeature("sequence_variant", "", 8, 8,
+            0f, cosmic);
+    sf7.setValue("alleles", "C,A,G"); // CCC -> CAC,CGC -> P/H/R
+    sf7.setValue("ID", "var7");
+    sf7.setValue("clinical_significance", "Good");
+
+    List<DnaVariant> codon1Variants = new ArrayList<>();
+    List<DnaVariant> codon2Variants = new ArrayList<>();
+    List<DnaVariant> codon3Variants = new ArrayList<>();
     List<DnaVariant> codonVariants[] = new ArrayList[3];
     codonVariants[0] = codon1Variants;
     codonVariants[1] = codon2Variants;
@@ -2079,10 +2092,11 @@ public class AlignmentUtilsTests
      */
     codon1Variants.add(new DnaVariant("A", sf1));
     codon1Variants.add(new DnaVariant("A", sf2));
+    codon1Variants.add(new DnaVariant("A", sf3));
     codon2Variants.add(new DnaVariant("A"));
-    codon2Variants.add(new DnaVariant("A"));
-    codon3Variants.add(new DnaVariant("A", sf3));
+    // codon2Variants.add(new DnaVariant("A"));
     codon3Variants.add(new DnaVariant("A", sf4));
+    codon3Variants.add(new DnaVariant("A", sf5));
     AlignmentUtils.computePeptideVariants(peptide, 1, codonVariants);
 
     /*
@@ -2093,7 +2107,7 @@ public class AlignmentUtilsTests
     codon3Variants.clear();
     codon1Variants.add(new DnaVariant("T"));
     codon2Variants.add(new DnaVariant("T"));
-    codon3Variants.add(new DnaVariant("T", sf5));
+    codon3Variants.add(new DnaVariant("T", sf6));
     AlignmentUtils.computePeptideVariants(peptide, 2, codonVariants);
 
     /*
@@ -2103,7 +2117,7 @@ public class AlignmentUtilsTests
     codon2Variants.clear();
     codon3Variants.clear();
     codon1Variants.add(new DnaVariant("C"));
-    codon2Variants.add(new DnaVariant("C", sf6));
+    codon2Variants.add(new DnaVariant("C", sf7));
     codon3Variants.add(new DnaVariant("C"));
     AlignmentUtils.computePeptideVariants(peptide, 3, codonVariants);
 
@@ -2111,35 +2125,43 @@ public class AlignmentUtilsTests
      * verify added sequence features for
      * var1 K -> E Ensembl
      * var2 K -> Q dbSNP
-     * var4 K -> N Ensembl
-     * var6 P -> H COSMIC
-     * var6 P -> R COSMIC
+     * var3 K -> stop
+     * var4 synonymous
+     * var5 K -> N Ensembl
+     * var6 synonymous
+     * var7 P -> H COSMIC
+     * var8 P -> R COSMIC
      */
     List<SequenceFeature> sfs = peptide.getSequenceFeatures();
     SequenceFeatures.sortFeatures(sfs, true);
-    assertEquals(5, sfs.size());
+    assertEquals(8, sfs.size());
 
     /*
      * features are sorted by start position ascending, but in no
      * particular order where start positions match; asserts here
      * simply match the data returned (the order is not important)
      */
+    // AAA -> AAT -> K/N
     SequenceFeature sf = sfs.get(0);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Asn", sf.getDescription());
-    assertEquals("var4", sf.getValue("ID"));
+    assertEquals("var5", sf.getValue("ID"));
     assertEquals("Benign", sf.getValue("clinical_significance"));
-    assertEquals("ID=var4;clinical_significance=Benign", sf.getAttributes());
+    assertEquals("ID=var5;clinical_significance=Benign",
+            sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Lys1Asn var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4",
+            "p.Lys1Asn var5|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var5",
             sf.links.get(0));
     assertEquals(ensembl, sf.getFeatureGroup());
 
+    // AAA -> CAA -> K/Q
     sf = sfs.get(1);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Gln", sf.getDescription());
     assertEquals("var2", sf.getValue("ID"));
     assertEquals("Dodgy", sf.getValue("clinical_significance"));
@@ -2150,9 +2172,11 @@ public class AlignmentUtilsTests
             sf.links.get(0));
     assertEquals(dbSnp, sf.getFeatureGroup());
 
+    // AAA -> GAA -> K/E
     sf = sfs.get(2);
     assertEquals(1, sf.getBegin());
     assertEquals(1, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Lys1Glu", sf.getDescription());
     assertEquals("var1.125A>G", sf.getValue("ID"));
     assertNull(sf.getValue("clinical_significance"));
@@ -2164,30 +2188,79 @@ public class AlignmentUtilsTests
             sf.links.get(0));
     assertEquals(ensembl, sf.getFeatureGroup());
 
+    // AAA -> TAA -> stop codon
     sf = sfs.get(3);
+    assertEquals(1, sf.getBegin());
+    assertEquals(1, sf.getEnd());
+    assertEquals("stop_gained", sf.getType());
+    assertEquals("TAA", sf.getDescription());
+    assertEquals("var3", sf.getValue("ID"));
+    assertEquals("Bad", sf.getValue("clinical_significance"));
+    assertEquals("ID=var3;clinical_significance=Bad", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "TAA var3|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var3",
+            sf.links.get(0));
+    assertEquals(dbSnp, sf.getFeatureGroup());
+
+    // AAA -> AAG synonymous
+    sf = sfs.get(4);
+    assertEquals(1, sf.getBegin());
+    assertEquals(1, sf.getEnd());
+    assertEquals("synonymous_variant", sf.getType());
+    assertEquals("AAG", sf.getDescription());
+    assertEquals("var4", sf.getValue("ID"));
+    assertEquals("None", sf.getValue("clinical_significance"));
+    assertEquals("ID=var4;clinical_significance=None", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "AAG var4|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var4",
+            sf.links.get(0));
+    assertEquals(cosmic, sf.getFeatureGroup());
+
+    // TTT -> TTC synonymous
+    sf = sfs.get(5);
+    assertEquals(2, sf.getBegin());
+    assertEquals(2, sf.getEnd());
+    assertEquals("synonymous_variant", sf.getType());
+    assertEquals("TTC", sf.getDescription());
+    assertEquals("var6", sf.getValue("ID"));
+    assertNull(sf.getValue("clinical_significance"));
+    assertEquals("ID=var6", sf.getAttributes());
+    assertEquals(1, sf.links.size());
+    assertEquals(
+            "TTC var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            sf.links.get(0));
+    assertEquals(dbSnp, sf.getFeatureGroup());
+
+    // var7 generates two distinct protein variant features (two alleles)
+    // CCC -> CGC -> P/R
+    sf = sfs.get(6);
     assertEquals(3, sf.getBegin());
     assertEquals(3, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Pro3Arg", sf.getDescription());
-    assertEquals("var6", sf.getValue("ID"));
+    assertEquals("var7", sf.getValue("ID"));
     assertEquals("Good", sf.getValue("clinical_significance"));
-    assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes());
+    assertEquals("ID=var7;clinical_significance=Good", sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Pro3Arg var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            "p.Pro3Arg var7|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var7",
             sf.links.get(0));
     assertEquals(cosmic, sf.getFeatureGroup());
 
-    // var5 generates two distinct protein variant features
-    sf = sfs.get(4);
+    // CCC -> CAC -> P/H
+    sf = sfs.get(7);
     assertEquals(3, sf.getBegin());
     assertEquals(3, sf.getEnd());
+    assertEquals("nonsynonymous_variant", sf.getType());
     assertEquals("p.Pro3His", sf.getDescription());
-    assertEquals("var6", sf.getValue("ID"));
+    assertEquals("var7", sf.getValue("ID"));
     assertEquals("Good", sf.getValue("clinical_significance"));
-    assertEquals("ID=var6;clinical_significance=Good", sf.getAttributes());
+    assertEquals("ID=var7;clinical_significance=Good", sf.getAttributes());
     assertEquals(1, sf.links.size());
     assertEquals(
-            "p.Pro3His var6|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var6",
+            "p.Pro3His var7|http://www.ensembl.org/Homo_sapiens/Variation/Summary?v=var7",
             sf.links.get(0));
     assertEquals(cosmic, sf.getFeatureGroup());
   }
@@ -2308,7 +2381,7 @@ public class AlignmentUtilsTests
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
             new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
-    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
 
     /*
@@ -2340,7 +2413,7 @@ public class AlignmentUtilsTests
     seq1.createDatasetSequence();
     Mapping mapping = new Mapping(seq1, new MapList(
             new int[] { 3, 6, 9, 10 }, new int[] { 1, 6 }, 1, 1));
-    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<Integer, Map<SequenceI, Character>>();
+    Map<Integer, Map<SequenceI, Character>> map = new TreeMap<>();
     AlignmentUtils.addMappedPositions(seq1, from, mapping, map);
 
     /*
index 6611e05..779962c 100644 (file)
@@ -228,6 +228,9 @@ public class EnsemblCdnaTest
     sf.setValue("Parent", "transcript:" + accId);
     assertTrue(testee.retainFeature(sf, accId));
 
+    // test is not case-sensitive
+    assertTrue(testee.retainFeature(sf, accId.toLowerCase()));
+
     // feature with wrong parent is not retained
     sf.setValue("Parent", "transcript:XYZ");
     assertFalse(testee.retainFeature(sf, accId));
index 5920b89..1b1a2b4 100644 (file)
@@ -173,7 +173,8 @@ public class EnsemblGeneTest
     // NMD_transcript_variant treated like transcript in Ensembl
     SequenceFeature sf3 = new SequenceFeature("NMD_transcript_variant", "",
             22000, 22500, 0f, null);
-    sf3.setValue("Parent", "gene:" + geneId);
+    // id matching should not be case-sensitive
+    sf3.setValue("Parent", "gene:" + geneId.toLowerCase());
     sf3.setValue("transcript_id", "transcript3");
     genomic.addSequenceFeature(sf3);
 
@@ -259,6 +260,9 @@ public class EnsemblGeneTest
     sf.setValue("ID", "gene:" + accId);
     assertTrue(testee.identifiesSequence(sf, accId));
 
+    // test is not case-sensitive
+    assertTrue(testee.identifiesSequence(sf, accId.toLowerCase()));
+
     // transcript not valid:
     sf = new SequenceFeature("transcript", "", 1, 2, 0f, null);
     sf.setValue("ID", "gene:" + accId);
index e2af26b..42afa82 100644 (file)
@@ -21,9 +21,7 @@
 package jalview.ext.ensembl;
 
 import static org.testng.AssertJUnit.assertEquals;
-import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertSame;
-import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.Alignment;
 import jalview.datamodel.SequenceFeature;
index 4535c93..91fe602 100644 (file)
@@ -65,7 +65,7 @@ public class StructureChooserTest
     PDBEntry dbRef = new PDBEntry();
     dbRef.setId("1tim");
 
-    Vector<PDBEntry> pdbIds = new Vector<PDBEntry>();
+    Vector<PDBEntry> pdbIds = new Vector<>();
     pdbIds.add(dbRef);
 
     seq.setPDBId(pdbIds);
@@ -133,7 +133,7 @@ public class StructureChooserTest
     assertTrue(sc.getCmbFilterOption().getSelectedItem() != null);
     FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption()
             .getSelectedItem();
-    assertEquals("Cached PDB Entries", filterOpt.getName());
+    assertEquals("Cached Structures", filterOpt.getName());
   }
 
   @Test(groups = { "Network" })
index a02cc5a..7099282 100644 (file)
@@ -170,7 +170,7 @@ public class VCFLoaderTest
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 1);
     assertEquals(sf.getEnd(), 1);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Ser1Thr");
   }
 
@@ -425,7 +425,7 @@ public class VCFLoaderTest
     assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 6);
     assertEquals(sf.getEnd(), 6);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Ala6Gly");
   }
 
@@ -570,12 +570,19 @@ public class VCFLoaderTest
       }
     }
     List<SequenceFeature> proteinFeatures = peptide.getSequenceFeatures();
-    assertEquals(proteinFeatures.size(), 1);
+    SequenceFeatures.sortFeatures(proteinFeatures, true);
+    assertEquals(proteinFeatures.size(), 2);
     sf = proteinFeatures.get(0);
     assertEquals(sf.getFeatureGroup(), "VCF");
+    assertEquals(sf.getBegin(), 1);
+    assertEquals(sf.getEnd(), 1);
+    assertEquals(sf.getType(), SequenceOntologyI.SYNONYMOUS_VARIANT);
+    assertEquals(sf.getDescription(), "AGT");
+    sf = proteinFeatures.get(1);
+    assertEquals(sf.getFeatureGroup(), "VCF");
     assertEquals(sf.getBegin(), 4);
     assertEquals(sf.getEnd(), 4);
-    assertEquals(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT);
+    assertEquals(sf.getType(), SequenceOntologyI.NONSYNONYMOUS_VARIANT);
     assertEquals(sf.getDescription(), "p.Glu4Gly");
 
     /*