From 9f81ebf679e173fa77a05887195f0e17ab62be3a Mon Sep 17 00:00:00 2001 From: kmlefran Date: Wed, 13 Sep 2023 11:16:48 -0400 Subject: [PATCH] Improved documentation --- aiida_aimall/calculations.py | 36 +++++++++++------------------------ aiida_aimall/data/__init__.py | 27 ++++++++++++++------------ aiida_aimall/parsers.py | 23 +++++++++++++++++----- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/aiida_aimall/calculations.py b/aiida_aimall/calculations.py index ee973ba..ec29ad6 100644 --- a/aiida_aimall/calculations.py +++ b/aiida_aimall/calculations.py @@ -1,7 +1,8 @@ """ Calculations provided by aiida_aimall. -Register calculations via the "aiida.calculations" entry point in setup.json. +Upon pip install, AimqbCalculation is accessible in AiiDA.calculations plugins +Using the 'aimall' entry point """ from aiida.common import datastructures from aiida.engine import CalcJob @@ -33,7 +34,7 @@ def define(cls, spec): "num_machines": 1, "tot_num_mpiprocs": 2, } - # commented out parser to see default folder structure + spec.inputs["metadata"]["options"]["parser_name"].default = "aimqb.base" # new ports # spec.input( @@ -45,35 +46,19 @@ def define(cls, spec): help="Command line parameters for aimqb", ) spec.input( - "file", valid_type=SinglefileData, help="fchk, wfn, or wfx to run AimQB on" + "file", + valid_type=SinglefileData, + help="fchk, wfn, or wfx to run AimQB on", ) - # commented these to see + spec.output( "output_parameters", valid_type=Dict, required=True, help="The computed parameters of an AIMAll calculation", ) - # spec.output( - # "atomic_properties", - # valid_type=Dict, - # required=True, - # help="The result parameters of the calculation", - # ) - # spec.output( - # "bcp_properties", - # valid_type=Dict, - # required=True, - # help="The properties of all BCPs in the molecule", - # ) - # spec.output( - # "cc_properties", - # valid_type=Dict, - # required=False, - # help="The properties of VSCC in the molecule", - # ) - # spec.default_output_node = "output_parameters" + spec.default_output_node = "output_parameters" spec.outputs.dynamic = True # would put error codes here @@ -87,13 +72,14 @@ def prepare_for_submission(self, folder): place all files needed by the calculation. :return: `aiida.common.datastructures.CalcInfo` instance """ + # copy wfx file to input file input_string = self.inputs.file.get_content() with open( folder.get_abs_path(self.INPUT_FILE), "w", encoding="utf-8" ) as out_file: out_file.write(input_string) codeinfo = datastructures.CodeInfo() - # probably modify the next line + # generate command line params codeinfo.cmdline_params = self.inputs.parameters.cmdline_params( file_name=self.INPUT_FILE ) @@ -103,7 +89,7 @@ def prepare_for_submission(self, folder): # Prepare a `CalcInfo` to be returned to the engine calcinfo = datastructures.CalcInfo() calcinfo.codes_info = [codeinfo] # list since can involve more than one - + # Retrieve the sum file and the folder with atomic files calcinfo.retrieve_list = [ self.OUTPUT_FILE.replace("out", "sum"), self.OUTPUT_FILE.replace(".out", "_atomicfiles"), diff --git a/aiida_aimall/data/__init__.py b/aiida_aimall/data/__init__.py index 995c436..8f0cf57 100644 --- a/aiida_aimall/data/__init__.py +++ b/aiida_aimall/data/__init__.py @@ -1,15 +1,15 @@ """ Data types provided by plugin -Register data types via the "aiida.data" entry point in setup.json. +Upon pip install, AimqbParameters is accessible in AiiDA.data plugins +Using the 'aimall' entry point """ -# You can directly use or subclass aiida.orm.data.Data -# or any other data type listed under 'verdi data' + from voluptuous import Optional, Schema from aiida.orm import Dict -# AIMQB's command line options +# AIMQB's command line options and their expected type cmdline_options = { Optional("bim"): str, Optional("iasmesh"): str, @@ -51,6 +51,8 @@ class AimqbParameters(Dict): # pylint: disable=too-many-ancestors This class represents a python dictionary used to pass command line options to the executable. + The class takes a dictionary of parameters and validates + to ensure the aimqb command line parameters are correct """ schema = Schema(cmdline_options) @@ -58,7 +60,7 @@ class AimqbParameters(Dict): # pylint: disable=too-many-ancestors def __init__(self, parameter_dict=None, **kwargs): """Constructor for the data class - Usage: ``AimqbParameters(dict{'ignore-case': True})`` + Usage: ``AimqbParameters(parameter_dict{'ignore-case': True})`` :param parameters_dict: dictionary with commandline parameters :param type parameters_dict: dict @@ -85,17 +87,18 @@ def cmdline_params(self, file_name): e.g. [ '-atlaprhocps=True',...,'-nogui', 'filename'] - :param file_name: Name of first file + :param file_name: Name of wfx/fchk/wfn file :param type file_name: str """ - parameters = [] + # parameters = [] pm_dict = self.get_dict() - for key, value in pm_dict.items(): - parameters += [f"-{key}={value}"] - parameters += ["-nogui"] - parameters += [file_name] + parameters = [f"-{key}={value}" for key, value in pm_dict.items()] + # for key, value in pm_dict.items(): + # parameters += [f"-{key}={value}"] + parameters += ["-nogui"] # use no gui when running in aiida + parameters += [file_name] # input file return [str(p) for p in parameters] @@ -105,7 +108,7 @@ def __str__(self): Append values of dictionary to usual representation. E.g.:: uuid: b416cbee-24e8-47a8-8c11-6d668770158b (pk: 590) - {'ignore-case': True} + {'atlaprhocps': True} """ string = super().__str__() diff --git a/aiida_aimall/parsers.py b/aiida_aimall/parsers.py index fbbd505..a6002e0 100644 --- a/aiida_aimall/parsers.py +++ b/aiida_aimall/parsers.py @@ -52,7 +52,6 @@ def parse(self, **kwargs): output_filename.replace(".out", "_atomicfiles"), ] # Note: set(A) <= set(B) checks whether A is a subset of B - if not set(files_expected) <= set(files_retrieved): self.logger.error( f"Found files '{files_retrieved}', expected to find '{files_expected}'" @@ -60,7 +59,7 @@ def parse(self, **kwargs): # return self.exit_codes.ERROR_MISSING_OUTPUT_FILES return - # add output file + # parse output file self.logger.info(f"Parsing '{output_filename}'") OutFolderData = self.retrieved with OutFolderData.open(output_filename.replace("out", "sum"), "rb") as handle: @@ -70,20 +69,24 @@ def parse(self, **kwargs): "atomic_properties": self._parse_atomic_props(sum_lines), "bcp_properties": self._parse_bcp_props(sum_lines), } + # if laprhocps were calculated, get cc_properties if "-atlaprhocps=True" in input_parameters.cmdline_params("foo"): out_dict["cc_properties"] = self._parse_cc_props( out_dict["atomic_properties"] ) - # self.outputs.atomic_properties = self._parse_atomic_props(sum_lines) - # self.outputs.bcp_properties = self._parse_bcp_props(sum_lines) + # store in node self.outputs.output_parameters = Dict(out_dict) - # self.outputs.output_parameters.cc_properties = self._parse_cc_props() return # ExitCode(0) def _parse_cc_props(self, atomic_properties): + """Extract VSCC properties from output files + :param atomic_properties: dictionary of atomic properties from _parse_atomic_props + :param type atomic_properties: dict + """ output_filename = self.node.process_class.OUTPUT_FILE atom_list = list(atomic_properties.keys()) + # for each atom, load the .agpviz file in the _atomicfiles folder and get cc props cc_dict = { x: qt.get_atom_vscc( filename=self.retrieved.get_object_content( @@ -102,8 +105,18 @@ def _parse_cc_props(self, atomic_properties): return cc_dict def _parse_atomic_props(self, sum_file_string): + """Extracts atomic properties from .sum file + + :param sum_file_string: lines of .sum output file + :param type sum_file_string: str + """ return qt.get_atomic_props(sum_file_string.split("\n")) def _parse_bcp_props(self, sum_file_string): + """Extracts bcp properties from .sum file + + :param sum_file_string: lines of .sum output file + :param type sum_file_string: str + """ bcp_list = qt.find_all_connections(sum_file_string.split("\n")) return qt.get_selected_bcps(sum_file_string.split("\n"), bcp_list)