Home   Package List   Routine Alphabetical List   Global Alphabetical List   FileMan Files List   FileMan Sub-Files List   Package Component Lists   Package-Namespace Mapping  
Routine: MAGDSTAF

MAGDSTAF.m

Go to the documentation of this file.
  1. MAGDSTAF ;WOIFO/PMK - Q/R Retrieve of DICOM images from PACS to VistA ; Sep 17, 2020@13:11:24
  1. ;;3.0;IMAGING;**231**;5-May-2007;Build 9
  1. ;; Per VHA Directive 2004-038, this routine should not be modified.
  1. ;; +---------------------------------------------------------------+
  1. ;; | Property of the US Government. |
  1. ;; | No permission to copy or redistribute this software is given. |
  1. ;; | Use of unreleased versions of this software requires the user |
  1. ;; | to execute a written test agreement with the VistA Imaging |
  1. ;; | Development Office of the Department of Veterans Affairs, |
  1. ;; | telephone (301) 734-0100. |
  1. ;; | The Food and Drug Administration classifies this software as |
  1. ;; | a medical device. As such, it may not be changed in any way. |
  1. ;; | Modifications to this software may result in an adulterated |
  1. ;; | medical device under 21CFR820, the use of which is considered |
  1. ;; | to be a violation of US Federal Statutes. |
  1. ;; +---------------------------------------------------------------+
  1. ;;
  1. Q
  1. ;
  1. ; Fourth Step - Get missing images from PACS.
  1. ;
  1. ; VistA appears to be missing one or more images. Get them from the PACS
  1. ;
  1. ; Perform the following steps to get the missing images from the PACS:
  1. ; a. Issue a PACS Study Root Series Level query (C-FIND) using the Study
  1. ; Instance UID (0020,000D) as the key. Request the following return
  1. ; data attributes:
  1. ; i. Series Instance UID (0020,000E)
  1. ; ii. Number of Series Related Instances (0020,1209)
  1. ;
  1. ; b. For each Series Instance UID, if the number of Series Related Instances
  1. ; (0020,1209) is greater than the number of SOP Instances for that series
  1. ; on VistA, do the following steps:
  1. ; i. Use the Study Instance UID and Series Instance UID to issue a
  1. ; PACS Study Root Image Level query (C-FIND) to obtain the list
  1. ; of SOP Instance UIDs (0008,0018) for the series.
  1. ; ii. Compare the SOP Instance UIDs (0008,0018) from the PACS against
  1. ; those on VistA. Make a list of missing SOP Instances.
  1. ; iii. Use the Study Instance UID (0020,000D), Series Instance UID
  1. ; (0020,000E), and the list of missing SOP Instances (0008,0018) to
  1. ; issue a Study Root Image Level retrieve (C-MOVE) to copy the missing
  1. ; SOP Instances from the PACS to VistA.
  1. ;
  1. ;
  1. ; Note: PACS STUDYUID and VISTA STUDYUID are both multiples, since PACS and VistA
  1. ; may have more than on Study UID per study.
  1. ; GETIMAGE is called for each PACSSERIESUID for the study.
  1. ;
  1. GETIMAGE(PACSSERIESUID) ; retrieve one series of "PACS ONLY" SOP Instances
  1. N PACSSTUDYUID
  1. D QRSTATUS^MAGDSTAA("Getting SOP Instance UIDs for a series")
  1. ;
  1. ; get each PACSSTUDYUID from the multiple and process it
  1. ;
  1. S PACSSTUDYUID=""
  1. S PACSSTUDYUID=$O(^TMP("MAG",$J,"UIDS","PACS SERIES UID",PACSSERIESUID,"STUDY UID","")) Q:PACSSTUDYUID="" D
  1. . D STUDYUID(PACSSTUDYUID,PACSSERIESUID)
  1. . Q
  1. Q
  1. ;
  1. STUDYUID(PACSSTUDYUID,PACSSERIESUID) ; process one PACS Study Instance UID
  1. N I,SOPUID
  1. ;
  1. ; get the list of sop instances for the series and compare against VistA
  1. D GETSOPU(PACSSTUDYUID,PACSSERIESUID)
  1. D QRSTATUS^MAGDSTAA("Comparing SOP Instance UIDs for the series")
  1. D UIDCOMP(PACSSTUDYUID,PACSSERIESUID)
  1. ;
  1. ; retrieve the missing "PACS ONLY" images
  1. ;
  1. K ^TMP("MAG",$J,"Q/R QUERY")
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"STUDY INSTANCE UID(0001)")=PACSSTUDYUID
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"SERIES INSTANCE UID(0001)")=PACSSERIESUID
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"QUERY USER APPLICATION")=$$QRSCP^MAGDSTA8
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"RETRIEVE LEVEL")="IMAGE"
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"ROOT")="STUDY"
  1. S I=10000,SOPUID=""
  1. F S SOPUID=$O(^TMP("MAG",$J,"UIDS","PACS ONLY",PACSSTUDYUID,PACSSERIESUID,SOPUID)) Q:SOPUID="" D
  1. . S I=I+1,^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"SOP INSTANCE UID("_$E(I,2,5)_")")=SOPUID
  1. . Q
  1. S I=I-10000 ; remove numeric offset
  1. I I>1 D
  1. . D QRSTATUS^MAGDSTAA("Retrieving "_(I)_" images for one series")
  1. . Q
  1. E D
  1. . D QRSTATUS^MAGDSTAA("Retrieving one image for one series")
  1. . Q
  1. D STTINC^MAGDSTAA("PACS SERIES LEVEL RETRIEVES",1)
  1. D STTINC^MAGDSTAA("PACS IMAGES RETRIEVED",(I))
  1. D SOPUIDR^MAGDSTV1 ; C-MOVE
  1. Q
  1. ;
  1. GETSOPU(PACSSTUDYUID,PACSSERIESUID) ; query for the SOP Instance UIDs for the series
  1. N COUNT,I,SOPUID
  1. K ^TMP("MAG",$J,"Q/R QUERY")
  1. K ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,PACSSERIESUID)
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"STUDY INSTANCE UID(0001)")=PACSSTUDYUID
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"SERIES INSTANCE UID(0001)")=PACSSERIESUID
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"QUERY USER APPLICATION")=$$QRSCP^MAGDSTA8
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"QUERY LEVEL")="IMAGE"
  1. S ^TMP("MAG",$J,"Q/R QUERY",QRSTACK,"ROOT")="STUDY"
  1. D SOPUIDQ^MAGDSTV1 ; C-FIND
  1. S COUNT=$G(^XTMP(MAGXTMP,HOSTNAME,$J,QRSTACK,"IMAGE",1,1,1))
  1. F I=1:1:COUNT D
  1. . S SOPUID=$G(^XTMP(MAGXTMP,HOSTNAME,$J,QRSTACK,"IMAGE",1,1,1,I,"SOPUID"),"*")
  1. . S ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,PACSSERIESUID,SOPUID)=""
  1. . Q
  1. S ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,PACSSERIESUID,0)=COUNT
  1. Q
  1. ;
  1. UIDCOMP(PACSSTUDYUID,PACSSERIESUID) ;
  1. ; Compare the UIDs between those on PACS with those on VistA
  1. ; Return a count of UIDs on both as well as lists of missing ones
  1. ;
  1. ; Note that both PACS and VistA may have multiple Study Instance UIDs
  1. ; and that they may be different.
  1. ;
  1. ; Input: ^TMP("MAG",$J,"UIDS","VISTA",VISTASTUDYUID,SERIESUID,SOPUID)=""
  1. ; ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,SERIESUID,SOPUID)=""
  1. ;
  1. ; Output: BOTH - count of identical UIDs on both VistA and PACS
  1. ; ^TMP("MAG",$J,"UIDS","PACS ONLY",PACSSTUDYUID,SERIESUID,SOPUID)=""
  1. ; ^TMP("MAG",$J,"UIDS","VISTA ONLY",VISTASTUDYUID,SERIESUID,SOPUID)=""
  1. ; ^TMP("MAG",$J,"UIDS","COUNTS","BOTH")
  1. ; ^TMP("MAG",$J,"UIDS","COUNTS","PACS")
  1. ; ^TMP("MAG",$J,"UIDS","COUNTS","PACS ONLY")
  1. ; ^TMP("MAG",$J,"UIDS","COUNTS","VISTA")
  1. ; ^TMP("MAG",$J,"UIDS","COUNTS","VISTA ONLY")
  1. ;
  1. N BOTH,COUNT,MISSINGUIDS,PACSUIDS,VISTAUIDS,VISTASTUDYUID
  1. K ^TMP("MAG",$J,"UIDS","COUNTS"),^("PACS ONLY"),^("VISTA ONLY")
  1. ;
  1. ; build lists of SOP Instance UIDs (PACSSTUDYUID is a scalar)
  1. S ^TMP("MAG",$J,"UIDS","COUNTS","PACS")=$$UIDLIST("PACS",PACSSTUDYUID,PACSSERIESUID,.PACSUIDS)
  1. ;
  1. ; get each VISTASTUDYUID from the multiple and process it
  1. ;
  1. S ^TMP("MAG",$J,"UIDS","COUNTS","VISTA")=0,VISTASTUDYUID=""
  1. F S VISTASTUDYUID=$O(^TMP("MAG",$J,"UIDS","VISTA SERIES UID",PACSSERIESUID,"STUDY UID",VISTASTUDYUID)) Q:VISTASTUDYUID="" D
  1. . S COUNT=$$UIDLIST("VISTA",VISTASTUDYUID,PACSSERIESUID,.VISTAUIDS)
  1. . S ^TMP("MAG",$J,"UIDS","COUNTS","VISTA")=^TMP("MAG",$J,"UIDS","COUNTS","VISTA")+COUNT
  1. . Q
  1. ;
  1. ; compare PACS UIDs against VistA UIDs
  1. D SUBTRACT(.PACSUIDS,.VISTAUIDS,.MISSINGUIDS,.MISSING,.BOTH)
  1. S ^TMP("MAG",$J,"UIDS","COUNTS","BOTH")=BOTH
  1. S ^TMP("MAG",$J,"UIDS","COUNTS","PACS ONLY")=MISSING
  1. M ^TMP("MAG",$J,"UIDS","PACS ONLY",PACSSTUDYUID)=MISSINGUIDS
  1. ;
  1. ; don't need to compare VistA UIDs against PACS UIDs
  1. Q
  1. ;
  1. UIDLIST(SYSTEM,STUDYUID,SERIESUID,ARRAY) ; get an array of Series and SOP Instance UIDs
  1. N COUNT,SOPUID
  1. S COUNT=0 ; SOP Instance UID count
  1. ;
  1. ; build the array of SOP Instance UIDs and get count
  1. S SOPUID=0 ; skip count
  1. F S SOPUID=$O(^TMP("MAG",$J,"UIDS",SYSTEM,STUDYUID,SERIESUID,SOPUID)) Q:SOPUID="" D
  1. . S ARRAY(SERIESUID,SOPUID)=""
  1. . S COUNT=COUNT+1
  1. . Q
  1. Q COUNT
  1. ;
  1. SUBTRACT(A,B,C,MISSING,SAME) ; UID set subtraction
  1. ; A, B, and C are arrays of Series and SOP Instance UIDs
  1. ; C = all the nodes of A minus the nodes of B
  1. N SS1,SS2
  1. K C S (MISSING,SAME)=0
  1. M C=A
  1. S SS1=0
  1. F S SS1=$O(A(SS1)) Q:SS1="" D
  1. . S SS2=0
  1. . F S SS2=$O(A(SS1,SS2)) Q:SS2="" D
  1. . . I $D(B(SS1,SS2)) D ; same node in B and A (now C)
  1. . . . K C(SS1,SS2) ; remove B's node from C
  1. . . . S SAME=SAME+1 ; count of same nodes
  1. . . . Q
  1. . . E D ; node in B is missing in A (now C)
  1. . . . S MISSING=MISSING+1
  1. . . . Q
  1. . . Q
  1. . Q
  1. Q
  1. ;
  1. TEST1 ; test of SUBTRACT subroutine
  1. ; N A,B,C,MISSING,SAME
  1. S A(1,1)="1,1"
  1. S A(2,1)="2,1"
  1. S B(1,1)="ONE,ONE"
  1. S B(2,2)="TWO,TWO"
  1. D SUBTRACT(.A,.B,.C,.MISSING,.SAME)
  1. W !,"Same=",SAME," Missing=",MISSING," This should be C(2,1)=""2,1"""
  1. D TEST1A
  1. D SUBTRACT(.B,.A,.C,.MISSING,.SAME)
  1. W !!,"Same=",SAME," Missing=",MISSING," This should be C(2,2)=""TWO,TWO"""
  1. D TEST1A
  1. Q
  1. ;
  1. TEST1A ; output
  1. N SS1,SS2
  1. S SS1=""
  1. F S SS1=$O(C(SS1)) Q:SS1="" D
  1. . S SS2=""
  1. . F S SS2=$O(C(SS1,SS2)) Q:SS2="" D
  1. . . W !,"C(",SS1,",",SS2,")=""",C(SS1,SS2),""""
  1. . . Q
  1. . Q
  1. Q
  1. ;
  1. TEST2 ; test of UIDCOMP subroutine
  1. N I,PACSSTUDYUID,VISTASTUDYUID
  1. S PACSSTUDYUID="PACS STUDY UID",VISTASTUDYUID="VISTA STUDY UID"
  1. K ^TMP("MAG",$J,"UIDS")
  1. F I=1:1:5 S ^TMP("MAG",$J,"UIDS","VISTA",VISTASTUDYUID,"A",$C(65+I))=""
  1. F I=4:1:9 S ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,"A",$C(65+I))=""
  1. F I=4:1:9 S ^TMP("MAG",$J,"UIDS","VISTA",VISTASTUDYUID,"B",$C(75+I))=""
  1. F I=1:1:5 S ^TMP("MAG",$J,"UIDS","PACS",PACSSTUDYUID,"B",$C(75+I))=""
  1. D UIDCOMP(PACSSTUDYUID,VISTASTUDYUID,"A")
  1. W !!,"Numbers should be 2, 6, 4, 5, and 3"
  1. D TEST2A("A")
  1. D UIDCOMP(PACSSTUDYUID,VISTASTUDYUID,"B")
  1. W !!,"Numbers should be 2, 5, 3, 6, and 4"
  1. D TEST2A("B")
  1. Q
  1. ;
  1. TEST2A(SERIESUID) ; report
  1. W !,"Series UID: """,SERIESUID,""""
  1. F A="BOTH","PACS","PACS ONLY","VISTA","VISTA ONLY" D
  1. . W !,$J(A,10),": ",^TMP("MAG",$J,"UIDS","COUNTS",A)
  1. . Q
  1. Q