From cf6902c10fdf056bd0a2ece23b1dc0d0563c9c51 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 4 Sep 2024 17:11:40 -0700 Subject: [PATCH 1/4] Apt Buildpack --- Aptfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Aptfile b/Aptfile index cadb276..fdd151b 100644 --- a/Aptfile +++ b/Aptfile @@ -1 +1 @@ -coinor-libcbc-dev \ No newline at end of file +coinor-libcbc-dev From 4467d5d18ee5e997ccb61d0988f073eae150e216 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 4 Sep 2024 17:28:04 -0700 Subject: [PATCH 2/4] Add cbc wrapper / path configuration --- Gemfile | 1 + Gemfile.lock | 1 + 2 files changed, 2 insertions(+) diff --git a/Gemfile b/Gemfile index 88f43f7..0259818 100644 --- a/Gemfile +++ b/Gemfile @@ -52,6 +52,7 @@ gem 'spicy-proton' gem 'delaunator' gem 'oink' gem 'ruby-cbc', require: false +gem 'cbc-wrapper' gem 'unicorn' # gem 'rack-timeout' group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 8df2918..e8d44db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -489,6 +489,7 @@ DEPENDENCIES byebug capistrano capybara (>= 3.26) + cbc-wrapper cucumber-rails database_cleaner delaunator From 77671e36e1bd027825c73dbaf6e104265748cea5 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 4 Sep 2024 17:37:13 -0700 Subject: [PATCH 3/4] Downgrade cbc-wrapper --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 0259818..f7e7d4b 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,7 @@ gem 'spicy-proton' gem 'delaunator' gem 'oink' gem 'ruby-cbc', require: false -gem 'cbc-wrapper' +gem 'cbc-wrapper', '2.9.9.3' gem 'unicorn' # gem 'rack-timeout' group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index e8d44db..e224fc7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -109,7 +109,7 @@ GEM rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - cbc-wrapper (2.9.9.5) + cbc-wrapper (2.9.9.3) childprocess (4.1.0) coderay (1.1.3) concurrent-ruby (1.1.10) @@ -489,7 +489,7 @@ DEPENDENCIES byebug capistrano capybara (>= 3.26) - cbc-wrapper + cbc-wrapper (= 2.9.9.3) cucumber-rails database_cleaner delaunator From 438c3ee7380fee49ddbf0897df71e90b23b107ca Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 2 Oct 2024 13:17:30 -0700 Subject: [PATCH 4/4] Combined directional change --- Aptfile | 2 +- Gemfile | 1 - Gemfile.lock | 1 - app/models/oxdna_maker.rb | 130 +++++++++++++++++++++++--------------- 4 files changed, 80 insertions(+), 54 deletions(-) diff --git a/Aptfile b/Aptfile index fdd151b..8b13789 100644 --- a/Aptfile +++ b/Aptfile @@ -1 +1 @@ -coinor-libcbc-dev + diff --git a/Gemfile b/Gemfile index f7e7d4b..88f43f7 100644 --- a/Gemfile +++ b/Gemfile @@ -52,7 +52,6 @@ gem 'spicy-proton' gem 'delaunator' gem 'oink' gem 'ruby-cbc', require: false -gem 'cbc-wrapper', '2.9.9.3' gem 'unicorn' # gem 'rack-timeout' group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index e224fc7..94f2f98 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -489,7 +489,6 @@ DEPENDENCIES byebug capistrano capybara (>= 3.26) - cbc-wrapper (= 2.9.9.3) cucumber-rails database_cleaner delaunator diff --git a/app/models/oxdna_maker.rb b/app/models/oxdna_maker.rb index bb4a6c3..ef23f82 100644 --- a/app/models/oxdna_maker.rb +++ b/app/models/oxdna_maker.rb @@ -25,11 +25,12 @@ def setup(positions, staples_idxs, staples_points) r_Y = rotation_matrix(dir_Y, [1, 'bp']) r_Z = rotation_matrix(dir_Z, [1, 'bp']) r0 = Matrix.identity(3) - - dir_axis, largest_delta_idx = directional_change_axis(positions[1], positions[0]) + + combined_result = combined_directional_change(positions[1], positions[0]) + dir_axis, largest_delta_idx = combined_result[1] dir_axis_prv = dir_axis largest_delta_prv_idx = largest_delta_idx - dir_ch, dir_vec = directional_change(positions[1], positions[0]) + dir_ch, dir_vec = combined_result[0] dir_ch_prv = dir_ch a3 = dir_vec <= 0 ? binding.local_variable_get("dir_#{dir_ch}") : -binding.local_variable_get("dir_#{dir_ch}") @@ -46,13 +47,16 @@ def setup(positions, staples_idxs, staples_points) current_prime_dir = :X prev_prime_dir = :X positions.each_with_index do |pos, idx| - dir_axis, largest_delta_idx = directional_change_axis(positions[idx], positions[idx - 1]) unless idx < 1 + unless idx < 1 + combined_result = combined_directional_change(positions[idx], positions[idx - 1]) + dir_axis, largest_delta_idx = combined_result[1] + end unless idx < 2 - dir_axis_prv, largest_delta_prv_idx = directional_change_axis(positions[idx - 1], - positions[idx - 2]) + combined_result = combined_directional_change(positions[idx - 1], positions[idx - 2]) + dir_axis_prv, largest_delta_prv_idx = combined_result[1] end - dir_ch_prv, = directional_change(positions[idx - 1], positions[idx - 2]) if idx != 0 - dir_ch, dir_vec = directional_change(positions[idx], positions[idx - 1]) if idx != 0 + dir_ch_prv, = combined_directional_change(positions[idx - 1], positions[idx - 2])[0] if idx != 0 + dir_ch, dir_vec = combined_directional_change(positions[idx], positions[idx - 1])[0] if idx != 0 if idx != 0 curr_R = Matrix.identity(3) @@ -64,7 +68,7 @@ def setup(positions, staples_idxs, staples_points) euler_angles = sub_vec.euler_angles a3 = Vector[0, 0, 0] dir_axis.each_with_index do |ax, i| - a3 += binding.local_variable_get("dir_#{ax[0]}") * ax[1] + a3 += binding.local_variable_get("dir_#{ax[0]}") * ax[1] # Makes it not orthogonal end a3 = a3.normalize @@ -90,7 +94,7 @@ def setup(positions, staples_idxs, staples_points) end position = (rb - CM_CENTER_DS * a1) - a1 = curr_R * a1 + a1 = curr_R * a1 # This line makes it not orthogonal a1 = a1.normalize rb += a3 * BASE_BASE a1_d = -a1 @@ -249,6 +253,26 @@ def setup(positions, staples_idxs, staples_points) [scaffold_positions, scaffold_a1s, scaffold_a3s, staples_positions, staples_a1s, staples_a3s] end + def orthogonalize(v1, v2) + u1 = v1.normalize + u2 = v2 - u1 * u1.inner_product(v2) + u2 = u2.normalize + [u1, u2] + end + + def orthogonal?(vector1, vector2, tolerance = 1e-5) + vector1.inner_product(vector2).abs < tolerance + end + + def angle_between(vector1, vector2) + dot_product = vector1.inner_product(vector2) + magnitude_product = vector1.magnitude * vector2.magnitude + return 0 if magnitude_product == 0 + cos_theta = dot_product / magnitude_product + cos_theta = [[cos_theta, 1].min, -1].max + (Math.acos(cos_theta) * (180 / Math::PI)).round(2) + end + def orthogonal_dimension(v1, v2, shape, dimensions) Plane.orthogonal_dimension(Vertex.new(v1[0], v1[1], v1[2]), Vertex.new(v2[0], v2[1], v2[2]), shape, dimensions) end @@ -283,51 +307,55 @@ def rotation_matrix(axis, angles) [olc * x * z - st * y, olc * y * z + st * x, olc * z * z + ct]] end - def directional_change(v1, v2) - max_of = 0 + def combined_directional_change(v1, v2) + max_of = 0 + max_dir = :X + dir = 0 + + if (v1[0] - v2[0]).abs > max_of + max_of = (v1[0] - v2[0]).abs max_dir = :X - dir = 0 - - if (v1[0] - v2[0]).abs > max_of - max_of = (v1[0] - v2[0]).abs - max_dir = :X - dir = v1[0] - v2[0] - elsif (v1[1] - v2[1]).abs > max_of - max_of = (v1[1] - v2[1]).abs - max_dir = :Y - dir = v1[1] - v2[1] - elsif (v1[2] - v2[2]).abs > max_of - max_of = (v1[2] - v2[2]).abs - max_dir = :Z - dir = v1[2] - v2[2] - end - [max_dir, dir] + dir = v1[0] - v2[0] + elsif (v1[1] - v2[1]).abs > max_of + max_of = (v1[1] - v2[1]).abs + max_dir = :Y + dir = v1[1] - v2[1] + elsif (v1[2] - v2[2]).abs > max_of + max_of = (v1[2] - v2[2]).abs + max_dir = :Z + dir = v1[2] - v2[2] end - def directional_change_axis(v1, v2) - axis = {} - axis_count = 0 - dx = v1[0] - v2[0] - dy = v1[1] - v2[1] - dz = v1[2] - v2[2] - if dx != 0 - axis[:X] = dx - axis_count += dx.abs - end + directional_change_result = [max_dir, dir] - if dy != 0 - axis[:Y] = dy - axis_count += dy.abs - end + axis = {} + axis_count = 0 + dx = v1[0] - v2[0] + dy = v1[1] - v2[1] + dz = v1[2] - v2[2] - if dz != 0 - axis[:Z] = dz - axis_count += dz.abs - end - axis.each do |ax| - ax[1] /= axis_count - end - largest_delta_idx = axis.map { |e| e[1] }.each_with_index.max[1] - [axis, largest_delta_idx] + if dx != 0 + axis[:X] = dx + axis_count += dx.abs + end + + if dy != 0 + axis[:Y] = dy + axis_count += dy.abs + end + + if dz != 0 + axis[:Z] = dz + axis_count += dz.abs + end + + axis.each do |ax| + ax[1] /= axis_count + end + + largest_delta_idx = axis.map { |e| e[1] }.each_with_index.max[1] + directional_change_axis_result = [axis, largest_delta_idx] + + [directional_change_result, directional_change_axis_result] end end