[med-svn] [proalign] 06/10: New upstream version 0.603
Andreas Tille
tille at debian.org
Thu Nov 16 13:29:47 UTC 2017
This is an automated email from the git hooks/post-receive script.
tille pushed a commit to branch master
in repository proalign.
commit 6f89e7ca2729a6e53a096c3ca0889465cb751b68
Author: Andreas Tille <tille at debian.org>
Date: Thu Nov 16 14:24:55 2017 +0100
New upstream version 0.603
---
AlignmentLoop.java | 355 ++++++++++++
AlignmentNode.java | 1026 +++++++++++++++++++++++++++++++++
CheckSequence.java | 81 +++
CheckTrailing.java | 55 ++
CheckTreeAndData.java | 46 ++
EstimateFrequencies.java | 61 ++
InFile.java | 16 +
MinimumProbWindow.java | 87 +++
NeighborJoining.java | 178 ++++++
NicePrint.java | 50 ++
OpenDialog.java | 53 ++
OpenFileChooser.java | 55 ++
OpenFolderChooser.java | 52 ++
OutFile.java | 20 +
OutOfMemoryException.java | 19 +
PAFileFilter.java | 46 ++
ParameterEstimates.java | 195 +++++++
PixelRule.java | 102 ++++
PrintCurve.java | 76 +++
PrintData.java | 382 +++++++++++++
PrintMinimumCurve.java | 73 +++
PrintNames.java | 250 +++++++++
PrintTree.java | 194 +++++++
ProAlign.java | 231 ++++++++
PwAlignment.java | 345 ++++++++++++
PwAlignmentLoop.java | 273 +++++++++
PwSubstitutionMatrix.java | 143 +++++
QualityWindow.java | 96 ++++
ReadArguments.java | 232 ++++++++
ResultWindow.java | 1374 +++++++++++++++++++++++++++++++++++++++++++++
Rule.java | 117 ++++
RunClustalw.java | 186 ++++++
RunCommandLine.java | 209 +++++++
RunMultiple.java | 103 ++++
SampleAlignments.java | 446 +++++++++++++++
SampleLoop.java | 146 +++++
SaveData.java | 854 ++++++++++++++++++++++++++++
SequenceReader.java | 641 +++++++++++++++++++++
SetParameters.java | 881 +++++++++++++++++++++++++++++
SubstitutionModel.java | 511 +++++++++++++++++
TraceBackPath.java | 518 +++++++++++++++++
TransformLog.java | 36 ++
TreeNode.java | 317 +++++++++++
TreeReader.java | 226 ++++++++
UserSettings.java | 85 +++
Viterbi.java | 354 ++++++++++++
WinClustalw.java | 55 ++
debian/changelog | 12 -
debian/compat | 1 -
debian/control | 31 -
debian/copyright | 35 --
debian/manifest.txt | 3 -
debian/proalign.1 | 79 ---
debian/proalign.install | 3 -
debian/proalign.manpages | 1 -
debian/rules | 17 -
debian/scripts/proalign | 21 -
debian/source/format | 1 -
debian/upstream/metadata | 12 -
debian/watch | 4 -
60 files changed, 11851 insertions(+), 220 deletions(-)
diff --git a/AlignmentLoop.java b/AlignmentLoop.java
new file mode 100644
index 0000000..42cb609
--- /dev/null
+++ b/AlignmentLoop.java
@@ -0,0 +1,355 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class AlignmentLoop {
+
+/*
+ Do the viterbi path, and mark the track.
+ Do forward & backward algorithm, calculate posterior probs
+*/
+
+ ProAlign pa;
+ AlignmentLoop al;
+ AlignmentNode an;
+
+ double[][][] price, priceX, priceY;
+ double[][] vitM, vitX, vitY;
+
+ double[][][] pathM;
+ double[][] pathX, pathY;
+
+ double[][] fwdM, fwdX, fwdY;
+ double[][] bwdM, bwdX, bwdY;
+
+ double vitEnd, fwdEnd;
+ double[] pathEnd;
+
+ double[][] seq1, seq2;
+ float dist1, dist2;
+
+ int aSize;
+
+ int BWIDTH;
+ int MIDDLE;
+
+ int endPoint = 0;
+
+ AlignmentLoop(ProAlign pa,AlignmentNode an) {
+
+ this.pa = pa;
+ this.an = an;
+ al = this;
+
+ BWIDTH = ProAlign.bandWidth;
+ MIDDLE = BWIDTH/2+1;
+ }
+
+ void align(double[][] s1, double[][] s2, float d1, float d2) throws Exception {
+
+ seq1 = s1;
+ seq2 = s2;
+ dist1 = d1;
+ dist2 = d2;
+
+ al.pa.sm.setBranchLength(dist1,dist2);
+
+ aSize = seq1[0].length; // aSize = alphabet size;
+
+ ProAlign.log("AlignmentLoop");
+ ProAlign.log(" seq1.length = "+seq1.length+", seq2.length = "+seq2.length);
+
+ try {
+ al.initialiseMatrices();
+ } catch(Error e) {
+ if(ProAlign.isResultWindow) {
+ String text = "\n Out Of Memory Error!\n Please, increase JVM memory.\n";
+ OpenDialog od = new OpenDialog(pa.rw);
+ od.showDialog("Error!", text);
+ System.exit(0);
+ } else {
+ ProAlign.log.println("AlignmentLoop: Out Of Memory Error. Increase JVM memory.");
+ System.out.println("Out Of Memory Error.\nPlease, increase JVM memory.");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+// System.out.println("AlignmentLoop: throws an exception");
+ throw new OutOfMemoryException("Out Of Memory Error. Increase JVM memory");
+ }
+ }
+ }
+
+ Viterbi v = new Viterbi(al);
+
+ // do viterbi loop through the matrix;
+ // at the same, do forward and mark the path
+ // for the traceback
+
+ for(int i=1; i<vitM.length; i++) { // go through seq1
+ for(int j=0; j<BWIDTH; j++) { // go through seq2
+
+ if(j-MIDDLE+i < 1) { continue; } // upper border of real matrix
+
+ if(j-MIDDLE+i > seq2.length+1) { continue; } // lower border of real matrix
+
+ if(i==1 && j==MIDDLE) { continue; } // starting point
+
+ // exception if seq2 starts later; only X-gaps possible
+
+ if(j-MIDDLE+i==1) {
+
+ sumSubstPriceX(i,j);
+
+ pathM[i][j][0] = -1d;
+ pathM[i][j][1] = -1d;
+ vitX[i][j] = v.getViterbiX(i,j);
+ pathY[i][j] = -1d;
+ fwdX[i][j] = v.getForwardX(i,j);
+
+ endPoint = j;
+ }
+
+ // exception if seq1 starts later; only Y-gaps possible
+ else if(i==1) {
+
+ sumSubstPriceY(i,j);
+
+ pathM[i][j][0] = -1d;
+ pathM[i][j][1] = -1d;
+ pathX[i][j] = -1d;
+ vitY[i][j] = v.getViterbiY(i,j);
+ fwdY[i][j] = v.getForwardY(i,j);
+
+ endPoint = j;
+ }
+
+ else {
+
+ // go through alphabet, get probability for each character
+ sumSubstPrice(i,j);
+
+ vitM[i][j] = v.getViterbiM(i,j); // for 'Match'
+ vitX[i][j] = v.getViterbiX(i,j); // for 'X indel'
+ vitY[i][j] = v.getViterbiY(i,j); // for 'Y indel'
+ fwdM[i][j] = v.getForwardM(i,j);
+ fwdX[i][j] = v.getForwardX(i,j);
+ fwdY[i][j] = v.getForwardY(i,j);
+
+ endPoint = j;
+ }
+ }
+ }
+ vitEnd = v.getViterbiEnd(endPoint);
+
+ try {
+ al.initialiseBwdMatrices(endPoint);
+ } catch(Error e) {
+ if(ProAlign.isResultWindow) {
+ String text = "\n Out Of Memory Error!\n Please, increase JVM memory.\n";
+ OpenDialog od = new OpenDialog(pa.rw);
+ od.showDialog("Error!", text);
+ System.exit(0);
+ } else {
+ ProAlign.log.println("AlignmentLoop: Out Of Memory Error. Increase JVM memory.");
+ System.out.println("Out Of Memory Error.\nPlease, increase JVM memory.");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+// System.out.println("AlignmentLoop: throws an exception");
+ throw new OutOfMemoryException("Out Of Memory Error. Increase JVM memory");
+ }
+ }
+ }
+
+ // do backward loop through the matrix;
+ for(int i=vitM.length-1; i>0; i--) { // go through seq1
+ for(int j=BWIDTH-1; j>=0; j--) { // go through seq2
+
+ if(j-MIDDLE+i < 1) { continue; } // upper border of real matrix
+
+ else if(j-MIDDLE+i > seq2.length+1) { continue; } // lower border of real matrix
+
+ else if(i==vitM.length-1 && j==endPoint) { continue; } // starting point
+
+ else {
+ bwdM[i][j] = v.getBackwardM(i,j);
+ bwdX[i][j] = v.getBackwardX(i,j);
+ bwdY[i][j] = v.getBackwardY(i,j);
+ }
+ }
+ }
+ if(ProAlign.DEBUG) { // ---DEBUG---
+
+ TransformLog tl = new TransformLog();
+ double bwdEnd = tl.sumLogs(bwdM[1][MIDDLE],tl.sumLogs(bwdX[1][MIDDLE],
+ bwdY[1][MIDDLE]));
+ double diff = (double) bwdEnd-fwdEnd;
+ ProAlign.log.println("AlignmentLoop: vEnd: "+vitEnd+" fEnd: "+fwdEnd+
+ " bEnd: "+bwdEnd+" fwd-bwd: "+diff);
+ } // ---DEBUG---
+ }
+
+ // initialise all matrices before starting
+ void initialiseMatrices() {
+
+ // [seq1 length][band width][alphabet]
+ price = new double[seq1.length+2][BWIDTH][aSize+1];
+ priceX = new double[seq1.length+2][BWIDTH][aSize+1];
+ priceY = new double[seq1.length+3][BWIDTH][aSize+1];
+
+ vitM = new double[seq1.length+2][BWIDTH];
+ vitX = new double[seq1.length+2][BWIDTH];
+ vitY = new double[seq1.length+2][BWIDTH];
+
+ pathM = new double[seq1.length+2][BWIDTH][2];
+ pathX = new double[seq1.length+2][BWIDTH];
+ pathY = new double[seq1.length+2][BWIDTH];
+
+ fwdM = new double[seq1.length+2][BWIDTH];
+ fwdX = new double[seq1.length+2][BWIDTH];
+ fwdY = new double[seq1.length+2][BWIDTH];
+
+ bwdM = new double[seq1.length+3][BWIDTH];
+ bwdX = new double[seq1.length+3][BWIDTH];
+ bwdY = new double[seq1.length+3][BWIDTH];
+
+ pathEnd = new double[2];
+
+ for(int j=0; j<vitM[0].length; j++) {
+ for(int i=0; i<vitM.length; i++) {
+ vitM[i][j] = Double.NEGATIVE_INFINITY;
+ vitX[i][j] = Double.NEGATIVE_INFINITY;
+ vitY[i][j] = Double.NEGATIVE_INFINITY;
+ fwdM[i][j] = Double.NEGATIVE_INFINITY;
+ fwdX[i][j] = Double.NEGATIVE_INFINITY;
+ fwdY[i][j] = Double.NEGATIVE_INFINITY;
+ }
+
+ for(int i=0; i<bwdM.length; i++) {
+ bwdM[i][j] = Double.NEGATIVE_INFINITY;
+ bwdX[i][j] = Double.NEGATIVE_INFINITY;
+ bwdY[i][j] = Double.NEGATIVE_INFINITY;
+ }
+ }
+
+ if(an.hasTrailers) {
+
+ if(an.start0>an.start1) {
+ vitM[1][MIDDLE] = 0d;
+ vitX[1][MIDDLE] = 0d;
+ vitY[1][MIDDLE] = Double.NEGATIVE_INFINITY;
+
+ fwdM[1][MIDDLE] = 0d;
+ fwdX[1][MIDDLE] = 0d;
+ fwdY[1][MIDDLE] = Double.NEGATIVE_INFINITY;
+ } else {
+ vitM[1][MIDDLE] = 0d;
+ vitX[1][MIDDLE] = Double.NEGATIVE_INFINITY;
+ vitY[1][MIDDLE] = 0d;
+
+ fwdM[1][MIDDLE] = 0d;
+ fwdX[1][MIDDLE] = Double.NEGATIVE_INFINITY;
+ fwdY[1][MIDDLE] = 0d;
+ }
+
+ } else {
+ // ([0] means actually [-1])
+ vitM[1][MIDDLE] = 0d;
+ vitX[1][MIDDLE] = 0d;
+ vitY[1][MIDDLE] = 0d;
+
+ fwdM[1][MIDDLE] = 0d;
+ fwdX[1][MIDDLE] = 0d;
+ fwdY[1][MIDDLE] = 0d;
+ }
+ }
+
+ void initialiseBwdMatrices(int endPoint) {
+
+ bwdM[bwdM.length-2][endPoint] = 0d;
+ bwdX[bwdX.length-2][endPoint] = 0d;
+ bwdY[bwdY.length-2][endPoint] = 0d;
+ }
+
+
+
+ // calculate the sum of substitution prices for both branches separately;
+ // iterate over all possible characters at the node, child 1 and child 2;
+ // characters at [i] get values 'l'; at [j] values 'm'; node gets characters 'k'
+
+ void sumSubstPrice(int i, int j){
+
+ // character at node
+ int js = i+j-MIDDLE; // convert from "band" value to real value
+
+ double[][] sum = new double[2][aSize];
+
+ for(int k=0; k<aSize; k++) {
+ sum[0][k] = 0d;
+ sum[1][k] = 0d;
+ for(int l = 0; l<aSize; l++) {
+ // match
+ // characters at child 1; correction [i-2] for "positive" matrix
+ sum[0][k] += seq1[i-2][l]*al.pa.sm.substProb1[k][l];
+ // characters at child 2; correction [j-2] for "positive" matrix
+ sum[1][k] += seq2[js-2][l]*al.pa.sm.substProb2[k][l];
+
+ // x-gap
+ priceX[i][j][k] += al.seq1[i-2][l]*al.pa.sm.substProb1[k][l];
+
+ // y-gap
+ priceY[i][j][k] += al.seq2[js-2][l]*al.pa.sm.substProb2[k][l];
+ }
+
+ price[i][j][k] = sum[0][k]*sum[1][k]*al.pa.sm.charFreqs[k];
+ // because the other child is "gap" for sure
+ priceX[i][j][k] = priceX[i][j][k]*1.0d*al.pa.sm.substProb2[k][aSize-1]*al.pa.sm.charFreqs[k];
+ priceY[i][j][k] = priceY[i][j][k]*1.0d*al.pa.sm.substProb1[k][aSize-1]*al.pa.sm.charFreqs[k];
+ }
+
+ return;
+ }
+
+ void sumSubstPriceX(int i, int j){
+
+ for(int k=0; k<aSize; k++) {
+ for(int l = 0; l<aSize; l++) {
+ // x-gap
+ priceX[i][j][k] += al.seq1[i-2][l]*al.pa.sm.substProb1[k][l];
+ }
+
+ priceX[i][j][k] = priceX[i][j][k]*1.0d*al.pa.sm.substProb2[k][aSize-1]*al.pa.sm.charFreqs[k];
+ }
+ return;
+ }
+
+ void sumSubstPriceY(int i, int j){
+
+ int js = i+j-MIDDLE; // convert from "band" value to real value
+
+ for(int k=0; k<aSize; k++) {
+ for(int l = 0; l<aSize; l++) {
+ // y-gap
+ priceY[i][j][k] += al.seq2[js-2][l]*al.pa.sm.substProb2[k][l];
+ }
+
+ priceY[i][j][k] = priceY[i][j][k]*1.0d*al.pa.sm.substProb1[k][aSize-1]*al.pa.sm.charFreqs[k];
+ }
+ return;
+ }
+
+
+}
+
+
+
+
+
diff --git a/AlignmentNode.java b/AlignmentNode.java
new file mode 100644
index 0000000..9be47b3
--- /dev/null
+++ b/AlignmentNode.java
@@ -0,0 +1,1026 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.IOException;
+import java.lang.ClassNotFoundException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+public class AlignmentNode implements Serializable {
+
+ String sequence;
+ String alphabet;
+ String equateAlphabet;
+ String name;
+ String tree;
+ float distance;
+ int nodeNumber;
+
+ String minimumProbNode = new String();
+ int minimumProbNumber;
+
+ int treeX;
+ int treeY;
+
+ boolean isUnique = true;
+ int sampleTimes = 0;
+
+ boolean isBandWarning = false;
+
+ boolean hasTrailers = false;
+ int start0=0;
+ int start1=0;
+ int end0=0;
+ int end1=0;
+
+ double viterbiEnd;
+ double forwardEnd;
+
+ double[][] charProb;
+ boolean isTerminal;
+ int numChild;
+
+ double[] postProb;
+ int[][] cellPath;
+
+ AlignmentNode[] child;
+ AlignmentNode parent;
+ ProAlign pa;
+
+ AlignmentNode(ProAlign pa, String tree, float distance) {
+
+ this.pa = pa;
+ this.tree = tree;
+ this.distance = Math.abs(distance);
+ parent = this;
+
+ sequence = new String();
+
+ // If this is internal node..
+ //
+ if(tree.indexOf(",")>0) {
+
+ nodeNumber = pa.getNodeNumber(); // set unique number
+ child = new AlignmentNode[2];
+
+ String[] trees;
+ float[] distances;
+ TreeReader tr = new TreeReader();
+
+ if(nodeNumber==0) { // root is trifurcating: correction.
+
+ ProAlign.log("AlignmentNode: "+tree);
+
+ name = "root";
+
+ trees = tr.divideTree(tree);
+ distances = tr.distance;
+
+ } else { // other internal nodes bifurcating
+
+ ProAlign.log("AlignmentNode: "+tree);
+
+ name = "node"+nodeNumber;
+ trees = tr.divideTree(tree);
+ distances = tr.distance;
+ }
+
+ child[0] = new AlignmentNode(pa, trees[0], distances[0]);
+ child[1] = new AlignmentNode(pa, trees[1], distances[1]);
+
+ numChild = getNumChild();
+
+ }
+
+ // ..else this is terminal node.
+ //
+ else {
+
+ name = tree;
+ alphabet = pa.sm.alphabet;
+ equateAlphabet = pa.sm.equateAlphabet;
+ sequence = (String) pa.seqs.get(name);
+ isTerminal = true;
+ numChild = 0;
+
+ ProAlign.log("AlignmentNode: "+name+":"+distance+", "+sequence.length());
+
+ // Observed charcter has probability of 1, others 0.
+ //
+ charProb = new double[sequence.length()][alphabet.length()];
+
+ for(int i=0; i<sequence.length();i++) {
+ if(ProAlign.isDna) {
+ if(equateAlphabet.indexOf(sequence.charAt(i)) < 4) {
+ charProb[i][equateAlphabet.indexOf(sequence.charAt(i))] = 1d;
+ } else { // uses equate characters
+ if(sequence.charAt(i)=='R') {
+ charProb[i][0] = 0.5d;
+ charProb[i][2] = 0.5d;
+ } else if(sequence.charAt(i)=='Y') {
+ charProb[i][1] = 0.5d;
+ charProb[i][3] = 0.5d;
+ } else if(sequence.charAt(i)=='M') {
+ charProb[i][0] = 0.5d;
+ charProb[i][1] = 0.5d;
+ } else if(sequence.charAt(i)=='K') {
+ charProb[i][2] = 0.5d;
+ charProb[i][3] = 0.5d;
+ } else if(sequence.charAt(i)=='S') {
+ charProb[i][1] = 0.5d;
+ charProb[i][2] = 0.5d;
+ } else if(sequence.charAt(i)=='W') {
+ charProb[i][0] = 0.5d;
+ charProb[i][3] = 0.5d;
+ } else if(sequence.charAt(i)=='H') {
+ charProb[i][0] = (double)(1d/3d);
+ charProb[i][1] = (double)(1d/3d);
+ charProb[i][3] = (double)(1d/3d);
+ } else if(sequence.charAt(i)=='B') {
+ charProb[i][1] = (double)(1d/3d);
+ charProb[i][2] = (double)(1d/3d);
+ charProb[i][3] = (double)(1d/3d);
+ } else if(sequence.charAt(i)=='V') {
+ charProb[i][0] = (double)(1d/3d);
+ charProb[i][1] = (double)(1d/3d);
+ charProb[i][2] = (double)(1d/3d);
+ } else if(sequence.charAt(i)=='D') {
+ charProb[i][0] = (double)(1d/3d);
+ charProb[i][2] = (double)(1d/3d);
+ charProb[i][3] = (double)(1d/3d);
+ } else if(sequence.charAt(i)=='N') {
+ charProb[i][0] = 0.25d;
+ charProb[i][1] = 0.25d;
+ charProb[i][2] = 0.25d;
+ charProb[i][3] = 0.25d;
+ } else if(sequence.charAt(i)=='U') {
+ charProb[i][3] = 1d;
+ }
+ }
+ } else {
+ if(equateAlphabet.indexOf(sequence.charAt(i)) < 20) {
+ charProb[i][equateAlphabet.indexOf(sequence.charAt(i))] = 1d;
+ } else { // uses equate characters
+ for(int j=0; j<20; j++) {
+ charProb[i][j] = pa.sm.aaFreqs[j];
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+ void align() throws TraceBackException, Exception {
+
+ // If there are childs, align them first.
+ //
+ try {
+ if(child[0].getNumChild()>1) {
+ child[0].align();
+ }
+
+ if(child[1].getNumChild()>1) {
+ child[1].align();
+ }
+ } catch(TraceBackException tbe) { // throw exception if close to the edge
+ throw tbe;
+ }
+
+ // NEW TRAILING >>
+
+ int[] trail = new int[2];
+ double[][] midseq0 = new double[0][0];
+ double[][] midseq1 = new double[0][0];
+
+ if(ProAlign.removeTrailing) {
+
+ CheckTrailing ct = new CheckTrailing(pa);
+ trail = ct.trailing(child[0].sequence.trim(),child[1].sequence.trim());
+
+ if(Math.abs(trail[0])>ProAlign.offset || Math.abs(trail[1])>ProAlign.offset) {
+
+ if(trail[0]>ProAlign.offset) {
+ start0=trail[0]-ProAlign.offset;
+ }
+ if(trail[1]>ProAlign.offset) {
+ end0 = trail[1]-ProAlign.offset;
+ }
+
+ midseq0 = new double[child[0].charProb.length-end0-start0][child[0].charProb[0].length];
+
+ int k=0;
+ for(int i=start0; i<child[0].charProb.length-end0;i++) {
+ int l=0;
+ for(int j=0; j<child[0].charProb[i].length; j++) {
+ midseq0[k][l++] = child[0].charProb[i][j];
+ }
+ k++;
+ }
+
+
+ if(-1*trail[0]>ProAlign.offset) {
+ start1=Math.abs(trail[0])-ProAlign.offset;
+ }
+ if(-1*trail[1]>ProAlign.offset) {
+ end1 = Math.abs(trail[1])-ProAlign.offset;
+ }
+
+ midseq1 = new double[child[1].charProb.length-end1-start1][child[1].charProb[0].length];
+
+ k=0;
+ for(int i=start1; i<child[1].charProb.length-end1;i++) {
+ int l=0;
+ for(int j=0; j<midseq1[0].length; j++) {
+ midseq1[k][l++] = child[1].charProb[i][j];
+ }
+ k++;
+ }
+ hasTrailers=true;
+
+ }
+ }
+
+ // << NEW TRAILING
+
+ // Child's nodes are aligned, align childs.
+ //
+ AlignmentLoop loop = new AlignmentLoop(parent.pa,AlignmentNode.this);
+
+ ProAlign.log(" "+name+ ": aligning "+child[0].name+" and "+child[1].name);
+ if(ProAlign.isResultWindow) {
+ ResultWindow.updateInfo(" Creating multiple alignment: aligning '"+name+"'.");
+ }
+
+ try {
+ if(hasTrailers) {
+ loop.align(midseq0,midseq1,child[0].distance,child[1].distance);
+ } else {
+ loop.align(child[0].charProb,child[1].charProb,child[0].distance,child[1].distance);
+ }
+ } catch(Exception e) {
+// System.out.println("AlignmentNode: throws an exception");
+ throw e;
+ }
+
+ viterbiEnd = loop.vitEnd;
+ forwardEnd = loop.fwdEnd;
+
+ TraceBackPath path = new TraceBackPath(parent,loop);
+ try {
+ charProb = path.getNode(ProAlign.trackBest); // get best or sample.
+ postProb = path.postProb;
+ cellPath = path.cellPath;
+
+ if(hasTrailers) {
+ viterbiEnd += path.trailProb;
+ forwardEnd += path.trailProb;
+ }
+
+ } catch(TraceBackException tbe) {
+ String error = tbe.getMessage();
+ throw new TraceBackException(" Aligning "+name+":\n "+error);
+ }
+
+/*
+ System.out.print("\n0: ");
+ for(int x=0; x<cellPath.length; x++) {
+ System.out.print(cellPath[x][0]+",");
+ }
+ System.out.print("\n1: ");
+ for(int x=0; x<cellPath.length; x++) {
+ System.out.print(cellPath[x][1]+",");
+ }
+//*/
+ isUnique = path.isUnique;
+ sampleTimes = path.sampleTimes;
+ isBandWarning = path.isBandWarning;
+
+ createSequence();
+ }
+
+ // Create most likely sequence to be used for pw alignment
+ //
+ void createSequence() {
+
+ alphabet = pa.sm.alphabet;
+ sequence = new String();
+ for(int i=0; i<charProb.length; i++) {
+ double best = 0d;
+ char site = ' ';
+ for(int j=0; j<charProb[0].length-1; j++) {
+ if(charProb[i][j]>best) {
+ best = charProb[i][j];
+ site = alphabet.charAt(j);
+ }
+ }
+ sequence += site;
+ }
+ }
+
+ // Get maximum depth (#internal nodes) of the tree.
+ //
+ int getTreeDepth() {
+ if(isTerminal) {
+ return 0;
+ }
+ if(child[0].getTreeDepth()>child[1].getTreeDepth()){
+ return child[0].getTreeDepth()+1;
+ }else {
+ return child[1].getTreeDepth()+1;
+ }
+ }
+
+ // Get #terminal nodes below this node.
+ //
+ int getNumChild() {
+ if(isTerminal) {
+ return 1;
+ }
+ return (child[0].getNumChild() + child[1].getNumChild());
+ }
+
+ // Get #times the path was sampled.
+ //
+ int getSampleTimes() {
+ int times = parent.sampleTimes;
+ if(!child[0].isTerminal) {
+ times += child[0].getSampleTimes();
+ }
+ if(!child[1].isTerminal) {
+ times += child[1].getSampleTimes();
+ }
+ return times;
+ }
+
+ // Was the path sampled.
+ //
+ boolean isUnique() {
+ boolean unique0 = true;
+ boolean unique1 = true;
+ if(!child[0].isTerminal) {
+ unique0 = child[0].isUnique();
+ }
+ if(!child[1].isTerminal) {
+ unique1 = child[1].isUnique();
+ }
+ if(parent.isUnique && unique0 && unique1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ // Was the path close to the edge.
+ //
+ boolean isBandWarning() {
+ boolean warning0 = false;
+ boolean warning1 = false;
+ if(!child[0].isTerminal) {
+ warning0 = child[0].isBandWarning();
+ }
+ if(!child[1].isTerminal) {
+ warning1 = child[1].isBandWarning();
+ }
+ if(parent.isBandWarning || warning0 || warning1) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // Get alphabet.
+ //
+ String getAlphabet() {
+ if(isTerminal) {
+ return alphabet;
+ }
+ return child[0].getAlphabet();
+ }
+
+ // Get real site number at node 'str'.
+ //
+ int getSiteAt(int site, String str) {
+
+ if(isTerminal) {
+ if(site > sequence.length()-1){ // correct for values outside of range.
+ return -1;
+ } else if(site<0) {
+ return -1;
+ } else if(name.equals(str)) { // match - return!
+ return site;
+ } else {
+ return -1;
+ }
+
+ } else {
+ if(site > cellPath.length-1){
+ return -1;
+ } else if(site<0) {
+ return -1;
+ } else if(name.equals(str)) {
+ return site;
+ } else if(child[0].getSiteAt(cellPath[site][0]-2, str)>=0) { // correct
+ return child[0].getSiteAt(cellPath[site][0]-2, str); // for the
+ } else if(child[1].getSiteAt(cellPath[site][1]-2, str)>=0) { // difference
+ return child[1].getSiteAt(cellPath[site][1]-2, str); // on numbers.
+ } else {
+ return -1;
+ }
+ }
+ }
+
+ // Get characters at 'site'; returns an alignment column.
+ //
+ char[] getCharacterAt(int site) {
+
+ char[] chars;
+
+ // Terminal node returns a character or a gap
+ //
+ if(isTerminal) {
+ chars = new char[1];
+ if(site<0) {
+ chars[0] = '-';
+ } else {
+ chars[0] = sequence.charAt(site);
+ }
+ return chars;
+ }
+
+ // Internal node returns a vector of..
+ //
+ chars = new char[numChild];
+ if(site<0) { // ..gaps..
+ for(int i=0; i<numChild; i++) {
+ chars[i] = '-';
+ }
+ } else { // ..or characters on nodes below.
+
+ char[] chars0 = child[0].getCharacterAt(cellPath[site][0]-2);
+ char[] chars1 = child[1].getCharacterAt(cellPath[site][1]-2);
+
+ int c=0;
+ for(int i=0; i<chars0.length; i++) {
+ chars[c++] = chars0[i];
+ }
+ for(int i=0; i<chars1.length; i++) {
+ chars[c++] = chars1[i];
+ }
+ }
+ return chars;
+ }
+
+ // Get sum of viterbiEnds.
+ //
+ double sumViterbiEnd() {
+ if(isTerminal) {
+ return 0d;
+ } else {
+ double sum = child[0].sumViterbiEnd() + child[1].sumViterbiEnd() + viterbiEnd;
+ return sum;
+ }
+ }
+
+ // Get sum of forwardEnds.
+ //
+ double sumForwardEnd() {
+ if(isTerminal) {
+ return 0d;
+ } else {
+ double sum = child[0].sumForwardEnd() + child[1].sumForwardEnd() + forwardEnd;
+ return sum;
+ }
+ }
+
+ // Get posterior probability at 'site' for full column. This uses log's!
+ //
+ double[] getPostProbAt(int site) {
+
+ double[] post;
+
+ // Terminal node returns 0 (log(0) = 1) or -oo (log(-oo) = 0)
+ //
+ if(isTerminal) {
+ post = new double[1];
+ if(site<0) {
+ post[0] = Double.NEGATIVE_INFINITY;
+ } else {
+ post[0] = 0d;
+ }
+ return post;
+ }
+
+ // Note: #all nodes = 2*#terminal nodes-1.
+ //
+ post = new double[2*numChild-1];
+
+ // Outside of range.
+ //
+ if(site<0) {
+ for(int i=0; i<post.length; i++) {
+ post[i] = Double.NEGATIVE_INFINITY;
+ }
+ }
+
+ // Order: child[0], parent, child[1]
+ //
+ else {
+
+ double[] post0 = child[0].getPostProbAt(cellPath[site][0]-2);
+ double[] post1 = child[1].getPostProbAt(cellPath[site][1]-2);
+
+ int c=0;
+ for(int i=0; i<post0.length; i++) {
+ post[c++] = post0[i];
+ }
+ post[c++] = postProb[site];
+ for(int i=0; i<post1.length; i++) {
+ post[c++] = post1[i];
+ }
+ }
+ return post;
+
+ }
+
+ // Get posterior probability at 'site' for int. nodes. This uses log's!
+ //
+ double[] getInternalPostProbAt(int site) {
+
+ double[] post = new double[numChild-1];
+
+ // Outside of range.
+ //
+ if(site<0) {
+ for(int i=0; i<post.length; i++) {
+ post[i] = Double.NEGATIVE_INFINITY;
+ }
+ }
+
+ // Order: child[0], parent, child[1]
+ //
+ else {
+ double[] post0 = new double[0];
+ double[] post1 = new double[0];
+
+ if(!child[0].isTerminal) {
+ post0 = child[0].getInternalPostProbAt(cellPath[site][0]-2);
+ }
+ if(!child[1].isTerminal) {
+ post1 = child[1].getInternalPostProbAt(cellPath[site][1]-2);
+ }
+
+ int c=0;
+ for(int i=0; i<post0.length; i++) {
+ post[c++] = post0[i];
+ }
+ post[c++] = postProb[site];
+ for(int i=0; i<post1.length; i++) {
+ post[c++] = post1[i];
+ }
+ }
+ return post;
+
+ }
+
+ // Get minimum posterior probability at 'site' for int. nodes. This uses log's!
+ //
+ double getMinimumInternalPostProbAt(int site) {
+
+ minimumProbNode = name;
+ minimumProbNumber = nodeNumber;
+
+ double minPost;
+ // Outside of range.
+ //
+ if(site<0) {
+
+ minPost = 0d;
+
+ } else {
+
+ minPost = postProb[site];
+ double tmp = 0d;
+
+ if(!child[0].isTerminal) {
+ tmp = child[0].getMinimumInternalPostProbAt(cellPath[site][0]-2);
+ }
+ if(tmp < minPost) {
+ minPost = tmp;
+ minimumProbNode = child[0].getMinimumInternalPostProbNode();
+ minimumProbNumber = child[0].getMinimumInternalPostProbNumber();
+ } else if(tmp == minPost) {
+ minimumProbNode += ", "+child[0].getMinimumInternalPostProbNode();
+ minimumProbNumber = child[0].getMinimumInternalPostProbNumber();
+ }
+ if(!child[1].isTerminal) {
+ tmp = child[1].getMinimumInternalPostProbAt(cellPath[site][1]-2);
+ }
+ if(tmp < minPost) {
+ minPost = tmp;
+ minimumProbNode = child[1].getMinimumInternalPostProbNode();
+ minimumProbNumber = child[1].getMinimumInternalPostProbNumber();
+ } else if(tmp == minPost) {
+ minimumProbNode += ", "+child[1].getMinimumInternalPostProbNode();
+ minimumProbNumber = child[1].getMinimumInternalPostProbNumber();
+ }
+
+ }
+ return minPost;
+
+ }
+
+ // Get minimum posterior probability at 'site' for int. nodes. This uses log's!
+ //
+ String getMinimumInternalPostProbNode() {
+ return minimumProbNode;
+ }
+ int getMinimumInternalPostProbNumber() {
+ return minimumProbNumber;
+ }
+
+ // Get posterior probability at 'site' for sequence 'seq'. This uses log's!
+ //
+ double getOnePostProbAt(int site, String seq) {
+
+ // Outside of range.
+ //
+ if(site<0) {
+ return Double.NEGATIVE_INFINITY;
+ }
+ if(name.equals(seq)) {
+ return postProb[site];
+ }
+
+ if(!child[0].isTerminal) {
+ double post = child[0].getOnePostProbAt(cellPath[site][0]-2,seq);
+ if(post!=Double.NEGATIVE_INFINITY) {
+ return post;
+ }
+ }
+ if(!child[1].isTerminal) {
+ double post = child[1].getOnePostProbAt(cellPath[site][1]-2,seq);
+ if(post!=Double.NEGATIVE_INFINITY) {
+ return post;
+ }
+ }
+
+ return Double.NEGATIVE_INFINITY;
+ }
+
+
+ // Get viterbiEnd for int. nodes. This uses log's!
+ //
+ double[] getInternalViterbiEnd() {
+
+ double[] vit = new double[numChild-1];
+
+ // Order: child[0], parent, child[1]
+ //
+ double[] vit0 = new double[0];
+ double[] vit1 = new double[0];
+
+ if(!child[0].isTerminal) {
+ vit0 = child[0].getInternalViterbiEnd();
+ }
+ if(!child[1].isTerminal) {
+ vit1 = child[1].getInternalViterbiEnd();
+ }
+
+ int c=0;
+ for(int i=0; i<vit0.length; i++) {
+ vit[c++] = vit0[i];
+ }
+ vit[c++] = viterbiEnd;
+ for(int i=0; i<vit1.length; i++) {
+ vit[c++] = vit1[i];
+ }
+
+ return vit;
+
+ }
+
+
+ // Get terminal sequences.
+ //
+ String[] getTerminalSequences() {
+
+ String[] sequences;
+
+ if(isTerminal) {
+ sequences = new String[1];
+ sequences[0] = sequence;
+ } else {
+ sequences = new String[numChild];
+ String[] seqs0 = child[0].getTerminalSequences();
+ String[] seqs1 = child[1].getTerminalSequences();
+
+ int c=0;
+ for(int i=0; i<seqs0.length; i++) {
+ sequences[c++] = seqs0[i];
+ }
+ for(int i=0; i<seqs1.length; i++) {
+ sequences[c++] = seqs1[i];
+ }
+ }
+ return sequences;
+ }
+
+ // Get terminal names only.
+ //
+ String[] getTerminalNames() {
+
+ String[] names;
+
+ if(isTerminal) {
+ names = new String[1];
+ names[0] = name;
+ } else {
+ names = new String[numChild];
+ String[] names0 = child[0].getTerminalNames();
+ String[] names1 = child[1].getTerminalNames();
+
+ int c=0;
+ for(int i=0; i<names0.length; i++) {
+ names[c++] = names0[i];
+ }
+ for(int i=0; i<names1.length; i++) {
+ names[c++] = names1[i];
+ }
+ }
+ return names;
+ }
+
+ // Get terminal pair names only.
+ //
+ String[][] getTerminalPairNames() {
+
+ String[][] names;
+
+ if(child[0].isTerminal && child[1].isTerminal) {
+ names = new String[1][2];
+ names[0][0] = child[0].name;
+ names[0][1] = child[1].name;
+ } else if(child[0].isTerminal) {
+ names = child[1].getTerminalPairNames();
+ } else if(child[1].isTerminal) {
+ names = child[0].getTerminalPairNames();
+ } else {
+ String[][] names0 = child[0].getTerminalPairNames();
+ String[][] names1 = child[1].getTerminalPairNames();
+ names = new String[names0.length+names1.length][2];
+ int c=0;
+ for(int i=0; i<names0.length; i++) {
+ names[c][0] = names0[i][0];
+ names[c++][1] = names0[i][1];
+ }
+ for(int i=0; i<names1.length; i++) {
+ names[c][0] = names1[i][0];
+ names[c++][1] = names1[i][1];
+ }
+ }
+ return names;
+ }
+
+ // Get internal names only.
+ //
+ String[] getInternalNames() {
+
+ String[] names = new String[numChild-1];
+ if(numChild<=2) { // no internal nodes below.
+ names[0] = name;
+ }
+
+ else {
+
+ String[] names0 = new String[0];
+ String[] names1 = new String[0];
+
+ if(!child[0].isTerminal) {
+ names0 = child[0].getInternalNames();
+ }
+ if(!child[1].isTerminal) {
+ names1 = child[1].getInternalNames();
+ }
+
+ int c=0;
+ for(int i=0; i<names0.length; i++) {
+ names[c++] = names0[i];
+ }
+ names[c++] = name;
+ for(int i=0; i<names1.length; i++) {
+ names[c++] = names1[i];
+ }
+ }
+ return names;
+ }
+
+ // Get all names
+ //
+ String[] getAllNames() {
+
+ String[] names;
+
+ if(isTerminal) {
+ names = new String[1];
+ names[0] = name;
+ }
+
+ // Order: child[0], parent, child[1]
+ //
+ else {
+
+ names = new String[2*numChild-1];
+ String[] names0 = child[0].getAllNames();
+ String[] names1 = child[1].getAllNames();
+
+ int c=0;
+ for(int i=0; i<names0.length; i++) {
+ names[c++] = names0[i];
+ }
+ names[c++] = name;
+ for(int i=0; i<names1.length; i++) {
+ names[c++] = names1[i];
+ }
+ }
+ return names;
+ }
+
+ // Needed for graphics (used by getNodeNameAtXY).
+ //
+ void setTreeXY(int x, int y) {
+ treeX = x;
+ treeY = y;
+ }
+
+ // Get node that was clicked.
+ //
+ String getNodeNameAtXY(int x, int y) {
+ int prec = 4; // precision
+ if(Math.abs(treeX-x)<prec && Math.abs(treeY-y)<prec) {
+ return parent.name;
+ }
+ if(!child[1].isTerminal) {
+ String nodeName = child[1].getNodeNameAtXY(x,y);
+ if(!nodeName.equals("")){
+ return nodeName;
+ }
+ }
+ if(!child[0].isTerminal) {
+ String nodeName = child[0].getNodeNameAtXY(x,y);
+ if(!nodeName.equals("")){
+ return nodeName;
+ }
+ }
+ return new String();
+ }
+
+ // Get node by name.
+ //
+ AlignmentNode getNodeNamed(String node) {
+ if(name.equals(node)) {
+ return parent;
+ }
+ if(!child[0].isTerminal) {
+ AlignmentNode kid = child[0].getNodeNamed(node);
+ if(kid.name.equals(node)){
+ return kid;
+ }
+ }
+ if(!child[1].isTerminal) {
+ AlignmentNode kid = child[1].getNodeNamed(node);
+ if(kid.name.equals(node)){
+ return kid;
+ }
+ }
+ return parent;
+ }
+
+ private void writeObject(ObjectOutputStream s)
+ throws IOException {
+
+ s.writeObject("0.2");
+ s.writeBoolean(ProAlign.isDna);
+ s.writeBoolean(isTerminal);
+ s.writeObject(name);
+ s.writeObject(tree);
+ s.writeObject(parent);
+ s.writeInt(numChild);
+
+ s.writeInt(charProb.length);
+ s.writeInt(charProb[0].length);
+ for(int i=0; i<charProb.length; i++) {
+ for(int j=0; j<charProb[0].length; j++) {
+ s.writeDouble(charProb[i][j]);
+ }
+ }
+
+ if(isTerminal) {
+ s.writeObject(sequence);
+ s.writeObject(alphabet);
+
+ } else {
+ s.writeInt(nodeNumber);
+ s.writeInt(treeX);
+ s.writeInt(treeY);
+ s.writeObject(child[0]);
+ s.writeObject(child[1]);
+
+ s.writeDouble(viterbiEnd);
+ s.writeDouble(forwardEnd);
+
+ s.writeInt(postProb.length);
+ for(int i=0; i<postProb.length; i++) {
+ s.writeDouble(postProb[i]);
+ }
+
+ s.writeInt(cellPath.length);
+ s.writeInt(cellPath[0].length);
+ for(int i=0; i<cellPath.length; i++) {
+ for(int j=0; j<cellPath[0].length; j++) {
+ s.writeInt(cellPath[i][j]);
+ }
+ }
+ }
+ }
+
+ private void readObject(ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+
+ // version number can be used for backward compatibility!
+ String version = (String) s.readObject();
+ ProAlign.isDna = s.readBoolean();
+ isTerminal = s.readBoolean();
+ name = (String) s.readObject();
+ tree = (String) s.readObject();
+ parent = (AlignmentNode) s.readObject();
+ numChild = s.readInt();
+
+ int k = s.readInt();
+ int l = s.readInt();
+ charProb = new double[k][l];
+ for(int i=0; i<charProb.length; i++) {
+ for(int j=0; j<charProb[0].length; j++) {
+ charProb[i][j] = s.readDouble();
+ }
+ }
+
+ if(isTerminal) {
+ sequence = (String) s.readObject();
+ alphabet = (String) s.readObject();
+
+ } else {
+ nodeNumber = s.readInt();
+ treeX = s.readInt();
+ treeY = s.readInt();
+ child = new AlignmentNode[2];
+ child[0] = (AlignmentNode) s.readObject();
+ child[1] = (AlignmentNode) s.readObject();
+
+ viterbiEnd = s.readDouble();
+ forwardEnd = s.readDouble();
+
+ k = s.readInt();
+ postProb = new double[k];
+ for(int i=0; i<postProb.length; i++) {
+ postProb[i] = s.readDouble();
+ }
+
+ k = s.readInt();
+ l = s.readInt();
+ cellPath = new int[k][l];
+ for(int i=0; i<cellPath.length; i++) {
+ for(int j=0; j<cellPath[0].length; j++) {
+ cellPath[i][j] = s.readInt();
+ }
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/CheckSequence.java b/CheckSequence.java
new file mode 100644
index 0000000..b5f0935
--- /dev/null
+++ b/CheckSequence.java
@@ -0,0 +1,81 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+public class CheckSequence {
+
+ String error = new String("");
+ String alphabet;
+ CheckSequence() {
+ ProAlign.log("CheckSequence");
+ }
+
+ boolean isDna(HashMap seqs) {
+
+ Iterator seqKeys = seqs.keySet().iterator();
+ String name, seq;
+ int acgt = 0, total = 0;
+
+ while(seqKeys.hasNext()) {
+ name = (String) seqKeys.next();
+ seq = (String) seqs.get(name);
+
+ for(int i=0; i<seq.length(); i++) {
+ if(seq.charAt(i)=='A') {
+ acgt++;
+ } else if(seq.charAt(i)=='C') {
+ acgt++;
+ } else if(seq.charAt(i)=='G') {
+ acgt++;
+ } else if(seq.charAt(i)=='T') {
+ acgt++;
+ } else if(seq.charAt(i)=='U') {
+ acgt++;
+ }
+ total++;
+ }
+ }
+ if(((double) acgt/(double) total)>0.9d) {
+ return true;
+ }
+ return false;
+ }
+
+ boolean isFromAlphabet(HashMap seqs,String alphabet) {
+
+ boolean isFine = true;
+ Iterator seqKeys = seqs.keySet().iterator();
+ String name, seq;
+
+ while(seqKeys.hasNext()) {
+ name = (String) seqKeys.next();
+ seq = (String) seqs.get(name);
+
+ for(int i=0; i<seq.length(); i++) {
+ if(alphabet.indexOf(seq.charAt(i))<0) {
+ isFine = false;
+ error += "\n "+name+": '"+seq.charAt(i)+
+ "' is not from alphabet '"+alphabet+"'!";
+ ProAlign.log.print("\n "+name+": '"+seq.charAt(i)+
+ "' is not from alphabet '"+alphabet+"'!");
+ }
+ }
+ }
+ return isFine;
+ }
+
+ String getError() {
+ return error;
+ }
+}
diff --git a/CheckTrailing.java b/CheckTrailing.java
new file mode 100644
index 0000000..d40316f
--- /dev/null
+++ b/CheckTrailing.java
@@ -0,0 +1,55 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class CheckTrailing {
+
+ PwAlignment pwa;
+
+ CheckTrailing(ProAlign pa) {
+
+ ProAlign.log("CheckTrailing");
+
+ PwSubstitutionMatrix psm = new PwSubstitutionMatrix();
+ String pwAlphabet;
+ int[][] pwSubst;
+ int gOpen, gExt;
+
+ if(ProAlign.isDna){
+ pwAlphabet = psm.dnaAlphabet;
+ pwSubst = psm.swdna;
+ gOpen = -1*pa.pwDnaOpen;
+ gExt = -1*pa.pwDnaExt;
+
+ } else {
+
+ pwAlphabet = psm.protAlphabet;
+ if(pa.pwProtMatrix.equals("pam60")) {
+ pwSubst = psm.pam60;
+ } else if(pa.pwProtMatrix.equals("pam160")) {
+ pwSubst = psm.pam160;
+ } else if(pa.pwProtMatrix.equals("pam250")) {
+ pwSubst = psm.pam250;
+ } else {
+ pwSubst = psm.pam120;
+ }
+ gOpen = -1*pa.pwProtOpen;
+ gExt = -1*pa.pwProtExt;
+ }
+
+ pwa = new PwAlignment(pwSubst,gOpen,gExt,pwAlphabet,ProAlign.isDna);
+ }
+
+ int[] trailing(String s1, String s2) {
+ return pwa.trailing(s1,s2);
+ }
+
+}
diff --git a/CheckTreeAndData.java b/CheckTreeAndData.java
new file mode 100644
index 0000000..bb8779d
--- /dev/null
+++ b/CheckTreeAndData.java
@@ -0,0 +1,46 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.util.HashMap;
+
+class CheckTreeAndData {
+
+ boolean isFine = true;
+ boolean isDone = false;
+ String error = new String("");
+
+ CheckTreeAndData(String[] treeNodes, HashMap seqs) {
+
+ ProAlign.log("CheckTreeAndData");
+
+ for(int i=0; i<treeNodes.length; i++) {
+ isDone = true;
+ if(!seqs.containsKey(treeNodes[i])) {
+ isFine = false;
+ ProAlign.log.println("CheckTreeAndData: "+treeNodes[i]+": no sequence found!");
+ error = ""+treeNodes[i]+": no sequence found!";
+ }
+ }
+ }
+
+ boolean nodesAreSame() {
+ if(isDone) {
+ return isFine;
+ } else {
+ return false;
+ }
+ }
+
+ String getError() {
+ return error;
+ }
+}
diff --git a/EstimateFrequencies.java b/EstimateFrequencies.java
new file mode 100644
index 0000000..1576e19
--- /dev/null
+++ b/EstimateFrequencies.java
@@ -0,0 +1,61 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class EstimateFrequencies {
+
+ double[] charFreqs;
+
+ EstimateFrequencies(String[] dataArray, String alphabet, String equateAlphabet) {
+
+ ProAlign.log("EstimateFrequencies");
+
+ equateAlphabet = equateAlphabet+"-";
+
+ int[] eqCounts = new int[equateAlphabet.length()];
+
+ int sum = 0;
+ for(int i=0; i<dataArray.length; i++) {
+ for(int j=0; j<dataArray[i].length(); j++) {
+ eqCounts[equateAlphabet.indexOf(dataArray[i].charAt(j))]++;
+ sum++;
+ }
+ }
+
+ float[] counts = new float[alphabet.length()];
+ counts[0] = (float)eqCounts[0]+(float)eqCounts[4]/2f+(float)eqCounts[6]/2f+
+ (float)eqCounts[9]/2f+(float)eqCounts[10]/3f+(float)eqCounts[12]/3f+
+ +(float)eqCounts[13]/3f+(float)eqCounts[14]/4f;
+ counts[1] = (float)eqCounts[1]+(float)eqCounts[5]/2f+(float)eqCounts[6]/2f+
+ (float)eqCounts[8]/2f+(float)eqCounts[10]/3f+(float)eqCounts[11]/3f+
+ +(float)eqCounts[12]/3f+(float)eqCounts[14]/4f;
+ counts[2] = (float)eqCounts[2]+(float)eqCounts[4]/2f+(float)eqCounts[7]/2f+
+ (float)eqCounts[8]/2f+(float)eqCounts[11]/3f+(float)eqCounts[12]/3f+
+ +(float)eqCounts[13]/3f+(float)eqCounts[14]/4f;
+ counts[3] = (float)eqCounts[3]+(float)eqCounts[5]/2f+(float)eqCounts[7]/2f+
+ (float)eqCounts[9]/2f+(float)eqCounts[10]/3f+(float)eqCounts[11]/3f+
+ +(float)eqCounts[13]/3f+(float)eqCounts[14]/4f+eqCounts[15];
+ counts[4] = (float)eqCounts[16];
+
+ charFreqs = new double[alphabet.length()];
+ for(int i=0; i<alphabet.length(); i++) {
+ charFreqs[i] = (double) counts[i]/sum;
+ }
+
+ for(int i=0; i<alphabet.length(); i++) {
+ ProAlign.log(" "+alphabet.charAt(i)+":"+charFreqs[i]);
+ }
+ }
+
+ double[] getCharacterFrequencies() {
+ return charFreqs;
+ }
+}
diff --git a/InFile.java b/InFile.java
new file mode 100644
index 0000000..c9265a2
--- /dev/null
+++ b/InFile.java
@@ -0,0 +1,16 @@
+package proalign;
+
+import java.io.File;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
+import java.io.BufferedInputStream;
+import java.io.FileNotFoundException;
+
+public class InFile extends DataInputStream {
+ public InFile(String filename) throws FileNotFoundException {
+ super(new BufferedInputStream(new FileInputStream(filename)));
+ }
+ public InFile(File file) throws FileNotFoundException {
+ this(file.getPath());
+ }
+}
diff --git a/MinimumProbWindow.java b/MinimumProbWindow.java
new file mode 100644
index 0000000..5f15ba1
--- /dev/null
+++ b/MinimumProbWindow.java
@@ -0,0 +1,87 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JViewport;
+import javax.swing.JScrollPane;
+import javax.swing.JScrollBar;
+import javax.swing.BorderFactory;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+
+public class MinimumProbWindow extends JFrame {
+
+ JScrollPane sPane;
+ int height;
+ double[] minProb;
+
+ PixelRule pixRule;
+ PrintMinimumCurve curve;
+ ResultWindow rw;
+ String[] nodes;
+
+ MinimumProbWindow(double[] minProb, String[] nodes, ResultWindow rw) {
+
+ this.rw = rw;
+ this.nodes = nodes;
+ this.minProb = minProb;
+
+ height = this.getHeight();
+
+ setTitle("Minimum posterior probability");
+
+ curve = new PrintMinimumCurve(MinimumProbWindow.this, minProb, nodes);
+
+ // pixelruler.
+ pixRule = new PixelRule();
+ pixRule.setPreferredWidth((int) curve.getPreferredSize().getWidth());
+ pixRule.setIncrement(curve.xScale);
+ pixRule.setBackground(Color.white);
+
+
+ sPane = new JScrollPane(curve,
+ JScrollPane.VERTICAL_SCROLLBAR_NEVER,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+
+
+ sPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
+ sPane.setColumnHeaderView(pixRule);
+ sPane.setBackground(Color.white);
+
+ Container cp = getContentPane();
+ cp.add(sPane);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e){
+ PrintTree.numOpenWindows--;
+ dispose();
+ }
+ });
+ }
+
+ int getVisibleHeight() {
+ return sPane.getViewport().getHeight();
+ }
+}
+
+
+
+
+
+
+
diff --git a/NeighborJoining.java b/NeighborJoining.java
new file mode 100644
index 0000000..6186268
--- /dev/null
+++ b/NeighborJoining.java
@@ -0,0 +1,178 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+// As Implemented by Studier and Keppler (1988) in Li (1997), p. 111.
+//
+class NeighborJoining {
+
+ String[] newOtus;
+ String tree = new String();
+ String tree3 = new String();
+
+ NeighborJoining(double[][] distance, String[] otus) {
+
+ ProAlign.log("NeighborJoining");
+
+ while(distance.length>2) {
+ distance = joinNeighbors(distance, otus);
+ otus = newOtus;
+ }
+
+ double dist = Math.abs((distance[0][0]+distance[0][1])/2d);
+
+
+ tree = "("+otus[0]+":"+dist+","+otus[1]+":"+dist+");";
+
+ if(otus[0].startsWith("(")&&otus[0].endsWith(")")) {
+ tree3 = otus[0].substring(0,otus[0].length()-2)+","+
+ otus[1]+":"+dist*2d+");";
+ } else {
+ tree3 = "("+otus[0]+":"+dist*2d+","+otus[1].substring(1)+";";;
+ }
+ }
+
+ String getTree() {
+ return tree;
+ }
+ String getTree3() {
+ return tree3;
+ }
+
+ double[][] joinNeighbors(double[][] distance, String[] otus) {
+
+
+ int no = distance.length;
+ int otu1=0, otu2=0;
+ double minM = Double.POSITIVE_INFINITY;
+
+ double[] rDist = new double[no]; // sum of distances d_i,j
+
+ for(int i=0; i<no; i++) {
+ for(int j=0; j<no; j++) {
+ rDist[i] += distance[i][j];
+ }
+ }
+ for(int i=0; i<no; i++) {
+ for(int j=0; j<no; j++) {
+ if(j==i) {
+ continue;
+ }
+ double mDist = distance[i][j]-(rDist[i]+rDist[j])/(no-2);
+ if(mDist<minM) {
+ minM = mDist;
+ otu1 = Math.min(i,j);
+ otu2 = Math.max(i,j);
+ }
+ }
+ }
+
+ double brl1 = distance[otu1][otu2]/2+
+ (rDist[otu1]-rDist[otu2])/(2*(no-2));
+ double brl2 = distance[otu1][otu2]-brl1;
+
+
+ double[][] newDistance = new double[no-1][no-1];
+ newOtus = new String[no-1];
+ int ci=0;
+ int cj=0;
+
+ for(int i=0; i<no; i++) {
+ for(int j=0; j<no; j++) {
+ if(i==j) {
+ continue;
+ }
+
+ if(j<otu2) {
+ cj=j;
+ } else if(j==otu2) {
+ continue;
+ } else {
+ cj=j-1;
+ }
+
+ if(i<otu2) {
+ ci=i;
+ } else if(i==otu2) {
+ continue;
+ } else {
+ ci=i-1;
+ }
+
+ if(i==otu1) {
+ newDistance[ci][cj] = (distance[otu1][j]+distance[otu2][j]-
+ distance[otu1][otu2])/2;
+ } else if(j==otu1) {
+ newDistance[ci][cj] = (distance[otu1][i]+distance[otu2][i]-
+ distance[otu1][otu2])/2;
+ } else {
+ newDistance[ci][cj] = distance[i][j];
+ }
+ }
+ }
+
+ for(int i=0; i<no; i++) {
+ if(i==otu1) {
+ newOtus[i] = "("+otus[otu1]+":"+Math.abs(brl1)+","+
+ otus[otu2]+":"+Math.abs(brl2)+")";
+ continue;
+ } else if(i<otu2) {
+ ci = i;
+ } else if(i==otu2) {
+ continue;
+ } else {
+ ci=i-1;
+ }
+ newOtus[ci] = otus[i];
+ }
+
+ return newDistance;
+ }
+
+ public static void main(String[] args) {
+
+ // Reads PHYLIP distance tables
+
+ double[][] distance = new double [0][0];
+ String[] otus = new String[0];
+
+ try {
+
+ InFile in = new InFile(args[0]);
+ String row = in.readLine();
+ int no = new Integer(row.trim()).intValue();
+
+ otus = new String[no];
+ distance = new double[no][no];
+
+ int i=0;
+ while((row = in.readLine()) != null) {
+ otus[i] = row.substring(0,10).trim();
+ row = row.substring(11).trim();
+ for(int j=0; j<no-1; j++) {
+ String value = row.substring(0,row.indexOf(" ")).trim();
+ distance[i][j] = new Double(value).doubleValue();
+ row = row.substring(row.indexOf(" ")).trim();
+ }
+ distance[i][no-1] = new Double(row.trim()).doubleValue();
+ i++;
+ }
+ } catch(Exception e) {
+ System.out.println("Problems with "+args[0]);
+ e.printStackTrace();
+ System.exit(0);
+ }
+
+ NeighborJoining nj = new NeighborJoining(distance,otus);
+ System.out.println(nj.getTree());
+ System.out.println(nj.getTree3());
+ }
+}
diff --git a/NicePrint.java b/NicePrint.java
new file mode 100644
index 0000000..2c19831
--- /dev/null
+++ b/NicePrint.java
@@ -0,0 +1,50 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class NicePrint {
+ NicePrint() { };
+ String dbl(double number, int length) {
+ return ((""+number+" ").substring(0,length+1));
+ }
+
+ String rdbl(double val, int prec) {
+ String full = ""+val;
+ if(full.indexOf('.')>-1) {
+ String begin = full.substring(0,full.indexOf('.'));
+ String end = full.substring(full.indexOf('.')+1);
+ if(end.length()>prec) {
+ String zeros = new String();
+ while(end.startsWith("0")) {
+ end = end.substring(1);
+ zeros += "0";
+ }
+ char num = end.charAt(prec);
+ if(num=='0'||num=='1'||num=='2'||num=='3'||num=='4') {
+ full = begin+"."+zeros+end.substring(0,prec);
+ } else {
+ full = begin+"."+zeros+(new Integer(end.substring(0,prec)).intValue()+1);
+ }
+ }
+ }
+ return full;
+ }
+
+ void pdbl(double number, int length) {
+ System.out.print((""+number+" ").substring(0,length+1));
+ }
+ void str(String str) {
+ System.out.print(str);
+ }
+ void strl(String str) {
+ System.out.println(str);
+ }
+}
diff --git a/OpenDialog.java b/OpenDialog.java
new file mode 100644
index 0000000..1cd0e2a
--- /dev/null
+++ b/OpenDialog.java
@@ -0,0 +1,53 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.awt.Component;
+import java.awt.Font;
+import java.io.File;
+import java.io.IOException;
+import javax.swing.JTextArea;
+import javax.swing.BorderFactory;
+import javax.swing.border.Border;
+import javax.swing.JOptionPane;
+import javax.swing.JDialog;
+import java.awt.Color;
+
+public class OpenDialog extends JDialog {
+
+ Font font = new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize);
+ Component parent;
+
+ OpenDialog(Component parent) {
+ this.parent = parent;
+ }
+
+ void showDialog(String title, String text) {
+
+ JTextArea ta = new JTextArea(text);
+ ta.setFont(font);
+ ta.setEditable(false);
+ ta.setBackground(Color.white);
+
+ Border loweredbevel = BorderFactory.createLoweredBevelBorder();
+ ta.setBorder(loweredbevel);
+
+ JOptionPane op = new JOptionPane();
+ op.setMessage(ta);
+ op.setMessageType(JOptionPane.PLAIN_MESSAGE);
+
+ JDialog dialog = op.createDialog(parent,title);
+ dialog.setLocation(150,150);
+ dialog.show();
+ }
+}
+
+
diff --git a/OpenFileChooser.java b/OpenFileChooser.java
new file mode 100644
index 0000000..c2951c0
--- /dev/null
+++ b/OpenFileChooser.java
@@ -0,0 +1,55 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFileChooser;
+import java.awt.Component;
+import java.awt.Font;
+import java.io.File;
+import java.io.IOException;
+
+public class OpenFileChooser extends JFileChooser {
+
+ Component parent;
+ String txt;
+ boolean useFilter;
+
+ OpenFileChooser(Component parent, String txt, boolean useFilter) {
+ this.parent = parent;
+ this.txt = txt;
+ this.useFilter = useFilter;
+ }
+
+ String openFile() {
+
+ String filepath = new String("");
+ JFileChooser jfc = new JFileChooser(ProAlign.folderPath);
+ if(useFilter) {
+ jfc.addChoosableFileFilter(new PAFileFilter());
+ }
+ int returnValue = jfc.showDialog(parent, txt);
+
+ if(returnValue == JFileChooser.APPROVE_OPTION) {
+ File path;
+ if (jfc.getCurrentDirectory().toString().endsWith(File.separator)) {
+ path = new File(jfc.getCurrentDirectory().toString()
+ + jfc.getSelectedFile().getName());
+ } else {
+ path = new File(jfc.getCurrentDirectory().toString()
+ + File.separator + jfc.getSelectedFile().getName());
+ }
+ filepath = path.toString();
+ }
+ return filepath;
+
+ }
+}
+
diff --git a/OpenFolderChooser.java b/OpenFolderChooser.java
new file mode 100644
index 0000000..7102a5d
--- /dev/null
+++ b/OpenFolderChooser.java
@@ -0,0 +1,52 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFileChooser;
+import java.awt.Component;
+import java.awt.Font;
+import java.io.File;
+import java.io.IOException;
+
+public class OpenFolderChooser extends JFileChooser {
+
+ Component parent;
+ String txt;
+
+ OpenFolderChooser(Component parent, String txt) {
+ this.parent = parent;
+ this.txt = txt;
+ }
+
+ String openFile() {
+
+ String filepath = new String("");
+ JFileChooser jfc = new JFileChooser(ProAlign.folderPath);
+ jfc.setFileSelectionMode(1);
+
+ int returnValue = jfc.showDialog(parent, txt);
+
+ if(returnValue == JFileChooser.APPROVE_OPTION) {
+ File path;
+ if (jfc.getCurrentDirectory().toString().endsWith(File.separator)) {
+ path = new File(jfc.getCurrentDirectory().toString()
+ + jfc.getSelectedFile().getName());
+ } else {
+ path = new File(jfc.getCurrentDirectory().toString()
+ + File.separator + jfc.getSelectedFile().getName());
+ }
+ filepath = path.toString();
+ }
+ return filepath;
+
+ }
+}
+
diff --git a/OutFile.java b/OutFile.java
new file mode 100644
index 0000000..3c47616
--- /dev/null
+++ b/OutFile.java
@@ -0,0 +1,20 @@
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.BufferedOutputStream;
+import java.io.FileOutputStream;
+
+public class OutFile extends PrintStream {
+ public OutFile(String filename)
+ throws IOException {
+ super(
+ new BufferedOutputStream(
+ new FileOutputStream(filename)));
+ }
+ public OutFile(File file)
+ throws IOException {
+ this(file.getPath());
+ }
+}
diff --git a/OutOfMemoryException.java b/OutOfMemoryException.java
new file mode 100644
index 0000000..784262c
--- /dev/null
+++ b/OutOfMemoryException.java
@@ -0,0 +1,19 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+public class OutOfMemoryException extends Exception {
+
+ public OutOfMemoryException() {}
+ public OutOfMemoryException(String msg) {
+ super(msg);
+ }
+}
diff --git a/PAFileFilter.java b/PAFileFilter.java
new file mode 100644
index 0000000..e4a330a
--- /dev/null
+++ b/PAFileFilter.java
@@ -0,0 +1,46 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import javax.swing.filechooser.FileFilter;
+
+public class PAFileFilter extends FileFilter {
+
+ // Accept all directories and files ending with ProAlign.fileExt .
+ public boolean accept(File f) {
+ if (f.isDirectory()) {
+ return true;
+ }
+
+ String s = f.getName();
+ int i = s.lastIndexOf('.');
+ String ext = new String();
+ if (i > 0 && i < s.length() - 1) {
+ ext = s.substring(i+1).toLowerCase();
+ }
+
+ if (ext != null) {
+ if (ext.equals(ProAlign.fileExt)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ return false;
+ }
+
+ // The description of this filter
+ public String getDescription() {
+ return "ProAlign Object-file";
+ }
+}
diff --git a/ParameterEstimates.java b/ParameterEstimates.java
new file mode 100644
index 0000000..42abbd0
--- /dev/null
+++ b/ParameterEstimates.java
@@ -0,0 +1,195 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.util.HashMap;
+
+public class ParameterEstimates {
+
+ String[][] pairs;
+ HashMap seqs;
+ PwAlignment pwa;
+
+ ParameterEstimates(ResultWindow rw,SetParameters sp) {
+
+ this.seqs = rw.seqs;
+
+ PwSubstitutionMatrix psm = new PwSubstitutionMatrix();
+ String pwAlphabet;
+ int[][] pwSubst;
+ int gOpen, gExt;
+
+ if(ProAlign.isDna){
+ pwAlphabet = psm.dnaAlphabet;
+ pwSubst = psm.swdna;
+ gOpen = -1*rw.pa.pwDnaOpen;
+ gExt = -1*rw.pa.pwDnaExt;
+
+ } else {
+
+ pwAlphabet = psm.protAlphabet;
+ if(rw.pa.pwProtMatrix.equals("pam60")) {
+ pwSubst = psm.pam60;
+ } else if(rw.pa.pwProtMatrix.equals("pam160")) {
+ pwSubst = psm.pam160;
+ } else if(rw.pa.pwProtMatrix.equals("pam250")) {
+ pwSubst = psm.pam250;
+ } else {
+ pwSubst = psm.pam120;
+ }
+ gOpen = -1*rw.pa.pwProtOpen;
+ gExt = -1*rw.pa.pwProtExt;
+ }
+
+ pwa = new PwAlignment(pwSubst,gOpen,gExt,pwAlphabet,ProAlign.isDna);
+
+ pairs = rw.root.getTerminalPairNames();
+
+ this.estimate();
+
+ sp.textDelta.setText((""+ProAlign.modelDelta+" ").substring(0,5));
+ sp.textEpsil.setText((""+ProAlign.modelEpsilon+" ").substring(0,5));
+
+ }
+
+ ParameterEstimates(RunCommandLine rcl) {
+
+ ProAlign.log("ParameterEstimates");
+
+ AlignmentNode root = rcl.root;
+
+ seqs = rcl.pa.seqs;
+ pwa = rcl.pwa;
+
+ pairs = root.getTerminalPairNames();
+
+ this.estimate();
+ }
+
+ void estimate() {
+
+ double gapFreq = 0d;
+ double sumDelta = 0d;
+ double sumEpsilon = 0d;
+
+ for(int i=0; i<pairs.length; i++) {
+
+ String s0 = (String)seqs.get(pairs[i][0]);
+ String s1 = (String)seqs.get(pairs[i][1]);
+
+ String[] revSeq = pwa.revAligned(s0,s1);
+
+ int all = 0;
+ int ms = 0; // match sum
+ int mn = 1; // match numebr
+ int ml = 0; // match length
+ int gs = 0;
+ int gn = 1;
+ int gl = 0;
+ double mm = 5d; // match mean
+ double mg = 5d;
+ boolean isM = false;
+
+ for(int k=0; k<revSeq[0].length(); k++) {
+ if(k==0) {
+ if(revSeq[0].charAt(k)=='-' || revSeq[1].charAt(k)=='-') {
+ gn++;
+ } else {
+ mn++;
+ }
+ }
+
+ if(revSeq[0].charAt(k)=='-' || revSeq[1].charAt(k)=='-') {
+ gs++;
+ gl++;
+ if(isM) {
+ if(k>0) {
+ if(mn>1) {
+ mm = ((double)mm*(mn-1)+ml)/mn;
+ } else {
+ mm = (mm+ml)/2;
+ }
+ ml=0;
+ gn++;
+ }
+ isM = false;
+ }
+ } else {
+ ms++;
+ ml++;
+ if(!isM) {
+ if(k>0) {
+ if(gn>1) {
+ mg = ((double)mg*(gn-1)+gl)/gn;
+ } else {
+ mg = (mg+gl)/2;
+ }
+ gl=0;
+ mn++;
+ }
+ isM = true;
+ }
+ }
+
+ if(k+1==revSeq[0].length()) {
+ if(isM) {
+ if(mn>1) {
+ mm = ((double)mm*(mn-1)+ml)/mn;
+ } else {
+ mm = ml;
+ }
+ } else {
+ if(gn>1) {
+ mg = ((double)mg*(gn-1)+gl)/gn;
+ } else {
+ mg = gl;
+ }
+ }
+ }
+ all++;
+ }
+ gapFreq += (double)gs/(2*all);
+ sumDelta += mm;
+ sumEpsilon += mg;
+ }
+
+ gapFreq /= pairs.length;
+ sumDelta /= pairs.length;
+ sumEpsilon /= pairs.length;
+
+ if(ProAlign.estimateDelta) {
+ ProAlign.modelDelta = 0.5d/(sumDelta+1);
+ ProAlign.log.println(" HMM delta estimate: "+ProAlign.modelDelta);
+// System.out.println("modelDelta: "+ProAlign.modelDelta);
+ }
+ if(ProAlign.estimateEpsilon) {
+ ProAlign.modelEpsilon = (1d-1d/(sumEpsilon+1));
+ ProAlign.log.println(" HMM epsilon estimate: "+ProAlign.modelEpsilon);
+// System.out.println("modelEpsilon: "+ProAlign.modelEpsilon);
+ }
+ if(ProAlign.estimateGapFreq) {
+ ProAlign.gapFreq = gapFreq;
+ ProAlign.log.println(" gap frequency estimate: "+ProAlign.gapFreq);
+// System.out.println("gapFreq: "+ProAlign.gapFreq);
+ }
+ if(ProAlign.estimateGapProb) {
+ if(ProAlign.isDna) {
+ ProAlign.gapProb = gapFreq/4d;
+ } else {
+ ProAlign.gapProb = gapFreq/20d;
+ }
+ ProAlign.log.println(" gap probability estimate: "+ProAlign.gapProb);
+// System.out.println("gapProb: "+ProAlign.gapProb);
+ }
+
+ }
+
+}
diff --git a/PixelRule.java b/PixelRule.java
new file mode 100644
index 0000000..9769a77
--- /dev/null
+++ b/PixelRule.java
@@ -0,0 +1,102 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.awt.Toolkit;
+import java.awt.Graphics;
+import java.awt.Dimension;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+
+// A nice ruler for the quality window.
+//
+public class PixelRule extends JComponent {
+ int rulerHeight = 15;
+
+ private int increment;
+ private int startPosition = 0;
+ private int units;
+
+ public PixelRule() { }
+
+ public void setIncrement(int xScale) {
+ increment = xScale;
+ units = 25*xScale;
+ }
+
+ public void setPreferredWidth(int pw) {
+ setPreferredSize(new Dimension(pw,rulerHeight));
+ }
+
+ public void paintComponent(Graphics g) {
+ Rectangle drawHere = g.getClipBounds();
+
+ // Fill clipping area
+ g.setColor(Color.white);
+ g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
+
+ // Do the ruler labels in a small font
+ g.setFont(new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize-2));
+ g.setColor(Color.black);
+
+ // Some vars we need.
+ int tickLength = 0;
+ String text = null;
+
+ // Use clipping bounds to calculate first tick and last tick location.
+ int start = (drawHere.x / increment) * increment;
+ int end = (((drawHere.x + drawHere.width) / increment) + 1) * increment;
+
+ // Make a special case of 0 to display the number
+ // within the rule and draw a units label.
+ if (start == 0) {
+ text = Integer.toString(0);
+ tickLength = 3;
+ g.drawLine(0, rulerHeight-1, 0, rulerHeight-tickLength-1);
+ g.drawString("0", 0, 10);
+ start = increment;
+ }
+
+ // ticks and labels
+ for (int i = start; i < end; i += increment) {
+ if (i % units == 0) {
+ tickLength = 3;
+ text = Integer.toString(i/increment);
+ } else if(i % 10 == 0) {
+ tickLength = 1;
+ text = null;
+ } else {
+ tickLength = 0;
+ text = null;
+ }
+
+ if (tickLength != 0) {
+ g.drawLine(i, rulerHeight-1, i, rulerHeight-tickLength-1);
+ if (text != null)
+ g.drawString(text, i-10, 10);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PrintCurve.java b/PrintCurve.java
new file mode 100644
index 0000000..47ae598
--- /dev/null
+++ b/PrintCurve.java
@@ -0,0 +1,76 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JPanel;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+// Print a curve on a JPanel.
+//
+public class PrintCurve extends JPanel {
+
+ double[] postProb;
+ int height = 100;
+ int xScale = 2; // scale: pixels per column.
+ PrintCurve pc;
+ QualityWindow qw;
+
+ PrintCurve(QualityWindow qw, double[] postProb) {
+ pc = this;
+ this.qw = qw;
+ this.postProb = postProb;
+
+ setBackground(Color.white);
+ setForeground(Color.black);
+
+ setPreferredSize(new Dimension(xScale*postProb.length, height));
+ addMouseListener(new MiceListener());
+ }
+
+ // Update data when changing node.
+ //
+ void upDateData(double[] postProb) {
+ this.postProb = postProb;
+ pc.updateUI();
+ }
+
+ public void paintComponent(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+ super.paintComponent(g2); //clears the background
+ height = pc.qw.getVisibleHeight();
+ pc.setPreferredSize(new Dimension(xScale*postProb.length, height));
+ for(int i=0; i<postProb.length-1; i++) {
+ int y1 = (int) (Math.exp(postProb[i])*height);
+ int y2 = (int) (Math.exp(postProb[i+1])*height);
+ if(y1>0 && y2>0) {
+ g2.drawLine(i*xScale,height-y1,(i+1)*xScale,height-y2);
+ }
+ }
+ }
+
+ // Listens mouse click: focus alignment, update messageText.
+ //
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ qw.rw.focusAlignment(x/xScale);
+ qw.rw.convertNodeInfoX(x/xScale,qw.name);
+ }
+ }
+}
+
diff --git a/PrintData.java b/PrintData.java
new file mode 100644
index 0000000..84b0ace
--- /dev/null
+++ b/PrintData.java
@@ -0,0 +1,382 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.RenderingHints;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+
+// Prints alignment characters with nice colors, shows quality as color.
+//
+public class PrintData extends JPanel {
+
+ final Color bg = Color.white;
+ final Color fg = Color.black;
+ final Color purple = new Color(250,90,240);
+ final Color lblue = new Color(90,210,250);
+ final Color brown = new Color(200,160,30);
+ final Color blue = new Color(205,205,255);
+
+ int verticalCharSpace;
+ int horizontalCharSpace;
+
+ Font printFont;
+ FontMetrics currentMetrics;
+
+ int columnWidth, rowHeight;
+ int totalWidth, totalHeight;
+ int charWidth, charHeight;
+ int maxLength;
+
+ int startSite = -1;
+
+ boolean isDataGiven = false;
+ boolean isDataAligned = false;
+ boolean hasMouseListener = false;
+
+ boolean[] taxaRemoved = new boolean[0];
+ boolean[] sitesRemoved = new boolean[0];
+
+ String textArray[];
+ double[][] postProb;
+
+ PrintData pd;
+ ResultWindow parent;
+ JScrollPane sPane = null;
+
+ MiceListener mListener;
+
+ public PrintData() {
+ this.setParameters();
+ }
+
+ public PrintData(String[] textArray, int maxLength, ResultWindow rw) {
+
+ pd = this;
+ parent = rw;
+ this.maxLength = maxLength;
+ this.textArray = textArray;
+
+ verticalCharSpace = ResultWindow.verticalCharSpace;
+ horizontalCharSpace = ResultWindow.horizontalCharSpace;
+
+ this.setParameters();
+
+ isDataGiven = true;
+ isDataAligned = false;
+
+ totalWidth = maxLength*columnWidth+horizontalCharSpace;
+ totalHeight = textArray.length*rowHeight+verticalCharSpace;
+ setPreferredSize(new Dimension(totalWidth,totalHeight));
+
+ if(hasMouseListener) {
+ removeMouseListener(mListener);
+ hasMouseListener = false;
+ }
+ }
+
+ public PrintData(String[] textArray, double[][] postProb, ResultWindow rw) {
+
+ pd = this;
+ parent = rw;
+
+ this.textArray = textArray;
+ this.postProb = postProb;
+
+ verticalCharSpace = ResultWindow.verticalCharSpace;
+ horizontalCharSpace = ResultWindow.horizontalCharSpace;
+
+ this.setParameters();
+
+ isDataGiven = true;
+ isDataAligned = true;
+
+ sitesRemoved = new boolean[textArray[0].length()];
+ maxLength = textArray[0].length();
+
+ totalWidth = maxLength*columnWidth+horizontalCharSpace;
+ totalHeight = textArray.length*rowHeight+verticalCharSpace;
+ setPreferredSize(new Dimension(totalWidth,totalHeight));
+
+ mListener = new MiceListener();
+ addMouseListener(mListener);
+ hasMouseListener = true;
+
+ }
+
+ // Some parameters need to be set even without data.
+ //
+ void setParameters() {
+
+ printFont = new Font("monospaced", Font.BOLD, ResultWindow.rwFontSize);
+
+ setBackground(bg);
+ setForeground(fg);
+
+ currentMetrics = this.getFontMetrics(printFont);
+ charWidth = currentMetrics.charWidth(' ');
+ charHeight = currentMetrics.getHeight();
+
+ columnWidth = charWidth + horizontalCharSpace;
+ rowHeight = charHeight + verticalCharSpace;
+ }
+
+
+ public void paint(Graphics g) {
+
+ if(printFont.getSize()!=ResultWindow.rwFontSize ||
+ horizontalCharSpace!=ResultWindow.horizontalCharSpace ||
+ verticalCharSpace!=ResultWindow.verticalCharSpace){
+
+ printFont = new Font("monospaced", Font.BOLD, ResultWindow.rwFontSize);
+ horizontalCharSpace=ResultWindow.horizontalCharSpace;
+ verticalCharSpace=ResultWindow.verticalCharSpace;
+
+ this.setParameters();
+ }
+
+ if(isDataGiven) { // if no data, no update.
+ totalWidth = Math.max(maxLength*columnWidth+
+ horizontalCharSpace,sPane.getWidth());
+ totalHeight = Math.max(textArray.length*rowHeight+
+ verticalCharSpace,sPane.getHeight());
+ setPreferredSize(new Dimension(totalWidth,totalHeight));
+
+ int startX = sPane.getHorizontalScrollBar().getValue();
+ int endX = startX + sPane.getWidth();
+ int startY = sPane.getVerticalScrollBar().getValue();
+ int endY = startY + sPane.getHeight();
+
+ int startColumn = (int) (startX/columnWidth);
+ int endColumn = Math.min((int)(endX/columnWidth)+1,maxLength);
+ int startRow = (int) (startY/rowHeight);
+ int endRow = Math.min((int)(endY/rowHeight)+1,textArray.length);
+
+ int charX = startColumn * columnWidth;
+ int charY = rowHeight + startRow * rowHeight;
+
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setColor(bg);
+ g2.setFont(printFont);
+ g2.fillRect(Math.max(startX-10,0),Math.max(startY-10,0),
+ Math.min(endX+10,totalWidth),Math.min(endY+10,totalHeight));
+
+ for (int i = startRow; i < endRow; i++) {
+ String str = textArray[i];
+ for (int j = startColumn; j < endColumn; j++) {
+
+ if(j>=str.length()) { break; } // unaligned seqs can be of different length.
+
+ if(isDataAligned) { // if aligned, draw "selected/not-selected".
+ // Do only once...
+ if (i == startRow) {
+ if (j < sitesRemoved.length) {
+ if (sitesRemoved[j]) {
+ g2.setColor(blue);
+ g2.fillRect(charX,0,(charX+columnWidth),totalHeight);
+
+ } else {
+ g2.setColor(bg);
+ g2.fillRect(charX,0,(charX+columnWidth),totalHeight);
+ }
+ }
+ }
+ // ..until here.
+ }
+
+ g2.setColor(getColor(str.charAt(j)));
+ g2.drawString(""+str.charAt(j), charX, charY);
+ charX += columnWidth;
+ }
+
+ if(isDataAligned) { // if aligned, draw color box.
+ if(i<postProb[0].length) {
+ charX = startColumn * columnWidth ;
+ for (int j = startColumn; j < endColumn; j++) {
+ g2.setColor(getProbColor(postProb[j][i]));
+ g2.fillRect(charX+1,charY+1,columnWidth-2,verticalCharSpace-2);
+ g2.setColor(bg);
+ charX += columnWidth;
+ }
+ }
+ }
+
+ charY += rowHeight;
+ charX = startColumn * columnWidth ;
+ }
+ }
+ }
+
+ // A click on "quality box" updates messageText on the scree.
+ //
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ int col = (int) x/columnWidth;
+ y = y - rowHeight/2;
+ if(y<0) { y = 0; }
+ int row = (int) y/rowHeight;
+ if(col >= postProb.length) { col=postProb.length-1; }
+ if(row >= postProb[0].length) { row = postProb[0].length-1; }
+
+ parent.writeNodeInfo(col,row);
+
+ }
+ }
+
+ // Called from Rule.
+ //
+ void updateStableSites(int x, int y, boolean shiftDown) {
+ if(pd.isDataAligned) {
+
+ if(shiftDown) { // shift down -> range selection
+ if(startSite > 0) {
+ int site = (int) x/columnWidth;
+ int start, end;
+ if(startSite>site) {
+ start = site;
+ end = startSite;
+ } else {
+ start = startSite+1;
+ end = site+1;
+ }
+ for(int sx=start; sx<end; sx++) {
+ if (sitesRemoved[sx])
+ sitesRemoved[sx] = false;
+ else
+ sitesRemoved[sx] = true;
+ }
+ pd.repaint();
+
+ startSite = -1;
+ } else {
+ int site = (int) x/columnWidth;
+
+ if (sitesRemoved[site])
+ sitesRemoved[site] = false;
+ else
+ sitesRemoved[site] = true;
+ pd.repaint();
+
+ startSite = site;
+ }
+
+ } else { // not shift down -> single selection
+ int site = (int) x/columnWidth;
+
+ if (sitesRemoved[site])
+ sitesRemoved[site] = false;
+ else
+ sitesRemoved[site] = true;
+ pd.repaint();
+
+ startSite = -1;
+ }
+ }
+ }
+
+ public boolean[] getRemovedSites() {
+ return sitesRemoved;
+ }
+
+ Color getColor(char x) {
+ if(ProAlign.isDna) {
+ if (x == 'a' || x == 'A')
+ return Color.red;
+ if (x == 'c' || x == 'C')
+ return Color.blue;
+ if (x == 'g' || x == 'G')
+ return Color.green;
+ if (x == 't' || x == 'T' || x == 'u' || x == 'U')
+ return brown;
+ else
+ return Color.gray;
+ } else {
+ if (x == 'g' || x == 'G' || x == 'a' || x == 'A' || x == 't' || x == 'T')
+ return purple;
+ if (x == 'p' || x == 'P' || x == 's' || x == 'S')
+ return purple;
+ if (x == 'l' || x == 'L' || x == 'i' || x == 'I')
+ return Color.green;
+ if (x == 'v' || x == 'V' || x == 'm' || x == 'M')
+ return Color.green;
+ if (x == 'k' || x == 'K' || x == 'r' || x == 'R' || x == 'h' || x == 'H')
+ return lblue;
+ if (x == 'f' || x == 'F' || x == 'w' || x == 'W' || x == 'y' || x == 'Y')
+ return Color.blue;
+ if (x == 'e' || x == 'E' || x == 'q' || x == 'Q')
+ return Color.black;
+ if (x == 'd' || x == 'D' || x == 'n' || x == 'N')
+ return Color.black;
+ if (x == 'c' || x == 'C')
+ return Color.red;
+ else
+ return Color.gray;
+ }
+ }
+
+ Color getProbColor(double x) {
+ x = Math.exp(x);
+
+ if(x<=0d) {
+ return Color.white;
+ } else if(x>0d && x<=0.1d) {
+ return new Color(255,0,0);
+ } else if(x>0.1d && x<=0.2d) {
+ return new Color(255,26,0);
+ } else if(x>0.2d && x<=0.3d) {
+ return new Color(255,51,0);
+ } else if(x>0.3d && x<=0.4d) {
+ return new Color(255,78,0);
+ } else if(x>0.4d && x<=0.5d) {
+ return new Color(255,102,0);
+ } else if(x>0.5d && x<=0.6d) {
+ return new Color(255,128,0);
+ } else if(x>0.6d && x<=0.7d) {
+ return new Color(255,153,0);
+ } else if(x>0.7d && x<=0.8d) {
+ return new Color(255,179,0);
+ } else if(x>0.8d && x<=0.9d) {
+ return new Color(255,204,0);
+ } else if(x>0.9d) {
+ return new Color(255,230,0);
+ } else {
+ return Color.gray;
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PrintMinimumCurve.java b/PrintMinimumCurve.java
new file mode 100644
index 0000000..0664666
--- /dev/null
+++ b/PrintMinimumCurve.java
@@ -0,0 +1,73 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JPanel;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+// Print a curve on a JPanel.
+//
+public class PrintMinimumCurve extends JPanel {
+
+ double[] minProb;
+ String[] nodes;
+ int height = 100;
+ int xScale = 2; // scale: pixels per column.
+ PrintMinimumCurve pc;
+ MinimumProbWindow qw;
+
+ PrintMinimumCurve(MinimumProbWindow qw, double[] minProb, String[] nodes) {
+ pc = this;
+ this.qw = qw;
+ this.minProb = minProb;
+ this.nodes = nodes;
+
+ setBackground(Color.white);
+ setForeground(Color.black);
+
+ setPreferredSize(new Dimension(xScale*minProb.length, height));
+ addMouseListener(new MiceListener());
+ }
+
+ public void paintComponent(Graphics g) {
+ Graphics2D g2 = (Graphics2D) g;
+ super.paintComponent(g2); //clears the background
+ height = pc.qw.getVisibleHeight();
+ pc.setPreferredSize(new Dimension(xScale*minProb.length, height));
+ for(int i=0; i<minProb.length-1; i++) {
+ int y1 = (int) (Math.exp(minProb[i])*height);
+ int y2 = (int) (Math.exp(minProb[i+1])*height);
+ if(y1>0 && y2>0) {
+ g2.drawLine(i*xScale,height-y1,(i+1)*xScale,height-y2);
+ }
+ }
+ }
+
+ // Listens mouse click: focus alignment, update messageText.
+ //
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ qw.rw.focusAlignment(x/xScale);
+ qw.rw.messageText.setText(" Minimum posterior probability "+
+ (""+Math.exp(minProb[x/xScale])+" ").substring(0,5)+
+ " at "+nodes[x/xScale]+".");
+ }
+ }
+}
+
diff --git a/PrintNames.java b/PrintNames.java
new file mode 100644
index 0000000..53ee414
--- /dev/null
+++ b/PrintNames.java
@@ -0,0 +1,250 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.RenderingHints;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+
+// Prints taxa names, holds the info of sequences to remove.
+//
+public class PrintNames extends JPanel {
+
+ final Color bg = Color.white;
+ final Color fg = Color.black;
+ final Color blue = new Color(205,205,255);
+
+ int verticalCharSpace;
+ int horizontalCharSpace = 1;
+
+ Font printFont;
+ FontMetrics currentMetrics;
+
+ int columnWidth, rowHeight;
+ int totalWidth, totalHeight;
+ int charWidth, charHeight;
+
+ int startSite = -1;
+
+ boolean isNamesGiven = false;
+
+ boolean[] taxaRemoved = new boolean[0];
+
+ String textArray[];
+
+ PrintNames pn;
+ JScrollPane sPane = null;
+
+ public PrintNames() {
+
+ setBackground(bg);
+ setForeground(fg);
+
+ }
+
+ public PrintNames(String[] textArray, boolean isAligned) {
+
+ pn = this;
+ this.textArray = textArray;
+
+ verticalCharSpace = ResultWindow.verticalCharSpace;
+
+ isNamesGiven = true;
+
+ taxaRemoved = new boolean[textArray.length];
+
+ this.setParameters();
+
+ totalWidth = textArray[0].length()*columnWidth+horizontalCharSpace;
+ totalHeight = textArray.length*rowHeight+verticalCharSpace;
+ setPreferredSize(new Dimension(totalWidth,totalHeight));
+
+ if(isAligned) {
+ addMouseListener(new MiceListener());
+ }
+
+ }
+
+ void setParameters() {
+
+ printFont = new Font("monospaced", Font.PLAIN, ResultWindow.rwFontSize);
+
+ setBackground(bg);
+ setForeground(fg);
+
+ currentMetrics = pn.getFontMetrics(printFont);
+ charWidth = currentMetrics.charWidth(' ');
+ charHeight = currentMetrics.getHeight();
+
+ columnWidth = charWidth + horizontalCharSpace;
+ rowHeight = charHeight + verticalCharSpace;
+
+ }
+
+ public void paint(Graphics g) {
+
+ if(isNamesGiven) {
+
+ if(printFont.getSize()!=ResultWindow.rwFontSize ||
+ verticalCharSpace!=ResultWindow.verticalCharSpace){
+
+ printFont = new Font("monospaced", Font.BOLD, ResultWindow.rwFontSize);
+ verticalCharSpace=ResultWindow.verticalCharSpace;
+
+ this.setParameters();
+ }
+
+ totalWidth = Math.max(textArray[0].length()*columnWidth+
+ horizontalCharSpace,sPane.getWidth());
+ totalHeight = Math.max(textArray.length*rowHeight+
+ verticalCharSpace,sPane.getHeight());
+ setPreferredSize(new Dimension(totalWidth,totalHeight));
+
+ int startX = sPane.getHorizontalScrollBar().getValue();
+ int endX = startX + sPane.getWidth();
+ int startY = sPane.getVerticalScrollBar().getValue();
+ int endY = startY + sPane.getHeight();
+
+ int startColumn = (int) (startX/columnWidth);
+ int endColumn = Math.min((int)(endX/columnWidth)+1,textArray[0].length());
+ int startRow = (int) (startY/rowHeight);
+ int endRow = Math.min((int)(endY/rowHeight)+1,textArray.length);
+
+ int charX = startColumn*columnWidth;
+ int charY = rowHeight+startRow*rowHeight;
+
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setColor(bg);
+ g2.setFont(printFont);
+ g2.fillRect(Math.max(startX-10,0),Math.max(startY-10,0),
+ Math.min(endX+10,totalWidth),
+ Math.min(endY+10,totalHeight));
+
+ for (int i = startRow; i < endRow; i++) {
+ String str = textArray[i];
+ for (int j = startColumn; j < endColumn; j++) {
+ // Do only once...
+ if (j == startColumn) {
+ if (i < taxaRemoved.length) {
+ if (taxaRemoved[i]) {
+ g2.setColor(blue);
+ g2.fillRect(0,(charY-rowHeight+3),totalWidth,charY+3);
+ } else {
+ g2.setColor(bg);
+ g2.fillRect(0,(charY-rowHeight+3),totalWidth,charY+3);
+ }
+ g2.setColor(fg);
+ }
+ }
+ // ..until here.
+ g2.drawString(""+str.charAt(j), charX, charY);
+ charX += columnWidth;
+ }
+ charX = startColumn * columnWidth ;
+ charY += rowHeight;
+ }
+ }
+ }
+
+ // Click on a name excludes/includes the taxon.
+ //
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ if(e.isShiftDown()) {
+ pn.updateTaxonList(x,y,true);
+ } else {
+ pn.updateTaxonList(x,y,false);
+ }
+ }
+ }
+
+ // Taxa list kept up-to-date.
+ //
+ void updateTaxonList(int x, int y, boolean shiftDown) {
+
+ if(shiftDown) {
+ if(startSite > 0) {
+ int site = (int) y/rowHeight;
+ int start, end;
+ if(startSite>site) {
+ start = site;
+ end = startSite;
+ } else {
+ start = startSite+1;
+ end = site+1;
+ }
+ end = Math.min(end,taxaRemoved.length);
+ for(int sx=start; sx<end; sx++) {
+ if (taxaRemoved[sx])
+ taxaRemoved[sx] = false;
+ else
+ taxaRemoved[sx] = true;
+ }
+ pn.repaint();
+
+ startSite = -1;
+ } else {
+ int site = (int) y/rowHeight;
+
+ if (taxaRemoved[site])
+ taxaRemoved[site] = false;
+ else
+ taxaRemoved[site] = true;
+ pn.repaint();
+
+ startSite = site;
+ }
+
+
+ } else {
+ int taxon = (int) y/rowHeight;
+
+ taxon = Math.min(taxon,taxaRemoved.length-1);
+ if (taxaRemoved[taxon])
+ taxaRemoved[taxon] = false;
+ else
+ taxaRemoved[taxon] = true;
+ pn.repaint();
+
+ startSite = -1;
+ }
+ }
+
+ public boolean[] getRemovedTaxa() {
+ return taxaRemoved;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PrintTree.java b/PrintTree.java
new file mode 100644
index 0000000..ca62d5f
--- /dev/null
+++ b/PrintTree.java
@@ -0,0 +1,194 @@
+/**
+ * Title: ProAlign<p>
+ * Description: sequence alignment comparison program<p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JPanel;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Dimension;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+// Print a tree on a JPanel.
+//
+public class PrintTree extends JPanel {
+
+ int xBase, yBase, xMove, yMax, xMax, rowHeight;
+ int cs = 3; // circleSize
+ static int numOpenWindows = 0;
+
+ boolean isTreeGiven = false;
+
+ AlignmentNode root;
+ ResultWindow rw;
+ PrintTree pt;
+ QualityWindow currentQw;
+
+ PrintTree() {
+
+ setBackground(Color.white);
+ setForeground(Color.black);
+
+ }
+
+ PrintTree(AlignmentNode root, ResultWindow rw, boolean isAligned) {
+
+ this.root = root;
+ this.rw = rw;
+ pt = this;
+
+ isTreeGiven = true;
+
+ this.setParameters();
+
+ setPreferredSize(new Dimension(rw.splitWidth, yMax));
+
+
+ if(isAligned) {
+ addMouseListener(new MiceListener());
+ }
+
+ }
+
+ void setParameters() {
+
+ setBackground(Color.white);
+ setForeground(Color.black);
+
+ rowHeight = rw.seqname.rowHeight;
+ yMax = 4+root.getNumChild()*rowHeight;
+ xMax = rw.splitWidth-10;
+ yBase = 2+root.child[0].getNumChild()*rowHeight;
+ xBase = 5;
+ xMove = xMax/(root.getTreeDepth());
+
+ }
+
+ public void paintComponent(Graphics g) {
+
+ Graphics2D g2 = (Graphics2D) g;
+ super.paintComponent(g2); //clears the background
+
+ if(isTreeGiven) {
+
+ if(rowHeight!=rw.seqname.rowHeight) {
+ this.setParameters();
+ }
+
+ setPreferredSize(new Dimension(rw.sPane1.getWidth(), yMax));
+ xMax = rw.sPane1.getWidth()-10;
+ xMove = xMax/(root.getTreeDepth());
+
+ paintBranch(g2,root,yBase,xBase);
+ g2.drawLine(xBase-2,yBase,xBase,yBase);
+ }
+ }
+
+ // Called from 'paintComponent'. Calls recursively itself.
+ //
+ public void paintBranch(Graphics2D g2, AlignmentNode node, int y, int x) {
+
+ int nc0 = 0; int nc1 = 0; // number of child nodes
+ if(node.child[0].getNumChild() > 1) {
+ nc0 = node.child[0].child[1].getNumChild();
+ }
+ if(node.child[1].getNumChild()> 1) {
+ nc1 = node.child[1].child[0].getNumChild();
+ }
+
+ g2.fillOval(x-cs,y-cs,cs*2,cs*2);
+ node.setTreeXY(x,y);
+ g2.drawString(""+node.nodeNumber,x+cs*2,y+4);
+
+ if(nc0>0) {
+ g2.drawLine(x,y,x,y-nc0*rowHeight);
+ g2.drawLine(x,y-nc0*rowHeight,x+xMove,y-nc0*rowHeight);
+ paintBranch(g2,node.child[0],y-nc0*rowHeight,x+xMove);
+ } else {
+ g2.drawLine(x,y,x,y-rowHeight/2);
+ g2.drawLine(x,y-rowHeight/2,xMax,y-rowHeight/2);
+ }
+ if(nc1>0) {
+ g2.drawLine(x,y,x,y+nc1*rowHeight);
+ g2.drawLine(x,y+nc1*rowHeight,x+xMove,y+nc1*rowHeight);
+ paintBranch(g2,node.child[1],y+nc1*rowHeight,x+xMove);
+ } else {
+ g2.drawLine(x,y,x,y+rowHeight/2);
+ g2.drawLine(x,y+rowHeight/2,xMax,y+rowHeight/2);
+ }
+ }
+
+ // A click on a node opens an alignment quality window.
+ //
+ public void openQualityWindow(String name, boolean newWindow) {
+
+ // ifShiftDown, open a new window.
+ //
+ if(!newWindow) {
+ if(numOpenWindows==0) {
+ QualityWindow qw = new QualityWindow(root, name,rw);
+ qw.setSize(600,100);
+ qw.setLocation(200,300);
+ qw.setTitle("Posterior probability of "+name);
+ qw.setVisible(true);
+ currentQw = qw;
+ numOpenWindows++;
+ } else {
+ currentQw.upDateData(root, name);
+ currentQw.setTitle("Posterior probability of "+name);
+ }
+ } else {
+ QualityWindow qw = new QualityWindow(root, name,rw);
+ qw.setSize(600,100);
+ qw.setLocation(220,320);
+ qw.setTitle("Posterior probability of "+name);
+ qw.setVisible(true);
+ currentQw = qw;
+ numOpenWindows++;
+ }
+ }
+
+
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ String name = root.getNodeNameAtXY(x,y);
+ if(!name.equals("")) {
+ AlignmentNode node = root.getNodeNamed(name);
+ if(node.name.equals(name)) {
+ if(e.isShiftDown()) {
+ pt.openQualityWindow(name,true);
+ } else {
+ pt.openQualityWindow(name,false);
+ }
+ }
+ rw.messageText.setText(" viterbi:"+node.viterbiEnd+
+ "; forward: "+node.forwardEnd);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ProAlign.java b/ProAlign.java
new file mode 100644
index 0000000..1eab7d1
--- /dev/null
+++ b/ProAlign.java
@@ -0,0 +1,231 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.LookAndFeel;
+import javax.swing.UIManager;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.io.File;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * The main class of ProAlign, the probabilistic alignment program.
+ */
+public class ProAlign {
+
+ public static double modelDelta = 0.1d; // HMM
+ public static double modelEpsilon = 0.75d; // HMM
+
+ public static double distScale = 1d; // distance scale factor
+
+ public static double gapFreq = 0.05d; // prot model gap freq
+ public static double gapProb = 0.001d; // prot model gap subst prob
+
+ public int pwDnaOpen = 1500; // pw alignment
+ public int pwDnaExt = 700; // pw alignment
+
+ public int pwProtOpen = 1000; // pw alignment
+ public int pwProtExt = 100; // pw alignment
+ public String pwProtMatrix = "pam120"; // pw alignment
+
+ public String treefile = new String();
+ public String seqfile;
+ public String outfile = new String("proalign.out");
+
+ public boolean nogui = false;
+ public boolean doTree = false;
+ boolean isAligned = false;
+
+ public int outformat = 2;
+ int nodeNumber = -1;
+ int defBandWidth;
+ int defOffset;
+
+ HashMap seqs;
+
+ public static boolean isDna = true;
+ static boolean isResultWindow = false;
+ public static boolean trackBest = true; // traceback best
+ static boolean DEBUG = true; // write log
+ public static boolean removeTrailing = true;
+ public static boolean penalizeTerminal = true;
+ public static boolean correctMultiple = true;
+ public static boolean writeMin = true;
+ public static boolean writeMean = false;
+ public static boolean writeAll = false;
+ public static boolean writeRoot = false;
+ public static boolean estimateGapFreq = false;
+ public static boolean estimateGapProb = false;
+ public static boolean estimateDelta = false;
+ public static boolean estimateEpsilon = false;
+
+ public static boolean exitInError = true;
+ public static boolean estimateParameters = false;
+
+ public static int bandWidth = 101; // diagonal alignment band width
+ public static int offset = 15;
+
+ static String fileExt = new String("paa"); // PA-file extension
+ static String version = "0.5 alpha 0";
+
+ public static String protModel = "wag";
+
+ static int paFontSize = 11;
+ static String paFontName = "sansserif";
+
+ static String clustalwPath;
+ static String folderPath;
+ static String tempFolder;
+
+ static int wWidth = 800; // window size
+ static int wHeight = 300;
+
+ static OutFile log;
+
+ public SubstitutionModel sm;
+ AlignmentNode root;
+ ResultWindow rw;
+
+ public ProAlign() {
+// System.out.println("ProAlign");
+ }
+
+ public ProAlign(String[] args){
+
+ defBandWidth = bandWidth;
+ defOffset = offset;
+
+ startNewLog("proalign.log");
+ setUserData();
+
+ if(args.length>0) {
+ ReadArguments ra = new ReadArguments(ProAlign.this, args);
+ }
+
+ sm = new SubstitutionModel(ProAlign.this);
+ if(ProAlign.isDna){
+ sm.jcDnaModel();
+ } else {
+ if(ProAlign.protModel.equals("dayhoff")) {
+ sm.dayhoffProteinModel();
+ } else if(ProAlign.protModel.equals("jtt")) {
+ sm.jttProteinModel();
+ } else {
+ sm.wagProteinModel();
+ }
+ }
+
+ if(nogui) {
+ try {
+ RunCommandLine rcl = new RunCommandLine(ProAlign.this);
+ } catch(Exception e) { }
+ } else {
+
+ rw = new ResultWindow(ProAlign.this);
+ rw.setSize(wWidth,wHeight);
+ isResultWindow = true;
+ rw.setVisible(true);
+
+ }
+ }
+
+ /**
+ * Keeps count on the new nodes that are created. Gives a unique number.
+ */
+ int getNodeNumber() {
+ nodeNumber++;
+ return nodeNumber;
+ }
+
+
+ /**
+ * Resets the counter.
+ */
+ void setNodeNumber(int i) {
+ nodeNumber = i;
+ }
+
+
+ /**
+ * Keep log.
+ */
+ public void startNewLog(String file) {
+
+ try {
+ log = new OutFile(file);
+ } catch(Exception e) { }
+
+ String date = Calendar.getInstance().getTime().toString();
+ log.println("\n------------------------------------");
+ log.println("ProAlign - starting a new event log.");
+ log.println(" "+date);
+ log.println("------------------------------------\n");
+ log.flush();
+ }
+
+
+ /**
+ * Get userdata from file
+ */
+ void setUserData() {
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ try {
+ if(new File(userdata[0]).isDirectory())
+ folderPath = new File(userdata[0]).getAbsolutePath();
+ } catch (Exception e) {
+ folderPath = new String(".");
+ }
+ try {
+ if(new File(userdata[1]).isFile())
+ clustalwPath = new File(userdata[1]).getAbsolutePath();
+ } catch (Exception e) {
+ clustalwPath = new String("clustalw");
+ }
+ try {
+ if(new File(userdata[2]).isDirectory())
+ folderPath = new File(userdata[0]).getAbsolutePath();
+ } catch (Exception e) {
+ if(System.getProperty("os.name").startsWith("Windows")){
+ tempFolder = "C:\\TEMP";
+ } else {
+ tempFolder = "/tmp";
+ }
+ }
+ }
+
+ static void log(String txt) {
+ if(DEBUG) {
+ log.println(txt);
+ log.flush();
+ }
+ }
+
+ /**
+ * Main class. Takes command line arguments to run with scripts.
+ */
+ public static void main(String[] args) {
+
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Exception e) { }
+
+ ProAlign pa = new ProAlign(args);
+ }
+}
+
+
+
+
+
diff --git a/PwAlignment.java b/PwAlignment.java
new file mode 100644
index 0000000..b3e48c5
--- /dev/null
+++ b/PwAlignment.java
@@ -0,0 +1,345 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class PwAlignment {
+
+ int len1,len2;
+ int[][] matM,matX,matY,pointM,pointX,pointY;
+ String[] rev = new String[2];
+ String seq1, seq2;
+
+ int[][] subst;
+ int gOpen;
+ int gExt;
+ String alphabet;
+ boolean isDna;
+
+ PwAlignment(int[][] substTable, int gapOpen, int gapExt, String alpha, boolean isD) {
+
+ ProAlign.log("PwAlignment");
+
+ subst = substTable;
+ gOpen = gapOpen;
+ gExt = gapExt;
+ alphabet = alpha;
+ isDna = isD;
+
+ }
+
+ String[] revAligned(String s1, String s2) {
+
+ ProAlign.log("PwAlignment");
+
+ len1 = s1.length();
+ len2 = s2.length();
+ seq1 = " "+s1;
+ seq2 = " "+s2;
+
+ initializeMatrices();
+
+ pwAlignment();
+
+ return rev;
+ }
+
+ double align(String s1, String s2) {
+
+ len1 = s1.length();
+ len2 = s2.length();
+ seq1 = " "+s1;
+ seq2 = " "+s2;
+
+ initializeMatrices();
+
+ pwAlignment();
+
+
+ // Look for terminal gaps
+ //
+ int first = 0; int last = 0;
+ for(int i=0; i<rev[0].length(); i++) {
+ if(rev[0].charAt(i)=='-' || rev[1].charAt(i)=='-') {
+ continue;
+ } else {
+ first = i;
+ break;
+ }
+ }
+ for(int i=rev[0].length()-1; i>=0; i--) {
+ if(rev[0].charAt(i)=='-' || rev[1].charAt(i)=='-') {
+ continue;
+ } else {
+ last = i;
+ break;
+ }
+ }
+
+ // Count identities
+ //
+ int all = 0;
+ int same = 0;
+ for(int i=first; i<=last; i++) {
+ if(rev[0].charAt(i)==rev[1].charAt(i)) {
+ same++;
+ }
+ all++;
+ }
+
+ // Print the alignment & path
+ //
+ boolean printAlignment = false;
+ if(printAlignment) {
+ for(int i=rev[0].length()-1; i>=0; i--) {
+ System.out.print(rev[0].charAt(i));
+ }
+ System.out.println();
+ for(int i=rev[1].length()-1; i>=0; i--) {
+ System.out.print(rev[1].charAt(i));
+ }
+ System.out.println();
+ System.out.println("same "+same+", all "+all);
+ }
+
+ // Return the distance
+ //
+ if(isDna) {
+ double p = 1d-(double)same/(double)all;
+ double jcK;
+ if(p>0.75d) {
+ jcK=5d;
+ } else if(ProAlign.correctMultiple) {
+ jcK = -0.75d*Math.log(1d-4d/3d*p);
+ } else {
+ jcK = p;
+ }
+ if(jcK>5d) {
+ jcK=5d;
+ }
+ return jcK;
+ } else {
+ double p = 1d-(double)same/(double)all;
+ double kD;
+ if(p>0.85d) {
+ kD=5d;
+ } else if(ProAlign.correctMultiple) {
+ kD = -1d*Math.log(1-p-0.2d*p*p);
+ } else {
+ kD = p;
+ }
+ if(kD>5d) {
+ kD=5d;
+ }
+ return kD;
+ }
+ }
+
+ int[] trailing(String s1, String s2) {
+
+ len1 = s1.length();
+ len2 = s2.length();
+ seq1 = " "+s1;
+ seq2 = " "+s2;
+
+ initializeMatrices();
+
+ pwAlignment();
+
+ // Look for terminal gaps
+ //
+ int[] trail = new int[2];
+ int c1=0,c2=0;
+
+ for(int i=0; i<rev[0].length(); i++) {
+ if(rev[0].charAt(i)!='-') {
+ c1++;
+ }
+ if(rev[1].charAt(i)!='-') {
+ c2++;
+ }
+
+ if(rev[0].charAt(i)=='-' || rev[1].charAt(i)=='-') {
+ continue;
+ } else {
+ trail[1] = c1-c2;
+ break;
+ }
+ }
+ c1=0;
+ c2=0;
+ for(int i=rev[0].length()-1; i>=0; i--) {
+ if(rev[0].charAt(i)!='-') {
+ c1++;
+ }
+ if(rev[1].charAt(i)!='-') {
+ c2++;
+ }
+ if(rev[0].charAt(i)=='-' || rev[1].charAt(i)=='-') {
+ continue;
+ } else {
+ trail[0] = c1-c2;
+ break;
+ }
+ }
+
+ return trail;
+ }
+
+ void pwAlignment() {
+
+ // Fill the alignment tables
+ //
+ for(int i=0; i<=len1; i++) {
+ for(int j=0; j<=len2; j++) {
+
+ if(i==0 && j==0 ) {
+ continue;
+ }
+
+ if(i>0 && j>0) {
+ int match = subst[alphabet.indexOf(seq1.charAt(i))][alphabet.indexOf(seq2.charAt(j))];
+ if(matM[i-1][j-1] >= matX[i-1][j-1] && matM[i-1][j-1] >= matY[i-1][j-1]) {
+ matM[i][j] = matM[i-1][j-1]+match;
+ pointM[i][j] = 0;
+ } else if(matX[i-1][j-1] >= matY[i-1][j-1]) {
+ matM[i][j] = matX[i-1][j-1]+match;
+ pointM[i][j] = 1;
+ } else {
+ matM[i][j] = matY[i-1][j-1]+match;
+ pointM[i][j] = 2;
+ }
+ }
+
+ if(j==0 && i>0 && !ProAlign.penalizeTerminal) {
+ matX[i][j] = matX[i-1][j];
+ pointX[i][j] = 1;
+ } else if(j==len2 && i>0 && !ProAlign.penalizeTerminal) {
+ if(matM[i-1][j] >= matX[i-1][j]) {
+ matX[i][j] = matM[i-1][j];
+ pointX[i][j] = 0;
+ } else {
+ matX[i][j] = matX[i-1][j];
+ pointX[i][j] = 1;
+ }
+ } else if(i>0) {
+ if(matM[i-1][j]+gOpen >= matX[i-1][j]+gExt) {
+ matX[i][j] = matM[i-1][j]+gOpen;
+ pointX[i][j] = 0;
+ } else {
+ matX[i][j] = matX[i-1][j]+gExt;
+ pointX[i][j] = 1;
+ }
+ }
+
+ if(i==0 && j>0 && !ProAlign.penalizeTerminal) {
+ matY[i][j] = matY[i][j-1];
+ pointY[i][j] = 2;
+ } else if(i==len1 && j>0 && !ProAlign.penalizeTerminal) {
+ if(matM[i][j-1] >= matY[i][j-1]) {
+ matY[i][j] = matM[i][j-1];
+ pointY[i][j] = 0;
+ } else {
+ matY[i][j] = matY[i][j-1];
+ pointY[i][j] = 2;
+ }
+ } else if(j>0) {
+ if(matM[i][j-1]+gOpen >= matY[i][j-1]+gExt) {
+ matY[i][j] = matM[i][j-1]+gOpen;
+ pointY[i][j] = 0;
+ } else {
+ matY[i][j] = matY[i][j-1]+gExt;
+ pointY[i][j] = 2;
+ }
+ }
+ }
+ }
+
+
+ // Look for best end path & score
+ //
+ int end = 0; int point = 0;
+
+ if(matM[len1][len2] >= matX[len1][len2] && matM[len1][len2] >= matY[len1][len2]) {
+ end = matM[len1][len2];
+ point = 0;
+ } else if(matX[len1][len2] >= matY[len1][len2]) {
+ end = matX[len1][len2];
+ point = 1;
+ } else {
+ end = matY[len1][len2];
+ point = 2;
+ }
+
+ // Trace back the path
+ //
+ rev[0] = "";
+ rev[1] = "";
+
+ int i=len1; int j=len2;
+
+ while(i>0 || j>0) {
+
+ if(point==0) {
+ rev[0]+=seq1.charAt(i);
+ rev[1]+=seq2.charAt(j);
+ point = pointM[i][j];
+ i--;j--;
+ continue;
+
+ } else if(point==1) {
+ rev[0]+=seq1.charAt(i);
+ rev[1]+="-";
+ point = pointX[i][j];
+ i--;
+ continue;
+
+ } else if(point==2) {
+ rev[0]+="-";
+ rev[1]+=seq2.charAt(j);
+ point = pointY[i][j];
+ j--;
+ continue;
+
+ } else {
+ System.out.println("wrong pointer!");
+ break;
+ }
+ }
+ }
+
+
+ // Initialize matrices for score and pointers
+ //
+ void initializeMatrices() {
+
+ matM = new int[len1+1][len2+1];
+ matX = new int[len1+1][len2+1];
+ matY = new int[len1+1][len2+1];
+ pointM = new int[len1+1][len2+1];
+ pointX = new int[len1+1][len2+1];
+ pointY = new int[len1+1][len2+1];
+
+ int small = -100000;
+
+ for(int j=1; j<matM.length; j++) {
+ matM[j][0] = small;
+ matX[j][0] = small;
+ matY[j][0] = small;
+ }
+ for(int i=1; i<matM[0].length; i++) {
+ matM[0][i] = small;
+ matX[0][i] = small;
+ matY[0][i] = small;
+ }
+ }
+}
+
+
diff --git a/PwAlignmentLoop.java b/PwAlignmentLoop.java
new file mode 100644
index 0000000..36a89aa
--- /dev/null
+++ b/PwAlignmentLoop.java
@@ -0,0 +1,273 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+class PwAlignmentLoop extends Thread {
+
+
+ PwAlignment pa;
+ ResultWindow rw;
+ PwAlignmentLoop pal;
+
+ double[][] distance;
+ String[] names;
+ String tree;
+
+ PwAlignmentLoop(PwAlignment pa,HashMap seqs) {
+ this.pa = pa;
+
+ ProAlign.log("PwAlignmentLoop");
+
+ align(seqs);
+
+ if(ProAlign.DEBUG) {
+ for(int i=0; i<names.length; i++) {
+ ProAlign.log.print(names[i]+" ");
+ for(int j=0; j<names.length; j++) {
+ ProAlign.log.print((""+distance[i][j]+" ").substring(0,5)+" ");
+ }
+ ProAlign.log("");
+ }
+ }
+
+ NeighborJoining nj = new NeighborJoining(distance,names);
+
+ tree = nj.getTree();
+ ProAlign.log("PwAlignmentLoop unrooted tree:\n"+tree);
+
+ TreeNode tn = new TreeNode(tree);
+ tree = tn.findMiddlePoint();
+
+ }
+
+ PwAlignmentLoop(ResultWindow rw,PwAlignment pa) {
+ this.rw = rw;
+ this.pa = pa;
+ pal = this;
+
+ start();
+ }
+
+ public void run(){
+
+ ProAlign.log("PwAlignmentLoop");
+
+ if(rw.isAligned) {
+ pal.computeDistances();
+ } else {
+ pal.align(rw.seqs);
+ }
+
+ if(ProAlign.DEBUG) {
+ for(int i=0; i<names.length; i++) {
+ ProAlign.log.print(names[i]+" ");
+ for(int j=0; j<names.length; j++) {
+ ProAlign.log.print((""+distance[i][j]+" ").substring(0,5)+" ");
+ }
+ ProAlign.log("");
+ }
+ }
+
+ NeighborJoining nj = new NeighborJoining(distance,names);
+
+ tree = nj.getTree();
+ ProAlign.log("PwAlignmentLoop unrooted tree:\n"+tree);
+
+ TreeNode tn = new TreeNode(tree);
+ tree = tn.findMiddlePoint();
+
+ if(rw.isAligned) {
+ rw.removeGaps(tree);
+ } else {
+ rw.setRawDataAndTree(tree);
+ }
+ rw.setScrollPanes();
+
+ }
+
+ void computeDistances() {
+
+ names = rw.root.getTerminalNames();
+ String[] seqData = new String[rw.root.getNumChild()];
+
+ for(int i=0; i<seqData.length; i++) { seqData[i] = "";}
+ for(int i=0; i<rw.root.cellPath.length; i++) {
+
+ int h = 0;
+ char[] c0 = rw.root.child[0].getCharacterAt(rw.root.cellPath[i][0]-2);
+ char[] c1 = rw.root.child[1].getCharacterAt(rw.root.cellPath[i][1]-2);
+
+ for(int j=0; j<c0.length; j++) {
+ seqData[h] += c0[j];
+ h++;
+ }
+ for(int j=0; j<c1.length; j++) {
+ seqData[h] += c1[j];
+ h++;
+ }
+ }
+
+ int ns = names.length;
+ distance = new double[ns][ns];
+
+ for(int i=0; i<ns; i++) {
+ for(int j=i+1; j<ns; j++) {
+
+
+ // Remove terminal gaps
+ //
+ int k=0;
+ int first = 0; int last = 0;
+ for(k=0; k<seqData[i].length(); k++) {
+ if(seqData[i].charAt(k)=='-' || seqData[j].charAt(k)=='-') {
+ continue;
+ } else {
+ first = k;
+ break;
+ }
+ }
+ for(k=seqData[i].length()-1; k>=0; k--) {
+ if(seqData[i].charAt(k)=='-' || seqData[j].charAt(k)=='-') {
+ continue;
+ } else {
+ last = k;
+ break;
+ }
+ }
+
+
+ int all = 0;
+ int same = 0;
+ for(k=first; k<=last; k++) {
+ if(seqData[i].charAt(k)==seqData[j].charAt(k)) {
+ same++;
+ }
+ all++;
+ }
+
+ if(ProAlign.isDna) {
+ double p = 1d-(double)same/(double)all;
+ double jcK;
+ if(ProAlign.correctMultiple) {
+ jcK= -0.75d*Math.log(1d-4d/3d*p);
+ } else {
+ jcK = p;
+ }
+ if(jcK>5d) {
+ jcK=5d;
+ }
+
+ distance[i][j] = distance[j][i] = jcK;
+
+ } else {
+ double p = 1d-(double)same/(double)all;
+ double kD;
+ if(ProAlign.correctMultiple) {
+ kD = -1d*Math.log(1-p-0.2d*p*p);
+ } else {
+ kD = p;
+ }
+ if(kD>5d) {
+ kD=5d;
+ }
+ distance[i][j] = distance[j][i] = kD;
+
+ }
+ }
+ }
+ }
+
+ void align(HashMap seqs) {
+
+
+ Iterator seqKeys = seqs.keySet().iterator();
+ int ns = seqs.size();
+
+ names = new String[ns];
+ int h=0;
+ while(seqKeys.hasNext()) {
+ names[h++] = (String)seqKeys.next();
+ }
+
+ distance = new double[ns][ns];
+
+ for(int i=0; i<ns; i++) {
+ for(int j=i+1; j<ns; j++) {
+
+ if(ProAlign.isResultWindow) {
+ ResultWindow.updateInfo(" Computing distance matrix:"+
+ " aligning '"+names[i]+"' and '"+names[j]+"'.");
+ }
+ String seq1 = (String)seqs.get(names[i]);
+ String seq2 = (String)seqs.get(names[j]);
+ distance[i][j] = pa.align(seq1,seq2);
+ distance[j][i] = distance[i][j];
+ distance[i][i] = 0d;
+
+ }
+ }
+ }
+ double[][] getDistance() {
+ return distance;
+ }
+ String[] getNames() {
+ return names;
+ }
+
+ String getTree() {
+ return tree;
+ }
+
+/*
+ public static void main(String[] args) {
+
+ SequenceReader2 sr = new SequenceReader2();
+ boolean works = sr.fromFile(args[0]);
+ if(!works) {
+ System.exit(0);
+ }
+ HashMap seqs = sr.getSequences();
+
+ String alphabet;
+ int[][] subst;
+ int gOpen;
+ int gExt;
+ boolean isDna;
+
+ PwSubstitutionMatrix psm = new PwSubstitutionMatrix();
+ CheckSequence2 cs = new CheckSequence2();
+ if(cs.isDna(seqs)){
+ alphabet = psm.dnaAlphabet;
+ subst = psm.swdna;
+ gOpen = -15;
+ gExt = -7;
+ isDna = true;
+ } else {
+ alphabet = psm.protAlphabet;
+ subst = psm.pam60;
+ gOpen = -10;
+ gExt = -1;
+ isDna = false;
+ }
+
+ PwAlignment pa = new PwAlignment(subst,gOpen,gExt,alphabet,isDna);
+
+ PwAlignmentLoop pal = new PwAlignmentLoop(pa);
+ pal.align(seqs);
+
+ NeighborJoining nj = new NeighborJoining(pal.getDistance(),pal.getNames());
+ System.out.println(nj.getTree());
+ }
+*/
+}
diff --git a/PwSubstitutionMatrix.java b/PwSubstitutionMatrix.java
new file mode 100644
index 0000000..073951e
--- /dev/null
+++ b/PwSubstitutionMatrix.java
@@ -0,0 +1,143 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class PwSubstitutionMatrix {
+
+ PwSubstitutionMatrix() { }
+
+ String protAlphabet = "ABCDEFGHIKLMNPQRSTVWXYZ";
+ String dnaAlphabet = "ABCDGHKMNRSTUVWXY";
+
+ int[][] pam60 = {
+ {500,-200,-500,-200,-100,-600,0,-500,-300,-500,-400,-300,-200,0,-300,-500,100,100,-100,-1000,-200,-600,-200},
+ {-200,500,-900,500,200,-800,-200,0,-400,-100,-700,-600,500,-400,-100,-500,0,-200,-500,-800,-300,-500,100},
+ {-500,-900,900,-1000,-1000,-900,-700,-600,-400,-1000,-1100,-1000,-700,-600,-1000,-600,-100,-500,-400,-1200,-600,-200,-1000},
+ {-200,500,-1000,700,300,-1100,-200,-200,-500,-200,-900,-700,200,-500,-100,-600,-200,-300,-600,-1100,-300,-800,200},
+ {-100,200,-1000,300,700,-1000,-200,-300,-400,-300,-700,-500,0,-300,200,-600,-200,-400,-400,-1200,-300,-700,500},
+ {-600,-800,-900,-1100,-1000,800,-700,-400,-100,-1000,-100,-200,-600,-700,-900,-700,-500,-600,-500,-300,-500,300,-1000},
+ {0,-200,-700,-200,-200,-700,600,-600,-700,-500,-800,-600,-100,-400,-500,-700,0,-300,-400,-1100,-300,-1000,-300},
+ {-500,0,-600,-200,-300,-400,-600,800,-600,-400,-400,-700,100,-200,200,0,-400,-500,-500,-500,-300,-200,0},
+ {-300,-400,-400,-500,-400,-100,-700,-600,700,-400,0,100,-400,-600,-500,-400,-400,-100,300,-1000,-300,-400,-400},
+ {-500,-100,-1000,-200,-300,-1000,-500,-400,-400,600,-600,0,0,-400,-100,200,-200,-200,-600,-800,-300,-700,-200},
+ {-400,-700,-1100,-900,-700,-100,-800,-400,0,-600,600,200,-500,-500,-300,-600,-600,-500,-100,-400,-400,-500,-500},
+ {-300,-600,-1000,-700,-500,-200,-600,-700,100,0,200,1000,-600,-600,-200,-200,-400,-200,0,-900,-300,-700,-400},
+ {-200,500,-700,200,0,-600,-100,100,-400,0,-500,-600,600,-400,-200,-300,100,-100,-500,-600,-200,-300,-100},
+ {0,-400,-600,-500,-300,-700,-400,-200,-600,-400,-500,-600,-400,700,-100,-200,0,-200,-400,-1000,-300,-1000,-200},
+ {-300,-100,-1000,-100,200,-900,-500,200,-500,-100,-300,-200,-200,-100,700,0,-300,-400,-500,-900,-300,-800,600},
+ {-500,-500,-600,-600,-600,-700,-700,0,-400,200,-600,-200,-300,-200,0,800,-200,-400,-500,0,-400,-800,-200},
+ {100,0,-100,-200,-200,-500,0,-400,-400,-200,-600,-400,100,0,-300,-200,500,100,-400,-400,-200,-500,-300},
+ {100,-200,-500,-300,-400,-600,-300,-500,-100,-200,-500,-200,-100,-200,-400,-400,100,600,-100,-900,-200,-500,-400},
+ {-100,-500,-400,-600,-400,-500,-400,-500,300,-600,-100,0,-500,-400,-500,-500,-400,-100,600,-1100,-300,-500,-500},
+ {-1000,-800,-1200,-1100,-1200,-300,-1100,-500,-1000,-800,-400,-900,-600,-1000,-900,0,-400,-900,-1100,1300,-800,-300,-1100},
+ {-200,-300,-600,-300,-300,-500,-300,-300,-300,-300,-400,-300,-200,-300,-300,-400,-200,-200,-300,-800,-300,-500,-300},
+ {-600,-500,-200,-800,-700,300,-1000,-200,-400,-700,-500,-700,-300,-1000,-800,-800,-500,-500,-500,-300,-500,900,-700},
+ {-200,100,-1000,200,500,-1000,-300,0,-400,-200,-500,-400,-100,-200,600,-200,-300,-400,-500,-1100,-300,-700,500}
+ };
+
+ int[][] pam120 = {
+ {300,0,-300,0,0,-400,100,-300,-100,-200,-300,-200,-100,100,-100,-300,100,100,0,-700,-100,-400,-100},
+ {0,400,-600,400,300,-500,0,100,-300,0,-400,-400,300,-200,0,-200,0,0,-300,-600,-100,-300,200},
+ {-300,-600,900,-700,-700,-600,-400,-400,-300,-700,-700,-600,-500,-400,-700,-400,0,-300,-300,-800,-400,-100,-700},
+ {0,400,-700,500,300,-700,0,0,-300,-100,-500,-400,200,-300,100,-300,0,-100,-300,-800,-200,-500,300},
+ {0,300,-700,300,500,-700,-100,-100,-300,-100,-400,-300,100,-200,200,-300,-100,-200,-300,-800,-100,-500,400},
+ {-400,-500,-600,-700,-700,800,-500,-300,0,-700,0,-100,-400,-500,-600,-500,-300,-400,-300,-100,-300,400,-600},
+ {100,0,-400,0,-100,-500,500,-400,-400,-300,-500,-400,0,-200,-300,-400,100,-100,-200,-800,-200,-600,-200},
+ {-300,100,-400,0,-100,-300,-400,700,-400,-200,-300,-400,200,-100,300,100,-200,-300,-300,-300,-200,-100,100},
+ {-100,-300,-300,-300,-300,0,-400,-400,600,-300,100,100,-200,-300,-300,-200,-200,0,300,-600,-100,-200,-300},
+ {-200,0,-700,-100,-100,-700,-300,-200,-300,500,-400,0,100,-200,0,200,-100,-100,-400,-500,-200,-500,-100},
+ {-300,-400,-700,-500,-400,0,-500,-300,100,-400,500,300,-400,-300,-200,-400,-400,-300,100,-300,-200,-200,-300},
+ {-200,-400,-600,-400,-300,-100,-400,-400,100,0,300,800,-300,-300,-100,-100,-200,-100,100,-600,-200,-400,-200},
+ {-100,300,-500,200,100,-400,0,200,-200,100,-400,-300,400,-200,0,-100,100,0,-300,-400,-100,-200,0},
+ {100,-200,-400,-300,-200,-500,-200,-100,-300,-200,-300,-300,-200,600,0,-100,100,-100,-200,-700,-200,-600,-100},
+ {-100,0,-700,100,200,-600,-300,300,-300,0,-200,-100,0,0,600,100,-200,-200,-300,-600,-100,-500,400},
+ {-300,-200,-400,-300,-300,-500,-400,100,-200,200,-400,-100,-100,-100,100,600,-100,-200,-300,100,-200,-500,-100},
+ {100,0,0,0,-100,-300,100,-200,-200,-100,-400,-200,100,100,-200,-100,300,200,-200,-200,-100,-300,-100},
+ {100,0,-300,-100,-200,-400,-100,-300,0,-100,-300,-100,0,-100,-200,-200,200,400,0,-600,-100,-300,-200},
+ {0,-300,-300,-300,-300,-300,-200,-300,300,-400,100,100,-300,-200,-300,-300,-200,0,500,-800,-100,-300,-300},
+ {-700,-600,-800,-800,-800,-100,-800,-300,-600,-500,-300,-600,-400,-700,-600,100,-200,-600,-800,1200,-500,-200,-700},
+ {-100,-100,-400,-200,-100,-300,-200,-200,-100,-200,-200,-200,-100,-200,-100,-200,-100,-100,-100,-500,-200,-300,-100},
+ {-400,-300,-100,-500,-500,400,-600,-100,-200,-500,-200,-400,-200,-600,-500,-500,-300,-300,-300,-200,-300,800,-500},
+ {-100,200,-700,300,400,-600,-200,100,-300,-100,-300,-200,0,-100,400,-100,-100,-200,-300,-700,-100,-500,400}
+ };
+
+ int[][] pam160 = {
+ {200,0,-200,0,0,-300,100,-200,-100,-200,-200,-100,0,100,-100,-200,100,100,0,-500,0,-300,0},
+ {0,300,-400,300,200,-400,0,100,-200,0,-400,-300,200,-100,100,-100,0,0,-200,-500,-100,-300,200},
+ {-200,-400,900,-500,-500,-500,-300,-300,-200,-500,-600,-500,-400,-300,-500,-300,0,-200,-200,-700,-300,0,-500},
+ {0,300,-500,400,300,-600,0,0,-300,0,-400,-300,200,-200,100,-200,0,-100,-300,-600,-100,-400,200},
+ {0,200,-500,300,400,-500,0,0,-200,-100,-300,-200,100,-100,200,-200,0,-100,-200,-700,-100,-400,300},
+ {-300,-400,-500,-600,-500,700,-400,-200,0,-500,100,0,-300,-400,-500,-400,-300,-300,-200,-100,-300,500,-500},
+ {100,0,-300,0,0,-400,400,-300,-300,-200,-400,-300,0,-100,-200,-300,100,-100,-200,-700,-100,-500,-100},
+ {-200,100,-300,0,0,-200,-300,600,-300,-100,-200,-300,200,-100,200,100,-100,-200,-200,-300,-100,0,100},
+ {-100,-200,-200,-300,-200,0,-300,-300,500,-200,200,200,-200,-200,-200,-200,-200,0,300,-500,-100,-200,-200},
+ {-200,0,-500,0,-100,-500,-200,-100,-200,400,-300,0,100,-200,0,300,-100,0,-300,-400,-100,-400,0},
+ {-200,-400,-600,-400,-300,100,-400,-200,200,-300,500,300,-300,-300,-200,-300,-300,-200,100,-200,-200,-200,-300},
+ {-100,-300,-500,-300,-200,0,-300,-300,200,0,300,700,-200,-200,-100,-100,-200,-100,100,-400,-100,-300,-200},
+ {0,200,-400,200,100,-300,0,200,-200,100,-300,-200,300,-100,0,-100,100,0,-200,-400,0,-200,100},
+ {100,-100,-300,-200,-100,-400,-100,-100,-200,-200,-300,-200,-100,500,0,-100,100,0,-200,-500,-100,-500,-100},
+ {-100,100,-500,100,200,-500,-200,200,-200,0,-200,-100,0,0,500,100,-100,-100,-200,-500,-100,-400,300},
+ {-200,-100,-300,-200,-200,-400,-300,100,-200,300,-300,-100,-100,-100,100,600,-100,-100,-300,100,-100,-400,0},
+ {100,0,0,0,0,-300,100,-100,-200,-100,-300,-200,100,100,-100,-100,200,100,-100,-200,0,-300,-100},
+ {100,0,-200,-100,-100,-300,-100,-200,0,0,-200,-100,0,0,-100,-100,100,300,0,-500,0,-300,-100},
+ {0,-200,-200,-300,-200,-200,-200,-200,300,-300,100,100,-200,-200,-200,-300,-100,0,400,-600,-100,-300,-200},
+ {-500,-500,-700,-600,-700,-100,-700,-300,-500,-400,-200,-400,-400,-500,-500,100,-200,-500,-600,1200,-400,-100,-600},
+ {0,-100,-300,-100,-100,-300,-100,-100,-100,-100,-200,-100,0,-100,-100,-100,0,0,-100,-400,-100,-300,-100},
+ {-300,-300,0,-400,-400,500,-500,0,-200,-400,-200,-300,-200,-500,-400,-400,-300,-300,-300,-100,-300,800,-400},
+ {0,200,-500,200,300,-500,-100,100,-200,0,-300,-200,100,-100,300,0,-100,-100,-200,-600,-100,-400,300}
+ };
+
+ int[][] pam250 = {
+ {200,0,-200,0,0,-300,100,-100,-100,-100,-200,-100,0,100,0,-200,100,100,0,-600,0,-300,0},
+ {0,300,-400,300,300,-400,0,100,-200,100,-300,-200,200,-100,100,-100,0,0,-200,-500,-100,-300,200},
+ {-200,-400,1200,-500,-500,-400,-300,-300,-200,-500,-600,-500,-400,-300,-500,-400,0,-200,-200,-800,-300,0,-500},
+ {0,300,-500,400,300,-600,100,100,-200,0,-400,-300,200,-100,200,-100,0,0,-200,-700,-100,-400,300},
+ {0,300,-500,300,400,-500,0,100,-200,0,-300,-200,100,-100,200,-100,0,0,-200,-700,-100,-400,300},
+ {-300,-400,-400,-600,-500,900,-500,-200,100,-500,200,0,-300,-500,-500,-400,-300,-300,-100,0,-200,700,-500},
+ {100,0,-300,100,0,-500,500,-200,-300,-200,-400,-300,0,0,-100,-300,100,0,-100,-700,-100,-500,0},
+ {-100,100,-300,100,100,-200,-200,600,-200,0,-200,-200,200,0,300,200,-100,-100,-200,-300,-100,0,200},
+ {-100,-200,-200,-200,-200,100,-300,-200,500,-200,200,200,-200,-200,-200,-200,-100,0,400,-500,-100,-100,-200},
+ {-100,100,-500,0,0,-500,-200,0,-200,500,-300,0,100,-100,100,300,0,0,-200,-300,-100,-400,0},
+ {-200,-300,-600,-400,-300,200,-400,-200,200,-300,600,400,-300,-300,-200,-300,-300,-200,200,-200,-100,-100,-300},
+ {-100,-200,-500,-300,-200,0,-300,-200,200,0,400,600,-200,-200,-100,0,-200,-100,200,-400,-100,-200,-200},
+ {0,200,-400,200,100,-300,0,200,-200,100,-300,-200,200,0,100,0,100,0,-200,-400,0,-200,100},
+ {100,-100,-300,-100,-100,-500,0,0,-200,-100,-300,-200,0,600,0,0,100,0,-100,-600,-100,-500,0},
+ {0,100,-500,200,200,-500,-100,300,-200,100,-200,-100,100,0,400,100,-100,-100,-200,-500,-100,-400,300},
+ {-200,-100,-400,-100,-100,-400,-300,200,-200,300,-300,0,0,0,100,600,0,-100,-200,200,-100,-400,0},
+ {100,0,0,0,0,-300,100,-100,-100,0,-300,-200,100,100,-100,0,200,100,-100,-200,0,-300,0},
+ {100,0,-200,0,0,-300,0,-100,0,0,-200,-100,0,0,-100,-100,100,300,0,-500,0,-300,-100},
+ {0,-200,-200,-200,-200,-100,-100,-200,400,-200,200,200,-200,-100,-200,-200,-100,0,400,-600,-100,-200,-200},
+ {-600,-500,-800,-700,-700,0,-700,-300,-500,-300,-200,-400,-400,-600,-500,200,-200,-500,-600,1700,-400,0,-600},
+ {0,-100,-300,-100,-100,-200,-100,-100,-100,-100,-100,-100,0,-100,-100,-100,0,0,-100,-400,-100,-200,-100},
+ {-300,-300,0,-400,-400,700,-500,0,-100,-400,-100,-200,-200,-500,-400,-400,-300,-300,-200,0,-200,1000,-400},
+ {0,200,-500,300,300,-500,0,200,-200,0,-300,-200,100,0,300,0,0,-100,-200,-600,-100,-400,300}
+ };
+
+ int[][] swdna = {
+ {1000,-900,-900,1000,-900,1000,-900,1000,1000,1000,-900,-900,-900,1000,1000,1000,-900},
+ {-900,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {-900,1000,1000,-900,-900,1000,-900,1000,1000,-900,1000,-900,-900,1000,-900,1000,1000},
+ {1000,1000,-900,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {-900,1000,-900,1000,1000,-900,1000,-900,1000,1000,1000,-900,-900,1000,-900,1000,-900},
+ {1000,1000,1000,1000,-900,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {-900,1000,-900,1000,1000,1000,1000,-900,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {1000,1000,1000,1000,-900,1000,-900,1000,1000,1000,1000,-900,-900,1000,1000,1000,1000},
+ {1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {1000,1000,-900,1000,1000,1000,1000,1000,1000,1000,1000,-900,-900,1000,1000,1000,-900},
+ {-900,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,-900,-900,1000,-900,1000,1000},
+ {-900,1000,-900,1000,-900,1000,1000,-900,1000,-900,-900,1000,1000,-900,1000,1000,1000},
+ {-900,1000,-900,1000,-900,1000,1000,-900,1000,-900,-900,1000,1000,-900,1000,1000,1000},
+ {1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,-900,-900,1000,1000,1000,1000},
+ {1000,1000,-900,1000,-900,1000,1000,1000,1000,1000,-900,1000,1000,1000,1000,1000,1000},
+ {1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000,1000},
+ {-900,1000,1000,1000,-900,1000,1000,1000,1000,-900,1000,1000,1000,1000,1000,1000,1000}
+ };
+}
diff --git a/QualityWindow.java b/QualityWindow.java
new file mode 100644
index 0000000..445b540
--- /dev/null
+++ b/QualityWindow.java
@@ -0,0 +1,96 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JViewport;
+import javax.swing.JScrollPane;
+import javax.swing.JScrollBar;
+import javax.swing.BorderFactory;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+
+public class QualityWindow extends JFrame {
+
+ JScrollPane sPane;
+ int height;
+ double[] postProb;
+
+ PixelRule pixRule;
+ PrintCurve curve;
+ ResultWindow rw;
+ String name;
+
+ QualityWindow(AlignmentNode root, String name, ResultWindow rw) {
+
+ this.rw = rw;
+ this.name = name;
+
+ postProb = new double[root.cellPath.length];
+ for(int i=0; i<root.cellPath.length; i++) {
+ postProb[i] = root.getOnePostProbAt(i, name);
+ }
+ height = this.getHeight();
+
+ curve = new PrintCurve(QualityWindow.this, postProb);
+
+ // pixelruler.
+ pixRule = new PixelRule();
+ pixRule.setPreferredWidth((int) curve.getPreferredSize().getWidth());
+ pixRule.setIncrement(curve.xScale);
+ pixRule.setBackground(Color.white);
+
+
+ sPane = new JScrollPane(curve,
+ JScrollPane.VERTICAL_SCROLLBAR_NEVER,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+
+
+ sPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));
+ sPane.setColumnHeaderView(pixRule);
+ sPane.setBackground(Color.white);
+
+ Container cp = getContentPane();
+ cp.add(sPane);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e){
+ PrintTree.numOpenWindows--;
+ dispose();
+ }
+ });
+ }
+
+ int getVisibleHeight() {
+ return sPane.getViewport().getHeight();
+ }
+
+ void upDateData(AlignmentNode root, String name){
+ postProb = new double[root.cellPath.length];
+ for(int i=0; i<root.cellPath.length; i++) {
+ postProb[i] = root.getOnePostProbAt(i, name);
+ }
+ curve.upDateData(postProb);
+ }
+}
+
+
+
+
+
+
+
diff --git a/ReadArguments.java b/ReadArguments.java
new file mode 100644
index 0000000..a7ab0c1
--- /dev/null
+++ b/ReadArguments.java
@@ -0,0 +1,232 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+public class ReadArguments {
+
+ ReadArguments(ProAlign pa, String[] args) {
+
+ ProAlign.log("ReadArguments");
+
+ for(int i=0; i<args.length; i++) {
+
+ // sequence file
+ if(args[i].startsWith("-seqfile=")) {
+ pa.seqfile = args[i].substring(args[i].indexOf("=")+1);
+ ProAlign.log.println(" sequence file: "+pa.seqfile);
+
+ // guide tree file
+ } else if(args[i].startsWith("-treefile=")) {
+ pa.treefile = args[i].substring(args[i].indexOf("=")+1);
+ ProAlign.log.println(" tree file: "+pa.treefile);
+
+ // no GUI
+ } else if(args[i].startsWith("-nogui")) {
+ pa.nogui = true;
+ ProAlign.log.println(" no GUI: true");
+
+ // do tree
+ } else if(args[i].startsWith("-newtree")) {
+ pa.doTree = true;
+ ProAlign.log.println(" do tree: true");
+
+ // sample from post. probabilities
+ } else if(args[i].startsWith("-sample")) {
+ pa.trackBest = false;
+ ProAlign.log.println(" sample backtrace path: true");
+
+ // gap frequency
+ } else if(args[i].startsWith("-gapfreq=")) {
+ if(args[i].endsWith("=estimate")) {
+ pa.estimateGapFreq = true;
+ pa.estimateParameters = true ;
+ ProAlign.log.println(" gap frequency: estimate");
+ } else {
+ double tmp = new Double(
+ args[i].substring(args[i].indexOf("=")+1)).doubleValue();
+ if(tmp>0d && tmp<0.5d) {
+ pa.gapFreq = tmp;
+ ProAlign.log.println(" gap frequency: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: gap frequency "+tmp);
+ }
+ }
+
+ // gap probability
+ } else if(args[i].startsWith("-gapprob=")) {
+ if(args[i].endsWith("=estimate")) {
+ pa.estimateGapProb = true;
+ pa.estimateParameters = true ;
+ ProAlign.log.println(" gap probability: estimate");
+ } else {
+ double tmp = new Double(
+ args[i].substring(args[i].indexOf("=")+1)).doubleValue();
+ if(tmp>0d && tmp<0.5d) {
+ pa.gapProb = tmp;
+ ProAlign.log.println(" gap probability: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: gap probability "+tmp);
+ }
+ }
+
+ // delta for HMM model
+ } else if(args[i].startsWith("-delta=")) {
+ if(args[i].endsWith("=estimate")) {
+ pa.estimateDelta = true;
+ pa.estimateParameters = true ;
+ ProAlign.log.println(" HMM delta: estimate");
+ } else {
+ double tmp = new Double(
+ args[i].substring(args[i].indexOf("=")+1)).doubleValue();
+ if(tmp>0d && tmp<0.5d) {
+ pa.modelDelta = tmp;
+ ProAlign.log.println(" HMM delta: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: HMM delta "+tmp);
+ }
+ }
+
+ // epsilon for HMM model
+ } else if(args[i].startsWith("-epsilon=")) {
+ if(args[i].endsWith("=estimate")) {
+ pa.estimateEpsilon = true;
+ pa.estimateParameters = true ;
+ ProAlign.log.println(" HMM epsilon: estimate");
+ } else {
+ double tmp = new Double(
+ args[i].substring(args[i].indexOf("=")+1)).doubleValue();
+ if(tmp>0d && tmp<1.0d) {
+ pa.modelEpsilon = tmp;
+ ProAlign.log.println(" HMM epsilon: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: HMM epsilon "+tmp);
+ }
+ }
+
+ // band width
+ } else if(args[i].startsWith("-bwidth=")) {
+ int tmp = new Integer(
+ args[i].substring(args[i].indexOf("=")+1)).intValue();
+ if(tmp>5) {
+ pa.bandWidth = tmp;
+ ProAlign.log.println(" band width: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: band width "+tmp);
+ }
+
+ // distance scale
+ } else if(args[i].startsWith("-distscale=")) {
+ double tmp = new Double(
+ args[i].substring(args[i].indexOf("=")+1)).doubleValue();
+ if(tmp>0d && tmp<2.0d) {
+ pa.distScale = tmp;
+ ProAlign.log.println(" distance scale: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: distance scale "+tmp);
+ }
+ // multiple hits
+ } else if(args[i].startsWith("-nocorrection")) {
+ pa.correctMultiple = false ;
+ ProAlign.log.println(" correctMultiple: "+pa.correctMultiple);
+
+ // terminal gaps
+ } else if(args[i].startsWith("-penalize")) {
+ if(args[i].endsWith("=true")) {
+ pa.penalizeTerminal = true ;
+ } else if(args[i].endsWith("=false")) {
+ pa.penalizeTerminal = false ;
+ }
+ ProAlign.log.println(" penalizeTerminal: "+pa.penalizeTerminal);
+
+ // mean post prob.
+ } else if(args[i].startsWith("-writemean")) {
+ pa.writeMean = true ;
+ ProAlign.log.println(" output mean: "+pa.writeMean);
+
+ // all post prob.
+ } else if(args[i].startsWith("-writeall")) {
+ pa.writeAll = true ;
+ ProAlign.log.println(" output all: "+pa.writeAll);
+
+ // root characters
+ } else if(args[i].startsWith("-writeroot")) {
+ pa.writeRoot = true ;
+ ProAlign.log.println(" output root: "+pa.writeRoot);
+
+ // protein model
+ } else if(args[i].startsWith("-wag")) {
+ ProAlign.protModel = "wag";
+ ProAlign.isDna = false;
+ ProAlign.log.println(" protein model: "+ProAlign.protModel);
+
+ } else if(args[i].startsWith("-dayhoff")) {
+ ProAlign.protModel = "dayhoff";
+ ProAlign.isDna = false;
+ ProAlign.log.println(" protein model: "+ProAlign.protModel);
+
+ } else if(args[i].startsWith("-jtt")) {
+ ProAlign.protModel = "jtt";
+ ProAlign.isDna = false;
+ ProAlign.log.println(" protein model: "+ProAlign.protModel);
+
+ // trailing
+ } else if(args[i].startsWith("-notrailing")) {
+ pa.removeTrailing = false ;
+ ProAlign.log.println(" removeTrailing: "+pa.removeTrailing);
+
+
+ // allowed trailing
+ } else if(args[i].startsWith("-trailing=")) {
+ int tmp = new Integer(
+ args[i].substring(args[i].indexOf("=")+1)).intValue();
+ if(tmp>5 && tmp < pa.bandWidth/2) {
+ pa.offset = tmp;
+ ProAlign.log.println(" trailing: "+tmp);
+ } else {
+ ProAlign.log.println(" bad value: trailing "+tmp);
+ }
+
+ // output file
+ } else if(args[i].startsWith("-outfile=")) {
+ pa.outfile = args[i].substring(args[i].indexOf("=")+1);
+ ProAlign.log.println(" output file: "+pa.outfile);
+
+ // output format
+ } else if(args[i].startsWith("-outformat=")) {
+ if(args[i].substring(args[i].indexOf("=")+1).equalsIgnoreCase("fasta")){
+ pa.outformat = 2;
+ ProAlign.log.println(" outformat: PIR");
+ } else if(args[i].substring(args[i].indexOf("=")+1).equalsIgnoreCase("PIR")){
+ pa.outformat = 2;
+ ProAlign.log.println(" outformat: PIR");
+ } else if(args[i].substring(args[i].indexOf("=")+1).equalsIgnoreCase("nexus")){
+ pa.outformat = 1;
+ ProAlign.log.println(" outformat: nexus");
+ } else if(args[i].substring(args[i].indexOf("=")+1).equalsIgnoreCase("phylip")){
+ pa.outformat = 3;
+ ProAlign.log.println(" outformat: phylip");
+ } else if(args[i].substring(args[i].indexOf("=")+1).equalsIgnoreCase("msf")){
+ pa.outformat = 4;
+ ProAlign.log.println(" outformat: msf");
+ }
+
+ // stay quiet, no log
+ } else if(args[i].startsWith("-quiet")) {
+ pa.DEBUG = false;
+ ProAlign.log.println(" quiet...");
+ ProAlign.log.flush();
+ } else {
+ ProAlign.log.println("Unrecognized paramter: "+args[i]);
+ ProAlign.log.flush();
+ }
+ }
+ }
+}
diff --git a/ResultWindow.java b/ResultWindow.java
new file mode 100644
index 0000000..637699b
--- /dev/null
+++ b/ResultWindow.java
@@ -0,0 +1,1374 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextField;
+import javax.swing.JScrollBar;
+import javax.swing.BorderFactory;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JMenu;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.Graphics;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.beans.PropertyChangeEvent ;
+import java.beans.PropertyChangeListener;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.ArrayList;
+import java.io.File;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class ResultWindow extends JFrame {
+
+ JMenuBar mb = new JMenuBar();
+ JMenu
+ fm = new JMenu("File "),
+ dm = new JMenu("Import"),
+ em = new JMenu("Export"),
+ am = new JMenu("Align "),
+ tm = new JMenu("Font "),
+ tm1 = new JMenu("Font size"),
+ tm2 = new JMenu("Horizontal space"),
+ tm3 = new JMenu("Vertical space"),
+ pm = new JMenu("Result "),
+ lm = new JMenu("Filter sites");
+
+ JMenuItem[] file = {
+ new JMenuItem("About ProAlign"),
+ new JMenuItem("Open alignment"),
+ new JMenuItem("Save alignment"),
+ new JMenuItem("Save guide tree"),
+ new JMenuItem("Exit")
+ };
+ JMenuItem[] data = {
+ new JMenuItem("data"),
+ new JMenuItem("guide tree")
+ };
+ JMenuItem[] export = {
+ new JMenuItem("PIR"),
+ new JMenuItem("Phylip"),
+ new JMenuItem("MSF"),
+ new JMenuItem("Nexus")
+ };
+ JMenuItem align[] = {
+ new JMenuItem("Do ClustalW guide tree"),
+ new JMenuItem("Do ProAlign guide tree"),
+ new JMenuItem("Do multiple alignment"),
+ new JMenuItem("Sample alignments"),
+ new JMenuItem("Remove all gaps"),
+ new JMenuItem("Set parameters"),
+ };
+
+ JMenuItem proba[] = {
+ new JMenuItem("Plot min. probability"),
+ new JMenuItem("min 90%"),
+ new JMenuItem("min 80%"),
+ new JMenuItem("min 70%"),
+ new JMenuItem("min 60%"),
+ new JMenuItem("min 50%"),
+ new JMenuItem("min 40%"),
+ new JMenuItem("min 30%"),
+ new JMenuItem("min 20%"),
+ new JMenuItem("min 10%"),
+ new JMenuItem("0% (reset)"),
+ };
+
+ JMenuItem fom1[] = {
+ new JMenuItem("8"),
+ new JMenuItem("9"),
+ new JMenuItem("10"),
+ new JMenuItem("11"),
+ new JMenuItem("12"),
+ new JMenuItem("13"),
+ new JMenuItem("14")
+ };
+
+ JMenuItem fom2[] = {
+ new JMenuItem("2"),
+ new JMenuItem("3"),
+ new JMenuItem("4"),
+ new JMenuItem("5"),
+ new JMenuItem("6"),
+ new JMenuItem("7"),
+ new JMenuItem("8"),
+ new JMenuItem("9")
+ };
+
+ JMenuItem fom3[] = {
+ new JMenuItem("2"),
+ new JMenuItem("3"),
+ new JMenuItem("4"),
+ new JMenuItem("5"),
+ new JMenuItem("6"),
+ new JMenuItem("7"),
+ new JMenuItem("8"),
+ new JMenuItem("9")
+ };
+
+
+ JScrollPane sPane1;
+ JScrollPane sPane2;
+ JScrollPane sPane3;
+
+ JScrollBar sButt1;
+ JScrollBar sButt3;
+
+ // ScrollListener scro;
+
+ JSplitPane splitp1;
+ JSplitPane splitp2;
+
+ JTextField messageText;
+ Container cp;
+
+ Font font = new Font(ProAlign.paFontName,Font.PLAIN, ProAlign.paFontSize);
+ Font font1 = new Font("monospaced", Font.PLAIN, ProAlign.paFontSize);
+
+ PrintTree guidetree;
+ PrintNames seqname;
+ PrintData seqcont;
+
+ Rule charRule;
+ JPanel columnRule1;
+ JPanel columnRule2;
+
+ int splitWidth = 100;
+ boolean isAligned = false;
+ boolean hasData = false;
+ boolean hasTree = false;
+
+ String[] nodeNames;
+ double[][] postProb;
+
+ int wHeight;
+ int wWidth;
+ int maxLength;
+
+ static int verticalCharSpace = 5;
+ static int horizontalCharSpace = 5;
+ static int rwFontSize = 11;
+
+ HashMap seqs;
+
+ static ResultWindow rw;
+ AlignmentNode root;
+ ProAlign pa;
+
+ ResultWindow(ProAlign pa) {
+
+ rw = this;
+ this.pa = pa;
+ setTitle("ProAlign "+ProAlign.version);
+
+ // Create the JMenuBar - it's needed anyway.
+ //
+ FileMenuListener fle = new FileMenuListener();
+ AlignmentMenuListener alg = new AlignmentMenuListener();
+ ProbabilityMenuListener prb = new ProbabilityMenuListener();
+ FontMenuListener fon = new FontMenuListener();
+
+ file[0].setActionCommand("about");
+ file[0].addActionListener(fle);
+ file[0].setFont(font);
+ file[1].setActionCommand("open");
+ file[1].addActionListener(fle);
+ file[1].setFont(font);
+ file[2].setActionCommand("save");
+ file[2].addActionListener(fle);
+ file[2].setFont(font);
+ file[3].setActionCommand("savepag");
+ file[3].addActionListener(fle);
+ file[3].setFont(font);
+ file[4].setActionCommand("exit");
+ file[4].addActionListener(fle);
+ file[4].setFont(font);
+
+ data[0].setActionCommand("data");
+ data[0].addActionListener(fle);
+ data[0].setFont(font);
+ data[1].setActionCommand("tree");
+ data[1].addActionListener(fle);
+ data[1].setEnabled(false);
+ data[1].setFont(font);
+
+ export[0].setActionCommand("fasta");
+ export[0].addActionListener(fle);
+ export[0].setFont(font);
+ export[1].setActionCommand("phylip");
+ export[1].addActionListener(fle);
+ export[1].setFont(font);
+ export[2].setActionCommand("msf");
+ export[2].addActionListener(fle);
+ export[2].setFont(font);
+ export[3].setActionCommand("nexus");
+ export[3].addActionListener(fle);
+ export[3].setFont(font);
+
+ align[0].setActionCommand("guide");
+ align[0].addActionListener(alg);
+ align[0].setFont(font);
+ align[0].setEnabled(false);
+ align[1].setActionCommand("paguide");
+ align[1].addActionListener(alg);
+ align[1].setFont(font);
+ align[1].setEnabled(false);
+ align[2].setActionCommand("multiple");
+ align[2].addActionListener(alg);
+ align[2].setFont(font);
+ align[2].setEnabled(false);
+ align[3].setActionCommand("sample");
+ align[3].addActionListener(alg);
+ align[3].setFont(font);
+ align[3].setEnabled(false);
+ align[4].setActionCommand("remove");
+ align[4].addActionListener(alg);
+ align[4].setFont(font);
+ align[4].setEnabled(false);
+ align[5].setActionCommand("setting");
+ align[5].addActionListener(alg);
+ align[5].setFont(font);
+ align[5].setEnabled(true);
+
+ for(int i=0; i<proba.length; i++) {
+ proba[i].addActionListener(prb);
+ proba[i].setFont(font);
+ }
+ proba[0].setActionCommand("plot");
+ proba[0].setEnabled(false);
+ proba[1].setActionCommand("90percent");
+ proba[2].setActionCommand("80percent");
+ proba[3].setActionCommand("70percent");
+ proba[4].setActionCommand("60percent");
+ proba[5].setActionCommand("50percent");
+ proba[6].setActionCommand("40percent");
+ proba[7].setActionCommand("30percent");
+ proba[8].setActionCommand("20percent");
+ proba[9].setActionCommand("10percent");
+ proba[10].setActionCommand("0percent");
+
+
+ for(int i=0; i<fom1.length; i++) {
+ fom1[i].addActionListener(fon);
+ fom1[i].setFont(font);
+ fom1[i].setActionCommand("size");
+ tm1.add(fom1[i]);
+ }
+ for(int i=0; i<fom2.length; i++) {
+ fom2[i].addActionListener(fon);
+ fom2[i].setFont(font);
+ fom2[i].setActionCommand("hor");
+ tm2.add(fom2[i]);
+ }
+ for(int i=0; i<fom3.length; i++) {
+ fom3[i].addActionListener(fon);
+ fom3[i].setFont(font);
+ fom3[i].setActionCommand("ver");
+ tm3.add(fom3[i]);
+ }
+
+ dm.add(data[0]);
+ dm.add(data[1]);
+ dm.setFont(font);
+ em.add(export[0]);
+ em.add(export[1]);
+ em.add(export[2]);
+ em.add(export[3]);
+ em.setFont(font);
+ em.setEnabled(false);
+ fm.add(file[0]);
+ fm.addSeparator();
+ fm.add(file[1]);
+ fm.add(file[2]);
+ file[2].setEnabled(false);
+ fm.addSeparator();
+ fm.add(dm);
+ fm.add(em);
+ file[3].setEnabled(false);
+ fm.add(file[3]);
+ fm.addSeparator();
+ fm.add(file[4]);
+ fm.setFont(font);
+ am.add(align[0]);
+ am.add(align[1]);
+ am.add(align[2]);
+ am.add(align[3]);
+ am.addSeparator();
+ am.add(align[4]);
+ am.add(align[5]);
+ am.setFont(font);
+
+ for(int i=1; i<proba.length; i++) {
+ lm.add(proba[i]);
+ }
+ pm.add(proba[0]);
+ pm.add(lm);
+ lm.setFont(font);
+ lm.setEnabled(false);
+ pm.setFont(font);
+
+ mb.add(fm);
+
+ tm.setFont(font);
+ tm1.setFont(font);
+ tm2.setFont(font);
+ tm3.setFont(font);
+ tm.add(tm1);
+ tm.add(tm2);
+ tm.add(tm3);
+ mb.add(tm);
+
+ mb.add(am);
+ mb.add(pm);
+ setJMenuBar(mb);
+
+
+ // Message field to show some info.
+ //
+ messageText = new JTextField();
+ messageText.setFont(font);
+ messageText.setBackground(Color.white);
+ messageText.setEditable(false);
+
+
+ //Create empty panels and import data later.
+ //
+ seqname = new PrintNames();
+ seqname.setPreferredSize(new Dimension(50,100));
+ seqcont = new PrintData();
+ seqcont.setPreferredSize(new Dimension(500,100));
+ guidetree = new PrintTree();
+ guidetree.setPreferredSize(new Dimension(50,100));
+
+ // Create a split pane for the two scroll panes at time.
+ //
+ splitp1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ splitp1.setOneTouchExpandable(true);
+ splitp1.setDividerLocation(splitWidth);
+
+ // Listener needed to update the tree.
+ splitp1.addPropertyChangeListener(new SplitListener());
+
+ // Second splitpane will keep the first as a left-side.
+ //
+ splitp2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ splitp2.setOneTouchExpandable(true);
+ splitp2.setDividerLocation(splitWidth*2);
+
+ // Set scrollPanes.
+ //
+ setScrollPanes();
+
+
+ // Get the initial size from the parent - needs updating.
+ //
+ wHeight = ProAlign.wHeight;
+ wWidth = ProAlign.wWidth;
+
+ // Do not use layout but set it manually.
+ //
+ cp = getContentPane();
+ cp.setLayout(null);
+ cp.add(splitp2);
+ cp.add(messageText);
+
+ if(System.getProperty("os.name").startsWith("Windows")){
+ splitp2.setBounds(0,0, wWidth-10,wHeight-76);
+ messageText.setBounds(0,wHeight-75,wWidth-10,20);
+ } else if(System.getProperty("os.name").startsWith("Mac")){
+ splitp2.setBounds(0,0, wWidth-10,wHeight-76);
+ messageText.setBounds(0,wHeight-75,wWidth-20,25);
+ } else {
+ splitp2.setBounds(0,0, wWidth-10,wHeight-66);
+ messageText.setBounds(0,wHeight-65,wWidth-10,25);
+ }
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e){System.exit(0);}
+ });
+ addMouseMotionListener(new MiceListener());
+ }
+
+ void setAlignedData(AlignmentNode root) {
+
+ // Get the sequence names..
+ //
+ String[] seqNames = root.getTerminalNames();
+ for(int i=0; i<seqNames.length; i++) {
+ seqNames[i] = (seqNames[i]+" ").substring(0,20);
+ }
+
+ // and get the sequence data.
+ //
+ String[] seqData = new String[root.getNumChild()];
+ for(int i=0; i<seqData.length; i++) { seqData[i] = ""; }
+ for(int i=0; i<root.cellPath.length; i++) {
+
+ int h = 0;
+ char[] c0 = root.child[0].getCharacterAt(root.cellPath[i][0]-2);
+ char[] c1 = root.child[1].getCharacterAt(root.cellPath[i][1]-2);
+
+ for(int j=0; j<c0.length; j++) {
+ seqData[h++] += c0[j];
+ }
+ for(int j=0; j<c1.length; j++) {
+ seqData[h++] += c1[j];
+ }
+ }
+
+ // Get the posterior probabilities.
+ //
+ nodeNames = root.getInternalNames();
+ postProb = new double[root.cellPath.length][nodeNames.length];
+ for(int i=0; i<root.cellPath.length; i++) {
+ postProb[i] = root.getInternalPostProbAt(i);
+ }
+
+ // Update info & create new JPanels.
+ //
+ rw.messageText.setText(" Alignment ready: "+seqData.length+" sequences, "+
+ seqData[0].length() +" characters. viterbi:"+root.sumViterbiEnd()+
+ "; forward: "+root.sumForwardEnd());
+ seqname = new PrintNames(seqNames, true);
+ seqcont = new PrintData(seqData, postProb, rw);
+ guidetree = new PrintTree(root, rw, true);
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(true); // save alignment
+ rw.file[3].setEnabled(true); // save paguide
+
+ rw.data[1].setEnabled(true); // import guide tree
+
+ rw.align[0].setEnabled(false); // do guide tree
+ rw.align[1].setEnabled(true); // do paguide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(false); // sample
+ rw.align[4].setEnabled(true); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(true); // export
+
+ rw.proba[0].setEnabled(true); // plot prob's
+ rw.lm.setEnabled(true); // filter sites
+
+ isAligned = true;
+ hasData = true;
+ hasTree = true;
+
+ }
+
+ void setRawData(HashMap seqs) {
+
+ rw.seqs = seqs;
+
+ // Get the sequence names and the data.
+ //
+ Iterator seqKeys = seqs.keySet().iterator();
+ String[] seqNames = new String[seqs.keySet().size()];
+ String[] seqData = new String[seqs.keySet().size()];
+
+ int i = 0;
+ maxLength = 0;
+ while(seqKeys.hasNext()) {
+ String name = (String) seqKeys.next();
+ seqData[i] = (String) seqs.get(name);
+ seqNames[i] = (name+" ").substring(0,20);
+
+ if(seqData[i].length()>maxLength) {
+ maxLength = seqData[i].length();
+ }
+ i++;
+ }
+
+ // Update info & create new JPanels.
+ //
+ rw.messageText.setText(" Data ready: "+seqData.length+" sequences. ");
+ seqname = new PrintNames(seqNames, false);
+ seqcont = new PrintData(seqData, maxLength, rw);
+ guidetree = new PrintTree();
+ guidetree.setPreferredSize(new Dimension(50,seqname.getHeight()));
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.file[3].setEnabled(false); // save paguide
+
+ rw.data[1].setEnabled(true); // import guide tree
+
+ rw.align[0].setEnabled(true); // do clustalw guide tree
+ rw.align[1].setEnabled(true); // do proalign guide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(true); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(false); // export
+
+ rw.proba[0].setEnabled(false); // plot prob's
+ rw.lm.setEnabled(false); // filter sites
+
+ isAligned = false;
+ hasData = true;
+ hasTree = false;
+
+ }
+
+ void setRawDataAndTree(String tree) {
+
+ rw.root = new AlignmentNode(pa,tree,0f);
+
+ String[] seqNames = root.getTerminalNames();
+ String[] seqData = new String[seqNames.length];
+
+ for(int j=0; j<seqNames.length; j++) {
+ seqData[j] = (String) pa.seqs.get(seqNames[j]);
+ seqNames[j] = (seqNames[j]+" ").substring(0,20);
+ }
+
+ // Update info & create new JPanels.
+ //
+ rw.messageText.setText(" Data and tree ready: "+seqData.length+" sequences. ");
+ seqname = new PrintNames(seqNames, false);
+ seqcont = new PrintData(seqData, maxLength, rw);
+ guidetree = new PrintTree(root, rw, false);
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.file[3].setEnabled(true); // save paguide
+
+ rw.data[0].setEnabled(true); // import data
+ rw.data[1].setEnabled(true); // import guide tree
+
+ rw.align[0].setEnabled(true); // do guide tree
+ rw.align[1].setEnabled(true); // do paguide tree
+ rw.align[2].setEnabled(true); // do multiple
+ rw.align[3].setEnabled(true); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(false); // export
+
+ isAligned = false;
+ hasData = true;
+ hasTree = true;
+ }
+
+ void removeGaps(String tree) {
+
+ pa.setNodeNumber(-1);
+ rw.root = new AlignmentNode(pa,tree,0f);
+
+ String[] seqNames = rw.root.getTerminalNames();
+ String[] seqData = new String[rw.root.getNumChild()];
+
+ maxLength = 0;
+ for(int i=0; i<seqNames.length; i++) {
+ seqData[i] = (String) seqs.get(seqNames[i]);
+ seqNames[i] = (seqNames[i]+" ").substring(0,20);
+
+ if(seqData[i].length()>maxLength) {
+ maxLength = seqData[i].length();
+ }
+ }
+
+ // Update info & create new JPanels.
+ //
+ rw.messageText.setText(" Data and tree ready: "+seqData.length+" sequences. ");
+ seqname = new PrintNames(seqNames, false);
+ seqcont = new PrintData(seqData, maxLength, rw);
+ guidetree = new PrintTree(root, rw, false);
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.file[3].setEnabled(true); // save paguide
+
+ rw.data[1].setEnabled(true); // import guide tree
+
+ rw.align[0].setEnabled(true); // do guide tree
+ rw.align[1].setEnabled(true); // do pa guide tree
+ rw.align[2].setEnabled(true); // do multiple
+ rw.align[3].setEnabled(true); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(false); // export
+
+ rw.proba[0].setEnabled(false); // plot prob's
+ rw.lm.setEnabled(false); // filter sites
+
+ isAligned = false;
+ hasData = true;
+
+ }
+
+ // Update if the frame has been resized.
+ //
+ public void update(Graphics g) {
+
+ wHeight = rw.getHeight();
+ wWidth = rw.getWidth();
+
+ if(System.getProperty("os.name").startsWith("Windows")){
+ splitp2.setBounds(0,0, wWidth-10,wHeight-76);
+ messageText.setBounds(0,wHeight-75,wWidth-10,20);
+ } else if(System.getProperty("os.name").startsWith("Mac")){
+ splitp2.setBounds(0,0, wWidth-10,wHeight-76);
+ messageText.setBounds(0,wHeight-75,wWidth-20,25);
+ } else {
+ splitp2.setBounds(0,0, wWidth-10,wHeight-66);
+ messageText.setBounds(0,wHeight-65,wWidth-10,25);
+ }
+ splitp2.updateUI();
+
+ messageText.updateUI();
+
+ }
+ public void macUpdate() { // things don't work on OSX
+
+ if(wHeight!=rw.getHeight() || wWidth!=rw.getWidth()){
+
+ wHeight = rw.getHeight();
+ wWidth = rw.getWidth();
+
+ splitp2.setBounds(0,0, wWidth-10,wHeight-76);
+ messageText.setBounds(0,wHeight-75,wWidth-20,25);
+
+ splitp2.updateUI();
+
+ messageText.updateUI();
+ }
+ }
+
+ void setScrollPanes() {
+
+ sPane1 = new JScrollPane(guidetree,
+ JScrollPane.VERTICAL_SCROLLBAR_NEVER,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ sPane2 = new JScrollPane(seqname,
+ JScrollPane.VERTICAL_SCROLLBAR_NEVER,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ sPane3 = new JScrollPane(seqcont,
+ JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+
+ sButt1 = new JScrollBar();
+ sButt3 = new JScrollBar();
+
+ rw.setRulers();
+
+ sPane1.setViewportBorder(BorderFactory.createLineBorder(Color.black));
+ sPane1.setColumnHeaderView(columnRule1);
+ sPane1.setBackground(Color.white);
+
+ sPane2.setViewportBorder(BorderFactory.createLineBorder(Color.black));
+ sPane2.setColumnHeaderView(columnRule2);
+ sPane2.setBackground(Color.white);
+ seqname.sPane = sPane2;
+
+ sPane3.setViewportBorder(BorderFactory.createLineBorder(Color.black));
+ sPane3.setColumnHeaderView(charRule);
+ sPane3.setBackground(Color.white);
+ seqcont.sPane = sPane3;
+
+ sButt3.setUnitIncrement(30);
+ sButt3.setBlockIncrement(100);
+ sButt3.addAdjustmentListener(new ScrollListener());
+ sPane3.setVerticalScrollBar(sButt3);
+
+ sPane1.getHorizontalScrollBar().setBackground(Color.white);
+ sPane2.getHorizontalScrollBar().setBackground(Color.white);
+ sPane3.getHorizontalScrollBar().setBackground(Color.white);
+ sPane1.getVerticalScrollBar().setBackground(Color.white);
+ sPane3.getVerticalScrollBar().setBackground(Color.white);
+ sPane3.getHorizontalScrollBar().setUnitIncrement(50);
+ sPane3.getHorizontalScrollBar().setBlockIncrement(200);
+
+ splitp1.setLeftComponent(sPane1);
+ splitp1.setRightComponent(sPane2);
+ splitp2.setLeftComponent(splitp1);
+ splitp2.setRightComponent(sPane3);
+
+ splitp1.setOneTouchExpandable(true);
+ splitp1.setDividerLocation(splitWidth);
+ splitp2.setOneTouchExpandable(true);
+ splitp2.setDividerLocation(splitWidth*2);
+
+ splitp1.updateUI();
+ splitp2.updateUI();
+
+ }
+
+ void setRulers() {
+
+ // Create a ruler for sequence data..
+ //
+ charRule = new Rule(rw);
+ charRule.setPreferredWidth(seqcont.totalWidth);
+ charRule.setIncrement(seqcont.columnWidth, seqcont.horizontalCharSpace);
+ charRule.setBackground(Color.white);
+ // ..and two empty panels to fill the same space in other windows.
+ //
+ columnRule1 = new JPanel();
+ columnRule1.setPreferredSize(new Dimension(guidetree.getWidth(),charRule.rulerHeight));
+ columnRule1.setBackground(Color.white);
+ //
+ columnRule2 = new JPanel();
+ columnRule2.setPreferredSize(new Dimension(seqname.totalWidth,charRule.rulerHeight));
+ columnRule2.setBackground(Color.white);
+
+ }
+
+ // Focus the alignment view if clicked on the curve.
+ //
+ void focusAlignment(int x) {
+ int y3 = (int) sPane3.getViewport().getViewPosition().getY();
+ int x3 = x*seqcont.columnWidth-sPane3.getWidth()/2;
+ if(x3<0) {
+ x3 = 0;
+ }
+ if(x3>(seqcont.totalWidth-sPane3.getWidth())) {
+ x3 = seqcont.totalWidth-sPane3.getWidth();
+ }
+ sPane3.getViewport().setViewPosition(new Point(x3,y3));
+ sPane3.getViewport().updateUI();
+ }
+
+
+ // Write info at messageText field.
+ //
+ void writeNodeInfo(int col, int row) {
+ String nn = nodeNames[row];
+ AlignmentNode an = root.getNodeNamed(nn);
+ String alphabet = root.getAlphabet();
+ int site = root.getSiteAt(col,nn);
+
+ String txt = "";
+
+ if(site>-1) {
+ for(int i=0; i<alphabet.length(); i++) {
+ txt += ", ";
+ txt += alphabet.charAt(i)+": ";
+ if(ProAlign.isDna) {
+ if(an.charProb[site][i]<0.001) {
+ txt += ("0.000");
+ } else {
+ txt += (""+an.charProb[site][i]+" ").substring(0,5);
+ }
+ } else {
+ if(an.charProb[site][i]<0.001) {
+ txt += ("0.00");
+ } else {
+ txt += (""+an.charProb[site][i]+" ").substring(0,4);
+ }
+ }
+ }
+ } else {
+ txt = ", no info";
+ }
+
+ String pp = (""+Math.exp(postProb[col][row])+" ").substring(0,5);
+ messageText.setText(col+", "+nn+": "+pp+" (char "+site+txt+")");
+
+ }
+
+ void convertNodeInfoX(int col, String name) {
+
+ if(col >= postProb.length) { col=postProb.length-1; }
+ int row = -1;
+ for(int i=0; i<nodeNames.length; i++) {
+ if(nodeNames[i].equals(name)) { row = i; }
+ }
+ if(row > -1) {
+ rw.writeNodeInfo(col,row);
+ }
+ }
+
+ void writeTempFasta() {
+
+ try {
+ OutFile out = new OutFile(ProAlign.tempFolder+File.separator+"proalign.seq");
+
+ Iterator seqKeys = seqs.keySet().iterator();
+
+ while(seqKeys.hasNext()) {
+ String name = (String) seqKeys.next();
+ String data = (String) seqs.get(name);
+
+ if(ProAlign.isDna) {
+ out.println(">DL;" +name);
+ } else {
+ out.println(">P1;" +name);
+ }
+ out.println();
+ int count = 0;
+ for(int j = 0; j<data.length(); j++) {
+ count++;
+ out.print(data.charAt(j));
+ if(count == 50) {
+ out.println("");
+ count = 0;
+ }
+ }
+ out.println("*");
+ }
+ out.close();
+ } catch (IOException e) {
+ }
+ }
+
+ static void updateInfo(String text) {
+
+ rw.messageText.setText(text);
+
+ }
+
+ // Vertical scrolling - requires some synchronizing.
+ //
+ class ScrollListener implements AdjustmentListener {
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+
+ int y3 = (int) sPane3.getViewport().getViewPosition().getY();
+ int x3 = (int) sPane3.getViewport().getViewPosition().getX();
+ int x2 = (int) sPane2.getViewport().getViewPosition().getX();
+
+ sPane1.getViewport().setViewPosition(new Point(0,y3));
+ sPane2.getViewport().setViewPosition(new Point(x2,y3));
+ sPane3.getViewport().setViewPosition(new Point(x3,y3));
+
+ sPane2.getViewport().updateUI();
+ sPane3.getViewport().updateUI();
+
+ }
+ }
+
+ // Tree split pane - tree dimesions need updating.
+ //
+ class SplitListener implements PropertyChangeListener {
+ public void propertyChange(PropertyChangeEvent e) {
+
+ if(guidetree.isTreeGiven) {
+ guidetree.setPreferredSize(new Dimension(sPane1.getWidth(), guidetree.yMax));
+ guidetree.updateUI();
+ }
+
+ }
+ }
+
+
+ // ActionListener for 'File' menu
+ //
+ class FileMenuListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JMenuItem target = (JMenuItem)e.getSource();
+ String actionCommand = target.getActionCommand();
+
+ if(actionCommand.equals("about")) {
+
+ String text = new String(
+ "\n ProAlign v. "+ProAlign.version+"\n"+
+ " a program for probabilistic sequence alignment \n"+
+ " (c) 2002 Ari Loytynoja & Michel C. Milinkovitch \n");
+ OpenDialog od = new OpenDialog(ResultWindow.this);
+ od.showDialog("About ProAlign", text);
+
+ } else if(actionCommand.equals("open")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(ResultWindow.this,"Open",true);
+ String filepath = opf.openFile();
+
+ if(!filepath.equals("")) {
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+
+ boolean validFile = true;
+
+ try {
+ ObjectInputStream is =
+ new ObjectInputStream(new FileInputStream(filepath));
+ rw.root = (AlignmentNode) is.readObject();
+ }
+ catch(InvalidClassException ice) {
+ String text = new String("\n Error! File doesn't look\n"+
+ " like a ProAlign-file!\n");
+ OpenDialog od = new OpenDialog(ResultWindow.this);
+ od.showDialog("Error!", text);
+
+ ProAlign.log.println("Open exception1: "+filepath+"\n"+ice.toString());
+ ProAlign.log.flush();
+ validFile = false;
+ }
+ catch(Exception oe) {
+ ProAlign.log.println("Open exception2: "+filepath+"\n"+oe.toString());
+ ProAlign.log.flush();
+ //oe.printStackTrace();
+ validFile = false;
+ }
+
+ if(validFile) {
+
+ rw.setAlignedData(rw.root);
+ rw.setScrollPanes();
+ PrintTree.numOpenWindows = 0;
+ }
+
+ // Set substitution model
+ if(ProAlign.isDna){
+ rw.pa.sm.jcDnaModel();
+ } else {
+ rw.pa.sm.wagProteinModel();
+ }
+
+ // Set ProAlign 'seqs' hashmap
+ //
+ String[] names = rw.root.getTerminalNames();
+ String[] data = new String[rw.root.getNumChild()];
+
+ for(int i=0; i<data.length; i++) { data[i] = ""; }
+ for(int i=0; i<rw.root.cellPath.length; i++) {
+
+ int h = 0;
+ char[] c0 = root.child[0].getCharacterAt(root.cellPath[i][0]-2);
+ char[] c1 = root.child[1].getCharacterAt(root.cellPath[i][1]-2);
+
+ for(int j=0; j<c0.length; j++) {
+ if(c0[j]!='-') {
+ data[h] += c0[j];
+ }
+ h++;
+ }
+ for(int j=0; j<c1.length; j++) {
+ if(c1[j]!='-') {
+ data[h] += c1[j];
+ }
+ h++;
+ }
+ }
+
+ rw.seqs = new HashMap();
+ for(int i=0; i<names.length; i++) {
+ rw.seqs.put(names[i], data[i]);
+ }
+ pa.seqs = seqs;
+
+ }
+
+ } else if(actionCommand.equals("save")) {
+
+ if(rw.root != null) {
+ OpenFileChooser opf =
+ new OpenFileChooser(ResultWindow.this,"Save",true);
+ String filepath = opf.openFile();
+
+ if(!filepath.equals("")) {
+ if(!filepath.endsWith(ProAlign.fileExt)) {
+ filepath += "."+ProAlign.fileExt;
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+ try {
+ ObjectOutputStream os =
+ new ObjectOutputStream(new FileOutputStream(filepath));
+ os.writeObject((AlignmentNode) rw.root);
+ os.flush();
+ os.close();
+ } catch(IOException ioe) {
+ ProAlign.log.println("Save exception1: "+filepath+"\n"+ioe.toString());
+ ProAlign.log.flush();
+ //ioe.printStackTrace();
+ }
+ catch(Exception oe) {
+ ProAlign.log.println("Save exception2: "+filepath+"\n"+oe.toString());
+ ProAlign.log.flush();
+ //oe.printStackTrace();
+ }
+ }
+ }
+
+ } else if(actionCommand.equals("savepag")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(ResultWindow.this,"Save guide tree",false);
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ try {
+ OutFile paguide = new OutFile(filepath);
+ paguide.println(rw.root.tree);
+ paguide.flush();
+ paguide.close();
+ } catch(Exception ne) { }
+ }
+ //System.out.println("pag: "+rw.root.tree);
+
+ } else if(actionCommand.equals("data")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(ResultWindow.this,"Import",false);
+ String filepath = opf.openFile();
+
+ SequenceReader sr = new SequenceReader();
+ if(!filepath.equals("")) {
+ if(sr.fromFile(filepath)) {
+ HashMap seqs = sr.getSequences();
+ pa.seqs = seqs;
+
+ CheckSequence cs = new CheckSequence();
+ if(cs.isDna(seqs)){
+ pa.sm.jcDnaModel();
+ ProAlign.isDna = true;
+ } else {
+ pa.sm.wagProteinModel();
+ ProAlign.isDna = false;
+ }
+
+ if(!cs.isFromAlphabet(seqs,pa.sm.equateAlphabet)) {
+ OpenDialog od = new OpenDialog(ResultWindow.this);
+ od.showDialog("Error!", cs.getError());
+ } else {
+ rw.setRawData(seqs);
+ rw.setScrollPanes();
+
+ rw.root = null;
+ pa.setNodeNumber(-1);
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+ } else {
+ OpenDialog od = new OpenDialog(ResultWindow.this);
+ od.showDialog("Error!", sr.getErrors());
+ }
+ }
+
+ } else if(actionCommand.equals("tree")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(ResultWindow.this,"Import",false);
+ String filepath = opf.openFile();
+
+ if(!filepath.equals("")) {
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+
+ TreeReader tr = new TreeReader();
+
+ String[] treeNodes = tr.getAllNodes(filepath);
+ CheckTreeAndData chk =
+ new CheckTreeAndData(treeNodes, rw.seqs);
+ if(chk.nodesAreSame()) {
+ pa.setNodeNumber(-1);
+ String guide = tr.readFile(filepath);
+ if(tr.isUnRooted) {
+ TreeNode tn = new TreeNode(guide);
+ guide = tn.findMiddlePoint();
+ }
+ if(rw.isAligned) {
+ rw.removeGaps(guide);
+ } else {
+ rw.setRawDataAndTree(guide);
+ }
+ rw.setScrollPanes();
+
+ }
+ }
+ } else if(actionCommand.equals("fasta")) {
+
+ SaveData sd = new SaveData("Fasta", ResultWindow.this);
+
+ } else if(actionCommand.equals("phylip")) {
+
+ SaveData sd = new SaveData("Phylip", ResultWindow.this);
+
+ } else if(actionCommand.equals("msf")) {
+
+ SaveData sd = new SaveData("MSF", ResultWindow.this);
+
+ } else if(actionCommand.equals("nexus")) {
+
+ SaveData sd = new SaveData("Nexus", ResultWindow.this);
+
+ } else if(actionCommand.equals("exit")) {
+ dispatchEvent(new WindowEvent(ResultWindow.this,
+ WindowEvent.WINDOW_CLOSING));
+ }
+ }
+ }
+
+ // ActionListener for 'Alignment' menu
+ //
+ class AlignmentMenuListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JMenuItem target = (JMenuItem)e.getSource();
+ String actionCommand = target.getActionCommand();
+
+ if(actionCommand.equals("guide")) {
+
+ pa.setNodeNumber(-1);
+ rw.writeTempFasta();
+
+ try {
+ RunClustalw rc = new RunClustalw(ResultWindow.this);
+ rw.messageText.setText(" Creating ClustalW guide tree.");
+
+ rw.file[1].setEnabled(false); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.dm.setEnabled(false); // import
+ rw.align[0].setEnabled(false); // do guide tree
+ rw.align[1].setEnabled(false); // do paguide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(false); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ } catch(Exception ex) {
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.file[3].setEnabled(false); // save paguide
+
+ rw.data[1].setEnabled(true); // import guide tree
+
+ rw.align[0].setEnabled(true); // do clustalw guide tree
+ rw.align[1].setEnabled(true); // do proalign guide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(true); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(false); // export
+
+ rw.proba[0].setEnabled(false); // plot prob's
+ rw.lm.setEnabled(false); // filter sites
+
+ }
+
+ } else if(actionCommand.equals("paguide")) {
+
+ pa.setNodeNumber(-1);
+ PwSubstitutionMatrix psm = new PwSubstitutionMatrix();
+ String pwAlphabet;
+ int[][] pwSubst;
+ int gOpen, gExt;
+
+ if(ProAlign.isDna){
+ pwAlphabet = psm.dnaAlphabet;
+ pwSubst = psm.swdna;
+ gOpen = -1*pa.pwDnaOpen;
+ gExt = -1*pa.pwDnaExt;
+
+ } else {
+
+ pwAlphabet = psm.protAlphabet;
+ if(pa.pwProtMatrix.equals("pam60")) {
+ pwSubst = psm.pam60;
+ } else if(pa.pwProtMatrix.equals("pam160")) {
+ pwSubst = psm.pam160;
+ } else if(pa.pwProtMatrix.equals("pam250")) {
+ pwSubst = psm.pam250;
+ } else {
+ pwSubst = psm.pam120;
+ }
+ gOpen = -1*pa.pwProtOpen;
+ gExt = -1*pa.pwProtExt;
+ }
+
+ PwAlignment pa =
+ new PwAlignment(pwSubst,gOpen,gExt,pwAlphabet,ProAlign.isDna);
+ PwAlignmentLoop pal = new PwAlignmentLoop(ResultWindow.this,pa);
+ rw.messageText.setText(" Creating ProAlign guide tree.");
+
+ rw.file[1].setEnabled(false); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.dm.setEnabled(false); // import
+ rw.align[0].setEnabled(false); // do guide tree
+ rw.align[1].setEnabled(false); // do paguide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(false); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ } else if(actionCommand.equals("multiple")) {
+
+ RunMultiple rm = new RunMultiple(ResultWindow.this);
+ rw.messageText.setText(" Creating multiple alignment.");
+
+ rw.file[1].setEnabled(false); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.dm.setEnabled(false); // import
+ rw.align[0].setEnabled(false); // do guide tree
+ rw.align[1].setEnabled(false); // do paguide tree
+ rw.align[2].setEnabled(false); // do multiple
+ rw.align[3].setEnabled(false); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ } else if(actionCommand.equals("sample")) {
+
+ SampleAlignments sa = new SampleAlignments(ResultWindow.this);
+ sa.setSize(sa.width,sa.height);
+ sa.setVisible(true);
+
+ } else if(actionCommand.equals("remove")) {
+
+ rw.removeGaps(rw.root.tree);
+ rw.setScrollPanes();
+
+ } else if(actionCommand.equals("setting")) {
+
+ SetParameters sp = new SetParameters(ResultWindow.this);
+ sp.setSize(sp.width,sp.height);
+ sp.setVisible(true);
+
+ }
+ }
+ }
+
+ // ActionListener for 'Probability' menu
+ //
+ class ProbabilityMenuListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JMenuItem target = (JMenuItem)e.getSource();
+ String actionCommand = target.getActionCommand();
+ double limit = -1d;
+
+ if(actionCommand.equals("plot")) {
+ //
+ double[] minPost = new double[root.cellPath.length];
+ String[] minNode = new String[root.cellPath.length];
+ for(int i=0; i<root.cellPath.length; i++) {
+ minPost[i] = root.getMinimumInternalPostProbAt(i);
+ minNode[i] = root. getMinimumInternalPostProbNode();
+ }
+
+ MinimumProbWindow mpw = new MinimumProbWindow(minPost,minNode,rw);
+ mpw.setSize(600,100);
+ mpw.setLocation(220,320);
+ mpw.setVisible(true);
+
+ } else if(actionCommand.equals("90percent")) {
+ limit = 0.9d;
+ } else if(actionCommand.equals("80percent")) {
+ limit = 0.8d;
+ } else if(actionCommand.equals("70percent")) {
+ limit = 0.7d;
+ } else if(actionCommand.equals("60percent")) {
+ limit = 0.6d;
+ } else if(actionCommand.equals("50percent")) {
+ limit = 0.5d;
+ } else if(actionCommand.equals("40percent")) {
+ limit = 0.4d;
+ } else if(actionCommand.equals("30percent")) {
+ limit = 0.3d;
+ } else if(actionCommand.equals("20percent")) {
+ limit = 0.2d;
+ } else if(actionCommand.equals("10percent")) {
+ limit = 0.1d;
+ } else if(actionCommand.equals("0percent")) {
+ limit = 0d;
+ }
+
+ if(limit >= 0d) {
+
+ boolean[] sitesRemoved = new boolean[root.cellPath.length];
+ int count = 0;
+ for(int i=0; i<root.cellPath.length; i++) {
+ if(Math.exp(root.getMinimumInternalPostProbAt(i)) < limit) {
+ sitesRemoved[i] = true;
+ count++;
+ }
+ }
+ rw.seqcont.sitesRemoved = sitesRemoved;
+ rw.messageText.setText(
+ " Filter: "+count+" of "+root.cellPath.length+" sites have posterior "+
+ "probability lower than "+(int)(limit*100)+" percent.");
+
+ }
+ }
+ }
+
+ // ActionListener for 'Probability' menu
+ //
+ class FontMenuListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ JMenuItem target = (JMenuItem)e.getSource();
+ String actionCommand = target.getActionCommand();
+ // System.out.println(actionCommand+" "+target.getText()+"");
+
+ if(actionCommand.equals("size")) {
+ rwFontSize = new Integer(target.getText()).intValue();
+ } else if(actionCommand.equals("hor")) {
+ horizontalCharSpace = new Integer(target.getText()).intValue();
+ } else if(actionCommand.equals("ver")) {
+ verticalCharSpace = new Integer(target.getText()).intValue();
+ }
+
+ FontMetrics currentMetrics =
+ rw.getFontMetrics(new Font("monospaced", Font.BOLD, ResultWindow.rwFontSize));
+ int columnWidth = currentMetrics.charWidth(' ')+horizontalCharSpace;
+ rw.charRule.setIncrement(columnWidth,horizontalCharSpace);
+ rw.charRule.setPreferredWidth(rw.seqcont.maxLength*columnWidth);
+ }
+ }
+
+ class MiceListener extends MouseMotionAdapter {
+ public void mouseMoved(MouseEvent e) {
+ if(System.getProperty("os.name").startsWith("Mac")){
+ rw.macUpdate();
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Rule.java b/Rule.java
new file mode 100644
index 0000000..4867025
--- /dev/null
+++ b/Rule.java
@@ -0,0 +1,117 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.awt.Toolkit;
+import java.awt.Graphics;
+import java.awt.Dimension;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseListener;
+
+public class Rule extends JComponent {
+ int rulerHeight = 15;
+
+ private int increment;
+ private int startPosition;
+ private int units;
+
+ Rule rule;
+ ResultWindow parent;
+ public Rule(ResultWindow rw) {
+
+ rule = this;
+ parent = rw;
+
+ addMouseListener(new MiceListener());
+ }
+
+ public void setIncrement(int columnWidth, int startPosition) {
+ increment = columnWidth;
+ this.startPosition = startPosition;
+ units = 10*columnWidth;
+ }
+
+ public void setPreferredWidth(int pw) {
+ setPreferredSize(new Dimension(pw,rulerHeight));
+ }
+
+ public void paintComponent(Graphics g) {
+ Rectangle drawHere = g.getClipBounds();
+
+ // Fill clipping area
+ g.setColor(Color.white);
+ g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
+
+ // Do the ruler labels in a small font
+ g.setFont(new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize-2));
+ g.setColor(Color.black);
+
+ // Some vars we need.
+ int tickLength = 0;
+ String text = null;
+
+ // Use clipping bounds to calculate first tick and last tick location.
+ int start = (drawHere.x / increment) * increment;
+ int end = (((drawHere.x + drawHere.width) / increment) + 1) * increment;
+
+ // Make a special case of 0 to display the number
+ // within the rule and draw a units label.
+ if (start == 0) {
+ text = Integer.toString(0);
+ tickLength = 3;
+ g.drawLine(0, rulerHeight-1, 0, rulerHeight-tickLength-1);
+ start = increment;
+ }
+
+ // ticks and labels
+ for (int i = start; i < end; i += increment) {
+ if (i % units == 0) {
+ tickLength = 3;
+ text = Integer.toString(i/increment);
+ } else {
+ tickLength = 1;
+ text = null;
+ }
+
+ if (tickLength != 0) {
+ g.drawLine(i, rulerHeight-1, i, rulerHeight-tickLength-1);
+ if (text != null)
+ g.drawString(text, i-10, 10);
+ }
+ }
+ }
+ // A click on a site will include/exclude that character.
+ //
+ class MiceListener extends MouseAdapter {
+ public void mouseClicked(MouseEvent e) {
+ int x = e.getX();
+ int y = e.getY();
+ if(e.isShiftDown()) {
+ parent.seqcont.updateStableSites(x,y,true);
+ } else {
+ parent.seqcont.updateStableSites(x,y,false);
+ }
+ }
+ }
+
+
+}
+
+
+
+
+
+
diff --git a/RunClustalw.java b/RunClustalw.java
new file mode 100644
index 0000000..d664d09
--- /dev/null
+++ b/RunClustalw.java
@@ -0,0 +1,186 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.io.DataInputStream;
+import java.io.BufferedInputStream;
+
+/**
+ * Running native ClustalW.
+ */
+public class RunClustalw extends Thread {
+
+
+ String tempFolder;
+ String clustalwPath;
+ String cmdParameter;
+
+ ResultWindow rw;
+
+ Process process;
+ DataInputStream clustalwOut;
+
+ /**
+ * Argument list describing the ClustalW loop.
+ */
+ RunClustalw(ResultWindow rw) {
+
+ this.rw = rw;
+
+ ProAlign.log("RunClustalw");
+
+ clustalwPath = ProAlign.clustalwPath;
+ tempFolder = ProAlign.tempFolder+File.separator;
+
+ if(System.getProperty("os.name").startsWith("Windows")){
+ File oldFile = new File(tempFolder+"PROALIGN.TRE");
+ if(oldFile.exists()) {
+ try {
+ oldFile.delete();
+ } catch (Exception ie) {
+ ProAlign.log.println(" can not delete old guide tree-file!");
+ }
+ }
+ } else {
+ File oldFile = new File(tempFolder+"proalign.tre");
+ if(oldFile.exists()) {
+ try {
+ oldFile.delete();
+ } catch (Exception ie) {
+ ProAlign.log.println(" can not delete old guide tree-file!");
+ }
+ }
+ }
+
+ if(System.getProperty("os.name").startsWith("Windows")){
+ cmdParameter = "clustalw /tree /newtree="+tempFolder+"PROALIGN.TRE /infile="+
+ tempFolder+"proalign.seq";
+ } else {
+ cmdParameter = " -tree -newtree="+tempFolder+"proalign.tre -infile="+
+ tempFolder+"proalign.seq";
+ }
+
+ start();
+ }
+
+ public void run(){
+ /**
+ * Clustalw - make guide tree only!
+ */
+ if(System.getProperty("os.name").startsWith("Windows")) {
+
+
+ int narg = numArg(cmdParameter,"/");
+ try {
+ WinClustalw wc = new WinClustalw(narg,cmdParameter);
+
+ while(wc.running) {
+ try{
+ Thread.currentThread().sleep(500);
+ } catch(InterruptedException e) {}
+ }
+ } catch(Exception ex) {
+ ProAlign.log("WinClustalw error");
+ }
+
+ } else {
+ try {
+
+ process = Runtime.getRuntime().exec(clustalwPath+cmdParameter);
+ clustalwOut =
+ new DataInputStream(new BufferedInputStream(process.getInputStream()));
+
+ String str;
+ while((str = clustalwOut.readLine()) != null) {
+ if (str.length() > 0) {
+ ProAlign.log(str);
+ }
+ }
+ } catch(IOException e) { }
+ }
+ if(ProAlign.DEBUG) {
+ ProAlign.log.flush();
+ }
+
+ String filepath;
+ if(System.getProperty("os.name").startsWith("Windows")){
+ filepath = ProAlign.tempFolder+File.separator+"PROALIGN.TRE";
+ } else {
+ filepath = ProAlign.tempFolder+File.separator+"proalign.tre";
+ }
+
+ File newFile = new File(filepath);
+ if(!newFile.exists()) { // for some reason ClustalW failed.
+
+ String text = "\n ClustalW output not found!\n";
+ OpenDialog od = new OpenDialog(rw);
+ od.showDialog("Error!", text);
+ rw.setRawData(rw.seqs);
+ rw.setScrollPanes();
+
+ } else { // guide tree is fine.
+
+ TreeReader tr = new TreeReader();
+ String[] treeNodes = tr.getAllNodes(filepath);
+ CheckTreeAndData chk = new CheckTreeAndData(treeNodes, rw.seqs);
+
+ if(chk.nodesAreSame()) {
+ String tree = tr.readFile(filepath);
+ TreeNode tn = new TreeNode(tree);
+ tree = tn.findMiddlePoint();
+
+ rw.setRawDataAndTree(tree);
+ rw.setScrollPanes();
+
+ } else {
+
+ String text = new String("\n Guide tree and sequence \n"+
+ " file do not match!\n");
+ OpenDialog od = new OpenDialog(rw);
+ od.showDialog("Warning!", text);
+
+ ProAlign.log.println("ClustalW: nodes and names do not match!");
+
+ }
+ }
+ }
+
+ public int numArg(String cmnd,String csep) {
+ int narg = 0;
+ for(int i = 0, j = 0; i < cmnd.length();) {
+ j = cmnd.indexOf(csep, i);
+ if (j >= i){
+ narg++;
+ i = j;
+ }
+ i++;
+ }
+ return narg;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RunCommandLine.java b/RunCommandLine.java
new file mode 100644
index 0000000..8408a5e
--- /dev/null
+++ b/RunCommandLine.java
@@ -0,0 +1,209 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.util.HashMap;
+
+public class RunCommandLine {
+
+ ProAlign pa;
+ PwAlignment pwa;
+ PwAlignmentLoop pwal;
+ AlignmentNode root;
+
+ public RunCommandLine(ProAlign pa) throws Exception {
+
+ ProAlign.log("RunCommandLine");
+
+ this.pa = pa;
+ SequenceReader sr = new SequenceReader();
+
+ if(pa.seqfile != null && new File(pa.seqfile).exists()) {
+
+ // ..and it's a valid file,
+ if(sr.fromFile(pa.seqfile)) {
+ pa.seqs = sr.getSequences();
+
+ CheckSequence cs = new CheckSequence();
+ if(cs.isDna(pa.seqs)){
+ pa.sm.jcDnaModel();
+ ProAlign.isDna = true;
+ } else {
+ if(ProAlign.protModel.equals("dayhoff")) {
+ pa.sm.dayhoffProteinModel();
+ } else if(ProAlign.protModel.equals("jtt")) {
+ pa.sm.jttProteinModel();
+ } else {
+ pa.sm.wagProteinModel();
+ }
+ ProAlign.isDna = false;
+ }
+ if(!cs.isFromAlphabet(pa.seqs,pa.sm.equateAlphabet)) {
+ ProAlign.log.println("Sequence reading error: Illegal characters!");
+ System.out.println("Sequence reading error: Illegal characters!");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+ throw new Exception("Sequence reading error: Illegal characters");
+ }
+ }
+ } else {
+ String msg = sr.getErrors();
+ ProAlign.log.println(msg);
+ System.out.println(msg);
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+ throw new Exception("Sequence reading error");
+ }
+ }
+ } else {
+ ProAlign.log.println("Sequence file doesn't exist!");
+ System.out.println("Sequence file doesn't exist!");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+ throw new Exception("Sequence file doesn't exist");
+ }
+ }
+
+ String tree = new String();
+ TreeReader tr = new TreeReader();
+
+ // do a new tree
+
+ PwSubstitutionMatrix psm = new PwSubstitutionMatrix();
+ String pwAlphabet;
+ int[][] pwSubst;
+ int gOpen, gExt;
+
+ if(ProAlign.isDna){
+ pwAlphabet = psm.dnaAlphabet;
+ pwSubst = psm.swdna;
+ gOpen = -1*pa.pwDnaOpen;
+ gExt = -1*pa.pwDnaExt;
+
+ } else {
+
+ pwAlphabet = psm.protAlphabet;
+ if(pa.pwProtMatrix.equals("pam60")) {
+ pwSubst = psm.pam60;
+ } else if(pa.pwProtMatrix.equals("pam160")) {
+ pwSubst = psm.pam160;
+ } else if(pa.pwProtMatrix.equals("pam250")) {
+ pwSubst = psm.pam250;
+ } else {
+ pwSubst = psm.pam120;
+ }
+ gOpen = -1*pa.pwProtOpen;
+ gExt = -1*pa.pwProtExt;
+ }
+
+ pwa = new PwAlignment(pwSubst,gOpen,gExt,pwAlphabet,ProAlign.isDna);
+
+ if(pa.doTree) {
+
+ pwal = new PwAlignmentLoop(pwa,pa.seqs);
+ tree = pwal.getTree();
+
+ if(pa.treefile!=null) {
+ try {
+ OutFile newtree = new OutFile(pa.treefile);
+ newtree.println(tree);
+ newtree.close();
+ } catch(Exception e) { }
+
+ }
+ // open an existing tree file
+ } else if(pa.treefile != null && new File(pa.treefile).exists()) {
+
+ String[] treeNodes = tr.getAllNodes(pa.treefile);
+ CheckTreeAndData chk = new CheckTreeAndData(treeNodes,pa.seqs);
+
+ // ..and it's a valid file, set the tree.
+ if(chk.nodesAreSame()) {
+ tree = tr.readFile(pa.treefile);
+ if(tr.isUnRooted) {
+ TreeNode tn = new TreeNode(tree);
+ tree = tn.findMiddlePoint();
+ }
+ } else {
+ ProAlign.log.println("Sequence and tree files don't match!");
+ System.out.println("Sequence and tree files don't match!");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+ throw new Exception("Sequence and tree files don't match");
+ }
+ }
+ } else {
+ ProAlign.log.println("Tree file doesn't exist!");
+ System.out.println("Tree file doesn't exist!");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ }else {
+ throw new Exception("Tree file doesn't exist");
+ }
+ }
+
+
+ if(tree != null) {
+
+ root = new AlignmentNode(pa,tree,0f);
+
+//
+ if(ProAlign.estimateParameters) {
+ ParameterEstimates pe = new ParameterEstimates(RunCommandLine.this);
+
+ }
+//
+
+ try {
+ root.align();
+ } catch(TraceBackException tbe) {
+ String msg = tbe.getMessage();
+ ProAlign.log.println(msg);
+ System.out.println(msg);
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ }else {
+ throw new Exception(msg);
+ }
+ } catch(Exception e) {
+// System.out.println("RunCommandLine: throws an exception");
+ throw e;
+ }
+
+ // seems to be fine - save results.
+
+ if(pa.outformat==1) {
+ SaveData sd = new SaveData(pa.outfile,1,root);
+ } else if(pa.outformat==2){
+ SaveData sd = new SaveData(pa.outfile,2,root);
+ } else if(pa.outformat==3){
+ SaveData sd = new SaveData(pa.outfile,3,root);
+ } else if(pa.outformat==4){
+ SaveData sd = new SaveData(pa.outfile,4,root);
+ }
+
+ } else {
+
+ ProAlign.log.println("Problems with tree!");
+ System.out.println("Problems with tree!");
+ if(ProAlign.exitInError) {
+ System.exit(0);
+ } else {
+ throw new Exception("Problems with tree");
+ }
+ }
+ }
+}
diff --git a/RunMultiple.java b/RunMultiple.java
new file mode 100644
index 0000000..8200470
--- /dev/null
+++ b/RunMultiple.java
@@ -0,0 +1,103 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.io.DataInputStream;
+import java.io.BufferedInputStream;
+
+/**
+ * Running alignment in a separate thread
+ */
+public class RunMultiple extends Thread {
+
+ ResultWindow rw;
+
+ RunMultiple(ResultWindow rw) {
+
+ this.rw = rw;
+
+ ProAlign.log("RunMultiple");
+
+ start();
+ }
+
+ public void run() {
+
+ boolean isError = false;
+ String errorMsg = new String();
+
+ try {
+ rw.root.align();
+ } catch(TraceBackException tbe) {
+ isError = true;
+ errorMsg = tbe.getMessage();
+ } catch(Exception e) { }
+
+ if(isError) {
+
+ OpenDialog od = new OpenDialog(rw);
+ od.showDialog("Error!", "\n "+errorMsg+"\n Try to increase the band width.\n");
+
+ rw.file[1].setEnabled(true); // open alignment
+ rw.file[2].setEnabled(false); // save alignment
+ rw.data[0].setEnabled(true); // import data
+ rw.data[1].setEnabled(true); // import guide tree
+ rw.align[0].setEnabled(true); // do guide tree NOT YET
+ rw.align[1].setEnabled(true); // do multiple
+ rw.align[2].setEnabled(true); // do complete NOT YET
+ rw.align[3].setEnabled(true); // sample
+ rw.align[4].setEnabled(false); // remove gaps
+
+ rw.dm.setEnabled(true); // import
+ rw.em.setEnabled(false); // export
+
+ } else {
+
+ rw.setAlignedData(rw.root);
+ rw.setScrollPanes();
+
+ if(rw.root.isBandWarning()) {
+ String text = new String(
+ "\n Traceback path came very close\n to the band edge."+
+ " Alignment may\n not be the correct one!");
+ OpenDialog od = new OpenDialog(rw);
+ od.showDialog("Warning!",text);
+ }
+
+ if(!rw.root.isUnique()) {
+ String text = new String(
+ "\n There exist more than one possible\n alignment. The backtrace "+
+ "path was\n chosen "+rw.root.getSampleTimes()+" times randomly between\n"+
+ " two equally good alternatives.\n");
+ OpenDialog od = new OpenDialog(rw);
+ od.showDialog("Notice!",text);
+ }
+ }
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SampleAlignments.java b/SampleAlignments.java
new file mode 100644
index 0000000..1a9f435
--- /dev/null
+++ b/SampleAlignments.java
@@ -0,0 +1,446 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.JButton;
+import javax.swing.JRadioButton;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JTextField;
+import javax.swing.JTextArea;
+import javax.swing.JScrollPane;
+import javax.swing.JScrollBar;
+import java.awt.GridLayout;
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.ItemListener;
+import java.awt.event.ItemEvent;
+import java.io.File;
+import java.io.IOException;
+
+public class SampleAlignments extends JFrame {
+
+ JTextArea textOutput;
+ JTextField textNumber;
+ JCheckBox boxResult;
+ JCheckBox boxFolder;
+ JCheckBox boxNexus;
+ JCheckBox boxFasta;
+ JScrollPane sp;
+ JScrollBar sb;
+
+ String resultPath = new String("sample_result.csv");
+ String folderPath = new String("");
+ String nexusPath = new String("");
+ String fastaPath = new String("");
+ int numRun;
+
+ boolean writeResults = true;
+ boolean writeAlignments = false;
+ boolean writeNexus = false;
+ boolean writeFasta = false;
+ boolean isRunning = true;
+
+ OutFile resultOut;
+
+ int height = 300;
+ int width = 600;
+
+ ProAlign pa;
+ ResultWindow rw;
+ SampleAlignments sa;
+
+ SampleAlignments(ResultWindow rw) {
+
+ setTitle("Sample alignments");
+ this.rw = rw;
+ this.pa = rw.pa;
+ sa = this;
+
+ Font font = new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize);
+ try {
+ resultOut = new OutFile(resultPath);
+ } catch(IOException ioe) { }
+
+ JButton buttonResult = new JButton("Select");
+ buttonResult.setFont(font);
+ buttonResult.setActionCommand("result");
+ buttonResult.addActionListener(new ButtonL());
+ JButton buttonFolder = new JButton("Select");
+ buttonFolder.setFont(font);
+ buttonFolder.setActionCommand("folder");
+ buttonFolder.addActionListener(new ButtonL());
+ JButton buttonNexus = new JButton("Select");
+ buttonNexus.setFont(font);
+ buttonNexus.setActionCommand("nexus");
+ buttonNexus.addActionListener(new ButtonL());
+ JButton buttonFasta = new JButton("Select");
+ buttonFasta.setFont(font);
+ buttonFasta.setActionCommand("fasta");
+ buttonFasta.addActionListener(new ButtonL());
+ JButton buttonStart = new JButton("Start");
+ buttonStart.setFont(font);
+ buttonStart.setActionCommand("start");
+ buttonStart.addActionListener(new ButtonL());
+ JButton buttonStop = new JButton("Stop");
+ buttonStop.setFont(font);
+ buttonStop.setActionCommand("stop");
+ buttonStop.addActionListener(new ButtonL());
+ JButton buttonClose = new JButton("Close");
+ buttonClose.setFont(font);
+ buttonClose.setActionCommand("close");
+ buttonClose.addActionListener(new ButtonL());
+
+ JLabel labelHeader = new JLabel(" Sampling parameters");
+ labelHeader.setFont(font);
+ JLabel labelResult = new JLabel("Change file");
+ labelResult.setFont(font);
+ JLabel labelFolder = new JLabel("Change folder");
+ labelFolder.setFont(font);
+ JLabel labelNexus = new JLabel("Change folder");
+ labelNexus.setFont(font);
+ JLabel labelFasta = new JLabel("Change folder");
+ labelFasta.setFont(font);
+ JLabel labelNumber = new JLabel("Permutations");
+ labelNumber.setFont(font);
+ JLabel labelSample = new JLabel("Traceback route");
+ labelSample.setFont(font);
+
+ textNumber = new JTextField("100");
+ textNumber.setFont(font);
+
+ boxResult = new JCheckBox("Write results");
+ boxResult.setActionCommand("result");
+ boxResult.setFont(font);
+ if(writeResults) {
+ boxResult.setSelected(true);
+ } else {
+ boxResult.setSelected(false);
+ }
+
+ boxFolder = new JCheckBox("Save ."+ProAlign.fileExt);
+ boxFolder.setActionCommand("folder");
+ boxFolder.setFont(font);
+ boxFolder.setSelected(false);
+
+ boxNexus = new JCheckBox("Save .nex");
+ boxNexus.setActionCommand("nexus");
+ boxNexus.setFont(font);
+ boxNexus.setSelected(false);
+
+ boxFasta = new JCheckBox("Save .pir");
+ boxFasta.setActionCommand("fasta");
+ boxFasta.setFont(font);
+ boxFasta.setSelected(false);
+
+ JRadioButton traceBest = new JRadioButton("select best");
+ traceBest.setFont(font);
+ traceBest.setActionCommand("best");
+ JRadioButton traceSample = new JRadioButton("sample");
+ traceSample.setFont(font);
+ traceSample.setActionCommand("sample");
+ if(ProAlign.trackBest) {
+ traceBest.setSelected(true);
+ } else {
+ traceSample.setSelected(true);
+ }
+
+ CheckBoxListener chboxL = new CheckBoxListener();
+ boxResult.addItemListener(chboxL);
+ boxFolder.addItemListener(chboxL);
+ boxNexus.addItemListener(chboxL);
+ boxFasta.addItemListener(chboxL);
+
+ JPanel fullPanel = new JPanel();
+ fullPanel.setLayout(new GridLayout(1,2,15,15));
+ JPanel halfPanel = new JPanel();
+ halfPanel.setLayout(new GridLayout(10,1,5,5));
+
+ halfPanel.add(labelHeader);
+
+ JPanel pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(new JLabel());
+ pnl.add(labelNumber);
+ pnl.add(textNumber);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(boxResult);
+ pnl.add(labelResult);
+ pnl.add(buttonResult);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(boxFolder);
+ pnl.add(labelFolder);
+ pnl.add(buttonFolder);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(boxNexus);
+ pnl.add(labelNexus);
+ pnl.add(buttonNexus);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(boxFasta);
+ pnl.add(labelFasta);
+ pnl.add(buttonFasta);
+ halfPanel.add(pnl);
+
+ ButtonGroup traceBack = new ButtonGroup();
+ traceBack.add(traceBest);
+ traceBack.add(traceSample);
+
+ RadioListener radioL = new RadioListener();
+ traceBest.addActionListener(radioL);
+ traceSample.addActionListener(radioL);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(labelSample);
+ pnl.add(traceBest);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(new JPanel());
+ pnl.add(traceSample);
+ halfPanel.add(pnl);
+
+ halfPanel.add(new JPanel());
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(buttonStart);
+ pnl.add(buttonStop);
+ pnl.add(buttonClose);
+ halfPanel.add(pnl);
+
+ fullPanel.add(halfPanel);
+
+
+ textOutput = new JTextArea();
+ textOutput.setFont(font);
+
+ sp = new JScrollPane(textOutput,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
+ JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
+ sb = sp.getVerticalScrollBar();
+
+ fullPanel.add(sp);
+
+ Container cp = getContentPane();
+ cp.add(fullPanel);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ dispose();
+ }
+ });
+ }
+
+ public void write(String str) {
+ if (str != "") {
+ textOutput.append(" " + str + " \n");
+ sb.setValue(sb.getMaximum());
+ }
+ }
+
+ class ButtonL implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JButton target = (JButton)e.getSource();
+ String actionCommand = target.getActionCommand();
+
+ if(actionCommand.equals("result")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(SampleAlignments.this,"Save",false);
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ resultOut.close();
+ try {
+ resultOut = new OutFile(filepath);
+ } catch(IOException ioe) { }
+ sa.write("result file is: "+filepath);
+ resultPath = filepath;
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("folder")) {
+
+ OpenFolderChooser opf =
+ new OpenFolderChooser(SampleAlignments.this,"Select");
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ folderPath = filepath;
+ sa.write("alignment folder is: "+new File(folderPath).getAbsolutePath());
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("nexus")) {
+
+ OpenFolderChooser opf =
+ new OpenFolderChooser(SampleAlignments.this,"Select");
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ nexusPath = filepath;
+ sa.write("nexus folder is: "+new File(nexusPath).getAbsolutePath());
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("fasta")) {
+
+ OpenFolderChooser opf =
+ new OpenFolderChooser(SampleAlignments.this,"Select");
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ fastaPath = filepath;
+ sa.write("fasta folder is: "+new File(fastaPath).getAbsolutePath());
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("start")) {
+
+ while(true) {
+ try{
+ int maxRun = new Integer(textNumber.getText()).intValue();
+ if(maxRun>0) {
+ numRun = maxRun;
+ } else {
+ String text = new String("\n Illegal value! \n");
+ OpenDialog od = new OpenDialog(SampleAlignments.this);
+ od.showDialog("Error!", text);
+ break;
+ }
+ if(ProAlign.DEBUG) {
+ ProAlign.log("SampleAlignments");
+ ProAlign.log("resultPath="+resultPath+","+writeResults);
+ ProAlign.log("folderPath="+folderPath+","+writeAlignments);
+ ProAlign.log("nexusPath="+nexusPath+","+writeNexus);
+ ProAlign.log("fastaPath="+fastaPath+","+writeFasta);
+ ProAlign.log("numRun="+numRun);
+ ProAlign.log("trackBest="+ProAlign.trackBest);
+ ProAlign.log.flush();
+ }
+ } catch(NumberFormatException nfe) {
+ String text = new String("\n Illegal value! \n");
+ OpenDialog od = new OpenDialog(SampleAlignments.this);
+ od.showDialog("Error!", text);
+ break;
+ }
+
+ SampleLoop sl = new SampleLoop(SampleAlignments.this);
+ break;
+ }
+
+ } else if(actionCommand.equals("stop")) {
+
+ isRunning = false;
+
+ } else if(actionCommand.equals("close")) {
+
+ dispatchEvent(new WindowEvent(SampleAlignments.this,
+ WindowEvent.WINDOW_CLOSING));
+ }
+ }
+ }
+
+
+ class CheckBoxListener implements ItemListener {
+ public void itemStateChanged(ItemEvent e) {
+
+ JCheckBox target = (JCheckBox)e.getItem();
+ String actionCommand = target.getActionCommand();
+
+ if(actionCommand.equals("result")) {
+
+ if (e.getStateChange() == ItemEvent.DESELECTED) {
+ writeResults = false;
+ sa.write("writing results stopped!");
+ } else {
+ writeResults = true;
+ sa.write("writing results started.");
+ }
+
+ } else if(actionCommand.equals("folder")) {
+
+ if (e.getStateChange() == ItemEvent.DESELECTED) {
+ writeAlignments = false;
+ sa.write("sampled alignments are not saved!");
+ } else {
+ writeAlignments = true;
+ sa.write("all sampled alignments are saved.");
+ }
+
+ } else if(actionCommand.equals("nexus")) {
+
+ if (e.getStateChange() == ItemEvent.DESELECTED) {
+ writeNexus = false;
+ sa.write("nexus files are not saved!");
+ } else {
+ writeNexus = true;
+ sa.write("alignments are saved as nexus files.");
+ }
+
+ } else if(actionCommand.equals("fasta")) {
+
+ if (e.getStateChange() == ItemEvent.DESELECTED) {
+ writeFasta = false;
+ sa.write("fasta files are not saved!");
+ } else {
+ writeFasta = true;
+ sa.write("alignments are saved as fasta files.");
+ }
+ }
+ }
+ }
+
+ class RadioListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ String actionCommand = e.getActionCommand();
+
+ if(actionCommand.equals("sample")) {
+
+ ProAlign.trackBest = false;
+
+ } else if(actionCommand.equals("best")) {
+
+ ProAlign.trackBest = true;
+ }
+ }
+ }
+}
diff --git a/SampleLoop.java b/SampleLoop.java
new file mode 100644
index 0000000..adb007c
--- /dev/null
+++ b/SampleLoop.java
@@ -0,0 +1,146 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.FileOutputStream;
+import java.io.ObjectOutputStream;
+
+class SampleLoop extends Thread {
+
+ SampleAlignments sl;
+ AlignmentNode best;
+ AlignmentNode current;
+
+ double bestEnd = 0d;
+
+ int currentRun = 0;
+ int maxRun;
+
+ SampleLoop(SampleAlignments sl) {
+
+ this.sl = sl;
+ current = sl.rw.root;
+ maxRun = sl.numRun;
+
+ ProAlign.log("SampleLoop");
+
+ sl.write("\n Sampling "+maxRun+" alignments: ");
+ if(sl.writeResults) {
+ String[] names = current.getInternalNames();
+ String str = "number,length,total";
+ for(int i=0; i<names.length; i++) {
+ str += ","+names[i];
+ }
+ sl.resultOut.println(str);
+ sl.resultOut.flush();
+ }
+
+ start();
+
+ }
+
+ public void run(){
+
+ while(sl.isRunning && currentRun < maxRun) {
+
+ boolean isError = false;
+ String errorMsg = new String();
+ try {
+ current.align();
+ } catch(TraceBackException tbe) {
+ isError = true;
+ errorMsg = tbe.getMessage();
+ } catch(Exception e) { }
+
+ // Threw an exception during the alignment
+ if(isError) {
+
+ OpenDialog od = new OpenDialog(sl);
+ od.showDialog("Error!", "\n "+errorMsg+"\n Try to increase the band width.\n");
+ break;
+
+ } else {
+
+ if(current.isBandWarning()) {
+ sl.write("Traceback path came very close\n to the band edge."+
+ " Alignment may\n not be the correct one!");
+ }
+
+ }
+
+ if(currentRun==0) {
+ bestEnd = current.sumViterbiEnd();
+ sl.rw.root = current;
+ sl.rw.setAlignedData(sl.rw.root);
+ sl.rw.setScrollPanes();
+ sl.rw.messageText.setText(" Sample "+(currentRun+1)+"/"+maxRun+": "+current.sumViterbiEnd());
+
+ } else if (current.sumViterbiEnd() > bestEnd) {
+ bestEnd = current.sumViterbiEnd();
+ sl.rw.root = current;
+ sl.rw.setAlignedData(sl.rw.root);
+ sl.rw.setScrollPanes();
+ sl.rw.messageText.setText(" Sample "+(currentRun+1)+"/"+maxRun+": "+current.sumViterbiEnd());
+ }
+ if(sl.writeAlignments) {
+
+ String path = sl.folderPath+File.separator+(currentRun+1)+"."+ProAlign.fileExt;
+ try {
+ ObjectOutputStream os =
+ new ObjectOutputStream(new FileOutputStream(path));
+ os.writeObject((AlignmentNode) current);
+ os.flush();
+ os.close();
+ } catch(IOException ioe) {
+ ProAlign.log.println("Sample exception1: "+path+"\n"+ioe.toString());
+ ProAlign.log.flush();
+ //ioe.printStackTrace();
+ }
+ catch(Exception oe) {
+ ProAlign.log.println("Sample exception2: "+path+"\n"+oe.toString());
+ ProAlign.log.flush();
+ //oe.printStackTrace();
+ }
+ }
+
+ if(sl.writeNexus) {
+ String path = sl.nexusPath+File.separator+(currentRun+1)+".nex";
+ SaveData sd = new SaveData(path,1,current);
+ }
+ if(sl.writeFasta) {
+ String path = sl.fastaPath+File.separator+(currentRun+1)+".pir";
+ SaveData sd = new SaveData(path,2,current);
+ }
+
+ sl.write("Sample "+(currentRun+1)+"/"+maxRun+": "+current.sumViterbiEnd()+"; best: "+bestEnd);
+
+ if(sl.writeResults) {
+
+ double[] vit = current.getInternalViterbiEnd();
+ String str = (currentRun+1)+","+current.cellPath.length+","+current.sumViterbiEnd();
+ for(int i=0; i<vit.length; i++) {
+ str += ","+vit[i];
+ }
+ sl.resultOut.println(str);
+ sl.resultOut.flush();
+ }
+ if(ProAlign.DEBUG) {
+ ProAlign.log.println(" sample number "+currentRun);
+ ProAlign.log.flush();
+ }
+
+ currentRun++;
+ }
+ }
+}
diff --git a/SaveData.java b/SaveData.java
new file mode 100644
index 0000000..22ee7c8
--- /dev/null
+++ b/SaveData.java
@@ -0,0 +1,854 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JOptionPane;
+import java.io.File;
+import java.io.IOException;
+import java.util.Calendar;
+import java.util.Date;
+
+public class SaveData {
+
+ boolean[] sitesRemoved;
+ boolean[] taxaRemoved;
+
+ String filename;
+ String resultString;
+
+ String[] sequenceNames;
+ String[] sequenceData;
+
+ String spaceStr = " ";
+ int taxaNum;
+ int seqLength;
+
+ int numTaxa;
+ int numSite;
+
+ AlignmentNode root;
+
+ double[] minProb;
+
+//
+ public SaveData(String file, int type, AlignmentNode root) {
+
+ ProAlign.log("SaveData");
+
+ this.root = root;
+ resultString = "vitEnd: "+root.sumViterbiEnd()+", fwdEnd: "+root.sumForwardEnd();
+
+ sequenceNames = root.getTerminalNames();
+ for(int i=0; i<sequenceNames.length; i++) {
+ sequenceNames[i] = (sequenceNames[i]+spaceStr).substring(0,21);
+ }
+
+ sequenceData = new String[root.getNumChild()];
+ for(int i=0; i<sequenceData.length; i++) { sequenceData[i] = ""; }
+ for(int i=0; i<root.cellPath.length; i++) {
+
+ int h = 0;
+ char[] c0 = root.child[0].getCharacterAt(root.cellPath[i][0]-2);
+ char[] c1 = root.child[1].getCharacterAt(root.cellPath[i][1]-2);
+
+ for(int j=0; j<c0.length; j++) {
+ sequenceData[h++] += c0[j];
+ }
+ for(int j=0; j<c1.length; j++) {
+ sequenceData[h++] += c1[j];
+ }
+ }
+
+ sitesRemoved = new boolean[sequenceData[0].length()];
+ taxaRemoved = new boolean[sequenceNames.length];
+
+ taxaNum = sequenceNames.length;
+ seqLength = sequenceData[0].length();
+
+ minProb = new double[root.cellPath.length];
+ for(int i=0; i<root.cellPath.length; i++) {
+ minProb[i] = Math.exp(root.getMinimumInternalPostProbAt(i));
+ }
+
+ if(type==1) {
+ outputNexus(file,1);
+ } else if(type==2) {
+ outputFasta(file);
+ } else if(type==3) {
+ outputPhylip(file);
+ } else if(type==4) {
+ outputMsf(file);
+ }
+
+ if(ProAlign.writeRoot) {
+ writeRoot(file);
+ }
+ }
+
+//
+
+ public SaveData(String type, ResultWindow rw) {
+
+ ProAlign.log("SaveData");
+
+ this.root = rw.root;
+ resultString = "vitEnd: "+rw.root.sumViterbiEnd()+", fwdEnd: "+rw.root.sumForwardEnd();
+
+ sitesRemoved = rw.seqcont.getRemovedSites();
+ taxaRemoved = rw.seqname.getRemovedTaxa();
+
+ sequenceData = rw.seqcont.textArray;
+ sequenceNames = rw.seqname.textArray;
+
+ taxaNum = sequenceNames.length;
+ seqLength = sequenceData[0].length();
+
+ minProb = new double[rw.root.cellPath.length];
+ for(int i=0; i<rw.root.cellPath.length; i++) {
+ minProb[i] = Math.exp(rw.root.getMinimumInternalPostProbAt(i));
+ }
+
+
+ OpenFileChooser opf =
+ new OpenFileChooser(rw,"Save "+type,false);
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+
+ if(type.equals("Nexus")) {
+ Object[] options = {"interleaved",
+ "sequential"};
+ int n = JOptionPane.showOptionDialog(rw,"Do you want your alignment "+
+ "interleaved or sequential?","Nexus format",
+ JOptionPane.YES_NO_OPTION,
+ JOptionPane.PLAIN_MESSAGE,
+ null,options,options[0]);
+ if(n==JOptionPane.YES_OPTION) {
+ outputNexus(filepath,1);
+ } else if(n==JOptionPane.NO_OPTION) {
+ outputNexus(filepath,2);
+ }
+ } else if(type.equals("Fasta")) {
+ outputFasta(filepath);
+ } else if(type.equals("Phylip")) {
+ outputPhylip(filepath);
+ } else if(type.equals("MSF")) {
+ outputMsf(filepath);
+ }
+
+ if(ProAlign.writeRoot) {
+ writeRoot(filepath);
+ }
+
+ }
+ }
+
+
+ // Write data in nexus format.
+ //
+ public void outputNexus(String file,int type) {
+
+ try {
+
+ OutFile out = new OutFile(file);
+
+ // Write the intro.
+ out.println("#NEXUS");
+ String date = Calendar.getInstance().getTime().toString();
+ out.println("[ ProAlign - "+date+" ]\n");
+ out.println("Begin data;");
+ out.println(" Dimensions ntax=" + taxaNum +
+ " nchar=" + seqLength + ";");
+ if(ProAlign.isDna) {
+ out.print(" Format datatype=nucleotide");
+ } else {
+ out.print(" Format datatype=protein");
+ }
+ if(type == 1)
+ out.print(" interleave");
+ out.println(" missing=-;");
+
+ // Write the matrix.
+ out.println(" Matrix");
+
+ int k = 0, j = 0, max = 0;
+
+ if (type == 1) { // nexus interleaved
+
+ while(true) {
+
+ for(int i = 0; i < taxaNum; ++i) {
+ j = k;
+ String str = "";
+ str = ((sequenceNames[i]+spaceStr).substring(0,21) + " ");
+ int count = 0;
+ for(int m = 0; m < 100; m++) {
+ if (j >= (seqLength)) {
+ break;
+ }
+ str += (""+sequenceData[i].charAt(j++));
+ if(m > 0)
+ if((m+1) % 20 == 0) {
+ str += (" ");
+ }
+ }
+ out.println(str);
+ }
+ out.println("");
+ if(j >= (seqLength)) {
+ break;
+ }
+ k += 100;
+ }
+
+ } else { // nexus sequential
+ for(int i = 0; i < taxaNum; ++i) {
+ out.print((sequenceNames[i]+spaceStr).substring(0,21) + " ");
+ out.println(sequenceData[i]);
+ }
+ }
+
+ out.println(" ;\nEnd;\n");
+
+ // Write the paup block.
+ out.println("Begin paup;");
+
+ // Delete sequnces
+ String str = " Delete";
+ for (int i = 0; i < taxaNum; i++) {
+ if(taxaRemoved[i]) {
+ str += (" "+(sequenceNames[i]+spaceStr).substring(0,21).trim());
+ }
+ }
+ str += ";";
+ out.println(str);
+
+ // Exclude sites
+ boolean exc = false;
+ int prev = 0; int start = 0;
+
+ str = " Exclude";
+ for (int n = 0; n < sitesRemoved.length; n++) {
+ if(sitesRemoved[n]) {
+ prev = n;
+ if(!exc) {
+ // array starts form 0, Nexus matrix from 1!
+ str += (" " + (n+1));
+ start = n;
+ exc = true;
+ }
+ } else {
+ if(exc) {
+ if (start != prev)
+ str += ("-" + (prev+1));
+ exc = false;
+ }
+ }
+ }
+ if(exc)
+ if (start != prev)
+ str += ("-" + (prev+1));
+ str += ";";
+ out.println(str);
+
+ out.println("End;\n");
+
+ // Write the assumptions block.
+ out.println("Begin assumptions;");
+ str = " wtset ProAlignWeights (VECTOR) = \n ";
+ for (int i = 0; i < minProb.length; i++) {
+ str += (roundDoubleToString((double)minProb[i],3)+" ").substring(0,5)+" ";
+ if(type==1 && i>0 && (i+1)%15==0)
+ str += "\n ";
+ }
+ str += ";";
+ out.println(str);
+
+ out.println("End;\n");
+
+ out.close();
+ } catch (IOException e) { }
+ }
+
+
+
+ // Write data in fasta format.
+ //
+ public void outputFasta(String file) {
+
+ try {
+ OutFile out = new OutFile(file);
+
+ for(int i = 0; i < taxaNum; i++) {
+ if(!taxaRemoved[i]) {
+ if(ProAlign.isDna) {
+ out.println(">DL;" + sequenceNames[i].trim()+"\n");
+ } else {
+ out.println(">P1;" + sequenceNames[i].trim()+"\n");
+ }
+ int count = 0;
+ for(int j = 0; j < seqLength; j++) {
+ if(!sitesRemoved[j]) {
+ count++;
+ out.print(sequenceData[i].charAt(j));
+ if(count == 50) {
+ out.println("");
+ count = 0;
+ }
+ }
+ }
+ out.println("*");
+ }
+ }
+
+ out.close();
+ } catch (IOException e) {
+ }
+
+ if(ProAlign.writeMin) {
+ outputWeights(file+".min", false);
+ }
+ if(ProAlign.writeMean) {
+ outputMean(file+".mean", false);
+ }
+ if(ProAlign.writeAll) {
+ outputAll(file+".all", false);
+ }
+ }
+
+
+ //
+ // Write data table in given file in phylip int. format.
+ //
+ public void outputPhylip(String file) {
+
+ numTaxa=0;
+ for(int i = 0; i < taxaNum; i++) {
+ if(!taxaRemoved[i]) {
+ numTaxa++;
+ }
+ }
+ numSite=0;
+ for(int j = 0; j < seqLength; j++) {
+ if(!sitesRemoved[j]) {
+ numSite++;
+ }
+ }
+
+ try {
+ OutFile out = new OutFile(file);
+
+ int k = 0;
+ int j = 0;
+ int max = 0;
+ boolean newline = true;
+
+ out.println(" "+numTaxa+" "+numSite);
+
+ while(true) {
+ for(int i = 0; i < taxaNum; i++) {
+ newline = true;
+ j = k;
+ if(!taxaRemoved[i]) {
+ if(k == 0)
+ out.print((sequenceNames[i].trim()+
+ spaceStr).substring(0,10) + " ");
+ else
+ out.print(" ");
+
+ int count = 0;
+ while(count < 50) {
+ if (j >= seqLength) {
+ max = j;
+ break;
+ }
+
+ else if(!sitesRemoved[j]) {
+ out.print(sequenceData[i].charAt(j));
+ count++;
+ if(count % 50 == 0) {
+ out.print("");
+ } else if(count % 10 == 0)
+ out.print(" ");
+ }
+ j++;
+ }
+ max = j;
+ out.println("");
+ } else {
+ newline = false;
+ }
+ }
+ if (newline)
+ //out.println("");
+ if(max >= seqLength) {
+ break;
+ }
+ k = max;
+ out.println("");
+ }
+
+ out.close();
+ } catch (IOException e) {
+ }
+
+ if(ProAlign.writeMin) {
+ outputWeights(file+".min", false);
+ }
+ if(ProAlign.writeMean) {
+ outputMean(file+".mean", false);
+ }
+ if(ProAlign.writeAll) {
+ outputAll(file+".all", false);
+ }
+ }
+
+//
+
+ //
+ // Write data table in given file in phylip int. format.
+ //
+ public void outputMsf(String file) {
+
+ numSite=0;
+ for(int j = 0; j < seqLength; j++) {
+ if(!sitesRemoved[j]) {
+ numSite++;
+ }
+ }
+
+ try {
+ OutFile out = new OutFile(file);
+
+ int k = 0;
+ int j = 0;
+ int max = 0;
+ boolean newline = true;
+
+ out.println("PileUp\n");
+ out.print(" MSF: "+numSite);
+ if(ProAlign.isDna) {
+ out.println(" Type: N\n");
+ } else {
+ out.println(" Type: P\n");
+ }
+ for(int i = 0; i < taxaNum; i++) {
+ if(!taxaRemoved[i]) {
+ out.println(" Name: "+(sequenceNames[i].trim()
+ +spaceStr).substring(0,21) + " ");
+ }
+ }
+ out.println("\n//\n");
+
+ while(true) {
+ for(int i = 0; i < taxaNum; i++) {
+ newline = true;
+ j = k;
+ if(!taxaRemoved[i]) {
+ out.print((sequenceNames[i].trim()
+ +spaceStr).substring(0,21) + " ");
+
+ int count = 0;
+ while(count < 50) {
+ if (j >= seqLength) {
+ max = j;
+ break;
+ }
+
+ else if(!sitesRemoved[j]) {
+ out.print(sequenceData[i].charAt(j));
+ count++;
+ if(count % 50 == 0) {
+ out.print("");
+ } else if(count % 10 == 0)
+ out.print(" ");
+ }
+ j++;
+ }
+ max = j;
+ out.println("");
+ } else {
+ newline = false;
+ }
+ }
+ if (newline)
+ //out.println("");
+ if(max >= seqLength) {
+ break;
+ }
+ k = max;
+ out.println("");
+ }
+
+ out.close();
+ } catch (IOException e) {
+ }
+
+ if(ProAlign.writeMin) {
+ outputWeights(file+".min", false);
+ }
+ if(ProAlign.writeMean) {
+ outputMean(file+".mean", false);
+ }
+ if(ProAlign.writeAll) {
+ outputAll(file+".all", false);
+ }
+ }
+
+//
+
+
+ // Write probabilities in plain text format.
+ //
+ public void outputWeights(String file, boolean all) {
+ if (all) {
+ double min=0d;
+ int nc=0;
+ for (int i = 0; i < minProb.length; i++) {
+ min+=minProb[i];
+ nc++;
+ }
+ min=min/nc;
+
+ double mean=0d;
+ nc=0;
+ for (int i=0; i<seqLength; i++) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ mean+=sum;
+ nc++;
+ }
+ mean=mean/nc;
+
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: minimum posterior probability.\n");
+ out.print("# "+resultString+", averMin: "+min+", averAll: "+mean+".\n");
+ for (int i = 0; i < minProb.length; i++) {
+ out.print((roundDoubleToString((double)minProb[i],3)+" ").substring(0,5)+" ");
+ if(i>0 && (i+1)%20==0)
+ out.print("\n");
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ }
+ }else {
+ double min=0d;
+ int nc=0;
+ for (int i = 0; i < minProb.length; i++) {
+ if(!sitesRemoved[i]) {
+ min+=minProb[i];
+ nc++;
+ }
+ }
+ min=min/nc;
+
+ double mean=0d;
+ nc=0;
+ for (int i=0; i<seqLength; i++) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ mean+=sum;
+ nc++;
+ }
+ mean=mean/nc;
+
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: minimum posterior probability.\n");
+ out.print("# "+resultString+", averMin: "+min+", averAll: "+mean+".\n");
+ int count = 1;
+ for (int i = 0; i < minProb.length; i++) {
+ if(!sitesRemoved[i]) {
+ out.print((roundDoubleToString((double)minProb[i],3)+" ").substring(0,5)+" ");
+ if((count%20)==0)
+ out.print("\n");
+ count++;
+ }
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ // Write mean probabilities in plain text format.
+ //
+ public void outputMean(String file, boolean all) {
+ if (all) {
+ double min=0d;
+ int nc=0;
+ for (int i = 0; i < minProb.length; i++) {
+ if(!sitesRemoved[i]) {
+ min+=minProb[i];
+ nc++;
+ }
+ }
+ min=min/nc;
+
+ double mean=0d;
+ nc=0;
+ for (int i=0; i<seqLength; i++) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ mean+=sum;
+ nc++;
+ }
+ mean=mean/nc;
+
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: mean posterior probability.\n");
+ out.print("# "+resultString+", averMin: "+min+", averAll: "+mean+".\n");
+ for (int i=0; i<seqLength; i++) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ out.print((roundDoubleToString((double)sum,3)+" ").substring(0,5)+" ");
+ if(i>0 && (i+1)%20==0)
+ out.print("\n");
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ }
+ }else {
+ double min=0d;
+ int nc=0;
+ for (int i = 0; i < minProb.length; i++) {
+ if(!sitesRemoved[i]) {
+ min+=minProb[i];
+ nc++;
+ }
+ }
+ min=min/nc;
+
+ double mean=0d;
+ nc=0;
+ for (int i=0; i<seqLength; i++) {
+ if(!sitesRemoved[i]) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ mean+=sum;
+ nc++;
+ }
+ }
+ mean=mean/nc;
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: mean posterior probability.\n");
+ out.print("# "+resultString+", averMin: "+min+", averAll: "+mean+".\n");
+ int count = 1;
+ for (int i = 0; i < seqLength; i++) {
+ if(!sitesRemoved[i]) {
+ double[] column = root.getInternalPostProbAt(i);
+ double sum = 0d;
+ int cn=0;
+ for (int j=0; j<column.length; j++) {
+ if(column[j]!=Double.NEGATIVE_INFINITY) {
+ sum+=Math.exp(column[j]);
+ cn++;
+ }
+ }
+ sum=sum/cn;
+ out.print((roundDoubleToString((double)sum,3)+" ").substring(0,5)+" ");
+ if((count%20)==0)
+ out.print("\n");
+ count++;
+ }
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+
+ // Write all probabilities in plain text format.
+ //
+ public void outputAll(String file, boolean all) {
+ if (all) {
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: all posterior probability.\n");
+ out.print("# "+resultString+".\n");
+ String[] nodeNames = root.getInternalNames();
+ for (int j=0; j<root.getNumChild()-1; j++) {
+ out.print("# "+nodeNames[j]+".\n");
+ for (int i=0; i<seqLength; i++) {
+ double[] column = root.getInternalPostProbAt(i);
+ out.print((roundDoubleToString((double)Math.exp(column[j]),3)+" ").substring(0,5)+" ");
+ if(i>0 && (i+1)%20==0)
+ out.print("\n");
+ }
+ out.print("\n");
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ }
+ }else {
+ try {
+ OutFile out = new OutFile(file);
+ out.print("# ProAlign: mean posterior probability.\n");
+ out.print("# "+resultString+".\n");
+ String[] nodeNames = root.getInternalNames();
+ for (int j=0; j<root.getNumChild()-1; j++) {
+ out.print("# "+nodeNames[j]+".\n");
+ int count = 1;
+ for (int i = 0; i < seqLength; i++) {
+ if(!sitesRemoved[i]) {
+ double[] column = root.getInternalPostProbAt(i);
+ out.print((roundDoubleToString((double)Math.exp(column[j]),3)+" ").substring(0,5)+" ");
+ if((count%20)==0)
+ out.print("\n");
+ count++;
+ }
+ }
+ out.print("\n");
+ }
+ out.print("\n");
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // Write root character probabilities
+ //
+ public void writeRoot(String file) {
+
+ try {
+ OutFile out = new OutFile(file+".root");
+
+ for(int i=0; i<root.charProb.length; i++) {
+ out.print(i+1);
+ for(int j=0; j<root.charProb[i].length; j++) {
+ out.print(" "+root.charProb[i][j]);
+ }
+ out.println();
+ }
+
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // Round a value to certain precision
+ //
+ public String roundDoubleToString(double val, int prec) {
+ String full = ""+val;
+ if(full.indexOf('.')>-1) {
+ String begin = full.substring(0,full.indexOf('.'));
+ String end = full.substring(full.indexOf('.')+1);
+ if(end.length()>prec) {
+ char num = end.charAt(prec);
+ if(num=='0'||num=='1'||num=='2'||num=='3'||num=='4') {
+ full = begin+"."+end.substring(0,prec);
+
+ // last one is greater than 4 -> rounded up
+ } else {
+ char[] digit = new char[prec];
+ for(int i=0; i<prec; i++) {
+ digit[i] = end.charAt(i);
+ }
+
+ int add = 1;
+ for(int i=prec-1; i>=0; i--) {
+ if(digit[i]=='9') {
+ add = 1;
+ digit[i]='0';
+ } else {
+ digit[i]= (char)((int)digit[i]+add);
+ add = 0;
+ break;
+ }
+ }
+ begin = ""+(new Integer(begin).intValue()+add);
+ end = new String();
+ for(int i=0; i<prec; i++) {
+ end += digit[i];
+ }
+ full = begin+"."+end;
+ }
+ }
+ }
+ return full;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SequenceReader.java b/SequenceReader.java
new file mode 100644
index 0000000..ee90cec
--- /dev/null
+++ b/SequenceReader.java
@@ -0,0 +1,641 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.util.Iterator;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+
+/**
+ * Reads FASTA/PIR format alignment files.
+ * Data read into a hashtable: String 'name', String 'data'
+ */
+public class SequenceReader {
+ String row, str1, str2 = new String();
+ HashMap seqmap;
+ boolean allFine;
+ String alphabet;
+ String errors;
+
+ SequenceReader() { }
+
+
+ /**
+ * Tries to read from a file. Returns TRUE if fine, FALSE if errors.
+ */
+ boolean fromFile(String infile) {
+
+ allFine = true;
+ seqmap = new HashMap();
+ errors = new String("\n");
+
+ ProAlign.log("SequenceReader: "+infile);
+
+ String firstRow = new String();
+ try {
+ InFile in = new InFile(infile);
+ while(true) {
+ firstRow = in.readLine().trim();
+ if(firstRow.equals("")) {
+ continue;
+ }
+ break;
+ }
+
+ } catch(FileNotFoundException e) {
+ warnError("File not found:" + infile);
+ } catch(IOException e) { }
+
+ if(firstRow.startsWith(">")) {
+ readFasta(infile);
+ } else if(Character.isDigit(firstRow.charAt(0))) {
+ readPhylip(infile);
+ } else if(firstRow.equalsIgnoreCase("#nexus")) {
+ readNexus(infile);
+ } else if(firstRow.equalsIgnoreCase("PileUp")||
+ firstRow.equalsIgnoreCase("!!AA_MULTIPLE_ALIGNMENT")||
+ firstRow.equalsIgnoreCase("!!NA_MULTIPLE_ALIGNMENT")) {
+ readMsf(infile);
+ } else {
+ warnError(" The file does not look like Fasta-,\n"+
+ " PIR-, Phylip-, MSF-, or Nexus-format!");
+ }
+
+ if(seqmap.size()>0 && allFine) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+
+ void readFasta(String infile) {
+
+ try {
+
+ // Calls ready-made filereader
+ InFile in = new InFile(infile);
+
+ int formatType = 0;
+
+ while(true) { // Read first non-empty line
+ row = in.readLine().trim();
+ if(row.equals("")) {
+ continue;
+ }
+ break;
+ }
+
+ while(row != null) {
+
+ // Takes sequence name and checks
+ // that same name doesn't exist
+ if(row.startsWith(">")) {
+ row = row.substring(1);
+ row = row.trim();
+
+ // Sequence is PIR
+ if(row.startsWith("DL;")) {
+ formatType = 1;
+ row = row.substring(3);
+ row = row.trim();
+ in.readLine(); // skip one row!
+
+ } else if(row.startsWith("P1;")) {
+ formatType = 2;
+ row = row.substring(3);
+ row = row.trim();
+ in.readLine(); // skip one row!
+
+ //Sequence must be FASTA
+ } else {
+ formatType = 0;
+ }
+
+ // Same sequence name given twice!!
+ if(seqmap.containsKey(row)) {
+ warnError(" Sequence " + row + "\n is double defined!");
+ }
+
+ if(formatType > 0) { // If PIR -> has to end with '*'
+
+ str2 = "";
+ while((str1 = in.readLine())!= null) {
+
+ // remove "gap" signs
+ if(str1.indexOf("-")>-1) {
+ str1 = removeChar(str1,'-');
+ }
+ if(str1.indexOf(" ")>-1) {
+ str1 = removeSpace(str1);
+ }
+
+ if(str1.length() == 0) { // Skips empty lines.
+ continue;
+ }
+
+ str2 += str1;
+
+ if(str1.endsWith("*")){ // Reads until the asterisk (needed!)
+
+ str1 = str2.substring(0,str2.indexOf("*")); // but removed.
+ str1 = str1.toUpperCase();
+
+ seqmap.put(row, str1);
+ ProAlign.log(">"+row+"\n"+str1);
+
+ row = in.readLine(); // New one in!
+ break;
+ }
+ }
+ }
+
+
+
+ // Append FASTA sequence and save it.
+ else { // If FASTA -> no '*' in the end
+
+ str2 = "";
+ while((str1 = in.readLine())!= null) {
+
+ // remove "gap" signs
+ if(str1.indexOf("-")>-1) {
+ str1 = removeChar(str1,'-');
+ }
+ if(str1.indexOf(" ")>-1) {
+ str1 = removeSpace(str1);
+ }
+
+ if(str1.length() == 0) { // Skips empty lines.
+ continue;
+ }
+
+ if(str1.startsWith(">")){ // Loop works until a new seqname
+
+ str2 = str2.toUpperCase();
+
+ seqmap.put(row, str2);
+ ProAlign.log(">"+row+"\n"+str2);
+
+ row = str1; // Copy new one
+ row = row.trim();
+ break;
+ }
+ str2 += str1;
+ }
+ if(str1 == null) { // Take the last seq. End of the file.
+
+ str2 = str2.toUpperCase();
+
+ seqmap.put(row, str2);
+ ProAlign.log(">"+row+"\n"+str2);
+
+ row = str1; // Copy null so first loop stops
+ }
+ }
+ } else if(row.trim().equals("")){
+ row = in.readLine();
+ continue;
+ } else {
+ warnError(" File '" + infile + "'\n"+
+ " is supposed to start with '>'!");
+ break;
+ //row = in.readLine();
+ }
+ }
+ in.close();
+
+ // Something wrong. Give warnings and return.
+ } catch(FileNotFoundException e) {
+ warnError("File not found:" + infile);
+
+ } catch(IOException e) { }
+ }
+
+ void readPhylip(String infile) {
+
+ String[] seqNames = new String[0];
+ String[] seqData = new String[0];
+
+ String row = new String();
+ try {
+ InFile in = new InFile(infile);
+ while(true) {
+ row = in.readLine().trim();
+ if(row.equals("")) {
+ continue;
+ }
+ break;
+ }
+
+ int numTaxa = new Integer(row.substring(0,row.indexOf(" ")).trim()).intValue();
+ int seqLength = new Integer(row.substring(row.indexOf(" ")+1).trim()).intValue();
+
+ seqNames = new String[numTaxa];
+ seqData = new String[numTaxa];
+
+ int sn = 0;
+ int rn = 0;
+ while((row = in.readLine())!= null) {
+ if(row.trim().equals("")) {
+ continue;
+ }
+ if(rn<numTaxa) {
+ seqNames[sn] = row.substring(0,row.indexOf(" ")).trim();
+ seqData[sn] = row.substring(row.indexOf(" ")+1).trim();
+ rn++; sn++;
+ } else {
+ seqData[sn++] += row.trim();
+ }
+ if(sn==numTaxa) {
+ sn=0;
+ }
+ }
+ in.close();
+
+ // Something wrong. Give warnings and return.
+ } catch(FileNotFoundException e) {
+ warnError("File not found:" + infile);
+
+ } catch(IOException e) { }
+
+ for(int i=0; i<seqNames.length; i++) {
+
+ if(seqmap.containsKey(seqNames[i])) {
+ warnError(" Sequence " +seqNames[i]+ "\n is double defined!");
+ }
+
+ String seq = removeSpace(seqData[i].toUpperCase());
+ seq = removeChar(seq,'-');
+
+ seqmap.put(seqNames[i],seq);
+ ProAlign.log(">"+seqNames[i]+"\n"+seq);
+ }
+ }
+
+
+ void readMsf(String infile) {
+
+ String[] seqNames = new String[0];
+ String[] seqData = new String[0];
+ HashMap names = new HashMap();
+
+ String row = new String();
+ try {
+ InFile in = new InFile(infile);
+ int s=0;
+ while(true) {
+ row = in.readLine().trim();
+ if(row.startsWith("//")) {
+ break;
+ } else if(row.indexOf("Name:")>-1) {
+ row = row.substring(row.indexOf("Name:")+5).trim();
+ if(row.indexOf(" ")>-1) {
+ row = row.substring(0,row.indexOf(" ")).trim();
+ }
+ names.put(row,new Integer(s));
+ s++;
+ } else {
+ continue;
+ }
+ }
+
+ seqNames = new String[names.size()];
+ seqData = new String[names.size()];
+
+ Iterator nameKeys = names.keySet().iterator();
+ while(nameKeys.hasNext()) {
+ String n = (String) nameKeys.next();
+ s = ((Integer)names.get(n)).intValue();
+ seqNames[s] = n;
+ seqData[s] = "";
+ }
+
+ while((row = in.readLine())!= null) {
+ if(row.trim().equals("")) {
+ continue;
+ }
+
+ String begin = row.substring(0,row.indexOf(" ")).trim();
+
+ if(names.containsKey(begin)) {
+
+ String end = row.substring(row.indexOf(" ")+1).trim();
+ s = ((Integer)names.get(begin)).intValue();
+ seqData[s] += end;
+
+ }
+ }
+ in.close();
+
+ // Something wrong. Give warnings and return.
+ } catch(FileNotFoundException e) {
+ warnError("File not found:" + infile);
+
+ } catch(IOException e) { }
+
+ for(int i=0; i<seqNames.length; i++) {
+
+ if(seqmap.containsKey(seqNames[i])) {
+ warnError(" Sequence " +seqNames[i]+ "\n is double defined!");
+ }
+
+ String seq = removeSpace(seqData[i].toUpperCase());
+ seq = removeChar(seq,'-');
+ seq = removeChar(seq,'.');
+ seq = removeChar(seq,'~');
+
+ seqmap.put(seqNames[i],seq);
+ ProAlign.log(">"+seqNames[i]+"\n"+seq);
+ }
+//
+ ProAlign.log.print("CORE ");
+ for(int m=0; m<seqData[0].length(); m++) {
+ if(Character.isUpperCase(seqData[0].charAt(m))) {
+ ProAlign.log.print("1");
+ } else {
+ ProAlign.log.print("0");
+ }
+ }
+ ProAlign.log.println();
+//
+ }
+
+
+
+ void readNexus(String infile) {
+
+ String[] seqNames = new String[0];
+ String[] seqData = new String[0];
+ String missing = new String("?");
+
+ try {
+
+ // Calls ready-made filereader
+ InFile in = new InFile(infile);
+ int order = 0;
+
+ int numChar = 0;
+ int numTaxa = 0;
+
+ boolean interleave = false;
+
+ String row = in.readLine(); // Read first line
+ while((row != null)) {
+
+ row = row.toUpperCase().trim();
+
+ if(row.startsWith("DIMENSIONS")) {
+ if(row.indexOf("NTAX")>-1) {
+ String ntax = row.substring(row.indexOf("NTAX"));
+ ntax = ntax.substring(ntax.indexOf("=")+1);
+ if(ntax.indexOf(" ")>0) {
+ ntax = ntax.substring(0,ntax.indexOf(" "));
+ } else {
+ ntax = ntax.substring(0,ntax.indexOf(";"));
+ }
+ numTaxa = Integer.valueOf(ntax).intValue();
+ }
+ if(row.indexOf("NCHAR")>-1) {
+ String nchar = row.substring(row.indexOf("NCHAR"));
+ nchar = nchar.substring(nchar.indexOf("=")+1);
+ if(nchar.indexOf(" ")>0) {
+ nchar = nchar.substring(0,nchar.indexOf(" "));
+ } else {
+ nchar = nchar.substring(0,nchar.indexOf(";"));
+ }
+ numChar = Integer.valueOf(nchar).intValue();
+ }
+ }
+
+ if(row.indexOf("MISSING")>-1) {
+ missing = row.substring(row.indexOf("MISSING"));
+ missing = missing.substring(missing.indexOf("=")+1);
+ if(missing.indexOf(" ")>0) {
+ missing = missing.substring(0,missing.indexOf(" "));
+ } else {
+ missing = missing.substring(0,missing.indexOf(";"));
+ }
+ } else if(row.indexOf("GAP")>-1) {
+ missing = row.substring(row.indexOf("GAP"));
+ missing = missing.substring(missing.indexOf("=")+1);
+ if(missing.indexOf(" ")>0) {
+ missing = missing.substring(0,missing.indexOf(" "));
+ } else if(missing.indexOf(";")>0) {
+ missing = missing.substring(0,missing.indexOf(";"));
+ } else {
+ missing = missing.trim();
+ }
+ }
+ if(row.indexOf("INTERLEAVE")>0) {
+ interleave = true;
+ }
+
+ if(row.startsWith("MATRIX")) {
+
+ // sequence data starts.
+ seqNames = new String[numTaxa];
+ seqData = new String[numTaxa];
+
+ row = in.readLine();
+ while((row != null)) {
+ row = row.trim();
+ if(!interleave) {
+ for(int i=0; i<numTaxa; i++) {
+
+ if(row.length() == 0 ) {
+ row = in.readLine().trim();
+ continue;
+ }
+ if(row.indexOf("[")>-1) {
+ row = removeComment(row);
+ }
+ //System.out.println(i+": "+row);
+ if(row.indexOf(" ")>-1) {
+ seqNames[i] = row.substring(0,row.indexOf(" "));
+ row = row.substring(row.indexOf(" ")+1).toUpperCase();
+
+ seqData[i] = removeSpace(row);
+ row = in.readLine();
+ while(seqData[i].length() < numChar) {
+ if(row.length() == 0 ) {
+ row = in.readLine().trim();
+ continue;
+ }
+ row = row.toUpperCase();
+ seqData[i] += removeSpace(row);
+ row = in.readLine();
+ }
+ } else {
+ seqNames[i] = row.trim();
+ row = in.readLine().trim();
+ //System.out.println(i+": "+row);
+ seqData[i] = removeSpace(row);
+ row = in.readLine();
+ while(seqData[i].length() < numChar) {
+ if(row.length() == 0 ) {
+ row = in.readLine().trim();
+ continue;
+ }
+ row = row.toUpperCase();
+ seqData[i] += removeSpace(row);
+ row = in.readLine();
+ }
+ }
+
+ }
+ break;
+ } else {
+ for(int i=0; i<numTaxa; i++) {
+ if(row.length() == 0 ) {
+ row = in.readLine().trim();
+ continue;
+ }
+ seqNames[i] = row.substring(0,row.indexOf(" "));
+ row = row.substring(row.indexOf(" ")+1).toUpperCase();
+ seqData[i] = removeSpace(row);
+ row = in.readLine().trim();
+ }
+ while(seqData[0].length() < numChar) {
+ if(row.length() == 0 ) {
+ row = in.readLine().trim();
+ continue;
+ }
+ for(int i=0; i<numTaxa; i++) {
+ row = row.substring(row.indexOf(" ")+1).toUpperCase();
+ seqData[i] += removeSpace(row);
+ row = in.readLine().trim();
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ row = in.readLine();
+ }
+ in.close();
+
+ // Something wrong. Give warnings and return.
+ } catch(FileNotFoundException e) {
+ warnError("File not found:" + infile);
+
+ } catch(IOException e) { }
+
+ for(int i=0; i<seqNames.length; i++) {
+
+ if(seqmap.containsKey(seqNames[i])) {
+ warnError(" Sequence " +seqNames[i]+
+ "\n is double defined!");
+ }
+
+ String seq = seqData[i].toUpperCase();
+ seq = removeChar(seqData[i],missing.charAt(0));
+
+ seqmap.put(seqNames[i].trim(),seq);
+ ProAlign.log(">"+seqNames[i]+"\n"+seq);
+ }
+ }
+
+
+ String removeSpace(String row) {
+ if(row.indexOf(" ")>-1) {
+ String str = new String("");
+ for(int j=0; j<row.length(); j++) {
+ if(row.charAt(j)!=' ') {
+ str += row.charAt(j);
+ }
+ }
+ return str;
+ } else {
+ return row;
+ }
+ }
+
+ String removeChar(String row,char rem) {
+ if(row.indexOf(rem)>-1) {
+ String str = new String("");
+ for(int j=0; j<row.length(); j++) {
+ if(row.charAt(j)!=rem) {
+ str += row.charAt(j);
+ }
+ }
+ return str;
+ } else {
+ return row;
+ }
+ }
+
+ String removeComment(String row) {
+
+ String content = new String();
+ boolean keep = true;
+ for(int i=0; i<row.length(); i++) {
+ if(row.charAt(i)=='[') {
+ keep=false;
+ } else if(row.charAt(i)==']') {
+ keep=true;
+ i++;
+ }
+ if(keep) {
+ content += row.charAt(i);
+ }
+ }
+ return content.trim();
+ }
+
+
+ /**
+ * Reading sequences returns just TRUE or FALSE.
+ * Return sequences if reading the file was OK.
+ */
+ public HashMap getSequences() {
+ return seqmap;
+ }
+
+ void warnError(String msg) {
+ allFine = false;
+ ProAlign.log.println("SequenceReader: "+msg);
+ errors += msg+"\n";
+ }
+ String getErrors() {
+ return errors;
+ }
+
+/*
+ public static void main(String[] args) {
+ SequenceReader sr = new SequenceReader();
+ if(sr.fromFile(args[0])) {
+
+ HashMap seqs = sr.getSequences();
+ Iterator it = seqs.keySet().iterator();
+ while(it.hasNext()) {
+ String name = (String) it.next();
+ String seq = (String) seqs.get(name);
+ System.out.println(name+"\n"+seq);
+ }
+ }
+ }
+//*/
+}
+
+
+
+
+
+
+
+
+
+
diff --git a/SetParameters.java b/SetParameters.java
new file mode 100644
index 0000000..b883fec
--- /dev/null
+++ b/SetParameters.java
@@ -0,0 +1,881 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JLabel;
+import javax.swing.JMenuItem;
+import javax.swing.JComboBox;
+import javax.swing.JButton;
+import javax.swing.JRadioButton;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JTextField;
+import java.awt.GridLayout;
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.awt.Container;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.ItemListener;
+import java.awt.event.ItemEvent;
+import java.io.File;
+
+public class SetParameters extends JFrame {
+
+ JTextField textDelta;
+ JTextField textEpsil;
+ JTextField textGapF;
+ JTextField textGapP;
+ JTextField[] textFreq;
+ JTextField textPwOpen;
+ JTextField textPwExt;
+ JTextField textPwMat;
+ JTextField textWidth;
+ JTextField textClustalw;
+ JTextField textTemp;
+ JTextField textOffset;
+ JTextField textScale;
+ JCheckBox boxLog;
+ JCheckBox boxTrail;
+ JCheckBox boxMultiple;
+ JCheckBox boxPenalize;
+ JComboBox pwSubst;
+
+ String[] pwMatrix = {"pam60","pam120","pam160","pam250"};
+
+ int height = 300;
+ int width = 600;
+
+ ProAlign pa;
+ ResultWindow rw;
+
+ SetParameters(ResultWindow rw) {
+
+ setTitle("Set parameters");
+ this.rw = rw;
+ this.pa = rw.pa;
+
+ Font font = new Font(ProAlign.paFontName, Font.PLAIN, ProAlign.paFontSize);
+
+ ButtonListener but = new ButtonListener();
+ JButton buttonEstFreq = new JButton("Estimate");
+ buttonEstFreq.setFont(font);
+ buttonEstFreq.setActionCommand("estimatefreq");
+ buttonEstFreq.addActionListener(but);
+ JButton buttonDefFreq = new JButton("Default");
+ buttonDefFreq.setFont(font);
+ buttonDefFreq.setActionCommand("defaultfreq");
+ buttonDefFreq.addActionListener(but);
+ JButton buttonSetFreq = new JButton("Set");
+ buttonSetFreq.setFont(font);
+ buttonSetFreq.setActionCommand("setfreq");
+ buttonSetFreq.addActionListener(but);
+ JButton buttonLock = new JButton();
+ buttonLock.setFont(font);
+ buttonLock.setActionCommand("lock");
+ buttonLock.addActionListener(but);
+ JButton buttonHmmE = new JButton("Default");
+ buttonHmmE.setFont(font);
+ buttonHmmE.setActionCommand("hmmE");
+ buttonHmmE.addActionListener(but);
+ JButton buttonHmmD = new JButton("Default");
+ buttonHmmD.setFont(font);
+ buttonHmmD.setActionCommand("hmmD");
+ buttonHmmD.addActionListener(but);
+ JButton buttonHmmEst = new JButton("Estimate");
+ buttonHmmEst.setFont(font);
+ buttonHmmEst.setActionCommand("hmmEst");
+ buttonHmmEst.addActionListener(but);
+ if(rw.hasTree) {
+ buttonHmmEst.setEnabled(true);
+ } else {
+ buttonHmmEst.setEnabled(false);
+ }
+ JButton buttonGapF = new JButton("Default");
+ buttonGapF.setFont(font);
+ buttonGapF.setActionCommand("gapF");
+ buttonGapF.addActionListener(but);
+ JButton buttonGapP = new JButton("Default");
+ buttonGapP.setFont(font);
+ buttonGapP.setActionCommand("gapP");
+ buttonGapP.addActionListener(but);
+
+ JButton buttonOffset = new JButton("Default");
+ buttonOffset.setFont(font);
+ buttonOffset.setActionCommand("offset");
+ buttonOffset.addActionListener(but);
+ JButton buttonLog = new JButton("Select");
+ buttonLog.setFont(font);
+ buttonLog.setActionCommand("log");
+ buttonLog.addActionListener(but);
+ JButton buttonWidth = new JButton("Default");
+ buttonWidth.setFont(font);
+ buttonWidth.setActionCommand("defwidth");
+ buttonWidth.addActionListener(but);
+ JButton buttonClustalw = new JButton("Change");
+ buttonClustalw.setFont(font);
+ buttonClustalw.setActionCommand("clustalw");
+ buttonClustalw.addActionListener(but);
+ JButton buttonTemp = new JButton("Change");
+ buttonTemp.setFont(font);
+ buttonTemp.setActionCommand("temp");
+ buttonTemp.addActionListener(but);
+ JButton buttonOK = new JButton("OK");
+ buttonOK.setFont(font);
+ buttonOK.setActionCommand("ok");
+ buttonOK.addActionListener(but);
+ JButton buttonCancel = new JButton("Cancel");
+ buttonCancel.setFont(font);
+ buttonCancel.setActionCommand("cancel");
+ buttonCancel.addActionListener(but);
+
+ JLabel labelHMM = new JLabel(" HMM model");
+ labelHMM.setFont(font);
+ JLabel labelVit = new JLabel(" Viterbi parameters");
+ labelVit.setFont(font);
+ JLabel labelSet = new JLabel(" Other parameters");
+ labelSet.setFont(font);
+ JLabel labelChar = new JLabel(" Character frequencies");
+ labelChar.setFont(font);
+ JLabel labelTrail = new JLabel(" Trailing sequences");
+ labelTrail.setFont(font);
+ JLabel labelPenalize = new JLabel(" Terminal gaps");
+ labelPenalize.setFont(font);
+ JLabel labelOffset = new JLabel(" Max allow");
+ labelOffset.setFont(font);
+ JLabel labelMultiple = new JLabel(" Distances");
+ labelMultiple.setFont(font);
+ JLabel labelScale = new JLabel(" scale");
+ labelScale.setFont(font);
+
+ JLabel labelSample = new JLabel(" Viterbi traceback");
+ labelSample.setFont(font);
+ JLabel labelClustalw = new JLabel(" ClustalW");
+ labelClustalw.setFont(font);
+ JLabel labelTemp = new JLabel(" Temp folder");
+ labelTemp.setFont(font);
+ JLabel labelLog = new JLabel(" Change file");
+ labelLog.setFont(font);
+ JLabel labelDelta = new JLabel(" Delta");
+ labelDelta.setFont(font);
+ JLabel labelEpsil = new JLabel(" Epsilon");
+ labelEpsil.setFont(font);
+ JLabel labelGapF = new JLabel(" Gap frequency");
+ labelGapF.setFont(font);
+ JLabel labelGapP = new JLabel(" Gap probability");
+ labelGapP.setFont(font);
+ JLabel labelPwPar = new JLabel(" Pairwise alignment");
+ labelPwPar.setFont(font);
+ JLabel labelPwOpen = new JLabel(" Gap opening");
+ labelPwOpen.setFont(font);
+ JLabel labelPwExt = new JLabel(" Gap extension");
+ labelPwExt.setFont(font);
+ JLabel labelWidth = new JLabel(" Band width");
+ labelWidth.setFont(font);
+ JLabel[] labelFreq = new JLabel[pa.sm.alphabet.length()];
+
+ textDelta = new JTextField(" ");
+ textDelta.setText(""+pa.sm.delta);
+ textDelta.setFont(font);
+ textEpsil = new JTextField(" ");
+ textEpsil.setText(""+pa.sm.epsilon);
+ textEpsil.setFont(font);
+
+ textGapF = new JTextField(" ");
+ textGapF.setText(""+pa.gapFreq);
+ textGapF.setFont(font);
+ textGapP = new JTextField(" ");
+ textGapP.setText(""+pa.gapProb);
+ textGapP.setFont(font);
+
+ textPwOpen = new JTextField(" ");
+ textPwExt = new JTextField(" ");
+ textPwMat = new JTextField(" ");
+ textPwOpen.setFont(font);
+ textPwExt.setFont(font);
+
+ if(ProAlign.isDna) {
+ textPwOpen.setText(""+(float)pa.pwDnaOpen/100f);
+ textPwExt.setText(""+(float)pa.pwDnaExt/100f);
+ textPwMat.setText(" DNA");
+ textPwMat.setEditable(false);
+ } else {
+ textPwOpen.setText(""+(float)pa.pwProtOpen/100f);
+ textPwExt.setText(""+(float)pa.pwProtExt/100f);
+ textPwMat.setText(" "+pa.pwProtMatrix);
+ textPwMat.setEditable(false);
+ }
+
+ // Pairwise protein score matrix
+ pwSubst = new JComboBox();
+ pwSubst.setFont(font);
+ pwSubst.addItemListener(new ComboBoxListener());
+
+ for(int i=0; i<pwMatrix.length; i++) {
+ pwSubst.addItem(pwMatrix[i]);
+ }
+ pwSubst.setSelectedItem(pa.pwProtMatrix);
+
+ if(ProAlign.isDna) {
+ textFreq = new JTextField[pa.sm.alphabet.length()];
+ for(int i=0; i<textFreq.length; i++) {
+ labelFreq[i] = new JLabel();
+ labelFreq[i].setFont(font);
+ textFreq[i] = new JTextField();
+ textFreq[i].setFont(font);
+ labelFreq[i].setText(" "+pa.sm.alphabet.charAt(i));
+ textFreq[i].setText((""+pa.sm.charFreqs[i]+" ").substring(0,5));
+ }
+ buttonLock.setText(""+pa.sm.alphabet.charAt(pa.sm.alphabet.length()-1));
+ textFreq[pa.sm.alphabet.length()-1].setEditable(false);
+ }
+
+ textWidth = new JTextField(" ");
+ textWidth.setText(""+pa.bandWidth);
+ textWidth.setFont(font);
+ textClustalw = new JTextField(" ");
+ textClustalw.setText(""+pa.clustalwPath);
+ textClustalw.setFont(font);
+ textClustalw.setEditable(false);
+ textTemp = new JTextField(" ");
+ textTemp.setText(""+pa.tempFolder);
+ textTemp.setFont(font);
+ textTemp.setEditable(false);
+ textOffset = new JTextField(" ");
+ textOffset.setText(""+ProAlign.offset);
+ textOffset.setFont(font);
+ textScale = new JTextField(" ");
+ textScale.setText(""+ProAlign.distScale);
+ textScale.setFont(font);
+
+ JRadioButton traceBest = new JRadioButton("select best");
+ traceBest.setFont(font);
+ traceBest.setActionCommand("best");
+ JRadioButton traceSample = new JRadioButton("sample");
+ traceSample.setFont(font);
+ traceSample.setActionCommand("sample");
+
+ if(ProAlign.trackBest) {
+ traceBest.setSelected(true);
+ } else {
+ traceSample.setSelected(true);
+ }
+
+ boxLog = new JCheckBox("Write log");
+ boxLog.setFont(font);
+ boxLog.setActionCommand("log");
+ boxLog.addActionListener(new CheckBoxListener());
+ if(ProAlign.DEBUG) {
+ boxLog.setSelected(true);
+ } else {
+ boxLog.setSelected(false);
+ }
+
+ boxTrail = new JCheckBox("correct");
+ boxTrail.setFont(font);
+ boxTrail.setActionCommand("trailing");
+ boxTrail.addActionListener(new CheckBoxListener());
+ if(ProAlign.removeTrailing) {
+ boxTrail.setSelected(true);
+ textOffset.setEditable(true);
+ } else {
+ boxTrail.setSelected(false);
+ textOffset.setEditable(false);
+ }
+
+ boxMultiple = new JCheckBox("correct");
+ boxMultiple.setFont(font);
+ boxMultiple.setActionCommand("multiple");
+ boxMultiple.addActionListener(new CheckBoxListener());
+ if(ProAlign.correctMultiple) {
+ boxMultiple.setSelected(true);
+ } else {
+ boxMultiple.setSelected(false);
+ }
+
+ boxPenalize = new JCheckBox("penalize");
+ boxPenalize.setFont(font);
+ boxPenalize.setActionCommand("terminal");
+ boxPenalize.addActionListener(new CheckBoxListener());
+ if(ProAlign.penalizeTerminal) {
+ boxPenalize.setSelected(true);
+ } else {
+ boxPenalize.setSelected(false);
+ }
+
+ // Construct panels
+ //
+ JPanel fullPanel = new JPanel();
+ fullPanel.setLayout(new GridLayout(1,2,15,15));
+ JPanel halfPanel = new JPanel();
+ halfPanel.setLayout(new GridLayout(11,1,5,5));
+
+//
+ halfPanel.add(labelChar);
+
+ JPanel pnl = new JPanel();
+ if(ProAlign.isDna) {
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,textFreq.length,5,5));
+ for(int i=0; i<textFreq.length-1; i++) {
+ pnl.add(labelFreq[i]);
+ }
+ pnl.add(buttonLock);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,textFreq.length,5,5));
+ for(int i=0; i<textFreq.length; i++) {
+ pnl.add(textFreq[i]);
+ }
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(buttonSetFreq);
+ pnl.add(buttonDefFreq);
+ pnl.add(buttonEstFreq);
+ halfPanel.add(pnl);
+ } else {
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelGapF);
+ pnl.add(textGapF);
+ pnl.add(buttonGapF);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelGapP);
+ pnl.add(textGapP);
+ pnl.add(buttonGapP);
+ halfPanel.add(pnl);
+
+ halfPanel.add(new JLabel());
+ }
+
+ halfPanel.add(labelPwPar);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ if(ProAlign.isDna) {
+ pnl.add(new JLabel());
+ } else {
+ pnl.add(pwSubst);
+ }
+ pnl.add(labelPwOpen);
+ pnl.add(labelPwExt);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(textPwMat);
+ pnl.add(textPwOpen);
+ pnl.add(textPwExt);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(labelPenalize);
+ pnl.add(boxPenalize);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(labelTrail);
+ pnl.add(boxTrail);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelOffset);
+ pnl.add(textOffset);
+ pnl.add(buttonOffset);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,4,5,5));
+ pnl.add(labelMultiple);
+ pnl.add(boxMultiple);
+ pnl.add(labelScale);
+ pnl.add(textScale);
+ halfPanel.add(pnl);
+
+ fullPanel.add(halfPanel);
+
+ halfPanel = new JPanel();
+ halfPanel.setLayout(new GridLayout(11,1,5,5));
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelHMM);
+ pnl.add(new JLabel());
+ pnl.add(buttonHmmEst);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelDelta);
+ pnl.add(textDelta);
+ pnl.add(buttonHmmD);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelEpsil);
+ pnl.add(textEpsil);
+ pnl.add(buttonHmmE);
+ halfPanel.add(pnl);
+
+ ButtonGroup traceBack = new ButtonGroup();
+ traceBack.add(traceBest);
+ traceBack.add(traceSample);
+ traceBest.addActionListener(new RadioListener());
+ traceSample.addActionListener(new RadioListener());
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(labelSample);
+ pnl.add(traceBest);
+ halfPanel.add(pnl);
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,2,5,5));
+ pnl.add(new JPanel());
+ pnl.add(traceSample);
+ halfPanel.add(pnl);
+
+// halfPanel.add(new JLabel());
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(boxLog);
+ pnl.add(labelLog);
+ pnl.add(buttonLog);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelWidth);
+ pnl.add(textWidth);
+ pnl.add(buttonWidth);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelClustalw);
+ pnl.add(textClustalw);
+ pnl.add(buttonClustalw);
+ halfPanel.add(pnl);
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(labelTemp);
+ pnl.add(textTemp);
+ pnl.add(buttonTemp);
+ halfPanel.add(pnl);
+
+ halfPanel.add(new JLabel());
+
+ pnl = new JPanel();
+ pnl.setLayout(new GridLayout(1,3,5,5));
+ pnl.add(new JLabel());
+ pnl.add(buttonOK);
+ pnl.add(buttonCancel);
+ halfPanel.add(pnl);
+
+ fullPanel.add(halfPanel);
+
+ Container cp = getContentPane();
+ cp.add(fullPanel);
+
+ addWindowListener(new WindowAdapter() {
+ public void windowClosing(WindowEvent e) {
+ dispose();
+ }
+ });
+
+ }
+
+ class ButtonListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+
+ JButton target = (JButton)e.getSource();
+ String actionCommand = target.getActionCommand();
+
+ if(actionCommand.equals("estimatefreq")) {
+
+ if(!rw.hasData) {
+
+ String text = new String("\n Estimating frequencies needs some data! \n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Error!", text);
+
+ } else {
+
+ EstimateFrequencies ef = new EstimateFrequencies(
+ rw.seqcont.textArray,pa.sm.alphabet,pa.sm.equateAlphabet);
+ double[] freqs = ef.getCharacterFrequencies();
+
+ NicePrint nn = new NicePrint();
+ for(int i=0; i<textFreq.length; i++) {
+ textFreq[i].setText(nn.rdbl(freqs[i],3));
+ }
+
+ if(!rw.isAligned) {
+ String text = new String("\n Sequences are not aligned. Estimating \n"+
+ " gap frequency does not make much sense!\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+ }
+
+ } else if(actionCommand.equals("defaultfreq")) {
+
+ for(int i=0; i<textFreq.length; i++) {
+ textFreq[i].setText(""+pa.sm.charFreqsDefault[i]);
+ }
+
+ } else if(actionCommand.equals("setfreq")) {
+
+ NicePrint nn = new NicePrint();
+ if(textFreq[textFreq.length-1].isEditable()) {
+ double[] setFreqs = new double[textFreq.length];
+ double sum = 0d;
+ for(int i=0; i<textFreq.length; i++) {
+ setFreqs[i] = new Double(textFreq[i].getText()).doubleValue();
+ sum += setFreqs[i];
+ System.out.println("read: "+setFreqs[i]+", sum: "+sum);
+ }
+ for(int i=0; i<textFreq.length; i++) {
+ textFreq[i].setText(nn.rdbl(setFreqs[i]/sum,3));
+ System.out.println("write: "+setFreqs[i]/sum);
+ }
+ } else {
+ double sum = 0d;
+ for(int i=0; i<textFreq.length-1; i++) {
+ sum += new Double(textFreq[i].getText()).doubleValue();
+ }
+ if(sum < 1d) {
+ textFreq[textFreq.length-1].setText(nn.rdbl(1d-sum,3));
+ }
+ }
+
+ } else if(actionCommand.equals("lock")) {
+
+ if(textFreq[textFreq.length-1].isEditable()) {
+ textFreq[textFreq.length-1].setEditable(false);
+ } else {
+ textFreq[textFreq.length-1].setEditable(true);
+ }
+
+ } else if(actionCommand.equals("log")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(SetParameters.this,"Start log",false);
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ pa.log.close();
+ pa.startNewLog(filepath);
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ ProAlign.folderPath = new File(filepath).getParent();
+ userdata[0] = new File(filepath).getParent();
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("hmmE")) {
+
+ textEpsil.setText(""+pa.sm.epsilonDefault);
+
+ } else if(actionCommand.equals("hmmD")) {
+
+ textDelta.setText(""+pa.sm.deltaDefault);
+
+ } else if(actionCommand.equals("hmmEst")) {
+
+ ProAlign.estimateDelta = true;
+ ProAlign.estimateEpsilon = true;
+ ProAlign.estimateGapFreq = false;
+ ProAlign.estimateGapProb = false;
+
+ ParameterEstimates pe = new ParameterEstimates(rw,SetParameters.this);
+
+ } else if(actionCommand.equals("gapF")) {
+
+ textGapF.setText(""+pa.sm.gapFreqDefault);
+
+ } else if(actionCommand.equals("gapP")) {
+
+ textGapP.setText(""+pa.sm.gapProbDefault);
+
+ } else if(actionCommand.equals("defwidth")) {
+
+ textWidth.setText(""+pa.defBandWidth);
+
+ } else if(actionCommand.equals("offset")) {
+
+ textOffset.setText(""+pa.defOffset);
+ textOffset.setEditable(true);
+ boxTrail.setSelected(true);
+
+ } else if(actionCommand.equals("clustalw")) {
+
+ OpenFileChooser opf =
+ new OpenFileChooser(SetParameters.this,"Select",false);
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ pa.clustalwPath = filepath;
+ textClustalw.setText(filepath);
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[1] = filepath;
+ user.writeSettings(userdata);
+
+ }
+
+ } else if(actionCommand.equals("temp")) {
+
+ OpenFolderChooser opf =
+ new OpenFolderChooser(SetParameters.this,"Select");
+ String filepath = opf.openFile();
+ if(!filepath.equals("")) {
+ pa.tempFolder = filepath;
+ textTemp.setText(filepath);
+ UserSettings user = new UserSettings();
+ String[] userdata = user.readSettings();
+ userdata[2] = filepath;
+ user.writeSettings(userdata);
+ }
+
+ } else if(actionCommand.equals("cancel")) {
+
+ dispatchEvent(new WindowEvent(SetParameters.this,
+ WindowEvent.WINDOW_CLOSING));
+
+ } else if(actionCommand.equals("ok")) {
+
+ while(true) {
+ try{
+
+ if(ProAlign.isDna) {
+ // check that character freqs are reasonable and update them.
+ double[] setFreqs = new double[textFreq.length];
+ double sum = 0d;
+ for(int i=1; i<textFreq.length; i++) {
+ setFreqs[i] = new Double(textFreq[i].getText()).doubleValue();
+ sum += setFreqs[i];
+ }
+ if(sum < 1d) {
+ setFreqs[0] = 1d-sum;
+ }
+ pa.sm.charFreqs = setFreqs;
+ // or check that gap freq/prob are reasonable
+ } else {
+ double gapF = new Double(textGapF.getText()).doubleValue();
+ double gapP = new Double(textGapP.getText()).doubleValue();
+ if(gapF>0d && gapF<0.5d && gapP>0d && gapP<0.5d) {
+ pa.sm.gapFreq = gapF;
+ pa.sm.gapProb = gapP;
+ } else {
+ String text = new String("\n Illegal value for gap frequency/"+
+ "probability!\n Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ }
+
+ double delta = new Double(textDelta.getText()).doubleValue();
+ if(delta>0d && delta<0.5d) {
+ pa.sm.delta = delta;
+ } else {
+ String text = new String("\n Illegal value for delta!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ double epsilon = new Double(textEpsil.getText()).doubleValue();
+ if(epsilon>0d && epsilon<1.0d) {
+ pa.sm.epsilon = epsilon;
+ } else {
+ String text = new String("\n Illegal value for epsilon!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ int bandWidth = new Integer(textWidth.getText()).intValue();
+ if(bandWidth>10) {
+ pa.bandWidth = bandWidth;
+ } else {
+ String text = new String("\n Band width too low!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+ if(bandWidth>200) {
+ String text = new String("\n Too great band width may run\n"+
+ " your system out of memory!\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+ int gapOpen = (int)(new Float(textPwOpen.getText()).floatValue()*100f);
+ if(gapOpen>=0 && gapOpen<5100) {
+ if(ProAlign.isDna) {
+ pa.pwDnaOpen = gapOpen;
+ } else {
+ pa.pwProtOpen = gapOpen;
+ }
+ } else {
+ String text = new String("\n Illegal value for gap opening!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ int gapExt = (int)(new Float(textPwExt.getText()).floatValue()*100f);
+ if(gapExt>=0 && gapExt<2100) {
+ if(ProAlign.isDna) {
+ pa.pwDnaExt = gapExt;
+ } else {
+ pa.pwProtExt = gapExt;
+ }
+ } else {
+ String text = new String("\n Illegal value for gap extension!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ int offset = new Integer(textOffset.getText()).intValue();
+ if(offset>0 && offset<pa.bandWidth/2) {
+ pa.offset = offset;
+ } else {
+ String text = new String("\n Offset should be less than\n"+
+ " a half of the band width!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ double scale = new Double(textScale.getText()).doubleValue();
+ if(scale>0d && scale<2.0d) {
+ pa.distScale = scale;
+ } else {
+ String text = new String("\n Distance scale should be \n"+
+ " between 0.0 and 2.0!\n"+
+ " Value not changed.\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Warning!", text);
+ }
+
+ if(!ProAlign.isDna) {
+ pa.pwProtMatrix = textPwMat.getText().trim();
+ }
+
+ if(ProAlign.DEBUG) {
+ ProAlign.log("SetParameters");
+ ProAlign.log(" trackBest="+ProAlign.trackBest);
+ ProAlign.log(" bandWidth="+ProAlign.bandWidth);
+ ProAlign.log(" clustalwPath="+ProAlign.clustalwPath);
+ ProAlign.log(" tempFolder="+ProAlign.tempFolder);
+ ProAlign.log(" offset="+ProAlign.offset);
+ ProAlign.log(" distScale="+ProAlign.distScale);
+ ProAlign.log(" removeTrailing="+ProAlign.removeTrailing);
+ ProAlign.log(" penalizeTerminal="+ProAlign.penalizeTerminal);
+ if(ProAlign.isDna) {
+ ProAlign.log(" pwGapOpen="+pa.pwDnaOpen);
+ ProAlign.log(" pwGapExt="+pa.pwDnaExt);
+ } else {
+ ProAlign.log(" pwGapOpen="+pa.pwProtOpen);
+ ProAlign.log(" pwGapExt="+pa.pwProtExt);
+ ProAlign.log(" pwGapMatrix="+pa.pwProtMatrix);
+ }
+ ProAlign.log.flush();
+ }
+
+ } catch(NumberFormatException nfe) {
+ String text = new String("\n Illegal value!\n");
+ OpenDialog od = new OpenDialog(SetParameters.this);
+ od.showDialog("Error!", text);
+ break;
+ }
+
+ dispatchEvent(new WindowEvent(SetParameters.this,
+ WindowEvent.WINDOW_CLOSING));
+ break;
+ }
+ }
+ }
+ }
+
+ class RadioListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ String actionCommand = e.getActionCommand();
+
+ if(actionCommand.equals("sample")) {
+
+ ProAlign.trackBest = false;
+
+ } else if(actionCommand.equals("best")) {
+
+ ProAlign.trackBest = true;
+ }
+ }
+ }
+
+ class ComboBoxListener implements ItemListener {
+ public void itemStateChanged(ItemEvent e) {
+ if(!ProAlign.isDna) {
+ String item = (String) e.getItem();
+ textPwMat.setText(" "+item);
+ }
+ }
+ }
+
+ class CheckBoxListener implements ActionListener {
+ public void actionPerformed(ActionEvent e) {
+ String actionCommand = e.getActionCommand();
+ if(actionCommand.equals("log")) {
+ if(boxLog.isSelected()) {
+ ProAlign.DEBUG = true;
+ } else {
+ ProAlign.DEBUG = false;
+ }
+ } else if(actionCommand.equals("trailing")) {
+ if(boxTrail.isSelected()) {
+ ProAlign.removeTrailing = true;
+ textOffset.setEditable(true);
+ } else {
+ ProAlign.removeTrailing = false;
+ textOffset.setEditable(false);
+ }
+ } else if(actionCommand.equals("multiple")) {
+ if(boxMultiple.isSelected()) {
+ ProAlign.correctMultiple = true;
+ } else {
+ ProAlign.correctMultiple = false;
+ }
+ } else if(actionCommand.equals("terminal")) {
+ if(boxPenalize.isSelected()) {
+ ProAlign.penalizeTerminal = true;
+ } else {
+ ProAlign.penalizeTerminal = false;
+ }
+ }
+ }
+ }
+}
diff --git a/SubstitutionModel.java b/SubstitutionModel.java
new file mode 100644
index 0000000..f124e5e
--- /dev/null
+++ b/SubstitutionModel.java
@@ -0,0 +1,511 @@
+ /**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+public class SubstitutionModel {
+
+ double delta, epsilon;
+ double deltaDefault, epsilonDefault;
+
+ double[] charFreqs;
+ double[] charFreqsDefault;
+ double[][] substProb1, substProb2;
+
+ String alphabet;
+ String equateAlphabet;
+
+ double[] aaFreqs;
+ double[][] aaPam;
+ double[][] gapPam;
+
+ double gapFreq;
+ double gapProb;
+ double gapFreqDefault, gapProbDefault;
+
+ String modelName;
+
+ /**
+ * Holds a handle to ProAlign-class.
+ */
+ public SubstitutionModel(ProAlign pa) {
+
+ delta = pa.modelDelta; // prob to move to INSERT(X/Y)
+ epsilon = pa.modelEpsilon; // prob to stay in INSERT(X/Y)
+
+ gapFreq = pa.gapFreq;
+ gapProb = pa.gapProb;
+
+ // save defaults
+ deltaDefault = delta;
+ epsilonDefault = epsilon;
+ gapFreqDefault = gapFreq;
+ gapProbDefault = gapProb;
+
+ ProAlign.log("SubstitutionModel");
+ }
+
+ /**
+ * Simple DNA model. Currently the alphabet is "ACGT-", all the background
+ * frequencies are 0.2, and substitution probabilities are equal.
+ */
+ void jcDnaModel() {
+
+ modelName = "jcDnaModel";
+
+ alphabet = "ACGT-";
+ equateAlphabet = "ACGTRYMKSWHBVDNU";
+
+ charFreqs = new double[5];
+
+ charFreqs[0] = 0.2d;
+ charFreqs[1] = 0.2d;
+ charFreqs[2] = 0.2d;
+ charFreqs[3] = 0.2d;
+ charFreqs[4] = 0.2d;
+
+ printDebug();
+
+ // save defaults
+ charFreqsDefault = charFreqs;
+
+ }
+
+
+ /**
+ * Simple protein model based on WAG.
+ */
+
+ void wagProteinModel() {
+
+ modelName = "wagProteinModel";
+
+ alphabet = "ARNDCQEGHILKMFPSTWYV-";
+ equateAlphabet = "ARNDCQEGHILKMFPSTWYVX";
+
+ double[] tmp = {0.086628,0.043972,0.039089,0.057045,0.019308,
+ 0.036728,0.058059,0.083252,0.024431,0.048466,
+ 0.086209,0.062029,0.019503,0.038432,0.045763,
+ 0.069518,0.061013,0.014386,0.035274,0.070896};
+ aaFreqs = tmp;
+
+ double[][] tmp2 = {{0.989896,0.000294,0.000272,0.000394,0.000548,
+ 0.000485,0.000844,0.000756,0.000169,0.000103,
+ 0.000212,0.000483,0.000477,0.000112,0.000767,
+ 0.001798,0.001131,6.03e-05,0.000128,0.00107},
+ {0.000294,0.989794,0.000339,7.86e-05,0.000282,
+ 0.001619,0.000234,0.000312,0.00114,9.97e-05,
+ 0.000265,0.002854,0.000364,5.48e-05,0.000362,
+ 0.000653,0.000296,0.000621,0.000203,0.000134},
+ {0.000272,0.000339,0.986156,0.002896,0.000141,
+ 0.000823,0.000505,0.0006,0.00211,0.000296,
+ 7.01e-05,0.001606,0.000106,5.13e-05,0.000104,
+ 0.00212,0.001083,3.84e-05,0.000579,0.000105},
+ {0.000394,7.86e-05,0.002896,0.990311,1.62e-05,
+ 0.000329,0.003293,0.000462,0.000496,2.1e-05,
+ 4.52e-05,0.000256,5.53e-05,2.49e-05,0.000226,
+ 0.000572,0.0002,6.92e-05,0.000174,8.12e-05},
+ {0.000548,0.000282,0.000141,1.62e-05,0.995607,
+ 5.27e-05,1.14e-05,0.000164,0.000133,9.07e-05,
+ 0.000205,3.95e-05,0.000208,0.000212,5.83e-05,
+ 0.000751,0.000274,0.000382,0.00029,0.000534},
+ {0.000485,0.001619,0.000823,0.000329,5.27e-05,
+ 0.985928,0.002917,0.000176,0.00229,6.08e-05,
+ 0.000464,0.002077,0.000824,5.33e-05,0.000498,
+ 0.000549,0.000458,0.000115,0.000121,0.000161},
+ {0.000844,0.000234,0.000505,0.003293,1.14e-05,
+ 0.002917,0.988168,0.000303,0.000304,6.79e-05,
+ 8.23e-05,0.001378,0.000168,4.33e-05,0.000364,
+ 0.000376,0.000439,8.35e-05,0.000105,0.000314},
+ {0.000756,0.000312,0.0006,0.000462,0.000164,
+ 0.000176,0.000303,0.995427,0.000133,1.62e-05,
+ 3.27e-05,0.000199,9.29e-05,2.66e-05,0.00013,
+ 0.000716,0.00012,0.00018,5.53e-05,9.99e-05},
+ {0.000169,0.00114,0.00211,0.000496,0.000133,
+ 0.00229,0.000304,0.000133,0.988544,7.37e-05,
+ 0.000266,0.000475,0.000216,0.000362,0.000371,
+ 0.000395,0.000252,0.00014,0.002066,6.31e-05},
+ {0.000103,9.97e-05,0.000296,2.1e-05,9.07e-05,
+ 6.08e-05,6.79e-05,1.62e-05,7.37e-05,0.988961,
+ 0.001691,0.000173,0.002271,0.000565,5.33e-05,
+ 0.00017,0.000778,0.000113,0.000224,0.004171},
+ {0.000212,0.000265,7.01e-05,4.52e-05,0.000205,
+ 0.000464,8.23e-05,3.27e-05,0.000266,0.001691,
+ 0.990704,0.000137,0.002589,0.001128,0.000222,
+ 0.000184,0.000174,0.000355,0.000213,0.00096},
+ {0.000483,0.002854,0.001606,0.000256,3.95e-05,
+ 0.002077,0.001378,0.000199,0.000475,0.000173,
+ 0.000137,0.987915,0.000498,4.74e-05,0.000297,
+ 0.000516,0.00074,7.33e-05,7.11e-05,0.000163},
+ {0.000477,0.000364,0.000106,5.53e-05,0.000208,
+ 0.000824,0.000168,9.29e-05,0.000216,0.002271,
+ 0.002589,0.000498,0.988732,0.000635,9.14e-05,
+ 0.000263,0.000809,0.000275,0.000228,0.001098},
+ {0.000112,5.48e-05,5.13e-05,2.49e-05,0.000212,
+ 5.33e-05,4.33e-05,2.66e-05,0.000362,0.000565,
+ 0.001128,4.74e-05,0.000635,0.99161,8.61e-05,
+ 0.000291,9.17e-05,0.000816,0.003442,0.000347},
+ {0.000767,0.000362,0.000104,0.000226,5.83e-05,
+ 0.000498,0.000364,0.00013,0.000371,5.33e-05,
+ 0.000222,0.000297,9.14e-05,8.61e-05,0.994727,
+ 0.00086,0.000424,7.43e-05,0.000115,0.000168},
+ {0.001798,0.000653,0.00212,0.000572,0.000751,
+ 0.000549,0.000376,0.000716,0.000395,0.00017,
+ 0.000184,0.000516,0.000263,0.000291,0.00086,
+ 0.986629,0.002335,0.000279,0.00042,0.000124},
+ {0.001131,0.000296,0.001083,0.0002,0.000274,
+ 0.000458,0.000439,0.00012,0.000252,0.000778,
+ 0.000174,0.00074,0.000809,9.17e-05,0.000424,
+ 0.002335,0.989442,5.91e-05,0.000155,0.00074},
+ {6.03e-05,0.000621,3.84e-05,6.92e-05,0.000382,
+ 0.000115,8.35e-05,0.00018,0.00014,0.000113,
+ 0.000355,7.33e-05,0.000275,0.000816,7.43e-05,
+ 0.000279,5.91e-05,0.994745,0.001326,0.000195},
+ {0.000128,0.000203,0.000579,0.000174,0.00029,
+ 0.000121,0.000105,5.53e-05,0.002066,0.000224,
+ 0.000213,7.11e-05,0.000228,0.003442,0.000115,
+ 0.00042,0.000155,0.001326,0.989916,0.000168},
+ {0.00107,0.000134,0.000105,8.12e-05,0.000534,
+ 0.000161,0.000314,9.99e-05,6.31e-05,0.004171,
+ 0.00096,0.000163,0.001098,0.000347,0.000168,
+ 0.000124,0.00074,0.000195,0.000168,0.989304}};
+ aaPam = tmp2;
+ setGapPam();
+
+ printDebug();
+ }
+
+
+
+ void dayhoffProteinModel() {
+
+ modelName = "dayhoffProteinModel";
+
+ alphabet = "ARNDCQEGHILKMFPSTWYV-";
+ equateAlphabet = "ARNDCQEGHILKMFPSTWYVX";
+
+ double[] tmp = {0.087,0.041,0.04,0.047,0.033,
+ 0.038,0.05,0.089,0.034,0.037,
+ 0.085,0.08,0.015,0.04,0.051,
+ 0.07,0.058,0.01,0.03,0.065};
+ aaFreqs = tmp;
+
+ double[][] tmp2 = {{0.988234,0.000137,0.000509,0.000612,0.000187,
+ 0.000457,0.000994,0.001216,0.000115,0.000333,
+ 0.000209,0.000133,0.000361,9.35e-05,0.001264,
+ 0.002061,0.001901,5.46e-06,0.000125,0.00105},
+ {0.000137,0.991108,0.000169,8.44e-06,0.00012,
+ 0.001252,7.93e-06,4.46e-05,0.001202,0.000322,
+ 7.93e-05,0.002365,0.000449,6.94e-05,0.000521,
+ 0.000776,0.000137,0.001071,3.97e-05,0.000122},
+ {0.000509,0.000169,0.983089,0.004602,1.05e-05,
+ 0.000535,0.000764,0.000713,0.002702,0.000396,
+ 0.000177,0.001636,2.71e-05,7.11e-05,0.000215,
+ 0.002509,0.001185,0.000122,0.000488,8.13e-05},
+ {0.000612,8.44e-06,0.004602,0.985754,3.62e-06,
+ 0.000692,0.00575,0.00063,0.000438,0.000122,
+ 3.68e-06,0.000368,1.65e-05,1.84e-06,6.78e-05,
+ 0.000484,0.00034,4.59e-06,1.15e-05,9.05e-05},
+ {0.000187,0.00012,1.05e-05,3.62e-06,0.99741,
+ 3.1e-06,2.09e-06,5.54e-05,0.000145,0.000226,
+ 5.54e-06,1.15e-06,2.01e-05,1.23e-05,9.66e-05,
+ 0.000824,8.5e-05,4.93e-05,0.000493,0.00025},
+ {0.000457,0.001252,0.000535,0.000692,3.1e-06,
+ 0.98687,0.003612,0.000144,0.003058,9.25e-05,
+ 0.000378,0.000786,0.000571,2.56e-06,0.00078,
+ 0.000287,0.000273,1.36e-05,1.43e-05,0.000178},
+ {0.000994,7.93e-06,0.000764,0.00575,2.09e-06,
+ 0.003612,0.986165,0.000409,0.00022,0.000308,
+ 5.74e-05,0.000423,0.000152,2.81e-06,0.000255,
+ 0.0004,0.000174,1.04e-05,0.000108,0.000185},
+ {0.001216,4.46e-05,0.000713,0.00063,5.54e-05,
+ 0.000144,0.000409,0.994594,5.37e-05,3.28e-06,
+ 3.65e-05,0.000137,8.53e-05,7.77e-05,0.000176,
+ 0.001175,0.000158,1.83e-05,2.43e-06,0.000273},
+ {0.000115,0.001202,0.002702,0.000438,0.000145,
+ 0.003058,0.00022,5.37e-05,0.989644,3.88e-05,
+ 0.000225,0.000138,1.78e-05,0.000239,0.000469,
+ 0.000178,0.000115,0.000143,0.000638,0.000221},
+ {0.000333,0.000322,0.000396,0.000122,0.000226,
+ 9.25e-05,0.000308,3.28e-06,3.88e-05,0.988119,
+ 0.001308,0.000236,0.00167,0.000989,6.03e-05,
+ 0.000126,0.000977,1.4e-05,0.00019,0.004469},
+ {0.000209,7.93e-05,0.000177,3.68e-06,5.54e-06,
+ 0.000378,5.74e-05,3.65e-05,0.000225,0.001308,
+ 0.992281,9.33e-05,0.00264,0.000799,0.000161,
+ 8.75e-05,0.000172,0.000249,0.000147,0.000892},
+ {0.000133,0.002365,0.001636,0.000368,1.15e-06,
+ 0.000786,0.000423,0.000137,0.000138,0.000236,
+ 9.33e-05,0.990977,0.00122,9.45e-07,0.000171,
+ 0.000488,0.000701,4.86e-06,6.78e-05,5.32e-05},
+ {0.000361,0.000449,2.71e-05,1.65e-05,2.01e-05,
+ 0.000571,0.000152,8.53e-05,1.78e-05,0.00167,
+ 0.00264,0.00122,0.990068,0.000461,8.5e-05,
+ 0.00031,0.000523,2.3e-05,1.63e-05,0.001284},
+ {9.35e-05,6.94e-05,7.11e-05,1.84e-06,1.23e-05,
+ 2.56e-06,2.81e-06,7.77e-05,0.000239,0.000989,
+ 0.000799,9.45e-07,0.000461,0.99283,5.58e-05,
+ 0.000232,7.01e-05,0.000407,0.003523,6.25e-05},
+ {0.001264,0.000521,0.000215,6.78e-05,9.66e-05,
+ 0.00078,0.000255,0.000176,0.000469,6.03e-05,
+ 0.000161,0.000171,8.5e-05,5.58e-05,0.993738,
+ 0.001225,0.000401,5.08e-06,6.21e-06,0.000245},
+ {0.002061,0.000776,0.002509,0.000484,0.000824,
+ 0.000287,0.0004,0.001175,0.000178,0.000126,
+ 8.75e-05,0.000488,0.00031,0.000232,0.001225,
+ 0.985332,0.002788,0.000395,0.00017,0.000154},
+ {0.001901,0.000137,0.001185,0.00034,8.5e-05,
+ 0.000273,0.000174,0.000158,0.000115,0.000977,
+ 0.000172,0.000701,0.000523,7.01e-05,0.000401,
+ 0.002788,0.988977,5.96e-06,0.000215,0.000802},
+ {5.46e-06,0.001071,0.000122,4.59e-06,4.93e-05,
+ 1.36e-05,1.04e-05,1.83e-05,0.000143,1.4e-05,
+ 0.000249,4.86e-06,2.3e-05,0.000407,5.08e-06,
+ 0.000395,5.96e-06,0.997116,0.000325,1.79e-05},
+ {0.000125,3.97e-05,0.000488,1.15e-05,0.000493,
+ 1.43e-05,0.000108,2.43e-06,0.000638,0.00019,
+ 0.000147,6.78e-05,1.63e-05,0.003523,6.21e-06,
+ 0.00017,0.000215,0.000325,0.993278,0.000142},
+ {0.00105,0.000122,8.13e-05,9.05e-05,0.00025,
+ 0.000178,0.000185,0.000273,0.000221,0.004469,
+ 0.000892,5.32e-05,0.001284,6.25e-05,0.000245,
+ 0.000154,0.000802,1.79e-05,0.000142,0.989428}};
+ aaPam = tmp2;
+ setGapPam();
+
+ printDebug();
+ }
+
+
+
+ void jttProteinModel() {
+
+ modelName = "jttProteinModel";
+
+ alphabet = "ARNDCQEGHILKMFPSTWYV-";
+ equateAlphabet = "ARNDCQEGHILKMFPSTWYVX";
+
+ double[] tmp = {0.077,0.051,0.043,0.052,0.02,
+ 0.041,0.062,0.074,0.023,0.052,
+ 0.091,0.059,0.024,0.04,0.051,
+ 0.069,0.059,0.014,0.032,0.066};
+ aaFreqs = tmp;
+
+ double[][] tmp2 = {{0.986454,0.000128,0.000552,0.000645,0.00036,
+ 0.000494,0.000935,0.001705,0.000199,0.000277,
+ 0.000228,0.000211,0.000263,0.000109,0.001474,
+ 0.002439,0.00218,4.55e-06,0.000136,0.001205},
+ {0.000128,0.991919,0.00013,6.33e-06,0.000165,
+ 0.000963,5.31e-06,4.45e-05,0.001474,0.00019,
+ 6.15e-05,0.00266,0.000233,5.76e-05,0.000432,
+ 0.000653,0.000112,0.000635,3.09e-05,9.97e-05},
+ {0.000552,0.00013,0.982571,0.003993,1.66e-05,
+ 0.000476,0.000592,0.000823,0.003835,0.00027,
+ 0.000159,0.00213,1.63e-05,6.83e-05,0.000207,
+ 0.002444,0.001118,8.36e-05,0.000439,7.69e-05},
+ {0.000645,6.33e-06,0.003993,0.987626,5.57e-06,
+ 0.000598,0.004326,0.000707,0.000603,8.07e-05,
+ 3.2e-06,0.000465,9.64e-06,1.71e-06,6.33e-05,
+ 0.000458,0.000312,3.06e-06,1.01e-05,8.31e-05},
+ {0.00036,0.000165,1.66e-05,5.57e-06,0.995644,
+ 4.89e-06,2.88e-06,0.000113,0.000365,0.000274,
+ 8.82e-06,2.64e-06,2.14e-05,2.1e-05,0.000165,
+ 0.001423,0.000142,5.99e-05,0.000787,0.00042},
+ {0.000494,0.000963,0.000476,0.000598,4.89e-06,
+ 0.986951,0.002786,0.000166,0.004325,6.3e-05,
+ 0.000337,0.00102,0.000341,2.45e-06,0.000746,
+ 0.000279,0.000257,9.32e-06,1.28e-05,0.000167},
+ {0.000935,5.31e-06,0.000592,0.004326,2.88e-06,
+ 0.002786,0.988953,0.00041,0.000271,0.000182,
+ 4.46e-05,0.000477,7.9e-05,2.34e-06,0.000212,
+ 0.000337,0.000142,6.16e-06,8.46e-05,0.000152},
+ {0.001705,4.45e-05,0.000823,0.000707,0.000113,
+ 0.000166,0.00041,0.993253,9.86e-05,2.9e-06,
+ 4.24e-05,0.000231,6.61e-05,9.64e-05,0.000218,
+ 0.001479,0.000192,1.62e-05,2.82e-06,0.000333},
+ {0.000199,0.001474,0.003835,0.000603,0.000365,
+ 0.004325,0.000271,9.86e-05,0.985237,4.21e-05,
+ 0.000321,0.000284,1.7e-05,0.000365,0.000715,
+ 0.000275,0.000173,0.000156,0.000912,0.000332},
+ {0.000277,0.00019,0.00027,8.07e-05,0.000274,
+ 6.3e-05,0.000182,2.9e-06,4.21e-05,0.991779,
+ 0.000897,0.000235,0.000767,0.000726,4.43e-05,
+ 9.35e-05,0.000706,7.35e-06,0.000131,0.003232},
+ {0.000228,6.15e-05,0.000159,3.2e-06,8.82e-06,
+ 0.000337,4.46e-05,4.24e-05,0.000321,0.000897,
+ 0.993861,0.000122,0.001591,0.00077,0.000155,
+ 8.55e-05,0.000163,0.000171,0.000133,0.000847},
+ {0.000211,0.00266,0.00213,0.000465,2.64e-06,
+ 0.00102,0.000477,0.000231,0.000284,0.000235,
+ 0.000122,0.98903,0.001067,1.32e-06,0.00024,
+ 0.000693,0.000964,4.86e-06,8.89e-05,7.33e-05},
+ {0.000263,0.000233,1.63e-05,9.64e-06,2.14e-05,
+ 0.000341,7.9e-05,6.61e-05,1.7e-05,0.000767,
+ 0.001591,0.001067,0.993806,0.000297,5.48e-05,
+ 0.000203,0.000332,1.06e-05,9.87e-06,0.000816},
+ {0.000109,5.76e-05,6.83e-05,1.71e-06,2.1e-05,
+ 2.45e-06,2.34e-06,9.64e-05,0.000365,0.000726,
+ 0.00077,1.32e-06,0.000297,0.993338,5.76e-05,
+ 0.000243,7.11e-05,0.0003,0.003409,6.36e-05},
+ {0.001474,0.000432,0.000207,6.33e-05,0.000165,
+ 0.000746,0.000212,0.000218,0.000715,4.43e-05,
+ 0.000155,0.00024,5.48e-05,5.76e-05,0.993266,
+ 0.001283,0.000407,3.75e-06,6.01e-06,0.000249},
+ {0.002439,0.000653,0.002444,0.000458,0.001423,
+ 0.000279,0.000337,0.001479,0.000275,9.35e-05,
+ 8.55e-05,0.000693,0.000203,0.000243,0.001283,
+ 0.984122,0.002869,0.000295,0.000167,0.000158},
+ {0.00218,0.000112,0.001118,0.000312,0.000142,
+ 0.000257,0.000142,0.000192,0.000173,0.000706,
+ 0.000163,0.000964,0.000332,7.11e-05,0.000407,
+ 0.002869,0.98885,4.32e-06,0.000204,0.000802},
+ {4.55e-06,0.000635,8.36e-05,3.06e-06,5.99e-05,
+ 9.32e-06,6.16e-06,1.62e-05,0.000156,7.35e-06,
+ 0.000171,4.86e-06,1.06e-05,0.0003,3.75e-06,
+ 0.000295,4.32e-06,0.997991,0.000225,1.3e-05},
+ {0.000136,3.09e-05,0.000439,1.01e-05,0.000787,
+ 1.28e-05,8.46e-05,2.82e-06,0.000912,0.000131,
+ 0.000133,8.89e-05,9.87e-06,0.003409,6.01e-06,
+ 0.000167,0.000204,0.000225,0.993076,0.000135},
+ {0.001205,9.97e-05,7.69e-05,8.31e-05,0.00042,
+ 0.000167,0.000152,0.000333,0.000332,0.003232,
+ 0.000847,7.33e-05,0.000816,6.36e-05,0.000249,
+ 0.000158,0.000802,1.3e-05,0.000135,0.990742}};
+ aaPam = tmp2;
+ setGapPam();
+
+ printDebug();
+ }
+
+ void setBranchLength(double dist1, double dist2) {
+
+
+ dist1 = ProAlign.distScale*dist1;
+ dist2 = ProAlign.distScale*dist2;
+
+ if(ProAlign.isDna) {
+ setDnaSubstTable(dist1,1);
+ setDnaSubstTable(dist2,2);
+ } else {
+ setProtSubstTable(dist1*100,1);
+ setProtSubstTable(dist2*100,2);
+ }
+ }
+
+ void setDnaSubstTable(double dist, int table) {
+
+ // probablility matrix to observe character pairs
+ double[][] sProb = new double[5][5];
+
+ for(int i=0; i<sProb.length; i++) {
+ for(int j=0; j<sProb.length; j++) {
+ if(i==j) {
+ sProb[i][j] = (double) 1d/5d+4d/5d*Math.exp(-5d/4d*dist);
+ } else {
+ sProb[i][j] = (double) 1d/5d-1d/5d*Math.exp(-5d/4d*dist);
+ }
+ }
+ }
+
+ if(table == 1) {
+ substProb1 = sProb;
+ } else {
+ substProb2 = sProb;
+ }
+ }
+
+ void setGapPam() {
+
+ // Compute new character freqs.
+ charFreqs = new double[21];
+ for(int i=0; i<20; i++) {
+ charFreqs[i] = aaFreqs[i]*(1-gapFreq);
+ }
+ charFreqs[20] = gapFreq;
+
+ // Add gap to PAM1 matrix.
+ gapPam = new double[21][21];
+ for(int i=0; i<20; i++) {
+ gapPam[i][20] = gapProb;
+ gapPam[20][i] = gapProb;
+ }
+ gapPam[20][20] = 1-20*gapProb;
+
+ for(int i=0; i<20; i++) {
+ for(int j=0; j<20; j++) {
+ gapPam[i][j] = aaPam[i][j]*(1-gapPam[20][i]);
+ }
+ }
+
+ // Scale matrix to PAM1.
+ double sum = 0d;
+ for(int i=0; i<21; i++) {
+ sum += charFreqs[i]*(1-gapPam[i][i]);
+ }
+ for(int i=0; i<21; i++) {
+ for(int j=0; j<21; j++) {
+ gapPam[i][j] = gapPam[i][j]*(0.01d/sum);
+ }
+ }
+
+ for(int i=0; i<21; i++) {
+ sum = 0d;
+ for(int j=0; j<21; j++) {
+ if(j!=i) {
+ sum += gapPam[i][j];
+ }
+ }
+ gapPam[i][i] = 1-sum;
+ }
+ }
+
+ void setProtSubstTable(double num, int table) {
+
+ double[][] sProb = gapPam;
+ double[][] newProb;
+
+ for(int n=1; n<num; n++) {
+ newProb = new double[21][21];
+ for(int i=0; i<21; i++) {
+ for(int j=0; j<21; j++) {
+ double sum = 0d;
+ for(int k=0; k<21; k++) {
+ sum += gapPam[k][j]*sProb[i][k];
+ }
+ newProb[i][j] = sum;
+ }
+ }
+ sProb = newProb;
+ }
+
+ if(table == 1) {
+ substProb1 = sProb;
+ } else {
+ substProb2 = sProb;
+ }
+ }
+
+ void printDebug() {
+
+ if(ProAlign.DEBUG) {
+ ProAlign.log(" preset variables:");
+ ProAlign.log(" delta: "+delta);
+ ProAlign.log(" epsilon: "+epsilon);
+ ProAlign.log(" model: "+modelName+"\n");
+ ProAlign.log(" alphabet: "+alphabet);
+ ProAlign.log(" character freqs:");
+ for(int i=0; i<charFreqs.length; i++) {
+ ProAlign.log.print(" "+charFreqs[i]);
+ }
+ ProAlign.log("");
+ }
+ }
+
+}
diff --git a/TraceBackPath.java b/TraceBackPath.java
new file mode 100644
index 0000000..2dbc4c8
--- /dev/null
+++ b/TraceBackPath.java
@@ -0,0 +1,518 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.util.Random;
+
+class TraceBackPath {
+
+ AlignmentLoop al;
+ AlignmentNode an;
+ Random r;
+
+ int warnLimit = 10;
+ int stopLimit = 3;
+ boolean isBandWarning = false;
+
+ int state = 0;
+ int aSize;
+ int[][] cellPath;
+ double[] postProb;
+
+ double siteSum;
+ double trailProb;
+ double logDelta;
+ double logEpsilon;
+ double logMinusEpsilon;
+
+ int sampleTimes = 0;
+ boolean isUnique = true;
+ boolean BEST;
+
+ TraceBackPath(AlignmentNode an, AlignmentLoop al) {
+
+ this.an = an;
+ this.al = al;
+ r = new Random();
+
+ logDelta = Math.log(al.pa.sm.delta);
+ logEpsilon = Math.log(al.pa.sm.epsilon);
+ logMinusEpsilon = Math.log(1-al.pa.sm.epsilon);
+
+ ProAlign.log("TraceBackPath");
+ }
+
+ double[][] getNode(boolean best) throws TraceBackException {
+
+ this.BEST = best;
+ this.aSize = al.aSize;
+ char path = getEndPath();
+ int i=al.pathM.length-1; // back trace strting point (i,j)
+ int j=al.endPoint;
+
+ double[][] cProb = new double[i+j][aSize]; // char. probs. on the path
+ double[] pProb = new double[i+j]; // post. probs. on the path
+ int[][] cell = new int[i+j][2];
+ int ppc = 0;
+
+ // go through the matrix;
+ // start from end, stop when at (1,1)
+ while(true) {
+
+ if(j<stopLimit || j>ProAlign.bandWidth-stopLimit) {
+ throw new TraceBackException("traceback path comes too close to the band edge.");
+
+ } else if(j<warnLimit || j>ProAlign.bandWidth-warnLimit) {
+ isBandWarning = true;
+ }
+
+ if(i==1 && j==al.MIDDLE) { // currently(?) stops at middle
+ break;
+ }
+
+ if(state==0) { // -> match
+
+ path = getPathM(i,j);
+
+ for(int l=0; l<aSize; l++) {
+ cProb[ppc][l] = al.price[i][j][l];
+ }
+ cell[ppc][0] = i;
+ cell[ppc][1] = j-al.MIDDLE+i;
+ pProb[ppc++] = (al.fwdM[i][j]+al.bwdM[i][j])-al.fwdEnd;
+ i--;
+
+ if(path=='X') {
+ state = 1;
+ }else if(path=='Y') {
+ state = 2;
+ }
+ }
+
+
+ else if(state==1) { // -> gap X
+
+ path = getPathX(i,j);
+
+ for(int l=0; l<aSize; l++) {
+ cProb[ppc][l] = al.priceX[i][j][l];
+ }
+ cell[ppc][0] = i;
+ cell[ppc][1] = -1;
+ pProb[ppc++] = (al.fwdX[i][j]+al.bwdX[i][j])-al.fwdEnd;
+
+ i--;j++;
+
+ if(path=='m') {
+ state = 0;
+ }
+ }
+
+ else if(state==2) { // -> gap Y
+
+ path = getPathY(i,j);
+ for(int l=0; l<aSize; l++) {
+ cProb[ppc][l] = al.priceY[i][j][l];
+ }
+
+ cell[ppc][0] = -1;
+ cell[ppc][1] = j-al.MIDDLE+i;
+ pProb[ppc++] = (al.fwdY[i][j]+al.bwdY[i][j])-al.fwdEnd;
+
+ j--;
+ if(path=='m') {
+ state = 0;
+ }
+ }
+ }
+
+ double[][] charProb;
+
+ if(an.hasTrailers) { // trailing sequence(s) cut out
+
+ int start = Math.max(an.start0,an.start1);
+ int end = Math.max(an.end0,an.end1);
+ int length = ppc+start+end;
+ trailProb = 0d;
+ charProb = new double[length][aSize];
+ cellPath = new int[length][2];
+ postProb = new double[length];
+ if(start>0) {
+ if(an.start0>an.start1) {
+ for(int k=0; k<start; k++) {
+ charProb[k] = trailerCharProb1(k);
+ cellPath[k][0] = k+2;
+ cellPath[k][1] = -1;
+ postProb[k] = 0d;
+ trailProb += Math.log(siteSum)+logEpsilon;
+ }
+ trailProb = trailProb+logMinusEpsilon-logEpsilon;
+
+ for(int k=0; k<ppc; k++) {
+ double sum = 0d;
+ for(int l=0; l<aSize; l++) {
+ sum += cProb[ppc-k-1][l];
+ }
+ for(int l=0; l<aSize; l++) {
+ charProb[k+start][l] = cProb[ppc-k-1][l]/sum;
+ }
+ if(cell[ppc-k-1][0]>0) {
+ cellPath[k+start][0] = cell[ppc-k-1][0]+start;
+ } else {
+ cellPath[k+start][0] = cell[ppc-k-1][0];
+ }
+ cellPath[k+start][1] = cell[ppc-k-1][1];
+ postProb[k+start] = pProb[ppc-k-1];
+ }
+
+ } else {
+ for(int k=0; k<start; k++) {
+ charProb[k] = trailerCharProb2(k);
+ cellPath[k][0] = -1;
+ cellPath[k][1] = k+2;
+ postProb[k] = 0d;
+ trailProb += Math.log(siteSum)+logEpsilon;
+ }
+ trailProb = trailProb+logMinusEpsilon-logEpsilon;
+
+ for(int k=0; k<ppc; k++) {
+ double sum = 0d;
+ for(int l=0; l<aSize; l++) {
+ sum += cProb[ppc-k-1][l];
+ }
+ for(int l=0; l<aSize; l++) {
+ charProb[k+start][l] = cProb[ppc-k-1][l]/sum;
+ }
+ cellPath[k+start][0] = cell[ppc-k-1][0];
+ if(cell[ppc-k-1][1]>0) {
+ cellPath[k+start][1] = cell[ppc-k-1][1]+start;
+ } else {
+ cellPath[k+start][1] = cell[ppc-k-1][1];
+ }
+ postProb[k+start] = pProb[ppc-k-1];
+ }
+ }
+ } else {
+
+ for(int k=0; k<ppc; k++) {
+ double sum = 0d;
+ for(int l=0; l<aSize; l++) {
+ sum += cProb[ppc-k-1][l];
+ }
+ for(int l=0; l<aSize; l++) {
+ charProb[k][l] = cProb[ppc-k-1][l]/sum;
+ }
+ cellPath[k][0] = cell[ppc-k-1][0];
+ cellPath[k][1] = cell[ppc-k-1][1];
+ postProb[k] = pProb[ppc-k-1];
+ }
+
+ }
+ if(end>0) {
+ if(an.end0>an.end1) {
+
+ for(int k=0; k<end; k++) {
+ int p = an.child[0].charProb.length-end+k;
+ charProb[ppc+start+k] = trailerCharProb1(p);
+ cellPath[ppc+start+k][0] = p+2;
+ cellPath[ppc+start+k][1] = -1;
+ postProb[ppc+start+k] = 0d;
+ trailProb += Math.log(siteSum)+logEpsilon;
+ }
+
+ if(getEndPath()=='M') {
+ trailProb = trailProb+logDelta-logEpsilon;
+ }
+
+ } else {
+
+ for(int k=0; k<end; k++) {
+ int p = an.child[1].charProb.length-end+k;
+ charProb[ppc+start+k] = trailerCharProb2(p);
+ cellPath[ppc+start+k][0] = -1;
+ cellPath[ppc+start+k][1] = p+2;
+ postProb[ppc+start+k] = 0d;
+ trailProb += Math.log(siteSum)+logEpsilon;
+ }
+
+ if(getEndPath()=='M') {
+ trailProb = trailProb+logDelta-logEpsilon;
+ }
+ }
+ }
+ return charProb;
+
+ } else { // no trailing sequences removed
+
+ charProb = new double[ppc][aSize];
+
+ cellPath = new int[ppc][2];
+ postProb = new double[ppc];
+
+ for(int k=0; k<ppc; k++) {
+ double sum = 0d;
+ for(int l=0; l<aSize; l++) {
+ sum += cProb[ppc-k-1][l];
+ }
+ for(int l=0; l<aSize; l++) {
+ charProb[k][l] = cProb[ppc-k-1][l]/sum;
+ }
+ cellPath[k][0] = cell[ppc-k-1][0];
+ cellPath[k][1] = cell[ppc-k-1][1];
+ postProb[k] = pProb[ppc-k-1];
+ }
+ return charProb;
+ }
+ }
+
+ // get path to go backwards;
+ // select either best (viterbi) or sample from probabilities
+
+ char getEndPath() {
+
+ char path = ' ';
+ double pm = al.pathEnd[0];
+ double px = al.pathEnd[1];
+ double py = (double) 1d - pm - px;
+
+ // select viterbi path; if equally good, take one randomly
+ if(BEST) {
+ if(pm > px && pm > py) {
+ path = 'M';
+ } else if(pm > py && pm == px) {
+ if(r.nextBoolean()) {
+ path = 'M';
+ } else {
+ path = 'x';
+ state = 1;
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else if(pm > px && pm == py) {
+ if(r.nextBoolean()) {
+ path = 'M';
+ } else {
+ path = 'y';
+ state = 2;
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else if(px > py) {
+ path = 'x';
+ state = 1;
+ } else if(px == py) {
+ if(r.nextBoolean()) {
+ path = 'x';
+ state = 1;
+ } else {
+ path = 'y';
+ state = 2;
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else {
+ path = 'y';
+ state = 2;
+ }
+
+ // sample from paths according to their probabilities
+ } else {
+ double rdn = r.nextDouble();
+ if(rdn < pm) {
+ path = 'M';
+ } else if(rdn < (pm+px)) {
+ path = 'X';
+ state = 1;
+ } else {
+ path = 'Y';
+ state = 2;
+ }
+ }
+
+ return path;
+ }
+
+ char getPathM(int i, int j) {
+
+ char path = ' ';
+ double pm = al.pathM[i][j][0];
+ double px = al.pathM[i][j][1];
+ double py = (double) 1d - pm - px;
+
+ // select viterbi path; if equally good, take one randomly
+ if(BEST) {
+ if(pm > px && pm > py) {
+ path = 'M';
+ } else if(pm > py && pm == px) {
+ if(r.nextBoolean()) {
+ path = 'M';
+ } else {
+ path = 'X';
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else if(pm > px && pm == py) {
+ if(r.nextBoolean()) {
+ path = 'M';
+ } else {
+ path = 'Y';
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else if(px > py) {
+ path = 'X';
+ } else if(px == py) {
+ if(r.nextBoolean()) {
+ path = 'X';
+ } else {
+ path = 'Y';
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else {
+ path = 'Y';
+ }
+
+ // sample from paths according to their probabilities
+ } else {
+ double rdn = r.nextDouble();
+ if(rdn < pm) {
+ path = 'M';
+ } else if(rdn < (pm+px)) {
+ path = 'X';
+ } else {
+ path = 'Y';
+ }
+ }
+
+ return path;
+ }
+
+ char getPathX(int i, int j) {
+
+ char path = ' ';
+ double pm = al.pathX[i][j];
+ double px = (double) 1d - pm;
+
+ if(BEST) {
+ if(pm > px) {
+ path = 'm';
+ } else if( pm == px) {
+ if(r.nextBoolean()) {
+ path = 'm';
+ } else {
+ path = 'x';
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else {
+ path = 'x';
+ }
+
+ } else {
+ double rdn = r.nextDouble();
+ if(rdn < pm) {
+ path = 'm';
+ } else {
+ path = 'x';
+ }
+ }
+
+ return path;
+ }
+
+ char getPathY(int i, int j) {
+
+ char path = ' ';
+ double pm = al.pathY[i][j];
+ double py = (double) 1d - pm;
+
+ if(BEST) {
+ if(pm > py) {
+ path = 'm';
+ } else if( pm == py) {
+ if(r.nextBoolean()) {
+ path = 'm';
+ } else {
+ path = 'y';
+ }
+ isUnique = false;
+ sampleTimes++;
+ } else {
+ path = 'y';
+ }
+
+ } else {
+ double rdn = r.nextDouble();
+ if(rdn < pm) {
+ path = 'm';
+ } else {
+ path = 'y';
+ }
+ }
+
+ return path;
+ }
+
+ double[] trailerCharProb1(int i) {
+
+ double[] cProb = new double[aSize];
+ siteSum = 0d;
+ for(int k=0; k<aSize; k++) {
+ for(int l = 0; l<aSize; l++) {
+ cProb[k] += an.child[0].charProb[i][l]*al.pa.sm.substProb1[k][l];
+ }
+ cProb[k] = cProb[k]*al.pa.sm.substProb2[k][aSize-1]*al.pa.sm.charFreqs[k];
+ siteSum += cProb[k];
+ }
+ for(int k=0; k<aSize; k++) {
+ cProb[k] = cProb[k]/siteSum;
+ }
+ return cProb;
+ }
+
+ double[] trailerCharProb2(int i) {
+
+ double[] cProb = new double[aSize];
+ siteSum = 0d;
+ for(int k=0; k<aSize; k++) {
+ for(int l = 0; l<aSize; l++) {
+ cProb[k] += an.child[1].charProb[i][l]*al.pa.sm.substProb2[k][l];
+ }
+ cProb[k] = cProb[k]*al.pa.sm.substProb1[k][aSize-1]*al.pa.sm.charFreqs[k];
+ siteSum += cProb[k];
+ }
+ for(int k=0; k<aSize; k++) {
+ cProb[k] = cProb[k]/siteSum;
+ }
+ return cProb;
+ }
+}
+
+class TraceBackException extends Exception {
+
+ public TraceBackException() {}
+ public TraceBackException(String msg) {
+ super(msg);
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/TransformLog.java b/TransformLog.java
new file mode 100644
index 0000000..cf7adad
--- /dev/null
+++ b/TransformLog.java
@@ -0,0 +1,36 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class TransformLog {
+
+ TransformLog() { }
+ double sumLogs(double a, double b) {
+ if(Double.isNaN(a) && Double.isNaN(b)) {
+ return Double.NEGATIVE_INFINITY;
+ }
+ else if(Double.isNaN(a)){
+ return b;
+ }
+ else if(Double.isNaN(b)){
+ return a;
+ }
+ if(b>a){
+ double c = a;
+ a = b;
+ b = c;
+ }
+ return (a+Math.log(1+Math.exp(b-a)));
+ }
+}
+
+
+
diff --git a/TreeNode.java b/TreeNode.java
new file mode 100644
index 0000000..52561b9
--- /dev/null
+++ b/TreeNode.java
@@ -0,0 +1,317 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class TreeNode {
+
+ String tree;
+ String[] subTrees;
+ String[] revTrees;
+ static String mpTree;
+
+ TreeNode parent;
+ TreeNode child0;
+ TreeNode child1;
+
+ static float halfLength;
+ static float maxSpan;
+ static float minDiff;
+ float[] subDistances;
+ float maxLength = 0f;
+ float totalDist = 0f; // weight
+
+
+ boolean isLast = true;
+
+ TreeNode(String t) {
+
+ mpTree = new String();
+ minDiff = 100f;
+
+ ProAlign.log("TreeNode");
+
+ tree = t;
+ TreeReader tr = new TreeReader();
+
+ subTrees = tr.divideTree(tree);
+ subDistances = tr.distance;
+ subDistances[0] = Math.abs(subDistances[0]);
+ subDistances[1] = Math.abs(subDistances[1]);
+
+// System.out.println(subTrees[0]+" "+subTrees[1]);
+
+ float tot = subDistances[0]+subDistances[1];
+ revTrees = new String[2];
+ revTrees[0] = subTrees[1]+":"+tot;
+ revTrees[1] = subTrees[0]+":"+tot;
+
+ child0 = new TreeNode(tr,subTrees[0],TreeNode.this,0);
+ child1 = new TreeNode(tr,subTrees[1],TreeNode.this,1);
+
+ totalDist = subDistances[0]+subDistances[1]+
+ child0.totalDist+child1.totalDist;
+
+ float currPair = subDistances[0]+child0.maxLength+
+ subDistances[1]+child1.maxLength;
+ if(currPair > TreeNode.maxSpan) {
+ TreeNode.maxSpan = currPair;
+// System.out.println("ms0 "+child0.tree+":"+subDistances[0]+" | "+
+// child1.tree+":"+subDistances[1]+" "+currPair);
+ }
+ }
+
+ TreeNode(TreeReader tr,String t,TreeNode p,int branch) {
+
+ tree = t;
+ parent = p;
+
+ if(tree.indexOf(",")>0) {
+
+ isLast = false;
+ subTrees = tr.divideTree(tree);
+ subDistances = tr.distance;
+ subDistances[0] = Math.abs(subDistances[0]);
+ subDistances[1] = Math.abs(subDistances[1]);
+
+ revTrees = new String[2];
+ revTrees[0] = "("+parent.revTrees[branch]+","+
+ subTrees[1]+":"+subDistances[1]+"):"+subDistances[0];
+ revTrees[1] = "("+parent.revTrees[branch]+","+
+ subTrees[0]+":"+subDistances[0]+"):"+subDistances[1];
+
+ child0 = new TreeNode(tr,subTrees[0],TreeNode.this,0);
+ child1 = new TreeNode(tr,subTrees[1],TreeNode.this,1);
+
+ totalDist = subDistances[0]+subDistances[1]+
+ child0.totalDist+child1.totalDist;
+
+ float currPair = subDistances[0]+child0.maxLength+
+ subDistances[1]+child1.maxLength;
+ if(currPair > TreeNode.maxSpan) {
+ TreeNode.maxSpan = currPair;
+// System.out.println("ms1 "+child0.tree+":"+subDistances[0]+" | "+
+// child1.tree+":"+subDistances[1]+" "+currPair);
+ }
+ if(subDistances[0]+child0.maxLength > subDistances[1]+child1.maxLength) {
+ maxLength = subDistances[0]+child0.maxLength;
+ } else {
+ maxLength = subDistances[1]+child1.maxLength;
+ }
+// System.out.println("ml "+maxLength);
+ }
+ }
+
+ String findMiddlePoint() {
+
+ TreeNode.halfLength = TreeNode.maxSpan/2f;
+
+ if(TreeNode.halfLength > child0.maxLength &&
+ TreeNode.halfLength < child0.maxLength+subDistances[0]+subDistances[1]) {
+
+ float b0 = TreeNode.halfLength-child0.maxLength;
+ float b1 = subDistances[0]+subDistances[1]-b0;
+
+ TreeNode.mpTree = "("+child0.tree+": "+b0+","+child1.tree+":"+b1+");";
+ }
+
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+ ProAlign.log("mprooted: "+TreeNode.mpTree);
+ return TreeNode.mpTree;
+ }
+
+ void findMiddle(int branch) {
+ if(!isLast) {
+
+ if(branch==0) {
+
+ if(TreeNode.halfLength > child0.maxLength &&
+ TreeNode.halfLength < child0.maxLength+subDistances[0]) {
+
+ float b0 = TreeNode.halfLength-child0.maxLength;
+ float b1 = subDistances[0]-b0;
+
+ TreeNode.mpTree = "("+child0.tree+": "+b0+",("+parent.revTrees[1]+","+
+ subTrees[1]+":"+subDistances[1]+"):"+b1+");";
+
+// System.out.println("nt "+branch+": "+child0.tree+" "+child0.maxLength+" "+
+// child1.tree+" "+child1.maxLength+" "+TreeNode.halfLength+" "+TreeNode.minDiff);
+ }
+
+ if(TreeNode.halfLength > child1.maxLength &&
+ TreeNode.halfLength < child1.maxLength+subDistances[1]) {
+
+ float b0 = TreeNode.halfLength-child1.maxLength;
+ float b1 = subDistances[1]-b0;
+
+ TreeNode.mpTree = "("+child1.tree+": "+b0+",("+parent.revTrees[1]+","+
+ subTrees[0]+":"+subDistances[0]+"):"+b1+");";
+
+// System.out.println("nt "+branch+": "+child0.tree+" "+child0.maxLength+" "+
+// child1.tree+" "+child1.maxLength+" "+TreeNode.halfLength+" "+TreeNode.minDiff);
+
+ }
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+
+ } else {
+
+ if(TreeNode.halfLength > child0.maxLength &&
+ TreeNode.halfLength < child0.maxLength+subDistances[0]) {
+
+ float b0 = TreeNode.halfLength-child0.maxLength;
+ float b1 = subDistances[0]-b0;
+
+ TreeNode.mpTree = "("+child0.tree+": "+b0+",("+parent.revTrees[0]+
+ ","+subTrees[1]+":"+subDistances[1]+"):"+b1+");";
+
+// System.out.println("nt "+branch+": "+child0.tree+" "+child0.maxLength+" "+
+// child1.tree+" "+child1.maxLength+" "+TreeNode.halfLength+" "+TreeNode.minDiff);
+
+ }
+
+
+ if(TreeNode.halfLength > child1.maxLength &&
+ TreeNode.halfLength < child1.maxLength+subDistances[1]) {
+
+ float b0 = TreeNode.halfLength-child1.maxLength;
+ float b1 = subDistances[1]-b0;
+
+ TreeNode.mpTree = "("+child1.tree+": "+b0+",("+parent.revTrees[0]+
+ ","+subTrees[0]+":"+subDistances[0]+"):"+b1+");";
+
+// System.out.println("nt "+branch+": "+child0.tree+" "+child0.maxLength+" "+
+// child1.tree+" "+child1.maxLength+" "+TreeNode.halfLength+" "+TreeNode.minDiff);
+
+ }
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+ }
+ }
+ }
+
+
+/*
+This was the first attempt for the tree rooting. Not used anymore.
+*/
+
+ String findMiddleWeightPoint() {
+ TreeNode.halfLength = totalDist/2f;
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+ ProAlign.log("mprooted: "+TreeNode.mpTree);
+ return TreeNode.mpTree;
+ }
+
+ void findMiddleWeight(int branch) {
+ if(!isLast) {
+
+ if(branch==0) {
+ if(Math.abs(TreeNode.halfLength-child0.totalDist)<TreeNode.minDiff) {
+
+ TreeNode.minDiff = Math.abs(TreeNode.halfLength-child0.totalDist);
+ float b0,b1;
+ if(TreeNode.halfLength>child0.totalDist) {
+ b0 = TreeNode.halfLength-child0.totalDist;
+ b1 = subDistances[0]-b0;
+ } else if(subDistances[0]>0.001f) {
+ b0 = 0.001f;
+ b1 = subDistances[0]-b0;
+ } else {
+ b0 = 0f;
+ b1 = subDistances[0];
+ }
+ TreeNode.mpTree = "("+child0.tree+": "+b0+",("+parent.revTrees[1]+","+
+ subTrees[1]+":"+subDistances[1]+"):"+b1+");";
+ }
+
+ if(Math.abs(TreeNode.halfLength-child1.totalDist)<TreeNode.minDiff) {
+
+ TreeNode.minDiff = Math.abs(TreeNode.halfLength-child1.totalDist);
+ float b0,b1;
+ if(TreeNode.halfLength>child1.totalDist) {
+ b0 = TreeNode.halfLength-child1.totalDist;
+ b1 = subDistances[1]-b0;
+ } else if(subDistances[1]>0.001f) {
+ b0 = 0.001f;
+ b1 = subDistances[1]-b0;
+ } else {
+ b0 = 0f;
+ b1 = subDistances[1];
+ }
+ TreeNode.mpTree = "("+child1.tree+": "+b0+",("+parent.revTrees[1]+","+
+ subTrees[0]+":"+subDistances[0]+"):"+b1+");";
+ }
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+
+ } else {
+ if(Math.abs(TreeNode.halfLength-child0.totalDist)<TreeNode.minDiff) {
+
+ TreeNode.minDiff = Math.abs(TreeNode.halfLength-child0.totalDist);
+ float b0,b1;
+ if(TreeNode.halfLength>child0.totalDist) {
+ b0 = TreeNode.halfLength-child0.totalDist;
+ b1 = subDistances[0]-b0;
+ } else if(subDistances[0]>0.001f) {
+ b0 = 0.001f;
+ b1 = subDistances[0]-b0;
+ } else {
+ b0 = 0f;
+ b1 = subDistances[0];
+ }
+ TreeNode.mpTree = "("+child0.tree+": "+b0+",("+parent.revTrees[0]+
+ ","+subTrees[1]+":"+subDistances[1]+"):"+b1+");";
+ }
+
+ if(Math.abs(TreeNode.halfLength-child1.totalDist)<TreeNode.minDiff) {
+
+ TreeNode.minDiff = Math.abs(TreeNode.halfLength-child1.totalDist);
+ float b0,b1;
+ if(TreeNode.halfLength>child1.totalDist) {
+ b0 = TreeNode.halfLength-child1.totalDist;
+ b1 = subDistances[1]-b0;
+ } else if(subDistances[1]>0.001f) {
+ b0 = 0.001f;
+ b1 = subDistances[1]-b0;
+ } else {
+ b0 = 0f;
+ b1 = subDistances[1];
+ }
+ TreeNode.mpTree = "("+child1.tree+": "+b0+",("+parent.revTrees[0]+
+ ","+subTrees[0]+":"+subDistances[0]+"):"+b1+")";
+ }
+ child0.findMiddle(1);
+ child1.findMiddle(0);
+ }
+ }
+ }
+
+ void printNames() {
+ if(isLast) {
+ System.out.println(tree);
+ } else {
+ child0.printNames();
+ child1.printNames();
+ System.out.println("node: "+totalDist);
+ }
+ }
+ /*
+ public static void main(String[] args) {
+
+ TreeReader2 tr = new TreeReader2();
+ String tree = tr.readFile(args[0]);
+ TreeNode root = new TreeNode(tree);
+ TreeNode.halfLength = root.totalDist/2f;
+ System.out.println(root.findMiddlePoint());
+ }
+ //*/
+}
diff --git a/TreeReader.java b/TreeReader.java
new file mode 100644
index 0000000..3f0eb82
--- /dev/null
+++ b/TreeReader.java
@@ -0,0 +1,226 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+
+class TreeReader {
+
+ float[] distance;
+ boolean isUnRooted = false;
+
+ TreeReader(){
+
+ }
+
+ // Read a tree from a file and remove branch lengths
+ //
+ String readFile(String filename) {
+
+ String tree = new String();
+
+ ProAlign.log("TreeReader: "+filename);
+
+ try {
+ InFile in = new InFile(filename);
+
+ String row = new String();
+ while((row = in.readLine()) != null) {
+ tree += row;
+ }
+ } catch (Exception e) {}
+
+ return tree;
+ }
+
+ // Take a tree and divide it into two subtrees.
+ // Notice that clustalw root is trifurcating
+ //
+ String[] divideTree(String tree) {
+
+// System.out.println("tree "+tree+"\n");
+
+ String[] trees = new String[2];
+ distance = new float[2];
+ trees[0] = "";
+
+ if(tree.endsWith(";")) {
+ tree = tree.substring(0,tree.length()-1); // remove last ';'
+ }
+ tree = tree.substring(1,tree.length()-1); // remove first & last '('
+
+
+ if(tree.charAt(0)!='(') { // only one taxon
+
+ String tmp = tree.substring(0,tree.indexOf(","));
+ trees[0] = tmp.substring(0,tmp.indexOf(":"));
+ distance[0] = new Float(tmp.substring(tmp.indexOf(":")+1)).floatValue();
+
+ boolean trifurc = false;
+ int open = 0;
+ for(int j = tree.indexOf(",")+1; j<tree.length(); j++) {
+ if(tree.charAt(j)=='(') { open++; }
+ else if(tree.charAt(j)==')') { open--; }
+ if(open==0 && tree.substring(j).indexOf(",")>0) {
+ trifurc = true;
+ }
+ }
+
+ // correction for trifurcating root
+ if(trifurc) {
+
+ isUnRooted = true;
+ trees[1] = "("+tree.substring(tree.indexOf(",")+1)+")";
+ distance[0] = distance[0]/2f;
+ distance[1] = distance[0];
+
+ } else {
+
+ trees[1] = tree.substring(tree.indexOf(",")+1,tree.lastIndexOf(":"));
+ tmp = tree.substring(tree.lastIndexOf(":")+1);
+ distance[1] = new Float(tmp).floatValue();
+ }
+
+// System.out.println("1o: "+trees[0]+" "+distance[0]+"\n");
+// System.out.println("2o: "+trees[1]+" "+distance[1]+"\n");
+
+ } else {
+
+ int open = 0;
+
+ for(int i=0; i<tree.length(); i++) {
+
+ // count parentheses that are "open"
+ if(tree.charAt(i)=='(') { open++; }
+ else if(tree.charAt(i)==')') { open--; }
+ trees[0] += ""+tree.charAt(i);
+
+ if(open<=0) {
+ String tmp = tree.substring(i+2,tree.indexOf(",",i+2));
+ distance[0] = new Float(tmp).floatValue();
+
+ boolean trifurc = false;
+ open = 0;
+ for(int j = tree.indexOf(",",i+2)+1; j<tree.length(); j++) {
+ if(tree.charAt(j)=='(') { open++; }
+ else if(tree.charAt(j)==')') { open--; }
+ if(open==0 && tree.substring(j).indexOf(",")>0) {
+ trifurc = true;
+ }
+ }
+
+ // correction for trifurcating root
+ if(trifurc) {
+
+ isUnRooted = true;
+ trees[1] = "("+tree.substring(tree.indexOf(",",i+2)+1)+")";
+ distance[0] = distance[0]/2f;
+ distance[1] = distance[0];
+
+// System.out.println("1: "+trees[0]+" "+distance[0]+"\n");
+// System.out.println("2a: "+trees[1]+" "+distance[1]+"\n");
+
+ } else {
+
+ tmp = tree.substring(tree.indexOf(",",i+2)+1);
+ trees[1] = tmp.substring(0,tmp.lastIndexOf(":"));
+
+ tmp = tmp.substring(tmp.lastIndexOf(":")+1);
+ distance[1] = new Float(tmp).floatValue();
+
+// System.out.println("1: "+trees[0]+" "+distance[0]+"\n");
+// System.out.println("2b: "+trees[1]+" "+distance[1]+"\n");
+
+ }
+
+ break;
+ }
+ }
+
+ }
+
+ //System.out.println("0: "+trees[0]+" ["+distance[0]+"]");
+ //System.out.println("1: "+trees[1]+" ["+distance[1]+"]");
+
+ return trees;
+ }
+
+ String[] getAllNodes(String filepath) {
+ ArrayList nl = new ArrayList();
+ TreeReader tr = this;
+ String tree = this.readFile(filepath);
+// if(ProAlign.DEBUG) {
+// ProAlign.log.println(" reading a list of all the nodes.");
+// }
+
+ //System.out.println(clustalw);
+ String[] trees = tr.divideTree(tree);
+
+ tr.loopThroughNodes(trees[0],tr,nl);
+ tr.loopThroughNodes(trees[1],tr,nl);
+
+ String[] nodes = new String[nl.size()];
+ for(int i=0; i<nl.size(); i++) {
+ nodes[i] = (String) nl.get(i);
+ }
+
+ return nodes;
+ }
+
+ void loopThroughNodes(String tree, TreeReader tr, ArrayList nl) {
+ if(tree.indexOf(",")>0) {
+ String[] trees = tr.divideTree(tree);
+ tr.loopThroughNodes(trees[0],tr,nl);
+ tr.loopThroughNodes(trees[1],tr,nl);
+ } else {
+ nl.add(tree);
+ //System.out.println(nl.size()+" "+tree);
+ }
+ }
+
+
+ // ---DEBUGGING ONLY -->
+ void loopTreeTest(String tree, TreeReader tr) {
+ if(tree.indexOf(",")>0) {
+ String[] trees = tr.divideTree(tree);
+ tr.loopTreeTest(trees[0],tr);
+ tr.loopTreeTest(trees[1],tr);
+ } else {
+ //System.out.println("l "+tree);
+ }
+ }
+
+ public static void main(String[] args) {
+
+ TreeReader tr = new TreeReader();
+ String tree = tr.readFile(args[0]);
+ String[] trees = tr.divideTree(tree);
+ tr.loopTreeTest(trees[0],tr);
+ tr.loopTreeTest(trees[1],tr);
+ System.out.println("OK");
+ String[] nodes = tr.getAllNodes(args[0]);
+ for(int i=0; i<nodes.length; i++) {
+ System.out.println(nodes[i]);
+ }
+ }
+ // <--DEBUGGING ONLY ---
+
+}
+
+
+
+
+
+
+
diff --git a/UserSettings.java b/UserSettings.java
new file mode 100644
index 0000000..5dd01f5
--- /dev/null
+++ b/UserSettings.java
@@ -0,0 +1,85 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Reads and writes a file for user settings
+ */
+public class UserSettings {
+
+ String filepath;
+ File file;
+
+ UserSettings() {
+
+ ProAlign.log("UserSettings");
+
+ if(System.getProperty("os.name").startsWith("Windows")){
+ filepath = "proalign.ini";
+ } else {
+ filepath = ".proalignrc";
+ }
+ file = new File(filepath);
+ }
+
+ // Read existing settings
+ String[] readSettings() {
+ String[] userdata = new String[3];
+ String str = new String();
+ if(file.exists()) {
+ try {
+ InFile dataIn = new InFile(filepath);
+ if((str = dataIn.readLine())!=null) {
+ if(new File(str).isDirectory()){
+ userdata[0] = str;
+ }
+ }
+ if((str = dataIn.readLine())!=null) {
+ if(new File(str).isFile()){
+ userdata[1] = str;
+ }
+ }
+ if((str = dataIn.readLine())!=null) {
+ if(new File(str).isDirectory()){
+ userdata[2] = str;
+ }
+ }
+ dataIn.close();
+ } catch (IOException ie) { }
+ }
+ return userdata;
+ }
+
+ // Write current settings
+ void writeSettings(String[] userdata) {
+ if(file.exists()) {
+ try {
+ file.delete();
+ } catch (Exception ie) { }
+ }
+ try {
+ OutFile dataOut = new OutFile(filepath);
+ dataOut.println(userdata[0]); // ProAlign data
+ dataOut.println(userdata[1]); // ProAlign ClustalW
+ dataOut.println(userdata[2]); // temp
+ dataOut.close();
+ } catch (IOException ie) { }
+ }
+}
+
+
+
+
+
+
diff --git a/Viterbi.java b/Viterbi.java
new file mode 100644
index 0000000..aa8cf4a
--- /dev/null
+++ b/Viterbi.java
@@ -0,0 +1,354 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+class Viterbi {
+
+ AlignmentLoop al;
+
+ double[] charFreqs;
+ String alphabet;
+
+ double delta;
+ double epsilon;
+ double logDelta;
+ double logEpsilon;
+ double logMinus2Delta;
+ double logMinusEpsilon;
+
+ double constantM;
+ double constantX;
+ double constantY;
+
+ TransformLog tl;
+
+ int aSize;
+
+ Viterbi(AlignmentLoop al) {
+ this.al = al;
+
+ this.charFreqs = al.pa.sm.charFreqs;
+ this.alphabet = al.pa.sm.alphabet;
+
+ delta = al.pa.sm.delta;
+ epsilon = al.pa.sm.epsilon;
+ logDelta = Math.log(al.pa.sm.delta);
+ logEpsilon = Math.log(al.pa.sm.epsilon);
+ logMinus2Delta = Math.log(1-2*al.pa.sm.delta);
+ logMinusEpsilon = Math.log(1-al.pa.sm.epsilon);
+
+ aSize = al.seq1[0].length; // aSize = alphabet size;
+
+ tl = new TransformLog();
+ }
+
+ // get viterbi value for M-state; set probability of each path to this cell;
+ // pathM[i][j][0] = P(match to M)
+ // pathM[i][j][1] = P(match to X)
+ // 1 - pathM[i][j][0] - pathM[i][j][1] = P(match to Y)
+
+ double getViterbiM(int i, int j) {
+
+ constantM = Math.log(sumOverChars(i,j));
+
+ double max = maxOfThree(logMinus2Delta+al.vitM[i-1][j],
+ logMinusEpsilon+al.vitX[i-1][j],
+ logMinusEpsilon+al.vitY[i-1][j]);
+
+ double pm = logMinus2Delta+al.vitM[i-1][j];
+ double px = logMinusEpsilon+al.vitX[i-1][j];
+ double py = logMinusEpsilon+al.vitY[i-1][j];
+ double sum = tl.sumLogs(pm,tl.sumLogs(px,py));
+
+ al.pathM[i][j][0] = (double) Math.exp(pm-sum);
+ al.pathM[i][j][1] = (double) Math.exp(px-sum);
+
+ return (constantM+max);
+ }
+
+ // get viterbi value for X-state; set probability of each path to this cell;
+ // pathX[i][j] = P(match to M)
+ // 1 - pathX[i][j] = P(match to X)
+
+ double getViterbiX(int i, int j) {
+
+ if(j==al.BWIDTH-1) { // lower border of band, an X-gap impossible
+ return Double.NEGATIVE_INFINITY;
+ }
+
+ constantX = Math.log(sumOverCharsX(i,j));
+
+ double max = maxOfTwoX(logDelta+al.vitM[i-1][j+1],
+ logEpsilon+al.vitX[i-1][j+1]);
+
+ double pm = logDelta+al.vitM[i-1][j+1];
+ double px = logEpsilon+al.vitX[i-1][j+1];
+ double sum = tl.sumLogs(px,pm);
+
+ al.pathX[i][j] = (double) Math.exp(pm-sum);
+
+ return constantX+max;
+ }
+
+ // get viterbi value for X-state; set probability of each path to this cell;
+ // pathY[i][j] = P(match to M)
+ // 1 - pathY[i][j] = P(match to Y)
+
+ double getViterbiY(int i, int j) {
+
+ if(j==0) { // upper border of band, a Y-gap impossible
+ return Double.NEGATIVE_INFINITY;
+ }
+
+ constantY = Math.log(sumOverCharsY(i,j));
+
+ double max = maxOfTwoY(logDelta+al.vitM[i][j-1],
+ logEpsilon+al.vitY[i][j-1]);
+
+ double pm = logDelta+al.vitM[i][j-1];
+ double py = logEpsilon+al.vitY[i][j-1];
+ double sum = tl.sumLogs(py,pm);
+
+ al.pathY[i][j] = (double) Math.exp(pm-sum);
+
+ return constantY+max;
+ }
+
+ // set vierbi end, set forward end,
+ // set probability of each path ending.
+ // pathEnd[0] = P(match to M), pathEnd[1] = P(gap to x)
+ // 1 - pathEnd[0] - pathEnd[1] = P(gap to y)
+ // endPoint is not necessarily MIDDLE!
+
+ double getViterbiEnd(int endPoint) {
+
+ if(al.an.hasTrailers) {
+
+ double pm = al.vitM[al.vitM.length-1][endPoint];
+ double px = al.vitX[al.vitX.length-1][endPoint];
+ double py = al.vitY[al.vitY.length-1][endPoint];
+ double sum;
+
+ if(al.an.end0>al.an.end1) {
+ sum = tl.sumLogs(pm,px);
+ al.pathEnd[0] = (double) Math.exp(pm-sum);
+ al.pathEnd[1] = (double) Math.exp(px-sum);
+
+ al.fwdEnd = (double) tl.sumLogs(al.fwdM[al.fwdM.length-1][endPoint],
+ al.fwdX[al.fwdX.length-1][endPoint]);
+ } else {
+ sum = tl.sumLogs(pm,py);
+ al.pathEnd[0] = (double) Math.exp(pm-sum);
+ al.pathEnd[1] = Double.NEGATIVE_INFINITY;
+
+ al.fwdEnd = (double) tl.sumLogs(al.fwdM[al.fwdM.length-1][endPoint],
+ al.fwdY[al.fwdY.length-1][endPoint]);
+ }
+
+ } else {
+
+ double pm = al.vitM[al.vitM.length-1][endPoint];
+ double px = al.vitX[al.vitX.length-1][endPoint];
+ double py = al.vitY[al.vitY.length-1][endPoint];
+ double sum = tl.sumLogs(pm,tl.sumLogs(px,py));
+
+ al.pathEnd[0] = (double) Math.exp(pm-sum);
+ al.pathEnd[1] = (double) Math.exp(px-sum);
+
+ al.fwdEnd = (double) tl.sumLogs(al.fwdM[al.fwdM.length-1][endPoint],
+ tl.sumLogs(al.fwdX[al.fwdX.length-1][endPoint],
+ al.fwdY[al.fwdY.length-1][endPoint]));
+ }
+
+ return (double) maxOfThree(al.vitM[al.vitM.length-1][endPoint],
+ al.vitX[al.vitX.length-1][endPoint],
+ al.vitY[al.vitY.length-1][endPoint]);
+ }
+
+ double getForwardM(int i, int j) {
+
+ return constantM+tl.sumLogs(logMinus2Delta+al.fwdM[i-1][j],
+ logMinusEpsilon+tl.sumLogs(al.fwdX[i-1][j],al.fwdY[i-1][j]));
+ }
+
+ double getForwardX(int i, int j) {
+
+ if(j==al.BWIDTH-1) { // lower border of band, an X-gap impossible
+ return Double.NEGATIVE_INFINITY;
+ }
+
+ if(j-al.MIDDLE+i==1) { // only X-gaps possible, constant's not set
+ constantX = Math.log(sumOverCharsX(i,j));
+ }
+
+ return constantX+tl.sumLogs(logDelta+al.fwdM[i-1][j+1],logEpsilon+al.fwdX[i-1][j+1]);
+ }
+
+ double getForwardY(int i, int j) {
+
+ if(j==0) { // upper border of band, a Y-gap impossible
+ return Double.NEGATIVE_INFINITY;
+ }
+
+ if(i==1) { // only Y-gaps possible, constant's not set
+ constantY = Math.log(sumOverCharsY(i,j));
+ }
+
+ return constantY+tl.sumLogs(logDelta+al.fwdM[i][j-1],logEpsilon+al.fwdY[i][j-1]);
+ }
+
+ double getBackwardM(int i, int j) {
+
+ if(i==al.vitM.length-1) { // left border of matrix
+
+ constantM = Double.NEGATIVE_INFINITY;
+ constantX = Double.NEGATIVE_INFINITY;
+ constantY = Math.log(sumOverCharsY(i,j+1));
+
+ }else if(j-al.MIDDLE+i==al.seq2.length+1) { // lower border of real matrix
+
+ constantM = Double.NEGATIVE_INFINITY;
+ constantX = Math.log(sumOverCharsX(i+1,j-1));
+ constantY = Double.NEGATIVE_INFINITY;
+
+ }else if(j==0) {
+
+ constantM = Math.log(sumOverChars(i+1,j));
+ constantX = Double.NEGATIVE_INFINITY;
+ constantY = Math.log(sumOverCharsY(i,j+1));
+
+ }else if(j==al.BWIDTH-1) {
+
+ constantM = Math.log(sumOverChars(i+1,j));
+ constantX = Math.log(sumOverCharsX(i+1,j-1));
+ constantY = Double.NEGATIVE_INFINITY;
+
+ } else {
+
+ constantM = Math.log(sumOverChars(i+1,j));
+ constantX = Math.log(sumOverCharsX(i+1,j-1));
+ constantY = Math.log(sumOverCharsY(i,j+1));
+
+ }
+
+ if(j==0) { // upper border of the band; an X-gap impossible
+ return tl.sumLogs(logMinus2Delta+constantM+al.bwdM[i+1][j],
+ logDelta+constantY+al.bwdY[i][j+1]);
+ }
+
+ if(j==al.BWIDTH-1) { // lower border of the band; a Y-gap impossible
+ return tl.sumLogs(logMinus2Delta+constantM+al.bwdM[i+1][j],
+ logDelta+constantX+al.bwdX[i+1][j-1]);
+ }
+
+ return tl.sumLogs(logMinus2Delta+constantM+al.bwdM[i+1][j],
+ logDelta+tl.sumLogs(constantX+al.bwdX[i+1][j-1],
+ constantY+al.bwdY[i][j+1]));
+
+ }
+
+ double getBackwardX(int i, int j) {
+
+ if(j==0) { // upper border of the band; an X-gap impossible
+ return logMinusEpsilon+constantM+al.bwdM[i+1][j];
+ }
+
+ return tl.sumLogs(logMinusEpsilon+constantM+al.bwdM[i+1][j],
+ logEpsilon+constantX+al.bwdX[i+1][j-1]);
+ }
+
+ double getBackwardY(int i, int j) {
+
+ if(j==al.BWIDTH-1) { // lower border of the band; a Y-gap impossible
+ return logMinusEpsilon+constantM+al.bwdM[i+1][j];
+ }
+
+ return tl.sumLogs(logMinusEpsilon+constantM+al.bwdM[i+1][j],
+ logEpsilon+constantY+al.bwdY[i][j+1]);
+ }
+
+
+ // sum over all possible characters [k] at the node [i][j]
+
+ double sumOverChars(int i, int j){
+
+ double sum = 0d;
+ for(int k = 0; k<aSize; k++) {
+ sum += al.price[i][j][k];
+ }
+ return sum;
+ }
+
+ double sumOverCharsX(int i, int j){
+
+ double sum = 0d;
+ for(int k = 0; k<aSize; k++) {
+ sum += al.priceX[i][j][k];
+ }
+ return sum;
+ }
+
+ double sumOverCharsY(int i, int j){
+
+ double sum = 0d;
+ for(int k = 0; k<aSize; k++) {
+ sum += al.priceY[i][j][k];
+ }
+ return sum;
+ }
+
+
+ double maxOfTwoX(double m, double x) {
+ double max = 0d;
+ if(m > x) {
+ max = m;
+ } else {
+ max = x;
+ }
+
+ return max;
+ }
+
+ double maxOfTwoY(double m, double y) {
+ double max = 0d;
+ if(m > y) {
+ max = m;
+ } else {
+ max = y;
+ }
+ return max;
+ }
+
+ double maxOfThree(double m, double x, double y) {
+
+ double max = 0d;
+ if(m > x && m > y) {
+ max = m;
+ } else if(x > y){
+ max = x;
+ } else {
+ max = y;
+ }
+
+ return max;
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WinClustalw.java b/WinClustalw.java
new file mode 100644
index 0000000..e6dafae
--- /dev/null
+++ b/WinClustalw.java
@@ -0,0 +1,55 @@
+/**
+ * Title: ProAlign<p>
+ * Description: <p>
+ * Copyright: Copyright (c) Ari Loytynoja<p>
+ * License: GNU GENERAL PUBLIC LICENSE<p>
+ * @see http://www.gnu.org/copyleft/gpl.html
+ * Company: ULB<p>
+ * @author Ari Loytynoja
+ * @version 1.0
+ */
+package proalign;
+
+public class WinClustalw extends Thread {
+
+ String command;
+ int num;
+ boolean running = true;
+
+ WinClustalw(int num, String command) {
+
+ this.num = num;
+ this.command = command;
+ start();
+ }
+
+ public void run(){
+ runClustalw(num,command);
+ running = false;
+ }
+
+ /**
+ * Run native ClustalW
+ */
+ public native void runClustalw(int num, String cmnd);
+ static {
+ Runtime.getRuntime().load(ProAlign.clustalwPath);
+ }
+
+ /**
+ * Get output and write it in the log.
+ */
+ private void writeout(String txt) {
+ //System.out.println(txt);
+ ProAlign.log(txt);
+ try {
+ sleep(20);
+ } catch(InterruptedException e) {}
+ }
+}
+
+
+
+
+
+
diff --git a/debian/changelog b/debian/changelog
deleted file mode 100644
index e7e0715..0000000
--- a/debian/changelog
+++ /dev/null
@@ -1,12 +0,0 @@
-proalign (0.603-2) unstable; urgency=medium
-
- * Moved debian/upstream to debian/upstream/metadata
- * cme fix dpkg-control
-
- -- Andreas Tille <tille at debian.org> Wed, 13 Jan 2016 12:38:14 +0100
-
-proalign (0.603-1) unstable; urgency=low
-
- * Initial release (Closes: #378290)
-
- -- Thorsten Alteholz <debian at alteholz.de> Tue, 01 May 2013 18:00:00 +0200
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec63514..0000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
deleted file mode 100644
index 764994e..0000000
--- a/debian/control
+++ /dev/null
@@ -1,31 +0,0 @@
-Source: proalign
-Maintainer: Debian Med Packaging Team <debian-med-packaging at lists.alioth.debian.org>
-Uploaders: Andreas Tille <tille at debian.org>,
- Thorsten Alteholz <debian at alteholz.de>
-Section: science
-Priority: optional
-Build-Depends: debhelper (>= 9),
- default-jdk
-Standards-Version: 3.9.6
-Vcs-Browser: http://anonscm.debian.org/viewvc/debian-med/trunk/packages/proalign/trunk/
-Vcs-Svn: svn://anonscm.debian.org/debian-med/trunk/packages/proalign/trunk/
-Homepage: http://ueg.ulb.ac.be/ProAlign/
-
-Package: proalign
-Architecture: any
-Depends: ${shlibs:Depends},
- ${misc:Depends},
- default-jre
-Description: Probabilistic multiple alignment program
- ProAlign performs probabilistic sequence alignments using hidden Markov
- models (HMM). It includes a graphical interface (GUI) allowing to (i)
- perform alignments of nucleotide or amino-acid sequences, (ii) view the
- quality of solutions, (iii) filter the unreliable alignment regions and
- (iv) export alignments to other software.
- .
- ProAlign uses a progressive method, such that multiple alignment is
- created stepwise by performing pairwise alignments in the nodes of a
- guide tree. Sequences are described with vectors of character
- probabilities, and each pairwise alignment reconstructs the ancestral
- (parent) sequence by computing the probabilities of different
- characters according to an evolutionary model.
diff --git a/debian/copyright b/debian/copyright
deleted file mode 100644
index 5f26d57..0000000
--- a/debian/copyright
+++ /dev/null
@@ -1,35 +0,0 @@
-Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
-Upstream-Name: ProAlign
-Upstream-Contact: Ari Löytynoja & Michel C. Milinkovitch
-Source: http://ueg.ulb.ac.be/ProAlign/
-
-Files: *
-Copyright: © 2002-2003 Ari Löytynoja and Michel C. Milinkovitch.
-License: GPL-2+
-
-Files: debian/*
-Copyright: © 2012 Andreas Tille <tille at debian.org>
-License: GPL-2+
-
-License: GPL-2+
- 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 package; if not, write to the Free
- Software Foundation, Inc., 51 Franklin St, Fifth Floor,
- Boston, MA 02110-1301 USA
- .
- On Debian systems, the full text of the GNU General Public
- License version 2 can be found in the file
- `/usr/share/common-licenses/GPL-2'.
-
diff --git a/debian/manifest.txt b/debian/manifest.txt
deleted file mode 100644
index 3497d16..0000000
--- a/debian/manifest.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-version: 1.0
-Main-Class: proalign.ProAlign
-
diff --git a/debian/proalign.1 b/debian/proalign.1
deleted file mode 100644
index 03304e2..0000000
--- a/debian/proalign.1
+++ /dev/null
@@ -1,79 +0,0 @@
-.TH PROALIGN "1" "May 2013" "ProAlign" "User Commands"
-.SH NAME
-proalign \- a probabilistic multiple alignment program
-.SH SYNOPSIS
-.B proalign [OPTIONS]
-.SH DESCRIPTION
-Only limited usage of the program is possible from command line.
-Better use version with GUI (start without OPTIONS).
-.SH OPTIONS
-.TP
-\fB\-nogui\fR
-force command line
-.TP
-\fB-seqfile=<sequence file>\fR
-.TP
-\fB-treefile=<tree file>\fR
-.TP
-\fB-newtree \fR
-compute a new guide tree
-.TP
-\fB-sample \fR
-sample traceback path; if not given, Viterbi is chosen
-.TP
-\fB-delta=<HMM delta> or \-delta=estimate \fR
-if not given, default is used
-.TP
-\fB-epsilon=<HMM epsilon> or \-epsilon=estimate \fR
-if not given, default is used
-.TP
-\fB-gapfreq=<gap frequency> \fR
-if not given, default is used
-.TP
-\fB-gapprob=<gap substitution probability> \fR
-if not given, default is used
-.TP
-\fB-bwidth=<search band width> \fR
-if not given, default is used
-.TP
-\fB-distscale=<distance scale factor> \fR
-for branch lengths
-.TP
-\fB-nocorrection \fR
-no correction for pairwise distances on guide tree computation
-.TP
-\fB-notrailing \fR
-no trailing sequence corrcection
-.TP
-\fB-trailing=<trailing sequence correction length> \fR
-for missing ends
-.TP
-\fB-penalize=true, or =false \fR
-penalize end gaps on pairwise alignments for guide tree
-.TP
-\fB-writemean \fR
-write mean posterior probability of sites
-.TP
-\fB-writeall \fR
-write posterior probability of each node
-.TP
-\fB-writeroot \fR
-write root node character probabilities
-.TP
-\fB-wag \fR
-use WAG probability table
-.TP
-\fB-dayhoff \fR
-use Dayhoff probability table
-.TP
-\fB-jtt \fR
-use JTT probability table
-.TP
-\fB-outfile=<alignment file>\fR
-.TP
-\fB\-outformat=pir, \-outformat=msf, \-outformat=phylip, or \-outformat=nexus \fR
-output format
-.TP
-\fB-quiet \fR
-no log
-
diff --git a/debian/proalign.install b/debian/proalign.install
deleted file mode 100644
index 32cb5c6..0000000
--- a/debian/proalign.install
+++ /dev/null
@@ -1,3 +0,0 @@
-debian/scripts/proalign usr/bin
-build/ProAlign.jar usr/share/proalign
-
diff --git a/debian/proalign.manpages b/debian/proalign.manpages
deleted file mode 100644
index 2958a32..0000000
--- a/debian/proalign.manpages
+++ /dev/null
@@ -1 +0,0 @@
-debian/proalign.1
diff --git a/debian/rules b/debian/rules
deleted file mode 100755
index 71d903a..0000000
--- a/debian/rules
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/make -f
-
-# DH_VERBOSE := 1
-
-%:
- dh $@
-
-override_dh_auto_build:
- mkdir -p build
- javac -d ./build *.java
- (cd build; jar cmvf ../debian/manifest.txt ProAlign.jar *)
- #(cd build; jar cmvf ../debian/manifest.txt ProAlign.jar proalign/ProAlign.class proalign/OutFile.class)
-
-get-orig-source:
- mkdir -p ../tarballs
- uscan --verbose --force-download --destdir=../tarballs
-
diff --git a/debian/scripts/proalign b/debian/scripts/proalign
deleted file mode 100644
index 3024912..0000000
--- a/debian/scripts/proalign
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/sh
-
-PARA=$@
-
-if [ -z $JAVA_HOME ]; then
- java=java
-else
- java=$JAVA_HOME/bin/java
-fi
-
-if [ -x /usr/share/proalign ]; then
- if [ -r /usr/share/proalign/ProAlign.jar ]; then
- #cd /usr/share/proalign && $java -jar ProAlign.jar
- $java -jar /usr/share/proalign/ProAlign.jar $PARA
- else
- echo "Could not find /usr/share/proalign/ProAlign.jar"
- fi
-else
- echo "Could not find /usr/share/proalign directory."
-fi
-
diff --git a/debian/source/format b/debian/source/format
deleted file mode 100644
index 163aaf8..0000000
--- a/debian/source/format
+++ /dev/null
@@ -1 +0,0 @@
-3.0 (quilt)
diff --git a/debian/upstream/metadata b/debian/upstream/metadata
deleted file mode 100644
index 9321bcd..0000000
--- a/debian/upstream/metadata
+++ /dev/null
@@ -1,12 +0,0 @@
-Reference:
- Author: Ari Löytynoja and Michel C Milinkovitch
- Title: A hidden Markov model for progressive multiple alignment
- Journal: Bioinformatics
- Year: 2003
- Volume: 19
- Number: 12
- Pages: 1505-13
- DOI: 10.1093/bioinformatics/btg193
- PMID: 12912831
- URL: http://bioinformatics.oxfordjournals.org/content/19/12/1505
- eprint: http://bioinformatics.oxfordjournals.org/content/19/12/1505.full.pdf+html
diff --git a/debian/watch b/debian/watch
deleted file mode 100644
index a743fa0..0000000
--- a/debian/watch
+++ /dev/null
@@ -1,4 +0,0 @@
-version=3
-
-opts=uversionmangle=s/0/0\./ \
- http://ueg.ulb.ac.be/ProAlign/download/src/proalign_(.+)\.tgz
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/proalign.git
More information about the debian-med-commit
mailing list