00001 
00002 
00003 
00004 
00005 
00006    
00007 #undef MAIN
00008 
00009 #include "afni.h"
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 void AFNI_register_fimfunc( char *menu_name , int nbrik ,
00076                             generic_func *user_func , void *user_data )
00077 {
00078    MCW_function_list *rlist = &(GLOBAL_library.registered_fim) ;
00079    int num = rlist->num ;
00080 
00081 ENTRY("AFNI_register_fimfunc") ;
00082 
00083    if( menu_name == NULL || menu_name[0] == '\0' ||
00084        nbrik <= 0        || user_func == NULL      ) EXRETURN ; 
00085 
00086    if( num == sizeof(int) ) EXRETURN ;  
00087 
00088    if( num == 0 ){
00089      rlist->flags=NULL; rlist->labels=NULL; rlist->funcs=NULL;
00090      rlist->func_data=NULL; rlist->func_code=NULL; rlist->func_init=NULL;
00091    }
00092 
00093    rlist->flags = (int *) XtRealloc( (char *)rlist->flags, sizeof(int)*(num+1) ) ;
00094 
00095    rlist->labels = (char **) XtRealloc( (char *)rlist->labels ,
00096                                         sizeof(char *)*(num+1) ) ;
00097 
00098    rlist->funcs = (generic_func **) XtRealloc( (char *)rlist->funcs ,
00099                                                sizeof(generic_func *)*(num+1) ) ;
00100 
00101    rlist->func_data = (void **) XtRealloc( (char *)rlist->func_data ,
00102                                            sizeof(void *)*(num+1) ) ;
00103 
00104    rlist->func_code = (int *) XtRealloc( (char *)rlist->func_code, sizeof(int)*(num+1) ) ;
00105 
00106    rlist->func_init = (generic_func **) XtRealloc( (char *)rlist->func_init ,
00107                                                    sizeof(generic_func *)*(num+1) ) ;
00108 
00109    rlist->flags[num]     = nbrik ;
00110    rlist->labels[num]    = XtNewString(menu_name) ;
00111    rlist->funcs[num]     = user_func ;
00112    rlist->func_data[num] = user_data ;
00113    rlist->func_code[num] = FUNC_FIM  ;
00114    rlist->func_init[num] = NULL ;
00115 
00116    rlist->num = num+1 ;
00117    EXRETURN ;
00118 }
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 static void rank_order_float( int n , float *a )
00130 {
00131    register int ii , ns , n1 , ib ;
00132    static int    nb = 0 ;
00133    static int   *b  = NULL ;  
00134    static float *c  = NULL ;
00135    float cs ;
00136 
00137    
00138 
00139    if( a == NULL ){
00140       if( b != NULL ){ free(b); free(c); b=NULL ; c=NULL; nb=0; }  
00141       return ;
00142    }
00143 
00144    if( n < 1 ) return ;                     
00145    if( n == 1 ){ a[0] = 0.0 ; return ; }    
00146 
00147    
00148 
00149    if( nb < n ){
00150       if( b != NULL ){ free(b); free(c); }
00151       b  = (int   *) malloc(sizeof(int  )*n) ;
00152       c  = (float *) malloc(sizeof(float)*n) ;
00153       nb = n ;
00154    }
00155 
00156    for( ii=0 ; ii < n ; ii++ ) c[ii] = b[ii] = ii ;
00157 
00158    
00159 
00160    qsort_floatint( n , a , b ) ;  
00161 
00162    
00163 
00164    n1 = n-1 ;
00165    for( ii=0 ; ii < n1 ; ii++ ){
00166       if( a[ii] == a[ii+1] ){                  
00167          cs = 2*ii+1 ; ns = 2 ; ib=ii ; ii++ ;
00168          while( ii < n1 && a[ii] == a[ii+1] ){ ii++ ; ns++ ; cs += ii ; }
00169          for( cs/=ns ; ib <= ii ; ib++ ) c[ib] = cs ;
00170       }
00171    }
00172 
00173    for( ii=0 ; ii < n ; ii++ ) a[b[ii]] = c[ii] ;
00174 
00175    return ;
00176 }
00177 
00178 
00179 
00180 
00181 
00182 static float spearman_rank_prepare( int n , float *a )
00183 {
00184    register int ii ;
00185    register float rb , rs ;
00186 
00187    rank_order_float( n , a ) ;
00188 
00189    rb = 0.5*(n-1) ; rs=0.0 ;
00190    for( ii=0 ; ii < n ; ii++ ){
00191       a[ii] -= rb ;
00192       rs    += a[ii]*a[ii] ;
00193    }
00194 
00195    return rs ;
00196 }
00197 
00198 static float quadrant_corr_prepare( int n , float *a )
00199 {
00200    register int ii ;
00201    register float rb , rs ;
00202 
00203    rank_order_float( n , a ) ;
00204 
00205    rb = 0.5*(n-1) ; rs=0.0 ;
00206    for( ii=0 ; ii < n ; ii++ ){
00207       a[ii] = (a[ii] > rb) ? 1.0
00208                            : (a[ii] < rb) ? -1.0 : 0.0 ;
00209       rs    += a[ii]*a[ii] ;
00210    }
00211 
00212    return rs ;
00213 }
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 static float spearman_rank_corr( int n , float *x , float rv , float *r )
00224 {
00225    register int ii ;
00226    register float ss ; float xv ;
00227 
00228    xv = spearman_rank_prepare( n , x ) ; if( xv <= 0.0 ) return 0.0 ;
00229 
00230    for( ii=0,ss=0.0 ; ii < n ; ii++ ) ss += x[ii] * r[ii] ;
00231 
00232    return ( ss/sqrt(rv*xv) ) ;
00233 }
00234 
00235 static float spearman_rank_manycorr( int n , float *x ,
00236                                      int nr, float *rv, float **r )
00237 {
00238    register int ii ;
00239    register float ss ;
00240    int jj ;
00241    float bb , xv ;
00242 
00243    if( nr == 1 ) return spearman_rank_corr( n,x,rv[0],r[0] ) ;
00244 
00245    xv = spearman_rank_prepare( n , x ) ; if( xv <= 0.0 ) return 0.0 ;
00246 
00247    for( jj=0,bb=0.0 ; jj < nr ; jj++ ){
00248       for( ii=0,ss=0.0 ; ii < n ; ii++ ) ss += x[ii] * r[jj][ii] ;
00249       ss /= sqrt(rv[jj]*xv) ;
00250       if( fabs(ss) > fabs(bb) ) bb = ss ;
00251    }
00252 
00253    return bb ;
00254 }
00255 
00256 static float quadrant_corr( int n , float *x , float rv , float *r )
00257 {
00258    register int ii ;
00259    register float ss ; float xv ;
00260 
00261    xv = quadrant_corr_prepare( n , x ) ; if( xv <= 0.0 ) return 0.0 ;
00262 
00263    for( ii=0,ss=0.0 ; ii < n ; ii++ ) ss += x[ii] * r[ii] ;
00264 
00265    return ( ss/sqrt(rv*xv) ) ;
00266 }
00267 
00268 static float quadrant_manycorr( int n , float *x ,
00269                                 int nr, float *rv, float **r )
00270 {
00271    register int ii ;
00272    register float ss ;
00273    int jj ;
00274    float bb , xv ;
00275 
00276    if( nr == 1 ) return quadrant_corr( n,x,rv[0],r[0] ) ;
00277 
00278    xv = quadrant_corr_prepare( n , x ) ; if( xv <= 0.0 ) return 0.0 ;
00279 
00280    for( jj=0,bb=0.0 ; jj < nr ; jj++ ){
00281       for( ii=0,ss=0.0 ; ii < n ; ii++ ) ss += x[ii] * r[jj][ii] ;
00282       ss /= sqrt(rv[jj]*xv) ;
00283       if( fabs(ss) > fabs(bb) ) bb = ss ;
00284    }
00285 
00286    return bb ;
00287 }
00288 
00289 
00290 
00291 
00292 
00293 void spearman_fimfunc( int n, float *ts, void *ud, int nb, void *val )
00294 {
00295    static float *tsc=NULL , *refc=NULL , *refv=NULL , **rr ;
00296    static int   *keep=NULL ;
00297    static int    ntsc , nref , nkeep , polort,ignore , ncall;
00298 
00299    int ii , kk ;
00300    float *v ;
00301 
00302    
00303 
00304    if( ts == NULL ){
00305 
00306       
00307 
00308       if( n > 0 ){
00309 
00310          FIMdata *fd = (FIMdata *) val ;
00311 
00312          polort = fd->polort ;  
00313          ignore = fd->ignore ;
00314          ncall  = 0 ;           
00315 
00316          
00317 
00318          ntsc = n ;
00319          if( tsc != NULL ) free(tsc) ;
00320          tsc = (float *) malloc(sizeof(float)*ntsc) ;
00321 
00322          
00323 
00324          nref = fd->ref_ts->ny ;
00325          if( refc != NULL ) free(refc) ;
00326          if( refv != NULL ) free(refv) ;
00327          if( keep != NULL ) free(keep) ;
00328          if( rr   != NULL ) free(rr) ;
00329          refc = (float *) malloc(sizeof(float)*ntsc*nref) ;  
00330          refv = (float *) malloc(sizeof(float)*nref) ;      
00331          keep = (int *)   malloc(sizeof(int)*ntsc) ;       
00332          rr   = (float **)malloc(sizeof(float *)*nref) ;  
00333 
00334          for( kk=0 ; kk < nref ; kk++ ){
00335             rr[kk] = refc+kk*ntsc ;                       
00336             memcpy( rr[kk] ,                              
00337                     MRI_FLOAT_PTR(fd->ref_ts) + kk*fd->ref_ts->nx ,
00338                     sizeof(float)*ntsc  ) ;
00339          }
00340 
00341          
00342 
00343          for( nkeep=0,ii=ignore ; ii < ntsc ; ii++ ){ 
00344             for( kk=0 ; kk < nref ; kk++ )            
00345                if( rr[kk][ii] >= WAY_BIG ) break ;
00346 
00347             if( kk == nref ) keep[nkeep++] = ii ;     
00348          }
00349 
00350          
00351 
00352          if( nkeep < ntsc ){
00353             for( ii=0 ; ii < nkeep ; ii++ ){
00354                for( kk=0 ; kk < nref ; kk++ )
00355                   rr[kk][ii] = rr[kk][keep[ii]] ;  
00356             }
00357          }
00358 
00359          
00360 
00361          for( kk=0 ; kk < nref ; kk++ )
00362             refv[kk] = spearman_rank_prepare( nkeep , rr[kk] ) ;
00363 
00364 #if 0
00365 fprintf(stderr,"spearman_fimfunc: initialize ntsc=%d nkeep=%d nref=%d\n",
00366         ntsc,nkeep,nref);
00367 #endif
00368 
00369          return ;
00370 
00371       
00372 
00373       } else {
00374          THD_3dim_dataset *dset = (THD_3dim_dataset *) val ;
00375          int kb = -n ;
00376 
00377          free(tsc)  ; tsc  = NULL ;  
00378          free(refc) ; refc = NULL ;
00379          free(refv) ; refv = NULL ;
00380          free(keep) ; keep = NULL ;
00381          free(rr)   ; rr   = NULL ;
00382          rank_order_float(0,NULL) ;
00383 
00384          
00385 
00386          EDIT_BRICK_TO_FICO( dset , kb , nkeep , (nref==1)?1:2 , 1 ) ;
00387          EDIT_BRICK_LABEL( dset , kb , "Spearman CC" ) ;
00388 
00389 #if 0
00390 fprintf(stderr,"spearman_fimfunc: finalize with kb=%d\n",kb);
00391 #endif
00392 
00393          return ;
00394       }
00395    }
00396 
00397    
00398 
00399    ncall++ ;
00400 #if 0
00401 if(ncall%1000==0) fprintf(stderr,"spearman_fimfunc: ncall=%d\n",ncall);
00402 #endif
00403 
00404    
00405 
00406    if( nkeep < ntsc )
00407       for( ii=0 ; ii < nkeep ; ii++ ) tsc[ii] = ts[keep[ii]]; 
00408    else
00409       memcpy(tsc,ts,sizeof(float)*ntsc) ;                     
00410 
00411    
00412 
00413    v    = (float *) val ;
00414    v[0] = spearman_rank_manycorr( nkeep , tsc , nref , refv , rr ) ;
00415 
00416    return ;
00417 }
00418 
00419 
00420 
00421 
00422 
00423 void quadrant_fimfunc( int n, float *ts, void *ud, int nb, void *val )
00424 {
00425    static float *tsc=NULL , *refc=NULL , *refv=NULL , **rr ;
00426    static int   *keep=NULL ;
00427    static int    ntsc , nref , nkeep , polort,ignore , ncall;
00428 
00429    int ii , kk ;
00430    float *v ;
00431 
00432    
00433 
00434    if( ts == NULL ){
00435 
00436       
00437 
00438       if( n > 0 ){
00439 
00440          FIMdata *fd = (FIMdata *) val ;
00441 
00442          polort = fd->polort ;  
00443          ignore = fd->ignore ;
00444          ncall  = 0 ;           
00445 
00446          
00447 
00448          ntsc = n ;
00449          if( tsc != NULL ) free(tsc) ;
00450          tsc = (float *) malloc(sizeof(float)*ntsc) ;
00451 
00452          
00453 
00454          nref = fd->ref_ts->ny ;
00455          if( refc != NULL ) free(refc) ;
00456          if( refv != NULL ) free(refv) ;
00457          if( keep != NULL ) free(keep) ;
00458          if( rr   != NULL ) free(rr) ;
00459          refc = (float *) malloc(sizeof(float)*ntsc*nref) ;  
00460          refv = (float *) malloc(sizeof(float)*nref) ;      
00461          keep = (int *)   malloc(sizeof(int)*ntsc) ;       
00462          rr   = (float **)malloc(sizeof(float *)*nref) ;  
00463 
00464          for( kk=0 ; kk < nref ; kk++ ){
00465             rr[kk] = refc+kk*ntsc ;                       
00466             memcpy( rr[kk] ,                              
00467                     MRI_FLOAT_PTR(fd->ref_ts) + kk*fd->ref_ts->nx ,
00468                     sizeof(float)*ntsc  ) ;
00469          }
00470 
00471          
00472 
00473          for( nkeep=0,ii=ignore ; ii < ntsc ; ii++ ){ 
00474             for( kk=0 ; kk < nref ; kk++ )            
00475                if( rr[kk][ii] >= WAY_BIG ) break ;
00476 
00477             if( kk == nref ) keep[nkeep++] = ii ;     
00478          }
00479 
00480          
00481 
00482          if( nkeep < ntsc ){
00483             for( ii=0 ; ii < nkeep ; ii++ ){
00484                for( kk=0 ; kk < nref ; kk++ )
00485                   rr[kk][ii] = rr[kk][keep[ii]] ;  
00486             }
00487          }
00488 
00489          
00490 
00491          for( kk=0 ; kk < nref ; kk++ )
00492             refv[kk] = quadrant_corr_prepare( nkeep , rr[kk] ) ;
00493 
00494 #if 0
00495 fprintf(stderr,"quadrant_fimfunc: initialize ntsc=%d nkeep=%d nref=%d\n",
00496         ntsc,nkeep,nref);
00497 #endif
00498 
00499          return ;
00500 
00501       
00502 
00503       } else {
00504          THD_3dim_dataset *dset = (THD_3dim_dataset *) val ;
00505          int kb = -n ;
00506 
00507          free(tsc)  ; tsc  = NULL ;  
00508          free(refc) ; refc = NULL ;
00509          free(refv) ; refv = NULL ;
00510          free(keep) ; keep = NULL ;
00511          free(rr)   ; rr   = NULL ;
00512          rank_order_float(0,NULL) ;
00513 
00514          
00515 
00516          EDIT_BRICK_TO_FICO( dset , kb , nkeep , (nref==1)?1:2 , 1 ) ;
00517          EDIT_BRICK_LABEL( dset , kb , "Quadrant CC" ) ;
00518 
00519 #if 0
00520 fprintf(stderr,"quadrant_fimfunc: finalize with kb=%d\n",kb);
00521 #endif
00522 
00523          return ;
00524       }
00525    }
00526 
00527    
00528 
00529    ncall++ ;
00530 #if 0
00531 if(ncall%1000==0) fprintf(stderr,"quadrant_fimfunc: ncall=%d\n",ncall);
00532 #endif
00533 
00534    
00535 
00536    if( nkeep < ntsc )
00537       for( ii=0 ; ii < nkeep ; ii++ ) tsc[ii] = ts[keep[ii]]; 
00538    else
00539       memcpy(tsc,ts,sizeof(float)*ntsc) ;                     
00540 
00541    
00542 
00543    v    = (float *) val ;
00544    v[0] = quadrant_manycorr( nkeep , tsc , nref , refv , rr ) ;
00545 
00546    return ;
00547 }