Oracle ====== The primary purpose of the Oracle module is to execute and post-process "ground truth" calculations. These calculations can be used to create or supplement a IAP training set, or provide a reference to a given configuration. The module provides interfaces to use a number of simulation tools, including `LAMMPS `_, `Quantum Espresso `_, and `VASP `_. In addition, there is an interface to use :ref:`aiida_setup` for automated calculations with error handling and provenance tracking. The abstract base class :class:`~orchestrator.oracle.oracle_base.Oracle` provides the standard interface for all of the concrete implementations. See the full API for the module at :ref:`oracle_module`. Example Scripts --------------- The Oracle module can be called by other Orchestrator modules, or as a standalone class. A few examples are given below to show how the user could possibly interact with the module. The unit tests introduced in :ref:`testing` also provide a useful example of how the Oracle module can be deployed. All of the input parameters can be set within the same python script and passed to the respective functions. To increase readability, many of the code input parameters may be saved to a separate json file. Utility functions found in :class:`~orchestrator.utils.setup_input` can be used to pull the appropriate sections. Three different examples using :class:`~.VaspOracle`, :class:`~.EspressoOracle`, and :class:`~.AiidaEspressoOracle` are provided below. .. dropdown:: VaspOracle JSON example .. code-block:: json { "oracle":{ "oracle_type":"VASP", "oracle_args":{ "code_path":"" }, "extra_input_args":{ "incar": { "ENCUT": 250, "PREC": "ACCURATE", "EDIFF": 1E-4, "LORBIT": 11, "ISMEAR": 0, "SIGMA": 0.1, "GGA": "PS", "KPAR": 1, "NCORE": 1, "NELM": 500 }, }, "job_details":{ "synchronous":false, "walltime":5 } }, "workflow":{ "workflow_type":"", "workflow_args":{ "root_directory":"./oracle", "queue":"", "account":"", "nodes":"", "tasks":"", "wait_freq":60 } }, "storage":{ "storage_type":"COLABFIT", "storage_args":{ "credential_file":"" } } } .. dropdown:: EspressoOracle JSON example .. code-block:: json { "oracle":{ "oracle_type":"QE", "oracle_args":{ "code_path":"" }, "job_details":{ "synchronous":false, "walltime":5, "extra_args":{ "preamble":"echo 'hello world'", "after":"echo 'done'" } } }, "workflow":{ "workflow_type":"", "workflow_args":{ "root_directory":"./oracle", "queue":"", "account":"", "nodes":"", "tasks":"", "wait_freq":60 } }, "storage":{ "storage_type":"COLABFIT", "storage_args":{ "credential_file":"" } } } .. dropdown:: AiidaEspressoOracle JSON example .. code-block:: json { "oracle": { "oracle_type": "AiiDA-QE", "oracle_args": { "workchain": "quantumespresso.pw.relax", "code_str": "pw@localhost" }, "extra_input_args": { "parameters": "parameters.json", "potential_family": "SSSP/1.3/PBE/precision", "kspacing": 0.25 }, }, "storage": { "storage_type": "LOCAL", "storage_args": { "database_path": "/path/to/local/storage" } }, "workflow":{ "workflow_type": "AiiDA", "workflow_args": { "root_directory": "./oracle", "tasks": 1 } } } The values available for the :class:`~.Workflow` module can be seen in the documentation for :class:`~orchestrator.workflow.workflow_base.Workflow` or :class:`~orchestrator.workflow.workflow_base.HPCWorkflow` where the latter would likely be the normal use case. You will notice in the input files that the input parameters for the simulation can be written to an external json file as well. These values can be used for general settings and if multiple oracle simulations are ran, can be modified and passed to each individual simulation. An example for Quantum Espresso is shown below. .. dropdown:: Quantum Espresso parameters.json example .. code-block:: json { "CONTROL": { "calculation": "scf", "forc_conv_thr": 0.001, "tprnfor": true, "tstress": true, "etot_conv_thr": 0.0001 }, "SYSTEM": { "nosym": false, "occupations": "smearing", "smearing": "mv", "degauss": 0.01, "ecutwfc": 90.0, "ecutrho": 1080.0 }, "ELECTRONS": { "electron_maxstep": 80, "mixing_beta": 0.4, "conv_thr": 4e-10 } } A simple python script can then be used to import the values and submit the simulation to the oracle. .. dropdown:: Oracle simulation .. code-block:: python import json import os from ase.io import read from orchestrator.utils.setup_input import init_and_validate_module_type from orchestrator.utils.input_output import safe_write # Load all the inputs or define them in a dictionary. with open(input_file, 'r') as fin: all_inputs = json.load(fin) # Initialize each module for later use. oracle_inputs = all_inputs.get('oracle', all_inputs) oracle = init_and_validate_module_type('oracle', oracle_inputs, True) workflow = init_and_validate_module_type('workflow', all_inputs) if workflow is None: workflow = oracle.default_wf storage = init_and_validate_module_type('storage', all_inputs) # Read in the configurations for simulations. configs = [] for root, _, files in os.walk(oracle_inputs.get('data_path'), followlinks=True): for i, f in enumerate(files): configs.append(read(f'{root}/{f}')) if storage is not None: storage.set_default_property_map() configs = storage.sort_configurations(configs) # Initiate the individual oracle runs. calc_ids = oracle.run( oracle_inputs.get('path_type'), oracle_inputs.get('extra_input_args'), configs, workflow=workflow, job_details=oracle_inputs.get('job_details', {}), ) # Have orchestrator wait for the jobs. workflow.block_until_completed(calc_ids) # Save information from the simulations. new_handle = oracle.save_labeled_configs( calc_ids, storage=storage, dataset_name='run_01', workflow=workflow, ) print(f'Labeled configurations saved to {new_handle}') saved_data = storage.get_data(new_handle) for config, calc_id in zip(saved_data, calc_ids): save_path = workflow.get_job_path(calc_id) if save_path is None: save_path = workflow.make_path(oracle.__class__.__name__, f'{oracle_inputs.get('path_type')}_{calc_id}') safe_write(f'{save_path}/saved_config.extxyz', config) return True In the case that a user would like to upload calculations executed externally to the orchestrator, a brief explanation is provided at :ref:`upload_external`. Inheritance Graph ----------------- .. inheritance-diagram:: orchestrator.oracle.factory orchestrator.oracle.espresso orchestrator.oracle.vasp orchestrator.oracle.kim orchestrator.oracle.lammps orchestrator.oracle.aiida.vasp orchestrator.oracle.aiida.espresso :parts: 3