/** * Prepare a collection of molecules for rendering. If coordinates are not present they are * generated, if coordinates exists they are scaled to be consistent (length=1.5). * * @param mols molecules * @return coordinates * @throws CDKException */ private List<Double> prepareCoords(Iterable<IAtomContainer> mols) throws CDKException { List<Double> scaleFactors = new ArrayList<>(); for (IAtomContainer mol : mols) { if (ensure2dLayout(mol)) { scaleFactors.add(Double.NaN); } else if (mol.getBondCount() > 0) { final double factor = GeometryUtil.getScaleFactor(mol, 1.5); GeometryUtil.scaleMolecule(mol, factor); scaleFactors.add(factor); } else { scaleFactors.add(1d); // no bonds } } return scaleFactors; }
/** * Performs the pharmacophore matching. * * @param atomContainer The target molecule. Must have 3D coordinates * @param initializeTarget If <i>true</i>, the target molecule specified in the first argument * will be analyzed to identify matching pharmacophore groups. If <i>false</i> this is not * performed. The latter case is only useful when dealing with conformers since for a given * molecule, all conformers will have the same pharmacophore groups and only the constraints * will change from one conformer to another. * @return true is the target molecule contains the query pharmacophore * @throws org.openscience.cdk.exception.CDKException if the query pharmacophore was not set or * the query is invalid or if the molecule does not have 3D coordinates */ public boolean matches(IAtomContainer atomContainer, boolean initializeTarget) throws CDKException { if (!GeometryUtil.has3DCoordinates(atomContainer)) throw new CDKException("Molecule must have 3D coordinates"); if (pharmacophoreQuery == null) throw new CDKException("Must set the query pharmacophore before matching"); if (!checkQuery(pharmacophoreQuery)) throw new CDKException( "A problem in the query. Make sure all pharmacophore groups of the same symbol have the same same SMARTS"); String title = (String) atomContainer.getProperty(CDKConstants.TITLE); if (initializeTarget) pharmacophoreMolecule = getPharmacophoreMolecule(atomContainer); else { // even though the atoms comprising the pcore groups are // constant, their coords will differ, so we need to make // sure we get the latest set of effective coordinates for (IAtom iAtom : pharmacophoreMolecule.atoms()) { PharmacophoreAtom patom = (PharmacophoreAtom) iAtom; List<Integer> tmpList = new ArrayList<Integer>(); for (int idx : patom.getMatchingAtoms()) tmpList.add(idx); Point3d coords = getEffectiveCoordinates(atomContainer, tmpList); patom.setPoint3d(coords); } } if (pharmacophoreMolecule.getAtomCount() < pharmacophoreQuery.getAtomCount()) { logger.debug("Target [" + title + "] did not match the query SMARTS. Skipping constraints"); return false; } mappings = Pattern.findSubstructure(pharmacophoreQuery).matchAll(pharmacophoreMolecule); // XXX: doing one search then discarding return mappings.atLeast(1); }
/** * Automatically generate coordinates if a user has provided a molecule without them. * * @param container a molecule * @return if coordinates needed to be generated * @throws CDKException coordinates could not be generated */ private boolean ensure2dLayout(IAtomContainer container) throws CDKException { if (!GeometryUtil.has2DCoordinates(container)) { StructureDiagramGenerator sdg = new StructureDiagramGenerator(); sdg.generateCoordinates(container); return true; } return false; }
/** * Reset the coordinates to their position before rendering. * * @param mols molecules * @param scales how molecules were scaled */ private static void resetCoords(Iterable<IAtomContainer> mols, List<Double> scales) { Iterator<Double> it = scales.iterator(); for (IAtomContainer mol : mols) { final double factor = it.next(); if (!Double.isNaN(factor)) { GeometryUtil.scaleMolecule(mol, 1 / factor); } else { for (IAtom atom : mol.atoms()) atom.setPoint2d(null); } } }
private IRenderingElement generateAbbreviationSgroup(Sgroup sgroup) { String label = sgroup.getSubscript(); // already handled by symbol remapping if (sgroup.getBonds().size() > 0 || label == null || label.isEmpty()) { return new ElementGroup(); } // we're showing a label where there were no atoms before, we put it in the // middle of all of those which were hidden final Point2d labelCoords = GeometryUtil.get2DCenter(sgroup.getAtoms()); ElementGroup group = new ElementGroup(); for (Shape outline : atomGenerator .generatePseudoSymbol(label, HydrogenPosition.Right) .resize(1 / scale, 1 / -scale) .getOutlines()) group.add(GeneralPath.shapeOf(outline, foreground)); return MarkedElement.markupAtom(group, null); }