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 #define PROGRAM_NAME "3dfim+"
00033 #define PROGRAM_AUTHOR "B. Douglas Ward"
00034 #define PROGRAM_INITIAL "28 April 2000"
00035 #define PROGRAM_LATEST "29 October 2004"
00036
00037
00038
00039 #define MAX_FILES 20
00040
00041 #define RA_error FIM_error
00042
00043
00044
00045 #include "mrilib.h"
00046 #include "matrix.h"
00047
00048 #include "fim+.c"
00049
00050
00051
00052 typedef struct FIM_options
00053 {
00054 int NFirst;
00055 int NLast;
00056 int N;
00057 int polort;
00058 int num_ortts;
00059 int num_idealts;
00060 int q;
00061 int p;
00062
00063
00064 float fim_thr;
00065 float cdisp;
00066
00067 char * input_filename;
00068 char * mask_filename;
00069 char * input1D_filename;
00070
00071 int num_ort_files;
00072 char * ort_filename[MAX_FILES];
00073 int num_ideal_files;
00074 char * ideal_filename[MAX_FILES];
00075 char * bucket_filename;
00076
00077 int output_type[MAX_OUTPUT_TYPE];
00078
00079 } FIM_options;
00080
00081
00082
00083
00084
00085
00086
00087 void extract_ts_array
00088 (
00089 THD_3dim_dataset * dset_time,
00090 int iv,
00091 float * ts_array
00092 );
00093
00094
00095
00096
00097
00098
00099 void FIM_error (char * message)
00100 {
00101 fprintf (stderr, "%s Error: %s \n", PROGRAM_NAME, message);
00102 exit(1);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111 void display_help_menu()
00112 {
00113 printf (
00114 "Program to calculate the cross-correlation of an ideal reference waveform \n"
00115 "with the measured FMRI time series for each voxel. \n"
00116 " \n"
00117 "Usage: \n"
00118 "3dfim+ \n"
00119 "-input fname fname = filename of input 3d+time dataset \n"
00120 "[-input1D dname] dname = filename of single (fMRI) .1D time series \n"
00121 "[-mask mname] mname = filename of 3d mask dataset \n"
00122 "[-nfirst fnum] fnum = number of first dataset image to use in \n"
00123 " the cross-correlation procedure. (default = 0) \n"
00124 "[-nlast lnum] lnum = number of last dataset image to use in \n"
00125 " the cross-correlation procedure. (default = last) \n"
00126 "[-polort pnum] pnum = degree of polynomial corresponding to the \n"
00127 " baseline model (pnum = 0, 1, etc.) \n"
00128 " (default: pnum = 1) \n"
00129 "[-fim_thr p] p = fim internal mask threshold value (0 <= p <= 1) \n"
00130 " (default: p = 0.0999) \n"
00131 "[-cdisp cval] Write (to screen) results for those voxels \n"
00132 " whose correlation stat. > cval (0 <= cval <= 1) \n"
00133 " (default: disabled) \n"
00134 "[-ort_file sname] sname = input ort time series file name \n"
00135 "-ideal_file rname rname = input ideal time series file name \n"
00136 " \n"
00137 " Note: The -ort_file and -ideal_file commands may be used \n"
00138 " more than once. \n"
00139 " Note: If files sname or rname contain multiple columns, \n"
00140 " then ALL columns will be used as ort or ideal \n"
00141 " time series. However, individual columns or \n"
00142 " a subset of columns may be selected using a file \n"
00143 " name specification like 'fred.1D[0,3,5]', which \n"
00144 " indicates that only columns #0, #3, and #5 will \n"
00145 " be used for input. \n"
00146 );
00147
00148 printf("\n"
00149 "[-out param] Flag to output the specified parameter, where \n"
00150 " the string 'param' may be any one of the following: \n"
00151 " \n"
00152 "%12s L.S. fit coefficient for Best Ideal \n"
00153 "%12s Index number for Best Ideal \n"
00154 "%12s P-P amplitude of signal response / Baseline \n"
00155 "%12s Average of baseline model response \n"
00156 "%12s Best Ideal product-moment correlation coefficient \n"
00157 "%12s P-P amplitude of signal response / Average \n"
00158 "%12s Baseline + average of signal response \n"
00159 "%12s P-P amplitude of signal response / Topline \n"
00160 "%12s Baseline + P-P amplitude of signal response \n"
00161 "%12s Std. Dev. of residuals from best fit \n"
00162 "%9sAll This specifies all of the above parameters \n"
00163 "%12s Spearman correlation coefficient \n"
00164 "%12s Quadrant correlation coefficient \n"
00165 " \n"
00166 " Note: Multiple '-out' commands may be used. \n"
00167 " Note: If a parameter name contains imbedded spaces, the \n"
00168 " entire parameter name must be enclosed by quotes, \n"
00169 " e.g., -out '%8s' \n"
00170 " \n"
00171 "[-bucket bprefix] Create one AFNI 'bucket' dataset containing the \n"
00172 " parameters of interest, as specified by the above \n"
00173 " '-out' commands. \n"
00174 " The output 'bucket' dataset is written to a file \n"
00175 " with the prefix name bprefix. \n"
00176 ,
00177 OUTPUT_TYPE_name[FIM_FitCoef],
00178 OUTPUT_TYPE_name[FIM_BestIndex],
00179 OUTPUT_TYPE_name[FIM_PrcntChange],
00180 OUTPUT_TYPE_name[FIM_Baseline],
00181 OUTPUT_TYPE_name[FIM_Correlation],
00182 OUTPUT_TYPE_name[FIM_PrcntFromAve],
00183 OUTPUT_TYPE_name[FIM_Average],
00184 OUTPUT_TYPE_name[FIM_PrcntFromTop],
00185 OUTPUT_TYPE_name[FIM_Topline],
00186 OUTPUT_TYPE_name[FIM_SigmaResid],
00187 "",
00188 OUTPUT_TYPE_name[FIM_SpearmanCC],
00189 OUTPUT_TYPE_name[FIM_QuadrantCC],
00190 OUTPUT_TYPE_name[FIM_FitCoef]
00191 );
00192
00193 exit(0);
00194 }
00195
00196
00197
00198
00199
00200
00201
00202 void initialize_options
00203 (
00204 FIM_options * option_data
00205 )
00206
00207 {
00208 int is;
00209
00210
00211
00212 option_data->NFirst = 0;
00213 option_data->NLast = 32767;
00214 option_data->N = 0;
00215 option_data->polort = 1;
00216 option_data->num_ortts = 0;
00217 option_data->num_idealts = 0;
00218 option_data->q = 0;
00219 option_data->p = 0;
00220
00221 option_data->fim_thr = 0.0999;
00222 option_data->cdisp = -1.0;
00223
00224 option_data->num_ort_files = 0;
00225 option_data->num_ideal_files = 0;
00226
00227
00228
00229 for (is = 0; is < MAX_OUTPUT_TYPE; is++)
00230 option_data->output_type[is] = 0;
00231
00232
00233
00234 option_data->input_filename = NULL;
00235 option_data->mask_filename = NULL;
00236 option_data->input1D_filename = NULL;
00237 option_data->bucket_filename = NULL;
00238
00239 for (is = 0; is < MAX_FILES; is++)
00240 {
00241 option_data->ort_filename[is] = NULL;
00242 option_data->ideal_filename[is] = NULL;
00243 }
00244
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 void get_options
00254 (
00255 int argc,
00256 char ** argv,
00257 FIM_options * option_data
00258 )
00259
00260 {
00261 int nopt = 1;
00262 int ival, index;
00263 float fval;
00264 char message[THD_MAX_NAME];
00265 int k;
00266
00267
00268
00269 if (argc < 2 || strcmp(argv[1], "-help") == 0) display_help_menu();
00270
00271
00272
00273 AFNI_logger (PROGRAM_NAME,argc,argv);
00274
00275
00276
00277 initialize_options (option_data);
00278
00279
00280
00281 while (nopt < argc )
00282 {
00283
00284
00285 if (strcmp(argv[nopt], "-input") == 0)
00286 {
00287 nopt++;
00288 if (nopt >= argc) FIM_error ("need argument after -input ");
00289 option_data->input_filename = malloc (sizeof(char)*THD_MAX_NAME);
00290 MTEST (option_data->input_filename);
00291 strcpy (option_data->input_filename, argv[nopt]);
00292 nopt++;
00293 continue;
00294 }
00295
00296
00297
00298 if (strcmp(argv[nopt], "-mask") == 0)
00299 {
00300 nopt++;
00301 if (nopt >= argc) FIM_error ("need argument after -mask ");
00302 option_data->mask_filename = malloc (sizeof(char)*THD_MAX_NAME);
00303 MTEST (option_data->mask_filename);
00304 strcpy (option_data->mask_filename, argv[nopt]);
00305 nopt++;
00306 continue;
00307 }
00308
00309
00310
00311 if (strcmp(argv[nopt], "-input1D") == 0)
00312 {
00313 nopt++;
00314 if (nopt >= argc) FIM_error ("need argument after -input1D ");
00315 option_data->input1D_filename =
00316 malloc (sizeof(char)*THD_MAX_NAME);
00317 MTEST (option_data->input1D_filename);
00318 strcpy (option_data->input1D_filename, argv[nopt]);
00319 nopt++;
00320 continue;
00321 }
00322
00323
00324
00325 if (strcmp(argv[nopt], "-nfirst") == 0)
00326 {
00327 nopt++;
00328 if (nopt >= argc) FIM_error ("need argument after -nfirst ");
00329 sscanf (argv[nopt], "%d", &ival);
00330 if (ival < 0)
00331 FIM_error ("illegal argument after -nfirst ");
00332 option_data->NFirst = ival;
00333 nopt++;
00334 continue;
00335 }
00336
00337
00338
00339 if (strcmp(argv[nopt], "-nlast") == 0)
00340 {
00341 nopt++;
00342 if (nopt >= argc) FIM_error ("need argument after -nlast ");
00343 sscanf (argv[nopt], "%d", &ival);
00344 if (ival < 0)
00345 FIM_error ("illegal argument after -nlast ");
00346 option_data->NLast = ival;
00347 nopt++;
00348 continue;
00349 }
00350
00351
00352
00353 if (strcmp(argv[nopt], "-polort") == 0)
00354 {
00355 nopt++;
00356 if (nopt >= argc) FIM_error ("need argument after -polort ");
00357 sscanf (argv[nopt], "%d", &ival);
00358
00359 #undef PMAX
00360 #ifdef USE_LEGENDRE
00361 # define PMAX 19
00362 #else
00363 # define PMAX 2
00364 #endif
00365 if ((ival < 0) || (ival > PMAX))
00366 FIM_error ("illegal argument after -polort ");
00367
00368 #ifdef USE_LEGENDRE
00369 if( ival > 2 )
00370 fprintf(stderr,
00371 "** WARNING: -polort > 2 is a new untested option: 29 Mar 2005\n") ;
00372 #endif
00373
00374 option_data->polort = ival;
00375 nopt++;
00376 continue;
00377 }
00378
00379
00380
00381 if (strcmp(argv[nopt], "-fim_thr") == 0)
00382 {
00383 nopt++;
00384 if (nopt >= argc) FIM_error ("need argument after -fim_thr ");
00385 sscanf (argv[nopt], "%f", &fval);
00386 if ((fval < 0.0) || (fval > 1.0))
00387 FIM_error ("illegal argument after -fim_thr ");
00388 option_data->fim_thr = fval;
00389 nopt++;
00390 continue;
00391 }
00392
00393
00394
00395 if (strcmp(argv[nopt], "-cdisp") == 0)
00396 {
00397 nopt++;
00398 if (nopt >= argc) FIM_error ("need argument after -cdisp ");
00399 sscanf (argv[nopt], "%f", &fval);
00400 if ((fval < 0.0) || (fval > 1.0))
00401 FIM_error ("illegal argument after -cdisp ");
00402 option_data->cdisp = fval;
00403 nopt++;
00404 continue;
00405 }
00406
00407
00408
00409 if (strcmp(argv[nopt], "-ort_file") == 0)
00410 {
00411 nopt++;
00412 if (nopt >= argc) FIM_error ("need argument after -ort_file");
00413
00414 k = option_data->num_ort_files;
00415 if (k+1 > MAX_FILES)
00416 {
00417 sprintf (message, "Too many ( > %d ) ort time series files. ",
00418 MAX_FILES);
00419 FIM_error (message);
00420 }
00421
00422 option_data->ort_filename[k]
00423 = malloc (sizeof(char)*THD_MAX_NAME);
00424 MTEST (option_data->ort_filename[k]);
00425 strcpy (option_data->ort_filename[k], argv[nopt]);
00426 option_data->num_ort_files++;
00427 nopt++;
00428 continue;
00429 }
00430
00431
00432
00433 if (strcmp(argv[nopt], "-ideal_file") == 0)
00434 {
00435 nopt++;
00436 if (nopt >= argc) FIM_error ("need argument after -ideal_file");
00437
00438 k = option_data->num_ideal_files;
00439 if (k+1 > MAX_FILES)
00440 {
00441 sprintf (message, "Too many ( > %d ) ideal time series files. ",
00442 MAX_FILES);
00443 FIM_error (message);
00444 }
00445
00446 option_data->ideal_filename[k]
00447 = malloc (sizeof(char)*THD_MAX_NAME);
00448 MTEST (option_data->ideal_filename[k]);
00449 strcpy (option_data->ideal_filename[k], argv[nopt]);
00450 option_data->num_ideal_files++;
00451 nopt++;
00452 continue;
00453 }
00454
00455
00456
00457 if (strcmp(argv[nopt], "-out") == 0)
00458 {
00459 nopt++;
00460 if (nopt >= argc) FIM_error ("need argument after -out ");
00461 for (ival = 0; ival < MAX_OUTPUT_TYPE; ival++)
00462 if (strcmp(argv[nopt], OUTPUT_TYPE_name[ival]) == 0) break;
00463 if (ival < MAX_OUTPUT_TYPE)
00464 {
00465 option_data->output_type[ival] = 1;
00466 nopt++;
00467 continue;
00468 }
00469 else if (strcmp(argv[nopt], "All") == 0)
00470 {
00471 for (ival = 0; ival < MAX_OUTPUT_TYPE-2; ival++)
00472 option_data->output_type[ival] = 1;
00473 nopt++;
00474 continue;
00475 }
00476 else
00477 {
00478 sprintf(message,"Unrecognized output type: %s\n", argv[nopt]);
00479 FIM_error (message);
00480 }
00481 }
00482
00483
00484
00485 if (strcmp(argv[nopt], "-bucket") == 0)
00486 {
00487 nopt++;
00488 if (nopt >= argc) FIM_error ("need file prefixname after -bucket ");
00489 option_data->bucket_filename = malloc (sizeof(char)*THD_MAX_NAME);
00490 MTEST (option_data->bucket_filename);
00491 strcpy (option_data->bucket_filename, argv[nopt]);
00492 nopt++;
00493 continue;
00494 }
00495
00496
00497
00498 sprintf(message,"Unrecognized command line option: %s\n", argv[nopt]);
00499 FIM_error (message);
00500
00501 }
00502
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512 float * read_one_time_series
00513 (
00514 char * ts_filename,
00515 int * ts_length
00516 )
00517
00518 {
00519 char message[THD_MAX_NAME];
00520 char * cpt;
00521 char subv[THD_MAX_NAME];
00522 MRI_IMAGE * im, * flim;
00523
00524 float * far;
00525 int nx;
00526 int ny;
00527 int iy;
00528 int ipt;
00529 float * ts_data;
00530
00531
00532
00533 flim = mri_read_1D(ts_filename) ;
00534 if (flim == NULL)
00535 {
00536 sprintf (message, "Unable to read time series file: %s", ts_filename);
00537 FIM_error (message);
00538 }
00539
00540
00541
00542 far = MRI_FLOAT_PTR(flim);
00543 nx = flim->nx;
00544 ny = flim->ny; iy = 0 ;
00545 if( ny > 1 ){
00546 fprintf(stderr,"WARNING: time series %s has %d columns\n",ts_filename,ny);
00547 }
00548
00549
00550
00551 *ts_length = nx;
00552 ts_data = (float *) malloc (sizeof(float) * nx);
00553 MTEST (ts_data);
00554 for (ipt = 0; ipt < nx; ipt++)
00555 ts_data[ipt] = far[ipt + iy*nx];
00556
00557
00558 mri_free (flim); flim = NULL;
00559
00560 return (ts_data);
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570 MRI_IMAGE * read_time_series
00571 (
00572 char * ts_filename,
00573 int ** column_list
00574 )
00575
00576 {
00577 char message[THD_MAX_NAME];
00578 char * cpt;
00579 char filename[THD_MAX_NAME];
00580 char subv[THD_MAX_NAME];
00581 MRI_IMAGE * im, * flim;
00582
00583 float * far;
00584 int nx;
00585 int ny;
00586
00587
00588
00589 flim = mri_read_1D(ts_filename) ;
00590 if (flim == NULL)
00591 {
00592 sprintf (message, "Unable to read time series file: %s", ts_filename);
00593 FIM_error (message);
00594 }
00595
00596
00597
00598 far = MRI_FLOAT_PTR(flim);
00599 nx = flim->nx;
00600 ny = flim->ny;
00601 *column_list = NULL;
00602
00603 return (flim);
00604 }
00605
00606
00607
00608
00609
00610
00611
00612 void read_input_data
00613 (
00614 FIM_options * option_data,
00615 THD_3dim_dataset ** dset_time,
00616 THD_3dim_dataset ** mask_dset,
00617 float ** fmri_data,
00618 int * fmri_length,
00619 MRI_IMAGE ** ort_array,
00620 int ** ort_list,
00621 MRI_IMAGE ** ideal_array,
00622 int ** ideal_list
00623 )
00624
00625 {
00626 char message[THD_MAX_NAME];
00627
00628 int num_ort_files;
00629 int num_ideal_files;
00630 int is;
00631 int polort;
00632 int num_ortts;
00633 int num_idealts;
00634 int q;
00635 int p;
00636
00637
00638
00639
00640 polort = option_data->polort;
00641 num_ort_files = option_data->num_ort_files;
00642 num_ideal_files = option_data->num_ideal_files;
00643
00644
00645
00646 if (option_data->input1D_filename != NULL)
00647 {
00648
00649 *fmri_data = read_one_time_series (option_data->input1D_filename,
00650 fmri_length);
00651 if (*fmri_data == NULL)
00652 {
00653 sprintf (message, "Unable to read time series file: %s",
00654 option_data->input1D_filename);
00655 FIM_error (message);
00656 }
00657 *dset_time = NULL;
00658 }
00659
00660 else if (option_data->input_filename != NULL)
00661 {
00662
00663 *dset_time = THD_open_one_dataset (option_data->input_filename);
00664 if (!ISVALID_3DIM_DATASET(*dset_time))
00665 {
00666 sprintf (message, "Unable to open data file: %s",
00667 option_data->input_filename);
00668 FIM_error (message);
00669 }
00670 THD_load_datablock ((*dset_time)->dblk);
00671
00672 if (option_data->mask_filename != NULL)
00673 {
00674
00675 *mask_dset = THD_open_dataset (option_data->mask_filename);
00676 if (!ISVALID_3DIM_DATASET(*mask_dset))
00677 {
00678 sprintf (message, "Unable to open mask file: %s",
00679 option_data->mask_filename);
00680 FIM_error (message);
00681 }
00682 THD_load_datablock ((*mask_dset)->dblk);
00683 }
00684 }
00685 else
00686 FIM_error ("Must specify input measurement data");
00687
00688
00689
00690 for (is = 0; is < num_ort_files; is++)
00691 {
00692 ort_array[is] = read_time_series (option_data->ort_filename[is],
00693 &(ort_list[is]));
00694
00695 if (ort_array[is] == NULL)
00696 {
00697 sprintf (message, "Unable to read ort time series file: %s",
00698 option_data->ort_filename[is]);
00699 FIM_error (message);
00700 }
00701 }
00702
00703
00704
00705 for (is = 0; is < num_ideal_files; is++)
00706 {
00707 ideal_array[is] = read_time_series (option_data->ideal_filename[is],
00708 &(ideal_list[is]));
00709
00710 if (ideal_array[is] == NULL)
00711 {
00712 sprintf (message, "Unable to read ideal time series file: %s",
00713 option_data->ideal_filename[is]);
00714 FIM_error (message);
00715 }
00716 }
00717
00718
00719
00720 num_ortts = 0;
00721 for (is = 0; is < num_ort_files; is++)
00722 {
00723 if (ort_list[is] == NULL)
00724 num_ortts += ort_array[is]->ny;
00725 else
00726 num_ortts += ort_list[is][0];
00727 }
00728 q = polort + 1 + num_ortts;
00729
00730 num_idealts = 0;
00731 for (is = 0; is < num_ideal_files; is++)
00732 {
00733 if (ideal_list[is] == NULL)
00734 num_idealts += ideal_array[is]->ny;
00735 else
00736 num_idealts += ideal_list[is][0];
00737 }
00738 p = q + num_idealts;
00739
00740 option_data->num_ortts = num_ortts;
00741 option_data->num_idealts = num_idealts;
00742 option_data->q = q;
00743 option_data->p = p;
00744
00745 }
00746
00747
00748
00749
00750
00751
00752
00753 void check_one_output_file
00754 (
00755 THD_3dim_dataset * dset_time,
00756 char * filename
00757 )
00758
00759 {
00760 char message[THD_MAX_NAME];
00761 THD_3dim_dataset * new_dset=NULL;
00762 int ierror;
00763
00764
00765
00766 new_dset = EDIT_empty_copy( dset_time ) ;
00767
00768
00769 ierror = EDIT_dset_items( new_dset ,
00770 ADN_prefix , filename ,
00771 ADN_label1 , filename ,
00772 ADN_self_name , filename ,
00773 ADN_type , ISHEAD(dset_time) ? HEAD_FUNC_TYPE :
00774 GEN_FUNC_TYPE ,
00775 ADN_none ) ;
00776
00777 if( ierror > 0 )
00778 {
00779 sprintf (message,
00780 "*** %d errors in attempting to create output dataset!\n",
00781 ierror);
00782 FIM_error (message);
00783 }
00784
00785 if( THD_is_file(new_dset->dblk->diskptr->header_name) )
00786 {
00787 sprintf (message,
00788 "Output dataset file %s already exists "
00789 " -- cannot continue!\a\n",
00790 new_dset->dblk->diskptr->header_name);
00791 FIM_error (message);
00792 }
00793
00794
00795 THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
00796
00797 }
00798
00799
00800
00801
00802
00803
00804
00805 void check_output_files
00806 (
00807 FIM_options * option_data,
00808 THD_3dim_dataset * dset_time
00809 )
00810
00811 {
00812
00813 if ((option_data->bucket_filename != NULL)
00814 && (option_data->input1D_filename == NULL))
00815 check_one_output_file (dset_time, option_data->bucket_filename);
00816
00817 }
00818
00819
00820
00821
00822
00823
00824
00825 void check_for_valid_inputs
00826 (
00827 FIM_options * option_data,
00828 THD_3dim_dataset * dset_time,
00829 THD_3dim_dataset * mask_dset,
00830 int fmri_length,
00831 MRI_IMAGE ** ort_array,
00832 MRI_IMAGE ** ideal_array
00833 )
00834
00835 {
00836 char message[THD_MAX_NAME];
00837 int is;
00838 int num_ort_files;
00839 int num_ideal_files;
00840 int num_idealts;
00841 int nt;
00842 int NFirst;
00843 int NLast;
00844 int N;
00845
00846
00847
00848 if (option_data->input1D_filename != NULL)
00849 nt = fmri_length;
00850 else
00851 nt = DSET_NUM_TIMES (dset_time);
00852
00853 num_ort_files = option_data->num_ort_files;
00854 num_ideal_files = option_data->num_ideal_files;
00855 num_idealts = option_data->num_idealts;
00856
00857
00858 NFirst = option_data->NFirst;
00859
00860 NLast = option_data->NLast;
00861 if (NLast > nt-1) NLast = nt-1;
00862 option_data->NLast = NLast;
00863
00864 N = NLast - NFirst + 1;
00865 option_data->N = N;
00866
00867
00868
00869 if (num_idealts < 1) FIM_error ("No ideal time series?");
00870 if (num_idealts < 2) option_data->output_type[FIM_BestIndex] = 0;
00871
00872
00873
00874 if (mask_dset != NULL)
00875 {
00876 if ( (DSET_NX(dset_time) != DSET_NX(mask_dset))
00877 || (DSET_NY(dset_time) != DSET_NY(mask_dset))
00878 || (DSET_NZ(dset_time) != DSET_NZ(mask_dset)) )
00879 {
00880 sprintf (message, "%s and %s have incompatible dimensions",
00881 option_data->input_filename, option_data->mask_filename);
00882 FIM_error (message);
00883 }
00884
00885 if (DSET_NVALS(mask_dset) != 1 )
00886 FIM_error ("Must specify 1 sub-brick from mask dataset");
00887 }
00888
00889
00890
00891 for (is = 0; is < num_ort_files; is++)
00892 {
00893 if (ort_array[is]->nx < NLast+1)
00894 {
00895 sprintf (message, "Input ort time series file %s is too short",
00896 option_data->ort_filename[is]);
00897 FIM_error (message);
00898 }
00899 }
00900
00901
00902
00903 for (is = 0; is < num_ideal_files; is++)
00904 {
00905 if (ideal_array[is]->nx < NLast+1)
00906 {
00907 sprintf (message, "Input ideal time series file %s is too short",
00908 option_data->ideal_filename[is]);
00909 FIM_error (message);
00910 }
00911 }
00912
00913
00914
00915 check_output_files (option_data, dset_time);
00916
00917 }
00918
00919
00920
00921
00922
00923
00924
00925 void allocate_memory
00926 (
00927 FIM_options * option_data,
00928 THD_3dim_dataset * dset,
00929 float *** fim_params_vol
00930 )
00931
00932 {
00933 int ip;
00934 int nxyz;
00935 int ixyz;
00936
00937
00938
00939 nxyz = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz;
00940
00941
00942
00943 *fim_params_vol = (float **) malloc (sizeof(float *) * MAX_OUTPUT_TYPE);
00944 MTEST(*fim_params_vol);
00945
00946 for (ip = 0; ip < MAX_OUTPUT_TYPE; ip++)
00947 {
00948 if (option_data->output_type[ip])
00949 {
00950 (*fim_params_vol)[ip] = (float *) malloc (sizeof(float) * nxyz);
00951 MTEST((*fim_params_vol)[ip]);
00952 for (ixyz = 0; ixyz < nxyz; ixyz++)
00953 {
00954 (*fim_params_vol)[ip][ixyz] = 0.0;
00955 }
00956 }
00957 else
00958 (*fim_params_vol)[ip] = NULL;
00959 }
00960
00961 }
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971 void initialize_program
00972 (
00973 int argc,
00974 char ** argv,
00975 FIM_options ** option_data,
00976 THD_3dim_dataset ** dset_time,
00977 THD_3dim_dataset ** mask_dset,
00978 float ** fmri_data,
00979 int * fmri_length,
00980 MRI_IMAGE ** ort_array,
00981 int ** ort_list,
00982 MRI_IMAGE ** ideal_array,
00983 int ** ideal_list,
00984 float *** fim_params_vol
00985 )
00986
00987 {
00988
00989 *option_data = (FIM_options *) malloc (sizeof(FIM_options));
00990
00991
00992
00993 get_options (argc, argv, *option_data);
00994
00995
00996
00997 read_input_data (*option_data, dset_time, mask_dset, fmri_data, fmri_length,
00998 ort_array, ort_list, ideal_array, ideal_list);
00999
01000
01001
01002 check_for_valid_inputs (*option_data, *dset_time, *mask_dset,
01003 *fmri_length, ort_array, ideal_array);
01004
01005
01006
01007 if ((*option_data)->input1D_filename == NULL)
01008 allocate_memory (*option_data, *dset_time, fim_params_vol);
01009
01010 }
01011
01012
01013
01014
01015
01016
01017
01018 void extract_ts_array
01019 (
01020 THD_3dim_dataset * dset_time,
01021 int iv,
01022 float * ts_array
01023 )
01024
01025 {
01026 MRI_IMAGE * im;
01027 float * ar;
01028 int ts_length;
01029 int it;
01030
01031
01032
01033 im = THD_extract_series (iv, dset_time, 0);
01034
01035
01036
01037 if (im == NULL) FIM_error ("Unable to extract data from 3d+time dataset");
01038
01039
01040
01041 ts_length = DSET_NUM_TIMES (dset_time);
01042 ar = MRI_FLOAT_PTR (im);
01043 for (it = 0; it < ts_length; it++)
01044 {
01045 ts_array[it] = ar[it];
01046 }
01047
01048
01049
01050 mri_free (im); im = NULL;
01051
01052 }
01053
01054
01055
01056
01057
01058
01059
01060 void save_voxel
01061 (
01062 int iv,
01063 float * fim_params,
01064 float ** fim_params_vol
01065 )
01066
01067 {
01068 int ip;
01069
01070
01071
01072 for (ip = 0; ip < MAX_OUTPUT_TYPE; ip++)
01073 {
01074 if (fim_params_vol[ip] != NULL)
01075 fim_params_vol[ip][iv] = fim_params[ip];
01076 }
01077
01078 }
01079
01080
01081
01082
01083
01084
01085
01086 float set_fim_thr_level
01087 (
01088 int NFirst,
01089 float fim_thr,
01090 THD_3dim_dataset * dset
01091 )
01092
01093 {
01094 int nt;
01095 int nxyz;
01096 int ixyz;
01097 double sum;
01098 float fthr;
01099 float * ts_array = NULL;
01100
01101
01102
01103 nxyz = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz;
01104 nt = DSET_NUM_TIMES (dset);
01105
01106 ts_array = (float *) malloc (sizeof(float) * nt);
01107 MTEST (ts_array);
01108
01109 sum = 0.0;
01110
01111 for (ixyz = 0; ixyz < nxyz; ixyz++)
01112 {
01113 extract_ts_array (dset, ixyz, ts_array);
01114 sum += fabs(ts_array[NFirst]);
01115 }
01116
01117
01118
01119 fthr = fim_thr * sum / nxyz;
01120
01121
01122 free (ts_array); ts_array = NULL;
01123
01124 return (fthr);
01125 }
01126
01127
01128
01129
01130
01131
01132
01133 void calculate_results
01134 (
01135 FIM_options * option_data,
01136 THD_3dim_dataset * dset,
01137 THD_3dim_dataset * mask,
01138 float * fmri_data,
01139 int fmri_length,
01140 MRI_IMAGE ** ort_array,
01141 int ** ort_list,
01142 MRI_IMAGE ** ideal_array,
01143 int ** ideal_list,
01144 float ** fim_params_vol
01145 )
01146
01147 {
01148 float * ts_array = NULL;
01149 float mask_val[1];
01150 float fthr;
01151
01152 int q;
01153 int p;
01154
01155 int m;
01156 int n;
01157
01158
01159 matrix xdata;
01160 matrix x_base;
01161 matrix xtxinvxt_base;
01162 matrix x_ideal[MAX_FILES];
01163 matrix xtxinvxt_ideal[MAX_FILES];
01164
01165 vector y;
01166
01167 int ixyz;
01168 int nxyz;
01169
01170 int nt;
01171 int NFirst;
01172 int NLast;
01173 int N;
01174
01175 int num_ort_files;
01176 int num_ideal_files;
01177 int polort;
01178 int num_ortts;
01179 int num_idealts;
01180
01181 int i;
01182 int is;
01183 int ilag;
01184 float stddev;
01185 char * label;
01186
01187 float * x_bot = NULL;
01188 float * x_ave = NULL;
01189 float * x_top = NULL;
01190 int * good_list = NULL;
01191 float ** rarray = NULL;
01192 float FimParams[MAX_OUTPUT_TYPE];
01193
01194
01195
01196 matrix_initialize (&xdata);
01197 matrix_initialize (&x_base);
01198 matrix_initialize (&xtxinvxt_base);
01199 for (is =0; is < MAX_FILES; is++)
01200 {
01201 matrix_initialize (&x_ideal[is]);
01202 matrix_initialize (&xtxinvxt_ideal[is]);
01203 }
01204 vector_initialize (&y);
01205
01206
01207
01208 if (option_data->input1D_filename != NULL)
01209 {
01210 nxyz = 1;
01211 nt = fmri_length;
01212 }
01213 else
01214 {
01215 nxyz = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz;
01216 nt = DSET_NUM_TIMES (dset);
01217 }
01218
01219 NFirst = option_data->NFirst;
01220 NLast = option_data->NLast;
01221 N = option_data->N;
01222 p = option_data->p;
01223 q = option_data->q;
01224
01225 polort = option_data->polort;
01226 num_idealts = option_data->num_idealts;
01227 num_ort_files = option_data->num_ort_files;
01228 num_ideal_files = option_data->num_ideal_files;
01229
01230
01231
01232 ts_array = (float *) malloc (sizeof(float) * nt); MTEST (ts_array);
01233 x_bot = (float *) malloc (sizeof(float) * p); MTEST (x_bot);
01234 x_ave = (float *) malloc (sizeof(float) * p); MTEST (x_ave);
01235 x_top = (float *) malloc (sizeof(float) * p); MTEST (x_top);
01236 good_list = (int *) malloc (sizeof(int) * N); MTEST (good_list);
01237 rarray = (float **) malloc (sizeof(float *) * num_idealts); MTEST (rarray);
01238
01239
01240
01241 N = init_indep_var_matrix (q, p, NFirst, N, polort,
01242 num_ort_files, num_ideal_files,
01243 ort_array, ort_list, ideal_array, ideal_list,
01244 x_bot, x_ave, x_top, good_list, &xdata);
01245 option_data->N = N;
01246
01247
01248
01249 if (option_data->input1D_filename == NULL)
01250 fthr = set_fim_thr_level (good_list[0]+NFirst, option_data->fim_thr, dset);
01251
01252
01253
01254 init_regression_analysis (q, p, N, num_idealts, xdata, &x_base,
01255 &xtxinvxt_base, x_ideal, xtxinvxt_ideal, rarray);
01256
01257
01258 vector_create (N, &y);
01259
01260
01261
01262 for (ixyz = 0; ixyz < nxyz; ixyz++)
01263 {
01264
01265 if (mask != NULL)
01266 {
01267 extract_ts_array (mask, ixyz, mask_val);
01268 if (mask_val[0] == 0.0) continue;
01269 }
01270
01271
01272
01273 if (option_data->input1D_filename != NULL)
01274 {
01275 for (i = 0; i < N; i++)
01276 y.elts[i] = fmri_data[good_list[i]+NFirst];
01277 }
01278 else
01279 {
01280 extract_ts_array (dset, ixyz, ts_array);
01281 if (fabs(ts_array[good_list[0]+NFirst]) < fthr)
01282 continue;
01283 for (i = 0; i < N; i++)
01284 y.elts[i] = ts_array[good_list[i]+NFirst];
01285 }
01286
01287
01288
01289 regression_analysis (N, q, num_idealts,
01290 x_base, xtxinvxt_base, x_ideal, xtxinvxt_ideal,
01291 y, x_bot, x_ave, x_top, rarray,
01292 option_data->output_type, FimParams);
01293
01294
01295
01296 if (option_data->input1D_filename == NULL)
01297 save_voxel (ixyz, FimParams, fim_params_vol);
01298
01299
01300
01301 if ( ((fabs(FimParams[FIM_Correlation]) > option_data->cdisp)
01302 && (option_data->cdisp >= 0.0))
01303 || (option_data->input1D_filename != NULL) )
01304 {
01305 printf ("\n\nResults for Voxel #%d: \n", ixyz);
01306 report_results (option_data->output_type, FimParams, &label);
01307 printf ("%s \n", label);
01308 }
01309
01310 }
01311
01312
01313
01314 vector_destroy (&y);
01315 for (is = 0; is < MAX_FILES; is++)
01316 {
01317 matrix_destroy (&xtxinvxt_ideal[is]);
01318 matrix_destroy (&x_ideal[is]);
01319 }
01320 matrix_destroy (&xtxinvxt_base);
01321 matrix_destroy (&x_base);
01322 matrix_destroy (&xdata);
01323
01324
01325
01326 free (ts_array); ts_array = NULL;
01327 free (x_bot); x_bot = NULL;
01328 free (x_ave); x_ave = NULL;
01329 free (x_top); x_top = NULL;
01330 free (good_list); good_list = NULL;
01331 for (is = 0; is < num_idealts; is++)
01332 {
01333 free (rarray[is]); rarray[is] = NULL;
01334 }
01335 free (rarray); rarray = NULL;
01336
01337 }
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 float EDIT_coerce_autoscale_new( int nxyz ,
01352 int itype,void *ivol , int otype,void *ovol )
01353 {
01354 float fac=0.0 , top ;
01355
01356 if( MRI_IS_INT_TYPE(otype) ){
01357 top = MCW_vol_amax( nxyz,1,1 , itype,ivol ) ;
01358 if (top == 0.0) fac = 0.0;
01359 else fac = MRI_TYPE_maxval[otype]/top;
01360 }
01361
01362 EDIT_coerce_scale_type( nxyz , fac , itype,ivol , otype,ovol ) ;
01363 return ( fac );
01364 }
01365
01366
01367
01368
01369
01370
01371
01372 void attach_sub_brick
01373 (
01374 THD_3dim_dataset * new_dset,
01375 int ibrick,
01376 float * volume,
01377 int nxyz,
01378 int brick_type,
01379 char * brick_label,
01380 int nsam,
01381 int nfit,
01382 int nort,
01383 short ** bar
01384 )
01385
01386 {
01387 const float EPSILON = 1.0e-10;
01388 float factor;
01389
01390
01391
01392 bar[ibrick] = (short *) malloc (sizeof(short) * nxyz);
01393 MTEST (bar[ibrick]);
01394 factor = EDIT_coerce_autoscale_new (nxyz, MRI_float, volume,
01395 MRI_short, bar[ibrick]);
01396
01397 if (factor < EPSILON) factor = 0.0;
01398 else factor = 1.0 / factor;
01399
01400
01401
01402 EDIT_BRICK_LABEL (new_dset, ibrick, brick_label);
01403 EDIT_BRICK_FACTOR (new_dset, ibrick, factor);
01404
01405 if (brick_type == FUNC_COR_TYPE)
01406 EDIT_BRICK_TO_FICO (new_dset, ibrick, nsam, nfit, nort);
01407
01408
01409
01410 EDIT_substitute_brick (new_dset, ibrick, MRI_short, bar[ibrick]);
01411
01412 }
01413
01414
01415
01416
01417
01418
01419 void write_bucket_data
01420 (
01421 int argc,
01422 char ** argv,
01423 FIM_options * option_data,
01424 float ** fim_params_vol
01425 )
01426
01427 {
01428 THD_3dim_dataset * old_dset = NULL;
01429 THD_3dim_dataset * new_dset = NULL;
01430 char output_prefix[THD_MAX_NAME];
01431 char output_session[THD_MAX_NAME];
01432 int nbricks;
01433 short ** bar = NULL;
01434
01435 int brick_type;
01436 int brick_coef;
01437 char brick_label[THD_MAX_NAME];
01438
01439 int ierror;
01440 float * volume;
01441
01442 int N;
01443 int q;
01444 int num_idealts;
01445 int ip;
01446 int nxyz;
01447 int ibrick;
01448 int nsam;
01449 int nfit;
01450 int nort;
01451 char label[THD_MAX_NAME];
01452
01453
01454
01455 old_dset = THD_open_one_dataset (option_data->input_filename);
01456
01457
01458
01459 nxyz = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz;
01460 num_idealts = option_data->num_idealts;
01461 q = option_data->q;
01462 N = option_data->N;
01463
01464
01465
01466 nbricks = 0;
01467 for (ip = 0; ip < MAX_OUTPUT_TYPE; ip++)
01468 if (option_data->output_type[ip]) nbricks++;
01469
01470
01471 strcpy (output_prefix, option_data->bucket_filename);
01472 strcpy (output_session, "./");
01473
01474
01475
01476 bar = (short **) malloc (sizeof(short *) * nbricks);
01477 MTEST (bar);
01478
01479
01480
01481 new_dset = EDIT_empty_copy (old_dset);
01482
01483
01484
01485 tross_Copy_History( old_dset , new_dset ) ;
01486 tross_Make_History( PROGRAM_NAME , argc , argv , new_dset ) ;
01487 sprintf (label, "Output prefix: %s", output_prefix);
01488 tross_Append_History ( new_dset, label);
01489
01490
01491
01492 THD_delete_3dim_dataset( old_dset , False ); old_dset = NULL ;
01493
01494
01495
01496
01497 ierror = EDIT_dset_items (new_dset,
01498 ADN_prefix, output_prefix,
01499 ADN_directory_name, output_session,
01500 ADN_type, HEAD_FUNC_TYPE,
01501 ADN_func_type, FUNC_BUCK_TYPE,
01502 ADN_datum_all, MRI_short ,
01503 ADN_ntt, 0,
01504 ADN_nvals, nbricks,
01505 ADN_malloc_type, DATABLOCK_MEM_MALLOC ,
01506 ADN_none ) ;
01507
01508 if( ierror > 0 )
01509 {
01510 fprintf(stderr,
01511 "*** %d errors in attempting to create bucket dataset!\n",
01512 ierror);
01513 exit(1);
01514 }
01515
01516 if (THD_is_file(DSET_HEADNAME(new_dset)))
01517 {
01518 fprintf(stderr,
01519 "*** Output dataset file %s already exists--cannot continue!\n",
01520 DSET_HEADNAME(new_dset));
01521 exit(1);
01522 }
01523
01524
01525
01526 ibrick = 0;
01527 for (ip = 0; ip < MAX_OUTPUT_TYPE; ip++)
01528 {
01529 if (option_data->output_type[ip] == 0) continue;
01530
01531 strcpy (brick_label, OUTPUT_TYPE_name[ip]);
01532
01533 if (ip == FIM_Correlation)
01534 {
01535 brick_type = FUNC_COR_TYPE;
01536 nsam = N; nort = q;
01537 if (num_idealts > 1) nfit = 2;
01538 else nfit = 1;
01539 }
01540 else if (ip == FIM_SpearmanCC)
01541 {
01542 #if 0
01543 brick_type = FUNC_THR_TYPE;
01544 #else
01545 brick_type = FUNC_COR_TYPE;
01546 #endif
01547 nsam = N; nort = q;
01548 if (num_idealts > 1) nfit = 2;
01549 else nfit = 1;
01550 }
01551 else if (ip == FIM_QuadrantCC)
01552 {
01553 #if 0
01554 brick_type = FUNC_THR_TYPE;
01555 #else
01556 brick_type = FUNC_COR_TYPE;
01557 #endif
01558 nsam = N; nort = q;
01559 if (num_idealts > 1) nfit = 2;
01560 else nfit = 1;
01561 }
01562 else
01563 {
01564 brick_type = FUNC_FIM_TYPE;
01565 nsam = 0; nfit = 0; nort = 0;
01566 }
01567
01568 volume = fim_params_vol[ip];
01569 attach_sub_brick (new_dset, ibrick, volume, nxyz,
01570 brick_type, brick_label, nsam, nfit, nort, bar);
01571
01572 ibrick++;
01573 }
01574
01575
01576
01577 THD_load_statistics (new_dset);
01578 THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
01579 fprintf(stderr,"Wrote bucket dataset ");
01580 fprintf(stderr,"into %s\n", DSET_BRIKNAME(new_dset));
01581
01582
01583
01584 THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
01585
01586 }
01587
01588
01589
01590
01591
01592
01593
01594 void output_results
01595 (
01596 int argc,
01597 char ** argv,
01598 FIM_options * option_data,
01599 float ** fim_params_vol
01600 )
01601
01602 {
01603 int q;
01604 int num_idealts;
01605 int ib;
01606 int is;
01607 int ts_length;
01608 int N;
01609
01610
01611
01612 q = option_data->polort + 1;
01613 num_idealts = option_data->num_idealts;
01614 N = option_data->N;
01615
01616
01617
01618 if (option_data->bucket_filename != NULL)
01619 write_bucket_data (argc, argv, option_data, fim_params_vol);
01620
01621 }
01622
01623
01624
01625
01626 void terminate_program
01627 (
01628 FIM_options ** option_data,
01629 MRI_IMAGE ** ort_array,
01630 int ** ort_list,
01631 MRI_IMAGE ** ideal_array,
01632 int ** ideal_list,
01633 float *** fim_params_vol
01634 )
01635
01636 {
01637 int num_idealts;
01638 int ip;
01639 int is;
01640
01641
01642
01643 num_idealts = (*option_data)->num_idealts;
01644
01645
01646
01647 free (*option_data); *option_data = NULL;
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 if (*fim_params_vol != NULL)
01659 {
01660 for (ip = 0; ip < MAX_OUTPUT_TYPE; ip++)
01661 {
01662 if ((*fim_params_vol)[ip] != NULL)
01663 { free ((*fim_params_vol)[ip]); (*fim_params_vol)[ip] = NULL; }
01664 }
01665
01666 free (*fim_params_vol); *fim_params_vol = NULL;
01667 }
01668
01669 }
01670
01671
01672
01673
01674 int main
01675 (
01676 int argc,
01677 char ** argv
01678 )
01679
01680 {
01681 FIM_options * option_data;
01682 THD_3dim_dataset * dset_time = NULL;
01683 THD_3dim_dataset * mask_dset = NULL;
01684 float * fmri_data = NULL;
01685 int fmri_length;
01686 MRI_IMAGE * ort_array[MAX_FILES];
01687 int * ort_list[MAX_FILES];
01688 MRI_IMAGE * ideal_array[MAX_FILES];
01689 int * ideal_list[MAX_FILES];
01690
01691 float ** fim_params_vol = NULL;
01692
01693
01694
01695
01696 printf ("\n\n");
01697 printf ("Program: %s \n", PROGRAM_NAME);
01698 printf ("Author: %s \n", PROGRAM_AUTHOR);
01699 printf ("Initial Release: %s \n", PROGRAM_INITIAL);
01700 printf ("Latest Revision: %s \n", PROGRAM_LATEST);
01701 printf ("\n");
01702
01703
01704
01705 { int new_argc ; char ** new_argv ;
01706 addto_args( argc , argv , &new_argc , &new_argv ) ;
01707 if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
01708 }
01709
01710
01711
01712 initialize_program (argc, argv, &option_data, &dset_time, &mask_dset,
01713 &fmri_data, &fmri_length,
01714 ort_array, ort_list, ideal_array, ideal_list,
01715 &fim_params_vol);
01716
01717
01718
01719 calculate_results (option_data, dset_time, mask_dset,
01720 fmri_data, fmri_length,
01721 ort_array, ort_list, ideal_array, ideal_list,
01722 fim_params_vol);
01723
01724
01725
01726 if (dset_time != NULL)
01727 { THD_delete_3dim_dataset (dset_time, False); dset_time = NULL; }
01728 if (mask_dset != NULL)
01729 { THD_delete_3dim_dataset (mask_dset, False); mask_dset = NULL; }
01730
01731
01732
01733 if (option_data->input1D_filename == NULL)
01734 output_results (argc, argv, option_data, fim_params_vol);
01735
01736
01737
01738 terminate_program (&option_data,
01739 ort_array, ort_list, ideal_array, ideal_list,
01740 &fim_params_vol);
01741
01742 exit(0);
01743 }
01744
01745
01746
01747
01748
01749
01750
01751
01752