1 | MAGDIR8A ;WOIFO/PMK - Read a DICOM image file ; 03/08/2005 07:02
|
---|
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 | ;
|
---|
19 | ; M2MB server
|
---|
20 | ;
|
---|
21 | ; Lookup the patient/study in the imaging service's database
|
---|
22 | ; Different entry points are invoked from LOOKUP^MAGDIR81
|
---|
23 | ;
|
---|
24 | RADLKUP ; Radiology patient/study lookup -- called by ^MAGDIR81
|
---|
25 | ; (also invoked by ^MAGDEXC4, ^MAGDFND4 and ^MAGDIW1)
|
---|
26 | ;
|
---|
27 | ; returns RADATA array DFN, DATETIME, and PROCDESC
|
---|
28 | ;
|
---|
29 | N CPTCODE ;-- CPT code for the procedure
|
---|
30 | N CPTNAME ;-- CPT name for the procedure
|
---|
31 | N EXAMSTS ;-- Exam status (don't post images to CANCELLED exams)
|
---|
32 | N PROCIEN ;-- radiology procedure ien in ^RAMIS(71)
|
---|
33 | N RAIX ;----- cross reference subscript for case number lookup
|
---|
34 | N RADPT1 ;--- first level subscript in ^RADPT
|
---|
35 | N RADPT2 ;--- second level subscript in ^RADPT (after "DT")
|
---|
36 | N RADPT3 ;--- third level subscript in ^RADPT (after "P")
|
---|
37 | N I,LIST,VARIABLE,X,Z
|
---|
38 | ;
|
---|
39 | ; find the patient/study in ^RARPT using the Radiology Case Number
|
---|
40 | K RADATA ; kill returned array of Radiology Package data
|
---|
41 | D RADLKUP1
|
---|
42 | S LIST="RADPT1^RADPT2^RADPT3^PROCIEN^CPTCODE^CPTNAME^Z^EXAMSTS"
|
---|
43 | F I=1:1:$L(LIST,"^") D
|
---|
44 | . S VARIABLE=$P(LIST,"^",I)
|
---|
45 | . S RADATA(VARIABLE)=$G(@VARIABLE)
|
---|
46 | . Q
|
---|
47 | Q
|
---|
48 | ;
|
---|
49 | RADLKUP1 ; not an entry point
|
---|
50 | Q:CASENUMB="" ;LB 12/16/98
|
---|
51 | S RAIX=$S($D(^RADPT("C")):"C",1:"AE") ; for Radiology Patch RA*5*7
|
---|
52 | S RAIX=$S(CASENUMB["-":"ADC",1:RAIX) ; select the cross-reference
|
---|
53 | S RADPT1=$O(^RADPT(RAIX,CASENUMB,"")) I 'RADPT1 Q
|
---|
54 | S RADPT2=$O(^RADPT(RAIX,CASENUMB,RADPT1,"")) I 'RADPT2 Q
|
---|
55 | S RADPT3=$O(^RADPT(RAIX,CASENUMB,RADPT1,RADPT2,"")) I 'RADPT3 Q
|
---|
56 | S X=$O(^RADPT(RAIX,CASENUMB,RADPT1,RADPT2,RADPT3))
|
---|
57 | I '$D(^RADPT(RADPT1,0)) Q ; no patient demographics file pointer
|
---|
58 | ; get patient demographics file pointer
|
---|
59 | S X=^RADPT(RADPT1,0),DFN=$P(X,"^")
|
---|
60 | I '$D(^RADPT(RADPT1,"DT",RADPT2,0)) Q ; no datetime level
|
---|
61 | ; get date and time of examination
|
---|
62 | S DATETIME=$P($G(^RADPT(RADPT1,"DT",RADPT2,0)),"^",1)
|
---|
63 | ; get case info
|
---|
64 | S X=$G(^RADPT(RADPT1,"DT",RADPT2,"P",RADPT3,0))
|
---|
65 | S PROCIEN=$P(X,"^",2),EXAMSTS=$P(X,"^",3)
|
---|
66 | I EXAMSTS S EXAMSTS=$$GET1^DIQ(72,EXAMSTS,.01)
|
---|
67 | S (PROCDESC,CPTNAME,CPTCODE)=""
|
---|
68 | I 'PROCIEN Q ; need PROCIEN to do lookup in ^RAMIS
|
---|
69 | S Z=$G(^RAMIS(71,PROCIEN,0))
|
---|
70 | S PROCDESC=$P(Z,"^"),CPTCODE=$P(Z,"^",9)
|
---|
71 | S CPTNAME=PROCDESC ; approximate value since ^ICPT is not translated
|
---|
72 | Q
|
---|
73 | ;
|
---|
74 | CONLKUP ; CPRS Consult/Procedure patient/study lookup -- called by ^MAGDIR81
|
---|
75 | N EXAMSTS ;-- Exam status (don't post images to CANCELLED exams)
|
---|
76 | N CONPROC,Z
|
---|
77 | I ACNUMB'?1"GMRC-".1N.N Q
|
---|
78 | S GMRCIEN=$P(ACNUMB,"-",2)
|
---|
79 | S DFN=$$GET1^DIQ(123,GMRCIEN,.02,"I")
|
---|
80 | I DFN="" Q ; no patient demographics file pointer
|
---|
81 | S EXAMSTS=$$GET1^DIQ(123,GMRCIEN,8) ; check for cancelled exam
|
---|
82 | I EXAMSTS="CANCELLED" S RADATA("EXAMSTS")=EXAMSTS Q
|
---|
83 | S PROCDESC=$$GET1^DIQ(123,GMRCIEN,1)
|
---|
84 | S Z=$$GET1^DIQ(123,GMRCIEN,13,"I") ; request type
|
---|
85 | S CONPROC=$S(Z="C":"CONSULT",Z="P":"PROCEDURE",1:"UNKNOWN")
|
---|
86 | Q
|
---|
87 | ;
|
---|
88 | PIDCHECK() ; compare VistA patient ID with DICOM patient ID
|
---|
89 | N CHECK ;---- patient demographic comparison check value
|
---|
90 | N FIRSTVAH ;- patient first name from VADM(1)
|
---|
91 | N IDDCM ;---- patient id, w/o punctuation, from image header
|
---|
92 | N IDVAH ;---- patient id from VADM(2)
|
---|
93 | N LASTVAH ;-- patient last name from VADM(1)
|
---|
94 | N MIVAH ;---- patient middle initial from VADM(1)
|
---|
95 | N DIQUIET,I,VA,VAERR,X,Y
|
---|
96 | ;
|
---|
97 | S X=PNAMEDCM X ^%ZOSF("UPPERCASE") S PNAMEDCM=Y
|
---|
98 | ; parse the DICOM patient name (2 formats)
|
---|
99 | I PNAMEDCM["^" D ; DICOM format patient name
|
---|
100 | . S LASTDCM=$P(PNAMEDCM,"^"),FIRSTDCM=$P(PNAMEDCM,"^",2)
|
---|
101 | . S MIDCM=$P(PNAMEDCM,"^",3)
|
---|
102 | . Q
|
---|
103 | E I PNAMEDCM["," D ; ACR-NEMA format patient name
|
---|
104 | . F Q:'$F(PNAMEDCM,", ") D ; remove blanks after last name comma
|
---|
105 | . . S PNAMEDCM=$P(PNAMEDCM,", ")_","_$P(PNAMEDCM,", ",2,999)
|
---|
106 | . . Q
|
---|
107 | . S LASTDCM=$P(PNAMEDCM,","),FIRSTDCM=$P(PNAMEDCM,",",2)
|
---|
108 | . S MIDCM=$S(PNAMEDCM[",":$P(FIRSTDCM,",",2),1:$P(FIRSTDCM," ",2,999))
|
---|
109 | . Q
|
---|
110 | E D ; patient name in "last first mi" order with space delimiters
|
---|
111 | . S LASTDCM=$P(PNAMEDCM," "),FIRSTDCM=$P(PNAMEDCM," ",2)
|
---|
112 | . S MIDCM=$P(PNAMEDCM," ",3)
|
---|
113 | . Q
|
---|
114 | S FIRSTDCM=$S(FIRSTDCM[",":$P(FIRSTDCM,","),1:$P(FIRSTDCM," "))
|
---|
115 | ; only check the first part of the name
|
---|
116 | ; remove dashes and atypical punctuation from the DICOM PID
|
---|
117 | S IDDCM="" F I=1:1:$L(PID) I $E(PID,I)?1AN S IDDCM=IDDCM_$E(PID,I)
|
---|
118 | ;
|
---|
119 | I CASENUMB="" Q "-1,NO CASE #"
|
---|
120 | I '$G(DFN) Q "-2,BAD CASE #"
|
---|
121 | I $G(RADATA("EXAMSTS"))="CANCELLED" Q "-3,CANCELLED"
|
---|
122 | ;
|
---|
123 | ; lookup patient in VistA database
|
---|
124 | S DIQUIET=1 D DEM^VADPT
|
---|
125 | S PNAMEVAH=VADM(1)
|
---|
126 | S LASTVAH=$P(PNAMEVAH,","),FIRSTVAH=$P(PNAMEVAH,",",2)
|
---|
127 | S MIVAH=$TR($P(FIRSTVAH," ",2,999),"."),FIRSTVAH=$P(FIRSTVAH," ")
|
---|
128 | S IDVAH=$P(VADM(2),"^"),DCMPID=$P(VADM(2),"^",2)
|
---|
129 | ;
|
---|
130 | ; compare the values - allow a single transposition in the patient name,
|
---|
131 | ; but require exact patient id values (i.e., social security numbers)
|
---|
132 | S CHECK=(5*$$COMPARE(LASTDCM,LASTVAH))
|
---|
133 | S CHECK=CHECK+(5*$$COMPARE($E(FIRSTDCM,1,6),$E(FIRSTVAH,1,6)))
|
---|
134 | S CHECK=CHECK+(1*$$COMPARE(MIDCM,MIVAH))
|
---|
135 | S CHECK=CHECK+(5*(IDDCM=IDVAH)) ; patient id requires an exact match
|
---|
136 | I CHECK<14.5 Q "-4,PID ERROR" ; require an "almost exact" match
|
---|
137 | Q 0 ; correct patient
|
---|
138 | ;
|
---|
139 | COMPARE(A,B) ; pattern match checker
|
---|
140 | Q:A=B 1 ; exact match
|
---|
141 | Q:A="" 0 Q:B="" 0 ; don't count missing data
|
---|
142 | ; calculate fractional value for pattern match
|
---|
143 | N I,LENGTH,MATCH
|
---|
144 | S MATCH=0,LENGTH=$S($L(B)>$L(A):$L(B),1:$L(A))
|
---|
145 | F I=1:1:LENGTH D
|
---|
146 | . I $E(A,I)=$E(B,I) S MATCH=MATCH+1
|
---|
147 | . E I $E(A,I)=$E(B,I-1) S MATCH=MATCH+.25
|
---|
148 | . E I $E(A,I)=$E(B,I+1) S MATCH=MATCH+.25
|
---|
149 | . E I $E(A,I-1)=$E(B,I) S MATCH=MATCH+.25
|
---|
150 | . E I $E(A,I+1)=$E(B,I) S MATCH=MATCH+.25
|
---|
151 | . Q
|
---|
152 | Q MATCH/LENGTH ; return fractional pattern match value
|
---|