def long_route() -> LatticeRoute: nodes = [ LatticeNode(np.array([0., 0., 10.])), LatticeNode(np.array([0, 20. * 0.42, 10.])) ] route = LatticeRoute(nodes) return route
def test_route(): nodes = [ LatticeNode(np.array([0., 10., 0.])), LatticeNode(np.array([0., 30., 0.])), LatticeNode(np.array([30., 30., 0.])), LatticeNode(np.array([30., 10., 0.])), ] route = LatticeRoute(nodes) assert len(route.edges) == 3 system = System(np.array([50., 50., 50.])) system.add_strand(route) assert len(system.strands) == 1 system = route.system(box=np.array([50., 50., 50.])) assert len(system.strands) == 1 system.write_oxDNA(root=ROOT) return route
def test_StapleRoute(route: LatticeRoute): x1 = 0 x2 = 15 row = 0 scaffold_rows = route.get_strand()[1] staple_nodes = [ StapleNode([x1, row, 0.0]), StapleNode([x2, row, 0.0]), StapleNode([x2, row + 1, 0.0]), StapleNode([x1, row + 1, 0.0]) ] return StapleRoute(scaffold_rows, staple_nodes)
def route(self, crossovers=None, *args, **kwargs) -> List[LatticeNode]: """ Generate DNASnake scaffold route, returns list of LatticeNode objects Arguments: crossovers - binary array or list of coordinates of crossovers *args & **kwargs - correspond to those of the `LatticeRoute` class Note: Different subclasses will use `Lattice` in a different way. Moreover, they will probably have a different routing algorithm """ if crossovers is None: coords = self.crossover_coords elif np.shape(crossovers)[1] not in [2, 3]: # if array coords = self.array_to_coords(crossovers) else: coords = crossovers # add 3rd column (z = 0) shape = np.shape(coords) if shape[1] != 3: coords = np.c_[coords, np.zeros(shape[0])] crossovers_per_row = 2 lattice_rows = int(coords[:, 1].max() + 1) # coords counts from 0 vertices_in_route = int(crossovers_per_row * lattice_rows) vertex_list = np.zeros((vertices_in_route, 3)) # Find final crossover from left or right and make it a node for row in range(0, lattice_rows): vertex_index_L = bisect_left(coords[:, 1], row) vertex_index_R = bisect_right(coords[:, 1], row) - 1 if row % 2 == 0: # if even vertex_list[row * 2] = coords[vertex_index_L] vertex_list[row * 2 + 1] = coords[vertex_index_R] else: # if odd vertex_list[row * 2] = coords[vertex_index_R] vertex_list[row * 2 + 1] = coords[vertex_index_L] # print(vertex_list) node_list = [LatticeNode(i) for i in vertex_list] return LatticeRoute(node_list, *args, **kwargs)
def side_staples(route: LatticeRoute, staple_width=16): scaffold = ScaffoldRows(route) staples = [] scaffold_rows = route.get_strand()[1] for row, info in scaffold.info.iterrows(): x2 = info["bounds"][0] if info["start side"] == "left": x1 = x2 + staple_width elif info["start side"] == "right": x1 = x2 - staple_width staple_nodes = [ StapleNode([x1, row, 0.0]), StapleNode([x2, row, 0.0]), StapleNode([x2, row + 1, 0.0]), StapleNode([x1, row + 1, 0.0]) ] staples.append(StapleRoute(scaffold_rows, staple_nodes)) return StapleCollection(staples)
return StapleRoute(scaffold_rows, staple_nodes) if __name__ == "__main__": half_turn_indices = [4, 15, 25, 36, 46, 56, 67, 77, 88, 98, 109] staple_lengths = [9, 31, 51, 73] route_vertices = [[0., 0., 0.], [56., 0., 0.], [56., 1., 0.], [0., 1., 0.], [0., 2., 0.], [56., 2., 0.], [56., 3., 0.], [0., 3., 0.], [0., 4., 0.], [56., 4., 0.], [56., 5., 0.], [0., 5., 0.], [0., 6., 0.], [56., 6., 0.], [56., 7., 0.], [0., 7., 0.], [0., 8., 0.], [88., 8., 0.], [88., 9., 0.], [0., 9., 0.], [0., 10., 0.], [88., 10., 0.], [88., 11., 0.], [0., 11., 0.], [0., 12., 0.], [56., 12., 0.], [56., 13., 0.], [0., 13., 0.], [0., 14., 0.], [56., 14., 0.], [56, 15, 0], [0, 15, 0]] nodes = [LatticeNode(np.array(i)) for i in route_vertices] route = LatticeRoute(nodes) fig, ax = plt.subplots() route.plot(ax=ax) # test, scaf = test_StapleRoute(route) # system = System(np.array([50,50,50])) # system.add_strands(scaf) # system.write_oxDNA("scaffold") collection = side_staples(route) system = route.system(collection.staples) system.write_oxDNA("lol")