Skip to content

Commit 19975dd

Browse files
committed
added unit test for internal modification that goes between bases
1 parent 91936b2 commit 19975dd

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

scadnano/scadnano.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,11 +1123,17 @@ class ModificationInternal(Modification):
11231123
"""Internal modification of DNA sequence, e.g., biotin or Cy3."""
11241124

11251125
allowed_bases: Optional[AbstractSet[str]] = None
1126-
"""If None, then this is an internal modification that goes between bases.
1126+
"""
1127+
If None, then this is an internal modification that goes between bases.
1128+
In this case, the key :data:`Strand.modifications_int` specifying the position of the internal
1129+
modification is interpreted to mean that the modification goes *after* the base at that position.
1130+
(For example, this is the parameter `idx` in :meth:`StrandBuilder.with_modification_internal`.)
1131+
11271132
If instead it is a list of bases, then this is an internal modification that attaches to a base,
11281133
and this lists the allowed bases for this internal modification to be placed at.
11291134
For example, internal biotins for IDT must be at a T. If any base is allowed, it should be
1130-
``{'A','C','G','T'}``."""
1135+
``{'A','C','G','T'}``.
1136+
"""
11311137

11321138
def __post_init__(self) -> None:
11331139
super().__post_init__()

tests/scadnano_tests.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,29 @@ def test_domain_delimiters_modifications(self) -> None:
11361136
self.assertEqual(f'{strand_name};/5Biosg/ AAAAA CCCC/iBiodT/ GGGGG /3Cy3Sp/;25nm;STD',
11371137
idt_content)
11381138

1139+
def test_domain_delimiters_internal_nonbase_modifications(self) -> None:
1140+
strand_name = 's1'
1141+
mod_i = sc.ModificationInternal(display_text='9C', idt_text='/iSp9/')
1142+
1143+
helices = [sc.Helix(max_offset=100) for _ in range(6)]
1144+
design = sc.Design(helices=helices, strands=[], grid=sc.square)
1145+
1146+
(design.draw_strand(0, 0)
1147+
.move(5).with_domain_sequence('AAAAA')
1148+
.cross(1).move(-5).with_domain_sequence('CCCCT')
1149+
.cross(2).move(5).with_domain_sequence('GGGGG')
1150+
.with_name(strand_name)
1151+
.with_modification_internal(8, mod_i)
1152+
)
1153+
1154+
strand = design.strands[0]
1155+
strand_idt_dna_sequence = strand.idt_dna_sequence(domain_delimiter=' ')
1156+
self.assertEqual('AAAAA CCCC/iSp9/T GGGGG', strand_idt_dna_sequence)
1157+
1158+
idt_content = design.to_idt_bulk_input_format(delimiter=';', domain_delimiter=' ')
1159+
self.assertEqual(f'{strand_name};AAAAA CCCC/iSp9/T GGGGG;25nm;STD',
1160+
idt_content)
1161+
11391162
def test_to_idt_bulk_input_format__row_major_5p(self) -> None:
11401163
key = sc.strand_order_key_function(column_major=False, strand_order=sc.StrandOrder.five_prime)
11411164
names_joined = self._get_names_idt(self.design_6h, key)

0 commit comments

Comments
 (0)