Skip to content

Add example for sampling tips with unknown location - #26

Draft
sebastianduchene wants to merge 1 commit into
CompEvol:masterfrom
sebastianduchene:tip-sampling-example
Draft

sebastianduchene wants to merge 1 commit into
CompEvol:masterfrom
sebastianduchene:tip-sampling-example

Conversation

@sebastianduchene

Copy link
Copy Markdown

MascotWithTipSampling lets the location of a tip be sampled as part of the MCMC, but it has no example and no documentation, so the setup has to be reverse engineered from the source. This adds one.

What the example is

examples/TipSampling.xml is examples/Constant.xml with two of the 77 Ebola taxa treated as if their location were unknown:

Taxon True location State
20140134|KR653227|Bombali|2014-08-26 Bombali 0
J0156|KP759698|WesternUrban|2014-11-07 WesternUrban 4

The true locations are part of the taxon names, so the sampled states can be scored against the right answer. Both tips are given Kenema as their placeholder and their starting state, so neither starts where it belongs.

The header comment carries the documentation: the four pieces needed, the two things that look like they should mean "unknown" and do not, and the two constraints that come with logging mapped trees.

Things worth knowing, all checked against the code

  • ? in the type trait is taken as a literal deme name. On this file it silently gives 6 demes, 6 Ne parameters and 30 migration rates instead of 5 and 20.
  • Omitting the taxon from the type trait throws a NullPointerException. Dynamics.initAndValidate sorts the trait values to fix the deme order, and the missing taxon contributes a null to that sort.
  • A tipStates id matching no taxon throws IllegalArgumentException: Not all tips that should be sampled found in tree.
  • The deme numbering is the sorted order of the trait values, unless the dynamics types input is set.
  • StructuredTreeLogger cannot log this distribution, since its mascot input takes a Mascot and MascotWithTipSampling is a sibling rather than a subclass. The example uses MappedMascotWithTipSampling with internalNodesOnly="true", which keeps the node count constant so TreeAnnotator can summarise; without it the count varies per tree and TreeAnnotator stops on clade counts. The same distribution must be kept out of the trace logger, where it writes a Newick string into every row.

It does not run yet, and not because of this file

On beast-base 2.8.0-beta5, which master pins, and also on 2.8.0-beta8, the chain dies on the first proposal:

java.lang.IllegalArgumentException: n must be positive
  at beast.base.spec.inference.operator.uniform.IntUniformOperator.proposal(IntUniformOperator.java:62)

IntUniformOperator.proposal draws from nextInt(upper - lower + 1). The lower and upper given in the XML never reach the parameter: in IntVectorParam.initAndValidate the block that would apply them is commented out, so the bounds keep their defaults of Integer.MIN_VALUE + 1 and Integer.MAX_VALUE - 1, and that span overflows to a negative number. Setting lower equal to upper changes nothing, because the inputs are not read at all. IntScalarParam ignores its bounds the same way.

So this is a beast3 matter rather than a MASCOT one, and I am happy to open it there if that is useful. Opened as a draft for that reason.

The same model runs on the BEAST 2 line, where the parameter is an IntegerParameter that honours its bounds. Verified with BEAST 2.7.8 and MASCOT 3.0.7 over four chains: the tip whose location the data determines is recovered from a start two demes away, with posterior support between 0.50 and 0.81 depending on chain length, and TreeAnnotator writes both tips' location posteriors onto the summary tree as typeTrait.set and typeTrait.set.prob. The other tip stays near flat, which is a property of that taxon rather than of the sampler.

🤖 Generated with Claude Code

https://claude.ai/code/session_014cBeW7pSF6vAxXPDwrAzpp

MascotWithTipSampling has no example and no documentation, and the two things
that look like they should express an unknown location both fail quietly or
obscurely: "?" in the type trait becomes a literal extra deme, and omitting the
taxon throws a NullPointerException out of Dynamics.initAndValidate.

This adds examples/TipSampling.xml, built from examples/Constant.xml by treating
two of the 77 Ebola taxa as if their location were unknown. Their true locations
are part of their taxon names, so the sampled states can be scored against the
right answer. The header documents the four pieces needed, the two failure modes
above, and the two constraints that come with logging mapped trees.

The examples directory ignores everything by name, so the new file needs its own
exception line.

Verified on the BEAST 2 line, where the same model runs: BEAST 2.7.8 with MASCOT
3.0.7, four chains, the tip with a well determined location recovered from a
starting state two demes away. On BEAST 3 the example parses but cannot run yet;
the header explains why.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014cBeW7pSF6vAxXPDwrAzpp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant