Skip to content

Commit

Permalink
Merge pull request #221 from cdk/patch/cxsmilesgen
Browse files Browse the repository at this point in the history
Patch/cxsmilesgen
  • Loading branch information
egonw committed Aug 17, 2016
2 parents b5c9719 + a607a73 commit cf622a4
Show file tree
Hide file tree
Showing 12 changed files with 1,355 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ public static int getAtomCount(IReaction reaction) {
for (int i = 0; i < reactants.getAtomContainerCount(); i++) {
count += reactants.getAtomContainer(i).getAtomCount();
}
IAtomContainerSet agents = reaction.getAgents();
for (int i = 0; i < agents.getAtomContainerCount(); i++) {
count += agents.getAtomContainer(i).getAtomCount();
}
IAtomContainerSet products = reaction.getProducts();
for (int i = 0; i < products.getAtomContainerCount(); i++) {
count += products.getAtomContainer(i).getAtomCount();
Expand All @@ -73,6 +77,10 @@ public static int getBondCount(IReaction reaction) {
for (int i = 0; i < reactants.getAtomContainerCount(); i++) {
count += reactants.getAtomContainer(i).getBondCount();
}
IAtomContainerSet agents = reaction.getAgents();
for (int i = 0; i < agents.getAtomContainerCount(); i++) {
count += agents.getAtomContainer(i).getBondCount();
}
IAtomContainerSet products = reaction.getProducts();
for (int i = 0; i < products.getAtomContainerCount(); i++) {
count += products.getAtomContainer(i).getBondCount();
Expand All @@ -88,6 +96,13 @@ public static void removeAtomAndConnectedElectronContainers(IReaction reaction,
mol.removeAtomAndConnectedElectronContainers(atom);
}
}
IAtomContainerSet agents = reaction.getReactants();
for (int i = 0; i < agents.getAtomContainerCount(); i++) {
IAtomContainer mol = agents.getAtomContainer(i);
if (mol.contains(atom)) {
mol.removeAtomAndConnectedElectronContainers(atom);
}
}
IAtomContainerSet products = reaction.getProducts();
for (int i = 0; i < products.getAtomContainerCount(); i++) {
IAtomContainer mol = products.getAtomContainer(i);
Expand All @@ -105,6 +120,13 @@ public static void removeElectronContainer(IReaction reaction, IElectronContaine
mol.removeElectronContainer(electrons);
}
}
IAtomContainerSet agents = reaction.getReactants();
for (int i = 0; i < agents.getAtomContainerCount(); i++) {
IAtomContainer mol = agents.getAtomContainer(i);
if (mol.contains(electrons)) {
mol.removeElectronContainer(electrons);
}
}
IAtomContainerSet products = reaction.getProducts();
for (int i = 0; i < products.getAtomContainerCount(); i++) {
IAtomContainer mol = products.getAtomContainer(i);
Expand All @@ -124,6 +146,7 @@ public static IAtomContainerSet getAllMolecules(IReaction reaction) {
IAtomContainerSet moleculeSet = reaction.getBuilder().newInstance(IAtomContainerSet.class);

moleculeSet.add(getAllReactants(reaction));
moleculeSet.add(getAllAgents(reaction));
moleculeSet.add(getAllProducts(reaction));

return moleculeSet;
Expand Down Expand Up @@ -159,6 +182,15 @@ public static IAtomContainerSet getAllReactants(IReaction reaction) {
return moleculeSet;
}

public static IAtomContainerSet getAllAgents(IReaction reaction) {
IAtomContainerSet moleculeSet = reaction.getBuilder().newInstance(IAtomContainerSet.class);
IAtomContainerSet agents = reaction.getAgents();
for (int i = 0; i < agents.getAtomContainerCount(); i++) {
moleculeSet.addAtomContainer(agents.getAtomContainer(i));
}
return moleculeSet;
}

/**
* Returns a new Reaction object which is the reverse of the given
* Reaction.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

import com.google.common.collect.Maps;

import org.openscience.cdk.CDK;
import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.config.Isotopes;
import org.openscience.cdk.config.IsotopeFactory;
Expand Down Expand Up @@ -91,39 +90,33 @@ final class CDKToBeam {
* Whether to convert the molecule with isotope and stereo information -
* Isomeric SMILES.
*/
private final boolean isomeric;

/** Use aromatic flags. */
private final boolean aromatic;

/** Set atom class data. */
private final boolean atomClasses;
private final int flavour;

/** Create a isomeric and aromatic converter. */
CDKToBeam() {
this(true, true);
this(SmiFlavour.AtomicMass | SmiFlavour.AtomAtomMap | SmiFlavour.UseAromaticSymbols);
}

/** Create a aromatic converter specifying whether to be isomeric or not. */
CDKToBeam(boolean isomeric) {
this(isomeric, true);
CDKToBeam(int flavour) {
this.flavour = flavour;
}

/**
* Create a convert which will optionally convert isomeric and aromatic
* information from CDK data model.
*
* @param isomeric convert isomeric information
* @param aromatic convert aromatic information
*/
CDKToBeam(boolean isomeric, boolean aromatic) {
this(isomeric, aromatic, true);
Graph toBeamGraph(IAtomContainer ac) throws CDKException {
return toBeamGraph(ac, flavour);
}

CDKToBeam(boolean isomeric, boolean aromatic, boolean atomClasses) {
this.isomeric = isomeric;
this.aromatic = aromatic;
this.atomClasses = atomClasses;
Atom toBeamAtom(IAtom atom) throws CDKException {
return toBeamAtom(atom, flavour);
}

Edge toBeamEdge(IBond b, Map<IAtom, Integer> indices) throws CDKException {

checkArgument(b.getAtomCount() == 2, "Invalid number of atoms on bond");

int u = indices.get(b.getAtom(0));
int v = indices.get(b.getAtom(1));

return toBeamEdgeLabel(b, this.flavour).edge(u, v);
}

/**
Expand All @@ -134,7 +127,7 @@ final class CDKToBeam {
* @param ac an atom container instance
* @return the Beam ChemicalGraph for additional manipulation
*/
Graph toBeamGraph(IAtomContainer ac) throws CDKException {
static Graph toBeamGraph(IAtomContainer ac, int flavour) throws CDKException {

int order = ac.getAtomCount();

Expand All @@ -143,21 +136,24 @@ Graph toBeamGraph(IAtomContainer ac) throws CDKException {

for (IAtom a : ac.atoms()) {
indices.put(a, indices.size());
gb.add(toBeamAtom(a));
gb.add(toBeamAtom(a, flavour));
}

for (IBond b : ac.bonds()) {
gb.add(toBeamEdge(b, indices));
gb.add(toBeamEdge(b, flavour, indices));
}

// configure stereo-chemistry by encoding the stereo-elements
if (isomeric) {
if (SmiFlavour.isSet(flavour, SmiFlavour.Stereo)) {
for (IStereoElement se : ac.stereoElements()) {
if (se instanceof ITetrahedralChirality) {
if (SmiFlavour.isSet(flavour, SmiFlavour.StereoTetrahedral) &&
se instanceof ITetrahedralChirality) {
addTetrahedralConfiguration((ITetrahedralChirality) se, gb, indices);
} else if (se instanceof IDoubleBondStereochemistry) {
addGeometricConfiguration((IDoubleBondStereochemistry) se, gb, indices);
} else if (se instanceof ExtendedTetrahedral) {
} else if (SmiFlavour.isSet(flavour, SmiFlavour.StereoCisTrans) &&
se instanceof IDoubleBondStereochemistry) {
addGeometricConfiguration((IDoubleBondStereochemistry) se, flavour, gb, indices);
} else if (SmiFlavour.isSet(flavour, SmiFlavour.StereoExTetrahedral) &&
se instanceof ExtendedTetrahedral) {
addExtendedTetrahedralConfiguration((ExtendedTetrahedral) se, gb, indices);
}
}
Expand All @@ -177,9 +173,9 @@ Graph toBeamGraph(IAtomContainer ac) throws CDKException {
* @throws NullPointerException the atom had an undefined symbol or implicit
* hydrogen count
*/
Atom toBeamAtom(final IAtom a) {
static Atom toBeamAtom(final IAtom a, final int flavour) {

final boolean aromatic = this.aromatic && a.getFlag(CDKConstants.ISAROMATIC);
final boolean aromatic = SmiFlavour.isSet(flavour, SmiFlavour.UseAromaticSymbols) && a.getFlag(CDKConstants.ISAROMATIC);
final Integer charge = a.getFormalCharge();
final String symbol = checkNotNull(a.getSymbol(), "An atom had an undefined symbol");

Expand All @@ -199,7 +195,7 @@ Atom toBeamAtom(final IAtom a) {
if (charge != null) ab.charge(charge);

// use the mass number to specify isotope?
if (isomeric) {
if (SmiFlavour.isSet(flavour, SmiFlavour.AtomicMass)) {
Integer massNumber = a.getMassNumber();
if (massNumber != null) {
// XXX: likely causing some overhead but okay for now
Expand All @@ -214,7 +210,7 @@ Atom toBeamAtom(final IAtom a) {
}

Integer atomClass = a.getProperty(ATOM_ATOM_MAPPING);
if (atomClasses && atomClass != null) {
if (SmiFlavour.isSet(flavour, SmiFlavour.AtomAtomMap) && atomClass != null) {
ab.atomClass(atomClass);
}

Expand All @@ -231,14 +227,14 @@ Atom toBeamAtom(final IAtom a) {
* unsupported order
* @throws NullPointerException the bond order was undefined
*/
Edge toBeamEdge(IBond b, Map<IAtom, Integer> indices) throws CDKException {
static Edge toBeamEdge(IBond b, int flavour, Map<IAtom, Integer> indices) throws CDKException {

checkArgument(b.getAtomCount() == 2, "Invalid number of atoms on bond");

int u = indices.get(b.getAtom(0));
int v = indices.get(b.getAtom(1));

return toBeamEdgeLabel(b).edge(u, v);
return toBeamEdgeLabel(b, flavour).edge(u, v);
}

/**
Expand All @@ -250,9 +246,9 @@ Edge toBeamEdge(IBond b, Map<IAtom, Integer> indices) throws CDKException {
* not-aromatic
* @throws IllegalArgumentException the bond order could not be converted
*/
private Bond toBeamEdgeLabel(IBond b) throws CDKException {
private static Bond toBeamEdgeLabel(IBond b, int flavour) throws CDKException {

if (this.aromatic && b.getFlag(CDKConstants.ISAROMATIC)) return Bond.AROMATIC;
if (SmiFlavour.isSet(flavour, SmiFlavour.UseAromaticSymbols) && b.getFlag(CDKConstants.ISAROMATIC)) return Bond.AROMATIC;

if (b.getOrder() == null) throw new CDKException("A bond had undefined order, possible query bond?");

Expand All @@ -268,7 +264,7 @@ private Bond toBeamEdgeLabel(IBond b) throws CDKException {
case QUADRUPLE:
return Bond.QUADRUPLE;
default:
if (!this.aromatic && b.getFlag(CDKConstants.ISAROMATIC))
if (!SmiFlavour.isSet(flavour, SmiFlavour.UseAromaticSymbols) && b.getFlag(CDKConstants.ISAROMATIC))
throw new CDKException("Cannot write Kekulé SMILES output due to aromatic bond with unset bond order - molecule should be Kekulized");
throw new CDKException("Unsupported bond order: " + order);
}
Expand All @@ -281,13 +277,13 @@ private Bond toBeamEdgeLabel(IBond b) throws CDKException {
* @param gb the current graph builder
* @param indices atom indices
*/
private void addGeometricConfiguration(IDoubleBondStereochemistry dbs, GraphBuilder gb, Map<IAtom, Integer> indices) {
private static void addGeometricConfiguration(IDoubleBondStereochemistry dbs, int flavour, GraphBuilder gb, Map<IAtom, Integer> indices) {

IBond db = dbs.getStereoBond();
IBond[] bs = dbs.getBonds();

// don't try to set a configuration on aromatic bonds
if (this.aromatic && db.getFlag(CDKConstants.ISAROMATIC)) return;
if (SmiFlavour.isSet(flavour, SmiFlavour.UseAromaticSymbols) && db.getFlag(CDKConstants.ISAROMATIC)) return;

int u = indices.get(db.getAtom(0));
int v = indices.get(db.getAtom(1));
Expand All @@ -310,7 +306,7 @@ private void addGeometricConfiguration(IDoubleBondStereochemistry dbs, GraphBuil
* @param gb the current graph builder
* @param indices atom indices
*/
private void addTetrahedralConfiguration(ITetrahedralChirality tc, GraphBuilder gb, Map<IAtom, Integer> indices) {
private static void addTetrahedralConfiguration(ITetrahedralChirality tc, GraphBuilder gb, Map<IAtom, Integer> indices) {

IAtom[] ligands = tc.getLigands();

Expand All @@ -329,7 +325,7 @@ private void addTetrahedralConfiguration(ITetrahedralChirality tc, GraphBuilder
* @param gb the current graph builder
* @param indices atom indices
*/
private void addExtendedTetrahedralConfiguration(ExtendedTetrahedral et, GraphBuilder gb,
private static void addExtendedTetrahedralConfiguration(ExtendedTetrahedral et, GraphBuilder gb,
Map<IAtom, Integer> indices) {

IAtom[] ligands = et.peripherals();
Expand Down
Loading

0 comments on commit cf622a4

Please sign in to comment.