def test_other_units(self): rds = readdy.ReactionDiffusionSystem( box_size=[1., 1., 1.], unit_system={'length_unit': 'kilometer'}) rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system={'time_unit': 'hour'}) rds = readdy.ReactionDiffusionSystem( box_size=[1., 1., 1.], unit_system={'energy_unit': 'kcal/mol'}) rds = readdy.ReactionDiffusionSystem( box_size=[1., 1., 1.], unit_system={'temperature_unit': 'rankine'})
def test_system_with_wrong_unit_dimensions(self): with self.assertRaises(ValueError): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system={'energy_unit': 'rankine'}) with self.assertRaises(ValueError): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system={'length_unit': 'kiloseconds'}) with self.assertRaises(ValueError): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system={'time_unit': 'kilonanometer'}) with self.assertRaises(ValueError): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system={'temperature_unit': 'second'})
def test_potentials(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_species("A") rds.potentials.add_box("A", 1.0, [1.0, 1.0, 1.0], [1.0, 1.0, 1.0]) rds.potentials.add_box("A", 1.0 * ut.joule / ut.mol / (ut.meter ** 2), np.array([1.0, 1.0, 1.0]) * ut.meter, np.array([1.0, 1.0, 1.0]) * ut.meter) rds.potentials.add_harmonic_repulsion("A", "A", 1.0, 1.0) rds.potentials.add_harmonic_repulsion("A", "A", 1.0 * ut.joule / ut.mol / (ut.meter ** 2), 1.0 * ut.meter) rds.potentials.add_lennard_jones("A", "A", 1, 1, cutoff=10) rds.potentials.add_lennard_jones("A", "A", 1 * ut.joule / ut.mol, 1 * ut.nanometer, m=12, n=6, cutoff=10 * ut.nanometer) rds.potentials.add_screened_electrostatics("A", "A", 10, 10, 10, 10, 10, 10) rds.potentials.add_screened_electrostatics("A", "A", 10 * ut.joule / ut.mol * ut.meter, 10 / ut.meter, 10 * ut.joule / ut.mol, 10 * ut.meter, 10, 10 * ut.meter) rds.potentials.add_sphere("A", 10, (10, 10, 10), 1, True) rds.potentials.add_sphere("A", 10 * ut.joule / ut.mol / (ut.kilometer ** 2), np.array([10, 10, 10]) * ut.nanometer, 1 * ut.picometer, True) rds.potentials.add_sphere("A", 10, (10, 10, 10), 1, False) rds.potentials.add_sphere("A", 10 * ut.joule / ut.mol / (ut.kilometer ** 2), np.array([10, 10, 10]) * ut.nanometer, 1 * ut.picometer, False) rds.potentials.add_spherical_barrier("A", 1, 1, (0, 0, 0), 1) rds.potentials.add_spherical_barrier("A", 1 * ut.kilojoule / ut.mole, 1 * ut.meter, np.array([0, 0, 0]) * ut.meter, 1 * ut.meter) rds.potentials.add_cylinder("A", 10, (10, 10, 10), (10, 10, 10), 1, True) rds.potentials.add_cylinder("A", 10 * ut.joule / ut.mol / (ut.kilometer ** 2), np.array([10, 10, 10]) * ut.nanometer, np.array([10, 10, 10]) * ut.nanometer, 1 * ut.picometer, True) rds.potentials.add_cylinder("A", 10, (10, 10, 10), (10, 10, 10), 1, False) rds.potentials.add_cylinder("A", 10 * ut.joule / ut.mol / (ut.kilometer ** 2), np.array([10, 10, 10]) * ut.nanometer, np.array([10, 10, 10]) * ut.nanometer, 1 * ut.picometer, False) rds.potentials.add_weak_interaction_piecewise_harmonic("A", "A", 10, 10, 10, 10) rds.potentials.add_weak_interaction_piecewise_harmonic("A", "A", 10 * ut.joule / ut.mol / (ut.meter ** 2), 10 * ut.nanometer, 10 * ut.joule / ut.mol, 10 * ut.nanometer)
def test_temperature(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.temperature = 293. np.testing.assert_equal(rds.temperature, 293. * rds.temperature_unit) np.testing.assert_almost_equal(rds.kbt.magnitude, (2.4361374086224026 * rds.energy_unit).magnitude)
def test_edges_decay(self): def dissociation_reaction_function(topology): recipe = readdy.StructuralReactionRecipe(topology) edges = topology.get_graph().get_edges() edge = edges[1 + np.random.randint(0, len(edges) - 2)] recipe.remove_edge(edge) recipe.change_particle_type(edge[0].get().particle_index, "Head") recipe.change_particle_type(edge[1].get().particle_index, "Head") return recipe system = readdy.ReactionDiffusionSystem(box_size=[100, 100, 100]) system.topologies.add_type("Polymer") system.add_topology_species("Head", .002) system.add_topology_species("Tail", .002) simulation = system.simulation(kernel="SingleCPU") head_position = [0, 0, 0] tail1 = [0, 0, 1] tail2 = [0, 0, 2] head_position2 = [0, 0, 3] top = simulation.add_topology( "Polymer", ["Head", "Tail", "Tail", "Head"], np.array([head_position, tail1, tail2, head_position2]).squeeze()) top.get_graph().add_edge(0, 1) top.get_graph().add_edge(1, 2) top.get_graph().add_edge(2, 3) dissociation_reaction_function(top)
def test_add_topology(self): rds = readdy.ReactionDiffusionSystem([10., 10., 10.]) rds.topologies.add_type("toptype") rds.add_topology_species("TopA") rds.add_topology_species("TopB") sim = rds.simulation(kernel="SingleCPU") top1positions = np.random.random((4, 3)) topology1 = sim.add_topology("toptype", "TopA", top1positions) for i, v in enumerate(topology1.get_graph().get_vertices()): np.testing.assert_equal("TopA", topology1.particle_type_of_vertex(v)) np.testing.assert_equal( readdy.api.utils.vec3_of(top1positions[i, :]), topology1.position_of_vertex(v)) top2_types = ["TopB"] + ["TopA" for _ in range(9)] top2positions = np.random.random((10, 3)) topology2 = sim.add_topology("toptype", top2_types, top2positions) for i, v in enumerate(topology2.get_graph().get_vertices()): np.testing.assert_equal( readdy.api.utils.vec3_of(top2positions[i, :]), topology2.position_of_vertex(v)) if i == 0: np.testing.assert_equal("TopB", topology2.particle_type_of_vertex(v)) else: np.testing.assert_equal("TopA", topology2.particle_type_of_vertex(v))
def test_species(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_species("A", 1.) self.assertTrue("A" in rds.registered_species()) rds.add_topology_species("Top A", 10.) self.assertTrue("A" in rds.registered_species() and "Top A" in rds.registered_species())
def test_add_species_unitless_wrong_dimension(self): rds = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], unit_system=None) with self.assertRaises(ValueError): rds.add_species("A", diffusion_constant=1. * readdy.units.nanometer**2 / readdy.units.second)
def runsim(): system = readdy.ReactionDiffusionSystem(box_size=[150, 150, 150]) system.topologies.add_type("Topology") system.add_topology_species("T") system.topologies.configure_harmonic_bond("T", "T", force_constant=20., length=2.) sim = system.simulation() n_topology_particles = 70 positions = [[0, 0, 0], np.random.normal(size=3)] for i in range(n_topology_particles - 2): delta = positions[-1] - positions[-2] offset = np.random.normal(size=3) + delta offset = offset / np.linalg.norm(offset) positions.append(positions[-1] + 2. * offset) topology = sim.add_topology(topology_type="Topology", particle_types="T", positions=np.array(positions)) graph = topology.get_graph() for i in range(len(graph.get_vertices()) - 1): graph.add_edge(i, i + 1) sim.observe.topologies(1) sim.record_trajectory(1) sim.output_file = "yay.h5" sim.run(n_steps=1000, timestep=1e-2)
def test_spatial_topology_reactions(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_topology_species("A", 0.) rds.topologies.add_type("T1") rds.topologies.add_type("T2") rds.topologies.add_type("T3") rds.topologies.add_spatial_reaction("test_fusion: T1(A)+T2(A) -> T3(A--A)", 1., 1.) rds.topologies.add_spatial_reaction("test_enzymatic: T1(A)+T2(A) -> T3(A)+T2(A)", 1., 1.)
def test_pbc(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.periodic_boundary_conditions = True, False, True np.testing.assert_equal(rds.periodic_boundary_conditions, [True, False, True]) rds.periodic_boundary_conditions = np.array([False, False, True]) np.testing.assert_equal(rds.periodic_boundary_conditions, [False, False, True])
def test_simulation_with_negative_skin(self): rds = readdy.ReactionDiffusionSystem([10., 10., 10.]) rds.add_species("A") sim = rds.simulation("CPU") sim.add_particle("A", [0., 0., 0.]) with self.assertRaises(Exception): sim.skin = -1. sim.run(10, 0.1, show_summary=False)
def test_temperature_unitless(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], unit_system=None) rds.kbt = 2.436 with self.assertRaises(ValueError): rds.temperature = 300. # setting temperature without units is not allowed with self.assertRaises(ValueError): print(rds.temperature) # same goes for reading self.assertEqual(rds.kbt, 2.436)
def test_box_size(self): rds = readdy.ReactionDiffusionSystem([1., 2., 3.], unit_system=None) np.testing.assert_equal(rds.box_size, [1., 2., 3.]) rds.box_size = np.array([5., 6., 7.]) np.testing.assert_equal(rds.box_size, [5., 6., 7.]) rds.box_size = (1., 5., 7.) np.testing.assert_equal(rds.box_size, [1., 5., 7.]) np.testing.assert_equal(rds.box_volume, 5. * 7.)
def test_simulation_with_skin(self): rds = readdy.ReactionDiffusionSystem([10., 10., 10.]) rds.add_species("A") rds.potentials.add_harmonic_repulsion("A", "A", 10., 0.5) sim = rds.simulation("CPU") sim.skin = 1. sim.add_particle("A", [0., 0., 0.]) sim.run(10, 0.1, show_summary=False)
def test_change_temperature(self): rds1 = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], temperature=300.) rds1.temperature = 293. np.testing.assert_almost_equal(rds1.temperature.magnitude, 293.) rds2 = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], temperature=300., unit_system={'energy_unit': 'joule'}) rds2.temperature = 293. np.testing.assert_almost_equal(rds2.temperature.magnitude, 293.) rds3 = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], temperature=30. * readdy.units.kelvin, unit_system={'energy_unit': 'joule'}) rds3.temperature = 293. np.testing.assert_almost_equal(rds3.temperature.magnitude, 293.) rds4 = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], temperature=300.) rds4.temperature = 293. * readdy.units.rankine self.assertAlmostEqual(rds4.temperature.magnitude, 162.77, delta=0.1)
def test_topology_potentials(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_topology_species("A", 1.) rds.add_topology_species("B", 1.) rds.add_topology_species("C", 1.) rds.add_topology_species("D", 1.) rds.topologies.configure_harmonic_bond("A", "B", 1., 0.) rds.topologies.configure_harmonic_angle("A", "B", "C", 1., 0.) rds.topologies.configure_cosine_dihedral("A", "B", "C", "D", 1., 1, 0.)
def setUpClass(cls): cls.dir = tempfile.mkdtemp("test-observables-io") sys = readdy.ReactionDiffusionSystem([10, 10, 10]) sys.add_species("A", 1.) sim = sys.simulation() sim.record_trajectory() sim.add_particles("A", np.random.uniform(-4, 4, size=(100, 3))) sim.output_file = cls.dir + "/out.h5" sim.run(123, 1e-4) cls.traj = readdy.Trajectory(sim.output_file)
def test_build_and_run_custom_loop(self): rds = readdy.ReactionDiffusionSystem(box_size=[7., 7., 7.], unit_system=None) rds.add_species("A", 1.0) rds.add_species("B", 1.0) rds.add_species("C", 1.0) rds.reactions.add("fusion: A +(2) B -> C", 10.) simulation = rds.simulation("SingleCPU") simulation.add_particle("A", [0., 0., 0.]) simulation.add_particle("B", [3., 0., 0.]) simulation.output_file = os.path.join(self.dir, "customlooptest1.h5") simulation.observe.number_of_particles(1, ["A", "B", "C"]) def loop(): nonlocal simulation dt = 1.0 n_steps = 10000 base_path = os.path.join(self.dir, "ckpts") os.makedirs(base_path, exist_ok=True) max_n_saves = 2 init = simulation._actions.initialize_kernel() diff = simulation._actions.integrator_euler_brownian_dynamics(dt) calc_forces = simulation._actions.calculate_forces() create_nl = simulation._actions.create_neighbor_list(rds.calculate_max_cutoff()) update_nl = simulation._actions.update_neighbor_list() reac = simulation._actions.reaction_handler_uncontrolled_approximation(dt) obs = simulation._actions.evaluate_observables() check = simulation._actions.make_checkpoint(base_path, max_n_saves) init() create_nl() calc_forces() update_nl() obs(0) for t in tqdm(range(1, n_steps + 1)): diff() update_nl() reac() update_nl() calc_forces() obs(t) # striding of observables is done internally if t % 100 == 0: check(t) simulation._run_custom_loop(loop) traj = readdy.Trajectory(simulation.output_file) ts, ns = traj.read_observable_number_of_particles() self.assertEqual(ns[0, 0], 1) self.assertEqual(ns[0, 1], 1) self.assertEqual(ns[0, 2], 0) self.assertEqual(ns[-1, 0], 0) self.assertEqual(ns[-1, 1], 0) self.assertEqual(ns[-1, 2], 1)
def create_and_show_sim(): try: import os import readdy.util.io_utils as ioutils import matplotlib.pyplot as plt if os.path.exists('out.h5'): os.unlink('out.h5') system = readdy.ReactionDiffusionSystem([25., 25., 25.], temperature=300. * readdy.units.kelvin) system.add_species("A", 1.0) system.reactions.add("myfusion: A +(2) A -> A", rate=10.) system.reactions.add("myfission: A -> A +(2) A", rate=3.) system.potentials.add_harmonic_repulsion("A", "A", force_constant=10., interaction_distance=2.) simulation = system.simulation(kernel="CPU") simulation.output_file = "out.h5" simulation.reaction_handler = "UncontrolledApproximation" simulation.add_particle("A", [0., 0., 0.]) simulation.record_trajectory(stride=1) simulation.observe.number_of_particles(stride=100) simulation.run(n_steps=3000, timestep=1e-2) n_particles_per_frame, positions, types, ids = load_trajectory_to_npy( simulation.output_file, stride=10) config = readdyviewer.Configuration() t = readdy.Trajectory(simulation.output_file) config.colors[t.particle_types['A']] = readdyviewer.Color( plt.cm.jet(0)[0], plt.cm.jet(0)[1], plt.cm.jet(0)[2]) config.radii[t.particle_types['A']] = 7 config.stride = 1 config.smoothing = 3 config.cutoff = 5 config.bond_radius = .02 config.wait = 5 config.clearcolor = readdyviewer.Color(.5, .5, .5) config.draw_periodic = False config.set_box_size(25, 25, 25) readdyviewer.watch_npy(positions, types, ids, n_particles_per_frame, config) finally: if os.path.exists('out.h5'): os.unlink('out.h5')
def test_run_without_progress(self): # deals with issue 161 system = readdy.ReactionDiffusionSystem([25., 25., 25.], temperature=300. * readdy.units.kelvin) simulation = system.simulation(kernel="CPU") simulation.output_file = os.path.join(self.dir, 'test_run_without_progress.h5') simulation.show_progress = False simulation.run(n_steps=10000, timestep=1e-2)
def test_room_temperature_kbt(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.], room_temperature_diffusion=True) rds.temperature = 123 rds.add_species("A", 1.) rds.add_topology_species("T", 2.5) np.testing.assert_almost_equal(rds.diffusion_constants['A'].magnitude, 1. * 123. / 293.) np.testing.assert_almost_equal(rds.diffusion_constants['T'].magnitude, 2.5 * 123. / 293.) with self.assertRaises(Exception): rds.diffusion_constants['A'] = 10. rds.temperature = 200 np.testing.assert_almost_equal(rds.diffusion_constants["A"].magnitude, 1. * (123. / 293.) * (200. / 123.)) np.testing.assert_almost_equal(rds.diffusion_constants["T"].magnitude, 2.5 * (123. / 293.) * (200. / 123.))
def test_structural_topology_reactions(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_topology_species("foo") rds.topologies.add_type("foofoo") def reaction_fun(topology): return readdy.StructuralReactionRecipe(topology) \ .change_particle_type(0, "foo").change_particle_position(0, [0., 0., .1]) def rate_fun(topology): return len(topology.particles) rds.topologies.add_structural_reaction("test", "foofoo", reaction_fun, rate_fun)
def test_displace_particle(self): rds = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], unit_system=None) rds.add_species("A", 1.0) simulation = rds.simulation("SingleCPU") simulation.add_particle("A", [0., 0., 0.]) dt = 1.0 # action factory is an experimental feature and thus _hidden integrator = simulation._actions.integrator_euler_brownian_dynamics(dt) p = simulation.current_particles[0] self.assertTrue(np.all(p.pos == np.array([0., 0., 0.]))) integrator() p = simulation.current_particles[0] self.assertFalse(np.all(p.pos == np.array([0., 0., 0.])))
def test_observables(self): rds = readdy.ReactionDiffusionSystem(box_size=[1., 1., 1.]) rds.add_species("A") simulation = rds.simulation("CPU") simulation.observe.rdf(5, [0., 1., 2.], ["A"], "A", 10) simulation.observe.forces(5) simulation.observe.number_of_particles(5) simulation.observe.particle_positions(5) simulation.observe.particles(5) simulation.observe.reaction_counts(5) simulation.observe.reactions(5) simulation.observe.virial(5) simulation.observe.pressure(5) simulation.run(10, .1 * ut.nanosecond, False)
def lj_system(temperature=1.): system = readdy.ReactionDiffusionSystem( box_size=[edge_length, edge_length, edge_length], unit_system=None) system.kbt = temperature system.add_species("A", diffusion_constant=temperature) system.potentials.add_lennard_jones("A", "A", m=12, n=6, epsilon=1., sigma=1., cutoff=4., shift=True) return system
def test_low_concentration_limit(self): rds = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], unit_system=None) rds.add_species("A", 1.) rds.add_species("B", 1.) rds.add_species("C", 1.) rds.reactions.add("fus: A +(3) B -> C", 10.) rds.reactions.add("fis: C -> A +(3) B", 2.) rds.reactions.add("conversion: A -> C", 5.) rds.potentials.add_harmonic_repulsion("A", "B", 2., 3.) simulation = rds.simulation("SingleCPU") simulation.reaction_handler = "DetailedBalance" simulation.add_particle("A", [0., 0., 0.]) simulation.add_particle("B", [0., 0., 0.]) simulation.run(1000, 1e-1)
def test_write_traj(self): traj_fname = os.path.join(self.tempdir, "traj.h5") rdf = readdy.ReactionDiffusionSystem(box_size=(10, 10, 10)) rdf.add_species("A", diffusion_constant=1.0) rdf.reactions.add_conversion("myconversion", "A", "A", 1.0) rdf.reactions.add_fusion("myfusion", "A", "A", "A", 2, .5) rdf.potentials.add_harmonic_repulsion("A", "A", 1., .2) sim = rdf.simulation(kernel="SingleCPU") sim.show_progress = False sim.output_file = traj_fname sim.record_trajectory(1) sim.add_particles("A", np.random.random((100, 3))) recorded_positions = [] sim.observe.particle_positions( 1, callback=lambda x: recorded_positions.append(x)) sim.run(50, 1e-3, False) traj = readdy.Trajectory(traj_fname) np.testing.assert_equal(traj.diffusion_constants["A"], 1.0) np.testing.assert_("A" in traj.particle_types.keys()) np.testing.assert_equal(len(traj.reactions), 2) conv = next(x for x in traj.reactions if x.name == "myconversion") np.testing.assert_equal(conv.type, "conversion") np.testing.assert_equal(conv.name, "myconversion") np.testing.assert_equal(conv.rate, 1.0) np.testing.assert_equal(conv.educt_types, ["A"]) np.testing.assert_equal(conv.product_types, ["A"]) fusion = next(x for x in traj.reactions if x.name == "myfusion") np.testing.assert_equal(fusion.type, "fusion") np.testing.assert_equal(fusion.name, "myfusion") np.testing.assert_equal(fusion.rate, 2) np.testing.assert_equal(fusion.educt_distance, .5) np.testing.assert_equal(fusion.educt_types, ["A", "A"]) np.testing.assert_equal(fusion.product_types, ["A"]) for idx, frame in enumerate(traj.read()): recorded = recorded_positions[idx] np.testing.assert_equal(len(recorded), len(frame)) for e_idx, entry in enumerate(frame): pos = recorded[e_idx] np.testing.assert_equal(pos.toarray(), entry.position) np.testing.assert_equal("NORMAL", entry.flavor) np.testing.assert_equal("A", entry.type) np.testing.assert_equal(idx, entry.t)
def spatial_reaction_rate_function(kernel): """ Create a small simulation of 4 polymers that form arranged as a square. Heads of the polymers are close, such that they could bind. The rate function should allow only two of the polymers to bind, so that we end up with 2 pairs of two connected polymers. """ def rate_function(top1, top2): vert1 = top1.get_graph().get_vertices() vert2 = top2.get_graph().get_vertices() if len(vert1) + len(vert2) > 12: return 0.0 return 1e10 system = readdy.ReactionDiffusionSystem(box_size=[30., 30., 30.]) system.topologies.add_type("Polymer") system.add_topology_species("Head", 0.002) system.add_topology_species("Core", 0.002) system.topologies.configure_harmonic_bond("Head", "Core", force_constant=50, length=1.) system.topologies.configure_harmonic_bond("Core", "Core", force_constant=50, length=1.) system.topologies.add_spatial_reaction( "Association: Polymer(Head) + Polymer(Head) -> Polymer(Core--Core)", rate=rate_function, radius=2.0) simulation = system.simulation(kernel=kernel) types_and_positions = TestTopologyReactions._get_polymer_types_and_positions( ) for t, p in types_and_positions: top = simulation.add_topology("Polymer", t, p) for i in range(5): top.get_graph().add_edge(i, i + 1) simulation.run(10, 1.) np.testing.assert_equal(2, len(simulation.current_topologies))
def test_box_compartment(self): system = readdy.ReactionDiffusionSystem([10, 10, 10]) system.add_species("A", diffusion_constant=1.) system.add_species("Aint", diffusion_constant=1.) system.compartments.add_geometry({"A": "Aint"}, "tmp", system.geometry.create_box( [-1, -1, -1], [3, 3, 3]), True) system.compartments.add_geometry({"A": "Aint"}, "tmp", system.geometry.create_sphere( [0, 0, 0], 1.), True) system.compartments.add_geometry( {"A": "Aint"}, "tmp", system.geometry.create_capsule([0., 0., 0.], [1., 0., 0.], 1., 2.), True) sim = system.simulation() sim.add_particles("A", np.random.uniform(-5, 5, size=(100, 3))) sim.run(1000, timestep=1e-3)