From: sushil r. <ron...@gm...> - 2007-04-25 06:02:25
|
I really appreciate the work you have done. Your code is working fine. It is creating a atomcontainer and also giving a match for few expression from UIT. i have not looked at all the aspect but here is my observation. ///////// Success! /////////// C=C c:c:c:c:c:c c:c:n:c:c:c [$([CX2](=C)=C)] //////////////////////////// like expression are parsed successfully and also return true from UIT. But for a complex expression like this ///////////// Error ! /////////////////// c:c:c:[c,n]:c:c [NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N] //from benchmark() [OX1]=[C]~[N]~[C]=[OX1] [OX1]=[CX3]~[NH1]~[CX3]=[OX1] [$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]//from benchmark() ////////////////////////////////////////////////////// It is giving this error. ********************************************** at org.openscience.cdk.isomorphism.UniversalIsomorphismTester.nodeConstructor( UniversalIsomorphismTester.java:696) at org.openscience.cdk.isomorphism.UniversalIsomorphismTester.buildRGraph( UniversalIsomorphismTester.java:384) at org.openscience.cdk.isomorphism.UniversalIsomorphismTester.search (UniversalIsomorphismTester.java:413) at org.openscience.cdk.isomorphism.UniversalIsomorphismTester.getSubgraphMaps( UniversalIsomorphismTester.java:227) at org.openscience.cdk.smiles.smarts.SMARTSQueryTool.matches( SMARTSQueryTool.java:135) at org.openscience.cdk.applications.SubstructureFinder.main( SubstructureFinder.java:108) *********************************************** This error has nothing to do with the parsing but with creation of atomcontainer. Comment: 1) May be the code is parsing the smarts correctly but that does not mean anything unless we create the atomcontainer. ( As we discuss previously) 2) If this parser is also good for the simple expressions that even the oldest code could do then creating this code will be like reinventing the wheel. 3)As jiao is running out of time with this progress in code only sure he will not be as active as today and progress in code will stop somebody else will have to take over the code,which will be more difficult for cdk because understanding this design is not that way easy for people already having their half hard disk full of chemistry. (as javacc is design is easy to understand any body can easily learn and start coding) (like for this query [$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)] present parser will say this is not valid smart encounter $ so programmer will understand he has to write a simple expression like <$> atomExpression() and parse this kind of SMARTS and create atom container as soon as a token is encounter.) 4) Adapting this design is not permanent solution and also not easy for other developer to adapt and code and contribute. (And we have to remember we need other developer to contribute because it is not possible for one to make a full substructure search and solution like jjtree will always tempting the admin to adapt something that will complete it quickly.) 5) But as our friend has worked on it we have to give a justification to his effort. Well this is my view you can test his code but remember to change the parser line in SQT. as both parser will have same name. looking forward to hear from you. -- ******************************** sushil ronghe Center of Pharmacoinformatics India ********************************* |
From: Jiao, D. <dj...@in...> - 2007-04-25 12:40:57
|
> 1) May be the code is parsing the smarts correctly but that does not > mean anything unless we create the atomcontainer. > ( As we discuss previously) Absolutely agree with you. In fact, I never claim my QueryAtomContainer building is flawless. I have kept saying it's a prototype. Frankly I've never tested it with UIT. Thanks for doing it and I am actually surprised to see that it works for some smarts :) I'll definately take a look at those not working. I feel that make the parsing work is also important, since what we are building is a smarts parser. Having a full picture of the Smarts language and parser at the beginning could only benefit the design. > > 2) If this parser is also good for the simple expressions that even > the oldest code could do then creating this code will be like > reinventing the wheel. Well the wheel has been invented, I totally agree. I don't deem JJTree is reinventing the wheel, but improving it. We could add optimization for example. Besides, I think having the AST could be handy, and make the process more modular. When something becomes modular, very often you could find surprises, as proved by Object Oriented programming. > > 3)As jiao is running out of time with this progress in code only sure > he will not be as active as today and progress in code > will stop somebody else will have to take over the code,which will > be more difficult for cdk because understanding this design is not > that way easy for people already having their half hard disk full of > chemistry. > (as javacc is design is easy to understand any body can easily learn > and start coding) > (like for this query > [$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)] > present parser will say this is not valid smart > encounter $ so programmer will understand he has to write a simple > expression like <$> atomExpression() and parse this kind of > SMARTS and create atom container as soon as a token is encounter.) Thanks for speaking for me. That is not my plan though ;) This week is the final week at my university. It only means I could be more active in the future. Anyway, we are working on an open source project. I believe all of us have to adjust our efforts according to our schedules. For the recursive smarts, if you look at JJTree, you would see that anybody could understand JavaCC and Tree structure can understand JJTree very easily. As to those Recursive parsing, JJTree parses it, but put in the log message that these can't be processed. We need to improve the API to handle recursive smarts, as mentioned before. > > 4) Adapting this design is not permanent solution and also not easy > for other developer to adapt and code and contribute. > (And we have to remember we need other developer to contribute > because it is not possible for one to make a full substructure > search and solution like jjtree will always tempting the admin to > adapt something that will complete it quickly.) On the contrary, I feel it could make collaboration smoother for all of us. People don't need to go into JavaCC to edit java code. So we can use Eclipse full functionality when writing Java code. > 5) But as our friend has worked on it we have to give a justification > to his effort. Thanks. But I don't want anybody to feel obliged to justify my effort. I just want to have some fun and contribute to the best open source project in chem(o)informatics :) Best regards, David |
From: sushil r. <ron...@gm...> - 2007-04-25 14:01:38
|
Dear friend, I was actually studing your code today. I am very happy to see that things are very clear to you. I am ready to merge the code. You do the parsing i will do the matching. but before that assure me you are confident about jjtree parsing will do it. let me explain you this with a simple example. for a expression like this [CH4] or [CX2] i have adapted fallowing logic. Element() [TotalHCount()|TotalConnectionAtom()] setProperty() The element funtion will consume the element i.e C in setProperty method i do this(atom means lastatom that is consumed) if(atom instanceof TotalHCountAtom || atom instanceof TotalConnectionAtom){ container.removeAtom(atom); IQueryAtom Tatom = (IQueryAtom)container.getLastAtom(); container.removeAtom(Tatom); atom.setSymbol(Tatom.getSymbol()); container.addAtom(atom); previousAtom = atom; } In this way i have parsed the CH4 expression in the totalHydrogenCountAtom and set the symbol of that atom to "C". I think this is the flxibility of javacc. You must be agree with this. Now making the API stronger does not mean we should have 100 of classes representing the atom of particular type.( I am justifying the use of TotalHCountAtom in this case and setting it's sumbol is perfect design instead of having a new class. Also it is done so easily in parser) SMARTS atom expression has 10 kind of atom and we already have those classess in SMARTS bond expression has 6 kind we have 4 of them at present. SMARTS operator are 6 we have 4 of then (excluding $ and .) SMarts ( ) are not still implemented. Also you can see how successfully i have parsed the operator atoms like [Cl,Br,I,] or [!r6&r5] in a single function. ///////////////////////////////////////////////////////////////////// void OperatorExpression(): {} { ( Operator() (OperatorAtom() | ExpressionAtom()))* AddOperatorExpression() } void FinalOperatorExpression(): {} { (OperatorAtom() | ExpressionAtom()) [OperatorExpression()] AddFinalOperatorExpression() } ////////////////////////////////////////////////////////////// Can we have this much flexibility in jjtree. If yes i am ready to fallow you. if no you will have to fallow me. that's a deal my friend. what do you think? On 4/25/07, Jiao, Dazhi <dj...@in...> wrote: > > > > 1) May be the code is parsing the smarts correctly but that does not > > mean anything unless we create the atomcontainer. > > ( As we discuss previously) > Absolutely agree with you. In fact, I never claim my QueryAtomContainer > building is flawless. I have kept saying it's a prototype. Frankly I've > never tested it with UIT. Thanks for doing it and I am actually > surprised to see that it works for some smarts :) I'll definately take a > look at those not working. > I feel that make the parsing work is also important, since what we are > building is a smarts parser. Having a full picture of the Smarts > language and parser at the beginning could only benefit the design. > > > > 2) If this parser is also good for the simple expressions that even > > the oldest code could do then creating this code will be like > > reinventing the wheel. > Well the wheel has been invented, I totally agree. I don't deem JJTree > is reinventing the wheel, but improving it. We could add optimization > for example. Besides, I think having the AST could be handy, and make > the process more modular. When something becomes modular, very often you > could find surprises, as proved by Object Oriented programming. > > > > 3)As jiao is running out of time with this progress in code only sure > > he will not be as active as today and progress in code > > will stop somebody else will have to take over the code,which will > > be more difficult for cdk because understanding this design is not > > that way easy for people already having their half hard disk full of > > chemistry. > > (as javacc is design is easy to understand any body can easily learn > > and start coding) > > (like for this query > > [$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)] > > present parser will say this is not valid smart > > encounter $ so programmer will understand he has to write a simple > > expression like <$> atomExpression() and parse this kind of > > SMARTS and create atom container as soon as a token is encounter.) > Thanks for speaking for me. That is not my plan though ;) This week is > the final week at my university. It only means I could be more active in > the future. Anyway, we are working on an open source project. I believe > all of us have to adjust our efforts according to our schedules. > For the recursive smarts, if you look at JJTree, you would see that > anybody could understand JavaCC and Tree structure can understand JJTree > very easily. > As to those Recursive parsing, JJTree parses it, but put in the log > message that these can't be processed. We need to improve the API to > handle recursive smarts, as mentioned before. > > > > 4) Adapting this design is not permanent solution and also not easy > > for other developer to adapt and code and contribute. > > (And we have to remember we need other developer to contribute > > because it is not possible for one to make a full substructure > > search and solution like jjtree will always tempting the admin to > > adapt something that will complete it quickly.) > On the contrary, I feel it could make collaboration smoother for all of > us. People don't need to go into JavaCC to edit java code. So we can use > Eclipse full functionality when writing Java code. > > 5) But as our friend has worked on it we have to give a justification > > to his effort. > Thanks. But I don't want anybody to feel obliged to justify my effort. I > just want to have some fun and contribute to the best open source > project in chem(o)informatics :) > > Best regards, > > David > > > -- ******************************** sushil ronghe Center of Pharmacoinformatics India ********************************* |
From: Jiao, D. <dj...@in...> - 2007-04-25 14:32:16
|
I think [CH4] or [CX2] is nothing but an implicit logical expression. Similar we could think about even [CH2X4] or even more complex expression. I agree with you we should just make the most elementary QueryAtom classes. In fact, I think we should even keep the TotalHCountAtom class as simple as possible, but building the logical relationships in a class in higher level. So, my solution is, JJTree creates AST tree nodes representing these expressions and tokens. Then in the visitor class, I build a tree structure containing all logical operators, and make the matches() method in SMARTSAtom recursively traversing this tree. This was mentioned in an previous email. I copied it here as below. So as to your examples [CH4] -> C & H4 -> AND / \ SymbolAtom TotalHCountAtom [CX2] -> C & X2 -> AND / \ SymbolAtom TotalConnectionAtom [CH2X4] -> C & H2 & X4 -> AND / \ AND TotalConnectionAtom / \ SymbolAtom TotalHCountAtom Then please look at the matches() method in SMARTSAtom to see how these tree nodes can be easily translated to boolean operators in Java, and then use the boolean operators to return a boolean value based on the mathces() result of each individual atom. This only works for atoms. It won't work if there is recursive smarts in the expression. We need to come up with some API for that. David ********** my email on LogicalOperator *************** I think we could keep the QueryAtom classes to the base level. Each QueryAtom subclass (AliphaticAtom, AromaticAtom, QuerySymbolAtom etc...) represents only one basic case. Then we can create a LogicalOperator (or a better name) class, which will contain the logical relationships. So for parsing some Smarts like [R2;C;D3], or [Cl, I, Br], we don't need to create a new class for each of them. Instead, simply build an instance of the Logical Operator. public class LogicalOperator { private Object left; private String name; // "and" , "or", "not", "" private Object right; public Object getLeft() { return left; } public String getName() { return name; } public Object getRight() { return right; } public void setLeft(Object left) { this.left = left; } public void setName(String name) { this.name = name; } public void setRight(Object right) { this.right = right; } } The LogicalOperator is basically a binary tree node. It could be built when parsing smarts. The left/right children could each be a QueryAtom, or another LogicalOperator. Thus, the SmartsAtom will contain a partial binary tree for the logical relationships. It's partial because "NOT" is a unary operator. The leaves are QueryAtom subclasses. Each non-leaf node is a LogicalOperator. The "matches" method in SmartsAtom can then be wrote as below. Basically it recursively traverses the logic tree and return a boolen. public boolean matches(IAtom atom) { return checkLogicalExpression(atom, logicalExpression); } private boolean checkLogicalExpression(IAtom atom, LogicalOperator op) { if ("".equals(op.getName())) { // means there is only one QueryAtom, e.g, parsed from [C], [R] return ((IQueryAtom) op.getLeft()).matches(atom); // then there is only one leaf } Object lo = op.getLeft(); boolean lb = false; if (lo instanceof IQueryAtom) { lb = ((IQueryAtom) lo).matches(atom); } else if (lo instanceof LogicalOperator) { lb = checkLogicalExpression(atom, (LogicalOperator) lo); } Object ro = op.getRight(); boolean rb = true; if (ro != null) { if (ro instanceof IQueryAtom) { rb = ((IQueryAtom) ro).matches(atom); } else if (ro instanceof LogicalOperator) { rb = checkLogicalExpression(atom, (LogicalOperator) ro); } } if ("and".equals(op.getName())) { return (lb && rb); } else if ("or".equals(op.getName())) { return (lb || rb); } else if ("not".equals(op.getName())) { return (!lb); } else { // should never happen return false; } } The only problem is when there is a recursive Smarts inside the brackets. Then we not only have QueryAtom, but also QueryAtomContainer. I don't see how to modify the SmartsAtom. So I think instead, when parsing smarts, we need to build a QueryAtomContainer when there is Recursive Smarts in the Brackets. When there is no Recursive Smarts, return a SmartsAtom. Just my 2 cents. ************* End of email on Logical Operator **************** sushil ronghe wrote: > > Dear friend, > > I was actually studing your code today. > I am very happy to see that things are very clear to you. > I am ready to merge the code. > > You do the parsing i will do the matching. > but before that assure me you are confident about jjtree parsing > will do it. > let me explain you this with a simple example. > > for a expression like this [CH4] or [CX2] > i have adapted fallowing logic. > Element() [TotalHCount()|TotalConnectionAtom()] setProperty() > > The element funtion will consume the element i.e C in setProperty > method i do this(atom means lastatom that is consumed) > > if(atom instanceof TotalHCountAtom || atom instanceof > TotalConnectionAtom){ > container.removeAtom(atom); > IQueryAtom Tatom = (IQueryAtom)container.getLastAtom(); > container.removeAtom(Tatom); > atom.setSymbol( Tatom.getSymbol()); > container.addAtom(atom); > previousAtom = atom; > } > > In this way i have parsed the CH4 expression in the > totalHydrogenCountAtom and set the symbol of that atom to "C". > I think this is the flxibility of javacc. You must be agree with this. > Now making the API stronger does not mean we should have 100 of > classes representing the > atom of particular type.( I am justifying the use of TotalHCountAtom > in this case and setting it's > sumbol is perfect design instead of having a new class. Also it is > done so easily in parser) > SMARTS atom expression has 10 kind of atom and we already have those > classess in > SMARTS bond expression has 6 kind we have 4 of them at present. > SMARTS operator are 6 we have 4 of then (excluding $ and .) > SMarts ( ) are not still implemented. > Also you can see how successfully i have parsed the operator atoms like > [Cl,Br,I,] or [!r6&r5] in a single function. > > ///////////////////////////////////////////////////////////////////// > > void OperatorExpression(): > {} > { > ( Operator() (OperatorAtom() | ExpressionAtom()))* > AddOperatorExpression() > } > void FinalOperatorExpression(): > {} > { > (OperatorAtom() | ExpressionAtom()) [OperatorExpression()] > AddFinalOperatorExpression() > } > > ////////////////////////////////////////////////////////////// > Can we have this much flexibility in jjtree. > > If yes i am ready to fallow you. > if no you will have to fallow me. > > that's a deal my friend. > what do you think? > > > > > > > > > > > > > > > > > > On 4/25/07, *Jiao, Dazhi* <dj...@in... > <mailto:dj...@in...>> wrote: > > > > 1) May be the code is parsing the smarts correctly but that does not > > mean anything unless we create the atomcontainer. > > ( As we discuss previously) > Absolutely agree with you. In fact, I never claim my > QueryAtomContainer > building is flawless. I have kept saying it's a prototype. Frankly > I've > never tested it with UIT. Thanks for doing it and I am actually > surprised to see that it works for some smarts :) I'll definately > take a > look at those not working. > I feel that make the parsing work is also important, since what we are > building is a smarts parser. Having a full picture of the Smarts > language and parser at the beginning could only benefit the design. > > > > 2) If this parser is also good for the simple expressions that even > > the oldest code could do then creating this code will be like > > reinventing the wheel. > Well the wheel has been invented, I totally agree. I don't deem JJTree > is reinventing the wheel, but improving it. We could add optimization > for example. Besides, I think having the AST could be handy, and make > the process more modular. When something becomes modular, very > often you > could find surprises, as proved by Object Oriented programming. > > > > 3)As jiao is running out of time with this progress in code only > sure > > he will not be as active as today and progress in code > > will stop somebody else will have to take over the code,which will > > be more difficult for cdk because understanding this design is not > > that way easy for people already having their half hard disk > full of > > chemistry. > > (as javacc is design is easy to understand any body can easily > learn > > and start coding) > > (like for this query > > > [$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)] > > present parser will say this is not valid smart > > encounter $ so programmer will understand he has to write a simple > > expression like <$> atomExpression() and parse this kind of > > SMARTS and create atom container as soon as a token is > encounter.) > Thanks for speaking for me. That is not my plan though ;) This week is > the final week at my university. It only means I could be more > active in > the future. Anyway, we are working on an open source project. I > believe > all of us have to adjust our efforts according to our schedules. > For the recursive smarts, if you look at JJTree, you would see that > anybody could understand JavaCC and Tree structure can understand > JJTree > very easily. > As to those Recursive parsing, JJTree parses it, but put in the log > message that these can't be processed. We need to improve the API to > handle recursive smarts, as mentioned before. > > > > 4) Adapting this design is not permanent solution and also not easy > > for other developer to adapt and code and contribute. > > (And we have to remember we need other developer to contribute > > because it is not possible for one to make a full substructure > > search and solution like jjtree will always tempting the > admin to > > adapt something that will complete it quickly.) > On the contrary, I feel it could make collaboration smoother for > all of > us. People don't need to go into JavaCC to edit java code. So we > can use > Eclipse full functionality when writing Java code. > > 5) But as our friend has worked on it we have to give a > justification > > to his effort. > Thanks. But I don't want anybody to feel obliged to justify my > effort. I > just want to have some fun and contribute to the best open source > project in chem(o)informatics :) > > Best regards, > > David > > > > > > -- > ******************************** > sushil ronghe > Center of Pharmacoinformatics > India > ********************************* |
From: sushil r. <ron...@gm...> - 2007-04-25 20:48:34
|
ok i am completly agree > Similar we could think about even [CH2X4] or even more complex expression even more complex like [CH2X4+] . > > JJTree creates AST tree nodes representing these > expressions and tokens. Then in the visitor class, I build a tree > structure containing all logical operators, and make the matches() > method in SMARTSAtom recursively traversing this tree. Well that will be easy. i am only worry about performace but that won't matter if this solution works well. But while recursively transversing the tree you will use the if and else statements write. means if node==atom do this like this or else... this will be very important i think. > [CH2X4] -> C & H2 & X4 -> i have already made a SMARTSOperatorAtom class that can handle this expression. Well what about bonds. how do we know that atom is finished and bond has to be added because in the same container we have to add it and UIT or SQT both use this very extensively. The class logicalOperator: if you can see the smartsOperatorAtom class instead of using logicalOperator we can adapt the similar logic. i strongly believe it should be created at the time of parsing. Well let's experiment with this. > We need to come up with some API for that. sure doing recursive smarts will be milestone. i will also study your code. -- ******************************** sushil ronghe Center of Pharmacoinformatics India ********************************* |
From: Jiao, D. <dj...@in...> - 2007-04-25 21:21:07
|
sushil ronghe wrote: > ok i am completly agree > > > Similar we could think about even [CH2X4] or even more complex > expression > > > even more complex like [CH2X4+] . > > > JJTree creates AST tree nodes representing these > expressions and tokens. Then in the visitor class, I build a tree > structure containing all logical operators, and make the matches() > method in SMARTSAtom recursively traversing this tree. > > > > > Well that will be easy. i am only worry about performace but that > won't matter if this > solution works well. But while recursively transversing the tree you > will use the if and else > statements write. > means if node==atom do this like this or else... > this will be very important i think. To eliminate the if, we can make the LogicalOperator an subclass of SMARTSAtom. Just like what you did in SMARTSOpeartorAtom. But without the reference to the QueryAtomContainer. Then the class will be very light-weighted, and no "if...else..." needed anymore. I think the performance of the parser is very good in both cases. It should not be the bottleneck of the whole process comparing to matching algorithms. > > > [CH2X4] -> C & H2 & X4 -> > > > i have already made a SMARTSOperatorAtom class that can handle this > expression. > > > Well what about bonds. > how do we know that atom is finished and bond has to be added because > in the same container we have to add it and UIT or SQT both use this > very extensively. For cases without recursive smarts, this is easy. Anything between the [] can be think as a SMARTSAtom. So bonds and atoms are broken apart during parsing. With recursive smarts, things are much more complicated, because they could also appear in []. For example, [$(CCC),N]=O. Now we not only have atom, but also an atomcontainer. I haven't cleared my thoughts either. I could imagine there being a SMARTSAtomContainer, working like the SMARTSAtom (or your SMARTSOperatorAtom), that could contain both an SMARTSAtom or a AtomContainer.But how that could affect the matching algorithms, I have no idea. Maybe the AST tree can becomes the savor. When a recursive smarts occurs, we can break the smarts apart and build seperate smarts for each case. So [$(CCC),N]=O would becomes CCC=O OR N=O. Then we match these expression individually and join them with boolean operators. This might be an easy solution without too much change in the matching algorithms. But could be of poor performance. > > The class logicalOperator: > if you can see the smartsOperatorAtom class instead of using > logicalOperator we can > adapt the similar logic. i strongly believe it should be created at > the time of parsing. You can think the visitor class as part of parsing. JJTree just break parsing into two steps - AST Tree building, and visiting. |
From: Jiao, D. <dj...@in...> - 2007-04-26 13:59:16
|
sushil ronghe wrote: > ok, > > I want some more information about recursively traversing the tree. > Means how the code will look like. Please look at the visitor classes. > > also tell me how can we print the AST tree. SmartsDumpVisitor (should rename to ASTDumpVisitor) > > > For cases without recursive smarts, this is easy. Anything between the > [] can be think as a SMARTSAtom. So bonds and atoms are broken apart > during parsing. > > > Yes, that is very nice. > > > With recursive smarts, things are much more complicated, because they > could also appear in []. For example, [$(CCC),N]=O. Now we not > only have > atom, but also an atomcontainer. I haven't cleared my thoughts > either. I > could imagine there being a SMARTSAtomContainer, working like the > SMARTSAtom (or your SMARTSOperatorAtom), that could contain both an > SMARTSAtom or a AtomContainer.But how that could affect the matching > algorithms, I have no idea > > > > Also you claim that this parser is best and should be adapted because > it will be > easy for resursive smarts and opertors but it is also looking like > having a trouble > for recursion. No I didn't claim it's the best :) I claimed that JJTree is good for the architecture and reusability. Which recursion are you referring, AST Tree or the LogicalOperator tree? There are problems mainly because the API is not ready, but parsing is nearly ready. > but we will do it together. Glad to work with you! > > What i think we should also have to implement the ( ) expression. > and left the recursion as a last stop. Which () expression are your referring to, group or recursive smarts? Both can be parsed in the JJTree code, but again, no API ready, which is the problem. > We will also have to implement the steriochemistry of bond. Yes! That I definately have a problem. I think the JJTree code is parsing them now, but I am not sure if 100% correctly. Also the JJTree is making assumptions on the [H], you can find the discussion in a previous email sent to this list. The OpenBabel smarts parser seems to have the same problem. Also JJTree is not parsing AtomicMass, it's also mentioned in a previous email. |