Bio::DB::GFF(3pm)
๐ Bio::DB::GFF ๐
ok so bestie, you've stumbled into the manual page for Bio::DB::GFF, from the User Contributed Perl Documentation section (the <pink>(3pm)</pink> vibe, iykyk). sit down, grab a boba, and let's get into it ๐
โจ NAME โจ
Bio::DB::GFF โ Storage and retrieval of sequence annotation data ๐งฌ
๐ SYNOPSIS ๐
ok so first you gotta open the sequence database, and it's giving very straightforward:
use Bio::DB::GFF;
# Open the sequence database
my $db = Bio::DB::GFF->new( -adaptor => 'dbi::mysqlopt',
-dsn => 'dbi:mysql:elegans');
# fetch a 1 megabase segment of sequence starting at landmark "ZK909"
my $segment = $db->segment('ZK909', 1 => 1000000);
# pull out all transcript features
my @transcripts = $segment->features('transcript');
# for each transcript, total the length of the introns
my %totals;
for my $t (@transcripts) {
my @introns = $t->Intron;
$totals{$t->name} += $_->length foreach @introns;
}
# Sort the exons of the first transcript by position
my @exons = sort {$a->start <=> $b->start} $transcripts[0]->Exon;
# Get a region 1000 bp upstream of first exon
my $upstream = $exons[0]->subseq(-1000,0);
# get its DNA
my $dna = $upstream->seq;
# and get all curated polymorphisms inside it
@polymorphisms = $upstream->contained_features('polymorphism:curated');
# get all feature types in the database
my @types = $db->types;
# count all feature types in the segment
my %type_counts = $segment->types(-enumerate=>1);
# get an iterator on all curated features of type 'exon' or 'intron'
my $iterator = $db->get_seq_stream(-type => ['exon:curated','intron:curated']);
while (my $s = $iterator->next_seq) {
print $s,"\n";
}
# find all transcripts annotated as having function 'kinase'
my $iterator = $db->get_seq_stream(-type=>'transcript',
-attributes=>{Function=>'kinase'});
while (my $s = $iterator->next_seq) {
print $s,"\n";
}
like?? look at all that. one file, whole genome annotations. slay โจ
๐ธ DESCRIPTION ๐ธ
so Bio::DB::GFF gives you fast indexed access to a sequence annotation database. it's flexible like that โ it supports multiple database types (ACeDB, relational), and multiple schemas, which it pulls off through a whole little ecosystem of adaptors and aggregators. ๐ง
here's everything this module can do for you, bestie:
- retrieving a segment of sequence based on the ID of a landmark
- retrieving the DNA from that segment
- finding all annotations that overlap with the segment
- finding all annotations that are completely contained within the
segment
- retrieving all annotations of a particular type, either within a
segment, or globally
- conversion from absolute to relative coordinates and back again,
using any arbitrary landmark for the relative coordinates
- using a sequence segment to create new segments based on relative
offsets
the data model here is compatible with the GFF flat file format (<http://www.sequenceontology.org/gff3.shtml>). so yes, the module can load a set of GFF files straight into the database, and it serves you objects with methods that correspond to GFF fields. no cap.
and the objects it hands back? they're compatible with the SeqFeatureI interface, which means Bio::Graphics and Bio::DAS can use them too. teamwork, honestly. ๐ซถ
๐งฐ Auxiliary Scripts ๐งฐ
the bioperl distribution ships with a bunch of scripts that make working with Bio::DB::GFF databases way easier. they live in the scripts directory, under a subdirectory named Bio::DB::GFF:
bp_load_gff.plโ this one loads a Bio::DB::GFF database from a flat GFF file of sequence annotations. only the relational database version of Bio::DB::GFF is supported. you can use it to build the database from scratch, or to incrementally load new data. it takes a--fastaargument to load raw DNA into the database as well โ but honestly, GFF databases don't need access to the raw DNA for most of their functionality. it also has a--upgradeoption, which performs a non-destructive upgrade of older schemas to newer ones. iconique.bp_bulk_load_gff.plโ this one populates a Bio::DB::GFF database from a flat GFF file of sequence annotations. only the MySQL database version of Bio::DB::GFF is supported. it uses the"LOAD DATA INFILE"query to speed loading up a lot; however (and this is the catch, bestie), it can only be used for the initial load, not for updates. it also takes a--fastaargument to load raw DNA into the database as well โ same deal as before, GFF databases don't require raw DNA access for most of their functionality.bp_fast_load_gff.plโ as fast asbp_bulk_load_gff.pl, but it uses Unix pipe tricks so that incremental updates are possible. it only supports the MySQL database version of Bio::DB::GFF, and it is guaranteed not to work on non-Unix platforms. ๐ arguments are the same asbp_load_gff.pl.gadfly_to_gff.plโ converts the GFF-like format used by the Berkeley Drosophila Sequencing project into a format you can actually use with this module. ๐ฆsgd_to_gff.plโ converts the tab-delimited feature files used by the Saccharomyces Genome Database into a format suitable for this module. ๐
๐งฌ GFF Fundamentals ๐งฌ
ok so GFF is a flat tab-delimited file, and every single line corresponds to an annotation, aka a feature. each line has nine columns and looks exactly like this:
Chr1 curated CDS 365647 365963 . + 1 Transcript "R119.7"
and here's what those 9 columns actually are, one by one:
- reference sequence โ the ID of the sequence used to establish the coordinate system of the annotation. in the example above, the reference sequence is
"Chr1". - source โ the source of the annotation. this field tells you how the annotation was derived. in the example above, the source is
"curated", meaning the feature came out of human curation. software program names and versions often show up here too, like"tRNAScan-SE/1.2". - method โ the annotation method. this describes the type of the annotation, like
"CDS". together, method and source describe the annotation type. - start position โ where the annotation starts, relative to the reference sequence.
- stop position โ where the annotation stops, relative to the reference sequence. start is always less than or equal to stop. always. don't fight it. โ
- score โ for annotations tied to a numeric score (sequence similarity, for example), this field holds the score. the units are completely unspecified, but for sequence similarities it's typically percent identity. annotations with no score can just use
".". - strand โ for strand-specific annotations, this is the strand the annotation lives on. it's
"+"for the forward strand,"-"for the reverse strand, or"."for annotations that aren't stranded at all. - phase โ for annotations linked to proteins, this describes the phase of the annotation on the codons. it's a number from
0to2, or"."for features with no phase. - group โ GFF gives you a cute little way to build annotation hierarchies ("is composed of" relationships) by providing a group field. the group field contains the class and ID of an annotation that is the logical parent of the current one. in the example above, the group is the Transcript named
"R119.7". the group field is also where info about the target of sequence similarity hits lives, plus miscellaneous notes. (next section covers how to describe similarity targets, keep reading ๐) and the format of the group field is"Class ID"โ with a single space (NOT a tab) separating the class from the ID. it is VERY IMPORTANT to follow this format, or grouping will simply not work properly. that's not a vibe, that's a rule.
the sequences used to establish the coordinate system for annotations can correspond to sequenced clones, clone fragments, contigs, or super-contigs. so this module is useful throughout the entire lifecycle of a sequencing project. main character energy from start to finish. ๐
and in addition to a group ID, the GFF format lets annotations have a group class. for example, in the ACeDB representation, RNA interference experiments have a class of "RNAi" and an ID that's unique among the RNAi experiments. since not every database supports this notion, the class is optional in all calls to this module, and it defaults to "Sequence" when you don't provide one.
oh, and double-quotes sometimes show up in GFF files around components of the group field. strictly speaking, that's only necessary if the group name or class contains whitespace. ๐
๐ Making GFF files work with this module ๐
some annotations just don't need to be individually named. like, it's probably not useful to give every single ALU repeat in a vertebrate genome its own unique name, bestie. but others โ predicted genes, for instance โ correspond to named biological objects, and you probably want to fetch the positions of those objects by referring to them by name.
so to accommodate named annotations, the GFF format puts the object class and name in the group field. the name identifies the object, and the class keeps similarly-named objects from colliding โ clones and sequences, for example. ๐
a named object looks like this excerpt from a GFF file:
Chr1 curated transcript 939627 942410 . + . Transcript Y95B8A.2
this object is a predicted transcript named Y95BA.2. in this case, the group field identifies the class and name of the object, even though no other annotation belongs to that group.
and now โ the fun part โ you can retrieve the region of the genome covered by transcript Y95B8A.2 using the segment() method:
$segment = $db->segment(-class=>'Transcript',-name=>'Y95B8A.2');
it's not necessary for the annotation's method to correspond to the object class, although that's commonly the case. lowkey convenient.
as explained above, each annotation in a GFF file refers to a reference sequence. and it's important that each reference sequence ALSO be identified by a line in the GFF file. this lets the Bio::DB::GFF module figure out the length and class of the reference sequence, and it's what makes relative arithmetic possible. ๐งฎ
so for example, if "Chr1" is used as a reference sequence, it should have an entry in the GFF file like this one:
Chr1 assembly chromosome 1 14972282 . + . Sequence Chr1
this indicates that the reference sequence named "Chr1" has length 14972282 bp, method "chromosome" and source "assembly". and as the group field shows, Chr1 has class "Sequence" and name "Chr1". โจ
The object class Sequence is what gets used by default when you don't pass a class in the segment() call. Which means you get the cute lil shortcut version of segment():
$segment = $db->segment('Chr1'); # whole chromosome
$segment = $db->segment('Chr1',1=>1000); # first 1000 bp
And bestie, there's a bonus โจ โ if, while loading a GFF file, Bio::DB::GFF bumps into a line like this:
##sequence-region Chr1 1 14972282
it will automatically generate this entry for you:
Chr1 reference Component 1 14972282 . + . Sequence Chr1
Which is literally all you need to use Chr1 as a reference point. And guess what, the ##sequence-region line shows up all the time in the GFF files that annotation groups hand out, so you'll see it constantly. ๐
๐ซถ Specifying the group tag ๐ซถ
Okay so here's a classic GFF problem: there are like several tag/value pairs chilling in the 9th column, and the file is giving you no help figuring out which one is <em>the</em> grouping pair. Normally the first tag gets used for grouping โ but some GFF-wrangling tools out here do <em>not</em> preserve the order of attributes, which is giving chaos. ๐ญ
To kill that ambiguity, this module gives you two ways to say exactly which tag to group on:
- Using
-preferred_groupsโ when you create a Bio::DB::GFF object, hand it a-preferred_groups=>argument. That names a tag that will be used for grouping. And you can pass an <em>array reference</em> to specify a whole list of such tags. - In the GFF header โ the GFF file itself can declare which tags get used for grouping. Drop in a comment like this:
##group-tags Accession Locus
That says: use the Accession tag for grouping. If it's not available, use the Locus tag. And if neither tag is available? Fall back to the first pair that appears.
Heads up ๐ซถ these options only apply when you're <strong>loading a GFF file into the database</strong>. They do <strong>nothing</strong> to existing databases.
Also, the group-tags comment in the GFF file will <strong>override</strong> the preferred groups you set when you created the Bio::DB::GFF object. Like, it wins. Periodt.
For backward compatibility (iykyk), the tags Sequence and Transcript are <strong>always</strong> treated as grouping tags unless preferred_tags are specified. The "Target" tag is <strong>always</strong> used for grouping regardless of the preferred_groups() setting. And the tags "tstart", "tend" and "Note" <strong>cannot</strong> be used for grouping. These are historical artefacts from various interpretations of GFF2, and no, they cannot be changed. ๐
๐ธ Sequence alignments ๐ธ
There are two cases where an annotation is telling you about the relationship between two sequences:
- A similarity hit โ the annotation indicates an alignment.
- A map assembly โ the annotation indicates that a portion of a larger sequence is built up from one or more smaller ones.
Both cases get flagged by using the Target tag in the group field. So a typical similarity hit looks like this:
Chr1 BLASTX similarity 76953 77108 132 + 0 Target Protein:SW:ABL_DROME 493 544
The group field holds the Target tag, followed by an identifier for the biological object it's referring to. GFF uses the notation Class:Name for the biological object โ and yeah, it's stylistically inconsistent, but that's just how it's done, bestie. After the object identifier come two integers saying where the alignment starts and stops on the target sequence. ๐
Unlike the main start and stop columns, it is <strong>totally possible for the target start to be greater than the target end</strong>. The example above is saying that the section of Chr1 from 76,953 to 77,108 aligns to the protein SW:ABL_DROME, starting at position 493 and extending to position 544.
A similar notation covers sequence assembly info, like this:
Chr1 assembly Link 10922906 11177731 . . . Target Sequence:LINK_H06O01 1 254826
LINK_H06O01 assembly Cosmid 32386 64122 . . . Target Sequence:F49B2 6 31742
So this is saying the region between bases 10922906 and 11177731 of Chr1 is composed of LINK_H06O01 from bp 1 to bp 254826. And the region of LINK_H0601 between 32386 and 64122 is, in turn, composed of the bases 5 to 31742 of cosmid F49B2. Nested. Iconic. ๐
๐ Attributes ๐
Okay so this is <em>not</em> meant to be a general-purpose sequence database (for that, go look at bioperl-db, fr fr), but GFF does let you tag features with arbitrary attributes. Attributes live in the Group field, right after the initial class/name pair. Example time:
Chr1 cur trans 939 942 . + . Transcript Y95B8A.2 ; Gene sma-3 ; Alias sma3
This line tags the feature named Transcript Y95B8A.2 as being "Gene" named sma-3 and having the Alias "sma3". And features with these attributes can be looked up with the fetch_feature_by_attribute() method. Slay. ๐
Two attributes have special meaning:
"Note"โ kept for backward compatibility, used for unstructured text remarks."Alias"โ treated as a synonym for the feature name, and it gets consulted whenever you're looking up a feature by its name.
๐ฆ Adaptors and Aggregators ๐ฆ
This module runs on a whole system of adaptors and aggregators, so it can flex to work with a variety of databases. Two flavours, let's go:
Adaptors
The core of the module handles the user API, annotation coordinate arithmetic, and other common stuff. The nitty-gritty of fetching information out of databases is handled by an <strong>adaptor</strong>, which you specify when constructing Bio::DB::GFF. The adaptor encapsulates all the database-specific info โ the schema, user authentication, access methods, all of it.
There are currently <strong>five adaptors</strong> recommended for general use:
memoryโ A simple in-memory database suitable for testing and small data sets.berkeleydbโ An indexed file database based on the DB_File module, suitable for medium-sized read-only data sets.dbi::mysqlโ An interface to a schema implemented in the Mysql relational database management system.dbi::oracleโ An interface to a schema implemented in the Oracle relational database management system.dbi::pgโ An interface to a schema implemented in the PostgreSQL relational database management system.
Go check the Bio/DB/GFF/Adaptor directory and its subdirectories for other, more specialized adaptors, plus the experimental ones. ๐ฅ
Aggregators
GFF uses a "group" field to indicate the aggregation properties of individual features. Like, a set of exons and introns might share a common transcript group, and multiple transcripts might share the same gene group.
Aggregators are small modules that use that group info to rebuild the hierarchy. When you create a Bio::DB::GFF object, you tell it to use a set of one or more aggregators. Each aggregator provides a new composite annotation type. Before the database query gets generated, each aggregator is called to <strong>"disaggregate"</strong> its annotation type into a list of component types contained in the database. After the query is generated, each aggregator gets called <em>again</em> so it can build composite annotations out of the returned components.
For example, during disaggregation, the standard "processed_transcript" aggregator generates a list of component feature types including "UTR", "CDS", and "polyA_site". Later, it aggregates those features into a set of annotations of type "processed_transcript".
During aggregation, the list of aggregators is called in <strong>reverse order</strong>. That's what lets aggregators collaborate and build multi-level structures: the transcript aggregator assembles transcripts from introns and exons; then the gene aggregator assembles genes from sets of transcripts. Teamwork, honestly. ๐ซถ
Three default aggregators are provided:
transcriptโ assembles transcripts from features of typeexon,CDS,5'UTR,3'UTR,TSS, andPolyAcloneโ assembles clones fromClone_left_end,Clone_right_endandSequencefeatures.alignmentโ assembles gapped alignments from features of type"similarity".
On top of that, this module provides the optional "wormbase_gene" aggregator, which accommodates the WormBase representation of genes. This aggregator aggregates features of method "exon", "CDS", "5'UTR", "3'UTR", "polyA" and "TSS" into a single object. It also expects to find a single feature of type "Sequence" that spans the entire gene.
The existing aggregators are super easy to customize, bestie.
Important!! ๐จ Aggregation will <strong>not</strong> occur unless you specifically request the aggregation type. So this call:
@features = $segment->features('alignment');
will generate an array of aggregated alignment features. But <em>this</em> call:
@features = $segment->features();
will return a list of unaggregated similarity segments. Vibe check: no request, no aggregation. ๐
For more informnation, see the manual pages for Bio::DB::GFF::Aggregator::processed_transcript, Bio::DB::GFF::Aggregator::clone, etc.
โญ Loading GFF3 Files โญ
This module <em>will</em> accept GFF3 files, as described at http://song.sourceforge.net/gff3.shtml. <span>However</span>, the implementation has some limitations. Let's get into it:
GFF version string is required
The GFF file <strong>must</strong> contain the version comment:
##gff-version 3
Unless this version string is present at the top of the GFF file, the loader will attempt to parse the file in GFF2 format, with less-than-desirable results. ๐ญ So like, put it in. Please.
Only one level of nesting allowed
Here's a major restriction: Bio::DB::GFF only allows <strong>one level</strong> of nesting of features. For nesting, the Target tag will be used preferentially, followed by the ID tag, followed by the Parent tag. Which means if genes are represented like this:
XXXX XXXX gene XXXX XXXX XXXX ID=myGene
XXXX XXXX mRNA XXXX XXXX XXXX ID=myTranscript;Parent=myGene
XXXX XXXX exon XXXX XXXX XXXX Parent=myTranscript
XXXX XXXX exon XXXX XXXX XXXX Parent=myTranscript
Then there will be one group called myGene containing the "gene" feature and one group called myTranscript containing the mRNA, and two exons.
You <em>can</em> work around this restriction to some extent by using the Alias attribute literally, like so:
XXXX XXXX gene XXXX XXXX XXXX ID=myGene
XXXX XXXX mRNA XXXX XXXX XXXX ID=myTranscript;Parent=myGene;Alias=myGene
XXXX XXXX exon XXXX XXXX XXXX Parent=myTranscript;Alias=myGene
XXXX XXXX exon XXXX XXXX XXXX Parent=myTranscript;Alias=myGene
This limitation will be corrected in the next version of Bio::DB::GFF. ๐
๐ฅ API ๐ฅ
Okay bestie, here's the whole entire API for Bio::DB::GFF. Buckle up. ๐
๐พ Querying GFF Databases ๐พ
โจ new โจ
Title : new
Usage : my $db = Bio::DB::GFF->new(@args);
Function: create a new Bio::DB::GFF object
Returns : new Bio::DB::GFF object
Args : lists of adaptors and aggregators
Status : Public
These are the arguments, and I need you to actually read them because this is where the magic happens:
-adaptorโ Name of the adaptor module to use. If none provided, defaults to"dbi::mysqlopt".-aggregatorโ Array reference to a list of aggregators to apply to the database. If none provided, defaults to['processed_transcript','alignment'].-preferred_groupsโ When interpreting the 9th column of a GFF2 file, the indicated group names will have preference over other attributes, even if they do not come first in the list of attributes. This can be a scalar value or an array reference.<other>โ Any other named argument pairs are passed to the adaptor for processing.
The adaptor argument must correspond to a module contained within the Bio::DB::GFF::Adaptor namespace. For example, the Bio::DB::GFF::Adaptor::dbi::mysql adaptor is loaded by specifying 'dbi::mysql'. By Perl convention, the adaptors names are lower case because they are loaded at run time. iykyk ๐
The aggregator array may contain a list of aggregator names, a list of initialized aggregator objects, or a string in the form "aggregator_name{subpart1,subpart2,subpart3/main_method}" (the "/main_method" part is optional, but if present a feature with the main_method must be present in order for aggregation to occur). For example, if you wish to change the components aggregated by the transcript aggregator, you could pass it to the GFF constructor this way:
my $transcript =
Bio::DB::Aggregator::transcript->new(-sub_parts=>[qw(exon intron utr
polyA spliced_leader)]);
my $db = Bio::DB::GFF->new(-aggregator=>[$transcript,'clone','alignment],
-adaptor => 'dbi::mysql',
-dsn => 'dbi:mysql:elegans42');
Alternatively, you could create an entirely new transcript aggregator this way:
my $new_agg = 'transcript{exon,intron,utr,polyA,spliced_leader}';
my $db = Bio::DB::GFF->new(-aggregator=>[$new_agg,'clone','alignment],
-adaptor => 'dbi::mysql',
-dsn => 'dbi:mysql:elegans42');
See Bio::DB::GFF::Aggregator for more details. ๐
The -preferred_groups argument is used to change the default processing of the 9th column of GFF version 2 files. By default, the first tag/value pair is used to establish the group class and name. If you pass -preferred_groups a scalar, the parser will look for a tag of the indicated type and use it as the group even if it is not first in the file. If you pass this argument a list of group classes as an array ref, then the list will establish the precedence for searching. ๐ง
The commonly used 'dbi::mysql' adaptor recognizes the following adaptor-specific arguments:
-dsnโ the DBI data source, e.g.'dbi:mysql:ens0040'. If a partial name is given, such as"ens0040", the"dbi:mysql:"prefix will be added automatically.-userโ username for authentication-passโ the password for authentication-refclassโ landmark Class; defaults to"Sequence"
The commonly used 'dbi::mysqlopt' adaptor also recognizes the following arguments.
-fastaโ path to a directory containing FASTA files for the DNA contained in this database (e.g."/usr/local/share/fasta")-acedbโ an acedb URL to use when converting features into ACEDB objects (e.g.sace://localhost:2005)
๐ธ types ๐ธ
Title : types
Usage : $db->types(@args)
Function: return list of feature types in range or database
Returns : a list of Bio::DB::GFF::Typename objects
Args : see below
Status : public
This routine returns a list of feature types known to the database. The list can be database-wide or restricted to a region. It is also possible to find out how many times each feature occurs. Obsessed, honestly. โจ
For range queries, it is usually more convenient to create a Bio::DB::GFF::Segment object, and then invoke it's types() method. ๐
Arguments are as follows:
-refโ ID of reference sequence-classโ class of reference sequence-startโ start of segment-stopโ stop of segment-enumerateโ if true, count the features
The returned value will be a list of Bio::DB::GFF::Typename objects, which if evaluated in a string context will return the feature type in "method:source" format. This object class also has method() and source() methods for retrieving the like-named fields. ๐ซถ
If -enumerate is true, then the function returns a hash (not a hash reference) in which the keys are type names in "method:source" format and the values are the number of times each feature appears in the database or segment. No cap. ๐ฏ
The argument -end is a synonym for -stop, and -count is a synonym for -enumerate. Two for one, we love to see it. ๐
๐ฆ classes ๐ฆ
Title : classes
Usage : $db->classes
Function: return list of landmark classes in database
Returns : a list of classes
Args : none
Status : public
This routine returns the list of reference classes known to the database, or empty if classes are not used by the database. Classes are distinct from types, being essentially qualifiers on the reference namespaces. Lowkey a whole different vibe. ๐
๐ segment ๐
Title : segment
Usage : $db->segment(@args);
Function: create a segment object
Returns : segment object(s)
Args : numerous, see below
Status : public
This method generates a segment object, which is a Perl object subclassed from Bio::DB::GFF::Segment. The segment can be used to find overlapping features and the raw DNA. ๐งฌ
When making the segment() call, you specify the ID of a sequence landmark (e.g. an accession number, a clone or contig), and a positional range relative to the landmark. If no range is specified, then the entire extent of the landmark is used to generate the segment.
You may also provide the ID of a "reference" sequence, which will set the coordinate system and orientation used for all features contained within the segment. The reference sequence can be changed later. If no reference sequence is provided, then the coordinate system is based on the landmark.
Arguments:
-nameโ ID of the landmark sequence.-classโ Database object class for the landmark sequence."Sequence"assumed if not specified. This is irrelevant for databases which do not recognize object classes.-startโ Start of the segment relative to landmark. Positions follow standard 1-based sequence rules. If not specified, defaults to the beginning of the landmark.-endโ Stop of the segment relative to the landmark. If not specified, defaults to the end of the landmark.-stopโ Same as-end.-offsetโ For those who prefer 0-based indexing, the offset specifies the position of the new segment relative to the start of the landmark.-lengthโ For those who prefer 0-based indexing, the length specifies the length of the new segment.-refseqโ Specifies the ID of the reference landmark used to establish the coordinate system for the newly-created segment.-refclassโ Specifies the class of the reference landmark, for those databases that distinguish different object classes. Defaults to"Sequence".-absoluteโ Return features in absolute coordinates rather than relative to the parent segment.-nocheckโ Don't check the database for the coordinates and length of this feature. Construct a segment using the indicated name as the reference, a start coordinate of 1, an undefined end coordinate, and a strand of+1.-forceโ Same as-nocheck.-seq,-sequence,-sourceseqโ Aliases for-name.-begin,-endโ Aliases for-startand-stop-off,-lenโ Aliases for-offsetand-length-seqclassโ Alias for-class
Here's an example to explain how this works:
my $db = Bio::DB::GFF->new(-dsn => 'dbi:mysql:human',-adaptor=>'dbi::mysql');
If successful, $db will now hold the database accessor object. We now try to fetch the fragment of sequence whose ID is A0000182 and class is "Accession." ๐
my $segment = $db->segment(-name=>'A0000182',-class=>'Accession');
If successful, $segment now holds the entire segment corresponding to this accession number. By default, the sequence is used as its own reference sequence, so its first base will be 1 and its last base will be the length of the accession.
Assuming that this sequence belongs to a longer stretch of DNA, say a contig, we can fetch this information like so:
my $sourceseq = $segment->sourceseq;
and find the start and stop on the source like this:
my $start = $segment->abs_start;
my $stop = $segment->abs_stop;
If we had another segment, say $s2, which is on the same contiguous piece of DNA, we can pass that to the refseq() method in order to establish it as the coordinate reference point:
$segment->refseq($s2);
Now calling start() will return the start of the segment relative to the beginning of $s2, accounting for differences in strandedness:
my $rel_start = $segment->start;
IMPORTANT NOTE: This method can be used to return the segment spanned by an arbitrary named annotation. However, if the annotation appears at multiple locations on the genome, for example an EST that maps to multiple locations, then, provided that all locations reside on the same physical segment, the method will return a segment that spans the minimum and maximum positions. If the reference sequence occupies ranges on different physical segments, then it returns them all in an array context, and raises a "multiple segment exception" exception in a scalar context. ๐ญ
๐ฅ features ๐ฅ
Title : features
Usage : $db->features(@args)
Function: get all features, possibly filtered by type
Returns : a list of Bio::DB::GFF::Feature objects
Args : see below
Status : public
This routine will pull features out of the database and it literally does not care where they sit position-wise ๐ . Use it to grab everything, or just a slice of it filtered by method and source. So versatile, we stan.
Here's the tea on the arguments:
-typesโ the list of feature types you want back. It's an array ref full of strings shaped like"method:source".-mergeโ do we apply aggregators to the features we generate? yes/no.-rareโ flips on optimizations for a pretty rare feature type, where it makes way more sense to filter by feature type first and then by position.-attributesโ a hash ref stuffed with attributes to match.-iteratorโ should we hand you back an iterator over the features?-binsizeโ a true value here builds a set of artificial features whose start and stop positions mark bins of the given size, and whose scores are the number of features in that bin. The feature's class and method get set to"bin", its source to"method:source", and its group to"bin:method:source". Honestly such a handy way to make histograms of feature density ๐.
If -iterator is true, the method returns one single scalar value: a Bio::SeqIO object โจ. You can just call next_seq() on it over and over to fetch each feature in turn. If iterator is false or missing entirely, then all the features come back as a list.
Currently aggregation is disabled when iterating over a series of features. Just so you know, bestie.
Types get indicated using the nomenclature "method:source". Either of those fields can be left out, and when it is, a wildcard slides into the missing slot ๐. Type names with no colon (like "exon") get read as the method name plus a source wild card. Regular expressions are allowed in either field, like this: "similarity:BLAST.*".
The -attributes argument is a hashref holding one or more attributes to match against:
-attributes => { Gene => 'abc-1',
Note => 'confirmed' }
Attribute matching is plain string matching, and multiple attributes get ANDed together. No cap.
get_seq_stream
Title : get_seq_stream
Usage : my $seqio = $self->get_seq_sream(@args)
Function: Performs a query and returns an iterator over it
Returns : a Bio::SeqIO stream capable of producing sequence
Args : As in features()
Status : public
This routine takes the exact same arguments as features(), but it hands you back a Bio::SeqIO::Stream-compliant object instead ๐ฆ. Use it like this:
$stream = $db->get_seq_stream('exon');
while (my $exon = $stream->next_seq) {
print $exon,"\n";
}
NOTE: This is also called get_feature_stream(), because that's literally what it really does ๐.
get_feature_by_name
Title : get_feature_by_name
Usage : $db->get_feature_by_name($class => $name)
Function: fetch features by their name
Returns : a list of Bio::DB::GFF::Feature objects
Args : the class and name of the desired feature
Status : public
This method fetches a named feature straight from the database. GFF annotations get named using the group class and name fields, so for features that belong to a group of size one, this method can grab that group โ and it's equivalent to the segment() method, iconic โจ. Any Alias attributes also get searched for matching names.
There's an alternative syntax that lets you search for features by name inside a circumscribed region:
@f = $db->get_feature_by_name(-class => $class,-name=>$name,
-ref => $sequence_name,
-start => $start,
-end => $end);
This method may return zero, one, or several Bio::DB::GFF::Feature objects. Could be anything, fr fr.
Aggregation gets performed on features as usual.
NOTE: At various times, this function was calledfetch_group(),fetch_feature(),fetch_feature_by_name()andsegments(). These names are preserved for backward compatibility ๐ซถ.
get_feature_by_target
Title : get_feature_by_target
Usage : $db->get_feature_by_target($class => $name)
Function: fetch features by their similarity target
Returns : a list of Bio::DB::GFF::Feature objects
Args : the class and name of the desired feature
Status : public
This method fetches a named feature from the database based on its similarity hit. Slay.
get_feature_by_attribute
Title : get_feature_by_attribute
Usage : $db->get_feature_by_attribute(attribute1=>value1,attribute2=>value2)
Function: fetch segments by combinations of attribute values
Returns : a list of Bio::DB::GFF::Feature objects
Args : the class and name of the desired feature
Status : public
This method fetches a whole set of features from the database. Attributes are a list of name=>value pairs, and they get logically ANDED together. Periodt.
get_feature_by_id
Title : get_feature_by_id
Usage : $db->get_feature_by_id($id)
Function: fetch segments by feature ID
Returns : a Bio::DB::GFF::Feature object
Args : the feature ID
Status : public
This method fetches a feature from the database using its ID. โ ๏ธ But heads up bestie โ not all GFF databases support IDs, so be careful with this one.
get_feature_by_gid
Title : get_feature_by_gid
Usage : $db->get_feature_by_gid($id)
Function: fetch segments by feature ID
Returns : a Bio::DB::GFF::Feature object
Args : the feature ID
Status : public
This method fetches a feature from the database using its group ID. Again โ not all GFF databases support IDs, so be careful ๐ .
The group ID is often way more interesting than the feature ID, since groups can be complex objects containing subobjects. Main character energy, honestly ๐.
delete_fattribute_to_features
Title : delete_fattribute_to_features
Usage : $db->delete_fattribute_to_features(@ids_or_features)
Function: delete one or more fattribute_to_features
Returns : count of fattribute_to_features deleted
Args : list of features or feature ids
Status : public
Hand this method a list of numeric feature ids or a set of features. It'll attempt to remove the fattribute_to_features rows of those features from the database and hand you back a count of the rows it removed.
NOTE: This method is also calleddelete_fattribute_to_feature(). Also seedelete_groups()anddelete_features().
delete_features
Title : delete_features
Usage : $db->delete_features(@ids_or_features)
Function: delete one or more features
Returns : count of features deleted
Args : list of features or feature ids
Status : public
Pass this method a list of numeric feature ids or a set of features. It'll attempt to remove the features from the database and return a count of the features removed. Bye bye ๐.
NOTE: This method is also calleddelete_feature(). Also seedelete_groups().
delete_groups
Title : delete_groups
Usage : $db->delete_groups(@ids_or_features)
Function: delete one or more feature groups
Returns : count of features deleted
Args : list of features or feature group ids
Status : public
Pass this method a list of numeric group ids or a set of features. It'll attempt to recursively remove the features and ALL members of their group from the database. It returns a count of the number of features (not groups) returned. Not me deleting the whole squad ๐ญ.
NOTE: This method is also calleddelete_group(). Also seedelete_features().
delete
Title : delete
Usage : $db->delete(@args)
Function: delete features
Returns : count of features deleted -- if available
Args : numerous, see below
Status : public
This method deletes every feature that overlaps the specified region, or that's of a particular type. If you give it no arguments and the -force argument is true, then it deletes ALL the features. Everything. Gone. ๐
Arguments:
-nameโ ID of the landmark sequence.-refโ ID of the landmark sequence (synonym for-name).-classโ database object class for the landmark sequence."Sequence"is assumed if you don't specify it. This is irrelevant for databases that don't recognize object classes.-startโ start of the segment relative to landmark. Positions follow standard 1-based sequence rules. If you don't specify it, it defaults to the beginning of the landmark.-endโ stop of the segment relative to the landmark. If you don't specify it, it defaults to the end of the landmark.-offsetโ zero-based addressing.-lengthโ length of region.-type,-typesโ either a single scalar type to be deleted, or a reference to an array of types.-forceโ force the operation to be performed even if it would delete the entire feature table. ๐จ-range_typeโ control the range type of the deletion. One of"overlaps"(the default),"contains"or"contained_in".
Examples:
$db->delete(-type=>['intron','repeat:repeatMasker']); # remove all introns & repeats
$db->delete(-name=>'chr3',-start=>1,-end=>1000); # remove annotations on chr3 from 1 to 1000
$db->delete(-name=>'chr3',-type=>'exon'); # remove all exons on chr3
The short form of this call, as described in segment(), is also allowed:
$db->delete("chr3",1=>1000);
$db->delete("chr3");
IMPORTANT NOTE: This method only deletes features. It does NOT delete the names of groups that contain the deleted features. Group IDs will be reused if you later load a feature with the same group name as one that was previously deleted. Iykyk ๐.
NOTE ON FEATURE COUNTS: The DBI-based versions of this call return the result code from the SQLDELETEoperation. Some dbd drivers return the count of rows deleted, while others return0E0. Caveat emptor.
absolute
Title : absolute
Usage : $abs = $db->absolute([$abs]);
Function: gets/sets absolute mode
Returns : current setting of absolute mode boolean
Args : new setting for absolute mode boolean
Status : public
$db->absolute(1) turns on absolute mode for the entire database โจ. Every segment retrieved will use absolute coordinates by default instead of relative coordinates. You can still make them use relative coordinates by calling $segment->absolute(0).
Note that this is not the same as calling abs_segment() โ it keeps on letting you look up groups that aren't used directly as reference sequences. Subtle but important, bestie ๐ฆ.
strict_bounds_checking
Title : strict_bounds_checking
Usage : $flag = $db->strict_bounds_checking([$flag])
Function: gets/sets strict bounds checking
Returns : current setting of bounds checking flag
Args : new setting for bounds checking flag
Status : public
This flag turns on extra checks for segment requests that go wayyy past the ends of their reference sequences ๐. So if bounds checking is on, the segments you get back get truncated to their physical length, and their truncated() methods will return true โ bestie they're being honest about it now ๐
.
If the flag is off (and that's the default, no cap), then the module will hand you back segments that appear to extend beyond their physical boundaries. Requests for features beyond the end of the segment will, however, return empty โ so it's giving "yes the segment exists" but "no there's nothing out there" ๐ซ .
get_Seq_by_id ๐
- Title:
get_Seq_by_id - Usage:
$seq = $db->get_Seq_by_id('ROA1_HUMAN') - Function: Gets a Bio::Seq object by its name
- Returns: a Bio::Seq object
- Args: the id (as a string) of a sequence
- Throws:
"id does not exist"exception
NOTE: Bio::DB::RandomAccessI compliant method โจ
get_Seq_by_accession ๐ฆ
- Title:
get_Seq_by_accession - Usage:
$seq = $db->get_Seq_by_accession('AL12234') - Function: Gets a Bio::Seq object by its accession
- Returns: a Bio::Seq object
- Args: the id (as a string) of a sequence
- Throws:
"id does not exist"exception
NOTE: Bio::DB::RandomAccessI compliant method โจ
get_Seq_by_acc ๐ธ
- Title:
get_Seq_by_acc - Usage:
$seq = $db->get_Seq_by_acc('X77802'); - Function: Gets a Bio::Seq object by accession number
- Returns: A Bio::Seq object
- Args: accession number (as a string)
- Throws:
"acc does not exist"exception
NOTE: Bio::DB::RandomAccessI compliant method โจ
get_Stream_by_name ๐ง
- Title:
get_Stream_by_name - Usage:
$seq = $db->get_Stream_by_name(@ids); - Function: Retrieves a stream of Seq objects given their names
- Returns: a Bio::SeqIO stream object
- Args: an array of unique ids/accession numbers, or an array reference
NOTE: This is also called get_Stream_by_batch() ๐ซ
get_Stream_by_id ๐
- Title:
get_Stream_by_id - Usage:
$seq = $db->get_Stream_by_id(@ids); - Function: Retrieves a stream of Seq objects given their ids
- Returns: a Bio::SeqIO stream object
- Args: an array of unique ids/accession numbers, or an array reference
NOTE: This is also called get_Stream_by_batch() ๐ซ
get_Stream_by_batch () ๐
- Title:
get_Stream_by_batch - Usage:
$seq = $db->get_Stream_by_batch(@ids); - Function: Retrieves a stream of Seq objects given their ids
- Returns: a Bio::SeqIO stream object
- Args: an array of unique ids/accession numbers, or an array reference
NOTE: This is the same as get_Stream_by_id(). Periodt ๐
get_Stream_by_group () ๐
Bioperl compatibility. That's it, that's the whole vibe โจ.
all_seqfeatures ๐
- Title:
all_seqfeatures - Usage:
@features = $db->all_seqfeatures(@args) - Function: fetch all the features in the database
- Returns: an array of features, or an iterator
- Args: See below
- Status: public
This is equivalent to calling $db->features() without any types, and it will return all the features in the database โ every single one, bestie, no filter ๐ซถ. The -merge and -iterator arguments are recognized here, and they behave the same as described for features() ๐.
๐ Creating and Loading GFF Databases ๐
initialize
Title : initialize
Usage : $db->initialize(-erase=>$erase,-option1=>value1,-option2=>value2);
Function: initialize a GFF database
Returns : true if initialization successful
Args : a set of named parameters
Status : Public
okay so this one spins up a whole fresh empty database for you ๐. It takes these named args:
-eraseโ a boolean. If it's true, the database gets wiped clean if it already has data in it. Like, gone. Poof. ๐
Other named args might get picked up by subclasses โ those turn into database meta values that control all the various settable options.
And as a lil shortcut (plus for backward compatibility ๐ซถ), passing a single true argument is exactly the same as calling initialize(-erase=>1).
load_gff
Title : load_gff
Usage : $db->load_gff($file|$directory|$filehandle [,$verbose]);
Function: load GFF data into database
Returns : count of records loaded
Args : a directory, a file, a list of files,
or a filehandle
Status : Public
This one takes a single overloaded argument, bestie, and it can be any of these:
- a scalar that points at a GFF file on the system
A pathname to a local GFF file. Any files ending in .gz, .Z, or .bz2 get transparently decompressed with the appropriate command-line utility โจ.
- an array reference holding a list of GFF files on the system
For example ['/home/gff/gff1.gz','/home/gff/gff2.gz']
- a directory path
The directory you point at gets searched for all files ending in .gff, .gff.gz, .gff.Z or .gff.bz2 ๐.
- a filehandle
An open filehandle to read the GFF data from. Tied filehandles work now too, no cap.
- a pipe expression
Yep, a pipe expression works as well. For example, a GFF file sitting on a remote web server can be loaded with an expression like this:
$db->load_gff("lynx -dump -source http://stein.cshl.org/gff_test |");
The optional second argument, if it's true, turns on verbose status reports so you can watch the progress ๐.
If it works, the method returns the number of GFF lines successfully loaded ๐.
NOTE: this method used to be called load(), but it got changed. The old method name is still recognized though, so you're not stranded.
load_gff_file
Title : load_gff_file
Usage : $db->load_gff_file($file [,$verbose]);
Function: load GFF data into database
Returns : count of records loaded
Args : a path to a file
Status : Public
This is here as an alternative to load_gff_file. It doesn't munge STDIN or play tricks with ARGV ๐.
load_fasta
Title : load_fasta
Usage : $db->load_fasta($file|$directory|$filehandle);
Function: load FASTA data into database
Returns : count of records loaded
Args : a directory, a file, a list of files,
or a filehandle
Status : Public
Same energy as load_gff, but for FASTA ๐
. Single overloaded argument, any of:
- a scalar corresponding to a FASTA file on the system
A pathname to a local FASTA file. Any files ending in .gz, .Z, or .bz2 get transparently decompressed with the appropriate command-line utility.
- an array reference containing a list of FASTA files on the system
For example ['/home/fasta/genomic.fa.gz','/home/fasta/genomic.fa.gz']
- a path to a directory
The directory gets searched for all files ending in .fa, .fa.gz, .fa.Z or .fa.bz2.
- a filehandle
An open filehandle to read the FASTA data from.
- a pipe expression
A pipe expression works too. For example, a FASTA file on a remote web server can be loaded with an expression like this:
$db->load_gff("lynx -dump -source http://stein.cshl.org/fasta_test.fa |");
load_fasta_file
Title : load_fasta_file
Usage : $db->load_fasta_file($file [,$verbose]);
Function: load FASTA data into database
Returns : count of records loaded
Args : a path to a file
Status : Public
Here as an alternative to load_fasta. Doesn't munge STDIN or play tricks with ARGV ๐ซถ.
load_sequence_string
Title : load_sequence_string
Usage : $db->load_sequence_string($id,$dna)
Function: load a single DNA entry
Returns : true if successfully loaded
Args : a raw sequence string (DNA, RNA, protein)
Status : Public
lock_on_load
Title : lock_on_load
Usage : $lock = $db->lock_on_load([$lock])
Function: set write locking during load
Returns : current value of lock-on-load flag
Args : new value of lock-on-load-flag
Status : Public
Some of the adaptors honor this one. If the value is true, the tables the GFF modules use get locked for writing during loads โ which means other processes can't touch them while that's happening ๐.
meta
Title : meta
Usage : $value = $db->meta($name [,$newval])
Function: get or set a meta variable
Returns : a string
Args : meta variable name and optionally value
Status : abstract
Get or set a named metavalue for the database. Metavalues are for database-specific settings.
By default, this method does nothing! ๐ (it's abstract, so subclasses are the ones doing the actual work)
default_meta_values
Title : default_meta_values
Usage : %values = $db->default_meta_values
Function: empty the database
Returns : a list of tag=>value pairs
Args : none
Status : protected
This hands you back a list of tag=>value pairs containing the default meta info about the database. It gets invoked by initialize() to write out those default meta values. The base class version just returns an empty list ๐.
For things to work properly, meta value names must be UPPERCASE. periodt.
error
Title : error
Usage : $db->error( [$new error] );
Function: read or set error message
Returns : error message
Args : an optional argument to set the error message
Status : Public
Use this to grab the last error message. Heads up though: errors are not reset to empty by successful calls, so the contents are only valid immediately after an error condition has been detected ๐ญ. Don't trust a stale read.
debug
Title : debug
Usage : $db->debug( [$flag] );
Function: read or set debug flag
Returns : current value of debug flag
Args : new debug flag (optional)
Status : Public
Flip this on to turn on debug messages โจ. What those messages actually look like depends entirely on the adaptor in use.
automerge
Title : automerge
Usage : $db->automerge( [$new automerge] );
Function: get or set automerge value
Returns : current value (boolean)
Args : an optional argument to set the automerge value
Status : Public
By default this module uses the aggregators to merge groups into single composite objects. You can flip that default to false by calling automerge(0) ๐
.
attributes
Title : attributes
Usage : @attributes = $db->attributes($id,$name)
Function: get the "attributes" on a particular feature
Returns : an array of string
Args : feature ID
Status : public
Some GFF version 2 files use the groups column to store a series of attribute/value pairs. In this interpretation of GFF, the first such pair is treated as the primary group for the feature, and everything after it is treated as attributes. Two of these attributes have special meaning: "Note" is there for backward compatibility and is used for unstructured text remarks. "Alias" is considered a synonym for the feature name ๐ท๏ธ.
If you don't give a name, attributes() returns a flattened hash of attribute=>value pairs. That lets you do:
%attributes = $db->attributes($id);
If you give no arguments at all, attributes() returns the list of all attribute names:
@attribute_names = $db->attributes();
Normally though, attributes() gets called by the feature:
@notes = $feature->attributes('Note');
In scalar context, attributes() returns the first value of the attribute if a tag is present โ otherwise it hands back a hash reference where the keys are attribute names and the values are anonymous arrays containing the values ๐.
fast_queries
Title : fast_queries
Usage : $flag = $db->fast_queries([$flag])
Function: turn on and off the "fast queries" option
Returns : a boolean
Args : a boolean flag (optional)
Status : public
The mysql database driver (and possibly others) supports a "fast" query mode that caches results server-side. That makes queries come back faster, especially when you're creating iterators ๐ฅ. The downside? While you're iterating, new queries will die with a "command synch" error ๐. This method turns the feature on and off.
For databases that don't support a fast query, this method has no effect at all.
add_aggregator
Title : add_aggregator
Usage : $db->add_aggregator($aggregator)
Function: add an aggregator to the list
Returns : nothing
Args : an aggregator
Status : public
This appends an aggregator to the end of the list of registered aggregators. Three different argument types are accepted:
- a
Bio::DB::GFF::Aggregatorobject โ it will be added - a string in the form
"aggregator_name{subpart1,subpart2,subpart3/main_method}"โ it gets turned into aBio::DB::GFF::Aggregatorobject (the/main_methodpart is optional) - a valid Perl token โ it gets turned into a
Bio::DB::GFF::Aggregatorsubclass, where the token corresponds to the subclass name
aggregators
Title : aggregators
Usage : $db->aggregators([@new_aggregators]);
Function: retrieve list of aggregators
Returns : list of aggregators
Args : a list of aggregators to set (optional)
Status : public
Get or set the list of aggregators assigned to the database. If you pass 1 or more arguments, the existing set gets cleared first ๐ธ.
clear_aggregators
Title : clear_aggregators
Usage : $db->clear_aggregators
Function: clears list of aggregators
Returns : nothing
Args : none
Status : public
Wipes the aggregators stored in the database object. Use aggregators() or add_aggregator() to add some back ๐งน.
preferred_groups
Title : preferred_groups
Usage : $db->preferred_groups([$group_name_or_arrayref])
Function: get/set list of groups for altering GFF2 parsing
Returns : a list of classes
Args : new list (scalar or array ref)
Status : public
โจ Methods for use by Subclasses โจ
okay bestie, this next batch is lowkey not for you. Straight from the source: "The following methods are chiefly of interest to subclasses and are not intended for use by end programmers." So if you're just vibing at the top level, this is background lore. If you're writing a subclass though? This is your whole personality now. ๐
abscoords
- Title:
abscoords - Usage:
$db->abscoords($name,$class,$refseq) - Function: finds position of a landmark in reference coordinates
- Returns:
($ref,$class,$start,$stop,$strand) - Args: name and class of landmark
- Status: public
Bio::DB::GFF::RelSegment calls this one to figure out where a sequence landmark actually lives in absolute coordinates. You hand it the name and the class of the landmark. If it works out, abscoords() gives you back the ID of the reference sequence, its class, its start and stop positions, and which way the reference sequence's coordinate system is pointing โ "+" for forward strand, "-" for reverse strand. ๐งญ
And if $refseq shows up in the argument list, it forces the query to go hunt for that landmark inside one specific reference sequence. no wandering. ๐ฏ
do_load_gff
- Title:
do_load_gff - Usage:
$db->do_load_gff($handle) - Function: load a GFF input stream
- Returns: number of features loaded
- Args: A filehandle.
- Status: protected
This is the one that gets called to load a GFF data stream. It reads GFF features from <> and shoves them into the database, and when it's done it has to return the number of features loaded. Like, that's the assignment. ๐
Heads up: this method is the one responsible for parsing the GFF lines itself. Why? Because everyone and their cousin interprets the "group" field differently โ and those interpretations are, in the original's own words, legion. ๐ญ
You probably want to use load_gff() instead. It's way more flexible about the arguments it accepts. slay
load_sequence
- Title:
load_sequence - Usage:
$db->load_sequence($handle) - Function: load a FASTA data stream
- Returns: number of sequences
- Args: a filehandle to the FASTA file
- Status: protected
Yeah bestie, you probably want to use load_fasta() instead. ๐ซถ
setup_load
- Title:
setup_load - Usage:
$db->setup_load - Function: called before
load_gff_line() - Returns: void
- Args: none
- Status: abstract
This abstract method gives subclasses a little window to do any schema-specific initialization before a whole set of GFF records gets loaded. It's abstract, so somebody has to implement it โ that somebody is a subclass, and if you're the subclass, that's you. ๐
finish_load
- Title:
finish_load - Usage:
$db->finish_load - Function: called after
load_gff_line() - Returns: number of records loaded
- Args: none
- Status: abstract
Same energy, opposite end of the party: this gives subclasses a chance to do schema-specific cleanup after a set of GFF records has been loaded. ๐งน
load_gff_line
- Title:
load_gff_line - Usage:
$db->load_gff_line(@args) - Function: called to load one parsed line of GFF
- Returns: true if successfully inserted
- Args: see below
- Status: abstract
Another abstract one โ it gets called once per line of the GFF, and it's handed a hashref stuffed with all the parsed GFF fields. Which fields, you ask? These ones, exactly:
{ref => $ref,
class => $class,
source => $source,
method => $method,
start => $start,
stop => $stop,
score => $score,
strand => $strand,
phase => $phase,
gclass => $gclass,
gname => $gname,
tstart => $tstart,
tstop => $tstop,
attributes => $attributes}
not a single field left behind โจ
do_initialize
- Title:
do_initialize - Usage:
$db->do_initialize([$erase]) - Function: initialize and possibly erase database
- Returns: true if successful
- Args: optional erase flag
- Status: protected
This is the implementation behind initialize() (described above, in an earlier part of this page), and it takes the same arguments. Yes, including the optional erase flag. Yes, that erase flag means exactly what you think it means. ๐
dna
- Title:
dna - Usage:
$db->dna($id,$start,$stop,$class) - Function: return the raw DNA string for a segment
- Returns: a raw DNA string
- Args: id of the sequence, its class, start and stop positions
- Status: public
Bio::DB::GFF::Segment calls this one when it needs the actual raw DNA sequence. ๐งฌ The arguments are:
-name sequence name
-start start position
-stop stop position
-class sequence class
If both start and stop are undef, you get the entire DNA. So to grab the whole thing, call it like this:
$db->dna($name_of_sequence);
or like this:
$db->dna(-name=>$name_of_sequence,-class=>$class_of_sequence);
NOTE: you will probably prefer to create a Segment and then invoke its dna() method. That's the move. ๐
get_dna
- Title:
get_dna - Usage:
$db->get_dna($id,$start,$stop,$class) - Function: get DNA for indicated segment
- Returns: the dna string
- Args: sequence ID, start, stop and class
- Status: protected
Important vibe: if start > stop and the sequence is nucleotide, then this method should return the reverse complement. ๐ The sequence class may just get ignored by databases that don't recognize different object types โ they're not being rude, they just can't tell. ๐
get_features
- Title:
get_features - Usage:
$db->get_features($search,$options,$callback) - Function: get list of features for a region
- Returns: count of number of features retrieved
- Args: see below
- Status: protected
First argument is a hash reference holding the search criteria. It's giving:
rangetypeโ One of "overlaps", "contains" or "contained_in". Tells you what kind of range query got requested.refseqโ ID of the landmark that establishes the absolute coordinate system.refclassโ Class of this landmark. Implementations that don't recognize such distinctions can just ignore it.startโ Start of the range, inclusive.stopโ Stop of the range, inclusive.typesโ Array reference containing the list of annotation types to fetch from the database. Each annotation type is itself an array reference made of[source,method].
Second argument is a hash reference with options that change how stuff gets retrieved:
sort_by_groupโ A flag. If true, the returned features get sorted by the group they're in. ๐๏ธsparseโ A flag. If true, it means the expected density of features is such that searching by type beats searching by range. If a fetch is taking forever, give this a try. ๐ขโก๏ธ๐binsizeโ A true value will create a set of artificial features whose start and stop positions indicate bins of the given size, and whose scores are the number of features in the bin. The class of the feature gets set to "bin", and its name to "method:source". It's a handy way to generate histograms of feature density. ๐ obsessed
Third argument, the $callback, is a code reference that retrieved features get passed to. More on it in a sec.
This routine is the one responsible for pulling arrays of GFF data out of the database and handing them to the callback subroutine. The callback does the work of building a Bio::DB::GFF::Feature object out of that data. The callback expects a list of 13 fields:
$refseq The reference sequence
$start feature start
$stop feature stop
$source feature source
$method feature method
$score feature score
$strand feature strand
$phase feature phase
$groupclass group class (may be undef)
$groupname group ID (may be undef)
$tstart target start for similarity hits (may be undef)
$tstop target stop for similarity hits (may be undef)
$feature_id A unique feature ID (may be undef)
These fields are in the same order as the raw GFF file โ the only glow-up is that the group column has been parsed into separate group class and group name fields. โจ
The feature ID, when it's provided, is a unique identifier of the feature line. The module does not depend on this ID in any way whatsoever, but it's available via Bio::DB::GFF->id() if you want it. In the dbi::mysql and dbi::mysqlopt adaptor, that ID is a unique row ID. In the acedb adaptor it just isn't used. ๐คทโโ๏ธ
feature_summary(), coverage_array()
The DBI adaptors provide methods for rapidly fetching coverage statistics across a region of interest. Please see Bio::DB::GFF::Adaptor::dbi for more information about these methods. iykyk ๐
_feature_by_name
- Title:
_feature_by_name - Usage:
$db->_feature_by_name($class,$name,$location,$callback) - Function: get a list of features by name and class
- Returns: count of number of features retrieved
- Args: name of feature, class of feature, and a callback
- Status: abstract
Internal-use-only energy. The callback arguments are the same as the ones make_feature() uses. This method must be overridden by subclasses โ no skipping. ๐ซ
_feature_by_id
- Title:
_feature_by_id - Usage:
$db->_feature_by_id($ids,$type,$callback) - Function: get a feature based
- Returns: count of number of features retrieved
- Args: arrayref to feature IDs to fetch
- Status: abstract
Also internal. This one fetches features either by their ID or by their group ID. $ids is an arrayref containing a list of IDs, $type is one of "feature" or "group", and $callback is a callback. Same callback arguments as make_feature() again. And yeah โ this method must be overridden by subclasses too. ๐
overlapping_features
- Title:
overlapping_features - Usage:
$db->overlapping_features(@args) - Function: get features that overlap the indicated range
- Returns: a list of Bio::DB::GFF::Feature objects
- Args: see below
- Status: public
Bio::DB::GFF::Segment->features() calls this to find every feature that overlaps a given range. But honestly? It's generally preferable to create the Segment first and then fetch the features. ๐ธ
This method takes set of named arguments:
-refseqโ the ID of the reference sequence, bestie ๐-classโ the class of that reference sequence-startโ where the range you want starts, inrefseqcoordinates-stopโ where that range stops, also inrefseqcoordinates-typesโ a list of the feature types you want back. The argument is an array reference holding strings formatted like"method:source"-parentโ a parentBio::DB::GFF::Segmentobject, which is what makes relative coordinates happen in the features you generate-rareโ flips on an optimization that's good for a feature type that's pretty rare. In that case it's faster to filter by feature type first and then by position, instead of the other way round-mergeโ whether to apply aggregators to the generated features-iteratorโ whether to hand you back an iterator across the features
So if -iterator is true, the method gives you back a single scalar value that's a Bio::SeqIO object. Call next_seq() on it over and over and it'll hand you each feature one at a time, no cap. If iterator is false or just not there, then all the features come back as a list instead.
Heads up, bestie: right now aggregation is disabled when you're iterating over a series of features. That's just how it is ๐ญ
Types get written with the nomenclature "method:source". You can leave either of those fields out, and a wildcard just slides in for whatever's missing. And a type name with no colon at all (like "exon") gets read as the method name plus a source wildcard. Regex is allowed in either field too, like:
similarity:BLAST.*
๐ contained_features ๐
Title : contained_features
Usage : $db->contained_features(@args)
Function: get features that are contained within the indicated range
Returns : a list of Bio::DB::GFF::Feature objects
Args : see overlapping_features()
Status : public
This one is basically overlapping_features()'s sibling, except it only pulls features whose end points sit completely inside the range you specified. Fully contained, fully slaying ๐
Most of the time you'll want to grab a Bio::DB::GFF::Segment object and call its contained_features() method instead of calling this directly. Just saying.
๐ธ contained_in ๐ธ
Title : contained_in
Usage : @features = $s->contained_in(@args)
Function: get features that contain this segment
Returns : a list of Bio::DB::GFF::Feature objects
Args : see features()
Status : Public
Behaviourally this is identical to features(), except it only gives you back the features that completely contain the segment. The opposite vibe of the last one, periodt.
โญ get_abscoords โญ
Title : get_abscoords
Usage : $db->get_abscoords($name,$class,$refseq)
Function: get the absolute coordinates of sequence with name & class
Returns : ($absref,$absstart,$absstop,$absstrand)
Args : name and class of the landmark
Status : protected
Give this function the name and class of a genomic landmark, and it hands you back a four-element array made of:
$absref the ID of the reference sequence that contains this landmark
$absstart the position at which the landmark starts
$absstop the position at which the landmark stops
$absstrand the strand of the landmark, relative to the reference sequence
And if you pass in $refseq, it only searches inside that one specified reference sequence. Iconic.
๐ฆ get_types ๐ฆ
Title : get_types
Usage : $db->get_types($absref,$class,$start,$stop,$count)
Function: get list of all feature types on the indicated segment
Returns : list or hash of Bio::DB::GFF::Typename objects
Args : see below
Status : protected
The arguments, bestie:
$absref the ID of the reference sequence
$class the class of the reference sequence
$start the position to start counting
$stop the position to end counting
$count a boolean indicating whether to count the number
of occurrences of each feature type
If $count is true, you get back a hash. The keys of that hash are feature type names formatted as "method:source", and the values are how many times a feature of that type overlaps the segment you pointed at. Otherwise the call returns a set of Bio::DB::GFF::Typename objects. And if $start or $stop is undef, then literally every feature on that segment gets enumerated. If $absref is undef, then you get all the feature types in the database. All of them. The whole roster ๐ญ๐
๐ make_feature ๐
Title : make_feature
Usage : $db->make_feature(@args)
Function: Create a Bio::DB::GFF::Feature object from string data
Returns : a Bio::DB::GFF::Feature object
Args : see below
Status : internal
This takes 14 arguments (really!):
$parent A Bio::DB::GFF::RelSegment object
$group_hash A hashref containing unique list of GFF groups
$refname The name of the reference sequence for this feature
$refclass The class of the reference sequence for this feature
$start Start of feature
$stop Stop of feature
$source Feature source field
$method Feature method field
$score Feature score field
$strand Feature strand
$phase Feature phase
$group_class Class of feature group
$group_name Name of feature group
$tstart For homologies, start of hit on target
$tstop Stop of hit on target
The $parent argument, if it's actually present, gets used to establish relative coordinates in the resulting Bio::DB::Feature object. That's the whole trick that lets one feature generate a list of other features that are relative to its own coordinate system โ like finding the coordinates of the second exon relative to the coordinates of the first. So cute, so useful ๐ซถ
The $group_hash lets the group_class/group_name strings get turned into rich database objects via the make_obect() method (see above). And because those objects can be expensive to create, $group_hash is what uniquefies them. The index of this hash is the composite key {$group_class,$group_name,$tstart,$tstop}. The values are whatever object make_object() returned.
The rest of the fields come straight off the GFF line, with one exception: "Target" features โ the ones carrying info about the target of a homology search โ get parsed into their components.
๐ make_match_sub ๐
Title : make_match_sub
Usage : $db->make_match_sub($types)
Function: creates a subroutine used for filtering features
Returns : a code reference
Args : a list of parsed type names
Status : protected
This method is used internally to generate a code subroutine that accepts or rejects a feature based on its method and source. It takes an array of parsed type names in the format that parse_types() returns, and it generates an anonymous subroutine. That subroutine takes a single Bio::DB::GFF::Feature object and returns true if the feature matches one of the desired feature types, and false otherwise. A little vibe check, but for features โจ
๐ง make_object ๐ง
Title : make_object
Usage : $db->make_object($class,$name,$start,$stop)
Function: creates a feature object
Returns : a feature object
Args : see below
Status : protected
This method gets called to make an object out of the GFF "group" field. By default, all Target groups become Bio::DB::GFF::Homol objects, and everything else becomes a Bio::DB::GFF::Featname. But adaptors are totally free to override this method and generate more interesting objects โ true BioPerl objects, Acedb objects, whatever gives โจ
The arguments:
$name database ID for object
$class class of object
$start for similarities, start of match inside object
$stop for similarities, stop of match inside object
๐ do_attributes ๐
Title : do_attributes
Usage : $db->do_attributes($id [,$tag]);
Function: internal method to retrieve attributes given an id and tag
Returns : a list of Bio::DB::GFF::Feature objects
Args : a feature id and a attribute tag (optional)
Status : protected
Subclasses override this one so it can return a list of attributes. Call it with a tag and you get the value of attributes of that tag type. Call it without a tag and you get a flattened array of (tag=>value) pairs. And yes โ a particular tag can show up multiple times. It's giving main character energy, honestly ๐
๐ clone ๐
The clone() method is the one you reach for when you want to pass the Bio::DB::GFF object to a child process across a fork(). The child must call clone() before making any queries. No exceptions, bestie.
The default behavior is to do nothing at all. But adaptors that use the DBI interface might need to implement this so they can dodge database handle errors. See the dbi adaptor for an example.
๐ซฃ Internal Methods
Okay bestie, listen โ these ones are internal. That means they're the plumbing behind the walls, the unglamorous little gremlins that keep the lights on. They are not guaranteed to remain the same, so do not build your whole personality around them, mmkay? ๐
๐ธ _features
- Title โ
_features - Usage โ
$db->_features($search,$options,$parent) - Function โ internal method
- Returns โ a list of
Bio::DB::GFF::Featureobjects - Args โ see below
- Status โ internal
So this is an internal method, and it's the one that overlapping_features(), contained_features() and features() all call to actually build features off a parent segment's coordinate system. She's the workhorse fr fr. She takes three arguments: a search options hashref, an options hashref, and a parent segment. ๐
The search hashref has these keys in it:
rangetype One of "overlaps", "contains" or "contained_in". Indicates
the type of range query requested.
refseq reference sequence ID
refclass reference sequence class
start start of range
stop stop of range
types arrayref containing list of types in "method:source" form
The options hashref can have zero or more of these:
sparse turn on optimizations for a rare feature
automerge if true, invoke aggregators to merge features
iterator if true, return an iterator
And the $parent argument? She's a scalar object holding a Bio::DB::GFF::RelSegment object (or one of its descendants). ๐
โจ get_features_iterator
- Title โ
get_features_iterator - Usage โ
$db->get_features_iterator($search,$options,$callback) - Function โ get an iterator on a features query
- Returns โ a
Bio::SeqIOobject - Args โ as per
get_features() - Status โ Public
She takes the exact same args as get_features(), but instead of dumping everything on you at once she hands back an iterator you can use to pull features one at a time, sequentially, just like Bio::SeqIO does. Chill, patient, no chaos. ๐ฆ
Internally she's literally just a front end for range_query(). That one does the actual building and running of the query and returns a statement handle; our girl here takes that statement handle and passes it straight to the iterator constructor, along with the callback. Delegation, slay. ๐
๐ split_group
- Title โ
split_group - Usage โ
$db->split_group($group_field,$gff3_flag) - Function โ parse GFF group field
- Returns โ
($gclass,$gname,$tstart,$tstop,$attributes) - Args โ the gff group column and a flag indicating gff3 compatibility
- Status โ internal
Called by load_gff_line to parse out the contents of one or more group fields. She gives you back the class of the group, its name, the start and stop of the target (if there is one), and an array reference stuffed with any attributes that got crammed into the group field, formatted as [attribute_name,attribute_value]. ๐
๐ _split_gff2_group
An internal method, called by split_group(). That's it, that's the whole blurb. She's shy. ๐
๐ง gff3_name_munging
- Title โ
gff3_name_munging - Usage โ
$db->gff3_name_munging($boolean) - Function โ get/set gff3_name_munging flag
- Returns โ
$currentvalue of flag - Args โ new value of flag (optional)
- Status โ utility
Set this to true (default is false, jsyk) and features in gff3 files that have an ID shaped like foo:bar get parsed so that "foo" becomes the class and "bar" becomes the name. It's mostly there for backward compatibility with GFF2, aka giving the old format a lil hug. ๐ซถ
๐ซ _split_gff3_group
Called internally from split_group(). Short and sweet, no notes. โญ
๐ _delete_features(), _delete_groups(), _delete(), _delete_fattribute_to_features()
- Title โ
_delete_features(),_delete_groups(),_delete(),_delete_fattribute_to_features() - Usage โ
$count = $db->_delete_features(@feature_ids)
$count = $db->_delete_groups(@group_ids)
$count = $db->_delete(\%delete_spec)
$count = $db->_delete_fattribute_to_features(@feature_ids)
- Function โ low-level feature/group deleter
- Returns โ count of groups removed
- Args โ list of feature or group ids removed
- Status โ for implementation by subclasses
These ones have to be implemented in adaptors โ they're abstract, so don't come crying to the base class. ๐ญ
For _delete_features, _delete_groups and _delete_fattribute_to_features, the arguments are a list of feature or group IDs to remove.
For _delete(), the argument is a hashref with three keys: 'segments', 'types' and 'force'.
'segments'holds an arrayref ofBio::DB::GFF::RelSegmentobjects to delete โ and note that all FEATURES within the segment are deleted. ๐'types'holds an arrayref of[method,source]feature types to delete.- The two are ANDed together.
- If
'force'is true, the operation is forced to keep going even if it would delete all features. That is genuinely unhinged behaviour, so use with care bestie. ๐
๐ญ BUGS
- Features can only belong to a single group at a time. This must be addressed soon. (Justice for polyamorous features.)
- Start coordinate can be greater than stop coordinate for relative addressing. This breaks strict BioPerl compatibility and must be fixed. She's a little chaotic like that, ngl.
๐ SEE ALSO
Bio::DB::GFF::RelSegmentBio::DB::GFF::AggregatorBio::DB::GFF::FeatureBio::DB::GFF::Adaptor::dbi::mysqloptBio::DB::GFF::Adaptor::dbi::oracleBio::DB::GFF::Adaptor::memoryBio::DB::GFF::Adaptor::berkeleydb
๐ AUTHOR
Lincoln Stein <lstein@cshl.org>.
Copyright (c) 2001 Cold Spring Harbor Laboratory.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. ๐ช
and that's the whole page, bestie!! This one ships as perl v5.30.0, dated 2020-01-13, and it's the Bio::DB::GFF(3pm) man page โ so go forth, query your features, delete responsibly, and don't touch the internal methods unless you're built different. mwah ๐๐
โจ
๐ฆ where this page comes from
- debian bookworm: libbio-db-gff-perl 1.7.4-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libbio-db-gff-perl 1.7.4-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu jammy: libbio-db-gff-perl 1.7.4-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libbio-db-gff-perl 1.7.4-1 ยท Artistic-1.0-Perl OR GPL-1.0-or-later
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms