diff --git a/read_structure_step/formats/mop/find_mopac.py b/read_structure_step/formats/mop/find_mopac.py index 4b1a779..0498a67 100644 --- a/read_structure_step/formats/mop/find_mopac.py +++ b/read_structure_step/formats/mop/find_mopac.py @@ -6,6 +6,25 @@ def find_mopac(): + # Try the commandline options / config file + parser = seamm_util.getParser() + options = parser.get_options() + + if "mopac-step" in options: + mopac_options = options["mopac-step"] + exe = mopac_options["mopac_exe"] + mopac_path = mopac_options["mopac_path"] + if mopac_path != "": + exe = str(Path(mopac_path).expanduser().resolve() / exe) + + try: + mopac_exe = seamm_util.check_executable(exe) + except FileNotFoundError: + pass + else: + return mopac_exe + + # Next try common locations try: mopac_exe = "/opt/mopac/MOPAC2016.exe" @@ -14,10 +33,8 @@ def find_mopac(): 'The directory "/opt/mopac/" exists, but the executable \ "MOPAC2016.exe" is not there' ) - except FileNotFoundError: try: - mopac_path = os.path.split(os.environ["mopac"])[0] mopac_exe = mopac_path + "MOPAC2016.exe" @@ -26,7 +43,6 @@ def find_mopac(): 'The environment variable "mopac" is defined, but \ the executable "MOPAC2016.exe" is not there' ) - except (KeyError, FileNotFoundError): try: mopac_exe = Path(os.environ["MOPAC_LICENSE"]) / "MOPAC2016.exe" diff --git a/read_structure_step/formats/mop/obabel.py b/read_structure_step/formats/mop/obabel.py index 288de0b..7a98e39 100644 --- a/read_structure_step/formats/mop/obabel.py +++ b/read_structure_step/formats/mop/obabel.py @@ -23,16 +23,16 @@ "CP": "constant pressure heat capacity", "CPR": "reference.constant pressure heat capacity", "D": "dipole moment", - "DR": "reference.dipole moment", + "DR": "dipole moment.reference", "H": "enthalpy of formation", - "HR": "reference.enthalpy of formation", + "HR": "enthalpy of formation.reference", "S": "entropy", - "SR": "reference.entropy", + "SR": "entropy.reference", "I": "ionization energy", "IE": "ionization energy", "IA": "ionization energy", - "IR": "reference.ionization energy", - "GR": "reference.geometry", + "IR": "ionization energy.reference", + "GR": "geometry.reference", } multiplicities = { "SINGLET": 1, @@ -494,7 +494,7 @@ def load_mop( # Save keywords, description and any data encoded in the file to the database if save_data: properties = configuration.properties - if len("keywords") != 0: + if len(keywords) != 0: key = "MOPAC.keywords" properties.add( key, "str", description="The keywords for MOPAC", noerror=True @@ -536,14 +536,29 @@ def load_mop( print() continue keyword = metadata[keyword] + if value == "": + print(f"Value for {keyword} missing in MOPAC .mop file") + continue if "reference" in keyword: - description = keyword.split(".")[1] + description = keyword.split(".")[0] properties.add( keyword, "str", description=f"Reference for the {description}.", noerror=True, ) + elif "," in value: + # value , stderr + tmp = value.split(",") + value = tmp[0].strip() + stderr = tmp[1].strip() + properties.add( + f"{keyword}.stderr", + "float", + description=f"stderr for the {keyword}.", + noerror=True, + ) + properties.put(f"{keyword}.stderr", stderr) properties.put(keyword, value) except Exception as e: print(f"{e}: {key}") diff --git a/read_structure_step/read_structure.py b/read_structure_step/read_structure.py index a578439..10dc873 100644 --- a/read_structure_step/read_structure.py +++ b/read_structure_step/read_structure.py @@ -22,6 +22,7 @@ from .read import read import seamm from seamm_util import ureg, Q_ # noqa: F401 +from seamm_util import getParser import seamm_util.printing as printing from seamm_util.printing import FormattedText as __ from .utils import guess_extension @@ -69,6 +70,62 @@ def git_revision(self): """The git version of this module.""" return read_structure_step.__git_revision__ + def create_parser(self): + """Setup the command-line / config file parser""" + # Need to mimic MOPAC step to find the MOPAC executable + parser_name = "mopac-step" + print(f"Parser {parser_name}, {self.step_type=}") + parser = getParser() + + # Remember if the parser exists ... this type of step may have been + # found before + parser_exists = parser.exists(parser_name) + print(f"{parser_exists=}") + + # Create the standard options, e.g. log-level + result = super().create_parser(name=parser_name) + + if parser_exists: + return result + + # Options for Mopac + parser.add_argument( + parser_name, + "--mopac-exe", + default="MOPAC2016.exe", + help="the name of the MOPAC executable", + ) + + parser.add_argument( + parser_name, + "--mopac-path", + default="", + help="the path to the MOPAC executable", + ) + + parser.add_argument( + parser_name, + "--ncores", + default="default", + help="How many threads to use in MOPAC", + ) + + parser.add_argument( + parser_name, + "--mkl-num-threads", + default="default", + help="How many threads to use with MKL in MOPAC", + ) + + parser.add_argument( + parser_name, + "--max-atoms-to-print", + default=25, + help="Maximum number of atoms to print charges, etc.", + ) + + return result + def description_text(self, P=None): """Create the text description of what this step will do. The dictionary of control values is passed in as P so that