00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #include "thd_iochan.h"
00059
00060
00061
00062
00063 static char afni_host[128] = "." ;
00064 static char afni_name[128] = "\0" ;
00065 static int afni_port = 8001 ;
00066
00067 static int afni_verbose = 0 ;
00068 static int afni_do_ijk = 0 ;
00069
00070
00071
00072 int afni_io(void) ;
00073
00074
00075
00076
00077
00078
00079
00080 int main( int argc , char * argv[] )
00081 {
00082 int narg , ii ;
00083
00084
00085
00086 if( argc == 2 && strncmp(argv[1],"-help",5) == 0 ){
00087 printf("Usage: plugout_tt [-host name] [-v]\n"
00088 "This program connects to AFNI and receives notification\n"
00089 "whenever the user changes Talairach coordinates.\n\n"
00090 "Options:\n"
00091 " -host name Means to connect to AFNI running on the\n"
00092 " computer 'name' using TCP/IP. The default is to\n"
00093 " connect on the current host using shared memory.\n"
00094 " -ijk Means to get voxel indices from AFNI, rather\n"
00095 " than Talairach coordinates.\n"
00096 " -v Verbose mode: prints out lots of stuff.\n"
00097 " -port pp Use TCP/IP port number 'pp'. The default is\n"
00098 " 8001, but if two copies of this are running on\n"
00099 " the same computer, they must use different ports.\n"
00100 " -name sss Use the string 'sss' for the name that AFNI assigns\n"
00101 " to this plugout. The default is something stupid.\n"
00102 ) ;
00103 exit(0) ;
00104 }
00105
00106
00107
00108 narg = 1 ;
00109 while( narg < argc ){
00110
00111
00112
00113 if( strncmp(argv[narg],"-host",5) == 0 ){
00114 narg++ ;
00115 if( narg >= argc ){
00116 fprintf(stderr,"-host needs a following name!\a\n"); exit(1);
00117 }
00118 strcpy( afni_host , argv[narg] ) ;
00119 narg++ ; continue ;
00120 }
00121
00122
00123
00124 if( strncmp(argv[narg],"-name",5) == 0 ){
00125 narg++ ;
00126 if( narg >= argc ){
00127 fprintf(stderr,"-name needs a following string!\a\n"); exit(1);
00128 }
00129 strcpy( afni_name , argv[narg] ) ;
00130 narg++ ; continue ;
00131 }
00132
00133
00134
00135 if( strncmp(argv[narg],"-v",2) == 0 ){
00136 afni_verbose = 1 ;
00137 narg++ ; continue ;
00138 }
00139
00140
00141
00142 if( strncmp(argv[narg],"-port",4) == 0 ){
00143 narg++ ;
00144 if( narg >= argc ){
00145 fprintf(stderr,"-port needs a following argument!\a\n"); exit(1);
00146 }
00147 afni_port = strtol( argv[narg] , NULL , 10 ) ;
00148 if( afni_port <= 0 ){
00149 fprintf(stderr,"-port needs a positive argument!\a\n"); exit(1);
00150 }
00151 if( strcmp(afni_host,".") == 0 ) strcpy(afni_host,"localhost") ;
00152 narg++ ; continue ;
00153 }
00154
00155
00156
00157 if( strncmp(argv[narg],"-ijk",4) == 0 ){
00158 afni_do_ijk = 1 ;
00159 narg++ ; continue ;
00160 }
00161
00162
00163
00164 fprintf(stderr,"Unrecognized option: %s\a\n",argv[narg]) ;
00165 exit(1) ;
00166 }
00167
00168
00169
00170 while( 1 ){
00171 ii = afni_io() ;
00172 if( ii < 0 ) exit(0) ;
00173 iochan_sleep(100) ;
00174 }
00175
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 #define AFNI_OPEN_CONTROL_MODE 1
00202 #define AFNI_WAIT_CONTROL_MODE 2
00203 #define AFNI_OPEN_DATA_MODE 3
00204 #define AFNI_WAIT_DATA_MODE 4
00205 #define AFNI_CONTINUE_MODE 5
00206
00207
00208
00209 #define POACKSIZE 4
00210
00211 #define PO_ACK_BAD(ic) iochan_sendall( (ic) , "BAD" , POACKSIZE )
00212 #define PO_ACK_OK(ic) iochan_sendall( (ic) , "OK!" , POACKSIZE )
00213 #define PO_SEND(ic,str) iochan_sendall( (ic) , (str) , strlen((str))+1 )
00214
00215 int afni_io(void)
00216 {
00217 static int afni_mode = AFNI_OPEN_CONTROL_MODE ;
00218 static IOCHAN * afni_ioc = NULL ;
00219 int ii ;
00220
00221
00222
00223
00224
00225 if( afni_mode <= 0 ) return -1 ;
00226
00227
00228
00229
00230 if( afni_mode == AFNI_OPEN_CONTROL_MODE ){
00231 char afni_iocname[128] ;
00232
00233
00234
00235
00236 if( strcmp(afni_host,".") == 0 )
00237 sprintf( afni_iocname , "tcp:%s:7955" , "localhost" );
00238 else
00239 sprintf( afni_iocname , "tcp:%s:7955" , afni_host ) ;
00240 afni_ioc = iochan_init( afni_iocname , "create" ) ;
00241 if( afni_ioc == NULL ){
00242 fprintf(stderr,
00243 "Can't create control channel %s to AFNI!\n",afni_iocname) ;
00244 afni_mode = 0 ;
00245 return -1 ;
00246 }
00247 afni_mode = AFNI_WAIT_CONTROL_MODE ;
00248 if( afni_verbose )
00249 fprintf(stderr,"AFNI control channel created\n") ;
00250 }
00251
00252
00253
00254
00255 if( afni_mode == AFNI_WAIT_CONTROL_MODE ){
00256 ii = iochan_writecheck( afni_ioc , 5 ) ;
00257
00258
00259
00260
00261
00262
00263 if( ii < 0 ){
00264 fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
00265 IOCHAN_CLOSE(afni_ioc) ;
00266 afni_mode = 0 ;
00267 return -1 ;
00268 } else if( ii > 0 ){
00269 afni_mode = AFNI_OPEN_DATA_MODE ;
00270 if( afni_verbose )
00271 fprintf(stderr,"AFNI control channel connected\n");
00272 } else {
00273 return 0 ;
00274 }
00275 }
00276
00277
00278
00279
00280 if( afni_mode == AFNI_OPEN_DATA_MODE ){
00281 char afni_iocname[128] ;
00282 char afni_buf[256] ;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 if( strcmp(afni_host,".") == 0 )
00294 strcpy( afni_iocname , "shm:test_plugout:1K+1K" ) ;
00295 else
00296 sprintf( afni_iocname , "tcp:%s:%d" , afni_host , afni_port ) ;
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 if( afni_name[0] == '\0' ) strcpy(afni_name,"aManCalledHorse") ;
00309
00310 if( afni_do_ijk ){
00311 sprintf( afni_buf , "DSET_IJK_DELTA\n"
00312 "UNDERLAY_DELTA\n"
00313 "PONAME %s\n"
00314 "IOCHAN %s" ,
00315 afni_name , afni_iocname ) ;
00316 } else {
00317 sprintf( afni_buf , "TT_XYZ_DELTA\n"
00318 "UNDERLAY_DELTA\n"
00319 "PONAME %s\n"
00320 "IOCHAN %s" ,
00321 afni_name , afni_iocname ) ;
00322 }
00323
00324 if( afni_verbose )
00325 fprintf(stderr,"Sending control information to AFNI\n") ;
00326
00327
00328
00329 ii = iochan_sendall( afni_ioc , afni_buf , strlen(afni_buf)+1 ) ;
00330
00331
00332
00333
00334 if( ii < 0 ){
00335 fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
00336 IOCHAN_CLOSE(afni_ioc) ;
00337 afni_mode = 0 ;
00338 return -1 ;
00339
00340 } else {
00341
00342
00343
00344 ii = iochan_recvall( afni_ioc , afni_buf , POACKSIZE ) ;
00345 IOCHAN_CLOSE(afni_ioc) ;
00346
00347 if( ii < 0 || strncmp(afni_buf,"OK!",3) != 0 ){
00348 fprintf(stderr,"AFNI didn't like control information!\a\n") ;
00349 afni_mode = 0 ;
00350 return -1 ;
00351 }
00352
00353
00354
00355 afni_ioc = iochan_init( afni_iocname , "create" ) ;
00356 if( afni_ioc == NULL ){
00357 fprintf(stderr,
00358 "Can't open data channel %s to AFNI!\a\n",afni_iocname) ;
00359 afni_mode = 0 ;
00360 return -1 ;
00361 } else {
00362 afni_mode = AFNI_WAIT_DATA_MODE ;
00363 if( afni_verbose ) fprintf(stderr,"AFNI data channel created\n") ;
00364 }
00365 }
00366 }
00367
00368
00369
00370
00371 if( afni_mode == AFNI_WAIT_DATA_MODE ){
00372
00373 ii = iochan_goodcheck( afni_ioc , 5 ) ;
00374 if( ii < 0 ){
00375 fprintf(stderr,
00376 "AFNI data channel aborted before any data was sent!\a\n") ;
00377 IOCHAN_CLOSE( afni_ioc ) ;
00378 afni_mode = 0 ;
00379 return -1 ;
00380 } else if( ii > 0 ){
00381 afni_mode = AFNI_CONTINUE_MODE ;
00382 if( afni_verbose ) fprintf(stderr,"AFNI data channel is open\n") ;
00383 } else {
00384 return 0 ;
00385 }
00386 }
00387
00388
00389
00390
00391
00392 if( afni_mode == AFNI_CONTINUE_MODE ){
00393 char afni_buf[256] ;
00394 float xx , yy , zz ;
00395 int ix , jy , kz ;
00396
00397 ii = iochan_readcheck( afni_ioc , 0 ) ;
00398
00399
00400
00401
00402
00403 if( ii < 0 ){
00404 fprintf(stderr,"AFNI data channel aborted!\a\n") ;
00405 IOCHAN_CLOSE(afni_ioc) ;
00406 afni_mode = 0 ;
00407 return -1 ;
00408 } else if( ii == 0 ){
00409 return 0 ;
00410 }
00411
00412
00413
00414 ii = iochan_recv( afni_ioc , afni_buf , 256 ) ;
00415
00416 if( ii <= 0 ){
00417 fprintf(stderr,"AFNI data channel recv failed!\a\n") ;
00418 IOCHAN_CLOSE(afni_ioc) ;
00419 afni_mode = 0 ;
00420 return -1 ;
00421 }
00422
00423
00424
00425
00426 #if 0
00427 if( afni_do_ijk )
00428 ii = sscanf( afni_buf , "DSET_IJK %d %d %d" , &ix,&jy,&kz ) ;
00429 else
00430 ii = sscanf( afni_buf , "TT_XYZ %f %f %f" , &xx,&yy,&zz ) ;
00431
00432
00433
00434
00435 if( ii < 3 ){
00436 fprintf(stderr,"AFNI sent bad data: %s\a\n",afni_buf) ;
00437 PO_ACK_BAD(afni_ioc) ;
00438 } else if( afni_do_ijk ){
00439 fprintf(stderr,"AFNI sent indices: %d %d %d\n",ix,jy,kz) ;
00440 PO_ACK_OK(afni_ioc) ;
00441 } else {
00442 fprintf(stderr,"AFNI sent coords: %9.3f %9.3f %9.3f\n",xx,yy,zz) ;
00443 PO_ACK_OK(afni_ioc) ;
00444 }
00445 #else
00446 fprintf(stderr,"AFNI sent data:\n%s\n",afni_buf) ;
00447 PO_ACK_OK(afni_ioc) ;
00448 #endif
00449 }
00450
00451 return 0 ;
00452 }