#include "afni.h"
#ifndef ALLOW_PLUGINS
# error "Plugins not properly set up -- see machdep.h"
#endif
/***********************************************************************
Plugin to plot averages over ROIs.
************************************************************************/
static int tsgraph_num=0 ;
static MEM_topshell_data *tsgraph_mtd=NULL ;
static void ROIPLOT_tsgraph_draw (void) ;
static void ROIPLOT_tsgraph_mtdkill( MEM_topshell_data * mp ) ;
static char * ROIPLOT_main( PLUGIN_interface * ) ;
static char helpstring[] =
" Purpose: Plot averages over ROIs.\n"
"\n"
" INPUTS\n"
" ------\n"
" Source: Defines where the data to be averaged over the ROIs comes from.\n"
" Dataset = Where to get time series values from\n"
" Start = 1st sub-brick index to extract\n"
" Stop = Last sub-brick index to extract\n"
"\n"
" Two methods are available to define the ROIs from which dataset values\n"
" will be extracted. Only one of these can be used at a time:\n"
"\n"
" Cluster: Clusters of contiguous voxels are extracted (as in 3dclust),\n"
" -------- and these are used for the ROIs.\n"
" From = Dataset to define the clusters in\n"
" Index = Sub-brick index to define the clusters in\n"
" Thresh = Minimum value to accept in the sub-brick\n"
" rmm }= Clustering radius and\n"
" vmul }= minimum cluster volume\n"
"\n"
" Values: ROIs are defined by common values stored in a dataset, as\n"
" ------- might be generated by the 'Draw Dataset' plugin.\n"
" From = Dataset to define the ROIs\n"
" Index = Sub-brick index to define the ROIs\n"
" Min }= Range of values to\n"
" Max }= use for the ROIS\n"
" *** N.B.: Values selection is NOT YET IMPLEMENTED ***\n"
"\n"
" Author -- RW Cox - April 2002"
;
/***********************************************************************
Set up the interface to the user
************************************************************************/
DEFINE_PLUGIN_PROTOTYPE
PLUGIN_interface * PLUGIN_init( int ncall )
{
PLUGIN_interface * plint ;
if( ncall > 0 ) return NULL ; /* only one interface */
/*-- set titles and call point --*/
plint = PLUTO_new_interface( "ROI Plot" , "Plot Average Timeseries over ROI" ,
helpstring ,
PLUGIN_CALL_VIA_MENU , ROIPLOT_main ) ;
PLUTO_short_choose(plint) ;
PLUTO_short_number(plint) ;
PLUTO_add_hint( plint , "Plot Average Timeseries over ROI" ) ;
PLUTO_set_sequence( plint , "A:afniinfo:dset" ) ;
PLUTO_set_runlabels( plint , "Plot+Keep" , "Plot+Close" ) ; /* 04 Nov 2003 */
/*-- first line of input --*/
PLUTO_add_option( plint , "Source" , "Source" , TRUE ) ;
PLUTO_add_dataset(plint , "Timeseries" ,
ANAT_ALL_MASK , FUNC_ALL_MASK ,
DIMEN_4D_MASK | BRICK_ALLREAL_MASK ) ;
PLUTO_add_number( plint , "Start" , 0,99999,0 , 0 ,1 ) ;
PLUTO_add_number( plint , "Stop" , 0,99999,0 , 99999,1 ) ;
/*-- second line of input --*/
PLUTO_add_option( plint , "Cluster" , "Cluster" , FALSE ) ;
PLUTO_add_dataset( plint , "From" ,
ANAT_ALL_MASK , FUNC_ALL_MASK ,
DIMEN_ALL_MASK | BRICK_ALLREAL_MASK ) ;
PLUTO_add_number( plint , "Index" , 0,99999,0 , 0,1 ) ;
PLUTO_add_number( plint , "Thresh", 0,9999 ,1 , 1,1 ) ;
PLUTO_add_number( plint , "rmm" , 0,99 ,1 , 11,1 ) ;
PLUTO_add_number( plint , "vmul" , 0,9999,-1 , 20,1 ) ;
/*-- third line of input --*/
PLUTO_add_option( plint , "Values" , "Values" , FALSE ) ;
PLUTO_add_dataset( plint , "From" ,
ANAT_ALL_MASK , FUNC_ALL_MASK ,
DIMEN_ALL_MASK | BRICK_ALLREAL_MASK ) ;
PLUTO_add_number( plint , "Index" , 0,99999,0 , 0,1 ) ;
PLUTO_add_number( plint , "Min" , 0,99999,0 , 0 ,1 ) ;
PLUTO_add_number( plint , "Max" , 0,99999,0 , 99999,1 ) ;
return plint ;
}
/***************************************************************************
Main routine for this plugin (will be called from AFNI).
****************************************************************************/
static char * ROIPLOT_main( PLUGIN_interface * plint )
{
MCW_idcode *idc ;
THD_3dim_dataset *input_dset , *mask_dset ;
int iv_start,iv_stop , nvox , iv_mask ;
float thr,rmm,vmul , dx,dy,dz ;
int val_min , val_max , nx,ny,nz , ii,jj , nt,nc ;
char *tag ;
MCW_cluster_array *clustar ;
MRI_IMAGE *flim ;
float *flar , **yar , *xar , xcm,ycm,zcm ;
char **nam_yyy ;
MEM_plotdata * mp ;
#define MAX_NC 7
/*--------------------------------------------------------------------*/
/*----- Check inputs from AFNI to see if they are reasonable-ish -----*/
if( plint == NULL )
return "*************************\n"
"ROIPLOT_main: NULL input\n"
"*************************" ;
/*-- read 1st line --*/
PLUTO_next_option(plint) ;
idc = PLUTO_get_idcode(plint) ;
input_dset = PLUTO_find_dset(idc) ;
if( input_dset == NULL )
return "*********************************\n"
"ROIPLOT_main: bad Source dataset\n"
"*********************************" ;
iv_start = (int) PLUTO_get_number(plint) ;
iv_stop = (int) PLUTO_get_number(plint) ;
if( iv_stop >= DSET_NVALS(input_dset) ) iv_stop = DSET_NVALS(input_dset)-1 ;
if( iv_start >= iv_stop )
return "***********************************\n"
"ROIPLOT_main: bad Start/Stop range\n"
"***********************************" ;
DSET_load(input_dset) ;
if( DSET_ARRAY(input_dset,iv_stop) == NULL )
return "****************************************\n"
"ROIPLOT_main: can't load Source dataset\n"
"****************************************" ;
nx = input_dset->daxes->nxx ; dx = fabs(input_dset->daxes->xxdel) ;
ny = input_dset->daxes->nyy ; dy = fabs(input_dset->daxes->yydel) ;
nz = input_dset->daxes->nzz ; dz = fabs(input_dset->daxes->zzdel) ;
nvox = nx*ny*nz ;
/*-- read next lines --*/
tag = PLUTO_get_optiontag(plint) ;
if( tag == NULL )
return "***********************************"
"ROIPLOT_main: no ROI selection made\n"
"***********************************" ;
/*--------------------------------------*/
if( strcmp(tag,"Cluster") == 0 ){
float *vfim ;
MCW_cluster_array *clbig ;
MCW_cluster *cl ;
int ptmin ;
idc = PLUTO_get_idcode(plint) ;
mask_dset = PLUTO_find_dset(idc) ;
if( mask_dset == NULL )
return "**********************************\n"
"ROIPLOT_main: bad Cluster dataset\n"
"**********************************" ;
if( DSET_NVOX(mask_dset) != nvox )
return "******************************************************\n"
"ROIPLOT_main: Source and Cluster datasets don't match\n"
"******************************************************" ;
iv_mask = (int) PLUTO_get_number(plint) ;
if( iv_mask >= DSET_NVALS(mask_dset) )
return "********************************\n"
"ROIPLOT_main: bad Cluster index\n"
"*********************************" ;
DSET_load(mask_dset) ;
if( DSET_ARRAY(mask_dset,iv_mask) == NULL )
return "*****************************************\n"
"ROIPLOT_main: can't load Cluster dataset\n"
"*****************************************\n" ;
thr = PLUTO_get_number(plint) ;
rmm = PLUTO_get_number(plint) ;
vmul = PLUTO_get_number(plint) ;
vfim = (float *) malloc(sizeof(float)*nx*ny*nz) ;
EDIT_coerce_scale_type( nvox ,
DSET_BRICK_FACTOR(mask_dset,iv_mask) ,
DSET_BRICK_TYPE(mask_dset,iv_mask) ,
DSET_ARRAY(mask_dset,iv_mask) ,
MRI_float , vfim ) ;
if( thr > 0.0 ){
for( ii=0 ; ii < nvox ; ii++ )
if( fabs(vfim[ii]) < thr ) vfim[ii] = 0.0 ;
}
clustar = MCW_find_clusters( nx,ny,nz , dx,dy,dz ,
MRI_float , vfim , rmm ) ;
free(vfim) ;
if( clustar == NULL )
return "********************************\n"
"ROIPLOT_main: no Clusters found\n"
"********************************\n" ;
/* edit for volume */
ptmin = (int) (vmul / (dx*dy*dz) + 0.99) ;
INIT_CLARR(clbig) ;
for( ii=0 ; ii < clustar->num_clu ; ii++ ){
cl = clustar->clar[ii] ;
if( cl != NULL && cl->num_pt >= ptmin ){ /* big enough */
ADDTO_CLARR(clbig,cl) ; /* copy pointer */
clustar->clar[ii] = NULL ; /* null out original */
}
}
DESTROY_CLARR(clustar) ;
clustar = clbig ;
if( clustar == NULL || clustar->num_clu == 0 ){
printf("** NO CLUSTERS FOUND ***\n") ;
if( clustar != NULL ) DESTROY_CLARR(clustar) ;
return "********************************\n"
"ROIPLOT_main: no Clusters found\n"
"********************************\n" ;
}
SORT_CLARR(clustar) ;
/*--------------------------------------*/
} else if( strcmp(tag,"Values") == 0 ){
idc = PLUTO_get_idcode(plint) ;
mask_dset = PLUTO_find_dset(idc) ;
if( mask_dset == NULL )
return "*********************************\n"
"ROIPLOT_main: bad Values dataset\n"
"*********************************" ;
if( DSET_NVOX(mask_dset) != nvox )
return "*****************************************************\n"
"ROIPLOT_main: Source and Values datasets don't match\n"
"*****************************************************" ;
iv_mask = (int) PLUTO_get_number(plint) ;
if( iv_mask >= DSET_NVALS(mask_dset) )
return "*******************************\n"
"ROIPLOT_main: bad Values index\n"
"********************************" ;
DSET_load(mask_dset) ;
if( DSET_ARRAY(mask_dset,iv_mask) == NULL )
return "****************************************\n"
"ROIPLOT_main: can't load Values dataset\n"
"****************************************\n" ;
val_min = (int) PLUTO_get_number(plint) ;
val_max = (int) PLUTO_get_number(plint) ;
if( val_max < val_min ) val_max = val_min ;
/* must build cluster here */
return "****************************************\n"
"ROIPLOT_main: Values NOT IMPLEMENT YET!\n"
"****************************************\n" ;
} else {
return "*******************************\n"
"ROIPLOT_main: no ROI selection?\n"
"********************************" ;
}
/* check for too many options */
tag = PLUTO_get_optiontag(plint) ;
if( tag != NULL )
PLUTO_popup_transient(plint,"\n"
"+++++++ WARNING ++++++++\n"
" Using Cluster option;\n"
" Ignoring Values option\n" ) ;
/* extract average time series */
flim = THD_average_timeseries( clustar , input_dset ) ;
if( flim == NULL ){
DESTROY_CLARR(clustar) ;
return "***********************************************\n"
"ROIPLOT_main: Can't extract average timeseries\n"
"***********************************************\n" ;
}
nc = flim->ny ; if( nc > MAX_NC ) nc = MAX_NC ;
nt = flim->nx ;
flar = MRI_FLOAT_PTR(flim) ;
yar = (float **) malloc(sizeof(float *)*nc) ;
for( ii=0 ; ii < nc ; ii++ ) yar[ii] = flar + (ii*nt+iv_start) ;
xar = (float *) malloc(sizeof(float)*nt) ;
for( ii=0 ; ii < nt ; ii++ ) xar[ii] = ii ;
nam_yyy = (char **) malloc(sizeof(char *)*nc) ;
for( ii=0 ; ii < nc ; ii++ ){
xcm = ycm = zcm = 0.0 ;
for( jj=0 ; jj < clustar->clar[ii]->num_pt ; jj++ ){
xcm += clustar->clar[ii]->i[ii] ;
ycm += clustar->clar[ii]->j[ii] ;
zcm += clustar->clar[ii]->k[ii] ;
}
xcm /= clustar->clar[ii]->num_pt ;
ycm /= clustar->clar[ii]->num_pt ;
zcm /= clustar->clar[ii]->num_pt ;
nam_yyy[ii] = malloc(256) ;
sprintf(nam_yyy[ii],"%d voxels\n"
"_{ijk: %d %d %d}" ,
clustar->clar[ii]->num_pt ,
(int)(xcm+0.499) , (int)(ycm+0.499) , (int)(zcm+0.499) ) ;
}
DESTROY_CLARR(clustar);
mp = plot_ts_mem( iv_stop-iv_start+1 , xar+iv_start ,
nc,TSP_SEPARATE_YBOX,yar ,
NULL,NULL,NULL,nam_yyy ) ;
for( ii=0 ; ii < nc ; ii++ ) free(nam_yyy[ii]) ;
free(nam_yyy);
free(xar); free(yar); mri_free(flim);
if( mp == NULL )
return "******************************************\n"
"ROIPLOT_main: Can't create in-memory plot\n"
"******************************************\n" ;
memplot_to_topshell( plint->im3d->dc->display , mp , NULL ) ;
return NULL ;
}
/*------------------------------------------------------------------*/
/*------------------------------------------------------------------*/
syntax highlighted by Code2HTML, v. 0.9.1