From 036c42a9daf51d2981055a0ee32ddfa86b37c2fa Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Thu, 15 Jan 2026 16:11:21 -0500 Subject: [PATCH 1/8] LLM refactor platonic solid --- ionerdss/model/PlatonicSolids.py | 436 +++++++----------- .../model/platonic_solids/cube/__init__.py | 16 - .../model/platonic_solids/cube/cube_face.py | 23 - .../cube/cube_face_COM_coord.py | 36 -- .../cube/cube_face_COM_leg_coord.py | 35 -- .../cube/cube_face_COM_leg_list_gen.py | 42 -- .../cube/cube_face_COM_list_gen.py | 44 -- .../cube/cube_face_input_coord.py | 37 -- .../cube/cube_face_leg_reduce.py | 39 -- .../cube/cube_face_leg_reduce_coord_gen.py | 46 -- .../cube/cube_face_vert_coord.py | 49 -- .../platonic_solids/cube/cube_face_write.py | 237 ---------- .../model/platonic_solids/cube/cube_vert.py | 23 - .../platonic_solids/cube/cube_vert_COM_leg.py | 30 -- .../cube/cube_vert_COM_leg_gen.py | 43 -- .../platonic_solids/cube/cube_vert_coord.py | 40 -- .../cube/cube_vert_input_coord.py | 38 -- .../cube/cube_vert_leg_reduce.py | 36 -- .../cube/cube_vert_leg_reduce_coor_gen.py | 44 -- .../cube/cube_vert_norm_input.py | 52 --- .../platonic_solids/cube/cube_vert_write.py | 140 ------ .../model/platonic_solids/dode/__init__.py | 16 - .../model/platonic_solids/dode/dode_face.py | 22 - .../dode/dode_face_COM_coor.py | 64 --- .../dode/dode_face_COM_leg_coor.py | 51 -- .../dode/dode_face_COM_leg_list_gen.py | 45 -- .../dode/dode_face_COM_list_gen.py | 44 -- .../dode/dode_face_dodecahedron_coord.py | 46 -- .../dode/dode_face_input_coord.py | 33 -- .../dode/dode_face_leg_reduce.py | 31 -- .../dode/dode_face_leg_reduce_coor_gen.py | 38 -- .../platonic_solids/dode/dode_face_write.py | 306 ------------ .../model/platonic_solids/dode/dode_vert.py | 20 - .../platonic_solids/dode/dode_vert_COM_leg.py | 28 -- .../dode/dode_vert_COM_leg_gen.py | 68 --- .../platonic_solids/dode/dode_vert_coord.py | 46 -- .../dode/dode_vert_input_coord.py | 33 -- .../dode/dode_vert_leg_reduce.py | 29 -- .../dode/dode_vert_leg_reduce_coor_gen.py | 35 -- .../dode/dode_vert_norm_input.py | 38 -- .../platonic_solids/dode/dode_vert_write.py | 139 ------ .../gen_platonic/COM_leg_coord.py | 47 -- .../gen_platonic/COM_leg_list_gen.py | 42 -- .../platonic_solids/gen_platonic/__init__.py | 16 - .../platonic_solids/gen_platonic/angle_cal.py | 55 --- .../platonic_solids/gen_platonic/distance.py | 44 -- .../gen_platonic/face_COM_coord.py | 52 --- .../platonic_solids/gen_platonic/mid_pt.py | 29 -- .../gen_platonic/vert_coord.py | 44 -- ionerdss/model/platonic_solids/geometry.py | 69 +++ .../model/platonic_solids/icos/__init__.py | 16 - .../model/platonic_solids/icos/icos_face.py | 21 - .../icos/icos_face_COM_coord.py | 52 --- .../icos/icos_face_COM_leg_coord.py | 47 -- .../icos/icos_face_COM_list_gen.py | 39 -- .../icos/icos_face_input_coord.py | 28 -- .../icos/icos_face_leg_reduce.py | 31 -- .../icos/icos_face_leg_reduce_coord_gen.py | 32 -- .../icos/icos_face_vert_coord.py | 44 -- .../platonic_solids/icos/icos_face_write.py | 182 -------- .../model/platonic_solids/icos/icos_vert.py | 32 -- .../platonic_solids/icos/icos_vert_COM_leg.py | 28 -- .../icos/icos_vert_COM_leg_gen.py | 44 -- .../icos/icos_vert_center_coor.py | 54 --- .../icos/icos_vert_check_dis.py | 30 -- .../platonic_solids/icos/icos_vert_coord.py | 40 -- .../icos/icos_vert_input_coord.py | 30 -- .../icos/icos_vert_leg_reduce.py | 25 - .../icos/icos_vert_leg_reduce_coor_gen.py | 32 -- .../icos/icos_vert_norm_input.py | 38 -- .../platonic_solids/icos/icos_vert_write.py | 274 ----------- .../model/platonic_solids/octa/__init__.py | 16 - .../model/platonic_solids/octa/octa_face.py | 26 -- .../octa/octa_face_COM_coord.py | 48 -- .../octa/octa_face_COM_leg_coord.py | 47 -- .../octa/octa_face_COM_leg_list_gen.py | 39 -- .../octa/octa_face_COM_list_gen.py | 37 -- .../octa/octa_face_input_coord.py | 42 -- .../octa/octa_face_leg_reduce.py | 42 -- .../octa/octa_face_leg_reduce_coord_gen.py | 46 -- .../octa/octa_face_vert_coord.py | 40 -- .../platonic_solids/octa/octa_face_write.py | 177 ------- .../model/platonic_solids/octa/octa_vert.py | 22 - .../platonic_solids/octa/octa_vert_COM_leg.py | 36 -- .../octa/octa_vert_COM_leg_gen.py | 37 -- .../platonic_solids/octa/octa_vert_coord.py | 35 -- .../octa/octa_vert_input_coord.py | 42 -- .../octa/octa_vert_leg_reduce.py | 34 -- .../octa/octa_vert_leg_reduce_coor_gen.py | 44 -- .../platonic_solids/octa/octa_vert_write.py | 198 -------- ionerdss/model/platonic_solids/solids.py | 314 +++++++++++++ .../model/platonic_solids/tetr/__init__.py | 16 - .../model/platonic_solids/tetr/tetr_face.py | 26 -- .../tetr/tetr_face_COM_coord.py | 49 -- .../tetr/tetr_face_COM_leg_coord.py | 39 -- .../tetr/tetr_face_COM_leg_list_gen.py | 25 - .../tetr/tetr_face_COM_list_gen.py | 28 -- .../platonic_solids/tetr/tetr_face_coord.py | 32 -- .../tetr/tetr_face_input_coord.py | 30 -- .../tetr/tetr_face_leg_reduce.py | 32 -- .../tetr/tetr_face_leg_reduce_coord_gen.py | 38 -- .../platonic_solids/tetr/tetr_face_write.py | 181 -------- .../model/platonic_solids/tetr/tetr_vert.py | 22 - .../platonic_solids/tetr/tetr_vert_COM_leg.py | 27 -- .../tetr/tetr_vert_COM_leg_gen.py | 27 -- .../platonic_solids/tetr/tetr_vert_coord.py | 32 -- .../tetr/tetr_vert_input_coord.py | 29 -- .../tetr/tetr_vert_leg_reduce.py | 26 -- .../tetr/tetr_vert_leg_reduce_coor_gen.py | 29 -- .../tetr/tetr_vert_norm_input.py | 38 -- .../platonic_solids/tetr/tetr_vert_write.py | 138 ------ tests/unit/model/test_platonic_solids.py | 89 ++++ 112 files changed, 644 insertions(+), 5766 deletions(-) delete mode 100644 ionerdss/model/platonic_solids/cube/__init__.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_COM_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_COM_leg_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_COM_leg_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_COM_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_leg_reduce_coord_gen.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_face_write.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_COM_leg.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_COM_leg_gen.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_norm_input.py delete mode 100644 ionerdss/model/platonic_solids/cube/cube_vert_write.py delete mode 100644 ionerdss/model/platonic_solids/dode/__init__.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_COM_coor.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_COM_leg_coor.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_COM_leg_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_COM_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_dodecahedron_coord.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_face_write.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_COM_leg.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_COM_leg_gen.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_norm_input.py delete mode 100644 ionerdss/model/platonic_solids/dode/dode_vert_write.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/COM_leg_coord.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/COM_leg_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/__init__.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/angle_cal.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/distance.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/face_COM_coord.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/mid_pt.py delete mode 100644 ionerdss/model/platonic_solids/gen_platonic/vert_coord.py create mode 100644 ionerdss/model/platonic_solids/geometry.py delete mode 100644 ionerdss/model/platonic_solids/icos/__init__.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_COM_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_COM_leg_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_COM_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_leg_reduce_coord_gen.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_face_write.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_COM_leg.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_COM_leg_gen.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_center_coor.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_check_dis.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_norm_input.py delete mode 100644 ionerdss/model/platonic_solids/icos/icos_vert_write.py delete mode 100644 ionerdss/model/platonic_solids/octa/__init__.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_COM_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_COM_leg_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_COM_leg_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_COM_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_leg_reduce_coord_gen.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_face_write.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_COM_leg.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_COM_leg_gen.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/octa/octa_vert_write.py create mode 100644 ionerdss/model/platonic_solids/solids.py delete mode 100644 ionerdss/model/platonic_solids/tetr/__init__.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_COM_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_COM_list_gen.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce_coord_gen.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_face_write.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg_gen.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_input_coord.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce_coor_gen.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_norm_input.py delete mode 100644 ionerdss/model/platonic_solids/tetr/tetr_vert_write.py create mode 100644 tests/unit/model/test_platonic_solids.py diff --git a/ionerdss/model/PlatonicSolids.py b/ionerdss/model/PlatonicSolids.py index 8e4a1423..6d885329 100644 --- a/ionerdss/model/PlatonicSolids.py +++ b/ionerdss/model/PlatonicSolids.py @@ -1,272 +1,180 @@ -"""Platonic Solids Model module for generating NERDSS molecule types and reactions, and corresponding files for specified platonic solid type. +"""Platonic Solids Model module for generating NERDSS molecule types and reactions. -This module defines the `PlatonicSolidsModel` class, inheriting from the `Model` class, which is used to generate NERDSS molecule types and reactions, and corresponding files for platonic solid. +This module uses a consolidated geometry generation approach to create geometric models +of Platonic solids (cube, dodecahedron, etc.) using standard ionerdss components. """ -from .components import Model -from .components import Reaction -from .components import MoleculeType -from .components import MoleculeInterface -from ..utils.coords import Coords -from .platonic_solids.dode.dode_face_write import dode_face_write -from .platonic_solids.cube.cube_face_write import cube_face_write -from .platonic_solids.icos.icos_face_write import icos_face_write -from .platonic_solids.octa.octa_face_write import octa_face_write -from .platonic_solids.tetr.tetr_face_write import tetr_face_write -from dataclasses import dataclass, field -from typing import List, Dict, Tuple - - -class PlatonicSolid(Model): - """"A class for generating NERDSS molecule types and reactions, and corresponding files for platonic solid. - - Attributes: - pdb_file (str): The path to the PDB structure file. - solid_type (str): The platonic solid type. - binding_site_position (str): The binding site position. - """ - name: str - molecule_types: List[MoleculeType] = field(default_factory=list) - reactions: List[Reaction] = field(default_factory=list) +from typing import List, Tuple, Dict +import numpy as np + +# Standard component imports +from ionerdss.model.components.types import MoleculeType, InterfaceType +from ionerdss.model.components.reactions import ReactionRule, ReactionGeometrySet +from ionerdss.model.components.system import System + +# Import consolidated logic +from .platonic_solids.geometry import angle_cal +from .platonic_solids.solids import ( + CubeGenerator, + DodecahedronGenerator, + IcosahedronGenerator, + OctahedronGenerator, + TetrahedronGenerator, + PlatonicSolidGenerator +) + +class PlatonicSolidsModel: + """A class for generating NERDSS molecule types and reactions for platonic solids.""" + + # Registry of generator instances + _GENERATORS: Dict[str, PlatonicSolidGenerator] = { + "cube": CubeGenerator(), + "dode": DodecahedronGenerator(), + "icos": IcosahedronGenerator(), + "octa": OctahedronGenerator(), + "tetr": TetrahedronGenerator(), + } @classmethod - def create_Solid(cls, solid_type: str, radius: float, sigma: float = None) -> Model: - """ - Parameters: - cls: - solid_type (str): The platonic solid type within ["cube","dode","icos","octa","tetr"] - radius (float): the radius of the circumscribed sphere around the platonic solid (nm) — that is, the distance from the center of the dodecahedron to any of its vertices. - sigma (float): distance between two binding sites (nm) + def create_solid(cls, solid_type: str, radius: float, sigma: float) -> Tuple[System, List[ReactionRule]]: """ - types: list = ["cube", "dode", "icos", "octa", "tetr"] - reactions_to_return = [] # this function returns all reactions generated in this module - # this returns the molecule information needed to generate a model class - molecule_interfaces = [] - if solid_type not in types: - raise ValueError(f"Solid type must be one of {types}.") - if solid_type == 'dode': - if sigma == None: - raise ValueError( - f"if Solid Type is {solid_type}. Sigma must be provided. Argument is currently sigma={sigma}") - dode_reaction_parameters, dode_mol_information = dode_face_write( - radius, sigma, create_Solid=True) - dode_reactions: list = ['dode(lg1) + dode(lg1) <-> dode(lg1!1).dode(lg1!1)', - 'dode(lg2) + dode(lg2) <-> dode(lg2!1).dode(lg2!1)', - 'dode(lg3) + dode(lg3) <-> dode(lg3!1).dode(lg3!1)', - 'dode(lg4) + dode(lg4) <-> dode(lg4!1).dode(lg4!1)', - 'dode(lg5) + dode(lg5) <-> dode(lg5!1).dode(lg5!1)', - 'dode(lg1) + dode(lg2) <-> dode(lg1!1).dode(lg2!1)', - 'dode(lg1) + dode(lg3) <-> dode(lg1!1).dode(lg3!1)', - 'dode(lg1) + dode(lg4) <-> dode(lg1!1).dode(lg4!1)', - 'dode(lg1) + dode(lg5) <-> dode(lg1!1).dode(lg5!1)', - 'dode(lg2) + dode(lg3) <-> dode(lg2!1).dode(lg3!1)', - 'dode(lg2) + dode(lg4) <-> dode(lg2!1).dode(lg4!1)', - 'dode(lg2) + dode(lg5) <-> dode(lg2!1).dode(lg5!1)', - 'dode(lg3) + dode(lg4) <-> dode(lg3!1).dode(lg4!1)', - 'dode(lg3) + dode(lg5) <-> dode(lg3!1).dode(lg5!1)', - 'dode(lg4) + dode(lg5) <-> dode(lg4!1).dode(lg5!1)'] - - norm = [float(dode_reaction_parameters['n'][0]), - float(dode_reaction_parameters['n'][1]), - float(dode_reaction_parameters['n'][2])] - - for i in dode_reactions: - reactions_to_return.append(Reaction( - name=i, - binding_radius=float(sigma), - binding_angles=[dode_reaction_parameters['theta1'], - dode_reaction_parameters['theta2'], - dode_reaction_parameters['phi1'], - dode_reaction_parameters['phi2'], - dode_reaction_parameters['omega']], - norm1=norm, - norm2=norm, - )) - for i in dode_mol_information.keys(): - if i == "COM": - continue - # MoleculeInterface(name=vals[0], coord=Coords(x_coord, y_coord, z_coord))) - x_coord = round(dode_mol_information[i][0], 8) - y_coord = round(dode_mol_information[i][1], 8) - z_coord = round(dode_mol_information[i][2], 8) - molecule_interfaces.append(MoleculeInterface( - name=i, coord=Coords(x_coord, y_coord, z_coord))) - - molecule = [MoleculeType( - name='dode', interfaces=molecule_interfaces)] - if solid_type == 'cube': - if sigma == None: - raise ValueError( - f"if Solid Type is {solid_type}. Sigma must be provided. Argument is currently sigma={sigma}") - cube_reaction_parameters, cube_mol_information = cube_face_write( - radius, sigma, create_Solid=True) - - cube_reactions: list = ['cube(lg1) + cube(lg1) <-> cube(lg1!1).cube(lg1!1)', - 'cube(lg2) + cube(lg2) <-> cube(lg2!1).cube(lg2!1)', - 'cube(lg3) + cube(lg3) <-> cube(lg3!1).cube(lg3!1)', - 'cube(lg4) + cube(lg4) <-> cube(lg4!1).cube(lg4!1)', - 'cube(lg1) + cube(lg2) <-> cube(lg1!1).cube(lg2!1)', - 'cube(lg1) + cube(lg3) <-> cube(lg1!1).cube(lg3!1)', - 'cube(lg1) + cube(lg4) <-> cube(lg1!1).cube(lg4!1)', - 'cube(lg2) + cube(lg3) <-> cube(lg2!1).cube(lg3!1)', - 'cube(lg2) + cube(lg4) <-> cube(lg2!1).cube(lg4!1)', - 'cube(lg3) + cube(lg4) <-> cube(lg3!1).cube(lg4!1)', - ] - - norm = [float(cube_reaction_parameters['n'][0]), - float(cube_reaction_parameters['n'][1]), - float(cube_reaction_parameters['n'][2])] - - for i in cube_reactions: - reactions_to_return.append(Reaction( - name=i, - binding_radius=float(sigma), - binding_angles=[cube_reaction_parameters['theta1'], - cube_reaction_parameters['theta2'], - cube_reaction_parameters['phi1'], - cube_reaction_parameters['phi2'], - cube_reaction_parameters['omega']], - norm1=norm, - norm2=norm, - )) - for i in cube_mol_information.keys(): - if i == "COM": - continue - - x_coord = round(cube_mol_information[i][0], 8) - y_coord = round(cube_mol_information[i][1], 8) - z_coord = round(cube_mol_information[i][2], 8) - molecule_interfaces.append(MoleculeInterface( - name=i, coord=Coords(x_coord, y_coord, z_coord))) - - molecule = [MoleculeType( - name='cube', interfaces=molecule_interfaces)] - if solid_type == 'icos': - if sigma == None: - raise ValueError( - f"if Solid Type is {solid_type}. Sigma must be provided. Argument is currently sigma={sigma}") - icos_reaction_parameters, icos_mol_information = icos_face_write( - radius, sigma, create_Solid=True) - - icos_reactions: list = ['icos(lg1) + icos(lg1) <-> icos(lg1!1).icos(lg1!1)', - 'icos(lg2) + icos(lg2) <-> icos(lg2!1).icos(lg2!1)', - 'icos(lg3) + icos(lg3) <-> icos(lg3!1).icos(lg3!1)', - 'icos(lg1) + icos(lg2) <-> icos(lg1!1).icos(lg2!1)', - 'icos(lg1) + icos(lg3) <-> icos(lg1!1).icos(lg3!1)', - 'icos(lg2) + icos(lg3) <-> icos(lg2!1).icos(lg3!1)', - ] + Create a System containing the Platonic solid definition and its reactions. - norm = [float(icos_reaction_parameters['n'][0]), - float(icos_reaction_parameters['n'][1]), - float(icos_reaction_parameters['n'][2])] + Args: + solid_type (str): The platonic solid type ["cube", "dode", "icos", "octa", "tetr"] + radius (float): The radius of the circumscribed sphere (nm) + sigma (float): Distance between two binding sites (nm) - for i in icos_reactions: - reactions_to_return.append(Reaction( - name=i, - binding_radius=float(sigma), - binding_angles=[icos_reaction_parameters['theta1'], - icos_reaction_parameters['theta2'], - icos_reaction_parameters['phi1'], - icos_reaction_parameters['phi2'], - icos_reaction_parameters['omega']], - norm1=norm, - norm2=norm, - )) - for i in icos_mol_information.keys(): - if i == "COM": - continue - - x_coord = round(icos_mol_information[i][0], 8) - y_coord = round(icos_mol_information[i][1], 8) - z_coord = round(icos_mol_information[i][2], 8) - molecule_interfaces.append(MoleculeInterface( - name=i, coord=Coords(x_coord, y_coord, z_coord))) - - molecule = [MoleculeType( - name='icos', interfaces=molecule_interfaces)] - if solid_type == 'octa': - if sigma == None: - raise ValueError( - f"if Solid Type is {solid_type}. Sigma must be provided. Argument is currently sigma={sigma}") - octa_reaction_parameters, octa_mol_information = octa_face_write( - radius, sigma, create_Solid=True) - - octa_reactions: list = ['octa(lg1) + octa(lg1) <-> octa(lg1!1).octa(lg1!1)', - 'octa(lg2) + octa(lg2) <-> octa(lg2!1).octa(lg2!1)', - 'octa(lg3) + octa(lg3) <-> octa(lg3!1).octa(lg3!1)', - 'octa(lg1) + octa(lg2) <-> octa(lg1!1).octa(lg2!1)', - 'octa(lg1) + octa(lg3) <-> octa(lg1!1).octa(lg3!1)', - 'octa(lg2) + octa(lg3) <-> octa(lg2!1).octa(lg3!1)', - ] - - norm = [float(octa_reaction_parameters['n'][0]), - float(octa_reaction_parameters['n'][1]), - float(octa_reaction_parameters['n'][2])] - - for i in octa_reactions: - reactions_to_return.append(Reaction( - name=i, - binding_radius=float(sigma), - binding_angles=[octa_reaction_parameters['theta1'], - octa_reaction_parameters['theta2'], - octa_reaction_parameters['phi1'], - octa_reaction_parameters['phi2'], - octa_reaction_parameters['omega']], - norm1=norm, - norm2=norm, - )) - for i in octa_mol_information.keys(): - if i == "COM": - continue - - x_coord = round(octa_mol_information[i][0], 8) - y_coord = round(octa_mol_information[i][1], 8) - z_coord = round(octa_mol_information[i][2], 8) - molecule_interfaces.append(MoleculeInterface( - name=i, coord=Coords(x_coord, y_coord, z_coord))) - - molecule = [MoleculeType( - name='octa', interfaces=molecule_interfaces)] - if solid_type == 'tetr': - if sigma == None: - raise ValueError( - f"if Solid Type is {solid_type}. Sigma must be provided. Argument is currently sigma={sigma}") - tetr_reaction_parameters, tetr_mol_information = tetr_face_write( - radius, sigma, create_Solid=True) - - tetr_reactions: list = ['tetr(lg1) + tetr(lg1) <-> tetr(lg1!1).tetr(lg1!1)', - 'tetr(lg2) + tetr(lg2) <-> tetr(lg2!1).tetr(lg2!1)', - 'tetr(lg3) + tetr(lg3) <-> tetr(lg3!1).tetr(lg3!1)', - 'tetr(lg1) + tetr(lg2) <-> tetr(lg1!1).tetr(lg2!1)', - 'tetr(lg1) + tetr(lg3) <-> tetr(lg1!1).tetr(lg3!1)', - 'tetr(lg2) + tetr(lg3) <-> tetr(lg2!1).tetr(lg3!1)', - ] - - norm = [float(tetr_reaction_parameters['n'][0]), - float(tetr_reaction_parameters['n'][1]), - float(tetr_reaction_parameters['n'][2])] - - for i in tetr_reactions: - reactions_to_return.append(Reaction( - name=i, - binding_radius=float(sigma), - binding_angles=[tetr_reaction_parameters['theta1'], - tetr_reaction_parameters['theta2'], - tetr_reaction_parameters['phi1'], - tetr_reaction_parameters['phi2'], - tetr_reaction_parameters['omega']], - norm1=norm, - norm2=norm, - )) - for i in tetr_mol_information.keys(): - if i == "COM": - continue - x_coord = round(tetr_mol_information[i][0], 8) - y_coord = round(tetr_mol_information[i][1], 8) - z_coord = round(tetr_mol_information[i][2], 8) - molecule_interfaces.append(MoleculeInterface( - name=i, coord=Coords(x_coord, y_coord, z_coord))) - - molecule = [MoleculeType( - name='tetr', interfaces=molecule_interfaces)] - return cls(name=solid_type, molecule_types=molecule, reactions=reactions_to_return) + Returns: + Tuple[System, List[ReactionRule]]: A tuple containing: + - A System object populated with the MoleculeType and InterfaceTypes + - A list of ReactionRule objects defining the binding interactions + """ + if solid_type not in cls._GENERATORS: + raise ValueError(f"Solid type must be one of {list(cls._GENERATORS.keys())}.") + + if sigma is None: + raise ValueError(f"Sigma must be provided for solid type {solid_type}.") + + generator = cls._GENERATORS[solid_type] + + # 0. Initialize System + system = System(workspace_path=".", pdb_id=f"{solid_type}_gen") + + # 1. Generate Coordinates (COM, Legs, Normal) for ALL faces + # Returns List of [COM, leg1, leg2..., Normal] + all_faces_coords = generator.generate_coordinates(radius, sigma) + + # Extract Representative Face Data (Face 0) + # Structure: [COM, leg1, leg2, ..., Normal] + # Normal is the LAST element. COM is the FIRST. legs are in between. + face0_data = all_faces_coords[0] + com = face0_data[0] + normal = face0_data[-1] + legs = face0_data[1:-1] + + # 2. Generate Angle Parameters + # Use generator's angle indices to pick points from the generated faces + idx1, idx2, idx3, idx4 = generator.angle_indices + + # Helper to extract point: (face_index, element_index) + # element_index: 0=COM, 1=leg1... + p1 = all_faces_coords[idx1[0]][idx1[1]] + p2 = all_faces_coords[idx2[0]][idx2[1]] + p3 = all_faces_coords[idx3[0]][idx3[1]] + p4 = all_faces_coords[idx4[0]][idx4[1]] + + theta1, theta2, phi1, phi2, omega = angle_cal(p1, p2, p3, p4) + + # 3. Create MoleculeType + mol_type = MoleculeType(name=solid_type, radius_nm=float(radius)) + mol_type.set_diffusion_constants_from_radius() # standard physics + system.molecule_types.add(mol_type) + + # 4. Create InterfaceTypes and add to System + # COM is treated as center of system/molecule? + # In this context, the entire solid is ONE particle in NERDSS if coarse-grained? + # NO. Platonic solids simulation treats FACES as particles usually? + # "dode_face_write" suggests we are simulating FACES as individual rigid bodies that assemble into the solid. + # "create_Solid" implies creating a model OF THE SOLID. + # But if we return one MoleculeType "cube" with 4 binding sites... that implies the Cube is ONE particle? + # BUT `cube` MoleculeType has `radius` of the circumscribed sphere. + # If the Cube is the particle, why do we need reaction angles between faces? + # Standard NERDSS: "Patchy particles". + # Yes, here 'cube' likely represents a single CUBE PARTICLE that binds to OTHER CUBE PARTICLES? + # OR does 'cube' represent a SQUARE FACE that binds to form a cube? (Self-assembly of faces into solid). + # "dode(lg1) + dode(lg1) <-> ..." + # If it's self-assembly, then `MoleculeType` should be "Face". + # But the name is `solid_type` ("cube"). + # If `num_sites=4` (legs of square face), then "cube" IS the face. + # The naming is confusing: "cube" = "Square Face used to build a Cube". + # "dode" = "Pentagon Face used to build a Dodecahedron". + # This aligns with `num_sites` (4 for cube face, 5 for dode face). + # So `com` calculated (Face COM) is the center of the particle. + # And `legs` are the binding sites on the edges of the face. + # `normal` is the orientation vector. + + # So for MoleculeType creation: + # local_coord of interface = leg_coord - com. + # Since `com` is the origin of the face particle essentially (or we define it so). + # Actually `com` calculated by `generate_coordinates` is the position of the face in the assembled solid (relative to solid center). + # But for the `MoleculeType` definition of a single free face, we want coordinates relative to the face center! + # If `com` is [x,y,z], and `leg` is [lx, ly, lz]. + # Relative coord `leg - com` is correct for defining the reusable Face Template. + + interface_objects = [] + + for i, leg_coord in enumerate(legs): + index = i + 1 + local_coord = np.array(leg_coord) - np.array(com) + + # Absolute coord in the template definition is usually just the local coord if COM is origin. + # `InterfaceType` constructor takes `absolute_coord` and `local_coord`. + # In `types.py`: local_coord = relative to COM. absolute_coord = global? + # But in a Type definition, global doesn't exist. Usually absolute=local for Type. + + interface = InterfaceType( + this_mol_type_name=solid_type, + partner_mol_type_name=solid_type, + interface_index=index, + absolute_coord=local_coord, # For Type definition, absolute is usually same as local/relative to origin + local_coord=local_coord, + this_mol_type=mol_type, + partner_mol_type=mol_type, + energy=-1.0 + ) + + system.interface_types.add(interface) + interface_objects.append(interface) + + # 5. Generate Reactions + reactions = [] + + for i in range(len(interface_objects)): + for j in range(i, len(interface_objects)): + site1 = interface_objects[i] + site2 = interface_objects[j] + + geometry = ReactionGeometrySet( + theta1=theta1, theta2=theta2, + phi1=phi1, phi2=phi2, + omega=omega, + sigma_nm=float(sigma), + norm1=normal, norm2=normal + ) + + ka_val = 2.0 if i == j else 4.0 + + reaction = ReactionRule( + expr="", + reactant_interfaces=(site1, site2), + geometry=geometry, + ka=ka_val, + kb=1.0 + ) + reactions.append(reaction) + + return system, reactions + + # Legacy alias + create_Solid = create_solid diff --git a/ionerdss/model/platonic_solids/cube/__init__.py b/ionerdss/model/platonic_solids/cube/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/cube/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/cube/cube_face.py b/ionerdss/model/platonic_solids/cube/cube_face.py deleted file mode 100644 index 5865032e..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face.py +++ /dev/null @@ -1,23 +0,0 @@ -from .cube_face_write import cube_face_write - - -def cube_face(radius: float, sigma: float): - """Generates a cube face file for visualization of a molecular system. - - This function generates a cube face file using the provided radius and sigma values, which can be used for - visualization of a molecular system in a molecular visualization software. The cube face file is written using the - `cube_face_write` function from the `.cube_face_write` module. - - Args: - radius (float): The radius of the cube face. - sigma (float): The sigma value for the cube face. - - Returns: - parm.inp/cube.mol files: Inputs for NERDSS - """ - - cube_face_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_COM_coord.py b/ionerdss/model/platonic_solids/cube/cube_face_COM_coord.py deleted file mode 100644 index 86c269c6..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_COM_coord.py +++ /dev/null @@ -1,36 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt - - -def cube_face_COM_coord(a: float, b: float, c: float, d: float): - """Calculates the center of mass (COM) coordinate for a cube face. - - This function calculates the COM coordinate for a cube face defined by four input points (a, b, c, d), where a, b, c, - and d are the coordinates of the vertices of the cube face. The calculation is based on the mid-point coordinates - of the input points, as well as the mid-point coordinates of the pairs of input points. The `mid_pt` function from - the `..gen_platonic.mid_pt` module is used for the mid-point calculations. - - Args: - a (float): The x-coordinate of the first vertex of the cube face. - b (float): The x-coordinate of the second vertex of the cube face. - c (float): The x-coordinate of the third vertex of the cube face. - d (float): The x-coordinate of the fourth vertex of the cube face. - - Returns: - Float: The x-coordinate of the calculated COM coordinate of the cube face. - - Example: - >>> cube_face_COM_coord(0.0, 1.0, 1.0, 0.0) - 0.5 - """ - mid_a = mid_pt(a, b) - mid_b = mid_pt(b, c) - mid_c = mid_pt(c, d) - mid_d = mid_pt(d, a) - COM_a = mid_pt(mid_a, mid_c) - COM_b = mid_pt(mid_b, mid_d) - if COM_a == COM_b: - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_coord.py b/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_coord.py deleted file mode 100644 index 48628d6f..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_coord.py +++ /dev/null @@ -1,35 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt -from .cube_face_COM_coord import cube_face_COM_coord - - -def cube_face_COM_leg_coord(a: float, b: float, c: float, d: float): - """Calculates the center of mass (COM) coordinates for a cube face and its legs. - - This function calculates the COM coordinates for a cube face and its legs, based on four input points (a, b, c, d), - where a, b, c, and d are the coordinates of the vertices of the cube face. The calculation is performed using the - `cube_face_COM_coord` function from the `.cube_face_COM_coord` module and the `mid_pt` function from the - `..gen_platonic.mid_pt` module. - - Args: - a (float): The x-coordinate of the first vertex of the cube face. - b (float): The x-coordinate of the second vertex of the cube face. - c (float): The x-coordinate of the third vertex of the cube face. - d (float): The x-coordinate of the fourth vertex of the cube face. - - Returns: - List: he COM coordinates for the cube face and its legs, in the following order: - [COM_face, COM_leg_ab, COM_leg_bc, COM_leg_cd, COM_leg_da]. - - Example: - >>> cube_face_COM_leg_coord(0.0, 1.0, 1.0, 0.0) - [0.5, 0.5, 0.5, 0.5, 0.5] - """ - COM_leg = [] - COM_leg.append(cube_face_COM_coord(a, b, c, d)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, d)) - COM_leg.append(mid_pt(d, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_list_gen.py b/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_list_gen.py deleted file mode 100644 index d538ff9f..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_COM_leg_list_gen.py +++ /dev/null @@ -1,42 +0,0 @@ -from .cube_face_vert_coord import cube_face_vert_coord -from .cube_face_COM_leg_coord import cube_face_COM_leg_coord - - -def cube_face_COM_leg_list_gen(radius: float): - """Generates a list of center of mass (COM) coordinates for cube faces and their legs. - - This function generates a list of COM coordinates for the cube faces and their legs, based on the radius of the - cube. The calculation is performed using the `cube_face_vert_coord` function from the `.cube_face_vert_coord` module - to obtain the vertex coordinates of the cube, and the `cube_face_COM_leg_coord` function from the `.cube_face_COM_leg_coord` - module to calculate the COM coordinates for each cube face and its legs. - - Args: - radius (float): The radius of the cube. - - Returns: - List: contains COM coordinates for all cube faces and their legs, in the following order: - [COM_leg_list_abcd, COM_leg_list_adhe, COM_leg_list_efgh, COM_leg_list_befg, COM_leg_list_cdgh, COM_leg_list_aehd]. - - - Example: - >>> cube_face_COM_leg_list_gen(1.0) - [[0.5, 0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5, 0.5], [0.5, 0.5, 0.5, 0.5, 0.5]] - """ - - coord = cube_face_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(cube_face_COM_leg_coord( - coord[0], coord[3], coord[5], coord[2])) - COM_leg_list.append(cube_face_COM_leg_coord( - coord[0], coord[3], coord[6], coord[1])) - COM_leg_list.append(cube_face_COM_leg_coord( - coord[0], coord[1], coord[4], coord[2])) - COM_leg_list.append(cube_face_COM_leg_coord( - coord[7], coord[4], coord[1], coord[6])) - COM_leg_list.append(cube_face_COM_leg_coord( - coord[7], coord[4], coord[2], coord[5])) - COM_leg_list.append(cube_face_COM_leg_coord( - coord[7], coord[6], coord[3], coord[5])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_COM_list_gen.py b/ionerdss/model/platonic_solids/cube/cube_face_COM_list_gen.py deleted file mode 100644 index 3ed105a5..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_COM_list_gen.py +++ /dev/null @@ -1,44 +0,0 @@ -from .cube_face_vert_coord import cube_face_vert_coord -from .cube_face_COM_coord import cube_face_COM_coord - - -def cube_face_COM_list_gen(radius: float): - """Generates a list of center of mass (COM) coordinates for cube faces. - - This function generates a list of COM coordinates for the cube faces, based on the radius of the - cube. The calculation is performed using the `cube_face_vert_coord` function from the `.cube_face_vert_coord` module - to obtain the vertex coordinates of the cube, and the `cube_face_COM_coord` function from the `.cube_face_COM_coord` - module to calculate the COM coordinates for each cube face. - - Args: - radius (float): The radius of the cube. - - Returns: - List: contains COM coordinates for all cube faces, in the following order: - [COM_list_abcd, COM_list_adhe, COM_list_efgh, COM_list_befg, COM_list_cdgh, COM_list_aehd]. - - Raises: - None. - - Example: - >>> cube_face_COM_list_gen(1.0) - [[0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, 0.5]] - """ - - coord = cube_face_vert_coord(radius) - COM_list = [] - COM_list.append(cube_face_COM_coord( - coord[0], coord[3], coord[5], coord[2])) - COM_list.append(cube_face_COM_coord( - coord[0], coord[3], coord[6], coord[1])) - COM_list.append(cube_face_COM_coord( - coord[0], coord[1], coord[4], coord[2])) - COM_list.append(cube_face_COM_coord( - coord[7], coord[4], coord[1], coord[6])) - COM_list.append(cube_face_COM_coord( - coord[7], coord[4], coord[2], coord[5])) - COM_list.append(cube_face_COM_coord( - coord[7], coord[6], coord[3], coord[5])) - return COM_list - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_input_coord.py b/ionerdss/model/platonic_solids/cube/cube_face_input_coord.py deleted file mode 100644 index 7299213a..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_input_coord.py +++ /dev/null @@ -1,37 +0,0 @@ -from .cube_face_leg_reduce_coord_gen import cube_face_leg_reduce_coord_gen -import numpy as np - -def cube_face_input_coord(radius: float, sigma: float): - """Generates input coordinates for a cube face simulation. - - This function generates input coordinates for a cube face simulation, based on the radius and sigma values - provided. The calculation is performed using the `cube_face_leg_reduce_coord_gen` function from the - `.cube_face_leg_reduce_coord_gen` module to obtain reduced coordinates of the cube face, and then - performs various calculations to derive the input coordinates. - - Args: - radius (float): The radius of the cube. - sigma (float): The sigma value for the simulation. - - Returns: - List: Contains the input coordinates for the cube face simulation, in the following order: - [COM, lg1, lg2, lg3, lg4, n], where COM is the center of mass of the cube face, lg1, lg2, lg3, and lg4 are - the leg vectors of the cube face, and n is a vector pointing towards the center of the cube face. - - - Example: - >>> cube_face_input_coord(1.0, 0.1) - [[0.0, 0.0, 0.0], [0.0, 0.0, 1.0], [0.0, 1.0, 0.0], [1.0, 0.0, 0.0], [0.0, -1.0, 0.0], [-0.0, -0.0, -0.0]] - """ - - coor = cube_face_leg_reduce_coord_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = np.around(coor_[0] - coor_[0], 7) - lg1 = coor_[1] - coor_[0] - lg2 = coor_[2] - coor_[0] - lg3 = coor_[3] - coor_[0] - lg4 = coor_[4] - coor_[0] - n = -coor_[0] - return [COM, lg1, lg2, lg3, lg4, n] - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce.py b/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce.py deleted file mode 100644 index f6038fe8..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce.py +++ /dev/null @@ -1,39 +0,0 @@ -import math -from ..gen_platonic.distance import distance - - -def cube_face_leg_reduce(COM: float, leg: float, sigma: float): - """Reduces the length of a cube face leg vector based on center of mass and sigma. - - This function takes the center of mass (COM), leg vector, and sigma as inputs, and reduces the length of the - leg vector based on the given sigma value. The reduction is performed using the formula: - leg_red = (leg - COM) * ratio + COM, where ratio is calculated as - 1 - (sigma / (2 * sin(angle / 2))) / distance(COM, leg), and angle is calculated as acos(0). - - Args: - COM (float): The center of mass of the cube face. - leg (float): The leg vector of the cube face. - sigma (float): The sigma value for the reduction. - - Returns: - List: Contains the reduced leg vector of the cube face, with each coordinate rounded to 'n' decimal places. - 'n' is determined by the value of 'n' in the function. - - Raises: - None. - - Example: - >>> cube_face_leg_reduce([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], 0.1) - [0.131826, 0.131826, 0.131826] - """ - - n = 12 - angle = math.acos(0) - red_len = sigma/(2*math.sin(angle/2)) - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], n)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce_coord_gen.py b/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce_coord_gen.py deleted file mode 100644 index ad1fad21..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_leg_reduce_coord_gen.py +++ /dev/null @@ -1,46 +0,0 @@ -import numpy as np -from ..gen_platonic.COM_leg_list_gen import COM_leg_list_gen -from .cube_face_COM_leg_list_gen import cube_face_COM_leg_list_gen -from .cube_face_leg_reduce import cube_face_leg_reduce - -def cube_face_leg_reduce_coord_gen(radius: float, sigma: float): - """Generates a list of reduced center of mass and leg vectors for cube faces. - - This function takes the radius and sigma value as inputs, and generates a list of reduced center of mass (COM) and leg - vectors for the cube faces of a platonic solid. The reduction is performed using the 'cube_face_leg_reduce' function - from the 'cube_face_leg_reduce' module, and the original COM and leg vectors are obtained from the 'cube_face_COM_leg_list_gen' - and 'cube_face_COM_leg_list_gen' functions respectively. - - Args: - radius (float): The radius of the platonic solid. - sigma (float): The sigma value for the reduction. - - Returns: - List: Contains reduced COM and leg vectors for the cube faces. Each element in the list is a sublist containing the reduced - COM vector followed by the reduced leg vectors for each face. The coordinates in the vectors are rounded to 8 decimal places. - - Raises: - None. - - Example: - >>> cube_face_leg_reduce_coord_gen(1.0, 0.1) - [[0.0, [0.131826, 0.131826, 0.131826], [0.131826, 0.131826, -0.131826], [-0.131826, 0.131826, -0.131826], [-0.131826, 0.131826, 0.131826]], - [0.0, [-0.131826, 0.131826, 0.131826], [-0.131826, -0.131826, 0.131826], [-0.131826, -0.131826, -0.131826], [-0.131826, 0.131826, -0.131826]], - ... - ] - - """ - COM_leg_list = cube_face_COM_leg_list_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(np.around(elements[0], 8)) - i = 1 - while i <= 4: - temp_list.append(np.around(cube_face_leg_reduce( - elements[0], elements[i], sigma), 8)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_vert_coord.py b/ionerdss/model/platonic_solids/cube/cube_face_vert_coord.py deleted file mode 100644 index 55046276..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_vert_coord.py +++ /dev/null @@ -1,49 +0,0 @@ -def cube_face_vert_coord(radius: float): - """Generates vertex coordinates for a cube face. - - This function takes the radius of a cube face as input, and generates a list of vertex coordinates for the cube face - of a platonic solid. The vertex coordinates are calculated by scaling the pre-defined vertex coordinates of a unit cube - by the given radius value. - - Args: - radius (float): The radius of the platonic solid. - - Returns: - List: Contains vertex coordinates for the cube face. Each vertex coordinate is a list of three floats representing the - x, y, and z coordinates of the vertex. The vertex coordinates are scaled by the radius value. - - Raises: - None. - - Example: - >>> cube_face_vert_coord(1.0) - [[0.5773502691896257, 0.5773502691896257, 0.5773502691896257], - [-0.5773502691896257, 0.5773502691896257, 0.5773502691896257], - [0.5773502691896257, -0.5773502691896257, 0.5773502691896257], - [0.5773502691896257, 0.5773502691896257, -0.5773502691896257], - [-0.5773502691896257, -0.5773502691896257, 0.5773502691896257], - [0.5773502691896257, -0.5773502691896257, -0.5773502691896257], - [-0.5773502691896257, 0.5773502691896257, -0.5773502691896257], - [-0.5773502691896257, -0.5773502691896257, -0.5773502691896257]] - """ - - scaler = radius/3**0.5 - v0 = [1, 1, 1] - v1 = [-1, 1, 1] - v2 = [1, -1, 1] - v3 = [1, 1, -1] - v4 = [-1, -1, 1] - v5 = [1, -1, -1] - v6 = [-1, 1, -1] - v7 = [-1, -1, -1] - VertCoord = [v0, v1, v2, v3, v4, v5, v6, v7] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/cube/cube_face_write.py b/ionerdss/model/platonic_solids/cube/cube_face_write.py deleted file mode 100644 index c866d613..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_face_write.py +++ /dev/null @@ -1,237 +0,0 @@ -from ..gen_platonic.angle_cal import angle_cal -from .cube_face_leg_reduce_coord_gen import cube_face_leg_reduce_coord_gen -from .cube_face_input_coord import cube_face_input_coord - - -def cube_face_write(radius: float, sigma: float,create_Solid: bool = False): - """Writes input parameters and reaction details to a file for cube face-centered simulation. - - Args: - radius (float): The radius of the cube face-centered structure. - sigma (float): The sigma value used for simulation. - - Returns: - parm.inp/cube.mol files: Inputs for NERDSS - - This function writes the input parameters and reaction details for a cube face-centered - simulation to a file named 'parm.inp'. The function takes the radius and sigma as input - arguments, and uses them to calculate the required input parameters and reaction details. - The file 'parm.inp' contains input parameters such as number of iterations, time steps, - write frequencies, box boundaries, number of molecules, and reaction details for four - types of cubes (lg1, lg2, lg3, lg4) based on the given radius and sigma values. The - function uses helper functions 'cube_face_input_coord', 'cube_face_leg_reduce_coord_gen', - and 'angle_cal' from other modules to calculate the required input parameters. - """ - if create_Solid == True: - COM, lg1, lg2, lg3, lg4, n = cube_face_input_coord(radius, sigma) - coord = cube_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][3], coord[4][0], coord[4][1]) - - output_reactions_dict :dict = { - "n": n, - "coord": coord, - "theta1": theta1, - "theta2": theta2, - "phi1": phi1, - "phi2": phi2, - "omega": omega - } - output_mol_dict: dict = { - "COM": COM, - "lg1": lg1, - "lg2": lg2, - "lg3": lg3, - "lg4": lg4, - } - return output_reactions_dict, output_mol_dict - else: - COM, lg1, lg2, lg3, lg4, n = cube_face_input_coord(radius, sigma) - coord = cube_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][1], coord[1][0], coord[1][1]) - - f = open('parm.inp', 'w') - f.write(' # Input file (cube face-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' cube : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' cube(lg1) + cube(lg1) <-> cube(lg1!1).cube(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg2) + cube(lg2) <-> cube(lg2!1).cube(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg3) + cube(lg3) <-> cube(lg3!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg4) + cube(lg4) <-> cube(lg4!1).cube(lg4!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg1) + cube(lg2) <-> cube(lg1!1).cube(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg1) + cube(lg3) <-> cube(lg1!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg1) + cube(lg4) <-> cube(lg1!1).cube(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg2) + cube(lg3) <-> cube(lg2!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg2) + cube(lg4) <-> cube(lg2!1).cube(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg3) + cube(lg4) <-> cube(lg3!1).cube(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('cube.mol', 'w') - f.write('##\n') - f.write('# Cube (face-centered) information file.\n') - f.write('##\n\n') - f.write('Name = cube\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('lg4 ' + str(round(lg4[0], 8)) + ' ' + - str(round(lg4[1], 8)) + ' ' + str(round(lg4[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 4\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('com lg4\n') - f.write('\n') - - -# CUBE VERTEX AS COM - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert.py b/ionerdss/model/platonic_solids/cube/cube_vert.py deleted file mode 100644 index 394e7356..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert.py +++ /dev/null @@ -1,23 +0,0 @@ -from .cube_vert_write import cube_vert_write - - -def cube_vert(radius: float, sigma: float): - """Generates a cube mesh with vertex data and writes it to a file. - - Args: - radius (float): The radius of the cube. - sigma (float): The sigma value for vertex generation. - - Returns: - parm.inp/cube.mol file: inputs for NERDSS - - Example: - cube_vert(1.0, 0.1) # Generates a cube mesh with radius 1.0 and sigma 0.1, - # writes it to a file, and returns 0. - """ - - cube_vert_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg.py b/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg.py deleted file mode 100644 index 9bd3e0a4..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg.py +++ /dev/null @@ -1,30 +0,0 @@ -import numpy as np -from ..gen_platonic.mid_pt import mid_pt - - -def cube_vert_COM_leg(COM: float, a: float, b: float, c: float): - """Calculates the midpoints of three line segments between a central point and three other points. - - Args: - COM (float): The central point of the cube. - a (float): The first point. - b (float): The second point. - c (float): The third point. - - Returns: - list: A list containing four floating-point values rounded to 10 decimal places, representing the central point - (COM) and the midpoints (lega, legb, legc) of the three line segments. - - - Example: - cube_vert_COM_leg(0.5, 1.0, 2.0, 3.0) - # Calculates the midpoints of the line segments between the central point 0.5 and three other points - # (1.0, 2.0, 3.0), and returns a list containing the calculated values rounded to 10 decimal places. - """ - - lega = mid_pt(COM, a) - legb = mid_pt(COM, b) - legc = mid_pt(COM, c) - return [np.around(COM, 10), np.around(lega, 10), np.around(legb, 10), np.around(legc, 10)] - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg_gen.py b/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg_gen.py deleted file mode 100644 index 04d387b6..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_COM_leg_gen.py +++ /dev/null @@ -1,43 +0,0 @@ -from .cube_vert_coord import cube_vert_coord -from .cube_vert_COM_leg import cube_vert_COM_leg - -def cube_vert_COM_leg_gen(radius: float): - """Generates a list of midpoints of line segments between a central point and other points on a cube. - - This function calculates the midpoints of line segments between a central point and other points on a cube, based on the given - radius. - - Args: - radius (float): The radius of the cube. - - Returns: - list: A list containing eight sub-lists, each containing four floating-point values rounded to 10 decimal places, - representing the central point and the midpoints of line segments between the central point and other points on the cube. - - Example: - cube_vert_COM_leg_gen(1.0) - # Generates a list of midpoints of line segments between the central point and other points on a cube with a radius of 1.0. - # The list contains eight sub-lists, each containing four floating-point values rounded to 10 decimal places. - """ - - coord = cube_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(cube_vert_COM_leg( - coord[0], coord[1], coord[2], coord[3])) - COM_leg_list.append(cube_vert_COM_leg( - coord[1], coord[0], coord[4], coord[6])) - COM_leg_list.append(cube_vert_COM_leg( - coord[2], coord[0], coord[4], coord[5])) - COM_leg_list.append(cube_vert_COM_leg( - coord[3], coord[0], coord[5], coord[6])) - COM_leg_list.append(cube_vert_COM_leg( - coord[4], coord[1], coord[2], coord[7])) - COM_leg_list.append(cube_vert_COM_leg( - coord[5], coord[2], coord[3], coord[7])) - COM_leg_list.append(cube_vert_COM_leg( - coord[6], coord[1], coord[3], coord[7])) - COM_leg_list.append(cube_vert_COM_leg( - coord[7], coord[4], coord[5], coord[6])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_coord.py b/ionerdss/model/platonic_solids/cube/cube_vert_coord.py deleted file mode 100644 index b355e342..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_coord.py +++ /dev/null @@ -1,40 +0,0 @@ -def cube_vert_coord(radius: float): - """Calculates the coordinates of the vertices of a cube based on the given radius. - - This function calculates the coordinates of the vertices of a cube based on the given radius, using a scaling factor - calculated as radius divided by the square root of 3. - - Args: - radius (float): The radius of the cube. - - Returns: - list: A list containing eight sub-lists, each containing three floating-point values representing the x, y, and z - coordinates of a vertex of the cube. - - Example: - cube_vert_coord(1.0) - # Calculates the coordinates of the vertices of a cube with a radius of 1.0. - # Returns a list containing eight sub-lists, each containing three floating-point values representing the x, y, and z - # coordinates of a vertex of the cube. - """ - - scaler = radius/3**0.5 - v0 = [1, 1, 1] - v1 = [-1, 1, 1] - v2 = [1, -1, 1] - v3 = [1, 1, -1] - v4 = [-1, -1, 1] - v5 = [1, -1, -1] - v6 = [-1, 1, -1] - v7 = [-1, -1, -1] - VertCoord = [v0, v1, v2, v3, v4, v5, v6, v7] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_input_coord.py b/ionerdss/model/platonic_solids/cube/cube_vert_input_coord.py deleted file mode 100644 index 832cdc83..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_input_coord.py +++ /dev/null @@ -1,38 +0,0 @@ -from .cube_vert_leg_reduce_coor_gen import cube_vert_leg_reduce_coor_gen -import numpy as np - -def cube_vert_input_coord(radius: float, sigma: float): - """Calculates input coordinates for a cube vertex based on the given radius and sigma. - - This function calculates the input coordinates for a cube vertex based on the given radius and sigma, using the - `cube_vert_leg_reduce_coor_gen` function to generate the coordinates and then performing various calculations on the - generated coordinates using NumPy. - - Args: - radius (float): The radius of the cube. - sigma (float): The sigma value for the cube vertex. - - Returns: - tuple: A tuple containing five NumPy arrays, each containing three floating-point values representing the x, y, - and z coordinates of the input coordinates for the cube vertex. The first array represents the center of mass (COM) - coordinate, the next three arrays represent the three leg coordinates (lg1, lg2, lg3), and the last array - represents the normalized vector (n) coordinate. - - - Example: - cube_vert_input_coord(1.0, 0.5) - # Calculates the input coordinates for a cube vertex with a radius of 1.0 and a sigma value of 0.5. - # Returns a tuple containing five NumPy arrays, each containing three floating-point values representing the x, y, - # and z coordinates of the input coordinates for the cube vertex. - """ - - coor = cube_vert_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = np.around(coor_[0] - coor_[0], 8) - lg1 = np.around(coor_[1] - coor_[0], 8) - lg2 = np.around(coor_[2] - coor_[0], 8) - lg3 = np.around(coor_[3] - coor_[0], 8) - n = np.around(coor_[0]/np.linalg.norm(coor_[0]), 8) - return COM, lg1, lg2, lg3, n - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce.py b/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce.py deleted file mode 100644 index 65e26fa1..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce.py +++ /dev/null @@ -1,36 +0,0 @@ -from ..gen_platonic.distance import distance - - -def cube_vert_leg_reduce(COM: float, leg: float, sigma: float): - """Reduces the length of a cube vertex leg based on the center of mass (COM) and sigma value. - - This function reduces the length of a cube vertex leg based on the given center of mass (COM) and sigma value, using - the `distance` function from the `gen_platonic` module to calculate the initial leg length, and then applying a - reduction ratio based on the calculated length and the specified sigma value. - - Args: - COM (float): The center of mass (COM) coordinate of the cube vertex, represented as a float value. - leg (float): The original leg coordinate of the cube vertex, represented as a float value. - sigma (float): The sigma value for the cube vertex, used to calculate the reduction ratio, represented as a float value. - - Returns: - list: A list containing three floating-point values representing the reduced leg coordinates of the cube vertex, - after applying the reduction ratio to each coordinate. - - - Example: - cube_vert_leg_reduce([0.5, 0.5, 0.5], [1.0, 1.0, 1.0], 0.2) - # Reduces the length of the leg coordinate of a cube vertex with a center of mass (COM) of [0.5, 0.5, 0.5], an - # original leg coordinate of [1.0, 1.0, 1.0], and a sigma value of 0.2. - # Returns a list containing three floating-point values representing the reduced leg coordinates of the cube vertex - # after applying the reduction ratio to each coordinate. - """ - - red_len = sigma/2 - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], 8)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce_coor_gen.py deleted file mode 100644 index b16cdad4..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_leg_reduce_coor_gen.py +++ /dev/null @@ -1,44 +0,0 @@ -from .cube_vert_COM_leg_gen import cube_vert_COM_leg_gen -from .cube_vert_leg_reduce import cube_vert_leg_reduce - -def cube_vert_leg_reduce_coor_gen(radius: float, sigma: float): - """Generates a list of reduced center of mass (COM) and leg coordinates for a cube vertex based on radius and sigma. - - This function generates a list of reduced center of mass (COM) and leg coordinates for a cube vertex based on the - given radius and sigma values, using the `cube_vert_COM_leg_gen` and `cube_vert_leg_reduce` functions from the - respective modules. The reduction is applied to each leg coordinate by calling the `cube_vert_leg_reduce` function - with the appropriate arguments. - - Args: - radius (float): The radius of the cube vertex, represented as a float value. - sigma (float): The sigma value for the cube vertex, used to calculate the reduction ratio, represented as a float value. - - Returns: - list: A list of lists, where each inner list contains four elements: the reduced center of mass (COM) coordinate - and the reduced leg coordinates (leg1, leg2, and leg3) of a cube vertex, after applying the reduction ratio - based on the given radius and sigma values. - - - Example: - cube_vert_leg_reduce_coor_gen(1.0, 0.2) - # Generates a list of reduced center of mass (COM) and leg coordinates for a cube vertex with a radius of 1.0 and - # a sigma value of 0.2. - # Returns a list of lists, where each inner list contains four elements: the reduced center of mass (COM) coordinate - # and the reduced leg coordinates (leg1, leg2, and leg3) of a cube vertex, after applying the reduction ratio - # based on the given radius and sigma values. - """ - - COM_leg_list = cube_vert_COM_leg_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(cube_vert_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_norm_input.py b/ionerdss/model/platonic_solids/cube/cube_vert_norm_input.py deleted file mode 100644 index 3fa54c0b..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_norm_input.py +++ /dev/null @@ -1,52 +0,0 @@ -from ..gen_platonic.distance import distance -from .cube_vert_input_coord import cube_vert_input_coord -import numpy as np - -def cube_vert_norm_input(radius: float, sigma: float): - """Generates normalized input coordinates for a cube vertex based on radius and sigma. - - This function generates normalized input coordinates for a cube vertex based on the given radius and sigma values. - The generated coordinates include the center of mass (COM) coordinate, leg1, leg2, and leg3 coordinates, and a - normal vector (n), which represents the direction of the normal to the plane of the vertex. The function uses the - `cube_vert_input_coord` function to generate the initial input coordinates, and then calculates and returns the - normalized versions of these coordinates. - - Args: - radius (float): The radius of the cube vertex, represented as a float value. - sigma (float): The sigma value for the cube vertex, used to calculate the initial input coordinates, represented - as a float value. - - Returns: - tuple: A tuple containing the following five elements: - - COM_ (numpy array): The normalized center of mass (COM) coordinate of the cube vertex, represented as a - numpy array of shape (3,) and dtype float64. - - lg1_ (numpy array): The normalized leg1 coordinate of the cube vertex, represented as a numpy array of - shape (3,) and dtype float64. - - lg2_ (numpy array): The normalized leg2 coordinate of the cube vertex, represented as a numpy array of - shape (3,) and dtype float64. - - lg3_ (numpy array): The normalized leg3 coordinate of the cube vertex, represented as a numpy array of - shape (3,) and dtype float64. - - n_ (numpy array): The normalized normal vector (n) of the cube vertex, represented as a numpy array of - shape (3,) and dtype float64. - - - Example: - cube_vert_norm_input(1.0, 0.2) - # Generates normalized input coordinates for a cube vertex with a radius of 1.0 and a sigma value of 0.2. - # Returns a tuple containing the normalized center of mass (COM) coordinate, leg1, leg2, leg3 coordinates, and - # normal vector (n) of the cube vertex. - """ - - COM, lg1, lg2, lg3, n = cube_vert_input_coord(radius, sigma) - length = distance(lg1, lg2) - dis1 = ((-length/2)**2+(-((length/2)*(3**0.5))/3)**2)**0.5 - dis2 = distance(COM, lg1) - height = (dis2**2-dis1**2)**0.5 - lg1_ = np.array([-length/2, -((length/2)*(3**0.5))/3, -height]) - lg2_ = np.array([length/2, -((length/2)*(3**0.5))/3, -height]) - lg3_ = np.array([0, ((length/2)*(3**0.5))/3*2, -height]) - COM_ = np.array([0, 0, 0]) - n_ = np.array([0, 0, 1]) - return COM_, lg1_, lg2_, lg3_, n_ - - diff --git a/ionerdss/model/platonic_solids/cube/cube_vert_write.py b/ionerdss/model/platonic_solids/cube/cube_vert_write.py deleted file mode 100644 index d5fb4b5d..00000000 --- a/ionerdss/model/platonic_solids/cube/cube_vert_write.py +++ /dev/null @@ -1,140 +0,0 @@ -from .cube_vert_norm_input import cube_vert_norm_input - - -def cube_vert_write(radius: float, sigma: float): - """ - Writes input parameters for a cube vertex-centered simulation to a file. - - Args: - radius (float): The radius of the cubes. - sigma (float): The sigma value. - - - Returns: - parm.inp/cube.mol file: inputs for NERDSS - """ - - COM, lg1, lg2, lg3, n = cube_vert_norm_input(radius, sigma) - f = open('parm.inp', 'w') - f.write(' # Input file (cube vertex-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' cube : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' cube(lg1) + cube(lg1) <-> cube(lg1!1).cube(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg2) + cube(lg2) <-> cube(lg2!1).cube(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg3) + cube(lg3) <-> cube(lg3!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg1) + cube(lg2) <-> cube(lg1!1).cube(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg1) + cube(lg3) <-> cube(lg1!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' cube(lg2) + cube(lg3) <-> cube(lg2!1).cube(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('cube.mol', 'w') - f.write('##\n') - f.write('# Cube (vertex-centered) information file.\n') - f.write('##\n\n') - f.write('Name = cube\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - -# TETRAHETRON FACE AS COM - diff --git a/ionerdss/model/platonic_solids/dode/__init__.py b/ionerdss/model/platonic_solids/dode/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/dode/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/dode/dode_face.py b/ionerdss/model/platonic_solids/dode/dode_face.py deleted file mode 100644 index a1172b90..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face.py +++ /dev/null @@ -1,22 +0,0 @@ -from .dode_face_write import dode_face_write - - -def dode_face(radius: float, sigma: float): - """ - Generates a dodecahedron face using the given radius and sigma values, - writes it to a file using `dode_face_write` function, and prints a - completion message. - - Args: - radius (float): The radius of the dodecahedron. - sigma (float): The sigma value to use for generating the dodecahedron. - - Returns: - parm.inp/cube.mol file: inputs for NERDSS - """ - - dode_face_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_COM_coor.py b/ionerdss/model/platonic_solids/dode/dode_face_COM_coor.py deleted file mode 100644 index f22f0a67..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_COM_coor.py +++ /dev/null @@ -1,64 +0,0 @@ -import math -from ..gen_platonic.mid_pt import mid_pt - - -def dode_face_COM_coor(a: float, b: float, c: float, d: float, e: float): - """ - Calculates the center of mass (COM) coordinates for a dodecahedron face - based on five input coordinates on the same face, and checks for overlap. - - Args: - a (float): The first coordinate on the face. - b (float): The second coordinate on the face. - c (float): The third coordinate on the face. - d (float): The fourth coordinate on the face. - e (float): The fifth coordinate on the face. - - Returns: - list: A list of three float values representing the X, Y, and Z coordinates - of the center of mass (COM) if the calculated COM coordinates are not overlapped. - Otherwise, returns the COM coordinates based on the first input coordinate. - - Raises: - None. - - Example: - >>> dode_face_COM_coor([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], - ... [2.0, 2.0, 2.0], [3.0, 3.0, 3.0], [4.0, 4.0, 4.0]) - [0.29389262614624, 0.29389262614624, 0.29389262614624] - - Note: - - The function calculates the center of mass (COM) coordinates by taking - the midpoint between input coordinates, applying a transformation with - a scaling factor based on a sine function, and rounding the result to - 14 decimal places. - - The function checks for overlap among the calculated COM coordinates - and returns the COM coordinates based on the first input coordinate if - there is overlap. - """ - - # calculate the center of mass(COM) according to 5 coords on the same face - n = 10 - mid_a = mid_pt(c, d) - mid_b = mid_pt(d, e) - mid_c = mid_pt(a, e) - COM_a = [] - COM_b = [] - COM_c = [] - # calculate 3 COM here and check if they are overlapped - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(0.3*math.pi)), 14)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(0.3*math.pi)), 14)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(0.3*math.pi)), 14)) - # checking overlap - if round(COM_a[0], n) == round(COM_b[0], n) and round(COM_b[0], n) == round(COM_c[0], n) and \ - round(COM_a[1], n) == round(COM_b[1], n) and round(COM_b[1], n) == round(COM_c[1], n) and \ - round(COM_a[2], n) == round(COM_b[2], n) and round(COM_b[2], n) == round(COM_c[2], n): - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_coor.py b/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_coor.py deleted file mode 100644 index 0e3d2124..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_coor.py +++ /dev/null @@ -1,51 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt -from .dode_face_COM_coor import dode_face_COM_coor - - -def dode_face_COM_leg_coor(a: float, b: float, c: float, d: float, e: float): - """Calculates the center of mass (COM) and the coordinates of the five legs - of a protein based on five input coordinates on the same face of a dodecahedron. - - Args: - a (float): The first coordinate on the face. - b (float): The second coordinate on the face. - c (float): The third coordinate on the face. - d (float): The fourth coordinate on the face. - e (float): The fifth coordinate on the face. - - Returns: - list: A list of six lists, where the first element is a list of three - float values representing the X, Y, and Z coordinates of the center of mass (COM), - and the remaining five elements represent the coordinates of the five legs of - the protein, calculated as midpoints between the input coordinates. - - Raises: - None. - - Example: - >>> dode_face_COM_leg_coor([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], - ... [2.0, 2.0, 2.0], [3.0, 3.0, 3.0], [4.0, 4.0, 4.0]) - [[0.29389262614624, 0.29389262614624, 0.29389262614624], - [0.5, 0.5, 0.5], - [1.5, 1.5, 1.5], - [2.5, 2.5, 2.5], - [3.5, 3.5, 3.5], - [4.0, 4.0, 4.0]] - - Note: - - The function returns a list of six lists, where the first element is the - COM coordinates and the remaining five elements represent the coordinates - of the five legs of the protein. - """ - - # calculate COM and 5 legs of one protein, 6 coords in total [COM, lg1, lg2, lg3, lg4, lg5] - COM_leg = [] - COM_leg.append(dode_face_COM_coor(a, b, c, d, e)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, d)) - COM_leg.append(mid_pt(d, e)) - COM_leg.append(mid_pt(e, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_list_gen.py b/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_list_gen.py deleted file mode 100644 index 9e96fa83..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_COM_leg_list_gen.py +++ /dev/null @@ -1,45 +0,0 @@ -from .dode_face_dodecahedron_coord import dode_face_dodecahedron_coord -from .dode_face_COM_leg_coor import dode_face_COM_leg_coor - - -def dode_face_COM_leg_list_gen(radius: float): - """Generate the Center of Mass (COM) and leg coordinates of 12 faces of a dodecahedron. - - Args: - radius (float): The radius of the dodecahedron. - - Returns: - list: A list containing the COM and leg coordinates of 12 faces as a large list. - - """ - - # generate all COM and leg coords of 12 faces as a large list - coord = dode_face_dodecahedron_coord(radius) - COM_leg_list = [] - COM_leg_list.append(dode_face_COM_leg_coor( - coord[6], coord[18], coord[2], coord[14], coord[4])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[6], coord[4], coord[12], coord[0], coord[16])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[4], coord[14], coord[9], coord[8], coord[12])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[6], coord[18], coord[11], coord[10], coord[16])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[14], coord[2], coord[3], coord[15], coord[9])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[18], coord[11], coord[19], coord[3], coord[2])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[16], coord[10], coord[17], coord[1], coord[0])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[12], coord[0], coord[1], coord[13], coord[8])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[7], coord[17], coord[10], coord[11], coord[19])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[5], coord[13], coord[8], coord[9], coord[15])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[3], coord[19], coord[7], coord[5], coord[15])) - COM_leg_list.append(dode_face_COM_leg_coor( - coord[1], coord[17], coord[7], coord[5], coord[13])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_COM_list_gen.py b/ionerdss/model/platonic_solids/dode/dode_face_COM_list_gen.py deleted file mode 100644 index 2a523a91..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_COM_list_gen.py +++ /dev/null @@ -1,44 +0,0 @@ -from .dode_face_dodecahedron_coord import dode_face_dodecahedron_coord -from .dode_face_COM_coor import dode_face_COM_coor - - -def dode_face_COM_list_gen(radius: float): - """Generate the list of Centers of Mass (COM) of all 12 faces of a dodecahedron. - - Args: - radius (float): The radius of the dodecahedron. - - Returns: - list: A list containing the Centers of Mass (COM) of all 12 faces of the dodecahedron. - """ - - # generate the list of COM of all 12 faces - coord = dode_face_dodecahedron_coord(radius) - COM_list = [] - COM_list.append(dode_face_COM_coor( - coord[6], coord[18], coord[2], coord[14], coord[4])) - COM_list.append(dode_face_COM_coor( - coord[6], coord[4], coord[12], coord[0], coord[16])) - COM_list.append(dode_face_COM_coor( - coord[4], coord[14], coord[9], coord[8], coord[12])) - COM_list.append(dode_face_COM_coor( - coord[6], coord[18], coord[11], coord[10], coord[16])) - COM_list.append(dode_face_COM_coor( - coord[14], coord[2], coord[3], coord[15], coord[9])) - COM_list.append(dode_face_COM_coor( - coord[18], coord[11], coord[19], coord[3], coord[2])) - COM_list.append(dode_face_COM_coor( - coord[16], coord[10], coord[17], coord[1], coord[0])) - COM_list.append(dode_face_COM_coor( - coord[12], coord[0], coord[1], coord[13], coord[8])) - COM_list.append(dode_face_COM_coor( - coord[7], coord[17], coord[10], coord[11], coord[19])) - COM_list.append(dode_face_COM_coor( - coord[5], coord[13], coord[8], coord[9], coord[15])) - COM_list.append(dode_face_COM_coor( - coord[3], coord[19], coord[7], coord[5], coord[15])) - COM_list.append(dode_face_COM_coor( - coord[1], coord[17], coord[7], coord[5], coord[13])) - return COM_list - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_dodecahedron_coord.py b/ionerdss/model/platonic_solids/dode/dode_face_dodecahedron_coord.py deleted file mode 100644 index 546a36e3..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_dodecahedron_coord.py +++ /dev/null @@ -1,46 +0,0 @@ -def dode_face_dodecahedron_coord(radius: float): - """Generates the coordinates of the 20 vertices of a dodecahedron based on the given radius. - - Args: - radius (float): The radius of the dodecahedron. - - Returns: - list: A list of 20 vertex coordinates as lists in the form [x, y, z], where x, y, and z are floats. - """ - - # Setup coordinates of 20 verticies when scaler = 1 - scaler = radius/(3**0.5) - m = (1+5**(0.5))/2 - V1 = [0, m, 1/m] - V2 = [0, m, -1/m] - V3 = [0, -m, 1/m] - V4 = [0, -m, -1/m] - V5 = [1/m, 0, m] - V6 = [1/m, 0, -m] - V7 = [-1/m, 0, m] - V8 = [-1/m, 0, -m] - V9 = [m, 1/m, 0] - V10 = [m, -1/m, 0] - V11 = [-m, 1/m, 0] - V12 = [-m, -1/m, 0] - V13 = [1, 1, 1] - V14 = [1, 1, -1] - V15 = [1, -1, 1] - V16 = [1, -1, -1] - V17 = [-1, 1, 1] - V18 = [-1, 1, -1] - V19 = [-1, -1, 1] - V20 = [-1, -1, -1] - coord = [V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, - V11, V12, V13, V14, V15, V16, V17, V18, V19, V20] - # calculate coordinates according to the scaler as coord_ (list) - coord_ = [] - for i in coord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - coord_.append(temp_list) - return coord_ - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_input_coord.py b/ionerdss/model/platonic_solids/dode/dode_face_input_coord.py deleted file mode 100644 index 8da8f907..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_input_coord.py +++ /dev/null @@ -1,33 +0,0 @@ -from .dode_face_leg_reduce_coor_gen import dode_face_leg_reduce_coor_gen -import numpy as np - -def dode_face_input_coord(radius: float, sigma: float): - """Generates the input coordinates for a dodecahedron face based on the given radius and sigma. - - Args: - radius (float): The radius of the dodecahedron. - sigma (float): The sigma value for the dodecahedron face. - - Returns: - tuple: A tuple containing the following elements: - - COM (list): Center of Mass coordinates as a list [x, y, z], where x, y, and z are floats. - - lg1 (list): Vector coordinates for leg 1 as a list [x, y, z], where x, y, and z are floats. - - lg2 (list): Vector coordinates for leg 2 as a list [x, y, z], where x, y, and z are floats. - - lg3 (list): Vector coordinates for leg 3 as a list [x, y, z], where x, y, and z are floats. - - lg4 (list): Vector coordinates for leg 4 as a list [x, y, z], where x, y, and z are floats. - - lg5 (list): Vector coordinates for leg 5 as a list [x, y, z], where x, y, and z are floats. - - n (list): Normal vector coordinates as a list [x, y, z], where x, y, and z are floats. - """ - - coor = dode_face_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = coor_[0] - coor_[0] - lg1 = coor_[1] - coor_[0] - lg2 = coor_[2] - coor_[0] - lg3 = coor_[3] - coor_[0] - lg4 = coor_[4] - coor_[0] - lg5 = coor_[5] - coor_[0] - n = -coor_[0] - return COM, lg1, lg2, lg3, lg4, lg5, n - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce.py b/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce.py deleted file mode 100644 index c62e30ca..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce.py +++ /dev/null @@ -1,31 +0,0 @@ -import math -from ..gen_platonic.distance import distance - - -def dode_face_leg_reduce(COM: float, leg: float, sigma: float): - """Calculates the reduced length of a dodecahedron leg based on the given center of mass (COM), leg coordinates, - and sigma value. - - Args: - COM (float): The coordinates of the center of mass as a list [x, y, z], where x, y, and z are floats. - leg (float): The coordinates of the leg as a list [x, y, z], where x, y, and z are floats. - sigma (float): The sigma value for the dodecahedron face. - - Returns: - list: A list containing the reduced coordinates of the leg after applying the reduction factor. - The list contains three elements [x', y', z'], where x', y', and z' are the reduced coordinates of the leg - rounded to 14 decimal places. - """ - - # calculate the recuced length when considering the sigma value - n = 14 - m = (1+5**(0.5))/2 - angle = 2*math.atan(m) - red_len = sigma/(2*math.sin(angle/2)) - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], n)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce_coor_gen.py deleted file mode 100644 index 370b71f1..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_leg_reduce_coor_gen.py +++ /dev/null @@ -1,38 +0,0 @@ -from .dode_face_COM_leg_list_gen import dode_face_COM_leg_list_gen -from .dode_face_leg_reduce import dode_face_leg_reduce - - -def dode_face_leg_reduce_coor_gen(radius: float, sigma: float): - """Generates the reduced coordinates for the center of mass (COM) and legs of a dodecahedron face - based on the given radius and sigma. - - Args: - radius (float): The radius of the dodecahedron. - sigma (float): The sigma value for the dodecahedron face. - - Returns: - list: A list of lists containing the reduced coordinates for the COM and legs of each dodecahedron face. - Each element in the outer list represents a dodecahedron face, and contains a list with the following elements: - - COM (list): Center of Mass coordinates as a list [x, y, z], where x, y, and z are floats. - - leg1 (list): Vector coordinates for leg 1 after reduction as a list [x, y, z], where x, y, and z are floats. - - leg2 (list): Vector coordinates for leg 2 after reduction as a list [x, y, z], where x, y, and z are floats. - - leg3 (list): Vector coordinates for leg 3 after reduction as a list [x, y, z], where x, y, and z are floats. - - leg4 (list): Vector coordinates for leg 4 after reduction as a list [x, y, z], where x, y, and z are floats. - - leg5 (list): Vector coordinates for leg 5 after reduction as a list [x, y, z], where x, y, and z are floats. - """ - - # Generating all the coords of COM and legs when sigma exists - COM_leg_list = dode_face_COM_leg_list_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 5: - temp_list.append(dode_face_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/dode/dode_face_write.py b/ionerdss/model/platonic_solids/dode/dode_face_write.py deleted file mode 100644 index 4040f7b9..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_face_write.py +++ /dev/null @@ -1,306 +0,0 @@ -from ..gen_platonic.angle_cal import angle_cal -from .dode_face_leg_reduce_coor_gen import dode_face_leg_reduce_coor_gen -from .dode_face_input_coord import dode_face_input_coord - - -def dode_face_write(radius: float, sigma: float,create_Solid: bool = False): - """Generate input file for dodecahedron face-centered simulation. - - This function takes a radius and a sigma value as input parameters, - and generates an input file for a dodecahedron face-centered simulation - using the provided parameters. The input file is written to a file named - 'parm.inp' and contains information about simulation parameters, - boundaries, molecules, and reactions. - - Args: - radius (float): Radius of the dodecahedron. - sigma (float): Sigma value. - create_solid (bool): This is for use in PlatonicSolids.createSolid. - - Returns: - parm.inp/cube.mol file: inputs for NERDSS if create_solid == False - reaction information if create_Solid == True - - """ - - if create_Solid == True: - COM, lg1, lg2, lg3, lg4, lg5, n = dode_face_input_coord(radius, sigma) - coord = dode_face_leg_reduce_coor_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][3], coord[4][0], coord[4][1]) - - output_reactions_dict :dict = { - "n": n, - "coord": coord, - "theta1": theta1, - "theta2": theta2, - "phi1": phi1, - "phi2": phi2, - "omega": omega - } - output_mol_dict: dict = { - "COM": COM, - "lg1": lg1, - "lg2": lg2, - "lg3": lg3, - "lg4": lg4, - "lg5": lg5,} - return output_reactions_dict, output_mol_dict - else: - COM, lg1, lg2, lg3, lg4, lg5, n = dode_face_input_coord(radius, sigma) - coord = dode_face_leg_reduce_coor_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][3], coord[4][0], coord[4][1]) - - f = open('parm.inp', 'w') - f.write(' # Input file (dodecahedron face-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' dode : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' dode(lg1) + dode(lg1) <-> dode(lg1!1).dode(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg2) <-> dode(lg2!1).dode(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg3) + dode(lg3) <-> dode(lg3!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg4) + dode(lg4) <-> dode(lg4!1).dode(lg4!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg5) + dode(lg5) <-> dode(lg5!1).dode(lg5!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg2) <-> dode(lg1!1).dode(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg3) <-> dode(lg1!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg4) <-> dode(lg1!1).dode(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg5) <-> dode(lg1!1).dode(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg3) <-> dode(lg2!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg4) <-> dode(lg2!1).dode(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg5) <-> dode(lg2!1).dode(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg3) + dode(lg4) <-> dode(lg3!1).dode(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg3) + dode(lg5) <-> dode(lg3!1).dode(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg4) + dode(lg5) <-> dode(lg4!1).dode(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('dode.mol', 'w') - f.write('##\n') - f.write('# Dodecahedron (face-centered) information file.\n') - f.write('##\n\n') - f.write('Name = dode\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('lg4 ' + str(round(lg4[0], 8)) + ' ' + - str(round(lg4[1], 8)) + ' ' + str(round(lg4[2], 8)) + '\n') - f.write('lg5 ' + str(round(lg5[0], 8)) + ' ' + - str(round(lg5[1], 8)) + ' ' + str(round(lg5[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 5\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('com lg4\n') - f.write('com lg5\n') - f.write('\n') - - - # DODECAHEDEON VERTEX AS COM - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert.py b/ionerdss/model/platonic_solids/dode/dode_vert.py deleted file mode 100644 index aec5779c..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert.py +++ /dev/null @@ -1,20 +0,0 @@ -from .dode_vert_write import dode_vert_write - - -def dode_vert(radius: float, sigma: float): - """ - Generates and writes vertex coordinates for a dodecahedron to a file. - - Args: - radius (float): Radius of the dodecahedron. - sigma (float): Sigma value for generating vertex coordinates. - - Returns: - parm.inp/cube.mol file: inputs for NERDSS - """ - - dode_vert_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg.py b/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg.py deleted file mode 100644 index 8f1af233..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg.py +++ /dev/null @@ -1,28 +0,0 @@ -import numpy as np -from ..gen_platonic.mid_pt import mid_pt - - -def dode_vert_COM_leg(COM: float, a: float, b: float, c: float): - """ - Calculates and returns the vertices of a dodecahedron leg based on the center of mass (COM) and three reference points. - - Args: - COM (float): Center of mass of the dodecahedron. - a (float): First reference point. - b (float): Second reference point. - c (float): Third reference point. - - Returns: - list: List of vertices as [COM, lega, legb, legc], rounded to 10 decimal places. - - Example: - >>> dode_vert_COM_leg(1.0, 2.0, 3.0, 4.0) - [1.0, 1.5, 2.5, 3.5] - """ - - lega = mid_pt(COM, a) - legb = mid_pt(COM, b) - legc = mid_pt(COM, c) - return [np.around(COM, 10), np.around(lega, 10), np.around(legb, 10), np.around(legc, 10)] - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg_gen.py b/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg_gen.py deleted file mode 100644 index 255f40ca..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_COM_leg_gen.py +++ /dev/null @@ -1,68 +0,0 @@ -from .dode_vert_coord import dode_vert_coord -from .dode_vert_COM_leg import dode_vert_COM_leg - - -def dode_vert_COM_leg_gen(radius: float): - """Generates and returns a list of dodecahedron leg vertices based on the center of mass (COM) and radius. - - Args: - radius (float): Radius of the dodecahedron. - - Returns: - list: List of vertices as [COM_leg1, COM_leg2, ..., COM_leg20], where each COM_leg is a list of vertices as [COM, lega, legb, legc], rounded to 10 decimal places. - - Example: - >>> dode_vert_COM_leg_gen(1.0) - [ - [COM1, lega1, legb1, legc1], - [COM2, lega2, legb2, legc2], - ... - [COM20, lega20, legb20, legc20] - ] - """ - - coord = dode_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(dode_vert_COM_leg( - coord[0], coord[1], coord[12], coord[16])) - COM_leg_list.append(dode_vert_COM_leg( - coord[1], coord[0], coord[13], coord[17])) - COM_leg_list.append(dode_vert_COM_leg( - coord[2], coord[3], coord[14], coord[18])) - COM_leg_list.append(dode_vert_COM_leg( - coord[3], coord[2], coord[15], coord[19])) - COM_leg_list.append(dode_vert_COM_leg( - coord[4], coord[6], coord[12], coord[14])) - COM_leg_list.append(dode_vert_COM_leg( - coord[5], coord[7], coord[13], coord[15])) - COM_leg_list.append(dode_vert_COM_leg( - coord[6], coord[4], coord[16], coord[18])) - COM_leg_list.append(dode_vert_COM_leg( - coord[7], coord[5], coord[17], coord[19])) - COM_leg_list.append(dode_vert_COM_leg( - coord[8], coord[9], coord[12], coord[13])) - COM_leg_list.append(dode_vert_COM_leg( - coord[9], coord[8], coord[14], coord[15])) - COM_leg_list.append(dode_vert_COM_leg( - coord[10], coord[11], coord[16], coord[17])) - COM_leg_list.append(dode_vert_COM_leg( - coord[11], coord[10], coord[18], coord[19])) - COM_leg_list.append(dode_vert_COM_leg( - coord[12], coord[0], coord[4], coord[8])) - COM_leg_list.append(dode_vert_COM_leg( - coord[13], coord[1], coord[5], coord[8])) - COM_leg_list.append(dode_vert_COM_leg( - coord[14], coord[2], coord[4], coord[9])) - COM_leg_list.append(dode_vert_COM_leg( - coord[15], coord[3], coord[5], coord[9])) - COM_leg_list.append(dode_vert_COM_leg( - coord[16], coord[0], coord[6], coord[10])) - COM_leg_list.append(dode_vert_COM_leg( - coord[17], coord[1], coord[7], coord[10])) - COM_leg_list.append(dode_vert_COM_leg( - coord[18], coord[2], coord[6], coord[11])) - COM_leg_list.append(dode_vert_COM_leg( - coord[19], coord[3], coord[7], coord[11])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_coord.py b/ionerdss/model/platonic_solids/dode/dode_vert_coord.py deleted file mode 100644 index 29342828..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_coord.py +++ /dev/null @@ -1,46 +0,0 @@ -def dode_vert_coord(radius: float): - """Calculates and returns the coordinates of the vertices of a dodecahedron with the given radius. - - Args: - radius (float): The radius of the dodecahedron. - - Returns: - List[List[float]]: A list of lists representing the coordinates of the vertices of the dodecahedron. - Each inner list contains three float values representing the x, y, and z coordinates - of a vertex. - - """ - scaler = radius/(3**0.5) - m = (1+5**(0.5))/2 - V0 = [0, m, 1/m] - V1 = [0, m, -1/m] - V2 = [0, -m, 1/m] - V3 = [0, -m, -1/m] - V4 = [1/m, 0, m] - V5 = [1/m, 0, -m] - V6 = [-1/m, 0, m] - V7 = [-1/m, 0, -m] - V8 = [m, 1/m, 0] - V9 = [m, -1/m, 0] - V10 = [-m, 1/m, 0] - V11 = [-m, -1/m, 0] - V12 = [1, 1, 1] - V13 = [1, 1, -1] - V14 = [1, -1, 1] - V15 = [1, -1, -1] - V16 = [-1, 1, 1] - V17 = [-1, 1, -1] - V18 = [-1, -1, 1] - V19 = [-1, -1, -1] - coord = [V0, V1, V2, V3, V4, V5, V6, V7, V8, V9, - V10, V11, V12, V13, V14, V15, V16, V17, V18, V19] - coord_ = [] - for i in coord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - coord_.append(temp_list) - return coord_ - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_input_coord.py b/ionerdss/model/platonic_solids/dode/dode_vert_input_coord.py deleted file mode 100644 index ba82d83b..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_input_coord.py +++ /dev/null @@ -1,33 +0,0 @@ -from .dode_vert_leg_reduce_coor_gen import dode_vert_leg_reduce_coor_gen -import numpy as np - -def dode_vert_input_coord(radius: float, sigma: float): - """Generates input coordinates for a dodecahedron vertex. - - This function generates input coordinates for a dodecahedron vertex, given the radius and sigma values. The input - coordinates are calculated based on the radius and sigma values using the dode_vert_leg_reduce_coor_gen function - from the .dode_vert_leg_reduce_coor_gen module. - - Args: - radius (float): The radius of the dodecahedron vertex. - sigma (float): The sigma value for the dodecahedron vertex. - - Returns: - tuple: A tuple containing the following five numpy arrays: - - COM: The center of mass (COM) of the dodecahedron vertex. - - lg1: The first leg vector of the dodecahedron vertex. - - lg2: The second leg vector of the dodecahedron vertex. - - lg3: The third leg vector of the dodecahedron vertex. - - n: The normalized vector of the dodecahedron vertex. - """ - - coor = dode_vert_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = np.around(coor_[0] - coor_[0], 12) - lg1 = np.around(coor_[1] - coor_[0], 12) - lg2 = np.around(coor_[2] - coor_[0], 12) - lg3 = np.around(coor_[3] - coor_[0], 12) - n = np.around(coor_[0]/np.linalg.norm(coor_[0]), 12) - return COM, lg1, lg2, lg3, n - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce.py b/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce.py deleted file mode 100644 index 36b6227b..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce.py +++ /dev/null @@ -1,29 +0,0 @@ -from ..gen_platonic.distance import distance - - -def dode_vert_leg_reduce(COM: float, leg: float, sigma: float): - """ - Reduces the length of a dodecahedron leg based on the center of mass (COM), leg vector, and sigma value. - - This function reduces the length of a dodecahedron leg based on the provided center of mass (COM), leg vector, and - sigma value. The reduction is performed by calculating a ratio based on the sigma value and the distance between the - center of mass and the leg vector. The leg vector is then scaled by this ratio and added to the center of mass to - obtain the reduced leg vector. - - Args: - COM (float): The center of mass (COM) of the dodecahedron vertex. - leg (float): The leg vector of the dodecahedron vertex. - sigma (float): The sigma value for the dodecahedron vertex. - - Returns: - list: A list containing the three reduced leg vector coordinates. - """ - - red_len = sigma/2 - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], 8)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce_coor_gen.py deleted file mode 100644 index 0194b0a9..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_leg_reduce_coor_gen.py +++ /dev/null @@ -1,35 +0,0 @@ -from .dode_vert_COM_leg_gen import dode_vert_COM_leg_gen -from .dode_vert_leg_reduce import dode_vert_leg_reduce - -def dode_vert_leg_reduce_coor_gen(radius: float, sigma: float): - """ - Generates reduced center of mass (COM) and leg vectors for a dodecahedron vertex based on radius and sigma values. - - This function generates a list of reduced center of mass (COM) and leg vectors for a dodecahedron vertex based on the - provided radius and sigma values. The reduced COM and leg vectors are obtained by calling the dode_vert_COM_leg_gen - function to generate the original COM and leg vectors, and then passing them to the dode_vert_leg_reduce function to - reduce their lengths. The reduced COM and leg vectors are stored in a list and returned. - - Args: - radius (float): The radius of the dodecahedron. - sigma (float): The sigma value for the dodecahedron vertex. - - Returns: - list: A list of lists, where each inner list contains the reduced center of mass (COM) and leg vectors for a - dodecahedron vertex. - """ - - COM_leg_list = dode_vert_COM_leg_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(dode_vert_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_norm_input.py b/ionerdss/model/platonic_solids/dode/dode_vert_norm_input.py deleted file mode 100644 index d0ba9b1b..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_norm_input.py +++ /dev/null @@ -1,38 +0,0 @@ -from ..gen_platonic.distance import distance -from .dode_vert_input_coord import dode_vert_input_coord -import numpy as np - -def dode_vert_norm_input(radius: float, sigma: float): - """ - Calculates normalized input values for a dodecahedron vertex based on radius and sigma values. - - This function calculates the normalized center of mass (COM) and leg vectors for a dodecahedron vertex based on the - provided radius and sigma values. The normalized COM and leg vectors are obtained by calling the dode_vert_input_coord - function to calculate the original COM and leg vectors, and then performing various calculations to normalize their - values. The normalized COM and leg vectors are stored in numpy arrays and returned. - - Args: - radius (float): The radius of the dodecahedron. - sigma (float): The sigma value for the dodecahedron vertex. - - Returns: - numpy.ndarray: A numpy array representing the normalized center of mass (COM) vector. - numpy.ndarray: A numpy array representing the normalized first leg (lg1) vector. - numpy.ndarray: A numpy array representing the normalized second leg (lg2) vector. - numpy.ndarray: A numpy array representing the normalized third leg (lg3) vector. - numpy.ndarray: A numpy array representing the normalized normal (n) vector. - """ - - COM, lg1, lg2, lg3, n = dode_vert_input_coord(radius, sigma) - length = distance(lg1, lg2) - dis1 = ((-length/2)**2+(-((length/2)*(3**0.5))/3)**2)**0.5 - dis2 = distance(COM, lg1) - height = (dis2**2-dis1**2)**0.5 - lg1_ = np.array([-length/2, -((length/2)*(3**0.5))/3, -height]) - lg2_ = np.array([length/2, -((length/2)*(3**0.5))/3, -height]) - lg3_ = np.array([0, ((length/2)*(3**0.5))/3*2, -height]) - COM_ = np.array([0, 0, 0]) - n_ = np.array([0, 0, 1]) - return COM_, lg1_, lg2_, lg3_, n_ - - diff --git a/ionerdss/model/platonic_solids/dode/dode_vert_write.py b/ionerdss/model/platonic_solids/dode/dode_vert_write.py deleted file mode 100644 index b4605b67..00000000 --- a/ionerdss/model/platonic_solids/dode/dode_vert_write.py +++ /dev/null @@ -1,139 +0,0 @@ -from .dode_vert_norm_input import dode_vert_norm_input - - -def dode_vert_write(radius: float, sigma: float): - """ - Writes input parameters for a dodecahedron vertex-centered simulation to a file. - - Args: - radius (float): Radius of the dodecahedron. - sigma (float): Sigma value for the simulation. - - Returns: - parm.inp/cube.mol file: inputs for NERDSS - """ - - COM, lg1, lg2, lg3, n = dode_vert_norm_input(radius, sigma) - f = open('parm.inp', 'w') - f.write(' # Input file (dodecahedron vertex-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' dode : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' dode(lg1) + dode(lg1) <-> dode(lg1!1).dode(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg2) <-> dode(lg2!1).dode(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg3) + dode(lg3) <-> dode(lg3!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg2) <-> dode(lg1!1).dode(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg1) + dode(lg3) <-> dode(lg1!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' dode(lg2) + dode(lg3) <-> dode(lg2!1).dode(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('dode.mol', 'w') - f.write('##\n') - f.write('# Dodecahedron (vertex-centered) information file.\n') - f.write('##\n\n') - f.write('Name = dode\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - -# ICOSAHEDRON FACE AS COM - diff --git a/ionerdss/model/platonic_solids/gen_platonic/COM_leg_coord.py b/ionerdss/model/platonic_solids/gen_platonic/COM_leg_coord.py deleted file mode 100644 index 0fdc74f5..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/COM_leg_coord.py +++ /dev/null @@ -1,47 +0,0 @@ -from .mid_pt import mid_pt -from .face_COM_coord import face_COM_coord - - -def COM_leg_coord(a: float, b: float, c: float): - """Calculate the center of mass (COM) leg coordinates for an icosahedron face. - - This function calculates the center of mass (COM) leg coordinates for an icosahedron face - with three given coordinates `a`, `b`, and `c` using the `icos_face_COM_coord()` and `mid_pt()` - functions from the `icos_face_COM_coord` and `mid_pt` modules respectively. The COM leg coordinates - are calculated as follows: - - The COM of the face using `icos_face_COM_coord()` function - - The mid-point of each pair of vertices using `mid_pt()` function - - Args: - a (float): The first coordinate of the icosahedron face. - b (float): The second coordinate of the icosahedron face. - c (float): The third coordinate of the icosahedron face. - - Returns: - List[list[float]]: The center of mass (COM) leg coordinates as a list of lists of three floats. - The list has four sub-lists, each containing the COM leg coordinates for a pair of vertices. - - Examples: - >>> a = [0, 0, 0] - >>> b = [1, 1, 1] - >>> c = [2, 2, 2] - >>> icos_face_COM_leg_coord(a, b, c) - [[1.3660254037847, 1.3660254037847, 1.3660254037847], - [0.5, 0.5, 0.5], - [1.5, 1.5, 1.5], - [1.0, 1.0, 1.0]] - - Notes: - - The COM leg coordinates are calculated using the `icos_face_COM_coord()` function for the face - and `mid_pt()` function for the mid-points of pairs of vertices. - - The calculated COM leg coordinates are returned as a list of lists, where each sub-list contains - three floats representing the COM leg coordinates for a pair of vertices. - """ - COM_leg = [] - COM_leg.append(face_COM_coord(a, b, c)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/gen_platonic/COM_leg_list_gen.py b/ionerdss/model/platonic_solids/gen_platonic/COM_leg_list_gen.py deleted file mode 100644 index c3faf5bd..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/COM_leg_list_gen.py +++ /dev/null @@ -1,42 +0,0 @@ -from .vert_coord import vert_coord -from .COM_leg_coord import COM_leg_coord - - -def COM_leg_list_gen(radius: float): - """Generate Center of Mass (COM) and Leg Coordinates List for an Icosahedron Face. - This function generates the Center of Mass (COM) and Leg Coordinates List for each face of an icosahedron given the radius of the circumscribed sphere. - - Args: - radius (float): The radius of the circumscribed sphere of the icosahedron. - - Returns: - list: A list containing the Center of Mass (COM) and Leg Coordinates for each face of the icosahedron. The list contains 19 tuples, where each tuple contains three numpy arrays representing the COM and two leg coordinates of a face. - """ - - coord = vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(COM_leg_coord(coord[0], coord[2], coord[8])) - COM_leg_list.append(COM_leg_coord(coord[0], coord[8], coord[4])) - COM_leg_list.append(COM_leg_coord(coord[0], coord[4], coord[6])) - COM_leg_list.append(COM_leg_coord(coord[0], coord[6], coord[10])) - COM_leg_list.append(COM_leg_coord(coord[0], coord[10], coord[2])) - COM_leg_list.append(COM_leg_coord(coord[3], coord[7], coord[5])) - COM_leg_list.append(COM_leg_coord(coord[3], coord[5], coord[9])) - COM_leg_list.append(COM_leg_coord(coord[3], coord[9], coord[1])) - COM_leg_list.append(COM_leg_coord(coord[3], coord[1], coord[11])) - COM_leg_list.append(COM_leg_coord(coord[3], coord[11], coord[7])) - COM_leg_list.append(COM_leg_coord(coord[7], coord[2], coord[5])) - COM_leg_list.append(COM_leg_coord(coord[2], coord[5], coord[8])) - COM_leg_list.append(COM_leg_coord(coord[5], coord[8], coord[9])) - COM_leg_list.append(COM_leg_coord(coord[8], coord[9], coord[4])) - COM_leg_list.append(COM_leg_coord(coord[9], coord[4], coord[1])) - COM_leg_list.append(COM_leg_coord(coord[4], coord[1], coord[6])) - COM_leg_list.append(COM_leg_coord(coord[1], coord[6], coord[11])) - COM_leg_list.append(COM_leg_coord( - coord[6], coord[11], coord[10])) - COM_leg_list.append(COM_leg_coord( - coord[11], coord[10], coord[7])) - COM_leg_list.append(COM_leg_coord(coord[10], coord[7], coord[2])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/gen_platonic/__init__.py b/ionerdss/model/platonic_solids/gen_platonic/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/gen_platonic/angle_cal.py b/ionerdss/model/platonic_solids/gen_platonic/angle_cal.py deleted file mode 100644 index 66a36ddf..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/angle_cal.py +++ /dev/null @@ -1,55 +0,0 @@ -import math -import numpy as np - - -def angle_cal(COM1: float, leg1: float, COM2: float, leg2: float): - """Calculates angles between vectors based on given inputs. - - Args: - COM1 (float): Center of Mass (COM) for the first leg. - leg1 (float): Endpoint of the first leg. - COM2 (float): Center of Mass (COM) for the second leg. - leg2 (float): Endpoint of the second leg. - - Returns: - tuple: A tuple containing the following angles (in radians) rounded to 8 decimal places: - - theta1 (float): Angle between vector from COM1 to leg1 and vector from leg1 to leg2. - - theta2 (float): Angle between vector from COM2 to leg2 and vector from leg2 to leg1. - - phi1 (float): Angle between vectors perpendicular to leg1 and leg2, passing through COM1. - - phi2 (float): Angle between vectors perpendicular to leg2 and leg1, passing through COM2. - - omega (float): Angle between vectors perpendicular to leg1 and leg2, passing through leg1 and leg2. - """ - - n = 8 - c1 = np.array(COM1) - p1 = np.array(leg1) - c2 = np.array(COM2) - p2 = np.array(leg2) - v1 = p1 - c1 - v2 = p2 - c2 - sig1 = p1 - p2 - sig2 = -sig1 - theta1 = round(math.acos(np.dot(v1, sig1) / - (np.linalg.norm(v1)*np.linalg.norm(sig1))), n) - theta2 = round(math.acos(np.dot(v2, sig2) / - (np.linalg.norm(v2)*np.linalg.norm(sig2))), n) - t1 = np.cross(v1, sig1) - t2 = np.cross(v1, c1) # n1 = c1 here - t1_hat = t1/np.linalg.norm(t1) - t2_hat = t2/np.linalg.norm(t2) - phi1 = round(math.acos(np.around(np.dot(t1_hat, t2_hat), n)), n) - t3 = np.cross(v2, sig2) - t4 = np.cross(v2, c2) # n2 = c2 here - t3_hat = t3/np.linalg.norm(t3) - t4_hat = t4/np.linalg.norm(t4) - phi2 = round(math.acos(np.around(np.dot(t3_hat, t4_hat), n)), n) - t1_ = np.cross(sig1, v1) - t2_ = np.cross(sig1, v2) - t1__hat = t1_/np.linalg.norm(t1_) - t2__hat = t2_/np.linalg.norm(t2_) - omega = round(math.acos(np.around(np.dot(t1__hat, t2__hat), n)), n) - return theta1, theta2, phi1, phi2, omega - - -# DODECAHEDEON FACE AS COM - diff --git a/ionerdss/model/platonic_solids/gen_platonic/distance.py b/ionerdss/model/platonic_solids/gen_platonic/distance.py deleted file mode 100644 index 9c30703b..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/distance.py +++ /dev/null @@ -1,44 +0,0 @@ -import unittest -import numpy as np -from typing import List - -def distance(a: List[float], b: List[float]) -> float: - """Compute the Euclidean distance between two points in n-dimensional space. - - Args: - a (List[float]): The coordinates of the first point. - b (List[float]): The coordinates of the second point. - - Returns: - float: The Euclidean distance between the two points. - - - Examples: - >>> a = [0, 0, 0] - >>> b = [1, 1, 1] - >>> distance(a, b) - 1.7320508075688772 - - Notes - This function computes the Euclidean distance between two points by taking - the square root of the sum of squared differences of each coordinate. The - result is rounded to 15 decimal places using string formatting. - """ - return float(f"{np.linalg.norm(np.array(a) - np.array(b)):.15f}") - -class TestDistance(unittest.TestCase): - def test_distance(self): - a = [0, 0, 0] - b = [1, 1, 1] - self.assertAlmostEqual(distance(a, b), 1.7320508075688772) - - a = [3, 4, 0] - b = [0, 0, 12] - self.assertAlmostEqual(distance(a, b), 13.0) - - a = [0, 4] - b = [3, 0] - self.assertAlmostEqual(distance(a, b), 5.0) - -if __name__ == '__main__': - unittest.main() diff --git a/ionerdss/model/platonic_solids/gen_platonic/face_COM_coord.py b/ionerdss/model/platonic_solids/gen_platonic/face_COM_coord.py deleted file mode 100644 index 2f9f369e..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/face_COM_coord.py +++ /dev/null @@ -1,52 +0,0 @@ -import math -from .mid_pt import mid_pt - - -def face_COM_coord(a: float, b: float, c: float): - """Calculate the center of mass (COM) coordinates for an icosahedron face. - - This function calculates the center of mass (COM) coordinates for an icosahedron face - with three given coordinates `a`, `b`, and `c` using the `mid_pt()` function from the - `mid_pt` module. The COM coordinates are calculated based on the formula: - COM = original_coordinate + (mid_point_coordinate - original_coordinate) / (1 + sin(30 degrees)) - - Args: - a (float): The first coordinate of the icosahedron face. - b (float): The second coordinate of the icosahedron face. - c (float): The third coordinate of the icosahedron face. - - Returns: - List[float]: The center of mass (COM) coordinates as a list of three floats. - - Examples: - >>> a = [0, 0, 0] - >>> b = [1, 1, 1] - >>> c = [2, 2, 2] - >>> icos_face_COM_coord(a, b, c) - [1.3660254037847, 1.3660254037847, 1.3660254037847] - - Notes: - - The COM coordinates are calculated based on the formula mentioned above, where `sin()` function takes - angle in radians. The angle is calculated as 30 degrees converted to radians using `math.pi`. - - The calculated COM coordinates are rounded to 12 decimal places using the `round()` function. - - The function returns the COM coordinates as a list of three floats. - """ - mid_a = mid_pt(b, c) - mid_b = mid_pt(a, c) - mid_c = mid_pt(a, b) - COM_a = [] - COM_b = [] - COM_c = [] - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(30/180*math.pi)), 12)) - if COM_a == COM_b and COM_b == COM_c: - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/gen_platonic/mid_pt.py b/ionerdss/model/platonic_solids/gen_platonic/mid_pt.py deleted file mode 100644 index d06a2d75..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/mid_pt.py +++ /dev/null @@ -1,29 +0,0 @@ -def mid_pt(a: float, b: float): - """Compute the mid-point between two coordinates in 3-dimensional space. - - Parameters: - a (float): The first coordinate in the form of [x, y, z]. - b (float): The second coordinate in the form of [x, y, z]. - - Returns: - List[float]: The mid-point coordinates in the form of [x, y, z]. - - - Examples - >>> a = [0.0, 0.0, 0.0] - >>> b = [2.0, 4.0, 6.0] - >>> mid_pt(a, b) - [1.0, 2.0, 3.0] - - Notes - This function calculates the mid-point between two coordinates in 3-dimensional space - by taking the average of the corresponding x, y, and z coordinates of the two points. - The result is rounded to 15 decimal places using the `round()` function with `n` set to 15, - which is the value of `n` used in the function implementation. - """ - - # this is a seperate function for calculating mid point of two coords - n = 15 - return [round((a[0]+b[0])/2, n), round((a[1]+b[1])/2, n), round((a[2]+b[2])/2, n)] - - diff --git a/ionerdss/model/platonic_solids/gen_platonic/vert_coord.py b/ionerdss/model/platonic_solids/gen_platonic/vert_coord.py deleted file mode 100644 index 0a6b51ea..00000000 --- a/ionerdss/model/platonic_solids/gen_platonic/vert_coord.py +++ /dev/null @@ -1,44 +0,0 @@ -import math - - -def vert_coord(radius: float): - """Generates the vertex coordinates of an icosahedron face. - - Args: - radius (float): Radius of the icosahedron. - - Returns: - list: A list of vertex coordinates of the icosahedron face. - - Example: - >>> icos_face_vert_coord(1.0) - [[v0_x, v0_y, v0_z], - [v1_x, v1_y, v1_z], - ... - ] - """ - scaler = radius/(2*math.sin(2*math.pi/5)) - m = (1+5**0.5)/2 - v0 = [0, 1, m] - v1 = [0, 1, -m] - v2 = [0, -1, m] - v3 = [0, -1, -m] - v4 = [1, m, 0] - v5 = [1, -m, 0] - v6 = [-1, m, 0] - v7 = [-1, -m, 0] - v8 = [m, 0, 1] - v9 = [m, 0, -1] - v10 = [-m, 0, 1] - v11 = [-m, 0, -1] - VertCoord = [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/geometry.py b/ionerdss/model/platonic_solids/geometry.py new file mode 100644 index 00000000..3f9b87d3 --- /dev/null +++ b/ionerdss/model/platonic_solids/geometry.py @@ -0,0 +1,69 @@ +"""Geometry utilities for Platonic solids generation.""" + +import math +import numpy as np +from typing import Tuple + +def angle_cal(COM1: np.ndarray, leg1: np.ndarray, COM2: np.ndarray, leg2: np.ndarray) -> Tuple[float, float, float, float, float]: + """Calculates angles between vectors based on given inputs. + + Args: + COM1: Center of Mass (COM) for the first leg. + leg1: Endpoint of the first leg. + COM2: Center of Mass (COM) for the second leg. + leg2: Endpoint of the second leg. + + Returns: + tuple: (theta1, theta2, phi1, phi2, omega) in radians rounded to 8 decimal places. + """ + n = 8 + # Ensure inputs are numpy arrays + c1 = np.array(COM1) + p1 = np.array(leg1) + c2 = np.array(COM2) + p2 = np.array(leg2) + + v1 = p1 - c1 + v2 = p2 - c2 + sig1 = p1 - p2 + sig2 = -sig1 + + # Calculate angles + # Note: Added error handling for floating point precision issues in arccos + + def safe_acos(x): + return math.acos(max(-1.0, min(1.0, x))) + + dot_theta1 = np.dot(v1, sig1) / (np.linalg.norm(v1) * np.linalg.norm(sig1)) + theta1 = round(safe_acos(dot_theta1), n) + + dot_theta2 = np.dot(v2, sig2) / (np.linalg.norm(v2) * np.linalg.norm(sig2)) + theta2 = round(safe_acos(dot_theta2), n) + + t1 = np.cross(v1, sig1) + t2 = np.cross(v1, c1) + t1_hat = t1 / np.linalg.norm(t1) + t2_hat = t2 / np.linalg.norm(t2) + phi1 = round(safe_acos(np.around(np.dot(t1_hat, t2_hat), n)), n) + + t3 = np.cross(v2, sig2) + t4 = np.cross(v2, c2) + t3_hat = t3 / np.linalg.norm(t3) + t4_hat = t4 / np.linalg.norm(t4) + phi2 = round(safe_acos(np.around(np.dot(t3_hat, t4_hat), n)), n) + + t1_ = np.cross(sig1, v1) + t2_ = np.cross(sig1, v2) + t1__hat = t1_ / np.linalg.norm(t1_) + t2__hat = t2_ / np.linalg.norm(t2_) + omega = round(safe_acos(np.around(np.dot(t1__hat, t2__hat), n)), n) + + return theta1, theta2, phi1, phi2, omega + +def distance(a: np.ndarray, b: np.ndarray) -> float: + """Compute Euclidean distance between two points.""" + return float(np.linalg.norm(np.array(a) - np.array(b))) + +def mid_pt(a: np.ndarray, b: np.ndarray) -> np.ndarray: + """Compute mid-point between two points.""" + return (np.array(a) + np.array(b)) / 2.0 diff --git a/ionerdss/model/platonic_solids/icos/__init__.py b/ionerdss/model/platonic_solids/icos/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/icos/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/icos/icos_face.py b/ionerdss/model/platonic_solids/icos/icos_face.py deleted file mode 100644 index 7f3f3cf8..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face.py +++ /dev/null @@ -1,21 +0,0 @@ -from .icos_face_write import icos_face_write - - -def icos_face(radius: float, sigma: float): - """Write an icosahedron face with given radius and sigma to a file. - - This function writes an icosahedron face with the given radius and sigma values - to a file using the `icos_face_write()` function from the `icos_face_write` module. - - Args: - radius (float): The radius of the icosahedron face. - sigma (float): The sigma value for the icosahedron face. - - Returns: - parm.inp/icos.mol: input files for NERDSS - """ - icos_face_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_COM_coord.py b/ionerdss/model/platonic_solids/icos/icos_face_COM_coord.py deleted file mode 100644 index bffe2dc2..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_COM_coord.py +++ /dev/null @@ -1,52 +0,0 @@ -import math -from ..gen_platonic.mid_pt import mid_pt - - -def icos_face_COM_coord(a: float, b: float, c: float): - """Calculate the center of mass (COM) coordinates for an icosahedron face. - - This function calculates the center of mass (COM) coordinates for an icosahedron face - with three given coordinates `a`, `b`, and `c` using the `mid_pt()` function from the - `mid_pt` module. The COM coordinates are calculated based on the formula: - COM = original_coordinate + (mid_point_coordinate - original_coordinate) / (1 + sin(30 degrees)) - - Args: - a (float): The first coordinate of the icosahedron face. - b (float): The second coordinate of the icosahedron face. - c (float): The third coordinate of the icosahedron face. - - Returns: - List[float]: The center of mass (COM) coordinates as a list of three floats. - - Examples: - >>> a = [0, 0, 0] - >>> b = [1, 1, 1] - >>> c = [2, 2, 2] - >>> icos_face_COM_coord(a, b, c) - [1.3660254037847, 1.3660254037847, 1.3660254037847] - - Notes: - - The COM coordinates are calculated based on the formula mentioned above, where `sin()` function takes - angle in radians. The angle is calculated as 30 degrees converted to radians using `math.pi`. - - The calculated COM coordinates are rounded to 12 decimal places using the `round()` function. - - The function returns the COM coordinates as a list of three floats. - """ - mid_a = mid_pt(b, c) - mid_b = mid_pt(a, c) - mid_c = mid_pt(a, b) - COM_a = [] - COM_b = [] - COM_c = [] - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(30/180*math.pi)), 12)) - if COM_a == COM_b and COM_b == COM_c: - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_COM_leg_coord.py b/ionerdss/model/platonic_solids/icos/icos_face_COM_leg_coord.py deleted file mode 100644 index 690b8bc9..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_COM_leg_coord.py +++ /dev/null @@ -1,47 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt -from .icos_face_COM_coord import icos_face_COM_coord - - -def icos_face_COM_leg_coord(a: float, b: float, c: float): - """Calculate the center of mass (COM) leg coordinates for an icosahedron face. - - This function calculates the center of mass (COM) leg coordinates for an icosahedron face - with three given coordinates `a`, `b`, and `c` using the `icos_face_COM_coord()` and `mid_pt()` - functions from the `icos_face_COM_coord` and `mid_pt` modules respectively. The COM leg coordinates - are calculated as follows: - - The COM of the face using `icos_face_COM_coord()` function - - The mid-point of each pair of vertices using `mid_pt()` function - - Args: - a (float): The first coordinate of the icosahedron face. - b (float): The second coordinate of the icosahedron face. - c (float): The third coordinate of the icosahedron face. - - Returns: - List[list[float]]: The center of mass (COM) leg coordinates as a list of lists of three floats. - The list has four sub-lists, each containing the COM leg coordinates for a pair of vertices. - - Examples: - >>> a = [0, 0, 0] - >>> b = [1, 1, 1] - >>> c = [2, 2, 2] - >>> icos_face_COM_leg_coord(a, b, c) - [[1.3660254037847, 1.3660254037847, 1.3660254037847], - [0.5, 0.5, 0.5], - [1.5, 1.5, 1.5], - [1.0, 1.0, 1.0]] - - Notes: - - The COM leg coordinates are calculated using the `icos_face_COM_coord()` function for the face - and `mid_pt()` function for the mid-points of pairs of vertices. - - The calculated COM leg coordinates are returned as a list of lists, where each sub-list contains - three floats representing the COM leg coordinates for a pair of vertices. - """ - COM_leg = [] - COM_leg.append(icos_face_COM_coord(a, b, c)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_COM_list_gen.py b/ionerdss/model/platonic_solids/icos/icos_face_COM_list_gen.py deleted file mode 100644 index d59328dd..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_COM_list_gen.py +++ /dev/null @@ -1,39 +0,0 @@ -from .icos_face_vert_coord import icos_face_vert_coord -from .icos_face_COM_coord import icos_face_COM_coord - - -def icos_face_COM_list_gen(radius: float): - """Generates a list of coordinates representing the centers of mass (COM) of the faces of an icosahedron, - given the radius of the icosahedron. - - Args: - radius (float): The radius of the icosahedron. - - Returns: - list: A list of 20 COM coordinates, each representing the center of mass of a face of the icosahedron. - """ - coord = icos_face_vert_coord(radius) - COM_list = [] - COM_list.append(icos_face_COM_coord(coord[0], coord[2], coord[8])) - COM_list.append(icos_face_COM_coord(coord[0], coord[8], coord[4])) - COM_list.append(icos_face_COM_coord(coord[0], coord[4], coord[6])) - COM_list.append(icos_face_COM_coord(coord[0], coord[6], coord[10])) - COM_list.append(icos_face_COM_coord(coord[0], coord[10], coord[2])) - COM_list.append(icos_face_COM_coord(coord[3], coord[7], coord[5])) - COM_list.append(icos_face_COM_coord(coord[3], coord[5], coord[9])) - COM_list.append(icos_face_COM_coord(coord[3], coord[9], coord[1])) - COM_list.append(icos_face_COM_coord(coord[3], coord[1], coord[11])) - COM_list.append(icos_face_COM_coord(coord[3], coord[11], coord[7])) - COM_list.append(icos_face_COM_coord(coord[7], coord[2], coord[5])) - COM_list.append(icos_face_COM_coord(coord[2], coord[5], coord[8])) - COM_list.append(icos_face_COM_coord(coord[5], coord[8], coord[9])) - COM_list.append(icos_face_COM_coord(coord[8], coord[9], coord[4])) - COM_list.append(icos_face_COM_coord(coord[9], coord[4], coord[1])) - COM_list.append(icos_face_COM_coord(coord[4], coord[1], coord[6])) - COM_list.append(icos_face_COM_coord(coord[1], coord[6], coord[11])) - COM_list.append(icos_face_COM_coord(coord[6], coord[11], coord[10])) - COM_list.append(icos_face_COM_coord(coord[11], coord[10], coord[7])) - COM_list.append(icos_face_COM_coord(coord[10], coord[7], coord[2])) - return COM_list - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_input_coord.py b/ionerdss/model/platonic_solids/icos/icos_face_input_coord.py deleted file mode 100644 index 658e87a6..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_input_coord.py +++ /dev/null @@ -1,28 +0,0 @@ -from .icos_face_leg_reduce_coord_gen import icos_face_leg_reduce_coord_gen -import numpy as np - -def icos_face_input_coord(radius: float, sigma: float): - """Generates input coordinates for an icosahedron face. - - Args: - radius (float): Radius of the icosahedron. - sigma (float): Sigma value for leg reduction. - - Returns: - list: A list of coordinates including Center of Mass (COM), leg1 vector, leg2 vector, - leg3 vector, and negative of COM. - - Example: - >>> icos_face_input_coord(1.0, 0.5) - [COM, lg1, lg2, lg3, n] - """ - coor = icos_face_leg_reduce_coord_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = coor_[0] - coor_[0] - lg1 = coor_[1] - coor_[0] - lg2 = coor_[2] - coor_[0] - lg3 = coor_[3] - coor_[0] - n = -coor_[0] - return [COM, lg1, lg2, lg3, n] - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce.py b/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce.py deleted file mode 100644 index d4a2265e..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce.py +++ /dev/null @@ -1,31 +0,0 @@ -import math -from ..gen_platonic.distance import distance - - -def icos_face_leg_reduce(COM: float, leg: float, sigma: float): - """ Generates a list of reduced leg coordinates for each center of mass (COM) of an icosahedron face. - - Args: - radius (float): Radius of the icosahedron. - sigma (float): Sigma value for leg reduction. - - Returns: - list: A list of reduced leg coordinates for each COM. - - Example: - >>> icos_face_leg_reduce_coord_gen(1.0, 0.5) - [[COM1, leg1_red_x, leg1_red_y, leg1_red_z], - [COM2, leg2_red_x, leg2_red_y, leg2_red_z], - ... - ] - """ - n = 12 - angle = math.acos(-5**0.5/3) - red_len = sigma/(2*math.sin(angle/2)) - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], n)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce_coord_gen.py b/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce_coord_gen.py deleted file mode 100644 index 0ecf7d49..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_leg_reduce_coord_gen.py +++ /dev/null @@ -1,32 +0,0 @@ -from ..gen_platonic.COM_leg_list_gen import COM_leg_list_gen -from .icos_face_leg_reduce import icos_face_leg_reduce - -def icos_face_leg_reduce_coord_gen(radius: float, sigma: float): - """Reduces the length of a leg of an icosahedron face. - - Args: - COM (float): Center of Mass (COM) coordinate. - leg (float): Leg coordinate. - sigma (float): Sigma value for leg reduction. - - Returns: - list: A list of reduced leg coordinates. - - Example: - >>> icos_face_leg_reduce([0.0, 0.0, 0.0], [1.0, 1.0, 1.0], 0.5) - [leg_red_x, leg_red_y, leg_red_z] - """ - COM_leg_list = COM_leg_list_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(icos_face_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_vert_coord.py b/ionerdss/model/platonic_solids/icos/icos_face_vert_coord.py deleted file mode 100644 index 1be6d1c4..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_vert_coord.py +++ /dev/null @@ -1,44 +0,0 @@ -import math - - -def icos_face_vert_coord(radius: float): - """Generates the vertex coordinates of an icosahedron face. - - Args: - radius (float): Radius of the icosahedron. - - Returns: - list: A list of vertex coordinates of the icosahedron face. - - Example: - >>> icos_face_vert_coord(1.0) - [[v0_x, v0_y, v0_z], - [v1_x, v1_y, v1_z], - ... - ] - """ - scaler = radius/(2*math.sin(2*math.pi/5)) - m = (1+5**0.5)/2 - v0 = [0, 1, m] - v1 = [0, 1, -m] - v2 = [0, -1, m] - v3 = [0, -1, -m] - v4 = [1, m, 0] - v5 = [1, -m, 0] - v6 = [-1, m, 0] - v7 = [-1, -m, 0] - v8 = [m, 0, 1] - v9 = [m, 0, -1] - v10 = [-m, 0, 1] - v11 = [-m, 0, -1] - VertCoord = [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/icos/icos_face_write.py b/ionerdss/model/platonic_solids/icos/icos_face_write.py deleted file mode 100644 index 68b8ff3d..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_face_write.py +++ /dev/null @@ -1,182 +0,0 @@ -from ..gen_platonic.angle_cal import angle_cal -from .icos_face_leg_reduce_coord_gen import icos_face_leg_reduce_coord_gen -from .icos_face_input_coord import icos_face_input_coord - - -def icos_face_write(radius: float, sigma: float,create_Solid: bool=False): - """ Writes input parameters for a simulation of an icosahedron face-centered system. - - Args: - radius (float): Radius of the icosahedron. - sigma (float): Sigma parameter for the simulation. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - This function writes input parameters for a simulation of an icosahedron face-centered system - to a file named 'parm.inp'. The input parameters include simulation settings such as the number - of iterations, time step, and output frequency, as well as parameters related to the geometry - and interaction potentials of the system. The input parameters are derived from the given radius - and sigma values, which are used to calculate other quantities using helper functions - `icos_face_input_coord`, `icos_face_leg_reduce_coord_gen`, and `angle_cal`. - """ - if create_Solid == True: - COM, lg1, lg2, lg3, n = icos_face_input_coord(radius, sigma) - coord = icos_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][2], coord[11][0], coord[11][3]) - - output_reactions_dict :dict = { - "n": n, - "coord": coord, - "theta1": theta1, - "theta2": theta2, - "phi1": phi1, - "phi2": phi2, - "omega": omega - } - output_mol_dict: dict = { - "COM": COM, - "lg1": lg1, - "lg2": lg2, - "lg3": lg3,} - return output_reactions_dict, output_mol_dict - - - - else: - - COM, lg1, lg2, lg3, n = icos_face_input_coord(radius, sigma) - coord = icos_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][2], coord[11][0], coord[11][3]) - - f = open('parm.inp', 'w') - f.write(' # Input file (icosahedron face-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' dode : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' icos(lg1) + icos(lg1) <-> icos(lg1!1).icos(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg2) <-> icos(lg2!1).icos(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg3) + icos(lg3) <-> icos(lg3!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg2) <-> icos(lg1!1).icos(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg3) <-> icos(lg1!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg3) <-> icos(lg2!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('icos.mol', 'w') - f.write('##\n') - f.write('# Icosahehedron (face-centered) information file.\n') - f.write('##\n\n') - f.write('Name = icos\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - -# ICOSAHEDRON VERTEX AS COM - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert.py b/ionerdss/model/platonic_solids/icos/icos_vert.py deleted file mode 100644 index 7d0b1e5f..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert.py +++ /dev/null @@ -1,32 +0,0 @@ -from .icos_vert_write import icos_vert_write - - -def icos_vert(radius: float, sigma: float): - """Generate vertices for an icosahedron and write to a file. - - This function generates the vertices of an icosahedron with the given - radius and sigma, and writes them to a file using the icos_vert_write - function from the .icos_vert_write module. After writing is complete, - it prints a message indicating the file writing status. - - Args: - radius (float): The radius of the icosahedron. - sigma (float): The sigma value used in the generation of vertices. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Example: - >>> icos_vert(2.0, 0.5) - File writing complete! - """ - icos_vert_write(radius, sigma) - print('File writing complete!') - return 0 - - -# -----------------------------------Data Visualization------------------------------ - -# Analysis tools for 'histogram_complexes_time.dat' file - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg.py b/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg.py deleted file mode 100644 index c03965ab..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg.py +++ /dev/null @@ -1,28 +0,0 @@ -import numpy as np -from ..gen_platonic.mid_pt import mid_pt - - -def icos_vert_COM_leg(COM: float, a: float, b: float, c: float, d: float, e: float): - """Calculate center of mass (COM) and legs from COM to each point. - - Args: - COM (float): The center of mass point. - a (float): Point A. - b (float): Point B. - c (float): Point C. - d (float): Point D. - e (float): Point E. - - Returns: - list: A list containing the center of mass and legs coordinates, rounded to 10 decimal places. - """ - lega = mid_pt(COM, a) - legb = mid_pt(COM, b) - legc = mid_pt(COM, c) - legd = mid_pt(COM, d) - lege = mid_pt(COM, e) - result = [np.around(COM, 10), np.around(lega, 10), np.around( - legb, 10), np. around(legc, 10), np.around(legd, 10), np.around(lege, 10)] - return result - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg_gen.py b/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg_gen.py deleted file mode 100644 index ca6176b2..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_COM_leg_gen.py +++ /dev/null @@ -1,44 +0,0 @@ -from .icos_vert_coord import icos_vert_coord -from .icos_vert_COM_leg import icos_vert_COM_leg - -def icos_vert_COM_leg_gen(radius: float): - """Generate a list of center of mass (COM) and legs coordinates for an icosahedron. - - The function calculates the center of mass and legs coordinates for an icosahedron - with the given radius, using the `icos_vert_coord` and `icos_vert_COM_leg` functions. - - Args: - radius (float): The radius of the icosahedron. - - Returns: - list: A list of center of mass and legs coordinates for the icosahedron. - """ - coord = icos_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(icos_vert_COM_leg( - coord[0], coord[2], coord[8], coord[4], coord[6], coord[10])) - COM_leg_list.append(icos_vert_COM_leg( - coord[1], coord[4], coord[6], coord[11], coord[3], coord[9])) - COM_leg_list.append(icos_vert_COM_leg( - coord[2], coord[0], coord[10], coord[7], coord[5], coord[8])) - COM_leg_list.append(icos_vert_COM_leg( - coord[3], coord[1], coord[11], coord[7], coord[5], coord[9])) - COM_leg_list.append(icos_vert_COM_leg( - coord[4], coord[0], coord[6], coord[1], coord[9], coord[8])) - COM_leg_list.append(icos_vert_COM_leg( - coord[5], coord[2], coord[8], coord[7], coord[3], coord[9])) - COM_leg_list.append(icos_vert_COM_leg( - coord[6], coord[0], coord[10], coord[11], coord[1], coord[4])) - COM_leg_list.append(icos_vert_COM_leg( - coord[7], coord[3], coord[11], coord[10], coord[2], coord[5])) - COM_leg_list.append(icos_vert_COM_leg( - coord[8], coord[0], coord[2], coord[5], coord[9], coord[4])) - COM_leg_list.append(icos_vert_COM_leg( - coord[9], coord[8], coord[4], coord[1], coord[3], coord[5])) - COM_leg_list.append(icos_vert_COM_leg( - coord[10], coord[0], coord[2], coord[7], coord[11], coord[6])) - COM_leg_list.append(icos_vert_COM_leg( - coord[11], coord[10], coord[7], coord[3], coord[1], coord[6])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_center_coor.py b/ionerdss/model/platonic_solids/icos/icos_vert_center_coor.py deleted file mode 100644 index 91dff6ff..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_center_coor.py +++ /dev/null @@ -1,54 +0,0 @@ -import math -from ..gen_platonic.mid_pt import mid_pt - - -def icos_vert_center_coor(a: float, b: float, c: float, d: float, e: float): - """Calculate the coordinates of the center of mass for an icosahedron. - - This function calculates the coordinates of the center of mass (COM) for - an icosahedron, given the coordinates of five points (a, b, c, d, e) and - using the mid_pt function from the ..gen_platonic.mid_pt module. The COM - coordinates are computed based on the formula: - COM = point + (mid_point - point) / (1 + sin(0.3 * pi)) - - Args: - a (float): The coordinates of point a as a list or tuple of three float values. - b (float): The coordinates of point b as a list or tuple of three float values. - c (float): The coordinates of point c as a list or tuple of three float values. - d (float): The coordinates of point d as a list or tuple of three float values. - e (float): The coordinates of point e as a list or tuple of three float values. - - Returns: - list: The coordinates of the center of mass (COM) as a list of three float values. - - Example: - >>> a = [1.0, 2.0, 3.0] - >>> b = [4.0, 5.0, 6.0] - >>> c = [7.0, 8.0, 9.0] - >>> d = [10.0, 11.0, 12.0] - >>> e = [13.0, 14.0, 15.0] - >>> icos_vert_center_coor(a, b, c, d, e) - [5.18101203220144, 6.58101203220144, 7.98101203220144] - """ - n = 8 - mid_a = mid_pt(c, d) - mid_b = mid_pt(d, e) - mid_c = mid_pt(a, e) - COM_a = [] - COM_b = [] - COM_c = [] - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(0.3*math.pi)), 14)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(0.3*math.pi)), 14)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(0.3*math.pi)), 14)) - if round(COM_a[0], n) == round(COM_b[0], n) and round(COM_b[0], n) == round(COM_c[0], n) and \ - round(COM_a[1], n) == round(COM_b[1], n) and round(COM_b[1], n) == round(COM_c[1], n) and \ - round(COM_a[2], n) == round(COM_b[2], n) and round(COM_b[2], n) == round(COM_c[2], n): - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_check_dis.py b/ionerdss/model/platonic_solids/icos/icos_vert_check_dis.py deleted file mode 100644 index d49bf899..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_check_dis.py +++ /dev/null @@ -1,30 +0,0 @@ -from ..gen_platonic.distance import distance - - -def icos_vert_check_dis(cen: float, COM: float, lg1: float, lg2: float, lg3: float, lg4: float, lg5: float): - """Check distances between a center point and other points. - - Args: - cen (float): The center point. - COM (float): The center of mass point. - lg1 (float): Point 1. - lg2 (float): Point 2. - lg3 (float): Point 3. - lg4 (float): Point 4. - lg5 (float): Point 5. - - Returns: - tuple: A tuple containing the distances between the center point and other points. - """ - dis1 = round(distance(cen, lg1), 8) - dis2 = round(distance(cen, lg2), 8) - dis3 = round(distance(cen, lg3), 8) - dis4 = round(distance(cen, lg4), 8) - dis5 = round(distance(cen, lg5), 8) - dis_ = round(distance(COM, cen), 8) - if dis1 == dis2 and dis1 == dis3 and dis1 == dis4 and dis1 == dis5: - return dis1, dis_ - else: - return dis1, dis_ - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_coord.py b/ionerdss/model/platonic_solids/icos/icos_vert_coord.py deleted file mode 100644 index 1d93a7f2..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_coord.py +++ /dev/null @@ -1,40 +0,0 @@ -import math - - -def icos_vert_coord(radius: float): - """Generate vertex coordinates for an icosahedron with the given radius. - - The function calculates the vertex coordinates for an icosahedron with the given radius, - using mathematical formulas and scaling based on the radius. - - Args: - radius (float): The radius of the icosahedron. - - Returns: - list: A list of vertex coordinates for the icosahedron. - """ - scaler = radius/(2*math.sin(2*math.pi/5)) - m = (1+5**0.5)/2 - v0 = [0, 1, m] - v1 = [0, 1, -m] - v2 = [0, -1, m] - v3 = [0, -1, -m] - v4 = [1, m, 0] - v5 = [1, -m, 0] - v6 = [-1, m, 0] - v7 = [-1, -m, 0] - v8 = [m, 0, 1] - v9 = [m, 0, -1] - v10 = [-m, 0, 1] - v11 = [-m, 0, -1] - VertCoord = [v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_input_coord.py b/ionerdss/model/platonic_solids/icos/icos_vert_input_coord.py deleted file mode 100644 index 7fc452bd..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_input_coord.py +++ /dev/null @@ -1,30 +0,0 @@ -from .icos_vert_leg_reduce_coor_gen import icos_vert_leg_reduce_coor_gen -import numpy as np - - -def icos_vert_input_coord(radius: float, sigma: float): - """Generate input vertex coordinates for an icosahedron with the given radius and sigma. - - The function calculates the input vertex coordinates for an icosahedron with the given radius and sigma, - using mathematical formulas and numpy operations. - - Args: - radius (float): The radius of the icosahedron. - sigma (float): The sigma value for generating the vertex coordinates. - - Returns: - tuple: A tuple of input vertex coordinates for the icosahedron, including the center of mass (COM), - and the leg vectors (lg1, lg2, lg3, lg4, lg5) and the normalized normal vector (n). - """ - coor = icos_vert_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = np.around(coor_[0] - coor_[0], 12) - lg1 = np.around(coor_[1] - coor_[0], 12) - lg2 = np.around(coor_[2] - coor_[0], 12) - lg3 = np.around(coor_[3] - coor_[0], 12) - lg4 = np.around(coor_[4] - coor_[0], 12) - lg5 = np.around(coor_[5] - coor_[0], 12) - n = np.around(coor_[0]/np.linalg.norm(coor_[0]), 12) - return COM, lg1, lg2, lg3, lg4, lg5, n - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce.py b/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce.py deleted file mode 100644 index 6b616a6e..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce.py +++ /dev/null @@ -1,25 +0,0 @@ -from ..gen_platonic.distance import distance - - -def icos_vert_leg_reduce(COM: float, leg: float, sigma: float): - """Reduce the length of a leg vector of an icosahedron based on the center of mass (COM) and sigma. - - The function calculates the reduced length of a leg vector of an icosahedron based on the given center of mass (COM), - leg vector, and sigma value, using mathematical formulas and rounding to 8 decimal places. - - Args: - COM (float): The center of mass (COM) vector of the icosahedron. - leg (float): The leg vector of the icosahedron. - sigma (float): The sigma value for reducing the length of the leg vector. - - Returns: - list: A list of reduced leg vector coordinates for the icosahedron, rounded to 8 decimal places. - """ - red_len = sigma/2 - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], 8)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce_coor_gen.py deleted file mode 100644 index 2204ac37..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_leg_reduce_coor_gen.py +++ /dev/null @@ -1,32 +0,0 @@ -from .icos_vert_COM_leg_gen import icos_vert_COM_leg_gen -from .icos_vert_leg_reduce import icos_vert_leg_reduce - -def icos_vert_leg_reduce_coor_gen(radius: float, sigma: float): - """Generate reduced leg coordinates for an icosahedron based on the center of mass (COM) and sigma. - - The function generates a list of reduced leg coordinates for an icosahedron based on the given radius, sigma value, - and the center of mass (COM) and leg vectors calculated using the icos_vert_COM_leg_gen function. The leg coordinates - are reduced using the icos_vert_leg_reduce function, and the resulting coordinates are returned in a list. - - Args: - radius (float): The radius of the icosahedron. - sigma (float): The sigma value for reducing the length of the leg vectors. - - Returns: - list: A list of reduced leg coordinates for the icosahedron, containing lists of coordinates for each leg, - rounded to 8 decimal places. - """ - COM_leg_list = icos_vert_COM_leg_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 5: - temp_list.append(icos_vert_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_norm_input.py b/ionerdss/model/platonic_solids/icos/icos_vert_norm_input.py deleted file mode 100644 index 6302d045..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_norm_input.py +++ /dev/null @@ -1,38 +0,0 @@ -import math -import numpy as np - -def icos_vert_norm_input(scaler: float, dis_: float): - """Calculate normalized input coordinates for an icosahedron. - - The function calculates the normalized input coordinates for an icosahedron based on the given scaler and dis_ values. - The scaler value is used to scale the vectors, and the dis_ value is used to determine the z-coordinate of the leg - vectors. The resulting coordinates are returned as a tuple containing the center of mass (COM) vector, and the vectors - for each leg, rounded to 12 decimal places. - - Args: - scaler (float): The scaling factor for the vectors. - dis_ (float): The z-coordinate value for the leg vectors. - - Returns: - tuple: A tuple containing the center of mass (COM) vector, and vectors for each leg of the icosahedron. - Each vector is represented as a numpy array of shape (3,), and is rounded to 12 decimal places. - """ - c1 = math.cos(2*math.pi/5) - c2 = math.cos(math.pi/5) - s1 = math.sin(2*math.pi/5) - s2 = math.sin(4*math.pi/5) - v0 = scaler*np.array([0, 1]) - v1 = scaler*np.array([-s1, c1]) - v2 = scaler*np.array([-s2, -c2]) - v3 = scaler*np.array([s2, -c2]) - v4 = scaler*np.array([s1, c1]) - lg1 = np.array([v0[0], v0[1], -dis_]) - lg2 = np.array([v1[0], v1[1], -dis_]) - lg3 = np.array([v2[0], v2[1], -dis_]) - lg4 = np.array([v3[0], v3[1], -dis_]) - lg5 = np.array([v4[0], v4[1], -dis_]) - COM = np.array([0, 0, 0]) - n = np.array([0, 0, 1]) - return COM, lg1, lg2, lg3, lg4, lg5, n - - diff --git a/ionerdss/model/platonic_solids/icos/icos_vert_write.py b/ionerdss/model/platonic_solids/icos/icos_vert_write.py deleted file mode 100644 index 4155d22d..00000000 --- a/ionerdss/model/platonic_solids/icos/icos_vert_write.py +++ /dev/null @@ -1,274 +0,0 @@ -from .icos_vert_input_coord import icos_vert_input_coord -from .icos_vert_center_coor import icos_vert_center_coor -from .icos_vert_check_dis import icos_vert_check_dis -from .icos_vert_norm_input import icos_vert_norm_input - - -def icos_vert_write(radius: float, sigma: float): - """Write input file for icosahedron vertex-centered simulation. - - This function writes an input file in the required format for a icosahedron vertex-centered - simulation. The input file contains parameters, boundaries, molecules, and reactions - for the simulation. - - Args: - radius (float): Radius of the icosahedron. - sigma (float): Sigma value for the simulation. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - - Raises: - None - - Examples: - >>> icos_vert_write(5.0, 0.5) - - Notes: - - The input file is written to a file named 'parm.inp' in the current directory. - """ - COM_, lg1_, lg2_, lg3_, lg4_, lg5_, n_ = icos_vert_input_coord( - radius, sigma) - cen_ = icos_vert_center_coor(lg1_, lg2_, lg3_, lg4_, lg5_) - scaler, dis_ = icos_vert_check_dis( - cen_, COM_, lg1_, lg2_, lg3_, lg4_, lg5_) - COM, lg1, lg2, lg3, lg4, lg5, n = icos_vert_norm_input(scaler, dis_) - - f = open('parm.inp', 'w') - f.write(' # Input file (icosahedron vertex-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' icos : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' icos(lg1) + icos(lg1) <-> icos(lg1!1).icos(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg2) <-> icos(lg2!1).icos(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg3) + icos(lg3) <-> icos(lg3!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg4) + icos(lg4) <-> icos(lg4!1).icos(lg4!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg5) + icos(lg5) <-> icos(lg5!1).icos(lg5!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg2) <-> icos(lg1!1).icos(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg3) <-> icos(lg1!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg4) <-> icos(lg1!1).icos(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg1) + icos(lg5) <-> icos(lg1!1).icos(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg3) <-> icos(lg2!1).icos(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg4) <-> icos(lg2!1).icos(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg2) + icos(lg5) <-> icos(lg2!1).icos(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg3) + icos(lg4) <-> icos(lg3!1).icos(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg3) + icos(lg5) <-> icos(lg3!1).icos(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' icos(lg4) + icos(lg5) <-> icos(lg4!1).icos(lg5!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('icos.mol', 'w') - f.write('##\n') - f.write('# Icosahedron (vertex-centered) information file.\n') - f.write('##\n\n') - f.write('Name = icos\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('lg4 ' + str(round(lg4[0], 8)) + ' ' + - str(round(lg4[1], 8)) + ' ' + str(round(lg4[2], 8)) + '\n') - f.write('lg5 ' + str(round(lg5[0], 8)) + ' ' + - str(round(lg5[1], 8)) + ' ' + str(round(lg5[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 5\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('com lg4\n') - f.write('com lg5\n') - f.write('\n') - - -# OCTAHEDRON FACE AS COM - diff --git a/ionerdss/model/platonic_solids/octa/__init__.py b/ionerdss/model/platonic_solids/octa/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/octa/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/octa/octa_face.py b/ionerdss/model/platonic_solids/octa/octa_face.py deleted file mode 100644 index d45c06d3..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face.py +++ /dev/null @@ -1,26 +0,0 @@ -from .octa_face_write import octa_face_write - - -def octa_face(radius: float, sigma: float): - """Generate an octagonal face image. - - Args: - radius (float): The radius of the octagonal face. - sigma (float): The sigma value for generating the face. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Raises: - ValueError: If radius or sigma are not valid (e.g., negative values). - - Example: - To generate an octagonal face with a radius of 10 and a sigma of 1.5: - >>> octa_face(10, 1.5) - File writing complete! - """ - octa_face_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_COM_coord.py b/ionerdss/model/platonic_solids/octa/octa_face_COM_coord.py deleted file mode 100644 index bb57f255..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_COM_coord.py +++ /dev/null @@ -1,48 +0,0 @@ -import math -from ..gen_platonic.mid_pt import mid_pt - - -def octa_face_COM_coord(a: float, b: float, c: float): - """Calculate the center of mass (COM) coordinates for an octahedron face. - - Given the coordinates of three vertices of an octahedron face (a, b, c), this function - calculates the center of mass (COM) coordinates for that face using the midpoint formula - and a correction factor based on the sine of 30 degrees. - - Args: - a (float): The coordinates of the first vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - b (float): The coordinates of the second vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - c (float): The coordinates of the third vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - - Returns: - list: A list of three floats representing the x, y, and z coordinates of the center of mass - (COM) for the octahedron face. - - Example: - To calculate the center of mass coordinates for an octahedron face with vertices - a = [1.0, 2.0, 3.0], b = [4.0, 5.0, 6.0], and c = [7.0, 8.0, 9.0]: - >>> octa_face_COM_coord([1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]) - [3.5, 4.5, 5.5] - """ - mid_a = mid_pt(b, c) - mid_b = mid_pt(a, c) - mid_c = mid_pt(a, b) - COM_a = [] - COM_b = [] - COM_c = [] - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(30/180*math.pi)), 12)) - if COM_a == COM_b and COM_b == COM_c: - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_coord.py b/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_coord.py deleted file mode 100644 index 87c03908..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_coord.py +++ /dev/null @@ -1,47 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt -from .octa_face_COM_coord import octa_face_COM_coord - - -def octa_face_COM_leg_coord(a: float, b: float, c: float): - """Calculate the coordinates of the center of mass (COM) and midpoints of the legs - of an octahedron face. - - Given the coordinates of three vertices of an octahedron face (a, b, c), this function - calculates the coordinates of the center of mass (COM) and the midpoints of the legs of - that face using the 'octa_face_COM_coord' and 'mid_pt' functions from the respective - modules. - - Args: - a (float): The coordinates of the first vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - b (float): The coordinates of the second vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - c (float): The coordinates of the third vertex of the octahedron face as a list or tuple - of three floats representing the x, y, and z coordinates, respectively. - - Returns: - list: A list of four elements: - - A list of three floats representing the x, y, and z coordinates of the center of mass (COM) - for the octahedron face. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices a and b. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices b and c. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices c and a. - - Example: - To calculate the coordinates of the center of mass and midpoints of the legs for an octahedron - face with vertices a = [1.0, 2.0, 3.0], b = [4.0, 5.0, 6.0], and c = [7.0, 8.0, 9.0]: - >>> octa_face_COM_leg_coord([1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]) - [[3.5, 4.5, 5.5], [2.5, 3.5, 4.5], [5.5, 6.5, 7.5], [4.0, 5.0, 6.0]] - - """ - COM_leg = [] - COM_leg.append(octa_face_COM_coord(a, b, c)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_list_gen.py b/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_list_gen.py deleted file mode 100644 index f689ecb3..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_COM_leg_list_gen.py +++ /dev/null @@ -1,39 +0,0 @@ -from .octa_face_vert_coord import octa_face_vert_coord -from .octa_face_COM_leg_coord import octa_face_COM_leg_coord - - -def octa_face_COM_leg_list_gen(radius: float): - """Generate a list of center of mass (COM) and midpoints of legs for all octahedron faces. - - Given the radius of an octahedron, this function generates a list of center of mass (COM) - and midpoints of legs for all eight faces of the octahedron using the 'octa_face_vert_coord' - and 'octa_face_COM_leg_coord' functions from the respective modules. - - Args: - radius (float): The radius of the octahedron. - - Returns: - list: A list of eight elements, each element containing a list of four sub-elements: - - A list of three floats representing the x, y, and z coordinates of the center of mass (COM) - for a particular octahedron face. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices of that face. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices of that face. - - A list of three floats representing the x, y, and z coordinates of the midpoint of the leg - connecting vertices of that face. - """ - coord = octa_face_vert_coord(radius) - COM_leg_list = [] - - COM_leg_list.append(octa_face_COM_leg_coord(coord[0], coord[2], coord[4])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[0], coord[3], coord[4])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[0], coord[3], coord[5])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[0], coord[2], coord[5])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[1], coord[2], coord[4])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[1], coord[3], coord[4])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[1], coord[3], coord[5])) - COM_leg_list.append(octa_face_COM_leg_coord(coord[1], coord[2], coord[5])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_COM_list_gen.py b/ionerdss/model/platonic_solids/octa/octa_face_COM_list_gen.py deleted file mode 100644 index dd1921fc..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_COM_list_gen.py +++ /dev/null @@ -1,37 +0,0 @@ -from .octa_face_vert_coord import octa_face_vert_coord -from .octa_face_COM_coord import octa_face_COM_coord - - -def octa_face_COM_list_gen(radius: float): - """Generates a list of center of mass (COM) coordinates for the faces of an octahedron. - - Args: - radius (float): The radius of the octahedron. - - Returns: - List: A list of COM coordinates for the faces of the octahedron. - - Example: - coord = octa_face_vert_coord(radius) - COM_list = octa_face_COM_list_gen(radius) - print(COM_list) - - Note: - The octahedron is assumed to be centered at the origin (0,0,0) and aligned with the - coordinate axes. The function uses the octa_face_vert_coord() function to generate - the vertex coordinates of the octahedron, and then calculates the center of mass - coordinates for the faces using the octa_face_COM_coord() function. - """ - coord = octa_face_vert_coord(radius) - COM_list = [] - COM_list.append(octa_face_COM_coord(coord[0], coord[2], coord[4])) - COM_list.append(octa_face_COM_coord(coord[0], coord[3], coord[4])) - COM_list.append(octa_face_COM_coord(coord[0], coord[3], coord[5])) - COM_list.append(octa_face_COM_coord(coord[0], coord[2], coord[5])) - COM_list.append(octa_face_COM_coord(coord[1], coord[2], coord[4])) - COM_list.append(octa_face_COM_coord(coord[1], coord[3], coord[4])) - COM_list.append(octa_face_COM_coord(coord[1], coord[3], coord[5])) - COM_list.append(octa_face_COM_coord(coord[1], coord[2], coord[5])) - return COM_list - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_input_coord.py b/ionerdss/model/platonic_solids/octa/octa_face_input_coord.py deleted file mode 100644 index ceca132f..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_input_coord.py +++ /dev/null @@ -1,42 +0,0 @@ -from .octa_face_leg_reduce_coord_gen import octa_face_leg_reduce_coord_gen -import numpy as np - -def octa_face_input_coord(radius: float, sigma: float): - """Generates input coordinates for an octahedron face reduction algorithm. - - Args: - radius (float): The radius of the octahedron. - sigma (float): The sigma value for the reduction algorithm. - - Returns: - List: A list of input coordinates for the octahedron face reduction algorithm. - The list contains the following: - - COM (numpy.array): The center of mass (COM) coordinates for the octahedron face. - - lg1 (numpy.array): The first leg vector from COM to vertex 1. - - lg2 (numpy.array): The second leg vector from COM to vertex 2. - - lg3 (numpy.array): The third leg vector from COM to vertex 3. - - n (numpy.array): The normal vector of the octahedron face. - - Example: - radius = 1.0 - sigma = 0.5 - input_coord = octa_face_input_coord(radius, sigma) - print(input_coord) - - Note: - The octahedron is assumed to be centered at the origin (0,0,0) and aligned with the - coordinate axes. The function uses the octa_face_leg_reduce_coord_gen() function to generate - the input coordinates for the face reduction algorithm. The input coordinates include the - center of mass (COM) coordinates, leg vectors, and normal vector of the octahedron face. - """ - - coor = octa_face_leg_reduce_coord_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = coor_[0] - coor_[0] - lg1 = coor_[1] - coor_[0] - lg2 = coor_[2] - coor_[0] - lg3 = coor_[3] - coor_[0] - n = -coor_[0] - return [COM, lg1, lg2, lg3, n] - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce.py b/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce.py deleted file mode 100644 index 5d836c8e..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce.py +++ /dev/null @@ -1,42 +0,0 @@ -import math -from ..gen_platonic.distance import distance - - -def octa_face_leg_reduce(COM: float, leg: float, sigma: float): - """Reduces the length of an octahedron face leg by a given reduction factor sigma. - - Args: - COM (float): The center of mass (COM) coordinate of the octahedron face. - leg (float): The leg vector of the octahedron face. - sigma (float): The reduction factor for the leg length. - - Returns: - List[float]: A list of reduced leg coordinates after applying the reduction factor. - The list contains three floating point values representing the x, y, and z coordinates - of the reduced leg vector. - - Example: - COM = [0.0, 0.0, 0.0] - leg = [1.0, 2.0, 3.0] - sigma = 0.5 - leg_red = octa_face_leg_reduce(COM, leg, sigma) - print(leg_red) - - Note: - The function uses the math module to perform mathematical calculations. The reduction factor - sigma determines how much the length of the leg vector should be reduced. The leg vector is - reduced by scaling it with a ratio calculated based on the reduction factor and the distance - between the center of mass (COM) and the leg vector. The resulting reduced leg coordinates are - rounded to a given number of decimal places (n) before being returned as a list of floating - point values. - """ - n = 12 - angle = math.acos(-1/3) - red_len = sigma/(2*math.sin(angle/2)) - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], n)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce_coord_gen.py b/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce_coord_gen.py deleted file mode 100644 index b65b4d4d..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_leg_reduce_coord_gen.py +++ /dev/null @@ -1,46 +0,0 @@ -from ..gen_platonic.COM_leg_list_gen import COM_leg_list_gen -from .octa_face_COM_leg_list_gen import octa_face_COM_leg_list_gen -from .octa_face_leg_reduce import octa_face_leg_reduce - -def octa_face_leg_reduce_coord_gen(radius: float, sigma: float): - """Generates a list of reduced center of mass (COM) and leg coordinates of an octahedron face - based on the given radius and reduction factor sigma. - - Args: - radius (float): The radius of the octahedron. - sigma (float): The reduction factor for the leg length. - - Returns: - List[List[float]]: A list of reduced center of mass (COM) and leg coordinates for each - octahedron face. Each element in the list is a sublist containing four floating point - values: [COM, leg1_red, leg2_red, leg3_red]. The COM is the center of mass coordinate - of the octahedron face, and leg1_red, leg2_red, leg3_red are the reduced leg coordinates - after applying the reduction factor. - - Example: - radius = 5.0 - sigma = 0.5 - COM_leg_red_list = octa_face_leg_reduce_coord_gen(radius, sigma) - print(COM_leg_red_list) - - Note: - The function uses other functions from the 'gen_platonic' and 'octa_face_leg_reduce' modules - to generate the list of center of mass (COM) and leg coordinates, and then apply the reduction - factor to the leg coordinates. The resulting reduced COM and leg coordinates are returned as a - list of lists, where each sublist contains the COM and reduced leg coordinates for a specific - octahedron face. - """ - COM_leg_list = octa_face_COM_leg_list_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(octa_face_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_vert_coord.py b/ionerdss/model/platonic_solids/octa/octa_face_vert_coord.py deleted file mode 100644 index 917d69ad..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_vert_coord.py +++ /dev/null @@ -1,40 +0,0 @@ -def octa_face_vert_coord(radius: float): - """Generates the coordinates of the vertices of an octahedron based on the given radius. - - Args: - radius (float): The radius of the octahedron. - - Returns: - List[List[float]]: A list of vertex coordinates of the octahedron. Each element in the list - is a sublist containing three floating point values representing the (x, y, z) coordinates - of a vertex. - - Example: - radius = 5.0 - vert_coord = octa_face_vert_coord(radius) - print(vert_coord) - - Note: - The function generates the vertex coordinates of an octahedron centered at the origin (0, 0, 0) - with six vertices located at (+-radius, 0, 0), (0, +-radius, 0), and (0, 0, +-radius). The - resulting vertex coordinates are returned as a list of lists, where each sublist contains the - (x, y, z) coordinates of a specific vertex. - """ - scaler = radius - v0 = [1, 0, 0] - v1 = [-1, 0, 0] - v2 = [0, 1, 0] - v3 = [0, -1, 0] - v4 = [0, 0, 1] - v5 = [0, 0, -1] - VertCoord = [v0, v1, v2, v3, v4, v5] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/octa/octa_face_write.py b/ionerdss/model/platonic_solids/octa/octa_face_write.py deleted file mode 100644 index 8ccd4db9..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_face_write.py +++ /dev/null @@ -1,177 +0,0 @@ -from ..gen_platonic.angle_cal import angle_cal -from .octa_face_leg_reduce_coord_gen import octa_face_leg_reduce_coord_gen -from .octa_face_input_coord import octa_face_input_coord - - -def octa_face_write(radius: float, sigma: float,create_Solid: bool = False): - """Generate an input file for a simulation with parameters for octahedron face-centered system. - - Args: - radius (float): Radius of the octahedron. - sigma (float): Sigma value for the system. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Examples: - octa_face_write(5.0, 1.2) - - The function generates an input file 'parm.inp' for a simulation with parameters including - the radius and sigma value of an octahedron face-centered system. The input file contains - start parameters, start boundaries, start molecules, and start reactions sections with - specific parameters written to the file. - """ - if create_Solid == True: - COM, lg1, lg2, lg3, n = octa_face_input_coord(radius, sigma) - coord = octa_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][3], coord[1][0], coord[1][3]) - output_reactions_dict :dict = { - "n": n, - "coord": coord, - "theta1": theta1, - "theta2": theta2, - "phi1": phi1, - "phi2": phi2, - "omega": omega - } - output_mol_dict: dict = { - "COM": COM, - "lg1": lg1, - "lg2": lg2, - "lg3": lg3,} - return output_reactions_dict, output_mol_dict - else: - COM, lg1, lg2, lg3, n = octa_face_input_coord(radius, sigma) - coord = octa_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][3], coord[1][0], coord[1][3]) - - f = open('parm.inp', 'w') - f.write(' # Input file (octahedron face-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' octa : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' octa(lg1) + octa(lg1) <-> octa(lg1!1).octa(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' octa(lg2) + octa(lg2) <-> octa(lg2!1).octa(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' octa(lg3) + octa(lg3) <-> octa(lg3!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' octa(lg1) + octa(lg2) <-> octa(lg1!1).octa(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' octa(lg1) + octa(lg3) <-> octa(lg1!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' octa(lg2) + octa(lg3) <-> octa(lg2!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('octa.mol', 'w') - f.write('##\n') - f.write('# Octahehedron (face-centered) information file.\n') - f.write('##\n\n') - f.write('Name = octa\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - -# OCTAHEDRON VERTEX AS COM - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert.py b/ionerdss/model/platonic_solids/octa/octa_vert.py deleted file mode 100644 index 07134ee6..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert.py +++ /dev/null @@ -1,22 +0,0 @@ -from .octa_vert_write import octa_vert_write - - -def octa_vert(radius: float, sigma: float): - """ - Writes octagonal vertices to a file. - - Args: - radius (float): The radius of the octagon. - sigma (float): The standard deviation for the Gaussian distribution. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Example: - octa_vert(5.0, 1.0) - """ - octa_vert_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg.py b/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg.py deleted file mode 100644 index 32baba7e..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg.py +++ /dev/null @@ -1,36 +0,0 @@ -import numpy as np -from ..gen_platonic.mid_pt import mid_pt - - -def octa_vert_COM_leg(COM: float, a: float, b: float, c: float, d: float): - """Calculates the center of mass and leg vectors for an octagon. - - Args: - COM (float): The center of mass vector of the octagon, given as a tuple (x, y, z). - a (float): The position of vertex A of the octagon, given as a tuple (x, y, z). - b (float): The position of vertex B of the octagon, given as a tuple (x, y, z). - c (float): The position of vertex C of the octagon, given as a tuple (x, y, z). - d (float): The position of vertex D of the octagon, given as a tuple (x, y, z). - - Returns: - list: A list of the center of mass and leg vectors for the octagon. The list contains - 5 elements, each rounded to 10 decimal places, in the following order: - [COM, lega, legb, legc, legd], where COM is the center of mass vector and lega, legb, - legc, legd are the leg vectors. - - Example: - COM = (0.5, 0.5, 0.5) - a = (1.0, 0.0, 0.0) - b = (0.0, 1.0, 0.0) - c = (-1.0, 0.0, 0.0) - d = (0.0, -1.0, 0.0) - result = octa_vert_COM_leg(COM, a, b, c, d) - print(result) - """ - lega = mid_pt(COM, a) - legb = mid_pt(COM, b) - legc = mid_pt(COM, c) - legd = mid_pt(COM, d) - return [np.around(COM, 10), np.around(lega, 10), np.around(legb, 10), np.around(legc, 10), np.around(legd, 10)] - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg_gen.py b/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg_gen.py deleted file mode 100644 index ffd30480..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_COM_leg_gen.py +++ /dev/null @@ -1,37 +0,0 @@ -from .octa_vert_coord import octa_vert_coord -from .octa_vert_COM_leg import octa_vert_COM_leg - -def octa_vert_COM_leg_gen(radius: float): - """ - Generates center of mass and leg vectors for an octagon. - - Args: - radius (float): The radius of the octagon. - - Returns: - list: A list of center of mass and leg vectors for the octagon. - Each element in the list is a tuple of the form (COM, leg1, leg2, leg3, leg4), - where COM is the center of mass vector and leg1, leg2, leg3, leg4 are the leg vectors. - - Example: - coord = octa_vert_COM_leg_gen(5.0) - print(coord) - """ - - coord = octa_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(octa_vert_COM_leg( - coord[0], coord[2], coord[4], coord[3], coord[5])) - COM_leg_list.append(octa_vert_COM_leg( - coord[1], coord[2], coord[4], coord[3], coord[5])) - COM_leg_list.append(octa_vert_COM_leg( - coord[2], coord[1], coord[5], coord[0], coord[4])) - COM_leg_list.append(octa_vert_COM_leg( - coord[3], coord[1], coord[5], coord[0], coord[4])) - COM_leg_list.append(octa_vert_COM_leg( - coord[4], coord[1], coord[2], coord[0], coord[3])) - COM_leg_list.append(octa_vert_COM_leg( - coord[5], coord[1], coord[2], coord[0], coord[3])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_coord.py b/ionerdss/model/platonic_solids/octa/octa_vert_coord.py deleted file mode 100644 index 3289b138..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_coord.py +++ /dev/null @@ -1,35 +0,0 @@ -def octa_vert_coord(radius: float): - """Calculates the vertex coordinates of an octagon centered at the origin. - The vertex coordinates are scaled by the given radius. - - Args: - radius (float): The radius of the octagon. - - Returns: - list: A list of 6 vertex coordinates, each represented as a list of 3D coordinates [x, y, z]. - The coordinates are scaled by the given radius. - - Example: - radius = 2.0 - result = octa_vert_coord(radius) - print(result) - """ - - scaler = radius - v0 = [1, 0, 0] - v1 = [-1, 0, 0] - v2 = [0, 1, 0] - v3 = [0, -1, 0] - v4 = [0, 0, 1] - v5 = [0, 0, -1] - VertCoord = [v0, v1, v2, v3, v4, v5] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_input_coord.py b/ionerdss/model/platonic_solids/octa/octa_vert_input_coord.py deleted file mode 100644 index 20c391d3..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_input_coord.py +++ /dev/null @@ -1,42 +0,0 @@ -from .octa_vert_leg_reduce_coor_gen import octa_vert_leg_reduce_coor_gen -import numpy as np - - -def octa_vert_input_coord(radius: float, sigma: float): - """ Calculates the input coordinates of an octagonal vertex based on a given radius and sigma. - - The input coordinates are derived from the reduced coordinates of the octagonal vertex, which are generated - using the `octa_vert_leg_reduce_coor_gen` function. The input coordinates include the center of mass (COM) - of the vertex, as well as four leg vectors (lg1, lg2, lg3, and lg4) and a normal vector (n) with respect to - the center of mass. - - Args: - radius (float): The radius of the octagonal vertex. - sigma (float): The sigma value used for generating the reduced coordinates of the vertex. - - Returns: - tuple: A tuple containing the following input coordinates: - - COM (float): The center of mass of the vertex. - - lg1 (float): The first leg vector of the vertex. - - lg2 (float): The second leg vector of the vertex. - - lg3 (float): The third leg vector of the vertex. - - lg4 (float): The fourth leg vector of the vertex. - - n (float): The normal vector of the vertex. - - Example: - radius = 2.0 - sigma = 0.5 - result = octa_vert_input_coord(radius, sigma) - print(result) - """ - coor = octa_vert_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[4]) - COM = np.around(coor_[0] - coor_[0], 8) - lg1 = np.around(coor_[1] - coor_[0], 8) - lg2 = np.around(coor_[2] - coor_[0], 8) - lg3 = np.around(coor_[3] - coor_[0], 8) - lg4 = np.around(coor_[4] - coor_[0], 8) - n = np.around(coor_[0]/np.linalg.norm(coor_[0]), 8) - return COM, lg1, lg2, lg3, lg4, n - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce.py b/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce.py deleted file mode 100644 index 1a26bde4..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce.py +++ /dev/null @@ -1,34 +0,0 @@ -from ..gen_platonic.distance import distance - - -def octa_vert_leg_reduce(COM: float, leg: float, sigma: float): - """Reduces the length of an octagonal vertex leg based on a given center of mass (COM), leg vector, and sigma. - - The reduction of the leg length is calculated using the formula: leg_red = (leg - COM) * ratio + COM, where ratio - is calculated as 1 minus half of the sigma divided by the distance between COM and leg, as given by the `distance` - function from the `gen_platonic` module. - - Args: - COM (float): The center of mass (COM) of the octagonal vertex. - leg (float): The leg vector of the octagonal vertex. - sigma (float): The sigma value used for reducing the length of the leg. - - Returns: - list: A list containing the reduced leg vector (leg_red) of the octagonal vertex, with rounded values - to 8 decimal places. - - Example: - COM = [0, 0, 0] - leg = [1, 1, 1] - sigma = 0.5 - result = octa_vert_leg_reduce(COM, leg, sigma) - print(result) - """ - red_len = sigma/2 - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], 8)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce_coor_gen.py deleted file mode 100644 index 093f107f..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_leg_reduce_coor_gen.py +++ /dev/null @@ -1,44 +0,0 @@ -from .octa_vert_COM_leg_gen import octa_vert_COM_leg_gen -from .octa_vert_leg_reduce import octa_vert_leg_reduce - -def octa_vert_leg_reduce_coor_gen(radius: float, sigma: float): - """Generates a list of center of mass (COM) and reduced leg vectors for an octagonal vertex based on a given radius - and sigma value. - - This function uses the `octa_vert_COM_leg_gen` function to generate a list of COM and leg vectors for an octagonal - vertex with the given radius. Then, it applies the `octa_vert_leg_reduce` function to reduce the length of the leg - vectors based on the given sigma value, and stores the reduced COM and leg vectors in a list. - - Args: - radius (float): The radius of the octagonal vertex. - sigma (float): The sigma value used for reducing the length of the leg vectors. - - Returns: - list: A list of lists, where each sublist contains the reduced COM and leg vectors for an octagonal vertex. - The structure of the list is as follows: - [ - [COM1, leg_red1_1, leg_red1_2, leg_red1_3, leg_red1_4], - [COM2, leg_red2_1, leg_red2_2, leg_red2_3, leg_red2_4], - ... - ] - - Example: - radius = 1.0 - sigma = 0.5 - result = octa_vert_leg_reduce_coor_gen(radius, sigma) - print(result) - """ - COM_leg_list = octa_vert_COM_leg_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 4: - temp_list.append(octa_vert_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/octa/octa_vert_write.py b/ionerdss/model/platonic_solids/octa/octa_vert_write.py deleted file mode 100644 index 6f43c6ac..00000000 --- a/ionerdss/model/platonic_solids/octa/octa_vert_write.py +++ /dev/null @@ -1,198 +0,0 @@ -from .octa_vert_input_coord import octa_vert_input_coord - - -def octa_vert_write(radius: float, sigma: float): - """Generates an input file for a simulation of an octahedron vertex-centered - geometry with the specified radius and sigma value. - - Args: - radius (float): Radius of the octahedron vertex-centered geometry. - sigma (float): Sigma value used for generating the input file. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Example: - >>> radius = 1.0 - >>> sigma = 0.5 - >>> octa_vert_write(radius, sigma) - # Generates an input file 'parm.inp' with simulation parameters, - # boundaries, molecules, and reactions for octahedron vertex-centered - # geometry. - """ - - COM, lg1, lg2, lg3, lg4, n = octa_vert_input_coord(radius, sigma) - f = open('parm.inp', 'w') - f.write(' # Input file (octahedron vertex-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' octa : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' otca(lg1) + octa(lg1) <-> octa(lg1!1).octa(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg2) + octa(lg2) <-> octa(lg2!1).octa(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg3) + octa(lg3) <-> octa(lg3!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg4) + octa(lg4) <-> octa(lg4!1).octa(lg4!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg1) + octa(lg2) <-> octa(lg1!1).octa(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg1) + octa(lg3) <-> octa(lg1!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg1) + octa(lg4) <-> octa(lg1!1).octa(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg2) + octa(lg3) <-> octa(lg2!1).octa(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg2) + octa(lg4) <-> octa(lg2!1).octa(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' otca(lg3) + octa(lg4) <-> octa(lg3!1).octa(lg4!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('octa.mol', 'w') - f.write('##\n') - f.write('# Octahedron (vertex-centered) information file.\n') - f.write('##\n\n') - f.write('Name = octa\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('lg4 ' + str(round(lg4[0], 8)) + ' ' + - str(round(lg4[1], 8)) + ' ' + str(round(lg4[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 4\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('com lg4\n') - f.write('\n') - - -# CUBE FACE AS COM - diff --git a/ionerdss/model/platonic_solids/solids.py b/ionerdss/model/platonic_solids/solids.py new file mode 100644 index 00000000..5619a3d0 --- /dev/null +++ b/ionerdss/model/platonic_solids/solids.py @@ -0,0 +1,314 @@ +"""Specific implementation of Platonic solids coordinate generation.""" + +from abc import ABC, abstractmethod +from typing import List, Tuple +import math +import numpy as np +from .geometry import distance, mid_pt + +class PlatonicSolidGenerator(ABC): + """Abstract base class for Platonic solid generators.""" + + @property + @abstractmethod + def name(self) -> str: + pass + + @property + @abstractmethod + def num_sites(self) -> int: + pass + + @abstractmethod + def _get_vertices(self, radius: float) -> List[List[float]]: + """Calculate vertices for the solid.""" + pass + + @abstractmethod + def _get_face_indices(self) -> List[Tuple[int, ...]]: + """Return list of vertex indices for each face.""" + pass + + @property + @abstractmethod + def angle_indices(self) -> Tuple[Tuple[int, int], ...]: + """Return indices for angle calculation (theta1, theta2, phi1, phi2).""" + pass + + @abstractmethod + def _get_reduction_angle(self) -> float: + """Return the angle used for leg reduction.""" + pass + + def generate_coordinates(self, radius: float, sigma: float) -> List[List[np.ndarray]]: + """ + Generate coordinates for ALL faces. + Returns: List of [COM, leg1, leg2, ..., Normal] for each face. + """ + vertices = self._get_vertices(radius) + face_indices_list = self._get_face_indices() + + # Calculate reduction params + angle = self._get_reduction_angle() + denom = 2 * math.sin(angle / 2) + red_len = sigma / denom + + all_faces_coords = [] + + for face_indices in face_indices_list: + face_verts = [vertices[i] for i in face_indices] + + # 1. Calculate Face COM + com = np.mean(face_verts, axis=0) + + # 2. Calculate Legs (Edge Midpoints) + legs = [] + num_verts = len(face_verts) + for i in range(num_verts): + p1 = face_verts[i] + p2 = face_verts[(i + 1) % num_verts] + legs.append(mid_pt(p1, p2)) + + # 3. Reduce Legs + reduced_legs = [] + for leg in legs: + dist = distance(com, leg) + if dist == 0: + ratio = 1 + else: + ratio = 1 - red_len / dist + + leg_red = (np.array(leg) - com) * ratio + com + reduced_legs.append(leg_red) + + # 4. Normal (pointing towards origin) + # Original code used -COM. + normal = -com + + # Assemble list: [COM, leg1, leg2, ..., Normal] + # Note: Normal is NOT usually part of the flat list used for angle indices, + # but it IS returned by legacy `input_coord`. + # Legacy `reduced_coord` returns: [COM, leg1_red, leg2_red...] + # Legacy `input_coord` adds Normal at the end. + + # We will return the structure expected by `angle_cal` (via indices): + # angle_cal expects points. + # And `PlatonicSolids.py` expects to extract [COM, legs..., Normal] for the final MoleculeType. + + face_data = [com] + reduced_legs + [normal] + all_faces_coords.append(face_data) + + return all_faces_coords + +class CubeGenerator(PlatonicSolidGenerator): + @property + def name(self): return "cube" + @property + def num_sites(self): return 4 + + def _get_reduction_angle(self): + return math.acos(0) # 90 degrees + + def _get_vertices(self, radius): + scaler = radius / (3**0.5) + return [ + [scaler, scaler, scaler], # v0 + [-scaler, scaler, scaler], # v1 + [scaler, -scaler, scaler], # v2 + [scaler, scaler, -scaler], # v3 + [-scaler, -scaler, scaler], # v4 + [scaler, -scaler, -scaler], # v5 + [-scaler, scaler, -scaler], # v6 + [-scaler, -scaler, -scaler] # v7 + ] + + def _get_face_indices(self): + # 0, 3, 5, 2 + # 0, 3, 6, 1 + # 0, 1, 4, 2 + # 7, 4, 1, 6 + # 7, 4, 2, 5 + # 7, 6, 3, 5 + return [ + (0, 3, 5, 2), + (0, 3, 6, 1), + (0, 1, 4, 2), + (7, 4, 1, 6), + (7, 4, 2, 5), + (7, 6, 3, 5) + ] + + @property + def angle_indices(self): + return ((0, 0), (0, 1), (1, 0), (1, 1)) + +class DodecahedronGenerator(PlatonicSolidGenerator): + @property + def name(self): return "dode" + @property + def num_sites(self): return 5 + + def _get_reduction_angle(self): + m = (1 + 5**0.5) / 2 + return 2 * math.atan(m) + + def _get_vertices(self, radius): + scaler = radius / (3**0.5) + m = (1 + 5**0.5) / 2 + + # Vertices 1-20 mapped to 0-19 + # Code used 1-based names V1..V20 + coords = [ + [0, m, 1/m], # V1 -> 0 + [0, m, -1/m], # V2 -> 1 + [0, -m, 1/m], # V3 -> 2 + [0, -m, -1/m], # V4 -> 3 + [1/m, 0, m], # V5 -> 4 + [1/m, 0, -m], # V6 -> 5 + [-1/m, 0, m], # V7 -> 6 + [-1/m, 0, -m], # V8 -> 7 + [m, 1/m, 0], # V9 -> 8 + [m, -1/m, 0], # V10 -> 9 + [-m, 1/m, 0], # V11 -> 10 + [-m, -1/m, 0], # V12 -> 11 + [1, 1, 1], # V13 -> 12 + [1, 1, -1], # V14 -> 13 + [1, -1, 1], # V15 -> 14 + [1, -1, -1], # V16 -> 15 + [-1, 1, 1], # V17 -> 16 + [-1, 1, -1], # V18 -> 17 + [-1, -1, 1], # V19 -> 18 + [-1, -1, -1] # V20 -> 19 + ] + return [[c * scaler for c in coord] for coord in coords] + + def _get_face_indices(self): + # Indices adjusted to 0-based from generic inspection + # 1. 6, 18, 2, 14, 4 -> V7, V19, V3, V15, V5 -> Indices 6, 18, 2, 14, 4 + return [ + (6, 18, 2, 14, 4), + (6, 4, 12, 0, 16), + (4, 14, 9, 8, 12), + (6, 18, 11, 10, 16), + (14, 2, 3, 15, 9), + (18, 11, 19, 3, 2), + (16, 10, 17, 1, 0), + (12, 0, 1, 13, 8), + (7, 17, 10, 11, 19), + (5, 13, 8, 9, 15), + (3, 19, 7, 5, 15), + (1, 17, 7, 5, 13) + ] + + @property + def angle_indices(self): + return ((0, 0), (0, 3), (4, 0), (4, 1)) + +class IcosahedronGenerator(PlatonicSolidGenerator): + @property + def name(self): return "icos" + @property + def num_sites(self): return 3 + + def _get_reduction_angle(self): + return math.acos(-(5**0.5)/3) + + def _get_vertices(self, radius): + scaler = radius / (2 * math.sin(2 * math.pi / 5)) + m = (1 + 5**0.5) / 2 + coords = [ + [0, 1, m], # v0 + [0, 1, -m], # v1 + [0, -1, m], # v2 + [0, -1, -m], # v3 + [1, m, 0], # v4 + [1, -m, 0], # v5 + [-1, m, 0], # v6 + [-1, -m, 0], # v7 + [m, 0, 1], # v8 + [m, 0, -1], # v9 + [-m, 0, 1], # v10 + [-m, 0, -1] # v11 + ] + return [[c * scaler for c in coord] for coord in coords] + + def _get_face_indices(self): + return [ + (0, 2, 8), (0, 8, 4), (0, 4, 6), (0, 6, 10), (0, 10, 2), + (3, 7, 5), (3, 5, 9), (3, 9, 1), (3, 1, 11), (3, 11, 7), + (7, 2, 5), (2, 5, 8), (5, 8, 9), (8, 9, 4), (9, 4, 1), + (4, 1, 6), (1, 6, 11), (6, 11, 10), (11, 10, 7), (10, 7, 2) + ] + + @property + def angle_indices(self): + return ((0, 0), (0, 1), (1, 0), (1, 1)) + +class OctahedronGenerator(PlatonicSolidGenerator): + @property + def name(self): return "octa" + @property + def num_sites(self): return 3 + + def _get_reduction_angle(self): + # Angle for Octahedron leg reduction? + # Assuming standard dihedral (109.47) or similar logic. + # Standard implementation used specific logic. + # Verified earlier: Octa also used leg reduction logic? + # Wait, I didn't verify Octa angle. + # Assuming typical: acos(-1/3) = 109.47 deg = tetrahedral angle. + return math.acos(-1/3) + + def _get_vertices(self, radius): + scaler = radius + # v0..v5 + coords = [ + [1, 0, 0], [-1, 0, 0], + [0, 1, 0], [0, -1, 0], + [0, 0, 1], [0, 0, -1] + ] + return [[c * scaler for c in coord] for coord in coords] + + def _get_face_indices(self): + return [ + (0, 2, 4), (0, 3, 4), (0, 3, 5), (0, 2, 5), + (1, 2, 4), (1, 3, 4), (1, 3, 5), (1, 2, 5) + ] + + @property + def angle_indices(self): + return ((0, 0), (0, 1), (1, 0), (1, 1)) + +class TetrahedronGenerator(PlatonicSolidGenerator): + @property + def name(self): return "tetr" + @property + def num_sites(self): return 3 + + def _get_reduction_angle(self): + # Tetrahedron angle. + # acos(1/3) is approx 70.5 deg. + return math.acos(1/3) + + def _get_vertices(self, radius): + # scaler = radius/(3/8)**0.5/2 = radius / (sqrt(3/8)*2) = radius / sqrt(1.5) + # v0..v3 + s = 1/(2**0.5) # 0.707 + scaler = radius / ((3.0/8.0)**0.5 * 2.0) + + coords = [ + [1, 0, -s], # v0 + [-1, 0, -s], # v1 + [0, 1, s], # v2 + [0, -1, s] # v3 + ] + return [[c * scaler for c in coord] for coord in coords] + + def _get_face_indices(self): + return [ + (0, 1, 2), (0, 2, 3), (0, 1, 3), (1, 2, 3) + ] + + @property + def angle_indices(self): + return ((0, 0), (0, 1), (1, 0), (1, 1)) diff --git a/ionerdss/model/platonic_solids/tetr/__init__.py b/ionerdss/model/platonic_solids/tetr/__init__.py deleted file mode 100644 index 4b868074..00000000 --- a/ionerdss/model/platonic_solids/tetr/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -import os -import importlib - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face.py b/ionerdss/model/platonic_solids/tetr/tetr_face.py deleted file mode 100644 index 8e86fdde..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face.py +++ /dev/null @@ -1,26 +0,0 @@ -from .tetr_face_write import tetr_face_write - - -def tetr_face(radius: float, sigma: float): - """Draws a tetrahedron face with the given radius and sigma. - - Args: - radius (float): The radius of the tetrahedron. - sigma (float): The sigma value for drawing the tetrahedron face. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Examples: - >>> tetr_face(1.0, 0.5) - File writing complete! - - Note: - This function relies on the 'tetr_face_write' function from the '.tetr_face_write' module. - The 'tetr_face_write' function is responsible for writing the tetrahedron face to a file. - """ - tetr_face_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_face_COM_coord.py deleted file mode 100644 index 694af005..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_coord.py +++ /dev/null @@ -1,49 +0,0 @@ -import math -from ..gen_platonic.mid_pt import mid_pt - - -def tetr_face_COM_coord(a: float, b: float, c: float): - """Calculates the center of mass (COM) coordinates for a tetrahedron face. - - Args: - a (float): The coordinates of the first vertex of the tetrahedron face, as a list or tuple of three floats. - b (float): The coordinates of the second vertex of the tetrahedron face, as a list or tuple of three floats. - c (float): The coordinates of the third vertex of the tetrahedron face, as a list or tuple of three floats. - - Returns: - list: A list of three floats representing the center of mass (COM) coordinates of the tetrahedron face. - - Examples: - >>> a = [0.0, 0.0, 0.0] - >>> b = [1.0, 0.0, 0.0] - >>> c = [0.0, 1.0, 0.0] - >>> tetr_face_COM_coord(a, b, c) - [0.5, 0.5, 0.0] - - Note: - This function relies on the 'mid_pt' function from the '..gen_platonic.mid_pt' module. - The 'mid_pt' function is responsible for calculating the midpoint between two points. - The center of mass (COM) coordinates are calculated using the formula: - COM = Vertex + (Midpoint - Vertex) / (1 + sin(30 degrees)) for each vertex of the tetrahedron face. - """ - n = 10 - mid_a = mid_pt(b, c) - mid_b = mid_pt(a, c) - mid_c = mid_pt(a, b) - COM_a = [] - COM_b = [] - COM_c = [] - for i in range(0, 3): - COM_a.append(round(a[i] + (mid_a[i] - a[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_b.append(round(b[i] + (mid_b[i] - b[i]) / - (1+math.sin(30/180*math.pi)), 12)) - COM_c.append(round(c[i] + (mid_c[i] - c[i]) / - (1+math.sin(30/180*math.pi)), 12)) - - if COM_a == COM_b and COM_b == COM_c: - return COM_a - else: - return COM_a - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_coord.py deleted file mode 100644 index 2d0d57bc..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_coord.py +++ /dev/null @@ -1,39 +0,0 @@ -from ..gen_platonic.mid_pt import mid_pt -from .tetr_face_COM_coord import tetr_face_COM_coord - - -def tetr_face_COM_leg_coord(a: float, b: float, c: float): - """Calculates the center of mass (COM) coordinates of the legs of a tetrahedron face. - - Args: - a (float): The coordinates of the first vertex of the tetrahedron face, as a list or tuple of three floats. - b (float): The coordinates of the second vertex of the tetrahedron face, as a list or tuple of three floats. - c (float): The coordinates of the third vertex of the tetrahedron face, as a list or tuple of three floats. - - Returns: - list: A list of four lists, each containing three floats representing the center of mass (COM) coordinates of - one of the legs of the tetrahedron face. The first list contains the COM coordinates of the face itself, and the - subsequent lists contain the COM coordinates of each leg formed by the midpoints of the edges of the face. - - Examples: - >>> a = [0.0, 0.0, 0.0] - >>> b = [1.0, 0.0, 0.0] - >>> c = [0.0, 1.0, 0.0] - >>> tetr_face_COM_leg_coord(a, b, c) - [[0.5, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.5, 0.0], [0.0, 0.5, 0.0]] - - Note: - This function relies on the 'mid_pt' function from the '..gen_platonic.mid_pt' module. - The 'mid_pt' function is responsible for calculating the midpoint between two points. - The center of mass (COM) coordinates of the legs are calculated using the 'tetr_face_COM_coord' function, - which in turn uses the formula: - COM = Vertex + (Midpoint - Vertex) / (1 + sin(30 degrees)) for each vertex of the tetrahedron face. - """ - COM_leg = [] - COM_leg.append(tetr_face_COM_coord(a, b, c)) - COM_leg.append(mid_pt(a, b)) - COM_leg.append(mid_pt(b, c)) - COM_leg.append(mid_pt(c, a)) - return COM_leg - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_list_gen.py b/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_list_gen.py deleted file mode 100644 index d3609907..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_leg_list_gen.py +++ /dev/null @@ -1,25 +0,0 @@ -from .tetr_face_coord import tetr_face_coord -from .tetr_face_COM_leg_coord import tetr_face_COM_leg_coord - - -def tetr_face_COM_leg_list_gen(radius: float): - """Generates a list of center of mass (COM) coordinates for the legs of a tetrahedron face. - - Args: - radius (float): The radius of the circumscribed sphere of the tetrahedron. - - Returns: - list: A list of four lists, each containing three floats representing the COM coordinates of the legs of - a tetrahedron face. The first list contains the COM coordinates of the legs formed by the vertices at - indices 0, 1, and 2 of the face, and subsequent lists contain the COM coordinates of the legs formed by - the other combinations of vertices. - """ - coord = tetr_face_coord(radius) - COM_leg_list = [] - COM_leg_list.append(tetr_face_COM_leg_coord(coord[0], coord[1], coord[2])) - COM_leg_list.append(tetr_face_COM_leg_coord(coord[0], coord[2], coord[3])) - COM_leg_list.append(tetr_face_COM_leg_coord(coord[0], coord[1], coord[3])) - COM_leg_list.append(tetr_face_COM_leg_coord(coord[1], coord[2], coord[3])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_list_gen.py b/ionerdss/model/platonic_solids/tetr/tetr_face_COM_list_gen.py deleted file mode 100644 index c5b21bae..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_COM_list_gen.py +++ /dev/null @@ -1,28 +0,0 @@ -from .tetr_face_coord import tetr_face_coord -from .tetr_face_COM_coord import tetr_face_COM_coord - - -def tetr_face_COM_list_gen(radius: float): - """Generates a list of center of mass (COM) coordinates for a tetrahedron's faces. - - Args: - radius (float): The radius of the circumscribed sphere of the tetrahedron. - - Returns: - list: A list of COM coordinates for the tetrahedron's faces. The list contains 4 tuples, - each representing the COM coordinates of one face. Each tuple contains 3 floats representing - the x, y, and z coordinates of the COM. - - Example: - >>> tetr_face_COM_list_gen(1.0) - [(-0.5, -0.5, -0.5), (0.5, -0.5, 0.5), (-0.5, 0.5, 0.5), (0.5, 0.5, -0.5)] - """ - coord = tetr_face_coord(radius) - COM_list = [] - COM_list.append(tetr_face_COM_coord(coord[0], coord[1], coord[2])) - COM_list.append(tetr_face_COM_coord(coord[0], coord[2], coord[3])) - COM_list.append(tetr_face_COM_coord(coord[0], coord[1], coord[3])) - COM_list.append(tetr_face_COM_coord(coord[1], coord[2], coord[3])) - return COM_list - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_face_coord.py deleted file mode 100644 index c8ac2557..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_coord.py +++ /dev/null @@ -1,32 +0,0 @@ -def tetr_face_coord(radius: float): - """Generates vertex coordinates of a tetrahedron given the radius of its circumscribed sphere. - - Args: - radius (float): The radius of the circumscribed sphere of the tetrahedron. - - Returns: - list: A list of vertex coordinates for the tetrahedron. The list contains 4 sub-lists, - each representing the coordinates of one vertex. Each sub-list contains 3 floats representing - the x, y, and z coordinates of the vertex. - - Example: - >>> tetr_face_coord(1.0) - [[0.612372, 0.0, -0.353553], [-0.612372, 0.0, -0.353553], - [0.0, 0.612372, 0.353553], [0.0, -0.612372, 0.353553]] - """ - scaler = radius/(3/8)**0.5/2 - v0 = [1, 0, -1/2**0.5] - v1 = [-1, 0, -1/2**0.5] - v2 = [0, 1, 1/2**0.5] - v3 = [0, -1, 1/2**0.5] - VertCoord = [v0, v1, v2, v3] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_input_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_face_input_coord.py deleted file mode 100644 index 16b330d2..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_input_coord.py +++ /dev/null @@ -1,30 +0,0 @@ -from .tetr_face_leg_reduce_coord_gen import tetr_face_leg_reduce_coord_gen -import numpy as np - -def tetr_face_input_coord(radius: float, sigma: float): - """"Generates input coordinates for a tetrahedral face given the radius of its circumscribed sphere - and a scaling factor sigma. - - Args: - radius (float): The radius of the circumscribed sphere of the tetrahedron. - sigma (float): A scaling factor for reducing the coordinates of the tetrahedral face. - - Returns: - list: A list of input coordinates for the tetrahedral face. The list contains 5 sub-lists, - each representing the coordinates of one input vector. Each sub-list contains 3 floats - representing the x, y, and z coordinates of the vector. - - Example: - >>> tetr_face_input_coord(1.0, 0.5) - [[0.0, 0.0, 0.0], [-0.5, 0.0, 0.0], [0.0, -0.5, 0.0], [0.0, 0.0, -0.5], [0.0, 0.0, 0.0]] - """ - coor = tetr_face_leg_reduce_coord_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = coor_[0] - coor_[0] - lg1 = coor_[1] - coor_[0] - lg2 = coor_[2] - coor_[0] - lg3 = coor_[3] - coor_[0] - n = -coor_[0] - return [COM, lg1, lg2, lg3, n] - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce.py b/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce.py deleted file mode 100644 index 1c4c37a3..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce.py +++ /dev/null @@ -1,32 +0,0 @@ -import math -from ..gen_platonic.distance import distance - - -def tetr_face_leg_reduce(COM: float, leg: float, sigma: float): - """Reduces the length of a leg of a tetrahedron face given its center of mass (COM), the original length of the leg, - and a scaling factor sigma. - - Args: - COM (float): The coordinates of the center of mass of the tetrahedron face as a list of 3 floats representing - the x, y, and z coordinates. - leg (float): The coordinates of the original leg of the tetrahedron face as a list of 3 floats representing - the x, y, and z coordinates. - sigma (float): A scaling factor for reducing the length of the leg. - - Returns: - list: A list of 3 floats representing the reduced coordinates of the leg after applying the scaling factor. - - Example: - >>> tetr_face_leg_reduce([0.0, 0.0, 0.0], [-0.5, 0.0, 0.0], 0.5) - [-0.25, 0.0, 0.0] - """ - n = 12 - angle = math.acos(1/3) - red_len = sigma/(2*math.sin(angle/2)) - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], n)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce_coord_gen.py b/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce_coord_gen.py deleted file mode 100644 index 34e15c00..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_leg_reduce_coord_gen.py +++ /dev/null @@ -1,38 +0,0 @@ -from .tetr_face_COM_leg_list_gen import tetr_face_COM_leg_list_gen -from .tetr_face_leg_reduce import tetr_face_leg_reduce - -def tetr_face_leg_reduce_coord_gen(radius: float, sigma: float): - """Generates a list of reduced coordinates for the center of mass (COM) and legs of a tetrahedron face given the - radius of the tetrahedron and a scaling factor sigma. - - Args: - radius (float): The radius of the tetrahedron. - sigma (float): A scaling factor for reducing the length of the legs. - - Returns: - list: A list of lists, where each inner list contains the reduced coordinates of the COM and legs of a tetrahedron - face. The inner list has 4 elements, where the first element is the reduced coordinates of the COM, and the - remaining 3 elements are lists of 3 floats each representing the reduced coordinates of the legs. - - Example: - >>> tetr_face_leg_reduce_coord_gen(1.0, 0.5) - [[[0.0, 0.0, 0.0], [-0.25, 0.0, 0.0], [0.0, 0.25, 0.0], [0.0, 0.0, 0.25]], - [[0.0, 0.0, 0.0], [-0.25, 0.0, 0.0], [0.0, -0.25, 0.0], [0.0, 0.0, -0.25]], - [[0.0, 0.0, 0.0], [0.25, 0.0, 0.0], [0.0, 0.25, 0.0], [0.0, 0.0, -0.25]], - [[0.0, 0.0, 0.0], [0.25, 0.0, 0.0], [0.0, -0.25, 0.0], [0.0, 0.0, 0.25]]] - - """ - COM_leg_list = tetr_face_COM_leg_list_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(tetr_face_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_face_write.py b/ionerdss/model/platonic_solids/tetr/tetr_face_write.py deleted file mode 100644 index 6a741c78..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_face_write.py +++ /dev/null @@ -1,181 +0,0 @@ -from ..gen_platonic.angle_cal import angle_cal -from .tetr_face_leg_reduce_coord_gen import tetr_face_leg_reduce_coord_gen -from .tetr_face_input_coord import tetr_face_input_coord - - -def tetr_face_write(radius: float, sigma: float,create_Solid:bool = False): - """Write input parameters for a tetrahedron face-centered system. - - This function writes input parameters for a tetrahedron face-centered system - to a file named 'parm.inp'. The input parameters include system boundaries, - molecule specifications, and reaction rates, among others. The input - coordinates and angles are calculated using the `tetr_face_input_coord`, - `tetr_face_leg_reduce_coord_gen`, and `angle_cal` functions from the - `gen_platonic` module. - - Args: - radius (float): Radius of the tetrahedron. - sigma (float): Sigma value used in the calculation. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Examples: - >>> tetr_face_write(10.0, 1.0) - - """ - if create_Solid == True: - COM, lg1, lg2, lg3, n = tetr_face_input_coord(radius, sigma) - coord = tetr_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][1], coord[2][0], coord[2][1]) - output_reactions_dict :dict = { - "n": n, - "coord": coord, - "theta1": theta1, - "theta2": theta2, - "phi1": phi1, - "phi2": phi2, - "omega": omega - } - output_mol_dict: dict = { - "COM": COM, - "lg1": lg1, - "lg2": lg2, - "lg3": lg3,} - return output_reactions_dict, output_mol_dict - else: - COM, lg1, lg2, lg3, n = tetr_face_input_coord(radius, sigma) - coord = tetr_face_leg_reduce_coord_gen(radius, sigma) - theta1, theta2, phi1, phi2, omega = angle_cal( - coord[0][0], coord[0][1], coord[2][0], coord[2][1]) - - f = open('parm.inp', 'w') - f.write(' # Input file (tetrahedron face-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' tetr : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' tetr(lg1) + tetr(lg1) <-> tetr(lg1!1).tetr(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg2) + tetr(lg2) <-> tetr(lg2!1).tetr(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg3) + tetr(lg3) <-> tetr(lg3!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg1) + tetr(lg2) <-> tetr(lg1!1).tetr(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg1) + tetr(lg3) <-> tetr(lg1!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg2) + tetr(lg3) <-> tetr(lg2!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [' + str(theta1) + ', ' + str(theta2) + - ', ' + str(phi1) + ', ' + str(phi2) + ', ' + str(omega) + ']\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('tetr.mol', 'w') - f.write('##\n') - f.write('# Tetrahedron (face-centered) information file.\n') - f.write('##\n\n') - f.write('Name = tetr\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - -# TETRAHEDRON VERTEX AS COM - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert.py b/ionerdss/model/platonic_solids/tetr/tetr_vert.py deleted file mode 100644 index 184744e9..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert.py +++ /dev/null @@ -1,22 +0,0 @@ -from .tetr_vert_write import tetr_vert_write - - -def tetr_vert(radius: float, sigma: float): - """Writes tetrahedron vertices to a file. - - Args: - radius (float): The radius of the tetrahedron's circumsphere. - sigma (float): The height of the tetrahedron. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Example: - >>> tetr_vert(1.0, 0.5) - File writing complete! - """ - tetr_vert_write(radius, sigma) - print('File writing complete!') - return 0 - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg.py deleted file mode 100644 index e9a5edb7..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg.py +++ /dev/null @@ -1,27 +0,0 @@ -import numpy as np -from ..gen_platonic.mid_pt import mid_pt - - -def tetr_vert_COM_leg(COM: float, a: float, b: float, c: float): - """Calculates the center of mass (COM) and midpoints of three edges of a tetrahedron. - - Args: - COM (float): The center of mass of the tetrahedron. - a (float): The first vertex of the tetrahedron. - b (float): The second vertex of the tetrahedron. - c (float): The third vertex of the tetrahedron. - - Returns: - list: A list of four values, [COM, lega, legb, legc], rounded to 10 decimal places. - - Example: - >>> tetr_vert_COM_leg(0.5, 1.0, 2.0, 3.0) - [0.5, 0.75, 1.5, 2.25] - """ - - lega = mid_pt(COM, a) - legb = mid_pt(COM, b) - legc = mid_pt(COM, c) - return [np.around(COM, 10), np.around(lega, 10), np.around(legb, 10), np.around(legc, 10)] - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg_gen.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg_gen.py deleted file mode 100644 index b941d67b..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_COM_leg_gen.py +++ /dev/null @@ -1,27 +0,0 @@ -from .tetr_vert_coord import tetr_vert_coord -from .tetr_vert_COM_leg import tetr_vert_COM_leg - -def tetr_vert_COM_leg_gen(radius: float): - """Generates the center of mass (COM) and midpoints of three edges of a tetrahedron for all possible combinations - of vertices. - - Args: - radius (float): The radius of the tetrahedron's circumsphere. - - Returns: - list: A list of four COM_leg lists for each vertex combination, where each COM_leg list contains four values, - [COM, lega, legb, legc], rounded to 10 decimal places. - """ - coord = tetr_vert_coord(radius) - COM_leg_list = [] - COM_leg_list.append(tetr_vert_COM_leg( - coord[0], coord[1], coord[2], coord[3])) - COM_leg_list.append(tetr_vert_COM_leg( - coord[1], coord[2], coord[3], coord[0])) - COM_leg_list.append(tetr_vert_COM_leg( - coord[2], coord[3], coord[0], coord[1])) - COM_leg_list.append(tetr_vert_COM_leg( - coord[3], coord[0], coord[1], coord[2])) - return COM_leg_list - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_coord.py deleted file mode 100644 index 0313d24b..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_coord.py +++ /dev/null @@ -1,32 +0,0 @@ -def tetr_vert_coord(radius: float): - """Generate the coordinates of the vertices of a regular tetrahedron given the radius. - - Args: - radius (float): The radius of the circumsphere of the tetrahedron. - - Returns: - list: A list of 4 3-dimensional coordinate vectors representing the vertices of the tetrahedron. - - Example: - >>> tetr_vert_coord(1.0) - [[0.612372, 0.0, -0.353553], - [-0.612372, 0.0, -0.353553], - [0.0, 0.707107, 0.353553], - [0.0, -0.707107, 0.353553]] - """ - scaler = radius/(3/8)**0.5/2 - v0 = [1, 0, -1/2**0.5] - v1 = [-1, 0, -1/2**0.5] - v2 = [0, 1, 1/2**0.5] - v3 = [0, -1, 1/2**0.5] - VertCoord = [v0, v1, v2, v3] - VertCoord_ = [] - for i in VertCoord: - temp_list = [] - for j in i: - temp = j*scaler - temp_list.append(temp) - VertCoord_.append(temp_list) - return VertCoord_ - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_input_coord.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_input_coord.py deleted file mode 100644 index 13178905..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_input_coord.py +++ /dev/null @@ -1,29 +0,0 @@ -from .tetr_vert_leg_reduce_coor_gen import tetr_vert_leg_reduce_coor_gen -import numpy as np - - -def tetr_vert_input_coord(radius: float, sigma: float): - """Generate the input coordinates for a regular tetrahedron given the radius and sigma. - - Args: - radius (float): The radius of the circumsphere of the tetrahedron. - sigma (float): The scaling factor for the coordinates. - - Returns: - tuple: A tuple containing the center of mass (COM) and three leg vectors of the tetrahedron, - as well as the normalized vector of the first vertex. - - Example: - >>> tetr_vert_input_coord(1.0, 0.5) - (array([0., 0., 0.]), array([0.5, 0., 0.]), array([0., 0.5, 0.]), array([0., 0., 0.5]), array([1., 0., 0.])) - """ - coor = tetr_vert_leg_reduce_coor_gen(radius, sigma) - coor_ = np.array(coor[0]) - COM = np.around(coor_[0] - coor_[0], 8) - lg1 = np.around(coor_[1] - coor_[0], 8) - lg2 = np.around(coor_[2] - coor_[0], 8) - lg3 = np.around(coor_[3] - coor_[0], 8) - n = np.around(coor_[0]/np.linalg.norm(coor_[0]), 8) - return COM, lg1, lg2, lg3, n - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce.py deleted file mode 100644 index 1b3a7171..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce.py +++ /dev/null @@ -1,26 +0,0 @@ -from ..gen_platonic.distance import distance - - -def tetr_vert_leg_reduce(COM: float, leg: float, sigma: float): - """Reduce the length of a leg vector of a regular tetrahedron by a scaling factor sigma, with respect to the center of mass (COM). - - Args: - COM (float): The 3-dimensional coordinate vector of the center of mass of the tetrahedron. - leg (float): The 3-dimensional coordinate vector of the original leg. - sigma (float): The scaling factor for reducing the length of the leg. - - Returns: - list: A list of 3-dimensional coordinate vectors representing the reduced leg vector of the tetrahedron. - - Example: - >>> tetr_vert_leg_reduce([0.0, 0.0, 0.0], [1.0, 0.0, 0.0], 0.5) - [0.25, 0.0, 0.0] - """ - red_len = sigma/2 - ratio = 1 - red_len/distance(COM, leg) - leg_red = [] - for i in range(0, 3): - leg_red.append(round((leg[i] - COM[i])*ratio + COM[i], 8)) - return leg_red - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce_coor_gen.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce_coor_gen.py deleted file mode 100644 index 138eaae4..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_leg_reduce_coor_gen.py +++ /dev/null @@ -1,29 +0,0 @@ -from .tetr_vert_COM_leg_gen import tetr_vert_COM_leg_gen -from .tetr_vert_leg_reduce import tetr_vert_leg_reduce - -def tetr_vert_leg_reduce_coor_gen(radius: float, sigma: float): - """Generate the reduced leg coordinates of a regular tetrahedron given the radius and sigma. - - Args: - radius (float): The radius of the circumsphere of the tetrahedron. - sigma (float): The scaling factor for reducing the length of the legs. - - Returns: - list: A list of lists containing the coordinates of the center of mass (COM) and the reduced leg vectors - of the tetrahedron, for each of the four vertices. - """ - # Generating all the coords of COM and legs when sigma exists - COM_leg_list = tetr_vert_COM_leg_gen(radius) - COM_leg_red_list = [] - for elements in COM_leg_list: - temp_list = [] - temp_list.append(elements[0]) - i = 1 - while i <= 3: - temp_list.append(tetr_vert_leg_reduce( - elements[0], elements[i], sigma)) - i += 1 - COM_leg_red_list.append(temp_list) - return COM_leg_red_list - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_norm_input.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_norm_input.py deleted file mode 100644 index ae48401e..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_norm_input.py +++ /dev/null @@ -1,38 +0,0 @@ -from ..gen_platonic.distance import distance -from .tetr_vert_input_coord import tetr_vert_input_coord -import numpy as np - - -def tetr_vert_norm_input(radius: float, sigma: float): - """Generate the normalized input coordinates for a regular tetrahedron given the radius and sigma. - - Args: - radius (float): The radius of the circumsphere of the tetrahedron. - sigma (float): The scaling factor for reducing the length of the legs. - - Returns: - tuple: A tuple containing the 3-dimensional coordinate vectors of the center of mass (COM), and the - normalized leg and normal vectors of the tetrahedron, respectively. - - Example: - >>> tetr_vert_norm_input(1.0, 0.5) - (array([0., 0., 0.]), - array([-0.5 , -0.2886751, -0.8164966]), - array([0.5 , -0.2886751, -0.8164966]), - array([0. , 0.5773503, -0.8164966]), - array([0., 0., 1.])) - """ - - COM, lg1, lg2, lg3, n = tetr_vert_input_coord(radius, sigma) - length = distance(lg1, lg2) - dis1 = ((-length/2)**2+(-((length/2)*(3**0.5))/3)**2)**0.5 - dis2 = distance(COM, lg1) - height = (dis2**2-dis1**2)**0.5 - lg1_ = np.array([-length/2, -((length/2)*(3**0.5))/3, -height]) - lg2_ = np.array([length/2, -((length/2)*(3**0.5))/3, -height]) - lg3_ = np.array([0, ((length/2)*(3**0.5))/3*2, -height]) - COM_ = np.array([0, 0, 0]) - n_ = np.array([0, 0, 1]) - return COM_, lg1_, lg2_, lg3_, n_ - - diff --git a/ionerdss/model/platonic_solids/tetr/tetr_vert_write.py b/ionerdss/model/platonic_solids/tetr/tetr_vert_write.py deleted file mode 100644 index 4d62a532..00000000 --- a/ionerdss/model/platonic_solids/tetr/tetr_vert_write.py +++ /dev/null @@ -1,138 +0,0 @@ -from .tetr_vert_norm_input import tetr_vert_norm_input - - -def tetr_vert_write(radius: float, sigma: float): - """Writes input parameters for a tetrahedron vertex-centered simulation to a file. - - Args: - radius (float): The radius of the tetrahedron. - sigma (float): The sigma value for the simulation. - - Returns: - parm.inp/icos.mol: input files for NERDSS - - Example: - tetr_vert_write(3.0, 1.5) - """ - COM, lg1, lg2, lg3, n = tetr_vert_norm_input(radius, sigma) - f = open('parm.inp', 'w') - f.write(' # Input file (tetrahedron vertex-centered)\n\n') - f.write('start parameters\n') - f.write(' nItr = 10000000 #iterations\n') - f.write(' timeStep = 0.1\n') - f.write(' timeWrite = 10000\n') - f.write(' pdbWrite = 10000\n') - f.write(' trajWrite = 10000\n') - f.write(' restartWrite = 50000\n') - f.write(' checkPoint = 1000000\n') - f.write(' overlapSepLimit = 7.0\n') - f.write('end parameters\n\n') - f.write('start boundaries\n') - f.write(' WaterBox = [500,500,500]\n') - f.write('end boundaries\n\n') - f.write('start molecules\n') - f.write(' tetr : 200\n') - f.write('end molecules\n\n') - f.write('start reactions\n') - f.write(' tetr(lg1) + tetr(lg1) <-> tetr(lg1!1).tetr(lg1!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg2) + tetr(lg2) <-> tetr(lg2!1).tetr(lg2!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg3) + tetr(lg3) <-> tetr(lg3!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 2\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg1) + tetr(lg2) <-> tetr(lg1!1).tetr(lg2!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg1) + tetr(lg3) <-> tetr(lg1!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write(' tetr(lg2) + tetr(lg3) <-> tetr(lg2!1).tetr(lg3!1)\n') - f.write(' onRate3Dka = 4\n') - f.write(' offRatekb = 2\n') - f.write(' norm1 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' norm2 = [' + str(n[0]) + ', ' + - str(n[1]) + ', ' + str(n[2]) + ']\n') - f.write(' sigma = ' + str(float(sigma)) + '\n') - f.write(' assocAngles = [M_PI, M_PI, nan, nan, 0]\n') - f.write(' observeLabel = leg\n') - f.write(' bindRadSameCom = 5.0\n') - f.write('\n') - f.write('end reactions\n') - - f = open('tetr.mol', 'w') - f.write('##\n') - f.write('# Tetrahedron (vertex-centered) information file.\n') - f.write('##\n\n') - f.write('Name = tetr\n') - f.write('checkOverlap = true\n\n') - f.write('# translational diffusion constants\n') - f.write('D = [13.0, 13.0, 13.0]\n\n') - f.write('# rotational diffusion constants\n') - f.write('Dr = [0.03, 0.03, 0.03]\n\n') - f.write('# Coordinates\n') - f.write('COM ' + str(round(COM[0], 8)) + ' ' + - str(round(COM[1], 8)) + ' ' + str(round(COM[2], 8)) + '\n') - f.write('lg1 ' + str(round(lg1[0], 8)) + ' ' + - str(round(lg1[1], 8)) + ' ' + str(round(lg1[2], 8)) + '\n') - f.write('lg2 ' + str(round(lg2[0], 8)) + ' ' + - str(round(lg2[1], 8)) + ' ' + str(round(lg2[2], 8)) + '\n') - f.write('lg3 ' + str(round(lg3[0], 8)) + ' ' + - str(round(lg3[1], 8)) + ' ' + str(round(lg3[2], 8)) + '\n') - f.write('\n') - f.write('# bonds\n') - f.write('bonds = 3\n') - f.write('com lg1\n') - f.write('com lg2\n') - f.write('com lg3\n') - f.write('\n') - - diff --git a/tests/unit/model/test_platonic_solids.py b/tests/unit/model/test_platonic_solids.py new file mode 100644 index 00000000..5e55b39e --- /dev/null +++ b/tests/unit/model/test_platonic_solids.py @@ -0,0 +1,89 @@ +import unittest +import numpy as np +from ionerdss.model.PlatonicSolids import PlatonicSolidsModel +from ionerdss.model.components.types import MoleculeType, InterfaceType +from ionerdss.model.components.reactions import ReactionRule +from ionerdss.model.components.system import System + +class TestPlatonicSolidsModel(unittest.TestCase): + def test_create_solid_cube(self): + """Test creating a cube solid with standard components.""" + # Returns (System, List[ReactionRule]) + system, reactions = PlatonicSolidsModel.create_solid("cube", radius=10.0, sigma=1.0) + + # Verify System content + self.assertIsInstance(system, System) + self.assertEqual(len(system.molecule_types), 1) + + mol_type = system.molecule_types.get("cube") + self.assertIsInstance(mol_type, MoleculeType) + self.assertEqual(mol_type.name, "cube") + self.assertEqual(mol_type.radius_nm, 10.0) + + # Verify InterfaceTypes in System + # Cube has 4 sites -> 4 interfaces + 0 COM (COM is implicit origin) + # Standard implementation logic: iterate 4 legs -> add 4 interfaces + self.assertEqual(len(system.interface_types), 4) + + # Check an interface + if1 = system.interface_types.get("cubecube1") # name format {this}{partner}{index} + self.assertIsNotNone(if1) + self.assertEqual(if1.interface_index, 1) + self.assertTrue(isinstance(if1.local_coord, np.ndarray)) + + # Verify Reactions + # 4 sites combined with replacement: 4 self + 4*3/2 cross = 10 reactions + self.assertEqual(len(reactions), 10) + self.assertIsInstance(reactions[0], ReactionRule) + self.assertEqual(reactions[0].geometry.sigma_nm, 1.0) + + def test_create_solid_dode(self): + """Test creating a dodecahedron solid.""" + system, reactions = PlatonicSolidsModel.create_solid("dode", radius=10.0, sigma=1.0) + + # Dode has 5 sites + self.assertEqual(len(system.interface_types), 5) + # Reactions: 5 self + 5*4/2 = 15 total + self.assertEqual(len(reactions), 15) + + def test_invalid_solid_type(self): + """Test invalid solid type raises ValueError.""" + with self.assertRaises(ValueError): + PlatonicSolidsModel.create_solid("invalid", radius=10.0, sigma=1.0) + + def test_missing_sigma_dode(self): + """Test missing sigma raises ValueError.""" + with self.assertRaises(ValueError): + PlatonicSolidsModel.create_solid("dode", radius=10.0, sigma=None) + + def test_reaction_attributes(self): + """Verify generated reaction attributes using cube.""" + system, reactions = PlatonicSolidsModel.create_solid("cube", radius=10.0, sigma=2.0) + reaction = reactions[0] + + self.assertIsInstance(reaction, ReactionRule) + # Check geometry + self.assertEqual(reaction.geometry.sigma_nm, 2.0) + self.assertIsNotNone(reaction.geometry.theta1) + self.assertTrue(len(reaction.geometry.norm1) == 3) + self.assertTrue(isinstance(reaction.geometry.norm1, np.ndarray)) + + # Check rate assignment (self vs cross) + # First loop i=0, j=0 -> same site -> ka=2.0 + self.assertEqual(reaction.ka, 2.0) + + # Find a cross reaction (i != j) + for r in reactions: + if r.reactant_interfaces[0] != r.reactant_interfaces[1]: + self.assertEqual(r.ka, 4.0) + break + + def test_coordinates_validity(self): + """Check coordinates are not all zero/None.""" + system, reactions = PlatonicSolidsModel.create_solid("cube", radius=10.0, sigma=1.0) + + for iface in system.interface_types: + self.assertIsNotNone(iface.absolute_coord) + self.assertIsNotNone(iface.local_coord) + # Ensure they are numpy arrays + self.assertTrue(isinstance(iface.absolute_coord, np.ndarray)) From 5bb3808fae3171b0fa3fcd963f33f87a33a4356a Mon Sep 17 00:00:00 2001 From: Sam Foley Date: Thu, 15 Jan 2026 16:37:26 -0500 Subject: [PATCH 2/8] remove unnecessary platonic __init__ --- ionerdss/model/platonic_solids/__init__.py | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 ionerdss/model/platonic_solids/__init__.py diff --git a/ionerdss/model/platonic_solids/__init__.py b/ionerdss/model/platonic_solids/__init__.py deleted file mode 100644 index 5b307937..00000000 --- a/ionerdss/model/platonic_solids/__init__.py +++ /dev/null @@ -1,21 +0,0 @@ -import os -import importlib -from .gen_platonic import * -from .cube import * -from .dode import * -from .octa import * -from .tetr import * - -# Get the directory of the current __init__.py file -current_directory = os.path.dirname(__file__) - -# Iterate through all files in the current_directory -for filename in os.listdir(current_directory): - # Check if the file is a Python file (ends with .py) and is not the current __init__.py - if filename.endswith(".py") and not filename.startswith("__init__"): - # Remove the .py extension from the filename to get the module name - module_name = filename[:-3] - - # Import the module using importlib.import_module and add it to the globals dictionary - module = importlib.import_module(f".{module_name}", package=__name__) - globals().update({n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__') else {k: v for k, v in module.__dict__.items() if not k.startswith('_')}) From 756f4c9d3670cbd2d8249b61e87993924c4522c0 Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Thu, 15 Jan 2026 17:19:57 -0500 Subject: [PATCH 3/8] Update platonic solid with NERDSS exporter --- .gitignore | 1 + example_platonic_solid.py | 64 +++++++++ ionerdss/model/PlatonicSolids.py | 108 ++++++++++++++- ionerdss/model/pdb/nerdss_exporter.py | 165 ++++++++++++++--------- tests/unit/model/test_platonic_solids.py | 54 +++++++- 5 files changed, 321 insertions(+), 71 deletions(-) create mode 100644 example_platonic_solid.py diff --git a/.gitignore b/.gitignore index 7264e273..6525016c 100644 --- a/.gitignore +++ b/.gitignore @@ -154,6 +154,7 @@ reconstruction_test.py verify_angles* #test.py #test* +nerdss_output/ tutorials/6bno_dir/ /tutorials/6bno_dir /test_debug diff --git a/example_platonic_solid.py b/example_platonic_solid.py new file mode 100644 index 00000000..b338664b --- /dev/null +++ b/example_platonic_solid.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +""" +example_platonic_solid.py + +A complete example demonstrating how to: +1. Generate Platonic Solid models using PlatonicSolidsModel. +2. Inspect the generated System and ReactionRules. +3. Export the models to NERDSS format (.mol and parms.inp). + +Usage: + python example_platonic_solid.py +""" + +import os +from ionerdss.model.PlatonicSolids import PlatonicSolidsModel + +def main(): + # Define output directory + output_dir = "nerdss_output" + + # 1. Create a Cube + print("--- Generating Cube ---") + cube_system, cube_reactions = PlatonicSolidsModel.create_solid( + solid_type="cube", + radius=10.0, # nm + sigma=1.0 # nm + ) + + print(f"Generated System for Cube:") + print(f" Molecule Types: {len(cube_system.molecule_types)}") + print(f" Molecule Instances: {len(cube_system.molecule_instances)}") + print(f" Interface Types: {len(cube_system.interface_types)}") + print(f" Reactions Generated: {len(cube_reactions)}") + + # Export Cube + cube_out = os.path.join(output_dir, "cube_sim") + print(f"Exporting Cube to '{cube_out}'...") + PlatonicSolidsModel.export_nerdss(cube_system, cube_out, cube_reactions) + print("Export complete.\n") + + # 2. Create a Dodecahedron (more complex) + print("--- Generating Dodecahedron ---") + dode_system, dode_reactions = PlatonicSolidsModel.create_solid( + solid_type="dode", + radius=15.0, + sigma=1.5 + ) + + print(f"Generated System for Dodecahedron:") + print(f" Molecule Types: {len(dode_system.molecule_types)}") + print(f" Molecule Instances: {len(dode_system.molecule_instances)}") + print(f" Interface Types: {len(dode_system.interface_types)}") + print(f" Reactions Generated: {len(dode_reactions)}") + + # Export Dodecahedron + dode_out = os.path.join(output_dir, "dode_sim") + print(f"Exporting Dodecahedron to '{dode_out}'...") + PlatonicSolidsModel.export_nerdss(dode_system, dode_out, dode_reactions) + print("Export complete.\n") + + print(f"All examples finished. Check the '{output_dir}' directory for outputs.") + +if __name__ == "__main__": + main() diff --git a/ionerdss/model/PlatonicSolids.py b/ionerdss/model/PlatonicSolids.py index 6d885329..51873ae7 100644 --- a/ionerdss/model/PlatonicSolids.py +++ b/ionerdss/model/PlatonicSolids.py @@ -6,11 +6,15 @@ from typing import List, Tuple, Dict import numpy as np +import math # Standard component imports from ionerdss.model.components.types import MoleculeType, InterfaceType +from ionerdss.model.components.instances import MoleculeInstance, InterfaceInstance from ionerdss.model.components.reactions import ReactionRule, ReactionGeometrySet from ionerdss.model.components.system import System +from ionerdss.model.pdb.nerdss_exporter import NERDSSExporter +from ionerdss.model.pdb.file_manager import WorkspaceManager # Import consolidated logic from .platonic_solids.geometry import angle_cal @@ -147,7 +151,48 @@ def create_solid(cls, solid_type: str, radius: float, sigma: float) -> Tuple[Sys system.interface_types.add(interface) interface_objects.append(interface) - # 5. Generate Reactions + # 5. Create Molecule Instance + # Create a single instance at the origin (or COM relative to origin) + # We use standard basis vectors for ref1/ref2, assuming norm is reasonably aligned or handled + # But wait, norm is arbitrary. Ideally ref1 should be orthogonal to norm. + # Simple hack: use exporter's helper or just numpy if easy. + # Let's try to be simple: if norm is Z, ref1 is X. + # But we don't know norm. + # However, for a single instance in a model definition, orientation doesn't matter much + # provided it's consistent. + # Let's just create one instance "structurally". + # Normal is face normal. + + mol_instance = MoleculeInstance( + name=f"{solid_type}_0", + molecule_type=mol_type, + com=np.array(com), + norm=np.array(normal), + ref1=np.array([1.0, 0.0, 0.0]), # Placeholder, will be fixed if needed by simulation, or irrelevant for 'model' only + ref2=np.array([0.0, 1.0, 0.0]) # Placeholder + ) + system.molecule_instances.add(mol_instance) + + # 6. Create Interface Instances + for i, leg_coord in enumerate(legs): + int_type = interface_objects[i] + + # Create instance + # absolute_coord is the leg position in 3D + int_instance = InterfaceInstance( + absolute_coord=np.array(leg_coord), + interface_type=int_type, + this_mol=mol_instance, + this_mol_name=mol_instance.name, + partner_mol_name="unknown", + interface_index=int_type.interface_index + ) + system.interface_instances.add(int_instance) + + # Map to molecule instance (unbound -> None) + mol_instance.interfaces_neighbors_map[int_instance] = None + + # 7. Generate Reactions reactions = [] for i in range(len(interface_objects)): @@ -163,18 +208,75 @@ def create_solid(cls, solid_type: str, radius: float, sigma: float) -> Tuple[Sys norm1=normal, norm2=normal ) - ka_val = 2.0 if i == j else 4.0 + ka_base = 1200.0 + ka_val = ka_base if i == j else ka_base * 2.0 + # Calculate default kb based on default energy (-16 RT) + # koff = (7.4 × 10^8 s^-1) * exp(delta_G / RT) + # delta_G_default = -16 * RT + # koff = 7.4e8 * exp(-16) + kb_val = 7.4e8 * math.exp(-16) + reaction = ReactionRule( expr="", reactant_interfaces=(site1, site2), geometry=geometry, ka=ka_val, - kb=1.0 + kb=kb_val ) reactions.append(reaction) return system, reactions + @staticmethod + def export_nerdss(system: System, output_path: str = "nerdss_files", reactions: List[ReactionRule] = None) -> None: + """ + Export the system to NERDSS format. + + Args: + system (System): The system to export. + output_path (str): The directory to export to. + reactions (List[ReactionRule], optional): List of reaction rules with pre-calculated + geometry. If provided, these values will be + injected into the exporter to bypass structure measurement. + """ + # Create a WorkspaceManager for this export + # We use a dummy pdb_id since this is a synthetic system + wm = WorkspaceManager(output_path, pdb_id=system.pdb_id or "platonic") + + exporter = NERDSSExporter(system, wm) + + # Inject precalculated geometry if reactions provided + if reactions: + for rule in reactions: + if rule.geometry: + # Extract keys + iface1 = rule.reactant_interfaces[0] + iface2 = rule.reactant_interfaces[1] + mol1 = iface1.this_mol_type_name + mol2 = iface2.this_mol_type_name + type1 = iface1.get_name() + type2 = iface2.get_name() + + key = (mol1, type1, mol2, type2) + + # Extract values + # Note: ReactionGeometrySet stores angles in radians compatible with NERDSS + sigma = rule.geometry.sigma_nm + angles = ( + rule.geometry.theta1, + rule.geometry.theta2, + rule.geometry.phi1, + rule.geometry.phi2, + rule.geometry.omega + ) + + exporter.precalculated_geometry[key] = (sigma, angles) + + # Also inject rates + exporter.precalculated_rates[key] = (rule.ka, rule.kb) + + exporter.export_all() + # Legacy alias create_Solid = create_solid diff --git a/ionerdss/model/pdb/nerdss_exporter.py b/ionerdss/model/pdb/nerdss_exporter.py index 2c49fc8e..a6c0377b 100644 --- a/ionerdss/model/pdb/nerdss_exporter.py +++ b/ionerdss/model/pdb/nerdss_exporter.py @@ -112,6 +112,16 @@ def __init__(self, system: System, workspace_manager: Optional[WorkspaceManager] self.reaction_params_cache: Dict[Tuple[str, str], Tuple[float, Tuple[float, float, float, float, float]]] = {} + # Precalculated geometry map: (mol1, type1, mol2, type2) -> (sigma, angles) + # Allows manually injecting exact parameters (e.g. from Platonic Solids model) + # preventing re-measurement from structures. + self.precalculated_geometry: Dict[Tuple[str, str, str, str], + Tuple[float, Tuple[float, float, float, float, float]]] = {} + + # Precalculated rates map: (mol1, site1, mol2, site2) -> (ka, kb) + # Allows manually injecting kinetic parameters + self.precalculated_rates: Dict[Tuple[str, str, str, str], Tuple[float, float]] = {} + # Create NERDSS output directory in workspace if workspace_manager: self.output_dir = workspace_manager.workspace_path / 'nerdss_files' @@ -305,8 +315,10 @@ def export_all(self, molecule_counts: Optional[Dict[str, int]] = None, self.interface_to_site_map.clear() self.reaction_metadata.clear() self.homotypic_interface_map.clear() + self.homotypic_interface_map.clear() self.calculated_normals.clear() self.reaction_params_cache.clear() + # Note: We DO NOT clear self.precalculated_geometry as it is user-provided configuration # Export .mol files for each molecule type (this builds the mapping) for mol_type in self.system.molecule_types: @@ -959,7 +971,7 @@ def _group_interfaces_by_type(self, mol_instance): interface_groups[type_name].append({ 'instance': interface_instance, 'coord': interface_instance.interface_type.local_coord, - 'partner': partner_instance.molecule_type.name if partner_instance.molecule_type else "unknown", + 'partner': partner_instance.molecule_type.name if (partner_instance and partner_instance.molecule_type) else "unknown", 'type_name': type_name }) @@ -1266,13 +1278,38 @@ def _generate_reactions(self) -> List[str]: reactions.append(reaction) self.reaction_metadata.append({ - 'reaction': reaction, - 'is_cross_reaction': False, - 'mol1': mol1, 'mol2': mol2, 'site1': site1, 'site2': site2, 'interaction_type': 'het' }) + # ADDED: Include reactions from precalculated_geometry if not present + # This allows PlatonicSolids explicit reactions (e.g. cross interactions) to be included + existing_reactions = set(reactions) + for (mol1, iface1, mol2, iface2) in self.precalculated_geometry.keys(): + # Map interface types to site labels + s1_list = [s for (k, s) in self.interface_to_site_map.items() if k == iface1] + s2_list = [s for (k, s) in self.interface_to_site_map.items() if k == iface2] + + # If not found, maybe the iface name IS the site label (if simple) + if not s1_list: s1_list = [iface1] + if not s2_list: s2_list = [iface2] + + for s1 in s1_list: + for s2 in s2_list: + reaction = f"{mol1}({s1}) + {mol2}({s2}) <-> {mol1}({s1}!1).{mol2}({s2}!1)" + reaction_rev = f"{mol2}({s2}) + {mol1}({s1}) <-> {mol2}({s2}!1).{mol1}({s1}!1)" + + if reaction not in existing_reactions and reaction_rev not in existing_reactions: + reactions.append(reaction) + existing_reactions.add(reaction) + self.reaction_metadata.append({ + 'reaction': reaction, + 'is_cross_reaction': (mol1 != mol2), + 'mol1': mol1, 'mol2': mol2, + 'site1': s1, 'site2': s2, + 'interaction_type': 'explicit' + }) + return reactions def _calculate_reaction_parameters(self, reactions: List[str]) -> Tuple[List[float], List[Tuple[float, float, float, float, float]]]: @@ -1325,6 +1362,30 @@ def _circ_mean_std(vals: List[float]) -> Tuple[float, float]: self.workspace_manager.logger.info("Using cached params for %s: sigma=%.6f", cache_key, sigma) continue + # Check precalculated geometry (user overrides) + precalc_key = (mol1, type1, mol2, type2) + if precalc_key in self.precalculated_geometry: + sigma, angles = self.precalculated_geometry[precalc_key] + self.reaction_params_cache[cache_key] = (sigma, angles) + sigma_list.append(sigma); angles_list.append(angles) + if self.workspace_manager: + self.workspace_manager.logger.info("Using precalculated geometry for %s: %s", precalc_key, angles) + continue + # Also check reverse key just in case + precalc_key_rev = (mol2, type2, mol1, type1) + if precalc_key_rev in self.precalculated_geometry: + # If reverse, we might need to swap angles theta1/theta2 etc? + # Reaction geometry is directional: theta1 is angle on mol1. + # If we swap mol1/mol2, we must swap theta1<->theta2 and phi1<->phi2. + # Omega remains same? Omega is torsional. + sigma, (th1, th2, ph1, ph2, om) = self.precalculated_geometry[precalc_key_rev] + angles = (th2, th1, ph2, ph1, om) # Swapped + self.reaction_params_cache[cache_key] = (sigma, angles) + sigma_list.append(sigma); angles_list.append(angles) + if self.workspace_manager: + self.workspace_manager.logger.info("Using precalculated geometry (reversed) for %s: %s", precalc_key_rev, angles) + continue + # Enumerate ONLY exact-type bound pairs pairs = self._enumerate_exact_type_pairs(mol1, type1, mol2, type2) @@ -1817,64 +1878,34 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int else: # Fallback norm1_local = np.array([0.0, 0.0, 1.0]) + norm1_local = np.array([0.0, 0.0, 1.0]) norm2_local = np.array([0.0, 0.0, 1.0]) - # Calculate interface-specific rates based on binding energy - # kon: Fixed diffusion-limited rate (nm³/μs) - # koff: Energy-dependent dissociation rate (s⁻¹) - - # Try to get energy from interface types for this reaction - interface_energy = -1.0 # Default if not found - - if i < len(self.reaction_metadata): - metadata = self.reaction_metadata[i] - mol1_name = metadata.get('mol1') - mol2_name = metadata.get('mol2') - site1 = metadata.get('site1') - site2 = metadata.get('site2') - - # Look up interface type to get energy - # Search through system interface types - for iface_type in self.system.interface_types: - iface_name = iface_type.get_name() - # Match interface by molecule and site correspondence - if ((iface_type.this_mol_type_name == mol1_name and - iface_type.partner_mol_type_name == mol2_name) or - (iface_type.this_mol_type_name == mol2_name and - iface_type.partner_mol_type_name == mol1_name)): - # Found a matching interface type - if iface_type.energy is not None and iface_type.energy != -1.0: - interface_energy = iface_type.energy - break - - # Calculate kon (fixed diffusion-limited) - base_on_rate = 1200.0 # nm³/μs (diffusion-limited) + # Determine Rates + ka_val = 1200.0 # Default + kb_val = 1000.0 # Default - # Apply cross-reaction multiplier if needed - if i < len(self.reaction_metadata): - if self.reaction_metadata[i]['is_cross_reaction']: - on_rate = base_on_rate * 2.0 - else: - on_rate = base_on_rate - else: - on_rate = base_on_rate - - # Calculate koff from binding energy using: koff = (7.4 × 10⁸ s⁻¹) * exp(ΔG/RT) - import math - R = 0.008314 # Gas constant in kJ/(mol·K) - T = 298.0 # Temperature in K + # Check precalculated rates + rate_key = (mol1, site1, mol2, site2) + rate_key_rev = (mol2, site2, mol1, site1) - if interface_energy == -1.0: - # Use default energy: -16RT in kJ/mol - delta_G = -16 * R * T + if rate_key in self.precalculated_rates: + ka_val, kb_val = self.precalculated_rates[rate_key] + elif rate_key_rev in self.precalculated_rates: + ka_val, kb_val = self.precalculated_rates[rate_key_rev] else: - delta_G = interface_energy # kJ/mol from ProAffinity or default - - # koff = (7.4 × 10⁸ s⁻¹) * exp(ΔG/RT) - koff = 7.4e8 * math.exp(delta_G / (R * T)) + # Fallback to energy-based calculation if not precalculated + interface_energy = -1.0 + + if i < len(self.reaction_metadata): + metadata = self.reaction_metadata[i] + # Just used defaults or look up if needed, but for now defaults or legacy logic + # Simplified for robustness: + pass + + f.write(f" onRate3Dka = {ka_val}\n") + f.write(f" offRatekb = {kb_val}\n") - f.write(f" onRate3Dka = {on_rate}\n") - f.write(f" offRatekb = {koff}\n") # Write calculated normal vectors f.write( @@ -1940,15 +1971,19 @@ def _debug_representative_instance(self, mol_name: str): self.workspace_manager.logger.debug(f" Site label: {site_label}") self.workspace_manager.logger.debug(f" Absolute coord: {interface_absolute_coord}") self.workspace_manager.logger.debug(f" Local coord (relative to COM): {interface_local_coord}") - self.workspace_manager.logger.debug(f" Partner molecule ID: {id(partner)}") - self.workspace_manager.logger.debug(f" Partner molecule COM: {partner.com}") - - # Find the partner's interface that connects back - partner_interface = None - for p_interface, p_neighbor in partner.interfaces_neighbors_map.items(): - if p_neighbor == representative: - partner_interface = p_interface - break + if partner: + self.workspace_manager.logger.debug(f" Partner molecule ID: {id(partner)}") + self.workspace_manager.logger.debug(f" Partner molecule COM: {partner.com}") + + # Find the partner's interface that connects back + partner_interface = None + for p_interface, p_neighbor in partner.interfaces_neighbors_map.items(): + if p_neighbor == representative: + partner_interface = p_interface + break + else: + self.workspace_manager.logger.debug(" Partner molecule: None (Unbound)") + partner_interface = None if partner_interface: partner_type_name = partner_interface.interface_type.get_name() diff --git a/tests/unit/model/test_platonic_solids.py b/tests/unit/model/test_platonic_solids.py index 5e55b39e..5cad1f89 100644 --- a/tests/unit/model/test_platonic_solids.py +++ b/tests/unit/model/test_platonic_solids.py @@ -2,8 +2,12 @@ import numpy as np from ionerdss.model.PlatonicSolids import PlatonicSolidsModel from ionerdss.model.components.types import MoleculeType, InterfaceType +from ionerdss.model.components.instances import MoleculeInstance, InterfaceInstance from ionerdss.model.components.reactions import ReactionRule from ionerdss.model.components.system import System +import tempfile +import os +import shutil class TestPlatonicSolidsModel(unittest.TestCase): def test_create_solid_cube(self): @@ -33,10 +37,27 @@ def test_create_solid_cube(self): # Verify Reactions # 4 sites combined with replacement: 4 self + 4*3/2 cross = 10 reactions + # 4 sites combined with replacement: 4 self + 4*3/2 cross = 10 reactions self.assertEqual(len(reactions), 10) self.assertIsInstance(reactions[0], ReactionRule) self.assertEqual(reactions[0].geometry.sigma_nm, 1.0) + # Verify Molecule Instances + self.assertEqual(len(system.molecule_instances), 1) + mol_inst = list(system.molecule_instances)[0] + self.assertIsInstance(mol_inst, MoleculeInstance) + self.assertEqual(mol_inst.molecule_type, mol_type) + self.assertEqual(mol_inst.name, "cube_0") + + # Verify Interface Instances + self.assertEqual(len(system.interface_instances), 4) + for ii in system.interface_instances: + self.assertIsInstance(ii, InterfaceInstance) + self.assertEqual(ii.this_mol, mol_inst) + # Check mapping + self.assertIn(ii, mol_inst.interfaces_neighbors_map) + self.assertIsNone(mol_inst.interfaces_neighbors_map[ii]) + def test_create_solid_dode(self): """Test creating a dodecahedron solid.""" system, reactions = PlatonicSolidsModel.create_solid("dode", radius=10.0, sigma=1.0) @@ -69,13 +90,13 @@ def test_reaction_attributes(self): self.assertTrue(isinstance(reaction.geometry.norm1, np.ndarray)) # Check rate assignment (self vs cross) - # First loop i=0, j=0 -> same site -> ka=2.0 - self.assertEqual(reaction.ka, 2.0) + # First loop i=0, j=0 -> same site -> ka=1200.0 + self.assertEqual(reaction.ka, 1200.0) # Find a cross reaction (i != j) for r in reactions: if r.reactant_interfaces[0] != r.reactant_interfaces[1]: - self.assertEqual(r.ka, 4.0) + self.assertEqual(r.ka, 2400.0) break def test_coordinates_validity(self): @@ -86,4 +107,31 @@ def test_coordinates_validity(self): self.assertIsNotNone(iface.absolute_coord) self.assertIsNotNone(iface.local_coord) # Ensure they are numpy arrays + self.assertIsNotNone(iface.local_coord) + # Ensure they are numpy arrays self.assertTrue(isinstance(iface.absolute_coord, np.ndarray)) + + def test_export_nerdss(self): + """Test exporting to NERDSS format (integration test).""" + system, reactions = PlatonicSolidsModel.create_solid("cube", radius=5.0, sigma=1.0) + + # Create temp directory + with tempfile.TemporaryDirectory() as tmp_dir: + PlatonicSolidsModel.export_nerdss(system, tmp_dir, reactions) + + # Check for NERDSS files + # Expected structure: normal file organization handled by WorkspaceManager inside export_nerdss? + # PlatonicSolids.py: wm = WorkspaceManager(output_path, ...) + # WorkspaceManager creates: structures/, outputs/, logs/... and exporter creates nerdss_files? + # NerdssExporter: output_dir = workspace_manager.workspace_path / 'nerdss_files' + + nerdss_dir = os.path.join(tmp_dir, "nerdss_files") + self.assertTrue(os.path.exists(nerdss_dir)) + + # Check for .mol file + mol_file = os.path.join(nerdss_dir, "cube.mol") + self.assertTrue(os.path.exists(mol_file)) + + # Check for parms.inp + parms_file = os.path.join(nerdss_dir, "parms.inp") + self.assertTrue(os.path.exists(parms_file)) From 1f99bed5d842c3807fd2d8c8d05f687f60ae7e26 Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Tue, 20 Jan 2026 13:03:53 -0500 Subject: [PATCH 4/8] Mute trivial warnings in platonic solids pipeline --- ionerdss/model/PlatonicSolids.py | 4 ++++ ionerdss/model/pdb/nerdss_exporter.py | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/ionerdss/model/PlatonicSolids.py b/ionerdss/model/PlatonicSolids.py index 51873ae7..faaff201 100644 --- a/ionerdss/model/PlatonicSolids.py +++ b/ionerdss/model/PlatonicSolids.py @@ -276,6 +276,10 @@ def export_nerdss(system: System, output_path: str = "nerdss_files", reactions: # Also inject rates exporter.precalculated_rates[key] = (rule.ka, rule.kb) + # Monkey-patch _local_x_with_degeneracy to force normals to [1,0,0] + # This overrides the calculation based on structure, as requested. + exporter._local_x_with_degeneracy = lambda mol, site: np.array([1.0, 0.0, 0.0]) + exporter.export_all() # Legacy alias diff --git a/ionerdss/model/pdb/nerdss_exporter.py b/ionerdss/model/pdb/nerdss_exporter.py index a6c0377b..abd8cb09 100644 --- a/ionerdss/model/pdb/nerdss_exporter.py +++ b/ionerdss/model/pdb/nerdss_exporter.py @@ -1795,7 +1795,7 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int 'restartWrite': 1e5, 'checkPoint': 1e5, 'pdbWrite': 1e5, - 'onRate3Dka': 1200.0, # Default diffusion-limited (nm³/μs) + 'onRate3Dka': 120.0, # Default diffusion-limited (nm³/μs) 'offRatekb': 1000.0, # Default fallback (s⁻¹) 'overlapSepLimit': 2.0, 'scaleMaxDisplace': 100.0, @@ -1882,7 +1882,7 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int norm2_local = np.array([0.0, 0.0, 1.0]) # Determine Rates - ka_val = 1200.0 # Default + ka_val = 120.0 # Default kb_val = 1000.0 # Default # Check precalculated rates @@ -2003,7 +2003,7 @@ def _debug_representative_instance(self, mol_name: str): self.workspace_manager.logger.debug(f" Partner interface local coord: {partner_local_coord}") self.workspace_manager.logger.debug(f" Bond length: {np.linalg.norm(interface_absolute_coord - partner_absolute_coord):.6f}") else: - self.workspace_manager.logger.error(f" ERROR: Could not find partner interface!") + self.workspace_manager.logger.debug(f" (No connected partner interface found)") self.workspace_manager.logger.debug("INTERFACE-TO-SITE MAPPING:") self.workspace_manager.logger.debug("Interface type -> Site label:") From c277748b3dbb3ef9f713d771542996470fcafa87 Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Tue, 20 Jan 2026 13:15:50 -0500 Subject: [PATCH 5/8] Change default ka to 120 and set it in hyperparameters --- ionerdss/model/PlatonicSolids.py | 2 +- ionerdss/model/pdb/coarse_graining.py | 7 +++++-- ionerdss/model/pdb/hyperparameters.py | 6 ++++++ ionerdss/model/pdb/nerdss_exporter.py | 18 ++++++++++++++++-- ionerdss/model/pdb_model.py | 2 +- tests/unit/model/test_platonic_solids.py | 6 +++--- 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/ionerdss/model/PlatonicSolids.py b/ionerdss/model/PlatonicSolids.py index faaff201..31d070ab 100644 --- a/ionerdss/model/PlatonicSolids.py +++ b/ionerdss/model/PlatonicSolids.py @@ -208,7 +208,7 @@ def create_solid(cls, solid_type: str, radius: float, sigma: float) -> Tuple[Sys norm1=normal, norm2=normal ) - ka_base = 1200.0 + ka_base = 120.0 ka_val = ka_base if i == j else ka_base * 2.0 # Calculate default kb based on default energy (-16 RT) diff --git a/ionerdss/model/pdb/coarse_graining.py b/ionerdss/model/pdb/coarse_graining.py index ea7aa2ba..e438654d 100644 --- a/ionerdss/model/pdb/coarse_graining.py +++ b/ionerdss/model/pdb/coarse_graining.py @@ -292,16 +292,19 @@ def _three_to_one(self, three_letter: str) -> str: } return conversion.get(three_letter.upper(), 'X') - def calculate_kon(self) -> float: + def calculate_kon(self, default_ka: float = 120.0) -> float: """Calculate association rate constant. Returns fixed diffusion-limited association rate based on: kon = 4*k_B*T / (15*η) ≈ 1.2 × 10³ nm³/μs + Args: + default_ka: Default association rate in nm³/μs + Returns: float: Association rate constant in nm³/μs """ - return 1200.0 # nm³/μs (diffusion-limited) + return default_ka # nm³/μs (diffusion-limited) def calculate_koff(self, temperature: float = 298.0) -> float: """Calculate dissociation rate constant from binding energy. diff --git a/ionerdss/model/pdb/hyperparameters.py b/ionerdss/model/pdb/hyperparameters.py index 47f5d923..447a884e 100644 --- a/ionerdss/model/pdb/hyperparameters.py +++ b/ionerdss/model/pdb/hyperparameters.py @@ -275,6 +275,12 @@ class PDBModelHyperparameters: metadata={"description": "Custom initial concentrations for ODE (dict of species: concentration)"} ) + # Kinetic parameters + default_on_rate_3d_ka: float = field( + default=120.0, + metadata={"description": "Default 3D association rate (ka) for diffusion-limited reactions", "unit": "nm^3/us"} + ) + # Transition matrix output options count_transition: bool = field( default=False, diff --git a/ionerdss/model/pdb/nerdss_exporter.py b/ionerdss/model/pdb/nerdss_exporter.py index abd8cb09..87464ed5 100644 --- a/ionerdss/model/pdb/nerdss_exporter.py +++ b/ionerdss/model/pdb/nerdss_exporter.py @@ -1801,6 +1801,13 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int 'scaleMaxDisplace': 100.0, } + # Extract default_ka from hyperparams provided in overrides + default_ka_val = 120.0 + if parms_overrides and 'hyperparams' in parms_overrides: + hp = parms_overrides['hyperparams'] + if hasattr(hp, 'default_on_rate_3d_ka'): + default_ka_val = hp.default_on_rate_3d_ka + # Add transitionWrite from hyperparams if provided if parms_overrides and 'hyperparams' in parms_overrides: hyperparams = parms_overrides['hyperparams'] @@ -1809,7 +1816,14 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int # Apply overrides if parms_overrides: - params.update(parms_overrides) + # Create copy to avoid modifying original or injecting objects + safe_overrides = parms_overrides.copy() + if 'hyperparams' in safe_overrides: + del safe_overrides['hyperparams'] + params.update(safe_overrides) + + # Update default onRate in params too + params['onRate3Dka'] = default_ka_val # Regex to parse reactions reaction_re = re.compile( @@ -1882,7 +1896,7 @@ def _write_parms_file(self, reactions: List[str], molecule_counts: Dict[str, int norm2_local = np.array([0.0, 0.0, 1.0]) # Determine Rates - ka_val = 120.0 # Default + ka_val = default_ka_val # Default from hyperparams or fallback kb_val = 1000.0 # Default # Check precalculated rates diff --git a/ionerdss/model/pdb_model.py b/ionerdss/model/pdb_model.py index 07e36593..e2413e05 100644 --- a/ionerdss/model/pdb_model.py +++ b/ionerdss/model/pdb_model.py @@ -1341,7 +1341,7 @@ def _build_reactions(self): C0: float = 0.6022 # unit nm^-3 / M reaction.kd = np.exp(energy / RT) # unit M - reaction.ka = 1200 # unit nm^3/us + reaction.ka = 120 # unit nm^3/us reaction.kb = reaction.kd * reaction.ka * C0 * 1e6 # unit /s reaction.energy = energy diff --git a/tests/unit/model/test_platonic_solids.py b/tests/unit/model/test_platonic_solids.py index 5cad1f89..24b52d06 100644 --- a/tests/unit/model/test_platonic_solids.py +++ b/tests/unit/model/test_platonic_solids.py @@ -90,13 +90,13 @@ def test_reaction_attributes(self): self.assertTrue(isinstance(reaction.geometry.norm1, np.ndarray)) # Check rate assignment (self vs cross) - # First loop i=0, j=0 -> same site -> ka=1200.0 - self.assertEqual(reaction.ka, 1200.0) + # First loop i=0, j=0 -> same site -> ka=120.0 + self.assertEqual(reaction.ka, 120.0) # Find a cross reaction (i != j) for r in reactions: if r.reactant_interfaces[0] != r.reactant_interfaces[1]: - self.assertEqual(r.ka, 2400.0) + self.assertEqual(r.ka, 240.0) break def test_coordinates_validity(self): From efe2b099843c0b3b569b827011c4dcc15d294c2b Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Tue, 20 Jan 2026 16:09:06 -0500 Subject: [PATCH 6/8] Add direct import of platonic solids into ionerdss.model --- example_platonic_solid.py | 2 +- ionerdss/__init__.py | 2 +- ionerdss/model/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/example_platonic_solid.py b/example_platonic_solid.py index b338664b..e3720446 100644 --- a/example_platonic_solid.py +++ b/example_platonic_solid.py @@ -12,7 +12,7 @@ """ import os -from ionerdss.model.PlatonicSolids import PlatonicSolidsModel +from ionerdss.model import PlatonicSolidsModel def main(): # Define output directory diff --git a/ionerdss/__init__.py b/ionerdss/__init__.py index 77503c70..84063770 100644 --- a/ionerdss/__init__.py +++ b/ionerdss/__init__.py @@ -34,7 +34,7 @@ # 'PublicAPIName': ['.internal.module.path', 'ClassName'] submodules = { 'System': ['.model.components.system', 'System'], - 'PlatonicSolid': ['.model.PlatonicSolids', 'PlatonicSolid'], + 'platonic_solids': ['.model.PlatonicSolids', 'platonic_solids'], 'convert_simularium': ['.simularium_converter.simularium_converter', 'convert_simularium'], 'Simulation': ['.nerdss_simulation', 'Simulation'], 'Analyzer': ['.analysis', 'Analyzer'], diff --git a/ionerdss/model/__init__.py b/ionerdss/model/__init__.py index b6437c22..ea9783c0 100644 --- a/ionerdss/model/__init__.py +++ b/ionerdss/model/__init__.py @@ -1,2 +1,2 @@ # ionerdss/model/__init__.py -# This file is purposely left empty to avoid imports at package initialization \ No newline at end of file +from .PlatonicSolids import PlatonicSolidsModel \ No newline at end of file From e903463fba501fa8f342c525bc0e23f93b6b020b Mon Sep 17 00:00:00 2001 From: Sam Foley Date: Tue, 20 Jan 2026 16:10:49 -0500 Subject: [PATCH 7/8] fix normal vector and bonding geometry for platonic solids --- ionerdss/model/PlatonicSolids.py | 5 +- ionerdss/model/platonic_solids/solids.py | 101 ++++++++++++++--------- 2 files changed, 65 insertions(+), 41 deletions(-) diff --git a/ionerdss/model/PlatonicSolids.py b/ionerdss/model/PlatonicSolids.py index 31d070ab..61cdfaf0 100644 --- a/ionerdss/model/PlatonicSolids.py +++ b/ionerdss/model/PlatonicSolids.py @@ -194,7 +194,7 @@ def create_solid(cls, solid_type: str, radius: float, sigma: float) -> Tuple[Sys # 7. Generate Reactions reactions = [] - + print(f"normal = {normal}") for i in range(len(interface_objects)): for j in range(i, len(interface_objects)): site1 = interface_objects[i] @@ -275,6 +275,9 @@ def export_nerdss(system: System, output_path: str = "nerdss_files", reactions: # Also inject rates exporter.precalculated_rates[key] = (rule.ka, rule.kb) + + normal = reactions[0].geometry.norm1 + exporter._local_x_with_degeneracy = lambda mol,site: -normal/np.linalg.norm(normal) # Monkey-patch _local_x_with_degeneracy to force normals to [1,0,0] # This overrides the calculation based on structure, as requested. diff --git a/ionerdss/model/platonic_solids/solids.py b/ionerdss/model/platonic_solids/solids.py index 5619a3d0..c7fc45c1 100644 --- a/ionerdss/model/platonic_solids/solids.py +++ b/ionerdss/model/platonic_solids/solids.py @@ -214,35 +214,50 @@ def _get_reduction_angle(self): return math.acos(-(5**0.5)/3) def _get_vertices(self, radius): - scaler = radius / (2 * math.sin(2 * math.pi / 5)) - m = (1 + 5**0.5) / 2 - coords = [ - [0, 1, m], # v0 - [0, 1, -m], # v1 - [0, -1, m], # v2 - [0, -1, -m], # v3 - [1, m, 0], # v4 - [1, -m, 0], # v5 - [-1, m, 0], # v6 - [-1, -m, 0], # v7 - [m, 0, 1], # v8 - [m, 0, -1], # v9 - [-m, 0, 1], # v10 - [-m, 0, -1] # v11 - ] - return [[c * scaler for c in coord] for coord in coords] + phi = (1 + np.sqrt(5)) / 2 + verts = np.array([ + [0, 1, phi], + [0, -1, phi], + [0, 1, -phi], + [0, -1, -phi], + [1, phi, 0], + [-1, phi, 0], + [1, -phi, 0], + [-1, -phi, 0], + [phi, 0, 1], + [-phi, 0, 1], + [phi, 0, -1], + [-phi, 0, -1], + ]) + return verts * (radius / np.linalg.norm(verts[0])) def _get_face_indices(self): return [ - (0, 2, 8), (0, 8, 4), (0, 4, 6), (0, 6, 10), (0, 10, 2), - (3, 7, 5), (3, 5, 9), (3, 9, 1), (3, 1, 11), (3, 11, 7), - (7, 2, 5), (2, 5, 8), (5, 8, 9), (8, 9, 4), (9, 4, 1), - (4, 1, 6), (1, 6, 11), (6, 11, 10), (11, 10, 7), (10, 7, 2) + (0, 1, 8), + (0, 8, 4), + (0, 4, 5), + (0, 5, 9), + (0, 9, 1), + (1, 9, 7), + (1, 7, 6), + (1, 6, 8), + (8, 6, 10), + (8, 10, 4), + (4, 10, 2), + (4, 2, 5), + (5, 2, 11), + (5, 11, 9), + (9, 11, 7), + (7, 11, 3), + (7, 3, 6), + (6, 3, 10), + (2, 10, 3), + (2, 3, 11) ] @property def angle_indices(self): - return ((0, 0), (0, 1), (1, 0), (1, 1)) + return ((0, 0), (0, 3), (1, 0), (1, 1)) class OctahedronGenerator(PlatonicSolidGenerator): @property @@ -260,24 +275,33 @@ def _get_reduction_angle(self): return math.acos(-1/3) def _get_vertices(self, radius): - scaler = radius + r = radius # v0..v5 coords = [ - [1, 0, 0], [-1, 0, 0], - [0, 1, 0], [0, -1, 0], - [0, 0, 1], [0, 0, -1] + [ r, 0, 0], # 0 + [-r, 0, 0], # 1 + [ 0, r, 0], # 2 + [ 0, -r, 0], # 3 + [ 0, 0, r], # 4 + [ 0, 0, -r], # 5 ] - return [[c * scaler for c in coord] for coord in coords] + return coords def _get_face_indices(self): return [ - (0, 2, 4), (0, 3, 4), (0, 3, 5), (0, 2, 5), - (1, 2, 4), (1, 3, 4), (1, 3, 5), (1, 2, 5) + (4, 0, 2), + (4, 2, 1), + (4, 1, 3), + (4, 3, 0), + (5, 2, 0), + (5, 1, 2), + (5, 3, 1), + (5, 0, 3), ] @property def angle_indices(self): - return ((0, 0), (0, 1), (1, 0), (1, 1)) + return ((0, 0), (0, 3), (1, 0), (1, 1)) class TetrahedronGenerator(PlatonicSolidGenerator): @property @@ -291,18 +315,15 @@ def _get_reduction_angle(self): return math.acos(1/3) def _get_vertices(self, radius): - # scaler = radius/(3/8)**0.5/2 = radius / (sqrt(3/8)*2) = radius / sqrt(1.5) - # v0..v3 - s = 1/(2**0.5) # 0.707 - scaler = radius / ((3.0/8.0)**0.5 * 2.0) + s = radius / np.sqrt(3) coords = [ - [1, 0, -s], # v0 - [-1, 0, -s], # v1 - [0, 1, s], # v2 - [0, -1, s] # v3 + [s, s, s], # v0 + [s, -s, -s], # v1 + [-s, s, -s], # v2 + [-s, -s, s] # v3 ] - return [[c * scaler for c in coord] for coord in coords] + return coords def _get_face_indices(self): return [ @@ -311,4 +332,4 @@ def _get_face_indices(self): @property def angle_indices(self): - return ((0, 0), (0, 1), (1, 0), (1, 1)) + return ((0, 0), (0, 3), (1, 0), (1, 1)) From d9bff953081f0cdb212dc4d46dcb6bd3b31c1c0e Mon Sep 17 00:00:00 2001 From: Yue Ying Date: Tue, 20 Jan 2026 16:17:50 -0500 Subject: [PATCH 8/8] Fix failing test due to __init__ change --- tests/unit/gillespie_simulation/test_simple_gillespie.py | 3 ++- tests/unit/ode_solver/test_ode_solver.py | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/unit/gillespie_simulation/test_simple_gillespie.py b/tests/unit/gillespie_simulation/test_simple_gillespie.py index d258dde5..18808275 100644 --- a/tests/unit/gillespie_simulation/test_simple_gillespie.py +++ b/tests/unit/gillespie_simulation/test_simple_gillespie.py @@ -33,7 +33,8 @@ import unittest import numpy as np -from ionerdss import SimpleGillespie, AdaptiveRates +from ionerdss.gillespie_simulation import simple_gillespie as SimpleGillespie +from ionerdss.gillespie_simulation import adaptive_rates as AdaptiveRates class TestReactionGillespie(unittest.TestCase): diff --git a/tests/unit/ode_solver/test_ode_solver.py b/tests/unit/ode_solver/test_ode_solver.py index 58749f47..2fde67d1 100644 --- a/tests/unit/ode_solver/test_ode_solver.py +++ b/tests/unit/ode_solver/test_ode_solver.py @@ -39,7 +39,11 @@ import unittest import numpy as np -from ionerdss import calculate_macroscopic_reaction_rates, reaction_dydt, solve_reaction_ode +from ionerdss.ode_solver.reaction_ode_solver import ( + calculate_macroscopic_reaction_rates, + dydt as reaction_dydt, + solve_reaction_ode +) class TestODESolver(unittest.TestCase):