/* * OperatorsGenerator.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.generator; import dr.app.beauti.components.ComponentFactory; import dr.app.beauti.options.*; import dr.app.beauti.types.ClockType; import dr.app.beauti.types.TreePriorType; import dr.app.beauti.util.XMLWriter; import dr.evolution.datatype.DataType; import dr.evomodel.operators.BitFlipInSubstitutionModelOperator; import dr.inference.operators.AdaptableVarianceMultivariateNormalOperator; import dr.oldevomodel.substmodel.AbstractSubstitutionModel; import dr.evomodel.tree.TreeModel; import dr.evomodelxml.coalescent.GMRFSkyrideLikelihoodParser; import dr.evomodelxml.coalescent.VariableDemographicModelParser; import dr.evomodelxml.coalescent.operators.GMRFSkyrideBlockUpdateOperatorParser; import dr.evomodelxml.coalescent.operators.SampleNonActiveGibbsOperatorParser; import dr.evomodelxml.operators.*; import dr.evomodelxml.speciation.BirthDeathModelParser; import dr.evomodelxml.speciation.SpeciesTreeModelParser; import dr.evomodelxml.speciation.YuleModelParser; import dr.oldevomodelxml.substmodel.GeneralSubstitutionModelParser; import dr.inference.model.ParameterParser; import dr.inference.operators.OperatorSchedule; import dr.inference.operators.RateBitExchangeOperator; import dr.inferencexml.model.CompoundParameterParser; import dr.inferencexml.operators.*; import dr.util.Attribute; import dr.util.Transform; import dr.util.TransformParsers; import dr.xml.XMLParser; import java.util.List; /** * @author Alexei Drummond * @author Andrew Rambaut * @author Walter Xie */ public class OperatorsGenerator extends Generator { public OperatorsGenerator(BeautiOptions options, ComponentFactory[] components) { super(options, components); } /** * Write the operator schedule XML block. * * @param operators the list of operators * @param writer the writer */ public void writeOperatorSchedule(List<Operator> operators, XMLWriter writer) { Attribute[] operatorAttributes; // certain models would benefit from a logarithm operator optimization boolean shouldLogCool = false; for (PartitionTreePrior partition : options.getPartitionTreePriors()) { if (partition.getNodeHeightPrior() == TreePriorType.SKYGRID || partition.getNodeHeightPrior() == TreePriorType.GMRF_SKYRIDE) { shouldLogCool = true; break; } } for (PartitionSubstitutionModel model : options.getPartitionSubstitutionModels()) { if (model.getDataType().getType() == DataType.GENERAL || model.getDataType().getType() == DataType.CONTINUOUS) { shouldLogCool = true; break; } } operatorAttributes = new Attribute[] { new Attribute.Default<String>(XMLParser.ID, "operators"), new Attribute.Default<String>(SimpleOperatorScheduleParser.OPTIMIZATION_SCHEDULE, (shouldLogCool ? OperatorSchedule.OptimizationTransform.LOG.toString() : OperatorSchedule.OptimizationTransform.DEFAULT.toString())) }; writer.writeComment("Define operators"); writer.writeOpenTag( SimpleOperatorScheduleParser.OPERATOR_SCHEDULE, operatorAttributes // new Attribute[]{new Attribute.Default<String>(XMLParser.ID, "operators")} ); for (Operator operator : operators) { if (operator.getWeight() > 0. && operator.isUsed()) { setModelPrefix(operator.getPrefix()); writeOperator(operator, writer); } } generateInsertionPoint(ComponentGenerator.InsertionPoint.IN_OPERATORS, writer); // Added for special operators writer.writeCloseTag(SimpleOperatorScheduleParser.OPERATOR_SCHEDULE); } private void writeOperator(Operator operator, XMLWriter writer) { switch (operator.getOperatorType()) { case SCALE: writeScaleOperator(operator, writer); break; case RANDOM_WALK: writeRandomWalkOperator(operator, writer); break; case RANDOM_WALK_ABSORBING: writeRandomWalkOperator(operator, false, writer); break; case RANDOM_WALK_INT: writeRandomWalkIntegerOperator(operator, writer); break; case RANDOM_WALK_REFLECTING: writeRandomWalkOperator(operator, true, writer); break; case INTEGER_RANDOM_WALK: writeIntegerRandomWalkOperator(operator, writer); break; case UP_DOWN: writeUpDownOperator(UpDownOperatorParser.UP_DOWN_OPERATOR, operator, writer); break; case MICROSAT_UP_DOWN: writeUpDownOperator(MicrosatelliteUpDownOperatorParser.MICROSAT_UP_DOWN_OPERATOR, operator, writer); break; case UP_DOWN_ALL_RATES_HEIGHTS: writeUpDownOperatorAllRatesTrees(operator, writer); break; case SCALE_ALL: writeScaleAllOperator(operator, writer); break; case SCALE_INDEPENDENTLY: writeScaleOperator(operator, writer, true); break; case CENTERED_SCALE: writeCenteredOperator(operator, writer); break; case DELTA_EXCHANGE: writeDeltaOperator(operator, false, writer); break; case WEIGHTED_DELTA_EXCHANGE: writeDeltaOperator(operator, true, writer); break; case INTEGER_DELTA_EXCHANGE: writeIntegerDeltaOperator(operator, writer); break; case SWAP: writeSwapOperator(operator, writer); break; case BITFLIP: writeBitFlipOperator(operator, writer); break; case BITFIP_IN_SUBST: writeBitFlipInSubstOperator(operator, writer); break; case RATE_BIT_EXCHANGE: writeRateBitExchangeOperator(operator, writer); break; case TREE_BIT_MOVE: writeTreeBitMoveOperator(operator, writer); break; case UNIFORM: writeUniformOperator(operator, writer); break; case INTEGER_UNIFORM: writeIntegerUniformOperator(operator, writer); break; case SUBTREE_LEAP: writeSubtreeLeapOperator(operator, writer); break; case SUBTREE_SLIDE: writeSubtreeSlideOperator(operator, writer); break; // write multivariate operator case NARROW_EXCHANGE: writeNarrowExchangeOperator(operator, writer); break; case WIDE_EXCHANGE: writeWideExchangeOperator(operator, writer); break; case WILSON_BALDING: writeWilsonBaldingOperator(operator, writer); break; case SAMPLE_NONACTIVE: writeSampleNonActiveOperator(operator, writer); break; case SCALE_WITH_INDICATORS: writeScaleWithIndicatorsOperator(operator, writer); break; case GMRF_GIBBS_OPERATOR: writeGMRFGibbsOperator(operator, writer); break; case SKY_GRID_GIBBS_OPERATOR: writeSkyGridGibbsOperator(operator, writer); break; case NODE_REHIGHT: writeSpeciesTreeOperator(operator, writer); break; case ADAPTIVE_MULTIVARIATE: writeAdaptiveMultivariateOperator(operator, writer); break; default: throw new IllegalArgumentException("Unknown operator type"); } } private void writeParameter1Ref(XMLWriter writer, Operator operator) { writer.writeIDref(ParameterParser.PARAMETER, operator.getParameter1().getName()); } private void writeParameter2Ref(XMLWriter writer, Operator operator) { writer.writeIDref(ParameterParser.PARAMETER, operator.getParameter2().getName()); } private void writeOperatorRef(XMLWriter writer, Operator operator) { writer.writeIDref(ParameterParser.PARAMETER, operator.getName()); } private void writeScaleOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag( ScaleOperatorParser.SCALE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) }); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(ScaleOperatorParser.SCALE_OPERATOR); } private void writeScaleOperator(Operator operator, XMLWriter writer, boolean indepedently) { writer.writeOpenTag( ScaleOperatorParser.SCALE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()), new Attribute.Default<String>(ScaleOperatorParser.SCALE_ALL_IND, indepedently ? "true" : "false") }); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(ScaleOperatorParser.SCALE_OPERATOR); } private void writeRandomWalkOperator(Operator operator, XMLWriter writer) { final String name = RandomWalkOperatorParser.RANDOM_WALK_OPERATOR; writer.writeOpenTag( name, new Attribute[]{ new Attribute.Default<Double>("windowSize", operator.getTuning()), getWeightAttribute(operator.getWeight()) }); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(name); } private void writeRandomWalkOperator(Operator operator, boolean reflecting, XMLWriter writer) { final String name = RandomWalkOperatorParser.RANDOM_WALK_OPERATOR; writer.writeOpenTag( name, new Attribute[]{ new Attribute.Default<Double>("windowSize", operator.getTuning()), getWeightAttribute(operator.getWeight()), new Attribute.Default<String>("boundaryCondition", (reflecting ? "reflecting" : "absorbing")), (operator.isAutoOptimize() == false ? new Attribute.Default<Boolean>("autoOptimize", false) : null) }); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(name); } private void writeRandomWalkIntegerOperator(Operator operator, XMLWriter writer) { final String name = RandomWalkIntegerOperatorParser.RANDOM_WALK_INTEGER_OPERATOR; writer.writeOpenTag( name, new Attribute[]{ new Attribute.Default<Double>("windowSize", operator.getTuning()), getWeightAttribute(operator.getWeight()) }); writeParameter1Ref(writer, operator); writer.writeCloseTag(name); } private void writeIntegerRandomWalkOperator(Operator operator, XMLWriter writer) { int windowSize = (int) Math.round(operator.getTuning()); if (windowSize < 1) windowSize = 1; final String name = RandomWalkIntegerOperatorParser.RANDOM_WALK_INTEGER_OPERATOR; writer.writeOpenTag( name, new Attribute[]{ new Attribute.Default<Integer>("windowSize", windowSize), getWeightAttribute(operator.getWeight()) }); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(name); } private void writeScaleAllOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag( ScaleOperatorParser.SCALE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), new Attribute.Default<String>(ScaleOperatorParser.SCALE_ALL, "true"), getWeightAttribute(operator.getWeight()) }); if (operator.getParameter2() == null) { writeParameter1Ref(writer, operator); } else { writer.writeOpenTag(CompoundParameterParser.COMPOUND_PARAMETER); writeParameter1Ref(writer, operator); // writer.writeIDref(ParameterParser.PARAMETER, operator.getParameter2().getName()); writeParameter2Ref(writer, operator); writer.writeCloseTag(CompoundParameterParser.COMPOUND_PARAMETER); } writer.writeCloseTag(ScaleOperatorParser.SCALE_OPERATOR); } private void writeCenteredOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(CenteredScaleOperatorParser.CENTERED_SCALE, new Attribute[]{ new Attribute.Default<Double>(CenteredScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(CenteredScaleOperatorParser.CENTERED_SCALE); } private void writeDeltaOperator(Operator operator, boolean weighted, XMLWriter writer) { int[] parameterWeights = operator.getParameter1().getParameterDimensionWeights(); Attribute[] attributes; if (weighted && parameterWeights != null && parameterWeights.length > 1) { String pw = "" + parameterWeights[0]; for (int i = 1; i < parameterWeights.length; i++) { pw += " " + parameterWeights[i]; } attributes = new Attribute[]{ new Attribute.Default<Double>(DeltaExchangeOperatorParser.DELTA, operator.getTuning()), new Attribute.Default<String>(DeltaExchangeOperatorParser.PARAMETER_WEIGHTS, pw), getWeightAttribute(operator.getWeight()) }; } else { attributes = new Attribute[]{ new Attribute.Default<Double>(DeltaExchangeOperatorParser.DELTA, operator.getTuning()), getWeightAttribute(operator.getWeight()) }; } writer.writeOpenTag(DeltaExchangeOperatorParser.DELTA_EXCHANGE, attributes); writeParameter1Ref(writer, operator); writer.writeCloseTag(DeltaExchangeOperatorParser.DELTA_EXCHANGE); } private void writeIntegerDeltaOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(DeltaExchangeOperatorParser.DELTA_EXCHANGE, new Attribute[]{ new Attribute.Default<String>(DeltaExchangeOperatorParser.DELTA, Integer.toString((int) operator.getTuning())), new Attribute.Default<String>("integer", "true"), getWeightAttribute(operator.getWeight()), new Attribute.Default<String>("autoOptimize", "false") } ); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(DeltaExchangeOperatorParser.DELTA_EXCHANGE); } private void writeSwapOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(SwapOperatorParser.SWAP_OPERATOR, new Attribute[]{ new Attribute.Default<String>("size", Integer.toString((int) operator.getTuning())), getWeightAttribute(operator.getWeight()), new Attribute.Default<String>("autoOptimize", "false") } ); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(SwapOperatorParser.SWAP_OPERATOR); } private void writeBitFlipOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(BitFlipOperatorParser.BIT_FLIP_OPERATOR, getWeightAttribute(operator.getWeight())); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(BitFlipOperatorParser.BIT_FLIP_OPERATOR); } private void writeBitFlipInSubstOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(BitFlipInSubstitutionModelOperator.BIT_FLIP_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight())}); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); PartitionSubstitutionModel model = (PartitionSubstitutionModel) operator.getOptions(); writer.writeIDref(GeneralSubstitutionModelParser.GENERAL_SUBSTITUTION_MODEL, model.getPrefix() + AbstractSubstitutionModel.MODEL); // <svsGeneralSubstitutionModel idref="originModel"/> writer.writeCloseTag(BitFlipInSubstitutionModelOperator.BIT_FLIP_OPERATOR); } private void writeRateBitExchangeOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(RateBitExchangeOperator.OPERATOR_NAME, getWeightAttribute(operator.getWeight())); writer.writeOpenTag(RateBitExchangeOperator.BITS); writeParameter1Ref(writer, operator); writer.writeCloseTag(RateBitExchangeOperator.BITS); writer.writeOpenTag(RateBitExchangeOperator.RATES); writeParameter2Ref(writer, operator); writer.writeCloseTag(RateBitExchangeOperator.RATES); writer.writeCloseTag(RateBitExchangeOperator.OPERATOR_NAME); } private void writeTreeBitMoveOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(TreeBitMoveOperatorParser.BIT_MOVE_OPERATOR, getWeightAttribute(operator.getWeight())); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); writer.writeCloseTag(TreeBitMoveOperatorParser.BIT_MOVE_OPERATOR); } private void writeUniformOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag("uniformOperator", getWeightAttribute(operator.getWeight())); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag("uniformOperator"); } private void writeIntegerUniformOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(UniformIntegerOperatorParser.UNIFORM_INTEGER_OPERATOR, getWeightAttribute(operator.getWeight())); writeParameter1Ref(writer, operator); // writeOperatorRef(writer, operator); writer.writeCloseTag(UniformIntegerOperatorParser.UNIFORM_INTEGER_OPERATOR); } private void writeNarrowExchangeOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(ExchangeOperatorParser.NARROW_EXCHANGE, getWeightAttribute(operator.getWeight())); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); writer.writeCloseTag(ExchangeOperatorParser.NARROW_EXCHANGE); } private void writeWideExchangeOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(ExchangeOperatorParser.WIDE_EXCHANGE, getWeightAttribute(operator.getWeight())); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); writer.writeCloseTag(ExchangeOperatorParser.WIDE_EXCHANGE); } private void writeWilsonBaldingOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(WilsonBaldingParser.WILSON_BALDING, getWeightAttribute(operator.getWeight())); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); // not supported anymore. probably never worked. (todo) get it out of GUI too // if (options.nodeHeightPrior == TreePriorType.CONSTANT) { // treePriorGenerator.writeNodeHeightPriorModelRef(writer); // } writer.writeCloseTag(WilsonBaldingParser.WILSON_BALDING); } private void writeSampleNonActiveOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(SampleNonActiveGibbsOperatorParser.SAMPLE_NONACTIVE_GIBBS_OPERATOR, getWeightAttribute(operator.getWeight())); writer.writeOpenTag(SampleNonActiveGibbsOperatorParser.DISTRIBUTION); writeOperatorRef(writer, operator); writer.writeCloseTag(SampleNonActiveGibbsOperatorParser.DISTRIBUTION); writer.writeOpenTag(SampleNonActiveGibbsOperatorParser.DATA_PARAMETER); writeParameter1Ref(writer, operator); writer.writeCloseTag(SampleNonActiveGibbsOperatorParser.DATA_PARAMETER); writer.writeOpenTag(SampleNonActiveGibbsOperatorParser.INDICATOR_PARAMETER); writeParameter2Ref(writer, operator); writer.writeCloseTag(SampleNonActiveGibbsOperatorParser.INDICATOR_PARAMETER); writer.writeCloseTag(SampleNonActiveGibbsOperatorParser.SAMPLE_NONACTIVE_GIBBS_OPERATOR); } private void writeSkyGridGibbsOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag( GMRFSkyrideBlockUpdateOperatorParser.GRID_BLOCK_UPDATE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(GMRFSkyrideBlockUpdateOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writer.writeIDref(GMRFSkyrideLikelihoodParser.SKYLINE_LIKELIHOOD, modelPrefix + "skygrid"); writer.writeCloseTag(GMRFSkyrideBlockUpdateOperatorParser.GRID_BLOCK_UPDATE_OPERATOR); } private void writeGMRFGibbsOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag( GMRFSkyrideBlockUpdateOperatorParser.BLOCK_UPDATE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(GMRFSkyrideBlockUpdateOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writer.writeIDref(GMRFSkyrideLikelihoodParser.SKYLINE_LIKELIHOOD, modelPrefix + "skyride"); writer.writeCloseTag(GMRFSkyrideBlockUpdateOperatorParser.BLOCK_UPDATE_OPERATOR); } private void writeScaleWithIndicatorsOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag( ScaleOperatorParser.SCALE_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) }); writeParameter1Ref(writer, operator); writer.writeOpenTag(ScaleOperatorParser.INDICATORS, new Attribute.Default<String>(ScaleOperatorParser.PICKONEPROB, "1.0")); writeParameter2Ref(writer, operator); writer.writeCloseTag(ScaleOperatorParser.INDICATORS); writer.writeCloseTag(ScaleOperatorParser.SCALE_OPERATOR); } // write multivariate operator private void writeSubtreeLeapOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(SubtreeLeapOperatorParser.SUBTREE_LEAP, new Attribute[]{ new Attribute.Default<Double>("size", operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); writer.writeCloseTag(SubtreeLeapOperatorParser.SUBTREE_LEAP); } private void writeSubtreeSlideOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(SubtreeSlideOperatorParser.SUBTREE_SLIDE, new Attribute[]{ new Attribute.Default<Double>("size", operator.getTuning()), new Attribute.Default<String>("gaussian", "true"), getWeightAttribute(operator.getWeight()) } ); writer.writeIDref(TreeModel.TREE_MODEL, modelPrefix + TreeModel.TREE_MODEL); writer.writeCloseTag(SubtreeSlideOperatorParser.SUBTREE_SLIDE); } private void writeSpeciesTreeOperator(Operator operator, XMLWriter writer) { writer.writeOpenTag(TreeNodeSlideParser.TREE_NODE_REHEIGHT, new Attribute[]{getWeightAttribute(operator.getWeight())} ); writer.writeIDref(TraitData.TRAIT_SPECIES, TraitData.TRAIT_SPECIES); writer.writeIDref(SpeciesTreeModelParser.SPECIES_TREE, Generator.SP_TREE); writer.writeCloseTag(TreeNodeSlideParser.TREE_NODE_REHEIGHT); } private void writeUpDownOperator(String opTag, Operator operator, XMLWriter writer) { writer.writeOpenTag(opTag, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writer.writeOpenTag(UpDownOperatorParser.UP); if (!operator.getParameter1().isFixed() /* && operator.getClockModelGroup().getRateTypeOption() != FixRateType.FIXED_MEAN */) { writeParameter1Ref(writer, operator); } else { writer.writeComment("Rate is fixed - scale node heights only"); } writer.writeCloseTag(UpDownOperatorParser.UP); writer.writeOpenTag(UpDownOperatorParser.DOWN); if (operator.getTag() == null) { writeParameter2Ref(writer, operator); } else { writer.writeIDref(operator.getTag(), operator.getIdref()); } writer.writeCloseTag(UpDownOperatorParser.DOWN); writer.writeCloseTag(opTag); } private void writeUpDownOperatorAllRatesTrees(Operator operator, XMLWriter writer) { writer.writeOpenTag(UpDownOperatorParser.UP_DOWN_OPERATOR, new Attribute[]{ new Attribute.Default<Double>(ScaleOperatorParser.SCALE_FACTOR, operator.getTuning()), getWeightAttribute(operator.getWeight()) } ); writer.writeOpenTag(UpDownOperatorParser.UP); for (PartitionClockModel model : options.getPartitionClockModels()) { // if (model.isEstimatedRate()) { switch (model.getClockType()) { case STRICT_CLOCK: case RANDOM_LOCAL_CLOCK: writer.writeIDref(ParameterParser.PARAMETER, model.getPrefix() + "clock.rate"); break; case UNCORRELATED: switch (model.getClockDistributionType()) { case LOGNORMAL: writer.writeIDref(ParameterParser.PARAMETER, model.getPrefix() + ClockType.UCLD_MEAN); break; case GAMMA: throw new UnsupportedOperationException("Uncorrelated gamma relaxed clock model not implemented yet"); // break; case CAUCHY: throw new UnsupportedOperationException("Uncorrelated Cauchy relaxed clock model not implemented yet"); // break; case EXPONENTIAL: writer.writeIDref(ParameterParser.PARAMETER, model.getPrefix() + ClockType.UCED_MEAN); break; } break; case AUTOCORRELATED: throw new UnsupportedOperationException("Autocorrelated relaxed clock model not implemented yet"); // break; default: throw new IllegalArgumentException("Unknown clock model"); } } if (options.useStarBEAST) { if (options.getPartitionTreePriors().get(0).getNodeHeightPrior() == TreePriorType.SPECIES_BIRTH_DEATH) { writer.writeIDref(ParameterParser.PARAMETER, TraitData.TRAIT_SPECIES + "." + BirthDeathModelParser.MEAN_GROWTH_RATE_PARAM_NAME); } else if (options.getPartitionTreePriors().get(0).getNodeHeightPrior() == TreePriorType.SPECIES_YULE) { writer.writeIDref(ParameterParser.PARAMETER, TraitData.TRAIT_SPECIES + "." + YuleModelParser.YULE + "." + YuleModelParser.BIRTH_RATE); } }// nothing for EBSP writer.writeCloseTag(UpDownOperatorParser.UP); writer.writeOpenTag(UpDownOperatorParser.DOWN); if (options.useStarBEAST) { writer.writeIDref(SpeciesTreeModelParser.SPECIES_TREE, SP_TREE); // <speciesTree idref="sptree" /> has to be the 1st always writer.writeIDref(ParameterParser.PARAMETER, TraitData.TRAIT_SPECIES + "." + options.starBEASTOptions.POP_MEAN); writer.writeIDref(ParameterParser.PARAMETER, SpeciesTreeModelParser.SPECIES_TREE + "." + SPLIT_POPS); } else if (options.isEBSPSharingSamePrior()) { writer.writeIDref(ParameterParser.PARAMETER, VariableDemographicModelParser.demoElementName + ".populationMean"); writer.writeIDref(ParameterParser.PARAMETER, VariableDemographicModelParser.demoElementName + ".popSize"); } for (PartitionTreeModel tree : options.getPartitionTreeModels()) { writer.writeIDref(ParameterParser.PARAMETER, tree.getPrefix() + "treeModel.allInternalNodeHeights"); } writer.writeCloseTag(UpDownOperatorParser.DOWN); writer.writeCloseTag(UpDownOperatorParser.UP_DOWN_OPERATOR); } private void writeAdaptiveMultivariateOperator(Operator operator, XMLWriter writer) { //determine how many parameters will be part of the AVMVN transition kernel int parameterCount = 0; for (Parameter parameter : options.selectParameters()) { parameterCount++; } //options set according to recommendations in AVMVN paper int initial = 200*parameterCount; int burnin = initial/2; writer.writeOpenTag(AdaptableVarianceMultivariateNormalOperator.AVMVN_OPERATOR, new Attribute[]{ getWeightAttribute(operator.getWeight()), new Attribute.Default<Double>(AdaptableVarianceMultivariateNormalOperator.SCALE_FACTOR, operator.getTuning()), new Attribute.Default<Integer>(AdaptableVarianceMultivariateNormalOperator.INITIAL, initial), new Attribute.Default<Integer>(AdaptableVarianceMultivariateNormalOperator.BURNIN, burnin), new Attribute.Default<Double>(AdaptableVarianceMultivariateNormalOperator.BETA, 0.05), new Attribute.Default<Double>(AdaptableVarianceMultivariateNormalOperator.COEFFICIENT, 1.0), new Attribute.Default<Boolean>(AdaptableVarianceMultivariateNormalOperator.AUTO_OPTIMIZE, true), new Attribute.Default<Boolean>(AdaptableVarianceMultivariateNormalOperator.FORM_XTX, false) }); // @todo Need to collate only the parameters being controlled by this here. for (Parameter parameter : options.selectParameters()) { if (parameter.isAdaptiveMultivariateCompatible) { writer.writeIDref(ParameterParser.PARAMETER, parameter.getName()); } } //set appropriate transformations for all parameters //TODO: we should aggregate as best as possible the different transformation so as to have fewer attributes int startTransform = 0; for (Parameter parameter : options.selectParameters()) { if (parameter.isAdaptiveMultivariateCompatible) { if (parameter.isNonNegative) { writer.writeTag(TransformParsers.TRANSFORM, new Attribute[]{new Attribute.Default<String>(TransformParsers.TYPE, new Transform.LogTransform().getTransformName()), new Attribute.Default<Integer>(TransformParsers.START, startTransform), new Attribute.Default<Integer>(TransformParsers.END, startTransform + parameter.getDimensionWeight()), }, true); startTransform += parameter.getDimensionWeight(); System.out.println(parameter + ": " + parameter.getDimensionWeight()); } else { // -Inf to Inf writer.writeTag(TransformParsers.TRANSFORM, new Attribute[]{new Attribute.Default<String>(TransformParsers.TYPE, new Transform.NoTransform().getTransformName()), new Attribute.Default<Integer>(TransformParsers.START, startTransform), new Attribute.Default<Integer>(TransformParsers.END, startTransform + parameter.getDimensionWeight()), }, true); startTransform += parameter.getDimensionWeight(); System.out.println(parameter + ": " + parameter.getDimensionWeight()); } } } writer.writeCloseTag(AdaptableVarianceMultivariateNormalOperator.AVMVN_OPERATOR); } private Attribute getWeightAttribute(double weight) { if (weight == (int) weight) { return new Attribute.Default<Integer>("weight", (int) weight); } else { return new Attribute.Default<Double>("weight", weight); } } }