float THD_pval_to_stat( float pval , int statcode , float * stataux ) { float stat = -1.0 ; /* error flag */ if( pval >= 0.999999 ) return 0.0 ; /* WTF */ if( stataux == NULL && statcode != FUNC_ZT_TYPE ) return pval ; switch( statcode ){ /* if statcode is illegal, will return -1 */ /** the routines below are in mri_stats.c **/ case FUNC_COR_TYPE: stat = correl_p2t( pval , stataux[0] , stataux[1] , stataux[2] ) ; break ; case FUNC_TT_TYPE: stat = student_p2t( pval , stataux[0] ) ; break ; case FUNC_FT_TYPE: stat = fstat_p2t( pval , stataux[0] , stataux[1] ) ; break ; case FUNC_ZT_TYPE: /* only type that doesn't */ stat = normal_p2t( pval ) ; /* use stataux parameters */ break ; case FUNC_CT_TYPE: stat = chisq_p2t( pval , stataux[0] ) ; break ; case FUNC_BT_TYPE: stat = beta_p2t( pval , stataux[0] , stataux[1] ) ; break ; case FUNC_BN_TYPE: stat = binomial_p2t( pval , stataux[0] , stataux[1] ) ; break ; case FUNC_GT_TYPE: stat = gamma_p2t( pval , stataux[0] , stataux[1] ) ; break ; case FUNC_PT_TYPE: stat = poisson_p2t( pval , stataux[0] ) ; break ; } return stat ; }
void process_volume (float * ffim, int statcode, float * stataux) { int ixyz; /* voxel index */ int icount; /* count of sorted p-values */ float fval; /* voxel input statistical value */ float pval; /* voxel input stat. p-value */ float qval; /* voxel FDR q-value */ float zval; /* voxel FDR z-score */ float qval_min; /* smallest previous q-value */ voxel * head_voxel = NULL; /* linked list of voxels */ voxel * voxel_ptr = NULL; /* pointer to current voxel */ int ibin; /* p-value bin */ int * iarray = NULL; /* output array of voxel indices */ float * parray = NULL; /* output array of voxel p-values */ float * qarray = NULL; /* output array of voxel FDR q-values */ float * zarray = NULL; /* output array of voxel FDR z-scores */ float numer ; /*------------ 18 Jan 2008: use the 'new' method? ------------*/ if( FDR_old < 1 ){ MRI_IMAGE *qim ; int flags=0 ; qim = mri_new_vol_empty( FDR_nxyz,1,1 , MRI_float ) ; mri_fix_data_pointer( ffim , qim ) ; if( FDR_mask != NULL ){ float zz = (FUNC_IS_STAT(statcode)) ? 0.0f : 1.0f ; for( ixyz=0 ; ixyz < FDR_nxyz ; ixyz++ ) if( !FDR_mask[ixyz] ) ffim[ixyz] = zz ; } if( FDR_curve ){ /* hidden option: produce t-z curve */ floatvec *fv = mri_fdr_curve( qim , statcode , stataux ) ; if( fv == NULL ) ERROR_message("mri_fdr_curve fails!") ; else { printf("# FDR thresh-z curve\n") ; for( ixyz=0 ; ixyz < fv->nar ; ixyz++ ) printf("%g %g\n", fv->x0+ixyz*fv->dx , fv->ar[ixyz] ) ; } exit(0) ; } else { /* normal operation: convert to z(q) or q */ if( FDR_pmask == 0 ) flags |= 1 ; /* compatibility mode */ if( FDR_cn > 1.0f ) flags |= 2 ; /* dependency flag */ if( FDR_qval ) flags |= 4 ; /* qval flag */ (void)mri_fdrize( qim , statcode,stataux , flags ) ; } mri_clear_data_pointer(qim); mri_free(qim); return ; } /*---------------- back to the 'old' method ------------------*/ /*----- Allocate memory for screen output arrays -----*/ if (FDR_list) { iarray = (int *) malloc (sizeof(int) * FDR_nthr); MTEST(iarray); parray = (float *) malloc (sizeof(float) * FDR_nthr); MTEST(parray); qarray = (float *) malloc (sizeof(float) * FDR_nthr); MTEST(qarray); zarray = (float *) malloc (sizeof(float) * FDR_nthr); MTEST(zarray); } /*----- Loop over all voxels; sort p-values -----*/ icount = FDR_nthr; for (ixyz = 0; ixyz < FDR_nxyz; ixyz++) { /*----- First, check if voxel is inside the mask -----*/ if( FDR_mask != NULL && !FDR_mask[ixyz] ) continue; /*----- Convert stats to p-values -----*/ fval = fabs(ffim[ixyz]); if (statcode <= 0) pval = fval; else pval = THD_stat_to_pval (fval, statcode, stataux); if (pval >= 1.0) { /*----- Count but don't sort voxels with p-value = 1 -----*/ icount--; if (FDR_list) { iarray[icount] = ixyz; parray[icount] = 1.0; qarray[icount] = 1.0; zarray[icount] = 0.0; } } else { /*----- Place voxel in p-value bin -----*/ ibin = (int) (pval * (FDR_MAX_LL)); if (ibin < 0) ibin = 0; if (ibin > FDR_MAX_LL-1) ibin = FDR_MAX_LL-1; head_voxel = new_voxel (ixyz, pval, FDR_head_voxel[ibin]); FDR_head_voxel[ibin] = head_voxel; } } /*----- Calculate FDR q-values -----*/ qval_min = 1.0; ibin = FDR_MAX_LL-1; numer = (FDR_pmask) ? icount : FDR_nthr ; /* 18 Jan 2008 */ while (ibin >= 0) { voxel_ptr = FDR_head_voxel[ibin]; while (voxel_ptr != NULL) { /*----- Convert sorted p-values to FDR q-values -----*/ pval = voxel_ptr->pvalue; qval = FDR_cn * (pval*numer) / icount; if (qval > qval_min) qval = qval_min; else qval_min = qval; /*----- Convert FDR q-value to FDR z-score -----*/ if( !FDR_qval ){ if (qval < 1.0e-20) zval = 10.0; else zval = normal_p2t(qval); } else { zval = qval ; } icount--; /*----- Save calculated values -----*/ if (FDR_list) { iarray[icount] = voxel_ptr->ixyz; parray[icount] = pval; qarray[icount] = qval; zarray[icount] = zval; } voxel_ptr->pvalue = zval; voxel_ptr = voxel_ptr->next_voxel; } ibin--; } /*----- Write out the calculated values -----*/ if (FDR_list) { printf ("%12s %12s %12s %12s \n", "Index", "p-value", "q-value", "z-score"); for (icount = 0; icount < FDR_nthr; icount++) { if (FDR_input1D_filename != NULL) ixyz = iarray[icount] + 1; else ixyz = iarray[icount]; printf ("%12d %12.6f %12.6f %12.6f \n", ixyz, parray[icount], qarray[icount], zarray[icount]); } /*----- Deallocate memory for output arrays -----*/ free (iarray); free (parray); free (qarray); free (zarray); } /*----- Place FDR z-scores into float array -----*/ save_all_voxels (ffim); /*----- Deallocate linked-list memory -----*/ delete_all_voxels(); }