Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

rtfeedme.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "mrilib.h"
00008 
00009 #define MAX_CHAN 32  /* 02 Aug 2002: cf. plug_realtime.c */
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         /* always send control data to AFNI    */
00021 #define AFNI_TCP_PORT      7953         /* maybe send image data to AFNI       */
00022 
00023 #define AFNI_OPEN_CONTROL_MODE   1      /* 1st time thru: open control channel */
00024 #define AFNI_WAIT_CONTROL_MODE   2      /* waiting for AFNI to open control    */
00025 #define AFNI_OPEN_DATA_MODE      3      /* now can open data channel to AFNI   */
00026 #define AFNI_CATCHUP_MODE        4      /* waiting for AFNI to open data       */
00027 #define AFNI_CONTINUE_MODE       5      /* at last! data channel is ready!     */
00028 
00029 /*-- global control variables --*/
00030 
00031 int      AFNI_mode        = 0 ;           /* if > 0, then means AFNI is active  */
00032 int      AFNI_use_tcp     = 0 ;           /* if > 0, use TCP/IP to send images */
00033 char     AFNI_host[128]   = "localhost" ; /* hostname of CPU AFNI is on       */
00034 char     AFNI_iochan[128] = "\0" ;        /* I/O channel name to AFNI        */
00035 IOCHAN * AFNI_ioc         = NULL ;        /* ptr to I/O channel itself      */
00036 char     AFNI_buf[1024]          ;        /* temporary space               */
00037 int      AFNI_verbose     = 0    ;        /* debugging mode               */
00038 
00039 char     AFNI_infocom[256]= "\0" ;        /* command for AFNI info */
00040 
00041 /*-- prototypes --*/
00042 
00043 void RT_start_io(void) ;
00044 void RT_exit(void) ;
00045 
00046 /*-- how to execute a command on another system --*/
00047 
00048 #ifdef HP
00049 # define RSH "remsh"
00050 #else
00051 # define RSH "rsh"
00052 #endif
00053 
00054 /*=============================================================================*/
00055 
00056 void RT_exit(void)                   /* Function to be called to make sure */
00057 {                                    /* the AFNI data channels get closed. */
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)   /** signal handler for fatal errors **/
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   Do I/O startup stuff.
00086 
00087   At any given moment, this routine is in one of a number of modes
00088   (the AFNI_mode variable).
00089   The first time in, AFNI_mode == AFNI_OPEN_CONTROL_MODE.  In each mode,
00090   certain tasks must be accomplished and this program must be synchronized
00091   with AFNI.  When the necessary deeds are done, the routine advances to
00092   the next mode.  If the deeds cannot be done when this routine is called,
00093   then it will stay in the same mode, and the next time it is called it
00094   will try to do them again.  This routine should be called repeatedly
00095   until it progresses to the last mode (AFNI_CONTINUE_MODE), which is for
00096   normal transmission of images (one at a time) to AFNI.
00097 
00098   If an error occurs, so that this program can no longer talk to AFNI, then
00099   AFNI_mode is set to 0, which means "do nothing further".  The rest of
00100   the data acquisition software will continue, but these routines will
00101   be stopped dead.
00102 ******************************************************************************/
00103 
00104 void AFNI_start_io( void )
00105 {
00106    int ii , jj ;
00107 
00108    /***** Check for conditions in which to do nothing *****/
00109 
00110    if( AFNI_mode <= 0 || AFNI_mode == AFNI_CONTINUE_MODE ) return ;
00111 
00112    /***** If we are at the first time in,
00113           try to open a control socket to talk to AFNI *****/
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 ;                       /* disable AFNI */
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 ;  /* begin waiting for AFNI connection */
00133          iochan_sleep(5) ;                     /* give other program a moment */
00134       }
00135    }
00136 
00137    /***** Check if the control socket is connected to AFNI *****/
00138 
00139    if( AFNI_mode == AFNI_WAIT_CONTROL_MODE ){
00140 
00141       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  /* Check; wait at most 1 msec */
00142 
00143       /** if ii == 0, then the channel is still pending,
00144           so do nothing; otherwise, take some action.    **/
00145 
00146       if( ii < 0 ){
00147          fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
00148          IOCHAN_CLOSE(AFNI_ioc) ;
00149          AFNI_mode = 0 ;                    /* disable AFNI */
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 ;  /* prepare to send data to AFNI */
00155       }
00156    }
00157 
00158    /***** Send the control information, which says
00159           how we will talk to AFNI in the future (shmem or TCP/IP),
00160           then close the control channel and open this new data channel *****/
00161 
00162    if( AFNI_mode == AFNI_OPEN_DATA_MODE ){
00163 
00164       /* decide name of data channel: it can be TCP/IP or shared memory */
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") ;  /* 11 Dec 2002 */
00169 
00170       strcpy(AFNI_buf,AFNI_iochan) ;     /* tell AFNI where to read data */
00171       if( AFNI_infocom[0] != '\0' ){
00172          strcat(AFNI_buf,"\n") ;
00173          strcat(AFNI_buf,AFNI_infocom) ; /* tell it where to get 3T info */
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       /** A negative return is bad news **/
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) ) /* wait for control data to clear */
00190             iochan_sleep(2) ;
00191          IOCHAN_CLOSE(AFNI_ioc) ;                 /* close control channel */
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" ) ; /* open data channel */
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) ;                     /* give other program a moment */
00205          }
00206       }
00207    }
00208 
00209    /***** Wait for the data channel to be connected to AFNI,
00210           and then send any images that are reconstructed and ready to go *****/
00211 
00212    if( AFNI_mode == AFNI_CATCHUP_MODE ){
00213 
00214       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  /* wait at most 1 msec */
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 ){                      /* can now send data to AFNI! */
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 /* 11 Dec 2002: string to mark end of image data,
00234                 to enable ending dataset(s) without closing data channel */
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] ;   /* 02 Oct 2002 */
00248    int   num_note=0 ;
00249    int   num_start=0 , jarg , bwait ; /* 11 Dec 2002 */
00250    float gyr=0.0 ;                    /* 29 Jan 2004 */
00251 
00252    /*-- help the ignorant user --*/
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    /*-- scan arguments --*/
00321 
00322    while( iarg < argc && argv[iarg][0] == '-' ){
00323 
00324       if( strcmp(argv[iarg],"-gyr") == 0 ){     /* 29 Jan 2004 */
00325         gyr = strtod( argv[++iarg] , NULL ) ;
00326         iarg++ ; continue ;
00327       }
00328 
00329       if( strcmp(argv[iarg],"-drive") == 0 ){   /* 30 Jul 2002 */
00330          drive_afni[ndrive++] = argv[++iarg] ;
00331          iarg++ ; continue ;
00332       }
00333 
00334       if( strcmp(argv[iarg],"-note") == 0 ){    /* 02 Oct 2002 */
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    /*-- this stuff is one-time-only setup of the I/O to AFNI --*/
00383 
00384    atexit(RT_exit) ;                     /* call this when program ends */
00385    AFNI_mode = AFNI_OPEN_CONTROL_MODE ;  /* mode in which to start I/O  */
00386 
00387    signal(SIGINT ,RT_sigfunc) ;  /* setup signal handler */
00388    signal(SIGBUS ,RT_sigfunc) ;  /* for fatal errors */
00389    signal(SIGSEGV,RT_sigfunc) ;
00390    signal(SIGTERM,RT_sigfunc) ;
00391 
00392    /*------ 11 Dec 2002: after a -break, will jump back here ------*/
00393 
00394 Restart:
00395 
00396    /*-- count datasets up to end of argv or next -break --*/
00397 
00398    jarg     = iarg ;  /* keep track of where we are starting */
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    /*-- skip any -break's for when we loop back to Restart --*/
00409 
00410    for( ; iarg < argc && strncmp(argv[iarg],"-break",6) == 0 ; iarg++ ) ; /* nada */
00411 
00412    /* check for delay in the form of "-break_XXX" where XXX = # sec to wait */
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++ ;  /* number of times we've been here */
00421 
00422    /*-- read the input dataset(s) and check them for OK-ositiness --*/
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 ){  /* check for compatibility with #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      /* load from disk */
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    } /* end of loop over channels (datasets to send in parallel) */
00455 
00456    /*-- initiate communications with AFNI --*/
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 ) ;  /* 300 msec wait */
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    /*-- Send dataset control information --*/
00477 
00478 #define ADDTO_BUF ( strcat(RT_buf,RT_com) , strcat(RT_buf,"\n") )
00479 
00480    RT_buf[0] = '\0' ;   /* string to hold commands to AFNI realtime plugin */
00481 
00482    /*** Number of channels [Aug 2002] ***/
00483 
00484    if( num_chan > 1 ){                         /* default is 1 channel */
00485      sprintf(RT_com,"NUM_CHAN %d",num_chan) ;
00486      ADDTO_BUF ;
00487    }
00488 
00489    /*** How the data will be sent ***/
00490 
00491    strcpy(RT_com,"ACQUISITION_TYPE ") ;
00492    if( DSET_NVALS(RT_dset[0]) == 1 ){
00493      if( RT_3D ) strcat(RT_com,"3D") ;    /* 1 3D array, all at once */
00494      else        strcat(RT_com,"2D+z") ;  /* 1 3D array, by slices */
00495    } else {
00496      if( RT_3D ) strcat(RT_com,"3D+t") ;  /* multi 3D arrays, each all at once */
00497      else        strcat(RT_com,"2D+zt") ; /* multi 3D arrays, each by slices */
00498    }
00499    ADDTO_BUF ;
00500 
00501    /*** Time step, if needed ***/
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    /*** Volume dimensions ***/
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    /*** Matrix sizes ***/
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    /*** Data type ***/
00533 
00534    sprintf( RT_com, "DATUM %s", MRI_TYPE_name[DSET_BRICK_TYPE(RT_dset[0],0)] ) ;
00535    ADDTO_BUF ;
00536 
00537    /*** Slice order ***/
00538 
00539    if( ! RT_3D ){                         /* this cheapo program always      */
00540      strcpy( RT_com , "ZORDER seq" ) ;    /* send slices in sequential order */
00541      ADDTO_BUF ;                          /* unlike their true acquisition   */
00542    }
00543 
00544    /*** Axes orientation [e.g., RAI] ***/
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    /*** Axes offsets [11 Dec 2002] ***/
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    /*** DRIVE_AFNI commands [Jul 2002] ***/
00577 
00578    for( ii=0 ; ii < ndrive ; ii++ ){
00579      sprintf( RT_com , "DRIVE_AFNI %s" , drive_afni[ii] ) ;
00580      ADDTO_BUF ;
00581    }
00582 
00583    /*** NOTE commands [02 Oct 2002] ***/
00584 
00585    for( ii=0 ; ii < num_note ; ii++ ){
00586      sprintf( RT_com , "NOTE %s" , note[ii] ) ;
00587      ADDTO_BUF ;
00588    }
00589 
00590    /*** GRAPH range commands [29 Jan 2004] ***/
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    /*** send metadata buffer to AFNI ***/
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) ;  /* let AFNI digest the results for a while */
00613 
00614    /*-- compute number of bytes per slice, and per image transmission --*/
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) ;                     /* free old workspace */
00622    qar = (char *) malloc( sizeof(char) * nbytes ) ;  /* make new workspace */
00623    if( qar == NULL ){
00624      fprintf(stderr,"*** Can't malloc workspace!\n"); exit(1);
00625    }
00626 
00627    /*--- send slices or volumes to AFNI ---*/
00628 
00629    xtime = COX_clock_time() ;                  /* keep track of elapsed time */
00630 
00631    ntran = DSET_NVALS(RT_dset[0]) * num_chan ; /* number of transmissions: */
00632    if( !RT_3D ) ntran *= DSET_NZ(RT_dset[0]) ; /* volumes or slices */
00633 
00634    for( tt=0 ; tt < DSET_NVALS(RT_dset[0]) ; tt++ ){  /* loop over time points */
00635 
00636       if( RT_3D ){                          /** send 3D arrays **/
00637 
00638        for( cc=0 ; cc < num_chan ; cc++ ){  /* loop over channels (datasets) */
00639 
00640          bar = DSET_ARRAY(RT_dset[cc],tt) ; /* array to send */
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 ){                    /* swap bytes? */
00649            memcpy(qar,sar,nbytes) ; sar = qar ;
00650            mri_swap2( nbytes/2 , (short *) sar ) ;
00651          }
00652 
00653          /* send the whole 3D array (sar points to data to transmit) */
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          /* maybe wait for prescribed transmission time */
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) ;  /* number of milliseconds */
00669              iochan_sleep( ii ) ;
00670            }
00671          }
00672        } /* end of loop over channels */
00673 
00674       /** send 2D slices from each channel in turn **/
00675 
00676       } else {
00677 
00678          for( kk=0 ; kk < DSET_NZ(RT_dset[0]) ; kk++ ){  /* loop over slices */
00679           for( cc=0 ; cc < num_chan ; cc++ ){            /* loop over channels */
00680 
00681             bar = DSET_ARRAY(RT_dset[cc],tt) ;  /* 3D array to get slice from */
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) ;  /* pointer to start of slice data */
00690 
00691             if( RT_swap2 ){           /* byte swapping */
00692                memcpy(qar,sar,nbslice) ; sar = qar ;
00693                mri_swap2( nbslice/2 , (short *) sar ) ;
00694             }
00695 
00696             /* send slice data */
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 ){  /* wait for prescribed transmission time */
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           } /* end of loop over channels */
00716          } /* end of loop over slices */
00717 
00718       } /* end of if 3D or 2D transmissions */
00719 
00720       /** unload dataset bricks we just sent **/
00721 
00722       for( cc=0 ; cc < num_chan ; cc++ )
00723         DSET_unload_one( RT_dset[cc] , tt ) ;
00724 
00725    } /* end of loop over time points */
00726 
00727    /*-- cleanup --*/
00728 
00729    xtime = COX_clock_time() - xtime ;  /* total transmit time */
00730 
00731    for( cc=0 ; cc < num_chan ; cc++ )  /* unload all datasets */
00732       DSET_delete( RT_dset[cc] ) ;
00733 
00734    /* make sure all data is transmitted to AFNI */
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    /*-- If we are going to restart, send the end-of-input message. --*/
00748    /*-- Note that an entire image must be sent with this message.  --*/
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) ;  /* let AFNI meditate on that for a while */
00755      goto Restart ;
00756    }
00757 
00758    /*-- Otherwise, quit. --*/
00759 
00760    exit(0) ;
00761 }
 

Powered by Plone

This site conforms to the following standards: