Old wine in new bottles: creating graphical user interfaces for FORTRAN programs via Tcl/Tk

Brian H. Toby,

Crystallography Team, NIST Center for Neutron Research, Stop 8562 , National Institute of Standards and Technology, Gaithersburg, MD 20899-8562, USA. Tel: 301-975-4297; Fax: 301-921-9847;
Brian.Toby@NIST.gov; WWW: http://www.ncnr.nist.gov/xtal

About a decade ago, I started looking for a good way to create graphical user interfaces (GUI) for the FORTRAN programs that I was using on a regular basis and for those I was writing. To me "good" means: (1) Easy to learn. Learning new skills is important, but time is always scarce; (2) cross platform. I want the same software to work on my desktop SGI, my Linux home computer and my coworker's Windows box; (3) cheap. I want to encourage other people to collaborate on software -- if they must purchase something to do this, they probably won't.

I spent many years looking.

The solution that eventually adopted is a scripting language, called Tcl, and a GUI tool, called Tk. Some people feel that other scripting languages, notably Perl and Python might be better choices than Tcl. Those folks may be right. What I can say is that Tcl was very easy for me to learn and it turns out to be very powerful, so I have never needed anything else. Also, while Tk is available for Perl and Python, it was originally created by the author of Tcl, John Ousterhout, so it comes as no surprise that Tk works best with Tcl. For my purposes, I'll consider them a single language, Tcl/Tk. Java gets lots of press, too, and can do many of the same things. At the time when I was looking, platform-independent GUI tools for Java were not available and Sun and Microsoft were fighting for control of the turf. The former is no longer true, but from what I can see, there are still many platform-dependency issues Java. True, I do need to tweak my Tcl/Tk code a bit to get around some of the limitations of Windows. However, to take one project (EXPGUI) as an example, in »37,000 lines of code only a few hundred lines are either Windows or Unix-specific. Those sections of the code check what operating system is being used and react accordingly. Thus, the exact same source code is used on all platforms.

In this article, I will tell you a little bit about Tcl/Tk. I'll also give an overview of some of the projects that I have tackled using Tcl/Tk. Lest I forget to mention: Tcl/Tk and, for that matter, all my software is available on the Internet, free, and with source code.


Perhaps the easiest way to give you a feel for Tcl/Tk is to give you an example of a very simple program. Suppose you have Tcl/Tk loaded on your computer (and there is a fair chance you do), you can start the command interpreter by typing "wish" in Unix. In Windows, you might have to find the WISH82.EXE file in a folder like c:\GSAS\TCL832\BIN and then click on it. A window for commands and a window for graphics will then be displayed. Into the command window, type the following commands, one line at a time:

set w .b

button $w -text "Hello World" -command {puts "Hello World"}

pack $w

These three lines of code create a GUI with a working button and invoke three commands, "set", "button" and "pack". The first line defines a variable, w, which contains a character string ".b". Note, I did not need to declare the variable. The second line creates a button and the third line places the button on the screen. In fact, I could have written this program in a single line. Note, also that no compilation was needed. Tcl interpreted the commands as they were typed. We can change things as we go, too. For example, now type:

 $w config -command {tk_dialog .msg msg Hello "" "" OK}

The button action now changes to display a new window when pressed.

One of the major criticisms of interpreted languages is speed. A program that is compiled will run faster than one that is interpreted. I have two comments on this, though. Speed is not always very important in a GUI. When you push a button something should happen soon. Nevertheless, if soon is 0.00005 seconds or 0.05 seconds, you will be hard pressed to tell. Modern computers can do an awful lot in 1/20 of a second. Second, Tcl interprets commands once and saves the byte-compiled code, so slow is not always that slow.

Tcl is designed to have commands added to the language. So, you can define your own Tcl command, say, Solve_Structure_and_Publish either as a procedure composed of other Tcl/Tk commands or, for better speed and power, by adding compiled C (or FORTRAN) code into the language. This means that rather than adding a macro language to your program, you can add your program to Tcl/Tk and in the process get a full-featured GUI and macro language. Many commercial vendors do this, but to be honest, it can take some work and takes effort to support on multiple platforms, so I now avoid it. I'll discuss that more below. However, many people have written collections of commands, called packages, which add capabilities to Tcl/Tk that are not present in the native language. One example that I use extensively for scientific graphics is called BLT. Another is called LA, for linear algebra.

Scientific graphics

One might think that scientific graphics (xy plots, etc.) should be easy to do in a GUI environment, but that has not been my experience. The scientific plotting package I use, BLT, allows creates and manipulates graphs (for example, zooming in, change colors,...). BLT is a blessing and a curse. It is keeps getting more features, which sometimes break old code. It creates really mediocre hard-copy output. It makes Tcl/Tk installation that much more complex. Until the advent of OSX, BLT was not supported on the Mac. However, it is easy to use and offers lots of power.

Some Tcl/Tk web links

FAQ links: http://www.purl.org/NET/Tcl-FAQ/

yet more links: http://www.cetus-links.org/oo_tcl_tk.html

misc Tcl/Tk programming ideas: http://aspn.activestate.com/ASPN/Cookbook/Tcl

Wiki (programming tips, etc): http://wiki.tcl.tk/0 and http://wiki.tcl.tk/969

Newsgroup comp.lang.tcl info: http://www.purl.org/net/tcl-welcome

Tcl/Tk successes: a personal gallery

EXPGUI. I imagine that my front-end to the GSAS crystallographic package, EXPGUI, is the most widely used software package that I have written. It uses Tcl/Tk to edit the "experiment" (.EXP) file that GSAS uses for input. EXPGUI can also be used to launch all the other GSAS programs, for example the least-squares minimizer, GENLES. With time, I have added more scientific graphics to the program.

Most of EXPGUI is written in Tcl/Tk. An exception is the sections of the program that adds new phases or histograms to a refinement. This involves many complex steps; it was much easier to borrow FORTRAN code from the GSAS EXPEDT program than try to rewrite it in Tcl/Tk. So, when the user presses the "add phase" or "add histogram" program, (or, for that matter, plots the results), an external FORTRAN program is called. Its fast, so the user probably does not know that. The major stumbling block in getting EXPGUI to work cross-platform is that Tcl/Tk has trouble starting Windows "console" applications (where a program runs in a "DOS window") under Windows-95/98/ME. For that platform, I use a package called WINEXEC to work around this. (At some point, I'll switch to a newer package by D. Gravereaux called winutils.) All the tricks used in EXPGUI can be figured out by reading the source code. [See http://www.ncnr.nist.gov/programs/crystallography/software/expgui/expgui_intro.html]


Fig 1 (a, b): Screen image examples of EPGUI

CMPR. The name for CMPR was taken from a prehistoric VAX program that I wrote to plot powder diffraction data and do peak fitting. With time, I have added many more features. I consider CMPR to be sort of a "Swiss Army Knife" where I add a new blade (capability) as I have time and need. One of the unique features of CMPR is peak position visualizer that superimposes reflection positions on top of diffraction data. The neat part is that the GUI has "sliders" for each appropriate unit cell parameter. Adjusting the slider via the mouse causes the reflection positions to move seemingly instantaneously. It makes a nice teaching tool for showing how changing unit cell symmetry splits classes of reflections. It can also be used for pattern indexing and for looking at space group extinctions. From a programming perspective, the way it works is a bit surprising. When I wrote the code, I got to the point where I had a set of unit cell parameters, a wavelength, and a list of hkl values. My plan was to imbed a new command into Tcl that would take that input and spit out a list of 2q, Q values, or whatever. However, for testing, my Tcl code wrote this input to a file, invoked a short FORTRAN program which would do the number-crunching and write the peak positions back to a file. The Tcl/Tk script then read the peak positions back by Tcl/Tk. This test code, though clumsy, gave response time that was already sufficiently fast, even with the 90 MHz PC I was then using, that I never bothered to add the new command. I would not have believed it, but this means that Tcl/Tk can fork external FORTRAN programs quickly enough to do primitive computer animation - even in Windows! Amazing.

[See http://www.ncnr.nist.gov/programs/crystallography/software/cmpr/cmpr.html]

LOGIC. The LOGIC program is a clone of a VAX application for Boolean searching of the ICDD-JCPDS database. It was the project that I used to learn Tcl/Tk. For this project, I took all of the search capabilities from the original FORTRAN code, rewrote the VAX-specific low-level subroutines in C. Then wrote C wrappers around the upper-level FORTRAN code. Getting all the naming and argument passing right so that C can call FORTRAN and vice versa with different compilers for the SGI, Linux and Windows was a pain, but it works (now one can use gcc for Windows). I then wrote a Tk GUI. Voila, a platform-independent code for accessing the JCPDS-ICDD database. Later, having all the database access routines already written in Tcl/Tk, it was pretty easy to add ICDD entry plotting into EXPGUI and CMPR. LOGIC was written in the mid-90's and I am not maintaining it actively at present, but I do hear from people who are using it. [See http://www.ncnr.nist.gov/programs/crystallography/software/logic.html] Also in the mid-90's, to show the power of intranet-based searching of the database, I created a web interface by creating a Tcl cgi script that used the guts from LOGIC. I had hoped to slap it together with the help of my Tcl/Tk guru, Przemek Klosowski, over a weekend, but it took a few weeks before we resolved a weird bug. Still, not bad for a first attempt at a web application.

[See ftp://www.ncnr.nist.gov/pub/cryst/powdersuite/icdd_search.tar.gz].

NCNR Crystal Data Searching. Use of FORTRAN code embedded into Tcl was chosen for this project, so that I could open the database once, and string searches together in a sequential fashion, but it made LOGIC hard to maintain and distribute. For my next web-based search program, I decided to try a different approach, where each search would: i) start a FORTRAN program; ii) load the previous search results; iii) perform a new search; and iv) write the result to file. Yes, this approach is wasteful compared to the one used in LOGIC. It probably squanders hundreds, if not thousands of microseconds each use, but the code is so much easier to write and maintain. Besides, for a web application, the search programs really does need to be started each time the user presses "Search" on her/his browser screen.

For reasons unclear to me, NIST is no longer selling the Crystal Data database in the format I used for this project, but the web interface is in use within my center and the code can be found on-line. I think this is a nice example for how to set up a web-based Boolean search engine. [See ftp://www.ncnr.nist.gov/pub/cryst/powdersuite/crystaldata.html].

CIF Applications. Most recently, I have been at work on a number of programs for creating, viewing and editing crystallographic information files (CIFs). To give an idea of how powerful Tcl/Tk is for lexical processing, a complete Tcl/Tk parser and browser took little more than 2,000 lines of code. Another program built on this parser reads and plots powder diffraction patterns read from CIF. As of this writing, these projects have not made it to the web, but look for a link on http://www.ncnr.nist.gov/xtal soon.

In conclusion, Tcl/Tk is a pretty nifty way to provide modern interfaces with valuable, but sometimes hard-to-use older codes. It is also easy enough to learn, such that several people have contributed code to CMPR and EXPGUI.