00001 
00002 
00003 
00004 
00005 
00006    
00007 #include "thd_maker.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 
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 #undef  FREE_WORKSPACE
00075 #define FREE_WORKSPACE                              \
00076   do{ FREEUP(bptr) ; FREEUP(sptr) ; FREEUP(fptr) ;  \
00077       FREEUP(cptr) ; FREEUP(fxar) ; FREEUP(fac)  ;  \
00078       FREEUP(fout) ; FREEUP(dtr)  ; FREEUP(tout) ;  \
00079     } while(0)
00080 
00081 
00082 
00083 
00084 THD_3dim_dataset * MAKER_4D_to_typed_fith( THD_3dim_dataset * old_dset ,
00085                                            char * new_prefix , int new_datum ,
00086                                            int ignore , int detrend ,
00087                                            generic_func * user_func ,
00088                                            void * user_data )
00089 {
00090    THD_3dim_dataset * new_dset ;  
00091 
00092    byte    ** bptr = NULL ;  
00093    short   ** sptr = NULL ;  
00094    float   ** fptr = NULL ;  
00095    complex ** cptr = NULL ;
00096 
00097    float * fxar = NULL ;  
00098    float * fac  = NULL ;  
00099    float * fout = NULL ;  
00100    float * tout = NULL ;  
00101    float * dtr  = NULL ;  
00102 
00103    float val , d0fac , d1fac , x0,x1;
00104    double tzero , tdelta , ts_mean , ts_slope ;
00105    int   ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , nbad ;
00106    register int kk ;
00107 
00108    void (*ufunc)(double,double,int,float *,double,double,void *,float *,float *)
00109      = (void (*)(double,double,int,float *,double,double,void *,float *,float *))user_func ;
00110 
00111    
00112    
00113 
00114    if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ;
00115 
00116    if( new_datum >= 0         &&
00117        new_datum != MRI_short &&
00118        new_datum != MRI_float   ) return NULL ;
00119 
00120    if( user_func == NULL ) return NULL ;
00121 
00122    if( ignore < 0 ) ignore = 0 ;
00123 
00124    
00125 
00126    old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ;   
00127    nuse      = DSET_NUM_TIMES(old_dset) - ignore ; 
00128    if( nuse < 2 ) return NULL ;
00129 
00130    if( new_datum < 0 ) new_datum = old_datum ;   
00131    if( new_datum == MRI_complex ) return NULL ;  
00132 
00133    DSET_load( old_dset ) ;  
00134 
00135    kk = THD_count_databricks( old_dset->dblk ) ;  
00136    if( kk < DSET_NVALS(old_dset) ){               
00137       DSET_unload( old_dset ) ;
00138       return NULL ;
00139    }
00140 
00141    switch( old_datum ){  
00142 
00143       default:                      
00144          DSET_unload( old_dset ) ;
00145          return NULL ;
00146 
00147 
00148 
00149       
00150       
00151       
00152 
00153       case MRI_byte:
00154          bptr = (byte **) malloc( sizeof(byte *) * nuse ) ;
00155          if( bptr == NULL ) return NULL ;
00156          for( kk=0 ; kk < nuse ; kk++ )
00157             bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ;
00158       break ;
00159 
00160       
00161       
00162       
00163 
00164       case MRI_short:
00165          sptr = (short **) malloc( sizeof(short *) * nuse ) ;
00166          if( sptr == NULL ) return NULL ;
00167          for( kk=0 ; kk < nuse ; kk++ )
00168             sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ;
00169       break ;
00170 
00171       
00172       
00173       
00174 
00175       case MRI_float:
00176          fptr = (float **) malloc( sizeof(float *) * nuse ) ;
00177          if( fptr == NULL ) return NULL ;
00178          for( kk=0 ; kk < nuse ; kk++ )
00179             fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ;
00180       break ;
00181 
00182       
00183       
00184       
00185 
00186       case MRI_complex:
00187          cptr = (complex **) malloc( sizeof(complex *) * nuse ) ;
00188          if( cptr == NULL ) return NULL ;
00189          for( kk=0 ; kk < nuse ; kk++ )
00190             cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ;
00191       break ;
00192 
00193    } 
00194 
00195    
00196 
00197    fxar = (float *) malloc( sizeof(float) * nuse ) ;   
00198    if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; }
00199 
00200    
00201 
00202    fac = (float *) malloc( sizeof(float) * nuse ) ;   
00203    if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; }
00204 
00205    use_fac = 0 ;
00206    for( kk=0 ; kk < nuse ; kk++ ){
00207       fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ;
00208       if( fac[kk] != 0.0 ) use_fac++ ;
00209       else                 fac[kk] = 1.0 ;
00210    }
00211    if( !use_fac ) FREEUP(fac) ;
00212 
00213    
00214 
00215    dtr = (float *) malloc( sizeof(float) * nuse ) ;
00216    if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; }
00217 
00218    d0fac = 1.0 / nuse ;
00219    d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ;
00220    for( kk=0 ; kk < nuse ; kk++ )
00221       dtr[kk] = kk - 0.5 * (nuse-1) ;  
00222 
00223    
00224 
00225    new_dset = EDIT_empty_copy( old_dset ) ; 
00226 
00227    
00228 
00229    ii = EDIT_dset_items(
00230            new_dset ,
00231               ADN_prefix      , new_prefix ,           
00232               ADN_malloc_type , DATABLOCK_MEM_MALLOC , 
00233               ADN_datum_all   , new_datum ,            
00234               ADN_nvals       , 2 ,                    
00235               ADN_ntt         , 0 ,                    
00236               ADN_type        , ISHEAD(old_dset)       
00237                                  ? HEAD_FUNC_TYPE
00238                                  : GEN_FUNC_TYPE ,
00239               ADN_func_type   , FUNC_THR_TYPE ,        
00240            ADN_none ) ;
00241 
00242    if( ii != 0 ){
00243       THD_delete_3dim_dataset( new_dset , False ) ;  
00244       FREE_WORKSPACE ; return NULL ;
00245    }
00246 
00247    
00248 
00249 
00250    nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ;
00251 
00252    fout = (float *) malloc( sizeof(float) * nvox ); 
00253    tout = (float *) malloc( sizeof(float) * nvox ); 
00254 
00255    if( ( fout == NULL ) || (tout == NULL) ){
00256       THD_delete_3dim_dataset( new_dset , False ) ;
00257       FREE_WORKSPACE ; return NULL ;
00258    }
00259 
00260    
00261 
00262    tdelta = old_dset->taxis->ttdel ;
00263    if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ;
00264    if( tdelta == 0.0 ) tdelta = 1.0 ;
00265 
00266    izold  = -666 ;
00267    nxy    = old_dset->daxes->nxx * old_dset->daxes->nyy ;
00268 
00269    
00270    
00271 
00272    
00273 
00274 #if 0
00275    user_func(  0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL , NULL ) ;
00276 #else
00277    ufunc(  0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL , NULL ) ;
00278 #endif
00279 
00280    
00281 
00282    for( ii=0 ; ii < nvox ; ii++  ){  
00283 
00284       
00285 
00286       switch( old_datum ){
00287 
00288          
00289 
00290          case MRI_byte:
00291             for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ;
00292          break ;
00293 
00294          
00295 
00296          case MRI_short:
00297             for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ;
00298          break ;
00299 
00300          
00301 
00302          case MRI_float:
00303             for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ;
00304          break ;
00305 
00306          
00307 
00308          case MRI_complex:
00309             for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ;
00310          break ;
00311 
00312       } 
00313 
00314       
00315 
00316       if( use_fac )
00317          for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ;
00318 
00319 
00320 
00321       x0 = x1 = 0.0 ;
00322       for( kk=0 ; kk < nuse ; kk++ ){
00323          x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ;
00324       }
00325 
00326       x0 *= d0fac ; x1 *= d1fac ;  
00327 
00328       ts_mean  = x0 ;
00329       ts_slope = x1 / tdelta ;
00330 
00331 
00332 
00333       if( detrend )
00334          for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ;
00335 
00336 
00337 
00338       iz = ii / nxy ;    
00339 
00340       if( iz != izold ){          
00341          tzero = THD_timeof( ignore ,
00342                              old_dset->daxes->zzorg
00343                            + iz*old_dset->daxes->zzdel , old_dset->taxis ) ;
00344          izold = iz ;
00345 
00346          if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ;
00347       }
00348 
00349       
00350 
00351 #if 0
00352       user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data ,
00353                  fout+ii , tout+ii ) ;
00354 #else
00355       ufunc( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data ,
00356                  fout+ii , tout+ii ) ;
00357 #endif
00358 
00359       
00360       if (tout[ii] >  1.0)  tout[ii] =  1.0;
00361       if (tout[ii] < -1.0)  tout[ii] = -1.0;
00362 
00363    } 
00364 
00365    DSET_unload( old_dset ) ;  
00366 
00367    
00368 
00369 #if 0
00370    user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL , NULL ) ;
00371 #else
00372    ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL , NULL ) ;
00373 #endif
00374 
00375    nbad = thd_floatscan(nvox,fout) + thd_floatscan(nvox,tout) ;
00376    if( nbad > 0 )
00377       fprintf(stderr,
00378               "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fith\n\a",
00379               nbad ) ;
00380 
00381    
00382    
00383 
00384 
00385    switch( new_datum ){
00386 
00387       
00388 
00389 
00390       case MRI_float:
00391          EDIT_substitute_brick( new_dset , 0 , MRI_float , fout ) ;
00392          EDIT_substitute_brick( new_dset , 1 , MRI_float , tout ) ;
00393          fout = NULL ;   tout = NULL;    
00394       break ;
00395 
00396       
00397 
00398 
00399       case MRI_short:{
00400          short * bout ;
00401          short * tbout ;
00402          float sfac[2] ;
00403 
00404          
00405 
00406          bout = (short *) malloc( sizeof(short) * nvox ) ;
00407          tbout = (short *) malloc( sizeof(short) * nvox ) ;
00408          if( (bout == NULL) || (tbout == NULL) ){
00409             fprintf(stderr,
00410              "\nFinal malloc error in MAKER_4D_to_fith - is memory exhausted?\n\a") ;
00411             EXIT(1) ;
00412          }
00413 
00414          
00415 
00416          sfac[0] = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ;
00417          if( sfac[0] > 0.0 ){
00418             sfac[0] = 32767.0 / sfac[0] ;
00419             EDIT_coerce_scale_type( nvox,sfac[0] ,
00420                                     MRI_float,fout , MRI_short,bout ) ;
00421             sfac[0] = 1.0 / sfac[0] ;
00422          }
00423          sfac[1] = FUNC_THR_SCALE_SHORT;
00424          EDIT_coerce_scale_type( nvox,sfac[1] ,
00425                                  MRI_float,tout , MRI_short,tbout ) ;
00426          sfac[1] = 1.0 / sfac[1];
00427 
00428          
00429 
00430          EDIT_substitute_brick( new_dset , 0 , MRI_short , bout ) ;
00431          EDIT_substitute_brick( new_dset , 1 , MRI_short , tbout ) ;
00432          EDIT_dset_items( new_dset , ADN_brick_fac , sfac , ADN_none ) ;
00433       }
00434       break ;
00435 
00436 
00437    } 
00438 
00439    
00440 
00441    FREE_WORKSPACE ;
00442    return new_dset ;
00443 }