I have downloaded Marvin 5.3.2, and I am now experiencing a new problem regarding electron-flow arrows.
After importing a document with flow arrows and molecules, I convert the Molecule to its fragments, which should associate the MolAtoms with the fragments, and store the Molecule fragments in appropriate MechStages. I then extract the MEFlow arrows, use the MolAtoms of the sources and sinks of the MEFlows to find their associated Molecules, and put them in the MechStages that their associated Molecules are in. Then, when I am ready to calculate products of flow arrows in each stage, I fuse all the stage's Molecules together, create a new MDocument from it, add the MEFlows to it, and export it to MRV format.
In cases where an electron-flow arrow begins at an atom, I am now getting a MolExportException:
MechStage.setStageMDoc: creating MDocument with molecule:
[OH-].[H][N+](C)(C)C
MechStage.setStageMDoc: adding flow:
Source Bond: N[+1]1 to H4, order 1
Sink Atom: N[+1]1
MechStage.setStageMDoc: adding flow:
Source Atom: O[-1]5
Sink Incip Bond: O[-1]-1 to H-1
MechStage.setStageMDoc: can't export stage MDocument:
document does not contain MolAtom@1fe8884[O] (0) in MAtomSetPoint
chemaxon.marvin.io.MolExportException: document does not contain MolAtom@1fe8884[O] (0) in MAtomSetPoint
at chemaxon.marvin.io.formats.cml.MrvExport.findMolAtomIds(Unknown Source)
at chemaxon.marvin.io.formats.cml.MrvExport.appendPoint(Unknown Source)
at chemaxon.marvin.io.formats.cml.MrvExport.appendMObject(Unknown Source)
at chemaxon.marvin.io.formats.cml.MrvExport.convert0(Unknown Source)
at chemaxon.marvin.io.formats.cml.MrvExport.convert(Unknown Source)
at chemaxon.struc.Molecule.exportToObject(Unknown Source)
at chemaxon.struc.Molecule.exportToObject(Unknown Source)
at chemaxon.struc.MDocument.exportToObject(Unknown Source)
at chemaxon.struc.MDocument.exportToFormat(Unknown Source)
at com.prenhall.epoch.mechanisms.MechStage.setStageMDoc(MechStage.java:358)
Note that the sink incipient bond of the second arrow contains O and H atoms whose coordinates are -1. This is pretty strange, because the source O atom, index 5, is the SAME ATOM as the sink O atom, index -1. Why would the same atom have different indices with respect to the same parent???
Clearly something is wrong in the way that the incipient bond atoms are stored or retrieved.
Here is the code for printing the flow arrows:
/** Prints details about the electron-flow arrow. */
void print() {
final MolAtom[] srcAtoms = getSrcAtoms();
final Molecule parent = (Molecule) srcAtoms[0].getParent();
print(parent);
} // print()
/** Prints details about the electron-flow arrow.
* @param parent molecule containing the atoms of the electron-flow
* arrows
*/
void print(Molecule parent) {
final MolAtom[] srcAtoms = getSrcAtoms();
debugPrint(" Parent molecule is ", parent);
if (srcIsAtom()) {
Utils.alwaysPrint(" Source Atom: ", srcAtoms[0],
parent.indexOf(srcAtoms[0]));
} else if (srcIsBond()) {
Utils.alwaysPrint(" Source Bond: ", srcAtoms[0],
parent.indexOf(srcAtoms[0]), " to ",
srcAtoms[1], parent.indexOf(srcAtoms[1]),
", order ", getSrcBond().getType());
} else Utils.alwaysPrint(" Source: INVALID! Neither atom nor bond");
final MolAtom[] sinkAtoms = getSinkAtoms();
if (sinkIsAtom()) {
Utils.alwaysPrint(" Sink Atom: ", sinkAtoms[0],
parent.indexOf(sinkAtoms[0]));
} else if (sinkIsBond()) {
Utils.alwaysPrint(" Sink Bond: ", sinkAtoms[0],
parent.indexOf(sinkAtoms[0]), " to ",
sinkAtoms[1], parent.indexOf(sinkAtoms[1]),
", order ", getSinkBond().getType());
} else if (sinkIsIncipBond()) {
Utils.alwaysPrint(" Sink Incip Bond: ", sinkAtoms[0],
parent.indexOf(sinkAtoms[0]), " to ",
sinkAtoms[1], parent.indexOf(sinkAtoms[1]));
} else Utils.alwaysPrint(" Sink: INVALID! Neither atom "
+ "nor bond nor incipient bond");
} // print(Molecule)
/** Gets the atom or atoms at the arrow source.
* @return the atom or atoms at the arrow source
*/
MolAtom[] getSrcAtoms() {
return getAtoms(getSource());
} // getSrcAtoms()
/** Gets the atom or atoms at the arrow sink.
* @return the atom or atoms at the arrow sink
*/
MolAtom[] getSinkAtoms() {
return (is2electronAtom2Atom()
? new MolAtom[] {getSrcAtom(), getSinkAtom()}
: getAtoms(getSink()));
} // getSinkAtoms()
/** Gets the atom or atoms at the terminus of an arrow.
* @param terminus the arrow terminus
* @return the atom or atoms at the terminus of an arrow
*/
private static MolAtom[] getAtoms(Object terminus) {
final String SELF = "MechFlow.getAtoms: ";
MolAtom[] atoms;
if (isAtom(terminus)) {
debugPrint(SELF + "arrow terminus is atom.");
atoms = new MolAtom[] {getAtom(terminus)};
} else if (isBond(terminus)) {
debugPrint(SELF + "arrow terminus is bond.");
final MolBond bond = (MolBond) terminus;
atoms = new MolAtom[] {bond.getAtom1(), bond.getAtom2()};
} else if (isIncipBond(terminus)) {
debugPrint(SELF + "arrow terminus is incipient bond.");
atoms = (MolAtom[]) terminus;
} else {
try {
debugPrint(SELF + "terminus is of unknown type ",
terminus.getClass().getName(),
", getting empty array.");
} catch (NullPointerException e) {
debugPrint(SELF + "terminus is null, getting empty array.");
}
atoms = new MolAtom[0];
}
return atoms;
} // getAtoms(Object)
/** Gets the origin of the electron-flow arrow (MolAtom or MolBond).
* @return origin of the electron-flow arrow
*/
Object getSource() { return meFlow.getMolObject(MEFlow.E_SOURCE); }
/** Gets the destination of the electron-flow arrow (MolAtom, MolBond, or
* MolAtom[2] for incipient bond).
* @return destination of the electron-flow arrow
*/
Object getSink() { return meFlow.getMolObject(MEFlow.E_SINK); }
I'm also attaching a picture of the Marvin picture that's generating the error.
Please advise.
P.S. Note how in the Marvin drawing, the electron-flow arrow overlaps with the incipient H attached to O. It shouldn't.