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

Reply via email to