Make spec RandomTree recognise spec MRCAPrior constraints - #121
Merged
Conversation
beast.base.spec.evolution.tree.coalescent.RandomTree still imported the legacy beast.base.evolution.tree.MRCAPrior. Since the spec MRCAPrior extends Distribution directly rather than subclassing the legacy class, the `instanceof MRCAPrior` scan over the tree's outputs never matched, so monophyletic constraints were silently dropped when initialising the starting tree. Any calibrated analysis then starts from a random tree that violates its own monophyly constraints, giving -Infinity/NaN clade priors and "Could not find a proper state to initialise". This affects every calibrated analysis produced by BEAUti, whose Standard.xml template pairs spec RandomTree with spec MRCAPrior. Switch the import, calibrationsInput and the distributions list to the spec MRCAPrior / ScalarDistribution types. ScalarDistribution returns a boxed value from inverseCumulativeProbability, so unbox explicitly when computing the calibration bounds.
alexeid
force-pushed
the
fix/spec-randomtree-mrcaprior
branch
from
July 23, 2026 21:05
c801678 to
28c76bf
Compare
LoggerTest.testFileLog failed or passed depending purely on where surefire happened to schedule it. Three JVM-wide globals are set by the integration tests and never restored: - file.name.prefix (XMLPathUtil.setUpOutputDir) - Logger.FILE_MODE (ExampleXmlParsingTest, ResumeTest, ...) - Logger.sampleOffset (ResumeTest, via the resume path) If LoggerTest runs after them, openLogFile() prepends the stale prefix and writes to <prefix>beast.log while the test resolves "beast.log" against the working directory, so the existence check fails; and the stale sampleOffset is added to every logged sample, so the round-tripped sample number is off by the leaked offset. Reset all three in setUp(). sampleOffset is protected static and so is not reachable from this package directly, but a subclass inherits it regardless of package. Verified by forcing the ordering: with -Dsurefire.runOrder=reversealphabetical over ExampleXmlParsingTest, ResumeTest and LoggerTest, testFileLog failed on a clean tree before this change and passes after it, as it does under alphabetical and filesystem ordering.
alexeid
added a commit
to BEAST2-Dev/bModelTest
that referenced
this pull request
Jul 23, 2026
beta7 is the first release containing the spec RandomTree fix (CompEvol/beast3#121), so the example XMLs no longer need a locally built SNAPSHOT and Maven Central will accept the release. Verified against the artifacts as published: 31/31 tests pass and all three example XMLs start at a finite likelihood and sample. version.xml already declares atleast='2.8.0', which matches the BEAST package version beast3 ships, so it needs no change -- the Maven artifact version and the BEAST package version are separate axes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
beast.base.spec.evolution.tree.coalescent.RandomTreestill imported the legacybeast.base.evolution.tree.MRCAPrior. The specMRCAPriorextendsDistributiondirectly rather than subclassing the legacy class, so theinstanceof MRCAPriorscan over the tree's outputs never matched and monophyletic constraints were silently dropped when initialising the starting tree.Any calibrated analysis then starts from a random tree that violates its own monophyly constraints:
Reproduced on seeds 1, 7, 42 and 12345 — it is not seed-dependent.
There was no XML-level workaround:
calibrationsInputwas typed to the legacy class too, so an explicit<constraint idref="..."/>would fail type-checking, and legacyMRCAPrior.distInputrequires aParametricDistributionwhile spec priors areScalarDistribution— incompatible hierarchies.Impact
This is not limited to one package.
beast-fx/src/main/resources/beast.fx/fxtemplates/Standard.xmlpairs specRandomTreewith specMRCAPrior, so every calibrated analysis produced by BEAUti under BEAST 3 is affected.Fix
Switch the import,
calibrationsInputand thedistributionslist to the specMRCAPrior/ScalarDistributiontypes.ScalarDistribution.inverseCumulativeProbabilityreturns a boxed value, so it is unboxed explicitly when computing the calibration bounds.The legacy
beast.base.evolution.tree.coalescent.RandomTreeis untouched, so legacy XMLs keep working through the legacy class. No other caller passes MRCAPriors into the spec class —RandomTreeTestconstructs one without constraints andRandomGeneTreedoes not touch the constraint machinery.Verification
examples/beast2-paper.xml(7 monophyletic clade calibrations), which failed to initialise on every seed before this change and now starts at a finite likelihood and samples normally:Second commit:
LoggerTestisolationCI on this branch went red on
LoggerTest.testFileLog, which is unrelated to the change above — it fails or passes purely on where surefire schedules it relative to the integration tests. Three JVM-wide globals are set by those tests and never restored:file.name.prefix(XMLPathUtil.setUpOutputDir),Logger.FILE_MODE, andLogger.sampleOffset(ResumeTest).Run ordering is not stable between CI runs, which is why master has been green:
LoggerTest2971466383130044812322When
LoggerTestruns second,openLogFile()prepends the stale prefix and writes to<prefix>beast.logwhile the test resolvesbeast.logagainst the working directory, so the existence check fails; and the stalesampleOffsetis added to every logged sample, so the round-tripped sample number is off by the leaked offset.Fixed by resetting all three in
setUp(). Verified by forcing the ordering — with-Dsurefire.runOrder=reversealphabeticaloverExampleXmlParsingTest,ResumeTestandLoggerTest,testFileLogfails on a clean tree before the change and passes after it, as it does underalphabeticalandfilesystemordering. Fullbeast-basesuite: 458 tests, 0 failures.