All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lphy.base.evolution.birthdeath.SimFBDAge Maven / Gradle / Ivy

Go to download

The standard library of LPhy, which contains the required generative distributions and basic functions.

The newest version!
package lphy.base.evolution.birthdeath;

import lphy.base.evolution.tree.TimeTree;
import lphy.base.evolution.tree.TimeTreeNode;
import lphy.base.function.tree.PruneTree;
import lphy.core.model.GenerativeDistribution;
import lphy.core.model.RandomVariable;
import lphy.core.model.Value;
import lphy.core.model.annotation.GeneratorCategory;
import lphy.core.model.annotation.GeneratorInfo;
import lphy.core.model.annotation.ParameterInfo;
import lphy.core.simulator.RandomUtils;
import org.apache.commons.math3.random.RandomGenerator;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import static lphy.base.evolution.birthdeath.BirthDeathConstants.*;

/**
 * A Birth-death tree generative distribution
 */
public class SimFBDAge implements GenerativeDistribution {

    private Value birthRate;
    private Value deathRate;
    private Value psiVal;
    private Value fracVal;
    private Value originAge;

    RandomGenerator random;

    private static final int MAX_ATTEMPTS = 1000;

    public SimFBDAge(@ParameterInfo(name = lambdaParamName, description = "per-lineage birth rate.") Value birthRate,
                     @ParameterInfo(name = muParamName, description = "per-lineage death rate.") Value deathRate,
                     @ParameterInfo(name = fracParamName, description = "fraction of extant taxa sampled.") Value fracVal,
                     @ParameterInfo(name = psiParamName, description = "per-lineage sampling-through-time rate.") Value psiVal,
                     @ParameterInfo(name = originAgeParamName, description = "the age of the origin.") Value originAge) {


        this.birthRate = birthRate;
        this.deathRate = deathRate;
        this.fracVal = fracVal;
        this.psiVal = psiVal;
        this.originAge = originAge;

        random = RandomUtils.getRandom();
    }

    @GeneratorInfo(name = "SimFBDAge",
            category = GeneratorCategory.BD_TREE, examples = {"simFBDAge.lphy"},
            description = "A tree of extant species and those sampled through time, which is conceptually embedded in a full species tree produced by a speciation-extinction (birth-death) branching process.
" + "Conditioned on origin age.") public RandomVariable sample() { int nonNullLeafCount = 0; TimeTree sampleTree = null; int attempts = 0; while (nonNullLeafCount < 1 && attempts < MAX_ATTEMPTS) { FullBirthDeathTree birthDeathTree = new FullBirthDeathTree(birthRate, deathRate, null, originAge); RandomVariable fullTree = birthDeathTree.sample(); SimFossilsPoisson simFossilsPoisson = new SimFossilsPoisson(fullTree, psiVal); Value fullTreeWithFossils = simFossilsPoisson.sample(); sampleTree = new TimeTree(fullTreeWithFossils.value()); List leafNodes = new ArrayList<>(); for (TimeTreeNode node : sampleTree.getNodes()) { if (node.isLeaf() && node.getAge() == 0.0) { leafNodes.add(node); } } int toNull = (int)Math.round(leafNodes.size()* (1.0-fracVal.value())); List nullList = new ArrayList<>(); for (int i =0; i < toNull; i++) { nullList.add(leafNodes.remove(random.nextInt(leafNodes.size()))); } for (TimeTreeNode node : nullList) { node.setId(null); } nonNullLeafCount = leafNodes.size(); attempts += 1; } if (attempts == MAX_ATTEMPTS) throw new RuntimeException("Failed to simulate SimFBDAge after " + MAX_ATTEMPTS + " attempts."); PruneTree pruneTree = new PruneTree(new Value<>(null, sampleTree)); TimeTree tree = pruneTree.apply().value(); return new RandomVariable<>(null, tree, this); } @Override public double logDensity(TimeTree timeTree) { throw new UnsupportedOperationException("Not implemented!"); } @Override public Map getParams() { return new TreeMap<>() {{ put(lambdaParamName, birthRate); put(muParamName, deathRate); put(fracParamName, fracVal); put(psiParamName, psiVal); put(originAgeParamName, originAge); }}; } @Override public void setParam(String paramName, Value value) { switch (paramName) { case lambdaParamName: birthRate = value; break; case muParamName: deathRate = value; break; case fracParamName: fracVal = value; break; case psiParamName: psiVal = value; break; case originAgeParamName: originAge = value; break; default: throw new RuntimeException("Unexpected parameter " + paramName); } } public Value getBirthRate() { return birthRate; } public Value getDeathRate() { return deathRate; } public Value getRho() { return fracVal; } public Value getPsi() { return psiVal; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy