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