Root Cause Analysis Framework
The neqsim.process.diagnostics package provides a structured root cause analysis (RCA)
framework for diagnosing equipment operational anomalies. It integrates four evidence
sources via Bayesian-inspired confidence scoring:
- Reliability Data — Prior probabilities from public reliability databases (IOGP/SINTEF, CCPS 1989, IEEE 493-2007, Lees 2012, SINTEF PDS) with optional OREDA overlay
- Historian — Likelihood scoring from time-series trend, threshold, and correlation analysis
- STID — Cross-reference against design conditions
- Autonomous findings — Hypothesis-specific anomaly and topology evidence
- Simulation — Coverage-qualified, magnitude-aware verification from NeqSim perturbation
Architecture
Symptom (enum)
│
├── HypothesisGenerator → Generate candidate hypotheses
│ │
│ └── Reliability priors (ReliabilityDataSource)
│ Sources: IOGP/SINTEF, CCPS, IEEE 493, Lees, OREDA
│
├── EvidenceCollector → Analyze historian + STID data against expected signals
│ │
│ ├── Trend analysis (linear regression R²)
│ ├── Threshold exceedance
│ ├── Rate-of-change step detection (3σ)
│ └── Pearson correlation (|r| > 0.7)
│
├── AnomalyScanner + topology → Add matched autonomous evidence to ranking
├── SimulationVerifier → Clone, perturb, compare normalized response magnitude
│
└── RootCauseReport → Ranked hypotheses with confidence scores
Each built-in hypothesis carries expected signal fingerprints. For example, compressor bearing degradation expects increasing vibration and bearing temperature, while liquid ingestion expects a step change in vibration and high upstream separator or scrubber level. Evidence that matches the fingerprint is marked as supporting; opposite behavior is marked as contradictory; unrelated trends are ignored.
Confidence Scoring
Each hypothesis receives a confidence score calculated as:
\[\text{confidence} = P_{\text{prior}} \times L_{\text{historian}} \times V_{\text{simulation}}\]Where:
- $P_{\text{prior}}$ — Prior probability from reliability data (IOGP/SINTEF, CCPS, IEEE 493, etc.)
- $L_{\text{historian}}$ — Likelihood score from time-series evidence
- $V_{\text{simulation}}$ — Verification score from direction and normalized response-magnitude matching
Likelihood and verification each carry an EvaluationStatus: UNKNOWN, EVALUATED,
UNSUPPORTED, or FAILED. Only EVALUATED scores participate in the product. An
evaluated score of exactly zero is contradictory evidence, while a stage that was not
run or could not run remains explicitly neutral. JSON includes both statuses plus
simulation KPI coverage and comparison count.
Reproducible Diagnosis Cases
DiagnosisCase records the equipment, historian time window, source provenance,
process-model identity/revision, operating context, and data-quality metadata. Attach an
explicit case when source query IDs or model revisions are known; otherwise the analyzer
derives a minimal case and historian quality counts.
DiagnosisCase diagnosisCase = new DiagnosisCase("Export Compressor")
.setCaseId("trip-2026-07-19")
.setTimeWindow(1784480400.0, 1784484000.0)
.setProcessModel("export-compression", "model-rev-7")
.addDataSource("PI", "compressed-query-id-42")
.addOperatingContext("mode", "recycle")
.addDataQuality("coverage", "98%");
rca.setDiagnosisCase(diagnosisCase);
Data Sources
ReliabilityDataSource loads failure rates and repair times from multiple public databases,
requiring no commercial license:
| Source | Coverage | Access |
|---|---|---|
| IOGP Report 434 / SINTEF | Offshore O&G equipment, safety systems | Free |
| CCPS Process Equipment Reliability Data (1989) | Vessels, piping, instruments, valves | Published handbook |
| IEEE 493-2007 (Gold Book) | Industrial power and electrical equipment | Purchasable standard |
| Lees’ Loss Prevention (2012) | Generic process industry failure rates | Textbook |
| SINTEF PDS Data Handbook | Safety-instrumented system failure rates | Purchasable |
| API 689 | Rotating and process equipment reliability | Purchasable standard |
| OREDA (optional) | Offshore equipment (consortium license) | Commercial |
Supplementary CSVs are loaded automatically. Primary data takes precedence over supplementary
entries, so users can override any value by editing equipment_reliability.csv.
Supported Equipment Types
| Equipment Type | Symptoms | Hypothesis Categories |
|---|---|---|
| Compressor | HIGH_VIBRATION, HIGH_TEMPERATURE, LOW_EFFICIENCY, SURGE_EVENT, TRIP | Bearing wear, seal leak, fouling, surge, valve fault |
| Pump | HIGH_VIBRATION, LOW_EFFICIENCY, TRIP | Cavitation, impeller wear, seal failure, motor fault |
| Separator | LIQUID_CARRYOVER, PRESSURE_DEVIATION, FOULING | Demister damage, control malfunction, wax/hydrate, inlet device |
| Heat Exchanger | HIGH_TEMPERATURE, LOW_EFFICIENCY, PRESSURE_DEVIATION | Fouling, tube leak, baffle damage, bypass |
| Valve | FLOW_DEVIATION, ABNORMAL_NOISE | Trim erosion, actuator fault, positioner drift, cavitation |
Java Usage
import neqsim.process.diagnostics.*;
// Build process
ProcessSystem process = ...; // existing process model
process.run();
// Create analyzer
RootCauseAnalyzer rca = new RootCauseAnalyzer(process, "Export Compressor");
rca.setSymptom(Symptom.HIGH_VIBRATION);
// Optional: add historian data
Map<String, double[]> data = new HashMap<>();
data.put("vibration_mm_s", new double[]{2.1, 2.3, 2.8, 3.5, 4.2});
data.put("bearing_temp_C", new double[]{65, 67, 72, 78, 85});
double[] timestamps = {0, 1, 2, 3, 4};
rca.setHistorianData(data, timestamps);
// Optional: design limits
rca.setDesignLimit("vibration_mm_s", 0.0, 4.5);
// Run analysis
RootCauseReport report = rca.analyze();
// Output
String textReport = report.toTextReport();
String json = report.toJson();
Python (Jupyter) Usage
RootCauseAnalyzer = ns.JClass("neqsim.process.diagnostics.RootCauseAnalyzer")
Symptom = ns.JClass("neqsim.process.diagnostics.Symptom")
rca = RootCauseAnalyzer(process, "Export Compressor")
rca.setSymptom(Symptom.HIGH_VIBRATION)
report = rca.analyze()
# Get JSON report
import json
result = json.loads(str(report.toJson()))
for h in result["hypotheses"]:
print(f"{h['rank']}. {h['name']} — confidence: {h['confidenceScore']:.3f}")
MCP Tool
The runRootCauseAnalysis MCP tool exposes this framework to LLM agents:
{
"processJson": "{\"fluid\": {...}, \"process\": [...]}",
"equipmentName": "Export Compressor",
"symptom": "HIGH_VIBRATION",
"historianCsv": "timestamp,vibration,bearing_temp\n0,2.1,65\n1,2.3,67\n2,2.8,72",
"designLimits": { "vibration": [0, 4.5] },
"simulationEnabled": true,
"diagnosisCase": {
"caseId": "trip-2026-07-19",
"processModelId": "export-compression",
"processModelRevision": "model-rev-7",
"dataSources": { "PI": "compressed-query-id-42" },
"operatingContext": { "mode": "recycle" },
"dataQuality": { "coverage": "98%" }
}
}
processJson is passed as a JSON string to the MCP runner. The schema catalog
entry run_root_cause_analysis shows the exact input fields and output shape.
The returned diagnosisCase object and per-hypothesis evaluation statuses are additive,
so consumers of the existing report fields continue to work.
Custom Hypotheses
Register domain-specific hypotheses for specialized equipment:
HypothesisGenerator generator = new HypothesisGenerator();
generator.register("compressor", Symptom.HIGH_VIBRATION,
new Hypothesis.Builder()
.name("Coupling misalignment")
.description("Flexible coupling misalignment causing 1x/2x vibration")
.category(Hypothesis.Category.MECHANICAL)
.priorProbability(0.15)
.addExpectedSignal("vibration|2x|axialVibration", Hypothesis.ExpectedBehavior.INCREASE,
2.5, "Misalignment normally increases axial and 2x vibration")
.addAction("Laser alignment check")
.build());
RootCauseAnalyzer rca = new RootCauseAnalyzer(process, "Compressor");
rca.setHypothesisGenerator(generator);
Classes
| Class | Description |
|---|---|
Symptom |
Enum of 12 observable symptoms (TRIP, HIGH_VIBRATION, etc.) |
Hypothesis |
Ranked failure hypothesis with evidence, confidence, and actions |
HypothesisGenerator |
Registry-based generator with built-in equipment libraries |
EvidenceCollector |
Time-series analysis (trend, threshold, correlation) |
DiagnosisCase |
Reproducible window, provenance, model identity, context, and quality metadata |
SimulationVerifier |
Process perturbation with explicit status, KPI coverage, and magnitude-aware scoring |
RootCauseReport |
Ranked report with JSON, text, and results map output |
RootCauseAnalyzer |
Main orchestrator integrating all components |