Scripting¶
Cadnano2.5 can be invoked from a Python3 script. Manipulating the cadnano
data model without invoking the GUI window can be useful for automating
certain tasks that are tedious with the mouse and keyboard. After importing the
cadnano package with import cadnano
and initializing a Document, it is
straightforward to make API calls via object references to the document, part,
oligos, strands, and so on.
Note
The code block line numbers do not line up due to a bug (#415) with the readthedocs theme. It is fixed in the beta (0.2.5b2) but may not be reflected here yet.
Basic concepts¶
Here is a simple example, which can be found in misc/examples along with other scripts. It reads an input file and prints some information.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #!/usr/bin/env python3
# bare_bones_example.py
# Shawn M Douglas, April 2017
# BSD-3 open-source license
import cadnano
from cadnano.document import Document
app = cadnano.app()
doc = app.document = Document()
doc.readFile('myfile.json')
part = doc.activePart()
oligos = part.oligos()
for oligo in oligos:
print("{0}\t{1}\t\'{2}\'\t{3}".format(oligo,
oligo.length(),
oligo.getColor(),
oligo.sequence()))
vhs = list(part.getIdNums()) # convert set to list
for vh_id in vhs[:3]: # display first 3 vhs
fwd_ss, rev_ss = part.getStrandSets(vh_id)
print('VH{0}'.format(vh_id))
print('\t', fwd_ss, '\t', [s.idxs() for s in fwd_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in fwd_ss.strands()])
print('\t', rev_ss, '\t', [s.idxs() for s in rev_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in rev_ss.strands()])
|
Let’s go line-by-line:
1 | #!/usr/bin/env python3
|
Make sure you are using the python3 interpreter, not python2.
6 7 | import cadnano
from cadnano.document import Document
|
The cadnano package must be imported to make use of its functions. If the import
fails with the python3 interpreter, try calling pip3 list
from the terminal
and check that cadnano and PyQt5 are both installed. If PyQt5 is installed, you
should also be able to cleanly import PyQt5
without any exception. The
submodule document contains the class Document, which we will use as well.
9 | app = cadnano.app()
|
Here we create a cadnano application object, and store a reference. See cadnano.app and cadnano.__init__.py in the source.
10 11 | doc = app.document = Document()
doc.readFile('myfile.json')
|
Create a new Document instance, assign it to the app.document
variable, as well as doc
variable in the local scope. The
Document class is the root of the model. It is the parent of all
parts and maintains the undo stack.
12 | part = doc.activePart()
|
The Part class corresponds to a molecular nanostructure. NucleicAcidPart subclasses Part, and corresponds to a DNA origami design. At the lowest level, origami designs are comprised of Strand objects, which are contiguous segments of ssDNA between endpoints and/or crossovers. Parts keep track of Strands in two separate classes simultaneously: Oligo and VirtualHelix.
We can finally start doing useful maniupulations at the oligo level. Before we examine the output, let’s take a look at the input file in the GUI.
Oligos correspond to a full-length physical oligonucleotide (i.e. a “staple” or “scaffold”).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #!/usr/bin/env python3
# bare_bones_example.py
# Shawn M Douglas, April 2017
# BSD-3 open-source license
import cadnano
from cadnano.document import Document
app = cadnano.app()
doc = app.document = Document()
doc.readFile('myfile.json')
part = doc.activePart()
oligos = part.oligos()
for oligo in oligos:
print("{0}\t{1}\t\'{2}\'\t{3}".format(oligo,
oligo.length(),
oligo.getColor(),
oligo.sequence()))
vhs = list(part.getIdNums()) # convert set to list
for vh_id in vhs[:3]: # display first 3 vhs
fwd_ss, rev_ss = part.getStrandSets(vh_id)
print('VH{0}'.format(vh_id))
print('\t', fwd_ss, '\t', [s.idxs() for s in fwd_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in fwd_ss.strands()])
print('\t', rev_ss, '\t', [s.idxs() for s in rev_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in rev_ss.strands()])
|
We can iterate over the Part’s oligos and print their repr, length, color, and sequence (which should be none since we haven’t applied anything yet.) Now let’s look at the output of lines 15–19.
<Oligo 3688>(10[53]) 24 '#f74308' None
<Oligo 1064>(7[2]) 21 '#57bb00' None
<Oligo 6560>(17[5]) 74 '#57bb00' None
<Oligo 5224>(14[57]) 18 '#57bb00' None
<Oligo 1344>(6[53]) 276 '#03b6a2' None
<Oligo 1416>(13[5]) 74 '#007200' None
<Oligo 7064>(5[21]) 42 '#0066cc' None
<Oligo 1928>(8[53]) 24 '#f7931e' None
<Oligo 1368>(11[2]) 21 '#57bb00' None
<Oligo 1544>(4[57]) 18 '#57bb00' None
<Oligo 6928>(15[5]) 74 '#57bb00' None
<Oligo 7648>(2[57]) 18 '#57bb00' None
<Oligo 8720>(5[5]) 21 '#aaaa00' None
<Oligo 3216>(0[57]) 60 '#1700de' None
<Oligo 3360>(1[5]) 21 '#57bb00' None
<Oligo 3176>(16[57]) 18 '#57bb00' None
<Oligo 5672>(0[21]) 948 '#0066cc' None
<Oligo 4304>(13[21]) 42 '#0066cc' None
<Oligo 3416>(9[2]) 21 '#b8056c' None
<Oligo 4808>(12[57]) 60 '#cc0000' None
<Oligo 9808>(3[5]) 21 '#57bb00' None
The VirtualHelix (VH) is a group of Strands that share the same double-helix axis in space. VHs each contain a “forward” and “reverse” StrandSet, which is a container class for a group of Strands along the same helix axis.
21 22 23 24 25 26 27 28 | vhs = list(part.getIdNums()) # convert set to list
for vh_id in vhs[:3]: # display first 3 vhs
fwd_ss, rev_ss = part.getStrandSets(vh_id)
print('VH{0}'.format(vh_id))
print('\t', fwd_ss, '\t', [s.idxs() for s in fwd_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in fwd_ss.strands()])
print('\t', rev_ss, '\t', [s.idxs() for s in rev_ss.strands()], '\n\t\t\t\t',
[s.getColor() for s in rev_ss.strands()])
|
Here we use Part.getStrandSets()
to get references to both the fwd and rev
StrandSets, and use list concatenations to print the start and end indices via Strand.idxs()
,
and color via Strand.getColor()
.
VH0
<fwd_StrandSet(0)> [(5, 20), (21, 57)]
['#0066cc', '#0066cc']
<rev_StrandSet(0)> [(5, 20), (21, 41), (42, 57)]
['#007200', '#03b6a2', '#1700de']
VH1
<fwd_StrandSet(1)> [(5, 13), (14, 20), (21, 34), (35, 41), (42, 48), (49, 57)]
['#57bb00', '#007200', '#03b6a2', '#03b6a2', '#1700de', '#57bb00']
<rev_StrandSet(1)> [(5, 32), (33, 57)]
['#0066cc', '#0066cc']
VH2
<fwd_StrandSet(2)> [(5, 32), (33, 57)]
['#0066cc', '#0066cc']
<rev_StrandSet(2)> [(5, 20), (21, 41), (42, 48), (49, 57)]
['#57bb00', '#03b6a2', '#1700de', '#57bb00']
Apply scaffold sequence¶
TK
Modify oligo sequences by color¶
TK
Export to legacy format¶
TK