1 #include "afni.h"
2
3 #ifndef ALLOW_PLUGINS
4 # error "Plugins not properly set up -- see machdep.h"
5 #endif
6
7 /***********************************************************************
8 Plugin to plot averages over ROIs.
9 ************************************************************************/
10
11 static int tsgraph_num=0 ;
12 static MEM_topshell_data *tsgraph_mtd=NULL ;
13
14 static void ROIPLOT_tsgraph_draw (void) ;
15 static void ROIPLOT_tsgraph_mtdkill( MEM_topshell_data * mp ) ;
16
17 static char * ROIPLOT_main( PLUGIN_interface * ) ;
18
19 static char helpstring[] =
20 " Purpose: Plot averages over ROIs.\n"
21 "\n"
22 " INPUTS\n"
23 " ------\n"
24 " Source: Defines where the data to be averaged over the ROIs comes from.\n"
25 " Dataset = Where to get time series values from\n"
26 " Start = 1st sub-brick index to extract\n"
27 " Stop = Last sub-brick index to extract\n"
28 "\n"
29 " Two methods are available to define the ROIs from which dataset values\n"
30 " will be extracted. Only one of these can be used at a time:\n"
31 "\n"
32 " Cluster: Clusters of contiguous voxels are extracted (as in 3dclust),\n"
33 " -------- and these are used for the ROIs.\n"
34 " From = Dataset to define the clusters in\n"
35 " Index = Sub-brick index to define the clusters in\n"
36 " Thresh = Minimum value to accept in the sub-brick\n"
37 " rmm }= Clustering radius and\n"
38 " vmul }= minimum cluster volume\n"
39 "\n"
40 " Values: ROIs are defined by common values stored in a dataset, as\n"
41 " ------- might be generated by the 'Draw Dataset' plugin.\n"
42 " From = Dataset to define the ROIs\n"
43 " Index = Sub-brick index to define the ROIs\n"
44 " Min }= Range of values to\n"
45 " Max }= use for the ROIS\n"
46 " *** N.B.: Values selection is NOT YET IMPLEMENTED ***\n"
47 "\n"
48 " Author -- RW Cox - April 2002"
49 ;
50
51 /***********************************************************************
52 Set up the interface to the user
53 ************************************************************************/
54
55
56 DEFINE_PLUGIN_PROTOTYPE
57
PLUGIN_init(int ncall)58 PLUGIN_interface * PLUGIN_init( int ncall )
59 {
60 PLUGIN_interface * plint ;
61
62 if( ncall > 0 ) return NULL ; /* only one interface */
63
64 CHECK_IF_ALLOWED("ROIPLOT","ROI Plot") ; /* 30 Sep 2016 */
65
66 /*-- set titles and call point --*/
67
68 plint = PLUTO_new_interface( "ROI Plot" , "Plot Average Timeseries over ROI" ,
69 helpstring ,
70 PLUGIN_CALL_VIA_MENU , ROIPLOT_main ) ;
71
72 PLUTO_short_choose(plint) ;
73 PLUTO_short_number(plint) ;
74
75 PLUTO_add_hint( plint , "Plot Average Timeseries over ROI" ) ;
76
77 PLUTO_set_sequence( plint , "A:afniinfo:dset" ) ;
78
79 PLUTO_set_runlabels( plint , "Plot+Keep" , "Plot+Close" ) ; /* 04 Nov 2003 */
80
81 /*-- first line of input --*/
82
83 PLUTO_add_option( plint , "Source" , "Source" , TRUE ) ;
84 PLUTO_add_dataset(plint , "Timeseries" ,
85 ANAT_ALL_MASK , FUNC_ALL_MASK ,
86 DIMEN_4D_MASK | BRICK_ALLREAL_MASK ) ;
87
88 PLUTO_add_number( plint , "Start" , 0,99999,0 , 0 ,1 ) ;
89 PLUTO_add_number( plint , "Stop" , 0,99999,0 , 99999,1 ) ;
90
91 /*-- second line of input --*/
92
93 PLUTO_add_option( plint , "Cluster" , "Cluster" , FALSE ) ;
94 PLUTO_add_dataset( plint , "From" ,
95 ANAT_ALL_MASK , FUNC_ALL_MASK ,
96 DIMEN_ALL_MASK | BRICK_ALLREAL_MASK ) ;
97 PLUTO_add_number( plint , "Index" , 0,99999,0 , 0,1 ) ;
98 PLUTO_add_number( plint , "Thresh", 0,9999 ,1 , 1,1 ) ;
99 PLUTO_add_number( plint , "rmm" , 0,99 ,1 , 11,1 ) ;
100 PLUTO_add_number( plint , "vmul" , 0,9999,-1 , 20,1 ) ;
101
102 /*-- third line of input --*/
103
104 PLUTO_add_option( plint , "Values" , "Values" , FALSE ) ;
105 PLUTO_add_dataset( plint , "From" ,
106 ANAT_ALL_MASK , FUNC_ALL_MASK ,
107 DIMEN_ALL_MASK | BRICK_ALLREAL_MASK ) ;
108 PLUTO_add_number( plint , "Index" , 0,99999,0 , 0,1 ) ;
109 PLUTO_add_number( plint , "Min" , 0,99999,0 , 0 ,1 ) ;
110 PLUTO_add_number( plint , "Max" , 0,99999,0 , 99999,1 ) ;
111
112 return plint ;
113 }
114
115 /***************************************************************************
116 Main routine for this plugin (will be called from AFNI).
117 ****************************************************************************/
118
ROIPLOT_main(PLUGIN_interface * plint)119 static char * ROIPLOT_main( PLUGIN_interface * plint )
120 {
121 MCW_idcode *idc ;
122 THD_3dim_dataset *input_dset , *mask_dset ;
123 int iv_start,iv_stop , nvox , iv_mask ;
124 float thr,rmm,vmul , dx,dy,dz ;
125 int val_min , val_max , nx,ny,nz , ii,jj , nt,nc ;
126 char *tag ;
127 MCW_cluster_array *clustar ;
128 MRI_IMAGE *flim ;
129 float *flar , **yar , *xar , xcm,ycm,zcm ;
130 char **nam_yyy ;
131 MEM_plotdata * mp ;
132
133 #define MAX_NC 7
134
135 /*--------------------------------------------------------------------*/
136 /*----- Check inputs from AFNI to see if they are reasonable-ish -----*/
137
138 if( plint == NULL )
139 return "*************************\n"
140 "ROIPLOT_main: NULL input\n"
141 "*************************" ;
142
143 /*-- read 1st line --*/
144
145 PLUTO_next_option(plint) ;
146 idc = PLUTO_get_idcode(plint) ;
147 input_dset = PLUTO_find_dset(idc) ;
148 if( input_dset == NULL )
149 return "*********************************\n"
150 "ROIPLOT_main: bad Source dataset\n"
151 "*********************************" ;
152
153 iv_start = (int) PLUTO_get_number(plint) ;
154 iv_stop = (int) PLUTO_get_number(plint) ;
155 if( iv_stop >= DSET_NVALS(input_dset) ) iv_stop = DSET_NVALS(input_dset)-1 ;
156 if( iv_start >= iv_stop )
157 return "***********************************\n"
158 "ROIPLOT_main: bad Start/Stop range\n"
159 "***********************************" ;
160 DSET_load(input_dset) ;
161 if( DSET_ARRAY(input_dset,iv_stop) == NULL )
162 return "****************************************\n"
163 "ROIPLOT_main: can't load Source dataset\n"
164 "****************************************" ;
165
166 nx = input_dset->daxes->nxx ; dx = fabs(input_dset->daxes->xxdel) ;
167 ny = input_dset->daxes->nyy ; dy = fabs(input_dset->daxes->yydel) ;
168 nz = input_dset->daxes->nzz ; dz = fabs(input_dset->daxes->zzdel) ;
169 nvox = nx*ny*nz ;
170
171 /*-- read next lines --*/
172
173 tag = PLUTO_get_optiontag(plint) ;
174 if( tag == NULL )
175 return "***********************************"
176 "ROIPLOT_main: no ROI selection made\n"
177 "***********************************" ;
178
179 /*--------------------------------------*/
180
181 if( strcmp(tag,"Cluster") == 0 ){
182 float *vfim ;
183 MCW_cluster_array *clbig ;
184 MCW_cluster *cl ;
185 int ptmin ;
186
187 idc = PLUTO_get_idcode(plint) ;
188 mask_dset = PLUTO_find_dset(idc) ;
189 if( mask_dset == NULL )
190 return "**********************************\n"
191 "ROIPLOT_main: bad Cluster dataset\n"
192 "**********************************" ;
193 if( DSET_NVOX(mask_dset) != nvox )
194 return "******************************************************\n"
195 "ROIPLOT_main: Source and Cluster datasets don't match\n"
196 "******************************************************" ;
197 iv_mask = (int) PLUTO_get_number(plint) ;
198 if( iv_mask >= DSET_NVALS(mask_dset) )
199 return "********************************\n"
200 "ROIPLOT_main: bad Cluster index\n"
201 "*********************************" ;
202 DSET_load(mask_dset) ;
203 if( DSET_ARRAY(mask_dset,iv_mask) == NULL )
204 return "*****************************************\n"
205 "ROIPLOT_main: can't load Cluster dataset\n"
206 "*****************************************\n" ;
207
208 thr = PLUTO_get_number(plint) ;
209 rmm = PLUTO_get_number(plint) ;
210 vmul = PLUTO_get_number(plint) ;
211
212 vfim = (float *) malloc(sizeof(float)*nx*ny*nz) ;
213 EDIT_coerce_scale_type( nvox ,
214 DSET_BRICK_FACTOR(mask_dset,iv_mask) ,
215 DSET_BRICK_TYPE(mask_dset,iv_mask) ,
216 DSET_ARRAY(mask_dset,iv_mask) ,
217 MRI_float , vfim ) ;
218 if( thr > 0.0 ){
219 for( ii=0 ; ii < nvox ; ii++ )
220 if( fabs(vfim[ii]) < thr ) vfim[ii] = 0.0 ;
221 }
222
223 clustar = MCW_find_clusters( nx,ny,nz , dx,dy,dz ,
224 MRI_float , vfim , rmm ) ;
225 free(vfim) ;
226
227 if( clustar == NULL )
228 return "********************************\n"
229 "ROIPLOT_main: no Clusters found\n"
230 "********************************\n" ;
231
232 /* edit for volume */
233
234 ptmin = (int) (vmul / (dx*dy*dz) + 0.99) ;
235 INIT_CLARR(clbig) ;
236 for( ii=0 ; ii < clustar->num_clu ; ii++ ){
237 cl = clustar->clar[ii] ;
238 if( cl != NULL && cl->num_pt >= ptmin ){ /* big enough */
239 ADDTO_CLARR(clbig,cl) ; /* copy pointer */
240 clustar->clar[ii] = NULL ; /* null out original */
241 }
242 }
243 DESTROY_CLARR(clustar) ;
244 clustar = clbig ;
245 if( clustar == NULL || clustar->num_clu == 0 ){
246 printf("** NO CLUSTERS FOUND ***\n") ;
247 if( clustar != NULL ) DESTROY_CLARR(clustar) ;
248 return "********************************\n"
249 "ROIPLOT_main: no Clusters found\n"
250 "********************************\n" ;
251 }
252 SORT_CLARR(clustar) ;
253
254 /*--------------------------------------*/
255
256 } else if( strcmp(tag,"Values") == 0 ){
257 idc = PLUTO_get_idcode(plint) ;
258 mask_dset = PLUTO_find_dset(idc) ;
259 if( mask_dset == NULL )
260 return "*********************************\n"
261 "ROIPLOT_main: bad Values dataset\n"
262 "*********************************" ;
263 if( DSET_NVOX(mask_dset) != nvox )
264 return "*****************************************************\n"
265 "ROIPLOT_main: Source and Values datasets don't match\n"
266 "*****************************************************" ;
267 iv_mask = (int) PLUTO_get_number(plint) ;
268 if( iv_mask >= DSET_NVALS(mask_dset) )
269 return "*******************************\n"
270 "ROIPLOT_main: bad Values index\n"
271 "********************************" ;
272 DSET_load(mask_dset) ;
273 if( DSET_ARRAY(mask_dset,iv_mask) == NULL )
274 return "****************************************\n"
275 "ROIPLOT_main: can't load Values dataset\n"
276 "****************************************\n" ;
277
278 val_min = (int) PLUTO_get_number(plint) ;
279 val_max = (int) PLUTO_get_number(plint) ;
280 if( val_max < val_min ) val_max = val_min ;
281
282 /* must build cluster here */
283
284 return "****************************************\n"
285 "ROIPLOT_main: Values NOT IMPLEMENT YET!\n"
286 "****************************************\n" ;
287
288 } else {
289 return "*******************************\n"
290 "ROIPLOT_main: no ROI selection?\n"
291 "********************************" ;
292 }
293
294 /* check for too many options */
295
296 tag = PLUTO_get_optiontag(plint) ;
297 if( tag != NULL )
298 PLUTO_popup_transient(plint,"\n"
299 "+++++++ WARNING ++++++++\n"
300 " Using Cluster option;\n"
301 " Ignoring Values option\n" ) ;
302
303 /* extract average time series */
304
305 flim = THD_average_timeseries( clustar , input_dset ) ;
306
307 if( flim == NULL ){
308 DESTROY_CLARR(clustar) ;
309 return "***********************************************\n"
310 "ROIPLOT_main: Can't extract average timeseries\n"
311 "***********************************************\n" ;
312 }
313
314 nc = flim->ny ; if( nc > MAX_NC ) nc = MAX_NC ;
315 nt = flim->nx ;
316 flar = MRI_FLOAT_PTR(flim) ;
317 yar = (float **) malloc(sizeof(float *)*nc) ;
318 for( ii=0 ; ii < nc ; ii++ ) yar[ii] = flar + (ii*nt+iv_start) ;
319 xar = (float *) malloc(sizeof(float)*nt) ;
320 for( ii=0 ; ii < nt ; ii++ ) xar[ii] = ii ;
321 nam_yyy = (char **) malloc(sizeof(char *)*nc) ;
322 for( ii=0 ; ii < nc ; ii++ ){
323 xcm = ycm = zcm = 0.0 ;
324 for( jj=0 ; jj < clustar->clar[ii]->num_pt ; jj++ ){
325 xcm += clustar->clar[ii]->i[ii] ;
326 ycm += clustar->clar[ii]->j[ii] ;
327 zcm += clustar->clar[ii]->k[ii] ;
328 }
329 xcm /= clustar->clar[ii]->num_pt ;
330 ycm /= clustar->clar[ii]->num_pt ;
331 zcm /= clustar->clar[ii]->num_pt ;
332 nam_yyy[ii] = malloc(256) ;
333 sprintf(nam_yyy[ii],"%d voxels\n"
334 "_{ijk: %d %d %d}" ,
335 clustar->clar[ii]->num_pt ,
336 (int)(xcm+0.499) , (int)(ycm+0.499) , (int)(zcm+0.499) ) ;
337 }
338 DESTROY_CLARR(clustar);
339
340 mp = plot_ts_mem( iv_stop-iv_start+1 , xar+iv_start ,
341 nc,TSP_SEPARATE_YBOX,yar ,
342 NULL,NULL,NULL,nam_yyy ) ;
343
344 for( ii=0 ; ii < nc ; ii++ ) free(nam_yyy[ii]) ;
345 free(nam_yyy);
346 free(xar); free(yar); mri_free(flim);
347
348 if( mp == NULL )
349 return "******************************************\n"
350 "ROIPLOT_main: Can't create in-memory plot\n"
351 "******************************************\n" ;
352
353 memplot_to_topshell( plint->im3d->dc->display , mp , NULL ) ;
354
355 return NULL ;
356 }
357
358 /*------------------------------------------------------------------*/
359
360 /*------------------------------------------------------------------*/
361