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 }