Mercurial > repos > jjohnson > crest
diff Gene.pm @ 0:acc8d8bfeb9a
Uploaded
author | jjohnson |
---|---|
date | Wed, 08 Feb 2012 16:59:24 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Gene.pm Wed Feb 08 16:59:24 2012 -0500 @@ -0,0 +1,130 @@ +package Gene; +use strict; +use Transcript; +use Carp; +use Data::Dumper; + +# a light weight gene structure is used here + +my @Gene_slots; +BEGIN { + @Gene_slots = qw(NAME CHR START END STRAND EXONS TRANSCRIPTS TYPE); +} +use enum @Gene_slots; + +my %attribute = ( + name => NAME, + chr => CHR, + start => START, + end => END, + strand => STRAND, + transcripts => TRANSCRIPTS, + type => TYPE, +); + +#using an array instead of a hash for the node +sub _accessor { + my $index = shift; + return sub { + my $self = shift; + return undef unless $self; + if (@_) { + $self->[$index] = shift; + } + return $self->[$index]; + }; +} + +while(my($at, $idx) = each %attribute) { + no strict 'refs'; + *$at = _accessor($idx); +} + +sub new { + my $class = shift; + my $obj = []; + $obj->[TRANSCRIPTS] = []; + if (@_) { + my %arg = @_; + $obj->[NAME] = $arg{-NAME} if($arg{-NAME}); + $obj->[CHR] = $arg{-CHR} if($arg{-CHR}); + $obj->[START] = $arg{-START} if($arg{-START}); + $obj->[END] = $arg{-END} if($arg{-END}); + $obj->[STRAND] = $arg{-STRAND} if($arg{-STRAND}); + $obj->[TRANSCRIPTS] = $arg{-TRANSCRIPTS} if($arg{-TRANSCRIPTS}); + } + return bless $obj, $class; +} + +sub add_transcript { + my ($self, $fea) = @_; + croak "You must add a Transcript type into a gene" + unless ($fea->isa('Transcript')); + if($self->[STRAND] && $self->[STRAND] ne $fea->strand) { + croak "The transcript has different orientation with the gene"; + } + if($self->[CHR] && $self->[CHR] ne $fea->chr) { + croak "The transcript is on different chr with the gene"; + } +# if($self->[TYPE] && $fea->type ne $fea->type) { +# croak "The type of the transcript are different from the gene"; +# } + $self->[STRAND] = $fea->strand; + $self->[CHR] = $fea->chr; +# $self->[TYPE] = $fea->type; + + push @{$self->[TRANSCRIPTS]}, $fea; + + $self->[NAME] = $self->[NAME] ? $self->[NAME] . "," . $fea->name : $fea->name; + + + #update the start and end of the gene + $self->[START] = $fea->start if(!$self->[START] || $self->[START] > $fea->start); + $self->[END] = $fea->end if(!$self->[END] || $self->[END] < $fea->end); +} + +sub get_start { + my ($self, $pos, $ext) = @_; + my $rtn = $pos; + foreach my $t (@{$self->[TRANSCRIPTS]}) { + my $tmp = $t->get_start($pos, $ext); + $rtn = $tmp if($tmp < $rtn); + } + return $rtn; +} + +sub get_end { + my ($self, $pos, $ext) = @_; + my $rtn = $pos; + foreach my $t (@{$self->[TRANSCRIPTS]}) { + my $tmp = $t->get_end($pos, $ext); + $rtn = $tmp if($tmp > $rtn); + } + return $rtn; +} + +sub overlap { + my ($self, $fea) = @_; + + if(ref($fea) eq 'ARRAY') { + foreach my $t ( @{$self->[TRANSCRIPTS]} ) { + return 1 if($t->overlap($fea)); + } + } + elsif($fea->isa('Transcript')) { + return if($fea->strand && $self->[STRAND] ne $fea->strand ); + return if($fea->chr && $self->[CHR] ne $fea->chr) ; + #return if($fea->type && $self->[TYPE] ne $fea->type); + foreach my $e ( @{$fea->exons}) { + foreach my $t ( @{$self->[TRANSCRIPTS]} ) { + return 1 if($t->overlap($e)); + } + } + } + else { + croak "Not implemented overlap"; + } + return 0; +} + +1;