|
| 1 | +#!/usr/bin/env python3 |
| 2 | + |
| 3 | +import numpy as np |
| 4 | +import pandas as pd |
| 5 | +from rdkit import Chem |
| 6 | +from rdkit.Chem import rdMolDescriptors |
| 7 | +from unidecode import unidecode |
| 8 | + |
| 9 | +from fairmd.lipids.experiment import ExperimentCollection, OPExperiment |
| 10 | + |
| 11 | +H5_MASTER = "exp-op-dataset.h5" |
| 12 | + |
| 13 | + |
| 14 | +def store_to_hdf5(df: pd.DataFrame, e: OPExperiment, lipid_name: str): |
| 15 | + _mcontent = e.membrane_composition(basis="molar") |
| 16 | + mcontent = {"name": [], "inchikey": [], "fraction": []} |
| 17 | + for lname, frac in _mcontent.items(): |
| 18 | + k = lname |
| 19 | + ik = e.lipids[lname].metadata["bioschema_properties"]["inChIKey"] |
| 20 | + mcontent["name"] += [k] |
| 21 | + mcontent["inchikey"] += [ik] |
| 22 | + mcontent["fraction"] += [frac] |
| 23 | + hydration = e.get_hydration() |
| 24 | + scontent = e.solution_composition(basis="molar") |
| 25 | + temperature = e["TEMPERATURE"] |
| 26 | + inchikey = e.lipids[lipid_name].metadata["bioschema_properties"]["inChIKey"] |
| 27 | + smiles = e.lipids[lipid_name].metadata["bioschema_properties"]["smiles"] |
| 28 | + # store all vars and df to the HDF5 table |
| 29 | + group = "E" + unidecode(e.exp_id).replace("-", "_").replace("/", "_").replace(".", "") + "__" + lipid_name |
| 30 | + |
| 31 | + with pd.HDFStore(H5_MASTER, "a") as store: |
| 32 | + # DataFrame table |
| 33 | + store.put(f"{group}/op_values", df, format="table", data_columns=True) |
| 34 | + # Metadata attributes |
| 35 | + op_storer = store.get_storer(f"{group}/op_values") |
| 36 | + op_storer.attrs["inchikey"] = inchikey |
| 37 | + op_storer.attrs["smiles"] = smiles |
| 38 | + |
| 39 | + # Metadata attributes |
| 40 | + store.put(f"{group}/sample_table", pd.DataFrame(mcontent), format="table", data_columns=True) |
| 41 | + sample_storer = store.get_storer(f"{group}/op_values") |
| 42 | + sample_storer.attrs["temperature"] = temperature |
| 43 | + sample_storer.attrs["hydration"] = hydration |
| 44 | + sample_storer.attrs["solution"] = ", ".join([f"{k:<25} {v * 100:>6.1f}%" for k, v in sorted(scontent.items())]) |
| 45 | + |
| 46 | + |
| 47 | +def by_c_uname(opdict: dict, uname: str) -> dict: |
| 48 | + """Return only OP vals of named heavy atoms. Sorted by val.""" |
| 49 | + res = [] |
| 50 | + for k, v in opdict.items(): |
| 51 | + if k.split()[0] == uname: |
| 52 | + res.append(v) |
| 53 | + return sorted(res, key=lambda x: x[0]) |
| 54 | + |
| 55 | + |
| 56 | +def main() -> None: |
| 57 | + print("Generating OP datasets.") |
| 58 | + ee = ExperimentCollection.load_from_data("OPExperiment") |
| 59 | + for e in ee: |
| 60 | + print(e) |
| 61 | + for lname, opdict in e.data.items(): |
| 62 | + mol = e.lipids[lname] |
| 63 | + smiles = mol.metadata["bioschema_properties"]["smiles"] |
| 64 | + rdmol = Chem.MolFromSmiles("CCO") # Ethanol |
| 65 | + n_heavy_atoms = rdMolDescriptors.CalcNumHeavyAtoms(rdmol) |
| 66 | + print(smiles) |
| 67 | + smi2uname = {} |
| 68 | + for uname, aprops in mol.mapping_dict.items(): |
| 69 | + if "SMILEIDX" in aprops: |
| 70 | + smid = int(aprops["SMILEIDX"]) |
| 71 | + smi2uname[smid] = uname |
| 72 | + if not smi2uname: |
| 73 | + # NO SMILEIDX. Cannot store. |
| 74 | + continue |
| 75 | + smi2uname = dict(sorted(smi2uname.items())) |
| 76 | + df = pd.DataFrame( |
| 77 | + { |
| 78 | + "id": np.full(len(opdict), -1, dtype=np.int64), # int64, init NaN |
| 79 | + "val": np.full(len(opdict), np.nan), |
| 80 | + "err": np.full(len(opdict), np.nan), |
| 81 | + } |
| 82 | + ) |
| 83 | + cur_row = 0 |
| 84 | + for id_, uname in smi2uname.items(): |
| 85 | + for opdict_row in by_c_uname(opdict, uname): |
| 86 | + if cur_row >= len(df): |
| 87 | + break |
| 88 | + df.at[cur_row, "id"] = id_ |
| 89 | + df.at[cur_row, "val"] = opdict_row[0] |
| 90 | + df.at[cur_row, "err"] = 0.02 if len(opdict_row) == 1 else opdict_row[1] |
| 91 | + cur_row += 1 |
| 92 | + # now, we are ready to store to HDF5 |
| 93 | + store_to_hdf5(df, e, lname) |
| 94 | + |
| 95 | + |
| 96 | +if __name__ == "__main__": |
| 97 | + main() |
0 commit comments