ORU^R01 is the HL7 message that carries every lab result, radiology read, and point-of-care test from a Laboratory Information System (LIS) to downstream clinical applications. A production Mirth Connect ORU channel must parse OBX segments reliably, detect critical values requiring immediate notification, map local codes to LOINC standards, handle corrected results, and fan out to EHR, FHIR R4 API, and population health databases simultaneously. See our LIS HL7 ORU to FHIR DiagnosticReport guide for the FHIR conversion layer.
ORU Message Structure: OBR + OBX Groups
An ORU^R01 message contains patient identification (PID), one OBR per ordered test, and one or more OBX per result component. A complete metabolic panel generates 1 OBR and 14 OBX segments. A CBC with differential generates 18 OBX. OBX-2 (value type) tells Mirth how to handle OBX-5: NM (numeric — compare against ranges), ST (string — qualitative result), TX (text — multi-line report), ED (encapsulated data — Base64 PDF).
Production OBX Parsing Pattern
var results = [];
for each (var obx in msg['OBX']) {
results.push({
loincCode : obx['OBX.3']['CWE.1'].toString(),
loincName : obx['OBX.3']['CWE.2'].toString(),
valueType : obx['OBX.2'].toString(),
value : obx['OBX.5'].toString(),
units : obx['OBX.6']['CWE.1'].toString(),
refRange : obx['OBX.7'].toString(),
abnFlag : obx['OBX.8'].toString(), // LL/HH = critical
status : obx['OBX.11'].toString(), // F/P/C
obsTime : obx['OBX.14'].toString()
});
}
channelMap.put('parsed_results', JSON.stringify(results));Critical Value Detection: Two-Layer Approach
Critical values require immediate clinician notification — a potassium of 6.8 mEq/L cannot wait for the next inbox check. OBX-8 flags LL (critically low) and HH (critically high) are the HL7 indicators, but not all LIS systems populate them reliably. A value range fallback table catches the gaps:
var CRITICAL = {
'2951-2': {low:120, high:160}, // Sodium
'2823-3': {low:2.5, high:6.5}, // Potassium
'2160-0': {low:0, high:10.0}, // Creatinine
'2345-7': {low:40, high:500}, // Glucose
};
function isCritical(loincCode, value, abnFlag) {
if (abnFlag === 'LL' || abnFlag === 'HH') return true;
var range = CRITICAL[loincCode];
if (!range) return false;
var n = parseFloat(value);
return !isNaN(n) && (n < range.low || n > range.high);
}
var critical = results.filter(function(r) {
return isCritical(r.loincCode, r.value, r.abnFlag);
});
channelMap.put('has_critical', (critical.length > 0).toString());
channelMap.put('critical_results', JSON.stringify(critical));Route critical results to a dedicated notification destination targeting under-60-second delivery. The PagerDuty runbook for Mirth covers the alerting integration pattern. Monitor latency with OpenTelemetry instrumentation.
LOINC Code Mapping From Local LIS Codes
// Load LOINC map at channel startup (Deploy script)
var db = DatabaseConnectionFactory.createDatabaseConnection(
'org.postgresql.Driver','jdbc:postgresql://db:5432/mirth_ref','ro','pass'
);
try {
var rs = db.executeCachedQuery(
'SELECT local_code, loinc_code FROM loinc_map WHERE active = true'
);
var map = {};
while (rs.next())
map[rs.getString('local_code')] = rs.getString('loinc_code');
globalMap.put('loinc_map', JSON.stringify(map));
} finally { db.close(); }
// In transformer — lookup from cache
var loincMap = JSON.parse(globalMap.get('loinc_map'));
var resolvedCode = loincMap[localCode] || localCode;Corrected Results: OBX-11 = C
OBX-11 status 'C' means a correction to a previously reported value. Downstream systems must update their existing result record rather than create a new one. In FHIR, corrected results create a new Observation with status: 'amended' linking back to the original. Set a channelMap flag so destination transformers can generate the correct update operation:
var isCorrection = results.some(function(r) { return r.status === 'C'; });
channelMap.put('is_corrected', isCorrection.toString());
if (isCorrection)
logger.info('Corrected result for order: ' + msg['OBR']['OBR.3']['EI.1'].toString());Monitoring Your ORU Channel
Key metrics: message throughput (20% drop signals LIS outage), critical value routing latency (target under 60 seconds), unmapped LOINC codes, error queue depth, and corrected result rate (spike = LIS data quality issue). Full monitoring setup in our Mirth production monitoring guide.



