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