{ "cells": [ { "cell_type": "markdown", "id": "c68ca2c1-a940-4eda-9ee4-1e0660e7cc67", "metadata": {}, "source": [ "## Create Example Jobs" ] }, { "cell_type": "markdown", "id": "ffa8d650-61fb-4b8f-8e60-38348d96cf51", "metadata": {}, "source": [ "To begin with, we create a variety of AMS jobs with different settings, tasks, engines and calculation types.\n", "\n", "This allows us to generate diverse example single point/geometry optimization calculations with DFTB, ADF etc." ] }, { "cell_type": "code", "execution_count": 1, "id": "d2c2776a-5100-41c7-a4d7-3a7b308b9a59", "metadata": {}, "outputs": [], "source": [ "from scm.plams import from_smiles, AMSJob, PlamsError, Settings, Molecule, Atom\n", "from scm.base import ChemicalSystem\n", "from scm.input_classes.drivers import AMS\n", "from scm.input_classes.engines import DFTB\n", "from scm.utils.conversions import plams_molecule_to_chemsys\n", "\n", "\n", "def example_job_dftb(smiles, task, use_chemsys=False):\n", " # Generate molecule from smiles\n", " mol = from_smiles(smiles)\n", " if use_chemsys:\n", " mol = plams_molecule_to_chemsys(mol)\n", "\n", " # Set up calculation settings using PISA\n", " sett = Settings()\n", " sett.runscript.nproc = 1\n", " driver = AMS()\n", " driver.Task = task\n", " driver.Engine = DFTB()\n", " sett.input = driver\n", " return AMSJob(molecule=mol, settings=sett, name=\"dftb\")\n", "\n", "\n", "def example_job_adf(smiles, task, basis, gga=None, use_chemsys=False):\n", " # Generate molecule from smiles\n", " mol = from_smiles(smiles)\n", " if use_chemsys:\n", " mol = plams_molecule_to_chemsys(mol)\n", "\n", " # Set up calculation settings using standard settings\n", " sett = Settings()\n", " sett.runscript.nproc = 1\n", " sett.input.AMS.Task = task\n", " sett.input.ADF.Basis.Type = basis\n", " if gga:\n", " sett.input.ADF.XC.GGA = gga\n", " return AMSJob(molecule=mol, settings=sett, name=\"adf\")\n", "\n", "\n", "def example_job_neb(iterations, use_chemsys=False):\n", " # Set up molecules\n", " main_molecule = Molecule()\n", " main_molecule.add_atom(Atom(symbol=\"C\", coords=(0, 0, 0)))\n", " main_molecule.add_atom(Atom(symbol=\"N\", coords=(1.18, 0, 0)))\n", " main_molecule.add_atom(Atom(symbol=\"H\", coords=(2.196, 0, 0)))\n", " final_molecule = main_molecule.copy()\n", " final_molecule.atoms[1].x = 1.163\n", " final_molecule.atoms[2].x = -1.078\n", "\n", " mol = {\"\": main_molecule, \"final\": final_molecule}\n", "\n", " if use_chemsys:\n", " mol = {k: plams_molecule_to_chemsys(v) for k, v in mol.items()}\n", "\n", " # Set up calculation settings\n", " sett = Settings()\n", " sett.runscript.nproc = 1\n", " sett.input.ams.Task = \"NEB\"\n", " sett.input.ams.NEB.Images = 9\n", " sett.input.ams.NEB.Iterations = iterations\n", " sett.input.DFTB\n", "\n", " return AMSJob(molecule=mol, settings=sett, name=\"neb\")" ] }, { "cell_type": "markdown", "id": "aec4b300-ba2f-4883-bb72-a3dd303f4d22", "metadata": {}, "source": [ "Now, we create a selection of jobs covering different systems and settings:" ] }, { "cell_type": "code", "execution_count": 2, "id": "b41d6fac-5199-4e2f-987c-8d31e37b20e9", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[23.03|10:47:05] JOB dftb STARTED\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] JOB dftb STARTED\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] Renaming job adf to adf.002\n", "[23.03|10:47:05] JOB dftb STARTED\n", "[23.03|10:47:05] Renaming job dftb to dftb.002\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] Renaming job adf to adf.003\n", "[23.03|10:47:05] JOB dftb RUNNING\n", "[23.03|10:47:05] JOB adf STARTED\n", "[23.03|10:47:05] Renaming job adf to adf.004\n", "[23.03|10:47:05] JOB adf RUNNING\n", "[23.03|10:47:05] JOB adf.004 RUNNING\n", "[23.03|10:47:05] Renaming job dftb to dftb.003\n", "[23.03|10:47:05] JOB adf.002 RUNNING\n", "[23.03|10:47:05] Renaming job adf to adf.005\n", "[23.03|10:47:05] JOB dftb.002 RUNNING\n", "[23.03|10:47:05] JOB adf.005 RUNNING\n", "[23.03|10:47:05] JOB dftb.003 RUNNING\n", "[23.03|10:47:05] JOB adf.003 RUNNING\n", "[23.03|10:47:05] JOB dftb FINISHED\n", "[23.03|10:47:05] JOB dftb.003 FINISHED\n", "[23.03|10:47:06] JOB dftb.002 FINISHED\n", "[23.03|10:47:06] JOB dftb.002 SUCCESSFUL\n", "[23.03|10:47:06] JOB dftb SUCCESSFUL\n", "[23.03|10:47:06] JOB dftb.003 SUCCESSFUL\n", "[23.03|10:47:06] JOB dftb STARTED\n", "[23.03|10:47:06] JOB adf STARTED\n", "[23.03|10:47:06] Renaming job adf to adf.006\n", "[23.03|10:47:06] JOB adf.006 RUNNING\n", "[23.03|10:47:06] Renaming job dftb to dftb.004\n", "[23.03|10:47:06] JOB adf STARTED\n", "[23.03|10:47:06] Renaming job adf to adf.007\n", "[23.03|10:47:07] JOB adf.007 RUNNING\n", "[23.03|10:47:07] JOB dftb.004 RUNNING\n", "[23.03|10:47:07] JOB dftb.004 FINISHED\n", "[23.03|10:47:07] JOB dftb.004 SUCCESSFUL\n", "[23.03|10:47:07] Renaming job adf to adf.008\n", "[23.03|10:47:07] JOB adf.008 RUNNING\n", "[23.03|10:47:07] JOB dftb STARTED\n", "[23.03|10:47:09] JOB adf.005 FINISHED\n", "[23.03|10:47:09] JOB adf.005 SUCCESSFUL\n", "[23.03|10:47:09] Renaming job dftb to dftb.005\n", "[23.03|10:47:09] JOB adf STARTED\n", "[23.03|10:47:09] JOB dftb.005 RUNNING\n", "[23.03|10:47:10] JOB dftb.005 FINISHED\n", "[23.03|10:47:10] JOB dftb.005 SUCCESSFUL\n", "[23.03|10:47:10] JOB adf STARTED\n", "[23.03|10:47:10] Renaming job adf to adf.009\n", "[23.03|10:47:10] JOB adf.009 RUNNING\n", "[23.03|10:47:12] JOB adf.002 FINISHED\n", "[23.03|10:47:12] JOB adf.002 SUCCESSFUL\n", "[23.03|10:47:12] Renaming job adf to adf.010\n", "[23.03|10:47:12] JOB dftb STARTED\n", "[23.03|10:47:12] JOB adf.010 RUNNING\n", "[23.03|10:47:13] JOB adf.009 FINISHED\n", "[23.03|10:47:13] JOB adf.009 SUCCESSFUL\n", "[23.03|10:47:13] Renaming job dftb to dftb.006\n", "[23.03|10:47:13] JOB adf STARTED\n", "[23.03|10:47:13] JOB dftb.006 RUNNING\n", "[23.03|10:47:13] JOB dftb.006 FINISHED\n", "[23.03|10:47:14] JOB dftb.006 SUCCESSFUL\n", "[23.03|10:47:14] JOB adf STARTED\n", "[23.03|10:47:14] Renaming job adf to adf.011\n", "[23.03|10:47:14] JOB adf.011 RUNNING\n", "[23.03|10:47:14] JOB adf.006 FINISHED\n", "[23.03|10:47:14] JOB adf.006 SUCCESSFUL\n", "[23.03|10:47:14] Renaming job adf to adf.012\n", "[23.03|10:47:14] JOB dftb STARTED\n", "[23.03|10:47:14] JOB adf.012 RUNNING\n", "[23.03|10:47:16] JOB adf.010 FINISHED\n", "[23.03|10:47:16] JOB adf.010 SUCCESSFUL\n", "[23.03|10:47:16] Renaming job dftb to dftb.007\n", "[23.03|10:47:16] JOB adf STARTED\n", "[23.03|10:47:16] JOB dftb.007 RUNNING\n", "[23.03|10:47:16] JOB dftb.007 FINISHED\n", "[23.03|10:47:17] JOB dftb.007 SUCCESSFUL\n", "[23.03|10:47:17] Renaming job adf to adf.013\n", "[23.03|10:47:17] JOB adf STARTED\n", "[23.03|10:47:17] JOB adf.013 RUNNING\n", "[23.03|10:47:18] JOB adf.007 FINISHED\n", "[23.03|10:47:18] JOB adf.007 SUCCESSFUL\n", "[23.03|10:47:18] JOB dftb STARTED\n", "[23.03|10:47:18] Renaming job adf to adf.014\n", "[23.03|10:47:18] JOB adf.014 RUNNING\n", "[23.03|10:47:20] JOB adf.011 FINISHED\n", "[23.03|10:47:20] JOB adf.011 SUCCESSFUL\n", "[23.03|10:47:20] JOB adf STARTED\n", "[23.03|10:47:20] Renaming job dftb to dftb.008\n", "[23.03|10:47:20] JOB dftb.008 RUNNING\n", "[23.03|10:47:20] JOB dftb.008 FINISHED\n", "[23.03|10:47:21] JOB dftb.008 SUCCESSFUL\n", "[23.03|10:47:21] JOB adf STARTED\n", "[23.03|10:47:21] Renaming job adf to adf.015\n", "[23.03|10:47:21] JOB adf.015 RUNNING\n", "[23.03|10:47:22] JOB adf FINISHED\n", "[23.03|10:47:22] JOB adf SUCCESSFUL\n", "[23.03|10:47:22] JOB neb STARTED\n", "[23.03|10:47:22] Renaming job adf to adf.016\n", "[23.03|10:47:22] JOB adf.016 RUNNING\n", "[23.03|10:47:24] JOB adf.012 FINISHED\n", "[23.03|10:47:24] JOB adf.012 SUCCESSFUL\n", "[23.03|10:47:24] JOB neb RUNNING\n", "[23.03|10:47:24] JOB neb STARTED\n", "[23.03|10:47:24] JOB adf.013 FINISHED\n", "[23.03|10:47:24] JOB adf.013 SUCCESSFUL\n", "[23.03|10:47:24] Waiting for job adf.003 to finish\n", "[23.03|10:47:24] Renaming job neb to neb.002\n", "[23.03|10:47:24] JOB neb.002 RUNNING\n", "[23.03|10:47:25] JOB neb FINISHED\n", "[23.03|10:47:25] Job neb reported errors. Please check the output\n", "[23.03|10:47:25] JOB neb FAILED\n", "[23.03|10:47:25] Job neb reported errors. Please check the output\n", "[23.03|10:47:25] Error message for job neb was:\n", "\tNEB optimization did NOT converge\n", "[23.03|10:47:25] Job neb reported errors. Please check the output\n", "[23.03|10:47:25] Job neb reported errors. Please check the output\n", "[23.03|10:47:28] JOB neb.002 FINISHED\n", "[23.03|10:47:28] JOB neb.002 SUCCESSFUL\n", "[23.03|10:47:30] JOB adf.014 FINISHED\n", "[23.03|10:47:30] JOB adf.014 SUCCESSFUL\n", "[23.03|10:47:31] JOB adf.008 FINISHED\n", "[23.03|10:47:31] JOB adf.008 SUCCESSFUL\n", "[23.03|10:47:37] JOB adf.015 FINISHED\n", "[23.03|10:47:37] JOB adf.015 SUCCESSFUL\n", "[23.03|10:47:42] JOB adf.003 FINISHED\n", "[23.03|10:47:42] JOB adf.003 SUCCESSFUL\n", "[23.03|10:47:42] Waiting for job adf.004 to finish\n", "[23.03|10:47:53] JOB adf.016 FINISHED\n", "[23.03|10:47:53] JOB adf.016 SUCCESSFUL\n", "[23.03|10:48:12] JOB adf.004 FINISHED\n", "[23.03|10:48:12] JOB adf.004 SUCCESSFUL\n" ] } ], "source": [ "from scm.plams import config, JobRunner\n", "\n", "config.default_jobrunner = JobRunner(parallel=True, maxthreads=8)\n", "\n", "smiles = [\"CC\", \"C\", \"O\", \"CO\"]\n", "tasks = [\"SinglePoint\", \"GeometryOptimization\"]\n", "engines = [\"DFTB\", \"ADF\"]\n", "jobs = []\n", "for i, s in enumerate(smiles):\n", " for j, t in enumerate(tasks):\n", " job_dftb = example_job_dftb(s, t, use_chemsys=i % 2)\n", " job_adf1 = example_job_adf(s, t, \"DZ\", use_chemsys=True)\n", " job_adf2 = example_job_adf(s, t, \"TZP\", \"PBE\")\n", " jobs += [job_dftb, job_adf1, job_adf2]\n", "\n", "job_neb1 = example_job_neb(10)\n", "job_neb2 = example_job_neb(100, use_chemsys=True)\n", "jobs += [job_neb1, job_neb2]\n", "\n", "for j in jobs:\n", " j.run()\n", "\n", "for j in jobs:\n", " j.ok()" ] }, { "cell_type": "markdown", "id": "0d7e3247-a30d-4520-975a-4619ce927d71", "metadata": {}, "source": [ "## Job Analysis" ] }, { "cell_type": "markdown", "id": "fd0ff7de-7288-4b75-a010-e63a90774ea1", "metadata": {}, "source": [ "The `JobAnalysis` tool can be used to extract data from a large number of jobs, and analyse the results." ] }, { "cell_type": "markdown", "id": "402352bc-3f54-42ae-ac94-70c56f7a7953", "metadata": {}, "source": [ "### Adding and Loading Jobs\n", "\n", "Jobs can be loaded by passing job objects directly to the `JobAnalysis`, or alternatively loading from a path. This latter option is useful for loading jobs run previously in other scripts." ] }, { "cell_type": "code", "execution_count": 3, "id": "4ebf6505-6489-4e29-af55-60b2e3d71663", "metadata": {}, "outputs": [], "source": [ "from scm.plams import JobAnalysis" ] }, { "cell_type": "code", "execution_count": 4, "id": "c60b2999-dda2-4dbd-8b37-96303407b68e", "metadata": {}, "outputs": [], "source": [ "ja = JobAnalysis(jobs=jobs)\n", "# ja = JobAnalysis(paths=[j.path for j in jobs]) # alternatively load jobs from a set of paths" ] }, { "cell_type": "markdown", "id": "dbf478f5-474c-4913-b082-b7d23030b61b", "metadata": {}, "source": [ "Additional jobs can also be added or removed after initialization of the `JobAnalysis` tool." ] }, { "cell_type": "code", "execution_count": 5, "id": "6d77b6f7-ccbd-4bac-b406-272d19386d64", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[23.03|10:58:08] JOB dftb STARTED\n", "[23.03|10:58:08] Waiting for job dftb to finish\n", "[23.03|10:58:08] Renaming job dftb to dftb.009\n", "[23.03|10:58:08] JOB dftb.009 RUNNING\n", "[23.03|10:58:08] JOB dftb.009 FINISHED\n", "[23.03|10:58:09] JOB dftb.009 SUCCESSFUL\n" ] } ], "source": [ "extra_job = example_job_dftb(\"CCC\", \"SinglePoint\")\n", "extra_job.run()\n", "extra_job.ok()\n", "\n", "ja = ja.add_job(extra_job)" ] }, { "cell_type": "markdown", "id": "fe3d90de-21eb-49c0-95c7-04036a3dbd3d", "metadata": {}, "source": [ "The loaded jobs and the initial analysis fields can be shows by displaying the `JobAnalysis` table:" ] }, { "cell_type": "code", "execution_count": 6, "id": "ff27494b-0e05-494d-96db-c25fdbc3ed53", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Path | Name | OK | Check | ErrorMsg |\n", "|---------------------------------------------------------------------------------------------------------------|----------|-------|-------|-----------------------------------|\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb | dftb | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.002 | adf.002 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf | adf | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.002 | dftb.002 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.003 | adf.003 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.004 | adf.004 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.003 | dftb.003 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.005 | adf.005 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.006 | adf.006 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.004 | dftb.004 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.007 | adf.007 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.008 | adf.008 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.005 | dftb.005 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.009 | adf.009 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.010 | adf.010 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.006 | dftb.006 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.011 | adf.011 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.012 | adf.012 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.007 | dftb.007 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.013 | adf.013 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.014 | adf.014 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.008 | dftb.008 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.015 | adf.015 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/adf.016 | adf.016 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/neb | neb | False | False | NEB optimization did NOT converge |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/neb.002 | neb.002 | True | True | None |\n", "| /Users/ormrodmorley/Documents/code/ams/amshome/userdoc/PythonExamples/job-analysis/plams_workdir.004/dftb.009 | dftb.009 | True | True | None |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja.display_table()" ] }, { "cell_type": "markdown", "id": "730eb6b2-411f-4022-840b-d686a5608055", "metadata": {}, "source": [ "### Adding and Removing Fields" ] }, { "cell_type": "markdown", "id": "998c4c13-eef6-4ee6-81f9-43b6e87a3518", "metadata": {}, "source": [ "On initialization, some analysis fields are automatically included in the analysis (`Path`, `Name`, `OK`, `Check` and `ErrorMsg`). These are useful to see which jobs were loaded, and whether they succeeded. However, one or more of these fields can be removed with the `remove_field` method." ] }, { "cell_type": "code", "execution_count": 7, "id": "7c2edc68-d31b-45de-9a93-b7b0a5cd7918", "metadata": {}, "outputs": [], "source": [ "ja = ja.remove_field(\"Path\")" ] }, { "cell_type": "markdown", "id": "43418de2-3abf-49b8-b00a-0f9d249638e2", "metadata": {}, "source": [ "A range of other common fields can be added with the `add_standard_field(s)` method. " ] }, { "cell_type": "code", "execution_count": 8, "id": "8d1151ef-5e75-485d-b7d9-2839a676226d", "metadata": {}, "outputs": [], "source": [ "ja = ja.add_standard_fields([\"Formula\", \"Smiles\", \"CPUTime\", \"SysTime\"])" ] }, { "cell_type": "markdown", "id": "7d4f14c4-1986-4a73-87ff-fab23dc70e1a", "metadata": {}, "source": [ "In addition, all fields deriving from the job input settings can be added with the `add_settings_input_fields` method. By default, these will have names corresponding to the concatenated settings entries. Individual settings field can be added with the `add_settings_field` method. This is useful to see the differences in the input settings of various jobs which may have succeeded/failed." ] }, { "cell_type": "code", "execution_count": 9, "id": "0acafae2-cffd-45fe-bf7a-df16b1321e53", "metadata": {}, "outputs": [], "source": [ "ja = ja.add_settings_input_fields()" ] }, { "cell_type": "markdown", "id": "3c73c258-1313-400e-8d5a-ad2f6272b092", "metadata": {}, "source": [ "For output results, fields from the rkfs can be added with the `add_rkf_field` method, using a specified rkf file (default `ams.rkf`), section and variable." ] }, { "cell_type": "code", "execution_count": 10, "id": "726f9bc2-560e-4c62-8ba9-cbcf84f73809", "metadata": {}, "outputs": [], "source": [ "ja = ja.add_rkf_field(\"General\", \"engine\")" ] }, { "cell_type": "markdown", "id": "9eb6bc43-9609-4e11-bfdb-a0c7e59f91a6", "metadata": {}, "source": [ "Finally, custom fields can also be added with the `add_field` method, by defining a field key, value accessor and optional arguments like the display name and value formatting. This is most useful to extract results from jobs using built-in methods on the job results class." ] }, { "cell_type": "code", "execution_count": 11, "id": "42073591-bc82-4577-b08b-652fd10baf07", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Name | OK | Check | ErrorMsg | Formula | Smiles | CPUTime | SysTime | InputAmsTask | InputAdfBasisType | InputAdfXcGga | InputAmsNebImages | InputAmsNebIterations | AmsGeneralEngine | Energy [kJ/mol] | AtomType | Charge |\n", "|----------|-------|-------|-----------------------------------|-------------------|-------------------|----------|----------|--------------|-------------------|---------------|-------------------|-----------------------|------------------|-----------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|\n", "| dftb | True | True | None | C2H6 | CC | 0.211799 | 0.023247 | SinglePoint | None | None | None | None | dftb | -19594.01 | ['C', 'C', 'H', 'H', 'H', 'H', 'H', 'H'] | [-0.07293185 -0.07372966 0.0229089 0.02613236 0.02365099 0.02302581\n", " 0.02508041 0.02586303] |\n", "| adf.002 | True | True | None | C2H6 | CC | 3.853033 | 0.318997 | SinglePoint | DZ | None | None | None | adf | -3973.29 | ['C', 'C', 'H', 'H', 'H', 'H', 'H', 'H'] | [-0.83243445 -0.83187828 0.27390333 0.28078289 0.27678388 0.27344691\n", " 0.27910823 0.28028749] |\n", "| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |\n", "| neb | False | False | NEB optimization did NOT converge | : CHN, final: CHN | : C=N, final: C#N | 0.474088 | 0.086321 | NEB | None | None | 9 | 10 | dftb | None | ['C', 'N', 'H'] | None |\n", "| neb.002 | True | True | None | : CHN, final: CHN | : C=N, final: C#N | 1.480769 | 0.313988 | NEB | None | None | 9 | 100 | dftb | -14936.53 | ['C', 'N', 'H'] | [-0.00724506 -0.21146552 0.21871057] |\n", "| dftb.009 | True | True | None | C3H8 | CCC | 0.191499 | 0.013078 | SinglePoint | None | None | None | None | dftb | -27967.66 | ['C', 'C', 'C', 'H', 'H', 'H', 'H', 'H', 'H', 'H', 'H'] | [-0.08484515 -0.0311758 -0.08604109 0.02623135 0.02847202 0.02639002\n", " 0.02083141 0.02232931 0.02618436 0.02685258 0.02477098] |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja = ja.add_field(\n", " \"Energy\",\n", " lambda j: j.results.get_energy(unit=\"kJ/mol\"),\n", " display_name=\"Energy [kJ/mol]\",\n", " fmt=\".2f\",\n", ")\n", "ja = ja.add_field(\"AtomType\", lambda j: [at.symbol for at in j.results.get_main_molecule()])\n", "ja = ja.add_field(\"Charge\", lambda j: j.results.get_charges())\n", "\n", "ja.display_table(max_rows=5)" ] }, { "cell_type": "markdown", "id": "3bce481d-494e-43c2-9a64-7d608d6e7e7f", "metadata": {}, "source": [ "### Processing Data" ] }, { "cell_type": "markdown", "id": "d40411a2-53d4-4df6-972a-bbdc788e4e5c", "metadata": {}, "source": [ "Once an initial analysis has been created, the data can be further processed, depending on the use case.\n", "For example, to inspect the difference between failed and successful jobs, jobs can be filtered down and irrelevant fields removed.\n", "\n", "Here we first filter the jobs to those which have the `NEB` task:" ] }, { "cell_type": "code", "execution_count": 12, "id": "e1c5e318-7070-4f26-bfb7-aada32f7e92f", "metadata": {}, "outputs": [], "source": [ "ja_neb = ja.filter_jobs(lambda data: data[\"InputAmsTask\"] == \"NEB\")" ] }, { "cell_type": "markdown", "id": "89e5904c-ee50-453c-8901-d23306ce16c4", "metadata": {}, "source": [ "Then we remove the \"uniform fields\" i.e. fields where all the values are the same. This lets us remove the noise and focus on the fields which have differences." ] }, { "cell_type": "code", "execution_count": 13, "id": "2b381c2f-f057-4443-b05a-d38adf18beb3", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Name | OK | Check | CPUTime | SysTime | InputAmsNebIterations |\n", "|---------|-------|-------|----------|----------|-----------------------|\n", "| neb | False | False | 0.474088 | 0.086321 | 10 |\n", "| neb.002 | True | True | 1.480769 | 0.313988 | 100 |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja_neb = ja_neb.remove_uniform_fields(ignore_empty=True)\n", "ja_neb.display_table()" ] }, { "cell_type": "markdown", "id": "8cc4f829-07c6-419c-97ff-110b28dd876f", "metadata": {}, "source": [ "Another use case may be to analyze the results from one or more jobs.\n", "For this, it can be useful to utilize the `expand` functionality to convert job(s) to multiple rows.\n", "During this process, fields selected for expansion will have their values extracted into individual rows, whilst other fields have their values duplicated.\n", "\n", "First we filter to a single job, the geometry optimization of water:" ] }, { "cell_type": "code", "execution_count": 14, "id": "beb3c9b2-bcdb-4be8-8d96-84f29a3bfdd5", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Name | OK | Check | ErrorMsg | Formula | Smiles | CPUTime | SysTime | InputAmsTask | InputAdfBasisType | InputAdfXcGga | InputAmsNebImages | InputAmsNebIterations | AmsGeneralEngine | Energy [kJ/mol] | AtomType | Charge |\n", "|---------|------|-------|----------|---------|--------|----------|----------|----------------------|-------------------|---------------|-------------------|-----------------------|------------------|-----------------|-----------------|---------------------------------------|\n", "| adf.011 | True | True | None | H2O | O | 2.684484 | 0.324325 | GeometryOptimization | DZ | None | None | None | adf | -1316.30 | ['O', 'H', 'H'] | [-0.84168651 0.42084715 0.42083936] |\n", "| adf.012 | True | True | None | H2O | O | 4.183557 | 0.484223 | GeometryOptimization | TZP | PBE | None | None | adf | -1363.77 | ['O', 'H', 'H'] | [-0.6739805 0.33698187 0.33699863] |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja_adf_water = ja.filter_jobs(\n", " lambda data: (\n", " data[\"InputAmsTask\"] == \"GeometryOptimization\"\n", " and data[\"InputAdfBasisType\"] is not None\n", " and data[\"Smiles\"] == \"O\"\n", " )\n", ")\n", "ja_adf_water.display_table()" ] }, { "cell_type": "markdown", "id": "b11f6136-d757-43ac-8e40-af8eb85d4515", "metadata": {}, "source": [ "Then we \"expand\" a given field to flatten the arrays and have one row per entry in the array. This lets us see the charge per atom for each job:" ] }, { "cell_type": "code", "execution_count": 15, "id": "1f298dff-948c-4b45-91b1-2670286f46d7", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| Name | CPUTime | SysTime | InputAdfBasisType | InputAdfXcGga | Energy [kJ/mol] | AtomType | Charge |\n", "|---------|----------|----------|-------------------|---------------|-----------------|----------|---------------------|\n", "| adf.011 | 2.684484 | 0.324325 | DZ | None | -1316.30 | O | -0.8416865089598673 |\n", "| adf.011 | 2.684484 | 0.324325 | DZ | None | -1316.30 | H | 0.4208471524496712 |\n", "| adf.011 | 2.684484 | 0.324325 | DZ | None | -1316.30 | H | 0.42083935651019355 |\n", "| adf.012 | 4.183557 | 0.484223 | TZP | PBE | -1363.77 | O | -0.6739804981076105 |\n", "| adf.012 | 4.183557 | 0.484223 | TZP | PBE | -1363.77 | H | 0.3369818667176927 |\n", "| adf.012 | 4.183557 | 0.484223 | TZP | PBE | -1363.77 | H | 0.3369986313899128 |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja_adf_water_expanded = (\n", " ja_adf_water.expand_field(\"AtomType\").expand_field(\"Charge\").remove_uniform_fields()\n", ")\n", "ja_adf_water_expanded.display_table()" ] }, { "cell_type": "markdown", "id": "77d0c620-3ca7-4dfb-969f-c5a5abbad76b", "metadata": {}, "source": [ "Expansion can be undone with the corresponding `collapse` method. \n", "\n", "Fields can be also further filtered, modified or reordered to customize the analysis. This example also illustrates the \"fluent\" syntax of the `JobAnalysis` tool, whereb" ] }, { "cell_type": "code", "execution_count": 16, "id": "e15126b0-4689-413b-b374-1545ba1b737b", "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "| AtomType | Charge | Energy [kJ/mol] | CPUTime | SysTime | GGA | InputAdfXcGga |\n", "|----------|---------|-----------------|---------|----------|-----|---------------|\n", "| O | -0.8417 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "| H | 0.4208 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "| H | 0.4208 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "| O | -0.6740 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |\n", "| H | 0.3370 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |\n", "| H | 0.3370 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "ja_adf = (\n", " ja_adf_water_expanded.remove_field(\"Name\")\n", " .format_field(\"CPUTime\", \".2f\")\n", " .format_field(\"Charge\", \".4f\")\n", " .rename_field(\"InputAdfBasisType\", \"Basis\")\n", " .rename_field(\"InputAdfBasisType\", \"GGA\")\n", " .reorder_fields([\"AtomType\", \"Charge\", \"Energy\"])\n", ")\n", "ja_adf.display_table()" ] }, { "cell_type": "markdown", "id": "62361885-1b81-44b4-b944-176acb33d17a", "metadata": {}, "source": [ "### Extracting Analysis Data" ] }, { "cell_type": "markdown", "id": "90b34dca-a351-4ec1-8646-1f38dbeed906", "metadata": {}, "source": [ "Analysis data can be extracted in a variety of ways.\n", "\n", "As has been demonstrated, a visual representation of the table can be easily generated using the `to_table` method (or `display_table` in a notebook).\n", "The format can be selected as markdown, html or rst. This will return the data with the specified display names and formatting." ] }, { "cell_type": "code", "execution_count": 17, "id": "1258b6ef-c2fb-42c2-a8c5-33cbf87ffbed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| AtomType | Charge | Energy [kJ/mol] | CPUTime | SysTime | GGA | InputAdfXcGga |\n", "+==========+=========+=================+=========+==========+=====+===============+\n", "| O | -0.8417 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| H | 0.4208 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| H | 0.4208 | -1316.30 | 2.68 | 0.324325 | DZ | None |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| O | -0.6740 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| H | 0.3370 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n", "| H | 0.3370 | -1363.77 | 4.18 | 0.484223 | TZP | PBE |\n", "+----------+---------+-----------------+---------+----------+-----+---------------+\n" ] } ], "source": [ "print(ja_adf.to_table(fmt=\"rst\"))" ] }, { "cell_type": "markdown", "id": "b1ef86ba-79e9-486f-8adc-ab81f23c949b", "metadata": {}, "source": [ "Alternatively, raw data can be retrieved via the `get_analysis` method, which returns a dictionary of analysis keys to values." ] }, { "cell_type": "code", "execution_count": 18, "id": "cce8f9c5-13e7-423d-999d-cd9df8f22a72", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'AtomType': ['O', 'H', 'H', 'O', 'H', 'H'], 'Charge': [-0.8416865089598673, 0.4208471524496712, 0.42083935651019355, -0.6739804981076105, 0.3369818667176927, 0.3369986313899128], 'Energy': [-1316.2997406507902, -1316.2997406507902, -1316.2997406507902, -1363.76629419659, -1363.76629419659, -1363.76629419659], 'CPUTime': [2.684484, 2.684484, 2.684484, 4.183557, 4.183557, 4.183557], 'SysTime': [0.324325, 0.324325, 0.324325, 0.484223, 0.484223, 0.484223], 'InputAdfBasisType': ['DZ', 'DZ', 'DZ', 'TZP', 'TZP', 'TZP'], 'InputAdfXcGga': [None, None, None, 'PBE', 'PBE', 'PBE']}\n" ] } ], "source": [ "print(ja_adf.get_analysis())" ] }, { "cell_type": "markdown", "id": "c95fe2f9-585b-46cc-9122-f0afbfc034da", "metadata": {}, "source": [ "Data can also be easily written to a csv file using `to_csv_file`, to be exported to another program." ] }, { "cell_type": "code", "execution_count": 19, "id": "cd5031bb-08f8-4a8f-b0a0-724baeca56d1", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "AtomType,Charge,Energy,CPUTime,SysTime,InputAdfBasisType,InputAdfXcGga\n", "O,-0.8416865089598673,-1316.2997406507902,2.684484,0.324325,DZ,\n", "H,0.4208471524496712,-1316.2997406507902,2.684484,0.324325,DZ,\n", "H,0.42083935651019355,-1316.2997406507902,2.684484,0.324325,DZ,\n", "O,-0.6739804981076105,-1363.76629419659,4.183557,0.484223,TZP,PBE\n", "H,0.3369818667176927,-1363.76629419659,4.183557,0.484223,TZP,PBE\n", "H,0.3369986313899128,-1363.76629419659,4.183557,0.484223,TZP,PBE\n", "\n" ] } ], "source": [ "csv_name = \"./tmp.csv\"\n", "ja_adf.to_csv_file(csv_name)\n", "\n", "with open(csv_name) as csv:\n", " print(csv.read())" ] }, { "cell_type": "markdown", "id": "ae737a2a-7490-4750-ae01-21b79c862d0c", "metadata": {}, "source": [ "Finally, for more complex data analysis, the results can be converted to a [pandas](https://pandas.pydata.org) dataframe. This is recommended for more involved data manipulations." ] }, { "cell_type": "code", "execution_count": 20, "id": "35abbc0f-8565-441d-a894-f36152cddb48", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
AtomTypeChargeEnergyCPUTimeSysTimeInputAdfBasisTypeInputAdfXcGga
0O-0.841687-1316.2997412.6844840.324325DZNone
1H0.420847-1316.2997412.6844840.324325DZNone
2H0.420839-1316.2997412.6844840.324325DZNone
3O-0.673980-1363.7662944.1835570.484223TZPPBE
4H0.336982-1363.7662944.1835570.484223TZPPBE
5H0.336999-1363.7662944.1835570.484223TZPPBE
\n", "
" ], "text/plain": [ " AtomType Charge Energy CPUTime SysTime InputAdfBasisType \\\n", "0 O -0.841687 -1316.299741 2.684484 0.324325 DZ \n", "1 H 0.420847 -1316.299741 2.684484 0.324325 DZ \n", "2 H 0.420839 -1316.299741 2.684484 0.324325 DZ \n", "3 O -0.673980 -1363.766294 4.183557 0.484223 TZP \n", "4 H 0.336982 -1363.766294 4.183557 0.484223 TZP \n", "5 H 0.336999 -1363.766294 4.183557 0.484223 TZP \n", "\n", " InputAdfXcGga \n", "0 None \n", "1 None \n", "2 None \n", "3 PBE \n", "4 PBE \n", "5 PBE " ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = ja_adf.to_dataframe()\n", "df" ] }, { "cell_type": "code", "execution_count": null, "id": "e6b633ce-cc40-4a03-b663-9d729d67d40f", "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.16" } }, "nbformat": 4, "nbformat_minor": 5 }