00001 
00002 
00003 
00004 
00005 
00006    
00007 #include "mrilib.h"
00008 
00009 
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 static int bi7func( double a , double b , double xc , double * bi7 )
00037 {
00038 #define NL 20  
00039 
00040    static double *yy=NULL , *ww=NULL ;
00041    double xx , s00,s10,s01,s20,s11,s02 , ff , l0,l1 ;
00042    register int ii ;
00043 
00044    if( a  <= 0.0 || b  <= 0.0 ||
00045        xc <= 0.0 || xc >= 1.0 || bi7 == NULL ) return -1 ;  
00046 
00047    
00048 
00049    if( yy == NULL ) get_laguerre_table( NL , &yy , &ww ) ;
00050 
00051    s00=s10=s01=s20=s11=s02 = 0.0 ;
00052    for( ii=NL-1 ; ii >= 0 ; ii-- ){
00053       xx = xc*exp(-yy[ii]/a) ;            
00054       l0 = log(xx) ; l1 = log(1.0-xx) ;   
00055       ff = pow(1.0-xx,b-1.0) ;            
00056       s00 += ww[ii] * ff ;                
00057       s10 += ww[ii] * ff * l0 ;
00058       s20 += ww[ii] * ff * l0 * l0 ;
00059       s01 += ww[ii] * ff * l1 ;
00060       s02 += ww[ii] * ff * l1 * l1 ;
00061       s11 += ww[ii] * ff * l0 * l1 ;
00062    }
00063 
00064    if( s00 <= 0.0 ) return -1 ;
00065 
00066    bi7[0] = s00 * pow(xc,a) / a ;           
00067    bi7[1] = s10/s00 ;                       
00068    bi7[2] = s01/s00 ;                       
00069    bi7[3] = (s20*s00-s10*s10)/(s00*s00) ;   
00070    bi7[4] = (s11*s00-s10*s01)/(s00*s00) ;   
00071    bi7[5] = bi7[4] ;                        
00072    bi7[6] = (s02*s00-s01*s01)/(s00*s00) ;   
00073 
00074    return 0 ;
00075 }
00076 
00077 
00078 
00079 
00080 
00081 #define LL   0.2
00082 #define UL   10000.0
00083 
00084 static double AL   = 0.21 ;
00085 static double AU   = 9.9 ;
00086 static double BL   = 5.9 ;
00087 static double BU   = 999.9 ;
00088 static int    NRAN = 6666 ;
00089 
00090 static void betarange( double al,double au , double bl , double bu , int nran )
00091 {
00092    if( al > 0.0 ) AL = al ;
00093    if( au > AL  ) AU = au ;
00094    if( bl > 0.0 ) BL = bl ;
00095    if( bu > BL  ) BU = bu ;
00096    if( nran > 1 ) NRAN = nran ;
00097 }
00098 
00099 static double ainit=0.0 ;
00100 static double binit=0.0 ;
00101 
00102 static void beta_init( double ai , double bi )
00103 {
00104    ainit = ai ; binit = bi ; return ;
00105 }
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 static int betasolve( double e0, double e1, double xc, double * ap, double * bp )
00115 {
00116    double bi7[7] , aa,bb , da,db , m11,m12,m21,m22 , r1,r2 , dd,ee ;
00117    int nite=0 , ii,jj ;
00118 
00119    if( ap == NULL || bp == NULL ||
00120        xc <= 0.0  || xc >= 1.0  || e0 >= 0.0 || e1 >= 0.0 ) return -1 ;
00121 
00122    
00123 
00124    dd = 1.e+20 ; aa = bb = 0.0 ;
00125    if( ainit > 0.0 && binit > 0.0 ){
00126       ii = bi7func( ainit , binit , xc , bi7 ) ;
00127       if( ii == 0 ){
00128          r1 = bi7[1]-e0; r2 = bi7[2]-e1; dd = fabs(r1/e0)+fabs(r2/e1);
00129          aa = ainit ; bb = binit ;
00130       }
00131    }
00132 
00133    dd = 1.e+20 ; aa = bb = 0.0 ;
00134    for( jj=0 ; jj < NRAN ; jj++ ){
00135       da = AL +(AU-AL) * drand48() ;
00136       db = BL +(BU-BL) * drand48() ;
00137       ii = bi7func( da , db , xc , bi7 ) ; if( ii ) continue ;
00138       r1 = bi7[1]-e0; r2 = bi7[2]-e1; ee = fabs(r1/e0)+fabs(r2/e1);
00139       if( ee < dd ){ aa=da ; bb=db ; dd=ee ;  }
00140    }
00141    if( aa == 0.0 || bb == 0.0 ) return -1 ;
00142 #if 0
00143    fprintf(stderr,"%2d: aa=%15.10g  bb=%15.10g  ee=%g\n",nite,aa,bb,ee) ;
00144 #endif
00145 
00146    do{
00147       ii = bi7func( aa , bb , xc , bi7 ) ;
00148       if( ii ) return -1 ;
00149       r1  = bi7[1] - e0 ;
00150       r2  = bi7[2] - e1 ; ee = fabs(r1/e0) + fabs(r2/e1) ;
00151       m11 = bi7[3] ; m12 = bi7[4] ; m21 = bi7[5] ; m22 = bi7[6] ;
00152       dd  = m11*m22 - m12*m21 ;
00153       if( dd == 0.0 ) return -1 ;
00154       da = ( m22*r1 - m12*r2 ) / dd ;
00155       db = (-m21*r1 + m11*r2 ) / dd ;
00156       nite++ ;
00157       aa -= da ; bb -=db ;
00158 #if 0
00159       if( aa < LL ) aa = LL ; else if( aa > UL ) aa = UL ;
00160       if( bb < LL ) bb = LL ; else if( bb > UL ) bb = UL ;
00161 
00162       if( aa == LL || bb == LL || aa == UL || bb == UL ) return -1 ;
00163 #else
00164       if( aa < AL ) aa = AL ; else if( aa > AU ) aa = AU ;
00165       if( bb < BL ) bb = BL ; else if( bb > BU ) bb = BU ;
00166 #endif
00167 
00168    } while( nite < 99 && fabs(da)+fabs(db) > 0.02 ) ;
00169 
00170    *ap = aa ; *bp = bb ; return 0 ;
00171 }
00172 
00173 
00174 
00175 typedef struct {
00176   int mcount , ibot ;
00177   float * bval , * cval ;
00178 } BFIT_data ;
00179 
00180 typedef struct {
00181   int mgood , itop ;
00182   float a,b,xcut,chisq,df_chisq,q_chisq,eps ;
00183 } BFIT_result ;
00184 
00185 void BFIT_free_data( BFIT_data * bfd )
00186 {
00187    if( bfd != NULL ){
00188       if( bfd->bval != NULL ) free(bfd->bval) ;
00189       if( bfd->cval != NULL ) free(bfd->cval) ;
00190       free(bfd) ;
00191    }
00192 }
00193 
00194 void BFIT_free_result( BFIT_result * bfr ){ if( bfr != NULL ) free(bfr); }
00195 
00196 
00197 
00198 BFIT_data * BFIT_bootstrap_sample( BFIT_data * bfd )
00199 {
00200    BFIT_data * nfd ;
00201    int ii , jj , mcount,ibot , nuse ;
00202 
00203    if( bfd == NULL ) return NULL ;
00204    mcount = bfd->mcount ;
00205    ibot   = bfd->ibot   ;
00206    nuse   = mcount - ibot ;
00207 
00208    nfd = (BFIT_data *) malloc(sizeof(BFIT_data)) ;
00209 
00210    nfd->mcount = mcount ;
00211    nfd->ibot   = ibot ;
00212    nfd->bval   = (float *) malloc( sizeof(float) * mcount ) ;
00213    if( bfd->cval != NULL )
00214       nfd->cval = (float *) malloc( sizeof(float) * mcount ) ;
00215    else
00216       nfd->cval = NULL ;
00217 
00218    for( ii=0 ; ii < ibot ; ii++ ){
00219       nfd->bval[ii] = 0.0 ;
00220       if( nfd->cval != NULL ) nfd->cval[ii] = 0.0 ;
00221    }
00222 
00223    for( ii=ibot ; ii < mcount ; ii++ ){
00224       jj = ((lrand48()>>8) % nuse) + ibot ;
00225       nfd->bval[ii] = bfd->bval[jj] ;
00226       if( nfd->cval != NULL )
00227          nfd->cval[ii] = bfd->cval[jj] ;
00228    }
00229 
00230    if( nfd->cval != NULL )
00231       qsort_floatfloat( mcount , nfd->bval , nfd->cval ) ;
00232    else
00233       qsort_float( mcount , nfd->bval ) ;
00234 
00235    return nfd ;
00236 }
00237 
00238 
00239 
00240 BFIT_data * BFIT_prepare_dataset(
00241                 THD_3dim_dataset * input_dset , int ival , int sqr ,
00242                 THD_3dim_dataset * mask_dset  , int miv  ,
00243                 float mask_bot  , float mask_top            )
00244 {
00245    int mcount , ii,jj , nvox,ibot ;
00246    byte * mmm ;
00247    BFIT_data * bfd ;
00248    float * bval , * cval ;
00249 
00250    
00251 
00252    if( !ISVALID_DSET(input_dset)     ||
00253        ival < 0                      ||
00254        ival >= DSET_NVALS(input_dset)  ) return NULL ;
00255 
00256    nvox = DSET_NVOX(input_dset) ;
00257 
00258    if( ISVALID_DSET(mask_dset)          &&
00259        (miv < 0                      ||
00260         miv >= DSET_NVALS(mask_dset) ||
00261         DSET_NVOX(mask_dset) != nvox   )   ) return NULL ;
00262 
00263    DSET_load(input_dset) ;
00264    if( DSET_ARRAY(input_dset,ival) == NULL ) return NULL ;
00265 
00266    
00267 
00268    
00269 
00270    if( mask_dset == NULL ){
00271       mmm = (byte *) malloc( sizeof(byte) * nvox ) ;
00272       memset( mmm , 1, nvox ) ; mcount = nvox ;
00273    } else {
00274 
00275       mmm = THD_makemask( mask_dset , miv , mask_bot , mask_top ) ;
00276       mcount = THD_countmask( nvox , mmm ) ;
00277 
00278       if( !EQUIV_DSETS(mask_dset,input_dset) ) DSET_unload(mask_dset) ;
00279       if( mcount < 999 ){
00280          free(mmm) ;
00281          fprintf(stderr,"*** BFIT_prepare_dataset:\n"
00282                         "***   only %d voxels survive the masking!\n",
00283                  mcount ) ;
00284          return NULL ;
00285       }
00286    }
00287 
00288    
00289 
00290    bval = (float *) malloc( sizeof(float) * mcount ) ;
00291 
00292    switch( DSET_BRICK_TYPE(input_dset,ival) ){
00293 
00294          case MRI_short:{
00295             short * bar = (short *) DSET_ARRAY(input_dset,ival) ;
00296             float mfac = DSET_BRICK_FACTOR(input_dset,ival) ;
00297             if( mfac == 0.0 ) mfac = 1.0 ;
00298             for( ii=jj=0 ; ii < nvox ; ii++ )
00299                if( mmm[ii] ) bval[jj++] = mfac*bar[ii] ;
00300          }
00301          break ;
00302 
00303          case MRI_byte:{
00304             byte * bar = (byte *) DSET_ARRAY(input_dset,ival) ;
00305             float mfac = DSET_BRICK_FACTOR(input_dset,ival) ;
00306             if( mfac == 0.0 ) mfac = 1.0 ;
00307             for( ii=jj=0 ; ii < nvox ; ii++ )
00308                if( mmm[ii] ) bval[jj++] = mfac*bar[ii] ;
00309          }
00310          break ;
00311 
00312          case MRI_float:{
00313             float * bar = (float *) DSET_ARRAY(input_dset,ival) ;
00314             float mfac = DSET_BRICK_FACTOR(input_dset,ival) ;
00315             if( mfac == 0.0 ) mfac = 1.0 ;
00316                for( ii=jj=0 ; ii < nvox ; ii++ )
00317                   if( mmm[ii] ) bval[jj++] = mfac*bar[ii] ;
00318          }
00319          break ;
00320    }
00321 
00322    free(mmm) ; DSET_unload(input_dset) ;  
00323 
00324    
00325    
00326 
00327    if( sqr ){
00328       cval = (float *) malloc( sizeof(float) * mcount ) ;
00329       for( ii=0 ; ii < mcount ; ii++ ){
00330          cval[ii] = bval[ii] ;                
00331          bval[ii] = bval[ii]*bval[ii] ;
00332       }
00333       qsort_floatfloat( mcount , bval , cval ) ;
00334    } else {                                   
00335       cval = NULL ;
00336       qsort_float( mcount , bval ) ;
00337    }
00338 
00339    
00340 
00341    if( bval[mcount-1] > 1.0 ){
00342       free(bval) ; if(cval!=NULL) free(cval) ;
00343       fprintf(stderr,"*** BFIT_prepare_dataset:\n"
00344                      "***   R**2 values > 1.0 exist in dataset!\n") ;
00345       return NULL ;
00346    }
00347    if( bval[0] < 0.0 ){
00348       free(bval) ; if(cval!=NULL) free(cval) ;
00349       fprintf(stderr,"*** BFIT_prepare_dataset:\n"
00350                      "***   R**2 values < 0.0 exist in dataset!\n") ;
00351       return NULL ;
00352    }
00353 
00354    
00355 
00356    for( ibot=0; ibot<mcount && bval[ibot]<=0.0; ibot++ ) ; 
00357 
00358    
00359 
00360    bfd = (BFIT_data *) malloc( sizeof(BFIT_data) ) ;
00361 
00362    bfd->mcount = mcount ;
00363    bfd->ibot   = ibot ;
00364    bfd->bval   = bval ;
00365    bfd->cval   = cval ;
00366 
00367    return bfd ;
00368 }
00369 
00370 
00371 
00372 BFIT_result * BFIT_compute( BFIT_data * bfd ,
00373                             float pcut ,
00374                             float abot , float atop ,
00375                             float bbot , float btop ,
00376                             int   nran , int   nbin  )
00377 {
00378    BFIT_result * bfr ;
00379 
00380    float eps,eps1 ;
00381    float *bval , *cval ;
00382    double e0,e1 , aa,bb,xc ;
00383    double chq,ccc,cdf ;
00384    int    ihqbot,ihqtop ;
00385    int mcount,mgood , ii,jj , ibot,itop , sqr ;
00386    float hbot,htop,dbin ;
00387    int * hbin, * jbin ;
00388    MRI_IMAGE * flim ;
00389 
00390    
00391 
00392    if( bfd == NULL ) return NULL ;
00393    if( pcut < 20.0 || pcut >  99.0 ) return NULL ;
00394    if( abot < 0.1  || abot >= atop ) return NULL ;
00395    if( bbot < 9.9  || bbot >= btop ) return NULL ;
00396 
00397    if( nran < 10 ) nran = 10 ;
00398 
00399    mcount = bfd->mcount ;
00400    ibot   = bfd->ibot ;
00401    bval   = bfd->bval ;
00402    cval   = bfd->cval ; sqr = (cval != NULL) ;
00403 
00404    
00405 
00406    itop  = (int)( ibot + 0.01*pcut*(mcount-ibot) + 0.5 ) ;
00407    mgood = itop - ibot ;
00408    if( mgood < 999 ){
00409       fprintf(stderr,"*** BFIT_compute: mgood=%d\n",mgood) ;
00410       return NULL ;
00411    }
00412 
00413    xc = bval[itop-1] ;
00414 
00415    
00416 
00417    e0 = e1 = 0.0 ;
00418    for( ii=ibot ; ii < itop ; ii++ ){
00419      e0 += log(bval[ii]) ; e1 += log(1.0-bval[ii]) ;
00420    }
00421    e0 /= mgood ; e1 /= mgood ;
00422 
00423    
00424 
00425    betarange( abot , atop , bbot , btop ,  nran ) ;
00426 
00427    ii = betasolve( e0,e1,xc , &aa,&bb );
00428    if( ii < 0 ) return NULL ; 
00429 
00430    
00431 
00432 
00433    
00434 
00435    eps1 = mgood / ( (mcount-ibot)*(1.0-beta_t2p(xc,aa,bb)) ) ;
00436    eps  = 1.0-eps1 ;
00437    if( eps1 > 1.0 ) eps1 = 1.0 ;
00438    eps1 = (mcount-ibot) * eps1 ;
00439 
00440    
00441 
00442    if( nbin >= 100 ){  
00443 
00444 #define NEW_HCQ
00445 #ifdef NEW_HCQ    
00446 
00447      { float * xbin = (float *) malloc(sizeof(float)*nbin) ;
00448 
00449        hbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00450        jbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00451 
00452        htop = 1.0 - beta_t2p(xc,aa,bb) ;   
00453        dbin = htop / nbin ;                
00454        ii   = rint( eps1 * dbin ) ;
00455        for( jj=0 ; jj < nbin ; jj++ ){
00456           xbin[jj] = beta_p2t( 1.0 - (jj+1)*dbin , aa , bb ) ;
00457           jbin[jj] = ii ;
00458        }
00459        xbin[nbin-1] = xc ;
00460 
00461        for( ii=ibot ; ii < mcount ; ii++ ){
00462           for( jj=0 ; jj < nbin ; jj++ ){
00463              if( bval[ii] <= xbin[jj] ){ hbin[jj]++ ; break ; }
00464           }
00465        }
00466 
00467        free(xbin) ;
00468 
00469        ihqbot = 0 ;
00470        ihqtop = nbin-1 ;
00471      }
00472 
00473 #else             
00474 
00475      
00476 
00477      if( !sqr ){
00478         hbot = 0.0 ; htop = 1.001 * xc ;
00479         dbin = (htop-hbot)/nbin ;
00480 
00481         hbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00482         jbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00483 
00484         for( ii=0 ; ii < nbin ; ii++ ){  
00485            jbin[ii] = (int)( eps1 * ( beta_t2p(hbot+ii*dbin,aa,bb)
00486                                      -beta_t2p(hbot+ii*dbin+dbin,aa,bb) ) ) ;
00487         }
00488 
00489         flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ;
00490         mri_fix_data_pointer( bval+ibot , flim ) ;
00491         mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ;
00492 
00493         ihqbot = 0 ;
00494         ihqtop = rint( xc / dbin ) ;
00495 
00496      } else {   
00497 
00498         double hb,ht ;
00499         htop = sqrt(1.001*xc) ;
00500         hbot = -htop ;
00501         dbin = (htop-hbot)/nbin ;
00502 
00503         hbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00504         jbin = (int *) calloc((nbin+1),sizeof(int)) ;  
00505 
00506         for( ii=0 ; ii < nbin ; ii++ ){  
00507            hb = hbot+ii*dbin ; ht = hb+dbin ;
00508            hb = hb*hb ; ht = ht*ht ;
00509            if( hb > ht ){ double qq=hb ; hb=ht ; ht=qq ; }
00510            jbin[ii] = (int)( 0.5*eps1 * ( beta_t2p(hb,aa,bb)
00511                                          -beta_t2p(ht,aa,bb) ) ) ;
00512         }
00513 
00514         ihqbot = rint( (-sqrt(xc) - hbot) / dbin ) ;
00515         ihqtop = rint( ( sqrt(xc) - hbot) / dbin ) ;
00516 
00517         flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ;
00518         mri_fix_data_pointer( cval+ibot , flim ) ;
00519         mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ;
00520 
00521      }
00522 #endif
00523 
00524    
00525 
00526      chq = cdf = 0.0 ;
00527      for( ii=ihqbot ; ii <= ihqtop ; ii++ ){
00528         ccc = jbin[ii] ;
00529         if( ccc > 1.0 ){
00530            chq += SQR(hbin[ii]-ccc) / ccc ;
00531            cdf++ ;
00532         }
00533      }
00534      cdf -= 3.0 ;
00535      ccc = chisq_t2p( chq , cdf ) ;
00536 
00537 #ifndef NEW_HCQ
00538      mri_clear_data_pointer(flim) ; mri_free(flim) ;
00539 #endif
00540      free(hbin) ; free(jbin) ;
00541 
00542    } else {
00543       chq = ccc = cdf = 0.0 ;
00544    }
00545 
00546    bfr = (BFIT_result *) malloc(sizeof(BFIT_result)) ;
00547 
00548    bfr->mgood    = mgood ;
00549    bfr->itop     = itop  ;
00550 
00551    bfr->a        = aa  ;
00552    bfr->b        = bb  ;
00553    bfr->xcut     = xc  ;
00554    bfr->chisq    = chq ;
00555    bfr->q_chisq  = ccc ;
00556    bfr->df_chisq = cdf ;
00557    bfr->eps      = eps ;
00558 
00559    return bfr ;
00560 }