00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "mrilib.h"
00008 
00009 #define MAX_CHAN 32  
00010 
00011 static THD_3dim_dataset * RT_dset[MAX_CHAN] ;
00012 static float              RT_dt             = 0.0 ;
00013 static int                RT_3D             = 0 ;
00014 static int                RT_swap2          = 0 ;
00015 static char               RT_buf[32768] , RT_com[1024] ;
00016 static int                RT_mega = 1 ;
00017 
00018 
00019 
00020 #define AFNI_CONTROL_PORT  7954         
00021 #define AFNI_TCP_PORT      7953         
00022 
00023 #define AFNI_OPEN_CONTROL_MODE   1      
00024 #define AFNI_WAIT_CONTROL_MODE   2      
00025 #define AFNI_OPEN_DATA_MODE      3      
00026 #define AFNI_CATCHUP_MODE        4      
00027 #define AFNI_CONTINUE_MODE       5      
00028 
00029 
00030 
00031 int      AFNI_mode        = 0 ;           
00032 int      AFNI_use_tcp     = 0 ;           
00033 char     AFNI_host[128]   = "localhost" ; 
00034 char     AFNI_iochan[128] = "\0" ;        
00035 IOCHAN * AFNI_ioc         = NULL ;        
00036 char     AFNI_buf[1024]          ;        
00037 int      AFNI_verbose     = 0    ;        
00038 
00039 char     AFNI_infocom[256]= "\0" ;        
00040 
00041 
00042 
00043 void RT_start_io(void) ;
00044 void RT_exit(void) ;
00045 
00046 
00047 
00048 #ifdef HP
00049 # define RSH "remsh"
00050 #else
00051 # define RSH "rsh"
00052 #endif
00053 
00054 
00055 
00056 void RT_exit(void)                   
00057 {                                    
00058    fprintf(stderr,"*** RT_exit: closing data channel to AFNI\n") ;
00059    iochan_close(AFNI_ioc) ;
00060    return ;
00061 }
00062 
00063 
00064 
00065 #include <signal.h>
00066 
00067 void RT_sigfunc(int sig)   
00068 {
00069    char * sname ;
00070    static volatile int fff=0 ;
00071    if( fff ) _exit(1) ; else fff = 1 ;
00072    switch(sig){
00073       default:      sname = "unknown" ; break ;
00074       case SIGINT:  sname = "SIGINT"  ; break ;
00075       case SIGPIPE: sname = "SIGPIPE" ; break ;
00076       case SIGSEGV: sname = "SIGSEGV" ; break ;
00077       case SIGBUS:  sname = "SIGBUS"  ; break ;
00078       case SIGTERM: sname = "SIGTERM" ; break ;
00079    }
00080    fprintf(stderr,"\n*** Fatal Signal %d (%s) received\n",sig,sname) ;
00081    exit(1) ;
00082 }
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 void AFNI_start_io( void )
00105 {
00106    int ii , jj ;
00107 
00108    
00109 
00110    if( AFNI_mode <= 0 || AFNI_mode == AFNI_CONTINUE_MODE ) return ;
00111 
00112    
00113 
00114 
00115    if( AFNI_mode == AFNI_OPEN_CONTROL_MODE ){
00116 
00117       sprintf( AFNI_iochan , "tcp:%s:%d" , AFNI_host , AFNI_CONTROL_PORT ) ;
00118 
00119       if( AFNI_verbose )
00120          fprintf(stderr,"Opening control channel %s to AFNI.\n",AFNI_iochan) ;
00121 
00122       AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ;
00123 
00124       if( AFNI_ioc == NULL ){
00125          fprintf(stderr,"Can't open control channel %s to AFNI!\a\n",AFNI_iochan) ;
00126 #if 0
00127          AFNI_mode = 0 ;                       
00128 #endif
00129          return ;
00130       } else {
00131          if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_WAIT_CONTROL_MODE.\n") ;
00132          AFNI_mode = AFNI_WAIT_CONTROL_MODE ;  
00133          iochan_sleep(5) ;                     
00134       }
00135    }
00136 
00137    
00138 
00139    if( AFNI_mode == AFNI_WAIT_CONTROL_MODE ){
00140 
00141       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  
00142 
00143 
00144 
00145 
00146       if( ii < 0 ){
00147          fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
00148          IOCHAN_CLOSE(AFNI_ioc) ;
00149          AFNI_mode = 0 ;                    
00150          return ;
00151       } else if( ii > 0 ){
00152          if( AFNI_verbose ) fprintf(stderr,"Control channel connected to AFNI."
00153                                            "  Entering AFNI_OPEN_DATA_MODE.\n") ;
00154          AFNI_mode = AFNI_OPEN_DATA_MODE ;  
00155       }
00156    }
00157 
00158    
00159 
00160 
00161 
00162    if( AFNI_mode == AFNI_OPEN_DATA_MODE ){
00163 
00164       
00165 
00166       if( AFNI_use_tcp ) sprintf(AFNI_iochan,"tcp:%s:%d",AFNI_host,AFNI_TCP_PORT) ;
00167       else if( RT_mega ) sprintf(AFNI_iochan,"shm:grv:%dM",RT_mega) ;
00168       else               sprintf(AFNI_iochan,"shm:grv:50K") ;  
00169 
00170       strcpy(AFNI_buf,AFNI_iochan) ;     
00171       if( AFNI_infocom[0] != '\0' ){
00172          strcat(AFNI_buf,"\n") ;
00173          strcat(AFNI_buf,AFNI_infocom) ; 
00174       }
00175 
00176       if( AFNI_verbose )
00177          fprintf(stderr,"Sending control information to AFNI:\n%s\n",AFNI_buf) ;
00178 
00179       ii = iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
00180 
00181 
00182 
00183       if( ii < 0 ){
00184          fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
00185          IOCHAN_CLOSE(AFNI_ioc) ;
00186          AFNI_mode = 0 ;
00187          return ;
00188       } else {
00189          while( ! iochan_clearcheck(AFNI_ioc,2) ) 
00190             iochan_sleep(2) ;
00191          IOCHAN_CLOSE(AFNI_ioc) ;                 
00192 
00193          if( AFNI_verbose )
00194             fprintf(stderr,"Opening data channel %s to AFNI.\n",AFNI_iochan) ;
00195 
00196          AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ; 
00197          if( AFNI_ioc == NULL ){
00198             fprintf(stderr,"Can't open data channel %s to AFNI!\a\n",AFNI_iochan) ;
00199             AFNI_mode = 0 ;
00200             return ;
00201          } else {
00202             if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_CATCHUP_MODE.\n") ;
00203             AFNI_mode = AFNI_CATCHUP_MODE ;
00204             iochan_sleep(5) ;                     
00205          }
00206       }
00207    }
00208 
00209    
00210 
00211 
00212    if( AFNI_mode == AFNI_CATCHUP_MODE ){
00213 
00214       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  
00215       if( ii < 0 ){
00216          fprintf(stderr,"AFNI data channel aborted before any data was sent!\a\n") ;
00217          IOCHAN_CLOSE( AFNI_ioc ) ;
00218          AFNI_mode = 0 ;
00219          return ;
00220       } else if( ii > 0 ){                      
00221          if( AFNI_verbose )
00222             fprintf(stderr,"AFNI data channel %s is connected.\n"
00223                            "Entering AFNI_CONTINUE_MODE.\n" , AFNI_iochan) ;
00224          AFNI_mode = AFNI_CONTINUE_MODE ;
00225       }
00226    }
00227 
00228    return ;
00229 }
00230 
00231 
00232 
00233 
00234 
00235 
00236 #define COMMAND_MARKER        "Et Earello Endorenna utulien!!"
00237 #define COMMAND_MARKER_LENGTH 30
00238 
00239 int main( int argc , char * argv[] )
00240 {
00241    int iarg=1 , ii,tt,kk , nbytes , nbslice , ntran , nzfake=0 ;
00242    char *bar , *qar=NULL , *sar ;
00243    double start_time , left_time , xtime ;
00244    char *drive_afni[128] ;
00245    int   ndrive=0 ;
00246    int   num_chan , cur_chan , cc ;
00247    char *note[128] ;   
00248    int   num_note=0 ;
00249    int   num_start=0 , jarg , bwait ; 
00250    float gyr=0.0 ;                    
00251 
00252    
00253 
00254    if( argc < 2 || strcmp(argv[1],"-help") == 0 ){
00255       printf(
00256         "Usage: rtfeedme [options] dataset [dataset ...]\n"
00257         "Test the real-time plugin by sending all the bricks in 'dataset' to AFNI.\n"
00258         " * 'dataset' may include a sub-brick selector list.\n"
00259         " * If more than one dataset is given, multiple channel acquisition\n"
00260         "    will be simulated.  Each dataset must then have the same datum\n"
00261         "    and dimensions.\n"
00262         " * If you put the flag '-break' between datasets, then the datasets\n"
00263         "    in each group will be transmitted in parallel, but the groups\n"
00264         "    will be transmitted serially (one group, then another, etc.).\n"
00265         "    + For example:\n"
00266         "        rtfeedme A+orig B+orig -break C+orig -break D+orig\n"
00267         "       will send the A and B datasets in parallel, then send\n"
00268         "       the C dataset separately, then send the D dataset separately.\n"
00269         "       (That is, there will be 3 groups of datasets.)\n"
00270         "    + There is a 1 second delay between the end transmission for\n"
00271         "       a group and the start transmission for the next group.\n"
00272         "    + You can extend the inter-group delay by using a break option\n"
00273         "       of the form '-break_20' to indicate a 20 second delay.\n"
00274         "    + Within a group, each dataset must have the same datum and\n"
00275         "       same x,y,z,t dimensions.  (Different groups don't need to\n"
00276         "       be conformant to each other.)\n"
00277         "    + All the options below apply to each group of datasets;\n"
00278         "       i.e., they will all get the same notes, drive commands, ....\n"
00279         "\n"
00280         "Options:\n"
00281         "  -host sname =  Send data, via TCP/IP, to AFNI running on the\n"
00282         "                 computer system 'sname'.  By default, uses the\n"
00283         "                 current system, and transfers data using shared\n"
00284         "                 memory.  To send on the current system using\n"
00285         "                 TCP/IP, use the system 'localhost'.\n"
00286         "\n"
00287         "  -dt ms      =  Tries to maintain an inter-transmit interval of\n"
00288         "                 'ms' milliseconds.  The default is to send data\n"
00289         "                 as fast as possible.\n"
00290         "\n"
00291         "  -3D         =  Sends data in 3D bricks.  By default, sends in\n"
00292         "                 2D slices.\n"
00293         "\n"
00294         "  -buf m      =  When using shared memory, sets the interprocess\n"
00295         "                 communications buffer to 'm' megabytes.  Has no\n"
00296         "                 effect if using TCP/IP.  Default is m=1.\n"
00297         "                 If you use m=0, then a 50 Kbyte buffer is used.\n"
00298         "\n"
00299         "  -verbose    =  Be talkative about actions.\n"
00300         "  -swap2      =  Swap byte pairs before sending data.\n"
00301         "\n"
00302         "  -nzfake nz  =  Send 'nz' as the value of nzz (for debugging).\n"
00303         "\n"
00304         "  -drive cmd  =  Send 'cmd' as a DRIVE_AFNI command; e.g.,\n"
00305         "                   -drive 'OPEN_WINDOW A.axialimage'\n"
00306         "                 If cmd contains blanks, it must be in 'quotes'.\n"
00307         "                 Multiple -drive options may be used.\n"
00308         "\n"
00309         "  -note sss   =  Send 'sss' as a NOTE to the realtime plugin.\n"
00310         "                 Multiple -note options may be used.\n"
00311         "\n"
00312         "  -gyr v      =  Send value 'v' as the y-range for realtime motion\n"
00313         "                 estimation graphing.\n"
00314       ) ;
00315       exit(0) ;
00316    }
00317 
00318    mainENTRY("rtfeedme") ;
00319 
00320    
00321 
00322    while( iarg < argc && argv[iarg][0] == '-' ){
00323 
00324       if( strcmp(argv[iarg],"-gyr") == 0 ){     
00325         gyr = strtod( argv[++iarg] , NULL ) ;
00326         iarg++ ; continue ;
00327       }
00328 
00329       if( strcmp(argv[iarg],"-drive") == 0 ){   
00330          drive_afni[ndrive++] = argv[++iarg] ;
00331          iarg++ ; continue ;
00332       }
00333 
00334       if( strcmp(argv[iarg],"-note") == 0 ){    
00335          note[num_note++] = argv[++iarg] ;
00336          iarg++ ; continue ;
00337       }
00338 
00339       if( strcmp(argv[iarg],"-nzfake") == 0 ){
00340          nzfake = (int) strtod( argv[++iarg] , NULL ) ;
00341          iarg++ ; continue ;
00342       }
00343 
00344       if( strcmp(argv[iarg],"-buf") == 0 ){
00345          RT_mega = (int) strtod( argv[++iarg] , NULL ) ;
00346          if( RT_mega < 0 ){
00347             fprintf(stderr,"*** Illegal value after -buf\n") ; exit(1) ;
00348          }
00349          iarg++ ; continue ;
00350       }
00351 
00352       if( strcmp(argv[iarg],"-host") == 0 ){
00353          strcpy( AFNI_host , argv[++iarg] ) ;
00354          AFNI_use_tcp = 1 ;
00355          iarg++ ; continue ;
00356       }
00357 
00358       if( strcmp(argv[iarg],"-dt") == 0 ){
00359          RT_dt = strtod( argv[++iarg] , NULL ) * 0.001 ;
00360          iarg++ ; continue ;
00361       }
00362 
00363       if( strcmp(argv[iarg],"-3D") == 0 ){
00364          RT_3D = 1 ;
00365          iarg++ ; continue ;
00366       }
00367 
00368       if( strcmp(argv[iarg],"-swap2") == 0 ){
00369          RT_swap2 = 1 ;
00370          iarg++ ; continue ;
00371       }
00372 
00373       if( strcmp(argv[iarg],"-verbose") == 0 ){
00374          AFNI_verbose = 1 ;
00375          iarg++ ; continue ;
00376       }
00377 
00378       fprintf(stderr,"*** Unrecognized option: %s\n",argv[iarg]) ;
00379       exit(1) ;
00380    }
00381 
00382    
00383 
00384    atexit(RT_exit) ;                     
00385    AFNI_mode = AFNI_OPEN_CONTROL_MODE ;  
00386 
00387    signal(SIGINT ,RT_sigfunc) ;  
00388    signal(SIGBUS ,RT_sigfunc) ;  
00389    signal(SIGSEGV,RT_sigfunc) ;
00390    signal(SIGTERM,RT_sigfunc) ;
00391 
00392    
00393 
00394 Restart:
00395 
00396    
00397 
00398    jarg     = iarg ;  
00399    num_chan = 0 ;
00400    for( ; iarg < argc && strncmp(argv[iarg],"-break",6) != 0 ; iarg++ ) num_chan++;
00401    if( num_chan == 0 ){
00402      fprintf(stderr,"*** No more datasets!  Free, free, free at last!\n"); exit(0);
00403    }
00404    if( num_chan > MAX_CHAN ){
00405      fprintf(stderr,"*** Too many datasets on command line!\n"); exit(1);
00406    }
00407 
00408    
00409 
00410    for( ; iarg < argc && strncmp(argv[iarg],"-break",6) == 0 ; iarg++ ) ; 
00411 
00412    
00413 
00414    bwait = 1 ;
00415    if( iarg < argc && strncmp(argv[iarg-1],"-break_",7) == 0 ){
00416      bwait = strtol( argv[iarg-1]+7 , NULL , 10 ) ;
00417    }
00418    if( bwait < 0 ) bwait = 1 ;
00419 
00420    num_start++ ;  
00421 
00422    
00423 
00424    for( cc=0 ; cc < num_chan ; cc++ ){
00425 
00426      RT_dset[cc] = THD_open_dataset( argv[jarg+cc] ) ;
00427 
00428      if( RT_dset[cc] == NULL ){
00429        fprintf(stderr,"*** Can't open dataset %s\n",argv[jarg+cc]); exit(1);
00430      }
00431 
00432      if( cc > 0 ){  
00433 
00434 #define ERREX(ee)                                                           \
00435   do { fprintf(stderr,"*** " ee ":%s and %s\n",argv[jarg],argv[jarg+cc]) ;  \
00436        exit(1) ; } while(0)
00437 
00438       if( DSET_NX   (RT_dset[0]) != DSET_NX   (RT_dset[cc]) ) ERREX("nx mismatch") ;
00439       if( DSET_NY   (RT_dset[0]) != DSET_NY   (RT_dset[cc]) ) ERREX("ny mismatch") ;
00440       if( DSET_NZ   (RT_dset[0]) != DSET_NZ   (RT_dset[cc]) ) ERREX("nz mismatch") ;
00441 
00442       if( DSET_NVALS(RT_dset[0]) != DSET_NVALS(RT_dset[cc]) ) ERREX("nvals mismatch");
00443 
00444       if( DSET_BRICK_TYPE(RT_dset[0],0) != DSET_BRICK_TYPE(RT_dset[cc],0) )
00445                                                               ERREX("datum mismatch");
00446      }
00447 
00448      
00449 
00450      DSET_load(RT_dset[cc]) ;
00451      if( !DSET_LOADED(RT_dset[cc]) ){
00452        fprintf(stderr,"*** Can't load dataset %s\n",argv[jarg+cc]); exit(1);
00453      }
00454    } 
00455 
00456    
00457 
00458    if( AFNI_verbose ) fprintf(stderr,"--- Starting I/O to AFNI\n") ;
00459 
00460    AFNI_start_io() ;
00461 
00462    ii = 1 ;
00463    while( AFNI_mode > 0 && AFNI_mode != AFNI_CONTINUE_MODE && ii < 1000 ){
00464      iochan_sleep( 300 ) ;  
00465      AFNI_start_io() ;
00466      ii++ ;
00467    }
00468 
00469    if( AFNI_mode != AFNI_CONTINUE_MODE ){
00470      fprintf(stderr,"\n*** Can't connect to AFNI?!\n") ; exit(1) ;
00471    }
00472 
00473    if( AFNI_verbose )
00474      fprintf(stderr,"\n--- Connection to AFNI is ready after %d tries\n",ii) ;
00475 
00476    
00477 
00478 #define ADDTO_BUF ( strcat(RT_buf,RT_com) , strcat(RT_buf,"\n") )
00479 
00480    RT_buf[0] = '\0' ;   
00481 
00482    
00483 
00484    if( num_chan > 1 ){                         
00485      sprintf(RT_com,"NUM_CHAN %d",num_chan) ;
00486      ADDTO_BUF ;
00487    }
00488 
00489    
00490 
00491    strcpy(RT_com,"ACQUISITION_TYPE ") ;
00492    if( DSET_NVALS(RT_dset[0]) == 1 ){
00493      if( RT_3D ) strcat(RT_com,"3D") ;    
00494      else        strcat(RT_com,"2D+z") ;  
00495    } else {
00496      if( RT_3D ) strcat(RT_com,"3D+t") ;  
00497      else        strcat(RT_com,"2D+zt") ; 
00498    }
00499    ADDTO_BUF ;
00500 
00501    
00502 
00503    if( DSET_NVALS(RT_dset[0]) > 1 && DSET_TR(RT_dset[0]) > 0.0 ){
00504      float TR = DSET_TR(RT_dset[0]) ;
00505      if( DSET_TIMEUNITS(RT_dset[0]) == UNITS_MSEC_TYPE ) TR *= 0.001 ;
00506      sprintf( RT_com , "TR %f" , TR ) ;
00507      ADDTO_BUF ;
00508    }
00509 
00510    
00511 
00512    sprintf( RT_com, "XYFOV %f %f %f", fabs(DSET_DX(RT_dset[0]) * DSET_NX(RT_dset[0])) ,
00513                                       fabs(DSET_DY(RT_dset[0]) * DSET_NY(RT_dset[0])) ,
00514                                       fabs(DSET_DZ(RT_dset[0]) * DSET_NZ(RT_dset[0]))  ) ;
00515    ADDTO_BUF ;
00516 
00517    
00518 
00519    if( nzfake <= 0 ){
00520      sprintf( RT_com , "XYMATRIX %d %d %d" , DSET_NX(RT_dset[0]) ,
00521                                              DSET_NY(RT_dset[0]) ,
00522                                              DSET_NZ(RT_dset[0])  ) ;
00523      ADDTO_BUF ;
00524    } else {
00525      sprintf( RT_com , "XYMATRIX %d %d" , DSET_NX(RT_dset[0]) ,
00526                                           DSET_NY(RT_dset[0])  ) ;
00527      ADDTO_BUF ;
00528      sprintf( RT_com , "ZNUM %d" , nzfake ) ;
00529      ADDTO_BUF ;
00530    }
00531 
00532    
00533 
00534    sprintf( RT_com, "DATUM %s", MRI_TYPE_name[DSET_BRICK_TYPE(RT_dset[0],0)] ) ;
00535    ADDTO_BUF ;
00536 
00537    
00538 
00539    if( ! RT_3D ){                         
00540      strcpy( RT_com , "ZORDER seq" ) ;    
00541      ADDTO_BUF ;                          
00542    }
00543 
00544    
00545 
00546    sprintf( RT_com , "XYZAXES %s %s %s" ,
00547             ORIENT_shortstr[ RT_dset[0]->daxes->xxorient ] ,
00548             ORIENT_shortstr[ RT_dset[0]->daxes->yyorient ] ,
00549             ORIENT_shortstr[ RT_dset[0]->daxes->zzorient ]  ) ;
00550    ADDTO_BUF ;
00551 
00552    
00553 
00554    { float xorg,yorg,zorg ;
00555      int   xorc,yorc,zorc ;
00556 
00557      xorg = RT_dset[0]->daxes->xxorg ;
00558      yorg = RT_dset[0]->daxes->yyorg ;
00559      zorg = RT_dset[0]->daxes->zzorg ;
00560 
00561      xorc = RT_dset[0]->daxes->xxorient ;
00562      yorc = RT_dset[0]->daxes->yyorient ;
00563      zorc = RT_dset[0]->daxes->zzorient ;
00564 
00565      if( ORIENT_sign[xorc] == '+' ) xorc = ORIENT_OPPOSITE(xorc) ;
00566      if( ORIENT_sign[yorc] == '+' ) yorc = ORIENT_OPPOSITE(yorc) ;
00567      if( ORIENT_sign[zorc] == '+' ) zorc = ORIENT_OPPOSITE(zorc) ;
00568 
00569      sprintf( RT_com , "XYZFIRST %g%c %g%c %g%c" ,
00570               xorg , ORIENT_first[xorc] ,
00571               yorg , ORIENT_first[yorc] ,
00572               zorg , ORIENT_first[zorc]  ) ;
00573      ADDTO_BUF ;
00574    }
00575 
00576    
00577 
00578    for( ii=0 ; ii < ndrive ; ii++ ){
00579      sprintf( RT_com , "DRIVE_AFNI %s" , drive_afni[ii] ) ;
00580      ADDTO_BUF ;
00581    }
00582 
00583    
00584 
00585    for( ii=0 ; ii < num_note ; ii++ ){
00586      sprintf( RT_com , "NOTE %s" , note[ii] ) ;
00587      ADDTO_BUF ;
00588    }
00589 
00590    
00591 
00592    if( DSET_NVALS(RT_dset[0]) > 9 ){
00593      sprintf( RT_com , "GRAPH_XRANGE %d" , DSET_NVALS(RT_dset[0]) ) ;
00594      ADDTO_BUF ;
00595      if( gyr > 0.0 ){
00596        sprintf( RT_com , "GRAPH_YRANGE %.2f" , gyr ) ;
00597        ADDTO_BUF ;
00598      }
00599    }
00600 
00601    
00602 
00603    if( AFNI_verbose )
00604       fprintf(stderr,"--- Dataset control info for AFNI:\n%s",RT_buf) ;
00605 
00606    ii = iochan_sendall( AFNI_ioc , RT_buf , strlen(RT_buf)+1 ) ;
00607    if( ii < 0 ){
00608      fprintf(stderr,"*** Error sending dataset control info to AFNI\n") ;
00609      exit(1) ;
00610    }
00611 
00612    iochan_sleep(128) ;  
00613 
00614    
00615 
00616    nbslice = nbytes = mri_datum_size( DSET_BRICK_TYPE(RT_dset[0],0) )
00617                       * DSET_NX(RT_dset[0]) * DSET_NY(RT_dset[0]) ;
00618 
00619    if( RT_3D ) nbytes *= DSET_NZ(RT_dset[0]) ;
00620 
00621    if( qar != NULL ) free(qar) ;                     
00622    qar = (char *) malloc( sizeof(char) * nbytes ) ;  
00623    if( qar == NULL ){
00624      fprintf(stderr,"*** Can't malloc workspace!\n"); exit(1);
00625    }
00626 
00627    
00628 
00629    xtime = COX_clock_time() ;                  
00630 
00631    ntran = DSET_NVALS(RT_dset[0]) * num_chan ; 
00632    if( !RT_3D ) ntran *= DSET_NZ(RT_dset[0]) ; 
00633 
00634    for( tt=0 ; tt < DSET_NVALS(RT_dset[0]) ; tt++ ){  
00635 
00636       if( RT_3D ){                          
00637 
00638        for( cc=0 ; cc < num_chan ; cc++ ){  
00639 
00640          bar = DSET_ARRAY(RT_dset[cc],tt) ; 
00641 
00642          if( AFNI_verbose )
00643            fprintf(stderr,"--- Sending brick %d, channel %02d\n",tt,cc+1) ;
00644 
00645          if( RT_dt > 0.0 ) start_time = COX_clock_time() ;
00646 
00647          sar = bar ;
00648          if( RT_swap2 ){                    
00649            memcpy(qar,sar,nbytes) ; sar = qar ;
00650            mri_swap2( nbytes/2 , (short *) sar ) ;
00651          }
00652 
00653          
00654 
00655          ii = iochan_sendall( AFNI_ioc , sar , nbytes ) ;
00656          if( ii < 0 ){
00657            fprintf(stderr,
00658                    "*** Error sending brick %d, channel %02d, to AFNI\n",
00659                    tt,cc+1) ;
00660            exit(1) ;
00661          }
00662 
00663          
00664 
00665          if( RT_dt > 0.0 ){
00666            left_time = RT_dt - ( COX_clock_time() - start_time ) ;
00667            if( left_time >= 0.001 ){
00668              ii = (int) (1000.0 * left_time) ;  
00669              iochan_sleep( ii ) ;
00670            }
00671          }
00672        } 
00673 
00674 
00675 
00676       } else {
00677 
00678          for( kk=0 ; kk < DSET_NZ(RT_dset[0]) ; kk++ ){  
00679           for( cc=0 ; cc < num_chan ; cc++ ){            
00680 
00681             bar = DSET_ARRAY(RT_dset[cc],tt) ;  
00682 
00683             if( AFNI_verbose )
00684               fprintf(stderr,"--- Sending brick %d, slice %d, channel %02d\n",
00685                              tt,kk,cc+1) ;
00686 
00687             if( RT_dt > 0.0 ) start_time = COX_clock_time() ;
00688 
00689             sar = bar+(kk*nbslice) ;  
00690 
00691             if( RT_swap2 ){           
00692                memcpy(qar,sar,nbslice) ; sar = qar ;
00693                mri_swap2( nbslice/2 , (short *) sar ) ;
00694             }
00695 
00696             
00697 
00698             ii = iochan_sendall( AFNI_ioc , sar , nbslice ) ;
00699 
00700             if( ii < 0 ){
00701               fprintf(stderr,
00702                       "*** Error sending slice brick %d, slice %d, channel %02d to AFNI\n",
00703                       tt,kk,cc+1) ;
00704               exit(1) ;
00705             }
00706 
00707             if( RT_dt > 0.0 ){  
00708               left_time = RT_dt - ( COX_clock_time() - start_time ) ;
00709               if( left_time >= 0.001 ){
00710                 ii = (int) (1000.0 * left_time) ;
00711                 iochan_sleep( ii ) ;
00712               }
00713             }
00714 
00715           } 
00716          } 
00717 
00718       } 
00719 
00720 
00721 
00722       for( cc=0 ; cc < num_chan ; cc++ )
00723         DSET_unload_one( RT_dset[cc] , tt ) ;
00724 
00725    } 
00726 
00727    
00728 
00729    xtime = COX_clock_time() - xtime ;  
00730 
00731    for( cc=0 ; cc < num_chan ; cc++ )  
00732       DSET_delete( RT_dset[cc] ) ;
00733 
00734    
00735 
00736    if( AFNI_verbose ) fprintf(stderr,"--- Clearing buffer") ;
00737    iochan_sleep(100) ;
00738    while( ! iochan_clearcheck(AFNI_ioc,100) ){
00739       if( AFNI_verbose ) fprintf(stderr,".") ;
00740    }
00741    if( AFNI_verbose ) fprintf(stderr,"\n") ;
00742 
00743    fprintf(stderr,
00744            "--- Elapsed transmit time = %f s (%f per transmit)\n",
00745            xtime,xtime/ntran) ;
00746 
00747    
00748    
00749 
00750    if( iarg < argc ){
00751      fprintf(stderr,"--- Restarting after '-break'\n") ;
00752      memcpy( qar , COMMAND_MARKER , COMMAND_MARKER_LENGTH ) ;
00753      iochan_sendall( AFNI_ioc , qar , nbytes ) ;
00754      iochan_sleep(1000*bwait) ;  
00755      goto Restart ;
00756    }
00757 
00758    
00759 
00760    exit(0) ;
00761 }