00001 #include "afni.h"
00002
00003 #ifndef ALLOW_PLUGINS
00004 # error "Plugins not properly set up -- see machdep.h"
00005 #endif
00006
00007 #define DSETN_VERSION "Version 1.1 <October, 2002>"
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 char * DSETN_main ( PLUGIN_interface *) ;
00022 void DSETN_func ( MRI_IMAGE * ) ;
00023 void DSETN_dset_recv( int why, int np, int * ijk, void * aux ) ;
00024
00025 static int set_global_dsets_from_ids( void );
00026
00027 #undef USE_WHERE
00028
00029 static char helpstring[] =
00030 " Purpose: Control the 'Dataset#N' 1D timeseries function\n"
00031 "\n"
00032 " Dataset = a 3D+time dataset from which to extract data\n"
00033 " Color = color to overlay in AFNI graph window\n"
00034 "\n"
00035 " Usage:\n"
00036 " 1) Choose in this plugin the 3D+time datasets you want to graph,\n"
00037 " and their overlay colors. Then press 'Set+Keep'.\n"
00038 " 2) In an AFNI graph window, choose 'Tran 1D' to be 'Dataset#N'.\n"
00039 " This will cause the time series chosen here to replace the\n"
00040 " time series of the dataset being graphed.\n"
00041 " 3) Optionally, you can set 'Double Plot' to 'Overlay' in the\n"
00042 " AFNI graph window - this will then also show the time series\n"
00043 " from the current AFNI graph window.\n"
00044 "\n"
00045 " Note that changes in this plugin interface are not communicated\n"
00046 " to AFNI itself until you press one of the 'Set' buttons.\n"
00047 #ifdef USE_WHERE
00048 "\n"
00049 " Justify = Left means to put timeseries data at start of output array\n"
00050 " Right means to put timeseries data at end of output array\n"
00051 "\n"
00052 " Fill = Extend means to copy the last value\n"
00053 " Zero means to fill with zeros\n"
00054 "\n"
00055 " Justify and Fill are only used when the number of points in the input\n"
00056 " dataset doesn't match the number of points in the timeseries being replaced.\n"
00057 " Let M = length of dataset, N = length of timeseries,\n"
00058 " ts[] = timeseries array, ds[] = dataset array.\n"
00059 "\n"
00060 " Case: M < N (too little data to fill timeseries)\n"
00061 " Left: ts[i] = ds[i] i=0..M-1 Data goes to left\n"
00062 " = ds[M-1] i=M..N-1 if Extend edge of timeseries\n"
00063 " = 0.0 i=M..N-1 if Zero\n"
00064 " Right: ts[i] = ds[0] i=0..J-1 if Extend (with J=N-M) Data goes to right\n"
00065 " = 0.0 i=0..J-1 if Zero edge of timeseries\n"
00066 " = ds[i-J] i=J..N-1\n"
00067 " Case: M > N (too much data for timeseries)\n"
00068 " Left: ts[i] = ds[i] i=0..N-1 Left data to ts[]\n"
00069 " Right: ts[i] = ds[i+J] i=0..N-1 (with J=M-N) Right data to ts[]\n"
00070 #endif
00071 "\n"
00072 " -- RWCox - 29 Mar 2002\n"
00073 ;
00074
00075 #define NMAX 9
00076
00077 static THD_3dim_dataset *dset[NMAX] ;
00078 static MCW_idcode g_id[NMAX] ;
00079 static int ovc [NMAX] ;
00080 static int g_dset_recv = -1 ;
00081 static int g_valid_data = 0 ;
00082
00083 #ifdef USE_WHERE
00084 static int justify = 0 ;
00085 static int fill = 0 ;
00086 #endif
00087
00088
00089
00090
00091
00092 static char *lr[2] = { "Left" , "Right" } ;
00093 static char *ez[2] = { "Extend" , "Zero" } ;
00094
00095 static PLUGIN_interface *plint=NULL ;
00096
00097 static void DSETN_func_init(void)
00098 {
00099 PLUG_startup_plugin_CB( NULL , (XtPointer)plint , NULL ) ;
00100 }
00101
00102
00103 DEFINE_PLUGIN_PROTOTYPE
00104
00105 PLUGIN_interface * PLUGIN_init( int ncall )
00106 {
00107 int id ;
00108
00109 ENTRY("PLUGIN_init - Dataset#N") ;
00110
00111 if( ncall > 0 ) RETURN( NULL );
00112
00113 AFNI_register_nD_function ( 1 , "Dataset#N" , (generic_func *)DSETN_func ,
00114 NEEDS_DSET_INDEX|PROCESS_MRI_IMAGE ) ;
00115 AFNI_register_nD_func_init( 1 , (generic_func *) DSETN_func_init ) ;
00116
00117 plint = PLUTO_new_interface( "Dataset#N", "Controls 1D function Dataset#N",
00118 helpstring, PLUGIN_CALL_VIA_MENU, DSETN_main ) ;
00119
00120 PLUTO_add_hint( plint , "Controls 1D function Dataset#N" ) ;
00121
00122 PLUTO_set_sequence( plint , "A:funcs:dataset#N" ) ;
00123
00124 PLUTO_set_runlabels( plint , "Set+Keep" , "Set+Close" ) ;
00125
00126 for( id=0 ; id < NMAX ; id++ ){
00127 PLUTO_add_option( plint , "Input" , "Input" , FALSE ) ;
00128 PLUTO_add_dataset(plint , "Dataset" ,
00129 ANAT_ALL_MASK , FUNC_ALL_MASK ,
00130 DIMEN_4D_MASK | BRICK_ALLREAL_MASK ) ;
00131 PLUTO_add_overlaycolor( plint , "Color" ) ;
00132 }
00133
00134 #ifdef USE_WHERE
00135 PLUTO_add_option( plint , "Where" , "Where" , FALSE ) ;
00136 PLUTO_add_string( plint, "Justify", 2, lr, justify ) ;
00137
00138 PLUTO_add_option( plint , "How" , "How" , FALSE ) ;
00139 PLUTO_add_string( plint, "Fill", 2, ez, fill ) ;
00140 #endif
00141
00142
00143 for ( id=0 ; id < NMAX ; id++ ){
00144 dset[id] = NULL;
00145 ZERO_IDCODE(g_id[id]);
00146 }
00147
00148 RETURN( plint ) ;
00149 }
00150
00151
00152
00153
00154
00155 char * DSETN_main( PLUGIN_interface * plint )
00156 {
00157 MCW_idcode *idc ;
00158 char *str , *tag ;
00159 int id=0 ;
00160
00161 ENTRY( "DSETN_main" ) ;
00162
00163 if( plint == NULL )
00164 RETURN("***********************\n"
00165 "DSETN_main: NULL input\n"
00166 "***********************") ;
00167
00168 for( id=0 ; id < NMAX ; id++ ){
00169 dset[id] = NULL ;
00170 ZERO_IDCODE(g_id[id]);
00171 }
00172
00173 id = 0 ;
00174
00175 while( (tag=PLUTO_get_optiontag(plint)) != NULL ){
00176
00177
00178
00179 if( strcmp(tag,"Input") == 0 ){
00180 idc = PLUTO_get_idcode(plint) ;
00181 dset[id] = PLUTO_find_dset(idc) ;
00182
00183 if ( ! ISVALID_DSET( dset[id] ) )
00184 RETURN("******************************\n"
00185 "DSETN_main: bad input dataset\n"
00186 "******************************") ;
00187
00188 g_id[id] = *idc ;
00189 ovc [id] = PLUTO_get_overlaycolor(plint) ;
00190 id++ ; continue ;
00191 }
00192
00193 #ifdef USE_WHERE
00194
00195
00196 if( strcmp(tag,"Where") == 0 ){
00197 str = PLUTO_get_string(plint) ;
00198 justify = (strcmp(str,lr[0]) != 0) ;
00199 continue ;
00200 }
00201
00202
00203
00204 if( strcmp(tag,"How") == 0 ){
00205 str = PLUTO_get_string(plint) ;
00206 fill = (strcmp(str,ez[0]) != 0) ;
00207 continue ;
00208 }
00209 #endif
00210
00211 }
00212
00213 if ( id <= 0 )
00214 RETURN( NULL ) ;
00215
00216 g_valid_data = 1 ;
00217
00218 if ( g_dset_recv < 0 )
00219 g_dset_recv = AFNI_receive_init( plint->im3d, RECEIVE_DSETCHANGE_MASK,
00220 DSETN_dset_recv, plint ,
00221 "DSETN_dset_recv" ) ;
00222 if ( g_dset_recv < 0 )
00223 RETURN("*************************************\n"
00224 "DSETN_main: failed AFNI_receive_init\n"
00225 "*************************************") ;
00226
00227 PLUTO_force_redisplay() ;
00228 RETURN( NULL );
00229 }
00230
00231
00232
00233 void DSETN_dset_recv( int why, int np, int * ijk, void * aux )
00234 {
00235 PLUGIN_interface * plint = (PLUGIN_interface *)aux;
00236
00237 ENTRY( "DSETN_dset_recv" );
00238
00239 switch ( why )
00240 {
00241 default:
00242 {
00243 fprintf( stderr, "warning: DSETN_dset_recv() called with invalid "
00244 "why code, %d\n", why );
00245 EXRETURN;
00246 }
00247
00248 case RECEIVE_ALTERATION:
00249 case RECEIVE_DSETCHANGE:
00250 {
00251
00252 int num_valid = set_global_dsets_from_ids( );
00253
00254 if ( g_valid_data != 1 || num_valid <= 0 )
00255 {
00256
00257
00258 g_valid_data = 0;
00259
00260 AFNI_receive_control( plint->im3d, g_dset_recv,
00261 EVERYTHING_SHUTDOWN, NULL );
00262 g_dset_recv = -1;
00263 PLUTO_popup_worker( plint,
00264 "Warning: plugin 'Dataset#N'\n"
00265 "has lost its dataset links.\n"
00266 "To plot 1-D overlays, please\n"
00267 "re-run the plugin.",
00268 MCW_USER_KILL | MCW_TIMER_KILL ) ;
00269 }
00270 }
00271 }
00272
00273 EXRETURN;
00274 }
00275
00276
00277
00278 void DSETN_func( MRI_IMAGE *qim )
00279 {
00280 int id , ny , nxtop=0 , ijk , ii ;
00281 MRI_IMARR *tar ;
00282 MRI_IMAGE *tsim , *zim ;
00283 float *tsar , *dar ;
00284 int ovi[NMAX] ;
00285 char str[16+4*NMAX] ;
00286
00287 ENTRY( "DSETN_func" );
00288
00289 if ( g_valid_data != 1 )
00290 EXRETURN ;
00291
00292 INIT_IMARR(tar) ;
00293 ijk = AFNI_needs_dset_ijk() ;
00294
00295 for( id=0 ; id < NMAX ; id++ ){
00296 if( ISVALID_DSET(dset[id]) ){
00297 tsim = THD_extract_series( ijk,dset[id], 0 ) ;
00298 if( tsim == NULL ) continue ;
00299 ovi[IMARR_COUNT(tar)] = ovc[id] ;
00300 ADDTO_IMARR(tar,tsim) ;
00301 nxtop = MAX(nxtop,tsim->nx) ;
00302 }
00303 }
00304
00305 ny = IMARR_COUNT(tar) ;
00306
00307 if( ny == 0 || nxtop < 2 ){ DESTROY_IMARR(tar); EXRETURN; }
00308
00309 if( ny == 1 ){
00310 tsim = IMARR_SUBIM(tar,0); FREE_IMARR(tar);
00311 mri_move_guts(qim,tsim);
00312 sprintf(str,"color: %d",ovi[0]) ; mri_add_name(str,qim) ;
00313 EXRETURN;
00314 }
00315
00316
00317 tsim = mri_new( nxtop , ny , MRI_float ) ;
00318 tsar = MRI_FLOAT_PTR(tsim) ;
00319 strcpy(str,"color:") ;
00320 for( id=0 ; id < ny ; id++ ){
00321 zim = IMARR_SUBIM(tar,id) ;
00322 dar = MRI_FLOAT_PTR(zim) ;
00323 memcpy( tsar , dar , sizeof(float)*zim->nx) ;
00324 if( zim->nx < nxtop ){
00325 for( ii=zim->nx ; ii < nxtop ; ii++ ) tsar[ii] = WAY_BIG ;
00326 }
00327 tsar += nxtop ;
00328 sprintf(str+strlen(str)," %d",ovi[id]) ;
00329 }
00330
00331 DESTROY_IMARR(tar) ;
00332 mri_move_guts(qim,tsim) ; mri_add_name(str,qim) ;
00333 EXRETURN;
00334 }
00335
00336 static int set_global_dsets_from_ids( void )
00337 {
00338 THD_3dim_dataset * dptr;
00339 int idcount, num_valid = 0;
00340
00341 ENTRY( "set_global_dsets_from_ids" );
00342
00343 for ( idcount = 0; idcount < NMAX; idcount++ )
00344 {
00345 if ( ! ISZERO_IDCODE( g_id[idcount] ) )
00346 {
00347 dptr = PLUTO_find_dset( &g_id[idcount] );
00348 if ( ! ISVALID_DSET( dptr ) )
00349 {
00350 dptr = NULL;
00351 ZERO_IDCODE( g_id[idcount] );
00352 }
00353 else
00354 num_valid++;
00355 }
00356 else
00357 dptr = NULL;
00358
00359 dset[idcount] = dptr;
00360 }
00361
00362 RETURN( num_valid );
00363 }