[613] | 1 | MAG7UP ;WOIFO/MLH - Imaging - HL7 - utilities - break out message into a parse tree ; 06/03/2005 12:05
|
---|
| 2 | ;;3.0;IMAGING;**11,51**;26-August-2005
|
---|
| 3 | ;; +---------------------------------------------------------------+
|
---|
| 4 | ;; | Property of the US Government. |
|
---|
| 5 | ;; | No permission to copy or redistribute this software is given. |
|
---|
| 6 | ;; | Use of unreleased versions of this software requires the user |
|
---|
| 7 | ;; | to execute a written test agreement with the VistA Imaging |
|
---|
| 8 | ;; | Development Office of the Department of Veterans Affairs, |
|
---|
| 9 | ;; | telephone (301) 734-0100. |
|
---|
| 10 | ;; | |
|
---|
| 11 | ;; | The Food and Drug Administration classifies this software as |
|
---|
| 12 | ;; | a medical device. As such, it may not be changed in any way. |
|
---|
| 13 | ;; | Modifications to this software may result in an adulterated |
|
---|
| 14 | ;; | medical device under 21CFR820, the use of which is considered |
|
---|
| 15 | ;; | to be a violation of US Federal Statutes. |
|
---|
| 16 | ;; +---------------------------------------------------------------+
|
---|
| 17 | ;;
|
---|
| 18 | Q
|
---|
| 19 | ;
|
---|
| 20 | PARSE(XMSG,XTREE) ; break the HL7 message lines into a parse tree
|
---|
| 21 | ;
|
---|
| 22 | ; INPUT: The single-dimensional array of message lines
|
---|
| 23 | ;
|
---|
| 24 | ; OUTPUT: The parse tree, in the structure
|
---|
| 25 | ; @XTREE@(NSEG,0) segment name
|
---|
| 26 | ; @XTREE@(NSEG,NFLD,NREP,NCMP,NSCM) element data
|
---|
| 27 | ; @XTREE@("B",SEGID,NSEG) null
|
---|
| 28 | ;
|
---|
| 29 | N I,J,K,L,M,X,Z ; --------------------- scratch vars
|
---|
| 30 | N IMSG ; ------------------------------ message array index
|
---|
| 31 | N ISUBSEG ; --------------------------- index of continuation data for long segs
|
---|
| 32 | N ISUCC ; ----------------------------- successor element index
|
---|
| 33 | N FERR ; ------------------------------ error flag
|
---|
| 34 | N SEG ; ------------------------------- segment data
|
---|
| 35 | N SEGTAG ; ---------------------------- segment ID ("0th" piece)
|
---|
| 36 | N UFS,UCS,URS,UEC,USS ;---------------- HL7 delimiters (universal)
|
---|
| 37 | N ENC ;-------------------------------- HL7 encoding characters
|
---|
| 38 | N UFSESC,UCSESC,URSESC,UECESC,USSESC ;- HL7 escape sequences for delimiters (universal)
|
---|
| 39 | N PATTERN ; --------------------------- pattern match for spanned record
|
---|
| 40 | N NSEG ; ------------------------------ segment number in the parse tree
|
---|
| 41 | N NSEGINPT ; -------------------------- segment number of input HL7 data
|
---|
| 42 | N NFLD ; ------------------------------ field number in the segment
|
---|
| 43 | N FLD ; ------------------------------- field data
|
---|
| 44 | ;
|
---|
| 45 | S FERR=0 ; assume no error
|
---|
| 46 | S IMSG=""
|
---|
| 47 | ;
|
---|
| 48 | ; process MSH segment
|
---|
| 49 | ; If there's a message problem, return it in an NTE segment.
|
---|
| 50 | ;
|
---|
| 51 | S IMSG=$O(@XMSG@(IMSG)) ; array sent?
|
---|
| 52 | I IMSG="" D Q FERR ; no
|
---|
| 53 | . S FERR=-1
|
---|
| 54 | . ; have to use default field separator
|
---|
| 55 | . S @XMSG@(0)="NTE|1||"_FERR_";no input array found"
|
---|
| 56 | . Q
|
---|
| 57 | S SEG=$G(@XMSG@(IMSG)) Q:$E(SEG,1,3)'="MSH" -2 ; an HL7 message?
|
---|
| 58 | I $E(SEG,1,3)'="MSH" D Q FERR ; no
|
---|
| 59 | . S FERR=-2
|
---|
| 60 | . S ISUCC=$O(@XMSG@(IMSG)) S:'ISUCC ISUCC=IMSG+1
|
---|
| 61 | . ; have to use default field separator
|
---|
| 62 | . S @XMSG@(IMSG+ISUCC/2)="NTE|1||"_FERR_";invalid HL7 message (1st 3 chars must be MSH)"
|
---|
| 63 | . Q
|
---|
| 64 | ;
|
---|
| 65 | ; set up delimiters and escape sequences
|
---|
| 66 | S UFS=$E(SEG,4),@XTREE@(1,1,1,1,1)=UFS
|
---|
| 67 | S ENC=$P(SEG,UFS,2),@XTREE@(1,2,1,1,1)=ENC
|
---|
| 68 | S UCS=$E(ENC),URS=$E(ENC,2),UEC=$E(ENC,3),USS=$E(ENC,4)
|
---|
| 69 | S UFSESC=UEC_"F"_UEC,UCSESC=UEC_"S"_UEC,URSESC=UEC_"S"_UEC,UECESC=UEC_"E"_UEC,USSESC=UEC_"T"_UEC
|
---|
| 70 | S PATTERN="1A2AN1"""_UFS_""""
|
---|
| 71 | S @XTREE@(1,0)="MSH",@XTREE@("B","MSH",1)=""
|
---|
| 72 | F NFLD=3:1:$L(SEG,UFS) S FLD=$P(SEG,UFS,NFLD) D
|
---|
| 73 | . I FLD]"" D PROCFLD(XTREE,1,NFLD,FLD)
|
---|
| 74 | . Q
|
---|
| 75 | ; process the remaining segments
|
---|
| 76 | S SEG="" ; SEG will be a concatenated series of spanned records
|
---|
| 77 | S NSEG=2 ; next segment in the parse tree will be #2
|
---|
| 78 | F NSEGINPT=2:1 S IMSG=$O(@XMSG@(IMSG)) Q:IMSG="" D Q:FERR
|
---|
| 79 | . S SEG=$G(@XMSG@(IMSG)) Q:SEG=""
|
---|
| 80 | . S ISUBSEG="" ; prepare to handle very long HL7 segments (up to 32K)
|
---|
| 81 | . F S ISUBSEG=$O(@XMSG@(IMSG,ISUBSEG)) Q:ISUBSEG="" D
|
---|
| 82 | . . S SEG=SEG_$G(@XMSG@(IMSG,ISUBSEG))
|
---|
| 83 | . . Q
|
---|
| 84 | . S SEGTAG=$P(SEG,UFS) I SEGTAG'?1U2.3UN S FERR=-3 Q
|
---|
| 85 | . S @XTREE@(NSEG,0)=SEGTAG,@XTREE@("B",SEGTAG,NSEG)=""
|
---|
| 86 | . F NFLD=2:1:$L(SEG,UFS) D
|
---|
| 87 | . . S FLD=$P(SEG,UFS,NFLD)
|
---|
| 88 | . . I FLD]"" D PROCFLD(XTREE,NSEG,NFLD-1,FLD)
|
---|
| 89 | . . Q
|
---|
| 90 | . S SEG="" ; reinitialize SEG for the next possible concatenation
|
---|
| 91 | . S NSEG=NSEG+1 ; increment counter for next segment in the parse tree
|
---|
| 92 | . Q
|
---|
| 93 | Q FERR
|
---|
| 94 | ;
|
---|
| 95 | PROCFLD(XTREE,XNSEG,XNFLD,XFLD) ; process a field
|
---|
| 96 | ;
|
---|
| 97 | ; input: XTREE name of MUMPS array for parse tree ($NA format)
|
---|
| 98 | ; XNSEG segment number for parse tree
|
---|
| 99 | ; XNFLD field number for parse tree
|
---|
| 100 | ; XFLD field data
|
---|
| 101 | ;
|
---|
| 102 | N SG ; ------ segment name
|
---|
| 103 | N NREP ; ---- repetition (occurrence) number
|
---|
| 104 | N REP ; ----- repetition data
|
---|
| 105 | N NCMP ; ---- component number
|
---|
| 106 | N CMP ; ----- component data
|
---|
| 107 | N NSCM ; ---- subcomponent number
|
---|
| 108 | N SCM ; ----- subcomponent data
|
---|
| 109 | ;
|
---|
| 110 | S SG=@XTREE@(XNSEG,0)
|
---|
| 111 | ; Per DICOM meeting 2004-02-24, reaffirmed that data may need to be
|
---|
| 112 | ; retrieved above the subcomponent level, and that those data will
|
---|
| 113 | ; need to be de-escaped because the receiving application won't have
|
---|
| 114 | ; access to the delimiters from the original message.
|
---|
| 115 | S @XTREE@(XNSEG,XNFLD)=$$DEESC(XFLD)
|
---|
| 116 | ;
|
---|
| 117 | ; Break out to the lowest delimiter level too. This is not strictly an
|
---|
| 118 | ; HL7 parse because it does not take actual HL7 (or realm constraining)
|
---|
| 119 | ; data types into account.
|
---|
| 120 | ;
|
---|
| 121 | F NREP=1:1:$L(XFLD,URS) S REP=$P(XFLD,URS,NREP) I REP]"" D
|
---|
| 122 | . F NCMP=1:1:$L(REP,UCS) S CMP=$P(REP,UCS,NCMP) I CMP]"" D
|
---|
| 123 | . . ; Per DICOM meeting 2004-02-24, reaffirmed that data may need to be
|
---|
| 124 | . . ; retrieved above the subcomponent level, and that those data will
|
---|
| 125 | . . ; need to be de-escaped because the receiving application won't have
|
---|
| 126 | . . ; access to the delimiters from the original message.
|
---|
| 127 | . . S @XTREE@(XNSEG,XNFLD,NREP,NCMP)=$$DEESC(CMP)
|
---|
| 128 | . . F NSCM=1:1:$L(CMP,USS) S SCM=$P(CMP,USS,NSCM) I SCM]"" D
|
---|
| 129 | . . . S @XTREE@(XNSEG,XNFLD,NREP,NCMP,NSCM)=$$DEESC(SCM)
|
---|
| 130 | . . . Q
|
---|
| 131 | . . Q
|
---|
| 132 | . Q
|
---|
| 133 | Q
|
---|
| 134 | ;
|
---|
| 135 | DEESC(XSCM) ; replace escape sequences with delimiter characters
|
---|
| 136 | ;
|
---|
| 137 | ; input: XSCM element data before replacement
|
---|
| 138 | ;
|
---|
| 139 | ; expects: UFSESC, UCSESC, URSESC, UECESC, USSESC
|
---|
| 140 | ; delimiter escape sequences
|
---|
| 141 | ;
|
---|
| 142 | ; function return: element data after replacement
|
---|
| 143 | ;
|
---|
| 144 | N HIT ; need another pass after each hit
|
---|
| 145 | F D Q:'$D(HIT)
|
---|
| 146 | . K HIT
|
---|
| 147 | . I XSCM[UFSESC S XSCM=$P(XSCM,UFSESC)_UFS_$P(XSCM,UFSESC,2,99999),HIT=1
|
---|
| 148 | . I XSCM[UCSESC S XSCM=$P(XSCM,UCSESC)_UCS_$P(XSCM,UCSESC,2,99999),HIT=1
|
---|
| 149 | . I XSCM[URSESC S XSCM=$P(XSCM,URSESC)_URS_$P(XSCM,URSESC,2,99999),HIT=1
|
---|
| 150 | . I XSCM[UECESC S XSCM=$P(XSCM,UECESC)_UEC_$P(XSCM,UECESC,2,99999),HIT=1
|
---|
| 151 | . I XSCM[USSESC S XSCM=$P(XSCM,USSESC)_USS_$P(XSCM,USSESC,2,99999),HIT=1
|
---|
| 152 | . Q
|
---|
| 153 | Q $E(XSCM,1,510)
|
---|
| 154 | ;
|
---|