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 ; }
THD_3dim_dataset * THD_localhistog( int nsar , THD_3dim_dataset **insar , int numval , int *rlist , MCW_cluster *nbhd , int do_prob , int verb ) { THD_3dim_dataset *outset=NULL , *inset ; int nvox=DSET_NVOX(insar[0]) ; int ids, iv, bb, nnpt=nbhd->num_pt ; MRI_IMAGE *bbim ; int btyp ; float **outar , **listar ; ENTRY("THD_localhistog") ; /*---- create output dataset ----*/ outset = EDIT_empty_copy(insar[0]) ; EDIT_dset_items( outset , ADN_nvals , numval , ADN_datum_all , MRI_float , ADN_nsl , 0 , ADN_brick_fac , NULL , ADN_none ) ; outar = (float **)malloc(sizeof(float *)*numval) ; for( bb=0 ; bb < numval ; bb++ ){ EDIT_substitute_brick( outset , bb , MRI_float , NULL ) ; outar[bb] = DSET_BRICK_ARRAY(outset,bb) ; } /*---- make mapping between values and arrays to get those values ----*/ listar = (float **)malloc(sizeof(float *)*TWO16) ; for( bb=0 ; bb < TWO16 ; bb++ ) listar[bb] = outar[0] ; for( bb=1 ; bb < numval ; bb++ ){ listar[ rlist[bb] + TWO15 ] = outar[bb] ; } /*----------- loop over datasets, add in counts for all voxels -----------*/ for( ids=0 ; ids < nsar ; ids++ ){ /* dataset loop */ inset = insar[ids] ; DSET_load(inset) ; for( iv=0 ; iv < DSET_NVALS(inset) ; iv++ ){ /* sub-brick loop */ if( verb ) fprintf(stderr,".") ; bbim = DSET_BRICK(inset,iv) ; btyp = bbim->kind ; if( nnpt == 1 ){ /* only 1 voxel in nbhd */ int qq,ii,jj,kk,ib,nb ; switch( bbim->kind ){ case MRI_short:{ short *sar = MRI_SHORT_PTR(bbim) ; for( qq=0 ; qq < nvox ; qq++ ) listar[sar[qq]+TWO15][qq]++ ; } break ; case MRI_byte:{ byte *bar = MRI_BYTE_PTR(bbim) ; for( qq=0 ; qq < nvox ; qq++ ) listar[bar[qq]+TWO15][qq]++ ; } break ; case MRI_float:{ float *far = MRI_FLOAT_PTR(bbim) ; short ss ; for( qq=0 ; qq < nvox ; qq++ ){ ss = SHORTIZE(far[qq]); listar[ss+TWO15][qq]++; } } break ; } } else { /* multiple voxels in nbhd */ AFNI_OMP_START ; #pragma omp parallel { int qq,ii,jj,kk,ib,nb ; void *nar ; short *sar,ss ; byte *bar ; float *far ; nar = malloc(sizeof(float)*nnpt) ; sar = (short *)nar ; bar = (byte *)nar ; far = (float *)nar ; #pragma omp for for( qq=0 ; qq < nvox ; qq++ ){ /* qq=voxel index */ ii = DSET_index_to_ix(inset,qq) ; jj = DSET_index_to_jy(inset,qq) ; kk = DSET_index_to_kz(inset,qq) ; nb = mri_get_nbhd_array( bbim , NULL , ii,jj,kk , nbhd , nar ) ; if( nb == 0 ) continue ; switch( btyp ){ case MRI_short: for( ib=0 ; ib < nb ; ib++ ) listar[sar[ib]+TWO15][qq]++ ; break ; case MRI_byte: for( ib=0 ; ib < nb ; ib++ ) listar[bar[ib]+TWO15][qq]++ ; break ; case MRI_float: for( ib=0 ; ib < nb ; ib++ ){ ss = SHORTIZE(far[ib]); listar[ss+TWO15][qq]++; } break ; } } /* end of voxel loop */ free(nar) ; } /* end of OpenMP */ AFNI_OMP_END ; } } /* end of sub-brick loop */ DSET_unload(inset) ; } /* end of dataset loop */ if( verb ) fprintf(stderr,"\n") ; free(listar) ; /*---- post-process output ---*/ if( do_prob ){ byte **bbar ; int pp ; if( verb ) INFO_message("Conversion to probabilities") ; AFNI_OMP_START ; #pragma omp parallel { int qq , ib ; float pfac , val ; byte **bbar ; #pragma omp for for( qq=0 ; qq < nvox ; qq++ ){ pfac = 0.0001f ; for( ib=0 ; ib < numval ; ib++ ) pfac += outar[ib][qq] ; pfac = 250.0f / pfac ; for( ib=0 ; ib < numval ; ib++ ){ val = outar[ib][qq]*pfac ; outar[ib][qq] = BYTEIZE(val) ; } } } /* end OpenMP */ AFNI_OMP_END ; bbar = (byte **)malloc(sizeof(byte *)*numval) ; for( bb=0 ; bb < numval ; bb++ ){ bbar[bb] = (byte *)malloc(sizeof(byte)*nvox) ; for( pp=0 ; pp < nvox ; pp++ ) bbar[bb][pp] = (byte)outar[bb][pp] ; EDIT_substitute_brick(outset,bb,MRI_byte,bbar[bb]) ; EDIT_BRICK_FACTOR(outset,bb,0.004f) ; } free(bbar) ; } /* end of do_prob */ free(outar) ; RETURN(outset) ; }
MRI_IMAGE *mri_to_short_sclip( double scl , double lev , int bot , int top , MRI_IMAGE *oldim ) { MRI_IMAGE *newim ; register int ii , npix ; double imin,imax ; register double dscale , dbbot ; register float scale , flbot , val ; register short * ar ; ENTRY("mri_to_short_sclip") ; if( oldim == NULL ) RETURN( NULL ); /* 09 Feb 1999 */ newim = mri_new_conforming( oldim , MRI_short ) ; npix = oldim->nvox ; if( scl == 0 ){ /* compute scaling to make [min..max] -> [0..lev] */ imin = (oldim->kind==MRI_complex || oldim->kind==MRI_rgb) ? (0) : mri_min(oldim) ; imax = mri_max( oldim ) ; imax = (imax <= imin) ? imin+1 : imax ; scale = dscale = (lev+0.99) / (imax-imin) ; flbot = dbbot = imin ; } else { /* user controlled scaling, with lev -> 0 */ scale = dscale = scl ; flbot = dbbot = lev ; } ar = mri_data_pointer( newim ) ; /* fast access to data */ switch( oldim->kind ){ case MRI_rgb:{ register byte * rgb = mri_data_pointer(oldim) ; float rfac=0.299*scale , gfac=0.587*scale , bfac=0.114*scale ; for( ii=0 ; ii < npix ; ii++ ) ar[ii] = (short) ( rfac * rgb[3*ii] + gfac * rgb[3*ii+1] + bfac * rgb[3*ii+2] ) ; } break ; case MRI_byte:{ register byte * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ){ val = scale * (oar[ii]-flbot) ; ar[ii] = BYTEIZE(val) ; } break ; } case MRI_short:{ register short * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ){ val = scale * (oar[ii]-flbot) ; ar[ii] = SHORTIZE(val) ; } break ; } case MRI_int:{ register int * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ) ar[ii] = scale * (oar[ii]-flbot) ; break ; } case MRI_float:{ register float * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ) ar[ii] = scale * (oar[ii]-flbot) ; break ; } case MRI_double:{ register double * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ) ar[ii] = dscale * (oar[ii]-dbbot) ; break ; } case MRI_complex:{ register complex * oar = mri_data_pointer(oldim) ; for( ii=0 ; ii < npix ; ii++ ) ar[ii] = scale * CABS(oar[ii]) ; break ; } default: fprintf( stderr , "mri_to_short_scl: unrecognized image kind\n" ) ; MRI_FATAL_ERROR ; } /* clip, if desired */ if( bot < top ){ register short bb = bot , tt = top ; for( ii=0 ; ii < npix ; ii++ ){ if( ar[ii] < bb ) ar[ii] = bb ; else if( ar[ii] > tt ) ar[ii] = tt ; } } MRI_COPY_AUX(newim,oldim) ; RETURN( newim ); }
int main( int argc , char *argv[] ) { THD_3dim_dataset *dset , *oset=NULL , *tset=NULL ; int nvals , iv , nxyz , ii,jj,kk , iarg , kz,kzold ; float cut1=2.5,cut2=4.0 , sq2p,sfac , fq ; MRI_IMAGE *flim ; char *prefix="despike" , *tprefix=NULL ; int corder=-1 , nref , ignore=0 , polort=2 , nuse , nomask=0 ; int nspike, nbig, nproc ; float **ref ; float c21,ic21 , pspike,pbig ; short *sar , *qar ; byte *tar , *mask=NULL ; float *zar , *yar ; int datum ; int localedit=0 ; /* 04 Apr 2007 */ int verb=1 ; int do_NEW = 0 ; /* 29 Nov 2013 */ MRI_IMAGE *NEW_psinv=NULL ; int dilate = 4 ; /* 04 Dec 2013 */ int ctim = 0 ; /*----- Read command line -----*/ AFNI_SETUP_OMP(0) ; /* 24 Jun 2013 */ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf("Usage: 3dDespike [options] dataset\n" "Removes 'spikes' from the 3D+time input dataset and writes\n" "a new dataset with the spike values replaced by something\n" "more pleasing to the eye.\n" "\n" "Method:\n" " * L1 fit a smooth-ish curve to each voxel time series\n" " [see -corder option for description of the curve]\n" " [see -NEW option for a different & faster fitting method]\n" " * Compute the MAD of the difference between the curve and\n" " the data time series (the residuals).\n" " * Estimate the standard deviation 'sigma' of the residuals\n" " as sqrt(PI/2)*MAD.\n" " * For each voxel value, define s = (value-curve)/sigma.\n" " * Values with s > c1 are replaced with a value that yields\n" " a modified s' = c1+(c2-c1)*tanh((s-c1)/(c2-c1)).\n" " * c1 is the threshold value of s for a 'spike' [default c1=2.5].\n" " * c2 is the upper range of the allowed deviation from the curve:\n" " s=[c1..infinity) is mapped to s'=[c1..c2) [default c2=4].\n" "\n" "Options:\n" " -ignore I = Ignore the first I points in the time series:\n" " these values will just be copied to the\n" " output dataset [default I=0].\n" " -corder L = Set the curve fit order to L:\n" " the curve that is fit to voxel data v(t) is\n" "\n" " k=L [ (2*PI*k*t) (2*PI*k*t) ]\n" " f(t) = a+b*t+c*t*t + SUM [ d * sin(--------) + e * cos(--------) ]\n" " k=1 [ k ( T ) k ( T ) ]\n" "\n" " where T = duration of time series;\n" " the a,b,c,d,e parameters are chosen to minimize\n" " the sum over t of |v(t)-f(t)| (L1 regression);\n" " this type of fitting is is insensitive to large\n" " spikes in the data. The default value of L is\n" " NT/30, where NT = number of time points.\n" "\n" " -cut c1 c2 = Alter default values for the spike cut values\n" " [default c1=2.5, c2=4.0].\n" " -prefix pp = Save de-spiked dataset with prefix 'pp'\n" " [default pp='despike']\n" " -ssave ttt = Save 'spikiness' measure s for each voxel into a\n" " 3D+time dataset with prefix 'ttt' [default=no save]\n" " -nomask = Process all voxels\n" " [default=use a mask of high-intensity voxels, ]\n" " [as created via '3dAutomask -dilate 4 dataset'].\n" " -dilate nd = Dilate 'nd' times (as in 3dAutomask). The default\n" " value of 'nd' is 4.\n" " -q[uiet] = Don't print '++' informational messages.\n" "\n" " -localedit = Change the editing process to the following:\n" " If a voxel |s| value is >= c2, then replace\n" " the voxel value with the average of the two\n" " nearest non-spike (|s| < c2) values; the first\n" " one previous and the first one after.\n" " Note that the c1 cut value is not used here.\n" "\n" " -NEW = Use the 'new' method for computing the fit, which\n" " should be faster than the L1 method for long time\n" " series (200+ time points); however, the results\n" " are similar but NOT identical. [29 Nov 2013]\n" " * You can also make the program use the 'new'\n" " method by setting the environment variable\n" " AFNI_3dDespike_NEW\n" " to the value YES; as in\n" " setenv AFNI_3dDespike_NEW YES (csh)\n" " export AFNI_3dDespike_NEW=YES (bash)\n" " * If this variable is set to YES, you can turn off\n" " the '-NEW' processing by using the '-OLD' option.\n" " -->>* For time series more than 500 points long, the\n" " '-OLD' algorithm is tremendously slow. You should\n" " use the '-NEW' algorith in such cases.\n" " ** At some indeterminate point in the future, the '-NEW'\n" " method will become the default!\n" " -->>* As of 29 Sep 2016, '-NEW' is the default if there\n" " is more than 500 points in the time series dataset.\n" "\n" " -NEW25 = A slightly more aggressive despiking approach than\n" " the '-NEW' method.\n" "\n" "Caveats:\n" "* Despiking may interfere with image registration, since head\n" " movement may produce 'spikes' at the edge of the brain, and\n" " this information would be used in the registration process.\n" " This possibility has not been explored or calibrated.\n" "* [LATER] Actually, it seems like the registration problem\n" " does NOT happen, and in fact, despiking seems to help!\n" "* Check your data visually before and after despiking and\n" " registration!\n" " [Hint: open 2 AFNI controllers, and turn Time Lock on.]\n" ) ; PRINT_AFNI_OMP_USAGE("3dDespike",NULL) ; PRINT_COMPILE_DATE ; exit(0) ; } /** AFNI package setup and logging **/ mainENTRY("3dDespike main"); machdep(); AFNI_logger("3dDespike",argc,argv); PRINT_VERSION("3dDespike") ; AUTHOR("RW Cox") ; /** parse options **/ if( AFNI_yesenv("AFNI_3dDespike_NEW") ) do_NEW = 1 ; /* 29 Nov 2013 */ iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncmp(argv[iarg],"-q",2) == 0 ){ /* 04 Apr 2007 */ verb = 0 ; iarg++ ; continue ; } if( strncmp(argv[iarg],"-v",2) == 0 ){ verb++ ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-NEW") == 0 ){ /* 29 Nov 2013 */ do_NEW = 1 ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-NEW25") == 0 ){ /* 29 Sep 2016 */ do_NEW = 1 ; use_des25 = 1 ; cut1 = 2.5f ; cut2 = 3.2f ; iarg++ ; continue ; } if( strcmp(argv[iarg],"-OLD") == 0 ){ do_NEW = 0 ; iarg++ ; continue ; } /** -localedit **/ if( strcmp(argv[iarg],"-localedit") == 0 ){ /* 04 Apr 2007 */ localedit = 1 ; iarg++ ; continue ; } /** don't use masking **/ if( strcmp(argv[iarg],"-nomask") == 0 ){ nomask = 1 ; iarg++ ; continue ; } /** dilation count [04 Dec 2013] **/ if( strcmp(argv[iarg],"-dilate") == 0 ){ dilate = (int)strtod(argv[++iarg],NULL) ; if( dilate <= 0 ) dilate = 1 ; else if( dilate > 99 ) dilate = 99 ; iarg++ ; continue ; } /** output dataset prefix **/ if( strcmp(argv[iarg],"-prefix") == 0 ){ prefix = argv[++iarg] ; if( !THD_filename_ok(prefix) ) ERROR_exit("-prefix is not good"); iarg++ ; continue ; } /** ratio dataset prefix **/ if( strcmp(argv[iarg],"-ssave") == 0 ){ tprefix = argv[++iarg] ; if( !THD_filename_ok(tprefix) ) ERROR_exit("-ssave prefix is not good"); iarg++ ; continue ; } /** trigonometric polynomial order **/ if( strcmp(argv[iarg],"-corder") == 0 ){ corder = strtol( argv[++iarg] , NULL , 10 ) ; if( corder < 0 ) ERROR_exit("Illegal value of -corder"); iarg++ ; continue ; } /** how much to ignore at start **/ if( strcmp(argv[iarg],"-ignore") == 0 ){ ignore = strtol( argv[++iarg] , NULL , 10 ) ; if( ignore < 0 ) ERROR_exit("Illegal value of -ignore"); iarg++ ; continue ; } /** thresholds for s ratio **/ if( strcmp(argv[iarg],"-cut") == 0 ){ cut1 = strtod( argv[++iarg] , NULL ) ; cut2 = strtod( argv[++iarg] , NULL ) ; if( cut1 < 1.0 || cut2 < cut1+0.5 ) ERROR_exit("Illegal values after -cut"); iarg++ ; continue ; } ERROR_exit("Unknown option: %s",argv[iarg]) ; } c21 = cut2-cut1 ; ic21 = 1.0/c21 ; /*----- read input dataset -----*/ if( iarg >= argc ) ERROR_exit("No input dataset!!??"); dset = THD_open_dataset( argv[iarg] ) ; CHECK_OPEN_ERROR(dset,argv[iarg]) ; datum = DSET_BRICK_TYPE(dset,0) ; if( (datum != MRI_short && datum != MRI_float) || !DSET_datum_constant(dset) ) ERROR_exit("Can't process non-short, non-float dataset!") ; if( verb ) INFO_message("Input data type = %s\n",MRI_TYPE_name[datum]) ; nvals = DSET_NUM_TIMES(dset) ; nuse = nvals - ignore ; if( nuse < 15 ) ERROR_exit("Can't use dataset with < 15 time points per voxel!") ; if( nuse > 500 && !do_NEW ){ INFO_message("Switching to '-NEW' method since number of time points = %d > 500",nuse) ; do_NEW = 1 ; } if( use_des25 && nuse < 99 ) use_des25 = 0 ; if( verb ) INFO_message("ignoring first %d time points, using last %d",ignore,nuse); if( corder > 0 && 4*corder+2 > nuse ){ ERROR_exit("-corder %d is too big for NT=%d",corder,nvals) ; } else if( corder < 0 ){ corder = rint(nuse/30.0) ; if( corder > 50 && !do_NEW ) corder = 50 ; if( verb ) INFO_message("using %d time points => -corder %d",nuse,corder) ; } else { if( verb ) INFO_message("-corder %d set from command line",corder) ; } nxyz = DSET_NVOX(dset) ; if( verb ) INFO_message("Loading dataset %s",argv[iarg]) ; DSET_load(dset) ; CHECK_LOAD_ERROR(dset) ; /*-- create automask --*/ if( !nomask ){ mask = THD_automask( dset ) ; if( verb ){ ii = THD_countmask( DSET_NVOX(dset) , mask ) ; INFO_message("%d voxels in the automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ; } for( ii=0 ; ii < dilate ; ii++ ) THD_mask_dilate( DSET_NX(dset), DSET_NY(dset), DSET_NZ(dset), mask, 3 ) ; if( verb ){ ii = THD_countmask( DSET_NVOX(dset) , mask ) ; INFO_message("%d voxels in the dilated automask [out of %d in dataset]",ii,DSET_NVOX(dset)) ; } } else { if( verb ) INFO_message("processing all %d voxels in dataset",DSET_NVOX(dset)) ; } /*-- create empty despiked dataset --*/ oset = EDIT_empty_copy( dset ) ; EDIT_dset_items( oset , ADN_prefix , prefix , ADN_brick_fac , NULL , ADN_datum_all , datum , ADN_none ) ; if( THD_deathcon() && THD_is_file(DSET_HEADNAME(oset)) ) ERROR_exit("output dataset already exists: %s",DSET_HEADNAME(oset)); tross_Copy_History( oset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , oset ) ; /* create bricks (will be filled with zeros) */ for( iv=0 ; iv < nvals ; iv++ ) EDIT_substitute_brick( oset , iv , datum , NULL ) ; /* copy the ignored bricks */ switch( datum ){ case MRI_short: for( iv=0 ; iv < ignore ; iv++ ){ sar = DSET_ARRAY(oset,iv) ; qar = DSET_ARRAY(dset,iv) ; memcpy( sar , qar , DSET_BRICK_BYTES(dset,iv) ) ; DSET_unload_one(dset,iv) ; } break ; case MRI_float: for( iv=0 ; iv < ignore ; iv++ ){ zar = DSET_ARRAY(oset,iv) ; yar = DSET_ARRAY(dset,iv) ; memcpy( zar , yar , DSET_BRICK_BYTES(dset,iv) ) ; DSET_unload_one(dset,iv) ; } break ; } /*-- setup to save a threshold statistic dataset, if desired --*/ if( tprefix != NULL ){ float *fac ; tset = EDIT_empty_copy( dset ) ; fac = (float *) malloc( sizeof(float) * nvals ) ; for( ii=0 ; ii < nvals ; ii++ ) fac[ii] = TFAC ; EDIT_dset_items( tset , ADN_prefix , tprefix , ADN_brick_fac , fac , ADN_datum_all , MRI_byte , ADN_func_type , FUNC_FIM_TYPE , ADN_none ) ; free(fac) ; tross_Copy_History( tset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , tset ) ; #if 0 if( THD_is_file(DSET_HEADNAME(tset)) ) ERROR_exit("-ssave dataset already exists"); #endif tross_Copy_History( tset , dset ) ; tross_Make_History( "3dDespike" , argc , argv , tset ) ; for( iv=0 ; iv < nvals ; iv++ ) EDIT_substitute_brick( tset , iv , MRI_byte , NULL ) ; } /*-- setup to find spikes --*/ sq2p = sqrt(0.5*PI) ; sfac = sq2p / 1.4826f ; /* make ref functions */ nref = 2*corder+3 ; ref = (float **) malloc( sizeof(float *) * nref ) ; for( jj=0 ; jj < nref ; jj++ ) ref[jj] = (float *) malloc( sizeof(float) * nuse ) ; /* r(t) = 1 */ for( iv=0 ; iv < nuse ; iv++ ) ref[0][iv] = 1.0 ; jj = 1 ; /* r(t) = t - tmid */ { float tm = 0.5 * (nuse-1.0) ; float fac = 2.0 / nuse ; for( iv=0 ; iv < nuse ; iv++ ) ref[1][iv] = (iv-tm)*fac ; jj = 2 ; /* r(t) = (t-tmid)**jj */ for( ; jj <= polort ; jj++ ) for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = pow( (iv-tm)*fac , (double)jj ) ; } for( kk=1 ; kk <= corder ; kk++ ){ fq = (2.0*PI*kk)/nuse ; /* r(t) = sin(2*PI*k*t/N) */ for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = sin(fq*iv) ; jj++ ; /* r(t) = cos(2*PI*k*t/N) */ for( iv=0 ; iv < nuse ; iv++ ) ref[jj][iv] = cos(fq*iv) ; jj++ ; } /****** setup for the NEW solution method [29 Nov 2013] ******/ if( do_NEW ){ NEW_psinv = DES_get_psinv(nuse,nref,ref) ; INFO_message("Procesing time series with NEW model fit algorithm") ; } else { INFO_message("Procesing time series with OLD model fit algorithm") ; } /*--- loop over voxels and do work ---*/ #define Laplace_t2p(val) ( 1.0 - nifti_stat2cdf( (val), 15, 0.0, 1.4427 , 0.0 ) ) if( verb ){ if( !localedit ){ INFO_message("smash edit thresholds: %.1f .. %.1f MADs",cut1*sq2p,cut2*sq2p) ; ININFO_message(" [ %.3f%% .. %.3f%% of normal distribution]", 200.0*qg(cut1*sfac) , 200.0*qg(cut2*sfac) ) ; ININFO_message(" [ %.3f%% .. %.3f%% of Laplace distribution]" , 100.0*Laplace_t2p(cut1) , 100.0*Laplace_t2p(cut2) ) ; } else { INFO_message("local edit threshold: %.1f MADS",cut2*sq2p) ; ININFO_message(" [ %.3f%% of normal distribution]", 200.0*qg(cut2*sfac) ) ; ININFO_message(" [ %.3f%% of Laplace distribution]", 100.0*Laplace_t2p(cut1) ) ; } INFO_message("%d slices to process",DSET_NZ(dset)) ; } kzold = -1 ; nspike = 0 ; nbig = 0 ; nproc = 0 ; ctim = NI_clock_time() ; AFNI_OMP_START ; #pragma omp parallel if( nxyz > 6666 ) { int ii , iv , iu , id , jj ; float *far , *dar , *var , *fitar , *ssp , *fit , *zar ; short *sar , *qar ; byte *tar ; float fsig , fq , cls , snew , val ; float *NEW_wks=NULL ; #pragma omp critical (DESPIKE_malloc) { far = (float *) malloc( sizeof(float) * nvals ) ; dar = (float *) malloc( sizeof(float) * nvals ) ; var = (float *) malloc( sizeof(float) * nvals ) ; fitar = (float *) malloc( sizeof(float) * nvals ) ; ssp = (float *) malloc( sizeof(float) * nvals ) ; fit = (float *) malloc( sizeof(float) * nref ) ; if( do_NEW ) NEW_wks = (float *)malloc(sizeof(float)*DES_workspace_size(nuse,nref)) ; } #ifdef USE_OMP INFO_message("start OpenMP thread #%d",omp_get_thread_num()) ; #endif #pragma omp for for( ii=0 ; ii < nxyz ; ii++ ){ /* ii = voxel index */ if( mask != NULL && mask[ii] == 0 ) continue ; /* skip this voxel */ #ifndef USE_OMP kz = DSET_index_to_kz(dset,ii) ; /* starting a new slice */ if( kz != kzold ){ if( verb ){ fprintf(stderr, "++ start slice %2d",kz ) ; if( nproc > 0 ){ pspike = (100.0*nspike)/nproc ; pbig = (100.0*nbig )/nproc ; fprintf(stderr, "; so far %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]", nproc,nspike,pspike,nbig,pbig ) ; } fprintf(stderr,"\n") ; } kzold = kz ; } #else if( verb && ii % 2345 == 1234 ) fprintf(stderr,".") ; #endif /*** extract ii-th time series into far[] ***/ switch( datum ){ case MRI_short: for( iv=0 ; iv < nuse ; iv++ ){ qar = DSET_ARRAY(dset,iv+ignore) ; /* skip ignored data */ far[iv] = (float)qar[ii] ; } break ; case MRI_float: for( iv=0 ; iv < nuse ; iv++ ){ zar = DSET_ARRAY(dset,iv+ignore) ; far[iv] = zar[ii] ; } break ; } AAmemcpy(dar,far,sizeof(float)*nuse) ; /* copy time series into dar[] */ /*** solve for L1 fit ***/ if( do_NEW ) cls = DES_solve( NEW_psinv , far , fit , NEW_wks ) ; /* 29 Nov 2013 */ else cls = cl1_solve( nuse , nref , far , ref , fit,0 ) ; /* the slow part */ if( cls < 0.0f ){ /* fit failed! */ #if 0 fprintf(stderr,"curve fit fails at voxel %d %d %d\n", DSET_index_to_ix(dset,ii) , DSET_index_to_jy(dset,ii) , DSET_index_to_kz(dset,ii) ) ; #endif continue ; /* skip this voxel */ } for( iv=0 ; iv < nuse ; iv++ ){ /* detrend */ val = fit[0] + fit[1]*ref[1][iv] /* quadratic part of curve fit */ + fit[2]*ref[2][iv] ; for( jj=3 ; jj < nref ; jj++ ) /* rest of curve fit */ val += fit[jj] * ref[jj][iv] ; fitar[iv] = val ; /* save curve fit value */ var[iv] = dar[iv]-val ; /* remove fitted value = resid */ far[iv] = fabsf(var[iv]) ; /* abs value of resid */ } /*** compute estimate standard deviation of detrended data ***/ fsig = sq2p * qmed_float(nuse,far) ; /* also mangles far array */ /*** process time series for spikes, editing data in dar[] ***/ if( fsig > 0.0f ){ /* data wasn't fit perfectly */ /* find spikiness for each point in time */ fq = 1.0f / fsig ; for( iv=0 ; iv < nuse ; iv++ ){ ssp[iv] = fq * var[iv] ; /* spikiness s = how many sigma out */ } /* save spikiness in -ssave datset */ if( tset != NULL ){ for( iv=0 ; iv < nuse ; iv++ ){ tar = DSET_ARRAY(tset,iv+ignore) ; snew = ITFAC*fabsf(ssp[iv]) ; /* scale for byte storage */ tar[ii] = BYTEIZE(snew) ; /* cf. mrilib.h */ } } /* process values of |s| > cut1, editing dar[] */ for( iv=0 ; iv < nuse ; iv++ ){ /* loop over time points */ if( !localedit ){ /** classic 'smash' edit **/ if( ssp[iv] > cut1 ){ snew = cut1 + c21*mytanh((ssp[iv]-cut1)*ic21) ; /* edit s down */ dar[iv] = fitar[iv] + snew*fsig ; #pragma omp critical (DESPIKE_counter) { nspike++ ; if( ssp[iv] > cut2 ) nbig++ ; } } else if( ssp[iv] < -cut1 ){ snew = -cut1 + c21*mytanh((ssp[iv]+cut1)*ic21) ; /* edit s up */ dar[iv] = fitar[iv] + snew*fsig ; #pragma omp critical (DESPIKE_counter) { nspike++ ; if( ssp[iv] < -cut2 ) nbig++ ; } } } else { /** local edit: 04 Apr 2007 **/ if( ssp[iv] >= cut2 || ssp[iv] <= -cut2 ){ for( iu=iv+1 ; iu < nuse ; iu++ ) /* find non-spike above */ if( ssp[iu] < cut2 && ssp[iu] > -cut2 ) break ; for( id=iv-1 ; id >= 0 ; id-- ) /* find non-spike below */ if( ssp[id] < cut2 && ssp[id] > -cut2 ) break ; switch( (id>=0) + 2*(iu<nuse) ){ /* compute replacement val */ case 3: val = 0.5*(dar[iu]+dar[id]); break; /* iu and id OK */ case 2: val = dar[iu] ; break; /* only iu OK */ case 1: val = dar[id] ; break; /* only id OK */ default: val = fitar[iv] ; break; /* shouldn't be */ } dar[iv] = val ; #pragma omp critical (DESPIKE_counter) { nspike++ ; nbig++ ; } } } } /* end of loop over time points */ #pragma omp atomic nproc += nuse ; /* number data points processed */ } /* end of processing time series when fsig is positive */ /* put dar[] time series (possibly edited above) into output bricks */ switch( datum ){ case MRI_short: for( iv=0 ; iv < nuse ; iv++ ){ sar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */ sar[ii] = (short)dar[iv] ; /* original or mutated data */ } break ; case MRI_float: for( iv=0 ; iv < nuse ; iv++ ){ zar = DSET_ARRAY(oset,iv+ignore) ; /* output brick */ zar[ii] = dar[iv] ; /* original or mutated data */ } break ; } } /* end of loop over voxels #ii */ #pragma omp critical (DESPIKE_malloc) { free(fit); free(ssp); free(fitar); free(var); free(dar); free(far); if( do_NEW ) free(NEW_wks) ; } } /* end OpenMP */ AFNI_OMP_END ; #ifdef USE_OMP if( verb ) fprintf(stderr,"\n") ; #endif ctim = NI_clock_time() - ctim ; INFO_message( "Elapsed despike time = %s" , nice_time_string(ctim) ) ; if( ctim > 345678 && !do_NEW ) ININFO_message("That was SLOW -- try the '-NEW' option for a speedup") ; #ifdef USE_OMP if( verb ) fprintf(stderr,"\n") ; #endif /*--- finish up ---*/ if( do_NEW ) mri_free(NEW_psinv) ; DSET_delete(dset) ; /* delete input dataset */ if( verb ){ if( nproc > 0 ){ pspike = (100.0*nspike)/nproc ; pbig = (100.0*nbig )/nproc ; INFO_message("FINAL: %d data points, %d edits [%.3f%%], %d big edits [%.3f%%]", nproc,nspike,pspike,nbig,pbig ) ; } else { INFO_message("FINAL: no good voxels found to process!!??") ; } } /* write results */ DSET_write(oset) ; if( verb ) WROTE_DSET(oset) ; DSET_delete(oset) ; if( tset != NULL ){ DSET_write(tset) ; if( verb ) WROTE_DSET(tset) ; DSET_delete(tset) ; } exit( THD_get_write_error_count() ) ; }
int thd_mask_from_brick(THD_3dim_dataset * dset, int volume, float thresh, byte ** mask, int absolute) { float factor; byte * tmask; int nvox, type, c, size = 0; ENTRY("thd_mask_from_brick"); if ( mask ) *mask = NULL; /* to be sure */ if ( !ISVALID_DSET(dset) || ! mask || volume < 0 ) RETURN(-1); if ( volume >= DSET_NVALS(dset) ) { fprintf(stderr,"** tmfb: sub-brick %d out-of-range\n", volume); RETURN(-1); } if( !DSET_LOADED(dset) ) DSET_load(dset); nvox = DSET_NVOX(dset); type = DSET_BRICK_TYPE(dset, volume); if ( type != MRI_byte && type != MRI_short && type != MRI_int && type != MRI_float ) { fprintf(stderr,"** tmfb: invalid dataset type %s, sorry...\n", MRI_type_name[type]); RETURN(-1); } tmask = (byte *)calloc(nvox, sizeof(byte)); if ( ! tmask ) { fprintf(stderr,"** tmfb: failed to allocate mask of %d bytes\n", nvox); RETURN(-1); } factor = DSET_BRICK_FACTOR(dset, volume); /* cheat: adjust threshold, not data */ if ( factor != 0.0 ) thresh /= factor; switch( DSET_BRICK_TYPE(dset, volume) ) { case MRI_byte: { if (thresh <= (float)MRI_maxbyte) { /* ZSS: Oct 2011 Without this test, a high threshold value might end up equal to MRI_maxbyte when BYTEIZED below, resulting in the highest voxel making it to the mask no matter how much higher the threshold is set. */ byte * dp = DSET_ARRAY(dset, volume); byte thr = BYTEIZE(thresh + 0.99999); /* ceiling */ for ( c = 0; c < nvox; c++ ) if ( dp[c] != 0 && ( dp[c] >= thr ) ) { size++; tmask[c] = 1; } } } break; case MRI_short: { if (thresh <= (float)MRI_maxshort) { /* ZSS: Oct 2011 */ short * dp = DSET_ARRAY(dset, volume); short thr = SHORTIZE(thresh + 0.99999); /* ceiling */ for ( c = 0; c < nvox; c++, dp++ ) if ( *dp != 0 && ( *dp >= thr || (absolute && *dp <= -thr) ) ) { size++; tmask[c] = 1; } } } break; case MRI_int: { int * dp = DSET_ARRAY(dset, volume); int thr = (int)(thresh + 0.99999); /* ceiling */ for ( c = 0; c < nvox; c++, dp++ ) if ( *dp != 0 && ( *dp >= thr || (absolute && *dp <= -thr) ) ) { size++; tmask[c] = 1; } } break; case MRI_float: { float * dp = DSET_ARRAY(dset, volume); for ( c = 0; c < nvox; c++, dp++ ) if (*dp != 0 && (*dp >= thresh || (absolute && *dp <= -thresh))) { size++; tmask[c] = 1; } } break; default: /* let's be sure */ { fprintf(stderr,"** tmfb: invalid dataset type, sorry...\n"); free(tmask); } break; } *mask = tmask; RETURN(size); }
byte * THD_makemask( THD_3dim_dataset *mask_dset , int miv , float mask_bot , float mask_top ) { float maxval ; /* for computing limits for an empty mask */ byte *mmm = NULL ; int nvox , ii ; int empty = 0 ; /* do we return an empty mask */ if( !ISVALID_DSET(mask_dset) || miv < 0 || miv >= DSET_NVALS(mask_dset) ) return NULL ; nvox = DSET_NVOX(mask_dset) ; DSET_load(mask_dset) ; if( !DSET_LOADED(mask_dset) ) return NULL ; mmm = (byte *) calloc( sizeof(byte) * nvox , 1 ) ; switch( DSET_BRICK_TYPE(mask_dset,miv) ){ default: free(mmm) ; DSET_unload(mask_dset) ; return NULL ; 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 ){ /* maybe this mask is empty, allow for rounding */ maxval = MRI_TYPE_maxval[MRI_short] + 0.5 ; if( mask_bot/mfac >= maxval || mask_top/mfac <= -maxval ) empty=1; 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] ; } if( !empty ) /* 6 Jun 2007 */ for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ) mmm[ii]=1; } 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 && mask_top > 0.0 ){ /* maybe this mask is empty, allow for rounding */ /* (top <= 0 is flag for full mask) */ maxval = MRI_TYPE_maxval[MRI_byte] + 0.5 ; if( mask_bot/mfac >= maxval ) empty = 1; mbot = BYTEIZE(mask_bot/mfac) ; mtop = BYTEIZE(mask_top/mfac) ; } else { mbot = 0 ; mtop = (byte) MRI_TYPE_maxval[MRI_short] ; } if( !empty ) /* 6 Jun 2007 */ for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ) mmm[ii]=1; } 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( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ) mmm[ii]=1; } break ; } return mmm ; }
int THD_makedsetmask( THD_3dim_dataset *mask_dset , int miv , float mask_bot , float mask_top, byte *cmask ) { float maxval ; /* for computing limits for an empty mask */ int nvox , ii, nonzero=-1 , empty = 0 ; if( !ISVALID_DSET(mask_dset) || miv < 0 || miv >= DSET_NVALS(mask_dset) ) return (-1) ; nvox = DSET_NVOX(mask_dset) ; DSET_mallocize(mask_dset); /* do this or else it could be a read only dset! */ DSET_load(mask_dset) ; if( !DSET_LOADED(mask_dset) ) return (-1) ; nonzero = 0; switch( DSET_BRICK_TYPE(mask_dset,miv) ){ default: DSET_unload(mask_dset) ; return (-1) ; 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 ){ /* maybe this mask is empty, allow for rounding */ maxval = MRI_TYPE_maxval[MRI_short] + 0.5 ; if( mask_bot/mfac >= maxval || mask_top/mfac <= -maxval ) empty=1; 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] ; } if (empty) { /* if empty, clear result 6 Jun 2007 */ for( ii=0 ; ii < nvox ; ii++ ) mar[ii] = 0; } else if (cmask) { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 && cmask[ii]) { mar[ii]=1; ++nonzero; } else { mar[ii] = 0; } } else { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ) { mar[ii]=1; ++nonzero; } else { mar[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 && mask_top > 0.0 ){ /* maybe this mask is empty, allow for rounding */ /* (top <= 0 is flag for full mask) */ maxval = MRI_TYPE_maxval[MRI_byte] + 0.5 ; if( mask_bot/mfac >= maxval ) empty = 1; mbot = BYTEIZE(mask_bot/mfac) ; mtop = BYTEIZE(mask_top/mfac) ; } else { mbot = 0 ; mtop = (byte) MRI_TYPE_maxval[MRI_short] ; } if (empty) { /* if empty, clear result 6 Jun 2007 */ for( ii=0 ; ii < nvox ; ii++ ) mar[ii] = 0; } else if (cmask) { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 && cmask[ii]){ mar[ii]=1; ++nonzero; } else { mar[ii] = 0; } } else { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ){ mar[ii]=1; ++nonzero; } else { mar[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 ; } if (cmask) { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 && cmask[ii]) { mar[ii]=1; ++nonzero; } else { mar[ii] = 0; } } else { for( ii=0 ; ii < nvox ; ii++ ) if( mar[ii] >= mbot && mar[ii] <= mtop && mar[ii] != 0 ) { mar[ii]=1; ++nonzero; } else { mar[ii] = 0; } } } break ; } /* remove any scaling factor ZSS April 24 06*/ EDIT_BRICK_FACTOR(mask_dset,miv , 0.0); return (nonzero) ; }