Repository: duartegroup/autodE

Issue:
Implement `ade.TransitionState.from_species()`

Comments:

Patch:
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 5ca80c4..5ed79b8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -4,4 +4,3 @@ repos:
     hooks:
       - id: black
         language_version: python3.9
-
diff --git a/autode/__init__.py b/autode/__init__.py
index 0a1dd63..5789c25 100644
--- a/autode/__init__.py
+++ b/autode/__init__.py
@@ -7,6 +7,7 @@ from autode import mol_graphs
 from autode import hessians
 from autode.reactions.reaction import Reaction
 from autode.reactions.multistep import MultiStepReaction
+from autode.transition_states.transition_state import TransitionState
 from autode.atoms import Atom
 from autode.species.molecule import Reactant, Product, Molecule, Species
 from autode.species.complex import NCIComplex
@@ -55,6 +56,7 @@ __all__ = [
     "Reactant",
     "Product",
     "Molecule",
+    "TransitionState",
     "NCIComplex",
     "Config",
     "Calculation",
diff --git a/autode/transition_states/base.py b/autode/transition_states/base.py
index 6ce9b99..7011a6d 100644
--- a/autode/transition_states/base.py
+++ b/autode/transition_states/base.py
@@ -4,6 +4,7 @@ from typing import Optional
 import autode.exceptions as ex
 from autode.atoms import metals
 from autode.config import Config
+from autode.geom import calc_rmsd
 from autode.constraints import DistanceConstraints
 from autode.log import logger
 from autode.methods import get_hmethod, get_lmethod
@@ -74,8 +75,11 @@ class TSbase(Species, ABC):
 
     def __eq__(self, other):
         """Equality of this TS base to another"""
-        logger.warning("TSs types are not equal to any others")
-        return False
+        return (
+            isinstance(other, TSbase)
+            and calc_rmsd(self.coordinates, other.coordinates) < 1e-6,
+            super().__eq__(other),
+        )
 
     def _init_graph(self) -> None:
         """Set the molecular graph for this TS object from the reactant"""
diff --git a/autode/transition_states/transition_state.py b/autode/transition_states/transition_state.py
index 80a17fc..e42d844 100644
--- a/autode/transition_states/transition_state.py
+++ b/autode/transition_states/transition_state.py
@@ -3,6 +3,7 @@ from multiprocessing import Pool
 from autode.values import Frequency
 from autode.transition_states.base import displaced_species_along_mode
 from autode.transition_states.base import TSbase
+from autode.transition_states.ts_guess import TSguess
 from autode.transition_states.templates import TStemplate
 from autode.input_output import atoms_to_xyz_file
 from autode.calculations import Calculation
@@ -358,3 +359,20 @@ class TransitionState(TSbase):
 
         logger.info("Saved TS template")
         return None
+
+    @classmethod
+    def from_species(
+        cls, species: "autode.species.Species"
+    ) -> "TransitionState":
+        """
+        Generate a TS from a species. Note this does not set the bond rearrangement
+        thus mode checking will not work from this species.
+
+        -----------------------------------------------------------------------
+        Arguments:
+            species:
+
+        Returns:
+            (autode.transition_states.transition_state.TransitionState): TS
+        """
+        return cls(ts_guess=TSguess.from_species(species), bond_rearr=None)
diff --git a/doc/changelog.rst b/doc/changelog.rst
index 3097412..a56aa8f 100644
--- a/doc/changelog.rst
+++ b/doc/changelog.rst
@@ -14,7 +14,8 @@ Usability improvements/Changes
 
 Functionality improvements
 **************************
-- 
+- Adds :code:`ade.transition_states.TransitionState.from_species` method to construct transition states from a species or molecule
+
 
 Bug Fixes
 *********


Test patch:
diff --git a/tests/test_ts/test_ts_template.py b/tests/test_ts/test_ts_template.py
index ede99ad..f0443c6 100644
--- a/tests/test_ts/test_ts_template.py
+++ b/tests/test_ts/test_ts_template.py
@@ -5,6 +5,7 @@ from .. import testutils
 import pytest
 from autode.exceptions import TemplateLoadingFailed
 from autode.config import Config
+from autode.species.molecule import Molecule
 from autode.bond_rearrangement import BondRearrangement
 from autode.species.complex import ReactantComplex, ProductComplex
 from autode.species.molecule import Reactant, Product
@@ -238,3 +239,13 @@ def test_inactive_graph():
 
     template.graph = ch3f.graph.copy()
     assert not template.graph_has_correct_structure()
+
+
+@testutils.work_in_zipped_dir(os.path.join(here, "data", "ts_template.zip"))
+def test_ts_from_species_is_same_as_from_ts_guess():
+
+    ts = TransitionState(
+        TSguess(atoms=xyz_file_to_atoms("vaskas_TS.xyz"), charge=0, mult=1)
+    )
+
+    assert TransitionState.from_species(Molecule("vaskas_TS.xyz")) == ts