1 #include "mrilib.h"
2
3 #define FatalError(str) \
4 ( fprintf(stderr,"\nEPsim error: %s\n",(str)) , exit(1) )
5
6 static int use_shm = 1 ;
7 static int delay = 100 ;
8 static int use_child = 0 ;
9 static int use_3T = 0 ;
10 char * fname_3T = NULL ;
11 static int ntimes = 1 ;
12 static char host[128] = "localhost" ;
13 static char buf[4096] ;
14 static int nbytes , jj , first=1 ;
15
16 #if 0 /* ZSS June 2011. Delete useless code after dust has settled. */
17 #define CONTROL_PORT 7954
18 #define TCP_PORT 7955
19 /* replace with:
20 get_port_named("CONTROL_PORT")
21 get_port_named("AFNI_PLUGOUT_TCP_BASE")
22 */
23 #endif
24 #define SHM_NAME "shm:epsim:1M"
25
26 static IOCHAN * ioc = NULL ;
27
28 #define SHORT_DELAY 1 /* msec */
29 #define LONG_DELAY 10
30
31 /*---------------------------------------------------------------------------*/
32
Syntax(void)33 void Syntax(void)
34 {
35 printf(
36 "Program: epsim \n\n"
37 "Purpose: Extract 2D data files from 3D dataset & send to AFNI\n"
38 "Usage: epsim [-v] [-shm | -tcp] [-delay mmm] [-host cpu] [-child]\n"
39 " -input fname \n"
40 "Options: \n"
41 "-v Print out verbose information.\n"
42 #if 0
43 "-nsize Adjust size of 2d data file to be NxN, by padding \n"
44 " with zeros, where N is a power of 2. \n"
45 #endif
46 "-shm Use shared memory to communicate with AFNI. \n"
47 "-tcp Use TCP/IP to communicate with AFNI. \n"
48 "-delay mmm Delay mmm milliseconds between slices. \n"
49 "-host cpu Access AFNI on host named 'cpu'. \n"
50 "-child Tell AFNI to read header info from a child. \n"
51 "-3T fname Tell AFNI to get data from the 3T_toafni program\n"
52 " with the 3T control data stored in file 'fname'.\n"
53 "-input fname Read from dataset in file 'fname'. \n"
54 "-times n Send the dataset 'n' times.\n"
55 ) ;
56 exit(0) ;
57 }
58
59 /*---------------------------------------------------------------------------*/
60
F3D_initialize_user_data(int Argc,char * Argv[],RwcBoolean * verbose,RwcBoolean * nsize,int * zfirst,int * zlast,int * tfirst,int * tlast,char * input_filename,char * prefix_filename)61 void F3D_initialize_user_data ( int Argc, char * Argv[],
62 RwcBoolean * verbose, RwcBoolean * nsize,
63 int * zfirst, int * zlast, int * tfirst, int * tlast,
64 char * input_filename, char * prefix_filename )
65
66 {
67 const int BIGNUMBER = 10000;
68 int nopt;
69 float ftemp;
70
71 if (Argc < 2) Syntax();
72
73 /* --- set default values --- */
74 *verbose = FALSE;
75 *nsize = FALSE;
76 *zfirst = 1;
77 *zlast = BIGNUMBER;
78 *tfirst = 1;
79 *tlast = BIGNUMBER;
80 strcpy(input_filename, "");
81 strcpy(prefix_filename, "");
82
83
84 /* --- scan options --- */
85 nopt = 1 ;
86 while ( nopt < Argc && Argv[nopt][0] == '-' )
87 {
88
89 /* --- help option --- */
90 if ( strncmp(Argv[nopt],"-help",4) == 0 ) Syntax() ;
91
92 /* --- verbose option --- */
93 if ( strncmp(Argv[nopt],"-v",2) == 0 )
94 {
95 *verbose = TRUE;
96 nopt++ ;
97 continue;
98 }
99 #if 0
100 /* --- nsize option --- */
101 if ( strncmp(Argv[nopt],"-nsize",4) == 0 )
102 {
103 *nsize = TRUE;
104 nopt++ ;
105 continue;
106 }
107 #endif
108
109 /*-- -times n --*/
110 if( strncmp(Argv[nopt],"-times",4) == 0 ){
111 if( ++nopt >= Argc ) FatalError("-times needs an argument") ;
112 ftemp = strtod( Argv[nopt] , NULL ) ;
113 if( ftemp >= 1.0 ) ntimes = (int) ftemp ;
114 nopt++ ; continue ;
115 }
116
117 #if 0
118 /* --- zfirst option --- */
119 if ( strncmp(Argv[nopt],"-zfirst",4) == 0 )
120 {
121 if( ++nopt >= Argc ) FatalError("-zfirst needs an argument") ;
122 ftemp = strtod( Argv[nopt] , NULL ) ;
123 *zfirst = (int) ftemp ;
124 nopt++ ;
125 continue ;
126 }
127
128 /* --- zlast option --- */
129 if ( strncmp(Argv[nopt],"-zlast",4) == 0 )
130 {
131 if( ++nopt >= Argc ) FatalError("-zlast needs an argument") ;
132 ftemp = strtod( Argv[nopt] , NULL ) ;
133 *zlast = (int) ftemp ;
134 nopt++ ;
135 continue ;
136 }
137
138 /* --- tfirst option --- */
139 if ( strncmp(Argv[nopt],"-tfirst",4) == 0 )
140 {
141 if( ++nopt >= Argc ) FatalError("-tfirst needs an argument") ;
142 ftemp = strtod( Argv[nopt] , NULL ) ;
143 *tfirst = (int) ftemp ;
144 nopt++ ;
145 continue ;
146 }
147
148 /* --- tlast option --- */
149 if ( strncmp(Argv[nopt],"-tlast",4) == 0 )
150 {
151 if( ++nopt >= Argc ) FatalError("-tlast needs an argument") ;
152 ftemp = strtod( Argv[nopt] , NULL ) ;
153 *tlast = (int) ftemp ;
154 nopt++ ;
155 continue ;
156 }
157 #endif
158
159 if( strncmp(Argv[nopt],"-shm",4) == 0 ){
160 use_shm = 1 ;
161 nopt++ ; continue ;
162 }
163
164 if( strncmp(Argv[nopt],"-tcp",4) == 0 ){
165 use_shm = 0 ;
166 nopt++ ; continue ;
167 }
168
169 if( strncmp(Argv[nopt],"-child",4) == 0 ){
170 use_child = 1 ;
171 nopt++ ; continue ;
172 }
173
174 if( strncmp(Argv[nopt],"-3T",4) == 0 ){
175 if( ++nopt >= Argc ) FatalError("-3T needs a filename") ;
176 fname_3T = Argv[nopt] ;
177 use_3T = 1 ;
178 nopt++ ; continue ;
179 }
180
181 if( strncmp(Argv[nopt],"-delay",4) == 0 ){
182 if ( ++nopt >= Argc ) FatalError("-delay needs a number") ;
183 ftemp = strtod( Argv[nopt] , NULL ) ;
184 if( ftemp >= 0.0 ) delay = (int) ftemp ;
185 nopt++ ; continue ;
186 }
187
188 if( strncmp(Argv[nopt],"-host",4) == 0 ){
189 if ( ++nopt >= Argc ) FatalError("-host needs a cpu name") ;
190 strcpy( host , Argv[nopt] ) ;
191 nopt++ ; continue ;
192 }
193
194 /* --- input file name --- */
195 if ( strncmp(Argv[nopt],"-input",4) == 0 )
196 {
197 if ( ++nopt >= Argc ) FatalError("-input needs a name") ;
198 strcpy ( input_filename , Argv[nopt] ) ;
199 nopt++ ; continue ;
200 }
201
202 #if 0
203 /* --- prefix name --- */
204 if ( strncmp(Argv[nopt],"-prefix",4) == 0 )
205 {
206 if ( ++nopt >= Argc ) FatalError("-prefix needs a name") ;
207 strcpy ( prefix_filename , Argv[nopt] ) ;
208 nopt++ ; continue ;
209 }
210 #endif
211
212 /* --- exception --- */
213 fprintf(stderr,"Don't understand argument %s\n",Argv[nopt]) ;
214 FatalError ("Illegal input");
215
216 } /* nopt */
217
218 /* --- check for valid inputs --- */
219 #if 0
220 if (*zfirst > *zlast)
221 FatalError ("Cannot have zfirst > zlast");
222 if (*tfirst > *tlast)
223 FatalError ("Cannot have tfirst > tlast");
224 if (!strcmp(prefix_filename,""))
225 FatalError ("Must specify prefix file name.");
226 #endif
227 if (!strcmp(input_filename,""))
228 FatalError ("Must specify input file name. ");
229
230 if( strcmp(host,"localhost") != 0 && use_shm ){
231 printf("EPsim: must use TCP/IP for host %s\n",host) ;
232 use_shm = 0 ;
233 }
234
235 if( use_child && use_3T )
236 FatalError("Can't use -child and -3T together!") ;
237
238 return;
239 }
240
241 /*---------------------------------------------------------------------------*/
242
main(int argc,char * argv[])243 int main( int argc , char * argv[] )
244 {
245 /* --- variable declarations --- */
246 THD_3dim_dataset * dset ;
247 THD_diskptr * dskptr;
248 int nx, ny, nz, nv, itim;
249 RwcBoolean verbose, nsize;
250 int ok;
251 MRI_IMAGE * im, * im2d, * tim2d;
252 MRI_TYPE kind;
253 int ibr, iz, count, izz,izsub ;
254 int zfirst, zlast, tfirst, tlast;
255 char input_filename[THD_MAX_NAME],
256 prefix_filename[THD_MAX_NAME],
257 output_filename[THD_MAX_NAME],
258 str[THD_MAX_NAME];
259
260 /* --- get user command line inputs --- */
261 F3D_initialize_user_data (argc, argv,
262 &verbose, &nsize,
263 &zfirst, &zlast, &tfirst, &tlast,
264 input_filename, prefix_filename );
265
266 /* --- open 3d data set --- */
267 dset = THD_open_one_dataset( input_filename ) ;
268 if( dset == NULL ) FatalError ("Unable to open input file") ;
269 if ( verbose ) printf("EPsim: 3d Dataset File = %s\n" , input_filename ) ;
270
271 /* --- load data block --- */
272 ok = THD_load_datablock( dset->dblk );
273 if ( !ok ) FatalError ("Unable to load data block") ;
274
275 /* --- get data dimensions --- */
276 dskptr = dset->dblk->diskptr;
277 nx = dskptr->dimsizes[0];
278 ny = dskptr->dimsizes[1];
279 nz = dskptr->dimsizes[2];
280 nv = dskptr->nvals;
281 if ( verbose )
282 printf ("EPsim: nx=%d ny=%d nz=%d nv=%d\n", nx, ny, nz, nv);
283
284 /* --- check for valid user inputs --- */
285 if (zfirst < 1) zfirst = 1;
286 if (zlast > nz) zlast = nz;
287 if (tfirst < 1) tfirst = 1;
288 if (tlast > nv) tlast = nv;
289 if (zfirst > nz) FatalError ("No data selected -- zfirst too large.");
290 if (zlast < 1) FatalError ("No data selected -- zlast too small.");
291 if (tfirst > nv) FatalError ("No data selected -- tfirst too large.");
292 if (tlast < 1) FatalError ("No data selected -- tlast too small.");
293
294 /* --- get data type --- */
295 kind = IMAGE_IN_IMARR ( dset->dblk->brick, 0 ) -> kind;
296 if ( verbose ) printf ("EPsim: datum = %s \n", MRI_TYPE_name[kind]);
297
298 /* --- create 2d data pointer --- */
299 im2d = mri_new_vol_empty ( nx, ny, 1, kind );
300
301 /*** open channel to AFNI ***/
302
303 sprintf( buf , "tcp:%s:%d" , host , get_port_named("CONTROL_PORT") ) ;
304 ioc = iochan_init( buf , "create" ) ;
305 if( ioc == NULL ) FatalError("Cannot open control channel to AFNI") ;
306
307 if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ;
308
309 while(1){
310 iz = iochan_goodcheck( ioc , 1000 ) ;
311 if( iz < 0 ) FatalError("control channel failed") ;
312 if( iz > 0 ) break ;
313 if( verbose ){ printf(".") ; fflush(stdout) ; }
314 }
315 if( verbose ){ printf("!\n") ; fflush(stdout) ; }
316
317 if( use_shm ) strcpy( buf , SHM_NAME ) ;
318 else sprintf(buf , "tcp:%s:%d" ,
319 host , get_port_named("AFNI_PLUGOUT_TCP_BASE") ) ;
320
321 if( use_child ){
322 jj = strlen(buf) ;
323 sprintf(buf+jj,"\ncat epsim.out") ;
324 } else if( use_3T ){
325 jj = strlen(buf) ;
326 sprintf(buf+jj,"\n3T_toafni -dummy < %s" , fname_3T ) ;
327 }
328
329 if( verbose ) printf("sending control data: %s\n",buf) ;
330
331 jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ;
332 if( jj < 0 ) FatalError("send control data failed") ;
333 iochan_sleep(LONG_DELAY) ; /* wait a bit */
334 while( ! iochan_clearcheck(ioc,LONG_DELAY) ) /* loop until cleared */
335 iochan_sleep(LONG_DELAY) ;
336
337 if( verbose ) printf("EPsim: closing control channel\n") ;
338 IOCHAN_CLOSE(ioc) ;
339
340 /*** now open data channel ***/
341
342 ioc = iochan_init( buf , "create" ) ;
343 if( ioc == NULL ) FatalError("Cannot open data channel to AFNI") ;
344
345 if( verbose ) printf("EPsim: waiting for AFNI") ; fflush(stdout) ;
346
347 while(1){
348 iz = iochan_goodcheck( ioc , 1000 ) ;
349 if( iz < 0 ) FatalError("data channel failed") ;
350 if( iz > 0 ) break ;
351 if( verbose ){ printf(".") ; fflush(stdout) ; }
352 }
353 if( verbose ){ printf("!\n") ; fflush(stdout) ; }
354
355 if( use_child ){
356 FILE * fp = fopen( "epsim.out" , "w" ) ;
357 if( fp == NULL ){fprintf(stderr,"Can't open epsim.out!\n");IOCHAN_CLOSE(ioc);exit(1);}
358 fprintf( fp , "ZNUM %d\n"
359 "ZDELTA %g\n"
360 "XYFOV %g %g\n"
361 "ZFIRST %g%c\n"
362 "ZORDER seq\n"
363 "XYZAXES %s %s %s\n"
364 "ACQUISITION_TYPE %s\n"
365 ,
366 nz ,
367 fabs(dset->daxes->zzdel) ,
368 fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny ,
369 fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] ,
370 ORIENT_shortstr[dset->daxes->xxorient] ,
371 ORIENT_shortstr[dset->daxes->yyorient] ,
372 ORIENT_shortstr[dset->daxes->zzorient] ,
373 ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" )
374 ) ;
375 fclose(fp) ;
376 if( verbose ) printf("EPsim: wrote epsim.out file\n") ;
377
378 sprintf( buf , "XYMATRIX %d %d\n"
379 "DATUM %s\n"
380 ,
381 nx , ny ,
382 MRI_TYPE_name[kind]
383 ) ;
384 } else if( use_3T ){
385 sprintf( buf , "XYMATRIX %d %d\n"
386 "DATUM %s\n"
387 ,
388 nx , ny ,
389 MRI_TYPE_name[kind]
390 ) ;
391 } else {
392 sprintf( buf , "ZNUM %d\n"
393 "ZDELTA %g\n"
394 "XYFOV %g %g\n"
395 "ZFIRST %g%c\n"
396 "ZORDER seq\n"
397 "XYZAXES %s %s %s\n"
398 "ACQUISITION_TYPE %s\n"
399 "XYMATRIX %d %d\n"
400 "DATUM %s\n"
401 ,
402 nz ,
403 fabs(dset->daxes->zzdel) ,
404 fabs(dset->daxes->xxdel)*nx , fabs(dset->daxes->yydel)*ny ,
405 fabs(dset->daxes->zzorg) , ORIENT_first[dset->daxes->zzorient] ,
406 ORIENT_shortstr[dset->daxes->xxorient] ,
407 ORIENT_shortstr[dset->daxes->yyorient] ,
408 ORIENT_shortstr[dset->daxes->zzorient] ,
409 ( ((zlast-zfirst)>0) ? "2D+zt" : "2D+z" ) ,
410 nx , ny ,
411 MRI_TYPE_name[kind]
412 ) ;
413 }
414
415 nbytes = im2d->nvox * im2d->pixel_size ;
416
417 for( itim=0 ; itim < ntimes ; itim++ ){
418 count = 0;
419
420 if( use_3T ) izsub = (nz%2 == 0) ? (nz-1) : (nz) ;
421
422 for ( ibr = tfirst-1 ; ibr < tlast ; ibr++ )
423 {
424 for ( iz = zfirst-1 ; iz < zlast ; iz++ )
425 {
426 /* --- set 2d data pointer into 3d data set --- */
427 im = IMAGE_IN_IMARR ( dset->dblk->brick, ibr );
428
429 if( use_3T ){
430 izz = 2*iz ; if( izz >= nz ) izz -= izsub ; /* alt ordering */
431 } else {
432 izz = iz ; /* seq ordering */
433 }
434
435 switch ( kind )
436 {
437 case MRI_byte :
438 mri_set_data_pointer(im2d, MRI_BYTE_PTR(im) + iz*nx*ny) ;
439 break;
440 case MRI_short :
441 mri_set_data_pointer(im2d, MRI_SHORT_PTR(im) + iz*nx*ny) ;
442 break;
443 case MRI_int :
444 mri_set_data_pointer(im2d, MRI_INT_PTR(im) + iz*nx*ny) ;
445 break;
446 case MRI_float :
447 mri_set_data_pointer(im2d, MRI_FLOAT_PTR(im) + iz*nx*ny) ;
448 break;
449 case MRI_double :
450 mri_set_data_pointer(im2d, MRI_DOUBLE_PTR(im) + iz*nx*ny) ;
451 break;
452 case MRI_complex :
453 mri_set_data_pointer(im2d, MRI_COMPLEX_PTR(im) + iz*nx*ny) ;
454 break;
455 case MRI_rgb :
456 mri_set_data_pointer(im2d, MRI_RGB_PTR(im) + 3*iz*nx*ny) ;
457 break;
458 default :
459 FatalError ("Illegal data type encountered.");
460 }
461
462 #if 0
463 /* --- create 2d data file name --- */
464 strcpy ( output_filename, prefix_filename );
465 if ( nv > 1 )
466 sprintf ( str, "%02d.%04d", izz+1, ibr+1 );
467 else
468 if ( nz > 999 )
469 sprintf ( str, ".%04d", izz+1 );
470 else
471 sprintf ( str, ".%03d", izz+1 );
472 strcat ( output_filename, str );
473 #endif
474
475 if( first ){
476 if( verbose )
477 printf("EPsim: sending this data as header info in image channel:\n%s\n",buf) ;
478 jj = iochan_sendall( ioc , buf , strlen(buf)+1 ) ;
479 if( jj < 0 ) FatalError("send header info failed") ;
480 first = 0 ;
481 }
482
483 if ( verbose )
484 printf ( "EPsim: sending 2D image izz=%d ibr=%d\n", izz,ibr );
485
486 jj = iochan_sendall( ioc , mri_data_pointer(im2d) , nbytes ) ;
487 if( jj < 0 ) FatalError("send image failed") ;
488 iochan_sleep( delay ) ;
489
490 #if 0
491 if ( !nsize )
492 ok = mri_write ( output_filename, im2d );
493 else
494 {
495 tim2d = mri_nsize (im2d);
496 ok = mri_write ( output_filename, tim2d);
497 mri_free (tim2d);
498 }
499 #endif
500
501 count ++ ;
502
503 } /* --- iz --- */
504 } /* --- ibr --- */
505 sleep(20) ;
506 } /* -- itim --*/
507
508 if ( verbose ) printf ("Sent %d 2D images. \n", count);
509
510 if( verbose ){ printf("Waiting for AFNI") ; fflush(stdout) ; }
511 while(1){
512 jj = iochan_clearcheck(ioc,1000) ;
513 if( jj ) break ;
514 if( verbose ){ printf(".") ; fflush(stdout) ; }
515 }
516 if( verbose ) printf("!\n") ;
517 iochan_sleep(100) ; IOCHAN_CLOSE(ioc) ;
518
519 exit(0) ;
520 }
521