00001 package org.gel.mauve.dcjx;
00002
00003 import java.awt.CardLayout;
00004 import java.awt.Panel;
00005 import java.io.OutputStream;
00006 import java.io.PrintStream;
00007 import java.util.HashMap;
00008 import java.util.Vector;
00009
00010 import javax.swing.JTextArea;
00011
00012 import org.gel.mauve.BaseViewerModel;
00013 import org.gel.mauve.Genome;
00014 import org.gel.mauve.XmfaViewerModel;
00015 import org.gel.mauve.analysis.PermutationExporter;
00016 import org.gel.mauve.gui.AnalysisDisplayWindow;
00017
00018 public class DCJDistance {
00019
00020
00021
00022 private static final String NWAY_COMMAND = "N-Way";
00023 private static final String NWAY_DESC = "Distances based on N-Way LCBs";
00024 private static final String PWISE_COMMAND = "Pairwise";
00025 private static final String PWISE_DESC = "Distances based on Pairwise LCBs";
00026 private static final String NBLKS_COMMAND = "NoBlocks";
00027 private static final String NBLKS_DESC = "Number of blocks between each pair";
00028
00029 private static final String temp = "Running...";
00030 private static final String error = "Error computing DCJ distances! Please report bug to atritt@ucdavis.edu";
00031
00032 private static HashMap<String,DCJDistance> modelMap;
00033
00034 private JTextArea nwayTA, pwiseTA;
00035
00036 private AnalysisDisplayWindow adw;
00037
00038 private int fWIDTH = 400;
00039
00040 private int fHEIGHT = 400;
00041
00042 private DCJ[][] nWayDist;
00043
00044 private DCJ[][] pWiseDist;
00045
00046 private static DCJDistance curr;
00047
00048
00049
00050
00051
00052 public static void launchWindow(BaseViewerModel model) {
00053 if (modelMap == null)
00054 modelMap = new HashMap<String,DCJDistance>();
00055 String key = model.getSrc().getAbsolutePath();
00056 if (modelMap.containsKey(key)) {
00057 modelMap.get(key).adw.showWindow();
00058 }else if (model instanceof XmfaViewerModel){
00059 modelMap.put(key, new DCJDistance((XmfaViewerModel)model));
00060 } else {
00061 System.err.println("Can't compute DCJ distance without contig boundaries.");
00062 }
00063 }
00064
00065 public DCJDistance (XmfaViewerModel model) {
00066 int numGenomes = model.getGenomes().size();
00067
00068 DistanceFunction dcj = new DistanceFunction(){
00069 public int distance(DCJ dcj) { return dcj.dcjDistance();}
00070 };
00071 DistanceFunction scj = new DistanceFunction(){
00072 public int distance(DCJ dcj){ return dcj.scjDistance();}
00073 };
00074 DistanceFunction bp = new DistanceFunction(){
00075 public int distance(DCJ dcj){ return dcj.bpDistance();}
00076 };
00077 if (numGenomes > 2){
00078 adw = new AnalysisDisplayWindow("DCJ - "+model.getSrc().getName(), fWIDTH, fHEIGHT);
00079 nwayTA = adw.addContentPanel(NWAY_COMMAND, NWAY_DESC, true);
00080 pwiseTA = adw.addContentPanel(PWISE_COMMAND, PWISE_DESC, false);
00081 adw.showWindow();
00082 Vector<Genome> v = model.getGenomes();
00083 Genome[] genomes = v.toArray(new Genome[v.size()]);
00084 int numGen = genomes.length;
00085 nWayDist = new DCJ[numGen][numGen];
00086 pWiseDist = new DCJ[numGen][numGen];
00087 nwayTA.append(temp);
00088 pwiseTA.append(temp);
00089 try {
00090 loadMatrices(model, nWayDist, pWiseDist);
00091 nwayTA.replaceRange("", 0, temp.length());
00092 pwiseTA.replaceRange("", 0, temp.length());
00093 nwayTA.append("# Rearrangement distances based on N-way LCBs\n");
00094 nwayTA.append("# No. of blocks = " + nWayDist[1][0].numBlocks()+" #\n\n");
00095 pwiseTA.append("# Rearrangement distances based on pairwise LCBs #\n\n");
00096 printHeader(pwiseTA,model);
00097 printHeader(nwayTA,model);
00098
00099 nwayTA.append("\n");
00100 pwiseTA.append("\n");
00101 PrintStream out = new PrintStream(textArea2OutputStream(nwayTA));
00102 out.print("# DCJ distance\n");
00103 printDistance(out, nWayDist, dcj);
00104 out.print("\n# SCJ distance\n");
00105 printDistance(out, nWayDist, scj);
00106 out.print("\n# Breakpoint distance\n");
00107 printDistance(out, nWayDist, bp);
00108 DistanceFunction nblks = new DistanceFunction(){
00109 public int distance(DCJ dcj){ return dcj.numBlocks();}
00110 };
00111 out = new PrintStream(textArea2OutputStream(pwiseTA));
00112 out.print("# Number of Blocks\n");
00113 printDistance(out, pWiseDist, nblks);
00114 out.print("\n# DCJ distance\n");
00115 printDistance(out, pWiseDist, dcj);
00116 out.print("\n# SCJ distance\n");
00117 printDistance(out, pWiseDist, scj);
00118 out.print("\n# Breakpoint distance\n");
00119 printDistance(out, pWiseDist, bp);
00120 } catch (Exception e){
00121 nwayTA.replaceRange(error, 0, temp.length());
00122 pwiseTA.replaceRange(error, 0, temp.length());
00123 e.printStackTrace();
00124 }
00125 } else {
00126 adw = new AnalysisDisplayWindow("DCJ - "+model.getSrc().getName(), fWIDTH, fHEIGHT);
00127 nwayTA = adw.addContentPanel("DCJ", NWAY_DESC, true);
00128 adw.showWindow();
00129 nwayTA.append(temp);
00130 try {
00131 String[] perms = PermutationExporter.getPermStrings(model,true);
00132 DCJ dcjDist = new DCJ(perms[0], perms[1]);
00133 nwayTA.replaceRange("", 0, temp.length());
00134 StringBuilder sb = new StringBuilder();
00135 sb.append("no. of blocks = " + dcjDist.numBlocks()+" #\n\n");
00136 sb.append("# DCJ distance\n");
00137 sb.append("0\n"+dcjDist.dcjDistance()+"\t0\n\n");
00138 sb.append("# SCJ distance\n");
00139 sb.append("0\n"+dcjDist.scjDistance()+"\t0\n\n");
00140 sb.append("# Breakpoint distance\n");
00141 sb.append("0\n"+dcjDist.bpDistance()+"\t0\n\n");
00142 nwayTA.setText(sb.toString());
00143 } catch (Exception e){
00144 nwayTA.replaceRange(error, 0, temp.length());
00145 System.err.println(error);
00146 e.printStackTrace();
00147
00148 }
00149 }
00150
00151 }
00152
00153
00154 private static void printNBlks(PrintStream out, DCJ[][] mat){
00155 for (int i = 0; i < mat.length; i++){
00156 for (int j = 0; j < i; j++){
00157 out.print(mat[i][j].numBlocks()+"\t");
00158 }
00159 out.print("0\n");
00160 }
00161 }
00162
00163 private static void printDistance(PrintStream out, DCJ[][] mat, DistanceFunction func){
00164 for (int i = 0; i < mat.length; i++){
00165 for (int j = 0; j < i; j++){
00166 out.print(func.distance(mat[i][j])+"\t");
00167 }
00168 out.print("0\n");
00169 }
00170 }
00171
00172 private static void printHeader(JTextArea nblksTA2, XmfaViewerModel model){
00173 Vector<Genome> v = model.getGenomes();
00174 Genome[] genomes = v.toArray(new Genome[v.size()]);
00175 for (int i = 0; i < genomes.length; i++){
00176 nblksTA2.append("# "+(i+1)+": " + genomes[i].getDisplayName()+"\n");
00177 }
00178 }
00179
00180 private static void printHeader(StringBuilder sb, XmfaViewerModel model){
00181 Vector<Genome> v = model.getGenomes();
00182 Genome[] genomes = v.toArray(new Genome[v.size()]);
00183 for (int i = 0; i < genomes.length; i++){
00184 sb.append("# "+(i+1)+": " + genomes[i].getDisplayName()+"\n");
00185 }
00186 }
00187
00188 private void loadMatrices(XmfaViewerModel model, DCJ[][] nway, DCJ[][] pwise){
00189 Vector<Genome> v = model.getGenomes();
00190 Genome[] genomes = new Genome[v.size()];
00191 v.toArray(genomes);
00192 Genome[] pair = new Genome[2];
00193 String[] nWayPerms = PermutationExporter.getPermStrings(model, genomes,true);
00194 String[] pairPerm = null;
00195 DCJ[][] nWayDist = nway;
00196 DCJ[][] pWiseDist = pwise;
00197 for (int i = 0; i < genomes.length; i++){
00198 for (int j = 0; j < i; j++){
00199 pair[0] = genomes[i];
00200 pair[1] = genomes[j];
00201 pairPerm = PermutationExporter.getPermStrings(model, pair,true);
00202
00203 if (!Permutation.equalContents(pairPerm[0], pairPerm[1])){
00204 System.err.println("Unequal contents between genomes "+
00205 i + " and " + j+"\n" + pairPerm[0] +"\n"+pairPerm[1]);
00206 }
00207 nWayDist[i][j] = new DCJ(nWayPerms[i],nWayPerms[j]);
00208 pWiseDist[i][j] = new DCJ(pairPerm[0],pairPerm[1]);
00209 }
00210 }
00211 }
00212
00213
00214
00215
00216
00217 OutputStream textArea2OutputStream(final JTextArea t)
00218 { return new OutputStream()
00219 { JTextArea ta = t;
00220 public void write(int b)
00221 { byte[] bs = new byte[1]; bs[0] = (byte) b;
00222 ta.append(new String(bs));
00223 }
00224 };
00225 }
00226
00227 private interface DistanceFunction {
00228 public int distance(DCJ dcj);
00229 }
00230
00231 }