Geneious 2024.0.5 Public API
Geneious Public API Contents
- Introduction
- Getting Started - Choosing your plugin type
- Getting Started - Compiling and building your plugin
- Documents in Geneious
- Important classes in the API
- FAQ
- How do I add an item to the menu bar or toolbar?
- How do I popup a dialog for user input?
- How do I get all documents in the same folder as a given document?
- How do I get all documents in the user's local database?
- How do I export to any document format supported by Geneious?
- How do I import any document format supported by Geneious?
- How do I add a document to the user's database?
- How do I add annotations to a sequence?
- How do I allow my plugin to depend on external libraries or resources?
- How do I create a log file from within my plugin?
- How do I write unit test cases for my plugin?
- How do I invoke other plugin operations?
- API Packages
Introduction
The Geneious Public API is a rich and powerful API that allows to create a wide variety of plugins. In fact most of the functionality provided by Geneious is actually just a set of plugins bundled with the Geneious distribution that interact with the core Geneious platform and with each other via the Public API. Examples of plugins in Geneious include the sequence viewer, sequence alignment operation, primer design, the sequence logo graph, the NCBI databases, agents, and even the user's local database. The architecture of Geneious is centered around the concept of documents which are stored in either a local or shared database. Operations can modify documents or create derived documents using existing documents as input. Viewers provide a system for visualization and sometimes editing the contents of one or more documents.Getting Started - Choosing your plugin type
The first thing to decide upon when writing a plug-in is what type of plug-in you want. AllGeneiousPlugins
fall
under one of the following categories. There is an example plug-in for many of these categories included with the
API distribution.
-
SequenceAnnotationGenerators
integrate into the SequenceViewer to provide an entry in the tools popup menu to generate annotations on the currently selected sequence(s). The SequenceViewer plugin handles all associated necessary behaviour such as providing undo functionality and saving the generated annotations to disk. Examples of SequenceAnnotationGenerator plugins in Geneious include primer design, restriction analysis, ORF finding, and motif finding.
Example Source Code: ExampleSequenceAnnotationGenerator -
DocumentOperations
allow the creation of a new document(s) from an existing document(s) (or from no documents). The DocumentOperation specifies its location in the menu or toolbar along with a signature specifying what type of documents it operates on and Geneious handles invoking the DocumentOperation and saving any generated documents to disk. Examples of DocumentOperation plugins in Geneious include Set Paired Reads and tree building.
Example Source Code: ReverseSequence, BackTranslationPlugin -
Assemblers
allow the implementation of a read mapper, reference assembler or de novo assembler. Assemblers could be implemented as DocumentOperations but this API provides a simpler API tailored for assemblers. Examples of Assembler plugins in Geneious include Geneious Reference Assembler, Geneious De Novo Assembler and Velvet (on Geneious Server only)
Example Source Code: ExampleAssembler -
AlignmentOperations
allow the implementation of an alignment algorithm. AlignmentOperations could be implemented as DocumentOperations but this API provides a simpler API tailored for alignment. Examples of AlignmentOperation plugins in Geneious include Geneious Aligner, Muscle and ClustalW
Example Source Code: ExampleAlignmentOperation -
DocumentViewers
allow the viewing of 1 or more documents. DocumentViewers specify a signature of the types of documents they can view and Geneious displays the DocumentViewer each time the user selects documents matching it's signature. Examples of DocumentViewer plugins in Geneious include the sequence viewer, the tree viewer, and the dotplot viewer.
Example Source Code: ExampleDocumentViewer -
SequenceGraphs
allow displaying of graphs on sequences inside the sequence viewer. Examples of SequenceGraph plugins in Geneious include the identity graph, the sequence logo graph, and the chromatogram graph.
Example Source Code: ExampleSequenceGraph , ExampleSequenceGraph2 -
GeneiousServices
allow entries in the sources panel on the left hand side of the main Geneious window. Typically these are databases providing access to local or external sequences. Examples of GeneiousService plugins in Geneious include the local database and the NCBI services.
Example Source Code: ExampleGeneiousService -
DocumentFileImporters
provide support for importing various file formats into Geneious. Examples of DocumentFileImporter plugins in Geneious include the fasta importer, GenBank importer, and nexus importer.
Example Source Code: ExampleFastaImporter , TextFiles -
DocumentFileExporters
provide support for exporting documents from Geneious into various file formats. Examples of DocumentFileExporter plugins in Geneious include the fasta exporter, GenBank exporter and nexus exporter.
Example Source Code: ExampleFastaExporter , TextFiles -
TreeViewerExtensions
provide support for extending the functionality of the Tree Viewer. The standard Geneious distribution does not include plugins of this type, but the 3rd party Species Delimitation plugin available from the Preferences->Plugins window is an example of this.
Example Source Code: ExampleTreeViewerExtensionPlugin -
SequenceViewerExtensions
provide support for extending the functionality of the Sequence/Alignment/Contig Viewer. For example with statistics, toolbar buttons or new components. Examples of SequenceViewerExtensions plugins in Geneious include the annotations table and many of the statistics in the sequence viewer.
Example Source Code: ExampleSequenceViewerStatistics
Getting Started - Compiling and building your plugin
The easiest thing to do is run one of the examples using a supported IDE. More information about how to do this is available in the setup.html file that is included with the plugin development kit. Once you are comfortable with this choose an example plugin that most closely matches the plugin you want to create (see Getting Started - Choosing your plugin type), optionally rename the example using thecopyPluginAndRename
Ant task, and start modifying it to achieve the functionality you want.More information on building and distributing your plugin can also be found in the setup file.
Documents in Geneious
A document is an item that appears in the table listing the contents of a folder. There are 2 super-classes in the API that are used when handling documents.PluginDocument
is the interface
which most other document types
such as SequenceDocument
,
TreeDocument
or
PublicationDocument
extend.
PluginDocuments are however
not stored directly in the user's database. Instead these are wrapped in the top-level AnnotatedPluginDocument.
AnnotatedPluginDocument
decorates all PluginDocuments with additional functionality, such as allowing custom notes to be added
to documents, and allowing the user to edit displayed field values without the PluginDocument
implementations needing to worry about providing this sort of functionality. A plugin never implements
or subclasses AnnotatedPluginDocument.
In many situations,
plugins can ignore the functionality provided by AnnotatedPluginDocument
and instead just directly access the wrapped PluginDocument from an AnnotatedPluginDocument using
AnnotatedPluginDocument.getDocument()
or
creating a AnnotatedPluginDocument from a PluginDocument using
DocumentUtilities.createAnnotatedPluginDocument()
.
Defining your own document types
While the Geneious Public API provides a range of document interfaces and implementations, sometimes it is necessary to create your own document types or extend the functionality of the existing types. Usually this is only necessary if you are creating a plugin which provides multiple types of functionality - for example you wish to create a document operation that generates your own custom data types, and provide a document viewer to view those data types. Geneious allows you to do this by directly implementing thePluginDocument
interface. A plugin can also define additional static properties (such as icons) associated with new
PluginDocument types using GeneiousPlugin.getDocumentTypes()
.
Important classes in the API
In addition to the GeneiousPlugin and the various plugin type classes (see choosing your plugin type), and the Geneious document system (see documents in Geneious), there are a number of important or widely used classes in the Geneious API you should become familiar with.Options
- Many types of plugins will need to use Options as the way of prompting for user input. Make sure you read the top-level documentation in this class to see what Options is capable of.GeneiousActionOptions
- The description, icon and location of a menu item or button to invoke a plugin or functionality within a plugin.SequenceDocument
- Any plugin that deals with nucleotide or amino acid sequences should be aware of this. Also seeDefaultSequenceDocument
which is the most widely used SequenceDocument implementation.SequenceCharSequence
- The nucleotides or amino acids in a SequenceDocument are often stored in a SequenceCharSequence instead of a String for both more efficient memory usage, and for efficient representation of end gaps in an alignment.SequenceAnnotation
- is used to represent features or annotations on a SequenceDocumentSequenceTrack
- is used to represent a collection of SequenceAnnotations on a SequenceDocumentSequenceListDocument
- SequenceDocuments are often grouped into a single SequenceListDocument.DefaultSequenceListDocument
is the most widely used SequenceListDocument implementationSequenceListOnDisk
- The list of nucleotide sequences returned fromSequenceListDocument.getNucleotideSequences()
is often a SequenceListOnDisk where the sequences represent a large number of sequencing reads. The SequenceDocuments obtained from this list are loaded on demand and for optimal performance code should iterate over the list in order. Note that collections of chromosome sized sequences are usually not a SequenceListOnDisk. Instead the SequenceDocuments in these lists are loaded along with the SequenceListDocument, but theSequenceCharSequence
andSequenceTracks
within those sequences are loaded later on demand.SequenceAlignmentDocument
- Alignments and contigs are both represented using a SequenceAlignmentDocument which is most commonly implemented using aDefaultAlignmentDocument
ProgressListener
- although this is from the JEBL package which Geneious depends on, it is very widely used throughout Geneious for operations to report progress and allow the user to cancel them.
Dialogs
- methods for displaying dialogsFindable
- AllowsDocumentViewer
to easily implement 'Find' functionalityEndGapsManager
- Given a set of aligned sequences, provides methods for quickly finding all sequences that intersect a given base number, ignoring those sequences in end gap regions.PairedReads
- Provides distance and orientation of paired/mate sequencing readsSequenceGapInformation
- Precalculates information about the location of gaps ('-') in a CharSequence, and can efficiently calculate translate between indices in the gapped and ungapped sequenceCombinedAlignmentAndSequenceDocument
- a document which contains both a stand-alone sequence and an alignment. Typically used in sequence search resultsImmutableSequence
- an very compact (in memory and on disk) implementation of aSequenceDocument
SequenceListSummary
- provides details about the sequences and annotations in a large sequence list or alignment/contig without needing to iterate over the entire listSequenceSelection
- provides details on the currently selection regions in the sequence viewer to DocumentOperations, AnnotationGenerators and other DocumentViewersDocumentViewerMessageHandler
- provides a system for DocumentViewers to interact with each otherOperationRecordDocument
- provides details about the relationships between documentsFolderViewDocument
- a hidden document attached to the folder of a sequence search resultStandardIcons
- set of standard icons used in Geneious. Use of these in 3rd party plugins is encouraged to keep the look consistent.WritableDatabaseService
- the local and shared Databases in Geneious are both WritableDatabaseServices. Each document stored in a database exposes its location viaAnnotatedPluginDocument.getDatabase()
CallSoon
- Provides a system for invoking a Runnable shortly in the Swing thread with optional coalescing of multiple calls and an optional delay until the runnable is invokedDocumentNoteUtilities
- management of custom notes on documentsDocumentUtilities
- utility methods for handlingAnnotatedPluginDocuments
PluginUtilities
- utility methods for handling interaction with other pluginsImportUtilities
- utility methods for importing documents and various file formats into GeneiousSequenceUtilities
andCharSequenceUtilities
- utility methods for handlingSequenceDocuments
and the char sequences (SequenceCharSequence
) within themSequenceExtractionUtilities
- utility methods for handling extracting sub-sequences fromSequenceDocuments
PluginDocument.FILE_DATA_ATTRIBUTE_NAME
- provides a system for efficient serialization of binary data in PluginDocumentsFileUtilities
,StringUtilities
,GuiUtilities
,SystemUtilities
,IconUtilities
,GeneralUtilities
- various non-bioinformatics utility classes whose names should be self explanatory.
FAQ
How do I add an item to the menu bar or toolbar?
This depends on what you will use it for. If it is intended for generating annotations on a sequence, useSequenceAnnotationGenerator
.getActionOptions()
.
Otherwise use DocumentOperation
.getActionOptions()
.
If your menu item is not intended to apply an action to any documents, you should still use a DocumentOperation
,
except it should return an empty selection signature to indicate it accepts no input documents.
DocumentOperation.getActionOptions() {
return new GeneiousActionOptions
("My Action").setMainMenuLocation(GeneiousActionOptions.MainMenu.Tools).setInMainToolbar(true).setInPopupMenu(true);
}
How do I popup a dialog for user input?
This is usually done as part of aSequenceAnnotationGenerator
or DocumentOperation
by returning
Options
from
SequenceAnnotationGenerator.getOptions()
or
DocumentOperation.getOptions()
.
publicAlternatively, if you wish to popup a dialog independent of aOptions
DocumentOperation.getOptions(AnnotatedPluginDocument... documents) throws DocumentOperationException { Options options=new Options(getClass()); options.addBooleanOption
("reverseComplement","Reverse Complement",false); options.addStringOption
("name","Name","Default Name"); return options; }
SequenceAnnotationGenerator
or DocumentOperation
then do something like this
Options options=new Options(getClass()); Options.BooleanOption reverseComplement = options.addBooleanOption("reverseComplement", "Reverse Complement", false); Options.StringOption name = options.addStringOption("name", "Name", "Default Name"); if (Dialogs.showOptionsDialog(options,"Title",true)) { // returns true if user clicked OK. if (reverseComplement.getValue()) { System.out.println("Reverse complement selected and name="+name.getValue()); } }
How do I get all documents in the same folder as a given document?
AnnotatedPluginDocument document; List<AnnotatedPluginDocument> documentsInSameFolder = document.getDatabase()
.retrieve
(Query.Factory.createBrowseQuery
(), ProgressListener.EMPTY);
How do I get all documents in the user's local database?
WritableDatabaseService
database= (WritableDatabaseService) PluginUtilities.getGeneiousService
("LocalDocuments"); List<AnnotatedPluginDocument> documentsInEntireDatabase = database.retrieve
(Query.Factory.createQuery
(""), ProgressListener.EMPTY); List<AnnotatedPluginDocument> documentsInRootFolderOnly = database.retrieve
(Query.Factory.createBrowseQuery
(), ProgressListener.EMPTY);
How do I export to any document format supported by Geneious?
SequenceDocument sequence=newDefaultNucleotideSequence
("Name","","GATTACA",null); AnnotatedPluginDocument document = DocumentUtilities.createAnnotatedPluginDocument
(sequence); PluginUtilities.exportDocuments
(new File("a.fasta"),document);
How do I import any document format supported by Geneious?
List<AnnotatedPluginDocument> docs = PluginUtilities.importDocuments
(new File("a.fasta"), ProgressListener.EMPTY);SequenceDocument
sequence = (SequenceDocument) docs.get(0).getDocument
(); System.out.println("Sequence String="+sequence.getSequenceString
());
How do I add a document to the user's database?
Normally you wouldn't do this directly. Instead use aDocumentOperation
to generate documents. But if
this doesn't suit your plugin needs, you could do something like this which creates
a folder in the user's database, adds a new document to it, and selects that document.
SequenceDocument sequence=newDefaultNucleotideSequence
("Name","","GATTACA",null); AnnotatedPluginDocument document = DocumentUtilities.createAnnotatedPluginDocument
(sequence);WritableDatabaseService
database= (WritableDatabaseService) PluginUtilities.getGeneiousService("LocalDocuments"); WritableDatabaseService folder = database.createChildFolder
("My Folder"); document = folder.addDocumentCopy
(document, ProgressListener.EMPTY); DocumentUtilities.selectDocument
(document.getURN());
How do I add annotations to a sequence?
Normally you wouldn't do this directly. Instead use aSequenceAnnotationGenerator
which integrates creating
annotations into the sequence viewer and manages undoing and saving. But if you need to do it yourself, here is how:
AnnotatedPluginDocument document; // This is assumed to be an editable sequence document that is already in the user's database.SequenceAnnotation
annotationToAdd = new SequenceAnnotation("Name", SequenceAnnotation.TYPE_CDS, new SequenceAnnotationInterval(3,10));EditableSequenceDocument
sequence = (EditableSequenceDocument) document.getDocument
(); List<SequenceAnnotation> annotations= new ArrayList<SequenceAnnotation>(sequence.getSequenceAnnotations
()); annotations.add(annotationToAdd); sequence.setAnnotations
(annotations); document.saveDocument
();
How do I allow my plugin to depend on external libraries or resources?
For accessing external resources such as data files your plugin should be distributed as a zip file with extension .gplugin containing only a single folder named exactly the same as the fully qualified name of your GeneiousPlugin class. This folder must then contain your plugin jar file (can have any name) and any other files your plugin uses. This folder will be given to your plugin at runtime through the pluginDirectory parameter of theGeneiousPlugin.initialize
method.
See ExampleGeneiousService plugin for an example that bundles a data file.
To depend on an external library jar file, also just bundle that alongside your plugin's jar file.
Geneious automatically adds all jar files in your plugin's directory to your plugin's class-loader. However,
in rare cases you may find this doesn't work as the external library may try to find classes using the
system or thread class-loader instead of the class-loader they
were created from. If the external library is using the current thread class-loader, wrapping calls
to the external library from within your plugin like in the following code fragment may help:
final ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader(); try { Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); // Code that calls a problematic external library method goes here. } finally { Thread.currentThread().setContextClassLoader(oldContextClassLoader); }
How do I create a log file from within my plugin?
You can use Java's standard logging system (see java.util.logging). You can specify your logging properties file in the Geneious virtual machine options file.-
On Windows, this is
Geneious.vmoptions
inside your Geneious installation directory. Each command line option should be separated by a new line. For example, your VM options file may contain:-Xmx500M -Djava.util.logging.config.file=c:\temp\logging.properties
-
On MacOS, this is
Info.plist
in theContents
folder inside the Geneious.app bundle (Ctrl+Click on Geneious and selectShow package contents
). OpenInfo.plist
using the default program (Property List Editor.app) and go in to theJava
then theProperties
node. Change the keyjava.util.logging.config.file
to contain the path to your logging properties file, eg:/Users/richard/logging.properties
.level=WARNING com.biomatters.level=INFO your.package.name.level=FINE handlers=java.util.logging.FileHandler java.util.logging.FileHandler.append=true java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter java.util.logging.FileHandler.pattern=c:\\temp\\geneious.logReplacing your.package.name with your package name. And in your source code you would use a line like:
Logger.getLogger(getClass().getName()).fine("Hello World!");
How do I write unit test cases for my plugin?
Geneious provides the classTestGeneious
to facilitate
writing test cases. If you add all Geneious libraries to your classpath, then you can use
TestGeneious.initialize
to initialize
many of the methods in the public api that would otherwise only work from within the Geneious application.
For example DocumentUtilities.createAnnotatedPluginDocument
requires TestGeneious.initialize() to have been called. If your plugin test case itself needs to depend on other
plugins, then TestGeneious.initializeAllPlugins
initializes all
plugins so that methods such as PluginUtilities.getDocumentOperation
can be used to obtain references to other plugins. You may also find TestGeneious.isRunningTest
useful.
In a rare case that you want to test your plugin when it is instantiated from the Geneious plugin loading environment (rather
than just running from class files), then if you build and copy your plugin to the Geneious plugins folder then your test case
could use TestGeneious.initializePlugin
to load your plugin and can then use PluginUtilities.getClass
to obtain a reference to your class and call any testing methods on it you need to.
How do I invoke other plugin operations?
Sometimes you may want to make use of functionality provided by other plugins when implementing your own plugin. First your plugin needs to get a reference to the functionality provided by another plugin usingPluginUtilities
and it can then proceed to make use of the plugin.
- Getting a reference to the other plugin.
EachDocumentOperation
andSequenceAnnotationGenerator
has a unique ID. (DocumentOperation.getUniqueId()
andSequenceAnnotationGenerator.getUniqueId()
). As long as you know the uniqueID of the operation or annotation generator you can usePluginUtilities.getDocumentOperation()
orPluginUtilities.getSequenceAnnotationGenerator()
to get a reference to it. To view a list of all available uniqueIds, use the following code fragment:
StringBuilder builder = new StringBuilder(); builder.append("Document Operations:\n"); for (DocumentOperation operation : PluginUtilities.getDocumentOperations()) { builder.append(operation.getActionOptions().getName()+" has id: "+operation.getUniqueId()+"\n"); } builder.append("\n\nAnnotation Generators:\n"); for (SequenceAnnotationGenerator generator : PluginUtilities.getSequenceAnnotationGenerators()) { builder.append(generator.getActionOptions().getName()+" has id: "+generator.getUniqueId()+"\n"); } String message=builder.toString(); Dialogs.showMessageDialog(message);
- Using the other plugin.
Once you have a reference to your document operation or annotation generator, you could do something like this to use it:
SequenceAnnotationGenerator primerDesign = PluginUtilities.getSequenceAnnotationGenerator("com.biomatters.plugins.primerDesign.PrimerDesignAnnotationGenerator"); SequenceDocument sequence = new DefaultNucleotideSequence("Name","","GATTACA",null); AnnotatedPluginDocument sequenceDocument = DocumentUtilities.createAnnotatedPluginDocument(sequence); SequenceAnnotationGenerator.SelectionRange selectionRange = new SequenceAnnotationGenerator.SelectionRange(0, 0, 0, sequence.getSequenceLength() - 1); Options options = primerDesign.getOptions(selectionRange, sequenceDocument); options.setStringValue("MAXIMUM_NUMBER_OF_NON_MATCHING_SEQUENCES","2"); List<SequenceAnnotation> annotationsList = primerDesign.generateAnnotations(selectionRange, ProgressListener.EMPTY, options, sequenceDocument).get(0);
CallingOptions.setStringValue()
requires knowledge of what options are available. For a given Options instance, callingOptions.getDescriptionAndState()
lists all supported option values. For example,Dialogs.showMessageDialog(StringUtilities.escapeHtmlCharacters(options.getDescriptionAndState()));
in the above example would list all the options you could set when generating primers.
Package | Description |
---|---|
com.biomatters.geneious.publicapi | |
com.biomatters.geneious.publicapi.components |
Provides useful GUI (graphical user interface) components, none of which
are necessary for creating a plugin, but many plugin implentations
will find these components useful.
|
com.biomatters.geneious.publicapi.databaseservice |
Provides the interface and associated classes for
defining a database service which is a service that
appears on the left-hand side of the main Geneious window
and provides the user with access to a database, for example
NCBI or the local database for storing the user's documents.
|
com.biomatters.geneious.publicapi.documents |
Provides interfaces and classes for defining documents in Geneious and related
interfaces and classes for dealing with XMLSerialization.
|
com.biomatters.geneious.publicapi.documents.sequence |
Provides interfaces specifying the types of
sequence and
alignment
documents in Geneious, together with concrete classes used by sequence documents
such as SequenceAnnotation
and SequenceCharSequence . |
com.biomatters.geneious.publicapi.documents.types |
Provides interfaces specifying the types of documents available in Geneious.
|
com.biomatters.geneious.publicapi.implementations |
Provides implementations for many of the document interfaces defined
in the package com.biomatters.geneious.publicapi.documents.types
together with some utility classes for dealing with some of these
document types.
|
com.biomatters.geneious.publicapi.implementations.sequence |
Provides
SequenceDocument
implementations for nucelotide, amino acid, and nucleotide graph (chromatogram) sequences. |
com.biomatters.geneious.publicapi.implementations.structure |
Provides
MolecularStructureDocument
implementations for many commonly used 3D structure documents. |
com.biomatters.geneious.publicapi.laf | |
com.biomatters.geneious.publicapi.plugin |
Provides the
GeneiousPlugin interface and plugin
related interfaces. |
com.biomatters.geneious.publicapi.utilities |
Provides various utility methods and classes, none of which
are necessary for creating a plugin, but many plugins implentations
will find these methods useful.
|
com.biomatters.geneious.publicapi.utilities.xml |