/*
* Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
* Copyright (C) $$Year-Rel$$ The Jalview Authors
*
* This file is part of Jalview.
*
* Jalview 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 3
* of the License, or (at your option) any later version.
*
* Jalview 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 Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
package jalview.gui;
import jalview.analysis.AlignSeq;
import jalview.analysis.scoremodels.ScoreMatrix;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPairwiseAlignPanel;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import jalview.math.MiscMath;
import java.awt.event.ActionEvent;
import java.util.Vector;
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
public class PairwiseAlignPanel extends GPairwiseAlignPanel
{
private static final String DASHES = "---------------------\n";
private float[][] scores;
private float[][] alignmentScores; // scores used by PaSiMap
private int GAP_OPEN_COST;
private int GAP_EXTEND_COST;
AlignmentViewport av;
Vector sequences;
private String alignmentOutput;
private boolean quiet;
private boolean discardAlignments;
private boolean endGaps;
// for listening
public static final String TOTAL = "total";
public static final String PROGRESS = "progress";
private int total;
private int progress;
private SequenceGroup selection;
/**
* input sequences
*/
private SequenceI[] seqs=null;
private ScoreMatrix scoreMatrix;
/**
* Creates a new PairwiseAlignPanel object.
*
* @param viewport
* contains selected sequences to align
* @param endGaps ~ toggle gaps and the beginning and end of sequences
*/
public PairwiseAlignPanel(AlignmentViewport viewport)
{
this(viewport, null, false, 120, 20, true, null); // default penalties used in AlignSeq
}
public PairwiseAlignPanel(AlignmentViewport viewport, ScoreMatrix params)
{
this(viewport, null, false, 120, 20, true,params); // default penalties used in AlignSeq
}
public PairwiseAlignPanel(AlignmentViewport viewport, boolean endGaps, int gapOpenCost, int gapExtendCost)
{
this(viewport, null, endGaps, gapOpenCost, gapExtendCost, true, null);
}
/**
* Create a new pairwise alignpanel with specified parameters and score model, and optionally start the calculation
* @param viewport
* @param selection
* @param endGaps
* @param gapOpenCost
* @param gapExtendCost
* @param run
* @param scoreMatrix
*/
public PairwiseAlignPanel(AlignmentViewport viewport, SequenceGroup selection, boolean endGaps,
int gapOpenCost, int gapExtendCost, boolean run, ScoreMatrix scoreMatrix)
{
super();
this.av = viewport;
this.GAP_OPEN_COST = gapOpenCost;
this.GAP_EXTEND_COST = gapExtendCost;
this.endGaps = endGaps;
this.selection = selection;
this.total = MiscMath.combinations(av.getAlignment().getHeight(), 2);
this.scoreMatrix = scoreMatrix;
if (run) {
calculate();
}
}
public void calculate()
{
calculate(scoreMatrix);
}
public void calculate (ScoreMatrix sm)
{
StringBuilder sb = new StringBuilder(1024);
sequences = new Vector();
String[] seqStrings;
seqs=null;
if (selection != null)
{
// given a set of sequences to compare
seqs = selection.getSelectionAsNewSequences(av.getAlignment());
seqStrings = new String[seqs.length];
int s = 0;
for (SequenceI seq : seqs)
{
seqStrings[s++] = seq.getSequenceAsString();
}
}
else
{
SequenceGroup selectionGroup = av.getSelectionGroup();
boolean isSelection = selectionGroup != null
&& selectionGroup.getSize() > 0;
AlignmentView view = av.getAlignmentView(isSelection);
seqStrings = view.getSequenceStrings(av.getGapCharacter());
if (isSelection)
{
seqs = (SequenceI[]) view
.getAlignmentAndHiddenColumns(av.getGapCharacter())[0];
}
else
{
seqs = av.getAlignment().getSequencesArray();
}
}
String type = (av.getAlignment().isNucleotide()) ? AlignSeq.DNA
: AlignSeq.PEP;
float[][] scores = new float[seqs.length][seqs.length];
float[][] alignmentScores = new float[seqs.length][seqs.length];
double totscore = 0D;
int count = seqs.length;
boolean first = true;
progress = 0;
firePropertyChange(TOTAL, 0, total);
for (int i = 1; i < count; i++)
{
// fill diagonal alignmentScores with Float.NaN
alignmentScores[i - 1][i - 1] = Float.NaN;
for (int j = 0; j < i; j++)
{
AlignSeq as = new AlignSeq(seqs[i], seqStrings[i], seqs[j],
seqStrings[j], type, GAP_OPEN_COST, GAP_EXTEND_COST);
if (sm != null) {
as.setScoreMatrix(sm);
}
if (as.s1str.length() == 0 || as.s2str.length() == 0)
{
continue;
}
as.calcScoreMatrix();
if (endGaps)
{
as.traceAlignmentWithEndGaps();
}
else
{
as.traceAlignment();
}
as.scoreAlignment();
if (!first && !quiet)
{
jalview.bin.Console.outPrintln(DASHES);
textarea.append(DASHES);
sb.append(DASHES);
}
first = false;
if (!discardAlignments) {
as.printAlignment(System.out);
}
scores[i][j] = as.getMaxScore() / as.getASeq1().length;
alignmentScores[i][j] = as.getAlignmentScore();
totscore = totscore + scores[i][j];
if (!quiet)
{
textarea.append(as.getOutput());
sb.append(as.getOutput());
}
if (!discardAlignments)
{
sequences.add(as.getAlignedSeq1());
sequences.add(as.getAlignedSeq2());
}
firePropertyChange(PROGRESS, progress, ++progress);
}
}
alignmentScores[count - 1][count - 1] = Float.NaN;
this.scores = scores;
this.alignmentScores = alignmentScores;
if (count > 2 && !quiet)
{
printScoreMatrix(seqs, scores, totscore);
}
alignmentOutput = sb.toString();
}
public float[][] getScores()
{
return this.scores;
}
public float[][] getAlignmentScores()
{
return this.alignmentScores;
}
public String getAlignmentOutput()
{
return this.alignmentOutput;
}
/**
* Prints a matrix of seqi-seqj pairwise alignment scores to sysout
*
* @param seqs
* @param scores
* @param totscore
*/
protected void printScoreMatrix(SequenceI[] seqs, float[][] scores,
double totscore)
{
System.out
.println("Pairwise alignment scaled similarity score matrix\n");
for (int i = 0; i < seqs.length; i++)
{
jalview.bin.Console.outPrintln(
String.format("%3d %s", i + 1, seqs[i].getDisplayId(true)));
}
/*
* table heading columns for sequences 1, 2, 3...
*/
System.out.print("\n ");
for (int i = 0; i < seqs.length; i++)
{
System.out.print(String.format("%7d", i + 1));
}
jalview.bin.Console.outPrintln();
for (int i = 0; i < seqs.length; i++)
{
System.out.print(String.format("%3d", i + 1));
for (int j = 0; j < i; j++)
{
/*
* as a fraction of tot score, outputs are 0 <= score <= 1
*/
System.out.print(String.format("%7.3f", scores[i][j] / totscore));
}
jalview.bin.Console.outPrintln();
}
jalview.bin.Console.outPrintln("\n");
}
/**
* DOCUMENT ME!
*
* @param e
* DOCUMENT ME!
*/
@Override
protected void viewInEditorButton_actionPerformed(ActionEvent e)
{
SequenceI[] seq = new SequenceI[sequences.size()];
for (int i = 0; i < sequences.size(); i++)
{
seq[i] = sequences.elementAt(i);
}
AlignFrame af = new AlignFrame(new Alignment(seq),
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
Desktop.addInternalFrame(af,
MessageManager.getString("label.pairwise_aligned_sequences"),
AlignFrame.DEFAULT_WIDTH, AlignFrame.DEFAULT_HEIGHT);
}
public long getTotal()
{
return total;
}
public long getProgress()
{
return progress;
}
public SequenceI[] getInputSequences()
{
return seqs;
}
/**
* Set to true to suppress output of progress to Console.stdout or GUI
* @param quiet
*/
public void setQuiet(boolean quiet)
{
this.quiet=quiet;
}
/**
* set this if you are only interested in final alignment scores
* @param discard
*/
public void setDiscardAlignments(boolean discard)
{
discardAlignments=discard;
}
}