File Coverage

blib/lib/GenOO/TranscriptCollection/Factory/GTF.pm
Criterion Covered Total %
statement 57 59 96.6
branch 20 24 83.3
condition 10 24 41.6
subroutine 10 10 100.0
pod 0 1 0.0
total 97 118 82.2


line stmt bran cond sub pod time code
1             # POD documentation - main docs before the code
2              
3             =head1 NAME
4              
5             GenOO::TranscriptCollection::Factory::GTF - Factory to create TranscriptCollection from a GTF file
6              
7             =head1 SYNOPSIS
8              
9             Creates GenOO::TranscriptCollection containing transcripts from a GTF file
10             Preferably use it through the generic GenOO::TranscriptCollection::Factory
11              
12             my $factory = GenOO::TranscriptCollection::Factory->new('GTF',{
13             file => 'sample.gtf'
14             });
15              
16             =head1 DESCRIPTION
17              
18             An instance of this class is a concrete factory for the creation of a
19             L<GenOO::TranscriptCollection> containing transcripts from a GTF file. It offers the method
20             "read_collection" (as the consumed role requires) which returns the actual
21             L<GenOO::TranscriptCollection> object in the form of
22             L<GenOO::RegionCollection::Type::DoubleHashArray>. The latter is the implementation
23             of the L<GenOO::RegionCollection> class based on the complex data structure
24             L<GenOO::Data::Structure::DoubleHashArray>.
25              
26             =head1 EXAMPLES
27              
28             # Create a concrete factory
29             my $factory_implementation = GenOO::TranscriptCollection::Factory->new('GTF',{
30             file => 'sample.gtf'
31             });
32            
33             # Return the actual GenOO::TranscriptCollection object
34             my $collection = $factory_implementation->read_collection;
35             print ref($collection) # GenOO::TranscriptCollection::Type::DoubleHashArray
36              
37             =cut
38              
39             # Let the code begin...
40              
41             package GenOO::TranscriptCollection::Factory::GTF;
42             $GenOO::TranscriptCollection::Factory::GTF::VERSION = '1.5.2';
43             #######################################################################
44             ####################### Load External modules #####################
45             #######################################################################
46 1     1   19557 use Modern::Perl;
  1         3  
  1         11  
47 1     1   170 use autodie;
  1         2  
  1         10  
48 1     1   5410 use Moose;
  1         3  
  1         10  
49 1     1   7790 use namespace::autoclean;
  1         2  
  1         12  
50              
51              
52             #######################################################################
53             ####################### Load GenOO modules #####################
54             #######################################################################
55 1     1   830 use GenOO::RegionCollection::Factory;
  1         4  
  1         66  
56 1     1   710 use GenOO::Transcript;
  1         5  
  1         55  
57 1     1   715 use GenOO::Gene;
  1         3  
  1         55  
58 1     1   746 use GenOO::Data::File::GFF;
  1         5  
  1         795  
59              
60              
61             #######################################################################
62             ####################### Interface attributes ######################
63             #######################################################################
64             has 'file' => (
65             isa => 'Str',
66             is => 'ro'
67             );
68              
69              
70             #######################################################################
71             ########################## Consumed Roles #########################
72             #######################################################################
73             with 'GenOO::RegionCollection::Factory::Requires';
74              
75              
76             #######################################################################
77             ######################## Interface Methods ########################
78             #######################################################################
79             sub read_collection {
80 9     9 0 69575 my ($self) = @_;
81            
82 9         441 my @transcripts = $self->_read_gtf_with_transcripts($self->file);
83            
84 9         627 return GenOO::RegionCollection::Factory->create('RegionArray', {
85             array => \@transcripts
86             })->read_collection;
87             }
88              
89             #######################################################################
90             ######################### Private methods ##########################
91             #######################################################################
92             sub _read_gtf_with_transcripts {
93 9     9   49 my ($self, $file)=@_;
94            
95 9         53 my %transcripts;
96             my %transcript_splice_starts;
97 9         0 my %transcript_splice_stops;
98 9         0 my %genes;
99            
100 9         388 my $gff = GenOO::Data::File::GFF->new(file => $file);
101              
102 9         92 while (my $record = $gff->next_record){
103 4936 50       173375 my $transcript_id = $record->attribute('transcript_id') or die "transcript_id attribute must be defined\n";
104            
105 4936 50       136886 if ($record->strand == 0){
106 0         0 warn "Skipping transcript $transcript_id: strand symbol". $record->strand_symbol." not accepted\n";
107 0         0 next;
108             }
109            
110             # Get transcript with id or create a new one. Update coordinates if required
111 4936         11090 my $transcript = $transcripts{$transcript_id};
112 4936 100       10362 if (not defined $transcript) {
113 618         16768 $transcript = GenOO::Transcript->new(
114             id => $transcript_id,
115             chromosome => $record->rname,
116             strand => $record->strand,
117             start => $record->start,
118             stop => $record->stop,
119             splice_starts => [$record->start], # will be re-written later
120             splice_stops => [$record->stop], # will be re-written later
121             );
122 618         4845 $transcripts{$transcript_id} = $transcript;
123 618         2203 $transcript_splice_starts{$transcript_id} = [];
124 618         1690 $transcript_splice_stops{$transcript_id} = [];
125             }
126             else {
127 4318 100       115487 $transcript->start($record->start) if ($record->start < $transcript->start);
128 4318 100       116285 $transcript->stop($record->stop) if ($record->stop > $transcript->stop);
129             }
130            
131 4936 100       136996 if ($record->feature eq 'exon') {
    100          
    100          
132 3369         5411 push @{$transcript_splice_starts{$transcript_id}}, $record->start;
  3369         92363  
133 3369         6050 push @{$transcript_splice_stops{$transcript_id}}, $record->stop;
  3369         90715  
134             }
135             elsif ($record->feature eq 'start_codon') {
136 197 100 33     5272 if ($record->strand == 1 and
    50 66        
      33        
      33        
137             (!defined $transcript->coding_start or
138             $record->start < $transcript->coding_start)) {
139              
140 116         3282 $transcript->coding_start($record->start);
141             }
142             elsif ($record->strand == -1 and
143             (!defined $transcript->coding_stop or
144             $record->stop > $transcript->coding_stop)) {
145              
146 81         2237 $transcript->coding_stop($record->stop);
147             }
148             }
149             elsif ($record->feature eq 'stop_codon') {
150 197 100 33     5407 if ($record->strand == 1 and
    50 66        
      33        
      33        
151             (!defined $transcript->coding_stop or
152             $record->stop > $transcript->coding_stop)) {
153              
154 116         3203 $transcript->coding_stop($record->stop);
155             }
156             elsif ($record->strand == -1 and
157             (!defined $transcript->coding_start or
158             $record->start < $transcript->coding_start)) {
159              
160 81         2263 $transcript->coding_start($record->start);
161             }
162             }
163             }
164            
165 9         319 foreach my $transcript_id (keys %transcripts) {
166 618         2560 $transcripts{$transcript_id}->set_splice_starts_and_stops($transcript_splice_starts{$transcript_id}, $transcript_splice_stops{$transcript_id});
167             }
168            
169 9         581 return values %transcripts;
170             }
171              
172             1;