def bilayer_lipid(): import matplotlib.pyplot as plt outfile = "/home/mho/Downloads/new-self-ass.h5" n_particles_per_frame, positions, types, ids = load_trajectory_to_npy( outfile, stride=10) config = readdyviewer.Configuration() t = readdy.Trajectory(outfile) config.colors[t.particle_types['Head']] = readdyviewer.Color( plt.cm.jet(0)[0], plt.cm.jet(0)[1], plt.cm.jet(0)[2]) config.radii[t.particle_types['Head']] = .7 config.colors[t.particle_types['Tail']] = readdyviewer.Color( plt.cm.jet(1.)[0], plt.cm.jet(1.)[1], plt.cm.jet(1.)[2]) config.radii[t.particle_types['Tail']] = .7 config.stride = 1 config.smoothing = 5 config.cutoff = 5 config.bond_radius = .02 config.wait = 3 config.draw_periodic = True config.set_box_size(25, 25, 25) readdyviewer.watch_npy(positions, types, ids, n_particles_per_frame, config) #
def calc_unbound_rdf(trajfiles, nL, rbins, tbins, rrange, nmax=None): r = [] t = [] for trajfile in trajfiles: print("Processing trajectory: {}".format(trajfile)) traji = readdy.Trajectory(trajfile) density_ideal = nL / (traji.box_size[0] * traji.box_size[1] * traji.box_size[2]) try: bound_intervals, unbound_intervals = get_bound_unbound_intervals( traji) if nmax is None: nmax = len(unbound_intervals) elif nmax > len(unbound_intervals): nmax = len(unbound_intervals) def parfunc(bi): ri, ti = calc_LS_distance(traji, nL, bi) return (ri, ti) n_proc = 4 out = Parallel(n_jobs=n_proc)(delayed(parfunc)(bi) for bi in unbound_intervals[0:nmax]) [r.append(xi[0]) for xi in out if xi[1] is not None] [t.append(xi[1]) for xi in out if xi[1] is not None] except IndexError as e: print(e) r = np.vstack(r) t = np.hstack(t) T = np.zeros(r.shape) for i in range(r.shape[1]): T[:, i] = t r = r.flatten() T = T.flatten() trange = (0., np.max(t)) rmin = rrange[0] rmax = rrange[1] rbins = np.linspace(rmin, rmax, rbins + 1) dr = rbins[1] - rbins[0] rbin_centers = rbins[0:-1] + dr * 0.5 rweights = 1. / (4. * np.pi * rbin_centers**2. * dr * density_ideal) hist2d, r_edges, t_edges = np.histogram2d(r, T, bins=[rbins, tbins], range=[rrange, trange]) for j in range(hist2d.shape[1]): hist2d[:, j] *= rweights return hist2d, r_edges, t_edges
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 calc_bound_rdf(trajfiles, nL, rbins, tbins, rrange): r = [] t = [] for trajfile in trajfiles: print("Processing trajectory: {}".format(trajfile)) traji = readdy.Trajectory(trajfile) density_ideal = nL / (traji.box_size[0] * traji.box_size[1] * traji.box_size[2]) try: bound_intervals, unbound_intervals = get_bound_unbound_intervals( traji) def parfunc(bi): ri, ti = calc_LSL_distance(traji, nL, bi) return (ri, ti) n_proc = 4 out = Parallel(n_jobs=n_proc)(delayed(parfunc)(bi) for bi in bound_intervals) [r.append(xi[0]) for xi in out] [t.append(xi[1]) for xi in out] except IndexError as e: print(e) r = np.vstack(r) t = np.hstack(t) r = np.array(r).flatten() t = np.array(t).flatten() trange = (0., np.max(t)) rmin = rrange[0] rmax = rrange[1] rbins = np.linspace(rmin, rmax, rbins + 1) dr = rbins[1] - rbins[0] rbin_centers = rbins[0:-1] + dr * 0.5 rweights = 1. / (4. * np.pi * rbin_centers**2. * dr * density_ideal) hist2d, r_edges, t_edges = np.histogram2d(r, t, bins=[rbins, tbins], range=[rrange, trange]) for j in range(hist2d.shape[1]): #hist2d[:,j] *= rweights / (np.sum(hist2d[:,j])) hist2d[:, j] *= rweights return hist2d, r_edges, t_edges
def calculate_unbinding_moves(trajfile,potdict,rneighbor,R_react,weight_L,weight_S,**kwargs): if 'n_samples' in kwargs: n_samples = kwargs['n_samples'] else: n_samples = 10000 if 'n_trials' in kwargs: n_trials = kwargs['n_trials'] else: n_trials = 1 if 'savefile' in kwargs: savefile = kwargs['savefile'] else: savefile = "accepted_dissociation_moves.txt" if 'tau_mol' in kwargs: tau_mol = kwargs['tau_mol'] else: tau_mol = None if 'micro_model' in kwargs: if kwargs['micro_model']=="dimer": sample_diss = lambda traj: sample_dissociation_events_dimer(traj,potdict,rneighbor,R_react,weight_L,weight_S,n_samples,n_trials) elif kwargs['micro_model']=="sphere": sample_diss = lambda traj: sample_dissociation_events(traj,potdict,rneighbor,R_react,weight_L,weight_S,n_samples,n_trials) else: print("ERROR: micro_model must be either dimer or sphere, if defined!") else: sample_diss = lambda traj: sample_dissociation_events(traj,potdict,rneighbor,R_react,weight_L,weight_S,n_samples,n_trials) traj = readdy.Trajectory(trajfile) #stored_accepted_moves, Naccepted, Ntotal, Paccept, total_time, rvals = sample_dissociation_events(traj,potdict,rneighbor,R_react,weight_L,weight_S,n_samples,n_trials) stored_accepted_moves, Naccepted, Ntotal, Paccept, total_time, rvals = sample_diss(traj) print("**********************************************") print("Accepted/Total trials: {}/{}".format(Naccepted,Ntotal)) print("Acceptance Probability: {:.2f}".format(Paccept)) if tau_mol is not None: print("Sampling Time/Molecular Timescale: {:.1f} independent samples".format(total_time/tau_mol)) print("**********************************************") # Write accepted dissociation configurations to seperate files to use as initital conditions header = "R_react {} weight_L {} weight_S {} Pacc {}".format(R_react,weight_L,weight_S,Paccept) np.savetxt(savefile, stored_accepted_moves, header=header) return
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 edges(): print(readdyviewer.__file__) trajfile = "/home/mho/Development/readdyviewer/tests/topology_simulation.h5" n_particles_per_frame, positions, types, ids = load_trajectory_to_npy( trajfile) config = readdyviewer.Configuration() t = readdy.Trajectory(trajfile) entries = t.read() time, topology_records = t.read_observable_topologies() print(len(topology_records)) print(len(topology_records[0][0].edges)) edges = [] for timestep, tops in zip(time, topology_records): current_edges = [] for top in tops: for e1, e2 in top.edges: if e1 <= e2: ix1 = top.particles[e1] ix2 = top.particles[e2] current_edges.append((ix1, ix2)) p1 = entries[timestep][ix1] p2 = entries[timestep][ix2] assert p1.type == 'T' or p1.type == 'unstable T', "expected topology type but got {} -- {}".format( p1, p2) assert p2.type == 'T' or p2.type == 'unstable T', "expected topology type but got {} -- {}".format( p1, p2) edges.append(current_edges) config.colors[t.particle_types['unstable T']] = readdyviewer.Color( 153. / 255., 255. / 255., 0.) config.radii[t.particle_types['unstable T']] = .5 config.colors[t.particle_types['T']] = readdyviewer.Color( 255. / 255., 153. / 255., 0.) config.radii[t.particle_types['T']] = .5 config.colors[t.particle_types['Ligand']] = readdyviewer.Color(.5, .5, .5) config.radii[t.particle_types['Ligand']] = 1. config.colors[t.particle_types['Decay']] = readdyviewer.Color(.1, .2, .3) config.radii[t.particle_types['Decay']] = .5 config.stride = 1 config.smoothing = 10 config.bond_radius = .2 config.cutoff = 3 config.edge_color = readdyviewer.Color(.1, .1, .1) readdyviewer.watch_npy(positions, types, ids, n_particles_per_frame, config, edges)
def calc_survival_times(traj_file): print(traj_file) traj = readdy.Trajectory(traj_file) periodic_directions = [0,1,2] timestep = 1e-4 time_sim, counts = traj.read_observable_number_of_particles() time = time_sim * timestep counts = counts.astype(np.int8) # copy number of inactive sensor at each timestep diffS = np.diff(counts[:,1]) act_reacts_inds = np.where(diffS==-1) # timesteps of S->SA reactions deact_reacts_inds = np.where(diffS==1) # timesteps of SA->S reactions act_times = time[act_reacts_inds] deact_times = time[deact_reacts_inds] if counts[0,1]==0: # Sensor is initially in bound state act_times = np.insert(act_times,0,0.) # Calculate survival times (i.e. unbound durations) if act_times.shape[0]==deact_times.shape[0]: survival_times = act_times[1:] - deact_times[:-1] else: survival_times = act_times[1:] - deact_times # Calculate suruvival time of complex (i.e. bound durations) if act_times.shape[0]==deact_times.shape[0]: bound_times = deact_times - act_times else: bound_times = deact_times - act_times[:-1] return (survival_times, bound_times)
def more_topologies_sim(): trajfile = "/home/mho/Development/readdyviewer/tests/more_topologies_simulation.h5" n_particles_per_frame, positions, types, ids = load_trajectory_to_npy( trajfile) config = readdyviewer.Configuration() t = readdy.Trajectory(trajfile) entries = t.read() time, topology_records = t.read_observable_topologies() edges = [] for timestep, tops in enumerate(topology_records): current_edges = [] for top in tops: for e1, e2 in top.edges: ix1 = top.particles[e1] ix2 = top.particles[e2] current_edges.append((ix1, ix2)) p1 = entries[timestep][ix1] p2 = entries[timestep][ix2] assert p1.type == 'T' or p1.type == 'center T', "expected topology type but got {} -- {}".format( p1, p2) assert p2.type == 'T' or p2.type == 'center T', "expected topology type but got {} -- {}".format( p1, p2) edges.append(current_edges) config.colors[t.particle_types['center T']] = readdyviewer.Color( 153. / 255., 255. / 255., 0.) config.radii[t.particle_types['center T']] = .5 config.colors[t.particle_types['T']] = readdyviewer.Color( 255. / 255., 153. / 255., 0.) config.radii[t.particle_types['T']] = .5 config.clearcolor = readdyviewer.Color(155. / 255., 155. / 255., 155. / 255.) config.stride = 1 print(positions.shape) print("go!") readdyviewer.watch_npy(positions, types, ids, n_particles_per_frame, config, edges)
import os import numpy as np import readdy rds = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.], unit_system=None) rds.add_species("A") rds.potentials.add_cylinder("A", 100, (0, 0, 0), (1, 0, 0), 1, inclusion=False) simulation = rds.simulation(kernel="SingleCPU") simulation.output_file = "out.h5" simulation.add_particles("A", np.random.normal(size=(5000, 3))) simulation.record_trajectory(stride=100) if os.path.exists(simulation.output_file): os.remove(simulation.output_file) simulation.run(n_steps=30000, timestep=1e-3) trajectory = readdy.Trajectory('out.h5') trajectory.convert_to_xyz(particle_radii={'A': 0.1})
if not os.path.exists(outdir): os.makedirs(outdir) outfile = "{}/LigandDiffusion_unbound_out_bulk_index_{}.h5".format( outdir, config_index) if args.savexyz: save_xyz = bool(args.savexyz) else: save_xyz = False #----------------------------------------------------------------------------------- #### Load trajectory and L-R configuration files #### #----------------------------------------------------------------------------------- # Load trajectory data traj = readdy.Trajectory(rundir + 'LigandDiffusion_out_bulk.h5') timestep, types, ids, positions = traj.read_observable_particles() # Load LR config file LRconfigfile = rundir + "accepted_dissociation_moves.txt" with open(LRconfigfile, 'r') as f: header = f.readline() split_header = header.split() # Get particle positions for initial condition orientation_data = np.loadtxt(LRconfigfile, skiprows=config_index + 1, max_rows=1) config_time_ind = int(orientation_data[0]) dE = orientation_data[1] pos_dissocL = orientation_data[2:5].reshape((1, 3))
def perform(kernel="SingleCPU", n_particles_a=2357, force_constant=10., file_suffix="", full_simulation=False, debug_run=False, n_threads=-1): print("kernel {}, n_particles_a {}, force_constant {}, threads {}".format( kernel, n_particles_a, force_constant, n_threads)) n_particles_b = n_particles_a n_particles_c = 0 desired_a_density = 2357. / 1e6 # number of particles per nanometer**3 edge_length = (n_particles_a / desired_a_density)**(1. / 3.) print("Use edge length {}".format(edge_length)) system = readdy.ReactionDiffusionSystem( box_size=[edge_length, edge_length, edge_length], temperature=293., unit_system={ "length_unit": "nanometer", "time_unit": "nanosecond", "energy_unit": "kilojoule / mol" }) particle_radii = {"A": 1.5, "B": 3., "C": 3.12} # in nanometers ut = readdy.units system.add_species("A", diffusion_constant=143.1 * ut.micrometer**2 / ut.second) system.add_species("B", diffusion_constant=71.6 * ut.micrometer**2 / ut.second) system.add_species("C", diffusion_constant=68.82 * ut.micrometer**2 / ut.second) reaction_radius = particle_radii["A"] + particle_radii["B"] system.reactions.add_fusion("fusion", "A", "B", "C", rate=1e6 * 1. / ut.second, educt_distance=reaction_radius * ut.nanometer) system.reactions.add_fission("fission", "C", "A", "B", rate=5e4 * 1. / ut.second, product_distance=reaction_radius * ut.nanometer) if force_constant > 0.: fc = force_constant * ut.kilojoule / ut.mol / (ut.nanometer**2) system.potentials.add_harmonic_repulsion( "A", "A", fc, interaction_distance=particle_radii["A"] + particle_radii["A"]) system.potentials.add_harmonic_repulsion( "B", "B", fc, interaction_distance=particle_radii["B"] + particle_radii["B"]) system.potentials.add_harmonic_repulsion( "C", "C", fc, interaction_distance=particle_radii["C"] + particle_radii["C"]) system.potentials.add_harmonic_repulsion( "A", "B", fc, interaction_distance=particle_radii["A"] + particle_radii["B"]) system.potentials.add_harmonic_repulsion( "B", "C", fc, interaction_distance=particle_radii["B"] + particle_radii["C"]) system.potentials.add_harmonic_repulsion( "C", "A", fc, interaction_distance=particle_radii["C"] + particle_radii["A"]) simulation = system.simulation(kernel=kernel) simulation.output_file = "cytosolic_reactions_" + kernel + "_n_a_" + str(n_particles_a) \ + "_force_" + str(force_constant) + "_" + file_suffix + ".h5" simulation.reaction_handler = "UncontrolledApproximation" edge_length = system.box_size[0] if full_simulation: initial_positions_a = np.random.random( size=(n_particles_a, 3)) * edge_length - .5 * edge_length initial_positions_b = np.random.random( size=(n_particles_b, 3)) * edge_length - .5 * edge_length simulation.add_particles("A", initial_positions_a) simulation.add_particles("B", initial_positions_b) else: # start in roughly equilibrated state n_particles_c = n_particles_a * 2 // 3 n_particles_a_actual = n_particles_a - n_particles_c n_particles_b = n_particles_a_actual initial_positions_a = np.random.random( size=(n_particles_a_actual, 3)) * edge_length - .5 * edge_length initial_positions_b = np.random.random( size=(n_particles_b, 3)) * edge_length - .5 * edge_length initial_positions_c = np.random.random( size=(n_particles_c, 3)) * edge_length - .5 * edge_length simulation.add_particles("A", initial_positions_a) simulation.add_particles("B", initial_positions_b) simulation.add_particles("C", initial_positions_c) simulation.observe.number_of_particles(stride=1, types=["A", "B", "C"]) if os.path.exists(simulation.output_file): os.remove(simulation.output_file) dt = 1e-1 # in nanoseconds if full_simulation: n_steps = int(10000. / dt) # simulate to 10 microseconds else: n_steps = 3000 if debug_run: n_steps = 200 print("Performing n_steps {} ..".format(n_steps)) if kernel != 'SingleCPU': simulation.kernel_configuration.n_threads = n_threads simulation.run(n_steps=n_steps, timestep=dt * ut.nanosecond) perf = simulation._simulation.performance_root() print(perf) print("Simulated for {} seconds".format(perf.time())) performance_tree = traverse_performance_tree(perf) traj = readdy.Trajectory(simulation.output_file) times, counts = traj.read_observable_number_of_particles() counts = {"A": counts[:, 0], "B": counts[:, 1], "C": counts[:, 2]} times = times * dt n_frames = len(counts["A"]) average_n_particles = (np.sum(counts["A"]) + np.sum(counts["B"]) + np.sum(counts["C"])) / n_frames print("Time averaged total number of particles {}".format( average_n_particles)) t_pp_ps = perf.time() / average_n_particles / n_steps print("Computation time per particle per integration step is {} seconds". format(t_pp_ps)) arguments = { "kernel": kernel, "n_particles_a": n_particles_a, "force_constant": force_constant, "file_suffix": file_suffix } result = { "time/particle/step": t_pp_ps, "average_n_particles": average_n_particles, "n_particles": counts, "times": times, "computation_time": perf.time(), "performance_tree": performance_tree, "volume": edge_length**3, "unit_system": { "length_unit": "nanometer", "time_unit": "nanosecond", "energy_unit": "kilojoule / mol" }, "n_steps": n_steps, "n_threads": n_threads } data = dict() data.update(arguments) data.update(result) os.unlink(simulation.output_file) del simulation del system import gc gc.collect() return data
if __name__ == '__main__': system = readdy.ReactionDiffusionSystem( box_size=(4, 4, 4), periodic_boundary_conditions=[True, True, True], unit_system=None) system.add_species("A", 1.0) system.add_species("B", 1.0) system.potentials.add_harmonic_repulsion("A", "B", 1., 1.) simulation = system.simulation(kernel="SingleCPU") simulation.output_file = "out.h5" simulation.observe.rdf(200, np.linspace(0., 2., 10), ["A"], ["B"], 1. / system.box_volume) simulation.add_particle("A", [0., 0., 0.]) simulation.add_particle("B", [0., 0., 1.]) if os.path.exists(simulation.output_file): os.remove(simulation.output_file) simulation.run(n_steps=10000000, timestep=2e-3) traj = readdy.Trajectory(simulation.output_file) rdf_times, bin_centers, rdf_values = traj.read_observable_rdf() mean, std_dev, std_err = average_across_first_axis(rdf_values) plt.errorbar(bin_centers, mean, yerr=std_err, fmt=".", label="ReaDDy") plot_boltzmann(1., 1.) plt.legend() plt.xlabel(r"Distance $r$ of A and B") plt.ylabel(r"Radial distribution function $g(r)$") plt.show()
def test_reactions_observable(self): fname = os.path.join(self.dir, "test_observables_particle_reactions.h5") context = Context() context.box_size = [10., 10., 10.] context.particle_types.add("A", .0) context.particle_types.add("B", .0) context.particle_types.add("C", .0) context.reactions.add_conversion("mylabel", "A", "B", .00001) context.reactions.add_conversion("A->B", "A", "B", 1.) context.reactions.add_fusion("B+C->A", "B", "C", "A", 1.0, 1.0, .5, .5) sim = Simulation("CPU", context) sim.add_particle("A", common.Vec(0, 0, 0)) sim.add_particle("B", common.Vec(1.0, 1.0, 1.0)) sim.add_particle("C", common.Vec(1.1, 1.0, 1.0)) n_timesteps = 1 handle = sim.register_observable_reactions(1) with closing(io.File.create(fname)) as f: handle.enable_write_to_file(f, u"reactions", int(3)) loop = sim.create_loop(1) loop.write_config_to_file(f) loop.run(n_timesteps) type_str_to_id = { k: x["type_id"] for k, x in ioutils.get_particle_types(fname).items() } traj = readdy.Trajectory(fname) reac = traj.read_observable_reactions() with h5py.File(fname, "r") as f2: data = f2["readdy/observables/reactions"] time_series = f2["readdy/observables/reactions/time"] np.testing.assert_equal(time_series, np.array(range(0, n_timesteps + 1))) def get_item(name, collection): return next(x for x in collection if x["name"] == name) import readdy.util.io_utils as io_utils reactions = io_utils.get_reactions(fname) mylabel_reaction = get_item(b"mylabel", reactions.values()) np.testing.assert_allclose(mylabel_reaction["rate"], .00001) np.testing.assert_equal(mylabel_reaction["n_educts"], 1) np.testing.assert_equal(mylabel_reaction["n_products"], 1) np.testing.assert_equal(mylabel_reaction["educt_types"], [type_str_to_id["A"], 0]) np.testing.assert_equal(mylabel_reaction["product_types"], [type_str_to_id["B"], 0]) atob_reaction = get_item(b"A->B", reactions.values()) np.testing.assert_equal(atob_reaction["rate"], 1.) np.testing.assert_equal(atob_reaction["n_educts"], 1) np.testing.assert_equal(atob_reaction["n_products"], 1) np.testing.assert_equal(mylabel_reaction["educt_types"], [type_str_to_id["A"], 0]) np.testing.assert_equal(mylabel_reaction["product_types"], [type_str_to_id["B"], 0]) fusion_reaction = get_item(b"B+C->A", reactions.values()) np.testing.assert_equal(fusion_reaction["rate"], 1.) np.testing.assert_equal(fusion_reaction["educt_distance"], 1.) np.testing.assert_equal(fusion_reaction["n_educts"], 2) np.testing.assert_equal(fusion_reaction["n_products"], 1) np.testing.assert_equal(fusion_reaction["educt_types"], [type_str_to_id["B"], type_str_to_id["C"]]) np.testing.assert_equal(fusion_reaction["product_types"], [type_str_to_id["A"], 0]) _, records = reac np.testing.assert_equal(len(records), 2) # records of 1st time step for record in records[1]: np.testing.assert_(record.type in ('conversion', 'fusion')) if record.type == 'conversion': np.testing.assert_equal(record.position, np.array([.0, .0, .0])) np.testing.assert_equal(record.reaction_label, 'A->B') else: # fusion np.testing.assert_allclose(record.position, np.array([1.05, 1.0, 1.0])) np.testing.assert_equal(record.reaction_label, 'B+C->A')
nC = 1 kOn = "1E+2" kOff = "1E-0" traj_numbers = range(0, 10) rundir = "./run_bulk_nL{}_nC{}_kOn{}_kOff{}/".format(nLtag, nC, kOn, kOff) # Set number of free ligands nL = nLtag - 1 trajfiles = [ rundir + 'trajectory_{}/LR_out_bulk.h5'.format(traji) for traji in traj_numbers ] # Build bins for radial distribution function of ligands as function of time traj0 = readdy.Trajectory(trajfiles[0]) rbins = 100 rmin = 1.7 rmax = traj0.box_size[0] * 0.5 # (this can be improved upon) bin_edges = np.linspace(rmin, rmax, rbins + 1) rrange = (rmin, rmax) tbins = 100 hist2d, r_edges, t_edges = calc_bound_rdf(trajfiles, nL, rbins, tbins, rrange) print(hist2d.shape) # Normalize rdf at each time for j in range(hist2d.shape[1]):
def calculate_reaction_probs(rundir,potdict,r_react,weight_L,nL,nLtag,**kwargs):#n_cores=1,savefile): # Parse kwargs if 'n_cores' in kwargs: n_cores = kwargs['n_cores'] else: n_cores = 1 if 'savefile' in kwargs: savefile = kwargs['savefile'] else: savefile = "unbound_reaction_event_density_nL_{}".format(nL) if 'trajfile' in kwargs: trajfile = kwargs['trajfile'] else: trajfile = None if 'micro_model' in kwargs: if kwargs['micro_model']=="dimer": parfunc_calc_accept = lambda trajfile: calc_accept_dimer(trajfile,potdict,r_react,weight_L,nL,nLtag) elif kwargs['micro_model']=="sphere": parfunc_calc_accept = lambda trajfile: calc_accept(trajfile,potdict,r_react,weight_L,nL,nLtag) else: print("ERROR: micro_model must be either dimer or sphere, if defined!") else: parfunc_calc_accept = lambda trajfile: calc_accept(trajfile,potdict,r_react,weight_L,nL,nLtag) # Loop over unbound simulations if trajfile is None: trajfilebase = rundir+'unbound_simulations_fine_output/LigandDiffusion_unbound_out_bulk_index_*.h5' config_indices = [] trajfiles = [] total_errors = 0 for filepath in glob.iglob(trajfilebase): trajfiles.append(filepath) else: trajfiles = [trajfile] traj0 = readdy.Trajectory(trajfiles[0]) timestep, types, ids, positions = traj0.read_observable_particles() tstart = 0 tstop = timestep.shape[0] sample_freq = 1 time_indices = range(tstart,tstop,sample_freq) #parfunc_calc_accept = lambda trajfile: calc_accept(trajfile,potdict,r_react,weight_L,nL,nLtag) react_probs = Parallel(n_jobs=n_cores)(delayed(parfunc_calc_accept)(traji) for traji in trajfiles) react_probs = [x for x in react_probs if x is not None] react_probs = np.array(react_probs) # Save reaction probability header = "tstart {} tstop {} sample_freq {} nL {}".format(tstart,tstop,sample_freq,nL) outfile = rundir + savefile np.save(outfile,react_probs) print("Reaction Probabilities saved to: {}".format(outfile)) return react_probs
def main(): parser = argparse.ArgumentParser( description="Parses an hdf5 (*.h5) trajectory file produced\ by the ReaDDy software and converts it into the Simularium\ visualization-data-format") parser.add_argument("file_path", help="the file path of the trajectory to parse") parser.add_argument( "output_path", help="the output file path to save the processed trajectory to") args = parser.parse_args() file_path = args.file_path output_path = args.output_path traj = readdy.Trajectory(file_path) n_particles_per_frame, positions, types, ids = traj.to_numpy(start=0, stop=None) # load flavors flavors = np.zeros_like(types) for typeid in range(np.max(types)): if traj.is_topology_particle_type(typeid): flavors[types == typeid] = 1 else: flavors[types == typeid] = 0 # types.shape[1] is the max. number of particles in the simulation # for each particle: # - vis type 1000 (1) # - type id (1) # - loc (3) # - rot (3) # - radius/flavor (1) # - n subpoints (1) max_n_particles = types.shape[1] frame_buf = np.zeros((max_n_particles * 10, )) frame_buf[::10] = 1000 # vis type data = {} data['msgType'] = 1 data['bundleStart'] = 0 data['bundleSize'] = len(n_particles_per_frame) data['bundleData'] = [] ix_particles = np.empty((3 * max_n_particles, ), dtype=int) for i in range(max_n_particles): ix_particles[3 * i:3 * i + 3] = np.arange(i * 10 + 2, i * 10 + 2 + 3) for t in range(len(n_particles_per_frame)): frame_data = {} frame_data['frameNumber'] = t frame_data['time'] = float(t) n_particles = int(n_particles_per_frame[t]) local_buf = frame_buf[:10 * n_particles] local_buf[1::10] = types[t, :n_particles] local_buf[ix_particles[:3 * n_particles]] = positions[ t, :n_particles].flatten() local_buf[8::10] = flavors[t, :n_particles] frame_data['data'] = local_buf.tolist() data['bundleData'].append(frame_data) with open(output_path, 'w+') as outfile: json.dump(data, outfile)
def _run_test(self, with_topologies, with_particles, fname): system = self._set_up_system() sim = system.simulation() if with_topologies: t1_initial_pos = np.random.normal(0, 1, size=(4, 3)) t1 = sim.add_topology("TT1", ["T1", "T2", "T1", "T2"], t1_initial_pos) t1.graph.add_edge(0, 1) t1.graph.add_edge(1, 2) t1.graph.add_edge(2, 3) t1.graph.add_edge(3, 0) t2_initial_pos = np.random.normal(0, 1, size=(4, 3)) t2 = sim.add_topology("TT2", ["T2", "T1", "T2", "T1"], t2_initial_pos) t2.graph.add_edge(0, 1) t2.graph.add_edge(1, 2) t2.graph.add_edge(2, 3) if with_particles: a_particles_initial_pos = np.random.normal(0, 1, size=(20, 3)) sim.add_particles("A", a_particles_initial_pos) b_particles_initial_pos = np.random.normal(0, 1, size=(50, 3)) sim.add_particles("B", b_particles_initial_pos) def topologies_callback(_): if with_topologies: if len(sim.current_topologies) % 2 == 0: sim.add_topology("Dummy", "Dummy", np.random.random(size=(1, 3))) else: t = sim.add_topology("Dummy", "Dummy", np.random.random(size=(5, 3))) t.graph.add_edge(0, 1) t.graph.add_edge(1, 2) t.graph.add_edge(2, 3) t.graph.add_edge(3, 4) t.configure() sim.make_checkpoints(7, output_directory=self.dir, max_n_saves=7) sim.record_trajectory() sim.observe.topologies(1, callback=topologies_callback) sim.output_file = os.path.join(self.dir, fname) sim.show_progress = False sim.run(120, 1e-2, show_summary=False) traj = readdy.Trajectory(sim.output_file) entries = traj.read() _, traj_tops = traj.read_observable_topologies() system = self._set_up_system() sim = system.simulation() ckpt_files = sim.list_checkpoint_files(self.dir) ckpt_file = sim.get_latest_checkpoint_file(self.dir) checkpoints = sim.list_checkpoints(ckpt_file) checkpoint = checkpoints[-1] latest_checkpoint_step = 120 // 7 * 7 assert checkpoint['step'] == latest_checkpoint_step, "expected {} but got {} (file {} of files {})"\ .format(latest_checkpoint_step, checkpoint['step'], ckpt_file, ckpt_files) sim.load_particles_from_checkpoint(ckpt_file) current_entries = entries[latest_checkpoint_step] current_particles = sim.current_particles if with_topologies: tops = sim.current_topologies assert len(tops) == len(traj_tops[latest_checkpoint_step]), \ f"expected {len(traj_tops[latest_checkpoint_step])} topologies, " \ f"got {len(tops)} (file {ckpt_file})" assert tops[0].type == "TT1" assert tops[0].graph.has_edge(0, 1) assert tops[0].graph.has_edge(1, 2) assert tops[0].graph.has_edge(2, 3) assert tops[0].graph.has_edge(3, 0) assert not tops[0].graph.has_edge(0, 2) assert not tops[0].graph.has_edge(1, 3) assert tops[1].type == "TT2" assert tops[1].graph.has_edge(0, 1) assert tops[1].graph.has_edge(1, 2) assert tops[1].graph.has_edge(2, 3) topologies = traj_tops[checkpoint['step']] # check whether restored topologies are o.k. assert len(topologies) == len(tops) for ix, topology_record in enumerate(topologies): restored_topology = tops[ix] for edge in topology_record.edges: assert tops[ix].graph.has_edge(*edge) for pix, particle_ix in enumerate(topology_record.particles): particle = current_entries[particle_ix] restored_particle = restored_topology.particles[pix] assert np.array_equal(restored_particle.pos, np.array(particle.position)) assert restored_particle.type == particle.type # check whether restored particles are o.k. for entry in current_entries: # see if entry is available in current particles ix = 0 for ix, particle in enumerate(current_particles): if particle.type == entry.type and np.array_equal( particle.pos, entry.position): break assert ix < len(current_particles ), f"entry {entry} was not found in particles!" current_particles.pop(ix) assert len(current_particles) == 0 sim.show_progress = False sim.run(500, 1e-3, show_summary=False)
def main(**kwargs): h5_fname = kwargs['fname'] logger.info(f'Reading trajectory from {h5_fname}') trajectory = readdy.Trajectory(h5_fname) trajectory.convert_to_xyz() xyz_fname = f'{h5_fname}.xyz' n_lines = \ int(check_output(['wc', '-l' , xyz_fname]).split()[0].decode("utf-8")) with open(xyz_fname, 'r') as f: n_atoms = int(f.readline().strip()) start = 2 n_frames = int(n_lines / (n_atoms + 2)) f_folder = 'traj' try: rmtree(Path(f_folder)) except FileNotFoundError: pass Path.mkdir(Path(f_folder)) particles = trajectory.read_observable_particles() timesteps = particles[0] particle_types = particles[1] n_particles = pd.DataFrame() for i in range(n_frames - 1): data = pd.read_csv(xyz_fname, delimiter='\t', skiprows=start + i * (n_atoms + 2), nrows=n_atoms, header=None, na_values='0').rename(columns={ 0: 'type', 1: 'x', 2: 'y', 3: 'z' }) n_active_atoms = n_atoms - data.isnull().sum().values[-1] data = data.dropna().reset_index(drop=True) with open(f'{f_folder}/readdy.xyz.{i}', 'w') as f: f.write(f'{n_active_atoms}\n\n') data.to_csv(f, index=False, header=False, float_format="%g", sep='\t') n_particles = pd.concat( [n_particles, pd.DataFrame(count(particle_types[i])).T]) n_particles = n_particles.reset_index(drop=True) fig, ax = plt.subplots() particle_names = [ 'unbonded', 'gel', 'released', 'enzyme', ] for i in range(4): ax.plot(n_particles[i], label=particle_names[i]) ax.set_xlabel('Timestep') ax.set_ylabel('Number of Particles') ax.legend(frameon=False) fig.savefig('particles.pdf') plt.show()
def _run_readwrite_test_for(self, kernel, reaction_handler): traj_fname = os.path.join(self.tempdir, "traj_{}_{}.h5".format(kernel, reaction_handler)) traj_fname2 = os.path.join(self.tempdir, "traj2_{}_{}.h5".format(kernel, reaction_handler)) rds = readdy.ReactionDiffusionSystem(box_size=[10., 10., 10.]) rds.add_species("A", diffusion_constant=1.0) rds.add_species("B", diffusion_constant=1.0) rds.reactions.add_conversion("myconversion", "A", "B", 1.0) rds.reactions.add_fusion("myfusion", "A", "A", "A", 2, .5) rds.reactions.add_fission("myfission", "A", "A", "A", 2, .5) rds.potentials.add_harmonic_repulsion("A", "A", 1., .2) sim = rds.simulation(kernel=kernel, reaction_handler=reaction_handler) sim.show_progress = False sim.output_file = traj_fname sim.add_particles("A", np.random.random((100, 3))) sim.observe.particle_positions(1) sim.observe.particles(1) sim.observe.rdf(1, bin_borders=np.arange(-5, 5, 1.), types_count_from=["A"], types_count_to=["A"], particle_to_density=1. / rds.box_volume) sim.observe.number_of_particles(1, types=["B", "A"]) reactions = [] sim.observe.reactions(1, callback=lambda x: reactions.append(x)) sim.observe.reaction_counts(1) sim.observe.forces(1) sim.observe.energy(1) pressures = [] pressures_inactive = [] class PressureCallback(object): def __init__(self): self.active = True def __call__(self, p): if self.active: pressures.append(p) else: pressures_inactive.append(p) pressure_callback = PressureCallback() sim.observe.pressure(1, callback=pressure_callback) sim.run(50, 1e-3, False) pressure_callback.active = False sim.output_file = traj_fname2 sim.run(50, 1e-3, False) for fname in [traj_fname, traj_fname2]: traj = readdy.Trajectory(fname) np.testing.assert_almost_equal(traj.kbt, rds.kbt.magnitude) np.testing.assert_equal(traj.periodic_boundary_conditions, rds.periodic_boundary_conditions) np.testing.assert_almost_equal(traj.box_size, rds.box_size.magnitude) np.testing.assert_almost_equal(traj.box_volume, rds.box_volume.magnitude) time, positions = traj.read_observable_particle_positions() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(positions), 51) time, pressure = traj.read_observable_pressure() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(pressure), 51) np.testing.assert_equal(len(pressures), 51) np.testing.assert_equal(len(pressures_inactive), 51) if fname == traj_fname: np.testing.assert_array_almost_equal(pressure, np.array(pressures)) else: np.testing.assert_array_almost_equal(pressure, np.array(pressures_inactive)) time, types, ids, positions = traj.read_observable_particles() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(types), 51) np.testing.assert_equal(len(ids), 51) np.testing.assert_equal(len(positions), 51) time, bin_centers, rdf = traj.read_observable_rdf() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(bin_centers), len(np.arange(-5, 5, 1.)) - 1) np.testing.assert_equal(rdf.shape, (51, len(np.arange(-5, 5, 1)) - 1)) time, counts = traj.read_observable_number_of_particles() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(counts), 51) time, records = traj.read_observable_reactions() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(records), 51) time, forces = traj.read_observable_forces() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(forces), 51) time, energy = traj.read_observable_energy() np.testing.assert_equal(len(time), 51) np.testing.assert_equal(len(energy), 51) time, counts = traj.read_observable_reaction_counts() np.testing.assert_equal(len(time), 51) counts_reactions = counts["reactions"] np.testing.assert_equal(len(counts_reactions.keys()), 3) for t, rr, counts_1, counts_2, counts_3 in zip(time, records, counts_reactions["myconversion"], counts_reactions["myfusion"], counts_reactions["myfission"]): convrecords = [r for r in rr if r.reaction_label == "myconversion"] fusrecords = [r for r in rr if r.reaction_label == "myfusion"] fissrecords = [r for r in rr if r.reaction_label == "myfission"] np.testing.assert_equal(counts_1, len(convrecords), err_msg="conversion count mismatch: t={}, counts={}, nrecords={}, kernel={}" .format(t, counts_1, len(convrecords), kernel)) np.testing.assert_equal(counts_2, len(fusrecords), err_msg="fusion count mismatch: t={}, counts={}, nrecords={}, kernel={}" .format(t, counts_2, len(fusrecords), kernel)) np.testing.assert_equal(counts_3, len(fissrecords), err_msg="fission count mismatch: t={}, counts={}, nrecords={}, kernel={}" .format(t, counts_3, len(fissrecords), kernel)) for curr_positions, curr_types, curr_ids, curr_forces in zip(positions, types, ids, forces): np.testing.assert_equal(len(curr_positions), len(curr_types)) np.testing.assert_equal(len(curr_types), len(curr_ids)) np.testing.assert_equal(len(curr_ids), len(curr_forces))
# equilibration sim = system.simulation(kernel="SingleCPU") sim.add_particles("A", positions) sim.observe.particle_positions(200, callback=pos_callback, save=None) sim.observe.energy(50, callback=lambda x: print(x), save=None) sim.record_trajectory(stride=1) sim.output_file = "lj_eq.h5" if os.path.exists(sim.output_file): os.remove(sim.output_file) sim.run(n_steps=1000, timestep=2e-4) traj = readdy.Trajectory(sim.output_file) traj.convert_to_xyz(particle_radii={"A": 0.5}) # measure sim = system.simulation(kernel="SingleCPU") sim.add_particles("A", positions) sim.observe.energy(50) sim.observe.forces(50) sim.observe.particle_positions(50) sim.observe.rdf(50, bin_borders=np.linspace(0.5, 4., 40), types_count_from="A", types_count_to="A", particle_to_density=density) sim.output_file = "lj_measure.h5"
def _run_topology_observable_integration_test_for(self, kernel): traj_fname = os.path.join(self.tempdir, "traj_top_obs_integration_{}.h5".format(kernel)) system = readdy.ReactionDiffusionSystem(box_size=[150, 150, 150]) system.periodic_boundary_conditions = False, False, False system.add_species("Ligand", diffusion_constant=3.) system.add_species("Decay", diffusion_constant=1.) system.add_topology_species("T", diffusion_constant=1.) system.add_topology_species("unstable T", diffusion_constant=1.) system.reactions.add("decay: Decay ->", 1e20) system.potentials.add_box("Ligand", 10., [-70, -70, -70], [130, 130, 130]) system.potentials.add_box("Decay", 10., [-70, -70, -70], [130, 130, 130]) system.potentials.add_box("T", 10., [-70, -70, -70], [130, 130, 130]) system.potentials.add_box("unstable T", 10., [-70, -70, -70], [130, 130, 130]) system.potentials.add_harmonic_repulsion("Decay", "unstable T", force_constant=20., interaction_distance=2.) system.topologies.configure_harmonic_bond("T", "T", force_constant=20., length=2.) system.topologies.configure_harmonic_bond("unstable T", "unstable T", force_constant=20., length=2.) system.topologies.add_type("stable") system.topologies.add_type("intermediate") system.topologies.add_type("unstable") system.topologies.add_spatial_reaction( "encounter: stable(T) + (Ligand) -> intermediate(T) + (Ligand)", rate=10.0, radius=2.0 ) def intermediate_rate_function(_): return 1e3 def intermediate_reaction_function(topology): recipe = readdy.StructuralReactionRecipe(topology) for v in topology.graph.vertices: recipe.change_particle_type(v, "unstable T") recipe.change_topology_type("unstable") return recipe system.topologies.add_structural_reaction(name="intermediate_reaction", topology_type="intermediate", reaction_function=intermediate_reaction_function, rate_function=intermediate_rate_function) def unstable_rate_function(_): return 1000. def unstable_reaction_function(topology): recipe = readdy.StructuralReactionRecipe(topology) index = np.random.randint(0, len(topology.particles)) recipe.separate_vertex(index) recipe.change_particle_type(index, "Decay") recipe.change_particle_position(index, [0, 0, 0]) return recipe system.topologies.add_structural_reaction("unstable_reaction", topology_type="unstable", reaction_function=unstable_reaction_function, rate_function=unstable_rate_function) simulation = system.simulation(kernel=kernel) 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 = simulation.add_topology(topology_type="stable", 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) simulation.add_particles("Ligand", -6 * np.ones((5, 3))) simulation.output_file = traj_fname simulation.record_trajectory() simulation.observe.topologies(1) simulation.show_progress = False simulation.run(n_steps=100, timestep=1e-2, show_summary=False) t = readdy.Trajectory(simulation.output_file) entries = t.read() time, topology_records = t.read_observable_topologies() assert len(time) == len(entries) assert len(topology_records) == len(entries) time1, t_rec1 = t.read_observable_topologies(start=0, stop=len(time) // 3) assert(len(time1) == len(time) // 3) time2, t_rec2 = t.read_observable_topologies(start=len(time) // 3, stop=int(2 * len(time) // 3)) assert(len(time2) == int(2 * len(time) // 3) - len(time) // 3) time3, t_rec3 = t.read_observable_topologies(start=int(2 * len(time) // 3), stop=len(time)) assert(len(time3) == len(time) - int(2 * len(time) // 3)) assert len(time) == len(time1) + len(time2) + len(time3) assert len(topology_records) == len(t_rec1) + len(t_rec2) + len(t_rec3) np.testing.assert_array_almost_equal(time, np.concatenate((time1, time2, time3))) for ix, recs in enumerate(t_rec1 + t_rec2 + t_rec3): assert len(recs) == len(topology_records[ix]) for iy, rec in enumerate(recs): assert rec == topology_records[ix][iy] for frame in entries: for entry in frame: if entry.type == 'Decay': np.testing.assert_array_almost_equal(entry.position, np.array([0, 0, 0])) for timestep, tops in zip(time, topology_records): current_edges = [] for top in tops: for e1, e2 in top.edges: ix1 = top.particles[e1] ix2 = top.particles[e2] current_edges.append((ix1, ix2)) p1 = entries[timestep][ix1] p2 = entries[timestep][ix2] assert p1.type == 'T' or p1.type == 'unstable T', \ "expected topology type but got {} -- {}".format(p1, p2) assert p2.type == 'T' or p2.type == 'unstable T', \ "expected topology type but got {} -- {}".format(p1, p2)
def calc_accept_dimer(trajfile,potdict,r_react,weight_L,nL,nLtag): print("Processing trajectory: {}".format(trajfile)) # Load trajectory try: traj = readdy.Trajectory(trajfile) except (OSError, ValueError) as e: print("OSError while loading trajectory for index {}".format(config_index)) return None timestep, types, ids, positions = traj.read_observable_particles() # Define distance function for periodic box dist = lambda x1,x2,boxsize: util.dist(x1,x2,boxsize) lj_LL = potdict['lj_LL'] lj_SL = potdict['lj_SL'] #lj_SLL = potdict['lj_SLL'] lj_CL = potdict['lj_CL'] lj_CC = potdict['lj_CC'] lj_CS = potdict['lj_CS'] #lj_SLC = potdict['lj_SLC'] tstart = 0 tstop = timestep.shape[0] sample_freq = 1 time_indices = range(tstart,tstop,sample_freq) react_prob = np.zeros((len(time_indices),)) # Choose which ligands to label as ligands vs crowders, if applicable ids0 = np.array([traj.species_name(j) for j in types[0]]) if nL!=nLtag: # NEEDS FIXING indsAllL = np.char.equal(ids0,"L") indsR = np.char.equal(ids0,"R") posAllL = positions[0][indsAllL] posR = positions[0][indsR] dLR = util.dist(posAllL,posR,traj.box_size) closestLigand = np.argmin(dLR) choose_prob = np.ones(indsAllL.shape) choose_prob[indsR] = 0 choose_prob[closestLigand] = 0 if nLtag != 1: indsLbulk = np.random.choice(indsAllL.shape[0],size=nL-1,replace=False,p=choose_prob/np.sum(choose_prob)) indsL = np.full(indsAllL.shape,False) if nLtag != 1: indsL[indsLbulk] = True indsL[closestLigand] = True indsC = np.full(indsAllL.shape,True) indsC[indsL] = False indsC[indsR] = False else: indsL = np.char.equal(ids0,"L") indsC = np.char.equal(ids0,"C") indsS = np.char.equal(ids0,"S") posLi = positions[0][indsL] posCi = positions[0][indsC] posSi = positions[0][indsS] # Loop over timepoints with step size sample_freq for ti,i in enumerate(time_indices): posLi = positions[i][indsL] posSi = positions[i][indsS] posCi = positions[i][indsC] # Get distances from receptor to all ligands along trajectory (w/ periodic boundaries) dLS = util.dist(posLi,posSi,traj.box_size) # Get distances from receptor to all crowders along trajectory (w/ periodic boundaries) dSC = util.dist(posCi,posSi,traj.box_size) # Calculate internal energy of receptor (in unbound state) Ereceptor = np.sum(lj_SL(dLS)) + np.sum(lj_CS(dSC)) # Calculate reaction propensity react_propensity = doi_reaction_model(dLS,r_react) react_candidates = np.nonzero(react_propensity)[0] # Test binding event accept = 0 p_no_react_i = 1. #for j in react_candidates: if len(react_candidates)>0: # Choose randomly from reaction candidates for test reaction j = random.choice(react_candidates) # Choose position for fussion reaction product accounting for periodic boundaries vecStoLi = util.wrapped_vector(posLi[j]-posSi,traj.box_size) rS_Li = np.linalg.norm(vecStoLi) dr = r_react - rS_Li drS = -weight_L * dr * vecStoLi/rS_Li drL = (1.-weight_L) * dr * vecStoLi/rS_Li posSb = util.wrapped_vector(posSi + drS,traj.box_size) posLb = util.wrapped_vector(posLi[j] + drL,traj.box_size) # Calculate needed intermolecular distances dLLj = util.dist(posLi[j],posLi[np.arange(len(posLi))!=j],traj.box_size) # Ligand_j to other ligands dcrowderLj = util.dist(posLi[j],posCi,traj.box_size) # Ligand_j to crowders dSbL = util.dist(posSb,posLi[np.arange(len(posLi))!=j],traj.box_size) # Proposed bound receptor to other ligands dSbCrowder = util.dist(posSb,posCi,traj.box_size) # Proposed bound receptor to crowders dLbL = util.dist(posLb,posLi[np.arange(len(posLi))!=j],traj.box_size) # Proposed bound ligand to other ligands dLbCrowder = util.dist(posLb,posCi,traj.box_size) # Proposed bound ligand to crowders ## Calculate energy of ligand_j before binding test move # Interaction energy between ligand_j and other ligands EligandjL = lj_LL(dLLj) # Interaction energy between ligand_j and crowders Eligandjcrowder = lj_CL(dcrowderLj) # Total interaction energy of ligand_j excluding interaction w/ receptor Eligandj = np.sum(EligandjL) + np.sum(Eligandjcrowder) # Interaction energy between ligand_j and receptor EligandjS = lj_SL(dLS[j]) ## Calculate energy of test ligand after binding # Interaction energy of test particle with other ligands ELbL = lj_LL(dLbL) # Interaction energy of test particle with crowders ELbCrowder = lj_CL(dLbCrowder) # Total interaction energy of test ligand particle ELb = np.sum(ELbL) + np.sum(ELbCrowder) ## Calculate energy of test receptor after binding # Interaction energy of test particle with other ligands ESbL = lj_SL(dSbL) # Interaction energy of test particle with crowders ESbCrowder = lj_CS(dSbCrowder) # Total interaction energy of test receptor particle ESb = np.sum(ESbL) + np.sum(ESbCrowder) # Interaction energy between test ligand and test receptor (in the complex) ESbLb = lj_SL(r_react) # Total energy for the complex EComplex = ESb + ELb + ESbLb # Energy change for fussion reaction dE = EComplex - (Eligandj + Ereceptor) # Add back energy of fusion educt internal energy since accounted for by proposal density dE = dE + EligandjS if dE>0: p_no_react_i *= 1.-np.exp(-dE) else: p_no_react_i *= 0 react_prob[ti] = 1. - p_no_react_i return react_prob
def _run_topology_observable_test_for(self, kernel): traj_fname = os.path.join(self.tempdir, "traj_top_obs_{}.h5".format(kernel)) system = readdy.ReactionDiffusionSystem(box_size=[300, 300, 300]) system.periodic_boundary_conditions = False, False, False system.add_species("Decay", diffusion_constant=.01) system.add_topology_species("unstable T", diffusion_constant=.01) system.reactions.add("decay: Decay ->", .1) system.potentials.add_box("Decay", 100., [-70, -70, -70], [130, 130, 130]) system.potentials.add_box("unstable T", 100., [-70, -70, -70], [130, 130, 130]) system.potentials.add_harmonic_repulsion("Decay", "unstable T", force_constant=20., interaction_distance=2.) system.topologies.configure_harmonic_bond("unstable T", "unstable T", force_constant=20., length=2.) system.topologies.add_type("unstable") def unstable_rate_function(_): return .1 def unstable_reaction_function(topology): recipe = readdy.StructuralReactionRecipe(topology) index = np.random.randint(0, len(topology.particles)) recipe.separate_vertex(index) recipe.change_particle_type(index, "Decay") return recipe system.topologies.add_structural_reaction(name="unstable_reaction", topology_type="unstable", reaction_function=unstable_reaction_function, rate_function=unstable_rate_function) simulation = system.simulation(kernel=kernel) 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 = simulation.add_topology(topology_type="unstable", particle_types="unstable T", positions=np.array(positions)) graph = topology.get_graph() for i in range(len(graph.get_vertices()) - 1): graph.add_edge(i, i + 1) simulation.output_file = traj_fname topology_records = [] simulation.record_trajectory() simulation.observe.topologies(1, callback=lambda x: topology_records.append(x)) simulation.show_progress = False n_steps = 100 simulation.run(n_steps=n_steps, timestep=1e-1, show_summary=False) traj = readdy.Trajectory(simulation.output_file) time, tops = traj.read_observable_topologies() entries = traj.read() np.testing.assert_equal(len(time), n_steps + 1) for ix, records in enumerate(topology_records): np.testing.assert_equal(len(records), len(tops[ix])) for record, recordedRecord in zip(records, tops[ix]): np.testing.assert_equal(record.particles, recordedRecord.particles, err_msg="observable callback: {}, file: {}".format(record.particles, recordedRecord.particles)) np.testing.assert_equal(record.edges, recordedRecord.edges) for edge in record.edges: p1 = entries[ix][record.particles[edge[0]]] p2 = entries[ix][record.particles[edge[1]]] assert p1.type == 'unstable T', "expected topology type but got {}".format(p1) assert p2.type == 'unstable T', "expected topology type but got {}".format(p2)
simulation.add_particles("C", positions=positions_C) simulation.add_particles("L", positions=positions_L) simulation.add_particles("S", positions=positions_S) #### Define observables for simulation #### simulation.record_trajectory(stride=1000) simulation.observe.number_of_particles(stride=1, types=["L", "S", "C"]) simulation.observe.particles(stride=100, callback=None) #simulation.observe.reaction_counts(stride=100) #simulation.observe.reactions(stride=100) if os.path.exists(simulation.output_file): os.remove(simulation.output_file) #------------------------------------------------------------------------------------------------------- #### Run simulation #### #------------------------------------------------------------------------------------------------------- simulation.run(n_steps=n_steps, timestep=1e-4) #### Save trajectory #### trajectory = readdy.Trajectory(outfile) trajectory.convert_to_xyz(particle_radii={ 'C': r_C, 'L': r_L, 'S': r_S, 'SA': r_SL }) #trajectory.convert_to_xyz(particle_radii={'L': 1.,'S': 1.,'SL': 1.})
import numpy as np import matplotlib.pyplot as plt import readdy #---------------------------------------------------------------------------------------- if __name__=="__main__": basedir = './run_bulk_nL1_nC0_kOn10_kOff1/trajectory_20/' traj_file = basedir + 'LR_out_bulk.h5' traj = readdy.Trajectory(traj_file) periodic_directions = [0,1,2] timestep = 1e-4 time_sim, counts = traj.read_observable_number_of_particles() time = time_sim * timestep counts = counts.astype(np.int8) # copy number of inactive sensor at each timestep fig, ax = plt.subplots(1,1,figsize=(8,3)) #ax.plot(time[20000:22000]-time[20000],1.-counts[20000:22000,1],label="S") ax.plot(time,1.-counts[:,1],label="SL complex") ax.set_xlabel("Time",fontsize=18) ax.set_ylabel("Receptor Occupacy",fontsize=18) fig.tight_layout()
def _test_kernel(self, kernel): system = readdy.ReactionDiffusionSystem(box_size=[20, 20, 20]) system.topologies.add_type("T1") system.topologies.add_type("T2") system.add_species("A") system.add_topology_species("B") system.topologies.configure_harmonic_bond("B", "B", 1., .1) system.add_topology_species("C") system.topologies.configure_harmonic_bond("C", "C", 1., .1) system.topologies.add_spatial_reaction( "attach: T1(B) + (A) -> T1(B--B)", rate=1e-1, radius=.5) def flip1(topology): recipe = readdy.StructuralReactionRecipe(topology) for v in topology.graph.vertices: recipe.change_particle_type(v, "C") recipe.change_topology_type("T2") return recipe def flip2(topology): recipe = readdy.StructuralReactionRecipe(topology) for v in topology.graph.vertices: recipe.change_particle_type(v, "B") recipe.change_topology_type("T1") return recipe system.topologies.add_structural_reaction("flip_types_1", "T1", flip1, lambda x: 5e-2) system.topologies.add_structural_reaction("flip_types_2", "T2", flip2, lambda x: 5e-2) sim = system.simulation(kernel=kernel) sim.output_file = os.path.join(self.dir, "out_{}.h5".format(kernel)) collected_counts = [] def callback(results): nonlocal collected_counts collected_counts.append(results) sim.observe.reaction_counts(1, callback=callback) sim.observe.number_of_particles(1, types=["A", "B", "C"]) sim.add_particles("A", np.random.normal(scale=1, size=(1000, 3))) for _ in range(10): sim.add_topology("T1", "B", np.random.normal(size=(1, 3))) sim.run(1000, timestep=1, show_summary=False) traj = readdy.Trajectory(sim.output_file) times, n_particles = traj.read_observable_number_of_particles() times2, counts = traj.read_observable_reaction_counts() np.testing.assert_array_equal(times, times2) assert not counts["reactions"] spatials = counts["spatial_topology_reactions"] n_spatial = 0 cA_prev = None for t, (cA, cB, cC), cc in zip(times, n_particles, collected_counts): assert cA_prev is None or cA <= cA_prev np.testing.assert_equal(cA + cB + cC, 1010) cc_normal = cc[0] assert not cc_normal cc_spatial = cc[1] cc_structural = cc[2] n_spatial += spatials["attach"][t] assert cA == 1000 - n_spatial, f"Got {cA} A particles, expected {1000 - n_spatial}, at time t {t}" for sp in cc_spatial.keys(): recorded = spatials[sp][t] assert cc_spatial[ sp] == recorded, f"Got {cc_spatial[sp]} != {recorded} (t={t})" for st in cc_structural.keys(): recorded = counts["structural_topology_reactions"][st][t] assert cc_structural[ st] == recorded, f"Got {cc_structural[st]} != {recorded} (t={t})" cA_prev = cA