/* * AscertainedSitePatterns.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.util.TaxonList; import dr.util.Citable; import dr.util.Citation; import dr.util.CommonCitations; import java.util.*; /** * Package: AscertainedSitePatterns * Description: * <p/> * <p/> * Created by * Alexander V. Alekseyenko (alexander.alekseyenko@gmail.com) * Date: Mar 10, 2008 * Time: 12:50:36 PM */ public class AscertainedSitePatterns extends SitePatterns implements Citable { protected int[] includePatterns; protected int[] excludePatterns; protected int ascertainmentIncludeCount; protected int ascertainmentExcludeCount; /** * Constructor */ public AscertainedSitePatterns(Alignment alignment) { super(alignment); } /** * Constructor */ public AscertainedSitePatterns(Alignment alignment, TaxonList taxa) { super(alignment, taxa); } /** * Constructor */ public AscertainedSitePatterns(Alignment alignment, int from, int to, int every) { super(alignment, from, to, every); } /** * Constructor */ public AscertainedSitePatterns(Alignment alignment, TaxonList taxa, int from, int to, int every) { super(alignment, taxa, from, to, every); } /** * Constructor */ public AscertainedSitePatterns(SiteList siteList) { super(siteList); } /** * Constructor */ public AscertainedSitePatterns(SiteList siteList, int from, int to, int every) { super(siteList, from, to, every); } public AscertainedSitePatterns(Alignment alignment, TaxonList taxa, int from, int to, int every, int includeFrom, int includeTo, int excludeFrom, int excludeTo) { super(alignment, taxa, from, to, every); int[][] newPatterns = new int[patterns.length + (includeTo - includeFrom) + (excludeTo - excludeFrom)][]; double[] newWeights = new double[patterns.length + (includeTo - includeFrom) + (excludeTo - excludeFrom)]; for (int i = 0; i < patterns.length; ++i) { newPatterns[i] = patterns[i]; newWeights[i] = weights[i]; } patterns = newPatterns; weights = newWeights; if (includeTo - includeFrom >= 1) includePatterns(includeFrom, includeTo, every); if (excludeTo - excludeFrom >= 1) excludePatterns(excludeFrom, excludeTo, every); } @Override public Citation.Category getCategory() { return Citation.Category.DATA_MODELS; } @Override public String getDescription() { return "Ascertained Site Patterns"; } public List<Citation> getCitations() { return Collections.singletonList( CommonCitations.ALEKSEYENKO_2008 ); } public int getIncludePatternCount() { return ascertainmentIncludeCount; } public int[] getIncludePatternIndices() { return includePatterns; } protected void includePatterns(int includeFrom, int includeTo, int every) { if (includePatterns == null) { includePatterns = new int[includeTo - includeFrom]; } for (int i = includeFrom; i < includeTo; i += every) { int[] pattern = siteList.getPattern(i); int index = addAscertainmentPattern(pattern); includePatterns[ascertainmentIncludeCount] = index; ascertainmentIncludeCount += 1; } } public int getExcludePatternCount() { return ascertainmentExcludeCount; } public int[] getExcludePatternIndices() { return excludePatterns; } protected void excludePatterns(int excludeFrom, int excludeTo, int every) { if (excludePatterns == null) excludePatterns = new int[excludeTo - excludeFrom]; for (int i = excludeFrom; i < excludeTo; i += every) { int[] pattern = siteList.getPattern(i); int index = addAscertainmentPattern(pattern); weights[index] = 0.0; // Site is excluded, so set weight = 0 excludePatterns[ascertainmentExcludeCount] = index; ascertainmentExcludeCount += 1; } } public double getAscertainmentCorrection(double[] patternLogProbs) { double excludeProb = 0, includeProb = 0, returnProb = 1.0; int[] includeIndices = getIncludePatternIndices(); int[] excludeIndices = getExcludePatternIndices(); for (int i = 0; i < getIncludePatternCount(); i++) { int index = includeIndices[i]; includeProb += Math.exp(patternLogProbs[index]); } for (int j = 0; j < getExcludePatternCount(); j++) { int index = excludeIndices[j]; excludeProb += Math.exp(patternLogProbs[index]); } if (includeProb == 0.0) { returnProb -= excludeProb; } else if (excludeProb == 0.0) { returnProb = includeProb; } else { returnProb = includeProb - excludeProb; } return Math.log(returnProb); } private int addAscertainmentPattern(int[] pattern) { for (int i = 0; i < patternCount; i++) { if (comparePatterns(patterns[i], pattern)) { return i; } } int index = patternCount; patterns[index] = pattern; weights[index] = 0.0; /* do not affect weight */ patternCount++; return index; } }