diff --git a/rmgpy/data/kinetics/rules.py b/rmgpy/data/kinetics/rules.py index 959b96120c2..a185529a6c1 100644 --- a/rmgpy/data/kinetics/rules.py +++ b/rmgpy/data/kinetics/rules.py @@ -550,7 +550,25 @@ def __getAverageKinetics(self, kineticsList): E0 = (E0*0.001,"kJ/mol"), ) return averagedKinetics + + def calculateNormDistance(self, template, otherTemplate): + """ + Calculate the norm distance squared between two rate rules with + `template` and `otherTemplate`. The norm distance is + a^2 + b^2 + c^2 .... when a is the distance between the nodes in the + first tree, b is the distance between the nodes in the second tree, etc. + """ + + # Do it the stupid way first and calculate distances from the top + # rather than from each other for now... it's dumb but need to see results first + import numpy + depth = numpy.array([len(self.ancestors(node)) for node in template]) + otherDepth = numpy.array([len(self.ancestors(otherNode)) for otherNode in otherTemplate]) + distance = numpy.array(depth-otherDepth) + norm = numpy.dot(distance,distance) + return norm + def estimateKinetics(self, template, degeneracy=1): """ Determine the appropriate kinetics for a reaction with the given @@ -573,7 +591,18 @@ def getTemplateLabel(template): kineticsList.append([kinetics, t]) if len(kineticsList) > 0: - + + if len(kineticsList) > 1: + # First, let's cull any pairs that have a longer norm distance than the other + norms = [self.calculateNormDistance(template, t) for kinetics,t in kineticsList] + #for kinetics, t in kineticsList: + # norm = self.calculateNormDistance(template, t) + # norms.append(norm) + minNorm = min(norms) + + + kineticsList = [pair for pair, norm in zip(kineticsList,norms) if norm == min(norms)] + if len(kineticsList) == 1: kinetics, t = kineticsList[0] # Check whether the exact rate rule for the original template (most specific