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  

3T_toafni.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 <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 /*** the command that will output the info from ParaVision ***/
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 /*** miscellaneous constants ***/
00024 
00025 #define INFO_SIZE     (16*1024)       /* bytes */
00026 #define SHORT_DELAY      1            /* msec */
00027 #define LONG_DELAY      10
00028 
00029 #define DEBUG
00030 
00031 /*** global variables and prototypes ***/
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   Gets the information about the current imaging sequence from the MCW
00040   Bruker 3T/60 scanner, formats it for AFNI, and sends it to AFNI.
00041   Usage:
00042    3T_toafni [-dummy]
00043   The output is written to stdout (AFNI will pipe it into itself).  If the
00044   -dummy option is used, then the data from the scanner will be read from
00045   stdin instead of from the scanner console computer.  Note that this program
00046   exits with _exit(), since it is likely to be forked from AFNI.
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    /** loop over command line arguments **/
00065 
00066    while( iarg < argc ){
00067 
00068       /** -dummy **/
00069 
00070       if( strncmp(argv[iarg],"-dummy",4) == 0 ){
00071          dummy = 1 ;
00072          iarg++ ; continue ;
00073       }
00074 
00075       /** unknown argument **/
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    /** send message to 3T to get ParaVision control information **/
00094 
00095    if( !dummy ){
00096       fp = popen( PIPE_COMMAND , "r" ) ;  /* open pipe to 3T */
00097       if( fp == NULL ){
00098          fprintf(stderr,"3T_toafni: can't open pipe to 3T60!\n") ; _exit(1) ;
00099       }
00100    } else {
00101       fp = stdin ;  /* dummy input from stdin */
00102    }
00103 
00104    /** read control information from pipe until all used up **/
00105 
00106    while( fgets(buf+nbuf,INFO_SIZE-nbuf,fp) != NULL ){
00107       nbuf = strlen(buf) ;
00108    }
00109    if( !dummy ) pclose(fp) ;  /* close pipe, if it was opened */
00110 
00111    /** convert ParaVision control data into AFNI control data **/
00112 
00113    RT_3T_to_AFNI( nbuf,buf , info ) ;
00114 
00115    /** send data to the parent **/
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++ ;  /* skip leading array brace */
00154 
00155    /* loop until end of line, end of string, or conversion fails */
00156 
00157    do{
00158       val = strtod( qq , &eptr ) ;
00159       if( val == 0.0 && eptr == qq ) break ;  /* stop when no conversion */
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 /** get AFNI orientation codes from matrix elements **/
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 /** get an integer **/
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 /** get a float **/
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' ;  /* initialize output info to be empty */
00216 
00217    /* read scalar values and format them for AFNI */
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    /* read slice orientation matrix and compute AFNI orientation codes */
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] ,  /* frequency encode */
00246             pex=far[3],pey=far[4],pez=far[5] ,  /* phase encode */
00247             sex=far[6],sey=far[7],sez=far[8]  ; /* slice encode */
00248 
00249 #if 1
00250       fes = XYZ_TO_ANAT(-fex,-fey,-fez) ; /* mirror imaging */
00251       pes = XYZ_TO_ANAT(-pex,-pey,-pez) ; /* mirror imaging */
00252 #else
00253       fes = XYZ_TO_ANAT( fex, fey, fez) ; /* no mirror imaging */
00254       pes = XYZ_TO_ANAT( pex, pey, pez) ; /* no mirror imaging */
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    /* read FOV */
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    /* read slice offsets */
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    /* read slice order */
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 }
 

Powered by Plone

This site conforms to the following standards: