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 }