web stats
Grouping OBX by multiple OBRs - Mirth Community

Go Back   Mirth Community > Mirth Connect > Support

Reply
 
Thread Tools Display Modes
  #1  
Old 07-31-2019, 08:45 AM
as703 as703 is offline
What's HL7?
 
Join Date: Jul 2019
Posts: 4
as703 is on a distinguished road
Default Grouping OBX by multiple OBRs

I'm completely new to Mirth Connect and would really appreciate some pointers.

I'm receiving lab results in hl7 format and need to output to html and pdf. I've created a channel which works for simple cases with a single OBR but I'm struggling with a more complex case with multiple OBRs.

I'd like the output to look something like this:

OBR 1 - Haematology
- OBX1
- OBX2
- OBX3 ...

OBR 2 - Biochemistry
- OBX1
- OBX2
- OBX3 ...

and so on.

I'm currently using the following javascript to fill a results table:

Quote:
var results = new XML('<tbody></tbody>');
var tr;

for each (mOBX in msg..OBX) {

tr = new XML('<tr></tr>');

tr['td'][0] = '';
if (mOBX['OBX.8']['OBX.8.1'].toString() != "N") {
tr['td'][0]['img']['@src'] = '/mnt/media_b/mirth/red_flag.png';
}
// Test Name
tr['td'][1] = mOBX['OBX.3']['OBX.3.2'].toString();
// Result
tr['td'][2] = mOBX['OBX.5']['OBX.5.1'].toString() + " "+ mOBX['OBX.6']['OBX.6.1'].toString();
// Flag - Red if not N = normal
tr['td'][3] = mOBX['OBX.8']['OBX.8.1'].toString();
// Reference range
tr['td'][4] = mOBX['OBX.7']['OBX.7.1'].toString() + " " + mOBX['OBX.6']['OBX.6.1'].toString();

results[''] += tr;
}

channelMap.put("Results",results);
I then use $Results in my destination HTML template to output the results table.

How do I modify the above to create a separate table for each of the OBRs in my hl7 file? Each table should have a header with the test name (OBR 4.2). All the results tables are going to be written to the same file/document.

I can provide an example hl7 file if that's useful.

Many thanks in advance for your help - it's very much appreciated.
Reply With Quote
  #2  
Old 08-02-2019, 06:06 AM
schillert schillert is offline
OBX.1 Kenobi
 
Join Date: Jul 2012
Posts: 29
schillert is on a distinguished road
Default

This should help. The trick is to iterate over the whole message.

Code:
var results = new XML('<tbody></tbody>');
var tr;

for each (seg in msg.children()) {
	switch (seg.name().toString()) {
		case "OBR":
			tr = new XML('<tr></tr>');
			break;
		case "OBX":
			tr['td'][0] = '';
			if (seg['OBX.8']['OBX.8.1'].toString() != "N") {
				tr['td'][0]['img']['@src'] = '/mnt/media_b/mirth/red_flag.png';
			}
			// Test Name
			tr['td'][1] = seg['OBX.3']['OBX.3.2'].toString();
			// Result
			tr['td'][2] = seg['OBX.5']['OBX.5.1'].toString() + " "+ seg['OBX.6']['OBX.6.1'].toString();
			// Flag - Red if not N = normal
			tr['td'][3] = seg['OBX.8']['OBX.8.1'].toString();
			// Reference range
			tr['td'][4] = seg['OBX.7']['OBX.7.1'].toString() + " " + seg['OBX.6']['OBX.6.1'].toString();
			results[''] += tr;
			break;
	}
}
channelMap.put("Results",results);
Oops - I forgot the header. This can be done in the OBR branch of the switch-case

Last edited by schillert; 08-02-2019 at 06:10 AM.
Reply With Quote
  #3  
Old 08-05-2019, 06:38 AM
as703 as703 is offline
What's HL7?
 
Join Date: Jul 2019
Posts: 4
as703 is on a distinguished road
Default

Many thanks for getting back to me it's much appreciated.

I replaced my Javascript with what you provided but it didn't seem to split the output.

An example of the HL7 message I'm trying to parse:

Quote:
MSH|^~\&|TDL Messaging|TDL|Receiving App|Receiving facility|201810021212||ORM^O01|20181002121215_ORDE RID|T|2.3.1|||AL|||||
PID|||PATIENT||PATIENT^TEST`^^^||00010101|M|||^^^^ |||||||||||||||||||
PV1|||GRAHAM^Graham Hogan||||||KERMITDAFROG||||||||||||||||||||||||||| ||||||||
ORC|OK|ORDERID|0010T197770||IP>||||201810021212||| ||||||||
OBR|1|ORDERID|0010T197770|^^WinPath||20110924|2011 0924|||||||||KERMITDAFROG^KERMITDAFROG||||||||TDL| I||||||||||||||||||||
OBX|1|NM|HB^HAEMOGLOBIN^WinPath^HAEMATOLOGY^1^0||1 5.9|g/dL|13.0 - 17.0||||F|||||
OBX|2|NM|MCHC^MCHC^WinPath^HAEMATOLOGY^2^5||32.3|g/dL| 30 - 35||||F|||||
OBX|3|NM|RBGF^FASTING BLOOD GLUCOSE^WinPath^BIOCHEMISTRY^3^37||3.0|mmol/L| 3.9 - 5.8|L|||F|||||
OBR|2|ORDERID|0010T197770|FBCX^FULL BLOOD COUNT^WinPath||20110924|20110924|||||||||KERMITDAF ROG^KERMITDAFROG||||||||TDL|I||||||||||||||||||||
OBX|1|NM|HCT^HCT^WinPath^HAEMATOLOGY^1^1||0.492||0 .37 - 0.50||||F|||||
OBX|2|NM|RBC^RED CELL COUNT^WinPath^HAEMATOLOGY^2^2||5.31|x10^12/L|4.40 - 5.80||||F|||||
OBX|3|NM|MCV^MCV^WinPath^HAEMATOLOGY^3^3||92.7|fL| 80 - 99||||F|||||
OBX|4|NM|MCH^MCH^WinPath^HAEMATOLOGY^4^4||29.9|pg| 26.0 - 33.5||||F|||||
OBX|5|NM|RDW^RDW^WinPath^HAEMATOLOGY^5^6||13.1||11 .5 - 15.0||||F|||||
OBX|6|NM|PLTS^PLATELET COUNT^WinPath^HAEMATOLOGY^6^7||174|x10^9/L|150 - 400||||F|||||
OBX|7|NM|MPV^MPV^WinPath^HAEMATOLOGY^7^8||11.1|fL| 7 - 13||||F|||||
OBX|8|NM|WBC^WHITE CELL COUNT^WinPath^HAEMATOLOGY^8^9||6.94|x10^9/L| 3.0 - 10.0||||F|||||
OBX|9|ST|NEUT^ Neutrophils^WinPath^HAEMATOLOGY^9^10||54.6% 3.79|x10^9/L| 2.0 - 7.5||||F|||||
OBX|10|ST|LYMP^ Lymphocytes^WinPath^HAEMATOLOGY^10^11||33.6% 2.33|x10^9/L| 1.2 - 3.65||||F|||||
OBX|11|ST|MONO^ Monocytes^WinPath^HAEMATOLOGY^11^12|| 7.5% 0.52|x10^9/L| 0.2 - 1.0||||F|||||
OBX|12|ST|EOSI^ Eosinophils^WinPath^HAEMATOLOGY^12^13|| 3.9% 0.27|x10^9/L| 0.0 - 0.4||||F|||||
OBX|13|ST|BASO^ Basophils^WinPath^HAEMATOLOGY^13^14|| 0.4% 0.03|x10^9/L| 0.0 - 0.1||||F|||||
NTE|1|All cell populations appear normal.|
OBR|3|ORDERID|0010T197770|ESR^ERYTHROCYTE SEDIMENT RATE^WinPath||20110924|20110924|||||||||KERMITDAFR OG^KERMITDAFROG||||||||TDL|I||||||||||||||||||||
OBX|1|NM|ESR^ESR^WinPath^HAEMATOLOGY^1^15||5|mm/hr| 1 - 20||||F|||||
NTE|1|Note ref range raised in patients over 40|
I'd like to split each OBR, OBX section into separate tables with a new header above each table.

Many thanks again.
Reply With Quote
  #4  
Old 08-08-2019, 01:01 AM
schillert schillert is offline
OBX.1 Kenobi
 
Join Date: Jul 2012
Posts: 29
schillert is on a distinguished road
Default

Sorry for the complete and utter nonsense-code from my earlier post.
I have tested the code below with your sample message and it works.

Code:
var results = <body/>;
var workToDo=false;
for each (seg in msg.children()) {
	switch (seg.name().toString()) {
		case "OBR":
			if(workToDo) {
				table.appendChild(tbody.copy());
				results.appendChild(table.copy());
				workToDo=false;
			}
			var table = <table/>;
			var thead = <thead/>;
			thead.appendChild(<tr><td colspan="5">{seg["OBR.4"]["OBR.4.2"].toString()}</td></tr>);
			table.appendChild(thead.copy());
			var tbody = <tbody/>;
			break;
		case "OBX":
			workToDo=true;
			var tr=<tr/>;
			if (seg['OBX.8']['OBX.8.1'].toString() != "N") {
				tr.appendChild(<td><img src="/mnt/media_b/mirth/red_flag.png"/></td>);
			} else {
				tr.appendChild(<td/>);
			}
			// Test Name
			tr.appendChild(<td>{seg['OBX.3']['OBX.3.2'].toString()}</td>);
			// Result
			tr.appendChild(<td>{seg['OBX.5']['OBX.5.1'].toString() + " " + seg['OBX.6']['OBX.6.1'].toString()}</td>);
			// Flag - Red if not N = normal
			tr.appendChild(<td>{seg['OBX.8']['OBX.8.1'].toString()}</td>);
			// Reference range
			tr.appendChild(<td>{seg['OBX.7']['OBX.7.1'].toString() + " " + seg['OBX.6']['OBX.6.1'].toString()}</td>);
			tbody.appendChild(tr.copy());
			break;
	}
}
if(workToDo) {
	table.appendChild(tbody.copy());
	results.appendChild(table.copy());
}
tmp=<html>{results}</html>;
Reply With Quote
  #5  
Old 08-08-2019, 05:16 AM
as703 as703 is offline
What's HL7?
 
Join Date: Jul 2019
Posts: 4
as703 is on a distinguished road
Default

Brilliant - many thanks
Reply With Quote
  #6  
Old 08-10-2019, 04:51 AM
as703 as703 is offline
What's HL7?
 
Join Date: Jul 2019
Posts: 4
as703 is on a distinguished road
Default

Forgive my ignorance but Iím slightly unclear on one aspect of your code and would be very grateful if you could explain it to me.

When using appendChild to add nodes to the table, why do you need to use .copy()?

Many thanks for your help.
Reply With Quote
  #7  
Old 08-15-2019, 12:17 PM
ASIFM786 ASIFM786 is offline
Mirth Newb
 
Join Date: Oct 2008
Posts: 16
ASIFM786
Default

Quote:
Originally Posted by schillert View Post
Sorry for the complete and utter nonsense-code from my earlier post.
I have tested the code below with your sample message and it works.

Code:
var results = <body/>;
var workToDo=false;
for each (seg in msg.children()) {
	switch (seg.name().toString()) {
		case "OBR":
			if(workToDo) {
				table.appendChild(tbody.copy());
				results.appendChild(table.copy());
				workToDo=false;
			}
			var table = <table/>;
			var thead = <thead/>;
			thead.appendChild(<tr><td colspan="5">{seg["OBR.4"]["OBR.4.2"].toString()}</td></tr>);
			table.appendChild(thead.copy());
			var tbody = <tbody/>;
			break;
		case "OBX":
			workToDo=true;
			var tr=<tr/>;
			if (seg['OBX.8']['OBX.8.1'].toString() != "N") {
				tr.appendChild(<td><img src="/mnt/media_b/mirth/red_flag.png"/></td>);
			} else {
				tr.appendChild(<td/>);
			}
			// Test Name
			tr.appendChild(<td>{seg['OBX.3']['OBX.3.2'].toString()}</td>);
			// Result
			tr.appendChild(<td>{seg['OBX.5']['OBX.5.1'].toString() + " " + seg['OBX.6']['OBX.6.1'].toString()}</td>);
			// Flag - Red if not N = normal
			tr.appendChild(<td>{seg['OBX.8']['OBX.8.1'].toString()}</td>);
			// Reference range
			tr.appendChild(<td>{seg['OBX.7']['OBX.7.1'].toString() + " " + seg['OBX.6']['OBX.6.1'].toString()}</td>);
			tbody.appendChild(tr.copy());
			break;
	}
}
if(workToDo) {
	table.appendChild(tbody.copy());
	results.appendChild(table.copy());
}
tmp=<html>{results}</html>;
hey just wondering how would incorporate NTE part of the message in this?

thanks in advance
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 07:18 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Mirth Corporation