### A brief introduction to SM

examples | overview of commands | hints

SM is a versatile plotting utility which grew out of a graphics package called mongo (SM is formerly "supermongo"). It is widely used in the astronomical community.

The utility can do most anything required of a scientific plotting package--2D plots, histograms, surface and contour plots, data manipulation etc. While it does not have all of the graphics sophistication of Mathematica or Maple, it is easy to use and can provide a quick and effective way of examining data. What weaknesses it possesses in terms of predefined functions are offset by the fact that users can define their own macros.

This page is intended to be a "least-action" guide for information that will you help you accomplish a few very specific things with SM. For more thorough and accurate information, please try the official SM tutorial or the html version of the SM manual.

### Getting started.

Below are some example exercises to learn a few of the things one can do with sm. To begin an sm session, type sm into an xterm shell:
host> sm
(you type sm only; host might be darkstar for example). SM's prompt is a colon (:). Next you may need to specify a plotting device; here let's assume for now that you want to see your plot as a new window in X. Type in
: dev X11 # define output "device", a window in the X-windows system.
(Note: the hash (#) symbol is used here to indicate the start of a comment.) This should cause a new plotting window to be created, and now you are ready to proceed. Bear in mind the following useful actions which can be taken during a session:

• end the session by typing quit;
• clear the plotting device (making it ready for a new plot) by typing erase; and
• get on-line help with the help command.

#### Plotting a function.

In this example we plot a function y=sin(x**(1/2)). First we must define the vector x, for example in the range of 0 to 10, then we set the y values.

: set x=0,10,2 # set x=(0,2,4,..10)
: set y=sin(x**(1/2)) # pack y values
: limits -0.5 10.5 -1.1 1.1 # set limits of axes "by hand" (could've used limits x y, also)
: box # draw the axes using the limits just specified
: connect x y # connect the dots
: poi x y # make points too, using abbreviation poi
(Again, the # symbol indicates the beginning of a comment.) Note: x is vector -- a list of N numbers x[0],x[1],...x[N-1] determined by the setcommand. Also note: we could define x (or y or both) by reading it from a file as in the next example.

#### Plotting a set of data points in a file.

Make a data file. It should be ASCII text (not binary), with x,y values listed in two columns (no commas, please). Note that SM will stop reading data after it encounters the first "unexpected" part of the file (e.g., the end of file, a blank line, non-numeric characters, a change in the number of columns). Lines which begin with a hash (#) are comments and are ignored without ill effect when SM reads a data file.

: erase # this clears the plotting window
: data file.dat # tell sm the name of your data file (file.dat)
: read {x 1 y 2} # read the file, store column 1 in vector x (col 2 -> y)
: limits x y # set ranges of plot axes based on values in vectors x and y
: box # create the borders of the plot, tickmarks and all
: points x y # plot the data points stored in vectors x and y.
: xlabel X (some units) # label horizontal axis
: ylabel Y (other units) # " vertical ".
The read statement created the vectors x and y (or recreated them if they were already defined) from the N elements of the first two columns of the file. x[0] comes from the first column of the first line in the file while y[N-1] is from teh second column of the N line of the file (excluding comment lines).

#### Plotting error bars x-y data

Suppose now that a data file has three columns where the first two are independent and dependent variables (x,y) and the third is the errors associated with y. To plot error bars, use
: data errfil.dat # name of data file
: read {x 1 y 2 sy 3} # read the file containing x y and sigma_y.
: limits x y # set ranges of plot axes based on values in vectors x and y
: box # create the borders of the plot, tickmarks and all
: points x y # plot the data points stored in vectors x and y.
: errorbar x y sy 2 # plot upper half of error bar (2 => +y dir)
: errorbar x y sy 4 # plot upper half of error bar (4 => -y dir)
Note that errorbars need not be symmetrical (the reason for the two calls to errorbar above) and the you can put them along x direction as well. (Of course these point+errorbar commands will work on any vectors, not just those read in from the file.)

#### Fitting a line to the x-y data

: lsq x y # do a least-squares fit of a line to x vs. y
: calc \$a # print the value of variable \$a = slope of the best-fit line
: calc \$b # print y-intercept of best-fit.
: lsq x y x q # do lsq on x y, set q=\$a*x+\$b
: con x q # draw lines between points x vs. q
Note: the lsq function can have 2 arguments or 4 (or 5--type help lsq) When it has 2 args, it merely does the bestfit to the line y = \$a*x+\$b, setting the values of variables \$a, \$b. When it has four arguments, lsq x y p q it does the fit to x and y, then it looks at vector p, assumed to be a list of x-values, and creates (or recreates) a vector q such that q = \$a*p+\$b. In the above example, x was used as the list of x-values at which to evaluate q. You probably don't want to write lsq x y x y because this will overwrite data stored in vector y with the best-fit values.

You can do a weighted least-squares fit, as when you have known errors in the dependent variable as in the previous exercise with error bars. To incorporate these uncertainties, in the fitting routine, try

: set w=1/(sy*sy) # set weight to 1/sigma_y^2
: wlsq x y w # do a least-squares fit of a line to x vs. y
(see the help information on wlsq).

#### Generating a histogram

SM's apropos [keyword] help facility will flag several occurances of the keyword "histogram". It is used in a context dependnet way, as follows:
: set q = -100,100,5 # let this vector define the histogram bins of width=5.
: set h=histogram(y:q) # bin the (predefined) vector y as per bin locations given by q.
: limits q h # set axis ranges.
: histogram q h # this plots the histogram.
: box # finishing touch, maybe.
Note: see the help pages for keyword arithmetic for a discussion on the use of histogram(a:b). (For example, b must be sorted, and the behavior differs depending on whether the bins are equally space.

#### More than one plot on a page

The window command allows you to plot more than one graph on a physical page. The command takes four arguments, the first two are the number of windows along the horizontal and verticle axes (repsectively), while the third and fourth are the "coordinates" (1..nx,1..ny) of the window to which subsequent output will be sent. For example,
: window 1 2 1 1 # two windows, stacked vertically, use lower one
will direct subsequent plotting output to the lower half of the page. Use
: window 1 1 1 1 # (yawn)
to reset to one window. The help pages are worth looking at, as they give some details on how to control more directly the subdivision of area for the plotting windows.

#### Image plotting: surfaces and contours

SM can plot image data, but the data must be in specific formats. Here we choose the "C" formats as explained in help image. To do so, copy/create a .sm file in your home directory (for example, see ~p5720/.sm) and be sure it contains the following line:
file_type C
After this line is in place (re)start SM.

(An example of a file in SM's "C" format is in ~p5720/data/slc.map_thinned.sm; it has elevations for the SLC area on a 51x51 grid. Note elevations are in meters, between 1000m and 4000m.)

To make a surface plot of an image file, try the following:

: image "fil.dat" 0 1 0 1 # read im image data, set image to lie in x,y=(0,1).
: limits 0 1 0 1 # set limits to match image (actually these are default values).
: surface 1 0 5000 # draw surface, 2 => top surface only; 0,5000 are z-axis limits.
That should do it. Use viewpoint to change perspective. Type help surface to see other possibilities. Note load surface allows you to draw projected 3D axes:
: overload viewpoint 1 # redefine SM's viewpoint command
: overload surface 1 # redefine the surface command
: surface# like above, but it calcs the z limits automatically
: box3 # put on proj. x,y,z, axes + labels.

Contour plots: For contour plots, try the following perscription. (The file ~p5720/data/slc.map.sm is a "C" format datafile that has elevations for the SLC area on a 201x201 point grid.)

: image "fil.dat" # as above, but w/default image size, locale (see help).
: limits 0 200 0 200 # assuming image size is (nx,ny) =(201,201)
: levels { 1000 2000 3000 } # define contour levels (z values!) to plot
: lweight 2 # set thickness of line to be moderately heavy
: contour # generates the contours.
: lweight 1. # set line weight back to normal
: levels { 500 1500 2500 3500 } # define new contour levels
: contour # and plot the new levels
: box # afterthought(?) draw axes
If you want use different units for the x and y axes than the grid size in the above example, you can either user the image command with 5 arguments as in the surface plot example, or you could even just reset the limits after you draw the contours but before you draw the axes with the box command!

SM can read and execute a list of commands, like the examples given above, directly from a text file. Use execute sm_commands.file, or input sm_commands.file (although this latter may not work).

A couple of hints:

• In your text file keep one SM command per line.
• Remember, # starts a comment (commands after it on same line are ignored)

#### Output (file dump)

SM's output can be directed with the device command. To make a postscript file that contains a plot as directed from the commands in some file sm_commands.file (an emacs-generated text file with a line-by-line list of SM commands, for example), try
: dev postfile file.ps # setup for output to postscript file
: execute sm_commands.file # make the plot....
: dev X11 # changing the device triggers SM to write the .ps file
BE SURE that your sm_commands.file does not have a dev command in it or you may get nothing dumped to the postscript file! (Also, note that you needn't use the execute command--that's just a convenience. You could type all plotting instructions in directly.)

Local hint for JPEG output

If you want to create a JPEG file (for display on the web, or when required in a homework assignment!) try

: dev pbm file.pbm # setup for output to Pixel Bit Map file
: execute sm_commands.file # make the plot....
: dev X11 # changing the device triggers SM to write the .pbm file
pbmtopgm 1 1 file.pbm | cjpeg > ! file.jpg
This converts the .pbm file into a Pixel Gray Map format (.pgm), which is piped to the "cjpeg" utility. Cjpeg does the final conversion to a .jpg file. Be sure to type this VERBATIM! See the "man" or "info" pages if you are curious about the arguments. The final redirect from cjpeg is important -- you may find your terminal in a very bad state if you do not redirect the output!

### Overview of the most important commands.

Here is a list of commonly used commands. For each, you should type the most important one, help (command), for more details.

dev sets the output device;
dev X11 => X-windows; and
dev postfile file.ps =>. write to postscript file named file.ps

set creates variables (scalars or vectors);
set x={0 10 20 30} creates a vector x with dimension 4 such that x[0] = 0.0, x[1] = 10.0, ...x[3] = 30.0.
set x=0,30,10, has the same effect; it means to pack x with values of 0 to 40, using steps of 10.
set y=4.0*x**2+3.2*x-23 creates y with the same dimension as x then packs it, element for element, with the quadratic function of x.

data file.dat loads a filename into the guts of sm to read later.
read reads the file specified by the data command. read { x 1 y 2 z 3} packs x with first column of numbers, y with 2nd....

erase clears the output device (wipes the "page" clean).

limits sets the ranges for the x and y axes.
limits x y figures out nice horiz. and vert. axis ranges from data in vectors x and y.
limits 100.1 200 -10 10 set horiz. axis range of 100.1 to 200, and vert. axis range of -10 to 10.

box plots the axes, tickmarks and number labels indicating range.

points x y plots the points in x,y as ordered pairs. Note: x and y must have the same dimension (# of elements).
ptype # # can be used to change the type of point (e.g., dot, circle)--see the help info.
expand # changes the size BUT it also changes the size of other things, too, like axis labels.

connect x y draws lines between points x,y.
ltype # can be used to choose line type (solid, dashed, etc.). lweight # changes the weight or thickness of the lines--like expand, it is global in that other things like points, axis labels, are affected by the most recent setting of lweight.

apropos allows you to search for keywords in the online help files.

quit exits SM.

### Hints

#### Some potentially useful features of SM.

• You can use 3-letter abbreviations of some commands like lim for limits, con for connect, etc.

• You can use the set command to define data vectors which are subsets of other vectors. For example, suppose vectors x,y, and z all have the same dimension (e.g., they have all been read from the same data file). If you want to plot only x-y data that are restricted to some range in z, you can do so by working with two new vectors defined as follows:
: set p = x if (z > 2 && z < 10) # p gets x values when 2 < z < 10
: set q = y if (z > 2 && z < 10) # q gets y values when 2 < z < 10
Then just plot p,q in the usual manner.

• You can get info about a vector using the calc command:
: calc dimen(x) # print the dimension of x
: calc sum(x)/dimen(x) # sum x, divide by # of elements -- this gets the avg x value

#### Some quick comments to avoid problems:

• The data command may require double-quotes if your data filename contains slashes or minus signs.

• Be sure to use dev X11 if you want to see your display on a system running X.

#### Troubleshooting

• Failure to read in data files correctly? The file format is pretty specific: sm wants columns of numbers only, except that you can comment out lines with a hash (#) symbol at the beginning of a line. There can be a fair number of columns (I don't know what the limit is, certainly > 10) but if the number changes from one line to the next, read will fail. If a line is blank then read will read no further, and it may whine about it if it found spaces or tab characters. If, at the end of the file, the last line doesn't have a new-line (carriage-return) character, that may cause trouble as well.

• Unable to see any output? Type dev X11 to bring up an X-plotting window.

bcb 11-Sep-98.