JAL-1665 refactored Sequence.getSequenceFeatures features/sequenceFeatureRefactor
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 19 Feb 2015 13:14:06 +0000 (13:14 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 19 Feb 2015 13:14:06 +0000 (13:14 +0000)
18 files changed:
resources/lang/Messages.properties
src/jalview/analysis/AlignmentSorter.java
src/jalview/analysis/Dna.java
src/jalview/bin/JalviewLite.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/Sequence.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/IdPanel.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SequenceFetcher.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/io/StockholmFile.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
test/jalview/datamodel/SequenceTest.java

index 2e37e06..7f62deb 100644 (file)
@@ -671,7 +671,7 @@ label.view_structure = View Structure
 label.clustalx_colours = Clustalx colours
 label.above_identity_percentage = Above % Identity
 label.create_sequence_details_report_annotation_for = Annotation for {0}
-label.sequece_details_for = Sequece Details for {0}
+label.sequence_details_for = Sequence Details for {0}
 label.sequence_name = Sequence Name
 label.sequence_description = Sequence Description
 label.edit_sequence_name_description = Edit Sequence Name/Description
index b7cfbbd..3233cb1 100755 (executable)
  */
 package jalview.analysis;
 
-import java.util.*;
-
-import jalview.datamodel.*;
-import jalview.util.*;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.QuickSort;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
 
 /**
  * Routines for manipulating the order of a multiple sequence alignment TODO:
@@ -785,10 +795,6 @@ public class AlignmentSorter
     for (int i = 0; i < seqs.length; i++)
     {
       SequenceFeature[] sf = seqs[i].getSequenceFeatures();
-      if (sf == null && seqs[i].getDatasetSequence() != null)
-      {
-        sf = seqs[i].getDatasetSequence().getSequenceFeatures();
-      }
       if (sf == null)
       {
         sf = new SequenceFeature[0];
index 2e56e67..b639e36 100644 (file)
  */
 package jalview.analysis;
 
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.Vector;
-
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
@@ -39,6 +35,10 @@ import jalview.schemes.ResidueProperties;
 import jalview.util.MapList;
 import jalview.util.ShiftList;
 
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Vector;
+
 public class Dna
 {
   /**
@@ -52,9 +52,13 @@ public class Dna
   {
     if (cdp2 == null
             || (cdp1[0] == cdp2[0] && cdp1[1] == cdp2[1] && cdp1[2] == cdp2[2]))
+    {
       return 0;
+    }
     if (cdp1[0] < cdp2[0] || cdp1[1] < cdp2[1] || cdp1[2] < cdp2[2])
+     {
       return -1; // one base in cdp1 precedes the corresponding base in the
+    }
     // other codon
     return 1; // one base in cdp1 appears after the corresponding base in the
     // other codon.
@@ -146,7 +150,9 @@ public class Dna
       }
     }
     if (codons.aaWidth == 0)
+    {
       return null;
+    }
     SequenceI[] newseqs = new SequenceI[pepseqs.size()];
     pepseqs.copyInto(newseqs);
     AlignmentI al = new Alignment(newseqs);
@@ -264,7 +270,9 @@ public class Dna
             // generate seqstring for this sequence based on mapping
 
             if (sqstr.length() > alwidth)
+            {
               alwidth = sqstr.length();
+            }
             cdnasqs.addElement(sqstr.toString());
             cdnasqi.addElement(dna);
             cdnaprod.addElement(intersect);
@@ -407,7 +415,7 @@ public class Dna
     }
     if (contrib > 1)
     {
-      annot.value /= (float) contrib;
+      annot.value /= contrib;
     }
     return annot;
   }
@@ -429,6 +437,7 @@ public class Dna
    *             {@link #translateCodingRegion(SequenceI,String,int[],AlignedCodonFrame,char,DBRefEntry,boolean)}
    *             instead
    */
+  @Deprecated
   public static SequenceI translateCodingRegion(SequenceI selection,
           String seqstring, int[] viscontigs, AlignedCodonFrame codons,
           char gapCharacter, DBRefEntry product)
@@ -694,7 +703,9 @@ public class Dna
           scontigs = t;
         }
         if (vc <= 0)
+        {
           scontigs = null;
+        }
       }
       if (scontigs != null)
       {
@@ -705,7 +716,9 @@ public class Dna
           scontigs[vc] = selection.findPosition(scontigs[vc]); // not from 1!
           scontigs[vc + 1] = selection.findPosition(scontigs[vc + 1]); // exclusive
           if (scontigs[vc + 1] == selection.getEnd())
+          {
             break;
+          }
         }
         // trim trailing empty intervals.
         if ((vc + 2) < scontigs.length)
@@ -778,8 +791,7 @@ public class Dna
   private static void transferCodedFeatures(SequenceI dna, SequenceI pep,
           MapList map, Hashtable featureTypes, Hashtable featureGroups)
   {
-    SequenceFeature[] sf = (dna.getDatasetSequence() != null ? dna
-            .getDatasetSequence() : dna).getSequenceFeatures();
+    SequenceFeature[] sf = dna.getSequenceFeatures();
     Boolean fgstate;
     jalview.datamodel.DBRefEntry[] dnarefs = jalview.util.DBRefUtils
             .selectRefs(dna.getDBRef(),
index e022c73..447a9ea 100644 (file)
@@ -1875,6 +1875,7 @@ public class JalviewLite extends Applet implements
       if ((al != null) && (al.getHeight() > 0))
       {
         dbgMsg("Successfully loaded file.");
+        al.setDataset(null); // create dataset sequences
         newAlignFrame = new AlignFrame(al, applet, file, embedded);
         if (initialAlignFrame == null)
         {
index 3b54641..92bd14d 100644 (file)
@@ -179,13 +179,7 @@ public class AlignViewController implements AlignViewControllerI
       int tfeat = 0;
       if (sq != null)
       {
-        SequenceI dsq = sq.getDatasetSequence();
-        while (dsq.getDatasetSequence() != null)
-        {
-          dsq = dsq.getDatasetSequence();
-        }
-        ;
-        SequenceFeature[] sf = dsq.getSequenceFeatures();
+        SequenceFeature[] sf = sq.getSequenceFeatures();
         if (sf != null)
         {
           int ist = sq.findIndex(sq.getStart());
index 96e469a..f4795f1 100755 (executable)
@@ -326,13 +326,26 @@ public class Sequence implements SequenceI
   }
 
   /**
-   * DOCUMENT ME!
+   * Returns the sequence features (if any), looking first on the sequence, then
+   * on its dataset sequence, and so on until a non-null value is found (or
+   * none). This supports retrieval of sequence features stored on the sequence
+   * (as in the applet) or on the dataset sequence (as in the Desktop version).
    * 
-   * @return DOCUMENT ME!
+   * @return
    */
   public SequenceFeature[] getSequenceFeatures()
   {
-    return sequenceFeatures;
+    SequenceFeature[] features = sequenceFeatures;
+
+    SequenceI seq = this;
+    int count = 0; // failsafe against loop in sequence.datasetsequence...
+    while (features == null && seq.getDatasetSequence() != null
+            && count++ < 10)
+    {
+      seq = seq.getDatasetSequence();
+      features = ((Sequence) seq).sequenceFeatures;
+    }
+    return features;
   }
 
   public void addPDBId(PDBEntry entry)
index 6517e70..be8e592 100644 (file)
@@ -1305,8 +1305,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
           sy = s * av.charHeight + scaleHeight;
 
           SequenceI seq = av.getAlignment().getSequenceAt(s);
-          SequenceFeature[] features = seq.getDatasetSequence()
-                  .getSequenceFeatures();
+          SequenceFeature[] features = seq.getSequenceFeatures();
           SequenceGroup[] groups = av.getAlignment().findAllGroups(seq);
           for (res = 0; res < alwidth; res++)
           {
index 3475fe3..0f44c48 100644 (file)
@@ -428,15 +428,13 @@ public class FeatureSettings extends JPanel
     String group;
     for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
     {
-      if (af.getViewport().getAlignment().getSequenceAt(i)
-              .getDatasetSequence().getSequenceFeatures() == null)
+      tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
+              .getSequenceFeatures();
+      if (tmpfeatures == null)
       {
         continue;
       }
 
-      tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
-              .getDatasetSequence().getSequenceFeatures();
-
       int index = 0;
       while (index < tmpfeatures.length)
       {
@@ -546,7 +544,7 @@ public class FeatureSettings extends JPanel
     {
 
       tmpfeatures = af.getViewport().getAlignment().getSequenceAt(i)
-              .getDatasetSequence().getSequenceFeatures();
+              .getSequenceFeatures();
       if (tmpfeatures == null)
       {
         continue;
index a22e918..11cbd03 100755 (executable)
@@ -323,8 +323,7 @@ public class IdPanel extends JPanel implements MouseListener,
       // build a new links menu based on the current links + any non-positional
       // features
       Vector nlinks = new Vector(Preferences.sequenceURLLinks);
-      SequenceFeature sf[] = sq == null ? null : sq.getDatasetSequence()
-              .getSequenceFeatures();
+      SequenceFeature sf[] = sq == null ? null : sq.getSequenceFeatures();
       for (int sl = 0; sf != null && sl < sf.length; sl++)
       {
         if (sf[sl].begin == sf[sl].end && sf[sl].begin == 0)
index a2cd147..39ed81a 100644 (file)
@@ -682,9 +682,9 @@ public class Jalview2XML
         }
       }
 
-      if (jdatasq.getSequenceFeatures() != null)
+      if (jds.getSequenceFeatures() != null)
       {
-        jalview.datamodel.SequenceFeature[] sf = jdatasq
+        jalview.datamodel.SequenceFeature[] sf = jds
                 .getSequenceFeatures();
         int index = 0;
         while (index < sf.length)
index 8565f9f..1137990 100644 (file)
@@ -2023,10 +2023,10 @@ public class PopupMenu extends JPopupMenu
     }
     cap.setText("<html>" + contents.toString() + "</html>");
 
-    Desktop.instance.addInternalFrame(cap, MessageManager.formatMessage(
-            "label.sequece_details_for",
-            (sequences.length == 1 ? new String[]
-            { sequences[0].getDisplayId(true) } : new String[]
+    Desktop.addInternalFrame(cap, MessageManager.formatMessage(
+            "label.sequence_details_for",
+            (sequences.length == 1 ? new Object[]
+            { sequences[0].getDisplayId(true) } : new Object[]
             { MessageManager.getString("label.selection") })), 500, 400);
 
   }
index 35bc29a..2928102 100755 (executable)
  */
 package jalview.gui;
 
-import java.util.*;
-import java.util.List;
-
-import java.awt.*;
-import java.awt.event.*;
-
-import javax.swing.*;
-import javax.swing.tree.DefaultMutableTreeNode;
-
-import com.stevesoft.pat.Regex;
-
-import jalview.datamodel.*;
-import jalview.io.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.io.FormatAdapter;
+import jalview.io.IdentifyFile;
 import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
 import jalview.ws.seqfetcher.DbSourceProxy;
+
 import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingConstants;
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.stevesoft.pat.Regex;
 
 public class SequenceFetcher extends JPanel implements Runnable
 {
@@ -283,7 +301,9 @@ public class SequenceFetcher extends JPanel implements Runnable
       public void keyPressed(KeyEvent e)
       {
         if (e.getKeyCode() == KeyEvent.VK_ENTER)
+        {
           ok_actionPerformed();
+        }
       }
     });
     jPanel3.setLayout(borderLayout1);
@@ -794,7 +814,7 @@ public class SequenceFetcher extends JPanel implements Runnable
         {
           for (SequenceI sq : alsqs)
           {
-            if ((sfs = (sq).getDatasetSequence().getSequenceFeatures()) != null)
+            if ((sfs = sq.getSequenceFeatures()) != null)
             {
               if (sfs.length > 0)
               {
index db43a3f..2001338 100644 (file)
@@ -137,8 +137,7 @@ public class BioJsHTMLOutput
       seqPojo.setName(name.toString());
       seqPojo.setSeq(seq.getSequenceAsString());
 
-      SequenceFeature[] seqFeatures = seq.getDatasetSequence()
-              .getSequenceFeatures();
+      SequenceFeature[] seqFeatures = seq.getSequenceFeatures();
       if (seqFeatures != null)
       {
         ArrayList<BioJsFeaturePojo> bjsSeqFeatures = new ArrayList<BioJsFeaturePojo>();
index 1757239..e60e7e5 100644 (file)
  */
 package jalview.io;
 
-import java.util.ArrayList;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.util.UrlLink;
 
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
 /**
  * generate HTML reports for a sequence
  * 
@@ -364,7 +364,7 @@ public class SequenceAnnotationReport
     }
 
     // ADD NON POSITIONAL SEQUENCE INFO
-    SequenceFeature[] features = ds.getSequenceFeatures();
+    SequenceFeature[] features = sequence.getSequenceFeatures();
     if (showNpFeats && features != null)
     {
       for (int i = 0; i < features.length; i++)
index 3b9fb00..c4d3e5c 100644 (file)
@@ -978,6 +978,7 @@ public class StockholmFile extends AlignFile
             {
               feature = ds.getSequenceFeatures()[0].type;
             }
+            // ?bug - feature may still have previous loop value
             String key = type2id(feature);
 
             if (key == null)
index 5e6ac29..362ef5e 100644 (file)
@@ -20,28 +20,6 @@ public class FeatureRenderer extends
 
   boolean offscreenRender = false;
 
-  /**
-   * DOCUMENT ME!
-   * 
-   * @param g
-   *          DOCUMENT ME!
-   * @param seq
-   *          DOCUMENT ME!
-   * @param sg
-   *          DOCUMENT ME!
-   * @param start
-   *          DOCUMENT ME!
-   * @param end
-   *          DOCUMENT ME!
-   * @param x1
-   *          DOCUMENT ME!
-   * @param y1
-   *          DOCUMENT ME!
-   * @param width
-   *          DOCUMENT ME!
-   * @param height
-   *          DOCUMENT ME!
-   */
   protected SequenceI lastSeq;
 
   char s;
@@ -188,30 +166,29 @@ public class FeatureRenderer extends
       return initialCol;
     }
 
-    final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq
-            .getDatasetSequence() : seq;
+    SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
     if (seq != lastSeq)
     {
       lastSeq = seq;
-      sequenceFeatures = aseq.getSequenceFeatures();
-      if (sequenceFeatures != null)
+      lastSequenceFeatures = sequenceFeatures;
+      if (lastSequenceFeatures != null)
       {
-        sfSize = sequenceFeatures.length;
+        sfSize = lastSequenceFeatures.length;
       }
     }
     else
     {
-      if (sequenceFeatures != aseq.getSequenceFeatures())
+      if (lastSequenceFeatures != sequenceFeatures)
       {
-        sequenceFeatures = aseq.getSequenceFeatures();
-        if (sequenceFeatures != null)
+        lastSequenceFeatures = sequenceFeatures;
+        if (lastSequenceFeatures != null)
         {
-          sfSize = sequenceFeatures.length;
+          sfSize = lastSequenceFeatures.length;
         }
       }
     }
 
-    if (sequenceFeatures == null || sfSize == 0)
+    if (lastSequenceFeatures == null || sfSize == 0)
     {
       return initialCol;
     }
@@ -255,7 +232,7 @@ public class FeatureRenderer extends
 
   }
 
-  private volatile SequenceFeature[] sequenceFeatures;
+  private volatile SequenceFeature[] lastSequenceFeatures;
 
   int sfSize;
 
@@ -268,10 +245,8 @@ public class FeatureRenderer extends
   public synchronized void drawSequence(Graphics g, final SequenceI seq,
           int start, int end, int y1)
   {
-    final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq
-            .getDatasetSequence() : seq;
-    if (aseq.getSequenceFeatures() == null
-            || aseq.getSequenceFeatures().length == 0)
+    SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
+    if (sequenceFeatures == null || sequenceFeatures.length == 0)
     {
       return;
     }
@@ -284,10 +259,10 @@ public class FeatureRenderer extends
     updateFeatures();
 
     if (lastSeq == null || seq != lastSeq
-            || aseq.getSequenceFeatures() != sequenceFeatures)
+            || sequenceFeatures != lastSequenceFeatures)
     {
       lastSeq = seq;
-      sequenceFeatures = aseq.getSequenceFeatures();
+      lastSequenceFeatures = sequenceFeatures;
     }
 
     if (transparency != 1 && g != null)
@@ -303,7 +278,7 @@ public class FeatureRenderer extends
       epos = lastSeq.findPosition(end);
     }
 
-    sfSize = sequenceFeatures.length;
+    sfSize = lastSequenceFeatures.length;
     String type;
     for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
     {
@@ -318,25 +293,26 @@ public class FeatureRenderer extends
       // current feature to render
       for (sfindex = 0; sfindex < sfSize; sfindex++)
       {
-        if (!sequenceFeatures[sfindex].type.equals(type))
+        if (!lastSequenceFeatures[sfindex].type.equals(type))
         {
           continue;
         }
 
         if (featureGroups != null
-                && sequenceFeatures[sfindex].featureGroup != null
-                && sequenceFeatures[sfindex].featureGroup.length() != 0
+                && lastSequenceFeatures[sfindex].featureGroup != null
+                && lastSequenceFeatures[sfindex].featureGroup.length() != 0
                 && featureGroups
-                        .containsKey(sequenceFeatures[sfindex].featureGroup)
+                        .containsKey(lastSequenceFeatures[sfindex].featureGroup)
                 && !featureGroups
-                        .get(sequenceFeatures[sfindex].featureGroup)
+.get(
+                        lastSequenceFeatures[sfindex].featureGroup)
                         .booleanValue())
         {
           continue;
         }
 
         if (!offscreenRender
-                && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex]
+                && (lastSequenceFeatures[sfindex].getBegin() > epos || lastSequenceFeatures[sfindex]
                         .getEnd() < spos))
         {
           continue;
@@ -344,56 +320,59 @@ public class FeatureRenderer extends
 
         if (offscreenRender && offscreenImage == null)
         {
-          if (sequenceFeatures[sfindex].begin <= start
-                  && sequenceFeatures[sfindex].end >= start)
+          if (lastSequenceFeatures[sfindex].begin <= start
+                  && lastSequenceFeatures[sfindex].end >= start)
           {
             // this is passed out to the overview and other sequence renderers
             // (e.g. molecule viewer) to get displayed colour for rendered
             // sequence
             currentColour = new Integer(
-                    getColour(sequenceFeatures[sfindex]).getRGB());
+getColour(
+                    lastSequenceFeatures[sfindex]).getRGB());
             // used to be retreived from av.featuresDisplayed
             // currentColour = av.featuresDisplayed
             // .get(sequenceFeatures[sfindex].type);
 
           }
         }
-        else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
+        else if (lastSequenceFeatures[sfindex].type
+                .equals("disulfide bond"))
         {
 
           renderFeature(g, seq,
-                  seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
-                  seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
-                  getColour(sequenceFeatures[sfindex])
+                  seq.findIndex(lastSequenceFeatures[sfindex].begin) - 1,
+                  seq.findIndex(lastSequenceFeatures[sfindex].begin) - 1,
+                  getColour(lastSequenceFeatures[sfindex])
                   // new Color(((Integer) av.featuresDisplayed
                   // .get(sequenceFeatures[sfindex].type)).intValue())
                   , start, end, y1);
           renderFeature(g, seq,
-                  seq.findIndex(sequenceFeatures[sfindex].end) - 1,
-                  seq.findIndex(sequenceFeatures[sfindex].end) - 1,
-                  getColour(sequenceFeatures[sfindex])
+                  seq.findIndex(lastSequenceFeatures[sfindex].end) - 1,
+                  seq.findIndex(lastSequenceFeatures[sfindex].end) - 1,
+                  getColour(lastSequenceFeatures[sfindex])
                   // new Color(((Integer) av.featuresDisplayed
                   // .get(sequenceFeatures[sfindex].type)).intValue())
                   , start, end, y1);
 
         }
-        else if (showFeature(sequenceFeatures[sfindex]))
+        else if (showFeature(lastSequenceFeatures[sfindex]))
         {
           if (av_isShowSeqFeatureHeight
-                  && sequenceFeatures[sfindex].score != Float.NaN)
+                  && lastSequenceFeatures[sfindex].score != Float.NaN)
           {
             renderScoreFeature(g, seq,
-                    seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
-                    seq.findIndex(sequenceFeatures[sfindex].end) - 1,
-                    getColour(sequenceFeatures[sfindex]), start, end, y1,
-                    normaliseScore(sequenceFeatures[sfindex]));
+                    seq.findIndex(lastSequenceFeatures[sfindex].begin) - 1,
+                    seq.findIndex(lastSequenceFeatures[sfindex].end) - 1,
+                    getColour(lastSequenceFeatures[sfindex]), start, end,
+                    y1, normaliseScore(lastSequenceFeatures[sfindex]));
           }
           else
           {
             renderFeature(g, seq,
-                    seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
-                    seq.findIndex(sequenceFeatures[sfindex].end) - 1,
-                    getColour(sequenceFeatures[sfindex]), start, end, y1);
+                    seq.findIndex(lastSequenceFeatures[sfindex].begin) - 1,
+                    seq.findIndex(lastSequenceFeatures[sfindex].end) - 1,
+                    getColour(lastSequenceFeatures[sfindex]), start, end,
+                    y1);
           }
         }
 
index c7cee04..674f3d1 100644 (file)
@@ -247,12 +247,6 @@ public abstract class FeatureRendererModel implements
     ArrayList<SequenceFeature> tmp = new ArrayList<SequenceFeature>();
     SequenceFeature[] features = sequence.getSequenceFeatures();
 
-    while (features == null && sequence.getDatasetSequence() != null)
-    {
-      sequence = sequence.getDatasetSequence();
-      features = sequence.getSequenceFeatures();
-    }
-
     if (features != null)
     {
       for (int i = 0; i < features.length; i++)
@@ -329,9 +323,7 @@ public abstract class FeatureRendererModel implements
     for (int i = 0; i < alignment.getHeight(); i++)
     {
       SequenceI asq = alignment.getSequenceAt(i);
-      SequenceI dasq = asq.getDatasetSequence();
-      SequenceFeature[] features = dasq != null ? dasq
-              .getSequenceFeatures() : asq.getSequenceFeatures();
+      SequenceFeature[] features = asq.getSequenceFeatures();
 
       if (features == null)
       {
index 40476a0..fa4d717 100644 (file)
@@ -5,6 +5,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 import static org.junit.Assert.assertTrue;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.junit.Before;
@@ -135,4 +136,178 @@ public class SequenceTest
     assertSame(annotation2, anns[1]);
 
   }
-}
+
+  @Test
+  public void testGetStartGetEnd()
+  {
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    assertEquals(1, seq.getStart());
+    assertEquals(6, seq.getEnd());
+
+    seq = new Sequence("test", "--AB-C-DEF--");
+    assertEquals(1, seq.getStart());
+    assertEquals(6, seq.getEnd());
+
+    seq = new Sequence("test", "----");
+    assertEquals(1, seq.getStart());
+    assertEquals(0, seq.getEnd()); // ??
+  }
+
+  /**
+   * Tests for the method that returns an alignment column position (base 1) for
+   * a given sequence position (base 1).
+   */
+  @Test
+  public void testFindIndex()
+  {
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    assertEquals(0, seq.findIndex(0));
+    assertEquals(1, seq.findIndex(1));
+    assertEquals(5, seq.findIndex(5));
+    assertEquals(6, seq.findIndex(6));
+    assertEquals(6, seq.findIndex(9));
+
+    seq = new Sequence("test", "-A--B-C-D-E-F--");
+    assertEquals(2, seq.findIndex(1));
+    assertEquals(5, seq.findIndex(2));
+    assertEquals(7, seq.findIndex(3));
+
+    // before start returns 0
+    assertEquals(0, seq.findIndex(0));
+    assertEquals(0, seq.findIndex(-1));
+
+    // beyond end returns last residue column
+    assertEquals(13, seq.findIndex(99));
+
+  }
+
+  /**
+   * Tests for the method that returns a dataset sequence position (base 1) for
+   * an aligned column position (base 0).
+   */
+  @Test
+  public void testFindPosition()
+  {
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    assertEquals(1, seq.findPosition(0));
+    assertEquals(6, seq.findPosition(5));
+    // assertEquals(-1, seq.findPosition(6)); // fails
+
+    seq = new Sequence("test", "AB-C-D--");
+    assertEquals(1, seq.findPosition(0));
+    assertEquals(2, seq.findPosition(1));
+    // gap position 'finds' residue to the right (not the left as per javadoc)
+    assertEquals(3, seq.findPosition(2));
+    assertEquals(3, seq.findPosition(3));
+    assertEquals(4, seq.findPosition(4));
+    assertEquals(4, seq.findPosition(5));
+    // returns 1 more than sequence length if off the end ?!?
+    assertEquals(5, seq.findPosition(6));
+    assertEquals(5, seq.findPosition(7));
+
+    seq = new Sequence("test", "--AB-C-DEF--");
+    assertEquals(1, seq.findPosition(0));
+    assertEquals(1, seq.findPosition(1));
+    assertEquals(1, seq.findPosition(2));
+    assertEquals(2, seq.findPosition(3));
+    assertEquals(3, seq.findPosition(4));
+    assertEquals(3, seq.findPosition(5));
+    assertEquals(4, seq.findPosition(6));
+    assertEquals(4, seq.findPosition(7));
+    assertEquals(5, seq.findPosition(8));
+    assertEquals(6, seq.findPosition(9));
+    assertEquals(7, seq.findPosition(10));
+    assertEquals(7, seq.findPosition(11));
+  }
+
+  @Test
+  public void testDeleteChars()
+  {
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    assertEquals(1, seq.getStart());
+    assertEquals(6, seq.getEnd());
+    seq.deleteChars(2, 3);
+    assertEquals("ABDEF", seq.getSequenceAsString());
+    assertEquals(1, seq.getStart());
+    assertEquals(5, seq.getEnd());
+
+    seq = new Sequence("test", "ABCDEF");
+    seq.deleteChars(0, 2);
+    assertEquals("CDEF", seq.getSequenceAsString());
+    assertEquals(3, seq.getStart());
+    assertEquals(6, seq.getEnd());
+  }
+
+  @Test
+  public void testInsertCharAt()
+  {
+    // non-static methods:
+    SequenceI seq = new Sequence("test", "ABCDEF");
+    seq.insertCharAt(0, 'z');
+    assertEquals("zABCDEF", seq.getSequenceAsString());
+    seq.insertCharAt(2, 2, 'x');
+    assertEquals("zAxxBCDEF", seq.getSequenceAsString());
+
+    // for static method see StringUtilsTest
+  }
+
+  /**
+   * Test the method that returns an array of aligned sequence positions where
+   * the array index is the data sequence position (both base 0).
+   */
+  @Test
+  public void testGapMap()
+  {
+    SequenceI seq = new Sequence("test", "-A--B-CD-E--F-");
+    seq.createDatasetSequence();
+    assertEquals("[1, 4, 6, 7, 9, 12]", Arrays.toString(seq.gapMap()));
+  }
+
+  /**
+   * Test the method that gets sequence features, either from the sequence or
+   * its dataset.
+   */
+  @Test
+  public void testGetSequenceFeatures()
+  {
+    SequenceI seq = new Sequence("test", "GATCAT");
+    seq.createDatasetSequence();
+
+    assertNull(seq.getSequenceFeatures());
+
+    /*
+     * SequenceFeature on sequence
+     */
+    SequenceFeature sf = new SequenceFeature();
+    seq.addSequenceFeature(sf);
+    SequenceFeature[] sfs = seq.getSequenceFeatures();
+    assertEquals(1, sfs.length);
+    assertSame(sf, sfs[0]);
+
+    /*
+     * SequenceFeature on sequence and dataset sequence; returns that on
+     * sequence
+     */
+    SequenceFeature sf2 = new SequenceFeature();
+    seq.getDatasetSequence().addSequenceFeature(sf2);
+    sfs = seq.getSequenceFeatures();
+    assertEquals(1, sfs.length);
+    assertSame(sf, sfs[0]);
+
+    /*
+     * SequenceFeature on dataset sequence only
+     */
+    seq.setSequenceFeatures(null);
+    sfs = seq.getSequenceFeatures();
+    assertEquals(1, sfs.length);
+    assertSame(sf2, sfs[0]);
+
+    /*
+     * Corrupt case - no SequenceFeature, dataset's dataset is the original
+     * sequence. Test shows no infinite loop results.
+     */
+    seq.getDatasetSequence().setSequenceFeatures(null);
+    seq.getDatasetSequence().setDatasetSequence(seq); // loop!
+    assertNull(seq.getSequenceFeatures());
+  }
+}
\ No newline at end of file