Skip to content

Commit

Permalink
Merge pull request #630 from UC-Davis-molecular-computing/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
dave-doty authored Jul 31, 2021
2 parents c11212c + 85bac1a commit 6ce1030
Show file tree
Hide file tree
Showing 33 changed files with 236 additions and 175 deletions.
3 changes: 2 additions & 1 deletion lib/src/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import 'state/grid.dart';

// WARNING: Do not modify line below, except for the version string
// (and also add new version string to scadnano_versions_to_link).
const String CURRENT_VERSION = "0.16.1";
const String CURRENT_VERSION = "0.16.2";
const String INITIAL_VERSION = "0.1.0";

// scadnano versions that we deploy so that older versions can be used.
final scadnano_older_versions_to_link =[
"0.16.1",
"0.16.0",
"0.15.3",
"0.15.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ List<RollXY> _calculate_rolls_and_positions(

Geometry geometry = design.geometry;

double z = helices[0].position3d().z;
double y = helices[0].position3d().y;
double z = helices[0].position3d.z;
double y = helices[0].position3d.y;
List<RollXY> rollxys = [RollXY(roll: first_roll, x: z, y: y)];

for (int i = 0; i < addresses.length; i++) {
Expand Down Expand Up @@ -329,7 +329,7 @@ List<actions.UndoableAction> set_rolls_and_positions(List<Helix> helices, List<R
var helix = helices[i];
var rollxy = rolls_and_positions[i];
var roll_action = actions.HelixRollSet(helix_idx: helix.idx, roll: rollxy.roll);
var position = Position3D(x: rollxy.x, y: rollxy.y, z: helix.position3d().z);
var position = Position3D(x: rollxy.x, y: rollxy.y, z: helix.position3d.z);
var pos_action = actions.HelixPositionSet(helix_idx: helix.idx, position: position);
all_actions.add(roll_action);
all_actions.add(pos_action);
Expand Down
8 changes: 4 additions & 4 deletions lib/src/middleware/helix_grid_change.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import '../state/app_state.dart';
// at most one helix (i.e., function mapping real-coordinates to grid-coordinates is 1-1)
helix_grid_offsets_middleware(Store<AppState> store, dynamic action, NextDispatcher next) {
if (action is actions.GridChange &&
!action.grid.is_none() &&
store.state.design.groups[action.group_name].grid.is_none()) {
!action.grid.is_none &&
store.state.design.groups[action.group_name].grid.is_none) {
Geometry geometry = store.state.design.geometry;
Map<int, GridPosition> new_grid_positions_map = {
for (var helix in store.state.design.helices_in_group(action.group_name).values)
Expand All @@ -32,8 +32,8 @@ helix_grid_offsets_middleware(Store<AppState> store, dynamic action, NextDispatc
var gp2 = new_grid_positions_map[h2idx];
if (gp1 == gp2) {
var helices = store.state.design.helices;
var pos1 = helices[h1idx].position3d();
var pos2 = helices[h2idx].position3d();
var pos1 = helices[h1idx].position3d;
var pos2 = helices[h2idx].position3d;
var msg = '''\
This design cannot be automatically converted to the ${action.grid.name} grid.
Two helices, with idx values ${h1idx} and ${h2idx}, have positions that are
Expand Down
2 changes: 1 addition & 1 deletion lib/src/middleware/helix_hide_all.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ helix_hide_all_middleware(Store<AppState> store, dynamic action, NextDispatcher
action is actions.HelixRemove ||
action is actions.LoadDNAFile ||
action is actions.SetAppUIStateStorable) &&
!store.state.has_error()) {
!store.state.has_error) {
var ui_state = store.state.ui_state;
var design = store.state.design;
if (ui_state.only_display_selected_helices &&
Expand Down
27 changes: 19 additions & 8 deletions lib/src/middleware/oxdna_export.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class OxdnaVector {
}

// Constants related to oxdna export
const _GROOVE_GAMMA = 20;
const _GROOVE_GAMMA = 20.0;
const _BASE_DIST = 0.6;
final _OXDNA_ORIGIN = OxdnaVector(0, 0, 0);

Expand All @@ -103,10 +103,10 @@ class OxdnaNucleotide {

OxdnaNucleotide(this.center, this.normal, this.forward, this.base);

OxdnaVector get b => -normal.rotate(-_GROOVE_GAMMA, forward).normalize();

OxdnaVector get r => center - b * _BASE_DIST;

OxdnaVector get b => -normal;

OxdnaVector get n => forward;
}

Expand All @@ -123,7 +123,7 @@ class OxdnaStrand {
class OxdnaSystem {
List<OxdnaStrand> strands = [];

OxdnaVector compute_bounding_box() {
OxdnaVector compute_bounding_box([bool cubic = true]) {
OxdnaVector min_vec = null;
OxdnaVector max_vec = null;

Expand All @@ -142,7 +142,12 @@ class OxdnaSystem {
if (min_vec != null && max_vec != null) {
// 5 is arbitrarily chosen so that the box has a bit of wiggle room
// 1.5 multiplier is to make all crossovers appear (advice from Oxdna authors)
return (max_vec - min_vec + OxdnaVector(5, 5, 5)) * 1.5; // changed
var box = (max_vec - min_vec + OxdnaVector(5, 5, 5)) * 1.5;
if (cubic) { // oxDNA requires cubic bounding box with default simulation options
var max_side = max(box.x, max(box.y, box.z));
box = OxdnaVector(max_side, max_side, max_side);
}
return box;
} else {
return OxdnaVector(1, 1, 1);
}
Expand Down Expand Up @@ -277,7 +282,7 @@ OxdnaSystem convert_design_to_oxdna_system(Design design) {
}
}

// propagate the modifier so it stays consistent accross domains
// propagate the modifier so it stays consistent across domains
for (int idx in design.helices.keys) {
var helix = design.helices[idx];
for (int offset = helix.min_offset + 1; offset < helix.max_offset; offset++) {
Expand Down Expand Up @@ -307,6 +312,10 @@ OxdnaSystem convert_design_to_oxdna_system(Design design) {
seq = seq.split('').reversed.join(''); // reverse DNA sequence
}

// oxDNA will rotate angles by +/- _GROOVE_GAMMA, so we first unrotate by that amount
var groove_gamma_correction = domain.forward ? _GROOVE_GAMMA : -_GROOVE_GAMMA;
normal = normal.rotate(groove_gamma_correction, forward);

// dict / set for insertions / deletions to make lookup easier and cheaper when there are lots of them
var deletions = Set<int>.from(domain.deletions);
Map<int, int> insertions = {};
Expand All @@ -330,15 +339,17 @@ OxdnaSystem convert_design_to_oxdna_system(Design design) {
var r = origin +
forward * (offset + mod - num + i) * geometry.rise_per_base_pair * NM_TO_OX_UNITS;
var b = normal.rotate(step_rot * (offset + mod - num + i), forward);
var nuc = OxdnaNucleotide(r, b, forward, seq[index]);
var n = domain.forward ? -forward : forward;
var nuc = OxdnaNucleotide(r, b, n, seq[index]);
dom_strand.nucleotides.add(nuc);
index += 1;
}
}

var r = origin + forward * (offset + mod) * geometry.rise_per_base_pair * NM_TO_OX_UNITS;
var b = normal.rotate(step_rot * (offset + mod), forward);
var nuc = OxdnaNucleotide(r, b, forward, seq[index]);
var n = domain.forward ? -forward : forward;
var nuc = OxdnaNucleotide(r, b, n, seq[index]);
dom_strand.nucleotides.add(nuc);
index += 1;
}
Expand Down
16 changes: 8 additions & 8 deletions lib/src/reducers/delete_reducer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,34 +21,34 @@ BuiltList<Strand> delete_all_reducer(
}

var select_mode_state = state.ui_state.select_mode_state;
if (select_mode_state.strands_selectable()) {
if (select_mode_state.strands_selectable) {
// strands
var strands_to_remove = Set<Strand>.from(items.where((item) => item is Strand));
strands = _remove_strands(strands, strands_to_remove);
} else if (select_mode_state.linkers_selectable()) {
} else if (select_mode_state.linkers_selectable) {
// crossovers/loopouts
var crossovers = Set<Crossover>.from(items.where((item) => item is Crossover));
var loopouts = Set<Loopout>.from(items.where((item) => item is Loopout));
strands = _remove_crossovers_and_loopouts(strands, state, crossovers, loopouts);
} else if (select_mode_state.ends_selectable()) {
} else if (select_mode_state.ends_selectable) {
// DNA ends
var ends = items.where((item) => item is DNAEnd);
var domains = ends.map((end) => state.design.end_to_domain[end]);
strands = remove_domains(strands, state, domains);
} else if (select_mode_state.domains_selectable()) {
} else if (select_mode_state.domains_selectable) {
// domains
var domains = List<Domain>.from(items.where((item) => item is Domain));
strands = remove_domains(strands, state, domains);
} else if (select_mode_state.deletions_selectable() || select_mode_state.insertions_selectable()) {
} else if (select_mode_state.deletions_selectable || select_mode_state.insertions_selectable) {
// deletions/insertions
List<SelectableDeletion> deletions = select_mode_state.deletions_selectable()
List<SelectableDeletion> deletions = select_mode_state.deletions_selectable
? List<SelectableDeletion>.from(items.where((item) => item is SelectableDeletion))
: [];
List<SelectableInsertion> insertions = select_mode_state.insertions_selectable()
List<SelectableInsertion> insertions = select_mode_state.insertions_selectable
? List<SelectableInsertion>.from(items.where((item) => item is SelectableInsertion))
: [];
strands = remove_deletions_and_insertions(strands, state, deletions, insertions);
} else if (select_mode_state.modifications_selectable()) {
} else if (select_mode_state.modifications_selectable) {
// modifications
var modifications =
List<SelectableModification>.from(items.where((item) => item is SelectableModification));
Expand Down
4 changes: 2 additions & 2 deletions lib/src/reducers/helices_reducer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -463,12 +463,12 @@ BuiltMap<int, Helix> helix_grid_change_reducer(
var helix = helices[idx];
HelixBuilder helix_builder = helix.toBuilder();
helix_builder.grid = action.grid;
if (!action.grid.is_none() && helix.grid_position == null) {
if (!action.grid.is_none && helix.grid_position == null) {
helix_builder.grid_position =
util.position3d_to_grid_position(helix.position, action.grid, geometry).toBuilder();
helix_builder.position_ = null;
}
if (action.grid.is_none() && helix.position_ == null) {
if (action.grid.is_none && helix.position_ == null) {
helix_builder.grid_position = null;
//NOTE: it's important to use helix.grid (i.e., the OLD grid, since util.grid_to_position3d will crash
// if given the none grid)
Expand Down
2 changes: 1 addition & 1 deletion lib/src/reducers/inline_insertions_deletions_reducer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ _inline_deletions_insertions_on_helix(
dels_ins_offsets_sorted.sort();

// fix helix major ticks
List<int> major_ticks = helix.calculate_major_ticks();
List<int> major_ticks = helix.calculate_major_ticks;
major_ticks.sort();

//////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 1 addition & 1 deletion lib/src/reducers/selection_reducer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ BuiltSet<int> helix_selections_adjust_reducer(

select.Box helix_to_box(Helix helix) {
//FIXME: this is making boxes that are not far enough apart
var position3d = helix.position3d();
var position3d = helix.position3d;
num x, y, width, height;
var svg_pos = util.position3d_to_side_view_svg(position3d, helix.invert_xy, helix.geometry);
x = svg_pos.x - helix.geometry.helix_radius_svg;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/state/app_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ abstract class AppState implements Built<AppState, AppStateBuilder> {
return map;
}

bool has_error() => error_message != null && error_message.length > 0;
@memoized
bool get has_error => error_message != null && error_message.length > 0;

/*********************************** begin built_value boilerplate ***********************************/

Expand Down
6 changes: 3 additions & 3 deletions lib/src/state/design.dart
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ abstract class Design with UnusedFields implements Built<Design, DesignBuilder>,
json_map.addAll(unused_fields.toMap());

if (has_default_groups()) {
json_map[constants.grid_key] = default_group().grid.to_json();
json_map[constants.grid_key] = default_group().grid.to_json;
}

if (!this.geometry.is_default()) {
Expand Down Expand Up @@ -1046,7 +1046,7 @@ abstract class Design with UnusedFields implements Built<Design, DesignBuilder>,
group_json[constants.pitch_key] = new_pitch;
group_json[constants.yaw_key] = new_yaw;
group_json[constants.position_key] = group.position.build().to_json_serializable();
group_json[constants.grid_key] = group.grid.to_json();
group_json[constants.grid_key] = group.grid.to_json;
new_groups[new_group_name] =
HelixGroup.from_json(group_json, helix_idxs: helix_list.map((e) => e.idx)).toBuilder();

Expand Down Expand Up @@ -1093,7 +1093,7 @@ abstract class Design with UnusedFields implements Built<Design, DesignBuilder>,
if (position_x_z_should_swap) {
for (var helix_builder in helix_builders_map.values) {
if (grid_is_none && !using_groups ||
using_groups && group_builders_map[helix_builder.group].grid.is_none()) {
using_groups && group_builders_map[helix_builder.group].grid.is_none) {
// prior to version 0.13.0, x and z had the opposite role
num swap = helix_builder.position_.x;
helix_builder.position_.x = helix_builder.position_.z;
Expand Down
15 changes: 8 additions & 7 deletions lib/src/state/domain.dart
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,10 @@ abstract class Domain
int get offset_5p => this.forward ? this.start : this.end - 1;

/// 3' end, INCLUSIVE
@memoized
@memoized
int get offset_3p => this.forward ? this.end - 1 : this.start;

int dna_length() => (this.end - this.start) - this.deletions.length + this.num_insertions();
int dna_length() => (this.end - this.start) - this.deletions.length + this.num_insertions;

/// Number of bases in this [Domain] between [left] and [right] offsets (INCLUSIVE).
int dna_length_in(int left, int right) {
Expand All @@ -338,7 +338,8 @@ abstract class Domain
throw ArgumentError('right = ${right} should be at most end - 1 = ${end - 1}');
}
int num_deletions = deletions.where((d) => left <= d && d <= right).length;
int num_insertions = insertions.where((i) => left <= i.offset && i.offset <= right).length;
var list_of_insertions = insertions.where((i) => left <= i.offset && i.offset <= right);
int num_insertions = num_insertions_in_list(list_of_insertions);
return (right - left + 1) - num_deletions + num_insertions;
}

Expand Down Expand Up @@ -371,7 +372,8 @@ abstract class Domain
}

/// List of offsets (inclusive at each end) in 5' - 3' order.
List<int> offsets_in_5p_3p_order() {
@memoized
List<int> get offsets_in_5p_3p_order {
List<int> offsets = [];
if (this.forward) {
for (int offset = this.start; offset < this.end; offset++) {
Expand Down Expand Up @@ -508,9 +510,8 @@ abstract class Domain
(!this.forward && offset_edge < offset_to_test && offset_to_test < this.end);
}

int num_insertions() {
return num_insertions_in_list(insertions);
}
@memoized
int get num_insertions => num_insertions_in_list(insertions);

static int num_insertions_in_list(Iterable<Insertion> insertions) {
int num = 0;
Expand Down
9 changes: 6 additions & 3 deletions lib/src/state/grid.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ class Grid extends EnumClass {

static Grid valueOf(String name) => _$valueOf(name);

String to_json() => name;
@memoized
String get to_json => name;

bool is_none() => this == none;
@memoized
bool get is_none => this == none;

static Serializer<Grid> get serializer => _$gridSerializer;

int default_major_tick_distance() {
@memoized
int get default_major_tick_distance {
if (this == Grid.hex || this == Grid.honeycomb) {
return 7;
} else if (this == Grid.square) {
Expand Down
Loading

0 comments on commit 6ce1030

Please sign in to comment.