Skip to content

Commit

Permalink
Merge pull request #248 from duartegroup/v1.3.5
Browse files Browse the repository at this point in the history
V1.3.5
  • Loading branch information
t-young31 authored Feb 11, 2023
2 parents 6813afd + dded76b commit 161818c
Show file tree
Hide file tree
Showing 22 changed files with 262 additions and 68 deletions.
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ Please replace _#ISSUE_ with just e.g. #12 if this PR resolves issue 12.
* [ ] The changes include an associated explanation of how/why
* [ ] Test pass
* [ ] Documentation has been updated
* [ ] Changelog has been updated
3 changes: 3 additions & 0 deletions .github/workflows/catch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches:
- master
pull_request:
paths-ignore:
- 'doc/**'
- 'examples/**'

env:
BUILD_TYPE: Release
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
branches:
- master
pull_request:
paths-ignore:
- 'doc/**'
- 'examples/**'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pytest_cov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ on:
push:
branches:
- master
- 'v[0-9]+.[0-9]+.[0-9]+'
pull_request:
paths-ignore:
- 'doc/**'
- 'examples/**'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
2 changes: 1 addition & 1 deletion autode/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
- Merge when tests pass
"""

__version__ = "1.3.4"
__version__ = "1.3.5"


__all__ = [
Expand Down
6 changes: 3 additions & 3 deletions autode/hessians.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,9 +234,9 @@ def _mass_weighted(self) -> np.ndarray:
axis=np.newaxis,
)

return Hessian(
H / np.sqrt(np.outer(mass_array, mass_array)), units="J m^-2 kg^-1"
)
return np.array(
H / np.sqrt(np.outer(mass_array, mass_array))
) # J Å^-2 kg^-1

@cached_property
def _proj_mass_weighted(self) -> np.ndarray:
Expand Down
5 changes: 4 additions & 1 deletion autode/log/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

"""
Set up logging with the standard python logging module. Set the log level with
$AUTODE_LOG_LEVEL = {'', INFO, WARNING, DEBUG}
$AUTODE_LOG_LEVEL = {'', ERROR, WARNING, INFO, DEBUG}
i.e. export AUTODE_LOG_LEVEL=DEBUG
Expand Down Expand Up @@ -36,6 +36,9 @@ def get_log_level():
if log_level_str == "INFO":
return logging.INFO

if log_level_str == "ERROR":
return logging.ERROR

return logging.CRITICAL


Expand Down
6 changes: 3 additions & 3 deletions autode/units.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,15 +211,15 @@ def energy_unit_from_name(name: str) -> "autode.units.Unit":


ha_per_ang = CompositeUnit(
ha, per=[ang], aliases=["ha Å-1", "ha Å^-1", "ha/ang"]
ha, per=[ang], aliases=["ha / Å", "ha Å-1", "ha Å^-1", "ha/ang"]
)

ha_per_a0 = CompositeUnit(
ha, per=[a0], aliases=["ha a0-1", "ha a0^-1", "ha/bohr"]
ha, per=[a0], aliases=["ha / a0", "ha a0-1", "ha a0^-1", "ha/bohr"]
)

ev_per_ang = CompositeUnit(
ev, per=[ang], aliases=["ha a0-1", "ev Å^-1", "ev/ang"]
ev, per=[ang], aliases=["ev / Å", "ev Å^-1", "ev/ang"]
)

kcalmol_per_ang = CompositeUnit(
Expand Down
92 changes: 60 additions & 32 deletions autode/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,12 @@
)


def _to(value: Union["Value", "ValueArray"], units: Union[Unit, str]):
def _to(
value: Union["Value", "ValueArray"], units: Union[Unit, str], inplace: bool
) -> Any:
"""
Convert a value or value array to a new unit and return a copy
Convert a value or value array to a new unit and return a copy if
inplace=False
---------------------------------------------------------------------------
Arguments:
Expand All @@ -62,26 +65,29 @@ def _to(value: Union["Value", "ValueArray"], units: Union[Unit, str]):

except StopIteration:
raise TypeError(
f"No viable unit conversion from {value.units} " f"-> {units}"
f"No viable unit conversion from {value.units} -> {units}"
)

# Convert to the base unit, then to the new units
c = float(units.conversion / value.units.conversion)

if isinstance(value, Value):
return value.__class__(float(value) * c, units=units)

elif isinstance(value, ValueArray):
value[:] = np.array(value, copy=True) * c
value.units = units
return value

else:
if not (isinstance(value, Value) or isinstance(value, ValueArray)):
raise ValueError(
f"Cannot convert {value} to new units. Must be one of"
f" Value of ValueArray"
)

if isinstance(value, Value) and inplace:
raise ValueError(
"Cannot modify a value inplace as floats are immutable"
)

# Convert to the base unit, then to the new units
c = float(units.conversion / value.units.conversion)

new_value = value if inplace else value.copy()
new_value *= c
new_value.units = units

return None if inplace else new_value


def _units_init(value, units: Union[Unit, str, None]):
"""Initialise the units of this value
Expand Down Expand Up @@ -171,6 +177,11 @@ def _other_same_units(self, other):

return other.to(self.units)

def _like_self_from_float(self, value: float) -> "Value":
new_value = self.__class__(value, units=self.units)
new_value.__dict__.update(self.__dict__)
return new_value

def __eq__(self, other) -> bool:
"""Equality of two values, which may be in different units"""

Expand Down Expand Up @@ -210,20 +221,26 @@ def __add__(self, other) -> "Value":
if isinstance(other, np.ndarray):
return other + float(self)

return self.__class__(
float(self) + self._other_same_units(other), units=self.units
return self._like_self_from_float(
float(self) + self._other_same_units(other)
)

def __mul__(self, other) -> "Value":
def __mul__(self, other) -> Union[float, "Value"]:
"""Multiply this value with another"""
if isinstance(other, np.ndarray):
return other * float(self)

return self.__class__(
float(self) * self._other_same_units(other), units=self.units
if isinstance(other, Value):
logger.warning(
"Multiplying autode.Value returns a float with no units"
)
return float(self) * self._other_same_units(other)

return self._like_self_from_float(
float(self) * self._other_same_units(other)
)

def __rmul__(self, other) -> "Value":
def __rmul__(self, other) -> Union[float, "Value"]:
return self.__mul__(other)

def __radd__(self, other) -> "Value":
Expand All @@ -232,16 +249,13 @@ def __radd__(self, other) -> "Value":
def __sub__(self, other) -> "Value":
return self.__add__(-other)

def __floordiv__(self, other):
raise NotImplementedError(
"Integer division is not supported by " "autode.values.Value"
)
def __floordiv__(self, other) -> Union[float, "Value"]:
x = float(self) // self._other_same_units(other)
return x if isinstance(other, Value) else self._like_self_from_float(x)

def __truediv__(self, other) -> "Value":
return self.__class__(
float(self) / float(self._other_same_units(other)),
units=self.units,
)
def __truediv__(self, other) -> Union[float, "Value"]:
x = float(self) / self._other_same_units(other)
return x if isinstance(other, Value) else self._like_self_from_float(x)

def __abs__(self) -> "Value":
"""Absolute value"""
Expand All @@ -260,7 +274,7 @@ def to(self, units):
Raises:
(TypeError):
"""
return _to(self, units)
return _to(self, units, inplace=False)


class Energy(Value):
Expand Down Expand Up @@ -643,7 +657,21 @@ def to(self, units) -> Any:
Raises:
(TypeError):
"""
return _to(self, units)
return _to(self, units, inplace=False)

def to_(self, units) -> None:
"""
Convert this array into a set of new units, inplace. This will not copy
the array
-----------------------------------------------------------------------
Returns:
(None)
Raises:
(TypeError):
"""
_to(self, units, inplace=True)

def __array_finalize__(self, obj):
"""See https://numpy.org/doc/stable/user/basics.subclassing.html"""
Expand Down
16 changes: 11 additions & 5 deletions autode/wrappers/QChem.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,17 +158,24 @@ def coordinates_from(self, calc: "CalculationExecutor") -> Coordinates:
"Non-optimisation calculation performed - no change"
" to geometry"
)
return calc.molecule.atoms
return calc.molecule.coordinates

if calc.molecule.n_atoms == 1:
# Coordinate of a single atom will not change
return calc.molecule.coordinates

coords = []

for i, line in enumerate(calc.output.file_lines):

if "Coordinates (Angstroms)" not in line:
if "Coordinates (Angstroms)" in line:
start_idx = i + 2
elif "Standard Nuclear Orientation (Angstroms)" in line:
start_idx = i + 3
else:
continue

"""e.g.
"""e.g.
Coordinates (Angstroms)
ATOM X Y Z
1 O 0.0003489977 -0.1403224128 0.0000000000
Expand All @@ -177,7 +184,6 @@ def coordinates_from(self, calc: "CalculationExecutor") -> Coordinates:
Point Group: cs Number of degrees of freedom: 3
"""

start_idx = i + 2
end_idx = start_idx + calc.molecule.n_atoms
coords = []
for cline in calc.output.file_lines[start_idx:end_idx]:
Expand Down
34 changes: 18 additions & 16 deletions autode/wrappers/XTB.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,31 @@ def print_cartesian_constraints(self, inp_file, molecule):
if molecule.constraints.cartesian is None:
return None

constrained_atom_idxs = [i + 1 for i in molecule.constraints.cartesian]
list_of_ranges, used_atoms = [], []

for i in constrained_atom_idxs:
atom_range = []
if i not in used_atoms:
while i in constrained_atom_idxs:
used_atoms.append(i)
atom_range.append(i)
i += 1
if len(atom_range) in (1, 2):
list_of_ranges += str(atom_range)
else:
list_of_ranges.append(f"{atom_range[0]}-{atom_range[-1]}")
atom_idxs = list(
sorted(int(i) + 1 for i in molecule.constraints.cartesian)
)
list_of_ranges = []

for atom_idx in atom_idxs:
last_range = (
list_of_ranges[-1] if len(list_of_ranges) > 0 else None
)
if last_range is not None and atom_idx - 1 == last_range[-1]:
last_range.append(atom_idx)
else:
list_of_ranges.append([atom_idx])

list_of_ranges_str = [
f"{idxs[0]}-{idxs[-1]}" if len(idxs) > 1 else str(idxs[0])
for idxs in list_of_ranges
]
print(
f"$constrain\n"
f"force constant={self.force_constant}\n"
f'atoms: {",".join(list_of_ranges)}\n'
f'atoms: {",".join(list_of_ranges_str)}\n'
f"$",
file=inp_file,
)

return None

@staticmethod
Expand Down
27 changes: 25 additions & 2 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,30 @@
Changelog
=========

1.3.5
--------
----------


Usability improvements/Changes
******************************
- :code:`autode.value.ValueArray.to()` now defaults to copying the object rather than inplace modification


Functionality improvements
**************************
- Adds a :code:`to_` method to :code:`autode.value.ValueArray` for explicit inplace modification of the array


Bug Fixes
*********
- Fixes :code:`ERROR` logging level being ignored from environment variable :code:`AUTODE_LOG_LEVEL`
- Fixes :code:`autode.values.Value` instances generating items with units on division, and throw a warning if multiplying
- Fixes the printing of cartesian constraints in XTB input files, meaning they are no longer ignored
- Fixes :code:`Hessian` instances changing units when normal modes are calculated
- Fixes an incorrect alias for :code:`ev_per_ang`


1.3.4
--------
----------
Expand All @@ -10,7 +34,6 @@ Feature additions.
Usability improvements/Changes
******************************
* Throw useful exception for invalid :code:`ade.Config.ts_template_folder_path`
* Adds the reaction temperature to the unique reaction hash


Functionality improvements
Expand All @@ -22,7 +45,7 @@ Functionality improvements

Bug Fixes
*********
-
- Fixes calculation :code:`clean_up()` failing with a null filename


1.3.3
Expand Down
2 changes: 1 addition & 1 deletion doc/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ to see all the options.
Logging
-------

To set the logging level to one of {INFO, WARNING, ERROR} set the :code:`AUTODE_LOG_LEVEL`
To set the logging level to one of {DEBUG, INFO, WARNING, ERROR} set the :code:`AUTODE_LOG_LEVEL`
environment variable, in bash::

$ export AUTODE_LOG_LEVEL=INFO
Expand Down
Loading

0 comments on commit 161818c

Please sign in to comment.