| name | control-chart-analyzer |
| description | Statistical process control chart creation and analysis skill with control limit calculation and special cause detection. |
| allowed-tools | Bash(*) Read Write Edit Glob Grep WebFetch |
| metadata | {"author":"babysitter-sdk","version":"1.0.0","category":"quality-engineering","backlog-id":"SK-IE-014"} |
| graph | {"domains":["domain:industrial-engineering"],"skillAreas":["skill-area:statistical-analysis","skill-area:organizational-design","skill-area:data-analysis"],"roles":["role:operations-analyst","role:research-engineer"]} |
control-chart-analyzer
You are control-chart-analyzer - a specialized skill for creating and analyzing statistical process control charts with control limit calculation and special cause detection.
Overview
This skill enables AI-powered SPC analysis including:
- X-bar and R chart generation
- X-bar and S chart for large subgroups
- Individual and Moving Range (I-MR) charts
- p-chart and np-chart for attribute data
- c-chart and u-chart for defects
- Control limit calculation (3-sigma)
- Nelson rules detection
- Western Electric rules application
- Out-of-control pattern identification
Prerequisites
- Python 3.8+ with numpy, scipy, matplotlib
- Process measurement data
- Understanding of SPC principles
Capabilities
1. X-bar and R Charts
import numpy as np
from scipy import stats
A2 = {2: 1.880, 3: 1.023, 4: 0.729, 5: 0.577, 6: 0.483, 7: 0.419,
8: 0.373, 9: 0.337, 10: 0.308}
D3 = {2: 0, 3: 0, 4: 0, 5: 0, 6: 0, 7: 0.076, 8: 0.136, 9: 0.184, 10: 0.223}
D4 = {2: 3.267, 3: 2.574, 4: 2.282, 5: 2.114, 6: 2.004, 7: 1.924,
8: 1.864, 9: 1.816, 10: 1.777}
():
n = subgroup_size
subgroups = np.array(data)
xbars = np.mean(subgroups, axis=)
ranges = np.ptp(subgroups, axis=)
xbar_bar = np.mean(xbars)
r_bar = np.mean(ranges)
xbar_ucl = xbar_bar + A2[n] * r_bar
xbar_lcl = xbar_bar - A2[n] * r_bar
r_ucl = D4[n] * r_bar
r_lcl = D3[n] * r_bar
{
: {
: xbar_bar,
: xbar_ucl,
: xbar_lcl,
: xbars.tolist()
},
: {
: r_bar,
: r_ucl,
: r_lcl,
: ranges.tolist()
},
: n,
: (subgroups)
}
2. Individual and Moving Range (I-MR) Chart
def imr_chart(data):
"""
Create Individual and Moving Range chart
For individual observations (subgroup size = 1)
"""
x = np.array(data)
n = len(x)
mr = np.abs(np.diff(x))
x_bar = np.mean(x)
mr_bar = np.mean(mr)
d2 = 1.128
sigma_hat = mr_bar / d2
x_ucl = x_bar + 3 * sigma_hat
x_lcl = x_bar - 3 * sigma_hat
mr_ucl = 3.267 * mr_bar
mr_lcl = 0
return {
"i_chart": {
"center_line": x_bar,
"ucl": x_ucl,
"lcl": x_lcl,
"data": x.tolist(),
"sigma_estimate": sigma_hat
},
"mr_chart": {
"center_line": mr_bar,
"ucl": mr_ucl,
"lcl": mr_lcl,
"data": mr.tolist()
},
"num_observations": n
}
3. Attribute Charts (p-chart, np-chart)
def p_chart(defectives, sample_sizes):
"""
p-chart for proportion defective
Variable sample sizes supported
"""
defectives = np.array(defectives)
n = np.array(sample_sizes)
p = defectives / n
p_bar = np.sum(defectives) / np.sum(n)
ucl = p_bar + 3 * np.sqrt(p_bar * (1 - p_bar) / n)
lcl = np.maximum(0, p_bar - 3 * np.sqrt(p_bar * (1 - p_bar) / n))
return {
"center_line": p_bar,
"ucl": ucl.tolist(),
"lcl": lcl.tolist(),
"data": p.tolist(),
"sample_sizes": n.tolist()
}
def np_chart(defectives, sample_size):
"""
np-chart for number defective
Constant sample size
"""
defectives = np.array(defectives)
n = sample_size
np_bar = np.mean(defectives)
p_bar = np_bar / n
ucl = np_bar + 3 * np.sqrt(np_bar * (1 - p_bar))
lcl = max(0, np_bar - 3 * np.sqrt(np_bar * (1 - p_bar)))
return {
"center_line": np_bar,
"ucl": ucl,
"lcl": lcl,
"data": defectives.tolist(),
"sample_size": n,
"p_bar": p_bar
}
4. c-chart and u-chart
def c_chart(defects):
"""
c-chart for count of defects
Constant inspection unit size
"""
c = np.array(defects)
c_bar = np.mean(c)
ucl = c_bar + 3 * np.sqrt(c_bar)
lcl = max(0, c_bar - 3 * np.sqrt(c_bar))
return {
"center_line": c_bar,
"ucl": ucl,
"lcl": lcl,
"data": c.tolist()
}
def u_chart(defects, unit_sizes):
"""
u-chart for defects per unit
Variable inspection unit sizes
"""
defects = np.array(defects)
n = np.array(unit_sizes)
u = defects / n
u_bar = np.sum(defects) / np.sum(n)
ucl = u_bar + 3 * np.sqrt(u_bar / n)
lcl = np.maximum(0, u_bar - 3 * np.sqrt(u_bar / n))
return {
"center_line": u_bar,
"ucl": ucl.tolist(),
"lcl": lcl.tolist(),
"data": u.tolist(),
"unit_sizes": n.tolist()
}
5. Nelson Rules Detection
def detect_nelson_rules(data, center_line, ucl, lcl):
"""
Detect all 8 Nelson rules for special cause variation
"""
x = np.array(data)
sigma = (ucl - center_line) / 3
violations = {
"rule_1": [],
"rule_2": [],
"rule_3": [],
"rule_4": [],
"rule_5": [],
"rule_6": [],
"rule_7": [],
"rule_8": []
}
n = len(x)
for i in range(n):
if x[i] > ucl or x[i] < lcl:
violations["rule_1"].append(i)
for i in range(n - 8):
window = x[i:i+9]
if all(w > center_line for w in window) or all(w < center_line for w in window):
violations["rule_2"].append(i)
i (n - ):
window = x[i:i+]
diffs = np.diff(window)
(d > d diffs) (d < d diffs):
violations[].append(i)
i (n - ):
window = x[i:i+]
diffs = np.diff(window)
alternating = (diffs[j] * diffs[j+] < j ((diffs)-))
alternating:
violations[].append(i)
two_sigma_up = center_line + * sigma
two_sigma_down = center_line - * sigma
i (n - ):
window = x[i:i+]
above = ( w window w > two_sigma_up)
below = ( w window w < two_sigma_down)
above >= below >= :
violations[].append(i)
one_sigma_up = center_line + sigma
one_sigma_down = center_line - sigma
i (n - ):
window = x[i:i+]
above = ( w window w > one_sigma_up)
below = ( w window w < one_sigma_down)
above >= below >= :
violations[].append(i)
i (n - ):
window = x[i:i+]
(one_sigma_down < w < one_sigma_up w window):
violations[].append(i)
i (n - ):
window = x[i:i+]
(w > one_sigma_up w < one_sigma_down w window):
violations[].append(i)
violations
():
interpretations = {
: ,
: ,
: ,
: ,
: ,
: ,
: ,
:
}
findings = []
rule, indices violations.items():
indices:
findings.append({
: rule,
: (indices),
: indices[:],
: interpretations[rule]
})
findings
6. Process Stability Assessment
def assess_process_stability(chart_data, violations):
"""
Overall assessment of process stability
"""
total_violations = sum(len(v) for v in violations.values())
n_points = len(chart_data['data'])
out_of_control_points = set()
for rule, indices in violations.items():
out_of_control_points.update(indices)
pct_in_control = (n_points - len(out_of_control_points)) / n_points * 100
assessment = {
"total_points": n_points,
"out_of_control_points": len(out_of_control_points),
"percent_in_control": pct_in_control,
"total_rule_violations": total_violations,
"stability_status": "",
"recommendations": []
}
if pct_in_control >= 99:
assessment["stability_status"] = "Stable - Process in statistical control"
assessment["recommendations"].append("Process is stable - proceed with capability analysis")
elif pct_in_control >= 95:
assessment["stability_status"] = "Mostly stable - Minor instabilities detected"
assessment["recommendations"].append("Investigate recent out-of-control points")
elif pct_in_control >= 90:
assessment["stability_status"] = "Unstable - Multiple special causes present"
assessment[].append()
:
assessment[] =
assessment[].append()
assessment
Process Integration
This skill integrates with the following processes:
statistical-process-control-implementation.js
root-cause-analysis-investigation.js
oee-improvement.js
Output Format
{
"chart_type": "X-bar and R",
"subgroup_size": 5,
"num_subgroups": 25,
"xbar_chart": {
"center_line": 50.2,
"ucl": 52.8,
"lcl": 47.6
},
"r_chart": {
"center_line": 4.5,
"ucl": 9.5,
"lcl": 0
},
"violations": {
"rule_1": 2,
"rule_2": 1
},
"stability_status":
Best Practices
- Collect sufficient data - Minimum 25 subgroups for initial limits
- Choose appropriate chart - Match chart to data type
- Apply rules consistently - Use agreed-upon detection rules
- Investigate all signals - Every out-of-control point has a cause
- Recalculate after improvement - Update limits when process changes
- Train operators - Enable real-time response
Constraints
- Control limits from in-control data only
- Document all rule sets used
- Distinguish common vs special cause
- Never adjust process based on common cause