Skip to main content
Version: 3.0.1

Inhibition Rules Design

Document Type: Rule Design (Tier 2) Domain: RULES-INHIBITION Domain Character: Algorithmic SRS References: rule-inhibition-ct.md, rule-inhibition-qualitative.md, rule-inhibition-quantification.md, rule-inhibition-serum-quantitative.md, rule-systemic-inhibition.md, rule-negative-control-inhibition.md, rule-icct.md, rule-ic-qual-serum.md Status: Draft Last Updated: 2026-01-25


1. Overview

1.0 Rule Summary

PropertyValue
IntentDetect potential PCR inhibition by evaluating Internal Control (IC) CT values, comparing against negative control baselines, and applying specimen-type and sample-type specific logic to assign appropriate error codes. The family includes: INH (baseline comparison), PICQUAL/BICQUAL (qualitative), PICQUANT/BIC (quantification), serum variants, and systemic detection.
InputsWell observations (IC CT, non-IC CT, quantities), Negative control wells, Kit configuration (ct_inhibition_delta, LoD, cutoffs), Sample testing history, Well association data (mix, extraction, date, batch)
OutputsProblem codes (IC_FAILED), Error codes (IC_RULE_NO_NC_IN_RUN, ICQUAL_INHN, ICQUAL_FIRST_RUN, ICQUANT_INHN, ICQUANT_INHP, ICQUANT_FIRST_RUN, BICQUAL_WELL, BICQUAL_TARGET, SYSTEMIC_INHIBITON_DETECTED)
PrecedenceINH executes early (within IC combined outcomes); PICQUAL/PICQUANT after INH; SYSTEMIC_INHIBITION after individual well errors assigned

1.1 Purpose

The Inhibition Rules family detects when PCR reactions are suppressed by interfering substances, ensuring unreliable results are flagged before reporting. Inhibition can produce false negatives or inaccurate quantification.

The family includes:

RuleCodePurpose
INHInhRuleBaseline comparison against negative control IC CT
PICQUALPicqualRuleQualitative sample inhibition with repeat/first-run tracking
PICQUANTPicquantRuleQuantification sample inhibition with quantity compensation
PICQUAL_SERUMPicqualSerumRuleSerum specimen qualitative inhibition
PICQUANT_SERUMPicquantSerumRuleSerum specimen quantification inhibition
BICQUALBicqualRuleNegative Extraction Control inhibition (well + target errors)
BICBicRuleBlanking inhibition for quantification
SYSTEMIC_INHIBITIONSystemicInhibitionRuleCross-well pattern detection
ICCTIcctRuleFinal CT/CLS resolution (related, provides input values)

1.2 Requirements Covered

REQ IDTitlePriorityRule
REQ-RULES-INHCT-001Flag IC Observation When CT Exceeds ThresholdMustINH
REQ-RULES-INHCT-002Calculate Negative Control IC CT BaselineMustINH
REQ-RULES-INHCT-003Use Fallback Control MixesMustINH
REQ-RULES-INHCT-004Exclude Roles from IC Delta CheckMustINH
REQ-RULES-INHCT-005Assign NO NC IN RUN ErrorMustINH
REQ-RULES-INHQUAL-001Detect Inhibition in Qualitative WellsMustPICQUAL
REQ-RULES-INHQUAL-002Bypass Repeat Check When Quantity Meets CutoffMustPICQUAL
REQ-RULES-INHQUANT-001Evaluate IC Inhibition for Quantification SamplesMustPICQUANT
REQ-RULES-INHSERUMQUANT-001Evaluate IC Inhibition for Serum Quantitative SamplesMustPICQUANT_SERUM
REQ-RULES-SYSINH-001Detect Systemic Inhibition Across Associated WellsMustSYSTEMIC_INHIBITION
REQ-RULES-SYSINH-002Exclude Control Wells from Systemic InhibitionMustSYSTEMIC_INHIBITION
REQ-RULES-SYSINH-003Exclude Detected-Type Wells from ErrorMustSYSTEMIC_INHIBITION
REQ-RULES-NECINH-001Detect Inhibition in NEC WellsMustBICQUAL
REQ-RULES-ICQUALSERUM-001Evaluate IC Validity for Qualitative Serum SamplesMustPICQUAL_SERUM
REQ-RULES-ICCT-001Determine Final CT and CLS Based on Manual InputsMustICCT

1.3 Constraints

Tier 2 Constraint: This document describes ownership, patterns, and design rationale. It links to reference docs for full schemas.

1.4 Dependencies

DirectionComponentPurpose
ConsumesWell + ObservationsWell data with IC CT values
Kit ConfigurationThresholds (ct_inhibition_delta, LoD, cutoffs)
Negative Control WellsBaseline for INH rule
Sample Test HistoryRepeat vs first-run determination
ProducesIC_FAILEDProblem code on observation
Well Error CodesICQUAL_, ICQUANT_, SYSTEMIC_*
Run Target ErrorsBICQUAL_TARGET for NEC failures

2. Component Architecture

2.1 Component Diagram

2.2 Component Responsibilities

ComponentFileResponsibilityREQ Trace
InhRuleAnalyzer/Rules/InhRule.phpNC baseline lookup, CT delta comparison, IC_FAILED assignmentREQ-RULES-INHCT-001 to 005
PicqualRuleAnalyzer/Rules/PicqualRule.phpQualitative inhibition with repeat/first-runREQ-RULES-INHQUAL-001, 002
PicquantRuleAnalyzer/Rules/PicquantRule.phpQuantification inhibition with quantity checkREQ-RULES-INHQUANT-001
PicqualSerumRuleAnalyzer/Rules/PicqualSerumRule.phpSerum-specific qualitative inhibitionREQ-RULES-ICQUALSERUM-001
PicquantSerumRuleAnalyzer/Rules/PicquantSerumRule.phpSerum-specific quantification inhibitionREQ-RULES-INHSERUMQUANT-001
BicqualRuleAnalyzer/Rules/BicqualRule.phpNEC well inhibition (well + target error)REQ-RULES-NECINH-001
BicRuleAnalyzer/Rules/BicRule.phpBlanking inhibition for quantificationREQ-RULES-INHQUANT-001
SystemicInhibitionRuleAnalyzer/Rules/SystemicInhibitionRule.phpCross-well pattern detectionREQ-RULES-SYSINH-001 to 003
SetErrorToWellAnalyzer/Rules/Concerns/SetErrorToWell.phpApply error code to wellAll
AssociateWellComparatorSupport/AssociateWellComparator.phpWell association matchingREQ-RULES-SYSINH-001

3. Data Design

3.1 Entities

This rule family reads from configuration and well data, writes to well records and observations:

EntityOwnerRead/WriteFields Used
wellsRUNRPTRead/WriteIC observations, errors, LIMS status, mix, extraction, batch
observationsRUNRPTRead/Writefinal_ct, final_cls, quantity, problems
run_targetsRUNRPTWriteerrors (for BICQUAL_TARGET)
control_labelsKITCFGReadexclude_from_ic_delta_check, backup_mixes
targetsKITCFGReadct_inhibition_delta, type (IC)

See Database Reference for full schema.

3.2 IC Qualification State

interface InhibitionEvaluationContext {
well: Well;
icObservation: Observation; // IC target observation

// INH Rule inputs
negativeControlWells: Well[];
ncIcCtAverage: number | null; // Calculated baseline
ctInhibitionDelta: number; // From target config

// Sample-type rule inputs
icCtThreshold: number; // Fixed at 35
hasPositiveNonIcObservation: boolean;
quantityValue: number | null;
lodThreshold: number | null;
highQuantThreshold: number; // Fixed at 10,000

// History inputs
hasBeenTestedBefore: boolean; // For repeat/first-run

// Systemic inputs
associatedWells: Well[];
inhibitedWellCount: number;
}

4. Interface Design

4.1 Rule Interface

All inhibition rules implement the standard AnalyzerRuleContract:

interface AnalyzerRuleContract {
public function handle(
ConfigurationRepository $config,
AnalyzableObservation $observation,
RunMix $runMix,
RunTarget $runTarget,
AnalyzableWell $well,
WellCollection $wells,
PatientWellCollection $previousPatientWells,
PecWellCollection $previousPecWells,
RunTargetsCollection $runTargets
): void;
}

4.2 Key Methods

MethodLocationPurpose
getAssociateNegativeControls()WellCollectionFind NC wells for INH baseline
hasLargerDiffBetweenIcTargetObservationAndOtherNegativeControlIcTargetObservations()AnalyzableWellINH delta comparison
finalCtIsLessThanOrEqualToCutoffCt()ObservationIC CT threshold check
quantityIsGreaterThanOrEqualsCutoffQuantity()ObservationHigh quantity bypass
hasMatchingWellForObservation()PatientWellCollectionRepeat sample detection
AssociateWellComparator::compare()SupportSystemic well grouping

4.3 Events

These rules do not emit events. They modify well/observation state directly.


5. Behavioral Design

5.1 INH Rule Algorithm (REQ-RULES-INHCT-001 to 005) {#req-rules-inhct-001} {#req-rules-inhct-002} {#req-rules-inhct-003} {#req-rules-inhct-004}

Algorithm: Evaluate IC CT Against Negative Control Baseline

Inputs:
- well: Well - The patient/sample well being evaluated
- observation: Observation - IC target observation
- wells: WellCollection - All wells in run
- config: ConfigurationRepository - Kit configuration

Outputs:
- void (modifies observation.problems, well.error)

Assumptions:
- Observation is IC-type target
- Negative control wells have been identified

Steps:
1. Resolution bypass: IF well has 'INH' resolution code: RETURN

2. IC target check: IF observation does not have IC target: RETURN

3. Find negative controls:
nc_wells = wells.getAssociateNegativeControls(well, config)

4. No NC error: IF nc_wells is empty:
- Set well.error = IC_RULE_NO_NC_IN_RUN
- RETURN

5. Filter excluded controls:
valid_nc = nc_wells.reject(well =>
well.hasError() OR well.hasResolutionCodes()
)

6. Calculate baseline: nc_average = AVG(valid_nc.ic_ct)

7. Delta comparison:
IF ABS(observation.ic_ct - nc_average) > ct_inhibition_delta:
- Add IC_FAILED problem to observation

Notes:
- Fallback mixes are handled in getAssociateNegativeControls()
- Role exclusion (exclude_from_ic_delta_check) is applied in NC lookup
- Error/resolved controls excluded from baseline calculation

5.1.1 INH Decision Logic

NC AvailableWithin DeltaResult
No*IC_RULE_NO_NC_IN_RUN error
YesYesNo action (pass)
YesNoIC_FAILED problem

Precedence: NC error check before delta calculation. Default: If within delta, no problem assigned.


5.2 PICQUAL Algorithm (REQ-RULES-INHQUAL-001, 002) {#req-rules-inhqual-001}

Algorithm: Evaluate Qualitative Sample Inhibition

Inputs:
- well: Well - Qualitative sample well
- observation: Observation - Target observation
- previousPatientWells: PatientWellCollection - Historical wells

Outputs:
- void (modifies well.error)

Assumptions:
- Well contains IC target observation
- IC CT threshold is 35

Steps:
1. Resolution bypass: IF well has 'PICQUAL' resolution: apply LIMS, RETURN

2. IC CT check: IF ic_observation.final_ct <= 35: RETURN (pass)

3. Positive observation bypass:
IF observation has positive final_cls AND ct < reporting_upper_boundary:
RETURN (pass)

4. Repeat check:
IF previousPatientWells.hasMatchingWellForObservation(observation):
- Set well.error = ICQUAL_RPT
- RETURN

5. First run:
- Set well.error = ICQUAL_FIRST_RUN

5.2.1 PICQUAL Decision Logic

IC CTNon-IC PositiveRepeat SampleResult
<= 35**Pass
> 35Yes (CT < cutoff)*Pass
> 35NoYesICQUAL_RPT (or ICQUAL_INHN)
> 35NoNoICQUAL_FIRST_RUN

Precedence: IC CT check, then positive bypass, then repeat check. Default: First run gets ICQUAL_FIRST_RUN.


5.3 PICQUANT Algorithm (REQ-RULES-INHQUANT-001)

Algorithm: Evaluate Quantification Sample Inhibition

Inputs:
- well: Well - Quantification sample well
- observation: Observation - Target observation
- previousPatientWells: PatientWellCollection - Historical wells

Outputs:
- void (modifies well.error)

Steps:
1. Resolution bypass: IF well has 'PIQUANT' resolution: apply LIMS, RETURN

2. IC pass check: IF ic_observation.ct <= 35 AND ic_observation has positive CLS:
RETURN (pass)

3. High quantity bypass: IF observation.quantity >= cutoff_quantity:
RETURN (pass)

4. Repeat sample with quantity evaluation:
IF previousPatientWells.hasMatchingWellForObservation(observation):
IF observation.quantity < reporting_upper_boundary:
- Set well.error = ICQUANT_INHN
ELSE:
- Set well.error = ICQUANT_INHP
RETURN

5. First run:
- Set well.error = ICQUANT_FIRST_RUN

5.3.1 PICQUANT Decision Logic

IC CTIC CLSQuantityRepeatResult
<= 35Positive**Pass
> 35*>= 10,000*Pass
> 35*< LoDYesICQUANT_INHN
> 35*>= LoD, < 10kYesICQUANT_INHP
> 35*< 10kNoICQUANT_FIRST_RUN

Precedence: IC check, then quantity bypass, then repeat/quantity classification. Default: First run gets ICQUANT_FIRST_RUN.


5.4 Serum Variant Algorithms

The serum variants (PICQUAL_SERUM, PICQUANT_SERUM) follow simplified versions of the base algorithms:

PICQUAL_SERUM (REQ-RULES-ICQUALSERUM-001):

  • Applies only to Serum specimen type
  • IC CT <= 35: Pass
  • IC CT > 35 AND positive non-IC observation: Pass
  • Otherwise: ICQUAL_INHN

PICQUANT_SERUM (REQ-RULES-INHSERUMQUANT-001):

  • Applies only to Serum specimen type
  • IC CT <= 35: Pass
  • IC CT > 35 AND quantity > 10,000: Pass
  • IC CT > 35 AND quantity < LoD: ICQUANT_INHN
  • IC CT > 35 AND quantity between LoD and 10,000: ICQUANT_INHP

5.5 BICQUAL Algorithm (REQ-RULES-NECINH-001)

Algorithm: Detect Negative Extraction Control Inhibition

Inputs:
- well: Well - NEC (Negative Extraction Control) well
- runTarget: RunTarget - Run target for target-level error

Outputs:
- void (modifies well.error, runTarget.errors)

Steps:
1. Resolution bypass: IF well has 'BICQUAL' resolution: apply LIMS, RETURN

2. IC evaluation:
ic_obs = well.getIcTargetObservation()
IF ic_obs.final_ct > cutoff_ct OR ic_obs.final_cls == Negative:
- Set well.error = BICQUAL_WELL
- Add BICQUAL_TARGET to runTarget

5.5.1 BICQUAL Decision Logic

IC Final CTIC Final CLSWell ErrorTarget Error
<= 35PositiveNoneNone
> 35PositiveBICQUAL_WELLBICQUAL_TARGET
nullNegativeBICQUAL_WELLBICQUAL_TARGET

Precedence: Single evaluation. Default: No error if IC passes.


5.6 Systemic Inhibition Algorithm (REQ-RULES-SYSINH-001 to 003) {#req-rules-sysinh-001} {#req-rules-sysinh-002}

Algorithm: Detect Systemic Inhibition Pattern

Inputs:
- well: Well - Current well
- wells: WellCollection - All wells in run

Constants:
- THRESHOLD: 3 (wells required to trigger)

Outputs:
- void (modifies well.error for affected wells)

Steps:
1. Skip conditions: IF well is not patient OR well has no inhibition issues
OR well has detected LIMS: RETURN

2. Find associated patient wells:
associate_wells = wells.filter(w =>
AssociateWellComparator.compare(w, well) AND w.isPatientWell()
)

3. Count inhibited wells:
inhibited = associate_wells.filter(w => w.hasInhibitionIssues())

4. Threshold check: IF inhibited.count < 3: RETURN

5. Get affecting wells (exclude detected LIMS):
affecting = associate_wells.filter(w => !hasDetectedLims(w))

6. Apply error:
FOR each affecting_well:
IF affecting_well has positive observation:
- Set error = INHN
ELSE:
- Set error = SYSTEMIC_INHIBITON_DETECTED

5.6.1 Systemic Inhibition Decision Logic

Patient WellInhibited CountHas Detected LIMSHas Positive ObsResult
No***Skip (control excluded)
Yes< 3**No action
Yes>= 3Yes*Retain LIMS (excluded)
Yes>= 3NoYesINHN
Yes>= 3NoNoSYSTEMIC_INHIBITON_DETECTED

Precedence: Patient check, threshold check, detected exclusion, positive observation check. Default: No error if threshold not met. Detected Types: DETECTED, DETECTED_LOQ, DETECTED_QUANT, DETECTED_HIQ are excluded.

5.6.2 Well Association Criteria

Wells are associated when ALL criteria match:

CriterionComparison
MixSame mix ID
Extraction InstrumentSame instrument
Extraction DateSame date
BatchSame batch ID

6. Error Handling

ConditionRuleDetectionResponse
No negative controlsINHEmpty NC collectionIC_RULE_NO_NC_IN_RUN error
All NCs excluded (role/error)INHEmpty after filterIC_RULE_NO_NC_IN_RUN error
Missing IC observationINHhasIcTarget() falseSkip rule
Missing reporting configPICQUAL/PICQUANTgetFirstGroupReporting nullSkip rule
History unavailablePICQUAL/PICQUANTExceptionTreat as first run
Resolution code presentAllContains checkSkip rule, apply resolution LIMS

7. Configuration

SettingDefaultDescriptionAffects
ct_inhibition_deltaPer targetMax CT deviation from NC baselineINH
ic_ct_threshold35Fixed threshold for IC passPICQUAL, PICQUANT, serum variants
high_quant_threshold10,000Quantity that compensates for inhibitionPICQUANT, PICQUANT_SERUM
exclude_from_ic_delta_checkfalseRole exclusion flagINH
backup_mixes[]Fallback mixes for NC lookupINH
lodPer mix/targetLimit of DetectionPICQUANT variants

See Configuration Reference for full documentation.


8. Implementation Mapping

8.1 Code Locations

ComponentPath
INH RuleAnalyzer/Rules/InhRule.php
PICQUAL RuleAnalyzer/Rules/PicqualRule.php
PICQUANT RuleAnalyzer/Rules/PicquantRule.php
PICQUAL_SERUM RuleAnalyzer/Rules/PicqualSerumRule.php
PICQUANT_SERUM RuleAnalyzer/Rules/PicquantSerumRule.php
BICQUAL RuleAnalyzer/Rules/BicqualRule.php
BIC RuleAnalyzer/Rules/BicRule.php
SYSTEMIC_INHIBITION RuleAnalyzer/Rules/SystemicInhibitionRule.php
SetErrorToWellAnalyzer/Rules/Concerns/SetErrorToWell.php
AssociateWellComparatorSupport/AssociateWellComparator.php

8.2 Requirement Traceability

REQ IDDesign SectionPrimary Code
REQ-RULES-INHCT-001§5.1InhRule.php
REQ-RULES-INHCT-002§5.1InhRule.php, WellCollection.php
REQ-RULES-INHCT-003§5.1WellCollection::getAssociateNegativeControls()
REQ-RULES-INHCT-004§5.1Control label config
REQ-RULES-INHCT-005§5.1InhRule.php line 50
REQ-RULES-INHQUAL-001§5.2PicqualRule.php
REQ-RULES-INHQUAL-002§5.2PicqualRule.php
REQ-RULES-INHQUANT-001§5.3PicquantRule.php
REQ-RULES-INHSERUMQUANT-001§5.4PicquantSerumRule.php
REQ-RULES-SYSINH-001§5.6SystemicInhibitionRule.php
REQ-RULES-SYSINH-002§5.6SystemicInhibitionRule::handle()
REQ-RULES-SYSINH-003§5.6SystemicInhibitionRule::hasDetectedLims()
REQ-RULES-NECINH-001§5.5BicqualRule.php
REQ-RULES-ICQUALSERUM-001§5.4PicqualSerumRule.php
REQ-RULES-ICCT-001RelatedIcctRule.php (provides input values)

9. Design Decisions

DecisionRationaleAlternatives Considered
Separate rules per specimen/sample typeDifferent logic paths, independent testabilitySingle rule with specimen switch (rejected: complex branching)
Fixed IC CT threshold of 35Standard laboratory cutoff for IC validityConfigurable per kit (rejected: unnecessary complexity)
Systemic threshold of 3 wellsBalance between sensitivity and false positivesLower threshold (rejected: too many false alerts), Higher (rejected: miss patterns)
Detected LIMS exclusion from systemicPositive results override inhibition concernInclude all wells (rejected: overrides valid detections)
Typo preservation (INHIBITON)Backward compatibility with existing dataFix typo (rejected: breaks existing records)
Quantity bypass before repeat checkOptimization: skip expensive history lookupAlways check history (rejected: performance impact)

10. Performance Considerations

ScenarioConcernMitigation
Large runs (>384 wells)NC lookup iterationIndexed well queries, cached NC collections
Historical well lookupDatabase queries for repeat checkBatch query for run, cache results
Systemic inhibitionCross-well association checksAssociateWellComparator caches comparison results
Multiple rules per wellRule execution overheadShort-circuit on resolution codes, early exit patterns

DocumentRelevant Sections
SRS: rule-inhibition-ct.mdINH requirements
SRS: rule-inhibition-qualitative.mdPICQUAL requirements
SRS: rule-inhibition-quantification.mdPICQUANT requirements
SRS: rule-inhibition-serum-quantitative.mdPICQUANT_SERUM requirements
SRS: rule-systemic-inhibition.mdSystemic detection requirements
SRS: rule-negative-control-inhibition.mdBICQUAL requirements
SRS: rule-icct.mdICCT rule requirements
SRS: rule-ic-qual-serum.mdPICQUAL_SERUM requirements
SDS: Rules EngineFramework overview
SDS: Combined OutcomesIC_FAILED consumption