{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Task, Engine and Property Blocks" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from scm.plams import Settings, AMSJob" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Helper function to print the settings in the AMS input format style:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "def print_input(settings):\n", " print(AMSJob(settings=settings).get_input())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Tasks can be specified in the settings under the `input.AMS.Task` key:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n" ] } ], "source": [ "go_settings = Settings()\n", "go_settings.input.AMS.Task = \"GeometryOptimization\"\n", "go_settings.input.AMS.GeometryOptimization.Convergence.Gradients = 1e-5\n", "print_input(go_settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Properties can be specified under the `input.AMS.Properties` key:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Properties\n", " NormalModes Yes\n", "End\n", "\n", "\n" ] } ], "source": [ "nm_settings = Settings()\n", "nm_settings.input.ams.Properties.NormalModes = \"Yes\"\n", "print_input(nm_settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Engine settings can be specified under the `input.` key, for the engine of interest:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Engine ADF\n", " Basis\n", " Type DZP\n", " End\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "lda_settings = Settings()\n", "lda_settings.input.ADF.Basis.Type = \"DZP\"\n", "print_input(lda_settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Combining Settings" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Settings objects can also be combined for easy reuse and job setup. Settings can be merged using the `+` and `+=` operators." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Properties\n", " NormalModes Yes\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine ADF\n", " Basis\n", " Type DZP\n", " End\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "settings = go_settings + lda_settings + nm_settings\n", "print_input(settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note however that this merge is a \"soft\" update, so values of existing keys will not be overwritten:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Properties\n", " NormalModes Yes\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine ADF\n", " Basis\n", " Type DZP\n", " End\n", " xc\n", " gga pbe\n", " End\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "pbe_settings = Settings()\n", "pbe_settings.input.ADF.Basis.Type = \"TZP\"\n", "pbe_settings.input.ADF.xc.gga = \"pbe\"\n", "settings += pbe_settings # adds \"pbe\" but will not set \"TZP\", because a Basis.Type already exists in settings\n", "print_input(settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To achieve \"hard update\" behaviour, the `update` method can be used, which overwrites existing keys:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Properties\n", " NormalModes Yes\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine ADF\n", " Basis\n", " Type TZP\n", " End\n", " xc\n", " gga pbe\n", " End\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "settings.update(pbe_settings) # will also set \"TZP\"\n", "print_input(settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Subtracting settings\n", "\n", "Settings can also be removed using the `-` and `-=` operators:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Properties\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine ADF\n", " Basis\n", " Type TZP\n", " End\n", " xc\n", " gga pbe\n", " End\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "settings -= nm_settings\n", "print_input(settings)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "## Comparison" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Two settings objects can be compared to check the differences between them. The result will show the nested key and value of any added, removed and modified entries." ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'added': {('input', 'DFTB', 'Model'): 'GFN1-xTB'},\n", " 'modified': {('input', 'AMS', 'Task'): ('SinglePoint',\n", " 'GeometryOptimization')},\n", " 'removed': {('input', 'ADF', 'Basis', 'Type'): 'DZP',\n", " ('input', 'AMS', 'GeometryOptimization', 'Convergence', 'Gradients'): 1e-05,\n", " ('input', 'AMS', 'Properties', 'NormalModes'): 'Yes'}}\n" ] } ], "source": [ "from pprint import pprint\n", "\n", "settings1 = go_settings + lda_settings + nm_settings\n", "settings2 = Settings()\n", "settings2.input.AMS.Task = \"SinglePoint\"\n", "settings2.input.DFTB.Model = \"GFN1-xTB\"\n", "comparison = settings2.compare(settings1) # dictionary with keys 'added', 'modified', and 'removed'\n", "pprint(comparison)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Repeated blocks as lists, Hybrid engine\n", "\n", "Multiple values in a settings block can be configured using a list:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine Hybrid\n", " Energy\n", " Term\n", " EngineID adf-lda\n", " Factor 1.0\n", " Region *\n", " End\n", " Term\n", " EngineID adf-lda\n", " Factor -1.0\n", " Region one\n", " End\n", " Term\n", " EngineID adf-gga\n", " Factor 1.0\n", " Region one\n", " End\n", " Term\n", " EngineID adf-lda\n", " Factor -1.0\n", " Region two\n", " End\n", " Term\n", " EngineID adf-gga\n", " Factor 1.0\n", " Region two\n", " End\n", " End\n", " Engine ADF adf-lda\n", " Basis\n", " Type DZP\n", " End\n", " EndEngine\n", " Engine ADF adf-gga\n", " Basis\n", " Type TZP\n", " End\n", " xc\n", " gga pbe\n", " End\n", " EndEngine\n", "\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "hybrid_settings = go_settings.copy()\n", "hybrid_settings.input.Hybrid.Energy.Term = []\n", "for i in range(5):\n", " factor = (-1) ** (i % 2) * 1.0\n", " region = \"*\" if i == 0 else \"one\" if i < 3 else \"two\"\n", " engine_id = \"adf-lda\" if i == 0 or factor == -1 else \"adf-gga\"\n", " term = Settings({\"Factor\": factor, \"Region\": region, \"EngineID\": engine_id})\n", " hybrid_settings.input.Hybrid.Energy.Term.append(term)\n", "hybrid_settings.input.Hybrid.Engine = [\n", " lda_settings.input.ADF.copy(),\n", " pbe_settings.input.ADF.copy(),\n", "]\n", "hybrid_settings.input.Hybrid.Engine[0]._h = \"ADF adf-lda\"\n", "hybrid_settings.input.Hybrid.Engine[1]._h = \"ADF adf-gga\"\n", "print_input(hybrid_settings)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note also in the example below, the use of the special `_h` \"header\" key, which can be used to add data to the header line for a block." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Nested Keys" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It can be useful to access values from a Settings object using \"nested\" keys, available in AMS2025+. These are tuples of keys, where each successive element of the tuple corresponds to a further layer in the settings. Lists are flattened so their elements can be accessed with the corresponding index.\n", "\n", "These options are mainly useful if you programatically need to compare or set different settings. If you manually create a Settings object it is easier to just use the normal dot notation shown in the previous example." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[('input',), ('input', 'AMS'), ('input', 'AMS', 'Task'), ('input', 'AMS', 'GeometryOptimization'), ('input', 'AMS', 'GeometryOptimization', 'Convergence'), ('input', 'AMS', 'GeometryOptimization', 'Convergence', 'Gradients'), ('input', 'Hybrid'), ('input', 'Hybrid', 'Energy'), ('input', 'Hybrid', 'Energy', 'Term'), ('input', 'Hybrid', 'Energy', 'Term', 0), ('input', 'Hybrid', 'Energy', 'Term', 0, 'Factor'), ('input', 'Hybrid', 'Energy', 'Term', 0, 'Region'), ('input', 'Hybrid', 'Energy', 'Term', 0, 'EngineID'), ('input', 'Hybrid', 'Energy', 'Term', 1), ('input', 'Hybrid', 'Energy', 'Term', 1, 'Factor'), ('input', 'Hybrid', 'Energy', 'Term', 1, 'Region'), ('input', 'Hybrid', 'Energy', 'Term', 1, 'EngineID'), ('input', 'Hybrid', 'Energy', 'Term', 2), ('input', 'Hybrid', 'Energy', 'Term', 2, 'Factor'), ('input', 'Hybrid', 'Energy', 'Term', 2, 'Region'), ('input', 'Hybrid', 'Energy', 'Term', 2, 'EngineID'), ('input', 'Hybrid', 'Energy', 'Term', 3), ('input', 'Hybrid', 'Energy', 'Term', 3, 'Factor'), ('input', 'Hybrid', 'Energy', 'Term', 3, 'Region'), ('input', 'Hybrid', 'Energy', 'Term', 3, 'EngineID'), ('input', 'Hybrid', 'Energy', 'Term', 4), ('input', 'Hybrid', 'Energy', 'Term', 4, 'Factor'), ('input', 'Hybrid', 'Energy', 'Term', 4, 'Region'), ('input', 'Hybrid', 'Energy', 'Term', 4, 'EngineID'), ('input', 'Hybrid', 'Engine'), ('input', 'Hybrid', 'Engine', 0), ('input', 'Hybrid', 'Engine', 0, '_h'), ('input', 'Hybrid', 'Engine', 0, 'Basis'), ('input', 'Hybrid', 'Engine', 0, 'Basis', 'Type'), ('input', 'Hybrid', 'Engine', 1), ('input', 'Hybrid', 'Engine', 1, '_h'), ('input', 'Hybrid', 'Engine', 1, 'Basis'), ('input', 'Hybrid', 'Engine', 1, 'Basis', 'Type'), ('input', 'Hybrid', 'Engine', 1, 'xc'), ('input', 'Hybrid', 'Engine', 1, 'xc', 'gga')]\n" ] } ], "source": [ "print(list(hybrid_settings.nested_keys()))" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n" ] } ], "source": [ "print(hybrid_settings.get_nested((\"input\", \"AMS\", \"Task\")))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GeometryOptimization\n", " Convergence\n", " Gradients 1e-05\n", " End\n", "End\n", "\n", "Task GeometryOptimization\n", "\n", "\n", "Engine Hybrid\n", " Energy\n", " Term\n", " EngineID adf-lda\n", " Factor 1.0\n", " Region *\n", " End\n", " Term\n", " EngineID adf-lda\n", " Factor -1.0\n", " Region one\n", " End\n", " Term\n", " EngineID adf-gga\n", " Factor 1.0\n", " Region one\n", " End\n", " Term\n", " EngineID adf-lda\n", " Factor -1.0\n", " Region two\n", " End\n", " Term\n", " EngineID adf-gga\n", " Factor 1.0\n", " Region two\n", " End\n", " End\n", " Engine ADF adf-lda\n", " Basis\n", " Type DZP\n", " End\n", " NumericalQuality Good\n", " EndEngine\n", " Engine ADF adf-gga\n", " Basis\n", " Type TZP\n", " End\n", " xc\n", " gga pbe\n", " End\n", " EndEngine\n", "\n", "EndEngine\n", "\n", "\n" ] } ], "source": [ "if hybrid_settings.contains_nested((\"input\", \"Hybrid\", \"Engine\", 0)):\n", " hybrid_settings.set_nested((\"input\", \"Hybrid\", \"Engine\", 0, \"NumericalQuality\"), \"Good\")\n", "print_input(hybrid_settings)" ] }, { "cell_type": "code", "execution_count": null, "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": 4 }