/* * MutationDeathType.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.datatype; /** * Package: MutationDeathType * Description: * <p/> * <p/> * Created by * Alexander V. Alekseyenko (alexander.alekseyenko@gmail.com) * Date: Mar 5, 2008 * Time: 1:09:40 PM */ public class MutationDeathType extends DataType { protected static String DESCRIPTION = "MutationDeathType"; protected static int UNKNOWN_STATE = 128; protected int[][] codes; protected char[] stateCodes; public int DEATHSTATE; public MutationDeathType(char deathCode, char extantCode) { // Constructor for pure death type super(); initialize_internals(); codes[extantCode] = new int[]{0}; stateCodes[0] = extantCode; codes[deathCode] = new int[]{1}; stateCodes[1] = deathCode; stateCount = 2; DEATHSTATE = 1; ambiguousStateCount = 0; } public MutationDeathType(DataType x, char deathCode) { // constructor for extention type super(); int i; char stateCode; initialize_internals(); for (i = 0; i < x.getStateCount(); ++i) { /* Copy unique codes */ stateCode = x.getCode(i).charAt(0); this.codes[stateCode] = new int[]{i}; stateCodes[i] = stateCode; } this.codes[deathCode] = new int[]{i}; /* Append the state space with the death state */ stateCodes[i] = deathCode; DEATHSTATE = i; stateCount = i + 1; for (i = 0; i < 128; ++i) { int state = x.getState((char) i); if (state > 0 && state < 128 && x.isAmbiguousState(state) && i != deathCode) { if (!x.isUnknownState(state)) { int[] states = x.getStates(state); this.codes[i] = new int[states.length]; System.arraycopy(states, 0, this.codes[i], 0, states.length); } } } ambiguousStateCount = x.getAmbiguousStateCount() + 1; } public void addAmbiguity(char ambiguityCode, String s) { if (s.length() == 0) { this.codes[ambiguityCode] = new int[stateCount]; for (int i = 0; i < stateCount; ++i) { this.codes[ambiguityCode][i] = i; } } else { this.codes[ambiguityCode] = new int[s.length()]; for (int i = 0; i < s.length(); ++i) { this.codes[ambiguityCode][i] = getState(s.charAt(i)); } } ambiguousStateCount += 1; } private void initialize_internals() { this.codes = new int[128][]; /* stores states (w/ ambiguities) corresponding to codes */ this.stateCodes = new char[128]; /* Stores characters corresponding to unique state codes*/ } @Override public char[] getValidChars() { return null; } /** * Get state corresponding to a character * * @param c character * @return state */ public int getState(char c) { if (codes[c] != null && codes[c].length == 1) { return codes[c][0]; } else { return c; } } /** * Get state corresponding to an unknown * * @return state */ public int getUnknownState() { return UNKNOWN_STATE; } /** * Get character corresponding to a given state * * @param state state * <p/> * return corresponding character */ public char getChar(int state) { if (state < stateCount) return stateCodes[state]; return super.getChar(state); } /** * returns an array containing the non-ambiguous states that this state represents. */ public int[] getStates(int state) { if (state < stateCount) return codes[stateCodes[state]]; else return codes[state]; } /** * returns anarray of indicatiors for non-ambiguous states that this state represents. */ public boolean[] getStateSet(int state) { boolean[] stateSet = new boolean[stateCount]; int states[]; int i; for (i = 0; i < stateCount; ++i) stateSet[i] = false; states = getStates(state); for (i = 0; states != null && i < states.length; ++i) { stateSet[states[i]] = true; } return stateSet; } /** * @return true if this character is an ambiguous state */ public boolean isAmbiguousChar(char c) { return codes[c] != null && codes[c].length > 1; } /** * @return true if this character is a gap */ public boolean isUnknownChar(char c) { return codes[c] == null; } /** * returns true if this state is an ambiguous state. */ public boolean isAmbiguousState(int state) { return state >= stateCount; } /** * @return true if this state is an unknown state */ public boolean isUnknownState(int state) { return state >= stateCount && codes[state] == null; } public String getDescription() { return DESCRIPTION; } public int getType() { return 314; } }