00001 
00002 
00003 
00004 
00005 
00006 
00007 #include "def_epi.h"
00008 #include "jp_afni.h"
00009 
00010 EXT struct im_info imX[] ;  
00011 
00012 #if defined(AFNI_SIGNA_KECK)
00013    extern int   AJxres, AJreps, AJovs, AJtopovs, AJyres, epramp, opentry, oppos;
00014    extern int   opspf, opplane, opobplane, AJopte, opte2, opti, optr, opslquant;
00015    extern float opfov, opslthick, opslspace, opnex, filt_band, sl_pos[];
00016    extern int   Signa_info ;
00017 #endif
00018 
00019 static char AFNI_infobuf[1024] = "\0" ;  
00020 
00021 
00022 
00023 #define USE_FORK    
00024 
00025 #include <unistd.h>
00026 #include <sys/types.h>
00027 #include <signal.h>
00028 #include <sys/wait.h>
00029 static int   use_fork = 0 ;
00030 static pid_t pid_fork = 0 ;
00031 
00032 
00033 
00034 #include <signal.h>
00035 
00036 static void AFNI_sigfunc(int sig)  
00037 {
00038    char * sname ;
00039    switch(sig){
00040       default:      sname = "unknown" ; break ;
00041       case SIGINT:  sname = "SIGINT"  ; break ;
00042       case SIGPIPE: sname = "SIGPIPE" ; break ;
00043       case SIGSEGV: sname = "SIGSEGV" ; break ;
00044       case SIGBUS:  sname = "SIGBUS"  ; break ;
00045       case SIGTERM: sname = "SIGTERM" ; break ;
00046    }
00047    fprintf(stderr,"\nFatal Signal %d (%s) received\n",sig,sname) ;
00048    fprintf(stderr,"*** Program Abort ***\n") ; fflush(stderr) ;
00049    exit(1) ;
00050 }
00051 
00052 
00053 
00054 void AFNI_exit(void)                   
00055 {                                      
00056    iochan_close(AFNI_ioc) ;
00057 
00058 #ifdef USE_FORK
00059    if( use_fork && pid_fork != 0 && pid_fork != (pid_t)(-1) ){
00060       int kk = kill( pid_fork , SIGTERM ) ;
00061       if( kk == 0 ){
00062          pid_t qpid=0 ;
00063          for( kk=0 ; kk < 10 && qpid == 0 ; kk++ ){
00064             iochan_sleep(5) ;
00065             qpid = waitpid( pid_fork , NULL , WNOHANG ) ;
00066          }
00067       }
00068    }
00069 #endif
00070 
00071    return ;
00072 }
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 void AFNI_start_io( int nim )
00096 {
00097    int ii ;
00098 
00099    
00100 
00101    if( AFNI_mode <= 0 || AFNI_mode == AFNI_CONTINUE_MODE ) return ;
00102 
00103    
00104 
00105 
00106    if( AFNI_mode == AFNI_OPEN_CONTROL_MODE ){
00107 
00108       sprintf( AFNI_iochan , "tcp:%s:%d" , AFNI_host , AFNI_CONTROL_PORT ) ;
00109 
00110       if( AFNI_verbose )
00111          fprintf(stderr,"Opening control channel %s to AFNI.\n",AFNI_iochan) ;
00112 
00113       AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ;
00114 
00115       if( AFNI_ioc == NULL ){
00116          fprintf(stderr,"Can't open control channel %s to AFNI!\a\n",AFNI_iochan) ;
00117          AFNI_mode = 0 ; return ;
00118       } else {
00119          if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_WAIT_CONTROL_MODE.\n") ;
00120          AFNI_mode = AFNI_WAIT_CONTROL_MODE ;  
00121       }
00122 
00123       signal( SIGTERM , AFNI_sigfunc ) ; 
00124       signal( SIGSEGV , AFNI_sigfunc ) ;
00125       signal( SIGINT  , AFNI_sigfunc ) ;
00126    }
00127 
00128    
00129 
00130    if( AFNI_mode == AFNI_WAIT_CONTROL_MODE ){
00131 
00132       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  
00133 
00134 
00135 
00136 
00137       if( ii < 0 ){
00138          fprintf(stderr,"Control channel to AFNI failed!\a\n") ;
00139          IOCHAN_CLOSE(AFNI_ioc) ;
00140          AFNI_mode = 0 ; return ;
00141       } else if( ii > 0 ){
00142          if( AFNI_verbose ) fprintf(stderr,"Control channel connected to AFNI."
00143                                            "  Entering AFNI_OPEN_DATA_MODE.\n") ;
00144          AFNI_mode = AFNI_OPEN_DATA_MODE ;  
00145       }
00146    }
00147 
00148    
00149 
00150 
00151 
00152    if( AFNI_mode == AFNI_OPEN_DATA_MODE ){
00153 
00154 
00155 
00156       if( AFNI_use_tcp ) sprintf(AFNI_iochan,"tcp:%s:%d",AFNI_host,AFNI_TCP_PORT) ;
00157       else               strcpy(AFNI_iochan,"shm:eps:8M") ;
00158 
00159       strcpy(AFNI_buf,AFNI_iochan) ;     
00160       if( AFNI_infocom[0] != '\0' ){
00161          strcat(AFNI_buf,"\n") ;
00162          strcat(AFNI_buf,AFNI_infocom) ; 
00163       }
00164 
00165       if( AFNI_verbose )
00166          fprintf(stderr,"Sending control information to AFNI:\n%s\n",AFNI_buf) ;
00167 
00168       ii = iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
00169 
00170 
00171 
00172       if( ii < 0 ){
00173          fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
00174          IOCHAN_CLOSE(AFNI_ioc) ;
00175          AFNI_mode = 0 ; return ;
00176       } else {
00177          while( ! iochan_clearcheck(AFNI_ioc,2) ) 
00178             iochan_sleep(2) ;
00179          IOCHAN_CLOSE(AFNI_ioc) ;                 
00180 
00181          if( AFNI_verbose )
00182             fprintf(stderr,"Opening data channel %s to AFNI.\n",AFNI_iochan) ;
00183 
00184 #ifdef USE_FORK
00185          use_fork = AFNI_use_tcp ;
00186 #endif
00187 
00188          if( use_fork ){  
00189 
00190             AFNI_ioc = iochan_init( "shm:forkage:8M" , "create" ) ;
00191             if( AFNI_ioc == NULL ){
00192                fprintf(stderr,"Can't open shm:forkage:8M for relay to AFNI!\n");
00193                use_fork = 0 ; AFNI_mode = 0 ; return ;
00194             }
00195             pid_fork = iochan_fork_relay( "shm:forkage:8M" , AFNI_iochan ) ;
00196             if( pid_fork == (pid_t)(-1) || pid_fork == 0 ){
00197                fprintf(stderr,"Can't fork for relay to AFNI!\n") ;
00198                IOCHAN_CLOSE(AFNI_ioc) ; pid_fork = 0 ; use_fork = 0 ;
00199                AFNI_mode = 0 ; return ;
00200             }
00201 
00202          } else {  
00203 
00204             AFNI_ioc = iochan_init( AFNI_iochan , "w" ) ; 
00205             if( AFNI_ioc == NULL ){
00206                fprintf(stderr,"Can't open data channel %s to AFNI!\a\n",AFNI_iochan) ;
00207                AFNI_mode = 0 ; return ;
00208             }
00209          }
00210 
00211          if( AFNI_verbose ) fprintf(stderr,"Entering AFNI_CATCHUP_MODE.\n") ;
00212          AFNI_mode = AFNI_CATCHUP_MODE ;
00213       }
00214    }
00215 
00216    
00217 
00218 
00219    if( AFNI_mode == AFNI_CATCHUP_MODE ){
00220 
00221       ii = iochan_writecheck( AFNI_ioc , 1 ) ;  
00222       if( ii < 0 ){
00223          fprintf(stderr,"AFNI data channel aborted before any data was sent!\a\n") ;
00224          IOCHAN_CLOSE( AFNI_ioc ) ;
00225          use_fork = 0 ; AFNI_mode = 0 ; return ;
00226       } else if( ii > 0 ){                      
00227          if( AFNI_verbose )
00228             fprintf(stderr,"AFNI data channel %s is connected.\n",AFNI_iochan) ;
00229 
00230          
00231 
00232 #if defined(AFNI_BRUKER_BRI)
00233 
00234          
00235 
00236 
00237          if( AFNI_verbose )
00238             fprintf(stderr,"Entering AFNI_CONTINUE_MODE.\n") ;
00239          AFNI_mode = AFNI_CONTINUE_MODE ;
00240 
00241 #elif defined(AFNI_SIGNA_KECK)
00242 
00243          
00244 
00245          if( !Signa_info ){
00246             double tt = COX_clock_time() ;
00247 
00248             fprintf(stderr,
00249                     "\n\a"
00250                     "*** WARNING: Reading Signa info for AFNI ('load')\n");
00251 
00252             read_Signa_cvs() ;
00253 
00254             if( !Signa_info ){  
00255                fprintf(stderr,
00256                        "\n\a"
00257                        "*** ERROR:   Signa info is not 'load'-ed!\n"
00258                        "***          Closing connection to AFNI.\n") ;
00259 
00260                IOCHAN_CLOSE( AFNI_ioc ) ;
00261                use_fork = 0 ; AFNI_mode = 0 ; return ;
00262             }
00263 
00264             tt = COX_clock_time() - tt ;
00265             fprintf(stderr,
00266                     "***          Signa info transferred in %.1f s\n",tt) ;
00267          }
00268 
00269          
00270 
00271          
00272 
00273          ii = strlen(AFNI_infobuf) ;
00274          sprintf( AFNI_infobuf+ii , "ZORDER alt\n"
00275                                     "ACQUISITION_TYPE 2D+zt\n" ) ;
00276 
00277          
00278 
00279          ii = strlen(AFNI_infobuf) ;
00280          sprintf( AFNI_infobuf+ii , "XYFOV %.2f 0 0\n" , opfov ) ;
00281 
00282          
00283 
00284          ii = strlen(AFNI_infobuf) ;
00285          sprintf( AFNI_infobuf+ii , "ZNUM %d\n" , opslquant ) ;
00286 
00287          
00288 
00289          ii = strlen(AFNI_infobuf) ;
00290          sprintf( AFNI_infobuf+ii , "ZDELTA %.2f\n" , opslthick+opslspace ) ;
00291 
00292          
00293 
00294          { static char *zzz[3]={"S","R","A"} ;  
00295            char *axx , *ayy , *azz ;            
00296            int jj = opplane ;                   
00297 
00298            if( jj < 1 || jj > 3 ){
00299               static char * pn[3] = { "Axial" , "Sagittal" , "Coronal" } ;
00300               jj = opobplane ; if( jj < 1 || jj > 3 ) jj = 1 ;
00301               fprintf(stderr,
00302                       "\n\a"
00303                       "*** WARNING: oblique slices; AFNI orientation=%s\n",pn[jj-1]) ;
00304            }
00305 
00306            
00307 
00308            axx = ayy = azz = "???" ;  
00309            switch( jj ){
00310              case 1:                                              
00311                if( opspf == 0 ){ axx = "A-P" ; ayy = "R-L" ; }
00312                else            { axx = "L-R" ; ayy = "A-P" ; }
00313 
00314                if( sl_pos[0] < sl_pos[1] ) azz = "I-S" ;
00315                else                        azz = "S-I" ;
00316              break ;
00317 
00318              case 2:                                              
00319                if( opspf == 0 ){ axx = "S-I" ; ayy = "A-P" ; }
00320                else            { axx = "P-A" ; ayy = "S-I" ; }
00321 
00322                if( sl_pos[0] < sl_pos[1] ) azz = "L-R" ;
00323                else                        azz = "R-L" ;
00324              break ;
00325 
00326              case 3:                                              
00327                if( opspf == 0 ){ axx = "I-S" ; ayy = "R-L" ; }
00328                else            { axx = "R-L" ; ayy = "S-I" ; }
00329 
00330                if( sl_pos[0] < sl_pos[1] ) azz = "P-A" ;
00331                else                        azz = "A-P" ;
00332              break ;
00333            }
00334 
00335            ii = strlen(AFNI_infobuf) ;
00336            sprintf( AFNI_infobuf+ii , "XYZAXES %s %s %s\n" , axx,ayy,azz ) ;
00337 
00338 fprintf(stderr,"AFNI Signa info: plane=%d spf=%d\n" ,jj,opspf) ;      
00339 fprintf(stderr,"              => XYZAXES %s %s %s\n",axx,ayy,azz) ;
00340 fprintf(stderr,"              => ZFIRST %.2f%s\n"   ,sl_pos[0],zzz[jj-1] ) ;
00341 
00342            ii = strlen(AFNI_infobuf) ;
00343            sprintf( AFNI_infobuf+ii , "ZFIRST %.2f%s\n" , sl_pos[0],zzz[jj-1] ) ;
00344          }
00345 
00346          
00347 
00348          ii = strlen(AFNI_infobuf) ;
00349          sprintf( AFNI_infobuf+ii , "TR %.3f\n" , 1.e-6*optr ) ;
00350 
00351          
00352 
00353          if( AFNI_verbose )
00354             fprintf(stderr,"Entering AFNI_CONTINUE_MODE.\n") ;
00355          AFNI_mode = AFNI_CONTINUE_MODE ;
00356 
00357 #endif   
00358 
00359          
00360 
00361          if( AFNI_mode == AFNI_CONTINUE_MODE ){
00362             if( nim > 0 && AFNI_verbose )
00363                fprintf(stderr,"Playing AFNI catchup with %d images.\n",nim) ;
00364 
00365             for( ii=0 ; ii < nim ; ii++ ) AFNI_send_image( ii ) ;
00366          }
00367       }
00368    }
00369 
00370    return ;
00371 }
00372 
00373 
00374 
00375 
00376 
00377 void AFNI_send_image( int nim )
00378 {
00379    int lx = imX[nim].x , ly = imX[nim].y , nbytes = 2*lx*ly , soff , jj ;
00380 
00381    if( AFNI_mode != AFNI_CONTINUE_MODE ) return ;
00382 
00383    if ( (lx*ly) == 65536 ) soff = OFFSET;  
00384    else                    soff = 0;
00385 
00386 
00387 
00388    if( nim == 0 ){
00389 
00390       if( AFNI_verbose ) fprintf(stderr,"Sending 1st info+image to AFNI.\n") ;
00391 
00392       if( AFNI_infobuf[0] == '\0' )
00393          sprintf( AFNI_buf , "DATUM short\nXYMATRIX %d %d\n" , lx,ly ) ;
00394       else
00395          sprintf( AFNI_buf , "%s\nDATUM short\nXYMATRIX %d %d\n" ,
00396                              AFNI_infobuf , lx,ly ) ;
00397 
00398       iochan_sendall( AFNI_ioc , AFNI_buf , strlen(AFNI_buf)+1 ) ;
00399 
00400    } else if( AFNI_verbose ){
00401 
00402       fprintf(stderr,"Sending image %d to AFNI.\n",nim+1) ;
00403 
00404    }
00405 
00406    jj = iochan_writecheck( AFNI_ioc , 1 ) ;
00407    if( jj <= 0 ){
00408       fprintf(stderr,"Image transmission to AFNI impossible at #%d.\a\n",nim) ;
00409       if( AFNI_ioc->type == SHM_IOCHAN )
00410          fprintf(stderr," shm: bstart=%d  bend=%d\n",
00411                 *(AFNI_ioc->bstart),*(AFNI_ioc->bend) ) ;
00412       iochan_sleep(1) ;
00413       IOCHAN_CLOSE(AFNI_ioc) ;
00414       use_fork = 0 ; AFNI_mode = 0 ;
00415       fprintf(stderr,"Closed connection to AFNI\n") ;
00416       return ;
00417    }
00418    if( AFNI_ioc->type == SHM_IOCHAN && jj < nbytes ){
00419       fprintf(stderr,"Image transmission to AFNI incomplete at #%d.\a\n",nim) ;
00420       if( AFNI_ioc->type == SHM_IOCHAN )
00421          fprintf(stderr," shm: bstart=%d  bend=%d\n",
00422                 *(AFNI_ioc->bstart),*(AFNI_ioc->bend) ) ;
00423       iochan_sleep(1) ;
00424       IOCHAN_CLOSE(AFNI_ioc) ;
00425       use_fork = 0 ; AFNI_mode = 0 ;
00426       fprintf(stderr,"Closed connection to AFNI\n") ;
00427       return ;
00428    }
00429 
00430    jj = iochan_sendall( AFNI_ioc , imX[nim].arr + soff , nbytes ) ;
00431 
00432 
00433 
00434    if( jj < 0 ){
00435       fprintf(stderr,"Image transmission to AFNI fails at #%d.\a\n",nim) ;
00436       if( AFNI_ioc->type == SHM_IOCHAN )
00437          fprintf(stderr," shm: bstart=%d  bend=%d\n",
00438                 *(AFNI_ioc->bstart),*(AFNI_ioc->bend) ) ;
00439       iochan_sleep(1) ;
00440       IOCHAN_CLOSE(AFNI_ioc) ;
00441       use_fork = 0 ; AFNI_mode = 0 ;
00442       fprintf(stderr,"Closed connection to AFNI\n") ;
00443       return ;
00444    }
00445 
00446    return ;
00447 }