diff --git a/molecularnodes/__init__.py b/molecularnodes/__init__.py index 80869f6d..398caa3e 100644 --- a/molecularnodes/__init__.py +++ b/molecularnodes/__init__.py @@ -13,7 +13,8 @@ import bpy from bpy.app.handlers import frame_change_post, load_post, save_post - +from bpy.props import PointerProperty, CollectionProperty +from .handlers import update_trajectories from . import entities, operators, props, session, ui from .utils import add_current_module_to_path from .ui import pref @@ -24,8 +25,8 @@ ui.CLASSES + operators.CLASSES + entities.CLASSES + + props.CLASSES + [ - props.MolecularNodesObjectProperties, MN_PT_Scene, ] + pref.CLASSES @@ -56,14 +57,13 @@ def register(): save_post.append(session._pickle) load_post.append(session._load) - frame_change_post.append(entities.trajectory.handlers.update_trajectories) + frame_change_post.append(update_trajectories) bpy.types.Scene.MNSession = session.MNSession() - bpy.types.Object.mn = bpy.props.PointerProperty( - type=props.MolecularNodesObjectProperties - ) - bpy.types.Object.mn_trajectory_selections = bpy.props.CollectionProperty( - type=entities.trajectory.selections.TrajectorySelectionItem + bpy.types.Object.mn = PointerProperty(type=props.MolecularNodesObjectProperties) + bpy.types.Scene.mn = PointerProperty(type=props.MolecularNodesSceneProperties) + bpy.types.Object.mn_trajectory_selections = CollectionProperty( + type=entities.trajectory.props.TrajectorySelectionItem ) @@ -81,7 +81,8 @@ def unregister(): save_post.remove(session._pickle) load_post.remove(session._load) - frame_change_post.remove(entities.trajectory.handlers.update_trajectories) + frame_change_post.remove(update_trajectories) del bpy.types.Scene.MNSession + del bpy.types.Scene.mn del bpy.types.Object.mn del bpy.types.Object.mn_trajectory_selections diff --git a/molecularnodes/blender_manifest.toml b/molecularnodes/blender_manifest.toml index c19b7498..d9dbc77b 100644 --- a/molecularnodes/blender_manifest.toml +++ b/molecularnodes/blender_manifest.toml @@ -35,16 +35,16 @@ wheels = [ "./wheels/biotite-0.41.2-cp311-cp311-macosx_11_0_arm64.whl", "./wheels/biotite-0.41.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", "./wheels/biotite-0.41.2-cp311-cp311-win_amd64.whl", - "./wheels/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", - "./wheels/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", - "./wheels/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", - "./wheels/contourpy-1.3.0-cp311-cp311-win_amd64.whl", + "./wheels/contourpy-1.3.1-cp311-cp311-macosx_10_9_x86_64.whl", + "./wheels/contourpy-1.3.1-cp311-cp311-macosx_11_0_arm64.whl", + "./wheels/contourpy-1.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "./wheels/contourpy-1.3.1-cp311-cp311-win_amd64.whl", "./wheels/cycler-0.12.1-py3-none-any.whl", "./wheels/fasteners-0.19-py3-none-any.whl", - "./wheels/fonttools-4.54.1-cp311-cp311-macosx_10_9_universal2.whl", - "./wheels/fonttools-4.54.1-cp311-cp311-macosx_11_0_arm64.whl", - "./wheels/fonttools-4.54.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", - "./wheels/fonttools-4.54.1-cp311-cp311-win_amd64.whl", + "./wheels/fonttools-4.55.0-cp311-cp311-macosx_10_9_universal2.whl", + "./wheels/fonttools-4.55.0-cp311-cp311-macosx_10_9_x86_64.whl", + "./wheels/fonttools-4.55.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "./wheels/fonttools-4.55.0-cp311-cp311-win_amd64.whl", "./wheels/joblib-1.4.2-py3-none-any.whl", "./wheels/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", "./wheels/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", @@ -62,7 +62,7 @@ wheels = [ "./wheels/msgpack-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", "./wheels/msgpack-1.1.0-cp311-cp311-win_amd64.whl", "./wheels/networkx-3.4.2-py3-none-any.whl", - "./wheels/packaging-24.1-py3-none-any.whl", + "./wheels/packaging-24.2-py3-none-any.whl", "./wheels/pandas-2.2.3-cp311-cp311-macosx_10_9_x86_64.whl", "./wheels/pandas-2.2.3-cp311-cp311-macosx_11_0_arm64.whl", "./wheels/pandas-2.2.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", @@ -81,7 +81,7 @@ wheels = [ "./wheels/six-1.16.0-py2.py3-none-any.whl", "./wheels/starfile-0.5.6-py3-none-any.whl", "./wheels/threadpoolctl-3.5.0-py3-none-any.whl", - "./wheels/tqdm-4.66.6-py3-none-any.whl", + "./wheels/tqdm-4.67.0-py3-none-any.whl", "./wheels/typing_extensions-4.12.2-py3-none-any.whl", "./wheels/tzdata-2024.2-py2.py3-none-any.whl", ] diff --git a/molecularnodes/entities/ensemble/cif.py b/molecularnodes/entities/ensemble/cif.py index 06be969d..a206d7f6 100644 --- a/molecularnodes/entities/ensemble/cif.py +++ b/molecularnodes/entities/ensemble/cif.py @@ -30,16 +30,15 @@ def _get_structure(self, extra_fields: str = None, sec_struct=True, bonds=True): # which can be extracted with the get_component() try: array = pdbx.get_structure(self.file, extra_fields=extra_fields) - try: - array.set_annotation( - "sec_struct", _get_secondary_structure(array, self.file) - ) - except KeyError: - warnings.warn("No secondary structure information.") - try: - array.set_annotation("entity_id", _get_entity_id(array, self.file)) - except KeyError: - warnings.warn("Non entity_id information.") + annotations = { + "sec_struct": _get_secondary_structure, + "entity_id": _get_entity_id, + } + for key, func in annotations.items(): + try: + array.set_annotation(key, func(array, self.file)) + except KeyError: + pass except InvalidFileError: array = pdbx.get_component(self.file) diff --git a/molecularnodes/entities/molecule/ui.py b/molecularnodes/entities/molecule/ui.py index 03fe866f..e2b7cb93 100644 --- a/molecularnodes/entities/molecule/ui.py +++ b/molecularnodes/entities/molecule/ui.py @@ -14,6 +14,7 @@ from .pdb import PDB from .pdbx import BCIF, CIF from .sdf import SDF +from ...style import STYLE_ITEMS def parse(filepath) -> Molecule: @@ -103,20 +104,6 @@ def load_local( return mol -STYLE_ITEMS = ( - ("spheres", "Spheres", "Space-filling atoms style."), - ("cartoon", "Cartoon", "Secondary structure cartoons"), - ("surface", "Surface", "Solvent-accsible surface."), - ("ribbon", "Ribbon", "Continuous backbone ribbon."), - ("sticks", "Sticks", "Sticks for each bond."), - ("ball_and_stick", "Ball and Stick", "Spheres for atoms, sticks for bonds"), - ("preset_1", "Preset 1", "A pre-made combination of different styles"), - ("preset_2", "Preset 2", "A pre-made combination of different styles"), - ("preset_3", "Preset 3", "A pre-made combination of different styles"), - ("preset_4", "Preset 4", "A pre-made combination of different styles"), -) - - class Import_Molecule(bpy.types.Operator): style: EnumProperty( # type: ignore name="Style", @@ -381,7 +368,7 @@ def execute(self, context): style = None if scene.MN_import_node_setup: - style = scene.MN_import_style + style = scene.mn.import_style centre = "" if scene.MN_import_centre: @@ -423,7 +410,7 @@ def execute(self, context): scene = context.scene file_path = scene.MN_import_local_path - style = scene.MN_import_style + style = scene.mn.import_style if not scene.MN_import_node_setup: style = None @@ -467,7 +454,7 @@ def execute(self, context): style = None if scene.MN_import_node_setup: - style = scene.MN_import_style + style = scene.mn.import_style centre = "" if scene.MN_import_centre: @@ -559,7 +546,7 @@ def panel_wwpdb(layout, scene): row = options.row() row.prop(scene, "MN_import_node_setup", text="") col = row.column() - col.prop(scene, "MN_import_style") + col.prop(scene.mn, "import_style") col.enabled = scene.MN_import_node_setup row_centre = options.row() @@ -601,7 +588,7 @@ def panel_alphafold(layout, scene): row = options.row() row.prop(scene, "MN_import_node_setup", text="") col = row.column() - col.prop(scene, "MN_import_style") + col.prop(scene.mn, "import_style") col.enabled = scene.MN_import_node_setup row_centre = options.row() @@ -638,7 +625,7 @@ def panel_local(layout, scene): row = options.row() row.prop(scene, "MN_import_node_setup", text="") col = row.column() - col.prop(scene, "MN_import_style") + col.prop(scene.mn, "import_style") col.enabled = scene.MN_import_node_setup row_centre = options.row() diff --git a/molecularnodes/entities/trajectory/__init__.py b/molecularnodes/entities/trajectory/__init__.py index 3695176e..23831404 100644 --- a/molecularnodes/entities/trajectory/__init__.py +++ b/molecularnodes/entities/trajectory/__init__.py @@ -1,6 +1,7 @@ from . import selections from . import ui +from . import props from .ui import load from .trajectory import Trajectory -CLASSES = selections.CLASSSES + ui.CLASSES +CLASSES = props.CLASSSES + ui.CLASSES diff --git a/molecularnodes/entities/trajectory/dna.py b/molecularnodes/entities/trajectory/dna.py index 36759a29..da17254e 100644 --- a/molecularnodes/entities/trajectory/dna.py +++ b/molecularnodes/entities/trajectory/dna.py @@ -1,324 +1,84 @@ -import numpy as np +from MDAnalysis import Universe import bpy +from bpy.props import StringProperty +from .ops import TrajectoryImportOperator from ... import color -from ...blender import mesh, coll, nodes +from ...blender import coll, nodes from ... import bpyd from ...bpyd import AttributeTypes -bpy.types.Scene.MN_import_oxdna_topology = bpy.props.StringProperty( - name="Toplogy", - description="File path for the topology to import (.top)", - subtype="FILE_PATH", - maxlen=0, -) -bpy.types.Scene.MN_import_oxdna_trajectory = bpy.props.StringProperty( - name="Trajectory", - description="File path for the trajectory to import (.oxdna / .dat)", - subtype="FILE_PATH", - maxlen=0, -) -bpy.types.Scene.MN_import_oxdna_name = bpy.props.StringProperty( - name="Name", - description="Name of the created object.", - default="NewOrigami", - maxlen=0, -) +from .oxdna.OXDNAParser import OXDNAParser +from .oxdna.OXDNAReader import OXDNAReader +from .trajectory import Trajectory +DNA_SCALE = 10 -def base_to_int(bases: np.array) -> np.array: - """ - Convert an array of DNA bases to their corresponding MN integer values. - Parameters - ---------- - bases : np.array - Array of DNA bases. - - Returns - ------- - np.array - Array of corresponding integer values for the DNA bases. - """ - # Values for internal Molecular Nodes use. Defined in data.py - base_lookup = {"A": 30, "C": 31, "G": 32, "T": 33} - - ints = np.array([base_lookup.get(base, -1) for base in bases]) - - return ints - - -def is_new_topology(filepath): - with open(filepath) as f: - firstline = f.readline() - - return "5 -> 3" in firstline - - -def read_topology_new(filepath): - with open(filepath, "r") as file: - contents = file.read() - - lines = np.array(contents.split("\n")) - - def read_seq_line(line): - sequence = line.split(" ")[0] - return np.array([c for c in sequence]) - - strands = [] - counter = 0 - - for i, line in enumerate(lines[1:]): - bases = read_seq_line(line) - arr = np.zeros((len(bases), 4), dtype=int) - idx = np.array(range(len(bases)), dtype=int) - arr[:, 0] = i + 1 # strand ID - arr[:, 1] = base_to_int(bases) # base - bond_3 = idx - 1 + counter - bond_5 = idx + 1 + counter - bond_3[0] = -1 - bond_5[-1] = -1 - arr[:, 2] = bond_3 - arr[:, 3] = bond_5 - - strands.append(arr) - counter += len(bases) - - return np.vstack(strands) - - -def read_topology_old(filepath): - """ - Read the topology from a file and convert it to a numpy array. - - - Strand assignment - | Base assignment - | | 3' Bonded base to the current base (index based on row) - | | | 5' Bonded base to the current base (index based on row) - | | | | - S B 3' 5' - S B 3' 5' - S B 3' 5' - - Parameters - ---------- - filepath : str - The path to the file containing the topology. - - Returns - ------- - numpy.ndarray - The topology as a integer numpy array. Base assignment is (30, 31, 32, 33) where - this corresponds to (A, C, G, T) for use inside of Molecular Nodes. - - """ - - with open(filepath, "r") as file: - contents = file.read() - - lines = np.array(contents.split("\n")) - # metadata = lines[0] - - # read the topology from the file sans the first metadata line - # have to initially read as strings, then convert bases to numeric later - array_str = np.loadtxt(lines[1:], dtype=str) - - # convert the columns to numeric - array_int = np.zeros(array_str.shape, dtype=int) - array_int[:, (0, 2, 3)] = array_str[:, (0, 2, 3)].astype( - int - ) # easy convert numeric columns to int - # convert bases (A, C, G, T) to (30, 31, 32, 33) - array_int[:, 1] = base_to_int(array_str[:, 1]) - - return array_int - - -def read_trajectory(filepath): - """ - Read an oxDNA trajectory file and return an array of frames. - - Each frame becomes a 2D array in a stack. Each frame has 5 three-component vectors. - The vectors are: (position, base_vector, base_normal, veclocity, angular_velocity), - which totals 15 columns in the array. The (velocity, angular_velocity) are optional - and can sometimes not appear in the trajectory. - - Parameters - ---------- - filepath : str - The path to the trajectory file. - - Returns - ------- - frames : ndarray - An array of frames, where each frame is a 2D array of positions - - """ - # Open the file and read its contents - with open(filepath, "r") as file: - contents = file.read() - - # Split the contents into lines - lines = np.array(contents.split("\n")) - is_meta = np.char.find(lines, "=") > 0 - - group_id = np.cumsum(np.append([True], np.diff(is_meta))) - groups = np.unique(group_id) - - frames = [] - - for group in groups: - mask = group == group_id - if "=" in lines[mask][0]: - continue - - arr = np.loadtxt(lines[mask]) - frames.append(arr) - - return np.stack(frames) - - -def store_named_attributes_to_dna_mol(obj, frame, scale_dna=0.1): - attributes = ("base_vector", "base_normal", "velocity", "angular_velocity") - for i, att in enumerate(attributes): - col_idx = np.array([3, 4, 5]) + i * 3 - - try: - data = frame[:, col_idx] - except IndexError as e: - print(f"Unable to get {att} attribute from coordinates. Error: {e}") - continue - - if att != "angular_velocity": - data *= scale_dna - - bpyd.store_named_attribute( - obj=obj, data=data, name=att, atype=AttributeTypes.FLOAT_VECTOR +class OXDNA(Trajectory): + def __init__(self, universe: Universe, world_scale: float = 0.01): + super().__init__(universe=universe, world_scale=world_scale) + self._att_names = ( + "base_vector", + "base_normal", + "velocity", + "angular_velocity", ) + def _create_object(self, style: str = "oxdna", name: str = "NewUniverseObject"): + self.object = bpyd.create_object( + name=name, + collection=coll.mn(), + vertices=self.univ_positions * self.world_scale * DNA_SCALE, + edges=self.bonds, + ) + self.object.mn.uuid = self.uuid + self.object.mn.molecule_type = "md" + self._update_timestep_values() + + for name in ("chain_id", "res_id", "res_name"): + if name == "res_name": + att_name = "res_num" + else: + att_name = name + self.store_named_attribute(getattr(self, att_name), name) + + self.store_named_attribute( + data=color.color_chains_equidistant(self.chain_id), + name="Color", + atype=AttributeTypes.FLOAT_COLOR, + ) -def toplogy_to_bond_idx_pairs(topology: np.ndarray): - """ - Convert the given topology array into pairs of indices representing each distinct bond. - - Strand assignment - | Base assignment - | | 3' Bonded base to the current base (index based on row) - | | | 5' Bonded base to the current base (index based on row) - | | | | - 1 A -1 1 - 1 G 0 2 - 1 C 1 -1 - - The topology above becomes: - np.array([[0, 1], [2, 1]]) - - The order of the bond indices doesn't matter to Blender. - - Parameters: - topology (np.ndarray): Numeric numpy array representing the topology. - - Returns: - np.ndarray: Array of pairs of indices representing each distinct bond. - """ - - # to get pairs of indices which represent each distinct bond, which are needed for - # edge creation in Blender, take each bonded column and create a 'bond' with itself - idx = np.array(list(range(topology.shape[0]))) - bond_3 = np.vstack((idx, topology[:, 2])).reshape((len(idx), 2)) - bond_5 = np.vstack((idx, topology[:, 3])).reshape((len(idx), 2)) - bonds = np.vstack((bond_3, bond_5)) - - # drop where either bond is -1 (not bonded) from the bond indices - mask = bonds == -1 - mask = np.logical_not(mask.any(axis=1)) - - bond_idxs = np.unique(bonds[mask, :], axis=0) - - return np.sort(bond_idxs, axis=1) - - -def load(top, traj, name="oxDNA", setup_nodes=True, world_scale=0.01): - # the scale of the oxDNA files seems to be based on nanometres rather than angstrongs - # like most structural biology files, so currently adjusting the world_scale to - # compensate - scale_dna = world_scale * 10 - - # read in the topology and trajectory files - is_new_top = is_new_topology(top) - if is_new_top: - topology = read_topology_new(top) - else: - topology = read_topology_old(top) + if style: + nodes.create_starting_node_tree(self.object, style="oxdna", color=None) - trajectory = read_trajectory(traj) - n_frames = trajectory.shape[0] + return self.object - # creat toplogy object with positions of the first frame, and the bonds from the - # topology object - obj = bpyd.create_object( - name=name, - collection=coll.mn(), - vertices=trajectory[0][:, 0:3] * scale_dna, - edges=toplogy_to_bond_idx_pairs(topology), - ) + def _update_positions(self, frame: int) -> None: + super()._update_positions(frame) + self._update_timestep_values() - # adding additional toplogy information from the topology and frames objects - bpyd.store_named_attribute( - obj=obj, data=topology[:, 1], name="res_name", atype=AttributeTypes.INT - ) - bpyd.store_named_attribute( - obj=obj, data=topology[:, 0], name="chain_id", atype=AttributeTypes.INT - ) - bpyd.store_named_attribute( - obj=obj, - data=color.color_chains_equidistant(topology[:, 0]), - name="Color", - atype=AttributeTypes.FLOAT_COLOR, - ) - store_named_attributes_to_dna_mol(obj, trajectory[0], scale_dna=scale_dna) + def _update_timestep_values(self): + for name in self._att_names: + try: + self.store_named_attribute( + self.universe.trajectory.ts.data[name] * self.world_scale, name=name + ) + except KeyError: + pass - # if the 'frames' file only contained one timepoint, return the object without creating - # any kind of collection for storing multiple frames from a trajectory, and a None - # object in place of the frames collection - if n_frames == 1: - if setup_nodes: - nodes.create_starting_node_tree(obj, style="oxdna", color=None) - return obj, None - # create a collection to store all of the frame objects that are part of the trajectory - # they will contain all of the possible attributes which can be interpolated betewen - # frames such as position, base_vector, base_normal, velocity, angular_velocity - collection = coll.frames(name) - for i, frame in enumerate(trajectory): - fill_n = int(np.ceil(np.log10(n_frames))) - frame_name = f"{name}_frame_{str(i).zfill(fill_n)}" - frame_obj = bpyd.create_object( - frame[:, 0:3] * scale_dna, name=frame_name, collection=collection - ) - store_named_attributes_to_dna_mol(frame_obj, frame, scale_dna) +def load(top, traj, name="oxDNA", style="oxdna", world_scale=0.01): + univ = Universe(top, traj, topology_format=OXDNAParser, format=OXDNAReader) + traj = OXDNA(univ, world_scale=world_scale * DNA_SCALE) + traj.create_object(name=name, style=style) + return traj - if setup_nodes: - nodes.create_starting_node_tree( - obj, coll_frames=collection, style="oxdna", color=None - ) - return obj, collection - - -class MN_OT_Import_OxDNA_Trajectory(bpy.types.Operator): +class MN_OT_Import_OxDNA_Trajectory(TrajectoryImportOperator): bl_idname = "mn.import_oxdna" - bl_label = "Load" - bl_description = "Will import the given file and toplogy." - bl_options = {"REGISTER"} def execute(self, context): - s = context.scene - load( - top=s.MN_import_oxdna_topology, - traj=s.MN_import_oxdna_trajectory, - name=s.MN_import_oxdna_name, - ) + load(top=self.topology, traj=self.trajectory, name=self.name) return {"FINISHED"} @@ -326,8 +86,11 @@ def panel(layout, scene): layout.label(text="Load oxDNA File", icon="FILE_TICK") layout.separator() row = layout.row() - row.prop(scene, "MN_import_oxdna_name") - row.operator("mn.import_oxdna") + row.prop(scene, "import_oxdna_name") + op = row.operator("mn.import_oxdna") + op.name = scene.mn.import_oxdna_name + op.topology = scene.mn.import_oxdna_topology + op.trajectory = scene.mn.import_oxdna_trajectory col = layout.column(align=True) - col.prop(scene, "MN_import_oxdna_topology") - col.prop(scene, "MN_import_oxdna_trajectory") + col.prop(scene.mn, "import_oxdna_topology") + col.prop(scene.mn, "import_oxdna_trajectory") diff --git a/molecularnodes/entities/trajectory/ops.py b/molecularnodes/entities/trajectory/ops.py new file mode 100644 index 00000000..6ea585ee --- /dev/null +++ b/molecularnodes/entities/trajectory/ops.py @@ -0,0 +1,35 @@ +from bpy.types import Operator +from bpy.props import StringProperty, BoolProperty, EnumProperty + +from ...style import STYLE_ITEMS + + +class TrajectoryImportOperator(Operator): + bl_label = "Import" + bl_description = "Will import the given file and toplogy." + bl_options = {"REGISTER"} + + topology: StringProperty( # type: ignore + name="Toplogy", + description="File path for the topology file", + subtype="FILE_PATH", + maxlen=0, + ) + trajectory: StringProperty( # type: ignore + name="Trajectory", + description="File path for the trajectory file", + subtype="FILE_PATH", + maxlen=0, + ) + name: StringProperty( # type: ignore + name="Name", + description="Name for the object that will be created and linked to the trajectory", + default="NewOrigami", + maxlen=0, + ) + style: EnumProperty( # type: ignore + name="Style", + description="Starting style on import", + default="spheres", + items=STYLE_ITEMS, + ) diff --git a/molecularnodes/entities/trajectory/oxdna/OXDNAParser.py b/molecularnodes/entities/trajectory/oxdna/OXDNAParser.py new file mode 100644 index 00000000..fbc091bf --- /dev/null +++ b/molecularnodes/entities/trajectory/oxdna/OXDNAParser.py @@ -0,0 +1,134 @@ +import numpy as np +from MDAnalysis.topology.base import TopologyReaderBase +from MDAnalysis.core.topology import Topology +from MDAnalysis.core.topologyattrs import ( + Atomids, + Bonds, + ChainIDs, + Resids, + Resnames, + Resnums, +) + + +class OXDNAParser(TopologyReaderBase): + def parse(self, **kwargs): + top = self._parseatoms() + + return top + + @classmethod + def _is_new_topology(self, filename) -> bool: + with open(filename) as f: + return "5->3" in f.readline() + + @classmethod + def _read_topo_new(cls, filename) -> Topology: + with open(filename) as f: + lines = f.readlines() + n_atoms, n_chains, direction = np.array(lines[0].split()) + n_atoms = int(n_atoms) + atom_idx = np.arange(n_atoms) + + res_name_list = [] + chain_id_list = [] + for i, line in enumerate(lines[1:]): + is_rna = "type=RNA" in line + is_dna = not is_rna + + line_split = line.split() + bases = line_split[0] + + base_list = [] + start = 0 + end = 0 + in_custom_base = False + for i, letter in enumerate(bases): + if letter == "(": + start = i + 1 + in_custom_base = True + continue + if letter == ")": + end = i + base_list.append(line[start:end]) + in_custom_base = False + continue + + if in_custom_base: + continue + + base_list.append(letter) + chain_id_list.append(np.repeat(i, len(base_list))) + + res_name_list.append(np.array(base_list)) + + res_names = np.hstack(res_name_list) + chain_ids = np.hstack(chain_id_list) + + bond_idx = np.zeros((n_atoms, 2), dtype=int) + bond_idx[:, :] = -1 + + for i in atom_idx: + if i == 1: + continue + if chain_ids[i] == chain_ids[-1]: + bond_idx[i, :] = np.array((i, i - 1), dtype=int) + + mask = np.logical_and(bond_idx[:, 0] != -1, bond_idx[:, 1] != -1) + bond_idx = bond_idx[mask, :] + + attrs = [] + for Attr in (Atomids, Resnums, Resids): + attrs.append(Attr(atom_idx)) + + attrs.append(ChainIDs(chain_ids)) + attrs.append(Resnames(res_names)) + + topo = Topology(n_atoms, n_atoms, 1, attrs=attrs) + bonds = Bonds(bond_idx) + topo.add_TopologyAttr(bonds) + + return topo + + @classmethod + def _read_topo_old(cls, filename) -> Topology: + with open(filename) as f: + first_line = f.readline() + + dimensions = np.array(first_line.split()) + n_atoms = int(dimensions[0]) + array = np.loadtxt(filename, skiprows=1, max_rows=n_atoms, dtype=str) + + # each topology item has two bond columns, which say what the base is bonded + # from and what it is bonded to. -1 means it is not bonded + # we need to turn that into an array of bond pairs + bond_idx = np.zeros((n_atoms * 2, 2), int) + row_numbers = np.arange(n_atoms, dtype=int) + for i in range(2): + rows = row_numbers + (i * n_atoms) + bond_idx[rows, 0] = array[:, (i + 2)] + bond_idx[rows, 1] = row_numbers + + # drop any that have -1 as they aren't bonded to anything + mask = np.logical_and(bond_idx[:, 0] != -1, bond_idx[:, 1] != -1) + bond_idx = bond_idx[mask, :] + + attrs = [] + idx = np.arange(1, n_atoms + 1, dtype=int) + for Attr in (Atomids, Resnums, Resids): + attrs.append(Attr(idx)) + attrs.append(ChainIDs(array[:, 0].astype(int))) + attrs.append(Resnames(array[:, 1].astype(str))) + + topo = Topology(n_atoms, n_atoms, 1, attrs=attrs) + + bonds = Bonds(bond_idx) + topo.add_TopologyAttr(bonds) + + return topo + + def _parseatoms(self): + if self._is_new_topology(self.filename): + return self._read_topo_new(self.filename) + else: + return self._read_topo_old(self.filename) diff --git a/molecularnodes/entities/trajectory/oxdna/OXDNAReader.py b/molecularnodes/entities/trajectory/oxdna/OXDNAReader.py new file mode 100644 index 00000000..81c1ec3a --- /dev/null +++ b/molecularnodes/entities/trajectory/oxdna/OXDNAReader.py @@ -0,0 +1,90 @@ +import numpy as np + +from MDAnalysis.coordinates.base import ReaderBase +from MDAnalysis.lib import util + + +def _is_info_line(line: str): + return line.startswith("t = ") or line.startswith("b = ") or line.startswith("E = ") + + +class OXDNAReader(ReaderBase): + def __init__(self, filename, **kwargs): + super(OXDNAReader, self).__init__(filename, **kwargs) + + self.n_atoms = kwargs["n_atoms"] + self.ts = self._Timestep(self.n_atoms, **self._ts_kwargs) + + oxdnafile = self._oxdnafile = util.anyopen(filename, "rb") + + starts = [] + stops = [] + + line = "a new line" + previous_is_info = False + current_is_info = False + while line: + line = oxdnafile.readline().decode() + current_is_info = _is_info_line(line) + + # get the lines where the data values start and stop, which + # are separated by the several lines of overall information + if not current_is_info and previous_is_info: + starts.append(oxdnafile.tell() - len(line)) + if current_is_info and not previous_is_info: + stops.append(oxdnafile.tell() - len(line)) + + previous_is_info = current_is_info + + # add the end of the file + stops += [oxdnafile.tell()] + + self._start_offsets = starts + self._stop_offsets = stops[1:] # drop the first + self.n_frames = len(self._start_offsets) + + self._read_frame(0) + + def _reopen(self): + self.close() + self._oxdnafile = util.anyopen(self.filename, "rb") + self.ts.frame = -1 + + def _read_next_timestep(self, ts=None): + frame = self.frame + 1 + return self._read_frame(frame) + + def _read_frame(self, frame): + try: + start = self._start_offsets[frame] + stop = self._stop_offsets[frame] + except IndexError: + raise OSError from None + + self._oxdnafile.seek(start) + chunk = self._oxdnafile.read(stop - start) + + array = np.array( + [ + np.array(line.split(), dtype=float) + for line in chunk.decode().splitlines() + ] + ) + + # TODO: also access and update the other values + self.ts.positions = array[:, :3] + + for i, name in enumerate( + ("base_vector", "base_normal", "velocity", "angular_velocity") + ): + starting_column = 3 * (i + 1) + if starting_column >= array.shape[1]: + continue + cols = np.arange(3) + starting_column + self.ts.data[name] = array[:, cols] + self.ts.frame = frame + + return self.ts + + def close(self): + self._oxdnafile.close() diff --git a/molecularnodes/entities/trajectory/props.py b/molecularnodes/entities/trajectory/props.py new file mode 100644 index 00000000..2333042e --- /dev/null +++ b/molecularnodes/entities/trajectory/props.py @@ -0,0 +1,119 @@ +import bpy +from bpy.props import StringProperty, BoolProperty +from ...handlers import _selection_update_trajectories, _update_trajectories + + +class TrajectorySelectionItem(bpy.types.PropertyGroup): + """Group of properties for custom selections for MDAnalysis import.""" + + name: StringProperty( # type: ignore + name="Name", + description="Name of the attribute on the mesh", + default="custom_selection", + update=_selection_update_trajectories, + ) + + selection_str: StringProperty( # type: ignore + name="Selection", + description="Selection to be applied, written in the MDAnalysis selection language", + default="name CA", + update=_selection_update_trajectories, + ) + + updating: BoolProperty( # type: ignore + name="Updating", + description="Recalculate the selection on scene frame change", + default=True, + update=_selection_update_trajectories, + ) + + periodic: BoolProperty( # type: ignore + name="Periodic", + description="For geometric selections, whether to account for atoms in different periodic images when searching", + default=True, + update=_selection_update_trajectories, + ) + + message: StringProperty( # type: ignore + name="Message", + description="Message to report back from `universe.select_atoms()`", + default="", + ) + + immutable: BoolProperty( # type: ignore + name="Immutable", + description="Whether the selection is immutable", + default=False, + ) + + +class MN_UL_TrajectorySelectionListUI(bpy.types.UIList): + """UI List""" + + def draw_item( + self, context, layout, data, item, icon, active_data, active_propname, index + ): + custom_icon = "VIS_SEL_11" + + if self.layout_type in {"DEFAULT", "COMPACT"}: + row = layout.row() + if item.message != "": + custom_icon = "ERROR" + row.alert = True + + row.prop(item, "name", text="", emboss=False) + row.prop(item, "updating", icon_only=True, icon="FILE_REFRESH") + row.prop(item, "periodic", icon_only=True, icon="CUBE") + if item.immutable: + row.enabled = False + + elif self.layout_type in {"GRID"}: + layout.alignment = "CENTER" + layout.label(text="", icon=custom_icon) + + +class MN_OT_Universe_Selection_Add(bpy.types.Operator): + "Add a new custom selection to a trajectory" + + bl_idname = "mn.trajectory_selection_add" + bl_label = "+" + bl_description = "Add a new boolean attribute for the given MDA selection string" + + def execute(self, context): + obj = context.active_object + obj.mn_trajectory_selections.add() + i = int(len(obj.mn_trajectory_selections) - 1) + obj.mn_trajectory_selections[i].name = f"selection_{i + 1}" + obj.mn["list_index"] = i + _update_trajectories(self, context) + + return {"FINISHED"} + + +class MN_OT_Universe_Selection_Delete(bpy.types.Operator): + bl_idname = "mda.delete_item" + bl_label = "-" + bl_description = "Delete the given boolean selection from the universe" + + @classmethod + def poll(cls, context): + return context.active_object.mn_trajectory_selections + + def execute(self, context): + obj = context.active_object + index = obj.mn.trajectory_selection_index + + sel_list = obj.mn_trajectory_selections + sel_list.remove(index) + obj.mn.trajectory_selection_index = len(sel_list) - 1 + _update_trajectories(self, context) + + return {"FINISHED"} + + +CLASSSES = [ + TrajectorySelectionItem, # has to be registered before the others to work properly + MN_UL_TrajectorySelectionListUI, + MN_OT_Universe_Selection_Add, + MN_OT_Universe_Selection_Delete, +] diff --git a/molecularnodes/entities/trajectory/selections.py b/molecularnodes/entities/trajectory/selections.py index 50f94da3..6af069e3 100644 --- a/molecularnodes/entities/trajectory/selections.py +++ b/molecularnodes/entities/trajectory/selections.py @@ -1,9 +1,6 @@ -import bpy import MDAnalysis as mda import numpy.typing as npt import numpy as np -from bpy.props import StringProperty, BoolProperty -from .handlers import _selection_update_trajectories, _update_trajectories class Selection: @@ -83,119 +80,3 @@ def from_atomgroup(cls, atomgroup: mda.AtomGroup, name: str = ""): selection.ag = atomgroup selection.mask_array = selection._ag_to_mask() return selection - - -class TrajectorySelectionItem(bpy.types.PropertyGroup): - """Group of properties for custom selections for MDAnalysis import.""" - - name: StringProperty( # type: ignore - name="Name", - description="Name of the attribute on the mesh", - default="custom_selection", - update=_selection_update_trajectories, - ) - - selection_str: StringProperty( # type: ignore - name="Selection", - description="Selection to be applied, written in the MDAnalysis selection language", - default="name CA", - update=_selection_update_trajectories, - ) - - updating: BoolProperty( # type: ignore - name="Updating", - description="Recalculate the selection on scene frame change", - default=True, - update=_selection_update_trajectories, - ) - - periodic: BoolProperty( # type: ignore - name="Periodic", - description="For geometric selections, whether to account for atoms in different periodic images when searching", - default=True, - update=_selection_update_trajectories, - ) - - message: StringProperty( # type: ignore - name="Message", - description="Message to report back from `universe.select_atoms()`", - default="", - ) - - immutable: BoolProperty( # type: ignore - name="Immutable", - description="Whether the selection is immutable", - default=False, - ) - - -class MN_UL_TrajectorySelectionListUI(bpy.types.UIList): - """UI List""" - - def draw_item( - self, context, layout, data, item, icon, active_data, active_propname, index - ): - custom_icon = "VIS_SEL_11" - - if self.layout_type in {"DEFAULT", "COMPACT"}: - row = layout.row() - if item.message != "": - custom_icon = "ERROR" - row.alert = True - - row.prop(item, "name", text="", emboss=False) - row.prop(item, "updating", icon_only=True, icon="FILE_REFRESH") - row.prop(item, "periodic", icon_only=True, icon="CUBE") - if item.immutable: - row.enabled = False - - elif self.layout_type in {"GRID"}: - layout.alignment = "CENTER" - layout.label(text="", icon=custom_icon) - - -class MN_OT_Universe_Selection_Add(bpy.types.Operator): - "Add a new custom selection to a trajectory" - - bl_idname = "mn.trajectory_selection_add" - bl_label = "+" - bl_description = "Add a new boolean attribute for the given MDA selection string" - - def execute(self, context): - obj = context.active_object - obj.mn_trajectory_selections.add() - i = int(len(obj.mn_trajectory_selections) - 1) - obj.mn_trajectory_selections[i].name = f"selection_{i + 1}" - obj.mn["list_index"] = i - _update_trajectories(self, context) - - return {"FINISHED"} - - -class MN_OT_Universe_Selection_Delete(bpy.types.Operator): - bl_idname = "mda.delete_item" - bl_label = "-" - bl_description = "Delete the given boolean selection from the universe" - - @classmethod - def poll(cls, context): - return context.active_object.mn_trajectory_selections - - def execute(self, context): - obj = context.active_object - index = obj.mn.trajectory_selection_index - - sel_list = obj.mn_trajectory_selections - sel_list.remove(index) - obj.mn.trajectory_selection_index = len(sel_list) - 1 - _update_trajectories(self, context) - - return {"FINISHED"} - - -CLASSSES = [ - TrajectorySelectionItem, # has to be registered before the others to work properly - MN_UL_TrajectorySelectionListUI, - MN_OT_Universe_Selection_Add, - MN_OT_Universe_Selection_Delete, -] diff --git a/molecularnodes/entities/trajectory/trajectory.py b/molecularnodes/entities/trajectory/trajectory.py index 5186fd84..10565736 100644 --- a/molecularnodes/entities/trajectory/trajectory.py +++ b/molecularnodes/entities/trajectory/trajectory.py @@ -16,7 +16,7 @@ frames_to_average, fraction, ) -from .selections import Selection, TrajectorySelectionItem +from .selections import Selection class Trajectory(MolecularEntity): @@ -30,7 +30,7 @@ def __init__(self, universe: mda.Universe, world_scale: float = 0.01): self.cache: dict = {} bpy.context.scene.MNSession.trajectories[self.uuid] = self - def selection_from_ui(self, ui_item: TrajectorySelectionItem) -> Selection: + def selection_from_ui(self, ui_item) -> Selection: self.selections[ui_item.name] = Selection( universe=self.universe, selection_str=ui_item.selection_str, @@ -48,7 +48,7 @@ def add_selection( name: str, updating: bool = True, periodic: bool = True, - ) -> TrajectorySelectionItem: + ): "Adds a new selection with the given name, selection string and selection parameters." obj = self.object @@ -209,6 +209,10 @@ def uframe(self, value) -> None: def res_name(self) -> np.ndarray: return np.array(list(map(lambda x: x[0:3], self.atoms.resnames))) + @property + def atom_id(self) -> np.ndarray: + return self.universe.atoms.atom_id + @property def res_num(self) -> np.ndarray: return np.array( @@ -258,10 +262,13 @@ def atom_type_unique(self) -> np.ndarray: @property def atom_type_num(self) -> np.ndarray: - atom_type_unique, atom_type_index = np.unique( - self.atom_type, return_inverse=True - ) - return atom_type_index + try: + atom_type_unique, atom_type_index = np.unique( + self.atom_type, return_inverse=True + ) + return atom_type_index + except AttributeError: + return None @property def atom_name(self) -> np.ndarray: @@ -400,13 +407,9 @@ def save_filepaths_on_object(self) -> None: path_resolve(self.universe.trajectory.filename) ) - def create_object( - self, - style: str = "vdw", - name: str = "NewUniverseObject", - subframes: int = 0, - # in_memory: bool = False, - ): + def _create_object( + self, style: str = "vdw", name: str = "NewUniverseObject" + ) -> bpy.types.Object: obj = bpyd.create_object( name=name, collection=coll.mn(), @@ -432,20 +435,20 @@ def create_object( segs.append(seg.atoms[0].segid) obj["segments"] = segs - - obj["chain_ids"] = self.chain_ids - obj["atom_type_unique"] = self.atom_type_unique - self.subframes = subframes - obj.mn.molecule_type = "md" - self.save_filepaths_on_object() - if style is not None: nodes.create_starting_node_tree(obj, style=style, name=f"MN_{obj.name}") - bpy.context.view_layer.objects.active = obj - obj.mn.uuid = self.uuid + def create_object(self, style: str = "vdw", name: str = "NewUniverseObject"): + self._create_object(style=style, name=name) + self.object.mn.uuid = self.uuid + self.object["chain_ids"] = self.chain_ids + if hasattr(self, "atom_type_unique"): + self.object["atom_type_unique"] = self.atom_type_unique + self.object.mn.molecule_type = "md" + self.save_filepaths_on_object() + bpy.context.view_layer.objects.active = self.object - return obj + return self.object def _update_calculations(self): for name, func in self.calculations.items(): diff --git a/molecularnodes/entities/trajectory/ui.py b/molecularnodes/entities/trajectory/ui.py index bc69e1ba..0e819739 100644 --- a/molecularnodes/entities/trajectory/ui.py +++ b/molecularnodes/entities/trajectory/ui.py @@ -9,7 +9,6 @@ import MDAnalysis as mda from ... import blender as bl -from ...session import get_session from .trajectory import Trajectory from bpy.props import StringProperty @@ -33,13 +32,7 @@ ) -def load( - top, - traj, - name="NewTrajectory", - style="spheres", - subframes: int = 0, -): +def load(top, traj, name="NewTrajectory", style="spheres"): top = bl.path_resolve(top) traj = bl.path_resolve(traj) @@ -47,7 +40,7 @@ def load( traj = Trajectory(universe=universe) - traj.create_object(name=name, style=style, subframes=subframes) + traj.create_object(name=name, style=style) return traj @@ -63,7 +56,7 @@ class MN_OT_Reload_Trajectory(bpy.types.Operator): @classmethod def poll(cls, context): obj = context.active_object - traj = get_session(context).trajectories.get(obj.mn.uuid) + traj = context.scene.MNSession.trajectories.get(obj.mn.uuid) return not traj def execute(self, context): @@ -91,7 +84,7 @@ def execute(self, context): top=topology_file, traj=trajectory_file, name=name, - style=scene.MN_import_style, + style=scene.mn.import_style, ) context.view_layer.objects.active = trajectory.object @@ -127,7 +120,7 @@ def panel(layout, scene): row = layout.row() row.prop(scene, "MN_import_node_setup", text="") col = row.column() - col.prop(scene, "MN_import_style") + col.prop(scene.mn, "import_style") col.enabled = scene.MN_import_node_setup diff --git a/molecularnodes/entities/trajectory/handlers.py b/molecularnodes/handlers.py similarity index 93% rename from molecularnodes/entities/trajectory/handlers.py rename to molecularnodes/handlers.py index 8e1ef63e..51e3fc29 100644 --- a/molecularnodes/entities/trajectory/handlers.py +++ b/molecularnodes/handlers.py @@ -1,6 +1,8 @@ import bpy from bpy.app.handlers import persistent +# from .session import MNSession + # this update function requires a self and context input, as funcitons with these inputs # have ot be passed to the `update` arguments of UI properties. When the UI is updated, @@ -34,7 +36,8 @@ def _selection_update_trajectories(self, context: bpy.types.Context) -> None: @persistent def update_trajectories(scene): "Updatins all positions and selections for each trajectory." - for trajectory in scene.MNSession.trajectories.values(): + session: MNSession = scene.MNSession + for trajectory in session.trajectories.values(): try: trajectory._update_positions(scene.frame_current) trajectory._update_selections() diff --git a/molecularnodes/props.py b/molecularnodes/props.py index 59139694..052bc78f 100644 --- a/molecularnodes/props.py +++ b/molecularnodes/props.py @@ -1,6 +1,9 @@ import bpy +from bpy.types import PropertyGroup from bpy.props import IntProperty, BoolProperty, EnumProperty, StringProperty -from .entities.trajectory.handlers import _update_trajectories +from .handlers import _update_trajectories +from .style import STYLE_ITEMS + bpy.types.Scene.MN_import_centre = BoolProperty( name="Centre Structure", @@ -48,7 +51,29 @@ ) -class MolecularNodesObjectProperties(bpy.types.PropertyGroup): +class MolecularNodesSceneProperties(PropertyGroup): + import_oxdna_topology: StringProperty( # type: ignore + name="Toplogy", + description="File path for the topology to import (.top)", + subtype="FILE_PATH", + ) + import_oxdna_trajectory: StringProperty( # type: ignore + name="Trajectory", + description="File path for the trajectory to import (.oxdna / .dat)", + subtype="FILE_PATH", + ) + import_oxdna_name: StringProperty( # type: ignore + name="Name", description="Name of the created object.", default="NewOrigami" + ) + import_style: EnumProperty( # type: ignore + name="Style", + description="Default style for importing", + items=STYLE_ITEMS, + default="spheres", + ) + + +class MolecularNodesObjectProperties(PropertyGroup): molecule_type: StringProperty( # type: ignore name="Molecular Type", description="How the file was imported, dictating how MN interacts with it", @@ -115,3 +140,6 @@ class MolecularNodesObjectProperties(bpy.types.PropertyGroup): subtype="FILE_PATH", default="", ) + + +CLASSES = [MolecularNodesObjectProperties, MolecularNodesSceneProperties] diff --git a/molecularnodes/style.py b/molecularnodes/style.py new file mode 100644 index 00000000..3d98752c --- /dev/null +++ b/molecularnodes/style.py @@ -0,0 +1,12 @@ +STYLE_ITEMS = ( + ("spheres", "Spheres", "Space-filling atoms style."), + ("cartoon", "Cartoon", "Secondary structure cartoons"), + ("surface", "Surface", "Solvent-accsible surface."), + ("ribbon", "Ribbon", "Continuous backbone ribbon."), + ("sticks", "Sticks", "Sticks for each bond."), + ("ball_and_stick", "Ball and Stick", "Spheres for atoms, sticks for bonds"), + ("preset_1", "Preset 1", "A pre-made combination of different styles"), + ("preset_2", "Preset 2", "A pre-made combination of different styles"), + ("preset_3", "Preset 3", "A pre-made combination of different styles"), + ("preset_4", "Preset 4", "A pre-made combination of different styles"), +) diff --git a/molecularnodes/ui/__init__.py b/molecularnodes/ui/__init__.py index ac676ffd..dcf93ca0 100644 --- a/molecularnodes/ui/__init__.py +++ b/molecularnodes/ui/__init__.py @@ -1,3 +1,4 @@ -from . import panel, node_menu +from .panel import CLASSES as PANEL_CLASSES +from .node_menu import CLASSES as NODE_MENU_CLASSES -CLASSES = panel.CLASSES + node_menu.CLASSES +CLASSES = PANEL_CLASSES + NODE_MENU_CLASSES diff --git a/molecularnodes/ui/panel.py b/molecularnodes/ui/panel.py index 27ee50af..4dcdcb28 100644 --- a/molecularnodes/ui/panel.py +++ b/molecularnodes/ui/panel.py @@ -33,25 +33,7 @@ ("dna", "oxDNA", "Import an oxDNA file"), ), ) -STYLE_ITEMS = ( - ("spheres", "Spheres", "Space-filling atoms style."), - ("cartoon", "Cartoon", "Secondary structure cartoons"), - ("surface", "Surface", "Solvent-accsible surface."), - ("ribbon", "Ribbon", "Continuous backbone ribbon."), - ("sticks", "Sticks", "Sticks for each bond."), - ("ball_and_stick", "Ball and Stick", "Spheres for atoms, sticks for bonds"), - ("preset_1", "Preset 1", "A pre-made combination of different styles"), - ("preset_2", "Preset 2", "A pre-made combination of different styles"), - ("preset_3", "Preset 3", "A pre-made combination of different styles"), - ("preset_4", "Preset 4", "A pre-made combination of different styles"), -) -bpy.types.Scene.MN_import_style = bpy.props.EnumProperty( - name="Style", - description="Default style for importing molecules.", - items=STYLE_ITEMS, - default="spheres", -) chosen_panel = { "pdb": molecule.ui.panel_wwpdb, @@ -64,17 +46,6 @@ "dna": dna.panel, } -packages = { - "pdb": ["biotite"], - "alphafold": ["biotite"], - "star": ["starfile", "mrcfile", "pillow"], - "local": ["biotite"], - "cellpack": ["biotite", "msgpack"], - "md": ["MDAnalysis"], - "density": ["mrcfile"], - "dna": [], -} - def pt_object_context(self, context): layout = self.layout diff --git a/tests/__snapshots__/test_dna.ambr b/tests/__snapshots__/test_dna.ambr index 0c7b6ab1..cc245c3a 100644 --- a/tests/__snapshots__/test_dna.ambr +++ b/tests/__snapshots__/test_dna.ambr @@ -1,1511 +1,379 @@ # serializer version: 1 -# name: test_read_oxdna - [32 33 30 31 31 31 32 31 31 30 30 31 30 33 33 32 33 31 32 33 31 30 33 31 - 30 32 33 32 33 32 33 32 31 32 32 32 30 33 30 31 31 32 32 33 30 30 31 30 - 31 33 33 31 31 31 33 31 30 31 32 30 31 32 33 31 32 33 31 31 33 32 31 32 - 32 32 33 33 31 30 30 31 33 30 32 32 30 33 33 32 31 30 33 33 32 33 31 31 - 33 33 30 30] +# name: TestOXDNAReading.test_comparing_topologies[top_new] + list([ + list([ + 1, + 2, + ]), + list([ + 2, + 3, + ]), + list([ + 3, + 4, + ]), + list([ + 4, + 5, + ]), + list([ + 5, + 6, + ]), + list([ + 6, + 7, + ]), + list([ + 7, + 8, + ]), + list([ + 8, + 9, + ]), + list([ + 9, + 10, + ]), + list([ + 10, + 11, + ]), + ]) # --- -# name: test_read_oxdna.1 - [4 1 4 3 1 1 2 4 3 3 1 3 4 2 3 4 4 1 2 4 3 1 3 3 1 3 3 2 3 4 2 3 1 1 2 3 4 - 2 4 4 1 4 2 3 3 3 1 1 4 4 2 1 3 3 2 3 4 2 2 2 1 2 2 1 3 3 3 3 3 3 1 4 1 2 - 3 3 1 4 2 1 3 4 1 4 3 4 3 4 4 4 3 3 2 4 1 3 2 2 2 3] +# name: TestOXDNAReading.test_comparing_topologies[top_new].1 + list([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]) # --- -# name: test_read_oxdna.10 - [ True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True] +# name: TestOXDNAReading.test_comparing_topologies[top_new].2 + list([ + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + 5.0, + ]) # --- -# name: test_read_oxdna.11 - AttributeError("The selected attribute 'sharp_face' does not exist on the mesh.") +# name: TestOXDNAReading.test_comparing_topologies[top_new].3 + list([ + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + ]) # --- -# name: test_read_oxdna.12 - [32 32 30 30 31 31 33 31 31 30 33 32 32 33 31 30 33 30 31 31 31 33 31 30 - 32 31 32 33 33 32 33 33 32 30 33 31 31 33 30 31 30 31 33 32 32 32 33 30 - 31 31 31 32 32 33 33 33 32 30 32 33 31 32 30 31 31 32 33 31 32 33 31 31 - 32 31 30 33 30 32 31 32 33 32 31 33 33 30 33 32 33 33 32 30 31 32 32 33 - 32 31 31 33] +# name: TestOXDNAReading.test_comparing_topologies[top_new_custom] + list([ + list([ + 5, + 6, + ]), + list([ + 6, + 7, + ]), + list([ + 7, + 8, + ]), + list([ + 8, + 9, + ]), + list([ + 9, + 10, + ]), + list([ + 10, + 11, + ]), + ]) # --- -# name: test_read_oxdna.13 - [3 4 3 2 1 1 3 1 4 1 3 4 2 2 3 2 3 3 3 1 3 1 2 3 3 3 2 3 3 2 2 1 4 2 4 4 1 - 1 3 3 4 1 4 3 4 4 2 4 3 4 2 2 4 2 4 2 4 1 2 1 1 4 4 1 1 2 3 4 4 2 1 3 2 3 - 3 3 3 3 3 2 3 4 3 3 4 2 3 2 3 3 4 1 1 4 3 1 2 3 4 3] +# name: TestOXDNAReading.test_comparing_topologies[top_new_custom].1 + list([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ]) # --- -# name: test_read_oxdna.14 - [[0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.3 0.5 1.0] - [0.3 0.8 0.2 1.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.7 0.8 0.4 0.0] - [0.8 0.3 0.5 1.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.3 0.8 0.2 1.0] - [0.3 0.8 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.8 0.3 0.5 1.0] - [0.3 0.8 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.3 0.5 1.0] - [0.8 0.2 0.2 1.0] - [0.7 0.8 0.4 0.0] - [0.8 0.3 0.5 1.0] - [0.3 0.8 0.2 1.0] - [0.8 0.4 0.4 0.0] - [0.8 0.3 0.5 1.0] - [0.4 0.8 0.5 0.0] - [0.3 0.8 0.2 1.0] - [0.4 0.5 0.8 0.0] - [0.3 0.8 0.2 1.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.8 0.2 0.2 1.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.2 0.2 1.0] - [0.8 0.2 0.2 1.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.2 0.2 1.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.3 0.8 0.2 1.0] - [0.3 0.8 0.2 1.0] - [0.8 0.2 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.2 0.2 1.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.3 0.8 0.2 1.0] - [0.8 0.2 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.3 0.5 0.8 1.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.3 0.8 0.2 1.0] - [0.8 0.2 0.2 1.0] - [0.4 0.8 0.5 0.0] - [0.8 0.2 0.2 1.0] - [0.3 0.8 0.2 1.0] - [0.8 0.3 0.5 1.0] - [0.4 0.5 0.8 0.0] - [0.3 0.5 0.8 1.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.3 0.5 1.0] - [0.8 0.2 0.2 1.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.3 0.5 1.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.3 0.8 0.2 1.0] - [0.8 0.3 0.5 1.0]] +# name: TestOXDNAReading.test_comparing_topologies[top_new_custom].2 + list([ + 8.0, + 8.0, + 8.0, + 8.0, + 8.0, + 8.0, + 9.0, + 9.0, + 9.0, + 9.0, + 9.0, + 9.0, + ]) # --- -# name: test_read_oxdna.15 - [[-0.3 0.5 0.1] - [-0.0 0.8 -0.1] - [-0.1 0.7 0.1] - [ 0.1 0.3 0.1] - [-0.3 0.3 0.6] - [-0.3 0.4 0.6] - [-0.1 0.8 -0.3] - [ 0.1 0.5 0.1] - [-0.2 0.4 0.3] - [-0.0 0.3 -0.0] - [-0.1 0.8 -0.2] - [-0.1 0.8 -0.0] - [ 0.0 0.4 0.2] - [-0.5 0.2 0.1] - [-0.1 0.7 -0.1] - [ 0.1 0.3 0.0] - [-0.1 0.7 0.0] - [-0.1 0.7 0.1] - [-0.5 0.2 0.1] - [-0.2 0.4 0.6] - [-0.0 0.6 -0.1] - [-0.1 0.3 0.1] - [-0.4 0.2 0.1] - [-0.2 0.3 0.1] - [-0.2 0.5 0.1] - [-0.1 0.7 -0.1] - [ 0.0 0.3 0.1] - [-0.1 0.9 -0.2] - [-0.1 0.8 -0.2] - [-0.1 0.4 -0.0] - [-0.1 0.4 0.1] - [-0.1 0.3 0.0] - [-0.1 0.8 -0.1] - [ 0.1 0.3 0.1] - [-0.2 0.4 0.4] - [-0.1 0.5 0.2] - [ 0.1 0.5 0.1] - [-0.1 0.3 0.0] - [-0.3 0.4 -0.0] - [-0.4 0.2 -0.0] - [-0.2 0.6 0.0] - [-0.2 0.3 0.0] - [-0.1 0.6 -0.0] - [-0.1 0.7 0.1] - [-0.1 0.6 0.1] - [-0.2 0.4 0.6] - [-0.0 0.4 0.1] - [-0.2 0.7 -0.1] - [-0.1 0.6 -0.1] - [-0.1 0.5 0.2] - [ 0.1 0.3 0.1] - [ 0.2 0.5 0.0] - [-0.1 0.8 -0.1] - [-0.5 0.3 0.0] - [-0.1 0.4 0.5] - [-0.2 0.3 -0.1] - [-0.2 0.3 0.5] - [-0.1 0.4 0.3] - [ 0.2 0.4 0.0] - [-0.1 0.3 0.0] - [-0.1 0.3 0.1] - [-0.1 0.4 0.6] - [-0.1 0.6 0.1] - [ 0.1 0.5 0.0] - [ 0.2 0.4 0.1] - [ 0.0 0.3 0.1] - [-0.1 1.0 -0.2] - [-0.1 0.6 0.2] - [-0.2 0.8 -0.1] - [-0.3 0.2 0.1] - [ 0.2 0.5 0.1] - [-0.5 0.2 0.0] - [-0.1 0.3 0.0] - [-0.1 0.7 -0.2] - [-0.2 0.3 0.0] - [-0.3 0.3 0.0] - [-0.1 0.7 0.1] - [-0.2 0.5 0.1] - [-0.2 0.5 0.1] - [ 0.2 0.4 0.1] - [-0.3 0.4 0.1] - [-0.2 0.4 0.5] - [-0.5 0.2 0.1] - [-0.1 0.8 -0.2] - [-0.2 0.6 -0.0] - [-0.4 0.2 0.1] - [-0.2 0.6 0.2] - [ 0.2 0.3 0.0] - [-0.0 0.6 -0.0] - [-0.1 0.6 0.1] - [-0.1 0.7 -0.1] - [-0.1 0.3 -0.0] - [-0.1 0.3 0.1] - [-0.1 0.6 0.1] - [-0.2 0.5 0.2] - [-0.1 0.3 0.1] - [ 0.2 0.4 -0.0] - [-0.2 0.6 0.2] - [-0.1 0.5 0.2] - [-0.1 0.6 0.1]] +# name: TestOXDNAReading.test_comparing_topologies[top_new_custom].3 + list([ + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + ]) # --- -# name: test_read_oxdna.16 - [[ 6.8e-02 5.6e-02 4.6e-02] - [-3.6e-02 -5.9e-02 -7.2e-02] - [-1.6e-02 -6.4e-02 -7.5e-02] - [-4.0e-02 9.0e-02 -1.8e-02] - [ 6.2e-02 7.8e-02 -1.8e-03] - [ 9.7e-02 2.5e-02 1.3e-03] - [ 4.1e-02 3.0e-02 -8.6e-02] - [ 3.6e-02 -8.4e-02 -4.1e-02] - [ 9.8e-02 -1.9e-02 -7.1e-03] - [-1.8e-02 7.2e-02 6.7e-02] - [ 9.2e-02 -4.8e-03 3.9e-02] - [ 7.1e-02 -6.9e-02 -1.6e-02] - [-5.8e-03 2.3e-02 -9.7e-02] - [ 2.8e-02 -9.1e-02 -2.9e-02] - [-2.6e-03 8.7e-02 5.0e-02] - [-4.0e-02 9.0e-02 -1.8e-02] - [-9.2e-02 1.1e-02 -3.9e-02] - [-1.6e-02 -6.4e-02 -7.5e-02] - [-1.6e-02 4.5e-02 -8.8e-02] - [ 6.2e-02 7.8e-02 -1.8e-03] - [-7.8e-02 6.2e-02 1.2e-03] - [-1.8e-02 9.8e-02 -6.2e-03] - [-3.9e-06 -3.2e-02 -9.5e-02] - [ 6.5e-03 -1.5e-02 -9.9e-02] - [ 9.3e-02 2.8e-02 2.5e-02] - [-2.6e-03 8.7e-02 5.0e-02] - [-5.8e-03 2.3e-02 -9.7e-02] - [ 4.7e-02 -8.8e-02 2.6e-04] - [ 9.2e-02 -4.8e-03 3.9e-02] - [ 2.7e-02 -8.4e-02 4.8e-02] - [ 1.2e-02 -7.5e-02 -6.5e-02] - [-1.8e-02 9.8e-02 -6.2e-03] - [ 2.5e-02 -8.0e-02 -5.5e-02] - [-4.0e-02 9.0e-02 -1.8e-02] - [ 5.7e-02 7.9e-02 2.2e-02] - [-8.2e-02 -4.1e-02 -4.0e-02] - [ 3.6e-02 -8.4e-02 -4.1e-02] - [-1.8e-02 9.8e-02 -6.2e-03] - [ 2.0e-02 -7.6e-02 6.1e-02] - [-1.9e-02 7.0e-02 6.9e-02] - [-1.4e-02 7.5e-02 6.4e-02] - [-1.8e-02 2.0e-02 -9.6e-02] - [ 3.8e-02 6.0e-02 7.0e-02] - [-6.4e-02 -3.7e-02 -6.7e-02] - [-9.6e-02 1.0e-02 2.7e-02] - [-6.7e-02 -7.4e-02 -4.0e-03] - [ 9.2e-03 -2.2e-02 -9.7e-02] - [ 8.6e-02 -2.1e-02 4.6e-02] - [-7.8e-02 6.2e-02 1.2e-03] - [-8.2e-02 -4.1e-02 -4.0e-02] - [-2.5e-02 7.0e-02 -6.7e-02] - [-8.5e-03 5.9e-03 9.9e-02] - [-3.6e-02 -5.9e-02 -7.2e-02] - [ 2.8e-02 -9.1e-02 -2.9e-02] - [-7.7e-02 6.2e-02 1.3e-02] - [-8.2e-03 1.4e-02 9.9e-02] - [-9.4e-02 3.3e-02 -5.0e-03] - [-8.0e-02 6.0e-02 1.5e-03] - [-3.9e-02 5.4e-02 7.5e-02] - [-1.8e-02 9.8e-02 -6.2e-03] - [-1.8e-02 2.0e-02 -9.6e-02] - [-9.5e-02 -3.1e-02 -3.3e-03] - [-7.7e-02 3.4e-02 5.5e-02] - [ 4.2e-02 -3.8e-02 -8.3e-02] - [ 1.0e-02 8.4e-03 -9.9e-02] - [-5.8e-03 2.3e-02 -9.7e-02] - [-1.8e-02 -6.7e-02 7.2e-02] - [-8.2e-02 -4.1e-02 -4.0e-02] - [ 7.1e-02 -6.9e-02 -1.6e-02] - [-1.3e-02 8.1e-02 -5.7e-02] - [ 1.0e-02 8.4e-03 -9.9e-02] - [-1.6e-02 4.5e-02 -8.8e-02] - [-5.0e-03 -3.3e-02 9.4e-02] - [ 4.1e-02 6.7e-02 6.2e-02] - [ 6.5e-03 -1.5e-02 -9.9e-02] - [ 2.2e-02 -9.7e-02 4.7e-04] - [-1.6e-02 -6.4e-02 -7.5e-02] - [ 9.3e-02 2.8e-02 2.5e-02] - [ 9.6e-02 -6.6e-03 -2.6e-02] - [-3.9e-02 5.4e-02 7.5e-02] - [ 2.2e-02 -9.7e-02 4.7e-04] - [-7.7e-03 9.9e-02 1.4e-02] - [-2.5e-02 9.2e-02 -3.0e-02] - [ 4.1e-02 3.0e-02 -8.6e-02] - [ 3.8e-02 6.0e-02 7.0e-02] - [-1.9e-02 2.6e-02 -9.4e-02] - [ 7.9e-02 -4.1e-02 -4.6e-02] - [-4.5e-02 7.9e-02 4.0e-02] - [-9.2e-02 1.1e-02 -3.9e-02] - [ 1.8e-02 -5.2e-02 -8.3e-02] - [ 7.1e-02 -6.9e-02 -1.6e-02] - [-1.8e-02 7.2e-02 6.7e-02] - [-2.8e-02 8.0e-02 -5.4e-02] - [-9.6e-02 1.0e-02 2.7e-02] - [ 6.8e-02 5.6e-02 4.6e-02] - [-1.8e-02 9.8e-02 -6.2e-03] - [-8.5e-03 5.9e-03 9.9e-02] - [ 9.6e-02 -6.6e-03 -2.6e-02] - [-9.8e-02 -1.9e-02 -9.5e-03] - [ 1.8e-02 -5.2e-02 -8.3e-02]] +# name: TestOXDNAReading.test_comparing_topologies[top_old] + list([ + list([ + 0, + 1, + ]), + list([ + 1, + 2, + ]), + list([ + 2, + 3, + ]), + list([ + 3, + 4, + ]), + list([ + 4, + 5, + ]), + list([ + 6, + 7, + ]), + list([ + 7, + 8, + ]), + list([ + 8, + 9, + ]), + list([ + 9, + 10, + ]), + list([ + 10, + 11, + ]), + ]) # --- -# name: test_read_oxdna.17 - [[-0.0 0.1 -0.1] - [-0.1 -0.0 0.1] - [ 0.1 0.1 -0.1] - [-0.1 -0.0 0.0] - [-0.0 -0.0 -0.1] - [-0.0 0.0 -0.1] - [ 0.0 0.1 0.0] - [ 0.1 0.0 0.0] - [-0.0 -0.0 0.1] - [ 0.1 0.0 -0.0] - [ 0.0 0.0 -0.1] - [-0.1 -0.1 0.0] - [-0.1 -0.0 0.0] - [-0.1 -0.0 -0.0] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 0.0] - [ 0.0 0.1 -0.1] - [ 0.1 0.1 -0.1] - [ 0.1 0.0 -0.0] - [-0.0 -0.0 -0.1] - [ 0.0 0.0 -0.1] - [ 0.1 0.0 -0.0] - [-0.1 -0.0 0.0] - [ 0.1 0.0 0.0] - [-0.0 0.1 -0.1] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 0.0] - [ 0.1 0.0 0.1] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 -0.0] - [-0.1 -0.0 -0.0] - [ 0.1 0.0 -0.0] - [-0.1 -0.1 0.0] - [-0.1 -0.0 0.0] - [ 0.0 -0.0 0.1] - [-0.0 -0.0 0.1] - [ 0.1 0.0 0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 0.0] - [ 0.1 0.0 -0.0] - [-0.0 -0.1 0.1] - [ 0.1 0.0 -0.0] - [-0.0 -0.1 0.1] - [ 0.1 0.0 -0.1] - [ 0.0 -0.1 0.1] - [-0.0 0.0 0.1] - [-0.1 -0.0 -0.0] - [-0.0 -0.1 0.1] - [ 0.0 0.0 -0.1] - [-0.0 -0.0 0.1] - [-0.1 -0.0 0.0] - [-0.1 -0.0 -0.0] - [-0.1 -0.0 0.1] - [-0.1 -0.0 -0.0] - [ 0.0 -0.0 0.1] - [-0.1 -0.1 0.0] - [ 0.0 0.0 0.1] - [ 0.0 0.0 -0.1] - [-0.1 -0.1 0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 -0.0] - [-0.0 0.0 0.1] - [ 0.0 -0.1 0.1] - [ 0.1 0.0 0.0] - [ 0.1 0.0 0.0] - [-0.1 -0.0 0.0] - [ 0.1 0.1 0.1] - [-0.0 -0.0 0.1] - [-0.1 -0.1 0.0] - [-0.1 0.0 0.0] - [ 0.1 0.0 0.0] - [ 0.1 0.0 -0.0] - [-0.1 -0.1 -0.0] - [ 0.0 0.1 -0.1] - [ 0.1 0.0 0.0] - [ 0.1 0.0 0.0] - [ 0.1 0.1 -0.1] - [-0.0 0.1 -0.1] - [-0.0 0.1 -0.1] - [-0.1 -0.1 0.0] - [ 0.1 0.0 0.0] - [ 0.0 -0.0 0.1] - [ 0.1 0.0 -0.0] - [ 0.0 0.1 0.0] - [-0.0 -0.1 0.1] - [-0.1 0.0 0.0] - [ 0.0 0.1 -0.1] - [-0.1 -0.1 0.0] - [ 0.0 0.1 -0.1] - [ 0.0 0.1 -0.0] - [-0.1 -0.1 0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 -0.0] - [ 0.0 -0.1 0.1] - [-0.0 0.1 -0.1] - [ 0.1 0.0 -0.0] - [-0.1 -0.0 -0.0] - [-0.0 0.1 -0.1] - [ 0.0 -0.1 0.1] - [ 0.0 0.1 -0.0]] +# name: TestOXDNAReading.test_comparing_topologies[top_old].1 + list([ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ]) # --- -# name: test_read_oxdna.18 - [[-1.0e-02 6.0e-02 4.2e-03] - [ 2.0e-03 1.5e-02 6.5e-02] - [ 2.2e-02 1.9e-02 6.3e-03] - [ 5.5e-02 -3.0e-02 -2.1e-02] - [-1.0e-02 2.1e-02 1.1e-02] - [ 2.1e-02 3.4e-02 8.3e-03] - [-2.0e-02 1.3e-02 3.4e-02] - [ 8.2e-03 4.7e-03 -4.0e-02] - [ 1.9e-04 2.8e-02 3.6e-02] - [-1.5e-02 2.1e-02 2.7e-02] - [-1.6e-02 -5.1e-03 1.2e-02] - [ 2.4e-02 -2.8e-02 3.3e-04] - [-1.3e-02 8.6e-03 2.8e-02] - [-5.4e-04 4.0e-02 -1.4e-02] - [ 8.4e-03 -1.5e-02 -2.7e-02] - [ 5.5e-02 -3.0e-02 -2.1e-02] - [ 1.0e-02 1.1e-02 -1.5e-02] - [ 2.2e-02 1.9e-02 6.3e-03] - [ 1.4e-02 3.0e-02 -3.1e-02] - [-1.0e-02 2.1e-02 1.1e-02] - [-1.5e-02 3.7e-02 1.0e-02] - [ 1.4e-02 4.2e-02 2.6e-02] - [ 2.2e-02 1.5e-02 1.4e-02] - [-4.7e-03 -9.1e-03 -3.0e-02] - [ 2.9e-02 9.3e-04 1.7e-02] - [ 8.4e-03 -1.5e-02 -2.7e-02] - [-1.3e-02 8.6e-03 2.8e-02] - [ 3.8e-02 2.9e-02 -1.4e-02] - [-1.6e-02 -5.1e-03 1.2e-02] - [-1.8e-03 -3.2e-02 3.8e-03] - [ 2.9e-02 5.6e-03 1.3e-03] - [ 1.4e-02 4.2e-02 2.6e-02] - [-3.2e-02 3.3e-02 -2.0e-02] - [ 5.5e-02 -3.0e-02 -2.1e-02] - [ 3.0e-03 2.6e-02 2.3e-02] - [-1.2e-02 3.3e-03 1.9e-03] - [ 8.2e-03 4.7e-03 -4.0e-02] - [ 1.4e-02 4.2e-02 2.6e-02] - [-2.4e-02 -2.9e-02 -1.2e-02] - [-1.7e-02 4.3e-03 -7.8e-02] - [ 3.8e-02 2.7e-02 1.1e-01] - [-4.8e-02 6.6e-02 -1.7e-02] - [-2.8e-02 -6.7e-02 1.9e-03] - [-4.9e-03 1.8e-02 4.4e-05] - [ 1.3e-02 -1.7e-02 -1.8e-02] - [ 9.5e-03 1.7e-02 1.3e-02] - [ 9.9e-03 2.4e-02 1.7e-02] - [-7.7e-03 4.0e-02 5.0e-04] - [-1.5e-02 3.7e-02 1.0e-02] - [-1.2e-02 3.3e-03 1.9e-03] - [-3.1e-02 -7.3e-03 -2.0e-02] - [-5.6e-02 4.8e-02 4.7e-02] - [ 2.0e-03 1.5e-02 6.5e-02] - [-5.4e-04 4.0e-02 -1.4e-02] - [-1.9e-03 -9.6e-04 -1.0e-02] - [ 3.2e-04 1.1e-02 -3.1e-02] - [-3.6e-02 -3.1e-03 5.8e-03] - [-2.5e-04 -2.2e-02 3.5e-02] - [ 4.6e-03 -1.7e-02 1.3e-02] - [ 1.4e-02 4.2e-02 2.6e-02] - [-4.8e-02 6.6e-02 -1.7e-02] - [ 1.8e-02 -8.6e-03 -5.4e-02] - [ 3.1e-02 2.5e-02 1.7e-02] - [-4.4e-02 -3.5e-02 -5.4e-02] - [ 6.2e-02 4.2e-03 2.4e-02] - [-1.3e-02 8.6e-03 2.8e-02] - [ 1.6e-02 -7.0e-03 2.8e-02] - [-1.2e-02 3.3e-03 1.9e-03] - [ 2.4e-02 -2.8e-02 3.3e-04] - [-3.3e-03 -5.2e-02 6.3e-03] - [ 6.2e-02 4.2e-03 2.4e-02] - [ 1.4e-02 3.0e-02 -3.1e-02] - [ 1.7e-02 3.8e-02 -1.2e-03] - [ 1.4e-02 3.6e-02 -1.2e-02] - [-4.7e-03 -9.1e-03 -3.0e-02] - [ 4.1e-03 -1.6e-02 -4.5e-02] - [ 2.2e-02 1.9e-02 6.3e-03] - [ 2.9e-02 9.3e-04 1.7e-02] - [ 7.9e-04 2.7e-02 2.7e-02] - [ 4.6e-03 -1.7e-02 1.3e-02] - [ 4.1e-03 -1.6e-02 -4.5e-02] - [ 2.0e-02 -5.2e-02 1.8e-02] - [ 5.0e-02 -2.7e-02 -2.0e-02] - [-2.0e-02 1.3e-02 3.4e-02] - [-2.8e-02 -6.7e-02 1.9e-03] - [-2.3e-02 -3.0e-02 5.5e-03] - [ 1.9e-02 5.0e-02 -3.5e-02] - [ 2.7e-03 -1.4e-02 -1.1e-03] - [ 1.0e-02 1.1e-02 -1.5e-02] - [ 7.1e-03 6.9e-02 -4.1e-02] - [ 2.4e-02 -2.8e-02 3.3e-04] - [-1.5e-02 2.1e-02 2.7e-02] - [-1.4e-03 1.2e-02 -4.1e-02] - [ 1.3e-02 -1.7e-02 -1.8e-02] - [-1.0e-02 6.0e-02 4.2e-03] - [ 1.4e-02 4.2e-02 2.6e-02] - [-5.6e-02 4.8e-02 4.7e-02] - [ 7.9e-04 2.7e-02 2.7e-02] - [ 1.9e-03 9.0e-03 3.5e-02] - [ 7.1e-03 6.9e-02 -4.1e-02]] +# name: TestOXDNAReading.test_comparing_topologies[top_old].2 + list([ + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 1.0, + 2.0, + 2.0, + 2.0, + 2.0, + 2.0, + 2.0, + ]) # --- -# name: test_read_oxdna.19 - [[ 0.1 -0.1 -0.1] - [ 0.2 0.0 0.1] - [ 0.5 -0.0 -0.2] - [ 0.0 -0.6 0.4] - [ 0.0 0.3 0.2] - [-0.7 -0.0 0.0] - [-0.3 0.0 0.5] - [ 0.3 0.1 0.6] - [ 0.2 0.5 0.4] - [ 0.1 -0.2 0.6] - [-0.3 0.5 0.1] - [ 0.3 0.1 -0.1] - [ 0.0 0.0 0.2] - [-0.0 -0.3 -0.1] - [-0.6 0.1 -0.6] - [ 0.0 -0.6 0.4] - [ 0.1 0.5 -0.0] - [ 0.5 -0.0 -0.2] - [ 0.5 0.1 0.1] - [ 0.0 0.3 0.2] - [ 0.1 -0.3 0.0] - [-0.1 0.1 0.4] - [ 0.2 -0.1 0.4] - [ 0.7 -0.1 0.5] - [-0.3 -0.0 -0.3] - [-0.6 0.1 -0.6] - [ 0.0 0.0 0.2] - [-0.2 -0.1 -0.2] - [-0.3 0.5 0.1] - [ 0.1 0.1 0.2] - [ 0.3 0.3 0.5] - [-0.1 0.1 0.4] - [-0.1 -0.1 0.3] - [ 0.0 -0.6 0.4] - [-0.0 -0.2 0.1] - [-0.2 -0.1 0.0] - [ 0.3 0.1 0.6] - [-0.1 0.1 0.4] - [-0.3 0.7 0.1] - [-0.2 -0.1 -0.5] - [-0.0 -0.5 0.5] - [-0.5 0.0 0.1] - [ 0.7 -0.4 0.4] - [-0.6 0.1 -0.1] - [ 0.0 0.3 -0.6] - [ 0.0 0.3 0.0] - [ 0.1 0.2 0.7] - [ 0.1 -0.1 -0.2] - [ 0.1 -0.3 0.0] - [-0.2 -0.1 0.0] - [-0.3 -0.4 0.2] - [-0.3 -0.1 -0.1] - [ 0.2 0.0 0.1] - [-0.0 -0.3 -0.1] - [-0.1 0.0 0.2] - [ 0.1 0.4 -0.4] - [-0.3 -0.3 -0.2] - [ 0.2 0.2 0.3] - [ 0.0 0.5 -0.1] - [-0.1 0.1 0.4] - [-0.5 0.0 0.1] - [ 0.3 0.2 0.2] - [ 0.1 -0.2 0.0] - [ 0.0 -0.0 0.7] - [ 0.1 0.8 -0.3] - [ 0.0 0.0 0.2] - [-0.3 -0.4 -0.3] - [-0.2 -0.1 0.0] - [ 0.3 0.1 -0.1] - [ 0.3 -0.0 -0.3] - [ 0.1 0.8 -0.3] - [ 0.5 0.1 0.1] - [ 0.0 0.2 0.4] - [ 0.2 -0.3 0.5] - [ 0.7 -0.1 0.5] - [ 0.1 -0.5 0.2] - [ 0.5 -0.0 -0.2] - [-0.3 -0.0 -0.3] - [-0.3 0.6 0.5] - [ 0.0 0.5 -0.1] - [ 0.1 -0.5 0.2] - [ 0.4 0.3 -0.4] - [ 0.2 -0.2 0.0] - [-0.3 0.0 0.5] - [ 0.7 -0.4 0.4] - [-0.2 -0.4 0.1] - [-0.1 -0.5 -0.0] - [ 0.3 -0.4 0.2] - [ 0.1 0.5 -0.0] - [ 0.3 -0.2 0.0] - [ 0.3 0.1 -0.1] - [ 0.1 -0.2 0.6] - [-0.1 0.5 0.4] - [ 0.0 0.3 -0.6] - [ 0.1 -0.1 -0.1] - [-0.1 0.1 0.4] - [-0.3 -0.1 -0.1] - [-0.3 0.6 0.5] - [-0.1 0.4 0.3] - [ 0.3 -0.2 0.0]] +# name: TestOXDNAReading.test_comparing_topologies[top_old].3 + list([ + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + 42, + ]) # --- -# name: test_read_oxdna.2 - [[0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.7 0.8 0.4 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.5 0.8 0.0] - [0.4 0.8 0.5 0.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.5 0.8 0.0] - [0.8 0.4 0.4 0.0] - [0.4 0.8 0.5 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.7 0.8 0.4 0.0] - [0.4 0.8 0.5 0.0]] +# name: TestOXDNAReading.test_univ_snapshot + [[-2.7e-03 3.5e-03 6.1e-03] + [-2.8e-03 3.7e-03 5.7e-03] + [-2.8e-03 4.0e-03 5.3e-03] + [-2.7e-03 4.3e-03 5.0e-03] + [-2.3e-03 4.6e-03 4.6e-03] + [-1.9e-03 4.6e-03 4.3e-03] + [-1.5e-03 4.5e-03 4.0e-03] + [-1.4e-03 4.4e-03 3.4e-03] + [-1.4e-03 4.2e-03 3.0e-03] + [-1.6e-03 4.1e-03 2.5e-03] + [-1.9e-03 4.2e-03 2.0e-03] + [-1.6e-03 3.0e-03 9.0e-04] + [-1.2e-03 2.8e-03 7.2e-04] + [-7.7e-04 2.8e-03 4.1e-04] + [-4.2e-04 3.0e-03 8.1e-05] + [-1.3e-04 3.4e-03 -1.3e-04] + [ 1.4e-04 3.8e-03 -1.6e-04] + [ 5.4e-04 4.2e-03 -1.9e-05] + [ 7.2e-04 4.4e-03 3.7e-04] + [ 1.1e-03 4.6e-03 7.6e-04] + [ 1.4e-03 4.5e-03 1.1e-03] + [ 1.9e-03 4.5e-03 1.2e-03] + [ 2.1e-03 4.4e-03 5.7e-05] + [ 1.8e-03 4.0e-03 1.1e-04] + [ 1.6e-03 3.7e-03 3.2e-04] + [ 1.2e-03 3.4e-03 5.9e-04] + [ 7.4e-04 3.4e-03 8.6e-04] + [ 2.4e-04 3.5e-03 1.0e-03] + [-1.8e-04 3.7e-03 1.0e-03] + [-6.2e-04 3.9e-03 8.5e-04] + [-9.7e-04 4.0e-03 3.9e-04] + [-1.5e-03 3.8e-03 8.9e-05] + [-1.7e-03 3.4e-03 -1.7e-04] + [-2.1e-03 3.0e-03 -2.2e-04] + [-2.3e-03 2.5e-03 -5.8e-06] + [-2.7e-03 2.3e-03 3.2e-04] + [-3.2e-03 2.3e-03 6.7e-04] + [-3.5e-03 2.5e-03 1.0e-03] + [-4.0e-03 2.8e-03 1.0e-03] + [-4.6e-03 2.9e-03 9.7e-04] + [-5.1e-03 2.9e-03 6.9e-04] + [-5.4e-03 2.8e-03 3.4e-04] + [-5.8e-03 2.5e-03 5.3e-05] + [-6.0e-03 2.0e-03 -1.2e-04] + [-6.0e-03 2.0e-03 1.1e-03] + [-5.5e-03 1.8e-03 9.9e-04] + [-5.1e-03 1.7e-03 7.3e-04] + [-4.7e-03 1.8e-03 4.0e-04] + [-4.3e-03 2.1e-03 1.1e-04] + [-4.1e-03 2.5e-03 -1.5e-04] + [-3.7e-03 2.9e-03 -2.3e-04] + [-3.3e-03 3.3e-03 -3.4e-05] + [-3.0e-03 3.5e-03 3.7e-04] + [-2.6e-03 3.4e-03 7.2e-04] + [-2.1e-03 3.2e-03 9.3e-04] + [-2.1e-03 4.6e-03 1.6e-03] + [-2.2e-03 5.1e-03 1.4e-03] + [-2.3e-03 5.5e-03 1.4e-03] + [-2.1e-03 6.1e-03 1.3e-03] + [-1.7e-03 6.5e-03 1.2e-03] + [-1.4e-03 6.7e-03 8.6e-04] + [-9.9e-04 6.7e-03 5.3e-04] + [-6.8e-04 6.8e-03 8.2e-05] + [-6.4e-04 6.8e-03 -4.7e-04] + [-7.8e-04 6.9e-03 -9.7e-04] + [-9.4e-04 7.1e-03 -1.4e-03] + [-1.0e-03 7.6e-03 -1.6e-03] + [-8.0e-04 8.0e-03 -1.8e-03] + [-1.6e-03 8.9e-03 -1.9e-03] + [-1.4e-03 8.2e-03 -2.6e-03] + [-1.8e-03 8.4e-03 -3.2e-03] + [-1.4e-03 8.4e-03 -3.1e-03] + [-9.0e-04 8.3e-03 -2.9e-03] + [-6.0e-04 8.7e-03 -2.7e-03] + [-6.2e-04 9.1e-03 -2.5e-03] + [-5.5e-04 9.3e-03 -2.0e-03] + [-6.2e-04 7.9e-03 -6.4e-04] + [-1.0e-03 7.9e-03 -4.1e-04] + [-1.5e-03 7.5e-03 -3.7e-04] + [-1.8e-03 7.0e-03 -3.9e-04] + [-1.8e-03 6.5e-03 -1.8e-04] + [-1.7e-03 6.0e-03 -3.9e-05] + [-1.5e-03 5.7e-03 2.3e-04] + [-1.2e-03 5.6e-03 6.1e-04] + [-1.1e-03 5.4e-03 1.1e-03] + [-1.1e-03 5.3e-03 1.6e-03] + [-1.2e-03 5.2e-03 2.1e-03] + [-1.5e-03 5.2e-03 2.5e-03] + [-2.0e-03 5.2e-03 2.8e-03] + [-2.3e-03 4.9e-03 3.0e-03] + [-2.6e-03 4.5e-03 3.4e-03] + [-2.6e-03 4.0e-03 3.7e-03] + [-2.4e-03 3.6e-03 4.1e-03] + [-2.1e-03 3.5e-03 4.4e-03] + [-1.8e-03 3.5e-03 4.8e-03] + [-1.7e-03 3.7e-03 5.3e-03] + [-1.7e-03 4.1e-03 5.7e-03] + [-1.9e-03 4.4e-03 6.1e-03]] # --- -# name: test_read_oxdna.20 - [ True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True] +# name: TestOXDNAReading.test_univ_snapshot.1 + ['C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' + 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' + 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' + 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' + 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C' + 'C' 'C' 'C' 'C' 'C' 'C' 'C' 'C'] # --- -# name: test_read_oxdna.21 - [[1985 1986] - [1386 1387] - [2062 2066] - [ 189 195] - [1142 1146] - [1902 1903] - [ 507 508] - [ 24 25] - [ 6 12] - [ 374 380] - [1630 1631] - [1422 1423] - [1102 1106] - [1895 1892] - [1825 1826] - [ 836 840] - [ 692 693] - [1922 1923] - [ 34 40] - [ 552 553] - [1154 1155] - [2008 2009] - [ 373 374] - [1813 1814] - [ 951 948] - [1288 1289] - [1292 1293] - [1681 1682] - [ 133 134] - [ 352 353] - [1359 1356] - [1331 1328] - [1729 1730] - [2017 2018] - [1809 1810] - [ 523 524] - [1631 1628] - [2014 2015] - [1486 1487] - [1692 1693] - [ 244 250] - [2126 2127] - [ 979 976] - [ 734 738] - [ 245 251] - [ 807 811] - [2005 2006] - [ 939 936] - [2016 2017] - [ 461 456] - [1035 1032] - [ 132 133] - [1882 1883] - [ 369 370] - [1734 1735] - [1552 1553] - [1994 1995] - [ 612 616] - [ 147 148] - [ 61 62] - [1426 1427] - [ 384 385] - [2079 2083] - [1608 1609] - [ 804 805] - [1149 1150] - [2094 2095] - [ 355 356] - [1224 1225] - [1390 1394] - [1580 1581] - [1726 1727] - [2019 2016] - [1195 1192] - [ 71 77] - [1550 1551] - [ 804 808] - [ 485 491] - [1460 1464] - [ 992 993] - [ 650 651] - [ 795 792] - [1429 1430] - [ 237 238] - [ 161 167] - [1184 1185] - [1671 1675] - [1255 1252] - [ 377 372] - [ 226 227] - [1479 1483] - [ 533 528] - [ 671 675] - [1781 1785] - [ 365 360] - [ 855 859] - [1141 1142] - [ 564 570] - [ 373 379] - [1450 1451]] +# name: TestOXDNAReading.test_univ_snapshot.2 + [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] # --- -# name: test_read_oxdna.22 - [ True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True] -# --- -# name: test_read_oxdna.23 - [ True True True False True True False False False False True True - True True True True True True False False True True False True - True True True True False False True True True True True False - True True True False True True True False True True True False - True True False True True True True False False True False True - True True True True False True True True True True True False - True True False True True True True True False False True True - True False False True False True True False True True False False - True False True True] -# --- -# name: test_read_oxdna.3 - [[-0.2 0.5 0.6] - [-0.1 0.3 0.0] - [-0.1 0.6 0.0] - [-0.6 0.2 0.1] - [-0.1 0.4 0.4] - [-0.3 0.3 0.6] - [ 0.2 0.3 0.1] - [-0.2 0.6 -0.1] - [-0.0 0.6 -0.1] - [-0.2 0.3 0.1] - [-0.3 0.5 0.5] - [-0.5 0.1 0.1] - [-0.1 0.6 0.1] - [-0.2 0.3 -0.1] - [-0.1 0.8 -0.3] - [-0.3 0.3 0.3] - [-0.2 0.3 0.4] - [ 0.0 0.4 -0.0] - [-0.2 0.3 -0.1] - [-0.1 0.4 0.5] - [-0.6 0.1 0.1] - [-0.0 0.4 -0.1] - [-0.1 0.8 -0.3] - [-0.3 0.6 0.2] - [-0.0 0.4 -0.0] - [-0.0 0.6 0.1] - [-0.1 0.8 -0.2] - [-0.6 0.2 -0.0] - [-0.1 1.0 -0.2] - [-0.1 0.4 0.5] - [-0.2 0.3 -0.0] - [-0.4 0.3 -0.0] - [-0.0 0.4 -0.0] - [-0.1 0.4 0.3] - [-0.2 0.2 0.0] - [-0.0 0.7 0.1] - [-0.1 0.6 0.1] - [-0.2 0.3 -0.1] - [-0.2 0.6 0.2] - [-0.1 0.6 0.2] - [-0.2 0.5 0.5] - [-0.2 0.3 0.5] - [-0.5 0.3 -0.0] - [-0.1 0.9 -0.3] - [-0.3 0.4 -0.0] - [-0.1 0.7 0.1] - [ 0.1 0.5 0.2] - [-0.0 0.4 -0.1] - [-0.1 0.6 0.2] - [-0.3 0.5 0.3] - [-0.2 0.3 -0.1] - [ 0.1 0.5 0.1] - [-0.5 0.1 0.1] - [-0.3 0.3 0.1] - [-0.2 0.3 -0.0] - [-0.1 0.6 -0.1] - [-0.1 0.6 -0.0] - [-0.4 0.3 0.1] - [ 0.2 0.4 0.0] - [-0.3 0.2 0.1] - [-0.3 0.4 0.5] - [-0.1 0.3 -0.1] - [-0.0 0.4 0.1] - [-0.3 0.5 0.6] - [-0.2 0.5 0.2] - [-0.3 0.4 0.1] - [-0.1 0.6 -0.1] - [-0.1 0.7 -0.1] - [-0.1 0.8 -0.2] - [-0.4 0.3 -0.0] - [ 0.2 0.4 0.2] - [-0.1 0.4 0.5] - [-0.2 0.4 0.2] - [-0.2 0.4 -0.0] - [-0.1 0.8 -0.3] - [-0.1 0.8 -0.2] - [-0.0 0.4 -0.0] - [-0.1 0.6 0.1] - [-0.3 0.3 0.1] - [ 0.1 0.4 0.1] - [-0.2 0.9 -0.2] - [-0.1 0.6 0.1] - [-0.1 0.4 0.3] - [-0.1 0.9 -0.0] - [-0.4 0.4 0.0] - [-0.1 0.3 0.5] - [-0.1 1.0 -0.3] - [-0.2 0.3 0.4] - [-0.2 0.5 0.3] - [-0.1 0.6 0.1] - [-0.2 0.8 -0.2] - [-0.2 0.8 -0.4] - [-0.1 0.3 -0.0] - [-0.3 0.5 0.3] - [-0.1 0.4 0.4] - [-0.6 0.1 0.1] - [-0.3 0.2 0.1] - [-0.5 0.3 0.1] - [ 0.1 0.3 0.1] - [-0.1 0.7 0.1]] -# --- -# name: test_read_oxdna.4 - [[-6.7e-02 -7.4e-02 -4.0e-03] - [-1.8e-02 9.8e-02 -6.2e-03] - [-1.4e-02 7.5e-02 6.4e-02] - [-1.3e-04 2.0e-03 -1.0e-01] - [-9.0e-02 -3.5e-02 -2.7e-02] - [ 6.2e-02 7.8e-02 -1.8e-03] - [-4.5e-02 7.9e-02 4.0e-02] - [ 7.7e-02 2.4e-02 6.0e-02] - [-7.8e-02 6.2e-02 1.2e-03] - [ 6.5e-03 -1.5e-02 -9.9e-02] - [ 6.2e-02 -7.7e-02 -1.2e-02] - [-2.5e-02 9.2e-02 -3.0e-02] - [-7.7e-02 3.4e-02 5.5e-02] - [-8.2e-03 1.4e-02 9.9e-02] - [ 5.9e-03 1.0e-01 6.9e-04] - [ 9.1e-02 3.5e-02 2.1e-02] - [ 5.7e-02 7.9e-02 2.2e-02] - [ 1.2e-02 -2.3e-02 9.7e-02] - [-5.0e-03 -3.3e-02 9.4e-02] - [-7.7e-02 6.2e-02 1.3e-02] - [-1.6e-02 4.5e-02 -8.8e-02] - [-4.2e-03 3.5e-02 9.4e-02] - [-5.3e-02 7.7e-02 3.6e-02] - [ 9.6e-02 -6.6e-03 -2.6e-02] - [-4.2e-03 3.5e-02 9.4e-02] - [-6.4e-02 -3.7e-02 -6.7e-02] - [ 4.1e-02 3.0e-02 -8.6e-02] - [ 2.9e-02 -6.1e-02 7.3e-02] - [ 4.7e-02 -8.8e-02 2.6e-04] - [-9.4e-02 3.3e-02 -5.0e-03] - [-8.2e-03 1.4e-02 9.9e-02] - [ 1.5e-02 9.5e-03 9.8e-02] - [ 1.2e-02 -2.3e-02 9.7e-02] - [-9.8e-02 1.6e-02 -1.2e-02] - [-2.3e-02 7.4e-02 6.4e-02] - [-6.4e-02 -3.7e-02 -6.7e-02] - [-7.7e-02 3.4e-02 5.5e-02] - [-8.2e-03 1.4e-02 9.9e-02] - [-3.0e-02 -8.4e-02 -4.5e-02] - [-9.8e-02 -1.9e-02 -9.5e-03] - [ 2.6e-02 -9.6e-02 -4.9e-03] - [-7.7e-03 9.9e-02 1.4e-02] - [ 2.4e-02 -9.2e-02 3.2e-02] - [-6.7e-02 2.3e-03 7.4e-02] - [ 2.0e-02 -7.6e-02 6.1e-02] - [-1.6e-02 -6.4e-02 -7.5e-02] - [ 4.2e-02 -3.8e-02 -8.3e-02] - [-4.2e-03 3.5e-02 9.4e-02] - [-9.8e-02 -1.9e-02 -9.5e-03] - [ 7.9e-02 -6.1e-02 -8.3e-03] - [-8.2e-03 1.4e-02 9.9e-02] - [ 3.6e-02 -8.4e-02 -4.1e-02] - [-1.6e-02 4.5e-02 -8.8e-02] - [ 2.9e-02 -6.0e-02 -7.4e-02] - [-8.2e-03 1.4e-02 9.9e-02] - [-2.6e-03 8.7e-02 5.0e-02] - [-1.4e-02 7.5e-02 6.4e-02] - [-3.9e-06 -3.2e-02 -9.5e-02] - [-3.9e-02 5.4e-02 7.5e-02] - [-1.8e-02 9.8e-02 7.5e-04] - [ 9.3e-02 -3.5e-02 -9.2e-03] - [-5.0e-03 -3.3e-02 9.4e-02] - [ 9.2e-03 -2.2e-02 -9.7e-02] - [ 9.3e-02 -3.5e-02 -9.2e-03] - [ 9.3e-02 2.8e-02 2.5e-02] - [ 2.2e-02 -9.7e-02 4.7e-04] - [-7.8e-02 6.2e-02 1.2e-03] - [-2.6e-03 8.7e-02 5.0e-02] - [ 9.2e-02 -4.8e-03 3.9e-02] - [ 1.5e-02 9.5e-03 9.8e-02] - [ 1.0e-02 8.4e-03 -9.9e-02] - [-9.4e-02 3.3e-02 -5.0e-03] - [-1.9e-02 9.5e-02 2.5e-02] - [ 2.7e-02 -8.4e-02 4.8e-02] - [-5.3e-02 7.7e-02 3.6e-02] - [ 6.3e-02 -7.8e-02 -2.8e-03] - [ 1.2e-02 -2.3e-02 9.7e-02] - [-7.7e-02 3.4e-02 5.5e-02] - [-1.9e-02 2.6e-02 -9.4e-02] - [ 4.2e-02 -3.8e-02 -8.3e-02] - [ 5.3e-02 8.1e-02 2.4e-02] - [-7.7e-02 3.4e-02 5.5e-02] - [-9.8e-02 1.6e-02 -1.2e-02] - [-3.6e-02 -5.9e-02 -7.2e-02] - [ 2.0e-02 -7.6e-02 6.1e-02] - [-7.7e-02 6.2e-02 1.3e-02] - [-1.8e-02 -6.7e-02 7.2e-02] - [-7.7e-03 9.9e-02 1.4e-02] - [ 3.0e-02 -9.0e-02 -3.1e-02] - [-7.7e-02 3.4e-02 5.5e-02] - [ 9.2e-02 -4.8e-03 3.9e-02] - [ 5.9e-03 1.0e-01 6.9e-04] - [-5.0e-03 -3.3e-02 9.4e-02] - [ 7.9e-02 -6.1e-02 -8.3e-03] - [-9.0e-02 -3.5e-02 -2.7e-02] - [-1.3e-04 2.0e-03 -1.0e-01] - [-1.3e-02 8.1e-02 -5.7e-02] - [ 2.8e-02 -9.1e-02 -2.9e-02] - [-4.0e-02 9.0e-02 -1.8e-02] - [-1.6e-02 -6.4e-02 -7.5e-02]] -# --- -# name: test_read_oxdna.5 - [[-0.0 0.0 0.1] - [ 0.1 0.0 -0.0] - [-0.0 -0.1 0.1] - [ 0.1 0.0 0.0] - [ 0.0 0.0 -0.1] - [-0.0 -0.0 -0.1] - [-0.1 -0.1 0.0] - [-0.0 -0.1 0.1] - [ 0.0 0.0 -0.1] - [ 0.1 0.0 0.0] - [ 0.0 0.0 -0.1] - [ 0.1 0.0 -0.0] - [ 0.0 -0.1 0.1] - [-0.1 -0.1 0.0] - [ 0.1 -0.0 0.1] - [-0.0 -0.0 0.1] - [ 0.0 -0.0 0.1] - [ 0.1 0.0 -0.0] - [-0.1 -0.1 -0.0] - [ 0.0 -0.0 0.1] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 0.1] - [-0.0 0.1 -0.1] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 -0.1] - [ 0.0 0.1 0.0] - [-0.1 -0.0 -0.0] - [ 0.1 0.0 0.1] - [ 0.0 0.0 0.1] - [-0.1 -0.1 0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 -0.0] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 0.0] - [ 0.1 0.0 -0.1] - [ 0.0 -0.1 0.1] - [-0.1 -0.1 0.0] - [-0.0 -0.0 0.1] - [ 0.0 -0.1 0.1] - [ 0.0 0.0 -0.1] - [ 0.0 -0.0 0.1] - [-0.1 -0.0 -0.0] - [ 0.1 0.0 0.1] - [ 0.1 0.0 0.0] - [ 0.1 0.1 -0.1] - [ 0.1 0.0 0.0] - [ 0.1 0.0 -0.0] - [ 0.0 -0.1 0.1] - [-0.0 -0.0 0.1] - [-0.1 -0.1 0.0] - [ 0.1 0.0 0.0] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 0.0] - [-0.1 -0.1 0.0] - [ 0.0 0.0 -0.1] - [-0.0 -0.1 0.1] - [-0.1 -0.0 0.0] - [-0.1 -0.1 0.0] - [-0.1 -0.0 0.0] - [-0.0 0.0 -0.1] - [-0.1 -0.1 -0.0] - [-0.1 -0.0 -0.0] - [-0.0 0.0 -0.1] - [-0.0 0.1 -0.1] - [ 0.1 0.0 0.0] - [ 0.0 0.0 -0.1] - [ 0.0 0.0 -0.1] - [ 0.0 0.0 -0.1] - [ 0.1 0.0 -0.0] - [ 0.1 0.0 0.0] - [ 0.0 0.0 0.1] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 -0.0] - [ 0.1 0.0 0.1] - [ 0.1 0.0 -0.1] - [ 0.1 0.0 -0.0] - [ 0.0 -0.1 0.1] - [-0.1 0.0 0.0] - [ 0.1 0.0 0.0] - [ 0.1 -0.0 -0.0] - [ 0.0 -0.1 0.1] - [ 0.0 0.0 -0.1] - [-0.1 -0.0 0.1] - [ 0.1 0.0 0.0] - [ 0.0 -0.0 0.1] - [ 0.1 0.1 0.1] - [ 0.0 -0.0 0.1] - [-0.0 -0.0 0.1] - [ 0.0 -0.1 0.1] - [ 0.0 0.0 -0.1] - [ 0.1 -0.0 0.1] - [-0.1 -0.1 -0.0] - [-0.0 -0.0 0.1] - [ 0.0 0.0 -0.1] - [ 0.1 0.0 0.0] - [-0.1 0.0 0.0] - [-0.1 -0.0 -0.0] - [-0.1 -0.0 0.0] - [ 0.1 0.1 -0.1]] -# --- -# name: test_read_oxdna.6 - [[ 9.5e-03 1.7e-02 1.3e-02] - [ 1.4e-02 4.2e-02 2.6e-02] - [ 3.8e-02 2.7e-02 1.1e-01] - [ 1.8e-02 -1.1e-02 5.3e-03] - [ 3.3e-02 -5.0e-02 1.6e-02] - [-1.0e-02 2.1e-02 1.1e-02] - [ 2.7e-03 -1.4e-02 -1.1e-03] - [-1.0e-02 -6.8e-02 4.5e-03] - [-1.5e-02 3.7e-02 1.0e-02] - [-4.7e-03 -9.1e-03 -3.0e-02] - [ 5.3e-02 2.6e-02 -1.1e-02] - [ 5.0e-02 -2.7e-02 -2.0e-02] - [ 3.1e-02 2.5e-02 1.7e-02] - [ 3.2e-04 1.1e-02 -3.1e-02] - [ 1.0e-02 2.4e-02 3.0e-03] - [-5.5e-03 -7.8e-03 2.2e-03] - [ 3.0e-03 2.6e-02 2.3e-02] - [-6.1e-03 1.8e-02 1.6e-03] - [ 1.7e-02 3.8e-02 -1.2e-03] - [-1.9e-03 -9.6e-04 -1.0e-02] - [ 1.4e-02 3.0e-02 -3.1e-02] - [ 5.5e-02 2.7e-02 -1.6e-03] - [ 4.8e-02 -5.3e-03 -1.5e-02] - [ 7.9e-04 2.7e-02 2.7e-02] - [ 5.5e-02 2.7e-02 -1.6e-03] - [-4.9e-03 1.8e-02 4.4e-05] - [-2.0e-02 1.3e-02 3.4e-02] - [ 5.2e-03 -2.5e-02 -9.8e-03] - [ 3.8e-02 2.9e-02 -1.4e-02] - [-3.6e-02 -3.1e-03 5.8e-03] - [ 3.2e-04 1.1e-02 -3.1e-02] - [ 5.9e-03 1.9e-02 4.2e-02] - [-6.1e-03 1.8e-02 1.6e-03] - [-2.2e-02 -1.9e-02 6.9e-02] - [ 7.2e-02 -3.0e-02 -1.7e-02] - [-4.9e-03 1.8e-02 4.4e-05] - [ 3.1e-02 2.5e-02 1.7e-02] - [ 3.2e-04 1.1e-02 -3.1e-02] - [-7.3e-02 1.3e-02 -2.1e-02] - [ 1.9e-03 9.0e-03 3.5e-02] - [-5.7e-04 3.9e-03 -1.7e-02] - [ 2.0e-02 -5.2e-02 1.8e-02] - [ 3.0e-02 1.9e-02 -2.1e-04] - [ 1.7e-02 5.7e-04 6.4e-02] - [-2.4e-02 -2.9e-02 -1.2e-02] - [ 2.2e-02 1.9e-02 6.3e-03] - [-4.4e-02 -3.5e-02 -5.4e-02] - [ 5.5e-02 2.7e-02 -1.6e-03] - [ 1.9e-03 9.0e-03 3.5e-02] - [-1.3e-02 -1.3e-02 -3.7e-02] - [ 3.2e-04 1.1e-02 -3.1e-02] - [ 8.2e-03 4.7e-03 -4.0e-02] - [ 1.4e-02 3.0e-02 -3.1e-02] - [-2.3e-02 2.3e-02 1.6e-02] - [ 3.2e-04 1.1e-02 -3.1e-02] - [ 8.4e-03 -1.5e-02 -2.7e-02] - [ 3.8e-02 2.7e-02 1.1e-01] - [ 2.2e-02 1.5e-02 1.4e-02] - [ 4.6e-03 -1.7e-02 1.3e-02] - [ 6.3e-02 3.8e-02 5.4e-02] - [-3.9e-02 -9.4e-03 -3.1e-02] - [ 1.7e-02 3.8e-02 -1.2e-03] - [ 9.9e-03 2.4e-02 1.7e-02] - [-3.9e-02 -9.4e-03 -3.1e-02] - [ 2.9e-02 9.3e-04 1.7e-02] - [ 4.1e-03 -1.6e-02 -4.5e-02] - [-1.5e-02 3.7e-02 1.0e-02] - [ 8.4e-03 -1.5e-02 -2.7e-02] - [-1.6e-02 -5.1e-03 1.2e-02] - [ 5.9e-03 1.9e-02 4.2e-02] - [ 6.2e-02 4.2e-03 2.4e-02] - [-3.6e-02 -3.1e-03 5.8e-03] - [ 1.7e-02 -3.6e-02 -1.8e-02] - [-1.8e-03 -3.2e-02 3.8e-03] - [ 4.8e-02 -5.3e-03 -1.5e-02] - [-1.5e-02 3.4e-02 4.0e-02] - [-6.1e-03 1.8e-02 1.6e-03] - [ 3.1e-02 2.5e-02 1.7e-02] - [-2.3e-02 -3.0e-02 5.5e-03] - [-4.4e-02 -3.5e-02 -5.4e-02] - [-1.1e-02 -1.8e-02 -1.0e-02] - [ 3.1e-02 2.5e-02 1.7e-02] - [-2.2e-02 -1.9e-02 6.9e-02] - [ 2.0e-03 1.5e-02 6.5e-02] - [-2.4e-02 -2.9e-02 -1.2e-02] - [-1.9e-03 -9.6e-04 -1.0e-02] - [ 1.6e-02 -7.0e-03 2.8e-02] - [ 2.0e-02 -5.2e-02 1.8e-02] - [-2.1e-02 1.1e-02 4.4e-02] - [ 3.1e-02 2.5e-02 1.7e-02] - [-1.6e-02 -5.1e-03 1.2e-02] - [ 1.0e-02 2.4e-02 3.0e-03] - [ 1.7e-02 3.8e-02 -1.2e-03] - [-1.3e-02 -1.3e-02 -3.7e-02] - [ 3.3e-02 -5.0e-02 1.6e-02] - [ 1.8e-02 -1.1e-02 5.3e-03] - [-3.3e-03 -5.2e-02 6.3e-03] - [-5.4e-04 4.0e-02 -1.4e-02] - [ 5.5e-02 -3.0e-02 -2.1e-02] - [ 2.2e-02 1.9e-02 6.3e-03]] -# --- -# name: test_read_oxdna.7 - [[ 0.0 0.3 0.0] - [-0.1 0.1 0.4] - [-0.0 -0.5 0.5] - [-0.2 0.1 0.2] - [-0.1 0.1 0.3] - [ 0.0 0.3 0.2] - [ 0.3 -0.4 0.2] - [-0.2 0.4 0.0] - [ 0.1 -0.3 0.0] - [ 0.7 -0.1 0.5] - [-0.4 -0.2 -1.1] - [ 0.2 -0.2 0.0] - [ 0.1 -0.2 0.0] - [ 0.1 0.4 -0.4] - [ 0.2 -0.3 0.4] - [-0.0 -0.0 0.4] - [-0.0 -0.2 0.1] - [ 0.1 0.2 0.2] - [ 0.0 0.2 0.4] - [-0.1 0.0 0.2] - [ 0.5 0.1 0.1] - [ 0.2 -0.2 0.4] - [ 0.5 -0.4 -0.2] - [-0.3 0.6 0.5] - [ 0.2 -0.2 0.4] - [-0.6 0.1 -0.1] - [-0.3 0.0 0.5] - [ 0.3 -0.4 0.4] - [-0.2 -0.1 -0.2] - [-0.3 -0.3 -0.2] - [ 0.1 0.4 -0.4] - [ 0.1 -0.2 -0.0] - [ 0.1 0.2 0.2] - [ 0.3 -0.2 -0.1] - [ 0.3 -0.1 0.1] - [-0.6 0.1 -0.1] - [ 0.1 -0.2 0.0] - [ 0.1 0.4 -0.4] - [ 0.1 0.1 0.5] - [-0.1 0.4 0.3] - [-0.5 0.1 -0.1] - [ 0.4 0.3 -0.4] - [ 0.2 0.3 -0.0] - [ 0.4 -0.3 0.0] - [-0.3 0.7 0.1] - [ 0.5 -0.0 -0.2] - [ 0.0 -0.0 0.7] - [ 0.2 -0.2 0.4] - [-0.1 0.4 0.3] - [ 0.0 -0.1 -0.7] - [ 0.1 0.4 -0.4] - [ 0.3 0.1 0.6] - [ 0.5 0.1 0.1] - [-0.1 -0.1 0.2] - [ 0.1 0.4 -0.4] - [-0.6 0.1 -0.6] - [-0.0 -0.5 0.5] - [ 0.2 -0.1 0.4] - [ 0.0 0.5 -0.1] - [-0.4 0.1 0.0] - [ 0.1 -0.4 -0.1] - [ 0.0 0.2 0.4] - [ 0.1 0.2 0.7] - [ 0.1 -0.4 -0.1] - [-0.3 -0.0 -0.3] - [ 0.1 -0.5 0.2] - [ 0.1 -0.3 0.0] - [-0.6 0.1 -0.6] - [-0.3 0.5 0.1] - [ 0.1 -0.2 -0.0] - [ 0.1 0.8 -0.3] - [-0.3 -0.3 -0.2] - [-0.8 0.6 -0.2] - [ 0.1 0.1 0.2] - [ 0.5 -0.4 -0.2] - [-0.0 0.1 -0.2] - [ 0.1 0.2 0.2] - [ 0.1 -0.2 0.0] - [-0.2 -0.4 0.1] - [ 0.0 -0.0 0.7] - [-0.1 0.2 0.2] - [ 0.1 -0.2 0.0] - [ 0.3 -0.2 -0.1] - [ 0.2 0.0 0.1] - [-0.3 0.7 0.1] - [-0.1 0.0 0.2] - [-0.3 -0.4 -0.3] - [ 0.4 0.3 -0.4] - [-0.3 0.0 -0.0] - [ 0.1 -0.2 0.0] - [-0.3 0.5 0.1] - [ 0.2 -0.3 0.4] - [ 0.0 0.2 0.4] - [ 0.0 -0.1 -0.7] - [-0.1 0.1 0.3] - [-0.2 0.1 0.2] - [ 0.3 -0.0 -0.3] - [-0.0 -0.3 -0.1] - [ 0.0 -0.6 0.4] - [ 0.5 -0.0 -0.2]] -# --- -# name: test_read_oxdna.8 - [ True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True True True True True True True True True - True True True True] -# --- -# name: test_read_oxdna.9 - [[ 39 40] - [550 556] - [378 384] - [ 75 81] - [ 0 6] - [247 253] - [495 501] - [326 327] - [352 358] - [ 14 20] - [331 337] - [473 479] - [153 154] - [409 410] - [538 539] - [540 541] - [ 66 67] - [143 138] - [569 564] - [426 432] - [ 54 55] - [431 426] - [365 371] - [ 64 65] - [303 304] - [401 396] - [260 261] - [558 564] - [151 152] - [374 380] - [ 73 74] - [ 58 64] - [159 160] - [300 301] - [568 574] - [144 145] - [490 491] - [467 462] - [ 98 104] - [302 303] - [249 250] - [442 443] - [351 357] - [293 288] - [118 119] - [ 57 58] - [460 461] - [511 512] - [155 150] - [113 108] - [271 277] - [447 453] - [149 144] - [339 340] - [532 538] - [204 205] - [151 157] - [177 178] - [505 506] - [ 25 31] - [134 135] - [160 166] - [ 79 85] - [329 335] - [578 579] - [369 375] - [329 324] - [334 335] - [516 517] - [359 354] - [350 356] - [138 144] - [467 473] - [ 35 41] - [233 239] - [428 429] - [376 377] - [ 70 71] - [510 516] - [250 251] - [ 56 57] - [570 576] - [457 463] - [340 341] - [ 30 31] - [494 495] - [435 436] - [501 507] - [339 345] - [399 400] - [ 49 50] - [141 142] - [432 438] - [511 517] - [580 586] - [196 202] - [ 97 103] - [537 538] - [126 127] - [262 263]] +# name: TestOXDNAReading.test_univ_snapshot.3 + [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 + 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 + 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4] # --- diff --git a/tests/__snapshots__/test_load.ambr b/tests/__snapshots__/test_load.ambr index 5e82b38e..e410b4aa 100644 --- a/tests/__snapshots__/test_load.ambr +++ b/tests/__snapshots__/test_load.ambr @@ -385,25 +385,22 @@ [ 3.3e-01 8.1e-02 9.6e-02]] # --- # name: test_pdb_no_bonds - [[ 0.0 0.0 0.0] - [ 0.0 0.0 0.0] - [ 0.0 0.0 0.0] - [ 0.0 0.0 0.0] - [ 0.0 0.0 0.0] - [ 0.1 0.1 0.1] - [ 0.1 0.1 0.1] - [ 0.1 0.1 0.1] - [ 0.1 0.1 0.1] - [-0.0 -0.0 -0.0] - [-0.0 -0.0 -0.0] - [-0.0 -0.0 -0.0] - [-0.0 -0.0 -0.0] - [-0.0 -0.0 -0.0] - [-0.1 -0.1 -0.1] - [-0.1 -0.1 -0.1]] -# --- -# name: test_pdb_no_bonds.1 - [] + array([[ 0.01, 0.01, 0.01], + [ 0.02, 0.02, 0.02], + [ 0.03, 0.03, 0.03], + [ 0.04, 0.04, 0.04], + [ 0.05, 0.05, 0.05], + [ 0.06, 0.06, 0.06], + [ 0.07, 0.07, 0.07], + [ 0.08, 0.08, 0.08], + [ 0.09, 0.09, 0.09], + [-0.01, -0.01, -0.01], + [-0.02, -0.02, -0.02], + [-0.03, -0.03, -0.03], + [-0.04, -0.04, -0.04], + [-0.05, -0.05, -0.05], + [-0.06, -0.06, -0.06], + [-0.07, -0.07, -0.07]]) # --- # name: test_rcsb_nmr[False] [[ 0.1 0.0 -0.1] diff --git a/tests/data/oxdna/top_new_custom.top b/tests/data/oxdna/top_new_custom.top new file mode 100644 index 00000000..12dcb175 --- /dev/null +++ b/tests/data/oxdna/top_new_custom.top @@ -0,0 +1,3 @@ +12 2 5->3 +GT(13)GCG type=DNA +CGC(-10)AC type=DNA \ No newline at end of file diff --git a/tests/data/oxdna/traj_old_new.dat b/tests/data/oxdna/traj_old_new.dat new file mode 100644 index 00000000..c8a1aad7 --- /dev/null +++ b/tests/data/oxdna/traj_old_new.dat @@ -0,0 +1,30 @@ +t = 500000 +b = 17 17 17 +E = -1.26125121116638 -1.40279078483582 0.141539588570595 +-2.71388244628906 3.47911643981934 6.11712265014648 0.623006105422974 0.782013833522797 -0.0178236979991198 -0.00681409984827042 -0.0173595044761896 -0.99982613325119 -0.104749746620655 0.207955867052078 0.110502049326897 0.0185949858278036 0.337806850671768 0.245974078774452 +-2.84630966186523 3.69316101074219 5.7212028503418 0.966981947422028 0.254525274038315 0.0127692595124245 -0.0131023805588484 0.0996926948428154 -0.994932115077972 0.212986201047897 0.339831411838531 0.082770824432373 -0.713768541812897 -0.0234667118638754 0.0252062696963549 +-2.82102584838867 4.00576019287109 5.30809211730957 0.932236790657043 -0.350077509880066 -0.0915448889136314 -0.0169287864118814 0.210519894957542 -0.977442979812622 -0.385900378227234 -0.0936472117900848 -0.313209593296051 0.060018464922905 -0.358485043048859 -0.125160396099091 +-2.70832443237305 4.34485244750977 4.95480155944824 0.624891877174377 -0.771166145801544 -0.121707588434219 0.0888340398669243 0.225115388631821 -0.970273911952972 0.527467906475067 0.261296689510345 -0.110662423074245 -0.435533821582794 -0.157417297363281 -1.07367062568665 +-2.3138313293457 4.62926292419434 4.59322357177734 0.261396735906601 -0.963984310626984 -0.0490521043539047 0.337246656417847 0.13882876932621 -0.931123673915863 -0.00569585803896189 0.0389907471835613 -0.169724598526955 -0.452835589647293 0.0985835194587708 -0.0695057287812233 +-1.86847686767578 4.6140079498291 4.27702713012695 -0.44191586971283 -0.887813329696655 -0.128443613648415 0.188339829444885 0.0481664389371872 -0.980922043323517 0.221844404935837 -0.153715997934341 0.626589596271515 -0.184030756354332 0.109232373535633 -0.243071481585503 +-1.54825973510742 4.52231025695801 3.97049713134766 -0.898629486560822 -0.346900135278702 -0.268561482429504 0.242089331150055 0.118410050868988 -0.963001430034637 0.327147036790848 -0.497938275337219 0.155039936304092 -0.0512844771146774 0.0948343500494957 0.28431835770607 +-1.39173126220703 4.39387130737305 3.42015838623047 -0.980471789836884 0.158813059329987 -0.115989819169044 0.132955610752106 0.100710794329643 -0.985992014408112 -0.220508337020874 -0.185717165470123 0.685320019721985 0.323797792196274 -0.220896035432816 -0.104263804852962 +-1.35349273681641 4.16534996032715 2.97673606872559 -0.800813436508179 0.598714113235474 0.0154705159366131 0.00132620707154274 0.0276035778224468 -0.999618053436279 -0.00249419989995658 -0.22495037317276 0.350358664989471 0.214432939887047 0.232472226023674 0.32265642285347 +-1.60685729980469 4.05478477478027 2.47950744628906 -0.194842725992203 0.94876229763031 0.248769581317902 0.109083957970142 0.273018062114716 -0.955804228782654 0.167082190513611 -0.359410494565964 -0.178383335471153 -0.824753701686859 0.637020826339722 -0.167981579899788 +-1.91200256347656 4.21942138671875 1.97663497924805 0.379594355821609 0.804162502288818 0.457417547702789 0.203989282250404 0.40950345993042 -0.88921046257019 -0.00431415066123009 0.0244927313178778 -0.116692334413528 0.125121146440506 0.595021784305573 0.56517106294632 +-1.58051300048828 3.00995254516602 0.902116775512695 -0.178838655352592 0.198652476072311 -0.963615119457245 0.977483808994293 0.147357195615768 -0.151034310460091 -0.476231455802917 0.662693500518799 -0.170812621712685 -0.542614102363586 0.0206559374928474 0.0502250045537949 +t = 1000000 +b = 17 17 17 +E = -1.22928142547607 -1.36916053295135 0.139879152178764 +7.46204137802124 7.52110433578491 7.83010578155518 -0.853093445301056 0.426008105278015 -0.301245599985123 -0.227878659963608 -0.823602437973022 -0.519375205039978 -0.332762956619263 -0.317888766527176 0.282985895872116 -0.353773027658463 -0.669774651527405 0.484911501407623 +7.21830224990845 7.0861120223999 7.7243504524231 -0.528895139694214 0.625599324703217 -0.573493957519531 -0.409386813640594 -0.779989540576935 -0.473306149244308 0.151937931776047 -0.167389675974846 -0.14412122964859 0.279533714056015 0.157498434185982 -0.317104578018188 +6.75138759613037 6.81209516525269 7.7138819694519 -0.115494772791862 0.383829653263092 -0.916152715682983 -0.408844739198685 -0.858943819999695 -0.30832052230835 0.309087634086609 0.212393179535866 0.0225550550967455 0.156060591340065 0.423906028270721 -0.265006899833679 +6.34469318389893 6.58345937728882 7.48868465423584 0.632181882858276 0.0849567949771881 -0.77014821767807 -0.432633817195892 -0.785887837409973 -0.441823750734329 -0.637137830257416 0.113170854747295 0.0633947029709816 0.202342167496681 -0.0456349290907383 -0.13218092918396 +6.08737134933472 6.2936577796936 7.19296026229858 0.820043802261353 0.0645908638834953 -0.568644106388092 -0.435493439435959 -0.574235141277313 -0.693252742290497 0.0720811188220978 0.19222217798233 0.11419240385294 0.205475464463234 -0.0490295737981796 0.0106330988928676 +5.9496488571167 6.22579193115234 6.71777057647705 0.914512693881989 -0.371278703212738 -0.160681933164597 -0.35827162861824 -0.558784961700439 -0.747931063175201 0.614271342754364 -0.0999471619725227 0.361342281103134 0.0820026695728302 -0.355395525693893 -0.028274804353714 +6.03442049026489 6.15534734725952 6.20938539505005 0.597340881824493 -0.71271675825119 0.36772084236145 -0.176585033535957 -0.56414407491684 -0.806572437286377 0.201110288500786 -0.0539062209427357 -0.169853910803795 0.221071720123291 -0.00261460873298347 0.186809182167053 +6.31864213943481 6.01393890380859 5.74865531921387 -0.00441425293684006 -0.795202493667603 0.606327891349792 -0.164589241147041 -0.597486793994904 -0.784805655479431 0.126673400402069 -0.333357959985733 -0.693504929542542 -0.680877029895782 0.0207977201789618 -0.0766764506697655 +6.39327239990234 5.57877922058105 5.39767599105835 -0.169323325157166 -0.566127598285675 0.806739985942841 -0.242910355329514 -0.769335150718689 -0.590862274169922 -0.0956622660160065 0.0371962748467922 0.139915153384209 0.0668022334575653 0.27230516076088 -0.415111631155014 +6.51349687576294 5.13402462005615 5.28965139389038 -0.83998566865921 -0.0992453396320343 0.5334552526474 -0.211517080664635 -0.845468461513519 -0.49035057425499 0.143512487411499 -0.734968781471252 0.625438094139099 -0.504727780818939 0.427298992872238 0.396458148956299 +6.48263263702393 4.60228633880615 5.25323915481567 -0.928756654262543 0.336657911539078 0.155153423547745 -0.369067341089249 -0.800676763057709 -0.471917301416397 0.556943237781525 0.18658272922039 0.303757041692734 0.0550393797457218 -0.197236597537994 0.301765143871307 +7.78814792633057 4.3724536895752 4.33855724334717 0.794353783130646 -0.602611839771271 -0.0765565186738968 0.0845730304718018 0.234512984752655 -0.968427062034607 -0.803858280181885 0.203380703926086 -0.433198422193527 0.0429709292948246 0.275111734867096 -0.058091577142477 diff --git a/tests/test_dna.py b/tests/test_dna.py index 58236a93..f0c37bc7 100644 --- a/tests/test_dna.py +++ b/tests/test_dna.py @@ -1,59 +1,97 @@ -import numpy as np -import molecularnodes as mn +import pytest +import MDAnalysis as mda from molecularnodes.entities.trajectory import dna -from .utils import sample_attribute, NumpySnapshotExtension +from .utils import NumpySnapshotExtension from .constants import data_dir -def test_read_topology(): - file_new = data_dir / "oxdna/top_new.top" - file_old = data_dir / "oxdna/top_old.top" - - arr_old = dna.toplogy_to_bond_idx_pairs(dna.read_topology_old(file_old)) - arr_new = dna.toplogy_to_bond_idx_pairs(dna.read_topology_new(file_new)) - - assert np.array_equal(arr_old, arr_new) - - -def test_topology_to_idx(): - top = np.array([[1, 31, -1, 1], [1, 3, 0, 1], [1, 2, 1, -1]]) - - bonds = dna.toplogy_to_bond_idx_pairs(top) - expected = np.array([[0, 1], [1, 2]]) - - assert np.array_equal(bonds, expected) - - -def test_base_lookup(): - bases = np.array(["A", "C", "C", "G", "T", "-10", "G", "C", "-3"]) - expected = np.array([30, 31, 31, 32, 33, -1, 32, 31, -1]) - - ints = dna.base_to_int(bases) - - assert np.array_equal(ints, expected) - - -def test_read_trajectory(): - traj = dna.read_trajectory(data_dir / "oxdna/holliday.dat") - - assert traj.shape == (20, 98, 15) - - -def test_read_oxdna(snapshot_custom: NumpySnapshotExtension): - name = "holliday" - mol, coll_frames = dna.load( - top=data_dir / "oxdna/holliday.top", - traj=data_dir / "oxdna/holliday.dat", - name=name, - ) - - assert len(coll_frames.objects) == 20 - assert mol.name == name - - for att in mol.data.attributes.keys(): - assert snapshot_custom == sample_attribute(mol, att) - - # realise all of the geometry and sample some attributes - mn.blender.nodes.realize_instances(mol) - for att in mol.data.attributes.keys(): - assert snapshot_custom == sample_attribute(mol, att, evaluate=True) +class TestOXDNAReading: + @pytest.fixture(scope="module") + def filepath_top(self): + return data_dir / "oxdna/holliday.top" + + @pytest.fixture(scope="module") + def filepath_top_new(self): + return data_dir / "oxdna/top_new.top" + + @pytest.fixture(scope="module") + def filepath_top_new_custom(self): + return data_dir / "oxdna/top_new_custom.top" + + @pytest.fixture(scope="module") + def filepath_top_old(self): + return data_dir / "oxdna/top_old.top" + + @pytest.fixture(scope="module") + def filepath_traj_old_new(self): + return data_dir / "oxdna/traj_old_new.dat" + + @pytest.fixture(scope="module") + def filepath_traj_dat(self): + return data_dir / "oxdna/holliday.dat" + + @pytest.fixture(scope="module") + def universe(self, filepath_top, filepath_traj_dat): + return mda.Universe( + filepath_top, + filepath_traj_dat, + format=dna.OXDNAReader, + topology_format=dna.OXDNAParser, + ) + + def test_read_as_universe(self, filepath_top, filepath_traj_dat): + u = mda.Universe( + filepath_top, + filepath_traj_dat, + format=dna.OXDNAReader, + topology_format=dna.OXDNAParser, + ) + assert u.atoms.n_atoms == 98 + + def test_univ_as_traj(self, universe): + traj = dna.OXDNA(universe) + assert traj.universe + assert not traj.object + assert all([x in ["A", "C", "T", "G"] for x in traj.res_name]) + + def test_univ_snapshot(self, universe: mda.Universe, snapshot_custom): + traj = dna.OXDNA(universe) + traj.create_object() + for name in ["position", "res_name", "res_id", "chain_id"]: + assert snapshot_custom == getattr(traj, name) + + def test_detect_new_top( + self, filepath_top_old, filepath_top_new, filepath_top_new_custom + ): + assert dna.OXDNAParser._is_new_topology(filepath_top_new) + assert dna.OXDNAParser._is_new_topology(filepath_top_new_custom) + assert not dna.OXDNAParser._is_new_topology(filepath_top_old) + + def test_topo_reading( + self, + filepath_top_old, + filepath_top_new, + filepath_top_new_custom, + ): + top_new = dna.OXDNAParser._read_topo_new(filepath_top_new) + top_new_custom = dna.OXDNAParser._read_topo_new(filepath_top_new_custom) + top_old = dna.OXDNAParser._read_topo_old(filepath_top_old) + + for top in [top_new, top_old, top_new_custom]: + assert top.n_atoms == 12 + assert top.n_residues == 12 + + @pytest.mark.parametrize("topfile", ["top_new", "top_new_custom", "top_old"]) + def test_comparing_topologies(self, snapshot, topfile, filepath_traj_old_new): + u = mda.Universe( + data_dir / f"oxdna/{topfile}.top", + filepath_traj_old_new, + topology_format=dna.OXDNAParser, + format=dna.OXDNAReader, + ) + traj = dna.OXDNA(u) + traj.create_object() + assert len(traj) == 12 + assert snapshot == traj.bonds.tolist() + for att in ["res_id", "chain_id", "res_name"]: + assert snapshot == traj.named_attribute(att).tolist() diff --git a/tests/test_load.py b/tests/test_load.py index bf808232..1dfa014a 100644 --- a/tests/test_load.py +++ b/tests/test_load.py @@ -127,10 +127,11 @@ def test_local_pdb(snapshot_custom): for mol in molecules: assert snapshot_custom == sample_attribute(mol, att, evaluate=False) -def test_pdb_no_bonds(snapshot_custom): - molecule = mn.entities.load_local(data_dir / f"no_bonds.pdb", style="spheres") - for attr in ["position", "bond_type"]: - assert snapshot_custom == sample_attribute(molecule, attr, evaluate=False) + +def test_pdb_no_bonds(snapshot): + mol = mn.entities.load_local(data_dir / "no_bonds.pdb", style=None) + assert len(mol.object.data.edges) == 0 + assert snapshot == mol.position @pytest.mark.parametrize("del_hydrogen", [True, False]) diff --git a/tests/test_ops.py b/tests/test_ops.py index a05b7cef..52753ad6 100644 --- a/tests/test_ops.py +++ b/tests/test_ops.py @@ -20,7 +20,7 @@ def test_op_api_cartoon( scene = bpy.context.scene scene.MN_import_node_setup = True scene.MN_pdb_code = code - scene.MN_import_style = style + scene.mn.import_style = style scene.MN_import_node_setup = True scene.MN_import_build_assembly = False scene.MN_import_centre = False @@ -47,7 +47,7 @@ def test_op_api_cartoon( def test_op_local(snapshot_custom, code, file_format): scene = bpy.context.scene scene.MN_import_node_setup = False - scene.MN_import_style = "spheres" + scene.mn.import_style = "spheres" scene.MN_import_build_assembly = False scene.MN_import_del_solvent = False scene.MN_import_format_download = file_format @@ -81,7 +81,7 @@ def test_op_api_mda(snapshot_custom: NumpySnapshotExtension): bpy.context.scene.MN_import_md_topology = topo bpy.context.scene.MN_import_md_trajectory = traj - bpy.context.scene.MN_import_style = "ribbon" + bpy.context.scene.mn.import_style = "ribbon" with ObjectTracker() as o: bpy.ops.mn.import_trajectory() @@ -90,6 +90,7 @@ def test_op_api_mda(snapshot_custom: NumpySnapshotExtension): assert obj_1.name == name traj = mn.entities.trajectory.load(topo, traj, name="test", style="ribbon") + traj.subframes = 0 obj_2 = traj.object for mol in [obj_1, obj_2]: