Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #411 from cdk/patch/sgrouphydrogens
Oh, you gave a lot more than I was hoping for, thanks :)
  • Loading branch information
egonw committed Jan 14, 2018
2 parents a32c59f + 435c636 commit 7d2c854
Show file tree
Hide file tree
Showing 13 changed files with 483 additions and 25 deletions.
18 changes: 17 additions & 1 deletion base/core/src/main/java/org/openscience/cdk/sgroup/Sgroup.java
Expand Up @@ -114,14 +114,22 @@ public final Set<Sgroup> getParents() {
}

/**
* Add a bond to this Sgroup.
* Add an atom to this Sgroup.
*
* @param atom the atom
*/
public final void addAtom(IAtom atom) {
this.atoms.add(atom);
}

/**
* Remove an atom from this Sgroup.
* @param atom the atom
*/
public final void removeAtom(IAtom atom) {
this.atoms.remove(atom);
}

/**
* Add a bond to this Sgroup. The bond list
*
Expand All @@ -131,6 +139,14 @@ public final void addBond(IBond bond) {
this.bonds.add(bond);
}

/**
* Remove a bond from this Sgroup.
* @param bond the bond
*/
public final void removeBond(IBond bond) {
this.bonds.remove(bond);
}

/**
* Add a parent Sgroup.
*
Expand Down
Expand Up @@ -45,6 +45,15 @@ public SgroupBracket(double x1, double y1, double x2, double y2) {
this.p2 = new Point2d(x2, y2);
}

/**
* Copy constructor.
* @param org original sgroup bracket
*/
public SgroupBracket(SgroupBracket org) {
this(org.p1.x, org.p1.y,
org.p2.x, org.p2.y);
}

/**
* First point of the bracket (x1,y1).
*
Expand Down
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2018 John Mayfield
*
* Contact: cdk-devel@lists.sourceforge.net
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version. All we ask is that proper credit is given
* for our work, which includes - but is not limited to - adding the above
* copyright notice to the beginning of your source code files, and to any
* copyright notice that you may distribute with programs based on this work.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 U
*/
package org.openscience.cdk.tools.manipulator;

import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObject;
import org.openscience.cdk.sgroup.Sgroup;
import org.openscience.cdk.sgroup.SgroupBracket;
import org.openscience.cdk.sgroup.SgroupKey;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Utilities related to Ctab Sgroups.
*/
public final class SgroupManipulator {

private SgroupManipulator() {
}

@SuppressWarnings("unchecked")
private static <T extends IChemObject> T get(Map<? extends IChemObject,
? extends IChemObject> map,
T obj) {
if (map == null)
return obj;
T val = (T) map.get(obj);
if (val == null)
return obj;
return val;
}

/**
* Copy a collection of Sgroups, replacing any {@link IAtom}/{@link IBond}
* references with those present in the provided 'replace' map. If an empty
* replace map is provided (null or empty) the sgroups are simply
* duplicated. If an item is not present in the replacement map the original
* item is preserved.
* <br>
* <pre>{@code
* Map<IChemObject,IChemObject> replace = new HashMap<>();
* replace.put(orgAtom, newAtom);
* replace.put(orgBond, newBond);
* newSgroups = copy(orgSgroups, replace);
* }</pre>
*
* @param sgroups collection of sgroups, can be null
* @param replace the replacement map, can be null
* @return list of copied sgroups, null if sgroups input was null
*/
public static List<Sgroup> copy(Collection<Sgroup> sgroups,
Map<? extends IChemObject,
? extends IChemObject> replace) {
if (sgroups == null) return null;
Map<Sgroup, Sgroup> sgroupMap = new HashMap<>();
for (Sgroup sgroup : sgroups)
sgroupMap.put(sgroup, new Sgroup());
for (Map.Entry<Sgroup, Sgroup> e : sgroupMap.entrySet()) {
Sgroup orgSgroup = e.getKey();
Sgroup cpySgroup = e.getValue();
cpySgroup.setType(orgSgroup.getType());
for (IAtom atom : orgSgroup.getAtoms())
cpySgroup.addAtom(get(replace, atom));
for (IBond bond : orgSgroup.getBonds())
cpySgroup.addBond(get(replace, bond));
for (Sgroup parent : orgSgroup.getParents())
cpySgroup.addParent(sgroupMap.get(parent));
for (SgroupKey key : SgroupKey.values()) {
switch (key) {
case CtabParentAtomList: {
Collection<IAtom> orgVal = orgSgroup.getValue(key);
if (orgVal != null) {
List<IAtom> cpyVal = new ArrayList<>();
for (IAtom atom : orgVal)
cpyVal.add(get(replace, atom));
cpySgroup.putValue(key, cpyVal);
}
}
break;
case CtabBracket: {
Collection<IAtom> orgVal = orgSgroup.getValue(key);
if (orgVal != null) {
cpySgroup.putValue(key,
new SgroupBracket((SgroupBracket) orgVal));
}
}
break;
default:
// primitive values, String, Integer are immutable
Object val = orgSgroup.getValue(key);
if (val != null)
cpySgroup.putValue(key, val);
break;
}
}
}
return new ArrayList<>(sgroupMap.values());
}
}
14 changes: 14 additions & 0 deletions base/data/src/main/java/org/openscience/cdk/AtomContainer.java
Expand Up @@ -21,6 +21,7 @@
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
Expand All @@ -33,13 +34,16 @@
import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IAtomContainer;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObject;
import org.openscience.cdk.interfaces.IChemObjectChangeEvent;
import org.openscience.cdk.interfaces.IChemObjectListener;
import org.openscience.cdk.interfaces.IElectronContainer;
import org.openscience.cdk.interfaces.ILonePair;
import org.openscience.cdk.interfaces.ISingleElectron;
import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.interfaces.IBond.Order;
import org.openscience.cdk.sgroup.Sgroup;
import org.openscience.cdk.tools.manipulator.SgroupManipulator;

/**
* Base class for all chemical objects that maintain a list of Atoms and
Expand Down Expand Up @@ -1394,6 +1398,16 @@ public IAtomContainer clone() throws CloneNotSupportedException {
clone.addStereoElement(element.map(atomMap, bondMap));
}

// update sgroups
Collection<Sgroup> sgroups = getProperty(CDKConstants.CTAB_SGROUPS);
if (sgroups != null) {
Map<IChemObject,IChemObject> replace = new HashMap<>();
replace.putAll(atomMap);
replace.putAll(bondMap);
clone.setProperty(CDKConstants.CTAB_SGROUPS,
SgroupManipulator.copy(sgroups, replace));
}

return clone;

}
Expand Down
14 changes: 14 additions & 0 deletions base/data/src/main/java/org/openscience/cdk/AtomContainer2.java
Expand Up @@ -28,6 +28,7 @@
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IBond.Order;
import org.openscience.cdk.interfaces.IBond.Stereo;
import org.openscience.cdk.interfaces.IChemObject;
import org.openscience.cdk.interfaces.IChemObjectChangeEvent;
import org.openscience.cdk.interfaces.IElectronContainer;
import org.openscience.cdk.interfaces.ILonePair;
Expand All @@ -37,12 +38,15 @@
import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.isomorphism.matchers.IQueryAtom;
import org.openscience.cdk.isomorphism.matchers.IQueryBond;
import org.openscience.cdk.sgroup.Sgroup;
import org.openscience.cdk.stereo.DoubleBondStereochemistry;
import org.openscience.cdk.stereo.ExtendedTetrahedral;
import org.openscience.cdk.stereo.TetrahedralChirality;
import org.openscience.cdk.tools.manipulator.SgroupManipulator;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
Expand Down Expand Up @@ -1476,6 +1480,16 @@ public IAtomContainer clone() throws CloneNotSupportedException {
clone.addStereoElement(element.map(atomMap, bondMap));
}

// update sgroups
Collection<Sgroup> sgroups = getProperty(CDKConstants.CTAB_SGROUPS);
if (sgroups != null) {
Map<IChemObject,IChemObject> replace = new HashMap<>();
replace.putAll(atomMap);
replace.putAll(bondMap);
clone.setProperty(CDKConstants.CTAB_SGROUPS,
SgroupManipulator.copy(sgroups, replace));
}

return clone;
}

Expand Down
13 changes: 13 additions & 0 deletions base/data/src/main/java/org/openscience/cdk/Polymer.java
Expand Up @@ -24,11 +24,14 @@

import org.openscience.cdk.interfaces.IAtom;
import org.openscience.cdk.interfaces.IBond;
import org.openscience.cdk.interfaces.IChemObject;
import org.openscience.cdk.interfaces.ILonePair;
import org.openscience.cdk.interfaces.IMonomer;
import org.openscience.cdk.interfaces.IPolymer;
import org.openscience.cdk.interfaces.ISingleElectron;
import org.openscience.cdk.interfaces.IStereoElement;
import org.openscience.cdk.sgroup.Sgroup;
import org.openscience.cdk.tools.manipulator.SgroupManipulator;

import java.util.Collection;
import java.util.HashMap;
Expand Down Expand Up @@ -223,6 +226,16 @@ public IPolymer clone() throws CloneNotSupportedException {
clone.addStereoElement(element.map(atomMap, bondMap));
}

// update sgroups
Collection<Sgroup> sgroups = getProperty(CDKConstants.CTAB_SGROUPS);
if (sgroups != null) {
Map<IChemObject,IChemObject> replace = new HashMap<>();
replace.putAll(atomMap);
replace.putAll(bondMap);
clone.setProperty(CDKConstants.CTAB_SGROUPS,
SgroupManipulator.copy(sgroups, replace));
}

return clone;
}

Expand Down

0 comments on commit 7d2c854

Please sign in to comment.