Skip to content

Commit b678847

Browse files
committed
initial version of adding SGroups to partitioned containers
1 parent 03c7f3a commit b678847

File tree

3 files changed

+146
-15
lines changed

3 files changed

+146
-15
lines changed

base/standard/src/main/java/org/openscience/cdk/graph/ConnectivityChecker.java

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@
1919
*/
2020
package org.openscience.cdk.graph;
2121

22-
import java.util.HashMap;
23-
import java.util.Map;
22+
import java.util.*;
2423

24+
import org.openscience.cdk.CDKConstants;
2525
import org.openscience.cdk.interfaces.IAtom;
2626
import org.openscience.cdk.interfaces.IAtomContainer;
2727
import org.openscience.cdk.interfaces.IAtomContainerSet;
@@ -32,6 +32,8 @@
3232
import org.openscience.cdk.interfaces.ISingleElectron;
3333
import org.openscience.cdk.interfaces.IStereoElement;
3434
import org.openscience.cdk.interfaces.ITetrahedralChirality;
35+
import org.openscience.cdk.sgroup.Sgroup;
36+
import org.openscience.cdk.sgroup.SgroupKey;
3537
import org.openscience.cdk.stereo.ExtendedTetrahedral;
3638

3739
/**
@@ -93,23 +95,33 @@ public static IAtomContainerSet partitionIntoMolecules(IAtomContainer container,
9395
maxComponentIndex = component;
9496

9597
IAtomContainer[] containers = new IAtomContainer[maxComponentIndex + 1];
96-
Map<IAtom, IAtomContainer> componentsMap = new HashMap<IAtom, IAtomContainer>(2 * container.getAtomCount());
98+
Map<IAtom, IAtomContainer> componentsMap = new HashMap<>(2 * container.getAtomCount());
99+
Map<IAtom, IAtom> componentAtomMap = new HashMap<>(2 * container.getAtomCount());
100+
Map<IBond, IBond> componentBondMap = new HashMap<>(2 * container.getBondCount());
101+
97102

98103
for (int i = 1; i < containers.length; i++)
99104
containers[i] = container.getBuilder().newInstance(IAtomContainer.class);
100105

101106
IAtomContainerSet containerSet = container.getBuilder().newInstance(IAtomContainerSet.class);
102107

103108
for (int i = 0; i < container.getAtomCount(); i++) {
104-
componentsMap.put(container.getAtom(i), containers[components[i]]);
105-
containers[components[i]].addAtom(container.getAtom(i));
109+
IAtom origAtom = container.getAtom(i);
110+
IAtomContainer newContainer = containers[components[i]];
111+
componentsMap.put(origAtom, newContainer);
112+
newContainer.addAtom(origAtom);
113+
//the atom should always be added so this should be safe
114+
componentAtomMap.put(origAtom, newContainer.getAtom(newContainer.getAtomCount()-1));
106115
}
107116

108117
for (IBond bond : container.bonds()) {
109118
IAtomContainer begComp = componentsMap.get(bond.getBegin());
110119
IAtomContainer endComp = componentsMap.get(bond.getEnd());
111-
if (begComp == endComp)
120+
if (begComp == endComp) {
112121
begComp.addBond(bond);
122+
//bond should always be added so this should be safe
123+
componentBondMap.put(bond, begComp.getBond(begComp.getBondCount()-1));
124+
}
113125
}
114126

115127
for (ISingleElectron electron : container.singleElectrons())
@@ -130,10 +142,85 @@ public static IAtomContainerSet partitionIntoMolecules(IAtomContainer container,
130142
throw new IllegalStateException("New stereo element not using an atom/bond for focus?");
131143
}
132144
}
133-
145+
//add SGroups
146+
List<Sgroup> sgroups = container.getProperty(CDKConstants.CTAB_SGROUPS);
147+
148+
if(sgroups !=null){
149+
Map<Sgroup, Sgroup> old2NewSgroupMap = new HashMap<>();
150+
List<Sgroup>[] newSgroups = new List[containers.length];
151+
for(Sgroup sgroup : sgroups){
152+
Iterator<IAtom> iter =sgroup.getAtoms().iterator();
153+
if(!iter.hasNext()){
154+
continue;
155+
}
156+
int componentIndex = getComponentIndexFor(components, containers,iter.next());
157+
boolean allMatch=componentIndex>=0;
158+
while(allMatch && iter.hasNext()){
159+
//if component index for some atoms
160+
//don't match then the sgroup is split across components
161+
//so ignore it for now?
162+
allMatch = (componentIndex == getComponentIndexFor(components,containers, iter.next()));
163+
}
164+
if(allMatch && componentIndex >=0){
165+
Sgroup cpy = new Sgroup();
166+
List<Sgroup> newComponentSgroups = newSgroups[componentIndex];
167+
if(newComponentSgroups ==null){
168+
newComponentSgroups = newSgroups[componentIndex] = new ArrayList<>();
169+
}
170+
newComponentSgroups.add(cpy);
171+
old2NewSgroupMap.put(sgroup, cpy);
172+
for (IAtom atom : sgroup.getAtoms()) {
173+
cpy.addAtom(componentAtomMap.get(atom));
174+
175+
}
176+
for (IBond bond : sgroup.getBonds()) {
177+
IBond newBond = componentBondMap.get(bond);
178+
if(newBond!=null) {
179+
cpy.addBond(newBond);
180+
}
181+
}
182+
183+
for (SgroupKey key : sgroup.getAttributeKeys())
184+
cpy.putValue(key, sgroup.getValue(key));
185+
186+
}
187+
}
188+
//finally update parents
189+
for(Sgroup sgroup : sgroups){
190+
Sgroup newSgroup = old2NewSgroupMap.get(sgroup);
191+
if(newSgroup !=null){
192+
for (Sgroup parent : sgroup.getParents()){
193+
Sgroup newParent = old2NewSgroupMap.get(parent);
194+
if(newParent !=null){
195+
newSgroup.addParent(newParent);
196+
}
197+
}
198+
}
199+
}
200+
for(int i=1; i< containers.length; i++){
201+
List<Sgroup> sg = newSgroups[i];
202+
if(sg !=null){
203+
containers[i].setProperty(CDKConstants.CTAB_SGROUPS, sg);
204+
}
205+
}
206+
}
134207
for (int i = 1; i < containers.length; i++)
135208
containerSet.addAtomContainer(containers[i]);
136209

137210
return containerSet;
138211
}
212+
213+
private static int getComponentIndexFor(int[] components, IAtomContainer[] containers, IAtom atom) {
214+
int aIndex = atom.getIndex();
215+
if(aIndex >= 0) {
216+
return components[aIndex];
217+
}
218+
//if index isn't known check each container
219+
for (int i = 1; i < containers.length; i++){
220+
if(containers[i].contains(atom)){
221+
return i;
222+
}
223+
}
224+
return -1;
225+
}
139226
}

base/test-standard/src/test/java/org/openscience/cdk/graph/ConnectivityCheckerTest.java

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,20 @@
2121

2222
import java.io.InputStream;
2323
import java.util.List;
24+
import java.util.Set;
2425

2526
import org.junit.Assert;
2627
import org.junit.Test;
27-
import org.openscience.cdk.Atom;
28-
import org.openscience.cdk.AtomContainer;
29-
import org.openscience.cdk.CDKTestCase;
30-
import org.openscience.cdk.ChemFile;
31-
import org.openscience.cdk.ChemObject;
32-
import org.openscience.cdk.DefaultChemObjectBuilder;
33-
import org.openscience.cdk.LonePair;
34-
import org.openscience.cdk.SingleElectron;
28+
import org.openscience.cdk.*;
3529
import org.openscience.cdk.exception.InvalidSmilesException;
30+
import org.openscience.cdk.interfaces.IAtom;
3631
import org.openscience.cdk.interfaces.IAtomContainer;
3732
import org.openscience.cdk.interfaces.IAtomContainerSet;
3833
import org.openscience.cdk.io.HINReader;
3934
import org.openscience.cdk.io.ISimpleChemObjectReader;
4035
import org.openscience.cdk.io.MDLV2000Reader;
36+
import org.openscience.cdk.sgroup.Sgroup;
37+
import org.openscience.cdk.sgroup.SgroupType;
4138
import org.openscience.cdk.silent.SilentChemObjectBuilder;
4239
import org.openscience.cdk.smiles.SmilesParser;
4340
import org.openscience.cdk.templates.TestMoleculeFactory;
@@ -229,4 +226,30 @@ public void testNoAtomsIsConnected() {
229226
Assert.assertTrue("Molecule appears not to be connected", ConnectivityChecker.isConnected(container));
230227
}
231228

229+
@Test
230+
public void copySgroups() throws Exception {
231+
String filename = "data/mdl/sgroup-split.mol";
232+
try(InputStream ins = this.getClass().getClassLoader().getResourceAsStream(filename);
233+
ISimpleChemObjectReader reader = new MDLV2000Reader(ins);
234+
){
235+
ChemFile content = (ChemFile) reader.read((ChemObject) new ChemFile());
236+
List<IAtomContainer> cList = ChemFileManipulator.getAllAtomContainers(content);
237+
IAtomContainer ac = cList.get(0);
238+
IAtomContainerSet containerSet = ConnectivityChecker.partitionIntoMolecules(ac);
239+
Assert.assertEquals(2, containerSet.getAtomContainerCount());
240+
IAtomContainer container1 = containerSet.getAtomContainer(0);
241+
IAtomContainer container2 = containerSet.getAtomContainer(1);
242+
IAtomContainer h2o = container1.getAtomCount()<=3? container1 : container2;
243+
Assert.assertNull( h2o.getProperty(CDKConstants.CTAB_SGROUPS));
244+
IAtomContainer otherContainer = h2o == container1? container2: container1;
245+
List<Sgroup> sgroups = otherContainer.getProperty(CDKConstants.CTAB_SGROUPS);
246+
Assert.assertEquals(1, sgroups.size());
247+
Sgroup sgroup = sgroups.get(0);
248+
Assert.assertEquals(SgroupType.CtabStructureRepeatUnit, sgroup.getType());
249+
Set<IAtom> atoms = sgroup.getAtoms();
250+
Assert.assertEquals(2, atoms.size());
251+
252+
}
253+
}
254+
232255
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
JSDraw209162011172D
3+
4+
6 4 0 0 0 0 999 V2000
5+
14.5600 -7.3036 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
6+
15.9110 -8.0836 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
7+
17.2620 -7.3036 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
8+
18.6130 -8.0836 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
9+
19.9640 -7.3036 0.0000 C 0 0 0 0 0 0 0 0 0 0 0 0
10+
14.5600 -4.9116 0.0000 O 0 0 0 0 0 0 0 0 0 0 0 0
11+
1 2 1 0 0 0 0
12+
2 3 1 0 0 0 0
13+
3 4 1 0 0 0 0
14+
4 5 1 0 0 0 0
15+
M STY 1 1 SRU
16+
M SAL 1 2 3 4
17+
M SBL 1 2 2 4
18+
M SMT 1 A
19+
M SDI 1 4 16.6400 -9.2276 16.6400 -6.6276
20+
M SDI 1 4 19.3960 -6.6276 19.3960 -9.2276
21+
M END

0 commit comments

Comments
 (0)