File Coverage

lib/Bio/Resistome/EMBL/AccessionLookup.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Bio::Resistome::EMBL::AccessionLookup;
2             # ABSTRACT: Take in an accession number, lookup EMBL and populate a datastructure
3              
4              
5 1     1   241404 use Moose;
  0            
  0            
6             use LWP::UserAgent;
7             use XML::TreePP;
8             use URI::Escape;
9             use Bio::Resistome::EMBL::Exceptions;
10             use Bio::Resistome::GeneMetaData;
11              
12             has 'accession_number' => ( is => 'ro', isa => 'Str', required => 1 );
13             has 'accession_number_lookup_service' => ( is => 'ro', isa => 'Str', default => 'http://www.ebi.ac.uk/ena/data/view/' );
14              
15             has 'accession_metadata' => (is => 'rw', isa => 'Bio::Resistome::GeneMetaData', lazy => 1, builder => '_build_accession_metadata');
16             has '_full_lookup_url' => (is => 'rw', isa => 'Str', lazy => 1, builder => '_build__full_lookup_url');
17              
18             has '_species' => (is => 'rw', isa => 'Maybe[Str]');
19             has '_taxon_id' => (is => 'rw', isa => 'Maybe[Int]');
20             has '_lineage' => (is => 'rw', isa => 'ArrayRef', default => sub { [] } );
21             has '_pubmed_ids' => (is => 'rw', isa => 'ArrayRef', default => sub { [] } );
22             has '_description' => (is => 'rw', isa => 'Maybe[Str]');
23              
24             sub _build__full_lookup_url
25             {
26             my ($self) = @_;
27             $self->accession_number_lookup_service.$self->accession_number.'&display=xml';
28             }
29              
30             sub _build_accession_metadata
31             {
32             my ($self) = @_;
33             my $full_query = $self->_full_lookup_url;
34            
35             my $accession_metadata_obj = $self->_local_lookup_accession_metadata($full_query);
36             unless(defined($accession_metadata_obj))
37             {
38             $accession_metadata_obj = $self->_remote_lookup_accession_metadata($full_query);
39             }
40             return $accession_metadata_obj;
41             }
42              
43             sub _populate_description_metadata
44             {
45             my ($self, $tree) = @_;
46             return $self if(!(defined($tree->{description})));
47            
48             if(ref($tree->{description}) && $tree->{description} =~ /ARRAY/)
49             {
50             Bio::Resistome::EMBL::Exceptions::MoreThanOneDescription->throw(error => "Theres more than 1 description which shouldnt happen for ".$self->accession_number);
51             }
52             else
53             {
54             $self->_description($tree->{description});
55             }
56             return $self;
57             }
58              
59             sub _get_pubmed_id
60             {
61             my ($self, $xref) = @_;
62              
63             if(defined($xref) && defined($xref->{'-db'}) && $xref->{'-db'} eq 'PUBMED' && defined($xref->{'-id'}) )
64             {
65             return $xref->{'-id'};
66             }
67             return undef;
68             }
69              
70             sub _populate_reference_metadata
71             {
72             my ($self, $tree) = @_;
73             my @pubmed_ids;
74            
75             if(ref($tree->{reference}) && $tree->{reference} =~ /ARRAY/)
76             {
77             for my $reference (@{$tree->{reference}})
78             {
79             next if(! defined($reference->{xref}));
80             if( $reference->{xref} =~ /ARRAY/)
81             {
82             for my $xref (@{$reference->{xref}})
83             {
84             my $pubmed_id = $self->_get_pubmed_id($xref);
85             push(@pubmed_ids,$pubmed_id) if(defined($pubmed_id));
86             }
87             }
88             else
89             {
90             my $pubmed_id = $self->_get_pubmed_id($reference->{xref} );
91             push(@pubmed_ids,$pubmed_id) if(defined($pubmed_id));
92             }
93             }
94             }
95             else
96             {
97             my $pubmed_id = $self->_get_pubmed_id($tree->{reference});
98             push(@pubmed_ids,$pubmed_id) if(defined($pubmed_id));
99             }
100            
101             # Theres a lot more meta data in the referenes section that we dont look at yet, but we might, so this isnt a builder in its own right.
102             $self->_pubmed_ids(\@pubmed_ids);
103              
104             return $self;
105             }
106              
107             sub _populate_species_metadata
108             {
109             my ($self, $tree) = @_;
110            
111             # Can be an array of features or a single feature
112             if(ref($tree->{feature}) && $tree->{feature} =~ /ARRAY/)
113             {
114             for my $feature (@{$tree->{feature}})
115             {
116             if(defined($feature->{taxon}))
117             {
118             $self->_populate_feature_species_details($feature);
119             return $self;
120             }
121             }
122             }
123             else
124             {
125             $self->_populate_feature_species_details($tree->{feature});
126             }
127             return $self;
128             }
129              
130             sub _populate_feature_species_details
131             {
132             my ($self, $feature) = @_;
133            
134             if(defined($feature->{taxon}))
135             {
136              
137             $self->_species($feature->{taxon}->{'-scientificName'}) if(defined($feature->{taxon}->{'-scientificName'}));
138             $self->_taxon_id($feature->{taxon}->{'-taxId'}) if(defined($feature->{taxon}->{'-taxId'}));
139            
140             if(defined($feature->{taxon}->{lineage}) && defined($feature->{taxon}->{lineage}->{taxon}))
141             {
142             my @lineages;
143             if(ref($feature->{taxon}->{lineage}->{taxon}) && $feature->{taxon}->{lineage}->{taxon} =~ /ARRAY/)
144             {
145             for my $lineage (@{$feature->{taxon}->{lineage}->{taxon}})
146             {
147             push(@lineages, $lineage->{'-scientificName'}) if(defined($lineage->{'-scientificName'}));
148             }
149             $self->_lineage(\@lineages);
150             }
151             }
152             }
153             return $self;
154             }
155              
156             sub _parse_xml_and_return_gene_metadata
157             {
158             my ($self, $tree) = @_;
159              
160             if(defined($tree) && defined($tree->{ROOT}) && defined($tree->{ROOT}->{entry}) )
161             {
162             $self->_populate_species_metadata($tree->{ROOT}->{entry});
163             $self->_populate_reference_metadata($tree->{ROOT}->{entry});
164             $self->_populate_description_metadata($tree->{ROOT}->{entry});
165             }
166              
167             my $accession_metadata_obj = Bio::Resistome::GeneMetaData->new(
168             accession_number => $self->accession_number,
169             species => $self->_species,
170             taxon_id => $self->_taxon_id,
171             lineage => $self->_lineage,
172             pubmed_ids => $self->_pubmed_ids,
173             description => $self->_description,
174             );
175            
176             return $accession_metadata_obj;
177             }
178              
179              
180             sub _local_lookup_accession_metadata
181             {
182             my ($self, $file) = @_;
183             return undef unless (-e $file);
184            
185             my $tpp = XML::TreePP->new();
186             my $tree = $tpp->parsefile( $file );
187             return $self->_parse_xml_and_return_gene_metadata($tree);
188             }
189              
190             sub _remote_lookup_accession_metadata
191             {
192             my ($self, $url) = @_;
193            
194             eval {
195             my $tpp = $self->_setup_xml_parser_via_proxy;
196             my $tree = $tpp->parsehttp( GET => $url );
197             return $self->_parse_xml_and_return_gene_metadata($tree);
198             } or do
199             {
200             Bio::Resistome::EMBL::Exceptions::AccessionLookupFailed->throw( error => "Cant lookup accession number ".$self->accession_number );
201             };
202             }
203              
204             sub _setup_xml_parser_via_proxy
205             {
206             my ($self) = @_;
207             my $tpp = XML::TreePP->new();
208             my $ua = LWP::UserAgent->new();
209             $ua->timeout( 60 );
210             $ua->env_proxy;
211             $tpp->set( lwp_useragent => $ua );
212             $tpp;
213             }
214              
215             __PACKAGE__->meta->make_immutable;
216              
217             no Moose;
218              
219             1;
220              
221             __END__
222              
223             =pod
224              
225             =head1 NAME
226              
227             Bio::Resistome::EMBL::AccessionLookup - Take in an accession number, lookup EMBL and populate a datastructure
228              
229             =head1 VERSION
230              
231             version 1.123560
232              
233             =head1 SYNOPSIS
234              
235             Take in an accession number, lookup EMBL and populate a datastructure
236              
237             use Bio::Resistome::EMBL::AccessionLookup;
238             my $obj = Bio::Resistome::EMBL::AccessionLookup->new(
239             accession_number => 'ABC'
240             );
241             $obj->accession_metadata;
242              
243             =head1 METHODS
244              
245             =head2 accession_metadata
246              
247             Returns a populated Bio::Resistome::GeneMetaData object.
248              
249             =head1 SEE ALSO
250              
251             =over 4
252              
253             =item *
254              
255             L<Bio::Resistome::GeneMetaData>
256              
257             =back
258              
259             =head1 AUTHOR
260              
261             Andrew J. Page <ap13@sanger.ac.uk>
262              
263             =head1 COPYRIGHT AND LICENSE
264              
265             This software is Copyright (c) 2012 by Wellcome Trust Sanger Institute.
266              
267             This is free software, licensed under:
268              
269             The GNU General Public License, Version 3, June 2007
270              
271             =cut