Getting Started Documentation Glish Learn More Programming Contact Us
Version 1.9 Build 1556
News FAQ
Search Home


next up previous contents
Next: Astronomical Calibration and Imaging Up: The Design of AIPS++ AIPS++ Implementation Memo 111 Previous: Introduction

Subsections



Guiding Principles

Goals

The AIPS++ project has a mission statement ([Hun93]). Somewhat simplified, the portions of it which have design ramifications are:

It is probably worthwhile quoting verbatim the final point of the mission statement:

``15. In summary, AIPS++ shall be programmed to be flexible and versatile to use, to modify, and to enhance. Researchers other than the main support staff shall be invited and encouraged to add applications and functionality.''

Some other issues related to the implementation of these goals by the AIPS++ project are described in [RJ94].

Object-oriented (OO) programming

A fundamental decision was made to use object oriented concepts in designing and implementing AIPS++. Largely because of the requirement for portability, C++ was chosen as the implementation language. While C++ implementations presently tend to be immature and painful to use, on balance it has been a suitable choice.

Object oriented design and implementation offers some major benefits. Probably the primary advantage is that of encapsulation. Encapsulation imposes the discipline that data can only be modified through a well defined and consistent interface. The unit of encapsulation in C++ is the Class, which is (more or less) the same thing as a type. With encapsulation, if only the implementation of functionality needs to be changed, but not its interface, then no source code changes outside the class need be considered (i.e., changes in implementation are localized).

In a sense, adding classes to an OO language can be considered to be tuning the language to the problem domain (especially in a language like C++ which has syntactic sugar such as operator overloading).

Another advantage of OO is inheritance: the ability to create a new derived class by adding on to an existing class.

Much more important than inheritance is polymorphism, which allows classes with a sufficiently similar interface to substitute for one another. This allows, for example, a new kind of clean deconvolution to be introduced without having to change any client code that needs such deconvolution. That is, not only does a class interface hide its own implementation, it can also hide the details of exactly what class is being used, allowing the class in question to be substituted without causing changes in the clients.

In C++, polymorphism is achieved through inheritance (derived classes may substitute for base classes) and templates.1

The above short summary cannot hope to do justice to the subject. For more details on OO design and programming in general see [Boo91,Mey88,RBP$^$91]. For an introduction to C++ by the creator of the language, see [Str91]. For an excellent description of the C++ idioms necessary to build a complex, real-world system, see [BN94].

Reusable software libraries

The gems of any software project are its application-domain algorithms and unique support structures. It is vital that these be reusable, not constantly reinvented.

The primary consequence of this is that application-domain expertise should be available in libraries, not ``locked up'' in an executable. Functionality which is only available through an executable is only able to serve those needs the application programmer was able to foresee.

Applications should thus be fairly simple. In some sense they are merely a convenient packaging of some aspects of a library. At the very least, functionality should at least be put into application specific classes and functions which can later be migrated to a library.

Multi-level programming

Users and programmers will want to approach programming in AIPS++ in a variety of ways:

Parallel to the above programming levels (``how much stuff is done by each line of code'') are levels that correspond to how much of an underlying model (e.g., a calibration and imaging model) the programmer has to accept.

Since there are certain to be disagreements about such models, programmers who are too impatient to learn them, and new instruments or disciplines that do not fit them; it is important that such programmers be accommodated.

To accommodate such programmers, the actual computations they might need must be available at a mid-level. For example, rather than having CLEAN embedded solely in a high-level ``Measurement model,'' the actual computational kernel should be available in mid-level classes that work on arrays and/or images. Irrespective of other concerns, such layering is good software practice.

The X-Windows system has a similar problem and solution. The core functionality is encapsulated in policy-free libraries, and the higher level ``models'' are encapsulated in additional libraries (Motif) and entities (e.g., window managers).


Access to data

A decision which has caused some controversy is that all3 AIPS++ data should reside in a common data structure, the AIPS++ Table (described in section 4). This decision allows several important capabilities:

It is certainly true that the user can get into trouble by arbitrarily modifying tables (since software might not understand what to do with those tables if sufficiently changed). However, the alternative is worse; after all the data does belong to the user, and sometimes scientific exploration will require operations that no software system can anticipate.

Other goals

While the following run the danger of being non-controversial statements of motherhood and apple pie, perhaps they will be of some use written down:

Flexible
It should be possible to use the classes to build unanticipated applications. Ideally this should be possible both from compiled languages and an interactive command line interpreter. Flexibility implies generality at some level, e.g., tools should be N-dimensional when possible.

Efficient
Our production codes must be about as efficient as the ones they are replacing. It is acceptable to recode critical sections with less flexible functions if necessary to achieve this. This most critically constrains the data system.

Portable
There are several types of portability that are important. The software must be portable to various computers and architectures. This implies that the use of host features that can't be emulated on other systems should be avoided for the core system. Until there is a C++ standard, portability between compilers needs to be addressed.4 Data needs to be portable at run time on different host architectures, which we solve by storing that data in a canonical format. Data also needs to be portable to other software systems, including those in the future, which means storing offline data in an archival format, i.e., FITS.

Implementable
We have an ambitious project with relatively modest resources; at times this will imply that we must implement a subset of the functionality we would actually like.


next up previous contents
Next: Astronomical Calibration and Imaging Up: The Design of AIPS++ AIPS++ Implementation Memo 111 Previous: Introduction   Contents
Please send questions or comments about AIPS++ to aips2-request@nrao.edu.
Copyright © 1995-2000 Associated Universities Inc., Washington, D.C.

Return to AIPS++ Home Page
2006-10-15