package aliview.alignment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
import javax.swing.JOptionPane;
import javax.swing.undo.UndoableEdit;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import utils.DialogUtils;
import utils.nexus.CharSet;
import utils.nexus.CharSets;
import utils.nexus.Excludes;
import utils.nexus.NexusRange;
import utils.nexus.NexusUtilities;
import aliview.AliViewExtraNexusUtilities;
import aliview.AminoAcid;
import aliview.Base;
import aliview.GeneticCode;
import aliview.NucleotideUtilities;
import aliview.gui.TextEditDialog;
import aliview.importer.AlignmentImportException;
import aliview.importer.FileFormat;
import aliview.importer.MSFFileIndexer;
import aliview.importer.MSFImporter;
import aliview.importer.SequencesFactory;
import aliview.messenges.Messenger;
import aliview.primer.Dimer;
import aliview.primer.Primer;
import aliview.sequencelist.AlignmentDataListener;
import aliview.sequencelist.AlignmentSelectionEvent;
import aliview.sequencelist.AlignmentSelectionListener;
import aliview.sequencelist.FileSequenceAlignmentListModel;
import aliview.sequencelist.FindObject;
import aliview.sequencelist.MemorySequenceAlignmentListModel;
import aliview.sequencelist.AlignmentListModel;
import aliview.sequencelist.FileSequenceLoadListener;
import aliview.sequences.FastaFileSequence;
import aliview.sequences.InMemorySequence;
import aliview.sequences.PhylipSequence;
import aliview.sequences.Sequence;
import aliview.sequences.SequenceUtils;
import aliview.settings.Settings;
import aliview.utils.ArrayUtilities;
public class Alignment implements FileSequenceLoadListener {
private static final Logger logger = Logger.getLogger(Alignment.class);
private static final String LF = System.getProperty("line.separator");
private static final SequencesFactory seqFactory = new SequencesFactory();
AlignmentListModel sequences;
protected int nextFindSequenceNumber;
protected int nextFindStartPos;
private AlignmentFile alignmentFile;
private int PRIMER_MAX_DEGENERATE_SCORE = 1000;
private boolean isEditedAfterLastSave = false;
private AlignmentMeta alignmentMeta;
private int readingFrame = 1;
private boolean editMode;
private ArrayList<AlignmentListener> alignmentListeners = new ArrayList<AlignmentListener>();
private boolean isSelectable;
public Alignment(){
this(null, new MemorySequenceAlignmentListModel(), new AlignmentMeta());
}
public Alignment(AlignmentListModel sequences) {
this(null, sequences, new AlignmentMeta());
}
public Alignment(File file, AlignmentListModel sequences, AlignmentMeta aliMeta) {
setAlignmentFile(file);
this.sequences = sequences;
this.sequences.setAlignment(this);
//this.sequences.addAlignmentSelectionListener(this);
this.alignmentMeta = aliMeta;
setEditedAfterLastSave(false);
fireAllSequencesAreNew();
}
public void setNewSequencesFromUndo(AlignmentListModel seqs){
this.sequences.setSequences(seqs.getDelegateSequences());
// TODO this should also be read from file
this.alignmentMeta = new AlignmentMeta();
//setEditedAfterLastSave(false);
fireAllSequencesAreNew();
}
public double getApproximateMemorySizeMB(){
double seqSize = sequences.getSize() * sequences.getLongestSequenceLength();
double MB = 1000 * 1000;
return seqSize /MB;
}
public void addAlignmentListener(AlignmentListener l){
alignmentListeners.add(l);
}
public void addAlignmentDataListener(AlignmentDataListener l){
sequences.addAlignmentDataListener(l);
}
public void addAlignmentSelectionListener(AlignmentSelectionListener l){
sequences.addAlignmentSelectionListener(l);
}
private void fireAlignmentMetaOnlyChanged(){
for(AlignmentListener listener: alignmentListeners){
// listener.alignmentMetaChanged(new AlignmentEvent(this));
}
}
// instead listen to sequence change and then set cached histogram
private void fireAllSequencesAreNew(){
for(AlignmentListener listener: alignmentListeners){
listener.newSequences(new AlignmentEvent(this));
}
}
public int getMaxY() {
return sequences.getSize();
}
public byte getBaseAt(int x, int y) {
return sequences.getBaseAt(x,y);
}
public AminoAcid getTranslatedAminoAcidAtNucleotidePos(int x, int y) {
return sequences.getTranslatedAminoAcidAtNucleotidePos(x,y);
}
public int getLengthAt(int y) {
return sequences.getLengthAt(y);
}
// TODO this is the only place where sequences are checked for modification when they are "outside"
public AlignmentListModel getSequences() {
return sequences;
}
public int getMaxX() {
return sequences.getLongestSequenceLength();
}
public int getMaximumSequenceLength() {
return getMaxX();
}
public int getLongestSequenceLength() {
return getMaxX();
}
public int getSize(){
return sequences.getSize();
}
public void clearSelection() {
sequences.clearSequenceSelection();
//fireSelectionChanged();
}
public int getSequenceIndex(Sequence seq) {
return sequences.indexOf(seq);
}
public AlignmentFile getAlignmentFile() {
return this.alignmentFile;
}
public String getFileName() {
if(alignmentFile == null){
return null;
}
return alignmentFile.getName();
}
public void setAlignmentFile(File alignmentFile) {
if(alignmentFile != null && alignmentFile.exists()){
this.alignmentFile = new AlignmentFile(alignmentFile);
}
}
public void storeAlignmetAsFasta(Writer out) throws IOException{
int longest = sequences.getLongestSequenceLength();
for(Sequence seq: sequences){
String name = seq.getName();
out.write('>');
out.write(seq.getName());
out.write(LF);
seq.writeBases(out);
out.write(LF);
}
out.flush();
out.close();
}
private void storeAlignmetAsClustal(Writer out) throws IOException {
// First write meta
out.write("CLUSTAL W (1.99) multiple sequence alignment" + LF);
out.write(LF);
out.write(LF);
int longSeq = sequences.getLongestSequenceLength();
int namePadSize = sequences.getLongestSequenceName() + 1;
// Clustal uses up to 60 residues per line
for(int pos = 0; pos < longSeq; pos += 60){
int endPos = pos + 59; // end is inclusive
endPos = Math.min(endPos, longSeq);
for(int n = 0; n < sequences.getSize(); n++){
// Write name space and up to 60 residues
Sequence seq = sequences.get(n);
String paddedName = StringUtils.rightPad(seq.getName(), namePadSize);
// byte[] bases = seq.getBasesBetween(pos, endPos);
out.write(paddedName);
seq.writeBasesBetween(pos, endPos, out);
out.write(LF);
// out.flush();
}
// add two blank lines
out.write(LF);
out.write(LF);
out.flush();
}
out.flush();
out.close();
}
private void storeAlignmetAsMSF(Writer out) throws IOException {
int longSeq = sequences.getLongestSequenceLength();
int namePadSize = sequences.getLongestSequenceName() + 1;
// first write alignment meta
String type = "P";
String type2 = "!!AA";
if(this.isNucleotideAlignment()){
type = "N";
type2 = "!!NA";
}
out.write("" + type2 + "_MULTIPLE_ALIGNMENT" + LF);
out.write(LF);
out.write(LF);
// checksumTotal += check;
// checksumTotal %= 10000;
int checkTotal = 0;
for(int n = 0; n < sequences.getSize(); n++){
Sequence seq = sequences.get(n);
String paddedName = StringUtils.rightPad(seq.getName(), namePadSize);
int check = MSFImporter.GCGchecksum(seq);
checkTotal += check;
checkTotal %= 10000;
}
String totalMeta = " MSF: " + longSeq + " Type: " + type + " Check: " + checkTotal + " ..";
out.write(totalMeta);
out.write(LF);
out.write(LF);
// then write names and checksums
for(int n = 0; n < sequences.getSize(); n++){
Sequence seq = sequences.get(n);
String paddedName = StringUtils.rightPad(seq.getName(), namePadSize);
int check = MSFImporter.GCGchecksum(seq);
String seqMeta = " Name: " + paddedName + " Len: " + seq.getLength() + " Check: " + check + " Weight: 1.00";
out.write(seqMeta);
out.write(LF);
}
// start sequences
out.write(LF);
out.write(LF);
out.write("//");
out.write(LF);
out.write(LF);
// then write
// MSF uses up to 50 residues per line
for(int pos = 0; pos < longSeq; pos += 50){
int endPos = pos + 50;
endPos = Math.min(endPos, longSeq);
for(int n = 0; n < sequences.getSize(); n++){
// Write name space and up to 50 residues
Sequence seq = sequences.get(n);
String paddedName = StringUtils.rightPad(seq.getName(), namePadSize);
out.write(paddedName);
byte[] bases = seq.getBasesBetween(pos, endPos - 1);
// replace gaps to MSF notation
bases = ArrayUtilities.replaceAll(bases, '-', (byte) '.');
// write bases with space every 10 pos
for(int delPos = 0; delPos < bases.length; delPos += 10){
int maxLen = 10;
maxLen = Math.min(maxLen, bases.length - delPos);
out.write(new String(bases, delPos, maxLen));
// add space, but not at last
if(delPos+10 < bases.length){
out.write(' ');
}
}
out.write(LF);
}
// add two blank lines
out.write(LF);
out.write(LF);
}
out.flush();
out.close();
}
private void storeAlignmetAsPhyFile(Writer out, FileFormat fileFormat) throws IOException{
// First line number of seq + seqLen
out.write("" + sequences.getSize() + " " + this.getMaximumSequenceLength() + LF);
// Interleaved
if(fileFormat == FileFormat.PHYLIP_RELAXED_PADDED_INTERLEAVED_AKA_LONG_NAME_INTERLEAVED){
int longSeq = sequences.getLongestSequenceLength();
int namePadSize = sequences.getLongestSequenceName() + 1;
// 60 residues per line
int residuesPerLine = 80;
// names on first round only
for(int n = 0; n < sequences.getSize(); n++){
// Write name space and up to xx residues
Sequence seq = sequences.get(n);
String seqName = seq.getName();
seqName = escapeSeqName(seqName);
String paddedName = StringUtils.rightPad(seqName, namePadSize);
out.write(paddedName);
//byte[] bases = seq.;
seq.writeBasesBetween(0, residuesPerLine - 1, out);
out.write(LF);
}
out.write(LF);
out.write(LF);
for(int pos = residuesPerLine; pos < longSeq; pos += residuesPerLine){
int endPos = pos + residuesPerLine;
endPos = Math.min(endPos, longSeq);
for(int n = 0; n < sequences.getSize(); n++){
// Write name space and up to xx residues
Sequence seq = sequences.get(n);
// String seqName = seq.getName();
// seqName = escapeSeqName(seqName);
//
// String paddedName = StringUtils.rightPad(seqName, namePadSize);
//
// out.write(paddedName);
//byte[] bases = seq.getBasesBetween;
// ((out.write(new String(bases));
seq.writeBasesBetween(pos, endPos - 1, out);
out.write(LF);
}
// add two blank lines before next "interleave"
out.write(LF);
out.write(LF);
}
}
// Sequential versions
else{
for(Sequence seq: sequences){
String seqName = seq.getName();
seqName = escapeSeqName(seqName);
if(fileFormat == FileFormat.PHYLIP_RELAXED){
int longSeqName = sequences.getLongestSequenceName();
seqName += ' '; // + one space
}
else if(fileFormat == FileFormat.PHYLIP_STRICT_SEQUENTIAL_AKA_SHORT_NAME_SEQUENTIAL){
// Make sure exact 10 positions
if(seqName.length() > 10){
seqName = StringUtils.substring(seqName, 0, 10);
}
seqName = StringUtils.rightPad(seqName , 10); // 10 name no space
}
// default is FileFormat.PHYLIP_RELAXED_PADDED
else{
int longSeqName = sequences.getLongestSequenceName();
seqName = StringUtils.rightPad(seqName , longSeqName + 1); // + one space
}
out.write(seqName); // no space after name that is added on name already (but not on strict)
seq.writeBases(out);
out.write(LF);
}
}
out.flush();
out.close();
}
private String escapeSeqName(String name) {
if(name != null && name.indexOf(' ') > -1){
name = StringUtils.replace(name, " ", "_");
}
return name;
}
/*
private void storeAlignmetAsPhyTranslatedAminoAcidFile(Writer out) throws IOException{
// First line number of seq + seqLen
out.write("" + sequences.getSize() + " " + alignmentMeta.getCodonPositions().getAminoAcidPosFromNucleotidePos(sequences.getLongestSequenceLength()) + LF);
// int longSeqName = sequences.getLongestSequenceName();
AATranslator aaTransSeq = new AATranslator(getAlignmentMeta().getCodonPositions(),getGeneticCode());
for(Sequence seq: sequences){
aaTransSeq.setSequence(seq);
out.write(escapeSeqName(seq.getName()) + " ");
aaTransSeq.writeTranslation(out);
out.write(LF);
}
out.flush();
out.close();
}
private void storeAlignmetAsFastaTranslatedAminoAcidFile(Writer out) throws IOException{
// make sure it is translated
boolean wasTranslated = isTranslatedOnePos();
setTranslationOnePos(true);
for(Sequence seq: sequences){
String name = seq.getName();
out.write('>');
out.write(seq.getName());
out.write(LF);
seq.writeBases(out);
out.write(LF);
}
out.flush();
out.close();
setTranslationOnePos(wasTranslated);
}
*/
private void storeMetaData(BufferedWriter outMeta) throws IOException {
outMeta.write("" + NexusUtilities.getExcludesAsNexusBlock(alignmentMeta.getExcludes()));
outMeta.write(LF);
outMeta.write("" + NexusUtilities.getCodonPosAsNexusBlock(alignmentMeta.getCodonPositions(), 0, this.getMaximumSequenceLength()));
outMeta.write(LF);
outMeta.write("" + NexusUtilities.getCharsetsBlockAsNexus(alignmentMeta.getCharsets()));
outMeta.write(LF);
outMeta.flush();
outMeta.close();
}
private void storeTranslatedMetaData(BufferedWriter outMeta, AlignmentMeta translatedMeta) throws IOException {
outMeta.write("" + NexusUtilities.getExcludesAsNexusBlock(translatedMeta.getExcludes()));
outMeta.write(LF);
//outMeta.write("" + NexusUtilities.getCodonPosAsNexusBlock(alignmentMeta.getCodonPositions()));
outMeta.write("" + NexusUtilities.getCharsetsBlockAsNexus(translatedMeta.getCharsets()));
outMeta.write(LF);
outMeta.flush();
outMeta.close();
}
public void saveSelectionAsFastaFile(File selectedFile){
try {
BufferedWriter buffOut = new BufferedWriter(new FileWriter(selectedFile));
sequences.writeSelectionAsFasta(buffOut);
buffOut.flush();
buffOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveAlignmentAsFile(File outFile) throws IOException{
// save as current format
saveAlignmentAsFile(outFile,getFileFormat());
}
public void exportPartitionsFileRaxMLFormat(File outFile) throws IOException{
// DNA,p1=1-1194
// DNA,p2=1195-3029
// DNA,p3=3030-4345
// DNA,p4=4346-5697
// DNA,p5=5698-6997
String datatypeModel = "";
if(isAAAlignment()){
datatypeModel = "JTT";
}
else{
datatypeModel = "DNA";
}
String partitionsAsText = "";
CharSets charsets = getAlignmentMeta().getCharsets();
for(CharSet charSet: charsets){
String charsetRangeText = "";
ArrayList<NexusRange> ranges = charSet.getAsContinousNexusRanges();
int rangeCount = 0;
for(NexusRange range: ranges){
charsetRangeText += range.toString() + ",";
rangeCount ++;
}
// remove last ,
if(rangeCount > 0){
charsetRangeText = StringUtils.removeEnd(charsetRangeText, ",");
}
partitionsAsText += datatypeModel + "," + charSet.getName() + " = " + charsetRangeText + LF;
}
FileUtils.writeStringToFile(outFile, partitionsAsText);
}
public void saveAlignmentAsFile(File outFile, FileFormat fileFormat) throws IOException{
logger.info("fileFormat" + fileFormat);
// make sure they are equal length (if editable)
if(sequences.isEditable()){
sequences.rightPadWithGapUntilEqualLength();
sequences.rightTrimSequencesRemoveGapsUntilEqualLength();
}
// store current translation (might be modofied below)
boolean wasTranslated = isTranslatedOnePos();
BufferedWriter out = new BufferedWriter(new FileWriter(outFile));
int nexusDatatype = AliViewExtraNexusUtilities.DATATYPE_DNA;
if(sequences.getSequenceType() == SequenceUtils.TYPE_AMINO_ACID){
nexusDatatype = AliViewExtraNexusUtilities.DATATYPE_PROTEIN;
}
if(fileFormat == FileFormat.FASTA){
setTranslationOnePos(false);
storeAlignmetAsFasta(out);
// save meta if exset it is set
if(this.alignmentMeta.isMetaOutputNeeded()){
BufferedWriter outMeta = new BufferedWriter(new FileWriter(new File(outFile.getAbsoluteFile() + ".meta")));
storeMetaData(outMeta);
}
}else if(fileFormat == FileFormat.PHYLIP || fileFormat == FileFormat.PHYLIP_RELAXED ||
fileFormat == FileFormat.PHYLIP_RELAXED_PADDED_AKA_LONG_NAME_SEQUENTIAL || fileFormat == FileFormat.PHYLIP_STRICT_SEQUENTIAL_AKA_SHORT_NAME_SEQUENTIAL ||
fileFormat == FileFormat.PHYLIP_RELAXED_PADDED_INTERLEAVED_AKA_LONG_NAME_INTERLEAVED){
setTranslationOnePos(false);
storeAlignmetAsPhyFile(out, fileFormat);
// save meta if exset it is set
if(this.alignmentMeta.isMetaOutputNeeded()){
BufferedWriter outMeta = new BufferedWriter(new FileWriter(new File(outFile.getAbsoluteFile() + ".meta")));
storeMetaData(outMeta);
}
}else if(fileFormat == FileFormat.PHYLIP_TRANSLATED_AMINO_ACID){
setTranslationOnePos(true);
storeAlignmetAsPhyFile(out, FileFormat.PHYLIP_RELAXED_PADDED_AKA_LONG_NAME_SEQUENTIAL);
// save meta if exset it is set
if(this.alignmentMeta.isMetaOutputNeeded()){
//AlignmentMeta translatedMeta = getTranslatedMeta();
BufferedWriter outMeta = new BufferedWriter(new FileWriter(new File(outFile.getAbsoluteFile() + ".meta")));
// storeTranslatedMetaData(outMeta, translatedMeta);
}
}else if(fileFormat == FileFormat.FASTA_TRANSLATED_AMINO_ACID){
setTranslationOnePos(true);
storeAlignmetAsFasta(out);
// save meta if exset it is set
if(this.alignmentMeta.isMetaOutputNeeded()){
//AlignmentMeta translatedMeta = getTranslatedMeta();
BufferedWriter outMeta = new BufferedWriter(new FileWriter(new File(outFile.getAbsoluteFile() + ".meta")));
//storeTranslatedMetaData(outMeta, translatedMeta);
}
}else if(fileFormat == FileFormat.CLUSTAL){
setTranslationOnePos(false);
storeAlignmetAsClustal(out);
}else if(fileFormat == FileFormat.MSF){
setTranslationOnePos(false);
storeAlignmetAsMSF(out);
}else if(fileFormat == FileFormat.NEXUS){
setTranslationOnePos(false);
AliViewExtraNexusUtilities.exportAlignmentAsNexus(new BufferedWriter(new FileWriter(outFile)), this, false,nexusDatatype);
}else if(fileFormat == FileFormat.NEXUS_TRANSLATED_AMINO_ACID){
// make sure it is translated
setTranslationOnePos(true);
AliViewExtraNexusUtilities.exportAlignmentAsNexus(new BufferedWriter(new FileWriter(outFile)), this, false, AliViewExtraNexusUtilities.DATATYPE_PROTEIN);
}else if(fileFormat == FileFormat.NEXUS_SIMPLE){
setTranslationOnePos(false);
AliViewExtraNexusUtilities.exportAlignmentAsNexus(new BufferedWriter(new FileWriter(outFile)), this, true, nexusDatatype);
}else if(fileFormat == FileFormat.NEXUS_CODONPOS_CHARSET){
setTranslationOnePos(false);
AliViewExtraNexusUtilities.exportAlignmentAsNexusCodonpos(new BufferedWriter(new FileWriter(outFile)), this, AliViewExtraNexusUtilities.DATATYPE_DNA);
}
// revert translation
setTranslationOnePos(wasTranslated);
}
/*
* utility method
*/
/*
private String translateSequence(Sequence seq){
AATranslator aaTransSeq = new AATranslator(getAlignmentMeta().getCodonPositions(),getGeneticCode());
aaTransSeq.setSequence(seq);
return aaTransSeq.getTranslatedAsString();
}
private Alignment getTranslatedAlignment(){
AlignmentMeta transMeta = getTranslatedMeta();
AlignmentListModel transSeq = createTranslatedSequences();
Alignment translatedAlignment = new Alignment(null, null, transSeq, transMeta);
return translatedAlignment;
}
*/
//
// TODO this is not working for fileSequences
//
/*
private AlignmentListModel createTranslatedSequences(){
AlignmentListModel transSeqs = new MemorySequenceAlignmentListModel();
for(Sequence seq: sequences){
transSeqs.add(new PhylipSequence(seq.getName(), translateSequence(seq)));
}
return transSeqs;
}
*/
// TODO this might get wrong if translating sequence and sequence order in alignment not is same, or sequence
// has x offset in alignment
// private AlignmentMeta getTranslatedMeta(){
// CharSets charsetsTrans = new CharSets();
// Excludes excludesTrans = new Excludes();
// AlignmentMeta metaTrans = new AlignmentMeta(excludesTrans,null,charsetsTrans,alignmentMeta.getGeneticCode());
//
// // This is the translation of the Charsets
// for(CharSet charset: alignmentMeta.getCharsets()){
// ArrayList<NexusRange> nexusRanges = charset.getAsContinousNexusRanges();
// if(nexusRanges != null){
// logger.info("rangesSize" + nexusRanges.size());
//
// CharSet translatedSet = new CharSet(charset.getName());
// for(NexusRange range: nexusRanges){
// NexusRange translatedRange = new NexusRange(alignmentMeta.getCodonPositions().getAminoAcidPosFromNucleotidePos(range.getMinimumInt()) + 1, // +1 för Nexus ranges börjar på 1
// alignmentMeta.getCodonPositions().getAminoAcidPosFromNucleotidePos(range.getMaximumInt()) + 1, // +1 för Nexus ranges börjar på 1
// range.getPositionVal(), range.getSteps());
// logger.info(translatedRange);
// translatedSet.addNexusRange(translatedRange);
// }
// charsetsTrans.add(translatedSet);
// }
// }
//
// // This is the translaiton of the excludes
// for(NexusRange range: alignmentMeta.getExcludes().getAsContinousNexusRanges()){
// NexusRange translatedRange = new NexusRange(alignmentMeta.getCodonPositions().getAminoAcidPosFromNucleotidePos(range.getMinimumInt()),
// alignmentMeta.getCodonPositions().getAminoAcidPosFromNucleotidePos(range.getMaximumInt()),
// range.getPositionVal(), range.getSteps());
// excludesTrans.addNexusRange(translatedRange);
// }
// return metaTrans;
// }
/*
* Alternate method
*/
public boolean mergeTwoSequences(List<Sequence> seqs, boolean allowOverlap) {
boolean isMerged = false;
if(seqs.size() == 2){
isMerged = mergeTwoSequences(seqs.get(0),seqs.get(1), allowOverlap);
}
return isMerged;
}
public boolean mergeTwoSequences(Sequence seq1, Sequence seq2, boolean allowOverlap){
if(seq1 instanceof InMemorySequence && seq2 instanceof InMemorySequence){
boolean wasMerged = sequences.mergeTwoSequences((InMemorySequence)seq1, (InMemorySequence) seq2, allowOverlap);
return wasMerged;
}
else{
return false;
}
}
public void deleteAllExsetBases(){
// first create a deletemask
boolean[] deleteMask = new boolean[this.alignmentMeta.getExcludes().getMaximumEndPos()];
for(int n = 0; n < deleteMask.length; n++){
if(this.alignmentMeta.isExcluded(n)){
deleteMask[n] = true;
}
}
sequences.deleteBasesInAllSequencesFromMask(deleteMask);
//and finally remove in AlignmentMeta(excludes, codonpos & charset)
alignmentMeta.deleteFromMask(deleteMask);
// sequencesChanged();
}
public ArrayList<Primer> findPrimerInSelection(){
ArrayList<Primer> allPrimers = new ArrayList<Primer>();
// no selection returm
if(! sequences.hasSelection()){
return allPrimers;
}
String selection = getSelectionAsNucleotides();
// logger.info(selection);
String[] selectionSeq = selection.split("\\n");
// Start with a prototype as consensus
int consensusVal[] = new int[selectionSeq[0].length()];
for(String seq: selectionSeq){
for(int n = 0; n < consensusVal.length; n++){
int baseVal = NucleotideUtilities.baseValFromChar(seq.charAt(n));
// Create consensus by bitwise OR of the bases in the same column
consensusVal[n] = consensusVal[n] | baseVal;
}
}
// Create consensus from baseValues
StringBuilder consensusBuilder = new StringBuilder();
for(int n = 0; n < consensusVal.length; n++){
consensusBuilder.append(NucleotideUtilities.charFromBaseVal(consensusVal[n]));
}
String consensus = consensusBuilder.toString();
logger.info(consensus.length());
// remove gaps in consensus
consensus = consensus.replaceAll("\\-", "");
// create primer put them in a list and sort list (on score)
// create all primer min-max bases long
int primerMinLen = Settings.getMinPrimerLength().getIntValue();
int primerMaxLen = Settings.getMaxPrimerLength().getIntValue();
int primerMinTM = Settings.getPrimerMinTM().getIntValue();
int primerMaxTM = Settings.getPrimerMaxTM().getIntValue();
Dimer.setDimerLengthThreashold(Settings.getDimerReportThreashold().getIntValue());
long nCount = 0;
int selectionStartPos = getFirstSelectedPositionX();
for(int winSize = primerMinLen; winSize <= primerMaxLen; winSize ++){
int offset = 0;
int startPos = offset;
int endPos = offset + winSize;
logger.info(consensus.length());
logger.info( endPos);
while(endPos <= consensus.length()){
String primerSeq = consensus.substring(startPos, endPos);
Primer aPrimer = new Primer(primerSeq, selectionStartPos + startPos);
// only add primers below score
long degenFold = aPrimer.getDegenerateFold();
double baseStackTM = aPrimer.getBaseStackingAvgTm();
if(degenFold <= PRIMER_MAX_DEGENERATE_SCORE){
if(baseStackTM >= primerMinTM && baseStackTM <= primerMaxTM){
allPrimers.add(aPrimer);
}
}
offset ++;
startPos = offset;
endPos = offset + winSize;
nCount ++;
}
logger.info("winSize=" + winSize);
}
logger.info("Primers tested:" + nCount);
Collections.sort(allPrimers);
return allPrimers;
// https://ecom.mwgdna.com/services/webgist/mops.tcl?ot=OLIGO_ALC_UNMOD&oligoSequence=RTTGCTYRAKACTCGGTRA&ShowModiTables=OFF&oligo_name=&mod3=&mod5=&modx=&modz=&ot=OLIGO_ALC_UNMOD&oligo_name=&oligoSequence=RTT+GCT+YYY+RAK+ACT+CGG+TRA&action=properties&next_url=
}
/*
*
* Selection section
*
*
*/
private String getSelectionAsNucleotides(){
return sequences.getSelectionAsNucleotides();
}
public void copySelectionToClipboardAsFasta(){
StringWriter writer = new StringWriter();
sequences.writeSelectionAsFasta(writer);
// Set to clipboard
StringSelection ss = new StringSelection(writer.toString());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
}
public void copySelectionToClipboardAsNucleotides(){
// Set to clipboard
StringSelection ss = new StringSelection(getSelectionAsNucleotides());
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
}
public void copySelectionNames() {
// Set to clipboard
logger.info("copy sel names");
String names = sequences.getSelectionNames();
StringSelection ss = new StringSelection(names);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss, null);
Toolkit.getDefaultToolkit().getSystemSelection().setContents(ss, null);
}
public boolean isBaseSelected(int x, int y) {
return sequences.isBaseSelected(x, y);
}
public void setSelectionAt(int xPos, int yPos) {
setSelectionAt(xPos, yPos, false);
}
public void setSelectionAt(int xPos, int yPos, boolean clearFirst) {
sequences.setSelectionAt(xPos, yPos, clearFirst);
//fireSelectionChanged();
}
public void setSelectionWithin(Rectangle bounds) {
sequences.setSelectionWithin(bounds);
//fireSelectionChanged();
}
public void reverseComplementAlignment(){
sequences.reverseComplement();
alignmentMeta.reverse(getMaximumSequenceLength());
}
public void reverseComplementFullySelectedSequences(){
sequences.reverseComplementFullySelectedSequences();
}
/*
* Find
*/
public FindObject findInNames(FindObject findObj) {
findObj = sequences.findInNames(findObj);
return findObj;
}
public void clearFindLastPos() {
nextFindSequenceNumber = 0;
nextFindStartPos = 0;
}
public FindObject findAndSelectInSequences(FindObject findObj){
findObj = sequences.findAndSelect(findObj);
return findObj;
}
public Sequence getSequenceByName(String name){
return sequences.getSequenceByName(name);
}
public Sequence getSequenceByID(int id){
return sequences.getSequenceByID(id);
}
public void incReadingFrame() {
int newReadFrame = this.getReadingFrame();
newReadFrame ++;
if(newReadFrame > 3){
newReadFrame = 1;
}
this.setReadingFrame(newReadFrame);
}
public int getReadingFrame() {
return this.readingFrame;
}
public void decReadingFrame() {
int newReadFrame = this.getReadingFrame();
newReadFrame --;
if(newReadFrame < 1){
newReadFrame = 3;
}
this.setReadingFrame(newReadFrame);
}
public List<Sequence> clearSelectedBases(boolean undoable){
List<Sequence> affected = sequences.replaceSelectedBasesWithGap(undoable);
return affected;
}
public void deleteFullySelectedSequences(){
sequences.deleteFullySelectedSequences();
}
public void deleteSelectedBases() {
int first = sequences.getFirstSelectedWholeColumn();
// If whole column is selected do a bit different since we also want to delete
// in meta
if(first != -1){
int last = sequences.getLastSelectedWholeColumn();
logger.info("first" + first);
logger.info("last" + last);
// create a bit-mask with pos to delete
boolean[] deleteMask = new boolean[getMaxX()];
for(int n = first; n <= last; n++){
deleteMask[n] = true;
}
sequences.deleteBasesInAllSequencesFromMask(deleteMask);
//and finally remove in AlignmentMeta(excludes, codonpos & charset)
//logger.info(alignmentMeta.getCodonPositions().getLength());
alignmentMeta.deleteFromMask(deleteMask);
//logger.info(alignmentMeta.getCodonPositions().getLength());
}
// only delete in selected sequences
else{
List<Sequence> affected = sequences.deleteSelectedBases();
}
}
public String getConsensus(){
return sequences.getConsensus();
}
public void deleteVerticalGaps(){
String cons = getConsensus();
logger.info("done cons" + cons);
//logger.info('-' == cons.charAt(0));
// if there is a gap
if(cons.indexOf(SequenceUtils.GAP_SYMBOL) >= 0){
logger.info("there is a gap in cons");
// create a bit-mask with pos to delete
boolean[] deleteMask = new boolean[cons.length()];
for(int n = 0; n < deleteMask.length; n++){
if(cons.charAt(n) == SequenceUtils.GAP_SYMBOL){
deleteMask[n] = true;
}
}
sequences.deleteBasesInAllSequencesFromMask(deleteMask);
//and finally remove in AlignmentMeta(excludes, codonpos & charset)
alignmentMeta.deleteFromMask(deleteMask);
}
}
public void addFasta(String clipboardSelection) {
try {
AlignmentListModel sequencesFromClipboard = seqFactory.createFastaSequences(new StringReader(clipboardSelection));
sequences.addAll(sequencesFromClipboard, true);
} catch (AlignmentImportException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void addNewSequence() {
int minLen = sequences.getShortestSequenceLength();
int maxLen = sequences.getLongestSequenceLength();
int len;
if(maxLen == minLen){
len = maxLen;
}else{
len = 1;
}
String seqName = "New_sequence";
byte[] bases = new byte[len];
Arrays.fill(bases,(byte)'-');
// TODO this is not working on file sequences
Sequence newSeq = new InMemorySequence(seqName, bases);
Point lastSel = sequences.getLastSelectedPos();
// logger.info("lastSel.y" + lastSel.y);
// logger.info("sequences.getSize()" + sequences.getSize());
if(lastSel != null && lastSel.y + 1 < sequences.getSize()){
sequences.add(lastSel.y +1, newSeq);
}else{
sequences.add(newSeq);
}
}
public void addSequences(File additionalFile) {
addSequences(additionalFile, 0);
}
public void addSequences(File additionalFile, int index) {
try {
AlignmentListModel additionalSequences = seqFactory.createSequences(additionalFile);
sequences.addAll(index, additionalSequences);
} catch (AlignmentImportException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
*
*
* Start Aligner section
*
*
*
*/
public void clearSelectionOffset() {
sequences.setSelectionOffset(0);
}
public List<Sequence> moveSelectionRight(boolean undoable){
logger.info("move");
List<Sequence> previousState = sequences.moveSelectedResiduesRightIfGapIsPresent(undoable);
return previousState;
}
public List<Sequence> moveSelectionLeft(boolean undoable) {
List<Sequence> previousState = sequences.moveSelectedResiduesLeftIfGapIsPresent(undoable);
return previousState;
}
public List<Sequence> moveSelection(int diff, boolean undoable) {
List<Sequence> previousState = sequences.moveSelectedResiduesIfGapIsPresent(diff, undoable);
return previousState;
}
public boolean isMoveSelectionLeftPossible() {
return sequences.isGapPresentLeftOfSelection();
}
public boolean isMoveSelectionRightPossible() {
return sequences.isGapPresentRightOfSelection();
}
public List<Sequence> deleteGapMoveLeft(boolean undoable) {
List<Sequence> previousState = sequences.deleteGapMoveLeft(undoable);
if(previousState.size()> 0){
rightPadSequencesWithGapUntilEqualLength();
}
return previousState;
}
public List<Sequence> deleteGapMoveRight(boolean undoable) {
List<Sequence> previousState = sequences.deleteGapMoveRight(undoable);
if(previousState.size()> 0){
rightPadSequencesWithGapUntilEqualLength();
}
return previousState;
}
public List<Sequence> insertGapLeftOfSelectionMoveRight(boolean undoable) {
List<Sequence> previousState = sequences.insertGapLeftOfSelectedBase(undoable);
if(previousState.size()> 0){
rightPadSequencesWithGapUntilEqualLength();
}
return previousState;
}
public List<Sequence> insertGapRightOfSelectionMoveLeft(boolean undoable) {
List<Sequence> previousState = sequences.insertGapRightOfSelectedBase(undoable);
if(previousState.size()> 0){
leftPadSequencesWithGapUntilEqualLength();
}
return previousState;
}
public boolean rightPadSequencesWithGapUntilEqualLength(){
boolean wasPadded = sequences.rightPadWithGapUntilEqualLength();
// if(wasPadded){
// alignmentMeta.verifyLength(sequences.getLongestSequenceLength());
// }
return wasPadded;
}
public boolean leftPadSequencesWithGapUntilEqualLength() {
boolean wasPadded = sequences.leftPadWithGapUntilEqualLength();
// if(wasPadded){
// alignmentMeta.verifyLength(sequences.getLongestSequenceLength());
// }
return wasPadded;
}
/*
*
* End Aligner section
*
*/
public long getSelectedBasesCount(){
return sequences.getSelectionSize();
}
public Rectangle getSelectionAsMinRect(){
if(! hasSelection()){
return null;
}
int minX = Integer.MAX_VALUE;
int minY = Integer.MAX_VALUE;
int maxX = Integer.MIN_VALUE;
int maxY = Integer.MIN_VALUE;
int seqIndex = 0;
for(int n = 0; n < sequences.getSize(); n++){
int[] selection = sequences.get(n).getSelectedPositions();
if(selection.length > 0){
minY = Math.min(minY, n);
maxY = Math.max(maxY, n);
minX = Math.min(minX, selection[0]);
maxX = Math.max(minX, selection[selection.length - 1]);
}
}
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}
public void addOrRemoveSelectionToExcludes() {
// check if anythin is excluded already - then remove
// otherwise add
Rectangle selection = getSelectionAsMinRect();
if(isTranslatedOnePos()){
selection = getAlignmentMeta().reTranslatePositions(selection);
}
boolean containsExcludedAlready = getAlignmentMeta().excludesIntersectsPositions(selection.x, selection.x + selection.width);
logger.info("containsExcludedAlready" + containsExcludedAlready);
if(containsExcludedAlready){
removeSelectionFromExcludes();
}else{
addSelectionToExcludes();
}
}
public void addSelectionToExcludes() {
Rectangle selection = getSelectionAsMinRect();
if(isTranslatedOnePos()){
selection = getAlignmentMeta().reTranslatePositions(selection);
}
getAlignmentMeta().excludeRange(selection.x, selection.x + selection.width);
// getAlignmentMeta().excludePositions(selection.x, selection.x + selection.width);
//fireAlignmentMetaOnlyChanged();
}
public void removeSelectionFromExcludes() {
Rectangle selection = getSelectionAsMinRect();
if(isTranslatedOnePos()){
selection = getAlignmentMeta().reTranslatePositions(selection);
}
getAlignmentMeta().removeExcludeRange(selection.x, selection.x + selection.width);
//getAlignmentMeta().excludesRemovePositions(selection.x, selection.x + selection.width);
}
public void setSelectionAsCoding(int startOffset) {
Rectangle bounds = sequences.getSelectionBounds();
if(sequences.isTranslated()){
bounds = getAlignmentMeta().reTranslatePositions(bounds);
}
// TODO check that selection is continous
if(bounds != null){
this.alignmentMeta.getCodonPositions().addRange(bounds.x, bounds.x + bounds.width, startOffset);
}
//fireAlignmentMetaOnlyChanged();
}
public void setSelectionAsNonCoding() {
setSelectionAsCoding(0);
}
public void complementAlignment() {
sequences.complement();
}
public boolean isEditedAfterLastSave() {
return isEditedAfterLastSave;
}
public void setEditedAfterLastSave(boolean isEditedAfterLastSave) {
this.isEditedAfterLastSave = isEditedAfterLastSave;
}
/*
public boolean isAllCharactersValid() {
return getFirstMuscleInvalidCharacter().length() == 0;
}
*/
// TODO should be different depending on alignment class nuc or protein
public String getFirstAlignmentProgInvalidCharacter() {
String testChars = "?ÅÄÖ*";
String invalidCharsInAlignment = "";
for(int n = 0; n < testChars.length(); n++){
char testChar = testChars.charAt(n);
for(Sequence seq: getSequences()){
if(seq.contains(testChar)){
invalidCharsInAlignment += testChar;
break; // breaking out of this is loop no reason to check other seq
}
}
}
return invalidCharsInAlignment;
}
public void setAlignmentFormat(FileFormat fileFormat) {
sequences.setFileFormat(fileFormat);
}
public FileFormat getFileFormat() {
return sequences.getFileFormat();
}
public int getLongestSequenceName() {
return sequences.getLongestSequenceName();
}
public int getCodonPosAt(int x) {
return alignmentMeta.getCodonPosAt(x);
}
public void setReadingFrame(int readingFrame){
if(readingFrame > 0 && readingFrame <=3){
this.readingFrame = readingFrame;
alignmentMeta.setReadingFrame(readingFrame);
// fireAlignmentMetaOnlyChanged();
}
}
public boolean isFullCodonStartingAt(int x) {
return alignmentMeta.isFullCodonStartingAt(x);
}
public boolean isExcluded(int x) {
return alignmentMeta.isExcluded(x);
}
public AlignmentMeta getAlignentMetaCopy(){
return alignmentMeta.getCopy();
}
public void setAlignentMeta(AlignmentMeta aliMeta) {
this.alignmentMeta = aliMeta;
//fireAlignmentMetaOnlyChanged();
}
public AlignmentMeta getAlignmentMeta() {
return alignmentMeta;
}
public ArrayList<Integer> getAllCodonPositions(int i, boolean removeExcluded, int startPos, int endPosInclusive) {
return alignmentMeta.getAllCodonPositions(i, removeExcluded, startPos, endPosInclusive);
}
/*
*
*/
public void selectDuplicates(){
sequences.findAndSelectDuplicates();
}
public ArrayList<String> findDuplicateNames(){
if(sequences != null){
return sequences.findDuplicateNames();
}else{
return null;
}
}
public void selectDuplicateNamesSequences(){
sequences.selectDuplicateNamesSequences();
}
/*
*
* This one is just dumpting to stdout
*
*/
public void getStats() {
// TODO might not work if no charset
for(CharSet charSet: alignmentMeta.getCharsets()){
// Start with a prototype as consensus
int consensusVal[] = new int[sequences.getLongestSequenceLength()];
int missingCount = 0;
int nonemptySeqCount = 0;
for(Sequence seq: sequences){
boolean sequenceIsAllEmpty = true;
int sequenceMissingCount = 0;
for(int n = 0; n <consensusVal.length; n++){
if(charSet.contains(n)){
int baseVal = NucleotideUtilities.baseValFromBase(seq.getBaseAtPos(n));
// Create consensus by bitwise OR of the bases in the same column
// Skip if n or unknown
if(baseVal == NucleotideUtilities.N || baseVal == NucleotideUtilities.UNKNOWN || baseVal == NucleotideUtilities.GAP){
sequenceMissingCount ++;
}else{
consensusVal[n] = consensusVal[n] | baseVal;
sequenceIsAllEmpty = false;
}
}
}
if(! sequenceIsAllEmpty){
nonemptySeqCount ++;
missingCount += sequenceMissingCount;
}
}
// Create consensus from baseValues
StringBuilder consensusBuilder = new StringBuilder();
int invaribleCount = 0;
int varibleCount = 0;
for(int n = 0; n < consensusVal.length; n++){
if(charSet.contains(n)){
consensusBuilder.append(NucleotideUtilities.charFromBaseVal(consensusVal[n]));
if(consensusVal[n] == NucleotideUtilities.A || consensusVal[n] == NucleotideUtilities.C || consensusVal[n] == NucleotideUtilities.G || consensusVal[n] == NucleotideUtilities.T){
invaribleCount ++;
}
else{
varibleCount ++;
}
}
}
String consensus = consensusBuilder.toString();
logger.info(charSet.getName());
logger.info("consensus" + consensus);
logger.info("invaribleCount" + invaribleCount);
logger.info("variableCount" + varibleCount);
logger.info("totalCount" + (invaribleCount + varibleCount));
logger.info("missingCount" + missingCount);
logger.info("nonemptySeqCount" + nonemptySeqCount);
double totalBases = (invaribleCount + varibleCount) * nonemptySeqCount;
double missingPercent = missingCount/totalBases;
logger.info("missingPercent" + missingPercent);
}
}
public ArrayList<Sequence> deleteEmptySequences() {
ArrayList<Sequence> deleted = sequences.deleteEmptySequences();
return deleted;
}
public void deleteSequence(Sequence sequence) {
sequences.deleteSequence(sequence);
}
public int getFirstSelectedSequenceIndex() {
int selectedIndex = -1;
int n = 0;
for(Sequence seq: sequences){
if(seq.hasSelection()){
selectedIndex = n;
break;
}
n++;
}
return selectedIndex;
}
public void selectSequencesWithIndex(List<Integer> selectedIndex) {
sequences.selectSequencesWithIndex(selectedIndex);
}
public void selectSequencesWithIndex(int[] selectedIndex) {
sequences.selectSequencesWithIndex(selectedIndex);
}
public GeneticCode getGeneticCode() {
return alignmentMeta.getGeneticCode();
}
public void setGeneticCode(GeneticCode genCode) {
alignmentMeta.setGeneticCode(genCode);
//fireAlignmentMetaOnlyChanged();
}
public boolean isUndoable() {
boolean isUndoable = true;
if(this.getSequences() != null){
if(this.getSequences() instanceof FileSequenceAlignmentListModel){
isUndoable = false;
}
}
return isUndoable;
}
public boolean isNucleotideAlignment() {
return (sequences.getSequenceType() == SequenceUtils.TYPE_NUCLEIC_ACID);
}
public boolean isAAAlignment() {
return (sequences.getSequenceType() == SequenceUtils.TYPE_AMINO_ACID);
}
public boolean replaceSelectedWithChar(char newChar) {
List<Sequence> replacedSeqs = sequences.replaceSelectedWithChar(newChar, isUndoable());
if(replacedSeqs.size() > 0){
return true;
}else{
return false;
}
}
public void selectEverythingWithinGaps(Point point) {
sequences.selectEverythingWithinGaps(point);
}
public void realignNucleotidesUseThisAAAlignmentAsTemplate(Alignment realignment) throws Exception {
sequences.realignNucleotidesUseTheseAASequenceAsTemplate(realignment.getSequences());
}
public void deleteAllGaps() {
sequences.deleteAllGaps();
}
public void padAndTrimSequences(){
boolean wasPadded = sequences.rightPadWithGapUntilEqualLength();
boolean wasTrimed = sequences.rightTrimSequencesRemoveGapsUntilEqualLength();
}
public void trimSequences(){
boolean wasTrimed = sequences.rightTrimSequencesRemoveGapsUntilEqualLength();
}
public void selectAll(){
sequences.selectAll();
}
public void selectionExtendRight() {
sequences.selectionExtendRight();
}
public void selectionExtendLeft() {
sequences.selectionExtendLeft();
}
public void invertSelection() {
long startTime = System.currentTimeMillis();
sequences.invertSelection();
long endTime = System.currentTimeMillis();
logger.info("Invert took" + (endTime - startTime) + " milliseconds");
}
public boolean isPositionValid(int x, int y) {
return sequences.isPositionValid(x,y);
}
public boolean getSelectionAt(int x, int y) {
return sequences.isBaseSelected(x, y);
}
public void setAllHorizontalSelectionAt(int y, boolean selection) {
if(selection == true){
sequences.selectSequenceWithIndex(y);
}else{
sequences.clearAllSelectionInSequenceWithIndex(y);
}
}
public void copySelectionFromSequenceTo(int indexFrom, int indexTo) {
sequences.copySelectionFromInto(indexFrom,indexTo);
//fireSelectionChanged();
}
public void selectColumn(int columnIndex) {
sequences.selectColumn(columnIndex);
}
public void clearColumnSelection(int columnIndex) {
sequences.clearColumnSelection(columnIndex);
//fireSelectionChanged();
}
public void copySelectionFromPosX1toX2(int x1, int x2) {
sequences.copySelectionFromPosX1toX2(x1, x2);
//fireSelectionChanged();
}
public void setEditMode(boolean editMode) {
this.editMode = editMode;
}
public boolean isEditMode() {
return editMode;
}
public Point getFirstSelectedPosition() {
return sequences.getFirstSelectedPos();
}
public int getFirstSelectedPositionX() {
Point pos = sequences.getFirstSelectedPos();
if(pos == null){
return 0;
}else{
return pos.x;
}
}
public int getFirstSelectedUngapedPositionX() {
Point pos = sequences.getFirstSelectedUngapedPos();
if(pos == null){
logger.info("pos == null");
return -1;
}else{
logger.info("pos == " + pos.x);
return pos.x;
}
}
public void sortSequencesByName() {
sequences.sortSequencesByName();
}
public void sortSequencesByCharInSelectedColumn() {
sequences.sortSequencesByCharInSelectedColumn(getHistogram());
}
public AliHistogram getHistogram(){
return sequences.getHistogram();
}
public boolean hasSelection() {
return sequences.hasSelection();
}
public List<Sequence> replaceSelectedCharactersWithThis(Alignment realignment) {
boolean undoable = true;
List<Sequence> affected = sequences.replaceSelectedCharactersWithThis(realignment.getSequences(), undoable);
return affected;
}
public void saveSelectedSequencesAsFastaFile(File outFile, boolean useIDAsName) throws IOException {
BufferedWriter buffWriter = new BufferedWriter(new FileWriter(outFile));
sequences.writeSelectedSequencesAsFasta(buffWriter, useIDAsName);
buffWriter.flush();
buffWriter.close();
}
public void saveUnSelectedSequencesAsFastaFile(File outFile, boolean useIDAsName) throws IOException {
BufferedWriter buffWriter = new BufferedWriter(new FileWriter(outFile));
sequences.writeUnSelectedSequencesAsFasta(buffWriter, useIDAsName);
buffWriter.flush();
buffWriter.close();
}
public boolean isEditable() {
boolean isEditable = false;
if(sequences != null){
isEditable = sequences.isEditable();
}
// if(sequences.isTranslated()){
// isEditable = false;
// }
return isEditable;
}
public boolean isSelectable(){
return isSelectable;
}
public long getSelectionSize() {
return sequences.getSelectionSize();
}
public void fileSequenceContentsChanged() {
logger.info("fileSequenceContChanged");
// if(alignmentMeta.getCodonPositions().size()getLength() == 0){
// //logger.info("sequences.getLongestSequenceLength()" + sequences.getLongestSequenceLength());
// alignmentMeta = new AlignmentMeta(this.geneticCode);
// }
}
public void setTranslationOnePos(boolean showTranslationOnePos){
if(isNucleotideAlignment()){
sequences.setTranslation(showTranslationOnePos);
alignmentMeta.setTranslation(showTranslationOnePos);
}
}
public boolean isTranslatedOnePos(){
return sequences.isTranslated();
}
public boolean hasFullySelectedSequences() {
return sequences.hasFullySelectedSequences();
}
public void sortSequencesByThisModel(AlignmentListModel prevSeqOrder) {
sequences.sortSequencesByThisModel(prevSeqOrder);
}
public int getSelectedColumnCount() {
return sequences.getSelectedColumnCount();
}
public int getSelectedSequencesCount() {
return sequences.getSelectedSequencesCount();
}
public List<Sequence> getSelectedSequences() {
return sequences.getSelectedSequences();
}
public String getFirstSelectedSequenceName() {
return sequences.getFirstSelectedName();
}
public List<Sequence> setFirstSelectedSequenceName(String newName) {
List<Sequence> previous = sequences.setFirstSelectedName(newName);
return previous;
}
public ArrayList<CharSet> getSelectedCharsets() {
Rectangle selection = sequences.getSelectionBounds();
if(selection == null){
return new ArrayList<CharSet>();
}
ArrayList<CharSet> intersected = alignmentMeta.getCharsets().getIntersected(selection);
return intersected;
}
public void selectAll(CharSet aCharSet) {
sequences.selectAll(aCharSet);
}
public int countStopCodons() {
int totalCount = 0;
if(isNucleotideAlignment()){
for(Sequence seq: sequences){
totalCount += seq.countStopCodon();
}
}else{
for(Sequence seq: sequences){
totalCount += seq.countChar('*');
}
}
return totalCount;
}
public void saveFastaIndex() {
logger.info("this.fileFormat");
if(getFileFormat() == FileFormat.FASTA && sequences instanceof FileSequenceAlignmentListModel){
FileSequenceAlignmentListModel model = (FileSequenceAlignmentListModel) getSequences();
//String indexName = FileFormat.stripFileSuffixFromName(this.getAlignmentFile().getAbsolutePath());
String indexName = this.getAlignmentFile().getAbsolutePath();
indexName += ".fai";
File indexFile = new File(indexName);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(indexFile));
Sequence firstSeq = sequences.get(0);
int charsPerLine = 0;
int newlinePos = firstSeq.indexOf('\n');
if(newlinePos == -1){
charsPerLine = firstSeq.getLength() + 2; // +2 because of .......
}else{
charsPerLine = newlinePos + 1 + 1; // +1 because of 0f index, +1 because of LF;
}
int spacePerLine = firstSeq.countChar(' ', 0, newlinePos);
logger.info("newlinePos" + newlinePos);
logger.info("spacePerLine" + spacePerLine);
spacePerLine += 1; // +1 because of LF
int residuesPerLine = charsPerLine - spacePerLine;
// int returnCount = firstSeq.countChar('\r');
// int tabCount = firstSeq.countChar('\t');
// int spaceCount = firstSeq.countChar(' ');
// int totalLen = firstSeq.getLength();
//int lenWithoutWhite = totalLen - newlineCount - returnCount - tabCount - spaceCount;
// logger.info("lenWithoutWhite" + lenWithoutWhite);
for(Sequence seq: sequences){
FastaFileSequence fileSeq = (FastaFileSequence) seq;
//String name = StringUtils.substring(fileSeq.getName(), 0, 50);
String name = fileSeq.getName();
out.write(name);
out.write('\t');
int length = fileSeq.getLength();
logger.info("length" + length);
int fullRows = length/charsPerLine;
logger.info("fullRows" + fullRows);
int diff = charsPerLine - residuesPerLine;
logger.info("diff" + diff);
double decimalPart = (double)length/(double)charsPerLine - (double)fullRows;
int remindDiff = (int) (decimalPart * (double)diff);
logger.info("remindDiff" + remindDiff);
diff = diff * fullRows;
diff = diff + remindDiff;
logger.info("diff" + diff);
int lengthWithoutWhite = length - diff + 1; // don't know exactly why +1
out.write("" + lengthWithoutWhite);
out.write('\t');
out.write("" + (fileSeq.getSequenceAfterNameStartPointer() -1));
out.write('\t');
out.write("" + residuesPerLine);
out.write('\t');
out.write("" + charsPerLine);
out.write(LF);
}
out.flush();
out.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Messenger.showOKOnlyMessage(Messenger.NO_FASTA_INDEX_COULD_BE_SAVED);
}
}
public void setTempSelection(Rectangle selectRectMatrixCoords) {
getSequences().setTempSelection(selectRectMatrixCoords);
}
public Rectangle getTempSelection() {
return getSequences().getTempSelection();
}
public void clearTempSelection() {
getSequences().clearTempSelection();
}
public void moveSelectedSequencesToBottom() {
getSequences().moveSelectedSequencesToBottom();
}
public void moveSelectedSequencesToTop() {
getSequences().moveSelectedSequencesToTop();
}
public void moveSelectedSequencesUp() {
getSequences().moveSelectedSequencesUp();
}
public void moveSelectedSequencesDown() {
getSequences().moveSelectedSequencesDown();
}
public void moveSelectedSequencesTo(int index) {
getSequences().moveSelectedSequencesTo(index);
}
public void selectIndices(List<Integer> allFoundIndices) {
getSequences().getAlignmentSelectionModel().selectSequencesWithIndex(allFoundIndices);
}
public boolean isFileSequences() {
if(getSequences() instanceof FileSequenceAlignmentListModel){
return true;
}
return false;
}
}