Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

High-level depiction API - Part 1 (Molecules) #159

Merged
merged 29 commits into from Sep 19, 2015
Merged

High-level depiction API - Part 1 (Molecules) #159

merged 29 commits into from Sep 19, 2015

Conversation

johnmay
Copy link
Member

@johnmay johnmay commented Sep 19, 2015

A new module (cdk-depict) that makes it easy to create stunning depictions with little expertise. The current APIs (AtomContainerRenderer, MoleculeSetRenderer, ReactionRenderer) are flexible but require a lot of setup and are difficult for new and advanced uses. I've struggled myself trying to get things looking just right so many times and it gets really complicated with margins, padding (between molecules), and the scaling.

I've thought about this and tweaked a lot and come up with two new public API classes, a DepictionGenerator (factory) and a Depiction. The 'Depiction' is a pre-rendered intermediate that allows serialisation to different format - there will be different implementations but currently only MolGrid which depicts molecule(s) in a grid.

At the simplest level depiction of an atom container is reduced to a single line:

new DepictionGenerator().depict(molecule).writeTo("~/mol.png");

Write to different formats.

Depiction depiction = new DepictionGenerator().depict(molecule);
depiction.writeTo("~/mol.png");
depiction.writeTo("~/mol.svg");
depiction.writeTo("~/mol.pdf");

Create an image of a fixed size.

DepictionGenerator dg = new DepictionGenerator();
dg.withSize(256, 256)
  .depict(molecule)
  .writeTo("~/mol.png");

Convenience options

DepictionGenerator dg = new DepictionGenerator();
dg.withSize(256, 256)
  .withMargin(10)
  .withMolTitle()
  .withAtomNumbers()
  .withHighlight(...)
  .depict(molecule)
  .writeTo("~/mol.png");

I've put this under a new sub-module (cdk-app) since it's very high-level and pulls in many other features (e.g. SDG is performed if needed). It could also go under 'cdk-tool' by I think an 'app' like modules with high-level convenience code would be useful. Next 'app' module will probably be for molecule conversion.

Examples

These are full examples that only skip the loading from a file input.

Pattern ptrn = SmartsPattern.create("a:a", null); // highlight aromatic parts
DepictionGenerator dg = new DepictionGenerator().withMolTitle()
                                                .withTitleColor(Color.BLACK);
for (IAtomContainer mol : molecules) {
    mol.setProperty(CDKConstants.TITLE, mol.getProperty("ChEBI Id"));
    dg.withHighlight(ptrn.matchAll(mol).uniqueAtoms().toChemObjects(),
                                     Color.RED);
}        
dg.depict(molecules).writeTo("~/molgrid.png");

MolGrid-1

Pattern ptrn = SmartsPattern.create("a:a", null); // highlight aromatic parts
DepictionGenerator dg = new DepictionGenerator().withMolTitle()
                                                .withTitleColor(Color.BLACK);
for (IAtomContainer mol : molecules) {
    mol.setProperty(CDKConstants.TITLE, mol.getProperty("ChEBI Name"));
    dg.withHighlight(ptrn.matchAll(mol).uniqueAtoms().toChemObjects(),
                                     Color.GREEN);
}        
dg.depict(molecules).writeTo("~/molgrid.png");

MolGrid-2

Future additions

Part 2 will be reactions but there is already a tonne of code in this patch so wanted to push it now.

Long term plans include molecule clouds - http://www.ncbi.nlm.nih.gov/pubmed/22769057

…l option that says how much space want between them.
…s out how big it needs to be. This decouples the computation from the StandardGenerator.
…ements is problematic since the font size is determine right before rendering we can't calculate sizes.
…and PDF. We need to do some work to scale properly (px -> mm).
…w due to FreeHEP page sizing (see acrobatics needed for PDF) so removed.
…le parameter for each molecule. Since the scaling is already pretty complicated in the depiction it's simpler to consider a single scale parameter for the whole set (old MoleculeSetRenderer also did this) and scale the molecule individually. Note we reset the coordinates after depiction.
…ult) that plugs straight into the new depiction generator.
…t (e.g. of titles). Resolved an issue with text outline bounds that happened when flipping the y-axis.
@johnmay
Copy link
Member Author

johnmay commented Sep 19, 2015

Oh right - also I couldn't use my normal goto vector graphics implementation (http://trac.erichseifert.de/vectorgraphics2d/) as it's not on central. I found an alternative but it's not quite as polished (different focus) and so I will probably write/adapt a custom SVG visitor. Also the PostScript wasn't possible as it always wanted to make thinks a full A4 page.

@@ -0,0 +1,322 @@
/* Copyright (C) 2015 The Chemistry Development Kit (CDK) project
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feel free to say here:

Copyright (C) 2015 NextMove Software Ltd https://nextmovesoftware.com

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need - there will likely be some work related patches in future but this was all spare time.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... because you had/have that in the pom.xml ...

<parent>
<artifactId>cdk-app</artifactId>
<groupId>org.openscience.cdk</groupId>
<version>1.5.12-SNAPSHOT</version>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still am not verbose enough in Maven, but can this be ${project.version} ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ${project.version} (really ${project.parentVersion}) actually comes from this tag so it's the only place you must specify it.

@egonw
Copy link
Member

egonw commented Sep 19, 2015

Patch looks good.

@egonw
Copy link
Member

egonw commented Sep 19, 2015

Thought... in addition to writeTo() is there also an asStream() ?

@johnmay
Copy link
Member Author

johnmay commented Sep 19, 2015

I think that's covered...

OutputStream out = ...;
depiction.writeTo(Depiction.SVG_FMT, out)
or
depiction.toSvg()

@johnmay
Copy link
Member Author

johnmay commented Sep 19, 2015

Additional commit addressing comments.

@egonw egonw merged commit b305bb3 into master Sep 19, 2015
* @param path the file system path
* @return normalised path
*/
private static String replaceTildaWithHomeDir(String path) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I think it is "tilde" not "tilda".

@johnmay
Copy link
Member Author

johnmay commented Sep 21, 2015

Thanks for comment will patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants