#define USE_BETTER_ENUMS #include #include #include #include #include #include #include #include #include #define PT_OPT_GET(opt) opts.opt = pt.get(#opt, opts.opt) namespace RDKit { namespace MolDraw2DUtils { void updateMolDrawOptionsFromJSON(MolDrawOptions &opts, const char *json) { PRECONDITION(json, "no parameter string"); updateMolDrawOptionsFromJSON(opts, std::string(json)); } RDKIT_MOLDRAW2D_EXPORT void updateDrawerParamsFromJSON(MolDraw2D &drawer, const char *json) { updateMolDrawOptionsFromJSON(drawer.drawOptions(), json); } void get_rgba(const boost::property_tree::ptree &node, DrawColour &colour) { boost::property_tree::ptree::const_iterator itm = node.begin(); colour.r = itm->second.get_value(); ++itm; colour.g = itm->second.get_value(); ++itm; colour.b = itm->second.get_value(); ++itm; if (itm != node.end()) { colour.a = itm->second.get_value(); ++itm; } } void get_colour_option(const boost::property_tree::ptree &pt, const char *pnm, DrawColour &colour) { PRECONDITION(pnm && strlen(pnm), "bad property name"); if (pt.find(pnm) == pt.not_found()) { return; } const auto &node = pt.get_child(pnm); get_rgba(node, colour); } void get_colour_palette_option(const boost::property_tree::ptree &pt, const char *pnm, ColourPalette &palette) { PRECONDITION(pnm && strlen(pnm), "bad property name"); static const std::map PRESET_PALETTE_MAP{ {"default", assignDefaultPalette}, {"avalon", assignAvalonPalette}, {"cdk", assignCDKPalette}, {"darkmode", assignDarkModePalette}, {"bw", assignBWPalette}, }; auto atomColourPaletteIt = pt.find(pnm); if (atomColourPaletteIt == pt.not_found()) { return; } // Does the "atomColourPalette" key correspond to a terminal value? if (atomColourPaletteIt->second.empty()) { const auto &v = atomColourPaletteIt->second.data(); if (v.empty()) { return; } auto paletteName = boost::lexical_cast(v); boost::algorithm::to_lower(paletteName); auto preSetPaletteIt = PRESET_PALETTE_MAP.find(paletteName); if (preSetPaletteIt == PRESET_PALETTE_MAP.end()) { return; } // Populate the palette calling the corresponding function preSetPaletteIt->second(palette); } else { for (const auto &atomicNumNode : atomColourPaletteIt->second) { int atomicNum = boost::lexical_cast(atomicNumNode.first); DrawColour colour; get_rgba(atomicNumNode.second, colour); palette[atomicNum] = colour; } } } void get_highlight_style_option(const boost::property_tree::ptree &pt, const char *pnm, MultiColourHighlightStyle &mchs) { PRECONDITION(pnm && strlen(pnm), "bad property name"); if (pt.find(pnm) == pt.not_found()) { return; } const auto &node = pt.get_child(pnm); auto styleStr = node.get_value(); if (styleStr == "Lasso") { mchs = MultiColourHighlightStyle::LASSO; } else if (styleStr == "CircleAndLine") { mchs = MultiColourHighlightStyle::CIRCLEANDLINE; } } void get_legend_position_option(const boost::property_tree::ptree &pt, const char *pnm, MolDrawOptions::LegendPosition &pos) { PRECONDITION(pnm && strlen(pnm), "bad property name"); if (pt.find(pnm) == pt.not_found()) { return; } const auto &node = pt.get_child(pnm); auto str = node.get_value(); if (str == "Top") { pos = MolDrawOptions::LegendPosition::Top; } else if (str == "Left") { pos = MolDrawOptions::LegendPosition::Left; } else if (str == "Right") { pos = MolDrawOptions::LegendPosition::Right; } else { pos = MolDrawOptions::LegendPosition::Bottom; } } void updateMolDrawOptionsFromJSON(MolDrawOptions &opts, const std::string &json) { if (json.empty()) { return; } std::istringstream ss; ss.str(json); boost::property_tree::ptree pt; boost::property_tree::read_json(ss, pt); PT_OPT_GET(atomLabelDeuteriumTritium); PT_OPT_GET(dummiesAreAttachments); PT_OPT_GET(circleAtoms); PT_OPT_GET(splitBonds); PT_OPT_GET(continuousHighlight); PT_OPT_GET(fillHighlights); PT_OPT_GET(highlightRadius); PT_OPT_GET(flagCloseContactsDist); PT_OPT_GET(includeAtomTags); PT_OPT_GET(clearBackground); PT_OPT_GET(legendFontSize); PT_OPT_GET(legendFraction); PT_OPT_GET(maxFontSize); PT_OPT_GET(minFontSize); PT_OPT_GET(fixedFontSize); PT_OPT_GET(baseFontSize); PT_OPT_GET(annotationFontScale); PT_OPT_GET(fontFile); PT_OPT_GET(multipleBondOffset); PT_OPT_GET(padding); PT_OPT_GET(componentPadding); PT_OPT_GET(additionalAtomLabelPadding); PT_OPT_GET(noAtomLabels); PT_OPT_GET(bondLineWidth); PT_OPT_GET(scaleBondWidth); PT_OPT_GET(scaleHighlightBondWidth); PT_OPT_GET(highlightBondWidthMultiplier); PT_OPT_GET(prepareMolsBeforeDrawing); PT_OPT_GET(fixedScale); PT_OPT_GET(fixedBondLength); PT_OPT_GET(rotate); PT_OPT_GET(addAtomIndices); PT_OPT_GET(addBondIndices); PT_OPT_GET(isotopeLabels); PT_OPT_GET(dummyIsotopeLabels); PT_OPT_GET(addStereoAnnotation); PT_OPT_GET(showAllCIPCodes); PT_OPT_GET(atomHighlightsAreCircles); PT_OPT_GET(centreMoleculesBeforeDrawing); PT_OPT_GET(explicitMethyl); PT_OPT_GET(includeMetadata); PT_OPT_GET(includeRadicals); PT_OPT_GET(comicMode); PT_OPT_GET(variableBondWidthMultiplier); PT_OPT_GET(variableAtomRadius); PT_OPT_GET(includeChiralFlagLabel); PT_OPT_GET(simplifiedStereoGroupLabel); PT_OPT_GET(unspecifiedStereoIsUnknown); PT_OPT_GET(singleColourWedgeBonds); PT_OPT_GET(singleColourBonds); PT_OPT_GET(useMolBlockWedging); PT_OPT_GET(scalingFactor); PT_OPT_GET(drawMolsSameScale); PT_OPT_GET(useComplexQueryAtomSymbols); PT_OPT_GET(bracketsAroundAtomLists); PT_OPT_GET(standardColoursForHighlightedAtoms); get_colour_option(pt, "highlightColour", opts.highlightColour); get_colour_option(pt, "backgroundColour", opts.backgroundColour); get_colour_option(pt, "queryColour", opts.queryColour); get_colour_option(pt, "legendColour", opts.legendColour); get_colour_option(pt, "symbolColour", opts.symbolColour); get_colour_option(pt, "annotationColour", opts.annotationColour); get_colour_option(pt, "atomNoteColour", opts.atomNoteColour); get_colour_option(pt, "bondNoteColour", opts.bondNoteColour); get_colour_option(pt, "variableAttachmentColour", opts.variableAttachmentColour); get_colour_palette_option(pt, "atomColourPalette", opts.atomColourPalette); if (pt.find("atomLabels") != pt.not_found()) { for (const auto &item : pt.get_child("atomLabels")) { opts.atomLabels[boost::lexical_cast(item.first)] = item.second.get_value(); } } get_highlight_style_option(pt, "multiColourHighlightStyle", opts.multiColourHighlightStyle); get_legend_position_option(pt, "legendPosition", opts.legendPosition); PT_OPT_GET(legendVerticalText); const auto drawingExtentsIncludeIt = pt.find("drawingExtentsInclude"); if (drawingExtentsIncludeIt != pt.not_found()) { bool haveDrawElementFlags = false; auto drawingExtentsInclude = flagsFromJson( drawingExtentsIncludeIt->second, &haveDrawElementFlags); if (haveDrawElementFlags) { opts.drawingExtentsInclude = drawingExtentsInclude; } } } RDKIT_MOLDRAW2D_EXPORT void updateDrawerParamsFromJSON( MolDraw2D &drawer, const std::string &json) { updateMolDrawOptionsFromJSON(drawer.drawOptions(), json); } } // namespace MolDraw2DUtils } // namespace RDKit