File Coverage

blib/lib/Bio/GMOD/GenericGenePage.pm
Criterion Covered Total %
statement 14 90 15.5
branch n/a
condition 0 2 0.0
subroutine 5 24 20.8
pod 14 14 100.0
total 33 130 25.3


line stmt bran cond sub pod time code
1             package Bio::GMOD::GenericGenePage;
2 1     1   27874 use strict;
  1         3  
  1         44  
3 1     1   5 use warnings;
  1         2  
  1         32  
4 1     1   1273 use English;
  1         4526  
  1         5  
5 1     1   553 use Carp;
  1         1  
  1         1282  
6              
7             our $VERSION = 0.12;
8              
9              
10             =head1 NAME
11              
12             Bio::GMOD::GenericGenePage - Generic GMOD gene page base class
13              
14             =head1 SYNOPSIS
15              
16             my $page = Bio::GMOD::GenericGenePage->new( $gene_identifier );
17             my $xml = $page->render_xml();
18              
19             =head1 DESCRIPTION
20              
21             Bio::GMOD::GenericGenePage is an abstract class to make it easier for
22             Model Organism Databases (MODs) to serve up a simple XML that describes
23             attributes of their gene models. In order to implement this, the user
24             needs to subclass Bio::GMOD::GenericGenePage and provide the methods
25             listed below as abstract classes. These methods are then used by
26             the render_xml method to create XML for a given gene.
27              
28             There is one example implementation included with this distribution,
29             Bio::GMOD::GenericGenePage::Chado, which is a Chado adapter for a
30             yeast database derived from SGD's GFF3. In order to implement this for
31             another Chado database it should be fairly easy to modify the provided
32             methods to create your own adaptor. For example, ParameciumDB could
33             subclass Bio::GMOD::GenericGenePage::Chado and create
34             Bio::GMOD::GenericGenePage::Chado::ParameciumDB and only override
35             the data_provider and organism methods to have a working adaptor.
36             Databases not based on Chado will only have slightly more work, in order
37             to implement all of the abstract classes in Bio::GMOD::GenericGenePage.
38              
39             Another example implementation is included, CXGN::Phenome::GenericGenePage,
40             however this is only a partial implementation and will not work with
41             the current release of Bio::GMOD::GenericGenePage.
42              
43             =head1 BASE CLASS(ES)
44              
45             none
46              
47             =head1 SUBCLASSES
48              
49             Bio::GMOD::GenericGenePage::Chado
50             CXGN::Phenome::GenericGenePage
51              
52             =head1 BUGS AND SUPPORT
53              
54             Please report bugs and make support requests on the GMOD developers list,
55             gmod-devel@lists.sourceforge.net.
56              
57             =head1 AUTHOR
58              
59             Scott Cain
60             CPAN ID: SCAIN
61             Cold Spring Harbor Laboratory
62             scain@cpan.org
63             http://www.gmod.org/
64              
65             and Robert Buels.
66              
67             =head1 COPYRIGHT
68              
69             Copyright (c) 2008 Scott Cain and Robert Buels. All rights reserved.
70             This program is free software; you can redistribute
71             it and/or modify it under the same terms as Perl itself.
72              
73             The full text of the license can be found in the
74             LICENSE file included with this module.
75              
76              
77             =head1 SEE ALSO
78              
79             perl(1).
80              
81             =head1 PROVIDED METHODS
82              
83             =cut
84              
85             =head2 new
86              
87             Usage: my $genepage = MyGenePage->new( -id => $gene_identifier );
88             Desc : create a new gene page object. should be overridden
89             Args : not specified
90             Ret : a new gene page object
91             Side Effects: none as implemented here, but subclass
92             implementations may have side effects
93             Example:
94              
95             =cut
96              
97             sub new {
98 1     1 1 13 my ($class,%args) = @_;
99 1         4 return bless {}, $class;
100             }
101              
102             sub _counter {
103 0     0     my $self = shift;
104 0           $self->{'counter'}++;
105 0           return $self->{'counter'};
106             }
107              
108             =head2 render_xml
109              
110             Usage: my $xml = $page->render_xml();
111             Desc : render the XML for this generic gene page
112             Args : none
113             Ret : string of xml
114             Side Effects: none
115              
116             =cut
117              
118             sub render_xml {
119 0     0 1   my ($self) = @_;
120              
121 0           my $data_provider = " ".$self->data_provider."\n";
122              
123 0           my @accs = $self->accessions;
124 0           my $accession = join "\n", map {
125 0           qq| $_|
126             } @accs;
127              
128              
129 0           my $name = $self->name;
130              
131 0           my @syn = $self->synonyms;
132             #shift @syn; #should the real name be in there too?
133             #I don't think so--querying the synonym table is easy, why bother with
134             #a join when we don't need it
135              
136             #also, synonym should probably be a hash to optionally allow for a
137             #synonym type
138              
139 0           my $synonyms = join "\n", map {
140 0           qq| $_|
141             } @syn;
142              
143 0           my $dbreferences = $self->_xml_render_colon_separated_dbrefs( 2, $self->dbxrefs);
144 0           my $organism = $self->_xml_render_organism();
145 0           my $ontology_terms = $self->_xml_render_ontology_terms( 4, $self->ontology_terms);
146 0           my $literature = $self->_xml_render_colon_separated_dbrefs( 4, $self->literature_references);
147              
148 0           my $maplocations = join "\n", map {
149 0           qq| |
150             } $self->map_locations;
151              
152 0           my $comments = $self->_xml_render_comments($self->comments);
153              
154 0           return <
155            
156             $data_provider
157             $accession
158              
159             $name
160              
161             $synonyms
162              
163             $dbreferences
164              
165             $organism
166              
167            
168             $maplocations
169            
170              
171            
172             $ontology_terms
173            
174              
175            
176             $literature
177            
178              
179             $comments
180              
181            
182             EOXML
183             }
184              
185             sub _xml_render_organism {
186 0     0     my $self = shift;
187 0           my $counter = $self->_counter;
188 0           my $org = $self->organism;
189 0           my $organism = <
190            
191             $org->{common}
192             $org->{binomial}
193            
194            
195             END
196 0           return $organism;
197             }
198              
199             sub _xml_render_colon_separated_dbrefs {
200 0     0     my ($self,$spaces,@refs) = @_;
201 0           my $refstring = '';
202 0           for my $ref (@refs) {
203 0           my $counter = $self->_counter;
204 0           my ($type,$id) = split /:/,$ref,2;
205 0           $refstring .= (' 'x$spaces).qq|\n|
206             }
207 0           return $refstring;
208             }
209              
210             sub _xml_render_ontology_terms {
211 0     0     my ($self,$spaces,%term) = @_;
212            
213 0           my $xml_string = '';
214 0           for my $key (keys %term) {
215 0           my ($type,$id) = split /:/,$key;
216 0           my $value = $term{$key};
217 0           my $counter = $self->_counter;
218              
219             # the low casing of the 'o' seems inconsistent, so go with the upper
220             #$type = "Go" if ($type eq "GO");
221 0           $xml_string .= (' 'x$spaces).qq|\n|;
222 0           $xml_string .= (' 'x($spaces+2)).qq|\n|;
223 0           $xml_string .= (' 'x$spaces).qq|\n|;
224             }
225 0           return $xml_string;
226             }
227              
228             sub _xml_render_comments {
229 0     0     my ($self, %comments) = @_;
230              
231 0           my $xml_string = '';
232              
233 0           for my $key (keys %comments) {
234 0   0       my $value = $comments{$key} || "miscellaneous";
235 0           $xml_string .= " \n";
236 0           $xml_string .= " $key\n";
237 0           $xml_string .= " \n\n";
238             }
239              
240 0           return $xml_string;
241             }
242              
243             =head2 render_html NOT IMPLEMENTED!
244              
245             Usage: my $html = $page->render_html();
246             Desc : render HTML for this generic gene page. you may want to
247             override this method for your implementation
248             Args : none
249             Ret : string of html
250             Side Effects: none
251              
252             =cut
253              
254             sub render_html {
255 0     0 1   my ($self) = @_;
256              
257 0           return <
258              
259             EOHTML
260             }
261              
262             #helper method that calls all those functions
263             sub _info {
264 0     0     my ($self) = @_;
265              
266             return
267 0           { name => $self->name,
268             syn => [$self->synonyms],
269             loc => [$self->map_locations],
270             ont => [$self->ontology_terms],
271             dbx => [$self->dbxrefs],
272             lit => [$self->lit_refs],
273             comments => [$self->comment_text],
274             species => $self->species,
275             };
276             }
277              
278              
279             =head1 ABSTRACT METHODS
280              
281             Methods below should be overridden by each GenericGenePage implementation.
282              
283             =head2 name
284              
285             Usage: my $name = $genepage->name();
286             Desc : get the string name of this gene
287             Args : none
288             Ret : string gene name, e.g. 'Pax6'
289             Side Effects: none
290              
291             =cut
292              
293             sub name {
294 0     0 1   my ($self) = @_;
295 0           die 'name() method is abstract, must be implemented in a subclass;'
296             }
297              
298             =head2 accessions
299              
300             Usage: my @accessions = $genepage->accessions();
301             Desc : get a list of local accession values
302             Args : none
303             Ret : a list of local accessions
304             Side Effects: none
305              
306             Note that these are the accessions that are used by the MOD providing the
307             information, not accessions in external databases like GenBank.
308              
309             =cut
310              
311             sub accessions {
312 0     0 1   my ($self) = @_;
313 0           die 'accession() method is abstract, must be implemented in a subclass;'
314             }
315              
316             =head2 data_provider
317              
318             Usage: my $data_provider = $genepage->data_provider();
319             Desc : The name of the data providing authority (ie, WormBase, SGD, etc)
320             Args : none
321             Ret : string, name of the data provider
322             Side Effects: none
323              
324             =cut
325              
326             sub data_provider {
327 0     0 1   my ($self) = @_;
328 0           die 'data_provider() method is abstract, must be implemented in a subclass;'
329             }
330              
331              
332             =head2 synonyms
333              
334             Usage: my @syn = $genepage->synonyms();
335             Desc : get a list of synonyms for this gene
336             Args : none
337              
338             Ret : list of strings,
339             e.g. ( '1500038E17Rik',
340             'AEY11',
341             'Dey',
342             "Dickie's small eye",
343             'Gsfaey11',
344             'Pax-6',
345             )
346             Side Effects: none
347              
348             =cut
349              
350             sub synonyms {
351 0     0 1   my ($self) = @_;
352 0           die 'synonyms() method is abstract, must be implemented in a subclass;'
353             }
354              
355             =head2 map_locations
356              
357             Usage: my @locs = $genepage->map_locations()
358             Desc : get a list of known map locations for this gene
359             Args : none
360             Ret : list of map locations, each a hashref as:
361             { map_name => string map name,
362             chromosome => string chromosome name,
363             marker => (optional) associated marker name,
364             position => numerical position on the map,
365             units => map units, either 'cm', for centimorgans,
366             or 'b', for bases
367             }
368             Side Effects: none
369              
370             =cut
371              
372             sub map_locations {
373 0     0 1   my ($self) = @_;
374 0           die 'map_locations() method is abstract, must be implemented in a subclass;'
375             }
376              
377              
378             =head2 ontology_terms
379              
380             Usage: my @terms = $genepage->ontology_terms();
381             Desc : get a list of ontology terms
382             Args : none
383             Ret : hash-style list as:
384             termname => human-readable description,
385             Side Effects: none
386             Example:
387              
388             my %terms = $genepage->ontology_terms()
389              
390             # and %terms is now
391             ( GO:0016711 => 'F:flavonoid 3'-monooxygenase activity',
392             ...
393             )
394              
395             Note that the value in that has is the the concatenation of F:, B: or C:
396             for molecular_function, biological_process, or cellular_component GO terms
397             respectively. If the term does not belong to GO, there is no prepended
398             identifier.
399              
400             =cut
401              
402             sub ontology_terms {
403 0     0 1   my ($self) = @_;
404 0           die 'go_terms() method is abstract, must be implemented in a subclass'
405             }
406              
407             =head2 dbxrefs
408              
409             Usage: my @dbxrefs = $genepage->dbxrefs();
410             Desc : get a list of database cross-references for info related to this gene
411             Args : none
412             Ret : list of strings, like type:id e.g. ('PFAM:00012')
413             Side Effects: none
414              
415             =cut
416              
417             sub dbxrefs {
418 0     0 1   my ($self) = @_;
419 0           die 'dbxrefs() method is abstract, must be implemented in a subclass'
420             }
421              
422             =head2 comments
423              
424             Usage: my @comments = $genepage->comments();
425             Desc : get a list of comments with types
426             Args : none
427             Ret : a hash of comment=>type, where type is optional (empty string)
428             Side Effects: none
429              
430             =cut
431              
432             sub comments {
433 0     0 1   my ($self) = @_;
434 0           die 'comments() method is abstract, must be impemented in a subclass';
435             }
436              
437              
438             =head2 literature_references
439              
440             Usage: my @refs = $genepage->lit_refs();
441             Desc : get a list of literature references for this gene
442             Args : none
443             Ret : list of literature reference identifers, as type:id,
444             like ('PMID:0023423',...)
445             Side Effects: none
446              
447             =cut
448              
449             sub literature_references {
450 0     0 1   my ($self) = @_;
451 0           die 'lit_refs() method is abstract, must be implemented in a subclass'
452             }
453              
454              
455             =head2 summary_text
456              
457             Usage: my $summary = $page->summary_text();
458             Desc : get a text string of plain-English summary text for this gene
459             Args : none
460             Ret : string of summary text
461             Side Effects: none
462              
463             =cut
464              
465             sub summary_text {
466 0     0 1   my ($self) = @_;
467 0           die 'summary_text() method is abstract, must be implemented in a subclass'
468             }
469              
470             =head2 organism
471              
472             Usage: my $species_info = $genepage->organism
473             Desc : get a handful of species-related information
474             Args : none
475             Ret : hashref as:
476             { ncbi_taxon_id => ncbi taxon id, (e.g. 3702),
477             binomial => e.g. 'Arabidopsis thaliana',
478             common => e.g. 'Mouse-ear cress',
479             }
480             Side Effects: none
481              
482             =cut
483              
484             sub organism {
485 0     0 1   my ($self) = @_;
486 0           die 'organism() method is abstract, must be implemented in a subclass';
487             }
488              
489              
490             1;
491             # The preceding line will help the module return a true value
492