@@ -169,16 +169,121 @@ def test_uncertainty_assignment(self):
169169 thermo_unc = self .uncertainty .thermo_input_uncertainties
170170 kinetic_unc = self .uncertainty .kinetic_input_uncertainties
171171
172- np .testing .assert_allclose (
173- thermo_unc ,
174- [1.5 , 1.5 , 2.61966 , 2.51994 , 2.23886 , 1.5 , 2.30761 , 2.41611 , 2.61966 , 2.51994 , 2.61966 , 2.51994 , 2.61966 , 1.5 , 2.23886 , 2.30761 , 1.5 , 2.61966 , 2.07366 , 2.19376 , 2.19376 , 2.30761 , 1.94616 , 2.07366 , 2.07366 ],
175- rtol = 1e-4 ,
176- )
177- np .testing .assert_allclose (
178- kinetic_unc ,
179- [0.5 , 1.118 , 1.9783 , 1.9783 , 1.5363 , 0.5 , 2.0 , 1.5363 , 1.5363 , 0.5 ],
180- rtol = 1e-4
172+ expected_uncorrelated_thermo_uncertainties = np .array ([1.5 , 1.5 , 2.61966 , 2.51994 , 2.23886 , 1.5 , 2.30761 , 2.41611 , 2.61966 , 2.51994 , 2.61966 , 2.51994 , 2.61966 , 1.5 , 2.23886 , 2.30761 , 1.5 , 2.61966 , 2.07366 , 2.19376 , 2.19376 , 2.30761 , 1.94616 , 2.07366 , 2.07366 ])
173+ expected_uncorrelated_kinetic_uncertainties = np .array ([0.5 , 1.118 , 1.9783 , 1.9783 , 1.5363 , 0.5 , 2.0 , 1.5363 , 1.5363 , 0.5 ])
174+ np .testing .assert_allclose (thermo_unc , expected_uncorrelated_thermo_uncertainties , rtol = 1e-4 )
175+ np .testing .assert_allclose (kinetic_unc , expected_uncorrelated_kinetic_uncertainties , rtol = 1e-4 )
176+
177+ # ---------------------------- Now repeat for assign_intermediate_uncertainties -----------------------------
178+ # uncorrelated
179+ self .uncertainty .assign_intermediate_uncertainties (correlated = False )
180+ intermediate_thermo_unc = self .uncertainty .thermo_intermediate_uncertainties
181+ intermediate_kinetic_unc = self .uncertainty .kinetic_intermediate_uncertainties
182+ np .testing .assert_allclose (intermediate_thermo_unc , expected_uncorrelated_thermo_uncertainties , rtol = 1e-4 )
183+ np .testing .assert_allclose (intermediate_kinetic_unc , expected_uncorrelated_kinetic_uncertainties , rtol = 1e-4 )
184+
185+ # correlated
186+ self .uncertainty .assign_intermediate_uncertainties (correlated = True )
187+
188+ # do a spot check on some of the intermediates (dG/dq) these are derivatives, not uncertainties
189+ # Thermo library example
190+ assert self .uncertainty .thermo_intermediate_uncertainties [0 ].keys () == {'Library O(0)' }
191+ assert self .uncertainty .thermo_intermediate_uncertainties [0 ]['Library O(0)' ] == 1
192+
193+ # Thermo GAV example
194+ assert tuple (sorted (self .uncertainty .thermo_intermediate_uncertainties [2 ].keys ())) == ('Estimation HO2(2)' , 'Group(group) O2s-OsH' , 'Group(other) R' , 'Group(radical) HOOJ' )
195+ assert self .uncertainty .thermo_intermediate_uncertainties [2 ]['Estimation HO2(2)' ] == 1
196+ assert self .uncertainty .thermo_intermediate_uncertainties [2 ]['Group(group) O2s-OsH' ] == 2
197+ assert self .uncertainty .thermo_intermediate_uncertainties [2 ]['Group(other) R' ] == 2
198+ assert self .uncertainty .thermo_intermediate_uncertainties [2 ]['Group(radical) HOOJ' ] == 1
199+
200+ # Thermo library + GAV
201+ assert tuple (sorted (self .uncertainty .thermo_intermediate_uncertainties [14 ].keys ())) == ('Estimation CH3(14)' , 'Group(radical) CH3' , 'Library CH4(16)' )
202+ assert self .uncertainty .thermo_intermediate_uncertainties [14 ]['Estimation CH3(14)' ] == 1
203+ assert self .uncertainty .thermo_intermediate_uncertainties [14 ]['Group(radical) CH3' ] == 1
204+ assert self .uncertainty .thermo_intermediate_uncertainties [14 ]['Library CH4(16)' ] == 1
205+
206+ # Kinetics library
207+ assert self .uncertainty .kinetic_intermediate_uncertainties [0 ].keys () == {'Library O(0)+H2O2(3)<=>OH(1)+HO2(2)' }
208+
209+ # Rate rule (exact)
210+ assert tuple (sorted (self .uncertainty .kinetic_intermediate_uncertainties [1 ].keys ())) == ('Estimation Family CH3(14)+PC3H7(15)<=>CH4(16)+CH2CH2CH2(17)' , 'Rate Rule H_Abstraction C/H3/Cs;C_methyl' )
211+ assert self .uncertainty .kinetic_intermediate_uncertainties [1 ]['Estimation Family CH3(14)+PC3H7(15)<=>CH4(16)+CH2CH2CH2(17)' ] == 1
212+ assert self .uncertainty .kinetic_intermediate_uncertainties [1 ]['Rate Rule H_Abstraction C/H3/Cs;C_methyl' ] == 1
213+
214+ # Rate rule (non-exact, multiple rule weights)
215+ assert tuple (sorted (self .uncertainty .kinetic_intermediate_uncertainties [3 ].keys ())) == (
216+ 'Estimation Family C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ,
217+ 'Estimation Nonexact C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ,
218+ 'Rate Rule H_Abstraction C/H3/Cs\\ H2\\ Cs|O;Cd_Cd\\ H2_rad/Cs' ,
219+ 'Rate Rule H_Abstraction C/H3/Cs\\ H3;Cd_Cd\\ H2_pri_rad' ,
181220 )
221+ assert self .uncertainty .kinetic_intermediate_uncertainties [3 ]['Estimation Family C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ] == 1
222+ assert np .isclose (self .uncertainty .kinetic_intermediate_uncertainties [3 ]['Estimation Nonexact C2H3(20)+C3H8(19)<=>C2H4(11)+PC3H7(15)' ], 0.4771212547 , rtol = 1e-4 )
223+ assert self .uncertainty .kinetic_intermediate_uncertainties [3 ]['Rate Rule H_Abstraction C/H3/Cs\\ H2\\ Cs|O;Cd_Cd\\ H2_rad/Cs' ] == 0.5
224+ assert self .uncertainty .kinetic_intermediate_uncertainties [3 ]['Rate Rule H_Abstraction C/H3/Cs\\ H3;Cd_Cd\\ H2_pri_rad' ] == 0.5
225+
226+ # Training reaction
227+ assert self .uncertainty .kinetic_intermediate_uncertainties [5 ].keys () == {'Training H_Abstraction CH3(14)+C2H6(18)<=>CH4(16)+C2H5(12)' }
228+ assert self .uncertainty .kinetic_intermediate_uncertainties [5 ]['Training H_Abstraction CH3(14)+C2H6(18)<=>CH4(16)+C2H5(12)' ] == 1
229+
230+ # PDEP
231+ assert self .uncertainty .kinetic_intermediate_uncertainties [6 ].keys () == {'PDep HCCO(10)(+M)<=>O(0)+C2H(8)(+M)' }
232+ assert self .uncertainty .kinetic_intermediate_uncertainties [6 ]['PDep HCCO(10)(+M)<=>O(0)+C2H(8)(+M)' ] == 1
233+
234+ # correlated uncertainties should match uncorrelated, so check diagonal of covariance matrix
235+ thermo_covariance = np .sqrt (self .uncertainty .get_thermo_covariance_matrix ().diagonal ())
236+ kinetic_covariance = np .sqrt (self .uncertainty .get_kinetic_covariance_matrix ().diagonal ())
237+ assert np .isclose (thermo_covariance , expected_uncorrelated_thermo_uncertainties , rtol = 1e-4 ).all ()
238+ assert np .isclose (kinetic_covariance , expected_uncorrelated_kinetic_uncertainties , rtol = 1e-4 ).all ()
239+
240+ def test_source_correlations (self ):
241+ # Check some examples of different species containing the same sources
242+
243+ # ------------------------------------------------------------------------------
244+ # Make sure CH3 (Library + Radical) has a library index/value in common with CH4
245+ i_CH4 = rmgpy .tools .uncertainty .get_i_thing (rmgpy .species .Species (smiles = 'C' ), self .uncertainty .species_list )
246+ assert i_CH4 >= 0
247+
248+ i_CH3 = rmgpy .tools .uncertainty .get_i_thing (rmgpy .species .Species (smiles = '[CH3]' ), self .uncertainty .species_list )
249+ assert i_CH3 >= 0
250+
251+ self .uncertainty .extract_sources_from_model ()
252+ self .uncertainty .assign_parameter_uncertainties (correlated = True )
253+
254+ src1 = self .uncertainty .species_sources_dict [self .uncertainty .species_list [i_CH4 ]] # CH4
255+ src2 = self .uncertainty .species_sources_dict [self .uncertainty .species_list [i_CH3 ]] # CH3
256+
257+ assert 'Library' in src1
258+ assert 'Library' in src2
259+ assert 'GAV' in src2
260+ assert src1 ['Library' ] == src2 ['Library' ] # make sure they refer to the same library source
261+
262+ # -----------------------------------------------------------------------------
263+ # Make sure CH3X (Library + GAV + Adsorption Correction) has a library index/value in common with CH4 (Library)
264+ i_CH3X = rmgpy .tools .uncertainty .get_i_thing (rmgpy .species .Species (smiles = 'C*' ), self .uncertainty .species_list )
265+ assert i_CH3X == - 1
266+ # This is not in the model, so add it to the species list
267+ CH3X = rmgpy .species .Species (smiles = 'C*' )
268+ CH3X .thermo = self .uncertainty .database .thermo .get_thermo_data (CH3X )
269+ self .uncertainty .species_list .append (CH3X )
270+ try :
271+ i_CH3X = rmgpy .tools .uncertainty .get_i_thing (CH3X , self .uncertainty .species_list )
272+ assert i_CH3X >= 0
273+
274+ self .uncertainty .extract_sources_from_model ()
275+ self .uncertainty .assign_parameter_uncertainties (correlated = True )
276+
277+ src1 = self .uncertainty .species_sources_dict [self .uncertainty .species_list [i_CH4 ]] # CH4
278+ src2 = self .uncertainty .species_sources_dict [self .uncertainty .species_list [i_CH3X ]] # CH3X
279+
280+ assert 'Library' in src1
281+ assert 'Library' in src2
282+ assert 'ADS' in src2
283+ assert 'GAV' in src2
284+ assert src1 ['Library' ] == src2 ['Library' ] # make sure they refer to the same library source
285+ finally :
286+ self .uncertainty .species_list .pop () # remove the extra species so it doesn't affect other tests
182287
183288 def test_local_analysis (self ):
184289 """
0 commit comments