void process_1ddata () { float * ffim = NULL; /* input list of p-values */ /*----- Set pointer to input array of p-values -----*/ ffim = FDR_input1D_data; /*----- Calculate FDR z-scores for all input p-values -----*/ process_volume (ffim, -1, NULL); if( FDR_output_prefix != NULL && ffim != NULL ){ MRI_IMAGE *im = mri_new_vol_empty( FDR_nxyz,1,1 , MRI_float ) ; mri_fix_data_pointer( ffim , im ) ; mri_write_1D( FDR_output_prefix , im ) ; mri_fix_data_pointer( NULL , im ) ; mri_free( im ) ; } /*----- Deallocate memory -----*/ if (ffim != NULL) { free (ffim); ffim = NULL; } }
/* Get copy contents of sub-brick iv into an double array. if iv == -1, get the entire dset */ double *THD_extract_to_double( int iv , THD_3dim_dataset *dset ) { MRI_IMAGE *im ; double *var=NULL, *vv=NULL; register int ii , nvox ; ENTRY("THD_extract_to_double") ; if (!dset) RETURN(var); if (iv >= 0) { if (!(im = THD_extract_double_brick(iv, dset))) RETURN(var); var = MRI_DOUBLE_PTR(im);mri_fix_data_pointer(NULL, im); mri_free(im);im=NULL; } else if (iv == -1) { if (!(var = (double *)calloc(DSET_NVOX(dset)*DSET_NVALS(dset), sizeof(double)))){ ERROR_message("Failed to allocate"); RETURN(NULL); } for (ii=0; ii<DSET_NVALS(dset); ++ii) { if (!(im = THD_extract_double_brick(ii, dset))) { ERROR_message("Failed toextract sb %d from dset", ii); if (var) free(var); RETURN(NULL); } vv = MRI_DOUBLE_PTR(im); memcpy(var+ii*DSET_NVOX(dset),vv, sizeof(double)*DSET_NVOX(dset)); mri_free(im);im=NULL; } } else { ERROR_message("Bad value of %d\n", iv); } RETURN(var); }
void THD_load_tcat( THD_datablock *dblk ) { int ivout , dd , iv ; THD_3dim_dataset *dset_in , *dset_out ; NI_str_array *sar ; ENTRY("THD_load_tcat") ; if( !ISVALID_DBLK(dblk) ) EXRETURN ; dset_out = (THD_3dim_dataset *)dblk->parent ; if( !ISVALID_DSET(dset_out) ) EXRETURN ; sar = NI_decode_string_list( dset_out->tcat_list , "~" ) ; if( sar == NULL ) EXRETURN ; if( sar->num != dset_out->tcat_num ){ NI_delete_str_array(sar); EXRETURN; } ivout = 0 ; for( dd=0 ; dd < sar->num ; dd++ ){ dset_in = THD_open_dataset( sar->str[dd] ) ; if( dset_in == NULL ){ NI_delete_str_array(sar) ; DSET_unload(dset_out) ; EXRETURN ; } DSET_mallocize(dset_in) ; DSET_load(dset_in) ; if( !DSET_LOADED(dset_in) ){ NI_delete_str_array(sar) ; DSET_unload(dset_out) ; DSET_delete(dset_in) ; EXRETURN ; } for( iv=0 ; iv < DSET_NVALS(dset_in) ; iv++ ){ EDIT_substitute_brick( dset_out , ivout , DSET_BRICK_TYPE(dset_in,iv), DSET_ARRAY(dset_in,iv) ); mri_fix_data_pointer( NULL , DSET_BRICK(dset_in,iv) ) ; EDIT_BRICK_FACTOR( dset_out , ivout , DSET_BRICK_FACTOR(dset_in,iv) ) ; EDIT_BRICK_LABEL(dset_out, ivout, DSET_BRICK_LABEL(dset_in, iv)); /* ZSS Aug. 27 2012 */ ivout++ ; } DSET_delete(dset_in) ; } NI_delete_str_array(sar) ; EXRETURN ; }
/*-------------------------------------------------------*/ MRI_IMARR * dset_to_mri(THD_3dim_dataset * dset) /*--------------------------------------------------------*/ { int ii, kk, ntime, datum; int nvox, nx, ny, nz; int use_fac; MRI_IMARR * ims_in; MRI_IMAGE * im, *temp_im; byte ** bptr = NULL ; /* one of these will be the array of */ short ** sptr = NULL ; /* pointers to input dataset sub-bricks */ float ** fptr = NULL ; /* (depending on input datum type) */ float * fac = NULL ; /* array of brick scaling factors */ float * fout; ntime = DSET_NUM_TIMES(dset) ; nx = dset->daxes->nxx; ny = dset->daxes->nyy; nz = dset->daxes->nzz; nvox = dset->daxes->nxx * dset->daxes->nyy * dset->daxes->nzz ; datum = DSET_BRICK_TYPE( dset , 0 ) ; /* get dataset datum type */ switch( datum ){ /* pointer type depends on input datum type */ default: return NULL ; /** create array of pointers into old dataset sub-bricks **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..ntime-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * ntime ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < ntime ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(dset,kk) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..ntime-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * ntime ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < ntime; kk++ ) sptr[kk] = (short *) DSET_ARRAY(dset,kk) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..ntime-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * ntime) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < ntime; kk++ ) fptr[kk] = (float *) DSET_ARRAY(dset,kk) ; break ; } /* end of switch on input type */ INIT_IMARR(ims_in) ; for( kk=0 ; kk < ntime ; kk++ ){ im = mri_new_vol_empty( nx , ny , nz , datum ) ; ADDTO_IMARR(ims_in,im) ; } for( kk=0 ; kk < ntime ; kk++ ){ im = IMARR_SUBIMAGE(ims_in,kk) ; switch( datum ){ case MRI_byte: mri_fix_data_pointer( bptr[kk], im ) ; break ; case MRI_short: mri_fix_data_pointer( sptr[kk], im ) ; break ; case MRI_float: mri_fix_data_pointer( fptr[kk], im ) ; break ; } } return(ims_in); }
void EDIT_add_bricklist( THD_3dim_dataset *dset , int nbr, int *tbr, float *fbr , void *sbr[] ) { int ibr , typ , nx,ny,nz , nvals,new_nvals ; THD_datablock *dblk ; MRI_IMAGE *qim ; char str[32] ; ENTRY("EDIT_add_bricklist") ; /**-- Sanity Checks --**/ if( ! ISVALID_3DIM_DATASET(dset) || nbr <= 0 ) EXRETURN; /* error! */ if( dset->dblk->brick == NULL ) EXRETURN; /* error! */ if( dset->dblk->malloc_type != DATABLOCK_MEM_MALLOC )EXRETURN; /* error! */ dblk = dset->dblk ; nvals = dblk->nvals ; nx = dblk->diskptr->dimsizes[0] ; ny = dblk->diskptr->dimsizes[1] ; nz = dblk->diskptr->dimsizes[2] ; /**-- reallocate the brick control information --**/ new_nvals = nvals + nbr ; dblk->brick_bytes = (int64_t *) XtRealloc( (char *) dblk->brick_bytes , sizeof(int64_t) * new_nvals ) ; dblk->brick_fac = (float *) XtRealloc( (char *) dblk->brick_fac , sizeof(float) * new_nvals ) ; dblk->nvals = dblk->diskptr->nvals = new_nvals ; /** allocate new sub-brick images **/ for( ibr=0 ; ibr < nbr ; ibr++ ){ typ = (tbr != NULL ) ? tbr[ibr] : MRI_short ; qim = mri_new_vol_empty( nx,ny,nz , typ ) ; /* image with no data */ if( sbr != NULL && sbr[ibr] != NULL ) /* attach data to image */ mri_fix_data_pointer( sbr[ibr] , qim ) ; ADDTO_IMARR( dblk->brick , qim ) ; /* attach image to dset */ dblk->brick_fac[nvals+ibr] = (fbr != NULL) ? fbr[ibr] : 0.0 ; dblk->brick_bytes[nvals+ibr] = (int64_t)qim->pixel_size * (int64_t)qim->nvox ; dblk->total_bytes += dblk->brick_bytes[ibr] ; } /** allocate new sub-brick auxiliary data: labels **/ if( dblk->brick_lab == NULL ) THD_init_datablock_labels( dblk ) ; else dblk->brick_lab = (char **) XtRealloc( (char *) dblk->brick_lab , sizeof(char *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ sprintf( str , "#%d" , nvals+ibr ) ; dblk->brick_lab[nvals+ibr] = NULL ; THD_store_datablock_label( dblk , nvals+ibr , str ) ; } /** keywords **/ if( dblk->brick_keywords == NULL ) THD_init_datablock_keywords( dblk ) ; else dblk->brick_keywords = (char **) XtRealloc( (char *) dblk->brick_keywords , sizeof(char *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ dblk->brick_keywords[nvals+ibr] = NULL ; THD_store_datablock_keywords( dblk , nvals+ibr , NULL ) ; } /** stataux **/ if( dblk->brick_statcode != NULL ){ dblk->brick_statcode = (int *) XtRealloc( (char *) dblk->brick_statcode , sizeof(int) * new_nvals ) ; dblk->brick_stataux = (float **) XtRealloc( (char *) dblk->brick_stataux , sizeof(float *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ){ dblk->brick_statcode[nvals+ibr] = 0 ; dblk->brick_stataux[nvals+ibr] = NULL ; } } /** fdrcurve **/ if( dblk->brick_fdrcurve != NULL ){ dblk->brick_fdrcurve = (floatvec **) realloc( (void *)dblk->brick_fdrcurve , sizeof(floatvec *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ) dblk->brick_fdrcurve[nvals+ibr] = NULL ; } if( dblk->brick_mdfcurve != NULL ){ /* 22 Oct 2008 */ dblk->brick_mdfcurve = (floatvec **) realloc( (void *)dblk->brick_mdfcurve , sizeof(floatvec *) * new_nvals ) ; for( ibr=0 ; ibr < nbr ; ibr++ ) dblk->brick_mdfcurve[nvals+ibr] = NULL ; } EXRETURN; }
int main( int argc , char *argv[] ) { int nx,ny,nz , nxyz , ii,kk , num1,num2 , num_tt=0 , iv , piece , fim_offset; float dx,dy,dz , dxyz , num1_inv=0.0 , num2_inv , num1m1_inv=0.0 , num2m1_inv , dof , dd,tt,q1,q2 , f1,f2 , tt_max=0.0 ; THD_3dim_dataset *dset=NULL , *new_dset=NULL ; THD_3dim_dataset * base_dset; float *av1 , *av2 , *sd1 , *sd2 , *ffim , *gfim ; float *base_ary=NULL; void *vsp ; void *vdif ; /* output mean difference */ char cbuf[THD_MAX_NAME] ; float fbuf[MAX_STAT_AUX] , fimfac ; int output_datum ; float npiece , memuse ; float *dofbrik=NULL , *dofar=NULL ; THD_3dim_dataset *dof_dset=NULL ; /*-- read command line arguments --*/ if( argc < 2 || strncmp(argv[1],"-help",5) == 0 ) TT_syntax(NULL) ; /*-- 20 Apr 2001: addto the arglist, if user wants to [RWCox] --*/ mainENTRY("3dttest main"); machdep() ; PRINT_VERSION("3dttest") ; INFO_message("For most purposes, 3dttest++ should be used instead of 3dttest!") ; { int new_argc ; char ** new_argv ; addto_args( argc , argv , &new_argc , &new_argv ) ; if( new_argv != NULL ){ argc = new_argc ; argv = new_argv ; } } AFNI_logger("3dttest",argc,argv) ; TT_read_opts( argc , argv ) ; if( ! TT_be_quiet ) printf("3dttest: t-tests of 3D datasets, by RW Cox\n") ; /*-- read first dataset in set2 to get dimensions, etc. --*/ dset = THD_open_dataset( TT_set2->ar[0] ) ; /* 20 Dec 1999 BDW */ if( ! ISVALID_3DIM_DATASET(dset) ) ERROR_exit("Unable to open dataset file %s",TT_set2->ar[0]); nx = dset->daxes->nxx ; ny = dset->daxes->nyy ; nz = dset->daxes->nzz ; nxyz = nx * ny * nz ; dx = fabs(dset->daxes->xxdel) ; dy = fabs(dset->daxes->yydel) ; dz = fabs(dset->daxes->zzdel) ; dxyz = dx * dy * dz ; #ifdef TTDEBUG printf("*** nx=%d ny=%d nz=%d\n",nx,ny,nz) ; #endif /*-- make an empty copy of this dataset, for eventual output --*/ #ifdef TTDEBUG printf("*** making empty dataset\n") ; #endif new_dset = EDIT_empty_copy( dset ) ; tross_Make_History( "3dttest" , argc,argv , new_dset ) ; strcpy( cbuf , dset->self_name ) ; strcat( cbuf , "+TT" ) ; iv = DSET_PRINCIPAL_VALUE(dset) ; if( TT_datum >= 0 ){ output_datum = TT_datum ; } else { output_datum = DSET_BRICK_TYPE(dset,iv) ; if( output_datum == MRI_byte ) output_datum = MRI_short ; } #ifdef TTDEBUG printf(" ** datum = %s\n",MRI_TYPE_name[output_datum]) ; #endif iv = EDIT_dset_items( new_dset , ADN_prefix , TT_prefix , ADN_label1 , TT_prefix , ADN_directory_name , TT_session , ADN_self_name , cbuf , ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_TT_TYPE , ADN_nvals , FUNC_nvals[FUNC_TT_TYPE] , ADN_ntt , 0 , /* 07 Jun 2007 */ ADN_datum_all , output_datum , ADN_none ) ; if( iv > 0 ) ERROR_exit("%d errors in attempting to create output dataset!",iv ) ; if( THD_deathcon() && THD_is_file(new_dset->dblk->diskptr->header_name) ) ERROR_exit( "Output dataset file %s already exists--cannot continue!\a", new_dset->dblk->diskptr->header_name ) ; #ifdef TTDEBUG printf("*** deleting exemplar dataset\n") ; #endif THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; /** macro to test a malloc-ed pointer for validity **/ #define MTEST(ptr) \ if((ptr)==NULL) \ ( fprintf(stderr,"*** Cannot allocate memory for statistics!\n"), exit(0) ) /*-- make space for the t-test computations --*/ /* (allocate entire volumes) 13 Dec 2005 [rickr] */ npiece = 3.0 ; /* need at least this many */ if( TT_paired ) npiece += 1.0 ; else if( TT_set1 != NULL ) npiece += 2.0 ; npiece += mri_datum_size(output_datum) / (float) sizeof(float) ; npiece += mri_datum_size(output_datum) / (float) sizeof(float) ; #if 0 piece_size = TT_workmem * MEGA / ( npiece * sizeof(float) ) ; if( piece_size > nxyz ) piece_size = nxyz ; #ifdef TTDEBUG printf("*** malloc-ing space for statistics: %g float arrays of length %d\n", npiece,piece_size) ; #endif #endif av2 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av2) ; sd2 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd2) ; ffim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(ffim) ; num2 = TT_set2->num ; if( TT_paired ){ av1 = sd1 = NULL ; gfim = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(gfim) ; num1 = num2 ; } else if( TT_set1 != NULL ){ av1 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(av1) ; sd1 = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(sd1) ; gfim = NULL ; num1 = TT_set1->num ; } else { av1 = sd1 = NULL ; gfim = NULL ; num1 = 0 ; } vdif = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vdif) ; vsp = (void *) malloc( mri_datum_size(output_datum) * nxyz ) ; MTEST(vsp) ; /* 27 Dec 2002: make DOF dataset (if prefix is given, and unpooled is on) */ if( TT_pooled == 0 && TT_dof_prefix[0] != '\0' ){ dofbrik = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(dofbrik) ; dof_dset = EDIT_empty_copy( new_dset ) ; tross_Make_History( "3dttest" , argc,argv , dof_dset ) ; EDIT_dset_items( dof_dset , ADN_prefix , TT_dof_prefix , ADN_directory_name , TT_session , ADN_type , ISHEAD(dset) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE, ADN_func_type , FUNC_BUCK_TYPE , ADN_nvals , 1 , ADN_datum_all , MRI_float , ADN_none ) ; if( THD_is_file(dof_dset->dblk->diskptr->header_name) ) ERROR_exit( "-dof_prefix dataset file %s already exists--cannot continue!\a", dof_dset->dblk->diskptr->header_name ) ; EDIT_substitute_brick( dof_dset , 0 , MRI_float , dofbrik ) ; } /* print out memory usage to edify the user */ if( ! TT_be_quiet ){ memuse = sizeof(float) * nxyz * npiece + ( mri_datum_size(output_datum) + sizeof(short) ) * nxyz ; if( dofbrik != NULL ) memuse += sizeof(float) * nxyz ; /* 27 Dec 2002 */ printf("--- allocated %d Megabytes memory for internal use (%d volumes)\n", (int)(memuse/MEGA), (int)npiece) ; } mri_fix_data_pointer( vdif , DSET_BRICK(new_dset,0) ) ; /* attach bricks */ mri_fix_data_pointer( vsp , DSET_BRICK(new_dset,1) ) ; /* to new dataset */ /** only short and float are allowed for output **/ if( output_datum != MRI_short && output_datum != MRI_float ) ERROR_exit("Illegal output data type %d = %s", output_datum , MRI_TYPE_name[output_datum] ) ; num2_inv = 1.0 / num2 ; num2m1_inv = 1.0 / (num2-1) ; if( num1 > 0 ){ num1_inv = 1.0 / num1 ; num1m1_inv = 1.0 / (num1-1) ; } /*----- loop over pieces to process the input datasets with -----*/ /** macro to open a dataset and make it ready for processing **/ #define DOPEN(ds,name) \ do{ int pv ; (ds) = THD_open_dataset((name)) ; /* 16 Sep 1999 */ \ if( !ISVALID_3DIM_DATASET((ds)) ) \ ERROR_exit("Can't open dataset: %s",(name)) ; \ if( (ds)->daxes->nxx!=nx || (ds)->daxes->nyy!=ny || (ds)->daxes->nzz!=nz ) \ ERROR_exit("Axes size mismatch: %s",(name)) ; \ if( !EQUIV_GRIDS((ds),new_dset) ) \ WARNING_message("Grid mismatch: %s",(name)) ; \ if( DSET_NUM_TIMES((ds)) > 1 ) \ ERROR_exit("Can't use time-dependent data: %s",(name)) ; \ if( TT_use_editor ) EDIT_one_dataset( (ds), &TT_edopt ) ; \ else DSET_load((ds)) ; \ pv = DSET_PRINCIPAL_VALUE((ds)) ; \ if( DSET_ARRAY((ds),pv) == NULL ) \ ERROR_exit("Can't access data: %s",(name)) ; \ if( DSET_BRICK_TYPE((ds),pv) == MRI_complex ) \ ERROR_exit("Can't use complex data: %s",(name)) ; \ break ; } while (0) #if 0 /* can do it directly now (without offsets) 13 Dec 2005 [rickr] */ /** macro to return pointer to correct location in brick for current processing **/ #define SUB_POINTER(ds,vv,ind,ptr) \ do{ switch( DSET_BRICK_TYPE((ds),(vv)) ){ \ default: ERROR_exit("Illegal datum! ***"); \ case MRI_short:{ short * fim = (short *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; \ case MRI_byte:{ byte * fim = (byte *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; \ case MRI_float:{ float * fim = (float *) DSET_ARRAY((ds),(vv)) ; \ (ptr) = (void *)( fim + (ind) ) ; \ } break ; } break ; } while(0) #endif /** number of pieces to process **/ /* num_piece = (nxyz + piece_size - 1) / nxyz ; */ #if 0 nice(2) ; /** lower priority a little **/ #endif /* possibly open TT_base_dset now, and convert to floats */ if( TT_base_dname ) { DOPEN(base_dset, TT_base_dname) ; base_ary = (float *) malloc( sizeof(float) * nxyz ) ; MTEST(base_ary) ; EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(base_dset,0) , DSET_BRICK_TYPE(base_dset,0),DSET_ARRAY(base_dset,0), /* input */ MRI_float ,base_ary ) ; /* output */ THD_delete_3dim_dataset( base_dset , False ) ; base_dset = NULL ; } /* only 1 'piece' now 13 Dec 2005 [rickr] */ for( piece=0 ; piece < 1 ; piece++ ){ fim_offset = 0 ; #ifdef TTDEBUG printf("*** start of piece %d: length=%d offset=%d\n",piece,nxyz,fim_offset) ; #else if( ! TT_be_quiet ){ printf("--- starting piece %d/%d (%d voxels) ",piece+1,1,nxyz) ; fflush(stdout) ; } #endif /** process set2 (and set1, if paired) **/ for( ii=0 ; ii < nxyz ; ii++ ) av2[ii] = 0.0 ; for( ii=0 ; ii < nxyz ; ii++ ) sd2[ii] = 0.0 ; for( kk=0 ; kk < num2 ; kk++ ){ /** read in the data **/ DOPEN(dset,TT_set2->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set2->ar[kk]); #endif #if 0 /* fimfac will be compute when the results are ready */ if( piece == 0 && kk == 0 ){ fimfac = DSET_BRICK_FACTOR(dset,iv) ; if( fimfac == 0.0 ) fimfac = 1.0 ; fimfacinv = 1.0 / fimfac ; #ifdef TTDEBUG printf(" ** set fimfac = %g\n",fimfac) ; #endif } #endif /** convert it to floats (in ffim) **/ EDIT_coerce_scale_type(nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,ffim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; /** get the paired dataset, if present **/ if( TT_paired ){ DOPEN(dset,TT_set1->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set1->ar[kk]); #endif EDIT_coerce_scale_type( nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,gfim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; if( TT_voxel >= 0 ) fprintf(stderr,"-- paired values #%02d: %f, %f\n", kk,ffim[TT_voxel],gfim[TT_voxel]) ; for( ii=0 ; ii < nxyz ; ii++ ) ffim[ii] -= gfim[ii] ; } else if( TT_voxel >= 0 ) fprintf(stderr,"-- set2 value #%02d: %f\n",kk,ffim[TT_voxel]); #ifdef TTDEBUG printf(" * adding into av2 and sd2\n") ; #endif /* accumulate into av2 and sd2 */ for( ii=0 ; ii < nxyz ; ii++ ){ dd = ffim[ii] ; av2[ii] += dd ; sd2[ii] += dd * dd ; } } /* end of loop over set2 datasets */ /** form the mean and stdev of set2 **/ #ifdef TTDEBUG printf(" ** forming mean and sigma of set2\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] *= num2_inv ; dd = (sd2[ii] - num2*av2[ii]*av2[ii]) ; sd2[ii] = (dd > 0.0) ? sqrt( num2m1_inv * dd ) : 0.0 ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- s2 mean = %g, sd = %g\n", av2[TT_voxel],sd2[TT_voxel]) ; /** if set1 exists but is not paired with set2, process it now **/ if( ! TT_paired && TT_set1 != NULL ){ for( ii=0 ; ii < nxyz ; ii++ ) av1[ii] = 0.0 ; for( ii=0 ; ii < nxyz ; ii++ ) sd1[ii] = 0.0 ; for( kk=0 ; kk < num1 ; kk++ ){ DOPEN(dset,TT_set1->ar[kk]) ; iv = DSET_PRINCIPAL_VALUE(dset) ; #ifndef TTDEBUG if( ! TT_be_quiet ){ printf(".") ; fflush(stdout) ; } /* progress */ #else printf(" ** opened dataset file %s\n",TT_set1->ar[kk]); #endif EDIT_coerce_scale_type( nxyz , DSET_BRICK_FACTOR(dset,iv) , DSET_BRICK_TYPE(dset,iv),DSET_ARRAY(dset,iv), /* input */ MRI_float ,ffim ) ; /* output */ THD_delete_3dim_dataset( dset , False ) ; dset = NULL ; #ifdef TTDEBUG printf(" * adding into av1 and sd1\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ dd = ffim[ii] ; av1[ii] += dd ; sd1[ii] += dd * dd ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- set1 value #%02d: %g\n",kk,ffim[TT_voxel]) ; } /* end of loop over set1 datasets */ /** form the mean and stdev of set1 **/ #ifdef TTDEBUG printf(" ** forming mean and sigma of set1\n") ; #endif for( ii=0 ; ii < nxyz ; ii++ ){ av1[ii] *= num1_inv ; dd = (sd1[ii] - num1*av1[ii]*av1[ii]) ; sd1[ii] = (dd > 0.0) ? sqrt( num1m1_inv * dd ) : 0.0 ; } if( TT_voxel >= 0 ) fprintf(stderr,"-- s1 mean = %g, sd = %g\n", av1[TT_voxel], sd1[TT_voxel]) ; } /* end of processing set1 by itself */ /***** now form difference and t-statistic *****/ #ifndef TTDEBUG if( ! TT_be_quiet ){ printf("+") ; fflush(stdout) ; } /* progress */ #else printf(" ** computing t-tests next\n") ; #endif #if 0 /* will do at end using EDIT_convert_dtype 13 Dec 2005 [rickr] */ /** macro to assign difference value to correct type of array **/ #define DIFASS switch( output_datum ){ \ case MRI_short: sdar[ii] = (short) (fimfacinv*dd) ; break ; \ case MRI_float: fdar[ii] = (float) dd ; break ; } #define TOP_SS 32700 #define TOP_TT (32700.0/FUNC_TT_SCALE_SHORT) #endif if( TT_paired || TT_use_bval == 1 ){ /** case 1: paired estimate or 1-sample **/ if( TT_paired || TT_n1 == 0 ){ /* the olde waye: 1 sample test */ f2 = 1.0 / sqrt( (double) num2 ) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ; /* final mean */ if( sd2[ii] > 0.0 ){ num_tt++ ; tt = av2[ii] / (f2 * sd2[ii]) ; sd2[ii] = tt; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0; } } if( TT_voxel >= 0 ) fprintf(stderr,"-- paired/bval mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; } else { /* 10 Oct 2007: -sdn1 was used with -base1: 'two' sample test */ f1 = (TT_n1-1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ; f2 = (num2 -1.0) * (1.0/TT_n1 + 1.0/num2) / (TT_n1+num2-2.0) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= (base_ary ? base_ary[ii] : TT_bval) ; /* final mean */ q1 = f1 * TT_sd1*TT_sd1 + f2 * sd2[ii]*sd2[ii] ; if( q1 > 0.0 ){ num_tt++ ; tt = av2[ii] / sqrt(q1) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0 ; } } } /* end of -sdn1 special case */ #ifdef TTDEBUG printf(" ** paired or bval test: num_tt = %d\n",num_tt) ; #endif } else if( TT_pooled ){ /** case 2: unpaired 2-sample, pooled variance **/ f1 = (num1-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ; f2 = (num2-1.0) * (1.0/num1 + 1.0/num2) / (num1+num2-2.0) ; for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= av1[ii] ; /* final mean */ q1 = f1 * sd1[ii]*sd1[ii] + f2 * sd2[ii]*sd2[ii] ; if( q1 > 0.0 ){ num_tt++ ; tt = av2[ii] / sqrt(q1) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; } else { sd2[ii] = 0.0 ; } } if( TT_voxel >= 0 ) fprintf(stderr,"-- unpaired, pooled mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; #ifdef TTDEBUG printf(" ** pooled test: num_tt = %d\n",num_tt) ; #endif } else { /** case 3: unpaired 2-sample, unpooled variance **/ /** 27 Dec 2002: modified to save DOF into dofar **/ if( dofbrik != NULL ) dofar = dofbrik + fim_offset ; /* 27 Dec 2002 */ for( ii=0 ; ii < nxyz ; ii++ ){ av2[ii] -= av1[ii] ; q1 = num1_inv * sd1[ii]*sd1[ii] ; q2 = num2_inv * sd2[ii]*sd2[ii] ; if( q1>0.0 && q2>0.0 ){ /* have positive variances? */ num_tt++ ; tt = av2[ii] / sqrt(q1+q2) ; sd2[ii] = tt ; /* final t-stat */ tt = fabs(tt) ; if( tt > tt_max ) tt_max = tt ; if( dofar != NULL ) /* 27 Dec 2002 */ dofar[ii] = (q1+q2)*(q1+q2) / (num1m1_inv*q1*q1 + num2m1_inv*q2*q2) ; } else { sd2[ii] = 0.0 ; if( dofar != NULL ) dofar[ii] = 1.0 ; /* 27 Dec 2002 */ } } if( TT_voxel >= 0 ) fprintf(stderr,"-- unpaired, unpooled mean = %g, t = %g\n", av2[TT_voxel], sd2[TT_voxel]) ; #ifdef TTDEBUG printf(" ** unpooled test: num_tt = %d\n",num_tt) ; #endif } #ifndef TTDEBUG if( ! TT_be_quiet ){ printf("\n") ; fflush(stdout) ; } #endif } /* end of loop over pieces of the input */ if( TT_paired ){ printf("--- Number of degrees of freedom = %d (paired test)\n",num2-1) ; dof = num2 - 1 ; } else if( TT_use_bval == 1 ){ if( TT_n1 == 0 ){ printf("--- Number of degrees of freedom = %d (1-sample test)\n",num2-1) ; dof = num2 - 1 ; } else { dof = TT_n1+num2-2 ; printf("--- Number of degrees of freedom = %d (-sdn1 2-sample test)\n",(int)dof) ; } } else { printf("--- Number of degrees of freedom = %d (2-sample test)\n",num1+num2-2) ; dof = num1+num2-2 ; if( ! TT_pooled ) printf(" (For unpooled variance estimate, this is only approximate!)\n") ; } printf("--- Number of t-tests performed = %d out of %d voxels\n",num_tt,nxyz) ; printf("--- Largest |t| value found = %g\n",tt_max) ; kk = sizeof(ptable) / sizeof(float) ; for( ii=0 ; ii < kk ; ii++ ){ tt = student_p2t( ptable[ii] , dof ) ; printf("--- Double sided tail p = %8f at t = %8f\n" , ptable[ii] , tt ) ; } /**----------------------------------------------------------------------**/ /** now convert data to output format 13 Dec 2005 [rickr] **/ /* first set mean */ fimfac = EDIT_convert_dtype(nxyz , MRI_float,av2 , output_datum,vdif , 0.0) ; DSET_BRICK_FACTOR(new_dset, 0) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; dd = fimfac; /* save for debug output */ /* if output is of type short, limit t-stat magnitude to 32.7 */ if( output_datum == MRI_short ){ for( ii=0 ; ii < nxyz ; ii++ ){ if ( sd2[ii] > 32.7 ) sd2[ii] = 32.7 ; else if( sd2[ii] < -32.7 ) sd2[ii] = -32.7 ; } } fimfac = EDIT_convert_dtype(nxyz , MRI_float,sd2 , output_datum,vsp , 0.0) ; DSET_BRICK_FACTOR(new_dset, 1) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; #ifdef TTDEBUG printf(" ** fimfac for mean, t-stat = %g, %g\n",dd, fimfac) ; #endif /**----------------------------------------------------------------------**/ INFO_message("Writing combined dataset into %s\n", DSET_BRIKNAME(new_dset) ) ; fbuf[0] = dof ; for( ii=1 ; ii < MAX_STAT_AUX ; ii++ ) fbuf[ii] = 0.0 ; (void) EDIT_dset_items( new_dset , ADN_stat_aux , fbuf , ADN_none ) ; #if 0 /* factors already set */ fbuf[0] = (output_datum == MRI_short && fimfac != 1.0 ) ? fimfac : 0.0 ; fbuf[1] = (output_datum == MRI_short ) ? 1.0 / FUNC_TT_SCALE_SHORT : 0.0 ; (void) EDIT_dset_items( new_dset , ADN_brick_fac , fbuf , ADN_none ) ; #endif if( !AFNI_noenv("AFNI_AUTOMATIC_FDR") ) ii = THD_create_all_fdrcurves(new_dset) ; else ii = 0 ; THD_load_statistics( new_dset ) ; THD_write_3dim_dataset( NULL,NULL , new_dset , True ) ; if( ii > 0 ) ININFO_message("created %d FDR curves in header",ii) ; if( dof_dset != NULL ){ /* 27 Dec 2002 */ DSET_write( dof_dset ) ; WROTE_DSET( dof_dset ) ; } exit(0) ; }
Boolean THD_write_datablock( THD_datablock *blk , Boolean write_brick ) { THD_diskptr *dkptr ; Boolean good ; int id , nx , ny , nz , nv , nxy , nxyz , ibr ; int atrank[ATRSIZE_DATASET_RANK] , atdims[ATRSIZE_DATASET_DIMENSIONS] ; MRI_IMAGE *im ; int save_order ; int64_t nb , idone ; int do_mripurge ; /*-- sanity checks --*/ if( ! ISVALID_DATABLOCK(blk) ) return False ; if( DBLK_IS_MASTERED(blk) ) return False ; /* 11 Jan 1999 */ if( DBLK_IS_MINC(blk) ) WRITE_ERR("MINC with bad name extension?") ; /* 29 Oct 2001 */ if( DBLK_IS_ANALYZE(blk) ) WRITE_ERR("ANALYZE but bad name extension?") ; /* 27 Aug 2002 */ if( DBLK_IS_NIFTI(blk) ) WRITE_ERR("NIFTI but bad name extension?") ; /* 28 Aug 2003 */ dkptr = blk->diskptr ; if( ! ISVALID_DISKPTR(dkptr) ) WRITE_ERR("illegal file type") ; if( strlen(dkptr->directory_name) == 0 || strlen(dkptr->header_name) == 0 || strlen(dkptr->filecode) == 0 ) WRITE_ERR("illegal file names stored in dataset") ; if( dkptr->rank != 3 ) WRITE_ERR("cannot write non-3D datablock") ; /*-- create directory if necessary --*/ if( ! THD_is_directory(dkptr->directory_name) ){ id = mkdir( dkptr->directory_name , THD_MKDIR_MODE ) ; if( id != 0 ){ fprintf(stderr, "\n" "*** cannot mkdir new directory: %s\n" " - Do you have permission to write to this disk?\n" " - Is the disk full?\n" , dkptr->directory_name) ; return False ; } } /* 25 April 1998: deal with byte order issues */ if( native_order < 0 ){ /* initialization */ native_order = mri_short_order() ; if( output_order < 0 ) THD_enviro_write_order() ; } if( dkptr->byte_order <= 0 ) dkptr->byte_order = native_order ; save_order = (output_order > 0) ? output_order : dkptr->byte_order ; #if 0 fprintf(stderr,"THD_write_datablock: save_order=%d dkptr->byte_order=%d\n", save_order, dkptr->byte_order ) ; #endif if( save_order != LSB_FIRST && save_order != MSB_FIRST ) save_order = native_order ; if( save_order == LSB_FIRST ) THD_set_string_atr( blk , ATRNAME_BYTEORDER , LSB_FIRST_STRING ) ; else if( save_order == MSB_FIRST ) THD_set_string_atr( blk , ATRNAME_BYTEORDER , MSB_FIRST_STRING ) ; /*-- actually write attributes to disk --*/ good = THD_write_atr( blk ) ; if( good == False ) WRITE_ERR( "failure to write attributes - is disk full? do you have write permission?"); /*-- if not writing data, can exit --*/ if( write_brick == False || blk->brick == NULL || dkptr->storage_mode == STORAGE_UNDEFINED ) return True ; if( dkptr->storage_mode == STORAGE_BY_VOLUMES ){ /* 20 Jun 2002 */ fprintf(stderr,"** Writing dataset by VOLUMES not yet supported.\n") ; return False ; } /*-- check each brick for existence: if none exist, cannot write, but is OK if some but not all exist, cannot write, and is an error --*/ id = THD_count_potential_databricks( blk ) ; if( id <= 0 ) return True ; if( id < blk->nvals ){ ERROR_message("Write dataset error: only %d out of %d bricks in memory", id,blk->nvals) ; return False ; } if( blk->malloc_type == DATABLOCK_MEM_UNDEFINED ) WRITE_ERR("undefined data exists in memory") ; /*-- 13 Mar 2006: check for free disk space --*/ { int mm = THD_freemegabytes( dkptr->header_name ) ; int rr = blk->total_bytes / (1024l * 1024l) ; if( mm >= 0 && mm <= rr ) WARNING_message("Disk space: writing file %s (%d MB)," " but only %d free MB on disk" , dkptr->brick_name , rr , mm ) ; } /*-- write data out in whatever format is ordered --*/ nx = dkptr->dimsizes[0] ; ny = dkptr->dimsizes[1] ; nxy = nx * ny ; nz = dkptr->dimsizes[2] ; nxyz = nxy * nz ; nv = dkptr->nvals ; nb = blk->total_bytes ; switch( dkptr->storage_mode ){ default: WRITE_ERR("illegal storage_mode!") ; break ; case STORAGE_BY_BRICK:{ FILE *far ; Boolean purge_when_done = False , ok ; int force_gzip=0 , csave=COMPRESS_NONE ; /** if we have a mmap-ed file, copy into RAM (ugh) **/ if( blk->malloc_type == DATABLOCK_MEM_MMAP ){ char *bnew , *bold ; int offset ; bnew = (char *) malloc( (size_t)nb ) ; /* work space */ bold = DBLK_ARRAY(blk,0) ; /* start of mapped file */ if( bnew == NULL ) WRITE_ERR("cannot rewrite due to malloc failure - is memory exhausted?") ; memcpy( bnew , bold , (size_t)nb ) ; /* make a copy, */ munmap( (void *) bold , (size_t)nb ) ; /* then unmap file */ /* fix sub-brick pointers */ offset = 0 ; for( ibr=0 ; ibr < nv ; ibr++ ){ mri_fix_data_pointer( (void *)(bnew+offset) , DBLK_BRICK(blk,ibr) ) ; offset += DBLK_BRICK_BYTES(blk,ibr) ; DBLK_BRICK(blk,ibr)->fondisk = 0 ; /* 31 Jan 2007 */ } purge_when_done = True ; } /** fall thru to here if have a malloc-ed dataset **/ if( save_order != native_order ) purge_when_done = True ; /** delete old file, if any **/ COMPRESS_unlink( dkptr->brick_name ) ; /* Feb 1998 */ /** create new file **/ id = strlen(dkptr->directory_name) ; ok = ( dkptr->directory_name[id-1] == '/' ) ; if( ok ) sprintf( dkptr->brick_name , "%s%s.%s", dkptr->directory_name , dkptr->filecode , DATASET_BRICK_SUFFIX ); else sprintf( dkptr->brick_name , "%s/%s.%s", dkptr->directory_name , dkptr->filecode , DATASET_BRICK_SUFFIX ); /** COMPRESS for output added Feb 1998 */ if( compress_mode == COMPRESS_NOFILE ) THD_enviro_write_compression() ; #ifdef COMPRESS_GZIP /*-- 02 Mar 2001: check if we will force gzip --*/ if( compress_mode == COMPRESS_NONE && AFNI_yesenv("AFNI_AUTOGZIP") ){ double entrop = ENTROPY_datablock(blk) ; force_gzip = (entrop < 2.7) ; #if 0 fprintf(stderr,"Entropy=%g ==> forcing write gzip on %s\n",entrop,dkptr->brick_name) ; #endif } else { force_gzip = 0 ; } if( force_gzip ){ csave = compress_mode ; compress_mode = COMPRESS_GZIP ; } #endif far = COMPRESS_fopen_write( dkptr->brick_name , compress_mode ) ; if( far == NULL ){ if( compress_mode != COMPRESS_NONE ){ compress_mode = COMPRESS_NONE ; force_gzip = 0 ; far = COMPRESS_fopen_write( dkptr->brick_name , compress_mode ) ; } } if( far == NULL ) WRITE_ERR("cannot open output brick file - do you have write permission?") ; /** write each brick out in a separate operation **/ idone = 0 ; for( ibr=0 ; ibr < nv ; ibr++ ){ do_mripurge = MRI_IS_PURGED( DBLK_BRICK(blk,ibr) ) ; if( do_mripurge ) mri_unpurge( DBLK_BRICK(blk,ibr) ) ; if( save_order != native_order ){ /* 25 April 1998 */ switch( DBLK_BRICK_TYPE(blk,ibr) ){ default: break ; case MRI_short: mri_swap2( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ; break ; case MRI_complex: /* 23 Nov 1999 */ mri_swap4( 2*DBLK_BRICK_NVOX(blk,ibr), DBLK_ARRAY(blk,ibr)) ; break ; case MRI_float: /* 23 Nov 1999 */ case MRI_int: mri_swap4( DBLK_BRICK_NVOX(blk,ibr) , DBLK_ARRAY(blk,ibr) ) ; break ; } } idone += fwrite( DBLK_ARRAY(blk,ibr), 1, DBLK_BRICK_BYTES(blk,ibr), far ); if( do_mripurge ){ /* 31 Jan 2007 */ if( !purge_when_done ) mri_purge( DBLK_BRICK(blk,ibr) ) ; else mri_clear( DBLK_BRICK(blk,ibr) ) ; } } /* end of loop over sub-bricks */ COMPRESS_fclose(far) ; if( purge_when_done ){ if( blk->malloc_type == DATABLOCK_MEM_MMAP ){ free( DBLK_ARRAY(blk,0) ) ; for( ibr=0 ; ibr < nv ; ibr++ ) mri_clear_data_pointer( DBLK_BRICK(blk,ibr) ) ; } else { THD_purge_datablock( blk , DATABLOCK_MEM_MALLOC ) ; } } if( compress_mode >= 0 || save_order != native_order ){ blk->malloc_type = DATABLOCK_MEM_MALLOC ; } DBLK_mmapfix(blk) ; /* 28 Mar 2005 */ if( force_gzip ) compress_mode = csave ; /* 02 Mar 2001 */ if( idone != blk->total_bytes ) WRITE_ERR("Write error in brick file: Is disk full, or write_protected?") ; dkptr->byte_order = save_order ; /* 23 Nov 1999 */ return True ; } break ; } /* end of switch over data storage mode */ return False ; /* should NEVER be reached */ }
char * MASKAVE_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; THD_3dim_dataset * input_dset , * mask_dset ; int iv , mcount , nvox , ii , sigmait , nvals=0 , doall , ivbot,ivtop ; float mask_bot=666.0 , mask_top=-666.0 ; double sum=0.0 , sigma=0.0 ; float * sumar=NULL , * sigmar=NULL ; char * tag , * str , buf[64] , abuf[32],sbuf[32] ; byte * mmm ; char * cname=NULL ; /* 06 Aug 1998 */ int cdisk=0 ; /* 22 Aug 2000 */ int miv=0 ; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ if( plint == NULL ) return "*************************\n" "MASKAVE_main: NULL input\n" "*************************" ; /*-- read 1st line --*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; input_dset = PLUTO_find_dset(idc) ; if( input_dset == NULL ) return "********************************\n" "MASKAVE_main: bad input dataset\n" "********************************" ; iv = (int) PLUTO_get_number(plint) ; if( iv >= DSET_NVALS(input_dset) ) return "**********************************\n" "MASKAVE_main: bad input sub-brick\n" "**********************************" ; doall = (iv < 0) ; if( doall ){ nvals = DSET_NVALS(input_dset) ; ivbot = 0 ; ivtop = nvals-1 ; } else { ivbot = ivtop = iv ; } DSET_load(input_dset) ; if( DSET_ARRAY(input_dset,ivbot) == NULL ) return "*********************************\n" "MASKAVE_main: can't load dataset\n" "*********************************" ; nvox = DSET_NVOX(input_dset) ; /*-- read 2nd line --*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; mask_dset = PLUTO_find_dset(idc) ; if( mask_dset == NULL ) return "*******************************\n" "MASKAVE_main: bad mask dataset\n" "*******************************" ; if( DSET_NVOX(mask_dset) != nvox ) return "*************************************************************\n" "MASKAVE_main: mask input dataset doesn't match source dataset\n" "*************************************************************" ; miv = (int) PLUTO_get_number(plint) ; /* 06 Aug 1998 */ if( miv >= DSET_NVALS(mask_dset) ) return "*****************************************************\n" "MASKAVE_main: mask dataset sub-brick index is too big\n" "*****************************************************" ; DSET_load(mask_dset) ; if( DSET_ARRAY(mask_dset,0) == NULL ) return "**************************************\n" "MASKAVE_main: can't load mask dataset\n" "**************************************" ; /*-- read optional lines --*/ while( (tag=PLUTO_get_optiontag(plint)) != NULL ){ if( strcmp(tag,"Range") == 0 ){ mask_bot = PLUTO_get_number(plint) ; mask_top = PLUTO_get_number(plint) ; continue ; } if( strcmp(tag,"1D Save") == 0 ){ char * yn ; cname = PLUTO_get_string(plint) ; yn = PLUTO_get_string(plint) ; cdisk = (strcmp(yn,yesno_list[0]) == 0) ; continue ; } } /*------------------------------------------------------*/ /*---------- At this point, the inputs are OK ----------*/ /*-- build a byte mask array --*/ mmm = (byte *) malloc( sizeof(byte) * nvox ) ; if( mmm == NULL ) return "*** Can't malloc workspace! ***" ; /* separate code for each input data type */ switch( DSET_BRICK_TYPE(mask_dset,miv) ){ default: free(mmm) ; return "*** Can't use mask dataset -- illegal data type! ***" ; case MRI_short:{ short mbot , mtop ; short * mar = (short *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = SHORTIZE(mask_bot/mfac) ; mtop = SHORTIZE(mask_top/mfac) ; } else { mbot = (short) -MRI_TYPE_maxval[MRI_short] ; mtop = (short) MRI_TYPE_maxval[MRI_short] ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; case MRI_byte:{ byte mbot , mtop ; byte * mar = (byte *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = BYTEIZE(mask_bot/mfac) ; mtop = BYTEIZE(mask_top/mfac) ; if( mtop == 0 ){ free(mmm) ; return "*** Illegal mask range for mask dataset of bytes. ***" ; } } else { mbot = 0 ; mtop = (byte) MRI_TYPE_maxval[MRI_short] ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; case MRI_float:{ float mbot , mtop ; float * mar = (float *) DSET_ARRAY(mask_dset,miv) ; float mfac = DSET_BRICK_FACTOR(mask_dset,miv) ; if( mfac == 0.0 ) mfac = 1.0 ; if( mask_bot <= mask_top ){ mbot = (float) (mask_bot/mfac) ; mtop = (float) (mask_top/mfac) ; } else { mbot = -WAY_BIG ; mtop = WAY_BIG ; } for( mcount=0,ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mmm[ii] = 1 ; mcount++ ; } else { mmm[ii] = 0 ; } } break ; } if( mcount == 0 ){ free(mmm) ; return "*** No voxels survive the masking operations! ***" ; } sigmait = (mcount > 1) ; /*-- compute statistics --*/ if( doall ){ sumar = (float *) malloc( sizeof(float) * nvals ) ; sigmar = (float *) malloc( sizeof(float) * nvals ) ; } for( iv=ivbot ; iv <= ivtop ; iv++ ){ sum = sigma = 0.0 ; /* 13 Dec 1999 */ switch( DSET_BRICK_TYPE(input_dset,iv) ){ default: free(mmm) ; if( doall ){ free(sumar) ; free(sigmar) ; } return "*** Can't use source dataset -- illegal data type! ***" ; case MRI_short:{ short * bar = (short *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; case MRI_byte:{ byte * bar = (byte *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; case MRI_float:{ float * bar = (float *) DSET_ARRAY(input_dset,iv) ; float mfac = DSET_BRICK_FACTOR(input_dset,iv) ; if( mfac == 0.0 ) mfac = 1.0 ; for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sum += bar[ii] ; sum = sum / mcount ; if( sigmait ){ for( ii=0 ; ii < nvox ; ii++ ) if( mmm[ii] ) sigma += SQR(bar[ii]-sum) ; sigma = mfac * sqrt( sigma/(mcount-1) ) ; } sum = mfac * sum ; } break ; } if( doall ){ sumar[iv] = sum ; sigmar[iv] = sigma ; } } free(mmm) ; /*-- send report --*/ if( doall ){ str = (char *) malloc( 1024 + 64*nvals ) ; sprintf(str," ****** ROI statistics ****** \n" " Source = %s [all sub-bricks] \n" " Mask = %s [%s]" , DSET_FILECODE(input_dset) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) ) ; if( mask_bot <= mask_top ){ sprintf(buf," [range %g .. %g]" , mask_bot , mask_top ) ; strcat(str,buf) ; } strcat(str," \n") ; sprintf(buf," Count = %d voxels\n",mcount) ; strcat(str,buf) ; for( iv=0 ; iv < nvals ; iv++ ){ AV_fval_to_char( sumar[iv] , abuf ) ; AV_fval_to_char( sigmar[iv] , sbuf ) ; sprintf(buf," Average = %9.9s Sigma = %9.9s [%s] \n", abuf,sbuf , DSET_BRICK_LABEL(input_dset,iv) ) ; strcat(str,buf) ; } PLUTO_popup_textwin( plint , str ) ; /* 06 Aug 1998 */ if( cname != NULL && cname[0] != '\0' ){ MRI_IMAGE * qim = mri_new_vol_empty( nvals,1,1 , MRI_float ) ; mri_fix_data_pointer( sumar , qim ) ; PLUTO_register_timeseries( cname , qim ) ; if( cdisk ){ /* 22 Aug 2000 */ if( PLUTO_prefix_ok(cname) ){ char * cn ; if( strstr(cname,".1D") == NULL ){ cn = malloc(strlen(cname)+8) ; strcpy(cn,cname) ; strcat(cn,".1D") ; } else { cn = cname ; } mri_write_1D( cn , qim ) ; if( cn != cname ) free(cn) ; } else { PLUTO_popup_transient(plint," \n" "** Illegal filename **\n" "** in 'To Disk?' !! **\n" ) ; } } mri_fix_data_pointer( NULL , qim ) ; mri_free(qim) ; } free(str) ; free(sumar) ; free(sigmar) ; } else if( mask_bot <= mask_top ){ str = (char *) malloc( 1024 ) ; sprintf( str , " *** ROI Statistics *** \n" " Source = %s [%s] \n" " Mask = %s [%s] [range %g .. %g] \n" " Count = %d voxels \n" " Average = %g \n" " Sigma = %g " , DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) , mask_bot , mask_top , mcount , sum , sigma ) ; PLUTO_popup_message(plint,str) ; free(str) ; } else { str = (char *) malloc( 1024 ) ; sprintf( str , " *** ROI Statistics *** \n" " Source = %s [%s] \n" " Mask = %s [%s] \n" " Count = %d voxels \n" " Average = %g \n" " Sigma = %g " , DSET_FILECODE(input_dset) , DSET_BRICK_LABEL(input_dset,ivbot) , DSET_FILECODE(mask_dset) , DSET_BRICK_LABEL(mask_dset,miv) , mcount , sum , sigma ) ; PLUTO_popup_message(plint,str) ; free(str) ; } return NULL ; }
int main( int argc , char *argv[] ) { MRI_IMAGE *xim , *yim ; float *xar , *yar , *war ; int iarg , ndset , nvox , ii , jj, xyall , clip=0 ; THD_3dim_dataset *xset , *yset , * mask_dset=NULL ; float xbot=1.0f,xtop=0.0f , ybot=1.0f,ytop=0.0f , val ; float xsum,ysum , xsig,ysig ; byte *mmm=NULL ; char *save_hist=NULL, *save_hist_1D=NULL ; /*-- read command line arguments --*/ if( argc < 3 || strncmp(argv[1],"-help",5) == 0 ){ printf("Usage: 3dAcost [options] xset yset\n" "Output = 3dAllineate cost functions between 2 dataset bricks\n" " (for debugging purposes, mostly).\n" "\n" "Options:\n" " -mask mset Means to use the dataset 'mset' as a mask:\n" " Only voxels with nonzero values in 'mset'\n" " will be averaged from 'dataset'. Note\n" " that the mask dataset and the input dataset\n" " must have the same number of voxels.\n" " -histpow p Set histogram power to 'p'; number of bins in\n" " histogram (each axis) = n^p (n=# of points).\n" " (Default is p=0.33333.)\n" " -histbin m Set histogram to use 'm' bins (each axis).\n" " (Max number of bins is 255.)\n" " -savehist ss Save 2D histogram to image file 'ss'\n" " (floating point image; read with 'afni -im')\n" " -savehist_1D dd Save original form of 2D histogram to 1D file 'dd'\n" " (-savehist produces the rootogram)\n" " -xrange a b Use only xset values in range a..b.\n" " -yrange c d Use only yset values in range c..d.\n" " (Default is to use all values.)\n" " -clip Use values from min to mri_topclip()\n" ) ; exit(0) ; } iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcmp(argv[iarg],"-xrange") == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("no arguments after '%s'!",argv[iarg-1]) ; xbot = (float)strtod(argv[iarg++],NULL) ; xtop = (float)strtod(argv[iarg++],NULL) ; continue ; } if( strcmp(argv[iarg],"-yrange") == 0 ){ if( ++iarg >= argc-1 ) ERROR_exit("no arguments after '%s'!",argv[iarg-1]) ; ybot = (float)strtod(argv[iarg++],NULL) ; ytop = (float)strtod(argv[iarg++],NULL) ; continue ; } if( strcmp(argv[iarg],"-clip") == 0 ){ clip = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-savehist") == 0 ){ if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; if( !THD_filename_ok(argv[iarg]) ) ERROR_exit("badly formed filename: '%s' '%s'",argv[iarg-1],argv[iarg]); save_hist = argv[iarg] ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-savehist_1D") == 0 ){ if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; save_hist_1D= argv[iarg] ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-histpow") == 0 ){ double hist_pow ; if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; hist_pow = strtod(argv[iarg],NULL) ; set_2Dhist_hpower(hist_pow) ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-histbin") == 0 ){ int hist_nbin ; if( ++iarg >= argc ) ERROR_exit("no argument after '%s'!",argv[iarg-1]) ; hist_nbin = (int)strtod(argv[iarg],NULL) ; set_2Dhist_hbin(hist_nbin) ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-mask",5) == 0 ){ if( mask_dset != NULL ) ERROR_exit("Can't use -mask twice!") ; if( iarg+1 >= argc ) ERROR_exit("-mask needs a filename!") ; mask_dset = THD_open_dataset( argv[++iarg] ) ; CHECK_OPEN_ERROR(mask_dset,argv[iarg]) ; iarg++ ; continue ; } fprintf(stderr,"*** Unknown option: %s\n",argv[iarg]) ; exit(1) ; } /* should have at least 2 more arguments */ ndset = argc - iarg ; if( ndset <= 1 ){ fprintf(stderr,"*** No input datasets!?\n") ; exit(1) ; } xset = THD_open_dataset(argv[iarg++]) ; CHECK_OPEN_ERROR(xset,argv[iarg-1]) ; yset = THD_open_dataset(argv[iarg++]) ; CHECK_OPEN_ERROR(yset,argv[iarg-1]) ; DSET_load(xset) ; DSET_load(yset) ; CHECK_LOAD_ERROR(xset) ; CHECK_LOAD_ERROR(yset) ; if( DSET_NVALS(xset) > 1 || DSET_NVALS(yset) > 1 ) WARNING_message("Using only sub-brick [0] of input datasets") ; nvox = DSET_NVOX(xset) ; if( nvox != DSET_NVOX(yset) ) ERROR_exit("Input datasets dimensions don't match!") ; xim = mri_scale_to_float( DSET_BRICK_FACTOR(xset,0) , DSET_BRICK(xset,0) ); yim = mri_scale_to_float( DSET_BRICK_FACTOR(yset,0) , DSET_BRICK(yset,0) ); xar = MRI_FLOAT_PTR(xim) ; yar = MRI_FLOAT_PTR(yim) ; DSET_unload(xset); DSET_unload(yset); /* make a byte mask from mask dataset */ war = (float *)malloc(sizeof(float)*nvox) ; if( mask_dset != NULL ){ int mcount ; if( DSET_NVOX(mask_dset) != nvox ) ERROR_exit("Input and mask datasets are not same dimensions!"); mmm = THD_makemask( mask_dset , 0 , 666.0,-666.0 ) ; mcount = THD_countmask( nvox , mmm ) ; if( mcount <= 5 ) ERROR_exit("Mask is too small: %d voxels",mcount) ; DSET_delete(mask_dset) ; for( ii=0 ; ii < nvox ; ii++ ) war[ii] = (float)mmm[ii] ; free((void *)mmm) ; } else { for( ii=0 ; ii < nvox ; ii++ ) war[ii] = 1.0f ; } if( clip ){ xbot = mri_min(xim) ; xtop = mri_topclip(xim) ; INFO_message("xbot=%g xclip=%g",xbot,xtop) ; ybot = mri_min(yim) ; ytop = mri_topclip(yim) ; INFO_message("ybot=%g yclip=%g",ybot,ytop) ; } xyall = 0 ; if( xbot >= xtop ){ xbot = 1.e+38 ; xtop = -1.e+38 ; for( ii=0 ; ii < nvox ; ii++ ) if( war[ii] > 0.0f ){ if( xar[ii] < xbot ) xbot = xar[ii] ; else if( xar[ii] > xtop ) xtop = xar[ii] ; } INFO_message("xbot=%g xtop=%g",xbot,xtop) ; if( xbot >= xtop ) ERROR_exit("no x range?!") ; xyall++ ; } if( ybot >= ytop ){ ybot = 1.e+38 ; ytop = -1.e+38 ; for( ii=0 ; ii < nvox ; ii++ ) if( war[ii] > 0.0f ){ if( yar[ii] < ybot ) ybot = yar[ii] ; else if( yar[ii] > ytop ) ytop = yar[ii] ; } INFO_message("ybot=%g ytop=%g",ybot,ytop) ; if( ybot >= ytop ) ERROR_exit("no y range?!") ; xyall++ ; } if( xyall < 2 ){ for( ii=0 ; ii < nvox ; ii++ ) if( xar[ii] < xbot || xar[ii] > xtop || yar[ii] < ybot || yar[ii] > ytop ) war[ii] = 0.0f ; } xyall = 0 ; for( ii=0 ; ii < nvox ; ii++ ) xyall += (war[ii] > 0.0f) ; INFO_message("Processing %d voxels",xyall) ; if( xyall <= 5 ) ERROR_exit("Too few voxels to continue!") ; xsum = ysum = 0.0f ; for( ii=0 ; ii < nvox ; ii++ ){ if( war[ii] > 0.0f ){ xsum += xar[ii]; ysum += yar[ii]; } } xsum /= xyall ; ysum /= xyall ; INFO_message("xmean=%g ymean=%g",xsum,ysum) ; xsig = ysig = 0.0f ; for( ii=0 ; ii < nvox ; ii++ ){ if( war[ii] > 0.0f ){ val = (xar[ii]-xsum) ; xsig += val*val ; val = (yar[ii]-ysum) ; ysig += val*val ; } } xsig = sqrt( xsig/(xyall-1.0) ); ysig = sqrt( ysig/(xyall-1.0) ); INFO_message("xsig =%g ysig =%g",xsig,ysig) ; val = THD_pearson_corr_wt( nvox , xar , yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Correlation = %+.5f\n",val) ; val = -THD_mutual_info_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("-Mutual Info = %+.5f\n",val ) ; val = THD_norm_mutinf_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("Norm Mutual Info = %+.5f\n",val ) ; #if 0 INFO_message("THD_corr_ratio_scl(%d,%g,%g,xar,%g,%g,yar,war)", nvox , xbot,xtop , ybot,ytop ) ; #endif THD_corr_ratio_sym_mul ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio sym* = %+.5f\n",val) ; THD_corr_ratio_sym_add ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio sym+ = %+.5f\n",val) ; THD_corr_ratio_sym_not ; val = THD_corr_ratio_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; val = 1.0 - fabs(val) ; printf("1-Corr ratio unsym= %+.5f\n",val) ; val = -THD_hellinger_scl( nvox , xbot,xtop,xar , ybot,ytop,yar , war ) ; printf("-Hellinger metric = %+.5f\n",val) ; if( save_hist != NULL ){ /* Save 2D histogram */ int nbin ; float *xyc ; nbin = retrieve_2Dhist( &xyc ) ; if( nbin > 0 && xyc != NULL ){ MRI_IMAGE *fim,*qim ; double ftop ; fim = mri_new(nbin,nbin,MRI_float); mri_fix_data_pointer(xyc,fim); #if 0 for( ii=0 ; ii < nbin*nbin ; ii++ ) xyc[ii] = sqrtf(xyc[ii]) ; ftop = mri_max(fim); if( ftop == 0.0 ) ftop = 1.0; qim = mri_to_byte_scl(255.4/ftop,0.0,fim) ; mri_clear_data_pointer(fim); mri_free(fim); fim = mri_flippo(MRI_ROT_180,1,qim); mri_free(qim); mri_write_pnm(save_hist,fim); mri_free(fim); #else qim = mri_flippo(MRI_ROT_180,1,fim); mri_clear_data_pointer(fim); mri_free(fim); mri_write(save_hist,qim); mri_free(qim); #endif INFO_message("- Saved %dx%d histogram to %s",nbin,nbin,save_hist) ; } } if( save_hist_1D != NULL ){ /* Save 2D raw histogram */ int nbin ; float *xyc ; nbin = retrieve_2Dhist( &xyc ) ; if( nbin > 0 && xyc != NULL ){ FILE *fid=fopen(save_hist_1D,"w"); for( ii=0 ; ii < nbin; ii++ ) { for( jj=0 ; jj < nbin; jj++ ) { fprintf(fid,"%.4f\t", xyc[ii*nbin+jj]); } fprintf(fid,"\n"); } fclose(fid); } INFO_message("- Saved %dx%d 1D histogram to %s",nbin,nbin,save_hist_1D) ; } exit(0) ; }
int main( int argc , char * argv[] ) { float mrad=0.0f , fwhm=0.0f ; int nrep=1 ; char *prefix = "Polyfit" ; char *resid = NULL ; char *cfnam = NULL ; int iarg , verb=0 , do_automask=0 , nord=3 , meth=2 , do_mclip=0 ; THD_3dim_dataset *inset ; MRI_IMAGE *imout , *imin ; byte *mask=NULL ; int nvmask=0 , nmask=0 , do_mone=0 , do_byslice=0 ; MRI_IMARR *exar=NULL ; floatvec *fvit=NULL ; /* 26 Feb 2019 */ if( argc < 2 || strcasecmp(argv[1],"-help") == 0 ){ printf("\n" "Usage: 3dPolyfit [options] dataset ~1~\n" "\n" "* Fits a polynomial in space to the input dataset and outputs that fitted dataset.\n" "\n" "* You can also add your own basis datasets to the fitting mix, using the\n" " '-base' option.\n" "\n" "* You can get the fit coefficients using the '-1Dcoef' option.\n" "\n" "--------\n" "Options: ~1~\n" "--------\n" "\n" " -nord n = Maximum polynomial order (0..9) [default order=3]\n" " [n=0 is the constant 1]\n" " [n=-1 means only use volumes from '-base']\n" "\n" " -blur f = Gaussian blur input dataset (inside mask) with FWHM='f' (mm)\n" "\n" " -mrad r = Radius (voxels) of preliminary median filter of input\n" " [default is no blurring of either type; you can]\n" " [do both types (Gaussian and median), but why??]\n" " [N.B.: median blur is slower than Gaussian]\n" "\n" " -prefix pp = Use 'pp' for prefix of output dataset (the fit).\n" " [default prefix is 'Polyfit'; use NULL to skip this output]\n" "\n" " -resid rr = Use 'rr' for the prefix of the residual dataset.\n" " [default is not to output residuals]\n" "\n" " -1Dcoef cc = Save coefficients of fit into text file cc.1D.\n" " [default is not to save these coefficients]\n" "\n" " -automask = Create a mask (a la 3dAutomask)\n" " -mask mset = Create a mask from nonzero voxels in 'mset'.\n" " [default is not to use a mask, which is probably a bad idea]\n" "\n" " -mone = Scale the mean value of the fit (inside the mask) to 1.\n" " [probably this option is not useful for anything]\n" "\n" " -mclip = Clip fit values outside the rectilinear box containing the\n" " mask to the edge of that box, to avoid weird artifacts.\n" "\n" " -meth mm = Set 'mm' to 2 for least squares fit;\n" " set it to 1 for L1 fit [default method=2]\n" " [Note that L1 fitting is slower than L2 fitting!]\n" "\n" " -base bb = In addition to the polynomial fit, also use\n" " the volumes in dataset 'bb' as extra basis functions.\n" " [If you use a base dataset, then you can set nord]\n" " [to -1, to skip using any spatial polynomial fit.]\n" "\n" " -verb = Print fun and useful progress reports :-)\n" "\n" "------\n" "Notes: ~1~\n" "------\n" "* Output dataset is always stored in float format.\n" "\n" "* If the input dataset has more than 1 sub-brick, only sub-brick #0\n" " is processed. To fit more than one volume, you'll have to use a script\n" " to loop over the input sub-bricks, and then glue (3dTcat) the results\n" " together to get a final result. A simple example:\n" " #!/bin/tcsh\n" " set base = model.nii\n" " set dset = errts.nii\n" " set nval = `3dnvals $dset`\n" " @ vtop = $nval - 1\n" " foreach vv ( `count 0 $vtop` )\n" " 3dPolyfit -base \"$base\" -nord 0 -mask \"$base\" -1Dcoef QQ.$vv -prefix QQ.$vv.nii $dset\"[$vv]\"\n" " end\n" " 3dTcat -prefix QQall.nii QQ.0*.nii\n" " 1dcat QQ.0*.1D > QQall.1D\n" " \rm QQ.0*\n" " exit 0\n" "\n" "* If the '-base' dataset has multiple sub-bricks, all of them are used.\n" "\n" "* You can use the '-base' option more than once, if desired or needed.\n" "\n" "* The original motivation for this program was to fit a spatial model\n" " to a field map MRI, but that didn't turn out to be useful. Nevertheless,\n" " I make this program available to someone who might find it beguiling.\n" "\n" "* If you really want, I could allow you to put sign constraints on the\n" " fit coefficients (e.g., say that the coefficient for a given base volume\n" " should be non-negative). But you'll have to beg for this.\n" "\n" "-- Emitted by RWCox\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } /*-- startup paperwork --*/ mainENTRY("3dPolyfit main"); machdep(); AFNI_logger("3dPolyfit",argc,argv); PRINT_VERSION("3dPolyfit") ; /*-- scan command line --*/ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strcasecmp(argv[iarg],"-base") == 0 ){ THD_3dim_dataset *bset ; int kk ; MRI_IMAGE *bim ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-base'") ; bset = THD_open_dataset(argv[iarg]) ; CHECK_OPEN_ERROR(bset,argv[iarg]) ; DSET_load(bset) ; CHECK_LOAD_ERROR(bset) ; if( exar == NULL ) INIT_IMARR(exar) ; for( kk=0 ; kk < DSET_NVALS(bset) ; kk++ ){ bim = THD_extract_float_brick(kk,bset) ; if( bim != NULL ) ADDTO_IMARR(exar,bim) ; DSET_unload_one(bset,kk) ; } DSET_delete(bset) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-verb") == 0 ){ verb++ ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-hermite") == 0 ){ /* 25 Mar 2013 [New Year's Day] */ mri_polyfit_set_basis("hermite") ; /* HIDDEN */ iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-byslice") == 0 ){ /* 25 Mar 2013 [New Year's Day] */ do_byslice++ ; iarg++ ; continue ; /* HIDDEN */ } if( strcasecmp(argv[iarg],"-mask") == 0 ){ THD_3dim_dataset *mset ; if( ++iarg >= argc ) ERROR_exit("Need argument after '-mask'") ; if( mask != NULL || do_automask ) ERROR_exit("Can't have two mask inputs") ; mset = THD_open_dataset(argv[iarg]) ; CHECK_OPEN_ERROR(mset,argv[iarg]) ; DSET_load(mset) ; CHECK_LOAD_ERROR(mset) ; nvmask = DSET_NVOX(mset) ; mask = THD_makemask( mset , 0 , 0.5f, 0.0f ) ; DSET_delete(mset) ; if( mask == NULL ) ERROR_exit("Can't make mask from dataset '%s'",argv[iarg]) ; nmask = THD_countmask( nvmask , mask ) ; if( nmask < 99 ) ERROR_exit("Too few voxels in mask (%d)",nmask) ; if( verb ) INFO_message("Number of voxels in mask = %d",nmask) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-nord") == 0 ){ nord = (int)strtol( argv[++iarg], NULL , 10 ) ; if( nord < -1 || nord > 9 ) ERROR_exit("Illegal value after -nord :(") ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-meth") == 0 ){ meth = (int)strtol( argv[++iarg], NULL , 10 ) ; if( meth < 1 || meth > 2 ) ERROR_exit("Illegal value after -meth :(") ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-automask",5) == 0 ){ if( mask != NULL ) ERROR_exit("Can't use -mask and -automask together!") ; do_automask++ ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-mclip",5) == 0 ){ do_mclip++ ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-mone",5) == 0 ){ do_mone++ ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-mrad") == 0 ){ mrad = strtod( argv[++iarg] , NULL ) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-blur") == 0 ){ fwhm = strtod( argv[++iarg] , NULL ) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal value after -prefix :("); if( strcasecmp(prefix,"NULL") == 0 ) prefix = NULL ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-resid") == 0 ){ resid = argv[++iarg] ; if( !THD_filename_ok(resid) ) ERROR_exit("Illegal value after -resid :("); if( strcasecmp(resid,"NULL") == 0 ) resid = NULL ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-1Dcoef") == 0 ){ /* 26 Feb 2019 */ cfnam = argv[++iarg] ; if( !THD_filename_ok(cfnam) ) ERROR_exit("Illegal value after -1Dcoef :("); if( strcasecmp(cfnam,"NULL") == 0 ) cfnam = NULL ; iarg++ ; continue ; } ERROR_exit("Unknown option: %s\n",argv[iarg]); } /*--- check for blatant errors ---*/ if( iarg >= argc ) ERROR_exit("No input dataset name on command line?"); if( prefix == NULL && resid == NULL && cfnam == NULL ) ERROR_exit("-prefix and -resid and -1Dcoef are all NULL?!") ; if( do_byslice && cfnam != NULL ){ WARNING_message("-byslice does not work with -1Dcoef option :(") ; cfnam = NULL ; } if( nord < 0 && exar == NULL ) ERROR_exit("no polynomial fit AND no -base option ==> nothing to compute :(") ; /*-- read input --*/ if( verb ) INFO_message("Load input dataset") ; inset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(inset,argv[iarg]) ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; if( DSET_NVALS(inset) > 1 ) WARNING_message( "Only processing sub-brick #0 (out of %d)" , DSET_NVALS(inset) ); /* check input mask or create automask */ if( mask != NULL ){ if( nvmask != DSET_NVOX(inset) ) ERROR_exit("-mask and input datasets don't match in voxel counts :-(") ; } else if( do_automask ){ THD_automask_verbose( (verb > 1) ) ; THD_automask_extclip( 1 ) ; mask = THD_automask( inset ) ; nvmask = DSET_NVOX(inset) ; nmask = THD_countmask( nvmask , mask ) ; if( nmask < 99 ) ERROR_exit("Too few voxels in automask (%d)",nmask) ; if( verb ) ININFO_message("Number of voxels in automask = %d",nmask) ; } else { WARNING_message("3dPolyfit is running without a mask") ; } #undef GOOD #define GOOD(i) (mask == NULL || mask[i]) /* check -base input datasets */ if( exar != NULL ){ int ii,kk , nvbad=0 , nvox=DSET_NVOX(inset),nm ; float *ex , exb ; for( kk=0 ; kk < IMARR_COUNT(exar) ; kk++ ){ if( nvox != IMARR_SUBIM(exar,kk)->nvox ){ if( IMARR_SUBIM(exar,kk)->nvox != nvbad ){ ERROR_message("-base volume (%d voxels) doesn't match input dataset grid size (%d voxels)", IMARR_SUBIM(exar,kk)->nvox , nvox ) ; nvbad = IMARR_SUBIM(exar,kk)->nvox ; } } } if( nvbad != 0 ) ERROR_exit("Cannot continue :-(") ; /* subtract mean from each base input, if is a constant polynomial in the fit */ if( nord >= 0 ){ if( verb ) INFO_message("subtracting spatial mean from '-base'") ; for( kk=0 ; kk < IMARR_COUNT(exar) ; kk++ ){ exb = 0.0f ; ex = MRI_FLOAT_PTR(IMARR_SUBIM(exar,kk)) ; for( nm=ii=0 ; ii < nvox ; ii++ ){ if( GOOD(ii) ){ exb += ex[ii]; nm++; } } exb /= nm ; for( ii=0 ; ii < nvox ; ii++ ) ex[ii] -= exb ; } } } /* if blurring, edit mask a little */ if( mask != NULL && (fwhm > 0.0f || mrad > 0.0f) ){ int ii ; ii = THD_mask_remove_isolas( DSET_NX(inset),DSET_NY(inset),DSET_NZ(inset),mask ) ; if( ii > 0 ){ nmask = THD_countmask( nvmask , mask ) ; if( verb ) ININFO_message("Removed %d isola%s from mask, leaving %d voxels" , ii,(ii==1)?"\0":"s" , nmask ) ; if( nmask < 99 ) ERROR_exit("Too few voxels left in mask after isola removal :-(") ; } } /* convert input to float, which is simpler to deal with */ imin = THD_extract_float_brick(0,inset) ; if( imin == NULL ) ERROR_exit("Can't extract input dataset brick?! :-(") ; DSET_unload(inset) ; if( verb ) INFO_message("Start fitting process") ; /* do the Gaussian blurring */ if( fwhm > 0.0f ){ if( verb ) ININFO_message("Gaussian blur: FWHM=%g mm",fwhm) ; imin->dx = fabsf(DSET_DX(inset)) ; imin->dy = fabsf(DSET_DY(inset)) ; imin->dz = fabsf(DSET_DZ(inset)) ; mri_blur3D_addfwhm( imin , mask , fwhm ) ; } /* do the fitting */ mri_polyfit_verb(verb) ; if( do_byslice ) imout = mri_polyfit_byslice( imin , nord , exar , mask , mrad , meth ) ; else imout = mri_polyfit ( imin , nord , exar , mask , mrad , meth ) ; /* WTF? */ if( imout == NULL ) ERROR_exit("Can't compute polynomial fit :-( !?") ; if( resid == NULL ) mri_free(imin) ; if( ! do_byslice ) fvit = mri_polyfit_get_fitvec() ; /* get coefficients of fit [26 Feb 2019] */ /* scale the fit dataset? */ if( do_mone ){ float sum=0.0f ; int nsum=0 , ii,nvox ; float *par=MRI_FLOAT_PTR(imout) ; nvox = imout->nvox ; for( ii=0 ; ii < nvox ; ii++ ){ if( mask != NULL && mask[ii] == 0 ) continue ; sum += par[ii] ; nsum++ ; } if( nsum > 0 && sum != 0.0f ){ sum = nsum / sum ; if( verb ) ININFO_message("-mone: scaling fit by %g",sum) ; for( ii=0 ; ii < nvox ; ii++ ) par[ii] *= sum ; } } /* if there's a mask, clip values outside of its box */ #undef PF #define PF(i,j,k) par[(i)+(j)*nx+(k)*nxy] if( mask != NULL && do_mclip ){ int xm,xp,ym,yp,zm,zp , ii,jj,kk , nx,ny,nz,nxy ; float *par ; MRI_IMAGE *bim = mri_empty_conforming( imout , MRI_byte ) ; mri_fix_data_pointer(mask,bim) ; if( verb ) ININFO_message("-mclip: polynomial fit to autobox of mask") ; MRI_autobbox( bim , &xm,&xp , &ym,&yp , &zm,&zp ) ; mri_clear_data_pointer(bim) ; mri_free(bim) ; nx = imout->nx ; ny = imout->ny ; nz = imout->nz ; nxy = nx*ny ; par = MRI_FLOAT_PTR(imout) ; for( ii=0 ; ii < xm ; ii++ ) for( kk=0 ; kk < nz ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) PF(ii,jj,kk) = PF(xm,jj,kk) ; for( ii=xp+1 ; ii < nx ; ii++ ) for( kk=0 ; kk < nz ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) PF(ii,jj,kk) = PF(xp,jj,kk) ; for( jj=0 ; jj < ym ; jj++ ) for( kk=0 ; kk < nz ; kk++ ) for( ii=0 ; ii < nx ; ii++ ) PF(ii,jj,kk) = PF(ii,ym,kk) ; for( jj=yp+1 ; jj < ny ; jj++ ) for( kk=0 ; kk < nz ; kk++ ) for( ii=0 ; ii < nx ; ii++ ) PF(ii,jj,kk) = PF(ii,yp,kk) ; for( kk=0 ; kk < zm ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ) PF(ii,jj,kk) = PF(ii,jj,zm) ; for( kk=zp+1 ; kk < nz ; kk++ ) for( jj=0 ; jj < ny ; jj++ ) for( ii=0 ; ii < nx ; ii++ ) PF(ii,jj,kk) = PF(ii,jj,zp) ; } if( mask != NULL ) free(mask) ; /* write outputs */ if( prefix != NULL ){ THD_3dim_dataset *outset = EDIT_empty_copy( inset ) ; EDIT_dset_items( outset , ADN_prefix , prefix , ADN_nvals , 1 , ADN_ntt , 0 , ADN_none ) ; EDIT_substitute_brick( outset , 0 , MRI_float , MRI_FLOAT_PTR(imout) ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dPolyfit" , argc,argv , outset ) ; DSET_write(outset) ; WROTE_DSET(outset) ; } if( resid != NULL ){ THD_3dim_dataset *outset = EDIT_empty_copy( inset ) ; float *inar=MRI_FLOAT_PTR(imin) , *outar=MRI_FLOAT_PTR(imout) ; int nx,ny,nz , nxyz , kk ; nx = imout->nx ; ny = imout->ny ; nz = imout->nz ; nxyz = nx*ny*nz ; for( kk=0 ; kk < nxyz ; kk++ ) outar[kk] = inar[kk] - outar[kk] ; mri_free(imin) ; EDIT_dset_items( outset , ADN_prefix , resid , ADN_nvals , 1 , ADN_ntt , 0 , ADN_none ) ; EDIT_substitute_brick( outset , 0 , MRI_float , MRI_FLOAT_PTR(imout) ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dPolyfit" , argc,argv , outset ) ; DSET_write(outset) ; WROTE_DSET(outset) ; } if( cfnam != NULL && fvit != NULL ){ /* won't work with '-byslice' */ char *qn ; qn = STRING_HAS_SUFFIX(cfnam,".1D") ? cfnam : modify_afni_prefix(cfnam,NULL,".1D") ; mri_write_floatvec( qn , fvit ) ; } exit(0) ; }
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(); }
static char * BFIT_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; THD_3dim_dataset * input_dset , * mask_dset = NULL ; BFIT_data * bfd ; BFIT_result * bfr ; int nvals,ival , nran,nvox , nbin , miv=0 , sqr,sqt ; float abot,atop,bbot,btop,pcut , eps,eps1 , hlast ; float *bval , *cval ; double aa,bb,xc ; double chq,ccc,cdf ; int ihqbot,ihqtop ; int mcount,mgood , ii , jj , ibot,itop ; float mask_bot=666.0 , mask_top=-666.0 , hbot,htop,dbin ; char buf[THD_MAX_NAME+128] , tbuf[THD_MAX_NAME+128] , * tag ; int * hbin , * jbin,*kbin=NULL , *jist[2] ; MRI_IMAGE * flim ; double aext=-1.0,bext=-1.0 ; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ if( plint == NULL ) return "************************\n" "BFIT_main: NULL input\n" "************************" ; /*-- read 1st line --*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; input_dset = PLUTO_find_dset(idc) ; if( input_dset == NULL ) return "****************************\n" "BFIT_main: bad input dataset\n" "****************************" ; nvox = DSET_NVOX(input_dset) ; nvals = DSET_NVALS(input_dset) ; ival = (int) PLUTO_get_number(plint) ; if( ival < 0 || ival >= nvals ) return "**************************\n" "BFIT_main: bad Brick index\n" "**************************" ; DSET_load(input_dset) ; if( DSET_ARRAY(input_dset,0) == NULL ) return "*****************************\n" "BFIT_main: can't load dataset\n" "*****************************" ; tag = PLUTO_get_string(plint) ; sqr = PLUTO_string_index(tag,NYESNO,YESNO_strings) ; /*-- read 2nd line --*/ PLUTO_next_option(plint) ; abot = PLUTO_get_number(plint) ; atop = PLUTO_get_number(plint) ; if( atop <= abot ) return "*** atop <= abot! ***" ; PLUTO_next_option(plint) ; bbot = PLUTO_get_number(plint) ; btop = PLUTO_get_number(plint) ; if( atop <= abot ) return "*** btop <= bbot! ***" ; hlast = PLUTO_get_number(plint) ; PLUTO_next_option(plint) ; nran = (int) PLUTO_get_number(plint) ; pcut = PLUTO_get_number(plint) ; tag = PLUTO_get_string(plint) ; sqt = PLUTO_string_index(tag,NYESNO,YESNO_strings) ; /*-- read optional lines --*/ while( (tag=PLUTO_get_optiontag(plint)) != NULL ){ /*-- Mask itself --*/ if( strcmp(tag,"Mask") == 0 ){ idc = PLUTO_get_idcode(plint) ; mask_dset = PLUTO_find_dset(idc) ; if( mask_dset == NULL ){ return "******************************\n" "BFIT_main: bad mask dataset\n" "******************************" ; } if( DSET_NVOX(mask_dset) != nvox ){ return "************************************************************\n" "BFIT_main: mask input dataset doesn't match source dataset\n" "************************************************************" ; } miv = (int) PLUTO_get_number(plint) ; if( miv >= DSET_NVALS(mask_dset) || miv < 0 ){ return "****************************************************\n" "BFIT_main: mask dataset sub-brick index is illegal\n" "****************************************************" ; } DSET_load(mask_dset) ; if( DSET_ARRAY(mask_dset,miv) == NULL ){ return "*************************************\n" "BFIT_main: can't load mask dataset\n" "*************************************" ; } continue ; } /*-- Mask range of values --*/ if( strcmp(tag,"Range") == 0 ){ if( mask_dset == NULL ){ return "******************************************\n" "BFIT_main: Can't use Range without Mask\n" "******************************************" ; } mask_bot = PLUTO_get_number(plint) ; mask_top = PLUTO_get_number(plint) ; continue ; } /*-- Extra plot --*/ if( strcmp(tag,"Extra") == 0 ){ aext = PLUTO_get_number(plint) ; bext = PLUTO_get_number(plint) ; continue ; } } /*------------------------------------------------------*/ /*---------- At this point, the inputs are OK ----------*/ bfd = BFIT_prepare_dataset( input_dset , ival , sqr , mask_dset , miv , mask_bot , mask_top ) ; if( bfd == NULL ) return "*** BFIT_prepare_dataset fails ***" ; bfr = BFIT_compute( bfd , pcut , abot,atop , bbot,btop , nran,200 ) ; if( bfr == NULL ){ BFIT_free_data( bfd ) ; return "*** BFIT_compute fails! ***" ; } itop = bfr->itop ; mgood = bfr->mgood ; ibot = bfd->ibot ; bval = bfd->bval ; cval = bfd->cval ; mcount = bfd->mcount ; xc = bfr->xcut ; aa = bfr->a ; bb = bfr->b ; eps = bfr->eps ; eps1 = 1.0 - eps ; if( eps1 > 1.0 ) eps1 = 1.0 ; eps1 = (mcount-ibot) * eps1 ; /*-- compute and plot histogram --*/ /* original data was already squared (e.g., R**2 values) */ if( !sqr ){ hbot = 0.0 ; htop = 1.0 ; nbin = 200 ; if( bval[mcount-1] < 1.0 ) htop = bval[mcount-1] ; dbin = (htop-hbot)/nbin ; hbin = (int *) calloc((nbin+1),sizeof(int)) ; /* actual histogram */ jbin = (int *) calloc((nbin+1),sizeof(int)) ; /* theoretical fit */ for( ii=0 ; ii < nbin ; ii++ ){ /* beta fit */ jbin[ii] = (int)( eps1 * ( beta_t2p(hbot+ii*dbin,aa,bb) -beta_t2p(hbot+ii*dbin+dbin,aa,bb) ) ) ; } jist[0] = jbin ; flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ; mri_fix_data_pointer( bval+ibot , flim ) ; mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ; /* "extra" histogram (nominal values?) */ if( aext > 0.0 ){ kbin = (int *) calloc((nbin+1),sizeof(int)) ; jist[1] = kbin ; for( ii=0 ; ii < nbin ; ii++ ){ /* beta fit */ kbin[ii] = (int)( eps1 * ( beta_t2p(hbot+ii*dbin,aext,bext) -beta_t2p(hbot+ii*dbin+dbin,aext,bext) ) ) ; } } } else { /* original data was not squared (e.g., correlations) */ double hb,ht ; htop = 1.0 ; nbin = 200 ; if( bval[mcount-1] < 1.0 ) htop = sqrt(bval[mcount-1]) ; hbot = -htop ; dbin = (htop-hbot)/nbin ; hbin = (int *) calloc((nbin+1),sizeof(int)) ; /* actual histogram */ jbin = (int *) calloc((nbin+1),sizeof(int)) ; /* theoretical fit */ for( ii=0 ; ii < nbin ; ii++ ){ /* beta fit */ hb = hbot+ii*dbin ; ht = hb+dbin ; hb = hb*hb ; ht = ht*ht ; if( hb > ht ){ double qq=hb ; hb=ht ; ht=qq ; } jbin[ii] = (int)( 0.5*eps1 * ( beta_t2p(hb,aa,bb) -beta_t2p(ht,aa,bb) ) ) ; } jist[0] = jbin ; flim = mri_new_vol_empty( mcount-ibot,1,1 , MRI_float ) ; mri_fix_data_pointer( cval+ibot , flim ) ; mri_histogram( flim , hbot,htop , TRUE , nbin,hbin ) ; /* nominal fit */ if( aext > 0.0 ){ kbin = (int *) calloc((nbin+1),sizeof(int)) ; jist[1] = kbin ; for( ii=0 ; ii < nbin ; ii++ ){ /* beta fit */ hb = hbot+ii*dbin ; ht = hb+dbin ; hb = hb*hb ; ht = ht*ht ; if( hb > ht ){ double qq=hb ; hb=ht ; ht=qq ; } kbin[ii] = (int)( 0.5*eps1 * ( beta_t2p(hb,aext,bext) -beta_t2p(ht,aext,bext) ) ) ; } } } sprintf(buf,"%s[%d] a=%.2f b=%.2f \\epsilon=%.2f %%=%.0f", DSET_FILECODE(input_dset),ival,aa,bb,eps,pcut ) ; ccc = bfr->q_chisq ; /* blow up histogram details by sqrt-ing, if ordered */ if( sqt ){ for( ii=0 ; ii < nbin ; ii++ ){ hbin[ii] = (int) sqrt( (double)(100*hbin[ii]+0.5) ) ; jbin[ii] = (int) sqrt( (double)(100*jbin[ii]+0.5) ) ; if( kbin!=NULL ) kbin[ii] = (int) sqrt( (double)(100*kbin[ii]+0.5) ) ; } } /* and plot */ sprintf(tbuf,"\\beta fit: cutoff=%.2f nvox=%d q(\\chi^2)=%8.2e", (sqr)?sqrt(xc):xc , mgood , ccc ) ; if( sqt ){ ii = strlen(tbuf) ; sprintf( tbuf+ii , " \\surd ogram" ) ; } if( hlast > 0.0 ){ hbin[nbin-1] = jbin[nbin-1] = hlast ; if( kbin != NULL ) kbin[nbin-1] = hlast ; } PLUTO_histoplot( nbin,hbot,htop,hbin , tbuf,NULL,buf , (kbin==NULL)?1:2 , jist ) ; /* cleanup */ mri_clear_data_pointer(flim) ; mri_free(flim) ; free(hbin) ; free(jbin) ; if( kbin != NULL ) free(kbin); BFIT_free_data(bfd) ; BFIT_free_result(bfr) ; return NULL ; }
THD_3dim_dataset * fim3d_fimmer_compute ( THD_3dim_dataset * dset_time , time_series_array * ref_ts , time_series_array * ort_ts , int itbot, char * new_prefix, float max_percent /* 19 May 1997 */ ) { THD_3dim_dataset * new_dset ; int ifim , it,iv , nvox=0 , ngood_ref , ntime , it1 , dtyp , nxyz; float * vval , * tsar , * aval , * rbest , * abest ; int * indx=NULL ; short * bar ; void * ptr ; float stataux[MAX_STAT_AUX]; float fthr , topval ; int nx_ref , ny_ref , ivec , nnow ; PCOR_references ** pc_ref ; PCOR_voxel_corr ** pc_vc ; int save_resam ; int fim_nref , nx_ort , ny_ort=0 , internal_ort ; /* 10 Dec 1996 */ static float * ref_vec = NULL ; static int nref_vec = -666 ; float * ref_ts_min = NULL, * ref_ts_max = NULL, * baseline = NULL; /* 19 May 1997 */ int i; int nupdt = 0 , /* number of updates done yet */ min_updt = 5 ; /* min number needed for display */ /*--- check for legal inputs ---*/ /* 14 Jan 1998 */ if (!DSET_GRAPHABLE(dset_time)) { fprintf (stderr, "Error: Invalid 3d+time input data file \n"); RETURN (NULL); } if (ref_ts == NULL) { fprintf (stderr, "Error: No ideal time series \n"); RETURN (NULL); } for (i = 0; i < ref_ts->num; i++) if (ref_ts->tsarr[i]->len < DSET_NUM_TIMES(dset_time)) { fprintf (stderr, "Error: ideal time series is too short: ntime=%d num_ts=%d \n", DSET_NUM_TIMES(dset_time), ref_ts->tsarr[i]->len); RETURN (NULL) ; } /** 10 Dec 1996: allow for orts **/ if( ort_ts->num > 0 ) /** 05 Sept 1997 **/ { internal_ort = 0; ny_ort = ort_ts->num; for (i = 0; i < ny_ort; i++) { nx_ort = ort_ts->tsarr[i]->len ; if (nx_ort < DSET_NUM_TIMES(dset_time)) /* 14 Jan 1998 */ { fprintf (stderr, "Error: ort time series is too short: ntime=%d ort_ts=%d \n", DSET_NUM_TIMES(dset_time), ort_ts->tsarr[i]->len); RETURN (NULL) ; } } } else { internal_ort = 1 ; } fim_nref = (internal_ort) ? 3 : (ny_ort+3) ; if( nref_vec < fim_nref ) { ref_vec = (float *) malloc (sizeof(float)*fim_nref) ; nref_vec = fim_nref; } /* arrays to store maximum change in the ideal time series */ if (max_percent > 0.0) /* 19 May 1997 */ { ref_ts_max = (float *) malloc (sizeof(float) * (ref_ts->num)); ref_ts_min = (float *) malloc (sizeof(float) * (ref_ts->num)); } nx_ref = ref_ts->tsarr[0]->len; ny_ref = ref_ts->num; ntime = DSET_NUM_TIMES(dset_time) ; ngood_ref = 0 ; it1 = -1 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ tsar = ref_ts->tsarr[ivec]->ts; ifim = 0 ; if (max_percent > 0.0) /* 19 May 1997 */ { ref_ts_min[ivec] = (float) SO_BIG; ref_ts_max[ivec] = - (float) SO_BIG; } for( it=itbot ; it < ntime ; it++ ) { if( tsar[it] < SO_BIG ) { ifim++ ; if( it1 < 0 ) it1 = it ; if (max_percent > 0.0) /* 19 May 1997 */ { if (tsar[it] > ref_ts_max[ivec]) ref_ts_max[ivec] = tsar[it]; if (tsar[it] < ref_ts_min[ivec]) ref_ts_min[ivec] = tsar[it]; } } } if( ifim < min_updt ){ STATUS("ref_ts has too few good entries!") ; RETURN(NULL) ; } ngood_ref = MAX( ifim , ngood_ref ) ; } /** at this point, ngood_ref = max number of good reference points, and it1 = index of first point used in first reference **/ dtyp = DSET_BRICK_TYPE(dset_time,it1) ; if( ! AFNI_GOOD_FUNC_DTYPE(dtyp) ){ STATUS("illegal input data type!") ; RETURN(NULL) ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"new prefix = %s",new_prefix) ; STATUS(str) ; } #endif /*--- FIM: find values above threshold to fim ---*/ DSET_load(dset_time); CHECK_LOAD_ERROR(dset_time); nxyz = dset_time->dblk->diskptr->dimsizes[0] * dset_time->dblk->diskptr->dimsizes[1] * dset_time->dblk->diskptr->dimsizes[2] ; /** find the mean of the first array, compute the threshold (fthr) from it, make indx[i] be the 3D index of the i-th voxel above threshold **/ switch( dtyp ){ case MRI_short:{ short * dar = (short *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += abs(dar[iv]) ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( abs(dar[iv]) > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( abs(dar[iv]) > fthr ) indx[nvox++] = iv ; } break ; case MRI_float:{ float * dar = (float *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += fabs(dar[iv]) ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( fabs(dar[iv]) > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( fabs(dar[iv]) > fthr ) indx[nvox++] = iv ; } break ; case MRI_byte:{ byte * dar = (byte *) DSET_ARRAY(dset_time,it1) ; for( iv=0,fthr=0.0 ; iv < nxyz ; iv++ ) fthr += dar[iv] ; fthr = FIM_THR * fthr / nxyz ; for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( dar[iv] > fthr ) nvox++ ; indx = (int *) malloc( sizeof(int) * nvox ) ; if( indx == NULL ){ fprintf(stderr,"\n*** indx malloc failure in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } for( iv=0,nvox=0 ; iv < nxyz ; iv++ ) if( dar[iv] > fthr ) indx[nvox++] = iv ; } break ; } /** allocate space for voxel values **/ vval = (float *) malloc( sizeof(float) * nvox) ; if( vval == NULL ){ fprintf(stderr,"\n*** vval malloc failure in fim3d_fimmer_compute\n") ; free(indx) ; RETURN(NULL) ; } /*----- allocate space for baseline values -----*/ if (max_percent > 0.0) /* 19 May 1997 */ { baseline = (float *) malloc (sizeof(float) * nvox); if (baseline == NULL) { fprintf(stderr, "\n*** baseline malloc failure in fim3d_fimmer_compute\n") ; free(indx) ; free(vval); RETURN(NULL) ; } else /* initialize baseline values to zero */ for (iv = 0; iv < nvox; iv++) baseline[iv] = 0.0; } /** allocate extra space for comparing results from multiple ref vectors **/ if( ny_ref > 1 ){ aval = (float *) malloc( sizeof(float) * nvox) ; rbest = (float *) malloc( sizeof(float) * nvox) ; abest = (float *) malloc( sizeof(float) * nvox) ; if( aval==NULL || rbest==NULL || abest==NULL ){ fprintf(stderr,"\n*** abest malloc failure in fim3d_fimmer_compute\n") ; free(vval) ; free(indx) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } } else { aval = rbest = abest = NULL ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"nxyz = %d nvox = %d",nxyz,nvox) ; STATUS(str) ; } #endif /*--- FIM: initialize recursive updates ---*/ pc_ref = (PCOR_references **) malloc( sizeof(PCOR_references *) * ny_ref ) ; pc_vc = (PCOR_voxel_corr **) malloc( sizeof(PCOR_voxel_corr *) * ny_ref ) ; if( pc_ref == NULL || pc_vc == NULL ){ free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } ifim = 0 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ pc_ref[ivec] = new_PCOR_references( fim_nref ) ; pc_vc[ivec] = new_PCOR_voxel_corr( nvox , fim_nref ) ; if( pc_ref[ivec] == NULL || pc_vc[ivec] == NULL ) ifim++ ; } if( ifim > 0 ){ for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; fprintf(stderr,"\n*** FIM initialization fails in fim3d_fimmer_compute\n") ; RETURN(NULL) ; } /*--- Make a new dataset to hold the output ---*/ new_dset = EDIT_empty_copy( dset_time ) ; it = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , ADN_malloc_type , DATABLOCK_MEM_MALLOC , ADN_type , ISHEAD(dset_time) ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_COR_TYPE , ADN_nvals , FUNC_nvals[FUNC_COR_TYPE] , ADN_datum_all , MRI_short , ADN_ntt , 0 , ADN_none ) ; if( it > 0 ){ fprintf(stderr, "\n*** EDIT_dset_items error %d in fim3d_fimmer_compute\n",it) ; THD_delete_3dim_dataset( new_dset , False ) ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } for( iv=0 ; iv < new_dset->dblk->nvals ; iv++ ){ ptr = malloc( DSET_BRICK_BYTES(new_dset,iv) ) ; mri_fix_data_pointer( ptr , DSET_BRICK(new_dset,iv) ) ; } if( THD_count_databricks(new_dset->dblk) < new_dset->dblk->nvals ){ fprintf(stderr, "\n*** failure to malloc new bricks in fim3d_fimmer_compute\n") ; THD_delete_3dim_dataset( new_dset , False ) ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; RETURN(NULL) ; } /*--- FIM: do recursive updates ---*/ for( it=itbot ; it < ntime ; it++ ){ nnow = 0 ; for( ivec=0 ; ivec < ny_ref ; ivec++ ){ tsar = ref_ts->tsarr[ivec]->ts ; if( tsar[it] >= SO_BIG ) continue ; /* skip this */ ref_vec[0] = 1.0 ; /* we always supply orts */ ref_vec[1] = (float) it ; /* for mean and linear trend */ if (internal_ort) /* 10 Dec 1996 */ { ref_vec[2] = tsar[it] ; } else { for( iv=0 ; iv < ny_ort ; iv++ ) ref_vec[iv+2] = ort_ts->tsarr[iv]->ts[it]; ref_vec[ny_ort+2] = tsar[it] ; } #ifdef AFNI_DEBUG { char str[256] ; sprintf(str,"time index=%d ideal[%d]=%f" , it,ivec,tsar[it] ) ; if (ivec == 0) STATUS(str) ; } #endif update_PCOR_references( ref_vec , pc_ref[ivec] ) ; switch( dtyp ){ case MRI_short:{ short * dar = (short *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; case MRI_float:{ float * dar = (float *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; case MRI_byte:{ byte * dar = (byte *) DSET_ARRAY(dset_time,it) ; for( iv=0 ; iv < nvox ; iv++ ) vval[iv] = (float) dar[indx[iv]] ; } break ; } PCOR_update_float( vval , pc_ref[ivec] , pc_vc[ivec] ) ; nnow++ ; /*----- update baseline value calculation -----*/ if (max_percent > 0.0) /* 19 May 1997 */ if (ivec == 0) for (iv = 0; iv < nvox; iv++) baseline[iv] += vval[iv] / ngood_ref; } if( nnow > 0 ) nupdt++ ; /*--- Load results into the dataset and redisplay it ---*/ if( nupdt == ngood_ref ) { /*--- set the statistical parameters ---*/ stataux[0] = nupdt ; /* number of points used */ stataux[1] = (ny_ref==1) ? 1 : 2 ; /* number of references */ stataux[2] = fim_nref - 1 ; /* number of orts */ /* 12 Dec 96 */ for( iv=3 ; iv < MAX_STAT_AUX ; iv++ ) stataux[iv] = 0.0 ; STATUS("setting statistical parameters") ; (void) EDIT_dset_items( new_dset , ADN_stat_aux , stataux , ADN_none ) ; /*** Compute brick arrays for new dataset ***/ if( ny_ref == 1 ){ /*** Just 1 ref vector --> load values directly into dataset ***/ /*--- get alpha (coef) into vval, find max value, scale into brick array ---*/ STATUS("getting 1 ref alpha") ; PCOR_get_coef( pc_ref[0] , pc_vc[0] , vval ) ; /*--- replace alpha with percentage change, if so requested ---*/ if (max_percent > 0.0) /* 19 May 1997 */ { for (iv = 0; iv < nvox; iv++) { vval[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]); if (fabs(vval[iv]) < max_percent * fabs(baseline[iv])) vval[iv] = fabs( vval[iv] / baseline[iv] ); else vval[iv] = max_percent; } topval = max_percent; } else { topval = 0.0 ; for( iv=0 ; iv < nvox ; iv++ ) if( fabs(vval[iv]) > topval ) topval = fabs(vval[iv]) ; } bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; if( topval > 0.0 ){ topval = MRI_TYPE_maxval[MRI_short] / topval ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(topval * vval[iv] + 0.499) ; stataux[0] = 1.0/topval ; } else { stataux[0] = 0.0 ; } /*--- get correlation coefficient (pcor) into vval, scale into brick array (with fixed scaling factor) ---*/ STATUS("getting 1 ref pcor") ; PCOR_get_pcor( pc_ref[0] , pc_vc[0] , vval ) ; bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * vval[iv] + 0.499) ; stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ; } else { /*** Multiple references --> find best correlation at each voxel ***/ /*--- get first ref results into abest and rbest (best so far) ---*/ PCOR_get_coef( pc_ref[0] , pc_vc[0] , abest ) ; /*--- modify alpha for percentage change calculation ---*/ if (max_percent > 0.0) /* 19 May 1997 */ for (iv = 0; iv < nvox; iv++) abest[iv] *= 100.0 * (ref_ts_max[0] - ref_ts_min[0]); PCOR_get_pcor( pc_ref[0] , pc_vc[0] , rbest ) ; /*--- for each succeeding ref vector, get results into aval and vval, if |vval| > |rbest|, then use that result instead ---*/ for( ivec=1 ; ivec < ny_ref ; ivec++ ){ PCOR_get_coef( pc_ref[ivec] , pc_vc[ivec] , aval ) ; PCOR_get_pcor( pc_ref[ivec] , pc_vc[ivec] , vval ) ; for( iv=0 ; iv < nvox ; iv++ ){ if( fabs(vval[iv]) > fabs(rbest[iv]) ){ rbest[iv] = vval[iv] ; abest[iv] = aval[iv] ; /*--- modify alpha for percentage change calculation ---*/ if (max_percent > 0.0) /* 19 May 1997 */ abest[iv] *= 100.0 * (ref_ts_max[ivec] - ref_ts_min[ivec]); } } } /*--- at this point, abest and rbest are the best results, so scale them into the dataset bricks ---*/ /*--- finish percentage change calculation, if so requested ---*/ if (max_percent > 0.0) /* 19 May 1997 */ { for (iv = 0; iv < nvox; iv++) { if (fabs(abest[iv]) < max_percent * fabs(baseline[iv])) abest[iv] = fabs( abest[iv] / baseline[iv] ); else abest[iv] = max_percent; } topval = max_percent; } else { topval = 0.0 ; for( iv=0 ; iv < nvox ; iv++ ) if( fabs(abest[iv]) > topval ) topval = fabs(abest[iv]) ; } bar = DSET_ARRAY( new_dset , FUNC_ival_fim[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; if( topval > 0.0 ){ topval = MRI_TYPE_maxval[MRI_short] / topval ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(topval * abest[iv] + 0.499) ; stataux[0] = 1.0/topval ; } else { stataux[0] = 0.0 ; } bar = DSET_ARRAY( new_dset , FUNC_ival_thr[FUNC_COR_TYPE] ) ; memset( bar , 0 , sizeof(short)*nxyz ) ; for( iv=0 ; iv < nvox ; iv++ ) bar[indx[iv]] = (short)(FUNC_COR_SCALE_SHORT * rbest[iv] + 0.499) ; stataux[1] = 1.0 / FUNC_COR_SCALE_SHORT ; } STATUS("setting brick_fac") ; (void) EDIT_dset_items( new_dset , ADN_brick_fac , stataux , ADN_none ) ; } } /*--- End of recursive updates; now free temporary workspaces ---*/ for( ivec=0 ; ivec < ny_ref ; ivec++ ){ free_PCOR_references(pc_ref[ivec]) ; free_PCOR_voxel_corr(pc_vc[ivec]) ; } free(vval) ; free(indx) ; free(pc_ref) ; free(pc_vc) ; if( aval != NULL ) free(aval) ; if( rbest != NULL ) free(rbest) ; if( abest != NULL ) free(abest) ; if (ref_ts_min != NULL) free (ref_ts_min); /* 19 May 1997 */ if (ref_ts_max != NULL) free (ref_ts_max); if (baseline != NULL) free (baseline); /* --- load the statistics --- */ THD_load_statistics (new_dset); /*--- Return new dataset ---*/ RETURN(new_dset) ; }
MRI_IMAGE * mri_flip3D( int outx, int outy, int outz, MRI_IMAGE *inim ) { MRI_IMAGE *outim ; int ii,jj,kk , dsiz , nxin,nyin,nzin , nxout,nyout,nzout ; int nxyin , nxyout , ijk_out , ijk_in ; int ax,bx,cx,dx , ay,by,cy,dy , az,bz,cz,dz , aa,bb,cc,dd ; char *inar , *outar ; float delx,dely,delz ; ENTRY("mri_flip3D") ; /* check inputs for correctness */ if( inim == NULL || outx == 0 || outy == 0 || outz == 0 ) RETURN( NULL ); ii = abs(outx) ; jj = abs(outy) ; kk = abs(outz) ; if( ii > 3 || jj > 3 || kk > 3 ) RETURN( NULL ); if( ii == jj || ii == kk || jj == kk ) RETURN( NULL ); if( ii+jj+kk != 6 ) RETURN( NULL ); if( outx==1 && outy==2 && outz==3 ) RETURN( mri_copy(inim) ); /* easy case */ nxin = inim->nx ; nyin = inim->ny ; nxyin = nxin*nyin ; nzin = inim->nz ; /* setup so that i_out = ax + bx*i_in + cx*j_in + dx*k_in, for i_in=0..nxin-1, j_in=0..nyin-1, k_in=0..nzin-1, and then similarly for y and z axes */ switch( outx ){ case 1: ax=0 ; bx= 1; cx= 0; dx= 0; nxout=nxin; delx=inim->dx; break; case -1: ax=nxin-1; bx=-1; cx= 0; dx= 0; nxout=nxin; delx=inim->dx; break; case 2: ax=0 ; bx= 0; cx= 1; dx= 0; nxout=nyin; delx=inim->dy; break; case -2: ax=nyin-1; bx= 0; cx=-1; dx= 0; nxout=nyin; delx=inim->dy; break; case 3: ax=0 ; bx= 0; cx= 0; dx= 1; nxout=nzin; delx=inim->dz; break; case -3: ax=nzin-1; bx= 0; cx= 0; dx=-1; nxout=nzin; delx=inim->dz; break; default: RETURN( NULL ); } switch( outy ){ case 1: ay=0 ; by= 1; cy= 0; dy= 0; nyout=nxin; dely=inim->dx; break; case -1: ay=nxin-1; by=-1; cy= 0; dy= 0; nyout=nxin; dely=inim->dx; break; case 2: ay=0 ; by= 0; cy= 1; dy= 0; nyout=nyin; dely=inim->dy; break; case -2: ay=nyin-1; by= 0; cy=-1; dy= 0; nyout=nyin; dely=inim->dy; break; case 3: ay=0 ; by= 0; cy= 0; dy= 1; nyout=nzin; dely=inim->dz; break; case -3: ay=nzin-1; by= 0; cy= 0; dy=-1; nyout=nzin; dely=inim->dz; break; default: RETURN( NULL ); } switch( outz ){ case 1: az=0 ; bz= 1; cz= 0; dz= 0; nzout=nxin; delz=inim->dx; break; case -1: az=nxin-1; bz=-1; cz= 0; dz= 0; nzout=nxin; delz=inim->dx; break; case 2: az=0 ; bz= 0; cz= 1; dz= 0; nzout=nyin; delz=inim->dy; break; case -2: az=nyin-1; bz= 0; cz=-1; dz= 0; nzout=nyin; delz=inim->dy; break; case 3: az=0 ; bz= 0; cz= 0; dz= 1; nzout=nzin; delz=inim->dz; break; case -3: az=nzin-1; bz= 0; cz= 0; dz=-1; nzout=nzin; delz=inim->dz; break; default: RETURN( NULL ); } nxyout = nxout*nyout ; /* 3D index ijk_out = i_out + nxout*j_out + nxyout*k_out = (ax + bx*i_in + cx*j_in + dx*k_in) +(ay + by*i_in + cy*j_in + dy*k_in)*nxout +(az + bz*i_in + cz*j_in + dz*k_in)*nxyout = (ax+ay*nxout+az*nxyout) +(bx+by*nxout+bz*nxyout)*i_in +(cx+cy*nxout+cz*nxyout)*j_in +(dx+dy*nxout+dz*nxyout)*k_in = aa + bb*i_in + cc*j_in + dd*k_in */ inar = mri_data_pointer( inim ) ; outim = mri_new_vol( nxout,nyout,nzout , inim->kind ) ; outim->dx = delx ; outim->dy = dely ; outim->dz = delz ; outar = mri_data_pointer( outim ) ; if( inar == NULL ){ /* empty input ==> empty output */ free(outar) ; mri_fix_data_pointer(NULL,outim ); RETURN(outim); } dsiz = outim->pixel_size ; /* size of each voxel in bytes */ aa = (ax+ay*nxout+az*nxyout)*dsiz ; /* same as aa, etc. in above */ bb = (bx+by*nxout+bz*nxyout)*dsiz ; /* comment, but scaled to be */ cc = (cx+cy*nxout+cz*nxyout)*dsiz ; /* address offset in bytes */ dd = (dx+dy*nxout+dz*nxyout)*dsiz ; for( ijk_in=kk=0 ; kk < nzin ; kk++ ){ for( jj=0 ; jj < nyin ; jj++ ){ for( ii=0 ; ii < nxin ; ii++,ijk_in+=dsiz ){ ijk_out = aa + bb*ii + cc*jj + dd*kk ; memcpy( outar+ijk_out , inar+ijk_in , dsiz ) ; } } } RETURN(outim) ; }
void THD_load_nifti( THD_datablock *dblk ) { THD_diskptr *dkptr ; int nx,ny,nz,nxy,nxyz,nxyzv , nerr=0,ibr,nv, nslice ; int datum, need_copy=0 ; int scale_data=0 ; void *ptr ; nifti_image *nim ; nifti_brick_list NBL ; /* holds the data read from disk */ ENTRY("THD_load_nifti") ; /*-- open and read input [these errors should never occur] --*/ if( !ISVALID_DATABLOCK(dblk) || dblk->diskptr->storage_mode != STORAGE_BY_NIFTI || dblk->brick == NULL ) EXRETURN ; dkptr = dblk->diskptr ; /* purge any existing bricks [10 Mar 2014] */ STATUS("purging existing data bricks (if any)") ; THD_purge_datablock(dblk,DATABLOCK_MEM_ANY) ; STATUS("calling nifti_image_read_bricks") ; NBL.nbricks = 0 ; if( ! DBLK_IS_MASTERED(dblk) ) /* allow mastering 14 Apr 2006 [rickr] */ nim = nifti_image_read_bricks( dkptr->brick_name, 0,NULL , &NBL ) ; else { /* n2 10 Jul, 2015 [rickr] */ /* convert master_ival to an array of int64_t */ int64_t * i64_vals = copy_ints_as_i64(dblk->master_ival, dblk->nvals); nim = nifti_image_read_bricks( dkptr->brick_name, dblk->nvals, i64_vals, &NBL ) ; } if( nim == NULL || NBL.nbricks <= 0 ) EXRETURN ; datum = DBLK_BRICK_TYPE(dblk,0) ; /* destination data type */ /*-- determine if we need to copy the data from the bricks as loaded above because of a type conversion --*/ switch( nim->datatype ){ case DT_INT16: case DT_UINT8: need_copy = (datum == MRI_float) ; break ; case DT_FLOAT32: case DT_COMPLEX64: case DT_RGB24: need_copy = 0 ; break ; case DT_INT8: /* these are the cases where AFNI can't */ case DT_UINT16: /* directly handle the NIFTI datatype, */ case DT_INT32: /* so we'll convert them to floats. */ case DT_UINT32: case DT_FLOAT64: need_copy = 1 ; break ; #if 0 case DT_COMPLEX128: need_copy = 1 ; break ; #endif } /*-- various dimensions --*/ nx = dkptr->dimsizes[0] ; ny = dkptr->dimsizes[1] ; nxy = nx * ny ; nz = dkptr->dimsizes[2] ; nxyz = nxy * nz ; nv = dkptr->nvals ; if( nv > NBL.nbricks ) nv = NBL.nbricks ; nxyzv = nxyz * nv ; nslice = nz*nv ; dblk->malloc_type = DATABLOCK_MEM_MALLOC ; /*------ don't need to copy data ==> just copy pointers from NBL ------*/ if( !need_copy ){ STATUS("copying brick pointers directly") ; for( ibr=0 ; ibr < nv ; ibr++ ){ mri_fix_data_pointer( NBL.bricks[ibr] ,DBLK_BRICK(dblk,ibr) ) ; NBL.bricks[ibr] = NULL ; /* so it won't be deleted later */ if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_float ){ STATUS("doing floatscan") ; nerr += thd_floatscan( DBLK_BRICK_NVOX(dblk,ibr) , DBLK_ARRAY(dblk,ibr) ) ; } else if( DBLK_BRICK_TYPE(dblk,ibr) == MRI_complex ){ STATUS("doing complexscan") ; nerr += thd_complexscan( DBLK_BRICK_NVOX(dblk,ibr) , DBLK_ARRAY(dblk,ibr) ) ; } } if( nerr > 0 ) WARNING_message("file %s: corrected %d float errors\n", dkptr->brick_name , nerr ) ; } else { /*---------- need to copy data ==> do some more work -----------*/ register int ii ; void *nbuf ; STATUS("converting input bricks to floats") ; for( ibr=0 ; ibr < nv ; ibr++ ){ if( DBLK_ARRAY(dblk,ibr) == NULL ){ /* make space */ ptr = AFMALL(void, DBLK_BRICK_BYTES(dblk,ibr) ) ; /* for this */ if( ptr == NULL ) ERROR_message("malloc fails for NIfTI sub-brick #%d",ibr) ; mri_fix_data_pointer( ptr , DBLK_BRICK(dblk,ibr) ) ; /* sub-brick! */ } ptr = DBLK_ARRAY(dblk,ibr) ; if( ptr == NULL ) break ; /* bad news!! */ nbuf = NBL.bricks[ibr] ; /* data as read from NIfTI file */ /* macro to convert data from type "ityp" in nbuf to float in dataset */ #undef CPF #define CPF(ityp) do{ ityp *sar = (ityp *)nbuf ; float *far = (float *)ptr ; \ for( ii=0 ; ii < nxyz ; ii++ ) far[ii] = (float)sar[ii]; \ } while(0) /* load from nbuf into brick array (will be float or complex) */ STATUS(" converting sub-brick") ; switch( nim->datatype ){ case DT_UINT8: CPF(unsigned char) ; break ; case DT_INT8: CPF(signed char) ; break ; case DT_INT16: CPF(signed short) ; break ; case DT_UINT16: CPF(unsigned short) ; break ; case DT_INT32: CPF(signed int) ; break ; case DT_UINT32: CPF(unsigned int) ; break ; case DT_FLOAT64: /* added floatscan 2 Dec, 2014 [rickr] */ { CPF(double) ; thd_floatscan(nxyz, (float *)ptr) ; break ; } #if 0 case DT_COMPLEX128: break ; #endif } STATUS(" free-ing NIfTI volume") ; free(NBL.bricks[ibr]) ; NBL.bricks[ibr] = NULL ; } }
char * IMREG_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; /* input dataset idcode */ THD_3dim_dataset * old_dset , * new_dset ; /* input and output datasets */ char * new_prefix , * str ; /* strings from user */ int base , ntime , datum , nx,ny,nz , ii,kk , npix ; float dx,dy,dz ; MRI_IMARR * ims_in , * ims_out ; MRI_IMAGE * im , * imbase ; byte ** bptr = NULL , ** bout = NULL ; short ** sptr = NULL , ** sout = NULL ; float ** fptr = NULL , ** fout = NULL ; float * dxar = NULL , * dyar = NULL , * phiar = NULL ; /*--------------------------------------------------------------------*/ /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/ /*--------- go to first input line ---------*/ PLUTO_next_option(plint) ; idc = PLUTO_get_idcode(plint) ; /* get dataset item */ old_dset = PLUTO_find_dset(idc) ; /* get ptr to dataset */ if( old_dset == NULL ) return "*************************\n" "Cannot find Input Dataset\n" "*************************" ; ntime = DSET_NUM_TIMES(old_dset) ; if( ntime < 2 ) return "*****************************\n" "Dataset has only 1 time point\n" "*****************************" ; ii = DSET_NVALS_PER_TIME(old_dset) ; if( ii > 1 ) return "************************************\n" "Dataset has > 1 value per time point\n" "************************************" ; nx = old_dset->daxes->nxx ; dx = old_dset->daxes->xxdel ; ny = old_dset->daxes->nyy ; dy = old_dset->daxes->yydel ; npix = nx*ny ; nz = old_dset->daxes->nzz ; dz = old_dset->daxes->zzdel ; if( nx != ny || fabs(dx) != fabs(dy) ) { #ifdef IMREG_DEBUG fprintf(stderr,"\nIMREG: nx=%d ny=%d nz=%d dx=%f dy=%f dz=%f\n", nx,ny,nz,dx,dy,dz ) ; #endif return "***********************************\n" "Dataset does not have square slices\n" "***********************************" ; } new_prefix = PLUTO_get_string(plint) ; /* get string item (the output prefix) */ if( ! PLUTO_prefix_ok(new_prefix) ) /* check if it is OK */ return "************************\n" "Output Prefix is illegal\n" "************************" ; /*--------- go to next input line ---------*/ PLUTO_next_option(plint) ; base = PLUTO_get_number(plint) ; if( base >= ntime ) return "********************\n" "Base value too large\n" "********************" ; /*--------- see if the 3rd option line is present --------*/ str = PLUTO_get_optiontag( plint ) ; if( str != NULL ) { float fsig , fdxy , fdph ; fsig = PLUTO_get_number(plint) * 0.42466090 ; fdxy = PLUTO_get_number(plint) ; fdph = PLUTO_get_number(plint) ; mri_align_params( 0 , 0.0,0.0,0.0 , fsig,fdxy,fdph ) ; /* fprintf(stderr,"Set fine params = %f %f %f\n",fsig,fdxy,fdph) ; */ } /*------------- ready to compute new dataset -----------*/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: loading dataset\n") ; #endif DSET_load( old_dset ) ; /*** 1) Copy the dataset in toto ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: Copying dataset\n") ; #endif new_dset = PLUTO_copy_dset( old_dset , new_prefix ) ; if( new_dset == NULL ) return "****************************\n" "Failed to copy input dataset\n" "****************************" ; /*** 2) Make an array of empty images ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: making empty images\n") ; #endif datum = DSET_BRICK_TYPE(new_dset,0) ; INIT_IMARR(ims_in) ; for( ii=0 ; ii < ntime ; ii++ ) { im = mri_new_vol_empty( nx , ny , 1 , datum ) ; ADDTO_IMARR(ims_in,im) ; } imbase = mri_new_vol_empty( nx , ny , 1 , datum ) ; dxar = (float *) malloc( sizeof(float) * ntime ) ; dyar = (float *) malloc( sizeof(float) * ntime ) ; phiar = (float *) malloc( sizeof(float) * ntime ) ; /*** 3) Get pointers to sub-bricks in old and new datasets ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: getting input brick pointers\n") ; #endif switch( datum ) { /* pointer type depends on input datum type */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * ntime ) ; bout = (byte **) malloc( sizeof(byte *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { bptr[ii] = (byte *) DSET_ARRAY(old_dset,ii) ; bout[ii] = (byte *) DSET_ARRAY(new_dset,ii) ; } break ; case MRI_short: sptr = (short **) malloc( sizeof(short *) * ntime ) ; sout = (short **) malloc( sizeof(short *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { sptr[ii] = (short *) DSET_ARRAY(old_dset,ii) ; sout[ii] = (short *) DSET_ARRAY(new_dset,ii) ; } #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: sptr[0] = %p sout[0] = %p\n",sptr[0],sout[0]) ; #endif break ; case MRI_float: fptr = (float **) malloc( sizeof(float *) * ntime ) ; fout = (float **) malloc( sizeof(float *) * ntime ) ; for( ii=0 ; ii < ntime ; ii++ ) { fptr[ii] = (float *) DSET_ARRAY(old_dset,ii) ; fout[ii] = (float *) DSET_ARRAY(new_dset,ii) ; } break ; } /*** 4) Loop over slices ***/ PLUTO_popup_meter(plint) ; for( kk=0 ; kk < nz ; kk++ ) { /*** 4a) Setup ims_in images to point to input slices ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- setup input images\n",kk) ; #endif for( ii=0 ; ii < ntime ; ii++ ) { im = IMARR_SUBIMAGE(ims_in,ii) ; switch( datum ) { case MRI_byte: mri_fix_data_pointer( bptr[ii] + kk*npix, im ) ; break ; case MRI_short: mri_fix_data_pointer( sptr[ii] + kk*npix, im ) ; break ; case MRI_float: mri_fix_data_pointer( fptr[ii] + kk*npix, im ) ; break ; } } /*** 4b) Setup im to point to base image ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- setup base image\n",kk) ; #endif switch( datum ) { case MRI_byte: mri_fix_data_pointer( bptr[base] + kk*npix, imbase ) ; break ; case MRI_short: mri_fix_data_pointer( sptr[base] + kk*npix, imbase ) ; break ; case MRI_float: mri_fix_data_pointer( fptr[base] + kk*npix, imbase ) ; break ; } /*** 4c) Register this slice at all times ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- register\n",kk) ; #endif ims_out = mri_align_dfspace( imbase , NULL , ims_in , ALIGN_REGISTER_CODE , dxar,dyar,phiar ) ; if( ims_out == NULL ) fprintf(stderr,"IMREG: mri_align_dfspace return NULL\n") ; /*** 4d) Put the output back in on top of the input; note that the output is always in MRI_float format ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: slice %d -- put output back into dataset\n",kk) ; #endif for( ii=0 ; ii < ntime ; ii++ ) { switch( datum ) { case MRI_byte: im = mri_to_mri( MRI_byte , IMARR_SUBIMAGE(ims_out,ii) ) ; memcpy( bout[ii] + kk*npix , MRI_BYTE_PTR(im) , sizeof(byte)*npix ) ; mri_free(im) ; break ; case MRI_short: #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: conversion to short at ii=%d\n",ii) ; #endif im = mri_to_mri( MRI_short , IMARR_SUBIMAGE(ims_out,ii) ) ; #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: copying to %p from %p\n",sout[ii] + kk*npix,MRI_SHORT_PTR(im)) ; #endif memcpy( sout[ii] + kk*npix , MRI_SHORT_PTR(im) , sizeof(short)*npix ) ; #ifdef IMREG_DEBUG if( ii==0 )fprintf(stderr,"IMREG: freeing\n") ; #endif mri_free(im) ; break ; case MRI_float: im = IMARR_SUBIMAGE(ims_out,ii) ; memcpy( fout[ii] + kk*npix , MRI_FLOAT_PTR(im) , sizeof(float)*npix ) ; break ; } } PLUTO_set_meter(plint, (100*(kk+1))/nz ) ; /*** 4e) Destroy the output images ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: destroying aligned output\n") ; #endif DESTROY_IMARR( ims_out ) ; } /*** 5) Destroy the empty images and other workspaces ***/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: destroy workspaces\n") ; #endif mri_clear_data_pointer(imbase) ; mri_free(imbase) ; for( ii=0 ; ii < ntime ; ii++ ) { im = IMARR_SUBIMAGE(ims_in,ii) ; mri_clear_data_pointer(im) ; } DESTROY_IMARR(ims_in) ; FREE_WORKSPACE ; /*------------- let AFNI know about the new dataset ------------*/ #ifdef IMREG_DEBUG fprintf(stderr,"IMREG: send result to AFNI\n") ; #endif PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ; return NULL ; /* null string returned means all was OK */ }