diff --git a/modules/Bio/EnsEMBL/DnaDnaAlignFeature.pm b/modules/Bio/EnsEMBL/DnaDnaAlignFeature.pm index 19bc0b059a6a3e5462a4f751b607d4f7bab7dd17..4a25647eaaf0a7a7de15ee6b3ff50faa1c62cbea 100644 --- a/modules/Bio/EnsEMBL/DnaDnaAlignFeature.pm +++ b/modules/Bio/EnsEMBL/DnaDnaAlignFeature.pm @@ -61,5 +61,105 @@ sub _query_unit { return 1; } +=head2 restrict_between_positions + + Arg 1 : int $start + Arg 2 : int $end + Arg 3 : string $sequence_name + The Feature can either be restricted on Ensembl coords + or on hit coords. The sequence_name decides which one. + Example : none + Description: Makes a new AlignFeature that sits in the new coords + Returntype : DnaDnaAlignFeature + Exceptions : returns undef if it cant do the job + Caller : general + +=cut + +sub restrict_between_positions { + my ($self,$start,$end,$seqref) = @_; + + unless (defined $start && $start =~ /^\d+$/) { + $self->throw("The first argument is not defined or is not an integer"); + } + unless (defined $end && $end =~ /^\d+$/) { + $self->throw("The second argument is not defined or is not an integer"); + } + unless (defined $seqref && + ($seqref eq "seqname" || $seqref eq "hseqname")) { + $self->throw("The third argument is not defined or is not equal to 'seqname' or 'hseqname'"); + } + +# symbolic method references should be forbidden! + + my ($start_method1,$end_method1,$strand_method1,$start_method2,$end_method2,$strand_method2) = + qw(start end strand hstart hend hstrand); + + if ($seqref eq "hseqname") { + ($start_method1,$end_method1,$strand_method1,$start_method2,$end_method2,$strand_method2) = + qw(hstart hend hstrand start end strand); + } + + my @restricted_features; + + foreach my $ungapped_feature ($self->ungapped_features) { + + if ($ungapped_feature->$start_method1() > $end || + $ungapped_feature->$end_method1() < $start) { + + next; + + } elsif ($ungapped_feature->$end_method1() <= $end && + $ungapped_feature->$start_method1() >= $start) { + + push @restricted_features, $ungapped_feature; + + } else { + + if ($ungapped_feature->$strand_method1() eq $ungapped_feature->$strand_method2()) { + + if ($ungapped_feature->$start_method1() < $start) { + + my $offset = $start - $ungapped_feature->$start_method1(); + $ungapped_feature->$start_method1($start); + $ungapped_feature->$start_method2($ungapped_feature->$start_method2() + $offset); + + } + if ($ungapped_feature->$end_method1() > $end) { + + my $offset = $ungapped_feature->$end_method1() - $end; + $ungapped_feature->$end_method1($end); + $ungapped_feature->$end_method2($ungapped_feature->$end_method2() - $offset); + + } + } else { + + if ($ungapped_feature->$start_method1() < $start) { + + my $offset = $start - $ungapped_feature->$start_method1(); + $ungapped_feature->$start_method1($start); + $ungapped_feature->$end_method2($ungapped_feature->$end_method2() - $offset); + + } + if ($ungapped_feature->$end_method1() > $end) { + + my $offset = $ungapped_feature->$end_method1() - $end; + $ungapped_feature->$end_method1($end); + $ungapped_feature->$start_method2($ungapped_feature->$start_method2() + $offset); + + } + } + + push @restricted_features, $ungapped_feature; + } + } + + if (scalar @restricted_features) { + my $DnaDnaAlignFeature = new Bio::EnsEMBL::DnaDnaAlignFeature('-features' =>\@restricted_features); + return $DnaDnaAlignFeature; + } else { + return undef; + } +} 1;