def make_mmvt_milestone_between_two_anchors(self, anchor1, anchor2, input_anchor1, input_anchor2, milestone_index): neighbor_index1 = anchor2.index neighbor_index2 = anchor1.index milestone1 = base.Milestone() milestone1.index = milestone_index milestone1.neighbor_anchor_index = neighbor_index1 milestone1.alias_index = len(anchor1.milestones) + 1 milestone1.cv_index = self.index if input_anchor1.upper_milestone_radius is None: value = 0.5 * (input_anchor1.radius + input_anchor2.radius) else: value = input_anchor2.upper_milestone_radius milestone2 = base.Milestone() milestone2.index = milestone_index milestone2.neighbor_anchor_index = neighbor_index2 milestone2.alias_index = len(anchor2.milestones) + 1 milestone2.cv_index = self.index if input_anchor2.lower_milestone_radius is None: value = 0.5 * (input_anchor1.radius + input_anchor2.radius) else: value = input_anchor2.lower_milestone_radius # assign k milestone1.variables = {"k": 1.0, "radius": value} milestone2.variables = {"k": -1.0, "radius": value} for milestone in anchor1.milestones: if milestone.neighbor_anchor_index == neighbor_index1: # Then anchor1 already has this milestone added to it return milestone_index anchor1.milestones.append(milestone1) anchor2.milestones.append(milestone2) milestone_index += 1 return milestone_index
def make_elber_milestoning_objects_external( external_cv_input, milestone_alias, milestone_index, input_anchor_index, anchor_index, input_anchors, umbrella_force_constant): """ Make a set of 1-dimensional external Milestone objects to be put into an Anchor, and eventually, the Model. """ milestones = [] num_input_anchors = len(input_anchors) if input_anchor_index > 0: neighbor_index = anchor_index - 1 neighbor_index_input = input_anchor_index - 1 milestone1 = base.Milestone() milestone1.index = milestone_index - 1 milestone1.neighbor_anchor_index = neighbor_index milestone1.alias_index = 1 milestone1.is_source_milestone = False milestone1.cv_index = external_cv_input.index if input_anchors[input_anchor_index].lower_milestone_value is None: value = 0.5 * (input_anchors[input_anchor_index].value \ + input_anchors[neighbor_index_input].value) else: value = input_anchors[input_anchor_index].lower_milestone_value milestone1.variables = {"k": umbrella_force_constant, "value": value} milestones.append(milestone1) milestone2 = base.Milestone() milestone2.index = milestone_index milestone2.neighbor_anchor_index = milestone_index #milestone2.alias_index = milestone_alias milestone2.alias_index = 2 milestone2.is_source_milestone = True milestone2.cv_index = external_cv_input.index value = input_anchors[input_anchor_index].value milestone2.variables = {"k": umbrella_force_constant, "value": value} milestones.append(milestone2) if input_anchor_index < num_input_anchors-1: neighbor_index = anchor_index + 1 neighbor_index_input = input_anchor_index + 1 milestone3 = base.Milestone() milestone3.index = milestone_index + 1 milestone3.neighbor_anchor_index = neighbor_index milestone3.alias_index = 3 milestone3.is_source_milestone = False milestone3.cv_index = external_cv_input.index if input_anchors[input_anchor_index].upper_milestone_value is None: value = 0.5 * (input_anchors[input_anchor_index].value \ + input_anchors[neighbor_index_input].value) else: value = input_anchors[input_anchor_index].upper_milestone_value milestone3.variables = {"k": umbrella_force_constant, "value": value} milestones.append(milestone3) return milestones, milestone_alias, milestone_index+1
def make_elber_milestoning_objects_spherical( spherical_cv_input, milestone_alias, milestone_index, input_anchor_index, anchor_index, input_anchors, umbrella_force_constant): """ Make a set of 1-dimensional spherical Milestone objects to be put into an Anchor, and eventually, the Model. Each anchor needs 3 milestones. """ milestones = [] num_anchors = len(input_anchors) if input_anchor_index > 0: neighbor_index = anchor_index - 1 neighbor_index_input = input_anchor_index - 1 milestone1 = base.Milestone() milestone1.index = milestone_index-1 milestone1.neighbor_anchor_index = neighbor_index #milestone1.alias_index = milestone_alias milestone1.alias_index = 1 milestone1.is_source_milestone = False milestone1.cv_index = spherical_cv_input.index radius = input_anchors[neighbor_index_input].radius milestone1.variables = {"k": umbrella_force_constant, "radius": radius} #milestone_alias += 1 #milestone_index += 1 milestones.append(milestone1) milestone2 = base.Milestone() milestone2.index = milestone_index milestone2.neighbor_anchor_index = milestone_index #milestone2.alias_index = milestone_alias milestone2.alias_index = 2 milestone2.is_source_milestone = True milestone2.cv_index = spherical_cv_input.index radius = input_anchors[input_anchor_index].radius milestone2.variables = {"k": umbrella_force_constant, "radius": radius} milestones.append(milestone2) if input_anchor_index < num_anchors-1: neighbor_index = anchor_index + 1 neighbor_index_input = input_anchor_index + 1 milestone3 = base.Milestone() milestone3.index = milestone_index+1 milestone3.neighbor_anchor_index = neighbor_index #milestone3.alias_index = milestone_alias+1 milestone3.alias_index = 3 milestone3.is_source_milestone = False milestone3.cv_index = spherical_cv_input.index radius = input_anchors[neighbor_index_input].radius milestone3.variables = {"k": umbrella_force_constant, "radius": radius} milestones.append(milestone3) return milestones, milestone_alias, milestone_index+1
def make_mmvt_milestoning_objects_spherical( spherical_cv_input, milestone_alias, milestone_index, index, input_anchors): """ Make a set of 1-dimensional spherical Milestone objects to be put into an Anchor, and eventually, the Model. """ milestones = [] num_anchors = len(input_anchors) if index > 0: neighbor_index = index - 1 milestone1 = base.Milestone() milestone1.index = milestone_index milestone1.neighbor_anchor_index = neighbor_index milestone1.alias_index = milestone_alias milestone1.cv_index = spherical_cv_input.index if input_anchors[index].lower_milestone_radius is None: radius = 0.5 * (input_anchors[index].radius \ + input_anchors[neighbor_index].radius) else: radius = input_anchors[index].lower_milestone_radius milestone1.variables = {"k": -1.0, "radius": radius} milestone_alias += 1 milestone_index += 1 milestones.append(milestone1) if index < num_anchors-1: neighbor_index = index + 1 milestone2 = base.Milestone() milestone2.index = milestone_index milestone2.neighbor_anchor_index = neighbor_index milestone2.alias_index = milestone_alias milestone2.cv_index = spherical_cv_input.index if input_anchors[index].upper_milestone_radius is None: radius = 0.5 * (input_anchors[index].radius \ + input_anchors[neighbor_index].radius) else: radius = input_anchors[index].upper_milestone_radius milestone2.variables = {"k": 1.0, "radius": radius} milestones.append(milestone2) return milestones, milestone_alias, milestone_index
def make_simple_model(): n_anchors = 3 n_milestones = 3 # generate data to feed directly into MMVT_data_sample() model = base.Model() model.calculation_type = "elber" model.num_milestones = n_milestones model.num_anchors = n_anchors anchor0 = elber_base.Elber_toy_anchor() anchor0.index = 0 anchor0.endstate = True milestone_0_0 = base.Milestone() milestone_0_0.index = 0 milestone_0_0.neighbor_anchor_index = 0 milestone_0_0.alias_index = 2 milestone_0_1 = base.Milestone() milestone_0_1.index = 1 milestone_0_1.neighbor_anchor_index = 1 milestone_0_1.alias_index = 3 anchor0.milestones = [milestone_0_0, milestone_0_1] anchor1 = elber_base.Elber_toy_anchor() anchor1.index = 1 milestone_1_0 = base.Milestone() milestone_1_0.index = 0 milestone_1_0.neighbor_anchor_index = 0 milestone_1_0.alias_index = 1 milestone_1_1 = base.Milestone() milestone_1_1.index = 1 milestone_1_1.neighbor_anchor_index = 1 milestone_1_1.alias_index = 2 milestone_1_2 = base.Milestone() milestone_1_2.index = 2 milestone_1_2.neighbor_anchor_index = 2 milestone_1_2.alias_index = 3 anchor1.milestones = [milestone_1_0, milestone_1_1, milestone_1_2] anchor2 = elber_base.Elber_toy_anchor() anchor2.index = 2 milestone_2_0 = base.Milestone() milestone_2_0.index = 1 milestone_2_0.neighbor_anchor_index = 1 milestone_2_0.alias_index = 1 milestone_2_1 = base.Milestone() milestone_2_1.index = 2 milestone_2_1.neighbor_anchor_index = 2 milestone_2_1.alias_index = 2 anchor2.milestones = [milestone_2_0, milestone_2_1] anchor2.bulkstate = True model.anchors = [anchor0, anchor1, anchor2] return model
def make_simple_model(): n_anchors = 4 n_milestones = 3 # generate data to feed directly into MMVT_data_sample() model = base.Model() model.num_milestones = n_milestones model.num_anchors = n_anchors anchor0 = mmvt_base.MMVT_toy_anchor() anchor0.index = 0 milestone_0_0 = base.Milestone() milestone_0_0.index = 0 milestone_0_0.neighbor_anchor_index = 1 milestone_0_0.alias_index = 1 anchor0.milestones = [milestone_0_0] anchor1 = mmvt_base.MMVT_toy_anchor() anchor1.index = 1 milestone_1_0 = base.Milestone() milestone_1_0.index = 0 milestone_1_0.neighbor_anchor_index = 0 milestone_1_0.alias_index = 1 milestone_1_1 = base.Milestone() milestone_1_1.index = 1 milestone_1_1.neighbor_anchor_index = 2 milestone_1_1.alias_index = 2 anchor1.milestones = [milestone_1_0, milestone_1_1] anchor2 = mmvt_base.MMVT_toy_anchor() anchor2.index = 2 milestone_2_0 = base.Milestone() milestone_2_0.index = 1 milestone_2_0.neighbor_anchor_index = 1 milestone_2_0.alias_index = 1 milestone_2_1 = base.Milestone() milestone_2_1.index = 2 milestone_2_1.neighbor_anchor_index = 3 milestone_2_1.alias_index = 2 anchor2.milestones = [milestone_2_0, milestone_2_1] anchor3 = mmvt_base.MMVT_toy_anchor() anchor3.index = 3 milestone_3_0 = base.Milestone() milestone_3_0.index = 2 milestone_3_0.neighbor_anchor_index = 2 milestone_3_0.alias_index = 1 anchor3.milestones = [milestone_3_0] model.anchors = [anchor0, anchor1, anchor2, anchor3] return model
def make_test_model(tmp_dir, num_anchors=3, milestone_type="spherical", make_dir=True, mode="amber", engine="openmm", no_BD=False): if milestone_type == "spherical": #group1 = [2478, 2489, 2499, 2535, 2718, 2745, 2769, 2787, 2794, 2867, # 2926] group1 = list(range(147)) #group2 = [3221, 3222, 3223, 3224, 3225, 3226, 3227, 3228, 3229] group2 = list(range(147, 162)) groups = [group1, group2] cv1 = mmvt_base.MMVT_spherical_CV(index=0, groups=groups) cvs = [cv1] else: raise Exception("milestone type not implemented") mymodel = base.Model() mymodel.temperature = 277.8 mymodel.calculation_type = "MMVT" mymodel.calculation_settings = mmvt_base.MMVT_settings() mymodel.calculation_settings.num_production_steps = 100 mymodel.anchor_rootdir = tmp_dir mymodel.num_anchors = num_anchors mymodel.num_milestones = num_anchors - 1 if engine == "openmm": mymodel.openmm_settings = base.Openmm_settings() mymodel.openmm_settings.energy_reporter_frequency = 50 mymodel.openmm_settings.trajectory_reporter_frequency = 50 mymodel.openmm_settings.restart_checkpoint_frequency = 50 mymodel.openmm_settings.total_simulation_length = 50 mymodel.openmm_settings.cuda_platform_settings = None mymodel.openmm_settings.reference_platform = True if engine == "namd": mymodel.namd_settings = base.Namd_settings() mymodel.namd_settings.energy_reporter_frequency = 50 mymodel.namd_settings.trajectory_reporter_frequency = 50 mymodel.namd_settings.restart_checkpoint_frequency = 50 mymodel.namd_settings.total_simulation_length = 50 if not no_BD: my_k_on_info = base.K_on_info() my_k_on_info.source_milestones = [2] mymodel.k_on_info = my_k_on_info mymodel.collective_variables = cvs ''' for index in range(num_anchors): milestone_list = [] if index < num_anchors-1: milestone1 = base.Milestone() milestone1.index = index milestone1.neighbor_index = index+1 milestone1.alias_id = 2 milestone1.cv_index = 0 milestone1.variables = {"radius": 1.3} milestone_list.append(milestone1) bulkstate = False else: bulkstate = True if index > 0: milestone2 = base.Milestone() milestone2.index = index-1 milestone2.neighbor_index = index-1 milestone2.alias_id = 1 milestone2.cv_index = 0 milestone2.variables = {"radius": 1.1} milestone_list.append(milestone2) endstate = False else: endstate = True if bulkstate: endstate = True ''' for i in range(num_anchors): index = i milestone_list = [] num_milestones = 0 if i > 0: milestone1 = base.Milestone() milestone1.index = i - 1 milestone1.neighbor_anchor_index = i - 1 milestone1.alias_index = num_milestones + 1 milestone1.cv_index = 0 milestone1.variables = {"k": -1.0, "radius": 0.1 * i} milestone_list.append(milestone1) num_milestones += 1 endstate = False else: endstate = True if i < num_anchors - 1: milestone2 = base.Milestone() milestone2.index = i milestone2.neighbor_anchor_index = i + 1 milestone2.alias_index = num_milestones + 1 milestone2.cv_index = 0 milestone2.variables = {"k": 1.0, "radius": 0.1 * (i + 1)} milestone_list.append(milestone2) bulkstate = False else: bulkstate = True name = "anchor_%d" % index directory = name if make_dir: full_anchor_dir = os.path.join(tmp_dir, directory) os.mkdir(full_anchor_dir) prod_dir = os.path.join(full_anchor_dir, "prod") os.mkdir(prod_dir) building_dir = os.path.join(full_anchor_dir, "building") os.mkdir(building_dir) md_glob = "mmvt*.out" md = True bd = False #anchor = base.Anchor(name, index, directory, md_glob, md, bd, # endstate, bulkstate, len(milestone_list), milestone_list) anchor = mmvt_base.MMVT_anchor() anchor.name = name anchor.index = index anchor.directory = directory anchor.md_mmvt_output_glob = md_glob anchor.md = md anchor.bd = bd anchor.endstate = endstate anchor.bulkstate = bulkstate #anchor.num_milestones = len(milestone_list) anchor.milestones = milestone_list if mode == 'amber': make_amber_params(anchor, building_dir, engine=engine) elif mode == 'forcefield': make_forcefield_params(anchor, building_dir) else: raise Exception("mode not implemented:" + mode) mymodel.anchors.append(anchor) if not no_BD: mymodel.browndye_settings = base.Browndye_settings() mymodel.browndye_settings.apbs_grid_spacing = 0.5 mymodel.browndye_settings.n_threads = 1 mymodel.browndye_settings.recompute_ligand_electrostatics = 1 mymodel.browndye_settings.debye_length = 7.5612 mymodel.browndye_settings.ghost_indices_rec = [147] mymodel.browndye_settings.ghost_indices_lig = [15] mymodel.k_on_info.b_surface_directory = "b_surface" mymodel.k_on_info.b_surface_num_steps = 100 ion1 = base.Ion() ion1.radius = 1.2 ion1.charge = -1.0 ion1.conc = 0.15 ion2 = base.Ion() ion2.radius = 0.9 ion2.charge = 1.0 ion2.conc = 0.15 mymodel.k_on_info.ions = [ion1, ion2] if make_dir: b_surface_abs_path = os.path.join(tmp_dir, "b_surface") os.mkdir(b_surface_abs_path) make_browndye_params_b_surface(mymodel, b_surface_abs_path) mymodel.k_on_info.bd_milestones = [] bd_milestone = base.BD_milestone() bd_milestone.index = 0 bd_milestone.name = "bd_milestone_0" bd_milestone.directory = bd_milestone.name bd_milestone.outer_milestone = milestone2 #bd_milestone.outer_milestone = mymodel.anchors[-1].milestones[-1] assert "radius" in bd_milestone.outer_milestone.variables, \ "A BD outer milestone must be spherical." bd_milestone.inner_milestone = milestone1 bd_milestone.num_steps = 1 bd_milestone.receptor_indices = list(range(147)) bd_milestone.ligand_indices = list(range(15)) mymodel.k_on_info.bd_milestones.append(bd_milestone) for bd_milestone in mymodel.k_on_info.bd_milestones: bd_milestone_dict = {} bd_milestone_dict[bd_milestone.extracted_directory] = {} bd_milestone_dict[bd_milestone.fhpd_directory] = {} bd_milestone_filetree = filetree.Filetree( {bd_milestone.directory: bd_milestone_dict}) bd_milestone_filetree.make_tree(tmp_dir) return mymodel
def make_smol_model(tmp_path, num_anchors, intervals): basename = "testmmvt.dat" mymodel = base.Model() mymodel.temperature = 300.0 mymodel.calculation_type = "mmvt" mymodel.anchor_rootdir = tmp_path mymodel.num_anchors = num_anchors+1 mymodel.num_milestones = mymodel.num_anchors - 1 # TEMPORARY: toy system will eventually have its own settings mymodel.openmm_settings = base.Openmm_settings() intervals.append(1.0) for index in range(mymodel.num_anchors): boundary1 = float(index) boundary2 = float(index)+intervals[index] x0 = boundary1 + 0.5 milestones = [] anchor = mmvt_base.MMVT_anchor() if index == 0: milestone_count = 1 milestone1 = base.Milestone() milestone1.index = 0 milestone1.neighbor_anchor_index = 1 milestone1.alias_index = 1 milestone1.cv_index = 0 milestones.append(milestone1) anchor.bulkstate = False end_state = True elif index > 0 and index < mymodel.num_anchors-1: milestone_count = 2 milestone1 = base.Milestone() milestone1.index = index-1 milestone1.neighbor_anchor_index = index-1 milestone1.alias_index = 1 milestone1.cv_index = 0 milestone2 = base.Milestone() milestone2.index = index milestone2.neighbor_anchor_index = index+1 milestone2.alias_index = 2 milestone2.cv_index = 0 milestones.append(milestone1) milestones.append(milestone2) anchor.bulkstate = False end_state = False elif index == mymodel.num_anchors-1: milestone_count = 1 milestone1 = base.Milestone() milestone1.index = index-1 milestone1.neighbor_anchor_index = index-1 milestone1.alias_index = 1 milestone1.cv_index = 0 milestones.append(milestone1) anchor.bulkstate = True end_state = False anchor.name = "anchor_%d" % index anchor.index = index anchor.directory = anchor.name anchor.md_mmvt_output_glob = basename anchor.md = True anchor.endstate = end_state anchor.milestones = milestones mymodel.anchors.append(anchor) return mymodel
def test_mcmc_3x3_mmvt(tmpdir_factory): """ Use the same statistics to generate both MMVT and Elber rate matrices. Then use the data to sample matrices and compare the distributions to ensure that the MMVT and Elber matrix sampling methods are consistent. """ num = 10000 #100000 stride = 4 skip = 90 n_anchors = 4 n_milestones = 3 # generate data to feed directly into MMVT_data_sample() model = base.Model() model.num_milestones = n_milestones model.num_anchors = n_anchors anchor0 = mmvt_base.MMVT_toy_anchor() anchor0.index = 0 milestone_0_0 = base.Milestone() milestone_0_0.index = 0 milestone_0_0.neighbor_anchor_index = 1 milestone_0_0.alias_index = 1 anchor0.milestones = [milestone_0_0] anchor1 = mmvt_base.MMVT_toy_anchor() anchor1.index = 1 milestone_1_0 = base.Milestone() milestone_1_0.index = 0 milestone_1_0.neighbor_anchor_index = 0 milestone_1_0.alias_index = 1 milestone_1_1 = base.Milestone() milestone_1_1.index = 1 milestone_1_1.neighbor_anchor_index = 2 milestone_1_1.alias_index = 2 anchor1.milestones = [milestone_1_0, milestone_1_1] anchor2 = mmvt_base.MMVT_toy_anchor() anchor2.index = 2 milestone_2_0 = base.Milestone() milestone_2_0.index = 1 milestone_2_0.neighbor_anchor_index = 1 milestone_2_0.alias_index = 1 milestone_2_1 = base.Milestone() milestone_2_1.index = 2 milestone_2_1.neighbor_anchor_index = 3 milestone_2_1.alias_index = 2 anchor2.milestones = [milestone_2_0, milestone_2_1] anchor3 = mmvt_base.MMVT_toy_anchor() anchor3.index = 3 milestone_3_0 = base.Milestone() milestone_3_0.index = 2 milestone_3_0.neighbor_anchor_index = 2 milestone_3_0.alias_index = 1 anchor3.milestones = [milestone_3_0] model.anchors = [anchor0, anchor1, anchor2, anchor3] # MMVT stats N_alpha_beta = {(0,1):12, (1,0):12, (1,2):12, (2,1):12, (2,3):6, (3,2):6} k_alpha_beta = {(0,1):20.0, (1,0):10.0, (1,2):10.0, (2,1):(40.0/3.0), (2,3):(20.0/3.0), (3,2):20.0} N_i_j_alpha = [{}, {(0,1):4, (1,0):4}, {(1,2):2, (2,1):2}, {}] R_i_alpha_total = [{0: 1.2}, {0: 1.2, 1:1.2}, {1: 1.2, 2:0.6}, {2: 0.6}] T_alpha_total = [1.2, 2.4, 1.8, 0.6] main_data_sample = mmvt_analyze.MMVT_data_sample( model, N_alpha_beta, k_alpha_beta, N_i_j_alpha, R_i_alpha_total, T_alpha_total) main_data_sample.calculate_pi_alpha() main_data_sample.fill_out_data_quantities() main_data_sample.compute_rate_matrix() main_data_sample.calculate_thermodynamics() main_data_sample.calculate_kinetics() mmvt_Q = main_data_sample.Q # Elber stats N_i_j = {(0,1): 4, (1,0): 4, (1,2): 2, (2,1): 2} R_i = {0: 2.4, 1: 2.4, 2: 1.2} elber_N = np.array([[0, 4, 0], [4, 0, 2], [0, 2, 0]]) elber_R = np.array([[2.4], [2.4], [1.2]]) elber_Q = np.zeros((n_milestones, n_milestones)) for i in range(n_milestones): for j in range(n_milestones): key = (i,j) if key in N_i_j: elber_Q[i,j] = N_i_j[key] / R_i[i] for i in range(n_milestones): elber_Q[i,i] = -np.sum(elber_Q[i,:]) # Make sure the two models make identical matrices assert np.isclose(mmvt_Q, elber_Q).all() # Now compare the distributions of both of them # MMVT matrix sampler data_sample_list, p_i_error, free_energy_profile_err, MFPTs_error, \ k_off_error, k_ons_error = mmvt_analyze.monte_carlo_milestoning_error( main_data_sample, num=num, stride=stride, skip=skip, verbose=True) mmvt_q1_distribution = [] mmvt_q2_distribution = [] for data_sample in data_sample_list: mmvt_q1_distribution.append(data_sample.Q[0,1]) mmvt_q2_distribution.append(data_sample.Q[1,0]) # Elber matrix sampler elber_q1_distribution = [] elber_q2_distribution = [] for counter in range(num * (stride) + skip): #if verbose: print("MCMC stepnum: ", counter) elber_Qnew = markov_chain_monte_carlo\ .irreversible_stochastic_matrix_algorithm_sample( elber_Q, elber_N, elber_R) if counter > skip and counter % stride == 0: elber_q1_distribution.append(elber_Q[0,1]) elber_q2_distribution.append(elber_Q[1,0]) elber_Q = elber_Qnew assert np.isclose(np.mean(elber_q1_distribution), np.mean(mmvt_q1_distribution), rtol=0.5, atol=0.01) assert np.isclose(np.std(elber_q1_distribution), np.std(mmvt_q1_distribution), rtol=0.5, atol=0.01) assert np.isclose(np.mean(elber_q2_distribution), np.mean(mmvt_q2_distribution), rtol=0.5, atol=0.01) assert np.isclose(np.std(elber_q2_distribution), np.std(mmvt_q2_distribution), rtol=0.5, atol=0.01) return