IVD质量控制实施¶
质量控制概述¶
质量控制(Quality Control, QC)是确保IVD检测结果准确性和可靠性的关键过程,通过定期使用已知浓度的质控品来监测分析系统的性能。
Westgard规则¶
规则实现¶
class WestgardRules:
"""Westgard多规则质控"""
def __init__(self, mean, std_dev):
self.mean = mean
self.std_dev = std_dev
self.control_limits = {
"1s": (mean - std_dev, mean + std_dev),
"2s": (mean - 2*std_dev, mean + 2*std_dev),
"3s": (mean - 3*std_dev, mean + 3*std_dev)
}
def check_1_2s(self, value):
"""1_2s规则:单个值超过±2SD(警告规则)"""
lower_2s, upper_2s = self.control_limits["2s"]
return value < lower_2s or value > upper_2s
def check_1_3s(self, value):
"""1_3s规则:单个值超过±3SD(拒绝规则)"""
lower_3s, upper_3s = self.control_limits["3s"]
return value < lower_3s or value > upper_3s
def check_2_2s(self, values):
"""2_2s规则:连续2个值超过同侧±2SD"""
if len(values) < 2:
return False
lower_2s, upper_2s = self.control_limits["2s"]
# 检查最后两个值
last_two = values[-2:]
# 两个都在上侧
if all(v > upper_2s for v in last_two):
return True
# 两个都在下侧
if all(v < lower_2s for v in last_two):
return True
return False
def check_R_4s(self, values):
"""R_4s规则:一个值超过+2SD,另一个超过-2SD(范围>4SD)"""
if len(values) < 2:
return False
lower_2s, upper_2s = self.control_limits["2s"]
# 检查最后两个值
last_two = values[-2:]
# 一个在上侧,一个在下侧
if (last_two[0] > upper_2s and last_two[1] < lower_2s) or \
(last_two[0] < lower_2s and last_two[1] > upper_2s):
return True
return False
def check_4_1s(self, values):
"""4_1s规则:连续4个值超过同侧±1SD"""
if len(values) < 4:
return False
lower_1s, upper_1s = self.control_limits["1s"]
# 检查最后四个值
last_four = values[-4:]
# 四个都在上侧
if all(v > upper_1s for v in last_four):
return True
# 四个都在下侧
if all(v < lower_1s for v in last_four):
return True
return False
def check_10_x(self, values):
"""10_x规则:连续10个值在均值同侧"""
if len(values) < 10:
return False
# 检查最后10个值
last_ten = values[-10:]
# 十个都在上侧
if all(v > self.mean for v in last_ten):
return True
# 十个都在下侧
if all(v < self.mean for v in last_ten):
return True
return False
def evaluate(self, values):
"""评估质控数据"""
if not values:
return QCResult(status="NO_DATA")
current_value = values[-1]
# 按顺序应用规则
violations = []
# 1_3s - 最严重,立即拒绝
if self.check_1_3s(current_value):
violations.append("1_3s")
return QCResult(
status="REJECT",
violations=violations,
action="停止检测,调查原因"
)
# 1_2s - 警告规则,需要检查其他规则
if self.check_1_2s(current_value):
violations.append("1_2s")
# 检查其他规则
if self.check_2_2s(values):
violations.append("2_2s")
if self.check_R_4s(values):
violations.append("R_4s")
if self.check_4_1s(values):
violations.append("4_1s")
if self.check_10_x(values):
violations.append("10_x")
# 如果触发了其他规则,拒绝
if len(violations) > 1:
return QCResult(
status="REJECT",
violations=violations,
action="停止检测,调查原因"
)
else:
return QCResult(
status="WARNING",
violations=violations,
action="继续检测,密切监控"
)
# 没有违反任何规则
return QCResult(
status="ACCEPT",
violations=[],
action="继续正常检测"
)
质控品管理¶
质控品追踪¶
class QualityControlMaterialManagement:
"""质控品管理"""
def __init__(self):
self.qc_materials = {}
self.qc_results = []
def register_qc_material(self, material):
"""注册质控品"""
qc_lot = QCLot(
lot_number=material.lot_number,
analyte=material.analyte,
level=material.level, # Level 1, 2, 3
target_value=material.target_value,
acceptable_range=material.acceptable_range,
expiration_date=material.expiration_date,
opened_date=None,
stability_after_opening_days=material.stability_days
)
self.qc_materials[material.lot_number] = qc_lot
return qc_lot
def open_qc_material(self, lot_number):
"""开启质控品"""
qc_lot = self.qc_materials[lot_number]
qc_lot.opened_date = datetime.now()
# 计算失效日期
expiry_after_opening = qc_lot.opened_date + timedelta(
days=qc_lot.stability_after_opening_days
)
# 使用较早的日期
qc_lot.effective_expiration = min(
qc_lot.expiration_date,
expiry_after_opening
)
return qc_lot
def check_qc_validity(self, lot_number):
"""检查质控品有效性"""
qc_lot = self.qc_materials[lot_number]
# 检查是否过期
if datetime.now() > qc_lot.effective_expiration:
raise QCMaterialExpired(f"质控品{lot_number}已过期")
# 检查是否已开启
if qc_lot.opened_date is None:
raise QCMaterialNotOpened(f"质控品{lot_number}未开启")
return True
质控图表¶
Levey-Jennings图¶
class LeveyJenningsChart:
"""Levey-Jennings质控图"""
def __init__(self, analyte, level, target_mean, target_sd):
self.analyte = analyte
self.level = level
self.target_mean = target_mean
self.target_sd = target_sd
self.data_points = []
def add_data_point(self, value, timestamp):
"""添加数据点"""
data_point = QCDataPoint(
value=value,
timestamp=timestamp,
z_score=(value - self.target_mean) / self.target_sd
)
self.data_points.append(data_point)
return data_point
def plot_chart(self, num_points=30):
"""绘制质控图"""
recent_points = self.data_points[-num_points:]
chart = {
"title": f"{self.analyte} - Level {self.level}",
"x_axis": [p.timestamp for p in recent_points],
"y_axis": [p.value for p in recent_points],
"mean_line": self.target_mean,
"control_limits": {
"+3SD": self.target_mean + 3 * self.target_sd,
"+2SD": self.target_mean + 2 * self.target_sd,
"+1SD": self.target_mean + 1 * self.target_sd,
"Mean": self.target_mean,
"-1SD": self.target_mean - 1 * self.target_sd,
"-2SD": self.target_mean - 2 * self.target_sd,
"-3SD": self.target_mean - 3 * self.target_sd
}
}
return chart
def calculate_statistics(self, period_days=30):
"""计算统计数据"""
cutoff_date = datetime.now() - timedelta(days=period_days)
recent_data = [
p.value for p in self.data_points
if p.timestamp >= cutoff_date
]
if not recent_data:
return None
stats = {
"n": len(recent_data),
"mean": np.mean(recent_data),
"std_dev": np.std(recent_data, ddof=1),
"cv_percent": (np.std(recent_data, ddof=1) / np.mean(recent_data)) * 100,
"min": np.min(recent_data),
"max": np.max(recent_data),
"range": np.max(recent_data) - np.min(recent_data)
}
return stats
内部质控(IQC)¶
日常质控流程¶
class InternalQualityControl:
"""内部质控"""
def __init__(self):
self.westgard_rules = {}
self.qc_schedule = QCSchedule()
def run_daily_qc(self, instrument_id, date):
"""运行日常质控"""
qc_results = []
# 获取该仪器的质控计划
qc_tests = self.qc_schedule.get_tests_for_instrument(instrument_id, date)
for test in qc_tests:
# 运行质控测试
result = self.run_qc_test(test)
# 评估结果
evaluation = self.evaluate_qc_result(result)
qc_results.append({
"test": test,
"result": result,
"evaluation": evaluation
})
# 如果质控失败,停止
if evaluation.status == "REJECT":
self.handle_qc_failure(test, result, evaluation)
break
# 生成质控报告
report = self.generate_qc_report(instrument_id, date, qc_results)
return report
def run_qc_test(self, test):
"""运行质控测试"""
# 获取质控品
qc_material = self.get_qc_material(test.lot_number)
# 检查有效性
self.check_qc_validity(qc_material)
# 运行测试
measured_value = self.measure_qc_sample(
qc_material,
test.analyte,
test.method
)
return QCResult(
analyte=test.analyte,
level=qc_material.level,
measured_value=measured_value,
target_value=qc_material.target_value,
acceptable_range=qc_material.acceptable_range,
timestamp=datetime.now()
)
def evaluate_qc_result(self, result):
"""评估质控结果"""
# 获取该分析物的Westgard规则
rules = self.westgard_rules.get(result.analyte)
if rules is None:
# 如果没有建立规则,使用简单的范围检查
return self.simple_range_check(result)
# 获取历史数据
historical_data = self.get_historical_qc_data(
result.analyte,
result.level,
days=30
)
# 添加当前值
all_values = historical_data + [result.measured_value]
# 应用Westgard规则
evaluation = rules.evaluate(all_values)
return evaluation
def handle_qc_failure(self, test, result, evaluation):
"""处理质控失败"""
# 1. 停止患者样本检测
self.stop_patient_testing(test.instrument_id)
# 2. 记录事件
self.log_qc_failure(test, result, evaluation)
# 3. 通知相关人员
self.notify_supervisor(test, result, evaluation)
# 4. 启动调查程序
investigation = self.initiate_investigation(test, result, evaluation)
return investigation
外部质量评估(EQA)¶
室间质评管理¶
class ExternalQualityAssessment:
"""外部质量评估"""
def __init__(self):
self.eqa_provider = "CAP" # College of American Pathologists
self.eqa_results = []
def process_eqa_sample(self, eqa_sample):
"""处理室间质评样本"""
# 像患者样本一样测试
result = self.test_sample(
sample_id=eqa_sample.id,
analyte=eqa_sample.analyte,
method=eqa_sample.method
)
# 记录结果
eqa_result = EQAResult(
provider=self.eqa_provider,
survey_id=eqa_sample.survey_id,
sample_id=eqa_sample.id,
analyte=eqa_sample.analyte,
reported_value=result.value,
reported_unit=result.unit,
method=eqa_sample.method,
instrument=result.instrument,
test_date=datetime.now()
)
self.eqa_results.append(eqa_result)
# 提交结果
self.submit_eqa_result(eqa_result)
return eqa_result
def evaluate_eqa_performance(self, survey_id):
"""评估室间质评表现"""
# 接收评估报告
report = self.receive_eqa_report(survey_id)
performance = {
"survey_id": survey_id,
"analytes": {}
}
for analyte_result in report.results:
# 计算SDI (Standard Deviation Index)
sdi = (analyte_result.lab_value - analyte_result.peer_mean) / \
analyte_result.peer_sd
# 评估表现
if abs(sdi) <= 2.0:
status = "ACCEPTABLE"
elif abs(sdi) <= 3.0:
status = "WARNING"
else:
status = "UNACCEPTABLE"
performance["analytes"][analyte_result.analyte] = {
"lab_value": analyte_result.lab_value,
"peer_mean": analyte_result.peer_mean,
"peer_sd": analyte_result.peer_sd,
"sdi": sdi,
"status": status
}
# 如果有不可接受的结果,启动纠正措施
unacceptable = [
a for a, r in performance["analytes"].items()
if r["status"] == "UNACCEPTABLE"
]
if unacceptable:
self.initiate_corrective_action(survey_id, unacceptable)
return performance
相关资源¶
参考标准¶
- CLSI C24-A3: 统计质量控制
- CLSI EP23: 实验室质量控制
- ISO 15189: 医学实验室质量和能力要求
- Westgard QC: 质量控制规则和程序
💬 讨论区
欢迎在这里分享您的想法、提出问题或参与讨论。需要 GitHub 账号登录。