00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <string.h>
00011 #include <math.h>
00012
00013 #include "machdep.h"
00014
00015
00016
00017 #ifdef HP
00018 # define PIPE_COMMAND "remsh 3T60 -l scan ./bin/wrap"
00019 #else
00020 # define PIPE_COMMAND "rsh 3T60 -l scan ./bin/wrap"
00021 #endif
00022
00023
00024
00025 #define INFO_SIZE (16*1024)
00026 #define SHORT_DELAY 1
00027 #define LONG_DELAY 10
00028
00029 #define DEBUG
00030
00031
00032
00033 int dummy = 0 ;
00034
00035 int RT_get_3T_info(void) ;
00036 int RT_3T_to_AFNI( int , char * , char * ) ;
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 int main( int argc , char * argv[] )
00050 {
00051 int iarg = 1 ;
00052
00053 if( argc > 1 && strncmp(argv[1],"-help",4) == 0 ){
00054 printf("Usage: 3T_toafni [-dummy]\n"
00055 " Gets information about current imaging sequence from the MCW\n"
00056 " Bruker 3T/60 scanner, formats it for AFNI, and sends it to AFNI.\n"
00057 " The output is written to stdout ((AFNI will pipe it into itself).\n"
00058 " If the -dummy option is used, then the data from the scanner will\n"
00059 " be read from stdin instead of from the scanner console computer.\n"
00060 ) ;
00061 _exit(0) ;
00062 }
00063
00064
00065
00066 while( iarg < argc ){
00067
00068
00069
00070 if( strncmp(argv[iarg],"-dummy",4) == 0 ){
00071 dummy = 1 ;
00072 iarg++ ; continue ;
00073 }
00074
00075
00076
00077 fprintf(stderr,"3T_toafni: unknown argument '%s'\n",argv[iarg]) ;
00078 _exit(1) ;
00079 }
00080
00081 RT_get_3T_info() ; _exit(0) ;
00082 }
00083
00084
00085
00086 int RT_get_3T_info(void)
00087 {
00088 FILE * fp ;
00089 char * buf = (char *) malloc( sizeof(char) * INFO_SIZE ) ; int nbuf = 0 ;
00090 char * info = (char *) malloc( sizeof(char) * INFO_SIZE ) ; int ninfo = 0 ;
00091 int jj ;
00092
00093
00094
00095 if( !dummy ){
00096 fp = popen( PIPE_COMMAND , "r" ) ;
00097 if( fp == NULL ){
00098 fprintf(stderr,"3T_toafni: can't open pipe to 3T60!\n") ; _exit(1) ;
00099 }
00100 } else {
00101 fp = stdin ;
00102 }
00103
00104
00105
00106 while( fgets(buf+nbuf,INFO_SIZE-nbuf,fp) != NULL ){
00107 nbuf = strlen(buf) ;
00108 }
00109 if( !dummy ) pclose(fp) ;
00110
00111
00112
00113 RT_3T_to_AFNI( nbuf,buf , info ) ;
00114
00115
00116
00117 ninfo = strlen(info) ;
00118 fwrite( info , 1 , ninfo , stdout ) ; fflush(stdout) ;
00119 free(buf) ; free(info) ; return 0 ;
00120 }
00121
00122
00123
00124 char * RT_find_value( char * name , char * buf )
00125 {
00126 char * qq ;
00127
00128 if( name == NULL || buf == NULL ) return NULL ;
00129
00130 qq = strstr( buf , name ) ;
00131 if( qq == NULL ) return NULL ;
00132 qq = strstr( qq , "=") ;
00133 if( qq == NULL ) return NULL ;
00134 return (qq+2) ;
00135 }
00136
00137 #define INC_QAR 10
00138
00139 int RT_number_array( char * name , char * buf , float ** far )
00140 {
00141 char * qq , * eptr ;
00142 int iar , nqar ;
00143 float * qar ;
00144 float val ;
00145
00146 qq = RT_find_value( name , buf ) ;
00147 if( qq == NULL ){ *far = NULL ; return 0 ; }
00148
00149 iar = 0 ;
00150 nqar = INC_QAR ;
00151 qar = (float *) malloc( sizeof(float) * INC_QAR ) ;
00152
00153 if( *qq == '{' ) qq++ ;
00154
00155
00156
00157 do{
00158 val = strtod( qq , &eptr ) ;
00159 if( val == 0.0 && eptr == qq ) break ;
00160
00161 if( iar == nqar ){
00162 nqar += INC_QAR ;
00163 qar = (float *) realloc( qar , sizeof(float) * nqar ) ;
00164 }
00165 qar[iar++] = val ; qq = eptr ; if( *qq == ',' ) qq++ ;
00166 } while( *qq != '\0' && *qq != '\n' ) ;
00167
00168 if( iar == 0 ){ free(qar) ; qar = NULL ; }
00169
00170 *far = qar ; return iar ;
00171 }
00172
00173
00174
00175
00176
00177 #define XYZ_TO_ANAT(x,y,z) \
00178 ((x) > 0.999) ? "L-R" : ((x) <-0.999) ? "R-L" \
00179 : ((y) > 0.999) ? "P-A" : ((y) <-0.999) ? "A-P" \
00180 : ((z) > 0.999) ? "I-S" : ((z) <-0.999) ? "S-I" : "GEN"
00181
00182
00183
00184 #define GET_INT(iname,oname) \
00185 do{ vstart = RT_find_value( iname , buf3T ) ; \
00186 if( vstart != NULL ){ \
00187 ival = strtol( vstart , NULL , 10 ) ; \
00188 sprintf(buf,"%s %d\n",oname,ival) ; strcat(info,buf) ; \
00189 } else { fprintf(stderr,"3T_toafni: %s not found\n",iname) ; } } while(0)
00190
00191
00192
00193 #define GET_FLOAT(iname,oname) \
00194 do{ vstart = RT_find_value( iname , buf3T ) ; \
00195 if( vstart != NULL ){ \
00196 val = strtod( vstart , NULL ) ; \
00197 sprintf(buf,"%s %g\n",oname,val) ; strcat(info,buf) ; \
00198 } else { fprintf(stderr,"3T_toafni: %s not found\n",iname) ; } } while(0)
00199
00200
00201
00202 int RT_3T_to_AFNI( int nbuf , char * buf3T , char * info )
00203 {
00204 char * vstart ;
00205 float val ;
00206 int ival , jj , nfar ;
00207 char buf[128] ;
00208 float * far ;
00209 char * fes=NULL , * pes=NULL , * ses=NULL ;
00210
00211 #ifdef DEBUG
00212 fprintf(stderr,"3T buffer follows:\n%s\n",buf3T) ;
00213 #endif
00214
00215 info[0] = '\0' ;
00216
00217
00218
00219 GET_INT( "NSLICES" , "ZNUM" ) ;
00220 GET_INT( "NR" , "NUMVOL" ) ;
00221
00222 #if 0
00223 GET_FLOAT( "ACQ_slice_thick" , "ZDELTA" ) ;
00224 #else
00225 nfar = RT_number_array( "ACQ_slice_sepn" , buf3T , &far ) ;
00226 if( nfar > 0 ){
00227 float zdel = fabs(far[0]) ;
00228 if( zdel > 0 ){
00229 sprintf(buf,"ZDELTA %g\n",zdel) ; strcat(info,buf) ;
00230 } else {
00231 fprintf(stderr,"3T_toafni: ACQ_slice_sepn not positive\n") ;
00232 GET_FLOAT( "ACQ_slice_thick" , "ZDELTA" ) ;
00233 }
00234 } else {
00235 fprintf(stderr,"3T_toafni: ACQ_slice_sepn not found\n") ;
00236 GET_FLOAT( "ACQ_slice_thick" , "ZDELTA" ) ;
00237 }
00238 if( far != NULL ) free(far) ;
00239 #endif
00240
00241
00242
00243 nfar = RT_number_array( "ACQ_grad_matrix" , buf3T , &far ) ;
00244 if( nfar >= 9 ){
00245 float fex=far[0],fey=far[1],fez=far[2] ,
00246 pex=far[3],pey=far[4],pez=far[5] ,
00247 sex=far[6],sey=far[7],sez=far[8] ;
00248
00249 #if 1
00250 fes = XYZ_TO_ANAT(-fex,-fey,-fez) ;
00251 pes = XYZ_TO_ANAT(-pex,-pey,-pez) ;
00252 #else
00253 fes = XYZ_TO_ANAT( fex, fey, fez) ;
00254 pes = XYZ_TO_ANAT( pex, pey, pez) ;
00255 #endif
00256
00257 ses = XYZ_TO_ANAT( sex, sey, sez) ;
00258 sprintf(buf,"XYZAXES %s %s %s\n",fes,pes,ses) ; strcat(info,buf) ;
00259 } else if( nfar == 0 ){
00260 fprintf(stderr,"3T_toafni: ACQ_grad_matrix not found\n") ;
00261 } else {
00262 fprintf(stderr,"3T_toafni: ACQ_grad_matrix not good\n") ;
00263 }
00264 if( far != NULL ) free(far) ;
00265
00266
00267
00268 nfar = RT_number_array( "ACQ_fov" , buf3T , &far ) ;
00269 if( nfar >= 1 ){
00270 float xxfov , yyfov , zzfov ;
00271
00272 xxfov = 10.0 * far[0] ;
00273 yyfov = (nfar >= 2) ? 10.0 * far[1] : 0.0 ;
00274 zzfov = (nfar >= 3) ? 10.0 * far[2] : 0.0 ;
00275
00276 sprintf(buf,"XYFOV %g %g %g\n",xxfov,yyfov,zzfov) ; strcat(info,buf) ;
00277 } else {
00278 fprintf(stderr,"3T_toafni: ACQ_fov not found\n") ;
00279 }
00280 if( far != NULL ) free(far) ;
00281
00282
00283
00284 nfar = RT_number_array( "ACQ_slice_offset" , buf3T , &far ) ;
00285 if( nfar >= 1 ){
00286 float zoff = far[0] ;
00287
00288 if( ses == NULL ){
00289 sprintf(buf,"ZFIRST %g\n",zoff) ; strcat(info,buf) ;
00290 } else {
00291 sprintf(buf,"ZFIRST %g%c\n" , zoff , ses[2] ) ; strcat(info,buf) ;
00292 }
00293 } else {
00294 fprintf(stderr,"3T_toafni: ACQ_slice_offset not found\n") ;
00295 }
00296 if( far != NULL ) free(far) ;
00297
00298
00299
00300 nfar = RT_number_array( "ACQ_obj_order" , buf3T , &far ) ;
00301 if( nfar >= 2 ){
00302 int b0=far[0] , b1=far[1] ;
00303
00304 if( b1-b0 == 1 ) sprintf(buf,"ZORDER seq\n") ;
00305 else sprintf(buf,"ZORDER alt\n") ;
00306
00307 strcat(info,buf) ;
00308 } else if( nfar == 1 ){
00309 strcat(info,"ZORDER alt\n") ;
00310 } else {
00311 fprintf(stderr,"3T_toafni: ACQ_obj_order not found\n") ;
00312 }
00313 if( far != NULL ) free(far) ;
00314
00315 return 0 ;
00316 }