~ubuntu-branches/ubuntu/trusty/bioperl/trusty

« back to all changes in this revision

Viewing changes to Bio/Tools/EUtilities/Summary/Item.pm

  • Committer: Package Import Robot
  • Author(s): Charles Plessy
  • Date: 2013-09-22 13:39:48 UTC
  • mfrom: (3.1.11 sid)
  • Revision ID: package-import@ubuntu.com-20130922133948-c6z62zegjyp7ztou
Tags: 1.6.922-1
* New upstream release.
* Replaces and Breaks grinder (<< 0.5.3-3~) because of overlaping contents.
  Closes: #722910
* Stop Replacing and Breaking bioperl ( << 1.6.9 ): not needed anymore. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#
2
 
# BioPerl module for Bio::Tools::EUtilities::Summary::Item
3
 
#
4
 
# Please direct questions and support issues to <bioperl-l@bioperl.org> 
5
 
#
6
 
# Cared for by Chris Fields
7
 
#
8
 
# Copyright Chris Fields
9
 
#
10
 
# You may distribute this module under the same terms as perl itself
11
 
#
12
 
# POD documentation - main docs before the code
13
 
#
14
 
# Part of the EUtilities BioPerl package
15
 
 
16
 
=head1 NAME
17
 
 
18
 
Bio::Tools::EUtilities::Summary::Item - simple layered object for DocSum item data
19
 
 
20
 
=head1 SYNOPSIS
21
 
 
22
 
  # Items can be nested up to three levels at this time. These levels can be
23
 
  # accessed via Item, ListItem, or StructureItem methods:
24
 
 
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) {
30
 
        # do same here
31
 
        while (my $struct = $ls->next_StructureItem) {
32
 
           # do more stuff here
33
 
        }
34
 
     }
35
 
  }
36
 
 
37
 
 
38
 
=head1 DESCRIPTION
39
 
 
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.
44
 
 
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.
48
 
 
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().
57
 
 
58
 
=head1 FEEDBACK
59
 
 
60
 
=head2 Mailing Lists
61
 
 
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
66
 
is much appreciated.
67
 
 
68
 
  bioperl-l@lists.open-bio.org               - General discussion
69
 
  http://www.bioperl.org/wiki/Mailing_lists  - About the mailing lists
70
 
 
71
 
=head2 Support 
72
 
 
73
 
Please direct usage questions or support issues to the mailing list:
74
 
 
75
 
I<bioperl-l@bioperl.org>
76
 
 
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.
81
 
 
82
 
=head2 Reporting Bugs
83
 
 
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.
87
 
 
88
 
  https://redmine.open-bio.org/projects/bioperl/
89
 
 
90
 
=head1 AUTHOR Chris Fields
91
 
 
92
 
Email cjfields at bioperl dot org
93
 
 
94
 
=head1 APPENDIX
95
 
 
96
 
The rest of the documentation details each of the
97
 
object methods. Internal methods are usually
98
 
preceded with a _
99
 
 
100
 
=cut
101
 
 
102
 
# Let the code begin...
103
 
 
104
 
package Bio::Tools::EUtilities::Summary::Item;
105
 
use strict;
106
 
use warnings;
107
 
 
108
 
use base qw(Bio::Root::Root Bio::Tools::EUtilities::EUtilDataI);
109
 
 
110
 
=head2 new
111
 
 
112
 
 Title    : new
113
 
 Usage    : 
114
 
 Function : 
115
 
 Returns  : 
116
 
 Args     : 
117
 
 
118
 
=cut
119
 
 
120
 
sub new {
121
 
    my ($class, @args) = @_;
122
 
    my $self = $class->SUPER::new(@args);
123
 
    my ($type) = $self->_rearrange(['DATATYPE'],@args);
124
 
    $type ||= 'item';
125
 
    $self->datatype($type);
126
 
    $self->eutil('esummary');
127
 
    $self->rewind('recursive');
128
 
    return $self;
129
 
}
130
 
 
131
 
=head2 get_ids
132
 
 
133
 
 Title    : get_ids
134
 
 Usage    : my ($id) = $item->get_ids;
135
 
 Function : returns array or array ref with id
136
 
 Returns  : array or array ref
137
 
 Args     : none
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
140
 
            get_id()
141
 
 
142
 
=cut
143
 
 
144
 
sub get_ids {
145
 
    my $self = shift;
146
 
    return ($self->{'_id'});
147
 
}
148
 
 
149
 
=head2 get_id
150
 
 
151
 
 Title    : get_id
152
 
 Usage    : my ($id) = $item->get_id;
153
 
 Function : returns UID of record
154
 
 Returns  : integer
155
 
 Args     : none
156
 
 
157
 
=cut
158
 
 
159
 
sub get_id {
160
 
    my $self = shift;
161
 
    return $self->{'_id'};
162
 
}
163
 
 
164
 
=head2 next_ListItem
165
 
 
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
170
 
 Args     : none
171
 
 
172
 
=cut
173
 
 
174
 
sub next_ListItem {
175
 
    my $self = shift;
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}
181
 
    }        
182
 
    return $self->{'_lists_it'}->();
183
 
}
184
 
 
185
 
=head2 get_ListItems
186
 
 
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
191
 
 Args     : none
192
 
 
193
 
=cut
194
 
 
195
 
sub get_ListItems {
196
 
    my $self = shift;
197
 
    my @items = $self->get_type eq 'List' ? $self->get_subItems : ();
198
 
    return @items;
199
 
}
200
 
 
201
 
=head2 next_StructureItem
202
 
 
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
207
 
 Args     : none
208
 
 
209
 
=cut
210
 
 
211
 
sub next_StructureItem {
212
 
    my $self = shift;
213
 
    unless ($self->{'_structures_it'}) {
214
 
        my @structs = $self->get_StructureItems;
215
 
        $self->{'_structures_it'} = sub {return shift @structs}
216
 
    }
217
 
    return $self->{'_structures_it'}->();
218
 
}
219
 
 
220
 
=head2 get_StructureItems
221
 
 
222
 
 Title    : get_StructureItems
223
 
 Usage    : my @structs = $ls->get_StructureItems
224
 
 Function : returns list of Structure Items
225
 
 Returns  : array of StructureItems
226
 
 Args     : none
227
 
 
228
 
=cut
229
 
 
230
 
sub get_StructureItems {
231
 
    my $self = shift;
232
 
    my @items = $self->get_type eq 'Structure' ? $self->get_subItems : ();
233
 
    return @items;
234
 
}
235
 
 
236
 
=head2 next_subItem
237
 
 
238
 
 Title    : next_subItem
239
 
 Usage    : while (my $it = $ls->next_subItem) {...}
240
 
 Function : iterates through the next layer of Items
241
 
 Returns  : single Item
242
 
 Args     : none
243
 
 Notes    : unlike next_ListItem and next_StructureItem, this generically
244
 
            accesses any sub Items (useful for recursive calls, for example)
245
 
 
246
 
=cut
247
 
 
248
 
sub next_subItem {
249
 
    my $self = shift;
250
 
    unless ($self->{'_subitem_it'}) {
251
 
        my @structs = $self->get_subItems;
252
 
        $self->{'_subitem_it'} = sub {return shift @structs}
253
 
    }
254
 
    return $self->{'_subitem_it'}->();
255
 
}
256
 
 
257
 
=head2 get_subItems
258
 
 
259
 
 Title    : get_subItems
260
 
 Usage    : my @items = $ls->get_subItems
261
 
 Function : returns list of sub Items
262
 
 Returns  : array of Items
263
 
 Args     : none
264
 
 Notes    : unlike get_ListItems and get_StructureItems, this generically
265
 
            accesses any sub Items (useful for recursive calls, for example)
266
 
 
267
 
=cut
268
 
 
269
 
sub get_subItems {
270
 
    my $self = shift;
271
 
    ref $self->{'_items'}  ? return @{ $self->{'_items'} } : return ();
272
 
}
273
 
 
274
 
=head2 get_name
275
 
 
276
 
 Title    : get_name
277
 
 Usage    : my $nm = $ls->get_name
278
 
 Function : retrieves Item/ListItem/StructureItem name for this Item
279
 
 Returns  : string
280
 
 Args     : none
281
 
 
282
 
=cut
283
 
 
284
 
sub get_name {
285
 
    my $self = shift;
286
 
    return $self->{'_itemname'};
287
 
}
288
 
 
289
 
=head2 get_type
290
 
 
291
 
 Title    : get_type
292
 
 Usage    : my $type = $ls->get_type
293
 
 Function : retrieves Item/ListItem/StructureItem type 
294
 
 Returns  : string
295
 
 Args     : none
296
 
 Note     : this is not the same as the datatype(), which describes the
297
 
            group this Item object belongs to
298
 
 
299
 
=cut
300
 
 
301
 
sub get_type {
302
 
    my $self = shift;
303
 
    return $self->{'_itemtype'};
304
 
}
305
 
 
306
 
=head2 get_content
307
 
 
308
 
 Title    : get_content
309
 
 Usage    : my $data = $ls->get_content
310
 
 Function : retrieves Item/ListItem/StructureItem content (if any)
311
 
 Returns  : string
312
 
 Args     : none
313
 
 
314
 
=cut
315
 
 
316
 
sub get_content {
317
 
    my $self = shift;
318
 
    return $self->{'_itemcontent'};    
319
 
}
320
 
 
321
 
=head2 rewind
322
 
 
323
 
 Title    : rewind
324
 
 Usage    : $item->rewind()
325
 
 Function : rewinds iterators
326
 
 Returns  : none
327
 
 Args     : [optional] No arg - only rewinds current layer
328
 
           'all' - rewind all DocSum object layers
329
 
                (Items, ListItems, StructureItems)
330
 
 
331
 
=cut
332
 
 
333
 
sub rewind {
334
 
    my ($self, $request) = @_;
335
 
    if ($request && $request eq 'all') {
336
 
        map {$_->rewind()} $self->get_ListItems;
337
 
    }
338
 
    delete $self->{"_lists_it"} if $self->{"_lists_it"};
339
 
    delete $self->{"_structures_it"} if $self->{"_structures_it"};
340
 
}
341
 
 
342
 
=head1 ItemContainerI methods
343
 
 
344
 
=cut
345
 
 
346
 
=head2 next_Item
347
 
 
348
 
 Title    : next_Item
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()
355
 
 
356
 
=cut
357
 
 
358
 
sub next_Item {
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 :
364
 
                    $self->get_Items ;
365
 
        $self->{"_items_it"} = sub {return shift @items}
366
 
    }
367
 
    $self->{'_items_it'}->();
368
 
}
369
 
 
370
 
=head2 get_Items
371
 
 
372
 
 Title    : get_Items
373
 
 Usage    : my @items = $docsum->get_Items
374
 
 Function : returns list of, well, Items
375
 
 Returns  : array of Items
376
 
 Args     : none
377
 
 
378
 
=cut
379
 
 
380
 
sub get_Items {
381
 
    my $self = shift;
382
 
    return ref $self->{'_items'} ? @{ $self->{'_items'} } : return ();
383
 
}
384
 
 
385
 
=head2 get_all_Items
386
 
 
387
 
 Title    : get_all_Items
388
 
 Usage    : my @items = $docsum->get_all_Items
389
 
 Function : returns flattened list of all Item objects (Items, ListItems,
390
 
            StructureItems)
391
 
 Returns  : array of Items
392
 
 Args     : none
393
 
 Note     : items are added top-down (similar order to using nested calls)
394
 
            in original list order.
395
 
 
396
 
             1         2        7        8
397
 
           Item  -   Item  -  Item  -  Item ...
398
 
                     |
399
 
                    | 3        6
400
 
                 ListItem - ListItem
401
 
                   |
402
 
                  | 4          5
403
 
               Structure - Structure
404
 
 
405
 
=cut
406
 
 
407
 
sub get_all_Items {
408
 
    my $self = shift;
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;                
416
 
                } 
417
 
            }
418
 
        }
419
 
    }
420
 
    return @{$self->{'_ordered_items'}};
421
 
}
422
 
 
423
 
=head2 get_all_names
424
 
 
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
429
 
 Args     : none
430
 
 
431
 
=cut
432
 
 
433
 
sub get_all_names {
434
 
    my ($self) = @_;
435
 
    my %tmp;
436
 
    my @data = grep {!$tmp{$_}++}
437
 
        map {$_->get_name} $self->get_all_Items;
438
 
    return @data;
439
 
}
440
 
 
441
 
=head2 get_Items_by_name
442
 
 
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)
448
 
 
449
 
=cut
450
 
 
451
 
sub get_Items_by_name {
452
 
    my ($self, $key) = @_;
453
 
    return unless $key;
454
 
    my @data = grep {$_->get_name eq $key}
455
 
        $self->get_all_Items;
456
 
    return @data;
457
 
}
458
 
 
459
 
=head2 get_contents_by_name
460
 
 
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
464
 
            passed argument)
465
 
 Returns  : array of values (type varies per Item)
466
 
 Args     : string (Item name)
467
 
 
468
 
=cut
469
 
 
470
 
sub get_contents_by_name {
471
 
    my ($self, $key) = @_;
472
 
    return unless $key;
473
 
    my @data = map {$_->get_content} 
474
 
        grep {$_->get_name eq $key}
475
 
        $self->get_all_Items;
476
 
    return @data;
477
 
}
478
 
 
479
 
=head2 get_type_by_name
480
 
 
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
484
 
            passed argument)
485
 
 Returns  : scalar value (string) if present
486
 
 Args     : string (Item name)
487
 
 
488
 
=cut
489
 
 
490
 
sub get_type_by_name {
491
 
    my ($self, $key) = @_;
492
 
    return unless $key;
493
 
    my ($it) = grep {$_->get_name eq $key} $self->get_all_Items;
494
 
    return $it->get_type;
495
 
}
496
 
 
497
 
# private data method
498
 
 
499
 
sub _add_data {
500
 
    my ($self, $data) = @_;
501
 
    if ($data->{Item}) {
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;
511
 
        }
512
 
    }
513
 
    for my $nm (qw(Type content Name)) {
514
 
        $self->{'_item'.lc $nm} = $data->{$nm} if defined $data->{$nm};
515
 
    }
516
 
    $self->{'_id'} = $data->{Id} if exists $data->{Id};    
517
 
}
518
 
 
519
 
=head2 to_string
520
 
 
521
 
 Title    : to_string
522
 
 Usage    : $foo->to_string()
523
 
 Function : converts current object to string
524
 
 Returns  : none
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
528
 
 
529
 
=cut
530
 
 
531
 
# recursively called to grab subitems, then layer
532
 
 
533
 
sub to_string {
534
 
    my $self = shift;
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",
540
 
        $level, '',
541
 
        $pad, $self->get_name(),
542
 
        $self->_text_wrap(':',
543
 
             ' ' x ($pad).':',
544
 
             $content));
545
 
    for my $sub ($self->get_subItems) {
546
 
        $string .= $sub->to_string(4 + $level);
547
 
    }
548
 
    return $string;
549
 
}
550
 
 
551
 
1;
552