annotate Roary/lib/Bio/Roary/AssemblyStatistics.pm @ 0:c47a5f61bc9f draft

Uploaded
author dereeper
date Fri, 14 May 2021 20:27:06 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
1 package Bio::Roary::AssemblyStatistics;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
2
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
3 # ABSTRACT: Given a spreadsheet of gene presence and absence calculate some statistics
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
4
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
5 =head1 SYNOPSIS
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
6
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
7 Given a spreadsheet of gene presence and absence calculate some statistics
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
8
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
9 =cut
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
10
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
11 use Moose;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
12 use Bio::Roary::ExtractCoreGenesFromSpreadsheet;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
13 use Log::Log4perl qw(:easy);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
14 with 'Bio::Roary::SpreadsheetRole';
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
15
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
16 has 'output_filename' => ( is => 'ro', isa => 'Str', default => 'assembly_statistics.csv' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
17 has 'job_runner' => ( is => 'ro', isa => 'Str', default => 'Local' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
18 has 'cpus' => ( is => 'ro', isa => 'Int', default => 1 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
19 has 'core_definition' => ( is => 'rw', isa => 'Num', default => 0.99 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
20 has '_cloud_percentage' => ( is => 'rw', isa => 'Num', default => 0.15 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
21 has '_shell_percentage' => ( is => 'rw', isa => 'Num', default => 0.95 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
22 has '_soft_core_percentage' => ( is => 'rw', isa => 'Num', default => 0.99 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
23 has 'verbose' => ( is => 'ro', isa => 'Bool', default => 0 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
24 has 'contiguous_window' => ( is => 'ro', isa => 'Int', default => 10 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
25 has 'ordered_genes' => ( is => 'ro', isa => 'ArrayRef', lazy => 1, builder => '_build_ordered_genes' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
26 has '_genes_to_rows' => ( is => 'ro', isa => 'HashRef', lazy => 1, builder => '_build__genes_to_rows' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
27 has 'all_sample_statistics' => ( is => 'ro', isa => 'HashRef', lazy => 1, builder => '_build_all_sample_statistics' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
28 has 'sample_names_to_column_index' => ( is => 'rw', isa => 'Maybe[HashRef]' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
29 has 'summary_output_filename'=> ( is => 'ro', isa => 'Str', default => 'summary_statistics.txt' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
30 has 'logger' => ( is => 'ro', lazy => 1, builder => '_build_logger');
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
31 has 'gene_category_count' => ( is => 'ro', isa => 'HashRef', lazy => 1, builder => '_build_gene_category_count' );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
32
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
33 sub BUILD {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
34 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
35 $self->_genes_to_rows;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
36 $self->gene_category_count;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
37 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
38
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
39 sub _build_logger
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
40 {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
41 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
42 Log::Log4perl->easy_init( $ERROR );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
43 my $logger = get_logger();
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
44 return $logger;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
45 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
46
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
47 sub create_summary_output
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
48 {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
49 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
50 open(my $fh, '>', $self->summary_output_filename) or Bio::Roary::Exceptions::CouldntWriteToFile->throw(error => "Couldnt write to ".$self->summary_output_filename);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
51
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
52 my $core_percentage = $self->core_definition()*100;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
53 my $soft_core_percentage = $self->_soft_core_percentage*100;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
54 my $shell_percentage = $self->_shell_percentage()*100;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
55 my $cloud_percentage = $self->_cloud_percentage()*100;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
56
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
57 my $core_genes = ($self->gene_category_count->{core} ? $self->gene_category_count->{core} : 0);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
58 my $soft_core_genes = ($self->gene_category_count->{soft_core} ? $self->gene_category_count->{soft_core} : 0);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
59 my $shell_genes =($self->gene_category_count->{shell} ? $self->gene_category_count->{shell} : 0);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
60 my $cloud_genes = ($self->gene_category_count->{cloud} ? $self->gene_category_count->{cloud} : 0);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
61 my $total_genes = $core_genes + $soft_core_genes + $shell_genes + $cloud_genes ;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
62
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
63 $self->logger->warn("Very few core genes detected with the current settings. Try modifying the core definition ( -cd 90 ) and/or
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
64 the blast identity (-i 70) parameters. Also try checking for contamination (-qc) and ensure you only have one species.") if($core_genes < 100);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
65
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
66 print {$fh} "Core genes\t($core_percentage".'% <= strains <= 100%)'."\t$core_genes\n";
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
67 print {$fh} "Soft core genes\t(".$shell_percentage."% <= strains < ".$soft_core_percentage."%)\t$soft_core_genes\n";
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
68 print {$fh} "Shell genes\t(".$cloud_percentage."% <= strains < ".$shell_percentage."%)\t$shell_genes\n";
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
69 print {$fh} "Cloud genes\t(0% <= strains < ".$cloud_percentage."%)\t$cloud_genes\n";
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
70 print {$fh} "Total genes\t(0% <= strains <= 100%)\t$total_genes\n";
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
71
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
72 close($fh);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
73 return 1;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
74 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
75
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
76 sub _build_gene_category_count {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
77 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
78 my %gene_category_count;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
79 $self->_soft_core_percentage($self->core_definition);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
80
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
81 if ( $self->_soft_core_percentage <= $self->_shell_percentage ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
82 $self->_shell_percentage( $self->_soft_core_percentage - 0.01 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
83 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
84
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
85 my $number_of_samples = keys %{ $self->sample_names_to_column_index };
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
86 for my $gene_name ( keys %{ $self->_genes_to_rows } ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
87 my $isolates_with_gene = 0;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
88
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
89 for ( my $i = $self->_num_fixed_headers ; $i < @{ $self->_genes_to_rows->{$gene_name} } ; $i++ ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
90 $isolates_with_gene++
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
91 if ( defined( $self->_genes_to_rows->{$gene_name}->[$i] ) && $self->_genes_to_rows->{$gene_name}->[$i] ne "" );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
92 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
93
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
94 if ( $isolates_with_gene < $self->_cloud_percentage() * $number_of_samples ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
95 $gene_category_count{cloud}++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
96 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
97 elsif ( $isolates_with_gene < $self->_shell_percentage() * $number_of_samples ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
98 $gene_category_count{shell}++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
99 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
100 elsif ( $isolates_with_gene < $self->_soft_core_percentage() * $number_of_samples ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
101 $gene_category_count{soft_core}++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
102 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
103 else {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
104 $gene_category_count{core}++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
105 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
106 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
107 return \%gene_category_count;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
108 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
109
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
110 sub _build_ordered_genes {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
111 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
112 return Bio::Roary::ExtractCoreGenesFromSpreadsheet->new( spreadsheet => $self->spreadsheet, core_definition => $self->core_definition )
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
113 ->ordered_core_genes();
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
114 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
115
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
116 sub _build__genes_to_rows {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
117 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
118
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
119 my %genes_to_rows;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
120 seek( $self->_input_spreadsheet_fh, 0, 0 );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
121 my $header_row = $self->_csv_parser->getline( $self->_input_spreadsheet_fh );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
122 $self->_populate_sample_names_to_column_index($header_row);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
123
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
124 while ( my $row = $self->_csv_parser->getline( $self->_input_spreadsheet_fh ) ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
125 next if ( !defined( $row->[0] ) || $row->[0] eq "" );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
126 $genes_to_rows{ $row->[0] } = $row;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
127 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
128
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
129 return \%genes_to_rows;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
130 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
131
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
132 sub _populate_sample_names_to_column_index {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
133 my ( $self, $row ) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
134
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
135 my %samples_to_index;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
136 for ( my $i = $self->_num_fixed_headers ; $i < @{$row} ; $i++ ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
137 next if ( ( !defined( $row->[$i] ) ) || $row->[$i] eq "" );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
138 $samples_to_index{ $row->[$i] } = $i;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
139 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
140 $self->sample_names_to_column_index( \%samples_to_index );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
141 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
142
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
143 sub _build_all_sample_statistics {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
144 my ($self) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
145
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
146 my %sample_stats;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
147
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
148 # For each sample - loop over genes in order - number of contiguous blocks - max size of contiguous block - n50 - incorrect joins
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
149 for my $sample_name ( sort keys %{ $self->sample_names_to_column_index } ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
150 $sample_stats{$sample_name} = $self->_sample_statistics($sample_name);
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
151 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
152 return \%sample_stats;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
153 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
154
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
155 sub _sample_statistics {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
156 my ( $self, $sample_name ) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
157
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
158 my $sample_column_index = $self->sample_names_to_column_index->{$sample_name};
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
159 my @gene_ids;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
160 for my $gene_name ( @{ $self->ordered_genes } ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
161 my $sample_gene_id = $self->_genes_to_rows->{$gene_name}->[$sample_column_index];
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
162 next unless ( defined($sample_gene_id) );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
163
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
164 if ( $sample_gene_id =~ /_([\d]+)$/ ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
165 my $gene_number = $1;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
166 push( @gene_ids, $gene_number );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
167 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
168 else {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
169 next;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
170 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
171 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
172
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
173 return $self->_number_of_contiguous_blocks( \@gene_ids );
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
174 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
175
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
176 sub _number_of_contiguous_blocks {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
177 my ( $self, $gene_ids ) = @_;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
178
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
179 my $current_gene_id = $gene_ids->[0];
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
180 my $number_of_blocks = 1;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
181 my $largest_block_size = 0;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
182 my $block_size = 0;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
183 for my $gene_id ( @{$gene_ids} ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
184 if ( !( ( $current_gene_id + $self->contiguous_window >= $gene_id ) && ( $current_gene_id - $self->contiguous_window <= $gene_id ) )
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
185 )
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
186 {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
187 if ( $block_size >= $largest_block_size ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
188 $largest_block_size = $block_size;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
189 $block_size = 0;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
190 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
191 $number_of_blocks++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
192 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
193 $current_gene_id = $gene_id;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
194 $block_size++;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
195 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
196
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
197 if ( $block_size > $largest_block_size ) {
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
198 $largest_block_size = $block_size;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
199 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
200 return { num_blocks => $number_of_blocks, largest_block_size => $largest_block_size };
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
201 }
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
202
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
203 no Moose;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
204 __PACKAGE__->meta->make_immutable;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
205
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
206 1;
c47a5f61bc9f Uploaded
dereeper
parents:
diff changeset
207