Architecture

Abacus is structured so that the public MMM API stays small while the implementation can evolve behind stable seams. The most important rule is that PanelMMM is a facade, not the place where new core behaviour should accumulate.

For the complete module map, read ARCHITECTURE.md in the repository root. This page summarises the parts that matter most when you are deciding where to put new code.

Design Principles

  1. PanelMMM stays thin. Constructor normalisation, data prep, graph construction, prediction, calibration, runtime helpers, and serialisation live under abacus/mmm/models/.
  2. Compute comes before presentation. Diagnostics, summaries, and plotting should consume structured outputs from the model layer rather than embedding analytical logic in presentation code.
  3. Dependencies flow downward. Shared root infrastructure can be imported by MMM modules, but MMM-specific modules should not leak back into the shared layer.
  4. Compatibility is deliberate. If you move imports or rename internals, keep facades or compatibility shims where public usage would otherwise break.

High-Level Package Layers

Layer Purpose Examples
Public facades Stable user-facing entry points abacus.mmm.panel, abacus.mmm.plot, abacus.mmm.summary
Panel implementation seams Core panel behaviour abacus.mmm.models.panel_config, panel_build, panel_predict, panel_runtime, panel_serialize
MMM primitives Reusable modelling building blocks abacus.mmm.components, abacus.mmm.transforms, abacus.mmm.fourier, abacus.mmm.hsgp, abacus.mmm.events
Post-fit outputs Diagnostics, summaries, optimisation, plots abacus.mmm.diagnostics, abacus.mmm.summarization, abacus.mmm.optimization, abacus.mmm.plotting
Shared root Generic infrastructure used across the package abacus.modeling, abacus.prior, abacus.metrics, abacus.data, abacus.pipeline

Where New Code Goes

If you are adding… Put it in…
Constructor normalisation, dims logic, transform configuration abacus/mmm/models/panel_config.py
Data conversion, scaling, Mundlak support, prediction-data prep abacus/mmm/models/panel_data.py
PyMC graph construction abacus/mmm/models/panel_build.py
Posterior predictive or response-curve sampling abacus/mmm/models/panel_predict.py
Serialisation or save/load compatibility abacus/mmm/models/panel_serialize.py and shared helpers in abacus/modeling/io.py
Diagnostics compute abacus/mmm/diagnostics/
Summary tables and exported curve summaries abacus/mmm/summarization/
Static charts abacus/mmm/plotting/
Budget optimisation logic abacus/mmm/optimization/
Adstock or saturation behaviour abacus/mmm/components/ and abacus/mmm/transforms/
Shared model-builder infrastructure abacus/modeling/

Dependency Rules

Allowed

  • Shared root modules can be imported by MMM modules.
  • abacus/mmm/models/ can depend on MMM primitives and shared root modules.
  • Facades such as panel.py can depend on the extracted panel modules.
  • Plotting, summaries, diagnostics, and optimisation can depend on model outputs and extracted helpers.

Avoid

  • Importing panel.py from abacus/mmm/models/*.
  • Adding plotting or summary logic to core model-building modules.
  • Adding MMM-specific behaviour to the shared abacus/modeling/ layer unless it is genuinely reusable.
  • Defaulting to panel.py for new features just because it is visible.

Practical Guidance

When you touch a feature area, check whether there is already an extracted seam for it before adding a new helper. Examples:

  • Plot behaviour should usually land in abacus/mmm/plotting/, not in abacus/mmm/plot.py.
  • Serialisation changes should usually land in abacus/mmm/models/panel_serialize.py, not directly in PanelMMM.
  • Time-varying parameter behaviour should use the HSGP and TVP support modules rather than embedding new logic in plotting or builders.

Before You Merge

  • Confirm the change landed in the correct layer.
  • Keep public facades thin.
  • Preserve public API compatibility unless the change is explicitly breaking.
  • Add or update tests in the matching test area.
  • Run the local verification commands described in Testing.