Bio::DB::GFF(3pm)

๐Ÿ“ฆ
version 1.7.4 ยท 2 versions
, in debian bookworm, debian trixie, ubuntu jammy, ubuntu noble

๐Ÿ’– 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 --fasta argument 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 --upgrade option, 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 --fasta argument 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 as bp_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 as bp_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:

  1. 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".
  2. 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".
  3. method โ€” the annotation method. this describes the type of the annotation, like "CDS". together, method and source describe the annotation type.
  4. start position โ€” where the annotation starts, relative to the reference sequence.
  5. 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. โœ‹
  6. 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 ".".
  7. 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.
  8. phase โ€” for annotations linked to proteins, this describes the phase of the annotation on the codons. it's a number from 0 to 2, or "." for features with no phase.
  9. 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:

  1. A similarity hit โ€” the annotation indicates an alignment.
  2. 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 type exon, CDS, 5'UTR, 3'UTR, TSS, and PolyA
  • clone โ€” assembles clones from Clone_left_end, Clone_right_end and Sequence features.
  • 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 -start and -stop
  • -off, -len โ€” Aliases for -offset and -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 called fetch_group(), fetch_feature(), fetch_feature_by_name() and segments(). 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 called delete_fattribute_to_feature(). Also see delete_groups() and delete_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 called delete_feature(). Also see delete_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 called delete_group(). Also see delete_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 SQL DELETE operation. Some dbd drivers return the count of rows deleted, while others return 0E0. 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:

  1. a Bio::DB::GFF::Aggregator object โ€” it will be added
  2. a string in the form "aggregator_name{subpart1,subpart2,subpart3/main_method}" โ€” it gets turned into a Bio::DB::GFF::Aggregator object (the /main_method part is optional)
  3. a valid Perl token โ€” it gets turned into a Bio::DB::GFF::Aggregator subclass, 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, in refseq coordinates
  • -stop โ€” where that range stops, also in refseq coordinates
  • -types โ€” a list of the feature types you want back. The argument is an array reference holding strings formatted like "method:source"
  • -parent โ€” a parent Bio::DB::GFF::Segment object, 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::Feature objects
  • 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::SeqIO object
  • 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 โ€” $current value 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 of Bio::DB::GFF::RelSegment objects 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::RelSegment
  • Bio::DB::GFF::Aggregator
  • Bio::DB::GFF::Feature
  • Bio::DB::GFF::Adaptor::dbi::mysqlopt
  • Bio::DB::GFF::Adaptor::dbi::oracle
  • Bio::DB::GFF::Adaptor::memory
  • Bio::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