% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/api-simulation-spec.R
\name{build_mfrm_sim_spec}
\alias{build_mfrm_sim_spec}
\title{Build an explicit simulation specification for MFRM design studies}
\usage{
build_mfrm_sim_spec(
  n_person = 50,
  n_rater = 4,
  n_criterion = 4,
  raters_per_person = n_rater,
  design = NULL,
  score_levels = 4,
  theta_sd = 1,
  rater_sd = 0.35,
  criterion_sd = 0.25,
  noise_sd = 0,
  step_span = 1.4,
  thresholds = NULL,
  model = c("RSM", "PCM", "GPCM"),
  step_facet = NULL,
  slope_facet = NULL,
  slopes = NULL,
  facet_names = NULL,
  assignment = c("crossed", "rotating", "sparse_linked", "resampled", "skeleton"),
  latent_distribution = c("normal", "empirical"),
  empirical_person = NULL,
  empirical_rater = NULL,
  empirical_criterion = NULL,
  assignment_profiles = NULL,
  design_skeleton = NULL,
  sparse_controls = NULL,
  group_levels = NULL,
  dif_effects = NULL,
  interaction_effects = NULL,
  population_formula = NULL,
  population_coefficients = NULL,
  population_sigma2 = NULL,
  population_covariates = NULL
)
}
\arguments{
\item{n_person}{Number of persons/respondents to generate.}

\item{n_rater}{Number of rater facet levels to generate.}

\item{n_criterion}{Number of criterion/item facet levels to generate.}

\item{raters_per_person}{Number of raters assigned to each person.}

\item{design}{Optional named design override supplied as a named list,
named vector, or one-row data frame. Names may use canonical variables
(\code{n_person}, \code{n_rater}, \code{n_criterion}, \code{raters_per_person}), current
public aliases implied by \code{facet_names} (for example \code{n_judge},
\code{n_task}, \code{judge_per_person}), or role keywords (\code{person}, \code{rater},
\code{criterion}, \code{assignment}). The schema-only future branch input
\code{design$facets = c(person = ..., judge = ..., task = ...)} is also
accepted for the currently exposed facet keys. Do not specify the same
variable through both \code{design} and the scalar count arguments.}

\item{score_levels}{Number of ordered score categories.}

\item{theta_sd}{Standard deviation of simulated person measures.}

\item{rater_sd}{Standard deviation of simulated rater severities.}

\item{criterion_sd}{Standard deviation of simulated criterion difficulties.}

\item{noise_sd}{Optional observation-level noise added to the linear predictor.}

\item{step_span}{Spread used to generate equally spaced thresholds when
\code{thresholds = NULL}.}

\item{thresholds}{Optional threshold specification. Use a numeric vector of
common thresholds; a named list such as \code{list(C01 = c(-1, 0, 1))}; a
numeric matrix with one row per \code{StepFacet} and one column per step; or a
long data frame with columns \code{StepFacet}, \code{Step}/\code{StepIndex}, and
\code{Estimate}.}

\item{model}{Measurement model recorded in the simulation specification.}

\item{step_facet}{Step facet used when \code{model = "PCM"} and threshold values
vary across levels.}

\item{slope_facet}{Slope facet used when \code{model = "GPCM"}. The current
bounded \code{GPCM} branch requires \code{slope_facet == step_facet}.}

\item{slopes}{Optional slope specification for \code{model = "GPCM"}. Use either
a numeric vector aligned to the generated slope-facet levels or a data
frame with columns \code{SlopeFacet} and \code{Estimate}. Supplied slopes are treated
as relative discriminations and normalized to the package's geometric-mean-
one identification convention on the log scale. When omitted, slopes
default to 1 for every slope-facet level, giving an exact \code{PCM}
reduction. The \code{GPCM} model form follows Muraki's generalized partial
credit model; the package's slope-regime labels are validation stress
labels, not published psychometric cut points.}

\item{facet_names}{Optional public names for the two simulated non-person
facet columns. Supply either an unnamed character vector of length 2
in rater-like / criterion-like order, or a named vector with names
\code{c("rater", "criterion")}.}

\item{assignment}{Assignment design. \code{"crossed"} means every person sees
every rater; \code{"rotating"} uses a balanced rotating subset;
\code{"sparse_linked"} uses an incomplete rating design with optional linking
persons; \code{"resampled"} reuses empirical person-level rater-assignment
profiles; \code{"skeleton"} reuses an observed person-by-facet design skeleton.}

\item{latent_distribution}{Latent-value generator. \code{"normal"} samples from
centered normal distributions using the supplied standard deviations.
\code{"empirical"} resamples centered support values from
\code{empirical_person}/\code{empirical_rater}/\code{empirical_criterion}.}

\item{empirical_person}{Optional numeric support values used when
\code{latent_distribution = "empirical"}.}

\item{empirical_rater}{Optional numeric support values used when
\code{latent_distribution = "empirical"}.}

\item{empirical_criterion}{Optional numeric support values used when
\code{latent_distribution = "empirical"}.}

\item{assignment_profiles}{Optional data frame with columns
\code{TemplatePerson} and the public rater-like facet column (optionally
\code{Group}) describing empirical person-level rater-assignment profiles used
when \code{assignment = "resampled"}. The canonical name \code{Rater} is also
accepted.}

\item{design_skeleton}{Optional data frame with columns \code{TemplatePerson},
the public rater-like facet column, and the public criterion-like facet
column (optionally \code{Group}, \code{Weight}, and \code{TemplatePersonReuse})
describing an observed response skeleton used when
\code{assignment = "skeleton"}. The canonical names \code{Rater} and \code{Criterion}
are also accepted. \code{TemplatePersonReuse = TRUE} asks
\code{\link[=simulate_mfrm_data]{simulate_mfrm_data()}} to keep the template-person order instead of
resampling templates, which is used by \code{\link[=build_peer_review_sim_spec]{build_peer_review_sim_spec()}}.}

\item{sparse_controls}{Optional named list used when
\code{assignment = "sparse_linked"}. Supported entries are \code{link_fraction}
(default \code{0.1}), \code{link_persons} (overrides \code{link_fraction}),
\code{link_raters_per_person} (default \code{n_rater}), \code{assignment_mode}
(\code{"balanced"} or \code{"random"}), and
\code{min_common_persons_per_rater_pair} (diagnostic target, default \code{1}).}

\item{group_levels}{Optional character vector of group labels.}

\item{dif_effects}{Optional data frame of true group-linked DIF effects.}

\item{interaction_effects}{Optional data frame of true interaction effects.}

\item{population_formula}{Optional one-sided formula describing a
person-level latent-regression population model used when generating
person measures, for example \code{~ X + G}. When supplied, person measures are
generated from \code{X \%*\% beta + e} rather than from \code{N(0, theta_sd^2)}.}

\item{population_coefficients}{Optional numeric vector of latent-regression
coefficients corresponding to the design matrix implied by
\code{population_formula}.}

\item{population_sigma2}{Optional residual variance for the latent-regression
person distribution.}

\item{population_covariates}{Optional template data frame containing one row
per template person and the background variables referenced by
\code{population_formula}. Numeric/logical and categorical factor/character
variables are expanded through the same \code{stats::model.matrix()} contract
used by latent-regression fitting. During simulation, template rows are
resampled to the requested \code{n_person}.}
}
\value{
An object of class \code{mfrm_sim_spec}.
}
\description{
Build an explicit simulation specification for MFRM design studies
}
\details{
\code{build_mfrm_sim_spec()} creates an explicit, portable simulation
specification that can be passed to \code{\link[=simulate_mfrm_data]{simulate_mfrm_data()}}. The goal is to
make the data-generating mechanism inspectable and reusable rather than
relying only on ad hoc scalar arguments.

The resulting object records:
\itemize{
\item design counts (\code{n_person}, \code{n_rater}, \code{n_criterion}, \code{raters_per_person})
\item latent spread assumptions (\code{theta_sd}, \code{rater_sd}, \code{criterion_sd})
\item optional empirical latent support values for semi-parametric simulation
\item threshold structure (\code{threshold_table})
\item optional discrimination structure for bounded \code{GPCM} (\code{slope_table}) and
its identified log-slope spread label (\code{slope_regime})
\item assignment design (\code{assignment})
\item optional sparse linked-design controls (\code{sparse_controls}) when
\code{assignment = "sparse_linked"}
\item optional empirical assignment profiles (\code{assignment_profiles}) with
optional person-level \code{Group} labels
\item optional observed response skeleton (\code{design_skeleton})
with optional person-level \code{Group} labels and observation-level \code{Weight}
values
\item optional person-level latent-regression population metadata including
\code{population_formula}, \code{population_coefficients}, \code{population_sigma2}, and
a reusable template of person-level covariates, including model-matrix
xlevel/contrast provenance for categorical covariates
\item \code{planning_scope}, an explicit record that the current planning/forecasting
helpers target the role-based person x rater-like x criterion-like
design contract rather than a fully arbitrary-facet planner
\item \code{planning_constraints}, an explicit record of which design variables can
currently be changed from that specification without rebuilding it
\item \code{planning_schema}, a combined schema contract bundling the role descriptor,
scope boundary, current mutability map, a \code{facet_manifest}, a
schema-only \code{future_facet_table}, and a matching
\code{future_design_template}, plus a nested \code{future_branch_schema} scaffold
for a future arbitrary-facet planning branch
\item the current \code{design$facets(...)} parser now normalizes nested facet-count
input through that bundled \code{future_branch_schema}, whose nested
\code{design_schema} is now the authoritative schema-only branch object
\item optional signal tables for DIF and interaction bias
}

The current generator targets the package's standard person x rater x
criterion workflow, but the public output names for those two facet roles
can now be customized with \code{facet_names}. This naming layer improves public
ergonomics; it does not yet turn the generator into a fully arbitrary-facet
simulator. Internally, helper objects keep canonical role mappings so that
planning functions can treat the first non-person facet as rater-like and
the second as criterion-like. When threshold values are provided by
\code{StepFacet}, the supported step facets are the generated levels of the
chosen public rater-like or criterion-like column. For convenience,
step-facet-specific thresholds can be supplied as a named list or as a
numeric matrix whose row names are \code{StepFacet} labels.
When \code{model = "GPCM"}, the same public facet naming rules apply to the
slope table; the current bounded branch keeps \code{slope_facet} equal to
\code{step_facet}.
The \code{slope_regime} field summarizes the centered log-slope spread so
recovery simulations can be read against the intended generator stress
level. Its labels (\code{unit_slopes}, \code{near_flat}, \code{moderate}, and
\code{high_dispersion}) are package validation labels; they are not model-fit
decisions and should not be interpreted as literature-derived adequacy
thresholds. The GPCM data-generating form follows Muraki (1992,
doi:10.1177/014662169201600206), while information-function interpretation
follows Muraki (1993, doi:10.1177/014662169301700403). The explicit
simulation-specification metadata is intended to support ADEMP-style
simulation reporting as described by Morris, White, and Crowther (2019,
doi:10.1002/sim.8086).

The \code{assignment = "sparse_linked"} branch follows sparse
rater-mediated assessment work in treating incomplete rater assignment as
planned missingness rather than incidental nonresponse. Its \code{link_persons}
and \code{link_raters_per_person} controls emulate a common linking set so users
can inspect rater-pair common-person counts before using the generated data
in recovery or design studies. This is a design generator and diagnostic
metadata layer; it does not impose a universal minimum-linking cutoff.
Sparse-design motivation follows Wind, Jones, and Grajeda (2023,
doi:10.1177/01466216231182148), Wind and Jones (2018,
doi:10.1177/0013164417703733), and DeMars, Shapovalov, and Hathcoat
(2023).

If \code{population_formula} is supplied, the simulation specification carries a
first-version person-level latent-regression generator. This affects only the
person distribution. The current implementation keeps the non-person facets
in the existing many-facet Rasch generator and resamples rows from
\code{population_covariates} to the requested design size before computing
\eqn{\theta_n = x_n^\top \beta + \varepsilon_n} with
\eqn{\varepsilon_n \sim N(0, \sigma^2)}.
}
\section{Interpreting output}{

This object does not contain simulated data. It is a data-generating
specification that tells \code{\link[=simulate_mfrm_data]{simulate_mfrm_data()}} how to generate them.
}

\examples{
\donttest{
spec <- build_mfrm_sim_spec(
  design = list(person = 8, rater = 2, criterion = 2, assignment = 1),
  assignment = "rotating"
)
spec$model
spec$assignment
nrow(spec$threshold_table)
}
}
\seealso{
\code{\link[=extract_mfrm_sim_spec]{extract_mfrm_sim_spec()}}, \code{\link[=simulate_mfrm_data]{simulate_mfrm_data()}}
}
