/*
* HypermutantAlignment.java
*
* Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard
*
* This file is part of BEAST.
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership and licensing.
*
* BEAST is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* BEAST 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with BEAST; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*/
package dr.evolution.alignment;
import dr.evolution.datatype.*;
import dr.evolution.sequence.Sequence;
import dr.evolution.util.Taxon;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* An alignment class that takes another alignment and converts it on the fly
* to a different dataType.
*
* @author Andrew Rambaut
* @author Alexei Drummond
*
* @version $Id: ConvertAlignment.java,v 1.29 2005/05/24 20:25:55 rambaut Exp $
*/
public class HypermutantAlignment extends WrappedAlignment
{
public enum APOBECType {
ALL("all"),
BOTH("both"),
HA3G("hA3G"),
HA3F("hA3F");
APOBECType(String label) {
this.label = label;
}
public String toString() {
return label;
}
final String label;
}
/**
* Constructor.
*/
public HypermutantAlignment(APOBECType type, Alignment alignment) {
super(alignment);
this.type = type;
if (alignment.getDataType().getType() != DataType.NUCLEOTIDES) {
throw new RuntimeException("HypermutantAlignment can only convert nucleotide alignments");
}
mutatedContextCounts = new int[getTaxonCount()];
unmutatedContextCounts = new int[getTaxonCount()];
countContexts();
}
/**
* @return the sequence state at (taxon, site)
*/
public int getState(int taxonIndex, int siteIndex) {
int state = alignment.getState(taxonIndex, siteIndex);
if (state == Nucleotides.A_STATE) {
int nextState = getNextContextState(taxonIndex, siteIndex);
if ( (type == APOBECType.ALL) || // consider all As as G->As
(type == APOBECType.HA3G && nextState == Nucleotides.G_STATE) ||
(type == APOBECType.HA3F && nextState == Nucleotides.A_STATE) ||
(type == APOBECType.BOTH && (nextState == Nucleotides.G_STATE || nextState == Nucleotides.A_STATE))
) {
state = Nucleotides.R_STATE;
}
}
return state;
}
/**
* This finds the next state downstream of siteIndex, skipping over gaps
*/
private int getNextContextState(int taxonIndex, int siteIndex) {
int nextState = Nucleotides.GAP_STATE;
int i = siteIndex + 1;
while (nextState == Nucleotides.GAP_STATE && i < getSiteCount()) {
nextState = alignment.getState(taxonIndex, i);
i++;
}
return nextState;
}
private void countContexts() {
for (int i = 0; i < getTaxonCount(); i++) {
for (int j = 0; j < getSiteCount(); j++) {
int state = alignment.getState(i, j);
if (state == Nucleotides.A_STATE || state == Nucleotides.G_STATE) {
int nextState = getNextContextState(i, j);
if ( (type == APOBECType.ALL) || // consider all As as G->As
(type == APOBECType.HA3G && nextState == Nucleotides.G_STATE) ||
(type == APOBECType.HA3F && nextState == Nucleotides.A_STATE) ||
(type == APOBECType.BOTH && (nextState == Nucleotides.G_STATE || nextState == Nucleotides.A_STATE))
) {
if (state == Nucleotides.A_STATE) {
// a mutated context
mutatedContextCounts[i] ++;
} else {
// an unmutated context
unmutatedContextCounts[i] ++;
}
}
}
}
}
}
public int[] getMutatedContextCounts() {
return mutatedContextCounts;
}
public int[] getUnmutatedContextCounts() {
return unmutatedContextCounts;
}
public int getMutatedContextCount() {
int total = 0;
for (int count: mutatedContextCounts) {
total += count;
}
return total;
}
public int getUnmutatedContextCount() {
int total = 0;
for (int count: unmutatedContextCounts) {
total += count;
}
return total;
}
// **************************************************************
// INSTANCE VARIABLES
// **************************************************************
private APOBECType type = null;
private int[] mutatedContextCounts;
private int[] unmutatedContextCounts;
}