00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #define PROGRAM_NAME "3dFDR"                         
00020 #define PROGRAM_AUTHOR "B. Douglas Ward"                   
00021 #define PROGRAM_INITIAL "31 January 2002" 
00022 #define PROGRAM_LATEST "31 January 2002"    
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 #include "mrilib.h"
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 struct voxel;
00039 
00040 typedef struct voxel
00041 {
00042   int ixyz;                            
00043   float pvalue;                        
00044   struct voxel * next_voxel;           
00045 } voxel;
00046 
00047 
00048 
00049 
00050 
00051 #define  FDR_MAX_LL 10000        
00052 
00053 
00054 static int    FDR_quiet      = 0;      
00055 static int    FDR_list       = 0;      
00056 static float  FDR_mask_thr   = 1.0;    
00057 static float  FDR_cn         = 1.0;    
00058 static int    FDR_nxyz       = 0;      
00059 static int    FDR_nthr       = 0;      
00060 
00061 static char * FDR_input_filename   = NULL;   
00062 static char * FDR_input1D_filename = NULL;   
00063 static char * FDR_mask_filename    = NULL;   
00064 static char * FDR_output_prefix    = NULL;   
00065 
00066 static byte  * FDR_mask = NULL;            
00067 static float * FDR_input1D_data = NULL;    
00068 static voxel * FDR_head_voxel[FDR_MAX_LL]; 
00069 
00070 static char * commandline = NULL;          
00071 static THD_3dim_dataset * FDR_dset = NULL;   
00072 
00073 
00074 
00075 
00076 
00077 
00078 #define DOPEN(ds,name)                                                        \
00079 do{ int pv ; (ds) = THD_open_dataset((name)) ;                                \
00080        if( !ISVALID_3DIM_DATASET((ds)) ){                                     \
00081           fprintf(stderr,"*** Can't open dataset: %s\n",(name)) ; exit(1) ; } \
00082        THD_load_datablock( (ds)->dblk ) ;                                     \
00083        pv = DSET_PRINCIPAL_VALUE((ds)) ;                                      \
00084        if( DSET_ARRAY((ds),pv) == NULL ){                                     \
00085           fprintf(stderr,"*** Can't access data: %s\n",(name)) ; exit(1); }   \
00086        if( DSET_BRICK_TYPE((ds),pv) == MRI_complex ){                         \
00087           fprintf(stderr,"*** Can't use complex data: %s\n",(name)) ; exit(1);\
00088        }     \
00089        break ; } while (0)
00090 
00091 
00092 
00093 
00094 
00095 
00096 #define SUB_POINTER(ds,vv,ind,ptr)                                            \
00097    do{ switch( DSET_BRICK_TYPE((ds),(vv)) ){                                  \
00098          default: fprintf(stderr,"\n*** Illegal datum! ***\n");exit(1);       \
00099             case MRI_short:{ short * fim = (short *) DSET_ARRAY((ds),(vv)) ;  \
00100                             (ptr) = (void *)( fim + (ind) ) ;                 \
00101             } break ;                                                         \
00102             case MRI_byte:{ byte * fim = (byte *) DSET_ARRAY((ds),(vv)) ;     \
00103                             (ptr) = (void *)( fim + (ind) ) ;                 \
00104             } break ;                                                         \
00105             case MRI_float:{ float * fim = (float *) DSET_ARRAY((ds),(vv)) ;  \
00106                              (ptr) = (void *)( fim + (ind) ) ;                \
00107             } break ; } break ; } while(0)
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 void FDR_error (char * message)
00116 {
00117   fprintf (stderr, "%s Error: %s \n", PROGRAM_NAME, message);
00118   exit(1);
00119 }
00120 
00121 
00122 
00123 
00124 
00125 
00126 #define MTEST(ptr) \
00127 if((ptr)==NULL) \
00128 ( FDR_error ("Cannot allocate memory") )
00129      
00130 
00131 
00132 
00133 
00134 
00135 
00136 void FDR_Syntax(void)
00137 {
00138 printf(
00139 "This program implements the False Discovery Rate (FDR) algorithm for       \n"
00140 "thresholding of voxelwise statistics.                                      \n"
00141 "                                                                           \n"
00142 "Program input consists of a functional dataset containing one (or more)    \n"
00143 "statistical sub-bricks.  Output consists of a bucket dataset with one      \n"
00144 "sub-brick for each input sub-brick.  For non-statistical input sub-bricks, \n"
00145 "the output is a copy of the input.  However, statistical input sub-bricks  \n"
00146 "are replaced by their corresponding FDR values, as follows:                \n"
00147 "                                                                           \n"
00148 "For each voxel, the minimum value of q is determined such that             \n"
00149 "                               E(FDR) <= q                                 \n"
00150 "leads to rejection of the null hypothesis in that voxel. Only voxels inside\n"
00151 "the user specified mask will be considered.  These q-values are then mapped\n"
00152 "to z-scores for compatibility with the AFNI statistical threshold display: \n"
00153 "                                                                           \n"
00154 "               stat ==> p-value ==> FDR q-value ==> FDR z-score            \n"
00155 "                                                                           \n"
00156 );
00157 
00158 printf(
00159 "Usage:                                                                     \n"
00160 "  3dFDR                                                                    \n"
00161 "    -input fname       fname = filename of input 3d functional dataset     \n"
00162 "      OR                                                                   \n"
00163 "    -input1D dname     dname = .1D file containing column of p-values      \n"
00164 "                                                                           \n"
00165 "    -mask_file mname   Use mask values from file mname.                    \n"
00166 "                       Note: If file mname contains more than 1 sub-brick, \n"
00167 "                       the mask sub-brick must be specified!               \n"
00168 "                       Default: No mask                                    \n"
00169 "                                                                           \n"
00170 "    -mask_thr m        Only voxels whose corresponding mask value is       \n"
00171 "                       greater than or equal to m in absolute value will   \n"
00172 "                       be considered.  Default: m=1                        \n"
00173 "                                                                           \n"
00174 "                       Constant c(N) depends on assumption about p-values: \n"
00175 "    -cind              c(N) = 1   p-values are independent across N voxels \n"
00176 "    -cdep              c(N) = sum(1/i), i=1,...,N   any joint distribution \n"
00177 "                       Default:  c(N) = 1                                  \n"
00178 "                                                                           \n"
00179 "    -quiet             Flag to suppress screen output                      \n"
00180 "                                                                           \n"
00181 "    -list              Write sorted list of voxel q-values to screen       \n"
00182 "                                                                           \n"
00183 "    -prefix pname      Use 'pname' for the output dataset prefix name.     \n"
00184 "      OR                                                                   \n"
00185 "    -output pname                                                          \n"
00186 "                                                                           \n"
00187 "\n") ;
00188 
00189    printf("\n" MASTER_SHORTHELP_STRING ) ;
00190 
00191    exit(0) ;
00192 
00193 }
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 void read_options ( int argc , char * argv[] )
00203 {
00204   int nopt = 1 ;           
00205   char message[80];        
00206 
00207 
00208   
00209   
00210   while( nopt < argc )
00211     {
00212 
00213       
00214       if (strcmp(argv[nopt], "-input") == 0)
00215         {
00216           nopt++;
00217           if (nopt >= argc)  FDR_error ("need argument after -input ");
00218           FDR_input_filename = (char *) malloc (sizeof(char)*THD_MAX_NAME);
00219           MTEST (FDR_input_filename);
00220           strcpy (FDR_input_filename, argv[nopt]);
00221           nopt++;
00222           continue;
00223         }
00224       
00225       
00226       
00227       if (strcmp(argv[nopt], "-input1D") == 0)
00228         {
00229           nopt++;
00230           if (nopt >= argc)  FDR_error ("need argument after -input1D ");
00231           FDR_input1D_filename = (char *) malloc (sizeof(char)*THD_MAX_NAME);
00232           MTEST (FDR_input1D_filename);
00233           strcpy (FDR_input1D_filename, argv[nopt]);
00234           nopt++;
00235           continue;
00236         }
00237       
00238       
00239       
00240       if (strcmp(argv[nopt], "-mask_file") == 0)
00241         {
00242           nopt++;
00243           if (nopt >= argc)  FDR_error ("need argument after -mask_file ");
00244           FDR_mask_filename = (char *) malloc (sizeof(char)*THD_MAX_NAME);
00245           MTEST (FDR_mask_filename);
00246           strcpy (FDR_mask_filename, argv[nopt]);
00247           nopt++;
00248           continue;
00249         }
00250       
00251 
00252       
00253       if( strcmp(argv[nopt],"-mask_thr") == 0 ){
00254          float fval;
00255          nopt++ ;
00256          if( nopt >= argc ){
00257             FDR_error (" need 1 argument after -mask_thr"); 
00258          }
00259          sscanf (argv[nopt], "%f", &fval); 
00260          if (fval < 0.0){
00261             FDR_error (" Require mask_thr >= 0.0 ");
00262          }
00263          FDR_mask_thr = fval;
00264          nopt++;  continue;
00265       }
00266 
00267 
00268       
00269       if( strcmp(argv[nopt],"-cind") == 0 ){
00270          FDR_cn = 1.0;
00271          nopt++ ; continue ;
00272       }
00273 
00274       
00275       
00276       if( strcmp(argv[nopt],"-cdep") == 0 ){
00277          FDR_cn = -1.0;
00278          nopt++ ; continue ;
00279       }
00280 
00281       
00282       
00283       if( strcmp(argv[nopt],"-quiet") == 0 ){
00284          FDR_quiet = 1;
00285          nopt++ ; continue ;
00286       }
00287 
00288       
00289       
00290       if( strcmp(argv[nopt],"-list") == 0 ){
00291          FDR_list = 1;
00292          nopt++ ; continue ;
00293       }
00294 
00295       
00296       
00297       if( strcmp(argv[nopt],"-prefix") == 0 ||
00298           strcmp(argv[nopt],"-output") == 0   ){
00299          nopt++ ;
00300          if( nopt >= argc ){
00301             FDR_error (" need argument after -prefix!");
00302          }
00303          FDR_output_prefix = (char *) malloc (sizeof(char) * THD_MAX_PREFIX); 
00304          MCW_strncpy( FDR_output_prefix , argv[nopt++] , THD_MAX_PREFIX ) ;
00305          continue ;
00306       }
00307 
00308 
00309       
00310       sprintf(message,"Unrecognized command line option: %s\n", argv[nopt]);
00311       FDR_error (message);
00312       
00313 
00314    }  
00315 
00316 
00317 }
00318 
00319 
00320 
00321 
00322 
00323 
00324 
00325 
00326 float * read_time_series 
00327 (
00328   char * ts_filename,          
00329   int * ts_length              
00330 )
00331 
00332 {
00333   char message[THD_MAX_NAME];    
00334   char * cpt;                    
00335   char filename[THD_MAX_NAME];   
00336   char subv[THD_MAX_NAME];       
00337   MRI_IMAGE * im, * flim;  
00338 
00339   float * far;             
00340   int nx;                  
00341   int ny;                  
00342   int iy;                  
00343   int ipt;                 
00344   float * ts_data = NULL;  
00345 
00346 
00347   
00348   if (ts_filename == NULL)
00349     FDR_error ("Missing input time series file name");
00350 
00351 
00352   
00353   flim = mri_read_1D(ts_filename) ;
00354   if (flim == NULL)
00355     {
00356       sprintf (message,  "Unable to read time series file: %s",  ts_filename);
00357       FDR_error (message);
00358     }
00359 
00360   far = MRI_FLOAT_PTR(flim);
00361   nx = flim->nx;
00362   ny = flim->ny; iy = 0 ;
00363   if( ny > 1 ){
00364     fprintf(stderr,"WARNING: time series %s has more than 1 column\n",ts_filename);
00365   }
00366   
00367 
00368   
00369   *ts_length = nx;
00370   ts_data = (float *) malloc (sizeof(float) * nx);
00371   MTEST (ts_data);
00372   for (ipt = 0;  ipt < nx;  ipt++)
00373     ts_data[ipt] = far[ipt + iy*nx];   
00374   
00375   
00376   mri_free (flim);  flim = NULL;
00377 
00378   return (ts_data);
00379 }
00380 
00381 
00382 
00383 
00384 
00385 
00386 
00387 void check_one_output_file 
00388 (
00389   THD_3dim_dataset * dset_time,     
00390   char * filename                   
00391 )
00392 
00393 {
00394   char message[THD_MAX_NAME];      
00395   THD_3dim_dataset * new_dset=NULL;   
00396   int ierror;                         
00397 
00398   
00399   
00400   new_dset = EDIT_empty_copy( dset_time ) ;
00401   
00402   
00403   ierror = EDIT_dset_items( new_dset ,
00404                             ADN_prefix , filename ,
00405                             ADN_label1 , filename ,
00406                             ADN_self_name , filename ,
00407                             ADN_type , ISHEAD(dset_time) ? HEAD_FUNC_TYPE : 
00408                                                            GEN_FUNC_TYPE ,
00409                             ADN_none ) ;
00410   
00411   if( ierror > 0 )
00412     {
00413       sprintf (message,
00414                "*** %d errors in attempting to create output dataset!\n", 
00415                ierror);
00416       FDR_error (message);
00417     }
00418   
00419   if( THD_is_file(new_dset->dblk->diskptr->header_name) )
00420     {
00421       sprintf (message,
00422                "Output dataset file %s already exists "
00423                " -- cannot continue! ",
00424                new_dset->dblk->diskptr->header_name);
00425       FDR_error (message);
00426     }
00427   
00428      
00429   THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
00430   
00431 }
00432 
00433 
00434 
00435 
00436 
00437 
00438 
00439 
00440 void * initialize_program (int argc, char * argv[])
00441 {
00442   int iv;                  
00443   void * vfim = NULL;      
00444   float * ffim = NULL;     
00445   int ixyz;                
00446   int nx, ny, nz, nxyz;    
00447   int mx, my, mz, mxyz;    
00448   int nthr;                
00449   char message[80];        
00450   int ibin;                
00451 
00452 
00453   
00454   machdep() ; 
00455   { int new_argc ; char ** new_argv ;
00456   addto_args( argc , argv , &new_argc , &new_argv ) ;
00457   if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; }
00458   }
00459   
00460 
00461   
00462   commandline = tross_commandline( PROGRAM_NAME , argc,argv ) ;
00463 
00464 
00465   
00466   if( argc < 2 || strcmp(argv[1],"-help") == 0 ) FDR_Syntax() ;
00467 
00468   
00469   
00470   AFNI_logger (PROGRAM_NAME,argc,argv); 
00471 
00472 
00473   
00474   read_options( argc , argv ) ;
00475 
00476 
00477   
00478   if (FDR_mask_filename != NULL)
00479     {
00480       if (!FDR_quiet) 
00481         printf ("Reading mask dataset: %s \n", FDR_mask_filename);
00482       DOPEN (FDR_dset, FDR_mask_filename);
00483 
00484       if (FDR_dset == NULL)
00485         {
00486           sprintf (message, "Cannot open mask dataset %s", FDR_mask_filename); 
00487           FDR_error (message);
00488         }
00489 
00490       if (DSET_NVALS(FDR_dset) != 1)
00491         FDR_error ("Must specify single sub-brick for mask data");
00492 
00493 
00494       
00495       mx   = DSET_NX(FDR_dset);   
00496       my   = DSET_NY(FDR_dset);   
00497       mz   = DSET_NZ(FDR_dset);
00498       mxyz = mx*my*mz;
00499 
00500 
00501       
00502       ffim = (float *) malloc (sizeof(float) * mxyz);   MTEST (ffim);
00503 
00504 
00505       
00506       iv = DSET_PRINCIPAL_VALUE (FDR_dset);
00507       SUB_POINTER (FDR_dset, iv, 0, vfim);
00508       EDIT_coerce_scale_type (mxyz, DSET_BRICK_FACTOR(FDR_dset,iv),
00509                               DSET_BRICK_TYPE(FDR_dset,iv), vfim,  
00510                               MRI_float                   , ffim); 
00511   
00512       
00513       
00514       FDR_mask = (byte *) malloc (sizeof(byte) * mxyz);
00515       MTEST (FDR_mask);
00516       
00517       
00518       
00519       nthr = 0;
00520       for (ixyz = 0;  ixyz < mxyz;  ixyz++)
00521         if (fabs(ffim[ixyz]) >= FDR_mask_thr)  
00522           { 
00523             FDR_mask[ixyz] = 1;
00524             nthr++;
00525           }
00526         else
00527           FDR_mask[ixyz] = 0;
00528 
00529       if (!FDR_quiet)  
00530         printf ("Number of voxels above mask threshold = %d \n", nthr);
00531       if (nthr < 1)  
00532         FDR_error ("No voxels above mask threshold.  Cannot continue.");
00533 
00534 
00535       
00536       if (ffim != NULL) { free (ffim);   ffim = NULL; }
00537 
00538       
00539       THD_delete_3dim_dataset (FDR_dset, False);  FDR_dset = NULL ;
00540 
00541     }
00542 
00543 
00544   
00545 
00546   if (FDR_input1D_filename != NULL)
00547     {
00548       
00549       if (!FDR_quiet)  printf ("Reading input data: %s \n", 
00550                                FDR_input1D_filename);
00551       FDR_input1D_data = read_time_series (FDR_input1D_filename, &nxyz);
00552 
00553       if (FDR_input1D_data == NULL)  
00554         { 
00555           sprintf (message,  "Unable to read input .1D data file: %s", 
00556                    FDR_input1D_filename);
00557           FDR_error (message);
00558         }
00559       
00560       if (nxyz < 1)  
00561         { 
00562           sprintf (message,  "No p-values in input .1D data file: %s", 
00563                    FDR_input1D_filename);
00564           FDR_error (message);
00565         }
00566 
00567       FDR_nxyz = nxyz;
00568       FDR_nthr = nxyz;
00569     }
00570   
00571   else
00572     {
00573       
00574       if (!FDR_quiet)  printf ("Reading input dataset: %s \n", 
00575                                FDR_input_filename);
00576       FDR_dset = THD_open_dataset(FDR_input_filename);
00577       
00578       if (FDR_dset == NULL)
00579         {
00580           sprintf (message, "Cannot open input dataset %s", 
00581                    FDR_input_filename); 
00582           FDR_error (message);
00583         }
00584       
00585       
00586       nx   = DSET_NX(FDR_dset);   
00587       ny   = DSET_NY(FDR_dset);   
00588       nz   = DSET_NZ(FDR_dset);
00589       nxyz = nx*ny*nz;
00590       
00591       
00592       
00593       if (FDR_mask != NULL)
00594         {
00595           if ((nx != mx) || (ny != my) || (nz != mz))
00596             FDR_error ("Mask and input dataset have incompatible dimensions");
00597           FDR_nxyz = nxyz;
00598           FDR_nthr = nthr;
00599         }
00600       else
00601         {
00602           FDR_nxyz = nxyz;
00603           FDR_nthr = nxyz;
00604         }
00605 
00606 
00607       
00608       check_one_output_file (FDR_dset, FDR_output_prefix);
00609     }
00610 
00611 
00612   
00613   if (FDR_cn < 0.0)
00614     {
00615       double cn;
00616       cn = 0.0;
00617       for (ixyz = 1;  ixyz <= FDR_nthr;  ixyz++)
00618         cn += 1.0 / ixyz;
00619       FDR_cn = cn;
00620       if (!FDR_quiet)
00621         printf ("c(N) = %f \n", FDR_cn);
00622     }
00623   
00624   
00625   for (ibin = 0;  ibin < FDR_MAX_LL;  ibin++)
00626     FDR_head_voxel[ibin] = NULL;
00627 
00628 
00629 }
00630 
00631 
00632 
00633 
00634 
00635 
00636   
00637 voxel * create_voxel ()
00638 {
00639   voxel * voxel_ptr = NULL;
00640 
00641   voxel_ptr = (voxel *) malloc (sizeof(voxel));
00642   MTEST (voxel_ptr);
00643   
00644   voxel_ptr->ixyz = 0;
00645   voxel_ptr->pvalue = 0.0;
00646   voxel_ptr->next_voxel = NULL;
00647 
00648   return (voxel_ptr);
00649   
00650 }
00651 
00652 
00653 
00654 
00655 
00656 
00657 
00658 voxel * add_voxel (voxel * new_voxel, voxel * head_voxel)
00659 {
00660   voxel * voxel_ptr = NULL;
00661 
00662   if ((head_voxel == NULL) || (new_voxel->pvalue >= head_voxel->pvalue))
00663     {
00664       new_voxel->next_voxel = head_voxel;
00665       head_voxel = new_voxel;
00666     }
00667 
00668   else
00669     {
00670       voxel_ptr = head_voxel;
00671 
00672       while ((voxel_ptr->next_voxel != NULL) && 
00673              (new_voxel->pvalue < voxel_ptr->next_voxel->pvalue))
00674         voxel_ptr = voxel_ptr->next_voxel;
00675       
00676       new_voxel->next_voxel = voxel_ptr->next_voxel;
00677       voxel_ptr->next_voxel = new_voxel;
00678     }
00679 
00680   return (head_voxel);
00681 }
00682 
00683 
00684 
00685 
00686 
00687 
00688 
00689 voxel * new_voxel (int ixyz, float pvalue, voxel * head_voxel)
00690 
00691 {
00692   voxel * voxel_ptr = NULL;
00693 
00694   voxel_ptr = create_voxel ();
00695 
00696   voxel_ptr->ixyz      = ixyz;
00697   voxel_ptr->pvalue    = pvalue;
00698 
00699   head_voxel = add_voxel (voxel_ptr, head_voxel);
00700 
00701   return (head_voxel);
00702   
00703 }
00704 
00705 
00706 
00707 
00708 
00709 
00710 
00711 void delete_all_voxels ()
00712 {
00713   int ibin;
00714   voxel * voxel_ptr  = NULL;     
00715   voxel * next_voxel = NULL;     
00716 
00717 
00718   for (ibin = 0;  ibin < FDR_MAX_LL;  ibin++) 
00719     {
00720       voxel_ptr = FDR_head_voxel[ibin];
00721       while (voxel_ptr != NULL)
00722         {
00723           next_voxel = voxel_ptr->next_voxel;
00724           free (voxel_ptr);
00725           voxel_ptr = next_voxel;
00726         }
00727       FDR_head_voxel[ibin] = NULL;
00728     }
00729   
00730 }
00731 
00732 
00733 
00734 
00735 
00736 
00737 
00738 void save_all_voxels (float * far)
00739 {
00740   int ixyz, ibin;
00741   voxel * voxel_ptr  = NULL;     
00742   
00743 
00744   
00745   for (ixyz = 0;  ixyz < FDR_nxyz;  ixyz++)
00746     far[ixyz] = 0.0;
00747 
00748 
00749   for (ibin = 0;  ibin < FDR_MAX_LL;  ibin++) 
00750     {
00751       voxel_ptr = FDR_head_voxel[ibin];
00752   
00753       while (voxel_ptr != NULL)
00754         {
00755           far[voxel_ptr->ixyz] = voxel_ptr->pvalue;
00756           voxel_ptr = voxel_ptr->next_voxel;
00757         }
00758 
00759     }
00760 
00761 }
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 void process_volume (float * ffim, int statcode, float * stataux)
00770 
00771 {
00772   int ixyz;                      
00773   int icount;                    
00774   float fval;                    
00775   float pval;                    
00776   float qval;                    
00777   float zval;                    
00778   float qval_min;                
00779   voxel * head_voxel = NULL;     
00780   voxel * voxel_ptr  = NULL;     
00781   int ibin;                      
00782   int   * iarray = NULL;         
00783   float * parray = NULL;         
00784   float * qarray = NULL;         
00785   float * zarray = NULL;         
00786 
00787   
00788   
00789   if (FDR_list)
00790     {
00791       iarray = (int   *) malloc (sizeof(int)   * FDR_nthr);   MTEST(iarray);
00792       parray = (float *) malloc (sizeof(float) * FDR_nthr);   MTEST(parray);
00793       qarray = (float *) malloc (sizeof(float) * FDR_nthr);   MTEST(qarray);
00794       zarray = (float *) malloc (sizeof(float) * FDR_nthr);   MTEST(zarray);
00795     }
00796   
00797   
00798   
00799   icount = FDR_nthr;
00800   for (ixyz = 0;  ixyz < FDR_nxyz;  ixyz++)
00801     {
00802 
00803       
00804       if (FDR_mask != NULL)
00805         if (!FDR_mask[ixyz]) continue;
00806 
00807 
00808       
00809       fval = fabs(ffim[ixyz]);
00810       if (statcode <= 0)
00811         pval = fval;
00812       else
00813         pval = THD_stat_to_pval (fval, statcode, stataux);
00814 
00815       if (pval >= 1.0)  
00816         {
00817           
00818           icount--;
00819           if (FDR_list)
00820             {
00821               iarray[icount] = ixyz;
00822               parray[icount] = 1.0;
00823               qarray[icount] = 1.0;
00824               zarray[icount] = 0.0;
00825             }
00826         }
00827       else
00828         { 
00829           
00830           ibin = (int)  (pval * (FDR_MAX_LL));
00831           if (ibin < 0)  ibin = 0;
00832           if (ibin > FDR_MAX_LL-1)  ibin = FDR_MAX_LL-1;
00833           head_voxel = new_voxel (ixyz, pval, FDR_head_voxel[ibin]);
00834           FDR_head_voxel[ibin] = head_voxel;
00835         }
00836     }
00837 
00838   
00839   
00840   qval_min = 1.0;
00841   ibin = FDR_MAX_LL-1;
00842   while (ibin >= 0) 
00843     {
00844       voxel_ptr = FDR_head_voxel[ibin];
00845   
00846       while (voxel_ptr != NULL)
00847         {
00848           
00849           pval = voxel_ptr->pvalue;
00850           qval = FDR_cn * (pval*FDR_nthr) / icount;
00851           if (qval > qval_min)
00852             qval = qval_min;
00853           else
00854             qval_min = qval;
00855 
00856           
00857           if (qval < 1.0e-20)
00858             zval = 10.0;
00859           else
00860             zval = normal_p2t(qval);
00861 
00862           icount--;
00863 
00864           
00865           if (FDR_list)
00866             {
00867               iarray[icount] = voxel_ptr->ixyz;
00868               parray[icount] = pval;
00869               qarray[icount] = qval;
00870               zarray[icount] = zval;
00871             }
00872 
00873           voxel_ptr->pvalue = zval;
00874           voxel_ptr = voxel_ptr->next_voxel;
00875         }
00876 
00877       ibin--;
00878     }
00879 
00880 
00881   
00882   if (FDR_list)
00883     {
00884       printf ("%12s %12s %12s %12s \n", 
00885               "Index", "p-value", "q-value", "z-score");
00886       for (icount = 0;  icount < FDR_nthr;  icount++)
00887         {
00888           if (FDR_input1D_filename != NULL)
00889             ixyz = iarray[icount] + 1;
00890           else
00891             ixyz = iarray[icount];
00892           printf ("%12d %12.6f %12.6f %12.6f \n",  
00893                   ixyz, parray[icount], qarray[icount], zarray[icount]);
00894         }
00895 
00896       
00897       free (iarray);   free (parray);   free (qarray);   free (zarray);
00898     }
00899 
00900 
00901   
00902   save_all_voxels (ffim);
00903 
00904 
00905   
00906   delete_all_voxels();
00907 
00908 }
00909 
00910 
00911 
00912 
00913 
00914 
00915 
00916 void process_1ddata ()
00917 
00918 {
00919   float * ffim = NULL;     
00920 
00921   
00922   
00923   ffim = FDR_input1D_data;
00924 
00925 
00926   
00927   process_volume (ffim, -1, NULL);
00928 
00929   if( FDR_output_prefix != NULL && ffim != NULL ){
00930     MRI_IMAGE *im = mri_new_vol_empty( FDR_nxyz,1,1 , MRI_float ) ;
00931     mri_fix_data_pointer( ffim , im ) ;
00932     mri_write_1D( FDR_output_prefix , im ) ;
00933     mri_fix_data_pointer( NULL , im ) ;
00934     mri_free( im ) ;
00935   }
00936 
00937   
00938   if (ffim != NULL) { free (ffim);   ffim = NULL; }
00939 
00940 }
00941 
00942 
00943 
00944 
00945 
00946 
00947 
00948 
00949 
00950 
00951 
00952 
00953 
00954 float EDIT_coerce_autoscale_new( int nxyz ,
00955                                  int itype,void *ivol , int otype,void *ovol )
00956 {
00957   float fac=0.0 , top ;
00958   
00959   if( MRI_IS_INT_TYPE(otype) ){
00960     top = MCW_vol_amax( nxyz,1,1 , itype,ivol ) ;
00961     if (top == 0.0)  fac = 0.0;
00962     else  fac = MRI_TYPE_maxval[otype]/top;
00963   }
00964   
00965   EDIT_coerce_scale_type( nxyz , fac , itype,ivol , otype,ovol ) ;
00966   return ( fac );
00967 }
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 void process_subbrick (THD_3dim_dataset * dset, int ibrick)
00976 
00977 {
00978   const float EPSILON = 1.0e-10;
00979   float factor;            
00980   void * vfim = NULL;      
00981   float * ffim = NULL;     
00982   char brick_label[THD_MAX_NAME];       
00983 
00984 
00985   if (!FDR_quiet)  printf ("Processing sub-brick #%d \n", ibrick);
00986 
00987   
00988   
00989   ffim = (float *) malloc (sizeof(float) * FDR_nxyz);   MTEST (ffim);
00990 
00991 
00992   
00993   SUB_POINTER (dset, ibrick, 0, vfim);
00994   EDIT_coerce_scale_type (FDR_nxyz, DSET_BRICK_FACTOR(dset,ibrick),
00995                           DSET_BRICK_TYPE(dset,ibrick), vfim,   
00996                           MRI_float                   , ffim);  
00997 
00998 
00999   
01000   process_volume (ffim, DSET_BRICK_STATCODE(dset,ibrick),
01001                         DSET_BRICK_STATAUX (dset,ibrick));
01002 
01003 
01004   
01005   SUB_POINTER (dset, ibrick, 0, vfim);
01006   factor = EDIT_coerce_autoscale_new (FDR_nxyz, MRI_float, ffim,
01007                                       DSET_BRICK_TYPE(dset,ibrick), vfim);  
01008   if (factor < EPSILON)  factor = 0.0;
01009   else factor = 1.0 / factor;
01010   
01011 
01012   
01013   strcpy (brick_label, "FDRz ");
01014   strcat (brick_label, DSET_BRICK_LABEL(dset, ibrick));
01015   EDIT_BRICK_LABEL (dset, ibrick, brick_label);
01016   EDIT_BRICK_FACTOR (dset, ibrick, factor);
01017   EDIT_BRICK_TO_FIZT (dset, ibrick);
01018  
01019 
01020   
01021   if (ffim != NULL) { free (ffim);   ffim = NULL; }
01022 
01023 }
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 THD_3dim_dataset * process_dataset ()
01032 
01033 {
01034   THD_3dim_dataset * new_dset = NULL;     
01035   int ibrick, nbricks;                    
01036   int statcode;                           
01037 
01038 
01039   
01040   new_dset = EDIT_full_copy(FDR_dset, FDR_output_prefix);
01041 
01042 
01043   
01044   tross_Copy_History( FDR_dset , new_dset ) ;
01045 
01046   if( commandline != NULL )
01047     {
01048       tross_Append_History ( new_dset, commandline);
01049       free(commandline) ;
01050     }
01051 
01052 
01053      
01054   THD_delete_3dim_dataset (FDR_dset , False );  FDR_dset = NULL ;
01055 
01056 
01057   
01058   nbricks = DSET_NVALS(new_dset);
01059   for (ibrick = 0;  ibrick < nbricks;  ibrick++)
01060     {
01061       statcode = DSET_BRICK_STATCODE(new_dset, ibrick);
01062       if (FUNC_IS_STAT(statcode))
01063         {
01064           
01065           if (!FDR_quiet)  
01066             printf ("ibrick = %3d   statcode = %5s \n", 
01067                     ibrick, FUNC_prefixstr[statcode]);
01068           process_subbrick (new_dset, ibrick);
01069         }
01070     }
01071 
01072 
01073   return (new_dset);
01074 }
01075 
01076 
01077 
01078 
01079 
01080 
01081 
01082 void output_results (THD_3dim_dataset * new_dset)
01083 {
01084   int ierror;     
01085 
01086 
01087   
01088   ierror = EDIT_dset_items( new_dset ,
01089                             ADN_func_type , FUNC_BUCK_TYPE,
01090                             ADN_none ) ;
01091   if (ierror > 0)  
01092     FDR_error ("Errors in attempting to create output dataset.");
01093 
01094 
01095   
01096   if( !FDR_quiet ) fprintf(stderr,"Computing sub-brick statistics\n") ;
01097   THD_load_statistics( new_dset ) ;
01098 
01099   THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ;
01100   if( !FDR_quiet ) fprintf(stderr,"Wrote output to %s\n", DSET_BRIKNAME(new_dset) );
01101   
01102 
01103      
01104   THD_delete_3dim_dataset( new_dset , False ) ; new_dset = NULL ;
01105   
01106 }
01107 
01108 
01109 
01110 
01111 int main( int argc , char * argv[] )
01112 
01113 {
01114   THD_3dim_dataset * new_dset = NULL;      
01115   
01116 
01117   
01118   printf ("\n\n");
01119   printf ("Program:          %s \n", PROGRAM_NAME);
01120   printf ("Author:           %s \n", PROGRAM_AUTHOR); 
01121   printf ("Initial Release:  %s \n", PROGRAM_INITIAL);
01122   printf ("Latest Revision:  %s \n", PROGRAM_LATEST);
01123   printf ("\n");
01124 
01125 
01126   
01127 
01128   initialize_program (argc, argv);
01129 
01130 
01131   if (FDR_input1D_filename != NULL)
01132     {
01133       
01134       process_1ddata ();
01135     }
01136   else
01137     {
01138       
01139       new_dset = process_dataset ();
01140 
01141       
01142       output_results (new_dset);
01143     }
01144   
01145   exit(0) ;
01146 }
01147 
01148 
01149 
01150 
01151