Skip to content

Commit ebbf42d

Browse files
committed
CXSMILES corner case - collect the reaction atom index before merging the fragments together.
1 parent 9f7562a commit ebbf42d

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,26 +346,32 @@ private void parseRxnCXSMILES(String title, IReaction rxn) throws InvalidSmilesE
346346

347347
final Map<IAtom, IAtomContainer> atomToMol = new HashMap<>(100);
348348
final List<IAtom> atoms = new ArrayList<>();
349+
350+
// collect atom offsets before handling fragment groups
351+
for (IAtomContainer mol : rxn.getReactants().atomContainers())
352+
for (IAtom atom : mol.atoms())
353+
atoms.add(atom);
354+
for (IAtomContainer mol : rxn.getAgents().atomContainers())
355+
for (IAtom atom : mol.atoms())
356+
atoms.add(atom);
357+
for (IAtomContainer mol : rxn.getProducts().atomContainers())
358+
for (IAtom atom : mol.atoms())
359+
atoms.add(atom);
360+
349361
handleFragmentGrouping(rxn, cxstate);
350362

351363
// merge all together
352364
for (IAtomContainer mol : rxn.getReactants().atomContainers()) {
353-
for (IAtom atom : mol.atoms()) {
354-
atoms.add(atom);
365+
for (IAtom atom : mol.atoms())
355366
atomToMol.put(atom, mol);
356-
}
357367
}
358368
for (IAtomContainer mol : rxn.getAgents().atomContainers()) {
359-
for (IAtom atom : mol.atoms()) {
360-
atoms.add(atom);
369+
for (IAtom atom : mol.atoms())
361370
atomToMol.put(atom, mol);
362-
}
363371
}
364372
for (IAtomContainer mol : rxn.getProducts().atomContainers()) {
365-
for (IAtom atom : mol.atoms()) {
366-
atoms.add(atom);
373+
for (IAtom atom : mol.atoms())
367374
atomToMol.put(atom, mol);
368-
}
369375
}
370376

371377
assignCxSmilesInfo(rxn.getBuilder(), rxn, atoms, atomToMol, cxstate);

storage/smiles/src/test/java/org/openscience/cdk/smiles/CxSmilesParserTest.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,24 @@
2626
import org.hamcrest.BaseMatcher;
2727
import org.hamcrest.Description;
2828
import org.junit.Test;
29+
import org.openscience.cdk.exception.CDKException;
2930
import org.openscience.cdk.exception.InvalidSmilesException;
3031
import org.openscience.cdk.interfaces.IAtom;
3132
import org.openscience.cdk.interfaces.IAtomContainer;
33+
import org.openscience.cdk.interfaces.IPseudoAtom;
3234
import org.openscience.cdk.interfaces.IReaction;
3335
import org.openscience.cdk.interfaces.IStereoElement;
3436
import org.openscience.cdk.silent.SilentChemObjectBuilder;
37+
import org.openscience.cdk.tools.manipulator.ReactionManipulator;
3538

3639
import java.util.ArrayList;
3740
import java.util.Arrays;
3841
import java.util.HashMap;
42+
import java.util.List;
3943
import java.util.Map;
4044

4145
import static org.hamcrest.CoreMatchers.hasItem;
46+
import static org.hamcrest.CoreMatchers.instanceOf;
4247
import static org.hamcrest.CoreMatchers.is;
4348
import static org.hamcrest.CoreMatchers.not;
4449
import static org.hamcrest.MatcherAssert.assertThat;
@@ -354,7 +359,16 @@ public void hydrogenAndCoordinationBondingSkipped() {
354359
}
355360
}
356361

357-
362+
@Test public void atomOrderingWithNonContiguousFragments() throws CDKException {
363+
SmilesParser smipar = new SmilesParser(SilentChemObjectBuilder.getInstance());
364+
IReaction rxn = smipar.parseReactionSmiles("C.*.C>> |$;R1;$,f:0.2|");
365+
List<IAtomContainer> mols = ReactionManipulator.getAllAtomContainers(rxn);
366+
assertThat(mols.get(0).getAtomCount(), is(2));
367+
assertThat(mols.get(1).getAtomCount(), is(1));
368+
assertThat(mols.get(1).getAtom(0), is(instanceOf(IPseudoAtom.class)));
369+
assertThat(((IPseudoAtom)mols.get(1).getAtom(0)).getLabel(),
370+
is("R1"));
371+
}
358372

359373
/**
360374
* Custom matcher for checking an array of doubles closely matches (epsilon=0.01)

0 commit comments

Comments
 (0)