Skip to content

Commit 1f966fa

Browse files
committed
make uncertainties add in quadrature
1 parent f4bbc2e commit 1f966fa

2 files changed

Lines changed: 24 additions & 25 deletions

File tree

rmgpy/tools/uncertainty.py

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class ThermoParameterUncertainty(object):
4343
This class is an engine that generates the species uncertainty based on its thermo sources.
4444
"""
4545

46-
def __init__(self, dG_library=1.5, dG_QM=3.0, dG_GAV=1.5, dG_group=0.1, dG_ADS_correction=6.918, dG_surf_lib=6.918):
46+
def __init__(self, dG_library=1.5, dG_QM=3.0, dG_GAV=1.5, dG_group=0.316, dG_ADS_correction=6.918, dG_surf_lib=6.918):
4747
"""
4848
Initialize the different uncertainties dG_library, dG_QM, dG_GAV, and dG_other with set values
4949
in units of kcal/mol.
@@ -62,22 +62,22 @@ def get_uncertainty_value(self, source):
6262
"""
6363
Retrieve the uncertainty value in kcal/mol when the source of the thermo of a species is given.
6464
"""
65-
dG = 0.0
65+
varG = 0.0
6666
if 'Library' in source:
67-
dG += self.dG_library
67+
varG += self.dG_library ** 2
6868
if 'Surface_Library' in source:
69-
dG += self.dG_surf_lib
69+
varG += self.dG_surf_lib ** 2
7070
if 'QM' in source:
71-
dG += self.dG_QM
71+
varG += self.dG_QM ** 2
7272
if 'GAV' in source:
73-
dG += self.dG_GAV # Add a fixed uncertainty for the GAV method
73+
varG += self.dG_GAV ** 2 # Add a fixed uncertainty for the GAV method
7474
for group_type, group_entries in source['GAV'].items():
7575
group_weights = [groupTuple[-1] for groupTuple in group_entries]
76-
dG += np.sum([weight * self.dG_group for weight in group_weights])
76+
varG += np.sum([weight ** 2 * self.dG_group ** 2 for weight in group_weights])
7777
if 'ADS' in source:
78-
dG += self.dG_ADS_correction # Add adsorption correction uncertainty
78+
varG += self.dG_ADS_correction ** 2 # Add adsorption correction uncertainty
7979

80-
return dG
80+
return np.sqrt(varG)
8181

8282
def get_partial_uncertainty_value(self, source, corr_source_type, corr_param=None, corr_group_type=None):
8383
"""
@@ -169,21 +169,21 @@ def get_uncertainty_value(self, source):
169169
"""
170170
Retrieve the dlnk uncertainty when the source of the reaction kinetics are given
171171
"""
172-
dlnk = 0.0
172+
varlnk = 0.0
173173
if 'Library' in source:
174174
# Should be a single library reaction source
175-
dlnk += self.dlnk_library
175+
varlnk += self.dlnk_library ** 2
176176
elif 'Surface_Library' in source:
177177
# Should be a single library reaction source
178-
dlnk += self.dlnk_Surface_Library
178+
varlnk += self.dlnk_Surface_Library ** 2
179179
elif 'PDep' in source:
180180
# Should be a single pdep reaction source
181-
dlnk += self.dlnk_pdep
181+
varlnk += self.dlnk_pdep ** 2
182182
elif 'Training' in source:
183183
# Should be a single training reaction
184184
# Although some training entries may be used in reverse,
185185
# We still consider the kinetics to be directly dependent
186-
dlnk += self.dlnk_training
186+
varlnk += self.dlnk_training ** 2
187187
elif 'Rate Rules' in source:
188188
family_label = source['Rate Rules'][0]
189189
source_dict = source['Rate Rules'][1]
@@ -192,16 +192,16 @@ def get_uncertainty_value(self, source):
192192
training_weights = [trainingTuple[-1] for trainingTuple in source_dict['training']]
193193

194194
if 'surface' in family_label.lower():
195-
dlnk += self.dlnk_family_surface
195+
varlnk += self.dlnk_family_surface ** 2
196196
else:
197-
dlnk += self.dlnk_family
197+
varlnk += self.dlnk_family ** 2
198198

199199
N = len(rule_weights) + len(training_weights)
200200
if 'node_std_dev' in source_dict:
201201
# Handle autogen BM trees
202202
if source_dict['node_std_dev'] < 0:
203203
raise ValueError('Invalid value for std dev of kinetics family rule node')
204-
dlnk += source_dict['node_std_dev']
204+
varlnk += np.float_power(source_dict['node_std_dev'], 2.0)
205205
if source_dict['node_n_train'] < 0:
206206
raise ValueError('Invalid number of training reactions for kinetics family rule node')
207207
N = source_dict['node_n_train']
@@ -210,24 +210,24 @@ def get_uncertainty_value(self, source):
210210
# every node template has its own fitted rate rule by definition, but here we use the
211211
# number of training reactions as an approximation of the node's specificity/generality
212212
# and add a penalty for being too general (large # of training reactions)
213-
dlnk += np.log10(N + 1) * self.dlnk_nonexact
213+
varlnk += (np.log10(N + 1) * self.dlnk_nonexact) ** 2
214214
else:
215215
# Handle hand-made trees
216216
if not exact:
217217
# nonexactness contribution increases as N increases
218-
dlnk += np.log10(N + 1) * self.dlnk_nonexact
218+
varlnk += (np.log10(N + 1) * self.dlnk_nonexact) ** 2
219219

220220
# Add the contributions from rules
221-
dlnk += np.sum([weight * self.dlnk_rule for weight in rule_weights])
221+
varlnk += np.sum([weight ** 2 * self.dlnk_rule ** 2 for weight in rule_weights])
222222
# Add the contributions from training
223223
# Even though these source from training reactions, we actually
224224
# use the uncertainty for rate rules, since these are now approximations
225225
# of the original reaction. We consider these to be independent of original the training
226226
# parameters because the rate rules may be reversing the training reactions,
227227
# which leads to more complicated dependence
228-
dlnk += np.sum([weight * self.dlnk_rule for weight in training_weights])
228+
varlnk += np.sum([weight ** 2 * self.dlnk_rule ** 2 for weight in training_weights])
229229

230-
return dlnk
230+
return np.sqrt(varlnk)
231231

232232
def get_partial_uncertainty_value(self, source, corr_source_type, corr_param=None, corr_family=None):
233233
"""

test/rmgpy/tools/uncertaintyTest.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,11 @@ def test_uncertainty_assignment(self):
169169

170170
np.testing.assert_allclose(
171171
thermo_unc,
172-
[1.5, 1.5, 2.0, 1.9, 3.1, 1.5, 1.9, 2.0, 2.0, 1.9, 2.2, 1.9, 2.0, 1.5, 3.1, 1.9, 1.5, 2.0, 1.7, 1.8, 1.8, 1.9, 1.8, 1.9, 1.9],
172+
[1.5, 1.5, 1.7745, 1.7461, 2.1447, 1.5, 1.6879, 1.7173, 1.7745, 1.7461, 1.7745, 1.7461, 1.7745, 1.5, 2.1447, 1.6879, 1.5, 1.7745, 1.6277, 1.6581, 1.6581, 1.6879, 1.5967, 1.6277, 1.6277],
173173
rtol=1e-4,
174174
)
175175
np.testing.assert_allclose(
176176
kinetic_unc,
177-
# the 13.598 value comes from the SIDT tree node uncertainty: 11.54 + non-exact penalty for N=1: log10(1+1) * 3.5 + family uncertainty: 1.0
178-
[0.5, 1.5, 3.169924, 3.169924, 2.553605, 0.5, 2.0, 13.5938, 13.5938, 0.5],
177+
[0.5, 1.118, 1.9783, 1.9783, 1.5363, 0.5, 2.0, 11.6312, 11.6312, 0.5],
179178
rtol=1e-4
180179
)

0 commit comments

Comments
 (0)