def test_write_lammps_inputs(self): # script template with open(os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "kappa.txt")) as f: kappa_template = f.read() kappa_settings = {"method": "heat"} write_lammps_inputs(output_dir="heat", script_template=kappa_template, settings=kappa_settings) with open(os.path.join("heat", "in.lammps")) as f: kappa_script = f.read() fix_hot = re.search(r"fix\s+hot\s+all\s+([^\s]+)\s+", kappa_script) # placeholders supposed to be filled self.assertEqual(fix_hot.group(1), "heat") fix_cold = re.search(r"fix\s+cold\s+all\s+([^\s]+)\s+", kappa_script) self.assertEqual(fix_cold.group(1), "heat") lattice = re.search(r"lattice\s+fcc\s+(.*)\n", kappa_script) # parentheses not supposed to be filled self.assertEqual(lattice.group(1), "${rho}") pair_style = re.search(r"pair_style\slj/cut\s+(.*)\n", kappa_script) self.assertEqual(pair_style.group(1), "${rc}") with open(os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "in.peptide")) as f: peptide_script = f.read() # copy data file src = os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "data.quartz") write_lammps_inputs(output_dir="path", script_template=peptide_script, data=src) dst = os.path.join("path", "data.peptide") self.assertTrue(filecmp.cmp(src, dst, shallow=False)) # write data file from obj obj = LammpsData.from_file(src, atom_style="atomic") with pytest.warns(FutureWarning): write_lammps_inputs(output_dir="obj", script_template=peptide_script, data=obj) obj_read = LammpsData.from_file(os.path.join("obj", "data.peptide"), atom_style="atomic") pd.testing.assert_frame_equal(obj_read.masses, obj.masses) pd.testing.assert_frame_equal(obj_read.atoms, obj.atoms)
def setUpClass(cls): cls.peptide = LammpsData.from_file(filename=os.path.join(test_dir, "data.peptide")) cls.ethane = LammpsData.from_file(filename=os.path.join(test_dir, "ethane.data")) cls.quartz = LammpsData.from_file(filename=os.path.join(test_dir, "data.quartz"), atom_style="atomic") cls.virus = LammpsData.from_file(filename=os.path.join(test_dir, "virus.data"), atom_style="angle") cls.tatb = LammpsData.from_file( filename=os.path.join(test_dir, "tatb.data"), atom_style="charge", sort_id=True, )
def setUpClass(cls): cls.ec = LammpsData.from_file(filename=os.path.join(test_dir, "ec.data")) cls.fec = LammpsData.from_file(filename=os.path.join(test_dir, "fec.data")) cls.coord = CombinedData.parse_xyz(filename=os.path.join(test_dir, "ec_fec.xyz")) cls.ec_fec1 = CombinedData.from_files( os.path.join(test_dir, "ec_fec.xyz"), [1200, 300], os.path.join(test_dir, "ec.data"), os.path.join(test_dir, "fec.data"), ) cls.ec_fec2 = CombinedData.from_lammpsdata([cls.ec, cls.fec], ["EC", "FEC"], [1200, 300], cls.coord)
def test_write_file(self): filename1 = "test1.data" self.ethane.write_file(filename=filename1) c2h6 = LammpsData.from_file(filename1) pd.testing.assert_frame_equal(c2h6.masses, self.ethane.masses) pd.testing.assert_frame_equal(c2h6.atoms, self.ethane.atoms) ff_kw = random.sample(self.ethane.force_field.keys(), 1)[0] pd.testing.assert_frame_equal(c2h6.force_field[ff_kw], self.ethane.force_field[ff_kw], ff_kw) topo_kw = random.sample(self.ethane.topology.keys(), 1)[0] pd.testing.assert_frame_equal(c2h6.topology[topo_kw], self.ethane.topology[topo_kw], topo_kw) filename2 = "test2.data" self.virus.write_file(filename=filename2) v = LammpsData.from_file(filename2, atom_style="angle") pd.testing.assert_frame_equal(v.force_field["PairIJ Coeffs"], self.virus.force_field["PairIJ Coeffs"])
def get_ion(model="jensen_jorgensen", water="default", ion="li+"): data_path = DATA_DIR alias = DATA_MODELS.get("alias") signature = model.lower() if signature in alias: signature = alias.get(model) ion_type = ion.capitalize() for key in DATA_MODELS.get("ion").keys(): if key.startswith(signature): ion_model = DATA_MODELS.get("ion").get(key) if water in ion_model: if water == "default": file_path = os.path.join(data_path, "ion", key, ion_type + ".lmp") else: file_path = os.path.join(data_path, "ion", key, water, ion_type + ".lmp") if os.path.exists(file_path): return LammpsData.from_file(file_path) else: print("Ion not found. Please try another ion.\n") return None else: print("Water model not found. Please " "try another water model.\n") return None print("Ion model not found. Please " "try another ion model.\n") return None
def test_from_file(self): self.lammps_data.write_file(os.path.join(test_dir, "lammps_data.dat"), significant_figures=15) lammps_data = LammpsData.from_file(os.path.join( test_dir, "lammps_data.dat"), atom_style="charge") self.assertEqual(lammps_data.structure, self.lammps_data.structure)
def from_file(name, filename, lammps_data=None, data_filename="in.data", user_lammps_settings={}, is_forcefield=False): """ Read in the input settings from json file as ordereddict. Note: with monty.serialization.loadfn the order of paramters in the json file is not preserved Args: filename (string): name of the file with the lamps control paramters lammps_data (string/LammpsData/LammpsForceFieldData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file user_lammps_settings (dict): User lammps settings is_forcefield (bool): whether the data file has forcefield and topology info in it. This is required only if lammps_data is a path to the data file instead of a data object Returns: DictLammpsInput """ with open(filename) as f: config_dict = json.load(f, object_pairs_hook=OrderedDict) lammps_data = lammps_data if isinstance(lammps_data, six.string_types): if is_forcefield: lammps_data = LammpsForceFieldData.from_file(lammps_data) else: lammps_data = LammpsData.from_file(lammps_data) return DictLammpsInput(name, config_dict, lammps_data=lammps_data, data_filename=data_filename, user_lammps_settings=user_lammps_settings)
def from_file(cls, name, input_template, user_settings, lammps_data=None, data_filename="in.data", is_forcefield=False): """ Returns LammpsInputSet from input file template and input data. Args: input_template (string): path to the input template file. user_settings (dict): User lammps settings, the keys must correspond to the keys in the template. lammps_data (string/LammpsData/LammpsForceFieldData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file. is_forcefield (bool): whether the data file has forcefield and topology info in it. This is required only if lammps_data is a path to the data file instead of a data object. Returns: LammpsInputSet """ lammps_input = LammpsInput.from_file(input_template, user_settings) if isinstance(lammps_data, six.string_types): if is_forcefield: lammps_data = LammpsForceFieldData.from_file(lammps_data) else: lammps_data = LammpsData.from_file(lammps_data) return cls(name, lammps_input, lammps_data=lammps_data, data_filename=data_filename)
def from_file(cls, name, input_template, user_settings, lammps_data=None, data_filename="in.data", is_forcefield=False): """ Returns LammpsInputSet from input file template and input data. Args: name (str) input_template (string): path to the input template file. user_settings (dict): User lammps settings, the keys must correspond to the keys in the template. lammps_data (string/LammpsData/LammpsForceFieldData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file. is_forcefield (bool): whether the data file has forcefield and topology info in it. This is required only if lammps_data is a path to the data file instead of a data object. Returns: LammpsInputSet """ user_settings["data_file"] = data_filename lammps_input = LammpsInput.from_file(input_template, user_settings) if isinstance(lammps_data, six.string_types): if is_forcefield: lammps_data = LammpsForceFieldData.from_file(lammps_data) else: lammps_data = LammpsData.from_file(lammps_data) return cls(name, lammps_input, lammps_data=lammps_data, data_filename=data_filename)
def from_file(name, filename, data_filename=None, is_forcefield=False): """ Read in the input settings from json file as ordereddict. Also reads in the datafile if provided. Note: with monty.serialization.loadfn the order of paramters in the json file is not preserved Args: filename (string): name of the file with the lamps control paramters data_filename (string): path to the data file is_forcefield (bool): whether the data file has forcefield and topology info in it. Returns: DictLammpsInput """ with open(filename) as f: config_dict = json.load(f, object_pairs_hook=OrderedDict) lammps_data = None if data_filename: if is_forcefield: lammps_data = LammpsForceFieldData.from_file(data_filename) else: lammps_data = LammpsData.from_file(data_filename) return DictLammpsInput(name, config_dict, lammps_data)
def from_file(name, filename, data_obj=None, data_file=None, is_forcefield=False): """ Read in the input settings from json file as ordereddict. Also reads in the datafile if provided. Note: with monty.serialization.loadfn the order of paramters in the json file is not preserved Args: filename (string): name of the file with the lamps control paramters data_obj (LammpsData): LammpsData object data_file (string): name of the data file name is_forcefield (bool): whether the data file has forcefield and topology info in it. Returns: DictLammpsInput """ with open(filename) as f: config_dict = json.load(f, object_pairs_hook=OrderedDict) lammps_data = None if data_file: if is_forcefield: lammps_data = LammpsForceFieldData.from_file(data_file) else: lammps_data = LammpsData.from_file(data_file) if data_obj and isinstance(data_obj, LammpsData): lammps_data = data_obj return DictLammpsInput(name, config_dict, lammps_data)
def test_sort_structure(self): s = Structure(Lattice.cubic(4), ["S", "Fe"], [[0, 0, 0], [0.5, 0.5, 0.5]]) lmp = LammpsData.from_structure(s, is_sort=False) lmp.write_file("test1.data") lmp2 = LammpsData.from_file("test1.data", atom_style="charge") # internally element:type will be {Fe: 1, S: 2}, # therefore without sorting the atom types in structure # will be [2, 1], i.e., (S, Fe) self.assertListEqual(lmp2.atoms["type"].values.tolist(), [2, 1]) # with sorting the atom types in structures will be [1, 2] lmp = LammpsData.from_structure(s, is_sort=True) lmp.write_file("test1.data") lmp2 = LammpsData.from_file("test1.data", atom_style="charge") self.assertListEqual(lmp2.atoms["type"].values.tolist(), [1, 2])
def download_data(self, lmp_name): """ Helper function that download and write out the LAMMPS data file. Arg: lmp_name (str): Name of the LAMMPS data file. """ print("Structure info uploaded. Rendering force field...") self.wait.until(EC.presence_of_element_located((By.NAME, 'go'))) data_lmp = self.web.find_element_by_xpath( "/html/body/div[2]/div[2]/div[1]/div/div[14]/form/input[1]") data_lmp.click() print("Force field file downloaded.") time.sleep(1) lmp_file = max([ self.write_dir + "/" + f for f in os.listdir(self.write_dir) if os.path.splitext(f)[1] == ".lmp" ], key=os.path.getctime) if self.xyz: data_obj = LammpsData.from_file(lmp_file) element_id_dict = mass_to_name(data_obj.masses) coords = data_obj.atoms[['type', 'x', 'y', 'z']] lines = list() lines.append(str(len(coords.index))) lines.append("") for _, r in coords.iterrows(): line = element_id_dict.get(int(r['type'])) + ' ' + ' '.join( str(r[loc]) for loc in ["x", "y", "z"]) lines.append(line) with open(os.path.join(self.write_dir, lmp_name + ".xyz"), "w") as xyz_file: xyz_file.write("\n".join(lines)) print(".xyz file saved.") if self.gromacs: data_gro = self.web.find_element_by_xpath( "/html/body/div[2]/div[2]/div[1]/div/div[8]/form/input[1]") data_itp = self.web.find_element_by_xpath( "/html/body/div[2]/div[2]/div[1]/div/div[9]/form/input[1]") data_gro.click() data_itp.click() time.sleep(1) gro_file = max([ self.write_dir + "/" + f for f in os.listdir(self.write_dir) if os.path.splitext(f)[1] == ".gro" ], key=os.path.getctime) itp_file = max([ self.write_dir + "/" + f for f in os.listdir(self.write_dir) if os.path.splitext(f)[1] == ".itp" ], key=os.path.getctime) shutil.move(gro_file, os.path.join(self.write_dir, lmp_name[:-4] + ".gro")) shutil.move(itp_file, os.path.join(self.write_dir, lmp_name[:-4] + ".itp")) shutil.move(lmp_file, os.path.join(self.write_dir, lmp_name)) print("Force field file saved.")
def __init__(self, data_file, trajectory_file, log_file="log.lammps"): self.data_file = os.path.abspath(data_file) self.trajectory_file = os.path.abspath(trajectory_file) self.log_file = os.path.abspath(log_file) self.log = LammpsLog(log_file) self.lammps_data = LammpsData.from_file(self.data_file) self._set_mol_masses_and_charges() self._parse_trajectory()
def test_write_file(self): filename1 = "test1.data" self.ethane.write_file(filename=filename1) c2h6 = LammpsData.from_file(filename1) pd.testing.assert_frame_equal(c2h6.masses, self.ethane.masses) pd.testing.assert_frame_equal(c2h6.atoms, self.ethane.atoms) ff_kw = random.sample(self.ethane.force_field.keys(), 1)[0] pd.testing.assert_frame_equal(c2h6.force_field[ff_kw], self.ethane.force_field[ff_kw], ff_kw) topo_kw = random.sample(self.ethane.topology.keys(), 1)[0] pd.testing.assert_frame_equal(c2h6.topology[topo_kw], self.ethane.topology[topo_kw], topo_kw) filename2 = "test2.data" self.virus.write_file(filename=filename2) v = LammpsData.from_file(filename2, atom_style="angle") pd.testing.assert_frame_equal(v.force_field["PairIJ Coeffs"], self.virus.force_field["PairIJ Coeffs"])
def test_write_inputs(self): with tempfile.TemporaryDirectory() as tmpdir: # simple script without data file lis = LammpsTemplateGen().get_input_set( script_template=os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "kappa.txt"), settings={"method": "heat"}, data=None, data_filename="data.peptide", ) tmpdir = Path(tmpdir) assert len(lis) == 1 lis.write_input(tmpdir / "heat") with open(tmpdir / "heat" / "in.lammps") as f: kappa_script = f.read() fix_hot = re.search(r"fix\s+hot\s+all\s+([^\s]+)\s+", kappa_script) # placeholders supposed to be filled assert fix_hot.group(1) == "heat" fix_cold = re.search(r"fix\s+cold\s+all\s+([^\s]+)\s+", kappa_script) assert fix_cold.group(1) == "heat" lattice = re.search(r"lattice\s+fcc\s+(.*)\n", kappa_script) # parentheses not supposed to be filled assert lattice.group(1) == "${rho}" pair_style = re.search(r"pair_style\slj/cut\s+(.*)\n", kappa_script) assert pair_style.group(1) == "${rc}" # script with data file obj = LammpsData.from_file( os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "data.quartz"), atom_style="atomic" ) lis = LammpsTemplateGen().get_input_set( script_template=os.path.join(PymatgenTest.TEST_FILES_DIR, "lammps", "in.peptide"), settings=None, data=obj, data_filename="data.peptide", ) assert len(lis) == 2 assert isinstance(lis["data.peptide"], LammpsData) lis.write_input(tmpdir / "obj") obj_read = LammpsData.from_file(str(tmpdir / "obj" / "data.peptide"), atom_style="atomic") pd.testing.assert_frame_equal(obj_read.masses, obj.masses) pd.testing.assert_frame_equal(obj_read.atoms, obj.atoms)
def get_water(model="spce"): data_path = DATA_DIR signature = "".join(re.split('[\W|_]+', model)).lower() if signature in DATA_MODELS.get("water").keys(): return LammpsData.from_file( os.path.join(data_path, "water", DATA_MODELS.get("water").get(signature))) else: print("Water model not found. Please specify a customized data " "path or try another water model.\n") return None
def test_write(self): s = Structure( Lattice( np.array([[3.16, 0.1, 0.2], [0.1, 3.17, 0.3], [0.1, 0.2, 3]])), ["Mo", "Mo"], [[0, 0, 0], [0.13, 0.4, 0.2]]) with ScratchDir("."): write_data_from_structure(s, 'test.data') lmp = LammpsData.from_file('test.data', atom_style="charge") lmp2 = LammpsData.from_structure(s) lmp2.write_file("test2.data") self.assertTrue(str(lmp) == str(lmp2))
def __init__(self, data_file, trajectory_file, log_file="log.lammps", is_forcefield=False): self.data_file = data_file self.trajectory_file = trajectory_file self.log_file = log_file self.lammps_log = LammpsLog(log_file) if is_forcefield: self.lammps_data = LammpsForceFieldData.from_file(data_file) else: self.lammps_data = LammpsData.from_file(data_file) self._set_mol_masses_and_charges() self._parse_trajectory()
def test_write_lammps_inputs(self): # script template with open(os.path.join(test_dir, "kappa.txt")) as f: kappa_template = f.read() kappa_settings = {"method": "heat"} write_lammps_inputs(output_dir="heat", script_template=kappa_template, settings=kappa_settings) with open(os.path.join("heat", "in.lammps")) as f: kappa_script = f.read() fix_hot = re.search(r"fix\s+hot\s+all\s+([^\s]+)\s+", kappa_script) # placeholders supposed to be filled self.assertEqual(fix_hot.group(1), "heat") fix_cold = re.search(r"fix\s+cold\s+all\s+([^\s]+)\s+", kappa_script) self.assertEqual(fix_cold.group(1), "heat") lattice = re.search(r"lattice\s+fcc\s+(.*)\n", kappa_script) # parentheses not supposed to be filled self.assertEqual(lattice.group(1), "${rho}") pair_style = re.search(r"pair_style\slj/cut\s+(.*)\n", kappa_script) self.assertEqual(pair_style.group(1), "${rc}") with open(os.path.join(test_dir, "in.peptide")) as f: peptide_script = f.read() # copy data file src = os.path.join(test_dir, "data.quartz") write_lammps_inputs(output_dir="path", script_template=peptide_script, data=src) dst = os.path.join("path", "data.peptide") self.assertTrue(filecmp.cmp(src, dst, shallow=False)) # write data file from obj obj = LammpsData.from_file(src, atom_style="atomic") write_lammps_inputs(output_dir="obj", script_template=peptide_script, data=obj) obj_read = LammpsData.from_file(os.path.join("obj", "data.peptide"), atom_style="atomic") pd.testing.assert_frame_equal(obj_read.masses, obj.masses) pd.testing.assert_frame_equal(obj_read.atoms, obj.atoms)
def from_file(cls, name, filename, lammps_data=None, data_filename="in.data", user_lammps_settings={}, is_forcefield=False): """ Reads lammps style and JSON style input files putting the settings in an ordered dict (config_dict). Note: with monty.serialization.loadfn the order of paramters in the json file is not preserved Args: filename (string): name of the file with the lamps control paramters lammps_data (string/LammpsData/LammpsForceFieldData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file user_lammps_settings (dict): User lammps settings is_forcefield (bool): whether the data file has forcefield and topology info in it. This is required only if lammps_data is a path to the data file instead of a data object Returns: DictLammpsInput """ try: with open(filename) as f: config_dict = json.load(f, object_pairs_hook=OrderedDict) except ValueError: with open(filename, 'r') as f: data = f.read().splitlines() config_dict = OrderedDict() for line in data: if line and not line.startswith("#"): spt_line = (line.split(None, 1)) if spt_line[0] in config_dict: if isinstance(config_dict[spt_line[0]], list): config_dict[spt_line[0]].append(spt_line[1]) else: config_dict[spt_line[0]] = [config_dict[spt_line[0]], spt_line[1]] else: config_dict[spt_line[0]] = spt_line[1] lammps_data = lammps_data if isinstance(lammps_data, six.string_types): if is_forcefield: lammps_data = LammpsForceFieldData.from_file(lammps_data) else: lammps_data = LammpsData.from_file(lammps_data) return cls(name, config_dict, lammps_data=lammps_data, data_filename=data_filename, user_lammps_settings=user_lammps_settings)
def run_task(self, fw_spec): logger.info("PARSING final lammps positions to VASP.") data = LammpsData.from_file(self['structure_loc'], atom_style=self.get('atom_style', 'full'), sort_id=True) struc = data.structure structure = Structure(lattice=struc.lattice, species=[s.specie for s in struc.sites], coords=[s.coords for s in struc.sites], coords_are_cartesian=True) vis_cls = load_class("pymatgen.io.vasp.sets", self["vasp_input_set"]) vis = vis_cls(structure, **self.get("vasp_input_params", {})) vis.write_input(".")
def __init__(self, data_dir, wrapped_dir, unwrapped_dir, nvt_start, time_step, name, select_dict, cation_charge=1, anion_charge=-1, cond=True): """ Base constructor. """ self.wrapped_run = MDAnalysis.Universe(data_dir, wrapped_dir, format="LAMMPS") self.unwrapped_run = MDAnalysis.Universe(data_dir, unwrapped_dir, format="LAMMPS") self.nvt_start = nvt_start self.time_step = time_step self.name = name self.data = LammpsData.from_file(data_dir) self.element_id_dict = mass_to_name(self.data.masses) self.select_dict = select_dict self.nvt_steps = self.wrapped_run.trajectory.n_frames self.time_array = [i * self.time_step for i in range(self.nvt_steps)] self.cation_charge = cation_charge self.anion_charge = anion_charge self.num_li = len( self.wrapped_run.select_atoms(self.select_dict.get("cation")) ) if cond: self.cond_array = self.get_cond_array() else: self.cond_array = None self.init_x = self.get_init_dimension()[0] self.init_y = self.get_init_dimension()[1] self.init_z = self.get_init_dimension()[2] self.init_v = self.init_x * self.init_y * self.init_z self.nvt_x = self.get_nvt_dimension()[0] self.nvt_y = self.get_nvt_dimension()[1] self.nvt_z = self.get_nvt_dimension()[2] self.nvt_v = self.nvt_x * self.nvt_y * self.nvt_z gas_constant = 8.314 temp = 298.15 faraday_constant_2 = 96485 * 96485 self.c = (self.num_li / (self.nvt_v * 1e-30)) / (6.022*1e23) self.d_to_sigma = self.c * faraday_constant_2 / (gas_constant * temp)
def get_water(model: str = "spce") -> LammpsData: """ Retrieve water model parameters. Args: model: Water model to use. Valid choices are "spc", "spce", "opc3", "tip3pew", "tip3pfb", "tip4p2005", "tip4pew", "tip4pfb", and "opc". (Default: "spce") Returns: LammpsData: Force field parameters for the chosen water model. If you specify an invalid water model, None is returned. """ signature = "".join(re.split(r"[\W|_]+", model)).lower() if DATA_MODELS["water"].get(signature): return LammpsData.from_file( os.path.join(DATA_DIR, "water", DATA_MODELS["water"].get(signature))) raise ValueError( "Water model not found. Please specify a customized data path or try another water model.\n" )
def test_structure(self): structure = self.lammps_data.structure self.assertEqual(len(structure.composition.elements), 2) self.assertEqual(structure.num_sites, 3) self.assertEqual(structure.formula, "Li2 O1") lammps_data = LammpsData.from_file(os.path.join(test_dir, "nvt.data"), 'full') self.assertEqual(type(lammps_data.structure).__name__, 'Structure') self.assertEqual(len(lammps_data.structure.composition.elements), 2) self.assertEqual(lammps_data.structure.num_sites, 648) self.assertEqual(lammps_data.structure.symbol_set[0], 'O') self.assertEqual(lammps_data.structure.symbol_set[1], 'H') self.assertEqual(lammps_data.structure.volume, 27000) # test tilt structure tilt_str = mg.Structure.from_file(os.path.join(test_dir, "POSCAR")) lmp_tilt_data = LammpsData.from_structure(tilt_str) s = StructureMatcher() groups = s.group_structures([lmp_tilt_data.structure, tilt_str]) self.assertEqual(len(groups), 1)
def from_file(name, filename, lammps_data=None, data_filename="in.data", user_lammps_settings={}, is_forcefield=False): """ Read in the input settings from json file as ordereddict. Note: with monty.serialization.loadfn the order of paramters in the json file is not preserved Args: filename (string): name of the file with the lamps control paramters lammps_data (string/LammpsData/LammpsForceFieldData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file user_lammps_settings (dict): User lammps settings is_forcefield (bool): whether the data file has forcefield and topology info in it. This is required only if lammps_data is a path to the data file instead of a data object Returns: DictLammpsInput """ with open(filename) as f: config_dict = json.load(f, object_pairs_hook=OrderedDict) lammps_data = lammps_data if isinstance(lammps_data, six.string_types): if is_forcefield: lammps_data = LammpsForceFieldData.from_file(lammps_data) else: lammps_data = LammpsData.from_file(lammps_data) return DictLammpsInput(name, config_dict, lammps_data=lammps_data, data_filename=data_filename, user_lammps_settings=user_lammps_settings)
def from_file(cls, name, input_template, user_settings, lammps_data=None, data_filename="in.data"): """ Returns LammpsInputSet from input file template and input data. Args: name (str) input_template (string): path to the input template file. user_settings (dict): User lammps settings, the keys must correspond to the keys in the template. lammps_data (string/LammpsData): path to the data file or an appropriate object data_filename (string): name of the the lammps data file. Returns: LammpsInputSet """ user_settings["data_file"] = data_filename lammps_input = LammpsInput.from_file(input_template, user_settings) if isinstance(lammps_data, six.string_types): lammps_data = LammpsData.from_file(lammps_data) return cls(name, lammps_input, lammps_data=lammps_data, data_filename=data_filename)
def test_from_file(self): # general tests pep = self.peptide # header stats and Nos. of columns self.assertEqual(pep.masses.shape, (14, 1)) self.assertEqual(pep.atoms.shape, (2004, 9)) self.assertListEqual( list(pep.atoms.columns), ["molecule-ID", "type", "q", "x", "y", "z", "nx", "ny", "nz"]) topo = pep.topology self.assertEqual(topo["Bonds"].shape, (1365, 3)) self.assertEqual(topo["Angles"].shape, (786, 4)) self.assertEqual(topo["Dihedrals"].shape, (207, 5)) self.assertEqual(topo["Impropers"].shape, (12, 5)) ff = pep.force_field self.assertEqual(ff["Pair Coeffs"].shape, (14, 4)) self.assertEqual(ff["Bond Coeffs"].shape, (18, 2)) self.assertEqual(ff["Angle Coeffs"].shape, (31, 4)) self.assertEqual(ff["Dihedral Coeffs"].shape, (21, 4)) self.assertEqual(ff["Improper Coeffs"].shape, (2, 2)) # header box np.testing.assert_array_equal( pep.box_bounds, [[36.840194, 64.211560], [41.013691, 68.385058], [29.768095, 57.139462]]) # body self.assertEqual(pep.masses.at[7, "mass"], 12.0110) self.assertEqual(ff["Pair Coeffs"].at[9, "coeff3"], 0.152100) self.assertEqual(ff["Bond Coeffs"].at[5, "coeff2"], 1.430000) self.assertEqual(ff["Angle Coeffs"].at[21, "coeff2"], 120.000000) self.assertEqual(ff["Dihedral Coeffs"].at[10, "coeff1"], 0.040000) self.assertEqual(ff["Improper Coeffs"].at[2, "coeff1"], 20.000000) self.assertEqual(pep.atoms.at[29, "molecule-ID"], 1) self.assertEqual(pep.atoms.at[29, "type"], 7) self.assertEqual(pep.atoms.at[29, "q"], -0.020) self.assertAlmostEqual(pep.atoms.at[29, "x"], 42.96709) self.assertEqual(pep.atoms.at[1808, "molecule-ID"], 576) self.assertEqual(pep.atoms.at[1808, "type"], 14) self.assertAlmostEqual(pep.atoms.at[1808, "y"], 58.64352) self.assertEqual(pep.atoms.at[1808, "nx"], -1) self.assertAlmostEqual(pep.velocities.at[527, "vz"], -0.010889) self.assertEqual(topo["Bonds"].at[47, "type"], 8) self.assertEqual(topo["Bonds"].at[47, "atom2"], 54) self.assertEqual(topo["Bonds"].at[953, "atom1"], 1384) self.assertEqual(topo["Angles"].at[105, "type"], 19) self.assertEqual(topo["Angles"].at[105, "atom3"], 51) self.assertEqual(topo["Angles"].at[376, "atom2"], 772) self.assertEqual(topo["Dihedrals"].at[151, "type"], 14) self.assertEqual(topo["Dihedrals"].at[151, "atom4"], 51) self.assertEqual(topo["Impropers"].at[4, "atom4"], 32) # class 2 and comments ethane = self.ethane self.assertEqual(ethane.masses.shape, (2, 1)) self.assertEqual(ethane.atoms.shape, (8, 9)) class2 = ethane.force_field self.assertEqual(class2["Pair Coeffs"].shape, (2, 2)) self.assertEqual(class2["Bond Coeffs"].shape, (2, 4)) self.assertEqual(class2["Angle Coeffs"].shape, (2, 4)) self.assertEqual(class2["Dihedral Coeffs"].shape, (1, 6)) self.assertEqual(class2["Improper Coeffs"].shape, (2, 2)) self.assertEqual(class2["BondBond Coeffs"].at[2, "coeff3"], 1.1010) self.assertEqual(class2["BondAngle Coeffs"].at[2, "coeff4"], 1.1010) self.assertEqual(class2["AngleAngle Coeffs"].at[2, "coeff6"], 107.6600) self.assertEqual(class2["AngleAngle Coeffs"].at[2, "coeff6"], 107.6600) self.assertEqual(class2["AngleAngleTorsion Coeffs"].at[1, "coeff3"], 110.7700) self.assertEqual(class2["EndBondTorsion Coeffs"].at[1, "coeff8"], 1.1010) self.assertEqual(class2["MiddleBondTorsion Coeffs"].at[1, "coeff4"], 1.5300) self.assertEqual(class2["BondBond13 Coeffs"].at[1, "coeff3"], 1.1010) self.assertEqual(class2["AngleTorsion Coeffs"].at[1, "coeff8"], 110.7700) # box_tilt and another atom_style quartz = self.quartz np.testing.assert_array_equal(quartz.box_tilt, [-2.456700, 0.0, 0.0]) self.assertListEqual(list(quartz.atoms.columns), ["type", "x", "y", "z"]) self.assertAlmostEqual(quartz.atoms.at[7, "x"], 0.299963) # PairIJ Coeffs section virus = self.virus pairij = virus.force_field["PairIJ Coeffs"] self.assertEqual(pairij.at[7, "id1"], 3) self.assertEqual(pairij.at[7, "id2"], 3) self.assertEqual(pairij.at[7, "coeff2"], 2.1) # sort_id nvt = LammpsData.from_file(filename=os.path.join(test_dir, "nvt.data"), sort_id=True) atom_id = random.randint(1, 648) self.assertEqual(nvt.atoms.loc[atom_id].name, atom_id)
def test_from_file(self): peptide = self.peptide # header stats self.assertEqual(len(peptide.atoms), 2004) topology = peptide.topology self.assertEqual(len(topology["Bonds"]), 1365) self.assertEqual(len(topology["Angles"]), 786) self.assertEqual(len(topology["Dihedrals"]), 207) self.assertEqual(len(topology["Impropers"]), 12) self.assertEqual(len(peptide.masses), 14) force_field = peptide.force_field self.assertEqual(len(force_field["Pair Coeffs"]), 14) self.assertEqual(len(force_field["Bond Coeffs"]), 18) self.assertEqual(len(force_field["Angle Coeffs"]), 31) self.assertEqual(len(force_field["Dihedral Coeffs"]), 21) self.assertEqual(len(force_field["Improper Coeffs"]), 2) # header box np.testing.assert_array_equal(peptide.box_bounds, [[36.840194, 64.211560], [41.013691, 68.385058], [29.768095, 57.139462]]) # body last line of each section self.assertDictEqual(peptide.masses[-1], {"id": 14, "mass": 1.0100}) self.assertDictEqual(force_field["Pair Coeffs"][-1], {"id": 14, "coeffs": [0.046000, 0.400014, 0.046000, 0.400014]}) self.assertDictEqual(force_field["Bond Coeffs"][-1], {"id": 18, "coeffs": [450.000000, 0.957200]}) self.assertDictEqual(force_field["Angle Coeffs"][-1], {"id": 31, "coeffs": [55.000000, 104.520000, 0.000000, 0.000000]}) self.assertDictEqual(force_field["Dihedral Coeffs"][-1], {"id": 21, "coeffs": [0.010000, 3, 0, 1.000000]}) for c in force_field["Dihedral Coeffs"][-1]["coeffs"][1:2]: self.assertIsInstance(c, int) self.assertDictEqual(force_field["Improper Coeffs"][-1], {"id": 2, "coeffs": [20.000000, 0.000000]}) self.assertDictEqual(peptide.atoms[-1], {"id": 2004, "molecule-ID": 641, "type": 14, "q": 0.417, "x": 56.55074, "y": 49.75049, "z": 48.61854, "nx": 1, "ny": 1, "nz": 1}) self.assertDictEqual(peptide.velocities[-1], {"id": 2004, "velocity": [-0.010076, -0.005729, -0.026032]}) self.assertDictEqual(topology["Bonds"][-1], {"id": 1365, "type": 18, "bond": [2002, 2003]}) self.assertDictEqual(topology["Angles"][-1], {"id": 786, "type": 31, "angle": [2003, 2002, 2004]}) self.assertDictEqual(topology["Dihedrals"][-1], {"id": 207, "type": 3, "dihedral": [64, 79, 80, 82]}) self.assertDictEqual(topology["Impropers"][-1], {"id": 12, "type": 2, "improper": [79, 64, 80, 81]}) # box_tilt and another atom_style quartz = self.quartz np.testing.assert_array_equal(quartz.box_tilt, [-2.456700, 0.0, 0.0]) self.assertDictEqual(quartz.atoms[-1], {"id": 9, "type": 2, "x": 1.375998, "y": -1.140800, "z": -2.443511}) # sort_id nvt = LammpsData.from_file(filename=os.path.join(test_dir, "nvt.data"), sort_id=True) atom_id = random.randint(1, 648) self.assertEqual(nvt.atoms[atom_id - 1]["id"], atom_id) # PairIJ Coeffs section virus = LammpsData.from_file(filename=os.path.join(test_dir, "virus.data"), atom_style="angle") n = len(virus.masses) pairij = virus.force_field["PairIJ Coeffs"] self.assertEqual(len(pairij), n * (n + 1) / 2) self.assertDictEqual(pairij[-1], {"id1": 4, "id2": 4, "coeffs": [1, 1, 1.1225]})
def run_task(self, fw_spec): atom_style = self.get('atom_style') start_temp = self.get('start_temp') end_temp = self.get('end_temp') nsteps = self.get('nsteps') spawn = self.get('spawn') or False production = self.get('production') or False time_step = self.get('time_step') or 1 vasp_cmd = self.get('vasp_cmd') or ">>vasp_gam<<" copy_vasp_outputs = self.get('copy_vasp_outputs') or False user_incar_settings = self.get('user_incar_settings') or {} user_kpoints_settings = self.get('user_kpoints_settings') or None db_file = self.get('db_file') or None transmute = self.get('transmute') or None pressure_threshold = self.get('pressure_threshold') or 5 max_rescales = self.get('max_rescales') or 6 wall_time = self.get('wall_time') or 19200 copy_calcs = self.get('copy_calcs') or False calc_home = self.get('calc_home') or '~' logger.info("PARSING \"lammps.final\" to VASP.") data = LammpsData.from_file(os.path.join(os.getcwd(), self.get('final_data')), atom_style=atom_style, sort_id=True) struc = data.structure structure = Structure(lattice=struc.lattice, species=[s.specie for s in struc.sites], coords=[s.coords for s in struc.sites], coords_are_cartesian=True) if transmute: sites = structure.sites indices = [] for i, s in enumerate(sites): if s.specie.symbol == transmute[0]: indices.append(i) index = random.choice(indices) structure.replace( index, species=transmute[1], properties={'charge': Specie(transmute[1]).oxi_state}) vasp_input_set = MITMDSet(structure, start_temp, end_temp, nsteps, time_step, force_gamma=True, user_incar_settings=user_incar_settings) if user_kpoints_settings: v = vasp_input_set.as_dict() v.update({"user_kpoints_settings": user_kpoints_settings}) vasp_input_set = vasp_input_set.from_dict(v) fw = MDFW(structure, start_temp, end_temp, nsteps, vasp_input_set=vasp_input_set, vasp_cmd=vasp_cmd, copy_vasp_outputs=copy_vasp_outputs, db_file=db_file, name='MDFW', wall_time=wall_time) if spawn: t = fw.tasks t.append( SpawnMDFWTask(pressure_threshold=pressure_threshold, max_rescales=max_rescales, wall_time=wall_time, vasp_cmd=vasp_cmd, db_file=db_file, copy_calcs=copy_calcs, calc_home=calc_home, spawn_count=1, production=production)) fw = Firework(tasks=t, name='SpawnMDFW') return FWAction(detours=fw, stored_data={'LammpsStructure': structure})
def _setup(self): template_dir = os.path.join(os.path.dirname(__file__), 'templates', 'neb') with open(os.path.join(template_dir, 'in.relax'), 'r') as f: relax_template = f.read() with open(os.path.join(template_dir, 'in.neb'), 'r') as f: neb_template = f.read() unit_cell = self.get_unit_cell(specie=self.specie, lattice=self.lattice, alat=self.alat) lattice_calculator = LatticeConstant(ff_settings=self.ff_settings) a, _, _ = lattice_calculator.calculate([unit_cell])[0] unit_cell = self.get_unit_cell(specie=self.specie, lattice=self.lattice, alat=a) if self.lattice == 'fcc': start_idx, final_idx = 95, 49 scale_factor = [3, 3, 3] elif self.lattice == 'bcc': start_idx, final_idx = 40, 14 scale_factor = [3, 3, 3] elif self.lattice == 'diamond': start_idx, final_idx = 7, 15 scale_factor = [2, 2, 2] else: raise ValueError("Lattice type is invalid.") super_cell = unit_cell * scale_factor super_cell_ld = LammpsData.from_structure(super_cell, atom_style='atomic') super_cell_ld.write_file('data.supercell') with open('in.relax', 'w') as f: f.write( relax_template.format(ff_settings='\n'.join( self.ff_settings.write_param()), lattice=self.lattice, alat=a, specie=self.specie, del_id=start_idx + 1, relaxed_file='initial.relaxed')) p = subprocess.Popen([self.LMP_EXE, '-in', 'in.relax'], stdout=subprocess.PIPE) stdout = p.communicate()[0] rc = p.returncode if rc != 0: error_msg = 'LAMMPS exited with return code %d' % rc msg = stdout.decode("utf-8").split('\n')[:-1] try: error_line = [ i for i, m in enumerate(msg) if m.startswith('ERROR') ][0] error_msg += ', '.join([e for e in msg[error_line:]]) except: error_msg += msg[-1] raise RuntimeError(error_msg) with open('in.relax', 'w') as f: f.write( relax_template.format(ff_settings='\n'.join( self.ff_settings.write_param()), lattice=self.lattice, alat=a, specie=self.specie, del_id=final_idx + 1, relaxed_file='final.relaxed')) p = subprocess.Popen([self.LMP_EXE, '-in', 'in.relax'], stdout=subprocess.PIPE) stdout = p.communicate()[0] rc = p.returncode if rc != 0: error_msg = 'LAMMPS exited with return code %d' % rc msg = stdout.decode("utf-8").split('\n')[:-1] try: error_line = [ i for i, m in enumerate(msg) if m.startswith('ERROR') ][0] error_msg += ', '.join([e for e in msg[error_line:]]) except: error_msg += msg[-1] raise RuntimeError(error_msg) final_relaxed_struct = LammpsData.from_file( 'final.relaxed', atom_style='atomic').structure lines = ['{}'.format(final_relaxed_struct.num_sites)] for idx, site in enumerate(final_relaxed_struct): if idx == final_idx: idx = final_relaxed_struct.num_sites elif idx == start_idx: idx = final_idx else: idx = idx lines.append('{} {:.3f} {:.3f} {:.3f}'.format( idx + 1, site.x, site.y, site.z)) with open('data.final_replica', 'w') as f: f.write('\n'.join(lines)) input_file = 'in.neb' with open(input_file, 'w') as f: f.write( neb_template.format(ff_settings='\n'.join( self.ff_settings.write_param()), start_replica='initial.relaxed', final_replica='data.final_replica')) return input_file
# relax the bulk structure settings = { "structure_path": CONFIGURATION["structure_path"], "pair_style": CONFIGURATION["pair_style"], "potential_path": CONFIGURATION["potential_path"], "atom_types": CONFIGURATION["atom_types"], "output_path": "bulk.relax.lmp" } write_lammps_inputs(".", relax_template, settings=settings) cmd = "$LAMMPS_SERIAL_BIN -in in.lammps >/dev/null" print("Running structure relaxation...") os.system(cmd) print("Completed structure relaxation.") # load the relaxed structure file lammps_data = LammpsData.from_file("bulk.relax.lmp", atom_style="atomic") structure = lammps_data.structure # iterate over the lattice sites sim_counts = {} for i, site_i in enumerate(structure.sites): for j, site_j in enumerate(structure.sites): # skip identical sites if i == j: continue # skip sites which are not nearest neighbors if site_i.distance(site_j) > CONFIGURATION[ "nearest_neighbor_radius"] + CONFIGURATION["tolerance"]: continue
# relax the bulk structure settings = { "structure_path": CONFIGURATION["structure_path"], "pair_style": CONFIGURATION["pair_style"], "potential_path": CONFIGURATION["potential_path"], "atom_types": CONFIGURATION["atom_types"], "output_path": "bulk.relax.lmp" } write_lammps_inputs(".", primary_relax_template, settings=settings) cmd = "$LAMMPS_SERIAL_BIN -in in.lammps >/dev/null" print("Running primary structure relaxation...") os.system(cmd) print("Completed primary structure relaxation.") # load the relaxed structure file bulk_relax_data = LammpsData.from_file("bulk.relax.lmp", atom_style="atomic") # initialize simulation counter all_species = CONFIGURATION["atom_types"].split() sim_counts = { "{}-{}".format(s_i, s_j): 0 for s_i in all_species for s_j in all_species } # iterate over the bulk relaxed lattice sites for i, site_i in enumerate(bulk_relax_data.structure.sites): # check if simulations are maxed out is_complete = all([ v == CONFIGURATION["max_simulations_per_pair"] for v in sim_counts.values()
def _setup(self): template_dir = os.path.join(os.path.dirname(__file__), "templates", "neb") with open(os.path.join(template_dir, "in.relax"), "r") as f: relax_template = f.read() with open(os.path.join(template_dir, "in.neb"), "r") as f: neb_template = f.read() unit_cell = self.get_unit_cell(specie=self.specie, lattice=self.lattice, alat=self.alat) lattice_calculator = LatticeConstant(ff_settings=self.ff_settings) a, _, _ = lattice_calculator.calculate([unit_cell])[0] unit_cell = self.get_unit_cell(specie=self.specie, lattice=self.lattice, alat=a) if self.lattice == "fcc": start_idx, final_idx = 95, 49 scale_factor = [3, 3, 3] elif self.lattice == "bcc": start_idx, final_idx = 40, 14 scale_factor = [3, 3, 3] elif self.lattice == "diamond": start_idx, final_idx = 7, 15 scale_factor = [2, 2, 2] else: raise ValueError("Lattice type is invalid.") super_cell = unit_cell * scale_factor super_cell_ld = LammpsData.from_structure( super_cell, ff_elements=self.ff_settings.elements) super_cell_ld.write_file("data.supercell") with open("in.relax", "w") as f: f.write( relax_template.format( ff_settings="\n".join(self.ff_settings.write_param()), lattice=self.lattice, alat=a, specie=self.specie, del_id=start_idx + 1, relaxed_file="initial.relaxed", )) p = subprocess.Popen([self.LMP_EXE, "-in", "in.relax"], stdout=subprocess.PIPE) stdout = p.communicate()[0] rc = p.returncode if rc != 0: error_msg = "LAMMPS exited with return code %d" % rc msg = stdout.decode("utf-8").split("\n")[:-1] try: error_line = [ i for i, m in enumerate(msg) if m.startswith("ERROR") ][0] error_msg += ", ".join(msg[error_line:]) except Exception: error_msg += msg[-1] raise RuntimeError(error_msg) with open("in.relax", "w") as f: f.write( relax_template.format( ff_settings="\n".join(self.ff_settings.write_param()), lattice=self.lattice, alat=a, specie=self.specie, del_id=final_idx + 1, relaxed_file="final.relaxed", )) p = subprocess.Popen([self.LMP_EXE, "-in", "in.relax"], stdout=subprocess.PIPE) stdout = p.communicate()[0] rc = p.returncode if rc != 0: error_msg = "LAMMPS exited with return code %d" % rc msg = stdout.decode("utf-8").split("\n")[:-1] try: error_line = [ i for i, m in enumerate(msg) if m.startswith("ERROR") ][0] error_msg += ", ".join(msg[error_line:]) except Exception: error_msg += msg[-1] raise RuntimeError(error_msg) final_relaxed_struct = LammpsData.from_file( "final.relaxed", atom_style="charge").structure lines = ["{}".format(final_relaxed_struct.num_sites)] for idx, site in enumerate(final_relaxed_struct): if idx == final_idx: idx = final_relaxed_struct.num_sites elif idx == start_idx: idx = final_idx else: idx = idx lines.append("{} {:.3f} {:.3f} {:.3f}".format( idx + 1, site.x, site.y, site.z)) with open("data.final_replica", "w") as f: f.write("\n".join(lines)) input_file = "in.neb" with open(input_file, "w") as f: f.write( neb_template.format( ff_settings="\n".join(self.ff_settings.write_param()), start_replica="initial.relaxed", final_replica="data.final_replica", )) return input_file
def test_disassemble(self): # general tests c = LammpsData.from_file(os.path.join(test_dir, "crambin.data")) _, c_ff, topos = c.disassemble() mass_info = [('N1', 14.0067), ('H1', 1.00797), ('C1', 12.01115), ('H2', 1.00797), ('C2', 12.01115), ('O1', 15.9994), ('C3', 12.01115), ('O2', 15.9994), ('H3', 1.00797), ('C4', 12.01115), ('N2', 14.0067), ('C5', 12.01115), ('S1', 32.064), ('C6', 12.01115), ('N3', 14.0067), ('C7', 12.01115), ('C8', 12.01115), ('C9', 12.01115), ('O3', 15.9994)] self.assertListEqual(c_ff.mass_info, mass_info) np.testing.assert_array_equal(c_ff.nonbond_coeffs, c.force_field["Pair Coeffs"].values) base_kws = ["Bond", "Angle", "Dihedral", "Improper"] for kw in base_kws: ff_kw = kw + " Coeffs" i = random.randint(0, len(c_ff.topo_coeffs[ff_kw]) - 1) sample_coeff = c_ff.topo_coeffs[ff_kw][i] np.testing. \ assert_array_equal(sample_coeff["coeffs"], c.force_field[ff_kw].iloc[i].values, ff_kw) topo = topos[-1] atoms = c.atoms[c.atoms["molecule-ID"] == 46] np.testing.assert_array_almost_equal(topo.sites.cart_coords, atoms[["x", "y", "z"]]) np.testing.assert_array_equal(topo.charges, atoms["q"]) atom_labels = [m[0] for m in mass_info] self.assertListEqual(topo.sites.site_properties["ff_map"], [atom_labels[i - 1] for i in atoms["type"]]) shift = min(atoms.index) for kw in base_kws: ff_kw = kw + " Coeffs" ff_coeffs = c_ff.topo_coeffs[ff_kw] topo_kw = kw + "s" topos_df = c.topology[topo_kw] topo_df = topos_df[topos_df["atom1"] >= shift] topo_arr = topo_df.drop("type", axis=1).values np.testing.assert_array_equal(topo.topologies[topo_kw], topo_arr - shift, topo_kw) sample_topo = random.sample(list(topo_df.itertuples(False, None)), 1)[0] topo_type_idx = sample_topo[0] - 1 topo_type = tuple([ atom_labels[i - 1] for i in atoms.loc[sample_topo[1:], "type"] ]) self.assertIn(topo_type, ff_coeffs[topo_type_idx]["types"], ff_kw) # test no guessing element and pairij as nonbond coeffs v = self.virus _, v_ff, _ = v.disassemble(guess_element=False) self.assertDictEqual(v_ff.maps["Atoms"], dict(Qa1=1, Qb1=2, Qc1=3, Qa2=4)) pairij_coeffs = v.force_field["PairIJ Coeffs"].drop(["id1", "id2"], axis=1) np.testing.assert_array_equal(v_ff.nonbond_coeffs, pairij_coeffs.values) # test class2 ff _, e_ff, _ = self.ethane.disassemble() e_topo_coeffs = e_ff.topo_coeffs for k in ["BondBond Coeffs", "BondAngle Coeffs"]: self.assertIn(k, e_topo_coeffs["Angle Coeffs"][0], k) for k in [ "MiddleBondTorsion Coeffs", "EndBondTorsion Coeffs", "AngleTorsion Coeffs", "AngleAngleTorsion Coeffs", "BondBond13 Coeffs" ]: self.assertIn(k, e_topo_coeffs["Dihedral Coeffs"][0], k) self.assertIn("AngleAngle Coeffs", e_topo_coeffs["Improper Coeffs"][0])
def test_disassemble(self): # general tests c = LammpsData.from_file(os.path.join(test_dir, "crambin.data")) _, c_ff, topos = c.disassemble() mass_info = [('N1', 14.0067), ('H1', 1.00797), ('C1', 12.01115), ('H2', 1.00797), ('C2', 12.01115), ('O1', 15.9994), ('C3', 12.01115), ('O2', 15.9994), ('H3', 1.00797), ('C4', 12.01115), ('N2', 14.0067), ('C5', 12.01115), ('S1', 32.064), ('C6', 12.01115), ('N3', 14.0067), ('C7', 12.01115), ('C8', 12.01115), ('C9', 12.01115), ('O3', 15.9994)] self.assertListEqual(c_ff.mass_info, mass_info) np.testing.assert_array_equal(c_ff.nonbond_coeffs, c.force_field["Pair Coeffs"].values) base_kws = ["Bond", "Angle", "Dihedral", "Improper"] for kw in base_kws: ff_kw = kw + " Coeffs" i = random.randint(0, len(c_ff.topo_coeffs[ff_kw]) - 1) sample_coeff = c_ff.topo_coeffs[ff_kw][i] np.testing.\ assert_array_equal(sample_coeff["coeffs"], c.force_field[ff_kw].iloc[i].values, ff_kw) topo = topos[-1] atoms = c.atoms[c.atoms["molecule-ID"] == 46] np.testing.assert_array_equal(topo.sites.cart_coords, atoms[["x", "y", "z"]]) np.testing.assert_array_equal(topo.charges, atoms["q"]) atom_labels = [m[0] for m in mass_info] self.assertListEqual(topo.sites.site_properties["ff_map"], [atom_labels[i - 1] for i in atoms["type"]]) shift = min(atoms.index) for kw in base_kws: ff_kw = kw + " Coeffs" ff_coeffs = c_ff.topo_coeffs[ff_kw] topo_kw = kw + "s" topos_df = c.topology[topo_kw] topo_df = topos_df[topos_df["atom1"] >= shift] topo_arr = topo_df.drop("type", axis=1).values np.testing.assert_array_equal(topo.topologies[topo_kw], topo_arr - shift, topo_kw) sample_topo = random.sample(list(topo_df.itertuples(False, None)), 1)[0] topo_type_idx = sample_topo[0] - 1 topo_type = tuple([atom_labels[i - 1] for i in atoms.loc[sample_topo[1:], "type"]]) self.assertIn(topo_type, ff_coeffs[topo_type_idx]["types"], ff_kw) # test no guessing element and pairij as nonbond coeffs v = self.virus _, v_ff, _ = v.disassemble(guess_element=False) self.assertDictEqual(v_ff.maps["Atoms"], dict(Qa1=1, Qb1=2, Qc1=3, Qa2=4)) pairij_coeffs = v.force_field["PairIJ Coeffs"].drop(["id1", "id2"], axis=1) np.testing.assert_array_equal(v_ff.nonbond_coeffs, pairij_coeffs.values) # test class2 ff _, e_ff, _ = self.ethane.disassemble() e_topo_coeffs = e_ff.topo_coeffs for k in ["BondBond Coeffs", "BondAngle Coeffs"]: self.assertIn(k, e_topo_coeffs["Angle Coeffs"][0], k) for k in ["MiddleBondTorsion Coeffs", "EndBondTorsion Coeffs", "AngleTorsion Coeffs", "AngleAngleTorsion Coeffs", "BondBond13 Coeffs"]: self.assertIn(k, e_topo_coeffs["Dihedral Coeffs"][0], k) self.assertIn("AngleAngle Coeffs", e_topo_coeffs["Improper Coeffs"][0])
def test_from_file(self): self.lammps_data.write_data_file(os.path.join(test_dir, "lammps_data.dat")) lammps_data = LammpsData.from_file(os.path.join(test_dir, "lammps_data.dat")) self.assertEqual(str(lammps_data), str(self.lammps_data))
def test_from_file(self): peptide = self.peptide # header stats self.assertEqual(len(peptide.atoms), 2004) topology = peptide.topology self.assertEqual(len(topology["Bonds"]), 1365) self.assertEqual(len(topology["Angles"]), 786) self.assertEqual(len(topology["Dihedrals"]), 207) self.assertEqual(len(topology["Impropers"]), 12) self.assertEqual(len(peptide.masses), 14) force_field = peptide.force_field self.assertEqual(len(force_field["Pair Coeffs"]), 14) self.assertEqual(len(force_field["Bond Coeffs"]), 18) self.assertEqual(len(force_field["Angle Coeffs"]), 31) self.assertEqual(len(force_field["Dihedral Coeffs"]), 21) self.assertEqual(len(force_field["Improper Coeffs"]), 2) # header box np.testing.assert_array_equal( peptide.box_bounds, [[36.840194, 64.211560], [41.013691, 68.385058], [29.768095, 57.139462]]) # body last line of each section self.assertDictEqual(peptide.masses[-1], {"id": 14, "mass": 1.0100}) self.assertDictEqual(force_field["Pair Coeffs"][-1], { "id": 14, "coeffs": [0.046000, 0.400014, 0.046000, 0.400014] }) self.assertDictEqual(force_field["Bond Coeffs"][-1], { "id": 18, "coeffs": [450.000000, 0.957200] }) self.assertDictEqual( force_field["Angle Coeffs"][-1], { "id": 31, "coeffs": [55.000000, 104.520000, 0.000000, 0.000000] }) self.assertDictEqual(force_field["Dihedral Coeffs"][-1], { "id": 21, "coeffs": [0.010000, 3, 0, 1.000000] }) for c in force_field["Dihedral Coeffs"][-1]["coeffs"][1:2]: self.assertIsInstance(c, int) self.assertDictEqual(force_field["Improper Coeffs"][-1], { "id": 2, "coeffs": [20.000000, 0.000000] }) self.assertDictEqual( peptide.atoms[-1], { "id": 2004, "molecule-ID": 641, "type": 14, "q": 0.417, "x": 56.55074, "y": 49.75049, "z": 48.61854, "nx": 1, "ny": 1, "nz": 1 }) self.assertDictEqual(peptide.velocities[-1], { "id": 2004, "velocity": [-0.010076, -0.005729, -0.026032] }) self.assertDictEqual(topology["Bonds"][-1], { "id": 1365, "type": 18, "bond": [2002, 2003] }) self.assertDictEqual(topology["Angles"][-1], { "id": 786, "type": 31, "angle": [2003, 2002, 2004] }) self.assertDictEqual(topology["Dihedrals"][-1], { "id": 207, "type": 3, "dihedral": [64, 79, 80, 82] }) self.assertDictEqual(topology["Impropers"][-1], { "id": 12, "type": 2, "improper": [79, 64, 80, 81] }) # box_tilt and another atom_style quartz = self.quartz np.testing.assert_array_equal(quartz.box_tilt, [-2.456700, 0.0, 0.0]) self.assertDictEqual(quartz.atoms[-1], { "id": 9, "type": 2, "x": 1.375998, "y": -1.140800, "z": -2.443511 }) # sort_id nvt = LammpsData.from_file(filename=os.path.join(test_dir, "nvt.data"), sort_id=True) atom_id = random.randint(1, 648) self.assertEqual(nvt.atoms[atom_id - 1]["id"], atom_id) # PairIJ Coeffs section virus = LammpsData.from_file(filename=os.path.join( test_dir, "virus.data"), atom_style="angle") n = len(virus.masses) pairij = virus.force_field["PairIJ Coeffs"] self.assertEqual(len(pairij), n * (n + 1) / 2) self.assertDictEqual(pairij[-1], { "id1": 4, "id2": 4, "coeffs": [1, 1, 1.1225] })
def test_from_file(self): self.lammps_data.write_data_file( os.path.join(test_dir, "lammps_data.dat")) lammps_data = LammpsData.from_file( os.path.join(test_dir, "lammps_data.dat")) self.assertEqual(str(lammps_data), str(self.lammps_data))
def test_from_file(self): # general tests pep = self.peptide # header stats and Nos. of columns self.assertEqual(pep.masses.shape, (14, 1)) self.assertEqual(pep.atoms.shape, (2004, 9)) self.assertListEqual(list(pep.atoms.columns), ["molecule-ID", "type", "q", "x", "y", "z", "nx", "ny", "nz"]) topo = pep.topology self.assertEqual(topo["Bonds"].shape, (1365, 3)) self.assertEqual(topo["Angles"].shape, (786, 4)) self.assertEqual(topo["Dihedrals"].shape, (207, 5)) self.assertEqual(topo["Impropers"].shape, (12, 5)) ff = pep.force_field self.assertEqual(ff["Pair Coeffs"].shape, (14, 4)) self.assertEqual(ff["Bond Coeffs"].shape, (18, 2)) self.assertEqual(ff["Angle Coeffs"].shape, (31, 4)) self.assertEqual(ff["Dihedral Coeffs"].shape, (21, 4)) self.assertEqual(ff["Improper Coeffs"].shape, (2, 2)) # header box np.testing.assert_array_equal(pep.box_bounds, [[36.840194, 64.211560], [41.013691, 68.385058], [29.768095, 57.139462]]) # body self.assertEqual(pep.masses.at[7, "mass"], 12.0110) self.assertEqual(ff["Pair Coeffs"].at[9, "coeff3"], 0.152100) self.assertEqual(ff["Bond Coeffs"].at[5, "coeff2"], 1.430000) self.assertEqual(ff["Angle Coeffs"].at[21, "coeff2"], 120.000000) self.assertEqual(ff["Dihedral Coeffs"].at[10, "coeff1"], 0.040000) self.assertEqual(ff["Improper Coeffs"].at[2, "coeff1"], 20.000000) self.assertEqual(pep.atoms.at[29, "molecule-ID"], 1) self.assertEqual(pep.atoms.at[29, "type"], 7) self.assertEqual(pep.atoms.at[29, "q"], -0.020) self.assertAlmostEqual(pep.atoms.at[29, "x"], 42.96709) self.assertEqual(pep.atoms.at[1808, "molecule-ID"], 576) self.assertEqual(pep.atoms.at[1808, "type"], 14) self.assertAlmostEqual(pep.atoms.at[1808, "y"], 58.64352) self.assertEqual(pep.atoms.at[1808, "nx"], -1) self.assertAlmostEqual(pep.velocities.at[527, "vz"], -0.010889) self.assertEqual(topo["Bonds"].at[47, "type"], 8) self.assertEqual(topo["Bonds"].at[47, "atom2"], 54) self.assertEqual(topo["Bonds"].at[953, "atom1"], 1384) self.assertEqual(topo["Angles"].at[105, "type"], 19) self.assertEqual(topo["Angles"].at[105, "atom3"], 51) self.assertEqual(topo["Angles"].at[376, "atom2"], 772) self.assertEqual(topo["Dihedrals"].at[151, "type"], 14) self.assertEqual(topo["Dihedrals"].at[151, "atom4"], 51) self.assertEqual(topo["Impropers"].at[4, "atom4"], 32) # class 2 and comments ethane = self.ethane self.assertEqual(ethane.masses.shape, (2, 1)) self.assertEqual(ethane.atoms.shape, (8, 9)) class2 = ethane.force_field self.assertEqual(class2["Pair Coeffs"].shape, (2, 2)) self.assertEqual(class2["Bond Coeffs"].shape, (2, 4)) self.assertEqual(class2["Angle Coeffs"].shape, (2, 4)) self.assertEqual(class2["Dihedral Coeffs"].shape, (1, 6)) self.assertEqual(class2["Improper Coeffs"].shape, (2, 2)) self.assertEqual(class2["BondBond Coeffs"].at[2, "coeff3"], 1.1010) self.assertEqual(class2["BondAngle Coeffs"].at[2, "coeff4"], 1.1010) self.assertEqual(class2["AngleAngle Coeffs"].at[2, "coeff6"], 107.6600) self.assertEqual(class2["AngleAngle Coeffs"].at[2, "coeff6"], 107.6600) self.assertEqual(class2["AngleAngleTorsion Coeffs"].at[1, "coeff3"], 110.7700) self.assertEqual(class2["EndBondTorsion Coeffs"].at[1, "coeff8"], 1.1010) self.assertEqual(class2["MiddleBondTorsion Coeffs"].at[1, "coeff4"], 1.5300) self.assertEqual(class2["BondBond13 Coeffs"].at[1, "coeff3"], 1.1010) self.assertEqual(class2["AngleTorsion Coeffs"].at[1, "coeff8"], 110.7700) # box_tilt and another atom_style quartz = self.quartz np.testing.assert_array_equal(quartz.box_tilt, [-2.456700, 0.0, 0.0]) self.assertListEqual(list(quartz.atoms.columns), ["type", "x", "y", "z"]) self.assertAlmostEqual(quartz.atoms.at[7, "x"], 0.299963) # PairIJ Coeffs section virus = self.virus pairij = virus.force_field["PairIJ Coeffs"] self.assertEqual(pairij.at[7, "id1"], 3) self.assertEqual(pairij.at[7, "id2"], 3) self.assertEqual(pairij.at[7, "coeff2"], 2.1) # sort_id nvt = LammpsData.from_file(filename=os.path.join(test_dir, "nvt.data"), sort_id=True) atom_id = random.randint(1, 648) self.assertEqual(nvt.atoms.loc[atom_id].name, atom_id)