Doxygen Source Code Documentation
Main Page Alphabetical List Data Structures File List Data Fields Globals Search
afni_pplug_2dfunc.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include "afni.h"
00008 #include "parser.h"
00009
00010 #ifndef ALLOW_PLUGINS
00011 void F2D_init(void){}
00012 #else
00013
00014
00015
00016
00017
00018
00019
00020 static char helpstring[] =
00021 "Purpose: control the 2DChain function\n"
00022 "\n"
00023 "The 2DChain transformation allows you to chain together a sequence\n"
00024 "of up to 8 other 0D or 2D transformation functions. Each row of\n"
00025 "the input form controls one transformation. If it is toggled ON,\n"
00026 "then you can choose from a menu of functions. Each ON function is\n"
00027 "applied in turn.\n"
00028 "\n"
00029 "The special 'Expr 3x3' function lets you compute any expression\n"
00030 "that depends on the local 3x3 neighborhood of each pixel, where\n"
00031 "the expression is entered (a la 3dcalc) in the string field at\n"
00032 "the right of the form. The variable names that may be used in\n"
00033 "the expresssion are:\n"
00034 " r s t\n"
00035 " u v w\n"
00036 " x y z\n"
00037 "\n"
00038 "where 'v' is the center pixel. You may also use as a variable\n"
00039 "any name from previous active chain links (e.g., A,B,C, ...).\n"
00040 "For example, on line C, if you select 'Expr 3x3' as the function\n"
00041 "and enter\n"
00042 " (r+s+t+u+v+w+x+y+z)/9-A\n"
00043 "\n"
00044 "for the expression, this will evaluate the average of the 9\n"
00045 "local pixels and subtract the output of chain link A.\n"
00046 "On line C, you cannot use variables C or higher, since they\n"
00047 "won't have been calculated at the time C is being computed.\n"
00048 "\n"
00049 "Author -- RW Cox -- July 2000"
00050 ;
00051
00052
00053
00054 static char * F2D_main( PLUGIN_interface * ) ;
00055 static void F2D_chainfunc( int , int , double , double , float * ) ;
00056
00057
00058
00059
00060
00061 #define NUM_CHAIN 8
00062 static char alpha[27] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
00063
00064 #define RR 17
00065 #define SS 18
00066 #define TT 19
00067 #define UU 20
00068 #define VV 21
00069 #define WW 22
00070 #define XX 23
00071 #define YY 24
00072 #define ZZ 25
00073
00074 static int num0D , num2D ;
00075 static generic_func ** func0D , ** func2D ;
00076
00077 static int numfunc ;
00078 static char ** funcname ;
00079
00080 static int chain_do[NUM_CHAIN] ;
00081 static PARSER_code * chain_pc[NUM_CHAIN] ;
00082 static int chain_dd[NUM_CHAIN] ;
00083 static generic_func * chain_ff[NUM_CHAIN] ;
00084
00085 PLUGIN_interface * F2D_init(void)
00086 {
00087 PLUGIN_interface * plint ;
00088 int ii , num , ll ;
00089 char str[16] ;
00090 MCW_function_list * rlist ;
00091
00092
00093
00094 plint = PLUTO_new_interface( "2D Chain Func" ,
00095 "Control 2DChain function" ,
00096 helpstring ,
00097 PLUGIN_CALL_VIA_MENU ,
00098 (char *(*)())F2D_main ) ;
00099
00100 PLUTO_add_hint( plint , "Control 2DChain function" ) ;
00101
00102 PLUTO_set_runlabels( plint , "Set+Keep" , "Set+Close" ) ;
00103
00104
00105
00106 numfunc = 1 ;
00107 funcname = (char **) malloc(sizeof(char **)) ;
00108 funcname[0] = "Expr 3x3 -->" ;
00109
00110
00111
00112 rlist = &(GLOBAL_library.registered_0D) ;
00113 num0D = rlist->num ;
00114 if( num0D > 0 ){
00115 int n0 = 0 ;
00116 funcname = (char **) realloc( funcname, sizeof(char **)*(numfunc+num0D) );
00117 func0D = (generic_func **) malloc( sizeof(generic_func *)*num0D ) ;
00118 for( ii=0 ; ii < num0D ; ii++ ){
00119 if( rlist->flags[ii] == 0 ){
00120 ll = strlen(rlist->labels[ii]) ;
00121 funcname[numfunc] = AFMALL(char,ll+8) ;
00122 strcpy(funcname[numfunc],"0D: ") ;
00123 strcat(funcname[numfunc],rlist->labels[ii]) ;
00124 func0D[n0++] = rlist->funcs[ii] ;
00125 numfunc++ ;
00126 }
00127 }
00128 num0D = n0 ;
00129 }
00130
00131 rlist = &(GLOBAL_library.registered_2D) ;
00132 num2D = rlist->num ;
00133 if( num2D > 0 ){
00134 int n2 = 0 ;
00135 funcname = (char **) realloc( funcname, sizeof(char **)*(numfunc+num2D) );
00136 func2D = (generic_func **) malloc( sizeof(generic_func *)*num2D ) ;
00137 for( ii=0 ; ii < num2D ; ii++ ){
00138 if( rlist->flags[ii] == 0 ){
00139 ll = strlen(rlist->labels[ii]) ;
00140 funcname[numfunc] = AFMALL(char, ll+8) ;
00141 strcpy(funcname[numfunc],"2D: ") ;
00142 strcat(funcname[numfunc],rlist->labels[ii]) ;
00143 func2D[n2++] = rlist->funcs[ii] ;
00144 numfunc++ ;
00145 }
00146 }
00147 num2D = n2 ;
00148 }
00149
00150 AFNI_register_2D_function( "2DChain" , F2D_chainfunc ) ;
00151
00152
00153
00154 for( ii=0 ; ii < NUM_CHAIN ; ii++ ){
00155
00156 chain_do[ii] = 0 ;
00157 chain_pc[ii] = NULL ;
00158 chain_ff[ii] = NULL ;
00159
00160 str[0] = alpha[ii] ; str[1] = '\0' ;
00161
00162 PLUTO_add_option( plint ,
00163 str ,
00164 str ,
00165 FALSE
00166 ) ;
00167
00168 PLUTO_add_string( plint , "Function" ,
00169 numfunc , funcname , 0 ) ;
00170
00171 PLUTO_add_string( plint , "Expr 3x3" , 0,NULL,32 ) ;
00172 }
00173
00174
00175
00176 return plint ;
00177 }
00178
00179
00180
00181
00182
00183
00184
00185 static char * F2D_main( PLUGIN_interface * plint )
00186 {
00187 char *tag , *str ;
00188 int ii,kk,jj , ndone=0 ;
00189
00190
00191
00192 for( ii=0 ; ii < NUM_CHAIN ; ii++ ){
00193 chain_do[ii] = 0 ;
00194 chain_ff[ii] = NULL ;
00195 if( chain_pc[ii] != NULL ){ free(chain_pc[ii]); chain_pc[ii]=NULL; }
00196 }
00197
00198
00199
00200 while(1){
00201 tag = PLUTO_get_optiontag(plint) ;
00202 if( tag == NULL ) break ;
00203
00204
00205
00206 for( kk=0 ; kk < NUM_CHAIN ; kk++ )
00207 if( tag[0] == alpha[kk] ) break ;
00208
00209 if( kk >= NUM_CHAIN ) break ;
00210
00211 chain_do[kk] = 1 ; ndone++ ;
00212
00213 str = PLUTO_get_string(plint) ;
00214 jj = PLUTO_string_index( str , numfunc,funcname ) ;
00215
00216 if( jj < 0 || jj >= numfunc ){
00217
00218 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00219 return "** Internal Error **" ;
00220
00221 } else if( jj == 0 ){
00222 int hasym[26] , ns ;
00223
00224 str = PLUTO_get_string(plint) ;
00225 chain_pc[kk] = PARSER_generate_code(str) ;
00226 chain_dd[kk] = -1 ;
00227
00228 if( chain_pc[kk] == NULL ){
00229 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00230 return "** Expr 3x3 parser error **" ;
00231 }
00232
00233
00234
00235 PARSER_mark_symbols( chain_pc[kk] , hasym ) ;
00236
00237 for( ii=0 ; ii < kk ; ii++ ){
00238 if( hasym[ii] && chain_do[ii] == 0 ){
00239 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00240 return "** Expr 3x3 uses inactive symbol **" ;
00241 }
00242 }
00243
00244 if( hasym[kk] ){
00245 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00246 return "** Expr 3x3 uses current symbol **" ;
00247 }
00248
00249 for( ii=kk+1 ; ii < NUM_CHAIN ; ii++ ){
00250 if( hasym[ii] ){
00251 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00252 return "** Expr 3x3 uses subsequent symbol **" ;
00253 }
00254 }
00255
00256 for( ii=NUM_CHAIN ; ii < RR ; ii++ ){
00257 if( hasym[ii] ){
00258 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00259 return "** Expr 3x3 uses undefined symbol **" ;
00260 }
00261 }
00262
00263 for( ns=ii=0 ; ii < kk ; ii++ ) if( hasym[ii] ) ns++ ;
00264 for( ii=RR ; ii <=ZZ ; ii++ ) if( hasym[ii] ) ns++ ;
00265
00266 if( ns == 0 ){
00267 for( jj=0 ; jj < NUM_CHAIN ; jj++ ) chain_do[jj] = 0 ;
00268 return "** Expr 3x3 doesn't use any symbols **" ;
00269 }
00270
00271 } else if( jj >= 1 && jj <= num0D ){
00272
00273 chain_dd[kk] = 0 ;
00274 chain_ff[kk] = func0D[jj-1] ;
00275
00276 } else {
00277
00278 chain_dd[kk] = 2 ;
00279 chain_ff[kk] = func2D[jj-num0D-1] ;
00280 }
00281
00282 }
00283
00284
00285
00286 if( ndone == 0 ) return " \n** Don't you want to do anything? **\n " ;
00287
00288 return NULL ;
00289 }
00290
00291
00292
00293 static void F2D_chainfunc( int nx , int ny , double dx, double dy, float * ar )
00294 {
00295 int kk,ii,pp , ndo,nexp , nxy=nx*ny ;
00296 float * abc[NUM_CHAIN] , *aprev=ar , *rst,*uvw,*xyz ;
00297 double * atoz[26] , *tmp ;
00298
00299
00300
00301 for( nexp=ndo=kk=0 ; kk < NUM_CHAIN ; kk++ ){
00302 if( chain_do[kk] ){
00303 abc[kk] = (float *) malloc(sizeof(float)*nxy) ;
00304 ndo++ ;
00305 if( chain_pc[kk] != NULL ) nexp++ ;
00306 } else {
00307 abc[kk] = NULL ;
00308 }
00309 }
00310
00311 if( ndo == 0 ) return ;
00312
00313
00314
00315 if( nexp > 0 ){
00316 tmp = (double *) malloc(sizeof(double)*nx) ;
00317 for( ii=0 ; ii < 26 ; ii++)
00318 atoz[ii] = (double *) malloc(sizeof(double)*nx) ;
00319 }
00320
00321
00322
00323 for( kk=0 ; kk < NUM_CHAIN ; kk++ ){
00324 if( !chain_do[kk] ) continue ;
00325
00326 switch( chain_dd[kk] ){
00327
00328 case 0:
00329 memcpy( abc[kk] , aprev , sizeof(float)*nxy ) ;
00330 #if 0
00331 chain_ff[kk]( nxy , abc[kk] ) ;
00332 #else
00333 AFNI_CALL_0D_function( chain_ff[kk] , nxy,abc[kk] ) ;
00334 #endif
00335 break ;
00336
00337 case 2:
00338 memcpy( abc[kk] , aprev , sizeof(float)*nxy ) ;
00339 #if 0
00340 chain_ff[kk]( nx,ny , dx,dy , abc[kk] ) ;
00341 #else
00342 AFNI_CALL_2D_function( chain_ff[kk] , nx,ny,dx,dy,abc[kk] ) ;
00343 #endif
00344 break ;
00345
00346 case -1:{
00347 int hasym[26] , jj ;
00348
00349 PARSER_mark_symbols( chain_pc[kk] , hasym ) ;
00350
00351 for( jj=0 ; jj < ny ; jj++ ){
00352
00353 uvw = aprev + jj*nx ;
00354
00355 rst = (jj == 0) ? uvw
00356 : aprev + (jj-1)*nx ;
00357
00358 xyz = (jj == ny-1 ) ? uvw
00359 : aprev + (jj+1)*nx ;
00360
00361
00362
00363 for( pp=0 ; pp < 26 ; pp++){
00364 for( ii=0 ; ii < nx ; ii++ ) atoz[pp][ii] = 0.0 ;
00365 }
00366
00367
00368
00369 for( pp=0 ; pp < kk ; pp++ ){
00370 if( hasym[pp] ){
00371 for( ii=0 ; ii < nx ; ii++ )
00372 atoz[pp][ii] = (double) abc[pp][ii+jj*nx] ;
00373 }
00374 }
00375
00376 if( hasym[RR] ){
00377 atoz[RR][0] = (double) rst[0] ;
00378 for( ii=1 ; ii < nx ; ii++ )
00379 atoz[RR][ii] = (double) rst[ii-1] ;
00380 }
00381
00382 if( hasym[SS] ){
00383 for( ii=0 ; ii < nx ; ii++ )
00384 atoz[SS][ii] = (double) rst[ii] ;
00385 }
00386
00387 if( hasym[TT] ){
00388 for( ii=0 ; ii < nx-1 ; ii++ )
00389 atoz[TT][ii] = (double) rst[ii+1] ;
00390 atoz[TT][nx-1] = (double) rst[nx-1] ;
00391 }
00392
00393 if( hasym[UU] ){
00394 atoz[UU][0] = (double) uvw[0] ;
00395 for( ii=1 ; ii < nx ; ii++ )
00396 atoz[UU][ii] = (double) uvw[ii-1] ;
00397 }
00398
00399 if( hasym[VV] ){
00400 for( ii=0 ; ii < nx ; ii++ )
00401 atoz[VV][ii] = (double) uvw[ii] ;
00402 }
00403
00404 if( hasym[WW] ){
00405 for( ii=0 ; ii < nx-1 ; ii++ )
00406 atoz[WW][ii] = (double) uvw[ii+1] ;
00407 atoz[WW][nx-1] = (double) uvw[nx-1] ;
00408 }
00409
00410 if( hasym[XX] ){
00411 atoz[XX][0] = (double) xyz[0] ;
00412 for( ii=1 ; ii < nx ; ii++ )
00413 atoz[XX][ii] = (double) xyz[ii-1] ;
00414 }
00415
00416 if( hasym[YY] ){
00417 for( ii=0 ; ii < nx ; ii++ )
00418 atoz[YY][ii] = (double) xyz[ii] ;
00419 }
00420
00421 if( hasym[ZZ] ){
00422 for( ii=0 ; ii < nx-1 ; ii++ )
00423 atoz[ZZ][ii] = (double) xyz[ii+1] ;
00424 atoz[ZZ][nx-1] = (double) xyz[nx-1] ;
00425 }
00426
00427
00428
00429 PARSER_evaluate_vector( chain_pc[kk] , atoz , nx , tmp ) ;
00430
00431
00432
00433 uvw = abc[kk] + jj*nx ;
00434 for( ii=0 ; ii < nx ; ii++ ) uvw[ii] = (float) tmp[ii] ;
00435
00436 }
00437 }
00438 break ;
00439 }
00440
00441 aprev = abc[kk] ;
00442 }
00443
00444
00445
00446 memcpy( ar , aprev , sizeof(float)*nxy ) ;
00447
00448
00449
00450 for( kk=0 ; kk < NUM_CHAIN ; kk++ )
00451 if( abc[kk] != NULL ) free(abc[kk]) ;
00452
00453 if( nexp > 0 ){
00454 for( ii=0 ; ii < 26 ; ii++ ) free(atoz[ii]) ;
00455 free(tmp) ;
00456 }
00457
00458 return ;
00459 }
00460 #endif