From: jprocter Date: Thu, 28 Jun 2007 19:56:17 +0000 (+0000) Subject: imported utility classes for working with MapTypes from Jalview (v 2.3+ code) X-Git-Tag: Release_0.2~100 X-Git-Url: http://source.jalview.org/gitweb/?p=vamsas.git;a=commitdiff_plain;h=ebf96b94c3df53770d7cb8585cb89edff3de075d imported utility classes for working with MapTypes from Jalview (v 2.3+ code) git-svn-id: https://svn.lifesci.dundee.ac.uk/svn/repository/trunk@420 be28352e-c001-0410-b1a7-c7978e42abec --- diff --git a/src/uk/ac/vamsas/objects/utils/MapList.java b/src/uk/ac/vamsas/objects/utils/MapList.java new file mode 100644 index 0000000..5052c94 --- /dev/null +++ b/src/uk/ac/vamsas/objects/utils/MapList.java @@ -0,0 +1,810 @@ +/* + * This code was originated from + * Jalview - A Sequence Alignment Editor and Viewer + * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +package uk.ac.vamsas.objects.utils; + +import java.util.*; + +/** + * MapList + * Simple way of bijectively mapping a non-contiguous linear range to another non-contiguous linear range + * Use at your own risk! + * TODO: efficient implementation of private posMap method + * TODO: test/ensure that sense of from and to ratio start position is conserved (codon start position recovery) + * TODO: optimize to use int[][] arrays rather than vectors. + */ +public class MapList +{ + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(MapList obj) { + if (obj==this) + return true; + if (obj!=null && obj.fromRatio==fromRatio && obj.toRatio==toRatio + && obj.fromShifts!=null && obj.toShifts!=null) { + 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(); ipos) + limits[0]=pos; + if (limits[1]=ivSize) + { + return null; + } + int[] intv=(int[]) intVals.elementAt(iv++); + int from=intv[0],to=intv[1]; + if (from > to) + { + from = intv[1]; + to=intv[0]; + } + while (ivto) + { + to=intv[0]; + } + if (intv[1]>to) + { + to=intv[1]; + } + } + int tF=0,tT=0; + int mp[][] = new int[to-from+2][]; + for (int i = 0; i < mp.length; i++) + { + int[] m = shift(i+from,intVals,ratio,toIntVals, toRatio); + if (m != null) + { + if (i == 0) + { + tF=tT=m[0]; + } + else + { + if (m[0] < tF) + { + tF=m[0]; + } + if (m[0] > tT) + { + tT=m[0]; + } + } + } + mp[i] = m; + } + int[][] map = new int[][] + { + new int[] + { + from, to, tF, tT}, new int[to - from + 2]}; + + map[0][2] = tF; + map[0][3] = tT; + + for (int i = 0; i < mp.length; i++) + { + if (mp[i] != null) + { + map[1][i] = mp[i][0]-tF; + } + else + { + map[1][i] = -1; // indicates an out of range mapping + } + } + return map; + } + /** + * addShift + * @param pos start position for shift (in original reference frame) + * @param shift length of shift + * + public void addShift(int pos, int shift) + { + int sidx = 0; + int[] rshift=null; + while (sidx= intv[0] && pos <= intv[1]) + { + return new int[] + { + count + pos - intv[0] + 1, +1}; + } + else + { + count+=intv[1]-intv[0]+1; + } + } + else + { + if (pos >= intv[1] && pos <= intv[0]) + { + return new int[] + { + count + intv[0] - pos + 1, -1}; + } + else + { + count+=intv[0]-intv[1]+1; + } + } + } + return null; + } + /** + * count out pos positions into a series of intervals and return the position + * @param intVals + * @param pos + * @return position pos in interval set + */ + private int[] countToPos(Vector intVals, int pos) + { + int count = 0, diff = 0, iv=0,ivSize=intVals.size(), intv[] = + { + 0, 0}; + while (iv= 0) + { + if (pos <= count + 1 + diff) + { + return new int[] + { + pos - count - 1 + intv[0], +1}; + } + else + { + count+=1+diff; + } + } + else + { + if (pos <= count + 1 - diff) + { + return new int[] + { + intv[0] - (pos - count - 1), -1}; + } + else + { + count+=1-diff; + } + } + } + return null;//(diff<0) ? (intv[1]-1) : (intv[0]+1); + } + /** + * find series of intervals mapping from start-end in the From map. + * @param start position in to map + * @param end position in to map + * @return series of ranges in from map + */ + public int[] locateInFrom(int start, int end) { + // inefficient implementation + int fromStart[] = shiftTo(start); + 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); + return iv; + } + + /** + * find series of intervals mapping from start-end in the to map. + * @param start position in from map + * @param end position in from map + * @return series of ranges in to map + */ + public int[] locateInTo(int start, int end) { + // inefficient implementation + int toStart[] = shiftFrom(start); + int toEnd[] = shiftFrom(end); + if (toStart==null || toEnd==null) + return null; + int iv[] = getIntervals(toShifts, toStart, toEnd, toRatio); + return iv; + } + /** + * like shift - except returns the intervals in the given vector of shifts which were spanned + * in traversing fromStart to fromEnd + * @param fromShifts2 + * @param fromStart + * @param fromEnd + * @param fromRatio2 + * @return series of from,to intervals from from first position of starting region to final position of ending region inclusive + */ + private int[] getIntervals(Vector fromShifts2, int[] fromStart, int[] fromEnd, int fromRatio2) + { + int startpos,endpos; + startpos = fromStart[0]; // first position in fromStart + endpos = fromEnd[0]+fromEnd[2]*(fromRatio2-1); // last position in fromEnd + int intv=0,intvSize= fromShifts2.size(); + int iv[],i=0,fs=-1,fe=-1; // containing intervals + while (intv=iv[0] && startpos<=iv[1]) { + fs = i; + } + if (fe==-1 && endpos>=iv[0] && endpos<=iv[1]) { + fe = i; + } + } else { + if (fs==-1 && startpos<=iv[0] && startpos>=iv[1]) { + fs = i; + } + if (fe==-1 && endpos<=iv[0] && endpos>=iv[1]) { + fe = i; + } + } + i++; + } + if (fs==fe && fe==-1) + return null; + Vector ranges=new Vector(); + if (fs<=fe) { + intv = fs; + i=fs; + // truncate initial interval + 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[]) fromShifts2.elementAt(intv++); // get next interval + iv = new int[] { iv[0], iv[1]};// clone + i++; + } + if (i==fe) + iv[1] = endpos; + ranges.addElement(iv); // add only - or final range + } else { + // walk from end of interval. + i=fromShifts2.size()-1; + while (i>fs) { + i--; + } + iv = (int[]) fromShifts2.elementAt(i); + iv = new int[] { iv[1], iv[0]};// reverse and clone + // truncate initial interval + if (i==fs) + { + iv[0] = startpos; + } + while (--i!=fe) { // fix apparent logic bug when fe==-1 + ranges.addElement(iv); // add (truncated) reversed interval + iv = (int[]) fromShifts2.elementAt(i); + iv = new int[] { iv[1], iv[0] }; // reverse and clone + } + if (i==fe) { + // interval is already reversed + iv[1] = endpos; + } + ranges.addElement(iv); // add only - or final range + } + // create array of start end intervals. + int[] range = null; + if (ranges!=null && ranges.size()>0) + { + range = new int[ranges.size()*2]; + intv = 0; + intvSize=ranges.size(); + i=0; + while (intv" + toofrom[0]); + } + System.out.println("ShiftTo(" + too[0] + ")==" + toofrom[0] + " % " + + toofrom[1]+" ("+toofrom[2]+")"); + } + else + { + System.out.println("ShiftTo(" + too[0] + ")==" + + "NaN! - not Bijective Mapping!"); + } + } + } + int mmap[][] = ml.makeFromMap(); + System.out.println("FromMap : (" + mmap[0][0] + " " + mmap[0][1] + " " + + mmap[0][2] + " " + mmap[0][3] + " "); + for (int i = 1; i <= mmap[1].length; i++) + { + if (mmap[1][i - 1] == -1) + { + System.out.print(i+"=XXX"); + + } + else + { + System.out.print(i+"="+(mmap[0][2]+mmap[1][i-1])); + } + if (i % 20==0) + { + System.out.print("\n"); + } + else + { + System.out.print(","); + } + } + //test range function + System.out.print("\nTest locateInFrom\n"); + { + int f=mmap[0][2],t=mmap[0][3]; + while (f<=t) { + System.out.println("Range "+f+" to "+t); + int rng[] = ml.locateInFrom(f,t); + if (rng!=null) + { + for (int i=0; i 2) + vf[v].setDescription(f.getDescription() + "\nPart " + v); + } + */ + return frange; + } + } + // give up and just return the interval unchanged - this might not be the correct behaviour + return new int[] { begin, end }; + } + + /** + * return a series of contigs on the associated sequence corresponding to the + * from,to interval on the mapped reference frame + * + * @param from + * @param to + * @return int[] { from_i, to_i for i=1 to n contiguous regions in the + * associated sequence} + */ + public int[] locateRange(int from, int to) + { + if (map != null) + { + if (from <= to) + { + from = (map.getToLowest() < from) ? from : map.getToLowest(); + to = (map.getToHighest() > to) ? to : map.getToHighest(); + if (from > to) + return null; + } + else + { + from = (map.getToHighest() > from) ? from : map.getToHighest(); + to = (map.getToLowest() < to) ? to : map.getToLowest(); + if (from < to) + return null; + } + return map.locateInFrom(from, to); + } + return new int[] + { from, to }; + } + + /** + * return a series of mapped contigs mapped from a range on the associated + * sequence + * + * @param from + * @param to + * @return + */ + public int[] locateMappedRange(int from, int to) + { + if (map != null) + { + + if (from <= to) + { + from = (map.getFromLowest() < from) ? from : map.getFromLowest(); + to = (map.getFromHighest() > to) ? to : map.getFromHighest(); + if (from > to) + return null; + } + else + { + from = (map.getFromHighest() > from) ? from : map.getFromHighest(); + to = (map.getFromLowest() < to) ? to : map.getFromLowest(); + if (from < to) + return null; + } + return map.locateInTo(from, to); + } + return new int[] + { from, to }; + } + + /** + * return a new mapping object with a maplist modifed to only map the visible + * regions defined by viscontigs. + * + * @param viscontigs + * @return + */ + public Mapping intersectVisContigs(int[] viscontigs) + { + Mapping copy = new Mapping(this); + if (map != null) + { + Vector toRange = new Vector(); + Vector fromRange = new Vector(); + for (int vc = 0; vc < viscontigs.length; vc += 2) + { + // find a mapped range in this visible region + int[] mpr = locateMappedRange(1+viscontigs[vc], viscontigs[vc + 1]-1); + if (mpr != null) + { + for (int m = 0; m < mpr.length; m += 2) + { + toRange.addElement(new int[] + { mpr[m], mpr[m + 1] }); + int[] xpos = locateRange(mpr[m], mpr[m + 1]); + for (int x = 0; x < xpos.length; x += 2) + { + fromRange.addElement(new int[] + { xpos[x], xpos[x + 1] }); + } + } + } + } + int[] from = new int[fromRange.size()*2]; + int[] to = new int[toRange.size()*2]; + int[] r; + for (int f=0,fSize=fromRange.size(); f Protein exon map and a range of visContigs + */ + MapList fk = new MapList(new int[] { 1,6,8,13,15,23}, new int[] { 1,7}, 3, 1); + Mapping m = new Mapping(fk); + Mapping m_1 = m.intersectVisContigs(new int[] {fk.getFromLowest(), fk.getFromHighest()}); + Mapping m_2 = m.intersectVisContigs(new int[] {1,7,11,20}); + System.out.println(""+m_1.map.getFromRanges()); + // this test was for debugging purposes only - it should run without exceptions, but the + // integrity of the mapping was checked using an interactive debugger rather than programmatically. + } +}