MolAtom.getParent() for shortcut groups

User 870ab5b546

06-08-2012 18:01:35

The substrate:


<?xml version="1.0" ?>
<cml>
<MDocument>
<MEFlow id="o1" arcAngle="150.0" headSkip="0.25" headLength="0.5"
headWidth="0.4" tailSkip="0.25">
<MEFlowBasePoint atomRef="m1.a16" />
<MAtomSetPoint atomRefs="m1.a18" />
</MEFlow>
<MEFlow id="o2" arcAngle="248.39738999999997" headSkip="0.25"
headLength="0.5" headWidth="0.4" tailSkip="0.15">
<MAtomSetPoint atomRefs="m1.a18 m1.a19" />
<MAtomSetPoint atomRefs="m1.a19" />
</MEFlow>
<MChemicalStruct>
<molecule molID="m1">
<atomArray
atomID="a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19"
elementType="C C C O C C C C O R O R C C C O C H R"
formalCharge="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 0 0 0"
sgroupRef="0 0 0 0 0 0 0 0 0 sg1 0 sg2 0 0 0 0 0 0 sg3"
x2="56.619385084481216 58.8193132907819 60.345493480725175 60.056743785900956 61.919799891371575 53.038983997517455 54.372663119345496 55.70634224117352 52.64040266805957 51.95003955449017 55.70634224117352 57.040021363001564 53.32289372729834 53.69407132324747 55.74962468213605 55.94212956494855 58.15587803906965 58.1349983215332 59.6749983215332"
y2="-8.345448667391597 -9.115448667391597 -8.489823514803707 -7.431073324068844 -8.826698018893062 -6.630571811131835 -7.400571811131836 -6.630571811131835 -5.14304603864667 -7.719516254159119 -5.090571811131836 -7.400571811131836 -9.91384740048293 -11.646347972687519 -11.790722324188984 -13.619472896393575 -11.969401713045828 -14.485625267028809 -14.485625267028809"
/>
<bondArray>
<bond atomRefs2="a1 a2" order="1" />
<bond atomRefs2="a2 a3" order="1" />
<bond atomRefs2="a3 a4" order="2" />
<bond atomRefs2="a3 a5" order="1" />
<bond atomRefs2="a6 a7" order="1" />
<bond atomRefs2="a7 a8" order="1" />
<bond atomRefs2="a6 a9" order="2" />
<bond atomRefs2="a6 a10" order="1" />
<bond atomRefs2="a8 a11" order="2" />
<bond atomRefs2="a8 a12" order="1" />
<bond atomRefs2="a13 a14" order="1" />
<bond atomRefs2="a14 a15" order="1" />
<bond atomRefs2="a15 a16" order="1" />
<bond atomRefs2="a7 a13" order="1" />
<bond atomRefs2="a15 a17" order="1" />
<bond atomRefs2="a7 a1" order="1" />
<bond atomRefs2="a2 a15" order="1" />
<bond atomRefs2="a18 a19" order="1" />
</bondArray>
<molecule id="sg1" role="SuperatomSgroup" title="OEt" leftName="EtO" molID="m2">
<atomArray
atomID="a20 a21 a22"
elementType="O C C"
attachmentPoint="1 0 0"
sgroupAttachmentPoint="1 0 0"
x2="112.77400612345848 111.44032700163044 110.1066478798024"
y2="-17.917668608880355 -18.687668608880355 -17.917668608880355"
/>
<bondArray>
<bond atomRefs2="a21 a20" order="1" />
<bond atomRefs2="a22 a21" order="1" />
</bondArray>
</molecule>
<molecule id="sg2" role="SuperatomSgroup" title="OEt" leftName="EtO" molID="m3">
<atomArray
atomID="a23 a24 a25"
elementType="O C C"
attachmentPoint="1 0 0"
sgroupAttachmentPoint="1 0 0"
x2="122.30275654307518 120.96907742124714 119.63539829941911"
y2="-17.628918675637557 -18.398918675637557 -17.628918675637557"
/>
<bondArray>
<bond atomRefs2="a24 a23" order="1" />
<bond atomRefs2="a25 a24" order="1" />
</bondArray>
</molecule>
<molecule id="sg3" role="SuperatomSgroup" title="OtBu"
leftName="tBuO" molID="m4">
<atomArray
atomID="a26 a27 a28 a29 a30"
elementType="O C C C C"
attachmentPoint="1 0 0 0 0"
sgroupAttachmentPoint="1 0 0 0 0"
x2="121.3712530517578 122.91125305175781 122.91125305175781 124.45125305175782 122.91125305175781"
y2="-28.971250534057617 -28.971250534057617 -27.431250534057618 -28.971250534057617 -30.511250534057616"
/>
<bondArray>
<bond atomRefs2="a27 a26" order="1" />
<bond atomRefs2="a30 a27" order="1" />
<bond atomRefs2="a27 a28" order="1" />
<bond atomRefs2="a27 a29" order="1" />
</bondArray>
</molecule>
</molecule>
</MChemicalStruct>
</MDocument>
</cml>

The code:


                final MechFlow flow = flows.get(flowNum);
// get source atom or one atom of source bond
final MolAtom srcAtom = flow.getSrcAtoms()[0];
debugPrint(SELF + "flow ", flowNum + 1, " source atom is ",
srcAtom);
// get molecule containing source atom
final Molecule srcMol = (Molecule) srcAtom.getParent();
final int srcMolChg =
ChemUtils.stripMetals(srcMol).getTotalCharge();
if (srcMolChg == 0) {
debugPrint(SELF + "flow ", flowNum + 1,
" has neutral source ", srcMol, "; no violation.");
continue;
}
debugPrint(SELF + "flow ", flowNum + 1,
" has charged source ", srcMol, "; look at sinks.");
// get relevant atom or atoms of sink, convert to array
final MolAtom[] snkAtoms = flow.getSinkAtoms();
debugPrint(SELF + "flow ", flowNum + 1, " sink atom(s): ",
snkAtoms);
// get sink molecule of each relevant sink atom
boolean allSnksInSrc = true; // for debugging
for (MolAtom snkAtom : snkAtoms) {
final Molecule snkMol = (Molecule) snkAtom.getParent();
debugPrint(SELF + "molecule containing ", snkAtom,
" is ", snkMol);

Part of the log output:


MechRuleFunctions.noSameChargeReacting: flow 2 source atom is H
MechRuleFunctions.noSameChargeReacting: flow 2 has charged source [H]OC(C)(C)C.CCOC(=O)C1(CCC(C)([O-])C(C1)C(C)=O)C(=O)OCC; look at sinks.
MechRuleFunctions.noSameChargeReacting: flow 2 sink atom(s): [OtBu]
MechRuleFunctions.noSameChargeReacting: molecule containing OtBu is null

Note that the MolAtom.getParent() returns null when the atom is a shortcut group.  This is a bug; please fix.

User 870ab5b546

06-08-2012 19:39:35

After a little more research, I think I've discovered the problem.  I get the source and sink of an electron-flow arrow, storing them as Objects.  I then ungroup the shortcut groups in the parent molecules.  When I go back and examine the source and sink atoms of the electron-flow arrow, the sink is a shortcut group, but this shortcut group no longer exists in the parent molecule, so sinkAtom.getParent() returns null.  


The solution is that when a molecule's shortcut groups are ungrouped, any electron-flow arrows originating from or pointing to a shortcut group should now originate from or point to the atom that was the (first) attachment point for that shortcut group.  

ChemAxon 25dcd765a3

13-08-2012 12:05:47

Dear Bob,


I have tried to reproduce the bug, but without success yet.


Could you please modify the attached source code to reproduce the bug.

User 870ab5b546

13-08-2012 15:34:07

Try this code.  You need to ungroup the shortcut groups in the parent molecule after you acquire the MEFlow's sources and sinks, but before you get the sink atoms' parent molecules.  The problem is that if you have already stored the sink when you ungroup the shortcut groups in the parent molecule, the sink atom is now inconsistent with the parent molecule.  If a shortcut group is removed from a molecule, then anything pointing to that shortcut group needs to now point to the first attachment point of the original shortcut group.   

ChemAxon 25dcd765a3

13-08-2012 16:33:56

Thank you for the code.


I got the following result


after ungrouping, molecule containing MolAtom@79f6f296[H] is Molecule@2fdb7df8[27a,26b]
after ungrouping, molecule containing MolAtom@6627e353[O] is Molecule@2fdb7df8[27a,26b]



I think this is expected.


What is your result?

User 870ab5b546

13-08-2012 21:01:45

I figured out what is causing the inconsistency.  We have previously used setGUIContracted(true) on the molecule.  When we then use ungroupSgroups(), somehow the MEFlow doesn't get the message.  Try the attached program.


So I need to know how to reverse the effect of setGUIContracted(true).  Setting setGUIContracted(false) before ungroupSgroups() doesn't seem to help: the sink of the electron-flow arrow is still reported as OtBu.  


        for (Molecule mol : mols) {
// remove the shortcut groups now; they are nothing but trouble
mol.setGUIContracted(false);
mol.ungroupSgroups();
} // for each molecule
for (MechStage stage : stages) {
for (MechFlow flow : stage.getFlows()) {
debugPrint(SELF + "stage with temp index ",
stage.getBoxIndex() + 1, " has flow with "
+ "source atoms ", flow.getSrcAtoms(),
" and sink atoms ", flow.getSinkAtoms());
} // for each flow
} // for each stage

MechData.extractFlows: stage with temp index 3 has flow with source atoms [O[-1]] and sink atoms [O[-1].H]
MechData.extractFlows: stage with temp index 3 has flow with source atoms [H.O] and sink atoms [OtBu]

ChemAxon 25dcd765a3

14-08-2012 13:03:57

Dear Bob,


I have examined the attached Test2.java.


The problem is the following: you store the atom objects in flowAtoms list (one element in the list will be the superatom of a contracted sgroup), then you ungroup the sgroups of the molecule removing the superatom (and adding some more atoms). So your molecule will not contain the superatom any more but your list will contain it. That is why you get null.


So the flowAtom list should be in correspondance with the molecule.You should not modify the molecule (remove atoms) after your flowAtoms list is ready.


I hope this helps.


Andras

User 870ab5b546

14-08-2012 13:20:23

Yes, I understand why it is happening, but I need it not to happen.  As I said, when the shortcut groups in a molecule are being removed, any electron-flow arrows that are originating at or pointing to a shortcut group should be changed to originate at or point to the attachment point of the shortcut group.  It makes no sense not to do so.


Let me ask another way.  We need to use setGUIContracted(true) to investigate the physical locations of the shortcut groups in the figure.  This procedure has the unfortunate side effect of causing the electron-flow arrow to point at the shortcut group instead of its attachment point.  Is there a way to reverse the effect of setGUIContracted(true) so that an electron-flow arrow that originates at or points to a shortcut group will now originate at or point to the attachment point of the shortcut group?


-- Bob

ChemAxon 25dcd765a3

14-08-2012 14:00:01

 


As I said, when the shortcut groups in a molecule
are being removed, any electron-flow arrows that are originating at or
pointing to a shortcut group should be changed to originate at or point
to the attachment point of the shortcut group.  It makes no sense not to
do so.


I agree and as far as I see it works like this. Please attach a test file if you get different result. In Test2.java you store the objects in a seperate list (flowAtoms) which cannot be controlled by the molecule.


We need to use setGUIContracted(true) to 
investigate the physical locations of the shortcut groups in the figure.
 This procedure has the unfortunate side effect of causing
the electron-flow arrow to point at the shortcut group instead of its
attachment point.  Is there a way to reverse the effect of
setGUIContracted(true) so that an electron-flow arrow that originates at
or points to a shortcut group will now originate at or point to the
attachment point of the shortcut group?


If you need the location of the shortcut groups you need to store the location (snkAtom.getLocation()) and not the atom itself. The setGUIContracted(true) is intentionally changes the attachment point to shortcut group.

User 870ab5b546

14-08-2012 16:44:55










volfi wrote:

As I said, when the shortcut groups in a molecule
are being removed, any electron-flow arrows that are originating at or
pointing to a shortcut group should be changed to originate at or point
to the attachment point of the shortcut group.  It makes no sense not to
do so.

I agree and as far as I see it works like this. Please attach a test file if you get different result. In Test2.java you store the objects in a seperate list (flowAtoms) which cannot be controlled by the molecule.



Yes, you are right.  Unfortunately, I need to store the source and sink Objects of the MEFlow for other reasons.











volfi wrote:

We need to use setGUIContracted(true) to  investigate the physical locations of the shortcut groups in the figure.  This procedure has the unfortunate side effect of causing  the electron-flow arrow to point at the shortcut group instead of its  attachment point.  Is there a way to reverse the effect of  setGUIContracted(true) so that an electron-flow arrow that originates at or points to a shortcut group will now originate at or point to the  attachment point of the shortcut group?

If you need the location of the shortcut groups you need to store the location (snkAtom.getLocation()) and not the atom itself.





Yes, but the problem is that before I can get an accurate location of the shortcut groups, I need to run setGUIContracted(true).  (See this discussion.)  









The setGUIContracted(true) intentionally changes the attachment point to shortcut group.



Right.  Can I reverse the action of setGUIContracted() so that the flow arrows point back to the attachment point?  


ChemAxon 25dcd765a3

15-08-2012 07:05:40

Can I reverse the action of setGUIContracted() so that the flow arrows point back to the attachment point? 

Yes mol.setGUIContracted(false); does the job in the molecule, but it cannot change the objects in your flowAtoms list if you call it after the list creation. So the flowAtoms list will contain [OtBu] (due to setGUIContracted(true)) and the molecule eflow will point to the [O] atom (due to setGUIContracted(false)). Moreover the molecule will not contain the [OtBu] atom any more.


I still don't understand the problem, sorry.

User 870ab5b546

15-08-2012 13:45:36

Thanks, this discussion has been helpful.  I figured out how to avoid the inconsistency.