/** * Depict a set of molecules, they will be depicted in a grid with the specified number of rows * and columns. Rows are filled first and then columns. * * @param mols molecules * @param nrow number of rows * @param ncol number of columns * @return depiction * @throws CDKException a depiction could not be generated */ public Depiction depict(Iterable<IAtomContainer> mols, int nrow, int ncol) throws CDKException { int molId = 0; for (IAtomContainer mol : mols) { setIfMissing(mol, MarkedElement.ID_KEY, "mol" + ++molId); } // ensure we have coordinates, generate them if not // we also rescale the molecules such that all bond // lengths are the same. List<Double> scaleFactors = prepareCoords(mols); // highlight parts for (Map.Entry<IChemObject, Color> e : highlight.entrySet()) e.getKey().setProperty(StandardGenerator.HIGHLIGHT_COLOR, e.getValue()); // setup the model scale List<IAtomContainer> molList = FluentIterable.from(mols).toList(); DepictionGenerator copy = this.withParam(BasicSceneGenerator.Scale.class, caclModelScale(molList)); // generate bound rendering elements final RendererModel model = copy.getModel(); final List<Bounds> molElems = copy.generate(molList, model, 1); // reset molecule coordinates resetCoords(mols, scaleFactors); // generate titles (if enabled) final List<Bounds> titles = new ArrayList<>(); if (copy.getParameterValue(BasicSceneGenerator.ShowMoleculeTitle.class)) { for (IAtomContainer mol : mols) titles.add(copy.generateTitle(mol, model.get(BasicSceneGenerator.Scale.class))); } // remove current highlight buffer for (IChemObject obj : this.highlight.keySet()) obj.removeProperty(StandardGenerator.HIGHLIGHT_COLOR); this.highlight.clear(); return new MolGridDepiction(model, molElems, titles, dimensions, nrow, ncol); }
/** * Depict a reaction. * * @param rxn reaction instance * @return depiction * @throws CDKException a depiction could not be generated */ public Depiction depict(IReaction rxn) throws CDKException { ensure2dLayout(rxn); // can reorder components! final Color fgcol = getParameterValue(StandardGenerator.AtomColor.class) .getAtomColor(rxn.getBuilder().newInstance(IAtom.class, "C")); final List<IAtomContainer> reactants = toList(rxn.getReactants()); final List<IAtomContainer> products = toList(rxn.getProducts()); final List<IAtomContainer> agents = toList(rxn.getAgents()); // set ids for tagging elements int molId = 0; for (IAtomContainer mol : reactants) { setIfMissing(mol, MarkedElement.ID_KEY, "mol" + ++molId); setIfMissing(mol, MarkedElement.CLASS_KEY, "reactant"); } for (IAtomContainer mol : products) { setIfMissing(mol, MarkedElement.ID_KEY, "mol" + ++molId); setIfMissing(mol, MarkedElement.CLASS_KEY, "product"); } for (IAtomContainer mol : agents) { setIfMissing(mol, MarkedElement.ID_KEY, "mol" + ++molId); setIfMissing(mol, MarkedElement.CLASS_KEY, "agent"); } final Map<IChemObject, Color> myHighlight = new HashMap<>(); if (highlightAtomMap) { myHighlight.putAll(makeHighlightAtomMap(reactants, products)); } // user highlight buffer pushes out the atom-map highlight if provided myHighlight.putAll(highlight); highlight.clear(); final List<Double> reactantScales = prepareCoords(reactants); final List<Double> productScales = prepareCoords(products); final List<Double> agentScales = prepareCoords(agents); // highlight parts for (Map.Entry<IChemObject, Color> e : myHighlight.entrySet()) e.getKey().setProperty(StandardGenerator.HIGHLIGHT_COLOR, e.getValue()); // setup the model scale based on bond length final double scale = this.caclModelScale(rxn); final DepictionGenerator copy = this.withParam(BasicSceneGenerator.Scale.class, scale); final RendererModel model = copy.getModel(); // reactant/product/agent element generation, we number the reactants, then products then agents List<Bounds> reactantBounds = copy.generate(reactants, model, 1); List<Bounds> productBounds = copy.generate(toList(rxn.getProducts()), model, rxn.getReactantCount()); List<Bounds> agentBounds = copy.generate( toList(rxn.getAgents()), model, rxn.getReactantCount() + rxn.getProductCount()); // remove current highlight buffer for (IChemObject obj : myHighlight.keySet()) obj.removeProperty(StandardGenerator.HIGHLIGHT_COLOR); // generate a 'plus' element Bounds plus = copy.generatePlusSymbol(scale, fgcol); // reset the coordinates to how they were before we invoked depict resetCoords(reactants, reactantScales); resetCoords(products, productScales); resetCoords(agents, agentScales); final Bounds emptyBounds = new Bounds(); final Bounds title = copy.getParameterValue(BasicSceneGenerator.ShowReactionTitle.class) ? copy.generateTitle(rxn, scale) : emptyBounds; final List<Bounds> reactantTitles = new ArrayList<>(); final List<Bounds> productTitles = new ArrayList<>(); if (copy.getParameterValue(BasicSceneGenerator.ShowMoleculeTitle.class)) { for (IAtomContainer reactant : reactants) reactantTitles.add(copy.generateTitle(reactant, scale)); for (IAtomContainer product : products) productTitles.add(copy.generateTitle(product, scale)); } final Bounds conditions = generateReactionConditions(rxn, fgcol, model.get(BasicSceneGenerator.Scale.class)); return new ReactionDepiction( model, reactantBounds, productBounds, agentBounds, plus, rxn.getDirection(), dimensions, reactantTitles, productTitles, title, conditions, fgcol); }