LEXTRAN ; ISL/FJF - Lexicon code and text wrapper API's ; 01/31/2006 ;;2.0;LEXICON UTILITY;**41**;Sep 23, 1996;Build 34 ; Per VHA Directive 2004-038, this routine should not be modified. ; CODE(LEXCODE,LEXSRC,LEXVDT,LEXRAY) ; ; Lexicon wrapper application to obtain concept data for a given code ; and source ; ; Input ; ; LEXCODE code - mandatory ; LEXSRC code system source abbreviation e.g. SCT (SNOMED CT) ; - mandatory ; LEXVDT effective date (defaults to current date) - optional ; LEXRAY output array (defaults to 'LEX') optionaL ; ; Output ; ; if call finds an active code for the source ; "1^LEXCODE" ; LEX - an array containing information about the code ; LEX(0) - a five piece string: ; 1. code ; 2. hierarchy ; 3. version ; 4. legacy code ; 5. code status ; LEX("F") fully specified name ; LEX("P") preferred term ; LEX("S",n) synonyms (n is the nth synonym) ; ; if call cannot find specified code on file ; "-2^"_LEXSCNM_" code "_LEXCODE_" not on file" ; where LEXSCNM is the source name ; LEXCODE is the code ; ; if call finds an inactive code for the source ; "-4^"_LEXSCNM_" code "_LEXCODE_" not active for "_LEXVDT ; LEX - an array containing information about the code ; LEX(0) - a five piece string: ; 1. code ; 2. hierarchy ; 3. version ; 4. legacy code ; 5. code status ; ; otherwise ; "-1^error text" ; ; example of LEX array: ; LEX(0)="67922002^Substance^20050701^T-C2500^1" ; LEX("F")="Serum (Substance)" ; LEX("P")="Serum" ; ; check passed parameter arguments ; I $G(LEXCODE)="" Q "-1^no code specified" I $G(LEXSRC)="" Q "-1^no source specified" I '$D(^LEX(757.03,"B",LEXSRC)) Q "-1^source not recognized" I $D(^TMP("LEXSCH",$J,"VDT",0)) S LEXVDT=^(0) I $G(LEXVDT)'="" S LEXVDT=$$INTDAT(LEXVDT) I $G(LEXVDT)=-1 Q "-1^invalid date format" I $G(LEXVDT)="" S LEXVDT=$$DT^XLFDT I $G(LEXRAY)="" K LEXRAY ; ; obtain source mnemonic and ASAB ; N LEXSCNM,LEXSIEN,LEXASAB,LEXCIEN,VALCODE,LEXSTAT,LEXPIEN,T ; S LEXSIEN=$O(^LEX(757.03,"B",LEXSRC,"")) S T=^LEX(757.03,LEXSIEN,0) S LEXSCNM=$P(T,U,2) S LEXASAB=$E($P(T,U),1,3) ; ; check for code existence for source ; S LEXCIEN="",VALCODE=0 F Q:VALCODE=1 D Q:LEXCIEN="" .S LEXCIEN=$O(^LEX(757.02,"CODE",LEXCODE_" ",LEXCIEN)) Q:LEXCIEN="" D .I $D(^LEX(757.02,"ASRC",LEXASAB,LEXCIEN)) S VALCODE=1 Q I 'VALCODE Q "-2^"_LEXSCNM_" code "_LEXCODE_" not on file" ; ; now we know that the code belongs to the source and that it is known ; in our files ; check that code is valid for date ; K LEXSTAT,LEX K ^TMP("LEXSCH",$J) S LEXSTAT=$$STATCHK^LEXSRC2(LEXCODE,LEXVDT,.LEXSTAT) I +LEXSTAT=0 D Q "-4^"_LEXSCNM_" code "_LEXCODE_" not active for "_LEXVDT .S LEXPIEN=$P(LEXSTAT(1),U) .D INFO^LEXA(LEXPIEN) .D GETINFO .I $D(LEXRAY),LEXRAY'="LEX" M @LEXRAY=LEX K LEX ; ; if we've got this far we have a good code that is active S LEXPIEN=$P(LEXSTAT(1),U) ;Q "1^"_LEXCODE D INFO^LEXA(LEXPIEN) D GETINFO I $D(LEXRAY),LEXRAY'="LEX" M @LEXRAY=LEX K LEX ; Q "1^"_LEXCODE ; GETINFO ; obtain information for code and populate LEX array ; N LEXFSN,LEXHIER,LEXLGY,LEXVER,N,LEXSEP,I I $D(LEX("SEL","EXP","C","FUL")) D .S LEXFSN=LEX("SEL","EXP",$O(LEX("SEL","EXP","C","FUL",""))) .S LEXHIER=$P($P(LEXFSN,"(",$L(LEXFSN,"(")),")") ; legacy code S LEXLGY=$$GET1^DIQ(757.02,LEXCIEN_",",13) ; version S LEXVER=$$VERSION(LEXSRC,LEXCODE,LEXVDT) ; create return array ;S LEXSEP=" ["_LEXCODE_"]" S LEX(0)=LEXCODE_U_$G(LEXHIER)_U_$S(+LEXVER=-1:"",1:$P(LEXVER,U,3)) S LEX(0)=LEX(0)_U_LEXLGY_U_+LEXSTAT S LEX("P")=$P(LEX("SEL","EXP",$O(LEX("SEL","EXP","C","MAJ",""))),U,2) I $D(LEXFSN) S LEX("F")=$P(LEXFSN,"^",2) S N="" F I=1:1 S N=$O(LEX("SEL","EXP","C","SYN",N)) Q:N="" D .S LEX("S",I)=$P(LEX("SEL","EXP",N),U,2) K LEX("SEL") Q ; TEXT(LEXTEXT,LEXVDT,LEXSUB,LEXSRC,LEXRAY) ; ; ; Lexicon wrapper application to obtain concept data for a given text ; and source ; ; Input ; ; LEXTEXT the search string - mandatory ; LEXVDT effective date (defaults to current date) - optional ; LEXSUB subset or 'hierarchy' - optional ; LEXSRC code system source abbreviation e.g. SCT (SNOMED CT) ; - optional ; LEXRAY output array (defaults to 'LEX')- optional ; ; Output ; ; LEX or passed array name - an array containing information ; about the code ; LEX(0) - a five piece string: ; 1. code ; 2. hierarchy ; 3. version ; 4. legacy code ; 5. code status ; ; otherwise ; "-1^error text" ; ; example of LEX array: ; LEX(0)="67922002^Substance^20050701^T-C2500^1" ; LEX("F")="Serum (Substance)" ; LEX("P")="Serum" ; I $G(LEXTEXT)="" Q "-1^no search string specified" S LEXSRC=$G(LEXSRC) I $G(LEXVDT)'="" S LEXVDT=$$INTDAT(LEXVDT) I $G(LEXVDT)=-1 Q "-1^invalid date format" I $G(LEXVDT)="" S LEXVDT=$$DT^XLFDT S LEXSRC=$G(LEXSRC) S LEXSUB=$G(LEXSUB) I LEXSUB="" S LEXSUB=LEXSRC I $G(LEXRAY)="" K LEXRAY ; N X,LEXPIEN,LEXCODE,LEXSTAT,LEXCIEN,Y K ^TMP("LEXSCH",$J),LEX S X=LEXTEXT D CONFIG^LEXSET(LEXSRC,LEXSUB,LEXVDT) D EN^LEXA1 I +Y=-1 Q "-1^search could not find term" ; S LEXPIEN=+Y D INFO^LEXA(LEXPIEN) S LEXCODE=$O(LEX("SEL","SRC","C","")) S LEXSTAT=$$STATCHK^LEXSRC2(LEXCODE,LEXVDT,.LEXSTAT) S LEXCIEN=$P(LEXSTAT,U,2) S LEXSRC=$P(LEXSTAT(2),U,2) D GETINFO I $D(LEXRAY),LEXRAY'="LEX" M @LEXRAY=LEX K LEX Q "1^"_LEXPIEN ; VERSION(LEXSRC,LEXCODE,LEXVDT) ; ; infer version of code ; Input ; ; LEXSRC code system source abbreviation e.g. SCT (SNOMED CT) ; LEXCODE code - mandatory ; LEXVDT effective date (defaults to current date) - optional ; - optional ; ; Output ; ; 1^Version ; or ; -1^error message ; I $G(LEXVDT)'="" S LEXVDT=$$INTDAT(LEXVDT) I $G(LEXVDT)=-1 Q "-1^invalid date format" I $G(LEXVDT)="" S LEXVDT=$$DT^XLFDT N SIEN,VIEN,VDAT,LEXSTAT S SIEN=$O(^LEX(757.03,"B",LEXSRC,"")) I '$D(^LEX(757.03,SIEN,1)) Q "-1^No source version data available" S LEXSTAT=$$STATCHK^LEXSRC2(LEXCODE,LEXVDT,.LEXSTAT) I +LEXSTAT=0 Q "-1^Code not active for date specified" S VDAT=$O(^LEX(757.03,SIEN,1,"B",LEXVDT+1),-1) S VIEN=$O(^LEX(757.03,SIEN,1,"B",VDAT,"")) Q "1^"_^LEX(757.03,SIEN,1,VIEN,0) ; ; TXT4CS(LEXTEXT,LEXSRC,LEXRAY,LEXSUB) ; Is text valid for an SCT code ; ; Input ; ; LEXTEXT is term being checked ; LEXSRC is code system mnemonic or IEN ; LEXRAY output array (defaults to 'LEX') optional ; LEXSUB subset or 'hierarchy' - optional ; ; Output ; ; 1^no of finds ; plus ; LEX or passed array name - an array containing discovered ; concept IDs and expression type ; for finds ; e.g. LEX(113912006)="MAJOR CONCEPT" ; ; or ; ; -1^error message ; N EXP,EXIEN,MCIEN,FOUND,CIEN,CODE,EXPTYP,FINDS,LAR,HIER,HIERNAM,LEXW I $G(LEXTEXT)="" Q "-1^text not specified" I $G(LEXSRC)="" Q "-1^code system not specified" I $$CSYSIEN(LEXSRC)+$$CSYSMNEM(LEXSRC)=-2 Q "-1^code system unknown in Lexicon" I $G(LEXRAY)="" K LEXRAY S LEXSUB=$G(LEXSUB) I LEXSUB'="",'$D(^LEXT(757.2,"AA",LEXSUB)) Q "-1^hierarchy unknown in Lexicon" S:LEXSRC?.N LEXSRC=$P($$CSYSMNEM(LEXSRC),"^",2) ; text IEN's in 757.01 I '$D(^LEX(757.01,"B",$E($$UP^XLFSTR(LEXTEXT),1,63))) Q "-1^expression unknown in Lexicon" ; build an array of expression IENs for text S EXIEN="" F S EXIEN=$O(^LEX(757.01,"B",$$UP^XLFSTR(LEXTEXT),EXIEN)) Q:EXIEN="" D .S EXP(EXIEN)="" ; scan array to find code for expression (LEXTEXT) for code system (LEXSRC) S EXIEN="" K LEXW S (FOUND,FINDS)=0 F S EXIEN=$O(EXP(EXIEN)) Q:EXIEN="" D .S MCIEN=$P(^LEX(757.01,EXIEN,1),U) .S EXPTYP=$P(^LEX(757.011,$P(^LEX(757.01,EXIEN,1),U,2),0),U) .S CIEN="" .F S CIEN=$O(^LEX(757.02,"AMC",MCIEN,CIEN)) Q:CIEN="" D ..I $P($$CSYSMNEM($P(^LEX(757.02,CIEN,0),U,3)),U,2)=LEXSRC D ...S CODE=$P(^LEX(757.02,CIEN,0),U,2) ...S (HIER,HIERNAM)="" ...I LEXSUB'="" D ....K LAR ....S LAR=$$CODE(CODE,"SCT",,"LAR") ....S HIER=$P(LAR(0),U,2) ....S HIERNAM=$P(^LEXT(757.2,$O(^LEXT(757.2,"AA",LEXSUB,"")),0),U) ...I LEXSUB'="",HIER'=HIERNAM Q ...S FOUND=1 ...S FINDS=FINDS+1 ...S LEXW(CODE)=EXPTYP M LEX=LEXW I $D(LEXRAY),LEXRAY'="LEX" M @LEXRAY=LEX K LEX Q FOUND_"^"_FINDS ; CSYSIEN(MNEM) ; return code system IEN for mnemonic I '$D(^LEX(757.03,"B",MNEM)) Q "-1^code system unknown in Lexicon" Q "1^"_$O(^LEX(757.03,"B",MNEM,"")) ; CSYSMNEM(SIEN) ; return code system mnemonic for IEN I '$D(^LEX(757.03,SIEN)) Q "-1^code system unknown in Lexicon" Q "1^"_$P(^LEX(757.03,SIEN,0),"^") ; INTDAT(X) ; convert date from external format to VA internal format N Y D ^%DT Q Y