/** * Load a template library from an input stream. * * @return loaded template library * @throws java.io.IOException low level IO error */ static IdentityTemplateLibrary load(InputStream in) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(in)); String line = null; IdentityTemplateLibrary library = new IdentityTemplateLibrary(); while ((line = br.readLine()) != null) { // skip comments if (line.charAt(0) == '#') continue; library.add(decodeEntry(line)); } return library; }
/** * Create a library entry from a SMILES string with the coordinates suffixed in binary. The * entry should be created with {@link #encodeEntry(java.util.Map.Entry)} and not created * manually. Note, the entry is not added to the library. * * @param str input string * @return library entry */ static Entry<String, Point2d[]> decodeEntry(String str) { final int i = str.indexOf(' '); if (i < 0) throw new IllegalArgumentException(); return new SimpleEntry<String, Point2d[]>(str.substring(0, i), decodeCoordinates(str.substring(i + 1))); }
/** * Convert to an identity template library. * * @return identity template library */ IdentityTemplateLibrary toIdentityTemplateLibrary() { IdentityTemplateLibrary lib = IdentityTemplateLibrary.empty(); for (IAtomContainer mol : templates) { lib.add(AtomContainerManipulator.anonymise(mol)); } return lib; } }
/** * Create an entry for the provided container and add it to the library. * * @param container structure representation */ void add(IAtomContainer container) { add(createEntry(container)); }
@Test public void store() throws IOException { IdentityTemplateLibrary lib = IdentityTemplateLibrary.empty(); lib.add(IdentityTemplateLibrary.decodeEntry("[C][C][O] 0, 1, 2, 3, 4, 5")); lib.add(IdentityTemplateLibrary.decodeEntry("[C][C] 0, 1, 2, 3")); ByteArrayOutputStream baos = new ByteArrayOutputStream(); lib.store(baos); baos.close(); assertThat(new String(baos.toByteArray()), is("[C][C][O] |(.0,1.0,;2.0,3.0,;4.0,5.0,)|\n[C][C] |(.0,1.0,;2.0,3.0,)|\n")); } }
@Test public void assignEthanol() { IAtomContainer container = new AtomContainer(); container.addAtom(new Atom("O")); container.addAtom(new Atom("C")); container.addAtom(new Atom("C")); container.getAtom(0).setImplicitHydrogenCount(0); container.getAtom(1).setImplicitHydrogenCount(0); container.getAtom(2).setImplicitHydrogenCount(0); container.addBond(0, 1, IBond.Order.SINGLE); container.addBond(1, 2, IBond.Order.SINGLE); IdentityTemplateLibrary lib = IdentityTemplateLibrary.empty(); lib.add(IdentityTemplateLibrary.decodeEntry("OCC 4, 5, 2, 3, 0, 1")); assertTrue(lib.assignLayout(container)); assertThat(container.getAtom(0).getPoint2d().x, closeTo(4, 0.01)); assertThat(container.getAtom(0).getPoint2d().y, closeTo(5, 0.01)); assertThat(container.getAtom(1).getPoint2d().x, closeTo(2, 0.01)); assertThat(container.getAtom(1).getPoint2d().y, closeTo(3, 0.01)); assertThat(container.getAtom(2).getPoint2d().x, closeTo(0, 0.01)); assertThat(container.getAtom(2).getPoint2d().y, closeTo(1, 0.01)); }
@Test public void encodeEntry() { String smiles = "CO"; Point2d[] points = new Point2d[]{new Point2d(12.5f, 5.5f), new Point2d(4f, 2f)}; String encoded = IdentityTemplateLibrary.encodeEntry(new SimpleEntry<String, Point2d[]>(smiles, points)); Map.Entry<String, Point2d[]> entry = IdentityTemplateLibrary.decodeEntry(encoded); assertThat(encoded, is("CO |(12.5,5.5,;4.0,2.0,)|")); }
@Test public void assignEthanolNoEntry() { IAtomContainer container = new AtomContainer(); container.addAtom(new Atom("O")); container.addAtom(new Atom("C")); container.addAtom(new Atom("C")); container.getAtom(0).setImplicitHydrogenCount(0); container.getAtom(1).setImplicitHydrogenCount(0); container.getAtom(2).setImplicitHydrogenCount(0); container.addBond(0, 1, IBond.Order.SINGLE); container.addBond(1, 2, IBond.Order.SINGLE); assertFalse(IdentityTemplateLibrary.empty().assignLayout(container)); }
/** * Encodes an entry in a compact string representation. The encoded entry is a SMILES string * with the coordinates suffixed in binary. * * @param entry the entry to encode * @return encoded entry */ static String encodeEntry(Entry<String, Point2d[]> entry) { StringBuilder sb = new StringBuilder(); sb.append(entry.getKey()); sb.append(' '); sb.append(encodeCoordinates(entry.getValue())); return sb.toString(); }
/** * Sets the templateHandler attribute of the StructureDiagramGenerator object * * @param templateHandler The new templateHandler value * @deprecated substructure templates are no longer used for layout but those provided here * will be converted to identity templates */ @Deprecated public void setTemplateHandler(TemplateHandler templateHandler) { IdentityTemplateLibrary lib = templateHandler.toIdentityTemplateLibrary(); lib.add(identityLibrary); identityLibrary = lib; // new ones take priority }
/** * Store a template library to the provided output stream. * * @param out output stream * @throws IOException low level IO error */ void store(OutputStream out) throws IOException { BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out)); for (Entry<String, Point2d[]> e : templateMap.entries()) { bw.write(encodeEntry(e)); bw.write('\n'); } bw.close(); }
/** * Update the template library - can be called for safety after * each load. * * @param bldr builder */ void update(IChemObjectBuilder bldr) { final SmilesParser smipar = new SmilesParser(bldr); Multimap<String,Point2d[]> updated = LinkedListMultimap.create(); for (Map.Entry<String,Collection<Point2d[]>> e : templateMap.asMap().entrySet()) { try { IAtomContainer mol = smipar.parseSmiles(e.getKey()); int[] order = new int[mol.getAtomCount()]; String key = cansmi(mol, order); for (Point2d[] coords : e.getValue()) { updated.put(key, reorderCoords(coords, order)); } } catch (CDKException ex) { System.err.println(e.getKey() + " could not be updated: " + ex.getMessage()); } } templateMap.clear(); templateMap.putAll(updated); }
if (identityLibrary.assignLayout(container)) { for (int i = 0; i < ringSystem.getAtomCount(); i++) { IAtom atom = ringSystem.getAtom(i);
/** * Get all templated coordinates for the provided molecule. The return collection has * coordinates ordered based on the input. * * @param mol molecule (or fragment) to lookup * @return the coordinates */ Collection<Point2d[]> getCoordinates(IAtomContainer mol) { try { // create the library key to lookup an entry, we also store // the canonical out ordering int n = mol.getAtomCount(); int[] ordering = new int[n]; String smiles = cansmi(mol, ordering); final Collection<Point2d[]> coordSet = templateMap.get(smiles); final List<Point2d[]> orderedCoordSet = new ArrayList<>(coordSet.size()); for (Point2d[] coords : coordSet) { Point2d[] orderedCoords = new Point2d[coords.length]; for (int i = 0; i < n; i++) { orderedCoords[i] = new Point2d(coords[ordering[i]]); } orderedCoordSet.add(orderedCoords); } return Collections.unmodifiableList(orderedCoordSet); } catch (CDKException e) { return Collections.emptyList(); } }
@Test public void decodeEntry() { String encode = "CO 12.500, 5.500, 4.000, 2.000"; Map.Entry<String, Point2d[]> entry = IdentityTemplateLibrary.decodeEntry(encode); assertThat(entry.getKey(), is("CO")); assertThat(entry.getValue(), is(new Point2d[]{new Point2d(12.5f, 5.5f), new Point2d(4f, 2f)})); }
/** * Create an empty template library. * * @return an empty template library */ static IdentityTemplateLibrary empty() { return new IdentityTemplateLibrary(); }
/** * Create an entry for the provided container and add it to the library. * * @param container structure representation */ void add(IAtomContainer container) { add(createEntry(container)); }
/** * Encodes an entry in a compact string representation. The encoded entry is a SMILES string * with the coordinates suffixed in binary. * * @param entry the entry to encode * @return encoded entry */ static String encodeEntry(Entry<String, Point2d[]> entry) { StringBuilder sb = new StringBuilder(); sb.append(entry.getKey()); sb.append(' '); sb.append(encodeCoordinates(entry.getValue())); return sb.toString(); }
/** * Sets the templateHandler attribute of the StructureDiagramGenerator object * * @param templateHandler The new templateHandler value * @deprecated substructure templates are no longer used for layout but those provided here * will be converted to identity templates */ @Deprecated public void setTemplateHandler(TemplateHandler templateHandler) { IdentityTemplateLibrary lib = templateHandler.toIdentityTemplateLibrary(); lib.add(identityLibrary); identityLibrary = lib; // new ones take priority }
/** * Store a template library to the provided output stream. * * @param out output stream * @throws IOException low level IO error */ void store(OutputStream out) throws IOException { BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out)); for (Entry<String, Point2d[]> e : templateMap.entries()) { bw.write(encodeEntry(e)); bw.write('\n'); } bw.close(); }