crs4 / hl7apy

Python library to parse, create and handle HL7 v2 messages.
http://crs4.github.io/hl7apy/
MIT License
230 stars 90 forks source link

Cardinality/Optionality in module package files #111

Open J3lly-sec opened 1 year ago

J3lly-sec commented 1 year ago

Hello!

I had a question about cardinality for different versions and message types. I'm browsing the different package folders for each version, and for /v2_5/messages.py it contains similar to the following:

    'ORU_R01': ('sequence',
                (('MSH', SEGMENTS['MSH'], (1, 1), 'SEG'),
                 ('SFT', SEGMENTS['SFT'], (0, -1), 'SEG'),
                 ('ORU_R01_PATIENT_RESULT', GROUPS['ORU_R01_PATIENT_RESULT'], (1, -1), 'GRP'),
                 ('DSC', SEGMENTS['DSC'], (0, 1), 'SEG'),)),

I'm assuming the numbers in brackets refer to cardinality for that particular segment? E.g. (1, 1) means that segment is required. If so, what do (0, -1) and (1, -1) refer to? As i'm assuming (0, 1) is optional?

Thanks in advance :)

asulis commented 1 year ago

Hi, thanks for your message. The second element of the tuple is related to the number of repetitions that the specific segment/group can have, according to the message structure definition (in your case ORU_R01): 1 means that only one repetition is allowed, while -1 means that you can have infinite repetitions of that segment/group. -1 is a "convention" adopted by the library to represent "infinite" (∞).

Hope this helps, best regards Alessandro

J3lly-sec commented 1 year ago

Hi @asulis,

Thanks for the rapid response! This makes sense thanks. The issue i'm having regards a hl7 v2.5 message that does not contain an SFT segment. The message does not parse if the segment is not present, however once the segment is inserted it will parse successfully. I changed the messages.py file so that the cardinality is (0, 1) instead of (0, -1) and it seems to parse fine without the SFT segment. However, i'm not sure your description above explains why this might be happening and whether it's related to that?

asulis commented 1 year ago

Hi, that's strange, because, as the cardinality is (0,-1) for SFT, the message parsing should succeed in both cases (either with or without the SFT segment presence). Could you post us the HL7 message whose parsing is failing? Thanks

J3lly-sec commented 1 year ago

I've tried with both the below messages:

MSH|^~\&|^SureSignsVS||||20230629094736||ORU^R01^ORU_R01|CN2120532800000000C9|P|2.5|||||||||2.16.840.1.113883.9.2.1
PID|||4||smith^bob^
PV1|||^^6|||||||||||||||A|124
ORC|NW|||||||||||||||||CN21205328
OBR||||SPOTCHECK|||20230505074221|||9087
OBX||NM|0002-4bb8^SpO2^MDIL||97|0004-0220^%^MDIL|||||F
OBX||NM|0002-4182^HR_Pulse^MDIL||105|0004-0aa0^bpm^MDIL|||||F||||||0002-4bb8^SpO2^MDIL
MSH|^~\&|SendingSystem|SendingApplication|ReceivingSystem|ReceivingApplication|20230906120000||ORU^R01|123456789|P|2.5||||||ASCII
PID|1||123456789|123456789|Doe^John^A^Jr.^Dr.|Doe^Jane^A^||19700101|M|||123 Main St^^Springfield^IL^62701^USA||(555)555-5555||S||123456789|123-45-6789|
PV1|1|I|ICU^Room1|||||||||||||||||||1234567890|1234567890|1234567890|1|
OBR|1|1234567890|1234567890|CBC|||20230906120000|||||||||||Clinician^John^Doe^MD||1234567890|||F|||Clinician^Jane^Doe^MD|
OBX|1|NM|WBC^White Blood Cell Count^LN^WBC||6.7|10^3/uL|3.4-10.8||||F|||20230906120300|
OBX|2|NM|RBC^Red Blood Cell Count^LN|RBC||4.5|10^6/uL|4.3-5.9||||F|||20230906120300|
OBX|3|NM|HGB^Hemoglobin^LN|HGB||13.2|g/dL|13.5-17.5||||F|||20230906120300|
OBX|4|NM|HCT^Hematocrit^LN|HCT||38.9|%|38.3-48.6||||F|||20230906120300|
OBX|5|NM|PLT^Platelet Count^LN|PLT||150|10^3/uL|150-450||||F|||20230906120300|

As soon as I change the version to 2.4 they both parse fine. Thanks!

asulis commented 1 year ago

Hi, I've made a quick try:

from hl7apy.parser import parse_message

msg1 = """
MSH|^~\&|^SureSignsVS||||20230629094736||ORU^R01^ORU_R01|CN2120532800000000C9|P|2.5|||||||||2.16.840.1.113883.9.2.1
PID|||4||smith^bob^
PV1|||^^6|||||||||||||||A|124
ORC|NW|||||||||||||||||CN21205328
OBR||||SPOTCHECK|||20230505074221|||9087
OBX||NM|0002-4bb8^SpO2^MDIL||97|0004-0220^%^MDIL|||||F
OBX||NM|0002-4182^HR_Pulse^MDIL||105|0004-0aa0^bpm^MDIL|||||F||||||0002-4bb8^SpO2^MDIL
"""

message = parse_message(msg1)

msg2 = """
MSH|^~\&|SendingSystem|SendingApplication|ReceivingSystem|ReceivingApplication|20230906120000||ORU^R01|123456789|P|2.5||||||ASCII
PID|1||123456789|123456789|Doe^John^A^Jr.^Dr.|Doe^Jane^A^||19700101|M|||123 Main St^^Springfield^IL^62701^USA||(555)555-5555||S||123456789|123-45-6789|
PV1|1|I|ICU^Room1|||||||||||||||||||1234567890|1234567890|1234567890|1|
OBR|1|1234567890|1234567890|CBC|||20230906120000|||||||||||Clinician^John^Doe^MD||1234567890|||F|||Clinician^Jane^Doe^MD|
OBX|1|NM|WBC^White Blood Cell Count^LN^WBC||6.7|10^3/uL|3.4-10.8||||F|||20230906120300|
OBX|2|NM|RBC^Red Blood Cell Count^LN|RBC||4.5|10^6/uL|4.3-5.9||||F|||20230906120300|
OBX|3|NM|HGB^Hemoglobin^LN|HGB||13.2|g/dL|13.5-17.5||||F|||20230906120300|
OBX|4|NM|HCT^Hematocrit^LN|HCT||38.9|%|38.3-48.6||||F|||20230906120300|
OBX|5|NM|PLT^Platelet Count^LN|PLT||150|10^3/uL|150-450||||F|||20230906120300|
"""

message2 = parse_message(msg2)

Parsing is successful for both. But we still have to understand the reason for the parsing error in your code!

J3lly-sec commented 1 year ago

Huh strange! I have no idea what is going on then haha, i'll do some more debugging outside my main script, but maybe it's something in there that's causing it to fail. I'll keep you posted :) Thanks for your help so far!

svituz commented 11 months ago

Hi @kinnsFS is this fixed? Can we close it?