Skip to content

Releases: UC-Davis-molecular-computing/scadnano-python-package

v 0.20.1

15 Jul 16:14
90e9e75

Choose a tag to compare

Added back wc (deprecated) so as not to break existing scripts.

Commits

v0.20.0

25 Mar 21:30
f5f14c1

Choose a tag to compare

Release notes

BREAKING CHANGE: Minimum Python version is 3.9

The minimum Python version has been changed to 3.9. Technically there is not yet any part of the scadnano package that actually depends on 3.9 features; mainly this is done because support is being dropped for older Python versions in other tools, for example the unit tests that are run whenever we update the github repo no longer support older Python versions.

As of version 0.20.0, you can still install scadnano with Python version 3.7 or 3.8 by using the option --ignore-requires-python with pip: pip install scadnano --ignore-requires-python https://stackoverflow.com/questions/75726452/can-i-force-the-install-of-a-package-that-requires-a-newer-python-version-than-t However, future versions of scadnano may use newer features of Python, so it is advisable to upgrade to the latest Python version now for maximum future compatibility.

BREAKING CHANGE: parameter only_strands_with_idt changed to only_strands_with_vendor_fields

Version 0.19.0 changed some names of fields and classes from IDT-specific names to the more generic "vendor fields". However, the parameter only_strands_with_idt in a few methods was not at that time changed to only_strands_with_vendor_fields; now that parameter name has been changed as well in version 0.20.0.

HelixGroups custom geometry

See also UC-Davis-molecular-computing/scadnano#993 (comment).

There is a new optional field HelixGroup.geometry, which overrides the Geometry parameters of the Design.geometry field. For instance, the following code:

import scadnano as sc


def create_design() -> sc.Design:
    group0 = sc.HelixGroup(grid=sc.square)
    group1 = sc.HelixGroup(grid=sc.square, 
                           # NOTE: here's the custom geometry for helix 1
                           geometry=sc.Geometry(bases_per_turn=18),
                           position=sc.Position3D(0, 3, 0))
    groups = {"group 0": group0, "group 1": group1}
    helices = [sc.Helix(idx=idx, max_offset=40, group=group) for idx, group in
               [(0, "group 0"), (1, "group 1")]]
    design = sc.Design(helices=helices, groups=groups, strands=[])
    design.draw_strand(0, 0).move(40)
    design.draw_strand(0, 40).move(-40)
    design.draw_strand(1, 0).move(40)
    design.draw_strand(1, 40).move(-40)

    return design


if __name__ == '__main__':
    d = create_design()
    d.write_scadnano_file(directory='output_designs')

produces this design with helix 0 having 10.5 base pairs per turn, and helix 1 having 18 base pairs per turn:

image

Commits

  • 3600d1a: changed idt references to vendor_fields (David Doty) #313
  • e8905fa: fixes #304: Typo in set_dna_sequence comment (David Doty) #313
  • d9cd906: closes #306: allow per-helix-group geometry (David Doty) #307
  • c597888: removed xlwt from environment.yml (David Doty) #307
  • d6a52bd: Update run_unit_tests.yml (David Doty) #307
  • efce159: fixed group-specific geometry in oxdna/oxview export (David Doty) #313
  • 0c435bf: Update scadnano.py (David Doty) #313
  • 2795055: fixed issue 309 by rotating helix position by group's orientation before adding to helix group's offset (DanielHader) #312
  • cf75e42: Update scadnano.py (David Doty) #312
  • b7afcd2: removed assignment of None to Design.helices and Design.groups since constructor sets them anyway (David Doty) #313
  • abc8435: made StrandBuilder a dataclass and added documentation for fields (David Doty) #313
  • c4f64ba: bumped minimum Python version to 3.9 and bumped version to 0.20.0 (David Doty) #313

v0.19.4

28 Mar 22:15
78fcc89

Choose a tag to compare

Release notes

Changed type of Design.to_oxview_format from dict to str to keep convention with similar other methods such as Design.to_oxdna_format.

This is a breaking change, although the minor version number did not change. The method Design.to_oxview_json has the same functionality that Design.to_oxview_format, namely that it returns a JSON-serializable dict. Calling json.dumps on this dict produces the same output as Design.to_oxview_format.

v0.19.3

28 Mar 21:43
710410b

Choose a tag to compare

Release notes

Mostly fixes this bug with oxView export: #297.

We jumped straight from v0.19.0 to v0.19.3 due to some testing that happened in the dev branch.

Commits

  • a78b395: bumped version (David Doty) #299
  • 5cf25e3: changed parameter type of Strand.set_domains to allow Extension's (David Doty) #299
  • 1128beb: added the required build section (RayBipse) #292
  • dcede52: Removed python.version (RayBipse) #293
  • 3d20590: Removed python.version and added back tools.python (RayBipse) #294
  • 4380042: Changed to use mamba and added python version requirement to environment.yml (RayBipse) #295
  • 21aa34a: Added pip packages used to environment.yml (RayBipse) #296
  • e5572ad: fixes #297: fix oxView export exception on Loopouts (David Doty) #298
  • a220c32: Update scadnano.py (David Doty) #299

v0.19.0

07 Sep 00:34
f415a47

Choose a tag to compare

Release notes

BREAKING CHANGE: Renamed IDT-specific fields

Some names related to the DNA synthesis company IDT have been renamed to be more general. You will have to rename these in your own code for it to run:

  • class IDTFields --> VendorFields
  • field Modification.idt_text --> Modification.vendor_code
  • field Strand.idt --> Strand.vendor_fields

Additionally, some keys in the JSON format for .sc files have changed as well. Scadnano (both the web interface and the Python package) should be able to read files with the old keys and convert them to the new keys upon saving. However, if you are manually editing the .sc file then use the new keys.

Some IDT-specific methods remain, such as Design.write_idt_plate_excel_file. These use the values in Strand.vendor_fields and Modification.vendor_code, but since the file format actually is specific to IDT, the method name is unchanged.

Although currently there are no methods for exporting to file formats recognized by other synthesis companies, in the meantime it should be straightforward to use the values in VendorFields to write custom code for such exports.

Field Modification.id removed

Previously, scadnano used Modification.id as a unique identifier for modifications.

The field id has been removed. Now, the field vendor_code is used as a unique identifier for the modification, where id was previously used.

Previously, if no id was specified, but vendor_code/idt_text was, then id was set to the latter. Such code should continue to work unmodified. But code referencing id should now refer to vendor_code instead. Additionally, if a script used the same vendor_code for different Modifications, then this will break. Each Modification should now have a unique vendor_code field.

Note that some vendors such as Eurofins use the same code for 5'/3' modifications (see issue #283). For this reason, the modifications internally are stored in a way that encodes their location (5', 3', internal). But for any two modifications of the same "location" (both 5' modifications, both 3' modifications, or both internal modifications) the vendor_code must be unique to the type of modification.

Commits

v0.18.3

26 Aug 04:48
976ee4d

Choose a tag to compare

Release notes

Custom delimiter between DNA sequences of domains

A custom delimiter string to go in between DNA sequences of different domains on a strand can be specified, e.g., a space (which is ignored by IDT), so that the exported IDT sequences might look like this for a 3-domain strand:

ST0[8]0[15];/5Biosg/ ACGTCGT ACGTC ACGTAC;25nm;STD

See

https://scadnano-python-package.readthedocs.io/en/latest/#scadnano.Strand.vendor_dna_sequence
https://scadnano-python-package.readthedocs.io/en/latest/#scadnano.Design.to_idt_bulk_input_format
https://scadnano-python-package.readthedocs.io/en/latest/#scadnano.Design.write_idt_bulk_input_file

Commits

  • 301edc4: bumped version (David Doty) #278
  • 315c0f3: fixes #276: customize delimiter between domains in exported DNA sequences (David Doty) #277
  • 5d8b61d: updated unit test to test for non-default delimiter (David Doty) #277
  • 96b5e0d: removed delimiters between internal modifications and rest of sequence (David Doty) #277
  • 93431b4: Update scadnano.py (David Doty) #277
  • 19975dd: added unit test for internal modification that goes between bases (David Doty) #278

v0.18.2

24 Aug 15:07
c274ec0

Choose a tag to compare

Bug fixes related to relaxing helix rolls.

Commits

  • 8165951: bumped version (David Doty) #275
  • 3f5bb6e: fixed one unit test (David Doty) #275
  • a37b35a: Update scadnano.py (David Doty) #275
  • 0837366: Update scadnano.py (David Doty) #275
  • caf20e1: fixed bug in calculating minimum strain angle for helices with no crossovers (David Doty) #275
  • e832e53: Update scadnano_tests.py (David Doty) #275
  • 25fa92f: fixes #268: ignore loopouts when relaxing Helix rolls (David Doty) #269
  • 9ea350b: fixed bug with relaxing roll starting from non-0 roll (David Doty) #275
  • 7d938b5: cleaned up unit test (David Doty) #275
  • 15c1514: Update scadnano.py (David Doty) #275
  • 770366a: fixes #270: ignore "same helix" crossovers when relaxing helix rolls; also ensures domains on helix are stored in increasing order of start offsets (David Doty) #272
  • 888565c: added new example (David Doty) #272
  • 832c503: Update scadnano_tests.py (David Doty) #275
  • d84419f: added unit test for relaxing helix rolls with intrahelix crossovers and fixed bug in relax code that didn't account for that case (David Doty) #275
  • d3a6d7d: change parameter name (David Doty) #275
  • a2d4e52: fixes #273: deal with inter-group crossovers when relaxing helix rolls (David Doty) #274
  • 27568e4: Update scadnano_tests.py (David Doty) #275
  • 1dedd8b: fixed relax helix rolls to ignore intergroup crossovers (David Doty) #275
  • 51fbc9c: Update tutorial.md (David Doty) #275
  • 5189e8d: Update scadnano.py (David Doty) #275

v0.18.1

16 Aug 22:15
186a488

Choose a tag to compare

Release notes

automatically set Helix rolls based on crossover locations ("relax" the rolls)

In this design, the crossovers are well placed relative to each other, but the helix rolls need to be rotated. As the slice bar shows, with the default roll of 0, the crossovers do not point at the helices they connect to:

image

image

By calling Design.relax_helix_rolls, the helix rolls are set to minimize "strain" in the crossovers:

image

image

Formally, the strain is defined as the square of the angular distance between the "ideal" angle for the crossover (i.e., the relative angle of the other helix to which it is connecting) and the crossover's current angle. The roll is set so as to minimize this total strain across all crossovers in each helix.

The reason to minimize the sum of the squared angular distances is that, if we model each crossover as an angular spring exerting a rotational force on the helix proportional to its displacement from the "ideal" angle (pointing directly at the other helix), this minimizes the total energy stored in the springs.

Commits

  • 2b11342: bumped version (David Doty) #267
  • 49867e3: Merge branch 'dev' into 257-automatically-set-helix-rolls-based-on-crossover-locations-relax-the-rolls (David Doty) #264
  • 123e001: closes #257: automatically set Helix rolls based on crossover locations (relax the rolls) (David Doty) #264
  • 5208be3: fixed some unit tests (David Doty) #264
  • c370a1f: Update scadnano.py (David Doty) #264
  • c26dbe6: fixed dependencies (David Doty) #266
  • 62c5dd5: changed unit test versions for openpyxl and tabulate to versions matching what is in Anaconda package repository (David Doty) #266
  • 7b963c5: added instructions for installing openpyxl and tabulate to README (David Doty) #266
  • f45d3f0: fixes #234: export new Excel format (David Doty) #266
  • 3da4763: added openpyxl to tests_require (David Doty) #266
  • c177ef0: added openpyxl installation to docs-check GitHub action (David Doty) #266
  • 50899e3: Merge branch 'dev' into 257-automatically-set-helix-rolls-based-on-crossover-locations-relax-the-rolls (David Doty) #264

v0.18.0

22 Jul 16:10
4d0c152

Choose a tag to compare

Release notes

BREAKING CHANGE: label type is now str

Strands, domains, loopouts, and extensions have a field label. Previously the declared type was arbitrary, though at runtime it was required to be JSON-serializable.

Now we have changed the type of label field in Strand, Domain, Loopout, and Extension to str instead of an arbitrary object.

This is a breaking change because existing code using non-string labels will have to be altered to change the data to a string before storing and change it back to structured data when reading.

If you would like to store "structured data" (e.g., lists or dicts) in the label, you can serialize to a string and deserialize back to structured data manually using the json package.

Before, this was possible:

from typing import List

# previously was possible, now is not supported
nums = [1, 2, 3]
strand.label = nums   # stores strand.label as the list [1, 2, 3]; would be a mypy type error now

# and to get the structured data back out:
nums: List[int] = strand.label  # would be a mypy type error now

Now this is necessary to store a list of int's in the label:

import json
from typing import List

nums = [1, 2, 3]
strand.label = json.dumps(nums)  # stores strand.label as the string '[1, 2, 3]'

# and to get the structured data back out:
nums: List[int] = json.loads(strand.label)  # nums is now the list [1, 2, 3]

added p8634 variant of M13

There is a variant of M13 mentioned in a few papers (e.g., https://doi.org/10.1038/s41565-022-01283-1) called "p8634". It can be obtained from Tilibit (though not listed on their website). This sequence is now available as a predefined sequence. See https://scadnano-python-package.readthedocs.io/en/latest/#scadnano.M13Variant.p8634

Commits

  • d955eda: bumped version (David Doty) #258
  • 2f58b2b: updated docstrings (David Doty) #258
  • 0a482a7: Update scadnano.py (David Doty) #258
  • c55411e: Update scadnano.py (David Doty) #258
  • fca673a: added test generated by GitHub Copilot (David Doty) #258
  • 3e84a38: changed docstring for Design.base_pairs (David Doty) #258
  • fc2176b: added examples (David Doty) #258
  • 7b0603b: changed to LR newlines (David Doty) #258
  • 01c43e3: added p8634 variant of M13 (David Doty) #258
  • 0678d55: formatting (David Doty) #258
  • e8211db: fixed PyCharm warnings (David Doty) #258
  • 602575d: closes #261: change label type to str (David Doty) #262
  • a292757: removed all string type hints and replaced with forward references (not supported in Python 3.6) (David Doty) #262

v0.17.7

04 Dec 16:45
13d4e0e

Choose a tag to compare

Release notes

new method Design.base_pairs()

This method returns a dict mapping helix idx's where base pairs exist to a list of offsets where those base pairs are.

Domain/Extension/Loopout colors

Individual Domain's, Extension's, and Loopout's now have a color field. If specified, then this overrides the field Strand.color when displayed in the web interface. There is also a new method StrandBuilder.with_domain_color():

helices = [sc.Helix(max_offset=100) for _ in range(4)]
design = sc.Design(helices=helices, grid=sc.square)

red = sc.Color(255, 0, 0)
dark_red = sc.Color(150, 0, 0)
green = sc.Color(0, 255, 0)
dark_green = sc.Color(0, 150, 0)
blue = sc.Color(0, 0, 255)
dark_blue = sc.Color(0, 0, 150)
black = sc.Color(0, 0, 0)

design.draw_strand(0, 0) \
    .extension_5p(num_bases=5).with_domain_color(red) \
    .move(8).with_domain_color(green) \
    .loopout(1, 5).with_domain_color(dark_blue) \
    .move(-8).with_domain_color(dark_red) \
    .cross(2) \
    .move(8).with_domain_color(dark_green) \
    .cross(3) \
    .move(-8) \
    .extension_3p(num_bases=5).with_domain_color(black) \
    .with_color(blue)

image

Commits

  • 5586c9f: bumped version (David Doty) #256
  • 6463865: closes #252: add method Design.base_pairs() (David Doty) #254
  • fec6f43: changed return type of Design.base_pairs() to dict and added allow_mismatches parameter (David Doty) #254
  • e795627: fixed unit tests after updating with_sequence and with_domain_sequence to default to not assigning complement (David Doty) #254
  • 6b6001a: removed unused _popleft() function (David Doty) #254
  • e55609d: Update scadnano.py (David Doty) #256
  • afc44b8: don't put Helix idx in base_pairs dict if Helix has no base pairs (David Doty) #256
  • 1049cdc: fixed base pair calculation to allow for deletions/insertions/wildcards/None if DNA sequence is not assigned (David Doty) #256
  • e6c0737: added unit test for no base pairs (David Doty) #256
  • f81b8ff: Update scadnano_tests.py (David Doty) #256
  • 7b83a43: fixed bug in Design.base_pairs() when no reverse domains on helix (David Doty) #256
  • 5312a59: Update scadnano_tests.py (David Doty) #256
  • 1b7e605: closes #238: Domain colors (David Doty) #255
  • fea3b32: added example with domain colors (David Doty) #256