Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
plug_hemisub.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "afni.h"
00034
00035 typedef struct
00036 {
00037 int thresh_type;
00038 } hemi_s;
00039
00040 static char * process_data ( THD_3dim_dataset *, hemi_s * );
00041 static char * process_as_floats( THD_3dim_dataset *, hemi_s * );
00042
00043 #ifndef ALLOW_PLUGINS
00044 # error "Plugins not properly set up -- see machdep.h"
00045 #endif
00046
00047
00048
00049
00050
00051 char * HEMISUB_main( PLUGIN_interface * );
00052
00053 #define NUM_T_OPTS 3
00054
00055 static char * thresh_opts[ NUM_T_OPTS ] =
00056 { "any", "positives only", "negatives only" };
00057 static char helpstring[] =
00058 "Hemisubtract - used to subtract one hemisphere from the other\n"
00059 ;
00060
00061
00062
00063
00064
00065
00066
00067
00068 DEFINE_PLUGIN_PROTOTYPE
00069
00070 PLUGIN_interface * PLUGIN_init( int ncall )
00071 {
00072 PLUGIN_interface * plint ;
00073
00074 if( ncall > 0 ) return NULL ;
00075
00076
00077
00078 plint = PLUTO_new_interface( "Hemi-subtract", "hemisphere subtraction",
00079 helpstring, PLUGIN_CALL_VIA_MENU , HEMISUB_main );
00080
00081 PLUTO_add_hint( plint,
00082 "from each voxel's value, subtract that of the reflected voxel" );
00083
00084 PLUTO_set_sequence( plint , "z:Reynolds" ) ;
00085
00086
00087
00088 PLUTO_add_option( plint, "Input" , "Input" , TRUE );
00089 PLUTO_add_hint( plint, "choose dataset for input" );
00090 PLUTO_add_dataset(plint, "Dataset" , ANAT_ALL_MASK , FUNC_ALL_MASK,
00091 DIMEN_3D_MASK | BRICK_SHORT_MASK );
00092
00093
00094
00095 PLUTO_add_option( plint, "Output" , "prefix" , TRUE );
00096 PLUTO_add_hint( plint, "option: choose dataset prefix for output" );
00097 PLUTO_add_string( plint, "Prefix", 0, NULL, 19 );
00098
00099
00100
00101 PLUTO_add_option( plint, "Thresh Type", "Thresh Type", FALSE );
00102 PLUTO_add_string( plint, "Type", NUM_T_OPTS, thresh_opts, 0 );
00103
00104 return plint;
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114 char * HEMISUB_main( PLUGIN_interface * plint )
00115 {
00116 THD_3dim_dataset * dset, * new_dset;
00117 MCW_idcode * idc;
00118 hemi_s hs = { 0 };
00119 char * new_prefix;
00120 char * ret_string = NULL;
00121 char * tag;
00122
00123
00124 if ( plint == NULL )
00125 return "------------------------\n"
00126 "HEMISUB_main: NULL input\n"
00127 "------------------------\n";
00128
00129 PLUTO_next_option( plint );
00130 idc = PLUTO_get_idcode( plint );
00131 dset = PLUTO_find_dset( idc );
00132
00133 if( dset == NULL )
00134 return "-------------------------------\n"
00135 "HEMISUB_main: bad input dataset\n"
00136 "-------------------------------";
00137
00138 DSET_load( dset );
00139
00140 PLUTO_next_option( plint );
00141 new_prefix = PLUTO_get_string( plint );
00142 if ( ! PLUTO_prefix_ok( new_prefix ) )
00143 return "------------------------\n"
00144 "HEMISUB_main: bad prefix\n"
00145 "------------------------\n";
00146
00147 if ( ( new_dset = PLUTO_copy_dset( dset, new_prefix ) ) == NULL )
00148 return "------------------------------------------\n"
00149 "HEMISUB_main: failed to copy input dataset\n"
00150 "------------------------------------------\n";
00151
00152 tag = PLUTO_get_optiontag( plint );
00153 if ( tag && ! strcmp( tag, "Thresh Type" ) )
00154 {
00155 tag = PLUTO_get_string( plint );
00156 if ( tag != NULL )
00157 hs.thresh_type = PLUTO_string_index( tag, NUM_T_OPTS, thresh_opts );
00158 }
00159
00160 if ( ret_string = process_data( new_dset, &hs ) )
00161 return ret_string;
00162
00163 if ( PLUTO_add_dset( plint, new_dset, DSET_ACTION_MAKE_CURRENT ) )
00164 {
00165 THD_delete_3dim_dataset( new_dset, False );
00166
00167 return "---------------------------------------\n"
00168 "HEMISUB_main: failed to add new dataset\n"
00169 "---------------------------------------\n";
00170 }
00171
00172 return NULL;
00173 }
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 static char *
00185 process_data( THD_3dim_dataset * dset, hemi_s * hs )
00186 {
00187 int count, nx, ny, nz, cx, cx2;
00188 int type, diff, floats = ( DSET_BRICK_FACTOR( dset, 0 ) != 0.0 );
00189 short * data, * sp, * sp2;
00190
00191 nx = dset->daxes->nxx;
00192 ny = dset->daxes->nyy;
00193 nz = dset->daxes->nzz;
00194
00195 type = hs->thresh_type;
00196
00197 data = (short *)DSET_ARRAY( dset, 0 );
00198 for ( count = 0; ! floats && count < ny*nz; count++ )
00199 {
00200 sp = data;
00201 sp2 = data + nx - 1;
00202
00203 for ( cx = 0; cx < (nx+1)/2; cx++ )
00204 {
00205 if ( type == 1 )
00206 {
00207 if ( *sp < 0 )
00208 *sp = 0;
00209 if ( *sp2 < 0 )
00210 *sp2 = 0;
00211 }
00212 else if ( type == 2 )
00213 {
00214 if ( *sp > 0 )
00215 *sp = 0;
00216 if ( *sp2 > 0 )
00217 *sp2 = 0;
00218 }
00219
00220 diff = *sp - *sp2;
00221
00222 if ( ( diff > 32767 ) || ( diff < -32768 ) )
00223 floats = 1;
00224 else
00225 {
00226 *sp = diff;
00227 *sp2 = -diff;
00228 }
00229
00230 sp++;
00231 sp2--;
00232 }
00233
00234 data += nx;
00235 }
00236
00237 if ( floats )
00238 return process_as_floats( dset, hs );
00239
00240 return NULL;
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 static char *
00251 process_as_floats( THD_3dim_dataset * dset, hemi_s * hs )
00252 {
00253 int count, cx, type = hs->thresh_type;
00254 int nx, ny, nz, nvox;
00255 short * sp, * sdata;
00256 float * fdata, * fp, * fp2;
00257 float factor, maxabs;
00258
00259 nx = dset->daxes->nxx;
00260 ny = dset->daxes->nyy;
00261 nz = dset->daxes->nzz;
00262 nvox = nx * ny * nz;
00263
00264 sdata = (short *)DSET_ARRAY( dset, 0 );
00265
00266 factor = DSET_BRICK_FACTOR( dset, 0 );
00267 factor = factor == 0.0 ? 1.0 : factor;
00268
00269
00270
00271 if ( ( fdata = (float *)malloc( nvox * sizeof( float ) ) ) == NULL )
00272 return "------------------------------\n"
00273 "paf: failed allocation of floats"
00274 "------------------------------\n";
00275
00276 fp = fdata;
00277 sp = sdata;
00278 for ( count = 0; count < nvox; count++ )
00279 {
00280 *fp = *sdata * factor;
00281
00282 if ( ( type == 1 ) && ( *fp < 0 ) )
00283 *fp = 0;
00284 else if ( ( type == 2 ) && ( *fp > 0 ) )
00285 *fp = 0;
00286
00287 fp++;
00288 sp++;
00289 }
00290
00291
00292
00293 for ( count = 0; count < ny*nz; count++ )
00294 {
00295 fp = fdata + count * nx;
00296 fp2 = fp + nx - 1;
00297
00298 for ( cx = 0; cx < (nx+1)/2; cx++ )
00299 {
00300 *fp = *fp - *fp2;
00301 *fp2 = -*fp;
00302
00303 fp++;
00304 fp2--;
00305 }
00306 }
00307
00308
00309
00310 maxabs = MCW_vol_amax( nvox, 1, 1, MRI_float, fdata );
00311
00312
00313 if ( maxabs != 0.0 )
00314 {
00315 factor = MRI_TYPE_maxval[MRI_short] /maxabs;
00316
00317 EDIT_coerce_scale_type( nvox, factor, MRI_float, fdata, MRI_short, sdata );
00318
00319 DSET_BRICK_FACTOR( dset, 0 ) = factor == 0.0 ? 0.0 : 1.0 / factor;
00320
00321 THD_load_statistics( dset );
00322 }
00323 free(fdata);
00324 return NULL;
00325 }
00326