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 /*------------------------------------------------------------------------*/
8 /* Please note that this file is not "integrated" into AFNI. By this I
9 mean that it doesn't know about AFNI controllers, datasets, and so on.
10 It is a graphing server, and the caller needs to provide a callback
11 function to get data to be graphed, and also provide some other info.
12
13 The exceptions to the "not integrated into AFNI" ukase are the parts
14 of the code inside #ifdef BE_AFNI_AWARE ,,, #endif sections.
15
16 The actual graphs are drawn in function plot_graphs().
17 All the rest of the code is decoration or bureaucracy.
18
19 Note that XDrawLines and XFillPolygon are superseded by
20 function AFNI_XDrawLines and AFNI_XFillPolygon (way down in this file)
21 to provide for upsampling the curves with smoothing. Search below
22 for 'Upsampling' to find where these shenanigans begin.
23 *//*----------------------------------------------------------------------*/
24
25 /*------------------------------------------------------------------------*/
26 /* The AFNI graph viewer is organized much like the image viewer (imseq.c).
27 It gets data and sends info to AFNI via a "callback" function get_ser().
28 It can be driven from outside by calling function drive_MCW_grapher().
29 Much of the early code was adapted from program FD2.c (by myself),
30 which was in turn lifted from program FD.c (by Andrzej Jesmanowicz).
31
32 This history explains why there are 2 different X11 drawing objects:
33 fd_pxWind = a Pixmap, which is a non-visible object into which
34 most of the graphing information is drawn -- the
35 Pixmap is a client-side object, rather than a Window,
36 which is an X11 server-side object. The idea is
37 that drawing into the Pixmap does not require any
38 AFNI-to-X11 communication.
39 draw_fd = a Motif Drawing Area widget, whose Window on the X11
40 server is where the actual display takes place
41 The Pixmap is drawn -- in functions redraw_graph() and plot_graphs() --
42 and then pushed in a single operation to the window via function
43 fd_px_store(). The reason AJ chose for this somewhat clumsy method was
44 speed -- on the slower computers/displays of the early 1990s, redrawing
45 all the graphs just to make a minor change was slow. Instead, the idea
46 was to fix the stuff that doesn't change often, and then re-draw into
47 the window only the overlay stuff that changes more often. Of course,
48 FD and FD2 had a fixed size window, which made this choice more sensible.
49 Now, with faster everything and resizable graph windows, this division
50 of display labor perhaps seems a little silly.
51
52 But I'm not going to re-write it! -- RWCox -- January 2021
53 *//*----------------------------------------------------------------------*/
54
55 /*------------------------------------------------------------------------*/
56 /* Another word of explanation. The FIM menu items in the graph viewer
57 are a legacy of FD2.c -- which was a mashup of the older programs
58 fim.c (functional image map via the correlation method) and FD.c
59 (display of one slice worth of EPI images and graphs). FD2.c allowed
60 for the first time for interactive exploration of FMRI results,
61 albeit in only 2D+time. When I came to add 3D+time data to AFNI (1996),
62 I naturally adapted FD2.c as the starting point for the graph viewer.
63 However, the FIM functions have not be changed or updated in any way
64 for years now -- they still work (I hope), but are not particularly
65 useful, as the FMRI data analysis world has gotten more complicated.
66 But interactive FIM was fun while it lasted. You kids don't know
67 what you are missing.
68 *//*----------------------------------------------------------------------*/
69
70 /*----------------------------------------------------------------------
71 * history:
72 *
73 * 2003 Dec 19 [rickr]
74 * - added Mean and Sigma to bottom of graph window
75 *----------------------------------------------------------------------
76 */
77
78 #undef MAIN
79 #include "afni_graph.h"
80 #include "afni.h"
81 #include <X11/keysym.h> /* 24 Jan 2003 */
82
83 static int show_grapher_pixmap = 1 ;
84 static void fd_line( MCW_grapher *, int,int,int,int ) ;
85 static byte PLOT_FORCE_AUTOSCALE = 1; /* change to 1 [08 Mar 2016 - Okazaki] */
86 static Widget wtemp ;
87
88 #ifdef BE_AFNI_AWARE
89 static AFNI_dataset_choose_stuff cdds = { 0,0, NULL, NULL, NULL } ;
90 static void GRA_finalize_xaxis_dset_CB( Widget w, XtPointer cd, MCW_choose_cbs *cbs ) ;
91 extern void AFNI_choose_dataset_CB ( Widget , XtPointer , XtPointer ) ;
92 extern FD_brick * THD_3dim_dataset_to_brick( THD_3dim_dataset *dset ,
93 int ax_1, int ax_2, int ax_3 ) ;
94 extern MRI_IMAGE * FD_brick_to_series( int , FD_brick * br ) ;
95 #endif
96
97 static int fade_color = 19 ;
98
99 static char *startup_1D_transform = NULL ;
100
101 /*------------------------------------------------------------*/
102 /*! Macro to call the getser function with correct prototype. */
103
104 #undef CALL_getser
105 #define CALL_getser(gr,aa,bb,rtyp,rval) \
106 do{ XtPointer (*gs)(int,int,XtPointer) = \
107 (XtPointer (*)(int,int,XtPointer))(gr->getser) ; \
108 rval = (rtyp) gs(aa,bb,gr->getaux) ; \
109 } while(0)
110
111 /*------------------------------------------------------------*/
112 /*! And to call the send_CB function with a good prototype. */
113
114 #undef CALL_sendback
115 #define CALL_sendback(gr,scb) \
116 do{ void (*sb)(MCW_grapher *,XtPointer,GRA_cbs *) = \
117 (void (*)(MCW_grapher *,XtPointer,GRA_cbs *))(gr->status->send_CB) ; \
118 if( sb != NULL ) sb(gr,gr->getaux,&scb) ; \
119 } while(0)
120
121 #undef BOXOFF
122 #define BOXOFF 9 /* BOX vertical offset (pixels) - for various spacing things */
123
124 /*------------------------------------------------------------*/
125 /*! Create a new MCW_grapher window and structure. */
126
new_MCW_grapher(MCW_DC * dc,get_ptr getser,XtPointer aux)127 MCW_grapher * new_MCW_grapher( MCW_DC *dc , get_ptr getser , XtPointer aux )
128 {
129 int ii ;
130 MCW_grapher *grapher ;
131 static int new_xsize = -1 , new_ysize = -1 ;
132 char *buf , *cpt ;
133 Widget rc_tmp , mb_tmp , form_tmp ; /* 29 Sep 2000 */
134
135 ENTRY("new_MCW_grapher") ;
136
137 grapher = myXtNew( MCW_grapher ) ;
138
139 grapher->type = MCW_GRAPHER_TYPE ;
140 grapher->dc = dc ;
141 grapher->getser = getser ;
142 grapher->getaux = aux ;
143 grapher->parent = NULL ;
144 grapher->valid = 1 ;
145
146 grapher->grid_spacing = 10; /* prevent div by 0, 15 Aug 2008 [rickr] */
147
148 grapher->dont_redraw = 0 ; /* 27 Jan 2004 */
149 grapher->timer_id = 0 ; /* 04 Dec 2003 */
150 grapher->never_drawn = 1 ;
151 grapher->button2_enabled = 0 ; /* Feb 1998 */
152 grapher->mirror = 0 ; /* Jul 2000 */
153
154 grapher->tschosen = 0 ; /* 31 Mar 2004 */
155 grapher->detrend = -1; /* 05 Dec 2012 */
156 grapher->thresh_fade = AFNI_yesenv("AFNI_GRAPH_FADE") ; /* Mar 2013 */
157
158 grapher->gx_max = 0 ;
159 grapher->gy_max = 0 ;
160 grapher->fWIDE = 0 ;
161 grapher->fHIGH = 0 ;
162
163 grapher->glogo_pixmap = XmUNSPECIFIED_PIXMAP ;
164 grapher->glogo_width = grapher->glogo_height = 0 ;
165
166 #if 0
167 grapher->status = (MCW_grapher_status *) getser(0,graCR_getstatus,aux) ;
168 #else
169 CALL_getser( grapher , 0,graCR_getstatus , MCW_grapher_status *,grapher->status ) ;
170 #endif
171
172 if( grapher->status->num_series < 1 ){
173 fprintf(stderr,"*** Attempt to create grapher with < 1 time points! ***\a\n") ;
174 myXtFree(grapher) ;
175 RETURN(NULL) ;
176 }
177
178 GRA_NULL_tuser(grapher) ; /* 22 Apr 1997 */
179
180 /** make shell that holds all **/
181
182 grapher->fdw_graph =
183 XtVaAppCreateShell(
184 "AFNI" , "AFNI" , topLevelShellWidgetClass , dc->display ,
185 XmNminHeight , MIN_XSIZE + GL_DLX + GR_DLX ,
186 XmNmaxHeight , dc->height ,
187 XmNminWidth , MIN_YSIZE + GT_DLY + GB_DLY ,
188 XmNmaxWidth , dc->width ,
189 XmNdeleteResponse , XmDO_NOTHING , /* deletion handled below */
190 XmNallowShellResize , False , /* let code resize shell */
191 XmNinitialResourcesPersistent , False ,
192 XmNkeyboardFocusPolicy , XmEXPLICIT ,
193 NULL ) ;
194
195 DC_yokify( grapher->fdw_graph , dc ) ; /* 14 Sep 1998 */
196
197 /** find initial size of new graphs **/
198
199 if( new_xsize < 0 ){
200 new_xsize = GX_MAX ;
201 #if 0
202 buf = XGetDefault(dc->display,"AFNI","graph_width") ;
203 #else
204 buf = RWC_getname(dc->display,"graph_width") ;
205 #endif
206 if( buf != NULL ){
207 ii = strtol( buf , &cpt , 10 ) ;
208 if( *cpt == '\0' || new_xsize >= MIN_XSIZE ||
209 new_xsize <= dc->width - GL_DLX - GR_DLX )
210 new_xsize = ii ;
211 }
212
213 new_ysize = GY_MAX ;
214 #if 0
215 buf = XGetDefault(dc->display,"AFNI","graph_height") ;
216 #else
217 buf = RWC_getname(dc->display,"graph_height") ;
218 #endif
219 if( buf != NULL ){
220 ii = strtol( buf , &cpt , 10 ) ;
221 if( *cpt == '\0' || new_ysize >= MIN_YSIZE ||
222 new_ysize <= dc->width - GT_DLY - GB_DLY )
223 new_ysize = ii ;
224 }
225 }
226
227 /** 29 Sep 2000: put in a Form to hold everything **/
228
229 form_tmp = XtVaCreateWidget(
230 "dialog" , xmFormWidgetClass , grapher->fdw_graph ,
231 XmNwidth , new_xsize + GL_DLX + GR_DLX ,
232 XmNheight , new_ysize + GT_DLY + GB_DLY ,
233 XmNborderWidth , 0 ,
234 XmNtraversalOn , True ,
235 XmNinitialResourcesPersistent , False ,
236 NULL ) ;
237
238 grapher->top_form = form_tmp ; /* save this [24 May 2018] */
239
240 /** make a drawing area to get everything **/
241
242 grapher->draw_fd =
243 XtVaCreateManagedWidget(
244 "dialog" , xmDrawingAreaWidgetClass , form_tmp ,
245
246 #if 0
247 XmNwidth , new_xsize + GL_DLX + GR_DLX ,
248 XmNheight , new_ysize + GT_DLY + GB_DLY ,
249 #endif
250
251 XmNtopAttachment , XmATTACH_FORM ,
252 XmNleftAttachment , XmATTACH_FORM ,
253 XmNrightAttachment , XmATTACH_FORM ,
254 XmNbottomAttachment , XmATTACH_FORM ,
255
256 XmNmarginWidth , 0 ,
257 XmNmarginHeight , 0 ,
258
259 XmNtraversalOn , True ,
260 XmNinitialResourcesPersistent , False ,
261 NULL ) ;
262
263 XtInsertEventHandler( grapher->draw_fd , /* handle events in graphs */
264
265 0
266 | KeyPressMask /* get keystrokes */
267 | ButtonPressMask /* button presses */
268 | ExposureMask /* exposures */
269 | StructureNotifyMask /* resizes */
270 ,
271 FALSE , /* nonmaskable events? */
272 GRA_drawing_EV , /* super-handler! */
273 (XtPointer) grapher , /* client data */
274 XtListTail ) ; /* last in queue */
275
276 MCW_register_help( grapher->draw_fd ,
277 "Button 1 in a sub-graph --> move it to center\n"
278 "Button 1 in the central --> move time index\n"
279 " sub-graph to closest point\n"
280 " on the graph\n"
281 #if 0
282 "Shift or Ctrl keys with --> single-step time\n"
283 "Button 1 in the central index up or down\n"
284 " sub-graph\n"
285 #endif
286 "\n"
287 "The red dot in the central sub-graph shows\n"
288 "the location of the current time index.\n"
289 "\n"
290 "Button 3 in a sub-graph --> show statistics\n"
291 " of time series\n"
292 "\n"
293 "To turn off the AFNI logo, click Button 1\n"
294 "inside the logo.\n"
295 "\n"
296 "Miscellaneous Keystrokes:\n"
297 "< or [ = move back in time 1 point\n"
298 "> or ] = move forward in time 1 point\n"
299 "1 = move to 1st time point\n"
300 "l = move to last time point\n"
301 "L = turn AFNI logo on/off\n"
302 "F = turn threshold 'Fading' on/off\n"
303 "v/V = Video up/down in time\n"
304 "r/R = Video ricochet up/down in time\n"
305 "p = play sound from central graph\n"
306 "P = play sound from average graph\n"
307 " and central graph (polyphony)\n"
308 "K = kill any running sound player\n"
309 "C = cycle color scheme\n"
310 "s = draw smooth graph curves\n"
311 "^B = cycle thru graph drawing modes\n"
312 "\n"
313 "See the 'Opt' menu for other keypress actions\n"
314 "and for other options to control graph display."
315 ) ;
316
317 /*---------------------------*/
318 /*--- Button 3 popup menu ---*/
319 /*---------------------------*/
320
321 #ifdef BAD_BUTTON3_POPUPS /* 21 Jul 2003 */
322 grapher->but3_menu =
323 XmCreatePopupMenu( form_tmp, "menu" , NULL , 0 ) ;
324 #else
325 grapher->but3_menu =
326 XmCreatePopupMenu( grapher->draw_fd , "menu" , NULL , 0 ) ;
327 #endif
328
329 SAVEUNDERIZE(XtParent(grapher->but3_menu)) ; /* 27 Feb 2001 */
330
331 VISIBILIZE_WHEN_MAPPED(grapher->but3_menu) ;
332 #if 0
333 if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(grapher->but3_menu) ;
334 #endif
335
336 grapher->but3_label =
337 XtVaCreateManagedWidget(
338 "dialog" , xmLabelWidgetClass , grapher->but3_menu ,
339 XmNalignment , XmALIGNMENT_BEGINNING ,
340 XmNtraversalOn , True ,
341 XmNinitialResourcesPersistent , False ,
342 NULL ) ;
343 LABELIZE(grapher->but3_label) ;
344
345 /*-------------------------------------*/
346 /*--- RowColumn to hold all buttons ---*/
347 /*-------------------------------------*/
348
349 grapher->option_rowcol =
350 XtVaCreateWidget(
351 "dialog" , xmRowColumnWidgetClass , form_tmp ,
352 XmNpacking , XmPACK_TIGHT ,
353 XmNorientation , XmHORIZONTAL ,
354 XmNmarginWidth , 0 ,
355 XmNmarginHeight, 0 ,
356 XmNspacing , 2 ,
357 XmNbackground , grapher->dc->ovc->pixov_brightest ,
358 XmNtraversalOn , True ,
359 XmNinitialResourcesPersistent , False ,
360 XmNleftAttachment , XmATTACH_NONE ,
361 XmNtopAttachment , XmATTACH_NONE ,
362 XmNrightAttachment , XmATTACH_FORM ,
363 XmNbottomAttachment , XmATTACH_FORM ,
364 NULL ) ;
365
366 #if 0
367 allow_MCW_optmenu_popup( 0 ) ; /* 12 Dec 2001 */
368 #endif
369
370 /*------------------------*/
371 /*--- FIM Menu Buttons ---*/
372 /*------------------------*/
373
374 /* 29 Sep 2000: move menu buttons each onto private menubars */
375
376 rc_tmp = XtVaCreateWidget(
377 "dialog" , xmRowColumnWidgetClass , grapher->option_rowcol ,
378 XmNorientation , XmHORIZONTAL ,
379 XmNpacking , XmPACK_TIGHT ,
380 XmNmarginWidth , 0 ,
381 XmNmarginHeight, 0 ,
382 XmNspacing , 0 ,
383 XmNbackground , grapher->dc->ovc->pixov_brightest ,
384 XmNtraversalOn , True ,
385 XmNinitialResourcesPersistent , False ,
386 NULL ) ;
387 mb_tmp = XmCreateMenuBar( rc_tmp , "dialog" , NULL,0 ) ;
388 XtVaSetValues( mb_tmp ,
389 XmNmarginWidth , 0 ,
390 XmNmarginHeight , 0 ,
391 XmNspacing , 0 ,
392 XmNborderWidth , 0 ,
393 XmNborderColor , 0 ,
394 XmNtraversalOn , True ,
395 XmNbackground , grapher->dc->ovc->pixov_brightest ,
396 NULL ) ;
397 XtManageChild( mb_tmp ) ;
398
399 grapher->fmenu = AFNI_new_fim_menu( mb_tmp , GRA_fim_CB , 1 ) ;
400 grapher->fmenu->parent = (XtPointer) grapher ;
401 XtManageChild( rc_tmp ) ;
402
403 grapher->polort = 1 ; /* 27 May 1999 */
404
405 /* macros to put double and single separator lines in a menu */
406
407 #define MENU_DLINE(wmenu) \
408 (void) XtVaCreateManagedWidget( \
409 "dialog" , xmSeparatorWidgetClass , grapher -> wmenu , \
410 XmNseparatorType , XmDOUBLE_LINE , NULL )
411
412 #define MENU_SLINE(wmenu) \
413 (void) XtVaCreateManagedWidget( \
414 "dialog" , xmSeparatorWidgetClass , grapher -> wmenu , \
415 XmNseparatorType , XmSINGLE_LINE , NULL )
416
417 /*------------------------*/
418 /*--- Opt Menu Buttons ---*/
419 /*------------------------*/
420
421 /* 29 Sep 2000: move menu buttons each onto private menubars */
422
423 rc_tmp = XtVaCreateWidget(
424 "dialog" , xmRowColumnWidgetClass , grapher->option_rowcol ,
425 XmNorientation , XmHORIZONTAL ,
426 XmNpacking , XmPACK_TIGHT ,
427 XmNmarginWidth , 0 ,
428 XmNmarginHeight, 0 ,
429 XmNspacing , 0 ,
430 XmNbackground , grapher->dc->ovc->pixov_brightest ,
431 XmNtraversalOn , True ,
432 XmNinitialResourcesPersistent , False ,
433 NULL ) ;
434 mb_tmp = XmCreateMenuBar( rc_tmp , "dialog" , NULL,0 ) ;
435 XtVaSetValues( mb_tmp ,
436 XmNmarginWidth , 0 ,
437 XmNmarginHeight , 0 ,
438 XmNspacing , 0 ,
439 XmNborderWidth , 0 ,
440 XmNborderColor , 0 ,
441 XmNtraversalOn , True ,
442 XmNbackground , grapher->dc->ovc->pixov_brightest ,
443 NULL ) ;
444 XtManageChild( mb_tmp ) ;
445
446 grapher->opt_menu = XmCreatePulldownMenu( mb_tmp , "menu" , NULL,0 ) ;
447
448 VISIBILIZE_WHEN_MAPPED(grapher->opt_menu) ; /* 27 Sep 2000 */
449 #if 0
450 if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(grapher->opt_menu) ;
451 #endif
452
453 grapher->opt_cbut =
454 XtVaCreateManagedWidget(
455 "dialog" , xmCascadeButtonWidgetClass , mb_tmp ,
456 LABEL_ARG("Opt") ,
457 XmNsubMenuId , grapher->opt_menu ,
458 XmNmarginWidth , 0 ,
459 XmNmarginHeight , 0 ,
460 XmNmarginBottom , 0 ,
461 XmNmarginTop , 0 ,
462 XmNmarginRight , 0 ,
463 XmNmarginLeft , 0 ,
464 XmNtraversalOn , True ,
465 XmNinitialResourcesPersistent , False ,
466 NULL ) ;
467
468 XtManageChild( rc_tmp ) ;
469
470 MCW_register_hint( grapher->opt_cbut , "Graphing options menu" ) ;
471
472 MCW_register_help( grapher->opt_cbut ,
473 "******** Graph Display Options: ********\n"
474 "\n"
475 "Scale --> Change vertical scaling\n"
476 "Matrix --> Change number of sub-graphs\n"
477 "Grid --> Change number of grid lines;\n"
478 " also can Pin the number of\n"
479 " time points displayed.\n"
480 "Slice --> Change slice number\n"
481 "Colors, Etc --> Change colors of various\n"
482 " parts of the graph window\n"
483 "Baseline --> Display each sub-graph with\n"
484 " its minimum at the bottom of\n"
485 " its window (the default), OR\n"
486 " with the minimum of all sub-\n"
487 " graphs as the common baseline\n"
488 "Show Text? --> Instead of graphs, show the\n"
489 " numerical values of the data\n"
490 " at the current time index\n"
491 " in each sub-graph box\n"
492 "Save PNM --> Save the graph window as an\n"
493 " image to a PNM format file\n"
494 " [or .png or .jpg]\n"
495 "Write Center--> Central voxel timeseries will\n"
496 " be written to a file with a\n"
497 " name like 'X_Y_Z.suffix.1D'\n"
498 " where X,Y,Z are voxel indexes\n"
499 "Tran 0D --> Choose a function to apply to\n"
500 " each point in each timeseries\n"
501 "Tran 1D --> Choose a function to apply to\n"
502 " the timeseries as a whole\n"
503 "Double Plot --> If 'Tran 1D' is active, then\n"
504 " plot the data timeseries AND\n"
505 " the transformed timeseries\n"
506 "Done --> Close this graphing window\n"
507 "\n"
508 "The keystrokes indicated in the menus will\n"
509 "carry out the same functions, if pressed\n"
510 "when the cursor focus is in the graph window.\n"
511 "\n"
512 "N.B.: keystrokes without menu items are:\n"
513 " < --> move time index down by 1\n"
514 " > --> move time index up by 1\n"
515 " 1 --> move to first image (time index 0)\n"
516 " l --> move to last image in time series\n"
517 " L --> turn off the AFNI logo in the corner"
518 ) ;
519
520 /** macro to create a new opt menu button **/
521
522 #define OPT_MENU_BUT(wname,label,hhh) \
523 grapher -> wname = \
524 XtVaCreateManagedWidget( \
525 "dialog" , xmPushButtonWidgetClass , grapher->opt_menu , \
526 LABEL_ARG( label ) , \
527 XmNmarginHeight , 0 , \
528 XmNtraversalOn , True , \
529 XmNinitialResourcesPersistent , False , \
530 NULL ) ; \
531 XtAddCallback( grapher -> wname , XmNactivateCallback , \
532 GRA_opt_CB , (XtPointer) grapher ) ; \
533 MCW_register_hint( grapher -> wname , hhh ) ;
534
535 /** macro to create a new opt pullright menu **/
536 /** 07 Jan 1999: added the mapCallback to fix position **/
537
538 #define OPT_MENU_PULLRIGHT(wmenu,wcbut,label,hhh) \
539 grapher -> wmenu = \
540 XmCreatePulldownMenu( grapher->opt_menu , "menu" , NULL , 0 ) ; \
541 grapher -> wcbut = \
542 XtVaCreateManagedWidget( \
543 "dialog" , xmCascadeButtonWidgetClass , grapher->opt_menu , \
544 LABEL_ARG( label ) , \
545 XmNsubMenuId , grapher -> wmenu , \
546 XmNtraversalOn , True , \
547 XmNinitialResourcesPersistent , False , \
548 NULL ) ; \
549 MCW_register_hint( grapher -> wcbut , hhh ) ; \
550 XtAddCallback( grapher -> wmenu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ;
551
552 /** macro to create a new button on a pullright menu **/
553
554 #define OPT_MENU_PULL_BUT(wmenu,wname,label,hhh) \
555 grapher -> wname = \
556 XtVaCreateManagedWidget( \
557 "dialog" , xmPushButtonWidgetClass , grapher -> wmenu , \
558 LABEL_ARG( label ) , \
559 XmNmarginHeight , 0 , \
560 XmNtraversalOn , True , \
561 XmNinitialResourcesPersistent , False , \
562 NULL ) ; \
563 XtAddCallback( grapher -> wname , XmNactivateCallback , \
564 GRA_opt_CB , (XtPointer) grapher ) ; \
565 MCW_register_hint( grapher -> wname , hhh ) ;
566
567 #ifdef USE_OPTMENUS
568 /** macro to create an option menu on a pullright menu
569 (this menu must be fixed up later in GRA_fix_optmenus) **/
570
571 #define OPT_MENU_OPTMENU(wmenu,wname,label,cb,hhh) \
572 grapher -> wname = \
573 new_MCW_optmenu( grapher -> wmenu , label , 0,1,0,0 , \
574 cb , (XtPointer) grapher , NULL , NULL ) ; \
575 MCW_reghint_children( grapher -> wname -> wrowcol , hhh ) ;
576
577 #endif /* USE_OPTMENUS */
578
579 /*** top of menu = a label to click on that does nothing at all ***/
580
581 #ifdef USING_LESSTIF
582 /* Using xmLabelWidgetClass causes X11 to hang until
583 afni is terminated. The hangup occurs after an option
584 button, like:
585 ignore --> |-3|
586 is set and then -- Cancel -- is clicked upon.
587 Also, it seems that the hangup does not occur unless we have:
588 an 'option menu' inside a 'pulldown menu' which is in
589 another 'pulldown menu' !
590
591 So, not all Cancel LabelWidgets will be modified.
592
593 LessTif patrol Jan. 07 09 */
594 (void) XtVaCreateManagedWidget(
595 "dialog" , xmPushButtonWidgetClass , grapher->opt_menu ,
596 LABEL_ARG("--- Cancel ---") ,
597 XmNrecomputeSize , False ,
598 XmNinitialResourcesPersistent , False ,
599 NULL ) ;
600 #else
601 wtemp = XtVaCreateManagedWidget(
602 "dialog" , xmLabelWidgetClass , grapher->opt_menu ,
603 LABEL_ARG("--- Cancel ---") ,
604 XmNrecomputeSize , False ,
605 XmNinitialResourcesPersistent , False ,
606 NULL ) ; LABELIZE(wtemp) ;
607 #endif
608
609 MENU_SLINE(opt_menu) ;
610 OPT_MENU_BUT(opt_pin_choose_pb ,"Index Pin/Stride" , "Fix index range of graph window" ) ;
611
612 MENU_SLINE(opt_menu) ;
613
614 OPT_MENU_PULLRIGHT(opt_scale_menu,opt_scale_cbut ,"Scale" ,"Change vertical scale" );
615 OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_down_pb ,"Down [-]","Shrink graph heights" );
616 OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_up_pb ,"Up [+]","Increase graph heights");
617 OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_choose_pb,"Choose" ,"Set vertical scale" );
618 OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_auto_pb ,"Auto [a]","Scale automatically" );
619 OPT_MENU_PULL_BUT(opt_scale_menu,opt_scale_AUTO_pb ,"AUTO [A]","Always autoscale" );
620
621 OPT_MENU_PULLRIGHT(opt_mat_menu,opt_mat_cbut ,"Matrix" , "Change number of graphs" ) ;
622 OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_down_pb ,"Down [m]", "Reduce number of graphs" ) ;
623 OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_up_pb ,"Up [M]", "Increase number of graphs" ) ;
624 #ifdef USE_OPTMENUS
625 OPT_MENU_OPTMENU( opt_mat_menu,opt_mat_choose_av , "# " , GRA_mat_choose_CB , "Set number of graphs" ) ;
626 #else
627 OPT_MENU_PULL_BUT( opt_mat_menu,opt_mat_choose_pb ,"Choose" , "Set number of graphs" ) ;
628 #endif
629
630 OPT_MENU_PULLRIGHT(opt_grid_menu,opt_grid_cbut ,"Grid" , "Change vertical grid spacing" ) ;
631 OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_down_pb ,"Down [g]", "Reduce vertical grid spacing" ) ;
632 OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_up_pb ,"Up [G]", "Increase vertical grid spacing" ) ;
633 OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_auto_pb ,"AutoGrid", "Set grid spacing automatically" ) ;
634 OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_choose_pb,"Choose" , "Set vertical grid spacing" ) ;
635 OPT_MENU_PULL_BUT( opt_grid_menu,opt_grid_HorZ_pb ,"HorZ [h]", "Horizontal line at Zero" ) ; /* 05 Jan 1999 */
636
637 OPT_MENU_PULLRIGHT(opt_slice_menu,opt_slice_cbut ,"Slice" , "Change slice" ) ;
638 OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_down_pb ,"Down [z]", "Decrement slice" ) ;
639 OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_up_pb ,"Up [Z]", "Increment slice" ) ;
640 #ifdef USE_OPTMENUS
641 OPT_MENU_OPTMENU( opt_slice_menu,opt_slice_choose_av , "# " , GRA_slice_choose_CB , "Set slice" ) ;
642 #else
643 OPT_MENU_PULL_BUT( opt_slice_menu,opt_slice_choose_pb ,"Choose" , "Set slice" ) ;
644 #endif
645
646 /***** 16 June 1997: Colors submenu *****/
647
648 { static char *bbox_label[1] = { "Use Thick Lines" } ;
649 static char *pts_label[6] = { "Graph Points" ,
650 "Points+Lines" ,
651 "Boxes [B]" ,
652 "Box+LabelUp" ,
653 "Box+LabelTop" ,
654 "Box+LabelDown" } ;
655 char toplabel[64] ;
656 XmString xstr ;
657
658 OPT_MENU_PULLRIGHT(opt_colors_menu,opt_colors_cbut,"Colors, Etc.","Change graph appearance");
659
660 if( strlen(grapher->status->namecode) > 0 ){
661
662 sprintf( toplabel , "--- %s ---" , grapher->status->namecode ) ;
663 xstr = XmStringCreateLtoR( toplabel , XmFONTLIST_DEFAULT_TAG ) ;
664
665 #ifdef USING_LESSTIF
666
667 /* Using xmLabelWidgetClass causes X11 to hang until
668 afni is terminated. For details, see preceding comment.
669 for another --- Cancel --- button.
670
671 LessTif patrol Jan. 07 09 */
672 (void) XtVaCreateManagedWidget(
673 "dialog" , xmPushButtonWidgetClass , grapher->opt_colors_menu ,
674 XmNlabelString , xstr ,
675 XmNrecomputeSize , False ,
676 XmNinitialResourcesPersistent , False ,
677 NULL ) ;
678 #else
679 wtemp = XtVaCreateManagedWidget(
680 "dialog" , xmLabelWidgetClass , grapher->opt_colors_menu ,
681 XmNlabelString , xstr ,
682 XmNrecomputeSize , False ,
683 XmNinitialResourcesPersistent , False ,
684 NULL ) ; LABELIZE(wtemp) ;
685 #endif
686 XmStringFree( xstr ) ;
687
688 MENU_DLINE(opt_colors_menu) ;
689 }
690
691 if( gr_setup_default ){
692 gr_color_default[0] = INIT_GR_boxes_color ;
693 gr_color_default[1] = INIT_GR_backg_color ;
694 gr_color_default[2] = INIT_GR_grid_color ;
695 gr_color_default[3] = INIT_GR_text_color ;
696 gr_color_default[4] = INIT_GR_data_color ;
697 gr_color_default[5] = INIT_GR_ideal_color ;
698 gr_color_default[6] = INIT_GR_ort_color ;
699 gr_color_default[7] = INIT_GR_ignore_color ;
700 gr_color_default[8] = INIT_GR_dplot_color ;
701 gr_color_default[9] = INIT_GR_pmplot_color ;
702
703 gr_thick_default[0] = INIT_GR_boxes_thick ;
704 gr_thick_default[1] = -1 ;
705 gr_thick_default[2] = INIT_GR_grid_thick ;
706 gr_thick_default[3] = -1 ;
707 gr_thick_default[4] = INIT_GR_data_thick ;
708 gr_thick_default[5] = INIT_GR_ideal_thick ;
709 gr_thick_default[6] = INIT_GR_ort_thick ;
710 gr_thick_default[7] = -1 ;
711 gr_thick_default[8] = INIT_GR_dplot_thick ;
712 gr_thick_default[9] = INIT_GR_pmplot_thick ;
713
714 gr_setup_default = 0 ;
715 }
716
717 grapher->fixed_colors_setting = 0 ; /* 16 Apr 2019 */
718
719 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
720
721 grapher->color_index[ii] = GRA_COLOR(gr_color_default[ii]) ;
722 grapher->thick_index[ii] = gr_thick_default[ii] ;
723 grapher->points_index[ii]= gr_points_default[ii] ; /* 09 Jan 1998 */
724
725 grapher->opt_color_av[ii] =
726 new_MCW_colormenu( grapher->opt_colors_menu ,
727 gr_color_label[ii] ,
728 grapher->dc ,
729 gr_color_start[ii] , grapher->dc->ovc->ncol_ov-1,
730 grapher->color_index[ii] ,
731 GRA_color_CB , (XtPointer) grapher ) ;
732 MCW_reghint_children( grapher->opt_color_av[ii]->wrowcol ,
733 gr_color_hint[ii] ) ; /* 28 Jan 2004 */
734
735 if( grapher->thick_index[ii] >= 0 ){
736 grapher->opt_thick_bbox[ii] =
737 new_MCW_bbox( grapher->opt_colors_menu ,
738 1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
739 GRA_thick_CB , (XtPointer) grapher ) ;
740 MCW_reghint_children( grapher->opt_thick_bbox[ii]->wrowcol ,
741 "Draw these lines thicker" ) ;
742
743 if( grapher->thick_index[ii] )
744 MCW_set_bbox( grapher->opt_thick_bbox[ii] , 1 ) ;
745 } else {
746 grapher->opt_thick_bbox[ii] = NULL ;
747 }
748
749 /* 09 Jan 1998: add option to draw only points in graphs */
750 /* 01 Aug 1998: allow points+lines to be drawn as well */
751
752 if( grapher->points_index[ii] >= 0 && ii != PMPLOT_INDEX ){
753 int nbut = (ii==4) ? 6 : 2 ;
754 grapher->opt_points_bbox[ii] =
755 new_MCW_bbox( grapher->opt_colors_menu ,
756 nbut , pts_label , MCW_BB_radio_zero , MCW_BB_noframe ,
757 GRA_thick_CB , (XtPointer) grapher ) ;
758 MCW_reghint_children( grapher->opt_points_bbox[ii]->wrowcol ,
759 "How to plot graph data" ) ;
760
761 if( grapher->points_index[ii] )
762 MCW_set_bbox( grapher->opt_points_bbox[ii] ,
763 1 << (grapher->points_index[ii]-1) ) ;
764 } else {
765 grapher->opt_points_bbox[ii] = NULL ;
766 }
767
768 /* 01 Jun 2020: special case for PMPLOT */
769
770 if( ii == PMPLOT_INDEX ){
771 static char *pm_label[4] = { "Off" , "Curves" , "Bars" , "Fill" } ;
772 grapher->opt_points_bbox[ii] =
773 new_MCW_bbox( grapher->opt_colors_menu ,
774 4 , pm_label , MCW_BB_radio_one , MCW_BB_noframe ,
775 GRA_thick_CB , (XtPointer) grapher ) ;
776 MCW_reghint_children( grapher->opt_points_bbox[ii]->wrowcol ,
777 "If & How to plot Dplot as Plus/Minus" ) ;
778 MCW_set_bbox( grapher->opt_points_bbox[ii] , 1 ) ; /* Off */
779 grapher->points_index[ii] = 0 ;
780 }
781
782 MENU_DLINE( opt_colors_menu ) ;
783 }
784
785 /* 12 Jan 1998: control gap between graphs */
786
787 grapher->opt_ggap_av =
788 new_MCW_optmenu( grapher->opt_colors_menu , "Graph Gap" ,
789 0 , 19 , INIT_GR_ggap , 0 ,
790 GRA_ggap_CB , (XtPointer) grapher , NULL , NULL ) ;
791 AVOPT_columnize( grapher->opt_ggap_av , 4 ) ;
792 MCW_reghint_children( grapher->opt_ggap_av->wrowcol ,
793 "Space sub-graphs apart" ) ;
794
795 /* 06 Oct 2004: control 'thick' line size */
796
797 grapher->opt_gthick_av =
798 new_MCW_optmenu( grapher->opt_colors_menu , "'Thick' " ,
799 2 , 10 , INIT_GR_gthick , 0 ,
800 GRA_gthick_CB , (XtPointer) grapher , NULL , NULL ) ;
801 AVOPT_columnize( grapher->opt_gthick_av , 2 ) ;
802 MCW_reghint_children( grapher->opt_gthick_av->wrowcol ,
803 "Width of 'Thick' lines" ) ;
804
805 /* 28 May 2020: control upsampling for smoother curves */
806
807 { static char *strlist[2] = { "No" , "Yes" } ;
808 grapher->opt_upsam_av =
809 new_MCW_optmenu( grapher->opt_colors_menu , "Smooth? " ,
810 0 , 1 , 0 , 0 ,
811 GRA_upsam_CB , (XtPointer)grapher ,
812 MCW_av_substring_CB , strlist ) ;
813 AVOPT_columnize( grapher->opt_gthick_av , 2 ) ;
814 MCW_reghint_children( grapher->opt_upsam_av->wrowcol ,
815 "Draw smoother curves?" ) ;
816 grapher->do_upsam = 0 ;
817 }
818
819 }
820 /***** end colors submenu creation *****/
821
822 #if 0
823 OPT_MENU_BUT(opt_color_up_pb ,"Grid Color [r]" , "Rotate grid color" ) ;
824 #endif
825
826 /*-- 07 Aug 2001: Baseline sub-menu creation --*/
827
828 { char * bbox_label[3] = { "Individual [b]" ,
829 "Common [b]" ,
830 "Global [b]" } ;
831 XmString xstr ;
832 char gbuf[32] ; /* 08 Mar 2002 */
833
834 /* 08 Mar 2002: set baseline parameters from environment variables */
835
836 cpt = getenv( "AFNI_GRAPH_GLOBALBASE" ) ;
837 if( cpt != NULL )
838 grapher->global_base = strtod( cpt , NULL ) ;
839 else
840 grapher->global_base = 0.0 ;
841
842 cpt = getenv( "AFNI_GRAPH_BASELINE" ) ;
843 if( cpt != NULL ){
844 switch( *cpt ){
845 default: grapher->common_base = BASELINE_INDIVIDUAL ; break ;
846
847 case 'C':
848 case 'c': grapher->common_base = BASELINE_COMMON ; break ;
849
850 case 'G':
851 case 'g': grapher->common_base = BASELINE_GLOBAL ; break ;
852 }
853 } else {
854 grapher->common_base = BASELINE_INDIVIDUAL ;
855 }
856
857 /*- now create menu items -*/
858
859 OPT_MENU_PULLRIGHT(opt_baseline_menu,opt_baseline_cbut,
860 "Baseline","Change sub-graphs baseline");
861
862 grapher->opt_baseline_bbox =
863 new_MCW_bbox( grapher->opt_baseline_menu ,
864 3 , bbox_label , MCW_BB_radio_one , MCW_BB_noframe ,
865 GRA_baseline_CB , (XtPointer)grapher ) ;
866 MCW_set_bbox( grapher->opt_baseline_bbox , grapher->common_base ) ;
867
868 MCW_reghint_children( grapher->opt_baseline_bbox->wrowcol ,
869 "Graph baseline methods" ) ;
870
871 MENU_SLINE( opt_baseline_menu ) ;
872
873 OPT_MENU_PULL_BUT( opt_baseline_menu,opt_baseline_setglobal_pb ,
874 "Set Global" , "Global baseline level" ) ;
875
876 MENU_SLINE( opt_baseline_menu ) ;
877
878 strcpy(gbuf,"Global:") ;
879 AV_fval_to_char(grapher->global_base,gbuf+7) ;
880 xstr = XmStringCreateLtoR(gbuf,XmFONTLIST_DEFAULT_TAG) ;
881 grapher->opt_baseline_global_label =
882 XtVaCreateManagedWidget(
883 "dialog" , xmLabelWidgetClass , grapher->opt_baseline_menu ,
884 XmNlabelString , xstr ,
885 XmNrecomputeSize , False ,
886 XmNtraversalOn , True ,
887 XmNinitialResourcesPersistent , False ,
888 NULL ) ;
889 XmStringFree( xstr ) ; LABELIZE(grapher->opt_baseline_global_label) ;
890 }
891
892 /*----- 22 Sep 2000: Text toggle -----*/
893
894 { static char *bbox_label[1] = { "Show Text? [t]" } ;
895
896 grapher->opt_textgraph_bbox =
897 new_MCW_bbox( grapher->opt_menu ,
898 1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
899 GRA_textgraph_CB , (XtPointer)grapher ) ;
900
901 MCW_reghint_children( grapher->opt_textgraph_bbox->wrowcol ,
902 "Display text, not graphs" ) ;
903
904 grapher->textgraph = 0 ;
905 }
906
907 /*----- Mar 2013: thresh fade toggle -----*/
908
909 { static char *bbox_label[1] = { "Thresh Fade? [F]" } ;
910
911 grapher->opt_tfade_bbox =
912 new_MCW_bbox( grapher->opt_menu ,
913 1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
914 GRA_tfade_CB , (XtPointer)grapher ) ;
915
916 MCW_set_bbox( grapher->opt_tfade_bbox , grapher->thresh_fade ) ;
917
918 MCW_reghint_children( grapher->opt_tfade_bbox->wrowcol ,
919 "Fade out below-threshold voxel sub-graphs" ) ;
920 }
921
922 MENU_SLINE(opt_menu) ;
923 OPT_MENU_BUT(opt_save_pb ,"Save Image [S]" , "Save graph as an image" ) ;
924
925 MENU_SLINE(opt_menu) ;
926 OPT_MENU_BUT(opt_write_center_pb ,"Write Center [w]" , "Write central graph as a *.1D file" ) ;
927 OPT_MENU_BUT(opt_write_suffix_pb ,"Set 'w' Suffix" , "Set suffix for graph writing" ) ;
928
929 /*-------------------------------------------*/
930 /*--- Arrowval to list 0D transformations ---*/
931 /*-------------------------------------------*/
932
933 #define COLSIZE AV_colsize()
934
935 if( grapher->status->transforms0D != NULL &&
936 grapher->status->transforms0D->num > 0 ){ /* 22 Oct 1996 */
937
938 MENU_DLINE(opt_menu) ;
939
940 grapher->transform0D_av =
941 new_MCW_optmenu( grapher->opt_menu ,
942 "Tran 0D" ,
943 0 , grapher->status->transforms0D->num , 0 , 0 ,
944 GRA_transform_CB , (XtPointer) grapher ,
945 GRA_transform_label , (XtPointer) grapher->status->transforms0D ) ;
946
947 if( grapher->status->transforms0D->num >= COLSIZE )
948 AVOPT_columnize( grapher->transform0D_av ,
949 (grapher->status->transforms0D->num/COLSIZE)+1 ) ;
950
951 MCW_reghint_children( grapher->transform0D_av->wrowcol ,
952 "Pointwise data transformations" ) ;
953
954 } else {
955 grapher->transform0D_av = NULL ;
956 }
957 grapher->transform0D_func = NULL ; /* no function to start with */
958 grapher->transform0D_index = 0 ;
959
960 /*-------------------------------------------*/
961 /*--- Arrowval to list 1D transformations ---*/
962 /*-------------------------------------------*/
963
964 if( grapher->status->transforms1D != NULL &&
965 grapher->status->transforms1D->num > 0 ){ /* 03 Nov 1996 */
966
967 MENU_DLINE(opt_menu) ;
968
969 grapher->transform1D_av =
970 new_MCW_optmenu( grapher->opt_menu ,
971 "Tran 1D" ,
972 0 , grapher->status->transforms1D->num , 0 , 0 ,
973 GRA_transform_CB , (XtPointer) grapher ,
974 GRA_transform_label ,
975 (XtPointer) grapher->status->transforms1D ) ;
976
977 /* force the optmenu to call us even if the same button is chosen twice */
978 grapher->transform1D_av->optmenu_call_if_unchanged = 1 ; /* 10 Oct 2007 */
979
980 if( grapher->status->transforms1D->num >= COLSIZE )
981 AVOPT_columnize( grapher->transform1D_av ,
982 (grapher->status->transforms1D->num/COLSIZE)+1 ) ;
983
984 MCW_reghint_children( grapher->transform1D_av->wrowcol ,
985 "Time series transformations" ) ;
986
987 /* 08 Nov 1996: dplot = double plot */
988
989 { char *bbox_label[2] = { "DPlot Off" , "Dplot On" } ;
990
991 OPT_MENU_PULLRIGHT(opt_dplot_menu,opt_dplot_cbut,
992 "Double Plot","Graph Dataset and Tran 1D?");
993
994 grapher->opt_dplot_bbox =
995 new_MCW_bbox( grapher->opt_dplot_menu ,
996 2 , bbox_label , MCW_BB_radio_one , MCW_BB_noframe ,
997 GRA_dplot_change_CB , (XtPointer)grapher ) ;
998 MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OFF ) ;
999
1000 MCW_reghint_children( grapher->opt_dplot_bbox->wrowcol ,
1001 "Show 'Double Plot' graphs?" ) ;
1002 }
1003
1004 } else {
1005 grapher->transform1D_av = NULL ;
1006 grapher->opt_dplot_bbox = NULL ;
1007 }
1008 grapher->transform1D_func = NULL ; /* no function to start with */
1009 grapher->transform1D_index = 0 ;
1010
1011 /*------ optmenu for Polort [05 Dec 2012] ------*/
1012
1013 MENU_DLINE(opt_menu) ;
1014
1015 grapher->detrend_av =
1016 new_MCW_optmenu( grapher->opt_menu ,
1017 "Detrend" ,
1018 -1 , GRA_MAX_DETREND , -1 , 0 ,
1019 GRA_detrend_CB , (XtPointer)grapher ,
1020 NULL , NULL ) ;
1021
1022 MCW_reghint_children( grapher->detrend_av->wrowcol ,
1023 "Order of time series L1 detrending / baseline removal" ) ;
1024
1025 /*------ menu to control the x-axis drawing (09 Jan 1998) ------*/
1026
1027 MENU_DLINE(opt_menu) ;
1028
1029 OPT_MENU_PULLRIGHT( opt_xaxis_menu , opt_xaxis_cbut , "X-axis" , "Alter x-axis" ) ;
1030 OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_pick_pb ,
1031 "X-axis=1D file" , "Set timeseries for x-axis" ) ;
1032 #ifdef BE_AFNI_AWARE
1033 OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_dset_pb ,
1034 "X-axis=dataset" , "Set timeseries for x-axis" ) ;
1035 #else
1036 opt_xaxis_dset_pb = NULL ;
1037 #endif
1038 OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_center_pb ,
1039 "X-axis=center" , "X-axis = center voxel" ) ;
1040 OPT_MENU_PULL_BUT( opt_xaxis_menu , opt_xaxis_clear_pb ,
1041 "Clear X-axis" , "Clear X-axis timeseries" ) ;
1042
1043 /*------ last button on this menu ------*/
1044
1045 MENU_DLINE(opt_menu) ;
1046 OPT_MENU_BUT(opt_quit_pb ,"Done [q]" , "Close window" ) ;
1047 MCW_set_widget_bg( grapher->opt_quit_pb ,
1048 MCW_hotcolor(grapher->opt_quit_pb) , 0 ) ;
1049
1050 /** done with option buttons -- manage the manager widget **/
1051
1052 XtManageChild( grapher->option_rowcol ) ;
1053
1054 #if 0
1055 allow_MCW_optmenu_popup( 1 ) ; /* 12 Dec 2001 */
1056 #endif
1057
1058 /** initialize the internal parameters **/
1059
1060 if(PRINT_TRACING)
1061 { char str[128] ;
1062 sprintf(str,"STATUS: num_series=%d nx=%d ny=%d",
1063 grapher->status->num_series,grapher->status->nx,grapher->status->ny ) ;
1064 STATUS(str) ; }
1065
1066 grapher->fscale = 0 ;
1067 grapher->mat = 0 ;
1068 grapher->xpoint = -1 ;
1069 grapher->ypoint = -1 ;
1070 grapher->zpoint = -1 ;
1071 #if 0
1072 grapher->grid_color = GRID_COLOR(grapher) ;
1073 #endif
1074 grapher->grid_index = -1 ;
1075 grapher->grid_fixed = 0 ; /* 02 Apr 2004 */
1076 grapher->key_Nlock = 0 ;
1077 grapher->xFD = 0 ;
1078 grapher->yFD = 0 ;
1079 grapher->time_index = 0 ;
1080 grapher->pin_top = 0 ; /* 27 Apr 1997 */
1081 grapher->pin_bot = 0 ; /* 17 Mar 2004 */
1082 grapher->pin_stride = 1 ; /* 19 Jul 2013 */
1083 grapher->ggap = INIT_GR_ggap ; /* 12 Jan 1998 + 27 May 1999 */
1084 grapher->gthick = INIT_GR_gthick ; /* 06 Oct 2004 */
1085
1086 grapher->cen_line = NULL ; /* coords of central graph plot */
1087 grapher->ncen_line = 0 ;
1088 grapher->nncen = 0 ;
1089 grapher->cen_tsim = NULL ;
1090 grapher->xax_tsim = NULL ; /* 09 Jan 1998 */
1091 grapher->xax_dset = NULL ; /* 09 Feb 2015 */
1092 grapher->xax_fdbr = NULL ;
1093 grapher->ave_tsim = NULL ; /* 27 Jan 2004 */
1094 grapher->xax_cen = NULL ; /* 12 Feb 2015 */
1095
1096 grapher->xx_text_1 =
1097 grapher->xx_text_2 =
1098 grapher->xx_text_2p = grapher->xx_text_3 = grapher->xx_text_igf = 1 ;
1099
1100 grapher->ref_ts = NULL ;
1101 grapher->ort_ts = NULL ;
1102
1103 grapher->ref_ts_plotall = grapher->ort_ts_plotall = 1 ;
1104
1105 init_const( grapher ) ;
1106
1107 grapher->setshift_inc_av = NULL ;
1108 grapher->setshift_left_av = NULL ;
1109 grapher->setshift_right_av = NULL ;
1110 grapher->dialog = NULL ;
1111 grapher->setshift_inc = 0.5 ;
1112 grapher->setshift_left = 0 ;
1113 grapher->setshift_right = 0 ;
1114
1115 /** for the present, don't realize widgets (make the user do it later) **/
1116
1117 XtManageChild( form_tmp ) ; /* 29 Sep 2000 */
1118
1119 #if 0
1120 STATUS("realizing widgets") ;
1121 XtRealizeWidget( grapher->fdw_graph ) ;
1122 WAIT_for_window(grapher->form_tmp) ;
1123
1124 XtVaSetValues( grapher->option_rowcol ,
1125 XmNleftAttachment , XmATTACH_NONE ,
1126 XmNtopAttachment , XmATTACH_NONE ,
1127 XmNrightAttachment , XmATTACH_FORM ,
1128 XmNbottomAttachment , XmATTACH_FORM ,
1129 NULL ) ;
1130 XMapRaised( XtDisplay(grapher->option_rowcol) ,
1131 XtWindow(grapher->option_rowcol) ) ;
1132
1133 NORMAL_cursorize( grapher->fdw_graph ) ;
1134
1135 grapher->valid = 2 ;
1136 #ifdef USE_OPTMENUS
1137 GRA_fix_optmenus( grapher ) ;
1138 #endif
1139 #endif
1140
1141 grapher->fd_pxWind = (Pixmap) 0 ;
1142
1143 /*** add callback for the WM_DELETE_WINDOW protocol ***/
1144
1145 XmAddWMProtocolCallback(
1146 grapher->fdw_graph , XmInternAtom(dc->display,"WM_DELETE_WINDOW",False) ,
1147 end_fd_graph_CB , (XtPointer) grapher ) ;
1148
1149 RETURN(grapher) ;
1150 }
1151
1152 /*--------------------------------------------------------------------------*/
1153 /* Get the label for a time point. [18 Apr 2011]
1154 *//*------------------------------------------------------------------------*/
1155
GRA_getlabel(MCW_grapher * grapher,int index)1156 char * GRA_getlabel( MCW_grapher *grapher , int index )
1157 {
1158 char *lab = NULL ;
1159
1160 CALL_getser( grapher , index,graCR_getlabel , char * , lab ) ;
1161
1162 if( lab == NULL || *lab == '\0' ) return NULL ;
1163 #if 0
1164 if( *lab == '?' || *lab == '#' ) return NULL ;
1165 #endif
1166 return lab ;
1167 }
1168
1169 /*--------------------------------------------------------------------------*/
1170 /* Get the float-valued time series for graphing. [18 Apr 2011]
1171 *//*------------------------------------------------------------------------*/
1172
GRA_getseries(MCW_grapher * grapher,int index)1173 MRI_IMAGE * GRA_getseries( MCW_grapher *grapher , int index )
1174 {
1175 MRI_IMAGE *tsim ;
1176
1177 CALL_getser( grapher , index,graCR_getseries , MRI_IMAGE *,tsim ) ;
1178
1179 if( tsim == NULL ) return NULL;
1180 if( tsim->nx < 1 ){ mri_free(tsim); return NULL; }
1181
1182 MRI_floatscan(tsim) ; /* 10 Jun 2021 */
1183
1184 if( tsim->kind == MRI_complex ){
1185 MRI_IMAGE *qim ;
1186 char *eee = my_getenv("AFNI_GRAPH_CX2R") ;
1187 if( eee == NULL ) eee = "A" ;
1188 switch( *eee ){
1189 default:
1190 case 'A':
1191 case 'a': qim = mri_complex_abs(tsim) ; break ;
1192
1193 case 'P':
1194 case 'p': qim = mri_complex_phase(tsim); break ;
1195
1196 case 'r':
1197 case 'R': qim = mri_complex_real(tsim) ; break ;
1198
1199 case 'i':
1200 case 'I': qim = mri_complex_imag(tsim) ; break ;
1201 }
1202 qim->flags = tsim->flags ; mri_free(tsim) ; tsim = qim ;
1203
1204 } else if( tsim->kind != MRI_float ){
1205 MRI_IMAGE *qim = mri_to_float(tsim) ;
1206 qim->flags = tsim->flags ; mri_free(tsim) ; tsim = qim ;
1207 }
1208
1209 return tsim ;
1210 }
1211
1212 #ifdef BE_AFNI_AWARE
1213 /*--------------------------------------------------------------------------*/
1214 /* Get the float-valued time series for x-axis graphing. [10 Feb 2015]
1215 *//*------------------------------------------------------------------------*/
1216
GRA_getseries_xax(MCW_grapher * grapher,int index)1217 MRI_IMAGE * GRA_getseries_xax( MCW_grapher *grapher , int index )
1218 {
1219 MRI_IMAGE *tsim ; int tf ;
1220
1221 ENTRY("GRA_getseries_xax") ;
1222
1223 if( grapher->xax_fdbr == NULL ) RETURN(NULL) ; /* bad call */
1224
1225 tsim = FD_brick_to_series( index , grapher->xax_fdbr ) ;
1226
1227 if( tsim == NULL ) RETURN(NULL) ;
1228
1229 if( tsim->nx < 1 ){ mri_free(tsim); RETURN(NULL); }
1230
1231 MRI_floatscan(tsim) ; /* 10 Jun 2021 */
1232
1233 if( tsim->kind == MRI_complex ){
1234 MRI_IMAGE *qim ;
1235 char *eee = my_getenv("AFNI_GRAPH_CX2R") ;
1236 if( eee == NULL ) eee = "A" ;
1237 switch( *eee ){
1238 default:
1239 case 'A':
1240 case 'a': qim = mri_complex_abs(tsim) ; break ;
1241
1242 case 'P':
1243 case 'p': qim = mri_complex_phase(tsim); break ;
1244
1245 case 'r':
1246 case 'R': qim = mri_complex_real(tsim) ; break ;
1247
1248 case 'i':
1249 case 'I': qim = mri_complex_imag(tsim) ; break ;
1250 }
1251 qim->flags = tsim->flags ; mri_free(tsim) ; tsim = qim ;
1252
1253 } else if( tsim->kind != MRI_float ){
1254 MRI_IMAGE *qim = mri_to_float(tsim) ;
1255 qim->flags = tsim->flags ; mri_free(tsim) ; tsim = qim ;
1256 }
1257
1258 RETURN(tsim) ;
1259 }
1260 #endif
1261
1262 /*----------------------------------
1263 Exit button action
1264 ------------------------------------*/
1265
end_fd_graph_CB(Widget w,XtPointer client_data,XtPointer call_data)1266 void end_fd_graph_CB( Widget w , XtPointer client_data , XtPointer call_data )
1267 {
1268 MCW_grapher *grapher = (MCW_grapher *) client_data ;
1269 int ii ;
1270
1271 ENTRY("end_fd_graph_CB") ;
1272
1273 if( ! GRA_VALID(grapher) ) EXRETURN ;
1274
1275 GRA_timer_stop( grapher ) ; NI_sleep(1) ; /* 04 Dec 2003 */
1276
1277 grapher->valid = 0 ; /* can't do anything with this anymore */
1278
1279 if( grapher->fd_pxWind != (Pixmap) 0 ){
1280 STATUS("freeing Pixmap") ;
1281 XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
1282 }
1283
1284 #ifdef USE_OPTMENUS
1285 STATUS("destroying optmenus") ;
1286 FREE_AV(grapher->opt_mat_choose_av) ;
1287 FREE_AV(grapher->opt_slice_choose_av) ;
1288 FREE_AV(grapher->fmenu->fim_ignore_choose_av) ;
1289 FREE_AV(grapher->fmenu->fim_polort_choose_av) ;
1290 #endif
1291
1292 STATUS("destroying arrowvals") ;
1293 FREE_AV( grapher->setshift_right_av) ;
1294 FREE_AV( grapher->setshift_left_av) ;
1295 FREE_AV( grapher->setshift_inc_av) ;
1296 FREE_AV( grapher->transform0D_av ) ; /* 22 Oct 1996 */
1297 FREE_AV( grapher->transform1D_av ) ; /* 03 Nov 1996 */
1298 FREE_AV( grapher->opt_ggap_av ) ; /* 28 Sep 1998: via Purify */
1299 FREE_AV( grapher->opt_gthick_av ) ; /* 06 Oct 2004 */
1300 FREE_AV( grapher->opt_upsam_av ) ; /* 01 Jun 2020 */
1301
1302 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ) /* 16 Jun 1997 */
1303 FREE_AV( grapher->opt_color_av[ii] ) ;
1304
1305 STATUS("destroying fmenu") ;
1306 myXtFree( grapher->fmenu->fim_editref_winaver_bbox ); /* 27 Jan 2004 */
1307 myXtFree( grapher->fmenu->fim_opt_bbox ) ; /* Jan 1998 */
1308 myXtFree( grapher->fmenu->fimp_opt_bbox ); /* Jan 1998 */
1309 myXtFree( grapher->fmenu->fimp_user_bbox); /* Feb 2000 */
1310 myXtFree( grapher->fmenu ) ;
1311 myXtFree( grapher->cen_line ) ;
1312
1313 STATUS("destroying bboxes") ;
1314 myXtFree( grapher->opt_dplot_bbox ) ; /* 08 Nov 1996 */
1315
1316 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
1317 myXtFree( grapher->opt_thick_bbox[ii] ) ; /* 16 Jun 1997 */
1318 myXtFree( grapher->opt_points_bbox[ii] ) ; /* 09 Jan 1998 */
1319 }
1320
1321 myXtFree( grapher->opt_baseline_bbox ) ; /* 07 Aug 2001 */
1322 myXtFree( grapher->opt_textgraph_bbox ) ;
1323 myXtFree( grapher->opt_tfade_bbox ) ;
1324
1325 STATUS("freeing cen_tsim") ;
1326 mri_free( grapher->cen_tsim ) ;
1327 mri_free( grapher->xax_tsim ) ; /* 09 Jan 1998 */
1328 mri_free( grapher->ave_tsim ) ; /* 27 Jan 2004 */
1329 mri_free( grapher->xax_cen ) ; /* 12 Feb 2015 */
1330 grapher->xax_dset = NULL ; /* 09 Feb 2015 */
1331 DESTROY_FD_BRICK(grapher->xax_fdbr) ; grapher->xax_fdbr = NULL ;
1332
1333 STATUS("freeing tuser") ;
1334 GRA_CLEAR_tuser( grapher ) ; /* 22 Apr 1997 */
1335
1336 /* 31 Mar 2004:
1337 On the Mac, destroying widgets after the timeseries
1338 chooser is opened causes death for unknown reasons.
1339 So in that case, just hide them. What the ....? */
1340
1341 STATUS("destroying widgets") ;
1342 #ifdef DARWIN
1343 if( grapher->tschosen ) XtUnrealizeWidget( grapher->fdw_graph ) ;
1344 else XtDestroyWidget ( grapher->fdw_graph ) ;
1345 #else
1346 XtUnrealizeWidget( grapher->fdw_graph ) ;
1347 #endif
1348 STATUS("widgets now destroyed") ; NI_sleep(1) ;
1349
1350 /** if AFNI has a notify callback, it will free the data **/
1351
1352 if( grapher->status->send_CB != NULL ){
1353 GRA_cbs cbs ;
1354 cbs.reason = graCR_destroy ;
1355 STATUS("calling AFNI") ;
1356 #if 0
1357 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
1358 #else
1359 CALL_sendback( grapher , cbs ) ;
1360 #endif
1361 } else {
1362 STATUS("freeing grapher") ;
1363 myXtFree( grapher ) ; /* otherwise, we will free the data */
1364 }
1365
1366 EXRETURN ;
1367 }
1368
1369 /*----------------------------------
1370 Erase pixmap to background color
1371 ------------------------------------*/
1372
erase_fdw(MCW_grapher * grapher)1373 void erase_fdw( MCW_grapher *grapher )
1374 {
1375 ENTRY("erase_fdw") ;
1376
1377 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
1378
1379 DC_fg_color ( grapher->dc , BG_COLOR(grapher) ) ;
1380 DC_linewidth( grapher->dc , 0 ) ;
1381
1382 XFillRectangle( grapher->dc->display ,
1383 grapher->fd_pxWind , grapher->dc->myGC ,
1384 0 , 0 , grapher->fWIDE , grapher->fHIGH ) ;
1385
1386 if( show_grapher_pixmap &&
1387 grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP &&
1388 grapher->glogo_height > 0 && grapher->glogo_width > 0 ){
1389
1390 XCopyArea( grapher->dc->display ,
1391 grapher->glogo_pixmap , grapher->fd_pxWind , grapher->dc->myGC ,
1392 0,0 , grapher->glogo_width,grapher->glogo_height ,
1393 0,grapher->fHIGH - grapher->glogo_height + 1 ) ;
1394 }
1395
1396 EXRETURN ;
1397 }
1398
1399 /*-----------------------------------------------------*/
1400
rectangle_fdX(MCW_grapher * grapher,int xb,int yb,int xw,int yw,int clr)1401 void rectangle_fdX( MCW_grapher *grapher, int xb,int yb, int xw,int yw, int clr )
1402 {
1403 ENTRY("rectangle_fdX") ;
1404
1405 if( grapher->dont_redraw ) EXRETURN ;
1406
1407 if( xw <= 0 || yw <= 0 ) EXRETURN ;
1408
1409 if( xb < 0 ) xb = 0 ;
1410 if( yb < 0 ) yb = 0 ;
1411 yb = grapher->fHIGH - yb - yw ;
1412
1413 DC_fg_color ( grapher->dc , clr ) ; /* changing color in myGC */
1414
1415 XFillRectangle( grapher->dc->display ,
1416 grapher->fd_pxWind , grapher->dc->myGC , xb,yb , xw,yw ) ;
1417
1418 EXRETURN ;
1419 }
1420
1421 /*-----------------------------------------------------*/
1422 /* It plots line to point (x,y) for mod = 1 */
1423 /* or moves to this point for mod = 0. */
1424 /* All into the fd_pxWind. */
1425 /*-----------------------------------------------------*/
1426
plot_fdX(MCW_grapher * grapher,int x,int y,int mod)1427 void plot_fdX( MCW_grapher *grapher , int x , int y , int mod )
1428 {
1429 int iy = grapher->fHIGH - y ;
1430
1431 if( mod > 0 )
1432 XDrawLine( grapher->dc->display ,
1433 grapher->fd_pxWind , grapher->dc->myGC ,
1434 grapher->xFD , grapher->yFD , x , iy ) ;
1435
1436 grapher->xFD = x ; grapher->yFD = iy ;
1437 return ;
1438 }
1439
1440 /* ----------------------------------- */
1441 /* Reload pixmap fd_pxWind to FDWindow */
1442 /* ----------------------------------- */
1443
fd_px_store(MCW_grapher * grapher)1444 void fd_px_store( MCW_grapher * grapher )
1445 {
1446 ENTRY("fd_px_store") ;
1447
1448 if( ! MCW_widget_visible(grapher->draw_fd) ) EXRETURN ; /* 03 Jan 1999 */
1449
1450 XtVaSetValues( grapher->draw_fd ,
1451 XmNbackgroundPixmap , grapher->fd_pxWind ,
1452 NULL ) ;
1453
1454 XClearWindow( grapher->dc->display , XtWindow(grapher->draw_fd) ) ;
1455 XFlush( grapher->dc->display ) ;
1456 EXRETURN ;
1457 }
1458
1459 /*--------------------------------------------------------------
1460 draw a small circle somewhere:
1461 xwin,ywin = Window coordinates of center
1462 filled = 1 or 0, if you want the circle solid or not
1463 14 Jan 1998: 2 if for points on a filled circle
1464 ----------------------------------------------------------------*/
1465
1466 #define NCIR 12 /* number of points for hollow circle */
1467 #define NBAL 21 /* number of points for filled circle */
1468 #define NBAX 25 /* number of points for with points */
1469
1470 #define NBTOP NBAX /* max # of points */
1471
1472 static XPoint xball[] = {
1473 {-1,-2},{ 0,-2},{ 1,-2},
1474 { 2,-1},{ 2, 0},{ 2, 1},
1475 { 1, 2},{ 0, 2},{-1, 2},
1476 {-2, 1},{-2, 0},{-2,-1}, /* NCIR ends here */
1477 {-1,-1},{-1, 0},{-1, 1},
1478 { 0,-1},{ 0, 0},{ 0, 1},
1479 { 1,-1},{ 1, 0},{ 1, 1}, /* NBAL ends here */
1480 { 0,-3},{ 0, 3},{ 3, 0},
1481 {-3, 0} /* NBAX ends here */
1482 } ;
1483
1484 /*------------------ draw into Pixmap (the graph itself) -----------------------*/
1485
GRA_small_circle(MCW_grapher * grapher,int xwin,int ywin,int filled)1486 void GRA_small_circle( MCW_grapher *grapher, int xwin, int ywin, int filled )
1487 {
1488 int i, ncirc ;
1489 XPoint a[NBTOP] ;
1490
1491 switch( filled ){
1492 default: ncirc = NCIR ; break ;
1493 case 1: ncirc = NBAL ; break ;
1494 case 2: ncirc = NBAX ; break ;
1495 }
1496
1497 for( i=0 ; i < ncirc ; i++ ){ /* fill pixel coords */
1498 a[i].x = xball[i].x + xwin ;
1499 a[i].y = xball[i].y + ywin ;
1500 }
1501
1502 /* just draws pixels */
1503 XDrawPoints( grapher->dc->display, grapher->fd_pxWind,
1504 grapher->dc->myGC, a, ncirc, CoordModeOrigin ) ;
1505 return ;
1506 }
1507
1508 /*------------------ draw into window (the graph overlay) -----------------------*/
1509
GRA_overlay_circle(MCW_grapher * grapher,int xwin,int ywin,int filled)1510 void GRA_overlay_circle( MCW_grapher *grapher, int xwin, int ywin, int filled )
1511 {
1512 int i, ncirc ;
1513 XPoint a[NBTOP] ;
1514
1515 switch( filled ){
1516 default: ncirc = NCIR ; break ;
1517 case 1: ncirc = NBAL ; break ;
1518 case 2: ncirc = NBAX ; break ;
1519 }
1520
1521 for( i=0 ; i < ncirc ; i++ ){
1522 a[i].x = xball[i].x + xwin ;
1523 a[i].y = xball[i].y + ywin ;
1524 }
1525
1526 DC_linewidth( grapher->dc, 0 ) ;
1527
1528 XDrawPoints( grapher->dc->display, XtWindow(grapher->draw_fd),
1529 grapher->dc->myGC, a, ncirc, CoordModeOrigin ) ;
1530 return ;
1531 }
1532
1533 /*---------------------------------------------------------------------------*/
1534 /* Draw a complete circle using the XDrawArc function
1535 (where the angle of the arc is specified in units of degrees/64)
1536 *//*-------------------------------------------------------------------------*/
1537
GRA_draw_circle(MCW_grapher * grapher,int xc,int yc,int rad)1538 void GRA_draw_circle( MCW_grapher *grapher , int xc , int yc , int rad )
1539 {
1540 int xb,yb ;
1541 unsigned int ww ;
1542
1543 if( rad < 0 ) rad = 0 ;
1544 xb = xc-rad ; yb = yc-rad ; ww = 2*rad ;
1545 XDrawArc( grapher->dc->display , XtWindow(grapher->draw_fd) ,
1546 grapher->dc->myGC , xb,yb , ww,ww , 0,360*64 ) ;
1547 return ;
1548 }
1549
1550 /*---------------------------------------------------------------------------*/
1551 /* Same thing, but a filled circle = a disk */
1552
GRA_draw_disk(MCW_grapher * grapher,int xc,int yc,int rad)1553 void GRA_draw_disk( MCW_grapher *grapher , int xc , int yc , int rad )
1554 {
1555 int xb,yb ;
1556 unsigned int ww ;
1557
1558 if( rad < 0 ) rad = 0 ;
1559 xb = xc-rad ; yb = yc-rad ; ww = 2*rad ;
1560 XFillArc( grapher->dc->display , grapher->fd_pxWind ,
1561 grapher->dc->myGC , xb,yb , ww,ww , 0,360*64 ) ;
1562 return ;
1563 }
1564
1565 /*-----------------------------------------------
1566 redraw stuff that overlays the pixmap
1567 -------------------------------------------------*/
1568
1569 #define SHORT_NAME_WIDTH 384
1570
1571 static char *long_index_name = "indx=" ;
1572 static char *short_index_name = "#" ;
1573 static char *long_value_name = " val=" ;
1574 static char *short_value_name = "=" ;
1575 static char *long_time_name = " @t=" ;
1576 static char *short_time_name = "@" ;
1577 static char *long_xax_name = " @x=" ;
1578 static char *short_xax_name = "@" ;
1579
GRA_redraw_overlay(MCW_grapher * grapher)1580 void GRA_redraw_overlay( MCW_grapher *grapher )
1581 {
1582 Window win ;
1583 Display *dis ;
1584 int ii , xxx , jj , boff ;
1585 float val ;
1586 char buf[16] , strp[256] ;
1587 char *vbuf , *iname , *vname ;
1588
1589 ENTRY("GRA_redraw_overlay") ;
1590
1591 if( ! GRA_REALZ(grapher) ){ STATUS("ILLEGAL CALL") ; EXRETURN ; }
1592
1593 if( ! MCW_widget_visible(grapher->draw_fd) ) EXRETURN ; /* 03 Jan 1999 */
1594 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
1595
1596 /* erase contents of window (that aren't in the pixmap) */
1597
1598 dis = grapher->dc->display ;
1599 win = XtWindow(grapher->draw_fd) ;
1600 XClearWindow( dis , win ) ;
1601
1602 EXRONE(grapher) ; /* 22 Sep 2000 */
1603
1604 boff = DATA_BOXED(grapher) ? BOXOFF : 0 ; /* boxes are elevated */
1605
1606 /* draw some circles over ignored data points [23 May 2005] */
1607
1608 if( NIGNORE(grapher) > 0 && !grapher->textgraph && NSTRIDE(grapher) == 1 ){
1609 DC_fg_color( grapher->dc , IGNORE_COLOR(grapher) ) ;
1610 jj = NBOT(grapher) ; /* first point to plot */
1611 xxx = NTOP(grapher) ; /* last */
1612 xxx = MIN (xxx , NIGNORE(grapher)) ; /* point */
1613 xxx = MIN (xxx , jj+grapher->nncen) ; /* to plot */
1614 for( ii=jj ; ii < xxx ; ii++ )
1615 GRA_draw_circle( grapher , grapher->cen_line[ii-jj].x ,
1616 grapher->cen_line[ii-jj].y-boff , 4 ) ;
1617 }
1618
1619 /* 22 July 1996:
1620 draw a ball on the graph at the currently display time_index */
1621
1622 ii = grapher->time_index ; jj = NBOT(grapher) ;
1623 if( ii >= jj && NSTRIDE(grapher) == 1 &&
1624 ii < NTOP(grapher) && ii-jj < grapher->nncen && !grapher->textgraph ){
1625 int ww = MAX(4,DATA_THICK(grapher)) ;
1626
1627 DC_fg_color( grapher->dc , IDEAL_COLOR(grapher) ) ;
1628 GRA_overlay_circle( grapher , grapher->cen_line[ii-jj].x ,
1629 grapher->cen_line[ii-jj].y-boff , 2 ) ;
1630 GRA_draw_circle ( grapher , grapher->cen_line[ii-jj].x ,
1631 grapher->cen_line[ii-jj].y-boff , ww ) ;
1632 }
1633
1634 /* draw text showing value at currently displayed time_index */
1635
1636 if( ii >= 0 && grapher->cen_tsim != NULL &&
1637 ii < grapher->cen_tsim->nx && NSTRIDE(grapher) == 1 ){
1638 char *ilab=NULL ; MRI_IMAGE *xxim_cen=NULL ;
1639
1640 val = MRI_FLOAT_PTR(grapher->cen_tsim)[ii] ;
1641 AV_fval_to_char( val , buf ) ;
1642 vbuf = (buf[0]==' ') ? buf+1 : buf ;
1643
1644 if( grapher->fWIDE < SHORT_NAME_WIDTH ){
1645 iname = short_index_name ; vname = short_value_name ;
1646 } else {
1647 iname = long_index_name ; vname = long_value_name ;
1648 ilab = GRA_getlabel( grapher , ii ) ;
1649 }
1650
1651 if( ilab == NULL || *ilab == '\0' )
1652 sprintf( strp , "%s%d%s%s" , iname,ii , vname,vbuf ) ;
1653 else
1654 sprintf( strp , "%s%d [%.31s]%s%s",iname,ii,ilab , vname,vbuf ) ;
1655
1656 xxim_cen = (grapher->xax_cen != NULL) ? grapher->xax_cen : grapher->xax_tsim ;
1657 if( xxim_cen == NULL && grapher->cen_tsim->dx != 0.0 ){
1658 val = grapher->cen_tsim->xo + ii * grapher->cen_tsim->dx ;
1659 AV_fval_to_char( val , buf ) ;
1660 vbuf = (buf[0]==' ') ? buf+1 : buf ;
1661 sprintf( strp+strlen(strp) , "%s%s" ,
1662 (grapher->fWIDE < SHORT_NAME_WIDTH) ? short_time_name
1663 : long_time_name, vbuf ) ;
1664 } else if( xxim_cen != NULL ){
1665 if( ii >= 0 && ii < xxim_cen->nx ){
1666 val = MRI_FLOAT_PTR(xxim_cen)[ii] ;
1667 AV_fval_to_char( val , buf ) ;
1668 vbuf = (buf[0]==' ') ? buf+1 : buf ;
1669 sprintf( strp+strlen(strp) , "%s%s" ,
1670 (grapher->fWIDE < SHORT_NAME_WIDTH) ? short_xax_name
1671 : long_xax_name, vbuf ) ;
1672 }
1673 }
1674
1675 xxx = MAX( grapher->xx_text_2 ,
1676 grapher->xorigin[grapher->xc][grapher->yc]-39 ) ;
1677
1678 if( NIGNORE(grapher) > 0 || grapher->thresh_fade ){
1679 xxx = MAX( xxx , grapher->xx_text_2p ) ;
1680 xxx = MAX( xxx , grapher->xx_text_igf ) ; /* this allows for Fading + Ignore together */
1681 }
1682
1683 DC_fg_color( grapher->dc , IDEAL_COLOR(grapher) ) ;
1684 overlay_txt( grapher, xxx , GB_DLY-15 , strp ) ;
1685 }
1686
1687 /* no more to do now */
1688
1689 XFlush( dis ) ;
1690 EXRETURN ;
1691 }
1692
1693 /*------------------------------------------------------------------
1694 redraw entire graph;
1695 code is a mask of special values:
1696 0 = default action
1697 PLOTCODE_AUTOSCALE = scale graphs automatically
1698 -------------------------------------------------------------------*/
1699
redraw_graph(MCW_grapher * grapher,int code)1700 void redraw_graph( MCW_grapher *grapher , int code )
1701 {
1702 int x, y , www,xxx , rrr ;
1703 int xc = grapher->xc , yc = grapher->yc ;
1704 char strp[256] , buf[64] ;
1705 int xd,yd,zd ;
1706
1707 ENTRY("redraw_graph") ;
1708
1709 if( ! GRA_REALZ(grapher) ){ STATUS("ILLEGAL ENTRY"); EXRETURN; }
1710 if( grapher->fd_pxWind == (Pixmap) 0 ){ STATUS("ILLEGAL ENTRY"); EXRETURN; }
1711 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
1712
1713 /*---- draw the graphs ----*/
1714
1715 erase_fdw ( grapher ) ;
1716 draw_grids ( grapher ) ;
1717
1718 if (code == 0 && PLOT_FORCE_AUTOSCALE)
1719 code = PLOTCODE_AUTOSCALE; /* Daniel Glen
1720 July 14th Allons enfants de la patrie,
1721 la guillottine est arrivee! */
1722
1723 /* this is where all the 'fun' lives */
1724 plot_graphs( grapher , code ) ;
1725
1726 DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
1727
1728 if( TPTS(grapher) < 2 ){ /* 22 Sep 2000 */
1729 fd_txt( grapher , GL_DLX+5, 35,
1730 "Can't draw graphs for this dataset: Num < 2" ) ;
1731 fd_px_store( grapher ) ;
1732 EXRETURN ;
1733 }
1734
1735 /*---- draw some strings for informative purposes ----*/
1736
1737 DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
1738
1739 /*** y axis labels ***/
1740
1741 if( !grapher->textgraph ){
1742 AV_fval_to_char( grapher->pmax[xc][yc] , strp ) ;
1743 www = DC_text_width(grapher->dc,strp) ;
1744 xxx = GL_DLX - www - 2 ;
1745 xxx = MAX(0,xxx) ;
1746 fd_txt( grapher , xxx , GB_DLY + grapher->gy_max - MYTXT, strp) ;
1747
1748 AV_fval_to_char( grapher->pmax[xc][yc] - grapher->pmin[xc][yc] , buf ) ;
1749 if( buf[0] == ' ' ) buf[0] = '+' ;
1750 sprintf( strp , "[%s]" , buf ) ;
1751 www = DC_text_width(grapher->dc,strp) ;
1752 xxx = GL_DLX - www + 2 ;
1753 xxx = MAX(0,xxx) ;
1754 fd_txt( grapher , xxx , GB_DLY + grapher->gy_max - MYTXT - 14 , strp) ;
1755
1756 AV_fval_to_char( grapher->pmin[xc][yc] , strp ) ;
1757 www = DC_text_width(grapher->dc,strp) ;
1758 xxx = GL_DLX - www - 2 ;
1759 xxx = MAX(0,xxx) ;
1760 fd_txt( grapher , xxx , GB_DLY + 5, strp) ;
1761 }
1762
1763 /*** bottom of the page coordinates stuff ***/
1764
1765 /* first column */
1766
1767 grapher->xx_text_1 = GL_DLX+5 ;
1768
1769 xd = grapher->xpoint ; yd = grapher->ypoint ; zd = grapher->zpoint ;
1770 #ifndef DONT_MANGLE_XYZ
1771 { THD_ivec3 id ;
1772 id = THD_fdind_to_3dind( grapher->getaux , TEMP_IVEC3(xd,yd,zd) ) ;
1773 xd = id.ijk[0] ; yd = id.ijk[1] ; zd = id.ijk[2] ; }
1774 #endif
1775
1776 sprintf(strp,"I: %d", xd) ;
1777 fd_txt( grapher , GL_DLX+5 , 35, strp) ;
1778 xxx = DC_text_width(grapher->dc,strp) ;
1779
1780 sprintf(strp,"J: %d", yd) ;
1781 fd_txt( grapher , GL_DLX+5 , 21, strp) ;
1782 www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
1783
1784 if( grapher->status->nz > 1 ){
1785 sprintf(strp,"K: %d", zd) ;
1786 fd_txt( grapher , GL_DLX+5 , 7, strp) ;
1787 www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
1788 }
1789
1790 /* second column */
1791
1792 grapher->xx_text_2 = xxx = xxx + GL_DLX + 15 ;
1793
1794 DC_linewidth( grapher->dc , 0 ) ;
1795 fd_line( grapher , xxx-7 , 41 , xxx-7 , 5 ) ;
1796
1797 if( NIGNORE(grapher) > 0 ){ /* 23 May 2005 */
1798 sprintf(strp,"Ignore%4d",NIGNORE(grapher)) ;
1799 if( grapher->thresh_fade ) sprintf(strp+strlen(strp)," Fading") ;
1800 fd_txt( grapher , xxx , 35, strp) ; grapher->xx_text_igf = 1+xxx+DC_text_width(grapher->dc,strp) ;
1801 } else if( grapher->thresh_fade ){
1802 sprintf(strp,"Fading") ;
1803 fd_txt( grapher , xxx , 35, strp) ; grapher->xx_text_igf = 1+xxx+DC_text_width(grapher->dc,strp) ;
1804 }
1805
1806 sprintf(strp,"Grid:%5d", grapher->grid_spacing ) ;
1807 rrr = DC_text_width(grapher->dc,strp) ;
1808
1809 if( !grapher->textgraph ){
1810 if( grapher->fscale > 0 ){ /* 04 Feb 1998: */
1811 AV_fval_to_char( grapher->fscale , buf ) ; /* put scale on graph, too */
1812 www = strlen(strp) ;
1813 sprintf(strp+www," Scale:%s pix/datum",buf) ;
1814 } else if( grapher->fscale < 0 ){
1815 AV_fval_to_char( -grapher->fscale , buf ) ;
1816 www = strlen(strp) ;
1817 sprintf(strp+www," Scale:%s datum/pix",buf) ;
1818 }
1819 }
1820
1821 fd_txt( grapher , xxx , 21, strp ) ;
1822
1823 xxx = DC_text_width(grapher->dc,strp) ; /* 19 Dec 2003 [rickr] */
1824
1825 /* info about indexes we are viewing*/
1826
1827 { int bb=TBOT(grapher) , tt=TTOP(grapher)-1 , ss = NSTRIDE(grapher) ;
1828 if( ss == 1 ){
1829 if( bb > 999 || tt > 999 )
1830 sprintf(strp,"#%4d:%-4d" , bb,tt ) ;
1831 else
1832 sprintf(strp,"Num%3d:%-3d" , bb,tt ) ;
1833 } else { /* 11 Jun 2020 */
1834 if( bb > 999 || tt > 999 )
1835 sprintf(strp,"%3d:%-4d@%1d" , bb,tt,ss ) ;
1836 else
1837 sprintf(strp,"#%3d:%-3d@%1d" , bb,tt,ss ) ;
1838 }
1839 }
1840 fd_line( grapher ,
1841 grapher->xx_text_2+rrr+3 ,
1842 (NIGNORE(grapher) > 0 || grapher->thresh_fade) ? 41 : 31 ,
1843 grapher->xx_text_2+rrr+3 , 5 ) ;
1844
1845 grapher->xx_text_2p = grapher->xx_text_2+rrr+7 ; /* 23 May 2005 */
1846
1847 /* info about the baseline */
1848
1849 if( !grapher->textgraph ){
1850 switch( grapher->common_base ){
1851 default:
1852 case BASELINE_INDIVIDUAL:
1853 strcat(strp," Base: separate") ; break ;
1854
1855 case BASELINE_COMMON:
1856 strcat(strp," Base: common") ; break ;
1857
1858 case BASELINE_GLOBAL:
1859 strcat(strp," Base: global") ; break ;
1860 }
1861 }
1862
1863 fd_txt( grapher , grapher->xx_text_2 , 7, strp ) ;
1864
1865 /* add third column 19 Dec 2003 [rickr] */
1866
1867 www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
1868
1869 grapher->xx_text_3 = grapher->xx_text_2 + xxx + 15 ;
1870
1871 if( !grapher->textgraph && !ISONE(grapher) ){
1872 char *flab ;
1873
1874 sprintf(strp,"Mean: %10s", MV_format_fval(grapher->tmean[xc][yc]) ) ;
1875
1876 fd_txt( grapher , grapher->xx_text_3 , 21, strp ) ;
1877 xxx = DC_text_width(grapher->dc,strp) ;
1878
1879 sprintf(strp,"Sigma:%10s", MV_format_fval(grapher->tstd[xc][yc]) ) ;
1880
1881 fd_txt( grapher , grapher->xx_text_3 , 7, strp ) ;
1882 www = DC_text_width(grapher->dc,strp) ; xxx = MAX(xxx,www) ;
1883
1884 fd_line( grapher , grapher->xx_text_3-7 , 31 , grapher->xx_text_3-7 , 5 ) ;
1885
1886 www = grapher->xx_text_3 + xxx + 7 ;
1887 fd_line( grapher , www , 31 , www , 5 ) ;
1888
1889 flab = GRA_transform_label( grapher->transform0D_av ,
1890 (XtPointer) grapher->status->transforms0D ) ;
1891 sprintf(strp,"Tran 0D = %s",flab) ;
1892 www = grapher->xx_text_3 + xxx + 15 ;
1893 fd_txt( grapher , www , 21 , strp ) ;
1894
1895 flab = GRA_transform_label( grapher->transform1D_av ,
1896 (XtPointer) grapher->status->transforms1D ) ;
1897 sprintf(strp,"Tran 1D = %s",flab) ;
1898 www = grapher->xx_text_3 + xxx + 15 ;
1899 fd_txt( grapher , www , 7 , strp ) ;
1900 }
1901
1902 /*** flush the pixmap to the screen ***/
1903
1904 fd_px_store( grapher ) ;
1905
1906 /*** draw any overlay stuff ***/
1907
1908 GRA_redraw_overlay( grapher ) ;
1909
1910 #ifdef USE_OPTMENUS
1911 GRA_fix_optmenus( grapher ) ;
1912 #endif
1913
1914 /** 27 Jan 2004 **/
1915
1916 if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) )
1917 GRA_winaver_setref( grapher ) ;
1918
1919 grapher->never_drawn = 0 ;
1920 EXRETURN ;
1921 }
1922
1923 /*------------------------------------------------
1924 Plot text in fd_pxWind at x,y position
1925 relative to lower left corner (!).
1926 Note that myGC was setup in display.c,
1927 where the font is defined.
1928 --------------------------------------------------*/
1929
fd_txt(MCW_grapher * grapher,int x,int y,char * str)1930 void fd_txt( MCW_grapher *grapher , int x , int y , char * str )
1931 {
1932 XDrawString( grapher->dc->display, grapher->fd_pxWind,
1933 grapher->dc->myGC , x , grapher->fHIGH-y ,
1934 str , strlen(str) ) ;
1935 return ;
1936 }
1937
1938 /*---------------------------------------------------------------------------*/
1939 /* Write the string one character at a time, upwards (for graph box labels) */
1940
fd_txt_upwards(MCW_grapher * grapher,int x,int y,char * str)1941 void fd_txt_upwards( MCW_grapher *grapher , int x , int y , char *str )
1942 {
1943 int ii , nn ; int_pair ad ;
1944 if( str == NULL || *str == '\0' ) return ;
1945 for( nn=strlen(str)-1 ; nn >= 0 && isspace(str[nn]) ; nn-- ) ; /*nada*/
1946 for( ii=nn ; ii >= 0 ; ii-- ){
1947 if( isgraph(str[ii]) ){
1948 ad = DC_char_adscent(grapher->dc,str[ii]) ;
1949 y -= ad.j ;
1950 XDrawString( grapher->dc->display, grapher->fd_pxWind,
1951 grapher->dc->myGC , x , y , str+ii , 1 ) ;
1952 y -= ad.i+2 ;
1953 } else {
1954 y -= 2 ;
1955 }
1956 }
1957 return ;
1958 }
1959
1960 /*---------------------------------------------------------------------------*/
1961
overlay_txt(MCW_grapher * grapher,int x,int y,char * str)1962 void overlay_txt( MCW_grapher *grapher , int x , int y , char *str )
1963 {
1964 if( str == NULL || *str == '\0' ) return ;
1965 XDrawString( grapher->dc->display, XtWindow(grapher->draw_fd) ,
1966 grapher->dc->myGC , x , grapher->fHIGH-y ,
1967 str , strlen(str) ) ;
1968 return ;
1969 }
1970
1971 /*-----------------------------------------------*/
1972 /* draw a line in the Pixmap;
1973 this is used only for lines dividing
1974 the informative text below the graphs
1975 *//*---------------------------------------------*/
1976
fd_line(MCW_grapher * grapher,int x1,int y1,int x2,int y2)1977 static void fd_line( MCW_grapher *grapher , int x1,int y1, int x2,int y2 )
1978 {
1979 XDrawLine( grapher->dc->display , grapher->fd_pxWind ,
1980 grapher->dc->myGC , x1,grapher->fHIGH-y1,x2,grapher->fHIGH-y2 ) ;
1981 return ;
1982 }
1983
1984 /*------------------------------------------------------------------------*/
1985 /* get automatic vertical grid line spacings, given number of time points */
1986
1987 #define GRID_MAX 13
1988 static int grid_ar[GRID_MAX] =
1989 { 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000 } ;
1990
auto_grid(MCW_grapher * grapher,int npoints)1991 static void auto_grid( MCW_grapher *grapher , int npoints )
1992 {
1993 int ii ;
1994 if( npoints < 2 ) return ; /* 02 Apr 2004 */
1995 for( ii=GRID_MAX-1 ; ii > 0 ; ii-- )
1996 if( grid_ar[ii] <= npoints/3 ) break;
1997 grapher->grid_index = ii ;
1998 grapher->grid_spacing = grid_ar[ii] ;
1999 grapher->grid_fixed = 0 ; /* 02 Apr 2004 */
2000 return ;
2001 }
2002
2003 /*-----------------------------------------------*/
2004 /* Initialize some constants */
2005
init_const(MCW_grapher * grapher)2006 void init_const( MCW_grapher *grapher )
2007 {
2008 int ii ;
2009
2010 ENTRY("init_const") ;
2011
2012 if( !GRA_VALID(grapher) ) EXRETURN ;
2013
2014 /* vertical scale factor */
2015
2016 if( grapher->fscale == 0 ) grapher->fscale = 1 ;
2017
2018 /* max number of sub-graphs allowed */
2019
2020 grapher->mat_max = MAT_MAX ;
2021 grapher->mat_max = MIN( grapher->mat_max , grapher->status->nx ) ;
2022 grapher->mat_max = MIN( grapher->mat_max , grapher->status->ny ) ;
2023
2024 /* initial number of sub-graphs */
2025
2026 if( grapher->mat <= 0 ) grapher->mat = INIT_GR_gmat ;
2027 grapher->mat = MIN( grapher->mat , grapher->mat_max ) ;
2028
2029 /* initial center point in 3D space, if not previously set */
2030
2031 if( grapher->xpoint < 0 || grapher->xpoint >= grapher->status->nx )
2032 grapher->xpoint = grapher->status->nx / 2 ;
2033
2034 if( grapher->ypoint < 0 || grapher->ypoint >= grapher->status->ny )
2035 grapher->ypoint = grapher->status->ny / 2 ;
2036
2037 if( grapher->zpoint < 0 || grapher->zpoint >= grapher->status->nz )
2038 grapher->zpoint = grapher->status->nz / 2 ;
2039
2040 /* initial grid spacing */
2041
2042 if( grapher->grid_index < 0 ) auto_grid( grapher, NPTS(grapher) ) ;
2043
2044 #if 0
2045 if( grapher->grid_color < 0 )
2046 grapher->grid_color = 1 ; /* first overlay color */
2047 #endif
2048
2049 /* initial time point */
2050
2051 if( grapher->time_index < 0 )
2052 grapher->time_index = 0 ;
2053 else if( grapher->time_index >= grapher->status->num_series )
2054 grapher->time_index = grapher->status->num_series - 1 ;
2055
2056 /* setup the matrix-related constants */
2057
2058 init_mat(grapher) ;
2059 EXRETURN ;
2060 }
2061
2062 /*---------------------------------------------------------------*/
2063 /* Draw numbers instead of graphs -- 22 Sep 2000 -- RWCox
2064 Largely for the physicists out there, or the very inquisitive.
2065 *//*-------------------------------------------------------------*/
2066
text_graphs(MCW_grapher * grapher)2067 void text_graphs( MCW_grapher *grapher )
2068 {
2069 MRI_IMAGE *tsim ;
2070 int index, ix, iy, xtemp,ytemp,ztemp , xoff,yoff ;
2071 int iv , jv , www ;
2072 char str[64] , *strp ;
2073
2074 ENTRY("text_graphs") ;
2075 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
2076
2077 DC_fg_color( grapher->dc , TEXT_COLOR(grapher) ) ;
2078
2079 iv = grapher->time_index ;
2080 if( iv < 0 )
2081 iv = 0 ;
2082 else if( iv >= grapher->status->num_series )
2083 iv = grapher->status->num_series - 1 ;
2084
2085 ztemp = grapher->zpoint * grapher->status->ny * grapher->status->nx ;
2086
2087 /* loop over sub-graph boxes */
2088
2089 for( ix=0 ; ix < grapher->mat ; ix++ ){
2090 xtemp = grapher->xpoint + ix - grapher->xc ;
2091 if( xtemp < 0 ) xtemp += grapher->status->nx ;
2092 else if( xtemp >= grapher->status->nx ) xtemp -= grapher->status->nx ;
2093
2094 for( iy=0 ; iy < grapher->mat ; iy++ ){
2095 ytemp = grapher->ypoint - iy + grapher->yc ;
2096 if( ytemp < 0 ) ytemp += grapher->status->ny ;
2097 else if( ytemp >= grapher->status->ny ) ytemp -= grapher->status->ny ;
2098
2099 index = ztemp + ytemp * grapher->status->nx + xtemp ;
2100
2101 tsim = GRA_getseries( grapher , index ) ; /* get the data */
2102 if( tsim == NULL ) break ;
2103
2104 if( ix == grapher->xc && iy == grapher->yc ){
2105 mri_free( grapher->cen_tsim ) ; /* copy time series too */
2106 grapher->cen_tsim = mri_to_float( tsim ) ;
2107 }
2108
2109 if( grapher->thresh_fade && tsim->flags == 0 ){ /* Mar 2013 */
2110 rectangle_fdX( grapher ,
2111 grapher->xorigin[ix][iy]+1 , grapher->yorigin[ix][iy]+1 ,
2112 grapher->gx-2 , grapher->gy-2 ,
2113 fade_color ) ;
2114 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ; /* must reset */
2115 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
2116 }
2117
2118 #if 0
2119 if( grapher->transform0D_func != NULL )
2120 # if 0
2121 grapher->transform0D_func( tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
2122 # else
2123 AFNI_CALL_0D_function( grapher->transform0D_func ,
2124 tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
2125 # endif
2126 #endif
2127
2128 jv = iv ; if( jv >= tsim->nx ) jv = tsim->nx - 1 ;
2129 AV_fval_to_char( MRI_FLOAT_PTR(tsim)[jv] , str ) ;
2130 mri_free(tsim) ;
2131 strp = (str[0] == ' ') ? str+1 : str ;
2132 www = DC_text_width(grapher->dc,strp) ; /* for centering, below */
2133
2134 fd_txt( grapher , grapher->xorigin[ix][iy] + (grapher->gx-www)/2 ,
2135 grapher->yorigin[ix][iy] + 2 ,
2136 strp ) ;
2137 }
2138 }
2139
2140 EXRETURN ;
2141 }
2142
2143 /*-----------------------------------------------------------------------------*/
2144 /* Find the smallest/largest values in these images, for plotting [01 Jun 2020]
2145 Usage is tsim = main plot
2146 qim = double plot
2147 Either (or both) images can be NULL.
2148 Smallest/largest values are found over index range tbot..ttop-1.
2149 *//*--------------------------------------------------------------------------*/
2150
GRA_find_range(int tbot,int ttop,int tstep,MRI_IMAGE * tsim,MRI_IMAGE * qim)2151 float_pair GRA_find_range( int tbot, int ttop, int tstep, MRI_IMAGE *tsim , MRI_IMAGE *qim )
2152 {
2153 int tt , i , ibot=tbot , itop , first=1 ;
2154 float *far , tsbot=0.0f , tstop=0.0f ; float_pair tsout ;
2155
2156 ENTRY("GRA_find_range") ;
2157
2158 if( tstep < 1 ) tstep = 1 ; /* just to be safe */
2159
2160 if( tsim != NULL && tsim->nx > 1 ){ /* scan first image */
2161 far = MRI_FLOAT_PTR(tsim) ;
2162 itop = MIN( ttop , tsim->nx ) ;
2163 if( first && ibot < itop ){ tsbot = tstop = far[ibot] ; first = 0 ; }
2164 for( tt=0 ; tt < tsim->ny ; tt++ ){
2165 for( i=ibot ; i < itop ; i+=tstep ){
2166 tsbot = MIN( tsbot , far[i] ) ;
2167 tstop = MAX( tstop , far[i] ) ;
2168 }
2169 far += tsim->nx ;
2170 }
2171 }
2172
2173 if( qim != NULL && qim->nx > 1 ){ /* scan second image */
2174 far = MRI_FLOAT_PTR(qim) ;
2175 itop = MIN( ttop , qim->nx ) ;
2176 if( first && ibot < itop ){ tsbot = tstop = far[ibot] ; first = 0 ; }
2177 for( tt=0 ; tt < qim->ny ; tt++ ){
2178 for( i=ibot ; i < itop ; i+=tstep ){
2179 tsbot = MIN( tsbot , far[i] ) ;
2180 tstop = MAX( tstop , far[i] ) ;
2181 }
2182 far += qim->nx ;
2183 }
2184 }
2185
2186 tsout.a = tsbot ; tsout.b = tstop ; RETURN(tsout) ;
2187 }
2188
2189 /*-----------------------------------------------------------------------------*/
2190 /*! From the 'Detrend' menu */
2191
GRA_detrend_CB(MCW_arrowval * av,XtPointer cd)2192 void GRA_detrend_CB( MCW_arrowval *av , XtPointer cd ) /* 05 Dec 2012 */
2193 {
2194 MCW_grapher *grapher = (MCW_grapher *)cd ; int avd ;
2195
2196 ENTRY("GRA_detrend_CB") ;
2197
2198 if( ! GRA_VALID(grapher) ) EXRETURN ;
2199 avd = av->ival ; if( avd == grapher->detrend ) EXRETURN ;
2200 grapher->detrend = avd ;
2201 redraw_graph( grapher , 0 ) ;
2202 EXRETURN ;
2203 }
2204
2205 /*----------------------------------------------------------------------------*/
2206 /* Detrend each column of an image (L1, for robustness to outliers) */
2207
GRA_detrend_im(int dord,MRI_IMAGE * im)2208 static void GRA_detrend_im( int dord , MRI_IMAGE *im ) /* 05 Dec 2012 */
2209 {
2210 int jy , nx,ny ; float *iar ;
2211
2212 if( dord < 0 || im == NULL || im->kind != MRI_float ) return ;
2213 iar = MRI_FLOAT_PTR(im) ; if( iar == NULL ) return ;
2214 nx = im->nx ; ny = im->ny ; if( dord > nx+1 ) return ;
2215 for( jy=0 ; jy < ny ; jy++ )
2216 THD_generic_detrend_L1( nx , iar+(jy*nx) , dord , 0,NULL,NULL ) ;
2217
2218 return ;
2219 }
2220
2221 #if 0
2222 /*-----------------------------------------------------------------------------*/
2223 /* Detrend each column of each image [no longer used] */
2224
2225 static void GRA_detrend_imarr( int dord , MRI_IMARR *imar ) /* 05 Dec 2012 */
2226 {
2227 int ii ;
2228
2229 if( imar == NULL ) return ;
2230 for( ii=0 ; ii < IMARR_COUNT(imar) ; ii++ )
2231 GRA_detrend_im( dord , IMARR_SUBIM(imar,ii) ) ;
2232
2233 return ;
2234 }
2235 #endif
2236
2237 /*-----------------------------------------------------------
2238 Plot real graphs to pixmap [lots of code here]
2239 This is where the most of the 'fun' or 'work' is.
2240 -------------------------------------------------------------*/
2241
plot_graphs(MCW_grapher * grapher,int code)2242 void plot_graphs( MCW_grapher *grapher , int code )
2243 {
2244 MRI_IMAGE *tsim , *qim=NULL;
2245 MRI_IMARR *tsimar=NULL ;
2246 float *tsar , *qar=NULL;
2247 float tsbot=0.0f, xpfac=0.0f, ypfac,fwid,foff , tstop ;
2248 int i, m, index, ix, iy, xtemp,ytemp,ztemp, xoff=0,yoff=0, its,ibot,itop;
2249 int ptop,pbot,pnum,qnum , ntmax , qq ; /* 17 Mar 2004 */
2250
2251 int pstep =1 , nstep=0 ; /* stride thru data */
2252 int nupsam=0 ; /* 28 May 2020 */
2253 float_pair tsrange ; /* 01 Jun 2020 */
2254 int ntstemp=0 ;
2255 static float *tstemp=NULL ; /* 09 Jun 2020 */
2256
2257 static int *plot = NULL ; /* arrays to hold plotting coordinates */
2258 static XPoint *a_line = NULL ; /* one XPoint = (x,y) coords of one point in window */
2259 static int nplot_old = 0 ;
2260
2261 /* stuff for plotting along an arbitrary x-axis,
2262 as opposed to the equal spacing provided by default */
2263
2264 MRI_IMAGE *xxim=NULL, *xxim_cen=NULL , *xax_tsim=NULL ; /* 10 Feb 2015 */
2265 MRI_IMARR *xximar=NULL ;
2266 int do_xxim=0 ;
2267 double_pair xax_minmax ; float xax_tsim_bot=0.0f , xax_tsim_top=0.0f ;
2268
2269 /* boxes? box labels? */
2270 int do_boxes=0 , do_boxlab=0 ;
2271
2272 /* stuff for extra (overlaying) plots,
2273 in addition to the standard underlay plots */
2274
2275 MRI_IMARR *dplot_imar = NULL ; /* 08 Nov 1996 - for double plot */
2276 int dplot = 0 ;
2277 int pmplot_mode = 0 ; /* 01 Jun 2020 - new PLUSMINUS plot modes */
2278 int pmplot_color= 1 ;
2279
2280 /* stuff for extra (above) plots -- FIM and ORTs (very old stuff) */
2281
2282 MRI_IMARR *eximar = NULL ;
2283 int iex ;
2284
2285 /* things for setting the vertical scale between data and pixels */
2286
2287 float nd_bot=0 , nd_top=0 , nd_dif=0 ; /* 03 Feb 1998 */
2288 int set_scale = ( (code & PLOTCODE_AUTOSCALE) != 0 ||
2289 grapher->never_drawn ) ;
2290
2291 MRI_IMAGE *dsim ; /* 07 Aug 2001: also for double plot */
2292 float *dsar ;
2293
2294 #define OVI_MAX 19
2295 int tt, use_ovi, ovi[OVI_MAX] ; /* 29 Mar 2002: for multi-plots */
2296
2297 /*----- START OF EXECUTABLE CODE -----*/
2298
2299 ENTRY("plot_graphs") ;
2300 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
2301
2302 /* check if we draw text instead of curves */
2303
2304 if( grapher->status->num_series < 1 ){
2305 EXRETURN ;
2306 } else if( grapher->status->num_series == 1 ||
2307 grapher->textgraph || TPTS(grapher) < 2 ){
2308 text_graphs( grapher ) ; /* that was easy */
2309 EXRETURN ;
2310 }
2311
2312 /* for the x-axis specified by a time series file */
2313
2314 if( grapher->xax_tsim != NULL ){
2315 xax_tsim = mri_copy(grapher->xax_tsim) ; /* scaled local copy */
2316 GRA_fixup_xaxis( grapher , xax_tsim ) ; /* 09 Jan 1998 */
2317
2318 xax_minmax = mri_minmax( grapher->xax_tsim ) ;
2319 xax_tsim_bot = xax_minmax.a ;
2320 xax_tsim_top = xax_minmax.b ;
2321 }
2322
2323 mri_free(grapher->xax_cen) ; grapher->xax_cen = NULL ; /* 12 Feb 2015 */
2324
2325 /* special things to 'do' */
2326
2327 do_boxes = DATA_BOXED(grapher) ;
2328 do_boxlab = DATA_BOXLAB_CODE(grapher) ;
2329 do_xxim = (grapher->xax_fdbr != NULL) && !do_boxes ;
2330
2331 /* set colors and line widths [these alter the myGC X11 graphics context] */
2332
2333 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ;
2334 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
2335
2336 /* 17 Mar 2004: we will plot with x-axis = pbot..ptop-1 */
2337 /* Jun 2020: with stride of pstep [for Gang Chen] */
2338
2339 ptop = NTOP(grapher) ; pbot = NBOT(grapher) ; pstep = NSTRIDE(grapher) ;
2340 if( pbot >= ptop ){
2341 pbot = 0 ; ptop = grapher->status->num_series ;
2342 }
2343 if( pstep > 1 ){ /* adjust ptop so that pbot..ptop-1 */
2344 nstep = NABC(pbot,ptop,pstep) ; /* is an integer number of steps */
2345 if( nstep < 2 ){ grapher->pin_stride = pstep = 1 ; }
2346 else { ptop = pbot + (nstep-1)*pstep + 1 ; }
2347 }
2348 if( ptop <= pbot || ptop > grapher->status->num_series ){
2349 ptop = MIN(ptop,grapher->status->num_series) ;
2350 }
2351 pnum = NABC(pbot,ptop,pstep) ; /* number of data points to plot */
2352 if( pnum <= 1 ) EXRETURN ; /* should never happen?! */
2353
2354 /* how much to upsample the lines between data values? */
2355
2356 if( DO_UPSAM(grapher) ){ /* for smoothing [28 May 2020] */
2357 nupsam = XUPSAM(grapher->gx,pnum) ; /* XUPSAM is in afni_graph.h */
2358 if( nupsam > 1 && xxim != NULL ) nupsam *= 2 ; /* ad hoc */
2359 }
2360
2361 /* set aside static memory for plotting, etc. */
2362
2363 #define NPLOT_INIT 9999 /* 29 Apr 1997 */
2364 itop = MAX( NPLOT_INIT , grapher->status->num_series ) ;
2365 if( nplot_old == 0 || nplot_old < itop ){ /* probably only executed once */
2366 myXtFree(a_line) ; myXtFree(plot) ; /* unless a LOT of data comes in later */
2367 nplot_old = 2*itop+666 ; /* just to be safe */
2368 plot = (int *) XtMalloc( sizeof(int) * nplot_old ) ;
2369 a_line = (XPoint *) XtMalloc( sizeof(XPoint) * nplot_old ) ;
2370 tstemp = (float *) malloc ( sizeof(float) * nplot_old ) ; /* 09 Jun 2020 */
2371 }
2372 if( grapher->ncen_line < itop ){
2373 myXtFree(grapher->cen_line) ;
2374 grapher->cen_line = (XPoint *) XtMalloc( sizeof(XPoint) * itop ) ;
2375 grapher->ncen_line = itop ;
2376 }
2377
2378 /* set the bottom point (ibot) at which to compute time series statistics */
2379
2380 ibot = NIGNORE(grapher) ; /* first non-ignored data point */
2381 if( pstep > 1 ) ibot = 0 ; /* disable ignore for strides > 1 */
2382 if( ibot >= ptop-1 ) ibot = 0 ; /* disable ignore if too long */
2383 ibot = MAX(ibot,pbot) ;
2384
2385 /** loop over matrix of graphs and get all the time series for later use **/
2386
2387 INIT_IMARR(tsimar) ; /* image array to store the data time series */
2388
2389 if( do_xxim ) INIT_IMARR(xximar) ; /* to store x-axis time series, if needed */
2390
2391 /** 08 Nov 1996: initialize second array for double plotting **/
2392 /** 07 Aug 2001: modify to allow for multiple dplot cases **/
2393 /** Double plotting is implemented by 'transforms' of the input data, **/
2394 /** which in the case of Dataset#N simply provides entirely new data. **/
2395 /** Why this way? Because transforms already existed in the code. **/
2396
2397 if( grapher->transform1D_func != NULL &&
2398 MCW_val_bbox(grapher->opt_dplot_bbox) != DPLOT_OFF ){
2399
2400 STATUS(" initialize graph for DPLOT") ;
2401
2402 INIT_IMARR(dplot_imar) ;
2403 dplot = MCW_val_bbox(grapher->opt_dplot_bbox) ; /* 07 Aug 2001 */
2404 }
2405
2406 /* how to do the plus/minus double plot overlay [01 Jun 2020] */
2407 /* Cannot do pmplot with non-standard x-axis! */
2408
2409 pmplot_mode = 0 ;
2410 if( dplot && !do_xxim && xax_tsim == NULL ){
2411 pmplot_mode = PMPLOT_MODE(grapher) ; if( pmplot_mode == 1 ) pmplot_mode = 0;
2412 pmplot_color = PMPLOT_COLOR(grapher);
2413 }
2414
2415 /* clear the time series statistics etc. for this array of time series */
2416
2417 GRA_CLEAR_tuser( grapher ) ; /* 22 Apr 1997 */
2418
2419 /* 3D index offset to correct slice number */
2420 ztemp = grapher->zpoint * grapher->status->ny * grapher->status->nx ;
2421
2422 ntmax = 0 ; /* will be length of longest time series found below */
2423
2424 /**--- double loop to get the data for the (ix,iy)-th sub-graph ---**/
2425
2426 for( ix=0 ; ix < grapher->mat ; ix++ ){ /* get data for the 'main' plots */
2427
2428 /** compute the 3D index of the desired time series **/
2429
2430 xtemp = grapher->xpoint + ix - grapher->xc ;
2431 if( xtemp < 0 ) xtemp += grapher->status->nx ; /* wrap */
2432 else if( xtemp >= grapher->status->nx ) xtemp -= grapher->status->nx ;
2433
2434 for( iy=0 ; iy < grapher->mat ; iy++ ){
2435
2436 ytemp = grapher->ypoint - iy + grapher->yc ;
2437 if( ytemp < 0 ) ytemp += grapher->status->ny; /* wrap */
2438 else if( ytemp >= grapher->status->ny ) ytemp -= grapher->status->ny;
2439
2440 index = ztemp + ytemp * grapher->status->nx + xtemp ; /* 3D index in dataset */
2441
2442 /** get the desired time series, using the provided routine **/
2443
2444 tsim = GRA_getseries( grapher , index ) ; /* this is kind of important */
2445
2446 if( do_xxim ){ /* 10 Feb 2015 */
2447 xxim = GRA_getseries_xax( grapher , index ) ; /* for user-supplied */
2448 if( ix == grapher->xc && iy == grapher->yc ){ /* x-axis from a */
2449 xxim_cen = xxim ; /* dataset */
2450 mri_free(grapher->xax_cen) ; grapher->xax_cen = mri_copy(xxim) ;
2451 }
2452 xax_minmax = mri_minmax( xxim ) ;
2453 grapher->xax_bot[ix][iy] = xax_minmax.a ; /* get the min/max of */
2454 grapher->xax_top[ix][iy] = xax_minmax.b ; /* x-axis for (ix,iy) */
2455 GRA_fixup_xaxis( grapher , xxim ) ; /* scale to range 0..1 */
2456 ADDTO_IMARR(xximar,xxim) ; /* save for graphing */
2457 } else if( xax_tsim != NULL ){
2458 grapher->xax_bot[ix][iy] = xax_tsim_bot ; /* for user-supplied */
2459 grapher->xax_top[ix][iy] = xax_tsim_top ; /* x-axis from a 1D file */
2460 }
2461
2462 /* 08 Nov 1996: allow for return of NULL data timeseries */
2463
2464 if( tsim == NULL ){
2465 ADDTO_IMARR(tsimar,NULL) ;
2466 if( dplot_imar != NULL ) ADDTO_IMARR(dplot_imar,NULL) ;
2467 continue ; /* skip to next iy */
2468 }
2469
2470 ntmax = MAX( ntmax , tsim->nx ) ;/* longest time series seen to here */
2471
2472 /* 22 Oct 1996: transform each point, if ordered */
2473
2474 if( grapher->transform0D_func != NULL ){ /* 0D = pointwise in place */
2475 STATUS("about to perform 0D transformation") ;
2476 AFNI_CALL_0D_function( grapher->transform0D_func ,
2477 tsim->nx , MRI_FLOAT_PTR(tsim) ) ;
2478 }
2479
2480 /* 03 Nov 1996: 1D transformations, too [more cases to manage] */
2481 /* 08 Nov 1996: double plotting, too */
2482 /* that is, the 'transformation' can */
2483 /* just be an entirely new time series */
2484
2485 if( grapher->transform1D_func != NULL ){
2486
2487 if( dplot ){ /* copy and save original */
2488 qim = mri_to_float(tsim) ; /* if double plot is on */
2489 ADDTO_IMARR(dplot_imar,qim) ; /* so we can plot original */
2490 } /* and the 'transformed' */
2491 else
2492 qim = tsim ; /* just transform original image */
2493
2494 STATUS("about to perform 1D transformation") ;
2495
2496 /* 1D transform functions are coded with binary
2497 flags, which indicate how they are to be used here */
2498
2499 if( grapher->transform1D_flags & NEEDS_DSET_INDEX ){ /* 18 May 2000 */
2500 #ifdef BE_AFNI_AWARE /* if afni_graph.c is compiled for use with AFNI GUI */
2501 FD_brick *br=(FD_brick *)grapher->getaux ; THD_ivec3 id ;
2502 id = THD_fdind_to_3dind( br ,
2503 TEMP_IVEC3(xtemp,ytemp,grapher->zpoint) );
2504 AFNI_store_dset_index(
2505 id.ijk[0]
2506 +id.ijk[1] * br->nxyz.ijk[0]
2507 +id.ijk[2] * br->nxyz.ijk[0] * br->nxyz.ijk[1] , 0 ) ;
2508 #else
2509 AFNI_store_dset_index(-1,0) ; /* older dumbshit code */
2510 #endif
2511 }
2512
2513 /* over the centuries, the number of ways to
2514 call a 1D transform function kept metastasizing :( */
2515
2516 if( ! (grapher->transform1D_flags & PROCESS_MRI_IMAGE) ){ /* older code: */
2517 /* process image */
2518 if( ! (grapher->transform1D_flags & RETURNS_STRING) ){ /* contents only */
2519 AFNI_CALL_1D_function( grapher->transform1D_func ,
2520 qim->nx , qim->xo , qim->dx , /* just change */
2521 MRI_FLOAT_PTR(qim) ) ; /* the data */
2522 } else {
2523 char *quser = NULL ;
2524 AFNI_CALL_1D_funcstr( grapher->transform1D_func , /* also returns */
2525 qim->nx , qim->xo , qim->dx , /* a string */
2526 MRI_FLOAT_PTR(qim) , quser ) ;
2527 if( quser != NULL )
2528 grapher->tuser[ix][iy] = XtNewString(quser) ; /* save string */
2529 }
2530
2531 } else { /* 28 Mar 2002: process MRI_IMAGE struct */
2532 /* in place */
2533 if( ! (grapher->transform1D_flags & RETURNS_STRING) ){
2534 AFNI_CALL_1D_funcmrim( grapher->transform1D_func , qim ) ;
2535 } else {
2536 char *quser = NULL ;
2537 AFNI_CALL_1D_funcmrimstr( grapher->transform1D_func , qim,quser ) ;
2538 if( quser != NULL )
2539 grapher->tuser[ix][iy] = XtNewString(quser) ;
2540 }
2541
2542 } /* OK, the transformation/replacement of qim has happened */
2543
2544 /* 04 Oct 2007: discard double-plotted data when
2545 the transformation changed nothing */
2546
2547 if( dplot && mri_equal(tsim,qim) ){ /* every point is equal */
2548 mri_free(qim) ; qim = NULL ; /* dplot is on, so qim is not tsim */
2549 IMARR_SUBIM( dplot_imar , IMARR_COUNT(dplot_imar)-1 ) = NULL ;
2550 }
2551
2552 /* if this is a plus/minus double plot, we need to do some
2553 surgery on qim now:
2554 to make it 2 curves with tsim+qim and tsim-qim.
2555 So there is a double 'transformation':
2556 get the pmplot data into qim (from above)
2557 then convert it to qqim with 2 curves (below)
2558 and then pull a switcheroo, throwing qim away */
2559
2560 if( pmplot_mode && qim != NULL ){ /* 01 Jun 2020 */
2561 MRI_IMAGE *qqim; float *qqar,*qar ; int kk,nx ;
2562 nx = MIN( tsim->nx , qim->nx ) ; /* length of substitute */
2563 qqim = mri_new( nx , 2 , MRI_float ) ; /* substitute image */
2564 qqar = MRI_FLOAT_PTR(qqim) ; /* data in substitute */
2565 tsar = MRI_FLOAT_PTR(tsim) ; /* data in base */
2566 qar = MRI_FLOAT_PTR(qim) ; /* data in plus/minus */
2567 for( kk=0 ; kk < nx ; kk++ ){
2568 qqar[kk+0*nx] = tsar[kk] + qar[kk] ; /* plus */
2569 qqar[kk+1*nx] = tsar[kk] - qar[kk] ; /* minus */
2570 }
2571 mri_free(qim) ; qim = qqim ; /* get rid of qim, substitute it */
2572 IMARR_SUBIM( dplot_imar , IMARR_COUNT(dplot_imar)-1 ) = qim ;
2573 }
2574
2575 /* if we are detrending data time series,
2576 also detrend the other data to plot (if any) */
2577
2578 if( qim != tsim ) GRA_detrend_im( grapher->detrend , qim ) ;
2579
2580 /* At this point, qim is transformed and saved:
2581 if dplot is on, then qim was saved in dplot_imar earlier;
2582 if dplot is off, then qim==tsim, will be saved in tsimar below */
2583
2584 } /* end of transform1D (at last) */
2585
2586 /* detrend data and then put this base image on list of those to plot */
2587
2588 GRA_detrend_im( grapher->detrend , tsim ) ;
2589 ADDTO_IMARR(tsimar,tsim) ;
2590 }
2591 } /** end of double loop to get data for sub-graphs **/
2592
2593 /** find the average data time series, for fun and profit [27 Jan 2004] **/
2594
2595 if( ntmax > 1 && IMARR_COUNT(tsimar) > 0 ){
2596 float *avar , fac ; int nax , nts=0 ;
2597 STATUS("about to make average time series") ;
2598 if( grapher->ave_tsim != NULL ) mri_free(grapher->ave_tsim) ;
2599 grapher->ave_tsim = mri_new( ntmax , 1 , MRI_float ) ;
2600 avar = MRI_FLOAT_PTR(grapher->ave_tsim) ; /* is full of 0's already */
2601 for( ix=0 ; ix < IMARR_COUNT(tsimar) ; ix++ ){
2602 tsim = IMARR_SUBIMAGE(tsimar,ix) ; if( tsim == NULL ) continue ;
2603 tsar = MRI_FLOAT_PTR(tsim) ; if( tsar == NULL ) continue ;
2604 nax = MIN( ntmax , tsim->nx ) ;
2605 for( i=0 ; i < nax ; i++ ) avar[i] += tsar[i] ;
2606 nts++ ;
2607 }
2608 fac = 1.0f / MAX(nts,1) ; /* in case there isn't any data! */
2609 for( i=0 ; i < grapher->ave_tsim->nx ; i++ ) avar[i] *= fac ;
2610
2611 /* substitute new average into the
2612 FIM reference timeseries if that bbox is selected */
2613
2614 if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) ){
2615 if( grapher->ref_ts == NULL ) INIT_IMARR( grapher->ref_ts ) ;
2616 if( IMARR_COUNT(grapher->ref_ts) == 0 ){
2617 ADDTO_IMARR( grapher->ref_ts , grapher->ave_tsim ) ; /* create first one */
2618 } else {
2619 IMARR_SUBIMAGE(grapher->ref_ts,0) = grapher->ave_tsim ; /* replace first one */
2620 }
2621 }
2622
2623 } else if( grapher->ave_tsim != NULL ){
2624 mri_free(grapher->ave_tsim) ; grapher->ave_tsim = NULL ; /* no data to average */
2625 }
2626
2627 /** find some statistics of each time series [for popup 'menu'] **/
2628
2629 STATUS("finding statistics of time series") ;
2630
2631 /* stuff for setting vertical scale */
2632
2633 nd_bot = WAY_BIG ; nd_top = nd_dif = - WAY_BIG ; /* 03 Feb 1998 */
2634
2635 /* set the default entries for time series stat values,
2636 which is necessary if some sub-graphs don't return any data */
2637
2638 #define DEFAULT_TSTAT(i,j) \
2639 do{ grapher->tmean[i][j] = grapher->tbot[i][j] = \
2640 grapher->ttop[i][j] = grapher->tstd[i][j] = 0.0f; \
2641 grapher->tmed[i][j] = grapher->tmad[i][j] = 0.0f; \
2642 grapher->sbot[i][j] = grapher->stop[i][j] = 0 ; \
2643 grapher->tbmv[i][j] = 0.0f ; \
2644 grapher->dbot[i][j] = 0.0f ; \
2645 grapher->dtop[i][j] = 0.0f ; \
2646 grapher->tsnr[i][j] = 0.0f ; \
2647 } while(0)
2648
2649 /** double loop to statistic-ate each time series
2650 (just the parts being plotted, by the way) **/
2651
2652 for( ix=0,its=0 ; ix < grapher->mat ; ix++ ){
2653 for( iy=0 ; iy < grapher->mat ; iy++,its++ ){
2654 float qbot,qtop ;
2655 double qsum , qsumq ;
2656
2657 tsim = IMARR_SUBIMAGE(tsimar,its) ; /* the data */
2658 DEFAULT_TSTAT(ix,iy) ; /* zero out stats */
2659 if( tsim == NULL || tsim->nx < 2 ) continue ; /* skip ahead */
2660
2661 itop = MIN( ptop , tsim->nx ) ; /* ibot was set earlier */
2662 nstep = NABC(ibot,itop,pstep) ; /* number of data points */
2663 if( nstep < 2 ) continue ;
2664 tsar = MRI_FLOAT_PTR(tsim) ; /* do stats from ibot..itop-1 */
2665 if( tsar == NULL ) continue ; /* should NEVER happen */
2666
2667 qbot = qtop = tsar[ibot] ;
2668 qsum = qsumq = 0.0 ;
2669 for( ntstemp=0,i=ibot ; i < itop ; i+=pstep ){ /* compute stats over visible data */
2670 qbot = MIN( qbot , tsar[i] ) ;
2671 qtop = MAX( qtop , tsar[i] ) ;
2672 qsum += tsar[i] ;
2673 qsumq += tsar[i] * tsar[i] ;
2674 tstemp[ntstemp++] = tsar[i] ; /* temp save data for qmedmadbmv below */
2675 }
2676 grapher->tbot[ix][iy] = qbot ; grapher->ttop[ix][iy] = qtop ;
2677 grapher->sbot[ix][iy] = ibot ; grapher->stop[ix][iy] = i-pstep ;
2678 qsum = qsum / ntstemp ; grapher->tmean[ix][iy] = qsum ;
2679 qsumq = (qsumq - ntstemp * qsum * qsum) / (ntstemp-0.999999) ;
2680 grapher->tstd[ix][iy] = (qsumq > 0.0) ? sqrt(qsumq) : 0.0 ;
2681 grapher->tsnr[ix][iy] = (qsumq > 0.0) ? fabs(qsum) / grapher->tstd[ix][iy]
2682 : 0.0 ;
2683 if( grapher->tsnr[ix][iy] > 9999.9f ) grapher->tsnr[ix][iy] = 9999.9f ;
2684
2685 /* these statistics require a contiguous array = tstemp */
2686 qmedmadbmv_float( ntstemp , tstemp , /* 08 Mar 2001 */
2687 &(grapher->tmed[ix][iy]) ,
2688 &(grapher->tmad[ix][iy]) ,
2689 &(grapher->tbmv[ix][iy]) ) ; /* tbmv: 16 Oct 2009 */
2690
2691 /* get range of values to be plotted in this sub-graph [01 Jun 2020] */
2692 /* - the old way was just to use the range of tsim,
2693 but now us advanced types use the range of all the data shown :) */
2694
2695 qim = (dplot_imar != NULL) ? IMARR_SUBIMAGE(dplot_imar,its) : NULL ;
2696 tsrange = GRA_find_range( ibot,itop,pstep , tsim , qim ) ;
2697 grapher->dbot[ix][iy] = tsrange.a ;
2698 grapher->dtop[ix][iy] = tsrange.b ;
2699
2700 /* and set the global values for ranges (for scale calculation) */
2701
2702 nd_bot = MIN( nd_bot , tsrange.a ) ; /* smallest bottom */
2703 nd_top = MAX( nd_top , tsrange.b ) ; /* largest top */
2704 nd_dif = MAX( nd_dif , (tsrange.b-tsrange.a) ) ; /* largest range */
2705 }
2706 } /* end of loops over statistification of time series */
2707
2708 /* 03 Feb 1998: set the vertical scale factor (maybe) */
2709
2710 if( set_scale && nd_bot < nd_top && nd_dif > 0.0f ){
2711
2712 /* here, fscale will be the number of pixels per data value */
2713
2714 switch( grapher->common_base ){
2715 default:
2716 case BASELINE_INDIVIDUAL:
2717 grapher->fscale = 0.9f * grapher->gy / nd_dif ; /* biggest range */
2718 break ;
2719
2720 case BASELINE_COMMON:
2721 grapher->fscale = 0.9f * grapher->gy / (nd_top-nd_bot) ; /* global range */
2722 break ;
2723
2724 case BASELINE_GLOBAL:{
2725 float vbot = (nd_top > grapher->global_base)
2726 ? grapher->global_base : nd_bot ;
2727 grapher->fscale = 0.9f * grapher->gy / (nd_top-vbot) ;
2728 }
2729 break ;
2730 }
2731
2732 /** switcheroo on fscale (holdover from old FD program):
2733 fscale > 0 ==> this many pixels per unit of tsar
2734 fscale < 0 ==> this many units of tsar per pixel **/
2735
2736 if( grapher->fscale > 0.0f && grapher->fscale < 1.0f )
2737 grapher->fscale = -1.0f / grapher->fscale ;
2738
2739 if( grapher->fscale > 4.0f ) /* make it an integer */
2740 grapher->fscale = (int) grapher->fscale ;
2741
2742 else if( grapher->fscale > 1.0f ) /* or a half-integer */
2743 grapher->fscale = 0.5f * ((int)(2.0f*grapher->fscale)) ;
2744
2745 else if( grapher->fscale < -4.0f ) /* ditto for the negatives */
2746 grapher->fscale = -((int)(1.0f-grapher->fscale)) ;
2747
2748 else if( grapher->fscale < -1.0f )
2749 grapher->fscale = -0.5f * ((int)(1.0f-2.0f*grapher->fscale)) ;
2750 }
2751
2752 /** if it will be the same for all graphs,
2753 set the bottom magnitude for them all now = tsbot **/
2754
2755 if( grapher->common_base == BASELINE_COMMON ){
2756 tsbot = nd_bot ;
2757 } else if( grapher->common_base == BASELINE_GLOBAL ){
2758 tsbot = grapher->global_base ;
2759 }
2760
2761 /* do something to mark infra-threshold voxels [Mar 2013] */
2762 /* note that this is done before plotting graphs, so that it
2763 appears as background color - X11 has no idea about translucency */
2764
2765 if( grapher->thresh_fade ){
2766 for( ix=0,its=0 ; ix < grapher->mat ; ix++ ){
2767 for( iy=0 ; iy < grapher->mat ; iy++,its++ ){
2768 tsim = IMARR_SUBIMAGE(tsimar,its) ;
2769 if( tsim == NULL || tsim->flags == 0 ){
2770 rectangle_fdX( grapher ,
2771 grapher->xorigin[ix][iy]+1 , grapher->yorigin[ix][iy]+1 ,
2772 grapher->gx-2 , grapher->gy-2 ,
2773 fade_color ) ;
2774 }
2775 }
2776 }
2777 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ; /* must reset */
2778 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ; /* drawing colors */
2779 }
2780
2781 /**** loops over matrix of graphs and plot them all to the pixmap ****/
2782
2783 STATUS("starting time series graph loop") ;
2784 for( ix=0,its=0 ; ix < grapher->mat ; ix++ ){
2785
2786 for( iy=0 ; iy < grapher->mat ; iy++,its++ ){
2787
2788 tsim = IMARR_SUBIMAGE(tsimar,its) ;
2789 if( tsim == NULL || tsim->nx < 2 ) continue ; /* skip to next iy */
2790
2791 itop = MIN( ptop , tsim->nx ) ; /* ibot was set earlier */
2792 qnum = NABC(pbot,itop,pstep) ; /* number of points to plot */
2793 if( qnum < 2 ) continue ; /* skip if too few */
2794
2795 qim = (dplot_imar != NULL && pmplot_mode ) /* PLUSMINUS */
2796 ? IMARR_SUBIMAGE(dplot_imar,its) : NULL ; /* data */
2797
2798 /* stuff for user-supplied x-axis */
2799 if( do_xxim ) xxim = IMARR_SUBIMAGE(xximar,its) ; /* 10 Feb 2015 */
2800 else xxim = xax_tsim ; /* might be NULL */
2801
2802 /** find bottom value for this graph, if needed;
2803 otherwise, tsbot for all graphs was set above **/
2804
2805 if( grapher->common_base == BASELINE_INDIVIDUAL ){
2806 tsbot = grapher->dbot[ix][iy] ;
2807 }
2808 grapher->pmin[ix][iy] = tsbot ; /* value at graph bottom */
2809
2810 /** 29 Mar 2002: decode 'color:' from tsim->name, if present **/
2811
2812 use_ovi = (tsim->name!=NULL) && (strncmp(tsim->name,"color: ",7)==0) ;
2813 if( use_ovi ){
2814 char *cpt = tsim->name+6 ; int nuse, ngood ;
2815 for( tt=0 ; tt < OVI_MAX ; tt++ )
2816 ovi[tt] = DATA_COLOR(grapher) ;
2817 for( tt=0 ; tt < OVI_MAX ; tt++ ){
2818 ngood = sscanf(cpt,"%d%n",ovi+tt,&nuse) ;
2819 if( ngood < 1 ) break ;
2820 cpt += nuse ; if( *cpt == '\0' ) break ;
2821 }
2822 }
2823
2824 /** set ypfac = scale factor for vertical (y):
2825 fscale > 0 ==> this many pixels per unit of tsar
2826 fscale < 0 ==> this many units of tsar per pixel **/
2827
2828 ypfac = grapher->fscale ;
2829 if( ypfac == 0.0 ) ypfac = 1.0f ; /* should not happen */
2830 else if( ypfac < 0.0 ) ypfac = -1.0f / ypfac ;
2831
2832 xpfac = grapher->gx / (pnum-1.0f) ; /* x scale factor */
2833
2834 /* X11 pixel box for graph: (y runs DOWN the screen)
2835 x = xorigin[ix][iy] .. xorigin[ix][iy]+gx (L..R)
2836 y = fHIGH-yorigin[ix][iy]-gy .. fHIGH-yorigin[ix][iy] (T..B) */
2837
2838 xoff = grapher->xorigin[ix][iy] ; /* offsets */
2839 yoff = grapher->fHIGH - grapher->yorigin[ix][iy] ;
2840
2841 tsar = MRI_FLOAT_PTR(tsim) ; /* data to be plotted */
2842 qar = MRI_FLOAT_PTR(qim) ; /* will be NULL if image is NULL */
2843
2844 /* do the plus/minus double plot first [01 Jun 2020],
2845 since we will want to draw all later stuff on top of it */
2846
2847 if( pmplot_mode && qar != NULL && qim->ny == 2 ){
2848 int jtop = MIN(ptop,qim->nx) , jnum = NABC(pbot,jtop,pstep) ;
2849 if( jnum > 1 ){
2850 XPoint *d_line, *e_line, *f_line ; int nd_line = jnum+66 ;
2851 d_line = (XPoint *)malloc(sizeof(XPoint)*nd_line) ; /* allocate space */
2852 e_line = (XPoint *)malloc(sizeof(XPoint)*nd_line) ; /* for X11 points */
2853 /*--- plus lines = d_line array ---*/
2854 for( qq=0,i=pbot ; i < MIN(ibot,jtop) ; i+=pstep,qq++ ) /* pre-ignore */
2855 plot[qq] = (tsar[ibot] - tsbot) * ypfac ; /* just plot first value */
2856 for( ; i < jtop ; i+=pstep,qq++ ) /* post-ignore */
2857 plot[qq] = (qar[i] - tsbot) * ypfac ; /* plot the actual data */
2858 jnum = qq ;
2859
2860 for( i=0 ; i < jnum ; i++ ){ /* convert to pixels */
2861 d_line[i].x = xoff + i*xpfac ;
2862 d_line[i].y = yoff - plot[i] ; /* remember: -y is UP, +y is DOWN */
2863 }
2864 /*--- minus lines = e_line array [similar to above] ---*/
2865 for( qq=0,i=pbot ; i < MIN(ibot,jtop) ; i+=pstep,qq++ ) ; /*nada */
2866 for( ; i < jtop ; i+=pstep,qq++ )
2867 plot[qq] = (qar[i+qim->nx] - tsbot) * ypfac ;
2868
2869 for( i=0 ; i < jnum ; i++ ){
2870 e_line[i].x = d_line[i].x ;
2871 e_line[i].y = yoff - plot[i] ;
2872 }
2873 /*--- graphics choices ---*/
2874 DC_fg_color ( grapher->dc , pmplot_color ) ;
2875 DC_linewidth( grapher->dc , PMPLOT_THICK(grapher) ) ;
2876 switch( pmplot_mode ){
2877 default:
2878 case PMPLOT_CURVES: /* pretty much the olden way */
2879 AFNI_XDrawLines( grapher->dc->display ,
2880 grapher->fd_pxWind , grapher->dc->myGC ,
2881 d_line , jnum , CoordModeOrigin , nupsam ) ;
2882 AFNI_XDrawLines( grapher->dc->display ,
2883 grapher->fd_pxWind , grapher->dc->myGC ,
2884 e_line , jnum , CoordModeOrigin , nupsam ) ;
2885 break ;
2886
2887 case PMPLOT_FILL:{ /* filled solid color */
2888 f_line = (XPoint *)malloc(sizeof(XPoint)*nd_line*2) ;
2889 for( i=0 ; i < jnum ; i++ ) f_line[i] = d_line[i] ;
2890 for( i=0 ; i < jnum ; i++ ) f_line[2*jnum-1-i] = e_line[i] ;
2891 AFNI_XFillPolygon( grapher->dc->display ,
2892 grapher->fd_pxWind , grapher->dc->myGC ,
2893 f_line, 2*jnum, Complex, CoordModeOrigin, nupsam ) ;
2894 free(f_line) ;
2895 }
2896 break ;
2897
2898 case PMPLOT_BARS:{ /* error bars, of a sort */
2899 XPoint q_line[6] ; short dx ; float xd ;
2900 xd = grapher->gx / ( 4.0f* jnum ) ; dx = SHORTIZE(xd) ;
2901 if( dx > 16 ) dx = 16 ;
2902 for( i=0 ; i < jnum ; i++ ){
2903 q_line[0].x = e_line[i].x - dx ; q_line[0].y = e_line[i].y ;
2904 q_line[1].x = e_line[i].x + dx ; q_line[1].y = e_line[i].y ;
2905 q_line[2].x = e_line[i].x ; q_line[2].y = e_line[i].y ;
2906 q_line[3].x = d_line[i].x ; q_line[3].y = d_line[i].y ;
2907 q_line[4].x = d_line[i].x - dx ; q_line[4].y = d_line[i].y ;
2908 q_line[5].x = d_line[i].x + dx ; q_line[5].y = d_line[i].y ;
2909 AFNI_XDrawLines( grapher->dc->display ,
2910 grapher->fd_pxWind , grapher->dc->myGC ,
2911 q_line , 6 , CoordModeOrigin , 0 ) ;
2912 }
2913 }
2914 break ;
2915 }
2916
2917 free(e_line); free(d_line); /* free the XPoint arrays */
2918 }
2919 } /* end of pmplot BEFORE tsim plot! */
2920
2921 /*-- now do the tsim plot(s) --*/
2922
2923 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ; /* reset color */
2924 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
2925
2926 for( tt=0 ; tt < tsim->ny ; tt++ ){ /* 29 Mar 2002: multi-plots in one image */
2927
2928 /* scale to vertical pixels: before the ignore level */
2929
2930 for( qq=0,i=pbot ; i < MIN(ibot,itop) ; i+=pstep,qq++ )
2931 plot[qq] = (tsar[ibot] - tsbot) * ypfac ;
2932
2933 /* scale after the ignore level */
2934
2935 for( ; i < itop ; i+=pstep,qq++ )
2936 plot[qq] = (tsar[i] - tsbot) * ypfac ;
2937
2938 qnum = qq ; /* number of points in plot */
2939
2940 /* now have qnum points in plot[] */
2941
2942 grapher->pmax[ix][iy] = tsbot + grapher->gy / ypfac ; /* value at graph top */
2943
2944 /** Compute X11 line coords from pixel heights in plot[].
2945 N.B.: X11 y is DOWN the screen, but plot[] is UP the screen **/
2946
2947 if( do_boxes )
2948 xpfac = grapher->gx / (float)pnum ; /* x scale factor */
2949 else
2950 xpfac = grapher->gx / (pnum-1.0f) ; /* x scale factor */
2951
2952 /* 09 Jan 1998: allow x-axis to be chosen by a
2953 timeseries that ranges between 0 and 1
2954 '?' == get x pixel location from xxim
2955 ':' == get x pixel lcation from time series index ii */
2956
2957 #define XPIX(ii) \
2958 ( (xxim != NULL && (ii) < xxim->nx) \
2959 ? (MRI_FLOAT_PTR(xxim)[MAX((ii),ibot)] * grapher->gx) \
2960 : (((ii)-pbot) * xpfac) )
2961
2962 for( i=0 ; i < qnum ; i++ ){ /* generate X11 plot points */
2963 a_line[i].x = xoff + XPIX(i+pbot);
2964 a_line[i].y = yoff - plot[i] ; /* X11 y-axis is down the screen */
2965 }
2966
2967 if( use_ovi ) /* 29 Mar 2002: line color */
2968 DC_fg_color( grapher->dc , ovi[tt%OVI_MAX] ) ;
2969
2970 /* macro to draw a data point of size ww (ww is set below) */
2971 #define DRAW_A_DATA_POINT(x,y) \
2972 do{ if( ww < 3 ) GRA_small_circle(grapher,(x),(y),ww>1) ; \
2973 else GRA_draw_disk (grapher,(x),(y),ww+2) ; \
2974 } while(0)
2975
2976 /* draw points at the data values? (using the above macro) */
2977
2978 if( DATA_POINTS(grapher) ){ /* 09 Jan 1998 */
2979 int ww = DATA_THICK(grapher) ;
2980 for( i=0 ; i < qnum ; i++ ) DRAW_A_DATA_POINT(a_line[i].x,a_line[i].y) ;
2981 }
2982
2983 /* draw lines connecting the data values? */
2984
2985 if( DATA_LINES(grapher) ){ /* 01 Aug 1998 */
2986 AFNI_XDrawLines( grapher->dc->display ,
2987 grapher->fd_pxWind , grapher->dc->myGC ,
2988 a_line , qnum , CoordModeOrigin , nupsam ) ;
2989 }
2990
2991 /* draw boxes for the data values? (exclusive of the above) */
2992
2993 if( do_boxes ){ /* 26 Jun 2007 */
2994 XPoint q_line[4] ; short xb,xt ; float delt=xpfac/tsim->ny ;
2995 int labw=-1,labx=-1, aybas=0 ;
2996
2997 /* setup for box labels as well */
2998
2999 if( do_boxlab && grapher->mat <= 9 ){
3000 labw = labx = DC_char_width(grapher->dc,'M') ; /* widest character */
3001 /* labx will be the x-offset for the label position,
3002 so that the label is centered above the box of width delt;
3003 Note that if labx < 0, the box is too narrow to draw labels */
3004 if( labx > 0 ) labx = (int)(0.5*(delt-labx)-1.0f) ;
3005 switch( do_boxlab ){
3006
3007 case DATA_BOXLAB_CODE_UP: /* labels start at top of highest box */
3008 for( aybas=a_line[0].y,i=1 ; i < qnum ; i++ )
3009 if( a_line[i].y < aybas ) aybas = a_line[i].y ;
3010 aybas -= BOXOFF + grapher->gthick/3 ; /* shifted up by BOXOFF, and */
3011 break ; /* allowance for thick lines */
3012
3013 case DATA_BOXLAB_CODE_BOT: /* labels start at bottom of sub-graph */
3014 aybas = yoff ;
3015 break ;
3016 }
3017 }
3018
3019 /* loop over data points and draw boxes + labels */
3020 /* note that the top of a box is shifted up by BOXOFF pixels */
3021 /* this is so that the shortest box doesn't have height=0 */
3022
3023 for( i=0 ; i < qnum ; i++ ){
3024 xb = (short)(a_line[i].x + tt*delt + 0.499f) ; /* x bot */
3025 xt = (short)(xb + delt-0.999f) ; /* x top */
3026
3027 /* setup the X11 corners of the box */
3028 q_line[0].x = xb ; q_line[0].y = yoff ; /* lower left */
3029 q_line[1].x = xb ; q_line[1].y = a_line[i].y-BOXOFF ; /* upper left */
3030 q_line[2].x = xt ; q_line[2].y = a_line[i].y-BOXOFF ; /* upper right */
3031 q_line[3].x = xt ; q_line[3].y = yoff ; /* lower right */
3032
3033 AFNI_XDrawLines( grapher->dc->display ,
3034 grapher->fd_pxWind , grapher->dc->myGC ,
3035 q_line , 4 , CoordModeOrigin , 0 ) ; /* draw box */
3036
3037 if( labx >= 0 ){ /* if labels can be fit in box width */
3038 char *lab = GRA_getlabel(grapher,pbot+i) ; /* get the label (duh) */
3039
3040 if( aybas > 0 ){ /* fixed y-location for all labels */
3041 fd_txt_upwards(grapher,xb+labx,aybas-3,lab) ;
3042 } else { /* label goes on top of individual data box; */
3043 /* adjustments of -3-grapher->gthick/3 are so */
3044 /* the label doesn't overlap the top box line */
3045 fd_txt_upwards(grapher,xb+labx,a_line[i].y-3-BOXOFF-grapher->gthick/3,lab) ;
3046 }
3047 }
3048 }
3049 } /* end of drawing boxes */
3050
3051 /* 22 July 1996: save central graph data for later use */
3052
3053 if( ix == grapher->xc && iy == grapher->yc && tt == 0 ){
3054 for( i=0 ; i < qnum ; i++ ) grapher->cen_line[i] = a_line[i] ;
3055 grapher->nncen = qnum ;
3056 mri_free( grapher->cen_tsim ) ; /* copy time series too */
3057 grapher->cen_tsim = mri_to_float( tsim ) ;
3058 }
3059
3060 tsar += tsim->nx ; /* 29 Mar 2002: advance to next curve */
3061 } /* end of loop over multi-plot (tt) within a single tsim */
3062
3063 if( use_ovi )
3064 DC_fg_color( grapher->dc , DATA_COLOR(grapher) ) ; /* reset color */
3065
3066 /* 08 Nov 1996: double plot? Duplicate the above drawing code! */
3067 /* 29 Mar 2002: allow multiple time series (dsim->ny > 1) */
3068 /* 01 Jun 2020: PLUSMINUS (pmplot) now taken care of earlier */
3069 /* Note no boxes or pmplot here! */
3070
3071 if( dplot && pmplot_mode == 0 && !do_boxes ){
3072 int dny , id , qq,qtop ;
3073 dsim = IMARR_SUBIMAGE(dplot_imar,its) ;
3074 if( dsim == NULL || dsim->nx < 2 ) continue ; /* skip to next iy */
3075 dsar = MRI_FLOAT_PTR(dsim) ;
3076 tsar = MRI_FLOAT_PTR(tsim) ; /* 25 Feb 2003: reset this */
3077 itop = MIN( ptop , dsim->nx ); /* ibot was set long ago */
3078 qnum = NABC(pbot,itop,pstep) ; /* number of points to plot here */
3079 if( qnum < 2 ) continue ; /* skip to next iy = next sub-graph */
3080
3081 /** 29 Mar 2002: decode 'color:' from dsim->name, if present **/
3082
3083 use_ovi = (dsim->name!=NULL) && (strncmp(dsim->name,"color: ",7)==0) ;
3084 if( use_ovi ){
3085 char *cpt = dsim->name+6 ; int nuse, ngood ;
3086 for( tt=0 ; tt < OVI_MAX ; tt++ )
3087 ovi[tt] = DPLOT_COLOR(grapher) ;
3088 for( tt=0 ; tt < OVI_MAX ; tt++ ){
3089 ngood = sscanf(cpt,"%d%n",ovi+tt,&nuse) ;
3090 if( ngood < 1 ) break ;
3091 cpt += nuse ; if( *cpt == '\0' ) break ;
3092 }
3093 }
3094
3095 dny = dsim->ny ;
3096
3097 for( id=0 ; id < dny ; id++ ){ /* 29 Mar 2002: multi-plots */
3098 /* from the same dplot image */
3099 ypfac = grapher->fscale ;
3100 if( ypfac == 0.0 ) ypfac = 1.0 ;
3101 else if( ypfac < 0.0 ) ypfac = -1.0 / ypfac ;
3102
3103 /* 18 Mar 2004: scan backwards from itop to reject superlarge values */
3104
3105 for( qtop=itop-1 ; qtop >= pbot ; qtop-- )
3106 if( dsar[qtop] < WAY_BIG ) break ;
3107 if( qtop <= ibot ){ dsar += dsim->nx; continue; } /* skip */
3108 qtop++ ; qnum = NABC(pbot,qtop,pstep) ;
3109 if( qnum < 2 ){ dsar += dsim->nx; continue; } /* skip */
3110
3111 switch( dplot ){
3112 default:
3113 case DPLOT_OVERLAY: /* plot curve */
3114 for( qq=0,i=pbot ; i < MIN(ibot,qtop) ; i+=pstep,qq++ )
3115 plot[qq] = (dsar[ibot] - tsbot) * ypfac ;
3116 for( ; i < qtop ; i+=pstep,qq++ )
3117 plot[qq] = (dsar[i] - tsbot) * ypfac ;
3118
3119 qnum = qq ;
3120 break ;
3121 }
3122
3123 xpfac = grapher->gx / (pnum-1.0) ; /* cf. XPIX */
3124 xoff = grapher->xorigin[ix][iy] ;
3125 yoff = grapher->fHIGH - grapher->yorigin[ix][iy] ;
3126
3127 for( i=0 ; i < qnum ; i++ ){
3128 a_line[i].x = xoff + XPIX(i+pbot) ; /* 09 Jan 1998 */
3129 a_line[i].y = yoff - plot[i] ;
3130 }
3131
3132 if( use_ovi ) /* 29 Mar 2002 */
3133 DC_fg_color( grapher->dc , ovi[id%OVI_MAX] ) ;
3134 else
3135 DC_fg_color( grapher->dc , DPLOT_COLOR(grapher) ) ;
3136
3137 if( DPLOT_POINTS(grapher) ){ /* 09 Jan 1998 */
3138 int ww = DPLOT_THICK(grapher) ;
3139 for( i=0 ; i < qnum ; i++ )
3140 DRAW_A_DATA_POINT(a_line[i].x,a_line[i].y) ;
3141 }
3142 if( DPLOT_LINES(grapher) ) { /* 01 Aug 1998 */
3143 DC_linewidth( grapher->dc , DPLOT_THICK(grapher) ) ;
3144 AFNI_XDrawLines( grapher->dc->display ,
3145 grapher->fd_pxWind , grapher->dc->myGC ,
3146 a_line , qnum , CoordModeOrigin , nupsam ) ;
3147 }
3148
3149 dsar += dsim->nx ; /* 29 Mar 2002: next curve */
3150 } /* end of loop over multiple dplots */
3151
3152 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ;
3153 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
3154
3155 } /* end of dplot */
3156
3157 /* 05 Jan 1999: plot horizontal line through zero, if desired and needed */
3158
3159 if( grapher->HorZ && grapher->pmin[ix][iy] < 0.0 && grapher->pmax[ix][iy] > 0.0 ){
3160 DC_fg_color ( grapher->dc , GRID_COLOR(grapher) ) ; /* change myGC */
3161 DC_linewidth( grapher->dc , GRID_THICK(grapher) ) ;
3162 DC_dashed_line( grapher->dc ) ;
3163
3164 ypfac = grapher->fscale ;
3165 if( ypfac == 0.0 ) ypfac = 1.0 ;
3166 else if( ypfac < 0.0 ) ypfac = -1.0 / ypfac ;
3167
3168 XDrawLine( grapher->dc->display , grapher->fd_pxWind , grapher->dc->myGC ,
3169 (int) xoff , (int)(yoff + tsbot * ypfac) ,
3170 (int)(xoff + grapher->gx) , (int)(yoff + tsbot * ypfac) ) ;
3171
3172 DC_fg_color ( grapher->dc , DATA_COLOR(grapher) ) ; /* change myGC back */
3173 DC_linewidth( grapher->dc , DATA_THICK(grapher) ) ;
3174 DC_solid_line( grapher->dc ) ;
3175 }
3176
3177 } /* end of loop over y */
3178 } /* end of loop over x */
3179
3180 /** cast away the data timeseries! **/
3181
3182 DESTROY_IMARR(tsimar) ;
3183 if( dplot_imar != NULL ) DESTROY_IMARR(dplot_imar) ; /* 08 Nov 1996 */
3184
3185 /*---- Now do extra plots in center frame, if any [leftover from FD2] ----*/
3186
3187 #define REFTS_FRAC 0.38 /* fraction of one graph that this takes up */
3188 #define REFTS_TOP 0.98 /* top of reference graph in frame */
3189
3190 #define ORTTS_FRAC 0.38
3191 #define ORTTS_TOP 0.78
3192
3193 /* 12 Nov 1996: include graphs of orts by looping "iex" */
3194
3195 for( iex=0 ; iex <= 1 ; iex++ ){
3196
3197 if( pstep > 1 ) continue ; /* 11 Jun 2020 */
3198
3199 eximar = (iex==0) ? grapher->ref_ts : grapher->ort_ts ;
3200
3201 if( do_xxim ) xxim = xxim_cen ; /* 10 Feb 2015 */
3202 else xxim = xax_tsim ; /* might be NULL */
3203
3204 if( eximar != NULL && IMARR_COUNT(eximar) > 0 ){
3205 float yscal , val , xscal , exfrac , extop ;
3206 int nover , nvec , nx , ivec ;
3207 int excolor , exthick ;
3208 char *eee=NULL, *cnam=NULL; NI_str_array *cstr=NULL; int icc=0,ncstr=0;
3209
3210 STATUS("plotting extra graphs") ;
3211
3212 exfrac = (iex==0) ? REFTS_FRAC : ORTTS_FRAC ;
3213 extop = (iex==0) ? REFTS_TOP : ORTTS_TOP ;
3214 excolor = (iex==0) ? IDEAL_COLOR(grapher) : ORT_COLOR(grapher) ;
3215 exthick = (iex==0) ? IDEAL_THICK(grapher) : ORT_THICK(grapher) ;
3216
3217 /* 06 Oct 2010: get a list of colors to use */
3218
3219 if( iex == 0 ) eee = my_getenv("AFNI_IDEAL_COLORS") ;
3220 else if( iex == 1 ) eee = my_getenv("AFNI_ORT_COLORS") ;
3221
3222 if( eee != NULL && strlen(eee) > 3 ){
3223 cstr = NI_decode_string_list( eee , ":," ) ;
3224 if( cstr != NULL && cstr->num == 0 ){
3225 NI_delete_str_array(cstr) ; cstr = NULL ;
3226 } else {
3227 ncstr = cstr->num ;
3228 }
3229 }
3230
3231 for( its=0 ; its < IMARR_COUNT(eximar) ; its++ ){
3232
3233 tsim = IMARR_SUBIMAGE(eximar,its) ;
3234
3235 if( tsim == NULL || tsim->kind != MRI_float || tsim->nx < 2 ) continue ;
3236
3237 nx = tsim->nx ;
3238 itop = MIN( ptop , nx ) ;
3239 qnum = itop - pbot ; if( qnum < 2 ) continue ;
3240 nvec = (grapher->ref_ts_plotall) ? (tsim->ny) : 1 ;
3241
3242 for( ivec=0 ; ivec < nvec ; ivec++ ){ /* plot each sub-vector */
3243 if( ncstr > 0 ){ cnam = cstr->str[icc%ncstr] ; icc++ ; }
3244 tsar = MRI_FLOAT_PTR(tsim) + (ivec*nx) ;
3245 tsbot = 99999999.0 ; tstop = -99999999.0 ;
3246 nover = NIGNORE(grapher) ;
3247 for( i=ibot ; i < itop ; i++ ){
3248 val = tsar[i] ;
3249 if( val < WAY_BIG ){ tstop = MAX(tstop,val); tsbot = MIN(tsbot,val); }
3250 else { nover++ ; }
3251 }
3252 if( tstop >= WAY_BIG || tstop <= tsbot ) continue ; /* skip */
3253
3254 /*** scale into a_line and draw it***/
3255
3256 yscal = exfrac * grapher->gy / (tstop-tsbot) ;
3257 xscal = xpfac = grapher->gx / (pnum-1.0) ;
3258
3259 xoff = grapher->xorigin[grapher->xc][grapher->yc] ;
3260 yoff = grapher->fHIGH - grapher->yorigin[grapher->xc][grapher->yc]
3261 - (extop - exfrac) * grapher->gy ;
3262
3263 for( i=pbot ; i < itop; i++ ){
3264 val = (i >= ibot && tsar[i] < WAY_BIG) ? tsar[i] : tsbot ;
3265
3266 a_line[i-pbot].x = xoff + XPIX(i) ; /* 09 Jan 1998 */
3267 a_line[i-pbot].y = yoff - yscal*(val-tsbot) ;
3268 }
3269
3270 /* if none are over the limit, draw in one operation;
3271 otherwise, must plot each line separately in its needed color */
3272
3273 if( nover == 0 ){
3274 if( cnam != NULL && *cnam != '\0' )
3275 DC_fg_colortext( grapher->dc , cnam ) ;
3276 else
3277 DC_fg_color( grapher->dc , excolor ) ;
3278 DC_linewidth( grapher->dc , exthick ) ;
3279 AFNI_XDrawLines( grapher->dc->display ,
3280 grapher->fd_pxWind , grapher->dc->myGC ,
3281 a_line , qnum , CoordModeOrigin , nupsam ) ;
3282 } else {
3283 for( i=pbot ; i < itop-1 ; i++ ){
3284 if( i >= ibot && tsar[i] < WAY_BIG && tsar[i+1] < WAY_BIG ){
3285 if( cnam != NULL && *cnam != '\0' )
3286 DC_fg_colortext( grapher->dc , cnam ) ;
3287 else
3288 DC_fg_color( grapher->dc , excolor ) ;
3289 DC_linewidth( grapher->dc , exthick ) ;
3290 } else {
3291 DC_fg_color( grapher->dc , IGNORE_COLOR(grapher) ) ;
3292 if( grapher->mat < 4 &&
3293 ( i < ibot || tsar[i] >= WAY_BIG ) )
3294 GRA_small_circle( grapher,a_line[i-pbot].x,a_line[i-pbot].y,0 );
3295 }
3296
3297 AFNI_XDrawLines( grapher->dc->display ,
3298 grapher->fd_pxWind , grapher->dc->myGC ,
3299 a_line + (i-pbot) , 2 , CoordModeOrigin , 0 ) ;
3300 }
3301 if( grapher->mat < 4 &&
3302 ( i < ibot || tsar[i] >= WAY_BIG ) )
3303 GRA_small_circle( grapher,a_line[i-pbot].x,a_line[i-pbot].y,0 );
3304 }
3305 } /* end of loop over sub-vectors */
3306 } /* end of loop over refs */
3307
3308 if( cstr != NULL ){ NI_delete_str_array(cstr); cstr = NULL; }
3309
3310 } /* end of if refs exist */
3311 } /* end of loop over refs and orts */
3312
3313 /*---- 09 Jan 1998: plot graph showing x-axis as well ----*/
3314
3315 xxim = (do_xxim) ? xxim_cen : xax_tsim ;
3316 if( pstep == 1 && xxim != NULL ){ /* show the x-axis vertically at the left */
3317 float yscal , ftemp , xscal , yoff ;
3318 int npt ;
3319
3320 xscal = GL_DLX / (float) grapher->gx ;
3321 yscal = grapher->gy / (pnum-1.0) ;
3322 yoff = grapher->fHIGH - grapher->yorigin[grapher->xc][grapher->yc] ;
3323 ftemp = 1.0 ;
3324 npt = ptop ;
3325 if( npt > xxim->nx ) npt = xxim->nx ;
3326 if( npt > pbot+1 ){
3327 for( i=pbot ; i < npt ; i++ ){
3328 a_line[i-pbot].x = XPIX(i) * xscal ;
3329 a_line[i-pbot].y = yoff - yscal*(i-pbot) ;
3330 }
3331 DC_fg_color ( grapher->dc , IDEAL_COLOR(grapher) ) ;
3332 DC_linewidth( grapher->dc , IDEAL_THICK(grapher) ) ;
3333 AFNI_XDrawLines( grapher->dc->display , grapher->fd_pxWind , grapher->dc->myGC ,
3334 a_line , npt-pbot , CoordModeOrigin , 0 ) ;
3335 }
3336 } /* there is no code for showing the x-axis for pstep > 1, it's too hard */
3337
3338 /***** Done!!! (at last) *****/
3339
3340 if( do_xxim ) DESTROY_IMARR(xximar) ; /* 10 Feb 2015 */
3341 mri_free(xax_tsim) ;
3342
3343 EXRETURN ;
3344 }
3345
3346 /*------------------------------------------------------------------------
3347 Draw frames around each sub-graph and grids inside them
3348 12 Jan 1998: modified to allow for gaps between graphs
3349 --------------------------------------------------------------------------*/
3350
draw_grids(MCW_grapher * grapher)3351 void draw_grids( MCW_grapher *grapher )
3352 {
3353 int i , mat=grapher->mat , gx=grapher->gx , gy=grapher->gy ;
3354 int j, k, g, xo, yo, npoints , m ;
3355 int xc = grapher->xc , yc = grapher->yc ;
3356 float ftemp ;
3357
3358 ENTRY("draw_grids") ;
3359 if( grapher->dont_redraw ) EXRETURN ; /* 27 Jan 2004 */
3360
3361 /* draw grid lines in the chosen color */
3362
3363 if( GRID_COLOR(grapher) > 0 ){
3364 DC_fg_color ( grapher->dc , GRID_COLOR(grapher) ) ;
3365 DC_linewidth( grapher->dc , GRID_THICK(grapher) ) ;
3366
3367 g = grapher->grid_spacing ;
3368 npoints = NPTS(grapher) ; /* number time points in 1 sub-graph window */
3369
3370 if( npoints > 1 ){ /* this if: 22 Sep 2000 */
3371 if( DATA_BOXED(grapher) ) ftemp = gx / (float)npoints ;
3372 else ftemp = gx / (npoints-1.0f) ;
3373 for( i=0 ; i < mat ; i++ ){
3374 for( m=0 ; m < mat ; m++ ){
3375 xo = grapher->xorigin[i][m] ; yo = grapher->yorigin[i][m] ;
3376 for( j=1 ; j <= (npoints-1)/g ; j++ ){
3377 k = xo + j * g * ftemp ;
3378 plot_fdX( grapher , k , yo , 0 ) ;
3379 plot_fdX( grapher , k , yo+gy , 1 ) ;
3380 }
3381 }
3382 }
3383 }
3384
3385 /* draw an interior framing box at the central square */
3386
3387 xo = grapher->xorigin[xc][yc] ; yo = grapher->yorigin[xc][yc] ;
3388 g = MIN( grapher->gy/3 , grapher->gx/3 ) ; g = MIN( g , 4 ) ;
3389 for( j=1 ; j <= g ; j++ ){
3390 plot_fdX( grapher , xo+j , yo+j , 0 ) ;
3391 plot_fdX( grapher , xo+j , yo+gy-j , 1 ) ;
3392 plot_fdX( grapher , xo+gx-j , yo+gy-j , 1 ) ;
3393 plot_fdX( grapher , xo+gx-j , yo+j , 1 ) ;
3394 plot_fdX( grapher , xo+j , yo+j , 1 ) ;
3395 }
3396 }
3397
3398 /* draw exterior frames */
3399
3400 DC_fg_color ( grapher->dc , FG_COLOR(grapher) ) ;
3401 DC_linewidth( grapher->dc , FG_THICK(grapher) ) ;
3402
3403 for( i=0 ; i < mat ; i++ ){
3404 for( j=0 ; j < mat ; j++ ){
3405 xo = grapher->xorigin[i][j] ; yo = grapher->yorigin[i][j] ;
3406 plot_fdX( grapher , xo , yo , 0 ) ;
3407 plot_fdX( grapher , xo+gx , yo , 1 ) ;
3408 plot_fdX( grapher , xo+gx , yo+gy , 1 ) ;
3409 plot_fdX( grapher , xo , yo+gy , 1 ) ;
3410 plot_fdX( grapher , xo , yo , 1 ) ;
3411 }
3412 }
3413
3414 EXRETURN ;
3415 }
3416
3417 /*------------------------------------------
3418 Send the caller info about the new graph
3419 --------------------------------------------*/
3420
send_newinfo(MCW_grapher * grapher)3421 void send_newinfo( MCW_grapher *grapher )
3422 {
3423 ENTRY("send_newinfo") ;
3424
3425 if( GRA_VALID(grapher) && grapher->status->send_CB != NULL ){
3426 GRA_cbs cbs ;
3427
3428 cbs.reason = graCR_newxyzm ;
3429 cbs.xcen = grapher->xpoint ;
3430 cbs.ycen = grapher->ypoint ;
3431 cbs.zcen = grapher->zpoint ;
3432 cbs.mat = grapher->mat ;
3433 #if 0
3434 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
3435 #else
3436 CALL_sendback( grapher , cbs ) ;
3437 #endif
3438 }
3439
3440 EXRETURN ;
3441 }
3442
3443 /*---------------------------
3444 initialize matrix stuff
3445 -----------------------------*/
3446
init_mat(MCW_grapher * grapher)3447 void init_mat( MCW_grapher *grapher )
3448 {
3449 int i, j ;
3450 int gg ;
3451
3452 ENTRY("init_mat") ;
3453 if( !GRA_VALID(grapher) ) EXRETURN ;
3454
3455 grapher->gx = grapher->gx_max / grapher->mat;
3456 grapher->gy = grapher->gy_max / grapher->mat;
3457
3458 for (i=0;i<grapher->mat;i++) {
3459 for (j=0;j<grapher->mat;j++) {
3460 grapher->xorigin[i][j] = MDX1 + i * grapher->gx;
3461 grapher->yorigin[i][j] = MDY1 + j * grapher->gy;
3462 }
3463 }
3464
3465 if( grapher->mirror && grapher->mat > 1 ){ /* Jul 2000 */
3466 int mm = grapher->mat , m2 = mm/2 ; /* swap left and right */
3467
3468 for( j=0 ; j < mm ; j++ ){
3469 for( i=0 ; i < m2 ; i++ ){
3470 gg = grapher->xorigin[i][j] ;
3471 grapher->xorigin[i][j] = grapher->xorigin[mm-1-i][j] ;
3472 grapher->xorigin[mm-1-i][j] = gg ;
3473 }
3474 }
3475 }
3476
3477 grapher->xc = grapher->mat/2;
3478 grapher->yc = (grapher->mat-1)/2;
3479
3480 gg = grapher->ggap ; /* 12 Jan 1998 */
3481 if( gg > 0 ){
3482 gg = MIN( gg , grapher->gx / 2 ) ; /* shrink sizes of graphs */
3483 gg = MIN( gg , grapher->gy / 2 ) ;
3484 grapher->gx -= gg ;
3485 grapher->gy -= gg ;
3486 }
3487
3488 EXRETURN ;
3489 }
3490
3491 /* ----------------------------- */ /* scale plot up and redraw */
scale_up(MCW_grapher * grapher)3492 void scale_up( MCW_grapher * grapher )
3493 /* ----------------------------- */
3494 {
3495 if( !GRA_VALID(grapher) ) return ;
3496 if (grapher->fscale > 0) grapher->fscale *= 2;
3497 else if (grapher->fscale < -2) grapher->fscale /= 2;
3498 else grapher->fscale = 1;
3499
3500 if( grapher->fscale > 1000000.0 ){
3501 static int nn=0 ;
3502 nn++ ; if( nn < 3 ) fprintf(stderr,"Is that you, Bellgowan? If so, stop it!\a\n") ;
3503 }
3504 return ;
3505 }
3506
3507 /* ----------------------------- */ /* scale plot up and redraw */
scale_down(MCW_grapher * grapher)3508 void scale_down( MCW_grapher * grapher )
3509 /* ----------------------------- */
3510 {
3511 if( !GRA_VALID(grapher) ) return ;
3512 if (grapher->fscale > 1) grapher->fscale /= 2;
3513 else if (grapher->fscale < 0) grapher->fscale *= 2;
3514 else grapher->fscale = -2;
3515 return ;
3516 }
3517
3518 /* ----------------------------- */ /* decrease matrix and redraw */
mat_down(MCW_grapher * grapher)3519 void mat_down( MCW_grapher * grapher )
3520 /* ----------------------------- */
3521 {
3522 int old;
3523
3524 if( !GRA_VALID(grapher) ) return ;
3525 old = grapher->mat;
3526 grapher->mat--;
3527 if (grapher->mat < 1) grapher->mat = 1;
3528 else if (grapher->mat > grapher->mat_max) grapher->mat = grapher->mat_max;
3529 if (grapher->mat!= old) {
3530 init_mat( grapher ) ;
3531 redraw_graph( grapher , 0 ) ;
3532 }
3533 return ;
3534 }
3535
3536 /* ----------------------------- */ /* increase matrix and redraw */
mat_up(MCW_grapher * grapher)3537 void mat_up( MCW_grapher * grapher )
3538 /* ----------------------------- */
3539 {
3540 int old;
3541
3542 if( !GRA_VALID(grapher) ) return ;
3543 old = grapher->mat;
3544 grapher->mat++;
3545 if (grapher->mat < 1) grapher->mat = 1;
3546 else if (grapher->mat > grapher->mat_max) grapher->mat = grapher->mat_max;
3547 if (grapher->mat!= old) {
3548 init_mat(grapher) ;
3549 redraw_graph(grapher,0) ;
3550 }
3551 return ;
3552 }
3553
3554 /* ----------------------------- */ /* decrease grid spacing and redraw */
grid_down(MCW_grapher * grapher)3555 void grid_down( MCW_grapher * grapher )
3556 /* ----------------------------- */
3557 {
3558 int old;
3559
3560 if( !GRA_VALID(grapher) ) return ;
3561 old = grapher->grid_index;
3562 grapher->grid_index--;
3563 if (grapher->grid_index < 0) grapher->grid_index = 0;
3564 grapher->grid_spacing = grid_ar[grapher->grid_index] ;
3565 grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
3566 redraw_graph(grapher,0) ;
3567 return ;
3568 }
3569
3570 /* ----------------------------- */ /* increase grid spacing and redraw */
grid_up(MCW_grapher * grapher)3571 void grid_up( MCW_grapher * grapher )
3572 /* ----------------------------- */
3573 {
3574 int old;
3575
3576 if( !GRA_VALID(grapher) ) return ;
3577 old = grapher->grid_index;
3578 grapher->grid_index++;
3579 if (grapher->grid_index >= GRID_MAX) grapher->grid_index = GRID_MAX - 1;
3580 grapher->grid_spacing = grid_ar[grapher->grid_index] ;
3581 grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
3582 redraw_graph(grapher,0) ;
3583 return ;
3584 }
3585
3586 /*-----------------------------------------------------------------------
3587 Handle all events in an grapher drawing area widget
3588 -------------------------------------------------------------------------*/
3589
GRA_drawing_EV(Widget w,XtPointer client_data,XEvent * ev,RwcBoolean * continue_to_dispatch)3590 void GRA_drawing_EV( Widget w , XtPointer client_data ,
3591 XEvent * ev , RwcBoolean * continue_to_dispatch )
3592 {
3593 MCW_grapher * grapher = (MCW_grapher *) client_data ;
3594
3595 ENTRY("GRA_drawing_EV") ;
3596
3597 if( ! GRA_REALZ(grapher) ){
3598 if(PRINT_TRACING){
3599 char str[256] ;
3600 sprintf(str,"unrealized grapher! Event type = %d",(int)ev->type) ;
3601 STATUS(str) ; }
3602 EXRETURN ;
3603 }
3604
3605 if( grapher->valid == 666 ){ /* 06 Jan 1999 */
3606 if(PRINT_TRACING){
3607 char str[256] ;
3608 sprintf(str,"dying grapher! Event type = %d",(int)ev->type) ;
3609 STATUS(str) ; }
3610 EXRETURN ;
3611 }
3612
3613 switch( ev->type ){
3614
3615 /*----- redraw -----*/
3616
3617 case Expose:{
3618 XExposeEvent *event = (XExposeEvent *) ev ;
3619
3620 if(PRINT_TRACING){
3621 char str[256] ;
3622 sprintf(str,"Expose event with count = %d",event->count) ;
3623 STATUS(str) ; }
3624
3625 /**
3626 With the first expose, create the new pixmap.
3627 For subsequent ones, just redraw the non-pixmap (overlay) stuff.
3628
3629 06 Jan 1999: check event count
3630 **/
3631
3632 XSync( XtDisplay(w) , False ) ; /* 05 Feb 1999 */
3633
3634 if( event->count == 0 ){
3635 if( grapher->fd_pxWind == (Pixmap) 0 ){
3636 int width , height ;
3637 MCW_widget_geom( grapher->draw_fd , &width , &height , NULL,NULL ) ;
3638 GRA_new_pixmap( grapher , width , height , 1 ) ;
3639 } else {
3640 GRA_redraw_overlay( grapher ) ;
3641 }
3642 #if defined(DISCARD_EXCESS_EXPOSES)
3643 STATUS("discarding excess Expose events") ;
3644 MCW_discard_events( w , ExposureMask ) ;
3645 #endif
3646 }
3647
3648 }
3649 break ;
3650
3651 /*----- take key press -----*/
3652
3653 case KeyPress:{
3654 XKeyEvent *event = (XKeyEvent *) ev ;
3655 char buf[32] ;
3656 KeySym ks=0 ;
3657 int nbuf ;
3658
3659 STATUS("KeyPress event") ;
3660
3661 GRA_timer_stop( grapher ) ; /* 04 Dec 2003 */
3662
3663 if( grapher->fd_pxWind != (Pixmap) 0 ){
3664 buf[0] = '\0' ;
3665 nbuf = XLookupString( event , buf , 32 , &ks , NULL ) ;
3666 if( nbuf == 0 ){ /* 24 Jan 2003: substitution for special keys */
3667 switch(ks){
3668 case XK_KP_Left:
3669 case XK_Left: buf[0] = '<' ; break ;
3670 case XK_KP_Right:
3671 case XK_Right: buf[0] = '>' ; break ;
3672 case XK_KP_Page_Up:
3673 case XK_Page_Up: buf[0] = 'Z' ; break ;
3674 case XK_KP_Page_Down:
3675 case XK_Page_Down: buf[0] = 'z' ; break ;
3676 #if 0
3677 case XK_F5:
3678 MCW_melt_widget( grapher->draw_fd ) ; break ;
3679 #endif
3680 }
3681 }
3682 if( buf[0] != '\0' ) GRA_handle_keypress( grapher , buf , ev ) ;
3683 else if(PRINT_TRACING){
3684 char str[256] ;
3685 sprintf(str,"*** KeyPress was empty!? nbuf=%d",nbuf) ;
3686 STATUS(str) ;
3687 }
3688 }
3689 }
3690 break ;
3691
3692 /*----- take button press -----*/
3693
3694 case ButtonPress:{
3695 XButtonEvent *event = (XButtonEvent *) ev ;
3696 int bx,by , width,height , but=event->button ;
3697 int i, j, gx , gy , mat , xloc,yloc ;
3698 unsigned int but_state ;
3699 int xd,yd,zd ; /* 19 Mar 2004: for mangling to AFNI indexes */
3700
3701 STATUS("button press") ;
3702
3703 GRA_timer_stop(grapher) ; /* 31 May 2010 = Memorial Day */
3704
3705 /* 26 Feb 2007: Buttons 4 and 5 = scroll wheel = change time point */
3706
3707 if( but == Button4 || but == Button5 ){
3708 int dd=(but==Button4)?-1:+1 , tt ;
3709 if( AFNI_yesenv("AFNI_INDEX_SCROLLREV") ) dd = -dd ;
3710 tt = grapher->time_index + dd*NSTRIDE(grapher) ;
3711 EXRONE(grapher) ;
3712 if( tt >= 0 && tt < grapher->status->num_series && NSTRIDE(grapher) == 1 ){
3713 if( grapher->status->send_CB != NULL ){
3714 GRA_cbs cbs ;
3715 cbs.reason = graCR_setindex; cbs.key = tt; cbs.event = NULL;
3716 CALL_sendback( grapher , cbs ) ;
3717 } else {
3718 (void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)ITOP(tt)) ;
3719 }
3720 }
3721 MCW_discard_events( w , ButtonPressMask ) ; EXRETURN;
3722 }
3723
3724 /*-- some other button --*/
3725
3726 bx = event->x ; by = event->y ; but_state = event->state ;
3727 MCW_discard_events( w , ButtonPressMask ) ;
3728
3729 /* Button 1 in pixmap logo = toggle on or off */
3730 /* Button 3 in pixmap logo = raise up the dead */
3731
3732 if( grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP &&
3733 bx < grapher->glogo_width &&
3734 grapher->fHIGH - by < grapher->glogo_height ){
3735
3736 if( but == Button1 ){
3737 show_grapher_pixmap = ! show_grapher_pixmap ;
3738 if( XtIsManaged(grapher->option_rowcol) ) /* 04 Nov 1996 */
3739 XtUnmanageChild(grapher->option_rowcol) ;
3740 else
3741 XtManageChild(grapher->option_rowcol) ;
3742 redraw_graph( grapher , 0 ) ;
3743 } else if( but == Button3 ){ /* 17 Jun 2011 */
3744 GRA_cbs cbs ;
3745 cbs.reason = graCR_raiseupthedead ;
3746 CALL_sendback( grapher , cbs ) ;
3747 }
3748 break ; /* break out of ButtonPress case */
3749 }
3750
3751 /* compute which dataset pixel (xloc,yloc) the button press was in */
3752
3753 /* X11 box for graph (i,j):
3754 x = xorigin[i][j] .. xorigin[i][j]+gx (L..R)
3755 y = fHIGH-yorigin[i][j]-gy .. fHIGH-yorigin[i][j] (T..B) */
3756
3757 gx = grapher->gx ; gy = grapher->gy ; mat = grapher->mat ;
3758
3759 for( i=0 ; i < mat ; i++ )
3760 if( bx > grapher->xorigin[i][0] &&
3761 bx < grapher->xorigin[i][0] + gx ) break ; /* find in x */
3762
3763 if( i == mat ) break ; /* break out of ButtonPress case */
3764
3765 xloc = grapher->xpoint + i - grapher->xc ;
3766
3767 for( j=0 ; j < mat ; j++ ) /* find in y */
3768 if( by > grapher->fHIGH - grapher->yorigin[0][j] - gy &&
3769 by < grapher->fHIGH - grapher->yorigin[0][j] ) break ;
3770
3771 if( j == mat ) break ; /* break out of ButtonPress case */
3772
3773 yloc = grapher->ypoint - j + grapher->yc ;
3774
3775 /* adjust for possible wraparound */
3776
3777 if (xloc < 0) xloc += grapher->status->nx ;
3778 if (xloc >= grapher->status->nx) xloc -= grapher->status->nx ;
3779 if (yloc < 0) yloc += grapher->status->ny ;
3780 if (yloc >= grapher->status->ny) yloc -= grapher->status->ny ;
3781
3782 /* Feb 1998: button 2 --> send message back to AFNI, maybe */
3783 /* 03 Oct 2002: Shift+Button1 has the same effect */
3784
3785 if( but == Button2 ||
3786 ( but == Button1 && (event->state & ShiftMask) &&
3787 !(event->state & ControlMask) ) ){
3788
3789 if( grapher->button2_enabled && (bx > GL_DLX) ){
3790 GRA_cbs cbs ;
3791 cbs.reason = graCR_button2_points ;
3792 cbs.xcen = xloc ;
3793 cbs.ycen = yloc ;
3794 cbs.zcen = grapher->zpoint ;
3795 #if 0
3796 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
3797 #else
3798 CALL_sendback( grapher , cbs ) ;
3799 #endif
3800 } else {
3801 BEEPIT ;
3802 }
3803 }
3804
3805 /* button 1 --> move to new square as center of matrix,
3806 if it is actually a new center, that is,
3807 and if graphing is enabled, and if not off left edge */
3808
3809 if( grapher->fd_pxWind != (Pixmap) 0 &&
3810 but == Button1 && (bx > GL_DLX) &&
3811 ( (xloc != grapher->xpoint) || (yloc != grapher->ypoint) ) ){
3812
3813 grapher->xpoint = xloc ;
3814 grapher->ypoint = yloc ;
3815 redraw_graph( grapher , 0 ) ;
3816 send_newinfo( grapher ) ;
3817 }
3818
3819 /* 22 July 1996:
3820 button 1 in central graph of matrix causes jump to time_index */
3821
3822 else if( grapher->fd_pxWind != (Pixmap)0 &&
3823 NPTS(grapher) > 1 && !grapher->textgraph &&
3824 (but==Button1) && (bx > GL_DLX) &&
3825 (xloc == grapher->xpoint) && yloc == grapher->ypoint &&
3826 grapher->cen_line != NULL && grapher->nncen > 1 &&
3827 NSTRIDE(grapher) == 1 ){
3828
3829 float dist , dmin=999999.9 ;
3830 int imin = 0 ;
3831
3832 /*-- 09 Jan 1998: find closest pixel in central graph --*/
3833
3834 for( i=0 ; i < grapher->nncen ; i++ ){
3835 dist = abs( bx - grapher->cen_line[i].x ) /* L1 distance */
3836 + abs( by - grapher->cen_line[i].y ) ;
3837 if( dist < dmin ){ dmin = dist; imin = i; if(dmin == 0) break; }
3838 }
3839 i = imin * NSTRIDE(grapher) + NBOT(grapher) ;
3840
3841 if( i >= 0 && i < TTOP(grapher) ){
3842 if( grapher->status->send_CB != NULL ){
3843 GRA_cbs cbs ;
3844
3845 cbs.reason = graCR_setindex ;
3846 cbs.key = i ;
3847 cbs.event = ev ;
3848 #if 0
3849 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
3850 #else
3851 CALL_sendback( grapher , cbs ) ;
3852 #endif
3853 } else {
3854 (void) drive_MCW_grapher( grapher,graDR_setindex,(XtPointer)ITOP(i) );
3855 }
3856 }
3857 }
3858
3859 /* Button 3 --> popup statistics of this graph */
3860
3861 if( !AFNI_noenv("AFNI_GRAPH_BUT3") && /* stupid Xorg bug */
3862 but == Button3 && !ISONE(grapher) && !grapher->textgraph ){
3863 int ix , iy ;
3864
3865 ix = xloc - grapher->xpoint + grapher->xc ;
3866 if( ix < 0 ) ix += grapher->status->nx ;
3867 else if( ix >= grapher->mat ) ix -= grapher->status->nx ;
3868
3869 iy = grapher->ypoint - yloc + grapher->yc ;
3870 if( iy < 0 ) iy += grapher->status->ny ;
3871 else if( iy >= grapher->mat ) iy -= grapher->status->ny ;
3872
3873 if( ix >= 0 && ix < grapher->mat && iy >= 0 && iy < grapher->mat ){
3874 XmString xstr ;
3875 char bmin[16],bmax[16],bmean[16],bstd[16] ;
3876 char bmed[16] , bmad[16] ; /* 08 Mar 2001 */
3877 char bbmv[16] ; /* 16 Oct 2009 */
3878 char btsn[16] ; /* 08 Jan 2021 */
3879 char *qstr , *eee ; /* 07 Mar 2002 */
3880 int nlin , nltop=40 ; /* 07 Mar 2002 */
3881
3882 AV_fval_to_char( grapher->tbot[ix][iy] , bmin ) ;
3883 AV_fval_to_char( grapher->ttop[ix][iy] , bmax ) ;
3884 AV_fval_to_char( grapher->tmean[ix][iy] , bmean) ;
3885 AV_fval_to_char( grapher->tstd[ix][iy] , bstd ) ;
3886 AV_fval_to_char( grapher->tsnr[ix][iy] , btsn ) ;
3887
3888 AV_fval_to_char( grapher->tmed[ix][iy] , bmed ) ; /* 08 Mar 2001 */
3889 AV_fval_to_char( 1.4826*grapher->tmad[ix][iy] , bmad ) ;
3890 AV_fval_to_char( grapher->tbmv[ix][iy] , bbmv ) ; /* 16 Oct 2009 */
3891
3892 if( grapher->tuser[ix][iy] == NULL )
3893 qstr = AFMALL(char, 2048) ;
3894 else
3895 qstr = AFMALL(char, 2048+strlen(grapher->tuser[ix][iy])) ;
3896
3897 /* 19 Mar 2004: mangle FD_brick indexes to AFNI indexes */
3898
3899 xd = xloc; yd = yloc; zd = grapher->zpoint ;
3900 #ifndef DONT_MANGLE_XYZ
3901 { THD_ivec3 id ;
3902 id = THD_fdind_to_3dind( grapher->getaux , TEMP_IVEC3(xd,yd,zd) ) ;
3903 xd = id.ijk[0] ; yd = id.ijk[1] ; zd = id.ijk[2] ; }
3904 #endif
3905 sprintf( qstr, "Data Statistics\n"
3906 "---------------\n"
3907 "Indexes = %d:%-d@%d\n" /* 19 Mar 2004 */
3908 "x voxel = %d\n"
3909 "y voxel = %d\n"
3910 "z voxel = %d\n"
3911 "Min =%s\n"
3912 "Max =%s\n"
3913 "Mean =%s\n"
3914 "Median =%s\n" /* 08 Mar 2001 */
3915 "Sigma =%s\n"
3916 "Mean/Sig=%s\n" /* 08 Jan 2021 */
3917 "MAD*1.48=%s\n"
3918 "BiwtMidV=%s" , /* 16 Oct 2009 */
3919 grapher->sbot[ix][iy], grapher->stop[ix][iy], /* 19 Mar 2004 */
3920 NSTRIDE(grapher) , /* 11 Jun 2020 */
3921 xd , yd , zd ,
3922 bmin,bmax,bmean,bmed,bstd,btsn,bmad,bbmv ) ;
3923
3924 /** 12 Feb 2015: incorporate x-axis range info for this voxel **/
3925
3926 if( grapher->xax_cen != NULL || grapher->xax_tsim != NULL ){
3927 AV_fval_to_char( grapher->xax_bot[ix][iy] , bmin ) ;
3928 AV_fval_to_char( grapher->xax_top[ix][iy] , bmax ) ;
3929 sprintf( qstr+strlen(qstr) ,
3930 "\n"
3931 "X-ax min=%s\n"
3932 "X-ax top=%s" ,
3933 bmin , bmax ) ;
3934 }
3935
3936 /** 22 Apr 1997: incorporate user string for this voxel **/
3937
3938 if( grapher->tuser[ix][iy] != NULL ){
3939 strcat( qstr , "\n------------------\n" ) ;
3940 strcat( qstr , grapher->tuser[ix][iy] ) ;
3941 }
3942
3943 /* 07 Mar 2002: if string is too long, popup textwin,
3944 otherwise just open a popup window */
3945
3946 eee = getenv( "AFNI_GRAPH_TEXTLIMIT" ) ;
3947 if( eee != NULL ){
3948 nlin = strtol( eee , NULL , 10 ) ;
3949 if( nlin > 0 ) nltop = nlin ;
3950 }
3951
3952 for( nlin=1,eee=qstr ; *eee != '\0' ; eee++ )
3953 if( *eee == '\n' ) nlin++ ;
3954
3955 if( nlin < nltop ){
3956 xstr = XmStringCreateLtoR( qstr, XmFONTLIST_DEFAULT_TAG ) ;
3957 XtVaSetValues( grapher->but3_label,XmNlabelString,xstr,NULL );
3958 XmStringFree( xstr ) ;
3959 XmMenuPosition( grapher->but3_menu , event ) ; /* where */
3960 XtManageChild ( grapher->but3_menu ) ; /* popup */
3961 } else {
3962 (void) new_MCW_textwin(grapher->fdw_graph,qstr,TEXT_READONLY);
3963 }
3964 free(qstr) ;
3965
3966 } else {
3967 redraw_graph(grapher,0) ; /* 11 Nov 1996 */
3968 }
3969 }
3970 }
3971 break ;
3972
3973 /*----- window changed size -----*/
3974
3975 case ConfigureNotify:{
3976 XConfigureEvent * event = (XConfigureEvent *) ev ;
3977 int new_width , new_height ;
3978
3979 STATUS("ConfigureNotify event") ;
3980
3981 XSync( XtDisplay(w) , False ) ;
3982 GRA_timer_stop(grapher) ; /* 31 May 2010 = Memorial Day */
3983
3984 new_width = event->width ;
3985 new_height = event->height ;
3986
3987 if( new_width != grapher->fWIDE || new_height != grapher->fHIGH ){
3988 GRA_new_pixmap( grapher , new_width , new_height , 1 ) ;
3989 }
3990 }
3991 break ;
3992
3993 /*----- ignore all other events -----*/
3994
3995 default:
3996 #ifdef AFNI_DEBUG
3997 {char str[256]; sprintf(str,"Event code = %d\n",(int)ev->type); STATUS(str);}
3998 #endif
3999 break ;
4000
4001 } /* end of switch ev->type */
4002
4003 EXRETURN ;
4004 }
4005
4006 /*------------------------------------------------------------------
4007 Get a new pixmap for drawing purposes
4008 --------------------------------------------------------------------*/
4009
GRA_new_pixmap(MCW_grapher * grapher,int new_width,int new_height,int redraw)4010 void GRA_new_pixmap( MCW_grapher * grapher ,
4011 int new_width , int new_height , int redraw )
4012 {
4013 int ww,hh ;
4014
4015 ENTRY("GRA_new_pixmap") ;
4016
4017 if( ! GRA_REALZ(grapher) ) EXRETURN ;
4018
4019 grapher->fWIDE = new_width ;
4020 grapher->fHIGH = new_height ;
4021 grapher->gx_max = new_width - (GL_DLX + GR_DLX) ;
4022 grapher->gy_max = new_height - (GT_DLY + GB_DLY) ;
4023
4024 if( grapher->fd_pxWind != (Pixmap) 0 ){
4025 STATUS("freeing old Pixmap") ;
4026 XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
4027 }
4028
4029 STATUS("allocating new Pixmap") ;
4030 grapher->fd_pxWind = XCreatePixmap( grapher->dc->display ,
4031 XtWindow(grapher->draw_fd) ,
4032 grapher->fWIDE , grapher->fHIGH,
4033 grapher->dc->planes ) ;
4034
4035 MCW_widget_geom( grapher->option_rowcol , &ww , &hh , NULL,NULL ) ;
4036 XtVaSetValues( grapher->option_rowcol ,
4037 #ifdef WANT_AFNI_BITMAP
4038 XmNx , grapher->fWIDE - ww - 2 ,
4039 #else
4040 XmNx , 2 ,
4041 #endif
4042 XmNy , grapher->fHIGH - hh - 2 ,
4043 NULL ) ;
4044
4045 if( redraw ){
4046 init_mat( grapher ) ;
4047 redraw_graph( grapher , 0 ) ;
4048 }
4049
4050 EXRETURN ;
4051 }
4052
4053 /*----------------------------------------------------------
4054 Deal with keypresses in a graph window
4055 ------------------------------------------------------------*/
4056
GRA_handle_keypress(MCW_grapher * grapher,char * buf,XEvent * ev)4057 void GRA_handle_keypress( MCW_grapher *grapher , char *buf , XEvent *ev )
4058 {
4059 int ii=0 ;
4060 static int first_sound=1 ;
4061
4062 ENTRY("GRA_handle_keypress") ;
4063
4064 if( buf[0] == '\0' ) EXRETURN ;
4065
4066 if(PRINT_TRACING){
4067 char str[256] ;
4068 sprintf(str,"buf[0]=%c (%x)",(int)buf[0],(int)buf[0]) ;
4069 STATUS(str); }
4070
4071 /*** deal with the key sequence 'N <digits> <Enter>' ***/
4072
4073 /* first 'N' */
4074
4075 if( AFNI_yesenv("AFNI_GRAPH_ALLOW_SHIFTN") && grapher->key_Nlock==0 && buf[0]=='N' ){
4076 grapher->key_Nlock = 1 ;
4077 HAND_cursorize( grapher->fdw_graph ) ;
4078 HAND_cursorize( grapher->draw_fd ) ;
4079 grapher->key_lock_sum = 0 ;
4080 EXRETURN ;
4081 }
4082
4083 /* last <Enter> */
4084
4085 if( grapher->key_Nlock && buf[0] == 13 ){
4086
4087 /* if have a number, set the graph matrix size */
4088
4089 if( grapher->key_lock_sum > 0 )
4090 grapher->mat = MIN( grapher->mat_max , grapher->key_lock_sum ) ;
4091
4092 NORMAL_cursorize( grapher->fdw_graph ) ;
4093 if( ISONE(grapher) )
4094 NORMAL_cursorize( grapher->draw_fd ) ;
4095 else
4096 POPUP_cursorize( grapher->draw_fd ) ;
4097
4098 init_mat ( grapher ) ;
4099 redraw_graph( grapher , 0 ) ;
4100 send_newinfo( grapher ) ;
4101 grapher->key_Nlock = grapher->key_lock_sum = 0 ;
4102 EXRETURN ;
4103 }
4104
4105 /* intermediate <digit> */
4106
4107 if( grapher->key_Nlock ){
4108 if( isdigit(buf[0]) ){
4109 ii = buf[0] - 48;
4110 grapher->key_lock_sum = MIN( 10000, 10*grapher->key_lock_sum + ii ) ;
4111 }
4112 EXRETURN ;
4113 }
4114
4115 /*-- other keys are single stroke commands --*/
4116
4117 MCW_discard_events( grapher->draw_fd , KeyPressMask ) ;
4118
4119 switch (buf[0]) {
4120
4121 case '-':
4122 case '+':
4123 if( buf[0] == '-' ) scale_down( grapher ) ;
4124 else scale_up ( grapher ) ;
4125 if (PLOT_FORCE_AUTOSCALE) { /* turn it off, user wants to change */
4126 PLOT_FORCE_AUTOSCALE = !PLOT_FORCE_AUTOSCALE;
4127 MCW_invert_widget(grapher->opt_scale_AUTO_pb);
4128 }
4129 redraw_graph( grapher , 0 ) ;
4130 break;
4131
4132 case 'A':
4133 PLOT_FORCE_AUTOSCALE = !PLOT_FORCE_AUTOSCALE;
4134 MCW_invert_widget(grapher->opt_scale_AUTO_pb);
4135 if (PLOT_FORCE_AUTOSCALE) INFO_message("Graph Viewer: Autoscale forced ON") ;
4136 else INFO_message("Graph Viewer: Autoscale forced OFF") ;
4137 redraw_graph( grapher , 0);
4138 break;
4139
4140 case 'a':
4141 redraw_graph( grapher , PLOTCODE_AUTOSCALE ) ; /* 03 Feb 1998 */
4142 break ;
4143
4144 case 'i':
4145 if( !grapher->textgraph && NIGNORE(grapher) > 0 ){ /* 24 May 2005 */
4146 GRA_cbs cbs ;
4147 cbs.reason = graCR_setignore ; cbs.key = grapher->init_ignore - 1 ;
4148 CALL_sendback( grapher , cbs ) ;
4149 } else {
4150 BEEPIT ; WARNING_message("Can't lower Ignore any more") ;
4151 }
4152 break ;
4153
4154 case 'I':
4155 if( !grapher->textgraph ){ /* 24 May 2005 */
4156 GRA_cbs cbs ;
4157 cbs.reason = graCR_setignore ; cbs.key = grapher->init_ignore + 1 ;
4158 CALL_sendback( grapher , cbs ) ;
4159 } else {
4160 BEEPIT ; WARNING_message("Can't increase Ignore now") ;
4161 }
4162 break ;
4163
4164 case 'm':
4165 case 'M':
4166 if( buf[0] == 'm' ) mat_down( grapher ) ;
4167 else mat_up ( grapher ) ;
4168 send_newinfo( grapher ) ;
4169 break;
4170
4171 case 'g':
4172 grid_down( grapher ) ;
4173 break;
4174
4175 case 'G':
4176 grid_up( grapher ) ;
4177 break;
4178
4179 case 'h': /* 05 Jan 1999 */
4180 grapher->HorZ = ! grapher->HorZ ;
4181 redraw_graph( grapher , 0 ) ;
4182 break ;
4183
4184 case 'q':
4185 case 'Q':
4186 end_fd_graph_CB( NULL , (XtPointer) grapher , NULL ) ;
4187 break ;
4188
4189 /* modified 07 Aug 2001 to account for more complex baseline scenario */
4190
4191 case 'b':{
4192 int bbb = grapher->common_base << 1 ;
4193 if( bbb > BASELINE_GLOBAL ) bbb = BASELINE_INDIVIDUAL ;
4194 MCW_set_bbox( grapher->opt_baseline_bbox , bbb ) ;
4195 grapher->common_base = bbb ;
4196 redraw_graph( grapher , 0 ) ;
4197 }
4198 break ;
4199
4200 case 'B':{ /* 29 Jun 2007 */
4201 int bbb=grapher->points_index[4] , ccc ;
4202 ccc = (bbb==4) ? 0 : 4 ;
4203 MCW_set_bbox( grapher->opt_points_bbox[4] , ccc ) ;
4204 grapher->points_index[4] = ccc ;
4205 #if 0
4206 if( DATA_BOXED(grapher) )
4207 MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OFF ) ;
4208 #endif
4209 if( !grapher->textgraph ) redraw_graph( grapher , 0 ) ;
4210 }
4211 break ;
4212
4213 case 2:{ /* keypress ctrl-B = cycle through Data [11 Jan 2021] */
4214 int bbb=grapher->points_index[4] , ccc=bbb ,
4215 nbut=grapher->opt_points_bbox[4]->nbut ;
4216 ccc = (ccc <= 0) ? 1 : 2*ccc ; /* next highest value */
4217 if( ccc >= 2<<(nbut-1) ) ccc = 0 ; /* back to beginning */
4218 MCW_set_bbox( grapher->opt_points_bbox[4] , ccc ) ;
4219 grapher->points_index[4] = ccc ;
4220 if( !grapher->textgraph ) redraw_graph( grapher , 0 ) ;
4221 }
4222 break ;
4223
4224 case 't':{ /* 22 Sep 2000 */
4225 int bbb = ! grapher->textgraph ;
4226 MCW_set_bbox( grapher->opt_textgraph_bbox , bbb ) ;
4227 grapher->textgraph = bbb ;
4228 redraw_graph( grapher , 0 ) ;
4229 }
4230 break ;
4231
4232 case 'S':
4233 MCW_choose_string( grapher->option_rowcol ,
4234 "Save Image prefix:\n"
4235 " * end in .jpg or .png *\n"
4236 " * for those formats *" , NULL ,
4237 GRA_saver_CB , (XtPointer) grapher ) ;
4238 break ;
4239
4240 case 's':{ /* 28 May 2020 */
4241 int uu = ! grapher->do_upsam ;
4242 grapher->do_upsam = uu ;
4243 AV_assign_ival( grapher->opt_upsam_av , uu ) ;
4244 init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
4245 }
4246 break ;
4247
4248 #define POPUP_SOUND_ERROR_MESSAGE \
4249 do{ if( first_sound ){ \
4250 char msg[2048] ; \
4251 strcpy(msg," \n" "Cannot play sound:\n" ) ; \
4252 if( !GLOBAL_library.local_display ) \
4253 strcat( msg+strlen(msg) , " You are running AFNI remotely :(\n" ) ; \
4254 if( GLOBAL_library.sound_player==NULL ) \
4255 strcat( msg+strlen(msg) , " No sound playing program is found :(\n") ; \
4256 strcat( msg+strlen(msg) , " \n") ; \
4257 (void) MCW_popup_message( \
4258 grapher->fdw_graph , msg , MCW_USER_KILL | MCW_TIMER_KILL ) ; \
4259 } } while(0)
4260
4261 #define PRINT_SOUND_INFO_MESSAGE \
4262 do{ if( first_sound ){ \
4263 INFO_message("Use K keypress to kill playing sounds:") ; \
4264 ININFO_message(" might leave sound file named AFNI_SOUND_TEMP.something.au on disk;"); \
4265 ININFO_message(" if so, you will have to delete such files manually :(") ; \
4266 } } while(0)
4267
4268 case 'p': /* play sound [20 Aug 2018] */
4269 if( !GLOBAL_library.local_display || GLOBAL_library.sound_player==NULL ){
4270 POPUP_SOUND_ERROR_MESSAGE ;
4271 } else if( grapher->cen_tsim != NULL ){
4272 int ib = NIGNORE(grapher) ;
4273 PRINT_SOUND_INFO_MESSAGE ;
4274 mri_play_sound( grapher->cen_tsim , ib ) ;
4275 }
4276 first_sound = 0 ;
4277 break ;
4278
4279 case 'P': /* play sound [20 Aug 2018] */
4280 if( !GLOBAL_library.local_display || GLOBAL_library.sound_player==NULL ){
4281 POPUP_SOUND_ERROR_MESSAGE ;
4282 } else if( grapher->ave_tsim != NULL && grapher->cen_tsim != NULL ){
4283 int ib = NIGNORE(grapher) ;
4284 MRI_IMARR *imar ; MRI_IMAGE *qim ;
4285 INIT_IMARR(imar) ;
4286 ADDTO_IMARR(imar,grapher->ave_tsim) ; /* glue the 2 */
4287 ADDTO_IMARR(imar,grapher->cen_tsim) ; /* timeseries */
4288 qim = mri_catvol_1D( imar , 2 ) ; /* together */
4289 PRINT_SOUND_INFO_MESSAGE ;
4290 mri_play_sound( qim , ib ) ;
4291 mri_free(qim) ; FREE_IMARR(imar) ;
4292 }
4293 first_sound = 0 ;
4294 break ;
4295
4296 case 'K': /* kill sound players [27 Aug 2018] */
4297 if( !first_sound )
4298 kill_sound_players() ;
4299 break ;
4300
4301 case 'L':
4302 show_grapher_pixmap = ! show_grapher_pixmap ;
4303 if( grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP )
4304 redraw_graph( grapher , 0 ) ;
4305 break ;
4306
4307 case '<': case ',': /* change time point */
4308 case '>': case '.':
4309 case '[': case ']':
4310 case '1':
4311 case 'l':{
4312 int di ;
4313 EXRONE(grapher) ; /* 22 Sep 2000 */
4314 di = NSTRIDE(grapher) ; /* 11 Jun 2020 */
4315 if( buf[0]=='<' || buf[0]==',' || buf[0]=='[' ) ii = grapher->time_index-di;
4316 else if( buf[0]=='>' || buf[0]=='.' || buf[0]==']' ) ii = grapher->time_index+di;
4317 else if( buf[0] == '1' ) ii = 1 ;
4318 else if( buf[0] == 'l' ) ii = grapher->status->num_series-1;
4319
4320 ii = (ii+grapher->status->num_series) % grapher->status->num_series ;
4321 if( ii >= 0 && ii < grapher->status->num_series && di == 1 ){
4322 if( grapher->status->send_CB != NULL ){
4323 GRA_cbs cbs ;
4324
4325 cbs.reason = graCR_setindex ;
4326 cbs.key = ii;
4327 cbs.event = NULL ;
4328 #if 0
4329 grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
4330 #else
4331 CALL_sendback( grapher , cbs ) ;
4332 #endif
4333 } else {
4334 (void) drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)ITOP(ii)) ;
4335 }
4336 }
4337 }
4338 break ;
4339
4340 case 'v': /* 04 Dec 2003: video */
4341 case 'V':
4342 if( grapher->status->num_series > 1 ){
4343 grapher->timer_func = GRA_TIMERFUNC_INDEX ;
4344 grapher->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
4345 if( grapher->timer_delay <= 0 ) grapher->timer_delay = 1 ;
4346 grapher->timer_param = (buf[0] == 'v') ? 1 : -1 ;
4347 grapher->timer_id =
4348 XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb),
4349 grapher->timer_delay , GRA_timer_CB , grapher ) ;
4350 } else {
4351 BEEPIT ; WARNING_message("Can't video current graph window") ;
4352 }
4353 break ;
4354
4355 case 'r':
4356 case 'R':
4357 if( grapher->status->num_series > 1 ){
4358 grapher->timer_func = GRA_TIMERFUNC_BOUNCE ;
4359 grapher->timer_delay = (int) AFNI_numenv("AFNI_VIDEO_DELAY") ;
4360 if( grapher->timer_delay <= 0 ) grapher->timer_delay = 1 ;
4361 grapher->timer_param = (buf[0] == 'r') ? 1 : -1 ;
4362 grapher->timer_id =
4363 XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb),
4364 grapher->timer_delay , GRA_timer_CB , grapher ) ;
4365 } else {
4366 BEEPIT ; WARNING_message("Can't video current graph window") ;
4367 }
4368 break ;
4369
4370 case 'F':
4371 grapher->thresh_fade = !grapher->thresh_fade ;
4372 MCW_set_bbox( grapher->opt_tfade_bbox , grapher->thresh_fade ) ;
4373 redraw_graph( grapher , 0 ) ;
4374 break ;
4375
4376 case 'z': /* change slice */
4377 case 'Z':
4378 if( buf[0] == 'z' ){
4379 grapher->zpoint -- ;
4380 if( grapher->zpoint < 0 ) grapher->zpoint = grapher->status->nz - 1 ;
4381 } else {
4382 grapher->zpoint ++ ;
4383 if( grapher->zpoint >= grapher->status->nz ) grapher->zpoint = 0 ;
4384 }
4385 redraw_graph( grapher , 0 ) ;
4386 send_newinfo( grapher ) ;
4387 break ;
4388
4389 case 'w':{
4390 char * wcfname ;
4391 int ndig , ll ;
4392 MRI_IMAGE * tsim ;
4393 int xd,yd,zd ; /* 24 Sep 1999 */
4394
4395 /* EXRONE(grapher) ; */ /* 22 Sep 2000 */
4396
4397 ll = MAX( grapher->status->nx , grapher->status->ny ) ;
4398 ll = MAX( grapher->status->nz , ll ) ;
4399 ndig = (ll < 1000) ? 3 : 4 ;
4400
4401 ll = 3*ndig + 16 ;
4402 if( Grapher_Stuff.wcsuffix != NULL )
4403 ll += strlen(Grapher_Stuff.wcsuffix) ;
4404 wcfname = (char *) XtMalloc(ll) ;
4405
4406 /* 24 Sep 1999: mangle the name for the output */
4407
4408 xd = grapher->xpoint; yd = grapher->ypoint; zd = grapher->zpoint;
4409 #ifndef DONT_MANGLE_XYZ
4410 { THD_ivec3 id;
4411 id = THD_fdind_to_3dind( grapher->getaux, TEMP_IVEC3(xd,yd,zd) );
4412 xd = id.ijk[0]; yd = id.ijk[1]; zd = id.ijk[2]; }
4413 #endif
4414
4415 if( Grapher_Stuff.wcsuffix != NULL )
4416 sprintf(wcfname,"%0*d_%0*d_%0*d.%s.1D" ,
4417 ndig,xd , ndig,yd , ndig,zd ,
4418 Grapher_Stuff.wcsuffix ) ;
4419 else
4420 sprintf(wcfname,"%0*d_%0*d_%0*d.1D" ,
4421 ndig,xd , ndig,yd , ndig,zd ) ;
4422
4423 ll = grapher->xpoint +
4424 grapher->ypoint * grapher->status->nx +
4425 grapher->zpoint * grapher->status->nx * grapher->status->ny ;
4426
4427 tsim = GRA_getseries( grapher , ll ) ;
4428 if( tsim != NULL ){
4429 mri_write_1D( wcfname , tsim ) ; /* 16 Nov 1999: replaces mri_write_ascii */
4430 mri_free( tsim ) ;
4431 }
4432 myXtFree(wcfname) ;
4433 }
4434 break ;
4435
4436 case 'C':{ /* Change colors all at once [16 Apr 2019] */
4437 int fc = (grapher->fixed_colors_setting+1) % NUM_FIXED_COLORS_SETTING ;
4438 int ii,jj ;
4439 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
4440 jj = GRA_COLOR(fixed_colors[fc][ii]) ; /* color index */
4441 grapher->color_index[ii] = jj ;
4442 AV_assign_ival(grapher->opt_color_av[ii],jj) ; /* change menu */
4443 }
4444 grapher->fixed_colors_setting = fc ; /* for the next time through */
4445 redraw_graph(grapher,0) ; /* show the new beauty */
4446 }
4447 break ;
4448
4449 /*--- At this point, have a key not handled here.
4450 Call the creator to see if ze wishes to deal with it. ---*/
4451
4452 default:
4453 if( grapher->status->send_CB != NULL ){
4454 GRA_cbs cbs ;
4455
4456 cbs.reason = graCR_keypress ;
4457 cbs.key = buf[0] ;
4458 cbs.event = ev ;
4459 #if 0
4460 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
4461 #else
4462 CALL_sendback( grapher , cbs ) ;
4463 #endif
4464 }
4465 break ;
4466 }
4467
4468 EXRETURN ;
4469 }
4470
4471 /*--------------------------------------------------------------------------
4472 06 Jan 1999: handle death after a timeout.
4473 ----------------------------------------------------------------------------*/
4474
GRA_quit_timeout_CB(XtPointer client_data,XtIntervalId * id)4475 void GRA_quit_timeout_CB( XtPointer client_data , XtIntervalId * id )
4476 {
4477 MCW_grapher * grapher = (MCW_grapher *) client_data ;
4478
4479 ENTRY("GRA_quit_timeout_CB") ;
4480 GRA_handle_keypress( grapher , "q" , NULL ) ;
4481 EXRETURN ;
4482 }
4483
4484 /*--------------------------------------------------------------------------
4485 Handle buttons from the opt menu
4486 ----------------------------------------------------------------------------*/
4487
GRA_opt_CB(Widget w,XtPointer client_data,XtPointer call_data)4488 void GRA_opt_CB( Widget w , XtPointer client_data , XtPointer call_data )
4489 {
4490 MCW_grapher * grapher = (MCW_grapher *) client_data ;
4491
4492 ENTRY("GRA_opt_CB") ;
4493
4494 if( w == grapher->opt_scale_down_pb ){
4495 GRA_handle_keypress( grapher , "-" , NULL ) ;
4496 EXRETURN ;
4497 }
4498
4499 if( w == grapher->opt_scale_up_pb ){
4500 GRA_handle_keypress( grapher , "+" , NULL ) ;
4501 EXRETURN ;
4502 }
4503
4504 if( w == grapher->opt_scale_AUTO_pb ){
4505 GRA_handle_keypress( grapher , "A" , NULL ) ;
4506 EXRETURN ;
4507 }
4508
4509 if( w == grapher->opt_scale_auto_pb ){
4510 GRA_handle_keypress( grapher , "a" , NULL ) ;
4511 EXRETURN ;
4512 }
4513
4514 if( w == grapher->opt_grid_down_pb ){
4515 GRA_handle_keypress( grapher , "g" , NULL ) ;
4516 EXRETURN ;
4517 }
4518
4519 if( w == grapher->opt_grid_up_pb ){
4520 GRA_handle_keypress( grapher , "G" , NULL ) ;
4521 EXRETURN ;
4522 }
4523
4524 if( w == grapher->opt_grid_auto_pb ){ /* 02 Apr 2004 */
4525 auto_grid( grapher , NPTS(grapher) ) ;
4526 redraw_graph(grapher,0) ;
4527 EXRETURN ;
4528 }
4529
4530 if( w == grapher->opt_grid_HorZ_pb ){ /* 05 Jan 1999 */
4531 GRA_handle_keypress( grapher , "h" , NULL ) ;
4532 EXRETURN ;
4533 }
4534
4535 if( w == grapher->opt_slice_down_pb ){
4536 GRA_handle_keypress( grapher , "z" , NULL ) ;
4537 EXRETURN ;
4538 }
4539
4540 if( w == grapher->opt_slice_up_pb ){
4541 GRA_handle_keypress( grapher , "Z" , NULL ) ;
4542 EXRETURN ;
4543 }
4544
4545 if( w == grapher->opt_mat_down_pb ){
4546 GRA_handle_keypress( grapher , "m" , NULL ) ;
4547 EXRETURN ;
4548 }
4549
4550 if( w == grapher->opt_mat_up_pb ){
4551 GRA_handle_keypress( grapher , "M" , NULL ) ;
4552 EXRETURN ;
4553 }
4554
4555 #if 0
4556 if( w == grapher->opt_color_up_pb ){
4557 GRA_handle_keypress( grapher , "r" , NULL ) ;
4558 EXRETURN ;
4559 }
4560 #endif
4561
4562 if( w == grapher->opt_quit_pb ){
4563 #if 0
4564 GRA_handle_keypress( grapher , "q" , NULL ) ;
4565 #else
4566 STATUS("User pressed Done button: starting timeout") ;
4567 grapher->valid = 666 ;
4568 (void) XtAppAddTimeOut( XtWidgetToApplicationContext(w) ,
4569 50 , GRA_quit_timeout_CB , grapher ) ;
4570 #endif
4571 EXRETURN ;
4572 }
4573
4574 if( w == grapher->opt_save_pb ){
4575 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4576 GRA_handle_keypress( grapher , "S" , NULL ) ;
4577 EXRETURN ;
4578 }
4579
4580 if( w == grapher->opt_write_center_pb ){
4581 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4582 GRA_handle_keypress( grapher , "w" , NULL ) ;
4583 EXRETURN ;
4584 }
4585
4586 if( w == grapher->opt_write_suffix_pb ){
4587 /* EXRONE(grapher) ; */ /* 22 Sep 2000 */
4588 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4589 MCW_choose_string( grapher->option_rowcol ,
4590 "'Write Center' Suffix:" , Grapher_Stuff.wcsuffix ,
4591 GRA_wcsuffix_choose_CB , NULL ) ;
4592 EXRETURN ;
4593 }
4594
4595 if( w == grapher->opt_scale_choose_pb ){
4596 MCW_choose_integer( grapher->option_rowcol , "Scale" ,
4597 -9999 , 9999 , (int)(grapher->fscale) ,
4598 GRA_scale_choose_CB , (XtPointer) grapher ) ;
4599 EXRETURN ;
4600 }
4601
4602 #ifndef USE_OPTMENUS
4603 if( w == grapher->opt_mat_choose_pb ){
4604 MCW_choose_integer( grapher->option_rowcol , "Matrix" ,
4605 1 , grapher->mat_max , grapher->mat ,
4606 GRA_mat_choose_CB , (XtPointer) grapher ) ;
4607 EXRETURN ;
4608 }
4609 #endif
4610
4611 if( w == grapher->opt_grid_choose_pb ){
4612 MCW_choose_integer( grapher->option_rowcol , "Grid" ,
4613 1 , grid_ar[GRID_MAX-1] , grapher->grid_spacing ,
4614 GRA_grid_choose_CB , (XtPointer) grapher ) ;
4615 EXRETURN ;
4616 }
4617
4618 if( w == grapher->opt_pin_choose_pb ){ /* 19 Mar 2004 */
4619 char *lvec[3] = { "Bot..." , "Top..." , "Stride" } ;
4620 float fvec[3] ;
4621 int nav ; MCW_arrowval **av ;
4622 fvec[0] = grapher->pin_bot ;
4623 fvec[1] = grapher->pin_top ;
4624 fvec[2] = grapher->pin_stride ;
4625 MCW_choose_vector( grapher->option_rowcol , "Graph Pins: Bot..Top-1" ,
4626 3 , lvec,fvec ,
4627 GRA_pin_choose_CB , (XtPointer)grapher ) ;
4628 /* adjust some stuff on the 'vector' choosers [08 Jun 2020] */
4629 av = MCW_choose_vector_avarray( &nav ) ;
4630 av[0]->fmin = av[0]->imin = 0 ; /* change min for Bot */
4631 av[1]->fmin = av[1]->imin = 0 ; /* min for Top */
4632 av[1]->fmax = av[1]->imax = grapher->status->num_series ; /* max for Top */
4633 av[2]->fmin = av[2]->imin = 1 ; /* min for Stride */
4634 av[2]->fmax = av[2]->imax = MAX_STRIDE ; /* max for Stride */
4635 MCW_reghint_children( av[0]->wrowcol , "First index to graph" ) ;
4636 MCW_reghint_children( av[1]->wrowcol , "One AFTER last index to graph" ) ;
4637 MCW_reghint_children( av[2]->wrowcol , "Spacing between graphed indexes") ;
4638 EXRETURN ;
4639 }
4640
4641 #ifndef USE_OPTMENUS
4642 if( w == grapher->opt_slice_choose_pb && grapher->status->nz > 1 ){
4643 MCW_choose_integer( grapher->option_rowcol , "Slice" ,
4644 0 , grapher->status->nz - 1 , grapher->zpoint ,
4645 GRA_slice_choose_CB , (XtPointer) grapher ) ;
4646 EXRETURN ;
4647 }
4648 #endif
4649
4650 /*** 09 Jan 1998: x-axis stuff ***/
4651
4652 if( w == grapher->opt_xaxis_clear_pb ){
4653 mri_free( grapher->xax_tsim ) ; grapher->xax_tsim = NULL ;
4654 mri_free( grapher->xax_cen ) ; grapher->xax_cen = NULL ; /* 12 Feb 2015 */
4655 grapher->xax_dset = NULL ; /* 10 Feb 2015 */
4656 DESTROY_FD_BRICK(grapher->xax_fdbr) ; grapher->xax_fdbr = NULL ;
4657 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4658 redraw_graph( grapher , 0 ) ;
4659 EXRETURN ;
4660 }
4661
4662 if( w == grapher->opt_xaxis_pick_pb ){
4663 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4664 if( IMARR_COUNT(GLOBAL_library.timeseries) > 0 ){
4665 POPDOWN_strlist_chooser ;
4666 MCW_choose_timeseries( grapher->fdw_graph , "Graph x-axis" ,
4667 GLOBAL_library.timeseries , -1 ,
4668 GRA_pick_xaxis_CB , (XtPointer) grapher ) ;
4669 } else {
4670 (void) MCW_popup_message(
4671 grapher->option_rowcol ,
4672 "No timeseries library\nexists to pick from!" ,
4673 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4674 }
4675 EXRETURN ;
4676 }
4677
4678 #ifdef BE_AFNI_AWARE
4679 if( w == grapher->opt_xaxis_dset_pb ){ /* 09 Feb 2015 */
4680 FD_brick *br = (FD_brick *)grapher->getaux ;
4681 Three_D_View *im3d = (Three_D_View *)br->parent ;
4682 int vv , ii ; THD_3dim_dataset *dset ;
4683
4684 if( !IM3D_OPEN(im3d) ){
4685 ERROR_message("can't access AFNI controller for grapher?!?") ;
4686 EXRETURN ;
4687 }
4688
4689 cdds.ndset = 0 ;
4690 cdds.dset = (THD_3dim_dataset **)realloc(cdds.dset,
4691 sizeof(THD_3dim_dataset *)
4692 *im3d->ss_now->num_dsset ) ;
4693 cdds.cb = GRA_finalize_xaxis_dset_CB ;
4694 cdds.parent = grapher ;
4695 vv = im3d->vinfo->view_type ;
4696 for( ii=0 ; ii < im3d->ss_now->num_dsset ; ii++ ){
4697 dset = GET_SESSION_DSET(im3d->ss_now, ii, vv) ;
4698 if( ISVALID_DSET(dset) && /* qualifications */
4699 EQUIV_GRIDS(dset,im3d->anat_now) &&
4700 DSET_NVALS(dset) >= DSET_NVALS(im3d->anat_now) &&
4701 DSET_INMEMORY(dset) )
4702 cdds.dset[cdds.ndset++] = dset ;
4703 }
4704 if( cdds.ndset > 0 ){
4705 POPDOWN_timeseries_chooser ;
4706 AFNI_choose_dataset_CB( grapher->fdw_graph , im3d , &cdds ) ;
4707 } else {
4708 MCW_popup_message( grapher->fdw_graph ,
4709 " \n"
4710 "** No usable datasets **\n"
4711 "** available for X-axis **\n " ,
4712 MCW_USER_KILL | MCW_TIMER_KILL ) ;
4713 }
4714 EXRETURN ;
4715 }
4716 #endif
4717
4718 if( w == grapher->opt_xaxis_center_pb ){
4719 EXRONE(grapher) ; /* 22 Sep 2000 */
4720 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
4721 if( grapher->cen_tsim != NULL ){
4722 mri_free( grapher->xax_tsim ) ;
4723 grapher->xax_tsim = mri_to_float( grapher->cen_tsim ) ;
4724 grapher->xax_dset = NULL ; /* 10 Feb 2015 */
4725 DESTROY_FD_BRICK(grapher->xax_fdbr) ; grapher->xax_fdbr = NULL ;
4726 mri_free(grapher->xax_cen) ; grapher->xax_cen = NULL ; /* 12 Feb 2015 */
4727 redraw_graph(grapher,0) ;
4728 } else {
4729 BEEPIT ; WARNING_message("graph center time series not defined!?") ;
4730 }
4731 EXRETURN ;
4732 }
4733
4734 /** 07 Aug 2001: Set Global baseline **/
4735
4736 if( w == grapher->opt_baseline_setglobal_pb ){
4737 MCW_choose_integer( grapher->option_rowcol , "Global Baseline" ,
4738 -29999 , 29999 , (int)(grapher->global_base) ,
4739 GRA_finalize_global_baseline_CB ,
4740 (XtPointer) grapher ) ;
4741 EXRETURN ;
4742 }
4743
4744 /** shouldn't get to here, but who knows? **/
4745
4746 EXRETURN ;
4747 }
4748
4749 /*----------------------------------------------------------------------*/
4750
GRA_fixup_xaxis(MCW_grapher * grapher,MRI_IMAGE * tsim)4751 void GRA_fixup_xaxis( MCW_grapher *grapher , MRI_IMAGE *tsim ) /* 09 Jan 1998 */
4752 {
4753 int ii , npt , nx , ibot , nover=0 , pbot,ptop ;
4754 float top,bot , fac ;
4755 float * xxx ;
4756
4757 ENTRY("GRA_fixup_xaxis") ;
4758
4759 if( !GRA_VALID(grapher) || tsim == NULL ) EXRETURN ;
4760
4761 ptop = TTOP(grapher) ; pbot = TBOT(grapher) ;
4762 npt = ptop ; nx = tsim->nx ; npt = MIN(npt,nx) ;
4763 xxx = MRI_FLOAT_PTR(tsim) ; if( xxx == NULL ) EXRETURN ;
4764
4765 ibot = NIGNORE(grapher) ;
4766 if( ibot >= npt-1 ) ibot = 0 ;
4767 ibot = MAX(ibot,pbot) ;
4768
4769 /* find range over plotting interval (ibot..npt-1) */
4770
4771 top = -WAY_BIG ; bot = WAY_BIG ;
4772 for( ii=ibot ; ii < npt ; ii++ ){
4773 if( xxx[ii] < WAY_BIG ){
4774 top = MAX(top,xxx[ii]) ; bot = MIN(bot,xxx[ii]) ;
4775 } else {
4776 nover++ ;
4777 }
4778 }
4779 if( bot >= top ){ /* no range to data? replace with ramp */
4780 fac = 1.0f/(nx-1.0f) ;
4781 for( ii=0 ; ii < nx ; ii++ ){
4782 if( xxx[ii] < WAY_BIG ) xxx[ii] = ii*fac ;
4783 }
4784 EXRETURN ;
4785 }
4786
4787 /* scale all of the timeseries */
4788
4789 fac = 1.0 / (top-bot) ;
4790 for( ii=0 ; ii < nx ; ii++ ){
4791 if( xxx[ii] < WAY_BIG ) xxx[ii] = fac * (xxx[ii]-bot) ;
4792 else xxx[ii] = 0.0 ;
4793 }
4794
4795 EXRETURN ;
4796 }
4797
4798 /*----------------------------------------------------------------------*/
4799
GRA_pick_xaxis_CB(Widget wcall,XtPointer cd,MCW_choose_cbs * cbs)4800 void GRA_pick_xaxis_CB( Widget wcall , XtPointer cd , MCW_choose_cbs *cbs )
4801 {
4802 MCW_grapher *grapher = (MCW_grapher *) cd ;
4803 int its ;
4804 MRI_IMAGE *tsim ;
4805
4806 ENTRY("GRA_pick_xaxis_CB") ;
4807
4808 if( !GRA_VALID(grapher) || cbs->reason != mcwCR_timeseries ) EXRETURN ;
4809 GRA_timer_stop( grapher ) ;
4810
4811 its = cbs->ival ;
4812 if( its >= 0 && its < IMARR_COUNT(GLOBAL_library.timeseries) ){
4813 tsim = IMARR_SUBIMAGE(GLOBAL_library.timeseries,its) ;
4814 mri_free( grapher->xax_tsim ) ;
4815 grapher->xax_tsim = mri_to_float(tsim) ; /* a copy */
4816 grapher->xax_dset = NULL ; /* 10 Feb 2015 */
4817 DESTROY_FD_BRICK(grapher->xax_fdbr) ; grapher->xax_fdbr = NULL ;
4818 mri_free(grapher->xax_cen) ; grapher->xax_cen = NULL ; /* 12 Feb 2015 */
4819 } else {
4820 mri_free( grapher->xax_tsim ) ; grapher->xax_tsim = NULL ;
4821 }
4822
4823 redraw_graph( grapher , 0 ) ;
4824 EXRETURN ;
4825 }
4826
4827 #ifdef BE_AFNI_AWARE
4828 /*----------------------------------------------------------------------*/
4829 /* Stuff for dataset as X-axis [09 Feb 2015] */
4830
GRA_finalize_xaxis_dset_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)4831 static void GRA_finalize_xaxis_dset_CB( Widget w, XtPointer cd, MCW_choose_cbs *cbs )
4832 {
4833 Three_D_View *im3d = (Three_D_View *)cd ;
4834 MCW_grapher *grapher = (MCW_grapher *)cdds.parent ;
4835 FD_brick *br = (FD_brick *)grapher->getaux ;
4836 THD_3dim_dataset *dset ;
4837 int ival ;
4838
4839 ENTRY("GRA_finalize_xaxis_dset_CB") ;
4840
4841 if( !GRA_REALZ(grapher) || cbs == NULL ){ POPDOWN_strlist_chooser; EXRETURN; }
4842 if( br == NULL ) { POPDOWN_strlist_chooser; EXRETURN; }
4843 if( !IM3D_OPEN(im3d) ) { POPDOWN_strlist_chooser; EXRETURN; }
4844
4845 ival = cbs->ival ;
4846 if( ival < 0 || ival >= cdds.ndset ) { POPDOWN_strlist_chooser; EXRETURN; }
4847
4848 dset = cdds.dset[ival] ;
4849 if( DSET_NVALS(dset) >= DSET_NVALS(im3d->anat_now) &&
4850 EQUIV_GRIDS(dset,im3d->anat_now) ){
4851 grapher->xax_dset = (void *)dset ;
4852 } else {
4853 grapher->xax_dset = NULL ;
4854 }
4855
4856 /* make FD_brick corresponding to the one being viewed in this grapher */
4857
4858 DESTROY_FD_BRICK(grapher->xax_fdbr) ; grapher->xax_fdbr = NULL ;
4859 if( grapher->xax_dset != NULL ){
4860 FD_brick *br = (FD_brick *)grapher->getaux ;
4861 grapher->xax_fdbr = THD_3dim_dataset_to_brick( dset , br->a123.ijk[0] ,
4862 br->a123.ijk[1] ,
4863 br->a123.ijk[2] ) ;
4864 }
4865
4866 mri_free( grapher->xax_tsim ) ; grapher->xax_tsim = NULL ;
4867
4868 redraw_graph(grapher,0) ;
4869 EXRETURN ;
4870 }
4871 #endif
4872
4873 /*----------------------------------------------------------------------
4874 Callbacks from popup choosers
4875 ------------------------------------------------------------------------*/
4876
GRA_wcsuffix_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)4877 void GRA_wcsuffix_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
4878 {
4879 int ll , ii ;
4880
4881 ENTRY("GRA_wcsuffix_choose_CB") ;
4882
4883 if( cbs->reason != mcwCR_string ||
4884 cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ){
4885
4886 BEEPIT ; WARNING_message("illegal suffix choice!?") ; EXRETURN ;
4887 }
4888
4889 for( ii=0 ; ii < ll ; ii++ ){
4890 if( iscntrl(cbs->cval[ii]) ||
4891 isspace(cbs->cval[ii]) ||
4892 cbs->cval[ii] == '/' ){
4893
4894 BEEPIT ; WARNING_message("illegal suffix choice?!") ; EXRETURN ;
4895 }
4896 }
4897
4898 if( Grapher_Stuff.wcsuffix != NULL ) myXtFree(Grapher_Stuff.wcsuffix) ;
4899
4900 Grapher_Stuff.wcsuffix = XtNewString(cbs->cval) ;
4901 EXRETURN ;
4902 }
4903
4904 /*-----------------------------------------------------------------------------*/
4905
4906 #ifdef USE_OPTMENUS
GRA_mat_choose_CB(MCW_arrowval * cbs,XtPointer cd)4907 void GRA_mat_choose_CB( MCW_arrowval * cbs , XtPointer cd )
4908 #else
4909 void GRA_mat_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
4910 #endif
4911 {
4912 MCW_grapher *grapher = (MCW_grapher *) cd ;
4913
4914 ENTRY("GRA_mat_choose_CB") ;
4915
4916 if( ! GRA_VALID(grapher) || cbs->ival < 1 ) EXRETURN ;
4917
4918 grapher->mat = MIN( grapher->mat_max , cbs->ival ) ;
4919 init_mat ( grapher ) ;
4920 redraw_graph( grapher , 0 ) ;
4921 send_newinfo( grapher ) ;
4922 EXRETURN ;
4923 }
4924
4925 /*-----------------------------------------------------------------------------*/
4926
GRA_scale_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)4927 void GRA_scale_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
4928 {
4929 MCW_grapher *grapher = (MCW_grapher *) cd ;
4930
4931 ENTRY("GRA_scale_choose_CB") ;
4932
4933 if( ! GRA_VALID(grapher) ) EXRETURN ;
4934
4935 grapher->fscale = cbs->fval ;
4936 redraw_graph( grapher , 0 ) ;
4937 EXRETURN ;
4938 }
4939
4940 /*-----------------------------------------------------------------------------*/
4941
GRA_grid_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)4942 void GRA_grid_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
4943 {
4944 MCW_grapher *grapher = (MCW_grapher *) cd ;
4945
4946 ENTRY("GRA_grid_choose_CB") ;
4947
4948 if( ! GRA_VALID(grapher) ) EXRETURN ;
4949 grapher->grid_spacing = cbs->ival ;
4950 grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
4951 redraw_graph(grapher,0) ;
4952 EXRETURN ;
4953 }
4954
4955 /*-----------------------------------------------------------------------------*/
4956
GRA_pin_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)4957 void GRA_pin_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
4958 {
4959 MCW_grapher *grapher = (MCW_grapher *) cd ;
4960 float *vec = (float *)(cbs->cval) ;
4961 int pb=(int)vec[0], pt=(int)vec[1], ps=(int)vec[2], pvec[3] ;
4962
4963 ENTRY("GRA_pin_choose_CB") ;
4964
4965 GRA_timer_stop( grapher ) ;
4966
4967 /* check for criminal behaviour */
4968
4969 if( ps <= 0 ) ps = 1 ;
4970 if( pt > grapher->status->num_series ) pt = grapher->status->num_series ;
4971
4972 if( pb >= grapher->status->num_series-2 ||
4973 ps > MAX_STRIDE ||
4974 (pt > 0 && NABC(pb,pt,ps) < 2) ){ /* stupid user */
4975
4976 BEEPIT ; WARNING_message("Illegal Pin/Stride indexes!?") ; EXRETURN ;
4977 }
4978
4979 pvec[0] = pb ;
4980 pvec[1] = pt ;
4981 pvec[2] = ps ;
4982 drive_MCW_grapher( grapher , graDR_setpins , (XtPointer)pvec ) ;
4983 EXRETURN ;
4984 }
4985
4986 /*-----------------------------------------------------------------------------*/
4987
GRA_ggap_CB(MCW_arrowval * cbs,XtPointer cd)4988 void GRA_ggap_CB( MCW_arrowval *cbs , XtPointer cd ) /* 12 Jan 1998 */
4989 {
4990 MCW_grapher *grapher = (MCW_grapher *) cd ;
4991 int gg ;
4992
4993 ENTRY("GRA_ggap_CB") ;
4994
4995 if( ! GRA_VALID(grapher) ) EXRETURN ;
4996
4997 gg = grapher->ggap ; grapher->ggap = cbs->ival ;
4998 if( gg != grapher->ggap ){
4999 init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
5000 }
5001
5002 EXRETURN ;
5003 }
5004
5005 /*-----------------------------------------------------------------------------*/
5006
GRA_gthick_CB(MCW_arrowval * cbs,XtPointer cd)5007 void GRA_gthick_CB( MCW_arrowval *cbs , XtPointer cd ) /* 06 Oct 2004 */
5008 {
5009 MCW_grapher *grapher = (MCW_grapher *) cd ;
5010 int gg ;
5011
5012 ENTRY("GRA_gthick_CB") ;
5013
5014 if( ! GRA_VALID(grapher) ) EXRETURN ;
5015
5016 gg = grapher->gthick ; grapher->gthick = cbs->ival ;
5017 if( gg != grapher->gthick ){
5018 init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
5019 }
5020
5021 EXRETURN ;
5022 }
5023
5024 /*-----------------------------------------------------------------------------*/
5025
GRA_upsam_CB(MCW_arrowval * cbs,XtPointer cd)5026 void GRA_upsam_CB( MCW_arrowval *cbs , XtPointer cd ) /* 28 May 2020 */
5027 {
5028 MCW_grapher *grapher = (MCW_grapher *) cd ;
5029 int uu ;
5030
5031 ENTRY("GRA_upsam_CB") ;
5032
5033 if( ! GRA_VALID(grapher) ) EXRETURN ;
5034
5035 uu = grapher->do_upsam ; grapher->do_upsam = cbs->ival ;
5036 if( uu != grapher->do_upsam ){
5037 init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
5038 }
5039
5040 EXRETURN ;
5041 }
5042
5043 /*-----------------------------------------------------------------------------*/
5044
5045 #ifdef USE_OPTMENUS
GRA_slice_choose_CB(MCW_arrowval * cbs,XtPointer cd)5046 void GRA_slice_choose_CB( MCW_arrowval *cbs , XtPointer cd )
5047 #else
5048 void GRA_slice_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
5049 #endif
5050 {
5051 MCW_grapher *grapher = (MCW_grapher *) cd ;
5052
5053 ENTRY("GRA_slice_choose_CB") ;
5054
5055 if( ! GRA_VALID(grapher) ) EXRETURN ;
5056
5057 grapher->zpoint = cbs->ival ;
5058 if( grapher->zpoint >= grapher->status->nz )
5059 grapher->zpoint = grapher->status->nz - 1 ;
5060 redraw_graph( grapher , 0 ) ;
5061 send_newinfo( grapher ) ;
5062 EXRETURN ;
5063 }
5064
5065 /*-----------------------------------------------------------------------------*/
5066
5067 #ifdef USE_OPTMENUS
GRA_ignore_choose_CB(MCW_arrowval * cbs,XtPointer cd)5068 void GRA_ignore_choose_CB( MCW_arrowval * cbs , XtPointer cd )
5069 #else
5070 void GRA_ignore_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
5071 #endif
5072 {
5073 MCW_grapher *grapher = (MCW_grapher *) cd ;
5074
5075 ENTRY("GRA_ignore_choose_CB") ;
5076
5077 if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
5078
5079 if( cbs->ival >= 0 && cbs->ival < TTOP(grapher)-1 ){
5080 GRA_cbs gbs ;
5081
5082 gbs.reason = graCR_setignore ;
5083 gbs.key = cbs->ival ;
5084 #if 0
5085 grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
5086 #else
5087 CALL_sendback( grapher , gbs ) ;
5088 #endif
5089 }
5090 EXRETURN ;
5091 }
5092
5093 /*-----------------------------------------------------------------------------*/
5094
5095 #ifdef USE_OPTMENUS
GRA_polort_choose_CB(MCW_arrowval * cbs,XtPointer cd)5096 void GRA_polort_choose_CB( MCW_arrowval * cbs , XtPointer cd )
5097 #else
5098 void GRA_polort_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
5099 #endif
5100 {
5101 MCW_grapher * grapher = (MCW_grapher *) cd ;
5102
5103 ENTRY("GRA_polort_choose_CB") ;
5104
5105 if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
5106
5107 if( cbs->ival >= 0 && cbs->ival <= MAX_POLORT ){
5108 GRA_cbs gbs ;
5109
5110 gbs.reason = graCR_polort ;
5111 gbs.key = cbs->ival ;
5112 #if 0
5113 grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
5114 #else
5115 CALL_sendback( grapher , gbs ) ;
5116 #endif
5117 }
5118 EXRETURN ;
5119 }
5120
5121 /*-----------------------------------------------------------------------------*/
5122
GRA_bkthr_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)5123 void GRA_bkthr_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
5124 {
5125 ENTRY("GRA_bkthr_choose_CB") ;
5126 SET_FIM_bkthr( cbs->fval ) ;
5127 EXRETURN ;
5128 }
5129
5130 /*-----------------------------------------------------------------------------*/
5131
GRA_refread_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)5132 void GRA_refread_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
5133 {
5134 MCW_grapher * grapher = (MCW_grapher *) cd ;
5135 MRI_IMAGE * flim ;
5136 float * far ;
5137 int ii ;
5138 GRA_cbs gbs ;
5139
5140 ENTRY("GRA_refread_choose_CB") ;
5141
5142 if( ! GRA_VALID(grapher) ||
5143 grapher->status->send_CB == NULL ||
5144 cbs->reason != mcwCR_string ||
5145 cbs->cval == NULL || strlen(cbs->cval) == 0 ) EXRETURN ;
5146
5147 EXRONE(grapher) ; /* 22 Sep 2000 */
5148
5149 flim = mri_read_1D( cbs->cval ) ; /* 16 Nov 1999: replaces mri_read_ascii */
5150 if( flim == NULL || flim->nx < 2 ){
5151 BEEPIT ; mri_free(flim) ; WARNING_message("Can't read time seies file!?") ; EXRETURN ;
5152 }
5153
5154 far = MRI_FLOAT_PTR(flim) ;
5155 for( ii=0 ; ii < flim->nvox ; ii++ )
5156 if( fabs(far[ii]) >= 33333.0 ) far[ii] = WAY_BIG ;
5157
5158 { GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
5159 MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
5160 gbs.reason = graCR_refequals ;
5161 gbs.userdata = (XtPointer) flim ;
5162 #if 0
5163 grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
5164 #else
5165 CALL_sendback( grapher , gbs ) ;
5166 #endif
5167 mri_free(flim) ;
5168 EXRETURN ;
5169 }
5170
5171 /*-----------------------------------------------------------------------------*/
5172
GRA_refstore_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)5173 void GRA_refstore_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
5174 {
5175 MCW_grapher * grapher = (MCW_grapher *) cd ;
5176
5177 ENTRY("GRA_refstore_choose_CB") ;
5178
5179 if( ! GRA_VALID(grapher) ||
5180 grapher->ref_ts == NULL ||
5181 IMARR_COUNT(grapher->ref_ts) < 1 ||
5182 cbs->reason != mcwCR_string ||
5183 cbs->cval == NULL || strlen(cbs->cval) == 0 ) EXRETURN ;
5184
5185 EXRONE(grapher) ; /* 22 Sep 2000 */
5186
5187 PLUTO_register_timeseries( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
5188 EXRETURN ;
5189 }
5190
5191 /*-----------------------------------------------------------------------------*/
5192
GRA_refwrite_choose_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)5193 void GRA_refwrite_choose_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs * cbs )
5194 {
5195 MCW_grapher * grapher = (MCW_grapher *) cd ;
5196 MRI_IMAGE * tsim ;
5197 int ii , ll ;
5198 GRA_cbs gbs ;
5199
5200 ENTRY("GRA_refwrite_choose_CB") ;
5201
5202 if( ! GRA_VALID(grapher) ||
5203 grapher->ref_ts == NULL ||
5204 IMARR_COUNT(grapher->ref_ts) < 1 ||
5205 cbs->reason != mcwCR_string ||
5206 cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ) EXRETURN ;
5207
5208 EXRONE(grapher) ; /* 22 Sep 2000 */
5209
5210 for( ii=0 ; ii < ll ; ii++ ){
5211 if( iscntrl(cbs->cval[ii]) || isspace(cbs->cval[ii]) ||
5212 cbs->cval[ii] == '/' || cbs->cval[ii] == ';' ||
5213 cbs->cval[ii] == '*' || cbs->cval[ii] == '?' ||
5214 cbs->cval[ii] == '&' || cbs->cval[ii] == '|' ||
5215 cbs->cval[ii] == '"' || cbs->cval[ii] == '>' ||
5216 cbs->cval[ii] == '<' || cbs->cval[ii] == '\'' ||
5217 cbs->cval[ii] == '[' || cbs->cval[ii] == ']' ){
5218
5219 BEEPIT ; WARNING_message("Illegal filename") ; EXRETURN ;
5220 }
5221 }
5222
5223 #if 0
5224 tsim = mri_transpose( IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
5225 mri_write_ascii( cbs->cval , tsim ) ;
5226 mri_free( tsim ) ;
5227 #else
5228 mri_write_1D( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ; /* 16 Nov 1999 */
5229 #endif
5230
5231 /* 12 Nov 1996: put this in AFNI's list of library files */
5232
5233 if( grapher->status->send_CB != NULL ){
5234 mri_add_name( cbs->cval , IMARR_SUBIMAGE(grapher->ref_ts,0) ) ;
5235 gbs.reason = graCR_timeseries_library ;
5236 gbs.userdata = (XtPointer) IMARR_SUBIMAGE(grapher->ref_ts,0) ;
5237 #if 0
5238 grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
5239 #else
5240 CALL_sendback( grapher , gbs ) ;
5241 #endif
5242 }
5243 EXRETURN ;
5244 }
5245
5246 /*-----------------------------------------------------------------------
5247 External interface to drive an MCW_grapher:
5248 grapher = pointer to structure returned by new_MCW_grapher
5249 drive_code = integer indicating which action to take
5250 drive_data = data or pointer to data controlling action
5251 (you will probably have to cast this to
5252 XtPointer to avoid ugly warnings from the compiler)
5253
5254 OK drive_code drive_data should be
5255 -- ---------- --------------------
5256 * graDR_cursor (int) with new cursor id for the image window;
5257 (if negative, means from cursorfont)
5258
5259 * graDR_realize (ignored) an unrealized viewer is re-realized
5260
5261 * graDR_redraw (int *) array of 4 ints: x,y,z,m
5262 redraw the graph centered at x,y,z with matrix m
5263
5264 * graDR_destroy (ignored) destroy this MCW_grapher, and delete its
5265 own XtMalloc-ed internal data structures;
5266 after this call, you must myXtFree(grapher) to finish
5267 the job.
5268
5269 * graDR_newdata (XtPointer) contains new auxiliary data for getser;
5270 this call switches the data sequence to a
5271 new one entirely. As with imseq, this should
5272 be followed by a call with graDR_redraw.
5273
5274 * graDR_title (char *) contains new string for window title bar
5275
5276 * graDR_icon (Pixmap) sets the icon for this window
5277
5278 * graDR_addref_ts (MRI_IMAGE *) adds a reference timeseries to the list
5279 input == NULL --> delete all references
5280 ** N.B.: The input timeseries will not be copied, just
5281 will keep a pointer to it. Thus, the input
5282 timeseries should not be destroyed.
5283
5284 * graDR_addort_ts (MRI_IMAGE *) adds an ort timeseries to the list
5285 input == NULL --> delete all orts
5286
5287 * graDR_winaver (int) 0=off 1=on WinAver toggle on FIM menu
5288
5289 * graDR_setignore (int) set the initial ignore level for graphs
5290
5291 * graDR_polort (int) set the polort level for fimmery
5292
5293 * graDR_setindex (int) contains the new time_index;
5294 All this does is draw some stuff.
5295
5296 * graDR_button2_enable (ignored) Turn button2 reporting on
5297 * graDR_button2_disable (ignored) and off.
5298
5299 * graDR_fim_disable (ignored) Turn all FIM stuff off (for good)
5300
5301 * graDR_mirror (int) Turn mirroring on (==1) or off (==0)
5302
5303 * graDR_setmatrix (int) These 3 items set their corresponding
5304 * graDR_setgrid parameters to the drive parameter.
5305
5306 * graDR_newlength (int) set the expected length of time series
5307 to be some new value (e.g., the pin number)
5308 * graDR_setpinnum [same as newlength]
5309 * graDR_setpintop [same as newlength]
5310
5311 * graDR_setpinbot (int) set the bottom index for plotting
5312 * graDR_setpins (int *) set top AND bottom index AND stride
5313 for plotting; points to array of 3 ints
5314
5315 * graDR_setglobalbaseline (float *) Global baseline value
5316
5317 The RwcBoolean return value is True for success, False for failure.
5318 -------------------------------------------------------------------------*/
5319
drive_MCW_grapher(MCW_grapher * grapher,int drive_code,XtPointer drive_data)5320 RwcBoolean drive_MCW_grapher( MCW_grapher * grapher ,
5321 int drive_code , XtPointer drive_data )
5322 {
5323
5324 ENTRY("drive_MCW_grapher") ;
5325
5326 if( ! GRA_VALID(grapher) ) RETURN(False) ;
5327
5328 switch( drive_code ){
5329
5330 /*------- error! -------*/
5331
5332 default:{
5333 WARNING_message("drive_MCW_grapher: code=%d illegal!",drive_code) ;
5334 BEEPIT ; RETURN(False) ;
5335 }
5336
5337 /*------ winaver [27 Jan 2004] -----*/
5338
5339 case graDR_winaver:{
5340 int vvv = PTOI(drive_data) ;
5341 MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , vvv ) ;
5342 RETURN( True ) ;
5343 }
5344
5345 /*------ setglobalbaseline [07 Aug 2001] -----*/
5346
5347 case graDR_setglobalbaseline:{
5348 float *vvv = (float *)drive_data ; /* get value */
5349 int ii = thd_floatscan( 1 , vvv ) ; /* check value */
5350 MCW_choose_cbs cb ;
5351 if( ii != 0 ) RETURN( False ) ; /* this is bad */
5352 cb.reason = mcwCR_integer ;
5353 cb.fval = *vvv ;
5354 GRA_finalize_global_baseline_CB(NULL,(XtPointer)grapher,&cb) ;
5355 RETURN( True ) ;
5356 }
5357
5358 /*------ setmatrix [22 Sep 2000] -----*/
5359
5360 case graDR_setmatrix:{
5361 int mm = PTOI(drive_data) ;
5362 if( mm < 0 ) RETURN( False ) ;
5363 grapher->mat = MIN( grapher->mat_max , mm ) ;
5364 init_mat ( grapher ) ;
5365 redraw_graph( grapher, PLOTCODE_AUTOSCALE ); /* 12 Oct 2000: autoscale */
5366 send_newinfo( grapher ) ;
5367 RETURN( True ) ;
5368 }
5369
5370 /*------ setgrid [22 Sep 2000] -----*/
5371
5372 case graDR_setgrid:{
5373 int mm = PTOI(drive_data) ;
5374 if( mm < 2 ) RETURN( False ) ;
5375 grapher->grid_spacing = mm ;
5376 grapher->grid_fixed = 1 ; /* 02 Apr 2004 */
5377 redraw_graph(grapher,0) ;
5378 RETURN( True ) ;
5379 }
5380
5381 /*------ mirroring (Jul 2000) -----*/
5382
5383 case graDR_mirror:{
5384 int ii = PTOI(drive_data) ;
5385
5386 if( ii != grapher->mirror ){
5387 grapher->mirror = ii ;
5388 init_mat( grapher ) ; redraw_graph( grapher , 0 ) ;
5389 }
5390 }
5391 break ;
5392
5393 /*------ fim disabling -----*/
5394
5395 case graDR_fim_disable:{
5396 int ii ;
5397 XtUnmanageChild( grapher->fmenu->fim_cbut ) ;
5398 XtUnmanageChild( grapher->opt_xaxis_cbut ) ;
5399 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
5400 if( gr_unfim[ii] ){
5401 if( grapher->opt_color_av[ii] != NULL )
5402 XtUnmanageChild( grapher->opt_color_av[ii]->wrowcol ) ;
5403 if( grapher->opt_thick_bbox[ii] != NULL )
5404 XtUnmanageChild( grapher->opt_thick_bbox[ii]->wtop ) ;
5405 if( grapher->opt_points_bbox[ii] != NULL )
5406 XtUnmanageChild( grapher->opt_points_bbox[ii]->wtop ) ;
5407 }
5408 }
5409 }
5410 break ;
5411
5412 /*------ button2 stuff -----*/
5413
5414 case graDR_button2_enable:{
5415 grapher->button2_enabled = 1 ;
5416 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
5417 RETURN( True ) ;
5418 }
5419
5420 case graDR_button2_disable:{
5421 grapher->button2_enabled = 0 ;
5422 RETURN( True ) ;
5423 }
5424
5425 /*------ set time index -----*/
5426
5427 case graDR_setindex:{
5428 int new_index = PTOI(drive_data) ; /* Pointer to Integer cast */
5429
5430 if( new_index < 0 || new_index >= grapher->status->num_series )
5431 RETURN( False ) ;
5432
5433 if( new_index != grapher->time_index ){
5434 grapher->time_index = new_index ;
5435 if( grapher->textgraph )
5436 redraw_graph( grapher , 0 ) ;
5437 else
5438 GRA_redraw_overlay( grapher ) ;
5439 }
5440 RETURN( True ) ;
5441 }
5442
5443 /*------ reset top of time series plotting ------*/
5444 /* (same as graDR_setpinnum and graDR_setpintop) */
5445
5446 case graDR_newlength:{
5447 int newtop=PTOI(drive_data) ;
5448
5449 if( newtop < MIN_PIN ) newtop = 0 ;
5450 if( newtop > MAX_PIN ) newtop = MAX_PIN ;
5451
5452 grapher->pin_top = newtop ;
5453 if( NPTS(grapher) < 2 ) grapher->pin_bot = 0 ;
5454
5455 #ifdef USE_OPTMENUS
5456 GRA_fix_optmenus( grapher ) ;
5457 #endif
5458 redraw_graph( grapher, 0 ) ;
5459 RETURN( True ) ;
5460 }
5461
5462 /*------ reset bottom of time series plotting [17 Mar 2004] -----*/
5463
5464 case graDR_setpinbot:{
5465 int newbot=PTOI(drive_data) ;
5466
5467 if( newbot < 0 ) newbot = 0 ;
5468 if( newbot >= TTOP(grapher) ) newbot = 0 ;
5469
5470 grapher->pin_bot = newbot ;
5471
5472 #ifdef USE_OPTMENUS
5473 GRA_fix_optmenus( grapher ) ;
5474 #endif
5475 redraw_graph( grapher, 0 ) ;
5476 RETURN( True ) ;
5477 }
5478
5479 /*------ reset bot and top of time series plotting [19 Mar 2004] -----*/
5480
5481 case graDR_setpins:{
5482 int *pvec = (int *)drive_data ;
5483 int newbot,newtop,newstride ;
5484
5485 if( pvec == NULL ){
5486 newbot = newtop = 0 ; newstride = 1 ;
5487 } else {
5488 newbot = pvec[0] ; if( newbot < 0 ) newbot = 0 ;
5489 newtop = pvec[1] ; if( newtop < newbot ) newtop = 0 ;
5490 if( newtop < MIN_PIN ) newtop = 0 ;
5491 newstride = pvec[2] ;
5492 if( newstride <= 0 || newstride > 9 ) newstride = 1 ;
5493 }
5494 if( newtop > 0 && NABC(newbot,newtop,newstride) < 2 ){
5495 newbot = newtop = 0 ; newstride = 1 ;
5496 }
5497 if( newbot >= TTOP(grapher) ) newbot = 0 ;
5498
5499 grapher->pin_bot = newbot ;
5500 grapher->pin_top = newtop ;
5501 grapher->pin_stride = newstride ;
5502
5503 #ifdef USE_OPTMENUS
5504 GRA_fix_optmenus( grapher ) ;
5505 #endif
5506 redraw_graph( grapher, 0 ) ;
5507 RETURN( True ) ;
5508 }
5509
5510 /*------ set ignore count -----*/
5511
5512 case graDR_setignore:{
5513 int new_ignore = PTOI(drive_data) ;
5514
5515 if( new_ignore >= 0 && new_ignore < TTOP(grapher)-1 ){
5516 grapher->init_ignore = new_ignore ;
5517 redraw_graph( grapher , PLOTCODE_AUTOSCALE ) ;
5518 RETURN( True ) ;
5519 } else {
5520 RETURN( False ) ;
5521 }
5522 }
5523
5524 /*------- set polort [27 May 1999] --------*/
5525
5526 case graDR_polort:{
5527 int new_polort = PTOI(drive_data) ;
5528
5529 if( new_polort >= 0 ){
5530 grapher->polort = new_polort ;
5531 #ifdef USE_OPTMENUS
5532 GRA_fix_optmenus( grapher ) ;
5533 #endif
5534 }
5535 RETURN( True ) ;
5536 }
5537
5538 /*----- set reference time series (currently limited to one) -----*/
5539
5540 case graDR_addref_ts:{
5541 MRI_IMAGE *im = (MRI_IMAGE *) drive_data ;
5542
5543 if( im == NULL ){ /* no input --> kill kill kill */
5544 STATUS("freeing reference timeseries") ;
5545 FREE_IMARR(grapher->ref_ts) ; /* doesn't delete images inside */
5546 grapher->ref_ts = NULL ;
5547 } else{
5548 if( grapher->ref_ts == NULL ) INIT_IMARR( grapher->ref_ts ) ;
5549
5550 if( IMARR_COUNT(grapher->ref_ts) == 0 ){
5551 STATUS("adding reference timeseries") ;
5552 ADDTO_IMARR( grapher->ref_ts , im ) ; /* create first one */
5553 } else {
5554 STATUS("replacing reference timeseries") ;
5555 IMARR_SUBIMAGE(grapher->ref_ts,0) = im ; /* replace first one */
5556 }
5557 }
5558
5559 redraw_graph( grapher , 0 ) ;
5560 RETURN( True ) ;
5561 }
5562
5563 /*----- set ort time series (currently limited to one) -----*/
5564
5565 case graDR_addort_ts:{
5566 MRI_IMAGE *im = (MRI_IMAGE *) drive_data ;
5567
5568 if( im == NULL ){ /* no input --> kill kill kill */
5569 STATUS("freeing ort timeseries") ;
5570 FREE_IMARR(grapher->ort_ts) ;
5571 grapher->ort_ts = NULL ;
5572 } else{
5573 if( grapher->ort_ts == NULL ) INIT_IMARR( grapher->ort_ts ) ;
5574
5575 if( IMARR_COUNT(grapher->ort_ts) == 0 ){
5576 STATUS("adding ort timeseries") ;
5577 ADDTO_IMARR( grapher->ort_ts , im ) ; /* create first one */
5578 } else {
5579 STATUS("replacing ort timeseries") ;
5580 IMARR_SUBIMAGE(grapher->ort_ts,0) = im ; /* replace first one */
5581 }
5582 }
5583
5584 redraw_graph( grapher , 0 ) ;
5585 RETURN( True ) ;
5586 }
5587
5588 /*------ set icon pixmap -----*/
5589
5590 case graDR_icon:{
5591 int xret , yret ;
5592 unsigned int wret,hret,bret,dret ;
5593 Window rret ;
5594
5595 XtVaSetValues( grapher->fdw_graph , XmNiconPixmap , (Pixmap) drive_data , NULL ) ;
5596 grapher->glogo_pixmap = (Pixmap) drive_data ;
5597
5598 /* get geometry for later use */
5599
5600 if( grapher->glogo_pixmap != XmUNSPECIFIED_PIXMAP ){
5601 (void) XGetGeometry( grapher->dc->display , grapher->glogo_pixmap ,
5602 &rret , &xret , &yret , &wret , &hret , &bret , &dret ) ;
5603
5604 grapher->glogo_width = wret ;
5605 grapher->glogo_height = hret ;
5606 } else {
5607 grapher->glogo_width = 0 ;
5608 grapher->glogo_height = 0 ;
5609 }
5610 RETURN( True ) ;
5611 }
5612
5613 /*------- title --------*/
5614
5615 case graDR_title:{
5616 char * title = (char *) drive_data ;
5617
5618 if( title == NULL || strlen(title) == 0 ) RETURN( False ) ;
5619
5620 XtVaSetValues( grapher->fdw_graph , XmNtitle , title , NULL ) ;
5621 RETURN( True ) ;
5622 }
5623
5624 /*------- death! -------*/
5625
5626 case graDR_destroy:{
5627 end_fd_graph_CB( NULL , (XtPointer) grapher , NULL ) ;
5628 RETURN( True ) ;
5629 }
5630
5631 /*------- unrealize! -------*/
5632
5633 case graDR_unrealize:{
5634 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
5635 if( GRA_REALZ(grapher) ){
5636 XtUnrealizeWidget(grapher->fdw_graph); NI_sleep(1);
5637 }
5638 grapher->valid = 1 ;
5639
5640 if( grapher->fd_pxWind != (Pixmap) 0 )
5641 XFreePixmap( grapher->dc->display , grapher->fd_pxWind ) ;
5642 RETURN( True ) ;
5643 }
5644
5645 /*------- realize! -------*/
5646
5647 case graDR_realize:{
5648 if( ! GRA_REALZ(grapher) ){
5649 int width , height ;
5650
5651 grapher->valid = 2 ;
5652
5653 XtRealizeWidget( grapher->fdw_graph ) ; NI_sleep(1) ;
5654 WAIT_for_window( grapher->fdw_graph ) ; NI_sleep(1) ;
5655
5656 /* 29 Sep 2000: next 2 lines of code are for the Form change */
5657
5658 XtVaSetValues( grapher->option_rowcol ,
5659 XmNleftAttachment , XmATTACH_NONE ,
5660 XmNtopAttachment , XmATTACH_NONE ,
5661 XmNrightAttachment , XmATTACH_FORM ,
5662 XmNbottomAttachment , XmATTACH_FORM ,
5663 NULL ) ;
5664 XMapRaised( XtDisplay(grapher->option_rowcol) ,
5665 XtWindow(grapher->option_rowcol) ) ;
5666
5667 NORMAL_cursorize( grapher->fdw_graph ) ;
5668
5669 if( ISONE(grapher) )
5670 NORMAL_cursorize( grapher->draw_fd ) ; /* 07 Dec 2001 */
5671 else
5672 POPUP_cursorize( grapher->draw_fd ) ;
5673
5674 MCW_widget_geom( grapher->draw_fd , &width , &height , NULL,NULL ) ;
5675 GRA_new_pixmap( grapher , width , height , 0 ) ;
5676 #ifdef USE_OPTMENUS
5677 GRA_fix_optmenus( grapher ) ;
5678 #endif
5679 NI_sleep(1) ; /* 08 Mar 2002: for good luck */
5680
5681 if( startup_1D_transform != NULL ) /* 19 Dec 2018 */
5682 GRA_set_1D_transform( grapher , startup_1D_transform ) ;
5683 }
5684 RETURN( True ) ;
5685 }
5686
5687 /*------- new cursor for image -------*/
5688
5689 case graDR_cursor:{
5690 int cur = PTOI(drive_data) ;
5691
5692 MCW_alter_widget_cursor( grapher->fdw_graph , cur , "yellow" , "blue" ) ;
5693 RETURN( True ) ;
5694 }
5695
5696 /*------- new data sequence!!! -------*/
5697
5698 case graDR_newdata:{
5699 int npold = grapher->status->num_series ; /* 22 Sep 2000 */
5700
5701 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
5702
5703 grapher->getaux = drive_data ;
5704 #if 0
5705 grapher->status = (MCW_grapher_status *)
5706 grapher->getser(0,graCR_getstatus,drive_data) ;
5707 #else
5708 CALL_getser( grapher , 0,graCR_getstatus , MCW_grapher_status *,grapher->status ) ;
5709 #endif
5710 init_const( grapher ) ;
5711
5712 /* mustn't allow bottom of plotting range to be beyond top of data! */
5713
5714 if( grapher->pin_bot >= grapher->status->num_series-1 ) grapher->pin_bot = 0 ;
5715
5716 if( npold < 2 || !grapher->grid_fixed ){ /* 22 Sep 2000 */
5717 auto_grid( grapher , NPTS(grapher) ) ;
5718 }
5719
5720 #ifdef USE_OPTMENUS
5721 GRA_fix_optmenus( grapher ) ;
5722 #endif
5723
5724 if( ISONE(grapher) ) /* 07 Dec 2001 */
5725 NORMAL_cursorize( grapher->draw_fd ) ;
5726 else
5727 POPUP_cursorize( grapher->draw_fd ) ;
5728
5729 RETURN( True ) ;
5730 }
5731
5732 /*------- redraw -------*/
5733
5734 case graDR_redraw:{
5735 int *xym = (int *) drive_data ;
5736
5737 STATUS("graDR_redraw") ;
5738
5739 if( xym != NULL ){
5740 if( xym[0] >= 0 ) grapher->xpoint = xym[0] ;
5741 if( xym[1] >= 0 ) grapher->ypoint = xym[1] ;
5742 if( xym[2] >= 0 ) grapher->zpoint = xym[2] ;
5743 if( xym[3] > 0 ) grapher->mat = xym[3] ;
5744 init_mat(grapher) ;
5745 }
5746 redraw_graph( grapher , 0 ) ;
5747 RETURN( True ) ;
5748 }
5749
5750 } /* end of switch on drive_code */
5751
5752 RETURN( False ) ; /* should never be reached! */
5753 }
5754
5755 /*------------------------------------------------------------------
5756 Callback for all FIM menu buttons
5757 --------------------------------------------------------------------*/
5758
GRA_fim_CB(Widget w,XtPointer client_data,XtPointer call_data)5759 void GRA_fim_CB( Widget w , XtPointer client_data , XtPointer call_data )
5760 {
5761 FIM_menu * fm = (FIM_menu *) client_data ;
5762 MCW_grapher * grapher = (MCW_grapher *) fm->parent ;
5763 GRA_cbs cbs ;
5764
5765 ENTRY("GRA_fim_CB") ;
5766
5767 if( ! GRA_VALID(grapher) || grapher->status->send_CB == NULL ) EXRETURN ;
5768
5769 EXRONE(grapher) ; /* 22 Sep 2000 */
5770
5771 /*--- carry out action, depending on which widget called me ---*/
5772
5773 /*** Pick reference ***/
5774
5775 if( w == grapher->fmenu->fim_pickref_pb ){
5776 cbs.reason = graCR_pickref ;
5777 #if 0
5778 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5779 #else
5780 CALL_sendback( grapher , cbs ) ;
5781 #endif
5782 grapher->tschosen = 1 ; /* 31 Mar 2004 */
5783 }
5784
5785 /*** Pick ort ***/
5786
5787 else if( w == grapher->fmenu->fim_pickort_pb ){
5788 cbs.reason = graCR_pickort ;
5789 #if 0
5790 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5791 #else
5792 CALL_sendback( grapher , cbs ) ;
5793 #endif
5794 grapher->tschosen = 1 ; /* 31 Mar 2004 */
5795 }
5796
5797 /*** Clear FIM ***/
5798
5799 else if( w == grapher->fmenu->fim_editref_clear_pb ){
5800 cbs.reason = graCR_clearfim ;
5801 #if 0
5802 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5803 #else
5804 CALL_sendback( grapher , cbs ) ;
5805 #endif
5806 }
5807
5808 /*** Clear Ort ***/
5809
5810 else if( w == grapher->fmenu->fim_editort_clear_pb ){
5811 cbs.reason = graCR_clearort ;
5812 #if 0
5813 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5814 #else
5815 CALL_sendback( grapher , cbs ) ;
5816 #endif
5817 }
5818
5819 /*** set ref to central time series ***/
5820
5821 else if( w == grapher->fmenu->fim_editref_equals_pb ||
5822 w == grapher->fmenu->fim_editref_add_pb ){
5823 int ll ;
5824 MRI_IMAGE * tsim ;
5825
5826 ll = grapher->xpoint +
5827 grapher->ypoint * grapher->status->nx +
5828 grapher->zpoint * grapher->status->nx * grapher->status->ny ;
5829
5830 tsim = GRA_getseries( grapher , ll ) ;
5831
5832 if( tsim != NULL ){
5833 { GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
5834 MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
5835 cbs.reason = (w == grapher->fmenu->fim_editref_equals_pb)
5836 ? graCR_refequals : graCR_refadd ;
5837 cbs.userdata = (XtPointer) tsim ;
5838 #if 0
5839 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5840 #else
5841 CALL_sendback( grapher , cbs ) ;
5842 #endif
5843 mri_free( tsim ) ;
5844 }
5845 }
5846
5847 /*** read or write or smooth ***/
5848
5849 else if( w == grapher->fmenu->fim_editref_read_pb ){
5850 MCW_choose_string( grapher->option_rowcol ,
5851 "Ideal Input Filename:" , NULL ,
5852 GRA_refread_choose_CB , (XtPointer) grapher ) ;
5853 }
5854
5855 else if( w == grapher->fmenu->fim_editref_write_pb ){
5856 if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
5857 MCW_choose_string( grapher->option_rowcol ,
5858 "Ideal Output Filename:" , NULL ,
5859 GRA_refwrite_choose_CB , (XtPointer) grapher ) ;
5860 } else {
5861 BEEPIT ; WARNING_message("ref time series not defined!?") ;
5862 }
5863 }
5864
5865 else if( w == grapher->fmenu->fim_editref_store_pb ){
5866 if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
5867 MCW_choose_string( grapher->option_rowcol ,
5868 "Label to Store Ideal:" , NULL ,
5869 GRA_refstore_choose_CB , (XtPointer) grapher ) ;
5870 } else {
5871 BEEPIT ; WARNING_message("ref time series not defined!?") ;
5872 }
5873 }
5874
5875 else if( w == grapher->fmenu->fim_editref_smooth_pb ){
5876 cbs.reason = graCR_refsmooth ;
5877 if( grapher->ref_ts != NULL && IMARR_COUNT(grapher->ref_ts) > 0 ){
5878 { GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
5879 MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
5880 #if 0
5881 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5882 #else
5883 CALL_sendback( grapher , cbs ) ;
5884 #endif
5885 } else {
5886 BEEPIT ; WARNING_message("ref time series not defined!?") ;
5887 }
5888 }
5889
5890 /*** Set shifts ***/
5891
5892 else if( w == grapher->fmenu->fim_editref_setshift_pb ){
5893 GRA_setshift_startup( grapher ) ;
5894 }
5895
5896 /*** Execute FIM ***/
5897
5898 else if( w == grapher->fmenu->fim_execute_pb ){
5899 int val = MCW_val_bbox(grapher->fmenu->fim_opt_bbox) ;
5900 cbs.reason = graCR_dofim ;
5901 switch(val){
5902 default: cbs.key = FIM_ALPHA_MASK | FIM_CORR_MASK ; break ;
5903 case 2: cbs.key = FIM_PERC_MASK | FIM_CORR_MASK ; break ;
5904 case 4: cbs.key = FIM_PAVE_MASK | FIM_CORR_MASK ; break ;
5905 case 3: cbs.key = FIM_PTOP_MASK | FIM_CORR_MASK ; break ;
5906 }
5907 cbs.mat = 0 ; /* Feb 2000 */
5908 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
5909 #if 0
5910 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5911 #else
5912 CALL_sendback( grapher , cbs ) ;
5913 #endif
5914 }
5915
5916 else if( w == grapher->fmenu->fim_execfimp_pb ){
5917 cbs.reason = graCR_dofim ;
5918 cbs.key = MCW_val_bbox(grapher->fmenu->fimp_opt_bbox) ;
5919 cbs.mat = MCW_val_bbox(grapher->fmenu->fimp_user_bbox) ; /* Feb 2000 */
5920 GRA_timer_stop(grapher) ; /* 04 Dec 2003 */
5921 if( cbs.key || cbs.mat )
5922 #if 0
5923 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5924 #else
5925 CALL_sendback( grapher , cbs ) ;
5926 #endif
5927 else
5928 { BEEPIT ; WARNING_message("Can't execute FIM+ -- invalid settings!?") ; }
5929 }
5930
5931 /*** 04 Jan 2000: modify the FIM+ button settings ***/
5932
5933 else if( w == grapher->fmenu->fimp_setdefault_pb ){
5934 char *ff = my_getenv( "AFNI_FIM_MASK" ) ; int mm=0 ;
5935 if( ff != NULL ) mm = strtol(ff,NULL,10) ;
5936 if( mm <= 0 ) mm = FIM_DEFAULT_MASK ;
5937 MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , mm ) ;
5938 }
5939
5940 else if( w == grapher->fmenu->fimp_setall_pb ){
5941 int mm = (2 << FIM_NUM_OPTS) - 1 ;
5942 MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , mm ) ;
5943 }
5944
5945 else if( w == grapher->fmenu->fimp_unsetall_pb ){
5946 MCW_set_bbox( grapher->fmenu->fimp_opt_bbox , 0 ) ;
5947 }
5948
5949 /*** FIM plotting buttons ***/
5950
5951 else if( w == grapher->fmenu->fim_plot_firstref_pb ){
5952 if( grapher->ref_ts_plotall != 0 ){
5953 grapher->ref_ts_plotall = 0 ;
5954 redraw_graph( grapher , 0 ) ;
5955 }
5956 }
5957
5958 else if( w == grapher->fmenu->fim_plot_allrefs_pb ){
5959 if( grapher->ref_ts_plotall == 0 ){
5960 grapher->ref_ts_plotall = 1 ;
5961 redraw_graph( grapher , 0 ) ;
5962 }
5963 }
5964
5965 /*** Ignore stuff ***/
5966
5967 else if( w == grapher->fmenu->fim_ignore_down_pb && grapher->status->send_CB != NULL ){
5968 GRA_cbs cbs ;
5969
5970 cbs.reason = graCR_setignore ;
5971 cbs.key = grapher->init_ignore - 1 ;
5972 #if 0
5973 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5974 #else
5975 CALL_sendback( grapher , cbs ) ;
5976 #endif
5977 }
5978
5979 else if( w == grapher->fmenu->fim_ignore_up_pb && grapher->status->send_CB != NULL ){
5980 GRA_cbs cbs ;
5981
5982 cbs.reason = graCR_setignore ;
5983 cbs.key = grapher->init_ignore + 1 ;
5984 #if 0
5985 grapher->status->send_CB( grapher , grapher->getaux , &cbs ) ;
5986 #else
5987 CALL_sendback( grapher , cbs ) ;
5988 #endif
5989 }
5990
5991 else if( w == grapher->fmenu->fim_ignore_choose_pb && grapher->status->send_CB != NULL ){
5992 #ifdef USE_OPTMENUS
5993 GRA_ignore_choose_CB( grapher->fmenu->fim_ignore_choose_av , grapher ) ;
5994 #else
5995 MCW_choose_integer( grapher->option_rowcol , "Initial Ignore" ,
5996 0 , grapher->status->num_series-1 , grapher->init_ignore ,
5997 GRA_ignore_choose_CB , (XtPointer) grapher ) ;
5998 #endif
5999 }
6000
6001 /* 27 May 1999: set polort */
6002
6003 else if( w == grapher->fmenu->fim_polort_choose_pb && grapher->status->send_CB != NULL ){
6004 #ifdef USE_OPTMENUS
6005 GRA_polort_choose_CB( grapher->fmenu->fim_polort_choose_av , grapher ) ;
6006 #else
6007 MCW_choose_integer( grapher->option_rowcol , "Polort Order" ,
6008 0 , MAX_POLORT , grapher->polort ,
6009 GRA_polort_choose_CB , (XtPointer) grapher ) ;
6010 #endif
6011 }
6012
6013 /* 02 Jun 1999: set FIM bkg threshold */
6014
6015 else if( w == grapher->fmenu->fim_bkthr_choose_pb ){
6016 MCW_choose_integer( grapher->option_rowcol , "Bkg Thresh %" ,
6017 0 , 99 , (int)(100*FIM_THR) ,
6018 GRA_bkthr_choose_CB , (XtPointer) grapher ) ;
6019 }
6020
6021 /*** Unimplemented Button ***/
6022
6023 else {
6024 BEEPIT ; WARNING_message("You should never see this message!!") ;
6025 }
6026
6027 /*--- Done!!! ---*/
6028
6029 EXRETURN ;
6030 }
6031
6032 /*-----------------------------------------------------------------------*/
6033
6034 #define SETSHIFT_quit_label "Quit"
6035 #define SETSHIFT_apply_label "Apply"
6036 #define SETSHIFT_done_label "Set"
6037
6038 #define SETSHIFT_quit_help "Press to close\nthis control box"
6039 #define SETSHIFT_apply_help "Press to apply this choice\nand keep this control box"
6040 #define SETSHIFT_done_help "Press to apply this choice\nand close this control box"
6041
6042 #define NUM_SETSHIFT_ACT 3
6043
6044 static MCW_action_item SETSHIFT_act[NUM_SETSHIFT_ACT] = {
6045 { SETSHIFT_quit_label , GRA_setshift_action_CB, NULL, SETSHIFT_quit_help ,"Close window" , 0 },
6046 { SETSHIFT_apply_label , GRA_setshift_action_CB, NULL, SETSHIFT_apply_help,"Apply choice and keep window" , 0 },
6047 { SETSHIFT_done_label , GRA_setshift_action_CB, NULL, SETSHIFT_done_help ,"Apply choice and close window", 1 }
6048 } ;
6049
6050 #define SETSHIFT_QUIT 0
6051 #define SETSHIFT_APPLY 1
6052 #define SETSHIFT_DONE 2
6053
6054 /*-----------------------------------------------------------------------*/
6055
GRA_setshift_startup(MCW_grapher * grapher)6056 void GRA_setshift_startup( MCW_grapher * grapher )
6057 {
6058 int ib , xx,yy ;
6059 Widget wrc ;
6060
6061 ENTRY("GRA_setshift_startup") ;
6062
6063 if( ! GRA_REALZ(grapher) || grapher->dialog != NULL ) EXRETURN ;
6064
6065 MCW_widget_geom( grapher->fdw_graph , NULL,NULL,&xx,&yy ) ; /* geometry of shell */
6066
6067 grapher->dialog = XtVaCreatePopupShell(
6068 "menu" , xmDialogShellWidgetClass , grapher->fdw_graph ,
6069 XmNx , xx+15 ,
6070 XmNy , yy+15 ,
6071 XmNtitle , "Shifts" ,
6072 XmNdeleteResponse , XmDO_NOTHING ,
6073 XmNinitialResourcesPersistent , False ,
6074
6075 XmNvisual , grapher->dc->visual , /* 14 Sep 1998 */
6076 XmNcolormap , grapher->dc->colormap ,
6077 XmNdepth , grapher->dc->depth ,
6078 XmNscreen , grapher->dc->screen ,
6079 XmNbackground , 0 ,
6080 XmNborderColor , 0 ,
6081 XmNkeyboardFocusPolicy , XmEXPLICIT ,
6082
6083 NULL ) ;
6084
6085 if( MCW_isitmwm(grapher->fdw_graph) ){
6086 XtVaSetValues( grapher->dialog ,
6087 XmNmwmDecorations , MWM_DECOR_BORDER ,
6088 XmNmwmFunctions , MWM_FUNC_MOVE
6089 | MWM_FUNC_CLOSE ,
6090 NULL ) ;
6091 }
6092
6093 XmAddWMProtocolCallback( /* make "Close" window menu work */
6094 grapher->dialog ,
6095 XmInternAtom( grapher->dc->display , "WM_DELETE_WINDOW" , False ) ,
6096 GRA_setshift_action_CB , grapher ) ;
6097
6098 wrc = XtVaCreateWidget( /* RowColumn to hold all */
6099 "dialog" , xmRowColumnWidgetClass , grapher->dialog ,
6100 XmNpacking , XmPACK_TIGHT ,
6101 XmNorientation , XmVERTICAL ,
6102 XmNtraversalOn , True ,
6103 XmNinitialResourcesPersistent , False ,
6104 NULL ) ;
6105
6106 wtemp = XtVaCreateManagedWidget(
6107 "dialog" , xmLabelWidgetClass , wrc ,
6108 LABEL_ARG("-- Shift Controls --") ,
6109 XmNalignment , XmALIGNMENT_CENTER ,
6110 XmNinitialResourcesPersistent , False ,
6111 NULL ) ; LABELIZE(wtemp) ;
6112
6113 (void) XtVaCreateManagedWidget(
6114 "dialog" , xmSeparatorWidgetClass , wrc ,
6115 XmNseparatorType , XmSHADOW_ETCHED_IN ,
6116 XmNinitialResourcesPersistent , False ,
6117 NULL ) ;
6118
6119 grapher->setshift_inc_av = new_MCW_arrowval(
6120 wrc , "Increment " , MCW_AV_downup ,
6121 1 , 1000 , (int)(100.0*grapher->setshift_inc) ,
6122 MCW_AV_edittext , 2 ,
6123 NULL , NULL , NULL , NULL ) ;
6124
6125 grapher->setshift_left_av = new_MCW_arrowval(
6126 wrc , "Steps Left " , MCW_AV_downup ,
6127 0 , 29 , grapher->setshift_left ,
6128 MCW_AV_edittext , 0 ,
6129 NULL , NULL , NULL , NULL ) ;
6130
6131 grapher->setshift_right_av = new_MCW_arrowval(
6132 wrc , "Steps Right" , MCW_AV_downup ,
6133 0 , 29 , grapher->setshift_right ,
6134 MCW_AV_edittext , 0 ,
6135 NULL , NULL , NULL , NULL ) ;
6136
6137 grapher->setshift_inc_av->allow_wrap = 1 ; /* allow wrap at limits of values */
6138 grapher->setshift_left_av->allow_wrap = 1 ;
6139 grapher->setshift_right_av->allow_wrap = 1 ;
6140
6141 grapher->setshift_inc_av->fastdelay = 250 ; /* slow down arrow repeat action */
6142 grapher->setshift_left_av->fastdelay = 250 ;
6143 grapher->setshift_right_av->fastdelay = 250 ;
6144
6145 MCW_reghelp_children( grapher->setshift_inc_av->wrowcol ,
6146 "This controls the step size\n"
6147 "used to create the shifted\n"
6148 "time series -- for example,\n"
6149 "0.2 means a shift of 1/5\n"
6150 "of a time series stepsize."
6151 ) ;
6152 MCW_reghint_children( grapher->setshift_inc_av->wrowcol ,
6153 "Size of shift" ) ;
6154
6155 MCW_reghelp_children( grapher->setshift_left_av->wrowcol ,
6156 "This controls the number\n"
6157 "of left shifts used to\n"
6158 "create the desired multi-\n"
6159 "vector time series.\n\n"
6160 "N.B.: Steps Left plus\n"
6161 " Steps Right should\n"
6162 " be positive!"
6163 ) ;
6164 MCW_reghint_children( grapher->setshift_left_av->wrowcol ,
6165 "Number of steps left" ) ;
6166
6167 MCW_reghelp_children( grapher->setshift_right_av->wrowcol ,
6168 "This controls the number\n"
6169 "of right shifts used to\n"
6170 "create the desired multi-\n"
6171 "vector time series.\n\n"
6172 "N.B.: Steps Left plus\n"
6173 " Steps Right should\n"
6174 " be positive!"
6175 ) ;
6176 MCW_reghint_children( grapher->setshift_right_av->wrowcol ,
6177 "Number of steps right" ) ;
6178
6179 for( ib=0 ; ib < NUM_SETSHIFT_ACT ; ib++ )
6180 SETSHIFT_act[ib].data = (XtPointer) grapher ;
6181
6182 (void) MCW_action_area( wrc , SETSHIFT_act , NUM_SETSHIFT_ACT ) ;
6183
6184 XtManageChild( wrc ) ;
6185 XtPopup( grapher->dialog , XtGrabNone ) ; NI_sleep(1);
6186 RWC_visibilize_widget( grapher->dialog ) ; /* 09 Nov 1999 */
6187 NORMAL_cursorize( grapher->dialog ) ;
6188 EXRETURN ;
6189 }
6190
6191 /*-----------------------------------------------------------------------*/
6192
GRA_setshift_action_CB(Widget w,XtPointer client_data,XtPointer call_data)6193 void GRA_setshift_action_CB( Widget w , XtPointer client_data , XtPointer call_data )
6194 {
6195 MCW_grapher * grapher = (MCW_grapher *) client_data ;
6196 XmAnyCallbackStruct * cbs = (XmAnyCallbackStruct *) call_data ;
6197 char * wname ;
6198 int ib , close_window ;
6199
6200 ENTRY("GRA_setshift_action_CB") ;
6201
6202 if( !GRA_REALZ(grapher) || grapher->dialog==NULL ) EXRETURN ;
6203
6204 wname = XtName(w) ;
6205
6206 for( ib=0 ; ib < NUM_SETSHIFT_ACT ; ib++ ) /* button index, if any */
6207 if( strcmp(wname,SETSHIFT_act[ib].label) == 0 ) break ;
6208
6209 close_window = (ib == SETSHIFT_DONE ||
6210 ib == SETSHIFT_QUIT || ib == NUM_SETSHIFT_ACT) ;
6211
6212 if( close_window ){
6213 RWC_XtPopdown( grapher->dialog ) ;
6214 XSync( XtDisplay(w) , False ) ;
6215 XmUpdateDisplay( w ) ;
6216 }
6217
6218 switch( ib ){
6219
6220 case SETSHIFT_APPLY:
6221 case SETSHIFT_DONE:{
6222 grapher->setshift_inc = grapher->setshift_inc_av->fval ;
6223 grapher->setshift_left = grapher->setshift_left_av->ival ;
6224 grapher->setshift_right = grapher->setshift_right_av->ival ;
6225
6226 GRA_doshift( grapher ) ;
6227 }
6228 break ;
6229 }
6230
6231 if( close_window ){ /* close the window */
6232 XtDestroyWidget( grapher->dialog ) ; NI_sleep(1) ;
6233 grapher->dialog = NULL ;
6234 FREE_AV( grapher->setshift_right_av ) ;
6235 FREE_AV( grapher->setshift_left_av ) ;
6236 FREE_AV( grapher->setshift_inc_av ) ;
6237 }
6238
6239 EXRETURN ;
6240 }
6241
6242 /*-----------------------------------------------------------------------*/
6243
GRA_doshift(MCW_grapher * grapher)6244 void GRA_doshift( MCW_grapher * grapher )
6245 {
6246 MRI_IMAGE * tsim , * newim , * tim ;
6247 float * tsar , * nar , * tar ;
6248 int ii,ivec , nx , newny , nleft,nright ;
6249 float shinc ;
6250 GRA_cbs gbs ;
6251
6252 ENTRY("GRA_doshift") ;
6253
6254 if( !GRA_VALID(grapher) ) EXRETURN ;
6255
6256 if( grapher->status->send_CB == NULL ||
6257 grapher->setshift_inc <= 0.0 ||
6258 grapher->setshift_left + grapher->setshift_right <= 0 ||
6259 grapher->ref_ts == NULL ||
6260 IMARR_COUNT(grapher->ref_ts) == 0 ){
6261
6262 BEEPIT ; WARNING_message("Can't execute shift operation!?") ; EXRETURN ;
6263 }
6264
6265 tsim = IMARR_SUBIMAGE(grapher->ref_ts,0) ; /* current ref */
6266 tsar = MRI_FLOAT_PTR(tsim) ;
6267 nx = tsim->nx ;
6268
6269 shinc = grapher->setshift_inc ;
6270 nleft = grapher->setshift_left ;
6271 nright = grapher->setshift_right ;
6272 newny = 1 + nleft + nright ;
6273 newim = mri_new( nx , newny , MRI_float ) ;
6274 nar = MRI_FLOAT_PTR(newim) ;
6275
6276 for( ii=0 ; ii < nx ; ii++ )
6277 nar[ii] = (ii < NIGNORE(grapher) ) ? WAY_BIG : tsar[ii] ;
6278
6279 for( ivec=1 ; ivec <= nleft ; ivec++ ){
6280 tim = mri_shift_1D( newim , -ivec * shinc ) ;
6281 tar = MRI_FLOAT_PTR(tim) ;
6282 for( ii=0 ; ii < nx ; ii++ ) nar[ii+ivec*nx] = tar[ii] ;
6283 mri_free(tim) ;
6284 }
6285
6286 for( ivec=1 ; ivec <= nright ; ivec++ ){
6287 tim = mri_shift_1D( newim , ivec * shinc ) ;
6288 tar = MRI_FLOAT_PTR(tim) ;
6289 for( ii=0 ; ii < nx ; ii++ ) nar[ii+(ivec+nleft)*nx] = tar[ii] ;
6290 mri_free(tim) ;
6291 }
6292
6293 { GRA_cbs cbs; cbs.reason=graCR_winaver; CALL_sendback(grapher,cbs); }
6294 MCW_set_bbox( grapher->fmenu->fim_editref_winaver_bbox , 0 ) ;
6295 gbs.reason = graCR_refequals ;
6296 gbs.userdata = (XtPointer) newim ;
6297 #if 0
6298 grapher->status->send_CB( grapher , grapher->getaux , &gbs ) ;
6299 #else
6300 CALL_sendback( grapher , gbs ) ;
6301 #endif
6302 mri_free( newim ) ;
6303 EXRETURN ;
6304 }
6305
6306 /*---------------------------------------------------------------------
6307 Returns a bunch of widgets in a structure.
6308 The parent widget is intended to be a menu bar.
6309 -----------------------------------------------------------------------*/
6310
AFNI_new_fim_menu(Widget parent,XtCallbackProc cbfunc,int graphable)6311 FIM_menu * AFNI_new_fim_menu( Widget parent, XtCallbackProc cbfunc, int graphable )
6312 {
6313 FIM_menu *fmenu ;
6314 Widget qbut_menu = NULL ;
6315
6316 ENTRY("AFNI_new_fim_menu") ;
6317
6318 fmenu = myXtNew(FIM_menu) ;
6319 fmenu->cbfunc = cbfunc ;
6320
6321 /*------------------------*/
6322 /*--- FIM Menu Buttons ---*/
6323 /*------------------------*/
6324
6325 fmenu->fim_menu = XmCreatePulldownMenu( parent , "menu" , NULL,0 ) ;
6326
6327 VISIBILIZE_WHEN_MAPPED(fmenu->fim_menu) ; /* 27 Sep 2000 */
6328 #if 0
6329 if( !AFNI_yesenv("AFNI_DISABLE_TEAROFF") ) TEAROFFIZE(fmenu->fim_menu) ;
6330 #endif
6331
6332 fmenu->fim_cbut =
6333 XtVaCreateManagedWidget(
6334 "dialog" , xmCascadeButtonWidgetClass , parent ,
6335 LABEL_ARG("FIM") ,
6336 XmNsubMenuId , fmenu->fim_menu ,
6337 XmNmarginWidth , 0 ,
6338 XmNmarginHeight , 0 ,
6339 XmNmarginBottom , 0 ,
6340 XmNmarginTop , 0 ,
6341 XmNmarginRight , 0 ,
6342 XmNmarginLeft , 0 ,
6343 XmNtraversalOn , True ,
6344 XmNinitialResourcesPersistent , False ,
6345 NULL ) ;
6346
6347 if( graphable ){
6348 MCW_register_hint( fmenu->fim_cbut , "Functional Imaging menu" ) ;
6349 MCW_register_help( fmenu->fim_cbut ,
6350 "******* Functional Imaging Controls: *******\n"
6351 "\n"
6352 "Ideal Vector Operations:\n"
6353 " Pick Ideal --> Choose from a list\n"
6354 " Pick Ort --> Choose from a list\n"
6355 " Edit: = Center --> Use voxel timeseries\n"
6356 " += Center --> Average with voxel\n"
6357 " Smooth --> A 3 point filter\n"
6358 " Shift --> Time-shifted copies\n"
6359 " Clear --> Turn ideal off\n"
6360 " WinAver --> Average of sub-graphs\n"
6361 " Read --> Input from external file\n"
6362 " Write --> Output to external file\n"
6363 " Store --> Save in internal list\n"
6364 " Ignore: Set how many points to ignore\n"
6365 " at beginning of time series\n"
6366 " [ Applies both to graphing ]\n"
6367 " [ and to FIM computations. ]\n"
6368 "\n"
6369 "FIM Plots:\n"
6370 " Can choose to graph only first vector in\n"
6371 " ideal family, or all of them superimposed.\n"
6372 "\n"
6373 "Refresh Freq --> Choose number of time steps\n"
6374 " between redisplay of the functional overlay\n"
6375 " during FIM computations (0 == no redisplay).\n"
6376 "Compute FIM --> Use the recursive method to\n"
6377 " compute the correlation of each voxel time\n"
6378 " series with each ideal vector; uses the best\n"
6379 " correlation as the 'correct' waveform for\n"
6380 " each voxel, individually. Time points that\n"
6381 " have an ideal vector value >= 33333 will be\n"
6382 " ignored in the computations, as will those\n"
6383 " at the beginning specified in the Opt menu\n"
6384 " 'Ignore' function."
6385 ) ;
6386 } else {
6387 MCW_register_hint( fmenu->fim_cbut , "Functional Imaging menu" ) ;
6388 MCW_register_help( fmenu->fim_cbut ,
6389 "******* Functional Imaging Controls: *******\n"
6390 "\n"
6391 "Pick Dataset --> Choose time-dependent dataset\n"
6392 " from a list. If there is only one possible\n"
6393 " choice, it will be selected for you without\n"
6394 " displaying the list.\n"
6395 "\n"
6396 "Pick Ideal --> Choose time series from a list.\n"
6397 "Pick Ort --> Choose time series from a list.\n"
6398 "\n"
6399 "Ignore --> Set how many points to ignore at the\n"
6400 " beginning of time series.\n"
6401 " [ Applies both to graphing and FIM-ing. ]\n"
6402 "\n"
6403 "Refresh Freq --> Choose number of time steps\n"
6404 " between redisplay of the functional overlay\n"
6405 " during FIM computations (0 == no redisplay).\n"
6406 "\n"
6407 "Compute FIM --> Use the recursive method to\n"
6408 " compute the correlation of each voxel time\n"
6409 " series with each ideal vector; uses the best\n"
6410 " correlation as the 'correct' waveform for\n"
6411 " each voxel, individually. Time points that\n"
6412 " have an ideal vector value >= 33333 will be\n"
6413 " ignored in the computations, as will those\n"
6414 " at the beginning specified in the Opt menu\n"
6415 " 'Ignore' function."
6416 ) ;
6417 }
6418
6419 /* macros to put double and single separator lines in a menu */
6420
6421 #undef MENU_DLINE
6422 #define MENU_DLINE(wmenu) \
6423 (void) XtVaCreateManagedWidget( \
6424 "dialog" , xmSeparatorWidgetClass , fmenu -> wmenu , \
6425 XmNseparatorType , XmDOUBLE_LINE , NULL )
6426
6427 #undef MENU_SLINE
6428 #define MENU_SLINE(wmenu) \
6429 (void) XtVaCreateManagedWidget( \
6430 "dialog" , xmSeparatorWidgetClass , fmenu -> wmenu , \
6431 XmNseparatorType , XmSINGLE_LINE , NULL )
6432
6433 /* macro to create a new FIM menu button */
6434
6435 #define FIM_MENU_BUT(wname,label,hhh) \
6436 fmenu -> wname = \
6437 XtVaCreateManagedWidget( \
6438 "dialog" , xmPushButtonWidgetClass , fmenu->fim_menu , \
6439 LABEL_ARG( label ) , \
6440 XmNmarginHeight , 0 , \
6441 XmNtraversalOn , True , \
6442 XmNinitialResourcesPersistent , False , \
6443 NULL ) ; \
6444 XtAddCallback( fmenu -> wname , XmNactivateCallback , \
6445 cbfunc , (XtPointer) fmenu ) ; \
6446 MCW_register_hint( fmenu -> wname , hhh ) ;
6447
6448 /** macro to create a new fim pullright menu **/
6449 /** 07 Jan 1999: added the mapCallback to fix position **/
6450
6451 #define FIM_MENU_PULLRIGHT(wmenu,wcbut,label,hhh) \
6452 fmenu -> wmenu = \
6453 XmCreatePulldownMenu( fmenu->fim_menu , "menu" , NULL , 0 ) ; \
6454 fmenu -> wcbut = \
6455 XtVaCreateManagedWidget( \
6456 "dialog" , xmCascadeButtonWidgetClass , fmenu->fim_menu , \
6457 LABEL_ARG( label ) , \
6458 XmNsubMenuId , fmenu -> wmenu , \
6459 XmNtraversalOn , True , \
6460 XmNinitialResourcesPersistent , False , \
6461 NULL ) ; \
6462 MCW_register_hint( fmenu -> wcbut , hhh ) ; \
6463 XtAddCallback( fmenu -> wmenu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ;
6464
6465 /** macro to create a new button on a pullright menu **/
6466
6467 #define FIM_MENU_PULL_BUT(wmenu,wname,label,hhh) \
6468 fmenu -> wname = \
6469 XtVaCreateManagedWidget( \
6470 "dialog" , xmPushButtonWidgetClass , fmenu -> wmenu , \
6471 LABEL_ARG( label ) , \
6472 XmNmarginHeight , 0 , \
6473 XmNtraversalOn , True , \
6474 XmNinitialResourcesPersistent , False , \
6475 NULL ) ; \
6476 XtAddCallback( fmenu -> wname , XmNactivateCallback , \
6477 cbfunc , (XtPointer) fmenu ) ; \
6478 MCW_register_hint( fmenu -> wname , hhh ) ;
6479
6480 #define EMPTY_BUT(wname) fmenu -> wname = NULL
6481
6482 /** 15 Dec 1997: a pullright menu with a single button **/
6483
6484 #define FIM_MENU_QBUT(wname,label,qlab,hhh) \
6485 do { Widget ccc ; \
6486 qbut_menu = XmCreatePulldownMenu(fmenu->fim_menu,"menu",NULL,0); \
6487 ccc = XtVaCreateManagedWidget( "dialog" , \
6488 xmCascadeButtonWidgetClass , fmenu->fim_menu , \
6489 LABEL_ARG( label ) , \
6490 XmNsubMenuId , qbut_menu , \
6491 XmNtraversalOn , True , \
6492 XmNinitialResourcesPersistent , False , NULL ) ; \
6493 fmenu -> wname = XtVaCreateManagedWidget( "dialog" , \
6494 xmPushButtonWidgetClass , qbut_menu , \
6495 LABEL_ARG( qlab ) , \
6496 XmNmarginHeight , 0 , \
6497 XmNtraversalOn , True , \
6498 XmNinitialResourcesPersistent , False , NULL ) ; \
6499 MCW_register_hint( fmenu -> wname , hhh ) ; \
6500 XtAddCallback( fmenu -> wname , XmNactivateCallback , \
6501 cbfunc , (XtPointer) fmenu ) ; \
6502 XtAddCallback( qbut_menu, XmNmapCallback, GRA_mapmenu_CB, NULL ) ; \
6503 } while(0)
6504
6505 /*** top of menu = a label to click on that does nothing at all ***/
6506 #ifdef USING_LESSTIF
6507
6508 /* Using xmLabelWidgetClass causes X11 to hang until
6509 afni is terminated. For details, see preceding comment.
6510 for another --- Cancel --- button.
6511
6512 LessTif patrol Jan. 07 09 */
6513 (void) XtVaCreateManagedWidget(
6514 "dialog" , xmPushButtonWidgetClass , fmenu->fim_menu ,
6515 LABEL_ARG("--- Cancel ---") ,
6516 XmNrecomputeSize , False ,
6517 XmNinitialResourcesPersistent , False ,
6518 NULL ) ;
6519 #else
6520 wtemp = XtVaCreateManagedWidget(
6521 "dialog" , xmLabelWidgetClass , fmenu->fim_menu ,
6522 LABEL_ARG("--- Cancel ---") ,
6523 XmNrecomputeSize , False ,
6524 XmNinitialResourcesPersistent , False ,
6525 NULL ) ; LABELIZE(wtemp) ;
6526 #endif
6527
6528 MENU_SLINE(fim_menu) ;
6529
6530 if( graphable ){
6531 EMPTY_BUT(fim_pickdset_pb) ;
6532 } else {
6533 FIM_MENU_BUT( fim_pickdset_pb , "Pick Dataset" , "Choose Dataset to Graph" ) ;
6534 }
6535
6536 FIM_MENU_BUT( fim_pickref_pb , "Pick Ideal" , "Pick Ideal Timeseries to Graph" ) ;
6537 FIM_MENU_BUT( fim_pickort_pb , "Pick Ort" , "Pick Ort Timeseries to Graph" ) ;
6538
6539 if( graphable ){
6540 char *bbox_label[1] = { "Ideal=WinAver" } ;
6541 MENU_SLINE(fim_menu) ;
6542 FIM_MENU_PULLRIGHT(fim_editref_menu,fim_editref_cbut ,"Edit Ideal" , "Modify Ideal Timeseries" ) ;
6543 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_equals_pb ,"Ideal = Center", "Set to Center Sub-graph" ) ;
6544 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_add_pb ,"Ideal+= Center", "Add in Center Sub-graph" ) ;
6545 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_smooth_pb ,"Smooth Ideal" , "Lowpass Filter Ideal" ) ;
6546 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_setshift_pb,"Shift Ideal" , "Time Shift Ideal" ) ;
6547 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_clear_pb ,"Clear Ideal" , "Turn Ideal Off" ) ;
6548 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editort_clear_pb ,"Clear Ort" , "Turn Ort Off" ) ;
6549
6550 fmenu->fim_editref_winaver_bbox /* 27 Jan 2004 */
6551 = new_MCW_bbox( fmenu->fim_editref_menu ,
6552 1 , bbox_label , MCW_BB_check , MCW_BB_noframe ,
6553 GRA_winaver_CB , (XtPointer)fmenu ) ;
6554 MCW_reghint_children( fmenu->fim_editref_winaver_bbox->wrowcol ,
6555 "Ideal = Average of all Graphs in Window" ) ;
6556 #ifdef USE_OPTMENUS
6557 fmenu->fim_polort_choose_av =
6558 new_MCW_optmenu( fmenu->fim_editref_menu , "Polort " , 0,MAX_POLORT,1,0 ,
6559 GRA_fmenu_av_CB , (XtPointer) fmenu , NULL , NULL ) ;
6560 fmenu->fim_polort_choose_pb = fmenu->fim_polort_choose_av->wrowcol ;
6561 MCW_reghint_children( fmenu->fim_polort_choose_av->wrowcol , "Order of Polynomial Baseline for FIM" ) ;
6562 #else
6563 FIM_MENU_PULL_BUT( fim_editref_menu,fim_polort_choose_pb ,"Polort?", "Order of Polynomial Baseline for FIM") ;
6564 #endif
6565 FIM_MENU_PULL_BUT( fim_editref_menu,fim_bkthr_choose_pb ,"Bkg Thresh" , "Choose Background Threshold for FIM") ;
6566 MENU_SLINE (fim_editref_menu) ;
6567 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_read_pb ,"Read Ideal" , "Read from .1D file" ) ;
6568 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_write_pb ,"Write Ideal", "Write to .1D file" ) ;
6569 FIM_MENU_PULL_BUT (fim_editref_menu,fim_editref_store_pb ,"Store Ideal", "Save in internal list of timeseries" ) ;
6570 } else {
6571 EMPTY_BUT(fim_editref_cbut) ;
6572 EMPTY_BUT(fim_editref_equals_pb) ;
6573 EMPTY_BUT(fim_editref_add_pb) ;
6574 EMPTY_BUT(fim_editref_smooth_pb) ;
6575 EMPTY_BUT(fim_editref_setshift_pb) ;
6576 EMPTY_BUT(fim_editref_clear_pb) ;
6577 EMPTY_BUT(fim_editref_read_pb) ;
6578 EMPTY_BUT(fim_editref_write_pb) ;
6579 EMPTY_BUT(fim_editref_store_pb) ;
6580 EMPTY_BUT(fim_editort_clear_pb) ;
6581 EMPTY_BUT(fim_polort_choose_pb) ;
6582 fmenu->fim_editref_winaver_bbox = NULL ; /* 27 Jan 2004 */
6583 }
6584
6585 FIM_MENU_PULLRIGHT(fim_ignore_menu,fim_ignore_cbut ,"Ignore", "Number of initial timepoints to ignore" ) ;
6586 FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_down_pb ,"Down" , "Ignore fewer points" ) ;
6587 FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_up_pb ,"Up" , "Ignore more points" ) ;
6588 #ifdef USE_OPTMENUS
6589 fmenu->fim_ignore_choose_av =
6590 new_MCW_optmenu( fmenu->fim_ignore_menu , "# " , 0,2,0,0 ,
6591 GRA_fmenu_av_CB , (XtPointer) fmenu , NULL , NULL ) ;
6592 fmenu->fim_ignore_choose_pb = fmenu->fim_ignore_choose_av->wrowcol ;
6593 MCW_reghint_children( fmenu->fim_ignore_choose_av->wrowcol , "Pick number of ignored points" ) ;
6594 #else
6595 FIM_MENU_PULL_BUT( fim_ignore_menu,fim_ignore_choose_pb ,"Choose" , "Pick number of ignored points") ;
6596 #endif
6597
6598 if( graphable ){
6599 FIM_MENU_PULLRIGHT(fim_plot_menu,fim_plot_cbut ,"FIM Plots" , "Number of Ideals to plot" ) ;
6600 FIM_MENU_PULL_BUT( fim_plot_menu,fim_plot_firstref_pb ,"First Ideal" , "Only plot 1 Ideal" ) ;
6601 FIM_MENU_PULL_BUT( fim_plot_menu,fim_plot_allrefs_pb ,"All Ideals" , "Plot all Ideals" ) ;
6602 } else {
6603 EMPTY_BUT(fim_plot_cbut) ;
6604 EMPTY_BUT(fim_plot_firstref_pb) ;
6605 EMPTY_BUT(fim_plot_allrefs_pb) ;
6606 }
6607
6608 MENU_DLINE(fim_menu) ;
6609 FIM_MENU_QBUT( fim_execute_pb , "Compute FIM" , "-> fico" , "Correlation Analysis" ) ;
6610 MCW_set_widget_bg( fmenu->fim_execute_pb ,
6611 MCW_hotcolor(fmenu->fim_execute_pb) , 0 ) ;
6612
6613 { static char * blab[] = {"Fit Coef", "% Change", "% From Ave", "% From Top"};
6614 (void) XtVaCreateManagedWidget(
6615 "dialog" , xmSeparatorWidgetClass , qbut_menu ,
6616 XmNseparatorType , XmSINGLE_LINE , NULL ) ;
6617
6618 fmenu->fim_opt_bbox = new_MCW_bbox( qbut_menu , 4 , blab ,
6619 MCW_BB_radio_one , MCW_BB_noframe ,
6620 NULL , NULL ) ;
6621 MCW_reghint_children( fmenu->fim_opt_bbox->wrowcol , "What to Compute" ) ;
6622 }
6623
6624 MENU_DLINE(fim_menu) ;
6625 FIM_MENU_QBUT( fim_execfimp_pb , "Compute FIM+" , "-> fbuc" , "Extended Correlation Analysis" ) ;
6626 MCW_set_widget_bg( fmenu->fim_execfimp_pb ,
6627 MCW_hotcolor(fmenu->fim_execfimp_pb) , 0 ) ;
6628
6629 (void) XtVaCreateManagedWidget(
6630 "dialog" , xmSeparatorWidgetClass , qbut_menu ,
6631 XmNseparatorType , XmSINGLE_LINE , NULL ) ;
6632
6633 fmenu->fimp_opt_bbox = new_MCW_bbox( qbut_menu, FIM_NUM_OPTS, fim_opt_labels,
6634 MCW_BB_check , MCW_BB_noframe ,
6635 NULL , NULL ) ;
6636 MCW_reghint_children( fmenu->fimp_opt_bbox->wrowcol , "What to Compute" ) ;
6637
6638 { char * ff = my_getenv( "AFNI_FIM_MASK" ) ; int mm=0 ;
6639 if( ff != NULL ) mm = strtol(ff,NULL,10) ;
6640 if( mm <= 0 ) mm = FIM_DEFAULT_MASK ;
6641 MCW_set_bbox( fmenu->fimp_opt_bbox , mm ) ;
6642 }
6643
6644 /* 04 Jan 2000: add some more buttons */
6645
6646 (void) XtVaCreateManagedWidget(
6647 "dialog" , xmSeparatorWidgetClass , qbut_menu ,
6648 XmNseparatorType , XmSINGLE_LINE , NULL ) ;
6649
6650 fmenu->fimp_setdefault_pb =
6651 XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
6652 LABEL_ARG( "Set Defaults" ) ,
6653 XmNmarginHeight , 0 ,
6654 XmNtraversalOn , True ,
6655 XmNinitialResourcesPersistent , False ,
6656 NULL ) ;
6657 XtAddCallback( fmenu->fimp_setdefault_pb ,
6658 XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
6659 MCW_register_hint( fmenu->fimp_setdefault_pb , "Default computing options" ) ;
6660
6661 fmenu->fimp_setall_pb =
6662 XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
6663 LABEL_ARG( "Set All" ) ,
6664 XmNmarginHeight , 0 ,
6665 XmNtraversalOn , True ,
6666 XmNinitialResourcesPersistent , False ,
6667 NULL ) ;
6668 XtAddCallback( fmenu->fimp_setall_pb ,
6669 XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
6670 MCW_register_hint( fmenu->fimp_setall_pb , "Set all computing options on" ) ;
6671
6672 fmenu->fimp_unsetall_pb =
6673 XtVaCreateManagedWidget( "dialog" , xmPushButtonWidgetClass , qbut_menu ,
6674 LABEL_ARG( "Unset All" ) ,
6675 XmNmarginHeight , 0 ,
6676 XmNtraversalOn , True ,
6677 XmNinitialResourcesPersistent , False ,
6678 NULL ) ;
6679 XtAddCallback( fmenu->fimp_unsetall_pb ,
6680 XmNactivateCallback , cbfunc , (XtPointer) fmenu ) ;
6681 MCW_register_hint( fmenu->fimp_unsetall_pb , "Set all computing options off" ) ;
6682
6683 /* 01 Feb 2000: add user-contributed options (if any) */
6684
6685 fmenu->fimp_user_bbox = NULL ; /* default = no menu */
6686
6687 if( GLOBAL_library.registered_fim.num > 0 ){
6688
6689 (void) XtVaCreateManagedWidget(
6690 "dialog" , xmSeparatorWidgetClass , qbut_menu ,
6691 XmNseparatorType , XmDOUBLE_LINE , NULL ) ;
6692
6693 wtemp = XtVaCreateManagedWidget(
6694 "dialog" , xmLabelWidgetClass , qbut_menu ,
6695 LABEL_ARG("--Extra Funcs--") ,
6696 XmNrecomputeSize , False ,
6697 XmNinitialResourcesPersistent , False ,
6698 NULL ) ; LABELIZE(wtemp) ;
6699
6700 fmenu->fimp_user_bbox = new_MCW_bbox( qbut_menu,
6701 GLOBAL_library.registered_fim.num ,
6702 GLOBAL_library.registered_fim.labels ,
6703 MCW_BB_check , MCW_BB_noframe ,
6704 NULL , NULL ) ;
6705 MCW_reghint_children( fmenu->fimp_user_bbox->wrowcol , "Other correlation functions" ) ;
6706 }
6707
6708 RETURN(fmenu) ;
6709 }
6710
6711 /*-----------------------------------------------------------------------------
6712 Routines to handle point transformations of a timeseries (22 Oct 1996)
6713 -------------------------------------------------------------------------------*/
6714
GRA_transform_label(MCW_arrowval * av,XtPointer cd)6715 char * GRA_transform_label( MCW_arrowval * av , XtPointer cd )
6716 {
6717 MCW_function_list * xforms = (MCW_function_list *) cd ;
6718
6719 if( av == NULL || xforms == NULL ||
6720 av->ival <= 0 || av->ival > xforms->num ) return "-none-" ;
6721
6722 return xforms->labels[av->ival - 1] ; /* label for each function */
6723 }
6724
6725 /*-----------------------------------------------------------------------------*/
6726 /*! Will be called from both the 1D and 0D menus. */
6727
GRA_transform_CB(MCW_arrowval * av,XtPointer cd)6728 void GRA_transform_CB( MCW_arrowval *av , XtPointer cd )
6729 {
6730 MCW_grapher *grapher = (MCW_grapher *)cd ;
6731 int set_dplot = 0 ; /* 04 Oct 2007 */
6732
6733 ENTRY("GRA_transform_CB") ;
6734
6735 if( ! GRA_VALID(grapher) ) EXRETURN ;
6736
6737 /** set the 0D transform function pointer **/
6738
6739 if( av == grapher->transform0D_av && av != NULL ){
6740 if( grapher->status->transforms0D == NULL || av->ival <= 0 ||
6741 av->ival > grapher->status->transforms0D->num ){
6742
6743 grapher->transform0D_func = NULL ; /* no transform */
6744 grapher->transform0D_index = 0 ;
6745 } else {
6746 grapher->transform0D_func = grapher->status->transforms0D->funcs[av->ival-1];
6747 grapher->transform0D_index = av->ival ;
6748 grapher->transform0D_flags = grapher->status->transforms0D->flags[av->ival-1];
6749
6750 if( grapher->transform0D_flags & SET_DPLOT_OVERLAY ) set_dplot = 1 ;
6751
6752 /* 21 Jul 2003: call the init function, if present */
6753
6754 if( grapher->status->transforms0D->func_init[av->ival-1] != NULL )
6755 grapher->status->transforms0D->func_init[av->ival-1]() ;
6756 }
6757 }
6758
6759 /** set the 1D transform function pointer **/
6760
6761 if( av == grapher->transform1D_av && av != NULL ){
6762 if( grapher->status->transforms1D == NULL || av->ival <= 0 ||
6763 av->ival > grapher->status->transforms1D->num ){
6764
6765 grapher->transform1D_func = NULL ; /* no transform */
6766 grapher->transform1D_index = 0 ;
6767 } else {
6768 grapher->transform1D_func = grapher->status->transforms1D->funcs[av->ival-1];
6769 grapher->transform1D_index = av->ival ;
6770 grapher->transform1D_flags = grapher->status->transforms1D->flags[av->ival-1];
6771
6772 if( grapher->transform1D_flags & SET_DPLOT_OVERLAY ) set_dplot = 1 ;
6773
6774 /* 21 Jul 2003: call the init function, if present */
6775
6776 if( grapher->status->transforms1D->func_init[av->ival-1] != NULL )
6777 grapher->status->transforms1D->func_init[av->ival-1]() ;
6778 }
6779 }
6780
6781 if( set_dplot == 1 && !DATA_BOXED(grapher) ) /* 04 Oct 2007 */
6782 MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OVERLAY ) ;
6783
6784 redraw_graph( grapher , 0 ) ;
6785 EXRETURN ;
6786 }
6787
6788 /*----------------------------------------------------------------------------
6789 22 Sep 2000: for textgraph toggle
6790 ------------------------------------------------------------------------------*/
6791
GRA_textgraph_CB(Widget w,XtPointer client_data,XtPointer call_data)6792 void GRA_textgraph_CB( Widget w , XtPointer client_data , XtPointer call_data )
6793 {
6794 MCW_grapher *grapher = (MCW_grapher *) client_data ;
6795 int bbb ;
6796
6797 ENTRY("GRA_textgraph_CB") ;
6798
6799 if( ! GRA_VALID(grapher) ) EXRETURN ;
6800
6801 bbb = MCW_val_bbox( grapher->opt_textgraph_bbox ) ;
6802 if( bbb != grapher->textgraph ){
6803 grapher->textgraph = bbb ;
6804 redraw_graph( grapher , 0 ) ;
6805 }
6806 EXRETURN ;
6807 }
6808
6809 /*----------------------------------------------------------------------------
6810 Mar 2013: thresh fade toggle
6811 ------------------------------------------------------------------------------*/
6812
GRA_tfade_CB(Widget w,XtPointer client_data,XtPointer call_data)6813 void GRA_tfade_CB( Widget w , XtPointer client_data , XtPointer call_data )
6814 {
6815 MCW_grapher *grapher = (MCW_grapher *)client_data ;
6816 int bbb ;
6817
6818 ENTRY("GRA_tfade_CB") ;
6819
6820 if( ! GRA_VALID(grapher) ) EXRETURN ;
6821
6822 bbb = MCW_val_bbox( grapher->opt_tfade_bbox ) ;
6823 if( bbb != grapher->thresh_fade ){
6824 grapher->thresh_fade = bbb ;
6825 redraw_graph( grapher , 0 ) ;
6826 }
6827 EXRETURN ;
6828 }
6829
6830 /*----------------------------------------------------------------------------
6831 22 Sep 2000: for new baseline toggle
6832 ------------------------------------------------------------------------------*/
6833
GRA_baseline_CB(Widget w,XtPointer client_data,XtPointer call_data)6834 void GRA_baseline_CB( Widget w , XtPointer client_data , XtPointer call_data )
6835 {
6836 MCW_grapher *grapher = (MCW_grapher *) client_data ;
6837 int bbb ;
6838
6839 ENTRY("GRA_baseline_CB") ;
6840
6841 if( ! GRA_VALID(grapher) ) EXRETURN ;
6842
6843 bbb = MCW_val_bbox( grapher->opt_baseline_bbox ) ;
6844 if( bbb != grapher->common_base ){
6845 grapher->common_base = bbb ;
6846 redraw_graph( grapher , 0 ) ;
6847 }
6848 EXRETURN ;
6849 }
6850
6851 /*----------------------------------------------------------------------------
6852 Set the global baseline value
6853 ------------------------------------------------------------------------------*/
6854
GRA_finalize_global_baseline_CB(Widget w,XtPointer cd,MCW_choose_cbs * cbs)6855 void GRA_finalize_global_baseline_CB( Widget w,
6856 XtPointer cd , MCW_choose_cbs *cbs )
6857 {
6858 MCW_grapher *grapher = (MCW_grapher *) cd ;
6859 XmString xstr ;
6860 char str[32] ;
6861
6862 ENTRY("GRA_finalize_global_baseline_CB") ;
6863
6864 if( !GRA_VALID(grapher) ) EXRETURN ;
6865
6866 grapher->global_base = cbs->fval ;
6867 if( grapher->common_base == BASELINE_GLOBAL ) redraw_graph(grapher,0) ;
6868
6869 strcpy(str,"Global:") ;
6870 AV_fval_to_char(grapher->global_base,str+7) ;
6871 xstr = XmStringCreateLtoR( str,XmFONTLIST_DEFAULT_TAG ) ;
6872 XtVaSetValues( grapher->opt_baseline_global_label ,
6873 XmNlabelString,xstr ,
6874 NULL ) ;
6875 XmStringFree(xstr) ;
6876 EXRETURN ;
6877 }
6878
6879 /*----------------------------------------------------------------------------*/
6880 /*** user presses Ideal=WinAver toggle [27 Jan 2004] ***/
6881
GRA_winaver_CB(Widget w,XtPointer client_data,XtPointer call_data)6882 void GRA_winaver_CB( Widget w , XtPointer client_data , XtPointer call_data )
6883 {
6884 FIM_menu *fm = (FIM_menu *)client_data ;
6885 MCW_grapher *grapher = (MCW_grapher *)fm->parent ;
6886
6887 if( MCW_val_bbox(grapher->fmenu->fim_editref_winaver_bbox) ){
6888 GRA_cbs cbs ;
6889 cbs.reason = graCR_winaver ;
6890 CALL_sendback( grapher , cbs ) ;
6891 redraw_graph( grapher , 0 ) ;
6892 }
6893 }
6894 /*----------------------------------------------------------------------------*/
6895
GRA_winavertimer_CB(XtPointer cd,XtIntervalId * id)6896 void GRA_winavertimer_CB( XtPointer cd , XtIntervalId *id )
6897 {
6898 MCW_grapher *grapher = (MCW_grapher *)cd ;
6899 GRA_cbs cbs ;
6900
6901 if( !GRA_REALZ(grapher) || grapher->ave_tsim == NULL ) return ;
6902
6903 cbs.reason = graCR_refequals ;
6904 cbs.userdata = (XtPointer)grapher->ave_tsim ;
6905 grapher->dont_redraw = 1 ;
6906 CALL_sendback( grapher , cbs ) ;
6907 grapher->dont_redraw = 0 ;
6908 return ;
6909 }
6910
6911 /*----------------------------------------------------------------------------*/
6912 /*** set ref to average time series [27 Jan 2004] ***/
6913
GRA_winaver_setref(MCW_grapher * grapher)6914 void GRA_winaver_setref( MCW_grapher *grapher )
6915 {
6916 GRA_cbs cbs ;
6917
6918 ENTRY("GRA_winaver_setref") ;
6919
6920 if( !GRA_REALZ(grapher) || grapher->ave_tsim == NULL ){
6921 STATUS("nothing to do") ; EXRETURN ;
6922 }
6923
6924 (void)XtAppAddTimeOut( XtWidgetToApplicationContext(grapher->opt_quit_pb) ,
6925 1 , GRA_winavertimer_CB , grapher ) ;
6926 EXRETURN ;
6927 }
6928
6929 /*----------------------------------------------------------------------------
6930 08 Nov 1996: for "double plots" -- just redraw everything
6931 ------------------------------------------------------------------------------*/
6932
GRA_dplot_change_CB(Widget w,XtPointer client_data,XtPointer call_data)6933 void GRA_dplot_change_CB( Widget w , XtPointer client_data , XtPointer call_data )
6934 {
6935 MCW_grapher *grapher = (MCW_grapher *) client_data ;
6936
6937 ENTRY("GRA_dplot_change_CB") ;
6938
6939 if( ! GRA_REALZ(grapher) ) EXRETURN ;
6940 redraw_graph( grapher , 0 ) ;
6941 EXRETURN ;
6942 }
6943
6944 #ifdef USE_OPTMENUS
6945 /*---------------------------------------------------------------------------
6946 Fix the optmenus for the grapher; used when the dataset changes
6947 and so the upper limits on the selectors must change too
6948 -----------------------------------------------------------------------------*/
6949
GRA_fix_optmenus(MCW_grapher * grapher)6950 void GRA_fix_optmenus( MCW_grapher *grapher )
6951 {
6952 int igtop ;
6953
6954 ENTRY("GRA_fix_optmenus") ;
6955
6956 if( ! GRA_REALZ(grapher) ) EXRETURN ;
6957
6958 /** matrix selection **/
6959
6960 if( grapher->opt_mat_choose_av->imax != grapher->mat_max )
6961 refit_MCW_optmenu( grapher->opt_mat_choose_av ,
6962 1 , grapher->mat_max , grapher->mat , 0 ,
6963 NULL , NULL ) ;
6964
6965 else
6966 AV_assign_ival( grapher->opt_mat_choose_av , grapher->mat ) ;
6967
6968 /** slice selection **/
6969
6970 if( grapher->opt_slice_choose_av->imax != grapher->status->nz-1 )
6971 refit_MCW_optmenu( grapher->opt_slice_choose_av ,
6972 0, grapher->status->nz - 1, grapher->zpoint, 0,
6973 NULL , NULL ) ;
6974
6975 else
6976 AV_assign_ival( grapher->opt_slice_choose_av , grapher->zpoint ) ;
6977
6978 /** fim ignoration **/
6979
6980 igtop = MIN( grapher->status->num_series-2 , 99 ) ;
6981 igtop = MAX( igtop , 1 ) ;
6982
6983 if( grapher->fmenu->fim_ignore_choose_av->imax != igtop )
6984 refit_MCW_optmenu( grapher->fmenu->fim_ignore_choose_av ,
6985 0 , igtop , grapher->init_ignore, 0,
6986 NULL , NULL ) ;
6987 else
6988 AV_assign_ival( grapher->fmenu->fim_ignore_choose_av , grapher->init_ignore ) ;
6989
6990 /** 27 May 1999: fim polort **/
6991
6992 AV_assign_ival( grapher->fmenu->fim_polort_choose_av , grapher->polort ) ;
6993
6994 EXRETURN ;
6995 }
6996
6997 /*--------------------------------------------------------------------------*/
6998
GRA_fmenu_av_CB(MCW_arrowval * av,XtPointer cd)6999 void GRA_fmenu_av_CB( MCW_arrowval* av , XtPointer cd )
7000 {
7001 FIM_menu *fmenu = (FIM_menu *) cd ;
7002
7003 ENTRY("GRA_fmenu_av_CB") ;
7004 fmenu->cbfunc( av->wrowcol , cd , NULL ) ;
7005 EXRETURN ;
7006 }
7007 #endif /* USE_OPTMENUS */
7008
7009 /*--------------------------------------------------------------------------
7010 Selection of a color submenu item
7011 ----------------------------------------------------------------------------*/
7012
GRA_color_CB(MCW_arrowval * av,XtPointer cd)7013 void GRA_color_CB( MCW_arrowval *av , XtPointer cd )
7014 {
7015 MCW_grapher *grapher = (MCW_grapher *) cd ;
7016 int ii , jj ;
7017
7018 ENTRY("GRA_color_CB") ;
7019
7020 if( ! GRA_VALID(grapher) ) EXRETURN ;
7021
7022 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ )
7023 if( av == grapher->opt_color_av[ii] ) break ;
7024
7025 if( ii < NUM_COLOR_ITEMS ){
7026 jj = grapher->color_index[ii] ;
7027 grapher->color_index[ii] = av->ival ;
7028 if( jj != grapher->color_index[ii] ) redraw_graph( grapher , 0 ) ;
7029 }
7030 EXRETURN ;
7031 }
7032
7033 /*--------------------------------------------------------------------------*/
7034
GRA_thick_CB(Widget w,XtPointer cd,XtPointer call_data)7035 void GRA_thick_CB( Widget w , XtPointer cd , XtPointer call_data )
7036 {
7037 MCW_grapher *grapher = (MCW_grapher *) cd ;
7038 int ii , jj ;
7039
7040 ENTRY("GRA_thick_CB") ;
7041
7042 if( ! GRA_VALID(grapher) ) EXRETURN ;
7043
7044 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ )
7045 if( grapher->opt_thick_bbox[ii] != NULL &&
7046 w == grapher->opt_thick_bbox[ii]->wbut[0] ) break ;
7047
7048 if( ii < NUM_COLOR_ITEMS ){
7049 jj = grapher->thick_index[ii] ;
7050 grapher->thick_index[ii] = MCW_val_bbox( grapher->opt_thick_bbox[ii] ) ;
7051 if( jj != grapher->thick_index[ii] ) redraw_graph( grapher , 0 ) ;
7052 EXRETURN ;
7053 }
7054
7055 /* 09 Jan 1998 */
7056
7057 for( ii=0 ; ii < NUM_COLOR_ITEMS ; ii++ ){
7058 if( grapher->opt_points_bbox[ii] != NULL ){
7059 for( jj=0 ; jj < grapher->opt_points_bbox[ii]->nbut ; jj++ )
7060 if( w == grapher->opt_points_bbox[ii]->wbut[jj] ) break ;
7061 if( jj < grapher->opt_points_bbox[ii]->nbut ) break ;
7062 }
7063 }
7064
7065 if( ii < NUM_COLOR_ITEMS ){
7066 jj = grapher->points_index[ii] ;
7067 grapher->points_index[ii] = MCW_val_bbox( grapher->opt_points_bbox[ii] ) ;
7068 if( jj != grapher->points_index[ii] ){
7069 #if 0
7070 if( DATA_BOXED(grapher) )
7071 MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OFF ) ;
7072 #endif
7073 redraw_graph( grapher , 0 ) ;
7074 }
7075 EXRETURN ;
7076 }
7077
7078 EXRETURN ; /* should not be reached */
7079 }
7080
7081 /*--------------------------------------------------------------------------
7082 Save the background pixmap to a PNM file
7083 ----------------------------------------------------------------------------*/
7084
GRA_saver_CB(Widget wcaller,XtPointer cd,MCW_choose_cbs * cbs)7085 void GRA_saver_CB( Widget wcaller , XtPointer cd , MCW_choose_cbs *cbs )
7086 {
7087 int ll , ii ;
7088 MCW_grapher *grapher = (MCW_grapher *)cd ;
7089 char *fname , *ppnm ;
7090
7091 ENTRY("GRA_saver_CB") ;
7092
7093 if( ! GRA_REALZ(grapher) ) EXRETURN ;
7094
7095 if( cbs->reason != mcwCR_string ||
7096 cbs->cval == NULL || (ll=strlen(cbs->cval)) == 0 ){
7097
7098 BEEPIT ; WARNING_message("Bad save filename!?") ; EXRETURN ;
7099 }
7100
7101 fname = (char *) malloc( sizeof(char) * (ll+8) ) ;
7102 strcpy( fname , cbs->cval ) ;
7103
7104 for( ii=0 ; ii < ll ; ii++ )
7105 if( iscntrl(fname[ii]) || isspace(fname[ii]) ) break ;
7106
7107 if( ii < ll || ll < 2 || ll > 240 ){
7108 BEEPIT ; free(fname) ; WARNING_message("Bad save filename!?") ; EXRETURN ;
7109 }
7110
7111 ppnm = strstr( fname , ".ppm" ) ;
7112 if( ppnm == NULL ) ppnm = strstr( fname , ".pnm" ) ;
7113 if( ppnm == NULL ) ppnm = strstr( fname , ".jpg" ) ;
7114 if( ppnm == NULL ) ppnm = strstr( fname , ".JPG" ) ;
7115 if( ppnm == NULL ) ppnm = strstr( fname , ".png" ) ;
7116 if( ppnm == NULL ) ppnm = strstr( fname , ".PNG" ) ;
7117 if( ppnm == NULL ) strcat(fname,".ppm") ;
7118
7119 GRA_file_pixmap( grapher , fname ) ;
7120 POPDOWN_string_chooser ;
7121 free(fname) ; EXRETURN ;
7122 }
7123
7124 /*--------------------------------------------------------------------------*/
7125
GRA_file_pixmap(MCW_grapher * grapher,char * fname)7126 void GRA_file_pixmap( MCW_grapher *grapher , char *fname )
7127 {
7128 XImage *xim ;
7129 XGCValues gcv ;
7130 MRI_IMAGE *tim ;
7131 int ii ;
7132
7133 ENTRY("GRA_file_pixmap") ;
7134
7135 if( ! GRA_REALZ(grapher) ) EXRETURN ;
7136 if( grapher->fd_pxWind == (Pixmap) 0 ) EXRETURN ;
7137
7138 ii = XGetGCValues( grapher->dc->display ,
7139 grapher->dc->myGC , GCPlaneMask , &gcv ) ;
7140 if( ii == 0 ) EXRETURN ;
7141
7142 xim = XGetImage( grapher->dc->display , grapher->fd_pxWind ,
7143 0 , 0 , grapher->fWIDE , grapher->fHIGH ,
7144 gcv.plane_mask , ZPixmap ) ;
7145 if( xim == NULL ) EXRETURN ;
7146
7147 tim = XImage_to_mri( grapher->dc , xim , 0 ) ;
7148 if( tim == NULL ){ MCW_kill_XImage( xim ) ; EXRETURN ; }
7149
7150 INFO_message("Writing grapher image to '%s'",fname) ;
7151 mri_write_pnm( fname , tim ) ;
7152 mri_free( tim ) ;
7153 MCW_kill_XImage( xim ) ; /* 10 Mar 1999 */
7154 EXRETURN ;
7155 }
7156
7157 /*-----------------------------------------------------------------------------
7158 07 Jan 1999: change location of newly popped up menu
7159 -------------------------------------------------------------------------------*/
7160
GRA_mapmenu_CB(Widget w,XtPointer client_data,XtPointer call_data)7161 void GRA_mapmenu_CB( Widget w , XtPointer client_data , XtPointer call_data )
7162 {
7163 int ww,hh,xx,yy ;
7164 int pw,ph,px,py ;
7165
7166 ENTRY("GRA_mapmenu_CB") ;
7167
7168 #ifdef USING_LESSTIF
7169 EXRETURN; /* 30 Dec 2008, the LESSTIF patrol */
7170 #endif
7171 if( AFNI_yesenv("AFNI_DONT_MOVE_MENUS") ) EXRETURN ; /* 08 Aug 2001 */
7172
7173 MCW_widget_geom( w , &ww,&hh , &xx,&yy ) ;
7174 MCW_widget_geom( XtParent(XtParent(w)) , &pw,&ph , &px,&py ) ;
7175
7176 #if 1
7177 if(PRINT_TRACING){
7178 char str[256] ;
7179 sprintf(str,"menu: width=%d height=%d x=%d y=%d",ww,hh,xx,yy); STATUS(str);
7180 sprintf(str,"parent: width=%d height=%d x=%d y=%d",pw,ph,px,py); STATUS(str); }
7181 #endif
7182
7183 pw = pw >> 3 ;
7184 if( ! ( xx > px+7*pw || xx+ww < px+pw ) ){
7185 xx = px - ww ; if( xx < 0 ) xx = 0 ;
7186 #if 1
7187 if(PRINT_TRACING){
7188 char str[256]; sprintf(str,"moving menu to x=%d",xx); STATUS(str); }
7189 #endif
7190 XtVaSetValues( w , XmNx , xx , NULL ) ;
7191 }
7192
7193 RWC_xineramize( XtDisplay(w) , xx,yy,ww,hh , &xx,&yy ) ; /* 27 Sep 2000 */
7194 XtVaSetValues( w , XmNx,xx , XmNy,yy , NULL ) ;
7195 EXRETURN ;
7196 }
7197
7198 /*----------------------------------------------------------------------------*/
7199 /*! Do something every so often. */
7200
GRA_timer_CB(XtPointer cd,XtIntervalId * id)7201 void GRA_timer_CB( XtPointer cd , XtIntervalId *id ) /* 03 Dec 2003 */
7202 {
7203 MCW_grapher *grapher = (MCW_grapher *)cd ;
7204 int redo = 0 ;
7205
7206 ENTRY("GRA_timer_CB") ;
7207
7208 if( !GRA_REALZ(grapher) || grapher->timer_id == 0 ) EXRETURN ;
7209
7210 switch( grapher->timer_func ){
7211
7212 case GRA_TIMERFUNC_INDEX:{
7213 int nn = grapher->time_index , nt=grapher->status->num_series ;
7214 if( nt > 1 && grapher->timer_param != 0 ){
7215 nn = (nn+grapher->timer_param+nt) % nt ;
7216 redo = 1 ;
7217 if( grapher->status->send_CB != NULL ){
7218 GRA_cbs cbs ;
7219 cbs.reason = graCR_setindex ;
7220 cbs.key = nn ;
7221 cbs.event = NULL ;
7222 #if 0
7223 grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
7224 #else
7225 CALL_sendback( grapher , cbs ) ;
7226 #endif
7227 } else {
7228 (void)drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)ITOP(nn)) ;
7229 }
7230 }
7231 }
7232 break ;
7233
7234 case GRA_TIMERFUNC_BOUNCE:{
7235 int nn = grapher->time_index , nt=grapher->status->num_series ;
7236 if( nt > 1 && grapher->timer_param != 0 ){
7237 nn = nn + grapher->timer_param ;
7238 if( nn < 0 ){
7239 nn = -nn; grapher->timer_param = -grapher->timer_param;
7240 } else if( nn >= nt ){
7241 nn = 2*(nt-1)-nn; grapher->timer_param = -grapher->timer_param;
7242 }
7243 redo = 1 ;
7244 if( grapher->status->send_CB != NULL ){
7245 GRA_cbs cbs ;
7246 cbs.reason = graCR_setindex ;
7247 cbs.key = nn ;
7248 cbs.event = NULL ;
7249 #if 0
7250 grapher->status->send_CB( grapher, grapher->getaux, &cbs ) ;
7251 #else
7252 CALL_sendback( grapher , cbs ) ;
7253 #endif
7254 } else {
7255 (void)drive_MCW_grapher( grapher, graDR_setindex, (XtPointer)ITOP(nn)) ;
7256 }
7257 }
7258 }
7259 break ;
7260
7261 }
7262
7263 if( redo ) grapher->timer_id = XtAppAddTimeOut(
7264 XtWidgetToApplicationContext(grapher->opt_quit_pb) ,
7265 grapher->timer_delay , GRA_timer_CB , grapher ) ;
7266 else grapher->timer_id = 0 ;
7267
7268 EXRETURN ;
7269 }
7270
7271 /*--------------------------------------------------------------------------*/
7272
GRA_timer_stop(MCW_grapher * grapher)7273 void GRA_timer_stop( MCW_grapher *grapher )
7274 {
7275 if( grapher->timer_id > 0 ){
7276 XtRemoveTimeOut(grapher->timer_id); grapher->timer_id = 0;
7277 }
7278 }
7279
7280 /*--------------------------------------------------------------------------*/
7281 /* externally set 1D transformation [19 Dec 2018] */
7282
GRA_find_1D_transform(MCW_grapher * grapher,char * nam)7283 int GRA_find_1D_transform( MCW_grapher *grapher , char *nam )
7284 {
7285 int ii ;
7286
7287 if( grapher == NULL || grapher->status->transforms1D == NULL ) return -1 ;
7288 if( nam == NULL || *nam == '\0' ) return -1 ;
7289
7290 for( ii=0 ; ii < grapher->status->transforms1D->num ; ii++ ){
7291 if( strcmp( grapher->status->transforms1D->labels[ii] , nam ) == 0 )
7292 return ii ;
7293 }
7294
7295 return -1 ;
7296 }
7297
GRA_startup_1D_transform(char * nam)7298 void GRA_startup_1D_transform( char *nam )
7299 {
7300 if( startup_1D_transform != NULL ){
7301 free(startup_1D_transform) ;
7302 startup_1D_transform = NULL ;
7303 }
7304 if( nam != NULL && *nam != '\0' )
7305 startup_1D_transform = strdup(nam) ;
7306 return ;
7307 }
7308
GRA_set_1D_transform(MCW_grapher * grapher,char * nam)7309 void GRA_set_1D_transform( MCW_grapher *grapher , char *nam )
7310 {
7311 int tt ;
7312
7313 if( grapher == NULL ) return ;
7314 tt = GRA_find_1D_transform( grapher , nam ) ; if( tt < 0 ) return ;
7315
7316 AV_assign_ival( grapher->transform1D_av , tt+1 ) ;
7317
7318 grapher->transform1D_func = grapher->status->transforms1D->funcs[tt];
7319 grapher->transform1D_index = tt+1 ;
7320 grapher->transform1D_flags = grapher->status->transforms1D->flags[tt];
7321
7322 #if 0
7323 if( (grapher->transform1D_flags & SET_DPLOT_OVERLAY) && !DATA_BOXED(grapher) ){
7324 MCW_set_bbox( grapher->opt_dplot_bbox , DPLOT_OVERLAY ) ;
7325 }
7326 #endif
7327
7328 /** redraw_graph( grapher , 0 ) ; **/
7329 return ;
7330 }
7331
7332 /*--------------------------------------------------------------------------*/
7333 /** AFNI_XDrawLines() was moved from here to xdraw.c -- 30 Aug 2021 -- RWC */
7334 /*--------------------------------------------------------------------------*/
7335