Ejemplo n.º 1
0
def test_langevin_simulation_safety():
    # Test whether a brownian (overdamped langevin) simulation indeed will
    # refuse to overwrite existing data unless overwrite is set to true

    # Generate simulation
    sim = Simulation(model,
                     initial_coordinates,
                     length=sim_length,
                     save_interval=save_interval,
                     friction=friction,
                     masses=masses)
    # Check that no simulation is stored
    assert not sim._simulated

    traj = sim.simulate()
    assert sim.kinetic_energies is not None
    # Check that a simulation is stored now
    assert sim._simulated

    # Check that it can't be overwritten by default
    np.testing.assert_raises(RuntimeError, sim.simulate)

    # Check that it can be overwritten with overwrite=True; i.e. that
    # this command raises no error
    traj2 = sim.simulate(overwrite=True)
    assert sim._simulated
Ejemplo n.º 2
0
def test_harmonic_potential_zero_friction():
    # Test that zero friction returns a traj of zeroes and kinetic energy
    # of zeroes. Zero friction means vscale will be zero, which means
    # that velocities will only ever be updated by zero. We therefore
    # expect zero friction to leave our velocities completely unchanged.
    # Particularly, in the case where the starting velocities are zero,
    # we expect them to remain zero, and thus the positions do not
    # change either.

    # set up model, internal coords, and sim using class attirbutes
    model = HarmonicPotential(k=1,
                              T=300,
                              n_particles=1000,
                              dt=0.001,
                              friction=0,
                              n_sims=1,
                              sim_length=500)

    initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

    my_sim = Simulation(model,
                        initial_coordinates,
                        embeddings=None,
                        beta=model.beta,
                        length=model.sim_length,
                        friction=model.friction,
                        dt=model.dt,
                        masses=model.masses,
                        save_interval=model.save_interval)

    traj = my_sim.simulate()

    np.testing.assert_array_equal(traj, np.zeros(traj.shape))
    np.testing.assert_array_equal(my_sim.kinetic_energies,
                                  np.zeros(my_sim.kinetic_energies.shape))
Ejemplo n.º 3
0
def test_cgschnet_simulation_shapes():
    # Test simulation with embeddings and make sure the shapes of
    # the simulated coordinates, forces, and potential are correct
    schnet_feature, embedding_property, feature_size = _get_random_schnet_feature(
                                                           calculate_geometry=True)
    layer_list = [schnet_feature]
    feature_combiner = FeatureCombiner(layer_list)

    # Next, we make aa CGnet with a random hidden architecture
    arch = _get_random_architecture(feature_size)
    model = CGnet(arch, ForceLoss(), feature=feature_combiner)
    model.eval()

    sim_length = np.random.randint(10, 20)
    sim = Simulation(model, coords_torch, embedding_property, length=sim_length,
                     save_interval=1, beta=1., save_forces=True,
                     save_potential=True)

    traj = sim.simulate()

    np.testing.assert_array_equal(sim.simulated_coords.shape,
                                  [n_frames, sim_length, n_beads, 3])
    np.testing.assert_array_equal(sim.simulated_forces.shape,
                                  [n_frames, sim_length, n_beads, 3])
    np.testing.assert_array_equal(sim.simulated_potential.shape,
                                  [n_frames, sim_length, 1])
Ejemplo n.º 4
0
def test_harmonic_potential_several_temperatures():
    # Tests several harmonic potential simulations for correct temperature.
    # The standard deviation in measured temperature across the simulation
    # is expected to increase as the temperature increases. Heursitically I
    # observed it doesn't tend to exceed a standard deviation of 30 for
    # simulation lengths of 500 and max temperatures of 900.

    temp_parameter = [100, 300, 500, 700, 900]
    mean_temp_measured = []
    std_temp_measured = []

    for temp in temp_parameter:

        # set up model, internal coords, and sim using class attirbutes
        model = HarmonicPotential(k=1,
                                  T=temp,
                                  n_particles=1000,
                                  dt=0.001,
                                  friction=100,
                                  n_sims=1,
                                  sim_length=500)

        initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

        my_sim = Simulation(model,
                            initial_coordinates,
                            embeddings=None,
                            beta=model.beta,
                            length=model.sim_length,
                            friction=model.friction,
                            dt=model.dt,
                            masses=model.masses,
                            save_interval=model.save_interval)

        traj = my_sim.simulate()
        n_dofs = 3 * model.n_particles
        sim_temps = my_sim.kinetic_energies * 2 / n_dofs / model.kB
        sim_temps = sim_temps[:, 20:]

        # store mean
        sim_temp_mean = np.mean(sim_temps, axis=1)[0]  # only one simulation
        mean_temp_measured.append(sim_temp_mean)

        # store stdev
        sim_temp_std = np.std(sim_temps, axis=1)[0]  # only one simulation
        std_temp_measured.append(sim_temp_std)

    # Test that the means are all about the right temperature
    np.testing.assert_allclose(temp_parameter, mean_temp_measured, rtol=1)

    # Test that the stdevs are all less than 25 (heuristic)
    np.testing.assert_array_less(std_temp_measured,
                                 np.repeat(30, len(temp_parameter)))

    # Test that the stdevs go up as the temperature goes up
    np.testing.assert_array_equal(std_temp_measured, sorted(std_temp_measured))
Ejemplo n.º 5
0
def test_log_file_basics():
    # Tests whether the log file exists, is named correctly, and has the
    # correct number of lines

    n_sims = np.random.randint(1, high=5)
    sim_length = np.random.choice([24, 36])
    log_interval = np.random.choice([6, 12])
    save_interval = np.random.choice([2, 3])

    n_expected_logs = sim_length / log_interval

    model = HarmonicPotential(k=1,
                              T=300,
                              n_particles=10,
                              dt=0.001,
                              friction=None,
                              n_sims=n_sims,
                              sim_length=sim_length,
                              save_interval=save_interval)

    initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

    with tempfile.TemporaryDirectory() as tmp:
        my_sim = Simulation(model,
                            initial_coordinates,
                            embeddings=None,
                            beta=model.beta,
                            length=model.sim_length,
                            friction=model.friction,
                            dt=model.dt,
                            save_forces=False,
                            save_potential=False,
                            save_interval=model.save_interval,
                            log_interval=log_interval,
                            log_type='write',
                            filename=tmp + '/test')

        traj = my_sim.simulate()
        assert traj.shape[1] == sim_length / save_interval
        file_list = os.listdir(tmp)

        # Check that one file exists in the temp directory
        assert len(file_list) == 1

        # Check that it has the proper name
        assert file_list[0] == 'test_log.txt'

        # Gather its lines
        with open(tmp + '/' + file_list[0]) as f:
            line_list = f.readlines()

    # We expect the log file to contain the expected number of logs, plus two
    # extra lines: one at the start and one at the end.
    assert len(line_list) == n_expected_logs + 2
Ejemplo n.º 6
0
def test_harmonic_potential_shape_and_temperature():
    # Tests a single harmonic potential simulation for shape and temperature
    # - Tests shapes of trajectory and kinetic energies
    # - Tests that average temperature is about 300
    # - Tests that the standard deviation is less than 10; this is just
    #   heuristic based on trying out the data in a notebook when
    #   writing the test

    # set up model, internal coords, and sim using class attirbutes
    model = HarmonicPotential(k=1,
                              T=300,
                              n_particles=1000,
                              dt=0.001,
                              friction=100,
                              n_sims=1,
                              sim_length=500)

    initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

    my_sim = Simulation(model,
                        initial_coordinates,
                        embeddings=None,
                        beta=model.beta,
                        length=model.sim_length,
                        friction=model.friction,
                        dt=model.dt,
                        masses=model.masses,
                        save_interval=model.save_interval)

    traj = my_sim.simulate()

    # check shape of trajectory and kinetic energies
    assert traj.shape == (model.n_sims, model.sim_length, model.n_particles, 3)
    assert my_sim.kinetic_energies.shape == (1, model.sim_length)

    # Calculate temperatures, removing the first 20 time points (this is
    # about what it takes to get to a constant temperature)
    n_dofs = 3 * model.n_particles
    temperatures = my_sim.kinetic_energies * 2 / n_dofs / model.kB
    temperatures = temperatures[:, 20:]
    mean_temps = np.mean(temperatures, axis=1)

    # Test that the means are all about the right temperature
    np.testing.assert_allclose(np.mean(temperatures, axis=1),
                               np.repeat(model.T, model.n_sims),
                               rtol=1)

    # Test that the stdevs are all less than 25 (heuristic)
    np.testing.assert_array_less(np.std(temperatures, axis=1),
                                 np.repeat(10, model.n_sims))
Ejemplo n.º 7
0
def test_schnet_simulation_safety():
    # This test confirms that a simulation cannot be instantiated if
    # schnet features but no embeddings are provided
    with assert_raises(RuntimeError):
        Simulation(schnet_model,
                   initial_coordinates,
                   length=sim_length,
                   save_interval=save_interval)
Ejemplo n.º 8
0
def test_brownian_simulation_shape():
    # Test shape of Brownian (overdamped Langevin) simulation without
    # saving the forces or the potential

    # Generate simulation
    my_sim = Simulation(model,
                        initial_coordinates,
                        length=sim_length,
                        save_interval=save_interval)
    traj = my_sim.simulate()

    # Here, we verify that the trajectory shape corresponds with the
    # choices of simulation length and saving frequency above
    # We also verify that the potential and the forces are not saved
    assert traj.shape == (frames, sim_length // save_interval, beads, dims)
    assert my_sim.simulated_forces is None
    assert my_sim.simulated_potential is None
    assert my_sim.kinetic_energies is None
Ejemplo n.º 9
0
def test_brownian_simulation_seeding():
    # Test determinism of Brownian (overdamped langevin) simulation with
    # random seed. If the same seed is used for two separate simulations,
    # the results (trajectory, forces, potential) should be identical

    seed = np.random.randint(1000)  # Save random seed for simulations

    # Generate simulation number one
    sim1 = Simulation(model,
                      initial_coordinates,
                      length=sim_length,
                      save_interval=save_interval,
                      save_forces=True,
                      save_potential=True,
                      random_seed=seed)
    traj1 = sim1.simulate()

    # Generate simulation umber two
    sim2 = Simulation(model,
                      initial_coordinates,
                      length=sim_length,
                      save_interval=save_interval,
                      save_forces=True,
                      save_potential=True,
                      random_seed=seed)
    traj2 = sim2.simulate()

    # Verify that all components of each simulation are equal.
    np.testing.assert_array_equal(traj1, traj2)
    np.testing.assert_array_equal(sim1.simulated_forces, sim2.simulated_forces)
    np.testing.assert_array_equal(sim1.simulated_potential,
                                  sim2.simulated_potential)
    assert sim1.kinetic_energies is None
    assert sim2.kinetic_energies is None
Ejemplo n.º 10
0
def test_langevin_simulation_saved_potential_shape():
    # Test shape of langevin simulation with both forces and potential saved

    # Generate simulation
    my_sim = Simulation(model,
                        initial_coordinates,
                        length=sim_length,
                        save_interval=save_interval,
                        save_potential=True,
                        friction=friction,
                        masses=masses)
    traj = my_sim.simulate()

    # Here, we verify that the trajectory shape corresponds with the
    # choices of simulation length and saving frequency above
    # We also verify that the forces and the potential are saved
    assert traj.shape == (frames, sim_length // save_interval, beads, dims)
    assert my_sim.simulated_forces is None
    assert my_sim.simulated_potential.shape == (frames,
                                                sim_length // save_interval,
                                                beads, 1)
    assert my_sim.kinetic_energies.shape == (frames,
                                             sim_length // save_interval)
Ejemplo n.º 11
0
def test_langevin_simulation_seeding():
    # Test determinism of Langevin simulation with random seed. If the
    # same seed is used for two separate simulations, the results
    # (trajectory, forces, potential) should be identical

    seed = np.random.randint(1000)  # Save random seed for simulations

    # Generate simulation number one
    sim1 = Simulation(model,
                      initial_coordinates,
                      length=sim_length,
                      save_interval=save_interval,
                      save_forces=True,
                      save_potential=True,
                      random_seed=seed,
                      friction=friction,
                      masses=masses)
    traj1 = sim1.simulate()

    # Generate simulation umber two
    sim2 = Simulation(model,
                      initial_coordinates,
                      length=sim_length,
                      save_interval=save_interval,
                      save_forces=True,
                      save_potential=True,
                      random_seed=seed,
                      friction=friction,
                      masses=masses)
    traj2 = sim2.simulate()

    # Verify that all components of each simulation are equal, and not
    # because they're None
    assert traj1 is not None
    assert traj2 is not None
    assert sim1.simulated_forces is not None
    assert sim2.simulated_forces is not None
    assert sim1.simulated_potential is not None
    assert sim2.simulated_potential is not None
    assert sim1.kinetic_energies is not None
    assert sim2.kinetic_energies is not None

    np.testing.assert_array_equal(traj1, traj2)
    np.testing.assert_array_equal(sim1.simulated_forces, sim2.simulated_forces)
    np.testing.assert_array_equal(sim1.simulated_potential,
                                  sim2.simulated_potential)
    np.testing.assert_array_equal(sim1.kinetic_energies, sim2.kinetic_energies)
Ejemplo n.º 12
0
def test_cgnet_simulation():
    # Tests a simulation from a CGnet built with the GeometryFeature
    # for the shapes of its coordinate, force, and potential outputs

    # First, we set up a bond harmonic prior and a GeometryFeature layer
    bonds_idx = geom_stats.return_indices('Bonds')
    bonds_interactions, _ = geom_stats.get_prior_statistics(features='Bonds',
                                                            as_list=True)
    harmonic_potential = HarmonicLayer(bonds_idx, bonds_interactions)
    feature_layer = GeometryFeature(feature_tuples='all_backbone',
                                    n_beads=beads)
    num_feats = feature_layer(coords).size()[1]

    # Next, we create a 4 layer hidden architecture with a random width
    # and with a scalar output
    rand = np.random.randint(1, 10)
    arch = (LinearLayer(num_feats, rand, bias=True, activation=nn.Tanh()) +
            LinearLayer(rand, rand, bias=True, activation=nn.Tanh()) +
            LinearLayer(rand, rand, bias=True, activation=nn.Tanh()) +
            LinearLayer(rand, rand, bias=True, activation=nn.Tanh()) +
            LinearLayer(rand, 1, bias=True, activation=None))

    # Next, we instance a CGnet model using the above objects
    # with force matching as a loss criterion
    model = CGnet(arch,
                  ForceLoss(),
                  feature=feature_layer,
                  priors=[harmonic_potential])
    model.eval()

    # Here, we produce mock target protein force data
    forces = torch.randn((frames, beads, 3), requires_grad=False)

    # Here, we create an optimizer for traning the model,
    # and we train it for one epoch
    optimizer = torch.optim.Adam(model.parameters(), lr=0.05, weight_decay=0)
    optimizer.zero_grad()
    energy, pred_forces = model.forward(coords)
    loss = model.criterion(pred_forces, forces)
    loss.backward()
    optimizer.step()

    # Here, we define random simulation frame lengths
    # as well as randomly choosing to save every 2 or 4 frames
    length = np.random.choice([2, 4]) * 2
    save = np.random.choice([2, 4])

    # Here we instance a simulation class and produce a CG trajectory
    my_sim = Simulation(model,
                        coords,
                        beta=geom_stats.beta,
                        length=length,
                        save_interval=save,
                        save_forces=True,
                        save_potential=True)

    traj = my_sim.simulate()

    # We test to see if the trajectory is the proper shape based on the above
    # choices for simulation length and frame saving
    assert traj.shape == (frames, length // save, beads, dims)
    assert my_sim.simulated_forces.shape == (frames, length // save, beads,
                                             dims)
    assert my_sim.simulated_potential.shape == (frames, length // save, 1)
Ejemplo n.º 13
0
def test_single_model_simulation_vs_multimodelsimulation():
    # Tests to make sure that Simulation and MultiModelSimulation return
    # the same simulation results (coordinates, forces, potential energy,
    # and kinetic energies) if a single model is used in both cases.

    # First, we generate a random integer seed
    seed = np.random.randint(0, 1e6)

    # Next, we set up a model
    save_interval = 1
    dt = 0.001 * np.random.randint(1, 11)
    friction = 10 * np.random.randint(1, 11)
    k = np.random.randint(1, 6)
    n_particles = np.random.randint(1, 101)
    n_sims = np.random.randint(1, 11)
    initial_coordinates = torch.randn((n_sims, n_particles, 3))
    masses = n_particles * [np.random.randint(low=1, high=5)]
    sim_length = np.random.randint(2, 11)

    model = HarmonicPotential(k=k,
                              T=300,
                              n_particles=n_particles,
                              dt=dt,
                              friction=friction,
                              n_sims=n_sims,
                              sim_length=sim_length,
                              save_interval=save_interval)

    # Next, we simulate both models. We wrap both of the simulations in
    # a temporary directory as to not generate permanent simulation files
    with tempfile.TemporaryDirectory() as tmp:
        sim = Simulation(model,
                         initial_coordinates,
                         embeddings=None,
                         length=sim_length,
                         save_interval=save_interval,
                         masses=masses,
                         dt=dt,
                         save_forces=True,
                         save_potential=True,
                         friction=friction,
                         random_seed=seed,
                         filename=tmp + '/test')
        multi_sim = MultiModelSimulation([model],
                                         initial_coordinates,
                                         embeddings=None,
                                         length=sim_length,
                                         save_interval=save_interval,
                                         masses=masses,
                                         dt=dt,
                                         save_forces=True,
                                         save_potential=True,
                                         friction=friction,
                                         random_seed=seed,
                                         filename=tmp + '/test_copy')

        trajectory = sim.simulate()
        trajectory_from_multi = multi_sim.simulate()

        # Here, we test the equality of the two simulation results

        assert trajectory.shape == trajectory_from_multi.shape
        assert sim.simulated_forces.shape == multi_sim.simulated_forces.shape
        assert sim.simulated_potential.shape == multi_sim.simulated_potential.shape
        assert sim.kinetic_energies.shape == multi_sim.kinetic_energies.shape

        np.testing.assert_array_equal(trajectory, trajectory_from_multi)
        np.testing.assert_array_equal(sim.simulated_potential,
                                      multi_sim.simulated_potential)
        np.testing.assert_array_equal(sim.simulated_forces,
                                      multi_sim.simulated_forces)
        np.testing.assert_array_equal(sim.kinetic_energies,
                                      multi_sim.kinetic_energies)
Ejemplo n.º 14
0
def test_saving_all_quantities():
    # Tests, using a temporary directory, the saving of coordinates,
    # forces, potential, and kinetic energies from a Langevin simulation
    # (i)   That the number of numpy files saved is correct
    # (ii)  That the saved numpy files have the proper shapes
    # (iii) That the contatenation of the saved numpy files are equal to the
    #        trajectory output from the simulation
    n_sims = np.random.randint(1, high=5)
    sim_length = np.random.choice([24, 36])
    npy_interval = np.random.choice([6, 12])
    save_interval = np.random.choice([2, 3])

    n_expected_files = sim_length / npy_interval

    model = HarmonicPotential(k=1,
                              T=300,
                              n_particles=10,
                              dt=0.001,
                              friction=10,
                              n_sims=n_sims,
                              sim_length=sim_length,
                              save_interval=save_interval)

    initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

    with tempfile.TemporaryDirectory() as tmp:
        my_sim = Simulation(model,
                            initial_coordinates,
                            embeddings=None,
                            beta=model.beta,
                            length=model.sim_length,
                            friction=model.friction,
                            dt=model.dt,
                            save_forces=True,
                            save_potential=True,
                            masses=model.masses,
                            save_interval=model.save_interval,
                            export_interval=npy_interval,
                            filename=tmp + '/test')

        traj = my_sim.simulate()
        assert traj.shape[1] == sim_length / save_interval
        file_list = os.listdir(tmp)

        assert len(
            file_list) == n_expected_files * 4  # coords, forces, pot, ke
        coords_file_list = sorted(
            [file for file in file_list if 'coords' in file])
        force_file_list = sorted(
            [file for file in file_list if 'forces' in file])
        potential_file_list = sorted(
            [file for file in file_list if 'potential' in file])
        ke_file_list = sorted(
            [file for file in file_list if 'kineticenergy' in file])
        file_list_list = [
            coords_file_list, force_file_list, potential_file_list,
            ke_file_list
        ]
        expected_chunk_length = npy_interval / save_interval

        # needed for (iii)
        running_coords = None
        running_forces = None
        running_potential = None
        running_ke = None
        running_list = [
            running_coords, running_forces, running_potential, running_ke
        ]

        obs_list = [
            my_sim.simulated_coords, my_sim.simulated_forces,
            my_sim.simulated_potential, my_sim.kinetic_energies
        ]

        for j, obs_file_list in enumerate(file_list_list):
            for i in range(len(obs_file_list)):
                temp_traj = np.load(tmp + '/' + obs_file_list[i])
                # Test (ii)
                if j < 3:
                    np.testing.assert_array_equal(
                        temp_traj.shape,
                        [n_sims, expected_chunk_length, model.n_particles, 3])
                else:
                    np.testing.assert_array_equal(
                        temp_traj.shape, [n_sims, expected_chunk_length])

                if running_list[j] is None:
                    running_list[j] = temp_traj
                else:
                    running_list[j] = np.concatenate(
                        [running_list[j], temp_traj], axis=1)

            # Test (iii)
            np.testing.assert_array_equal(obs_list[j], running_list[j])
Ejemplo n.º 15
0
def test_saving_numpy_coordinates():
    # Tests, using a temporary directory, the saving of *coordinates*
    # from a Brownian (overdamped Langevin) simulation
    # (i)   That the number of numpy files saved is correct
    # (ii)  That the saved numpy files have the proper shapes
    # (iii) That the contatenation of the saved numpy files are equal to the
    #        trajectory output from the simulation
    n_sims = np.random.randint(1, high=5)
    sim_length = np.random.choice([24, 36])
    npy_interval = np.random.choice([6, 12])
    save_interval = np.random.choice([2, 3])

    n_expected_files = sim_length / npy_interval

    model = HarmonicPotential(k=1,
                              T=300,
                              n_particles=10,
                              dt=0.001,
                              friction=None,
                              n_sims=n_sims,
                              sim_length=sim_length,
                              save_interval=save_interval)

    initial_coordinates = torch.zeros((model.n_sims, model.n_particles, 3))

    with tempfile.TemporaryDirectory() as tmp:
        my_sim = Simulation(model,
                            initial_coordinates,
                            embeddings=None,
                            beta=model.beta,
                            length=model.sim_length,
                            friction=model.friction,
                            dt=model.dt,
                            save_forces=False,
                            save_potential=False,
                            save_interval=model.save_interval,
                            export_interval=npy_interval,
                            filename=tmp + '/test')

        traj = my_sim.simulate()
        assert traj.shape[1] == sim_length / save_interval
        file_list = os.listdir(tmp)

        assert len(file_list) == n_expected_files

        expected_chunk_length = npy_interval / save_interval
        running_traj = None  # needed for (iii)
        for i in range(len(file_list)):
            temp_traj = np.load(tmp + '/' + file_list[i])
            # Test (ii)
            np.testing.assert_array_equal(
                temp_traj.shape,
                [n_sims, expected_chunk_length, model.n_particles, 3])

            if running_traj is None:
                running_traj = temp_traj
            else:
                running_traj = np.concatenate([running_traj, temp_traj],
                                              axis=1)

        # Test (iii)
        np.testing.assert_array_equal(traj, running_traj)