package beast.evolution.alignment.distance; import beast.core.BEASTObject; import beast.core.Description; import beast.evolution.alignment.Alignment; import beast.evolution.alignment.TaxonSet; import beast.evolution.datatype.DataType; @Description("Provides distance between taxa") public interface Distance { /** return distance of two taxa, identified by their indices **/ double pairwiseDistance(int taxon1, int taxon2); @Description("Provides distance between two sequences in an alignment") public class Base extends BEASTObject implements Distance { //public static final double MAX_DISTANCE = 1000.0; public static final double MAX_DISTANCE = 5.0; @Override public void initAndValidate() { // nothing to do } /** * set the pattern source */ public void setPatterns(Alignment patterns) { this.taxa = new TaxonSet(); try { this.taxa.alignmentInput.setValue(patterns, this.taxa); } catch (Exception e) { e.printStackTrace(); } this.patterns = patterns; dimension = patterns.getTaxonCount(); dataType = patterns.getDataType(); distancesKnown = false; } /** * Calculate a pairwise distance */ @Override public double pairwiseDistance(int taxon1, int taxon2) { int state1, state2; int n = patterns.getPatternCount(); double weight, distance; double sumDistance = 0.0; double sumWeight = 0.0; int[] pattern; for (int i = 0; i < n; i++) { pattern = patterns.getPattern(i); state1 = pattern[taxon1]; state2 = pattern[taxon2]; weight = patterns.getPatternWeight(i); // sumDistance += dataType.getObservedDistance(state1, state2) * weight; if (!dataType.isAmbiguousState(state1) && !dataType.isAmbiguousState(state2) && state1 != state2) { sumDistance += weight; } sumWeight += weight; } distance = sumDistance / sumWeight; return distance; } // // Private stuff // protected DataType dataType = null; int dimension = 0; boolean distancesKnown; // private double[][] distances = null; protected Alignment patterns = null; private TaxonSet taxa = null; } }