Bounds should be wide enough that they do not influence the fitted value, except to constrain sign. Covariate coefficients get +/- upperAndLower, except drought-index terms (name matches droughtIndexPattern, e.g. CMD, CMD_sm, cumMDC – lower bound 0, since drought should not increase spread probability) and youngAge (upper bound 0, to prevent self-propagating fires). Every other term, including any other annual covariate, is symmetric. The two remaining logistic parameters get fixed bounds. hillSlope1, the logistic slope, is not among them: it is fixed at 1, not fitted, because it is not identifiable together with the covariate coefficients – with the linear predictor x = covariates %*% beta, hillSlope1 enters the link only as hillSlope1 * x, so scaling every coefficient by k and dividing hillSlope1 by k leaves every prediction unchanged (fireSenseUtils::fixHillSlope1() reinserts it before the objective evaluates par).

estimateSpreadParams(
  fireSense_spreadFormula,
  anyAnnualCovariates,
  whichBound,
  upperAndLower,
  fuelTerms = character(),
  upperAndLowerFuel = upperAndLower,
  upperTailBounds = NULL,
  yearSpreadSDBounds = NULL
)

Arguments

fireSense_spreadFormula

character; the spread formula.

anyAnnualCovariates

list of annual covariate data.tables; kept for call-site compatibility but no longer used – bound sign is now decided by term name, not by annual table membership.

whichBound

"upper" or "lower".

upperAndLower

numeric; absolute bound for covariate coefficients.

upperTailBounds

numeric; if not NULL, the bounds of upperTail1, which is added after inflectionPoint1 (link "logistic3pUpper").

Value

named numeric vector: maxAsymptote, inflectionPoint1, upperTail1 (with upperTailBounds), then formula terms. No hillSlope1 – it is fixed at 1, not fitted.