Bio::G...:Plugin(3pm)
π Bio::Graphics::Browser2::Plugin π
okay bestie, welcome to the manual page for Bio::Graphics::Browser2::Plugin β a Perl module, shipped with the User Contributed Perl Documentation, and honestly? it's the blueprint for every gbrowse plugin ever. strap in. π
β¨ NAME β¨
Bio::Graphics::Browser2::Plugin β the base class for gbrowse plugins. that's it, that's the whole vibe. it's the parent class everything else inherits from, the main character that lets the side characters pop off. π
πΈ SYNOPSIS πΈ
so here's what a baby plugin looks like. every line is a real thing gbrowse calls on you, no cap:
package Bio::Graphics::Browser2::Plugin::MyPlugin;
use Bio::Graphics::Browser2::Plugin;
use CGI ':standard';
@ISA = 'Bio::Graphics::Browser2::Plugin';
# called by gbrowse to return name of plugin for popup menu
sub name { 'Example Plugin' }
# called by gbrowse to return the descriptive verb for popup menu
sub verb { 'Demonstrate' }
# called by gbrowse to return description of plugin
sub description { 'This is an example plugin' }
# called by gbrowse to return type of plugin
sub type { 'annotator' }
# called by gbrowse to configure default settings for plugin
sub config_defaults {
my $self = shift;
return {foo => $value1,
bar => $value2}
}
# called by gbrowse to reconfigure plugin settings based on CGI parameters
sub reconfigure {
my $self = shift;
my $current = $self->configuration;
$current->{foo} = $self->config_param('foo');
$current->{bar} = $self->config_param('bar');
}
# called by gbrowse to create a <form> fragment for changing settings
sub configure_form {
my $self = shift;
my $current = $self->configuration;
my $form = textfield(-name => $self->config_name('foo'),
-value => $current->{foo})
.
textfield(-name => $self->config_name('bar'),
-value => $current->{bar});
return $form;
}
# called by gbrowse to annotate the DNA, returning features
sub annotate {
my $self = shift;
my ($segment,$coordinate_mapper) = @_;
my $config = $self->configuration;
my $feature_list = $self->new_feature_list;
$feature_list->add_type('my_type' => {glyph => 'generic',
key => 'my type',
bgcolor => 'green',
link => 'http://www.google.com/search?q=$name'
}
);
# do something with the sequence segment
my @features = do_something();
$feature_list->add_feature($_ => 'my_type') foreach @features;
return $feature_list;
}
likeβ¦ it's giving "template you copy-paste and then make yours". iconic. π¦
π DESCRIPTION π
okay so this is the base class for Generic Genome Browser plugins. plugins are perl .pm files, and they live in the gbrowse.conf/plugins directory. π
you turn a plugin on in the gbrowse.conf/ configuration file by putting it on the list that the plugins setting points at:
plugins = BatchDumper FastaDumper GFFDumper
OligoFinder RestrictionAnnotator
and if you've got plugins that are specific to your site, you can drop them into one or more site-specific directories and add them to the plugin search path with the plugin_path setting:
plugin_path = /usr/local/gbrowse_plugins
now, GBrowse currently recognizes five distinct types of plugins: (she says five. she then lists six. we love her for it, no notes.) β¨
- dumpers these receive the genomic segment object and generate a dump β the output can be text, html, or some other specialized format. Example: GAME dumper.
- finders these accept input from the user and return a list of genomic regions. the main browser displays the found regions and lets the user select among them. Example: BLAST search.
- annotators these receive the genomic segment object and either 1) return a list of features which are overlayed on top of the detailed view (Example: restriction site annotator) or 2) update the database with new or modified features and return nothing (Example: basic editor)
- trackfilters these can be used to reduce the complexity of sites that have many tracks, by providing search and filtering functions for the track table. when a trackfilter is active, its form-based user interface is positioned directly above the tracks table, and changes to the for cause the list of tracks to be updated dynamically.
- highlighters these will color-highlight features based on user-defined attributes. for example, you could highlight all features that are in the positive strand.
- filters these will filter features based on user-defined attributes. Only features that match the attributes will be displayed. for example, you could filter out RNA transcript features based on their size, so that only features that are less than 50 bp in length (e.g. short RNAs) are shown.
all plug-ins inherit from Bio::Graphics::Browser2::Plugin, which defines reasonable (but uninteresting) defaults for each of the methods. specific behavior is then implemented by selectively overriding certain methods. so basically: the base class is your chill parent who set up the house rules, and you redecorate whichever room you want. π
π§ the way to actually learn this π§
fr fr, the best way to understand how this works is to go read the source code of some working plugins. the examples that ship with the gbrowse distribution include:
GFFDumper.pmβ a simple dumper which produces GFF format output representing the features of the currently-selected segment.FastaDumper.pmβ a more complex dumper that illustrates how to create and manage persistent user-modifiable settings.SequenceDumper.pmβ another dumper that shows how plugins interact with theBio::SeqIOsystem.OligoFinder.pmβ a finder that searches for short oligos in the entire database. (Only works withBio::DB::GFFdatabases.)RestrictionAnnotator.pmβ an annotator that finds restriction sites in the currently selected region of the genome. It creates a new track for each type of restriction site selected.RandomGene.pmβ an example annotator that generates random gene-like structures in the currently displayed region of the genome. It's intended as a template for front-ends to gene prediction programs.AttributeHiliter.pmβ an example feature hiliter that works withBio::DB::GFFandBio::SeqFeature::Storedatabases.FilterTest.pmβ an example feature filter that filters based on strand of the feature.SimpleTrackFinder.pmβ an example track filter that filters tracks based on their name.SourceTrackFinder.pmβ another example track filter that filters tracks based on the contents of their "track source" and "data source" options.
go read them. seriously. reading real code > reading docs about code. πβ¨
π₯ METHODS π₯
the rest of this document describes the methods available to the programmer. aka the tools in your toolbox. π§°
π INITIALIZATION π
the initialization methods establish the human-readable name, description, and basic operating parameters of the plugin. they should be overridden in each plugin you write β like, that's the whole assignment, bestie. βοΈ
$name = $self->name()β return a short human-readable name for the plugin. this will be displayed to the user in a menu using one of the following forms:
Dump <name>
Find <name>
Annotate <name>
plugin_defined_verb <name>
$description = $self->description()β this method returns a longer description for the plugin. the text may contain HTML tags, and should describe what the plugin does and who wrote it. this text is displayed when the user presses the "About..." button. so like, hype yourself up in HTML, you've earned it. π«Ά$verb = $self->verb()β this method returns a verb to be used in the plugin popup menu in cases where the main three don't fit. this method should be set return whitespace or an empty string (notundefined) if you do not want a descriptive verb for the menu. β οΈ note that: whitespace or empty string, notundefined.$suppress_title = $self->suppress_title()β the purpose of this methods is to suppress the 'Configure...' or 'Find...' title that is printed at the top of the page when the plugin is loaded. it will return false unless overridden by a plugin where this behaviour is desired.$type = $self->type()β this tells gbrowse what the plugin's type is. it must return one of the scripts "dumper,", "finder,", "annotator" as described in the introduction to this documentation. if the method is not overridden,type()will return "dumper." π¦$self->init()β this method is called before any methods are invoked and allows the plugin to do any run-time initialization it needs. the default is to do nothing. ordinarily this method does not need to be implemented. (a true "if it ain't broke" moment.)
π ACCESS TO THE ENVIRONMENT π
the following methods give the plugin access to the environment, including the gbrowse page settings, the sequence features database, and the plugin's own configuration settings. π
these methods do not generally need to be overridden. hands off, they're doing great.
$config = $self->configuration()β call this method to retrieve the persistent configuration for this plugin. the configuration is a hashref containing the default configuration settings established byconfig_defaults(), possibly modified by the user. due to cookie limitations, the values of the hashref must be scalars or array references.
see CONFIGURATION METHODS for instructions on how to create and maintain the plugin's persistent configuration information.
$renderer = $self->rendererβ this method returns a copy of the Render object, which provides access to the internal workings of the page layout engine. You will need to troll theBio::Graphics::Browser2::Rendersource code to understand how to use this object. (yes, trolling. go spelunking, bestie. π¦)$database = $self->databaseβ this method returns a copy of the default database. depending on the data source chosen by the gbrowse administrator, this may be aBio::DB::GFFdatabase, aBio::DB::Das::Chadodatabase, aBio::Dasdatabase, aBio::DB::Das::BioSQLdatabase, or any of the other Das-like databases that gbrowse supports.@dbs = $self->all_databasesβ this method returns copies of all the databases defined for this data source. Most useful for Finder plugins.@track_names = $self->selected_tracksβ this method returns the list of track names that the user currently has turned on. Track names are the internal names identified in gbrowse configuration file stanzas, for example "ORFs" in the01.yeast.confexample file.@feature_types = $self->selected_featuresβ this method returns the list of feature types that the user currently has turned on. Feature types are the feature identifiers indicated by the "feature" setting in each track in the gbrowse configuration file, for example "ORF:sgd" in the01.yeast.conf[ORFs]track.
...and that's where part 1 ends, bestie β there's more coming. don't go anywhere. π
$gbrowse_settings = $self->page_settingsβ hands you a big fat hash stuffed with all the current gbrowse persistent user settings. Where are they documented tho? In the gbrowse executable source code, bestie. You will not ordinarily need to poke around inside this hash, and you should not change its values. Like, don't. π$browser_config = $self->browser_configβ gives you back a copy of theBio::Graphics::Browser2::DataSourceobject that drives gbrowse. This object is your little backstage pass: it lets you interrogate (and change!) the values set in the current gbrowse configuration file. Interrogate AND change, the audacity π$value = $self->setting('setting name')β the recommended use for this object is to recover plugin-specific settings from the gbrowse config file. The gbrowse admin can define these by dropping a stanza like this into the gbrowse config file:
[GOSearch:plugin]
traverse_isa = 1
use_server = http://amigo.geneontology.org
GOSearch is the package name of the plugin, and that :plugin part of the stanza name is the lil signal that tells gbrowse "hey, this is a plugin-private configuration section." private, do not perceive π«Ά
Now you can reach those settings from inside the plugin with this idiom:
my $traverse_isa = $self->setting('traverse_isa');
my $server = $self->setting('use_server');
This facility is meant for settings that the end user should not be changing. Persistent user preferences belong in the hash returned by configuration(). know the difference, it's giving separation of concerns β¨
And if your plugin inherits from another one, the inheritance path gets searched for settings too. Like, if the GOSearch plugin inherits from the OntologySearch plugin, then setting() will search first for a stanza named "GOSearch:plugin" and then for "OntologySearch:plugin". generational hand-me-down settings π
$search = $self->db_searchβ returns aBio::Graphics::Browser2::RegionSearchobject, which you can use to search all local and remote databases. The interface is this:
$features = $search->search_features(\%args);
where \%args are the various arguments (e.g. -type, -seq_id, -name) passed to the dbadaptors' search_features() method. Alternatively:
$features = $search->search_features('keyword string')
which implements GBrowse's heuristic search. π΅οΈβοΈ
The result is an array reference of features found. The search object also has a get_seq_stream() method that accepts the same arguments as search_features() but returns an iterator. That iterator implements a next_seq() method. iterator girlies rise π¦
$language = $self->languageβ returns the current I18n language file. You can use this to make translations with thetr()method:
print $self->language->tr('WELCOME');
multilingual icon behavior π
$segments = $self->segmentsβ returns the current segments in use by gbrowse. The active segments get set from within gbrowse:
$plugin->segments(\@segments);
Then the active segments can be retrieved from inside the plugin. This is useful when segment-specific info is needed by plugin methods that are not passed a segment object. no segment object? no problem π
$config_path = $self->config_pathβ returns the path to the directory where gbrowse stores its configuration files. Super useful for storing plugin-specific configuration files. See the source code of RestrictionAnnotator for an example of this. go read the source, it's giving tutorial β¨$feature_file = $self->new_feature_fileβ creates a newBio::Graphics::FeatureFilefor use by annotators. Theannotate()method must invoke this method, configure the resulting feature file, and then add one or moreBio::Graphics::Featureobjects to it.
This method is equivalent to calling Bio::Graphics::FeatureFile->new(-smart_features=>1), where the -smart_features argument is what allows features to be turned into imagemap links. π
π¦ METHODS TO BE IMPLEMENTED IN DUMPERS π¦
All plugins that act as feature dumpers should override one or more of the methods described in this section. your turn to do the work bestie π
$self->dump($segment)β given aBio::Das::SegmentIobject, produce some output from its sequence and/or features. This can dump something as simple as a FASTA file, or as complex as a motif analysis performed on the sequence. range, she has it π
As described in Bio::Das::SegmentI, the segment object represents the region of the genome currently on display in the gbrowse "detail" panel. You may call its seq() method to return the sequence as a string, or its features() method to return a list of all features that have been annotated onto this segment of the genome.
At the time that dump() is called, gbrowse will already have set up the HTTP header and performed other initialization. The dump() method merely needs to begin printing output using the appropriate MIME type. By default, the MIME type is text/plain, but this can be changed with the mime_type() method described next. setup done for you, you just print β¨
The following trivial example shows a dump() method that prints the name and length of the segment:
sub dump {
my $self = shift;
my $segment = shift;
print "name = ",$segment->seq_id,"\n";
print "length = ",$segment->length,"\n";
}
$type = $self->mime_typeβ return the MIME type of the information produced by the plugin. By default, this method returns"text/plain". Override it to return another MIME type, such as"text/xml". glow up your content type π
πΈ METHODS TO BE IMPLEMENTED IN FINDERS πΈ
All finder plugins will need to override one or more of the methods described in this section. finder girlies, this is your moment π
$features = $self->find($segment);β thefind()method gets passed aBio::Das::SegmentIsegment object, as described earlier for thedump()method. Your code should search the segment for features of interest, and return a two element list. The first element should be an arrayref ofBio::SeqFeatureIobjects (seeBio::SeqFeatureI), or an empty list if nothing was found. These synthetic feature objects should indicate the position, name and type of the features found. The second element of the returned list should be a (possibly shortened) version of the search string for display in informational messages. two things in, two things out, we love a return contract π«Ά
Depending on the type of find you are performing, you might search the preexisting features on the segment for matches, or create your own features from scratch in the way that the annotator plugins do. You may choose to ignore the passed segment and perform the search on the entire database, which you can obtain using the database() method call. whole-database search? bold. iconic. π
To create features from scratch I suggest you use either Bio::Graphics::Feature, or Bio::SeqFeature::Generic to generate the features. See their respective manual pages for details, and the OligoFinder.pm plugin for an example of how to do this. copy the homework, it's fine π
If the plugin requires user input before it can perform its task, find() should return undef. Gbrowse will invoke configure_form() followed by reconfigure() in order to prompt the user for input. If nothing is found, the plugin should return an empty list. undef means "ASK ME SOMETHING", empty list means "found nothing, move along" β do not mix these up bestie π
The following is an example of how to prompt the user for input -- in this case, a gene ontology term:
sub find {
my $self = shift;
my $segment = shift; # we ignore this!
my $config = $self->configuration;
my $query = $config->{query} or return undef; # PROMPT FOR INPUT
my $search = $self->db_search;
my @features = $search->features(-attributes=>{GO_Term => $query});
return (\@features,$query);
}
sub configure_form {
my $self = shift;
return "Enter a GO Term: "
. textfield(-name=>$self->config_name('query'));
}
sub reconfigure {
my $self = shift;
my $config = $self->configuration;
$config->{query} = $self->config_param('query');
}
See the sections below for more description of the configure_form() and reconfigure() methods.
NOTE: If you need to use auxiliary files like BLAST files, you can store the location of those files in the gbrowse.conffile under the stanza[YourPlugin:plugin]:
[YourPlugin:plugin]
blast_path = /usr/local/blast/databases
sub find {
my $self = shift;
my $segment = shift; # ignored
my $blast_path = $self->browser_config->plugin_setting('blast_path');
# etc etc etc
}
$features = $self->auto_find($search_string)β if the plugin has an"auto_find"method, then that method gets invoked whenever the user types a string into GBrowse's search box. The plugin may search any of the current data source's databases (which you can get using$self->all_databases), or its own databases. search box girlies, she's typing π₯
Return an arrayref containing the features found. Return an empty arrayref to indicate that no features were found. Return undef to indicate that the plugin declines to perform the search, in which case GBrowse will default to its own search algorithm. three different returns, three different vibes, choose wisely β¨
You may also choose to merge your search results with GBrowse's. To do this, you can initiate the default search by calling:
$default_features
= $self->db_search->search_features({-search_term => 'searchterm'})
Then do what you need to do to merge your customized search with the default terms. collab, not competition π
π METHODS TO BE IMPLEMENTED IN ANNOTATORS π
All annotator plugins will need to override the method described in this section. just the one, you got this π
$feature_file = $plugin->annotate($segment[,$coordinate_mapper])β theannotate()method gets invoked with aBio::Das::SegmentIsegment representing the region of the genome currently on view in the gbrowse detail panel. The method should first call its ownnew_feature_list()to create aBio::Graphics::FeatureFilefeature set object, and define one or more feature types to be added to the feature set. The method should then create one or moreBio::Graphics::Featureobjects and add them to the feature set usingadd_feature. build the set, fill the set, ship the set π
okay so the why behind annotate() handing you back a Bio::Graphics::FeatureFile instead of a plain array of features the way find() does? π
Because Bio::Graphics::FeatureFile isn't just a feature bucket β it's the whole styling suite. It also lets you set up how those features get rendered: you can define tracks, sort different feature types into different tracks, and hand each feature type its own glyph, color, and other options. It's giving full creative control, no cap. β¨
annotate() also gets passed a coordinate_mapper variable. That's a code ref to a function that transforms coordinates from relative β absolute. It takes a reference sequence name plus a list of [$start,$end] coordinate pairs, and returns a similar result β except the sequence name and the coordinates are all in absolute coordinate space. And currently there are no plugins that make use of this facility. π It's just sitting there, iconic but unemployed.
Want the full deets? See Bio::Graphics::FeatureFile, and peep the RestrictionAnnotator.pm plugin for a whole example. π
β¨ METHODS TO BE IMPLEMENTED IN TRACKFILTERS β¨
@track_names = $plugin->filter_tracks($tracks,$source)
You get a list of track names plus a Bio::Graphics::Browser2::DataSource object, and your job is to figure out which track names actually deserve to be displayed and return them as a list. The tracks come in as a reference to a list of all the possible track names. π
Wanna make that form interactive? You may wish to pepper the plugin's configuration form methods with calls to the javascript routine doPluginUpdate(). That makes GBrowse update the plugin's configuration and refresh the tracks table as a side effect. π¦
@terms = $plugin->hilite_terms
Returns a list of terms to hilight in the tracks table, or empty if there are none. Simple as that, bestie. β
π METHODS TO BE IMPLEMENTED IN FEATURE HILITERS π
$color = $self->highlight($feature)
This one gets passed a feature. It returns a color name (or honestly any Bio::Graphics color string) to highlight that feature in that color β or undef if the feature should not be highlighted at all. Periodt. π
π METHODS TO BE IMPLEMENTED IN FEATURE FILTERS π
($filter,$newkey) = $self->filter($track_label,$key)
You're passed a track label and the original key of the label. You're expected to return a two-element list: a coderef plus a new key for the track. That coderef should be a subroutine that takes a feature as its single argument and returns true to include the feature in the track, false to exclude it. Like so:
sub {
my $feature = shift;
return do_something() ? 1 : 0;
}
The filter() method should return an updated string for the track key, so the user can see that the track is being filtered β it's a little heads-up that this track is not showing all possible features. π
And if the filter() method doesn't wanna install or filter anything, or it wants to remove a filter that was previously installed? It should return an empty list. That's it, that's the whole vibe. π
πΈ PERSISTENT CONFIGURATION METHODS πΈ
These methods can be called to retrieve data about the environment the plugin is running in. They're also what gbrowse uses to change the plugin state. π₯
$config = $self->config_defaults()
This gets called once at plugin startup time, giving the plugin a chance to set up its default configuration state. If you implement this method, you should return the configuration as a hash reference where the values are either scalar values or array references. The contents of that hash get placed into a CGI::Session. π«Ά
You'll wanna implement this one if your plugin has user-modifiable settings.
NOTE ON FILEHANDLES: You are not allowed to permanently store a filehandle in the persistent configuration data structure. Why? Because the session-handling code will try to serialize and store the filehandle, and the default serializer does not allow that. π If you absolutely must store a filehandle in the configuration data structure, be sure to delete it within theannotate(),find()ordump()methods once you're done using it.
$self->configure_form()
This one fires when the user presses the "Configure plugin" button. You should return the HTML for a fill-out form that lets the user change the current settings. The HTML should contain the contents of an HTML <form> section, but not the actual <form> and </form> tags β those tags, along with the Submit and Cancel buttons, get added automatically. Typically you'll build up the HTML you return using a series of .= append operations. β¨
It is highly recommended that you use the CGI module to generate the fill-out form. And to avoid clashing with other parts of gbrowse, plugin fill-out forms must respect a namespacing convention: the name of each form field is preceded by the plugin package name and a dot. The package name is the last component of the plugin's package β for example "GoSearch" is the package name for Bio::Graphics::Browser2::Plugin::GoSearch. So to represent the "query" field of the plugin named "GOSearch", the text field must be named "GOSearch.query". iykyk. π
To make doing this right easier, the Plugin module provides a method named config_name() which will add the prefix for you. Here's how to use it with the "query" example:
$html .= textfield(-name => $self->config_name('query'));
$self->reconfigure()
If you implement a configure_form() method, you must also implement a reconfigure() method. It gets called after the user submits the form, and you should use it to integrate the form values with the current configuration. π¦
Remember: the form fields are namespaced. You can recover them using the CGI param() method by preceding them with the proper prefix. And to make that easier to manage, this module provides a config_param() method that handles the namespaces transparently for you. π
Here's a working example:
sub reconfigure {
my $self = shift;
my $current_configuration = $self->configuration;
$current_configuration->{query} = $self->config_param('query');
}
All this does is retrieve the current configuration by calling the configuration() method. Then the value of the "query" key gets replaced by a fill-out form parameter named "query", using config_param() instead of the more familiar CGI module's param() function. Iconic, honestly. β
π SEE ALSO π
- Bio::Graphics::Browser
π AUTHOR π
Lincoln Stein <lstein@cshl.org>.
Copyright (c) 2003 Cold Spring Harbor Laboratory
This package and its accompanying libraries is free software; you can redistribute it and/or modify it under the terms of the GPL (either version 1, or at your option, any later version) or the Artistic License 2.0. Refer to LICENSE for the full license text. In addition, please see DISCLAIMER.txt for disclaimers of warranty. π
and that's a wrap on the whole page, bestie!! π this one came from perl v5.40.0, dated 2024-10-20, and it's the Bio::G...:Plugin(3pm) page β go forth and build plugins, you absolute main character πβ¨π¦
π¦ where this page comes from
- ubuntu questing: gbrowse 2.56+dfsg-12build4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms