Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Many biochemical molecules, such as nucleic acids for example, are composed by nature in a hierarchical fashion from a limited number of building blocks. It would be nice to replicate this approach when typesetting these molecules. In the case of DNA and RNA, a natural approach would be:

  1. Define separate structures for ribose, phosphate and the bases (A,C,G,T,U)
  2. Derive deoxyribose from ribose
  3. Create nucleosides by combining ribose or deoxyribose with each of the bases
  4. Write DNA and RNA molecules as alternations of nucleosides and phosphate.

The chemfig package provides a \definesubmol command that allows for the definition of sub-molecules, which can then be substituted into other molecules. However, the package does not provide a built-in mechanism for making the results of such substitutions available as new sub-molecules. So, the question is how to define a command with the following behavior:

% "\derivesubmol" defines the new #1 submol, obtained by replacing all the
%  occurrences of "#3" by "#4" in the code of #2 submol

% arguments: #1 = new submol name, #2 = old submol name,
%            #3 = old substring, #4 = new substring
\newcommand*\derivesubmol[4]{% ...

This description is taken from the code that the package author of chemfig has provided to me by email. An example of his code in action is provided in the answer that I supply below.

To indicate that this question is, indeed, a question, let me add: ???

share|improve this question
3  
Why have you re-worded the entire question to no longer ask anything. Coming to it now I can't understand the answers here because I don't know what the question was. Please revert it to the most relevant version so future generation can benefit form your question, and you may be heaped up with upvotes. –  Pureferret Jan 13 '12 at 21:13
    
The question has been reworded because 1. the original version was unclear, and 2. it has been answered by the package author in private, and he has indicated to me that he did not intend to post his answer himself. It was precisely with the intention to "benefit future generations" that I updated the question to include the answer that the package author kindly provided to me; if this approach cost me your upvote, that is really too, too bad. –  Michael Palmer Jan 13 '12 at 21:25
    
That's not really how Stack Exchange is meant to work. The best solution is to roll back this question and submit your own answer echoing what the package author said. I don't know if you used Marc van Dongen's answer or not, and anyway your question is no longer a question. –  Pureferret Jan 13 '12 at 21:56
6  
@MichaelPalmer The best way to provide this kind of information in a Q&A format is to post an answer, not edit the answer into the question. There is nothing wrong with a self-answer, which you can then accept after a suitable delay. However, a 'question' which is a guide is not really what is intended here. –  Joseph Wright Jan 13 '12 at 22:16
    
Don't see what difference it makes but it if makes anyone happy ... –  Michael Palmer Jan 13 '12 at 22:29

2 Answers 2

up vote 11 down vote accepted

This answer was provided to me by Christian Tellechea in private correspondence; I post it here for the benefit of other people who may be interested.

\documentclass{minimal}
\usepackage{chemfig,xstring}
\makeatletter

% "\derivesubmol" defines the new #1 submol, obtained by replacing all the
%  occurrences of "#3" by "#4" in the code of #2 submol

% arguments: #1 = new submol name, #2 = old submol name,
%            #3 = old substring, #4 = new substring
\newcommand*\derivesubmol[4]{%
    \saveexpandmode\saveexploremode\expandarg\exploregroups
    \csname @\ifcat\relax\noexpand#2first\else second\fi oftwo\endcsname
        {\expandafter\StrSubstitute\@car#2\@nil}
        {\expandafter\StrSubstitute\csname CF@@#2\endcsname}
    {\@empty#3}{\@empty#4}[\temp@]%
    \csname @\ifcat\relax\noexpand#1first\else second\fi oftwo\endcsname
        {\expandafter\let\@car#1\@nil}
        {\expandafter\let\csname CF@@#1\endcsname}\temp@
    \restoreexpandmode\restoreexploremode
}
\makeatother

\setatomsep{2.5em}
\setcrambond{2pt}{}{}

\definesubmol{rt1}{-[2]rt1}
\definesubmol{rt2}{-[6,.6]rt2}

\definesubmol{ribose}{%
    -[:-90,2]%
        (%
            -[:25,1.176]O%
            -[:-25,1.176]%
        )%
    <[:-45,0.8]%
        (%
          -[0,,,,line width=2pt,shorten <=-.5pt,shorten >=-.5pt]%
              (!{rt2})%
          >[:45,0.8]%
              (!{rt1})%
         )%
}

\definesubmol{phosphate}{-[6,.6]O-[6,1.5]P(-[4,.8]HO)(=[6,0.8]O)-[,1.5]O}

\definesubmol{adenine}{N*5([::-18]-*6(-N=-N=(-NH_2)-)=-N=-)}

\definesubmol{uracil}{N*6(-(=O)-NH-(=O)-=-)}

\def\drawhline{\medbreak\hrulefill\medbreak}
\begin{document}

\chemfig{!{ribose}} \quad\quad The ribose template

\drawhline%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\derivesubmol{deoxyribose}{ribose}{(!{rt2})}{}% replace "(!{rt2})" by nothing
\chemfig{!{deoxyribose}} \quad\quad In deoxyribose, substituent rt2 is replaced by nothing

\drawhline

\derivesubmol{deoxyadenosine}{deoxyribose}{!{rt1}}{-[2,0.8]!{adenine}}
\chemfig{!{deoxyadenosine}} \quad\quad \parbox{4in}{Deoxyadenosine is derived from deoxyribose by substituting rt1 with adenine}

\drawhline%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% other method: locally redefine "rt1" submol and display "deoxyribose"
\begingroup
    \derivesubmol{rt1}{rt1}{rt1}{!{adenine}}
    \chemfig{!{deoxyribose}}
\endgroup
%
\quad\quad \parbox{4in}{Local redefinition of the rt 1 substituent in deoxyribose works, too}


\drawhline%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\derivesubmol{deoxyuridine}{deoxyribose}{!{rt1}}{-[2]!{uracil}}
\chemfig{
         !{deoxyuridine}
         !{phosphate}
         !{deoxyadenosine}
         !{phosphate}
         !{deoxyuridine}
        }
%
\quad\quad \parbox{2.5in}{Using the previously derived dU and dA templates, we can now easily write a DNA molecule}
\end{document}

The figure shows the result of the last \chemfig command:

enter image description here

Needless to say that I'm extremely happy with this solution. In case someone isn't, the chemfig package allows them to tweak all aspects of the structures with little effort. I recommend it highly.

share|improve this answer
    
This is awesome. It significantly shortens the typing and the time for creating complex molecules. I will borrow the \derivesubmol command for my costum chemistry preamble. Did Christian say anything about adding this command to chemfig? I think it would be a great feature. –  cgnieder Jan 14 '12 at 12:52
    
I agree that it would be very useful to include this macro in chemfig, but Christian did not mention whether or not he intended to do so. –  Michael Palmer Jan 14 '12 at 13:29
1  
This "feature" is a simple use of \StrSubstitute from the xstring package (replace all occurences of a string by an other string). xstring is not loaded by chemfig and must not because, for a reason I don't understand, xstring is not compatible with conTeXt and chemfig is. Therefore, I can't add this macro to chemfig. Even without this compatiblility issue, I would not have added it! Indeed, for special use, isn't it the user's job to create his own macros with the help of other packages? –  unbonpetit Jan 14 '12 at 15:49
    
@unbonpetit I agree that creating macros for special use is something that normally the user does. However, I am not quite sure that most users would have been able to create this specific macro. But as I said before: I'll borrow the code for my custom chemistry preamble, so I don't mind too much :) –  cgnieder Jan 14 '12 at 18:52
    
Christian, thanks for the explanation. However, let me add, from my perspective as a Latex pedestrian, I could not solve this problem myself, and –  Michael Palmer Jan 14 '12 at 18:53

It's not entirely clear what you mean, but the following seems a bit easier to use. Please note that I'm not a chemist and it's ages ago since I studied chemistry (at secondary school level).

\documentclass{minimal}
\usepackage{chemfig}   

\setatomsep{2.0em}
\setcrambond{2.0pt}{}{}
\setbondoffset{0.5pt}  

\definesubmol{OH}[HO]{OH} % let OH groups figure out which way to point

\definesubmol{phosphonate}{%
                 P          
     (=[::90,0.7]O)         
    (-[::-90,0.7]!{OH})     
       -[::0,0.7]!{OH}      
}                           

\definesubmol{sub1}{A}
\definesubmol{sub6}{B}

\definesubmol{fructose}{
      {}?[a]            
         (-[:90,0.6]    
          -[:30,0.7]O   
          -[:0,0.7]!{sub1}
         )
      <[:225,0.8]
         (-[:-90,0.6]OH)
         (-[:180,0.5,,,draw=none]          % note the devlishly clever trick
          -[:90,1.26,,,draw=none]O?[a]?[b] % to position the oxigen in the ring
         )
      -[:180,1,,,line width=2pt]
         (-[:90,0.6]OH)
      >[:135,0.8]?[b]
      -[:90,0.6]
      -[:150,0.7]O
      -[:180,0.7]!{sub6}
}

\begin{document}

\tikzset{sub1/.code=\redefinesubmol{sub1}{#1},
         sub6/.code=\redefinesubmol{sub6}{#1}}

\begin{tikzpicture}[x=0.8in,y=0.8in]
    \node[anchor=south west] at (0,2) {\chemfig{!{fructose}}};
    \begin{scope}[sub1=H,sub6=H]
        \node[anchor=south west,sub1=H,sub6=H] at (2.5,2) {\chemfig{!{fructose}}};
    \end{scope}
    \begin{scope}[sub1=!{phosphonate},sub6=H]
        \node[anchor=south west] at (5,2) {\chemfig{!{fructose}}};
    \end{scope}
    \begin{scope}[sub1=H,sub6=!{phosphonate}]
        \node[anchor=south west] at (0,0) {\chemfig{!{fructose}}};
    \end{scope}
    \begin{scope}[sub1=!{phosphonate},sub6=!{phosphonate}]
        \node[anchor=south west] at (2.5,0) {\chemfig{!{fructose}}};
    \end{scope}
\end{tikzpicture}

\end{document}

Of course you can also use the options sub1 and sub6 in the node options.

Perhaps you could explain again what you want? (Sorry about the ignorance.)

share|improve this answer
    
This is a very nice simplification of the code I got to work, but not quite what I intend to do as the next step. I will edit the question for clarity. –  Michael Palmer Jan 12 '12 at 15:28
    
This answer relates to a previous version of my question, which was lacking in clarity and which I have since deleted. If this answer falls short, it is only because my original question was poorly posed. –  Michael Palmer Jan 13 '12 at 20:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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