From 204923a2327024e3cbfe1254ba4f808060ad877a Mon Sep 17 00:00:00 2001 From: Tim Vaughan Date: Thu, 15 Jun 2023 20:37:36 +0200 Subject: [PATCH 1/4] Added missing operators to beauti templates. --- fxtemplates/MultiTypeBirthDeath.xml | 57 +++++++++++++++++-- fxtemplates/MultiTypeBirthDeathUncoloured.xml | 47 +++++++++++++-- .../RandomMultiTypeTreeFromBDMM.java | 1 - 3 files changed, 96 insertions(+), 9 deletions(-) diff --git a/fxtemplates/MultiTypeBirthDeath.xml b/fxtemplates/MultiTypeBirthDeath.xml index f57a8c5..35e8812 100644 --- a/fxtemplates/MultiTypeBirthDeath.xml +++ b/fxtemplates/MultiTypeBirthDeath.xml @@ -299,10 +299,6 @@ - - - - @@ -327,6 +323,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fxtemplates/MultiTypeBirthDeathUncoloured.xml b/fxtemplates/MultiTypeBirthDeathUncoloured.xml index 9bd116c..e598805 100644 --- a/fxtemplates/MultiTypeBirthDeathUncoloured.xml +++ b/fxtemplates/MultiTypeBirthDeathUncoloured.xml @@ -307,10 +307,6 @@ - - - - @@ -336,6 +332,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/bdmm/treesimulator/RandomMultiTypeTreeFromBDMM.java b/src/bdmm/treesimulator/RandomMultiTypeTreeFromBDMM.java index 1f69b1e..18b1b1f 100644 --- a/src/bdmm/treesimulator/RandomMultiTypeTreeFromBDMM.java +++ b/src/bdmm/treesimulator/RandomMultiTypeTreeFromBDMM.java @@ -6,7 +6,6 @@ import beast.base.inference.StateNodeInitialiser; import beast.base.inference.parameter.RealParameter; import beast.base.util.Randomizer; -import beast.evolution.tree.*; import multitypetree.evolution.tree.MultiTypeNode; import multitypetree.evolution.tree.MultiTypeTree; From 6bb8405ebac4dbd15b2e183ad2ee22e98f6ea468 Mon Sep 17 00:00:00 2001 From: Tim Vaughan Date: Mon, 19 Jun 2023 11:12:49 +0200 Subject: [PATCH 2/4] Improved build script. This uses the latest version of the universal build script, which relies on the PackageManager class to install package dependencies rather than having them built from source. --- build.xml | 301 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 187 insertions(+), 114 deletions(-) diff --git a/build.xml b/build.xml index b949195..d40d660 100644 --- a/build.xml +++ b/build.xml @@ -1,37 +1,44 @@ + + - + - - + + - - - + + + - + + + - + + + + + - @@ -50,125 +57,163 @@ - - - - - - + - - No local copy of the beast2 source found at ${beastDir}. + + No local copy of the beast2 source found at ${local-beast-source-root}. Compiling against version ${beast-version} from GitHub. - - + - - - - - - - - - - - - + + + + + - + - - Compiling against beast2 source found at ${beastDir}. + + Compiling against beast2 source found at ${local-beast-source-root}. - - + + + + - - - - - - - - + + + + + + + + + + + + + + - - - - - - + - + + + - + + Compiling against BeastFX source found at ${local-beastfx-source-root}. + + + + + - - Downloading dependencies... + + No local copy of the BeastFX source found at ${local-beastfx-source-root}. + Compiling against version ${beast-version} from GitHub. + - + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - - - + + + + + + + + + @@ -182,29 +227,50 @@ + + + + + + + + + + + + + + + + + + - - + + - - - - - - - + + + + + + + - - - + + + - + @@ -232,8 +298,7 @@ - - + @@ -242,6 +307,9 @@ + + + @@ -250,9 +318,9 @@ - + - + @@ -275,9 +343,14 @@ - + + + + + + @@ -344,7 +417,7 @@ - + @@ -352,10 +425,10 @@ The directory structure is as follows: ${src} - your java source goes here - ${test} - your junit tests go here (You _are_ going to write, those, aren't you!) + ${test} - your junit tests go here (You _are_ going to write those, aren't you!) ${doc} - your documentation goes here ${examples} - your example XML scripts go here - ${templates} - your BEAUti templates go here + ${fxtemplates} - your BEAUti fxtemplates go here To build your package, just type "ant" at the command line. From 77032cc5752bb2967827586e1aa282db28735503 Mon Sep 17 00:00:00 2001 From: Tim Vaughan Date: Wed, 6 Dec 2023 13:38:04 +0100 Subject: [PATCH 3/4] Converted all BDMM inputs to Functions. --- .../BirthDeathMigrationInputEditor.java | 70 ++++---- src/bdmm/core/util/Utils.java | 2 +- ...hDeathMigrationClusterModelUncoloured.java | 20 +-- .../speciation/BirthDeathMigrationModel.java | 6 +- .../BirthDeathMigrationModelUncoloured.java | 2 +- ...cewiseBirthDeathMigrationDistribution.java | 170 +++++++++--------- src/bdmm/math/p0_ODE.java | 20 +-- src/bdmm/math/p0ge_ODE.java | 50 +++--- 8 files changed, 166 insertions(+), 174 deletions(-) diff --git a/src/bdmm/app/beauti/BirthDeathMigrationInputEditor.java b/src/bdmm/app/beauti/BirthDeathMigrationInputEditor.java index dd37465..e33bd22 100644 --- a/src/bdmm/app/beauti/BirthDeathMigrationInputEditor.java +++ b/src/bdmm/app/beauti/BirthDeathMigrationInputEditor.java @@ -133,28 +133,28 @@ public void init(Input input, BEASTInterface beastObject, int itemNr, ExpandO r0Box = new HBox(); r0ModelVals = new ArrayList<>(); R0EstCheckBox = new CheckBox("estimate"); - this.initParameter(gridPane, 1, bdmm.R0.get(), "Reproduction number per type:", r0Box, r0ModelVals, R0EstCheckBox, bdmm.R0.getTipText(), ndim); + this.initParameter(gridPane, 1, (RealParameter) bdmm.R0.get(), "Reproduction number per type:", r0Box, r0ModelVals, R0EstCheckBox, bdmm.R0.getTipText(), ndim); // Init delta deltaBox = new HBox(); deltaModelVals = new ArrayList<>(); deltaEstCheckBox = new CheckBox("estimate"); - this.initParameter(gridPane, 2, bdmm.becomeUninfectiousRate.get(),"BecomeUninfectionRate per type:", deltaBox, deltaModelVals, deltaEstCheckBox, bdmm.becomeUninfectiousRate.getTipText(), ndim); + this.initParameter(gridPane, 2, (RealParameter) bdmm.becomeUninfectiousRate.get(),"BecomeUninfectionRate per type:", deltaBox, deltaModelVals, deltaEstCheckBox, bdmm.becomeUninfectiousRate.getTipText(), ndim); // Init sampling proportion samplingBox = new HBox(); samplingModelVals = new ArrayList<>(); samplingEstCheckBox = new CheckBox("estimate"); - this.initParameter(gridPane, 3, bdmm.samplingProportion.get(), "SamplingProportion per type:", samplingBox, samplingModelVals, samplingEstCheckBox, bdmm.samplingProportion.getTipText(), ndim*2); + this.initParameter(gridPane, 3, (RealParameter) bdmm.samplingProportion.get(), "SamplingProportion per type:", samplingBox, samplingModelVals, samplingEstCheckBox, bdmm.samplingProportion.getTipText(), ndim*2); // Init sampling change times but hide the first box samplingChangeBox = new HBox(); samplingChangeModelVals = new ArrayList<>(); - this.initParameter(gridPane, 4, bdmm.samplingRateChangeTimesInput.get(), "Sampling change time:", samplingChangeBox, samplingChangeModelVals, null, bdmm.samplingRateChangeTimesInput.getTipText(), 2); + this.initParameter(gridPane, 4, (RealParameter) bdmm.samplingRateChangeTimesInput.get(), "Sampling change time:", samplingChangeBox, samplingChangeModelVals, null, bdmm.samplingRateChangeTimesInput.getTipText(), 2); samplingChangeModelVals.get(0).setVisible(false); samplingChangeModelVals.get(0).setManaged(false); @@ -164,7 +164,7 @@ public void init(Input input, BEASTInterface beastObject, int itemNr, ExpandO rateMatrixBoxes = new ArrayList<>(); rateMatrixModelVals = new ArrayList<>(); rateMatrixEstCheckBox = new CheckBox("estimate"); - this.initMatrix(gridPane, 5, bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, "Migration rates:", rateMatrixBoxes, rateMatrixModelVals, rateMatrixEstCheckBox, bdmm.migrationMatrix.getTipText(), ndim); + this.initMatrix(gridPane, 5, (RealParameter) bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, "Migration rates:", rateMatrixBoxes, rateMatrixModelVals, rateMatrixEstCheckBox, bdmm.migrationMatrix.getTipText(), ndim); @@ -194,19 +194,19 @@ public void init(Input input, BEASTInterface beastObject, int itemNr, ExpandO // Update R0 - setVectorDimension(bdmm.R0.get(), r0Box, r0ModelVals, oldDim, newDim, bdmm.R0.getTipText()); + setVectorDimension((RealParameter) bdmm.R0.get(), r0Box, r0ModelVals, oldDim, newDim, bdmm.R0.getTipText()); // Update delta - setVectorDimension(bdmm.becomeUninfectiousRate.get(), deltaBox, deltaModelVals, oldDim, newDim, bdmm.becomeUninfectiousRate.getTipText()); + setVectorDimension((RealParameter) bdmm.becomeUninfectiousRate.get(), deltaBox, deltaModelVals, oldDim, newDim, bdmm.becomeUninfectiousRate.getTipText()); // Update sampling proportion - setVectorDimension(bdmm.samplingProportion.get(), samplingBox, samplingModelVals, oldDim*2, newDim*2, bdmm.samplingProportion.getTipText()); + setVectorDimension((RealParameter) bdmm.samplingProportion.get(), samplingBox, samplingModelVals, oldDim*2, newDim*2, bdmm.samplingProportion.getTipText()); // Update sampling change times - setVectorDimension(bdmm.samplingRateChangeTimesInput.get(), samplingChangeBox, samplingChangeModelVals, 2, 2, bdmm.samplingRateChangeTimesInput.getTipText()); + setVectorDimension((RealParameter) bdmm.samplingRateChangeTimesInput.get(), samplingChangeBox, samplingChangeModelVals, 2, 2, bdmm.samplingRateChangeTimesInput.getTipText()); // Update migration matrix - setMatrixDimension(bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, rateMatrixBoxes, rateMatrixModelVals, newDim, bdmm.migrationMatrix.getTipText()); + setMatrixDimension((RealParameter) bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, rateMatrixBoxes, rateMatrixModelVals, newDim, bdmm.migrationMatrix.getTipText()); System.out.println(" r0ModelVals " + r0ModelVals.size()); @@ -227,10 +227,10 @@ public void init(Input input, BEASTInterface beastObject, int itemNr, ExpandO sbfreqs.append(Double.toString(fr)); } - - bdmm.frequencies.get().valuesInput.setValue(sbfreqs.toString(), bdmm.frequencies.get()); - bdmm.frequencies.get().setDimension(newDim); - bdmm.frequencies.get().initAndValidate(); + + ((RealParameter) bdmm.frequencies.get()).valuesInput.setValue(sbfreqs.toString(), (RealParameter) bdmm.frequencies.get()); + ((RealParameter) bdmm.frequencies.get()).setDimension(newDim); + ((RealParameter) bdmm.frequencies.get()).initAndValidate(); bdmm.stateNumber.setValue(newDim, bdmm); //bdmm.setInputValue("stateNumber", newDim); @@ -273,7 +273,7 @@ private void initParameter(GridPane gridPane, int rowNum, RealParameter param, S // Add estimate checkbox if (checkBox != null) { - checkBox.setSelected(bdmm.R0.get().isEstimatedInput.get()); + checkBox.setSelected(((RealParameter) bdmm.R0.get()).isEstimatedInput.get()); checkBox.setTooltip(new Tooltip("Estimate value of this parameter in the MCMC chain")); @@ -298,7 +298,6 @@ private void initParameter(GridPane gridPane, int rowNum, RealParameter param, S * @param param * @param name * @param hboxes - * @param vector * @param checkBox * @param tooltip * @param ndim @@ -344,7 +343,7 @@ private void initMatrix(GridPane gridPane, int rowNum, RealParameter param, VBox // Add estimate checkbox if (checkBox != null) { - checkBox.setSelected(bdmm.R0.get().isEstimatedInput.get()); + checkBox.setSelected(((RealParameter) bdmm.R0.get()).isEstimatedInput.get()); checkBox.setTooltip(new Tooltip("Estimate value of this parameter in the MCMC chain")); @@ -405,7 +404,6 @@ private void saveParameter(RealParameter param, List vector, Boolean /** * Saves a parameter from the gui to bdmm * @param param - * @param vector */ private void saveMatrix(RealParameter param, List> matrix, Boolean selected, int ndim) { @@ -475,10 +473,6 @@ private void loadParameter(RealParameter param, List vector, HBox hbo /** * Same as above but for a matrix * @param param - * @param rateMatrixModelVals2 - * @param rateMatrixBoxes2 - * @param rateMatrixEstCheckBox2 - * @param tipText */ private void loadMatrix(RealParameter param, VBox vbox, List> matrix, List hboxes, CheckBox checkBox, String tooltip, int ndim) { @@ -565,8 +559,6 @@ private void setVectorDimension(RealParameter param, HBox hbox, List * @param vbox * @param hboxes * @param matrix - * @param oldDim - * @param newDim * @param tooltip */ private void setMatrixDimension(RealParameter param, VBox vbox, List hboxes, List> matrix, int ndim, String tooltip) { @@ -663,11 +655,11 @@ public void loadFromBDMM() { dimSpinner.getValueFactory().setValue(ndim); - this.loadParameter(bdmm.R0.get(), r0ModelVals, r0Box, R0EstCheckBox, bdmm.R0.getTipText()); - this.loadParameter(bdmm.becomeUninfectiousRate.get(), deltaModelVals, deltaBox, deltaEstCheckBox, bdmm.becomeUninfectiousRate.getTipText()); - this.loadParameter(bdmm.samplingProportion.get(), samplingModelVals, samplingBox, samplingEstCheckBox, bdmm.samplingProportion.getTipText()); - this.loadParameter(bdmm.samplingRateChangeTimesInput.get(), samplingChangeModelVals, samplingChangeBox, null, bdmm.samplingRateChangeTimesInput.getTipText()); - this.loadMatrix(bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, rateMatrixModelVals, rateMatrixBoxes, rateMatrixEstCheckBox, bdmm.migrationMatrix.getTipText(), ndim); + this.loadParameter((RealParameter) bdmm.R0.get(), r0ModelVals, r0Box, R0EstCheckBox, bdmm.R0.getTipText()); + this.loadParameter((RealParameter) bdmm.becomeUninfectiousRate.get(), deltaModelVals, deltaBox, deltaEstCheckBox, bdmm.becomeUninfectiousRate.getTipText()); + this.loadParameter((RealParameter) bdmm.samplingProportion.get(), samplingModelVals, samplingBox, samplingEstCheckBox, bdmm.samplingProportion.getTipText()); + this.loadParameter((RealParameter) bdmm.samplingRateChangeTimesInput.get(), samplingChangeModelVals, samplingChangeBox, null, bdmm.samplingRateChangeTimesInput.getTipText()); + this.loadMatrix((RealParameter) bdmm.migrationMatrix.get(), rateMatrixTextFieldBox, rateMatrixModelVals, rateMatrixBoxes, rateMatrixEstCheckBox, bdmm.migrationMatrix.getTipText(), ndim); @@ -682,18 +674,18 @@ public void saveParameters() { // Parse parameters - this.saveParameter(bdmm.R0.get(), r0ModelVals, R0EstCheckBox.isSelected(), ndim); - this.saveParameter(bdmm.becomeUninfectiousRate.get(), deltaModelVals, deltaEstCheckBox.isSelected(), ndim); - this.saveParameter(bdmm.samplingProportion.get(), samplingModelVals, samplingEstCheckBox.isSelected(), ndim*2); - this.saveParameter(bdmm.samplingRateChangeTimesInput.get(), samplingChangeModelVals, null, 2); - this.saveMatrix(bdmm.migrationMatrix.get(), rateMatrixModelVals, rateMatrixEstCheckBox.isSelected(), ndim); + this.saveParameter((RealParameter) bdmm.R0.get(), r0ModelVals, R0EstCheckBox.isSelected(), ndim); + this.saveParameter((RealParameter) bdmm.becomeUninfectiousRate.get(), deltaModelVals, deltaEstCheckBox.isSelected(), ndim); + this.saveParameter((RealParameter) bdmm.samplingProportion.get(), samplingModelVals, samplingEstCheckBox.isSelected(), ndim*2); + this.saveParameter((RealParameter) bdmm.samplingRateChangeTimesInput.get(), samplingChangeModelVals, null, 2); + this.saveMatrix((RealParameter) bdmm.migrationMatrix.get(), rateMatrixModelVals, rateMatrixEstCheckBox.isSelected(), ndim); try { - bdmm.R0.get().initAndValidate(); - bdmm.samplingProportion.get().initAndValidate(); - bdmm.samplingRateChangeTimesInput.get().initAndValidate(); - bdmm.becomeUninfectiousRate.get().initAndValidate(); - bdmm.migrationMatrix.get().initAndValidate(); + ((RealParameter)bdmm.R0.get()).initAndValidate(); + ((RealParameter)bdmm.samplingProportion.get()).initAndValidate(); + ((RealParameter)bdmm.samplingRateChangeTimesInput.get()).initAndValidate(); + ((RealParameter)bdmm.becomeUninfectiousRate.get()).initAndValidate(); + ((RealParameter)bdmm.migrationMatrix.get()).initAndValidate(); bdmm.initAndValidate(); } catch (Exception ex) { ex.printStackTrace(); diff --git a/src/bdmm/core/util/Utils.java b/src/bdmm/core/util/Utils.java index f0f6565..2fc563b 100755 --- a/src/bdmm/core/util/Utils.java +++ b/src/bdmm/core/util/Utils.java @@ -16,7 +16,7 @@ public class Utils { * @param m the total number of time intervals + 1 (the total number of time change events) * @return */ - public static int index(Double t, Double[] times, int m) { + public static int index(double t, double[] times, int m) { int epoch = Arrays.binarySearch(times, t); diff --git a/src/bdmm/evolution/speciation/BirthDeathMigrationClusterModelUncoloured.java b/src/bdmm/evolution/speciation/BirthDeathMigrationClusterModelUncoloured.java index f1e4762..920d5a9 100644 --- a/src/bdmm/evolution/speciation/BirthDeathMigrationClusterModelUncoloured.java +++ b/src/bdmm/evolution/speciation/BirthDeathMigrationClusterModelUncoloured.java @@ -88,19 +88,19 @@ protected Double updateRates(TreeInterface tree) { birth = new double[n*totalIntervals]; death = new double[n*totalIntervals]; - psi = new Double[n*totalIntervals]; - b_ij = new Double[totalIntervals*(n*(n-1))]; - M = new Double[totalIntervals*(n*(n-1))]; - if (SAModel) r = new Double[n * totalIntervals]; + psi = new double[n*totalIntervals]; + b_ij = new double[totalIntervals*(n*(n-1))]; + M = new double[totalIntervals*(n*(n-1))]; + if (SAModel) r = new double[n * totalIntervals]; if (transform) { transformParameters(); } else { - Double[] birthAmongDemesRates = new Double[1]; + double[] birthAmongDemesRates = new double[1]; - if (birthAmongDemes) birthAmongDemesRates = birthRateAmongDemes.get().getValues(); + if (birthAmongDemes) birthAmongDemesRates = birthRateAmongDemes.get().getDoubleValues(); updateBirthDeathPsiParams(); @@ -110,10 +110,10 @@ protected Double updateRates(TreeInterface tree) { } } - Double[] migRates = migrationMatrix.get().getValues(); - Double factor; + double[] migRates = migrationMatrix.get().getDoubleValues(); + double factor; if (migrationMatrixScaleFactor.get()!=null) { - factor = migrationMatrixScaleFactor.get().getValue(); + factor = migrationMatrixScaleFactor.get().getArrayValue(); for (int i = 0; i < M.length; i++) M[i] *= factor; } @@ -125,7 +125,7 @@ protected Double updateRates(TreeInterface tree) { for (int i = 0; i < totalIntervals; i++) birth[i]*=getRateForCluster(clusterIndices[currentCluster.get()-1]); - freq = frequencies.get().getValues(); + freq = frequencies.get().getDoubleValues(); setupIntegrators(); diff --git a/src/bdmm/evolution/speciation/BirthDeathMigrationModel.java b/src/bdmm/evolution/speciation/BirthDeathMigrationModel.java index 196c52e..fc07150 100755 --- a/src/bdmm/evolution/speciation/BirthDeathMigrationModel.java +++ b/src/bdmm/evolution/speciation/BirthDeathMigrationModel.java @@ -196,7 +196,7 @@ public double calculateTreeLogLikelihood(TreeInterface tree) { if (Double.isInfinite(logP)) logP = Double.NEGATIVE_INFINITY; - if (SAModel && !(removalProbability.get().getDimension()==n && removalProbability.get().getValue()==1.)) { + if (SAModel && !(removalProbability.get().getDimension()==n && removalProbability.get().getArrayValue()==1.)) { int internalNodeCount = tree.getLeafNodeCount() - ((Tree)tree).getDirectAncestorNodeCount()- 1; logP += Math.log(2)*internalNodeCount; } @@ -283,7 +283,7 @@ p0ge_InitialConditions calculateSubtreeLikelihood(Node node, Boolean isMigration System.arraycopy(g.conditionsOnP, 0, init.conditionsOnP, 0, n); if (birthAmongDemes) // this might be a birth among demes where only the child with the different type got sampled init.conditionsOnG[prevcol] = g.conditionsOnG[col].scalarMultiply(b_ij[totalIntervals * (prevcol * (n - 1) + (col < prevcol ? col : col - 1)) + index]); - if (M[0]!=null) // or it really is a migration event + if (M!=null) // or it really is a migration event init.conditionsOnG[prevcol] = g.conditionsOnG[col].scalarMultiply(M[totalIntervals * (prevcol * (n - 1) + (col < prevcol ? col : col - 1)) + index]); return getG(from, init, to, PG, node, true); @@ -448,7 +448,7 @@ public Boolean originBranchIsValid(MultiTypeNode root, Boolean allowChangeAtNode if (count>0){ - if (originBranch.getChangeTime(0) < root.getHeight() || originBranch.getChangeTime(count-1) > origin.get().getValue() ) + if (originBranch.getChangeTime(0) < root.getHeight() || originBranch.getChangeTime(count-1) > origin.get().getArrayValue() ) return false; if (!allowChangeAtNode && originBranch.getChangeType(0) == root.getFinalType()) diff --git a/src/bdmm/evolution/speciation/BirthDeathMigrationModelUncoloured.java b/src/bdmm/evolution/speciation/BirthDeathMigrationModelUncoloured.java index 6ad1e87..f9eed59 100755 --- a/src/bdmm/evolution/speciation/BirthDeathMigrationModelUncoloured.java +++ b/src/bdmm/evolution/speciation/BirthDeathMigrationModelUncoloured.java @@ -209,7 +209,7 @@ public double calculateTreeLogLikelihood(TreeInterface tree) { if (print) System.out.println("\nlogP = " + logP); if (Double.isInfinite(logP)) logP = Double.NEGATIVE_INFINITY; - if (SAModel && !(removalProbability.get().getDimension()==n && removalProbability.get().getValue()==1.)) { + if (SAModel && !(removalProbability.get().getDimension()==n && removalProbability.get().getArrayValue()==1.)) { int internalNodeCount = tree.getLeafNodeCount() - ((Tree)tree).getDirectAncestorNodeCount()- 1; logP += Math.log(2)*internalNodeCount; } diff --git a/src/bdmm/evolution/speciation/PiecewiseBirthDeathMigrationDistribution.java b/src/bdmm/evolution/speciation/PiecewiseBirthDeathMigrationDistribution.java index c4c576b..ba388b1 100644 --- a/src/bdmm/evolution/speciation/PiecewiseBirthDeathMigrationDistribution.java +++ b/src/bdmm/evolution/speciation/PiecewiseBirthDeathMigrationDistribution.java @@ -53,10 +53,10 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTreeDistribution { - public Input frequencies = + public Input frequencies = new Input<>("frequencies", "The frequencies for each type", Input.Validate.REQUIRED); - public Input origin = + public Input origin = new Input<>("origin", "The origin of infection x1"); public Input originIsRootEdge = @@ -75,30 +75,30 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr new Input<>("absTolerance", "absolute tolerance for numerical integration", 1e-100 /*Double.MIN_VALUE*/); // the interval times for the migration rates - public Input migChangeTimesInput = + public Input migChangeTimesInput = new Input<>("migChangeTimes", "The times t_i specifying when migration rate changes occur", (RealParameter) null); // the interval times for the birth rate - public Input birthRateChangeTimesInput = + public Input birthRateChangeTimesInput = new Input<>("birthRateChangeTimes", "The times t_i specifying when birth/R rate changes occur", (RealParameter) null); // the interval times for the birth rate among demes - public Input b_ijChangeTimesInput = + public Input b_ijChangeTimesInput = new Input<>("birthRateAmongDemesChangeTimes", "The times t_i specifying when birth/R among demes changes occur", (RealParameter) null); // the interval times for the death rate - public Input deathRateChangeTimesInput = + public Input deathRateChangeTimesInput = new Input<>("deathRateChangeTimes", "The times t_i specifying when death/becomeUninfectious rate changes occur", (RealParameter) null); // the interval times for sampling rate - public Input samplingRateChangeTimesInput = + public Input samplingRateChangeTimesInput = new Input<>("samplingRateChangeTimes", "The times t_i specifying when sampling rate or sampling proportion changes occur", (RealParameter) null); // the interval times for removal probability - public Input removalProbabilityChangeTimesInput = - new Input("removalProbabilityChangeTimes", "The times t_i specifying when removal probability changes occur", (RealParameter) null); + public Input removalProbabilityChangeTimesInput = + new Input<>("removalProbabilityChangeTimes", "The times t_i specifying when removal probability changes occur", (RealParameter) null); - public Input intervalTimes = + public Input intervalTimes = new Input<>("intervalTimes", "The time t_i for all parameters if they are the same", (RealParameter) null); public Input migTimesRelativeInput = @@ -124,7 +124,7 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr "Careful, rate array must still be given in FORWARD time (root to tips)."); // the times for rho sampling - public Input rhoSamplingTimes = + public Input rhoSamplingTimes = new Input<>("rhoSamplingTimes", "The times t_i specifying when rho-sampling occurs", (RealParameter) null); public Input contemp = new Input<>("contemp", "Only contemporaneous sampling (i.e. all tips are from same sampling time, default false)", false); @@ -133,37 +133,37 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr new Input<>("birthRate", "BirthRate = BirthRateVector * birthRateScalar, birthrate can change over time"); public Input deathRate = new Input<>("deathRate", "The deathRate vector with birthRates between times"); - public Input samplingRate = + public Input samplingRate = new Input<>("samplingRate", "The sampling rate per individual"); // psi - public Input m_rho = + public Input m_rho = new Input<>("rho", "The proportion of lineages sampled at rho-sampling times (default 0.)"); - public Input R0 = + public Input R0 = new Input<>("R0", "The basic reproduction number"); - public Input becomeUninfectiousRate = + public Input becomeUninfectiousRate = new Input<>("becomeUninfectiousRate", "Rate at which individuals become uninfectious (through recovery or sampling)", Input.Validate.XOR, deathRate); - public Input samplingProportion = + public Input samplingProportion = new Input<>("samplingProportion", "The samplingProportion = samplingRate / becomeUninfectiousRate", Input.Validate.XOR, samplingRate); public Input identicalRatesForAllTypesInput = new Input<>("identicalRatesForAllTypes", "True if all types should have the same 1) birth 2) death 3) sampling 4) rho 5) r 6) migration rate. Default false."); - public Input R0_base = + public Input R0_base = new Input<>("R0_base", "The basic reproduction number for the base pathogen class, should have the same dimension as " + "the number of time intervals."); - public Input lambda_ratio = + public Input lambda_ratio = new Input<>("lambda_ratio", "The ratio of basic infection rates of all other classes when compared to the base lambda, " + "should have the dimension of the number of pathogens - 1, as it is kept constant over intervals."); - public Input migrationMatrix = + public Input migrationMatrix = new Input<>("migrationMatrix", "Flattened migration matrix, can be asymmetric, diagonal entries omitted"); - public Input migrationMatrixScaleFactor = + public Input migrationMatrixScaleFactor = new Input<>("migrationMatrixScaleFactor", "A real number with which each migration rate entry is scaled."); // adapted from SCMigrationModel class in package MultiTypeTree by Tim Vaughan @@ -174,21 +174,21 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr + " (Default is to use all rates.)"); - public Input birthRateAmongDemes = + public Input birthRateAmongDemes = new Input<>("birthRateAmongDemes", "birth rate vector with rate at which transmissions occur among locations"); - public Input R0AmongDemes = + public Input R0AmongDemes = new Input<>("R0AmongDemes", "The basic reproduction number determining transmissions occur among locations"); - public Input removalProbability = - new Input("removalProbability", "The probability of an individual to become noninfectious immediately after the sampling"); + public Input removalProbability = + new Input<>("removalProbability", "The probability of an individual to become noninfectious immediately after the sampling"); public Input stateNumber = new Input<>("stateNumber", "The number of states or locations", Input.Validate.REQUIRED); - public Input adjustTimesInput = + public Input adjustTimesInput = new Input<>("adjustTimes", "Origin of MASTER sims which has to be deducted from the change time arrays"); // @@ -203,7 +203,7 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr //If a large number a cores is available (more than 8 or 10) the calculation speed can be increased by diminishing the parallelization factor //On the contrary, if only 2-4 cores are available, a slightly higher value (1/5 to 1/8) can be beneficial to the calculation speed. public Input minimalProportionForParallelizationInput = new Input<>("parallelizationFactor", "the minimal relative size the two children subtrees of a node" + - " must have to start parallel calculations on the children. (default: 1/10). ", new Double(1/10)); + " must have to start parallel calculations on the children. (default: 1/10). ", 0.1); public static boolean isParallelizedCalculation; @@ -227,9 +227,9 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr // these four arrays are totalIntervals in length protected double[] birth; double[] death; - Double[] psi; - static volatile Double[] rho; - Double[] r; + double[] psi; + static volatile double[] rho; + double[] r; /** * The number of change points in the birth rate, b_ij, death rate, sampling rate, rho, r @@ -264,12 +264,12 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr protected List deathRateChangeTimes = new ArrayList<>(); protected List samplingRateChangeTimes = new ArrayList<>(); protected List rhoSamplingChangeTimes = new ArrayList<>(); - protected List rChangeTimes = new ArrayList(); + protected List rChangeTimes = new ArrayList<>(); Boolean contempData; SortedSet timesSet = new TreeSet<>(); - protected static volatile Double[] times = new Double[]{0.}; + protected static volatile double[] times = new double[]{0.}; protected Boolean transform; @@ -281,11 +281,11 @@ public abstract class PiecewiseBirthDeathMigrationDistribution extends SpeciesTr Boolean rTimesRelative = false; Boolean[] reverseTimeArrays; - Double[] M; - Double[] b_ij; + double[] M; + double[] b_ij; Boolean birthAmongDemes = false; - Double[] freq; + double[] freq; static double[][] pInitialConditions; @@ -330,7 +330,7 @@ public void initAndValidate() { Double factor; if (migrationMatrix.get()!=null) { - M = migrationMatrix.get().getValues(); + M = migrationMatrix.get().getDoubleValues(); if (rateMatrixFlagsInput.get() != null) { rateMatrixFlags = rateMatrixFlagsInput.get(); @@ -347,7 +347,7 @@ public void initAndValidate() { if (migrationMatrixScaleFactor.get()!=null) { - factor = migrationMatrixScaleFactor.get().getValue(); + factor = migrationMatrixScaleFactor.get().getArrayValue(); for (int i = 0; i < M.length; i++) M[i] *= factor; } @@ -395,14 +395,14 @@ public void initAndValidate() { transform = false; death = deathRate.get().getDoubleValues(); - psi = samplingRate.get().getValues(); + psi = samplingRate.get().getDoubleValues(); birth = birthRate.get().getDoubleValues(); - if (SAModel) r = removalProbability.get().getValues(); + if (SAModel) r = removalProbability.get().getDoubleValues(); if (birthRateAmongDemes.get()!=null ){ birthAmongDemes = true; - b_ij=birthRateAmongDemes.get().getValues(); + b_ij=birthRateAmongDemes.get().getDoubleValues(); } } else if ((R0.get() != null || (R0_base.get() != null && lambda_ratio.get() != null)) && becomeUninfectiousRate.get() != null && samplingProportion.get() != null) { transform = true; @@ -439,11 +439,11 @@ public void initAndValidate() { if (SAModel) rChanges = removalProbability.get().getDimension()/n -1; if (m_rho.get()!=null) { - rho = m_rho.get().getValues(); + rho = m_rho.get().getDoubleValues(); rhoChanges = m_rho.get().getDimension()/n - 1; } - freq = frequencies.get().getValues(); + freq = frequencies.get().getDoubleValues(); double freqSum = 0; for (double f : freq) freqSum+= f; @@ -560,8 +560,8 @@ void setRho(){ constantRho = !(m_rho.get().getDimension() > n); if (m_rho.get().getDimension() <= n && (rhoSamplingTimes.get()==null || rhoSamplingTimes.get().getDimension() < 2)) { - if (!contempData && ((samplingProportion.get() != null && samplingProportion.get().getDimension() <= n && samplingProportion.get().getValue() == 0.) || // todo: instead of samplingProportion.get().getValue() == 0. need checked that samplingProportion[i]==0 for all i=0..n-1 - (samplingRate.get() != null && samplingRate.get().getDimension() <= 2 && samplingRate.get().getValue() == 0.))) { // todo: instead of samplingRate.get().getValue() == 0. need checked that samplingRate[i]==0 for all i=0..n-1 + if (!contempData && ((samplingProportion.get() != null && samplingProportion.get().getDimension() <= n && samplingProportion.get().getArrayValue() == 0.) || // todo: instead of samplingProportion.get().getValue() == 0. need checked that samplingProportion[i]==0 for all i=0..n-1 + (samplingRate.get() != null && samplingRate.get().getDimension() <= 2 && samplingRate.get().getArrayValue() == 0.))) { // todo: instead of samplingRate.get().getValue() == 0. need checked that samplingRate[i]==0 for all i=0..n-1 // check if data set is contemp! for (Node node : treeInput.get().getExternalNodes()){ @@ -578,17 +578,17 @@ void setRho(){ throw new RuntimeException("when contemp=true, rho must have dimension 1 (or equal to the stateNumber)"); else { - rho = new Double[n*totalIntervals]; + rho = new double[n*totalIntervals]; Arrays.fill(rho, 0.); Arrays.fill(isRhoTip, true); - for (int i=1; i<=n; i++) rho[i*totalIntervals - 1] = m_rho.get().getValue(i-1); + for (int i=1; i<=n; i++) rho[i*totalIntervals - 1] = m_rho.get().getArrayValue(i-1); rhoSamplingCount = 1; } } else { - Double[] rhos = m_rho.get().getValues(); - rho = new Double[n*totalIntervals]; + double[] rhos = m_rho.get().getDoubleValues(); + rho = new double[n*totalIntervals]; Arrays.fill(rho, 0.); for (int i = 0; i < totalIntervals; i++) { for (int j=0;j changeTimes, RealParameter intervalTimes, int numChanges, boolean relative, boolean reverse, boolean isPointEvent) { + public void getChangeTimes(double maxTime, List changeTimes, Function intervalTimes, int numChanges, boolean relative, boolean reverse, boolean isPointEvent) { changeTimes.clear(); if (intervalTimes == null) { //equidistant @@ -745,7 +745,7 @@ public void getChangeTimes(double maxTime, List changeTimes, RealParamet changeTimes.add(end); } else { - if (!reverse && intervalTimes.getValue(0) != 0.0 && !isPointEvent) { + if (!reverse && intervalTimes.getArrayValue(0) != 0.0 && !isPointEvent) { throw new RuntimeException("First time in interval times parameter should always be zero."); } @@ -757,7 +757,7 @@ public void getChangeTimes(double maxTime, List changeTimes, RealParamet double end; for (int i = (reverse?0:1); i < dim; i++) { - end = reverse ? (maxTime - intervalTimes.getValue(dim - i - 1)) : intervalTimes.getValue(i); + end = reverse ? (maxTime - intervalTimes.getArrayValue(dim - i - 1)) : intervalTimes.getArrayValue(i); if (relative) end *= maxTime; if (end < maxTime) changeTimes.add(end); //TODO does this mean that change times can never be input in absolute time? It looks like it does. } @@ -765,7 +765,7 @@ public void getChangeTimes(double maxTime, List changeTimes, RealParamet if (adjustTimesInput.get()!=null){ double iTime; - double aTime = adjustTimesInput.get().getValue(); + double aTime = adjustTimesInput.get().getArrayValue(); for (int i = 0 ; i < numChanges; i++){ @@ -792,12 +792,12 @@ void updateBirthDeathPsiParams(){ double[] birthRates = birthRate.get().getDoubleValues(); double[] deathRates = deathRate.get().getDoubleValues(); - Double[] samplingRates = samplingRate.get().getValues(); - Double[] removalProbabilities = new Double[1]; + double[] samplingRates = samplingRate.get().getDoubleValues(); + double[] removalProbabilities = new double[1]; if (SAModel) { - removalProbabilities = removalProbability.get().getValues(); - r = new Double[n*totalIntervals]; + removalProbabilities = removalProbability.get().getDoubleValues(); + r = new double[n*totalIntervals]; } int state; @@ -820,7 +820,7 @@ void updateBirthDeathPsiParams(){ } - void updateAmongParameter(Double[] param, Double[] paramFrom, int nrChanges, List changeTimes){ + void updateAmongParameter(double[] param, double[] paramFrom, int nrChanges, List changeTimes){ for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { @@ -840,8 +840,8 @@ void updateAmongParameter(Double[] param, Double[] paramFrom, int nrChanges, Lis void updateRho(){ if (m_rho.get() != null && (m_rho.get().getDimension()==1 || rhoSamplingTimes.get() != null)) { - Double[] rhos = m_rho.get().getValues(); - rho = new Double[n*totalIntervals]; + double[] rhos = m_rho.get().getDoubleValues(); + rho = new double[n*totalIntervals]; int state; for (int i = 0; i < totalIntervals*n; i++) { @@ -885,18 +885,18 @@ public int index(double t, List times) { public void transformWithinParameters(){ - Double[] p = samplingProportion.get().getValues(); - Double[] ds = becomeUninfectiousRate.get().getValues(); - Double[] R; + double[] p = samplingProportion.get().getDoubleValues(); + double[] ds = becomeUninfectiousRate.get().getDoubleValues(); + double[] R; if (R0.get() != null) { - R = R0.get().getValues(); + R = R0.get().getDoubleValues(); } else { - Double[] l_ratio = lambda_ratio.get().getValues(); - Double[] R_sens = R0_base.get().getValues(); + double[] l_ratio = lambda_ratio.get().getDoubleValues(); + double[] R_sens = R0_base.get().getDoubleValues(); int totalIntervals = R_sens.length; int totalTypes = l_ratio.length + 1; - R = new Double[totalIntervals * totalTypes]; + R = new double[totalIntervals * totalTypes]; for (int i=0; i < totalIntervals; i++) { R[i] = R_sens[i]; for (int j=1; j < totalTypes; j++) { @@ -906,8 +906,8 @@ public void transformWithinParameters(){ } } - Double[] removalProbabilities = new Double[1]; - if (SAModel) removalProbabilities = removalProbability.get().getValues(); + double[] removalProbabilities = new double[1]; + if (SAModel) removalProbabilities = removalProbability.get().getDoubleValues(); int state; @@ -955,8 +955,8 @@ public void transformWithinParameters(){ public void transformAmongParameters(){ - Double[] RaD = (birthAmongDemes) ? R0AmongDemes.get().getValues() : new Double[1]; - Double[] ds = becomeUninfectiousRate.get().getValues(); + double[] RaD = (birthAmongDemes) ? R0AmongDemes.get().getDoubleValues() : new double[1]; + double[] ds = becomeUninfectiousRate.get().getDoubleValues(); if (birthAmongDemes) { @@ -999,12 +999,12 @@ void checkOrigin(TreeInterface tree){ void updateOrigin(Node root){ - T = origin.get().getValue(); + T = origin.get().getArrayValue(); orig = T - root.getHeight(); if (originIsRootEdge.get()) { - orig = origin.get().getValue(); + orig = origin.get().getArrayValue(); T = orig + root.getHeight(); } @@ -1150,19 +1150,19 @@ protected Double updateRates() { birth = new double[n*totalIntervals]; death = new double[n*totalIntervals]; - psi = new Double[n*totalIntervals]; - b_ij = new Double[totalIntervals*(n*(n-1))]; - M = new Double[totalIntervals*(n*(n-1))]; - if (SAModel) r = new Double[n * totalIntervals]; + psi = new double[n*totalIntervals]; + b_ij = new double[totalIntervals*(n*(n-1))]; + M = new double[totalIntervals*(n*(n-1))]; + if (SAModel) r = new double[n * totalIntervals]; if (transform) { transformParameters(); } else { - Double[] birthAmongDemesRates = new Double[1]; + double[] birthAmongDemesRates = new double[1]; - if (birthAmongDemes) birthAmongDemesRates = birthRateAmongDemes.get().getValues(); + if (birthAmongDemes) birthAmongDemesRates = birthRateAmongDemes.get().getDoubleValues(); updateBirthDeathPsiParams(); @@ -1173,11 +1173,11 @@ protected Double updateRates() { } if (migrationMatrix.get()!=null) { - Double[] migRates = migrationMatrix.get().getValues(); + double[] migRates = migrationMatrix.get().getDoubleValues(); - Double factor; + double factor; if (migrationMatrixScaleFactor.get()!=null) { - factor = migrationMatrixScaleFactor.get().getValue(); + factor = migrationMatrixScaleFactor.get().getArrayValue(); for (int i = 0; i < migRates.length; i++) migRates[i] *= factor; } @@ -1194,7 +1194,7 @@ protected Double updateRates() { updateRho(); - freq = frequencies.get().getValues(); + freq = frequencies.get().getDoubleValues(); setupIntegrators(); @@ -1235,9 +1235,9 @@ public double getNbyNRate(int i, int j) { int offset = getArrayOffset(i, j); if (migrationMatrixScaleFactor.get()==null) - return migrationMatrix.get().getValue(offset); + return migrationMatrix.get().getArrayValue(offset); else - return migrationMatrixScaleFactor.get().getValue()*migrationMatrix.get().getValue(offset); + return migrationMatrixScaleFactor.get().getArrayValue()*migrationMatrix.get().getArrayValue(offset); } diff --git a/src/bdmm/math/p0_ODE.java b/src/bdmm/math/p0_ODE.java index 1cd0695..ea0b50b 100755 --- a/src/bdmm/math/p0_ODE.java +++ b/src/bdmm/math/p0_ODE.java @@ -16,18 +16,18 @@ public class p0_ODE implements FirstOrderDifferentialEquations { double[] b; - Double[] b_ij; + double[] b_ij; double[] d; - Double[] s; + double[] s; - Double[] M; + double[] M; int dimension; int intervals; - Double[] times; + double[] times; int index; - public p0_ODE(double[] b, Double[] b_ij, double[] d, Double[] s, Double[] M, int dimension , int intervals, Double[] times) { + public p0_ODE(double[] b, double[] b_ij, double[] d, double[] s, double[] M, int dimension , int intervals, double[] times) { this.b = b; this.b_ij = b_ij; @@ -42,7 +42,7 @@ public p0_ODE(double[] b, Double[] b_ij, double[] d, Double[] s, Double[] M, int } // updateRates is not used here because a new p0_ODE is created each time PiecewiseBirthDeathMigrationDistribution.updateRates() is called (called through setUpIntegrators()) - public void updateRates(double[] b, Double[] b_ij, double[] d, Double[] s, Double[] M, Double[] times){ + public void updateRates(double[] b, double[] b_ij, double[] d, double[] s, double[] M, double[] times){ this.b = b; this.b_ij = b_ij; @@ -80,7 +80,7 @@ public void computeDerivatives(double t, double[] y, double[] yDot) { yDot[i] -= b_ij[l]*y[i]*y[j]; } - if (M[0]!=null) {// migration: + if (M!=null) {// migration: yDot[i] += M[l] * y[i]; yDot[i] -= M[l] * y[j]; } @@ -100,11 +100,11 @@ public static void main(String[] args) throws Exception{ // 2d test double[] b = {1.03,1.06}; double[] d = {1.,1.}; - Double[] s = {0.02,0.04}; - Double[] M = new Double[]{3.,4.}; + double[] s = {0.02,0.04}; + double[] M = new double[]{3.,4.}; FirstOrderIntegrator integrator = new DormandPrince853Integrator(1.0e-8, 100.0, 1.0e-20, 1.0e-9);//new ClassicalRungeKuttaIntegrator(.01); // - FirstOrderDifferentialEquations ode = new p0_ODE(b,null,d,s,M, 2, 1, new Double[]{0.}); + FirstOrderDifferentialEquations ode = new p0_ODE(b,null,d,s,M, 2, 1, new double[]{0.}); double[] y0 = new double[]{1.,1.}; double[] y = new double[2]; diff --git a/src/bdmm/math/p0ge_ODE.java b/src/bdmm/math/p0ge_ODE.java index ad2842a..6ab490d 100755 --- a/src/bdmm/math/p0ge_ODE.java +++ b/src/bdmm/math/p0ge_ODE.java @@ -26,19 +26,19 @@ public class p0ge_ODE implements FirstOrderDifferentialEquations { public FirstOrderIntegrator p_integrator; double[] b; - Double[] b_ij; + double[] b_ij; double[] d; - Double[] s; + double[] s; Boolean augmented; Boolean birthAmongDemes; - Double[] M; + double[] M; double T; int dimension; /* ODE numberOfDemes = stateNumber */ int intervals; - Double[] times; + double[] times; int index; int maxEvals; @@ -46,7 +46,7 @@ public class p0ge_ODE implements FirstOrderDifferentialEquations { public static double globalPrecisionThreshold; - public p0ge_ODE(double[] b, Double[] b_ij, double[] d, Double[] s, Double[] M, int dimension, int intervals, double T, Double[] times, p0_ODE P, int maxEvals, Boolean augmented){ + public p0ge_ODE(double[] b, double[] b_ij, double[] d, double[] s, double[] M, int dimension, int intervals, double T, double[] times, p0_ODE P, int maxEvals, Boolean augmented){ this.b = b; @@ -102,7 +102,7 @@ public void computeDerivatives(double t, double[] g, double[] gDot) { } - if (M[0]!=null) {// migration: + if (M!=null) {// migration: gDot[i] += M[l] * g[i]; gDot[i] -= M[l] * g[j]; } @@ -130,7 +130,7 @@ public void computeDerivatives(double t, double[] g, double[] gDot) { } } - if (M[0]!=null) {// migration: + if (M!=null) {// migration: gDot[dimension + i] += M[l] * g[dimension + i]; if (!augmented) gDot[dimension + i] -= M[l] * g[dimension + j]; } @@ -151,7 +151,7 @@ public void computeDerivatives(double t, double[] g, double[] gDot) { * @param rho * @return */ - public double[] getP(double t, double[]P0, double t0, Boolean rhoSampling, Double[] rho){ + public double[] getP(double t, double[] P0, double t0, Boolean rhoSampling, double[] rho){ if (Math.abs(T-t) Date: Wed, 6 Dec 2023 13:47:11 +0100 Subject: [PATCH 4/4] Version bump. --- version.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.xml b/version.xml index 567f748..3c6adf7 100644 --- a/version.xml +++ b/version.xml @@ -1,4 +1,4 @@ - +