File Coverage

lib/Bio/Roary/Output/EmblGroups.pm
Criterion Covered Total %
statement 35 144 24.3
branch 4 36 11.1
condition 0 27 0.0
subroutine 9 19 47.3
pod 0 1 0.0
total 48 227 21.1


line stmt bran cond sub pod time code
1             package Bio::Roary::Output::EmblGroups;
2             $Bio::Roary::Output::EmblGroups::VERSION = '3.10.1';
3             # ABSTRACT: Create a tab/embl file with the features for drawing pretty pictures
4              
5              
6 2     2   87248 use Moose;
  2         414437  
  2         16  
7 2     2   14985 use POSIX;
  2         6845  
  2         15  
8 2     2   4424 use File::Basename;
  2         4  
  2         178  
9 2     2   298 use Bio::Roary::Exceptions;
  2         5  
  2         60  
10 2     2   223 use Bio::Roary::AnalyseGroups;
  2         6  
  2         97  
11 2     2   523 use Bio::Roary::AnnotateGroups;
  2         4  
  2         2713  
12             with 'Bio::Roary::Output::EMBLHeaderCommon';
13              
14             has 'annotate_groups_obj' => ( is => 'ro', isa => 'Bio::Roary::AnnotateGroups', required => 1 );
15             has 'analyse_groups_obj' => ( is => 'ro', isa => 'Bio::Roary::AnalyseGroups', required => 1 );
16             has 'output_filename' => ( is => 'ro', isa => 'Str', default => 'core_accessory.tab' );
17             has 'output_header_filename' => ( is => 'ro', isa => 'Str', lazy => 1, builder => '_build_output_header_filename' );
18             has 'groups_to_contigs' => ( is => 'ro', isa => 'Maybe[HashRef]' );
19             has 'ordering_key' => ( is => 'ro', isa => 'Str', default => 'core_accessory_overall_order' );
20              
21             has '_output_fh' => ( is => 'ro', lazy => 1, builder => '_build__output_fh' );
22             has '_output_header_fh' => ( is => 'ro', lazy => 1, builder => '_build__output_header_fh' );
23             has '_sorted_file_names' => ( is => 'ro', isa => 'ArrayRef', lazy => 1, builder => '_build__sorted_file_names' );
24             has '_groups_to_files' => ( is => 'ro', isa => 'HashRef', lazy => 1, builder => '_build__groups_to_files' );
25             has 'heatmap_lookup_table' => ( is => 'ro', isa => 'ArrayRef', lazy => 1, builder => '_build_heatmap_lookup_table' );
26              
27             sub _build__output_fh {
28 0     0   0 my ($self) = @_;
29 0 0       0 open( my $fh, '>', $self->output_filename )
30             or Bio::Roary::Exceptions::CouldntWriteToFile->throw( error => "Couldnt write output file:" . $self->output_filename );
31 0         0 return $fh;
32             }
33              
34             sub _build__output_header_fh {
35 0     0   0 my ($self) = @_;
36 0 0       0 open( my $fh, '>', $self->output_header_filename )
37             or Bio::Roary::Exceptions::CouldntWriteToFile->throw( error => "Couldnt write output file:" . $self->output_filename );
38 0         0 return $fh;
39             }
40              
41             sub _build_output_header_filename {
42 0     0   0 my ($self) = @_;
43 0         0 my $base_name = $self->output_filename;
44 0         0 $base_name =~ s/\.tab/.header.embl/i;
45 0         0 return $base_name;
46             }
47              
48             sub _build__sorted_file_names {
49 0     0   0 my ($self) = @_;
50 0         0 my @sorted_file_names = sort( @{ $self->analyse_groups_obj->fasta_files } );
  0         0  
51 0         0 return \@sorted_file_names;
52             }
53              
54             sub _build__groups_to_files {
55 0     0   0 my ($self) = @_;
56 0         0 my %groups_to_files;
57 0         0 for my $group ( @{ $self->annotate_groups_obj->_groups } ) {
  0         0  
58 0         0 my $genes = $self->annotate_groups_obj->_groups_to_id_names->{$group};
59 0         0 my %filenames;
60 0         0 for my $gene_name ( @{$genes} ) {
  0         0  
61 0         0 my $filename = $self->analyse_groups_obj->_genes_to_file->{$gene_name};
62 0         0 push( @{ $filenames{$filename} }, $gene_name );
  0         0  
63             }
64 0         0 $groups_to_files{$group} = \%filenames;
65             }
66 0         0 return \%groups_to_files;
67             }
68              
69             sub _block {
70 0     0   0 my ( $self, $group ) = @_;
71 0         0 my @taxon_names_array;
72 0         0 my $annotated_group_name = $self->annotate_groups_obj->_groups_to_consensus_gene_names->{$group};
73              
74             return ''
75             if (
76             !(
77             defined( $self->groups_to_contigs->{$annotated_group_name} )
78 0 0 0     0 && defined( $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key } )
79             )
80             );
81              
82             return ''
83             if ( defined( $self->groups_to_contigs->{$annotated_group_name}->{comment} )
84 0 0 0     0 && $self->groups_to_contigs->{$annotated_group_name}->{comment} ne '' );
85              
86 0         0 my $coordindates = $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key };
87              
88 0         0 for my $filename ( @{ $self->_sorted_file_names } ) {
  0         0  
89 0         0 my $group_to_file_genes = $self->_groups_to_files->{$group}->{$filename};
90              
91 0 0 0     0 if ( defined($group_to_file_genes) && @{$group_to_file_genes} > 0 ) {
  0         0  
92 0         0 my $filename_cpy = basename($filename);
93 0         0 $filename_cpy =~ s!\.gff\.proteome\.faa!!;
94 0         0 push( @taxon_names_array, $filename_cpy );
95 0         0 next;
96             }
97             }
98              
99 0         0 my $colour = $self->_get_heat_map_colour( \@taxon_names_array, $self->annotate_groups_obj->_number_of_files );
100              
101 0         0 my $taxon_names = join( " ", @taxon_names_array );
102              
103 0         0 my $tab_file_entry = "FT variation $coordindates\n";
104 0         0 $tab_file_entry .= "FT /colour=$colour\n";
105 0         0 $tab_file_entry .= "FT /gene=$annotated_group_name\n";
106 0         0 $tab_file_entry .= "FT /taxa=\"$taxon_names\"\n";
107              
108 0         0 return $tab_file_entry;
109             }
110              
111             sub _get_heat_map_colour {
112 14     14   35 my ( $self, $taxon_names, $number_of_files ) = @_;
113 14 100       18 return $self->heatmap_lookup_table->[0] if ( @{$taxon_names} == 1 );
  14         102  
114 12         20 my $number_of_colours = @{ $self->heatmap_lookup_table };
  12         434  
115 12 100       18 return $self->heatmap_lookup_table->[ $number_of_colours - 1 ] if ( @{$taxon_names} == $number_of_files );
  12         114  
116              
117 10         15 my $block_size = $number_of_files / @{ $self->heatmap_lookup_table };
  10         252  
118 10         50 my $colour_index = ceil( @{$taxon_names} / $block_size ) - 1;
  10         62  
119 10         271 return $self->heatmap_lookup_table->[$colour_index];
120             }
121              
122             sub _build_heatmap_lookup_table {
123 1     1   3 my ($self) = @_;
124             return [
125 1         42 4, # blue (RGB values: 0 0 255)
126             5, # cyan (RGB values: 0 255 255)
127             9, # light sky blue (RGB values: 135 206 250)
128             8, # pale green (RGB values: 152 251 152)
129             3, # green (RGB values: 0 255 0)
130             7, # yellow (RGB values: 255 255 0)
131             10, # orange (RGB values: 255 165 0)
132             16, # light red (RGB values: 255 127 127)
133             15, # mid red: (RGB values: 255 63 63)
134             2, # red (RGB values: 255 0 0)
135             ];
136             }
137              
138             sub _block_colour {
139 0     0     my ( $self, $accessory_label ) = @_;
140 0           my $colour = 2;
141 0 0         return $colour unless ( defined($accessory_label) );
142              
143 0           $colour += $accessory_label % 6;
144 0           return $colour;
145             }
146              
147             sub _header_block {
148 0     0     my ( $self, $group ) = @_;
149 0           my $annotated_group_name = $self->annotate_groups_obj->_groups_to_consensus_gene_names->{$group};
150 0           my $colour = 1;
151              
152             return ''
153             if (
154             !(
155             defined( $self->groups_to_contigs->{$annotated_group_name} )
156 0 0 0       && defined( $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key } )
157             )
158             );
159             return ''
160             if ( defined( $self->groups_to_contigs->{$annotated_group_name}->{comment} )
161 0 0 0       && $self->groups_to_contigs->{$annotated_group_name}->{comment} ne '' );
162 0           my $coordindates = $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key };
163 0           my $annotation_type = $self->_annotation_type($annotated_group_name);
164              
165 0           $colour = $self->_block_colour( $self->groups_to_contigs->{$annotated_group_name}->{accessory_label} );
166              
167 0           my $tab_file_entry = "FT$annotation_type$coordindates\n";
168 0           $tab_file_entry .= "FT /label=$annotated_group_name\n";
169 0           $tab_file_entry .= "FT /locus_tag=$annotated_group_name\n";
170 0           $tab_file_entry .= "FT /colour=$colour\n";
171              
172 0           return $tab_file_entry;
173             }
174              
175             sub _fragment_blocks {
176 0     0     my ( $self, $fh ) = @_;
177 0           my %fragment_numbers;
178 0           for my $group ( @{ $self->annotate_groups_obj->_groups } ) {
  0            
179 0           my $annotated_group_name = $self->annotate_groups_obj->_groups_to_consensus_gene_names->{$group};
180              
181 0 0         next unless ( defined( $self->groups_to_contigs->{$annotated_group_name}->{accessory_label} ) );
182 0 0         next unless ( defined( $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key } ) );
183 0 0         next if ( $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key } eq '' );
184             push(
185 0           @{ $fragment_numbers{ $self->groups_to_contigs->{$annotated_group_name}->{accessory_label} } },
186 0           $self->groups_to_contigs->{$annotated_group_name}->{ $self->ordering_key }
187             );
188             }
189              
190 0           for my $accessory_label ( keys %fragment_numbers ) {
191 0 0         next unless ( defined( $fragment_numbers{$accessory_label} ) );
192 0           my @sorted_fragment = sort { $a <=> $b } @{ $fragment_numbers{$accessory_label} };
  0            
  0            
193 0           my $tab_file_entry = '';
194 0 0         if ( @sorted_fragment > 1 ) {
    0          
195 0           my $min = $sorted_fragment[0];
196 0           my $max = $sorted_fragment[-1];
197              
198 0 0 0       next if ( !defined($min) || !defined($max) || $min eq '' || $max eq '' );
      0        
      0        
199 0           $tab_file_entry = "FT feature $min" . '..' . "$max\n";
200             }
201             elsif ( @sorted_fragment == 1 ) {
202 0           my $min = $sorted_fragment[0];
203 0 0 0       next if ( !defined($min) || $min eq '' );
204 0           $tab_file_entry = "FT feature $min\n";
205             }
206             else {
207 0           next;
208             }
209 0           $tab_file_entry .= "FT /colour=" . $self->_block_colour($accessory_label) . "\n";
210              
211 0           print {$fh} $tab_file_entry;
  0            
212             }
213              
214             }
215              
216             sub create_files {
217 0     0 0   my ($self) = @_;
218              
219 0           print { $self->_output_header_fh } $self->_header_top();
  0            
220 0           for my $group ( @{ $self->annotate_groups_obj->_groups } ) {
  0            
221 0           print { $self->_output_fh } $self->_block($group);
  0            
222 0           print { $self->_output_header_fh } $self->_header_block($group);
  0            
223             }
224 0           $self->_fragment_blocks( $self->_output_header_fh );
225 0           print { $self->_output_header_fh } $self->_header_bottom();
  0            
226 0           close( $self->_output_header_fh );
227 0           close( $self->_output_fh );
228             }
229              
230 2     2   19 no Moose;
  2         5  
  2         16  
231             __PACKAGE__->meta->make_immutable;
232              
233             1;
234              
235             __END__
236              
237             =pod
238              
239             =encoding UTF-8
240              
241             =head1 NAME
242              
243             Bio::Roary::Output::EmblGroups - Create a tab/embl file with the features for drawing pretty pictures
244              
245             =head1 VERSION
246              
247             version 3.10.1
248              
249             =head1 SYNOPSIS
250              
251             reate a tab/embl file with the features for drawing pretty pictures
252             use Bio::Roary::Output::EmblGroups;
253              
254             my $obj = Bio::Roary::Output::EmblGroups->new(
255             output_filename => 'group_statitics.csv',
256             annotate_groups_obj => $annotate_groups_obj,
257             analyse_groups_obj => $analyse_groups_obj
258             );
259             $obj->create_file;
260              
261             =head1 AUTHOR
262              
263             Andrew J. Page <ap13@sanger.ac.uk>
264              
265             =head1 COPYRIGHT AND LICENSE
266              
267             This software is Copyright (c) 2013 by Wellcome Trust Sanger Institute.
268              
269             This is free software, licensed under:
270              
271             The GNU General Public License, Version 3, June 2007
272              
273             =cut