1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #include "def_epi.h"
8 #include "ep_afni.h"
9
10 EXT struct im_info imX[] ;
11
12 /*****************************************************************************/
13
AFNI_exit(void)14 void AFNI_exit(void) /* Function to be called to make sure */
15 { /* the AFNI data channels get closed. */
16 iochan_close(AFNI_ioc) ;
17 return ;
18 }
19
20 /*****************************************************************************
21 Do I/O startup stuff; nim images are in the imX buffer at this time.
22
23 At any given moment, this routine is in one of a number of modes
24 (the AFNI_mode variable).
25 The first time in, AFNI_mode == AFNI_OPEN_CONTROL_MODE. In each mode,
26 certain tasks must be accomplished and this program must be synchronized
27 with AFNI. When the necessary deeds are done, the routine advances to
28 the next mode. If the deeds cannot be done when this routine is called,
29 then it will stay in the same mode, and the next time it is called it
30 will try to do them again. This routine should be called repeatedly
31 until it progresses to the last mode (AFNI_CONTINUE_MODE), which is for
32 normal transmission of images (one at a time) to AFNI. This operation
33 is handled in the separate routine AFNI_send_image (infra).
34
35 If an error occurs, so that this program can no longer talk to AFNI, then
36 AFNI_mode is set to 0, which means "do nothing further". The rest of
37 the data acquisition software will continue, but these routines will
38 be stopped dead.
39 ******************************************************************************/
40
AFNI_start_io(int nim)41 void AFNI_start_io( int nim )
42 {
43 int ii , jj ;
44
45 /***** Check for illegal conditions *****/
46
47 if( AFNI_mode <= 0 || AFNI_mode == AFNI_CONTINUE_MODE ) return ;
48
49 /***** If we are at the first time in,
50 try to open a control socket to talk to AFNI *****/
51
52 if( AFNI_mode == AFNI_OPEN_CONTROL_MODE ){
53
54 sprintf( AFNI_iochan , "tcp:%s:%d" ,
55 AFNI_host , get_port_named("AFNI_CONTROL_PORT") ) ;
56
57 if( AFNI_verbose )
58 fprintf(stderr,"Opening control channel %s to AFNI.\n",AFNI_iochan) ;
59
60 AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ;
61
62 if( AFNI_ioc == NULL ){
63 fprintf(stderr,"Can't open control channel %s to AFNI!\a\n",AFNI_iochan) ;
64 AFNI_mode = 0 ; /* disable AFNI */
65 return ;
66 } else {
67 if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_WAIT_CONTROL_MODE.\n") ;
68 AFNI_mode = AFNI_WAIT_CONTROL_MODE ; /* begin waiting for AFNI connection */
69 }
70 }
71
72 /***** Check if the control socket is connected to AFNI *****/
73
74 if( AFNI_mode == AFNI_WAIT_CONTROL_MODE ){
75
76 ii = iochan_writecheck( AFNI_ioc , 1 ) ; /* Check; wait at most 1 msec */
77
78 /** if ii == 0, then the channel is still pending,
79 so do nothing; otherwise, take some action. **/
80
81 if( ii < 0 ){
82 fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
83 IOCHAN_CLOSE(AFNI_ioc) ;
84 AFNI_mode = 0 ; /* disable AFNI */
85 return ;
86 } else if( ii > 0 ){
87 if( AFNI_verbose ) fprintf(stderr,"Control channel connected to AFNI."
88 " Entering AFNI_OPEN_DATA_MODE.\n") ;
89 AFNI_mode = AFNI_OPEN_DATA_MODE ; /* prepare to send data to AFNI */
90 }
91 }
92
93 /***** Send the control information, which says
94 how we will talk to AFNI in the future (shmem or TCP/IP),
95 then close the control channel and open this new data channel *****/
96
97 if( AFNI_mode == AFNI_OPEN_DATA_MODE ){
98
99 /* decide name of data channel: it can be TCP/IP or shared memory */
100
101 if( AFNI_use_tcp ) sprintf(AFNI_iochan,"tcp:%s:%d",
102 AFNI_host,get_port_named("AFNI_TCP_PORT")) ;
103 else strcpy(AFNI_iochan,"shm:eps:1M") ;
104
105 strcpy(AFNI_buf,AFNI_iochan) ; /* tell AFNI where to read data */
106 if( AFNI_infocom[0] != '\0' ){
107 strcat(AFNI_buf,"\n") ;
108 strcat(AFNI_buf,AFNI_infocom) ; /* tell it where to get 3T info */
109 }
110
111 if( AFNI_verbose )
112 fprintf(stderr,"Sending control information to AFNI:\n%s\n",AFNI_buf) ;
113
114 ii = iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
115
116 /** A negative return is bad news **/
117
118 if( ii < 0 ){
119 fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
120 IOCHAN_CLOSE(AFNI_ioc) ;
121 AFNI_mode = 0 ;
122 return ;
123 } else {
124 while( ! iochan_clearcheck(AFNI_ioc,2) ) /* wait for control data to clear */
125 iochan_sleep(2) ;
126 IOCHAN_CLOSE(AFNI_ioc) ; /* close control channel */
127
128 if( AFNI_verbose )
129 fprintf(stderr,"Opening data channel %s to AFNI.\n",AFNI_iochan) ;
130
131 AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ; /* open data channel */
132 if( AFNI_ioc == NULL ){
133 fprintf(stderr,"Can't open data channel %s to AFNI!\a\n",AFNI_iochan) ;
134 AFNI_mode = 0 ;
135 return ;
136 } else {
137 if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_CATCHUP_MODE.\n") ;
138 AFNI_mode = AFNI_CATCHUP_MODE ;
139 }
140 }
141 }
142
143 /***** Wait for the data channel to be connected to AFNI,
144 and then send any images that are reconstructed and ready to go *****/
145
146 if( AFNI_mode == AFNI_CATCHUP_MODE ){
147
148 ii = iochan_writecheck( AFNI_ioc , 1 ) ; /* wait at most 1 msec */
149 if( ii < 0 ){
150 fprintf(stderr,"AFNI data channel aborted before any data was sent!\a\n") ;
151 IOCHAN_CLOSE( AFNI_ioc ) ;
152 AFNI_mode = 0 ;
153 return ;
154 } else if( ii > 0 ){ /* can now send data to AFNI! */
155 if( AFNI_verbose )
156 fprintf(stderr,"AFNI data channel %s is connected.\n"
157 "Entering AFNI_CONTINUE_MODE.\n" , AFNI_iochan) ;
158 AFNI_mode = AFNI_CONTINUE_MODE ;
159
160 /* if there are any images already accumulated, send them now! */
161
162 if( nim > 0 && AFNI_verbose )
163 fprintf(stderr,"Playing AFNI catchup with %d images.\n",nim) ;
164
165 for( ii=0 ; ii < nim ; ii++ ) AFNI_send_image( ii ) ;
166 }
167 }
168
169 return ;
170 }
171
172 /*******************************************************************************/
173
174 /** send image in imX[nim] to AFNI **/
175
AFNI_send_image(int nim)176 void AFNI_send_image( int nim )
177 {
178 int lx = imX[nim].x , ly = imX[nim].y , nbytes = 2*lx*ly , soff , jj ;
179
180 if( AFNI_mode != AFNI_CONTINUE_MODE ) return ;
181
182 if ( (lx*ly) == 65536 ) soff = OFFSET; /* for Signa */
183 else soff = 0;
184
185 /** before very 1st image, send data type and matrix size **/
186
187 if( nim == 0 ){
188 if( AFNI_verbose ) fprintf(stderr,"Sending 1st info+image to AFNI.\n") ;
189 sprintf( AFNI_buf , "DATUM short\nXYMATRIX %d %d\n" , lx,ly ) ;
190 iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
191 } else if( AFNI_verbose ){
192 fprintf(stderr,"Sending image %d to AFNI.\n",nim+1) ;
193 }
194
195 jj = iochan_sendall( AFNI_ioc , imX[nim].arr + soff , nbytes ) ;
196
197 /** if the data channel failed, stop **/
198
199 if( jj < 0 ){
200 fprintf(stderr,"Image transmission to AFNI fails at #%d.\a\n",nim) ;
201 IOCHAN_CLOSE(AFNI_ioc) ;
202 AFNI_mode = 0 ;
203 }
204
205 return ;
206 }
207