00001 package org.gel.mauve.analysis;
00002
00003 import java.util.Comparator;
00004 import java.util.Iterator;
00005 import java.util.List;
00006
00007 import org.biojava.bio.seq.FeatureHolder;
00008 import org.gel.mauve.Chromosome;
00009 import org.gel.mauve.Genome;
00010 import org.gel.mauve.LCB;
00011 import org.gel.mauve.XmfaViewerModel;
00012
00013 public class Gap implements Comparable<Gap>{
00014
00015
00016 private int genSrcIdx;
00017
00018 private int lcbId;
00019
00020 private int lcbCol;
00021
00022 private long position;
00023
00024 private int posInCtg;
00025
00026 private Chromosome chrom;
00027
00028 private long length;
00029
00030 private XmfaViewerModel model;
00031
00032 private long[] pos;
00033
00034 private Chromosome[] chromosomes;
00035
00036
00046 public Gap(int genomeSrcIdx, int lcb, long pos, long len, XmfaViewerModel model){
00047 this.genSrcIdx = genomeSrcIdx;
00048 this.position = pos;
00049 this.length = len;
00050 this.lcbId = lcb;
00051 this.model = model;
00052 Genome[] genomes = model.getGenomes().toArray(new Genome[model.getGenomes().size()]);
00053 Genome g = model.getGenomeBySourceIndex(genSrcIdx);
00054 this.chrom = g.getChromosomeAt(position);
00055 if (this.chrom == null) System.err.println("Null Chromosome");
00056 this.posInCtg = (int) (position - this.chrom.getStart()+1);
00057 this.lcbCol = (int) model.getLCBAndColumn(g, position)[1];
00058 this.pos = new long[model.getGenomes().size()];
00059 long[] ar = model.getLCBAndColumn(genomeSrcIdx, pos);
00060 boolean[] gap = new boolean[model.getGenomes().size()];
00061 model.getColumnCoordinates((int)ar[0], ar[1], this.pos, gap);
00062 chromosomes = new Chromosome[genomes.length];
00063 for (int i = 0; i < genomes.length; i++){
00064 chromosomes[i] = genomes[i].getChromosomeAt(this.pos[i]);
00065 }
00066 }
00067
00068 private Gap(Gap gap){
00069 this.genSrcIdx = gap.genSrcIdx;
00070 this.position = gap.position;
00071 this.length = gap.length;
00072 this.lcbId = gap.lcbId;
00073 this.model = gap.model;
00074 this.chrom = gap.chrom;
00075 this.posInCtg = gap.posInCtg;
00076 this.lcbCol = gap.lcbCol;
00077 this.pos = new long[gap.pos.length];
00078 System.arraycopy(gap.pos, 0, this.pos, 0, this.pos.length);
00079 this.chromosomes = new Chromosome[gap.chromosomes.length];
00080 System.arraycopy(gap.chromosomes, 0, this.chromosomes, 0, this.chromosomes.length);
00081 }
00082
00083
00089 public String toString(){
00090 return this.toString("sequence_"+Integer.toString(genSrcIdx));
00091 }
00092
00093
00094
00104 public String toString(String genomeName){
00105 StringBuilder sb = new StringBuilder();
00106 sb.append(genomeName +"\t"+ chrom.getName() + "\t"+
00107 Integer.toString(posInCtg)+"\t" +
00108 Long.toString(position) +"\t"+ Long.toString(length));
00109 for (int i = 0; i < pos.length; i++){
00110 int ctg_pos = (int)(pos[i] - chromosomes[i].getStart()+1);
00111 sb.append("\t"+pos[i]+"\t"+chromosomes[i].getName()+"\t"+ctg_pos);
00112 }
00113 return sb.toString();
00114 }
00115
00116 public int getGenomeSrcIdx(){
00117 return genSrcIdx;
00118 }
00119
00120 public long getPosition(){
00121 return position;
00122 }
00123
00124 public long getLength(){
00125 return length;
00126 }
00127
00128 public int getLCB(){
00129 return lcbId;
00130 }
00131
00132 public FeatureHolder getFeatures(int genSrcIdx){
00133 Genome genome = model.getGenomeBySourceIndex(genSrcIdx);
00134 long[] starts = new long[model.getGenomes().size()];
00135 boolean[] gapS = new boolean[model.getGenomes().size()];
00136 long[] ends = new long[model.getGenomes().size()];
00137 boolean[] gapE = new boolean[model.getGenomes().size()];
00138 model.getColumnCoordinates(lcbId, lcbCol, starts, gapS);
00139 model.getColumnCoordinates(lcbId, lcbCol+1, ends, gapE);
00140 long left = Math.min(starts[genSrcIdx],ends[genSrcIdx]);
00141 long right = Math.max(starts[genSrcIdx],ends[genSrcIdx]);
00142 boolean rev = starts[genSrcIdx] > ends[genSrcIdx];
00143 return genome.getAnnotationsAt(left, right, rev);
00144 }
00145
00146
00153 public Chromosome getContig(){
00154 return chrom;
00155 }
00156
00165 public int getPositionInContig(){
00166 return posInCtg;
00167 }
00168
00169 public int compareTo(Gap g){
00170 if (this.genSrcIdx == g.genSrcIdx){
00171 if (this.position == g.position){
00172 if (this.length == g.length){
00173 return 0;
00174 } else {
00175 return this.length < g.length ? -1 : 1;
00176 }
00177 } else {
00178 return this.position < g.position ? -1 : 1;
00179 }
00180 } else {
00181 return this.genSrcIdx < g.genSrcIdx ? -1 : 1;
00182 }
00183 }
00184
00185
00186 public static Gap mergeGaps(Gap a, Gap b){
00187 if (a.genSrcIdx != b.genSrcIdx)
00188 throw new IllegalArgumentException("Can't merge gaps that aren't from same genome");
00189 if (a.position != b.position)
00190 throw new IllegalArgumentException("Can't merge gaps that don't start at the same position");
00191
00192 Gap ret = new Gap(a);
00193 ret.length += b.length;
00194 return ret;
00195
00196 }
00197
00198 public static Comparator<Gap> getAlnmtPosComparator(){
00199 return new Comparator<Gap>(){
00200 public int compare(Gap a, Gap b){
00201 if (a.genSrcIdx == b.genSrcIdx){
00202 if (a.position == b.position){
00203 return (int) (a.length - b.length);
00204 } else {
00205 return (int) (a.position - b.position);
00206 }
00207 } else {
00208 return a.genSrcIdx-b.genSrcIdx;
00209 }
00210 }
00211 };
00212 }
00230 public int relativePos(LiteWeightFeature feat){
00231 int pos = (int) Math.abs(this.pos[feat.getGenSrcIdx()]);
00232 if (pos < feat.getLeft())
00233 return -1;
00234 else if (pos <= feat.getRight())
00235 return 0;
00236 else
00237 return 1;
00238 }
00239
00240 }