Skip to content

Commit

Permalink
closes #195
Browse files Browse the repository at this point in the history
  • Loading branch information
manulera committed Jan 30, 2024
1 parent c7c6871 commit f99a879
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 17 deletions.
8 changes: 4 additions & 4 deletions src/pydna/dseqrecord.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,10 +901,9 @@ def __getitem__(self, sl):
# origin-spanning features should only be included after shifting
# in cases where the slice comprises the entire sequence, but then
# sl_start == sl_stop and the second condition is not met
# TODO: _location_boundaries
answer.features = [f for f in answer.features if (
f.location.parts[-1].end <= answer.seq.length and
f.location.parts[0].start <= f.location.parts[-1].end)]
_location_boundaries(f.location)[1] <= answer.seq.length and
_location_boundaries(f.location)[0] <= _location_boundaries(f.location)[1])]
else:
answer = Dseqrecord("")
identifier = "part_{id}".format(id=self.id)
Expand Down Expand Up @@ -1362,7 +1361,8 @@ def apply_cut(self, left_cut, right_cut):
# 2222
#
left_watson, left_crick, left_ovhg = self.seq.get_cut_parameters(left_cut, True)
features = self.shifted(min(left_watson, left_crick)).features
initial_shift = left_watson if left_ovhg < 0 else left_crick
features = self.shifted(initial_shift).features
# for f in features:
# print(f.id, f.location, _location_boundaries(f.location))
# Here, we have done what's shown below (* indicates the origin).
Expand Down
37 changes: 25 additions & 12 deletions src/pydna/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,21 +50,35 @@ def shift_location(original_location, shift, lim):
"""docstring."""
newparts = []
strand = original_location.strand

for part in original_location.parts:
ns = (part.start + shift) % lim
ne = (part.end + shift) % lim or lim
oe = newparts[-1].end if newparts else None
new_start = (part.start + shift) % lim
new_end = (part.end + shift) % lim or lim
old_start, old_end = (newparts[-1].start, newparts[-1].end) if len(newparts) else (None, None)

# The "join with old" cases are for features with multiple parts
# in which consecutive parts do not have any bases between them.
# This type of feature is generated to represent a feature that
# spans the origin of a circular sequence. See more details in
# https://github.com/BjornFJohansson/pydna/issues/195

if len(part) == 0:
newparts.append(_sl(ns, ns, strand))
newparts.append(_sl(new_start, new_start, strand))
continue
elif oe == ns:
# Join with old, case 1
elif strand != -1 and old_end == new_start:
part = newparts.pop()
part._end = new_end
new_start = part.start
# Join with old, case 2
elif strand == -1 and old_start == new_end:
part = newparts.pop()
part._end = ne
ns = part.start
if ns < ne:
newparts.append(_sl(ns, ne, strand))
part._start = new_start
new_end = part.end
if new_start < new_end:
newparts.append(_sl(new_start, new_end, strand))
else:
parttuple = (_sl(ns, lim, strand), _sl(0, ne, strand))
parttuple = (_sl(new_start, lim, strand), _sl(0, new_end, strand))
newparts.extend(parttuple if strand != -1 else parttuple[::-1])
try:
newloc = _cl(newparts)
Expand Down Expand Up @@ -836,8 +850,7 @@ def cuts_overlap(left_cut, right_cut, seq_len):

def location_boundaries(loc: _Union[_sl,_cl]):

#TODO: pending on https://github.com/BjornFJohansson/pydna/pull/179
if loc.strand != 1:
if loc.strand == -1:
return loc.parts[-1].start, loc.parts[0].end
else:
return loc.parts[0].start, loc.parts[-1].end
Expand Down
9 changes: 8 additions & 1 deletion tests/test_module_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,15 @@ def close(self):

def test_shift_location():
from pydna.utils import shift_location
from Bio.SeqFeature import SimpleLocation

# TODO: more tests here

# Shifting of locations should be reversible (https://github.com/BjornFJohansson/pydna/issues/195)
for strand in (1, -1, None):
loc = SimpleLocation(0, 2, strand)
assert shift_location(shift_location(loc, 1, 6), -1, 6) == loc

# Shifting of locations should be reversible


if __name__ == "__main__":
Expand Down

0 comments on commit f99a879

Please sign in to comment.