Merge branch 'develop' into features/JAL-250_hideredundantseqs
authorJim Procter <jprocter@issues.jalview.org>
Tue, 6 Dec 2016 15:30:00 +0000 (15:30 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 6 Dec 2016 15:30:00 +0000 (15:30 +0000)
1  2 
src/jalview/analysis/AlignSeq.java
src/jalview/api/AlignViewControllerI.java
src/jalview/controller/AlignViewController.java

@@@ -620,7 -620,10 +620,10 @@@ public class AlignSe
        {
          if ((i + (j * len)) < astr1.length())
          {
-           if (astr1.charAt(i + (j * len)) == astr2.charAt(i + (j * len))
+           boolean sameChar = Comparison.isSameResidue(
+                   astr1.charAt(i + (j * len)), astr2.charAt(i + (j * len)),
+                   false);
+           if (sameChar
                    && !jalview.util.Comparison.isGap(astr1.charAt(i
                            + (j * len))))
            {
      }
  
      pid = pid / (aseq1.length - count) * 100;
-     output = output.append(new Format("Percentage ID = %2.2f\n")
-             .form(pid));
+     output = output.append(new Format("Percentage ID = %2.2f\n").form(pid));
      try
      {
        os.print(output.toString());
            SequenceI[] originalSequences, String[] omitHidden, int start,
            int end, boolean ungapped)
    {
 +    return (float[]) computeRedundancyMatrixWithRep(originalSequences,
 +            omitHidden, start, end, ungapped)[0];
 +  }
 +
 +  public static Object[] computeRedundancyMatrixWithRep(
 +          SequenceI[] originalSequences, String[] omitHidden, int start,
 +          int end, boolean ungapped)
 +  {
 +
      int height = originalSequences.length;
      float[] redundancy = new float[height];
 +    SequenceI[] rep = new SequenceI[height];
      int[] lngth = new int[height];
      for (int i = 0; i < height; i++)
      {
          // use real sequence length rather than string length
          if (lngth[j] < lngth[i])
          {
 -          redundancy[j] = Math.max(pid, redundancy[j]);
 +          if (pid > redundancy[j])
 +          {
 +            rep[j] = originalSequences[i];
 +            redundancy[j] = pid;
 +          }
          }
          else
          {
 -          redundancy[i] = Math.max(pid, redundancy[i]);
 +          if (pid > redundancy[i])
 +          {
 +            rep[i] = originalSequences[j];
 +            redundancy[i] = pid;
 +          }
          }
  
        }
      }
 -    return redundancy;
 +    return new Object[] { redundancy, rep };
    }
  }
@@@ -20,7 -20,7 +20,8 @@@
   */
  package jalview.api;
  
 +import jalview.datamodel.SequenceGroup;
+ import jalview.io.DataSourceType;
  
  import java.util.List;
  
@@@ -90,21 -90,25 +91,33 @@@ public interface AlignViewController
     * add a features file of some kind to the current view
     * 
     * @param file
-    * @param protocol
+    * @param sourceType
     * @param relaxedIdMatching
     *          if true, try harder to match up IDs with local sequence data
     * @return true if parsing resulted in something being imported to the view or
     *         dataset
     */
-   public boolean parseFeaturesFile(String file, String protocol,
+   public boolean parseFeaturesFile(String file, DataSourceType sourceType,
            boolean relaxedIdMatching);
  
    /**
 +   * clear any group definitions in the current view and add a set of new group
 +   * definitions with randomly generated colours
 +   * 
 +   * @param gps
 +   */
 +  void showRandomColoursForGroups(List<SequenceGroup> gps);
 +
++  /**
+    * mark columns containing highlighted regions (e.g. from search, structure
+    * highlight, or a mouse over event in another viewer)
+    * 
+    * @param invert
+    * @param extendCurrent
+    * @param toggle
+    * @return
+    */
+   boolean markHighlightedColumns(boolean invert, boolean extendCurrent,
+           boolean toggle);
  }
@@@ -33,11 -33,11 +33,12 @@@ import jalview.datamodel.SequenceCollec
  import jalview.datamodel.SequenceFeature;
  import jalview.datamodel.SequenceGroup;
  import jalview.datamodel.SequenceI;
+ import jalview.io.DataSourceType;
  import jalview.io.FeaturesFile;
  import jalview.util.MessageManager;
  
  import java.awt.Color;
 +import java.util.Arrays;
  import java.util.BitSet;
  import java.util.List;
  
@@@ -102,36 -102,29 +103,36 @@@ public class AlignViewController implem
      }
      if (gps != null)
      {
 -      viewport.getAlignment().deleteAllGroups();
 -      viewport.clearSequenceColours();
 -      viewport.setSelectionGroup(null);
 -      // set view properties for each group
 -      for (int g = 0; g < gps.length; g++)
 -      {
 -        // gps[g].setShowunconserved(viewport.getShowUnconserved());
 -        gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
 -        viewport.getAlignment().addGroup(gps[g]);
 -        Color col = new Color((int) (Math.random() * 255),
 -                (int) (Math.random() * 255), (int) (Math.random() * 255));
 -        col = col.brighter();
 -        for (SequenceI sq : gps[g].getSequences(null))
 -        {
 -          viewport.setSequenceColour(sq, col);
 -        }
 -      }
 +      showRandomColoursForGroups(Arrays.asList(gps));
 +
        return true;
      }
      return false;
    }
  
    @Override
 +  public void showRandomColoursForGroups(List<SequenceGroup> gps)
 +  {
 +    viewport.getAlignment().deleteAllGroups();
 +    viewport.clearSequenceColours();
 +    viewport.setSelectionGroup(null);
 +    // set view properties for each group
 +    for (SequenceGroup sg : gps)
 +    {
 +      // gps[g].setShowunconserved(viewport.getShowUnconserved());
 +      sg.setshowSequenceLogo(viewport.isShowSequenceLogo());
 +      viewport.getAlignment().addGroup(sg);
 +      Color col = new Color((int) (Math.random() * 255),
 +              (int) (Math.random() * 255), (int) (Math.random() * 255));
 +      col = col.brighter();
 +      for (SequenceI sq : sg.getSequences(null))
 +      {
 +        viewport.setSequenceColour(sq, col);
 +      }
 +    }
 +  }
 +
 +  @Override
    public boolean createGroup()
    {
  
          SequenceFeature[] sfs = sq.getSequenceFeatures();
          if (sfs != null)
          {
-           /*
-            * check whether the feature start/end (base 1) 
-            * overlaps the selection start/end
-            */
            int ist = sq.findIndex(sq.getStart());
            int iend = sq.findIndex(sq.getEnd());
            if (iend < startPosition || ist > endPosition)
                // - findIndex wastes time by starting from first character and
                // counting
  
-               int i = sq.findIndex(sf.getBegin());
-               int j = sq.findIndex(sf.getEnd());
-               if (j < startPosition || i > endPosition)
+               int sfStartCol = sq.findIndex(sf.getBegin());
+               int sfEndCol = sq.findIndex(sf.getEnd());
+               if (sf.isContactFeature())
+               {
+                 /*
+                  * 'contact' feature - check for 'start' or 'end'
+                  * position within the selected region
+                  */
+                 if (sfStartCol >= startPosition
+                         && sfStartCol <= endPosition)
+                 {
+                   bs.set(sfStartCol - 1);
+                   sequenceHasFeature = true;
+                 }
+                 if (sfEndCol >= startPosition && sfEndCol <= endPosition)
+                 {
+                   bs.set(sfEndCol - 1);
+                   sequenceHasFeature = true;
+                 }
+                 continue;
+               }
+               /*
+                * contiguous feature - select feature positions (if any) 
+                * within the selected region
+                */
+               if (sfStartCol > endPosition || sfEndCol < startPosition)
                {
                  // feature is outside selected region
                  continue;
                }
                sequenceHasFeature = true;
-               if (i < startPosition)
+               if (sfStartCol < startPosition)
                {
-                 i = startPosition;
+                 sfStartCol = startPosition;
                }
-               if (i < ist)
+               if (sfStartCol < ist)
                {
-                 i = ist;
+                 sfStartCol = ist;
                }
-               if (j > endPosition)
+               if (sfEndCol > endPosition)
                {
-                 j = endPosition;
+                 sfEndCol = endPosition;
                }
-               for (; i <= j; i++)
+               for (; sfStartCol <= sfEndCol; sfStartCol++)
                {
-                 bs.set(i - 1); // convert to base 0
+                 bs.set(sfStartCol - 1); // convert to base 0
                }
              }
            }
    }
  
    @Override
-   public boolean parseFeaturesFile(String file, String protocol,
+   public boolean parseFeaturesFile(String file, DataSourceType protocol,
            boolean relaxedIdMatching)
    {
      boolean featuresFile = false;
      return featuresFile;
  
    }
+   @Override
+   public boolean markHighlightedColumns(boolean invert,
+           boolean extendCurrent, boolean toggle)
+   {
+     if (!viewport.hasSearchResults())
+     {
+       // do nothing if no selection exists
+       return false;
+     }
+     // JBPNote this routine could also mark rows, not just columns.
+     BitSet bs = new BitSet();
+     SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+             .getAlignment() : viewport.getSelectionGroup();
+     // this could be a lambda... - the remains of the method is boilerplate,
+     // except for the different messages for reporting selection.
+     int nseq = viewport.getSearchResults().markColumns(sqcol, bs);
+     ColumnSelection cs = viewport.getColumnSelection();
+     if (cs == null)
+     {
+       cs = new ColumnSelection();
+     }
+     if (bs.cardinality() > 0 || invert)
+     {
+       boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+               sqcol.getEndRes(), invert, extendCurrent, toggle);
+       if (changed)
+       {
+         viewport.setColumnSelection(cs);
+         alignPanel.paintAlignment(true);
+         int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+                 - bs.cardinality()
+                 : bs.cardinality();
+         avcg.setStatus(MessageManager.formatMessage(
+                 "label.view_controller_toggled_marked",
+                 new String[] {
+                     toggle ? MessageManager.getString("label.toggled")
+                             : MessageManager.getString("label.marked"),
+                     String.valueOf(columnCount),
+                     invert ? MessageManager
+                             .getString("label.not_containing")
+                             : MessageManager.getString("label.containing"),
+                     "Highlight", Integer.valueOf(nseq).toString() }));
+         return true;
+       }
+     }
+     else
+     {
+       avcg.setStatus(MessageManager
+               .formatMessage("No highlighted regions marked"));
+       if (!extendCurrent)
+       {
+         cs.clear();
+         alignPanel.paintAlignment(true);
+       }
+     }
+     return false;
+   }
  }