10
1
mirror of https://github.com/pfloos/quack synced 2024-12-22 20:34:46 +01:00

add SQLite database

This commit is contained in:
Abdallah Ammar 2024-08-28 01:06:31 +02:00
parent 4b03a45e58
commit 1a195f90cc
3 changed files with 157 additions and 29 deletions

42
tests/create_database.py Normal file
View File

@ -0,0 +1,42 @@
import sqlite3
from molecule import Molecule
from molecule import save_molecules_to_json, load_molecules_from_json
from molecule import create_database, add_molecule_to_db
molecules = [
Molecule(
name="H2O",
multiplicity=1,
geometry=[
{"element": "O", "x": 0.000000, "y": 0.000000, "z": 0.117790},
{"element": "H", "x": 0.000000, "y": 0.755453, "z": -0.471161},
{"element": "H", "x": 0.000000, "y": -0.755453, "z": -0.471161}
],
energies={
"RHF": {
"cc-pvdz": -76.0267058009,
"cc-pvtz": -76.0570239304,
"cc-pvqz": -76.0646816616
},
}
),
]
# Save molecules to JSON
save_molecules_to_json(molecules, 'molecules.json')
# Load molecules from JSON
loaded_molecules = load_molecules_from_json('molecules.json')
print(loaded_molecules)
# Create a database and add molecules
db_name = 'molecules.db'
create_database(db_name)
for molecule in molecules:
add_molecule_to_db(db_name, molecule)

86
tests/molecule.py Normal file
View File

@ -0,0 +1,86 @@
import json
import sqlite3
class Molecule:
def __init__(self, name, multiplicity, geometry, energies):
self.name = name
self.multiplicity = multiplicity
self.geometry = geometry # List of tuples (atom, x, y, z)
self.energies = energies # Dictionary of dictionaries: {method: {basis: energy}}
def get_energy(self, method, basis):
"""Retrieve energy for a specific method and basis set."""
return self.energies.get(method, {}).get(basis, None)
def to_dict(self):
return {
"name": self.name,
"multiplicity": self.multiplicity,
"geometry": self.geometry,
"energies": self.energies,
}
@staticmethod
def from_dict(data):
return Molecule(
name=data["name"],
multiplicity=data["multiplicity"],
geometry=data["geometry"],
energies=data["energies"]
)
def save_molecules_to_json(molecules, filename):
with open(filename, 'w') as f:
json_data = [molecule.to_dict() for molecule in molecules]
json.dump(json_data, f, indent=4)
def load_molecules_from_json(filename):
with open(filename, 'r') as f:
json_data = json.load(f)
return [Molecule.from_dict(data) for data in json_data]
def create_database(db_name):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS molecules
(name TEXT, multiplicity INTEGER, geometry TEXT, energies TEXT)''')
conn.commit()
conn.close()
def add_molecule_to_db(db_name, molecule):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
geometry_str = json.dumps(molecule.geometry)
energies_str = json.dumps(molecule.energies)
cursor.execute("INSERT INTO molecules VALUES (?, ?, ?, ?)",
(molecule.name, molecule.multiplicity, geometry_str, energies_str))
conn.commit()
conn.close()
def get_molecules_from_db(db_name):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
cursor.execute("SELECT name, multiplicity, geometry, energies FROM molecules")
rows = cursor.fetchall()
molecules = []
for row in rows:
name, multiplicity, geometry_str, energies_str = row
geometry = json.loads(geometry_str)
energies = json.loads(energies_str) # energies is a dictionary of dictionaries
molecules.append(Molecule(name, multiplicity, geometry, energies))
conn.close()
return molecules
def write_geometry_to_xyz(molecule, filename):
with open(filename, 'w') as f:
# First line: number of atoms
f.write(f"{len(molecule.geometry)}\n")
# Second line: empty comment line
f.write("\n")
# Remaining lines: atom positions
for atom, x, y, z in molecule.geometry:
f.write(f"{atom} {x:.6f} {y:.6f} {z:.6f}\n")

View File

@ -5,6 +5,9 @@ import subprocess
import platform import platform
from datetime import datetime from datetime import datetime
from molecule import get_molecules_from_db
current_date = datetime.now() current_date = datetime.now()
quack_root = os.getenv('QUACK_ROOT') quack_root = os.getenv('QUACK_ROOT')
@ -65,15 +68,6 @@ list_opt = [hf_opt, mp_opt, cc_opt, tda_opt, gf_opt, gw_opt, gt_opt, acfdt_opt,
# --- # ---
mol_multip = {
"Ne": 1,
"H2O": 1,
}
list_basis = ["cc-pvdz", "cc-pvtz", "cc-pvqz"]
# ---
class class_RHF: class class_RHF:
def gen_input(): def gen_input():
@ -163,30 +157,36 @@ def main():
work_path.mkdir(parents=True, exist_ok=True) work_path.mkdir(parents=True, exist_ok=True)
print(f"Directory '{work_path}' created.\n") print(f"Directory '{work_path}' created.\n")
for methd in ["RHF", "UHF", "GHF", "ROHF"]: for mol in molecules:
work_methd = Path('{}/{}'.format(work_path, methd)) mol_name = mol.name
if not work_methd.exists(): mol_mult = mol.multiplicity
work_methd.mkdir(parents=True, exist_ok=True)
print(f"Directory '{work_methd}' created.\n")
class_methd = class_map.get(methd)
# create input files for methd in list_methd:
class_methd.gen_input()
for mol in mol_multip: if methd not in mol.energies:
print(f"Method {methd} does not exist for {mol_name}.")
continue
multip = mol_multip[mol] for bas, _ in mol.energies[methd].items():
for bas in list_basis: work_methd = Path('{}/{}'.format(work_path, methd))
if not work_methd.exists():
work_methd.mkdir(parents=True, exist_ok=True)
print(f"Directory '{work_methd}' created.\n")
file_out = "{}/{}/{}_{}_{}.out".format(work_path, methd, mol, multip, bas) class_methd = class_map.get(methd)
print(" testing {} for {}@{} (2S+1 = {})".format(methd, mol, bas, multip)) # create input files
class_methd.gen_input()
file_out = "{}/{}/{}_{}_{}.out".format(work_path, methd, mol_name, mol_mult, bas)
print(" testing {} for {}@{} (2S+1 = {})".format(methd, mol_name, bas, mol_mult))
print(" file_out: {}".format(file_out)) print(" file_out: {}".format(file_out))
class_methd.run_job(file_out, mol, bas, multip) class_methd.run_job(file_out, mol_name, bas, mol_mult)
print("\n") print("\n")
print("\n\n") print("\n\n")
@ -195,10 +195,10 @@ def main():
print("\n\n\n") print("\n\n\n")
db_name = 'molecules.db'
molecules = get_molecules_from_db(db_name)
list_methd = ["RHF", "UHF", "GHF", "ROHF"]
main() main()