moving word methods to MapList and begin bug-fix for single-residue codon span featur...
[jalview.git] / src / jalview / util / MapList.java
index 5da89b0..826ead7 100644 (file)
@@ -31,13 +31,6 @@ import java.util.*;
 public class MapList
 {
   /* (non-Javadoc)
-   * @see java.lang.Object#clone()
-   */
-  protected Object clone() throws CloneNotSupportedException {
-    // TODO Auto-generated method stub
-    return super.clone();
-  }
-  /* (non-Javadoc)
    * @see java.lang.Object#equals(java.lang.Object)
    */
   public boolean equals(MapList obj) {
@@ -45,27 +38,25 @@ public class MapList
       return true;
     if (obj!=null && obj.fromRatio==fromRatio && obj.toRatio==toRatio
         && obj.fromShifts!=null && obj.toShifts!=null) {
-      Iterator i,j;
-      for (i=fromShifts.iterator(),j=obj.fromShifts.iterator(); i.hasNext();) {
-        int[] mi=(int[]) i.next();
-        if (!j.hasNext())
-          return false;
-        int[] mj=(int[]) j.next();
+      int i,iSize=fromShifts.size(),j,jSize=obj.fromShifts.size();
+      if (iSize!=jSize)
+        return false;
+      for (i=0,iSize=fromShifts.size(),j=0, jSize=obj.fromShifts.size(); i<iSize;) {
+        int[] mi=(int[]) fromShifts.elementAt(i++);
+        int[] mj=(int[]) obj.fromShifts.elementAt(j++);
         if (mi[0]!=mj[0] || mi[1]!=mj[1])
           return false;
       }
-      if (j.hasNext())
+      iSize=toShifts.size();
+      jSize=obj.toShifts.size();
+      if (iSize!=jSize)
         return false;
-      for (i=toShifts.iterator(),j=obj.toShifts.iterator(); i.hasNext();) {
-        int[] mi=(int[]) i.next();
-        if (!j.hasNext())
-          return false;
-        int[] mj=(int[]) j.next();
+      for (i=0,j=0; i<iSize;) {
+        int[] mi=(int[]) toShifts.elementAt(i++);
+        int[] mj=(int[]) obj.toShifts.elementAt(j++);
         if (mi[0]!=mj[0] || mi[1]!=mj[1])
           return false;
       }
-      if (j.hasNext())
-        return false;
       return true;
     }
     return false;
@@ -81,7 +72,7 @@ public class MapList
   /**
    * lowest and highest value in the to Map
    */
-  int[] toRange=null; 
+  int[] toRange=null;
   public int getFromRatio()
   {
     return fromRatio;
@@ -115,11 +106,11 @@ public class MapList
 
     fromShifts = new Vector();
     for (int i=0;i<from.length; i+=2)
-    {      
+    {
       ensureRange(fromRange, from[i]);
       ensureRange(fromRange, from[i+1]);
 
-      fromShifts.add(new int[]
+      fromShifts.addElement(new int[]
                              {from[i], from[i + 1]});
     }
     toShifts = new Vector();
@@ -127,12 +118,43 @@ public class MapList
     {
       ensureRange(toRange, to[i]);
       ensureRange(toRange, to[i+1]);
-      toShifts.add(new int[]
+      toShifts.addElement(new int[]
                            {to[i], to[i + 1]});
     }
     this.fromRatio=fromRatio;
     this.toRatio=toRatio;
   }
+  public MapList(MapList map)
+  {
+    this.fromRange = new int[]
+    { map.fromRange[0], map.fromRange[1] };
+    this.toRange = new int[]
+    { map.toRange[0], map.toRange[1] };
+    this.fromRatio = map.fromRatio;
+    this.toRatio = map.toRatio;
+    if (map.fromShifts != null)
+    {
+      this.fromShifts = new Vector();
+      Enumeration e = map.fromShifts.elements();
+      while (e.hasMoreElements())
+      {
+        int[] el = (int[]) e.nextElement();
+        fromShifts.addElement(new int[]
+        { el[0], el[1] });
+      }
+    }
+    if (map.toShifts != null)
+    {
+      this.toShifts = new Vector();
+      Enumeration e = map.toShifts.elements();
+      while (e.hasMoreElements())
+      {
+        int[] el = (int[]) e.nextElement();
+        toShifts.addElement(new int[]
+        { el[0], el[1] });
+      }
+    }
+  }
   /**
    * get all mapped positions from 'from' to 'to'
    * @return int[][] { int[] { fromStart, fromFinish, toStart, toFinish }, int [fromFinish-fromStart+2] { toStart..toFinish mappings}}
@@ -157,21 +179,21 @@ public class MapList
   private int[][] posMap(Vector intVals, int ratio, Vector toIntVals,
       int toRatio)
   {
-    Iterator iv = intVals.iterator();
-    if (!iv.hasNext())
+    int iv=0,ivSize = intVals.size();
+    if (iv>=ivSize)
     {
       return null;
     }
-    int[] intv=(int[]) iv.next();
+    int[] intv=(int[]) intVals.elementAt(iv++);
     int from=intv[0],to=intv[1];
     if (from > to)
     {
       from = intv[1];
       to=intv[0];
     }
-    while (iv.hasNext())
+    while (iv<ivSize)
     {
-      intv = (int[]) iv.next();
+      intv = (int[]) intVals.elementAt(iv++);
       if (intv[0]<from)
       {
         from=intv[0];
@@ -274,7 +296,7 @@ public class MapList
     return shift(pos, toShifts, toRatio, fromShifts, fromRatio);
   }
   /**
-   * 
+   *
    * @param fromShifts
    * @param fromRatio
    * @param toShifts
@@ -284,14 +306,14 @@ public class MapList
   private int[] shift(int pos, Vector fromShifts, int fromRatio,
       Vector toShifts, int toRatio)
   {
-    int[] fromCount = countPos(fromShifts.iterator(), pos);
+    int[] fromCount = countPos(fromShifts, pos);
     if (fromCount==null)
     {
       return null;
     }
     int fromRemainder=(fromCount[0]-1) % fromRatio;
     int toCount = 1+(((fromCount[0]-1) / fromRatio) * toRatio);
-    int[] toPos = countToPos(toShifts.iterator(), toCount);
+    int[] toPos = countToPos(toShifts, toCount);
     if (toPos==null)
     {
       return null; // throw new Error("Bad Mapping!");
@@ -307,12 +329,12 @@ public class MapList
    * @param pos
    * @return number of positions or null if pos is not within intervals
    */
-  private int[] countPos(Iterator intVals, int pos)
+  private int[] countPos(Vector intVals, int pos)
   {
-    int count=0,intv[];
-    while (intVals.hasNext())
+    int count=0,intv[],iv=0,ivSize=intVals.size();
+    while (iv<ivSize)
     {
-      intv = (int[])intVals.next();
+      intv = (int[])intVals.elementAt(iv++);
       if (intv[0] <= intv[1])
       {
         if (pos >= intv[0] && pos <= intv[1])
@@ -348,14 +370,14 @@ public class MapList
    * @param pos
    * @return position pos in interval set
    */
-  private int[] countToPos(Iterator intVals, int pos)
+  private int[] countToPos(Vector intVals, int pos)
   {
-    int count = 0, diff = 0, intv[] =
+    int count = 0, diff = 0, iv=0,ivSize=intVals.size(), intv[] =
     {
         0, 0};
-    while (intVals.hasNext())
+    while (iv<ivSize)
     {
-      intv = (int[])intVals.next();
+      intv = (int[])intVals.elementAt(iv++);
       diff = intv[1]-intv[0];
       if (diff >= 0)
       {
@@ -395,7 +417,7 @@ public class MapList
   public int[] locateInFrom(int start, int end) {
     // inefficient implementation
     int fromStart[] = shiftTo(start);
-    int fromEnd[] = shiftTo(end);
+    int fromEnd[] = shiftTo(end); // needs to be inclusive of end of symbol position
     if (fromStart==null || fromEnd==null)
       return null;
     int iv[] = getIntervals(fromShifts, fromStart, fromEnd,fromRatio);
@@ -428,26 +450,28 @@ public class MapList
    */
   private int[] getIntervals(Vector fromShifts2, int[] fromStart, int[] fromEnd, int fromRatio2)
   {
-    // correct for word direction for start and end
-    int startpos = fromStart[0]+fromStart[2]*(fromRatio2-1);
-    int endpos = fromEnd[0]+fromEnd[2]*(fromRatio2-1);
-    Iterator intv = fromShifts2.iterator();
+    // TODO: correct for word boundary w.r.t. fromStart->fromEnd direction for startpos and endpos.
+    // test is (1,8,12,17) to (1,5) and features on to : 2,2; 3,3; 4,3; 3,4; 4,4; 5,3; 3,5; 2,4; 4,2;
+    // correct for word direction for start and end :
+    int startpos = fromStart[0]+fromStart[2]*(fromRatio2-1); // Math.min(fromStart[0], .. );
+    int endpos = fromEnd[0]+fromEnd[2]*(fromRatio2-1); // Math.max(fromEnd[0],);
+    int intv=0,intvSize= fromShifts2.size();
     int iv[],i=0,fs=-1,fe=-1; // containing intervals
-    while (intv.hasNext() && (fs==-1 || fe==-1)) {
-      iv = (int[]) intv.next();
+    while (intv<intvSize && (fs==-1 || fe==-1)) {
+      iv = (int[]) fromShifts2.elementAt(intv++);
       if (iv[0]<=iv[1]) {
         if (fs==-1 && startpos>=iv[0] && startpos<=iv[1]) {
-          fs = i; 
+          fs = i;
         }
         if (fe==-1 && endpos>=iv[0] && endpos<=iv[1]) {
-          fe = i; 
+          fe = i;
         }
       } else {
         if (fs==-1 && startpos<=iv[0] && startpos>=iv[1]) {
-          fs = i; 
+          fs = i;
         }
         if (fe==-1 && endpos<=iv[0] && endpos>=iv[1]) {
-          fe = i; 
+          fe = i;
         }
       }
       i++;
@@ -456,20 +480,16 @@ public class MapList
       return null;
     Vector ranges=new Vector();
     if (fs<=fe) {
-      intv = fromShifts2.iterator();
-      i=0;
-      while (i<fs) {
-        intv.next();
-        i++;
-      }
+      intv = fs;
+      i=fs;
       // truncate initial interval
-      iv = (int[]) intv.next();
+      iv = (int[]) fromShifts2.elementAt(intv++);
       iv = new int[] { iv[0], iv[1]};// clone
       if (i==fs)
         iv[0] = startpos;
       while (i!=fe) {
         ranges.addElement(iv); // add initial range
-        iv = (int[]) intv.next(); // get next interval
+        iv = (int[]) fromShifts2.elementAt(intv++); // get next interval
         iv = new int[] { iv[0], iv[1]};// clone
         i++;
       }
@@ -485,7 +505,7 @@ public class MapList
       iv = (int[]) fromShifts2.elementAt(i);
       iv = new int[] { iv[1], iv[0]};//  reverse and clone
       // truncate initial interval
-      if (i==fs) 
+      if (i==fs)
       {
         iv[0] = startpos;
       }
@@ -502,22 +522,73 @@ public class MapList
     }
     // create array of start end intervals.
     int[] range = null;
-    if (ranges!=null && ranges.size()>0) 
+    if (ranges!=null && ranges.size()>0)
     {
       range = new int[ranges.size()*2];
-      intv = ranges.iterator();
-      i=0; 
-      while (intv.hasNext()) 
+      intv = 0;
+      intvSize=ranges.size();
+      i=0;
+      while (intv<intvSize)
       {
-        iv = (int[]) intv.next();
+        iv = (int[]) ranges.elementAt(intv);
         range[i++] = iv[0];
         range[i++] = iv[1];
-        intv.remove();
+        ranges.setElementAt(null, intv++); // remove
       }
     }
     return range;
   }
   /**
+ * get the 'initial' position of mpos in To
+ * @param mpos position in from
+ * @return position of first word in to reference frame
+ */
+public int getToPosition(int mpos)
+{
+  int[] mp = shiftTo(mpos);
+  if (mp!=null)
+  {
+    return mp[0];
+  }
+  return mpos;
+}
+/**
+ * get range of positions in To frame for the mpos word in From
+ * @param mpos position in From
+ * @return null or int[] first position in To for mpos, last position in to for Mpos
+ */
+public int[] getToWord(int mpos) {
+  int[] mp=shiftTo(mpos);
+  if (mp!=null) {
+      return new int[] {mp[0], mp[0]+mp[2]*(getFromRatio()-1)};
+  }
+  return null;
+}
+/**
+ * get From position in the associated
+ * reference frame for position pos in the
+ * associated sequence.
+ * @param pos
+ * @return
+ */
+public int getMappedPosition(int pos) {
+  int[] mp = shiftFrom(pos);
+  if (mp!=null)
+  {
+    return mp[0];
+  }
+  return pos;
+}
+public int[] getMappedWord(int pos) {
+  int[] mp = shiftFrom(pos);
+  if (mp!=null)
+  {
+    return new int[] { mp[0], mp[0]+mp[2]*(getToRatio()-1)};
+  }
+  return null;
+}
+
+  /**
    * test routine. not incremental.
    * @param ml
    * @param fromS
@@ -582,7 +653,7 @@ public class MapList
     System.out.print("\nTest locateInFrom\n");
     {
       int f=mmap[0][2],t=mmap[0][3];
-      while (f<t) {
+      while (f<=t) {
         System.out.println("Range "+f+" to "+t);
         int rng[] = ml.locateInFrom(f,t);
         if (rng!=null)
@@ -610,7 +681,7 @@ public class MapList
         System.out.print("\n");
         f++;t--;
       }
-    }    
+    }
     System.out.print("\n");
     mmap = ml.makeToMap();
     System.out.println("ToMap : (" + mmap[0][0] + " " + mmap[0][1] + " " +
@@ -640,7 +711,7 @@ public class MapList
     System.out.print("\nTest locateInTo\n");
     {
       int f=mmap[0][2],t=mmap[0][3];
-      while (f<t) {
+      while (f<=t) {
         System.out.println("Range "+f+" to "+t);
         int rng[] = ml.locateInTo(f,t);
         if (rng!=null) {
@@ -667,7 +738,7 @@ public class MapList
         f++; t--;
         System.out.print("\n");
       }
-    }    
+    }
 
   }