Go to the previous, next section.
This is the reference manual to SM's commands
@syntax ABORT.
Syntax: ABORT
ABORT closes the current device without producing any hardcopy. If you are writing an output file it will be removed. You are left talking to the null device, so you probably want to follow ABORT with a DEVICE command.
Syntax: ANGLE expr
For most purposes only the first element of the expr is used, let's
call it D
as it's an angle in degrees.
ANGLE will cause text from LABEL to come out D
degrees
anticlockwise from horizontal. It also causes points to be rotated
counter-clockwise by D
degrees.
If D
is non-zero it will force axis and other labels to be
written with SM's internal fonts, and will overrule the
tendency to put x-axis labels horizontal, and y-axis labels vertical.
For plotting points the full vector of values is used, with the point rotated by the value of expr. If more points are specified than the dimension of expr, the first element will be used for the excess.
The current value of ANGLE
is (almost) always available as the variable
$angle
(it is one of the special variables that are affected by the
DEFINE variable |
command).
@syntax APROPOS.
Syntax: APROPOS pattern
Apropos lists all macros whose name or introductory comments match
the given pattern. Probably the most common use for the command is
simply to look for a word -- e.g. APROPOS histogram
.
If your system supports it, APROPOS will also search the help files
for the given pattern (in this case matches may not extend over more
than one line). If VERBOSE
is zero only the line containing the
match is printed; if VERBOSE
is one or more then a couple of
lines on each side of the match are printed too. If the pattern
matches more than once each match will be printed, merged together if
appropriate and separated by line of dashes otherwise. If you use `q'
to stop looking at the help files APROPOS will immediately proceed to
search the macros.
The pattern is a slightly restricted version of a normal Unix regular expression, specifically:
.
[...]
[ ]
.
If the first character is a ^ it means use anything except the range specified (in any other position ^ isn't special)
A range may be specified with a - (e.g. [0-9]), and if a ]
is to be part of the range, it must appear first (or after
the leading ^, if specified). A - may appear as
the special range ---
.
^
^
with an ESQ-q if you use it as your history
character -- look in the index under history
to learn how
to change it.
$
\t
\n
\.
*
?
By default searches are case sensitive, but you can make searching
ignore case by defining the variable case_fold_search (you can do
this by putting a line case_fold_search 1
in your `.sm'
file if you so desire).
The name and the comments are searched separately, so you could list all macros beginning with a, b, c, d, e, or z by saying
APROPOS ^[a-ez](which works because all comments start with a
#
),
or
APROPOS "^#[^#]"to list all macros that start with a single
#
(the quotes are
needed to stop the #
's from being treated as comment characters).
@syntax ASPECT.
Syntax: ASPECT A
Set the aspect ratio (Y/X) to be A; This is used in drawing characters and points and is reset when a new DEVICE command is issued.
The current values of the x- and y- dimensions of the current device are
(almost) always available as the variables
$nx
and $ny
, and the current aspect ratio is $aspect
(they are some of the special variables that are
affected by the DEFINE variable |
command).
If A is exactly 0, the current aspect ratio is printed -- this is equivalent
to echo $aspect
and is retained as a curiosity.
Usually the aspect ratio is calculated by SM to make characters look right (and to make square points square), but it is sometimes useful to override this, especially when positioning labels on graphs that will be plotted on printers of different aspect ratios.
@syntax Arithmetic.
Arithmetic
Arithmetic is allowed on vectors and scalars in SM, using the following operators, where expr is a expression and vector the name of a vector.
Nonary (?): PI Pi
Unary: -expr Change sign ABS(expr) Absolute value ACOS(expr) Arccosine ASIN(expr) Arcsine ATAN(expr) Arctangent COS(expr) Cosine DIMEN(vector) Dimension of a vector EXP(expr) Exponential INT(expr) Integral part LG(expr) Log_10 LN(expr) Log_e RANDOM(s_expr) Random numbers SIN(expr) Sine SQRT(expr) Square root STRING(expr) Convert to a string SUM(expr) Sum_i expr_i TAN(expr) Tangent VECTOR[expr] Elements of an array ( expr ) Raise precedence
Binary: expr + expr Add expr - expr Subtract expr CONCAT expr Concatenate expr * expr Multiply expr / expr Divide expr ** expr Exponentiate ATAN2(expr_y,expr_x) Atan2
There are also some special operators:
HISTOGRAM(expr:expr) Construct histogram IMAGE(expr,expr) Extract cross section expr1 ? expr2 : expr3 expr2 if expr1 is true, else expr3
ATAN2
is the same as C's function of the same name, and is
equivalent to ATAN(y/x)
. It gives a result in the range
-pi -- pi
dealing correctly with divisions by zero.
RANDOM
generates a vector of s_expr
random numbers in the
range [0,1]. If you don't specify a seed (using SET RANDOM
) one
will be chosen for you based on the current time.
The expression
VECTOR[expr]
results in a vector of the same dimension as
the expr
, with elements taken from VECTOR
(i.e. VECTOR[INT(expr_i)]
). See, for example, the macro interp
.
You can also use WORD([ expr [ , ... ]])
as part of
an expression, where WORD
is a macro taking zero or more arguments.
The arguments are restricted to be either the names of vectors, strings,
or numbers; sorry.
The precedences are what you'd expect, with **
being highest, then
*
and /
, then +
and -
, and then CONCAT
.
The logical operators
all have even lower precedence than CONCAT
, and ?:
has the
lowest priority of all.
If you have defined an image file with the IMAGE command,
IMAGE(expr,expr)
is an expression to extract values from your image.
The two expressions give the x and y values where the image is to be sampled.
For example SET x=0,1,.01 SET z=IMAGE(x,0.5)
will extract a horizontal
cross section through an image.
HISTOGRAM(expr1:expr2)
constructs a histogram from a vector,
where the data is in expr1
, and expr2
(which must be sorted)
gives the centres
of the bins. Values on bin boundaries go into the higher bin up.
See `Logical' for the logical operators, `Strings' for string operators,
and `whatis' for finding out if strings are numbers, words, vectors, or
whatever.
@syntax AXIS.
Syntax: AXIS A1 A2 VSMALL VBIG AX AY ALEN ILABEL ICLOCK AXIS A1 A2 VSMALL VBIG VLAB AX AY ALEN ILABEL ICLOCK AXIS A1 A2 ASMALL ABIG AX AY ALEN ILABEL ICLOCK
Makes an axis labeled from A1
to A2
at location AX
,
AY
, length ALEN
.
The first form (with VSMALL
and VBIG
) specifies the values
where you want small and big ticks explicitly; if you specify the string-valued
vector VLAB it will be used to label the big ticks.
The third form is more
obscure: If ABIG
> 0 use that for spacing of large ticks.
If ASMALL
< 0 make a logarithmic axis, if ASMALL
= 0, do
the default. (See TICKSIZE for more on the meaning of negative
ASMALL
and/or ABIG
).
If ASMALL
> 0 try to use that for the spacing of small ticks.
ILABEL
is 0 for no labels, 1 for labels parallel to axis, 2 for
perpendicular to axis, and 3 for neither labels nor ticks.
ANGLE
determines the angle of the axis.
If ICLOCK
is even the ticks are anticlockwise on the axis,
if odd they are clockwise. You usually want the ticks perpendicular to
the axes, and this is what you get with ICLOCK
0 or 1; if it is
2 or 3 the ticks are vertical, and if 4 or 5 they are horizontal. The
labels are always on the opposite side of the axis from the ticks.
For example, if the limits were 0 1 0 1, then the following commands
would be equivalent to BOX
:
AXIS 0 1 0.05 0.2 3500 3500 27500 1 0 AXIS 0 1 0.05 0.2 3500 31000 27500 0 1 ANGLE 90 AXIS 0 1 0.05 0.2 3500 3500 27500 2 1 AXIS 0 1 0.05 0.2 31000 3500 27500 0 0 ANGLE 0(If expand is 1, that is). If you want to label the bottom axis of some plot only at prime points try
SET b={1 2 3 5 7 11 13 17 192 SET s=0,20 AXIS 0 20 s b 3500 3500 27500 1 0If you have used LIMITS to scale the axes and LOCATION or WINDOW to move them, you could say something like
AXIS $fx1 $fx2 s b $gx1 $gy1 $($gx2-$gx1) 1 0An example of using your own string valued labels would be:
set s=1,7,.5 set b=1,7 set labs={ O B A F G K M 2 LIMITS 1 7 0 0 AXIS 0 10 s b labs 3500 3500 27500 1 0which works as expected. If you don't have a shift key and try using lower case (obafgkm) you'll be surprised as all the letters are not at the same level (as they don't all have the same height). The easiest way to deal with this is to make them all the same height:
set labs={ o b a f g k m 2 + '\\strut'(a strut is a TeXism that has the height and depth of a parenthesis; I'm afraid that you do have to escape the \ in the string). If that leaves too much space try:
set labs='\\move 100' + { o b a f g k m 2 + '\\strut'I think that you get the point.
Rather than use AXIS to draw all of your axes, it may be easier to use BOX with some 3's to disable its axis-drawing habits. You'll still get a box, but no ticks or labels. For example,@example LIMITS 0 1 0 10 BOX 1 2 0 3 TICKSIZE 0 0 -1 0 BOX 3 3 1 3 will label the y-axis with both linear and logarithmic axes.
This was changed in V2.1: To specify logarithmic axes you should
now specify the logarithms, just as you do to BOX. For example, to
draw a logarithmic axis running from 1 to 1000,
specify A1
as 0 and A2
as 3, rather than 1 and 1000.
See NOTATION if you want to control the use of floating point
or exponential notation.
If you want your exponents to line up, i.e. if you
want a space before single-digit exponents, define the SM variable
line_up_exponents
(you can do this in your `.sm' file).
@syntax BOX.
Syntax: BOX [ INTEGER1 INTEGER2 [ INTEGER3 INTEGER4 ] ]
BOX puts axes around the plot region, labelling the lower and left according
to the values set by LIMITS and TICKSIZE.
If arguments INTEGER1
and INTEGER2
are included (default 1 and 2)
they are used as ILABEL
arguments for the lower and left axes (see AXIS). An ILABEL
of 0 means
to omit axis labels, 1 produces labels parallel to the axis, 2
perpendicular, and 3 omits both labels and tickmarks.
INTEGER3
and
INTEGER4
are
used for the top and right axes.
If you want to change the font used for axis labels, define the
variable default_font
, either interactively (DEFINE
default_font oe
), or by putting a line in your `.sm' file:
default_font oe
. This affects regular as well as axis labels,
and only works if you use TeX_strings
, which we recommend
anyway.
See NOTATION if you want to control the use of floating point or exponential notation.
@syntax CHDIR.
Syntax: CHDIR WORD
Set the current directory to be WORD
, where WORD
is any valid
directory. It might be wise to enclose it in quotes,
e.g. CHDIR "[-.more_data]"
, or use the cd
macro.
The new directory only affects SM,
for example DATA
or SAVE
commands. When you exit
SM, you will be back
where you started. If the directory starts with a `~',
the `~' will be replaced by the name of your home directory. This
is the only
place that `~' is significant; in particular it will not be recognised
by the DATA command.
@footnote #{Due to a VMS RTL bug, this command is not
available on all VMS systems.}
@syntax CONNECT.
Syntax: CONNECT WORD1 WORD2 [ IF (expr) ]
CONNECT draws line segments connecting the points in vectors WORD1
and
WORD2
. If the IF clause is present, only connect those points for which
expr
(see the section on vector arithmetic) is non-zero. Only contiguous
points in the input vectors will be connected, resulting in a number of
line-segments.
In fact, either or both of the WORD
s may be replaced by
`parenthesised expressions', i.e. expressions in parentheses. For example,
CONNECT x (2*y)plots x against 2y.
If WORD1
and WORD2
have different dimensions CONNECT will
ignore the excess points in the longer vector. If you want to plot a
constant value you'll have to explicitly promote it, for example@example
CONNECT x (1+0*x)
which makes a rather boring plot.
To draw a line in a label you can either use CONNECT or DRAW, or use the
TeX-macro \line
to directly insert your line.
@syntax CONTOUR.
Syntax: CONTOUR
Makes a contour plot of an image read by the IMAGE command (@xref{IMAGE}). The contour levels are set using the LEVELS command. Contrary to previous versions of the CONTOUR command, plot coordinates are taken to be those set by the LIMITS, and contours are drawn in the current LTYPE. It is not possible to produce labeled contours.
See also the IMAGE CURSOR command for using cursors to get values from images, MINMAX for finding the minimum and maximum of images, and Arithmetic for extracting cross-sections of images.
@syntax CTYPE.
Syntax: CTYPE WORD CTYPE INTEGER CTYPE = expr
With WORD
, set the line colour to be WORD
, if your
display device supports
coloured lines, where WORD
must be one of default
, white
,
black
, red
, green
, blue
, cyan
, magenta
,
or yellow
. The colours are those composed of three, zero, one, or two
of the primary colours red, green, and blue. When a device is opened
it sets default
to some device specific value (e.g. white for
xwindows, black for sunwindows).
Initially, CTYPE INTEGER
is another way of selecting the same colours
as are available with CTYPE WORD
, where CTYPE 1
is the equivalent of the
first colour listed above, or white (so default
is 0).
However, the CTYPE = expr
command redefines the available colours to be the elements of the array
given by expr. If it is arithmetic, each element of is interpreted as
RED + 256*GREEN + 256^2*BLUE for the given colour, where 0 is off,
and 255 corresponds to full intensity.
If the expr
is string-valued it specifies the names to be
used for the colours that you have just defined. Any connection
between the names and colours is, of course, up to you.
You can get the current value of CTYPE with DEFINE ctype |
.
So another way to get white lines would be to say:
CTYPE = { 0 255 0 2 + 256*({ 0 255 255 2 + 256*{ 0 255 0 }) CTYPE 1while
CTYPE 2would give green lines.
CTYPE ={ black white green 2would make your colour names correspond to reality again. You can use any names you like, you are certainly not restricted to the initial set.
You can reset the colours to their default (i.e. correct) values using the macro
reset_ctype
.
Many devices (e.g. sunview
) require you to specify
a number of colours that is a power of 2, so asking for 70 colours
will use up 128 slots. It is probably a good idea to
use as few colours as possible, as they are scarce resources on most displays.
You should also be aware that the display may use some of `your' slots
for the background, so specifying 63 colours on (e.g.) a sun actually
requires 64 (and asking for 64 will use up 128). If you specify more colours
than are physically available, or more than the device driver thinks
that you deserve, SM will interpolate your values of CTYPE for you.
The default colour is specified
in the device drivers, or in the DC
(Default Colour) graphcap
capability, and is set whenever a device is opened, so don't try to
modify it with a CTYPE = expr
command. You can, however, override
the default colour with a foreground
entry in your `.sm' file;
it should be the name of a colour (as listed above). You may also be able to
specify a background colour (as background
). This is either a colour
name or a set of three integers in the range 0-255 specifying
the red, green, and blue values. We allow you this chance to specify arbitrary
colours because it's your only chance to affect the background, and you can't
use a CTYPE = command to compose your own palette. On some devices
the name of the background colour may be chosen from a wider selection;
for example if you are using Xwindows you may use any name from the
colour database.
@syntax CURSOR.
Syntax: CURSOR CURSOR WORD1 WORD2
Display the crosshair cursor to enable you to get positions (in user coordinates). The current cursor position is typed on the screen every time that you hit a key; some keys are special, specifically you can exit the cursor routine by hitting `e' or `q'. If you exit with `e', CURSOR issues a relocate command to set the current plot position to the cursor position, and puts the command in the history buffer. If you exit with `q', no entry is made in the buffer. Usually successive positions overwrite each other, but if a digit is used to mark a point then the position is followed by a newline, so the next time you hit a key its position will appear on the next line. (You can remember that digits lead to numerous values appearing).
Many graphics devices have things called "GIN terminators". SM usually expects that this be set to `Carriage Return' with no extra characters, EOT is a popular (unacceptable) choice. If you have trouble check your graphics setup screen, then with your SM Guru who can look up in graphcap to see what is expected. If the local Guru were very friendly, he could change your GIN terminator to anything he wanted, even EOT, but he probably isn't.
The other form enables you to define a pair of vectors WORD1
and WORD2
. SM provides you with a cursor, and every time that
you hit a key it prints its position (just as above). If the letter is
`e' or `p' it draws a point of the current type at the current position,
prints the current position, and enters the (x,y) coordinates in the
vectors; if you use `m' to mark a point the coordinates are not written
to the screen, but the point is still added to the vectors. Exit with
`q', or abort with a ^C in which case WORD1
and
WORD2
are unchanged.
Note that if you want to use SPLINE on the vectors produced in this way, you should take care that at least one of the vectors is monotonic and increasing, or use the SORT command.
See also IMAGE CURSOR which returns the value under the cursor as well as the position if an IMAGE (@xref{IMAGE}) has been defined.
For devices with mice, if the buttons do anything, they should generate the characters `e', `p', and `q' (starting at the left). There is nothing special about `p', except that it is not `e' or `q' so it simply prints the current position.
The SunWindows cursor is slightly different. The cursor position is given
by a pointing finger (it's the best we could do), and
SM won't see any characters typed at
the keyboard until you hit a carriage return. Device sunwindows
is
obsolete anyway, you should simply switch to using the sunview
driver.
Its cursor has a bug, in that it only sees every other character
typed at the keyboard. If I knew why I'd fix it.
@syntax DATA.
Syntax: DATA file
Use file file
as the source of data read with the READ command.
The file is assumed to have numerical data in columns separated by spaces,
or tabs. The range of lines specified by LINES is reset. If the file
can't be opened for read, you will be warned. The variable $data_file
is set to file
.
See the READ command to see how to read the data.
You may need to quote the filename, e.g. DATA "/usr/file"
, which
you can do by using the macro da
: da /usr/file
.
Perverse people who wish to use filenames such as `12' or
`3.14' will find that they get syntax errors. If they must
persist DATA "3.14 "
will work.
@syntax DEFINE.
Syntax: DEFINE name value DEFINE name { value_list 2 DEFINE name < value_list > DEFINE name DELETE DEFINE name ( expr ) DEFINE name : DEFINE name | DEFINE name ? [ { prompt 2 ] DEFINE name ? [ < prompt > ] DEFINE name READ INTEGER DEFINE name READ INTEGER INTEGER2 DEFINE name IMAGE LIST DEFINE [ begin end ]
All of these varieties of DEFINE define variable name
to have some
value, but
as variables can be defined in all sorts of ways there are a good
many possibilities.
Name
is a single word starting with a letter, and
containing only letters, digits, or `_', and may be a keyword.W
henever SM comes across
$name
, it is interpreted as a reference to variable name
and
$name
is replaced by its value.
(Note that some variables such as date
are special as they always
contain an up-to-date value, for an example try echo $date
sometime.
These variables are listed under DEFINE name |
.)
You can also evaluate expressions with $(expr)
, for example
echo $(pi/2)
. The value can't be longer than about 80 characters,
except for the value_list
form in which case its length can
be essentially infinite.
If you just want to know if a variable is defined, then $?name
is defined to have the value 1 if name
is defined, and 0 otherwise.
Variables are not usually expanded within double quotes or {2, but if you use
the syntax $!name
the variable will be expanded within double quotes;
$!!name
will be expanded anywhere.
For the variants of DEFINE name value
and DEFINE name value_list
,
value
is either a word or number, or a list.
The difference between using
{2 and <>
to delimit a list is that keywords can appear within {2,
but variables are not usually expanded.
DEFINE name
DELETE, deletes a variable (see
also the macro undef to undefine variables).
DEFINE name ( expr )
defines a variable to have the value of
a (scalar) expression. When possible, it is more efficient to use
vectors to perform calculations on scalars, rather than putting them
into variables. It is also more efficient (and more obscure!) to use
numbered variables (macro arguments) than real named ones.
As a special dispensation, the expression can be an element of a
string-valued vector (elements of arithmetic vectors are allowed too
of course).
DEFINE name :
defines the variable name
from
the environment file. If name
can't be found, and is capitalised,
SM will look for it in the environment (as a logical variable for VMS
users).
DEFINE name |
is used to define a variable
from an internal SM variable such as expand
or angle
.
The variables accessible are angle
, aspect
, ctype
,
date
, exit_status
, expand
,
fx1
, fx2
, fy1
, fy2
,
gx1
, gx2
, gy1
, gy2
,
ltype
, lweight
, nx
, ny
, ptype
,
sdepth
, sheight
, slength
,
uxp
, uyp
, verbose
,
xp
, and yp
. The
current plot limits are fx1
etc., (or gx1
etc. in device
coordinates), the size of the screen (in pixels, or dots, or whatever the
hardware uses) is nx * ny
, the current position (in user
coordinates) is (uxp,uyp)
,
the current position (in plot
coordinates) is (xp,yp)
, exit_status
is the return code from the
last !
command,
sdepth
, sheight
, and slength
are the depth, height, and
length of the last string drawn to the screen,
and the rest should be obvious.
This sort of variable has changed a little with version 2.1.1. The variables
that you can use have not changed, but their usage has
slightly. They are all defined for you when SM starts and each is always
correct, tracking the current value of the corresponding internal variable.
For example, try echo $angle\n angle 45 echo $angle
. If you now
say define angle |
, $angle
will cease to track the internal
value and will remain fixed (the same effect can be achieved with
define angle 45
). When you say define angle delete
it will
once more track the internal value. Your old code will continue to work,
but in many cases it is possible to remove the explicit definition
with |
. This special sort of variable will not be SAVE
d,
and will not show up if you list the currently defined variables.
DEFINE name ?
will prompt you for the value
of name
at the keyboard, using the prompt string if given,
otherwise the name of the variable. The old value of the variable (if
defined) is printed within [], and is taken to be the default if you
simply hit carriage return. As previously discussed, the difference between
{2 and <>
is in the treatment of keywords and variables. If you
don't want to use {2 (probably because of something weird to do with when
variables are expanded), you can always use quotes within <>
.
The versions of the DEFINE command including READ define variables from
the current data file. DEFINE name
READ INTEGER
sets name
to be line INTEGER
of the current data file, while
DEFINE name
READ INTEGER INTEGER2
defines name
to be word INTEGER2
of line INTEGER
.
name
is subject to the usual restrictions. If the line begins with
a #
the first character is simply ignored when defining variables.
DEFINE name
IMAGE defines a variable from a file read with the
IMAGE command. Currently this only works for NX
, NY
,
X0
, X1
,
Y0
, Y1
, or any keyword from a FITS header.
LIST DEFINE lists all currently defined variables, or all those which are
between begin
and end
alphabetically (asciily).
Examples
DEFINE v1 5.993 DEFINE label1 KPNO DEFINE label1 < National Optical Astronomical Observatory > DEFINE v2 ($v1 + 3.4) DEFINE v1 DELETE DEFINE age ? { How old are you? 2 DEFINE macros : WRITE STANDARD "$!macros"(Note that we couldn't have used
<>
to prompt for your age, because then
the ? after you
would be treated as a keyword).
To illustrate the DEFINE name READ
commands, consider a file with
the following lines:
This is a file containing astronomical data Magnitude Intensity Wavelength ErrorThen using the
DEFINE
commands as follows:
DEFINE title READ 1 DEFINE labelx READ 2 3will assign the string
This is a file containing astronomical data
to the variable title
, and the word Wavelength
to the variable
labelx
, so you can say XLABEL $labelx
.
@syntax DELETE.
Syntax: DELETE [ INTEGER1 [ INTEGER2 ] ] DELETE HISTORY [ ! ] DELETE HISTORY [ INTEGER1 [ INTEGER2 ] ] DELETE WORD
Delete commands INTEGER1
to INTEGER2
(inclusive) from the
history buffer. If the INTEGER
s are not present, delete the last
command. DELETE 0 will delete all history commands. If the INTEGER
s
are negative they are interpreted relative to the current command, so
-1
is the last command.
The DELETE HISTORY commands are identical to the DELETE commands, except
they themselves do appear on the history list; they are preserved for
backwards compatibility and because DELETE HISTORY \n can be used to prevent
a command from appearing on the history list (the macro del1
).
If a macro contains a DELETE HISTORY
, or
calls a macro that contains one, or ... the macro will not appear on the
history list.
Traditionally, this meant that if there were two (or more) occurrences
of DELETE HISTORY the
previous command(s) were also be deleted, but in SM version 2.2.1 this
has been changed, and DELETE HISTORY will only delete the last command
typed at the keyboard. If for some nefarious purpose you really do want
to delete older commands too, you can say DELETE HISTORY ! and the command
will work the old way.
DELETE WORD deletes the vector WORD
(see SET WORD
or READ WORD
for how to define vectors), MACRO name DELETE
is used to delete a macro, DEFINE name DELETE
deletes a variable.
@syntax DEVICE.
Syntax: DEVICE WORD [ rest_of_line ] DEVICE INTEGER [ WORD ] [ rest_of_line ] DEVICE META WORD DEVICE META CLOSE
Choose a device to plot to. There are currently 9 devices available,
nodevice
(0), stdgraph
(1), raster
(2), imagen
, sunwindows
, sunview
, xwindows
, x11
,
and upc
(a Unix PC).
The first three are always available, with numbers
as given, while the existence and numbers of the others depends on how
SM was compiled. You never need refer to them by number anyway.
When using raster
you'll probably have to specify another device
name as well, e.g. DEVICE raster laserjet
, or (more likely)
say DEVICE laserjet
and put an DV=raster
in laserjet
's
graphcap entry (see section The Stdgraph Graphics Kernel).
The X-windows and SunView drivers will create a plot window for you, while the
Sunwindows should be run from inside a graphics tool.
Fortunately, stdgraph is capable
of driving almost all graphics terminals in use, and the WORD
argument
specifies which one you want. If you omit INTEGER
, and the device is
otherwise unknown, it is assumed to be stdgraph
. Stdgraph works
by using a file called graphcap to tell it about graphics capabilities
(see section The Stdgraph Graphics Kernel). Anything else on the line is passed
to the device driver.
The pseudo-device META is special, @xref{Meta}. It is used to support metafiles, which allow you to save a plot as you display it, and finally send it to a different device.
Some examples may clarify this a
little. DEVICE nodevice
and DEVICE 0 are equivalent, and specify
the null device, which does nothing. This is the default.
DEVICE 1 tek4010
, DEVICE stdgraph tek4010
, and
DEVICE tek4010
are all equivalent, and specify that the device is to
be stdgraph
, using the graphcap entry for a Tektronix 4010 terminal.
Among the devices supported by stdgraph are tek4010
, tek4012
,
pericom
,
selanar
, (or hirez
),
versaterm
(or macvt
),
vt640
(a vt100 with retrographics ), vt240
in REGIS mode,
hard4012
or hard4010
for a tek4010 that really has no decent
ascii mode, tek4025
, wyse1575
, cit414a
or 414a.
We also support graphcap drivers for Postscript, QMS, and LN03 laser printers,
(device names postscript, qms
and ln03
). Stdgraph can also
cooperate with raster
devices, for instance to plot on a lineprinter.
There are probably other devices not listed here, added to graphcap
since this was written.
Especially for hardcopy devices, you may have to specify which one you want,
e.g. DEVICE postscript latypus
. Because this depends on how your
local graphcap was configured you'll have to see your Guru for guidance;
@xref{Stdgraph}.
When a device is opened, it is set to the current CTYPE, LWEIGHT, and
LTYPE, and the proper aspect ratio is chosen to make text and plotted
points look nice. It also looks for an entry foreground
in your `.sm' file, and uses it as the default colour for the device (this
overrides any default that the device driver may have specified). The
device driver may (or may not) choose to honour a background
entry as well. These colours may be specified either as names (see
CTYPE), or the background colour may be given as a set of three numbers,
which are interpreted as the
red, green, and blue intensities in the range 0 - 255. Some devices may allow
you a wider selection of background names; for example the Xwindows driver
allows any name from the colour database.
If you want to use some foreground colour that CTYPE
doesn't usually
understand you must define it before opening the device. For example, after
defining the macro
add_colour 4 ## add a colour to the standard set. Usage: name r g b CTYPE=<0 255 0 255 0 0 0 255 255 $2> + \ 256*(<0 255 0 0 255 0 255 0 255 $3> + \ 256*<0 255 0 0 0 255 255 255 0 $4>) ctype=<default white black red green blue cyan magenta yellow $1>you could say
add_colour gray 200 200 200
, after which `gray' would
be a perfectly good `foreground' colour.
Use the LIST DEVICE command to see which devices are available, either
in graphcap or as hard-coded drivers. Different ways of plotting to
the same device (e.g. portrait or landscape) are accomodated by using
different drivers (e.g. postport
and postland
for postscript
devices) rather than some magic command to SM.
SM works on a PC running DOS either by using Borland's graphics or windows (@xref{MS-Windows}); this section describes the former. SM was ported to run under DOS by Laurent Bartholdi, who also wrote the BGI and MS-Windows device drivers. He gets all the credit for the PC version of SM, but of course he is not responsible for any remaining bugs (some of which we almost certainly created while merging the PC and regular versions).
The graphics drivers, the `.bgi' files, are assumed to be in a directory
given by the DOS BGIPATH
environment variable; alternatively you
can specify a bgipath
variable in your `.sm' file.
The DEVICE command takes two optional arguments:
DEVICE bgi devtype mode
. The first, devtype
, is the type of
hardware that you are running. If you want the driver to try to figure
this out for itself, use DEVICE bgi detect
(this is the default
if you omit devtype entirely); for a listing of
possibilities say DEVICE bgi ?
. The second argument, mode
,
determines how SM switches between screen and graphics modes. Your options are
none
, swap
(the default), or switch
; experiment to
see which works better for you. At present, a certain amount
of `snow' is left at the top of the graphics screen. This is very dependent
on the details of your graphics card, and we see no general way to prevent
its appearance.
Once you have decided what options you like best, you can set a variable
stdmode
in your `.sm' file (e.g. to detect swap
) to save
yourself some typing.
There is a `hot key', ALT-F1
, that can be used to toggle between text
and graphics mode.
The current return value of the function coreleft
is available as
$coreleft
(which is like any other DEFINE var |
variable).
Graphics Metafiles
As described elsewhere (@xref{Meta}) SM can save graphics commands to a metafile while producing a plot on your screen.
Strictly speaking, there are no postscript devices, merely postscript
drivers in stdgraph (@xref{Stdgraph}). On the other hand, SM is able
to drive postscript printers in a totally transparent way, so a user
can think of SM's postscript capability as discrete drivers. In the
following descriptions the arguments to the device command are referred to
as $1
, $2
, and so on. Aliases are listed in parentheses
after the device name, so post_colour
can also be called
post_color
.
Those
currently supported are:
postscript (POSTSCRIPT)
postport (POSTPORT)
postland (POSTLAND)
post_colour (post_color)
postscript
, but generates a colour postscript plot, and sends
it to a printer called ps_colour0.
blackpostscript
post_colour
, but uses a black background.
postfile (postencap)
postscript
, but generate an encapsulated postscript file in $1.
postlandfile
postland
, but generate an encapsulated postscript file in $1.
post_remote (postscript_remote)
postscript
, but prints to a printer $2
on host $1
.
postland_remote
postland
, but prints to a printer $2
on host $1
.
post_remote (postscript_remote)
postscript
, but prints to a printer $2
on host $1
.
postport_remote
postport
, but prints to a printer $2
on host $1
.
For an example of defining your own postscript device that takes a printer name as an argument, @xref{Stdgraph}.
The Silicon Graphics (and RS-6000) Device
The Silicon Graphics device driver works. If you read this and want more documentation, send mail to us and we'll get to it.
The General Device Driver, using Graphcap
For the stdgraph
(i.e. default) device driver the final word on
the command line (if present) is taken to be the name of a file to recieve
the output that would ordinarily go to the screen, so if you say
device graphon outfileand then create a plot nothing will seem to happen. However, if you close the device and write `outfile' to the terminal (maybe using /passall if you are running VMS) your plot will appear. In addition, any word beginning with a colon will be taken to be part of a graphcap entry (see section The Stdgraph Graphics Kernel), and prepended to the entry in the graphcap file for your chosen device. For example, if you wanted to save your postscript output in a file you could say@example dev postscript ":SY=echo File is $F:" which would replace the
SY
entry that sent the output
to the printer by a new one that merely tells you what the file is called.
If you'd prefer to give it a memorable name, you could say
dev postscript ":SY=echo File is \$F:OF=name:"or
dev postscript :SY@: :OF@: name(it doesn't matter if the entries are all in the same word). The former redefines the output file
OF
to be "name", and makes SY
tell you so. The latter disables both OF
and SY
, so the generated
postscript would ordinarily go to the terminal (just like any other
graphics terminal), but a file `name' is specified, so the output is sent
there instead.
If you find yourself frequently wanting to use a customised stdgraph device, this mechanism can become rather tedious; you'd rather simply invent the device and be done with it. The proper way to do this is to create a local graphcap file (see section The Graphcap File), and add your new device to it. For example, if you wanted to define a postscript device that took the name of the printer as its argument, you'd put an entry
mypostscript|like postscript, but specify the printer as its argument:\ :SY=lpr -r -P$1 $F:TC=postscript:in your file, and merrily proceed with making beautiful plots using
DEVICE mypostscript fred
. If you always want to use your new
device you could call it postscript
and in effect redefine the
old postscript
device (note carefully that I said :TC=postscript:
not :tc=postscript:
; if I hadn't, an infinite loop would have resulted).
The SunView (and Sunwindows) Devices
As the sunwindows
driver is now obsolete, and may well disappear in
some future release, you should use the sunview
driver instead.
If you insist on using the old driver, if
must be run from within a gfxtool.
The SunView window driver supports a subset of the usual SunView command line arguments, specifically:
-WH
-Wi
-Wl label
-Wn
-WP x y
-Wp x y
The standard SunView popup `frame' menu has been modified to
allow you to erase the graphics screen. It is perfectly safe to use
the menu to quit
the graphics window, in this case the next
device sunview
command will create a new one. If SM
thinks that the window is active when you try to kill it it will warn
you; failing to believe it may result in a cascade of complaints to
the console window. There is a bug in the cursor routine (I claim that
it is a SunView bug) that means that SM sees only every other key-stroke.
The Unix-PC Device
On a Unix-PC DEVICE upc
opens a window of 304 by 192 pixels,
which is about 4 by 4 inches. To quote the author
(Peter Teuben, teuben@astro.umd.edu),
YAPP_X
and
YAPP_Y
, but this may not work satisfactorily.
I don't have a Unix PC, so I can't work on this driver.
PC Graphics under MS-Windows
This section needs more work; send mail to rhl@astro.princeton.edu
.
VAX/VMS UIS$ device
the VAXUIS driver is used to display graphics on a VAX Workstation using the VAX UIS$ library routines. The optional X and Y parameters specify the size of the graphics window ( in centimeters ) created on the workstation screen.
If called without the optional X and Y parameters the graphics display window will be the same size as that previously displayed.
If the X and Y parameters are not specified the first time the DEVICE vaxuis command is issued, the graphics display window will occupy 1/2 the height and 1/2 the width of the workstation screen.
For example, to create a 15 cm wide x 10 cm tall display window say:
DEVICE vaxuis 15 10
The X-Windows Devices (X10 and X11) There are two X-Windows drivers, one for X10 and one for X11 and they differ in their treatment of command line arguments. The X11 driver is considerably more sophisticated and will be treated first.
The X11 window driver (device x11
) supports a subset of the standard
command line arguments, specifically:
#geom
-bd n
-bg colour
-display name
-fg colour
-fn fontname
-geometry geom
-help
-iconic
-name name
-preopened display_id:window_id
-synchronise
-title title
geom
is a standard geometry string of the form WxH+-X+-Y
,
and the preopened
option is for a programme calling SM
non-interactively.
All options may be abbreviated, so @example
device x11 -i #-1+1 -g 512x512+100+100
specifies that the graphics window be created as an icon in the top
right hand corner of the screen, and that the real window should be
512*512 and positioned near the top left corner.
If you want to raise your graphics window so that you can see it, you
can either use the window manager, reopen the device (dev x11
),
erase the screen, or use the PAGE
command.
On hardware that doesn't support a backing store (or if you have chosen
to disable a backing store when compiling the X11 driver) the screen will
only be refreshed when it is active or when SM is waiting for input. If
your operating system doesn't support the select()
system call you
may be even worse off, but reopening the device (device x11
) should
still result in the screen being redrawn.
The X10 driver is known as xwindow
, and you can optionally
specify a device to open, and a window ID, on the command line. For
example@example
device xwindows DEVICE unix:0
will open a graphics window on device unix:0
. (You can
optionally include a ID number
after the DEVICE if you are calling
SM from a programme, and have already opened the window).
The X10 driver doesn't bother to remember any hardware characters that
you may have
written on a graph, so that if you refresh the window they won't appear.
If this worries you can, as always, force the software character set
with an expand 1.001
.
@syntax DO.
Syntax: DO variable = start, end [ , incr ] { commands 2
While the value of $variable
runs from start
to end
, the commands
are executed. The optional increment defaults to 1. It is not possible
to change the value of the loop variable inside a loop (or at least it
has no effect on the next iteration). To break out of a loop you have
to break out of the current macro as well with RETURN (see section DO and FOREACH loops, and IF statements).
For example,@example
DO i=1,10,0.5 { WRITE STANDARD $i 2
will write 1 1.5 2 2.5 ... 10
to the terminal. The commands may be
spread over several lines.
@syntax DOT.
Syntax: DOT
Draw a point at the current location (set by RELOCATE, DRAW, etc.) in the style determined by PTYPE. The point's size and rotation are governed by EXPAND and ANGLE.
To insert dots into labels, it may be easier to use the `TeX'
definition \point
or \apoint
which inserts a dot of a
specified PTYPE into a string (see section SM's Fonts).
@syntax DRAW.
Syntax: DRAW #1 #2 DRAW ( #1 #2 )
Draw a line from the current position (set with, for example RELOCATE) to (#1, #2) in user coordinates. If the parentheses are present, use screen coordinates.
@syntax EDIT.
Syntax: EDIT function key_strokes
Bind a function to a set of key_strokes
for the editor.
For example, EDIT refresh ^R
makes the ^R key
refresh the screen. A complete list of functions is given in the
`Changing Key-Bindings' section in the main part of this manual (see
under `bindings' in the index). Each character in the key sequence can
be specified as a character, e.g. `a
' or the single character
`^A
',
as `^c
' representing the single character ^c
as the two
character sequence `^
' followed by `c
', or by `\nnn
'
where nnn
is an octal number (e.g. EDIT refresh \022
).
In order to use multiple key sequences
(e.g. ^A^B^C
) you must first undefine
any sub-sequences, in this case ^A
and ^A^B
,
by making them illegal -- EDIT illegal ^A
.
See READ
for how to define a set of keys from a file, and
KEY
for how to define keys to execute commands.
@syntax Environment Variables.
Environment (`sm') Variables
SM environment variables are defined in `.sm' files, which are searched
for along a path which typically consists of
the current directory, your home directory, and then some system place. You
can specify your own search path by setting the environment (VMS: logical)
variable SMPATH
.
If ~ appears in a path it is intepreted as your home directory unless you
specified -u NAME
when starting SM, in which case it will be interpreted
as NAME'S home directory instead.
Alternatively, you can specify the name of the environment file using the
`-f' flag on the command line.
Neither -f
nor -u
are passed on to raster devices.
Each line of the files is taken to consist of a variable name, and the
rest of the line which is taken to be its value. Any variable may be
accessed using the DEFINE name :
command, which defines name
from the environment file.
Comments run from `#' to the end of the line. If the first character of a line is a `@' or `+' the name is taken to start with the second character. A `@' means that the entry isn't present, and that SM should stop searching the path for it. A `+' means that SM should keep on searching the current `.sm' file, and then the rest of the search path, looking for more entries with the same name. If it finds one, the second value is added to the end of the first (and if the second occurence also had a `+' specified the search continues).
Some entries in the environment file are special to SM, although you are free to use them to your own ends as well. For most of those for which SM is only interested in whether the variable is defined, a value of 0 means that it shouldn't be defined. The variables are:
background
case_fold_search
default_font
device
edit
fan_compress
file_type
filecap
line_up_exponents
fonts
foreground
graphcap
help
history
history_char
history_file
macro
macro2
missing_macro_continue
name
noclobber
overload
printer
prompt
prompt2
remember_history_line
save_file
save_read_ptr
temp_dir
term
TERM
termcap
TeX_strings
traceback
uppercase
x_gutter
y_gutter
termcap
entry, or point it at
`/etc/termcap'. Also under Unix, SM knows how to look up your
name, so you can omit the name
entry. If you try to use a name
with more than one word, SM will use the first so you'll have
to call yourself `my_lord' rather than `my lord' (the `_' will be
replaced by a space).
Some of these are used directly by SM (e.g. help
, fonts
,
but some are merely used by the startup
macro to set the initial
value of SM variables (e.g. TeX_strings
, file_type
).
Other names may be used by the default startup
macro, e.g.
macro2
to specify a private macro directory or
term
to specify the terminal that you are using. See the
discussion of startup
under `useful macros'.
@syntax ERASE.
Syntax: ERASEERASE erases the graphics screen. The macro
era
erases the
screen without appearing on the history buffer. If you want to start a
new output page on a hardcopy device use the PAGE command.
You may be able to erase individual lines with LTYPE ERASE, if you can
you should look at the macro undo
.
@syntax ERRORBAR.
Syntax: ERRORBAR WORD1 WORD2 expr INTEGERERRORBAR is analogous to POINTS; it draws one-sided error bars on all points defined by vectors
WORD1
and WORD2
, where the
length of each errorbar is set by the corresponding value in expr
. INTEGER
is 1 to put the bar along the +x direction, 2 for
+y, 3 for -x, and 4 for -y. Use EXPAND to govern the size of the caps.
In fact, instead of either or both of WORD1
and WORD2
you
can use an expression in parentheses,
for example ERRORBAR (lg(x)) (lg(y)) 120 1
.
See also the macros ec
and err
for backwards compatibility with
Mongo, and error_x
and error_y
to produce (symmetrical)
two-sided errorbars.
There is also a macro logerr
to draw errorbars on logarithmic plots.
@syntax EXPAND.
Syntax: EXPAND exprEXPAND expands all characters and points, its default is 1.0. Note that the EXPAND factor is used in determining the plot window size in the WINDOW command. This means you should declare your EXPAND size to SM (if other than the default) before you use WINDOW. The current value of EXPAND is available as a
DEFINE expand |
.
If EXPAND is set to exactly 1, and ANGLE is exactly 0, then SM will use hardware fonts, when available, in writing labels. This is faster, but if you don't like it say "EXPAND 1.00001", or "ANGLE 0.00001", or use a \r explicitly to select the roman font.
EXPAND can in fact be given a vector of values, which are used for
each point in a POINTS command. This supercedes the use of a fractional
PTYPE (although we still support it as a quaint anachronism). Using
vectors for both ANGLE and EXPAND makes it easy to draw a vector
field, see (for example) the vfield
macro.
If more points are specified than
the dimension of expr, the first element will be used for the excess.
@syntax FFT.
Syntax: FFT n pexpr1 pexpr2 WORD1 WORD
Fourier transform 2 vectors (treated as the real and imaginary parts
of a complex vector), returning the answer in the two vectors WORD1
and
WORD2
. The input vectors may be the names of vectors or expressions in
parentheses. The direction is specified by n
, either +1 for a forward
transform, or -1 for an inverse.
The dimension of the vectors need not be a power of 2, but the transform is more efficient if it is. The worst case is when n is prime, in which case this command performs a slow Fourier transform in O(n^2) time.
@syntax FOREACH.
Syntax: FOREACH variable ( list ) { commands 2 FOREACH variable { list 2 { commands 2
The value of variable
is set to each element of list in turn,
and then the commands are executed. An example would be
var ( alpha 2 gamma ) { WRITE STANDARD $var 2which would write
alpha
, 2
, and then gamma
to the
terminal (see section DO and FOREACH loops, and IF statements).
The form with {2 can be useful if you want the list exactly as you type it, for example
FOREACH f { 0.1 $date 2 { echo $f 2
@syntax FORMAT.
Syntax: FORMAT [ x-format-string y-format-string ]Allow the user to specify the axis tick label formats. The format should be given as a standard C (e.g. %4.1g) or Fortran (e.g. F10.4). This format will be in effect until unset by issuing the FORMAT command with no argument, in which case SM will figure out the best format for you, or until you issue a new FORMAT command with new format strings.
If a format is specified as "0", the format string is left unchanged; if it is given as "1", the default value is reinstated. The command FORMAT 1 1 is thus equivalent to FORMAT.
@syntax GRID.
Syntax: GRID [ INTEGER1 [ INTEGER2 ] ]
Grid draws a grid at either major ( INTEGER1 = 0
) or
minor ( INTEGER1 = 1
) tickmarks within a box.
The default is INTEGER1 = 0
. You can use INTEGER2
to specify
only drawing an x- or y-axis grid: if INTEGER2
is omitted or 0,
draw both x and y; if it's 1 only draw x; if it's 2 only draw y (3 is
equivalent to 0).
@syntax HELP.
Syntax: HELP [ word ]
The HELP command tries to help you with word
. If possible, it
prints the entry from the help
directory specified in your `.sm' file, the definition of word
if it's a macro,
the value of word
if it's a variable, and the HELP string if it
is a vector.
If none of these are defined, HELP confesses defeat.
You might want to use the abbreviation h
which will not appear on
your history list (or you could overload help
itself). Further
discussion of the HELP
command is given in See section The Help Command.
If word
is omitted it is assumed to be HELP
.
See also APROPOS and LIST.
@syntax HISTOGRAM.
Syntax: HISTOGRAM WORD1 WORD2 [ IF (expr) ]
HISTOGRAM connects the points in vectors WORD1
and WORD2
as a histogram.
If the IF clause is present, only use those points for which expr
(see
the section on vector arithmetic) is true (i.e. non-zero).
In fact, either or both of the WORD
s may be replaced by
`parenthesised expressions', i.e. expressions in parentheses. For example,
HISTOGRAM x (2 + y)to plot x against 2 + y. There is a macro
barhist
for drawing bar charts.
See Arithmetic for how to convert vectors of data into histograms, and
SHADE
for how to shade them.
@syntax HISTORY.
Syntax: HISTORY [ - ]
List the current commands stored in the buffer. For details on the
history system, see section Command History.
With the optional minus sign, the history list is printed
backwards which is probably what you want if you are thinking of it as
a set of commands to repeat.
It's possible to overload list
to be a synonym for HISTORY, see
`overloading' in the index.
@syntax IDENTIFICATION.
Syntax: IDENTIFICATION str
IDENTIFICATION puts the current date and time followed by str
outside
the upper right hand corner of the plot region.
(Actually, identification
is a macro, which RELOCATEs to a point
above the right-hand axis, and half way between the top axis and the
top of the page, and then writes a string with a PUTLABEL 4.)
Note that the variable
$data_file
is set to the name of the current data file, and
$date
always expands to the current date and time.
@syntax IF.
Syntax: IF ( expr ) { list 2 IF ( expr ) { list 2 ELSE { list 2If the
expr
is true (non-zero), then the list
of commands
are executed, otherwise the ELSE
clause is executed. For various
complicated reasons, the ELSE
less command must end with a newline
(or as usual a \n) (see section DO and FOREACH loops, and IF statements).
One common use for IF tests is when the expression tests if a variable
has been defined, e.g.@example
IF($?file_name == 0) { DEFINE file_name ? 2
within some macro.
There are also commands using IF to define vectors conditionally (see SET), and to plot parts of vectors (See CONNECT, HISTOGRAM, POINTS).
@syntax IMAGE.
Syntax: IMAGE file IMAGE file xmin xmax ymin ymax IMAGE ( nx , ny ) IMAGE ( nx , ny ) xmin xmax ymin ymax IMAGE CURSOR IMAGE DELETE
Read an image from file
, optionally specifying the range of
coordinates covered by the data values. If you do not specify them
they will be taken to be 0 nx-1 0 ny-1
where
nx and ny are the dimensions of the image. If you specify
( nx, ny )
instead of a filename an empty image of the desired
size will be created (see section Two-Dimensional Graphics).
IMAGE CURSOR is identical to the CURSOR command (which see), except that value of the image under the cursor is returned in addition to the position.
IMAGE DELETE will forget the current image and levels.
The file format is specified using a `filecap' file, similar to
`graphcap',
and the entry to use in this file is given by the variable file_type
(see section Two-Dimensional Graphics).
The file is unformatted, and should start with two integers giving the
dimensions of the data
array, followed by the data values written row by row.
The current entries in `filecap' support files written from C,
or from fortran in one of a variety of ways.
For C programmers, DEFINE file_type C
, the file should be written with
open/write/close.
For Fortran, there are a variety of options depending on operating systems
and the details of how the file was opened. Under Unix, simply DEFINE
file_type unix
. Under VMS you have a choice. You can either create a
variable record type file (recordtype='variable'
in the OPEN
statement) and choose file_type vms_var
,
or set recordtype='fixed'
choose recl
to be the x-dimension
of the array and define file_type to be vms_fixed
. You must set
recordtype
in one of these two ways.
By default, data is taken to be real (float in C), but this can be overridden
in the filecap entry for a file type. There is also an entry for FITS files
(FITS is the `standard' image transport format for astronomical images).
If you want to use a different
file type you'll have to learn about `filecap'
(see section Two-Dimensional Graphics),
or else see your local SM Guru.
So under VMS either your code should look like (file_type = vms_var
)
integer i,j real arr(100,10) c open(2,file=filename,form='unformatted',recordtype='variable') i = 100 j = 10 c now write your data into arr write(2) i,j write(2) arr endor, with file_type =
vms_fixed
,
integer i,j real arr(100,10) c open(2,file=filename,form='unformatted',recl=100,recordtype='fixed') i = 100 j = 10 c write your data into arr here write(2) i,j do 1 j=1,10 write(2) (arr(i,j),i=1,100) 1 continue end
Under Unix, either of these programme fragments would work after omitting the record information from the open statement.
See also ARITHMETIC for how to extract a cross-section into a vector, or set values of an image from a vector, and DEFINE for defining a variable from the image header.
@syntax KEY.
Syntax: KEY KEY key string
Define a key to generate a string. This is most often used simply to
save typing some common command such as edit_hist
. With the
command KEY, you are prompted for the key
to define, and the string.
Because you are not using the history editor when you type the key,
you can simply hit the key that you want defined, type a space, and
then type the string terminated by a carriage return. The other form,
where the whole command appears on one line, is probably more suitable
for use in a macro such as your private startup macro (see under startup2
in the index). If you try entering it at the keyboard any special
characters in key
, such as ESC, will be interpreted by the
history editor so you'll probably have to quote the key
with
^Q or ESC-q. Alternatively you can use ^ and printing
characters , or octal numbers, to represent the escape characters in
the same way as for EDIT (@xref{EDIT}).
If key
is given as pf#
or
PF#
(where #
is 1, 2, 3, or 4) it will be interpreted as
a special function key on your keyboard in a terminal-independent way
(see the description of termcap (see section Termcap -- A Terminal Database) to see how these keys
are defined).
KEY definitions are listed along with
other key bindings by the LIST EDIT command.
If the string
ends in a \N, it will be executed the moment that
the key is struck. (Note that this is \N not \n, which would have
been interpreted as a newline.)
Only 10 keys can be defined, after that you'll start overwriting earlier definitions.
@syntax LABEL.
Syntax: LABEL str
LABEL writes the string str
, which starts one space after LABEL and
continues to the last non-space character, at the current location (set by
RELOCATE, etc). After the label is written the current location is on the
baseline, just to the right of the last character drawn.
You can of course use quotes to include trailing white space.
LABEL str is exactly equivalent to PUTLABEL 9 str.
The string's size and angle are determined by EXPAND and ANGLE. For more information on fonts and such like, See section Drawing Labels and SM's TeX Emulation.
@syntax LEVELS.
Syntax: LEVELS WORD LEVELS expr
Set the levels for the CONTOUR command to be the values of the
vector WORD
or to the values of the expression.
@syntax LIMITS.
Syntax: LIMITS WORD WORD LIMITS WORD Y1 Y2 LIMITS X1 X2 WORD LIMITS X1 X2 Y1 Y2
LIMITS sets the coordinates of the plot region. All coordinates in RELOCATE,
DRAW, etc, are referred to these limits. The various forms specify
explicit limits for the x or y axis (X1 X2
or Y1 Y2
), or default
(specify the name of the vector to be used).
In fact, either or both of the WORD
s may be replaced by
`parenthesised expressions', i.e. expressions in parentheses. For example,
LIMITS 0 5 (ln(y))will scale the y axis according to the logarithm of vector y (but not produce a logarithmic axis - see TICKSIZE for this capability).
The current value of the minimum and maximum values on the x and y axes
can be obtained with a DEFINE | command, e.g. DEFINE fx1 |
.
If the two limits specified for an axis are the same, the limits for that axis will not be changed.
You can specify that the limits on one or both axes have a desired range
using the RANGE command. This command affects the performance of the
LIMITS command. If a non-zero RANGE has been set, LIMITS
will ensure that the upper and lower limits differ by that amount. (e.g.
after RANGE 2 0
, LIMITS 0 1 0 1
is equivalent to
LIMITS -0.5 1.5 0 1
). If you specify a vector, the range is
centred on the median value. If you have specified a range, and then
ask for logarithmic axes with TICKSIZE, you may get complaints that
logarithmic axes are impossible. Simply unset RANGE, and the problem
should go away.@findex weird
@syntax LINES.
Syntax: LINES INTEGER INTEGERUse only lines
INTEGER1
to INTEGER2
from the current data file (specified
with the DATA command). If VERBOSE is greater than 0, the lines actually read
will be reported. LINES 0 0 will use the entire file, which is also
the default following a DATA command.
The variables $_l1
and $_l2
will be set to the first and
@syntax LIST.
Syntax: LIST DEFINE [ begin end ] LIST DEVICE LIST EDIT LIST MACRO [ begin end ] LIST SET
list all the currently defined variables (DEFINE) or macros (MACRO),
optionally only within the range begin - end
. If VERBOSE is 0
macros beginning ## won't be listed.
LIST EDIT will list all the keybindings. If VERBOSE is 0 only the keys that don't generate themselves are listed (i.e. because A is bound to A it isn't listed). If VERBOSE is 1, in addition all non-printing keys are listed, and if VERBOSE is 2 or greater all keys are listed. Both the EDIT and the KEY bindings are listed.
LIST DEVICE will list all the devices known to SM. The possible stdgraph devices (default devices defined in graphcap) are listed with each device on an (indented) line, first the primary name, then a list of aliases in parentheses, then a full name.
LIST SET lists all currently defined vectors. For each vector the name,
the dimension and the HELP
field are given. See SET
for how
to set the latter.
For a list of the history buffer use HISTORY (macro lis
), to list a
macro use HELP (macro h
). It can be useful to overload `list' so
that it doesn't appear on the history list, and so that `list' by
itself corresponds to the command HISTORY (this is done for you if you
use set_overload
or put overload
in your `.sm'
file).
@syntax LOCATION.
Syntax: LOCATION GX1 GX2 GY1 GY2
Set the physical location of the plot. The plot region is the rectangle inside the box drawn by BOX. Vectors and points are truncated at the bounds of the plot region. LOCATION specifies (in device coordinates) where the plot region is located. LOCATION can be used to make an arbitrary size and shape plot, providing that you want it rectangular.
Because all devices have the same coordinate system in SM
(0-32767), this command is considerably more useful than it used to
be. The default LOCATION is 3500 31000 3500 31000. You can get at the
current values of GX1
etc. using the DEFINE | command.
While you are using WINDOW (@xref{WINDOW}), LOCATION commands have no effect. SM remembers them, however, and obeys the most recent one when you are finished with WINDOW.
See the RELOCATE ( x y )
command to draw labels outside the plot region,
and DRAW ( x y )
to draw lines there.
If you want to increase the x-location by 500 (say), you can say:
LOCATION $($gx1 + 500) $gx2 $gy1 $gy2This is sometimes useful to make room for an axis label; if your verbosity is 1 or higher you'll be advised of the appropriate displacement.
@syntax Logical.
Syntax: Logical Operators
The following logical operators are allowed on vectors and scalars in SM, where non-zero means true:
Unary: !expr Logical Complement
Binary: expr == expr Equal to expr != expr Not equal expr < expr Less than expr <= expr Less than or equal expr > expr Greater than expr >= expr Greater than or equal expr && expr Logical and expr || expr Logical or
Only !
, ==
, and !=
are allowed for string valued vectors.
All arithmetic vectors test unequal to all string-valued vectors.
As in C, ==
has a higher precedence than &&
, which in turn has
higher precedence than ||
.
Note that there is also a ternary operator, (expr1) ? expr2 : expr3
which has the value expr2
if expr1
is true, and expr3
if it is false.
See `arithmetic' for the arithmetical operators @xref{Arithmetic}.
You can test to see if a variable is defined by looking at the value
of $?var
(@xref{DEFINE}).
@syntax LTYPE.
Syntax: LTYPE INTEGER LTYPE ERASE
All lines except for those making up axes and characters are drawn
with line type INTEGER
, meaning:
0 solid 1 dot 2 short dash 3 long dash 4 dot - short dash 5 dot - long dash 6 short dash - long dashthe default is a solid line, LTYPE 0. The current value of LTYPE is available as an internal variable (e.g.
DEFINE ltype |
)
LTYPE ERASE and will erase any lines
that are redrawn (e.g. LTYPE 0 BOX LTYPE ERASE BOX will first draw a
box, and then erase it). Not all devices can support erasing
individual lines, if yours doesn't you'll have to ERASE the whole
screen. A convenient way to use LTYPE ERASE is the undo
macro.
(in fact, LTYPEs 10 and 11 are used to implement LTYPE ERASE,
LTYPE 10 to start erasing, LTYPE 11 to notify a device that you've finished
doing so).
@syntax LWEIGHT.
Syntax: LWEIGHT number
Set all lines to have a weight of number
, where the bigger the blacker.
Generally, an lweight of 0 is taken to be the hardware's preferred width.
The current value of LWEIGHT is available as an internal variable
(e.g. DEFINE lweight |
)
@syntax MACRO.
Syntax: MACRO EDIT name MACRO LIST [begin end ] MACRO name [ narg ] { macro 2 MACRO name [ narg ] < macro > MACRO name DELETE MACRO name #1 #2 MACRO READ file MACRO WRITE file MACRO DELETE file MACRO WRITE name [ + ] file
MACRO EDIT name allows you to edit a macro. All the commands available to
the history editor area available (including the ^ history), except
that ^M inserts
a line before the cursor, ^N and ^P get the next and
previous lines respectively, and ^V and ESC-v move forwards and
backwards 5 lines at a time.
To exit use ^X
(or whatever you have bound to exit_editor
).
The macro need not exist, and both its name and number of arguments can be
changed by editing the zeroth line of the macro (^P from the
first line. If this line is corrupted, or deleted, no changes are made to the
macro when you exit. If the number of arguments is negative, the macro will be
deleted when you exit.) You may prefer to use the macro ed
instead of
MACRO EDIT, as it doesn't appear on the history list and, if invoked
without a macro name will edit the macro that you edited last. Incidently,
hm
(`help macro') will list the last macro that you edited with ed
.
The keybindings may be changed with READ EDIT.
LIST MACRO lists all currently defined macros, or all those which are
between begin
and end
alphabetically (asciily). If VERBOSE is
0, macros starting with ## are not listed.
MACRO name [narg] { macro 2
defines name
to be macro
,
where name
is a
single word, and macro
may be anything (most users need not
worry about the form in angle brackets; it is occasionally useful when
writing clever macros). A macro is invoked by
typing its name.
The optional nargs
is the number of arguments the macro expects,
default 0.
If the macro's body is defined to be delete
, the macro is deleted.
MACRO name
DELETE also deletes a macro.
Arguments are referred to as $1, $2, ... $n, up to a maximum of $9.
$0 gives the name of the macro. If the number of arguments is
declared as more than 9, the macro is taken to have a variable number
of arguments, up to the number declared modulo 10. If the number
declared is greater than 99 the last argument will extend to the end
of the line, and may consist of many words. When called, all the arguments
must appear on the same line as the macro itself. This line may, as
usual, be ended with an explicit \n. The macro can determine whether
it has been supplied a given argument by using the $?
construction
(see DEFINE). It is also possible to change the values of arguments
using DEFINE just as usual, and even to DEFINE arguments that you
didn't declare. These are temporary variables, local to the macro, and
will disappear when you exit the macro.
MACRO name #1 #2
defines macro name to consist of lines #1 -- #2
of the history buffer.
If #1 or #2 is negative it is interpreted
relative to the current command, so saying MACRO last2 -1 -2
will define a macro last2
consisting of the last 2 commands issued.
MACRO READ file
reads the macros in file
and defines them.
See RESTORE for how to also restore the history buffer from macro all
.
MACRO DELETE file
has the effect of deleting all macros defined in
file
.
MACRO WRITE file
writes all currently defined macros to file
in
alphabetical order.
If the file exists, and $noclobber
is defined, SM will refuse to
overwrite the file. You can set noclobber
by specifying it in
your `.sm' file.
MACRO WRITE name [ + ] file
writes the macro name
to file
.
If the +
is specified, or the file is the
same as for the previous use of this command, the macro is written to the
bottom of the file, otherwise the file is created.
If the file exists and you aren't simply appending, and $noclobber
is
defined, SM will refuse to overwrite the file.
You can set noclobber
by specifying it in your `.sm' file.
@syntax META.
Syntax: DEVICE META WORD DEVICE META CLOSE META READ WORD
If you open the special device called META it doesn't close the current device, merely intercepts plotting commands and stores them away as well as executing them immediately. This continues until you issue a CLOSE command.
The command META READ reads a metafile and executes it on the current device. So to make hardcopy of a plot you could say something like:
device x11 device meta metafile.dat my_cunning_macro more_brilliance device meta closeafter which (maybe after exiting SM and restarting it), you could say:
device postscript meta read metafile.dat device 0to make a hardcopy.
It is safe to concatenate metafiles together, if the fancy takes you.
Because of the way that SM interrogates devices about their abilities,
while using META all ltypes, lweights, and fonts will be emulated in
software (this guarantees that the device you playback on will be able
to handle the code). If the current device can handle dots (i.e.
PTYPE 0 0
) then META will attempt to use them too, but if
it can't then META will be reduced to faking them. This could
be a serious problem, so good luck. Metafiles do not support colour,
again due to the impossibility of knowing if they will have the same
behaviour as the original device.
@syntax MINMAX.
Syntax: MINMAX min max
Set variables min
and max
to the the maximum and minimum
values of an image
read by the IMAGE command. Only that portion of the image within
the current LIMITS is examined.
This may be useful for setting contour levels,
or doing a halftone plot (which is not currently implemented).
For example, the commands:@example MINMAX min max SET levs = $min,$max,($max-$min)/9 LEVELS levs will choose a set of 10 levels which cover the complete range of the data.
@syntax NOTATION.
Syntax: NOTATION XLO XHI YLO YHI
Set axis label format (exponential or floating). By default, all numbers
between 1e-4 and 1e4 are written as floating point numbers, and all numbers
outside this range are written with an exponent. This corresponds to a
NOTATION -4 4 -4 4
command.
If you set XLO
=XHI
and/or YLO
=YHI
,
all values on that axis will be plotted using exponents.
If you want your exponents to line up, i.e. if you
want a space before single-digit exponents, define the SM variable
line_up_exponents
(you can do this in your `.sm' file).
@syntax OVERLOAD.
Syntax: OVERLOAD keyword INTEGER
Allow "keyword" (in lowercase) to be used as a macro name if
integer is non-zero. For example,@example
overload set 1 overload define 1
macro set { DEFINE 2 macro define { SET 2
would interchange the
meanings of the SET and DEFINE commands. The uppercase forms
of the keywords retain their usual meanings. overload set 0
would reinstate the usual meaning of set. You may be surprised by the
effects of overloading certain keywords. For example, if you overload
help
to mean DELETE HISTORY HELP
, then set help vec
help_string
won't work (you'd have to say set HELP vec ...
).
This command is intended to be used for changing the default action of commands, rather than for a wholesale renaming of keywords! A more practical example than the above would be
overload erase 1 macro erase { del1 ERASE 2to prevent erase commands from appearing on the history list. See the macro
set_overload
for a set of definitions like this. It can
be automatically executed by including an "overload" line on your
`.sm' file.
@syntax PAGE.
Syntax: PAGEPAGE starts a new page for a hardcopy plot (n.b. the device driver for raster plots is unable to suport multiple page plots).
On window systems (X11, SunView) page will raise the window and refresh it if necessary.
@syntax POINTS.
Syntax: POINTS WORD1 WORD2 [ IF
(expr) ]
POINTS makes points of the current style (PTYPE), linetype (LTYPE),
colour (CTYPE), size (EXPAND), and rotation (ANGLE) at the points in
vectors WORD1
and WORD2
.
If the IF clause is present, only use those points for which expr
(see
the section on vector arithmetic) is non-zero.
In fact, either or both of the WORD
s may be replaced by
`parenthesised expressions', i.e. expressions in parentheses. For example,
POINTS x (lg(y))to plot x against the logarithm of y.
In case you ever need to know, the distance from the centre of a point to a corner is 128 screen units when unexpanded, if the ASPECT (@xref{ASPECT}) ratio is unity.
@syntax PRINT.
Syntax: PRINT [+] [ file ] [ 'format' ] { list 2 PRINT [+] [ file ] [ 'format' ] < list >
Print the vectors specified by list
to file
, if file
is
absent, print to the terminal (the output is paged, sort of).
The name of each vector is printed at the head of the
appropriate column. If the output is going to a file, each line of the
header starts with a `#', so the file can be read without using the
LINES command.
With the optional `+' the vectors are appended to the file, otherwise
it is overwritten unless $noclobber
is defined, in which case
SM will refuse to touch the file. You can set noclobber
by
specifying it in your `.sm' file.
The optional format string is of the type accepted by the C function
`printf', and you should see a book on C (or maybe the online system
manual or help command) for more details. Basically, the format string
is copied to the file with format specifiers beginning with %
signs replaced by the numbers that you want printed. The format
specifiers to use are the floating point ones, %e
(exponential), %f
(floating point), and %g
(computer's
choice, good for integers) or %s
for strings. Fields are right
justified by default, you
can insert a -
just after the %
to left justify them. A
%
may be written as %%
, and a tab as \t
. Lines
are not terminated by a newline by default, you have to write
them explicitly as \n
.
For example,
SET x=1,10 SET y=x**2 PRINT file '%c 10f (%10.2e)\n' { x y 2will produce
#........x............y # ..1.000000.(..1.00e+00) ..2.000000.(..4.00e+00) ..3.000000.(..9.00e+00) (etc.)where I have replaced each space by a
.
for clarity. If you say
PRINT '%g ' { x 2you will get
..........x 1.2.3.4.5.6.7.8.9.10.
If you want very long output lines you'll run into a number of SM's internal limits; specifically:
print file 'Date: %2d %2d %4d\n' { dd mm yy 2you can write
set date = sprintf('Date: %2d',dd) + \ sprintf(' %2d',mm) + \ sprintf(' %4d',yy) print file '%s\n' { date 2If you think that this is a hack, I rather agree with you, but it does permit formatted output of up to 400 characters.
@syntax PROMPT.
Syntax: PROMPT new_prompt
The current prompt is replaced by new_prompt
. Any occurrences of
the character `*' are taken as instructions to ring the terminal bell.
When you start SM your prompt is set to the value of the entry
prompt
in your `.sm' file (if you have one).
If you enter a partial command (e.g. macro foo {
or echo ABC\
)
SM switches to a different prompt. By default this is >>
, but if you
define the variable prompt2
that will be used instead. You can
set prompt2
in your `.sm' file.
@syntax PTYPE.
Syntax: PTYPE n s PTYPE WORD PTYPE ( expr ) PTYPE { list 2
PTYPE n s
causes points to be drawn as n
sided polygons of a
style s
, where s
refers to:
0
1
2
3
PTYPE 1 1
makes points appear as dots, PTYPE 4 1
(the default) makes
(diagonal) crosses, and PTYPE 6 3
makes filled hexagons.
Points made up of lines (types 0
, 1
, and 2
)
are drawn using the current LTYPE.
The current value of PTYPE is available as an internal variable (e.g.
DEFINE ptype |
)
PTYPE WORD
or PTYPE ( expr )
use vector WORD
or the
expression expr
as its source of n
and
s
, ( so you may define different point types for each point) except
that the
numbers are contracted together. If the entry has a fractional part, it is
treated as an expansion factor, relative to the current expansion
(no fractional part means default expansion).
For example, an an entry of 103.5 in WORD
is the same as PTYPE 10 3,
EXPAND 0.5, but if you now say EXPAND 2 the net expansion will be unity.
It's much easier to use a vector of
expansions directly to the EXPAND command, but fractional ptypes are
preserved for backwards compatibility.
N.b. due to a bug in X10R4 for the Sun,
PTYPE n 3
does not work for dev xwindows
on a sun.
If more points are specified than
the dimension of expr, the first element will be used for the excess.
If WORD
is a string-valued vector, its elements are used to
label the points of the graph. They are drawn at the current expand
and angle (vector-valued EXPANDs and ANGLEs are ignored), and in the
current default font. For TeX-string users this can be specified
with the variable default_font
, which can either simply be defined,
or set in your `.sm' file.
PTYPE { list 2
defines the symbol to use with the POINTS
command to be some creation of the user.
The list consists of a set of c x y
where c
is a letter,
and x
and y
are integers. If c
is `m' or `r' (move or relocate)
the plot pointer is moved to the point (x,y), if it is `d' (draw) or absent
a line is drawn from the current position to the point (x,y). The coordinates
are measured relative to the current point being plotted, and are
measured in screen coordinates (i.e. 0-32767). Both EXPAND and ANGLE
are applied to the (x,y) values as usual.
As an example the command
PTYPE { m 0 50 50 0 0 -50 -50 0 0 50 2will define the marker to be a diamond. As a more useful example, there is a macro
upper
which defines a variable $upper to draw an upper limit
sign, used as
PTYPE $upper(if ANGLE were 180, they'd be lower limits).
@syntax PUTLABEL.
Syntax: PUTLABEL INTEGER str
PUTLABEL writes a label at the current location with rotation and
size specified by ANGLE and EXPAND (exactly like LABEL). The label
is oriented with respect to the current location according to the
argument INTEGER
which can be 1 - 9 meaning that the label is:
left centre right above 7 8 9 centered 4 5 6 below 1 2 3(cf. a vt100 keyboard) To be a little more precise, `above' means that the string's baseline (the bottom of characters such as `a' that have no descender) is at the level of the current point, while `below' means that the top of the tallest character in the string is level with the current point. If you don't like this neglect of descenders, try
MACRO myputl 102 {label \raise\advance\depth{$22by100{2\n putlabel $1 $22 myputl 7 This is a Label(You can then say
overload putlabel 1 macro putlabel {myputl2
if the mood takes you).
After the label is written the current location is on the
baseline, just to the right of the last character drawn.
If INTEGER
is 0 the string isn't actually drawn,
but the string's dimensions are calculated (and are available as
$swidth
, $sheight
, and $sdepth
), and any
TeX definitions are remembered.
See section Drawing Labels and SM's TeX Emulation, for a description of how to enter a label with funny characters, sub- and super-scripts, and so forth.
If EXPAND is set to exactly 1, and ANGLE is exactly 0, then SM will use hardware fonts, when available, in writing labels. This is faster, but if you don't like it say "EXPAND 1.00001", or use a \r explicitly to select the roman font. Or ask your SM Guru to edit the `graphcap' file to stop your printer from ever using hardware fonts (or read the discussion under LABEL).
@syntax QUIT.
Syntax: QUITQuits the programme entirely. The macro `q' is defined as something like
DELETE HISTORY DEFINE 1 0 # default value DEFINE 1 ? { Are you sure? Enter 1 to really quit 2 IF($1) { QUIT 2so you won't quit accidently, and the QUIT won't appear in the history file. This is an obvious candidate for overloading.
@syntax RANGE.
Syntax: RANGE number_x number_y
If number is non-zero, set the range on the x or y axis to be number, so LIMITS will choose two values that differ by number. Nothing will happen until you issue a LIMITS command.
For instance, if you wanted to ensure that the y axis of a logarithmic plot
spans exactly two decades the commands RANGE 0 2
LIMITS x y
would
choose suitable y limits, with actual values appropriate for the y
vector (in fact symmetrical about the median value).
@syntax READ.
Syntax: READ WORD INTEGER READ { WORD INTEGER WORD INTEGER ... 2 READ { ... WORD range ... 2 READ ROW WORD INTEGER READ 'format' { WORD WORD ... 2 READ EDIT WORD READ OLD WORD WORD META READ WORD WORD
READ WORD INTEGER
reads a column of data from the file specified
by the DATA command, using the lines specified by LINES. Columns may
be separated by white space (blanks or tabs) or by a comma, or by some
combination of the two. It's OK if some of the columns contain text,
providing that you don't try to read them. You can read text columns
into string vectors, as described in the next paragraph.
The data is
read into the vector WORD
, which will be created, from column
INTEGER
. Any field beginning with a *
is taken to be `empty',
and is assigned the value 1.001e36. Any line beginning with a
# is skipped over (and printed if VERBOSE is greater than 1), any line ! is
skipped and always written to the terminal.
Long (logical) lines may be spread over
several (physical) lines by ending the line with a `\'; no line may
exceed a total of 1500 characters.
You can optionally specify a type of vector by adding a suffix onto the integer; `.f' (the default) means floating point, `.s' means string-valued. String valued vectors can be used as input to PTYPE commands, or simply for reading columns from data files that you want to PRINT.
READ { WORD INTEGER WORD INTEGER
... 2 is the same as repeating
READ WORD INTEGER
for each vector, but more efficient as it only has to
read the file once.
READ { x 1 y 5.s z 2.f 2will read columns 1 and 2 into floating point vectors
x
and z
,
and column 5 into string-valued vector y
.
If INTEGER
is invalid ( <= 0, or > 40), the contents of the file
are written
to the standard output. READ ROW is very similar, but the values
are read from row INTEGER
of the file. The same type qualifiers
are allowed as for reading columns.
If your data is in a number of columns (e.g. you have written it out to a file ten values to a line) you can specify a range of columns, for example
READ { x 1-4 y 5 z 6-10 2.You can only use ranges for numerical vectors, and only with the list form of
READ
. Ranges won't work if
there is a short line at the end, but you can still say something like
LINES 0 100 READ { x 1-4 2 READ ROW _x 101 SET x=x CONCAT _xwhich will be almost as efficient if you have defined
$save_read_ptr
.
In order to speed up multiple reads of the same file, SM is able to remember
where is got to in a file; this is only enabled if you define the variable
$save_read_ptr
(which can be done in your `.sm' file). The
remembered position is disabled everytime that you issue a DATA
command,
or try to re-read part of the file. You can get into trouble if you read
part of a file, modify the file, and then read some more, but in normal
usage it should be safe to enable saving the read pointer.
Instead of using simple column-orientated input
it is possible to specify a format similar to those used by C's scanf
functions (Fortran formats are not supported); if you don't know C
then most of what you need to know is that characters in the input
must match those in the input file, except that items to be read are specified
with format strings that start %
. For example, a format
abc%f:%f
expects the input to consist of `abc' then two floating point
numbers separated by a colon.
If the %
is followed by a *
the field is read but isn't assigned to a vector.
You can specify a newline as \n
or a tab as \t
.
As a further example, if your data file has lines like
1:12:30 -45:30:11you could read it with
read '%d:%d:%d %f:%f:%f' { hr min sec deg dmin dsec 2.The type of the vector is deduced from the format string; you can't use
.f
or .s
in the vector list (why would you want
to specify a type twice?).
I said that the %-formats were `similar' to scanf
's; they differ
in the way that they treat field widths and white space. If you don't
specify a width at all SM follows the usual C behaviour of skipping
white space between items; if you do specify a field width no space is
skipped over before the field begins. You can always explicitly skip
spaces with a %*[ ]
format.
The supported format letters are d
, e
, f
, g
,
s
, and [
, their meanings are:
%d
" 1234 "
(i.e. a
field width of 6, %6d
) has the value 1234
not 12340
.
%e
%g
%d
, trailing spaces in a fixed-width field are treated
as spaces not zeros.
%f
%d
, trailing spaces in a fixed-width field are treated
as spaces not zeros.
%s
%[...]
...
into a string valued
vector. You can specify a range as a-z
so %[a-zABC0-9]
would
read a string consisting of any lower case character or digit, or one
of A, B, or C.
If the first character is ^, read any characters except those
specified (e.g. %[^abc] reads anything but
the letters a, b, or c). If a field width is specified characters that
don't match those specified at the end of the field are ignored.
%%
READ EDIT WORD
reads a new set of keybindings from the file WORD
.
The format and syntax are given under History in the introduction.
READ OLD WORD1 WORD2
defines macro WORD1
to be the the
contents of file WORD2
. This is provided for compatibility with
Mongo (see section Tips for Mongo Users) and the read_old
macro. You no longer
need use read_old
to read SM history files, use RESTORE
instead.
If VERBOSE (@xref{VERBOSE}) is greater than 0, the lines actually read will be reported.
META READ WORD
reads a metafile, as produced with the pseudo-device
META, and executes the enclosed commands on the current device.
@syntax RELOCATE.
Syntax: RELOCATE X Y RELOCATE ( X Y )
The first form sets the current position to (X,Y
) in user
coordinates without drawing a line. The second (with parentheses) sets
the position in `screen' coordinates, i.e. 0-32767. The current
position is used by the DRAW, LABEL, and PUTLABEL commands.
There are a couple of pairs of internal variables ($uxp,$uyp)
and ($xp,$yp)
that give the current position of the plot pointer,
either in user or screen coordinates.
@syntax RESTORE.
Syntax: RESTORE [ filename ]
Restore all the current macros, variables, and vectors from file
filename
(if omitted the default is to use the value of save_file
in
your `.sm' file, or failing that `sm.dmp'). In
addition, the current history buffer
is replaced by the macro all
if defined in the RESTOREd file.
The file should have been written by the SAVE command, and RESTORE will treat any other file type as if it were a SM history file and add its commands to the end of the current history list.
If VERBOSE (@xref{VERBOSE}) is greater than 0, some extra information is printed.
@syntax RETURN.
Syntax: RETURN
Return from the current macro, which includes breaking out of DO and FOREACH loops. If you are not executing a macro, simply return to the prompt (this is more or less equivalent to typing ^C).
A RETURN can be useful while playing with fiddling with data
interactively. For example, if you want to playback
a set of commands, but then do other things when the plot has
appeared, you could put a RETURN after the desired part of the
playback buffer. (This doesn't work quite the way that you might
naively think. Playback
works by defining a macro all
from
the history list, and then executing it. The RETURN is actually returning
from this macro, rather than directly from the command list,
but the effect is the same. If RETURN always returned
directly to the prompt, macros such as hcopy
wouldn't work.)
If VERBOSE is 2 or more, the name of the macro being returned from is output.
If the very last command in a macro is RETURN then the RETURN
will take place, not from the desired macro, but from where the macro
was called from. You can work around this by putting
a space after the RETURN, or simply omitting it as it isn't doing anything
anyway. If a RETURN comes last on a history list, this problem will
lead to macros such as hcopy
not working correctly.
@syntax SAVE.
Syntax: SAVE [ filename ]
Save some or all of the current macros, variables, and vectors
in file filename
(if omitted the default is to use the value of save_file
in your
`.sm'
file, or failing that `sm.dmp'). The current history buffer may also
be saved, as the macro all
.
You are prompted for whether you want to save
variables, vectors, and macros (which includes all
, the current
playback buffer). Macros beginning
## are not saved, as they are assumed to be system macros.
Variables and vectors whose names start with a `_' are assumed to be
temporaries, and are not saved either.
The opposite to SAVE is RESTORE (@xref{RESTORE}).
You may want to use the MACRO
DELETE WORD command to undefine macros from e.g. the `utils' macro file.
See, for example, the macro sav
(which can be overloaded).
If VERBOSE (@xref{VERBOSE}) is greater than 0, some extra information is printed.
@syntax SET.
Syntax: SET name = expr SET name = { expr 2 SET name = expr IF ( expr ) SET name = expr1, expr2 [, expr3 ] SET name = expr1 ? expr2 : expr3 SET DIMEN ( name ) = INTEGER SET name = WORD ( [ WORD [ , WORD ... ] ] ) SET name [ expr ] = expr SET IMAGE(expr, expr) = expr SET HELP WORD [ rest ] SET RANDOM s_expr
Conduct various operations on vectors of data.
The simplest, SET name = expr
sets vector name
to be equal to the expression expr
.
If the IF clause is present, name
will only contain
those elements of expr
for which it is true (non-zero).
A special case of an expression is simply a list of values within braces.
For string-valued vectors, the
only allowable expressions are a string-valued vector, the
CONCATenation of two string vectors, or a string in single quotes
(e.g. SET s='Hello, World'
).
With expressions separated by commas the SET command is like a DO loop,
setting
name
to be the values between expr1
and expr2
, at
increments of expr3
(which defaults to 1).
The command with ? and : is similar to the C ternary operator.
If expr1
is true,
take the corresponding value of name
for expr2
, otherwise
use expr3
. This command is worth learning, as it can often be
used to replace a DO loop. This command is in fact simply a special case
of SET x = expr
.
If you have a DO loop that calculates each element of a vector in turn,
something that is possible if inefficient in SM,
you need to define a vector before you use it. You will also need to
declare a vector (or create it by putting it on the left of a SET command)
if you want to use a vector-valued subscript on the left of an expression.
This can be done with
the SET DIMEN(name
) = INTEGER
, which also initialises it to 0.
Thus SET DIMEN(y
) = DIMEN(x
) is
equivalent to SET y
= 0*x
. (Note a change:
you used to be allowed to use expressions as the dimension but no longer.
You can now say SET y
= $(4 + 4)
using the new
expression-valued variables instead). You can
optionally specify a qualifier to the dimension, in just the same way
that you can specify a qualifer to a column in a READ command, so
SET DIMEN(s
) = 10.s
declares a 10-element string-valued vector.
SET name
= WORD
( [ arg
[ , arg ...
] ] )
allows you to use a macro
as a sort of function definition. Within the macro WORD any
assignment to $0
has the effect of assigning to name
, and the
other arguments behave as normal. The arguments arg
can be words
or numbers (but not general expressions) and are separated by commas.
Note that this is a change to
the syntax of this command! Previously only one argument was
permitted, but it could be an expression, and the result was returned
by assigning to $1
in a rather confusing way.
SET word[expr] = expr
sets the elements expr
of vector word
to the values of the vector on the right hand side.
If the left hand side is a string but the right hand side is numerical
it will be converted.
The first expr
is converted to an integer before being used as an index; if it is too small
it's set to 0, if too large to the largest allowable index.
For example,
set i=0,10 set x=100*i set dimen(y) = dimen(x) set y[i-1] = xwill result in a complaint that -1 is an invalid index and set
y = { 100 200 300 ... 2
.
Note that
arrays are subscripted with [ ] not (), and that, as always, indices start
at 0 not at 1. The word
must exist before you can do this to it.
SET IMAGE(ix,iy) is used to set elements of an image to the specified values. The image must exist (@xref{IMAGE}), and the vectors ix and iy are interpreted as integer subscripts into the image (0-indexed, of course). This isn't quite the same as the SET z=IMAGE(x,y) command, as x and y are interpreted with using the (optional) xmin, xmax, ymin, and ymax values.
SET HELP sets the help string for a vector; the rest of the line is read,
and will be returned in response to a HELP WORD
request.
SET RANDOM number sets the seed of the random number generator used by the RANDOM operator; if you don't set it yourself it'll be set to some value based on the time since 1970.
Let's look at some examples.
SET y = $v1 + 5.0 * xThis sets each element of the vector
y
to be the value of the
scalar $v1
plus 5.0 times the corresponding element of the
vector x
(assuming that x
has been defined previously)
SET data_set_1 = lg(x) IF ( lg(x) > 0)This sets the elements of the vector
data_set_1
to be the (common)
logarithm
of the corresponding element of the vector x
, if that logarithm is
> 0. Thus data_set_1
will in general be of smaller size than x
.
SET data = (lg(x) > 0) ? lg(x) : 0In this case,
data_set_1
will be the same size as x
, and any
elements of data_set_1
where the corresponding element of
x
is less than or equal to 1, will be set to 0.
SET vec = 4*{ 1 1.5 2 2.5 3 2will define a vector
vec
, with 5 elements, with the values given
by four times those in the list.
SET vec = 1,12,2an alternative way of defining the same values.
SET i = { 2 3 2 SET x = vec[i]will set the vector
x
to have be 8 10
(i.e. vec[2]
and vec[3]
).
MACRO pow 2 { SET $0 = $1 ** $2 2 SET vec = pow(vec , 3)cube the vector
vec
.
SET vec[0] = 2*piChange your mind about the first element of
vec
.
SET HELP pam Wichita, Kansas, July 7, 1953will set the help string for vector
pam
to be the string
Wichita, Kansas, July 7, 1953
, so when you type
HELP pam
, this string will be printed out.
SET rhl=Robertdefines a string vector with one element.
SET DIMEN(rhl) = 10.sdefines a string vector with ten elements (all blank), while
SET rhl={Robert Horace Lupton2defines a string vector with initialised elements, and
SET rhl[1]=Hughcorrects it.
If you have an image defined (using the IMAGE command), you can extract
a cross-section using the SET name = IMAGE ( expr , expr )
command. The
two expressions give the (x,y) coordinates where you want the image to be
sampled. For example, @example
SET x=0,1,.01 SET z=IMAGE(x,0.5)
will extract a horizontal cross section through an image.
An example of creating an image from scratch would be
image (51,81) 0 1 0 1 define NX image define NY image set ix=0,$NX*$NY-1 set iy=ix set iy=int(iy/$NX) set ix=ix - $NX*iy set x=ix/($NX-1) set y=iy/($NY-1) set image(ix,iy) = sin(x)*sin(y)
See the CURSOR command for defining a pair of vectors using the cursor to mark the points, and SPLINE for how to fit splines to pairs of vectors.
@syntax SHADE.
Syntax: SHADE INTEGER pexpr pexpr SHADE HISTOGRAM INTEGER pexpr pexpr
(`Pexpr' is the name of a vector, or an expression in parentheses,
e.g. SHADE 1000 x (sqrt(y))
).
Shade `inside' a curve defined by the expressions. The shading is
rotated through the current value of ANGLE
, and lines are spaced
INTEGER
apart (screen coordinates, so the full screen is 32768
across). If INTEGER
is 0, the lines will be drawn as close
together as the device allows, simulating an area fill. This is a very
inefficient way to fill areas, made only slightly better by specifying a
large LWEIGHT
on devices that support such things in hardware
(you'll also get slightly jagged edges).
The meaning of `inside' is that as the shading is done, from
left to right taking the value of ANGLE
into account, lines are drawn
from every odd to every even crossing of the curve. The curve is
considered as being closed by joining the first to the last point. If
a shading line just touches the curve the algorithm may be confused,
change INTEGER
slightly, or adding 180 to ANGLE. Sometimes
joining the ends of the curve may
not be what you want, try using CONCAT
to add points on the end
yourself. For example,@findex shade
SET x=0,10 SET y=x**2 LIMITS x y SHADE 1000 x ylooks like a new moon, but
SHADE 1000 (x CONCAT 10) (y concat -1e10)shades beneath the curve, for
ANGLE
0 that is.
You could also try the macros scribble
and shading
in
demos, e.g. type load demos scribble
.
SHADE HISTOGRAM
is similar, but it shades the histogram that would
be drawn by HISTOGRAM
from the same set of points. In this case the
area to be shaded lies between the histogram and the line y=0. If this
offends you, offset the whole graph and lie about the axes.
@syntax SHOW.
Syntax: SHOW
List the values of some of the internal variables, including current location and plot region limits in user and device coordinates, the value of the expansion and angle variables, the line type and weight, and the physical limits. Show is actually a macro, so you could modify it to your own ends, for example listing the current data file too.
@syntax SORT.
Syntax: SORT { vector_list 2
Sort the first vector in the list into increasing numerical order, and
rearrange the others in the same way. The maximum number of vectors that can
be sorted is 10. For example, following the commands@example
SET e = { 2 7 1 8 2 8 1 8 2 2 SET p = { 3 1 4 1 5 9 2 6 5 2
SORT { e p 2
the vectors e
and p
would be 1 1 2 2 2 7 8 8 8
and
4 2 3 5 5 1 1 9 6
. The order within the p
vector is
not defined when the e
values are identical.
Any mixture of string- and arithmetic-valued vectors is allowed.
@syntax SPLINE.
Syntax: SPLINE x1 y1 x2 y2
Fit a natural cubic spline through the points specified by vectors x1
and
y1
.
The dimensions of x1
and y1
must be the same and must exceed 2,
x1
must
be monotonic increasing (use SORT if necessary). When the spline
has been fit, take the points
specified in vector x2
, and fill the (new) vector y2
with the
corresponding values. Linear interpolation is used beyond the ends of
x1
.
@syntax Strings.
Strings
SM supports a number of string operations on vectors and scalars. In the following descriptions expr is a expression and vector the name of a vector.
Unary:
LENGTH(expr)
STRLEN(expr)
STRING(expr)
( expr )
Binary:
expr + expr
expr CONCAT expr
INDEX(expr_1,expr_2)
SPRINTF(expr_1,expr_2)
sprintf(expr,expr) + sprint(expr,expr) ...
to
work around this restriction.
vector[expr]
Ternary:
SUBSTR(expr_1,expr_2,expr_3)
expr1 ? expr2 : expr3
The expression VECTOR[expr]
results in a vector of the same
dimension as the expr
, with elements taken from VECTOR
(i.e. VECTOR[INT(expr_i)]
).
You can also use WORD([ expr [ , ... ]])
as part of
an expression, where WORD
is a macro taking zero or more arguments.
The arguments are restricted to be either the names of vectors or numbers;
sorry.
The precedences are what you'd expect, with +
being higher than
CONCAT
. The logical operators have even lower precedence than
CONCAT
.
@syntax SURFACE.
Syntax: SURFACE type z1 z2 or SURFACE type z1 z2 WORD WORD
Draw a wire-frame surface of the current IMAGE
. If the WORDs
are omitted a line in the surface will be drawn for each row and column
of the image; if the WORDs are present they will be taken to be the
x
- and y
- coordinates of the desired lines, and SM will
interpolate in the image to determine
the corresponding values (see also the hundreds digit of type, below).
The last digit of TYPE is used to determine which surface to draw:
0 no hidden line removal 1 draw top surface 2 draw bottom surface 3 draw both top and bottom surfaces
If type
's tens digit is set, SURFACE
will use the current
limits (as set with LIMITS
) rather than autoscaling them from the
data.
If type
's hundreds digit is set, the two WORD
s are taken to
be the x
- and y
- coordinates corresponding to the rows and
columns of the IMAGE, but no interpolation is done. For example, after
IMAGE (11,11) SET ix=0,10 set xs=0,10,2 do y=0,10 { SET IMAGE(ix,$y) = cos(0.2*ix)*sin(0.4*$y) } VIEWPOINT 30 -10 -1 SURFACE 3 -1.1 1.1 xs xsWill draw a 2-sided surface, drawing 21 lines in each direction on the surface. If, on the other hand, the data were really only known on at irregular set of
x
- and y
-values, you could say something
like
IMAGE (11,11) SET ix=0,10 SET x = { 0 1.3 2.4 3 4 4.5 4.6 6.7 8.2 9.6 10 2 SET y = { 0 0.4 0.9 1.2 2.718 3.14 4.2 5.4 6.667 9.1 10 2 do i=0,10 { SET IMAGE(ix,$i) = cos(0.2*x)*sin(0.4*y[$i]) } CTYPE cyan SURFACE 103 -1.1 1.1 x y CTYPE defaultto draw the same surface.
z1
and z2
are the limits used for the z-axis;
you might want to set them with MINMAX
.
The command VIEWPOINT
specifies the position of the observer
and the type of projection used (@xref{VIEWPOINT}).
There are some useful macros in the file `surfaces'; say
load surfaces
to read them. If VERBOSE is one or more, a helpful
header will be printed when you load the file.
@syntax TERMTYPE.
Syntax: TERMTYPE word [ INTEGER ]
Set the terminal type to be WORD
. This has nothing to do with
graphics, but is to do with the history and macro editors. WORD
is case-sensitive. With two exceptions, the properties of the terminal
will be read from the termcap file (see section Termcap -- A Terminal Database). If WORD
is dumb
SM tries to support editing on a (very) stupid terminal.
If this isn't what you want, for example you are running SM from within
emacs TERMTYPE none
is equivalent to starting SM with the -s
flag and entirely disables input line editing (although commands
are still remembered so commands like playback
and hcopy
will still work). You can turn editing back on by issuing a TERMTYPE
command with a valid terminal name.
For most purposes you don't even need to use
this command, as when SM starts up it reads the value of the
environment variable TERM
(under Unix) or logical variable (under VMS)
it effectively issues a TERMTYPE command with its value as
argument. If you have a term
entry in your `.sm' file
this takes precedence over any TERM
variable. For example, a
term
entry of selanar -21
is equivalent to the command
TERMTYPE selanar -21
.
You also should not have to use the optional INTEGER
argument,
which specifies the number of lines that will appear at a time when
LISTing things, as this information
is usually derived from termcap. If you are using a window system,
then termcap may be wrong and this argument may be useful.
Another exception occurs when you wish to
disable cursor motion to avoid having your graphs scrolling off the
screen. If this concerns you see section Termcap -- A Terminal Database.
@syntax TICKSIZE.
Syntax: TICKSIZE SMALLX BIGX SMALLY BIGY
Determine tick intervals for BOX. SMALLX
refers to the interval
between small tick marks on the x axis, BIGX
refers to the
interval between large ticks and so forth. If BIG
is 0, the axis
routine will supply its own intervals according to the label limits.
If SMALL
< 0, the axis will have logarithmic tick spacing and
BOX assumes that the limits are logarithms, e.g. -2 and 2
refers to limits of 0.01 and 100.
Negative values of SMALL
and BIG
are interpreted as
specifying the tickspacing in the decade 1:10, and are scaled to fit
the decades actually plotted. For instance, if you say
LIMITS 0 1 3 4 TICKSIZE -1 10 -0.1 1 BOXthen the x-axis will have small ticks at 2, 3, ..., 9 and big ticks at 1 and 10, while the y axis will have small ticks at 1100, 1200, 1300, ... and big ticks at 1000, 2000, 3000, ... (You might want to use NOTATION to stop SM using exponential notation for the 10000 label). The most usual TICKSIZE is probably
-1 10
, and this may be written -1 0
for backwards compatibility.
Occasionally you may want to use the same tickspacing in all decades
of your plot. To do this make BIG
negative also in which case the
spacing used for the first decade plotted will be used for all decades.
(Note that this means that if the axis is plotted backwards then the
value from the largest decade will be used):
LIMITS 1.9 2.1 2.1 1.9 TICKSIZE -0.1 -1 -0.1 -1 BOXthis is a good way to make an axis very crowded!
If you really cannot use TICKSIZE to accomplish your needs, you can use AXIS and provide vectors specifying the positions of the big and little ticks, and even the axis labels.
@syntax USER.
Syntax: USER ABORT [ string ] USER integer string
The first form, USER ABORT, is used to generate a syntax error. The
command reported as the offender is string
if provided, otherwise
USER ABORT
.
The other, with an integer, calls a function called `userfn',
passing the integer
and the
string as arguments, both are passed by address as if SM were
written in fortran (string is passed as a NUL terminated C string, though).
This function is provided to allow users without C compilers to make
additions to the main grammar, but whether it is really useful is a
different matter. Currently, if integer
is non-zero then both
integer
and string
are printed unless integer
is
1
, in which case the command
USER 1 r 1.23
is equivalent to SET r=1.23
(only constants
are allowed).
If string
is dump
you'll get a macro stack trace, and if
it's segv
you'll get a segmentation violation (on purpose). If
you really want some new functionality, send us mail.
@syntax VERBOSE.
Syntax: VERBOSE INTEGER
Make SM produce output on what it is doing if INTEGER
is > 0.
Setting VERBOSE to 0 is a way of only listing `important' (non-system) macros,
and generally getting a little peace and quiet. It has the considerable
disadvantage that you can think that you are reading data from files, while
actually something is wrong. For this reason the default value is 1. A value
of 2 or more is basically useful for debugging. If you get some nondescript
syntax error and don't know where it is coming from, VERBOSE of 3 or 4 will
trace your programme, and should help find the problem. The original error
message will tell you which macro SM thinks it is processing
when the error occurred but it will be wrong if the macro
had been fully scanned when the error is detected. In this case it will
report a parent of the current macro. The reason for this behaviour is
related to why RETURN
can return from the wrong place
(see section The Command Interpreter).
If you want to know the current value of VERBOSE you can use the SHOW command (actually a macro), or try@example DEFINE verbose DELETE echo Verbose: $verbose which is (of course) what SHOW does anyway.
If verbose is one or more SM will:
INTEGER
is two or greater, then also :
INTEGER
is three or greater, then also :
if INTEGER
is four or greater, then also :
if INTEGER
is five or greater, then also :
If you set a negative verbosity, then if the parser was compiled with DEBUG defined, you'll get a veritable torrent of debugging information. Use another negative VERBOSE command to turn it off again.
@syntax VERSION.
Syntax: VERSION
Return a string identifying the version of SM in use. If you have any reason to communicate with SM's authors, we'll want to know which version you are running.
Syntax: VIEWPOINT theta phi l
Surfaces are drawn from a direction (THETA,PHI)
, and projected onto
a surface passing through the origin. The projection is from a point
L
away from the nearest corner of the cube containing the image. If
L
is positive a perspective projection is used; if it is 0 the viewpoint
is taken to be infinitely far from the surface, and if it is negative
an axonometric projection is used (i.e. the surface is projected from
infinity onto the x-z plane).
The coordinate system is such that the z-axis is THETA=90
, the
x-axis is (THETA,PHI) = (0,0)
, and the coordinate system is right
handed. Angles are taken to be in degrees, with theta lying in
[-90,90] and phi lies in [-180,180]. The nearest corner of the cube
containing the surface is projected onto the point (0,0).
There are some useful macros in the file `surfaces'; say
load surfaces
to read them. If VERBOSE is one or more, a helpful
header will be printed when you load the file.
@syntax Whatis.
Syntax: Whatis ( expr )
WHATIS(something) has a value depending on what something is:
a number: 0 not a number: set 01 bit (bit 0) a macro: set 02 bit (bit 1) a variable: set 04 bit (bit 2) a vector: set 010 bit (bit 3) a keyword: set 020 bit (bit 4)So if "aa" is the name of a vector, WHATIS(aa) has the binary value 011, or 9, whereas WHATIS(HELP) has the value 021, or 17, and WHATIS(1) is 0. There is a macro in `utils' called
is_set
that tests if WHATIS
sets a particular bit, for example
if(is_set(kkk,3)) { echo kkk is a vector 2tests if bit 3 (vector) is set for "kkk" and prints its findings.
@syntax WINDOW.
Syntax: WINDOW nx ny x y
WINDOW makes the current plot location the window at (x,y), where there are nx windows across and ny windows up and down. WINDOW 1 1 1 1 resets the plot location to the entire plot area. The size and placement of the windows is decided by the value of EXPAND when the WINDOW commands are issued, so be sure that EXPAND has the same value for every window in a set. (It's used to figure out the axis labels, and spacings between boxes). While plotting to a given window you can of course change EXPAND to your heart's content.
If the number of windows in either the x or y direction is
negative no space is left between the boxes in that direction
(try DO i=1,3 { WINDOW 1 -3 1 $i
BOX 2). It's possible to
overload `window' and `box' to only label external axes in blocks of
touching boxes.
If you don't want boxes that touch, but you don't like the gaps left
between boxes by the WINDOW
command, you can now do something
about it legally, without lying to SM. After we caulate the widths
of the `gutters' between the windows that we think that you need, they
are modified by the values of the SM variables x_gutter
and
y_gutter
, so if you think that the spacing is too large in the
x direction you can say
define x_gutter 0.5 window 2 2 1 1 box window 2 2 1 2 boxto make things look better.
The position of the windows pays no attention to the LOCATION used
when the windows are first set up, and
LOCATION commands are ignored until you are
finished with your windows. When you finally say WINDOW 1 1 1 1
the most recent LOCATION is restored.
@syntax WRITE.
Syntax: WRITE STANDARD string WRITE [+] WORD string WRITE HISTORY WORD
WRITE STANDARD writes a string, followed by a newline,
to the standard output. The string is taken to be the rest
of the line up to a carriage return (which may be written explicitly as \n).
The macro echo
is usually used as an abbreviation for this command.
WRITE WORD
is similar, except that the string is written to file
WORD
.
If the filename is the same as the previous WRITE, or if you preface the
filename with a +, the string is
appended, otherwise the file is overwritten.
WRITE HISTORY WORD
, writes macro WORD
onto
the end of the history list.
For MACRO WRITE, see under macros.
@syntax XLABEL.
Syntax: XLABEL str
Write the label str
centered under the x axis made by BOX.
The string is taken to be the rest
of the line up to a carriage return (which may be written explicitly as \n).
If you think that the label is badly positioned you can say things like
XLABEL \raise-500My X-axis Label(providing that you use TeX-style fonts, of course)
If the label is too tall it may overlap with the numerical tickmark labels. If VERBOSE is one or more, you'll be warned about this, and a suggested change to the plot LOCATION will be suggested. This moves the entire plot; it is your responsibility to reset it later if appropriate.
If ANGLE is non-zero, it will be used to determine the direction of the label, otherwise it is parallel to the x axis.
See section Drawing Labels and SM's TeX Emulation, for a description of how to enter a label with funny characters, sub- and super-scripts, and so forth.
If EXPAND is set to exactly 1, and ANGLE is exactly 0, then SM will use hardware fonts, when available, in writing labels. This is faster, but if you don't like it say "EXPAND 1.00001", or start the string with a \0 which does nothing, but forces the software character set.
@syntax YLABEL.
Syntax: YLABEL str
Write the label str
centered to the left of the yaxis made by BOX.
The string is taken to be the rest
of the line up to a carriage return (which may be written explicitly as \n).
If you think that the label is badly positioned you can say things like
YLABEL \raise500My Y-axis Label(providing that you use TeX-style fonts, of course)
If the label is too tall it may overlap with the numerical tickmark labels. If VERBOSE is one or more, you'll be warned about this, and a suggested change to the plot LOCATION will be suggested. This moves the entire plot; it is your responsibility to reset it later if appropriate.
If ANGLE is non-zero, it will be used to determine the direction of the label, otherwise it is parallel to the y axis (ANGLE 360 will achieve horizontal labels).
See section Drawing Labels and SM's TeX Emulation, for a description of how to enter a label with funny characters, sub- and super-scripts, and so forth.
If EXPAND is set to exactly 1, and ANGLE is exactly 0, then SM will use hardware fonts, when available, in writing labels. This is faster, but if you don't like it say "EXPAND 1.00001", or start the string with a \0 which does nothing, but forces the software character set.
Go to the previous, next section.