diff --git a/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm b/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm index 5529b1237d9954c5716f09ed3aed6e3752b2e2f1..7dd4054a689f1a8e1998b174b46d034f5fd823d5 100644 --- a/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm +++ b/modules/Bio/EnsEMBL/DBSQL/SliceAdaptor.pm @@ -589,6 +589,9 @@ sub fetch_by_location { Location names must be separated by a C<:>. All others can be separated by C<..>, C<:> C<_>, or C<->. + + If the start is negative, start will be reset to 1 (e.g.: 1: -10-1,000') + If both start and end are negative, returns undef (e.g.: 1: -10--1,000') Arg[2] : boolean $no_warnings Suppress warnings from this method Arg[3] : boolean $no_errors @@ -611,9 +614,10 @@ sub parse_location_to_values { my $separator_regex = qr/(?:-|[.]{2}|\:|_)?/; # support -, .., : and _ as separators my $hgvs_nomenclature_regex = qr/(?:g\.)?/; # check for HGVS looking locations e.g. X:g.1-100 my $number_regex = qr/[0-9, EMKG]+/xmsi; + my $number_regex_signed = qr/-?[0-9, EMKG]+/xmsi; # to capture negative locations as sometimes we end up in negative location if the location is padded my $strand_regex = qr/[+-1]|-1/xms; - my $regex = qr/^((?:\w|\.|_|-)+) \s* :? \s* $hgvs_nomenclature_regex ($number_regex)? $separator_regex ($number_regex)? $separator_regex ($strand_regex)? $/xms; + my $regex = qr/^((?:\w|\.|_|-)+) \s* :? \s* $hgvs_nomenclature_regex ($number_regex_signed)? $separator_regex ($number_regex)? $separator_regex ($strand_regex)? $/xms; my ($seq_region_name, $start, $end, $strand); if(($seq_region_name, $start, $end, $strand) = $location =~ $regex) { @@ -627,7 +631,12 @@ sub parse_location_to_values { $start =~ s/$number_seps_regex//g; if($start < 1) { warning "Start was less than 1 (${start}) which is not allowed. Resetting to 1" if ! $no_warnings; - $start = 1; + + unless(defined $end) { + # We will reach here only when the location is given without start and '-' is used as seperator eg: 1:-10 (expected to return 1:1-10) + $end = abs($start); + } + $start = 1; } } if(defined $end) { diff --git a/modules/t/sliceAdaptor.t b/modules/t/sliceAdaptor.t index 38e800fc163520acaf5d028f0b1b70d622db8ee7..45b8414cddda549f14d99eea0a8363495df1ed3e 100644 --- a/modules/t/sliceAdaptor.t +++ b/modules/t/sliceAdaptor.t @@ -632,6 +632,12 @@ test_toplevel_location('chr1: 100', 'chromosome', '1', 100, 246874334, 1, $ucsc) test_toplevel_location('chr1:100..2000000000', 'chromosome', '1', 100, 246874334, 1, $ucsc); test_toplevel_location('chr1:100..2E9', 'chromosome', '1', 100, 246874334, 1, $ucsc); +# Try negative locations +test_toplevel_location('chr1: -10-1,000', 'chromosome', '1', 1, 1000, 1, $ucsc); +test_toplevel_location('chr1: -10..1,000', 'chromosome', '1', 1, 1000, 1, $ucsc); +test_toplevel_location('chr1: -10_1,000', 'chromosome', '1', 1, 1000, 1, $ucsc); +ok(!defined $slice_adaptor->fetch_by_toplevel_location('1:-1000--10', 1), 'Checking with a bogus region with negative coords returns undef'); + #Try strands test_toplevel_location('1:1-1000:1', 'chromosome', '1', 1, 1000, 1); test_toplevel_location('1:1-1000:-1', 'chromosome', '1', 1, 1000, -1);