00001
00002
00003
00004
00005
00006
00007
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 #define PROGRAM_NAME "3dfim"
00041 #define PROGRAM_AUTHOR "R. W. Cox and B. D. Ward"
00042 #define PROGRAM_INITIAL "06 Sept 1996"
00043 #define PROGRAM_LATEST "15 August 2001"
00044
00045
00046
00047 #define SO_BIG 33333
00048
00049 #include "afni.h"
00050 #include "mrilib.h"
00051 #include "ts.h"
00052 #include "afni_pcor.c"
00053
00054
00055
00056
00057
00058 #undef FIM_THR
00059 #define FIM_THR 0.0999
00060
00061
00062 THD_3dim_dataset * fim3d_fimmer_compute ( THD_3dim_dataset * dset_time ,
00063 time_series_array * ref_ts , time_series_array * ort_ts ,
00064 int itbot, char * new_prefix,
00065 float max_percent )
00066 {
00067 THD_3dim_dataset * new_dset ;
00068 int ifim , it,iv , nvox , ngood_ref , ntime , it1 , dtyp , nxyz;
00069 float * vval , * tsar , * aval , * rbest , * abest ;
00070 int * indx ;
00071 short * bar ;
00072 void * ptr ;
00073 float stataux[MAX_STAT_AUX];
00074 float fthr , topval ;
00075 int nx_ref , ny_ref , ivec , nnow ;
00076 PCOR_references ** pc_ref ;
00077 PCOR_voxel_corr ** pc_vc ;
00078 int save_resam ;
00079
00080 int fim_nref , nx_ort , ny_ort , internal_ort ;
00081 static float * ref_vec = NULL ;
00082 static int nref_vec = -666 ;
00083
00084 float * ref_ts_min = NULL,
00085 * ref_ts_max = NULL,
00086 * baseline = NULL;
00087
00088 int i;
00089
00090 int nupdt = 0 ,
00091 min_updt = 5 ;
00092
00093
00094
00095
00096 if (!DSET_GRAPHABLE(dset_time))
00097 {
00098 fprintf (stderr, "Error: Invalid 3d+time input data file \n");
00099 RETURN (NULL);
00100 }
00101
00102 if (ref_ts == NULL)
00103 {
00104 fprintf (stderr, "Error: No ideal time series \n");
00105 RETURN (NULL);
00106 }
00107
00108 for (i = 0; i < ref_ts->num; i++)
00109 if (ref_ts->tsarr[i]->len < DSET_NUM_TIMES(dset_time))
00110 {
00111 char str[256] ;
00112 sprintf (str,
00113 "Error: ideal time series is too short: ntime=%d num_ts=%d \n",
00114 DSET_NUM_TIMES(dset_time),
00115 ref_ts->tsarr[i]->len);
00116 fprintf (stderr, str) ;
00117 RETURN (NULL) ;
00118 }
00119
00120
00121
00122
00123 if( ort_ts->num > 0 )
00124 {
00125 internal_ort = 0;
00126 ny_ort = ort_ts->num;
00127 for (i = 0; i < ny_ort; i++)
00128 {
00129 nx_ort = ort_ts->tsarr[i]->len ;
00130 if (nx_ort < DSET_NUM_TIMES(dset_time))
00131 {
00132 char str[256] ;
00133 sprintf (str,
00134 "Error: ort time series is too short: ntime=%d ort_ts=%d \n",
00135 DSET_NUM_TIMES(dset_time),
00136 ort_ts->tsarr[i]->len);
00137 fprintf (stderr, str) ;
00138 RETURN (NULL) ;
00139 }
00140 }
00141 }
00142 else
00143 {
00144 internal_ort = 1 ;
00145 }
00146 fim_nref = (internal_ort) ? 3 : (ny_ort+3) ;
00147
00148 if( nref_vec < fim_nref )
00149 {
00150 ref_vec = (float *) malloc (sizeof(float)*fim_nref) ;
00151 nref_vec = fim_nref;
00152 }
00153
00154
00155
00156 if (max_percent > 0.0)
00157 {
00158 ref_ts_max = (float *) malloc (sizeof(float) * (ref_ts->num));
00159 ref_ts_min = (float *) malloc (sizeof(float) * (ref_ts->num));
00160 }
00161
00162
00163 nx_ref = ref_ts->tsarr[0]->len;
00164 ny_ref = ref_ts->num;
00165 ntime = DSET_NUM_TIMES(dset_time) ;
00166 ngood_ref = 0 ;
00167 it1 = -1 ;
00168 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00169 tsar = ref_ts->tsarr[ivec]->ts;
00170 ifim = 0 ;
00171
00172 if (max_percent > 0.0)
00173 {
00174 ref_ts_min[ivec] = (float) SO_BIG;
00175 ref_ts_max[ivec] = - (float) SO_BIG;
00176 }
00177
00178 for( it=itbot ; it < ntime ; it++ )
00179 {
00180 if( tsar[it] < SO_BIG )
00181 {
00182 ifim++ ;
00183 if( it1 < 0 ) it1 = it ;
00184
00185 if (max_percent > 0.0)
00186 {
00187 if (tsar[it] > ref_ts_max[ivec]) ref_ts_max[ivec] = tsar[it];
00188 if (tsar[it] < ref_ts_min[ivec]) ref_ts_min[ivec] = tsar[it];
00189 }
00190 }
00191 }
00192
00193 if( ifim < min_updt ){
00194 STATUS("ref_ts has too few good entries!") ;
00195 RETURN(NULL) ;
00196 }
00197
00198 ngood_ref = MAX( ifim , ngood_ref ) ;
00199 }
00200
00201
00202
00203
00204 dtyp = DSET_BRICK_TYPE(dset_time,it1) ;
00205 if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){
00206 STATUS("illegal input data type!") ;
00207 RETURN(NULL) ;
00208 }
00209
00210
00211 #ifdef AFNI_DEBUG
00212 { char str[256] ;
00213 sprintf(str,"new prefix = %s",new_prefix) ; STATUS(str) ; }
00214 #endif
00215
00216
00217
00218 THD_load_datablock( dset_time->dblk ) ;
00219
00220 nxyz = dset_time->dblk->diskptr->dimsizes[0]
00221 * dset_time->dblk->diskptr->dimsizes[1]
00222 * dset_time->dblk->diskptr->dimsizes[2] ;
00223
00224
00225
00226
00227
00228 switch( dtyp ){
00229
00230 case MRI_short:{
00231 short * dar = (short *) DSET_ARRAY(dset_time,it1) ;
00232 for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ;
00233 fthr = FIM_THR * fthr / nxyz ;
00234 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00235 if( abs(dar[iv]) > fthr ) nvox++ ;
00236 indx = (int *) malloc( sizeof(int) * nvox ) ;
00237 if( indx == NULL ){
00238 fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
00239 RETURN(NULL) ;
00240 }
00241 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00242 if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ;
00243 }
00244 break ;
00245
00246 case MRI_float:{
00247 float * dar = (float *) DSET_ARRAY(dset_time,it1) ;
00248 for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ;
00249 fthr = FIM_THR * fthr / nxyz ;
00250 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00251 if( fabs(dar[iv]) > fthr ) nvox++ ;
00252 indx = (int *) malloc( sizeof(int) * nvox ) ;
00253 if( indx == NULL ){
00254 fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
00255 RETURN(NULL) ;
00256 }
00257 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00258 if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ;
00259 }
00260 break ;
00261
00262 case MRI_byte:{
00263 byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ;
00264 for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ;
00265 fthr = FIM_THR * fthr / nxyz ;
00266 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00267 if( dar[iv] > fthr ) nvox++ ;
00268 indx = (int *) malloc( sizeof(int) * nvox ) ;
00269 if( indx == NULL ){
00270 fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ;
00271 RETURN(NULL) ;
00272 }
00273 for( iv=0,nvox=0 ; iv < nxyz ; iv++ )
00274 if( dar[iv] > fthr ) indx[nvox++] = iv ;
00275 }
00276 break ;
00277 }
00278
00279
00280
00281 vval = (float *) malloc( sizeof(float) * nvox) ;
00282 if( vval == NULL ){
00283 fprintf(stderr,"\n*** vval malloc failure in fim3d_fimmer_compute\n") ;
00284 free(indx) ; RETURN(NULL) ;
00285 }
00286
00287
00288
00289 if (max_percent > 0.0)
00290 {
00291 baseline = (float *) malloc (sizeof(float) * nvox);
00292 if (baseline == NULL)
00293 {
00294 fprintf(stderr,
00295 "\n*** baseline malloc failure in fim3d_fimmer_compute\n") ;
00296 free(indx) ; free(vval); RETURN(NULL) ;
00297 }
00298 else
00299 for (iv = 0; iv < nvox; iv++)
00300 baseline[iv] = 0.0;
00301 }
00302
00303
00304
00305
00306 if( ny_ref > 1 ){
00307 aval = (float *) malloc( sizeof(float) * nvox) ;
00308 rbest = (float *) malloc( sizeof(float) * nvox) ;
00309 abest = (float *) malloc( sizeof(float) * nvox) ;
00310 if( aval==NULL || rbest==NULL || abest==NULL ){
00311 fprintf(stderr,"\n*** abest malloc failure in fim3d_fimmer_compute\n") ;
00312 free(vval) ; free(indx) ;
00313 if( aval != NULL ) free(aval) ;
00314 if( rbest != NULL ) free(rbest) ;
00315 if( abest != NULL ) free(abest) ;
00316 RETURN(NULL) ;
00317 }
00318 } else {
00319 aval = rbest = abest = NULL ;
00320 }
00321
00322 #ifdef AFNI_DEBUG
00323 { char str[256] ;
00324 sprintf(str,"nxyz = %d nvox = %d",nxyz,nvox) ; STATUS(str) ; }
00325 #endif
00326
00327
00328
00329 pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ;
00330 pc_vc = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ;
00331
00332 if( pc_ref == NULL || pc_vc == NULL ){
00333 free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
00334 if( aval != NULL ) free(aval) ;
00335 if( rbest != NULL ) free(rbest) ;
00336 if( abest != NULL ) free(abest) ;
00337 fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ;
00338 RETURN(NULL) ;
00339 }
00340
00341 ifim = 0 ;
00342 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00343 pc_ref[ivec] = new_PCOR_references( fim_nref ) ;
00344 pc_vc[ivec] = new_PCOR_voxel_corr( nvox , fim_nref ) ;
00345 if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ) ifim++ ;
00346 }
00347
00348 if( ifim > 0 ){
00349 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00350 free_PCOR_references(pc_ref[ivec]) ;
00351 free_PCOR_voxel_corr(pc_vc[ivec]) ;
00352 }
00353 free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
00354 if( aval != NULL ) free(aval) ;
00355 if( rbest != NULL ) free(rbest) ;
00356 if( abest != NULL ) free(abest) ;
00357 fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ;
00358 RETURN(NULL) ;
00359 }
00360
00361
00362
00363 new_dset = EDIT_empty_copy( dset_time ) ;
00364
00365 it = EDIT_dset_items( new_dset ,
00366 ADN_prefix , new_prefix ,
00367 ADN_malloc_type , DATABLOCK_MEM_MALLOC ,
00368 ADN_type , ISHEAD(dset_time)
00369 ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE ,
00370 ADN_func_type , FUNC_COR_TYPE ,
00371 ADN_nvals , FUNC_nvals[FUNC_COR_TYPE] ,
00372 ADN_datum_all , MRI_short ,
00373 ADN_ntt , 0 ,
00374 ADN_none ) ;
00375
00376 if( it > 0 ){
00377 fprintf(stderr,
00378 "\n*** EDIT_dset_items error %d in fim3d_fimmer_compute\n",it) ;
00379 THD_delete_3dim_dataset( new_dset , False ) ;
00380 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00381 free_PCOR_references(pc_ref[ivec]) ;
00382 free_PCOR_voxel_corr(pc_vc[ivec]) ;
00383 }
00384 free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
00385 if( aval != NULL ) free(aval) ;
00386 if( rbest != NULL ) free(rbest) ;
00387 if( abest != NULL ) free(abest) ;
00388 RETURN(NULL) ;
00389 }
00390
00391 for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){
00392 ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ;
00393 mri_fix_data_pointer( ptr , DSET_BRICK(new_dset,iv) ) ;
00394 }
00395
00396 if( THD_count_databricks(new_dset->dblk) < new_dset->dblk->nvals ){
00397 fprintf(stderr,
00398 "\n*** failure to malloc new bricks in fim3d_fimmer_compute\n") ;
00399 THD_delete_3dim_dataset( new_dset , False ) ;
00400 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00401 free_PCOR_references(pc_ref[ivec]) ;
00402 free_PCOR_voxel_corr(pc_vc[ivec]) ;
00403 }
00404 free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
00405 if( aval != NULL ) free(aval) ;
00406 if( rbest != NULL ) free(rbest) ;
00407 if( abest != NULL ) free(abest) ;
00408 RETURN(NULL) ;
00409 }
00410
00411
00412
00413
00414 for( it=itbot ; it < ntime ; it++ ){
00415
00416 nnow = 0 ;
00417 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00418 tsar = ref_ts->tsarr[ivec]->ts ;
00419 if( tsar[it] >= SO_BIG ) continue ;
00420
00421 ref_vec[0] = 1.0 ;
00422 ref_vec[1] = (float) it ;
00423
00424 if (internal_ort)
00425 {
00426 ref_vec[2] = tsar[it] ;
00427 }
00428 else
00429 {
00430 for( iv=0 ; iv < ny_ort ; iv++ )
00431 ref_vec[iv+2] = ort_ts->tsarr[iv]->ts[it];
00432 ref_vec[ny_ort+2] = tsar[it] ;
00433 }
00434
00435
00436 #ifdef AFNI_DEBUG
00437 { char str[256] ;
00438 sprintf(str,"time index=%d ideal[%d]=%f" , it,ivec,tsar[it] ) ;
00439 if (ivec == 0) STATUS(str) ; }
00440 #endif
00441
00442
00443 update_PCOR_references( ref_vec , pc_ref[ivec] ) ;
00444
00445 switch( dtyp ){
00446 case MRI_short:{
00447 short * dar = (short *) DSET_ARRAY(dset_time,it) ;
00448 for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
00449 }
00450 break ;
00451
00452 case MRI_float:{
00453 float * dar = (float *) DSET_ARRAY(dset_time,it) ;
00454 for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
00455 }
00456 break ;
00457
00458 case MRI_byte:{
00459 byte * dar = (byte *) DSET_ARRAY(dset_time,it) ;
00460 for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ;
00461 }
00462 break ;
00463 }
00464
00465 PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ;
00466 nnow++ ;
00467
00468
00469 if (max_percent > 0.0)
00470 if (ivec == 0)
00471 for (iv = 0; iv < nvox; iv++)
00472 baseline[iv] += vval[iv] / ngood_ref;
00473
00474 }
00475 if( nnow > 0 ) nupdt++ ;
00476
00477
00478
00479
00480 if( nupdt == ngood_ref )
00481 {
00482
00483
00484 stataux[0] = nupdt ;
00485 stataux[1] = (ny_ref==1) ? 1 : 2 ;
00486 stataux[2] = fim_nref - 1 ;
00487 for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ;
00488
00489 STATUS("setting statistical parameters") ;
00490
00491 (void) EDIT_dset_items( new_dset ,
00492 ADN_stat_aux , stataux ,
00493 ADN_none ) ;
00494
00495
00496
00497 if( ny_ref == 1 ){
00498
00499
00500
00501
00502
00503
00504 STATUS("getting 1 ref alpha") ;
00505
00506 PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ;
00507
00508
00509 if (max_percent > 0.0)
00510 {
00511 for (iv = 0; iv < nvox; iv++)
00512 {
00513 vval[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]);
00514 if (fabs(vval[iv]) < max_percent * fabs(baseline[iv]))
00515 vval[iv] = fabs( vval[iv] / baseline[iv] );
00516 else
00517 vval[iv] = max_percent;
00518 }
00519 topval = max_percent;
00520 }
00521 else
00522 {
00523 topval = 0.0 ;
00524 for( iv=0 ; iv < nvox ; iv++ )
00525 if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ;
00526 }
00527
00528 bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
00529
00530 #ifdef DONT_USE_MEMCPY
00531 for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
00532 #else
00533 memset( bar , 0 , sizeof(short)*nxyz ) ;
00534 #endif
00535
00536 if( topval > 0.0 ){
00537 topval = MRI_TYPE_maxval[MRI_short] / topval ;
00538 for( iv=0 ; iv < nvox ; iv++ )
00539 bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ;
00540
00541 stataux[0] = 1.0/topval ;
00542 } else {
00543 stataux[0] = 0.0 ;
00544 }
00545
00546
00547
00548
00549 STATUS("getting 1 ref pcor") ;
00550
00551 PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ;
00552
00553 bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
00554
00555 #ifdef DONT_USE_MEMCPY
00556 for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
00557 #else
00558 memset( bar , 0 , sizeof(short)*nxyz ) ;
00559 #endif
00560
00561 for( iv=0 ; iv < nvox ; iv++ )
00562 bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ;
00563
00564 stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;
00565
00566 } else {
00567
00568
00569
00570
00571
00572 PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ;
00573
00574
00575 if (max_percent > 0.0)
00576 for (iv = 0; iv < nvox; iv++)
00577 abest[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]);
00578
00579 PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ;
00580
00581
00582
00583
00584
00585 for( ivec=1 ; ivec < ny_ref ; ivec++ ){
00586
00587 PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ;
00588
00589 PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ;
00590
00591 for( iv=0 ; iv < nvox ; iv++ ){
00592 if( fabs(vval[iv]) > fabs(rbest[iv]) ){
00593 rbest[iv] = vval[iv] ;
00594 abest[iv] = aval[iv] ;
00595
00596
00597 if (max_percent > 0.0)
00598 abest[iv] *= 100.0 *
00599 (ref_ts_max[ivec] - ref_ts_min[ivec]);
00600
00601 }
00602 }
00603
00604 }
00605
00606
00607
00608
00609
00610 if (max_percent > 0.0)
00611 {
00612 for (iv = 0; iv < nvox; iv++)
00613 {
00614 if (fabs(abest[iv]) < max_percent * fabs(baseline[iv]))
00615 abest[iv] = fabs( abest[iv] / baseline[iv] );
00616 else
00617 abest[iv] = max_percent;
00618 }
00619 topval = max_percent;
00620 }
00621 else
00622 {
00623 topval = 0.0 ;
00624 for( iv=0 ; iv < nvox ; iv++ )
00625 if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ;
00626 }
00627
00628 bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ;
00629
00630 #ifdef DONT_USE_MEMCPY
00631 for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
00632 #else
00633 memset( bar , 0 , sizeof(short)*nxyz ) ;
00634 #endif
00635
00636 if( topval > 0.0 ){
00637 topval = MRI_TYPE_maxval[MRI_short] / topval ;
00638 for( iv=0 ; iv < nvox ; iv++ )
00639 bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ;
00640
00641 stataux[0] = 1.0/topval ;
00642 } else {
00643 stataux[0] = 0.0 ;
00644 }
00645
00646 bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ;
00647
00648 #ifdef DONT_USE_MEMCPY
00649 for( iv=0 ; iv < nxyz ; iv++ ) bar[iv] = 0 ;
00650 #else
00651 memset( bar , 0 , sizeof(short)*nxyz ) ;
00652 #endif
00653
00654 for( iv=0 ; iv < nvox ; iv++ )
00655 bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ;
00656
00657 stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ;
00658
00659 }
00660
00661 STATUS("setting brick_fac") ;
00662
00663 (void) EDIT_dset_items( new_dset ,
00664 ADN_brick_fac , stataux ,
00665 ADN_none ) ;
00666
00667 }
00668 }
00669
00670
00671
00672
00673 for( ivec=0 ; ivec < ny_ref ; ivec++ ){
00674 free_PCOR_references(pc_ref[ivec]) ;
00675 free_PCOR_voxel_corr(pc_vc[ivec]) ;
00676 }
00677 free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ;
00678 if( aval != NULL ) free(aval) ;
00679 if( rbest != NULL ) free(rbest) ;
00680 if( abest != NULL ) free(abest) ;
00681
00682 if (ref_ts_min != NULL) free (ref_ts_min);
00683 if (ref_ts_max != NULL) free (ref_ts_max);
00684 if (baseline != NULL) free (baseline);
00685
00686
00687
00688 THD_load_statistics (new_dset);
00689
00690
00691
00692 RETURN(new_dset) ;
00693 }
00694
00695
00696
00697
00698
00699 typedef struct
00700 {
00701 char prefix_name[THD_MAX_NAME];
00702 THD_3dim_dataset * dset;
00703 time_series_array * idts;
00704 time_series_array * ortts;
00705 int first_im;
00706 float max_percent;
00707
00708 } line_opt ;
00709
00710
00711
00712
00713 void Syntax( char * ) ;
00714
00715
00716
00717
00718
00719
00720 #define OPENERS "[{/%"
00721 #define CLOSERS "]}/%"
00722
00723 #define IS_OPENER(sss) (strlen((sss))==1 && strstr(OPENERS,(sss))!=NULL)
00724 #define IS_CLOSER(sss) (strlen((sss))==1 && strstr(CLOSERS,(sss))!=NULL)
00725
00726
00727 void get_line_opt( int argc , char *argv[] , line_opt *opt )
00728 {
00729
00730 int nopt ;
00731 float ftemp ;
00732 MRI_IMAGE *im ;
00733 time_series *ideal;
00734 time_series *ort;
00735 char err_note[128];
00736 Boolean ok;
00737 char input_filename[THD_MAX_NAME];
00738
00739
00740
00741 if( argc < 2 || strncmp(argv[1],"-help",4) == 0 ) Syntax(NULL) ;
00742
00743
00744 AFNI_logger (PROGRAM_NAME,argc,argv);
00745
00746
00747 strcpy (opt->prefix_name, "");
00748 opt->first_im = 0 ;
00749 opt->max_percent = 0.0;
00750
00751
00752 INIT_TSARR(opt->idts) ;
00753
00754
00755 INIT_TSARR (opt->ortts);
00756
00757
00758 ideal = NULL ;
00759 strcpy (input_filename, "");
00760
00761
00762
00763
00764
00765
00766
00767
00768 nopt = 1 ;
00769
00770 do{
00771
00772 #ifdef DEBUG
00773 # define DBOPT(str) fprintf(stderr,"at option %s: %s\n",argv[nopt],str)
00774 #else
00775 # define DBOPT(str)
00776 #endif
00777
00778
00779 if( strncmp(argv[nopt],"-im1",4) == 0 )
00780 {
00781 DBOPT("-im1") ;
00782 if( ++nopt >= argc ) Syntax("-im1 needs an argument") ;
00783 ftemp = strtod( argv[nopt] , NULL ) ;
00784 if( ftemp < 1.0 )
00785 {
00786 sprintf( err_note , "illegal -im1 value: %f" , ftemp ) ;
00787 Syntax(err_note) ;
00788 }
00789 opt->first_im = (int)(ftemp+0.499) - 1;
00790 continue ;
00791 }
00792
00793
00794
00795 if( strncmp(argv[nopt],"-ideal",5) == 0 )
00796 {
00797 DBOPT("-ideal") ;
00798 if( ++nopt >= argc ) Syntax("-ideal needs a filename") ;
00799
00800
00801
00802 if( ! IS_OPENER(argv[nopt]) )
00803 {
00804 ideal = RWC_read_time_series( argv[nopt] ) ;
00805 if( ideal == NULL ) Syntax ("Unable to read ideal time series.");
00806 ADDTO_TSARR( opt->idts , ideal ) ;
00807 }
00808 else
00809 {
00810 for( nopt++ ; !IS_CLOSER(argv[nopt]) && nopt<argc ; nopt++ )
00811 {
00812 ideal = RWC_read_time_series( argv[nopt] ) ;
00813 if( ideal == NULL ) Syntax ("Unable to read ideal time series.");
00814 ADDTO_TSARR( opt->idts , ideal ) ;
00815 }
00816 if( nopt == argc ) Syntax("-ideal never finishes!") ;
00817 }
00818 continue ;
00819 }
00820
00821
00822
00823 if( strncmp(argv[nopt],"-percent",8) == 0 )
00824 {
00825 DBOPT("-percent") ;
00826 if( ++nopt >= argc ) Syntax("-percent needs an argument") ;
00827 ftemp = strtod( argv[nopt] , NULL ) ;
00828 if( ftemp <= 0.0 )
00829 {
00830 sprintf( err_note , "illegal -percent value: %f" , ftemp ) ;
00831 Syntax(err_note) ;
00832 }
00833 opt->max_percent = ftemp;
00834 continue ;
00835 }
00836
00837
00838
00839 if( strncmp(argv[nopt],"-ort",4) == 0 )
00840 {
00841 DBOPT("-ort") ;
00842 if( ++nopt >= argc ) Syntax("-ort needs a filename") ;
00843
00844
00845
00846 if( ! IS_OPENER(argv[nopt]) )
00847 {
00848 ort = RWC_read_time_series( argv[nopt] ) ;
00849 if( ort == NULL ) Syntax ("Unable to read ort time series.");
00850 ADDTO_TSARR( opt->ortts , ort ) ;
00851 }
00852 else
00853 {
00854 for( nopt++ ; !IS_CLOSER(argv[nopt]) && nopt<argc ; nopt++ )
00855 {
00856 ort = RWC_read_time_series( argv[nopt] ) ;
00857 if( ort == NULL ) Syntax ("Unable to read ort time series.");
00858 ADDTO_TSARR( opt->ortts , ort ) ;
00859 }
00860 if( nopt == argc ) Syntax("-ort never finishes!") ;
00861 }
00862 continue ;
00863 }
00864
00865
00866
00867 if( strncmp(argv[nopt], "-prefix", 5) == 0 ){
00868 DBOPT("-prefix") ;
00869 if( ++nopt >= argc ) Syntax("-prefix needs a name") ;
00870 if( strcmp(opt->prefix_name, "") )
00871 Syntax("Cannot have two prefix output names!" ) ;
00872 strcpy (opt->prefix_name, argv[nopt]) ;
00873 DBOPT("stored as prefix") ;
00874 continue ;
00875 }
00876
00877
00878
00879 if( strncmp(argv[nopt], "-input", 5) == 0 )
00880 {
00881 DBOPT("-input") ;
00882 if( ++nopt >= argc ) Syntax("-input needs a name") ;
00883 if( strcmp(input_filename, "") )
00884 Syntax ("Cannot have two input names!" ) ;
00885 strcpy (input_filename, argv[nopt] );
00886
00887 opt->dset = THD_open_one_dataset( argv[nopt] ) ;
00888 if( opt->dset == NULL )
00889 {
00890 sprintf (err_note, "Unable to open 3d+time data file: %s", argv[nopt]);
00891 Syntax (err_note);
00892 }
00893 continue ;
00894 }
00895
00896
00897 sprintf( err_note , "Unknown option %s" , argv[nopt] ) ;
00898 Syntax(err_note) ;
00899
00900 } while( ++nopt < argc ) ;
00901
00902
00903
00904 if (!strcmp(input_filename,"")) Syntax ("No input file name was given.");
00905 if( opt->idts->num == 0 ) Syntax("No ideal response vector was defined!") ;
00906 if (!strcmp(opt->prefix_name,"")) Syntax ("No prefix name was specified.");
00907
00908
00909
00910
00911 return ;
00912 }
00913
00914
00915
00916
00917
00918 void Syntax( char *note )
00919 {
00920 static char *mesg[] = {
00921 "Program: 3dfim \n\n"
00922 "Purpose: Calculate functional image from 3d+time data file. \n"
00923 "Usage: 3dfim [-im1 num] -input fname -prefix name \n"
00924 " -ideal fname [-ideal fname] [-ort fname] \n"
00925 " " ,
00926 "options are:",
00927 "-im1 num num = index of first image to be used in time series ",
00928 " correlation; default is 1 ",
00929 " ",
00930 "-input fname fname = filename of 3d + time data file for input",
00931 " " ,
00932 "-prefix name name = prefix of filename for saving functional data",
00933 " ",
00934 "-ideal fname fname = filename of a time series to which the image data",
00935 " is to be correlated. ",
00936 " ",
00937 "-percent p Calculate percentage change due to the ideal time series ",
00938 " p = maximum allowed percentage change from baseline ",
00939 " Note: values greater than p are set equal to p. ",
00940 " ",
00941 "-ort fname fname = filename of a time series to which the image data",
00942 " is to be orthogonalized ",
00943 " ",
00944 " N.B.: It is possible to specify more than",
00945 " one ideal time series file. Each one is separately correlated",
00946 " with the image time series and the one most highly correlated",
00947 " is selected for each pixel. Multiple ideals are specified",
00948 " using more than one '-ideal fname' option, or by using the",
00949 " form '-ideal [ fname1 fname2 ... ]' -- this latter method",
00950 " allows the use of wildcarded ideal filenames.",
00951 " The '[' character that indicates the start of a group of",
00952 " ideals can actually be any ONE of these: " OPENERS ,
00953 " and the ']' that ends the group can be: " CLOSERS ,
00954 " ",
00955 " [Format of ideal time series files:",
00956 " ASCII; one number per line;",
00957 " Same number of lines as images in the time series;",
00958 " Value over 33333 --> don't use this image in the analysis]",
00959 " ",
00960 " N.B.: It is also possible to specify more than",
00961 " one ort time series file. The image time series is ",
00962 " orthogonalized to each ort time series. Multiple orts are ",
00963 " specified by using more than one '-ort fname' option, ",
00964 " or by using the form '-ort [ fname1 fname2 ... ]'. This ",
00965 " latter method allows the use of wildcarded ort filenames.",
00966 " The '[' character that indicates the start of a group of",
00967 " ideals can actually be any ONE of these: " OPENERS ,
00968 " and the ']' that ends the group can be: " CLOSERS ,
00969 " ",
00970 " [Format of ort time series files:",
00971 " ASCII; one number per line;",
00972 " At least same number of lines as images in the time series]",
00973 " ",
00974 " ",
00975 } ;
00976
00977 int nsize , ii ;
00978
00979 if( note != NULL && (nsize=strlen(note)) > 0 ){
00980 fprintf(stderr,"\n") ;
00981 for(ii=0;ii<nsize+9;ii++) fprintf(stderr,"*") ;
00982 fprintf(stderr,"\a\n Error: %s\n", note ) ;
00983 for(ii=0;ii<nsize+9;ii++) fprintf(stderr,"*") ;
00984 fprintf(stderr,"\nTry 3dfim -help for instructions\a\n") ;
00985 exit(-1) ;
00986 }
00987
00988 for( ii=0 ; ii < sizeof(mesg)/sizeof(char *) ; ii++ ){
00989 printf( " %s\n" , mesg[ii] );
00990 }
00991 exit(0) ;
00992 }
00993
00994
00995
00996
00997 int main( int argc , char *argv[] )
00998 {
00999 line_opt opt ;
01000 THD_3dim_dataset * new_dset;
01001 Boolean ok;
01002
01003
01004
01005 printf ("\n\n");
01006 printf ("Program: %s \n", PROGRAM_NAME);
01007 printf ("Author: %s \n", PROGRAM_AUTHOR);
01008 printf ("Initial Release: %s \n", PROGRAM_INITIAL);
01009 printf ("Latest Revision: %s \n", PROGRAM_LATEST);
01010 printf ("\n");
01011
01012
01013
01014
01015 { int new_argc ; char ** new_argv ;
01016 addto_args( argc , argv , &new_argc , &new_argv ) ;
01017 if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
01018 }
01019
01020
01021
01022 get_line_opt( argc , argv , &opt ) ;
01023
01024
01025 new_dset = fim3d_fimmer_compute (opt.dset, opt.idts, opt.ortts,
01026 opt.first_im, opt.prefix_name,
01027 opt.max_percent);
01028
01029
01030 tross_Copy_History( opt.dset , new_dset ) ;
01031 tross_Make_History( PROGRAM_NAME , argc , argv , new_dset ) ;
01032
01033
01034 ok = THD_write_3dim_dataset ("", opt.prefix_name, new_dset, TRUE);
01035 if (!ok) Syntax ("Failure to write functional data set.");
01036
01037
01038 THD_delete_3dim_dataset (new_dset, FALSE);
01039
01040 return (0);
01041 }
01042
01043