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 #include "mrilib.h"
8 #include "coxplot.h"
9 #include "xim.h"
10 #include "parser.h"
11
12 /*-------------------------------------------------------------------*/
13 /*---- quickie program to look at some graphs - RWCox - Feb 1999 ----*/
14
15 #define DEFAULT_NCOLOVR 20
16
17 static char *INIT_colovr[DEFAULT_NCOLOVR] = {
18 "#ffff00" , "#ffcc00" , "#ff9900" , "#ff6900" , "#ff4400" , "#ff0000" ,
19 "#0000ff" , "#0044ff" , "#0069ff" , "#0099ff" , "#00ccff" , "#00ffff" ,
20 "green" , "limegreen" , "violet" , "hotpink" ,
21 "white" , "#dddddd" , "#bbbbbb" , "black"
22 } ;
23
24 static char *INIT_labovr[DEFAULT_NCOLOVR] = {
25 "yellow" , "yell-oran" , "oran-yell" , "orange" , "oran-red" , "red" ,
26 "dk-blue", "blue" , "lt-blue1" , "lt-blue2" , "blue-cyan", "cyan" ,
27 "green" , "limegreen" , "violet" , "hotpink" ,
28 "white" , "gry-dd" , "gry-bb" , "black"
29 } ;
30
31 static int nx,nts , sep=1, sepscl=0;
32 static float **yar , *xar ;
33 static MCW_DC *dc ;
34 static char *title=NULL , *wintitle=NULL, *xlabel=NULL , *ylabel=NULL ;
35
36 static char *dfile_nar[6] = {
37 "Roll [\\degree]" , "Pitch [\\degree]" , "Yaw [\\degree]" ,
38 "\\Delta I-S [mm]" , "\\Delta R-L [mm]" , "\\Delta A-P [mm]" } ;
39
40 static int nyar = 0 ;
41 static char *ynar[128] ;
42 static char **yname = NULL ;
43
44 void startup_timeout_CB( XtPointer client_data , XtIntervalId *id ) ;
45
46 #undef JPEG_MODE
47 #undef PNG_MODE
48 #define JPEG_MODE 3
49 #define PNG_MODE 4
50
51 #undef PNM_MODE
52 #define PNM_MODE 5 /* 06 Jan 2016 */
53
54 /*-----------------------------------------------------------------*/
55 /* Stuff for censor color overlay boxes (cf. 3dDeconvolve.c) */
56
57 static int num_CENSOR = 0 ;
58 static int_triple *abc_CENSOR = NULL ;
59 static float_triple *rgb_CENSOR = NULL ;
60
61 static float_triple rgb_NOW = { 1.0f , 0.9f , 0.4f } ;
62
63 static int num_blocks = 0 ;
64 static int *block_list = NULL ;
65
66 static int num_censor_array = 0 ;
67 static float *censor_array = NULL ;
68 static float_triple *censor_rgb = NULL ;
69 static float_triple censor_rgbAA = { 1.0f , 0.9f , 0.4f } ;
70
71 /*-----------------------------------------------------------------*/
72 /* Help the pitifully ignorant users out there (most of them). */
73 /*-----------------------------------------------------------------*/
74
usage_1dplot(int detail)75 void usage_1dplot(int detail)
76 {
77 printf("\n"
78 "Usage: 1dplot [options] tsfile ...\n\n"
79 "Graphs the columns of a *.1D time series file to the X11 screen,\n"
80 "or to an image file (.jpg or .png).\n"
81 "\n"
82 " ** This is the original C-language plotting program in AFNI, first created **\n"
83 " ** in 1999 (by RW Cox), built on routines he first wrote in the 1980s. **\n"
84 " ** Also see the much newer and similar Python-language program 1dplot.py **\n"
85 " ** (created by PA Taylor in 2018), which can produce nicer looking graphs. **\n"
86 "\n"
87 "-------\n"
88 "OPTIONS\n"
89 "-------\n"
90 " -install = Install a new X11 colormap.\n"
91 " -sep = Plot each column in a separate sub-graph.\n"
92 " -one = Plot all columns together in one big graph.\n"
93 " [default = -sep]\n"
94 " -sepscl = Plot each column in a separate sub-graph\n"
95 " and allow each sub-graph to have a different\n"
96 " y-scale. -sepscl is meaningless with -one!\n"
97 " -noline = Don't plot the connecting lines (also implies '-box').\n"
98 " -NOLINE = Same as '-noline', but will not try to plot values outside\n"
99 " the rectangular box that contains the graph axes.\n"
100 " -box = Plot a small 'box' at each data point, in addition\n"
101 " to the lines connecting the points.\n"
102 " * The box size can be set via the environment variable\n"
103 " AFNI_1DPLOT_BOXSIZE; the value is a fraction of the\n"
104 " overall plot size. The standard box size is 0.006.\n"
105 " Example with a bigger box:\n"
106 " 1dplot -DAFNI_1DPLOT_BOXSIZE=0.01 -box A.1D\n"
107 " * The box shapes are different for different time\n"
108 " series columns. At present, there is no way to\n"
109 " control which shape is used for what column\n"
110 " (unless you modify the source code, that is).\n"
111 " * If you want some data columns plotted with boxes\n"
112 " and some with lines, don't use '-box'. Instead, use\n"
113 " option '-dashed'.\n"
114 " * You can set environment variable AFNI_1DPLOT_RANBOX\n"
115 " to YES to get the '-noline' boxes plotted in a\n"
116 " pseudo-random order, so that one particular color\n"
117 " doesn't dominate just because it is last in the\n"
118 " plotting order; for example:\n"
119 " 1dplot -DAFNI_1DPLOT_RANBOX=YES -one -x X.1D -noline Y1.1D Y2.1D Y3.1D\n"
120 "\n"
121 " -hist = Plot graphs in histogram style (i.e., vertical boxes).\n"
122 " * Histograms can be generated from 3D or 1D files using\n"
123 " program 3dhistog; for example\n"
124 " 3dhistog -nbin 50 -notitle -min 0 -max .04 err.1D > eh.1D\n"
125 " 1dplot -hist -x eh.1D'[0]' -xlabel err -ylabel hist eh.1D'[1]'\n"
126 " or, for something a little more fun looking:\n"
127 " 1dplot -one -hist -dashed 1:2 -x eh.1D'[0]' \\\n"
128 " -xlabel err -ylabel hist eh.1D'[1]' eh.1D'[1]'\n"
129 "\n"
130 " ** The '-norm' options below can be useful for plotting data\n"
131 " with different value ranges on top of each other via '-one':\n"
132 " -norm2 = Independently scale each time series plotted to\n"
133 " have L_2 norm = 1 (sum of squares).\n"
134 " -normx = Independently scale each time series plotted to\n"
135 " have max absolute value = 1 (L_infinity norm).\n"
136 " -norm1 = Independently scale each time series plotted to\n"
137 " have max sum of absolute values = 1 (L_1 norm).\n"
138 " -demean = This option will remove the mean from each time series\n"
139 " (before normalizing). The combination '-demean -normx -one'\n"
140 " can be useful when plotting disparate data together.\n"
141 " * If you use '-demean' twice, you will get linear detrending.\n"
142 " * Et cetera (e.g,, 4 times gives you cubic detrending.)\n"
143 "\n"
144 " -x X.1D = Use for X axis the data in X.1D.\n"
145 " Note that X.1D should have one column\n"
146 " of the same length as the columns in tsfile. \n"
147 " ** Coupled with '-box -noline', you can use '-x' to make\n"
148 " a scatter plot, as in graphing file A1.1D along the\n"
149 " x-axis and file A2.1D along the y-axis:\n"
150 " 1dplot -box -noline -x A1.1D -xlabel A1 -ylabel A2 A2.1D\n"
151 " ** '-x' will override -dx and -xzero; -xaxis still works\n"
152 "\n"
153 " -xl10 X.1D = Use log10(X.1D) as the X axis.\n"
154 "\n"
155 " -xmulti X1.1D X2.1D ...\n"
156 " This new [Oct 2013] option allows you to plot different\n"
157 " columns from the data with different values along the\n"
158 " x-axis. You can supply one or more 1D files after the\n"
159 " '-xmulti' option. The columns from these files are\n"
160 " catenated, and then the first xmulti column is used as\n"
161 " as x-axis values for the first data column plotted, the\n"
162 " second xmulti column gives the x-axis values for the\n"
163 " second data column plotted, and so on.\n"
164 " ** The command line arguments after '-xmulti' are taken\n"
165 " as 1D filenames to read, until an argument starts with\n"
166 " a '-' character -- this would either be another option,\n"
167 " or just a single '-' to separate the xmulti 1D files\n"
168 " from the data files to be plotted.\n"
169 " ** If you don't provide enough xmulti columns for all the\n"
170 " data files, the last xmulti column will be re-used.\n"
171 " ** Useless but fun example:\n"
172 " 1deval -num 100 -expr '(i-i)+z+gran(0,6)' > X1.1D\n"
173 " 1deval -num 100 -expr '(i-i)+z+gran(0,6)' > X2.1D\n"
174 " 1dplot -one -box -xmulti X1.1D X2.1D - X2.1D X1.1D\n"
175 "\n"
176 " -dx xx = Spacing between points on the x-axis is 'xx'\n"
177 " [default = 1] SYNONYMS: '-dt' and '-del'\n"
178 " -xzero zz = Initial x coordinate is 'zz' [default = 0]\n"
179 " SYNONYMS: '-tzero' and '-start'\n"
180 " -nopush = Don't 'push' axes ranges outwards.\n"
181 " -ignore nn = Skip first 'nn' rows in the input file\n"
182 " [default = 0]\n"
183 " -use mm = Plot 'mm' points [default = all of them]\n"
184 " -xlabel aa = Put string 'aa' below the x-axis\n"
185 " [default = no axis label]\n"
186 " -ylabel aa = Put string 'aa' to the left of the y-axis\n"
187 " [default = no axis label]\n"
188 " -plabel pp = Put string 'pp' atop the plot.\n"
189 " Some characters, such as '_' have\n"
190 " special formatting effects. You \n"
191 " can escape that with '\'. For example:\n"
192 " echo 2 4.5 -1 | 1dplot -plabel 'test_underscore' -stdin\n"
193 " versus\n"
194 " echo 2 4.5 -1 | 1dplot -plabel 'test\\_underscore' -stdin\n"
195 " -title pp = Same as -plabel, but only works with -ps/-png/-jpg/-pnm options.\n"
196 " -wintitle pp = Set string 'pp' as the title of the frame \n"
197 " containing the plot. Default is based on input.\n"
198 #if 0
199 " Use -plabel instead for full interoperability.\n"
200 " [In X11 mode, the X11 startup 'consumes' the '-title' ]\n"
201 " [before the program scans the command line for options]\n"
202 #endif
203 "\n"
204 " -naked = Do NOT plot axes or labels, just the graph(s).\n"
205 " You might want to use '-nopush' with '-naked'.\n"
206 " -aspect A = Set the width-to-height ratio of the plot region to 'A'.\n"
207 " Default value is 1.3. Larger 'A' means a wider graph.\n"
208 "\n"
209 " -stdin = Don't read from tsfile; instead, read from\n"
210 " stdin and plot it. You cannot combine input\n"
211 " from stdin and tsfile(s). If you want to do so,\n"
212 " use program 1dcat first.\n"
213 "\n"
214 " -ps = Don't draw plot in a window; instead, write it\n"
215 " to stdout in PostScript format.\n"
216 " * If you view the result in 'gv', you should turn\n"
217 " 'anti-alias' off, and switch to landscape mode.\n"
218 " * You can use the 'gs' program to convert PostScript\n"
219 " to other formats; for example, a .bmp file:\n"
220 " 1dplot -ps ~/data/verbal/cosall.1D | \n"
221 " gs -r100 -sOutputFile=fred.bmp -sDEVICE=bmp256 -q -dBATCH -\n"
222 " * 1dplot is built on some line drawing software written\n"
223 " a long time ago in a galaxy far away, which is why PostScript\n"
224 " output was a natural thing to do -- I doubt that anyone uses\n"
225 " this feature in these decadent modern times.\n"
226 "\n"
227 " -jpg fname } = Render plot to an image and save to a file named\n"
228 " -jpeg fname } = 'fname', in JPEG mode or in PNG mode or in PNM mode.\n"
229 " -png fname } = The default image width is 1024 pixels; to change\n"
230 " -pnm fname } = this value to 2048 pixels (say), do\n"
231 " setenv AFNI_1DPLOT_IMSIZE 2048\n"
232 " before running 1dplot, or add\n"
233 " -DAFNI_1DPLOT_IMSIZE=2048\n"
234 " to the 1dplot command line. Widths over 4096 might\n"
235 " start to look odd in some cases. The largest allowed\n"
236 " size is 8192 pixels.\n"
237 " * PNG files created by 1dplot will be smaller than JPEG,\n"
238 " and are compressed without loss.\n"
239 " * PNG output requires that the netpbm program\n"
240 " pnmtopng be installed somewhere in your PATH.\n"
241 " This program is NOT supplied with AFNI, but must\n"
242 " be installed separately:\n"
243 " https://afni.nimh.nih.gov/pub/dist/doc/htmldoc/index.html\n"
244 " * PNM output files are not compressed, and are manipulable\n"
245 " by the netpbm package: http://netpbm.sourceforge.net/\n"
246 " Otherwise, this format isn't very useful anymore.\n"
247 " * There will be small drawing differences between the\n"
248 " X11 (interactive) plotting window and the images saved\n"
249 " by these options -- or by the interactive button.\n"
250 " These differences arise from the use of different line\n"
251 " drawing functions for X11 windows and for off-screen\n"
252 " bitmap images.\n"
253 "\n"
254 " -pngs size fname } = convenience options equivalent to\n"
255 " -jpgs size fname } = -DAFNI_1DPLOT_IMSIZE=size followed by\n"
256 " -jpegs size fname} = -png fname (or -jpg or -jpeg or -pnm)\n"
257 " -pnms size fname } = The largest allowed size is 8192 pixels.\n"
258 "\n"
259 " -ytran 'expr' = Transform the data along the y-axis by\n"
260 " applying the expression to each input value.\n"
261 " For example:\n"
262 " -ytran 'log10(z)'\n"
263 " will take log10 of each input time series value\n"
264 " before plotting it.\n"
265 " * The expression should have one variable (any letter\n"
266 " from a-z will do), which stands for the time series\n"
267 " data to be transformed.\n"
268 " * An expression such as 'sqrt(x*x+i)' will use 'x'\n"
269 " for the time series value and use 'i' for the time\n"
270 " index (starting at 0) -- in this way, you can use\n"
271 " time-dependent transformations, if needed.\n"
272 " * This transformation applies to all input time series\n"
273 " (at present, there is no way to transform different\n"
274 " time series in distinct ways inside 1dplot).\n"
275 " * '-ytran' is applied BEFORE the various '-norm' options.\n"
276 "\n"
277 " -xtran 'expr' = Similar, but for the x-axis.\n"
278 " ** Applies to '-xmulti' , '-x' , or the default x-axis.\n"
279 "\n"
280 " -xaxis b:t:n:m = Set the x-axis to run from value 'b' to\n"
281 " value 't', with 'n' major divisions and\n"
282 " 'm' minor tic marks per major division.\n"
283 " For example:\n"
284 " -xaxis 0:100:5:20\n"
285 " Setting 'n' to 0 means no tic marks or labels.\n"
286 " * You can set 'b' to be greater than 't', to\n"
287 " have the x-coordinate decrease from left-to-right.\n"
288 " * This is the only way to have this effect in 1dplot.\n"
289 " * In particular, '-dx' with a negative value will not work!\n"
290 "\n"
291 " -yaxis b:t:n:m = Similar to above, for the y-axis. These\n"
292 " options override the normal autoscaling\n"
293 " of their respective axes.\n"
294 "\n"
295 " -ynames a b ... = Use the strings 'a', 'b', etc., as\n"
296 " labels to the right of the graphs,\n"
297 " corresponding to each input column.\n"
298 " These strings CANNOT start with the\n"
299 " '-' character.\n"
300 " N.B.: Each separate string after '-ynames'\n"
301 " is taken to be a new label, until the\n"
302 " end of the command line or until some\n"
303 " string starts with a '-'. In particular,\n"
304 " This means you CANNOT do something like\n"
305 " 1dplot -ynames a b c file.1D\n"
306 " since the input filename 'file.1D' will\n"
307 " be used as a label string, not a filename.\n"
308 " Instead, you must put another option between\n"
309 " the end of the '-ynames' label list, OR you\n"
310 " can put a single '-' at the end of the label\n"
311 " list to signal its end:\n"
312 " 1dplot -ynames a b c - file.1D\n"
313 " TSV files: When plotting a TSV file, where the first row\n"
314 " is the set of column labels, you can use this\n"
315 " Unix trick to put the column labels here:\n"
316 " -ynames `head -1 file.tsv`\n"
317 " The 'head' command copies just the first line\n"
318 " of the file to stdout, and the backquotes `...`\n"
319 " capture stdout and put it onto the command line.\n"
320 " * You might need to put a single '-' after this\n"
321 " option to prevent the problem alluded to above.\n"
322 " In any case, it can't hurt to use '-' as an option\n"
323 " after '-ynames'.\n"
324 " * If any of the TSV labels start with the '-' character,\n"
325 " peculiar and unpleasant things might transpire.\n"
326 "\n"
327 " -volreg = Makes the 'ynames' be the same as the\n"
328 " 6 labels used in plug_volreg for\n"
329 " Roll, Pitch, Yaw, I-S, R-L, and A-P\n"
330 " movements, in that order.\n"
331 "\n"
332 " -thick = Each time you give this, it makes the line\n"
333 " thickness used for plotting a little larger.\n"
334 " [An alternative to using '-DAFNI_1DPLOT_THIK=...']\n"
335 " -THICK = Twice the power of '-thick' at no extra cost!!\n"
336 "\n"
337 " -dashed codes = Plot dashed lines between data points. The 'codes'\n"
338 " are a colon-separated list of dash values, which\n"
339 " can be 1 (solid), 2 (longer dashes), or 3 (shorter dashes).\n"
340 " 0 can be used to indicate that a time series is to be\n"
341 " plotted without lines but with boxes instead.\n"
342 " ** Example: '-dashed 1:2:3' means to plot the first time\n"
343 " series with solid lines, the second with long dashes,\n"
344 " and the third with short dashes.\n"
345 "\n"
346 " -Dname=val = Set environment variable 'name' to 'val'\n"
347 " for this run of the program only:\n"
348 " 1dplot -DAFNI_1DPLOT_THIK=0.01 -DAFNI_1DPLOT_COLOR_01=blue '1D:3 4 5 3 1 0'\n"
349 "\n"
350 "You may also select a subset of columns to display using\n"
351 "a tsfile specification like 'fred.1D[0,3,5]', indicating\n"
352 "that columns #0, #3, and #5 will be the only ones plotted.\n"
353 "For more details on this selection scheme, see the output\n"
354 "of '3dcalc -help'.\n"
355 "\n"
356 "Example: graphing a 'dfile' output by 3dvolreg, when TR=5:\n"
357 " 1dplot -volreg -dx 5 -xlabel Time 'dfile[1..6]'\n"
358 "\n"
359 "You can also input more than one tsfile, in which case the files\n"
360 "will all be plotted. However, if the files have different column\n"
361 "lengths, the shortest one will rule.\n"
362 "\n"
363 "The colors for the line graphs cycle between black, red, green, and\n"
364 "blue. You can alter these colors by setting Unix environment\n"
365 "variables of the form AFNI_1DPLOT_COLOR_xx -- cf. README.environment.\n"
366 "You can alter the thickness of the lines by setting the variable\n"
367 "AFNI_1DPLOT_THIK to a value between 0.00 and 0.05 -- the units are\n"
368 "fractions of the page size; of course, you can also use the options\n"
369 "'-thick' or '-THICK' if you prefer.\n"
370 "\n"
371 "----------------\n"
372 "RENDERING METHOD\n"
373 "----------------\n"
374 "On 30 Apr 2012, a new method of rendering the 1dplot graph into an X11\n"
375 "window was introduced -- this method uses 'anti-aliasing' to produce\n"
376 "smoother-looking lines and characters. If you want the old coarser-looking\n"
377 "rendering method, set environment variable AFNI_1DPLOT_RENDEROLD to YES.\n"
378 "\n"
379 "The program always uses the new rendering method when drawing to a JPEG\n"
380 "or PNG or PNM file (which is not and never has been just a screen capture).\n"
381 "There is no way to disable the new rendering method for image-file saves.\n"
382 "\n"
383 "------\n"
384 "LABELS\n"
385 "------\n"
386 "Besides normal alphabetic text, the various labels can include some\n"
387 "special characters, using TeX-like escapes starting with '\\'.\n"
388 "Also, the '^' and '_' characters denote super- and sub-scripts,\n"
389 "respectively. The following command shows many of the escapes:\n"
390 " 1deval -num 100 -expr 'J0(t/4)' | 1dplot -stdin -thick \\\n"
391 " -xlabel '\\alpha\\beta\\gamma\\delta\\epsilon\\zeta\\eta^{\\oplus\\dagger}\\times c' \\\n"
392 " -ylabel 'Bessel Function \\green J_0(t/4)' \\\n"
393 " -plabel '\\Upsilon\\Phi\\Chi\\Psi\\Omega\\red\\leftrightarrow\\blue\\partial^{2}f/\\partial x^2'\n"
394 "\n"
395 TS_HELP_STRING
396 "\n"
397 TSV_HELP_STRING
398 ) ;
399
400 printf("\n"
401 "--------------\n"
402 "MARKING BLOCKS (e.g., censored time points)\n"
403 "--------------\n"
404 "The following options let you mark blocks along the x-axis, by drawing\n"
405 "colored vertical boxes over the standard white background.\n"
406 " * The intended use is to mark blocks of time points that are censored\n"
407 " out of an analysis, which is why the options are the same as those\n"
408 " in 3dDeconvolve -- but you can mark blocks for any reason, of course.\n"
409 " * These options don't do anything when the '-x' option is used to\n"
410 " alter the x-axis spacings.\n"
411 " * To see what the various color markings look like, try this silly example:\n"
412 "\n"
413 " 1deval -num 100 -expr 'lran(2)' > zz.1D\n"
414 " 1dplot -thick -censor_RGB red -CENSORTR 3-8 \\\n"
415 " -censor_RGB green -CENSORTR 11-16 \\\n"
416 " -censor_RGB blue -CENSORTR 22-27 \\\n"
417 " -censor_RGB yellow -CENSORTR 34-39 \\\n"
418 " -censor_RGB violet -CENSORTR 45-50 \\\n"
419 " -censor_RGB pink -CENSORTR 55-60 \\\n"
420 " -censor_RGB gray -CENSORTR 65-70 \\\n"
421 " -censor_RGB #2cf -CENSORTR 75-80 \\\n"
422 " -plabel 'red green blue yellow violet pink gray #2cf' zz.1D &\n"
423 "\n"
424 " -censor_RGB clr = set the color used for the marking to 'clr', which\n"
425 " can be one of the strings below:\n"
426 " red green blue yellow violet pink gray (OR grey)\n"
427 " * OR 'clr' can be in the form '#xyz' or '#xxyyzz', where\n"
428 " 'x', 'y', and 'z' are hexadecimal digits -- for example,\n"
429 " '#2cf' is sort of a cyan color.\n"
430 " * OR 'clr' can be in the form 'rgbi:rf/gf/bf' where\n"
431 " each color intensity (rf, gf, bf) is a number between\n"
432 " 0.0 and 1.0 -- e.g., white is 'rgbi:1.0/1.0/1.0'.\n"
433 " Since the background is white, dark colors don't look\n"
434 " good here, and will obscure the graphs; for example,\n"
435 " pink is defined here as 'rgbi:1.0/0.5/0.5'.\n"
436 " * The default color is (a rather pale) yellow.\n"
437 " * You can use '-censor_RGB' more than once. The color\n"
438 " most recently specified previous on the command line\n"
439 " is what will be used with the '-censor' and '-CENSORTR'\n"
440 " options. This allows you to mark different blocks\n"
441 " with different colors (e.g., if they were censored\n"
442 " for different reasons).\n"
443 " * The feature of allowing multiple '-censor_RGB' options\n"
444 " means that you must put this option BEFORE the\n"
445 " relevant '-censor' and/or '-CENSORTR' options.\n"
446 " Otherwise, you'll get the default yellow color!\n"
447 "\n"
448 " -censor cname = cname is the filename of censor .1D time series \n"
449 " * This is a file of 1s and 0s, indicating which \n"
450 " time points are to be un-marked (1) and which are \n"
451 " to be marked (0). \n"
452 " * Please note that only one '-censor' option can be \n"
453 " used, for compatibility with 3dDeconvolve. \n"
454 " * The option below may be simpler to use! \n"
455 " (And can be used multiple times.) \n"
456 "\n"
457 " -CENSORTR clist = clist is a list of strings that specify time indexes\n"
458 " to be marked in the graph(s). Each string is of \n"
459 " one of the following forms: \n"
460 " 37 => mark global time index #37 \n"
461 " 2:37 => mark time index #37 in run #2 \n"
462 " 37..47 => mark global time indexes #37-47 \n"
463 " 37-47 => same as above \n"
464 " *:0-2 => mark time indexes #0-2 in all runs \n"
465 " 2:37..47 => mark time indexes #37-47 in run #2 \n"
466 " * Time indexes within each run start at 0. \n"
467 " * Run indexes start at 1 (just be to confusing). \n"
468 " * Multiple -CENSORTR options may be used, or \n"
469 " multiple -CENSORTR strings can be given at \n"
470 " once, separated by spaces or commas. \n"
471 " * Each argument on the command line after \n"
472 " '-CENSORTR' is treated as a censoring string, \n"
473 " until an argument starts with a '-' or an \n"
474 " alphabetic character, or it contains the substring\n"
475 " '1D'. This means that if you want to plot a file \n"
476 " named '9zork.xyz', you may have to do this: \n"
477 " 1dplot -CENSORTR 3-7 18-22 - 9zork.xyz \n"
478 " The stand-alone '-' will stop the processing \n"
479 " of censor strings; otherwise, the '9zork.xyz' \n"
480 " string, since it doesn't start with a letter, \n"
481 " would be treated as a censoring string, which \n"
482 " you would find confusing. \n"
483 " ** N.B.: 2:37,47 means index #37 in run #2 and \n"
484 " global time index 47; it does NOT mean \n"
485 " index #37 in run #2 AND index #47 in run #2. \n"
486 "\n"
487 " -concat rname = rname is the filename for list of concatenated runs\n"
488 " * 'rname' can be in the format \n"
489 " '1D: 0 100 200 300' \n"
490 " which indicates 4 runs, the first of which \n"
491 " starts at time index=0, second at index=100, \n"
492 " and so on. \n"
493 " * The ONLY function of '-concat' is for use with \n"
494 " '-CENSORTR', to be compatible with 3dDeconvolve\n"
495 " [e.g., for plotting motion parameters from]\n"
496 " [3dvolreg -1Dfile, where you've cat-enated]\n"
497 " [the 1D files from separate runs into one ]\n"
498 " [long file for plotting with this program.]\n"
499 "\n"
500 " -rbox x1 y1 x2 y2 color1 color2\n"
501 " = Draw a rectangular box with corners (x1,y1) to\n"
502 " (x2,y2), in color1, with an outline in color2.\n"
503 " Colors are names, such as 'green'.\n"
504 " [This option lets you make bar]\n"
505 " [charts, *if* you care enough.]\n"
506 "\n"
507 " -Rbox x1 y1 x2 y2 y3 color1 color2\n"
508 " = As above, with an extra horizontal line at y3.\n"
509 "\n"
510 " -line x1 y1 x2 y2 color dashcode\n"
511 " = Draw one line segment.\n"
512 "\n"
513 "Another fun fun example:\n"
514 "\n"
515 " 1dplot -censor_RGB #ffa -CENSORTR '0-99' \\\n"
516 " `1deval -1D: -num 61 -dx 0.3 -expr 'J0(x)'`\n"
517 "\n"
518 "which illustrates the use of 'censoring' to mark the entire graph\n"
519 "background in pale yellow '#ffa', and also illustrates the use\n"
520 "of the '-1D:' option in 1deval to produce output that can be\n"
521 "used directly on the command line, via the backquote `...` operator.\n"
522 "\n"
523 ) ;
524
525 PRINT_COMPILE_DATE ;
526 return;
527 }
528
529 /*---------------------------------------------------------------------------*/
530 /* This program is a very elaborate wrapper for the plot_ts.c functions. */
531 /*---------------------------------------------------------------------------*/
532
main(int argc,char * argv[])533 int main( int argc , char *argv[] )
534 {
535 int iarg , ii , ny , ignore=0 , use=0 , install=0 ;
536 float dx=1.0 , xzero=0.0 ;
537 char *cpt , *xfile=NULL; int xl10=0 ;
538 MRI_IMAGE *inim , *flim ;
539 float *far ;
540 XtAppContext app ;
541 Widget shell=(Widget)NULL ;
542 int use_stdin=0 ; /* 01 Aug 2001 */
543 int out_ps =0 ; /* 29 Nov 2002 */
544 int nopush =0 ;
545 int nnax=0,mmax=0 , nnay=0,mmay=0 ;
546 float xbot,xtop , ybot,ytop ; float thik=0.0f ;
547 int skip_x11=0 , imsave=0 ; char *imfile=NULL ;
548 int do_norm=0 ; /* 26 Mar 2008 */
549 int demean=0 ; /* 14 May 2015 */
550 char *ytran=NULL; /* 16 Jun 2009 */
551 char *xtran=NULL; /* 23 Oct 2013 */
552 char autotitle[512]={""}; /* 23 March 2009 */
553 float tsbox=0.0f , boxsiz ; int noline=0 ;
554
555 /*---------- startup bureaucracy ----------*/
556
557 mainENTRY("1dplot main"); machdep();
558 PRINT_VERSION("1dplot"); AUTHOR("RWC et al.");
559
560 /*----- 29 Nov 2002: scan for things that make us skip X11 -----*/
561
562 for( ii=1 ; ii < argc ; ii++ ){
563 if( strcasecmp(argv[ii],"-ps") == 0 ){ skip_x11 = 1; break; }
564 if( strcasecmp(argv[ii],"-jpg") == 0 ){ skip_x11 = 1; break; }
565 if( strcasecmp(argv[ii],"-jpgs") == 0 ){ skip_x11 = 1; break; }
566 if( strcasecmp(argv[ii],"-jpeg") == 0 ){ skip_x11 = 1; break; }
567 if( strcasecmp(argv[ii],"-jpegs")== 0 ){ skip_x11 = 1; break; }
568 if( strcasecmp(argv[ii],"-png") == 0 ){ skip_x11 = 1; break; }
569 if( strcasecmp(argv[ii],"-pngs") == 0 ){ skip_x11 = 1; break; }
570 if( strcasecmp(argv[ii],"-help") == 0 ){ skip_x11 = 1; break; }
571 if( strcasecmp(argv[ii],"-pnm") == 0 ){ skip_x11 = 1; break; }
572 if( strcasecmp(argv[ii],"-pnms") == 0 ){ skip_x11 = 1; break; }
573 }
574 if( argc == 1 ) skip_x11 = 1 ; /*-- this is because Ziad is trouble --*/
575
576 /*----- check for the '-title' option now, since X11 will eat it -----*/
577
578 if( !skip_x11 ){
579 for( ii=1 ; ii < argc ; ii++ ){
580 if( strcmp(argv[ii],"-title") == 0 ){
581 #if 0
582 WARNING_message("-title used with X11 plotting: use -plabel instead!");
583 #endif
584 title = argv[ii+1] ; break ;
585 }
586 }
587 }
588
589 /*----- open X11 (don't do anything with it until the very end) ------*/
590
591 if( !skip_x11 ){
592 shell = XtVaAppInitialize(
593 &app , "AFNI" , NULL , 0 , &argc , argv , NULL , NULL ) ;
594 if( shell == NULL ) ERROR_exit("Cannot initialize X11!") ;
595 }
596
597 /*--- other pre-scan setup stuff ---*/
598
599 cpt = my_getenv("TMPDIR") ; /* just for fun */
600
601 boxsiz = AFNI_numenv("AFNI_1DPLOT_BOXSIZE") ;
602 if( boxsiz <= 0.0f ) boxsiz = 0.006f ;
603 else if( boxsiz < 0.001f ) boxsiz = 0.001f ;
604 else if( boxsiz > 0.020f ) boxsiz = 0.020f ;
605
606 /*------------ scan arguments that X11 didn't eat ------------*/
607
608 iarg = 1 ;
609 while( iarg < argc && argv[iarg][0] == '-' ){
610
611 /*-- help? --*/
612
613 if(strcmp(argv[iarg],"-help") == 0 ||
614 strcmp(argv[iarg],"-h") == 0) {
615 usage_1dplot(strlen(argv[iarg])>3?2:1);
616 exit(0) ;
617 }
618
619 /*----------*/
620
621 if( strcmp(argv[iarg],"-aspect") == 0 ){ /* 03 May 2018 */
622 float asp = (float)strtod(argv[++iarg],NULL) ;
623 if( asp > 0.0f && asp < 666.0f )
624 plot_ts_set_aspect(asp) ;
625 iarg++ ; continue ;
626 }
627
628 if( strcmp(argv[iarg],"-noaxes") == 0 ){ /* 03 May 2018 */
629 plot_ts_do_perim(0) ;
630 iarg++ ; continue ;
631 }
632
633 if( strcmp(argv[iarg],"-naked") == 0 ){ /* 03 May 2018 */
634 plot_ts_do_naked(1) ;
635 plot_ts_setthik(0.003f) ;
636 iarg++ ; continue ;
637 }
638 if( strcmp(argv[iarg],"-NAKED") == 0 ){ /* 09 May 2018 */
639 plot_ts_do_naked(2) ;
640 iarg++ ; continue ;
641 }
642
643 #if 0
644 if( strcmp(argv[iarg],"-vbox") == 0 ){ /* HIDDEN: just for testing */
645 float xb1,xb2 ;
646 xb1 = (float)strtod(argv[++iarg],NULL) ;
647 xb2 = (float)strtod(argv[++iarg],NULL) ;
648 plot_ts_add_vbox( -1 , xb1,xb2 , 1.0f,1.0f,0.0f ) ;
649 iarg++ ; continue ;
650 }
651 #endif
652
653 if( strcmp(argv[iarg],"-rbox") == 0 ){
654 float x1,y1 , x2,y2,y3 , r1,g1,b1 , r2,g2,b2 ; int qq ;
655 x1 = (float)strtod(argv[++iarg],NULL) ;
656 y1 = (float)strtod(argv[++iarg],NULL) ;
657 x2 = (float)strtod(argv[++iarg],NULL) ;
658 y2 = (float)strtod(argv[++iarg],NULL) ; y3 = 1.666e18f ;
659 qq = find_color_name( argv[++iarg] , &r1,&g1,&b1 ) ;
660 if( qq < 0 ){
661 ERROR_message("-rbox: bad 1st color name '%s'",argv[iarg]) ; iarg++ ; continue ;
662 }
663 qq = find_color_name( argv[++iarg] , &r2,&g2,&b2 ) ;
664 if( qq < 0 ){
665 ERROR_message("-rbox: bad 2nd color name '%s'",argv[iarg]) ; iarg++ ; continue ;
666 }
667 plot_ts_add_rbox( 0 , x1,y1 , x2,y2,y3 , r1,g1,b1 , r2,g2,b2 ) ;
668 iarg++ ; continue ;
669 }
670
671 if( strcmp(argv[iarg],"-Rbox") == 0 ){
672 float x1,y1 , x2,y2,y3 , r1,g1,b1 , r2,g2,b2 ; int qq ;
673 x1 = (float)strtod(argv[++iarg],NULL) ;
674 y1 = (float)strtod(argv[++iarg],NULL) ;
675 x2 = (float)strtod(argv[++iarg],NULL) ;
676 y2 = (float)strtod(argv[++iarg],NULL) ;
677 y3 = (float)strtod(argv[++iarg],NULL) ;
678 qq = find_color_name( argv[++iarg] , &r1,&g1,&b1 ) ;
679 if( qq < 0 ){
680 ERROR_message("-Rbox: bad 1st color name '%s'",argv[iarg]) ; iarg++ ; continue ;
681 }
682 qq = find_color_name( argv[++iarg] , &r2,&g2,&b2 ) ;
683 if( qq < 0 ){
684 ERROR_message("-Rbox: bad 2nd color name '%s'",argv[iarg]) ; iarg++ ; continue ;
685 }
686 plot_ts_add_rbox( 0 , x1,y1 , x2,y2,y3 , r1,g1,b1 , r2,g2,b2 ) ;
687 iarg++ ; continue ;
688 }
689
690 if( strcmp(argv[iarg],"-line") == 0 ){
691 float x1,y1 , x2,y2 , r1,g1,b1 ; int qq ;
692 x1 = (float)strtod(argv[++iarg],NULL) ;
693 y1 = (float)strtod(argv[++iarg],NULL) ;
694 x2 = (float)strtod(argv[++iarg],NULL) ;
695 y2 = (float)strtod(argv[++iarg],NULL) ;
696 qq = find_color_name( argv[++iarg] , &r1,&g1,&b1 ) ;
697 if( qq < 0 ){
698 ERROR_message("-line: bad color name '%s'",argv[iarg]) ; iarg++ ; continue ;
699 }
700 qq = (int)strtod(argv[++iarg],NULL) ;
701 plot_ts_add_tlin( 0 , x1,y1 , x2,y2 , r1,g1,b1 , qq ) ;
702 iarg++ ; continue ;
703 }
704
705 if( strcmp(argv[iarg],"-hist") == 0 ){ /* 14 Jul 2014 */
706 plot_ts_dohist(1) ; iarg++ ; continue ;
707 }
708
709 /*----------*/
710
711 if( strcmp(argv[iarg],"-") == 0 ){ /* 23 Aug 2006: null option */
712 iarg++ ; continue ;
713 }
714
715 /*----------*/
716
717 if( strncasecmp(argv[iarg],"-thi",4) == 0 ){ /* 15 Apr 2009: thickness */
718 thik += 0.004f ; if( argv[iarg][1] == 'T' ) thik += 0.004f ;
719 iarg++ ; continue ;
720 }
721
722 /*----------*/
723
724 if( strcmp(argv[iarg],"-norm2") == 0 ){ /* 26 Mar 2008 */
725 do_norm = 2 ; iarg++ ; continue ;
726 }
727 if( strcmp(argv[iarg],"-norm1") == 0 ){
728 do_norm = 1 ; iarg++ ; continue ;
729 }
730 if( strcmp(argv[iarg],"-normx") == 0 ){
731 do_norm = 666 ; iarg++ ; continue ;
732 }
733 if( strcmp(argv[iarg],"-demean") == 0 ){ /* 14 May 2015 */
734 demean++ ; iarg++ ; continue ;
735 }
736
737 /*----------*/
738
739 if( strcasecmp(argv[iarg],"-x") == 0 ){ /* ZSS: April 2007 */
740 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
741 xfile = argv[++iarg]; xl10 = 0 ;
742 iarg++; continue;
743 }
744 if( strcasecmp(argv[iarg],"-xl10") == 0 ){
745 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
746 xfile = argv[++iarg]; xl10 = 1 ;
747 iarg++; continue;
748 }
749
750 if( strcmp(argv[iarg],"-xaxis") == 0 ){ /* 22 Jul 2003 */
751 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
752 sscanf(argv[++iarg],"%f:%f:%d:%d",&xbot,&xtop,&nnax,&mmax) ;
753 #if 0
754 if( xbot >= xtop || nnax < 0 || mmax < 1 )
755 ERROR_exit("String after -xaxis is illegal!\n") ;
756 #else
757 if( xbot == xtop || nnax < 0 || mmax < 1 )
758 ERROR_exit("String after -xaxis is illegal!\n") ;
759 #endif
760
761 plot_ts_xfix( nnax,mmax , xbot,xtop ) ;
762 iarg++ ; continue ;
763 }
764
765 /*----------*/
766
767 if( strcmp(argv[iarg],"-yaxis") == 0 ){ /* 22 Jul 2003 */
768 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
769 sscanf(argv[++iarg],"%f:%f:%d:%d",&ybot,&ytop,&nnay,&mmay) ;
770 if( ybot >= ytop || nnay < 0 || mmay < 1 )
771 ERROR_exit("String after -yaxis is illegal!\n") ;
772
773 plot_ts_yfix( nnay,mmay , ybot,ytop ) ;
774 iarg++ ; continue ;
775 }
776
777 /*----------*/
778
779 if( strcmp(argv[iarg],"-ytran") == 0 ){ /* 16 Jun 2009 */
780 ytran = strdup(argv[++iarg]) ; iarg++ ; continue ;
781 }
782
783 if( strcmp(argv[iarg],"-xtran") == 0 ){ /* 23 Oct 2013 */
784 xtran = strdup(argv[++iarg]) ; iarg++ ; continue ;
785 }
786
787 /*----------*/
788
789 if( strcmp(argv[iarg],"-nopush") == 0 ){ /* 12 Mar 2003 */
790 plot_ts_xypush( 0 , 0 ) ;
791 iarg++ ; continue ;
792 }
793
794 /*----------*/
795
796 if( strcasecmp(argv[iarg],"-ps") == 0 ){
797 out_ps = 1 ; imsave = 0 ;
798 iarg++ ; continue ;
799 }
800
801 /*-- image file output --*/
802
803 if( strcasecmp(argv[iarg],"-jpeg") == 0 || strcasecmp(argv[iarg],"-jpg") == 0 ){
804 out_ps = 0 ; imsave = JPEG_MODE ;
805 iarg++ ; if( iarg >= argc ) ERROR_exit("need argument after '%s'",argv[iarg-1]) ;
806 imfile = (char *)malloc(strlen(argv[iarg])+8) ; strcpy(imfile,argv[iarg]) ;
807 if( !STRING_HAS_SUFFIX(imfile,".jpg") && !STRING_HAS_SUFFIX(imfile,".JPG") )
808 strcat(imfile,".jpg") ;
809 iarg++ ; continue ;
810 }
811
812 /*----------*/
813
814 if( strcasecmp(argv[iarg],"-jpegs") == 0 ||
815 strcasecmp(argv[iarg],"-jpgs" ) == 0 ){
816 int isize; static char sss[256]={""} ;
817 out_ps = 0 ; imsave = JPEG_MODE ;
818 iarg++ ;
819 if( iarg+1 >= argc )
820 ERROR_exit("need 2 arguments after '%s'",argv[iarg-1]) ;
821 isize = (int) strtod(argv[iarg], NULL);
822 sprintf(sss,"AFNI_1DPLOT_IMSIZE=%d", isize);
823 putenv(sss) ;
824 iarg++ ;
825 imfile = (char *)malloc(strlen(argv[iarg])+8) ;
826 strcpy(imfile,argv[iarg]) ;
827 if( !STRING_HAS_SUFFIX(imfile,".jpg") &&
828 !STRING_HAS_SUFFIX(imfile,".JPG") )
829 strcat(imfile,".jpg") ;
830 iarg++ ; continue ;
831 }
832
833 /*----------*/
834
835 if( strcasecmp(argv[iarg],"-png") == 0 ){
836 out_ps = 0 ; imsave = PNG_MODE ;
837 iarg++ ; if( iarg >= argc ) ERROR_exit("need argument after '%s'",argv[iarg-1]) ;
838 imfile = (char *)malloc(strlen(argv[iarg])+8) ; strcpy(imfile,argv[iarg]) ;
839 if( !STRING_HAS_SUFFIX(imfile,".png") && !STRING_HAS_SUFFIX(imfile,".PNG") )
840 strcat(imfile,".png") ;
841 iarg++ ; continue ;
842 }
843
844 /*----------*/
845
846 if( strcasecmp(argv[iarg],"-pngs") == 0 ){
847 int isize; static char sss[256]={""} ;
848 out_ps = 0 ; imsave = PNG_MODE ;
849 iarg++ ;
850 if( iarg+1 >= argc )
851 ERROR_exit("need 2 arguments after '%s'",argv[iarg-1]) ;
852 isize = (int) strtod(argv[iarg], NULL);
853 sprintf(sss,"AFNI_1DPLOT_IMSIZE=%d", isize);
854 putenv(sss) ;
855 iarg++ ;
856 imfile = (char *)malloc(strlen(argv[iarg])+8) ;
857 strcpy(imfile,argv[iarg]) ;
858 if( !STRING_HAS_SUFFIX(imfile,".png") && !STRING_HAS_SUFFIX(imfile,".PNG") )
859 strcat(imfile,".png") ;
860 iarg++ ; continue ;
861 }
862
863 /*----------*/
864
865 if( strcasecmp(argv[iarg],"-pnm") == 0 ){ /* 06 Jan 2016 */
866 out_ps = 0 ; imsave = PNM_MODE ;
867 iarg++ ; if( iarg >= argc ) ERROR_exit("need argument after '%s'",argv[iarg-1]) ;
868 imfile = (char *)malloc(strlen(argv[iarg])+8) ; strcpy(imfile,argv[iarg]) ;
869 if( !STRING_HAS_SUFFIX(imfile,".pnm") && !STRING_HAS_SUFFIX(imfile,".PNM") &&
870 !STRING_HAS_SUFFIX(imfile,".ppm") && !STRING_HAS_SUFFIX(imfile,".PPM") )
871 strcat(imfile,".pnm") ;
872 iarg++ ; continue ;
873 }
874
875 /*----------*/
876
877 if( strcasecmp(argv[iarg],"-pnms") == 0 ){ /* 06 Jan 2016 */
878 int isize; static char sss[256]={""} ;
879 out_ps = 0 ; imsave = PNM_MODE ;
880 iarg++ ;
881 if( iarg+1 >= argc )
882 ERROR_exit("need 2 arguments after '%s'",argv[iarg-1]) ;
883 isize = (int) strtod(argv[iarg], NULL);
884 sprintf(sss,"AFNI_1DPLOT_IMSIZE=%d", isize);
885 putenv(sss) ;
886 iarg++ ;
887 imfile = (char *)malloc(strlen(argv[iarg])+8) ;
888 strcpy(imfile,argv[iarg]) ;
889 if( !STRING_HAS_SUFFIX(imfile,".pnm") && !STRING_HAS_SUFFIX(imfile,".PNM") &&
890 !STRING_HAS_SUFFIX(imfile,".ppm") && !STRING_HAS_SUFFIX(imfile,".PPM") )
891 strcat(imfile,".pnm") ;
892 iarg++ ; continue ;
893 }
894
895 /*----------*/
896
897 if( strcmp(argv[iarg],"-install") == 0 ){
898 install++ ; iarg++ ; continue ;
899 }
900
901 /*----------*/
902
903 if( strcmp(argv[iarg],"-stdin") == 0 ){ /* 01 Aug 2001 */
904 use_stdin++ ; iarg++ ; continue ;
905 }
906
907 /*----------*/
908
909 if( strcmp(argv[iarg],"-ynames") == 0 ){
910 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
911 iarg++ ;
912 while( iarg < argc && argv[iarg][0] != '-' ){
913 ynar[nyar++] = argv[iarg++] ;
914 }
915 /* 23 Aug 2006: skip next arg if it is "-" */
916 if( iarg < argc && strcmp(argv[iarg],"-") == 0 ) iarg++ ;
917 continue ;
918 }
919
920 /*----------*/
921
922 if( strcmp(argv[iarg],"-xmulti") == 0 || strcmp(argv[iarg],"-multix") == 0 ){ /* 21 Oct 2013 */
923 MRI_IMAGE *qim ; float *qar ; int qq ;
924 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
925 while( ++iarg < argc && argv[iarg][0] != '-' ){
926 qim = mri_read_1D( argv[iarg] ) ;
927 if( qim == NULL || qim->nx < 2 )
928 ERROR_exit("can't read -xmulti file '%s'",argv[iarg]) ;
929 qar = MRI_FLOAT_PTR(qim) ;
930 for( qq=0 ; qq < qim->ny ; qq++ )
931 plot_ts_add_sepx( qim->nx , qar + qq*qim->nx ) ;
932 }
933 if( iarg < argc && strcmp(argv[iarg],"-") == 0 ) iarg++ ;
934 continue ;
935 }
936
937 /*----------*/
938
939 if( strcmp(argv[iarg],"-dashed") == 0 || strcmp(argv[iarg],"-dash") == 0 ){
940 int ddd[99] ; int ii , nd=0 ;
941 if( ++iarg < argc && isdigit(argv[iarg][0]) ){
942 char *cpt , *dpt=argv[iarg] ;
943 while(1){
944 ddd[nd] = (int)strtod(dpt,&cpt) ; nd++ ;
945 if( *cpt != '\0' ) dpt = cpt+1 ; else break ;
946 }
947 iarg++ ;
948 } else {
949 nd = 99 ; for( ii=0 ; ii < 99 ; ii++ ) ddd[ii] = 2 ;
950 }
951 plot_ts_setdash(nd,ddd) ; continue ;
952 }
953
954 /*----------*/
955
956 if( strcmp(argv[iarg],"-volreg") == 0 ){
957 int ii ;
958 for( ii=0 ; ii < 6 ; ii++ ) ynar[nyar++] = dfile_nar[ii] ;
959 iarg++ ; continue ;
960 }
961
962 /*----------*/
963
964 if( strcmp(argv[iarg],"-plabel") == 0 ){
965 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
966 title = argv[++iarg] ;
967 iarg++ ; continue ;
968 }
969
970 /*----------*/
971
972 if( strcmp(argv[iarg],"-wintitle") == 0 ){
973 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
974 wintitle = argv[++iarg] ;
975 iarg++ ; continue ;
976 }
977
978 /*----------*/
979
980 if( strcmp(argv[iarg],"-title") == 0 ){ /* normally eaten by XtVaAppInitialize */
981 #if 0
982 WARNING_message( /* unless using -ps! So keep it here, */
983 "Consider using -plabel; -title " /* it don't hurt. */
984 "only works with the -ps / -jpg / -png options" );
985 #endif
986 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
987 title = argv[++iarg] ;
988 iarg++ ; continue ;
989 }
990
991 /*----------*/
992
993 if( strcmp(argv[iarg],"-xlabel") == 0 ){
994 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
995 xlabel = argv[++iarg] ;
996 iarg++ ; continue ;
997 }
998
999 /*----------*/
1000
1001 if( strcmp(argv[iarg],"-ylabel") == 0 ){
1002 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
1003 ylabel = argv[++iarg] ;
1004 iarg++ ; continue ;
1005 }
1006
1007 /*----------*/
1008
1009 if( strcmp(argv[iarg],"-ignore") == 0 ){
1010 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
1011 ignore = strtod( argv[++iarg] , NULL ) ;
1012 if( ignore < 0 ) ERROR_exit("Illegal -ignore value!\n") ;
1013 iarg++ ; continue ;
1014 }
1015
1016 /*----------*/
1017
1018 if( strcmp(argv[iarg],"-use") == 0 || strcmp(argv[iarg],"-num") == 0 ){
1019 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
1020 use = strtod( argv[++iarg] , NULL ) ;
1021 if( use < 2 ) ERROR_exit("Illegal -use value!\n") ;
1022 iarg++ ; continue ;
1023 }
1024
1025 /*----------*/
1026
1027 if( strcmp(argv[iarg],"-dx" ) == 0 ||
1028 strcmp(argv[iarg],"-del") == 0 ||
1029 strcmp(argv[iarg],"-dt" ) == 0 ){
1030
1031 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
1032 dx = strtod( argv[++iarg] , NULL ) ;
1033 if( dx <= 0.0 ) ERROR_exit("Illegal -dx value!\n");
1034 iarg++ ; continue ;
1035 }
1036
1037 /*----------*/
1038
1039 if( strcmp(argv[iarg],"-xzero") == 0 || strcmp(argv[iarg],"-start") == 0 ||
1040 strcmp(argv[iarg],"-tzero") == 0 ){
1041
1042 if( iarg == argc-1 ) ERROR_exit("need argument after option %s",argv[iarg]) ;
1043 xzero = strtod( argv[++iarg] , NULL ) ;
1044 iarg++ ; continue ;
1045 }
1046
1047 /*----------*/
1048
1049 if( strcmp(argv[iarg],"-sep") == 0 ){
1050 sep = 1 ; iarg++ ; continue ;
1051 }
1052 if( strncmp(argv[iarg],"-sepsc" ,6) == 0 ||
1053 strncmp(argv[iarg],"-sep_sc",7) == 0 ){
1054 sepscl = 1 ; iarg++ ; continue ;
1055 }
1056 if( strcmp(argv[iarg],"-one") == 0 ){
1057 sep = 0 ; iarg++ ; continue ;
1058 }
1059
1060 /*----------*/
1061
1062 if( strncmp(argv[iarg],"-boxes",4) == 0 ){
1063 tsbox = boxsiz ; iarg++ ; continue ;
1064 }
1065
1066 /*----------*/
1067
1068 if( strncmp(argv[iarg],"-noline",4) == 0 ){
1069 noline = 1 ; tsbox = boxsiz ; iarg++ ; continue ;
1070 }
1071
1072 if( strncmp(argv[iarg],"-NOLINE",4) == 0 ){
1073 noline = 2 ; tsbox = boxsiz ; iarg++ ; continue ;
1074 }
1075
1076 /*----------*/
1077
1078 #if 0
1079 if( strncmp(argv[iarg],"-D",2) == 0 && strchr(argv[iarg],'=') != NULL ){
1080 (void) AFNI_setenv( argv[iarg]+2 ) ;
1081 iarg++ ; continue ;
1082 }
1083 #endif
1084
1085 /*--- censoring/marking stuff -- for Colm -- 24 Apr 2012 ---*/
1086
1087 if( strcasecmp(argv[iarg],"-censor_RGB" ) == 0 ||
1088 strcasecmp(argv[iarg],"-censor_RBG" ) == 0 ||
1089 strcasecmp(argv[iarg],"-censor_GBR" ) == 0 ||
1090 strcasecmp(argv[iarg],"-censor_GRB" ) == 0 ||
1091 strcasecmp(argv[iarg],"-censor_BRG" ) == 0 ||
1092 strcasecmp(argv[iarg],"-censor_BGR" ) == 0 ||
1093 strcasecmp(argv[iarg],"-censor_clr" ) == 0 ||
1094 strcasecmp(argv[iarg],"-censor_color") == 0 ){
1095 float rf,gf,bf ; char *eee ;
1096 if( ++iarg >= argc ) ERROR_exit("need argument after %s",argv[iarg-1]) ;
1097 rf = gf = bf = -1.0f ; eee = argv[iarg] ;
1098 (void)sscanf( eee , "rgbi:%f/%f/%f" , &rf,&gf,&bf ) ;
1099 if( rf >= 0.0f && rf <= 1.0f &&
1100 gf >= 0.0f && gf <= 1.0f &&
1101 bf >= 0.0f && bf <= 1.0f ){
1102 /* OK -- do nothing more here */
1103 } else if( strcasecmp(eee,"green") == 0 ){
1104 rf = 0.5f; gf = 1.0f; bf = 0.5f;
1105 } else if( strcasecmp(eee,"red") == 0 ){
1106 rf = 1.0f; gf = 0.3f; bf = 0.3f;
1107 } else if( strcasecmp(eee,"gray") == 0 || strcasecmp(eee,"grey") == 0 ){
1108 rf = gf = bf = 0.7654321f ;
1109 } else if( strcasecmp(eee,"blue") == 0 ){
1110 rf = 0.55f; gf = 0.55f; bf = 1.0f;
1111 } else if( strcasecmp(eee,"purple") == 0 || strcasecmp(eee,"violet") == 0 ){
1112 rf = 1.0f; gf = 0.5f; bf = 1.0f;
1113 } else if( strcasecmp(eee,"gold") == 0 || strcasecmp(eee,"yellow") == 0 ){
1114 rf = 1.0f; gf = 0.9f; bf = 0.4f;
1115 } else if( strcasecmp(eee,"pink") == 0 ){
1116 rf = 1.0f; gf = 0.5f; bf = 0.5f;
1117 } else if( *eee == '#' && *(eee+1) != '\0' ){
1118 int le=strlen(eee+1) , val , bas , rr,gg,bb ;
1119 val = (int)strtol( eee+1 , NULL , 16 ) ; /* hexadecimal */
1120 bas = (le <= 3) ? 16 : 256 ;
1121 bb = val % bas ; val = val / bas ; bf = bb / ((float)bas) ;
1122 gg = val % bas ; val = val / bas ; gf = gg / ((float)bas) ;
1123 rr = val % bas ; rf = rr / ((float)bas) ;
1124 } else {
1125 WARNING_message("%s is not a recognizable color -- choosing a random color :-)",eee ) ;
1126 rf = 0.4f * ( 1.0f + (float)drand48() ) ;
1127 gf = 0.4f * ( 1.0f + (float)drand48() ) ;
1128 bf = 0.4f * ( 1.0f + (float)drand48() ) ;
1129 }
1130 rgb_NOW.a = rf ; rgb_NOW.b = gf ; rgb_NOW.c = bf ;
1131 iarg++ ; continue ;
1132 }
1133
1134 /*----------*/
1135
1136 if( strncmp(argv[iarg],"-CENSOR",7) == 0 ||
1137 strncmp(argv[iarg],"-censorTR",9) == 0 ){
1138
1139 NI_str_array *nsar ;
1140 char *src=malloc(1), *cpt, *dpt ;
1141 int ns, r,a,b ; int_triple rab ;
1142
1143 if( iarg == argc-1 ) ERROR_exit("need an argument after option %s",argv[iarg]) ;
1144
1145 *src = '\0' ; /* cat all following options until starts with '-' */
1146 for( iarg++ ;
1147 iarg < argc && argv[iarg][0] != '-'
1148 && !isalpha(argv[iarg][0])
1149 && strstr(argv[iarg],"1D") == NULL ;
1150 iarg++ ){
1151 ns = strlen(argv[iarg]) ; if( ns == 0 ) continue ;
1152 src = realloc(src,strlen(src)+ns+2) ;
1153 strcat(src," ") ; strcat(src,argv[iarg]) ;
1154 }
1155 if( *src == '\0' ){
1156 WARNING_message("Bad argument after -CENSORTR") ; continue ;
1157 }
1158 nsar = NI_decode_string_list( src , "," ) ; /* break into substrings */
1159 for( ns=0 ; ns < nsar->num ; ns++ ){ /* loop over substrings */
1160 cpt = nsar->str[ns] ; dpt = strchr(cpt,':') ; r = 0 ;
1161 if( *cpt == '\0' ) continue ; /* skip an empty string */
1162 if( dpt != NULL ){ /* found 'run:' */
1163 if( *cpt == '*' ){ /* wildcard = all runs */
1164 r = -666 ;
1165 } else {
1166 r = (int)strtol(cpt,NULL,10) ;
1167 if( r <= 0 ){ /* skip out */
1168 WARNING_message("-CENSORTR %s -- run index '%d' is bad! [iarg=%d]",
1169 nsar->str[ns],r,iarg);
1170 continue ;
1171 }
1172 }
1173 cpt = dpt+1 ; /* skip to character after ':' */
1174 if( *cpt == '\0' ){ /* skip out */
1175 WARNING_message("-CENSORTR %s -- no data after run index! [iarg=%d]",
1176 nsar->str[ns],iarg);
1177 continue ;
1178 }
1179 }
1180 a = (int)strtol(cpt,&dpt,10) ; /* get first index number */
1181 if( a < 0 ){ /* skip out */
1182 WARNING_message("-CENSORTR %s -- time index '%d' is bad! [iarg=%d]",
1183 nsar->str[ns],a,iarg);
1184 continue ;
1185 }
1186 if( *dpt == '\0' ){ /* no second number */
1187 b = a ;
1188 } else { /* get second number */
1189 for( dpt++ ; *dpt != '\0' && !isdigit(*dpt) ; dpt++ ) ; /*nada*/
1190 b = (int)strtol(dpt,NULL,10) ;
1191 if( b < a || b < 0 ){ /* skip out */
1192 WARNING_message("-CENSORTR %s -- time indexes '%d' to '%d' is bad! [iarg=%d]",
1193 nsar->str[ns],a,b,iarg);
1194 continue ;
1195 }
1196 }
1197 rgb_CENSOR = (float_triple *)realloc( rgb_CENSOR ,
1198 sizeof(float_triple)*(num_CENSOR+1) );
1199 rgb_CENSOR[num_CENSOR] = rgb_NOW ;
1200 abc_CENSOR = (int_triple *) realloc( abc_CENSOR ,
1201 sizeof(int_triple)*(num_CENSOR+1) );
1202 rab.i = r; rab.j = a; rab.k = b; abc_CENSOR[num_CENSOR++] = rab ;
1203 } /* end of loop over -CENSORTR strings */
1204 NI_delete_str_array(nsar) ; free(src) ;
1205 continue ; /* next option */
1206 }
1207
1208 /*----- -concat filename -----*/
1209
1210 if( strcmp(argv[iarg],"-concat") == 0 ){
1211 MRI_IMAGE *cim ; float *car ; int qq ;
1212 if( ++iarg >= argc ) ERROR_exit("need argument after option %s",argv[iarg-1]) ;
1213 cim = mri_read_1D(argv[iarg]) ;
1214 if( cim == NULL ) ERROR_exit("can't read -concat file '%s'",argv[iarg]) ;
1215 car = MRI_FLOAT_PTR(cim) ;
1216 num_blocks = cim->nx ;
1217 block_list = (int *)malloc(sizeof(int)*num_blocks) ;
1218 for( qq=0 ; qq < num_blocks ; qq++ )
1219 block_list[qq] = (int)(car[qq]+0.5f) ;
1220 mri_free(cim) ; iarg++; continue;
1221 }
1222
1223 /*----- -censor filename -----*/
1224
1225 if( strcmp(argv[iarg], "-censor") == 0 ){
1226 MRI_IMAGE *cim ;
1227 if( ++iarg >= argc ) ERROR_exit("need argument after option %s",argv[iarg-1]) ;
1228 if( censor_array != NULL )
1229 WARNING_message("second -censor option replaces the first one!") ;
1230 cim = mri_read_1D(argv[iarg]) ;
1231 if( cim == NULL ) ERROR_exit("can't read -censor file '%s'",argv[iarg]) ;
1232 censor_array = MRI_FLOAT_PTR(cim) ;
1233 num_censor_array = cim->nx ;
1234 censor_rgbAA = rgb_NOW ;
1235 iarg++; continue;
1236 }
1237
1238 /*--- symplectically stoopid user ---*/
1239
1240 ERROR_message("Unknown option: %s\n",argv[iarg]) ;
1241 suggest_best_prog_option(argv[0], argv[iarg]);
1242 exit(1);
1243
1244 } /*--------- end of scan over command line args ----------*/
1245
1246 if( argc < 2 ){ usage_1dplot(0); exit(0) ; }
1247
1248 if( thik > 0.0f ) plot_ts_setTHIK(thik) ;
1249
1250 if(sepscl && sep == 0) {
1251 WARNING_message("Cannot use -sepscl with -one!") ; sepscl=0 ;
1252 }
1253 if( iarg >= argc && !use_stdin )
1254 ERROR_exit("No time series file on command line!\n") ;
1255
1256 /*-- setup color info --*/
1257
1258 if( !skip_x11 ){
1259 dc = MCW_new_DC( shell , 16 ,
1260 DEFAULT_NCOLOVR , INIT_colovr , INIT_labovr ,
1261 1.0 , install ) ;
1262
1263 if( !AFNI_yesenv("AFNI_1DPLOT_RENDEROLD") ){ /* 30 Apr 2012 */
1264 memplot_to_X11_set_DC(dc) ;
1265 X11_SET_NEW_PLOT ; /* cf. xim.h */
1266 thik += 0.0015f ;
1267 plot_ts_setthik(0.0015f) ;
1268 }
1269 }
1270
1271 if( nyar > 0 ) yname = ynar ;
1272
1273 /*-- 01 Aug 2001: read from stdin instead of a file --*/
1274
1275 #define NLBUF 131072
1276 #define NVMAX 10000
1277 if( use_stdin ){
1278 char *lbuf , *cpt , *dpt ;
1279 int nval ;
1280 float *val , fff ;
1281
1282 if (!wintitle) wintitle = "stdin"; /* ZSS Oct 7 09 */
1283
1284 lbuf = (char * )malloc(sizeof(char )*NLBUF) ;
1285 val = (float *)malloc(sizeof(float)*NVMAX) ;
1286
1287 /** 13 May 2005: modified to read up to NVMAX numbers from stdin,
1288 rather than the fixed size array of length 9 of old **/
1289
1290 do{ /* read lines until 1st char is non-blank and non-# */
1291 cpt = afni_fgets(lbuf,NLBUF,stdin) ;
1292 if( cpt==NULL ) ERROR_exit("Can't read from stdin!\n");
1293 for( ii=0 ; cpt[ii] != '\0' && isspace(cpt[ii]) ; ii++ ) ; /* nada */
1294 } while( cpt[ii] == '\0' || cpt[ii] == '#' ) ;
1295
1296 nval = 0 ; cpt = lbuf ; /* read numbers from lbuf into val */
1297 while(1){
1298 fff = strtod(cpt,&dpt) ; if( dpt == cpt ) break ;
1299 val[nval++] = fff ; if( nval == NVMAX ) break ;
1300 cpt = dpt; if( *cpt == ',' ) cpt++; if( *cpt == '\0' ) break;
1301 }
1302 if( nval < 1 )
1303 ERROR_exit("Can't read numbers from stdin!\n"
1304 " First line: '%-.30s'\n" , lbuf) ;
1305
1306 nx = nval ; ny = 1 ;
1307 far = (float *) malloc(sizeof(float)*nx) ;
1308 memcpy(far,val,sizeof(float)*nx) ;
1309 while(1){ /* read from stdin */
1310 cpt = afni_fgets(lbuf,NLBUF,stdin) ;
1311 if( cpt == NULL ) break ; /* done */
1312 for( ii=0 ; cpt[ii] != '\0' && isspace(cpt[ii]) ; ii++ ) ; /* nada */
1313 if( cpt[ii] == '\0' || cpt[ii] == '#' ) continue ; /* skip */
1314 memset(val,0,sizeof(float)*nx) ;
1315
1316 nval = 0 ; cpt = lbuf ; /* read numbers from lbuf into val */
1317 while(1){
1318 fff = strtod(cpt,&dpt) ; if( dpt == cpt ) break ;
1319 val[nval++] = fff ; if( nval == nx ) break ;
1320 cpt = dpt; if( *cpt == ',' ) cpt++; if( *cpt == '\0' ) break;
1321 }
1322 far = (float *) realloc( far , sizeof(float)*(ny+1)*nx ) ;
1323 memcpy(far+ny*nx,val,sizeof(float)*nx) ; ny++ ;
1324 }
1325 if( ny < 2 && nx < 2 )
1326 ERROR_exit("Can't read at least 2 lines from stdin\n");
1327
1328 flim = mri_new_vol_empty( nx,ny,1 , MRI_float ) ;
1329 mri_fix_data_pointer( far , flim ) ;
1330 if( ny > 1 ){ /* more than one row ==> transpose (the usual case) */
1331 inim = mri_transpose(flim) ; mri_free(flim) ;
1332 } else { /* only 1 row ==> am OK this way [13 May 2005] */
1333 inim = flim ;
1334 }
1335 free((void *)val); free((void *)lbuf);
1336
1337 } else { /*-- old code: read from a file --*/
1338 /*-- 05 Mar 2003: or more than 1 file --*/
1339
1340 if( iarg >= argc )
1341 ERROR_exit("No input files on command line?!\n"); /* bad user?! */
1342
1343
1344 if( iarg == argc-1 ){ /* only 1 input file */
1345
1346 if (!wintitle) wintitle = argv[iarg]; /* ZSS Oct 7 09 */
1347
1348 inim = mri_read_1D( argv[iarg] ) ;
1349 if( inim == NULL )
1350 ERROR_exit("Can't read input file '%s' iarg=%d\n",argv[iarg],iarg) ;
1351
1352 } else { /* multiple inputs [05 Mar 2003] */
1353 MRI_IMARR *imar ; /* read them & glue into 1 image */
1354 int iarg_first=iarg, nysum=0, ii,jj,nx=1 ;
1355 int constant = 1; /* are nx values constant */
1356 float *far,*iar ;
1357
1358 if (!wintitle) {
1359 snprintf(autotitle,64*sizeof(char),"%s ...", argv[iarg] );
1360 wintitle = autotitle;
1361 }
1362
1363 INIT_IMARR(imar) ;
1364 for( ; iarg < argc ; iarg++ ){
1365 inim = mri_read_1D( argv[iarg] ) ;
1366 if( inim == NULL )
1367 ERROR_exit("Can't read input file '%s' iarg=%d\n",argv[iarg],iarg) ;
1368
1369 if( inim->nx == 1 && inim->ny > 1 ){
1370 flim = mri_transpose(inim); mri_free(inim); inim = flim;
1371 }
1372
1373 /* compute nx as the smallest inim->nx, and note consistency */
1374 if( iarg == iarg_first || inim->nx < nx ) nx = inim->nx ;
1375 if( iarg > iarg_first && inim->nx != nx ) constant = 0;
1376
1377 ADDTO_IMARR(imar,inim) ; nysum += inim->ny ;
1378 }
1379
1380 /* if nx varied across images, warn the user 24 May 2011 [rickr] */
1381 if( ! constant )
1382 WARNING_message("plot lengths vary, truncating to %d values", nx);
1383
1384 flim = mri_new( nx,nysum, MRI_float ); far = MRI_FLOAT_PTR(flim);
1385 for( nysum=ii=0 ; ii < imar->num ; ii++ ){
1386 inim = IMARR_SUBIM(imar,ii) ; iar = MRI_FLOAT_PTR(inim) ;
1387 for( jj=0 ; jj < inim->ny ; jj++,nysum++ ){
1388 /* copy only nx floats, not inim->nx 24 May 2011 [rickr] */
1389 memcpy( far + nx*nysum , iar + jj*inim->nx , sizeof(float)*nx ) ;
1390 }
1391 }
1392 DESTROY_IMARR(imar) ; inim = flim ;
1393 }
1394
1395 if( inim->nx == 1 && inim->ny > 1 ){ /* 13 May 2005 */
1396 flim = mri_transpose(inim); mri_free(inim); inim = flim;
1397 }
1398
1399 } /* end of file input */
1400
1401 flim = inim ;
1402 far = MRI_FLOAT_PTR(flim) ;
1403 nx = flim->nx ;
1404 ny = flim->ny ;
1405
1406 if( nx < 2 )
1407 ERROR_exit("1dplot can't plot curves only 1 point long!\n") ;
1408
1409 #if 0 /* testing */
1410 { float qa,qb,qc,qm ; int jj ;
1411 for( jj=0 ; jj < ny ; jj++ ){
1412 qa = qfrac_float( nx , 0.40f , far+jj*nx ) ;
1413 qb = qfrac_float( nx , 0.50f , far+jj*nx ) ;
1414 qc = qfrac_float( nx , 0.60f , far+jj*nx ) ;
1415 qm = qmed_float ( nx , far+jj*nx ) ;
1416 INFO_message("#%d: %.5f %.5f %.5f %.5f",jj,qa,qb,qc,qm) ;
1417 }
1418 }
1419 #endif
1420
1421 /*--- select data to plot ---*/
1422
1423 nts = ny ;
1424 yar = (float **) malloc(sizeof(float *)*nts) ;
1425 for( ii=0 ; ii < ny ; ii++ ) yar[ii] = far + (ii*nx+ignore) ;
1426
1427 nx = nx - ignore ; /* cut off the ignored points */
1428
1429 if( use > 1 && nx > use ) nx = use ; /* 29 Nov 1999 */
1430
1431 /*--- 16 Jun 2009: -ytran transformation? ---*/
1432
1433 if( ytran != NULL && *ytran != '\0' ){
1434 int cc ;
1435 for( ii=0 ; ii < ny ; ii++ ){
1436 cc = PARSER_1dtran( ytran , nx , yar[ii] ) ;
1437 if( cc <= 0 ) ERROR_exit("Can't evaluate -ytran expression '%s'",ytran) ;
1438 }
1439 }
1440
1441 /*--- 26 Mar 2008: normalize time series? ---*/
1442
1443 if( demean ){ /* 14 May 2015 */
1444 for( ii=0 ; ii < ny ; ii++ )
1445 THD_generic_detrend_LSQ(nx,yar[ii],demean,0,NULL,NULL) ;
1446 }
1447
1448 switch( do_norm ){
1449 case 2:
1450 for( ii=0 ; ii < ny ; ii++ ) THD_normalize(nx,yar[ii]) ;
1451 break ;
1452
1453 case 1:
1454 for( ii=0 ; ii < ny ; ii++ ) THD_normL1(nx,yar[ii]) ;
1455 break ;
1456
1457 case 666:
1458 for( ii=0 ; ii < ny ; ii++ ) THD_normmax(nx,yar[ii]) ;
1459 break ;
1460 }
1461
1462 /*--- make x axis ---*/
1463
1464 if( !xfile ){ /* bog standard uniformly spaced x-axis */
1465
1466 xar = (float *) malloc( sizeof(float) * nx ) ;
1467 for( ii=0 ; ii < nx ; ii++ ) xar[ii] = xzero + dx*ii ;
1468
1469 /** 24 Apr 2012: add vbox stuff for censoring **/
1470
1471 if( censor_array != NULL || num_CENSOR > 0 ){
1472 int ic,it ; float_triple clr ;
1473 if( num_blocks == 0 ){
1474 num_blocks = 1; block_list = (int *)malloc(sizeof(int)); block_list[0] = 0;
1475 }
1476 if( censor_array == NULL ){
1477 censor_array = (float *)malloc(sizeof(float)*nx) ;
1478 for( ii=0 ; ii < nx ; ii++ ) censor_array[ii] = 1.0f ;
1479 } else if( num_censor_array < nx ){
1480 WARNING_message("-censor array is too short ==> extending it from %d to %d",
1481 num_censor_array , nx ) ;
1482 censor_array = (float *)realloc((void *)censor_array,sizeof(float)*nx) ;
1483 for( ii=num_censor_array ; ii < nx ; ii++ ) censor_array[ii] = 1.0f ;
1484 censor_rgbAA = rgb_NOW ;
1485 }
1486 censor_rgb = (float_triple *)malloc(sizeof(float_triple)*nx) ;
1487 for( ii=0 ; ii < nx ; ii++ ) censor_rgb[ii] = censor_rgbAA ;
1488 if( abc_CENSOR != NULL ){
1489 int rr , aa,bb , bbot,btop , nblk=num_blocks ;
1490 for( ic=0 ; ic < num_CENSOR ; ic++ ){ /* loop over CENSOR commands */
1491 clr = rgb_CENSOR[ic] ;
1492 rr = abc_CENSOR[ic].i ;
1493 aa = abc_CENSOR[ic].j ; if( aa < 0 ) continue ; /* shouldn't happen */
1494 bb = abc_CENSOR[ic].k ; if( bb < aa ) continue ; /* shouldn't happen */
1495 if( rr == -666 ){ /* run = wildcard ==> expand to nblk new triples */
1496 int_triple rab ;
1497 abc_CENSOR = (int_triple *)realloc( abc_CENSOR ,
1498 sizeof(int_triple)*(num_CENSOR+nblk) );
1499 rgb_CENSOR = (float_triple *)realloc( rgb_CENSOR ,
1500 sizeof(float_triple)*(num_CENSOR+nblk) );
1501 for( rr=1 ; rr <= nblk ; rr++ ){
1502 rab.i = rr; rab.j = aa; rab.k = bb; abc_CENSOR[num_CENSOR] = rab;
1503 rgb_CENSOR[num_CENSOR++] = rgb_CENSOR[ic] ;
1504 }
1505 continue ; /* skip to next one */
1506 }
1507 if( rr > 0 ){ /* convert local indexes to global */
1508 if( rr > nblk ){ /* stupid user */
1509 WARNING_message("-CENSORTR %d:%d-%d has run index out of range 1..%d",
1510 rr,aa,bb , nblk ) ;
1511 aa = -66666666 ;
1512 } else {
1513 bbot = block_list[rr-1] ; /* start index of block #rr */
1514 btop = (rr < nblk) ? block_list[rr]-1 : nx-1 ; /* last index */
1515 if( aa+bbot > btop ){ /* WTF? */
1516 WARNING_message(
1517 "-CENSORTR %d:%d-%d has start index past end of run (%d) - IGNORING",
1518 rr,aa,bb,btop-bbot ) ; aa = -66666666 ;
1519 } else if( bb+bbot > btop ){ /* oopsie */
1520 WARNING_message(
1521 "-CENSORTR %d:%d-%d has stop index past end of run (%d) - STOPPING THERE",
1522 rr,aa,bb,btop-bbot ) ;
1523 }
1524 aa += bbot ; bb += bbot ; if( bb > btop ) bb = btop ;
1525 }
1526 } else { /* global indexes: check for stupidities */
1527 if( aa >= nx ){
1528 WARNING_message(
1529 "-CENSORTR %d..%d has start index past end of data (%d) - IGNORING",
1530 rr,aa,bb,nx-1 ) ; aa = -66666666 ;
1531 } else if( bb > nx ){
1532 WARNING_message(
1533 "-CENSORTR %d..%d has stop index past end of data (%d) - STOPPING THERE",
1534 rr,aa,bb,nx-1 ) ; bb = nx-1 ;
1535 }
1536 }
1537 if( aa < 0 || aa >= nx ) continue ; /* nothing to do */
1538 if( bb < aa || bb >= nx ) continue ;
1539 for( it=aa ; it <= bb ; it++ ){
1540 censor_array[it] = 0.0f ; censor_rgb[it] = clr ;
1541 }
1542 } /* end of loop over CENSOR commands */
1543 free((void *)abc_CENSOR) ; abc_CENSOR = NULL ; num_CENSOR = 0 ;
1544 }
1545
1546 /* at this point, convert censor_array to vboxes */
1547
1548 #undef FTEQ
1549 #define FTEQ(p,q) ( (p).a==(q).a && (p).b==(q).b && (p).c==(q).c )
1550
1551 for( ic=0 ; ic < nx ; ){
1552 if( censor_array[ic] > 0.0f ){ ic++ ; continue ; }
1553 clr = censor_rgb[ic] ;
1554 for( it=ic+1 ; it < nx ; it++ ){
1555 if( censor_array[it] > 0.0f ) break ;
1556 if( !FTEQ(clr,censor_rgb[it]) ) break ;
1557 }
1558 plot_ts_add_vbox( -1 , xar[ic],xar[it-1] , clr.a,clr.b,clr.c ) ;
1559 ic = it ;
1560 }
1561 } /** end of censoring => vboxes */
1562
1563 } else { /** -x option was given */
1564
1565 MRI_IMAGE *inimx ;
1566 if( censor_array != NULL || num_CENSOR > 0 )
1567 WARNING_message("-x option used ==> -censor and -CENSORTR are ignored!") ;
1568
1569 inimx = mri_read_1D( xfile ) ; /* read x-axis */
1570 if( inimx == NULL )
1571 ERROR_exit("Can't read x-axis '-x %s'",xfile) ;
1572 if (inimx->nx < flim->nx)
1573 ERROR_exit("Number of rows in '-x %s' fewer than in plot data",xfile) ;
1574 if (inimx->ny != 1)
1575 WARNING_message("Using only first column from '-x %s'",xfile) ;
1576 far = MRI_FLOAT_PTR(inimx);
1577 xar = (float *) malloc( sizeof(float) * nx ) ;
1578 for( ii=0 ; ii < nx ; ii++ ) xar[ii] = far[ii+ignore] ;
1579 mri_free(inimx); inimx=NULL; far = NULL;
1580 if( xl10 )
1581 for( ii=0 ; ii < nx ; ii++ ) xar[ii] = log10(fabs(xar[ii])) ;
1582 }
1583
1584 if( xtran != NULL ){
1585 int ss , ns , *ls ; float **sx ;
1586 STATUS("xtran xar[]") ;
1587 ss = PARSER_1dtran( xtran , nx , xar ) ;
1588 if( ss <= 0 ) ERROR_exit("Can't evaluate -xtran expression '%s'",xtran) ;
1589 STATUS("fetch sepx") ;
1590 plot_ts_fetch_sepx( &ns , &ls , &sx ) ;
1591 STATUS("xtran sepx") ;
1592 for( ss=0 ; ss < ns ; ss++ ) PARSER_1dtran( xtran , ls[ss] , sx[ss] ) ;
1593 }
1594
1595 plot_ts_dobox(tsbox) ; plot_ts_noline(noline) ; /* 23 May 2011 */
1596
1597 /*--- start X11, plot will appear after a timeout ---*/
1598
1599 if( !skip_x11 ){
1600 set_wintitle_memplot(wintitle); /* ZSS Oct. 7 2009 */
1601
1602 (void) XtAppAddTimeOut( app , 123 , startup_timeout_CB , NULL ) ;
1603 XtAppMainLoop(app) ; /* never returns */
1604 }
1605
1606 /*---------------------------------------------------*/
1607 /* 29 Nov 2002: if here, output PostScript to stdout */
1608 /* 06 Dec 2007: or write plot to an image file */
1609
1610 { MEM_plotdata *mp ;
1611 int ymask = (sep) ? TSP_SEPARATE_YBOX : 0 ;
1612 if (sepscl) ymask = ymask | TSP_SEPARATE_YSCALE;
1613
1614 /* mri_draw_opacity(0.666f) ; */
1615
1616 mp = plot_ts_mem( nx,xar , nts,ymask,yar ,
1617 xlabel , ylabel , title , yname ) ;
1618
1619 if( out_ps ) memplot_to_postscript( "-" , mp ) ;
1620 else if( imsave == JPEG_MODE ) memplot_to_jpg( imfile , mp ) ;
1621 else if( imsave == PNG_MODE ) memplot_to_png( imfile , mp ) ;
1622 else if( imsave == PNM_MODE ) memplot_to_pnm( imfile , mp ) ; /* 06 Jan 2016 */
1623 else ERROR_message("You shouldn't see this message!") ;
1624 }
1625
1626 exit(0) ;
1627 }
1628
1629 /*-----------------------------------------------------------------*/
1630 /* This function is called when the plot window (below) dies. */
1631 /*-----------------------------------------------------------------*/
1632
killfunc(void * fred)1633 void killfunc(void *fred){ exit(0) ; }
1634
1635 /*-----------------------------------------------------------------*/
1636 /* Actually plot the data, after the timeout to let X11 start. */
1637 /*-----------------------------------------------------------------*/
1638
startup_timeout_CB(XtPointer client_data,XtIntervalId * id)1639 void startup_timeout_CB( XtPointer client_data , XtIntervalId *id )
1640 {
1641 int ng , ngx;
1642
1643 /* make graph */
1644
1645 memplot_topshell_setsaver( ".jpg" , memplot_to_jpg ) ; /* 05 Dec 2007 */
1646 memplot_topshell_setsaver( ".png" , memplot_to_png ) ;
1647 memplot_topshell_setsaver( ".pnm" , memplot_to_pnm ) ; /* 06 Jan 2016 */
1648
1649 ng = (sep) ? (-nts) : (nts) ;
1650 ngx = (sepscl) ? (-nx) : (nx) ;
1651 plot_ts_lab( dc->display , ngx , xar , ng , yar ,
1652 xlabel , ylabel , title , yname , killfunc ) ;
1653
1654 return ;
1655 }
1656