def MakesGauInputs(mol_file, dihed_atoms_file, w, num_conform=19):
    """
    Creates Gaussian input files in its own folder for mol_file structues that
    freezes the central angle at iterations of 180/num_conform degrees. This
    function requires Gaussian output file of molecule in question and file
    with dihedral atoms to be in the current working directory.
    """

    molecule_name = mol_file.split('/')[-1][:-12]
    mol_pymat = Molecule.from_file(mol_file)
    molecule = pmgmol_to_rdmol(mol_pymat)[0]

    with open(dihed_atoms_file, 'r') as fn:
        data = fn.readlines()
        dihedral1 = data[0].split(',')[0]
        dihedral2 = data[0].split(',')[1]

    d1atom1_num = int(dihedral1.split()[0])
    d1atom2_num = int(dihedral1.split()[1])
    d1atom3_num = int(dihedral1.split()[2])
    d1atom4_num = int(dihedral1.split()[3])

    phi = np.linspace(start=0, stop=180, num=num_conform)
    for P in phi:
        dir_name = "{}/{}_{:.0f}deg/".format(os.getcwd(), molecule_name, P)
        os.mkdir(dir_name)
        file_name = "{}/{}_{:.0f}deg".format(dir_name, molecule_name, P)

        SetDihedralDeg(molecule.GetConformer(), d1atom1_num, d1atom2_num,
                       d1atom3_num, d1atom4_num, P)
        with open(dir_name + "temp.xyz", 'w+') as fout:
            fout.write(str(MolToXYZBlock(molecule)))
        mol = Molecule.from_file(dir_name + 'temp.xyz')
        os.remove(dir_name + 'temp.xyz')
        gau = GaussianInput(mol=mol,
                            charge=0,
                            spin_multiplicity=1,
                            functional='uLC-wPBE',
                            basis_set='cc-pVDZ',
                            route_parameters={
                                "iop(3/107={}, 3/108={})".format(w, w): "",
                                "opt": "modredundant"
                            },
                            link0_parameters={
                                '%mem': '5GB',
                                '%chk':
                                '{}.chk'.format(file_name.split('/')[-1])
                            })
        gjf_file = gau.write_file(dir_name + 'temp.gjf')

        with open(dir_name + 'temp.gjf') as temp:
            lines = temp.readlines()
        os.remove(dir_name + 'temp.gjf')
        with open(file_name + '.gjf', 'w') as gjf:
            gjf.writelines([item for item in lines[:-2]])
            gjf.write("D * {} {} * F\n\n".format(d1atom2_num + 1,
                                                 d1atom3_num + 1))

    print(
        "Torsion Gaussian input files for {} finsihed!".format(molecule_name))
def MakeJSON(mol_dir,omega_file,json_file):
    """
    For a molecule rotation directory, mol_dir, this finds the energy, xyz, and
    degree of rotation and places those into  json_file.
    """
    mol_name = str(mol_dir.split('/')[-1])
    energy = 0
    mol_xyz = 0
    try:
    # if 0 == 0:
        log_fn = [x for x in os.listdir(mol_dir) if x.endswith('opt_0.log')][0]
        log_path = os.path.join(mol_dir,log_fn)
        mol = GaussianOutput(log_path)
        if mol.properly_terminated:
            num_electrons = mol.electrons[0]
            eigens = list(mol.eigenvalues.values())[0]
            h**o = eigens[num_electrons - 1] * 27.2114
            lumo = eigens[num_electrons] * 27.2114
            homo_lumo_gap = lumo - h**o
            pymat_mol = Molecule.from_file(log_path)
            smi_mol = pmgmol_to_rdmol(pymat_mol)[1]
            with open(omega_file,'r') as fn:
                omega_data = fn.readlines()[-2].split()[1]
                omega = "0{}".format(omega_data.split('.')[1])
            normal = 1
        else:
            normal = 0
            print("Error. wtuning for did not properly terminate for {}".format(mol_name))
    except Exception as e:
        normal = 0
        print("Error. Data NOT collected for {}. Energy calculations for dihedral rotations may not have finished!".format(mol_name))
        print(e)
    if normal == 1:
        json_data = {
        "molecule_name" : mol_name,
        "smiles" : smi_mol,
        "tuned_omega" : omega,
        "h**o" : h**o,
        "lumo" : lumo,
        "homo_lumo_gap" : homo_lumo_gap
        }
        with open(json_file,'w+') as fn:
            json.dump(json_data, fn)
            print("Data collected for {}".format(mol_name))
    else:
        pass
    try:
        json_file.close()
        omega_file.close()
    except:
        pass
Beispiel #3
0
def make_json(mol_dir, json_file, omega_file=None):
    """
    For a molecule directory, mol_dir, this finds the molecule_name, smiles, and tuned omega
    for the polymer. It then finds the optimized structures, energies, homos, lumos, and
    runtimes for each degree of rotation and places those into a json_file.
    """
    mol_name = mol_dir.split('/')[-1]
    xyz_dict, energy_dict, homo_dict, lumo_dict, runtime_dict = {}, {}, {}, {}, {}
    mol_smiles, omega = None, None
    if os.path.isfile(omega_file):
        with open(omega_file, 'r') as fn:
            try:
                omega_data = fn.readlines()[-1].split()[1]
                omega = "0{}".format(omega_data.split('.')[1])
            except IndexError:
                print('Error. wtuning for {} may not have finished'.format(
                    mol_name))
                return None
    deg_folders = [
        deg for deg in os.listdir(mol_dir)
        if os.path.isdir(os.path.join(mol_dir, deg))
    ]
    for deg in deg_folders:
        dpath = os.path.join(mol_dir, deg)
        if os.path.isdir(dpath):
            degree = str((deg.split('_')[-1])[:-3])
            try:
                log_fn = [
                    x for x in os.listdir(dpath) if x.endswith('deg.log')
                ][0]
                log_path = os.path.join(dpath, log_fn)
            except IndexError:
                print("Error. No log file for {} at {} degrees.".format(
                    mol_name, degree))
                continue
            if check_normal_optimization(log_path):
                runtime = runtime_from_log(log_path)
                mol = IMolecule.from_file(log_path)
                mol_xyz = mol.to(fmt="xyz")

                out_mol = GaussianOutput(log_path)
                num_electrons = out_mol.electrons[0]
                eigens = list(out_mol.eigenvalues.values())[0]
                h**o = eigens[num_electrons - 1] * 27.2114
                lumo = eigens[num_electrons] * 27.2114
                energy = out_mol.final_energy * 27.2114
                if mol_smiles is None:
                    mol_smiles = pmgmol_to_rdmol(mol)[1]
            else:
                print(
                    "Error. Optimization did not properly terminate for {} at {} degrees."
                    .format(mol_name, degree))
                continue
            xyz_dict[degree] = mol_xyz
            energy_dict[degree] = energy
            homo_dict[degree] = h**o
            lumo_dict[degree] = lumo
            runtime_dict[degree] = runtime
    json_data = {
        # Polymer data
        "molecule_name": mol_name,
        "smiles": mol_smiles,
        "tuned_omega": omega,
        # Rotation dictionaries
        "structures": xyz_dict,
        "energies": energy_dict,
        "homos": homo_dict,
        "lumos": lumo_dict,
        "runtimes": runtime_dict
    }

    write_json(json_data, json_file)
    print("Data collected for {}".format(mol_name))
Beispiel #4
0
from ocelot.schema.conformer import Molecule
from ocelot.routines.conformerparser import pmgmol_to_rdmol
from ocelot.schema.rdfunc import RdFunc

# rdkit is quite tricky in handling nitro groups
# see https://github.com/rdkit/rdkit/issues/1979
# and http://www.rdkit.org/docs/RDKit_Book.html#molecular-sanitization
m = Molecule.from_file('m.xyz')
rm, smiles = pmgmol_to_rdmol(m)
RdFunc.draw_mol(rm, 'm.ps')
print(rm)