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.
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.
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.
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.
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.
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.
When a pligin exits, it should send a single XML tag to genquire: <EXIT>
Genquire will then clean up and destroy that plugin handler.
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
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>
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>
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 <..> </..>)
request: <getContigIDs></getContigIDs> return: <..><contig>$contigID1</contig><contig>$contigID2</contig>....</..> function: to return the names of all contigs in the genome
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.
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.
request: <getOrganismName></getOrganismName> return: <..>$name</..> function: to return the latin name of the organism
request: <getSequenceVersion></getSequenceVersion> return: <..>$version</..> function: to return the version identifier
request: <getSelectedContigs></getSelectedContigs> return: <..><contig>$contig_id</contig>....</..> function: to return the names of the contigs currently selected in the genome map
request: <selectContigs><contig>$contig1</contig>...</selectContigs> return: <..>1</..> function: to set a contig as 'selected' in the genome map in the genome map
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.
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!!!!
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...)
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;...... )
request: <getSelectedFeatures></getSelectedFeatures> return: <..><feature>$fid</feature>...</..> function: retrieve the unique feature IDs for all currently selected features on all open maps.
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.
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.
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