JAL-891; base-pair logos can now be activated for structure
authorjanengelhardt <engelhardt87@googlemail.com>
Tue, 9 Aug 2011 23:01:22 +0000 (01:01 +0200)
committerjanengelhardt <engelhardt87@googlemail.com>
Tue, 9 Aug 2011 23:01:22 +0000 (01:01 +0200)
conservation row;

Change-Id: Ib3450f328f901eaf12ea094c9c914322f8398a88

src/jalview/analysis/StructureFrequency.java
src/jalview/gui/AnnotationPanel.java

index b9c61c2..4d83019 100644 (file)
@@ -44,6 +44,8 @@ public class StructureFrequency
 
   public static final String PROFILE = "P";
 
+  public static final String PAIRPROFILE = "B";
+
   public static final Hashtable[] calculate(Vector sequences, int start,
           int end)
   {
@@ -102,13 +104,13 @@ public class StructureFrequency
       maxResidue = "";
       nongap = 0;
       values = new int[255];
-      
 
       for (j = 0; j < jSize; j++)
       {
-        if (sequences[j]==null)
+        if (sequences[j] == null)
         {
-          System.err.println("WARNING: Consensus skipping null sequence - possible race condition.");
+          System.err
+                  .println("WARNING: Consensus skipping null sequence - possible race condition.");
           continue;
         }
         seq = sequences[j].getSequence();
@@ -180,19 +182,23 @@ public class StructureFrequency
       result[i] = residueHash;
     }
   }
-  
-  public static int findPair(SequenceFeature[] pairs,int indice){
-         for(int i=0; i<pairs.length; i++){
-                 if(pairs[i].getBegin()==indice){
-                         return pairs[i].getEnd();
-                 }
-         }
-         return -1;
+
+  public static int findPair(SequenceFeature[] pairs, int indice)
+  {
+    for (int i = 0; i < pairs.length; i++)
+    {
+      if (pairs[i].getBegin() == indice)
+      {
+        return pairs[i].getEnd();
+      }
+    }
+    return -1;
   }
-  
+
   /**
-   * Method to calculate a 'base pair consensus row', very similar 
-   * to nucleotide consensus but takes into account a given structure
+   * Method to calculate a 'base pair consensus row', very similar to nucleotide
+   * consensus but takes into account a given structure
+   * 
    * @param sequences
    * @param start
    * @param end
@@ -201,146 +207,186 @@ public class StructureFrequency
    * @param rnaStruc
    */
   public static final void calculate(SequenceI[] sequences, int start,
-                 int end, Hashtable[] result, boolean profile, AlignmentAnnotation rnaStruc){
-         //System.out.println("StructureFrequency.calculateNEW4");
-         Hashtable residueHash;
-         String maxResidue;
-         char[] seq, struc=rnaStruc.getRNAStruc().toCharArray();
-         SequenceFeature[] rna =rnaStruc._rnasecstr;
-         char c,s,cEnd;
-         int count,nonGap=0,i,bpEnd=-1,j,jSize = sequences.length;
-         int[] values = new int[255];
-         float percentage;
-                 
-         for (i = start; i < end; i++) //foreach column
-         {
-                 residueHash = new Hashtable();
-                 maxResidue="-";
-                 values = new int[255];
-                 bpEnd=-1;
-
-                 s = struc[i];
-                 if (s == '.' || s == ' ')
-                 {
-                         s = '-';
-                 }
-
-                 if(s != '('){
-                         if(s == '-'){
-                                 values['-']++;
-                         }
-                 }
-                 else
-                 {
-                         for (j = 0; j < jSize; j++) //foreach row
-                         {
-                                 if (sequences[j]==null)
-                                 {
-                                         System.err.println("WARNING: Consensus skipping null sequence - possible race condition.");
-                                         continue;
-                                 }
-                                 seq = sequences[j].getSequence();
-                                 
-                                 if (seq.length > i)
-                                 {
-                                         c = seq[i];
-
-                                         //standard representation for gaps in sequence and structure
-                                         if (c == '.' || c == ' ')
-                                         {
-                                                 c = '-';
-                                         }
-
-                                         if (c == '-')
-                                         {
-                                                 values['-']++;
-                                                 continue;
-                                         }
-                                         bpEnd=findPair(rna,i);
-                                         cEnd=seq[bpEnd];
-                                         if(checkBpType(c,cEnd)){
-                                                 values['H']++; //H means it's a helix (structured)
-                                         }
-                                         maxResidue="H";
-                                 }
-                         }
-//                       nonGap++;
-                 }
-                 //UPDATE this for new values
-             if (profile)
-             {
-                 //System.out.println("profile");
-               residueHash.put(PROFILE, new int[][]
-               { values, new int[]
-               { jSize, values['H'] } });
-             }
-                  
-
-                 count=values['H'];
-                                 
-                 residueHash.put(MAXCOUNT, new Integer(count));
-             residueHash.put(MAXRESIDUE, maxResidue);
-             
-                 percentage = ((float) count * 100) / (float) jSize;
-                 residueHash.put(PID_GAPS, new Float(percentage));
-
-                 //percentage = ((float) count * 100) / (float) nongap;
-                 //residueHash.put(PID_NOGAPS, new Float(percentage));
-                 if(result[i]==null){
-                         result[i] = residueHash;
-                 }
-                 if(bpEnd>0){
-                         result[bpEnd]=residueHash;
-                 }
-         }
+          int end, Hashtable[] result, boolean profile,
+          AlignmentAnnotation rnaStruc)
+  {
+    // System.out.println("StructureFrequency.calculateNEW4");
+    Hashtable residueHash;
+    String maxResidue;
+    char[] seq, struc = rnaStruc.getRNAStruc().toCharArray();
+    SequenceFeature[] rna = rnaStruc._rnasecstr;
+    char c, s, cEnd;
+    int count, nonGap = 0, i, bpEnd = -1, j, jSize = sequences.length;
+    int[] values;
+    int[][] pairs;
+    float percentage;
+
+    for (i = start; i < end; i++) // foreach column
+    {
+      residueHash = new Hashtable();
+      maxResidue = "-";
+      values = new int[255];
+      pairs = new int[255][255];
+      bpEnd = -1;
+
+      s = struc[i];
+      if (s == '.' || s == ' ')
+      {
+        s = '-';
+      }
+
+      if (s != '(')
+      {
+        if (s == '-')
+        {
+          values['-']++;
+        }
+      }
+      else
+      {
+        for (j = 0; j < jSize; j++) // foreach row
+        {
+          if (sequences[j] == null)
+          {
+            System.err
+                    .println("WARNING: Consensus skipping null sequence - possible race condition.");
+            continue;
+          }
+          seq = sequences[j].getSequence();
+
+          if (seq.length > i)
+          {
+            c = seq[i];
+
+            // standard representation for gaps in sequence and structure
+            if (c == '.' || c == ' ')
+            {
+              c = '-';
+            }
+
+            if (c == '-')
+            {
+              values['-']++;
+              continue;
+            }
+            bpEnd = findPair(rna, i);
+            cEnd = seq[bpEnd];
+            if (checkBpType(c, cEnd))
+            {
+              values['H']++; // H means it's a helix (structured)
+            }
+            // System.out.println("pair: "+c+","+cEnd);
+            pairs[c][cEnd]++;
+            // System.out.println("pairs: "+c+","+cEnd+" - "+pairs[c][cEnd]);
+
+            maxResidue = "H";
+          }
+        }
+        // nonGap++;
+      }
+      // UPDATE this for new values
+      if (profile)
+      {
+        // System.out.println("profile");
+        residueHash.put(PROFILE, new int[][]
+        { values, new int[]
+        { jSize, (jSize - values['-']) } });
+
+        residueHash.put(PAIRPROFILE, pairs);
+      }
+
+      count = values['H'];
+
+      residueHash.put(MAXCOUNT, new Integer(count));
+      residueHash.put(MAXRESIDUE, maxResidue);
+
+      percentage = ((float) count * 100) / (float) jSize;
+      residueHash.put(PID_GAPS, new Float(percentage));
+
+      // percentage = ((float) count * 100) / (float) nongap;
+      // residueHash.put(PID_NOGAPS, new Float(percentage));
+      if (result[i] == null)
+      {
+        result[i] = residueHash;
+      }
+      if (bpEnd > 0)
+      {
+        result[bpEnd] = residueHash;
+      }
+    }
   }
 
-        
   /**
-   * Method to check if a base-pair is a canonical or a wobble bp 
-   * @param up 5' base
-   * @param down 3' base
+   * Method to check if a base-pair is a canonical or a wobble bp
+   * 
+   * @param up
+   *          5' base
+   * @param down
+   *          3' base
    * @return True if it is a canonical/wobble bp
    */
-  public static boolean checkBpType(char up, char down){
-         if(up>'Z'){up-=32;}
-         if(down>'Z'){down-=32;}
-         
-         switch (up){
-               case 'A': 
-                       switch (down){
-                               case 'T': return true;
-                               case 'U': return true;
-                       }
-               break;
-               case 'C': 
-                       switch (down){
-                               case 'G': return true;
-                       }
-               break;
-               case 'T': 
-                       switch (down){
-                               case 'A': return true;
-                               case 'G': return true;
-                               }
-               break;
-               case 'G': 
-                       switch (down){
-                               case 'C': return true;
-                               case 'T': return true;
-                               case 'U': return true;
-                       }
-               break;
-               case 'U': 
-                       switch (down){
-                               case 'A': return true;
-                               case 'G': return true;
-                       }
-               break;
-         }       
-         return false;
+  public static boolean checkBpType(char up, char down)
+  {
+    if (up > 'Z')
+    {
+      up -= 32;
+    }
+    if (down > 'Z')
+    {
+      down -= 32;
+    }
+
+    switch (up)
+    {
+    case 'A':
+      switch (down)
+      {
+      case 'T':
+        return true;
+      case 'U':
+        return true;
+      }
+      break;
+    case 'C':
+      switch (down)
+      {
+      case 'G':
+        return true;
+      }
+      break;
+    case 'T':
+      switch (down)
+      {
+      case 'A':
+        return true;
+      case 'G':
+        return true;
+      }
+      break;
+    case 'G':
+      switch (down)
+      {
+      case 'C':
+        return true;
+      case 'T':
+        return true;
+      case 'U':
+        return true;
+      }
+      break;
+    case 'U':
+      switch (down)
+      {
+      case 'A':
+        return true;
+      case 'G':
+        return true;
+      }
+      break;
+    }
+    return false;
   }
-  
+
   /**
    * Compute all or part of the annotation row from the given consensus
    * hashtable
@@ -360,7 +406,7 @@ public class StructureFrequency
   {
     completeConsensus(consensus, hconsensus, iStart, width,
             ignoreGapsInConsensusCalculation, includeAllConsSymbols, null); // new
-                                                                            // char[]
+    // char[]
     // { 'A', 'C', 'G', 'T', 'U' });
   }
 
@@ -369,7 +415,8 @@ public class StructureFrequency
           boolean ignoreGapsInConsensusCalculation,
           boolean includeAllConsSymbols, char[] alphabet)
   {
-       System.out.println("StructureFrequency.completeConsensus "+includeAllConsSymbols);
+    System.out.println("StructureFrequency.completeConsensus "
+            + includeAllConsSymbols);
     float tval, value;
     if (consensus == null || consensus.annotations == null
             || consensus.annotations.length < width)
@@ -398,18 +445,22 @@ public class StructureFrequency
         value = ((Float) hconsensus[i].get(StructureFrequency.PID_GAPS))
                 .floatValue();
       }
-      
-      String maxRes = hconsensus[i].get(StructureFrequency.MAXRESIDUE).toString();
-      String mouseOver = hconsensus[i].get(StructureFrequency.MAXRESIDUE) + " ";
+
+      String maxRes = hconsensus[i].get(StructureFrequency.MAXRESIDUE)
+              .toString();
+      String mouseOver = hconsensus[i].get(StructureFrequency.MAXRESIDUE)
+              + " ";
       if (maxRes.length() > 1)
       {
         mouseOver = "[" + maxRes + "] ";
         maxRes = "+";
       }
-      int[][] profile = (int[][]) hconsensus[i].get(StructureFrequency.PROFILE);
-      if (profile != null && includeAllConsSymbols) //Just responsible for the tooltip
+      int[][] profile = (int[][]) hconsensus[i]
+              .get(StructureFrequency.PROFILE);
+      if (profile != null && includeAllConsSymbols) // Just responsible for the
+      // tooltip
       {
-       //System.out.println("StructureFrequency.includeAllConsSymbols");
+        // System.out.println("StructureFrequency.includeAllConsSymbols");
         mouseOver = "";
         if (alphabet != null)
         {
@@ -425,7 +476,7 @@ public class StructureFrequency
         }
         else
         {
-          //System.out.println("StructureFrequency.NOTincludeAllConsSymbols");
+          // System.out.println("StructureFrequency.NOTincludeAllConsSymbols");
           Object[] ca = new Object[profile[0].length];
           float[] vl = new float[profile[0].length];
           for (int c = 0; c < ca.length; c++)
@@ -469,59 +520,55 @@ public class StructureFrequency
    * @return
    */
   public static int[] extractProfile(Hashtable hconsensus,
-                 boolean ignoreGapsInConsensusCalculation,
-                 int column)
+          boolean ignoreGapsInConsensusCalculation, int column)
   {
-          //TODO is there a more elegant way to acces the column number?
-          /*
-           * calculate the frequence of the 16 bp variations for this column
-           * 'somehow' transfer this via getProfile and let it correctly draw
-           */
-          int[] rtnval = new int[22];
-         int[][] profile = (int[][]) hconsensus.get(StructureFrequency.PROFILE);
-         if (profile == null)
-                 return null;
-         
-         Object[] ca = new Object[profile[0].length];
-         float[] vl = new float[profile[0].length];
-         for (int c = 0; c < ca.length; c++)
-         {
-                 ca[c] = new char[]
-                                  { (char) c };
-                 vl[c] = (float) profile[0][c];
-         }
-         ;
-         jalview.util.QuickSort.sort(vl, ca);
-         rtnval[0] = 1;
-         for (int c = ca.length - 1; profile[0][((char[]) ca[c])[0]] > 0; c--)
-         {
-                 if (((char[]) ca[c])[0] != '-')
-                 {
-                         rtnval[rtnval[0]++] = ((char[]) ca[c])[0];
-                         //System.out.println("rtnval-"+c+": "+((char[]) ca[c])[0]);
-                         rtnval[rtnval[0]++] = (int) (((float) profile[0][((char[]) ca[c])[0]]) * 100f / (float) profile[1][ignoreGapsInConsensusCalculation ? 1
-                                         : 0]);
-                 }
-         }
-         for(int i=0; i<rtnval.length;i++){
-         //  System.out.print(rtnval[i]+",");
-         }
-         System.out.print("\n");
-         return rtnval;
+    // TODO is there a more elegant way to acces the column number?
+    /*
+     * calculate the frequence of the 16 bp variations for this column 'somehow'
+     * transfer this via getProfile and let it correctly draw
+     */
+    int[] rtnval = new int[51]; // 2*(5*5)+1
+    int[][] profile = (int[][]) hconsensus.get(StructureFrequency.PROFILE);
+    int[][] pairs = (int[][]) hconsensus
+            .get(StructureFrequency.PAIRPROFILE);
+
+    if (profile == null)
+      return null;
+    
+    rtnval[0] = 1;
+    for (int j = 65; j <= 90; j++)
+    {
+      for (int k = 65; k <= 90; k++)
+      {
+        if (pairs[j][k] > 0)
+        {
+          rtnval[rtnval[0]++] = j;
+          rtnval[rtnval[0]++] = k;
+          rtnval[rtnval[0]++] = (int) ((float) pairs[j][k] * 100f / (float) profile[1][ignoreGapsInConsensusCalculation ? 1
+                  : 0]);
+        }
+      }
+    }
+
+    return rtnval;
   }
 
-  public static void main(String args[]){
-         //Short test to see if checkBpType works
-         ArrayList<String> test = new ArrayList<String>();
-         test.add("A");
-         test.add("c");
-         test.add("g");
-         test.add("T");
-         test.add("U");
-         for (String i : test) {
-                 for (String j : test) {
-                         System.out.println(i+"-"+j+": "+StructureFrequency.checkBpType(i.charAt(0),j.charAt(0)));
-                 }
-         }
+  public static void main(String args[])
+  {
+    // Short test to see if checkBpType works
+    ArrayList<String> test = new ArrayList<String>();
+    test.add("A");
+    test.add("c");
+    test.add("g");
+    test.add("T");
+    test.add("U");
+    for (String i : test)
+    {
+      for (String j : test)
+      {
+        System.out.println(i + "-" + j + ": "
+                + StructureFrequency.checkBpType(i.charAt(0), j.charAt(0)));
+      }
+    }
   }
 }
index 1acc0ca..ca9b95f 100755 (executable)
@@ -1572,12 +1572,12 @@ public class AnnotationPanel extends JPanel implements MouseListener,
           char[] dc;
 
           /**
-           * profl.length == 11 indicates that the profile of a secondary
+           * profl.length == 51 indicates that the profile of a secondary
            * structure conservation row was accesed.
            * Therefore dc gets length 2, to have space for a basepair instead of
            * just a single nucleotide
            */
-          if (profl.length == 22)
+          if (profl.length == 51)
           {
             dc = new char[2];
           }
@@ -1593,7 +1593,7 @@ public class AnnotationPanel extends JPanel implements MouseListener,
 
             if (aa.label.startsWith("StrucConsensus"))
             {
-              dc[1] = 'A';
+              dc[1] = (char) profl[c++];
             }
             
             wdth = av.charWidth;