Skip to content

Commit

Permalink
Merge pull request #43 from ReactionMechanismGenerator/py3
Browse files Browse the repository at this point in the history
The tests are passing with krsna's Openbabel 2.4.1a and ampayne's RMG 3.0.0b. 馃帀 Coverage is down a touch (1.11%) but this is because some of our import shuffling - Addressing this coverage will be done in #45 but for now, we can merge this in.
  • Loading branch information
Nate Harms committed Oct 22, 2019
2 parents 02f5f8a + 239798d commit 73ec0f3
Show file tree
Hide file tree
Showing 38 changed files with 7,720 additions and 7,549 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*.pyc
*.so
*.pyd
*.symm
*.coverage

# Image files generated
Expand All @@ -29,6 +30,9 @@
*.idea/

# Gaussian scratch files and ase related io files
*.symm
*.ase
*.com
*.log
*.ts
*.kinetics
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
language: python
python:
- "2.7"
- "3.7"
install:
- cd ..
# Install miniconda
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget http://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget http://repo.continuum.io/miniconda/Miniconda2-latest-MacOSX-x86_64.sh -O miniconda.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then wget http://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O miniconda.sh; fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH=$HOME/miniconda/bin:$PATH
# Update conda
Expand All @@ -21,7 +21,7 @@ install:
- conda env create -f environment.yml
- source activate tst_env
- conda list
- yes | conda uninstall --force openbabel
#- yes | conda uninstall --force openbabel

script:
- make unittests
Expand Down
4 changes: 3 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
unittest unittests test-unittest test-unittests:
nosetests --nocapture --nologcapture --all-modules --verbose --with-coverage --cover-package=autotst
rm -r species
rm -r ts
rm -r ts
rm -r test/species
rm -r test/ts
1 change: 1 addition & 0 deletions autotst/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# -*- coding: utf-8 -*-

import os
import rdkit

__file_path = os.path.dirname(os.path.abspath(__file__))

Expand Down
65 changes: 35 additions & 30 deletions autotst/calculator/gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,6 @@
import numpy as np
from cclib.io import ccread

import rmgpy
from rmgpy.molecule import Molecule as RMGMolecule
from rmgpy.reaction import Reaction as RMGReaction

import autotst
from autotst.reaction import Reaction, TS
from autotst.species import Species, Conformer
Expand All @@ -46,6 +42,10 @@
from ase.io.gaussian import read_gaussian, read_gaussian_out
from ase.calculators.gaussian import Gaussian as ASEGaussian

import rmgpy
from rmgpy.molecule import Molecule as RMGMolecule
from rmgpy.reaction import Reaction as RMGReaction


class Gaussian():

Expand Down Expand Up @@ -158,7 +158,7 @@ def get_rotor_calc(self,
a, b, c, d = locked_torsion.atom_indices
addsec += 'D {0} {1} {2} {3} F\n'.format(a+1, b+1, c+1, d+1)

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()
mult = self.conformer.rmg_molecule.multiplicity

new_scratch = os.path.join(
Expand Down Expand Up @@ -207,7 +207,7 @@ def get_conformer_calc(self):
assert isinstance(
self.conformer, Conformer), "A Conformer object was not provided..."

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()

label = "{}_{}".format(self.conformer.smiles, self.conformer.index)

Expand Down Expand Up @@ -252,7 +252,7 @@ def get_shell_calc(self):
assert isinstance(self.conformer, TS), "A TS object was not provided..."
assert self.conformer.direction.lower() in ["forward", "reverse"]

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()

label = self.conformer.reaction_label + "_" + self.conformer.direction.lower() + "_shell_" + str(self.conformer.index)

Expand All @@ -267,10 +267,15 @@ def get_shell_calc(self):
os.makedirs(new_scratch)
except OSError:
pass

ind1 = self.conformer.rmg_molecule.getLabeledAtom("*1").sortingLabel
ind2 = self.conformer.rmg_molecule.getLabeledAtom("*2").sortingLabel
ind3 = self.conformer.rmg_molecule.getLabeledAtom("*3").sortingLabel

#if self.conformer.reaction_family != "Some reaction family with 4 labeled atoms..."
if self.conformer.reaction_family.lower() in ["h_abstraction", "intra_h_migration", "r_addition_multiplebond"]:
ind1 = self.conformer.rmg_molecule.get_labeled_atoms("*1")[0].sorting_label
ind2 = self.conformer.rmg_molecule.get_labeled_atoms("*2")[0].sorting_label
ind3 = self.conformer.rmg_molecule.get_labeled_atoms("*3")[0].sorting_label
else:
logging.error("Reaction family {} is not supported...".format(self.conformer.reaction_family))
raise AssertionError

combos = ""
combos += "{0} {1} F\n".format(ind1+1, ind2+1)
Expand Down Expand Up @@ -321,7 +326,7 @@ def get_center_calc(self):
a, b = combo
addsec += "{0} {1} F\n".format(a + 1, b + 1)

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()

label = self.conformer.reaction_label + "_" + self.conformer.direction.lower() + "_center_" + str(self.conformer.index)

Expand Down Expand Up @@ -369,7 +374,7 @@ def get_overall_calc(self):

assert isinstance(self.conformer, TS), "A TS object was not provided..."

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()

label = self.conformer.reaction_label + "_" + self.conformer.direction.lower() + "_" + str(self.conformer.index)

Expand Down Expand Up @@ -415,7 +420,7 @@ def get_irc_calc(self):

assert isinstance(self.conformer, TS), "A TS object was not provided..."

self.conformer.rmg_molecule.updateMultiplicity()
self.conformer.rmg_molecule.update_multiplicity()
label = self.conformer.reaction_label + "_irc_" + self.conformer.direction + "_" + str(self.conformer.index)

new_scratch = os.path.join(
Expand Down Expand Up @@ -491,39 +496,39 @@ def validate_irc(self):

pth1 = list()
steps = list()
with open(irc_path) as outputFile:
for line in outputFile:
with open(irc_path) as output_file:
for line in output_file:
line = line.strip()

if line.startswith('Point Number:'):
if int(line.split()[2]) > 0:
if int(line.split()[-1]) == 1:
ptNum = int(line.split()[2])
pth1.append(ptNum)
pt_num = int(line.split()[2])
pth1.append(pt_num)
else:
pass
elif line.startswith('# OF STEPS ='):
numStp = int(line.split()[-1])
steps.append(numStp)
num_step = int(line.split()[-1])
steps.append(num_step)
# This indexes the coordinate to be used from the parsing
if steps == []:
logging.error('No steps taken in the IRC calculation!')
return False
else:
pth1End = sum(steps[:pth1[-1]])
# Compare the reactants and products
ircParse = ccread(irc_path)
irc_parse = ccread(irc_path)


atomcoords = ircParse.atomcoords
atomnos = ircParse.atomnos
atomcoords = irc_parse.atomcoords
atomnos = irc_parse.atomnos

mol1 = RMGMolecule()
mol1.fromXYZ(atomnos, atomcoords[pth1End])
mol1.from_xyz(atomnos, atomcoords[pth1End])
mol2 = RMGMolecule()
mol2.fromXYZ(atomnos, atomcoords[-1])
mol2.from_xyz(atomnos, atomcoords[-1])

testReaction = RMGReaction(
test_reaction = RMGReaction(
reactants=mol1.split(),
products=mol2.split(),
)
Expand Down Expand Up @@ -557,19 +562,19 @@ def validate_irc(self):
for possible_reactant in possible_reactants:
reactant_list = []
for react in possible_reactant:
reactant_list.append(react.toSingleBonds())
reactant_list.append(react.to_single_bonds())

for possible_product in possible_products:
product_list = []
for prod in possible_product:
product_list.append(prod.toSingleBonds())
product_list.append(prod.to_single_bonds())

targetReaction = RMGReaction(
target_reaction = RMGReaction(
reactants=list(reactant_list),
products=list(product_list)
)

if targetReaction.isIsomorphic(testReaction):
if target_reaction.is_isomorphic(test_reaction):
logging.info("IRC calculation was successful!")
return True
logging.info("IRC calculation failed for {} :(".format(irc_path))
Expand Down
38 changes: 34 additions & 4 deletions autotst/calculator/gaussianTest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

##########################################################################
#
# AutoTST - Automated Transition State Theory
#
# Copyright (c) 2015-2018 Prof. Richard H. West (r.west@northeastern.edu)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the 'Software'),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
##########################################################################

import unittest

import os, shutil
Expand All @@ -6,10 +35,6 @@
import numpy as np
from cclib.io import ccread

import rmgpy
from rmgpy.molecule import Molecule as RMGMolecule
from rmgpy.reaction import Reaction as RMGReaction

import autotst
from autotst.reaction import Reaction, TS
from autotst.species import Species, Conformer
Expand All @@ -22,8 +47,13 @@
from ase.io.gaussian import read_gaussian, read_gaussian_out
from ase.calculators.gaussian import Gaussian as ASEGaussian

import rmgpy
from rmgpy.molecule import Molecule as RMGMolecule
from rmgpy.reaction import Reaction as RMGReaction

class TestGaussian(unittest.TestCase):
def setUp(self):
os.environ["PATH"] = os.path.expandvars("$AUTOTST/test/bin:") + os.environ["PATH"]
rxn = Reaction(label='C+[O]O_[CH3]+OO')
ts = rxn.ts["forward"][0]
ts.get_molecules()
Expand Down
6 changes: 3 additions & 3 deletions autotst/calculator/orca.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def load_conformer_attributes(self):
else:
self.base = self.label

self.charge = self.conformer.rmg_molecule.getNetCharge()
self.charge = self.conformer.rmg_molecule.get_net_charge()
self.mult = self.conformer.rmg_molecule.multiplicity

try:
Expand Down Expand Up @@ -168,7 +168,7 @@ def write_fod_input(self,directory=None):
f.write(self.coords)
f.write('*\n')

def check_NormalTermination(self,path):
def check_normal_termination(self,path):
"""
checks if an Orca job terminated normally.
Returns True is normal termination and False if something went wrong.
Expand All @@ -190,7 +190,7 @@ def read_fod_log(self,path):
"""
assert os.path.exists(path),'It seems {} is not a valid path'.format(path)

if self.check_NormalTermination(path):
if self.check_normal_termination(path):
N_FOD = None
for line in open(path,'r').readlines():
if 'N_FOD =' in line:
Expand Down
33 changes: 31 additions & 2 deletions autotst/calculator/orcaTest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-

##########################################################################
#
# AutoTST - Automated Transition State Theory
#
# Copyright (c) 2015-2018 Prof. Richard H. West (r.west@northeastern.edu)
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the 'Software'),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
#
##########################################################################

import unittest

import os
Expand Down Expand Up @@ -31,10 +60,10 @@ def test_write_fod_input(self):
self.orca.write_fod_input()
self.assertTrue(os.path.exists(os.path.join(self.orca.directory,'C_fod.inp')))

def test_check_NormalTermination(self):
def test_check_normal_termination(self):
path = os.path.expandvars(
"$AUTOTST/test/bin/log-files/C_fod.log")
self.assertTrue(self.orca.check_NormalTermination(path))
self.assertTrue(self.orca.check_normal_termination(path))

def test_read_fod_log(self):
path = os.path.expandvars(
Expand Down
Loading

0 comments on commit 73ec0f3

Please sign in to comment.