00001 #include "mrilib.h"
00002
00003 #define FatalError(str) \
00004 ( fprintf(stderr,"\nEPsim error: %s\n",(str)) , exit(1) )
00005
00006 static int use_shm = 1 ;
00007 static int delay = 100 ;
00008 static int use_child = 0 ;
00009 static int use_3T = 0 ;
00010 char * fname_3T = NULL ;
00011 static int ntimes = 1 ;
00012 static char host[128] = "localhost" ;
00013 static char buf[4096] ;
00014 static int nbytes , jj , first=1 ;
00015
00016 #define CONTROL_PORT 7954
00017 #define TCP_PORT 7955
00018 #define SHM_NAME "shm:epsim:1M"
00019
00020 static IOCHAN * ioc = NULL ;
00021
00022 #define SHORT_DELAY 1
00023 #define LONG_DELAY 10
00024
00025
00026
00027 void Syntax(void)
00028 {
00029 printf(
00030 "Program: epsim \n\n"
00031 "Purpose: Extract 2D data files from 3D dataset & send to AFNI\n"
00032 "Usage: epsim [-v] [-shm | -tcp] [-delay mmm] [-host cpu] [-child]\n"
00033 " -input fname \n"
00034 "Options: \n"
00035 "-v Print out verbose information.\n"
00036 #if 0
00037 "-nsize Adjust size of 2d data file to be NxN, by padding \n"
00038 " with zeros, where N is a power of 2. \n"
00039 #endif
00040 "-shm Use shared memory to communicate with AFNI. \n"
00041 "-tcp Use TCP/IP to communicate with AFNI. \n"
00042 "-delay mmm Delay mmm milliseconds between slices. \n"
00043 "-host cpu Access AFNI on host named 'cpu'. \n"
00044 "-child Tell AFNI to read header info from a child. \n"
00045 "-3T fname Tell AFNI to get data from the 3T_toafni program\n"
00046 " with the 3T control data stored in file 'fname'.\n"
00047 "-input fname Read from dataset in file 'fname'. \n"
00048 "-times n Send the dataset 'n' times.\n"
00049 ) ;
00050 exit(0) ;
00051 }
00052
00053
00054
00055 void F3D_initialize_user_data ( int Argc, char * Argv[],
00056 Boolean * verbose, Boolean * nsize,
00057 int * zfirst, int * zlast, int * tfirst, int * tlast,
00058 char * input_filename, char * prefix_filename )
00059
00060 {
00061 const int BIGNUMBER = 10000;
00062 int nopt;
00063 float ftemp;
00064
00065 if (Argc < 2) Syntax();
00066
00067
00068 *verbose = FALSE;
00069 *nsize = FALSE;
00070 *zfirst = 1;
00071 *zlast = BIGNUMBER;
00072 *tfirst = 1;
00073 *tlast = BIGNUMBER;
00074 strcpy(input_filename, "");
00075 strcpy(prefix_filename, "");
00076
00077
00078
00079 nopt = 1 ;
00080 while ( nopt < Argc && Argv[nopt][0] == '-' )
00081 {
00082
00083
00084 if ( strncmp(Argv[nopt],"-help",4) == 0 ) Syntax() ;
00085
00086
00087 if ( strncmp(Argv[nopt],"-v",2) == 0 )
00088 {
00089 *verbose = TRUE;
00090 nopt++ ;
00091 continue;
00092 }
00093 #if 0
00094
00095 if ( strncmp(Argv[nopt],"-nsize",4) == 0 )
00096 {
00097 *nsize = TRUE;
00098 nopt++ ;
00099 continue;
00100 }
00101 #endif
00102
00103
00104 if( strncmp(Argv[nopt],"-times",4) == 0 ){
00105 if( ++nopt >= Argc ) FatalError("-times needs an argument") ;
00106 ftemp = strtod( Argv[nopt] , NULL ) ;
00107 if( ftemp >= 1.0 ) ntimes = (int) ftemp ;
00108 nopt++ ; continue ;
00109 }
00110
00111 #if 0
00112
00113 if ( strncmp(Argv[nopt],"-zfirst",4) == 0 )
00114 {
00115 if( ++nopt >= Argc ) FatalError("-zfirst needs an argument") ;
00116 ftemp = strtod( Argv[nopt] , NULL ) ;
00117 *zfirst = (int) ftemp ;
00118 nopt++ ;
00119 continue ;
00120 }
00121
00122
00123 if ( strncmp(Argv[nopt],"-zlast",4) == 0 )
00124 {
00125 if( ++nopt >= Argc ) FatalError("-zlast needs an argument") ;
00126 ftemp = strtod( Argv[nopt] , NULL ) ;
00127 *zlast = (int) ftemp ;
00128 nopt++ ;
00129 continue ;
00130 }
00131
00132
00133 if ( strncmp(Argv[nopt],"-tfirst",4) == 0 )
00134 {
00135 if( ++nopt >= Argc ) FatalError("-tfirst needs an argument") ;
00136 ftemp = strtod( Argv[nopt] , NULL ) ;
00137 *tfirst = (int) ftemp ;
00138 nopt++ ;
00139 continue ;
00140 }
00141
00142
00143 if ( strncmp(Argv[nopt],"-tlast",4) == 0 )
00144 {
00145 if( ++nopt >= Argc ) FatalError("-tlast needs an argument") ;
00146 ftemp = strtod( Argv[nopt] , NULL ) ;
00147 *tlast = (int) ftemp ;
00148 nopt++ ;
00149 continue ;
00150 }
00151 #endif
00152
00153 if( strncmp(Argv[nopt],"-shm",4) == 0 ){
00154 use_shm = 1 ;
00155 nopt++ ; continue ;
00156 }
00157
00158 if( strncmp(Argv[nopt],"-tcp",4) == 0 ){
00159 use_shm = 0 ;
00160 nopt++ ; continue ;
00161 }
00162
00163 if( strncmp(Argv[nopt],"-child",4) == 0 ){
00164 use_child = 1 ;
00165 nopt++ ; continue ;
00166 }
00167
00168 if( strncmp(Argv[nopt],"-3T",4) == 0 ){
00169 if( ++nopt >= Argc ) FatalError("-3T needs a filename") ;
00170 fname_3T = Argv[nopt] ;
00171 use_3T = 1 ;
00172 nopt++ ; continue ;
00173 }
00174
00175 if( strncmp(Argv[nopt],"-delay",4) == 0 ){
00176 if ( ++nopt >= Argc ) FatalError("-delay needs a number") ;
00177 ftemp = strtod( Argv[nopt] , NULL ) ;
00178 if( ftemp >= 0.0 ) delay = (int) ftemp ;
00179 nopt++ ; continue ;
00180 }
00181
00182 if( strncmp(Argv[nopt],"-host",4) == 0 ){
00183 if ( ++nopt >= Argc ) FatalError("-host needs a cpu name") ;
00184 strcpy( host , Argv[nopt] ) ;
00185 nopt++ ; continue ;
00186 }
00187
00188
00189 if ( strncmp(Argv[nopt],"-input",4) == 0 )
00190 {
00191 if ( ++nopt >= Argc ) FatalError("-input needs a name") ;
00192 strcpy ( input_filename , Argv[nopt] ) ;
00193 nopt++ ; continue ;
00194 }
00195
00196 #if 0
00197
00198 if ( strncmp(Argv[nopt],"-prefix",4) == 0 )
00199 {
00200 if ( ++nopt >= Argc ) FatalError("-prefix needs a name") ;
00201 strcpy ( prefix_filename , Argv[nopt] ) ;
00202 nopt++ ; continue ;
00203 }
00204 #endif
00205
00206
00207 fprintf(stderr,"Don't understand argument %s\n",Argv[nopt]) ;
00208 FatalError ("Illegal input");
00209
00210 }
00211
00212
00213 #if 0
00214 if (*zfirst > *zlast)
00215 FatalError ("Cannot have zfirst > zlast");
00216 if (*tfirst > *tlast)
00217 FatalError ("Cannot have tfirst > tlast");
00218 if (!strcmp(prefix_filename,""))
00219 FatalError ("Must specify prefix file name.");
00220 #endif
00221 if (!strcmp(input_filename,""))
00222 FatalError ("Must specify input file name. ");
00223
00224 if( strcmp(host,"localhost") != 0 && use_shm ){
00225 printf("EPsim: must use TCP/IP for host %s\n",host) ;
00226 use_shm = 0 ;
00227 }
00228
00229 if( use_child && use_3T )
00230 FatalError("Can't use -child and -3T together!") ;
00231
00232 return;
00233 }
00234
00235
00236
00237 int main( int argc , char * argv[] )
00238 {
00239
00240 THD_3dim_dataset * dset ;
00241 THD_diskptr * dskptr;
00242 int nx, ny, nz, nv, itim;
00243 Boolean verbose, nsize;
00244 int ok;
00245 MRI_IMAGE * im, * im2d, * tim2d;
00246 MRI_TYPE kind;
00247 int ibr, iz, count, izz,izsub ;
00248 int zfirst, zlast, tfirst, tlast;
00249 char input_filename[THD_MAX_NAME],
00250 prefix_filename[THD_MAX_NAME],
00251 output_filename[THD_MAX_NAME],
00252 str[THD_MAX_NAME];
00253
00254
00255 F3D_initialize_user_data (argc, argv,
00256 &verbose, &nsize,
00257 &zfirst, &zlast, &tfirst, &tlast,
00258 input_filename, prefix_filename );
00259
00260
00261 dset = THD_open_one_dataset( input_filename ) ;
00262 if( dset == NULL ) FatalError ("Unable to open input file") ;
00263 if ( verbose ) printf("EPsim: 3d Dataset File = %s\n" , input_filename ) ;
00264
00265
00266 ok = THD_load_datablock( dset->dblk );
00267 if ( !ok ) FatalError ("Unable to load data block") ;
00268
00269
00270 dskptr = dset->dblk->diskptr;
00271 nx = dskptr->dimsizes[0];
00272 ny = dskptr->dimsizes[1];
00273 nz = dskptr->dimsizes[2];
00274 nv = dskptr->nvals;
00275 if ( verbose )
00276 printf ("EPsim: nx=%d ny=%d nz=%d nv=%d\n", nx, ny, nz, nv);
00277
00278
00279 if (zfirst < 1) zfirst = 1;
00280 if (zlast > nz) zlast = nz;
00281 if (tfirst < 1) tfirst = 1;
00282 if (tlast > nv) tlast = nv;
00283 if (zfirst > nz) FatalError ("No data selected -- zfirst too large.");
00284 if (zlast < 1) FatalError ("No data selected -- zlast too small.");
00285 if (tfirst > nv) FatalError ("No data selected -- tfirst too large.");
00286 if (tlast < 1) FatalError ("No data selected -- tlast too small.");
00287
00288
00289 kind = IMAGE_IN_IMARR ( dset->dblk->brick, 0 ) -> kind;
00290 if ( verbose ) printf ("EPsim: datum = %s \n", MRI_TYPE_name[kind]);
00291
00292
00293 im2d = mri_new_vol_empty ( nx, ny, 1, kind );
00294
00295
00296
00297 sprintf( buf , "tcp:%s:%d" , host , CONTROL_PORT ) ;
00298 ioc = iochan_init( buf , "create" ) ;
00299 if( ioc == NULL ) FatalError("Cannot open control channel to AFNI") ;
00300
00301 if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ;
00302
00303 while(1){
00304 iz = iochan_goodcheck( ioc , 1000 ) ;
00305 if( iz < 0 ) FatalError("control channel failed") ;
00306 if( iz > 0 ) break ;
00307 if( verbose ){ printf(".") ; fflush(stdout) ; }
00308 }
00309 if( verbose ){ printf("!\n") ; fflush(stdout) ; }
00310
00311 if( use_shm ) strcpy( buf , SHM_NAME ) ;
00312 else sprintf(buf , "tcp:%s:%d" , host , TCP_PORT ) ;
00313
00314 if( use_child ){
00315 jj = strlen(buf) ;
00316 sprintf(buf+jj,"\ncat epsim.out") ;
00317 } else if( use_3T ){
00318 jj = strlen(buf) ;
00319 sprintf(buf+jj,"\n3T_toafni -dummy < %s" , fname_3T ) ;
00320 }
00321
00322 if( verbose ) printf("sending control data: %s\n",buf) ;
00323
00324 jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ;
00325 if( jj < 0 ) FatalError("send control data failed") ;
00326 iochan_sleep(LONG_DELAY) ;
00327 while( ! iochan_clearcheck(ioc,LONG_DELAY) )
00328 iochan_sleep(LONG_DELAY) ;
00329
00330 if( verbose ) printf("EPsim: closing control channel\n") ;
00331 IOCHAN_CLOSE(ioc) ;
00332
00333
00334
00335 ioc = iochan_init( buf , "create" ) ;
00336 if( ioc == NULL ) FatalError("Cannot open data channel to AFNI") ;
00337
00338 if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ;
00339
00340 while(1){
00341 iz = iochan_goodcheck( ioc , 1000 ) ;
00342 if( iz < 0 ) FatalError("data channel failed") ;
00343 if( iz > 0 ) break ;
00344 if( verbose ){ printf(".") ; fflush(stdout) ; }
00345 }
00346 if( verbose ){ printf("!\n") ; fflush(stdout) ; }
00347
00348 if( use_child ){
00349 FILE * fp = fopen( "epsim.out" , "w" ) ;
00350 if( fp == NULL ){fprintf(stderr,"Can't open epsim.out!\n");IOCHAN_CLOSE(ioc);exit(1);}
00351 fprintf( fp , "ZNUM %d\n"
00352 "ZDELTA %g\n"
00353 "XYFOV %g %g\n"
00354 "ZFIRST %g%c\n"
00355 "ZORDER seq\n"
00356 "XYZAXES %s %s %s\n"
00357 "ACQUISITION_TYPE %s\n"
00358 ,
00359 nz ,
00360 fabs(dset->daxes->zzdel) ,
00361 fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny ,
00362 fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] ,
00363 ORIENT_shortstr[dset->daxes->xxorient] ,
00364 ORIENT_shortstr[dset->daxes->yyorient] ,
00365 ORIENT_shortstr[dset->daxes->zzorient] ,
00366 ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" )
00367 ) ;
00368 fclose(fp) ;
00369 if( verbose ) printf("EPsim: wrote epsim.out file\n") ;
00370
00371 sprintf( buf , "XYMATRIX %d %d\n"
00372 "DATUM %s\n"
00373 ,
00374 nx , ny ,
00375 MRI_TYPE_name[kind]
00376 ) ;
00377 } else if( use_3T ){
00378 sprintf( buf , "XYMATRIX %d %d\n"
00379 "DATUM %s\n"
00380 ,
00381 nx , ny ,
00382 MRI_TYPE_name[kind]
00383 ) ;
00384 } else {
00385 sprintf( buf , "ZNUM %d\n"
00386 "ZDELTA %g\n"
00387 "XYFOV %g %g\n"
00388 "ZFIRST %g%c\n"
00389 "ZORDER seq\n"
00390 "XYZAXES %s %s %s\n"
00391 "ACQUISITION_TYPE %s\n"
00392 "XYMATRIX %d %d\n"
00393 "DATUM %s\n"
00394 ,
00395 nz ,
00396 fabs(dset->daxes->zzdel) ,
00397 fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny ,
00398 fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] ,
00399 ORIENT_shortstr[dset->daxes->xxorient] ,
00400 ORIENT_shortstr[dset->daxes->yyorient] ,
00401 ORIENT_shortstr[dset->daxes->zzorient] ,
00402 ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" ) ,
00403 nx , ny ,
00404 MRI_TYPE_name[kind]
00405 ) ;
00406 }
00407
00408 nbytes = im2d->nvox * im2d->pixel_size ;
00409
00410 for( itim=0 ; itim < ntimes ; itim++ ){
00411 count = 0;
00412
00413 if( use_3T ) izsub = (nz%2 == 0) ? (nz-1) : (nz) ;
00414
00415 for ( ibr = tfirst-1 ; ibr < tlast ; ibr++ )
00416 {
00417 for ( iz = zfirst-1 ; iz < zlast ; iz++ )
00418 {
00419
00420 im = IMAGE_IN_IMARR ( dset->dblk->brick, ibr );
00421
00422 if( use_3T ){
00423 izz = 2*iz ; if( izz >= nz ) izz -= izsub ;
00424 } else {
00425 izz = iz ;
00426 }
00427
00428 switch ( kind )
00429 {
00430 case MRI_byte :
00431 im2d->im.byte_data = im->im.byte_data + izz * nx * ny ;
00432 break;
00433 case MRI_short :
00434 im2d->im.short_data = im->im.short_data + izz * nx * ny ;
00435 break;
00436 case MRI_int :
00437 im2d->im.int_data = im->im.int_data + izz * nx * ny ;
00438 break;
00439 case MRI_float :
00440 im2d->im.float_data = im->im.float_data + izz * nx * ny ;
00441 break;
00442 case MRI_double :
00443 im2d->im.double_data = im->im.double_data + izz * nx * ny ;
00444 break;
00445 case MRI_complex :
00446 im2d->im.complex_data = im->im.complex_data + izz * nx * ny ;
00447 break;
00448 case MRI_rgb :
00449 im2d->im.rgb_data = im->im.rgb_data + izz * nx * ny ;
00450 break;
00451 default :
00452 FatalError ("Illegal data type encountered.");
00453 }
00454
00455 #if 0
00456
00457 strcpy ( output_filename, prefix_filename );
00458 if ( nv > 1 )
00459 sprintf ( str, "%02d.%04d", izz+1, ibr+1 );
00460 else
00461 if ( nz > 999 )
00462 sprintf ( str, ".%04d", izz+1 );
00463 else
00464 sprintf ( str, ".%03d", izz+1 );
00465 strcat ( output_filename, str );
00466 #endif
00467
00468 if( first ){
00469 if( verbose )
00470 printf("EPsim: sending this data as header info in image channel:\n%s\n",buf) ;
00471 jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ;
00472 if( jj < 0 ) FatalError("send header info failed") ;
00473 first = 0 ;
00474 }
00475
00476 if ( verbose )
00477 printf ( "EPsim: sending 2D image izz=%d ibr=%d\n", izz,ibr );
00478
00479 jj = iochan_sendall( ioc , mri_data_pointer(im2d) , nbytes ) ;
00480 if( jj < 0 ) FatalError("send image failed") ;
00481 iochan_sleep( delay ) ;
00482
00483 #if 0
00484 if ( !nsize )
00485 ok = mri_write ( output_filename, im2d );
00486 else
00487 {
00488 tim2d = mri_nsize (im2d);
00489 ok = mri_write ( output_filename, tim2d);
00490 mri_free (tim2d);
00491 }
00492 #endif
00493
00494 count ++ ;
00495
00496 }
00497 }
00498 sleep(20) ;
00499 }
00500
00501 if ( verbose ) printf ("Sent %d 2D images. \n", count);
00502
00503 if( verbose ){ printf("Waiting for AFNI") ; fflush(stdout) ; }
00504 while(1){
00505 jj = iochan_clearcheck(ioc,1000) ;
00506 if( jj ) break ;
00507 if( verbose ){ printf(".") ; fflush(stdout) ; }
00508 }
00509 if( verbose ) printf("!\n") ;
00510 iochan_sleep(100) ; IOCHAN_CLOSE(ioc) ;
00511
00512 exit(0) ;
00513 }