1 /*****************************************************************************
2 Major portions of this software are copyrighted by the Medical College
3 of Wisconsin, 1994-2000, and are released under the Gnu General Public
4 License, Version 2. See the file README.Copyright for details.
5 ******************************************************************************/
6
7 #undef MAIN
8
9 #include "afni.h"
10 #include "afni_plugout.h"
11 #include "mcw_malloc.h"
12 extern char **Atlas_Names_List(ATLAS_LIST *atl);
13
14 static THD_3dim_dataset *atlas_ovdset = NULL;
15
16 static float Thval[9] = { 1.0 , 10.0 , 100.0 , 1000.0 , 10000.0 ,
17 100000.0 , 1000000.0 , 10000000.0 , 100000000.0 } ;
18
19 static int reset_func_range_ncall[MAX_CONTROLLERS] ; /* initialized to 0 by C */
20
21 /*-------------------------------------------------------------------
22 This routine is also used by the macros
23 AFNI_SEE_FUNC_ON and AFNI_SEE_FUNC_OFF
24 as well as the MCW_bbox that it is attached to as the callback.
25 ---------------------------------------------------------------------*/
26
AFNI_see_func_CB(Widget w,XtPointer cd,XtPointer cb)27 void AFNI_see_func_CB( Widget w, XtPointer cd, XtPointer cb )
28 {
29 Three_D_View *im3d = (Three_D_View *) cd ;
30 int old_val , new_val ;
31
32 ENTRY("AFNI_see_func_CB") ;
33
34 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
35
36 im3d->vinfo->stats_anat_ok =
37 im3d->vinfo->stats_func_ok =
38 im3d->vinfo->arang_func_ok =
39 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
40
41 old_val = (im3d->vinfo->func_visible) ? 1 : 0 ;
42 new_val = MCW_val_bbox( im3d->vwid->view->see_func_bbox ) ;
43
44 if( old_val != new_val ){
45 #if 0
46 STATUS_IM3D_TMASK(im3d) ;
47 STATUS("clear tmask") ;
48 #endif
49 im3d->vinfo->func_visible = (new_val == 1) ? True : False ;
50 if( ! ISVALID_3DIM_DATASET(im3d->fim_now) ){ /* 29 Apr 1997 */
51 im3d->vinfo->func_visible = False ; new_val = 0 ;
52 MCW_set_bbox( im3d->vwid->view->see_func_bbox , 0 ) ; /* 29 Jan 1999 */
53 }
54 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
55 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
56 OVERLAY_SUMA ; /* 16 Jun 2003 */
57 AFNI_redisplay_func( im3d ) ; /* 05 Mar 2002 */
58 im3d->vinfo->func_visible_count++ ; /* 03 Aug 2007 */
59 if( new_val == 0 ){ /* 21 Jul 2014 */
60 XtSetSensitive(im3d->vwid->func->pbar_jumpto_thmax_pb,False) ;
61 XtSetSensitive(im3d->vwid->func->pbar_jumpto_thmin_pb,False) ;
62 } else {
63 AFNI_setup_thrstat(im3d,1) ; /* 27 Jun 2019 */
64 }
65 }
66
67 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
68 RESET_AFNI_QUIT(im3d) ;
69 EXRETURN ;
70 }
71
72 /*---------------------------------------------------------------------------*/
73 /* Callback for "A" and "B" buttons on top of threshold slider [02 Nov 2018] */
74 /*---------------------------------------------------------------------------*/
75
AFNI_func_thrtop_CB(Widget w,XtPointer cd,XtPointer cb)76 void AFNI_func_thrtop_CB( Widget w, XtPointer cd, XtPointer cb )
77 {
78 Three_D_View *im3d = (Three_D_View *) cd ;
79
80 ENTRY("AFNI_thrtop_CB") ;
81 if( !IM3D_OPEN(im3d) ) EXRETURN ;
82
83 if( w == im3d->vwid->func->thrtop_alpha_pb ){
84
85 MCW_invert_widget(w) ;
86 im3d->vinfo->thr_use_alpha = !im3d->vinfo->thr_use_alpha ;
87 PBAR_force_bigexpose(im3d->vwid->func->inten_pbar) ;
88
89 } else if( w == im3d->vwid->func->thrtop_boxed_pb ){
90
91 MCW_invert_widget(w) ;
92 im3d->vinfo->thr_use_boxed = !im3d->vinfo->thr_use_boxed ;
93
94 }
95
96 IM3D_CLEAR_TMASK(im3d) ;
97 IM3D_CLEAR_THRSTAT(im3d) ;
98 AFNI_setup_thrstat(im3d,0) ;
99 AFNI_redisplay_func(im3d) ;
100 AFNI_set_window_titles(im3d) ;
101 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
102
103 EXRETURN ;
104 }
105
106 /*-----------------------------------------------------------------------*/
107 /*! Get the threshold automatically. [05 Mar 2007]
108 -------------------------------------------------------------------------*/
109
AFNI_get_autothresh(Three_D_View * im3d)110 float AFNI_get_autothresh( Three_D_View *im3d )
111 {
112 MRI_IMAGE *thrim ;
113 float thrval,pval=0.0f ; int ival ;
114
115 ENTRY("AFNI_get_autothresh") ;
116
117 if( !IM3D_OPEN(im3d) || !ISVALID_DSET(im3d->fim_now) ) RETURN(-1.0f) ;
118
119 ival = im3d->vinfo->thr_index ; /* threshold sub-brick index */
120
121 if( DSET_BRICK_STATCODE(im3d->fim_now,ival) > 0 )
122 pval = THD_pval_to_stat( 1.e-3 ,
123 DSET_BRICK_STATCODE(im3d->fim_now,ival) ,
124 DSET_BRICK_STATAUX (im3d->fim_now,ival) ) ;
125
126 DSET_load( im3d->fim_now ) ;
127 thrim = DSET_BRICK(im3d->fim_now,ival) ;
128 thrval = THD_cliplevel_abs( thrim , -0.500f ) ;
129 if( DSET_BRICK_FACTOR(im3d->fim_now,ival) > 0.0f )
130 thrval *= DSET_BRICK_FACTOR(im3d->fim_now,ival) ;
131
132 if( pval > 0.0f )
133 thrval = (thrval <= 0.0f) ? pval : sqrt(thrval*pval) ;
134
135 if( thrval == 0.0f ) thrval = -1.0f ;
136 RETURN(thrval) ;
137 }
138
139 /*-----------------------------------------------------------------------*/
140 /*! 25 Jul 2007 */
141
AFNI_func_autothresh_CB(Widget w,XtPointer cd,XtPointer cb)142 void AFNI_func_autothresh_CB( Widget w, XtPointer cd, XtPointer cb )
143 {
144 Three_D_View *im3d = (Three_D_View *)cd ;
145 float new_thresh ;
146
147 ENTRY("AFNI_func_autothresh_CB") ;
148
149 if( !IM3D_OPEN(im3d) ) EXRETURN ;
150
151 #if 0
152 STATUS_IM3D_TMASK(im3d) ;
153 STATUS("clear tmask") ;
154 #endif
155 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
156 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
157 new_thresh = AFNI_get_autothresh(im3d) ;
158 if( new_thresh > 0.0f ) AFNI_set_threshold(im3d,new_thresh) ;
159 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
160 EXRETURN ;
161 }
162
163 /*-----------------------------------------------------------------------*/
164 /*! 03 Dec 2013 */
165
166 #define TFLASH(iq) \
167 do{ MCW_flash_widget(2,(iq)->vwid->func->thr_scale); BEEPIT; } while(0)
168
AFNI_set_pval(Three_D_View * im3d,float pval)169 void AFNI_set_pval( Three_D_View *im3d , float pval )
170 {
171 float thresh ; int sig , scode ;
172
173 ENTRY("AFNI_set_pval") ;
174
175 if( !IM3D_OPEN(im3d) || pval <= 0.0f || pval >= 1.0f ) EXRETURN ;
176 if( DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) <= 0 ){
177 TFLASH(im3d) ; EXRETURN ;
178 }
179
180 scode = DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ;
181 sig = THD_stat_is_2sided( scode , 0 ) ;
182 if( sig > 0 && im3d->vinfo->thr_sign > 0 && scode != FUNC_FT_TYPE )
183 pval *= 2.0f ; /* Jan 2015 */
184
185 thresh = THD_pval_to_stat( pval ,
186 DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ,
187 DSET_BRICK_STATAUX (im3d->fim_now,im3d->vinfo->thr_index) ) ;
188 if( thresh < 0.0 ){ TFLASH(im3d); EXRETURN; }
189
190 AFNI_set_threshold(im3d,thresh) ;
191 EXRETURN ;
192 }
193
194 /*--- set threshold 16 Jul 2020 discoraj --------------------*/
195
AFNI_func_setthresh_final_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)196 void AFNI_func_setthresh_final_CB( Widget w, XtPointer cd, MCW_choose_cbs *cbs )
197 {
198 Three_D_View *im3d = (Three_D_View *)cd ;
199 float thresh ;
200 char *cpt ;
201 char contlab[2] , threshstr[32];
202 char drvmsg[256] = "SET_THRESHNEW ";
203
204 ENTRY("AFNI_func_setthresh_final_CB") ;
205
206 if( !IM3D_OPEN(im3d) ) EXRETURN ;
207
208 if( cbs->reason != mcwCR_string ||
209 cbs->cval == NULL ||
210 cbs->cval[0] == '\0' ){ TFLASH(im3d); EXRETURN; }
211
212 // get new threshold and no negatives to string
213 thresh = (float)strtod(cbs->cval,&cpt) ;
214 if( thresh < 0.0f ){ TFLASH(im3d); EXRETURN; }
215 sprintf(threshstr, "%f", thresh);
216
217 // fix the stat if dataset changes...
218 im3d->vinfo->fix_qval = 0 ;
219 im3d->vinfo->fixed_qval = 0.0f ;
220 im3d->vinfo->fix_pval = 0 ;
221 im3d->vinfo->fixed_pval = 0.0f ;
222
223 // get the controller label single letter only
224 memcpy( contlab, &AFNI_controller_label(im3d)[1], 1 );
225 contlab[1] = '\0';
226
227 // combine everything into 1 string
228 strcat(drvmsg,contlab) ; strcat(drvmsg," ") ; strcat(drvmsg,threshstr) ;
229
230 // drive to change the threshold
231 AFNI_driver(drvmsg);
232
233 // fix pbar size
234 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
235 EXRETURN ;
236 }
237
238 /*---------- set threshold 16 Jul 2020 discoraj ----------------------*/
239
AFNI_func_setthresh_CB(Widget w,XtPointer cd,XtPointer cb)240 void AFNI_func_setthresh_CB( Widget w, XtPointer cd, XtPointer cb )
241 {
242 Three_D_View *im3d = (Three_D_View *)cd ;
243
244 ENTRY("AFNI_func_setthresh_CB") ;
245
246 if( !IM3D_OPEN(im3d) ) EXRETURN ;
247
248 MCW_choose_string(w,"Enter threshold",NULL,AFNI_func_setthresh_final_CB,cd) ;
249 EXRETURN ;
250 }
251
252 /*-----------------------------------------------------------------------*/
253
AFNI_func_setpval_final_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)254 void AFNI_func_setpval_final_CB( Widget w, XtPointer cd, MCW_choose_cbs *cbs )
255 {
256 Three_D_View *im3d = (Three_D_View *)cd ;
257 float pval , thresh ;
258 int newdec , olddec , stop,smax , ival ;
259 char *cpt ;
260
261 ENTRY("AFNI_func_setpval_final_CB") ;
262
263 if( !IM3D_OPEN(im3d) ) EXRETURN ;
264
265 if( cbs->reason != mcwCR_string ||
266 cbs->cval == NULL ||
267 cbs->cval[0] == '\0' ){ TFLASH(im3d); EXRETURN; }
268
269 if( DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) <= 0 ){
270 TFLASH(im3d) ; EXRETURN ;
271 }
272
273 pval = (float)strtod(cbs->cval,&cpt) ;
274 if( pval > 0.0f && *cpt == '%' ) pval *= 0.01f ;
275 if( pval <= 0.0f || pval >= 1.0f ){ TFLASH(im3d); EXRETURN; }
276
277 im3d->vinfo->fix_qval = 0 ;
278 im3d->vinfo->fixed_qval = 0.0f ;
279
280 AFNI_set_pval(im3d,pval) ;
281 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
282 EXRETURN ;
283 }
284
285 /*-----------------------------------------------------------------------*/
286
AFNI_func_setpval_CB(Widget w,XtPointer cd,XtPointer cb)287 void AFNI_func_setpval_CB( Widget w, XtPointer cd, XtPointer cb )
288 {
289 Three_D_View *im3d = (Three_D_View *)cd ;
290
291 ENTRY("AFNI_func_setpval_CB") ;
292
293 if( !IM3D_OPEN(im3d) ) EXRETURN ;
294
295 MCW_choose_string( w, "Enter p-value", NULL, AFNI_func_setpval_final_CB,cd ) ;
296 EXRETURN ;
297 }
298
299 /*-----------------------------------------------------------------------*/
300
AFNI_func_setpval_001_CB(Widget w,XtPointer cd,XtPointer cb)301 void AFNI_func_setpval_001_CB( Widget w, XtPointer cd, XtPointer cb )
302 {
303 MCW_choose_cbs cbs ;
304
305 ENTRY("AFNI_func_setpval_001_CB") ;
306
307 cbs.reason = mcwCR_string ;
308 cbs.cval = "0.001" ;
309 AFNI_func_setpval_final_CB( w , cd , &cbs ) ;
310 EXRETURN ;
311 }
312
313 /*-----------------------------------------------------------------------*/
314 /*! 26 Feb 2014 */
315
AFNI_set_qval(Three_D_View * im3d,float qval)316 void AFNI_set_qval( Three_D_View *im3d , float qval )
317 {
318 float zval , thresh ;
319
320 ENTRY("AFNI_set_qval") ;
321
322 if( !IM3D_OPEN(im3d) || qval <= 0.0f || qval >= 1.0f ) EXRETURN ;
323 if( DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) <= 0 ){
324 TFLASH(im3d) ; EXRETURN ;
325 }
326
327 zval = qginv(0.5*qval) ;
328 thresh = THD_fdrcurve_zqtot( im3d->fim_now , im3d->vinfo->thr_index , zval ) ;
329 if( thresh <= 0.0 ){ TFLASH(im3d); EXRETURN; }
330
331 AFNI_set_threshold(im3d,thresh) ;
332 EXRETURN ;
333 }
334
335 /*-----------------------------------------------------------------------*/
336
337 static char *yesno[2] = { "No" , "Yes" } ;
338
AFNI_func_setqval_final_CB(Widget w,XtPointer cd,int nval,void ** val)339 void AFNI_func_setqval_final_CB( Widget w, XtPointer cd, int nval , void **val )
340 {
341 Three_D_View *im3d = (Three_D_View *)cd ;
342 float qval , zval , thresh ;
343 char *cpt ;
344
345 ENTRY("AFNI_func_setqval_final_CB") ;
346
347 if( !IM3D_OPEN(im3d) || nval != 2 || val == NULL ) EXRETURN ;
348
349 if( DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) <= 0 ){
350 TFLASH(im3d) ; EXRETURN ;
351 }
352
353 qval = (float)strtod((char *)val[0],&cpt) ;
354 if( qval > 0.0f && *cpt == '%' ) qval *= 0.01f ;
355 if( qval < 0.0f || qval >= 1.0f ){ TFLASH(im3d); EXRETURN; }
356
357 im3d->vinfo->fix_qval = ( qval > 0.0f && strcmp((char *)val[1],yesno[1]) == 0 ) ;
358 im3d->vinfo->fixed_qval = (im3d->vinfo->fix_qval) ? qval : 0.0f ;
359
360 im3d->vinfo->fix_pval = 0 ;
361 im3d->vinfo->fixed_pval = 0.0f ;
362
363 if( qval > 0.0f ) AFNI_set_qval(im3d,qval) ;
364 EXRETURN ;
365 }
366
367 /*-----------------------------------------------------------------------*/
368
AFNI_func_setqval_CB(Widget w,XtPointer cd,XtPointer cb)369 void AFNI_func_setqval_CB( Widget w, XtPointer cd, XtPointer cb )
370 {
371 Three_D_View *im3d = (Three_D_View *)cd ;
372 int ifix ;
373
374 ENTRY("AFNI_func_setqval_CB") ;
375
376 if( !IM3D_OPEN(im3d) ) EXRETURN ;
377
378 ifix = (im3d->vinfo->fix_qval) ? 1 : 0 ;
379
380 MCW_choose_stuff( w , "FDR q-value Settings" ,
381 AFNI_func_setqval_final_CB , im3d ,
382 MSTUF_STRING , "Set q-value" ,
383 MSTUF_STRLIST , "Keep fixed? " , 2 , ifix , yesno ,
384 MSTUF_END ) ;
385 EXRETURN ;
386 }
387
388 /*-----------------------------------------------------------------------*/
389 /*! 29 Jan 2008: add FDR curves to the functional dataset */
390
AFNI_func_fdr_CB(Widget w,XtPointer cd,XtPointer cb)391 void AFNI_func_fdr_CB( Widget w, XtPointer cd, XtPointer cb )
392 {
393 Three_D_View *im3d = (Three_D_View *)cd ;
394 THD_3dim_dataset *dset ; int nf ;
395
396 ENTRY("AFNI_func_fdr_CB") ;
397
398 if( !IM3D_OPEN(im3d) || !ISVALID_DSET(im3d->fim_now) ) EXRETURN ;
399 dset = im3d->fim_now ;
400 SHOW_AFNI_PAUSE ;
401 nf = THD_create_all_fdrcurves(dset) ;
402 AFNI_set_thr_pval(im3d) ;
403 INFO_message("Computed %d FDR curves in %s [but not saved on disk]" ,
404 nf , DSET_FILECODE(dset) ) ;
405 SHOW_AFNI_READY ;
406
407 EXRETURN ;
408 }
409
410 /*-----------------------------------------------------------------------*/
411 /*! 08 Aug 2007 */
412
AFNI_func_thrsign_CB(MCW_arrowval * av,XtPointer cd)413 void AFNI_func_thrsign_CB( MCW_arrowval *av , XtPointer cd )
414 {
415 Three_D_View *im3d = (Three_D_View *) cd ;
416
417 ENTRY("AFNI_func_thrsign_CB") ;
418
419 if( !IM3D_OPEN(im3d) ) EXRETURN ;
420
421 im3d->vinfo->thr_sign = av->ival ;
422 #if 0
423 STATUS_IM3D_TMASK(im3d) ;
424 STATUS("clear tmask") ;
425 #endif
426 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
427 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
428 AFNI_setup_thrstat(im3d,0) ;
429 AFNI_set_thr_pval( im3d ) ; /* Jan 2015 */
430 AFNI_redisplay_func( im3d ) ;
431 AFNI_set_window_titles( im3d ) ;
432 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
433 EXRETURN ;
434 }
435
436 /*---------------------------------------------------------------------------*/
437 /* Re-imagined alpha callback for choosing Linear or Quadratic [28 Jun 2021] */
438
AFNI_func_alpha_CB(MCW_arrowval * av,XtPointer cd)439 void AFNI_func_alpha_CB( MCW_arrowval *av , XtPointer cd )
440 {
441 Three_D_View *im3d = (Three_D_View *)cd ;
442
443 ENTRY("AFNI_func_alpha_CB") ;
444
445 if( !IM3D_OPEN(im3d) || !im3d->vinfo->thr_use_alpha ) EXRETURN ;
446
447 IM3D_CLEAR_TMASK(im3d) ;
448 IM3D_CLEAR_THRSTAT(im3d) ;
449 AFNI_redisplay_func( im3d ) ;
450 AFNI_set_window_titles( im3d ) ;
451 EXRETURN ;
452 }
453
454 #if 0 /*** old alpha stuff, now replaced by the 'A' button ***/
455 /*-----------------------------------------------------------------------*/
456 /*! 09 Dec 2014 */
457
458 void AFNI_func_floor_CB( MCW_arrowval *av , XtPointer cd )
459 {
460 Three_D_View *im3d = (Three_D_View *)cd ;
461
462 ENTRY("AFNI_func_floor_CB") ;
463
464 if( !IM3D_OPEN(im3d) ) EXRETURN ;
465
466 im3d->vinfo->thr_alpha_floor = av->ival * 0.2f ;
467 #if 0
468 STATUS_IM3D_TMASK(im3d) ;
469 STATUS("clear tmask") ;
470 #endif
471 IM3D_CLEAR_TMASK(im3d) ;
472 IM3D_CLEAR_THRSTAT(im3d) ;
473 AFNI_redisplay_func( im3d ) ;
474 AFNI_set_window_titles( im3d ) ;
475 EXRETURN ;
476 }
477 #endif /*------------- end of old alpha stuff ---------------------------*/
478
479 /*-----------------------------------------------------------------------*/
480 /*! Set the threshold and slider. [05 Mar 2007]
481 -------------------------------------------------------------------------*/
482
AFNI_set_threshold(Three_D_View * im3d,float val)483 void AFNI_set_threshold( Three_D_View *im3d , float val )
484 {
485 int olddec,newdec , smax,stop , ival ;
486
487 ENTRY("AFNI_set_threshold") ;
488
489 if( !IM3D_OPEN(im3d) || val < 0.0f || val > THR_top_value ) EXRETURN;
490
491 /* get current scale decimal setting */
492
493 olddec = (int)rint( log10(im3d->vinfo->func_thresh_top) ) ;
494 if( olddec < 0 ) olddec = 0 ;
495 else if( olddec > THR_top_expon ) olddec = THR_top_expon ;
496 newdec = olddec ;
497
498 if( val > 0.0f ){
499 newdec = (int)( log10(val) + 1.0 ) ;
500 if( newdec < 0 ) newdec = 0 ;
501 else if( newdec > THR_top_expon ) newdec = THR_top_expon ;
502 if( newdec != olddec )
503 AFNI_set_thresh_top( im3d , Thval[newdec] ) ;
504 }
505
506 smax = (int)rint( pow(10.0,THR_top_expon) ) ;
507 stop = smax - 1 ; /* max slider value */
508
509 ival = rint( val/(THR_factor*Thval[newdec]) ) ;
510 if( ival < 0 ) ival = 0 ;
511 else if( ival > stop ) ival = stop ;
512
513 #if 0
514 STATUS_IM3D_TMASK(im3d) ;
515 STATUS("clear tmask") ;
516 #endif
517 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
518 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
519 AFNI_setup_thrstat(im3d,0) ;
520 XmScaleSetValue( im3d->vwid->func->thr_scale , ival ) ;
521 AFNI_thr_scale_CB( im3d->vwid->func->thr_scale, (XtPointer)im3d, NULL ) ;
522 FIX_SCALE_SIZE(im3d) ;
523 AFNI_thresh_lock_carryout(im3d) ;
524 EXRETURN ;
525 }
526
527 /*-----------------------------------------------------------------------
528 Called when the scale for the threshold is adjusted.
529 30 Oct 1996: changed scale factor from slider to threshold
530 from 0.01 to 0.001 to allow for increased
531 precision of scale (0..999 instead of 0..99).
532 -------------------------------------------------------------------------*/
533
AFNI_thr_scale_CB(Widget w,XtPointer client_data,XtPointer call_data)534 void AFNI_thr_scale_CB( Widget w, XtPointer client_data, XtPointer call_data )
535 {
536 Three_D_View *im3d = (Three_D_View *) client_data ;
537 XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *) call_data ;
538 float fff ;
539 int ival ;
540
541 ENTRY("AFNI_thr_scale_CB") ;
542
543 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
544
545 if( cbs != NULL ) ival = cbs->value ;
546 else XmScaleGetValue( w , &ival ) ;
547
548 fff = THR_factor * ival ;
549 if( fff >= 0.0 && fff <= 1.0 ) im3d->vinfo->func_threshold = fff ;
550
551 FIX_SCALE_VALUE(im3d) ;
552 FIX_SCALE_SIZE(im3d) ; /* 09 May 2001 */
553
554 AFNI_set_thr_pval( im3d ) ;
555
556 MCW_discard_events_all( w , ButtonPressMask ) ; /* 20 Mar 2007 */
557
558 #if 0
559 STATUS_IM3D_TMASK(im3d) ;
560 STATUS("clear tmask") ;
561 #endif
562 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
563 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
564 AFNI_setup_thrstat(im3d,0) ;
565 if( ! DOING_REALTIME_WORK ) AFNI_redisplay_func( im3d ) ;
566
567 AFNI_thresh_lock_carryout(im3d) ; /* 06 Feb 2004 */
568
569 RESET_AFNI_QUIT(im3d) ;
570 EXRETURN ;
571 }
572
573 /*--------------------------------------------------------------------
574 Called when the user drags the threshold scale at all, even
575 without releasing it. Used to update the "p-value" interactively.
576 ----------------------------------------------------------------------*/
577
AFNI_thr_scale_drag_CB(Widget w,XtPointer client_data,XtPointer call_data)578 void AFNI_thr_scale_drag_CB( Widget w, XtPointer client_data, XtPointer call_data )
579 {
580 Three_D_View *im3d = (Three_D_View *) client_data ;
581 XmScaleCallbackStruct *cbs = (XmScaleCallbackStruct *) call_data ;
582 float fff ;
583
584 ENTRY("AFNI_thr_scale_drag CB") ;
585
586 if( IM3D_OPEN(im3d) && ISVALID_3DIM_DATASET(im3d->fim_now) ){
587
588 fff = THR_factor * cbs->value ;
589 if( fff >= 0.0 && fff <= 1.0 ) im3d->vinfo->func_threshold = fff ;
590
591 FIX_SCALE_VALUE(im3d) ;
592 if( FUNC_HAVE_PVAL(DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index)) )
593 AFNI_set_thr_pval( im3d ) ;
594
595 AFNI_thrdrag_lock_carryout( im3d ) ; /* 10 Feb 2004 */
596 }
597 EXRETURN ;
598 }
599
600 /*-----------------------------------------------------------------------
601 Set the top value used on the threshold slider.
602 (Should be followed by a function redisplay if needed.)
603 -------------------------------------------------------------------------*/
604
AFNI_set_thresh_itop(Three_D_View * im3d,int itop)605 void AFNI_set_thresh_itop( Three_D_View *im3d , int itop )
606 {
607 AFNI_set_thresh_top( im3d, Thval[itop] ) ;
608 }
609
AFNI_set_thresh_top(Three_D_View * im3d,float tval)610 void AFNI_set_thresh_top( Three_D_View *im3d , float tval )
611 {
612 int decim ;
613
614 ENTRY("AFNI_set_thresh_top") ;
615
616 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
617
618 if( tval <= 0.0 ) tval = 1.0 ;
619
620 decim = (2*THR_top_expon) - (int)(THR_top_expon + 0.01 + log10(tval)) ;
621 if( decim < 0 ) decim = 0 ;
622
623 XtVaSetValues( im3d->vwid->func->thr_scale, XmNdecimalPoints, decim, NULL ) ;
624
625 im3d->vinfo->func_thresh_top = tval ;
626
627 #if 0
628 STATUS_IM3D_TMASK(im3d) ;
629 STATUS("clear tmask") ;
630 #endif
631 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
632 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
633 AFNI_setup_thrstat(im3d,0) ;
634 FIX_SCALE_VALUE(im3d) ;
635 FIX_SCALE_SIZE(im3d) ; /* 09 May 2001 */
636 AFNI_set_thr_pval( im3d ) ;
637
638 /** fix the option menu at the bottom of the scale **/
639
640 decim = THR_top_expon - decim ;
641 if( decim != im3d->vwid->func->thr_top_av->ival )
642 AV_assign_ival( im3d->vwid->func->thr_top_av , decim ) ;
643
644 EXRETURN ;
645 }
646
647 /*-----------------------------------------------------------------------
648 Return the label for the threshold top chooser.
649 -------------------------------------------------------------------------*/
650
AFNI_thresh_tlabel_CB(MCW_arrowval * av,XtPointer junk)651 char * AFNI_thresh_tlabel_CB( MCW_arrowval *av , XtPointer junk )
652 {
653 static char tlab[8] ;
654 sprintf(tlab,"%d",av->ival) ;
655 return tlab ;
656 }
657
658 /*-----------------------------------------------------------------------
659 Take action when the user changes the threshold top chooser.
660 -------------------------------------------------------------------------*/
661
AFNI_thresh_top_CB(MCW_arrowval * av,XtPointer cd)662 void AFNI_thresh_top_CB( MCW_arrowval *av , XtPointer cd )
663 {
664 Three_D_View *im3d = (Three_D_View *) cd ;
665
666 ENTRY("AFNI_thresh_top_CB") ;
667
668 if( IM3D_OPEN(im3d) && im3d->vinfo->func_thresh_top != Thval[av->ival] ){
669
670 AFNI_set_thresh_top( im3d , Thval[av->ival] ) ;
671 FIX_SCALE_SIZE(im3d) ;
672
673 if( im3d->vinfo->func_visible ) AFNI_redisplay_func( im3d ) ;
674
675 AFNI_thresh_lock_carryout(im3d) ; /* 06 Feb 2004 */
676 }
677
678 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
679 EXRETURN ;
680 }
681
682 /*-----------------------------------------------------------------------*/
683 /* Something silly from Ziad */
684
AFNI_thresh_from_percentile(Three_D_View * im3d,float perc)685 float AFNI_thresh_from_percentile( Three_D_View *im3d, float perc)
686 {
687 float *fv, thresh=0.0;
688 int ithr;
689
690 if (!(fv = get_3Dview_sort(im3d, "T"))) return(perc);
691
692 ithr = (int)(perc*(float)(im3d->vinfo->N_th_sort-1)+0.5);
693 if (ithr < 0) {
694 thresh = fv[0]-1.0;
695 } else if (ithr > im3d->vinfo->N_th_sort) {
696 thresh = fv[im3d->vinfo->N_th_sort-1]+1.0;
697 } else {
698 thresh = fv[ithr];
699 }
700
701 #if 0
702 INFO_message( "Top val %f, bottom val %f\n"
703 "Sorting on set of %d voxels out of %d voxels in grid.\n"
704 "Thresholding bottom %f%% thresh=%f, ithr=%d.\n"
705 ,
706 fv[im3d->vinfo->N_th_sort-1], fv[0],
707 im3d->vinfo->N_th_sort, DSET_NVOX(im3d->fim_now),
708 100*perc, thresh, ithr
709 );
710 #endif
711 return(thresh);
712 }
713
714 /*-----------------------------------------------------------------------
715 Used to set the pval (significance) label at the bottom of the
716 threshold scale. And the qval (FDR) label.
717 -------------------------------------------------------------------------*/
718
AFNI_set_thr_pval(Three_D_View * im3d)719 void AFNI_set_thr_pval( Three_D_View *im3d )
720 {
721 float thresh , pval , zval , spval ;
722 char buf[32] ; int sig , scode ;
723
724 ENTRY("AFNI_set_thr_pval") ;
725
726 if( ! IM3D_OPEN(im3d) || ! ISVALID_3DIM_DATASET(im3d->fim_now) ) EXRETURN ;
727
728 thresh = get_3Dview_func_thresh(im3d,1);
729
730 /* get the p-value that goes with this threshold, for this functional dataset */
731
732 pval = THD_stat_to_pval( thresh ,
733 DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ,
734 DSET_BRICK_STATAUX (im3d->fim_now,im3d->vinfo->thr_index) ) ;
735
736 /* modify it if the threshold statistic is 2-sided but we are thresholding 1-sided */
737
738 scode = DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index) ;
739 if( im3d->vinfo->thr_sign == 0 || scode == FUNC_FT_TYPE )
740 sig = 0 ;
741 else
742 sig = THD_stat_is_2sided( scode , 0 ) ;
743 spval = pval ; if( sig > 0 ) spval *= 0.5f ; /* Jan 2015 */
744
745 im3d->vinfo->func_pval = spval ; /* 06 Feb 2004 -- changed to spval Jan 2015 */
746 im3d->vinfo->func_qval = 0.0f ; /* 23 Jan 2008 */
747
748 if(PRINT_TRACING)
749 { char buf[128] ;
750 sprintf( buf, "thresh=%g top=%g pval=%g",
751 thresh,im3d->vinfo->func_thresh_top,spval ) ; STATUS(buf) ; }
752
753 if( pval < 0.0 ){
754 strcpy( buf , THR_PVAL_LABEL_NONE ) ;
755 } else {
756 if( spval == 0.0 ){
757 strcpy( buf , "p=0" ) ;
758 } else if( spval >= 0.9999 ){
759 strcpy( buf , "p=1" ) ;
760 } else if( spval >= 0.0010 ){
761 char qbuf[20] ;
762 sprintf( qbuf , "%5.4f" , spval ) ;
763 strcpy(buf,"p=") ; strcat( buf , qbuf+1 ) ; /* qbuf+1 skips leading 0 */
764 } else {
765 int dec = (int)(0.999 - log10(spval)) ;
766 zval = spval * pow( 10.0 , (double) dec ) ; /* between 1 and 10 */
767 if( dec < 10 ) sprintf( buf , "p=%3.1f-%1d" , zval , dec ) ;
768 else sprintf( buf , "p=%1d.-%2d" , (int)rint(zval), dec ) ;
769 }
770 if( im3d->vedset.code > 0 && im3d->fim_now->dblk->vedim != NULL )
771 strcat(buf,"*") ; /* mark that are in clustering mode [05 Sep 2006] */
772 else if( im3d->vinfo->fix_pval && fabsf(im3d->vinfo->fixed_pval-pval)<1.e-4f )
773 strcat(buf,"f") ;
774 }
775
776 /* 23 Jan 2007: q-value from FDR curve? */
777
778 if( pval >= 0.0 ){
779 zval = THD_fdrcurve_zval( im3d->fim_now, im3d->vinfo->thr_index, thresh ) ;
780 if( zval > 0.0f ){
781 float qval = 2.0*qg(zval) ; /* convert z back to FDR q */
782 im3d->vinfo->func_qval = qval ;
783 if( qval > 0.0f && qval < 0.9999 ){
784 char qbuf[20] ;
785 if( qval >= 0.0010 ) sprintf(qbuf,"%5.4f",qval) ;
786 else {
787 int dec = (int)(0.999 - log10(qval)) ;
788 zval = qval * pow( 10.0 , (double)dec ) ; /* between 1 and 10 */
789 if( dec < 10 ) sprintf( qbuf, " %3.1f-%1d", zval, dec );
790 else sprintf( qbuf, " %1d.-%2d" , (int)rint(zval), dec );
791 }
792 strcat(buf,"\nq=") ; strcat(buf,qbuf+1) ;
793 if( im3d->vinfo->fix_qval && fabsf(im3d->vinfo->fixed_qval-qval)<1.e-4f )
794 strcat(buf,"f") ;
795 }
796 } else {
797 strcat(buf,"\nq=N/A") ;
798 }
799 }
800
801 MCW_set_widget_label( im3d->vwid->func->thr_pval_label , buf ) ;
802
803 if( im3d->vinfo->func_pval >= 0.0f && im3d->vinfo->func_pval <= 1.0f ){
804 #define EEEE 2.718282f /* e */
805 #define EINV 0.367879f /* 1/e */
806 char pstr[128] ; float mval ;
807 sprintf( pstr , "Uncorrected p=%.4e" , im3d->vinfo->func_pval ) ;
808 if( im3d->vinfo->func_pval > 0.0f && im3d->vinfo->func_pval < EINV &&
809 THD_stat_is_2sided( DSET_BRICK_STATCODE(im3d->fim_now,im3d->vinfo->thr_index),
810 im3d->vinfo->thr_sign) > 0 )
811 sprintf(pstr+strlen(pstr)," alpha(p)=%.4e",
812 1/(1-1/(EEEE*im3d->vinfo->func_pval*log(im3d->vinfo->func_pval))) ) ;
813 if( im3d->vinfo->func_qval >= 0.0f && im3d->vinfo->func_qval <= 1.0f )
814 sprintf(pstr+strlen(pstr),"; FDR q=%.4e",im3d->vinfo->func_qval) ;
815 else
816 sprintf(pstr+strlen(pstr),"; FDR q=N/A") ;
817 mval = THD_mdfcurve_mval( im3d->fim_now, im3d->vinfo->thr_index ,
818 im3d->vinfo->func_pval ) ;
819 #if 1
820 if( mval >= 0.0f )
821 sprintf(pstr+strlen(pstr),"; MDF=%.1f%%",100.0f*mval) ;
822 else
823 strcat(pstr,"; MDF=N/A") ;
824 #else
825 sprintf(pstr+strlen(pstr),"; MDF=%.1f%%",100.0f*mval) ;
826 #endif
827 MCW_register_hint( im3d->vwid->func->thr_pval_label , pstr ) ;
828 } else {
829 MCW_register_hint( im3d->vwid->func->thr_pval_label ,
830 "Uncorrected p-value per voxel" ) ;
831 }
832
833 FIX_SCALE_SIZE(im3d) ;
834 EXRETURN ;
835 }
836
837 /*---------------------------------------------------------------------------
838 30 Mar 2001: add range hints to a pbar
839 -----------------------------------------------------------------------------*/
840
AFNI_hintize_pbar(MCW_pbar * pbar,float fac)841 void AFNI_hintize_pbar( MCW_pbar *pbar , float fac )
842 {
843 int ip , np ;
844 Widget w ;
845 char sbot[16],stop[16] , hint[64] , *sb,*st ;
846 float bot , top ;
847
848 ENTRY("AFNI_hintize_pbar") ;
849
850 if( pbar == NULL || fac == 0.0f ) EXRETURN ; /* bad */
851
852 if( PBAR_FULLRANGE ) fac = 1.0f ; /* 03 Jun 2014 */
853
854 if( pbar->bigmode ){
855 MCW_register_hint( pbar->panes[0] ,
856 "Button-1=flip; Button-3=menu" ) ;
857 pbar->bigfac = fac ; /* 11 Feb 2003 */
858 } else {
859 np = pbar->num_panes ;
860 for( ip=0 ; ip < np ; ip++ ){
861 w = pbar->panes[ip] ; /* the widget for the ip-th pane */
862 top = pbar->pval[ip] * fac ; /* scaled top value */
863 bot = pbar->pval[ip+1] * fac ; /* scaled bot value */
864 AV_fval_to_char( bot , sbot ) ; /* convert to a nice string */
865 AV_fval_to_char( top , stop ) ;
866 sb = (sbot[0] == ' ') ? sbot+1 : sbot ; /* skip leading blanks */
867 st = (stop[0] == ' ') ? stop+1 : stop ;
868 sprintf(hint,"%s .. %s",sb,st) ; /* create hint */
869 MCW_register_hint( w , hint ) ; /* send to hint system */
870 }
871 }
872
873 EXRETURN ;
874 }
875
876 /*----------------------------------------------------------------------------
877 called when the pbar for the intensity mapping is adjusted
878 (thresholds or colors)
879 ------------------------------------------------------------------------------*/
880
AFNI_inten_pbar_CB(MCW_pbar * pbar,XtPointer cd,int reason)881 void AFNI_inten_pbar_CB( MCW_pbar *pbar , XtPointer cd , int reason )
882 {
883 Three_D_View *im3d = (Three_D_View *)cd ;
884 float fac ;
885
886 ENTRY("AFNI_inten_pbar_CB") ;
887
888 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
889
890 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
891 STATUS("incoherent ulay -- patching") ;
892 ERROR_message("AFNI_inten_pbar_CB: incoherent ulay -- patching") ;
893 AFNI_assign_ulay_bricks(im3d) ;
894 }
895
896 #if 0
897 STATUS_IM3D_TMASK(im3d) ;
898 STATUS("clear tmask") ;
899 #endif
900 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
901 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
902 AFNI_setup_thrstat(im3d,0) ;
903
904 #if 0
905 INFO_message("AFNI_inten_pbar_CB(%d)",AFNI_controller_index(im3d)) ;
906 #endif
907 if( im3d->vinfo->func_visible ) AFNI_redisplay_func( im3d ) ;
908
909 AFNI_hintize_pbar( pbar , FIM_RANGE(im3d) ) ;
910
911 FIX_SCALE_SIZE(im3d) ;
912
913 AFNI_pbar_lock_carryout(im3d) ; /* 07 Feb 2004 */
914
915 #if 0
916 AFNI_set_scale_size_fix_timer(im3d) ; /* 03 Jun 2019 */
917 #endif
918 EXRETURN ;
919 }
920
921 /*----------------------------------------------------------------------------*/
922
923 #if 0
924 void AFNI_iab_pbar_CB( MCW_pbar *pbar , XtPointer cd , int reason )
925 {
926 Three_D_View *im3d = (Three_D_View *)cd ;
927
928 ENTRY("AFNI_iab_pbar_CB") ;
929
930 if( pbar == NULL || !pbar->three_level || !IM3D_OPEN(im3d) ) EXRETURN ; /* error */
931
932 switch( reason ){
933
934 case pbCR_VALUE:{
935 float top,bot , ntop,nbot ;
936 ntop = top = pbar->pval[1] ; nbot = bot = pbar->pval[2] ;
937 switch( im3d->vwid->func->iab_bot_av->ival ){
938 case 1: /* Bot = -Top */
939 if( top > 0.0f ) nbot = -top ; else ntop = -bot ;
940 break ;
941 case 0: /* Bot = 0 */
942 if( top <= 0.0f ) ntop = -bot ;
943 nbot = 0.0f ;
944 break ;
945 }
946
947 if( ntop != top || nbot != bot ){
948 float pval[4] ;
949 pval[0] = pbar->pval[0] ; pval[3] = pbar->pval[3] ;
950 pval[1] = ntop ; pval[2] = nbot ;
951 alter_MCW_pbar( pbar , 0 , pval ) ;
952 }
953 }
954 break ;
955
956 case pbCR_COLOR: /* TBD */
957 break ;
958
959 }
960
961 FIX_SCALE_SIZE(im3d) ; EXRETURN ;
962 }
963
964 /*----------------------------------------------------------------------------*/
965
966 void AFNI_iab_av_CB( MCW_arrowval *av , XtPointer cd )
967 {
968 Three_D_View *im3d = (Three_D_View *)cd ;
969 MCW_pbar *pbar = im3d->vwid->func->iab_pbar ;
970
971 ENTRY("AFNI_iab_av_CB") ;
972
973 if( pbar == NULL ) EXRETURN ; /* error */
974
975 if( av == im3d->vwid->func->iab_pow_av ){
976 float pval[4] , fac ;
977 fac = powf(10.0f,(float)av->ival) ;
978 pval[0] = 1.2f*fac ; pval[1] = 1.0f*fac ;
979 pval[2] = -1.0f*fac ; pval[3] = -1.2f*fac ;
980 HIDE_SCALE(im3d) ;
981 alter_MCW_pbar( pbar , 0 , pval ) ;
982 FIX_SCALE_SIZE(im3d) ;
983
984 } else if( av == im3d->vwid->func->iab_bot_av ){
985
986 if( av->ival != 2 ) AFNI_iab_pbar_CB(pbar,im3d,pbCR_VALUE) ;
987
988 }
989
990 EXRETURN ;
991 }
992 #endif
993
994 /*-----------------------------------------------------------------------------
995 30 Mar 2001: rotate the colors on the pbar
996 -------------------------------------------------------------------------------*/
997
AFNI_range_rotate_av_CB(MCW_arrowval * av,XtPointer cd)998 void AFNI_range_rotate_av_CB( MCW_arrowval *av , XtPointer cd )
999 {
1000 MCW_pbar *pbar = (MCW_pbar *) cd ;
1001 int ddd ;
1002
1003 ENTRY("AFNI_range_rotate_av_CB") ;
1004
1005 /* which way to rotate? */
1006
1007 if( av->fval > av->old_fval ) ddd = +1 ;
1008 else ddd = -1 ;
1009
1010 /* Shift+click ==> rotate by 4 (useful for bigmode) */
1011
1012 if( av->xev.type == ButtonPress ){
1013 XButtonEvent *event = (XButtonEvent *) (&av->xev) ;
1014 if( event->state & ShiftMask ) ddd *= 4 ;
1015 }
1016
1017 rotate_MCW_pbar( pbar , ddd ) ;
1018 EXRETURN ;
1019 }
1020
1021 /*---------------------------------------------------------------------------
1022 called to set up the pbar for the intensity mapping
1023 -----------------------------------------------------------------------------*/
1024
1025 /** 3/27/95: changed to allow different initializations
1026 for the [0,1] and the [-1,1] range pbars. **/
1027
1028 /** 6/01/95: changed to put the initialization constants
1029 in tables initialized in afni.c, not here. **/
1030
AFNI_setup_inten_pbar(MCW_pbar * pbar)1031 void AFNI_setup_inten_pbar( MCW_pbar *pbar )
1032 {
1033 int np , i , jm , lcol ;
1034
1035 ENTRY("AFNI_setup_inten_pbar") ;
1036
1037 if( pbar == NULL ) EXRETURN ;
1038
1039 jm = pbar->mode ;
1040 lcol = pbar->dc->ovc->ncol_ov - 1 ;
1041
1042 /** load the 'save' values for all possible pane counts **/
1043
1044 for( np=NPANE_MIN ; np <= NPANE_MAX ; np++ ){
1045
1046 for( i=0 ; i <= np ; i++ ){
1047 pbar->pval_save[np][i][0] = INIT_pval_sgn[np][i] ;
1048 pbar->pval_save[np][i][1] = INIT_pval_pos[np][i] ;
1049 }
1050
1051 for( i=0 ; i < np ; i++ ){
1052 pbar->ovin_save[np][i][0] = MIN( lcol , INIT_ovin_sgn[np][i] ) ;
1053 pbar->ovin_save[np][i][1] = MIN( lcol , INIT_ovin_pos[np][i] ) ;
1054 }
1055 }
1056
1057 /** load the values for the current pane count **/
1058
1059 np = pbar->num_panes ;
1060 jm = pbar->mode ;
1061
1062 for( i=0 ; i <= np ; i++ ) pbar->pval[i] = pbar->pval_save[np][i][jm] ;
1063 for( i=0 ; i < np ; i++ ) pbar->ov_index[i] = pbar->ovin_save[np][i][jm] ;
1064
1065 pbar->update_me = 1 ;
1066 EXRETURN ;
1067 }
1068
1069 /*----------------------------------------------------------------------------
1070 called when the arrowval for the number of pbar panes is clicked
1071 ------------------------------------------------------------------------------*/
1072
AFNI_inten_av_CB(MCW_arrowval * av,XtPointer cd)1073 void AFNI_inten_av_CB( MCW_arrowval *av , XtPointer cd )
1074 {
1075 MCW_pbar *pbar = (MCW_pbar *)cd ;
1076 Three_D_View *im3d = (Three_D_View *)pbar->parent ;
1077
1078 if( !IM3D_OPEN(im3d) ) return ;
1079
1080 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
1081 STATUS("incoherent ulay -- patching") ;
1082 ERROR_message("AFNI_inten_av_CB: incoherent ulay -- patching") ;
1083 AFNI_assign_ulay_bricks(im3d) ;
1084 }
1085
1086 if( PBAR_FULLRANGE ) AFNI_redisplay_func_ignore(1) ;
1087
1088 #if 0
1089 STATUS_IM3D_TMASK(im3d) ;
1090 STATUS("clear tmask") ;
1091 #endif
1092 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
1093 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
1094 AFNI_setup_thrstat(im3d,0) ;
1095 HIDE_SCALE(im3d) ;
1096 if( av->ival > NPANE_MAX ){
1097 int npane=pbar->num_panes , jm=pbar->mode ;
1098 float pmax,pmin ;
1099 pmax = (pbar->big31) ? pbar->bigtop : pbar->pval_save[npane][0 ][jm] ;
1100 pmin = (pbar->big31) ? pbar->bigbot : pbar->pval_save[npane][npane][jm] ;
1101 PBAR_set_bigmode( pbar , 1 , pmin,pmax ) ;
1102 AFNI_inten_pbar_CB( pbar , im3d , 0 ) ;
1103 POPUP_cursorize( pbar->panew ) ; /* 08 Apr 2005 */
1104 } else {
1105 pbar->bigmode = 0 ;
1106 alter_MCW_pbar( pbar , av->ival , NULL ) ;
1107 NORMAL_cursorize( pbar->panew ) ; /* 08 Apr 2005 */
1108 }
1109 FIX_SCALE_SIZE(im3d) ;
1110
1111 if( PBAR_FULLRANGE ) AFNI_redisplay_func_ignore(0) ;
1112
1113 if( PBAR_FULLRANGE ) AFNI_pbar_topset(im3d,im3d->vinfo->fim_range) ;
1114 else HINTIZE_pbar(im3d) ;
1115
1116 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
1117 return ;
1118 }
1119
1120 /*----------------------------------------------------------------------------*/
1121
AFNI_inten_av_texter(MCW_arrowval * av,XtPointer cd)1122 char * AFNI_inten_av_texter( MCW_arrowval *av , XtPointer cd )
1123 {
1124 static char buf[4] ;
1125 if( av->ival > NPANE_MAX ) strcpy (buf,"**") ; /* label for */
1126 else sprintf(buf,"%d",av->ival) ; /* number of */
1127 return buf ; /* pbar panes */
1128 }
1129
1130 /*---------------------------------------------------------------------
1131 Make a warped dataset whose grid corresponds to the anat_parent and
1132 whose data comes from the data_parent.
1133 Note that the assumption is made that data_parent and the warp parent
1134 of the anat_parent are both in the same coordinate system (up to the
1135 to_dicomm transformation of their dataxes structs).
1136 -----------------------------------------------------------------------*/
1137
AFNI_follower_dataset(THD_3dim_dataset * anat_parent,THD_3dim_dataset * data_parent)1138 THD_3dim_dataset * AFNI_follower_dataset( THD_3dim_dataset *anat_parent ,
1139 THD_3dim_dataset *data_parent )
1140 {
1141 THD_3dim_dataset *new_dset ;
1142 int ii ;
1143
1144 ENTRY("AFNI_follower_dataset") ;
1145
1146 /* sanity checks */
1147
1148 if( ! ISVALID_3DIM_DATASET(anat_parent) ||
1149 ! ISVALID_3DIM_DATASET(data_parent) ) RETURN(NULL) ;
1150
1151 /* can't warp a time-dependent dataset (OK, maybe you can) */
1152
1153 if( DSET_NUM_TIMES(data_parent) > 1 && ! GLOBAL_argopt.warp_4D ) RETURN(NULL) ;
1154
1155 if(PRINT_TRACING)
1156 { char str[256] ;
1157 sprintf(str,"anat_parent=%s data_parent=%s",
1158 DSET_HEADNAME(anat_parent) , DSET_HEADNAME(data_parent) ) ;
1159 STATUS(str); }
1160
1161 /* make new dataset, copying appropriate fields from its various parents */
1162
1163 new_dset = myXtNew( THD_3dim_dataset ) ; INIT_KILL( new_dset->kl ) ;
1164
1165 new_dset->type = data_parent->type ; /* same data type */
1166 new_dset->func_type = data_parent->func_type ;
1167 new_dset->view_type = anat_parent->view_type ; /* but different view type */
1168
1169 /* use template space of parent to mark as TLRC/MNI/... */
1170 MCW_strncpy( new_dset->atlas_space ,
1171 anat_parent->atlas_space , THD_MAX_NAME ) ;
1172
1173 new_dset->anat_parent = anat_parent ; /* what else makes sense? */
1174
1175 new_dset->tagset = NULL ; /* Oct 1998 */
1176 new_dset->Label_Dtable = NULL; /* ZSS Feb 26 2010 */
1177
1178 MCW_strncpy( new_dset->anat_parent_name ,
1179 anat_parent->self_name , THD_MAX_NAME ) ;
1180
1181 new_dset->anat_parent_idcode = anat_parent->idcode ;
1182
1183 /* 11/09/94 addition: the data_parent may itself be a warp;
1184 in this case, we want the true warp parent to be the original data */
1185
1186 new_dset->warp_parent = (data_parent->warp_parent != NULL)
1187 ? (data_parent->warp_parent) : (data_parent) ;
1188
1189 MCW_strncpy( new_dset->warp_parent_name ,
1190 new_dset->warp_parent->self_name , THD_MAX_NAME ) ;
1191
1192 new_dset->warp_parent_idcode = new_dset->warp_parent->idcode ;
1193
1194 new_dset->idcode = MCW_new_idcode() ;
1195
1196 /* make the actual warp from the warp_parent to this dataset */
1197
1198 new_dset->vox_warp = NULL ;
1199 new_dset->warp = myXtNew( THD_warp ) ;
1200 *(new_dset->warp) = IDENTITY_WARP ; /* start with (Dicom) identity */
1201 new_dset->self_warp = NULL ; /* 26 Aug 2002 */
1202
1203 /* follow the links backward from desired view to original view */
1204
1205 AFNI_concatenate_warp( new_dset->warp , anat_parent->warp ) ;
1206 AFNI_concatenate_warp( new_dset->warp , data_parent->warp ) ;
1207
1208 /* reset the bounds in the new warp to be the same as in the anat_parent */
1209
1210 if( ISVALID_WARP(anat_parent->warp) &&
1211 anat_parent->warp->type == new_dset->warp->type ){
1212
1213 switch( anat_parent->warp->type ){
1214
1215 case WARP_AFFINE_TYPE:
1216 COPY_LMAP_BOUNDS( new_dset->warp->rig_bod.warp ,
1217 anat_parent->warp->rig_bod.warp ) ;
1218 break ;
1219
1220 case WARP_TALAIRACH_12_TYPE:
1221 for( ii=0 ; ii < 12 ; ii++ )
1222 COPY_LMAP_BOUNDS( new_dset->warp->tal_12.warp[ii] ,
1223 anat_parent->warp->tal_12.warp[ii] ) ;
1224 break ;
1225 }
1226 }
1227
1228 /* make up some names for this new dataset */
1229
1230 MCW_strncpy( new_dset->self_name ,
1231 new_dset->warp_parent->self_name , THD_MAX_NAME ) ;
1232 ii = strlen( new_dset->self_name ) ;
1233 new_dset->self_name[ii++] = '@' ;
1234 MCW_strncpy( &(new_dset->self_name[ii]) ,
1235 VIEW_typestr[new_dset->view_type] , THD_MAX_NAME-ii ) ;
1236
1237 MCW_strncpy( new_dset->label1 , data_parent->label1 , THD_MAX_LABEL ) ;
1238 MCW_strncpy( new_dset->label2 , data_parent->label2 , THD_MAX_LABEL ) ;
1239
1240 /* set the axes for this new dataset
1241 (same as anatomy parent, since that's the meaning of this routine) */
1242
1243 new_dset->daxes = myXtNew( THD_dataxes ) ; /* copy data axes of */
1244 *(new_dset->daxes) = *(anat_parent->daxes) ; /* anatomy parent */
1245
1246 new_dset->wod_daxes = NULL ;
1247 new_dset->wod_flag = True ;
1248
1249 /* 06 Aug 1996: added ability to use 3D+t datasets here */
1250
1251 if( DSET_NUM_TIMES(data_parent) < 2 ){
1252 new_dset->taxis = NULL ;
1253 } else {
1254 new_dset->taxis = myXtNew( THD_timeaxis ) ; /* new */
1255 *(new_dset->taxis) = *(data_parent->taxis) ; /* copy insides */
1256
1257 new_dset->taxis->nsl = 0 ; /* no slice stuff */
1258 new_dset->taxis->toff_sl = NULL ;
1259 new_dset->taxis->zorg_sl = 0.0 ;
1260 new_dset->taxis->dz_sl = 0.0 ;
1261 }
1262
1263 /* create a datablock and diskptr, in case the data is ever
1264 filled into memory (instead of wod) and written to disk */
1265
1266 new_dset->dblk = myXtNew( THD_datablock ) ; INIT_KILL( new_dset->dblk->kl ) ;
1267
1268 new_dset->dblk->type = DATABLOCK_TYPE ;
1269 new_dset->dblk->nvals = data_parent->dblk->nvals ;
1270 new_dset->dblk->malloc_type = DATABLOCK_MEM_UNDEFINED ;
1271 new_dset->dblk->natr = new_dset->dblk->natr_alloc = 0 ;
1272 new_dset->dblk->atr = NULL ;
1273 new_dset->dblk->parent = (XtPointer) new_dset ;
1274
1275 new_dset->dblk->vedim = NULL ; /* 05 Sep 2006 */
1276
1277 if( data_parent->dblk->brick_lab == NULL ){
1278 THD_init_datablock_labels( new_dset->dblk ) ; /* 30 Nov 1997 */
1279 } else {
1280 THD_copy_datablock_auxdata( data_parent->dblk , new_dset->dblk ) ;
1281 }
1282
1283 DSET_unlock(new_dset) ; /* Feb 1998 */
1284
1285 new_dset->dblk->diskptr = myXtNew( THD_diskptr ) ;
1286 new_dset->dblk->diskptr->type = DISKPTR_TYPE ;
1287 new_dset->dblk->diskptr->nvals = data_parent->dblk->nvals ;
1288 new_dset->dblk->diskptr->rank = 3 ;
1289 new_dset->dblk->diskptr->storage_mode = STORAGE_UNDEFINED ;
1290 new_dset->dblk->diskptr->byte_order = THD_get_write_order() ; /* 25 April 1998 */
1291 new_dset->dblk->diskptr->dimsizes[0] = new_dset->daxes->nxx ;
1292 new_dset->dblk->diskptr->dimsizes[1] = new_dset->daxes->nyy ;
1293 new_dset->dblk->diskptr->dimsizes[2] = new_dset->daxes->nzz ;
1294
1295 new_dset->dblk->brick_fac = NULL ; /* initialized below */
1296 new_dset->dblk->brick_bytes = NULL ;
1297 new_dset->dblk->brick = NULL ;
1298 THD_init_datablock_brick( new_dset->dblk , -1 , data_parent->dblk ) ;
1299
1300 new_dset->dblk->master_nvals = 0 ; /* 11 Jan 1999 */
1301 new_dset->dblk->master_ival = NULL ;
1302 new_dset->dblk->master_bytes = NULL ;
1303
1304 /* create the names for storage on disk (if ever)
1305 -- note we put it in the same directory as the data_parent */
1306
1307 THD_init_diskptr_names( new_dset->dblk->diskptr ,
1308 data_parent->dblk->diskptr->directory_name , NULL ,
1309 data_parent->dblk->diskptr->prefix ,
1310 new_dset->view_type , True ) ;
1311
1312 ADDTO_KILL( new_dset->dblk->kl , new_dset->dblk->diskptr ) ;
1313
1314 /* oh yeah, set the new_dset kill list,
1315 copy statistics if available, and NULL out any unused stuff */
1316
1317 ADDTO_KILL( new_dset->kl , new_dset->warp ) ;
1318 ADDTO_KILL( new_dset->kl , new_dset->daxes ) ;
1319 ADDTO_KILL( new_dset->kl , new_dset->dblk ) ;
1320
1321 new_dset->stats = NULL ;
1322 AFNI_copy_statistics( data_parent , new_dset ) ;
1323
1324 INIT_STAT_AUX( new_dset , MAX_STAT_AUX , data_parent->stat_aux ) ;
1325
1326 new_dset->markers = NULL ; /* no markers */
1327 new_dset->death_mark = 0 ; /* don't kill me! */
1328 new_dset->tcat_list = 0 ;
1329 new_dset->tcat_num = 0 ;
1330 new_dset->tcat_len = NULL ;
1331
1332 #ifdef ALLOW_DATASET_VLIST
1333 new_dset->pts = NULL ;
1334 #endif
1335
1336 PARENTIZE(new_dset,data_parent->parent) ;
1337
1338 tross_Copy_History( data_parent , new_dset ) ; /* 18 Oct 1999 */
1339
1340 RETURN(new_dset) ;
1341 }
1342
1343 /*------------------------------------------------------------------------
1344 Scan through a sessionlist and find any datasets that can be "filled in"
1345 as 'followers' (as in AFNI_follower_dataset). That is, find any slots
1346 that are not now filled, but are "downstream" from original view data
1347 that has an anatomy parent:
1348
1349 SPGR: orig acpc ----
1350 /^\ <--- anatomy parent
1351 | <--- relationship
1352 FIM: orig ---- ----
1353
1354 In this picture, the first blank in the FIM line can be filled in, using
1355 the fim+orig dataset as the data_parent and the spgr+acpc dataset as
1356 the anat_parent for the new fim+acpc dataset.
1357
1358 The algorithm used to find slots that may be filled in is as simple as
1359 the picture above -- the 'orig' view is presumed to contain all the basic
1360 anatomy parent relationships. This may not be true in the future
1361 (e.g., when registering one dataset to another, the 'rgst' view will
1362 then have a basic anatomy parent relationship). I'll worry about
1363 that later, as well as about the possibility that the newly created
1364 datasets may spawn further possible offspring (e.g., if they themselves
1365 are anatomical images that fill in slots that will become anat_parents).
1366 -- RWCox, November, 1994 A.D.
1367
1368 3 June 1998:
1369 The original version of this is renamed to be AFNI_make_descendants_old,
1370 and is modified to do a sweep starting at the "vbase" view. Then
1371 we sweep twice, once from +orig and once again from +acpc. This is
1372 to allow for creation of descendants from +acpc that do not have
1373 ancestors at +orig.
1374 ---------------------------------------------------------------------------*/
1375
1376 void AFNI_make_descendants_old( THD_sessionlist * , int ) ; /* prototype */
1377
AFNI_make_descendants(THD_sessionlist * ssl)1378 void AFNI_make_descendants( THD_sessionlist *ssl )
1379 {
1380 AFNI_make_descendants_old( ssl , VIEW_ORIGINAL_TYPE ) ;
1381 #if 0
1382 AFNI_make_descendants_old( ssl , VIEW_ACPCALIGNED_TYPE ) ; /* doesn't work */
1383 #endif
1384 return ;
1385 }
1386
1387 /** In this routine, each occurence of vbase was originally VIEW_ORIGINAL_TYPE **/
1388
AFNI_make_descendants_old(THD_sessionlist * ssl,int vbase)1389 void AFNI_make_descendants_old( THD_sessionlist *ssl , int vbase )
1390 {
1391 int iss , jdd , kvv , num_made=0 ;
1392 THD_session *ss, *temp_ss ;
1393 THD_3dim_dataset *orig_dset , *temp_dset, *temp_anat_dset ;
1394 THD_slist_find find ;
1395 THD_3dim_dataset *anat_parent_dset;
1396 /* **orig_row ;*/
1397 int orig_row_key, anat_parent_row_key;
1398
1399 ENTRY("AFNI_make_descendants_old") ;
1400
1401 if( ! ISVALID_SESSIONLIST(ssl) ) EXRETURN ;
1402
1403 /* loop over each session */
1404
1405 for( iss=0 ; iss < ssl->num_sess ; iss++ ){
1406 ss = ssl->ssar[iss] ;
1407 if( !ISVALID_SESSION(ss) ) continue ; /* no good ==> skip */
1408
1409 if( ss == GLOBAL_library.session ) continue ; /* 21 Dec 2001 */
1410
1411 /* loop over datasets in this session */
1412
1413 for( jdd=0 ; jdd < ss->num_dsset ; jdd++ ){
1414 orig_dset = GET_SESSION_DSET(ss, jdd, vbase);
1415 /* orig_dset = ss->dsset_xform_table[jdd][vbase] ; */ /* 03 Jun 98 */
1416 if( !ISVALID_3DIM_DATASET(orig_dset) || /* no good */
1417 orig_dset->anat_parent == NULL || /* no parent */
1418 orig_dset->anat_parent == orig_dset ) continue ; /* ==> skip */
1419
1420 if( DSET_in_global_session(orig_dset) ) continue ; /* 25 Dec 2001 */
1421
1422 /* look for orig_dset's anat parent in this sessionlist */
1423
1424 find = THD_dset_in_sessionlist( FIND_IDCODE ,
1425 &(orig_dset->anat_parent->idcode) ,
1426 ssl , iss ) ;
1427 if( find.dset == NULL )
1428 find = THD_dset_in_sessionlist( FIND_NAME ,
1429 orig_dset->anat_parent->self_name ,
1430 ssl , iss ) ;
1431
1432 /* check for a good find; if it doesn't happen,
1433 then skip (this eventuality should never occur!) */
1434
1435 if( find.dset == NULL ||
1436 ISFUNC(find.dset) || /* anat parent can't be a func! */
1437 find.view_index != vbase ) continue ;
1438
1439 /* make a pointer to the row of datasets of the anat
1440 parent (this is like the SPGR row in the picture above) */
1441
1442 /* will need to change this test with updated session tables - drg 05/2010 */
1443 anat_parent_dset =
1444 GET_SESSION_DSET(ssl->ssar[find.sess_index], find.dset_index, vbase) ;
1445 if(orig_dset == anat_parent_dset) continue ; /* 20 Jul 2010 */
1446
1447 anat_parent_row_key = find.dset_index;
1448 /* anat_parent_row =
1449 &(ssl->ssar[find.sess_index]->dsset_xform_table[find.dset_index][0]) ;*/
1450
1451 /* pointer to row of datasets being operated on now
1452 (like the FIM row in the picture above) */
1453 orig_row_key = jdd;
1454 /* orig_row = &(ss->dsset_xform_table[jdd][0]) ; */
1455 /* if( orig_row == anat_parent_row ) continue ;*/ /* 14 Dec 1999 */
1456
1457 /* loop over downstream dataset positions (from orig_dset);
1458 those that don't exist yet, but have entries in the
1459 anat_parent_row can be brought into being now */
1460 temp_ss = ssl->ssar[find.sess_index];
1461
1462 for( kvv=vbase+1 ; kvv <= LAST_VIEW_TYPE ; kvv++ ){
1463 if( GET_SESSION_DSET(ss, orig_row_key, kvv) != NULL ) continue ;
1464 temp_anat_dset = GET_SESSION_DSET(temp_ss, anat_parent_row_key, kvv);
1465 if( temp_anat_dset == NULL ) continue ;
1466
1467 temp_dset = AFNI_follower_dataset( temp_anat_dset, orig_dset ) ;
1468
1469 SET_SESSION_DSET(temp_dset, ss, orig_row_key, kvv);
1470 /* orig_row[kvv] = AFNI_follower_dataset( anat_parent_row[kvv] ,
1471 orig_dset ) ;*/
1472 num_made ++ ;
1473 }
1474 } /* end of loop over datasets in this session */
1475
1476 } /* end of loop over sessions */
1477
1478 if(PRINT_TRACING)
1479 { char str[256] ;
1480 sprintf(str,"total # descendants made = %d",num_made) ;
1481 STATUS(str) ; }
1482
1483 EXRETURN ;
1484 }
1485
1486 /*-----------------------------------------------------------------------
1487 Scan through a session and force any un-anat_parented functional
1488 datasets to have the first available parent, if any.
1489 (Note that only the dataset anat_parent pointer is set, not the
1490 anat_parent_name string, so that if the dataset is saved, no record
1491 of this will be kept.)
1492
1493 06 Aug 1996: force adoption of anats as well if "do_anats" is True.
1494 03 Dec 1999: print messages about forced adoptions
1495 -------------------------------------------------------------------------*/
1496
AFNI_force_adoption(THD_session * ss,RwcBoolean do_anats)1497 void AFNI_force_adoption( THD_session *ss , RwcBoolean do_anats )
1498 {
1499 int aa , ff , vv , apref=0 , aset=-1 ;
1500 THD_3dim_dataset *dset, *pref_dset, *anyanat_dset ;
1501 int quiet = !AFNI_noenv("AFNI_NO_ADOPTION_WARNING") ; /* 03 Dec 1999 */
1502 int first = 1 ;
1503
1504 ENTRY("AFNI_force_adoption") ;
1505
1506 if( ! ISVALID_SESSION(ss) || ss->num_dsset == 0 || ss->is_collection ) EXRETURN ;
1507
1508 if( ss == GLOBAL_library.session ) EXRETURN ; /* 21 Dec 2001 */
1509
1510 /* find a "preferred" parent (one with the most number of markers set) */
1511
1512 for( aa=0 ; aa < ss->num_dsset ; aa++ ){
1513
1514 if(PRINT_TRACING)
1515 { char str[256] ;
1516 sprintf(str,"scanning dataset %d for markers",aa) ; STATUS(str) ; }
1517 dset = GET_SESSION_DSET(ss, aa, 0); /* original view */
1518 /* dset = ss->dsset_xform_table[aa][0] ;*/ /* original view */
1519
1520 if( ISVALID_3DIM_DATASET(dset) && /* if a good dataset */
1521 ISANAT(dset) && /* and is anatomical */
1522 dset->markers != NULL ){ /* and has markers */
1523
1524 if( dset->markers->numset > aset ){ /* and has more markers than before */
1525 apref = aa ; /* try this as our "preferred" parent */
1526 aset = dset->markers->numset ;
1527 }
1528 }
1529 }
1530
1531 /* count potential parents [08 Dec 1999: modified from 03 Dec 1999 code] */
1532
1533 vv = 0 ;
1534 if( aset >= 0 ){
1535 for( aa=0 ; aa < ss->num_dsset ; aa++ ){
1536 dset = GET_SESSION_DSET(ss, aa, 0);
1537 if( ISVALID_DSET(dset) &&
1538 ISANAT(dset) &&
1539 dset->markers != NULL && dset->markers->numset >= aset ) vv++ ;
1540 }
1541 }
1542
1543 quiet = ( quiet || vv <= 1 ) ; /* be quiet if ordered, or if no alternatives */
1544
1545 if(aset >= 0 && PRINT_TRACING)
1546 { char str[256] ;
1547 THD_3dim_dataset *temp_dset;
1548 temp_dset = GET_SESSION_DSET(ss,apref,0);
1549 sprintf(str,"session %s: apref=%d [%s] aset=%d",
1550 ss->lastname,apref,DSET_HEADNAME(temp_dset),aset) ;
1551 /* sprintf(str,"session %s: apref=%d [%s] aset=%d",
1552 ss->lastname,apref,DSET_HEADNAME(ss->dsset_xform_table[apref][0]),aset) ;*/
1553 STATUS(str) ; }
1554
1555 /* scan through all datasets, all views */
1556
1557 for( ff=0 ; ff < ss->num_dsset ; ff++ ){
1558 for( vv=VIEW_ORIGINAL_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
1559 dset = GET_SESSION_DSET(ss, ff, vv); /* function that needs parent */
1560 /* dset = ss->dsset_xform_table[ff][vv] ; */ /* function that needs parent */
1561
1562 if( ! ISVALID_3DIM_DATASET(dset) ||
1563 dset->anat_parent != NULL ) continue ; /* nothing to do */
1564
1565 if( !do_anats && ISANAT(dset) ) continue ; /* 28 Jul 2003 */
1566
1567 if( DSET_in_global_session(dset) ) continue ; /* 25 Dec 2001 */
1568
1569 pref_dset = GET_SESSION_DSET(ss,apref,vv);
1570
1571 if( ISVALID_3DIM_DATASET(pref_dset) ){ /* if preferred is OK, */
1572 dset->anat_parent = pref_dset ; /* use it here */
1573 }
1574 else {
1575 for( aa=0 ; aa < ss->num_dsset ; aa++ ){ /* search for something, */
1576 anyanat_dset = GET_SESSION_DSET(ss, aa, vv);
1577 if( ISVALID_3DIM_DATASET(anyanat_dset)
1578 && ISANAT(anyanat_dset) ){ /* anything, and use it */
1579 dset->anat_parent = anyanat_dset ; break ;
1580 }
1581 }
1582 }
1583
1584 if( !quiet && dset->anat_parent != NULL && dset->anat_parent != dset ){
1585 if( first ){
1586 first = 0 ;
1587 fprintf(stderr,
1588 "\nDatasets with a 'forced adoption' of anat parent:\n") ;
1589 }
1590 fprintf(stderr,
1591 " %s gets parent %s\n",
1592 DSET_HEADNAME(dset) ,
1593 DSET_HEADNAME(dset->anat_parent) ) ;
1594 }
1595 }
1596 }
1597
1598 EXRETURN ;
1599 }
1600
1601 #undef ALLOW_OLD_EDGIZE
1602 #ifdef ALLOW_OLD_EDGIZE
1603 /*-----------------------------------------------------------------------*/
1604 /* Hollow out the overlay in place -- 21 Mar 2005 - RWCox.
1605 An interior pixel is defined as one whose 4 nearest neighbors are
1606 all nonzero. This editing is done in-place (in the input image).
1607 -------------------------------------------------------------------------*/
1608
mri_edgize(MRI_IMAGE * im)1609 static void mri_edgize( MRI_IMAGE *im )
1610 {
1611 int ii , jj , nx,ny,nxy , joff ;
1612
1613 if( im == NULL ) return ;
1614
1615 nx = im->nx ; ny = im->ny ; nxy = nx * ny ;
1616 if( nx < 3 || ny < 3 ) return ; /* no interior pixels at all?! */
1617
1618 switch( im->kind ){
1619
1620 case MRI_byte:{ /* 09 Dec 2014 */
1621 byte *ajj , *ajm , *ajp , *atemp , *ar ;
1622 ar = MRI_BYTE_PTR(im) ;
1623 atemp = (byte *)malloc(sizeof(byte)*nxy); if( atemp == NULL ) return;
1624 memcpy(atemp,ar,sizeof(byte)*nxy) ;
1625 for( jj=1 ; jj < ny-1 ; jj++ ){
1626 joff = jj * nx ; /* offset into this row */
1627 ajj = atemp + joff ; /* pointer to this row */
1628 ajm = ajj-nx ; /* pointer to last row */
1629 ajp = ajj+nx ; /* pointer to next row */
1630 for( ii=1 ; ii < nx-1 ; ii++ ){
1631 if( ajj[ii] != 0 &&
1632 ajm[ii] != 0 && ajp[ii] != 0 &&
1633 ajj[ii+1] != 0 && ajj[ii-1] != 0 ) ar[ii+joff] = 0 ;
1634 }
1635 }
1636 free((void *)atemp) ;
1637 }
1638 return ;
1639
1640 case MRI_short:{
1641 short *ajj , *ajm , *ajp , *atemp , *ar ;
1642 ar = MRI_SHORT_PTR(im) ;
1643 atemp = (short *)malloc(sizeof(short)*nxy); if( atemp == NULL ) return;
1644 memcpy(atemp,ar,sizeof(short)*nxy) ;
1645 for( jj=1 ; jj < ny-1 ; jj++ ){
1646 joff = jj * nx ; /* offset into this row */
1647 ajj = atemp + joff ; /* pointer to this row */
1648 ajm = ajj-nx ; /* pointer to last row */
1649 ajp = ajj+nx ; /* pointer to next row */
1650 for( ii=1 ; ii < nx-1 ; ii++ ){
1651 if( ajj[ii] != 0 &&
1652 ajm[ii] != 0 && ajp[ii] != 0 &&
1653 ajj[ii+1] != 0 && ajj[ii-1] != 0 ) ar[ii+joff] = 0 ;
1654 }
1655 }
1656 free((void *)atemp) ;
1657 }
1658 return ;
1659
1660 case MRI_rgb:{
1661 rgbyte *ajj , *ajm , *ajp , *atemp , *ar ;
1662 ar = (rgbyte *)MRI_RGB_PTR(im) ;
1663 atemp = (rgbyte *)malloc(sizeof(rgbyte)*nxy); if( atemp == NULL ) return;
1664 memcpy(atemp,ar,sizeof(rgbyte)*nxy) ;
1665 for( jj=1 ; jj < ny-1 ; jj++ ){
1666 joff = jj * nx ;
1667 ajj = atemp + joff ;
1668 ajm = ajj-nx ;
1669 ajp = ajj+nx ;
1670 for( ii=1 ; ii < nx-1 ; ii++ ){
1671 if( !RGBZEQ(ajj[ii]) &&
1672 !RGBZEQ(ajm[ii]) && !RGBZEQ(ajp[ii]) &&
1673 !RGBZEQ(ajj[ii+1]) && !RGBZEQ(ajj[ii-1]) ) RGBZAS(ar[ii+joff]) ;
1674 }
1675 }
1676 free((void *)atemp) ;
1677 }
1678 return ;
1679
1680 }
1681
1682 return ; /* default im->kind case ==> do nothing */
1683 }
1684 #endif
1685
1686 /*-----------------------------------------------------------------------*/
1687
mri_edgize_outer(MRI_IMAGE * im)1688 static void mri_edgize_outer( MRI_IMAGE *im )
1689 {
1690 int ii , jj , nx,ny,nxy , joff ;
1691
1692 if( im == NULL ) return ;
1693
1694 nx = im->nx ; ny = im->ny ; nxy = nx * ny ;
1695 if( nx < 3 || ny < 3 ) return ; /* no interior pixels at all?! */
1696
1697 switch( im->kind ){
1698
1699 default: break ;
1700
1701 case MRI_byte:{ /* 09 Dec 2014 */
1702 byte *ajj , *ajm , *ajp , *atemp , *ar ;
1703 ar = MRI_BYTE_PTR(im) ;
1704 #if 0
1705 (void)THD_mask_remove_isolas( im->nx , im->ny , 1 , ar ) ; /* 02 Nov 2018 */
1706 #endif
1707 atemp = (byte *)calloc(sizeof(byte),nxy); if( atemp == NULL ) return;
1708 for( jj=1 ; jj < ny-1 ; jj++ ){
1709 joff = jj * nx ; /* offset into this row */
1710 ajj = ar + joff ; /* pointer to this row */
1711 ajm = ajj-nx ; /* pointer to last row */
1712 ajp = ajj+nx ; /* pointer to next row */
1713 for( ii=1 ; ii < nx-1 ; ii++ ){
1714 if( ajj[ii] != 0 ){
1715 ajj[ii] = 1 ;
1716 if( ajm[ii] == 0 || ajp[ii] == 0 ||
1717 ajj[ii+1] == 0 || ajj[ii-1] == 0 ) atemp[ii+joff] = 1 ;
1718 }
1719 }
1720 if( ajj[0] != 0 ){ /* deal with left edge of row */
1721 ajj[0] = 1 ;
1722 if( ajm[0] == 0 || ajp[0] == 0 || ajj[1] == 0 ) atemp[joff] = 1 ;
1723 }
1724 if( ajj[nx-1] != 0 ){ /* and right edge */
1725 ajj[nx-1] = 1 ;
1726 if( ajm[nx-1] == 0 || ajp[nx-1] == 0 || ajj[nx-2] == 0 ) atemp[nx-1+joff] = 1 ;
1727 }
1728 }
1729 /* deal with the top row */
1730 joff = 0 ; ajj = ar + joff ; ajp = ajj+nx ;
1731 for( ii=1 ; ii < nx-1 ; ii++ ){
1732 if( ajj[ii] != 0 ){
1733 ajj[ii] = 1 ;
1734 if( ajp[ii] == 0 || ajj[ii+1] == 0 || ajj[ii-1] == 0 ) atemp[ii+joff] = 1 ;
1735 }
1736 }
1737 /* deal with the bottom row */
1738 joff = (ny-1) * nx ; ajj = ar + joff ; ajm = ajj-nx ;
1739 for( ii=1 ; ii < nx-1 ; ii++ ){
1740 if( ajj[ii] != 0 ){
1741 ajj[ii] = 1 ;
1742 if( ajm[ii] == 0 || ajj[ii+1] == 0 || ajj[ii-1] == 0 ) atemp[ii+joff] = 1 ;
1743 }
1744 }
1745 /* we do not deal with the 4 corner points -- let them eat cake */
1746
1747 /* at this point, atemp = 1 only at edge points of clusters */
1748 /* now modify atemp so that only points that are zero AND are
1749 next to an edge point get a nonzero value == 'outer' edge */
1750
1751 for( jj=1 ; jj < ny-1 ; jj++ ){
1752 joff = jj * nx ; /* offset into this row */
1753 ajj = atemp + joff ; /* pointer to this row */
1754 ajm = ajj-nx ; /* pointer to last row */
1755 ajp = ajj+nx ; /* pointer to next row */
1756 for( ii=1 ; ii < nx-1 ; ii++ ){
1757 if( ar[ii+joff] == 0 ){ /* not inside a blob */
1758 if( ajm[ii-1] != 0 || ajm[ii] != 0 || ajm[ii+1] != 0 ||
1759 ajj[ii-1] != 0 || ajj[ii] != 0 || ajj[ii+1] != 0 ||
1760 ajp[ii-1] != 0 || ajp[ii] != 0 || ajp[ii+1] != 0 ) ar[ii+joff] = 2 ;
1761 } else {
1762 ar[ii+joff] = 0 ; /* inside a blob ==> zero out */
1763 }
1764 }
1765 if( ar[joff] == 0 ){ /* left edge of row */
1766 if( ajm[0] != 0 || ajm[0+1] != 0 ||
1767 ajj[0] != 0 || ajj[0+1] != 0 ||
1768 ajp[0] != 0 || ajp[0+1] != 0 ) ar[joff] = 2 ;
1769 } else {
1770 ar[joff] = 0 ;
1771 }
1772 if( ar[nx-1+joff] == 0 ){ /* right edge of row */
1773 if( ajm[nx-2] != 0 || ajm[nx-1] != 0 ||
1774 ajj[nx-2] != 0 || ajj[nx-1] != 0 ||
1775 ajp[nx-2] != 0 || ajp[nx-1] != 0 ) ar[nx-1+joff] = 2 ;
1776 } else {
1777 ar[nx-1+joff] = 0 ;
1778 }
1779 }
1780 /* deal with the bottom row */
1781 joff = 0 ; ajj = atemp + joff ; ajp = ajj+nx ;
1782 for( ii=1 ; ii < nx-1 ; ii++ ){
1783 if( ar[ii+joff] == 0 ){ /* not inside a blob */
1784 if( ajj[ii-1] != 0 || ajj[ii] != 0 || ajj[ii+1] != 0 ||
1785 ajp[ii-1] != 0 || ajp[ii] != 0 || ajp[ii+1] != 0 ) ar[ii+joff] = 2 ;
1786 } else {
1787 ar[ii+joff] = 0 ; /* inside a blob ==> zero out */
1788 }
1789 }
1790 /* deal with the top row */
1791 joff = (ny-1) * nx ; ajj = atemp + joff ; ajm = ajj-nx ;
1792 for( ii=1 ; ii < nx-1 ; ii++ ){
1793 if( ar[ii+joff] == 0 ){ /* not inside a blob */
1794 if( ajm[ii-1] != 0 || ajm[ii] != 0 || ajm[ii+1] != 0 ||
1795 ajj[ii-1] != 0 || ajj[ii] != 0 || ajj[ii+1] != 0 ) ar[ii+joff] = 2 ;
1796 } else {
1797 ar[ii+joff] = 0 ; /* inside a blob ==> zero out */
1798 }
1799 }
1800
1801 free(atemp) ;
1802 }
1803 return ; /* end of MRI_byte */
1804
1805 } /* end of switching */
1806
1807 return ; /* default im->kind case ==> do nothing */
1808 }
1809
1810 /*-----------------------------------------------------------------------*/
1811 /* Convert a paned color bar to a continuous color scale,
1812 for use with AFNI_newnewfunc_overlay [17 Jul 2019 - RWC]
1813 *//*---------------------------------------------------------------------*/
1814
1815 #define NPANE_SUPERBIG 10001
1816
AFNI_panes_to_bigcolor(MCW_pbar * pbar,rgbyte * bigcolor,int nbig)1817 void AFNI_panes_to_bigcolor( MCW_pbar *pbar , rgbyte *bigcolor , int nbig )
1818 {
1819 float *pval ;
1820 int *ovind , npan ;
1821 byte *r_ov , *g_ov , *b_ov ;
1822 rgbyte *col ; float *val , eps; int neq,ii,jj,kk ;
1823
1824 ENTRY("AFNI_panes_to_bigcolor") ;
1825
1826 if( pbar == NULL || bigcolor == NULL ) EXRETURN ;
1827
1828 if( nbig < 16 ) nbig = NPANE_BIG ;
1829 else if( nbig > NPANE_SUPERBIG ) nbig = NPANE_SUPERBIG ;
1830
1831 pval = pbar->pval ; /* [i] = bot of panel #i, i=0..npan */
1832 ovind = pbar->ov_index ; /* [i] = color panel #i , i=0..npan-1 */
1833 npan = pbar->num_panes ; /* number of panes (duh) */
1834 r_ov = pbar->dc->ovc->r_ov ; /* [j] = R value of color #j */
1835 g_ov = pbar->dc->ovc->g_ov ; /* [j] = G value of color #j */
1836 b_ov = pbar->dc->ovc->b_ov ; /* [j] = B value of color #j */
1837
1838 eps = 0.10f * fabsf(pval[0]-pval[npan]) / (float)nbig ;
1839 neq = 2 * npan ;
1840 col = (rgbyte *)malloc(sizeof(rgbyte)*neq) ;
1841 val = (float * )malloc(sizeof(float) *neq) ;
1842
1843 jj = ovind[0] ; val[0] = pval[0] ;
1844 col[0].r = r_ov[jj] ; col[0].g = g_ov[jj] ; col[0].b = b_ov[jj] ;
1845 for( kk=ii=1 ; ii < npan ; ii++ ){
1846 jj = ovind[ii-1] ; val[kk] = pval[ii]+eps ;
1847 col[kk].r = r_ov[jj] ; col[kk].g = g_ov[jj] ; col[kk].b = b_ov[jj] ; kk++ ;
1848 jj = ovind[ii] ; val[kk] = pval[ii]-eps ;
1849 col[kk].r = r_ov[jj] ; col[kk].g = g_ov[jj] ; col[kk].b = b_ov[jj] ; kk++ ;
1850 }
1851 jj = ovind[npan-1] ; val[kk] = pval[npan] ;
1852 col[kk].r = r_ov[jj] ; col[kk].g = g_ov[jj] ; col[kk].b = b_ov[jj] ;
1853
1854 PBAR_fill_bigmap( neq , val , col , bigcolor , nbig ) ;
1855
1856 free(val) ; free(col) ;
1857 EXRETURN ;
1858 }
1859
1860 /*-----------------------------------------------------------------------*/
1861
1862 static int reject_zero = 0 ;
1863
1864 #undef ZREJ
1865 #define ZREJ(vvv) (reject_zero && (vvv)==0) /* 20 Apr 2005 */
1866
1867 #undef THBOT
1868 #undef THTOP
1869 #undef THBIG
1870 #define THBIG 1.e+37f
1871 #define THBOT(t) ((thrsign==0 || thrsign==2) ? (-(t)) : (-THBIG))
1872 #define THTOP(t) ((thrsign==0 || thrsign==1) ? (t) : (THBIG))
1873
1874 /*-----------------------------------------------------------------------*/
1875 /*! Make a functional overlay -- very simple routine at present;
1876 n = slice index , br_fim = data structure to extract slice from.
1877 Note that imseq requires that the overlay be an image of shorts.
1878 This routine requires that the function and threshold images be bytes,
1879 shorts, or floats (complex-valued functional images are not supported).
1880 (The underlay image may be any legal type; this image is not used here.)
1881 -------------------------------------------------------------------------*/
1882
AFNI_func_overlay(int n,FD_brick * br_fim)1883 MRI_IMAGE * AFNI_func_overlay( int n , FD_brick *br_fim )
1884 {
1885 Three_D_View *im3d ;
1886 MRI_IMAGE *im_thr , *im_fim , *im_ov , *im_noved=NULL ;
1887 short *ar_ov ;
1888 short fim_ovc[NPANE_MAX+1] ; /* for the 'old' discrete pane colorization */
1889 float fim_thr[NPANE_MAX+1] ;
1890 rgbyte pane_bigcolor[NPANE_SUPERBIG] ;
1891 int npix , ii , lp , num_lp , ival , nbig ;
1892 float scale_factor , scale_thr ;
1893 MCW_pbar *pbar ;
1894 int simult_thr , need_thr ;
1895 int thrsign ; /* 08 Aug 2007 */
1896
1897 ENTRY("AFNI_func_overlay") ;
1898
1899 /* sanity check */
1900
1901 if( br_fim == NULL || n < 0 ) RETURN(NULL) ; /* nothing to do */
1902
1903 im3d = (Three_D_View *) br_fim->parent ;
1904 if( !IM3D_OPEN(im3d) ) RETURN(NULL) ; /* should not happen */
1905
1906 pbar = im3d->vwid->func->inten_pbar ;
1907
1908 /* 22 May 2009: check if functional dataset is ready */
1909
1910 if( !ISVALID_DSET(im3d->fim_now) ){
1911 AFNI_SEE_FUNC_OFF(im3d) ; RETURN(NULL) ;
1912 }
1913
1914 reject_zero = VEDIT_good(im3d->vedset) || /* 09 Dec 2014 */
1915 !AFNI_yesenv("AFNI_OVERLAY_ZERO") ; /* 20 Apr 2005 */
1916
1917 ival = im3d->vinfo->thr_index ; /* threshold sub-brick index */
1918
1919 /* get the component images */
1920
1921 ival = im3d->vinfo->thr_index ; /* threshold sub-brick index */
1922 LOAD_DSET_VIEWS(im3d) ; /* 02 Nov 1996 */
1923
1924 need_thr = (im3d->vinfo->func_threshold > 0.0) && im3d->vinfo->thr_onoff ;
1925 thrsign = im3d->vinfo->thr_sign ; /* 08 Aug 2007 */
1926
1927 /* 29 Mar 2005: make sure statistics of overlay dataset are ready */
1928
1929 if( !DSET_LOADED(im3d->fim_now) ){
1930 DSET_load( im3d->fim_now ) ;
1931 if( !DSET_LOADED(im3d->fim_now) && im3d->fim_now->warp_parent != NULL )
1932 DSET_load( im3d->fim_now->warp_parent ) ;
1933 im3d->vinfo->stats_func_ok = im3d->vinfo->arang_func_ok = 0 ;
1934 }
1935 if( !im3d->vinfo->stats_func_ok || !im3d->vinfo->arang_func_ok
1936 || (!im3d->vinfo->stats_thresh_ok && need_thr) ){
1937 DSET_load( im3d->fim_now ) ;
1938 if( !DSET_LOADED(im3d->fim_now) && im3d->fim_now->warp_parent != NULL )
1939 DSET_load( im3d->fim_now->warp_parent ) ;
1940 AFNI_reset_func_range( im3d ) ;
1941 }
1942
1943 /* get the threshold image? */
1944
1945 if( need_thr ){
1946 STATUS("fetch im_thr") ;
1947 AFNI_set_ignore_vedit(1) ; /* 20 Oct 2016 */
1948 im_thr = FD_warp_to_mri( n , ival , br_fim ) ;
1949 AFNI_set_ignore_vedit(0) ;
1950 } else{
1951 STATUS("don't need im_thr") ;
1952 im_thr = NULL ;
1953 }
1954
1955 #if 1
1956 scale_thr = 1.0f ; /* FD_warp_to_mri() already scales this */
1957 #else
1958 scale_thr = DSET_BRICK_FACTOR(br_fim->dset,ival) ;
1959 if( scale_thr == 0.0f ) scale_thr = 1.0f ;
1960 #endif
1961
1962 /* get function image */
1963
1964 { int ind ;
1965
1966 ind = im3d->vinfo->fim_index ;
1967 if( ind >= DSET_NVALS(br_fim->dset) )
1968 ind = DSET_NVALS(br_fim->dset) - 1 ;
1969
1970 STATUS("fetch im_fim") ;
1971 im_fim = FD_warp_to_mri( n, ind, br_fim ) ; /* get func image */
1972 scale_factor = FIM_RANGE(im3d) ;
1973 if( scale_factor == 0.0 || PBAR_FULLRANGE ) scale_factor = 1.0f ;
1974
1975 /* Get non-volume-edited image as well, maybe [05 Nov 2018] */
1976
1977 if( im_fim != NULL &&
1978 VEDIT_good(im3d->vedset) &&
1979 im3d->vinfo->thr_use_alpha && pbar->bigmode ){
1980
1981 AFNI_set_ignore_vedit(1) ;
1982 STATUS("fetch im_noved") ;
1983 im_noved = FD_warp_to_mri( n , ind , br_fim ) ;
1984 AFNI_set_ignore_vedit(0) ;
1985 if( mri_equal(im_fim,im_noved) ){ mri_free(im_noved); im_noved=NULL; }
1986 }
1987
1988 /* set OLay label string, for display as text in GUI */
1989
1990 AFNI_set_valabel( br_fim , n ,
1991 (im_noved != NULL) ? im_noved : im_fim ,
1992 im3d->vinfo->func_val ) ;
1993 }
1994
1995 /* 04 Mar 2003: convert thresh to float if its datum is unacceptable */
1996 /* 21 Dec 2004: also allow RGB images as threshold via this mechanism :) */
1997
1998 if( im_thr != NULL && !(im_thr->kind == MRI_float ||
1999 im_thr->kind == MRI_short ||
2000 im_thr->kind == MRI_byte ) ){
2001
2002 MRI_IMAGE *qim = mri_to_float(im_thr) ;
2003 STATUS("converted im_thr to floats") ;
2004 mri_free(im_thr) ; im_thr = qim ; scale_thr = 1.0f ;
2005 }
2006
2007 /* set Thr label string, for display in GUI */
2008
2009 AFNI_set_valabel( br_fim , n , im_thr , im3d->vinfo->thr_val ) ;
2010
2011 /* if component images not good, quit now */
2012
2013 if( im_fim == NULL ){
2014 STATUS("couldn't get Func image!") ;
2015 KILL_1MRI(im_thr) ; RETURN(NULL) ;
2016 }
2017
2018 /* 15 Apr 2002: allow overlay image to be pure RBG (no colorscale) */
2019 /* 20 Dec 2004: allow thresholding of RGB overlays */
2020
2021 if( im_fim->kind == MRI_rgb ){ /* 15 Apr 2002: RGB overlays */
2022
2023 if( im_thr != NULL && im_thr != im_fim ){ /* 20 Dec 2004 */
2024 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2025 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2026 mri_threshold( thb,tht , im_thr , im_fim ) ; /* in place */
2027 }
2028
2029 /* 27 Apr 2005: transform RGB func image in place? */
2030
2031 mri_rgb_transform_nD( im_fim, 0, im3d->vwid->func->pbar_transform0D_func );
2032 mri_rgb_transform_nD( im_fim, 2, im3d->vwid->func->pbar_transform2D_func );
2033
2034 if( im_thr != im_fim ) KILL_1MRI(im_thr) ; /* toss the trash */
2035 RETURN(im_fim) ;
2036 }
2037
2038 /* must be a scalar image at this point */
2039
2040 if( ! AFNI_GOOD_FUNC_DTYPE(im_fim->kind) ){ /* should never happen! */
2041 MRI_IMAGE *qim = mri_to_float(im_fim) ; /* (but fix it if it does) */
2042 STATUS("had to convert im_fim to floats?????") ;
2043 mri_free(im_fim) ; im_fim = qim ;
2044 if( im_noved != NULL ){ mri_free(im_noved); im_noved=NULL; }
2045 }
2046
2047 /* 15 Jun 2000: transformation of functional image? */
2048
2049 if( im3d->vwid->func->pbar_transform0D_func != NULL ){
2050 MRI_IMAGE *tim = mri_to_float(im_fim) ;
2051 STATUS("transform0D of im_fim") ;
2052 #if 0
2053 im3d->vwid->func->pbar_transform0D_func( tim->nvox , MRI_FLOAT_PTR(tim) ) ;
2054 #else
2055 AFNI_CALL_0D_function( im3d->vwid->func->pbar_transform0D_func ,
2056 tim->nvox , MRI_FLOAT_PTR(tim) ) ;
2057 #endif
2058 if( im_fim != im_thr ) mri_free(im_fim) ;
2059 im_fim = tim ;
2060
2061 if( im_noved != NULL ){
2062 tim = mri_to_float(im_noved) ;
2063 AFNI_CALL_0D_function( im3d->vwid->func->pbar_transform0D_func ,
2064 tim->nvox , MRI_FLOAT_PTR(tim) ) ;
2065 mri_free(im_noved) ; im_noved = tim ;
2066 }
2067 }
2068
2069 if( im3d->vwid->func->pbar_transform2D_func != NULL ){
2070 MRI_IMAGE *tim = mri_to_float(im_fim) ;
2071 STATUS("transform2D of im_fim") ;
2072 #if 0
2073 im3d->vwid->func->pbar_transform2D_func( tim->nx, tim->ny,
2074 tim->dx, tim->dy,
2075 MRI_FLOAT_PTR(tim) ) ;
2076 #else
2077 AFNI_CALL_2D_function( im3d->vwid->func->pbar_transform2D_func ,
2078 tim->nx, tim->ny, tim->dx, tim->dy, MRI_FLOAT_PTR(tim) ) ;
2079 #endif
2080 if( im_fim != im_thr ) mri_free(im_fim) ;
2081 im_fim = tim ;
2082
2083 if( im_noved != NULL ){
2084 tim = mri_to_float(im_noved) ;
2085 AFNI_CALL_2D_function( im3d->vwid->func->pbar_transform2D_func ,
2086 tim->nx, tim->ny, tim->dx, tim->dy, MRI_FLOAT_PTR(tim) ) ;
2087 mri_free(im_noved) ; im_noved = tim ;
2088 }
2089 }
2090
2091 /**---------- 30 Jan 2003:
2092 if the pbar is in "big" mode,
2093 then create an RGB overlay in a separate function ----------**/
2094
2095 /* flag bits for using the newnew function (NFO = New Function Overlay?) */
2096
2097 #define NFO_ZBELOW_MASK 1
2098 #define NFO_ZABOVE_MASK 2
2099 #define NFO_ALIN_MASK 4 /* alpha = linear fade */
2100 #define NFO_AQUA_MASK 8 /* alpha = quadratic fade */
2101 #define NFO_USE_BOXED 16 /* not Boxster */
2102 #define NFO_POS_MASK 256
2103
2104 #define ALWAYS_USE_BIGMODE 1 /* use the newnew function always [17 Jul 2019] */
2105
2106 if( ALWAYS_USE_BIGMODE || pbar->bigmode ){ /*--- "continuous" colorscale --*/
2107
2108 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2109 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2110 int zbelow=0 , zabove=0 , flags ;
2111 rgbyte *bigcol=NULL ;
2112
2113 if( PRINT_TRACING && im_thr != NULL )
2114 { char str[256] ; float tmax ;
2115 sprintf(str,"im_thr: nx=%d ny=%d kind=%s",
2116 im_thr->nx,im_thr->ny,MRI_TYPE_NAME(im_thr)) ; STATUS(str) ;
2117 tmax = (float)mri_maxabs(im_thr) ;
2118 sprintf(str,"maxabs(im_thr)=%g scale_thr=%g thresh=%g",tmax,scale_thr,thresh);
2119 STATUS(str) ;
2120 sprintf(str,"func_threshold=%g func_thresh_top=%g cont_perc_thr=%d",
2121 im3d->vinfo->func_threshold,im3d->vinfo->func_thresh_top,
2122 im3d->cont_perc_thr);
2123 STATUS(str);
2124 }
2125
2126 /* Always use AFNI_newnewfunc_overlay() [05 Nov 2018] */
2127
2128 if( !pbar->bigmode ){ /* manufacture a 'continuous' colormap */
2129 #if 1
2130 nbig = NPANE_SUPERBIG ; /* this reduces inter-pane weird artifacts */
2131 #else
2132 nbig = NPANE_BIG ;
2133 #endif
2134 AFNI_panes_to_bigcolor( pbar , pane_bigcolor , nbig ) ;
2135 bigcol = pane_bigcolor ;
2136 } else {
2137 if( pbar->big30 ) reject_zero = VEDIT_good(im3d->vedset) ;
2138 if( pbar->big31 ){ /* Feb 2012 */
2139 zbelow = !pbar->big32 ; zabove = !pbar->big30 ;
2140 } else {
2141 zbelow = (pbar->bigbot == 0.0f) ;
2142 }
2143 bigcol = pbar->bigcolor ; nbig = NPANE_BIG ;
2144 }
2145
2146 /* set various rendering flags */
2147
2148 flags = zbelow * NFO_ZBELOW_MASK + zabove * NFO_ZABOVE_MASK ;
2149
2150 if( im3d->vinfo->thr_use_alpha ){ /* alpha fading? */
2151 int mm = im3d->vwid->func->thr_alpha_av->ival ; /* 28 Jun 2021 */
2152 flags |= (mm == 0 ) ? NFO_ALIN_MASK : NFO_AQUA_MASK ; /* fade method */
2153 }
2154
2155 if( im3d->vinfo->use_posfunc ) flags |= NFO_POS_MASK ; /* pos only FIM? */
2156 if( im3d->vinfo->thr_use_boxed ) flags |= NFO_USE_BOXED ; /* boxing day? */
2157
2158 /* Is there in truth no beauty? */
2159
2160 im_ov = AFNI_newnewfunc_overlay( im_thr , thb,tht ,
2161 im_fim , im_noved ,
2162 scale_factor*pbar->bigbot ,
2163 scale_factor*pbar->bigtop ,
2164 nbig , bigcol , flags ,
2165 im3d->vinfo->thr_alpha_floor , im3d->dc ) ;
2166 goto CLEANUP ;
2167 } /*-------------------- end of the new way of doing things ---------------*/
2168
2169 #if (ALWAYS_USE_BIGMODE == 0) /*------ cast aside code [17 Jul 2019] --------*/
2170
2171 /** create output image the old way (indexes into overlay colors) **/
2172
2173 npix = im_fim->nx * im_fim->ny ;
2174 im_ov = mri_new( im_fim->nx , im_fim->ny , MRI_short ) ;
2175 ar_ov = MRI_SHORT_PTR( im_ov ) ;
2176
2177 /* set overlay colors */
2178
2179 num_lp = pbar->num_panes ;
2180
2181 for( lp=0 ; lp < num_lp ; lp++ ) fim_ovc[lp] = pbar->ov_index[lp] ;
2182
2183 fim_ovc[num_lp] = (im3d->vinfo->use_posfunc) ? (0) : (fim_ovc[num_lp-1]) ;
2184
2185 /** process im_fim into overlay, depending on data type **/
2186
2187 simult_thr = (im_thr != NULL) && /* do threshold */
2188 (im3d->vinfo->func_threshold > 0.0) && /* simultaneously? */
2189 (im_fim->kind == im_thr->kind) ; /* (July 15, 1996) */
2190
2191 switch( im_fim->kind ){
2192
2193 default: /* should not happen! */
2194 if( im_thr != im_fim ) mri_free(im_thr) ;
2195 mri_free(im_fim) ; mri_free(im_ov) ; mri_free(im_noved) ;
2196 STATUS("bad im_fim->kind!") ;
2197 RETURN(NULL) ;
2198
2199 case MRI_short:{
2200 short *ar_fim = MRI_SHORT_PTR(im_fim) ;
2201
2202 for( lp=0 ; lp < num_lp ; lp++ )
2203 fim_thr[lp] = scale_factor * pbar->pval[lp+1] ;
2204
2205 if( simult_thr ){
2206 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2207 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2208 short *ar_thr = MRI_SHORT_PTR(im_thr) ;
2209 for( ii=0 ; ii < npix ; ii++ ){
2210 if( (ar_thr[ii] > thb && ar_thr[ii] < tht) || ZREJ(ar_fim[ii]) ){
2211 ar_ov[ii] = 0 ;
2212 } else {
2213 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2214 ar_ov[ii] = fim_ovc[lp] ;
2215 }
2216 }
2217 } else {
2218 for( ii=0 ; ii < npix ; ii++ ){
2219 if( ZREJ(ar_fim[ii]) ){
2220 ar_ov[ii] = 0 ;
2221 } else {
2222 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2223 ar_ov[ii] = fim_ovc[lp] ;
2224 }
2225 }
2226 }
2227 }
2228 break ;
2229
2230 case MRI_byte:{
2231 byte *ar_fim = MRI_BYTE_PTR(im_fim) ;
2232
2233 for( lp=0 ; lp < num_lp ; lp++ )
2234 fim_thr[lp] = (pbar->pval[lp+1] > 0.0) ? scale_factor*pbar->pval[lp+1]
2235 : 0.0 ;
2236
2237 if( simult_thr ){
2238 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2239 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2240 byte *ar_thr = MRI_BYTE_PTR(im_thr) ;
2241
2242 for( ii=0 ; ii < npix ; ii++ ){
2243 if( ar_thr[ii] < tht || ZREJ(ar_fim[ii]) ){ /* assuming thb <= 0 */
2244 ar_ov[ii] = 0 ;
2245 } else {
2246 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2247 ar_ov[ii] = fim_ovc[lp] ;
2248 }
2249 }
2250 } else {
2251 for( ii=0 ; ii < npix ; ii++ ){
2252 if( ZREJ(ar_fim[ii]) ){
2253 ar_ov[ii] = 0 ;
2254 } else {
2255 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2256 ar_ov[ii] = fim_ovc[lp] ;
2257 }
2258 }
2259 }
2260 }
2261 break ;
2262
2263 case MRI_float:{
2264 float *ar_fim = MRI_FLOAT_PTR(im_fim) ;
2265
2266 for( lp=0 ; lp < num_lp ; lp++ )
2267 fim_thr[lp] = scale_factor * pbar->pval[lp+1] ;
2268
2269 if( simult_thr ){
2270 float thresh = get_3Dview_func_thresh(im3d,1) ;
2271 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2272 float *ar_thr = MRI_FLOAT_PTR(im_thr) ;
2273
2274 for( ii=0 ; ii < npix ; ii++ ){
2275 if( (ar_thr[ii] > thb && ar_thr[ii] < tht) || ZREJ(ar_fim[ii]) ){
2276 ar_ov[ii] = 0 ;
2277 } else {
2278 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2279 ar_ov[ii] = fim_ovc[lp] ;
2280 }
2281 }
2282 } else {
2283 for( ii=0 ; ii < npix ; ii++ ){
2284 if( ZREJ(ar_fim[ii]) ){
2285 ar_ov[ii] = 0 ;
2286 } else {
2287 for( lp=0 ; lp < num_lp && ar_fim[ii] < fim_thr[lp] ; lp++ ) ; /*nada*/
2288 ar_ov[ii] = fim_ovc[lp] ;
2289 }
2290 }
2291 }
2292 }
2293 break ;
2294 }
2295
2296 /** if have yet to do threshold, clip the overlay **/
2297
2298 if( im_thr != NULL && im3d->vinfo->func_threshold > 0.0 && !simult_thr ){
2299
2300 switch( im_thr->kind ){
2301
2302 case MRI_short:{
2303 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2304 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2305 short *ar_thr = MRI_SHORT_PTR(im_thr) ;
2306
2307 for( ii=0 ; ii < npix ; ii++ )
2308 if( ar_thr[ii] > thb && ar_thr[ii] < tht ) ar_ov[ii] = 0 ;
2309 }
2310 break ;
2311
2312 case MRI_byte:{
2313 float thresh = get_3Dview_func_thresh(im3d,1) / scale_thr ;
2314 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2315 byte *ar_thr = MRI_BYTE_PTR(im_thr) ;
2316
2317 for( ii=0 ; ii < npix ; ii++ ) /* assuming thb <= 0 */
2318 if( ar_thr[ii] < tht ) ar_ov[ii] = 0 ;
2319 }
2320 break ;
2321
2322 case MRI_float:{
2323 float thresh = get_3Dview_func_thresh(im3d,1) ;
2324 float thb=THBOT(thresh) , tht=THTOP(thresh) ; /* 08 Aug 2007 */
2325 float *ar_thr = MRI_FLOAT_PTR(im_thr) ;
2326
2327 for( ii=0 ; ii < npix ; ii++ )
2328 if( ar_thr[ii] > thb && ar_thr[ii] < tht ) ar_ov[ii] = 0 ;
2329 }
2330 break ;
2331 }
2332 }
2333
2334 /* delete the overlay if it contains nothing */
2335
2336 for( ii=0 ; ii < npix ; ii++ ) if( ar_ov[ii] != 0 ) break ;
2337 if( ii == npix ) KILL_1MRI(im_ov) ; /* no nonzero values --> no overlay */
2338
2339 #endif /*------------------------ ALWAYS_USE_BIGMODE -------------------------*/
2340
2341 /** time to trot, Bwana **/
2342
2343 CLEANUP:
2344 if( im_thr != NULL && im_thr != im_fim ) mri_free( im_thr ) ;
2345 mri_free( im_fim ) ; mri_free( im_noved ) ;
2346
2347 #ifdef ALLOW_OLD_EDGIZE
2348 /* 21 Mar 2005: Hollow out overlay? */
2349 if( AFNI_yesenv("AFNI_EDGIZE_OVERLAY") ) mri_edgize(im_ov) ;
2350 #endif
2351
2352 RETURN(im_ov) ;
2353 }
2354
2355 #if 0 /******************* OBSOLETE FUNCTION - do not compile ***********/
2356 /*-----------------------------------------------------------------------*/
2357 /*! Make a functional overlay the new way (30 Jan 2003):
2358 - im_thr = threshold image (may be NULL)
2359 - thbot = pixels with values in im_thr in range (thbot..thtop)
2360 - thtop = don't get overlay
2361 - im_fim = image to make overlay from (may not be NULL)
2362 - fimbot = pixel value to map to fimcolor[0]
2363 - fimtop = pixel value to map to fimcolor[NPANE_BIG-1]
2364
2365 [08 Aug 2007 -- change 'thresh' to 'thbot,thtop']
2366 -------------------------------------------------------------------------*/
2367
2368 MRI_IMAGE * AFNI_newfunc_overlay( MRI_IMAGE *im_thr , float thbot,float thtop,
2369 MRI_IMAGE *im_fim ,
2370 float fimbot, float fimtop, rgbyte *fimcolor,
2371 int flags )
2372 {
2373 MRI_IMAGE *im_ov ;
2374 byte *ovar ;
2375 int ii , npix , jj ;
2376 float fac , val ;
2377 int dothr = (thbot < thtop) ; /* 08 Aug 2007 */
2378
2379 int zbelow = (flags & NFO_ZBELOW_MASK) != 0 ; /* Feb 2012 */
2380 int zabove = (flags & NFO_ZABOVE_MASK) != 0 ;
2381
2382 byte *bfim=NULL ; short *sfim=NULL ; float *ffim=NULL ; int kk ;
2383
2384 ENTRY("AFNI_newfunc_overlay") ;
2385
2386 if( im_fim == NULL || fimbot >= fimtop || fimcolor == NULL ) RETURN(NULL) ;
2387
2388 /* create output image */
2389
2390 STATUS("create output image") ;
2391 im_ov = mri_new_conforming( im_fim , MRI_rgb ) ;
2392 ovar = MRI_RGB_PTR(im_ov) ;
2393 npix = im_ov->nvox ;
2394 fac = NPANE_BIG / (fimtop-fimbot) ; /* scale from data value to color index */
2395
2396 kk = (int)im_fim->kind ;
2397 switch( kk ){
2398 default: mri_free(im_ov) ; RETURN(NULL) ; /* should never happen! */
2399 case MRI_short: sfim = MRI_SHORT_PTR(im_fim) ; break ;
2400 case MRI_byte : bfim = MRI_BYTE_PTR (im_fim) ; break ;
2401 case MRI_float: ffim = MRI_FLOAT_PTR(im_fim) ; break ;
2402 }
2403
2404 STATUS("colorization") ;
2405 for( ii=0 ; ii < npix ; ii++ ){
2406 if( kk == MRI_byte ) val = (float)bfim[ii] ;
2407 else if( kk == MRI_short ) val = (float)sfim[ii] ;
2408 else val = ffim[ii] ;
2409 if( ZREJ(val) || (zabove && val > fimtop) || (zbelow && val < fimbot) ) continue ;
2410 jj = (int)( fac*(fimtop-val) ) ;
2411 if( jj < 0 ) jj = 0 ; else if( jj > NPANE_BIG1 ) jj = NPANE_BIG1 ;
2412 ovar[3*ii ] = fimcolor[jj].r ;
2413 ovar[3*ii+1] = fimcolor[jj].g ;
2414 ovar[3*ii+2] = fimcolor[jj].b ;
2415 }
2416
2417 /** now apply threshold, if any **/
2418
2419 if( dothr && im_thr != NULL ){
2420 STATUS("thresholdization") ;
2421 switch( im_thr->kind ){
2422
2423 case MRI_short:{
2424 register float thb=thbot , tht=thtop ;
2425 register short *ar_thr = MRI_SHORT_PTR(im_thr) ;
2426 for( ii=0 ; ii < npix ; ii++ ){
2427 if( ar_thr[ii] > thb && ar_thr[ii] < tht )
2428 ovar[3*ii] = ovar[3*ii+1] = ovar[3*ii+2] = 0 ;
2429 }
2430 }
2431 break ;
2432
2433 case MRI_byte:{
2434 register float thb=thbot , tht=thtop ;
2435 register byte *ar_thr = MRI_BYTE_PTR(im_thr) ;
2436 for( ii=0 ; ii < npix ; ii++ ) /* assuming thb <= 0 always */
2437 if( ar_thr[ii] < tht )
2438 ovar[3*ii] = ovar[3*ii+1] = ovar[3*ii+2] = 0 ;
2439 }
2440 break ;
2441
2442 case MRI_float:{
2443 register float thb=thbot , tht=thtop ;
2444 register float *ar_thr = MRI_FLOAT_PTR(im_thr) ;
2445 for( ii=0 ; ii < npix ; ii++ )
2446 if( ar_thr[ii] > thb && ar_thr[ii] < tht )
2447 ovar[3*ii] = ovar[3*ii+1] = ovar[3*ii+2] = 0 ;
2448 }
2449 break ;
2450 }
2451 }
2452
2453 RETURN(im_ov) ;
2454 }
2455 #endif /***************** OBSOLETE FUNCTION ********************/
2456
2457 /*-----------------------------------------------------------------------*/
2458 /* This function is only used to alpha fade the pbar image.
2459 However, the macros below are used in AFNI_newnewfunc_overlay().
2460 *//*---------------------------------------------------------------------*/
2461
2462 /* th = threshold at this voxel
2463 fac = scales threshold to be between 0 and 1 */
2464
2465 #define ALIN(th,fac) (th*fac) /* linear fading */
2466 #define AQUA(th,fac) (ALIN(th,fac)*ALIN(th,fac)) /* quadratic fading */
2467
2468 /* alcode is internal to functions that use ALFA */
2469
2470 #define ALFA(th,fac) (alcode==1) ? 255.0f*ALIN(th,fac)+af \
2471 :(alcode==2) ? 255.0f*AQUA(th,fac)+af : 0.0f
2472
2473 /* convert alpha to a byte value for opacity '.a' in RGBA;
2474 max value set to 222 to try to make sure there is some
2475 distinction between above-threshold voxels and below threshold rebel scum */
2476
2477 #define ALFABYTE(xx) ( ((xx) < 0.0) ? (byte)0 \
2478 : ((xx) > 222.0) ? (byte)222 : (byte)rintf(xx) )
2479
2480
AFNI_alpha_fade_mri(Three_D_View * im3d,MRI_IMAGE * im)2481 void AFNI_alpha_fade_mri( Three_D_View *im3d , MRI_IMAGE *im )
2482 {
2483 float af,th,fi,aa,rf,bf,gf ; int ii,jj,kk,nx,ny ;
2484 byte *iar ;
2485 const int alcode=1 ; /* linear fading across color bar image */
2486
2487 if( !IM3D_OPEN(im3d) || im == NULL || im->kind != MRI_rgb ) return ;
2488 if( im3d->vinfo->thr_use_alpha <= 0 ) return ;
2489
2490 af = 255.0f*im3d->vinfo->thr_alpha_floor ;
2491 nx = im->nx ; if( nx < 2 ) return ;
2492 ny = im->ny ;
2493 fi = 0.995f/(nx-1) ;
2494 iar = MRI_RGB_PTR(im) ;
2495
2496 for( kk=jj=0 ; jj < ny ; jj++ ){
2497 for( ii=0 ; ii < nx ; ii++,kk+=3 ){
2498 if( ii==0 ) continue ;
2499 th = 1.0f - ii*fi ;
2500 aa = ALFA(th,1.0f) ;
2501 if( aa < 255.0f ){
2502 rf = iar[kk] ; gf = iar[kk+1] ; bf = iar[kk+2] ;
2503 if( rf== 0.0f && gf== 0.0f && bf== 0.0f ) continue ; /* don't alter */
2504 if( rf==255.0f && gf==255.0f && bf==255.0f ) continue ; /* black or white */
2505 rf = (aa/255.0f)*rf + (255.0f-aa) ; iar[kk ] = BYTEIZE(rf) ;
2506 gf = (aa/255.0f)*gf + (255.0f-aa) ; iar[kk+1] = BYTEIZE(gf) ;
2507 bf = (aa/255.0f)*bf + (255.0f-aa) ; iar[kk+2] = BYTEIZE(bf) ;
2508 }
2509 }
2510 }
2511 return ;
2512 }
2513
2514 /*-----------------------------------------------------------------------*/
2515 /*! Make a functional overlay the new new way (08 Dec 2014):
2516 - im_thr = threshold image (may be NULL)
2517 - thbot = pixels with values in im_thr in range (thbot..thtop)
2518 - thtop = get translucent overlay values
2519 - im_fim = image to make overlay from (may not be NULL)
2520 - fimbot = pixel value to map to fimcolor[0]
2521 - fimtop = pixel value to map to fimcolor[nfimc-1]
2522 - nfimc = number of colors in the fimcolor array
2523 - fimcolor = continuous color scale
2524 ** Changed Nov 2018 to allow a mixture of the volume edited
2525 FIM (im_fim) and the non-volume edited FIM (im_noved) to
2526 determine color and alpha.
2527 ** The output image is in RGBA format.
2528 -------------------------------------------------------------------------*/
2529
AFNI_newnewfunc_overlay(MRI_IMAGE * im_thr,float thbot,float thtop,MRI_IMAGE * im_fim,MRI_IMAGE * im_noved,float fimbot,float fimtop,int nfimc,rgbyte * fimcolor,int flags,float alpha_floor,MCW_DC * dc)2530 MRI_IMAGE * AFNI_newnewfunc_overlay( MRI_IMAGE *im_thr , float thbot,float thtop,
2531 MRI_IMAGE *im_fim , MRI_IMAGE *im_noved ,
2532 float fimbot, float fimtop,
2533 int nfimc , rgbyte *fimcolor,
2534 int flags , float alpha_floor , MCW_DC *dc )
2535 {
2536 MRI_IMAGE *im_ov ;
2537 rgba *ovar ;
2538 int ii , npix , jj , nfimc1 = nfimc-1 ;
2539 float fac , val , vval ;
2540 int dothr = (thbot < thtop) && (im_thr != NULL); /* 08 Aug 2007 */
2541 int alcode=0 ; /* 09 Dec 2014 */
2542 int do_pos = (flags & NFO_POS_MASK) != 0 ; /* 12 Dec 2014 */
2543 int do_box = (flags & NFO_USE_BOXED)!= 0 ; /* 02 Nov 2018 */
2544
2545 int zbelow = (flags & NFO_ZBELOW_MASK) != 0 ; /* Feb 2012 */
2546 int zabove = (flags & NFO_ZABOVE_MASK) != 0 ;
2547 byte *bfim=NULL ; short *sfim=NULL ; float *ffim=NULL ; int kf ;
2548 byte *bvim=NULL ; short *svim=NULL ; float *fvim=NULL ;
2549
2550 ENTRY("AFNI_newnewfunc_overlay") ;
2551
2552 if( im_fim == NULL || fimbot >= fimtop || fimcolor == NULL || nfimc < 2 ) RETURN(NULL) ;
2553
2554 /* create output image */
2555
2556 STATUS("create output image") ;
2557 im_ov = mri_new_conforming( im_fim , MRI_rgba ) ; /* zero filled */
2558 ovar = MRI_RGBA_PTR(im_ov) ; /* our job is to fill this up */
2559 npix = im_ov->nvox ;
2560 fac = nfimc / (fimtop-fimbot) ; /* scale from data value to color index */
2561 kf = (int)im_fim->kind ; /* type of data in FIM */
2562
2563 /* pointer for FIM data */
2564
2565 switch( kf ){
2566 default: mri_free(im_ov) ; RETURN(NULL) ; /* should never happen! */
2567 case MRI_short: sfim = MRI_SHORT_PTR(im_fim) ; break ;
2568 case MRI_byte : bfim = MRI_BYTE_PTR (im_fim) ; break ;
2569 case MRI_float: ffim = MRI_FLOAT_PTR(im_fim) ; break ;
2570 }
2571
2572 /* setup pointer for non-volume-edited FIM data */
2573
2574 if( im_noved == NULL || im_noved->kind != im_fim->kind )
2575 im_noved = im_fim ; /* make it be the same as the FIM data */
2576
2577 switch( kf ){
2578 case MRI_short: svim = MRI_SHORT_PTR(im_noved) ; break ;
2579 case MRI_byte : bvim = MRI_BYTE_PTR (im_noved) ; break ;
2580 case MRI_float: fvim = MRI_FLOAT_PTR(im_noved) ; break ;
2581 }
2582
2583 STATUS("colorization") ;
2584 /* compute the color of each pixel */
2585 /* color comes from the non-volume-edited data if available */
2586 /* note that pixels skipped here will get 0 alpha (ovar initialized to 0) */
2587 for( ii=0 ; ii < npix ; ii++ ){
2588 if( kf == MRI_byte ) vval = (float)bvim[ii] ;
2589 else if( kf == MRI_short ) vval = (float)svim[ii] ;
2590 else vval = fvim[ii] ;
2591
2592 if( ZREJ(vval) || (zabove && vval > fimtop) || (zbelow && vval < fimbot) ) continue ;
2593 if( do_pos && vval <= 0.0f ) continue ; /* 12 Dec 2014 */
2594
2595 jj = (int)( fac*(fimtop-vval) ) ;
2596 #if 0
2597 INFO_message("v=%f -> jj=%d fimbot=%f fimtop=%f fac=%f nfimc=%d",vval,jj,fimbot,fimtop,fac,nfimc) ;
2598 #endif
2599 if( jj < 0 ) jj = 0 ; else if( jj > nfimc1 ) jj = nfimc1 ;
2600 ovar[ii].r = fimcolor[jj].r ; /* colorize */
2601 ovar[ii].g = fimcolor[jj].g ;
2602 ovar[ii].b = fimcolor[jj].b ;
2603 ovar[ii].a = 255 ; /* default is opaque */
2604 /* but voxels skipped above are transparent */
2605 }
2606
2607 /** now apply threshold, if any **/
2608
2609 if( flags & NFO_ALIN_MASK ) alcode = 1 ; /* linear fade below thresh */
2610 else if( flags & NFO_AQUA_MASK ) alcode = 2 ; /* quadratic fade */
2611 else alcode = 0 ; /* no fade = sharp cutoff */
2612
2613 if( dothr ){
2614 MRI_IMAGE *eim=NULL ; byte *ear=NULL ;
2615 int do_edge = do_box ;
2616 float ft,fb,af ;
2617
2618 /* scalings for alpha fading on the threshold value */
2619
2620 ft = (thtop > 0.0f) ? (1.0f-alpha_floor)/thtop : 0.0f ; /* for positive thr */
2621 fb = (thbot < 0.0f) ? (1.0f-alpha_floor)/thbot : 0.0f ; /* for negative thr */
2622 af = 255.0f*alpha_floor ; /* always 0 for now */
2623
2624 if( do_edge ){ /* for later use in mri_edgize_outer() */
2625 eim = mri_new_conforming( im_fim , MRI_byte ) ; ear = MRI_BYTE_PTR(eim) ;
2626 }
2627
2628 STATUS("threshold-ization and alpha-ization") ;
2629 switch( im_thr->kind ){ /* the kind of data in the threshold image */
2630
2631 default: break ; /* should not happen */
2632
2633 /* in the following code,
2634 note that alcode==0 implies ALFA() = 0.0 implies not visible,
2635 whereas alcode==1 or ==2 implies 0 < ALFA() < 1 implies translucent */
2636
2637 case MRI_short:{
2638 register float thb=thbot , tht=thtop , aa ; register int rej, vvz ;
2639 register short *ar_thr = MRI_SHORT_PTR(im_thr) ;
2640 for( ii=0 ; ii < npix ; ii++ ){
2641 if( kf == MRI_byte ){ val = (float)bfim[ii]; vval = (float)bvim[ii]; }
2642 else if( kf == MRI_short ){ val = (float)sfim[ii]; vval = (float)svim[ii]; }
2643 else { val = ffim[ii]; vval = fvim[ii]; }
2644 vvz = (val == 0.0f) && (vval != 0.0f) ; /* was vedit-ed out? */
2645 rej = (ovar[ii].a == 0) || (ar_thr[ii] == 0) ; /* rejected out of hand */
2646 if( rej ){
2647 ovar[ii].a = 0 ; /* transparent */
2648 } else if( ar_thr[ii] > 0 && (ar_thr[ii] < tht || vvz) ){ /* alpha */
2649 aa = ALFA(ar_thr[ii],ft) ; ovar[ii].a = ALFABYTE(aa) ; /* fading */
2650 } else if( ar_thr[ii] < 0 && (ar_thr[ii] > thb || vvz) ){ /* if below */
2651 aa = ALFA(ar_thr[ii],fb) ; ovar[ii].a = ALFABYTE(aa) ; /* thresh */
2652 } else if( do_edge ){
2653 if( !(do_pos && val <= 0.0f) ) ear[ii] = 1 ; /* not faded or vedit-ed */
2654 }
2655 }
2656 }
2657 break ;
2658
2659 case MRI_byte:{
2660 register float thb=thbot , tht=thtop , aa ; register int rej, vvz ;
2661 register byte *ar_thr = MRI_BYTE_PTR(im_thr) ;
2662 for( ii=0 ; ii < npix ; ii++ ){ /* assuming thb <= 0 always */
2663 if( kf == MRI_byte ){ val = (float)bfim[ii]; vval = (float)bvim[ii]; }
2664 else if( kf == MRI_short ){ val = (float)sfim[ii]; vval = (float)svim[ii]; }
2665 else { val = ffim[ii]; vval = fvim[ii]; }
2666 vvz = (val == 0.0f) && (vval != 0.0f) ; /* was vedit-ed out? */
2667 rej = (ovar[ii].a == 0) || (ar_thr[ii] == 0) ; /* rejected out of hand */
2668 if( rej ){
2669 ovar[ii].a = 0 ; /* transparent */
2670 } else if( ar_thr[ii] > 0 && (ar_thr[ii] < tht || vvz) ){
2671 aa = ALFA(ar_thr[ii],ft) ; ovar[ii].a = ALFABYTE(aa) ;
2672 } else if( do_edge ){
2673 if( !(do_pos && val <= 0.0f) ) ear[ii] = 1 ; /* not faded or vedit-ed */
2674 }
2675 }
2676 }
2677 break ;
2678
2679 case MRI_float:{
2680 register float thb=thbot , tht=thtop , aa ; register int rej, vvz ;
2681 register float *ar_thr = MRI_FLOAT_PTR(im_thr) ;
2682 for( ii=0 ; ii < npix ; ii++ ){
2683 if( kf == MRI_byte ){ val = (float)bfim[ii]; vval = (float)bvim[ii]; }
2684 else if( kf == MRI_short ){ val = (float)sfim[ii]; vval = (float)svim[ii]; }
2685 else { val = ffim[ii]; vval = fvim[ii]; }
2686 vvz = (val == 0.0f) && (vval != 0.0f) ; /* was vedit-ed out? */
2687 rej = (ovar[ii].a == 0) || (ar_thr[ii] == 0) ; /* rejected out of hand */
2688 if( rej ){
2689 ovar[ii].a = 0 ; /* transparent */
2690 } else if( ar_thr[ii] > 0 && (ar_thr[ii] < tht || vvz) ){
2691 aa = ALFA(ar_thr[ii],ft) ; ovar[ii].a = ALFABYTE(aa) ;
2692 } else if( ar_thr[ii] < 0 && (ar_thr[ii] > thb || vvz) ){
2693 aa = ALFA(ar_thr[ii],fb) ; ovar[ii].a = ALFABYTE(aa) ;
2694 } else if( do_edge ){
2695 if( !(do_pos && val <= 0.0f) ) ear[ii] = 1 ; /* not faded or vedit-ed */
2696 }
2697 }
2698 }
2699 break ;
2700 }
2701
2702 /* process the edges of the above-threshold regions? [Boxes] */
2703
2704 if( do_edge ){
2705 char *cpt ; byte rb=1,gb=1,bb=1 ;
2706 mri_edgize_outer(eim) ; /* mark the edges of the unfaded regions */
2707 cpt = getenv("AFNI_FUNC_BOXED_COLOR") ;
2708 if( cpt != NULL ){
2709 float rf=0.005f, gf=0.005f, bf=0.005f ;
2710 DC_parse_color( dc , cpt , &rf,&gf,&bf ) ;
2711 rb = BYTEIZE(255.0f*rf); gb = BYTEIZE(255.0f*gf); bb = BYTEIZE(255.0f*bf);
2712 }
2713 for( ii=0 ; ii < npix ; ii++ ){
2714 if( ear[ii] ){ ovar[ii].r=rb; ovar[ii].g=gb; ovar[ii].b=bb; ovar[ii].a=254; }
2715 }
2716 mri_free(eim) ;
2717 }
2718 } /* end of threshold-ization and all the fun it has */
2719
2720 RETURN(im_ov) ;
2721 }
2722 #undef ALIN /* these are not used anywhere below */
2723 #undef AQUA
2724 #undef ALFA
2725
2726 /*-----------------------------------------------------------------------
2727 Make an overlay from the TT atlas
2728 n = slice index; (ax_1,ax_2,ax_3) = slice orientation codes
2729 fov = functional overlay image previously computed
2730 if non-NULL, then fov will be overlaid, and will be returned
2731 if NULL, then a new image will be created and returned
2732 This function is called from AFNI_overlay, when making the combined
2733 overlay image for display in a viewer.
2734 -- 25 Jul 2001 - RWCox
2735 -------------------------------------------------------------------------*/
2736
AFNI_ttatlas_overlay(Three_D_View * im3d,int n,int ax_1,int ax_2,int ax_3,MRI_IMAGE * fov)2737 MRI_IMAGE * AFNI_ttatlas_overlay( Three_D_View *im3d ,
2738 int n , int ax_1 , int ax_2 , int ax_3 ,
2739 MRI_IMAGE *fov )
2740 {
2741 THD_3dim_dataset *dseTT ;
2742 TTRR_params *ttp ;
2743 byte *b0=NULL , *brik, *ovc ;
2744 short *s0=NULL, *ovar, *val, *fovar ;
2745 float *f0=NULL;
2746 MRI_IMAGE *ovim=NULL, *b0im=NULL, *fovim=NULL, *b1im=NULL, *outim ;
2747 int gwin , fwin , nreg , ii,jj , nov ;
2748 int at_sbi, fim_type, at_vox, at_nsb;
2749 int jill = AFNI_yesenv("AFNI_JILL_TRAVESTY") ; /* Jill is trouble */
2750
2751 ENTRY("AFNI_ttatlas_overlay") ;
2752
2753 /* setup and sanity checks */
2754
2755 if(jill) INFO_message("Starting AFNI_ttatlas_overlay");
2756
2757 /* make sure we are actually drawing something */
2758
2759 STATUS("checking if Atlas Colors is on") ;
2760 ttp = TTRR_get_params() ;
2761 if( ttp == NULL ){
2762 if( jill ) ININFO_message(" params are off - vamoose") ;
2763 RETURN(NULL) ;
2764 }
2765
2766 STATUS("checking if Atlas dataset can be loaded") ;
2767
2768 if((!atlas_ovdset) ||
2769 ( DSET_NVOX(atlas_ovdset) != DSET_NVOX(im3d->anat_now))){
2770 if(atlas_ovdset)
2771 DSET_unload(atlas_ovdset);
2772 dseTT = TT_retrieve_atlas_dset(Current_Atlas_Default_Name(),0);
2773 if( dseTT == NULL ) RETURN(NULL) ;
2774 DSET_load(dseTT) ;
2775 if(atlas_ovdset) /* reset the atlas overlay dataset */
2776 DSET_unload(atlas_ovdset);
2777 atlas_ovdset = r_new_resam_dset ( dseTT, im3d->anat_now, 0, 0, 0, NULL,
2778 MRI_NN, NULL, 1, 0);
2779 if(jill)
2780 ININFO_message(" First time loading atlas dset");
2781 /* DSET_unload(dseTT);*/
2782 if(!atlas_ovdset) {
2783 if(jill)
2784 ININFO_message(" Could not load atlas dset");
2785 RETURN(NULL);
2786 }
2787 }
2788
2789 if( DSET_NVOX(atlas_ovdset) != DSET_NVOX(im3d->anat_now) ){
2790 WARNING_message(
2791 "Voxels do not match between resampled atlas and the underlay dataset");
2792 RETURN(NULL) ;
2793 }
2794 /* get slices from atlas dataset */
2795 STATUS("loading Atlas bricks") ;
2796
2797 /* extract slice from right direction from atlas */
2798 b0im = AFNI_slice_flip( n , 0 , RESAM_NN_TYPE , ax_1,ax_2,ax_3 ,
2799 atlas_ovdset ) ;
2800
2801 if( b0im == NULL ) RETURN(NULL) ; /* this is bad */
2802
2803 /* make a new overlay image [shorts] for the atlas colors */
2804
2805 STATUS("making new overlay for Atlas") ;
2806 ovim = mri_new_conforming( b0im , MRI_short ) ;
2807 ovar = MRI_SHORT_PTR(ovim) ;
2808 memset( ovar , 0 , ovim->nvox * sizeof(short) ) ; /* nugatory */
2809 /* actually, only needed b0im to get resampled grid dimensions */
2810 mri_free(b0im);
2811 if( jill )
2812 ININFO_message("ovim = %d x %d",ovim->nx,ovim->ny) ;
2813
2814 /* fwin => input function 'wins' over Atlas - overlay image gets priority */
2815 /* gwin => earlier Atlas brick 'wins' over later Atlas brick */
2816
2817 fwin = (ttp->meth == TTRR_METH_FGA) || (ttp->meth == TTRR_METH_FAG) ;
2818 gwin = (ttp->meth == TTRR_METH_FGA) || (ttp->meth == TTRR_METH_GAF) ;
2819
2820 nreg = ttp->num ; /* number of 'on' regions */
2821 brik = ttp->ttbrik ; /* which sub-brick in atlas */
2822 val = ttp->ttval ; /* which code in that sub-brick */
2823 ovc = ttp->ttovc ; /* which overlay color index */
2824
2825 /* loop over image voxels, find overlays from Atlas */
2826
2827 STATUS("doing Atlas overlay") ;
2828 at_nsb = DSET_NVALS(atlas_ovdset); /* number of atlas bricks */
2829 nov = 0;
2830 for( at_sbi=0; at_sbi < at_nsb; at_sbi++) { /* loop over bricks */
2831
2832 /* extract atlas slice from volumne #at_sbi */
2833 b1im = AFNI_slice_flip( n,at_sbi,RESAM_NN_TYPE,ax_1,ax_2,ax_3,
2834 atlas_ovdset);
2835 if( b1im == NULL ) continue ; /* this is bad */
2836
2837 /* get pointer to slice's data */
2838 fim_type = b1im->kind ;
2839 b0 = NULL ; s0 = NULL ; f0 = NULL ;
2840 switch( fim_type ){
2841 case MRI_byte: b0 = MRI_BYTE_PTR(b1im) ; break ;
2842 case MRI_short: s0 = MRI_SHORT_PTR(b1im); break ;
2843 case MRI_float: f0 = MRI_FLOAT_PTR(b1im); break ;
2844 }
2845 if( b0 == NULL && s0 == NULL && f0 == NULL ){ /* this is bad */
2846 ERROR_message("Atlas data type is illegal: %s",MRI_TYPE_NAME(b1im)) ;
2847 mri_free(b1im) ; continue ;
2848 }
2849
2850 for( ii=0 ; ii < ovim->nvox ; ii++ ){ /* loop over voxels */
2851
2852 /* if the overlay array is already set in the overlay */
2853 /* earlier atlas voxel, keep it (if gwin is also set) */
2854
2855 if( ovar[ii] && gwin ) continue ;
2856
2857 switch( fim_type ){ /* get the atlas value at this voxel */
2858 default:
2859 case MRI_byte: at_vox = (int) b0[ii]; break ;
2860 case MRI_short: at_vox = (int) s0[ii]; break ;
2861 case MRI_float: at_vox = (int)(f0[ii]+.1f); break ;
2862 }
2863
2864 /* check Atlas 'on' regions for hits */
2865 for( jj=0 ; jj < nreg ; jj++ ){
2866 if( at_vox == val[jj] ){ /* atlas value matches jj-th region in list */
2867 ovar[ii] = ovc[jj] ; nov++ ; break ;
2868 }
2869 }
2870
2871 }
2872 mri_free(b1im) ; /* done with this atlas slice */
2873 }
2874
2875 if(PRINT_TRACING)
2876 { char str[256]; sprintf(str,"Atlas overlaid %d pixels",nov); STATUS(str); }
2877 if(jill)
2878 ININFO_message(" Atlas overlaid %d image pixels out of %d",nov,ovim->nvox) ;
2879
2880 if( mri_allzero(ovim) ){ /* if it is all zero, we are done here */
2881 mri_free(ovim) ; RETURN(NULL) ;
2882 }
2883
2884 /* convert ovim from shorts to RGB at this point */
2885
2886 fovim = ISQ_index_to_rgb( im3d->dc , 1 , ovim ) ;
2887 mri_free(ovim) ;
2888 ovim = fovim ; fovim = NULL ;
2889
2890 /* setup input image for overlaying in RGB land */
2891
2892 if( fov == NULL ){ /* no input of existing overlay? */
2893 fovim = NULL ;
2894 } else if( fov->kind == MRI_short ){ /* should no longer be possible */
2895 fovim = ISQ_index_to_rgb( im3d->dc , 1 , ovim ) ; /* convert to RGB */
2896 } else if( IS_RGB_IMAGE(fov) ){
2897 fovim = fov ;
2898 } else { /* someone is is BIG trouble */
2899 ERROR_message(" Atlas input overlay image kind illegal: %s",MRI_TYPE_NAME(fov)) ;
2900 fovim = NULL;
2901 }
2902
2903 if( fovim == NULL ){ /* if there was no input overlay, return what we made */
2904 if(jill)
2905 ININFO_message(" No input overlay, that's okay - returning atlas overlay");
2906 RETURN(ovim);
2907 }
2908
2909 /* at this point, ovim is RGB and fovim is RGB or RGBA */
2910
2911 if( fovim->nvox != ovim->nvox ){ /* shouldn't happen! */
2912 if(jill)
2913 ININFO_message(" freeing atlas ovim due to input grid mismatch :(");
2914 if( fovim != fov ) mri_free(fovim) ;
2915 mri_free(ovim); RETURN(NULL) ;
2916 }
2917
2918 STATUS("merging input RGB* overlay with Atlas") ;
2919 if(jill)
2920 ININFO_message(" merging input %s overlay with Atlas",MRI_TYPE_NAME(fovim)) ;
2921
2922 if( fwin )
2923 outim = ISQ_overlay( im3d->dc , ovim , fovim , 1.0f ) ;
2924 else
2925 outim = ISQ_overlay( im3d->dc , fovim , ovim , 1.0f ) ;
2926
2927 if(jill)
2928 ININFO_message(" freeing ovim at normal return");
2929 mri_free(ovim); if( fovim != fov ) mri_free(fovim) ;
2930
2931 if(jill)
2932 ININFO_message(" leaving AFNI_ttatlas_overlay");
2933 RETURN(outim);
2934 }
2935
2936 /* use to force reload of atlas for new default */
reset_atlas_ovdset()2937 void reset_atlas_ovdset()
2938 {
2939 DSET_unload(atlas_ovdset);
2940 atlas_ovdset = NULL;
2941 }
2942
2943 /* get the current resampled dataset used for overlay */
current_atlas_ovdset()2944 THD_3dim_dataset * current_atlas_ovdset()
2945 {
2946 return(atlas_ovdset);
2947 }
2948
2949 /*---------------------------------------------------------------------*/
2950
AFNI_resam_texter(MCW_arrowval * av,XtPointer junk)2951 char * AFNI_resam_texter( MCW_arrowval *av , XtPointer junk )
2952 {
2953 return RESAM_shortstr[av->ival] ;
2954 }
2955
2956 /*---------------------------------------------------------------------*/
2957
AFNI_resam_av_CB(MCW_arrowval * av,XtPointer cd)2958 void AFNI_resam_av_CB( MCW_arrowval *av , XtPointer cd )
2959 {
2960 Three_D_View *im3d = (Three_D_View *) cd ;
2961 int reunder , redisplay ;
2962
2963 ENTRY("AFNI_resam_av_CB") ;
2964
2965 /* sanity check */
2966
2967 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
2968
2969 /* assign resampling type based on which arrowval, and redraw */
2970
2971 if( av == im3d->vwid->dmode->func_resam_av ){
2972 STATUS("set func_resam_mode") ;
2973 im3d->vinfo->func_resam_mode = av->ival ;
2974 if( im3d->b123_fim != NULL ){
2975 im3d->b123_fim->resam_code =
2976 im3d->b231_fim->resam_code =
2977 im3d->b312_fim->resam_code = im3d->vinfo->func_resam_mode ;
2978 }
2979
2980 } else if( av == im3d->vwid->dmode->thr_resam_av ){ /* 09 Dec 1997 */
2981 STATUS("set thr_resam_mode") ;
2982 im3d->vinfo->thr_resam_mode = av->ival ;
2983 if( im3d->b123_fim != NULL ){
2984 im3d->b123_fim->thr_resam_code =
2985 im3d->b231_fim->thr_resam_code =
2986 im3d->b312_fim->thr_resam_code = im3d->vinfo->thr_resam_mode ;
2987 }
2988
2989 } else if( av == im3d->vwid->dmode->anat_resam_av ){
2990 STATUS("set anat_resam_mode") ;
2991 im3d->vinfo->anat_resam_mode = av->ival ;
2992 im3d->b123_anat->resam_code =
2993 im3d->b231_anat->resam_code =
2994 im3d->b312_anat->resam_code = im3d->vinfo->anat_resam_mode ;
2995 }
2996
2997 SHOW_AFNI_PAUSE ;
2998 #if 0
2999 STATUS_IM3D_TMASK(im3d) ;
3000 STATUS("clear tmask") ;
3001 #endif
3002 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
3003 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
3004 AFNI_setup_thrstat(im3d,0) ;
3005 im3d->vinfo->tempflag = 1 ;
3006 AFNI_modify_viewing( im3d , False ) ; /* redisplay */
3007 SHOW_AFNI_READY ;
3008 RESET_AFNI_QUIT(im3d) ;
3009 EXRETURN ;
3010 }
3011
3012 /*----------------------------------------------------------------------*/
3013 /*----- set the bricks to use for the underlay images -----*/
3014
AFNI_assign_ulay_bricks(Three_D_View * im3d)3015 void AFNI_assign_ulay_bricks( Three_D_View *im3d )
3016 {
3017 ENTRY("AFNI_assign_ulay_bricks") ;
3018
3019 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
3020
3021 im3d->vinfo->stats_anat_ok =
3022 im3d->vinfo->stats_func_ok =
3023 im3d->vinfo->arang_func_ok =
3024 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
3025
3026 switch( im3d->vinfo->underlay_type ){
3027 default:
3028 case UNDERLAY_ANAT: /* set underlay to anat */
3029 STATUS("anatomy underlay") ;
3030 im3d->b123_ulay = im3d->b123_anat ;
3031 im3d->b231_ulay = im3d->b231_anat ;
3032 im3d->b312_ulay = im3d->b312_anat ;
3033 break ;
3034
3035 case UNDERLAY_ALLFUNC:
3036 if( ISVALID_DSET(im3d->fim_now) ){
3037 STATUS("functional underlay") ;
3038 im3d->b123_ulay = im3d->b123_fim ;
3039 im3d->b231_ulay = im3d->b231_fim ;
3040 im3d->b312_ulay = im3d->b312_fim ;
3041 } else {
3042 STATUS("defaulted anatomy underlay") ;
3043 WARNING_message("invalid Overlay dataset") ;
3044 im3d->b123_ulay = im3d->b123_anat ;
3045 im3d->b231_ulay = im3d->b231_anat ;
3046 im3d->b312_ulay = im3d->b312_anat ;
3047 #ifdef USE_UNDERLAY_BBOX
3048 MCW_set_bbox( im3d->vwid->func->underlay_bbox , 1<<UNDERLAY_ANAT ) ;
3049 #else
3050 im3d->vinfo->underlay_type = UNDERLAY_ANAT ;
3051 #endif
3052 }
3053 break ;
3054 }
3055
3056 EXRETURN ;
3057 }
3058
3059 /*----------------------------------------------------------------------
3060 called when the underlay needs to be changed:
3061 -- when the underlay type is altered by a button press
3062 -- when a new set of images is to be displayed
3063 -- when the existing underlay has been altered in some hideous way
3064 if the calling widget "w" is NULL, then the calling routine is
3065 required to do the redrawing later
3066 ------------------------------------------------------------------------*/
3067
AFNI_underlay_CB(Widget w,XtPointer cd,XtPointer cb)3068 void AFNI_underlay_CB( Widget w , XtPointer cd , XtPointer cb )
3069 {
3070 Three_D_View *im3d = (Three_D_View *)cd ;
3071 int bval , force_redraw=(cb != NULL) ;
3072 RwcBoolean seq_exist ;
3073
3074 ENTRY("AFNI_underlay_CB") ;
3075
3076 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
3077
3078 im3d->vinfo->stats_anat_ok =
3079 im3d->vinfo->stats_func_ok =
3080 im3d->vinfo->arang_func_ok =
3081 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
3082
3083 #ifdef USE_UNDERLAY_BBOX
3084 if( w != NULL ) bval = AFNI_first_tog( LAST_UNDERLAY_TYPE+1 ,
3085 im3d->vwid->func->underlay_bbox->wbut ) ;
3086 else bval = im3d->vinfo->underlay_type ;
3087 #else
3088 bval = im3d->vinfo->underlay_type ;
3089 #endif
3090
3091 if( bval == im3d->vinfo->underlay_type && w != NULL && IM3D_ULAY_COHERENT(im3d) ) EXRETURN ;
3092
3093 im3d->vinfo->underlay_type = bval ;
3094
3095 AFNI_assign_ulay_bricks(im3d) ; /* 10 Jun 2014 */
3096
3097 #if 0
3098 INFO_message("AFNI_underlay_CB: anat:%p %p %p fim:%p %p %p ulay:%p %p %p" ,
3099 im3d->b123_anat , im3d->b231_anat , im3d->b312_anat ,
3100 im3d->b123_fim , im3d->b231_fim , im3d->b312_fim ,
3101 im3d->b123_ulay , im3d->b231_ulay , im3d->b312_ulay ) ;
3102 #endif
3103
3104 /*--- May 1996: destroy useless graph windows ---*/
3105
3106 im3d->ignore_seq_callbacks = AFNI_IGNORE_REDRAWS ; /* 16 Feb 97 */
3107
3108 if( !DSET_GRAPHABLE(im3d->b123_ulay->dset) || !BRICK_GRAPHABLE(im3d->b123_ulay) ){
3109 if( im3d->g123 != NULL ){
3110 drive_MCW_grapher( im3d->g123 , graDR_destroy , NULL ) ;
3111 im3d->g123 = NULL ;
3112 }
3113 XtSetSensitive( im3d->vwid->imag->graph_xyz_pb , False ) ;
3114 } else {
3115 XtSetSensitive( im3d->vwid->imag->graph_xyz_pb , True ) ;
3116 }
3117
3118 if( !DSET_GRAPHABLE(im3d->b231_ulay->dset) || !BRICK_GRAPHABLE(im3d->b231_ulay) ){
3119 if( im3d->g231 != NULL ){
3120 drive_MCW_grapher( im3d->g231 , graDR_destroy , NULL ) ;
3121 im3d->g231 = NULL ;
3122 }
3123 XtSetSensitive( im3d->vwid->imag->graph_yzx_pb , False ) ;
3124 } else {
3125 XtSetSensitive( im3d->vwid->imag->graph_yzx_pb , True ) ;
3126 }
3127
3128 if( !DSET_GRAPHABLE(im3d->b312_ulay->dset) || !BRICK_GRAPHABLE(im3d->b312_ulay) ){
3129 if( im3d->g312 != NULL ){
3130 drive_MCW_grapher( im3d->g312 , graDR_destroy , NULL ) ;
3131 im3d->g312 = NULL ;
3132 }
3133 XtSetSensitive( im3d->vwid->imag->graph_zxy_pb , False ) ;
3134 } else {
3135 XtSetSensitive( im3d->vwid->imag->graph_zxy_pb , True ) ;
3136 }
3137
3138 /** 05 Mar 1997: disable viewers if x or y dimension is 1 pixel **/
3139
3140 if( !BRICK_DRAWABLE(im3d->b123_ulay) ){
3141 if( im3d->s123 != NULL ){
3142 drive_MCW_imseq( im3d->s123 , isqDR_destroy , NULL ) ;
3143 im3d->s123 = NULL ;
3144 }
3145 XtSetSensitive( im3d->vwid->imag->image_xyz_pb , False ) ;
3146 } else {
3147 XtSetSensitive( im3d->vwid->imag->image_xyz_pb , True ) ;
3148 }
3149
3150 if( !BRICK_DRAWABLE(im3d->b231_ulay) ){
3151 if( im3d->s231 != NULL ){
3152 drive_MCW_imseq( im3d->s231 , isqDR_destroy , NULL ) ;
3153 im3d->s231 = NULL ;
3154 }
3155 XtSetSensitive( im3d->vwid->imag->image_yzx_pb , False ) ;
3156 } else {
3157 XtSetSensitive( im3d->vwid->imag->image_yzx_pb , True ) ;
3158 }
3159
3160 if( !BRICK_DRAWABLE(im3d->b312_ulay) ){
3161 if( im3d->s312 != NULL ){
3162 drive_MCW_imseq( im3d->s312 , isqDR_destroy , NULL ) ;
3163 im3d->s312 = NULL ;
3164 }
3165 XtSetSensitive( im3d->vwid->imag->image_zxy_pb , False ) ;
3166 } else {
3167 XtSetSensitive( im3d->vwid->imag->image_zxy_pb , True ) ;
3168 }
3169
3170 im3d->ignore_seq_callbacks = AFNI_IGNORE_NOTHING ; /* 16 Feb 97 */
3171
3172 /*--- attach any changes to open image displays ---*/
3173
3174 seq_exist = (im3d->s123 != NULL) || (im3d->s231 != NULL) || (im3d->s312 != NULL) ||
3175 (im3d->g123 != NULL) || (im3d->g231 != NULL) || (im3d->g312 != NULL) ;
3176
3177 /* set the title for all windows */
3178
3179 AFNI_set_window_titles( im3d ) ;
3180
3181 if( seq_exist ){
3182
3183 im3d->ignore_seq_callbacks = AFNI_IGNORE_EVERYTHING ;
3184 #if 0
3185 STATUS_IM3D_TMASK(im3d) ;
3186 STATUS("clear tmask") ;
3187 #endif
3188 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
3189 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
3190 AFNI_setup_thrstat(im3d,0) ; /* 27 Jun 2019 */
3191
3192 if( im3d->s123 != NULL )
3193 drive_MCW_imseq( im3d->s123 , isqDR_newseq ,
3194 (XtPointer) im3d->b123_ulay ) ;
3195
3196 if( im3d->s231 != NULL )
3197 drive_MCW_imseq( im3d->s231 , isqDR_newseq ,
3198 (XtPointer) im3d->b231_ulay ) ;
3199
3200 if( im3d->s312 != NULL )
3201 drive_MCW_imseq( im3d->s312 , isqDR_newseq ,
3202 (XtPointer) im3d->b312_ulay ) ;
3203
3204 if( im3d->g123 != NULL )
3205 drive_MCW_grapher( im3d->g123 , graDR_newdata ,
3206 (XtPointer) im3d->b123_ulay ) ;
3207
3208 if( im3d->g231 != NULL )
3209 drive_MCW_grapher( im3d->g231 , graDR_newdata ,
3210 (XtPointer) im3d->b231_ulay ) ;
3211
3212 if( im3d->g312 != NULL )
3213 drive_MCW_grapher( im3d->g312 , graDR_newdata ,
3214 (XtPointer) im3d->b312_ulay ) ;
3215
3216 im3d->ignore_seq_callbacks = AFNI_IGNORE_REDRAWS ;
3217
3218 /** July 1996: get the sequences to send their montaging status **/
3219
3220 if( im3d->s123 != NULL )
3221 drive_MCW_imseq( im3d->s123 , isqDR_sendmontage , NULL ) ;
3222 else
3223 CLEAR_MONTAGE( im3d , im3d->b123_ulay ) ;
3224
3225 if( im3d->s231 != NULL )
3226 drive_MCW_imseq( im3d->s231 , isqDR_sendmontage , NULL ) ;
3227 else
3228 CLEAR_MONTAGE( im3d , im3d->b231_ulay ) ;
3229
3230 if( im3d->s312 != NULL )
3231 drive_MCW_imseq( im3d->s312 , isqDR_sendmontage , NULL ) ;
3232 else
3233 CLEAR_MONTAGE( im3d , im3d->b312_ulay ) ;
3234
3235 im3d->ignore_seq_callbacks = AFNI_IGNORE_NOTHING ;
3236
3237 if( w != NULL || force_redraw ){ /* a real callback */
3238 SHOW_AFNI_PAUSE ;
3239 AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_ALL ) ;
3240 SHOW_AFNI_READY ;
3241 }
3242 }
3243
3244 /* Feb 1998: if a receiver is open
3245 send it a message that something has altered */
3246
3247 AFNI_process_alteration(im3d) ;
3248
3249 HINTIZE_pbar(im3d) ; /* 15 Aug 2001 */
3250 FIX_SCALE_SIZE(im3d) ;
3251
3252 EXRETURN ;
3253 }
3254
3255 /*--------------------------------------------------------------------*/
3256
AFNI_controller_label(Three_D_View * im3d)3257 char * AFNI_controller_label( Three_D_View *im3d )
3258 {
3259 static char clabel[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
3260 static char str[8] ;
3261 int ic, ib;
3262
3263 ic = AFNI_controller_index( im3d ) ;
3264 if( ic < 0 || ic > 26 ) strcpy (str," ") ; /* shouldn't happen */
3265 else {
3266 if ((ib = get_user_np_bloc())>-1) { /* ZSS June 2011 */
3267 sprintf(str,"[%c%d] ",clabel[ic], ib) ;
3268 } else {
3269 sprintf(str,"[%c] ",clabel[ic]) ;
3270 }
3271 }
3272 return str ;
3273 }
3274
3275 /*--------------------------------------------------------------------
3276 Set the titles in all windows
3277 ----------------------------------------------------------------------*/
3278
3279 #undef USE_TITLE2
3280 #define USE_TITLE2(ds) ( ISVALID_DSET(ds) && \
3281 AFNI_yesenv("AFNI_TITLE_LABEL2") && \
3282 *((ds)->label2) != '\0' && \
3283 strcmp( (ds)->label2 , "zyxt" ) != 0 )
3284
AFNI_set_window_titles(Three_D_View * im3d)3285 void AFNI_set_window_titles( Three_D_View *im3d )
3286 {
3287 RwcBoolean redo_title ;
3288 char ttl[THD_MAX_NAME] , nam[THD_MAX_NAME] ;
3289 char *tnam , *clab ; int ilab ;
3290 char signum ; /* 08 Aug 2007 */
3291 int ninit=0;
3292
3293 ENTRY("AFNI_set_window_titles") ;
3294
3295 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
3296
3297 clab = AFNI_controller_label(im3d) ;
3298 ninit = strlen(clab)-1;
3299 switch( im3d->vinfo->thr_sign ){
3300 default: ilab = ninit -1; break ;
3301 case 1: ilab = ninit ; clab[ninit] = '+' ; break ;
3302 case 2: ilab = ninit ; clab[ninit] = '-' ; break ;
3303 }
3304 switch( im3d->vinfo->underlay_type ){ /* 08 May 2008 */
3305 default: clab[++ilab] = 'u' ; break ;
3306 case UNDERLAY_ALLFUNC: clab[++ilab] = 'o' ; break ;
3307 }
3308 clab[++ilab] = ' ' ; clab[++ilab] = '\0' ;
3309
3310 if( im3d->anat_wod_flag )
3311 sprintf(ttl , "{warp}%s%s: " , clab,GLOBAL_argopt.title_name) ;
3312 else
3313 sprintf(ttl , "%s%s: " , clab,GLOBAL_argopt.title_name) ;
3314
3315 if( USE_TITLE2(im3d->anat_now) ){
3316 strcat( ttl , im3d->anat_now->label2 ) ;
3317 } else {
3318 strcpy( nam , im3d->anat_now->dblk->diskptr->directory_name ) ;
3319 strcat( nam , im3d->anat_now->dblk->diskptr->filecode ) ;
3320 tnam = THD_trailname(nam,SESSTRAIL+1) ;
3321 strcat( ttl , tnam ) ;
3322 }
3323
3324 if( ISVALID_3DIM_DATASET(im3d->fim_now) ){
3325 strcat( ttl , " & " ) ;
3326 if( USE_TITLE2(im3d->fim_now) ){
3327 strcat( ttl , im3d->fim_now->label2 ) ;
3328 } else {
3329 strcat( ttl , im3d->fim_now->dblk->diskptr->filecode ) ;
3330 }
3331 }
3332
3333 redo_title = (RwcBoolean) (strcmp(ttl,im3d->window_title) != 0 ) ;
3334 if( redo_title ){
3335 strcpy( im3d->window_title , ttl ) ;
3336 XtVaSetValues( im3d->vwid->top_shell , XmNtitle , ttl , NULL ) ;
3337
3338 if( im3d->s123 != NULL )
3339 drive_MCW_imseq( im3d->s123 , isqDR_title , (XtPointer) ttl ) ;
3340
3341 if( im3d->s231 != NULL )
3342 drive_MCW_imseq( im3d->s231 , isqDR_title , (XtPointer) ttl ) ;
3343
3344 if( im3d->s312 != NULL )
3345 drive_MCW_imseq( im3d->s312 , isqDR_title , (XtPointer) ttl ) ;
3346
3347 if( im3d->g123 != NULL )
3348 drive_MCW_grapher( im3d->g123 , graDR_title , (XtPointer) ttl ) ;
3349
3350 if( im3d->g231 != NULL )
3351 drive_MCW_grapher( im3d->g231 , graDR_title , (XtPointer) ttl ) ;
3352
3353 if( im3d->g312 != NULL )
3354 drive_MCW_grapher( im3d->g312 , graDR_title , (XtPointer) ttl ) ;
3355 }
3356
3357 EXRETURN ;
3358 }
3359
3360 /*--------------------------------------------------------------------*/
3361 /*! Determine if dset is in the AFNI global session - 21 Dec 2001.
3362 ----------------------------------------------------------------------*/
3363
DSET_in_global_session(THD_3dim_dataset * dset)3364 int DSET_in_global_session( THD_3dim_dataset *dset )
3365 {
3366 THD_slist_find find ;
3367
3368 if( !ISVALID_DSET(dset) ) return 0 ;
3369
3370 find = THD_dset_in_session( FIND_IDCODE ,
3371 &(dset->idcode) ,
3372 GLOBAL_library.session ) ;
3373
3374 return (find.dset != NULL) ;
3375 }
3376
3377 /*--------------------------------------------------------------------
3378 used to select between sessions and datasets
3379 ----------------------------------------------------------------------*/
3380
3381 /** labels for the chooser window **/
3382
3383 static char *dset_choice[] = { "Session" , "Underlay" , "Overlay" , "Dataset" } ;
3384
3385 /** max size of strings in the list **/
3386
3387 #define STRLIST_SIZE (THD_MAX_PREFIX+256)
3388 #define MAX_SESSTRAIL_LEN 96
3389
AFNI_choose_dataset_CB(Widget w,XtPointer cd,XtPointer cb)3390 void AFNI_choose_dataset_CB( Widget w , XtPointer cd , XtPointer cb )
3391 {
3392 static char *strlist[THD_MAX_CHOICES] ; /* strings to choose between */
3393 static int first_call = 1 ; /* initialization flag */
3394
3395 int num_str , ii , init_str , vv , jj ;
3396 char *label ;
3397 Widget wpar ;
3398 Three_D_View *im3d = (Three_D_View *) cd ;
3399 int llen , ltop ;
3400 int browse_select = 0 ;
3401 int is_other = 0 ; /* 18 Dec 2007 */
3402 void (*cbfun)(Widget,XtPointer,MCW_choose_cbs *)=AFNI_finalize_dataset_CB;
3403 THD_3dim_dataset *temp_dset=NULL;
3404 int sesstrail = (strcmp(im3d->ss_now->sessname,"All_Datasets")==0) ;
3405 char *st=NULL , sst[STRLIST_SIZE+1] ;
3406
3407 ENTRY("AFNI_choose_dataset_CB") ;
3408
3409 /*--- initialize ---*/
3410
3411 if( ! IM3D_OPEN(im3d) || w == (Widget)NULL ) EXRETURN ;
3412
3413 sesstrail = (strcmp(im3d->ss_now->sessname,"All_Datasets")==0) ||
3414 AFNI_yesenv("AFNI_USE_SESSTRAIL") ;
3415
3416 im3d->vinfo->stats_anat_ok =
3417 im3d->vinfo->stats_func_ok =
3418 im3d->vinfo->arang_func_ok =
3419 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
3420
3421 if( GLOBAL_library.have_dummy_dataset ){ /* 26 Feb 2007: read session? */
3422 if( w == im3d->vwid->view->choose_sess_pb ||
3423 w == im3d->vwid->view->popchoose_sess_pb ){
3424
3425 AFNI_read_sess_CB(im3d->vwid->dmode->read_sess_pb,(XtPointer)im3d,NULL) ;
3426
3427 } else {
3428 BEEPIT ; WARNING_message("Can't choose dataset if all you have is Dummy") ;
3429 }
3430 EXRETURN ;
3431 }
3432
3433 #if 0
3434 if( AFNI_splash_isopen() == 1 ){ BEEPIT ; EXRETURN ; }
3435 #endif
3436
3437 /* how about a rescan ? ZSS - Fur Greg Detre */
3438
3439 if( AFNI_yesenv("AFNI_RESCAN_AT_SWITCH") &&
3440 !(w == im3d->vwid->view->choose_sess_pb ||
3441 w == im3d->vwid->view->popchoose_sess_pb) ){
3442
3443 STATUS("rescanning, per AFNI_RESCAN_AT_SWITCH") ;
3444 AFNI_rescan_CB( w , (XtPointer)im3d , NULL ) ;
3445 }
3446
3447 if( first_call ){
3448 for( ii=0 ; ii < THD_MAX_CHOICES ; ii++ )
3449 strlist[ii] = (char*)XtMalloc( sizeof(char) * (STRLIST_SIZE+1) ) ;
3450 first_call = 0 ;
3451 }
3452
3453 /*--- make a list of session names ---*/
3454
3455 if( w == im3d->vwid->view->choose_sess_pb ||
3456 w == im3d->vwid->view->popchoose_sess_pb ){
3457
3458 wpar = im3d->vwid->view->choose_sess_pb ;
3459 num_str = GLOBAL_library.sslist->num_sess ;
3460 if( num_str < 1 ) EXRETURN ;
3461
3462 for( ii=0 ; ii < num_str ; ii++ ){
3463 MCW_strncpy( strlist[ii] ,
3464 GLOBAL_library.sslist->ssar[ii]->lastname ,
3465 STRLIST_SIZE ) ;
3466 }
3467
3468 init_str = im3d->vinfo->sess_num ;
3469 label = dset_choice[0] ;
3470
3471 /*--- make a list of anatomy names ---*/
3472
3473 } else if( w == im3d->vwid->view->choose_anat_pb ||
3474 w == im3d->vwid->view->popchoose_anat_pb ){
3475
3476 wpar = im3d->vwid->view->choose_anat_pb ;
3477 num_str = im3d->ss_now->num_dsset ;
3478 if( num_str < 1 ) EXRETURN ;
3479
3480 if( AFNI_yesenv("AFNI_DATASET_BROWSE") ) browse_select = 1 ;
3481 THD_set_oblique_report(num_str-1, -1);
3482 ltop = 4 ;
3483 for( ii=0 ; ii < num_str ; ii++ ){
3484 #if 0 /* No more of this stuff ZSS Nov 2011 */
3485 THD_report_obliquity(GET_SESSION_DSET(im3d->ss_now,ii,0)) ;
3486 #endif
3487
3488 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ )
3489 {
3490 temp_dset = GET_SESSION_DSET(im3d->ss_now, ii, vv);
3491
3492 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3493 }
3494
3495 if( vv <= LAST_VIEW_TYPE ){
3496 llen = strlen( temp_dset->dblk->diskptr->prefix ) ;
3497 if( sesstrail ){
3498 st = THD_trailname(temp_dset->dblk->diskptr->directory_name,1) ;
3499 if( st != NULL ){
3500 if( strlen(st) > MAX_SESSTRAIL_LEN )
3501 st += (strlen(st)-MAX_SESSTRAIL_LEN) ;
3502 llen += strlen(st) ;
3503 }
3504 }
3505 if( llen > ltop ) ltop = llen ;
3506 }
3507 }
3508 ltop = MIN(ltop,STRLIST_SIZE-24) ; /* 06 Aug 2002 */
3509
3510 for( ii=0 ; ii < num_str ; ii++ ){
3511 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ) {
3512 temp_dset = GET_SESSION_DSET(im3d->ss_now, ii, vv);
3513 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3514 }
3515
3516 if( vv <= LAST_VIEW_TYPE ){
3517 if( sesstrail ){
3518 st = THD_trailname(temp_dset->dblk->diskptr->directory_name,1) ;
3519 if( st != NULL ){
3520 if( strlen(st) > MAX_SESSTRAIL_LEN )
3521 st += (strlen(st)-MAX_SESSTRAIL_LEN) ;
3522 }
3523 } else {
3524 st = "\0" ;
3525 }
3526 strcpy(sst,st) ; strcat(sst,temp_dset->dblk->diskptr->prefix) ;
3527 sprintf( strlist[ii] , "%-*s" , ltop,sst ) ;
3528
3529 strcat( strlist[ii] , " [" ) ;
3530 strcat( strlist[ii] , DSET_PREFIXSTR(temp_dset) ) ;
3531
3532 if( DSET_NUM_TIMES(temp_dset) > 1 ){
3533 int ll = strlen(strlist[ii]) ;
3534 sprintf( strlist[ii]+ll , ":3D+t:%d]" ,
3535 DSET_NUM_TIMES(temp_dset) ) ;
3536 } else if( ISBUCKET(temp_dset) ){
3537 int ll = strlen(strlist[ii]) ;
3538 sprintf( strlist[ii]+ll , ":%d]" ,
3539 DSET_NVALS(temp_dset) ) ;
3540 } else {
3541 strcat( strlist[ii] , "]" ) ;
3542 }
3543
3544 if( DSET_GRAPHABLE(temp_dset) )
3545 strcat( strlist[ii] , "*" ) ;
3546
3547 if( DSET_COMPRESSED(temp_dset) )
3548 strcat( strlist[ii] , "z" ) ;
3549
3550 /* 20 Dec 2001: mark if this is a global dataset */
3551
3552 if( DSET_in_global_session(temp_dset) )
3553 strcat( strlist[ii] , "G" ) ;
3554
3555
3556 } else {
3557 #if 1
3558 THD_3dim_dataset *qset ; static int first=1 ;
3559 if( first ){
3560 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
3561 qset = GET_SESSION_DSET(im3d->ss_now, ii, vv);
3562 if( qset != NULL ){
3563 INFO_message("BAD dataset: type=%d view_type=%d ibk=%d bkt=%d",
3564 qset->type , qset->view_type , qset->dblk != NULL , qset->dblk->type ) ;
3565 }
3566 }
3567 first=0 ;
3568 }
3569 #endif
3570 MCW_strncpy( strlist[ii] , "??*BAD*??" , THD_MAX_PREFIX ) ;
3571 }
3572 }
3573
3574 init_str = im3d->vinfo->anat_num ;
3575 label = dset_choice[1] ;
3576
3577 /*--- make a list of function names ---*/
3578
3579 } else {
3580 int nn=0 , ndset=0 ; THD_3dim_dataset **dset_list=NULL , *dset=NULL;
3581
3582 is_other = !( w == im3d->vwid->view->choose_func_pb ||
3583 w == im3d->vwid->view->popchoose_func_pb ) ;
3584
3585 num_str = im3d->ss_now->num_dsset ;
3586 if( num_str < 1 ) EXRETURN ;
3587
3588 if( is_other ){
3589 AFNI_dataset_choose_stuff *cs = (AFNI_dataset_choose_stuff *)cb ;
3590 if( cs == NULL ) EXRETURN ;
3591 ndset = cs->ndset ; if( ndset < 1 ) EXRETURN ;
3592 dset_list = cs->dset ; if( dset_list == NULL ) EXRETURN ;
3593 cbfun = cs->cb ; if( cbfun == NULL ) EXRETURN ;
3594 wpar = w ;
3595 /*** sesstrail = 0 ; ***/
3596 } else {
3597 if( AFNI_yesenv("AFNI_DATASET_BROWSE") ) browse_select = 1 ;
3598 wpar = im3d->vwid->view->choose_func_pb ;
3599 ndset = num_str ;
3600 }
3601
3602 ltop = 4 ;
3603 for( ii=0 ; ii < ndset ; ii++ ){
3604 if( is_other ){
3605 dset = dset_list[ii] ;
3606 } else {
3607 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
3608 dset = GET_SESSION_DSET(im3d->ss_now, ii, vv); if( ISVALID_DSET(dset) ) break;
3609 /* dset = im3d->ss_now->dsset_xform_table[ii][vv]; if( ISVALID_DSET(dset) ) break;*/
3610 }
3611 }
3612 if( ISVALID_DSET(dset) ){
3613 llen = strlen( dset->dblk->diskptr->prefix ) ;
3614 if( sesstrail ){
3615 st = THD_trailname(dset->dblk->diskptr->directory_name,1) ;
3616 if( st != NULL ){
3617 if( strlen(st) > MAX_SESSTRAIL_LEN )
3618 st += (strlen(st)-MAX_SESSTRAIL_LEN) ;
3619 llen += strlen(st) ;
3620 }
3621 }
3622 if( llen > ltop ) ltop = llen ;
3623 }
3624 }
3625 ltop = MIN(ltop,STRLIST_SIZE-24) ; /* 06 Aug 2002 */
3626
3627 for( ii=0 ; ii < ndset ; ii++ ){
3628
3629 if( is_other ){
3630 dset = dset_list[ii] ; if( !ISVALID_DSET(dset) ) continue ;
3631 } else {
3632 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
3633 dset = GET_SESSION_DSET(im3d->ss_now, ii, vv); if( ISVALID_DSET(dset) ) break;
3634 /* dset = im3d->ss_now->dsset_xform_table[ii][vv]; if( ISVALID_DSET(dset) ) break;*/
3635 }
3636 }
3637
3638 if( ISVALID_DSET(dset) ){
3639 if( sesstrail ){
3640 st = THD_trailname(dset->dblk->diskptr->directory_name,1) ;
3641 if( st != NULL ){
3642 if( strlen(st) > MAX_SESSTRAIL_LEN )
3643 st += (strlen(st)-MAX_SESSTRAIL_LEN) ;
3644 }
3645 } else {
3646 st = "\0" ;
3647 }
3648 strcpy(sst,st) ; strcat(sst,dset->dblk->diskptr->prefix) ;
3649 sprintf( strlist[nn] , "%-*s" , ltop,sst ) ;
3650
3651 strcat( strlist[nn] , " [" ) ;
3652 strcat( strlist[nn] , DSET_PREFIXSTR(dset) ) ;
3653
3654 if( DSET_NUM_TIMES(dset) > 1 ){
3655 int ll = strlen(strlist[nn]) ;
3656 sprintf( strlist[nn]+ll , ":3D+t:%d]" , DSET_NUM_TIMES(dset) ) ;
3657 } else if( ISBUCKET(dset) ){
3658 int ll = strlen(strlist[nn]) ;
3659 sprintf( strlist[nn]+ll , ":%d]" , DSET_NVALS(dset) ) ;
3660 } else {
3661 strcat( strlist[nn] , "]" ) ;
3662 }
3663
3664 if( DSET_COMPRESSED(dset) ) strcat( strlist[nn] , "z" ) ;
3665
3666 /* 20 Dec 2001: mark if this is a global dataset */
3667
3668 if( DSET_in_global_session(dset) ) strcat( strlist[nn] , "G" ) ;
3669
3670 } else { /* should never happen */
3671 #if 1
3672 THD_3dim_dataset *qset ; static int first=1 ;
3673 if( first ){
3674 for( vv=FIRST_VIEW_TYPE ; vv <= LAST_VIEW_TYPE ; vv++ ){
3675 qset = GET_SESSION_DSET(im3d->ss_now,ii,vv) ;
3676 if( qset != NULL ){
3677 INFO_message("BAD dataset: type=%d view_type=%d ibk=%d bkt=%d",
3678 qset->type , qset->view_type , qset->dblk != NULL , qset->dblk->type ) ;
3679 }
3680 }
3681 first=0 ;
3682 }
3683 #endif
3684 MCW_strncpy( strlist[nn] , "**?BAD?**" , THD_MAX_PREFIX ) ;
3685 }
3686
3687 nn++ ;
3688 }
3689
3690 if( nn < 1 ) EXRETURN ;
3691
3692 if( is_other ){
3693 init_str = 0 ;
3694 label = dset_choice[3] ;
3695 } else {
3696 init_str = im3d->vinfo->func_num ;
3697 label = dset_choice[2] ;
3698 }
3699 num_str = nn ;
3700
3701 }
3702
3703 /*--- call the chooser ---*/
3704
3705 MCW_set_browse_select( browse_select ) ;
3706
3707 MCW_choose_strlist( wpar , label , num_str , init_str , strlist ,
3708 cbfun , (XtPointer)im3d ) ;
3709
3710 RESET_AFNI_QUIT(im3d) ;
3711 EXRETURN ;
3712 }
3713
3714 /*-----------------------------------------------------------------------*/
3715
AFNI_finalize_dataset_CB(Widget wcall,XtPointer cd,MCW_choose_cbs * cbs)3716 void AFNI_finalize_dataset_CB( Widget wcall ,
3717 XtPointer cd , MCW_choose_cbs *cbs )
3718 {
3719 Three_D_View *im3d = (Three_D_View *)cd ;
3720 int old_sess , old_anat , old_func , old_view ;
3721 int new_sess=-1 , new_anat=-1 , new_func=-1 , new_view=-1 ;
3722 int ii , vv , ff ;
3723 THD_session *ss_new ;
3724 THD_3dim_dataset *temp_dset;
3725
3726 ENTRY("AFNI_finalize_dataset_CB") ;
3727
3728 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
3729
3730 old_sess = im3d->vinfo->sess_num ; /* record current status */
3731 old_anat = im3d->vinfo->anat_num ;
3732 old_func = im3d->vinfo->func_num ;
3733 old_view = im3d->vinfo->view_type ;
3734
3735 im3d->vinfo->stats_anat_ok =
3736 im3d->vinfo->stats_func_ok =
3737 im3d->vinfo->arang_func_ok =
3738 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
3739
3740 #if 0
3741 STATUS_IM3D_TMASK(im3d) ;
3742 STATUS("clear tmask") ;
3743 #endif
3744 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
3745 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
3746 AFNI_setup_thrstat(im3d,0) ; /* 27 Jun 2019 */
3747
3748 /*--- switch sessions ---*/
3749
3750 if( wcall == im3d->vwid->view->choose_sess_pb ){
3751
3752 DISABLE_INSTACORR(im3d) ; DESTROY_ICOR_setup(im3d->iset) ; /* 08 May 2009 */
3753
3754 new_sess = cbs->ival ;
3755 if( new_sess < 0 || new_sess >= GLOBAL_library.sslist->num_sess ){
3756 BEEPIT ;
3757 WARNING_message("bad session index when finalizing choice") ;
3758 EXRETURN ; /* bad! */
3759 }
3760
3761 ss_new = GLOBAL_library.sslist->ssar[new_sess] ;
3762
3763 /* find an anat in new session to match current anat */
3764
3765 temp_dset = GET_SESSION_DSET(ss_new, old_anat, old_view);
3766 if( ISVALID_3DIM_DATASET(temp_dset) ){ /* are OK */
3767 new_anat = old_anat ;
3768 } else {
3769 for( ii=0 ; ii < ss_new->num_dsset ; ii++ ) {
3770 temp_dset = GET_SESSION_DSET(ss_new, ii, old_view);
3771 if( ISVALID_3DIM_DATASET(temp_dset) ){ new_anat = ii ; break ; }
3772 }
3773 }
3774 if( new_anat < 0 ) new_anat = 0 ; /* use 1st if no match */
3775
3776 /* find a view to fit this chosen anat */
3777
3778 temp_dset = GET_SESSION_DSET(ss_new, new_anat, old_view);
3779 if( ISVALID_3DIM_DATASET(temp_dset )) { /* are OK */
3780 new_view = old_view ;
3781 } else {
3782 for( vv=old_view-1 ; vv >= FIRST_VIEW_TYPE ; vv-- ) { /* look below */
3783 temp_dset = GET_SESSION_DSET(ss_new, new_anat, vv);
3784 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3785 }
3786 if( vv >= FIRST_VIEW_TYPE ){ /* found it below */
3787 new_view = vv ;
3788 } else { /* look above */
3789 for( vv=old_view+1 ; vv <= LAST_VIEW_TYPE ; vv++ ) {
3790 temp_dset = GET_SESSION_DSET(ss_new, new_anat, vv);
3791 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3792 }
3793
3794 if( vv <= LAST_VIEW_TYPE ){ /* found it above */
3795 new_view = vv ;
3796 } else {
3797 BEEPIT ;
3798 WARNING_message("bad view code when finalizing choice") ;
3799 EXRETURN ; /* bad news */
3800 }
3801 }
3802 }
3803
3804 /* find a func in new session that fits the new view */
3805
3806 #define FINDAFUNC
3807 #ifdef FINDAFUNC
3808 temp_dset = GET_SESSION_DSET(ss_new, old_func, new_view);
3809 if( ISVALID_3DIM_DATASET(temp_dset) ){ /* are OK */
3810 new_func = old_func ;
3811 } else {
3812 for( ff=0 ; ff < ss_new->num_dsset ; ff++ ) { /* search */
3813 temp_dset = GET_SESSION_DSET(ss_new, ff, new_view);
3814 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3815 /* if( ISVALID_3DIM_DATASET(ss_new->dsset_xform_table[ff][new_view]) ) break ;*/
3816 }
3817
3818 if( ff < ss_new->num_dsset ) new_func = ff ; /* found one */
3819 }
3820 if( new_func < 0 ) new_func = 0 ; /* no match */
3821 #else
3822 new_func = old_func ;
3823 #endif
3824
3825 /*--- switch anatomy ---*/
3826
3827 } else if( wcall == im3d->vwid->view->choose_anat_pb ){
3828
3829 new_sess = old_sess ;
3830 ss_new = GLOBAL_library.sslist->ssar[new_sess] ;
3831
3832 new_anat = cbs->ival ;
3833 if( new_anat < 0 || new_anat >= ss_new->num_dsset ){
3834 BEEPIT ;
3835 WARNING_message("bad anat index when finalizing choice") ;
3836 EXRETURN ; /* bad! */
3837 }
3838
3839 /* find a view to fit this chosen anat */
3840 temp_dset = GET_SESSION_DSET(ss_new, new_anat, old_view);
3841
3842 if( ISVALID_3DIM_DATASET(temp_dset) ){ /* are OK */
3843 new_view = old_view ;
3844 } else {
3845 for( vv=old_view-1 ; vv >= FIRST_VIEW_TYPE ; vv-- ) { /* look below */
3846 temp_dset = GET_SESSION_DSET(ss_new, new_anat, vv);
3847 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3848 }
3849
3850 if( vv >= FIRST_VIEW_TYPE ){ /* found it below */
3851 new_view = vv ;
3852 } else { /* look above */
3853 for( vv=old_view+1 ; vv <= LAST_VIEW_TYPE ; vv++ ){
3854 temp_dset = GET_SESSION_DSET(ss_new, new_anat, vv);
3855 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3856 }
3857
3858 if( vv <= LAST_VIEW_TYPE ){ /* found it above */
3859 new_view = vv ;
3860 } else {
3861 BEEPIT ;
3862 WARNING_message("bad func index when finalizing choice") ;
3863 EXRETURN ; /* bad news */
3864 }
3865 }
3866 }
3867
3868 /* find a func to match this view */
3869
3870 #ifdef FINDAFUNC
3871 temp_dset = GET_SESSION_DSET(ss_new, old_func, new_view);
3872 if( ISVALID_3DIM_DATASET(temp_dset) ) {
3873 new_func = old_func ;
3874 } else {
3875 for( ff=0 ; ff < ss_new->num_dsset ; ff++ ) { /* search */
3876 temp_dset = GET_SESSION_DSET(ss_new, ff, new_view);
3877 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3878 /* if( ISVALID_3DIM_DATASET(ss_new->dsset_xform_table[ff][new_view]) ) break ;*/
3879 }
3880
3881 if( ff < ss_new->num_dsset ) new_func = ff ; /* found one */
3882 }
3883 if( new_func < 0 ) new_func = 0 ; /* no match */
3884 #else
3885 new_func = old_func ;
3886 #endif
3887
3888 /*--- switch function ---*/
3889
3890 } else if( wcall == im3d->vwid->view->choose_func_pb ){
3891
3892 new_sess = old_sess ;
3893 ss_new = GLOBAL_library.sslist->ssar[new_sess] ;
3894
3895 new_func = cbs->ival ;
3896 if( new_func < 0 || new_func >= ss_new->num_dsset ){ /* should not happen */
3897 BEEPIT ;
3898 WARNING_message("bad func index when finalizing choice!") ;
3899 EXRETURN ; /* bad! */
3900 }
3901
3902 /* find a view to fit this chosen func */
3903
3904 temp_dset = GET_SESSION_DSET(ss_new, new_func, old_view);
3905 if( ISVALID_3DIM_DATASET(temp_dset) ) {
3906 new_view = old_view ;
3907 } else {
3908 for( vv=old_view-1 ; vv >= FIRST_VIEW_TYPE ; vv-- ) { /* look below */
3909 temp_dset = GET_SESSION_DSET(ss_new, new_func, vv);
3910 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3911 }
3912
3913 if( vv >= FIRST_VIEW_TYPE ){ /* found it below */
3914 new_view = vv ;
3915 } else { /* look above */
3916 for( vv=old_view+1 ; vv <= LAST_VIEW_TYPE ; vv++ ) {
3917 temp_dset = GET_SESSION_DSET(ss_new, new_func, vv);
3918 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3919 }
3920
3921 if( vv <= LAST_VIEW_TYPE ){ /* found it above */
3922 new_view = vv ;
3923 } else { /* should not happen */
3924 BEEPIT ;
3925 WARNING_message("bad view index when finalizing choice!") ;
3926 EXRETURN ; /* bad news */
3927 }
3928 }
3929 }
3930
3931 /* find an anat to go with the new view (this is NOT optional) */
3932
3933 temp_dset = GET_SESSION_DSET(ss_new, old_anat, new_view);
3934 if( ISVALID_3DIM_DATASET(temp_dset) ) {
3935 new_anat = old_anat ;
3936 } else {
3937 for( ff=0 ; ff < ss_new->num_dsset ; ff++ ) { /* search */
3938 temp_dset = GET_SESSION_DSET(ss_new, ff, new_view);
3939 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
3940 }
3941 /* if( ISVALID_3DIM_DATASET(ss_new->dsset_xform_table[ff][new_view]) ) break ; */
3942
3943 if( ff < ss_new->num_dsset ) new_anat = ff ; /* found one */
3944 }
3945 if( new_anat < 0 ){ /* should not happen */
3946 BEEPIT ;
3947 WARNING_message("bad anat index when finalizing choice!") ;
3948 EXRETURN ; /* bad! */
3949 }
3950
3951 /* 03 Aug 2007: turn 'See Overlay' on? */
3952
3953 if( !im3d->vinfo->func_visible && im3d->vinfo->func_visible_count == 0 ){
3954 AFNI_SEE_FUNC_ON(im3d) ; OPEN_PANEL(im3d,func) ;
3955 im3d->vinfo->func_init_subbricks = 1 ; /* 12 Jan 2017 */
3956 if( im3d->vwid->func->do_setup ){
3957 int ii = (int)AFNI_numenv("AFNI_THRESH_INIT_EXPON") ;
3958 if( ii > 0 && ii < THR_top_expon ) AFNI_set_thresh_itop(im3d,ii) ;
3959 im3d->vwid->func->do_setup = 0 ;
3960 }
3961 }
3962
3963 /*--- switch to Hell? ---*/
3964
3965 } else {
3966 BEEPIT ;
3967 WARNING_message("bad switch?!") ;
3968 EXRETURN ; /* bad! */
3969 }
3970
3971 /*--- make sure all values are set OK-ly ---*/
3972
3973 if( new_view < 0 || new_sess < 0 || new_anat < 0 || new_func < 0 ){
3974 ERROR_message("Something bad happened when trying to 'Switch'\a") ;
3975 EXRETURN ; /* bad! */
3976 }
3977
3978 /*- beep & flash viewing control box if view type changes -*/
3979
3980 if( old_view != new_view ){
3981 static int nwarn=0 ;
3982 MCW_set_bbox( im3d->vwid->view->view_bbox , 1 << new_view ) ;
3983 UNCLUSTERIZE(im3d) ; /* 14 Feb 2008 */
3984
3985 /* this stuff is for Adam Thomas -- 18 Oct 2006 */
3986
3987 if( nwarn < 3 )
3988 WARNING_message("Forced switch from '%s' to '%s' [#%d]",
3989 VIEW_typestr[old_view] , VIEW_typestr[new_view] , nwarn+1 ) ;
3990
3991 if( AFNI_yesenv("AFNI_FLASH_VIEWSWITCH") ){
3992
3993 if( nwarn==0 && wcall != NULL ){
3994 char str[256] ;
3995 sprintf(str," \nForced switch from\n '%s'\nto\n '%s'\n ",
3996 VIEW_typestr[old_view] , VIEW_typestr[new_view] ) ;
3997 (void)MCW_popup_message( wcall, str, MCW_USER_KILL | MCW_TIMER_KILL ) ;
3998 }
3999
4000 if( wcall != NULL ){
4001 for( ii=0 ; ii < 3 ; ii++ ){
4002 MCW_invert_widget(im3d->vwid->view->view_bbox->wframe ); RWC_sleep(16);
4003 MCW_invert_widget(im3d->vwid->view->view_bbox->wrowcol); RWC_sleep(16);
4004 MCW_invert_widget(wcall) ;
4005 MCW_invert_widget(im3d->vwid->view->view_bbox->wframe ); RWC_sleep(16);
4006 MCW_invert_widget(im3d->vwid->view->view_bbox->wrowcol); RWC_sleep(16);
4007 MCW_invert_widget(wcall) ;
4008 }
4009 }
4010 }
4011
4012 nwarn++ ; /* 16 Sep 2009 */
4013 }
4014
4015 /*----- actually do the switch -----*/
4016
4017 if( im3d->vinfo->sess_num != new_sess ) /* disable FIMage in a new session */
4018 im3d->fimdata->fimdset = NULL ;
4019
4020 im3d->vinfo->view_type = new_view ;
4021 im3d->vinfo->sess_num = new_sess ;
4022 im3d->vinfo->anat_num = new_anat ;
4023 im3d->vinfo->func_num = new_func ;
4024
4025 if( new_func != old_func && im3d->vinfo->fim_autorange ) /* 20 Jun 2019 */
4026 reset_func_range_ncall[ AFNI_controller_index(im3d) ] = 0 ;
4027
4028 SHOW_AFNI_PAUSE ;
4029 AFNI_initialize_view( im3d->anat_now , im3d ) ;
4030 SHOW_AFNI_READY ;
4031 FIX_SCALE_SIZE(im3d) ;
4032
4033 if( AFNI_yesenv("AFNI_FLASH_VIEWSWITCH") && old_view != new_view ){ /* ending flash */
4034 BEEPIT ;
4035 for( ii=0 ; ii < 3 ; ii++ ){
4036 MCW_invert_widget( im3d->vwid->view->view_bbox->wframe ); RWC_sleep(16);
4037 MCW_invert_widget( im3d->vwid->view->view_bbox->wrowcol); RWC_sleep(16);
4038 MCW_invert_widget(wcall) ;
4039 MCW_invert_widget( im3d->vwid->view->view_bbox->wframe ); RWC_sleep(16);
4040 MCW_invert_widget( im3d->vwid->view->view_bbox->wrowcol); RWC_sleep(16);
4041 MCW_invert_widget(wcall) ;
4042 }
4043 }
4044
4045 if( wcall == im3d->vwid->view->choose_func_pb &&
4046 AFNI_yesenv("AFNI_THRESH_AUTO") ){ /* 05 Mar 2007 */
4047
4048 float new_thresh = AFNI_get_autothresh(im3d) ;
4049 if( new_thresh > 0.0f ) AFNI_set_threshold(im3d,new_thresh) ;
4050 }
4051
4052 if( wcall == im3d->vwid->view->choose_func_pb ){ /* ZSS 25 Feb 2010 */
4053 AFNI_set_dset_pbar((XtPointer)im3d);
4054 }
4055
4056 /* check obliquity of overlay and underlay */
4057 /* pop up warning if necessary */
4058
4059 if(wcall == im3d->vwid->view->choose_func_pb) {
4060 AFNI_check_obliquity(wcall,
4061 GET_SESSION_DSET(ss_new, new_func, 0),
4062 GET_SESSION_DSET(ss_new, new_anat, 0) );
4063 } else {
4064 AFNI_check_obliquity(wcall,
4065 GET_SESSION_DSET(ss_new, new_anat, 0),
4066 GET_SESSION_DSET(ss_new, new_func, 0) );
4067 }
4068 CLU_setup_alpha_tables(im3d) ;
4069
4070 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
4071 EXRETURN ;
4072 }
4073
4074 /*-----------------------------------------------------------*/
4075 /* check dataset for obliquity and pop-up warning if oblique */
4076
AFNI_check_obliquity(Widget w,THD_3dim_dataset * dset,THD_3dim_dataset * rset)4077 void AFNI_check_obliquity(Widget w, THD_3dim_dataset *dset,
4078 THD_3dim_dataset *rset)
4079 {
4080 double angle;
4081 char str[1024], sidcombo[256], *sid1=NULL, *sid2=NULL;
4082 static char *warncombos=NULL;
4083 static int num_warn = 0;
4084
4085 ENTRY("AFNI_check_obliquity");
4086 if( !ISVALID_DSET(dset) ) EXRETURN ;
4087
4088 if(AFNI_yesenv("AFNI_NO_OBLIQUE_WARNING")) EXRETURN;
4089
4090 if(AFNI_yesenv("AFNI_ONE_OBLIQUE_WARNING") && num_warn) EXRETURN;
4091
4092 angle = dset_obliquity_angle_diff(dset, rset, OBLIQ_ANGLE_THRESH);
4093 if(angle == 0.0) EXRETURN ;
4094
4095 /* A simple way to keep AFNI form complaining about obliquity all the time */
4096 sid1= DSET_IDCODE_STR(dset);
4097 if (rset) sid2 = DSET_IDCODE_STR(rset);
4098 else sid2 = "NA";
4099 if (!sid1) sid1="NO_ID1";
4100 if (!sid2) sid2="NO_ID2";
4101
4102 if (strcmp(sid1,sid2)<0) {
4103 sprintf(sidcombo,"-%s_WITH_%s-", sid1, sid2);
4104 } else {
4105 sprintf(sidcombo,"-%s_WITH_%s-", sid2, sid1);
4106 }
4107
4108 if (!warncombos) {
4109 warncombos = (char *)malloc(sizeof(char)*(strlen(sidcombo)+1));
4110 strcpy(warncombos,sidcombo);
4111 } else {
4112 if (strstr(warncombos,sidcombo)) EXRETURN;
4113 else {
4114 warncombos = (char *)realloc(warncombos,
4115 sizeof(char)*(strlen(sidcombo)+strlen(warncombos)+1));
4116 warncombos = strcat(warncombos, sidcombo);
4117 }
4118 }
4119
4120 if (AFNI_yesenv("AFNI_ONE_OBLIQUE_WARNING")) {
4121 snprintf( str, 1022*sizeof(char),
4122 " The underlay/overlay pair of datasets (%s/%s) have oblique angle \n"
4123 " difference of %f degrees. This may cause them to appear out of alignment \n"
4124 " in the viewer.\n"
4125 "\n"
4126 " If you are performing spatial transformations on an oblique dset, \n"
4127 " or viewing/combining it with volumes of differing obliquity,\n"
4128 " you should consider running: \n"
4129 " 3dWarp -deoblique \n"
4130 " on this and other oblique datasets in the same session.\n"
4131 "\n"
4132 " ** Other oblique warnings will be muted because AFNI_ONE_OBLIQUE_WARNING\n" " is set to YES. Consider setting it back to NO, obliquity warnings\n"
4133 " are much less overwhelming now.\n",
4134 DSET_PREFIX(dset), rset ? DSET_PREFIX(rset):"NA",
4135 angle );
4136 } else {
4137 snprintf( str, 1022*sizeof(char),
4138 " The underlay/overlay pair of datasets (%s/%s) have oblique angle \n"
4139 " difference of %f degrees. This may cause them to appear out of alignment \n"
4140 " in the viewer.\n"
4141 "\n"
4142 " If you are performing spatial transformations on an oblique dset, \n"
4143 " or viewing/combining it with volumes of differing obliquity,\n"
4144 " you should consider running: \n"
4145 " 3dWarp -deoblique \n"
4146 " on this and other oblique datasets in the same session.\n"
4147 "\n"
4148 " ** Warnings for the same data pair will be muted.\n",
4149 DSET_PREFIX(dset), rset ? DSET_PREFIX(rset):"NA",
4150 angle);
4151 }
4152 (void) MCW_popup_message( w , str, MCW_USER_KILL | MCW_TIMER_KILL ) ;
4153
4154 ++num_warn;
4155 EXRETURN ;
4156 }
4157
4158 /*----------------------------------------------------------------------
4159 Routines to close and open a file selection
4160 dialog associated with the im3d viewer.
4161 ------------------------------------------------------------------------*/
4162
AFNI_close_file_dialog_CB(Widget w,XtPointer cd,XtPointer cb)4163 void AFNI_close_file_dialog_CB( Widget w, XtPointer cd, XtPointer cb )
4164 {
4165 Three_D_View *im3d = (Three_D_View *) cd ;
4166
4167 ENTRY("AFNI_close_file_dialog") ;
4168
4169 if( IM3D_OPEN(im3d) && im3d->vwid->file_dialog != NULL )
4170 RWC_XtPopdown( im3d->vwid->file_dialog ) ;
4171
4172 EXRETURN ;
4173 }
4174
4175 /*----------------------------------------------------------------------
4176 After this is called, the calling routine must set the callbacks,
4177 window title, etc., appropriately.
4178 ------------------------------------------------------------------------*/
4179
AFNI_make_file_dialog(Three_D_View * im3d)4180 void AFNI_make_file_dialog( Three_D_View *im3d )
4181 {
4182 Widget www ;
4183
4184 ENTRY("AFNI_make_file_dialog") ;
4185
4186 /*** make a new dialog? ***/
4187
4188 if( im3d->vwid->file_dialog == NULL ){
4189 XmString oklabel , cancellabel ;
4190
4191 STATUS("creating new dialog") ;
4192
4193 im3d->vwid->file_dialog =
4194 XtVaCreatePopupShell(
4195 "menu" , xmDialogShellWidgetClass , im3d->vwid->top_shell ,
4196 XmNtitle , "GPL AFNI" ,
4197 XmNdeleteResponse , XmDO_NOTHING ,
4198 XmNinitialResourcesPersistent , False ,
4199 XmNkeyboardFocusPolicy , XmEXPLICIT ,
4200 NULL ) ;
4201
4202 XmAddWMProtocolCallback( /* make "Close" window menu work */
4203 im3d->vwid->file_dialog ,
4204 XmInternAtom( im3d->dc->display , "WM_DELETE_WINDOW" , False ) ,
4205 AFNI_close_file_dialog_CB , (XtPointer) im3d ) ;
4206
4207 /** change button labels to conform to other AFNI dialogs **/
4208
4209 oklabel = XmStringCreateLtoR( "Set" , XmFONTLIST_DEFAULT_TAG ) ;
4210 cancellabel = XmStringCreateLtoR( "Quit" , XmFONTLIST_DEFAULT_TAG ) ;
4211
4212 im3d->vwid->file_sbox =
4213 XtVaCreateManagedWidget(
4214 "menu" , xmFileSelectionBoxWidgetClass , im3d->vwid->file_dialog ,
4215 XmNfileTypeMask , XmFILE_ANY_TYPE ,
4216 XmNcancelLabelString , cancellabel ,
4217 XmNokLabelString , oklabel ,
4218 XmNtraversalOn , True ,
4219 XmNinitialResourcesPersistent , False ,
4220 NULL ) ;
4221
4222 XmStringFree(oklabel) ; XmStringFree(cancellabel) ;
4223
4224 im3d->vwid->file_cb = NULL ;
4225 im3d->vwid->file_cd = NULL ;
4226
4227 } else if( im3d->vwid->file_cb != NULL ){
4228 Widget www ;
4229
4230 STATUS("re-initializing old dialog") ;
4231
4232 /*** re-initialize an old dialog to have no callbacks ***/
4233
4234 XtRemoveCallback( im3d->vwid->file_sbox , XmNokCallback ,
4235 im3d->vwid->file_cb , im3d->vwid->file_cd ) ;
4236
4237 XtRemoveCallback( im3d->vwid->file_sbox , XmNcancelCallback ,
4238 im3d->vwid->file_cb , im3d->vwid->file_cd ) ;
4239
4240 XtRemoveCallback( im3d->vwid->file_sbox , XmNhelpCallback ,
4241 im3d->vwid->file_cb , im3d->vwid->file_cd ) ;
4242
4243 XtVaSetValues( im3d->vwid->file_sbox , XmNpattern,NULL , NULL ) ;
4244
4245 im3d->vwid->file_cb = NULL ;
4246 im3d->vwid->file_cd = NULL ;
4247
4248 XtVaSetValues(im3d->vwid->file_sbox,XmNfileTypeMask,XmFILE_ANY_TYPE,NULL);
4249 }
4250
4251 #if 0 /* doesn't work, because the button is a gadget, not a widget */
4252 www = XtNameToWidget( im3d->vwid->file_sbox , "OK" ) ;
4253 if( www != NULL )
4254 MCW_set_widget_bg( www , MCW_hotcolor(www) , 0 ) ;
4255 #endif
4256
4257 EXRETURN ;
4258 }
4259
4260 /*----------------------------------------------------------------
4261 Start getting ready to read a new session in. This
4262 is the CB for the "Read Sess" button. We'll get a filename
4263 from the user, and process it in another routine.
4264 ------------------------------------------------------------------*/
4265
AFNI_read_sess_CB(Widget w,XtPointer cd,XtPointer cb)4266 void AFNI_read_sess_CB( Widget w, XtPointer cd, XtPointer cb )
4267 {
4268 Three_D_View *im3d = (Three_D_View *)cd ;
4269 Widget www ;
4270
4271 ENTRY("AFNI_read_sess_CB") ;
4272
4273 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4274
4275 if( GLOBAL_library.sslist->num_sess >= THD_MAX_NUM_SESSION ){
4276 (void) MCW_popup_message( w ,
4277 "********************************\n"
4278 "** Maximum number of sessions **\n"
4279 "** would be exceeded. Sorry! **\n"
4280 "********************************"
4281 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4282 EXRETURN ;
4283 }
4284
4285 AFNI_make_file_dialog( im3d ) ;
4286
4287 XtAddCallback( im3d->vwid->file_sbox , XmNokCallback ,
4288 AFNI_finalize_read_sess_CB , cd ) ;
4289
4290 XtAddCallback( im3d->vwid->file_sbox , XmNcancelCallback ,
4291 AFNI_finalize_read_sess_CB , cd ) ;
4292
4293 XtAddCallback( im3d->vwid->file_sbox , XmNhelpCallback ,
4294 AFNI_finalize_read_sess_CB , cd ) ;
4295
4296 XtVaSetValues(im3d->vwid->file_sbox,XmNfileTypeMask,XmFILE_DIRECTORY,NULL);
4297 MCW_set_widget_label( XtNameToWidget(im3d->vwid->file_sbox,"Items") ,
4298 "Sessions" ) ;
4299
4300 im3d->vwid->file_cb = AFNI_finalize_read_sess_CB ;
4301 im3d->vwid->file_cd = cd ;
4302
4303 XtVaSetValues( im3d->vwid->file_dialog,
4304 XmNtitle, "AFNI: Read Session",
4305 NULL ) ;
4306
4307 XtPopup( im3d->vwid->file_dialog , XtGrabNone ) ; RWC_sleep(1);
4308 RWC_visibilize_widget( im3d->vwid->file_dialog ) ; /* 09 Nov 1999 */
4309 NORMAL_cursorize( im3d->vwid->file_dialog ) ;
4310
4311 EXRETURN ;
4312 }
4313
4314 /*---------------------------------------------------------------------
4315 Got a button press from the file selection dialog,
4316 so process it (maybe read in a new session!)
4317 -----------------------------------------------------------------------*/
4318
AFNI_finalize_read_sess_CB(Widget w,XtPointer cd,XtPointer cb)4319 void AFNI_finalize_read_sess_CB( Widget w, XtPointer cd, XtPointer cb )
4320 {
4321 Three_D_View *im3d = (Three_D_View *)cd ;
4322 XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *)cb ;
4323
4324 ENTRY("AFNI_finalize_read_sess_CB") ;
4325
4326 if( !IM3D_OPEN(im3d) || cbs == NULL ) EXRETURN ; /* 04 Feb 2008 */
4327
4328 switch( cbs->reason ){
4329
4330 /** close the file selection dialog **/
4331
4332 case XmCR_CANCEL:
4333 RWC_XtPopdown( im3d->vwid->file_dialog ) ;
4334 break ;
4335
4336 /** try to read a new session **/
4337
4338 case XmCR_OK:{
4339 char *text = NULL ;
4340 XmStringGetLtoR( cbs->value , XmFONTLIST_DEFAULT_TAG , &text ) ;
4341 if( text != NULL ){
4342
4343 THD_session *new_ss = NULL ;
4344
4345 /** if the user selected a file, strip it back to a directory **/
4346
4347 if(PRINT_TRACING)
4348 { char str[256] ; sprintf(str,"input text = %s",text) ; STATUS(str) ; }
4349
4350 if( THD_is_file(text) ){
4351 int ii = strlen(text)-1 ;
4352 for( ; ii > 0 && text[ii] != '/' ; ii-- ) text[ii] = '\0' ;
4353
4354 if(PRINT_TRACING)
4355 { char str[256] ; sprintf(str,"defiled text = %s",text) ; STATUS(str) ; }
4356 }
4357
4358 /** if the name given is a directory, try to read it **/
4359
4360 if( THD_is_directory(text) ){
4361 int ii , eq=0 ;
4362 THD_session *old_ss ;
4363
4364 /** 1st check if this is the same as some other session **/
4365
4366 STATUS("comparing to other sessions") ;
4367 for( ii=0 ; ii < GLOBAL_library.sslist->num_sess ; ii++ ){
4368 old_ss = GLOBAL_library.sslist->ssar[ii] ;
4369 eq = THD_equiv_files( old_ss->sessname , text ) ;
4370 if( eq == 1 ) break ;
4371 }
4372
4373 if( eq == 1 ){
4374 STATUS("illegal duplicate session") ;
4375 BEEPIT ;
4376 (void) MCW_popup_message( w ,
4377 "*******************************\n"
4378 "** Illegal duplicate session **\n"
4379 "*******************************"
4380 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4381 break ;
4382 } else {
4383 STATUS("reading new session") ;
4384 new_ss = THD_init_session( text ) ; /*** Read session! ***/
4385 }
4386 } else { /** wasn't a directory!? **/
4387
4388 STATUS("wasn't a directory") ;
4389 BEEPIT ;
4390 (void) MCW_popup_message( w ,
4391 "***********************************\n"
4392 "** Cannot find session directory **\n"
4393 "***********************************"
4394 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4395 break ;
4396 }
4397
4398 /** OK, was a directory and we tried to read it **/
4399
4400 if( new_ss == NULL || new_ss->num_dsset == 0 ){ /** failed to read anything **/
4401
4402 STATUS("failed to read new session") ;
4403 BEEPIT ;
4404 (void) MCW_popup_message( w ,
4405 "******************************\n"
4406 "** Cannot read any datasets **\n"
4407 "******************************"
4408 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4409
4410 } else if( GLOBAL_library.sslist->num_sess >= THD_MAX_NUM_SESSION ){
4411
4412 STATUS("too many sessions") ;
4413 BEEPIT ;
4414 (void) MCW_popup_message( w ,
4415 "****************************\n"
4416 "** Max number of sessions **\n"
4417 "** exceeded -- Sorry! **\n"
4418 "****************************"
4419 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4420
4421 } else { /** GOOD! Actually process a new session. **/
4422 /** (The following is from AFNI_read_inputs) **/
4423 int qd , vv ;
4424 char str[356] ; /* for messages */
4425 THD_3dim_dataset *dset ;
4426
4427 STATUS("processing new session") ;
4428
4429 new_ss->parent = NULL ;
4430
4431 for( qd=0 ; qd < new_ss->num_dsset ; qd++ ){ /* parentize */
4432 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
4433 dset = GET_SESSION_DSET(new_ss,qd,vv) ;
4434 /* dset = new_ss->dsset_xform_table[qd][vv] ;*/
4435 if( dset != NULL ){
4436 PARENTIZE( dset , NULL ) ;
4437 AFNI_inconstancy_check(NULL,dset) ; /* 06 Sep 2006 */
4438 }
4439 } }
4440 AFNI_inconstancy_check(im3d,NULL); /* 06 Sep 2006 */
4441
4442 /* 20 Dec 2001: if have global datasets, put them in here */
4443
4444 THD_append_sessions( new_ss , GLOBAL_library.session ) ;
4445
4446 /* if we were living with a dummy, fix that */
4447
4448 if( GLOBAL_library.have_dummy_dataset ) UNDUMMYIZE ;
4449
4450 /* put the new session into place in the list of sessions */
4451
4452 STATUS("adding new session to list") ;
4453 GLOBAL_library.sslist->ssar[GLOBAL_library.sslist->num_sess] = new_ss ;
4454 (GLOBAL_library.sslist->num_sess)++ ;
4455 THD_reconcile_parents( GLOBAL_library.sslist ) ;
4456 AFNI_force_adoption( new_ss , GLOBAL_argopt.warp_4D ) ; /* 28 Jan 2011 */
4457 AFNI_make_descendants( GLOBAL_library.sslist ) ; /* 28 Jan 2011 */
4458
4459 sprintf(str," \n Session #%2d"
4460 "\n %s"
4461 "\n %d datasets\n" ,
4462 GLOBAL_library.sslist->num_sess ,
4463 new_ss->sessname, new_ss->num_dsset ) ;
4464
4465 (void) MCW_popup_message( im3d->vwid->dmode->read_sess_pb,
4466 str, MCW_USER_KILL | MCW_TIMER_KILL ) ;
4467
4468 STATUS("rescanning timeseries files") ;
4469 AFNI_rescan_timeseries_CB(NULL,NULL,NULL) ;
4470
4471 /* 28 Aug 2002: deal with warptables */
4472
4473 if( new_ss->warptable != NULL ){
4474 if( GLOBAL_library.warptable == NULL ) /* create global warptable */
4475 GLOBAL_library.warptable = new_Htable(101) ;
4476 subsume_Htable( new_ss->warptable , GLOBAL_library.warptable ) ;
4477 destroy_Htable( new_ss->warptable ) ;
4478 new_ss->warptable = NULL ;
4479 }
4480
4481 RWC_XtPopdown( im3d->vwid->file_dialog ) ;
4482
4483 /* 04 Feb 2008: switch to this session */
4484
4485 if( !AFNI_noenv("AFNI_NEWSESSION_SWITCH") ){
4486 MCW_choose_cbs cbs;
4487 cbs.ival = GLOBAL_library.sslist->num_sess - 1 ;
4488 AFNI_finalize_dataset_CB( im3d->vwid->view->choose_sess_pb,
4489 (XtPointer)im3d , &cbs ) ;
4490 }
4491 } /* end of if we actually read a new session */
4492
4493 STATUS("freeing 'text' variable") ;
4494 myXtFree(text) ;
4495 }
4496 }
4497 break ;
4498
4499 case XmCR_HELP:
4500 (void) MCW_popup_message( w ,
4501 "To read in a new session, use the\n"
4502 "Directories and Sessions selectors,\n"
4503 "and the Filter entry and button,\n"
4504 "to get the 'Selection' box correct;\n"
4505 "that is, 'Selection' should be the\n"
4506 "be the name of the session directory.\n"
4507 "Then press 'Set'.\n"
4508 "\n"
4509 "How to Use the 'Directories' list:\n"
4510 " Click on or use arrow keys to select\n"
4511 " a directory, then press 'Enter' or\n"
4512 " double-click. This will set the\n"
4513 " Selection to that directory name,\n"
4514 " and will show the sub-directories\n"
4515 " in the Sessions list to the right.\n"
4516 "-----------------------------------\n"
4517 "N.B.: To see datasets in the new\n"
4518 " session, you must use the\n"
4519 " 'Switch Session' button!\n"
4520 , MCW_USER_KILL ) ;
4521 break ;
4522 }
4523 EXRETURN ;
4524 }
4525
4526 /*----------------------------------------------------------------
4527 Start getting ready to read a new timeseries in. This
4528 is the CB for the "Read 1D" button. We'll get a filename
4529 from the user, and process it in another routine.
4530 ------------------------------------------------------------------*/
4531
AFNI_read_1D_CB(Widget w,XtPointer cd,XtPointer cb)4532 void AFNI_read_1D_CB( Widget w, XtPointer cd, XtPointer cb )
4533 {
4534 Three_D_View *im3d = (Three_D_View *) cd ;
4535 XmString xstr ;
4536
4537 ENTRY("AFNI_read_1D_CB") ;
4538
4539 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4540
4541 AFNI_make_file_dialog( im3d ) ;
4542
4543 XtAddCallback( im3d->vwid->file_sbox , XmNokCallback ,
4544 AFNI_finalize_read_1D_CB , cd ) ;
4545
4546 XtAddCallback( im3d->vwid->file_sbox , XmNcancelCallback ,
4547 AFNI_finalize_read_1D_CB , cd ) ;
4548
4549 XtAddCallback( im3d->vwid->file_sbox , XmNhelpCallback ,
4550 AFNI_finalize_read_1D_CB , cd ) ;
4551
4552 XtVaSetValues(im3d->vwid->file_sbox,XmNfileTypeMask,XmFILE_REGULAR,NULL);
4553 MCW_set_widget_label( XtNameToWidget(im3d->vwid->file_sbox,"Items") ,
4554 "1D Files" ) ;
4555
4556
4557 /* 02 Feb 1998: put *.1D* in the filename pattern */
4558
4559 xstr = XmStringCreateLtoR( "*.1D*" , XmFONTLIST_DEFAULT_TAG ) ;
4560 XtVaSetValues( im3d->vwid->file_sbox ,
4561 XmNpattern , xstr ,
4562 NULL ) ;
4563 XmStringFree(xstr) ;
4564
4565 im3d->vwid->file_cb = AFNI_finalize_read_1D_CB ;
4566 im3d->vwid->file_cd = cd ;
4567
4568 XtVaSetValues( im3d->vwid->file_dialog,
4569 XmNtitle, "AFNI: Read 1D Timeseries",
4570 NULL ) ;
4571
4572 XtPopup( im3d->vwid->file_dialog , XtGrabNone ) ; RWC_sleep(1);
4573 RWC_visibilize_widget( im3d->vwid->file_dialog ) ; /* 09 Nov 1999 */
4574
4575 EXRETURN ;
4576 }
4577
4578 /*---------------------------------------------------------------------
4579 Got a button press from the file selection dialog,
4580 so process it (maybe read in a new timeseries!)
4581 -----------------------------------------------------------------------*/
4582
AFNI_finalize_read_1D_CB(Widget w,XtPointer cd,XtPointer cb)4583 void AFNI_finalize_read_1D_CB( Widget w, XtPointer cd, XtPointer cb )
4584 {
4585 Three_D_View *im3d = (Three_D_View *) cd ;
4586 XmFileSelectionBoxCallbackStruct *cbs = (XmFileSelectionBoxCallbackStruct *) cb ;
4587
4588 ENTRY("AFNI_finalize_read_1D_CB") ;
4589
4590 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4591
4592 switch( cbs->reason ){
4593
4594 /** close the file selection dialog **/
4595
4596 case XmCR_CANCEL:
4597 RWC_XtPopdown( im3d->vwid->file_dialog ) ;
4598 break ;
4599
4600 /** try to read a new timeseries **/
4601
4602 case XmCR_OK:{
4603 char *text = NULL ;
4604 MRI_IMAGE *flim ;
4605 float *far ;
4606 int ii ;
4607
4608 XmStringGetLtoR( cbs->value , XmFONTLIST_DEFAULT_TAG , &text ) ;
4609 flim = mri_read_1D( text ) ;
4610 if( flim == NULL || flim->nx < 2 ){
4611 BEEPIT ;
4612 (void) MCW_popup_message( w ,
4613 "********************************\n"
4614 "** Cannot read data from file **\n"
4615 "********************************"
4616 , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4617 myXtFree(text) ;
4618 break ;
4619 }
4620
4621 far = MRI_FLOAT_PTR(flim) ;
4622 for( ii=0 ; ii < flim->nvox ; ii++ )
4623 if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;
4624
4625 PLUTO_register_timeseries( text , flim ) ;
4626 mri_free(flim) ;
4627 myXtFree(text) ;
4628 RWC_XtPopdown( im3d->vwid->file_dialog ) ;
4629 }
4630 break ;
4631
4632 case XmCR_HELP:
4633 (void) MCW_popup_message( w ,
4634 "To read in a new timeseries, use the\n"
4635 "Directories and '1D Files' selectors,\n"
4636 "and the Filter entry and button,\n"
4637 "to get the 'Selection' box correct;\n"
4638 "that is, 'Selection' should be the\n"
4639 "be the name of the 1D file to read.\n"
4640 "Then press 'Set'.\n"
4641 "\n"
4642 "How to Use the 'Directories' list:\n"
4643 " Click on or use arrow keys to select\n"
4644 " a directory, then press 'Enter' or\n"
4645 " double-click. This will set the\n"
4646 " Selection to that directory name.\n"
4647 " You must then choose the 1D file you\n"
4648 " want from the '1D Files' list at the\n"
4649 " right.\n"
4650 , MCW_USER_KILL ) ;
4651 break ;
4652 }
4653 EXRETURN ;
4654 }
4655
4656 /*--------------------------------------------------------------------
4657 26 Mar 2001: read a dataset from the Web
4658 ----------------------------------------------------------------------*/
4659
AFNI_read_Web_CB(Widget w,XtPointer cd,XtPointer cb)4660 void AFNI_read_Web_CB( Widget w, XtPointer cd, XtPointer cb )
4661 {
4662 Three_D_View *im3d = (Three_D_View *) cd ;
4663 XmString xstr ;
4664
4665 ENTRY("AFNI_read_Web_CB") ;
4666
4667 #if 0
4668 if( AFNI_splash_isopen() == 1 ){ BEEPIT ; EXRETURN ; }
4669 #endif
4670
4671 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4672
4673 MCW_choose_string( w ,
4674 "Complete http:// or ftp:// address of dataset (.HEAD or .mnc or .mnc.gz):\n"
4675 "Examples: ftp://afni.nimh.nih.gov/AFNI/data/astrip+orig.HEAD\n"
4676 " https://afni.nimh.nih.gov/afni/norm305.mnc.gz"
4677 , NULL , AFNI_finalize_read_Web_CB , (XtPointer) im3d ) ;
4678
4679 EXRETURN ;
4680 }
4681
4682 /*--------------------------------------------------------------------*/
4683
AFNI_finalize_read_Web_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)4684 void AFNI_finalize_read_Web_CB( Widget w , XtPointer cd , MCW_choose_cbs *cbs )
4685 {
4686 Three_D_View *im3d = (Three_D_View *) cd ;
4687 THD_3dim_dataset *dset, *temp_dset ;
4688 RwcPointer_array *dsar ;
4689 THD_session *ss = GLOBAL_library.sslist->ssar[im3d->vinfo->sess_num] ;
4690 char str[256] ;
4691 int nds,dd,vv , nn, na=-1,nf=-1 ,nts ;
4692
4693 ENTRY("AFNI_finalize_read_Web_CB") ;
4694
4695 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4696
4697 if( cbs->reason != mcwCR_string ||
4698 cbs->cval == NULL ||
4699 cbs->cval[0] == '\0' ||
4700 (strstr(cbs->cval,"http://")==NULL && strstr(cbs->cval,"ftp://")==NULL) ){
4701
4702 (void) MCW_popup_message( im3d->vwid->dmode->read_Web_pb ,
4703 " \n** Illegal URL **\n " ,
4704 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4705
4706 BEEPIT ; EXRETURN ;
4707 }
4708
4709 /** read a list of datasets? **/
4710
4711 if( strstr(cbs->cval,"AFNILIST") != NULL ){
4712
4713 SHOW_AFNI_PAUSE ;
4714 dsar = THD_fetch_many_datasets( cbs->cval ) ; /* get array of datasets */
4715 SHOW_AFNI_READY ;
4716 if( dsar == NULL || dsar->num == 0 ){
4717 (void) MCW_popup_message( im3d->vwid->dmode->read_Web_pb ,
4718 " \n"
4719 "** Can't get datasets **\n"
4720 "** from that URL! **\n " ,
4721 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4722 BEEPIT ; EXRETURN ;
4723 }
4724
4725 } else { /** read one dataset **/
4726
4727 SHOW_AFNI_PAUSE ;
4728 dset = THD_fetch_dataset( cbs->cval ) ;
4729 SHOW_AFNI_READY ;
4730 if( dset == NULL ){
4731 (void) MCW_popup_message( im3d->vwid->dmode->read_Web_pb ,
4732 " \n"
4733 "** Can't get a dataset **\n"
4734 "** from that URL! **\n " ,
4735 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4736 BEEPIT ; EXRETURN ;
4737 }
4738 INIT_XTARR(dsar) ; ADDTO_XTARR(dsar,dset) ; XTARR_IC(dsar,0) = IC_DSET ;
4739 }
4740
4741 /** loop over all datasets in array, place in current session **/
4742
4743 for( nts=nds=dd=0 ; dd < dsar->num ; dd++ ){
4744
4745 if( XTARR_IC(dsar,dd) == IC_FLIM ){ /* process a 1D file */
4746 AFNI_add_timeseries( (MRI_IMAGE *) XTARR_XT(dsar,dd) ) ;
4747 nts++ ; continue ;
4748 }
4749 if( XTARR_IC(dsar,dd) != IC_DSET ) continue ; /* bad */
4750
4751 dset = (THD_3dim_dataset *) XTARR_XT(dsar,dd) ;
4752 if( !ISVALID_DSET(dset) ) continue ; /* bad */
4753 AFNI_inconstancy_check(NULL,dset) ; /* 06 Sep 2006 */
4754 vv = dset->view_type ;
4755 nn = ss->num_dsset ;
4756 if( nn >= THD_MAX_SESSION_SIZE ){
4757 fprintf(stderr,"\a\n*** too many anatomical datasets!\n") ;
4758 DSET_delete(dset) ; /* 01 Nov 2001 */
4759 } else {
4760 SET_SESSION_DSET(dset,ss,nn,vv) ;
4761 /* ss->dsset_xform_table[nn][vv] = dset ;*/
4762 ss->num_dsset++ ; nds++ ;
4763 if( vv == im3d->vinfo->view_type && na == -1 ) na = nn ;
4764 }
4765 } /* end of loop over dd=datasets in dsar */
4766
4767 FREE_XTARR(dsar) ;
4768 AFNI_inconstancy_check(im3d,NULL); /* 06 Sep 2006 */
4769
4770 /*-- popup a message saying what happened --*/
4771
4772 if( nts > 0 )
4773 sprintf(str," \n Read %d datasets and \n"
4774 " %d timeseries from\n"
4775 " %s\n ",nds,nts,cbs->cval ) ;
4776 else
4777 sprintf(str," \n Read %d datasets from\n"
4778 " %s\n ",nds,cbs->cval ) ;
4779
4780 (void) MCW_popup_message( im3d->vwid->dmode->read_Web_pb ,
4781 str , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4782
4783 if( nds == 0 ){ EXRETURN; }
4784
4785 /*-- prepare to switch back to AFNI --*/
4786
4787 if( na >= 0 ) im3d->vinfo->anat_num = na ; /* 1st new anat in current view */
4788 if( nf >= 0 ) im3d->vinfo->func_num = nf ; /* 1st new func in current view */
4789
4790 if( GLOBAL_library.have_dummy_dataset ){ /* switch away from dummy dataset */
4791 UNDUMMYIZE ;
4792 if( na < 0 && ss->num_dsset > 1 ){
4793 im3d->vinfo->anat_num = 1 ;
4794 im3d->vinfo->func_num = 1 ; /* 07 Sep 2006 (oops) */
4795 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
4796 temp_dset = GET_SESSION_DSET(ss,1,vv);
4797 if( ISVALID_DSET(temp_dset) ){
4798 im3d->vinfo->view_type = vv; break;
4799 }
4800 }
4801 } else if( na < 0 ){ /* should be impossible */
4802 (void) MCW_popup_message( im3d->vwid->dmode->read_Web_pb ,
4803 " \n** No datasets available **\n " ,
4804 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4805 }
4806 }
4807
4808 AFNI_initialize_view( NULL , im3d ) ;
4809 EXRETURN ;
4810 }
4811
4812 /*----------------------------------------------------------------
4813 Obey the command to rescan the current session
4814 ------------------------------------------------------------------*/
4815
AFNI_rescan_CB(Widget w,XtPointer cd,XtPointer cb)4816 void AFNI_rescan_CB( Widget w, XtPointer cd, XtPointer cb )
4817 {
4818 Three_D_View *im3d = (Three_D_View *)cd , *qq3d ;
4819 int cc ;
4820 char str[256+THD_MAX_NAME] ;
4821
4822 ENTRY("AFNI_rescan_CB") ;
4823
4824 if( !IM3D_OPEN(im3d) ) EXRETURN ;
4825
4826 SHOW_AFNI_PAUSE ;
4827 cc = AFNI_rescan_session( im3d->vinfo->sess_num ) ;
4828 POPDOWN_strlist_chooser ;
4829 if( cc > 0 ){
4830 sprintf(str," \n"
4831 " Added %d datasets to \n"
4832 " %s\n" ,
4833 cc ,
4834 GLOBAL_library.sslist->ssar[im3d->vinfo->sess_num]->sessname ) ;
4835 (void) MCW_popup_message( w , str , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4836 }
4837
4838 #if 1
4839 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){ /* 31 Mar 1999 */
4840 qq3d = GLOBAL_library.controllers[cc] ;
4841 if( IM3D_OPEN(qq3d) ) AFNI_process_dsetchange( qq3d ) ;
4842 }
4843 #endif
4844
4845 SHOW_AFNI_READY ;
4846 EXRETURN ;
4847 }
4848
4849 /*----------------------------------------------------------------*/
4850 /* 10 Nov 2005: check periodically for updated datasets */
4851
4852 static int block_rescan = 0 ;
AFNI_block_rescan(int bb)4853 void AFNI_block_rescan( int bb ){ block_rescan = bb ; }
4854
AFNI_rescan_timeout_CB(XtPointer client_data,XtIntervalId * id)4855 void AFNI_rescan_timeout_CB( XtPointer client_data , XtIntervalId *id )
4856 {
4857 XtAppContext *apc = (XtAppContext *)client_data ;
4858
4859 ENTRY("AFNI_rescan_timeout_CB") ;
4860 if( !block_rescan ) AFNI_rescan_all_CB(NULL,NULL,NULL) ;
4861 (void) XtAppAddTimeOut( *apc, 14999, AFNI_rescan_timeout_CB, apc ) ;
4862 EXRETURN ;
4863 }
4864
4865 /*----------------------------------------------------------------*/
4866
AFNI_rescan_all_CB(Widget w,XtPointer cd,XtPointer cb)4867 void AFNI_rescan_all_CB( Widget w, XtPointer cd, XtPointer cb )
4868 {
4869 int iss , cc=0 , uu=(w!=(Widget)NULL) , pp=0 ;
4870 Three_D_View *im3d ;
4871
4872 ENTRY("AFNI_rescan_all_CB") ;
4873
4874 for( iss=0 ; iss < GLOBAL_library.sslist->num_sess ; iss++ ){
4875 cc += AFNI_rescan_session( iss ) ;
4876 if( pp==0 && cc > 0 ){ SHOW_AFNI_PAUSE; pp=1; }
4877 }
4878 if( cc > 0 && uu ){
4879 char str[256] ;
4880 POPDOWN_strlist_chooser ;
4881 sprintf(str," \n"
4882 " Added %d datasets total \n" , cc ) ;
4883 (void) MCW_popup_message( w , str , MCW_USER_KILL | MCW_TIMER_KILL ) ;
4884 } else if( cc == 0 && uu ){
4885 (void) MCW_popup_message( w ,
4886 " \n Found no new datasets \n" ,
4887 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4888 }
4889
4890 #if 1
4891 if( cc > 0 ){
4892 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){ /* 31 Mar 1999 */
4893 im3d = GLOBAL_library.controllers[cc] ;
4894 if( IM3D_OPEN(im3d) ) AFNI_process_dsetchange( im3d ) ;
4895 }
4896 }
4897 #endif
4898
4899 if( pp ) SHOW_AFNI_READY ;
4900 EXRETURN ;
4901 }
4902
4903 /*----------------------------------------------------------------------*/
4904 /*!
4905 Re-read the session indexed by "sss". THE OLD WAY.
4906 Much of this code is taken from AFNI_read_inputs.
4907 WARNING: this will do bad things if the user deletes the
4908 session directory or the current active datasets within it
4909 before trying this. On the other hand, if the user is that
4910 stupid, bad things will probably have happened to him already
4911 (like being unable to open dataset files, or being unable to
4912 tie his shoes correctly, or being named Mike Beauchamp).
4913 ------------------------------------------------------------------------*/
4914
AFNI_rescan_session_OLD(int sss)4915 static int AFNI_rescan_session_OLD( int sss ) /* the old way */
4916 {
4917 int vv , ii , cc , nold,nnew ;
4918 THD_session *new_ss , *old_ss ;
4919 Three_D_View *im3d ;
4920 MCW_idcode anat_idcode[MAX_CONTROLLERS] ,
4921 func_idcode[MAX_CONTROLLERS] ;
4922 THD_slist_find find ;
4923 THD_3dim_dataset *dset, *temp_dset ;
4924
4925 ENTRY("AFNI_rescan_session_OLD") ;
4926 { char str[256]; sprintf(str,"session index %d\n",sss); STATUS(str); }
4927
4928 if( GLOBAL_library.have_dummy_dataset ){ RETURN(0) ; }
4929
4930 #if 0
4931 fprintf(stderr,"Enter AFNI_rescan_session_OLD on session index %d\n",sss) ;
4932 #endif
4933
4934 /*--- sanity checks ---*/
4935
4936 if( sss < 0 || sss >= GLOBAL_library.sslist->num_sess ){ RETURN(0) ; }
4937
4938 old_ss = GLOBAL_library.sslist->ssar[sss] ;
4939 if( ! ISVALID_SESSION(old_ss) || old_ss->is_collection ){ RETURN(0); }
4940
4941 if( old_ss == GLOBAL_library.session ) RETURN(0) ; /* 21 Dec 2001 */
4942
4943 if( ! THD_is_directory(old_ss->sessname) ) RETURN(0) ; /* 02 Jun 2016 */
4944
4945 /*--- Make sure that the dataset choosers are closed.
4946 Since these are just instances of the generic strlist
4947 chooser, and we can't tell what is being chosen just now,
4948 we'll just forcibly close the strlist chooser no matter what. ---*/
4949
4950 POPDOWN_strlist_chooser ;
4951
4952 /*--- mark all datasets in the old session for deletion from memory ---*/
4953
4954 STATUS("marking old session datasets") ;
4955
4956 nold = old_ss->num_dsset ;
4957
4958 for( ii=0 ; ii < old_ss->num_dsset ; ii++ )
4959 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
4960 temp_dset = GET_SESSION_DSET(old_ss, ii, vv);
4961 if( ISVALID_3DIM_DATASET(temp_dset) ){
4962 /* if( ISVALID_3DIM_DATASET(old_ss->dsset_xform_table[ii][vv]) )*/
4963 if( DSET_in_global_session(temp_dset) )
4964 SET_SESSION_DSET(NULL, old_ss, ii, vv);
4965 /* if( DSET_in_global_session(old_ss->dsset_xform_table[ii][vv]) )*/
4966 /* old_ss->dsset_xform_table[ii][vv] = NULL ; */ /* will be added back in later */
4967 else
4968 DSET_MARK_FOR_DEATH( temp_dset ) ;
4969 /* DSET_MARK_FOR_DEATH( old_ss->dsset_xform_table[ii][vv] ) ;*/
4970 }
4971 }
4972 /*--- mark all descendants for purging as well ---*/
4973
4974 AFNI_mark_for_death( GLOBAL_library.sslist ) ;
4975
4976 /*--- but before actual deletion, find the
4977 active datasets in each main controller window ---*/
4978
4979 STATUS("checking active controllers") ;
4980
4981 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
4982 ZERO_IDCODE(anat_idcode[cc]) ; ZERO_IDCODE(func_idcode[cc]) ;
4983 im3d = GLOBAL_library.controllers[cc] ;
4984 if( IM3D_OPEN(im3d) && im3d->vinfo->sess_num == sss ){
4985 anat_idcode[cc] = im3d->anat_now->idcode ;
4986
4987 if( ISVALID_3DIM_DATASET(im3d->fim_now) )
4988 func_idcode[cc] = im3d->fim_now->idcode ;
4989
4990 XmUpdateDisplay(im3d->vwid->top_shell) ;
4991 }
4992 }
4993
4994 /*--- now can flush the old datasets, prior to reading again ---*/
4995
4996 AFNI_andersonville( GLOBAL_library.sslist , False ) ; /* keep files! */
4997
4998 /*--- now read in the session again ---*/
4999
5000 STATUS("rescanning session now:") ;
5001 STATUS(old_ss->sessname) ;
5002
5003 new_ss = THD_init_session( old_ss->sessname ) ;
5004
5005 if( new_ss == NULL || new_ss->num_dsset <= 0 ){
5006 fprintf(stderr,"\n*** Fatal error: Rescan of session %s finds nothing!\n",
5007 old_ss->sessname ) ;
5008 EXIT(1) ;
5009 }
5010
5011 myXtFree( old_ss ) ; /* no longer need this */
5012
5013 /* set parent pointers */
5014
5015 STATUS("PARENTIZE-ing datasets in new session") ;
5016
5017 new_ss->parent = NULL ;
5018 for( ii=0 ; ii < new_ss->num_dsset ; ii++ ){
5019 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
5020 dset = GET_SESSION_DSET(new_ss, ii, vv);
5021 /* dset = new_ss->dsset_xform_table[ii][vv] ;*/
5022 if( dset != NULL ){
5023 PARENTIZE( dset, NULL ) ;
5024 /* PARENTIZE( new_ss->dsset_xform_table[ii][vv] , NULL ) ;*/
5025 AFNI_inconstancy_check(NULL,dset) ; /* 06 Sep 2006 */
5026 }
5027 } }
5028 AFNI_inconstancy_check(NULL,NULL);
5029
5030 /* put the new session into place in the list of sessions */
5031
5032 GLOBAL_library.sslist->ssar[sss] = new_ss ;
5033
5034 /* 20 Dec 2001: add the global datasets back in, if any */
5035
5036 THD_append_sessions( new_ss , GLOBAL_library.session ) ;
5037
5038 /* assign the warp and anatomy parent pointers;
5039 then, make any datasets that don't exist but logically
5040 descend from the warp and anatomy parents just assigned */
5041
5042 THD_reconcile_parents( GLOBAL_library.sslist ) ;
5043 AFNI_force_adoption( new_ss , GLOBAL_argopt.warp_4D ) ;
5044 AFNI_make_descendants( GLOBAL_library.sslist ) ;
5045
5046 /* 28 Aug 2002: deal with warptables */
5047
5048 if( new_ss->warptable != NULL ){
5049 if( GLOBAL_library.warptable == NULL ) /* create global warptable */
5050 GLOBAL_library.warptable = new_Htable(101) ;
5051 subsume_Htable( new_ss->warptable , GLOBAL_library.warptable ) ;
5052 destroy_Htable( new_ss->warptable ) ;
5053 new_ss->warptable = NULL ;
5054 }
5055
5056 /*--- for each main controller window, must reset some pointers ---*/
5057
5058 STATUS("fixing active controllers") ;
5059
5060 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
5061 im3d = GLOBAL_library.controllers[cc] ;
5062 if( IM3D_OPEN(im3d) && im3d->vinfo->sess_num == sss ){
5063 im3d->ss_now = new_ss ;
5064 vv = im3d->vinfo->view_type ; /* won't change this */
5065
5066 im3d->fimdata->fimdset = NULL ; /* disable FIMage */
5067
5068 /* look for old anat dataset in new session */
5069
5070 find = THD_dset_in_session( FIND_IDCODE ,
5071 &(anat_idcode[cc]) , new_ss ) ;
5072
5073 /* if have it, use it, otherwise, pick first anat in this view */
5074
5075 if( find.dset != NULL && find.view_index == vv ){
5076 im3d->vinfo->anat_num = find.dset_index ;
5077 } else {
5078 for( ii=0 ; ii < new_ss->num_dsset ; ii++ ) {
5079 temp_dset = GET_SESSION_DSET(new_ss, ii, vv);
5080 if( ISVALID_3DIM_DATASET(temp_dset)) break ;
5081 /* if( ISVALID_3DIM_DATASET(new_ss->dsset_xform_table[ii][vv]) ) break ;*/
5082 }
5083 if( ii < new_ss->num_dsset ){
5084 im3d->vinfo->anat_num = ii ;
5085 } else {
5086 fprintf(stderr,
5087 "\n*** Fatal error:"
5088 " Cannot find anat dataset to switch to after"
5089 " rescanning session %s\a\n",
5090 new_ss->sessname ) ;
5091 EXIT(1) ;
5092 }
5093 }
5094
5095 /* do the same for old func dataset, if any */
5096
5097 if( ! ISZERO_IDCODE(func_idcode[cc]) ){
5098 find = THD_dset_in_session( FIND_IDCODE ,
5099 &(func_idcode[cc]) , new_ss ) ;
5100
5101 if( find.dset != NULL && find.view_index == vv ){
5102 im3d->vinfo->func_num = find.dset_index ;
5103 } else {
5104 for( ii=0 ; ii < new_ss->num_dsset ; ii++ ) {
5105 temp_dset = GET_SESSION_DSET(new_ss, ii, vv);
5106 if( ISVALID_3DIM_DATASET(temp_dset) ) break ;
5107 /* if( ISVALID_3DIM_DATASET(new_ss->dsset_xform_table[ii][vv]) ) break ;*/
5108 }
5109 if( ii < new_ss->num_dsset ){
5110 im3d->vinfo->func_num = ii ;
5111 } else {
5112 im3d->vinfo->func_num = 0 ; /* no func is not fatal */
5113 }
5114 }
5115 } else {
5116 im3d->vinfo->func_num = 0 ;
5117 }
5118
5119 /* switch this controller to the new datasets */
5120
5121 AFNI_initialize_view( NULL , im3d ) ;
5122 XmUpdateDisplay(im3d->vwid->top_shell) ;
5123 }
5124 }
5125
5126 nnew = new_ss->num_dsset ;
5127
5128 RETURN( (nnew-nold) ) ;
5129 }
5130
5131 /*----------------------------------------------------------------------*/
5132 /*!
5133 Re-read the session indexed by "sss". THE NEW WAY.
5134 Much of this code is taken from AFNI_read_inputs().
5135
5136 WARNING:
5137 - This will do bad things if the user deletes the session directory
5138 or the current active datasets within it before trying this.
5139 - On the other hand, if the user is that stupid, bad things will
5140 probably have happened to him already (like being unable to open
5141 dataset files, or being unable to tie his shoes correctly).
5142
5143 28 Dec 2002: modified extensively to not clobber existing pointers
5144 to datasets, but instead to insert new datasets into the
5145 existing session -- RWCox (MX&HNY)
5146 ------------------------------------------------------------------------*/
5147
AFNI_rescan_session_NEW(int sss)5148 static int AFNI_rescan_session_NEW( int sss ) /* the new way */
5149 {
5150 int vv , ii , nr , na_new=0 ;
5151 THD_session *new_ss , *old_ss ;
5152 THD_slist_find find ;
5153 THD_3dim_dataset *new_dset, *temp_dset ;
5154
5155 ENTRY("AFNI_rescan_session_NEW") ;
5156 { char str[256]; sprintf(str,"session index %d\n",sss); STATUS(str); }
5157
5158 if( GLOBAL_library.have_dummy_dataset ){ RETURN(0); }
5159
5160 #if 0
5161 fprintf(stderr,"Enter AFNI_rescan_session_NEW on session index %d\n",sss) ;
5162 #endif
5163
5164 /*--- sanity checks ---*/
5165
5166 if( sss < 0 || sss >= GLOBAL_library.sslist->num_sess ){ RETURN(0); }
5167
5168 old_ss = GLOBAL_library.sslist->ssar[sss] ;
5169 if( ! ISVALID_SESSION(old_ss) || old_ss->is_collection ){ RETURN(0); }
5170
5171 /* can't rescan global session */
5172 if( old_ss == GLOBAL_library.session ) RETURN(0); /* 21 Dec 2001 */
5173
5174 if( ! THD_is_directory(old_ss->sessname) ) RETURN(0) ; /* 02 Jun 2016 */
5175
5176 /*--- read in the session again, into a new THD_session struct ---*/
5177
5178 STATUS("rescanning session now:") ;
5179 STATUS(old_ss->sessname) ;
5180
5181 new_ss = THD_init_session( old_ss->sessname ) ;
5182 if( ! ISVALID_SESSION(new_ss) ){ RETURN(0); } /* this is BAD */
5183
5184 /*--- scan datasets and remove those
5185 that already exist in this session ---*/
5186
5187 for( ii=0 ; ii < new_ss->num_dsset ; ii++ ){
5188 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ){
5189 new_dset = GET_SESSION_DSET(new_ss, ii, vv);
5190 /* new_dset = new_ss->dsset_xform_table[ii][vv] ;*/
5191 if( ISVALID_DSET(new_dset) ){
5192 find = THD_dset_in_session( FIND_IDCODE, &(new_dset->idcode), old_ss );
5193 if( find.dset == NULL ){
5194 find = THD_dset_in_session(FIND_PREFIX, DSET_PREFIX(new_dset),old_ss);
5195 if( find.dset != NULL && find.view_index != vv ) find.dset = NULL ;
5196 }
5197 if( find.dset != NULL ){
5198 DSET_delete(new_dset);
5199 SET_SESSION_DSET(NULL, new_ss, ii, vv);
5200 /* new_ss->dsset_xform_table[ii][vv] = NULL;*/
5201 }
5202 }
5203 }
5204 }
5205
5206 /*--- now scan survivors and put them
5207 at the end of the existing session ---*/
5208
5209 for( ii=0 ; ii < new_ss->num_dsset ; ii++ ){
5210 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ) /* see if row is empty */
5211 if( GET_SESSION_DSET(new_ss, ii, vv) != NULL ) break ;
5212 /* if( new_ss->dsset_xform_table[ii][vv] != NULL ) break ;*/
5213 if( vv > LAST_VIEW_TYPE ) continue ; /* empty row ==> skip */
5214 AFNI_inconstancy_check(NULL,GET_SESSION_DSET(new_ss, ii,vv)) ; /* 06 Sep 2006 */
5215 /* AFNI_inconstancy_check(NULL,new_ss->dsset_xform_table[ii][vv]) ;*/ /* 06 Sep 2006 */
5216 nr = old_ss->num_dsset ; /* next row in old_ss */
5217 if( nr >= THD_MAX_SESSION_SIZE ) break ; /* old session is full */
5218 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ) { /* copy new row to old */
5219 temp_dset = GET_SESSION_DSET(new_ss, ii, vv);
5220 SET_SESSION_DSET(temp_dset, old_ss, nr, vv);
5221 /* old_ss->dsset_xform_table[nr][vv] = new_ss->dsset_xform_table[ii][vv];*/
5222 }
5223 old_ss->num_dsset++ ; na_new++ ; /* 1 more row in old */
5224 }
5225 if( na_new == 0 ) RETURN(0) ; /* 10 Nov 2005 */
5226 AFNI_inconstancy_check(NULL,NULL); /* 06 Sep 2006 */
5227
5228 /*-- 15 Jan 2003: purge all datasets from memory (for Hauke Heekeren) --*/
5229
5230 for( ii=0 ; ii < old_ss->num_dsset ; ii++ )
5231 for( vv=0 ; vv <= LAST_VIEW_TYPE ; vv++ ) {
5232 temp_dset = GET_SESSION_DSET(old_ss, ii, vv);
5233 if( temp_dset != NULL ) DSET_unload(temp_dset);
5234 /* if( old_ss->dsset_xform_table[ii][vv] != NULL ) DSET_unload(old_ss->dsset_xform_table[ii][vv]);*/
5235 }
5236 /* assign the warp and anatomy parent pointers;
5237 then, make any datasets that don't exist but logically
5238 descend from the warp and anatomy parents just assigned */
5239
5240 THD_reconcile_parents( GLOBAL_library.sslist ) ;
5241 AFNI_force_adoption( old_ss , GLOBAL_argopt.warp_4D ) ;
5242 AFNI_make_descendants( GLOBAL_library.sslist ) ;
5243
5244 /* 28 Aug 2002: deal with warptables */
5245
5246 if( new_ss->warptable != NULL ){
5247 if( GLOBAL_library.warptable == NULL ) /* create global warptable */
5248 GLOBAL_library.warptable = new_Htable(101) ;
5249 subsume_Htable( new_ss->warptable , GLOBAL_library.warptable ) ;
5250 destroy_Htable( new_ss->warptable ) ;
5251 new_ss->warptable = NULL ;
5252 }
5253 free(new_ss) ;
5254
5255 RETURN(na_new) ;
5256 }
5257
5258 /*----------------------------------------------------------------------*/
5259 /*! Use the old or the new rescan session methods -- 07 Feb 2003.
5260 ------------------------------------------------------------------------*/
5261
AFNI_rescan_session(int sss)5262 int AFNI_rescan_session( int sss )
5263 {
5264 char *eee = getenv("AFNI_RESCAN_METHOD") ;
5265 int use_new , use_rep ;
5266 static int first=1 ;
5267
5268 use_rep = ( eee != NULL && strcasecmp(eee,"REPLACE") == 0 ) ;
5269
5270 use_new = ( AFNI_yesenv("AFNI_AUTO_RESCAN") ||
5271 AFNI_yesenv("AFNI_RESCAN_AT_SWITCH") || !use_rep ) ;
5272
5273 if( use_rep && use_new && first ){ /* 07 Oct 2008 */
5274 WARNING_message(
5275 " \n"
5276 " AFNI_RESCAN_METHOD = REPLACE is incompatible with\n"
5277 " AFNI_AUTO_RESCAN = YES and/or AFNI_RESCAN_AT_SWITCH = YES" ) ;
5278 first = 0 ;
5279 }
5280
5281 return (use_new) ? AFNI_rescan_session_NEW( sss )
5282 : AFNI_rescan_session_OLD( sss ) ;
5283 }
5284
5285 /*---------------------------------------------------------------
5286 Rescan for timeseries files
5287 -----------------------------------------------------------------*/
5288
AFNI_rescan_timeseries_CB(Widget w,XtPointer cd,XtPointer cb)5289 void AFNI_rescan_timeseries_CB(Widget w, XtPointer cd, XtPointer cb)
5290 {
5291 int iss , inew , jold , nnew , nold , nadd ;
5292 THD_string_array *dlist ;
5293 THD_session *ss ;
5294 MRI_IMARR *newtsar ;
5295 MRI_IMAGE *newim , *oldim ;
5296 NI_ELARR *newtsvar ; /* 16 Jun 2020 */
5297 NI_element *newel , *oldel ;
5298
5299 ENTRY("AFNI_rescan_timeseries_CB") ;
5300
5301 /** assemble list of directories **/
5302
5303 if( GLOBAL_library.have_dummy_dataset ){ EXRETURN ; }
5304
5305 INIT_SARR( dlist ) ;
5306
5307 for( iss=0 ; iss < GLOBAL_library.sslist->num_sess ; iss++ ){
5308 ss = GLOBAL_library.sslist->ssar[iss] ;
5309 if( ss->is_collection ) continue ;
5310 ADDTO_SARR(dlist,ss->sessname) ;
5311 }
5312
5313 if( dlist->num == 0 ){ DESTROY_SARR(dlist) ; EXRETURN ; }
5314
5315 /** read timeseries into a new array **/
5316
5317 newtsar = THD_get_many_timeseries( dlist ) ;
5318 newtsvar = THD_get_many_tcsv( dlist ) ;
5319 DESTROY_SARR( dlist ) ;
5320
5321 if( newtsar != NULL ){ /** check to see which ones are in the old list **/
5322
5323 nnew = IMARR_COUNT(newtsar) ;
5324 nold = IMARR_COUNT(GLOBAL_library.timeseries) ;
5325
5326 for( nadd=inew=0 ; inew < nnew ; inew++ ){
5327 newim = IMARR_SUBIMAGE(newtsar,inew) ; /* new timeseries */
5328 for( jold=0 ; jold < nold ; jold++ ){
5329 oldim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,jold) ; /* old one */
5330
5331 if( oldim != NULL && oldim->name != NULL && /* break out of loop */
5332 strcmp(oldim->name,newim->name) == 0 ) break ; /* when new == old */
5333 }
5334
5335 if( jold == nold ){
5336 ADDTO_IMARR(GLOBAL_library.timeseries,newim); nadd++; /* is new */
5337 } else {
5338 mri_free(newim) ; /* is old */
5339 }
5340 }
5341 if( nadd > 0 ) POPDOWN_timeseries_chooser ;
5342 FREE_IMARR(newtsar) ; newtsar = NULL ;
5343 }
5344
5345 if( newtsvar != NULL ){ /* repeat for tcsv files */
5346
5347 nnew = ELARR_COUNT(newtsvar) ;
5348 nold = ELARR_COUNT(GLOBAL_library.tcsv_data) ;
5349
5350 for( nadd=inew=0 ; inew < nnew ; inew++ ){
5351 newel = ELARR_SUBEL(newtsvar,inew) ; /* new data */
5352 for( jold=0 ; jold < nold ; jold++ ){
5353 oldel = ELARR_SUBEL(GLOBAL_library.tcsv_data,jold) ; /* old one */
5354
5355 if( oldel != NULL && /* break out of loop */
5356 strcmp(oldel->filename,newel->filename) == 0 ) break ; /* when new == old */
5357 }
5358
5359 if( jold == nold ){
5360 ADDTO_ELARR(GLOBAL_library.tcsv_data,newel); nadd++; /* is new */
5361 } else {
5362 NI_free_element(newel) ; /* is old */
5363 }
5364 }
5365 /* if( nadd > 0 ) POPDOWN_timeseries_chooser ; */
5366 FREE_ELARR(newtsvar) ;
5367 }
5368
5369 EXRETURN ;
5370 }
5371
5372 /*---------------------------------------------------------------
5373 callback for the anatmode bbox
5374 -----------------------------------------------------------------*/
5375
AFNI_anatmode_CB(Widget w,XtPointer cd,XtPointer cb)5376 void AFNI_anatmode_CB( Widget w, XtPointer cd, XtPointer cb )
5377 {
5378 Three_D_View *im3d = (Three_D_View *) cd ;
5379 int old_val , new_val ;
5380 THD_fvec3 fv ;
5381 THD_ivec3 iv ;
5382
5383 ENTRY("AFNI_anatmode_CB") ;
5384
5385 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
5386
5387 im3d->vinfo->stats_anat_ok =
5388 im3d->vinfo->stats_func_ok =
5389 im3d->vinfo->arang_func_ok =
5390 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
5391
5392 old_val = 1 << im3d->vinfo->force_anat_wod ;
5393 new_val = MCW_val_bbox( im3d->vwid->dmode->anatmode_bbox ) ;
5394
5395 if(PRINT_TRACING){
5396 char str[256] ; sprintf(str,"old_val=%d new_val=%d",old_val,new_val) ;
5397 STATUS(str) ; }
5398
5399 if( new_val != old_val ){
5400 im3d->vinfo->force_anat_wod = (new_val != DMODE_BRICK_BVAL) ;
5401 SHOW_AFNI_PAUSE ;
5402 im3d->vinfo->tempflag = 1 ; /* 15 Mar 2000 */
5403 AFNI_modify_viewing( im3d , True ) ; /* redisplay */
5404 SHOW_AFNI_READY ;
5405 }
5406
5407 RESET_AFNI_QUIT(im3d) ;
5408 EXRETURN ;
5409 }
5410
5411 /*---------------------------------------------------------------
5412 callback for the funcmode bbox
5413 -----------------------------------------------------------------*/
5414
AFNI_funcmode_CB(Widget w,XtPointer cd,XtPointer cb)5415 void AFNI_funcmode_CB( Widget w, XtPointer cd, XtPointer cb )
5416 {
5417 Three_D_View *im3d = (Three_D_View *) cd ;
5418 int old_val , new_val ;
5419 THD_fvec3 fv ;
5420 THD_ivec3 iv ;
5421
5422 ENTRY("AFNI_funcmode_CB") ;
5423
5424 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
5425
5426 im3d->vinfo->stats_anat_ok =
5427 im3d->vinfo->stats_func_ok =
5428 im3d->vinfo->arang_func_ok =
5429 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
5430
5431 old_val = 1 << im3d->vinfo->force_func_wod ;
5432 new_val = MCW_val_bbox( im3d->vwid->dmode->funcmode_bbox ) ;
5433
5434 if(PRINT_TRACING){
5435 char str[256] ; sprintf(str,"old_val=%d new_val=%d",old_val,new_val) ;
5436 STATUS(str) ; }
5437
5438 if( new_val != old_val ){
5439 im3d->vinfo->force_func_wod = (new_val != DMODE_BRICK_BVAL) ;
5440 SHOW_AFNI_PAUSE ;
5441 im3d->vinfo->tempflag = 1 ; /* 15 Mar 2000 */
5442 AFNI_modify_viewing( im3d , True ) ; /* redisplay */
5443 SHOW_AFNI_READY ;
5444 }
5445
5446 RESET_AFNI_QUIT(im3d) ;
5447 EXRETURN ;
5448 }
5449
5450 /*----------------------------------------------------------------
5451 Used to force redisplay when some datamode parameters have
5452 been altered
5453 ------------------------------------------------------------------*/
5454
AFNI_modify_viewing(Three_D_View * im3d,RwcBoolean rescaled)5455 void AFNI_modify_viewing( Three_D_View *im3d , RwcBoolean rescaled )
5456 {
5457 THD_fvec3 fv ;
5458 THD_ivec3 iv ;
5459
5460 ENTRY("AFNI_modify_viewing") ;
5461
5462 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
5463
5464 im3d->vinfo->stats_anat_ok =
5465 im3d->vinfo->stats_func_ok =
5466 im3d->vinfo->arang_func_ok =
5467 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
5468
5469 /* set up datasets for new imaging */
5470
5471 AFNI_setup_viewing( im3d , rescaled ) ;
5472
5473 /* transform current POV to new indices */
5474
5475 if( im3d->type == AFNI_3DDATA_VIEW ){ /* 19 Oct 1999 */
5476
5477 LOAD_ANAT_VIEW(im3d) ; /* 02 Nov 1996 */
5478 fv = THD_dicomm_to_3dmm(
5479 im3d->anat_now ,
5480 TEMP_FVEC3(im3d->vinfo->xi, im3d->vinfo->yj, im3d->vinfo->zk) ) ;
5481 iv = THD_3dmm_to_3dind( im3d->anat_now , fv ) ;
5482
5483 } else {
5484
5485 iv = TEMP_IVEC3( im3d->vinfo->i1 , im3d->vinfo->j2 , im3d->vinfo->k3 ) ;
5486 }
5487
5488 /* and redisplay the images */
5489
5490 DISABLE_LOCK ;
5491 AFNI_set_viewpoint( im3d, iv.ijk[0],iv.ijk[1],iv.ijk[2] , REDISPLAY_ALL ) ;
5492 ENABLE_LOCK ;
5493
5494 SAVE_VPT(im3d) ;
5495 FIX_SCALE_SIZE(im3d) ;
5496 EXRETURN ;
5497 }
5498
5499 /*--------------------------------------------------------------------
5500 23 Nov 1996: Setup to write out many datasets
5501 ----------------------------------------------------------------------*/
5502
AFNI_write_many_dataset_CB(Widget w,XtPointer cd,XtPointer cb)5503 void AFNI_write_many_dataset_CB( Widget w, XtPointer cd, XtPointer cb )
5504 {
5505 Three_D_View *im3d = (Three_D_View *) cd ;
5506 static MCW_idcode * idclist = NULL ;
5507 static char **strlist = NULL ;
5508 static int num_dset = -1 ;
5509
5510 int iss , id , vv , llen , ltop ;
5511 THD_session *ss ;
5512 THD_3dim_dataset *dset ;
5513 char nam[THD_MAX_NAME+16] , *tnam , qnam[THD_MAX_NAME+16] ;
5514
5515 ENTRY("AFNI_write_many_dataset_CB") ;
5516
5517 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
5518 if( GLOBAL_library.have_dummy_dataset ){ EXRETURN ; }
5519
5520 if( num_dset > 0 && strlist != NULL )
5521 for( id=0 ; id < num_dset ; id++ ) myXtFree(strlist[id]) ;
5522 myXtFree(idclist) ; myXtFree(strlist) ;
5523
5524 vv = im3d->vinfo->view_type ; /* select view type */
5525
5526 /** scan once to find longest string name **/
5527
5528 ltop = 4 ;
5529 for( iss=0 ; iss < GLOBAL_library.sslist->num_sess ; iss++ ){
5530 ss = GLOBAL_library.sslist->ssar[iss] ;
5531 if( ss->is_collection ) continue ;
5532
5533 for( id=0 ; id < ss->num_dsset ; id++ ){
5534 dset = GET_SESSION_DSET(ss, id, vv);
5535 /* dset = ss->dsset_xform_table[id][vv] ;*/
5536 if( DSET_WRITEABLE(dset) ){
5537 strcpy( nam , dset->dblk->diskptr->directory_name ) ;
5538 strcat( nam , dset->dblk->diskptr->filecode ) ;
5539 tnam = THD_trailname(nam,SESSTRAIL+1) ;
5540 llen = strlen(tnam) ; ltop = MAX(ltop,llen) ;
5541 }
5542 }
5543 }
5544 ltop = MIN(ltop,THD_MAX_NAME) ; /* 06 Aug 2002 */
5545
5546 num_dset = 0 ;
5547 for( iss=0 ; iss < GLOBAL_library.sslist->num_sess ; iss++ ){
5548 ss = GLOBAL_library.sslist->ssar[iss] ;
5549 if( ss->is_collection ) continue ;
5550
5551 /* check anat datasets */
5552
5553 for( id=0 ; id < ss->num_dsset ; id++ ){
5554 dset = GET_SESSION_DSET(ss, id, vv);
5555 /* dset = ss->dsset_xform_table[id][vv] ;*/
5556 if( DSET_WRITEABLE(dset) ){
5557 num_dset++ ;
5558 idclist = (MCW_idcode *) XtRealloc( (char *) idclist ,
5559 sizeof(MCW_idcode) * num_dset ) ;
5560 strlist = (char **) XtRealloc( (char *) strlist ,
5561 sizeof(char *) * num_dset ) ;
5562
5563 strcpy( nam , dset->dblk->diskptr->directory_name ) ;
5564 strcat( nam , dset->dblk->diskptr->filecode ) ;
5565 tnam = THD_trailname(nam,SESSTRAIL+1) ;
5566
5567 if( ISANAT(dset) ){
5568 if( ISANATBUCKET(dset) ) /* 30 Nov 1997 */
5569 sprintf(qnam,"%-*s [%s:%d]" ,
5570 ltop,tnam , ANAT_prefixstr[dset->func_type] , DSET_NVALS(dset) ) ;
5571
5572 else if( DSET_NUM_TIMES(dset) == 1 )
5573 sprintf(qnam,"%-*s [%s]" ,
5574 ltop,tnam ,ANAT_prefixstr[dset->func_type] ) ;
5575
5576 else
5577 sprintf(qnam,"%-*s [%s:3D+t]" ,
5578 ltop,tnam , ANAT_prefixstr[dset->func_type] ) ;
5579
5580 } else if( ISFUNC(dset) ){
5581 if( ISFUNCBUCKET(dset) ) /* 30 Nov 1997 */
5582 sprintf(qnam,"%-*s [%s:%d]" ,
5583 ltop,tnam , FUNC_prefixstr[dset->func_type] , DSET_NVALS(dset) ) ;
5584
5585 else if( DSET_NUM_TIMES(dset) == 1 )
5586 sprintf(qnam,"%-*s [%s]" ,
5587 ltop,tnam , FUNC_prefixstr[dset->func_type] ) ;
5588
5589 else
5590 sprintf(qnam,"%-*s [%s:3D+t]" ,
5591 ltop,tnam , FUNC_prefixstr[dset->func_type] ) ;
5592 }
5593
5594 strlist[num_dset-1] = XtNewString(qnam) ;
5595 idclist[num_dset-1] = dset->idcode ;
5596 }
5597 } /* end of loop over datasets */
5598
5599 } /* end of loop over sessions */
5600
5601 if( num_dset <= 0 ){
5602 (void) MCW_popup_message( w ,
5603 "*******************************\n"
5604 "** No datasets are available **\n"
5605 "** to write out to disk. **\n"
5606 "*******************************" ,
5607 MCW_USER_KILL | MCW_TIMER_KILL ) ;
5608 BEEPIT ; EXRETURN ;
5609 }
5610
5611 #if 1
5612 MCW_choose_multi_strlist( w , "Datasets to Write" , mcwCT_multi_mode ,
5613 num_dset , NULL , strlist ,
5614 AFNI_do_many_writes , (XtPointer) idclist ) ;
5615 #else
5616 { THD_string_array *sar ; /*** This code is for experiments only! ***/
5617 INIT_SARR(sar) ;
5618 for( id=0 ; id < num_dset ; id++ ) ADDTO_SARR(sar,strlist[id]) ;
5619
5620 MCW_choose_multi_editable_strlist( w , "Datasets to Write" , mcwCT_multi_mode ,
5621 sar , NULL ,
5622 AFNI_do_many_writes , (XtPointer) idclist ) ;
5623 }
5624 #endif
5625
5626 XtVaSetValues( w , XmNuserData , (XtPointer) im3d , NULL ) ;
5627
5628 EXRETURN ;
5629 }
5630
5631 /*--------------------------------------------------------------------*/
5632
AFNI_do_many_writes(Widget wpar,XtPointer cd,MCW_choose_cbs * cbs)5633 void AFNI_do_many_writes( Widget wpar , XtPointer cd , MCW_choose_cbs *cbs )
5634 {
5635 MCW_idcode *idclist = (MCW_idcode *) cd ;
5636 Three_D_View *im3d = NULL , *qq3d ;
5637 THD_3dim_dataset *dset ;
5638 THD_dataxes new_daxes ;
5639 int ib , resam_mode ;
5640 RwcBoolean good ;
5641 Widget wmsg ;
5642 int cc , ccanat[MAX_CONTROLLERS] , ccfunc[MAX_CONTROLLERS] ;
5643
5644 ENTRY("AFNI_do_many_writes") ;
5645
5646 XtVaGetValues( wpar , XmNuserData , &im3d , NULL ) ;
5647 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
5648
5649 SHOW_AFNI_PAUSE ;
5650
5651 /** mark all controllers as untouched **/
5652
5653 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ) ccanat[cc] = ccfunc[cc] = 0 ;
5654
5655 wmsg = MCW_popup_message( wpar ,
5656 "*******************************\n"
5657 "** Please wait for dataset **\n"
5658 "** computations and disk I/O **\n"
5659 "*******************************" , MCW_CALLER_KILL ) ;
5660 AFNI_speak("Writing",0) ;
5661
5662 /** loop through selected datasets and do the dirty work **/
5663
5664 for( ib=0 ; ib < cbs->nilist ; ib++ ){
5665 dset = PLUTO_find_dset( idclist + cbs->ilist[ib] ) ;
5666 if( DSET_WRITEABLE(dset) ){
5667
5668 fprintf(stderr,"-- writing dataset %s%s (%d of %d)\n" ,
5669 dset->dblk->diskptr->directory_name ,
5670 dset->dblk->diskptr->filecode ,
5671 ib+1 , cbs->nilist ) ;
5672
5673 new_daxes.type = DATAXES_TYPE ;
5674
5675 #ifdef USE_WRITEOWNSIZE
5676 if( im3d->vinfo->writeownsize )
5677 THD_edit_dataxes( im3d->vinfo->resam_vox , dset->daxes , &new_daxes ) ;
5678 else
5679 #endif
5680 THD_edit_dataxes( im3d->vinfo->resam_vox ,
5681 CURRENT_DAXES(im3d->anat_now) , &new_daxes ) ;
5682
5683 resam_mode = (ISFUNC(dset)) ? im3d->vinfo->func_resam_mode
5684 : im3d->vinfo->anat_resam_mode ;
5685
5686 good = AFNI_refashion_dataset( im3d , dset , &new_daxes , resam_mode ) ;
5687
5688 /** if the output failed, put a message to the screen **/
5689
5690 if( ! good ){ /* bad news! */
5691 char str[THD_MAX_NAME+128] ;
5692 sprintf( str , "**\n" "** Attempt to write dataset\n"
5693 "** %s%s\n" "** failed for unknown reasons!\n**" ,
5694 dset->dblk->diskptr->directory_name ,
5695 dset->dblk->diskptr->filecode ) ;
5696 (void) MCW_popup_message( wpar , str , MCW_USER_KILL | MCW_TIMER_KILL ) ;
5697
5698 fprintf(stderr," [output of %s%s failed!]\n",
5699 dset->dblk->diskptr->directory_name ,
5700 dset->dblk->diskptr->filecode ) ;
5701
5702 /** otherwise, check if the dataset just done is
5703 the active anatomy or function in any open controller window **/
5704
5705 } else {
5706 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
5707 qq3d = GLOBAL_library.controllers[cc] ;
5708 if( ! IM3D_OPEN(qq3d) ) continue ;
5709 if( dset == qq3d->anat_now ) ccanat[cc] = 1 ; /* flag their */
5710 if( dset == qq3d->fim_now ) ccfunc[cc] = 1 ; /* controllers */
5711 }
5712 }
5713 }
5714 }
5715
5716 /** for any controllers whose active datasets were written out,
5717 we need to set the "See Brick" buttons to be sensitive. **/
5718
5719 for( cc=0 ; cc < MAX_CONTROLLERS ; cc++ ){
5720 qq3d = GLOBAL_library.controllers[cc] ;
5721 if( ! IM3D_OPEN(qq3d) ) continue ;
5722
5723 if( ccfunc[cc] ){
5724 STATUS("resetting 'use func brick' button") ;
5725 XtSetSensitive( qq3d->vwid->dmode->funcmode_bbox->wbut[DMODE_BRICK] , True ) ;
5726 AFNI_reset_func_range( qq3d ) ;
5727 AFNI_set_viewpoint( qq3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
5728 }
5729
5730 if( ccanat[cc] ){
5731 STATUS("resetting 'use anat brick' button") ;
5732 XtSetSensitive( qq3d->vwid->dmode->anatmode_bbox->wbut[DMODE_BRICK] , True ) ;
5733 }
5734 }
5735
5736 XtDestroyWidget( wmsg ) ;
5737 SHOW_AFNI_READY ;
5738 EXRETURN ;
5739 }
5740
5741 /*--------------------------------------------------------------------------*/
5742
5743 static THD_3dim_dataset *saveas_iset = NULL ;
5744
AFNI_saveas_dataset_CB(Widget w,XtPointer cd,XtPointer cb)5745 void AFNI_saveas_dataset_CB( Widget w, XtPointer cd, XtPointer cb )
5746 {
5747 Three_D_View *im3d = (Three_D_View *) cd ;
5748 char *label ;
5749
5750 ENTRY("AFNI_saveas_dataset_CB") ;
5751
5752 saveas_iset = NULL ;
5753
5754 if( ! IM3D_OPEN(im3d) || w == NULL ||
5755 ! XtIsWidget(w) || ! XtIsRealized(w) ) EXRETURN ;
5756 if( GLOBAL_library.have_dummy_dataset ){ EXRETURN ; }
5757
5758 if( w == im3d->vwid->dmode->saveas_anat_pb ){
5759 saveas_iset = im3d->anat_now ; label = "Underlay Prefix" ;
5760 } else if( w == im3d->vwid->dmode->saveas_func_pb ){
5761 saveas_iset = im3d->fim_now ; label = "Overlay Prefix" ;
5762 } else {
5763 BEEPIT ; WARNING_message("SaveAs code improperly executed") ; EXRETURN ;
5764 }
5765
5766 MCW_choose_string( w, label, NULL, AFNI_saveas_finalize_CB, NULL ) ;
5767
5768 EXRETURN ;
5769 }
5770
5771 /*--------------------------------------------------------------------------*/
5772
AFNI_saveas_finalize_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)5773 void AFNI_saveas_finalize_CB( Widget w , XtPointer cd , MCW_choose_cbs *cbs )
5774 {
5775 char *prefix ;
5776 THD_3dim_dataset *oset ;
5777
5778 ENTRY("AFNI_saveas_finalize_CB") ;
5779
5780 if( cbs->reason != mcwCR_string || saveas_iset == NULL ){
5781 BEEPIT; WARNING_message("SaveAs code improperly invoked"); EXRETURN;
5782 }
5783
5784 prefix = cbs->cval ;
5785 if( !THD_filename_ok(prefix) ){
5786 BEEPIT; WARNING_message("SaveAs code improperly invoked"); EXRETURN;
5787 }
5788
5789 DSET_load(saveas_iset) ;
5790 if( !DSET_LOADED(saveas_iset) ){
5791 BEEPIT; WARNING_message("SaveAs code improperly invoked"); EXRETURN;
5792 }
5793
5794 MCW_invert_widget(w) ;
5795 oset = EDIT_full_copy( saveas_iset , prefix ) ;
5796 MCW_flash_widget(1,w) ;
5797 THD_force_ok_overwrite(1) ;
5798 DSET_write(oset) ;
5799 MCW_flash_widget(1,w) ;
5800 THD_force_ok_overwrite(0) ;
5801 WROTE_DSET(oset) ; DSET_delete(oset) ;
5802
5803 saveas_iset = NULL ; POPDOWN_string_chooser ; MCW_invert_widget(w) ;
5804 EXRETURN ;
5805 }
5806
5807 /*---------------------------------------------------------------------------*/
5808
AFNI_writeout_dataset(THD_3dim_dataset * dset,char * prefix)5809 void AFNI_writeout_dataset( THD_3dim_dataset *dset , char *prefix )
5810 {
5811 THD_3dim_dataset *oset ;
5812
5813 ENTRY("AFNI_writeout_dataset") ;
5814
5815 if( !ISVALID_DSET(dset) || !THD_filename_ok(prefix) ) EXRETURN ;
5816 DSET_load(dset) ; if( !DSET_LOADED(dset) ) EXRETURN ;
5817
5818 oset = EDIT_full_copy( dset , prefix ) ;
5819 THD_force_ok_overwrite(1) ;
5820 DSET_write(oset) ;
5821 THD_force_ok_overwrite(0) ;
5822 WROTE_DSET(oset) ; DSET_delete(oset) ;
5823
5824 EXRETURN ;
5825 }
5826
5827 /*-----------------------------------------------------------------
5828 Obey the command to write out the current dataset
5829 -------------------------------------------------------------------*/
5830
AFNI_write_dataset_CB(Widget w,XtPointer cd,XtPointer cb)5831 void AFNI_write_dataset_CB( Widget w, XtPointer cd, XtPointer cb )
5832 {
5833 Three_D_View *im3d = (Three_D_View *) cd ;
5834 THD_3dim_dataset *dset = NULL ;
5835 THD_dataxes new_daxes ;
5836 Widget wmsg ;
5837 int resam_mode = 0;
5838 RwcBoolean good , destroy ;
5839
5840 ENTRY("AFNI_write_dataset_CB") ;
5841
5842 if( ! IM3D_VALID(im3d) || w == NULL ||
5843 ! XtIsWidget(w) || ! XtIsRealized(w) ) EXRETURN ;
5844 if( GLOBAL_library.have_dummy_dataset ){ EXRETURN ; }
5845
5846 if( w == im3d->vwid->dmode->write_anat_pb ){ /* write anatomy */
5847 dset = im3d->anat_now ;
5848 resam_mode = im3d->vinfo->anat_resam_mode ;
5849
5850 } else if( w == im3d->vwid->dmode->write_func_pb ){ /* write function */
5851 dset = im3d->fim_now ;
5852 resam_mode = im3d->vinfo->func_resam_mode ;
5853 }
5854
5855 if( ISVALID_DSET(dset) && dset->dblk->diskptr->allow_directwrite == 1 ){
5856 INFO_message("Direct write of dataset '%s'",DSET_BRIKNAME(dset)) ;
5857 if (!AFNI_yesenv("AFNI_GUI_WRITE_AS_DECONFLICT")) { /* ZSS April 11 2010 */
5858 DSET_overwrite(dset) ;
5859 } else {
5860 char pfx[THD_MAX_PREFIX] ; /* to hold old one */
5861 MCW_strncpy( pfx , DSET_PREFIX(dset) , THD_MAX_PREFIX ) ;
5862 DSET_write(dset);
5863 /* Now put old prefix back in case there was deconflicting */
5864 EDIT_dset_items( dset , ADN_prefix , pfx , ADN_none ) ;
5865 }
5866
5867 EXRETURN ;
5868 }
5869
5870 good = ISVALID_3DIM_DATASET(dset) && /* check for bad data */
5871 resam_mode >= FIRST_RESAM_TYPE &&
5872 resam_mode <= LAST_RESAM_TYPE &&
5873 im3d->vinfo->resam_vox > 0.0 &&
5874 !DSET_IS_MINC(dset) && /* 29 Oct 2001 */
5875 !DSET_IS_ANALYZE(dset) && /* 27 Aug 2002 */
5876 !DSET_IS_CTFSAM(dset) &&
5877 !DSET_IS_CTFMRI(dset) &&
5878 !DSET_IS_1D(dset) &&
5879 !DSET_IS_NIFTI(dset) /* 28 Aug 2003 */
5880 ;
5881
5882 destroy = !DSET_WRITEABLE(dset) ; /* check for destruction */
5883
5884 if( good && destroy ){
5885 if( GLOBAL_argopt.destruct ){
5886 (void) MCW_popup_message( w ,
5887 "******************************\n"
5888 "** Potentially destructive **\n"
5889 "** dataset write initiated! **\n"
5890 "******************************" ,
5891 MCW_USER_KILL | MCW_TIMER_KILL ) ;
5892 } else {
5893 good = False ; /* destruction not OK */
5894 }
5895 }
5896
5897 if( !good ){
5898
5899 (void) MCW_popup_message( w ,
5900 "****************************************************\n"
5901 "** Cannot write dataset for one of these reasons: **\n"
5902 "** -- It isn't allowed to write data in the **\n"
5903 "** Original View. **\n"
5904 "** -- It isn't allowed to overwrite data that **\n"
5905 "** is not warped from some other dataset. **\n"
5906 "** -- An internal program error has occured! **\n"
5907 "****************************************************" ,
5908 MCW_USER_KILL | MCW_TIMER_KILL ) ;
5909
5910 BEEPIT ; EXRETURN;
5911 }
5912
5913 SHOW_AFNI_PAUSE ;
5914
5915 wmsg = MCW_popup_message( w ,
5916 "*******************************\n"
5917 "** Please wait for dataset **\n"
5918 "** computations and disk I/O **\n"
5919 "*******************************" , MCW_CALLER_KILL ) ;
5920
5921 XtSetSensitive( im3d->vwid->top_shell , False ) ;
5922 XmUpdateDisplay( im3d->vwid->top_shell ) ;
5923
5924 LOAD_DSET_VIEWS(im3d) ; /* 02 Nov 1996 */
5925
5926 new_daxes.type = DATAXES_TYPE ;
5927
5928 #ifdef USE_WRITEOWNSIZE
5929 if( im3d->vinfo->writeownsize )
5930 THD_edit_dataxes( im3d->vinfo->resam_vox , dset->daxes , &new_daxes ) ;
5931 else
5932 #endif
5933 new_daxes = *CURRENT_DAXES(im3d->anat_now) ;
5934
5935 good = AFNI_refashion_dataset( im3d , dset , &new_daxes , resam_mode ) ;
5936
5937 if(PRINT_TRACING){
5938 if( good ){
5939 STATUS("successful refashioning") ;
5940 } else {
5941 STATUS("failed refashioning") ;
5942 }}
5943
5944 if( good && ISFUNC(dset) ){
5945 AFNI_reset_func_range( im3d ) ;
5946 AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ; /* redraw */
5947 }
5948
5949 XtSetSensitive( im3d->vwid->top_shell , True ) ;
5950
5951 XtDestroyWidget( wmsg ) ;
5952 SHOW_AFNI_READY ;
5953
5954 /* allow the "use data brick" button, if we just wrote the anat out */
5955
5956 if( good && w == im3d->vwid->dmode->write_anat_pb ){
5957 STATUS("resetting 'use anat brick' button") ;
5958 XtSetSensitive( im3d->vwid->dmode->anatmode_bbox->wbut[DMODE_BRICK] , True ) ;
5959 }
5960
5961 if( good && w == im3d->vwid->dmode->write_func_pb ){
5962 STATUS("resetting 'use func brick' button") ;
5963 XtSetSensitive( im3d->vwid->dmode->funcmode_bbox->wbut[DMODE_BRICK] , True ) ;
5964 }
5965
5966 if( ! good ){ /* bad news! */
5967
5968 BEEPIT ;
5969 (void) MCW_popup_message( w ,
5970 "***************************************\n"
5971 "** Attempt to write dataset failed **\n"
5972 "** for unknown reasons! Check files! **\n"
5973 "***************************************" ,
5974 MCW_USER_KILL ) ;
5975
5976 dset->wod_flag = True ;
5977 }
5978
5979 EXRETURN ;
5980 }
5981
5982 /*------------------------------------------------------------------
5983 (re)compute and (re)write a dataset to disk, with the indicated
5984 geometric parameters. Note that the filenames for the save should
5985 already be initialized in the dset->dblk->diskptr. Also, note
5986 that the dataset's "permanent" dataxes will be remade to fit the
5987 new geometry.
5988 --------------------------------------------------------------------*/
5989
5990 #define PICTURIZE(px) \
5991 ( XtVaSetValues( im3d->vwid->picture, XmNlabelInsensitivePixmap,px, NULL ) , \
5992 MCW_expose_widget( im3d->vwid->picture ) )
5993
5994 #define UNPICTURIZE PICTURIZE(XmUNSPECIFIED_PIXMAP)
5995
5996 /** 09 Dec 1997: resam_mode is now ignored **/
5997
AFNI_refashion_dataset(Three_D_View * im3d,THD_3dim_dataset * dset,THD_dataxes * daxes,int resam_mode)5998 RwcBoolean AFNI_refashion_dataset( Three_D_View *im3d ,
5999 THD_3dim_dataset *dset ,
6000 THD_dataxes *daxes , int resam_mode )
6001 {
6002 THD_datablock *dblk = dset->dblk ;
6003 THD_diskptr *dkptr = dset->dblk->diskptr ;
6004 RwcBoolean good ;
6005 int npix , nx,ny,nz,nv , kk , ival , code , nzv , dsiz , isfunc , cmode ;
6006 MRI_IMAGE *im ;
6007 void *imar ;
6008 FILE *far ;
6009 float brfac_save ;
6010 int native_order , save_order ; /* 23 Nov 1999 */
6011
6012 RwcBoolean picturize ;
6013 Pixmap brain_pixmap=XmUNSPECIFIED_PIXMAP ;
6014
6015 #ifndef DONT_USE_METER
6016 Widget meter = NULL ;
6017 int meter_perc , meter_pold ;
6018 #endif
6019
6020 ENTRY("AFNI_refashion_dataset") ;
6021
6022 picturize = IM3D_OPEN(im3d) && im3d->vwid->picture != NULL &&
6023 afni48_pixmap != XmUNSPECIFIED_PIXMAP ;
6024
6025 if( picturize ){
6026 switch( ORIENT_xyz[daxes->zzorient] ){
6027 case 'x': brain_pixmap = afni48sag_pixmap ; break ;
6028 case 'y': brain_pixmap = afni48cor_pixmap ; break ;
6029 case 'z': brain_pixmap = afni48axi_pixmap ; break ;
6030 }
6031 }
6032
6033 #ifndef DONT_USE_METER
6034 meter = MCW_popup_meter( im3d->vwid->top_shell , METER_TOP_WIDE ) ;
6035 meter_pold = 0 ;
6036 #endif
6037
6038 /* set up for warp-on-demand */
6039
6040 dset->wod_daxes = myXtNew(THD_dataxes) ; /* 02 Nov 1996 */
6041 dset->wod_daxes->type = DATAXES_TYPE ; /* 02 Nov 1996 */
6042 dset->vox_warp = myXtNew(THD_warp) ; /* 02 Nov 1996 */
6043 dset->self_warp = NULL ; /* 26 Aug 2002 */
6044
6045 *(dset->wod_daxes) = *daxes ; /* copy insides of daxes */
6046 dset->wod_flag = True ; /* mark for warp-on-demand */
6047 dset->vox_warp->type = ILLEGAL_TYPE ; /* mark for recomputation */
6048
6049 /* copy the new geometric information into various places */
6050
6051 *(dset->daxes) = *(daxes) ; /* Make daxes permanent */
6052 dkptr->dimsizes[0] = dset->daxes->nxx ; /* Will cause trouble */
6053 dkptr->dimsizes[1] = dset->daxes->nyy ; /* if diskptr and */
6054 dkptr->dimsizes[2] = dset->daxes->nzz ; /* daxes don't match! */
6055
6056 /* write the header out */
6057
6058 THD_force_ok_overwrite(1);
6059 good = THD_write_3dim_dataset( NULL,NULL , dset , False ) ;
6060 THD_force_ok_overwrite(0);
6061 if( !good ){
6062 fprintf(stderr,"\a\n*** cannot write dataset header ***\n") ;
6063 if( picturize ) UNPICTURIZE ;
6064 RETURN(False) ;
6065 }
6066 STATUS("wrote output header file") ;
6067
6068 /* purge the datablock that now exists,
6069 then delete the file on disk that now exists (if any) */
6070
6071 DSET_unlock( dset ) ; /* Feb 1998 */
6072 PURGE_DSET( dset ) ;
6073 COMPRESS_unlink(dkptr->brick_name) ;
6074
6075 /* refashion its brick data structure,
6076 which requires first saving in a temporary
6077 array the datum type for each sub-brick */
6078
6079 { int ibr ; int *typ ;
6080 typ = (int *) XtMalloc( sizeof(int) * dblk->nvals ) ;
6081 for( ibr=0 ; ibr < dblk->nvals ; ibr++ )
6082 typ[ibr] = DBLK_BRICK_TYPE(dblk,ibr) ;
6083 THD_init_datablock_brick( dblk , dblk->nvals , typ ) ;
6084 myXtFree( typ ) ;
6085 }
6086
6087 /*-- 13 Mar 2006: check for free disk space --*/
6088
6089 { int mm = THD_freemegabytes(dkptr->header_name) ;
6090 int rr = (int)(dblk->total_bytes/(1024*1024)) ;
6091 if( rr >= 666 )
6092 fprintf(stderr,"++ WARNING: output filesize %s will be %d Mbytes!\n"
6093 "++ SUGGEST: increase voxel size to save disk space.\n",
6094 dkptr->brick_name , rr ) ;
6095 if( mm >= 0 && mm <= rr )
6096 WARNING_message("Disk space: writing file %s (%d MB),"
6097 " but only %d free MB on disk" ,
6098 dkptr->brick_name , rr , mm ) ;
6099 }
6100
6101 dkptr->storage_mode = STORAGE_UNDEFINED ; /* just for now */
6102 dblk->malloc_type = DATABLOCK_MEM_UNDEFINED ;
6103
6104 /*--- open the output file
6105 (N.B.: much of the following code is from THD_write_datablock) ---*/
6106
6107 /*-- create directory if necessary --*/
6108
6109 if( ! THD_is_directory(dkptr->directory_name) ){
6110 kk = mkdir( dkptr->directory_name , THD_MKDIR_MODE ) ;
6111 if( kk != 0 ){
6112 fprintf(stderr,
6113 "\a\n*** cannot mkdir new directory: %s\n",dkptr->directory_name) ;
6114 if( picturize ) UNPICTURIZE ;
6115 RETURN(False) ;
6116 }
6117 STATUS("created subdirectory") ;
6118 }
6119
6120 /*-- open output file --*/
6121
6122 cmode = THD_get_write_compression() ;
6123 far = COMPRESS_fopen_write( dkptr->brick_name , cmode ) ;
6124 if( far == NULL ){
6125 fprintf(stderr,
6126 "\a\n*** cannot open output file %s\n",dkptr->brick_name) ;
6127 if( picturize ) UNPICTURIZE ;
6128 RETURN(False) ;
6129 }
6130 STATUS("created output brick file") ;
6131
6132 /*--------- now, create each slice and write it out ----------*/
6133
6134 nx = dset->daxes->nxx ;
6135 ny = dset->daxes->nyy ; npix = nx*ny ;
6136 nz = dset->daxes->nzz ;
6137 nv = dkptr->nvals ; nzv = nz*nv ;
6138
6139 isfunc = ISFUNC(dset) ; /* 09 Dec 1997 */
6140 if( ! isfunc )
6141 resam_mode = im3d->vinfo->anat_resam_mode ;
6142
6143 native_order = mri_short_order() ; /* 23 Nov 1999 */
6144 save_order = (dkptr->byte_order > 0) ? dkptr->byte_order
6145 : THD_get_write_order() ;
6146
6147 for( ival=0 ; ival < nv ; ival++ ){ /* for each sub-brick */
6148
6149 dsiz = mri_datum_size( DSET_BRICK_TYPE(dset,ival) ) ;
6150
6151 /** force return of unscaled slices for output **/
6152
6153 brfac_save = DBLK_BRICK_FACTOR(dblk,ival) ;
6154 DBLK_BRICK_FACTOR(dblk,ival) = 0.0 ;
6155
6156 if( isfunc )
6157 resam_mode = (DSET_BRICK_STATCODE(dset,ival) > 0) /* 09 Dec 1997 */
6158 ? im3d->vinfo->thr_resam_mode
6159 : im3d->vinfo->func_resam_mode ;
6160
6161 for( kk=0 ; kk < nz ; kk++ ){ /* for each slice */
6162
6163 im = AFNI_dataset_slice( dset , 3 , kk , ival , resam_mode ) ;
6164 STATUS("have new image") ;
6165
6166 if( im == NULL ){
6167 fprintf(stderr,"\a\n*** failure to compute dataset slice %d\n",kk) ;
6168 COMPRESS_fclose(far) ;
6169 COMPRESS_unlink( dkptr->brick_name ) ;
6170 if( picturize ) UNPICTURIZE ;
6171 #ifndef DONT_USE_METER
6172 MCW_popdown_meter(meter) ;
6173 #endif
6174 RETURN(False) ;
6175 }
6176
6177 #ifdef AFNI_DEBUG
6178 { char str[256] ;
6179 sprintf(str,"writing slice %d: type=%s nx=%d ny=%d\n",
6180 kk,MRI_TYPE_NAME(im) , im->nx,im->ny ) ;
6181 STATUS(str) ; }
6182 #endif
6183
6184 imar = mri_data_pointer(im) ;
6185 if( save_order != native_order ){ /* 23 Nov 1999 */
6186 switch( im->kind ){
6187 default: break ;
6188 case MRI_short: mri_swap2( npix,imar) ; break ;
6189 case MRI_float:
6190 case MRI_int: mri_swap4( npix,imar) ; break ;
6191 case MRI_complex: mri_swap4(2*npix,imar) ; break ;
6192 }
6193 }
6194 code = fwrite( imar , dsiz , npix , far ) ;
6195 mri_free(im) ;
6196
6197 if( code != npix ){
6198 fprintf(stderr,
6199 "\a\n*** failure to write dataset slice %d (is disk full?)\n",kk) ;
6200 COMPRESS_fclose(far) ;
6201 COMPRESS_unlink( dkptr->brick_name ) ;
6202 if( picturize ) UNPICTURIZE ;
6203 #ifndef DONT_USE_METER
6204 MCW_popdown_meter(meter) ;
6205 #endif
6206 RETURN(False) ;
6207 }
6208
6209 if( picturize && kk%7 == 0 ){
6210 Pixmap pp ;
6211 pp = (kk%2 == 0) ? brain_pixmap : afni48_pixmap ;
6212 PICTURIZE(pp) ;
6213 XmUpdateDisplay( im3d->vwid->picture ) ;
6214 }
6215
6216 #ifndef DONT_USE_METER
6217 meter_perc = (int) ( 100.0 * (kk+ival*nz) / nzv ) ;
6218 if( meter_perc != meter_pold ){
6219 MCW_set_meter( meter , meter_perc ) ;
6220 meter_pold = meter_perc ;
6221 }
6222 #endif
6223
6224 } /* end of loop over kk (z-direction) */
6225
6226 /* restore the correct scaling of this sub-brick */
6227
6228 DBLK_BRICK_FACTOR(dblk,ival) = brfac_save ;
6229
6230 } /* end of loop over iv (nvals direction) */
6231 STATUS("all slices written") ;
6232
6233 /*--------------------- done!!! ---------------------*/
6234
6235 COMPRESS_fclose(far) ;
6236 STATUS("output file closed") ;
6237
6238 if( picturize ) PICTURIZE(logo_pixmap) ;
6239 #ifndef DONT_USE_METER
6240 MCW_set_meter( meter , 100 ) ;
6241 #endif
6242
6243 /*--- do a little surgery on the dataset's storage flags ---*/
6244
6245 dkptr->storage_mode = STORAGE_BY_BRICK ;
6246 #if MMAP_THRESHOLD > 0
6247 dblk->malloc_type = (dblk->total_bytes > MMAP_THRESHOLD)
6248 ? DATABLOCK_MEM_MMAP : DATABLOCK_MEM_MALLOC ;
6249
6250 if( cmode >= 0 ) dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
6251 DBLK_mmapfix(dblk) ; /* 28 Mar 2005 */
6252 #else
6253 dblk->malloc_type = DATABLOCK_MEM_MALLOC ;
6254 #endif
6255
6256 /*--- recompute the statistics and rewrite the header to hold them ---*/
6257
6258 STATUS("recomputing statistics") ;
6259
6260 THD_load_statistics( dset ) ;
6261
6262 STATUS("rewriting header") ;
6263
6264 tross_Append_History( dset , "AFNI: resampled and rewritten" ) ;
6265 DSET_overwrite(dset) ;
6266
6267 STATUS("purging datablock") ;
6268
6269 PURGE_DSET( dset ) ;
6270
6271 if( picturize ) UNPICTURIZE ;
6272 #ifndef DONT_USE_METER
6273 MCW_popdown_meter(meter) ;
6274 #endif
6275
6276 myXtFree(dset->wod_daxes) ; myXtFree(dset->vox_warp) ; /* 02 Nov 1996 */
6277
6278 RETURN(True) ;
6279 }
6280
6281 /*------------------------------------------------------------------
6282 This routine is part of the inverse of AFNI_make_descendants:
6283 it will mark for death the descendants of datasets that are about
6284 to be destroyed themselves (as noted by their "death_marks").
6285
6286 Note that this routine is not set up for recursive massacres:
6287 that is, it doesn't try to find grandchildren that should also
6288 be killed. That could be done by calling this routine more
6289 than once, until no changes occur.
6290
6291 Note also that this routine does not actually destroy any datasets.
6292 That is done by AFNI_andersonville.
6293
6294 31 Jan 1995: altered to avoid destruction of a dataset without
6295 a warp parent, since that dataset cannot be recreated.
6296 21 Dec 2001: modified to use DSET_MARK_FOR_DEATH(), which will
6297 not let a dataset marked for immortality be killed.
6298 --------------------------------------------------------------------*/
6299
AFNI_mark_for_death(THD_sessionlist * ssl)6300 void AFNI_mark_for_death( THD_sessionlist *ssl )
6301 {
6302 int iss , jdd , kvv , num_marked=0 ;
6303 THD_session *ss ;
6304 THD_3dim_dataset *dset ;
6305
6306 ENTRY("AFNI_mark_for_death") ;
6307
6308 if( ! ISVALID_SESSIONLIST(ssl) ) EXRETURN ;
6309
6310 /* loop over each session */
6311
6312 for( iss=0 ; iss < ssl->num_sess ; iss++ ){
6313 ss = ssl->ssar[iss] ;
6314 if( !ISVALID_SESSION(ss) ) continue ; /* no good ==> skip */
6315 if( ss->is_collection ) continue ;
6316
6317 /* loop over datasets in this session */
6318
6319 for( jdd=0 ; jdd < ss->num_dsset ; jdd++ ){
6320 for( kvv=FIRST_VIEW_TYPE ; kvv <= LAST_VIEW_TYPE ; kvv++ ){
6321 dset = GET_SESSION_DSET(ss, jdd, kvv);
6322 /* dset = ss->dsset_xform_table[jdd][kvv] ;*/
6323
6324 if( ISVALID_3DIM_DATASET(dset) && /* good dset */
6325 dset->anat_parent != NULL && /* has parent */
6326 dset->anat_parent->death_mark == DOOMED && /* parent dies */
6327 dset->warp_parent != NULL ){ /* is a warp child */
6328
6329 DSET_MARK_FOR_DEATH(dset) ;
6330 num_marked ++ ;
6331 }
6332 }
6333 }
6334 } /* end of loop over sessions */
6335
6336 #ifdef AFNI_DEBUG
6337 { char str[256] ;
6338 sprintf(str,"total # descendants marked = %d",num_marked) ;
6339 STATUS(str) ; }
6340 #endif
6341
6342 EXRETURN ;
6343 }
6344
6345 /*-------------------------------------------------------------------
6346 Mass death
6347 ---------------------------------------------------------------------*/
6348
AFNI_andersonville(THD_sessionlist * ssl,RwcBoolean kill_files)6349 void AFNI_andersonville( THD_sessionlist *ssl , RwcBoolean kill_files )
6350 {
6351 int iss , jdd , kvv , num_killed=0 ;
6352 THD_session *ss ;
6353 THD_3dim_dataset *dset ;
6354 RwcBoolean kill_me ;
6355
6356 ENTRY("AFNI_andersonville") ;
6357
6358 if( ! ISVALID_SESSIONLIST(ssl) ) EXRETURN ;
6359
6360 /* loop over each session */
6361
6362 for( iss=0 ; iss < ssl->num_sess ; iss++ ){
6363 ss = ssl->ssar[iss] ;
6364 if( !ISVALID_SESSION(ss) ) continue ; /* no good ==> skip */
6365 if( ss->is_collection ) continue ;
6366
6367 if( ss == GLOBAL_library.session ) continue ; /* 21 Dec 2001 */
6368
6369 /* loop over datasets in this session */
6370
6371 for( jdd=0 ; jdd < ss->num_dsset ; jdd++ ){
6372 for( kvv=FIRST_VIEW_TYPE ; kvv <= LAST_VIEW_TYPE ; kvv++ ){
6373 dset = GET_SESSION_DSET(ss, jdd, kvv);
6374 /* dset = ss->dsset_xform_table[jdd][kvv] ;*/
6375
6376 if( ISVALID_3DIM_DATASET(dset) && /* good dset */
6377 dset->death_mark == DOOMED ){ /* alas, poor Yorick */
6378
6379 kill_me = (kvv == VIEW_ORIGINAL_TYPE) ? False : kill_files ;
6380 THD_delete_3dim_dataset( dset , kill_me ) ;
6381 myXtFree( dset ) ;
6382 SET_SESSION_DSET(NULL, ss, jdd, kvv);
6383 /* ss->dsset_xform_table[jdd][kvv] = NULL ;*/
6384 num_killed ++ ;
6385 }
6386 }
6387 }
6388
6389 } /* end of loop over sessions */
6390
6391 #ifdef AFNI_DEBUG
6392 { char str[256] ;
6393 sprintf(str,"total # datasets killed = %d",num_killed) ;
6394 STATUS(str) ; }
6395 #endif
6396
6397 EXRETURN ;
6398 }
6399
6400 /*--------------------------------------------------------------*/
6401
AFNI_imseq_clearstat(Three_D_View * im3d)6402 void AFNI_imseq_clearstat( Three_D_View *im3d )
6403 {
6404
6405 ENTRY("AFNI_imseq_clearstat") ;
6406
6407 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
6408
6409 if( im3d->s123 != NULL )
6410 drive_MCW_imseq( im3d->s123 , isqDR_clearstat , NULL ) ;
6411
6412 if( im3d->s231 != NULL )
6413 drive_MCW_imseq( im3d->s231 , isqDR_clearstat , NULL ) ;
6414
6415 if( im3d->s312 != NULL )
6416 drive_MCW_imseq( im3d->s312 , isqDR_clearstat , NULL ) ;
6417
6418 EXRETURN ;
6419 }
6420
6421 /****************************************************************
6422 3/24/95: range controls in func panel for user management
6423 of the conversion of pbar values [-1..1] to
6424 thresholds for the coloring of functional data
6425 *****************************************************************/
6426
6427 /*--------------------------------------------------------------
6428 create label for range display in function control panel
6429 ----------------------------------------------------------------*/
6430
AFNI_range_label(Three_D_View * im3d)6431 XmString AFNI_range_label( Three_D_View *im3d )
6432 {
6433 char anat_minch[10] = " --------" , anat_maxch[10] = " --------" ,
6434 fim_minch[10] = " --------" , fim_maxch[10] = " --------" ,
6435 thr_minch[10] = " --------" , thr_maxch[10] = " --------" ;
6436 char buf[256] , qbuf[20] ;
6437 XmString xstr ;
6438 int iv ;
6439
6440 ENTRY("AFNI_range_label") ;
6441
6442 if( im3d != NULL && im3d->vinfo != NULL ){ /* 30 Mar 2005 */
6443 im3d->vinfo->stats_anat_ok =
6444 im3d->vinfo->stats_func_ok =
6445 im3d->vinfo->arang_func_ok =
6446 im3d->vinfo->stats_thresh_ok = 0 ;
6447 }
6448
6449 /*** anat statistics ***/
6450
6451 if( IM3D_OPEN(im3d) ){
6452 STATUS("RELOAD_STATS(anat_now)") ;
6453 RELOAD_STATS(im3d->anat_now) ;
6454 }
6455
6456 if( IM3D_OPEN(im3d) &&
6457 ISVALID_3DIM_DATASET(im3d->anat_now) &&
6458 ISVALID_STATISTIC(im3d->anat_now->stats) ){
6459
6460 iv = im3d->vinfo->anat_index ;
6461
6462 if( DSET_VALID_BSTAT(im3d->anat_now,iv) ){
6463 STATUS("anat_now statistics") ;
6464 AV_fval_to_char( im3d->anat_now->stats->bstat[iv].min , qbuf ) ;
6465 sprintf( anat_minch , "%9.9s" , qbuf ) ;
6466 AV_fval_to_char( im3d->anat_now->stats->bstat[iv].max , qbuf ) ;
6467 sprintf( anat_maxch , "%9.9s" , qbuf ) ;
6468 im3d->vinfo->stats_anat_ok = 1 ;
6469 } else {
6470 STATUS("can't load anat_now bstat") ;
6471 }
6472 }
6473
6474 /*** func statistics ***/
6475
6476 if( IM3D_OPEN(im3d) ){
6477 STATUS("RELOAD_STATS(fim_now)") ;
6478 RELOAD_STATS(im3d->fim_now) ;
6479 }
6480
6481 if( IM3D_OPEN(im3d) &&
6482 ISVALID_3DIM_DATASET(im3d->fim_now) &&
6483 ISVALID_STATISTIC(im3d->fim_now->stats) ){
6484
6485 iv = im3d->vinfo->fim_index ;
6486
6487 if( DSET_VALID_BSTAT(im3d->fim_now,iv) ){
6488 STATUS("fim_now statistics") ;
6489 AV_fval_to_char( im3d->fim_now->stats->bstat[iv].min , qbuf ) ;
6490 sprintf( fim_minch , "%9.9s" , qbuf ) ;
6491 AV_fval_to_char( im3d->fim_now->stats->bstat[iv].max , qbuf ) ;
6492 sprintf( fim_maxch , "%9.9s" , qbuf ) ;
6493 im3d->vinfo->stats_func_ok = 1 ;
6494 } else {
6495 STATUS("can't load fim_now bstat") ;
6496 }
6497
6498 iv = im3d->vinfo->thr_index ;
6499
6500 if( DSET_VALID_BSTAT(im3d->fim_now,iv) ){
6501 STATUS("thr_now statistics") ;
6502 AV_fval_to_char( im3d->fim_now->stats->bstat[iv].min , qbuf ) ;
6503 sprintf( thr_minch , "%9.9s" , qbuf ) ;
6504 AV_fval_to_char( im3d->fim_now->stats->bstat[iv].max , qbuf ) ;
6505 sprintf( thr_maxch , "%9.9s" , qbuf ) ;
6506 im3d->vinfo->stats_thresh_ok = 1 ;
6507 } else {
6508 STATUS("can't load thr_now bstat") ;
6509 }
6510 }
6511
6512 /*** make label ***/
6513
6514 STATUS("make buf label") ;
6515
6516 sprintf( buf , "ULay %s:%s\nOLay %s:%s\nThr %s:%s" ,
6517 anat_minch,anat_maxch, fim_minch,fim_maxch, thr_minch,thr_maxch ) ;
6518
6519 STATUS(buf) ;
6520
6521 xstr = XmStringCreateLtoR( buf , XmFONTLIST_DEFAULT_TAG ) ;
6522
6523 RETURN(xstr) ;
6524 }
6525
6526 /*-----------------------------------------------------------
6527 find the autorange (default value) and make a label for
6528 the autorange control widget
6529 -------------------------------------------------------------*/
6530
AFNI_autorange_label(Three_D_View * im3d)6531 XmString AFNI_autorange_label( Three_D_View *im3d )
6532 {
6533 XmString xstr ;
6534 float rrr ;
6535 char buf[32] , qbuf[20] ;
6536
6537 ENTRY("AFNI_autorange_label") ;
6538
6539 /* INFO_message("---------- AFNI_autorange_label") ; */
6540
6541 if( ! ISVALID_3DIM_DATASET(im3d->fim_now) ){ /* no function */
6542 rrr = DEFAULT_FIM_SCALE ;
6543 } else {
6544 RELOAD_STATS(im3d->fim_now) ;
6545 if( ISVALID_STATISTIC(im3d->fim_now->stats) ){
6546 float s1 , s2 ; int iv ;
6547
6548 iv = im3d->vinfo->fim_index ;
6549
6550 if( DSET_VALID_BSTAT(im3d->fim_now,iv) ){
6551 s1 = fabsf(im3d->fim_now->stats->bstat[iv].min) ,
6552 s2 = fabsf(im3d->fim_now->stats->bstat[iv].max) ;
6553 rrr = (s1 < s2) ? s2 : s1 ; /* largest fim */
6554 } else {
6555 rrr = DEFAULT_FIM_SCALE ; /* don't have brick stats */
6556 }
6557 } else {
6558 rrr = DEFAULT_FIM_SCALE ; /* don't have brick stats */
6559 }
6560 }
6561 #if 0
6562 if( rrr > 1.0f && rrr < DEFAULT_FIM_SCALE ){
6563 float ppp = AFNI_numenv("AFNI_AUTORANGE_POWER") ;
6564 if( ppp > 0.0f && ppp < 1.0f ) rrr = powf(rrr,ppp) ;
6565 }
6566 #endif
6567
6568 /* ININFO_message(" old style rrr = %g",rrr) ; */
6569
6570 /* Get the autorange as a percentage point of the nonzero values */
6571
6572 if( im3d->fim_now->int_cmap == CONT_CMAP && AUTORANGE_PERC > 1 && AUTORANGE_PERC < 100 ){
6573 MRI_IMAGE *qim=NULL ; float qval ;
6574 if( !DSET_LOADED(im3d->fim_now) && DSET_TOTALBYTES(im3d->fim_now) < 66666666 )
6575 DSET_load(im3d->fim_now) ;
6576 if( DSET_LOADED(im3d->fim_now) ){
6577 qim = THD_extract_float_brick(im3d->vinfo->fim_index,im3d->fim_now) ;
6578 } else if( im3d->fim_now->warp_parent != NULL &&
6579 DSET_LOADED(im3d->fim_now->warp_parent) ){
6580 qim = THD_extract_float_brick(im3d->vinfo->fim_index,im3d->fim_now->warp_parent) ;
6581 }
6582 if( qim != NULL ){
6583 qval = percentile_nzabs( qim->nvox, MRI_FLOAT_PTR(qim), AUTORANGE_PERC ) ;
6584 mri_free(qim) ;
6585 if( qval > 0.0f ) rrr = qval ;
6586 }
6587 }
6588
6589 if( rrr == 0.0f ) rrr = DEFAULT_FIM_SCALE ;
6590
6591 im3d->vinfo->fim_autorange = rrr ;
6592 im3d->vinfo->arang_func_ok = 1 ;
6593 AV_fval_to_char( rrr , qbuf ) ;
6594 sprintf( buf , "autoRange:%s" , qbuf ) ;
6595 xstr = XmStringCreateLtoR( buf , XmFONTLIST_DEFAULT_TAG ) ;
6596
6597 #ifdef AFNI_DEBUG
6598 { STATUS(buf) ;
6599 sprintf(buf,"rrr=%g",rrr) ; STATUS(buf) ; }
6600 #endif
6601
6602 RETURN(xstr) ;
6603 }
6604
6605 /*----------------------------------------------------------------
6606 called when the user toggles the autorange button
6607 ------------------------------------------------------------------*/
6608
AFNI_range_bbox_CB(Widget w,XtPointer cd,XtPointer cb)6609 void AFNI_range_bbox_CB( Widget w, XtPointer cd, XtPointer cb )
6610 {
6611 Three_D_View *im3d = (Three_D_View *) cd ;
6612 RwcBoolean new_auto ;
6613
6614 ENTRY("AFNI_range_bbox_CB") ;
6615
6616 if( ! IM3D_OPEN(im3d) ||
6617 w != im3d->vwid->func->range_bbox->wbut[RANGE_AUTOBUT] ) EXRETURN ;
6618
6619 new_auto = (MCW_val_bbox(im3d->vwid->func->range_bbox) & RANGE_AUTOVAL) != 0 ;
6620
6621 if( new_auto != im3d->vinfo->use_autorange ){ /* new button value */
6622
6623 im3d->vinfo->use_autorange = new_auto ;
6624
6625 im3d->vinfo->fim_range = (new_auto) ? (im3d->vinfo->fim_autorange)
6626 : (im3d->vwid->func->range_av->fval) ;
6627
6628 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
6629 STATUS("incoherent ulay -- patching") ;
6630 ERROR_message("AFNI_range_bbox_CB: incoherent ulay -- patching") ;
6631 AFNI_assign_ulay_bricks(im3d) ;
6632 }
6633
6634 if( PBAR_FULLRANGE ){
6635 AFNI_redisplay_func_ignore(1) ;
6636 AFNI_pbar_topset(im3d,im3d->vinfo->fim_range) ;
6637 AFNI_redisplay_func_ignore(0) ;
6638 }
6639 else HINTIZE_pbar(im3d) ;
6640
6641 AV_SENSITIZE( im3d->vwid->func->range_av , ! new_auto ) ;
6642
6643 AFNI_redisplay_func( im3d ) ;
6644
6645 AFNI_range_lock_carryout(im3d) ; /* 23 Feb 2004 */
6646 }
6647
6648 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
6649 EXRETURN ;
6650 }
6651
6652 /*----------------------------------------------------------------
6653 called when the user toggles the percentile button
6654 ------------------------------------------------------------------*/
6655
AFNI_perc_bbox_CB(Widget w,XtPointer cd,XtPointer cb)6656 void AFNI_perc_bbox_CB( Widget w, XtPointer cd, XtPointer cb )
6657 {
6658 Three_D_View *im3d = (Three_D_View *) cd ;
6659
6660 ENTRY("AFNI_perc_bbox_CB") ;
6661
6662 if( ! IM3D_OPEN(im3d) ||
6663 w != im3d->vwid->func->perc_bbox->wbut[PERC_AUTOBUT] ) EXRETURN ;
6664
6665 im3d->cont_perc_thr = MCW_val_bbox(im3d->vwid->func->perc_bbox);
6666 flush_3Dview_sort(im3d, "T");
6667
6668 AFNI_redisplay_func( im3d ) ;
6669 AFNI_thresh_lock_carryout(im3d) ;
6670
6671 EXRETURN ;
6672 }
6673
6674
6675 /*----------------------------------------------------------------
6676 called when the user (that rotten fellow) changes the fim range
6677 ------------------------------------------------------------------*/
6678
AFNI_range_av_CB(MCW_arrowval * av,XtPointer cd)6679 void AFNI_range_av_CB( MCW_arrowval *av , XtPointer cd )
6680 {
6681 Three_D_View *im3d = (Three_D_View *) cd ;
6682
6683 ENTRY("AFNI_range_av_CB") ;
6684
6685 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
6686
6687 im3d->vinfo->stats_anat_ok =
6688 im3d->vinfo->stats_func_ok =
6689 im3d->vinfo->arang_func_ok =
6690 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
6691
6692 im3d->vinfo->fim_range = av->fval ;
6693
6694 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
6695 STATUS("incoherent ulay -- patching") ;
6696 ERROR_message("AFNI_range_av_CB: incoherent ulay -- patching") ;
6697 AFNI_assign_ulay_bricks(im3d) ;
6698 }
6699
6700 if( PBAR_FULLRANGE ){
6701 AFNI_redisplay_func_ignore(1) ;
6702 AFNI_pbar_topset(im3d,im3d->vinfo->fim_range) ;
6703 AFNI_redisplay_func_ignore(0) ;
6704 }
6705 else HINTIZE_pbar(im3d) ;
6706
6707 AFNI_redisplay_func( im3d ) ;
6708
6709 AFNI_range_lock_carryout(im3d) ; /* 23 Feb 2004 */
6710
6711 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
6712 EXRETURN ;
6713 }
6714
6715 /*----------------------------------------------------------------
6716 called when the user toggles the posfunc button
6717 ------------------------------------------------------------------*/
6718
AFNI_inten_bbox_CB(Widget w,XtPointer cd,XtPointer cb)6719 void AFNI_inten_bbox_CB( Widget w, XtPointer cd, XtPointer cb )
6720 {
6721 Three_D_View *im3d = (Three_D_View *) cd ;
6722 RwcBoolean new_pos ;
6723 int jm ;
6724 MCW_pbar *pbar ;
6725
6726 ENTRY("AFNI_inten_bbox_CB") ;
6727
6728 if( ! IM3D_OPEN(im3d) ||
6729 w != im3d->vwid->func->inten_bbox->wbut[PBAR_MODEBUT] ) EXRETURN ;
6730
6731 new_pos = (MCW_val_bbox(im3d->vwid->func->inten_bbox) & PBAR_MODEPOS) != 0 ;
6732
6733 if( new_pos != im3d->vinfo->use_posfunc ){ /* new button value */
6734
6735 im3d->vinfo->use_posfunc = new_pos ; /* record for later use */
6736
6737 pbar = im3d->vwid->func->inten_pbar ;
6738 jm = pbar->mode = (new_pos) ? 1 : 0 ; /* pbar mode */
6739
6740 /* re-panel the pbar befitting its new mode */
6741
6742 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
6743 STATUS("incoherent ulay -- patching") ;
6744 ERROR_message("AFNI_inten_bbox_CB: incoherent ulay -- patching") ;
6745 AFNI_assign_ulay_bricks(im3d) ;
6746 }
6747
6748 AFNI_redisplay_func_ignore(1) ;
6749
6750 HIDE_SCALE(im3d) ;
6751 if( pbar->bigmode ){ /* 30 Jan 2003 */
6752 int npane=pbar->num_panes ;
6753 float pmin , pmax ;
6754 pmax = (pbar->big31) ? pbar->bigtop
6755 : pbar->pval_save[npane][0 ][jm] ;
6756 pmin = (pbar->big31) ? ( (jm==1) ? 0.0f : -pmax )
6757 : pbar->pval_save[npane][npane][jm] ;
6758 pbar->bigset = 0 ;
6759 PBAR_set_bigmode( pbar , 1 , pmin,pmax ) ;
6760 AFNI_inten_pbar_CB( pbar , im3d , 0 ) ;
6761 } else {
6762 alter_MCW_pbar( pbar , pbar->npan_save[jm] , NULL ) ;
6763 }
6764 FIX_SCALE_SIZE(im3d) ;
6765
6766 /* set the count on the pbar control arrowval to match */
6767
6768 if( pbar->bigmode )
6769 AV_assign_ival( im3d->vwid->func->inten_av, NPANE_MAX+1 ) ;
6770 else
6771 AV_assign_ival( im3d->vwid->func->inten_av, pbar->npan_save[jm] ) ;
6772
6773 if( PBAR_FULLRANGE && !IM3D_IS_BIGTHREE(im3d) )
6774 AFNI_pbar_topset(im3d,im3d->vinfo->fim_range) ;
6775 else
6776 HINTIZE_pbar(im3d) ;
6777
6778 AFNI_redisplay_func_ignore(0) ;
6779 AFNI_redisplay_func( im3d ) ;
6780 if( AFNI_count_controllers() > 1 && AFNI_check_pbar_lock() ) /* 03 Jul 2014 */
6781 AFNI_redisplay_func_all( im3d ) ;
6782 }
6783
6784 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
6785 EXRETURN ;
6786 }
6787
6788 /*--------------------------------------------------------------
6789 Called to reset the range related functional stuff
6790 ----------------------------------------------------------------*/
6791
AFNI_reset_func_range(Three_D_View * im3d)6792 void AFNI_reset_func_range( Three_D_View *im3d )
6793 {
6794 XmString xstr ;
6795 RwcBoolean same ;
6796 int iqq = AFNI_controller_index(im3d) ;
6797
6798 ENTRY("AFNI_reset_func_range") ;
6799
6800 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
6801
6802 im3d->vinfo->stats_anat_ok =
6803 im3d->vinfo->stats_func_ok =
6804 im3d->vinfo->arang_func_ok =
6805 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
6806
6807 if( PBAR_FULLRANGE && !IM3D_ULAY_COHERENT(im3d) ){ /* 10 Jun 2014 */
6808 STATUS("incoherent ulay -- patching") ;
6809 ERROR_message("AFNI_reset_func_range: incoherent ulay -- patching") ;
6810 AFNI_assign_ulay_bricks(im3d) ;
6811 }
6812
6813 /*-- the range label widget --*/
6814
6815 xstr = AFNI_range_label( im3d ) ;
6816 same = XmStringCompare( xstr , im3d->vinfo->old_range_label ) ;
6817
6818 if( same == False ){
6819 XtVaSetValues( im3d->vwid->func->range_label , /* redisplay */
6820 XmNlabelString , xstr , /* if changed */
6821 NULL ) ;
6822 MCW_expose_widget( im3d->vwid->func->range_label ) ; /* redraw now! */
6823 XmStringFree(im3d->vinfo->old_range_label) ; /* toss old */
6824 im3d->vinfo->old_range_label = xstr ; /* new old */
6825 } else {
6826 XmStringFree( xstr ) ; /* was same --> don't need this copy */
6827 }
6828
6829 /*-- the autorange toggle widget --*/
6830
6831 xstr = AFNI_autorange_label( im3d ) ;
6832 same = XmStringCompare( xstr , im3d->vinfo->autorange_label ) ;
6833
6834 if( same == False ){
6835 Widget www = im3d->vwid->func->range_bbox->wbut[RANGE_AUTOBUT] ;
6836 XtVaSetValues( www , XmNlabelString , xstr , NULL ) ;
6837 MCW_expose_widget( www ) ;
6838 XmStringFree(im3d->vinfo->autorange_label) ;
6839 im3d->vinfo->autorange_label = xstr ;
6840 } else {
6841 XmStringFree( xstr ) ; /* was same --> don't need this copy */
6842 }
6843
6844 /*-- the functional range itself --*/
6845
6846 im3d->vinfo->fim_range =
6847 (im3d->vinfo->use_autorange) ? (im3d->vinfo->fim_autorange)
6848 : (im3d->vwid->func->range_av->fval) ;
6849
6850 if( PBAR_FULLRANGE && (reset_func_range_ncall[iqq]==0 || !IM3D_IS_BIGTHREE(im3d)) ){
6851 AFNI_redisplay_func_ignore(1) ;
6852 AFNI_pbar_topset(im3d,im3d->vinfo->fim_range) ;
6853 AFNI_redisplay_func_ignore(0) ; reset_func_range_ncall[iqq]++ ;
6854 }
6855 else HINTIZE_pbar(im3d) ;
6856
6857 EXRETURN ;
6858 }
6859
6860 /*--------------------------------------------------------------------
6861 30 Nov 1997: Callback for when the a bucket chooser is altered;
6862 will switch the viewing to a new sub-brick.
6863 ----------------------------------------------------------------------*/
6864
AFNI_bucket_CB(MCW_arrowval * av,XtPointer cd)6865 void AFNI_bucket_CB( MCW_arrowval *av , XtPointer cd )
6866 {
6867 Three_D_View *im3d = (Three_D_View *) cd ;
6868 int doit=0 , iv , redisplay , dothr=0 ;
6869
6870 ENTRY("AFNI_bucket_CB") ;
6871
6872 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
6873
6874 #if 0
6875 STATUS_IM3D_TMASK(im3d) ;
6876 STATUS("clear tmask") ;
6877 #endif
6878 IM3D_CLEAR_TMASK(im3d) ; /* Mar 2013 */
6879 IM3D_CLEAR_THRSTAT(im3d) ; /* 12 Jun 2014 */
6880 AFNI_setup_thrstat(im3d,0) ; /* 27 Jun 2019 */
6881
6882 im3d->vinfo->stats_anat_ok =
6883 im3d->vinfo->stats_func_ok =
6884 im3d->vinfo->arang_func_ok =
6885 im3d->vinfo->stats_thresh_ok = 0 ; /* 24 May 2019 */
6886
6887 /** Anat sub-brick [29 Jul 2003: lock to time_index controller as well] **/
6888
6889 if( av == im3d->vwid->func->anat_buck_av ){
6890 iv = av->ival ;
6891 if( iv >= 0 && iv < DSET_NVALS(im3d->anat_now) ){
6892 doit = (iv != im3d->vinfo->anat_index) ;
6893 im3d->vinfo->anat_index = iv ;
6894 redisplay = REDISPLAY_ALL ;
6895 if( doit && im3d->vinfo->time_on )
6896 AV_assign_ival( im3d->vwid->imag->time_index_av , iv ) ;
6897 }
6898 }
6899
6900 /** Func sub-brick **/
6901
6902 else if( av == im3d->vwid->func->fim_buck_av ){
6903 iv = av->ival ;
6904 if( iv >= 0 && iv < DSET_NVALS(im3d->fim_now) ){
6905 doit = (iv != im3d->vinfo->fim_index) ;
6906 im3d->vinfo->fim_index = iv ;
6907 redisplay = REDISPLAY_OVERLAY ;
6908 AFNI_enforce_throlayx(im3d) ; /* 13 Aug 2010 */
6909 if( doit && im3d->vinfo->time_on && DSET_NUM_TIMES(im3d->anat_now) == 1 )
6910 AV_assign_ival( im3d->vwid->imag->time_index_av , iv ) ;
6911 }
6912 }
6913
6914 /** Thresh sub-brick **/
6915
6916 else if( av == im3d->vwid->func->thr_buck_av ){
6917 iv = av->ival ;
6918 if( iv >= 0 && iv < DSET_NVALS(im3d->fim_now) ){
6919 doit = (iv != im3d->vinfo->thr_index) ;
6920 im3d->vinfo->thr_index = iv ;
6921 redisplay = REDISPLAY_OVERLAY ;
6922 }
6923 dothr = 1 ;
6924 }
6925
6926 /** Change the view, if required **/
6927
6928 if( doit ){
6929 SHOW_AFNI_PAUSE ;
6930 im3d->vinfo->tempflag = 1 ;
6931 AFNI_setup_viewing( im3d , False ) ;
6932 AFNI_set_viewpoint( im3d , -1,-1,-1 , redisplay ) ; /* redraw */
6933 if( redisplay == REDISPLAY_OVERLAY &&
6934 im3d->vinfo->func_visible ) AFNI_process_funcdisplay(im3d) ;
6935 SHOW_AFNI_READY ;
6936 }
6937
6938 if( dothr && AFNI_yesenv("AFNI_THRESH_AUTO") ){ /* 05 Mar 2007 */
6939 float new_thresh = AFNI_get_autothresh(im3d) ;
6940 if( new_thresh > 0.0f ) AFNI_set_threshold(im3d,new_thresh) ;
6941 } else if( dothr ){
6942 if( im3d->vinfo->fix_pval && im3d->vinfo->fixed_pval > 0.0f )
6943 AFNI_set_pval(im3d,im3d->vinfo->fixed_pval) ;
6944 else if( im3d->vinfo->fix_qval && im3d->vinfo->fixed_qval > 0.0f )
6945 AFNI_set_qval(im3d,im3d->vinfo->fixed_qval) ;
6946 }
6947
6948
6949 FIX_SCALE_SIZE(im3d) ;
6950 AFNI_fix_scale_size_direct(im3d) ; /* 03 Jun 2019 */
6951 EXRETURN ;
6952 }
6953
6954 /*--------------------------------------------------------------------------*/
6955 /*! Prepare a bucket label for a menu.
6956 21 Jun 2004: modified to allow label length to be different from 14.
6957 ----------------------------------------------------------------------------*/
6958
6959 static int force_label_resize = 0 ;
AFNI_force_bucket_label_resize(int ff)6960 void AFNI_force_bucket_label_resize( int ff ){ force_label_resize = ff ; }
6961
AFNI_bucket_label_CB(MCW_arrowval * av,XtPointer cd)6962 char * AFNI_bucket_label_CB( MCW_arrowval *av , XtPointer cd )
6963 {
6964 static THD_3dim_dataset *dset_last = NULL ;
6965 static int nsiz_last = 4 ;
6966
6967 THD_3dim_dataset *dset = (THD_3dim_dataset *) cd ;
6968 static char *fmt[3]={NULL,NULL,NULL}, sfmt[THD_MAX_SBLABEL],blab[26+THD_MAX_SBLABEL] ;
6969 int nlab ;
6970 static int nlab_old = 0 ;
6971
6972 ENTRY("AFNI_bucket_label_CB") ;
6973
6974 /** 04 May 2005: customize width to this dataset **/
6975
6976 if( ISVALID_DSET(dset) && ( dset != dset_last || force_label_resize ) ){
6977 int nvals,kk,blw,mblw=4 ; char *lab ;
6978 dset_last = dset ;
6979 nvals = DSET_NVALS(dset) ;
6980 for( kk=0 ; kk < nvals ; kk++ ){
6981 lab = DSET_BRICK_LAB(dset,kk) ;
6982 if( lab != NULL ){ blw=strlen(lab) ; if(blw>mblw)mblw=blw ; }
6983 }
6984 if( mblw > THD_MAX_SBLABEL ) mblw = THD_MAX_SBLABEL ;
6985 nsiz_last = mblw ;
6986 }
6987
6988 /* see if the environment overrides the above */
6989
6990 #if 0
6991 nlab = (int)AFNI_numenv("AFNI_BUCKET_LABELSIZE") ;
6992 if( nlab <= 0 ) nlab = nsiz_last ;
6993 else if( nlab > 32 ) nlab = 32 ;
6994 #else
6995 nlab = nsiz_last ;
6996 #endif
6997
6998 /* make the format for the label string: left justified, width=nlab */
6999
7000 if( nlab != nlab_old ){
7001 nlab_old = nlab ;
7002 sprintf(sfmt,"%%-%d.%ds",nlab,nlab) ;
7003 if( fmt[0] == NULL ){
7004 fmt[0] = malloc(THD_MAX_SBLABEL); fmt[1] = malloc(THD_MAX_SBLABEL);
7005 fmt[2] = malloc(THD_MAX_SBLABEL);
7006 }
7007
7008 /* and now the formats including the sub-brick index and the label */
7009
7010 #ifdef USE_RIGHT_BUCK_LABELS
7011 sprintf(fmt[0],"%s #%%1d",sfmt) ; /* if the #xxx goes to the right */
7012 sprintf(fmt[1],"%s #%%2d",sfmt) ;
7013 sprintf(fmt[2],"%s #%%3d",sfmt) ;
7014 #else
7015 sprintf(fmt[0],"#%%1d %s",sfmt) ; /* if the #xxx goes to the left */
7016 sprintf(fmt[1],"#%%2d %s",sfmt) ;
7017 sprintf(fmt[2],"#%%3d %s",sfmt) ;
7018 #endif
7019 }
7020
7021 /* now actually make the label for this particular sub-brick */
7022
7023 if( ISVALID_3DIM_DATASET(dset) ){
7024
7025 #ifdef USE_RIGHT_BUCK_LABELS
7026 if( DSET_NVALS(dset) < 10 )
7027 sprintf(blab, fmt[0] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
7028 else if( DSET_NVALS(dset) < 100 )
7029 sprintf(blab, fmt[1] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
7030 else
7031 sprintf(blab, fmt[2] , DSET_BRICK_LABEL(dset,av->ival) , av->ival ) ;
7032 #else
7033 if( DSET_NVALS(dset) < 10 )
7034 sprintf(blab, fmt[0] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
7035 else if( DSET_NVALS(dset) < 100 )
7036 sprintf(blab, fmt[1] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
7037 else
7038 sprintf(blab, fmt[2] , av->ival , DSET_BRICK_LABEL(dset,av->ival) ) ;
7039 #endif
7040 }
7041 else
7042 sprintf(blab," #%d ",av->ival) ; /* shouldn't happen, but you never know */
7043
7044 RETURN(blab) ;
7045 }
7046
7047 /*---------------------------------------------------------------
7048 Callback for the 'AFNI Tips' button [27 Jun 2011]
7049 -----------------------------------------------------------------*/
7050
7051 #ifndef DONT_USE_HTMLWIN
7052 static int tips_open = 0 ;
7053 static MCW_htmlwin *tips_hw = NULL ;
AFNI_tips_killfun(XtPointer junk)7054 void AFNI_tips_killfun( XtPointer junk ){
7055 tips_open = 0 ; tips_hw = NULL ; return ;
7056 }
7057 #endif
7058
AFNI_tips_CB(Widget w,XtPointer cd,XtPointer cbd)7059 void AFNI_tips_CB( Widget w , XtPointer cd , XtPointer cbd )
7060 {
7061 #include "readme_afnigui.h"
7062 Three_D_View *im3d = (Three_D_View *)cd ;
7063 char *inf=NULL , *fpt=NULL ; int ii ;
7064
7065 ENTRY("AFNI_tips_CB") ;
7066
7067 #ifndef DONT_USE_HTMLWIN
7068 if( tips_open && tips_hw != NULL ){
7069 XMapRaised( XtDisplay(tips_hw->wshell) , XtWindow(tips_hw->wshell) ) ;
7070 EXRETURN ;
7071 } else if( !AFNI_noenv("AFNI_DONT_USE_HTMLWIN") ){
7072 fpt = THD_find_regular_file("afnigui.html", NULL) ;
7073 if( fpt != NULL && *fpt != '\0' ){
7074 inf = (char *)malloc(sizeof(char)*(strlen(fpt)+16)) ;
7075 strcpy(inf,"file:") ; strcat(inf,fpt) ; free(fpt) ;
7076 tips_hw = new_MCW_htmlwin( im3d->vwid->imag->topper, inf,
7077 AFNI_tips_killfun , NULL ,
7078 NULL, 0 ) ;
7079 free(inf) ; tips_open = 1 ; EXRETURN ;
7080 }
7081 }
7082 #endif
7083
7084 for( ii=0 ; readme_afnigui[ii] != NULL ; ii++ ){
7085 inf = THD_zzprintf( inf , " %s" , readme_afnigui[ii] ) ;
7086 }
7087 (void)new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7088 free(inf) ; EXRETURN ;
7089 }
7090
7091 /*---------------------------------------------------------------*/
7092 /* For the 'AFNI news' button [15 May 2019] */
7093
7094 #undef NEWS_LINK
7095 #define NEWS_LINK \
7096 "https://afni.nimh.nih.gov/pub/dist/src/AFNI_digest_history.txt"
7097
AFNI_news_CB(Widget w,XtPointer cd,XtPointer cbd)7098 void AFNI_news_CB( Widget w , XtPointer cd , XtPointer cbd )
7099 {
7100 static int first=1 ;
7101 if( GLOBAL_browser != NULL ){
7102 if( first ){
7103 (void) MCW_popup_message( w , " \n"
7104 " * At this time, the news page is *\n"
7105 " * very limited. We plan to make *\n"
7106 " * it much better REAL SOON NOW!! *\n" ,
7107 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7108 first = 0 ; AFNI_sleep(666) ;
7109 }
7110 whereami_browser(NEWS_LINK) ;
7111 } else {
7112 (void) MCW_popup_message( w , " \n"
7113 " ** Can't find a Web browser :( **\n"
7114 " Try setting environment variable\n"
7115 " AFNI_WEB_BROWSER\n"
7116 " to be the path to a browser\n"
7117 " command line path\n" ,
7118 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7119 }
7120 }
7121
7122 /*---------------------------------------------------------------*/
7123 /* For the 'AFNI Forum' button [17 May 2019] */
7124
7125 #undef FORUM_LINK
7126 #define FORUM_LINK \
7127 "https://afni.nimh.nih.gov/afni/community/board/"
7128
AFNI_forum_CB(Widget w,XtPointer cd,XtPointer cbd)7129 void AFNI_forum_CB( Widget w , XtPointer cd , XtPointer cbd )
7130 {
7131 if( GLOBAL_browser != NULL ){
7132 whereami_browser(FORUM_LINK) ;
7133 } else {
7134 (void) MCW_popup_message( w , " \n"
7135 " ** Can't find a Web browser :( **\n"
7136 " Try setting environment variable\n"
7137 " AFNI_WEB_BROWSER\n"
7138 " to be the path to a browser\n"
7139 " command line path\n" ,
7140 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7141 }
7142 }
7143
7144 /*---------------------------------------------------------------*/
7145 /* For the 'Prog Helps' button [17 May 2019] */
7146
7147 #undef PHELP_LINK
7148 #define PHELP_LINK \
7149 "https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/programs/main_toc.html"
7150
AFNI_phelp_CB(Widget w,XtPointer cd,XtPointer cbd)7151 void AFNI_phelp_CB( Widget w , XtPointer cd , XtPointer cbd )
7152 {
7153 if( GLOBAL_browser != NULL ){
7154 whereami_browser(PHELP_LINK) ;
7155 } else {
7156 (void) MCW_popup_message( w , " \n"
7157 " ** Can't find a Web browser :( **\n"
7158 " Try setting environment variable\n"
7159 " AFNI_WEB_BROWSER\n"
7160 " to be the path to a browser\n"
7161 " command line path\n" ,
7162 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7163 }
7164 }
7165
7166 /*---------------------------------------------------------------*/
7167 /* For the 'youtube' button [30 Apr 2020] discoraj */
7168
7169 #undef YTUBE_LINK
7170 #define YTUBE_LINK \
7171 "https://www.youtube.com/channel/UC40RiNZN7_dCuB6Lg7HJl1g"
7172
AFNI_ytube_CB(Widget w,XtPointer cd,XtPointer cbd)7173 void AFNI_ytube_CB( Widget w , XtPointer cd , XtPointer cbd )
7174 {
7175 if( GLOBAL_browser != NULL ){
7176 whereami_browser(YTUBE_LINK) ;
7177 } else {
7178 (void) MCW_popup_message( w , " \n"
7179 " ** Can't find a Web browser :( **\n"
7180 " Try setting environment variable\n"
7181 " AFNI_WEB_BROWSER\n"
7182 " to be the path to a browser\n"
7183 " command line path\n" ,
7184 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7185 }
7186 }
7187
7188 /*---------------------------------------------------------------*/
7189
7190 #include "PvalueStuff.h"
7191
AFNI_pvalue_CB(Widget w,XtPointer cd,XtPointer cbd)7192 void AFNI_pvalue_CB( Widget w , XtPointer cd , XtPointer cbd )
7193 {
7194 Three_D_View *im3d = (Three_D_View *)cd ;
7195 char *inf=NULL ; int ii ;
7196
7197 ENTRY("AFNI_pvalue_CB") ;
7198 if( !IM3D_OPEN(im3d) || w == NULL ) EXRETURN ;
7199
7200 for( ii=0 ; PvalueStuff[ii] != NULL ; ii++ )
7201 inf = THD_zzprintf( inf , " %s" , PvalueStuff[ii] ) ;
7202 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7203 free(inf) ;
7204 EXRETURN ;
7205 }
7206
7207 /*--------------------------------------------------------------------*/
7208 /* Print list of AFNI papers [02 May 2014] */
7209
AFNI_list_papers(Widget w)7210 void AFNI_list_papers( Widget w )
7211 {
7212 #include "afni_papers.h"
7213 int ii ;
7214
7215 if( w != (Widget)NULL && XtIsWidget(w) ){ /* open a window */
7216 char *inf=NULL ;
7217 for( ii=0 ; afni_papers[ii] != NULL ; ii++ ){
7218 inf = THD_zzprintf( inf , " %s" , afni_papers[ii] ) ;
7219 }
7220 #ifdef DONT_USE_HTMLWIN
7221 (void) new_MCW_textwin( w , inf , TEXT_READONLY ) ; /* plain text */
7222 #else
7223 { char *qqq = convert_text_to_html(inf) ; /* HTML with links */
7224 (void)new_MCW_htmlwin( w , qqq , NULL,NULL,NULL,0 ) ;
7225 free(qqq) ;
7226 }
7227 #endif
7228 free(inf) ;
7229
7230 } else { /* write papers list to stdout */
7231
7232 for( ii=0 ; afni_papers[ii] != NULL ; ii++ )
7233 fputs(afni_papers[ii],stdout) ;
7234
7235 }
7236 return ;
7237 }
7238
7239 /*--------------------------------------------------------------------*/
7240
AFNI_papers_CB(Widget w,XtPointer cd,XtPointer cbd)7241 void AFNI_papers_CB( Widget w , XtPointer cd , XtPointer cbd )
7242 {
7243 Three_D_View *im3d = (Three_D_View *)cd ;
7244
7245 if( IM3D_OPEN(im3d) )
7246 AFNI_list_papers( im3d->vwid->imag->topper ) ;
7247
7248 return ;
7249 }
7250
7251 /*---------------------------------------------------------------
7252 Callback for all actions in the misc menu
7253 -----------------------------------------------------------------*/
7254
AFNI_misc_CB(Widget w,XtPointer cd,XtPointer cbd)7255 void AFNI_misc_CB( Widget w , XtPointer cd , XtPointer cbd )
7256 {
7257 Three_D_View *im3d = (Three_D_View *)cd ;
7258 XmAnyCallbackStruct *cbs = (XmAnyCallbackStruct *)cbd ;
7259 int ic ;
7260
7261 ENTRY("AFNI_misc_CB") ;
7262
7263 if( !IM3D_OPEN(im3d) || w == NULL ) EXRETURN ;
7264
7265 ic = AFNI_controller_index(im3d) ;
7266
7267 /*.........................................................*/
7268
7269 if( w == im3d->vwid->dmode->misc_voxind_pb ){
7270 im3d->vinfo->show_voxind = MCW_val_bbox(im3d->vwid->dmode->misc_voxind_bbox);
7271 AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
7272 }
7273
7274 /*.........................................................*/
7275
7276 #ifndef DONT_USE_HINTS
7277 else if( w == im3d->vwid->dmode->misc_hints_pb ){
7278 int val = MCW_val_bbox(im3d->vwid->dmode->misc_hints_bbox) ;
7279 if( val != GLOBAL_library.hints_on ){
7280 int ii ; Three_D_View *qq3d ;
7281 MCW_hint_toggle() ; GLOBAL_library.hints_on = val ;
7282 for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ){ /* this loop: */
7283 qq3d = GLOBAL_library.controllers[ii] ; /* 07 Aug 1999 */
7284 if( IM3D_VALID(qq3d) )
7285 MCW_set_bbox( qq3d->vwid->dmode->misc_hints_bbox , val ) ;
7286 }
7287 }
7288 }
7289 #endif
7290
7291 /*.........................................................*/
7292
7293 else if( w == im3d->vwid->dmode->misc_anat_info_pb ){
7294 char *inf ;
7295 STATUS("getting anat info") ;
7296 inf = THD_dataset_info( im3d->anat_now , 0 ) ;
7297 if( inf != NULL ){
7298 if( DSET_ARRAY(im3d->anat_now,0) == NULL ){
7299 inf = THD_zzprintf( inf , "\n*** Not loaded into memory.\n") ;
7300 } else if( im3d->anat_now->dblk->malloc_type == DATABLOCK_MEM_MALLOC ){
7301 if( DBLK_LOCKED(im3d->anat_now->dblk) )
7302 inf = THD_zzprintf( inf , "\n*** Locked into memory using malloc.\n") ;
7303 else
7304 inf = THD_zzprintf( inf , "\n*** Loaded into memory using malloc.\n") ;
7305 } else if( im3d->anat_now->dblk->malloc_type == DATABLOCK_MEM_MMAP ){
7306 inf = THD_zzprintf( inf , "\n*** Loaded into memory using mmap.\n") ;
7307 } else if( im3d->anat_now->dblk->malloc_type == DATABLOCK_MEM_SHARED ){
7308 inf = THD_zzprintf( inf , "\n*** Loaded into shared memory segment %d.\n",
7309 im3d->anat_now->dblk->shm_idint) ;
7310 }
7311 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7312 free(inf) ;
7313 } else {
7314 BEEPIT ; WARNING_message("Can't get anat info") ;
7315 }
7316 }
7317
7318 /*.........................................................*/
7319
7320 else if( w == im3d->vwid->dmode->misc_func_info_pb ){
7321 char *inf ;
7322 STATUS("getting func info") ;
7323 inf = THD_dataset_info( im3d->fim_now , 0 ) ;
7324 STATUS("got func info") ;
7325 if( inf != NULL ){
7326 if( DSET_ARRAY(im3d->fim_now,0) == NULL ){
7327 inf = THD_zzprintf( inf , "\n*** Not loaded into memory.\n") ;
7328 } else if( im3d->fim_now->dblk->malloc_type == DATABLOCK_MEM_MALLOC ){
7329 if( DBLK_LOCKED(im3d->fim_now->dblk) )
7330 inf = THD_zzprintf( inf , "\n*** Locked into memory using malloc.\n") ;
7331 else
7332 inf = THD_zzprintf( inf , "\n*** Loaded into memory using malloc.\n") ;
7333 } else if( im3d->fim_now->dblk->malloc_type == DATABLOCK_MEM_MMAP ){
7334 inf = THD_zzprintf( inf , "\n*** Loaded into memory using mmap.\n") ;
7335 } else if( im3d->fim_now->dblk->malloc_type == DATABLOCK_MEM_SHARED ){
7336 inf = THD_zzprintf( inf , "\n*** Loaded into shared memory segment %d.\n",
7337 im3d->fim_now->dblk->shm_idint) ;
7338 }
7339 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7340 free(inf) ;
7341 } else {
7342 BEEPIT ; WARNING_message("Can't get func info") ;
7343 }
7344 }
7345
7346 /*.........................................................*/
7347
7348 else if( w == im3d->vwid->dmode->misc_license_pb ){ /* 03 Dec 2000 */
7349 #include "license.h"
7350 char *inf=NULL ; int ii ;
7351 for( ii=0 ; license[ii] != NULL ; ii++ )
7352 inf = THD_zzprintf( inf , " %s" , license[ii] ) ;
7353 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7354 free(inf) ;
7355 }
7356
7357 /*.........................................................*/
7358
7359 else if( w == im3d->vwid->dmode->misc_readme_env_pb ){ /* 05 Aug 2004 */
7360 #include "readme_env.h"
7361 char *inf=NULL ; int ii ;
7362 for( ii=0 ; readme_env[ii] != NULL ; ii++ )
7363 inf = THD_zzprintf( inf , " %s" , readme_env[ii] ) ;
7364 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
7365 free(inf) ;
7366 }
7367
7368 /*.........................................................*/
7369
7370 else if( w == im3d->vwid->dmode->misc_motd_pb ){ /* 29 Nov 2005 */
7371 AFNI_display_motd( im3d->vwid->imag->topper ) ;
7372 }
7373
7374 /*.........................................................*/
7375
7376 else if( w == im3d->vwid->dmode->misc_hist_pb ){ /* 05 Mar 2008 */
7377 AFNI_display_hist( im3d->vwid->imag->topper ) ;
7378 }
7379
7380 /*.........................................................*/
7381
7382 else if( w == im3d->vwid->dmode->misc_vcheck_pb ){ /* 11 Jan 2000 */
7383 FILE *fp = popen( "afni_vcheck" , "r" ); int vc;
7384 if( fp == NULL ){
7385 BEEPIT ;
7386 (void) MCW_popup_message( im3d->vwid->imag->topper ,
7387 " \n"
7388 "* Cannot execute *\n"
7389 "* afni_vcheck! *\n" ,
7390 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7391 } else {
7392 #define ISIZE 1024
7393 char *info=(char *)malloc(sizeof(char)*ISIZE) ; int ninfo ;
7394 strcpy(info," \n Output of Program afni_vcheck \n"
7395 " ---------------------------------\n \n" ) ;
7396 ninfo = strlen(info) ;
7397 while( afni_fgets(info+ninfo,ISIZE-ninfo,fp) != NULL ){
7398 ninfo = strlen(info) ;
7399 if( ninfo >= ISIZE-2 ) break ;
7400 }
7401 vc = pclose(fp) ;
7402 ninfo = strlen(info) ;
7403 if( ninfo+42 < ISIZE ){
7404 if( vc > 0 ) strcat(info,"\n\n****** VERSIONS DON'T MATCH !! ******\n");
7405 else if( vc == 0 ) strcat(info,"\n\n****** VERSIONS MATCH OK !! ******\n") ;
7406 }
7407 (void) MCW_popup_message( im3d->vwid->imag->topper , info ,
7408 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7409 free(info) ;
7410
7411 if( vc > 0 ) AFNI_vcheck_flasher(im3d) ;
7412 }
7413 }
7414
7415 /*.........................................................*/
7416
7417 else if( w == im3d->vwid->dmode->misc_purge_pb ){
7418 long long mb , ma ;
7419 mb = MCW_MALLOC_total ;
7420 AFNI_purge_dsets( 1 ) ;
7421 ma = MCW_MALLOC_total ;
7422 if( mb > 0 && ma > 0 )
7423 INFO_message("Purge: before=%s after=%s diff=%s",
7424 commaized_integer_string(mb) ,
7425 commaized_integer_string(ma) ,
7426 commaized_integer_string(mb-ma) ) ;
7427 }
7428
7429 /*.........................................................*/
7430
7431 #ifdef USE_TRACING
7432 else if( w == im3d->vwid->dmode->misc_tracing_pb ){
7433 DBG_trace = (DBG_trace + 1) % 3 ; /* Aug 23 1998: cycle between 0,1,2 */
7434 MCW_set_widget_label( im3d->vwid->dmode->misc_tracing_pb, DBG_label ) ; /* 01 Aug 1999 */
7435
7436 XSynchronize( im3d->dc->display, (Bool)(DBG_trace==2) ) ; /* 01 Dec 1999 */
7437 if( DBG_trace == 2 ) STATUS("XSynchronize enabled") ;
7438 else STATUS("XSynchronize disabled") ;
7439 }
7440 #endif
7441
7442 /*.........................................................*/
7443
7444 #ifdef USING_MCW_MALLOC /* 07 Mar 1999 */
7445 else if( MCW_MALLOC_enabled && w == im3d->vwid->dmode->misc_showmalloc_pb ){
7446 MCHECK ;
7447 }
7448
7449 else if( MCW_MALLOC_enabled && w == im3d->vwid->dmode->misc_dumpmalloc_pb ){
7450 mcw_malloc_dump() ;
7451 }
7452 #endif
7453
7454 /*.........................................................*/
7455
7456 #ifdef USE_WRITEOWNSIZE
7457 else if( w == im3d->vwid->dmode->misc_writeownsize_pb ){
7458 im3d->vinfo->writeownsize = MCW_val_bbox( im3d->vwid->dmode->misc_writeownsize_bbox ) ;
7459 }
7460 #endif
7461
7462 /*.........................................................*/
7463
7464 #ifdef ALLOW_PLUGINS
7465 else if( w == im3d->vwid->dmode->misc_environ_pb ){ /* 20 Jun 2000 */
7466 static PLUGIN_interface *plint=NULL ;
7467 Widget wpop ;
7468
7469 /* first time in: create interface like a plugin */
7470
7471 if( plint == NULL ){
7472 plint = ENV_init() ;
7473 if( plint == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7474 PLUG_setup_widgets( plint , GLOBAL_library.dc ) ;
7475 }
7476
7477 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7478
7479 plint->im3d = im3d ;
7480 XtVaSetValues( plint->wid->shell ,
7481 XmNtitle , "AFNI Environmentalism", /* top of window */
7482 XmNiconName , "Green AFNI" , /* label on icon */
7483 NULL ) ;
7484 PLUTO_cursorize( plint->wid->shell ) ;
7485
7486 /*-- if possible, find where this popup should go --*/
7487
7488 wpop = plint->wid->shell ;
7489
7490 if( cbs != NULL && cbs->event != NULL
7491 && cbs->event->type == ButtonRelease ){
7492
7493 XButtonEvent *xev = (XButtonEvent *) cbs->event ;
7494 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7495 int ww,hh , sw,sh ;
7496
7497 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7498 sw = WidthOfScreen (XtScreen(wpop)) ;
7499 sh = HeightOfScreen(XtScreen(wpop)) ;
7500
7501 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7502 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7503
7504 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7505 } else if( im3d->vwid->butx >= 0 && im3d->vwid->buty >= 0 ){
7506 XtVaSetValues( wpop ,
7507 XmNx , im3d->vwid->butx ,
7508 XmNy , im3d->vwid->buty , NULL ) ; /* 17 May 2005 */
7509 }
7510
7511 /*-- popup widgets --*/
7512
7513 XtMapWidget( wpop ) ; /* after this, is up to user */
7514 AFNI_sleep(1) ;
7515 RWC_visibilize_widget( wpop ) ;
7516 }
7517
7518 /*.........................................................*/
7519
7520 else if( w == im3d->vwid->dmode->misc_1dchain_pb ){ /* 07 Aug 2001 */
7521 static PLUGIN_interface *plint=NULL ;
7522 Widget wpop ;
7523
7524 /* first time in: create interface like a plugin */
7525
7526 if( plint == NULL ){
7527 plint = F1D_init() ;
7528 if( plint == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7529 PLUG_setup_widgets( plint , GLOBAL_library.dc ) ;
7530 }
7531
7532 if( cbs == NULL ) EXRETURN ; /* only for a setup call */
7533
7534 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7535
7536 plint->im3d = im3d ;
7537 XtVaSetValues( plint->wid->shell ,
7538 XmNtitle , "AFNI 1DChain Function", /* top of window */
7539 XmNiconName , "1DChain" , /* label on icon */
7540 NULL ) ;
7541 PLUTO_cursorize( plint->wid->shell ) ;
7542
7543 /*-- if possible, find where this popup should go --*/
7544
7545 wpop = plint->wid->shell ;
7546
7547 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7548
7549 XButtonEvent *xev = (XButtonEvent *) cbs->event ;
7550 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7551 int ww,hh , sw,sh ;
7552
7553 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7554 sw = WidthOfScreen (XtScreen(wpop)) ;
7555 sh = HeightOfScreen(XtScreen(wpop)) ;
7556
7557 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7558 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7559
7560 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7561 }
7562
7563 /*-- popup widgets --*/
7564
7565 XtMapWidget( wpop ) ; /* after this, is up to user */
7566 RWC_visibilize_widget( wpop ) ;
7567 }
7568
7569 /*.........................................................*/
7570
7571 else if( w == im3d->vwid->dmode->misc_2dchain_pb ){ /* 20 Jun 2000 */
7572 static PLUGIN_interface *plint=NULL ;
7573 Widget wpop ;
7574
7575 /* first time in: create interface like a plugin */
7576
7577 if( plint == NULL ){
7578 plint = F2D_init() ;
7579 if( plint == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7580 PLUG_setup_widgets( plint , GLOBAL_library.dc ) ;
7581 }
7582
7583 if( cbs == NULL ) EXRETURN ; /* only for a setup call */
7584
7585 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7586
7587 plint->im3d = im3d ;
7588 XtVaSetValues( plint->wid->shell ,
7589 XmNtitle , "AFNI 2DChain Function", /* top of window */
7590 XmNiconName , "2DChain" , /* label on icon */
7591 NULL ) ;
7592 PLUTO_cursorize( plint->wid->shell ) ;
7593
7594 /*-- if possible, find where this popup should go --*/
7595
7596 wpop = plint->wid->shell ;
7597
7598 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7599
7600 XButtonEvent *xev = (XButtonEvent *) cbs->event ;
7601 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7602 int ww,hh , sw,sh ;
7603
7604 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7605 sw = WidthOfScreen (XtScreen(wpop)) ;
7606 sh = HeightOfScreen(XtScreen(wpop)) ;
7607
7608 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7609 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7610
7611 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7612 }
7613
7614 /*-- popup widgets --*/
7615
7616 XtMapWidget( wpop ) ; /* after this, is up to user */
7617 RWC_visibilize_widget( wpop ) ;
7618 }
7619
7620 /*.........................................................*/
7621
7622 else if( w == im3d->vwid->func->icor_pb ){ /* 29 Apr 2009 */
7623 static PLUGIN_interface *plint[MAX_CONTROLLERS] ; static int first=1 ;
7624 Widget wpop ;
7625 char title[64] , *lc=AFNI_controller_label(im3d) ;
7626
7627 if( first ){ /* initialize */
7628 int ii ;
7629 for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ) plint[ii] = NULL ;
7630 first = 0 ;
7631 }
7632
7633 /* first time in for this controller: create interface like a plugin */
7634
7635 if( plint[ic] == NULL ){
7636 plint[ic] = ICOR_init(lc) ;
7637 if( plint[ic] == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7638 PLUG_setup_widgets( plint[ic] , GLOBAL_library.dc ) ;
7639 plint[ic]->im3d = im3d ;
7640 }
7641
7642 if( cbs == NULL ){ /* synthetic call */
7643 XtUnmapWidget(plint[ic]->wid->shell) ; EXRETURN ;
7644 }
7645
7646 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7647
7648 plint[ic]->im3d = im3d ;
7649 sprintf(title,"%sAFNI InstaCorr Setup Operations",lc) ;
7650 XtVaSetValues( plint[ic]->wid->shell ,
7651 XmNtitle , title , /* top of window */
7652 XmNiconName , "InstaCorr" , /* label on icon */
7653 NULL ) ;
7654 PLUTO_cursorize( plint[ic]->wid->shell ) ;
7655
7656 /*-- if possible, find where this popup should go --*/
7657
7658 wpop = plint[ic]->wid->shell ;
7659
7660 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7661
7662 XButtonEvent *xev = (XButtonEvent *)cbs->event ;
7663 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7664 int ww,hh , sw,sh ;
7665
7666 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7667 sw = WidthOfScreen (XtScreen(wpop)) ;
7668 sh = HeightOfScreen(XtScreen(wpop)) ;
7669
7670 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7671 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7672
7673 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7674 }
7675
7676 /*-- popup widgets --*/
7677
7678 XtMapWidget( wpop ) ; /* after this, is up to user */
7679 RWC_visibilize_widget( wpop ) ;
7680 }
7681
7682 /*.........................................................*/
7683
7684 else if( w == im3d->vwid->func->gicor_pb ){ /* 22 Dec 2009 */
7685 static PLUGIN_interface *plint=NULL ;
7686 Widget wpop ;
7687 char title[64] , *lc=AFNI_controller_label(im3d) ;
7688
7689 if( cbs == NULL && plint != NULL ){ /* synthetic call */
7690 XtUnmapWidget(plint->wid->shell) ; EXRETURN ;
7691 }
7692
7693 if( im3d->giset == NULL || !im3d->giset->ready ){
7694 if( cbs != NULL ){
7695 BEEPIT ;
7696 (void) MCW_popup_message( im3d->vwid->func->gicor_pb ,
7697 " \n"
7698 " ***** AFNI: ***** \n"
7699 " 3dGroupInCorr \n"
7700 " isn't connected!! \n " ,
7701 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7702 }
7703 EXRETURN ;
7704 }
7705
7706 /* first time in for this controller: create interface like a plugin */
7707
7708 if( plint == NULL ){
7709 plint = GICOR_init(lc) ;
7710 if( plint == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7711 PLUG_setup_widgets( plint , GLOBAL_library.dc ) ;
7712 plint->im3d = im3d ;
7713 }
7714
7715 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7716
7717 plint->im3d = im3d ;
7718 sprintf(title,"%sAFNI Group InstaCorr Setup",lc) ;
7719 XtVaSetValues( plint->wid->shell ,
7720 XmNtitle , title , /* top of window */
7721 XmNiconName , "GrpInCorr" , /* label on icon */
7722 NULL ) ;
7723 PLUTO_cursorize( plint->wid->shell ) ;
7724
7725 /*-- if possible, find where this popup should go --*/
7726
7727 wpop = plint->wid->shell ;
7728
7729 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7730
7731 XButtonEvent *xev = (XButtonEvent *)cbs->event ;
7732 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7733 int ww,hh , sw,sh ;
7734
7735 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7736 sw = WidthOfScreen (XtScreen(wpop)) ;
7737 sh = HeightOfScreen(XtScreen(wpop)) ;
7738
7739 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7740 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7741
7742 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7743 }
7744
7745 /*-- popup widgets --*/
7746
7747 XtMapWidget( wpop ) ; /* after this, is up to user */
7748 RWC_visibilize_widget( wpop ) ;
7749 }
7750
7751 /*.........................................................*/
7752
7753 else if( w == im3d->vwid->func->icalc_pb ){ /* 18 Sep 2009 */
7754 Widget wtop ;
7755
7756 if( im3d->vwid->func->iwid == NULL ){
7757 ICALC_make_widgets(im3d) ;
7758 if( im3d->vwid->func->iwid == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7759 }
7760
7761 if( im3d->icalc_setup == NULL )
7762 INIT_ICALC_setup(im3d->icalc_setup) ;
7763
7764 if( !im3d->vwid->func->iwid->is_open ) INSTACALC_LABEL_OFF(im3d) ;
7765 im3d->icalc_setup->is_good = 0 ;
7766
7767 wtop = im3d->vwid->func->iwid->wtop ;
7768
7769 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7770 XButtonEvent *xev = (XButtonEvent *)cbs->event ;
7771 int xx=(int)xev->x_root , yy=(int)xev->y_root , ww,hh,sw,sh ;
7772 MCW_widget_geom( wtop , &ww,&hh , NULL,NULL ) ;
7773 sw = WidthOfScreen (XtScreen(wtop)) ;
7774 sh = HeightOfScreen(XtScreen(wtop)) ;
7775 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7776 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7777 XtVaSetValues( wtop , XmNx , xx , XmNy , yy , NULL ) ;
7778 }
7779
7780 XtMapWidget(wtop) ; RWC_visibilize_widget( wtop ) ;
7781 XRaiseWindow( XtDisplay(wtop) , XtWindow(wtop) ) ;
7782 im3d->vwid->func->iwid->is_open = 1 ;
7783 }
7784
7785 /*.........................................................*/
7786
7787 else if( w == im3d->vwid->func->tstat_pb ){ /* 22 Mar 2018 */
7788 static PLUGIN_interface *plint[MAX_CONTROLLERS] ; static int first=1 ;
7789 Widget wpop ;
7790 char title[64] , *lc=AFNI_controller_label(im3d) ;
7791
7792 if( first ){ /* initialize */
7793 int ii ;
7794 for( ii=0 ; ii < MAX_CONTROLLERS ; ii++ ) plint[ii] = NULL ;
7795 first = 0 ;
7796 }
7797
7798 /* first time in for this controller: create interface like a plugin */
7799
7800 if( plint[ic] == NULL ){
7801 plint[ic] = TSTAT_init(lc) ;
7802 if( plint[ic] == NULL ){ BEEPIT; WARNING_message("WTF?!"); EXRETURN; }
7803 PLUG_setup_widgets( plint[ic] , GLOBAL_library.dc ) ;
7804 plint[ic]->im3d = im3d ;
7805 }
7806
7807 if( cbs == NULL ){ /* synthetic call */
7808 XtUnmapWidget(plint[ic]->wid->shell) ; EXRETURN ;
7809 }
7810
7811 /* code below is from PLUG_startup_plugin_CB() in afni_plugin.c */
7812
7813 plint[ic]->im3d = im3d ;
7814 sprintf(title,"%sAFNI Tstat Computations",lc) ;
7815 XtVaSetValues( plint[ic]->wid->shell ,
7816 XmNtitle , title , /* top of window */
7817 XmNiconName , "InstaCorr" , /* label on icon */
7818 NULL ) ;
7819 PLUTO_cursorize( plint[ic]->wid->shell ) ;
7820
7821 /*-- if possible, find where this popup should go --*/
7822
7823 wpop = plint[ic]->wid->shell ;
7824
7825 if( cbs->event != NULL && cbs->event->type == ButtonRelease ){
7826
7827 XButtonEvent *xev = (XButtonEvent *)cbs->event ;
7828 int xx = (int)xev->x_root , yy = (int)xev->y_root ;
7829 int ww,hh , sw,sh ;
7830
7831 MCW_widget_geom( wpop , &ww,&hh , NULL,NULL ) ;
7832 sw = WidthOfScreen (XtScreen(wpop)) ;
7833 sh = HeightOfScreen(XtScreen(wpop)) ;
7834
7835 if( xx+ww+3 >= sw && ww <= sw ) xx = sw-ww ;
7836 if( yy+hh+3 >= sh && hh <= sh ) yy = sh-hh ;
7837
7838 XtVaSetValues( wpop , XmNx , xx , XmNy , yy , NULL ) ;
7839 }
7840
7841 /*-- popup widgets --*/
7842
7843 XtMapWidget( wpop ) ; /* after this, is up to user */
7844 RWC_visibilize_widget( wpop ) ;
7845 }
7846
7847 /*.........................................................*/
7848
7849 else if( w == im3d->vwid->dmode->misc_plugout_pb ){ /* 07 Nov 2001 */
7850 AFNI_init_plugouts() ;
7851 XtSetSensitive(w,False) ;
7852 if( AFNI_have_niml() ) /* 02 Feb 2007 */
7853 XtSetSensitive(im3d->vwid->view->nimlpo_pb,False) ;
7854 }
7855 #endif /* ALLOW_PLUGINS */
7856
7857 else if( w == im3d->vwid->dmode->misc_niml_pb ){ /* 02 Mar 2002 */
7858 AFNI_init_niml() ;
7859 XtSetSensitive(w,False) ;
7860 if( AFNI_have_plugouts() ) /* 02 Feb 2007 */
7861 XtSetSensitive(im3d->vwid->view->nimlpo_pb,False) ;
7862 }
7863
7864 /*.........................................................*/
7865
7866 /****----- Get Outta Here -----****/
7867
7868 EXRETURN ;
7869 }
7870
7871 /*---------------------------------------------------------------*/
7872 /* Find a sub-brick containing a given text in its label */
7873
find_subbrick_with_label(THD_3dim_dataset * dset,char * lstr)7874 int find_subbrick_with_label( THD_3dim_dataset *dset , char *lstr )
7875 {
7876 int iv , nvals ;
7877
7878 if( !ISVALID_DSET(dset) || lstr == NULL || *lstr == '\0' ) return -1 ;
7879
7880 nvals = DSET_NVALS(dset) ;
7881 for( iv=0 ; iv < nvals ; iv++ ){
7882 if( strcasestr( DSET_BRICK_LABEL(dset,iv) , lstr ) != NULL )
7883 return iv ;
7884 }
7885 return -1 ;
7886 }
7887
7888 /*-------- get a pair of indexes for OLay/Thr [11 Jan 2017] --------*/
7889
find_reasonable_overlay_indexes(THD_3dim_dataset * dset)7890 int_pair find_reasonable_overlay_indexes( THD_3dim_dataset *dset )
7891 {
7892 int_pair ovp={-1,-1} ;
7893 int ith, iov ;
7894
7895 if( !ISVALID_DSET(dset) ) return ovp ;
7896
7897 iov = find_subbrick_with_label( dset , "Coef" ) ;
7898 if( iov < 0 )
7899 iov = find_subbrick_with_label( dset , "Beta" ) ;
7900 if( iov >= 0 ){
7901 ovp.i = iov ;
7902 if( iov+1 < DSET_NVALS(dset) ) ovp.j = iov+1 ;
7903 return ovp ;
7904 }
7905
7906 iov = find_subbrick_with_label( dset , "Tstat" ) ;
7907 if( iov < 0 )
7908 iov = find_subbrick_with_label( dset , "Fstat" ) ;
7909 if( iov >= 0 ){
7910 ovp.i = ovp.j = iov ;
7911 return ovp ;
7912 }
7913
7914 return ovp ;
7915 }
7916
7917 /*---------------------------------------------------------------*/
7918
AFNI_editenv_CB(Widget w,XtPointer cd,XtPointer cbd)7919 void AFNI_editenv_CB( Widget w , XtPointer cd , XtPointer cbd )
7920 {
7921 Three_D_View *im3d = (Three_D_View *) cd ;
7922
7923 if( !IM3D_OPEN(im3d) ) return ;
7924 AFNI_misc_CB( im3d->vwid->dmode->misc_environ_pb ,
7925 (XtPointer) im3d , (XtPointer) NULL ) ;
7926 }
7927
7928 #ifdef USE_HIDDEN
7929
7930 /*:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
7931 May 1995: Hidden popup menu stuff
7932 :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::*/
7933
7934 #ifndef ALLOW_PLUGINS
7935 # undef WANT_RWCOX_IMAGE
7936 #endif
7937
7938 #ifdef WANT_RWCOX_IMAGE
7939 void RWCOX_popper(void) ;
7940 #endif
7941
7942 #ifdef USE_SKIT
7943 void SKIT_popper( Three_D_View * ) ;
7944 #endif
7945
7946 static int num_poem = 0 ; /* 15 Oct 2003 */
7947 static char **fname_poem=NULL ;
7948 static void AFNI_find_poem_files(void) ;
7949
7950 #include "uscon.h"
7951
7952 /*---------------------------------------------------------------
7953 Callback for all actions in the hidden popup
7954 -----------------------------------------------------------------*/
7955
AFNI_hidden_CB(Widget w,XtPointer cd,XtPointer cbs)7956 void AFNI_hidden_CB( Widget w , XtPointer cd , XtPointer cbs )
7957 {
7958 Three_D_View *im3d = (Three_D_View *)cd ;
7959
7960 ENTRY("AFNI_hidden_CB") ;
7961
7962 if( ! IM3D_OPEN(im3d) || w == (Widget)NULL ) EXRETURN ;
7963
7964 #ifdef ALLOW_DATASET_VLIST
7965 /****----- Read points -----****/
7966
7967 if( w == im3d->vwid->prog->hidden_readpts_ijk_pb ||
7968 w == im3d->vwid->prog->hidden_readpts_xyz_pb ){
7969
7970 im3d->vwid->prog->hidden_code =
7971 (w == im3d->vwid->prog->hidden_readpts_ijk_pb) ? PTS_READ_IJK
7972 : PTS_READ_XYZ ;
7973
7974 POPDOWN_ovcolor_chooser ;
7975
7976 MCW_choose_string( im3d->vwid->picture ,
7977
7978 (im3d->vwid->prog->hidden_code == PTS_READ_IJK)
7979 ? "Enter IJK input filename:"
7980 : "Enter XYZ input filename:" ,
7981
7982 NULL , AFNI_hidden_pts_CB , cd ) ;
7983 }
7984
7985 /****----- Write points -----****/
7986
7987 else if( w == im3d->vwid->prog->hidden_writepts_ijk_pb ||
7988 w == im3d->vwid->prog->hidden_writepts_xyz_pb ){
7989
7990 if( im3d->anat_now->pts == NULL || im3d->anat_now->pts->num <= 0 ){
7991 (void) MCW_popup_message( im3d->vwid->picture ,
7992 "No points to write out!" ,
7993 MCW_USER_KILL | MCW_TIMER_KILL ) ;
7994 BEEPIT ; EXRETURN ;
7995 }
7996
7997 POPDOWN_ovcolor_chooser ;
7998
7999 im3d->vwid->prog->hidden_code =
8000 (w == im3d->vwid->prog->hidden_writepts_ijk_pb) ? PTS_WRITE_IJK
8001 : PTS_WRITE_XYZ ;
8002
8003 MCW_choose_string( im3d->vwid->picture ,
8004
8005 (im3d->vwid->prog->hidden_code == PTS_WRITE_IJK)
8006 ? "Enter IJK output filename:"
8007 : "Enter XYZ output filename:" ,
8008
8009 NULL , AFNI_hidden_pts_CB , cd ) ;
8010 }
8011
8012 /****----- Show points -----****/
8013
8014 else if( w == im3d->vwid->prog->hidden_colorpts_pb ){
8015
8016 POPDOWN_string_chooser ;
8017
8018 im3d->vwid->prog->hidden_code = PTS_SET_COLOR ;
8019
8020 MCW_choose_ovcolor( im3d->vwid->picture ,
8021 im3d->dc ,
8022 im3d->vinfo->pts_color ,
8023 AFNI_hidden_pts_CB , cd ) ;
8024 }
8025 #endif /* ALLOW_DATASET_VLIST */
8026
8027 /****----- Mission Statement -----****/
8028
8029 if( w == im3d->vwid->prog->hidden_mission_pb ){
8030 (void) MCW_popup_message( im3d->vwid->picture ,
8031 " \n"
8032 " AFNI Mission Statement\n"
8033 " ----------------------\n"
8034 " To empower neuroscientists\n"
8035 " to perform their own state-\n"
8036 " of-the-art data analyses and\n"
8037 " visualizations, so they will \n"
8038 " stop bugging me with their\n"
8039 " pitiful 'quick questions'.\n " ,
8040 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8041 }
8042
8043 else if( w == im3d->vwid->prog->hidden_uscon_pb ){ /* 30 Dec 2010 */
8044 char *inf=NULL ; int ii ;
8045 for( ii=0 ; uscon[ii] != NULL ; ii++ )
8046 inf = THD_zzprintf( inf , " %s" , uscon[ii] ) ;
8047 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
8048 free(inf) ;
8049 }
8050
8051 else if( w == im3d->vwid->prog->hidden_usdecl_pb ){ /* 06 Jan 2011 */
8052 char *inf=NULL ; int ii ;
8053 for( ii=0 ; usdecl[ii] != NULL ; ii++ )
8054 inf = THD_zzprintf( inf , " %s" , usdecl[ii] ) ;
8055 (void) new_MCW_textwin( im3d->vwid->imag->topper , inf , TEXT_READONLY ) ;
8056 free(inf) ;
8057 }
8058
8059 else if( w == im3d->vwid->prog->hidden_melter_pb ){ /* 18 Feb 2011 */
8060 MCW_melt_widget( im3d->vwid->top_form ) ;
8061 if( GLOBAL_library.have_sox && GLOBAL_library.local_display )
8062 AFNI_startup_sound(1) ;
8063 NI_sleep(111) ;
8064 if( GLOBAL_library.have_sox && GLOBAL_library.local_display )
8065 AFNI_startup_sound(1) ;
8066 MCW_set_widget_label(w,"Omega-13 is one use") ; SENSITIZE(w,0) ;
8067 }
8068
8069 else if( w != NULL && w == im3d->vwid->prog->hidden_sound_pb ){ /* 20 Aug 2018 */
8070 if( GLOBAL_library.have_sox && GLOBAL_library.local_display ){
8071 AFNI_startup_sound(1) ;
8072 AFNI_startup_sound(1) ;
8073 } else {
8074 WARNING_message("sound playing not available :(") ;
8075 }
8076 }
8077
8078 else if( w != NULL && w == im3d->vwid->prog->hidden_music_pb ){ /* 07 Aug 2019 */
8079 if( GLOBAL_library.sound_player != NULL && GLOBAL_library.local_display ){
8080 static int ncall=0 ;
8081 int nmusic = (int)AFNI_numenv("AFNI_MUSIC_SIZE") ;
8082 MRI_IMAGE *qim ; float *qar ; int ii ;
8083 if( nmusic < 4 ) nmusic = 321 ;
8084 else if( nmusic > 99999 ) nmusic = 99999 ;
8085 if( ncall == 0 )
8086 ININFO_message("Computing random music notes - about %d seconds worth",
8087 (int)(nmusic*0.095f)) ;
8088 qim = jRandom1D(nmusic,2); qar = MRI_FLOAT_PTR(qim); /* random */
8089 if( nmusic < 99 ) osfilt3_func( 2*nmusic , 0.0,1.0 , qar ); /* smooth */
8090 else adpt_wt_mn9 ( 2*nmusic , 0.0,1.0 , qar );
8091 for( ii=0 ; ii < nmusic ; ii++ ) /* correlate */
8092 qar[ii] += 0.222f * qar[ii+nmusic] ;
8093 mri_sound_play_append( "reverb 99 fade 0 0 2" ); /* sox only */
8094 if( ncall == 0 ) mri_play_sound_notify(1) ; /* only the first time */
8095 mri_play_sound_rate_fac( 1.2468f ) ;
8096 mri_play_sound(qim,0) ; /* let the music sound forth! */
8097 mri_free(qim) ; /* some cleanup */
8098 mri_sound_play_append( NULL ) ;
8099 mri_play_sound_notify(0) ;
8100 mri_play_sound_rate_fac( 1.0f ) ;
8101 ncall++ ;
8102 } else {
8103 WARNING_message("sound playing not available :(") ;
8104 }
8105 }
8106
8107 else if( w == im3d->vwid->prog->hidden_gamberi_pb ){
8108 AFNI_speak( "The Rime of the Gamberi Cattivi" , 0 ) ;
8109 (void) MCW_popup_message( im3d->vwid->imag->topper ,
8110 " \n"
8111 " The Rime of the Ancient Gamberi Cattivi\n"
8112 " (with apologies to Coleridge and Dante)\n"
8113 " -----------------------------------------\n\n"
8114 " Illuminato dal sole toscano,\n"
8115 " volsi lo sguardo all'orizzonte;\n"
8116 " nel mare bagnavo la mano,\n"
8117 " e al cielo volgevo la fronte.\n"
8118 " \n"
8119 " D'improvviso dal mare schiumante,\n"
8120 " due gamberi killer cattivi si avvicinarono.\n"
8121 " Uno stiletto mi poser d'innante,\n"
8122 " mentre i lunghi baffi neri si accarezzavano.\n"
8123 " \n"
8124 " Il piu giovane ordino:\n"
8125 " \"La macchina fotografica dalla giacca sgancia!\"\n"
8126 " mentre la lama premeva forte la guancia.\n"
8127 " Prima di dichiarare \"Del Governo e proprieta,\n"
8128 " sul mio corpo il nemico passar dovra!\",\n"
8129 " il gambero malvagio nella bocca la camera si fionda\n"
8130 " e del Tirreno scuro e profondo ritorna a prender l'onda.\n"
8131 " \n"
8132 " Roberto Cox \"il Magnifico\" di Milwaukee e il dottor Emiliano\n"
8133 " corrono al grido di Ziad, ma e tutto invano.\n"
8134 " \n"
8135 " Ai nostri eroi non resta che accettare l'accaduto,\n"
8136 " e a tutta Italia AFNI e SUMA insegnare.\n"
8137 " Scusateci se lo stile e un po' caduto,\n"
8138 " ma e la scusa per l'anno prossimo a Pisa ritornare.\n" ,
8139 MCW_USER_KILL ) ;
8140 }
8141
8142 else if( w == im3d->vwid->prog->hidden_hbmjust_pb ){
8143 (void)MCW_popup_message( im3d->vwid->imag->topper ,
8144 " Why I Must Attend HBM - RWCox\n"
8145 "---------------------------------\n"
8146 "I have been asked to state\n"
8147 "why HBM is great,\n"
8148 "and why it is a must\n"
8149 "that I incur this cost.\n"
8150 "Brain Mappers all converge\n"
8151 "to show their best new work,\n"
8152 "exactly in my field:\n"
8153 "ways to make data yield\n"
8154 "news about brain function,\n"
8155 "providing a conjunction\n"
8156 "of doers and of thinkers --\n"
8157 "ideal for science drinkers.\n"
8158 "This meet is Number One:\n"
8159 "the best come here to run\n"
8160 "their latest, their greatest\n"
8161 "past the world's most smartest.\n"
8162 "There is where I can see\n"
8163 "what's new and important to me\n"
8164 "in my work for the NIMH\n"
8165 "and to show them my batch\n"
8166 "of newly warped brains\n"
8167 "and how this entrains\n"
8168 "a new way to make\n"
8169 "FMRI a piece of (nonlinear) cake.\n" , MCW_USER_KILL ) ;
8170 }
8171
8172 else if( w == im3d->vwid->prog->hidden_ranpoem_pb ){
8173 static int *dold=NULL, ndold=0 ; int qq,dd ;
8174 char *poem ;
8175
8176 if( num_poem < 0 ) EXRETURN ;
8177 if( num_poem == 0 ){
8178 AFNI_find_poem_files() ;
8179 if( num_poem <= 0 ){ num_poem = -1 ; EXRETURN ; }
8180 }
8181 if( ndold == 0 && num_poem > 1 ){
8182 ndold = num_poem/2 ;
8183 dold = (int *) malloc(sizeof(int)*ndold) ;
8184 for( qq=0 ; qq < ndold ; qq++ ) dold[qq] = -1 ;
8185 }
8186 Retry_dd:
8187 dd = (lrand48() >> 8) % num_poem ; /* pick random file */
8188 if( num_poem > 1 ){ /* check if used recently */
8189 for( qq=0 ; qq < ndold && dold[qq] != dd ; qq++ ) ; /* nada */
8190 if( qq < ndold ) goto Retry_dd ; /* was recent */
8191 for( qq=1 ; qq < ndold ; qq++ ) /* wasn't, so save in list */
8192 dold[qq-1] = dold[qq] ;
8193 dold[ndold-1] = dd ;
8194 }
8195 poem = AFNI_suck_file( fname_poem[dd] ) ;
8196 if( poem == NULL ) EXRETURN ;
8197 (void) MCW_popup_message( im3d->vwid->imag->topper, poem, MCW_USER_KILL );
8198 free( poem ) ;
8199 }
8200
8201 /*------ Faces! [17 Dec 2004] -----*/
8202
8203 else if( w == im3d->vwid->prog->hidden_faces_pb && w != NULL ){
8204
8205 AFNI_faceup() ;
8206 }
8207
8208 /*------ Splashes! [12 Sep 2007] -----*/
8209
8210 else if( w == im3d->vwid->prog->hidden_splashes_pb && w != NULL ){
8211
8212 AFNI_allsplash() ;
8213 }
8214
8215 /*------ Browser [22 Apr 2005] -----*/
8216
8217 else if( w == im3d->vwid->prog->hidden_browser_pb && w != NULL &&
8218 GLOBAL_browser != NULL ){
8219 whereami_browser("https://afni.nimh.nih.gov/afni/doc/program_help/index.html");
8220 #if 0
8221 char cmd[2345] ;
8222 sprintf(cmd ,
8223 "%s https://afni.nimh.nih.gov/afni/doc/program_help/index.html &" ,
8224 GLOBAL_browser ) ;
8225 system(cmd) ;
8226 #endif
8227 }
8228
8229 /*------- random speaking --------*/
8230
8231 else if( w == im3d->vwid->prog->hidden_speech_pb && w != NULL ){
8232 static char *words[] = { "What do you want?" ,
8233 "Nice to see you" ,
8234 "Words fail me now" ,
8235 "I do not know what to say" ,
8236 "How are you feeling?" ,
8237 "Do you like, afnee?" ,
8238 "Do you use ess, pee, emm?" ,
8239 "Do you use eff, ess, ell?" ,
8240 "Exercise your hippocampus daily"
8241 } ;
8242 if( AFNI_noenv("AFNI_SPEECH") )
8243 BEEPIT ;
8244 else {
8245 static int nold=-1 ;
8246 int nn = sizeof(words)/sizeof(char *) , jj ;
8247 do{ jj = lrand48()%nn ; } while( jj == nold ) ;
8248 AFNI_speak( words[jj] , 1 ) ; nold = jj ;
8249 }
8250 }
8251
8252 /****----- Get Outta Here -----****/
8253
8254 EXRETURN ;
8255 }
8256
8257 /*--------------------------------------------------------------------------*/
8258
AFNI_find_poem_files(void)8259 static void AFNI_find_poem_files(void) /* 15 Oct 2003 */
8260 {
8261 char *epath , *elocal , *eee ;
8262 char edir[THD_MAX_NAME] , fdir[THD_MAX_NAME] , *udir , **ename ;
8263 int epos , ll , ii , id , npoem , nep ;
8264 char **fpoem ;
8265
8266 ENTRY("AFNI_find_poem_files") ;
8267
8268 if( num_poem != 0 ) EXRETURN ; /* should never happen */
8269
8270 /*----- get path to search -----*/
8271
8272 epath = getenv("AFNI_PLUGINPATH") ;
8273 if( epath == NULL ) epath = getenv("AFNI_PLUGIN_PATH") ;
8274 if( epath == NULL ) epath = getenv("PATH") ;
8275 if( epath == NULL ){ num_poem=-1; EXRETURN ; }
8276
8277 /*----- copy path list into local memory -----*/
8278
8279 ll = strlen(epath) ;
8280 elocal = AFMALL( char, sizeof(char) * (ll+2) ) ;
8281
8282 /*----- put a blank at the end -----*/
8283
8284 strcpy( elocal , epath ) ; elocal[ll] = ' ' ; elocal[ll+1] = '\0' ;
8285
8286 /*----- replace colons with blanks -----*/
8287
8288 for( ii=0 ; ii < ll ; ii++ )
8289 if( elocal[ii] == ':' ) elocal[ii] = ' ' ;
8290
8291
8292 /*----- extract blank delimited strings;
8293 use as directory names to look for files -----*/
8294
8295 ename = (char **) malloc(sizeof(char *)*2) ;
8296 ename[0] = (char *) malloc(THD_MAX_NAME) ;
8297 ename[1] = (char *) malloc(THD_MAX_NAME) ;
8298
8299 epos = 0 ;
8300
8301 do{
8302 ii = sscanf( elocal+epos , "%s%n" , edir , &id ); /* next substring */
8303 if( ii < 1 ) break ; /* none -> done */
8304
8305 /** check if edir occurs earlier in elocal **/
8306
8307 eee = strstr( elocal , edir ) ;
8308 if( eee != NULL && (eee-elocal) < epos ){ epos += id ; continue ; }
8309
8310 epos += id ; /* char after last scanned */
8311
8312 ii = strlen(edir) ; /* make sure name has */
8313 if( edir[ii-1] != '/' ){ /* a trailing '/' on it */
8314 edir[ii] = '/' ; edir[ii+1] = '\0' ;
8315 }
8316
8317 strcpy(fdir,edir) ; strcat(fdir,"funstuff") ; /* 07 Oct 2011 */
8318 if( THD_is_directory(fdir) ){ strcat(fdir,"/"); udir = fdir; } else { udir = edir; }
8319
8320 strcpy(ename[0],udir) ;
8321 strcat(ename[0],"poem_*.txt") ; /* add filename pattern */
8322 nep = 1 ;
8323
8324 MCW_file_expand( nep,ename, &npoem , &fpoem ); /* find files that match */
8325 if( npoem <= 0 ) continue ; /* no files found */
8326
8327 /** add files we found to list **/
8328
8329 if( fname_poem == NULL )
8330 fname_poem = (char **)malloc(sizeof(char *)*npoem) ;
8331 else
8332 fname_poem = (char **)realloc(fname_poem,sizeof(char *)*(num_poem+npoem));
8333
8334 for( ii=0 ; ii < npoem ; ii++ ){
8335 fname_poem[num_poem++] = strdup(fpoem[ii]) ;
8336
8337 if( udir == fdir ){ /* 07 Oct 2011 */
8338 char qnam[THD_MAX_NAME] ;
8339 strcpy(qnam,edir) ; strcat(qnam,THD_trailname(fpoem[ii],0)) ;
8340 if( THD_is_file(qnam) ) remove(qnam) ;
8341 }
8342 }
8343
8344 MCW_free_expand( npoem , fpoem ) ;
8345
8346 } while( epos < ll ) ; /* scan until 'epos' is after end of epath */
8347
8348 free(elocal) ; free(ename[0]) ; free(ename[1]) ; free(ename) ;
8349
8350 if( num_poem == 0 ) num_poem = -1 ;
8351 EXRETURN ;
8352 }
8353
8354 /*---------------------------------------------------------------------------*/
8355 /* 18 Feb 2014 */
8356
8357 #ifdef USE_SKIT
AFNI_alter_controller_bg(Three_D_View * im3d,float fac)8358 static void AFNI_alter_controller_bg( Three_D_View *im3d , float fac )
8359 {
8360 if( !IM3D_OPEN(im3d) || fac < 0.0f || fac > 2.0f ) return ;
8361 MCW_scale_widget_bg( im3d->vwid->top_form, fac, im3d->dc ) ;
8362 return ;
8363 }
8364 #endif
8365
8366 /*-----------------------------------------------------------------
8367 Event handler to find #3 button press for hidden popup
8368 -------------------------------------------------------------------*/
8369
AFNI_hidden_EV(Widget w,XtPointer cd,XEvent * ev,RwcBoolean * continue_to_dispatch)8370 void AFNI_hidden_EV( Widget w , XtPointer cd ,
8371 XEvent *ev , RwcBoolean *continue_to_dispatch )
8372 {
8373 Three_D_View *im3d = (Three_D_View *) cd ;
8374
8375 ENTRY("AFNI_hidden_EV") ;
8376
8377 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
8378
8379 /*** handle events ***/
8380
8381 switch( ev->type ){
8382
8383 /*----- take button press -----*/
8384
8385 case ButtonPress:{
8386 XButtonEvent *event = (XButtonEvent *) ev ;
8387
8388 if( event->button == Button3 ||
8389 (event->button == Button1 &&
8390 (event->state & (ShiftMask|ControlMask))) ){
8391
8392 im3d->vwid->butx = event->x_root ; /* 17 May 2005 */
8393 im3d->vwid->buty = event->y_root ;
8394 event->button = Button3 ; /* fakeout */
8395 XmMenuPosition( im3d->vwid->prog->hidden_menu , event ) ; /* where */
8396 XtManageChild ( im3d->vwid->prog->hidden_menu ) ; /* popup */
8397 }
8398 #ifdef WANT_RWCOX_IMAGE
8399 else if( !NO_frivolities && event->button == Button1 ) RWCOX_popper() ;
8400 #endif
8401
8402 #ifdef USE_SKIT
8403 else if( !NO_frivolities && event->button == Button2 ) SKIT_popper(im3d) ;
8404 else if( !NO_frivolities && event->button == Button4 ) AFNI_alter_controller_bg(im3d,0.960000f) ;
8405 else if( !NO_frivolities && event->button == Button5 ) AFNI_alter_controller_bg(im3d,1.041667f) ;
8406 #endif
8407 }
8408 break ;
8409
8410 /*----- take key press [09 Sep 2002] -----*/
8411
8412 case KeyPress:{
8413 XKeyEvent *event = (XKeyEvent *) ev ;
8414 char buf[32] ;
8415 KeySym ks ;
8416 int nbuf ;
8417
8418 buf[0] = '\0' ;
8419 nbuf = XLookupString( event , buf , 32 , &ks , NULL ) ;
8420
8421 switch( buf[0] ){
8422 case 'Q':
8423 exit(0) ; /* Death Now! */
8424
8425 case 'q':
8426 AFNI_quit_CB( w , im3d, NULL ) ; /* Close just this controller */
8427 break ;
8428
8429 case 'f':
8430 case 'F':
8431 AFNI_faceup() ; /* Faces! [27 Dec 2004] */
8432 break ;
8433
8434 case 'p':
8435 case 'P':
8436 AFNI_hidden_CB( im3d->vwid->prog->hidden_ranpoem_pb ,
8437 (XtPointer)im3d , NULL ) ;
8438 break ;
8439
8440 case 'g':
8441 case 'G':
8442 AFNI_hidden_CB( im3d->vwid->prog->hidden_gamberi_pb ,
8443 (XtPointer)im3d , NULL ) ;
8444 break ;
8445 }
8446 }
8447 break ;
8448 }
8449
8450 EXRETURN ;
8451 }
8452
8453 /*-------------------------------------------------------------------*/
8454
8455 #ifdef ALLOW_DATASET_VLIST
AFNI_hidden_pts_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)8456 void AFNI_hidden_pts_CB( Widget w , XtPointer cd , MCW_choose_cbs *cbs )
8457 {
8458 Three_D_View *im3d = (Three_D_View *) cd ;
8459 THD_3dim_dataset *dset_now ;
8460 THD_fvec3 xyz_vec ;
8461 THD_ivec3 ijk_vec ;
8462 RwcBoolean ijk_option , pause_it ;
8463 FILE *fil ;
8464 THD_vector_list *sv ;
8465 int ii ;
8466
8467 ENTRY("AFNI_hidden_pts_CB") ;
8468
8469 if( ! IM3D_OPEN(im3d) ) EXRETURN ;
8470 dset_now = im3d->anat_now ;
8471 if( ! ISVALID_3DIM_DATASET(dset_now) ) EXRETURN ;
8472
8473 ijk_option = False ;
8474 switch( im3d->vwid->prog->hidden_code ){ /* action set by user */
8475
8476 /*---- Set Color ----*/
8477
8478 case PTS_SET_COLOR:
8479 im3d->vinfo->pts_color = cbs->ival ;
8480 im3d->vinfo->pts_visible = (cbs->ival > 0) ? True : False ;
8481 AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ; /* redraw */
8482 break ;
8483
8484 /*---- READ pts int ----*/
8485
8486 case PTS_READ_IJK:
8487 ijk_option = True ; /* fall thru on purpose */
8488
8489 case PTS_READ_XYZ:
8490
8491 /** open input file **/
8492
8493 fil = fopen( cbs->cval , "r" ) ;
8494 if( fil == NULL ){
8495 char buf[256] ;
8496 sprintf(buf,"Cannot open file\n %s\nfor reading!",cbs->cval) ;
8497 (void) MCW_popup_message( im3d->vwid->picture , buf ,
8498 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8499 BEEPIT ; EXRETURN ;
8500 }
8501
8502 POPDOWN_string_chooser ;
8503
8504 pause_it = ( THD_filesize(cbs->cval) > 99999 ) ;
8505 if( pause_it ) SHOW_AFNI_PAUSE ;
8506
8507 /** read points **/
8508
8509 INIT_VLIST(sv,dset_now) ;
8510 do {
8511 if( ijk_option )
8512 ii = fscanf( fil , " %d %d %d\n",
8513 &(ijk_vec.ijk[0]),&(ijk_vec.ijk[1]),&(ijk_vec.ijk[2])) ;
8514 else
8515 ii = fscanf( fil , " %f %f %f\n",
8516 &(xyz_vec.xyz[0]),&(xyz_vec.xyz[1]),&(xyz_vec.xyz[2])) ;
8517
8518 if( ii == 3 ){ /* all 3 good! */
8519 if( ijk_option ){ ADD_IVEC_TO_VLIST(sv,ijk_vec) ; }
8520 else { ADD_FVEC_TO_VLIST(sv,xyz_vec) ; }
8521 } else if( ii == EOF ){ /* end of data! */
8522 fclose(fil) ;
8523 break ; /* exit do loop */
8524 } else {
8525 char buf[256] ; /* bad data! */
8526 fclose(fil) ;
8527 sprintf(buf,"Bad read in file\n %s\nat point # %d",
8528 cbs->cval , sv->num + 1 ) ;
8529 (void) MCW_popup_message( im3d->vwid->picture , buf ,
8530 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8531 DESTROY_VLIST(sv) ;
8532 BEEPIT ; EXRETURN ;
8533 }
8534 } while (1) ;
8535
8536 /** destroy any point sets in all current datasets **/
8537
8538 for( ii=0 ; ii <= LAST_VIEW_TYPE ; ii++ ){
8539 if( ISVALID_3DIM_DATASET(im3d->anat_dset[ii]) ){
8540 DESTROY_VLIST( im3d->anat_dset[ii]->pts ) ;
8541 im3d->anat_dset[ii]->pts_original = False ;
8542 }
8543 }
8544
8545 /** put new point set into current dataset **/
8546
8547 dset_now->pts = sv ;
8548 dset_now->pts_original = True ;
8549
8550 AFNI_set_viewpoint( im3d , -1,-1,-1 , REDISPLAY_OVERLAY ) ;
8551 if( pause_it ) SHOW_AFNI_READY ;
8552 break ; /* end of read pts */
8553
8554 /*---- WRITE pts out ----*/
8555
8556 case PTS_WRITE_IJK:
8557 ijk_option = True ; /* fall thru on purpose */
8558
8559 case PTS_WRITE_XYZ:
8560
8561 sv = im3d->anat_now->pts ;
8562 if( sv == NULL || sv->num == 0 ){
8563 BEEPIT ; WARNING_message("Can't write -- no points!") ; EXRETURN ;
8564 }
8565
8566 if( cbs->cval[0] == '|' ){ /* send to standard output */
8567 fil = stdout ;
8568 } else {
8569 if( THD_is_file(cbs->cval) ){
8570 char buf[256] ;
8571 sprintf(buf,"Desired output file\n %s\nalready exists!",cbs->cval);
8572 (void) MCW_popup_message( im3d->vwid->picture , buf ,
8573 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8574 BEEPIT ; EXRETURN ;
8575 }
8576
8577 fil = fopen( cbs->cval , "w" ) ;
8578 if( fil == NULL ){
8579 char buf[256] ;
8580 sprintf(buf,"Cannot open file\n %s\nfor writing!",cbs->cval) ;
8581 (void) MCW_popup_message( im3d->vwid->picture , buf ,
8582 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8583 BEEPIT ; EXRETURN ;
8584 }
8585 }
8586
8587 POPDOWN_string_chooser ;
8588
8589 pause_it = ( sv->num > 6666 ) ;
8590 if( pause_it ) SHOW_AFNI_PAUSE ;
8591
8592 if( ijk_option ){
8593 for( ii=0 ; ii < sv->num ; ii++ )
8594 fprintf(fil,"%d %d %d\n", sv->ijk[ii].ijk[0],
8595 sv->ijk[ii].ijk[1],
8596 sv->ijk[ii].ijk[2] ) ;
8597 } else {
8598 for( ii=0 ; ii < sv->num ; ii++ )
8599 fprintf(fil,"%g %g %g\n", sv->xyz[ii].xyz[0],
8600 sv->xyz[ii].xyz[1],
8601 sv->xyz[ii].xyz[2] ) ;
8602 }
8603
8604 if( fil != stdout ) fclose(fil) ;
8605 if( pause_it ) SHOW_AFNI_READY ;
8606 break ; /* end of write pts */
8607
8608 } /* end of switch */
8609
8610 EXRETURN ;
8611 }
8612 #endif
8613
8614 /*====================================================================================*/
8615 #if defined(WANT_RWCOX_IMAGE) && defined(ALLOW_PLUGINS)
8616
RWCOX_popper(void)8617 void RWCOX_popper(void)
8618 {
8619 AFNI_splashup() ;
8620 return ;
8621 }
8622 #endif /* WANT_RWCOX_IMAGE */
8623 /*====================================================================================*/
8624 #ifdef USE_SKIT
8625 #define NSKIT 50
8626 static char *skit[NSKIT][3] = {
8627 "artless" , "base-court" , "apple-john" ,
8628 "bawdy" , "bat-fowling" , "baggage" ,
8629 "beslubbering" , "beef-witted" , "barnacle" ,
8630 "bootless" , "beetle-headed" , "bladder" ,
8631 "churlish" , "boil-brained" , "boar-pig" ,
8632 "cockered" , "clapper-clawed" , "bugbear" ,
8633 "clouted" , "clay-brained" , "bum-bailey" ,
8634 "craven" , "common-kissing" , "canker-blossom" ,
8635 "currish" , "crook-pated" , "clack-dish" ,
8636 "dankish" , "dismal-dreaming" , "clotpole" ,
8637 "dissembling" , "dizzy-eyed" , "coxcomb" ,
8638 "droning" , "doghearted" , "codpiece" ,
8639 "errant" , "dread-bolted" , "death-token" ,
8640 "fawning" , "earth-vexing" , "dewberry" ,
8641 "fobbing" , "elf-skinned" , "flap-dragon" ,
8642 "froward" , "fat-kidneyed" , "flax-wench" ,
8643 "frothy" , "fen-sucked" , "flirt-gill" ,
8644 "gleeking" , "flap-mouthed" , "foot-licker" ,
8645 "goatish" , "fly-bitten" , "fustilarian" ,
8646 "gorbellied" , "folly-fallen" , "giglet" ,
8647 "impertinent" , "fool-born" , "gudgeon" ,
8648 "infectious" , "full-gorged" , "haggard" ,
8649 "jarring" , "guts-griping" , "harpy" ,
8650 "loggerheaded" , "half-faced" , "hedge-pig" ,
8651 "lumpish" , "hasty-witted" , "horn-beast" ,
8652 "mammering" , "hedge-born" , "hugger-mugger" ,
8653 "mangled" , "hell-hated" , "joithead" ,
8654 "mewling" , "idle-headed" , "lewdster" ,
8655 "paunchy" , "ill-breeding" , "lout" ,
8656 "pribbling" , "ill-nurtured" , "maggot-pie" ,
8657 "puking" , "knotty-pated" , "malt-worm" ,
8658 "puny" , "milk-livered" , "mammet" ,
8659 "qualling" , "motley-minded" , "measle" ,
8660 "rank" , "onion-eyed" , "minnow" ,
8661 "reeky" , "plume-plucked" , "miscreant" ,
8662 "roguish" , "pottle-deep" , "moldwarp" ,
8663 "ruttish" , "pox-marked" , "mumble-news" ,
8664 "saucy" , "reeling-ripe" , "nut-hook" ,
8665 "spleeny" , "rough-hewn" , "pigeon-egg" ,
8666 "spongy" , "rude-growing" , "pignut" ,
8667 "surly" , "rump-fed" , "puttock" ,
8668 "tottering" , "shard-borne" , "pumpion" ,
8669 "unmuzzled" , "sheep-biting" , "ratsbane" ,
8670 "vain" , "spur-galled" , "scut" ,
8671 "venomed" , "swag-bellied" , "skainsmate" ,
8672 "villainous" , "tardy-gaited" , "strumpet" ,
8673 "warped" , "tickle-brained" , "varlet" ,
8674 "wayward" , "toad-spotted" , "vassal" ,
8675 "weedy" , "unchin-snouted" , "whey-face" ,
8676 "yeasty" , "weather-bitten" , "wagtail"
8677 } ;
8678
8679 static char skstr[512] ;
8680
SKIT_popper(Three_D_View * im3d)8681 void SKIT_popper(Three_D_View *im3d)
8682 {
8683 int ii,jj,kk ;
8684
8685 if( !IM3D_OPEN(im3d) ) return ;
8686
8687 ii = lrand48() % NSKIT ; jj = lrand48() % NSKIT ; kk = lrand48() % NSKIT ;
8688 sprintf(skstr,"Randomly generated Shakespearean Insult:\n\n"
8689 " Thou %s %s %s! \n" ,
8690 skit[ii][0] , skit[jj][1] , skit[kk][2] ) ;
8691
8692 if( lrand48()%7 == 0 ){
8693 ii = strlen(skstr) ;
8694 sprintf( skstr+ii , "\n [Data provided by Sandy Kindermann]" ) ;
8695 }
8696
8697 (void) MCW_popup_message( im3d->vwid->picture , skstr ,
8698 MCW_USER_KILL | MCW_TIMER_KILL ) ;
8699 }
8700 #endif /* USE_SKIT */
8701 /*====================================================================================*/
8702
8703 #endif /* USE_HIDDEN */
8704