The OME API is an object-oriented framework for accessing information in an OME database, and for performing common workflow tasks in a consistent way. It is written in Perl, but can be called from any language via the OME Remote Framework. The Remote Framework also allows OME applications to be written in a client-server design pattern.
An overview for new OME developers is in newdevelopers
Some material about the OME Web server is available at OME::Web
Since the OME design relies heavily on extensible semantic types, almost all of the underlying database is defined via XML-based semantic type descriptors. Those tables which cannot be defined as semantic types are defined using their own perl modules.
This dichotomy is visible at the API layer, as well. Access to rows
in the core tables not defined as semantic types (or, ``database
objects'') is provided by the OME::DBObject class,
whereas access to instances of semantic types (or, ``attributes'') is
provide by the
OME::SemanticType::Superclass
class. Note that ultimiately all attributes inherit from OME::DBObject.
All OME tasks must be performed in the context of a ``session''. This requires a valid OME user to be logged in. The session saves user state, so the user will be returned to the same state next time they log in. A session is essentially permanent. Clients receive a short-lived session key which is assigned once the user logs in. In a web browser client, the session key is stored in a cookie. The key is used to 'unlock' the user's credentials on the server and reconnect a user with their session. The OME security model follows conventions from UNIX. Most OME objects (including all attributes) have both a user and group ownership. For attributes, this is inherited from the module execution that created them. For other OME objects, the user and group owner is specified in the object itself. Since most OME objects are immutable, access control applies to reading only. For more information about access control in OME, please refer to:
http://cvs.openmicroscopy.org.uk/tiki/tiki-index.php?page=Simple+DBObject-level+access+control
All database access should be done via database objects and
attributes. Arbitrary SQL should not be used except in extreme cases
where performance is a premium. Database objects and attributes are
instantiated via an OME::Factory instance, which is provided by the
active session. Since these objects are coupled to the factory that
created them, they must not be shared among sessions.
Although the OME::DBObject and
OME::SemanticType::Superclass classes
provide mutator methods, these should not be used in most cases, since
they provide direct access to the database. Rather than using these
objects to modify the underlying database tables, the workflow classes
in the OME::Tasks:: package should be used. This allows client code
to be written independent of how particular workflow tasks are
implemented.
See OME::Tasks::ProjectManager,
OME::Tasks::DatasetManager and
OME::Tasks::ImageManager for more information.
The OME Remote Framework provides access to the OME API to other languages and physical machines. For security reasons, only a portion of the API is published via the Remote Framework. It is, however, enough to fully implement an OME client program which uses an OME API-based server as its data store and which uses the workflow classes to implement its underlying functionality.
The Remote Framework is designed independent of the actual RPC
protocol used. (This means that no features specific to any RPC
protocol are used.) SOAP and XML-RPC are the currently supported
protocols. See OME::Remote for more information.
The following core tables are implemented in Perl as database objects. The name of the corresponding Perl class is given.
CONFIGURATION (OME::Configuration)
OME_SESSIONS (OME::Session)
PROJECTS (OME::Project)
DATASETS (OME::Dataset)
IMAGES (OME::Image)
FEATURES (OME::Feature)
LOOKUP_TABLES (OME::LookupTable)
LOOKUP_TABLE_ENTRIES (OME::LookupTable::Entries)
DATA_TABLES (OME::DataTable)
DATA_COLUMNS (OME::DataTable::Column)
ATTRIBUTE_TYPES (OME::SemanticType)
ATTRIBUTE_COLUMNS (OME::SemanticType::Column)
PROJECT_DATASET_MAP (OME::Project::DatasetMap)
IMAGE_DATASET_MAP (OME::Image::DatasetMap)
PROGRAMS (OME::Program)
FORMAL_INPUTS (OME::Program::FormalInput)
FORMAL_OUTPUTS (OME::Program::FormalOutput)
ANALYSES (OME::Analysis)
ACTUAL_INPUTS (OME::Analysis::ActualInput)
ANALYSIS_VIEWS (OME::AnalysisView)
ANALYSIS_VIEW_NODES (OME::AnalysisView::Node)
ANALYSIS_VIEW_LINKS (OME::AnalysisView::Link)
ANALYSIS_EXECUTIONS (OME::AnalysisExecution)
ANALYSIS_NODE_EXECUTIONS (OME::AnalysisExecution::NodeExecution)
An accessor/mutator method is defined for each column in the table. The method's name is the same as the columns name, but in lowercase. If a column is a foreign key to another core table, then its accessor/mutator method will expect values of the corresponding database class, not primary key values. Further, a foreign key method will have any trailing ``_id'' removed from the method name.
Attributes are handled differently than database objects, since they
are user-defined. Since an attribute is not well-defined without its
semantic type definition, you must first load the appropriate row from
the SEMANTIC_TYPES table (using the database object interfaces
described in the previous section). You can then use this
SemanticType object with the factory object to load attributes of
that type. These routines dynamically generate a subclass of
OME::SemanticType::Superclass for the
semantic type, and creates accessor/mutator methods for all of the
semantic elements. The methods have the exact same name as the
semantic elements, including case. If a semantic element is a
reference to another semantic type, the method will expect values of
the corresponding attribute class. The method name will remain
unchanged.
The following core semantic types will almost certainly be used by any OME client program:
Experimenter
Group
Repository
Dimensions
Pixels
These examples are written in Perl. Except for the act of opening and closing a session, the Remote Framework uses the exact same method calls.
1. my $username = "omeuser";
2. my $password = "password0";
3. my $manager = OME::SessionManager->new();
4. my $session = $manager->createSession($username,$password);
5. my $factory = $session->Factory();
6. my $image = $factory->loadObject("OME::Image",1);
7. print $image->name(),"\n";
Lines 1 and 2 would, of course, be replaced by whatever code is
necessary to get a username and password from the user.
Line 3 loads in a session manager, and then line 4 uses it to create a session for
the user
(see the TTYlogin() method in OME::SessionManager).
Line 5 obtains the factory for the newly created session,
and line 6 uses it to load in the row in the IMAGES table with a
primary key ID of 1. Line 7 prints this image's name to standard out.
Note that this example does absolutely no error-checking. A null value (undef in Perl) would be returned by line 4 if the username and password were invalid, or if there was some other problem connecting to the OME server. Line 6 would also return a null value if there was no image in the database with an ID of 1. In each of these cases, Perl would die with an error on the following line, when the code tried to call a method on the null value.
1. my $username = "omeuser";
2. my $password = "password0";
3. my $manager = OME::SessionManager->new();
4. my $session = $manager->createSession($username,$password);
5. my $factory = $session->Factory();
6. my $image = $factory->loadObject("OME::Image",1);
7. my @pixelses = $factory->findAttributes("Pixels",$image);
8. foreach my $pixels (@pixelses) {
9. my $repository = $pixels->Repository();
10. my $rPath = $repository->ImageServerURL();
11. my $iPath = $pixels->ImageServerID();
12. my $getInfoURL = $rPath."?Method=PixelsInfo&PixelsID=".$iPath;
13. print "$getInfoURL\n";
14. }
Lines 1 and 2 would, of course, be replaced by whatever code is
necessary to get a username and password from the user. Line 3 loads
in a session manager, and then line 4 uses it to create a session for
the user
(see the TTYlogin() method in OME::SessionManager).
Line 5 obtains the factory for the newly created session,
and line 6 uses it to load in the row in the IMAGES table with a
primary key ID of 1.
Line 7 loads in all of the Pixels attributes corresponding to the image. For each set of pixels, line 9 loads in the repository object corresponding to where those pixels are stored. Line 10 gets the repository's URL (the OMEIS URL), and line 11 gets the ID for these pixels in the repository. Lines 12-13 concatenate the two together to generate a URL that gets information about these pixels from the image server, and prints the URL to standard output.
You can copy/paste this URL into your
web browser or enclose it in single quotes and send it to the curl command-line
program (or use Perl's LWP module to issue the request). OME provides a perl module
to issue OMEIS requests. You can generate an OMEIS object corresponding to the
Pixels attribute (a OME::Image::Server::Pixels object):
my $omeis_pixels = OME::Tasks::PixelsManager->serverLoadPixels($pixels);
See documentation about the OME::Tasks::PixelsManager class.
As in example 1, no error-checking is performed.
Douglas Creager (dcreager@alum.mit.edu)
OME::DBObject, OME::SemanticType, OME::Factory, OME Module Table of Contents, Index