2
# BioPerl module for Bio::Tools::EUtilities::Summary::Item
4
# Please direct questions and support issues to <bioperl-l@bioperl.org>
6
# Cared for by Chris Fields
8
# Copyright Chris Fields
10
# You may distribute this module under the same terms as perl itself
12
# POD documentation - main docs before the code
14
# Part of the EUtilities BioPerl package
18
Bio::Tools::EUtilities::Summary::Item - simple layered object for DocSum item data
22
# Items can be nested up to three levels at this time. These levels can be
23
# accessed via Item, ListItem, or StructureItem methods:
25
while (my $item = $docsum->next_Item) {
26
print "Name: ",$item->get_name,"\n";
27
print "Data: ",$item->get_content,"\n";
28
print "Type: ",$item->get_type,"\n";
29
while (my $ls = $item->next_ListItem) {
31
while (my $struct = $ls->next_StructureItem) {
40
DocSum data, as returned from esummary, normally is a simple list of
41
item-content-content_type groups. However, items can also contain nested data to
42
represent more complex data (such as structural data). Up to three nested layers
43
may appear in any document summary.
45
This class contains methods to access data that can appear in a docsum for any
46
individual item as well as describes methods to traverse the hierarchy of items
47
present in a document summary.
49
The unique name for items are accessed via get_name(), the content by
50
get_content() (if present), and the data type by get_type(). Items can have
51
ListItems (Item objects with a datatype() 'list'), which in turn can have
52
StructureItems (Item objects with a datatype of 'structure'). Items are
53
initially traversed via a DocSum object using next_Item() or obtained all at
54
once with get_Items(). Similarly, nested Items can be accessed by using
55
next_ListItem/get_ListItems and next_StructureItem/get_StructureItem. A
56
flattened list of items can be accessed with get_all_Items().
62
User feedback is an integral part of the
63
evolution of this and other Bioperl modules. Send
64
your comments and suggestions preferably to one
65
of the Bioperl mailing lists. Your participation
68
bioperl-l@lists.open-bio.org - General discussion
69
http://www.bioperl.org/wiki/Mailing_lists - About the mailing lists
73
Please direct usage questions or support issues to the mailing list:
75
I<bioperl-l@bioperl.org>
77
rather than to the module maintainer directly. Many experienced and
78
reponsive experts will be able look at the problem and quickly
79
address it. Please include a thorough description of the problem
80
with code and data examples if at all possible.
84
Report bugs to the Bioperl bug tracking system to
85
help us keep track the bugs and their resolution.
86
Bug reports can be submitted via the web.
88
https://redmine.open-bio.org/projects/bioperl/
90
=head1 AUTHOR Chris Fields
92
Email cjfields at bioperl dot org
96
The rest of the documentation details each of the
97
object methods. Internal methods are usually
102
# Let the code begin...
104
package Bio::Tools::EUtilities::Summary::Item;
108
use base qw(Bio::Root::Root Bio::Tools::EUtilities::EUtilDataI);
121
my ($class, @args) = @_;
122
my $self = $class->SUPER::new(@args);
123
my ($type) = $self->_rearrange(['DATATYPE'],@args);
125
$self->datatype($type);
126
$self->eutil('esummary');
127
$self->rewind('recursive');
134
Usage : my ($id) = $item->get_ids;
135
Function : returns array or array ref with id
136
Returns : array or array ref
138
Note : the behavior of this method is to remain consistent with other
139
implementations of get_ids(). To retrieve the single DocSum ID use
146
return ($self->{'_id'});
152
Usage : my ($id) = $item->get_id;
153
Function : returns UID of record
161
return $self->{'_id'};
166
Title : next_ListItem
167
Usage : while (my $ls = $item->next_ListItem) {...}
168
Function : iterates through ListItems (nested layer of Item)
169
Returns : single ListItem
176
unless ($self->{'_lists_it'}) {
177
my @lists = $self->get_ListItems;
178
# reset the structure iterator (required!)
179
delete $self->{'_structures_it'} if $self->{'_structures_it'};
180
$self->{'_lists_it'} = sub {return shift @lists}
182
return $self->{'_lists_it'}->();
187
Title : get_ListItems
188
Usage : my @ls = $item->get_ListItems
189
Function : returns list of, well, List Items
190
Returns : array of List Items
197
my @items = $self->get_type eq 'List' ? $self->get_subItems : ();
201
=head2 next_StructureItem
203
Title : next_StructureItem
204
Usage : while (my $struc = $ls->next_StructureItem) {...}
205
Function : iterates through StructureItems (nested layer of ListItem)
206
Returns : single StructureItems
211
sub next_StructureItem {
213
unless ($self->{'_structures_it'}) {
214
my @structs = $self->get_StructureItems;
215
$self->{'_structures_it'} = sub {return shift @structs}
217
return $self->{'_structures_it'}->();
220
=head2 get_StructureItems
222
Title : get_StructureItems
223
Usage : my @structs = $ls->get_StructureItems
224
Function : returns list of Structure Items
225
Returns : array of StructureItems
230
sub get_StructureItems {
232
my @items = $self->get_type eq 'Structure' ? $self->get_subItems : ();
239
Usage : while (my $it = $ls->next_subItem) {...}
240
Function : iterates through the next layer of Items
241
Returns : single Item
243
Notes : unlike next_ListItem and next_StructureItem, this generically
244
accesses any sub Items (useful for recursive calls, for example)
250
unless ($self->{'_subitem_it'}) {
251
my @structs = $self->get_subItems;
252
$self->{'_subitem_it'} = sub {return shift @structs}
254
return $self->{'_subitem_it'}->();
260
Usage : my @items = $ls->get_subItems
261
Function : returns list of sub Items
262
Returns : array of Items
264
Notes : unlike get_ListItems and get_StructureItems, this generically
265
accesses any sub Items (useful for recursive calls, for example)
271
ref $self->{'_items'} ? return @{ $self->{'_items'} } : return ();
277
Usage : my $nm = $ls->get_name
278
Function : retrieves Item/ListItem/StructureItem name for this Item
286
return $self->{'_itemname'};
292
Usage : my $type = $ls->get_type
293
Function : retrieves Item/ListItem/StructureItem type
296
Note : this is not the same as the datatype(), which describes the
297
group this Item object belongs to
303
return $self->{'_itemtype'};
309
Usage : my $data = $ls->get_content
310
Function : retrieves Item/ListItem/StructureItem content (if any)
318
return $self->{'_itemcontent'};
324
Usage : $item->rewind()
325
Function : rewinds iterators
327
Args : [optional] No arg - only rewinds current layer
328
'all' - rewind all DocSum object layers
329
(Items, ListItems, StructureItems)
334
my ($self, $request) = @_;
335
if ($request && $request eq 'all') {
336
map {$_->rewind()} $self->get_ListItems;
338
delete $self->{"_lists_it"} if $self->{"_lists_it"};
339
delete $self->{"_structures_it"} if $self->{"_structures_it"};
342
=head1 ItemContainerI methods
349
Usage : while (my $item = $docsum->next_Item) {...}
350
Function : iterates through Items (nested layer of Item)
351
Returns : single Item
352
Args : [optional] single arg (string)
353
'flatten' - iterates through a flattened list ala
354
get_all_DocSum_Items()
359
my ($self, $request) = @_;
360
unless ($self->{"_items_it"}) {
361
#my @items = $self->get_Items;
362
my @items = ($request && $request eq 'flatten') ?
363
$self->get_all_Items :
365
$self->{"_items_it"} = sub {return shift @items}
367
$self->{'_items_it'}->();
373
Usage : my @items = $docsum->get_Items
374
Function : returns list of, well, Items
375
Returns : array of Items
382
return ref $self->{'_items'} ? @{ $self->{'_items'} } : return ();
387
Title : get_all_Items
388
Usage : my @items = $docsum->get_all_Items
389
Function : returns flattened list of all Item objects (Items, ListItems,
391
Returns : array of Items
393
Note : items are added top-down (similar order to using nested calls)
394
in original list order.
397
Item - Item - Item - Item ...
403
Structure - Structure
409
unless ($self->{'_ordered_items'}) {
410
for my $item ($self->get_Items) {
411
push @{$self->{'_ordered_items'}}, $item;
412
for my $ls ($item->get_ListItems) {
413
push @{$self->{'_ordered_items'}}, $ls;
414
for my $st ($ls->get_StructureItems) {
415
push @{$self->{'_ordered_items'}}, $st;
420
return @{$self->{'_ordered_items'}};
425
Title : get_all_names
426
Usage : my @names = get_all_names()
427
Function : Returns an array of names for all Item(s) in DocSum.
428
Returns : array of unique strings
436
my @data = grep {!$tmp{$_}++}
437
map {$_->get_name} $self->get_all_Items;
441
=head2 get_Items_by_name
443
Title : get_Items_by_name
444
Usage : my @items = get_Items_by_name('CreateDate')
445
Function : Returns named Item(s) in DocSum (indicated by passed argument)
446
Returns : array of Item objects
447
Args : string (Item name)
451
sub get_Items_by_name {
452
my ($self, $key) = @_;
454
my @data = grep {$_->get_name eq $key}
455
$self->get_all_Items;
459
=head2 get_contents_by_name
461
Title : get_contents_by_name
462
Usage : my ($data) = get_contents_by_name('CreateDate')
463
Function : Returns content for named Item(s) in DocSum (indicated by
465
Returns : array of values (type varies per Item)
466
Args : string (Item name)
470
sub get_contents_by_name {
471
my ($self, $key) = @_;
473
my @data = map {$_->get_content}
474
grep {$_->get_name eq $key}
475
$self->get_all_Items;
479
=head2 get_type_by_name
481
Title : get_type_by_name
482
Usage : my $data = get_type_by_name('CreateDate')
483
Function : Returns data type for named Item in DocSum (indicated by
485
Returns : scalar value (string) if present
486
Args : string (Item name)
490
sub get_type_by_name {
491
my ($self, $key) = @_;
493
my ($it) = grep {$_->get_name eq $key} $self->get_all_Items;
494
return $it->get_type;
497
# private data method
500
my ($self, $data) = @_;
502
my $objtype = lc $data->{Type}.'_item';
503
$self->{'_id'} = $data->{Id} if exists $data->{Id};
504
for my $sd (@{ $data->{Item} } ) {
505
$sd->{Id} = $data->{Id} if exists $data->{Id};
506
my $subdoc = Bio::Tools::EUtilities::Summary::Item->new(
507
-datatype => $objtype,
508
-verbose => $self->verbose);
509
$subdoc->_add_data($sd);
510
push @{ $self->{'_items'} }, $subdoc;
513
for my $nm (qw(Type content Name)) {
514
$self->{'_item'.lc $nm} = $data->{$nm} if defined $data->{$nm};
516
$self->{'_id'} = $data->{Id} if exists $data->{Id};
522
Usage : $foo->to_string()
523
Function : converts current object to string
525
Args : (optional) simple data for text formatting. This implementation
526
passes an argument for layering Items/subItems
527
Note : Used generically for debugging and print_DocSums methods
531
# recursively called to grab subitems, then layer
535
my $level = shift || 0;
536
# this is the field length for the initial data (spaces are padded in front)
537
my $pad = 20 - $level;
538
my $content = $self->get_content || '';
539
my $string .= sprintf("%-*s%-*s%s\n",
541
$pad, $self->get_name(),
542
$self->_text_wrap(':',
545
for my $sub ($self->get_subItems) {
546
$string .= $sub->to_string(4 + $level);