Overview

Overview

Data Input

The StructureLoader class defines a standardized interface for implementation classes which can load raw molecular data (resulting in the creation of a Structure object) into an application. This data may include atomic coordinate data, sequence data, 3D structure data, or any other data or metadata an application needs. Though the name "Structure" may imply 3D, don't let the name fool you. It not only enables an application to load a variety of data elements that the toolkit defines, but you can even define and register (on the fly) new data types that can be loaded by your own custom StructureLoader implementations.

All StructureLoader implementations have two methods in common. The load method, as you might expect, ultimately does the heavy lifting of producing a Structure (data container) object for the application. But, its the canLoad method that enables applications or other "smart" i/o components in the toolkit to probe a given StructureLoader as to its ability to load a given data set. This low-method-count architecture makes it easy to implement new loader while simultaneously enabling the toolkit to automatically select appropriate loaders when an application requests to load a data set. For example, a file-based loader (implementing the derived FileStructureLoader interface) can be used by a graphical "file open" dialog box to automatically filter out file types that the toolkit can't load while showing only files that it does know how to load. Or, for loaders which access large repositories of data sets (such as database sources) would likely use the BatchStructureLoader interface to enable the toolkit or applications to querry for a list of available data set names. With this mechanism, applications can provide a generic data set selection interface independent of the underlying BatchStructcureLoader implementation.

The bottom line is that any StructureLoader implementation simply has to answer whether it can load a given data set, and, should be able to return a Structure object when a load method is called.

While a StructureLoader implementation can be instantiated by an application and used directly to load Structure objects, the StructureFactory class provides a wrapper to enable an application to make calls to a single common interface which provides the logic to determine which loader is capable of loading a given named structure. The StructureFactory provides a central StructureLoader registry and Structure object factory. When the toolkit is initialized all built-in StructureLoader objects are automatically registered with the StructureFactory thus enabling it to handle loading of those supported data formats. Though, keep in mind that you can also add your own StructureLoader to this registry at run-time. To load a Structure given a String (ie: PDB ID), File, or URL, an application can simply call one of the static load methods in this class and it will automatically call the load method on the first loader who's canLoad method returns true.

This mechanism provides a single entry point for applications to load data and to automatically gain the ability to load from new data sources as new loaders are added to the toolkit.

This wrapper was also a nice place to add a format-independent mechanism to verify the integrity of data records. Since some loaders delay the process of parsing and loading their StructureComponent records until each record is requested, this "early verify" can be used to catch bad data before it "leaks" out into other parts of the toolkit and application.

Data Model

The Structure class provides the primary container for data in a molecular data set. It provides a purposfully simple "lists of records" data model. Each Structure may contain zero or more records ( StructureComponent objects) where each type is defined to be a subclass of StructureComponent. The StructureComponent types known by the toolkit are registered in the StructureComponentRegistry class. While the toolkit itself automatically initializes the registry with several well-known StructureComponent types (eg: Atom, Bond, Residue, Fragment, Chain, Coil, Helix, Strand, Turn, etc) new types, can also be dynamically registered by a custom StructureLoader or by application code.

The simple "list of records" data model enables programs that just want to read and process raw data to remain simple while simultaneously providing a powerful and extensible model for adding new data types and more complex data model layers on top of this basic container design.

The StructureMap class implements a derived data map for a Structure object. It generates a number of hierarchical links, indexes, and generally provides access to the numerous relationships that exists between chains, fragments (secondary structure conformations), residues, atoms, and bonds for a structure. The map enables one to "walk" a structure's backbone, and finds "gaps" in the map (ie: segments of chains which are not spanned by conformations). The set of map relationships that are managed by this class are suitable for applications and viewers to construct more spacially/biologically meaningful representations and displays.

The StructureMap class provides a number of different "entry points" to traverse the underlying structure data. The one an application should choose depeonds mostly on what the application wishes to accomplish. For example, while a basic sequence viewer might simply walk the raw list of residues (ie: by calling getResidueCount and getResidue in a loop) another sequence viewer may want to obtain residues by walking each chain (ie: by calling getChainCount, plus getChain and chain.getResidue in a nested loop) so that it knows where the residues of one chain ends and another begins. Again, its entirely up to the application.

Presentation

The StructureStyles class stores and retrieves styles associated with visible representations of objects provided by a StructureMap. A StructureStyles. object is obtained by calling the getStructureStyles method in a StructureMap instance (and a StructureMap is obtained by calling the getStructureMap method in a Structure instance).

The StructureStyles class only represents the STYLES that should be used to draw visible representations of objects. It does not specify WHAT should be drawn or HOW it should be drawn (these choices are left up to each Viewer). Also, while the set of style attributes maintained by this and subsidiary classes can provide style information for all objects that COULD be displayed by a Viewer, it does not mean that a given viewer MUST display a representation of all objects. That is, this infrastructure simply provides viewable attributes in case a Viewer chooses to create a visible representation of certain data. The use of common styles accross multiple viewers enables users to compare representations and thus correlate features between those views.

The StructureDocument class implements the top-level container for one or more Structure and Viewer objects. This class provides the container of Structure objects for MBT applications which intend to display Structure data using one or more Viewer modules.

In order view Structure data, an application will need to load one or more Structure objects (using either a StructureLoader directly or preferably the StructureFactory class). The loaded Structures can then be added to a StructureDocument instance. To begin viewing the set of structures, one or more viewers should be instantiated and similarly added to the document.

When a Structure object is added or removed from a StructureDocument, each registered viewer will automatically recieve a StructureDocumentEvent telling the viewer that a given structure was added (or removed as the case may be). It is then the responsibility of the viewer to use the structure reference to display a suitable visual representation (often this entails getting the StructureMap and then the StructureStyles object in order to display a representation using the defined colors and other visual display properties).

Viewing

The Viewer interface really doesn't provide any display functionality. Since the purpose of creating a viewer is to produce a new way of displaying data, it wouldn't make much sense to put drawing code in a base class. Furthermore, an implementor of the Viewer interface is not even required to draw anything! Think of it as just an "observer of document state". Since each viewer will recieve a StructureDocumentEvent or StructureStylesEvent when the state changes, its really left up to each implementation to present those changes in a way that makes sense for itself.

While a Viewer does not have to provide a visible interface, the toolkit does provide a number of implementations that do draw a picture. The most-used viewers that come with the toolkit are shown in the Explorer application below and include the StructureViewer (3D viewer in the lower right), the TreeViewer (the hierarchical viewer on the left), and the SequenceViewer (the 2D viewer at the top):