process-improve 2.2.0__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {process_improve-2.2.0 → process_improve-2.3.0}/PKG-INFO +1 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/pyproject.toml +90 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/pyproject.toml.orig +90 -2
- process_improve-2.3.0/src/process_improve/_tool_registry.py +205 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/control.py +78 -49
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/datasets.py +2 -3
- process_improve-2.3.0/src/process_improve/datasets/experiments/biscuit/NOTICE +38 -0
- process_improve-2.3.0/src/process_improve/datasets/experiments/biscuit/biscuit.csv +73 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/box-draper-2007.json +26 -11
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/box-hunter-hunter-1978.json +250 -52
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/davies-1956.json +255 -55
- process_improve-2.3.0/src/process_improve/datasets/experiments/reference_catalogue/mcmullen-jurica-2024.json +2578 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/pid-book.json +6 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/__init__.py +9 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/_shared.py +23 -0
- process_improve-2.3.0/src/process_improve/experiments/_analyses/diagnostics.py +202 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/glm.py +4 -3
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/lack_of_fit.py +45 -18
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/mixture.py +26 -11
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_finite_fields.py +65 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_lm.py +241 -21
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/analyze_experiment.py +11 -4
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/fit_linear_model.py +1 -4
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/recommend_next_step.py +1 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/run_sheet.py +36 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_uniform_sampling.py +3 -5
- process_improve-2.3.0/src/process_improve/experiments/across_blocks.py +352 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/analysis.py +341 -58
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/augment.py +48 -23
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/compare.py +12 -4
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/datasets.py +42 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_mixture_constrained.py +3 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_mixture_process.py +1 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_response_surface.py +1 -6
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_screening.py +15 -6
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_split_plot.py +26 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_supersaturated.py +15 -17
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/evaluate.py +58 -12
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/layouts.py +2 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/next_step.py +161 -50
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/optimal.py +2 -7
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/optimization.py +13 -8
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/random_effects.py +10 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/reference_catalogue.py +151 -75
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/region.py +6 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/separating.py +3 -1
- process_improve-2.3.0/src/process_improve/experiments/surface_checks.py +416 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/trade_off.py +7 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/api.py +3 -1
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/significance.py +78 -3
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/yates.py +25 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/monitoring/control_charts.py +61 -49
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/monitoring/metrics.py +7 -5
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/__init__.py +10 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_adaptive.py +322 -323
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_asca.py +79 -51
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_categorical.py +74 -60
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_common.py +30 -33
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_cv_criteria.py +126 -143
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_diagnostics.py +136 -72
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_impute.py +13 -8
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_limits.py +13 -8
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_mbpca.py +76 -76
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_mbpls.py +169 -174
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_nipals.py +36 -32
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_null.py +24 -20
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_opls.py +60 -49
- process_improve-2.3.0/src/process_improve/multivariate/_optimal_inversion.py +1505 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_pca.py +340 -422
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_pls.py +443 -595
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_plsda.py +125 -61
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_preprocessing.py +38 -136
- process_improve-2.3.0/src/process_improve/multivariate/_prm.py +404 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_procrustes.py +68 -63
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_projection.py +8 -8
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_resampling.py +15 -25
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_tpls.py +339 -405
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/methods.py +14 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/plots.py +14 -9
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/tools.py +30 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/_robust_regression.py +195 -75
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/_variance_components.py +54 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/tools.py +17 -4
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/ingest.py +19 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/tools.py +1 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/batch.py +17 -11
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/recipes.py +4 -2
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/tools.py +6 -4
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/tool_spec.py +6 -190
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/types.py +1 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/tools.py +3 -2
- process_improve-2.2.0/src/process_improve/experiments/_analyses/diagnostics.py +0 -102
- process_improve-2.2.0/src/process_improve/experiments/surface_checks.py +0 -180
- process_improve-2.2.0/src/process_improve/multivariate/_prm.py +0 -390
- {process_improve-2.2.0 → process_improve-2.3.0}/README.md +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/_extras.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/_linalg.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/_random.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/_remote_data.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_batch_monitor.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_batch_pca.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_batch_plots.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_batch_pls.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_common.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_gaps.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/_online.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/alignment_helpers.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/data_input.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/features.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/plotting.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/preprocessing.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/batch/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/bivariate/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/bivariate/_elbow_peak.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/bivariate/methods.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/bivariate/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/chemistry/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/chemistry/preprocessing.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/config.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/batch/batch-fake-data.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/batch/details.txt +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/batch/dryer.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/batch/nylon.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/boilingpot.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/corrosion.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/golf.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/pollutant.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/NOTICE.md +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/anderson-whitcomb-2007.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/derringer-suich-1980.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/efi-mooc-quizzes.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/fries-hunter-1980.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/goos-2025.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/goos-jones-2011.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/jones-nachtsheim-2011.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/jones-nachtsheim-2013.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/lenth-1989.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/montgomery-2013.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/nair-ffd-tutorial-2004.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/nist-ehandbook-ch5.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/nunez-ares-et-al-2023.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/nunez-ares-goos-2019.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/nunez-ares-goos-2020.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/schmidt-launsby-2000.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/topics.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/reference_catalogue/ullmann-doe-2012.json +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/solar.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/experiments/test_doe1.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/monitoring/batch-yield-and-purity.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/monitoring/rubber-colour.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/C.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/Hotellings_T2_A3.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/Hotellings_T2_A6.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/LDPE.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/P.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/R.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/T.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/U.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/W.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/LDPE/Yhat_A6.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/cheddar-cheese.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/NOTICE +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/extraction1.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/extraction2.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/extraction3.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/ftir1.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/ftir2.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/dtu-pectin/ftir3.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/kamyr.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/solvents.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tablet-spectra.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/SOURCE +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group1.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group2.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group3.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group4.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/formulas_Group5.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/process_conditions.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group1.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group2.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group3.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group4.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/properties_Group5.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/datasets/multivariate/tpls-pyphi/quality_indicators.csv +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/aliasing.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/box_cox.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/curvature.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/lenth.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/model_selection.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/ols_extractors.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/prediction.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/split_plot.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_analyses/transforms.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_blocking.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_classical.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_desirability.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_expression_text.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_moment_aberration.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_orthogonal_arrays.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_region_geometry.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_region_quadrature.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_rules.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/analyze_omars.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/augment_design.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/compare_designs.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/create_factorial_design.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/doe_knowledge.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/evaluate_design.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/generate_design.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/optimize_responses.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/recommend_strategy.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/search_design_catalog.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/simulate_design_performance.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/trade_off_table.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/_tools/visualize_doe.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/allocation.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/benchmark.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/crossed_arrays.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/design_catalog.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/design_measures.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_constrained.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_covariates.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_factorial.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_mixture.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_omars.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_omars_ilp.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_optimal.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_space_filling.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_three_level.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/designs_utils.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/factor.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/gaussian_process.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/incomplete_blocks.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/api.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/data/concepts.yaml +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/data/decision_rules.yaml +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/data/design_types.yaml +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/data/diagnostics.yaml +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/engine.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/knowledge/models.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/least_squares_means.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/marginal_means.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/model_comparison.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/models.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/multistratum.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/omars.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/omars_trade_off.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/projections.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/pseudocomponents.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/run_order.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/run_sheet.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/sequential.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/simulate.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/simulations.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/strategy/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/strategy/budget.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/strategy/domain_templates.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/strategy/engine.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/strategy/models.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/structures.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/three_level_components.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/true_process.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/variance_dispersion.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/cube_plot.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/design_quality.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/diagnostics.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/effects.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/optimization_plots.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/registry.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/square_plot.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/experiments/visualization/plots/surfaces.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/interactions.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/mcp_server.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/monitoring/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/monitoring/evop.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/monitoring/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_base.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_pca_pls.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/multivariate/_robust.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/py.typed +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/recipes.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/box_tidwell.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/methods.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/regression/nonlinear.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/analysis.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/designed.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/diagnostics.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/mam.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/panel.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/recipes.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/sensory/validation.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/context.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/latent.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/simulation/model.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/tool_safety.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/classical.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/error_transmission.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/metrics.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/reference_distribution.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/serial_correlation.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/stated_values.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/univariate/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/adapters/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/adapters/base.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/adapters/echarts_adapter.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/adapters/plotly_adapter.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/charts/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/charts/boxplot.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/colors.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/raincloud.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/spec.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/themes.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/visualization/tools.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/__init__.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/_expressions.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/project.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/recipe.py +0 -0
- {process_improve-2.2.0 → process_improve-2.3.0}/src/process_improve/workbench/variant.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: process-improve
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis.
|
|
5
5
|
Keywords: Designed Experiments,Design of Experiments,DoE,Optimal Design,Response Surface,Latent Variables,PCA,PLS,Multivariate Data Analysis,Chemometrics,Process Monitoring,Batch data analysis
|
|
6
6
|
Author: Kevin Dunn
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "process-improve"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.0"
|
|
4
4
|
description = "Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -107,7 +107,7 @@ dev = [
|
|
|
107
107
|
"pytest-cov>=7.0.0",
|
|
108
108
|
"pytest-xdist>=3.8.0",
|
|
109
109
|
"pydata-sphinx-theme>=0.16.1",
|
|
110
|
-
"ruff>=0.11.0,<0.
|
|
110
|
+
"ruff>=0.11.0,<0.18",
|
|
111
111
|
"sphinx>=8.1.3",
|
|
112
112
|
"nbsphinx>=0.9.5",
|
|
113
113
|
"ipykernel>=6.29",
|
|
@@ -301,3 +301,91 @@ known-third-party = [
|
|
|
301
301
|
"pytest",
|
|
302
302
|
"pandas",
|
|
303
303
|
]
|
|
304
|
+
|
|
305
|
+
[tool.mutmut]
|
|
306
|
+
source_paths = ["src"]
|
|
307
|
+
only_mutate = [
|
|
308
|
+
"src/process_improve/multivariate/_limits.py",
|
|
309
|
+
"src/process_improve/monitoring/metrics.py",
|
|
310
|
+
"src/process_improve/monitoring/evop.py",
|
|
311
|
+
"src/process_improve/monitoring/control_charts.py",
|
|
312
|
+
"src/process_improve/multivariate/_nipals.py",
|
|
313
|
+
"src/process_improve/multivariate/_preprocessing.py",
|
|
314
|
+
"src/process_improve/multivariate/_projection.py",
|
|
315
|
+
"src/process_improve/multivariate/_impute.py",
|
|
316
|
+
"src/process_improve/multivariate/_robust.py",
|
|
317
|
+
"src/process_improve/multivariate/_diagnostics.py",
|
|
318
|
+
"src/process_improve/multivariate/_resampling.py",
|
|
319
|
+
"src/process_improve/multivariate/_null.py",
|
|
320
|
+
"src/process_improve/multivariate/_procrustes.py",
|
|
321
|
+
"src/process_improve/multivariate/_prm.py",
|
|
322
|
+
"src/process_improve/multivariate/_opls.py",
|
|
323
|
+
"src/process_improve/multivariate/_pca.py",
|
|
324
|
+
"src/process_improve/multivariate/_pls.py",
|
|
325
|
+
"src/process_improve/multivariate/_mbpca.py",
|
|
326
|
+
"src/process_improve/multivariate/_mbpls.py",
|
|
327
|
+
"src/process_improve/multivariate/_tpls.py",
|
|
328
|
+
"src/process_improve/multivariate/_cv_criteria.py",
|
|
329
|
+
"src/process_improve/multivariate/_plsda.py",
|
|
330
|
+
"src/process_improve/multivariate/_asca.py",
|
|
331
|
+
"src/process_improve/multivariate/_categorical.py",
|
|
332
|
+
"src/process_improve/multivariate/_adaptive.py",
|
|
333
|
+
]
|
|
334
|
+
pytest_add_cli_args = [
|
|
335
|
+
"-o",
|
|
336
|
+
"addopts=",
|
|
337
|
+
"-p",
|
|
338
|
+
"no:cacheprovider",
|
|
339
|
+
]
|
|
340
|
+
pytest_add_cli_args_test_selection = [
|
|
341
|
+
"tests/test_multivariate_limits.py",
|
|
342
|
+
"tests/test_multivariate.py",
|
|
343
|
+
"tests/test_audit_regressions_multivariate.py",
|
|
344
|
+
"tests/test_multiblock_validation.py",
|
|
345
|
+
"tests/test_multivariate_introspection.py",
|
|
346
|
+
"tests/test_monitoring.py",
|
|
347
|
+
"tests/test_monitoring_helpers.py",
|
|
348
|
+
"tests/test_audit_regressions_univariate_monitoring.py",
|
|
349
|
+
"tests/test_evop.py",
|
|
350
|
+
"tests/test_control_chart_cusum.py",
|
|
351
|
+
"tests/test_control_chart_ewma.py",
|
|
352
|
+
"tests/test_control_chart_hw_golden.py",
|
|
353
|
+
"tests/test_nipals_quick_regress.py",
|
|
354
|
+
"tests/test_multivariate_adaptive.py",
|
|
355
|
+
"tests/test_multivariate_centring_traps.py",
|
|
356
|
+
"tests/test_multivariate_projection.py",
|
|
357
|
+
"tests/test_multivariate_pls_missing.py",
|
|
358
|
+
"tests/test_multivariate_prm.py",
|
|
359
|
+
"tests/test_contributions_missing_cells.py",
|
|
360
|
+
"tests/test_multivariate_contribution_plots.py",
|
|
361
|
+
"tests/test_multivariate_meda.py",
|
|
362
|
+
"tests/test_multivariate_resampler.py",
|
|
363
|
+
"tests/test_multivariate_null.py",
|
|
364
|
+
"tests/test_multivariate_gpa.py",
|
|
365
|
+
"tests/test_multivariate_opls.py",
|
|
366
|
+
"tests/test_multivariate_tsr.py",
|
|
367
|
+
"tests/test_pca_nipals_mixomics_crosscheck.py",
|
|
368
|
+
"tests/test_multivariate_nipals_seed.py",
|
|
369
|
+
"tests/test_r2_per_variable_cumulative.py",
|
|
370
|
+
"tests/test_multivariate_sample_weight.py",
|
|
371
|
+
"tests/test_multivariate_inversion.py",
|
|
372
|
+
"tests/test_multivariate_inversion_worked_example.py",
|
|
373
|
+
"tests/test_multivariate_feature_names.py",
|
|
374
|
+
"tests/test_sklearn_compat.py",
|
|
375
|
+
"tests/test_multivariate_robustness.py",
|
|
376
|
+
"tests/test_tool_spec.py",
|
|
377
|
+
"tests/test_multiblock_reference.py",
|
|
378
|
+
"--deselect",
|
|
379
|
+
"tests/test_multiblock_reference.py::TestFMCReference",
|
|
380
|
+
"tests/test_multiblock_weighting.py",
|
|
381
|
+
"tests/test_multivariate_categorical.py",
|
|
382
|
+
"tests/test_mbpls_cross_validation.py",
|
|
383
|
+
"tests/test_mbpls_regressor.py",
|
|
384
|
+
"tests/test_multivariate_tpls_validation.py",
|
|
385
|
+
"tests/test_multivariate_tpls_display.py",
|
|
386
|
+
"tests/test_multivariate_tpls_feature_importance.py",
|
|
387
|
+
"tests/test_multivariate_dataframedict.py",
|
|
388
|
+
"tests/test_multivariate_cv_criteria.py",
|
|
389
|
+
"tests/test_multivariate_plsda.py",
|
|
390
|
+
"tests/test_multivariate_asca.py",
|
|
391
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "process-improve"
|
|
3
|
-
version = "2.
|
|
3
|
+
version = "2.3.0"
|
|
4
4
|
description = 'Designed Experiments; Latent Variables (PCA, PLS, multivariate methods with missing data); Process Monitoring; Batch data analysis.'
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "MIT"
|
|
@@ -152,7 +152,7 @@ dev = [
|
|
|
152
152
|
"pytest-cov>=7.0.0",
|
|
153
153
|
"pytest-xdist>=3.8.0",
|
|
154
154
|
"pydata-sphinx-theme>=0.16.1",
|
|
155
|
-
"ruff>=0.11.0,<0.
|
|
155
|
+
"ruff>=0.11.0,<0.18", # upper-bound so a future ruff release cannot silently break the lint gate (see mypy)
|
|
156
156
|
"sphinx>=8.1.3",
|
|
157
157
|
"nbsphinx>=0.9.5",
|
|
158
158
|
"ipykernel>=6.29",
|
|
@@ -449,3 +449,91 @@ docstring-quotes = "double"
|
|
|
449
449
|
|
|
450
450
|
[tool.ruff.lint.isort]
|
|
451
451
|
known-third-party=["pytest", "pandas"]
|
|
452
|
+
|
|
453
|
+
# Mutation testing: see "Mutation testing" in CONTRIBUTING.md. Modules join `only_mutate` one at a
|
|
454
|
+
# time, each with no survivor, starting with those whose numbers users act on; the tests listed
|
|
455
|
+
# are those that reach them.
|
|
456
|
+
[tool.mutmut]
|
|
457
|
+
source_paths = ["src"]
|
|
458
|
+
only_mutate = [
|
|
459
|
+
"src/process_improve/multivariate/_limits.py",
|
|
460
|
+
"src/process_improve/monitoring/metrics.py",
|
|
461
|
+
"src/process_improve/monitoring/evop.py",
|
|
462
|
+
"src/process_improve/monitoring/control_charts.py",
|
|
463
|
+
"src/process_improve/multivariate/_nipals.py",
|
|
464
|
+
"src/process_improve/multivariate/_preprocessing.py",
|
|
465
|
+
"src/process_improve/multivariate/_projection.py",
|
|
466
|
+
"src/process_improve/multivariate/_impute.py",
|
|
467
|
+
"src/process_improve/multivariate/_robust.py",
|
|
468
|
+
"src/process_improve/multivariate/_diagnostics.py",
|
|
469
|
+
"src/process_improve/multivariate/_resampling.py",
|
|
470
|
+
"src/process_improve/multivariate/_null.py",
|
|
471
|
+
"src/process_improve/multivariate/_procrustes.py",
|
|
472
|
+
"src/process_improve/multivariate/_prm.py",
|
|
473
|
+
"src/process_improve/multivariate/_opls.py",
|
|
474
|
+
"src/process_improve/multivariate/_pca.py",
|
|
475
|
+
"src/process_improve/multivariate/_pls.py",
|
|
476
|
+
"src/process_improve/multivariate/_mbpca.py",
|
|
477
|
+
"src/process_improve/multivariate/_mbpls.py",
|
|
478
|
+
"src/process_improve/multivariate/_tpls.py",
|
|
479
|
+
"src/process_improve/multivariate/_cv_criteria.py",
|
|
480
|
+
"src/process_improve/multivariate/_plsda.py",
|
|
481
|
+
"src/process_improve/multivariate/_asca.py",
|
|
482
|
+
"src/process_improve/multivariate/_categorical.py",
|
|
483
|
+
"src/process_improve/multivariate/_adaptive.py",
|
|
484
|
+
]
|
|
485
|
+
# The runner drops pytest.ini's addopts: no xdist workers and no coverage inside each mutant run.
|
|
486
|
+
pytest_add_cli_args = ["-o", "addopts=", "-p", "no:cacheprovider"]
|
|
487
|
+
pytest_add_cli_args_test_selection = [
|
|
488
|
+
"tests/test_multivariate_limits.py",
|
|
489
|
+
"tests/test_multivariate.py",
|
|
490
|
+
"tests/test_audit_regressions_multivariate.py",
|
|
491
|
+
"tests/test_multiblock_validation.py",
|
|
492
|
+
"tests/test_multivariate_introspection.py",
|
|
493
|
+
"tests/test_monitoring.py",
|
|
494
|
+
"tests/test_monitoring_helpers.py",
|
|
495
|
+
"tests/test_audit_regressions_univariate_monitoring.py",
|
|
496
|
+
"tests/test_evop.py",
|
|
497
|
+
"tests/test_control_chart_cusum.py",
|
|
498
|
+
"tests/test_control_chart_ewma.py",
|
|
499
|
+
"tests/test_control_chart_hw_golden.py",
|
|
500
|
+
"tests/test_nipals_quick_regress.py",
|
|
501
|
+
"tests/test_multivariate_adaptive.py",
|
|
502
|
+
"tests/test_multivariate_centring_traps.py",
|
|
503
|
+
"tests/test_multivariate_projection.py",
|
|
504
|
+
"tests/test_multivariate_pls_missing.py",
|
|
505
|
+
"tests/test_multivariate_prm.py",
|
|
506
|
+
"tests/test_contributions_missing_cells.py",
|
|
507
|
+
"tests/test_multivariate_contribution_plots.py",
|
|
508
|
+
"tests/test_multivariate_meda.py",
|
|
509
|
+
"tests/test_multivariate_resampler.py",
|
|
510
|
+
"tests/test_multivariate_null.py",
|
|
511
|
+
"tests/test_multivariate_gpa.py",
|
|
512
|
+
"tests/test_multivariate_opls.py",
|
|
513
|
+
"tests/test_multivariate_tsr.py",
|
|
514
|
+
"tests/test_pca_nipals_mixomics_crosscheck.py",
|
|
515
|
+
"tests/test_multivariate_nipals_seed.py",
|
|
516
|
+
"tests/test_r2_per_variable_cumulative.py",
|
|
517
|
+
"tests/test_multivariate_sample_weight.py",
|
|
518
|
+
"tests/test_multivariate_inversion.py",
|
|
519
|
+
"tests/test_multivariate_inversion_worked_example.py",
|
|
520
|
+
"tests/test_multivariate_feature_names.py",
|
|
521
|
+
"tests/test_sklearn_compat.py",
|
|
522
|
+
"tests/test_multivariate_robustness.py",
|
|
523
|
+
"tests/test_tool_spec.py",
|
|
524
|
+
"tests/test_multiblock_reference.py",
|
|
525
|
+
# Its FMC case study reads a script from docs/, which mutmut does not copy, and its data from the web.
|
|
526
|
+
"--deselect",
|
|
527
|
+
"tests/test_multiblock_reference.py::TestFMCReference",
|
|
528
|
+
"tests/test_multiblock_weighting.py",
|
|
529
|
+
"tests/test_multivariate_categorical.py",
|
|
530
|
+
"tests/test_mbpls_cross_validation.py",
|
|
531
|
+
"tests/test_mbpls_regressor.py",
|
|
532
|
+
"tests/test_multivariate_tpls_validation.py",
|
|
533
|
+
"tests/test_multivariate_tpls_display.py",
|
|
534
|
+
"tests/test_multivariate_tpls_feature_importance.py",
|
|
535
|
+
"tests/test_multivariate_dataframedict.py",
|
|
536
|
+
"tests/test_multivariate_cv_criteria.py",
|
|
537
|
+
"tests/test_multivariate_plsda.py",
|
|
538
|
+
"tests/test_multivariate_asca.py",
|
|
539
|
+
]
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""(c) Kevin Dunn, 2010-2026. MIT License.
|
|
2
|
+
|
|
3
|
+
The ``@tool_spec`` decorator, the registry it fills, and ``clean``.
|
|
4
|
+
|
|
5
|
+
These are the parts of :mod:`process_improve.tool_spec` that every ``tools.py``
|
|
6
|
+
module imports. They live apart from tool discovery, which names every
|
|
7
|
+
``tools.py`` module, so that a tool module depends on this file alone and not,
|
|
8
|
+
through discovery, on every other tool module. ``tool_spec.py`` re-exports all
|
|
9
|
+
of it, and callers import it from there.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import math
|
|
15
|
+
from collections.abc import Callable
|
|
16
|
+
from typing import Any
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
from pydantic import BaseModel
|
|
20
|
+
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
# Registry
|
|
23
|
+
# ---------------------------------------------------------------------------
|
|
24
|
+
|
|
25
|
+
#: Maps tool name -> decorated callable. Populated by ``@tool_spec``.
|
|
26
|
+
_TOOL_REGISTRY: dict[str, Callable[..., Any]] = {}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
# RNG metadata validation
|
|
31
|
+
# ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _validate_rng_metadata(name: str, rng: dict[str, Any]) -> None:
|
|
35
|
+
"""Reject ``rng`` payloads that don't match the published contract.
|
|
36
|
+
|
|
37
|
+
The contract is intentionally narrow so downstream consumers (the
|
|
38
|
+
factorial reproducible-export service) can introspect specs without
|
|
39
|
+
defensive type-checking. See ``CLAUDE.md`` for the full schema.
|
|
40
|
+
"""
|
|
41
|
+
if not isinstance(rng, dict):
|
|
42
|
+
raise TypeError(f"@tool_spec(name={name!r}): 'rng' must be a dict, got {type(rng).__name__}.")
|
|
43
|
+
if "uses_rng" not in rng or not isinstance(rng["uses_rng"], bool):
|
|
44
|
+
raise ValueError(f"@tool_spec(name={name!r}): 'rng' must have a boolean 'uses_rng' key.")
|
|
45
|
+
allowed_keys = {"uses_rng", "seed_param", "default_seed", "note"}
|
|
46
|
+
extra = set(rng) - allowed_keys
|
|
47
|
+
if extra:
|
|
48
|
+
raise ValueError(
|
|
49
|
+
f"@tool_spec(name={name!r}): unknown keys in 'rng': {sorted(extra)}. Allowed: {sorted(allowed_keys)}."
|
|
50
|
+
)
|
|
51
|
+
if not rng["uses_rng"]:
|
|
52
|
+
# Deterministic tools shouldn't carry a seed_param / default_seed.
|
|
53
|
+
if rng.get("seed_param") is not None or rng.get("default_seed") is not None:
|
|
54
|
+
raise ValueError(
|
|
55
|
+
f"@tool_spec(name={name!r}): 'seed_param' / 'default_seed' must be omitted when uses_rng is False."
|
|
56
|
+
)
|
|
57
|
+
return
|
|
58
|
+
seed_param = rng.get("seed_param")
|
|
59
|
+
if seed_param is not None and not isinstance(seed_param, str):
|
|
60
|
+
raise TypeError(
|
|
61
|
+
f"@tool_spec(name={name!r}): 'seed_param' must be a string or None, got {type(seed_param).__name__}."
|
|
62
|
+
)
|
|
63
|
+
default_seed = rng.get("default_seed")
|
|
64
|
+
if default_seed is not None and not isinstance(default_seed, int):
|
|
65
|
+
raise TypeError(
|
|
66
|
+
f"@tool_spec(name={name!r}): 'default_seed' must be an int or None, got {type(default_seed).__name__}."
|
|
67
|
+
)
|
|
68
|
+
if seed_param is None and default_seed is not None:
|
|
69
|
+
raise ValueError(f"@tool_spec(name={name!r}): 'default_seed' requires a 'seed_param' name.")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# ---------------------------------------------------------------------------
|
|
73
|
+
# Decorator
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def tool_spec( # noqa: PLR0913
|
|
78
|
+
name: str,
|
|
79
|
+
description: str,
|
|
80
|
+
*,
|
|
81
|
+
input_model: type[BaseModel],
|
|
82
|
+
examples: str = "",
|
|
83
|
+
category: str = "",
|
|
84
|
+
rng: dict[str, Any] | None = None,
|
|
85
|
+
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
86
|
+
"""Mark a function as an agent-callable tool.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
name:
|
|
91
|
+
Unique tool name exposed to the LLM (snake_case).
|
|
92
|
+
description:
|
|
93
|
+
Natural-language description of what the tool does and when to use it.
|
|
94
|
+
input_model:
|
|
95
|
+
A :class:`pydantic.BaseModel` subclass describing the tool's
|
|
96
|
+
input. The model is the single source of truth for both the
|
|
97
|
+
function's Python signature and the MCP JSON Schema (derived
|
|
98
|
+
via :meth:`BaseModel.model_json_schema`). Every input model
|
|
99
|
+
**must** set ``model_config = ConfigDict(extra="forbid")`` so
|
|
100
|
+
unknown keys are rejected (closes the SEC-15
|
|
101
|
+
kwarg-injection vector at the schema layer).
|
|
102
|
+
|
|
103
|
+
The decorated function then receives the parsed model as its
|
|
104
|
+
single positional argument::
|
|
105
|
+
|
|
106
|
+
class FooInput(BaseModel):
|
|
107
|
+
model_config = ConfigDict(extra="forbid")
|
|
108
|
+
values: list[float] = Field(..., min_length=2)
|
|
109
|
+
|
|
110
|
+
@tool_spec(name="foo", description="...", input_model=FooInput)
|
|
111
|
+
def foo(spec: FooInput) -> dict:
|
|
112
|
+
return {"n": len(spec.values)}
|
|
113
|
+
examples:
|
|
114
|
+
Optional natural-language -> tool-call mappings appended to
|
|
115
|
+
``description`` so the LLM sees worked examples.
|
|
116
|
+
category:
|
|
117
|
+
Optional category string (e.g. ``"univariate"``). Used for
|
|
118
|
+
filtering with :func:`get_tool_specs`.
|
|
119
|
+
rng:
|
|
120
|
+
Optional reproducibility metadata; see :func:`_validate_rng_metadata`
|
|
121
|
+
for the contract.
|
|
122
|
+
|
|
123
|
+
Returns
|
|
124
|
+
-------
|
|
125
|
+
Callable
|
|
126
|
+
The original function, with an attached ``_tool_spec`` dict
|
|
127
|
+
and ``_input_model`` attribute.
|
|
128
|
+
"""
|
|
129
|
+
if rng is not None:
|
|
130
|
+
_validate_rng_metadata(name, rng)
|
|
131
|
+
|
|
132
|
+
if not (isinstance(input_model, type) and issubclass(input_model, BaseModel)):
|
|
133
|
+
raise TypeError(
|
|
134
|
+
f"@tool_spec(name={name!r}): input_model must be a pydantic BaseModel subclass; got {input_model!r}."
|
|
135
|
+
)
|
|
136
|
+
extra_policy = input_model.model_config.get("extra")
|
|
137
|
+
if extra_policy != "forbid":
|
|
138
|
+
raise ValueError(
|
|
139
|
+
f"@tool_spec(name={name!r}): input_model {input_model.__name__} "
|
|
140
|
+
"must set model_config = ConfigDict(extra='forbid') so unknown "
|
|
141
|
+
"kwargs are rejected (ENG-04 / SEC-15 contract)."
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
145
|
+
"""Attach the assembled tool spec to ``func`` and return it unchanged."""
|
|
146
|
+
full_description = description
|
|
147
|
+
if examples:
|
|
148
|
+
full_description = f"{description}\n\nExamples\n--------\n{examples}"
|
|
149
|
+
|
|
150
|
+
spec: dict[str, Any] = {
|
|
151
|
+
"name": name,
|
|
152
|
+
"description": full_description,
|
|
153
|
+
"input_schema": input_model.model_json_schema(),
|
|
154
|
+
}
|
|
155
|
+
if category:
|
|
156
|
+
spec["category"] = category
|
|
157
|
+
if rng is not None:
|
|
158
|
+
spec["rng"] = dict(rng)
|
|
159
|
+
|
|
160
|
+
func._tool_spec = spec # type: ignore[attr-defined]
|
|
161
|
+
func._input_model = input_model # type: ignore[attr-defined]
|
|
162
|
+
_TOOL_REGISTRY[name] = func
|
|
163
|
+
return func
|
|
164
|
+
|
|
165
|
+
return decorator
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
# ---------------------------------------------------------------------------
|
|
169
|
+
# Serialisation helper
|
|
170
|
+
# ---------------------------------------------------------------------------
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def clean(value: Any) -> Any: # noqa: PLR0911, ANN401
|
|
174
|
+
"""Recursively convert numpy scalars / arrays to plain Python types.
|
|
175
|
+
|
|
176
|
+
All ``tools.py`` modules should call ``clean(result)`` before returning
|
|
177
|
+
so that every tool output is JSON-serialisable.
|
|
178
|
+
"""
|
|
179
|
+
if isinstance(value, dict):
|
|
180
|
+
# Keys need unwrapping too: json.dumps rejects numpy scalar keys (a
|
|
181
|
+
# dict keyed by np.int64 group labels from a pandas groupby is the
|
|
182
|
+
# common case), and previously they leaked through untouched. Only
|
|
183
|
+
# numpy scalars are unwrapped - other key types pass through so
|
|
184
|
+
# hashability is never at risk.
|
|
185
|
+
return {(k.item() if isinstance(k, np.generic) else k): clean(v) for k, v in value.items()}
|
|
186
|
+
if isinstance(value, (list, tuple, set, frozenset)):
|
|
187
|
+
return [clean(v) for v in value]
|
|
188
|
+
# np.bool_ subclasses neither np.integer nor Python bool, and json.dumps
|
|
189
|
+
# rejects it; it must be tested before the numeric branches.
|
|
190
|
+
if isinstance(value, np.bool_):
|
|
191
|
+
return bool(value)
|
|
192
|
+
if isinstance(value, np.integer):
|
|
193
|
+
return int(value)
|
|
194
|
+
if isinstance(value, np.floating):
|
|
195
|
+
v = float(value)
|
|
196
|
+
return None if math.isnan(v) or math.isinf(v) else v
|
|
197
|
+
if isinstance(value, float):
|
|
198
|
+
return None if math.isnan(value) or math.isinf(value) else value
|
|
199
|
+
if isinstance(value, np.ndarray):
|
|
200
|
+
return clean(value.tolist())
|
|
201
|
+
if isinstance(value, np.generic):
|
|
202
|
+
# Catch-all for the remaining numpy scalar types (datetime64,
|
|
203
|
+
# complex, str_, ...): unwrap to the closest Python equivalent.
|
|
204
|
+
return clean(value.item())
|
|
205
|
+
return value
|
|
@@ -22,21 +22,29 @@ solves that choice as a quadratic program in the scaled space of a fitted
|
|
|
22
22
|
With the quadratic caps the problem is a convex quadratically-constrained QP.
|
|
23
23
|
The workhorse is the penalty-form pure QP solved with `osqp
|
|
24
24
|
<https://osqp.org>`_ (the ``control`` extra); the hard-cap mode wraps the
|
|
25
|
-
same QP in an outer
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
same QP in an outer iteration on the two penalty multipliers. It raises the
|
|
26
|
+
multiplier of each broken cap until both caps hold, then bisects each
|
|
27
|
+
multiplier down in turn, taking a step only when both caps still hold: a
|
|
28
|
+
schedule returned with status ``"ok"`` meets both caps to within 1%, and a
|
|
29
|
+
cap that binds alone ends with its statistic just inside it. When both caps
|
|
30
|
+
bind, a step down in one multiplier can break the other cap, so a statistic
|
|
31
|
+
can stay well inside its cap and the schedule can fall short of the capped
|
|
32
|
+
optimum.
|
|
28
33
|
|
|
29
34
|
The formulation follows the latent-variable batch control literature.
|
|
30
35
|
Flores-Cerrillo and MacGregor (2004) give the quality-tracking objective, the
|
|
31
|
-
movement-suppression term
|
|
32
|
-
measurements so far
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
movement-suppression term and the soft T2 term, and they check the SPE of the
|
|
37
|
+
measurements so far before a correction is computed, suggesting that the
|
|
38
|
+
schedule from the last decision point be kept when that check fails, which is
|
|
39
|
+
what the gate here does. The dead band plays the role of the "no-control
|
|
40
|
+
region" of Yabuki and MacGregor (1997). Garcia-Munoz, Kourti and MacGregor
|
|
41
|
+
(2004) compute Hotelling's T2 of on-line score estimates against the
|
|
42
|
+
covariance of the reference batches' estimates at each time, as Nomikos and
|
|
43
|
+
MacGregor (1995) suggested; the per-decision-point limits here, and the
|
|
44
|
+
prediction interval at a decision point, are built the same way, from the
|
|
45
|
+
training batches re-projected under that point's missingness pattern.
|
|
46
|
+
Arteaga and Ferrer (2002) give the trimmed score regression used to estimate
|
|
47
|
+
the scores of a partially observed row.
|
|
40
48
|
|
|
41
49
|
Two departures from Flores-Cerrillo and MacGregor are deliberate. Their
|
|
42
50
|
optimisation is over an adjustment to the scores, with the remaining
|
|
@@ -44,18 +52,20 @@ trajectories recovered by inverting the PLS model, which is what keeps those
|
|
|
44
52
|
trajectories consistent with past operation. Here the decision variables are
|
|
45
53
|
the future MV columns themselves, so actuator bounds and rate limits apply
|
|
46
54
|
exactly in engineering units, and the terms that hold the answer inside the
|
|
47
|
-
model's region are stated explicitly instead.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
model's region are stated explicitly instead. Golshan et al. (2010) give both
|
|
56
|
+
forms for latent-variable MPC: over a correction to the scores, and directly
|
|
57
|
+
over the future manipulated variables. Second, the SPE of the *candidate* row
|
|
58
|
+
is penalised and capped, not only checked on the measurements so far: a
|
|
59
|
+
trajectory reconstructed from adjusted scores lies on the model plane by
|
|
60
|
+
construction, and one written directly in the MV columns need not.
|
|
61
|
+
|
|
62
|
+
A practical caveat: models of this kind are identified on *recorded*
|
|
63
|
+
trajectories (the realised values plus measurement noise), while the
|
|
64
|
+
corrector outputs *setpoints*. The substitution is sound where the control
|
|
65
|
+
loops track their setpoints; the executed-policy evaluation in
|
|
66
|
+
:func:`evaluate_control_policies` (:mod:`process_improve.simulation`)
|
|
67
|
+
measures the realised effect rather than trusting the model's own
|
|
68
|
+
prediction.
|
|
59
69
|
|
|
60
70
|
References
|
|
61
71
|
----------
|
|
@@ -71,6 +81,9 @@ Garcia-Munoz, S., Kourti, T. and MacGregor, J.F., "Model Predictive
|
|
|
71
81
|
Monitoring for Batch Processes", Industrial & Engineering Chemistry
|
|
72
82
|
Research, 43, 5929-5941, 2004.
|
|
73
83
|
|
|
84
|
+
Nomikos, P. and MacGregor, J.F., "Multivariate SPC Charts for Monitoring
|
|
85
|
+
Batch Processes", Technometrics, 37, 41-59, 1995.
|
|
86
|
+
|
|
74
87
|
Yabuki, Y. and MacGregor, J.F., "Product quality control in semibatch
|
|
75
88
|
reactors using midcourse correction policies", Industrial & Engineering
|
|
76
89
|
Chemistry Research, 36, 1268-1275, 1997.
|
|
@@ -138,9 +151,10 @@ def _solve_qp(
|
|
|
138
151
|
eps_abs=1e-10,
|
|
139
152
|
eps_rel=1e-10,
|
|
140
153
|
max_iter=100_000,
|
|
141
|
-
|
|
154
|
+
polishing=True,
|
|
142
155
|
)
|
|
143
|
-
|
|
156
|
+
# Explicit, as osqp warns that its default will become True; the status check below raises instead.
|
|
157
|
+
result = problem.solve(raise_error=False)
|
|
144
158
|
status = str(result.info.status)
|
|
145
159
|
if "solved" not in status.lower():
|
|
146
160
|
raise RuntimeError(
|
|
@@ -660,10 +674,11 @@ class MidCourseCorrector:
|
|
|
660
674
|
answers the monitoring question at a decision point (the predicted final
|
|
661
675
|
quality with its interval, and the validity statistics of the batch so
|
|
662
676
|
far). :meth:`correct` adds the decision: it checks the batch-so-far
|
|
663
|
-
against the model (the SPE
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
677
|
+
against the model (the SPE check of Flores-Cerrillo and MacGregor, 2004,
|
|
678
|
+
keeping the current schedule when it fails), applies the no-correction
|
|
679
|
+
dead band (in the role of the no-control region of Yabuki and MacGregor,
|
|
680
|
+
1997) in target mode, builds the per-decision-point reference limits
|
|
681
|
+
(Garcia-Munoz et al., 2004), solves the QP, and returns the full
|
|
667
682
|
corrected schedule ready to implement (or to hand to
|
|
668
683
|
:meth:`process_improve.simulation.BioreactorSimulator.simulate_batch`).
|
|
669
684
|
|
|
@@ -795,13 +810,15 @@ class MidCourseCorrector:
|
|
|
795
810
|
and the *candidate* pattern (monitoring plus the future MV columns,
|
|
796
811
|
which the optimiser treats as observed) for the QP's SPE cap and the
|
|
797
812
|
score covariance behind its T2 term. Limits: the g-chi-squared SPE
|
|
798
|
-
limit
|
|
799
|
-
|
|
800
|
-
|
|
813
|
+
limit (Box's approximation, as Nomikos and MacGregor, 1995, use it)
|
|
814
|
+
on each pattern's training SPE values, and the F-distribution T2
|
|
815
|
+
limit on the candidate-pattern score estimates with their own
|
|
816
|
+
covariance (Garcia-Munoz et al., 2004).
|
|
801
817
|
|
|
802
818
|
Also returned: ``rmse_k`` (Series over the targets, original units),
|
|
803
819
|
the prediction error of the model at this decision point, from the
|
|
804
|
-
candidate-pattern estimates of the training batches
|
|
820
|
+
candidate-pattern estimates of the training batches (an in-sample
|
|
821
|
+
error, since the model was fitted on those batches); and the
|
|
805
822
|
condition numbers of the two pattern operators. Results are cached
|
|
806
823
|
per ``k``.
|
|
807
824
|
"""
|
|
@@ -903,7 +920,10 @@ class MidCourseCorrector:
|
|
|
903
920
|
uses the model's prediction error *at this decision point*
|
|
904
921
|
(``limits_at(k).rmse_k``) with the leverage of the estimated scores,
|
|
905
922
|
so it is wide early in the batch, when the estimate rests on few
|
|
906
|
-
observed columns, and narrows as the batch runs.
|
|
923
|
+
observed columns, and narrows as the batch runs. It is the prediction
|
|
924
|
+
interval of a least-squares regression of the quality on the scores,
|
|
925
|
+
with the scores treated as known; check its coverage on held-out
|
|
926
|
+
batches before relying on it.
|
|
907
927
|
|
|
908
928
|
Parameters
|
|
909
929
|
----------
|
|
@@ -1190,9 +1210,12 @@ def _oracle_remaining( # noqa: PLR0913 - explicit oracle inputs
|
|
|
1190
1210
|
Direct search (Nelder-Mead, then Powell from the same start) over
|
|
1191
1211
|
``n_knots`` linearly interpolated knot values per manipulated variable
|
|
1192
1212
|
from sample ``k`` onward, with the identical seed, so the disturbances
|
|
1193
|
-
match the batch being corrected.
|
|
1194
|
-
scheme at that decision point
|
|
1195
|
-
not a model of it
|
|
1213
|
+
match the batch being corrected. It estimates the ceiling for any
|
|
1214
|
+
mid-course scheme at that decision point: the objective is the true
|
|
1215
|
+
process, not a model of it, and the disturbances still to come are
|
|
1216
|
+
known to it, as they are to no scheme running on a plant. The search is
|
|
1217
|
+
local, within the full operating bounds and without rate limits, so the
|
|
1218
|
+
value is a lower bound on that ceiling.
|
|
1196
1219
|
"""
|
|
1197
1220
|
from scipy.optimize import minimize # noqa: PLC0415
|
|
1198
1221
|
|
|
@@ -1325,13 +1348,18 @@ def evaluate_control_policies( # noqa: PLR0913, PLR0915, C901 - one executed co
|
|
|
1325
1348
|
run the nominal schedule.
|
|
1326
1349
|
- **oracle-from-k**: for every batch the mid-course policy corrected,
|
|
1327
1350
|
the remaining schedule is instead optimised against the simulator
|
|
1328
|
-
itself at the same decision point
|
|
1329
|
-
the ceiling for any
|
|
1330
|
-
|
|
1331
|
-
limited historical
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1351
|
+
itself at the same decision point, with the batch's own seed
|
|
1352
|
+
(:func:`_oracle_remaining`). This estimates the ceiling for any
|
|
1353
|
+
mid-course scheme at that decision point. The gap to the mid-course
|
|
1354
|
+
row mixes the error of an empirical model with limited historical
|
|
1355
|
+
excitation, the oracle's knowledge of the disturbances still to come,
|
|
1356
|
+
and the corrector's own limits (movement penalty, validity caps,
|
|
1357
|
+
tighter bounds and rate limits).
|
|
1358
|
+
- **adapted**: every batch runs the schedule that maximises the
|
|
1359
|
+
disturbance-free titer for its own initial conditions, found before
|
|
1360
|
+
the batch starts from the simulator's own equations
|
|
1361
|
+
(``simulator.optimal_trajectory``): feedforward adaptation with a
|
|
1362
|
+
perfect process model, an estimate of the feedforward ceiling.
|
|
1335
1363
|
|
|
1336
1364
|
Parameters
|
|
1337
1365
|
----------
|
|
@@ -1357,10 +1385,11 @@ def evaluate_control_policies( # noqa: PLR0913, PLR0915, C901 - one executed co
|
|
|
1357
1385
|
Fit one model per feed class (labels from the training campaign;
|
|
1358
1386
|
test batches are assigned to the nearest class centroid in
|
|
1359
1387
|
standardised Z). With ``False``, or when class labels are
|
|
1360
|
-
unavailable, a single global model is used
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1388
|
+
unavailable, a single global model is used. The effect of a schedule
|
|
1389
|
+
change depends on the feed class and one linear model averages it:
|
|
1390
|
+
on the default configuration the global model corrects five batches
|
|
1391
|
+
for a mean executed gain of about 0.5 g/L, against eight batches and
|
|
1392
|
+
about 1.4 g/L per class, so per-class models are the default.
|
|
1364
1393
|
target_side, dead_band, weights, bounds, rate_limits, spe_cap, t2_cap, n_knots, method, ridge
|
|
1365
1394
|
Corrector settings, passed to :class:`MidCourseCorrector`. ``bounds``
|
|
1366
1395
|
defaults to the simulator's operating bounds tightened inward by
|
|
@@ -72,9 +72,8 @@ def _per_batch_table(sheet: pd.DataFrame, batch_ids: list[Hashable]) -> pd.DataF
|
|
|
72
72
|
def load_nylon() -> dict[Hashable, pd.DataFrame]:
|
|
73
73
|
"""Return the nylon autoclave reactor batch dataset.
|
|
74
74
|
|
|
75
|
-
Trajectory data from an industrial nylon polymerization autoclave
|
|
76
|
-
|
|
77
|
-
``Tag01`` to ``Tag10`` are temperatures, pressures, and flows recorded
|
|
75
|
+
Trajectory data from an industrial nylon polymerization autoclave.
|
|
76
|
+
Variables ``Tag01`` to ``Tag10`` are temperatures, pressures, and flows recorded
|
|
78
77
|
during each batch. Batch durations vary slightly (113 to 135 samples),
|
|
79
78
|
so resample or align the batches to a common length before unfolding
|
|
80
79
|
(see :func:`process_improve.batch.resample_to_reference`).
|