MAGDSTA7 ;WOIFO/PMK - Q/R Retrieve of DICOM images from PACS to VistA ; Mar 04, 2022@13:42:59
;;3.0;IMAGING;**231,305**;Mar 19, 2002;Build 3
;; Per VHA Directive 2004-038, this routine should not be modified.
;; +---------------------------------------------------------------+
;; | Property of the US Government. |
;; | No permission to copy or redistribute this software is given. |
;; | Use of unreleased versions of this software requires the user |
;; | to execute a written test agreement with the VistA Imaging |
;; | Development Office of the Department of Veterans Affairs, |
;; | telephone (301) 734-0100. |
;; | The Food and Drug Administration classifies this software as |
;; | a medical device. As such, it may not be changed in any way. |
;; | Modifications to this software may result in an adulterated |
;; | medical device under 21CFR820, the use of which is considered |
;; | to be a violation of US Federal Statutes. |
;; +---------------------------------------------------------------+
;;
;
; Supported IA #2056 reference $$GET1^DIQ function call
; Supported IA #2056 reference GETS^DIQ subroutine call
; Supported IA #10103 reference $$FMTE^XLFDT function call
; Controlled IA #4110 to read REQUEST/CONSULTATION file (#123)
; Controlled IA #3461 to read TIU EXTERNAL DATA LINK (#8825.91)
;
Q
;
; Look for images for partially resulted or completed studies.
;
MAIN() ; The main loop for the program for consults and procedures
; Input Variables
; SCANMODE ;-- "PATIENT", "DATE", or "NUMBER"
; DIRECTION ;- 1="ASCENDING" or 0="DESCENDING"
; BATCHSIZE ;- number of consult & procedure requests to process on this run
; BEGDATE ;--- begin date for search
; ENDDATE ;-- end date for search
; QRSCP ;----- default query/retrieve provider
; HOURS ;----- 24 character string of Y's and N's indicating active times
;
N GMRCIEN,RUNTIME,STOP,X
;
D HEADER^MAGDSTAA(0)
;
; STOP: -1=error, 0=run completed, 1=run stopped
S STOP=$$CONLKUP()
Q STOP
;
CONLKUP() ; Find the next study to retrieve
N STOP
I SCANMODE="PATIENT" D
. S STOP=$$PATIENT()
. Q
E I SCANMODE="DATE" D
. S STOP=$$DATE()
. Q
E I SCANMODE="NUMBER" D
. S STOP=$$NUMBER()
. Q
E D
. W !!,"*** Illegal SCAN MODE: """,SCANMODE,""""
. S STOP=-1
. Q
Q STOP
;
PATIENT() ; use "AD" cross-reference to find studies for a single patient
; ^GMR(123,"AD",DFN,GMRCDATE,GMRCIEN)=""
N DATEBEG,DATESTOP,DONE,GMRCDATE,STOP
S STOP=0 ; set to stop the q/r process
D SETDATES(.DATEBEG,.DATESTOP,BEGDATE,ENDDATE,DIRECTION)
S GMRCDATE=DATEBEG,DONE=0
; reverse date, opposite sort order
F S GMRCDATE=$O(^GMR(123,"AD",DFN,GMRCDATE),-DIRECTION) Q:'GMRCDATE Q:DONE Q:STOP D
. I DIRECTION=1 S DONE=GMRCDATE<DATESTOP Q:DONE
. E S DONE=GMRCDATE>DATESTOP Q:DONE
. S GMRCIEN=""
. F S GMRCIEN=$O(^GMR(123,"AD",DFN,GMRCDATE,GMRCIEN),DIRECTION) Q:'GMRCIEN Q:STOP D
. . ; does this consult get images?
. . I $$CHECK^MAGDSTA6(GMRCIEN)'=1 Q ; nope
. . S STOP=$$CONLKUP1(GMRCIEN)
. . Q
. Q
Q STOP
;
DATE() ; use "AE" cross-reference to find completed studies
; ^GMR(123,"AE",SERVICE,STATUS,GMRCDATE,GMRCIEN)=""
; only look for COMPLETED studies and PARTIAL RESULTS
N DATEBEG,DATESTOP,DONE,GMRCDATE,STATUS,STOP
S STOP=0 ; set to stop the q/r process
D SETDATES(.DATEBEG,.DATESTOP,BEGDATE,ENDDATE,DIRECTION)
S SERVICE="" F S SERVICE=$O(CONSULTSERVICES(SERVICE)) Q:SERVICE="" Q:STOP D
. F STATUS=2,9 D ; STATUS=2 for COMPLETE, STATUS=9 for PARTIAL RESULTS
. . W !!,CONSULTSERVICES(SERVICE)," -- "
. . W $S(STATUS=2:"COMPLETE",STATUS=9:"PARTIAL RESULTS",1:"Unknown Status "_STATUS)
. . S GMRCDATE=DATEBEG,DONE=0
. . ; reverse date, opposite sort order
. . F S GMRCDATE=$O(^GMR(123,"AE",SERVICE,STATUS,GMRCDATE),-DIRECTION) Q:'GMRCDATE Q:DONE Q:STOP D
. . . I DIRECTION=1 S DONE=GMRCDATE<DATESTOP Q:DONE
. . . E S DONE=GMRCDATE>DATESTOP Q:DONE
. . . S GMRCIEN=""
. . . F S GMRCIEN=$O(^GMR(123,"AE",SERVICE,STATUS,GMRCDATE,GMRCIEN),DIRECTION) Q:'GMRCIEN Q:STOP D
. . . . ; does this consult get images?
. . . . I $$CHECK^MAGDSTA6(GMRCIEN)'=1 Q ; nope
. . . . S STOP=$$CONLKUP1(GMRCIEN)
. . . . Q
. . . Q
. . Q
. Q
Q STOP
;
NUMBER() ; use GMRCIEN to find completed studies
; ^GMR(123,GMRC)=<consult record>
N BATCHSIZE,GMRCIEN,STOP,STUDYCNT
S STOP=0 ; set to stop the q/r process
S STUDYCNT=0
S BATCHSIZE=$G(^TMP("MAG",$J,"BATCH Q/R","BATCH SIZE"))
S GMRCIEN=$G(^TMP("MAG",$J,"BATCH Q/R","REPORT/STUDY IEN"))
S GMRCIEN=GMRCIEN-DIRECTION ; Massage value for $O
F S GMRCIEN=$O(^GMR(123,GMRCIEN),DIRECTION) Q:'GMRCIEN Q:STUDYCNT>=BATCHSIZE Q:STOP D
. ; does this consult get images?
. I $$CHECK^MAGDSTA6(GMRCIEN)'=1 Q ; nope
. S STUDYCNT=STUDYCNT+1
. S STOP=$$CONLKUP1(GMRCIEN)
. Q
Q STOP
;
CONLKUP1(GMRCIEN) ; check consult
N ACNUMB,DFN,EXAMDATE,I,ORDERINGFACILITY,MAGIENLIST
;
S ORDERINGFACILITY=$$GET1^DIQ(123,GMRCIEN,.05,"I")
I $$CHECKDIV^MAGDSTAB()="Y",ORDERINGFACILITY'=DIVISION Q 0 ; not this division
;
S ACNUMB=$$GMRCACN^MAGDFCNV(GMRCIEN) ; legacy or site-specific
S EXAMDATE=$$GET1^DIQ(123,GMRCIEN,.01,"I")
S DFN=$$GET1^DIQ(123,GMRCIEN,.02,"I")
I $$CONSULT(GMRCIEN,.MAGIENLIST)<0 Q 0
Q $$LOOKUP^MAGDSTAA(DFN,EXAMDATE,GMRCIEN,ACNUMB,.MAGIENLIST)
;
CONSULT(GMRCIEN,MAGIENLIST) ; return a list of MAG Group IENs
; A consult may have multiple TIU notes and a TIU note may have multiple image groups.
; A consult may also have images associated in the DICOM TEMP LIST file (#2006.5839).
N ERROR,GROUPIEN,I,MAG20065839,TIULIST,X
S ERROR=$$CONSULT1(GMRCIEN,.TIULIST)
I ERROR<0 Q ERROR
; a TIU note may have multiple image groups - get the list
F I=1:1:TIULIST(0) D
. D T892591(TIULIST(I),.MAGIENLIST)
. Q
S MAG20065839=""
F S MAG20065839=$O(^MAG(2006.5839,"C",123,GMRCIEN,MAG20065839)) Q:MAG20065839="" D
. S X=$G(^MAG(2006.5839,MAG20065839,0))
. S GROUPIEN=$P(X,"^",3)
. S MAGIENLIST(GROUPIEN)=""
. Q
Q 0
;
CONSULT1(GMRCIEN,TIULIST) ; return a list of TIU IENs
; a consult may have multiple TIU notes - get the list
N A,I,SS2,TIUIEN
K TIULIST ; initialize list of TIU IENs
S TIULIST(0)=0
D GETS^DIQ(123,GMRCIEN,"**","I","A")
I '$D(A) S OUT(1)="-1,Error in CONSULT1 with file #123 GMRCIEN Lookup" Q
S I=0,SS2="",I=0 F S SS2=$O(A(123.03,SS2)) Q:SS2="" D
. S TIUIEN=A(123.03,SS2,.01,"I")
. I $P(TIUIEN,";",2)="TIU(8925," D
. . S I=I+1,TIULIST(0)=I
. . S TIULIST(I)=$P(TIUIEN,";",1)
. . Q
. Q
Q 0
;
T892591(TIUIEN,MAGIENLIST) ;
N GROUPIEN,TIU892591
S TIU892591=""
F S TIU892591=$O(^TIU(8925.91,"B",TIUIEN,TIU892591)) Q:'TIU892591 D
. S GROUPIEN=$$GET1^DIQ(8925.91,TIU892591,.02,"I")
. S MAGIENLIST(GROUPIEN)=""
. Q
Q
;
SETDATES(DATEBEG,DATESTOP,BEGDATE,ENDDATE,DIRECTION) ; get date range
; get the beginning and ending dates for the FOR loop
; these are in GMRC reverse date format
; they are also DIRECTION specific
I DIRECTION=1 D ; ascending direction
. S DATEBEG=$$GMRCDATE(BEGDATE)
. S DATESTOP=$$GMRCDATE(ENDDATE)
. Q
E D ; descending direction
. S DATEBEG=$$GMRCDATE(ENDDATE)
. S DATESTOP=$$GMRCDATE(BEGDATE)
. Q
Q
;
GMRCDATE(GMRCDATE) ; convert a GMRC date to a FM date and vice versa
Q 9999999-GMRCDATE ; unlike radiology which uses 9999999.9999
;
I CONTINUE D CONTINUE^MAGDSTQ(0)
W @IOF," Patient",?12," Accession ",?30," Date",?40,"Images",?51,"Group #",?60,"VistA",?68,"PACS",?75,"Need"
W !,"---------",?12,"----------------",?30,"--------",?40,"------",?51,"-------",?60,"-----",?68,"----",?75,"----"
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HMAGDSTA7 7800 printed Nov 22, 2024@17:11:52 Page 2
MAGDSTA7 ;WOIFO/PMK - Q/R Retrieve of DICOM images from PACS to VistA ; Mar 04, 2022@13:42:59
+1 ;;3.0;IMAGING;**231,305**;Mar 19, 2002;Build 3
+2 ;; Per VHA Directive 2004-038, this routine should not be modified.
+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 ;; | The Food and Drug Administration classifies this software as |
+11 ;; | a medical device. As such, it may not be changed in any way. |
+12 ;; | Modifications to this software may result in an adulterated |
+13 ;; | medical device under 21CFR820, the use of which is considered |
+14 ;; | to be a violation of US Federal Statutes. |
+15 ;; +---------------------------------------------------------------+
+16 ;;
+17 ;
+18 ; Supported IA #2056 reference $$GET1^DIQ function call
+19 ; Supported IA #2056 reference GETS^DIQ subroutine call
+20 ; Supported IA #10103 reference $$FMTE^XLFDT function call
+21 ; Controlled IA #4110 to read REQUEST/CONSULTATION file (#123)
+22 ; Controlled IA #3461 to read TIU EXTERNAL DATA LINK (#8825.91)
+23 ;
+24 QUIT
+25 ;
+26 ; Look for images for partially resulted or completed studies.
+27 ;
MAIN() ; The main loop for the program for consults and procedures
+1 ; Input Variables
+2 ; SCANMODE ;-- "PATIENT", "DATE", or "NUMBER"
+3 ; DIRECTION ;- 1="ASCENDING" or 0="DESCENDING"
+4 ; BATCHSIZE ;- number of consult & procedure requests to process on this run
+5 ; BEGDATE ;--- begin date for search
+6 ; ENDDATE ;-- end date for search
+7 ; QRSCP ;----- default query/retrieve provider
+8 ; HOURS ;----- 24 character string of Y's and N's indicating active times
+9 ;
+10 NEW GMRCIEN,RUNTIME,STOP,X
+11 ;
+12 DO HEADER^MAGDSTAA(0)
+13 ;
+14 ; STOP: -1=error, 0=run completed, 1=run stopped
+15 SET STOP=$$CONLKUP()
+16 QUIT STOP
+17 ;
CONLKUP() ; Find the next study to retrieve
+1 NEW STOP
+2 IF SCANMODE="PATIENT"
Begin DoDot:1
+3 SET STOP=$$PATIENT()
+4 QUIT
End DoDot:1
+5 IF '$TEST
IF SCANMODE="DATE"
Begin DoDot:1
+6 SET STOP=$$DATE()
+7 QUIT
End DoDot:1
+8 IF '$TEST
IF SCANMODE="NUMBER"
Begin DoDot:1
+9 SET STOP=$$NUMBER()
+10 QUIT
End DoDot:1
+11 IF '$TEST
Begin DoDot:1
+12 WRITE !!,"*** Illegal SCAN MODE: """,SCANMODE,""""
+13 SET STOP=-1
+14 QUIT
End DoDot:1
+15 QUIT STOP
+16 ;
PATIENT() ; use "AD" cross-reference to find studies for a single patient
+1 ; ^GMR(123,"AD",DFN,GMRCDATE,GMRCIEN)=""
+2 NEW DATEBEG,DATESTOP,DONE,GMRCDATE,STOP
+3 ; set to stop the q/r process
SET STOP=0
+4 DO SETDATES(.DATEBEG,.DATESTOP,BEGDATE,ENDDATE,DIRECTION)
+5 SET GMRCDATE=DATEBEG
SET DONE=0
+6 ; reverse date, opposite sort order
+7 FOR
SET GMRCDATE=$ORDER(^GMR(123,"AD",DFN,GMRCDATE),-DIRECTION)
if 'GMRCDATE
QUIT
if DONE
QUIT
if STOP
QUIT
Begin DoDot:1
+8 IF DIRECTION=1
SET DONE=GMRCDATE<DATESTOP
if DONE
QUIT
+9 IF '$TEST
SET DONE=GMRCDATE>DATESTOP
if DONE
QUIT
+10 SET GMRCIEN=""
+11 FOR
SET GMRCIEN=$ORDER(^GMR(123,"AD",DFN,GMRCDATE,GMRCIEN),DIRECTION)
if 'GMRCIEN
QUIT
if STOP
QUIT
Begin DoDot:2
+12 ; does this consult get images?
+13 ; nope
IF $$CHECK^MAGDSTA6(GMRCIEN)'=1
QUIT
+14 SET STOP=$$CONLKUP1(GMRCIEN)
+15 QUIT
End DoDot:2
+16 QUIT
End DoDot:1
+17 QUIT STOP
+18 ;
DATE() ; use "AE" cross-reference to find completed studies
+1 ; ^GMR(123,"AE",SERVICE,STATUS,GMRCDATE,GMRCIEN)=""
+2 ; only look for COMPLETED studies and PARTIAL RESULTS
+3 NEW DATEBEG,DATESTOP,DONE,GMRCDATE,STATUS,STOP
+4 ; set to stop the q/r process
SET STOP=0
+5 DO SETDATES(.DATEBEG,.DATESTOP,BEGDATE,ENDDATE,DIRECTION)
+6 SET SERVICE=""
FOR
SET SERVICE=$ORDER(CONSULTSERVICES(SERVICE))
if SERVICE=""
QUIT
if STOP
QUIT
Begin DoDot:1
+7 ; STATUS=2 for COMPLETE, STATUS=9 for PARTIAL RESULTS
FOR STATUS=2,9
Begin DoDot:2
+8 WRITE !!,CONSULTSERVICES(SERVICE)," -- "
+9 WRITE $SELECT(STATUS=2:"COMPLETE",STATUS=9:"PARTIAL RESULTS",1:"Unknown Status "_STATUS)
+10 SET GMRCDATE=DATEBEG
SET DONE=0
+11 ; reverse date, opposite sort order
+12 FOR
SET GMRCDATE=$ORDER(^GMR(123,"AE",SERVICE,STATUS,GMRCDATE),-DIRECTION)
if 'GMRCDATE
QUIT
if DONE
QUIT
if STOP
QUIT
Begin DoDot:3
+13 IF DIRECTION=1
SET DONE=GMRCDATE<DATESTOP
if DONE
QUIT
+14 IF '$TEST
SET DONE=GMRCDATE>DATESTOP
if DONE
QUIT
+15 SET GMRCIEN=""
+16 FOR
SET GMRCIEN=$ORDER(^GMR(123,"AE",SERVICE,STATUS,GMRCDATE,GMRCIEN),DIRECTION)
if 'GMRCIEN
QUIT
if STOP
QUIT
Begin DoDot:4
+17 ; does this consult get images?
+18 ; nope
IF $$CHECK^MAGDSTA6(GMRCIEN)'=1
QUIT
+19 SET STOP=$$CONLKUP1(GMRCIEN)
+20 QUIT
End DoDot:4
+21 QUIT
End DoDot:3
+22 QUIT
End DoDot:2
+23 QUIT
End DoDot:1
+24 QUIT STOP
+25 ;
NUMBER() ; use GMRCIEN to find completed studies
+1 ; ^GMR(123,GMRC)=<consult record>
+2 NEW BATCHSIZE,GMRCIEN,STOP,STUDYCNT
+3 ; set to stop the q/r process
SET STOP=0
+4 SET STUDYCNT=0
+5 SET BATCHSIZE=$GET(^TMP("MAG",$JOB,"BATCH Q/R","BATCH SIZE"))
+6 SET GMRCIEN=$GET(^TMP("MAG",$JOB,"BATCH Q/R","REPORT/STUDY IEN"))
+7 ; Massage value for $O
SET GMRCIEN=GMRCIEN-DIRECTION
+8 FOR
SET GMRCIEN=$ORDER(^GMR(123,GMRCIEN),DIRECTION)
if 'GMRCIEN
QUIT
if STUDYCNT>=BATCHSIZE
QUIT
if STOP
QUIT
Begin DoDot:1
+9 ; does this consult get images?
+10 ; nope
IF $$CHECK^MAGDSTA6(GMRCIEN)'=1
QUIT
+11 SET STUDYCNT=STUDYCNT+1
+12 SET STOP=$$CONLKUP1(GMRCIEN)
+13 QUIT
End DoDot:1
+14 QUIT STOP
+15 ;
CONLKUP1(GMRCIEN) ; check consult
+1 NEW ACNUMB,DFN,EXAMDATE,I,ORDERINGFACILITY,MAGIENLIST
+2 ;
+3 SET ORDERINGFACILITY=$$GET1^DIQ(123,GMRCIEN,.05,"I")
+4 ; not this division
IF $$CHECKDIV^MAGDSTAB()="Y"
IF ORDERINGFACILITY'=DIVISION
QUIT 0
+5 ;
+6 ; legacy or site-specific
SET ACNUMB=$$GMRCACN^MAGDFCNV(GMRCIEN)
+7 SET EXAMDATE=$$GET1^DIQ(123,GMRCIEN,.01,"I")
+8 SET DFN=$$GET1^DIQ(123,GMRCIEN,.02,"I")
+9 IF $$CONSULT(GMRCIEN,.MAGIENLIST)<0
QUIT 0
+10 QUIT $$LOOKUP^MAGDSTAA(DFN,EXAMDATE,GMRCIEN,ACNUMB,.MAGIENLIST)
+11 ;
CONSULT(GMRCIEN,MAGIENLIST) ; return a list of MAG Group IENs
+1 ; A consult may have multiple TIU notes and a TIU note may have multiple image groups.
+2 ; A consult may also have images associated in the DICOM TEMP LIST file (#2006.5839).
+3 NEW ERROR,GROUPIEN,I,MAG20065839,TIULIST,X
+4 SET ERROR=$$CONSULT1(GMRCIEN,.TIULIST)
+5 IF ERROR<0
QUIT ERROR
+6 ; a TIU note may have multiple image groups - get the list
+7 FOR I=1:1:TIULIST(0)
Begin DoDot:1
+8 DO T892591(TIULIST(I),.MAGIENLIST)
+9 QUIT
End DoDot:1
+10 SET MAG20065839=""
+11 FOR
SET MAG20065839=$ORDER(^MAG(2006.5839,"C",123,GMRCIEN,MAG20065839))
if MAG20065839=""
QUIT
Begin DoDot:1
+12 SET X=$GET(^MAG(2006.5839,MAG20065839,0))
+13 SET GROUPIEN=$PIECE(X,"^",3)
+14 SET MAGIENLIST(GROUPIEN)=""
+15 QUIT
End DoDot:1
+16 QUIT 0
+17 ;
CONSULT1(GMRCIEN,TIULIST) ; return a list of TIU IENs
+1 ; a consult may have multiple TIU notes - get the list
+2 NEW A,I,SS2,TIUIEN
+3 ; initialize list of TIU IENs
KILL TIULIST
+4 SET TIULIST(0)=0
+5 DO GETS^DIQ(123,GMRCIEN,"**","I","A")
+6 IF '$DATA(A)
SET OUT(1)="-1,Error in CONSULT1 with file #123 GMRCIEN Lookup"
QUIT
+7 SET I=0
SET SS2=""
SET I=0
FOR
SET SS2=$ORDER(A(123.03,SS2))
if SS2=""
QUIT
Begin DoDot:1
+8 SET TIUIEN=A(123.03,SS2,.01,"I")
+9 IF $PIECE(TIUIEN,";",2)="TIU(8925,"
Begin DoDot:2
+10 SET I=I+1
SET TIULIST(0)=I
+11 SET TIULIST(I)=$PIECE(TIUIEN,";",1)
+12 QUIT
End DoDot:2
+13 QUIT
End DoDot:1
+14 QUIT 0
+15 ;
T892591(TIUIEN,MAGIENLIST) ;
+1 NEW GROUPIEN,TIU892591
+2 SET TIU892591=""
+3 FOR
SET TIU892591=$ORDER(^TIU(8925.91,"B",TIUIEN,TIU892591))
if 'TIU892591
QUIT
Begin DoDot:1
+4 SET GROUPIEN=$$GET1^DIQ(8925.91,TIU892591,.02,"I")
+5 SET MAGIENLIST(GROUPIEN)=""
+6 QUIT
End DoDot:1
+7 QUIT
+8 ;
SETDATES(DATEBEG,DATESTOP,BEGDATE,ENDDATE,DIRECTION) ; get date range
+1 ; get the beginning and ending dates for the FOR loop
+2 ; these are in GMRC reverse date format
+3 ; they are also DIRECTION specific
+4 ; ascending direction
IF DIRECTION=1
Begin DoDot:1
+5 SET DATEBEG=$$GMRCDATE(BEGDATE)
+6 SET DATESTOP=$$GMRCDATE(ENDDATE)
+7 QUIT
End DoDot:1
+8 ; descending direction
IF '$TEST
Begin DoDot:1
+9 SET DATEBEG=$$GMRCDATE(ENDDATE)
+10 SET DATESTOP=$$GMRCDATE(BEGDATE)
+11 QUIT
End DoDot:1
+12 QUIT
+13 ;
GMRCDATE(GMRCDATE) ; convert a GMRC date to a FM date and vice versa
+1 ; unlike radiology which uses 9999999.9999
QUIT 9999999-GMRCDATE
+2 ;
+1 IF CONTINUE
DO CONTINUE^MAGDSTQ(0)
+2 WRITE @IOF," Patient",?12," Accession ",?30," Date",?40,"Images",?51,"Group #",?60,"VistA",?68,"PACS",?75,"Need"
+3 WRITE !,"---------",?12,"----------------",?30,"--------",?40,"------",?51,"-------",?60,"-----",?68,"----",?75,"----"
+4 QUIT