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
PanelMMMstays thin. Constructor normalisation, data prep, graph construction, prediction, calibration, runtime helpers, and serialisation live underabacus/mmm/models/.- Compute comes before presentation. Diagnostics, summaries, and plotting should consume structured outputs from the model layer rather than embedding analytical logic in presentation code.
- Dependencies flow downward. Shared root infrastructure can be imported by MMM modules, but MMM-specific modules should not leak back into the shared layer.
- 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.pycan depend on the extracted panel modules. - Plotting, summaries, diagnostics, and optimisation can depend on model outputs and extracted helpers.
Avoid
- Importing
panel.pyfromabacus/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.pyfor 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 inabacus/mmm/plot.py. - Serialisation changes should usually land in
abacus/mmm/models/panel_serialize.py, not directly inPanelMMM. - 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.