Skip to content

Commit

Permalink
Merge pull request #215 from loriab/psiapi_detection
Browse files Browse the repository at this point in the history
psithon and psiapi
  • Loading branch information
dgasmith committed Jan 12, 2020
2 parents e370e86 + 0602e97 commit d31f65b
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 12 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
QCEngine
========
[![Travis Build Status](https://travis-ci.org/MolSSI/QCEngine.png)](https://travis-ci.org/MolSSI/QCEngine)
[![codecov](https://codecov.io/gh/MolSSI/QCEngine/branch/master/graph/badge.svg)](https://codecov.io/gh/MolSSI/QCEngine/branch/master)
[![codecov](https://img.shields.io/codecov/c/github/MolSSI/QCEngine.svg?logo=Codecov&logoColor=white)](https://codecov.io/gh/MolSSI/QCEngine)
[![Azure Build Status](https://dev.azure.com/MolSSI/QCArchive/_apis/build/status/MolSSI.QCEngine?branchName=master)](https://dev.azure.com/MolSSI/QCArchive/_build/latest?definitionId=5&branchName=master)
[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/MolSSI/QCEngine.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/MolSSI/QCEngine/context:python)
[![Documentation Status](https://readthedocs.org/projects/qcengine/badge/?version=latest)](https://qcengine.readthedocs.io/en/latest/?badge=latest)
Expand Down
21 changes: 19 additions & 2 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Changelog
=========

.. vX.Y.0 / 2019-MM-DD
.. -------------------
.. vX.Y.0 / 2020-MM-DD
.. --------------------
..
.. New Features
.. ++++++++++++
Expand All @@ -13,6 +13,23 @@ Changelog
.. Bug Fixes
.. +++++++++
v0.14.0 / 2020-MM-DD
--------------------

New Features
++++++++++++

Enhancements
++++++++++++
-(:pr:`215`) Psi4 - indicating location by either PATH or PYTHONPATH sets up both subprocess and API execution.
-(:pr:`215`) ``get_program`` shows the helpful "install this" messages from ``found()`` rather than just saying "cannot be found".

Bug Fixes
+++++++++
-(:pr:`215`) NWChem complains *before* a calculation if the necessary ``networkx`` package not available.


v0.13.0 / 2019-12-10
--------------------

Expand Down
10 changes: 7 additions & 3 deletions qcengine/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ def info_version():
import qcelemental

print(">>> Version information")
print(f"QCEngine version: {__version__}")
print(f"QCElemental version: {qcelemental.__version__}")
print(f"QCEngine: {__version__}")
print(f"QCElemental: {qcelemental.__version__}")
print()

def info_programs(): # lgtm: [py/similar-function]
Expand All @@ -88,12 +88,16 @@ def info_programs(): # lgtm: [py/similar-function]
version = get_program(prog_name).get_version()
if version is None:
version = "???"
print(f"{prog_name} v{version}")
print(f"{prog_name + ':':12} v{version}")

print()
print("Other supported programs:")
print(" ".join(sorted(all_progs - avail_progs)))
print()
print(
"""If you think available programs are missing, query for details: `python -c "import qcengine as qcng; qcng.get_program('<program>')"`"""
)
print()

def info_procedures(): # lgtm: [py/similar-function]
print(">>> Procedure information")
Expand Down
9 changes: 6 additions & 3 deletions qcengine/programs/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,11 @@ def get_program(name: str, check: bool = True) -> "ProgramHarness":
raise InputError(f"Program {name} is not registered to QCEngine.")

ret = programs[name]
if check and not ret.found():
raise ResourceError(f"Program {name} is registered with QCEngine, but cannot be found.")
if check:
try:
ret.found(raise_error=True)
except ModuleNotFoundError as err:
raise ResourceError(f"Program {name} is registered with QCEngine, but cannot be found.") from err

return ret

Expand Down Expand Up @@ -103,7 +106,7 @@ def list_available_programs() -> Set[str]:
register_program(TeraChemHarness())
register_program(TurbomoleHarness())

# Semi-emperical
# Semi-empirical
register_program(MopacHarness())

# AI
Expand Down
13 changes: 11 additions & 2 deletions qcengine/programs/nwchem/runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import numpy as np
import qcelemental as qcel
from qcelemental.models import AtomicResult, Provenance, AtomicInput
from qcelemental.util import safe_version, which
from qcelemental.util import safe_version, which, which_import

from qcengine.config import TaskConfig, get_config
from qcengine.exceptions import UnknownError
Expand Down Expand Up @@ -52,13 +52,22 @@ class Config(ProgramHarness.Config):

@staticmethod
def found(raise_error: bool = False) -> bool:
return which(
qc = which(
"nwchem",
return_bool=True,
raise_error=raise_error,
raise_msg="Please install via http:https://www.nwchem-sw.org/index.php/Download",
)

dep = which_import(
"networkx",
return_bool=True,
raise_error=raise_error,
raise_msg="For NWChem harness, please install via `conda install networkx -c conda-forge`.",
)

return qc and dep

def get_version(self) -> str:
self.found(raise_error=True)

Expand Down
26 changes: 25 additions & 1 deletion qcengine/programs/psi4.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
"""
import json
import os
import sys
from pathlib import Path
from typing import Dict, TYPE_CHECKING

if TYPE_CHECKING:
from ..config import TaskConfig
from qcelemental.models import AtomicInput

from qcelemental.models import AtomicResult
from qcelemental.util import deserialize, parse_version, safe_version, which
from qcelemental.util import deserialize, parse_version, safe_version, which, which_import

from ..exceptions import InputError, RandomError, ResourceError, UnknownError
from ..util import execute, popen, temporary_directory
Expand All @@ -34,6 +36,28 @@ class Config(ProgramHarness.Config):

@staticmethod
def found(raise_error: bool = False) -> bool:
psithon = which("psi4", return_bool=True)
psiapi = which_import("psi4", return_bool=True)

if psithon and not psiapi:
with popen([which("psi4"), "--pythonpath"]) as exc:
exc["proc"].wait(timeout=30)
if "pythonpath does not exist" in exc["stderr"]:
pass
else:
sys.path.append(exc["stdout"].split()[-1])

if psiapi and not psithon:
psiimport = str(Path(which_import("psi4")).parent.parent)
env = os.environ.copy()
env["PYTHONPATH"] = psiimport
with popen(["python", "-c", "import psi4; print(psi4.executable[:-5])"], popen_kwargs={"env": env}) as exc:
exc["proc"].wait(timeout=30)
os.environ["PATH"] += os.pathsep + exc["stdout"].split()[-1]

if psithon or psiapi:
return True

return which(
"psi4",
return_bool=True,
Expand Down

0 comments on commit d31f65b

Please sign in to comment.