@KEHANG and I discovered this behavior yesterday. We found that RMG does not create the proper averaged nodes with closest distance to the exact match, and can instead move further up the tree to an even more general set of nodes. We found this in the R_Addition_MultipleBond family after adding some a new groups Cds_Cds_benzene and Cds-CdH_Cds-CdR_benzene:
L1: R_R L1: Y_J
L2: Cd_R L2: CJ
L3: Cds_Cds L3: CsJ
L4: Cds_Cds_benzene L4: CsJ-HHH
L5: Cds-CdH_Cds-CdR_benzene L4: CsJ-CsHH
He then added a training reaction which matches with Cds-CdH_Cds-CdR_benzene; CsJ-HHH, the reaction between benzene and methyl radical. Then we tried to see whether a reaction between benzene and ethyl radical, which is a sibling of methyl, will use the expected rate rule which adopts from the training reaction added. We would expect RMG to find Cds-CdH_Cds-CdR_benzene; CsJ which uses the value from the training rule. But what we actually get is:

! Average of (Cds-CdH_Cds-CdR_benzene;CsJ-HHH from training reaction 73 +
! Average of (Cds-HH_Cds-HH;CsJ-HHH + Cds-HH_Cds-CsH;CsJ-HHH + Cds-HH_Cds-CsCs
! CsJ-HHH + Cds-HH_Cds-OsH;CsJ-HHH +
.
.
.
! + Cds-CdCd_Cds-CdCd;CsJ-CdCdCs)))
! Estimated using template (Cds_Cds;CsJ) for rate rule (Cds-CdH_Cds-CdR_benzene;CsJ-CsHH)
! Multiplied by reaction path degeneracy 6
ethyl(2)+benzene(1)=C8H11(5) 1.306e+04 2.433 7.412
Somehow, the rate rule used actually is a higher level, more general node. Investigation into the current behavior finds that RMG uses KineticsFamily.rules.fillRulesByAveragingUp at the beginning of the job, which recursively fills in values for general nodes until the the topmost node is reached. However, it does not try to generate values for pairs that come from different levels from the original trees. To demonstrate the behavior consider two trees in a family:
1 A
/ \ / \
2 3 B C
/ \ / \
4 5 D E
fillRulesByAveragingUp tries to generate a value for 1A first by using an average of its children (and if it doesn't have any, it uses itself), the combination of [2,3] with [B,C] from the function getAllCombinations. Then it proceeds to generate values for each of the children needed recursively.
Therefore the children needs for the nodes are:
1A: 2B, 2C, 3B, 3C
2B: 4D, 4E, 5D, 5E
2C: 4C, 5C
3B: 3D, 3E
3C: 3C
As we can see, we never compute cross-layer nodes such as 2E or 4B. In Kehang's case, he has added a value for 4D and wants to use RMG's averaging to get the best value for 4E. We feel that the closest distance match should then either be 2E or 4B if 4E is empty. However, because those nodes were never computed in the averaging up, we in fact move further up and use 2B instead. In more extreme cases in real family, the tree layers may have larger differences in depth, leading to even worse matches.
We propose to change this behavior to actually reflect the distance algorithm, instead of recursively filling until we complete the top node.
Step 1: generate all cross pairs
Step 2: generate all averages
For Step 2, the question remains for whether we should use only children to create values for parent nodes, ie.
Possible 2B linear composition = [2D, 2E, 4B, 5B, 4D, 4E, 5D, 5E] or 2B itself if the value exists
Current 2B linear composition = [4D, 4E, 5D, 5E] or 2B itself if the value exists
It may be better to use 2B = [2D, 2E, 4B, 5B] instead, since it uses all distance 1 nodes to estimate 2B, rather than [4D, 4E, 5D, 5E], the original method which uses all distance 2 nodes. Or perhaps a hybrid combination. Some sort of cross-validation may be useful here. Regardless, even without change the averaging behavior itself, generating all the cross pairs should improve the kinetics estimation dramatically.
@KEHANG and I discovered this behavior yesterday. We found that RMG does not create the proper averaged nodes with closest distance to the exact match, and can instead move further up the tree to an even more general set of nodes. We found this in the R_Addition_MultipleBond family after adding some a new groups
Cds_Cds_benzeneandCds-CdH_Cds-CdR_benzene:He then added a training reaction which matches with
Cds-CdH_Cds-CdR_benzene; CsJ-HHH, the reaction between benzene and methyl radical. Then we tried to see whether a reaction between benzene and ethyl radical, which is a sibling of methyl, will use the expected rate rule which adopts from the training reaction added. We would expect RMG to findCds-CdH_Cds-CdR_benzene; CsJwhich uses the value from the training rule. But what we actually get is:Somehow, the rate rule used actually is a higher level, more general node. Investigation into the current behavior finds that RMG uses
KineticsFamily.rules.fillRulesByAveragingUpat the beginning of the job, which recursively fills in values for general nodes until the the topmost node is reached. However, it does not try to generate values for pairs that come from different levels from the original trees. To demonstrate the behavior consider two trees in a family:fillRulesByAveragingUptries to generate a value for 1A first by using an average of its children (and if it doesn't have any, it uses itself), the combination of [2,3] with [B,C] from the functiongetAllCombinations. Then it proceeds to generate values for each of the children needed recursively.Therefore the children needs for the nodes are:
1A: 2B, 2C, 3B, 3C
2B: 4D, 4E, 5D, 5E
2C: 4C, 5C
3B: 3D, 3E
3C: 3C
As we can see, we never compute cross-layer nodes such as 2E or 4B. In Kehang's case, he has added a value for 4D and wants to use RMG's averaging to get the best value for 4E. We feel that the closest distance match should then either be 2E or 4B if 4E is empty. However, because those nodes were never computed in the averaging up, we in fact move further up and use 2B instead. In more extreme cases in real family, the tree layers may have larger differences in depth, leading to even worse matches.
We propose to change this behavior to actually reflect the distance algorithm, instead of recursively filling until we complete the top node.
Step 1: generate all cross pairs
Step 2: generate all averages
For Step 2, the question remains for whether we should use only children to create values for parent nodes, ie.
Possible 2B linear composition = [2D, 2E, 4B, 5B, 4D, 4E, 5D, 5E] or 2B itself if the value exists
Current 2B linear composition = [4D, 4E, 5D, 5E] or 2B itself if the value exists
It may be better to use 2B = [2D, 2E, 4B, 5B] instead, since it uses all distance 1 nodes to estimate 2B, rather than [4D, 4E, 5D, 5E], the original method which uses all distance 2 nodes. Or perhaps a hybrid combination. Some sort of cross-validation may be useful here. Regardless, even without change the averaging behavior itself, generating all the cross pairs should improve the kinetics estimation dramatically.