processbehavior 0.3.3__tar.gz → 0.5.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.
Files changed (244) hide show
  1. {processbehavior-0.3.3 → processbehavior-0.5.0}/CHANGELOG.md +231 -1
  2. {processbehavior-0.3.3 → processbehavior-0.5.0}/CITATION.cff +5 -5
  3. {processbehavior-0.3.3 → processbehavior-0.5.0}/CONTRIBUTING.md +16 -4
  4. {processbehavior-0.3.3 → processbehavior-0.5.0}/PKG-INFO +41 -11
  5. {processbehavior-0.3.3 → processbehavior-0.5.0}/README.md +40 -10
  6. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/__init__.py +2 -2
  7. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/analysis.py +577 -333
  8. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/analysis_dataset.py +49 -21
  9. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/analysis_result.py +75 -2
  10. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/capability.py +51 -10
  11. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/data_preparation.py +13 -2
  12. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/datasets/synthetic.py +3 -4
  13. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/effects_calculator.py +1 -1
  14. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/exceptions.py +4 -4
  15. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/focused_result.py +11 -3
  16. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/formulation_spec.py +6 -0
  17. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/loss_function.py +54 -24
  18. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/maximum_information.py +9 -6
  19. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/capability_chart.py +24 -15
  20. processbehavior-0.5.0/processbehavior/plotting/lane_boundaries.py +94 -0
  21. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/plotter.py +1 -0
  22. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/renderers.py +4 -3
  23. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/process_behavior.py +59 -44
  24. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/residual_calculator.py +120 -54
  25. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/result_signals.py +2 -0
  26. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/result_tabular.py +26 -49
  27. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/sds_detector.py +19 -19
  28. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/signals/detector.py +31 -2
  29. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/signals/detectors.py +3 -0
  30. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/spc_constants.py +80 -34
  31. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/study.py +119 -20
  32. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/types.py +18 -4
  33. processbehavior-0.5.0/tests/fixtures/bishop_analyses/aco_medicare.json +948 -0
  34. processbehavior-0.5.0/tests/fixtures/bishop_analyses/known_effects_sds_1.json +683 -0
  35. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_1.json +683 -0
  36. processbehavior-0.3.3/tests/fixtures/bishop_analyses/vassds3analysis.json → processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_2.json +208 -178
  37. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_3.json +1093 -0
  38. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_4.json +1100 -0
  39. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_5.json +786 -0
  40. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_inert_sds_6.json +1111 -0
  41. processbehavior-0.3.3/tests/fixtures/bishop_analyses/vassds1analysis.json → processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_1.json +32 -2
  42. processbehavior-0.3.3/tests/fixtures/bishop_analyses/vassds2analysis.json → processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_2.json +58 -28
  43. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_3.json +1089 -0
  44. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_4.json +1093 -0
  45. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_5.json +785 -0
  46. processbehavior-0.5.0/tests/fixtures/bishop_analyses/pm_sds_6.json +1111 -0
  47. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/coffee_capability_full_baseline.json +1 -0
  48. processbehavior-0.5.0/tests/fixtures/data/wheeler_cavity_thickness.csv +401 -0
  49. processbehavior-0.5.0/tests/fixtures/golden_masters/paired_xbar_s/S_data.parquet +0 -0
  50. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xbar_s/S_metadata.json +1 -0
  51. processbehavior-0.5.0/tests/fixtures/golden_masters/paired_xbar_s/Xbar_data.parquet +0 -0
  52. {processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_uneven → processbehavior-0.5.0/tests/fixtures/golden_masters/paired_xbar_s}/Xbar_metadata.json +1 -0
  53. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/S_data.parquet +0 -0
  54. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/S_metadata.json +53 -0
  55. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/S_statistics.json +7 -0
  56. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/Xbar_data.parquet +0 -0
  57. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/Xbar_metadata.json +58 -0
  58. processbehavior-0.5.0/tests/fixtures/golden_masters/phased_xbar_s/Xbar_statistics.json +7 -0
  59. processbehavior-0.5.0/tests/fixtures/golden_masters/residual_chart/S_data.parquet +0 -0
  60. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/residual_chart/S_metadata.json +1 -0
  61. processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_balanced/S_data.parquet +0 -0
  62. {processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_uneven → processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_balanced}/S_metadata.json +1 -0
  63. processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_balanced/Xbar_data.parquet +0 -0
  64. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/stratified_balanced/Xbar_metadata.json +1 -0
  65. processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_uneven/S_data.parquet +0 -0
  66. {processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_balanced → processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_uneven}/S_metadata.json +1 -0
  67. processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_uneven/Xbar_data.parquet +0 -0
  68. {processbehavior-0.3.3/tests/fixtures/golden_masters/paired_xbar_s → processbehavior-0.5.0/tests/fixtures/golden_masters/stratified_uneven}/Xbar_metadata.json +1 -0
  69. processbehavior-0.5.0/tests/test_ads3_charts.py +61 -0
  70. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_analysis_golden_master.py +17 -0
  71. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_bishop_reference.py +5 -5
  72. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_capability.py +74 -3
  73. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_execute_validation.py +51 -0
  74. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_loss_function.py +60 -25
  75. processbehavior-0.5.0/tests/test_manual_citations.py +49 -0
  76. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_maximum_information.py +26 -0
  77. processbehavior-0.5.0/tests/test_ordered_categorical_lane_order.py +73 -0
  78. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_performance.py +8 -0
  79. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_phased_limits.py +166 -4
  80. processbehavior-0.5.0/tests/test_phased_xbar_s.py +536 -0
  81. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_plotting_decorations.py +42 -1
  82. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_process_behavior.py +119 -15
  83. processbehavior-0.5.0/tests/test_r2_unavailable.py +56 -0
  84. processbehavior-0.5.0/tests/test_r6_effect.py +43 -0
  85. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_recentered_mr_fix.py +10 -10
  86. processbehavior-0.5.0/tests/test_recentering.py +55 -0
  87. processbehavior-0.5.0/tests/test_reference_integrity.py +108 -0
  88. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_residual_calculator.py +121 -186
  89. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_result_tabular.py +97 -3
  90. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_sds.py +5 -15
  91. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_sds_detector.py +7 -5
  92. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_spc_constants.py +1 -1
  93. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_stratified_insufficiency.py +25 -0
  94. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_supports_calibration.py +14 -1
  95. processbehavior-0.5.0/tests/test_unequal_subgroups.py +100 -0
  96. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_vas_chart_constants.py +41 -3
  97. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_xbar_residual_center.py +5 -6
  98. processbehavior-0.5.0/tests/test_xbar_s_helpers.py +153 -0
  99. processbehavior-0.3.3/processbehavior/plotting/lane_boundaries.py +0 -78
  100. processbehavior-0.3.3/tests/fixtures/golden_masters/paired_xbar_s/S_data.parquet +0 -0
  101. processbehavior-0.3.3/tests/fixtures/golden_masters/paired_xbar_s/Xbar_data.parquet +0 -0
  102. processbehavior-0.3.3/tests/fixtures/golden_masters/residual_chart/S_data.parquet +0 -0
  103. processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_balanced/S_data.parquet +0 -0
  104. processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_balanced/Xbar_data.parquet +0 -0
  105. processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_uneven/S_data.parquet +0 -0
  106. processbehavior-0.3.3/tests/fixtures/golden_masters/stratified_uneven/Xbar_data.parquet +0 -0
  107. processbehavior-0.3.3/tests/test_reference_integrity.py +0 -56
  108. {processbehavior-0.3.3 → processbehavior-0.5.0}/.gitignore +0 -0
  109. {processbehavior-0.3.3 → processbehavior-0.5.0}/CODE_OF_CONDUCT.md +0 -0
  110. {processbehavior-0.3.3 → processbehavior-0.5.0}/LICENSE +0 -0
  111. {processbehavior-0.3.3 → processbehavior-0.5.0}/SECURITY.md +0 -0
  112. {processbehavior-0.3.3 → processbehavior-0.5.0}/examples/README.md +0 -0
  113. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/calibration.py +0 -0
  114. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/datasets/__init__.py +0 -0
  115. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/datasets/data/coffee_shop_demo_long.csv +0 -0
  116. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/datasets/loaders.py +0 -0
  117. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/derivations.py +0 -0
  118. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/exporters/__init__.py +0 -0
  119. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/exporters/excel_exporter.py +0 -0
  120. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/__init__.py +0 -0
  121. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/_math.py +0 -0
  122. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/contracts.py +0 -0
  123. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/control_chart.py +0 -0
  124. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/effects_charts.py +0 -0
  125. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/limits.py +0 -0
  126. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/maximum_information_chart.py +0 -0
  127. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/report.py +0 -0
  128. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/residuals.py +0 -0
  129. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/run_rules_viz.py +0 -0
  130. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/stats_box.py +0 -0
  131. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/themes.py +0 -0
  132. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/x_axis_layout.py +0 -0
  133. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/plotting/zones.py +0 -0
  134. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/py.typed +0 -0
  135. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/series_length.py +0 -0
  136. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/signals/__init__.py +0 -0
  137. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/signals/config.py +0 -0
  138. {processbehavior-0.3.3 → processbehavior-0.5.0}/processbehavior/signals/result.py +0 -0
  139. {processbehavior-0.3.3 → processbehavior-0.5.0}/pyproject.toml +0 -0
  140. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/__init__.py +0 -0
  141. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/conftest.py +0 -0
  142. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/data/FILLWEIGHTDATA_800.csv +0 -0
  143. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/data/coffee_shop_demo_long.csv +0 -0
  144. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/X_data.parquet +0 -0
  145. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/X_metadata.json +0 -0
  146. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/X_statistics.json +0 -0
  147. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/mR_data.parquet +0 -0
  148. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/mR_metadata.json +0 -0
  149. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/missing_values/mR_statistics.json +0 -0
  150. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xbar_s/S_statistics.json +0 -0
  151. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xbar_s/Xbar_statistics.json +0 -0
  152. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/X_data.parquet +0 -0
  153. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/X_metadata.json +0 -0
  154. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/X_statistics.json +0 -0
  155. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_data.parquet +0 -0
  156. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_metadata.json +0 -0
  157. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/paired_xmr_r/mR_statistics.json +0 -0
  158. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/X_data.parquet +0 -0
  159. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/X_metadata.json +0 -0
  160. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/X_statistics.json +0 -0
  161. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/mR_data.parquet +0 -0
  162. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/mR_metadata.json +0 -0
  163. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/pathological_ordering/mR_statistics.json +0 -0
  164. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/residual_chart/S_statistics.json +0 -0
  165. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/X_data.parquet +0 -0
  166. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/X_metadata.json +0 -0
  167. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/X_statistics.json +0 -0
  168. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/mR_data.parquet +0 -0
  169. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/mR_metadata.json +0 -0
  170. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/single_obs_strata/mR_statistics.json +0 -0
  171. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/stratified_balanced/S_statistics.json +0 -0
  172. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/stratified_balanced/Xbar_statistics.json +0 -0
  173. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/stratified_uneven/S_statistics.json +0 -0
  174. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/stratified_uneven/Xbar_statistics.json +0 -0
  175. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/X_data.parquet +0 -0
  176. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/X_metadata.json +0 -0
  177. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/X_statistics.json +0 -0
  178. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/mR_data.parquet +0 -0
  179. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/mR_metadata.json +0 -0
  180. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/fixtures/golden_masters/unstratified_small/mR_statistics.json +0 -0
  181. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_analysis_bugs.py +0 -0
  182. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_analysis_dataset.py +0 -0
  183. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_analysis_result_contract.py +0 -0
  184. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_analysis_specifications.py +0 -0
  185. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_api_reference.py +0 -0
  186. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_beyond_limits_vectorized.py +0 -0
  187. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_bin_extremes.py +0 -0
  188. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_by_parameter.py +0 -0
  189. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_by_permutations.py +0 -0
  190. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_calibration.py +0 -0
  191. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_capability_chart.py +0 -0
  192. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_capability_window.py +0 -0
  193. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_chart_availability.py +0 -0
  194. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_chart_column_contract.py +0 -0
  195. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_chart_parsing.py +0 -0
  196. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_control_chart_figure.py +0 -0
  197. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_data_preparation.py +0 -0
  198. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_datasets.py +0 -0
  199. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_derivations.py +0 -0
  200. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_derivations_robustness.py +0 -0
  201. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_design_state_lineage.py +0 -0
  202. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_documented_rule_coverage.py +0 -0
  203. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_edge_cases.py +0 -0
  204. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_effects_calculator.py +0 -0
  205. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_effects_plotting.py +0 -0
  206. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_encode_rsg_vectorized.py +0 -0
  207. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_excel_export.py +0 -0
  208. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_focus.py +0 -0
  209. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_garbage_character_handling.py +0 -0
  210. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_init_cleaning.py +0 -0
  211. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_lane_boundaries.py +0 -0
  212. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_lane_connectors.py +0 -0
  213. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_limits_vectorized.py +0 -0
  214. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_na_in_factor_columns.py +0 -0
  215. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_notebook_ergonomics.py +0 -0
  216. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_p0_p2_regressions.py +0 -0
  217. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_plotting.py +0 -0
  218. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_plotting_hardening.py +0 -0
  219. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_plotting_xaxis.py +0 -0
  220. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_release_gate_0_1_0_checklist.py +0 -0
  221. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_residual_aliases.py +0 -0
  222. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_residual_labels.py +0 -0
  223. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_residual_scope.py +0 -0
  224. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_resolve_by_grouping.py +0 -0
  225. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_result_signals.py +0 -0
  226. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_sampling_plan.py +0 -0
  227. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_series_length.py +0 -0
  228. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_signal_detectors.py +0 -0
  229. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_signal_result_surface.py +0 -0
  230. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_signals.py +0 -0
  231. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_single_detection.py +0 -0
  232. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_solo_mr_residuals.py +0 -0
  233. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_srp_refactor.py +0 -0
  234. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_strata_companion.py +0 -0
  235. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_strata_sufficiency.py +0 -0
  236. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_synthetic.py +0 -0
  237. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_types.py +0 -0
  238. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_validate_by_parameter.py +0 -0
  239. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_weco_integration.py +0 -0
  240. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_why_not.py +0 -0
  241. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_x_axis_layout.py +0 -0
  242. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_xbar_s_options.py +0 -0
  243. {processbehavior-0.3.3 → processbehavior-0.5.0}/tests/test_xbar_stratified.py +0 -0
  244. {processbehavior-0.3.3 → processbehavior-0.5.0}/validation/PBTESTDATABASE_T100.csv +0 -0
@@ -7,6 +7,234 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-10-29
11
+
12
+ This release adds staged (phased) Xbar and S charts, computed per stage as Dr. Bishop
13
+ specified (2026-10-18), with `phase_statistics()` for the numbers behind each stage on both
14
+ chart families. A column of values with no time is now charted in the order received.
15
+
16
+ ### Added
17
+ - **A bare response is charted in the order received.** `formulate(response=...)` with no time,
18
+ factors or plan used to be refused. The values are now numbered 1..N in an `Observation` column
19
+ (the same numbers as `obs_id`) and the study is exactly the one `time='Observation'` gives: a
20
+ single stream, ADS 2, X/mR, sigma from N − 1 moving ranges. An NA response keeps its place as an
21
+ empty cell. The design report adds `Time: received order (no time column given)`. If the data
22
+ already has an `Observation` column, formulate asks you to pass it as `time=` or rename it (#129).
23
+ - **Phased limits on Xbar and S charts.** `execute(chart='Xbar', phased=True)` gives each factor
24
+ combination its own centre line and limits on one chart, drawn as stepped lines with a divider at
25
+ each change, the way phased X/mR already does for its lanes. Each phase is computed as a separate
26
+ Xbar/S analysis, exactly as `by=[time]` computes one chart per condition: the centre is the mean of
27
+ the phase's subgroup means, with its own S-bar and sigma-hat (10-12 manual Eqs 11-5, 11-8, 11-9,
28
+ 11-16, 11-17). `by=['stage', time]` pools the other factors into the subgroup and phases on the
29
+ stage; the centre is then the mean of the pooled subgroup averages, as Dr. Bishop specified
30
+ (2026-10-18). On Wheeler's four-cavity thickness data the per-cavity centres and limits match
31
+ Minitab's staged Xbar-S chart. Residual values, calibrations and `by=[time]` are refused with
32
+ messages that say what to use instead; a phase with no replicated subgroup keeps its points without
33
+ limits and is named in `metadata['insufficient_phases']`. (#144)
34
+ - **`result.phase_statistics(chart, stratum=None)`.** One row per phase of a phased chart. Xbar/S:
35
+ `phase`, `subgroups`, `N`, `center`, `s_bar`, `sigma_hat`, `lpl`, `upl`. X/mR: `phase`, `points`,
36
+ `center`, `mR_bar`, `lpl`, `upl`, per stratum on a stratified chart (`stratum=`, or through
37
+ `focus()`). (#144)
38
+ - **Docs: a Staged Charts tutorial**, executed in CI. On the bundled coffee-shop data, with the
39
+ stage derived by one `.bin()` call, it compares one set of limits with limits per stage on Xbar
40
+ and S, reads `phase_statistics()`, puts every reading on a phased X/mR chart, and pools or splits
41
+ a second factor. The chart-types guide's staged example now runs as written, and its pooling
42
+ example uses a study that has a factor to pool. (#144)
43
+
44
+ ### Changed
45
+ - **`formulate(response=..., factors=[])` with no time is the same study.** It used to treat the
46
+ whole column as one replicated cell: ADS 1, a recommended one-point Xbar chart, the "within-cell
47
+ replication" series-length line, and an X chart plotted against the response values. Its chart
48
+ tables now start with `Observation` (#129).
49
+ - **Xbar and S chart data carry `n`.** `get_chart('Xbar')` / `get_chart('S')`, and the Excel chart
50
+ sheets, gain an `n` column after the subgroup label. Unstratified Xbar/S metadata names the label
51
+ column as `group_col` (#143).
52
+ - **Lane dividers on an Xbar or S chart are labelled with the phase.** These charts have no time
53
+ column and so no cell band under the axis, which is where X charts name their lanes. (#144)
54
+ - **Phased chart data and `chart_table` carry a `phase` column** (the lane label) after the subgroup
55
+ label, on X/mR as well as Xbar/S. Phased Xbar/S metadata carries `phase_by`, `lane_boundaries`,
56
+ `single_point_phases` and `insufficient_phases`; `n_avg` is not reported on a phased chart, whose
57
+ `n_mode='average'` is applied per phase, so the per-phase mean size is `phase_statistics(chart)['N']`.
58
+ (#144)
59
+
60
+ ### Fixed
61
+ - **Xbar/S `chart_table` keeps the subgroup label and `n` on every `by=`.** With a `by=` other than
62
+ time alone, such as a pooled subset (`by=['FACTOR 1', time]`), all factors, factors without time,
63
+ or one factor, the table dropped both columns, so a row couldn't be traced to its subgroup and
64
+ stepped limits went unexplained. `n` is now the aggregation's own count, which covers every cell
65
+ a pooled subgroup spans. This also corrects one row on residual charts whose limits rest on R2
66
+ (R1, R3, R4, R5) in a design with singletons: the stream's first cell, where R2 is undefined at
67
+ the first value, showed its cell size, not the one-fewer values its S and limits use. Limits,
68
+ centres and statistics are unchanged (#143).
69
+ - **`execute()` no longer documents `phased=True` as requiring `by=[]`.** Stratified phasing of X/mR
70
+ (`by=['factor 1'], phased=True`) has been accepted since 75bcdd1; the docstring never caught up. (#144)
71
+ - **The companion mR of a phased X chart reports `single_point_phases`.** Only the solo mR did. (#144)
72
+ - **X/mR lane order honours an ordered pandas Categorical factor.** A stage column with categories
73
+ `before < after` already ordered the Xbar/S subgroups that way, but the canonical row order sorted
74
+ the raw labels, so X/mR lanes, phases and `strata` came out `after, before`. The canonical sort now
75
+ uses an ordered Categorical's category codes; plain string and numeric factors sort as before. (#144)
76
+
77
+ ## [0.4.0] - 2026-10-14
78
+
79
+ This release aligns the library with Bishop's VAS documentation manual dated 10-12-2026 and
80
+ reproduces his VAS runs of October 2026 (PM SDS, PM INERT, known-effects and Medicare decks).
81
+ Equation numbers below are that manual's.
82
+
83
+ ### Changed
84
+ - **R6's factor-level effect is the average of the condition effects over the level.** R6 = α_i + R2
85
+ with α_i the condition effects ρ̂_k = R5 - R2 averaged over the level (was the level's mean of R5,
86
+ Eq 14-24, "≈ α_i"). The two differ by the level's average R2, which Dr. Bishop notes is always
87
+ near 0; in ADS 1 it is 0 (R2 averages to zero in each cell). On ADS 2/3 it shows when levels are
88
+ small: Tom's Medicare run centres the organisation-effects chart at 10831.1 (PB was 10829.8, now
89
+ 10831.1).
90
+ - **R2 for designs with a one-observation subgroup (ADS 2 and 3) follows the manual.**
91
+ The data are first stripped of the process mean and the condition and period effects
92
+ (Z = Y − Ȳ_k − Ȳ_t + Ȳ, Eq 14-4 / 14-9), Z is differenced along the condition-then-time
93
+ sequence, and the difference is divided by twice the R2 scale factor
94
+ c(K, M) = √((K − 1)/(2K) · (1 − K/(M − 1))), computed from the layout (Eqs 14-5..14-13).
95
+ Previously R2 was half the difference of consecutive raw values, so every step from one
96
+ condition's last period to the next condition's first carried the level difference between
97
+ them, a common trend was read as noise, and the result sat on a smaller scale than σ. R3–R6,
98
+ the effects, maximum information and potential capability follow. PM SDS 2 R2 chart limits
99
+ ±1.94 → ±2.76, PM SDS 3 ±2.47 → ±3.70, potential Cp on PM SDS 2 (specs 232/242)
100
+ 2.51 → 1.78; on the Medicare ACO file the R2 σ falls from about 1,023 to 300 and the
101
+ organisation chart (recentred R5 by ACO) flags 19 of 24 organisations instead of 8. ADS 1
102
+ R2 (within-cell deviation, Eq 14-3) is unchanged. `calculate_r2` now dispatches on
103
+ `r2_method` and takes `n_conditions`; its `n_per_cell` argument is gone.
104
+ - **Taguchi loss follows the manual.** ADS 1 unexplained loss is the average cell
105
+ variance (1/KT)·ΣS²_kt, without dividing each S_kt by c4 (Eq 15-16). ADS 2/3 unexplained
106
+ loss is the sample variance of R2 (Eq 15-17; the 1/0.7 correction is gone), and the
107
+ interaction is what the other parts leave of the total loss (Ȳ − T)² + S², set to 0 when
108
+ negative (Eqs 15-18..15-20), so the parts add to the total. PM SDS 1 at target 237:
109
+ unexplained 23.0% → 20.9%, interaction 43.3% → 44.5%; PM SDS 2: interaction 42.5% → 25.6%,
110
+ unexplained 23.6% → 30.0%; pure noise (PM INERT) now shows 0% interaction in ADS 2/3.
111
+ - **Re-centred residuals are the residual plus the process mean, the mean of the cell means
112
+ (Eq 14-26).** RCR3, RCR4 and
113
+ RCR5 were "reconstructed Y" (each algebraically Ȳ_kt + R2), so a recentred interaction
114
+ chart plotted close to the raw cell means. They now plot the effect plus R2 on the
115
+ measurement scale, as VAS does; RCR2 is unchanged. Xbar means by condition (RCR5) or
116
+ period (RCR4) are unchanged on complete designs; period effects are charted from R4.
117
+ - **ADS 3 recommends the Xbar chart** (was X): Xbar/S is VAS's default for SDS 3 and 6.
118
+ - **Capability is centred on the process mean as VAS computes it**: the unweighted mean of the
119
+ (factor × time) cell means, the same centre as the Xbar chart and the loss function, instead
120
+ of the plain average of the readings. `CapabilityResult.y_bar`, current PPL/PPU and the
121
+ potential centre (ȳ + mean(R2)) move when cells have different sizes (SDS 3, 4, 6); balanced
122
+ designs are unchanged. PM SDS 6 now reads PROCESS MEAN 237.86 and PPL 1.102 / PPU 0.78, as
123
+ Tom's VAS run does (was 237.834, 1.098 / 0.784).
124
+ - **Validation gate re-referenced to Tom's 3 October 2026 VAS run**
125
+ (`validation/e2e_bishop_report.py`, `tests/fixtures/bishop_analyses/`). PM SDS 3 is checked
126
+ as Xbar/S, as VAS now draws it; its limits vary with subgroup size and are not printed on the
127
+ slides, so they carry no reference yet. The gate now reports 254 assertions passing and 61
128
+ with no reference value (was 280 / 35); PB's side is compared at full precision.
129
+ - **The validation gate covers every VAS run on hand** (14 runs, 1155 assertions, was 3 runs and
130
+ 254): PM SDS 1-6, PM INERT SDS 1-6 (the pure-noise column with each design state's missing-data
131
+ pattern), Tom's known-effects data (`validation/PBTESTKNOWNEFFECTS_T100.csv`, SDS 1) and the
132
+ Medicare ACO data (`validation/aco_per_capita_expenditure.csv`, 24 organisations x 4 years). Each
133
+ run's reference values, spec limits and target are in its own file,
134
+ `tests/fixtures/bishop_analyses/<run>.json` (the `vassds{1,2,3}analysis.json` references are
135
+ now `pm_sds_{1,2,3}.json`). All six PM runs use target 237; PM SDS 5's loss shares come from
136
+ Tom's rerun at 237 (8 October 2026), because his 10/3 run used the process mean.
137
+ - **Limits VAS prints as "UNEQUAL" are checked against the lines it draws.** Where subgroup sizes
138
+ differ, VAS steps the limits per subgroup and prints no value; the gate now reads every
139
+ subgroup's LBL/UBL from the red limit lines in the VAS chart drawing (scaled by the y-axis ticks,
140
+ good to about one drawing unit) and compares PB subgroup by subgroup, to 1.5 drawing units. 186
141
+ charts in SDS 3-6; the gate reports 1475 assertions passing, 0 failing, and 79 with no
142
+ reference (was 1155 / 0 / 399).
143
+ - **The R6 S charts are checked wherever VAS computed them correctly.** VAS's α<sub>N</sub>
144
+ (Eq 10-11) used Minitab's GAMMA function, which overflows above N = 343; the 10/3 VAS runs held
145
+ α<sub>N</sub> at 0.9995 from there on, so their S limits followed N = 500 whatever the subgroup size.
146
+ Dr. Bishop confirmed it (8 October 2026) and is replacing it with a table; PB computes α<sub>N</sub>
147
+ with log-gamma for any N. The gate now checks the R6 S charts whose subgroups are under 343 (all
148
+ match), the factor S charts' centerlines (one subgroup per factor level, as Dr. Bishop confirmed),
149
+ and PM SDS 5's loss shares from his rerun at 237; only the limits for subgroups of 343 or more
150
+ wait for his rerun. The references' notes now give that cause.
151
+ - **Every R6 S chart in the PM runs is checked, against Dr. Bishop's reruns of 13 October 2026.**
152
+ His reruns of PM SDS 1-6 and PM INERT SDS 1-6 compute α<sub>N</sub> for every N. Against the
153
+ 10/3 runs they change only the R6 S charts (pages 21, 25 and 27) and potential capability in
154
+ PM SDS 3 and 4. The limits for subgroups of 343 or more, pending until now, all match PB within
155
+ the gate's tolerances (36 assertions). The rerun's potential capability is now PB's value
156
+ to the digit it prints: PM SDS 3 Cp 1.58 and CPL 1.84 (PB 1.5751 and 1.8356; the 10/3 run
157
+ printed 1.57 and 1.83), and PM SDS 4 CPL 2.66 (PB 2.6555; was 2.65). The gate no longer lists
158
+ the per-factor loss shares (F1, F2, PDC Int) for a one-factor run such as Medicare, where they
159
+ don't exist. It reports 1547 assertions passing, 0 failing and 4 with no reference (was 1511 /
160
+ 0 / 43): the known-effects factor S limits, whose 6 October run predates the fix.
161
+
162
+ ### Added
163
+ - **R2 is reported unavailable, with the reason, when the R2 scale factor is undefined**
164
+ (fewer than two process design conditions, or M < K + 2 observations). `formulate()` warns;
165
+ R2–R6 are not offered; `execute()` and `why_not()` give the reason; `loss_function()` and
166
+ `maximum_information()` raise `ValidationError`; `capability()` reports potential capability
167
+ unavailable. Previously these layouts produced half-differences of the raw data.
168
+ - **`CapabilityResult.potential_center`**: the centre of the potential values, ȳ + mean(R2).
169
+ Potential CPL/CPU and the potential chart's centre line use it, as VAS does (Medicare potential
170
+ PPU 5.74; ȳ alone gives 5.73). It equals ȳ in ADS 1.
171
+
172
+ ### Fixed
173
+ - **Stratified charts take time in proportion to the data, however many strata there are.**
174
+ The stratified X/mR path looked each stratum up with a scan of the whole table, so its cost
175
+ grew with strata × rows. With every row its own condition, an X/mR pair took 48 s at 30,165
176
+ rows, and an estimated 80 minutes at 307,683 (a gene-expression study, 6,033 genes × 51
177
+ subjects). It now takes 0.2 s and 1.9 s. The same scan sat in the stratified Xbar/S loops and
178
+ the lane-boundary loop, the per-stratum limits were computed one `pd.Series` at a time, and
179
+ two lists of strata were searched as lists. Results are unchanged: every chart, statistic,
180
+ lane boundary and stratum list was compared before and after on the reference data and a
181
+ 30,165-row gene-effects file. `scripts/benchmark.py` adds a one-row-strata scenario, and
182
+ `tests/test_performance.py` checks that it scales linearly. Stratified Xbar/S still costs
183
+ about 2.5 ms per stratum (15 s at 6,033): linear, but not yet vectorised.
184
+ - **Charts with many lanes draw in a fraction of a second.** Each lane divider was added to the
185
+ figure with its own `add_shape` call, and plotly re-validates every shape already there, so the
186
+ cost grew with the square of the number of lanes: 800 dividers took 27 s, and an X chart of a
187
+ 6,033-gene study (one lane per gene) would have taken about 25 minutes. They are now added in
188
+ one assignment, which builds the same figure (0.03 s for 800). Above 1,000
189
+ (`plotting.lane_boundaries.MAX_LANE_DIVIDERS`) none are drawn: the dividers would merge into a
190
+ solid band at any chart width.
191
+ - **`detect_signals()` works on phased charts.** It raised `TypeError` on every `phased=True`
192
+ chart: each phase has its own centre, so the statistics carry `center=None`, and the zone
193
+ calculation read that scalar. The chart already marks run rules not applicable, but only the
194
+ plot read the flag. Phased charts now get Rule 1 by default, judged against each phase's
195
+ limits, with the same points the chart flags; an explicit rule list runs as given, against each
196
+ row's own centre. The limits and the flagged points on the chart were always correct.
197
+ - **`value='response'` charts the response**, as the `execute()` signature and docstring say.
198
+ Every chart refused it ("Valid charts for RESPONSE: None"): residuals are told apart by a leading
199
+ `R`, which `RESPONSE` also has. `execute()`, `supports_calibration()` and `why_not()` now treat
200
+ it, in any case, exactly as `value=None`.
201
+ - **Xbar and S charts with subgroups of unequal size follow the manual (Eqs 11-5, 11-16,
202
+ 11-17).** sigma-hat is the average of each subgroup's S_r / c4(N_r) (was S-bar / c4(N_r)), and each
203
+ subgroup's limits use its own N_r, so they step with subgroup size, as VAS draws them. N_r now
204
+ counts the values the chart is drawn from (was the response's count): on ADS 2 and 3 residual
205
+ charts, R2's blank first value leaves one subgroup one smaller. Equal-size charts are unchanged.
206
+ Found on Tom's Medicare run (slides 52-53): ACO-001 has 3 R6 values, and its limits are wider by
207
+ sqrt(4/3) on the Xbar chart and use B4(3) on the S chart.
208
+ - **Xbar charts include one-reading subgroups, as VAS draws them.** A subgroup with one value has
209
+ no S, so it takes no part in sigma-hat, but it is charted with limits centre ± 3 sigma-hat
210
+ (Eqs 11-16/17 with N_r = 1); it was left off the chart. The companion S chart still leaves it
211
+ out. On PM SDS 3 the Xbar chart now has all 800 subgroups (was 783) and on PM SDS 6 all 772
212
+ (was 642), matching the limit lines in Tom's VAS run subgroup by subgroup; on PM SDS 6's
213
+ interaction chart the one cell whose single reading has no R2 stays off, as in VAS. Designs
214
+ without one-reading subgroups (ADS 1) are unchanged.
215
+ - **Per-stratum Xbar centre lines count one-observation subgroups.** The centre is Bishop's
216
+ unweighted mean of every subgroup mean; subgroups with n = 1 were dropped before it was
217
+ taken, which moved four of the eight PM SDS 3 per-condition centres by 0.01–0.04.
218
+ - **Code and docs cite the manual's Chapters 10 and 12.** The X/mR limits and constants
219
+ (Eqs 12-1..12-11), c4 and the S-chart factors (Eqs 10-11, 10-12, 10-14), the cell and marginal
220
+ means (Eqs 10-7, 10-9) and the model the residuals estimate (Eq 10-3) now cite the manual where
221
+ the code computes exactly those equations, and every citation names the 10-12 edition (its
222
+ Chapter 10 drops the 10-1 edition's Eq 10-4, so Eqs 10-5..10-16 became 10-4..10-15); dotted
223
+ citations ("Eq 12.4") and an older manual's numbering in a test are gone.
224
+ `tests/test_manual_citations.py` keeps one citation form, and CONTRIBUTING.md describes it. The
225
+ residuals guide now says Ȳ is the mean of the cell means.
226
+ - **Bishop's methodology is called the Variation Analysis System**, as his VAS documentation
227
+ manual names it (was "Variance Analysis System" in the README, docs, CITATION.cff, docstrings and
228
+ the design report's VAS line). The synthetic-data module no longer credits the design states to
229
+ Wheeler.
230
+ - **Docs:** the three note blocks in the chart-types and design-state guides now render on the
231
+ MyST site (they used mkdocs syntax); the DS 4–6 chart tables and the no-factors branch of the
232
+ decision tree match what the library offers (a time-only study is DS 1, 2 or 3 by the number
233
+ of observations per time point, not DS 6); the R1 note no longer claims the residuals sum to
234
+ zero on unbalanced data (their cell means average to zero); R1 is cited as Eq 14-2, and the
235
+ design states are attributed to Bishop. The README's Validation section describes the gate as
236
+ it is (14 VAS runs, 1,547 assertions, SDS 4–6 included); it still described 3 runs and 254.
237
+
10
238
  ## [0.3.3] - 2026-09-29
11
239
 
12
240
  ### Changed
@@ -953,7 +1181,9 @@ and may change between minor versions until 1.0.
953
1181
  - `natsort >= 8.0`
954
1182
  - `plotly >= 5.18, < 7`
955
1183
 
956
- [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.3.3...HEAD
1184
+ [Unreleased]: https://github.com/cnicholas/processbehavior/compare/v0.5.0...HEAD
1185
+ [0.5.0]: https://github.com/cnicholas/processbehavior/compare/v0.4.0...v0.5.0
1186
+ [0.4.0]: https://github.com/cnicholas/processbehavior/compare/v0.3.3...v0.4.0
957
1187
  [0.3.3]: https://github.com/cnicholas/processbehavior/compare/v0.3.2...v0.3.3
958
1188
  [0.3.2]: https://github.com/cnicholas/processbehavior/compare/v0.3.1...v0.3.2
959
1189
  [0.3.1]: https://github.com/cnicholas/processbehavior/compare/v0.3.0...v0.3.1
@@ -1,8 +1,8 @@
1
1
  cff-version: 1.2.0
2
2
  message: "If you use processbehavior in your research, please cite it as below."
3
- title: "processbehavior: Process Behavior Charts and Variance Analysis for Python"
3
+ title: "processbehavior: Process Behavior Charts and Variation Analysis for Python"
4
4
  abstract: >-
5
- A Python implementation of Thomas A. Bishop's Variance Analysis System (VAS):
5
+ A Python implementation of Thomas A. Bishop's Variation Analysis System (VAS):
6
6
  three-state design-state lineage detection (planned / observed / analytical),
7
7
  process behavior charts, R1-R6 residual variance decomposition, capability
8
8
  indices, and Taguchi loss functions. Analytical outputs are validated
@@ -17,11 +17,11 @@ authors:
17
17
  repository-code: "https://github.com/cnicholas/processbehavior"
18
18
  url: "https://cnicholas.github.io/processbehavior/"
19
19
  license: Apache-2.0
20
- version: 0.2.0
20
+ version: 0.5.0
21
21
  keywords:
22
22
  - statistical process control
23
23
  - process behavior charts
24
- - variance analysis
24
+ - variation analysis
25
25
  - control charts
26
26
  - quality control
27
27
  - shewhart
@@ -31,7 +31,7 @@ references:
31
31
  - type: book
32
32
  title: "The Scientific Basis for Modern Analytic Practice"
33
33
  abstract: >-
34
- The methodological foundation for the Variance Analysis System this
34
+ The methodological foundation for the Variation Analysis System this
35
35
  package implements: applied-research foundations, scientific methodology,
36
36
  Shewhart's inductive analytic approach and process behavior charts,
37
37
  operational definitions and research protocols, and case studies.
@@ -1,7 +1,7 @@
1
1
  # Contributing to processbehavior
2
2
 
3
3
  Thanks for your interest. processbehavior is an implementation of Thomas A.
4
- Bishop's Variance Analysis System (VAS); methodology fidelity is more
4
+ Bishop's Variation Analysis System (VAS); methodology fidelity is more
5
5
  important than feature volume. Smaller, well-validated changes are preferred.
6
6
 
7
7
  ## What this library is, and what it is not
@@ -77,12 +77,12 @@ residuals (R1–R5), DS detection, limit calculations, or variance
77
77
  decomposition must keep the relevant Bishop-reference tests green:
78
78
 
79
79
  ```bash
80
- pytest tests/test_bishop_reference.py -v
80
+ pytest tests/test_bishop_reference.py -v # skips unless Bishop's residual workbooks are present
81
81
  ```
82
82
 
83
83
  There is also a full end-to-end check that compares every chart center, control
84
- limit, capability index and loss component against Bishop's published Minitab
85
- results — 280 assertions across ADS 1–3:
84
+ limit, capability index and loss component against Bishop's VAS runs for the
85
+ 10-12-2026 manual (PM SDS 1–6, PM INERT, his known-effects data and the Medicare data):
86
86
 
87
87
  ```bash
88
88
  python validation/e2e_bishop_report.py
@@ -97,6 +97,18 @@ summary.
97
97
  If a Bishop check fails after your change, the change is wrong — not the
98
98
  reference.
99
99
 
100
+ ## Citing the methodology
101
+
102
+ Code and docs cite Bishop's VAS documentation manual by edition and equation number:
103
+ `(10-12 manual Eq 14-8)`, `Eqs 14-4..14-13`, `Eqs 11-16/17`. Name the edition once per file and use
104
+ the chapter-number form; `tests/test_manual_citations.py` checks both. The citations are read
105
+ against the manual itself, so a new edition reports every place in the library whose equation
106
+ changed or moved.
107
+
108
+ Cite an equation only where the code computes exactly that equation. Where it computes something
109
+ close (a different weighting, an approximation, a different sequence), say how it differs instead
110
+ of citing it.
111
+
100
112
  ## Docs versioning
101
113
 
102
114
  The docs have one live version, deliberately, until 1.0:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: processbehavior
3
- Version: 0.3.3
3
+ Version: 0.5.0
4
4
  Summary: Python-native Process Behavior & Control Charts (spec-driven SPC with tidy outputs)
5
5
  Project-URL: Homepage, https://github.com/cnicholas/processbehavior
6
6
  Project-URL: Repository, https://github.com/cnicholas/processbehavior
@@ -89,7 +89,7 @@ Description-Content-Type: text/markdown
89
89
  [![codecov](https://codecov.io/gh/cnicholas/processbehavior/graph/badge.svg)](https://codecov.io/gh/cnicholas/processbehavior)
90
90
  [![License](https://img.shields.io/pypi/l/processbehavior.svg)](https://github.com/cnicholas/processbehavior/blob/main/LICENSE)
91
91
 
92
- A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variance Analysis System (VAS) methodology.
92
+ A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variation Analysis System (VAS) methodology.
93
93
 
94
94
  Unlike traditional SPC packages, processbehavior faithfully implements Bishop's VAS equation-by-equation: automatic detection of the three-state design lineage (PDS / ODS / ADS), variance decomposition via R1-R6 residuals, and chart selection routed by the data your study can actually analyze.
95
95
 
@@ -108,6 +108,22 @@ pip install "processbehavior[images]" # kaleido, for static plot images
108
108
 
109
109
  ## Quickstart
110
110
 
111
+ A column of values, charted in the order received, is an X/mR chart in two calls:
112
+
113
+ ```python
114
+ import pandas as pd
115
+ import processbehavior as pb
116
+
117
+ df = pd.DataFrame({'weight': [50.2, 49.8, 50.5, 50.1, 49.6, 50.9, 50.3, 49.9, 50.4, 50.0, 49.7, 50.6]})
118
+
119
+ study = pb.formulate(df, response='weight') # no time column: rows are numbered 1..N as 'Observation'
120
+ result = study.execute(companion=True) # X chart with its mR companion
121
+ print(result.statistics('X')) # {'N': 1, 'center': 50.167, 'lpl': 48.619, 'upl': 51.714}
122
+ result.plot()
123
+ ```
124
+
125
+ When the data has a time order, factors, or both, name them. The design state routes the analysis:
126
+
111
127
  ```python
112
128
  import processbehavior as pb
113
129
 
@@ -149,6 +165,20 @@ The whole pipeline is one expression when you don't need the intermediate object
149
165
  pb.formulate(df, response='y', factors=['factor 1'], time='time').execute().plot()
150
166
  ```
151
167
 
168
+ A process that changed on purpose gets its own limits for each stage with `phased=True`:
169
+
170
+ ```python
171
+ import processbehavior as pb
172
+
173
+ # The bundled coffee-shop data: a new machine in week 8, a new POS in week 12, new baristas from week 14
174
+ pbd = pb.load_coffee_shop().bin('week', method='breaks', breaks=[8, 12, 14],
175
+ bin_labels=['baseline', 'new machine', 'new POS', 'new baristas'],
176
+ label='stage')
177
+ staged = pbd.formulate(response='wait_sec', factors=['stage'], time='date').execute(chart='Xbar', phased=True, companion=True)
178
+ staged.phase_statistics('Xbar') # one row per stage: center, S-bar, sigma-hat, limits
179
+ staged.plot(chart='Xbar', title='Wait time: limits per stage')
180
+ ```
181
+
152
182
  Use `pb.ProcessBehavior(df)` directly when you want the fluent derived-variable verbs
153
183
  (`.transform(...)`, `.bin(...)`), which attach before formulating. With that object in hand,
154
184
  `pbd.cols.<column_name>` provides IDE auto-completion for column references.
@@ -231,17 +261,16 @@ for stratum in result.strata:
231
261
 
232
262
  ## Validation
233
263
 
234
- processbehavior's analytical outputs are continuously verified against Dr. Thomas A. Bishop's Minitab reference results. The validator at `validation/e2e_bishop_report.py` runs **280 numerical assertions** through the full formulate → execute → capability / loss / maximum-information pipeline:
235
-
236
- | Analytical Design State | Datasets validated | Assertions | Status |
237
- |---|---|---|---|
238
- | ADS 1 (full replication) | `PM SDS 1` from `PBTESTDATABASE_T100.csv` | 102 | ✅ all pass |
239
- | ADS 2 (no replication) | `PM SDS 2` | 89 | ✅ all pass |
240
- | ADS 3 (partial replication) | `PM SDS 3` | 89 | ✅ all pass |
264
+ processbehavior's analytical outputs are verified against Dr. Thomas A. Bishop's VAS (Minitab-based) reference results on every push. The validator at `validation/e2e_bishop_report.py` runs **1,547 numerical assertions** through the full formulate → execute → capability / loss pipeline, across 14 of his VAS runs:
241
265
 
242
- Reference data is Bishop's published Minitab golden output. The library matches every chart center, control limit, signal classification, capability index, and loss-function value to within the precision Bishop reports.
266
+ | VAS runs | Data | Analytical design states | Assertions | Status |
267
+ |---|---|---|---|---|
268
+ | `PM SDS 1`–`6` | `PBTESTDATABASE_T100.csv` | ADS 1, 2, 3 | 630 | ✅ all pass |
269
+ | `PM INERT SDS 1`–`6` (pure noise) | `PBTESTDATABASE_T100.csv` | ADS 1, 2, 3 | 630 | ✅ all pass |
270
+ | `PM SDS 1 KNOWN` (known effects) | `PBTESTKNOWNEFFECTS_T100.csv` | ADS 1 | 101 | ✅ all pass |
271
+ | `Medicare ACO (PCE)` | `aco_per_capita_expenditure.csv` | ADS 2 | 186 | ✅ all pass |
243
272
 
244
- ODS 4–6 (incomplete-grid scenarios) are detected and routed correctly but their end-to-end Bishop-reference coverage is pending. The synthetic generators in `make_design(state=4|5|6)` produce data with the structural shape Bishop's Table 1 specifies; full numerical validation against Bishop's incomplete-grid Minitab output is on the roadmap (issue #109).
273
+ Reference data is Bishop's VAS output for the 10-12-2026 manual (his runs of October 2026). The library matches every chart center, control limit, capability index and loss-function value that output prints, to within the precision Bishop reports. Where subgroup sizes differ, VAS prints "UNEQUAL" instead of a limit; there every subgroup's limits are read from the limit lines VAS draws and compared one by one. SDS 4–6 are incomplete grids (ODS 4–6), checked as the complete design that survives tidying (ADS 1–3). Four values, the factor S-chart limits of the known-effects run, wait for a VAS rerun. The per-run table is in `docs/reference/validation.md`.
245
274
 
246
275
  The full report renders to `validation/e2e_bishop_report.html`.
247
276
 
@@ -252,6 +281,7 @@ The full report renders to `validation/e2e_bishop_report.html`.
252
281
  - **Variance decomposition**: R1-R6 residuals for factorial designs
253
282
  - **Effects analysis**: Main effects, time effects, and interaction effects
254
283
  - **Stratified charts**: Automatic per-stratum limits for grouped individual data
284
+ - **Staged charts**: `phased=True` gives each stage its own center and limits on X/mR and Xbar/S; `phase_statistics()` returns the numbers behind the steps
255
285
  - **Signal detection**: all eight Western Electric rules on X/mR; Rule 1 (3-sigma) on Xbar/S, where the run- and zone-based rules need a time order that subgroup comparisons don't have
256
286
  - **Beyond the charts**: capability indices (Cp/Cpk/Pp/Ppk), Taguchi loss decomposition, and maximum-information analysis — validated in the same Bishop-reference CI gate
257
287
  - **IDE support**: Column auto-completion via `ProcessBehavior(df).cols`
@@ -6,7 +6,7 @@
6
6
  [![codecov](https://codecov.io/gh/cnicholas/processbehavior/graph/badge.svg)](https://codecov.io/gh/cnicholas/processbehavior)
7
7
  [![License](https://img.shields.io/pypi/l/processbehavior.svg)](https://github.com/cnicholas/processbehavior/blob/main/LICENSE)
8
8
 
9
- A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variance Analysis System (VAS) methodology.
9
+ A Python library for **Process Behavior Analysis** following Thomas A. Bishop's Variation Analysis System (VAS) methodology.
10
10
 
11
11
  Unlike traditional SPC packages, processbehavior faithfully implements Bishop's VAS equation-by-equation: automatic detection of the three-state design lineage (PDS / ODS / ADS), variance decomposition via R1-R6 residuals, and chart selection routed by the data your study can actually analyze.
12
12
 
@@ -25,6 +25,22 @@ pip install "processbehavior[images]" # kaleido, for static plot images
25
25
 
26
26
  ## Quickstart
27
27
 
28
+ A column of values, charted in the order received, is an X/mR chart in two calls:
29
+
30
+ ```python
31
+ import pandas as pd
32
+ import processbehavior as pb
33
+
34
+ df = pd.DataFrame({'weight': [50.2, 49.8, 50.5, 50.1, 49.6, 50.9, 50.3, 49.9, 50.4, 50.0, 49.7, 50.6]})
35
+
36
+ study = pb.formulate(df, response='weight') # no time column: rows are numbered 1..N as 'Observation'
37
+ result = study.execute(companion=True) # X chart with its mR companion
38
+ print(result.statistics('X')) # {'N': 1, 'center': 50.167, 'lpl': 48.619, 'upl': 51.714}
39
+ result.plot()
40
+ ```
41
+
42
+ When the data has a time order, factors, or both, name them. The design state routes the analysis:
43
+
28
44
  ```python
29
45
  import processbehavior as pb
30
46
 
@@ -66,6 +82,20 @@ The whole pipeline is one expression when you don't need the intermediate object
66
82
  pb.formulate(df, response='y', factors=['factor 1'], time='time').execute().plot()
67
83
  ```
68
84
 
85
+ A process that changed on purpose gets its own limits for each stage with `phased=True`:
86
+
87
+ ```python
88
+ import processbehavior as pb
89
+
90
+ # The bundled coffee-shop data: a new machine in week 8, a new POS in week 12, new baristas from week 14
91
+ pbd = pb.load_coffee_shop().bin('week', method='breaks', breaks=[8, 12, 14],
92
+ bin_labels=['baseline', 'new machine', 'new POS', 'new baristas'],
93
+ label='stage')
94
+ staged = pbd.formulate(response='wait_sec', factors=['stage'], time='date').execute(chart='Xbar', phased=True, companion=True)
95
+ staged.phase_statistics('Xbar') # one row per stage: center, S-bar, sigma-hat, limits
96
+ staged.plot(chart='Xbar', title='Wait time: limits per stage')
97
+ ```
98
+
69
99
  Use `pb.ProcessBehavior(df)` directly when you want the fluent derived-variable verbs
70
100
  (`.transform(...)`, `.bin(...)`), which attach before formulating. With that object in hand,
71
101
  `pbd.cols.<column_name>` provides IDE auto-completion for column references.
@@ -148,17 +178,16 @@ for stratum in result.strata:
148
178
 
149
179
  ## Validation
150
180
 
151
- processbehavior's analytical outputs are continuously verified against Dr. Thomas A. Bishop's Minitab reference results. The validator at `validation/e2e_bishop_report.py` runs **280 numerical assertions** through the full formulate → execute → capability / loss / maximum-information pipeline:
152
-
153
- | Analytical Design State | Datasets validated | Assertions | Status |
154
- |---|---|---|---|
155
- | ADS 1 (full replication) | `PM SDS 1` from `PBTESTDATABASE_T100.csv` | 102 | ✅ all pass |
156
- | ADS 2 (no replication) | `PM SDS 2` | 89 | ✅ all pass |
157
- | ADS 3 (partial replication) | `PM SDS 3` | 89 | ✅ all pass |
181
+ processbehavior's analytical outputs are verified against Dr. Thomas A. Bishop's VAS (Minitab-based) reference results on every push. The validator at `validation/e2e_bishop_report.py` runs **1,547 numerical assertions** through the full formulate → execute → capability / loss pipeline, across 14 of his VAS runs:
158
182
 
159
- Reference data is Bishop's published Minitab golden output. The library matches every chart center, control limit, signal classification, capability index, and loss-function value to within the precision Bishop reports.
183
+ | VAS runs | Data | Analytical design states | Assertions | Status |
184
+ |---|---|---|---|---|
185
+ | `PM SDS 1`–`6` | `PBTESTDATABASE_T100.csv` | ADS 1, 2, 3 | 630 | ✅ all pass |
186
+ | `PM INERT SDS 1`–`6` (pure noise) | `PBTESTDATABASE_T100.csv` | ADS 1, 2, 3 | 630 | ✅ all pass |
187
+ | `PM SDS 1 KNOWN` (known effects) | `PBTESTKNOWNEFFECTS_T100.csv` | ADS 1 | 101 | ✅ all pass |
188
+ | `Medicare ACO (PCE)` | `aco_per_capita_expenditure.csv` | ADS 2 | 186 | ✅ all pass |
160
189
 
161
- ODS 4–6 (incomplete-grid scenarios) are detected and routed correctly but their end-to-end Bishop-reference coverage is pending. The synthetic generators in `make_design(state=4|5|6)` produce data with the structural shape Bishop's Table 1 specifies; full numerical validation against Bishop's incomplete-grid Minitab output is on the roadmap (issue #109).
190
+ Reference data is Bishop's VAS output for the 10-12-2026 manual (his runs of October 2026). The library matches every chart center, control limit, capability index and loss-function value that output prints, to within the precision Bishop reports. Where subgroup sizes differ, VAS prints "UNEQUAL" instead of a limit; there every subgroup's limits are read from the limit lines VAS draws and compared one by one. SDS 4–6 are incomplete grids (ODS 4–6), checked as the complete design that survives tidying (ADS 1–3). Four values, the factor S-chart limits of the known-effects run, wait for a VAS rerun. The per-run table is in `docs/reference/validation.md`.
162
191
 
163
192
  The full report renders to `validation/e2e_bishop_report.html`.
164
193
 
@@ -169,6 +198,7 @@ The full report renders to `validation/e2e_bishop_report.html`.
169
198
  - **Variance decomposition**: R1-R6 residuals for factorial designs
170
199
  - **Effects analysis**: Main effects, time effects, and interaction effects
171
200
  - **Stratified charts**: Automatic per-stratum limits for grouped individual data
201
+ - **Staged charts**: `phased=True` gives each stage its own center and limits on X/mR and Xbar/S; `phase_statistics()` returns the numbers behind the steps
172
202
  - **Signal detection**: all eight Western Electric rules on X/mR; Rule 1 (3-sigma) on Xbar/S, where the run- and zone-based rules need a time order that subgroup comparisons don't have
173
203
  - **Beyond the charts**: capability indices (Cp/Cpk/Pp/Ppk), Taguchi loss decomposition, and maximum-information analysis — validated in the same Bishop-reference CI gate
174
204
  - **IDE support**: Column auto-completion via `ProcessBehavior(df).cols`
@@ -2,7 +2,7 @@
2
2
  ProcessBehavior - Statistical Process Control for Python
3
3
 
4
4
  A Pythonic library for process behavior analysis following Bishop's
5
- Variance Analysis System (VAS). The library models the data lifecycle
5
+ Variation Analysis System (VAS). The library models the data lifecycle
6
6
  through three design states and routes analysis by what your data
7
7
  actually supports:
8
8
 
@@ -47,7 +47,7 @@ its ``.sds`` field. Internally some modules still use the legacy "SDS"
47
47
  prefix (e.g. ``sds_detector.py``); the model itself is three-state.
48
48
  """
49
49
 
50
- __version__ = '0.3.3'
50
+ __version__ = '0.5.0'
51
51
 
52
52
  # Result object
53
53
  from processbehavior.analysis_result import AnalysisResult