6

I'm trying to recreate a figure that has many molecules, most of them are like the following structure:

enter image description here

Varying only what's 'X' and what's 'Y'. So, a normal submolecule doesn't really help, because I want to change the X and Y. I defined then:

\newcommand*{\HOOC}[2]{HOOC-[1]-[2]-[1]*6(=-=(-#1)-(-#2)=-)}

Which works just fine if there's only "normal" text inside \HOOC's arguments. If I use let's say

\chemfig*{!{\HOOC{OH}{OSO_3}}}

It gives me the Missing $ inserted. How can I overcome this? If there's a more correct or clever way do to this I'm open for suggestions.

M(N)WE:

\documentclass{standalone}
\usepackage{chemfig,tikz}
\renewcommand*\printatom[1]{\ensuremath{\mathsf{#1}}}
\newcommand*{\HOOC}[2]{HOOC-[1]-[2]-[1]*6(=-=(-#1)-(-#2)=-)}
\setatomsep{2em}
\usetikzlibrary{positioning}
\begin{document}
  \begin{tikzpicture}[label position={below}]
    \node[label={Dihydrocaffeic acid-3-O-glucuronide}] (DA3OG) {\chemfig*{!{\HOOC{OH}{O-[:30](-[::25](-[:190]OH)-[:-15](-[:75]OH)-[:15]?-[:-15]OH)(-[::-15]O-[::-30]?-[0]COOH)}}}};
    \node[label={Dihydroferulic acid-4-O-sulfate}, below left=-1.5cm and 3cm of DA3OG] {5
    \chemfig*{%
        !{\HOOC{OCH_3}{OSO_3^{-}}}%
        }%
    };
  \end{tikzpicture}
\end{document}

Desired Output

enter image description here

The above was obtained by copy/pasting the contents of \HOOC and replacing #1 and #2 by their corresponding values of the M(N)WE.

4

There are two issues involved. The first one is how to obtain variable parts in a molecule. The second one is how to use formulas in a tikzpicture.

As far as I understand, there are two possibilities to have variables in molecules.

  • Define submolecules.

    \definesubmol{X}{OCH_3}
    \definesubmol{Y}{OSO_3^{-}}
    \newcommand*\HOOC{HOOC-[1]-[2]-[1]*6(=-=(-!{X})-(-!{Y})=-)}
    \chemfig*{!\HOOC}
    

    Using \redefinesubmol{X}{...} you can set the names to new sub-molecules such that \chemfig*{!\HOOC} will result in a different molecule.

  • Define the \HOOC command including \chemfig.

    \newcommand*{\cfHOOC}[2]{\chemfig*{HOOC-[1]-[2]-[1]*6(=-=(-#1)-(-#2)=-)}}
    \cfHOOC{OCH_3}{OSO_3^{-}}
    

It doesn't seem to be possible to have a macro with arguments after !.

The second issue is related to the fact (?) that \chemfigs are tikz-pictures and that nesting of tikz-pictures may not work. A solution is to typeset the formulas outside of the tikz-picture into a box and to use this box inside the tikz-picture.

\newsavebox\formulaA
\savebox\formulaA{\cfHOOC{OH}{O-[:30](-[::25](-[:190]OH)-[:-15](-[:75]OH)-[:15]?-[:-15]OH)(-[::-15]O-[::-30]?-[0]COOH)}}

\newsavebox\formulaB
\savebox\formulaB{\cfHOOC{OCH_3}{OSO_3^{-}}}

\begin{tikzpicture}
... \usebox\formulaA ... \usebox\formulaB ...
\end{tikzpicture}

Here is the document and the corresponding code.

enter image description here

\documentclass[border=1mm]{standalone}
\usepackage{chemfig}
\renewcommand*\printatom[1]{\ensuremath{\mathsf{#1}}}
\setatomsep{2em}
\usetikzlibrary{positioning}
\begin{document}
\newcommand*{\cfHOOC}[2]{\chemfig*{HOOC-[1]-[2]-[1]*6(=-=(-#1)-(-#2)=-)}}

\newsavebox\formulaA
\savebox\formulaA{\cfHOOC{OH}{O-[:30](-[::25](-[:190]OH)-[:-15](-[:75]OH)-[:15]?-[:-15]OH)(-[::-15]O-[::-30]?-[0]COOH)}}

\newsavebox\formulaB
\savebox\formulaB{\cfHOOC{OCH_3}{OSO_3^{-}}}

\begin{tikzpicture}[label position={below}]
    \node[label={Dihydrocaffeic acid-3-O-glucuronide}] (DA3OG) {\usebox\formulaA};
    \node[label={Dihydroferulic acid-4-O-sulfate}, below left=-1.5cm and 3cm of DA3OG] {5\usebox\formulaB};
 \end{tikzpicture}
\end{document}

Edit: As it seems, these particular \chemfigs also work when using them directly in the tikz-picture. Just remember that when encountering errors this may be due to nested tikz-pictures.

| improve this answer | |
  • Very good solution. As to the nesting issue, I have used \chemfig macros inside \tikz nodes literally hundreds of times and never run into it. – Michael Palmer Dec 13 '16 at 17:31
  • @MichaelPalmer This makes life easier. I remember a post here where there was a problem when using \chemfig in a structure that was using tikz itself. In general, tikz-pictures cannot be nested, so the \savebox-trick may be necessary sometimes. – gernot Dec 13 '16 at 17:35
  • @gernot, awesome! But I'm with Micheal on this one, the "second issue" is not an issue at all (at least so far). And as for the \saveboxes that's really not an option for me, I'll be making about 40 of such molecules. I used the concept of your idea though, to define \radicals{X}{Y} which redefines the radicals, so I just issue this cmd before calling \chemfig*{!{hooc}}. – Guilherme Zanotelli Dec 13 '16 at 17:37
  • @GuilhermeZanotelli Well, "my" idea is just what's explained in the chemfig manual regarding the usage of ! ... – gernot Dec 13 '16 at 17:39
  • @gernot, WHERE? I've been browsing the manual for the past hour almost... :( – Guilherme Zanotelli Dec 13 '16 at 17:40
4

I brought up a similar question once to Christian Tellechea, the author of the chemfig package, and he was kind enough to provide me with some custom code to solve it. I paste that code in the example below. I hope you don't mind my using some example molecules of my own, rather than yours.

\documentclass{article}

\usepackage{chemfig,xstring}

\makeatletter

% he sent me this later ... it seems this is simply a slight refactoring.

\newcommand*\if@csfirst[1]{%
    \csname @\ifcat\relax\expandafter\noexpand\@car#1\@nil first\else second\fi oftwo\endcsname
}

\newcommand*\derivesubmol[4]{%
    \saveexpandmode\saveexploremode\expandarg\exploregroups
    \if@csfirst{#2}
        {\expandafter\StrSubstitute\@car#2\@nil}
        {\expandafter\StrSubstitute\csname CF@@#2\endcsname}
    {\@empty#3}{\@empty#4}[\temp@]%
    \if@csfirst{#1}
        {\expandafter\let\@car#1\@nil}
        {\expandafter\let\csname CF@@#1\endcsname}\temp@
    \restoreexpandmode\restoreexploremode
}

\newcommand*\showsubmol[1]{%
    \if@csfirst{#1}%
        {\begingroup submol "\expandafter\showsubmol@i\string#1" = \ttfamily
        \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter#1%
            \expandafter\expandafter\expandafter{\expandafter\@gobble#1}%
        \expandafter\expandafter\expandafter\strip@prefix\expandafter\meaning\@car#1\@nil
        \endgroup}%
        {\expandafter\showsubmol\csname CF@@#1\endcsname}%
}

\def\showsubmol@i#1#2#3#4#5{}

\newcommand*\exp@addtomacro[2]{\expandafter\@xs@addtomacro\expandafter#1\expandafter{#2}}

\newcommand*\expandsubmol[1]{%
    \if@csfirst{#1}%
        {\saveexpandmode\saveexploremode\expandarg\noexploregroups
        \let\parsed@mol\@empty\let\remain@mol#1%
        \IfSubStr#1!%
            {\expandsubmol@i
            \let#1\parsed@mol
            }%
            \relax
        }%
        {\expandafter\expandsubmol\csname CF@@#1\endcsname}%
}

\newcommand*\expandsubmol@i{%
    \StrBefore\remain@mol![\temp@]%
    \exp@addtomacro\parsed@mol\temp@
    \StrBehind\remain@mol![\remain@mol]%
    \StrSplit\remain@mol\@ne\remain@mol\temp@
    \StrRemoveBraces\remain@mol[\remain@mol]%
    \expandafter\if@csfirst\expandafter{\remain@mol}%
        {\expandafter\let\expandafter\remain@mol\remain@mol}%
        {\expandafter\let\expandafter\remain@mol\csname CF@@\remain@mol\endcsname}%
    \StrGobbleLeft\remain@mol\@ne[\remain@mol]%
    \exp@addtomacro\remain@mol\temp@
    \IfSubStr\remain@mol!%
        \expandsubmol@i
        {\exp@addtomacro\parsed@mol\remain@mol
        \restoreexpandmode\restoreexploremode
        }%
}

\makeatother

% cosmetic enhancements for the example 
\setcrambond{1.75pt}{0.4pt}{1.0pt} % previously too crammed for print.
\setatomsep{18pt}
\renewcommand*\printatom[1]{\ensuremath{\mathsf{#1}}}

\tikzset{ % bond in the foreground
    fgbond/.style={% foreground bond - connecting two cram bonds.
        line width=1.6pt,
        shorten <=-.6pt,
        shorten >=-.6pt
   }
}

% define named substituent dummies. Not strictly necessary, but useful for 
% visual display of the template that contains them. 
\definesubmol{rt1}{-[:90]rt1}
\definesubmol{rt2}{-[:-90,0.6]rt2}


% define a template that contains named dummy substituents that can be replaced
\definesubmol{ribosetemplate}{%
        (
            -[:28,1.508]O
            -[:-28,1.508]
        )
    <[:-45]
        (
          -[0,1.25,,,fgbond]
              (!{rt2})
          >[:45]
              (!{rt1})
         )
}


% partially specialize the template by supplying a substituent for the ribose
\derivesubmol{ribonucleoside}{ribosetemplate}{!{rt2}}{-[6,0.9]OH}
\derivesubmol{deoxyribonucleoside}{ribosetemplate}{!{rt2}}{}


% define some more submols
\definesubmol{adenine}{N*5([::-18]-*6(-N=-N=(-NH_2)-)=-N=-)}
\redefinesubmol{guanine}{N*5([::-18]-*6(-N=(-NH_2)-NH-(=O)-)=-N=-)}

% put those into the second position
\derivesubmol{guanosine}{ribonucleoside}{!{rt1}}{-[2]!{guanine}}
\derivesubmol{deoxyadenosine}{deoxyribonucleoside}{!{rt1}}{-[2]!{adenine}}

\begin{document}

% display the template, so that we know what is where
\chemfig{entry-[6]!{ribosetemplate}-[6]exit}
\hspace{1in}
% put it all together
\chemfig{X-[6,2]!{guanosine}-[6,2]{stuff}-[6,2]!{deoxyadenosine}-[6,2]B}

\end{document}

This produces

enter image description here

The code between \makeatletter and \makeatother is written by Christian and is as clear to me as some Cuneiform script; don't ask me about it. It depends on the xstring package, also written by Christian. However, it is easy enough to use. The idea is to define a template molecule with string placeholders, which can then be replaced with different substituents using the \derivesubmol macro. I think this macro would be a useful addition to the (already wonderful) chemfig package.

| improve this answer | |
  • Thank's, this is nice. But I think it may be overcomplicated for what I'm looking for... I'll see if I can figure out how to use this and wait to see if someone can figure out why I'm getting the error with the math chars _ and ^. It must be something simple that I'm missing. – Guilherme Zanotelli Dec 13 '16 at 16:56
  • My example is more complicated than yours, yes, but your problem would be easy enough to address with this approach. Just define the methoxy, glucuronosyl etc. groups as submoles. Define your X-Y-phenyl-propionic acid as the template, and specialize it as needed with \derivesubmol. Just stick the entire code at the top into a personal package, so that you can reuse it at any time. – Michael Palmer Dec 13 '16 at 17:05
  • I got how it works, I'm not talking about the example. I'm talking about the solution itself. I don't want to derive several submolecules from an original submolecule. I want be able to "morph" the original submolecule into others (varying only the two radicals) this may seem to be the same but one involves much more work. ;) – Guilherme Zanotelli Dec 13 '16 at 17:39
3

Following what @gernot has proposed (now known to be the contents of the manual) but using an approach without the \saveboxes - which may implicate in future issues but so far none has been encountered - it's possible to define the submolecule dependent of other submolecules (in macro form):

\definesubmol{hooc}{HOOC-[1]-[2]-[1]*6(=-=(-!{\X})-(-!{\Y})=-)}

Then we make a command to renew this macros \X and \Y as needed:

\newcommand*{\radicals}[2]{\edef\X{#1}\edef\Y{#2}}

The reason behind using macros (and \edef instead of \def) for the independent submolecules is that then we can define several other submolecules and use them too, e.g. \def\metil{CH_3}, this example is stupid but in the MWE below there's one more convincing:

\documentclass{standalone}
\usepackage{tikz,chemfig}

\renewcommand*\printatom[1]{\ensuremath{\mathsf{#1}}} % Uses sf font
\setatomsep{2em} % Sets atom separation
\usetikzlibrary{positioning}

\newcommand*{\radicals}[2]{\edef\X{#1}\edef\Y{#2}} % Macro that renews the radicals
\definesubmol{hooc}{HOOC-[1]-[2]-[1]*6(=-=(-!{\X})-(-!{\Y})=-)} % Dependent submol
\def\glucuronide{% Complex independent submol
 O-[:30](-[::25](-[:190]OH)-[:-15](-[:75]OH)-[:15]?-[:-15]OH)(-[::-15]O-[::-30]?-[0]COOH)
}

\begin{document}
  \begin{tikzpicture}[label position={below}]
    \node[label={Dihydrocaffeic acid-3-O-glucuronide}] (DA3OG)
         {\radicals{OH}{\glucuronide}\chemfig*{!{hooc}}};
    \node[label={Dihydroferulic acid-4-O-sulfate}, below left=-1.5cm and 3cm of DA3OG]
         {\radicals{OCH_3}{OSO_3^{-}}\chemfig*{!{hooc}}};
  \end{tikzpicture}
\end{document}

Results in the desired output

enter image description here

| improve this answer | |
  • Very good and concise solution. Will make use of this. – Michael Palmer Dec 13 '16 at 18:17
  • 1
    @MichaelPalmer, perhaps you'll like the graph I drew using the knowledge from this question + another one I made the picture is in the linked question. :) – Guilherme Zanotelli Dec 14 '16 at 22:49
  • Thanks for the update. I'd draw the arrows a little thinner in that example; otherwise, great work. I take it you are working on the metabolism of drugs or xenobiotics in some way? – Michael Palmer Dec 15 '16 at 1:30
  • You are welcome, the arrows are not ready, some will be thinner some dashed and all with labels. And it's not for me, it's for my girlfriend, so she's probably doing something with metabolism of stuff... xD – Guilherme Zanotelli Dec 15 '16 at 6:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.