1919 */
2020package 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 ;
2525import org .openscience .cdk .interfaces .IAtom ;
2626import org .openscience .cdk .interfaces .IAtomContainer ;
2727import org .openscience .cdk .interfaces .IAtomContainerSet ;
3232import org .openscience .cdk .interfaces .ISingleElectron ;
3333import org .openscience .cdk .interfaces .IStereoElement ;
3434import org .openscience .cdk .interfaces .ITetrahedralChirality ;
35+ import org .openscience .cdk .sgroup .Sgroup ;
36+ import org .openscience .cdk .sgroup .SgroupKey ;
3537import 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}
0 commit comments