Experience Programming Radiotherapy Applications ...

3 downloads 0 Views 138KB Size Report
Sullivan and Notkin 4] argue that the generalization of ab- stract data types ..... Sharon M. Hummel, Kevin J. Sullivan, and Jonathan M. Unger. Prism: A new ...
Experience Programming Radiotherapy Applications in Common Lisp 1

2

1

Ira J. Kalet, Ph.D. , Jonathan M. Unger, M.S. , Jonathan P. Jacky, Ph.D. ,

1 1 Radiation Oncology Dept., University of Washington, Seattle, WA 98195 2 RSA, Inc., 22 Terry Ave., Burlington, MA 01803 Mark H. Phillips, Ph.D.

We report on our experience using Common Lisp 1] as the programming language for a new radiation treatment planning (RTP) system, the Prism system 2]. The Prism system was built to provide new features such as arti cial intelligence tools and to take advantage of the most advanced computer graphic display and networking technologies. We decided to use Lisp because of: its high level of expressive power, the existence of a direct interface to the X window system for network-based graphic display, its standardization and its wide availability. Although Lisp is one of the oldest programming languages, in the past its use had been limited to arti cial intelligence research. It was not widely available, and Lisp compilers of the time were not able to generate highly e cient binary code. Modern Lisp systems have eliminated these obstacles, and added powerful object oriented programming capabilities, along with standardization, so that Common Lisp can be a powerful and practical system implementation language for interactive graphic applications like radiation treatment planning.

THE PRISM SYSTEM

Prism takes a very generalized approach to display and user manipulation of the system, extending ideas we incorporated into our previous work. The unique features of Prism are described in another publication 2].

User interface requirements

The Prism system user interface is distributed among several task-speci c windows we call panels, which act as a front end for those components of the system which actually carry out various functions related to radiotherapy planning. The interface is designed to provide as little nesting of interactions as possible, that is, we want almost all operations to be available to the user at all times. On the other hand, presenting a display with visible controls for every adjustable parameter of every object would be impossible. So our compromise is to associate a type of control panel, or object editor, with each type of object that the user can create or modify. A control panel is a window on the screen that includes controls, e.g., dials for angles, sliders for adjustable numbers, text input boxes for typed text, etc. so that when the control panel for a particular object is displayed, the user can at any time alter any of those attributes of the object. A patient panel that manages administrative information about the current patient case is always present in a given Prism session. Individual panels for plans, beams and other component objects control their respective domains, and view windows display graphical renditions of patient anatomy and beam portals. A graphic editing panel provides for the delineation and modi cation of patient anatomy, tumors and targets. The plan panel includes controls for the speci cation, computation and display of dosimetric information for a plan. The

user can bring up simultaneously any number of these or other component-speci c panels during the Prism session.

Design goals

In addition to the speci c user requirements, we set out design goals. They include: keeping the overall size of our programs small, so they will take less time to build and maintain, ease of nding and xing problems, ease of adding new features and extending existing ones, ability to add new kinds of objects, ability to add new kinds of control panels. These items are examples of the need for software evolution, a need that is di cult to satisfy, even using object-oriented design and object-oriented programming languages.

Architecture: objects and relationships

Our previous work 3] showed that RTP systems can be naturally modeled as collections of interacting objects, radiation beams, organs, etc. In Prism too, we chose an object-oriented design. The patient, the treatment equipment, and all their parts are represented as objects in the Common Lisp Object System. The patient case is the overall \container" object in the Prism system. The other objects are parts or components of the patient case. We have modeled some RTP object classes as subclasses. For example, there is a class, pstruct, that de nes a general three-dimensional anatomic object, and there are subclasses for organs, tumors and targets. All have contoured volumes, a display color, etc., but each subclass has additional attributes that represent special characteristics, e.g., organs may have a density, for use in the dose calculation. We also make extensive use of the part-of relationship, in which an attribute of an object may have as its value an instance or collection of instances of another object class. For example, a radiation beam is modeled as an object that includes a collimator subsystem as a component attribute. There are dierent classes of collimators, but only one class, beam for a radiation beam. As an example of how we implement these objects, the following shows the code that de nes the beam class. (defclass beam (generic-prism-object) ((machine :type string :documentation "The string naming the machine used for this beam, eg. Clinac 2500-6MV") (new-machine :type event :initform (make-event)) (gantry-angle :type single-float) (new-gantry-angle :type event :initform (make-event))

(collimator :type collimator :documentation "An object, one of the various types of collimators.") (collimator-angle :type single-float) (new-coll-angle :type event :initform (make-event)) (monitor-units :type single-float) ...etc... ))

The type declarations are not required but help the compiler produce faster, more e cient code. Documentation strings are parts of an object and can be accessed by a running program. They are data, not comments. We are considering using this facility or something like it to incorporate contextdependent online help in the Prism system. The types string and single-float are the usual types you nd in most programming languages, but an event is a type de ned in the Prism system, to provide connections between objects. An object announces an event, and other objects can respond. The responses depend on what is registered with the event while the program is running. The collimator type is also a class, with subclasses for dierent types of collimators. Here are some of the collimator subclasses. (defclass symmetric-jaw-coll (collimator) ((x :type single-float) (y :type single-float) (new-coll-x :type event :initform (make-event) :documentation "Announced when x is updated.") (new-coll-y ...)) (:default-initargs :x 10.0 :y 10.0))

This class de nition provides default values when a new collimator is created, to insure that the attributes always have valid values. (defclass portal-coll (collimator contour) () (:default-initargs :z 0.0 :vertices '((-5 -5) (5 -5) (5 5) (-5 5))) (:documentation "A collimator that has a portal, defined by a contour. The contour is always at z = 0."))

The class portal-coll adds no new slots or attributes, but combines the properties of the collimator and the contour classes, since a portal collimator has a portal de ned by a contour. (defclass electron-coll (portal-coll) ((cone-size :type single-float :documentation "An electron collimator is a square cone with a metal cutout plate.") ...other slots...))

Adding a slot for specifying the cone in use allows for specialized methods, e.g., for the user to select the cone size from a menu, and for the dose computation to look up tables based on cone size. Object-oriented design provides a way to make a close correspondence between the real world and the software system,

up to a point. Objects modeled as abstract data types (classes) can abstract and encapsulate attributes and operations on objects. But in a dynamic system, objects have actions that may aect other objects. The internal code of object implementations will then refer to other objects, and the result is that the objects are no longer independent and modular. Managing this interdependence in writing a large program like an RTP system is very di cult. Sullivan and Notkin 4] argue that the generalization of abstract data types (ADT) to include action interfaces, or abstract behavioral types (ABT), provides improved correspondence between speci cations and designs, improved abstraction and encapsulation, and behavioral composability of independent types. This is particularly important in dynamic modeling, where a software system must provide for the creation and destruction not only of objects but of relationships between them. The use of ABT provides a way to model such actions while retaining encapsulation. The potential of this approach to software design was suf ciently appealing that we decided to use it in designing and implementing the Prism system. We expected that behavioral abstraction would result in a simpler, more modular design than the use of object-oriented design and programming alone. A separate report 5] describes how this approach worked out in building the Prism system. In this report we address the speci c choice of Lisp as our implementation language and its contribution to the success of Prism.

WHY LISP?

In choosing a programming language for Prism, we considered several characteristics to be important. The language we use must support: object-oriented programming, the X window system, for graphic display and user interaction, a high level of abstraction, building large systems, i.e., programs that are large and complex, and that can handle very large amounts of data and numbers of objects, deployment in an application environment, i.e., routine use in the clinic, not just an experimental lashup to be used only by physicists. Few languages meet all of these requirements. The obvious choice of most designers these days is C++ but it does not provide as good an object-oriented programming environment as Common Lisp, nor does it provide a very high level of abstraction. We were not looking for \a better C". Before committing to development in Common Lisp, we reviewed the limitations we experienced with our earlier work, and did some prototyping that helped determine the feasibility of using Lisp.

Lisp in the light of previous work

Our earlier work 3] used the Pascal programming language. It was di cult because there are no facilities in Pascal for de ning abstract objects, i.e., classes, and for de ning generic functions for those objects. Although we created a workaround for our RTP system, it was inexible (it was di cult to add new object classes), and hard to understand, because the implementation had much code devoted to object management and function dispatch. This obscured the actual application, the radiotherapy objects and their operations.

We had some prior experience with Lisp, in writing an expert system program for automating part of the radiation treatment planning process 6]. That program did not have a graphical user interface and did not provide any of the complex data management characteristic of RTP systems. Interlisp, the dialect of Lisp that we rst used, was not a good candidate for an RTP system, as it did not have an e cient compiler (compiled code ran slowly), it did not include support for the emerging X window system, and although very large programs had been written using Interlisp, it was not well suited to writing programs for routine use by non-programmers. The emergence of Common Lisp as a standard and widely supported commercial product was a radical change. Common Lisp implementations became available that had very e cient compilers, support for X windows (there is a de facto standard Common Lisp binding to the X window system, CLX, and a public domain implementation is available), facilities for application deployment, and an excellent standard objectoriented programming system, the Common Lisp Object System (CLOS). Growing use of Lisp in serious applications has resulted in the formation of the Association of Lisp Users1 . Lisp is used in the video game software industry, as well as in software products such as AutoCAD and Interleaf, and as an HTML server2 . We wrote some prototype user interface code to experiment with the graphical performance of Common Lisp programs. Satis ed with its performance, we discarded this code, and began in earnest to design and write the Prism system.

Characteristics of Lisp

In deciding to write the Prism software in Lisp, we expected to take advantage of the ability to create layered designs, in which the programmer constructs supplements to the language as needed. In addition to meeting the criteria described above, Lisp has features and characteristics that make it radically dierent from all the more familiar programming languages. These features are important in writing RTP software they are not just exotica that arti cial intelligence researchers play with. In Prism the following features proved to be especially useful: Run-time types: Lisp can determine the type of a piece of data at run-time, and act accordingly. We take advantage of this to make the storage and retrieval of RTP plan data very simple. Multi-methods: In the Common Lisp Object System, methods for generic functions can be selected at run-time based on the type of any number of arguments. Lexical closures: Lisp code can create new functions while the program is running. This may be very unfamiliar to most programmers, because it is impossible to do in most programming languages, but it is very powerful. It is explained in Graham's book 1, pages 1{2]. Prism uses other unusual features of Lisp, too numerous to go into here. We refer the interested reader to some excellent books that explain Lisp programming in depth 1, 7].

Examples of advanced techniques

We include here some examples of Prism code that uses special or advanced features of Lisp. The Lisp function read can read text from a le and construct the right type of object from the format of the le. The 1 2

programmer does not need to provide any code for formatted or binary le reading. Prism takes advantage of this in storing patient and plan data and retrieving it for reuse. Prism objects contain many dierent types of data as values of their attributes. The data are all stored as ASCII text, using the Lisp write function. It formats the data automatically, without need for the programmer to do anything. The Prism function put-object executes the same code regardless of the type or complexity of the object. It obtains the names of the attributes of an object from its class de nition, and writes all the attributes without concern for order or type. When data are read back into a Prism session, the corresponding function get-object executes the same code regardless of what is read. The le contains data identifying the type of the object and the get-object code calls the standard CLOS function make-instance to make one. Then get-object reads keywords naming the attributes, and then reads values whose type is automatically known to Lisp by the format of the data. This alone represents a huge saving in code, where in our previous systems we had to write a lot of detailed code to handle the plan data le formats. It also makes it easy to add new kinds of objects: the old les are not made obsolete, and no new le reading and writing code needs to be written. An example of the use of multi-methods is the Prism draw generic function. There are many places where an object needs to be drawn into a view. Neither the type of object nor the type of view is xed, and at the same place in the program, but at dierent times during a Prism session, this function may need to draw dierent objects into various types of views. The function call is (draw object view) where object is some Prism object, a beam perhaps, and view is a view on the screen, maybe a transverse view. In general, in Prism, the types of the arguments are not known at compile time, and may even vary as the Prism session progresses. Many object-oriented programming languages use method dispatch on the type of a single parameter, i.e., a method is a piece of code that implements a function for a particular class of object, and we say that the method \belongs" to that class. This is analogous to the idea of \sending a message to an object" in order to invoke a function. So there would be draw methods for each of the dierent object classes. But what about the dierent kinds of views? It is complicated. Perhaps there will be a multiway branch inside the code for each draw method. Then adding a new object means writing a big method, and adding a new kind of view means modifying a lot of dierent modules. Instead, the Common Lisp Object System provides dispatch on any number of parameters, so the draw function can have methods organized according to the types of both parameters, i.e., there is a method for each combination. Here is an excerpt of a method for drawing an organ: (defmethod draw ((org organ) (tv transverse-view)) (let ((prim (find org (foreground tv) ...)) ...) (dolist (con (contours org)) (let ((pts (pixel-contour (vertices con) scale x0 y0))) (push (nconc pts (list (first pts) (second pts))) (points prim))))))

Drawing a dierent object, such as a beam, requires a dierent method for the draw function. The beam drawing method

refer to http://www.cs.rochester.edu/u/miller/ALU/home.html in particular, for the White House Publications distribution system via the World Wide Web

uses a formula for projecting and transforming a portal contour in arbitrary orientation, and also has to render the other items in the beam depiction, the isocenter, the central axis, and a wedge if present. (defmethod draw ((b beam) (v view)) (let ((solid-clr (display-color b)) ... (wdg (wedge b))) ...beam portal drawing code...))

The nal example we provide from Prism illustrates that in Lisp a program can write and execute programs as needed. The idea is that a function may be needed but what function is needed may vary. It is possible in most programming languages to pass functions as parameters to other functions, but in Lisp, a program can make up functions depending on conditions in the program, something impossible to do in most other languages. The following code (add-notify m (inserted os) #'(lambda (md obj-set obj) (dolist (v (elements (view-set md))) (insert-element (funcall mediator-fn obj v) (mediator-set md))

registers the function whose code begins with lambda so that it will be called when a new object is added (for example, a beam to a plan) and the new object therefore has to appear in all the views. This lambda function is a dierent function depending on the type of object and the type of view, when it is added, i.e., the function that gets registered is created by this code, not just selected. This is how Prism keeps all the objects and views coordinated, even though objects and views are being added and deleted all the time during a Prism session.

RESULTS AND DISCUSSION

The Prism system consists of about 45,000 lines of Lisp source code, making it similar in size to our two previous RTP systems, written in the Pascal programming language. It is an order of magnitude smaller than many other RTP systems, including commercial products. However, the capabilities of Prism far exceed any previous system we built. We have described elsewhere 2] some of the unique features of Prism, not found in any other RTP system of which we know. The object oriented programming support in Common Lisp enabled us to add facilities for modeling multileaf collimators and for stereotactic radiosurgery, after the initial system was put into clinical use. We are also adding support for intensity modulated radiotherapy using a computer controlled multileaf collimator 8, this volume]. Other advantages of Lisp include: ease of incorporating advanced software engineering design ideas such as the \mediator method" 5], ease of debugging, and simpli ed interactive graphics programming, particularly the CLX package for X programming. CLX is much less cluttered with low level details than the C binding for Xlib, even though it provides the same and even more functionality. We nd Lisp programming to be enjoyable and satisfying because with it we can express easily our ideas and speci cations without becoming embroiled in arcane details unrelated to our application. Some of the obstacles we had to work with include learning a new programming language whose style is very dierent

from Pascal or C, and the extra eort required to optimize the performance of the system. Overall, the choice of Common Lisp was a good one and Prism is successful, having been in clinical use for over two years. The system continues to evolve and is easy to maintain. In the future we hope to explore the possibility of developing a more high level implementation, something along the lines of the \Compiler TP" idea of Sterling 9], analogous to the CLOS Meta-Object Protocol 10]. Imagine an RTP system with all the standard features, and a high level dynamic RTP macro programming language built in, for adding features without modifying any existing code, and being able to use any existing components. That is our vision for the future of Prism.

ACKNOWLEDGEMENTS

This work was partially supported by NIH grant no. LM04174 from the National Library of Medicine.

References

1. Paul Graham. ANSI Common Lisp. Prentice-Hall, Englewood Clis, New Jersey 07632, 1996. 2. Ira J. Kalet, Jonathan P. Jacky, Mary M. Austin-Seymour, Sharon M. Hummel, Kevin J. Sullivan, and Jonathan M. Unger. Prism: A new approach to radiotherapy planning software. International Journal of Radiation Oncology, Biology and Physics, 36(2):451{461, 1996. 3. Jonathan Jacky and Ira Kalet. An object-oriented programming discipline for standard Pascal. Communications of the ACM, 30(9):772{776, September 1987. 4. Kevin Sullivan and David Notkin. Reconciling environment integration and software evolution. ACM Transactions on Software Engineering and Methods, 1(3):229{268, July 1992. 5. Kevin J. Sullivan, Ira J. Kalet, and David Notkin. Evaluating the mediator method: Prism as a case study. IEEE Transactions on Software Engineering, 22(8):563{579, August 1996. 6. Ira J. Kalet and Witold Paluszynski. Knowledge-based computer systems for radiotherapy planning. American Journal of Clinical Oncology, 13(4):344{351, 1990. 7. Paul Graham. On Lisp: Advanced Techniques for Common Lisp. Prentice-Hall, Englewood Clis, New Jersey 07632, 1994. 8. S. Sutlief, M. Phillips, I. Kalet, and P. Cho. Integration and veri cation of intensity modulated radiation therapy into a computer treatment planning program (Prism). In Dennis Leavitt and George Starkschall, editors, Proceedings of the Twelfth International Conference on Computers in Radiotherapy(ICCR), Madison, WI, 1997. Medical Physics Publishing. 9. Theodor D. Sterling. Natural language compilers and interpreters in radiation treatment planning or nous parlons anglais better than jede andere sprache. In Ulf Rosenow, editor, Proceedings of the Sixth International Conference on the Use of Computers in Radiation Therapy, pages 8{ 24, Gottingen, 1977. 10. Gregor Kiczales, Jim des Rivieres, and Daniel G. Bobrow. The Art of the Metaobject Protocol. The MIT Press, Cambridge, Massachusetts, 1991.

Suggest Documents