setPredKernel(reset = TRUE) leaves a stale explicit kernel in the slot, corrupting getTrophicLevel()
Two different tests are used to answer the same question, "is the predation kernel stored explicitly?":
!is.null(comment(params@pred_kernel)) — R/project_methods.R:311, :667, R/summary_methods.R:175, R/diffusion.R:140
length(dim(params@pred_kernel)) > 1 — encounter_kernel(), R/setPredKernel.R:419
reset = TRUE clears the comment (R/setPredKernel.R:148) and recomputes the ft_pred_kernel_* arrays, but never shrinks params@pred_kernel back. After a thaw the two tests therefore disagree: the rate functions take the FFT path with the freshly computed kernel, while encounter_kernel() still returns the stale explicit array.
getTrophicLevel() uses both. Its numerator is a trophic-level-weighted copy of the encounter integral built from encounter_kernel(), and its denominator is the consumption from getEncounter(). The comment at R/summary_methods.R:378 states the requirement explicitly: the ratio is only a trophic level if the two use the same quadrature. After a reset they do not.
library(mizer)
p <- NS_params
p3 <- setPredKernel(setPredKernel(p, pred_kernel = pred_kernel(p) * 2),
reset = TRUE)
getTrophicLevel(p3)[1, 1] #> 4.503
getTrophicLevel(p)[1, 1] #> 2.752
max(abs(getTrophicLevel(p3) - getTrophicLevel(p))) #> 24.6
getEncounter(p3) is numerically identical to getEncounter(p), so the model itself is fine — it is the reported trophic levels that are wrong, silently. pred_kernel(p3) also still returns the discarded doubled kernel, i.e. the accessor reports a kernel the model is not using.
Suggested fix
Give the question one answer. Either have reset = TRUE shrink params@pred_kernel back to its placeholder so dim and comment cannot disagree, or route all five sites through a single internal predicate. The first is cheaper and also fixes the accessor.
Related to #505: the same attribute is serving as both the freeze flag and the runtime dispatch key, which is why a second discriminator appeared in the first place.
setPredKernel(reset = TRUE)leaves a stale explicit kernel in the slot, corruptinggetTrophicLevel()Two different tests are used to answer the same question, "is the predation kernel stored explicitly?":
!is.null(comment(params@pred_kernel))—R/project_methods.R:311,:667,R/summary_methods.R:175,R/diffusion.R:140length(dim(params@pred_kernel)) > 1—encounter_kernel(),R/setPredKernel.R:419reset = TRUEclears the comment (R/setPredKernel.R:148) and recomputes theft_pred_kernel_*arrays, but never shrinksparams@pred_kernelback. After a thaw the two tests therefore disagree: the rate functions take the FFT path with the freshly computed kernel, whileencounter_kernel()still returns the stale explicit array.getTrophicLevel()uses both. Its numerator is a trophic-level-weighted copy of the encounter integral built fromencounter_kernel(), and its denominator is the consumption fromgetEncounter(). The comment atR/summary_methods.R:378states the requirement explicitly: the ratio is only a trophic level if the two use the same quadrature. After a reset they do not.getEncounter(p3)is numerically identical togetEncounter(p), so the model itself is fine — it is the reported trophic levels that are wrong, silently.pred_kernel(p3)also still returns the discarded doubled kernel, i.e. the accessor reports a kernel the model is not using.Suggested fix
Give the question one answer. Either have
reset = TRUEshrinkparams@pred_kernelback to its placeholder sodimandcommentcannot disagree, or route all five sites through a single internal predicate. The first is cheaper and also fixes the accessor.Related to #505: the same attribute is serving as both the freeze flag and the runtime dispatch key, which is why a second discriminator appeared in the first place.