Full factorial
Every combination of levels. All main effects and all interactions are estimable, and the run count doubles with each factor you add.
doetools builds the design, exports the run sheet your laboratory fills in, fits a model to each response, and maps the region of the domain where every specification holds at once. It runs inside the Python environment you already work in.
Y₁ = 76.90 − 4.84·X₁ − 5.60·X₂ + 1.84·X₁X₂ − 1.71·X₁² − 8.42·X₂²
Face-centred central composite design. Nine runs place the fitted surface within reach of both specifications; the marked point runs the mill at the highest load that still clears them. Data from Leardi, Anal. Chim. Acta 652 (2009) 161-172.
DoE software normally asks you to give up one of the two. We wanted a package that gave up neither, because our students and our clients kept running into the same wall.
doetools covers both halves. MIT licence, one pip install, and a single design object that carries the matrix, the model terms, the measured responses, the fitted models and the diagnostics from the first line of code to the exported PDF.
You create a design object from your factors. Every stage below is a method on that same object, so nothing has to be handed between libraries and nothing drifts out of sync.
Bounds, number of levels, discrete levels, mixture constraints. Each factor class carries what its design type needs.
Optional. Describe the study in five arguments and get back the design families that fit, each with its limits spelled out.
Build the matrix, or import one you already have. Replicates and centre points can be added afterwards.
Choose the effects you want to estimate and see whether the design can estimate them, before anyone spends a week at the bench.
The design leaves as a spreadsheet with the run order, the factor settings and empty response columns. Randomise the order on the way out.
Type the measured values into the same file and read it back. Each run stays tied to its design point.
Ordinary least squares, one model per response, with the coefficients, residuals and tests you need to decide whether to trust them.
Put a limit on each response and doetools shades the part of the domain that satisfies all of them, using the confidence bound instead of the mean prediction.
Below is what each one places in the domain, drawn from the point sets doetools generates. Filled markers are the runs you perform.
Every combination of levels. All main effects and all interactions are estimable, and the run count doubles with each factor you add.
Half the runs, or fewer. Some effects come back confounded with others, which is the price of ranking seven factors in eight experiments.
Edge midpoints and a centre point give a second-order model enough distinct levels to tell curvature apart from a straight line through the corners, and they keep every run off the extreme corners.
Components sum to one, so the domain is a triangle rather than a square. Vertices are pure components, edges are binary blends, and the real formulations sit inside.
When a constraint cuts a corner off the domain, an exchange algorithm keeps the subset of candidate points that maximises the determinant of X'X.
Bring in a design generated elsewhere, or a set of runs already performed, and use the fitting, diagnostic and plotting methods on it.
Choosing the design is where most DoE studies go wrong, and it happens before any data exists. The advisor takes a short description of the study and returns the families that fit, with what each one will and will not give you.
suggestions = suggest_design(
factors=factors, # 5 continuous, 2 levels
phase="screening",
model_order="linear",
max_experiments=10,
constraints=False,
performed_exp=False,
)
Five continuous variables at two levels, nothing run yet, no constraint on the domain, and the aim of ranking the main effects inside a budget of ten runs.
Design: Plackett-Burman Design
Number of runs: 8
Pros:
- Efficient main-effects screening design.
- Supports up to 7 factors in 8 runs.
- Well suited for rapid factor prioritization.
Cons:
- Does not estimate interaction effects.
- Main-effect estimates can be biased if
interactions or curvature are relevant.
Note:
- Confirm the top factors with a
higher-resolution design.
Each notebook takes a case study from the literature through the whole workflow, with the code, the measured responses and the graphics.
Two process variables, two responses pulling in opposite directions, and a feasible region drawn from the confidence bound rather than the mean, so the answer survives experimental error.
Open the notebook → MixtureThree ligands in a simplex centroid design, a special cubic Scheffé model, and the compositions where breaking load and dissolution rate both clear 50. Only ternary blends do.
Open the notebook → D-optimalTemperature, humidity and a categorical batch factor. A constraint removes 24 of the 156 candidate points, and 13 runs turn out to carry the most information per experiment.
Open the notebook →Ten more, including D-optimal augmentation and constrained mixture designs, are in the example gallery →
Pure Python, so it installs the same way on Windows, macOS and Linux, inside whichever environment you already use.
python -m pip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
doetools
doetools sits on TestPyPI while the first public release is finalised. The extra index lets pip pull NumPy, SciPy and the rest of the dependencies from PyPI as usual.
Or work from sourcegit clone https://github.com/LorenzoTJ/doetools.git
cd doetools
uv venv .venv
uv sync --all-extras
# the design behind the plot at the top of this page
from doetools import ContinuousFactor as CF
from doetools import CentralCompositeDesign as CCD
factors = {
"Load": CF(n_levels=3, lower_bound=5, upper_bound=15),
"Classifier": CF(n_levels=3, lower_bound=1, upper_bound=3),
}
design = CCD(factors=factors, center_points=1, design="ccf")
design.export_experiments(
responses=["Y1", "Y2"],
randomize=True,
save_path="ccd_design.xlsx",
)
# run the 9 experiments, fill in the sheet, then
design.import_responses(file_path="ccd_responses.xlsx")
design.set_response_conditions(
lower_limits=[70, None],
upper_limits=[None, 1],
maximize=[True, False],
)
Source and issue tracker: github.com/LorenzoTJ/doetools →
Installation, quick start, the API for every design class and workflow method, the mathematical background, and the full example gallery.
If doetools contributes to published work, cite the software and the exact version you used. GitHub generates the metadata from the repository's CITATION.cff.
doetools was presented at ANALITICA 2026, XXXII Congresso Nazionale della Divisione di Chimica Analitica, Venezia Mestre, 7 September 2026.
doetools is free for everyone, and its public development follows what is useful to the whole community. When a study needs more than the library, DataBloom works alongside the laboratory: planning the campaign, adapting the analysis to the process, and training the people who will run it after we leave.
doetools is at 0.1.x and under active development. Bug reports, feature requests and teaching feedback all shape what goes into the next release.
For bugs and feature requests that can be discussed in the open, tracked, and closed against a release.
Open an issueFor questions about applying doetools to a specific study, collaborations, and training or teaching material.
info@databloom.itReleased under the MIT Licence. Backward compatibility is not guaranteed until 1.0, and statistical output should be read together with the experimental context and the model assumptions.