float EDIT_coerce_autoscale( int nxyz , int itype,void *ivol , int otype,void *ovol ) { float fac=0.0 , top ; ENTRY("EDIT_coerce_autoscale") ; if( MRI_IS_INT_TYPE(otype) ) { top = MCW_vol_amax( nxyz,1,1 , itype,ivol ) ; fac = (top > MRI_TYPE_maxval[otype]) ? MRI_TYPE_maxval[otype]/top : 0.0 ; } EDIT_coerce_scale_type( nxyz , fac , itype,ivol , otype,ovol ) ; RETURN( fac ); }
float EDIT_convert_dtype( int nxyz , int itype,void *ivol , int otype,void *ovol , int limit ) { float fac=0.0 , top, olimit ; ENTRY("EDIT_convert_dtype") ; if( MRI_IS_INT_TYPE(otype) ) { olimit = (limit > 0) ? limit : MRI_TYPE_maxval[otype]; top = MCW_vol_amax( nxyz,1,1 , itype,ivol ) ; if( top > olimit || !is_integral_data(nxyz, itype, ivol) ) fac = olimit/top ; } EDIT_coerce_scale_type( nxyz , fac , itype,ivol , otype,ovol ) ; RETURN( fac ); }
char * POWER_main( PLUGIN_interface * plint ) { MCW_idcode * idc ; /* input dataset idcode */ THD_3dim_dataset * old_dset , * new_dsetD3 , * new_dsetA3, * new_dsetavgD3 ; /* input and output datasets */ char * new_prefix , * str , * namestr, * filename; /* strings from user */ int new_datum , ignore , nfft , ninp , /* control parameters */ old_datum , nuse , ntaper , ktbot, image_type, scale,OutputFlag ,numT,flip; float avFac; 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 * this = NULL ; /* array loaded from input dataset */ float ** foutD3 = NULL ; /* will be array of output floats */ float ** foutA3 = NULL ; /* will be array of output floats */ float ** foutavgD3 = NULL ; /* will be array of output floats */ float * tarD3 = NULL ; /* will be array of taper coefficients */ float * tarA3 = NULL ; /* will be array of taper coefficients */ float * taravgD3 = NULL ; /* will be array of taper coefficients */ /*float * flip;*/ float * numAv; float dfreq , pfact , phi , xr,xi , yr,yi ; float x0,x1 , y0,y1 , d0fac,d1fac ; int nfreq , nvox , perc , new_units ; int istr , ii,iip , ibot,itop , kk , icx ; /* temp variables */ new_prefix = (char *)calloc(100, sizeof(char)); filename = (char *)calloc(100, sizeof(char)); str = (char *)calloc(100, sizeof(char)); namestr = (char *)calloc(100, sizeof(char)); OutputFlag=0; /*--------------------------------------------------------------------*/ /*----- 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 */ namestr = DSET_PREFIX(old_dset) ; if( old_dset == NULL ) return "*************************\n" "Cannot find Input Dataset\n" "*************************" ; /*--------- go to second input line ---------*/ PLUTO_next_option(plint) ; filename = PLUTO_get_string(plint) ; /* get string item (the output prefix) */ sprintf(new_prefix,"%s%s",filename,"_D3"); if (strcmp(new_prefix,"_D3")==0){ OutputFlag=1; sprintf(new_prefix,"%s%s",namestr,"_D3"); } if (! PLUTO_prefix_ok(new_prefix) ){ PLUTO_popup_transient(plint,new_prefix); return "*************************\n" "Output filename already exists\n" "*************************" ; } PLUTO_popup_transient(plint,"Output file tags set automatically"); str = PLUTO_get_string(plint) ; /* get string item (the datum type) */ istr = PLUTO_string_index( str , /* find it in the list it came from */ NUM_TYPE_STRINGS , type_strings ) ; switch( istr ){ default: case 0: new_datum = MRI_float ; break ; break ; case 1: new_datum = MRI_byte ; break ; /* assign type of user's choice */ case 2: new_datum = MRI_short ; break ; case 3: new_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* use old dataset type */ } /*--------- go to next input lines ---------*/ PLUTO_next_option(plint) ; /* skip to next line */ ignore = PLUTO_get_number(plint) ; /* get number item (ignore) */ ninp = DSET_NUM_TIMES(old_dset) ; /* number of values in input */ nuse = ninp; /* number of values to actually use */ nfreq=nuse; nfft=nuse; str = PLUTO_get_string(plint) ; /* get string item (the datum type) */ istr = PLUTO_string_index( str , /* find it in the list it came from */ NUM_TYPE_STRINGSX , type_stringsx ) ; switch( istr ){ default: case 0: image_type = 0; break; } PLUTO_next_option(plint) ; /* skip to next line */ scale = PLUTO_get_number(plint) ; /* get number item (scale) */ /*------------------------------------------------------*/ /*---------- At this point, the inputs are OK ----------*/ PLUTO_popup_meter( plint ) ; /* popup a progress meter */ /*--------- set up pointers to each sub-brick in the input dataset ---------*/ DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum type */ switch( old_datum ){ /* pointer type depends on input datum type */ default: return "******************************\n" "Illegal datum in Input Dataset\n" "******************************" ; /** create array of pointers into old dataset sub-bricks **/ /** Note that we skip the first 'ignore' sub-bricks here **/ /*--------- input is bytes ----------*/ /* voxel #i at time #k is bptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return "Malloc\nFailure!\n [bptr]" ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return "Malloc\nFailure!\n [sptr]" ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return "Malloc\nFailure!\n [fptr]" ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk) ; break ; } /* end of switch on input type */ /*---- allocate space for 2 voxel timeseries and 1 FFT ----*/ this = (float *) malloc( sizeof(float) * nuse ) ; /* input */ tarD3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ; tarA3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ; taravgD3 = (float *) malloc( sizeof(float) * MAX(nuse,nfreq) ) ; /*flip = (float *)malloc( sizeof(float) * 1);*/ numAv = (float *)malloc( sizeof(float) * 1); numT=nuse-ignore; if (OutputFlag==1) sprintf(new_prefix,"%s%s",namestr,"_D3"); else sprintf(new_prefix,"%s%s",filename,"_D3"); new_dsetD3 = EDIT_empty_copy( old_dset ); { char * his = PLUTO_commandstring(plint) ; tross_Copy_History( old_dset , new_dsetD3 ) ; tross_Append_History( new_dsetD3 , his ) ; free(his) ; } /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dsetD3 , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , numT , ADN_ntt ,numT, ADN_none ) ; if (OutputFlag==1) sprintf(new_prefix,"%s%s",namestr,"_A3"); else sprintf(new_prefix,"%s%s",filename,"_A3"); numT=nuse-ignore; new_dsetA3 = EDIT_empty_copy( old_dset ); { char * his = PLUTO_commandstring(plint) ; tross_Copy_History( old_dset , new_dsetA3 ) ; tross_Append_History( new_dsetA3 , his ) ; free(his) ; } /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dsetA3 , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , numT, ADN_ntt ,numT, ADN_none ) ; if (OutputFlag==1) sprintf(new_prefix,"%s%s",namestr,"_avgD3"); else sprintf(new_prefix,"%s%s",filename,"_avgD3"); new_dsetavgD3 = EDIT_empty_copy( old_dset ); { char * his = PLUTO_commandstring(plint) ; tross_Copy_History( old_dset , new_dsetavgD3 ) ; tross_Append_History( new_dsetavgD3 , his ) ; free(his) ; } /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dsetavgD3 , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , 1, ADN_ntt ,1, ADN_none ) ; /*---------------------- make a new dataset ----------------------*/ /*-------------------making a new dataset------------------------------------*/ /*------ make floating point output sub-bricks (only at the end will scale to byte or shorts) Output #ii at freq #kk will go into fout[kk][ii], for kk=0..nfreq-1, and for ii=0..nvox-1. ------*/ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; foutD3 = (float **) malloc( sizeof(float *) * nuse ) ; /* ptrs to sub-bricks */ foutA3 = (float **) malloc( sizeof(float *) * nuse ) ; /* ptrs to sub-bricks */ foutavgD3 = (float **) malloc( sizeof(float *) * 1 ) ; /* ptrs to sub-bricks */ if( foutD3 == NULL | foutA3 == NULL | foutavgD3 == NULL){ THD_delete_3dim_dataset( new_dsetD3 , False ) ; THD_delete_3dim_dataset( new_dsetA3 , False ) ; THD_delete_3dim_dataset( new_dsetavgD3 , False ) ; FREE_WORKSPACE ; return "Malloc\nFailure!\n [fout]" ; } for( kk=0 ; kk < nfreq ; kk++ ){ foutD3[kk] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */ foutA3[kk] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */ foutavgD3[0] = (float *) malloc( sizeof(float) * nvox ) ; /* sub-brick # kk */ if( foutD3[kk] == NULL ) break ; if( foutA3[kk] == NULL ) break ; if( foutavgD3[0] == NULL ) break ; } if( kk < nfreq ){ for( ; kk >= 0 ; kk-- ){ FREEUP(foutD3[kk]) ; FREEUP(foutA3[kk]) ; FREEUP(foutavgD3[0]) ; }/* free all we did get */ THD_delete_3dim_dataset( new_dsetD3 , False ) ; THD_delete_3dim_dataset( new_dsetA3 , False ) ; THD_delete_3dim_dataset( new_dsetavgD3 , False ) ; FREE_WORKSPACE ; return "Malloc\nFailure!\n [arrays]" ; } { char buf[128] ; ii = (nfreq * nvox * sizeof(float)) / (1024*1024) ; sprintf( buf , " \n" "*** 3D+time ASL a3/d3:\n" "*** Using %d MBytes of workspace,\n " "*** with # time points = %d\n" , ii,numT ) ; PLUTO_popup_transient( plint , buf ) ; } /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /***** loop over voxels *****/ /* *(flip)=scale; */ *(numAv)= nuse-ignore; for( ii=0 ; ii < nvox ; ii ++ ){ /* time series */ switch( old_datum ){ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ){ this[kk] = bptr[kk][ii] ; } break ; case MRI_short: for( kk=0 ; kk < nuse ; kk++ ){ this[kk] = sptr[kk][ii] ; } break ; case MRI_float: for( kk=0 ; kk < nuse ; kk++ ){ this[kk] = fptr[kk][ii] ; } break ; } flip=scale*pow(-1,ignore+1); for( kk=0 ; kk < nuse-ignore ; kk++ ){ if (kk==nuse-1-ignore){ *(*(foutD3+kk)+ii)= flip*( *(this+kk+ignore-1)-*(this+kk+ignore) ); *(*(foutA3+kk)+ii)= 2*(*(this+kk+ignore-1)+*(this+kk+ignore)); } else if (kk==0){ /*D3 tag - control*/ *(*(foutD3+kk)+ii)= flip*( *(this+kk+ignore)-*(this+kk+ignore+1) ); *(*(foutA3+kk)+ii)= 2*(*(this+kk+ignore)+*(this+kk+ignore+1)); } else{ *(*(foutD3+kk)+ii)= flip*( 1*(*(this+kk+ignore-1))+-2*(*(this+kk+ignore))+1*(*(this+kk+ignore+1)) ); *(*(foutA3+kk)+ii)= ((*(this+kk+ignore-1))+2*(*(this+kk+ignore))+(*(this+kk+ignore+1))); flip=-1*flip; } } for( kk=0 ; kk < nuse-ignore ; kk++ ) *(*(foutavgD3)+ii)= *(*(foutavgD3)+ii)+(*(*(foutD3+kk)+ii)); *(*(foutavgD3)+ii)=*(*(foutavgD3)+ii) / (*(numAv)); } DSET_unload( old_dset ) ; /* don't need this no more */ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout bricks to the dataset ***/ case MRI_float: for( kk=0 ; kk < nuse-ignore ; kk++ ) EDIT_substitute_brick( new_dsetD3 , kk , MRI_float , foutD3[kk] ) ; break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * boutD3 ; float facD3 ; for( kk=0 ; kk < nuse-ignore ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ boutD3 = (short *) malloc( sizeof(short) * nvox ) ; if( boutD3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } /*-- find scaling and then scale --*/ facD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutD3[kk] ) ; if( facD3 > 0.0 ){ facD3 = 32767.0 / facD3 ; EDIT_coerce_scale_type( nvox,facD3 , MRI_float,foutD3[kk] , MRI_short,boutD3 ) ; facD3 = 1.0 / facD3 ; } free( foutD3[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dsetD3 , kk , MRI_short , boutD3 ) ; tarD3 [kk] = facD3 ; } /*-- save scale factor array into dataset --*/ EDIT_dset_items( new_dsetD3 , ADN_brick_fac , tarD3 , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * boutD3 ; float facD3 ; for( kk=0 ; kk < nuse-ignore ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ boutD3 = (byte *) malloc( sizeof(byte) * nvox ) ; if( boutD3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } /*-- find scaling and then scale --*/ facD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutD3[kk] ) ; if( facD3 > 0.0 ){ facD3 = 255.0 / facD3 ; EDIT_coerce_scale_type( nvox,facD3 , MRI_float,foutD3[kk] , MRI_byte,boutD3 ) ; facD3 = 1.0 / facD3 ; } free( foutD3[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dsetD3 , kk , MRI_byte , boutD3 ) ; tarD3 [kk] = facD3 ; } /*-- save scale factor array into dataset --*/ EDIT_dset_items( new_dsetD3 , ADN_brick_fac , tarD3 , ADN_none ) ; } break ; } /* end of switch on output data type */ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout bricks to the dataset ***/ case MRI_float: for( kk=0 ; kk < nuse-ignore ; kk++ ) EDIT_substitute_brick( new_dsetA3 , kk , MRI_float , foutA3[kk] ) ; break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * boutA3 ; float facA3 ; for( kk=0 ; kk < nuse-ignore ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ boutA3 = (short *) malloc( sizeof(short) * nvox ) ; if( boutA3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } /*-- find scaling and then scale --*/ facA3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutA3[kk] ) ; if( facA3 > 0.0 ){ facA3 = 32767.0 / facA3 ; EDIT_coerce_scale_type( nvox,facA3 , MRI_float,foutA3[kk] , MRI_short,boutA3 ) ; facA3 = 1.0 / facA3 ; } free( foutA3[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dsetA3 , kk , MRI_short , boutA3 ) ; tarA3[kk] = facA3 ; } /*-- save scale factor array into dataset --*/ EDIT_dset_items( new_dsetA3 , ADN_brick_fac , tarA3 , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * boutA3 ; float facA3 ; for( kk=0 ; kk < nuse-ignore ; kk++ ){ /* loop over sub-bricks */ /*-- get output sub-brick --*/ boutA3 = (byte *) malloc( sizeof(byte) * nvox ) ; if( boutA3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } /*-- find scaling and then scale --*/ facA3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutA3[kk] ) ; if( facA3 > 0.0 ){ facA3 = 255.0 / facA3 ; EDIT_coerce_scale_type( nvox,facA3 , MRI_float,foutA3[kk] , MRI_byte,boutA3 ) ; facA3 = 1.0 / facA3 ; } free( foutA3[kk] ) ; /* don't need this anymore */ /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dsetA3 , kk , MRI_byte , boutA3 ) ; tarA3[kk]= facA3 ; } /*-- save scale factor array into dataset --*/ EDIT_dset_items( new_dsetA3 , ADN_brick_fac , tarA3 , ADN_none ) ; } break ; } /* end of switch on output data type */ switch( new_datum ){ case MRI_float:{ EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_float , foutavgD3[0] ) ; } break ; case MRI_short:{ short * boutavgD3 ; float facavgD3 ; boutavgD3 = (short *) malloc( sizeof(short) * nvox ) ; if( boutavgD3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } facavgD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutavgD3[0] ) ; if( facavgD3 > 0.0 ){ facavgD3 = 32767.0 / facavgD3 ; EDIT_coerce_scale_type( nvox,facavgD3 , MRI_float,foutavgD3[0] , MRI_short,boutavgD3 ) ; facavgD3 = 1.0 / facavgD3 ; } EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_short , boutavgD3 ) ; taravgD3[0] = facavgD3 ; EDIT_dset_items( new_dsetavgD3 , ADN_brick_fac , taravgD3 , ADN_none ) ; } break ; case MRI_byte:{ byte * boutavgD3 ; float facavgD3 ; boutavgD3 = (byte *) malloc( sizeof(byte) * nvox ) ; if( boutavgD3 == NULL ){ fprintf(stderr,"\nFinal malloc error in plug_power!\n\a") ; EXIT(1) ; } facavgD3 = MCW_vol_amax( nvox,1,1 , MRI_float , foutavgD3[0] ) ; if( facavgD3 > 0.0 ){ facavgD3 = 255.0 / facavgD3 ; EDIT_coerce_scale_type( nvox,facavgD3 , MRI_float,foutavgD3[0] , MRI_byte,boutavgD3 ) ; facavgD3 = 1.0 / facavgD3 ; } EDIT_substitute_brick( new_dsetavgD3 , 0 , MRI_byte , boutavgD3 ) ; taravgD3[0]= facavgD3 ; EDIT_dset_items( new_dsetavgD3 , ADN_brick_fac , taravgD3 , ADN_none ) ; } break ; } /* endasda of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ PLUTO_add_dset( plint , new_dsetD3 , DSET_ACTION_NONE ) ; PLUTO_add_dset( plint , new_dsetA3 , DSET_ACTION_NONE ) ; PLUTO_add_dset( plint , new_dsetavgD3 , DSET_ACTION_NONE ) ; FREE_WORKSPACE ; free(numAv); return NULL ; /* null string returned means all was OK */ }
/*---------------------------------------------------------------------- ** ** Subtract hemispheres assuming we need floats. ** **---------------------------------------------------------------------- */ static char * process_as_floats( THD_3dim_dataset * dset, hemi_s * hs ) { int count, cx, type = hs->thresh_type; int nx, ny, nz, nvox; short * sp, * sdata; float * fdata, * fp, * fp2; float factor, maxabs; nx = dset->daxes->nxx; ny = dset->daxes->nyy; nz = dset->daxes->nzz; nvox = nx * ny * nz; sdata = (short *)DSET_ARRAY( dset, 0 ); factor = DSET_BRICK_FACTOR( dset, 0 ); factor = factor == 0.0 ? 1.0 : factor; /* first get the data into a float array */ if ( ( fdata = (float *)malloc( nvox * sizeof( float ) ) ) == NULL ) return "------------------------------\n" "paf: failed allocation of floats" "------------------------------\n"; fp = fdata; sp = sdata; for ( count = 0; count < nvox; count++ ) { *fp = *sdata * factor; if ( ( type == 1 ) && ( *fp < 0 ) ) *fp = 0; else if ( ( type == 2 ) && ( *fp > 0 ) ) *fp = 0; fp++; sp++; } /* now make the subtraction as floats */ for ( count = 0; count < ny*nz; count++ ) { fp = fdata + count * nx; fp2 = fp + nx - 1; for ( cx = 0; cx < (nx+1)/2; cx++ ) { *fp = *fp - *fp2; *fp2 = -*fp; fp++; fp2--; } } /* now make a new factor */ maxabs = MCW_vol_amax( nvox, 1, 1, MRI_float, fdata ); /* result is all zero, let the user worry */ if ( maxabs != 0.0 ) { factor = MRI_TYPE_maxval[MRI_short] /maxabs; /* 32767? / maxabs */ EDIT_coerce_scale_type( nvox, factor, MRI_float, fdata, MRI_short, sdata ); DSET_BRICK_FACTOR( dset, 0 ) = factor == 0.0 ? 0.0 : 1.0 / factor; THD_load_statistics( dset ); } free(fdata); return NULL; /* success */ }
/*! Turn float arrays into sub-bricks of a preset type (based on code in 3dMean) dset (THD_3dim_dataset *) new dset to which arrays will be added far (float **) each far[i] is to become one sub-brick in dset nval (int) the number of arrays in far otype (int) the sub-brick type. Supported options are: MRI_float (so far scaleopt (char) scaling options: 'A' scale if needed 'F' do scale each sub-brick 'G' scale all sub-bricks with the same factor 'N' Do not scale verb (int) loquaciousness returns 1 if all is well 0 all hell broke loose */ int EDIT_add_bricks_from_far(THD_3dim_dataset *dset, float **far, int nval, int otype, char scaleopt, int verb) { int ii=0, kk=0, nxyz; ENTRY("EDIT_add_bricks_from_far"); if (scaleopt != 'A' && scaleopt != 'F' && scaleopt != 'G' && scaleopt != 'N'){ ERROR_message("Bad scaleopt value of %c", scaleopt); RETURN(0); } if (!dset) { ERROR_message("NULL input"); RETURN(0); } nxyz = DSET_NVOX(dset); switch( otype ){ default: ERROR_message("Somehow ended up with otype = %d\n",otype) ; RETURN(0) ; case MRI_float:{ for( kk=0 ; kk < nval ; kk++ ){ EDIT_substitute_brick(dset, kk, MRI_float, far[kk]); DSET_BRICK_FACTOR(dset, kk) = 0.0; far[kk] = NULL; } } break ; case MRI_byte: case MRI_short:{ void ** dfim ; float gtop=0.0 , fimfac , gtemp ; if( verb ) fprintf(stderr," ++ Scaling output to type %s brick(s)\n", MRI_TYPE_name[otype] ) ; dfim = (void **) malloc(sizeof(void *)*nval) ; if( scaleopt == 'G' ){ /* allow global scaling */ gtop = 0.0 ; for( kk=0 ; kk < nval ; kk++ ){ gtemp = MCW_vol_amax( nxyz , 1 , 1 , MRI_float, far[kk] ) ; gtop = MAX( gtop , gtemp ) ; if( gtemp == 0.0 ) WARNING_message("output sub-brick %d is all zeros!\n",kk) ; } } for (kk = 0 ; kk < nval ; kk ++ ) { if( scaleopt != 'G' && scaleopt != 'N'){ /* compute max value in this sub-brick */ gtop = MCW_vol_amax( nxyz , 1 , 1 , MRI_float, far[kk] ) ; if( gtop == 0.0 ) WARNING_message("output sub-brick %d is all zeros!\n",kk) ; } if( scaleopt == 'F' || scaleopt == 'G'){ /* scaling needed */ fimfac = (gtop > 0.0) ? MRI_TYPE_maxval[otype] / gtop : 0.0 ; } else if( scaleopt == 'A' ){ /* only if needed */ fimfac = ( gtop > MRI_TYPE_maxval[otype] || (gtop > 0.0 && gtop < 1.0) ) ? MRI_TYPE_maxval[otype]/ gtop : 0.0 ; if( fimfac == 0.0 && gtop > 0.0 ){ /* 14 May 2010 */ float fv,iv ; /* force scaling if */ for( ii=0 ; ii < nxyz ; ii++ ){ /* non-integers are inside */ fv = far[kk][ii] ; iv = rint(fv) ; if( fabsf(fv-iv) >= 0.01 ){ fimfac = MRI_TYPE_maxval[otype] / gtop ; break ; } } } } else if( scaleopt == 'N') { /* no scaling allowed */ fimfac = 0.0 ; } else { ERROR_message("Should not see this one"); RETURN(0); } if( verb ){ if( fimfac != 0.0 ) INFO_message("Sub-brick %d scale factor = %f\n",kk,fimfac) ; else INFO_message("Sub-brick %d: no scale factor\n" ,kk) ; } dfim[kk] = (void *) malloc( mri_datum_size(otype) * nxyz ) ; if( dfim[kk] == NULL ){ ERROR_message("malloc fails at output\n"); exit(1); } EDIT_coerce_scale_type( nxyz , fimfac , MRI_float, far[kk] , otype,dfim[kk] ) ; if( otype == MRI_short ) EDIT_misfit_report( DSET_FILECODE(dset) , kk , nxyz , (fimfac != 0.0f) ? 1.0f/fimfac : 0.0f , dfim[kk] , far[kk] ) ; free( far[kk] ) ; far[kk] = NULL; EDIT_substitute_brick(dset, kk, otype, dfim[kk] ); DSET_BRICK_FACTOR(dset,kk) = (fimfac != 0.0) ? 1.0/fimfac : 0.0 ; dfim[kk]=NULL; } free(dfim); dfim = NULL; } break ; } RETURN(1); }
int main( int argc , char *argv[] ) { int vstep=0 , ii,nvox , ntin , ntout , do_one=0 , nup=-1 ; THD_3dim_dataset *inset=NULL , *outset ; char *prefix="Upsam", *dsetname=NULL ; int verb=0 , iarg=1, datum = MRI_float; float *ivec , *ovec , trin , trout, *fac=NULL, *ofac=NULL, top=0.0, maxtop=0.0; /*------- help the pitifully ignorant user? -------*/ if( argc < 2 || strcmp(argv[1],"-help") == 0 ){ printf( "Usage: 3dUpsample [options] n dataset\n" "\n" "* Upsamples a 3D+time dataset, in the time direction,\n" " by a factor of 'n'.\n" "* The value of 'n' must be between 2 and 320 (inclusive).\n" "* The output dataset is in float format by default.\n" "\n" "Options:\n" "--------\n" " -1 or -one = Use linear interpolation. Otherwise,\n" " or -linear 7th order polynomial interpolation is used.\n" "\n" " -prefix pp = Define the prefix name of the output dataset.\n" " [default prefix is 'Upsam']\n" "\n" " -verb = Be eloquently and mellifluosly verbose.\n" "\n" " -n n = An alternate way to specify n\n" " -input dataset = An alternate way to specify dataset\n" "\n" " -datum ddd = Use datatype ddd at output. Choose from\n" " float (default), short, byte.\n" "Example:\n" "--------\n" " 3dUpsample -prefix LongFred 5 Fred+orig\n" "\n" "Nota Bene:\n" "----------\n" "* You should not use this for files that were 3dTcat-ed across\n" " imaging run boundaries, since that will result in interpolating\n" " between non-contiguous time samples!\n" "* If the input has M time points, the output will have n*M time\n" " points. The last n-1 of them will be past the end of the original\n" " time series.\n" "* This program gobbles up memory and diskspace as a function of n.\n" " You can reduce output file size with -datum option.\n" "\n" "--- RW Cox - April 2008\n" ) ; PRINT_COMPILE_DATE ; exit(0) ; } mainENTRY("3dUpsample"); machdep(); PRINT_VERSION("3dUpsample"); AUTHOR("RWCox") ; AFNI_logger("3dUpsample",argc,argv); /*------- read command line args -------*/ datum = MRI_float; iarg = 1 ; while( iarg < argc && argv[iarg][0] == '-' ){ if( strncasecmp(argv[iarg],"-prefix",5) == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); prefix = argv[iarg] ; if( !THD_filename_ok(prefix) ) ERROR_exit("Illegal string after -prefix: '%s'",prefix) ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-one",4) == 0 || strcmp (argv[iarg],"-1" ) == 0 || strncasecmp(argv[iarg],"-lin",4) == 0 ){ do_one = 1 ; iarg++ ; continue ; } if( strncasecmp(argv[iarg],"-verb",3) == 0 ){ verb = 1 ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-n") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); nup = (int)strtod(argv[iarg],NULL) ; if( nup < 2 || nup > 320 ) ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-input") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); dsetname = argv[iarg]; iarg++ ; continue ; } if( strcasecmp(argv[iarg],"-datum") == 0 ){ if( ++iarg >= argc ) ERROR_exit("Need argument after '%s'",argv[iarg-1]); if( strcmp(argv[iarg],"short") == 0 ){ datum = MRI_short ; } else if( strcmp(argv[iarg],"float") == 0 ){ datum = MRI_float ; } else if( strcmp(argv[iarg],"byte") == 0 ){ datum = MRI_byte ; } else { ERROR_message("-datum of type '%s' not supported in 3dUpsample!\n", argv[iarg] ) ; exit(1) ; } iarg++ ; continue ; } ERROR_message("Unknown argument on command line: '%s'",argv[iarg]) ; suggest_best_prog_option(argv[0], argv[iarg]); exit (1); } /*------- check options for completeness and consistency -----*/ if (nup == -1) { if( iarg+1 >= argc ) ERROR_exit("need 'n' and 'dataset' on command line!") ; nup = (int)strtod(argv[iarg++],NULL) ; if( nup < 2 || nup > 320 ) ERROR_exit("3dUpsample rate '%d' is outside range 2..320",nup) ; } if (!dsetname) { if( iarg >= argc ) ERROR_exit("need 'dataset' on command line!") ; dsetname = argv[iarg]; } inset = THD_open_dataset(dsetname) ; if( !ISVALID_DSET(inset) ) ERROR_exit("3dUpsample can't open dataset '%s'", dsetname) ; ntin = DSET_NVALS(inset) ; trin = DSET_TR(inset) ; if( ntin < 2 ) ERROR_exit("dataset '%s' has only 1 value per voxel?!",dsetname) ; nvox = DSET_NVOX(inset) ; if( verb ) INFO_message("loading input dataset into memory") ; DSET_load(inset) ; CHECK_LOAD_ERROR(inset) ; /*------ create output dataset ------*/ ntout = ntin * nup ; trout = trin / nup ; /* scaling factor for output */ fac = NULL; maxtop = 0.0; if (MRI_IS_INT_TYPE(datum)) { fac = (float *)calloc(DSET_NVALS(inset), sizeof(float)); ofac = (float *)calloc(ntout, sizeof(float)); for (ii=0; ii<DSET_NVALS(inset); ++ii) { top = MCW_vol_amax( DSET_NVOX(inset),1,1 , DSET_BRICK_TYPE(inset,ii), DSET_BRICK_ARRAY(inset,ii) ) ; if (DSET_BRICK_FACTOR(inset, ii)) top = top * DSET_BRICK_FACTOR(inset,ii); fac[ii] = (top > MRI_TYPE_maxval[datum]) ? top/MRI_TYPE_maxval[datum] : 0.0 ; if (top > maxtop) maxtop = top; } if (storage_mode_from_filename(prefix) != STORAGE_BY_BRICK) { fac[0] = (maxtop > MRI_TYPE_maxval[datum]) ? maxtop/MRI_TYPE_maxval[datum] : 0.0 ; for (ii=0; ii<ntout; ++ii) ofac[ii] = fac[0]; if (verb) INFO_message("Forcing global scaling, Max = %f, fac = %f\n", maxtop, fac[0]); } else { if (verb) INFO_message("Reusing scaling factors of input dset\n"); upsample_1( nup, DSET_NVALS(inset), fac, ofac); } } free(fac); fac = NULL; outset = EDIT_empty_copy(inset) ; EDIT_dset_items( outset , ADN_nvals , ntout , ADN_ntt , DSET_NUM_TIMES(inset) > 1 ? ntout : 0 , ADN_datum_all , datum , ADN_brick_fac , ofac , ADN_prefix , prefix , ADN_none ) ; tross_Copy_History( inset , outset ) ; tross_Make_History( "3dUpsample" , argc,argv , outset ) ; free(ofac); ofac = NULL; if( outset->taxis != NULL ){ outset->taxis->ttdel /= nup ; outset->taxis->ttdur /= nup ; if( outset->taxis->toff_sl != NULL ){ for( ii=0 ; ii < outset->taxis->nsl ; ii++ ) outset->taxis->toff_sl[ii] /= nup ; } } for( ii=0 ; ii < ntout ; ii++ ){ /* create empty bricks to be filled below */ EDIT_substitute_brick( outset , ii , datum , NULL ) ; } /*------- loop over voxels and process them one at a time ---------*/ if( verb ) INFO_message("Upsampling time series from %d to %d: %s interpolation", ntin , ntout , (do_one) ? "linear" : "heptic" ) ; if( verb && nvox > 499 ) vstep = nvox / 50 ; if( vstep > 0 ) fprintf(stderr,"++ voxel loop: ") ; ivec = (float *)malloc(sizeof(float)*ntin) ; ovec = (float *)malloc(sizeof(float)*ntout) ; for( ii=0 ; ii < nvox ; ii++ ){ if( vstep > 0 && ii%vstep==vstep-1 ) vstep_print() ; THD_extract_array( ii , inset , 0 , ivec ) ; if( do_one ) upsample_1( nup , ntin , ivec , ovec ) ; else upsample_7( nup , ntin , ivec , ovec ) ; THD_insert_series( ii , outset , ntout , MRI_float , ovec , datum==MRI_float ? 1:0 ) ; } /* end of loop over voxels */ if( vstep > 0 ) fprintf(stderr," Done!\n") ; /*----- clean up and go away -----*/ DSET_write(outset) ; if( verb ) WROTE_DSET(outset) ; if( verb ) INFO_message("Total CPU time = %.1f s",COX_cpu_time()) ; exit(0); }
THD_3dim_dataset * MAKER_4D_to_typed_fim( THD_3dim_dataset * old_dset , char * new_prefix , int new_datum , int ignore , int detrend , generic_func * user_func , void * user_data ) { THD_3dim_dataset * new_dset ; /* output dataset */ 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) */ complex ** cptr = NULL ; float * fxar = NULL ; /* array loaded from input dataset */ float * fac = NULL ; /* array of brick scaling factors */ float * fout = NULL ; /* will be array of output floats */ float * dtr = NULL ; /* will be array of detrending coeff */ float val , d0fac , d1fac , x0,x1; double tzero=0 , tdelta , ts_mean , ts_slope ; int ii , old_datum , nuse , use_fac , iz,izold, nxy,nvox , nbad ; register int kk ; void (*ufunc)(double,double,int,float *,double,double,void *,float *) = (void (*)(double,double,int,float *,double,double,void *,float *)) user_func ; /*----------------------------------------------------------*/ /*----- Check inputs to see if they are reasonable-ish -----*/ if( ! ISVALID_3DIM_DATASET(old_dset) ) return NULL ; if( new_datum >= 0 && new_datum != MRI_byte && new_datum != MRI_short && new_datum != MRI_float ) return NULL ; if( user_func == NULL ) return NULL ; if( ignore < 0 ) ignore = 0 ; /*--------- set up pointers to each sub-brick in the input dataset ---------*/ old_datum = DSET_BRICK_TYPE( old_dset , 0 ) ; /* get old dataset datum */ nuse = DSET_NUM_TIMES(old_dset) - ignore ; /* # of points on time axis */ if( nuse < 2 ) return NULL ; if( new_datum < 0 ) new_datum = old_datum ; /* output datum = input */ if( new_datum == MRI_complex ) return NULL ; /* but complex = bad news */ DSET_load( old_dset ) ; /* must be in memory before we get pointers to it */ kk = THD_count_databricks( old_dset->dblk ) ; /* check if it was */ if( kk < DSET_NVALS(old_dset) ){ /* loaded correctly */ DSET_unload( old_dset ) ; return NULL ; } switch( old_datum ){ /* pointer type depends on input datum type */ default: /** don't know what to do **/ DSET_unload( old_dset ) ; 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..nuse-1. */ case MRI_byte: bptr = (byte **) malloc( sizeof(byte *) * nuse ) ; if( bptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) bptr[kk] = (byte *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is shorts ---------*/ /* voxel #i at time #k is sptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_short: sptr = (short **) malloc( sizeof(short *) * nuse ) ; if( sptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) sptr[kk] = (short *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is floats ---------*/ /* voxel #i at time #k is fptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_float: fptr = (float **) malloc( sizeof(float *) * nuse ) ; if( fptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) fptr[kk] = (float *) DSET_ARRAY(old_dset,kk+ignore) ; break ; /*--------- input is complex ---------*/ /* voxel #i at time #k is cptr[k][i] */ /* for i=0..nvox-1 and k=0..nuse-1. */ case MRI_complex: cptr = (complex **) malloc( sizeof(complex *) * nuse ) ; if( cptr == NULL ) return NULL ; for( kk=0 ; kk < nuse ; kk++ ) cptr[kk] = (complex *) DSET_ARRAY(old_dset,kk+ignore) ; break ; } /* end of switch on input type */ /*---- allocate space for 1 voxel timeseries ----*/ fxar = (float *) malloc( sizeof(float) * nuse ) ; /* voxel timeseries */ if( fxar == NULL ){ FREE_WORKSPACE ; return NULL ; } /*--- get scaling factors for sub-bricks ---*/ fac = (float *) malloc( sizeof(float) * nuse ) ; /* factors */ if( fac == NULL ){ FREE_WORKSPACE ; return NULL ; } use_fac = 0 ; for( kk=0 ; kk < nuse ; kk++ ){ fac[kk] = DSET_BRICK_FACTOR(old_dset,kk+ignore) ; if( fac[kk] != 0.0 ) use_fac++ ; else fac[kk] = 1.0 ; } if( !use_fac ) FREEUP(fac) ; /*--- setup for detrending ---*/ dtr = (float *) malloc( sizeof(float) * nuse ) ; if( dtr == NULL ){ FREE_WORKSPACE ; return NULL ; } d0fac = 1.0 / nuse ; d1fac = 12.0 / nuse / (nuse*nuse - 1.0) ; for( kk=0 ; kk < nuse ; kk++ ) dtr[kk] = kk - 0.5 * (nuse-1) ; /* linear trend, orthogonal to 1 */ /*---------------------- make a new dataset ----------------------*/ new_dset = EDIT_empty_copy( old_dset ) ; /* start with copy of old one */ /*-- edit some of its internal parameters --*/ ii = EDIT_dset_items( new_dset , ADN_prefix , new_prefix , /* filename prefix */ ADN_malloc_type , DATABLOCK_MEM_MALLOC , /* store in memory */ ADN_datum_all , new_datum , /* atomic datum */ ADN_nvals , 1 , /* # sub-bricks */ ADN_ntt , 0 , /* # time points */ ADN_type , ISHEAD(old_dset) /* dataset type */ ? HEAD_FUNC_TYPE : GEN_FUNC_TYPE , ADN_func_type , FUNC_FIM_TYPE , /* function type */ ADN_none ) ; if( ii != 0 ){ ERROR_message("Error creating dataset '%s'",new_prefix) ; THD_delete_3dim_dataset( new_dset , False ) ; /* some error above */ FREE_WORKSPACE ; return NULL ; } /*------ make floating point output brick (only at the end will scale to byte or shorts) ------*/ nvox = old_dset->daxes->nxx * old_dset->daxes->nyy * old_dset->daxes->nzz ; fout = (float *) malloc( sizeof(float) * nvox ) ; /* ptr to brick */ if( fout == NULL ){ THD_delete_3dim_dataset( new_dset , False ) ; FREE_WORKSPACE ; return NULL ; } /*----- set up to find time at each voxel -----*/ tdelta = old_dset->taxis->ttdel ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tdelta *= 0.001 ; if( tdelta == 0.0 ) tdelta = 1.0 ; izold = -666 ; nxy = old_dset->daxes->nxx * old_dset->daxes->nyy ; /*----------------------------------------------------*/ /*----- Setup has ended. Now do some real work. -----*/ /* start notification */ #if 0 user_func( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , nvox , NULL,0.0,0.0 , user_data , NULL ) ; #endif /***** loop over voxels *****/ for( ii=0 ; ii < nvox ; ii++ ){ /* 1 time series at a time */ /*** load data from input dataset, depending on type ***/ switch( old_datum ){ /*** input = bytes ***/ case MRI_byte: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = bptr[kk][ii] ; break ; /*** input = shorts ***/ case MRI_short: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = sptr[kk][ii] ; break ; /*** input = floats ***/ case MRI_float: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = fptr[kk][ii] ; break ; /*** input = complex (note we use absolute value) ***/ case MRI_complex: for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] = CABS(cptr[kk][ii]) ; break ; } /* end of switch over input type */ /*** scale? ***/ if( use_fac ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] *= fac[kk] ; /** compute mean and slope **/ x0 = x1 = 0.0 ; for( kk=0 ; kk < nuse ; kk++ ){ x0 += fxar[kk] ; x1 += fxar[kk] * dtr[kk] ; } x0 *= d0fac ; x1 *= d1fac ; /* factors to remove mean and trend */ ts_mean = x0 ; ts_slope = x1 / tdelta ; /** detrend? **/ if( detrend ) for( kk=0 ; kk < nuse ; kk++ ) fxar[kk] -= (x0 + x1 * dtr[kk]) ; /** compute start time of this timeseries **/ iz = ii / nxy ; /* which slice am I in? */ if( iz != izold ){ /* in a new slice? */ tzero = THD_timeof( ignore , old_dset->daxes->zzorg + iz*old_dset->daxes->zzdel , old_dset->taxis ) ; izold = iz ; if( DSET_TIMEUNITS(old_dset) == UNITS_MSEC_TYPE ) tzero *= 0.001 ; } /*** compute output ***/ #if 0 user_func( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #else ufunc( tzero,tdelta , nuse,fxar,ts_mean,ts_slope , user_data , fout+ii ) ; #endif } /* end of outer loop over 1 voxels at a time */ DSET_unload( old_dset ) ; /* don't need this no more */ /* end notification */ #if 0 user_func( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #else ufunc( 0.0 , 0.0 , 0 , NULL,0.0,0.0 , user_data , NULL ) ; #endif nbad = thd_floatscan( nvox , fout ) ; /* 08 Aug 2000 */ if( nbad > 0 ) fprintf(stderr, "++ Warning: %d bad floats computed in MAKER_4D_to_typed_fim\n\a", nbad ) ; /*------------------------------------------------------------*/ /*------- The output is now in fout[ii], ii=0..nvox-1. We must now put this into the output dataset -------*/ switch( new_datum ){ /*** output is floats is the simplest: we just have to attach the fout brick to the dataset ***/ case MRI_float: EDIT_substitute_brick( new_dset , 0 , MRI_float , fout ) ; fout = NULL ; /* so it won't be freed later */ break ; /*** output is shorts: we have to create a scaled sub-brick from fout ***/ case MRI_short:{ short * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (short *) malloc( sizeof(short) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 32767.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_short,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_short , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; /*** output is bytes (byte = unsigned char) we have to create a scaled sub-brick from fout ***/ case MRI_byte:{ byte * bout ; float sfac ; /*-- get output sub-brick --*/ bout = (byte *) malloc( sizeof(byte) * nvox ) ; if( bout == NULL ){ fprintf(stderr, "\nFinal malloc error in MAKER_4D_to_fim - is memory exhausted?\n\a"); EXIT(1) ; } /*-- find scaling and then scale --*/ sfac = MCW_vol_amax( nvox,1,1 , MRI_float , fout ) ; if( sfac > 0.0 ){ sfac = 255.0 / sfac ; EDIT_coerce_scale_type( nvox,sfac , MRI_float,fout , MRI_byte,bout ) ; sfac = 1.0 / sfac ; } /*-- put output brick into dataset, and store scale factor --*/ EDIT_substitute_brick( new_dset , 0 , MRI_byte , bout ) ; EDIT_dset_items( new_dset , ADN_brick_fac , &sfac , ADN_none ) ; } break ; } /* end of switch on output data type */ /*-------------- Cleanup and go home ----------------*/ FREE_WORKSPACE ; return new_dset ; }