% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/ild_msm_fit.R
\name{ild_msm_fit}
\alias{ild_msm_fit}
\title{Fit an MSM-style weighted mixed model from an estimand spec}
\usage{
ild_msm_fit(
  estimand,
  data,
  outcome_formula,
  history,
  history_spec = NULL,
  treatment_engine = c("sequential_msm", "pooled"),
  predictors_censor = NULL,
  weights_col = ".ipw",
  stabilize_treat = c("marginal", "prior_treatment", "none"),
  prior_treatment = NULL,
  stabilize_joint = c("mean1", "none"),
  trim = c(0.01, 0.99),
  inference = c("none", "robust", "bootstrap"),
  robust_type = c("CR2", "CR3", "CR0"),
  n_boot = 200L,
  weight_policy = c("fixed_weights", "reestimate_weights"),
  weights_fn = NULL,
  seed = NULL,
  strict_inference = FALSE,
  ...
)
}
\arguments{
\item{estimand}{Object from [ild_msm_estimand()].}

\item{data}{ILD data.}

\item{outcome_formula}{Outcome model formula for [ild_lme()] (typically includes treatment term).}

\item{history}{Predictors for treatment process weights:
one-sided formula (e.g. \code{~ stress_lag1 + trt_lag1}) or character vector.}

\item{history_spec}{Optional [ild_msm_history_spec()] to build lagged history before weighting.}

\item{treatment_engine}{\code{"sequential_msm"} (default) or \code{"pooled"}.}

\item{predictors_censor}{Optional character vector for IPCW model. If supplied, joint weights
are built with [ild_joint_msm_weights()] and stored in \code{weights_col}.}

\item{weights_col}{Column used by [ild_ipw_refit()] (default \code{".ipw"}).}

\item{stabilize_treat}{Treatment-weight stabilization mode. For sequential MSM:
\code{"marginal"}, \code{"prior_treatment"}, \code{"none"}. For pooled IPTW:
mapped to logical \code{stabilize}.}

\item{prior_treatment}{Required when \code{stabilize_treat = "prior_treatment"} in sequential MSM.}

\item{stabilize_joint}{Joint-weight stabilization for [ild_joint_msm_weights()].}

\item{trim}{Quantile trimming applied during weight construction.}

\item{inference}{\code{"none"} (default), \code{"robust"}, or \code{"bootstrap"}.}

\item{robust_type}{Passed to [ild_robust_se()] and [tidy_ild_model()] when \code{inference = "robust"}.}

\item{n_boot}{Passed to [ild_msm_bootstrap()] when \code{inference = "bootstrap"}.}

\item{weight_policy}{Passed to [ild_msm_bootstrap()] when \code{inference = "bootstrap"}.}

\item{weights_fn}{Passed to [ild_msm_bootstrap()] when \code{inference = "bootstrap"} and
\code{weight_policy = "reestimate_weights"}.}

\item{seed}{Optional seed for bootstrap inference.}

\item{strict_inference}{Logical. If \code{TRUE}, stop when requested inference or
regime dispatch cannot be delivered as requested. If \code{FALSE} (default),
degrade with warning and record machine-readable status.}

\item{...}{Passed to [ild_lme()].}
}
\value{
Object of class \code{ild_msm_fit} with elements:
  \code{estimand}, \code{history_spec}, \code{weights_data}, \code{fit}, \code{inference},
  \code{treatment_engine}, \code{weights_col}. Analysis provenance is attached.
}
\description{
High-level runner that takes an [ild_msm_estimand()] plus ILD data, builds
treatment (and optional censoring) weights, refits a weighted \code{lmer},
and optionally computes inference via robust SEs or cluster bootstrap.
}
\details{
v1.1 keeps the v1 workflow and adds explicit capability signaling for
inference/regime paths that are degraded or unsupported.
}
\examples{
set.seed(31)
d <- ild_simulate(n_id = 12, n_obs_per = 6, seed = 31)
d$stress <- rnorm(nrow(d))
d$trt <- as.integer(stats::rbinom(nrow(d), 1L, 0.45))
d <- ild_prepare(d, id = "id", time = "time")
d <- ild_center(d, y)
d <- ild_lag(d, stress, max_gap = Inf)
d <- ild_lag(d, trt, max_gap = Inf)
est <- ild_msm_estimand(treatment = "trt")
res <- ild_msm_fit(
  estimand = est,
  data = d,
  outcome_formula = y ~ y_bp + y_wp + stress + trt + (1 | id),
  history = ~ stress_lag1 + trt_lag1,
  predictors_censor = "stress",
  inference = "none",
  warn_no_ar1 = FALSE,
  warn_uncentered = FALSE
)
res$fit
}
