User 870ab5b546
07-09-2007 13:58:38
Hi,
In your Friedel-Crafts reaction definition, you have the charge on the aromatic atoms determine the selectivity [-energyE(ratom(1))], but steric factors also play a large role. In the case of toluene, the charge factor predicts that the major product is ortho, but, in fact, the major product is para. I can increase the tolerance slightly to give both products, but how can I rewrite the selectivity rule so that the major product is para?
I also suggest you expand your Friedel-Crafts example to include acyl anhydrides. Add O to the possibilities for atom 3, and add this exclude rule:
(match(ratom(3), "[O:1]", 1) && !match(ratom(3), "O=C[O:1]C=O", 1))
-- Bob
ChemAxon d76e6e95eb
07-09-2007 18:16:52
Your comment is right, no steric effect is considered in the current selectivity rule. You can combine the existing electronic effect with steric using the for example the stericHindrance function.
The stericHyndrance function calculates the geometry of the lowest energy conformer of the given molecule and uses the distances and covalent radii for calculating the steric hindrance of an atom.
The stericEffectIndex performes similar calculation but uses topological distances. Though this latter is very fast (no geometry optimization), it is not perfect for the effect of ortho substituents like isopropyl or isobuthyl.
These two functions are available at the moment, I am very interested in your opinion of their applicability.
(We plan to design a new topological function sometimes in the future which can provide better rapid hindrance prediction.)
User 870ab5b546
07-09-2007 18:26:50
Well, we need to say that if the difference in energyE between two ratom(1) possibilities is less than a certain amount, then the selectivity is determined by sterics.
I don't know how to write that in Chemical Terms Language, but perhaps you do.
BTW, I just started using dreidingEnergy(product(0)) > 100 as an exclude rule for intramolecular reactions, and it works very nicely to rule out cyclization reactions of trans-alkenes and alkynes, meta substitution in intramolecular Friedel-Crafts reactions, etc. I needed to acquire the Geometry plugin to use it.
User 870ab5b546
10-09-2007 14:41:27
All right, I'm trying to write an appropriate selectivity rule, and I am getting bizarre error messages.
The reaction is nitration:
Code: |
<?xml version="1.0" ?>
<MDocument>
<MChemicalStruct>
<reaction>
<propertyList>
<property dictRef="NAME" title="NAME">
<scalar><![CDATA[arene nitration]]></scalar>
</property>
</propertyList>
<reactantList>
<molecule molID="m1">
<atomArray
atomID="a1 a2"
elementType="C H"
mrvMap="1 2"
mrvQueryProps="a1 0"
x2="-8.620575316403775 -8.620575316403775"
y2="11.09088749380601 12.630887493806009"
/>
<bondArray>
<bond atomRefs2="a1 a2" order="1" />
</bondArray>
</molecule>
</reactantList>
<productList>
<molecule molID="m2">
<atomArray
atomID="a1 a2 a3 a4"
elementType="N C O O"
formalCharge="1 0 0 -1"
mrvMap="3 1 0 0"
mrvQueryProps="0 a1 0 0"
x2="9.966641700900924 10.069514351401217 8.632962579072888 11.30032082272896"
y2="11.82239134287164 10.285831152778506 12.592391342871641 12.59239134287164"
/>
<bondArray>
<bond atomRefs2="a1 a4" order="1" />
<bond atomRefs2="a2 a1" order="1" />
<bond atomRefs2="a1 a3" order="2" />
</bondArray>
</molecule>
</productList>
</reaction>
</MChemicalStruct>
</MDocument> |
I want to find those ratom(1) whose energyE() is within 0.3 of the minimum energyE(ratom(1)), and select the least hindered one. My best shot at a selectivity rule is,
minE = min(energyE(ratom(1)));
-stericHindrance(filter(reactant(0), "energyE(ratom(1)) - minE <= 0.3"))
I get this ReactionException:
Code: |
chemaxon.reaction.ReactionException: Error while evaluating expression:
minE = min(energyE(ratom(1))); -stericHindrance(filter(reactant(0), "energyE(ratom(1)) - minE <= 0.3"))
Error while compiling expression:
energyE(ratom(1)) - minE <= 0.3
Syntax Error (implicit multiplication not enabled)
at chemaxon.reaction.ReactionPerformer.reactHit(ReactionPerformer.java:987)
at chemaxon.reaction.ReactionPerformer.reactOne(ReactionPerformer.java:823)
at chemaxon.reaction.ReactionPerformer.reactBase(ReactionPerformer.java:767)
at chemaxon.reaction.ReactionPerformer.react(ReactionPerformer.java:749)
at chemaxon.reaction.Reactor.reactMain(Reactor.java:1582)
at chemaxon.reaction.Reactor.react(Reactor.java:1522) |
Where the heck does implicit multiplication appear in the expression?
I've tried many other versions of the rule, none of which appear to work any better. For example, if I omit reactant(0) from the filter expression or change it to ratom(1), I get this error message:
Code: |
SynthSolver: caught ReactionException:
could not convert to double[]: java.lang.Object@13ebe7b
chemaxon.reaction.ReactionException: could not convert to double[]: java.lang.Object@13ebe7b
at chemaxon.reaction.ReactionPerformer.reactHit(ReactionPerformer.java:987)
at chemaxon.reaction.ReactionPerformer.reactOne(ReactionPerformer.java:823)
at chemaxon.reaction.ReactionPerformer.reactBase(ReactionPerformer.java:767)
at chemaxon.reaction.ReactionPerformer.react(ReactionPerformer.java:749)
at chemaxon.reaction.Reactor.reactMain(Reactor.java:1582)
at chemaxon.reaction.Reactor.react(Reactor.java:1522) |
Zsolt wrote that you were trying to make Chemical Terms easier for chemists to use than a programming language. I think you have a ways to go toward that goal. It would help a lot if your error messages were more transparent.
User 870ab5b546
11-09-2007 14:14:42
I get the same error when I formulate the selectivity rule this way:
-stericHindrance(filter(ratom(1), "energyE() - minValue(ratom(1), 'energyE()') <= 0.03"))
Code: |
chemaxon.reaction.ReactionException: Error while evaluating expression:
-stericHindrance(filter(ratom(1), "energyE() - minValue(ratom(1), 'energyE()') <= 0.03"))
Error while compiling expression:
energyE() - minValue(ratom(1), 'energyE()') <= 0.03
Syntax Error (implicit multiplication not enabled)
at chemaxon.reaction.ReactionPerformer.reactHit(ReactionPerformer.java:987)
at chemaxon.reaction.ReactionPerformer.reactOne(ReactionPerformer.java:823)
at chemaxon.reaction.ReactionPerformer.reactBase(ReactionPerformer.java:767)
at chemaxon.reaction.ReactionPerformer.react(ReactionPerformer.java:749)
at chemaxon.reaction.Reactor.reactMain(Reactor.java:1582)
at chemaxon.reaction.Reactor.react(Reactor.java:1522) |
If instead I formulate two separate rules:
Selectivity: -energyE(ratom(1))
Exclude: stericHindrance(ratom(2)) - minValue(ratom(2), "stericHindrance()") >= 0.001
I no longer get a ReactionException, but it's as if I did not have the exclude rule at all.
ChemAxon e08c317633
11-09-2007 17:12:23
Hi Bob,
I have corrected some errors in your Chemical Terms expression. The corrected expression will not throw any exceptions, but still will not work as you expect:
Code: |
minE = min(energyE(ratom(1)));
-stericHindrance(reactant(0), min(filter(ratom(1), "energyE() - minE <= 0.03"))) |
Corrected errors, remarks:
1. The filter Chemical Terms function returns an atom index array, and if stericHindrance() function gets this array as input parameter then it will return an array too (the steric hindrance of all atoms ordered by atom index). The returned array will be interpreted by Reactor as a multiple selectivity rule (see Reaction rules section of the Reactor manual).
I have modified it to
to select only one atom index from the indexes filter(...) returns. Using this expression it will be a "simple" selectivity rule. The multiple selectivity rule will work, but has no useful chemical meaning.
2. In reaction context stericHindrance() function also requires a molecule parameter if the atom parameter is not referenced by atom map (e.g. ratom(1)), but by atom index:
Code: |
stericHindrance(reactant(0), <atomIndex>) |
The documentation says nothing about this, we will correct it.
3. Code: |
minE = min(energyE(ratom(1))); |
This expression does not really make sense: "energyE(ratom(1))" returns only one value, and the minimum of this one value is the value itself.
4. In the filtering expression of the filter function it is advised to use only one function that calculates atomic results. I have replaced the second part of the filtering expression with minE "constant".
I hope this helps,
Zsolt
User 870ab5b546
11-09-2007 17:36:20
Yes, that helps some. At least it explains why I was getting incomprehensible error messages.
But, like you said, it doesn't give me the result I want. The filter expression returns an array of atoms, and I want to find the one with the least steric hindrance. But stericHindrance() doesn't operate on arrays (edited: it does operate on arrays), and the Chemical Terms language doesn't have a for loop that I could use to loop through all the atoms returned by the filter function to see which has the smallest steric hindrance.
I tried breaking the expressions up: steric hindrance in Selectivity and energy in Reactivity:
Code: |
<property dictRef="REACTIVITY" title="REACTIVITY">
<scalar><![CDATA[minE = min(energyE(ratom(1)));
energyE(ratom(1)) - minE < 0.03]]></scalar>
</property>
<property dictRef="SELECTIVITY" title="SELECTIVITY">
<scalar><![CDATA[-stericHindrance(ratom(1))]]></scalar>
</property> |
I thought that the reactivity rule would keep any atom with an energy more than 0.03 above the minimum from reacting. But it does not appear to work that way; instead, the reactivity rule is pretty much ignored, and I get meta and para products, even with anisole as the substrate, and no matter how small I make the constant. What am I doing wrong now?
When I change the reactivity rule above to an Exclude rule, I get a ReactionException. It doesn't like the minE = min(energyE(ratom(1))); expression.
User 870ab5b546
14-09-2007 00:04:19
Thank you for the explanation of why my expressions weren't working. Although my head hurts now.
I am glad to hear that you are redesigning the Chemical Terms Language. If I cannot express a rule as simple as, "Among the C atoms with charges within 0.03 units of the minimum, choose the least hindered," there is a serious problem.
I would be happy to contribute to the development of a more versatile Chemical Terms Language. I strongly suggest you use an existing programming language such as Java as a model for developing a new Chemical Terms Language. Whether you make it object-oriented is less relevant than making rules read in a logical, self-evident fashion. I would like to see a rule that would read something like this:
Code: |
// ratom(1) is the set of atoms satisfying the reaction definition;
// the following code restricts the set
int minE = ratom(1).min(energyE());
for each ratom(1) atom
if (energyE(atom) - minE > 0.03)
ratom(1).remove(atom);
ratom(1) = ratom(1).minAtom(stericHindrance());
// or, if multiple products are desired:
// ratom(1).sort(stericHindrance(), ASCENDING));
reaction.set(ratom(1));
|
I would like to see the filter expressions disappear entirely. They are very confusing to write and hard to read. I would also like to see the plugin calculations look much more like they do in the API.
I don't think chemists will have a harder time learning how to use a Chemical Terms Language with simple terms like if, for, etc. than they will learning the existing language.
ChemAxon d76e6e95eb
14-09-2007 14:24:44
You are right, the current syntax of the filter expressions is very hard to read, it is a known problem and we will try to make it much simpler. Furthermore, as Zsolt said, we will redesign the Chemical Terms language to have a simpler syntax in general.
Since the reengineering of Chemical Terms has not been started yet (though decided more than a year ago), the planned format is not yet fixed. However we do not plan to make it similar to Java! We would like to design a syntax, that can be easily learned by a chemist who has no programming experience.
Some features of Java we would like to avoid: case sensitivity, function parentheses even if there are no parameters, fixed parameter order, zero based indexing, the form of logic operators (||, &&).
User 870ab5b546
14-09-2007 14:53:22
You may be chasing a mirage when you say you would like to design a syntax that a chemist who has no programming experience can use. By definition, you are designing a programming language.
Having said that, you can certainly make the language more similar to Basic or AppleScript than to Java. How about this?
Code: |
// ratom(1) is the set of atoms satisfying the reaction definition;
// the following code restricts the set
minE = minimum of energyE of each ratom(1);
for each atom in ratom(1)
if (energyE of atom) - minE > 0.03
then remove atom from ratom(1);
ratom(1) = atom with minimum of stericHindrance of each ratom(1);
// or, if multiple products are desired:
// sort ratom(1) by stericHindrance of each ratom(1), ascending;
|
ChemAxon d76e6e95eb
14-09-2007 15:17:08
No, we do not plan to make Chemical Terms a programming language. I do not exclude this possibility, but not at the moment. Conditonal expressions might appear (if), but we do not plan to add looping.
User 870ab5b546
17-09-2007 12:18:49
Hooray! With your help, I have succeeded in writing rules for electrophilic aromatic substitution reactions that take both sterics and electronics into account.
Reactivity rule:
Code: |
minE = min(energyE(reactant(0), filter(reactant(0), "aromaticAtom()")));
energyE(ratom(1)) - minE <= 0.05 |
Aromatic atoms must have localization energy close to the minimum of all aromatic atoms to provide the main product, but they don't have to be the absolute minimum.
Selectivity rule:
Code: |
-stericHindrance(ratom(1)) |
Among atoms determined by the reactivity rule, aromatic atom with the least steric hindrance provides the main product.
Tolerance:
Excludes ortho product for most substituents except OH and O-.
Thanks again for your help!
-- Bob