PlugIns in Genquire


DESCRIPTION

Genquire has a simple XML-based plugins API which is client driven. This means that all events are initiated from the plugin-side, and responses are sent back from Genquire.

Under Linux, communication between the plugin and Genquire occurs via STDIN/STDOUT, so for most plugins a simple ``print'' statement may be sufficient to initiate contact with Genquire. This also allows plugins to be written in any language.

Under Win32, bona fide files are used to pass messages back and forth with Genquire.  The filenames to pass information are:
            From the plugin to Genquire:   REQUEST
            From Genquire to the plugin:   RESPONSE
Note that the file must be completely written-to before becoming available for reading.  Since Win32 can not do file locking, the best way to achieve this is to write to a temporary file, and then rename it when writing is complete.  I know... this is ugly... but so is MSWindows.

HINT:  If you are writing your plugin in Perl, you are welcome to 'use' the module GQ_Comm.pm.  This module exports a single method - askGenquire() - which will take care of all plugin communication events in a platform-aware manner.  Please read the pod documentation for the askGenquire method, and take advantage of this module.

Genquire buffers its output and creates non-blocking filehandles at the Genquire end of the I/O pipes, however it is the responsibiliy of the plugin to ensure that it does not generate blocking calls.

Plugins.conf

the file plugins.conf must be in the PLUGINS directory of Genquire. the format of this file is as follows:
  Name,  script,  arg1,  arg2, ...
for example, the Blast plugin is called by the following line in plugins.conf:
  Blast, gq_blast.pl, /tmp/, /home/markw/BLAST/
where Blast is the program name (inserted into the drop-down menu of Genquire), gq_blast.pl is the name of the script that starts the plugin, and the two paths /tmp/ and /home/markw/BLAST are required by this script to find the working directory and the blast binaries.

Client death

If a plugin dies it should try to send a message to Genquire indicating that fact. the correct format of this message is: <KILLED>

this can appear anywhere in a message string, even in the middle of other XML tags. This allows SIG INT to be caught and the plugin handler to be cleaned up nicely at the Genquire end.

Server death

if Genquire dies, it will attempt to send a single message to the plugin: <KILL>

this may appear anywhere in the response string, even between or within XML tags. This can be caught by the plugin to allow it to cleanup and exit gracefully.

Exiting the plugin

When a pligin exits, it should send a single XML tag to genquire: <EXIT>

Genquire will then clean up and destroy that plugin handler.

Errors & failures

for many calls, genquire will report a failure if it was unable to execute the requested task, for reasons of invalid input or internal errors. In such a case, genquire responds as follows: <GQ_RESPONSE> <method_requested> <FAILED>message or reason here </FAILED> </method_requested> </GQ_RESPONSE>
=cut

Standard request format

This is quite straightforward. There is a <REQUEST></REQUEST> pair of tags and within these are the <method_requested></method_requested> pair, with any relevant data between them. See the API section below for valid methods and the required data

A correctly formatted query looks, for example, like this: <REQUEST> <getFullContigSequence>At23TY65</getFullContigSequence> </REQUEST>

Requests in parallel

Genquire processes a call in its entirety before it sends information back or begins processing another call. Thus the integrety of the response sent to STDIN should be guaranteed. Multiple calls will be processed in the order they are read from the plugin STDOUT. Calls are expected to be complete and correctly formatted; genquire will not correctly interpret overlaping calls.

Multiple calls may be stacked up in the response queue, and for this reason part of the response string is the name of the method that was called: <GQ_RESPONSE> <method_requested> <response_tag>response value</response_tag> </method_requested> </GQ_RESPONSE>


API

The calls below go between the <REQUEST>...</REQUEST> tags the response, as indicated above, is contained between the original request call tags (indicated here as <..> </..>)

getContigIDs

 request: <getContigIDs></getContigIDs>
 return: <..><contig>$contigID1</contig><contig>$contigID2</contig>....</..>
 function:  to return the names of all contigs in the genome

getUniqueContigSequence

 request: <getUniqueContigSequence>$contigID</getUniqueContigSequence>
 return: <..><contig>$contigID<seq>$seq</seq></contig><..>
 function:  to return the non-redundant sequence of a given contig
 non-redundant sequences are calculated such that a given portion of
 sequence will be returned on only one contig.  These can be used to
 build, for example, a Blast database.

getFullContigSequence

 request: <getFullContigSequence>$contigID</getFullContigSequence>
 return: <..><contig>$contigID<seq>$seq</seq></contig><..>
 function:  to return the entire sequence of a given contig
 If this contig overlaps other contigs then the returned sequence
 will include this overlap region. Retrieving the full set of
 full contig sequences will result in a largely redundant sequence set.

getOrganismName

 request: <getOrganismName></getOrganismName>
 return: <..>$name</..>
 function:  to return the latin name of the organism

getSequenceVersion

 request: <getSequenceVersion></getSequenceVersion>
 return: <..>$version</..>
 function:  to return the version identifier

getSelectedContigs

 request: <getSelectedContigs></getSelectedContigs>
 return: <..><contig>$contig_id</contig>....</..>
 function:  to return the names of the contigs currently selected
 in the genome map

selectContigs

 request: <selectContigs><contig>$contig1</contig>...</selectContigs>
 return: <..>1</..>
 function:  to set a contig as 'selected' in the genome map
 in the genome map

openContig

 request:
 <openContig>
  <contig>$contig1</contig>
  <start>$start</start>
  <stop>$stop</stop>
 </openContig>
 return: <..>1|0</..>
 function:  to open the detailed display of a contig from position $start to $stop
 the values of $start and $stop may be left blank to open the entire contig, but
 the tags must be present.

getActiveSequences

 request: <getActiveSequences></getActiveSequences>
 return:
 <..>
 <contig id='$MAP_id1'>
  <start>$start</start>
  <length>$length</length>
  <sequence>$seq</sequence>
 </contig>
 </..>
 function:  to retrieve the sequence of all currently open map displays
 Only the sequence of the dispayed portion of the contig is retrieved,
 NOT the entire contig.  N.B. $MAP_id1 is what is required in the contig
 field of the GFF string when you call mapFeatures!!!!

getFeatureIDs

 request: <getFeatureIDs></getFeatureIDs>
 return: <..><feature>$fid</feature>...</..>
 function:  retrieve the unique feature ids for all currently displayed
 features on all open maps (I don't think this is very useful...)

getFeatureByID

 request: <getFeatureByID>$fid</getFeatureByID>
 return:
   <..>
     <contig>$seq</contig>
     <map>$map</map>
     <source>$source</source>
     <feature>$feature</feature>
     <contig_start>$start</contig_start>
     <map_start>$map_start</map_start>
     <contig_end>$stop</contig_end>
     <map_end>$map_stop</map_end>
     <score>$score</score>
     <strand>$strand</strand>
     <frame>$frame</frame>
     <notes>$msg</notes> 
   </..>
 function:  retrieve the extended GFF information for the given feature ID.
 Note the difference between contig coordinates, and map coordinates in the
 returned information.  This is because a map does not necessarily display
 an entire contig.  $msg takes the form of a GFF2 attributes string.
( tag val val...;tag val;tag val val;...... )

getSelectedFeatures

 request: <getSelectedFeatures></getSelectedFeatures>
 return: <..><feature>$fid</feature>...</..>
 function:  retrieve the unique feature IDs for all currently selected
 features on all open maps.

selectFeatures

 request: <selectFeatures><feature>$fid</feature>...</selectFeatures>
 return: <..>1</..>
 function:  "select" all of the features in the list on the feature map
 features that are not present are ignored.

mapFeature

 request:
        [<import>]
        <mapFeature>
          <contig>$MapSequenceID</contig>
          <start>$start</start>
          <end>$end</end>
          <feature>$feature_type</feature>
          <source>$source</source>
          <strand>$strand</strand>
          <frame>$frame</frame>
          <score>$score</score>
          <attributes>$attrib</attributes>
        </mapFeature>
        [</import>]
 return: <..>1</..>
 function:  to map a feature onto a Sequence viewer and optionally import
 that feature into the database.  If the MapSequenceID is not recognized
 as a currently open map (i.e. if the sequence in-hand did not come from a
 call to getActiveSequences), but has the form of a map-name:
        contig_id::start-length
        eg:  T22H7::2500-5000
 then the call will be ignored to avoid writing spurious data into the database.
 This allows the mapFeatures call to double as a database import routine for contig
 analyses.
 Example: if you requested getFullContigSequence, instead of a getActiveSequences,
 you could do your sequence analysis and import the features into the database
 using mapFeature, regardless of being able to observe the mapped results.

defaultDisplay

 request:
        any unrecognized request,
        may direct to a file by: <html_file>$full_path</html_file>
 return: <..>1</..>
 function: any request sent to Genquire without a reconized request tag
 is sent to the default web browser to be displayed