OpendTect overview

Intro | Modules | Starting

Intro

Very short

OpendTect:

  • Is in C++ and a tiny bit of C
  • Uses CMake, which makes it easy to port across platforms
  • Is built with design principles and strict separations of functionality
  • Uses exclusively open source tools
  • Can be extended using plugins

C++

OpendTect is a C++-based environement. A couple of years ago, C++ was declared dead by many as a result of the Java hype. In some areas, Java is indeed far better suited. In our part of the world (geosciences, in particular geophysics-related), we don't think Java can match the advantages of C++: Fast yet flexible, Low-level yet supporting high-level OO constructs. And, we would be terrified having to program without templates.

That doesn't mean that programming in C++ automagically delivers good software, and neither that performance comes easy. Those are some of the things that can be reached by a good design.

Design principles

There are many aspects of software that can be categorised as 'good'. These include robustness, flexibility, high performance, compactness, maintainability, understandability. Software engineering is all about making choices - every aspect costs resources and there's always a limit to that. So, even if one tries to optimise all 'good' aspects, there will be different degrees of emphasis on each of them.

As OpendTect was developed in a research-minded environment, flexibility is a high priority. The Object-Oriented toolkit delivers many tricks to make software more flexible. Some of these tricks nowadays have labels - 'Design patterns' - like the ones in the 'Design Patterns' book (Factories,Singletons,etc.). Many constructs in the software are fit to match the problem though, always with a number of design principles in mind:

  • OCP Open/Closed: classes and modules should be open for extension, but closed for modification.
  • SRP Single responsibility: only one class or module does one thing well and complete.
  • LSP Substititutability: inheritance for interfaces makes classes substitutable.
  • DIP Dependency inversion: depending on abstract base classes inverts dependencies from high-level on low-level into dependency on stable high-level abstractions.
  • DIF Don't Implement the Future: All source code present should actually be used now.
  • NBS No BullShit: Create constructs if needed, not because they're cool or anything.

The last two are, [cough] of our own making. DIF ensures that there are no large amounts of unused code lying around to be maintained, NBS delivers a system that is as simple as possible given the constraints.

You may also want to look at the design/coding rules.

Isolation of external services

When services from another package (Qt, OpenSceneGraph, ...) are used, there is always an isolating layer - either a complete module or a class that uniquely uses those services. For software engineers this is an obvious action were it only to reduce the dependency problems.

There is however more to it. External services tend to be designed for much more general purposes than what is needed by OpendTect. Furthermore, some services that will be very important for us won't be available. And, we may not like the form in which the services are presented; moreover, the data structures used in the external package seldomly fit nicely with ours.

To overcome all this, and get a nice insulation at the same time, all external services are embedded in service layers that:

  • Do exactly what we need
  • Don't expose the external package's header files
  • Use data structures that are common in OpendTect

Isolation like this is present for a variety of subjects, from threads, sockets, file handling to User Interface building and Data loading.

Open source

OpendTect is based on a couple of external packages, which are mostly open source. These include:

  • Qt from The Qt Company
  • OpenSceneGraph from OpenSceneGraph.org
  • GNU tools (gmake, gcc) from FSF
  • CMake from CMake.org
  • Doxygen from Doxygen


Modules

Intro

A group of classes that handle a certain area of our domain is what could be called a module. Sometimes these modules have their own namespace, most often not (sometimes because the code pre-dates good support of namespaces by gcc). In any case, it does correspond with two physical directories in the source tree: include/module_name and src/module_name. Thus earth model related classes go in the EarthModel directories.

The separation

The separation of include and src is first of all a visibility issue. The include files can be 'seen' by other modules, the src files not. Conceptually, the separation is roughly interface versus implementation. Roughly, because small functions are often implemented in the header file.

Another separation that is very important is between UI- and 'Real Work' modules. No (direct) user interface work is done in the RW-modules. The amount of Real Work in the UI modules is minimised. Within the user interface part, there is a separation between basic UI (Qt-based in OpendTect) and 3D visualistion (OpenSceneGraph-based). Both types of user interface modules have a prefix: 'ui' and 'vis' respectively.

Making all these modules as opposed to just dumping everything in one big directory does have the effect that it becomes necessary to precisely know what's dependent on what. That's exactly what's described in the data/ModDeps.od file. This file is used by OpendTect to automatically load module libraries.

RW modules

First of all, there are the Basic, Algo and General modules. General depends on Algo, which in turn depends on Basic. The separation is a bit arbitrary, and the idea was that Basic would be tools also usable outside OpendTect. It's easy to find a counterexample like survinfo which was placed there to provide other Basic classes with good defaults.

In any case, Basic handles basic stuff like file-related, extra string utils, Ascii keyword-value files, positions (coords, inline/crossline), our own 'string' class the BufferString (not just a relict: it works better with C environments), sets: TypeSet, ObjectSet and BufferStringSet, OS dependent things like threads, stream opening, and a variety of basic algorithms.

Algo is for, well, Algorithmic stuff. General handles all sorts of things, like fast dynamic large N-D arrays (ArrayND etc.), the CBVS format for volumestorage, the IOObj, IOMan and other data store related classes, Translators enabling different formats, transforms and a few more things.

The domain-specific modules like Well, EarthModel, Seis etc. will be recognized by a geoscientist. There's also the Attribute and AttributeEngine, the seismic attribute modules, and the engine that does the work.

UI modules

For most of the RW-modules, there is a UI counterpart. This is made possible by the basic UI modules uiBase, uiTools and uiIo, the basic 3D visualisation module visBase and the basic combined stuff in uiOSG. On top of everything is the UI application logic in uiODMain.

The uiBase module is one of the two modules that access Qt services. Where uiOSG specifically handles the bridge bewteen Qt and OpenSceneGraph, uiBase is Qt only. These two are therefore isolation layers. uiBase's main task is to provide access to Qt widgets and implement the dynamic layout concept. In short, the OpendTect user interface was not painted with a paint tool, but rather programmed by attaching elements to each other. See the uiBase class documentation.

The uiTools module depends on uiBase only. It provides some general UI elements from the uiBase basic objects. Most notably, the uiGenInput class, providing generalised data input.

The uiIo module is intended mainly for object selection (in the data store).

The OpenSceneGraph-based visualisation services are made available in the visBase layer. Based on that, visSurvey delivers OpendTect-specific functionality.

It all comes together in the uiODMain module. Being the top level module it is dependent on all other modules. To keep the amount of knowledge contained in this module low, much of the functionality is obtained from the 'UI Part servers'. For example, the uiSeisPartServer is the isolation class for all seismic-related user interface work. The uiODApplMgr object is only coordinating the flow of information between the various part servers.



Starting the programming

Preconditions

Before you start, get a good development environment by using the 'Utilities-Create Devel. Env.' menu. When that's finished, you must run CMake. Then you should be able to start developing right away.

Making it happen

Along the way, you'll have to do some digging in the include directory or the class documentation to figure out what services are available. You probably won't want to miss the info from the UNIX or windows instruction documentation. The plugin manual, well, see for yourself. If all you want to do is make batch programs, try batch program doc. And if all else fails, you may even consider sending an e-mail to support@opendtect.org .


Index | Rules | Plugins | Attributes | UNIX | MS Windows | opendtect.org