/* * DiscreteTraitsComponentOptions.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.app.beauti.components.discrete; import dr.app.beauti.options.*; import dr.app.beauti.types.OperatorType; import dr.app.beauti.types.PriorScaleType; import dr.evolution.datatype.GeneralDataType; import dr.inference.operators.RateBitExchangeOperator; import java.util.List; import java.util.Set; /** * @author Andrew Rambaut * @version $Id$ */ public class DiscreteTraitsComponentOptions implements ComponentOptions { private final BeautiOptions options; public DiscreteTraitsComponentOptions(final BeautiOptions options) { this.options = options; } public void createParameters(final ModelOptions modelOptions) { for (AbstractPartitionData partitionData : options.getDataPartitions(GeneralDataType.INSTANCE)) { String prefix = partitionData.getName() + "."; if (!modelOptions.parameterExists(prefix + "frequencies")) { modelOptions.createZeroOneParameterUniformPrior(prefix + "frequencies", "discrete state frequencies", 0.25); modelOptions.createCachedGammaPrior(prefix + "rates", "discrete trait instantaneous transition rates", PriorScaleType.SUBSTITUTION_PARAMETER_SCALE, 1.0, 1.0, 1.0, false); // BSSVS modelOptions.createParameter(prefix + "indicators", "a vector of bits indicating non-zero rates for BSSVS", 1.0); // Poisson Prior on non zero ratesBSSVS modelOptions.createDiscreteStatistic(prefix + "nonZeroRates", "the number of non-zero rates for BSSVS"); modelOptions.createScaleOperator(prefix + "frequencies", 0.75, 1.0); modelOptions.createOperator(prefix + "rates", OperatorType.SCALE_INDEPENDENTLY, 0.75, 15.0); modelOptions.createOperator(prefix + "indicators", OperatorType.BITFLIP, -1.0, 7.0); // modelOptions.createScaleOperator(prefix + "mu", demoTuning, 10); modelOptions.createZeroOneParameterUniformPrior(prefix + "root.frequencies", "discrete state root frequencies", 0.25); modelOptions.createOperator(prefix + "root.frequencies", OperatorType.DELTA_EXCHANGE, 0.75, 1.0); //bit Flip on clock.rate in PartitionClockModelSubstModelLink // modelOptions.createBitFlipInSubstitutionModelOperator(OperatorType.BITFIP_IN_SUBST.toString() + "mu", prefix + "mu", // "bit Flip In Substitution Model Operator on trait.mu", getParameter("trait.mu"), this, demoTuning, 30); modelOptions.createOperatorUsing2Parameters(RateBitExchangeOperator.OPERATOR_NAME, "(indicators, rates)", "rateBitExchangeOperator (If both BSSVS and asymmetric subst selected)", prefix + "indicators", prefix + "rates", OperatorType.RATE_BIT_EXCHANGE, -1.0, 7.0); } } } public void selectParameters(final ModelOptions modelOptions, final List<Parameter> params) { for (PartitionSubstitutionModel substitutionModel : options.getPartitionSubstitutionModels(GeneralDataType.INSTANCE)) { String prefix = substitutionModel.getName() + "."; if (substitutionModel.isActivateBSSVS()) { modelOptions.getParameter(prefix + "indicators"); Parameter nonZeroRates = modelOptions.getParameter(prefix + "nonZeroRates"); Set<String> states = substitutionModel.getDiscreteStateSet(); int K = states.size(); if (substitutionModel.getDiscreteSubstType() == DiscreteSubstModelType.SYM_SUBST) { nonZeroRates.mean = Math.log(2); // mean = 0.693 and offset = K-1 nonZeroRates.offset = K - 1; } else if (substitutionModel.getDiscreteSubstType() == DiscreteSubstModelType.ASYM_SUBST) { nonZeroRates.mean = K - 1; // mean = K-1 and offset = 0 nonZeroRates.offset = 0.0; } else { throw new IllegalArgumentException("unknown discrete substitution type"); } params.add(nonZeroRates); } params.add(modelOptions.getParameter(prefix + "frequencies")); params.add(modelOptions.getParameter(prefix + "rates")); } for (AbstractPartitionData partition : options.getDataPartitions(GeneralDataType.INSTANCE)) { String prefix = partition.getPrefix(); if (partition.getPartitionSubstitutionModel().getDiscreteSubstType() == DiscreteSubstModelType.ASYM_SUBST) { params.add(modelOptions.getParameter(prefix + "root.frequencies")); } } } public void selectStatistics(final ModelOptions modelOptions, final List<Parameter> stats) { // no statistics } public void selectOperators(final ModelOptions modelOptions, final List<Operator> ops) { for (PartitionSubstitutionModel substitutionModel : options.getPartitionSubstitutionModels(GeneralDataType.INSTANCE)) { String prefix = substitutionModel.getName() + "."; // ops.add(modelOptions.getOperator(prefix + "frequencies")); // Usually fixed ops.add(modelOptions.getOperator(prefix + "rates")); if (substitutionModel.isActivateBSSVS()) { ops.add(modelOptions.getOperator(prefix + "indicators")); } } for (AbstractPartitionData partitionData : options.getDataPartitions(GeneralDataType.INSTANCE)) { if (partitionData.getPartitionSubstitutionModel().getDiscreteSubstType() == DiscreteSubstModelType.ASYM_SUBST) { ops.add(modelOptions.getOperator(partitionData.getName() + ".root.frequencies")); } } } }