Nice, For historical reasons, CDK uses unit bond length 1.5 instead of 1. Something to do with C-C bonds but that really only makes sense for 3D. Rescale it like this:
GeometryUtil.scaleMolecule(fixedSubstructure, 1.5/GeometryUtil.getBondLengthMedian(fixedSubstructure)); Also I presume you want *findSubstructure* rather than *findIdentical* (exact match). You should also avoid the *count() > 1* this is very waste-full if there are a lot of automorphisms in the query. Basically it says find them all and count them and then re-find the first one for alignment. You can completely remove that check as show but for the benefit of the mailing list the correct way to write that if-condition is: > *if (mappings.atLeast(1)) {}* Now the tricky part is working out when to/not align atoms in generic queries, for example: *C~C~O* matches both C=C=O and CCO the first would should not be bent when laid out. Anyways it's an open problem and for most queries it will be fine. Here's the final function, you probably also want the highlighting done at the same time but have omitted that here: https://gist.github.com/johnmay/12797a89f4186bc7da881f1f4a706671 public static void alignMoleculeToSubstructure(IAtomContainer mol, > IAtomContainer sub, > boolean fixBonds) throws > CDKException { > > * Pattern substructurePattern = Pattern.findSubstructure(sub);* > Mappings mappings = substructurePattern.matchAll(mol); > Set<IAtom> fixedAtoms = new HashSet<IAtom>(); > Set<IBond> fixedBonds = new HashSet<IBond>(); > for (Map<IChemObject, IChemObject> map : mappings.toAtomBondMap()) { > > * GeometryUtil.scaleMolecule(sub, > 1.5/GeometryUtil.getBondLengthMedian(sub));* > for (IChemObject substructureObject : map.keySet()) { > IChemObject targetObject = map.get(substructureObject); > if (targetObject instanceof IAtom) { > //set the target atom's position to that of the > substructure atom and add it to the fixed atom list > IAtom targetAtom = (IAtom) targetObject; > IAtom substructureAtom = (IAtom) substructureObject; > targetAtom.setPoint2d(new > Point2d(substructureAtom.getPoint2d())); > fixedAtoms.add(targetAtom); > } else if (fixBonds) { > //only check bonds if needed > if (targetObject instanceof IBond) { > //add the target bond to the fixed bond list > IBond targetBond = (IBond) substructureObject; > fixedBonds.add(targetBond); > } > } > } > //only align to the first matching substructure > break; > } > //generate coordinates for the molecule > StructureDiagramGenerator sdg = new StructureDiagramGenerator(); > sdg.setMolecule(mol, false, fixedAtoms, fixedBonds); > sdg.generateCoordinates(); > } John
_______________________________________________ Cdk-user mailing list Cdk-user@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cdk-user