/*****************************************************************************
Major portions of this software are copyrighted by the Medical College
of Wisconsin, 1994-2000, and are released under the Gnu General Public
License, Version 2. See the file README.Copyright for details.
******************************************************************************/
#include "afni.h"
#ifndef ALLOW_PLUGINS
# error "Plugins not properly set up -- see machdep.h"
#endif
/***********************************************************************
Plugin to compute voxelwise mean, slope, or sigma of a 3D+time dataset.
************************************************************************/
/*--------------------- string to 'help' the user --------------------*/
static char helpstring[] =
"Purpose: Compute mean, slope, or sigma of a 3D+time dataset.\n"
"Input items are:\n"
" 3d+time = 3D+time dataset to analyze\n"
" Method = Mean, Slope, or Sigma = type of analysis to do\n"
" Ignore = How many points to ignore at start\n"
"\n"
"Output: Prefix = Filename prefix for new dataset"
;
/*--------------------- strings for output format --------------------*/
static char * method_strings[] = { "Mean" , "Slope" , "Sigma" , "CVar" } ;
#define NUM_METHOD_STRINGS (sizeof(method_strings)/sizeof(char *))
#define METH_MEAN 0
#define METH_SLOPE 1
#define METH_SIGMA 2
#define METH_CVAR 3
/*----------------- prototypes for internal routines -----------------*/
char * STATS_main( PLUGIN_interface * ) ; /* the entry point */
void STATS_tsfunc( double tzero , double tdelta ,
int npts , float ts[] , double ts_mean , double ts_slope ,
void * ud , float * val ) ;
/*---------------------------- global data ---------------------------*/
static PLUGIN_interface * global_plint = NULL ;
/***********************************************************************
Set up the interface to the user:
1) Create a new interface using "PLUTO_new_interface";
2) For each line of inputs, create the line with "PLUTO_add_option"
(this line of inputs can be optional or mandatory);
3) For each item on the line, create the item with
"PLUTO_add_dataset" for a dataset chooser,
"PLUTO_add_string" for a string chooser,
"PLUTO_add_number" for a number chooser.
************************************************************************/
DEFINE_PLUGIN_PROTOTYPE
PLUGIN_interface * PLUGIN_init( int ncall )
{
PLUGIN_interface * plint ; /* will be the output of this routine */
if( ncall > 0 ) return NULL ; /* only one interface */
/*---------------- set titles and call point ----------------*/
plint = PLUTO_new_interface( "3D+t Statistic" ,
"Voxel Statistics of 3D+time Dataset" ,
helpstring ,
PLUGIN_CALL_VIA_MENU , STATS_main ) ;
PLUTO_add_hint( plint , "Voxel Statistics of 3D+time Dataset" ) ;
PLUTO_set_sequence( plint , "A:newdset:statistics" ) ;
global_plint = plint ; /* make global copy */
/*--------- 1st line: Input dataset ---------*/
PLUTO_add_option( plint ,
"Input" , /* label at left of input line */
"Input" , /* tag to return to plugin */
TRUE /* is this mandatory? */
) ;
PLUTO_add_dataset( plint ,
"3D+time" , /* label next to button */
ANAT_ALL_MASK , /* take any anat datasets */
FUNC_FIM_MASK , /* only allow fim funcs */
DIMEN_4D_MASK | /* need 3D+time datasets */
BRICK_ALLREAL_MASK /* need real-valued datasets */
) ;
PLUTO_add_hint( plint , "Choose input dataset" ) ;
/*---------- 2nd line: other inputs ----------*/
PLUTO_add_option( plint ,
"Input" , /* label at left of input line */
"Input" , /* tag to return to plugin */
TRUE /* is this mandatory? */
) ;
PLUTO_add_hint( plint , "Control parameters" ) ;
PLUTO_add_string( plint ,
"Method" , /* label next to chooser button */
NUM_METHOD_STRINGS , /* number of strings to choose among */
method_strings , /* list of strings to choose among */
0 /* index of default string */
) ;
PLUTO_add_hint( plint , "Choose statistic to compute" ) ;
PLUTO_add_number( plint ,
"Ignore" , /* label next to chooser */
0 , /* smallest possible value */
20 , /* largest possible value */
0 , /* decimal shift (none in this case) */
3 , /* default value */
FALSE /* allow user to edit value? */
) ;
PLUTO_add_hint( plint , "Number of points to ignore at start of time series" ) ;
/*---------- 3rd line: Output dataset ----------*/
PLUTO_add_option( plint ,
"Output" , /* label at left of input line */
"Output" , /* tag to return to plugin */
TRUE /* is this mandatory? */
) ;
PLUTO_add_string( plint ,
"Prefix" , /* label next to textfield */
0,NULL , /* no fixed strings to choose among */
19 /* 19 spaces for typing in value */
) ;
PLUTO_add_hint( plint , "Name of output dataset" ) ;
/*--------- done with interface setup ---------*/
return plint ;
}
/***************************************************************************
Main routine for this plugin (will be called from AFNI).
If the return string is not NULL, some error transpired, and
AFNI will popup the return string in a message box.
****************************************************************************/
char * STATS_main( PLUGIN_interface * plint )
{
MCW_idcode * idc ; /* input dataset idcode */
THD_3dim_dataset * old_dset , * new_dset ; /* input and output datasets */
char * new_prefix , * str ; /* strings from user */
int meth , ignore ;
/*--------------------------------------------------------------------*/
/*----- 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 */
if( old_dset == NULL )
return "*************************\n"
"Cannot find Input Dataset\n"
"*************************" ;
/*--------- go to next input line ---------*/
PLUTO_next_option(plint) ;
str = PLUTO_get_string(plint) ; /* get string item (the method) */
meth = PLUTO_string_index( str , /* find it in list it is from */
NUM_METHOD_STRINGS ,
method_strings ) ;
ignore = PLUTO_get_number(plint) ; /* get number item */
/*--------- go to next input line ---------*/
PLUTO_next_option(plint) ;
new_prefix = PLUTO_get_string(plint) ; /* get string item (the output prefix) */
if( ! PLUTO_prefix_ok(new_prefix) ) /* check if it is OK */
return "************************\n"
"Output Prefix is illegal\n"
"************************" ;
/*------------- ready to compute new dataset -----------*/
new_dset = PLUTO_4D_to_fim( old_dset , /* input dataset */
new_prefix , /* output prefix */
ignore , /* ignore count */
1 , /* detrend = ON */
STATS_tsfunc , /* timeseries processor */
(void *) meth /* data for tsfunc */
) ;
PLUTO_add_dset( plint , new_dset , DSET_ACTION_MAKE_CURRENT ) ;
return NULL ; /* null string returned means all was OK */
}
/**********************************************************************
Function that does the real work
***********************************************************************/
void STATS_tsfunc( double tzero , double tdelta ,
int npts , float ts[] , double ts_mean , double ts_slope ,
void * ud , float * val )
{
int meth = (int) ud ;
static int nvox , ncall ;
/** is this a "notification"? **/
if( val == NULL ){
if( npts > 0 ){ /* the "start notification" */
PLUTO_popup_meter( global_plint ) ; /* progress meter */
nvox = npts ; /* keep track of */
ncall = 0 ; /* number of calls */
} else { /* the "end notification" */
PLUTO_set_meter( global_plint , 100 ) ; /* set meter to 100% */
}
return ;
}
/** OK, actually do some work **/
switch( meth ){
default:
case METH_MEAN: *val = ts_mean ; break ;
case METH_SLOPE: *val = ts_slope ; break ;
case METH_CVAR:
case METH_SIGMA:{
register int ii ;
register double sum ;
sum = 0.0 ;
for( ii=0 ; ii < npts ; ii++ ) sum += ts[ii] * ts[ii] ;
sum = sqrt( sum/(npts-1) ) ;
if( meth == METH_SIGMA ) *val = sum ;
else if( ts_mean != 0.0 ) *val = sum / fabs(ts_mean) ;
else *val = 0.0 ;
}
}
/** set the progress meter to the % of completion **/
ncall++ ;
PLUTO_set_meter( global_plint , (100*ncall)/nvox ) ;
return ;
}
syntax highlighted by Code2HTML, v. 0.9.1